@portabletext/plugin-dnd 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.dnd.tsx"],"mappings":";;;;;;;KAwCY;EACV,MAAM;EACN;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.dnd.tsx"],"mappings":";;;;;;;KAwCY;EACV,MAAM;EACN;;;;;;;;;;;;;;;;;;;;iBAmRc,YAAY;EAAQ,WAAW;oBAAU,IAAA;;;;;;;;;;;iBAyCzC,gBACd,MAAM,OACL"}
|
package/dist/index.js
CHANGED
|
@@ -104,12 +104,14 @@ function createDropPositionStore(getEditorElement) {
|
|
|
104
104
|
position: next.position
|
|
105
105
|
} : void 0;
|
|
106
106
|
let editorElement = getEditorElement();
|
|
107
|
-
if (editorElement)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
if (editorElement) {
|
|
108
|
+
if (current && !restoreCaretColor) {
|
|
109
|
+
let previousCaretColor = editorElement.style.caretColor;
|
|
110
|
+
restoreCaretColor = () => {
|
|
111
|
+
editorElement.style.caretColor = previousCaretColor;
|
|
112
|
+
}, editorElement.style.caretColor = "transparent";
|
|
113
|
+
} else !current && restoreCaretColor && (restoreCaretColor(), restoreCaretColor = void 0);
|
|
114
|
+
}
|
|
113
115
|
(previous?.serializedPath !== current?.serializedPath || previous?.position !== current?.position) && (previous?.serializedPath !== current?.serializedPath && notify(previous?.serializedPath), notify(current?.serializedPath));
|
|
114
116
|
}
|
|
115
117
|
};
|
|
@@ -184,7 +186,7 @@ function createDropPositionBehaviors(setDropPosition) {
|
|
|
184
186
|
}), forward(event)]]
|
|
185
187
|
}), defineBehavior({
|
|
186
188
|
on: "drag.*",
|
|
187
|
-
guard: ({ event }) => event.type !== "drag.dragover",
|
|
189
|
+
guard: ({ event }) => event.type !== "drag.dragover" && event.type !== "drag.drag",
|
|
188
190
|
actions: [({ event }) => [effect(() => {
|
|
189
191
|
setDropPosition(void 0);
|
|
190
192
|
}), forward(event)]]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n })","editor.dom","useMemo(\n () =>\n createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n }),\n [editor],\n )","createDropPositionBehaviors(store.set)","set","useMemo(\n () => createDropPositionBehaviors(store.set),\n [store],\n )","() => {\n return () => {\n // A drag in progress when the provider unmounts never delivers its\n // clearing event.\n store.set(undefined)\n }\n }","[store]","<BehaviorPlugin behaviors={behaviors} />","<DndContext.Provider value={store}>\n <BehaviorPlugin behaviors={behaviors} />\n {props.children}\n </DndContext.Provider>","children","DndContext.Provider","serializePath(path)","(callback: () => void) => store.subscribeKey(serializedPath, callback)","useCallback(\n (callback: () => void) => store.subscribeKey(serializedPath, callback),\n [store, serializedPath],\n )","() => store.get(serializedPath)"],"sources":["../src/drag-selection.ts","../src/plugin.dnd.tsx"],"sourcesContent":["import type {EditorSelection, EditorSnapshot} from '@portabletext/editor'\nimport {\n getFocusInlineObject,\n getFocusSpan,\n getFocusTextBlock,\n getFragment,\n getSelectionEndBlock,\n getSelectionStartBlock,\n isOverlappingSelection,\n isSelectionCollapsed,\n isSelectionExpanded,\n} from '@portabletext/editor/selectors'\nimport {getBlockEndPoint, getBlockStartPoint} from '@portabletext/editor/utils'\n\n/**\n * Given the current editor `snapshot` and an `eventSelection` representing\n * where the drag event originates from, calculate the selection in the\n * editor that should be dragged.\n *\n * Duplicated from the editor's internal `getDragSelection` rather than\n * imported: exporting it from core would add permanent public API for what\n * is an implementation detail of this plugin. Built on public selectors\n * only. Keep in sync with\n * `packages/editor/src/selectors/drag-selection.ts`.\n */\nexport function getDragSelection({\n eventSelection,\n snapshot,\n}: {\n eventSelection: NonNullable<EditorSelection>\n snapshot: EditorSnapshot\n}): NonNullable<EditorSelection> {\n let dragSelection = eventSelection\n\n const draggedInlineObject = getFocusInlineObject({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n\n if (draggedInlineObject) {\n return dragSelection\n }\n\n const draggingCollapsedSelection = isSelectionCollapsed({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n const draggedTextBlock = getFocusTextBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n const draggedSpan = getFocusSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n\n if (draggingCollapsedSelection && draggedTextBlock && draggedSpan) {\n // Looks like we are dragging an empty span\n // Let's drag the entire block instead\n dragSelection = {\n anchor: getBlockStartPoint({\n context: snapshot.context,\n block: draggedTextBlock,\n }),\n focus: getBlockEndPoint({\n context: snapshot.context,\n block: draggedTextBlock,\n }),\n }\n }\n\n const selectedBlocks = getFragment(snapshot)\n\n if (\n snapshot.context.selection &&\n isSelectionExpanded(snapshot) &&\n selectedBlocks.length > 1\n ) {\n const selectionStartBlock = getSelectionStartBlock(snapshot)\n const selectionEndBlock = getSelectionEndBlock(snapshot)\n\n if (!selectionStartBlock || !selectionEndBlock) {\n return dragSelection\n }\n\n const selectionStartPoint = getBlockStartPoint({\n context: snapshot.context,\n block: selectionStartBlock,\n })\n const selectionEndPoint = getBlockEndPoint({\n context: snapshot.context,\n block: selectionEndBlock,\n })\n\n const eventSelectionInsideBlocks = isOverlappingSelection(eventSelection)({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {anchor: selectionStartPoint, focus: selectionEndPoint},\n },\n })\n\n if (eventSelectionInsideBlocks) {\n dragSelection = {\n anchor: selectionStartPoint,\n focus: selectionEndPoint,\n }\n }\n }\n\n return dragSelection\n}\n","import {useEditor, type Path} from '@portabletext/editor'\nimport {\n defineBehavior,\n effect,\n forward,\n type Behavior,\n} from '@portabletext/editor/behaviors'\nimport {BehaviorPlugin} from '@portabletext/editor/plugins'\nimport {\n getFocusBlock,\n getFocusInlineObject,\n getFocusTextBlock,\n getSelectedBlocks,\n isSelectingEntireBlocks,\n} from '@portabletext/editor/selectors'\nimport {\n getBlockEndPoint,\n getBlockStartPoint,\n isEmptyTextBlock,\n isEqualPaths,\n isEqualSelectionPoints,\n isKeyedSegment,\n isSelectionCollapsed,\n} from '@portabletext/editor/utils'\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useSyncExternalStore,\n type ReactNode,\n} from 'react'\nimport {getDragSelection} from './drag-selection'\n\n/**\n * The block-relative position a drop would land at.\n *\n * @beta\n */\nexport type DropPosition = {\n path: Path\n position: 'start' | 'end'\n}\n\n/**\n * One store per editor: the drag behaviors below maintain the current drop\n * position, and per-path subscriber buckets make notification O(changed\n * paths) rather than O(subscribers). `dragover` fires at mousemove\n * frequency, so only the block losing and the block gaining the indicator\n * re-render.\n */\ntype DropPositionStore = {\n get: (serializedPath: string) => DropPosition['position'] | undefined\n subscribeKey: (serializedPath: string, callback: () => void) => () => void\n set: (next: DropPosition | undefined) => void\n}\n\nfunction createDropPositionStore(\n getEditorElement: () => HTMLElement | undefined,\n): DropPositionStore {\n let current:\n | {serializedPath: string; position: DropPosition['position']}\n | undefined\n let restoreCaretColor: (() => void) | undefined\n const subscribers = new Map<string, Set<() => void>>()\n\n function notify(serializedPath: string | undefined) {\n if (serializedPath === undefined) {\n return\n }\n\n const bucket = subscribers.get(serializedPath)\n\n if (bucket === undefined) {\n return\n }\n\n for (const callback of bucket) {\n callback()\n }\n }\n\n return {\n get: (serializedPath) =>\n current?.serializedPath === serializedPath ? current.position : undefined,\n subscribeKey: (serializedPath, callback) => {\n let bucket = subscribers.get(serializedPath)\n\n if (bucket === undefined) {\n bucket = new Set()\n subscribers.set(serializedPath, bucket)\n }\n\n bucket.add(callback)\n\n return () => {\n bucket.delete(callback)\n\n if (bucket.size === 0) {\n subscribers.delete(serializedPath)\n }\n }\n },\n set: (next) => {\n const previous = current\n\n // Swap before notifying: `useSyncExternalStore` re-reads the snapshot\n // synchronously on notification and skips the re-render when it reads\n // an unchanged (stale) value.\n current = next\n ? {serializedPath: serializePath(next.path), position: next.position}\n : undefined\n\n const editorElement = getEditorElement()\n\n if (editorElement) {\n if (current && !restoreCaretColor) {\n const previousCaretColor = editorElement.style.caretColor\n restoreCaretColor = () => {\n editorElement.style.caretColor = previousCaretColor\n }\n // The native drop caret renders at the hovered text position and\n // promises a mid-text split, but an edge indicator means the drop\n // will snap to the block edge instead.\n editorElement.style.caretColor = 'transparent'\n } else if (!current && restoreCaretColor) {\n restoreCaretColor()\n restoreCaretColor = undefined\n }\n }\n\n if (\n previous?.serializedPath === current?.serializedPath &&\n previous?.position === current?.position\n ) {\n return\n }\n\n if (previous?.serializedPath !== current?.serializedPath) {\n notify(previous?.serializedPath)\n }\n\n notify(current?.serializedPath)\n },\n }\n}\n\n/**\n * The behaviors observe the public `drag.*` events and `forward` every\n * event they handle: consumer behaviors run before the editor's own drag\n * handling, so omitting the forward would swallow the event and break the\n * drag itself. (The editor's internal drop-position tracking gets away\n * without forwarding because it registers below core priority.)\n */\nfunction createDropPositionBehaviors(\n setDropPosition: (next: DropPosition | undefined) => void,\n): Array<Behavior> {\n return [\n defineBehavior({\n on: 'drag.dragover',\n guard: ({snapshot, event}) => {\n const dropFocusBlock = getFocusBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: event.position.selection,\n },\n })\n\n if (!dropFocusBlock) {\n return false\n }\n\n const dragOrigin = event.dragOrigin\n\n if (!dragOrigin) {\n return false\n }\n\n const dragSelection = getDragSelection({\n eventSelection: dragOrigin.selection,\n snapshot,\n })\n const dragSnapshot = {\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: dragSelection,\n },\n }\n\n const draggedBlocks = getSelectedBlocks(dragSnapshot)\n // `getSelectedBlocks` only looks at root-level children, so a drag\n // origin nested inside a container (a callout paragraph, a table\n // cell) resolves to the container, not the nested block actually\n // being dragged. `getFocusBlock` resolves the origin's own focus to\n // the same depth `dropFocusBlock` was resolved to, so comparing the\n // two catches a nested block dragged over itself too.\n const draggedFocusBlock = getFocusBlock(dragSnapshot)\n\n const selfDrop =\n draggedBlocks.some(\n (draggedBlock) =>\n draggedBlock.node._key === dropFocusBlock.node._key,\n ) ||\n (draggedFocusBlock !== undefined &&\n isEqualPaths(draggedFocusBlock.path, dropFocusBlock.path))\n\n if (selfDrop) {\n // Core cancels the drop, so no position is valid here, including\n // one left over from the previous hover.\n return {dropFocusBlock, droppedInsideTextBlock: false, clear: true}\n }\n\n const draggingEntireBlocks = isSelectingEntireBlocks({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: dragSelection,\n },\n })\n\n if (!draggingEntireBlocks) {\n return false\n }\n\n const dropSnapshot = {\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: event.position.selection,\n },\n }\n const focusTextBlock = getFocusTextBlock(dropSnapshot)\n // A collapsed drop strictly inside a non-empty text block already\n // shows the browser's own drop caret there.\n const droppedInsideTextBlock =\n isSelectionCollapsed(event.position.selection) &&\n focusTextBlock !== undefined &&\n !isEmptyTextBlock(snapshot.context, focusTextBlock.node) &&\n getFocusInlineObject(dropSnapshot) === undefined &&\n !isEqualSelectionPoints(\n event.position.selection.focus,\n getBlockStartPoint({\n context: snapshot.context,\n block: focusTextBlock,\n }),\n ) &&\n !isEqualSelectionPoints(\n event.position.selection.focus,\n getBlockEndPoint({\n context: snapshot.context,\n block: focusTextBlock,\n }),\n )\n\n return {dropFocusBlock, droppedInsideTextBlock, clear: false}\n },\n actions: [\n ({event}, {dropFocusBlock, droppedInsideTextBlock, clear}) => [\n effect(() => {\n setDropPosition(\n clear || droppedInsideTextBlock\n ? undefined\n : {\n path: dropFocusBlock.path,\n position: event.position.block,\n },\n )\n }),\n forward(event),\n ],\n ],\n }),\n defineBehavior({\n on: 'drag.*',\n guard: ({event}) => event.type !== 'drag.dragover',\n actions: [\n ({event}) => [\n effect(() => {\n setDropPosition(undefined)\n }),\n forward(event),\n ],\n ],\n }),\n ]\n}\n\nconst DndContext = createContext<DropPositionStore | undefined>(undefined)\n\n/**\n * Tracks the drop position during drag and drop and serves it through\n * context. Mount inside `EditorProvider`, wrapping whatever reads the\n * position:\n *\n * ```tsx\n * <EditorProvider initialConfig={...}>\n * <DndProvider>\n * <PortableTextEditable />\n * </DndProvider>\n * </EditorProvider>\n * ```\n *\n * Reads via {@link useDropPosition} only re-render when the drop position\n * at their own path changes.\n *\n * @beta\n */\nexport function DndProvider(props: {children?: ReactNode}) {\n const editor = useEditor()\n const store = useMemo(\n () =>\n createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n }),\n [editor],\n )\n const behaviors = useMemo(\n () => createDropPositionBehaviors(store.set),\n [store],\n )\n\n useEffect(() => {\n return () => {\n // A drag in progress when the provider unmounts never delivers its\n // clearing event.\n store.set(undefined)\n }\n }, [store])\n\n return (\n <DndContext.Provider value={store}>\n <BehaviorPlugin behaviors={behaviors} />\n {props.children}\n </DndContext.Provider>\n )\n}\n\n/**\n * Read where a drop would land relative to the block at `path`: `'start'`,\n * `'end'`, or `undefined` when no drag is hovering this block. Re-renders\n * only when the position at this path changes.\n *\n * `path` is the keyed block path render callbacks receive, e.g.\n * `[{_key: 'b0'}]`.\n *\n * @beta\n */\nexport function useDropPosition(\n path: Path,\n): DropPosition['position'] | undefined {\n const store = useContext(DndContext)\n\n if (store === undefined) {\n throw new Error('useDropPosition must be used below a <DndProvider>')\n }\n\n // Callers typically pass a fresh `path` array every render, so the\n // serialized string, not the array, is what keeps `subscribe` stable\n // below.\n const serializedPath = serializePath(path)\n\n const subscribe = useCallback(\n (callback: () => void) => store.subscribeKey(serializedPath, callback),\n [store, serializedPath],\n )\n\n const getSnapshot = () => store.get(serializedPath)\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n\n/**\n * Serialize a keyed path to a string using Sanity's bracket notation.\n * Duplicated from the editor's internal `serializePath`; see\n * `drag-selection.ts` for the duplication rationale.\n */\nfunction serializePath(path: Path): string {\n return path.reduce<string>((result, segment, index) => {\n if (isKeyedSegment(segment)) {\n return `${result}[_key==\"${segment._key}\"]`\n }\n\n const separator = index === 0 ? '' : '.'\n return `${result}${separator}${segment}`\n }, '')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n })","editor.dom","useMemo(\n () =>\n createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n }),\n [editor],\n )","createDropPositionBehaviors(store.set)","set","useMemo(\n () => createDropPositionBehaviors(store.set),\n [store],\n )","() => {\n return () => {\n // A drag in progress when the provider unmounts never delivers its\n // clearing event.\n store.set(undefined)\n }\n }","[store]","<BehaviorPlugin behaviors={behaviors} />","<DndContext.Provider value={store}>\n <BehaviorPlugin behaviors={behaviors} />\n {props.children}\n </DndContext.Provider>","children","DndContext.Provider","serializePath(path)","(callback: () => void) => store.subscribeKey(serializedPath, callback)","useCallback(\n (callback: () => void) => store.subscribeKey(serializedPath, callback),\n [store, serializedPath],\n )","() => store.get(serializedPath)"],"sources":["../src/drag-selection.ts","../src/plugin.dnd.tsx"],"sourcesContent":["import type {EditorSelection, EditorSnapshot} from '@portabletext/editor'\nimport {\n getFocusInlineObject,\n getFocusSpan,\n getFocusTextBlock,\n getFragment,\n getSelectionEndBlock,\n getSelectionStartBlock,\n isOverlappingSelection,\n isSelectionCollapsed,\n isSelectionExpanded,\n} from '@portabletext/editor/selectors'\nimport {getBlockEndPoint, getBlockStartPoint} from '@portabletext/editor/utils'\n\n/**\n * Given the current editor `snapshot` and an `eventSelection` representing\n * where the drag event originates from, calculate the selection in the\n * editor that should be dragged.\n *\n * Duplicated from the editor's internal `getDragSelection` rather than\n * imported: exporting it from core would add permanent public API for what\n * is an implementation detail of this plugin. Built on public selectors\n * only. Keep in sync with\n * `packages/editor/src/selectors/drag-selection.ts`.\n */\nexport function getDragSelection({\n eventSelection,\n snapshot,\n}: {\n eventSelection: NonNullable<EditorSelection>\n snapshot: EditorSnapshot\n}): NonNullable<EditorSelection> {\n let dragSelection = eventSelection\n\n const draggedInlineObject = getFocusInlineObject({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n\n if (draggedInlineObject) {\n return dragSelection\n }\n\n const draggingCollapsedSelection = isSelectionCollapsed({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n const draggedTextBlock = getFocusTextBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n const draggedSpan = getFocusSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: eventSelection,\n },\n })\n\n if (draggingCollapsedSelection && draggedTextBlock && draggedSpan) {\n // Looks like we are dragging an empty span\n // Let's drag the entire block instead\n dragSelection = {\n anchor: getBlockStartPoint({\n context: snapshot.context,\n block: draggedTextBlock,\n }),\n focus: getBlockEndPoint({\n context: snapshot.context,\n block: draggedTextBlock,\n }),\n }\n }\n\n const selectedBlocks = getFragment(snapshot)\n\n if (\n snapshot.context.selection &&\n isSelectionExpanded(snapshot) &&\n selectedBlocks.length > 1\n ) {\n const selectionStartBlock = getSelectionStartBlock(snapshot)\n const selectionEndBlock = getSelectionEndBlock(snapshot)\n\n if (!selectionStartBlock || !selectionEndBlock) {\n return dragSelection\n }\n\n const selectionStartPoint = getBlockStartPoint({\n context: snapshot.context,\n block: selectionStartBlock,\n })\n const selectionEndPoint = getBlockEndPoint({\n context: snapshot.context,\n block: selectionEndBlock,\n })\n\n const eventSelectionInsideBlocks = isOverlappingSelection(eventSelection)({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {anchor: selectionStartPoint, focus: selectionEndPoint},\n },\n })\n\n if (eventSelectionInsideBlocks) {\n dragSelection = {\n anchor: selectionStartPoint,\n focus: selectionEndPoint,\n }\n }\n }\n\n return dragSelection\n}\n","import {useEditor, type Path} from '@portabletext/editor'\nimport {\n defineBehavior,\n effect,\n forward,\n type Behavior,\n} from '@portabletext/editor/behaviors'\nimport {BehaviorPlugin} from '@portabletext/editor/plugins'\nimport {\n getFocusBlock,\n getFocusInlineObject,\n getFocusTextBlock,\n getSelectedBlocks,\n isSelectingEntireBlocks,\n} from '@portabletext/editor/selectors'\nimport {\n getBlockEndPoint,\n getBlockStartPoint,\n isEmptyTextBlock,\n isEqualPaths,\n isEqualSelectionPoints,\n isKeyedSegment,\n isSelectionCollapsed,\n} from '@portabletext/editor/utils'\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useSyncExternalStore,\n type ReactNode,\n} from 'react'\nimport {getDragSelection} from './drag-selection'\n\n/**\n * The block-relative position a drop would land at.\n *\n * @beta\n */\nexport type DropPosition = {\n path: Path\n position: 'start' | 'end'\n}\n\n/**\n * One store per editor: the drag behaviors below maintain the current drop\n * position, and per-path subscriber buckets make notification O(changed\n * paths) rather than O(subscribers). `dragover` fires at mousemove\n * frequency, so only the block losing and the block gaining the indicator\n * re-render.\n */\ntype DropPositionStore = {\n get: (serializedPath: string) => DropPosition['position'] | undefined\n subscribeKey: (serializedPath: string, callback: () => void) => () => void\n set: (next: DropPosition | undefined) => void\n}\n\nfunction createDropPositionStore(\n getEditorElement: () => HTMLElement | undefined,\n): DropPositionStore {\n let current:\n | {serializedPath: string; position: DropPosition['position']}\n | undefined\n let restoreCaretColor: (() => void) | undefined\n const subscribers = new Map<string, Set<() => void>>()\n\n function notify(serializedPath: string | undefined) {\n if (serializedPath === undefined) {\n return\n }\n\n const bucket = subscribers.get(serializedPath)\n\n if (bucket === undefined) {\n return\n }\n\n for (const callback of bucket) {\n callback()\n }\n }\n\n return {\n get: (serializedPath) =>\n current?.serializedPath === serializedPath ? current.position : undefined,\n subscribeKey: (serializedPath, callback) => {\n let bucket = subscribers.get(serializedPath)\n\n if (bucket === undefined) {\n bucket = new Set()\n subscribers.set(serializedPath, bucket)\n }\n\n bucket.add(callback)\n\n return () => {\n bucket.delete(callback)\n\n if (bucket.size === 0) {\n subscribers.delete(serializedPath)\n }\n }\n },\n set: (next) => {\n const previous = current\n\n // Swap before notifying: `useSyncExternalStore` re-reads the snapshot\n // synchronously on notification and skips the re-render when it reads\n // an unchanged (stale) value.\n current = next\n ? {serializedPath: serializePath(next.path), position: next.position}\n : undefined\n\n const editorElement = getEditorElement()\n\n if (editorElement) {\n if (current && !restoreCaretColor) {\n const previousCaretColor = editorElement.style.caretColor\n restoreCaretColor = () => {\n editorElement.style.caretColor = previousCaretColor\n }\n // The native drop caret renders at the hovered text position and\n // promises a mid-text split, but an edge indicator means the drop\n // will snap to the block edge instead.\n editorElement.style.caretColor = 'transparent'\n } else if (!current && restoreCaretColor) {\n restoreCaretColor()\n restoreCaretColor = undefined\n }\n }\n\n if (\n previous?.serializedPath === current?.serializedPath &&\n previous?.position === current?.position\n ) {\n return\n }\n\n if (previous?.serializedPath !== current?.serializedPath) {\n notify(previous?.serializedPath)\n }\n\n notify(current?.serializedPath)\n },\n }\n}\n\n/**\n * The behaviors observe the public `drag.*` events and `forward` every\n * event they handle: consumer behaviors run before the editor's own drag\n * handling, so omitting the forward would swallow the event and break the\n * drag itself. (The editor's internal drop-position tracking gets away\n * without forwarding because it registers below core priority.)\n */\nfunction createDropPositionBehaviors(\n setDropPosition: (next: DropPosition | undefined) => void,\n): Array<Behavior> {\n return [\n defineBehavior({\n on: 'drag.dragover',\n guard: ({snapshot, event}) => {\n const dropFocusBlock = getFocusBlock({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: event.position.selection,\n },\n })\n\n if (!dropFocusBlock) {\n return false\n }\n\n const dragOrigin = event.dragOrigin\n\n if (!dragOrigin) {\n return false\n }\n\n const dragSelection = getDragSelection({\n eventSelection: dragOrigin.selection,\n snapshot,\n })\n const dragSnapshot = {\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: dragSelection,\n },\n }\n\n const draggedBlocks = getSelectedBlocks(dragSnapshot)\n // `getSelectedBlocks` only looks at root-level children, so a drag\n // origin nested inside a container (a callout paragraph, a table\n // cell) resolves to the container, not the nested block actually\n // being dragged. `getFocusBlock` resolves the origin's own focus to\n // the same depth `dropFocusBlock` was resolved to, so comparing the\n // two catches a nested block dragged over itself too.\n const draggedFocusBlock = getFocusBlock(dragSnapshot)\n\n const selfDrop =\n draggedBlocks.some(\n (draggedBlock) =>\n draggedBlock.node._key === dropFocusBlock.node._key,\n ) ||\n (draggedFocusBlock !== undefined &&\n isEqualPaths(draggedFocusBlock.path, dropFocusBlock.path))\n\n if (selfDrop) {\n // Core cancels the drop, so no position is valid here, including\n // one left over from the previous hover.\n return {dropFocusBlock, droppedInsideTextBlock: false, clear: true}\n }\n\n const draggingEntireBlocks = isSelectingEntireBlocks({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: dragSelection,\n },\n })\n\n if (!draggingEntireBlocks) {\n return false\n }\n\n const dropSnapshot = {\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: event.position.selection,\n },\n }\n const focusTextBlock = getFocusTextBlock(dropSnapshot)\n // A collapsed drop strictly inside a non-empty text block already\n // shows the browser's own drop caret there.\n const droppedInsideTextBlock =\n isSelectionCollapsed(event.position.selection) &&\n focusTextBlock !== undefined &&\n !isEmptyTextBlock(snapshot.context, focusTextBlock.node) &&\n getFocusInlineObject(dropSnapshot) === undefined &&\n !isEqualSelectionPoints(\n event.position.selection.focus,\n getBlockStartPoint({\n context: snapshot.context,\n block: focusTextBlock,\n }),\n ) &&\n !isEqualSelectionPoints(\n event.position.selection.focus,\n getBlockEndPoint({\n context: snapshot.context,\n block: focusTextBlock,\n }),\n )\n\n return {dropFocusBlock, droppedInsideTextBlock, clear: false}\n },\n actions: [\n ({event}, {dropFocusBlock, droppedInsideTextBlock, clear}) => [\n effect(() => {\n setDropPosition(\n clear || droppedInsideTextBlock\n ? undefined\n : {\n path: dropFocusBlock.path,\n position: event.position.block,\n },\n )\n }),\n forward(event),\n ],\n ],\n }),\n defineBehavior({\n on: 'drag.*',\n guard: ({event}) =>\n // `drag.drag` fires continuously on the drag source between\n // `dragover`s. Clearing on it would toggle the drop position (and\n // the caret-color write on the editor root) on every pointer move,\n // and each write invalidates layout for the whole page right before\n // the next drag event reads element rects: a forced reflow per move,\n // scaling with page size.\n event.type !== 'drag.dragover' && event.type !== 'drag.drag',\n actions: [\n ({event}) => [\n effect(() => {\n setDropPosition(undefined)\n }),\n forward(event),\n ],\n ],\n }),\n ]\n}\n\nconst DndContext = createContext<DropPositionStore | undefined>(undefined)\n\n/**\n * Tracks the drop position during drag and drop and serves it through\n * context. Mount inside `EditorProvider`, wrapping whatever reads the\n * position:\n *\n * ```tsx\n * <EditorProvider initialConfig={...}>\n * <DndProvider>\n * <PortableTextEditable />\n * </DndProvider>\n * </EditorProvider>\n * ```\n *\n * Reads via {@link useDropPosition} only re-render when the drop position\n * at their own path changes.\n *\n * @beta\n */\nexport function DndProvider(props: {children?: ReactNode}) {\n const editor = useEditor()\n const store = useMemo(\n () =>\n createDropPositionStore(() => {\n const editorElement = editor.dom.getEditorElement()\n return editorElement instanceof HTMLElement ? editorElement : undefined\n }),\n [editor],\n )\n const behaviors = useMemo(\n () => createDropPositionBehaviors(store.set),\n [store],\n )\n\n useEffect(() => {\n return () => {\n // A drag in progress when the provider unmounts never delivers its\n // clearing event.\n store.set(undefined)\n }\n }, [store])\n\n return (\n <DndContext.Provider value={store}>\n <BehaviorPlugin behaviors={behaviors} />\n {props.children}\n </DndContext.Provider>\n )\n}\n\n/**\n * Read where a drop would land relative to the block at `path`: `'start'`,\n * `'end'`, or `undefined` when no drag is hovering this block. Re-renders\n * only when the position at this path changes.\n *\n * `path` is the keyed block path render callbacks receive, e.g.\n * `[{_key: 'b0'}]`.\n *\n * @beta\n */\nexport function useDropPosition(\n path: Path,\n): DropPosition['position'] | undefined {\n const store = useContext(DndContext)\n\n if (store === undefined) {\n throw new Error('useDropPosition must be used below a <DndProvider>')\n }\n\n // Callers typically pass a fresh `path` array every render, so the\n // serialized string, not the array, is what keeps `subscribe` stable\n // below.\n const serializedPath = serializePath(path)\n\n const subscribe = useCallback(\n (callback: () => void) => store.subscribeKey(serializedPath, callback),\n [store, serializedPath],\n )\n\n const getSnapshot = () => store.get(serializedPath)\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n}\n\n/**\n * Serialize a keyed path to a string using Sanity's bracket notation.\n * Duplicated from the editor's internal `serializePath`; see\n * `drag-selection.ts` for the duplication rationale.\n */\nfunction serializePath(path: Path): string {\n return path.reduce<string>((result, segment, index) => {\n if (isKeyedSegment(segment)) {\n return `${result}[_key==\"${segment._key}\"]`\n }\n\n const separator = index === 0 ? '' : '.'\n return `${result}${separator}${segment}`\n }, '')\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/plugin-dnd",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Track the drop position during drag and drop for custom drop indicators",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dnd",
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"typescript": "^7.0.2",
|
|
44
44
|
"vite": "^8.2.0",
|
|
45
45
|
"vitest": "^4.1.11",
|
|
46
|
-
"@portabletext/editor": "^8.1.
|
|
47
|
-
"@portabletext/
|
|
48
|
-
"@portabletext/
|
|
46
|
+
"@portabletext/editor": "^8.1.1",
|
|
47
|
+
"@portabletext/test": "^2.1.0",
|
|
48
|
+
"@portabletext/schema": "^3.0.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"react": "^19.2",
|
|
52
|
-
"@portabletext/editor": "^8.1.
|
|
52
|
+
"@portabletext/editor": "^8.1.1"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": ">=22.12"
|