@udecode/plate-selection
Advanced tools
Comparing version 39.1.2 to 39.1.4
@@ -85,44 +85,48 @@ "use strict"; | ||
// src/lib/isSelecting.ts | ||
var import_plate_common9 = require("@udecode/plate-common"); | ||
var import_plate_common11 = require("@udecode/plate-common"); | ||
// src/react/BlockContextMenuPlugin.tsx | ||
// src/react/BlockMenuPlugin.tsx | ||
var import_react = require("@udecode/plate-common/react"); | ||
var BlockContextMenuPlugin = (0, import_react.createTPlatePlugin)({ | ||
key: "blockContextMenu", | ||
var BLOCK_CONTEXT_MENU_ID = "context"; | ||
var BlockMenuPlugin = (0, import_react.createTPlatePlugin)({ | ||
key: "blockMenu", | ||
options: { | ||
action: { group: null, value: null }, | ||
anchorRect: { x: 0, y: 0 }, | ||
openEditorId: null, | ||
store: null | ||
openId: null, | ||
position: { | ||
x: -1e4, | ||
y: -1e4 | ||
} | ||
} | ||
}).extendApi(({ getOptions, setOptions }) => ({ | ||
}).extendApi(({ setOption, setOptions }) => ({ | ||
hide: () => { | ||
setOptions({ | ||
anchorRect: { x: 0, y: 0 }, | ||
openEditorId: null | ||
openId: null, | ||
position: { | ||
x: -1e4, | ||
y: -1e4 | ||
} | ||
}); | ||
}, | ||
reset: () => { | ||
setOptions({ anchorRect: { x: 0, y: 0 } }); | ||
}, | ||
show: (editorId, event) => { | ||
const { store } = getOptions(); | ||
setOptions({ | ||
anchorRect: { x: event.clientX, y: event.clientY }, | ||
openEditorId: editorId | ||
}); | ||
if (store) { | ||
store.show(); | ||
store.setAutoFocusOnShow(true); | ||
store.setInitialFocus("first"); | ||
show: (id, position) => { | ||
if (position) { | ||
setOptions({ | ||
openId: id, | ||
position | ||
}); | ||
} else { | ||
setOption("openId", id); | ||
} | ||
} | ||
})).extendOptions(({ getOptions }) => ({ | ||
isOpen: (editorId) => getOptions().openEditorId === editorId | ||
})).extendApi(({ api, editor }) => ({ | ||
showContextMenu: (blockId, position) => { | ||
var _a; | ||
(_a = editor.getApi({ key: "blockSelection" }).blockSelection) == null ? void 0 : _a.addSelectedRow(blockId); | ||
api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, position); | ||
} | ||
})).extend(({ api }) => ({ | ||
handlers: { | ||
onMouseDown: ({ editor, event, getOption }) => { | ||
if (event.button === 0 && getOption("isOpen", editor.id)) { | ||
onMouseDown: ({ event, getOptions }) => { | ||
if (event.button === 0 && getOptions().openId) { | ||
event.preventDefault(); | ||
api.blockContextMenu.hide(); | ||
api.blockMenu.hide(); | ||
} | ||
@@ -135,15 +139,106 @@ if (event.button === 2) event.preventDefault(); | ||
// src/react/BlockSelectionPlugin.tsx | ||
var import_plate_common8 = require("@udecode/plate-common"); | ||
var import_react7 = __toESM(require("react")); | ||
var import_react_dom = __toESM(require("react-dom")); | ||
var import_plate_common9 = require("@udecode/plate-common"); | ||
var import_plate_common10 = require("@udecode/plate-common"); | ||
var import_react8 = require("@udecode/plate-common/react"); | ||
var import_react9 = require("@udecode/plate-common/react"); | ||
// src/react/BlockSelectionAfterEditable.tsx | ||
var import_react5 = __toESM(require("react")); | ||
var import_react_dom = __toESM(require("react-dom")); | ||
var import_plate_common5 = require("@udecode/plate-common"); | ||
var import_react6 = require("@udecode/plate-common/react"); | ||
// src/react/useSelectionArea.ts | ||
// src/react/components/BlockSelectable.tsx | ||
var import_react2 = __toESM(require("react")); | ||
var import_plate_common = require("@udecode/plate-common"); | ||
var import_react3 = require("@udecode/plate-common/react"); | ||
var import_slate = require("slate"); | ||
var { BlockSelectableProvider, useBlockSelectableStore } = (0, import_react3.createAtomStore)( | ||
{ | ||
selectable: false | ||
}, | ||
{ name: "blockSelectable" } | ||
); | ||
var useBlockSelectableState = ({ | ||
active, | ||
element | ||
}) => { | ||
const { editor, getOptions } = (0, import_react3.useEditorPlugin)(BlockSelectionPlugin); | ||
const ref = (0, import_react2.useRef)(null); | ||
const path = import_react2.default.useMemo( | ||
() => (0, import_react3.findNodePath)(editor, element), | ||
[editor, element] | ||
); | ||
if (!path || (0, import_plate_common.isInline)(editor, element)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
const { query } = getOptions(); | ||
if (query && !(0, import_plate_common.queryNode)([element, path], query)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
return { | ||
active: active != null ? active : true, | ||
element, | ||
path, | ||
ref | ||
}; | ||
}; | ||
var useBlockSelectable = ({ | ||
active, | ||
element, | ||
path, | ||
ref | ||
}) => { | ||
const { api, editor, getOption, getOptions } = (0, import_react3.useEditorPlugin)(BlockSelectionPlugin); | ||
const id = element == null ? void 0 : element.id; | ||
const data = { "data-key": id }; | ||
return { | ||
props: __spreadValues({ | ||
className: "slate-selectable", | ||
ref, | ||
onContextMenu: (event) => { | ||
var _a, _b; | ||
if (!element || !active) return; | ||
const { enableContextMenu } = getOptions(); | ||
if (!enableContextMenu) return; | ||
if ((_a = editor.selection) == null ? void 0 : _a.focus) { | ||
const nodeEntry = (0, import_plate_common.getAboveNode)(editor); | ||
if (nodeEntry && import_slate.Path.isCommon(path, nodeEntry[1])) { | ||
const id2 = nodeEntry[0].id; | ||
const isSelected = getOption("isSelected", id2); | ||
const isOpenAlways = ((_b = event.target.dataset) == null ? void 0 : _b.openContextMenu) === "true"; | ||
if (!isSelected && !(0, import_plate_common.isVoid)(editor, nodeEntry[0]) && !isOpenAlways) | ||
return event.stopPropagation(); | ||
} | ||
} | ||
const aboveHtmlNode = ref.current; | ||
if (id && aboveHtmlNode) { | ||
api.blockSelection.addSelectedRow(id, { | ||
aboveHtmlNode, | ||
clear: !(event == null ? void 0 : event.shiftKey) | ||
}); | ||
} | ||
} | ||
}, data) | ||
}; | ||
}; | ||
function BlockSelectable(_a) { | ||
var _b = _a, { | ||
children, | ||
options | ||
} = _b, props = __objRest(_b, [ | ||
"children", | ||
"options" | ||
]); | ||
const state = useBlockSelectableState(options); | ||
const blockSelectable = useBlockSelectable(state); | ||
if (!state.active) | ||
return /* @__PURE__ */ import_react2.default.createElement(BlockSelectableProvider, null, children); | ||
return /* @__PURE__ */ import_react2.default.createElement(BlockSelectableProvider, { selectable: true }, /* @__PURE__ */ import_react2.default.createElement("div", __spreadValues(__spreadValues({}, blockSelectable.props), props), children)); | ||
} | ||
// src/react/hooks/useSelectionArea.ts | ||
var import_react4 = __toESM(require("react")); | ||
var import_react5 = require("@udecode/plate-common/react"); | ||
// src/internal/EventEmitter.ts | ||
@@ -607,3 +702,3 @@ var EventTarget = class { | ||
this._container = selectAll(container, document2)[0]; | ||
if (this._container.contains(target) && target.dataset.plateSelectable !== "true") | ||
if (this._container.contains(target) && target.dataset.slateEditor !== "true" && target.dataset.plateSelectable !== "true") | ||
return; | ||
@@ -896,7 +991,7 @@ this._containerRect = this._container.getBoundingClientRect(); | ||
// src/react/useSelectionArea.ts | ||
// src/react/hooks/useSelectionArea.ts | ||
var useSelectionArea = () => { | ||
const { api, editor, getOptions, setOption } = (0, import_react3.useEditorPlugin)(BlockSelectionPlugin); | ||
const { api, editor, getOptions, setOption } = (0, import_react5.useEditorPlugin)(BlockSelectionPlugin); | ||
const { areaOptions } = getOptions(); | ||
import_react2.default.useEffect(() => { | ||
import_react4.default.useEffect(() => { | ||
const selection = new SelectionArea(__spreadValues({ | ||
@@ -906,3 +1001,3 @@ document: window.document | ||
setOption("isSelectionAreaVisible", true); | ||
(0, import_react3.deselectEditor)(editor); | ||
(0, import_react5.deselectEditor)(editor); | ||
if (!(event == null ? void 0 : event.shiftKey)) { | ||
@@ -925,12 +1020,96 @@ selection.clearSelection(); | ||
// src/react/onKeyDownSelection.ts | ||
var import_plate_common2 = require("@udecode/plate-common"); | ||
var onKeyDownSelection = ({ | ||
api, | ||
editor, | ||
event | ||
}) => { | ||
if ((0, import_plate_common2.isHotkey)("mod+a", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common2.getAncestorNode)(editor); | ||
if (!ancestorNode) return; | ||
const [, path] = ancestorNode; | ||
if ((0, import_plate_common2.isSelectionCoverBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
if (!(0, import_plate_common2.isRangeInSameBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
(0, import_plate_common2.select)(editor, path); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
if ((0, import_plate_common2.isHotkey)("escape", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common2.getAncestorNode)(editor); | ||
const id = ancestorNode == null ? void 0 : ancestorNode[0].id; | ||
api.blockSelection.addSelectedRow(id); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
}; | ||
// src/react/transforms/duplicateBlockSelectionNodes.ts | ||
var import_plate_common3 = require("@udecode/plate-common"); | ||
var import_slate2 = require("slate"); | ||
var duplicateBlockSelectionNodes = (editor, blocks) => { | ||
(0, import_plate_common3.duplicateBlocks)(editor, blocks); | ||
const lastBlock = blocks.at(-1); | ||
if (!lastBlock) return; | ||
const path = import_slate2.Path.next(lastBlock[1]); | ||
const ids = blocks.map((_, index) => { | ||
const targetPath = [path[0] + index]; | ||
const targetNode = (0, import_plate_common3.getNodeEntry)(editor, targetPath); | ||
return targetNode == null ? void 0 : targetNode[0].id; | ||
}).filter(Boolean); | ||
setTimeout(() => { | ||
editor.getApi(BlockSelectionPlugin).blockSelection.setSelectedIds({ ids }); | ||
}, 0); | ||
}; | ||
// src/react/transforms/removeBlockSelectionNodes.ts | ||
var removeBlockSelectionNodes = (editor) => { | ||
const selectedIds = editor.getOption(BlockSelectionPlugin, "selectedIds"); | ||
if (!selectedIds) return; | ||
editor.removeNodes({ | ||
at: [], | ||
match: (n) => selectedIds.has(n.id) | ||
}); | ||
}; | ||
// src/react/transforms/selectBlockSelectionNodes.ts | ||
var import_plate_common4 = require("@udecode/plate-common"); | ||
var selectBlockSelectionNodes = (editor) => { | ||
(0, import_plate_common4.selectNodes)( | ||
editor, | ||
editor.getApi(BlockSelectionPlugin).blockSelection.getNodes() | ||
); | ||
editor.getApi(BlockSelectionPlugin).blockSelection.resetSelectedIds(); | ||
}; | ||
// src/react/transforms/setBlockSelectionNodes.ts | ||
var import_plate_common5 = require("@udecode/plate-common"); | ||
var setBlockSelectionNodes = (editor, props, options) => { | ||
(0, import_plate_common5.withoutNormalizing)(editor, () => { | ||
const blocks = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes(); | ||
blocks.forEach(([, path]) => { | ||
(0, import_plate_common5.setNodes)(editor, props, __spreadProps(__spreadValues({}, options), { | ||
at: path | ||
})); | ||
}); | ||
}); | ||
}; | ||
var setBlockSelectionTexts = (editor, props, options) => { | ||
setBlockSelectionNodes(editor, props, __spreadValues({ | ||
mode: "lowest" | ||
}, options)); | ||
}; | ||
// src/react/utils/copySelectedBlocks.ts | ||
var import_plate_common = require("@udecode/plate-common"); | ||
var import_plate_common6 = require("@udecode/plate-common"); | ||
var import_copy_to_clipboard = __toESM(require("copy-to-clipboard")); | ||
var copySelectedBlocks = (editor) => { | ||
const { api, getOptions, setOption } = (0, import_plate_common.getEditorPlugin)( | ||
editor, | ||
BlockSelectionPlugin | ||
); | ||
const { selectedIds } = getOptions(); | ||
const selectedEntries = api.blockSelection.getSelectedBlocks(); | ||
const { selectedIds } = editor.getOptions(BlockSelectionPlugin); | ||
const selectedEntries = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes(); | ||
const selectedFragment = selectedEntries.map(([node]) => node); | ||
@@ -943,7 +1122,7 @@ (0, import_copy_to_clipboard.default)(" ", { | ||
const div = document.createElement("div"); | ||
(0, import_plate_common.withoutNormalizing)(editor, () => { | ||
(0, import_plate_common6.withoutNormalizing)(editor, () => { | ||
selectedEntries.forEach(([, path]) => { | ||
(0, import_plate_common.select)(editor, { | ||
anchor: (0, import_plate_common.getStartPoint)(editor, path), | ||
focus: (0, import_plate_common.getEndPoint)(editor, path) | ||
(0, import_plate_common6.select)(editor, { | ||
anchor: (0, import_plate_common6.getStartPoint)(editor, path), | ||
focus: (0, import_plate_common6.getEndPoint)(editor, path) | ||
}); | ||
@@ -957,4 +1136,4 @@ editor.setFragmentData(data); | ||
}); | ||
(0, import_plate_common.deselect)(editor); | ||
setOption("selectedIds", selectedIds); | ||
(0, import_plate_common6.deselect)(editor); | ||
editor.setOption(BlockSelectionPlugin, "selectedIds", selectedIds); | ||
}); | ||
@@ -973,3 +1152,2 @@ data.setData("text/plain", textPlain); | ||
// src/react/utils/onChangeBlockSelection.ts | ||
var import_plate_common2 = require("@udecode/plate-common"); | ||
var onChangeBlockSelection = ({ | ||
@@ -980,6 +1158,5 @@ api, | ||
}) => { | ||
const blockContextMenu = (0, import_plate_common2.getEditorPlugin)(editor, BlockContextMenuPlugin); | ||
if (editor.selection && getOptions().isSelecting && !blockContextMenu.getOption("isOpen", editor.id)) { | ||
if (editor.selection && getOptions().isSelecting && !editor.getOption(BlockMenuPlugin, "openId")) { | ||
api.blockSelection.unselect(); | ||
blockContextMenu.api.blockContextMenu.hide(); | ||
editor.getApi(BlockMenuPlugin).blockMenu.hide(); | ||
} | ||
@@ -989,13 +1166,13 @@ }; | ||
// src/react/utils/pasteSelectedBlocks.ts | ||
var import_plate_common4 = require("@udecode/plate-common"); | ||
var import_react4 = require("@udecode/plate-common/react"); | ||
var import_slate = require("slate"); | ||
var import_plate_common8 = require("@udecode/plate-common"); | ||
var import_react6 = require("@udecode/plate-common/react"); | ||
var import_slate3 = require("slate"); | ||
// src/react/utils/selectInsertedBlocks.ts | ||
var import_plate_common3 = require("@udecode/plate-common"); | ||
var import_plate_common7 = require("@udecode/plate-common"); | ||
var selectInsertedBlocks = (editor) => { | ||
const { setOption } = (0, import_plate_common3.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const { setOption } = (0, import_plate_common7.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const ids = /* @__PURE__ */ new Set(); | ||
editor.operations.forEach((op) => { | ||
if (op.type === "insert_node" && op.node.id && (0, import_plate_common3.isBlock)(editor, op.node)) { | ||
if (op.type === "insert_node" && op.node.id && (0, import_plate_common7.isBlock)(editor, op.node)) { | ||
ids.add(op.node.id); | ||
@@ -1011,11 +1188,11 @@ } | ||
var pasteSelectedBlocks = (editor, e) => { | ||
const { api } = (0, import_plate_common4.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const entries = api.blockSelection.getSelectedBlocks(); | ||
const { api } = (0, import_plate_common8.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const entries = api.blockSelection.getNodes(); | ||
if (entries.length > 0) { | ||
const entry = entries.at(-1); | ||
const [node, path] = entry; | ||
(0, import_react4.focusEditor)(editor, (0, import_plate_common4.getStartPoint)(editor, path)); | ||
if (!(0, import_plate_common4.isElementEmpty)(editor, node)) { | ||
const at = import_slate.Path.next(path); | ||
(0, import_plate_common4.insertNodes)(editor, editor.api.create.block({}, at), { | ||
(0, import_react6.focusEditor)(editor, (0, import_plate_common8.getStartPoint)(editor, path)); | ||
if (!(0, import_plate_common8.isElementEmpty)(editor, node)) { | ||
const at = import_slate3.Path.next(path); | ||
(0, import_plate_common8.insertNodes)(editor, editor.api.create.block({}, at), { | ||
at, | ||
@@ -1025,4 +1202,4 @@ select: true | ||
} | ||
(0, import_react4.insertData)(editor, e.clipboardData); | ||
(0, import_plate_common4.deselect)(editor); | ||
(0, import_react6.insertData)(editor, e.clipboardData); | ||
(0, import_plate_common8.deselect)(editor); | ||
selectInsertedBlocks(editor); | ||
@@ -1032,14 +1209,12 @@ } | ||
// src/react/BlockSelectionAfterEditable.tsx | ||
// src/react/BlockSelectionPlugin.tsx | ||
var BlockSelectionAfterEditable = () => { | ||
const editor = (0, import_react6.useEditorRef)(); | ||
const { api, getOption, getOptions, useOption } = (0, import_react6.useEditorPlugin)(BlockSelectionPlugin); | ||
const editor = (0, import_react9.useEditorRef)(); | ||
const { api, getOption, getOptions, useOption } = (0, import_react9.useEditorPlugin)({ key: "blockSelection" }); | ||
const isSelecting2 = useOption("isSelecting"); | ||
const selectedIds = useOption("selectedIds"); | ||
const blockContextMenu = (0, import_react6.useEditorPlugin)(BlockContextMenuPlugin); | ||
const isOpen = blockContextMenu.useOption("isOpen", editor.id); | ||
useSelectionArea(); | ||
const inputRef = import_react5.default.useRef(null); | ||
const [isMounted, setIsMounted] = import_react5.default.useState(false); | ||
import_react5.default.useEffect(() => { | ||
const inputRef = import_react7.default.useRef(null); | ||
const [isMounted, setIsMounted] = import_react7.default.useState(false); | ||
import_react7.default.useEffect(() => { | ||
setIsMounted(true); | ||
@@ -1050,4 +1225,4 @@ return () => { | ||
}, []); | ||
import_react5.default.useEffect(() => { | ||
if (isSelecting2 && !isOpen && inputRef.current) { | ||
import_react7.default.useEffect(() => { | ||
if (isSelecting2 && inputRef.current) { | ||
inputRef.current.focus(); | ||
@@ -1057,17 +1232,17 @@ } else if (inputRef.current) { | ||
} | ||
}, [isSelecting2, isOpen]); | ||
const handleKeyDown = import_react5.default.useCallback( | ||
}, [isSelecting2]); | ||
const handleKeyDown = import_react7.default.useCallback( | ||
(e) => { | ||
var _a, _b; | ||
const isReadonly = (0, import_react6.isEditorReadOnly)(editor); | ||
const isReadonly = (0, import_react9.isEditorReadOnly)(editor); | ||
(_b = (_a = getOptions()).onKeyDownSelecting) == null ? void 0 : _b.call(_a, e.nativeEvent); | ||
if (!getOptions().isSelecting) return; | ||
if ((0, import_plate_common5.isHotkey)("escape")(e)) { | ||
if ((0, import_plate_common10.isHotkey)("escape")(e)) { | ||
api.blockSelection.unselect(); | ||
} | ||
if ((0, import_plate_common5.isHotkey)("mod+z")(e)) { | ||
if ((0, import_plate_common10.isHotkey)("mod+z")(e)) { | ||
editor.undo(); | ||
selectInsertedBlocks(editor); | ||
} | ||
if ((0, import_plate_common5.isHotkey)("mod+shift+z")(e)) { | ||
if ((0, import_plate_common10.isHotkey)("mod+shift+z")(e)) { | ||
editor.redo(); | ||
@@ -1077,4 +1252,4 @@ selectInsertedBlocks(editor); | ||
if (!getOption("isSelectingSome")) return; | ||
if ((0, import_plate_common5.isHotkey)("enter")(e)) { | ||
const entry = (0, import_plate_common5.findNode)(editor, { | ||
if ((0, import_plate_common10.isHotkey)("enter")(e)) { | ||
const entry = (0, import_plate_common10.findNode)(editor, { | ||
at: [], | ||
@@ -1085,8 +1260,8 @@ match: (n) => selectedIds.has(n.id) | ||
const [, path] = entry; | ||
(0, import_react6.focusEditor)(editor, (0, import_plate_common5.getEndPoint)(editor, path)); | ||
(0, import_react9.focusEditor)(editor, (0, import_plate_common10.getEndPoint)(editor, path)); | ||
e.preventDefault(); | ||
} | ||
} | ||
if ((0, import_plate_common5.isHotkey)(["backspace", "delete"])(e) && !isReadonly) { | ||
(0, import_plate_common5.removeNodes)(editor, { | ||
if ((0, import_plate_common10.isHotkey)(["backspace", "delete"])(e) && !isReadonly) { | ||
(0, import_plate_common10.removeNodes)(editor, { | ||
at: [], | ||
@@ -1096,9 +1271,9 @@ match: (n) => selectedIds.has(n.id) | ||
} | ||
if ((0, import_plate_common5.isHotkey)("up")(e)) { | ||
if ((0, import_plate_common10.isHotkey)("up")(e)) { | ||
const firstId = [...selectedIds][0]; | ||
const node = (0, import_plate_common5.findNode)(editor, { | ||
const node = (0, import_plate_common10.findNode)(editor, { | ||
at: [], | ||
match: (n) => n.id === firstId | ||
}); | ||
const prev = (0, import_plate_common5.getPreviousNode)(editor, { | ||
const prev = (0, import_plate_common10.getPreviousNode)(editor, { | ||
at: node == null ? void 0 : node[1] | ||
@@ -1109,9 +1284,9 @@ }); | ||
} | ||
if ((0, import_plate_common5.isHotkey)("down")(e)) { | ||
if ((0, import_plate_common10.isHotkey)("down")(e)) { | ||
const lastId = [...selectedIds].pop(); | ||
const node = (0, import_plate_common5.findNode)(editor, { | ||
const node = (0, import_plate_common10.findNode)(editor, { | ||
at: [], | ||
match: (n) => n.id === lastId | ||
}); | ||
const next = (0, import_plate_common5.getNextNode)(editor, { | ||
const next = (0, import_plate_common10.getNextNode)(editor, { | ||
at: node == null ? void 0 : node[1] | ||
@@ -1125,3 +1300,3 @@ }); | ||
); | ||
const handleCopy = import_react5.default.useCallback( | ||
const handleCopy = import_react7.default.useCallback( | ||
(e) => { | ||
@@ -1135,3 +1310,3 @@ e.preventDefault(); | ||
); | ||
const handleCut = import_react5.default.useCallback( | ||
const handleCut = import_react7.default.useCallback( | ||
(e) => { | ||
@@ -1141,8 +1316,8 @@ e.preventDefault(); | ||
copySelectedBlocks(editor); | ||
if (!(0, import_react6.isEditorReadOnly)(editor)) { | ||
(0, import_plate_common5.removeNodes)(editor, { | ||
if (!(0, import_react9.isEditorReadOnly)(editor)) { | ||
(0, import_plate_common10.removeNodes)(editor, { | ||
at: [], | ||
match: (n) => selectedIds.has(n.id) | ||
}); | ||
(0, import_react6.focusEditor)(editor); | ||
(0, import_react9.focusEditor)(editor); | ||
} | ||
@@ -1153,6 +1328,6 @@ } | ||
); | ||
const handlePaste = import_react5.default.useCallback( | ||
const handlePaste = import_react7.default.useCallback( | ||
(e) => { | ||
e.preventDefault(); | ||
if (!(0, import_react6.isEditorReadOnly)(editor)) { | ||
if (!(0, import_react9.isEditorReadOnly)(editor)) { | ||
pasteSelectedBlocks(editor, e.nativeEvent); | ||
@@ -1167,3 +1342,3 @@ } | ||
return import_react_dom.default.createPortal( | ||
/* @__PURE__ */ import_react5.default.createElement( | ||
/* @__PURE__ */ import_react7.default.createElement( | ||
"input", | ||
@@ -1189,130 +1364,3 @@ { | ||
}; | ||
// src/react/components/BlockSelectable.tsx | ||
var import_react7 = __toESM(require("react")); | ||
var import_plate_common6 = require("@udecode/plate-common"); | ||
var import_react8 = require("@udecode/plate-common/react"); | ||
var import_slate2 = require("slate"); | ||
var { BlockSelectableProvider, useBlockSelectableStore } = (0, import_react8.createAtomStore)( | ||
{ | ||
selectable: false | ||
}, | ||
{ name: "blockSelectable" } | ||
); | ||
var useBlockSelectableState = ({ | ||
active, | ||
element | ||
}) => { | ||
const { editor, getOptions } = (0, import_react8.useEditorPlugin)(BlockSelectionPlugin); | ||
const ref = (0, import_react7.useRef)(null); | ||
const path = import_react7.default.useMemo( | ||
() => (0, import_react8.findNodePath)(editor, element), | ||
[editor, element] | ||
); | ||
if (!path || (0, import_plate_common6.isInline)(editor, element)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
const { query } = getOptions(); | ||
if (query && !(0, import_plate_common6.queryNode)([element, path], query)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
return { | ||
active: active != null ? active : true, | ||
element, | ||
path, | ||
ref | ||
}; | ||
}; | ||
var useBlockSelectable = ({ | ||
active, | ||
element, | ||
path, | ||
ref | ||
}) => { | ||
const { api, editor, getOption, getOptions } = (0, import_react8.useEditorPlugin)(BlockSelectionPlugin); | ||
const id = element == null ? void 0 : element.id; | ||
const data = { "data-key": id }; | ||
return { | ||
props: __spreadValues({ | ||
className: "slate-selectable", | ||
ref, | ||
onContextMenu: (event) => { | ||
var _a, _b; | ||
if (!element || !active) return; | ||
const { enableContextMenu } = getOptions(); | ||
if (!enableContextMenu) return; | ||
if ((_a = editor.selection) == null ? void 0 : _a.focus) { | ||
const nodeEntry = (0, import_plate_common6.getAboveNode)(editor); | ||
if (nodeEntry && import_slate2.Path.isCommon(path, nodeEntry[1])) { | ||
const id2 = nodeEntry[0].id; | ||
const isSelected = getOption("isSelected", id2); | ||
const isOpenAlways = ((_b = event.target.dataset) == null ? void 0 : _b.openContextMenu) === "true"; | ||
if (!isSelected && !(0, import_plate_common6.isVoid)(editor, nodeEntry[0]) && !isOpenAlways) | ||
return event.stopPropagation(); | ||
} | ||
} | ||
const aboveHtmlNode = ref.current; | ||
if (id && aboveHtmlNode) { | ||
api.blockSelection.addSelectedRow(id, { | ||
aboveHtmlNode, | ||
clear: !(event == null ? void 0 : event.shiftKey) | ||
}); | ||
} | ||
} | ||
}, data) | ||
}; | ||
}; | ||
function BlockSelectable(_a) { | ||
var _b = _a, { | ||
children, | ||
options | ||
} = _b, props = __objRest(_b, [ | ||
"children", | ||
"options" | ||
]); | ||
const state = useBlockSelectableState(options); | ||
const blockSelectable = useBlockSelectable(state); | ||
if (!state.active) | ||
return /* @__PURE__ */ import_react7.default.createElement(BlockSelectableProvider, null, children); | ||
return /* @__PURE__ */ import_react7.default.createElement(BlockSelectableProvider, { selectable: true }, /* @__PURE__ */ import_react7.default.createElement("div", __spreadValues(__spreadValues({}, blockSelectable.props), props), children)); | ||
} | ||
// src/react/onKeyDownSelection.ts | ||
var import_plate_common7 = require("@udecode/plate-common"); | ||
var onKeyDownSelection = ({ | ||
api, | ||
editor, | ||
event | ||
}) => { | ||
if ((0, import_plate_common7.isHotkey)("mod+a", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common7.getAncestorNode)(editor); | ||
if (!ancestorNode) return; | ||
const [, path] = ancestorNode; | ||
if ((0, import_plate_common7.isSelectionCoverBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
if (!(0, import_plate_common7.isRangeInSameBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
(0, import_plate_common7.select)(editor, path); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
if ((0, import_plate_common7.isHotkey)("escape", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common7.getAncestorNode)(editor); | ||
const id = ancestorNode == null ? void 0 : ancestorNode[0].id; | ||
api.blockSelection.addSelectedRow(id); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
}; | ||
// src/react/BlockSelectionPlugin.tsx | ||
var BlockSelectionPlugin = (0, import_react9.createTPlatePlugin)({ | ||
var BlockSelectionPlugin = (0, import_react8.createTPlatePlugin)({ | ||
key: "blockSelection", | ||
@@ -1342,3 +1390,3 @@ options: { | ||
}, | ||
plugins: [BlockContextMenuPlugin], | ||
plugins: [BlockMenuPlugin], | ||
render: { | ||
@@ -1360,55 +1408,66 @@ aboveNodes: () => ({ children, element }) => BlockSelectable({ | ||
isSelectingSome: () => getOptions().selectedIds.size > 0 | ||
})).extendApi(({ getOptions, setOption }) => ({ | ||
resetSelectedIds: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
}, | ||
setSelectedIds: ({ added, ids, removed }) => { | ||
if (ids) { | ||
setOption("selectedIds", new Set(ids)); | ||
} | ||
if (added || removed) { | ||
const { selectedIds: prev } = getOptions(); | ||
const next = new Set(prev); | ||
extractSelectableIds(added).forEach((id) => next.add(id)); | ||
extractSelectableIds(removed).forEach((id) => next.delete(id)); | ||
setOption("selectedIds", next); | ||
} | ||
setOption("isSelecting", true); | ||
}, | ||
unselect: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
setOption("isSelecting", false); | ||
} | ||
})).extendApi( | ||
({ api, editor, getOption, getOptions, setOption }) => ({ | ||
addSelectedRow: (id, options = {}) => { | ||
const { aboveHtmlNode, clear = true } = options; | ||
const element = aboveHtmlNode != null ? aboveHtmlNode : getSelectedDomNode(id); | ||
if (!element) return; | ||
if (!getOptions().selectedIds.has(id) && clear) { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
} | ||
api.blockSelection.setSelectedIds({ | ||
added: [element], | ||
removed: [] | ||
}); | ||
}, | ||
getSelectedBlocks: () => { | ||
({ editor, getOption, getOptions, setOption }) => ({ | ||
getNodes: () => { | ||
const selectedIds = getOption("selectedIds"); | ||
return [ | ||
...(0, import_plate_common8.getNodeEntries)(editor, { | ||
...(0, import_plate_common9.getNodeEntries)(editor, { | ||
at: [], | ||
match: (n) => getOption("isSelected", n.id) | ||
match: (n) => selectedIds == null ? void 0 : selectedIds.has(n.id) | ||
}) | ||
]; | ||
}, | ||
selectedAll: () => { | ||
const all = getAllSelectableDomNode(); | ||
resetSelectedIds: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
api.blockSelection.setSelectedIds({ | ||
added: Array.from(all), | ||
removed: [] | ||
}); | ||
}, | ||
setSelectedIds: ({ added, ids, removed }) => { | ||
if (ids) { | ||
setOption("selectedIds", new Set(ids)); | ||
} | ||
if (added || removed) { | ||
const { selectedIds: prev } = getOptions(); | ||
const next = new Set(prev); | ||
if (added) { | ||
extractSelectableIds(added).forEach((id) => next.add(id)); | ||
} | ||
if (removed) { | ||
extractSelectableIds(removed).forEach((id) => next.delete(id)); | ||
} | ||
setOption("selectedIds", next); | ||
} | ||
setOption("isSelecting", true); | ||
}, | ||
unselect: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
setOption("isSelecting", false); | ||
} | ||
}) | ||
); | ||
).extendApi(({ api, getOptions, setOption }) => ({ | ||
addSelectedRow: (id, options = {}) => { | ||
const { aboveHtmlNode, clear = true } = options; | ||
const element = aboveHtmlNode != null ? aboveHtmlNode : getSelectedDomNode(id); | ||
if (!element) return; | ||
if (!getOptions().selectedIds.has(id) && clear) { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
} | ||
api.blockSelection.setSelectedIds({ | ||
added: [element], | ||
removed: [] | ||
}); | ||
}, | ||
selectedAll: () => { | ||
const all = getAllSelectableDomNode(); | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
api.blockSelection.setSelectedIds({ | ||
added: Array.from(all), | ||
removed: [] | ||
}); | ||
} | ||
})).extendTransforms(({ editor }) => ({ | ||
duplicate: (0, import_plate_common9.bindFirst)(duplicateBlockSelectionNodes, editor), | ||
removeNodes: (0, import_plate_common9.bindFirst)(removeBlockSelectionNodes, editor), | ||
select: (0, import_plate_common9.bindFirst)(selectBlockSelectionNodes, editor), | ||
setNodes: (0, import_plate_common9.bindFirst)(setBlockSelectionNodes, editor), | ||
setTexts: (0, import_plate_common9.bindFirst)(setBlockSelectionTexts, editor) | ||
})); | ||
@@ -1421,3 +1480,3 @@ // src/lib/isSelecting.ts | ||
); | ||
const selectionExpanded = (0, import_plate_common9.isSelectionExpanded)(editor); | ||
const selectionExpanded = (0, import_plate_common11.isSelectionExpanded)(editor); | ||
return selectionExpanded || isSelectingSome; | ||
@@ -1424,0 +1483,0 @@ }; |
import * as _udecode_plate_core_react from '@udecode/plate-core/react'; | ||
import { PluginConfig, QueryNodeOptions, TNodeEntry, TElement, SlateEditor } from '@udecode/plate-common'; | ||
import React$1, { CSSProperties } from 'react'; | ||
import { KeyboardHandler, EditableSiblingComponent, PlateEditor, OnChange } from '@udecode/plate-common/react'; | ||
import { PluginConfig, QueryNodeOptions, TNodeEntry, TElement, GetFragmentPropOptions, SlateEditor, TNodeProps, SetNodesOptions, TText } from '@udecode/plate-common'; | ||
import * as _udecode_slate from '@udecode/slate'; | ||
import React, { CSSProperties } from 'react'; | ||
import { EditableSiblingComponent, KeyboardHandler, PlateEditor, OnChange } from '@udecode/plate-common/react'; | ||
import * as jotai_x from 'jotai-x'; | ||
import { Path } from 'slate'; | ||
import * as _udecode_slate from '@udecode/slate'; | ||
type BlockContextMenuConfig = PluginConfig<'blockContextMenu', { | ||
action: { | ||
group: string | null; | ||
value: string | null; | ||
} | null; | ||
anchorRect: { | ||
declare const BLOCK_CONTEXT_MENU_ID = "context"; | ||
type OpenId = (string & {}) | typeof BLOCK_CONTEXT_MENU_ID; | ||
type BlockMenuConfig = PluginConfig<'blockMenu', { | ||
position: { | ||
x: number; | ||
y: number; | ||
}; | ||
openEditorId: string | null; | ||
store: any | null; | ||
openId: OpenId | null; | ||
}, { | ||
blockContextMenu: BlockContextMenuApi; | ||
blockMenu: BlockMenuApi; | ||
}>; | ||
type BlockContextMenuApi = { | ||
show: (editorId: string, event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; | ||
type BlockMenuApi = { | ||
hide: () => void; | ||
reset: () => void; | ||
show: (id: OpenId, position?: { | ||
x: number; | ||
y: number; | ||
}) => void; | ||
}; | ||
declare const BlockContextMenuPlugin: _udecode_plate_core_react.PlatePlugin<PluginConfig<"blockContextMenu", { | ||
isOpen: (editorId: string) => boolean; | ||
} & { | ||
action: { | ||
group: string | null; | ||
value: string | null; | ||
} | null; | ||
anchorRect: { | ||
declare const BlockMenuPlugin: _udecode_plate_core_react.PlatePlugin<PluginConfig<"blockMenu", { | ||
position: { | ||
x: number; | ||
y: number; | ||
}; | ||
openEditorId: string | null; | ||
store: any | null; | ||
openId: OpenId | null; | ||
}, { | ||
blockContextMenu: BlockContextMenuApi; | ||
} & Record<"blockContextMenu", Partial<BlockContextMenuApi>>, {}>>; | ||
blockMenu: BlockMenuApi; | ||
} & Record<"blockMenu", Partial<BlockMenuApi>> & Record<"blockMenu", { | ||
showContextMenu: (blockId: string, position: { | ||
x: number; | ||
y: number; | ||
}) => void; | ||
}>, {}>>; | ||
@@ -128,10 +125,11 @@ type Intersection = 'center' | 'cover' | 'touch'; | ||
}) => void; | ||
getSelectedBlocks: () => TNodeEntry[]; | ||
setSelectedIds: (options: Partial<ChangedElements> & { | ||
ids?: string[]; | ||
}) => void; | ||
getNodes: () => TNodeEntry[]; | ||
resetSelectedIds: () => void; | ||
selectedAll: () => void; | ||
setSelectedIds: (options: ChangedElements & { | ||
ids?: string[]; | ||
}) => void; | ||
unselect: () => void; | ||
}; | ||
declare const BlockSelectionAfterEditable: EditableSiblingComponent; | ||
declare const BlockSelectionPlugin: _udecode_plate_core_react.PlatePlugin<PluginConfig<"blockSelection", { | ||
@@ -152,11 +150,13 @@ isSelected: (id?: string) => boolean; | ||
blockSelection: BlockSelectionApi; | ||
} & Record<"blockSelection", Partial<BlockSelectionApi>>, {}>>; | ||
} & Record<"blockSelection", Partial<BlockSelectionApi>>, Record<"blockSelection", { | ||
duplicate: (blocks: TNodeEntry[]) => void; | ||
removeNodes: () => void; | ||
select: () => void; | ||
setNodes: (props: Partial<Omit<TElement, "children">>, options?: _udecode_slate.SetNodesOptions | undefined) => void; | ||
setTexts: (props: Partial<Omit<_udecode_slate.TText, "text">>, options?: Omit<_udecode_slate.SetNodesOptions, "at"> | undefined) => void; | ||
}>>>; | ||
declare const onKeyDownSelection: KeyboardHandler<BlockSelectionConfig>; | ||
declare const BlockSelectionAfterEditable: EditableSiblingComponent; | ||
declare const useSelectionArea: () => void; | ||
declare const BlockSelectableProvider: React$1.FC<jotai_x.ProviderProps<{ | ||
declare const BlockSelectableProvider: React.FC<jotai_x.ProviderProps<{ | ||
selectable: boolean; | ||
@@ -180,3 +180,3 @@ }>>; | ||
path: Path; | ||
ref: React$1.MutableRefObject<HTMLDivElement | null>; | ||
ref: React.MutableRefObject<HTMLDivElement | null>; | ||
}; | ||
@@ -187,4 +187,4 @@ declare const useBlockSelectable: ({ active, element, path, ref, }: ReturnType<typeof useBlockSelectableState>) => { | ||
className: string; | ||
ref: React$1.MutableRefObject<HTMLDivElement | null> | undefined; | ||
onContextMenu: (event: React$1.MouseEvent<HTMLDivElement, MouseEvent>) => void; | ||
ref: React.MutableRefObject<HTMLDivElement | null> | undefined; | ||
onContextMenu: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; | ||
}; | ||
@@ -194,42 +194,24 @@ }; | ||
options: BlockSelectableOptions; | ||
} & React$1.HTMLAttributes<HTMLDivElement>): React$1.JSX.Element; | ||
} & React.HTMLAttributes<HTMLDivElement>): React.JSX.Element; | ||
type CommandItem = { | ||
title: string; | ||
value: string; | ||
shortcut?: string; | ||
}; | ||
interface Menu { | ||
heading: string; | ||
items: CommandItem[]; | ||
} | ||
declare const ACTION_DELETE = "context_menu_delete"; | ||
declare const ACTION_COPY = "context_menu_copy"; | ||
declare const useBlockSelected: (_id?: string) => boolean; | ||
declare const useBlockContextMenuState: () => { | ||
action: { | ||
group: string | null; | ||
value: string | null; | ||
} | null; | ||
editor: _udecode_plate_core_react.PlateEditor; | ||
isOpen: boolean; | ||
selectedBlocks: _udecode_slate.TNodeEntry[]; | ||
selectedIds: Set<string> | undefined; | ||
}; | ||
declare const useBlockContextMenu: () => { | ||
props: {}; | ||
}; | ||
declare function useBlockSelectionNodes(): _udecode_slate.TNodeEntry<TElement>[]; | ||
declare function useBlockSelectionFragment(): TElement[]; | ||
declare function useBlockSelectionFragmentProp(options?: GetFragmentPropOptions): string | undefined; | ||
declare const useBlockMenuItemsState: () => { | ||
isOpen: boolean; | ||
selectedBlocks: _udecode_slate.TNodeEntry[]; | ||
selectedIds: Set<string> | undefined; | ||
}; | ||
declare const useBlockMenuItems: () => {}; | ||
declare const useBlockSelected: (_id?: string) => boolean; | ||
declare const isSelectingOrFocused: (editor: PlateEditor) => boolean; | ||
declare const useIsSelecting: () => boolean; | ||
declare const useSelectionArea: () => void; | ||
declare const duplicateBlockSelectionNodes: (editor: PlateEditor, blocks: TNodeEntry[]) => void; | ||
declare const removeBlockSelectionNodes: (editor: SlateEditor) => void; | ||
declare const selectBlockSelectionNodes: (editor: SlateEditor) => void; | ||
declare const setBlockSelectionNodes: (editor: PlateEditor, props: Partial<TNodeProps<TElement>>, options?: SetNodesOptions) => void; | ||
declare const setBlockSelectionTexts: (editor: PlateEditor, props: Partial<TNodeProps<TText>>, options?: Omit<SetNodesOptions, "at">) => void; | ||
declare const copySelectedBlocks: (editor: SlateEditor) => void; | ||
@@ -239,4 +221,2 @@ | ||
declare const openContextMenu: (editor: SlateEditor, e: any, selectedId?: string) => true | undefined; | ||
declare const pasteSelectedBlocks: (editor: SlateEditor, e: ClipboardEvent) => void; | ||
@@ -247,2 +227,2 @@ | ||
export { ACTION_COPY, ACTION_DELETE, type BlockContextMenuApi, type BlockContextMenuConfig, BlockContextMenuPlugin, BlockSelectable, type BlockSelectableOptions, BlockSelectableProvider, BlockSelectionAfterEditable, type BlockSelectionApi, type BlockSelectionConfig, BlockSelectionPlugin, type BlockSelectionSelectors, type CommandItem, type Menu, copySelectedBlocks, isSelectingOrFocused, onChangeBlockSelection, onKeyDownSelection, openContextMenu, pasteSelectedBlocks, selectInsertedBlocks, useBlockContextMenu, useBlockContextMenuState, useBlockMenuItems, useBlockMenuItemsState, useBlockSelectable, useBlockSelectableState, useBlockSelectableStore, useBlockSelected, useIsSelecting, useSelectionArea }; | ||
export { BLOCK_CONTEXT_MENU_ID, type BlockMenuApi, type BlockMenuConfig, BlockMenuPlugin, BlockSelectable, type BlockSelectableOptions, BlockSelectableProvider, BlockSelectionAfterEditable, type BlockSelectionApi, type BlockSelectionConfig, BlockSelectionPlugin, type BlockSelectionSelectors, copySelectedBlocks, duplicateBlockSelectionNodes, isSelectingOrFocused, onChangeBlockSelection, onKeyDownSelection, pasteSelectedBlocks, removeBlockSelectionNodes, selectBlockSelectionNodes, selectInsertedBlocks, setBlockSelectionNodes, setBlockSelectionTexts, useBlockSelectable, useBlockSelectableState, useBlockSelectableStore, useBlockSelected, useBlockSelectionFragment, useBlockSelectionFragmentProp, useBlockSelectionNodes, useIsSelecting, useSelectionArea }; |
@@ -62,5 +62,4 @@ "use strict"; | ||
__export(react_exports, { | ||
ACTION_COPY: () => ACTION_COPY, | ||
ACTION_DELETE: () => ACTION_DELETE, | ||
BlockContextMenuPlugin: () => BlockContextMenuPlugin, | ||
BLOCK_CONTEXT_MENU_ID: () => BLOCK_CONTEXT_MENU_ID, | ||
BlockMenuPlugin: () => BlockMenuPlugin, | ||
BlockSelectable: () => BlockSelectable, | ||
@@ -71,12 +70,12 @@ BlockSelectableProvider: () => BlockSelectableProvider, | ||
copySelectedBlocks: () => copySelectedBlocks, | ||
duplicateBlockSelectionNodes: () => duplicateBlockSelectionNodes, | ||
isSelectingOrFocused: () => isSelectingOrFocused, | ||
onChangeBlockSelection: () => onChangeBlockSelection, | ||
onKeyDownSelection: () => onKeyDownSelection, | ||
openContextMenu: () => openContextMenu, | ||
pasteSelectedBlocks: () => pasteSelectedBlocks, | ||
removeBlockSelectionNodes: () => removeBlockSelectionNodes, | ||
selectBlockSelectionNodes: () => selectBlockSelectionNodes, | ||
selectInsertedBlocks: () => selectInsertedBlocks, | ||
useBlockContextMenu: () => useBlockContextMenu, | ||
useBlockContextMenuState: () => useBlockContextMenuState, | ||
useBlockMenuItems: () => useBlockMenuItems, | ||
useBlockMenuItemsState: () => useBlockMenuItemsState, | ||
setBlockSelectionNodes: () => setBlockSelectionNodes, | ||
setBlockSelectionTexts: () => setBlockSelectionTexts, | ||
useBlockSelectable: () => useBlockSelectable, | ||
@@ -86,2 +85,5 @@ useBlockSelectableState: () => useBlockSelectableState, | ||
useBlockSelected: () => useBlockSelected, | ||
useBlockSelectionFragment: () => useBlockSelectionFragment, | ||
useBlockSelectionFragmentProp: () => useBlockSelectionFragmentProp, | ||
useBlockSelectionNodes: () => useBlockSelectionNodes, | ||
useIsSelecting: () => useIsSelecting, | ||
@@ -92,42 +94,46 @@ useSelectionArea: () => useSelectionArea | ||
// src/react/BlockContextMenuPlugin.tsx | ||
// src/react/BlockMenuPlugin.tsx | ||
var import_react = require("@udecode/plate-common/react"); | ||
var BlockContextMenuPlugin = (0, import_react.createTPlatePlugin)({ | ||
key: "blockContextMenu", | ||
var BLOCK_CONTEXT_MENU_ID = "context"; | ||
var BlockMenuPlugin = (0, import_react.createTPlatePlugin)({ | ||
key: "blockMenu", | ||
options: { | ||
action: { group: null, value: null }, | ||
anchorRect: { x: 0, y: 0 }, | ||
openEditorId: null, | ||
store: null | ||
openId: null, | ||
position: { | ||
x: -1e4, | ||
y: -1e4 | ||
} | ||
} | ||
}).extendApi(({ getOptions, setOptions }) => ({ | ||
}).extendApi(({ setOption, setOptions }) => ({ | ||
hide: () => { | ||
setOptions({ | ||
anchorRect: { x: 0, y: 0 }, | ||
openEditorId: null | ||
openId: null, | ||
position: { | ||
x: -1e4, | ||
y: -1e4 | ||
} | ||
}); | ||
}, | ||
reset: () => { | ||
setOptions({ anchorRect: { x: 0, y: 0 } }); | ||
}, | ||
show: (editorId, event) => { | ||
const { store } = getOptions(); | ||
setOptions({ | ||
anchorRect: { x: event.clientX, y: event.clientY }, | ||
openEditorId: editorId | ||
}); | ||
if (store) { | ||
store.show(); | ||
store.setAutoFocusOnShow(true); | ||
store.setInitialFocus("first"); | ||
show: (id, position) => { | ||
if (position) { | ||
setOptions({ | ||
openId: id, | ||
position | ||
}); | ||
} else { | ||
setOption("openId", id); | ||
} | ||
} | ||
})).extendOptions(({ getOptions }) => ({ | ||
isOpen: (editorId) => getOptions().openEditorId === editorId | ||
})).extendApi(({ api, editor }) => ({ | ||
showContextMenu: (blockId, position) => { | ||
var _a; | ||
(_a = editor.getApi({ key: "blockSelection" }).blockSelection) == null ? void 0 : _a.addSelectedRow(blockId); | ||
api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, position); | ||
} | ||
})).extend(({ api }) => ({ | ||
handlers: { | ||
onMouseDown: ({ editor, event, getOption }) => { | ||
if (event.button === 0 && getOption("isOpen", editor.id)) { | ||
onMouseDown: ({ event, getOptions }) => { | ||
if (event.button === 0 && getOptions().openId) { | ||
event.preventDefault(); | ||
api.blockContextMenu.hide(); | ||
api.blockMenu.hide(); | ||
} | ||
@@ -140,3 +146,7 @@ if (event.button === 2) event.preventDefault(); | ||
// src/react/BlockSelectionPlugin.tsx | ||
var import_react8 = __toESM(require("react")); | ||
var import_react_dom = __toESM(require("react-dom")); | ||
var import_plate_common10 = require("@udecode/plate-common"); | ||
var import_plate_common11 = require("@udecode/plate-common"); | ||
var import_react9 = require("@udecode/plate-common/react"); | ||
var import_react10 = require("@udecode/plate-common/react"); | ||
@@ -168,12 +178,99 @@ | ||
// src/react/BlockSelectionAfterEditable.tsx | ||
var import_react6 = __toESM(require("react")); | ||
var import_react_dom = __toESM(require("react-dom")); | ||
var import_plate_common7 = require("@udecode/plate-common"); | ||
var import_react7 = require("@udecode/plate-common/react"); | ||
// src/react/useSelectionArea.ts | ||
// src/react/components/BlockSelectable.tsx | ||
var import_react3 = __toESM(require("react")); | ||
var import_plate_common2 = require("@udecode/plate-common"); | ||
var import_react4 = require("@udecode/plate-common/react"); | ||
var import_slate = require("slate"); | ||
var { BlockSelectableProvider, useBlockSelectableStore } = (0, import_react4.createAtomStore)( | ||
{ | ||
selectable: false | ||
}, | ||
{ name: "blockSelectable" } | ||
); | ||
var useBlockSelectableState = ({ | ||
active, | ||
element | ||
}) => { | ||
const { editor, getOptions } = (0, import_react4.useEditorPlugin)(BlockSelectionPlugin); | ||
const ref = (0, import_react3.useRef)(null); | ||
const path = import_react3.default.useMemo( | ||
() => (0, import_react4.findNodePath)(editor, element), | ||
[editor, element] | ||
); | ||
if (!path || (0, import_plate_common2.isInline)(editor, element)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
const { query } = getOptions(); | ||
if (query && !(0, import_plate_common2.queryNode)([element, path], query)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
return { | ||
active: active != null ? active : true, | ||
element, | ||
path, | ||
ref | ||
}; | ||
}; | ||
var useBlockSelectable = ({ | ||
active, | ||
element, | ||
path, | ||
ref | ||
}) => { | ||
const { api, editor, getOption, getOptions } = (0, import_react4.useEditorPlugin)(BlockSelectionPlugin); | ||
const id = element == null ? void 0 : element.id; | ||
const data = { "data-key": id }; | ||
return { | ||
props: __spreadValues({ | ||
className: "slate-selectable", | ||
ref, | ||
onContextMenu: (event) => { | ||
var _a, _b; | ||
if (!element || !active) return; | ||
const { enableContextMenu } = getOptions(); | ||
if (!enableContextMenu) return; | ||
if ((_a = editor.selection) == null ? void 0 : _a.focus) { | ||
const nodeEntry = (0, import_plate_common2.getAboveNode)(editor); | ||
if (nodeEntry && import_slate.Path.isCommon(path, nodeEntry[1])) { | ||
const id2 = nodeEntry[0].id; | ||
const isSelected = getOption("isSelected", id2); | ||
const isOpenAlways = ((_b = event.target.dataset) == null ? void 0 : _b.openContextMenu) === "true"; | ||
if (!isSelected && !(0, import_plate_common2.isVoid)(editor, nodeEntry[0]) && !isOpenAlways) | ||
return event.stopPropagation(); | ||
} | ||
} | ||
const aboveHtmlNode = ref.current; | ||
if (id && aboveHtmlNode) { | ||
api.blockSelection.addSelectedRow(id, { | ||
aboveHtmlNode, | ||
clear: !(event == null ? void 0 : event.shiftKey) | ||
}); | ||
} | ||
} | ||
}, data) | ||
}; | ||
}; | ||
function BlockSelectable(_a) { | ||
var _b = _a, { | ||
children, | ||
options | ||
} = _b, props = __objRest(_b, [ | ||
"children", | ||
"options" | ||
]); | ||
const state = useBlockSelectableState(options); | ||
const blockSelectable = useBlockSelectable(state); | ||
if (!state.active) | ||
return /* @__PURE__ */ import_react3.default.createElement(BlockSelectableProvider, null, children); | ||
return /* @__PURE__ */ import_react3.default.createElement(BlockSelectableProvider, { selectable: true }, /* @__PURE__ */ import_react3.default.createElement("div", __spreadValues(__spreadValues({}, blockSelectable.props), props), children)); | ||
} | ||
// src/react/hooks/useSelectionArea.ts | ||
var import_react5 = __toESM(require("react")); | ||
var import_react6 = require("@udecode/plate-common/react"); | ||
// src/internal/EventEmitter.ts | ||
@@ -637,3 +734,3 @@ var EventTarget = class { | ||
this._container = selectAll(container, document2)[0]; | ||
if (this._container.contains(target) && target.dataset.plateSelectable !== "true") | ||
if (this._container.contains(target) && target.dataset.slateEditor !== "true" && target.dataset.plateSelectable !== "true") | ||
return; | ||
@@ -926,7 +1023,7 @@ this._containerRect = this._container.getBoundingClientRect(); | ||
// src/react/useSelectionArea.ts | ||
// src/react/hooks/useSelectionArea.ts | ||
var useSelectionArea = () => { | ||
const { api, editor, getOptions, setOption } = (0, import_react4.useEditorPlugin)(BlockSelectionPlugin); | ||
const { api, editor, getOptions, setOption } = (0, import_react6.useEditorPlugin)(BlockSelectionPlugin); | ||
const { areaOptions } = getOptions(); | ||
import_react3.default.useEffect(() => { | ||
import_react5.default.useEffect(() => { | ||
const selection = new SelectionArea(__spreadValues({ | ||
@@ -936,3 +1033,3 @@ document: window.document | ||
setOption("isSelectionAreaVisible", true); | ||
(0, import_react4.deselectEditor)(editor); | ||
(0, import_react6.deselectEditor)(editor); | ||
if (!(event == null ? void 0 : event.shiftKey)) { | ||
@@ -955,12 +1052,96 @@ selection.clearSelection(); | ||
// src/react/onKeyDownSelection.ts | ||
var import_plate_common3 = require("@udecode/plate-common"); | ||
var onKeyDownSelection = ({ | ||
api, | ||
editor, | ||
event | ||
}) => { | ||
if ((0, import_plate_common3.isHotkey)("mod+a", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common3.getAncestorNode)(editor); | ||
if (!ancestorNode) return; | ||
const [, path] = ancestorNode; | ||
if ((0, import_plate_common3.isSelectionCoverBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
if (!(0, import_plate_common3.isRangeInSameBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
(0, import_plate_common3.select)(editor, path); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
if ((0, import_plate_common3.isHotkey)("escape", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common3.getAncestorNode)(editor); | ||
const id = ancestorNode == null ? void 0 : ancestorNode[0].id; | ||
api.blockSelection.addSelectedRow(id); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
}; | ||
// src/react/transforms/duplicateBlockSelectionNodes.ts | ||
var import_plate_common4 = require("@udecode/plate-common"); | ||
var import_slate2 = require("slate"); | ||
var duplicateBlockSelectionNodes = (editor, blocks) => { | ||
(0, import_plate_common4.duplicateBlocks)(editor, blocks); | ||
const lastBlock = blocks.at(-1); | ||
if (!lastBlock) return; | ||
const path = import_slate2.Path.next(lastBlock[1]); | ||
const ids = blocks.map((_, index) => { | ||
const targetPath = [path[0] + index]; | ||
const targetNode = (0, import_plate_common4.getNodeEntry)(editor, targetPath); | ||
return targetNode == null ? void 0 : targetNode[0].id; | ||
}).filter(Boolean); | ||
setTimeout(() => { | ||
editor.getApi(BlockSelectionPlugin).blockSelection.setSelectedIds({ ids }); | ||
}, 0); | ||
}; | ||
// src/react/transforms/removeBlockSelectionNodes.ts | ||
var removeBlockSelectionNodes = (editor) => { | ||
const selectedIds = editor.getOption(BlockSelectionPlugin, "selectedIds"); | ||
if (!selectedIds) return; | ||
editor.removeNodes({ | ||
at: [], | ||
match: (n) => selectedIds.has(n.id) | ||
}); | ||
}; | ||
// src/react/transforms/selectBlockSelectionNodes.ts | ||
var import_plate_common5 = require("@udecode/plate-common"); | ||
var selectBlockSelectionNodes = (editor) => { | ||
(0, import_plate_common5.selectNodes)( | ||
editor, | ||
editor.getApi(BlockSelectionPlugin).blockSelection.getNodes() | ||
); | ||
editor.getApi(BlockSelectionPlugin).blockSelection.resetSelectedIds(); | ||
}; | ||
// src/react/transforms/setBlockSelectionNodes.ts | ||
var import_plate_common6 = require("@udecode/plate-common"); | ||
var setBlockSelectionNodes = (editor, props, options) => { | ||
(0, import_plate_common6.withoutNormalizing)(editor, () => { | ||
const blocks = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes(); | ||
blocks.forEach(([, path]) => { | ||
(0, import_plate_common6.setNodes)(editor, props, __spreadProps(__spreadValues({}, options), { | ||
at: path | ||
})); | ||
}); | ||
}); | ||
}; | ||
var setBlockSelectionTexts = (editor, props, options) => { | ||
setBlockSelectionNodes(editor, props, __spreadValues({ | ||
mode: "lowest" | ||
}, options)); | ||
}; | ||
// src/react/utils/copySelectedBlocks.ts | ||
var import_plate_common2 = require("@udecode/plate-common"); | ||
var import_plate_common7 = require("@udecode/plate-common"); | ||
var import_copy_to_clipboard = __toESM(require("copy-to-clipboard")); | ||
var copySelectedBlocks = (editor) => { | ||
const { api, getOptions, setOption } = (0, import_plate_common2.getEditorPlugin)( | ||
editor, | ||
BlockSelectionPlugin | ||
); | ||
const { selectedIds } = getOptions(); | ||
const selectedEntries = api.blockSelection.getSelectedBlocks(); | ||
const { selectedIds } = editor.getOptions(BlockSelectionPlugin); | ||
const selectedEntries = editor.getApi(BlockSelectionPlugin).blockSelection.getNodes(); | ||
const selectedFragment = selectedEntries.map(([node]) => node); | ||
@@ -973,7 +1154,7 @@ (0, import_copy_to_clipboard.default)(" ", { | ||
const div = document.createElement("div"); | ||
(0, import_plate_common2.withoutNormalizing)(editor, () => { | ||
(0, import_plate_common7.withoutNormalizing)(editor, () => { | ||
selectedEntries.forEach(([, path]) => { | ||
(0, import_plate_common2.select)(editor, { | ||
anchor: (0, import_plate_common2.getStartPoint)(editor, path), | ||
focus: (0, import_plate_common2.getEndPoint)(editor, path) | ||
(0, import_plate_common7.select)(editor, { | ||
anchor: (0, import_plate_common7.getStartPoint)(editor, path), | ||
focus: (0, import_plate_common7.getEndPoint)(editor, path) | ||
}); | ||
@@ -987,4 +1168,4 @@ editor.setFragmentData(data); | ||
}); | ||
(0, import_plate_common2.deselect)(editor); | ||
setOption("selectedIds", selectedIds); | ||
(0, import_plate_common7.deselect)(editor); | ||
editor.setOption(BlockSelectionPlugin, "selectedIds", selectedIds); | ||
}); | ||
@@ -1003,3 +1184,2 @@ data.setData("text/plain", textPlain); | ||
// src/react/utils/onChangeBlockSelection.ts | ||
var import_plate_common3 = require("@udecode/plate-common"); | ||
var onChangeBlockSelection = ({ | ||
@@ -1010,35 +1190,20 @@ api, | ||
}) => { | ||
const blockContextMenu = (0, import_plate_common3.getEditorPlugin)(editor, BlockContextMenuPlugin); | ||
if (editor.selection && getOptions().isSelecting && !blockContextMenu.getOption("isOpen", editor.id)) { | ||
if (editor.selection && getOptions().isSelecting && !editor.getOption(BlockMenuPlugin, "openId")) { | ||
api.blockSelection.unselect(); | ||
blockContextMenu.api.blockContextMenu.hide(); | ||
editor.getApi(BlockMenuPlugin).blockMenu.hide(); | ||
} | ||
}; | ||
// src/react/utils/openContextMenu.ts | ||
var import_plate_common4 = require("@udecode/plate-common"); | ||
var openContextMenu = (editor, e, selectedId) => { | ||
var _a; | ||
const { api } = (0, import_plate_common4.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const blockContextMenu = (0, import_plate_common4.getEditorPlugin)(editor, BlockContextMenuPlugin); | ||
const id = selectedId != null ? selectedId : (_a = (0, import_plate_common4.getAncestorNode)(editor)) == null ? void 0 : _a[0].id; | ||
if (!id) return; | ||
api.blockSelection.addSelectedRow(id); | ||
blockContextMenu.api.blockContextMenu.show(editor.id, e); | ||
(0, import_plate_common4.collapseSelection)(editor); | ||
return true; | ||
}; | ||
// src/react/utils/pasteSelectedBlocks.ts | ||
var import_plate_common6 = require("@udecode/plate-common"); | ||
var import_react5 = require("@udecode/plate-common/react"); | ||
var import_slate = require("slate"); | ||
var import_plate_common9 = require("@udecode/plate-common"); | ||
var import_react7 = require("@udecode/plate-common/react"); | ||
var import_slate3 = require("slate"); | ||
// src/react/utils/selectInsertedBlocks.ts | ||
var import_plate_common5 = require("@udecode/plate-common"); | ||
var import_plate_common8 = require("@udecode/plate-common"); | ||
var selectInsertedBlocks = (editor) => { | ||
const { setOption } = (0, import_plate_common5.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const { setOption } = (0, import_plate_common8.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const ids = /* @__PURE__ */ new Set(); | ||
editor.operations.forEach((op) => { | ||
if (op.type === "insert_node" && op.node.id && (0, import_plate_common5.isBlock)(editor, op.node)) { | ||
if (op.type === "insert_node" && op.node.id && (0, import_plate_common8.isBlock)(editor, op.node)) { | ||
ids.add(op.node.id); | ||
@@ -1054,11 +1219,11 @@ } | ||
var pasteSelectedBlocks = (editor, e) => { | ||
const { api } = (0, import_plate_common6.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const entries = api.blockSelection.getSelectedBlocks(); | ||
const { api } = (0, import_plate_common9.getEditorPlugin)(editor, BlockSelectionPlugin); | ||
const entries = api.blockSelection.getNodes(); | ||
if (entries.length > 0) { | ||
const entry = entries.at(-1); | ||
const [node, path] = entry; | ||
(0, import_react5.focusEditor)(editor, (0, import_plate_common6.getStartPoint)(editor, path)); | ||
if (!(0, import_plate_common6.isElementEmpty)(editor, node)) { | ||
const at = import_slate.Path.next(path); | ||
(0, import_plate_common6.insertNodes)(editor, editor.api.create.block({}, at), { | ||
(0, import_react7.focusEditor)(editor, (0, import_plate_common9.getStartPoint)(editor, path)); | ||
if (!(0, import_plate_common9.isElementEmpty)(editor, node)) { | ||
const at = import_slate3.Path.next(path); | ||
(0, import_plate_common9.insertNodes)(editor, editor.api.create.block({}, at), { | ||
at, | ||
@@ -1068,4 +1233,4 @@ select: true | ||
} | ||
(0, import_react5.insertData)(editor, e.clipboardData); | ||
(0, import_plate_common6.deselect)(editor); | ||
(0, import_react7.insertData)(editor, e.clipboardData); | ||
(0, import_plate_common9.deselect)(editor); | ||
selectInsertedBlocks(editor); | ||
@@ -1075,14 +1240,12 @@ } | ||
// src/react/BlockSelectionAfterEditable.tsx | ||
// src/react/BlockSelectionPlugin.tsx | ||
var BlockSelectionAfterEditable = () => { | ||
const editor = (0, import_react7.useEditorRef)(); | ||
const { api, getOption, getOptions, useOption } = (0, import_react7.useEditorPlugin)(BlockSelectionPlugin); | ||
const editor = (0, import_react10.useEditorRef)(); | ||
const { api, getOption, getOptions, useOption } = (0, import_react10.useEditorPlugin)({ key: "blockSelection" }); | ||
const isSelecting2 = useOption("isSelecting"); | ||
const selectedIds = useOption("selectedIds"); | ||
const blockContextMenu = (0, import_react7.useEditorPlugin)(BlockContextMenuPlugin); | ||
const isOpen = blockContextMenu.useOption("isOpen", editor.id); | ||
useSelectionArea(); | ||
const inputRef = import_react6.default.useRef(null); | ||
const [isMounted, setIsMounted] = import_react6.default.useState(false); | ||
import_react6.default.useEffect(() => { | ||
const inputRef = import_react8.default.useRef(null); | ||
const [isMounted, setIsMounted] = import_react8.default.useState(false); | ||
import_react8.default.useEffect(() => { | ||
setIsMounted(true); | ||
@@ -1093,4 +1256,4 @@ return () => { | ||
}, []); | ||
import_react6.default.useEffect(() => { | ||
if (isSelecting2 && !isOpen && inputRef.current) { | ||
import_react8.default.useEffect(() => { | ||
if (isSelecting2 && inputRef.current) { | ||
inputRef.current.focus(); | ||
@@ -1100,17 +1263,17 @@ } else if (inputRef.current) { | ||
} | ||
}, [isSelecting2, isOpen]); | ||
const handleKeyDown = import_react6.default.useCallback( | ||
}, [isSelecting2]); | ||
const handleKeyDown = import_react8.default.useCallback( | ||
(e) => { | ||
var _a, _b; | ||
const isReadonly = (0, import_react7.isEditorReadOnly)(editor); | ||
const isReadonly = (0, import_react10.isEditorReadOnly)(editor); | ||
(_b = (_a = getOptions()).onKeyDownSelecting) == null ? void 0 : _b.call(_a, e.nativeEvent); | ||
if (!getOptions().isSelecting) return; | ||
if ((0, import_plate_common7.isHotkey)("escape")(e)) { | ||
if ((0, import_plate_common11.isHotkey)("escape")(e)) { | ||
api.blockSelection.unselect(); | ||
} | ||
if ((0, import_plate_common7.isHotkey)("mod+z")(e)) { | ||
if ((0, import_plate_common11.isHotkey)("mod+z")(e)) { | ||
editor.undo(); | ||
selectInsertedBlocks(editor); | ||
} | ||
if ((0, import_plate_common7.isHotkey)("mod+shift+z")(e)) { | ||
if ((0, import_plate_common11.isHotkey)("mod+shift+z")(e)) { | ||
editor.redo(); | ||
@@ -1120,4 +1283,4 @@ selectInsertedBlocks(editor); | ||
if (!getOption("isSelectingSome")) return; | ||
if ((0, import_plate_common7.isHotkey)("enter")(e)) { | ||
const entry = (0, import_plate_common7.findNode)(editor, { | ||
if ((0, import_plate_common11.isHotkey)("enter")(e)) { | ||
const entry = (0, import_plate_common11.findNode)(editor, { | ||
at: [], | ||
@@ -1128,8 +1291,8 @@ match: (n) => selectedIds.has(n.id) | ||
const [, path] = entry; | ||
(0, import_react7.focusEditor)(editor, (0, import_plate_common7.getEndPoint)(editor, path)); | ||
(0, import_react10.focusEditor)(editor, (0, import_plate_common11.getEndPoint)(editor, path)); | ||
e.preventDefault(); | ||
} | ||
} | ||
if ((0, import_plate_common7.isHotkey)(["backspace", "delete"])(e) && !isReadonly) { | ||
(0, import_plate_common7.removeNodes)(editor, { | ||
if ((0, import_plate_common11.isHotkey)(["backspace", "delete"])(e) && !isReadonly) { | ||
(0, import_plate_common11.removeNodes)(editor, { | ||
at: [], | ||
@@ -1139,9 +1302,9 @@ match: (n) => selectedIds.has(n.id) | ||
} | ||
if ((0, import_plate_common7.isHotkey)("up")(e)) { | ||
if ((0, import_plate_common11.isHotkey)("up")(e)) { | ||
const firstId = [...selectedIds][0]; | ||
const node = (0, import_plate_common7.findNode)(editor, { | ||
const node = (0, import_plate_common11.findNode)(editor, { | ||
at: [], | ||
match: (n) => n.id === firstId | ||
}); | ||
const prev = (0, import_plate_common7.getPreviousNode)(editor, { | ||
const prev = (0, import_plate_common11.getPreviousNode)(editor, { | ||
at: node == null ? void 0 : node[1] | ||
@@ -1152,9 +1315,9 @@ }); | ||
} | ||
if ((0, import_plate_common7.isHotkey)("down")(e)) { | ||
if ((0, import_plate_common11.isHotkey)("down")(e)) { | ||
const lastId = [...selectedIds].pop(); | ||
const node = (0, import_plate_common7.findNode)(editor, { | ||
const node = (0, import_plate_common11.findNode)(editor, { | ||
at: [], | ||
match: (n) => n.id === lastId | ||
}); | ||
const next = (0, import_plate_common7.getNextNode)(editor, { | ||
const next = (0, import_plate_common11.getNextNode)(editor, { | ||
at: node == null ? void 0 : node[1] | ||
@@ -1168,3 +1331,3 @@ }); | ||
); | ||
const handleCopy = import_react6.default.useCallback( | ||
const handleCopy = import_react8.default.useCallback( | ||
(e) => { | ||
@@ -1178,3 +1341,3 @@ e.preventDefault(); | ||
); | ||
const handleCut = import_react6.default.useCallback( | ||
const handleCut = import_react8.default.useCallback( | ||
(e) => { | ||
@@ -1184,8 +1347,8 @@ e.preventDefault(); | ||
copySelectedBlocks(editor); | ||
if (!(0, import_react7.isEditorReadOnly)(editor)) { | ||
(0, import_plate_common7.removeNodes)(editor, { | ||
if (!(0, import_react10.isEditorReadOnly)(editor)) { | ||
(0, import_plate_common11.removeNodes)(editor, { | ||
at: [], | ||
match: (n) => selectedIds.has(n.id) | ||
}); | ||
(0, import_react7.focusEditor)(editor); | ||
(0, import_react10.focusEditor)(editor); | ||
} | ||
@@ -1196,6 +1359,6 @@ } | ||
); | ||
const handlePaste = import_react6.default.useCallback( | ||
const handlePaste = import_react8.default.useCallback( | ||
(e) => { | ||
e.preventDefault(); | ||
if (!(0, import_react7.isEditorReadOnly)(editor)) { | ||
if (!(0, import_react10.isEditorReadOnly)(editor)) { | ||
pasteSelectedBlocks(editor, e.nativeEvent); | ||
@@ -1210,3 +1373,3 @@ } | ||
return import_react_dom.default.createPortal( | ||
/* @__PURE__ */ import_react6.default.createElement( | ||
/* @__PURE__ */ import_react8.default.createElement( | ||
"input", | ||
@@ -1232,130 +1395,3 @@ { | ||
}; | ||
// src/react/components/BlockSelectable.tsx | ||
var import_react8 = __toESM(require("react")); | ||
var import_plate_common8 = require("@udecode/plate-common"); | ||
var import_react9 = require("@udecode/plate-common/react"); | ||
var import_slate2 = require("slate"); | ||
var { BlockSelectableProvider, useBlockSelectableStore } = (0, import_react9.createAtomStore)( | ||
{ | ||
selectable: false | ||
}, | ||
{ name: "blockSelectable" } | ||
); | ||
var useBlockSelectableState = ({ | ||
active, | ||
element | ||
}) => { | ||
const { editor, getOptions } = (0, import_react9.useEditorPlugin)(BlockSelectionPlugin); | ||
const ref = (0, import_react8.useRef)(null); | ||
const path = import_react8.default.useMemo( | ||
() => (0, import_react9.findNodePath)(editor, element), | ||
[editor, element] | ||
); | ||
if (!path || (0, import_plate_common8.isInline)(editor, element)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
const { query } = getOptions(); | ||
if (query && !(0, import_plate_common8.queryNode)([element, path], query)) { | ||
return { | ||
active: active != null ? active : false | ||
}; | ||
} | ||
return { | ||
active: active != null ? active : true, | ||
element, | ||
path, | ||
ref | ||
}; | ||
}; | ||
var useBlockSelectable = ({ | ||
active, | ||
element, | ||
path, | ||
ref | ||
}) => { | ||
const { api, editor, getOption, getOptions } = (0, import_react9.useEditorPlugin)(BlockSelectionPlugin); | ||
const id = element == null ? void 0 : element.id; | ||
const data = { "data-key": id }; | ||
return { | ||
props: __spreadValues({ | ||
className: "slate-selectable", | ||
ref, | ||
onContextMenu: (event) => { | ||
var _a, _b; | ||
if (!element || !active) return; | ||
const { enableContextMenu } = getOptions(); | ||
if (!enableContextMenu) return; | ||
if ((_a = editor.selection) == null ? void 0 : _a.focus) { | ||
const nodeEntry = (0, import_plate_common8.getAboveNode)(editor); | ||
if (nodeEntry && import_slate2.Path.isCommon(path, nodeEntry[1])) { | ||
const id2 = nodeEntry[0].id; | ||
const isSelected = getOption("isSelected", id2); | ||
const isOpenAlways = ((_b = event.target.dataset) == null ? void 0 : _b.openContextMenu) === "true"; | ||
if (!isSelected && !(0, import_plate_common8.isVoid)(editor, nodeEntry[0]) && !isOpenAlways) | ||
return event.stopPropagation(); | ||
} | ||
} | ||
const aboveHtmlNode = ref.current; | ||
if (id && aboveHtmlNode) { | ||
api.blockSelection.addSelectedRow(id, { | ||
aboveHtmlNode, | ||
clear: !(event == null ? void 0 : event.shiftKey) | ||
}); | ||
} | ||
} | ||
}, data) | ||
}; | ||
}; | ||
function BlockSelectable(_a) { | ||
var _b = _a, { | ||
children, | ||
options | ||
} = _b, props = __objRest(_b, [ | ||
"children", | ||
"options" | ||
]); | ||
const state = useBlockSelectableState(options); | ||
const blockSelectable = useBlockSelectable(state); | ||
if (!state.active) | ||
return /* @__PURE__ */ import_react8.default.createElement(BlockSelectableProvider, null, children); | ||
return /* @__PURE__ */ import_react8.default.createElement(BlockSelectableProvider, { selectable: true }, /* @__PURE__ */ import_react8.default.createElement("div", __spreadValues(__spreadValues({}, blockSelectable.props), props), children)); | ||
} | ||
// src/react/onKeyDownSelection.ts | ||
var import_plate_common9 = require("@udecode/plate-common"); | ||
var onKeyDownSelection = ({ | ||
api, | ||
editor, | ||
event | ||
}) => { | ||
if ((0, import_plate_common9.isHotkey)("mod+a", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common9.getAncestorNode)(editor); | ||
if (!ancestorNode) return; | ||
const [, path] = ancestorNode; | ||
if ((0, import_plate_common9.isSelectionCoverBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
if (!(0, import_plate_common9.isRangeInSameBlock)(editor)) { | ||
return api.blockSelection.selectedAll(); | ||
} | ||
(0, import_plate_common9.select)(editor, path); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
if ((0, import_plate_common9.isHotkey)("escape", event)) { | ||
if (event.defaultPrevented) return; | ||
const ancestorNode = (0, import_plate_common9.getAncestorNode)(editor); | ||
const id = ancestorNode == null ? void 0 : ancestorNode[0].id; | ||
api.blockSelection.addSelectedRow(id); | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
} | ||
}; | ||
// src/react/BlockSelectionPlugin.tsx | ||
var BlockSelectionPlugin = (0, import_react10.createTPlatePlugin)({ | ||
var BlockSelectionPlugin = (0, import_react9.createTPlatePlugin)({ | ||
key: "blockSelection", | ||
@@ -1385,3 +1421,3 @@ options: { | ||
}, | ||
plugins: [BlockContextMenuPlugin], | ||
plugins: [BlockMenuPlugin], | ||
render: { | ||
@@ -1403,129 +1439,111 @@ aboveNodes: () => ({ children, element }) => BlockSelectable({ | ||
isSelectingSome: () => getOptions().selectedIds.size > 0 | ||
})).extendApi(({ getOptions, setOption }) => ({ | ||
resetSelectedIds: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
}, | ||
setSelectedIds: ({ added, ids, removed }) => { | ||
if (ids) { | ||
setOption("selectedIds", new Set(ids)); | ||
} | ||
if (added || removed) { | ||
const { selectedIds: prev } = getOptions(); | ||
const next = new Set(prev); | ||
extractSelectableIds(added).forEach((id) => next.add(id)); | ||
extractSelectableIds(removed).forEach((id) => next.delete(id)); | ||
setOption("selectedIds", next); | ||
} | ||
setOption("isSelecting", true); | ||
}, | ||
unselect: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
setOption("isSelecting", false); | ||
} | ||
})).extendApi( | ||
({ api, editor, getOption, getOptions, setOption }) => ({ | ||
addSelectedRow: (id, options = {}) => { | ||
const { aboveHtmlNode, clear = true } = options; | ||
const element = aboveHtmlNode != null ? aboveHtmlNode : getSelectedDomNode(id); | ||
if (!element) return; | ||
if (!getOptions().selectedIds.has(id) && clear) { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
} | ||
api.blockSelection.setSelectedIds({ | ||
added: [element], | ||
removed: [] | ||
}); | ||
}, | ||
getSelectedBlocks: () => { | ||
({ editor, getOption, getOptions, setOption }) => ({ | ||
getNodes: () => { | ||
const selectedIds = getOption("selectedIds"); | ||
return [ | ||
...(0, import_plate_common10.getNodeEntries)(editor, { | ||
at: [], | ||
match: (n) => getOption("isSelected", n.id) | ||
match: (n) => selectedIds == null ? void 0 : selectedIds.has(n.id) | ||
}) | ||
]; | ||
}, | ||
selectedAll: () => { | ||
const all = getAllSelectableDomNode(); | ||
resetSelectedIds: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
api.blockSelection.setSelectedIds({ | ||
added: Array.from(all), | ||
removed: [] | ||
}); | ||
}, | ||
setSelectedIds: ({ added, ids, removed }) => { | ||
if (ids) { | ||
setOption("selectedIds", new Set(ids)); | ||
} | ||
if (added || removed) { | ||
const { selectedIds: prev } = getOptions(); | ||
const next = new Set(prev); | ||
if (added) { | ||
extractSelectableIds(added).forEach((id) => next.add(id)); | ||
} | ||
if (removed) { | ||
extractSelectableIds(removed).forEach((id) => next.delete(id)); | ||
} | ||
setOption("selectedIds", next); | ||
} | ||
setOption("isSelecting", true); | ||
}, | ||
unselect: () => { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
setOption("isSelecting", false); | ||
} | ||
}) | ||
); | ||
).extendApi(({ api, getOptions, setOption }) => ({ | ||
addSelectedRow: (id, options = {}) => { | ||
const { aboveHtmlNode, clear = true } = options; | ||
const element = aboveHtmlNode != null ? aboveHtmlNode : getSelectedDomNode(id); | ||
if (!element) return; | ||
if (!getOptions().selectedIds.has(id) && clear) { | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
} | ||
api.blockSelection.setSelectedIds({ | ||
added: [element], | ||
removed: [] | ||
}); | ||
}, | ||
selectedAll: () => { | ||
const all = getAllSelectableDomNode(); | ||
setOption("selectedIds", /* @__PURE__ */ new Set()); | ||
api.blockSelection.setSelectedIds({ | ||
added: Array.from(all), | ||
removed: [] | ||
}); | ||
} | ||
})).extendTransforms(({ editor }) => ({ | ||
duplicate: (0, import_plate_common10.bindFirst)(duplicateBlockSelectionNodes, editor), | ||
removeNodes: (0, import_plate_common10.bindFirst)(removeBlockSelectionNodes, editor), | ||
select: (0, import_plate_common10.bindFirst)(selectBlockSelectionNodes, editor), | ||
setNodes: (0, import_plate_common10.bindFirst)(setBlockSelectionNodes, editor), | ||
setTexts: (0, import_plate_common10.bindFirst)(setBlockSelectionTexts, editor) | ||
})); | ||
// src/react/context-menu/types.ts | ||
var ACTION_DELETE = "context_menu_delete"; | ||
var ACTION_COPY = "context_menu_copy"; | ||
// src/react/context-menu/useBlockContextMenu.ts | ||
var import_react11 = require("react"); | ||
var import_react12 = require("@udecode/plate-common/react"); | ||
var useBlockContextMenuState = () => { | ||
const { api, editor, useOption } = (0, import_react12.useEditorPlugin)(BlockSelectionPlugin); | ||
const blockContextMenu = (0, import_react12.useEditorPlugin)(BlockContextMenuPlugin); | ||
const isOpen = blockContextMenu.useOption("isOpen", editor.id); | ||
const selectedIds = useOption("selectedIds"); | ||
const action = (0, import_react11.useMemo)(() => blockContextMenu.getOptions().action, [isOpen]); | ||
const selectedBlocks = api.blockSelection.getSelectedBlocks(); | ||
return { | ||
action, | ||
editor, | ||
isOpen, | ||
selectedBlocks, | ||
selectedIds | ||
}; | ||
// src/react/hooks/useBlockSelected.ts | ||
var import_react11 = require("@udecode/plate-common/react"); | ||
var useBlockSelected = (_id) => { | ||
const { useOption } = (0, import_react11.useEditorPlugin)(BlockSelectionPlugin); | ||
const { id } = (0, import_react11.useElement)(); | ||
const isBlockSelected = useOption("isSelected", id); | ||
return isBlockSelected; | ||
}; | ||
var useBlockContextMenu = () => { | ||
return { | ||
props: { | ||
// onOpenChange: (value: boolean) => { | ||
// if (value) { | ||
// api.show(editor.id); | ||
// } else { | ||
// api.hide(); | ||
// } | ||
// }, | ||
} | ||
}; | ||
}; | ||
// src/react/context-menu/useBlockMenuItems.ts | ||
// src/react/hooks/useBlockSelectionNodes.ts | ||
var import_react12 = require("react"); | ||
var import_plate_common12 = require("@udecode/plate-common"); | ||
var import_react13 = require("@udecode/plate-common/react"); | ||
var useBlockMenuItemsState = () => { | ||
const { api, editor, useOption } = (0, import_react13.useEditorPlugin)(BlockSelectionPlugin); | ||
const blockContextMenu = (0, import_react13.useEditorPlugin)(BlockContextMenuPlugin); | ||
const isOpen = blockContextMenu.useOption("isOpen", editor.id); | ||
function useBlockSelectionNodes() { | ||
const { editor, useOption } = (0, import_react13.useEditorPlugin)(BlockSelectionPlugin); | ||
const selectedIds = useOption("selectedIds"); | ||
const selectedBlocks = api.blockSelection.getSelectedBlocks(); | ||
return { | ||
isOpen, | ||
selectedBlocks, | ||
selectedIds | ||
}; | ||
}; | ||
var useBlockMenuItems = () => { | ||
return {}; | ||
}; | ||
return (0, import_react12.useMemo)(() => { | ||
return [ | ||
...(0, import_plate_common12.getNodeEntries)(editor, { | ||
at: [], | ||
match: (n) => selectedIds == null ? void 0 : selectedIds.has(n.id) | ||
}) | ||
]; | ||
}, [editor, selectedIds]); | ||
} | ||
function useBlockSelectionFragment() { | ||
const nodes = useBlockSelectionNodes(); | ||
return (0, import_react12.useMemo)(() => nodes.map(([node]) => node), [nodes]); | ||
} | ||
function useBlockSelectionFragmentProp(options) { | ||
const fragment = useBlockSelectionFragment(); | ||
return (0, import_react12.useMemo)(() => (0, import_plate_common12.getFragmentProp)(fragment, options), [fragment, options]); | ||
} | ||
// src/react/useBlockSelected.ts | ||
// src/react/hooks/useIsSelecting.ts | ||
var import_plate_common13 = require("@udecode/plate-common"); | ||
var import_react14 = require("@udecode/plate-common/react"); | ||
var useBlockSelected = (_id) => { | ||
const { useOption } = (0, import_react14.useEditorPlugin)(BlockSelectionPlugin); | ||
const { id } = (0, import_react14.useElement)(); | ||
const isBlockSelected = useOption("isSelected", id); | ||
return isBlockSelected; | ||
}; | ||
// src/react/useIsSelecting.ts | ||
var import_plate_common11 = require("@udecode/plate-common"); | ||
var import_react15 = require("@udecode/plate-common/react"); | ||
var isSelectingOrFocused = (editor) => { | ||
return isSelecting(editor) || (0, import_react15.isEditorFocused)(editor); | ||
return isSelecting(editor) || (0, import_react14.isEditorFocused)(editor); | ||
}; | ||
var useIsSelecting = () => { | ||
const isSelectingSome = (0, import_react15.useEditorPlugin)(BlockSelectionPlugin).useOption("isSelectingSome"); | ||
const selectionExpanded = (0, import_react15.useEditorSelector)((editor) => { | ||
return (0, import_plate_common11.isSelectionExpanded)(editor); | ||
const isSelectingSome = (0, import_react14.useEditorPlugin)(BlockSelectionPlugin).useOption("isSelectingSome"); | ||
const selectionExpanded = (0, import_react14.useEditorSelector)((editor) => { | ||
return (0, import_plate_common13.isSelectionExpanded)(editor); | ||
}, []); | ||
@@ -1536,5 +1554,4 @@ return selectionExpanded || isSelectingSome; | ||
0 && (module.exports = { | ||
ACTION_COPY, | ||
ACTION_DELETE, | ||
BlockContextMenuPlugin, | ||
BLOCK_CONTEXT_MENU_ID, | ||
BlockMenuPlugin, | ||
BlockSelectable, | ||
@@ -1545,12 +1562,12 @@ BlockSelectableProvider, | ||
copySelectedBlocks, | ||
duplicateBlockSelectionNodes, | ||
isSelectingOrFocused, | ||
onChangeBlockSelection, | ||
onKeyDownSelection, | ||
openContextMenu, | ||
pasteSelectedBlocks, | ||
removeBlockSelectionNodes, | ||
selectBlockSelectionNodes, | ||
selectInsertedBlocks, | ||
useBlockContextMenu, | ||
useBlockContextMenuState, | ||
useBlockMenuItems, | ||
useBlockMenuItemsState, | ||
setBlockSelectionNodes, | ||
setBlockSelectionTexts, | ||
useBlockSelectable, | ||
@@ -1560,2 +1577,5 @@ useBlockSelectableState, | ||
useBlockSelected, | ||
useBlockSelectionFragment, | ||
useBlockSelectionFragmentProp, | ||
useBlockSelectionNodes, | ||
useIsSelecting, | ||
@@ -1562,0 +1582,0 @@ useSelectionArea |
{ | ||
"name": "@udecode/plate-selection", | ||
"version": "39.1.2", | ||
"version": "39.1.4", | ||
"description": "Plate React plugin to add a visual way of selecting blocks", | ||
@@ -59,3 +59,3 @@ "keywords": [ | ||
"peerDependencies": { | ||
"@udecode/plate-common": ">=39.0.0", | ||
"@udecode/plate-common": ">=39.1.4", | ||
"react": ">=16.8.0", | ||
@@ -62,0 +62,0 @@ "react-dom": ">=16.8.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
600839
6123