diff --git a/app/globals.css b/app/globals.css index 87248eac..87c8619c 100644 --- a/app/globals.css +++ b/app/globals.css @@ -105,3 +105,16 @@ a { @apply rounded-[4px]; @apply box-decoration-clone; } + +.selection-highlight { + background-color: Highlight; + @apply py-[1.5px]; +} + +.ProseMirror:focus-within .selection-highlight { + background-color: transparent; +} + +.Multiple-Selected:focus-within .selection-highlight { + background-color: transparent; +} diff --git a/components/Blocks/TextBlock/index.tsx b/components/Blocks/TextBlock/index.tsx index 9d0fd88e..3e295b43 100644 --- a/components/Blocks/TextBlock/index.tsx +++ b/components/Blocks/TextBlock/index.tsx @@ -39,6 +39,7 @@ import { setMark } from "src/utils/prosemirror/setMark"; import { rangeHasMark } from "src/utils/prosemirror/rangeHasMark"; import { useEntitySetContext } from "components/EntitySetProvider"; import { useHandlePaste } from "./useHandlePaste"; +import { highlightSelectionPlugin } from "./plugins"; export function TextBlock(props: BlockProps & { className: string }) { let initialized = useInitialPageLoad(); @@ -171,6 +172,7 @@ export function BaseTextBlock(props: BlockProps & { className: string }) { ySyncPlugin(value), TextBlockKeymap(propsRef, repRef), keymap(baseKeymap), + highlightSelectionPlugin, ], }), }); diff --git a/components/Blocks/TextBlock/plugins.ts b/components/Blocks/TextBlock/plugins.ts new file mode 100644 index 00000000..c78fb953 --- /dev/null +++ b/components/Blocks/TextBlock/plugins.ts @@ -0,0 +1,27 @@ +import { Decoration, DecorationSet } from "prosemirror-view"; +import { Plugin } from "prosemirror-state"; +export const highlightSelectionPlugin = new Plugin({ + state: { + init(_, { doc }) { + return DecorationSet.empty; + }, + apply(tr, oldDecorations, oldState, newState) { + let decorations = []; + + // Check if there's a selection + const { from, to } = newState.selection; + if (from !== to) { + decorations.push( + Decoration.inline(from, to, { class: "selection-highlight" }), + ); + } + + return DecorationSet.create(newState.doc, decorations); + }, + }, + props: { + decorations(state) { + return this.getState(state); + }, + }, +}); diff --git a/components/Blocks/index.tsx b/components/Blocks/index.tsx index b1aa3f60..debbe5d5 100644 --- a/components/Blocks/index.tsx +++ b/components/Blocks/index.tsx @@ -299,7 +299,9 @@ function Block(props: BlockProps) { props.type !== "heading" && props.type !== "text" && `first:pt-0 sm:first:pt-0 pl-3 pr-3 sm:pl-4 sm:pr-4 pt-1 pb-2` - }`} + } + ${selectedBlocks.length > 1 ? "Multiple-Selected" : ""} + `} id={elementId.block(props.entityID).container} > {selected && selectedBlocks.length > 1 && (