diff --git a/.changeset/little-shrimps-explain.md b/.changeset/little-shrimps-explain.md new file mode 100644 index 0000000000..70035030eb --- /dev/null +++ b/.changeset/little-shrimps-explain.md @@ -0,0 +1,6 @@ +--- +'@tiptap/extensions': patch +'tiptap-demos': patch +--- + +Fix the `Selection` extension highlighting beyond the selected text on multi-line selections: the native browser selection is now hidden while the editor is blurred, so only the styled `.selection` decoration is shown. diff --git a/demos/src/Extensions/Selection/React/index.tsx b/demos/src/Extensions/Selection/React/index.tsx index a227481dfe..9d449734c4 100644 --- a/demos/src/Extensions/Selection/React/index.tsx +++ b/demos/src/Extensions/Selection/React/index.tsx @@ -24,12 +24,12 @@ export default () => { ], content: `
- The selection extension adds a class to the selection when the editor is blurred. That enables you to visually preserve the selection even though the editor is blurred. By default, it’ll add .selection classname.
+ The Selection extension adds a class to the current text selection when the editor is blurred, which lets you keep the selected text highlighted even after the editor loses focus. This is especially useful when a selection spans multiple wrapped lines, where only the selected text should be highlighted rather than the empty space at the end of each line. By default it adds a .selection classname that you can style.
- The selection extension adds a class to the selection when the editor is blurred. That enables you to visually preserve the selection even though the editor is blurred. By default, it’ll add .selection classname.
+ The Selection extension adds a class to the current text selection when the editor is blurred, which lets you keep the selected text highlighted even after the editor loses focus. This is especially useful when a selection spans multiple wrapped lines, where only the selected text should be highlighted rather than the empty space at the end of each line. By default it adds a .selection classname that you can style.
Hello world
', + }) + + const styleTag = document.querySelector(styleSelector) + + expect(styleTag).not.toBeNull() + expect(styleTag?.textContent).toContain('.ProseMirror:not(.ProseMirror-focused) *::selection') + expect(styleTag?.textContent).toContain('*::-moz-selection') + expect(styleTag?.textContent).toContain('background: transparent') + }) + + it('does not inject the stylesheet when injectCSS is disabled', () => { + editor = new Editor({ + extensions: [Document, Paragraph, Text, Selection], + content: 'Hello world
', + injectCSS: false, + }) + + expect(document.querySelector(styleSelector)).toBeNull() + }) +}) diff --git a/packages/extensions/src/selection/selection.ts b/packages/extensions/src/selection/selection.ts index f47fcdeb52..d4a8b02421 100644 --- a/packages/extensions/src/selection/selection.ts +++ b/packages/extensions/src/selection/selection.ts @@ -1,7 +1,15 @@ -import { Extension, isNodeSelection } from '@tiptap/core' +import { createStyleTag, Extension, isNodeSelection } from '@tiptap/core' import { Plugin, PluginKey } from '@tiptap/pm/state' import { Decoration, DecorationSet } from '@tiptap/pm/view' +const selectionStyle = `.ProseMirror:not(.ProseMirror-focused) *::selection { + background: transparent; +} + +.ProseMirror:not(.ProseMirror-focused) *::-moz-selection { + background: transparent; +}` + export type SelectionOptions = { /** * The class name that should be added to the selected text. @@ -27,6 +35,10 @@ export const Selection = Extension.create