@payloadcms/richtext-lexical 3.0.0-beta.35 → 3.0.0-beta.36

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.
Files changed (235) hide show
  1. package/dist/cell/index.d.ts +2 -0
  2. package/dist/cell/index.d.ts.map +1 -1
  3. package/dist/cell/index.js +24 -15
  4. package/dist/cell/index.js.map +1 -1
  5. package/dist/field/Field.d.ts.map +1 -1
  6. package/dist/field/Field.js +66 -47
  7. package/dist/field/Field.js.map +1 -1
  8. package/dist/field/features/blocks/component/BlockContent.js +62 -45
  9. package/dist/field/features/blocks/component/BlockContent.js.map +1 -1
  10. package/dist/field/features/blocks/component/index.js +38 -28
  11. package/dist/field/features/blocks/component/index.js.map +1 -1
  12. package/dist/field/features/blocks/drawer/index.js +2 -1
  13. package/dist/field/features/blocks/drawer/index.js.map +1 -1
  14. package/dist/field/features/blocks/nodes/BlocksNode.d.ts +1 -1
  15. package/dist/field/features/blocks/nodes/BlocksNode.d.ts.map +1 -1
  16. package/dist/field/features/blocks/nodes/BlocksNode.js +2 -1
  17. package/dist/field/features/blocks/nodes/BlocksNode.js.map +1 -1
  18. package/dist/field/features/blocks/plugin/index.js +2 -1
  19. package/dist/field/features/blocks/plugin/index.js.map +1 -1
  20. package/dist/field/features/debug/testRecorder/plugin/index.js +65 -39
  21. package/dist/field/features/debug/testRecorder/plugin/index.js.map +1 -1
  22. package/dist/field/features/debug/treeView/plugin/index.js +2 -1
  23. package/dist/field/features/debug/treeView/plugin/index.js.map +1 -1
  24. package/dist/field/features/horizontalRule/nodes/HorizontalRuleNode.js +2 -1
  25. package/dist/field/features/horizontalRule/nodes/HorizontalRuleNode.js.map +1 -1
  26. package/dist/field/features/link/drawer/index.js +30 -22
  27. package/dist/field/features/link/drawer/index.js.map +1 -1
  28. package/dist/field/features/link/plugins/clickableLink/index.js +2 -1
  29. package/dist/field/features/link/plugins/clickableLink/index.js.map +1 -1
  30. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.d.ts.map +1 -1
  31. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js +88 -70
  32. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js.map +1 -1
  33. package/dist/field/features/link/plugins/floatingLinkEditor/index.js +2 -1
  34. package/dist/field/features/link/plugins/floatingLinkEditor/index.js.map +1 -1
  35. package/dist/field/features/lists/checklist/plugin/index.js +2 -1
  36. package/dist/field/features/lists/checklist/plugin/index.js.map +1 -1
  37. package/dist/field/features/lists/plugin/index.js +2 -1
  38. package/dist/field/features/lists/plugin/index.js.map +1 -1
  39. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/Component.js +9 -1
  40. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/Component.js.map +1 -1
  41. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.d.ts +1 -1
  42. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.d.ts.map +1 -1
  43. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.js +2 -1
  44. package/dist/field/features/migrations/lexicalPluginToLexical/nodes/unknownConvertedNode/index.js.map +1 -1
  45. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/Component.js +9 -1
  46. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/Component.js.map +1 -1
  47. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.d.ts +1 -1
  48. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.d.ts.map +1 -1
  49. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.js +2 -1
  50. package/dist/field/features/migrations/slateToLexical/nodes/unknownConvertedNode/index.js.map +1 -1
  51. package/dist/field/features/relationship/drawer/index.js +10 -2
  52. package/dist/field/features/relationship/drawer/index.js.map +1 -1
  53. package/dist/field/features/relationship/nodes/RelationshipNode.d.ts +1 -1
  54. package/dist/field/features/relationship/nodes/RelationshipNode.d.ts.map +1 -1
  55. package/dist/field/features/relationship/nodes/RelationshipNode.js +2 -1
  56. package/dist/field/features/relationship/nodes/RelationshipNode.js.map +1 -1
  57. package/dist/field/features/relationship/nodes/components/RelationshipComponent.js +64 -44
  58. package/dist/field/features/relationship/nodes/components/RelationshipComponent.js.map +1 -1
  59. package/dist/field/features/relationship/plugins/index.js +2 -1
  60. package/dist/field/features/relationship/plugins/index.js.map +1 -1
  61. package/dist/field/features/toolbars/fixed/Toolbar/index.js +60 -55
  62. package/dist/field/features/toolbars/fixed/Toolbar/index.js.map +1 -1
  63. package/dist/field/features/toolbars/fixed/Toolbar/index.scss +16 -2
  64. package/dist/field/features/toolbars/inline/Toolbar/index.js +57 -49
  65. package/dist/field/features/toolbars/inline/Toolbar/index.js.map +1 -1
  66. package/dist/field/features/toolbars/shared/ToolbarButton/index.d.ts +1 -1
  67. package/dist/field/features/toolbars/shared/ToolbarButton/index.d.ts.map +1 -1
  68. package/dist/field/features/toolbars/shared/ToolbarButton/index.js +5 -3
  69. package/dist/field/features/toolbars/shared/ToolbarButton/index.js.map +1 -1
  70. package/dist/field/features/toolbars/shared/ToolbarDropdown/DropDown.d.ts.map +1 -1
  71. package/dist/field/features/toolbars/shared/ToolbarDropdown/DropDown.js +54 -35
  72. package/dist/field/features/toolbars/shared/ToolbarDropdown/DropDown.js.map +1 -1
  73. package/dist/field/features/toolbars/shared/ToolbarDropdown/index.d.ts +1 -1
  74. package/dist/field/features/toolbars/shared/ToolbarDropdown/index.d.ts.map +1 -1
  75. package/dist/field/features/toolbars/shared/ToolbarDropdown/index.js +25 -22
  76. package/dist/field/features/toolbars/shared/ToolbarDropdown/index.js.map +1 -1
  77. package/dist/field/features/upload/component/ExtraFieldsDrawer/index.js +30 -22
  78. package/dist/field/features/upload/component/ExtraFieldsDrawer/index.js.map +1 -1
  79. package/dist/field/features/upload/component/index.js +104 -71
  80. package/dist/field/features/upload/component/index.js.map +1 -1
  81. package/dist/field/features/upload/drawer/index.js +8 -4
  82. package/dist/field/features/upload/drawer/index.js.map +1 -1
  83. package/dist/field/features/upload/nodes/UploadNode.d.ts +1 -1
  84. package/dist/field/features/upload/nodes/UploadNode.d.ts.map +1 -1
  85. package/dist/field/features/upload/nodes/UploadNode.js +2 -1
  86. package/dist/field/features/upload/nodes/UploadNode.js.map +1 -1
  87. package/dist/field/features/upload/plugin/index.js +2 -1
  88. package/dist/field/features/upload/plugin/index.js.map +1 -1
  89. package/dist/field/index.d.ts +2 -0
  90. package/dist/field/index.d.ts.map +1 -1
  91. package/dist/field/index.js +29 -21
  92. package/dist/field/index.js.map +1 -1
  93. package/dist/field/index.scss +0 -19
  94. package/dist/field/lexical/EditorFocusProvider.d.ts +1 -2
  95. package/dist/field/lexical/EditorFocusProvider.d.ts.map +1 -1
  96. package/dist/field/lexical/EditorFocusProvider.js +5 -3
  97. package/dist/field/lexical/EditorFocusProvider.js.map +1 -1
  98. package/dist/field/lexical/EditorPlugin.js +3 -2
  99. package/dist/field/lexical/EditorPlugin.js.map +1 -1
  100. package/dist/field/lexical/LexicalEditor.js +113 -81
  101. package/dist/field/lexical/LexicalEditor.js.map +1 -1
  102. package/dist/field/lexical/LexicalEditor.scss +10 -1
  103. package/dist/field/lexical/LexicalProvider.js +16 -10
  104. package/dist/field/lexical/LexicalProvider.js.map +1 -1
  105. package/dist/field/lexical/config/client/EditorConfigProvider.js +5 -3
  106. package/dist/field/lexical/config/client/EditorConfigProvider.js.map +1 -1
  107. package/dist/field/lexical/config/client/sanitize.d.ts +2 -1
  108. package/dist/field/lexical/config/client/sanitize.d.ts.map +1 -1
  109. package/dist/field/lexical/config/client/sanitize.js +2 -1
  110. package/dist/field/lexical/config/client/sanitize.js.map +1 -1
  111. package/dist/field/lexical/config/types.d.ts +2 -0
  112. package/dist/field/lexical/config/types.d.ts.map +1 -1
  113. package/dist/field/lexical/config/types.js.map +1 -1
  114. package/dist/field/lexical/plugins/MarkdownShortcut/index.js +2 -1
  115. package/dist/field/lexical/plugins/MarkdownShortcut/index.js.map +1 -1
  116. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.d.ts +1 -1
  117. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.d.ts.map +1 -1
  118. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu.js.map +1 -1
  119. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.d.ts +1 -1
  120. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.d.ts.map +1 -1
  121. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.js +2 -1
  122. package/dist/field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index.js.map +1 -1
  123. package/dist/field/lexical/plugins/SlashMenu/index.js +51 -40
  124. package/dist/field/lexical/plugins/SlashMenu/index.js.map +1 -1
  125. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.d.ts +2 -2
  126. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.d.ts.map +1 -1
  127. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.js +38 -119
  128. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.js.map +1 -1
  129. package/dist/field/lexical/plugins/handles/AddBlockHandlePlugin/index.scss +2 -2
  130. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/highlightElemOriginalPosition.d.ts +1 -1
  131. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/highlightElemOriginalPosition.d.ts.map +1 -1
  132. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/highlightElemOriginalPosition.js.map +1 -1
  133. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.d.ts +2 -2
  134. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.d.ts.map +1 -1
  135. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.js +102 -58
  136. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.js.map +1 -1
  137. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/index.scss +12 -3
  138. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.d.ts +8 -1
  139. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.d.ts.map +1 -1
  140. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.js +73 -25
  141. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.js.map +1 -1
  142. package/dist/field/lexical/plugins/handles/utils/calculateDistanceFromScrollerElem.d.ts +5 -0
  143. package/dist/field/lexical/plugins/handles/utils/calculateDistanceFromScrollerElem.d.ts.map +1 -0
  144. package/dist/field/lexical/plugins/handles/utils/calculateDistanceFromScrollerElem.js +21 -0
  145. package/dist/field/lexical/plugins/handles/utils/calculateDistanceFromScrollerElem.js.map +1 -0
  146. package/dist/field/lexical/plugins/handles/{DraggableBlockPlugin → utils}/getNodeCloseToPoint.d.ts +4 -0
  147. package/dist/field/lexical/plugins/handles/utils/getNodeCloseToPoint.d.ts.map +1 -0
  148. package/dist/field/lexical/plugins/handles/{DraggableBlockPlugin → utils}/getNodeCloseToPoint.js +2 -14
  149. package/dist/field/lexical/plugins/handles/utils/getNodeCloseToPoint.js.map +1 -0
  150. package/dist/field/lexical/plugins/handles/utils/setHandlePosition.d.ts.map +1 -1
  151. package/dist/field/lexical/plugins/handles/utils/setHandlePosition.js +4 -2
  152. package/dist/field/lexical/plugins/handles/utils/setHandlePosition.js.map +1 -1
  153. package/dist/field/lexical/theme/EditorTheme.scss +5 -0
  154. package/dist/field/lexical/ui/ContentEditable.d.ts +1 -1
  155. package/dist/field/lexical/ui/ContentEditable.d.ts.map +1 -1
  156. package/dist/field/lexical/ui/ContentEditable.js +2 -1
  157. package/dist/field/lexical/ui/ContentEditable.js.map +1 -1
  158. package/dist/field/lexical/ui/ContentEditable.scss +50 -2
  159. package/dist/field/lexical/ui/icons/AI/index.js +26 -17
  160. package/dist/field/lexical/ui/icons/AI/index.js.map +1 -1
  161. package/dist/field/lexical/ui/icons/Add/index.js +14 -9
  162. package/dist/field/lexical/ui/icons/Add/index.js.map +1 -1
  163. package/dist/field/lexical/ui/icons/Add/light.svg +4 -0
  164. package/dist/field/lexical/ui/icons/AlignCenter/index.js +21 -15
  165. package/dist/field/lexical/ui/icons/AlignCenter/index.js.map +1 -1
  166. package/dist/field/lexical/ui/icons/AlignJustify/index.js +21 -15
  167. package/dist/field/lexical/ui/icons/AlignJustify/index.js.map +1 -1
  168. package/dist/field/lexical/ui/icons/AlignLeft/index.js +21 -15
  169. package/dist/field/lexical/ui/icons/AlignLeft/index.js.map +1 -1
  170. package/dist/field/lexical/ui/icons/AlignRight/index.js +21 -15
  171. package/dist/field/lexical/ui/icons/AlignRight/index.js.map +1 -1
  172. package/dist/field/lexical/ui/icons/Block/index.js +30 -24
  173. package/dist/field/lexical/ui/icons/Block/index.js.map +1 -1
  174. package/dist/field/lexical/ui/icons/Blockquote/index.js +8 -6
  175. package/dist/field/lexical/ui/icons/Blockquote/index.js.map +1 -1
  176. package/dist/field/lexical/ui/icons/Bold/index.js +8 -6
  177. package/dist/field/lexical/ui/icons/Bold/index.js.map +1 -1
  178. package/dist/field/lexical/ui/icons/Checklist/index.js +19 -14
  179. package/dist/field/lexical/ui/icons/Checklist/index.js.map +1 -1
  180. package/dist/field/lexical/ui/icons/Code/index.js +14 -9
  181. package/dist/field/lexical/ui/icons/Code/index.js.map +1 -1
  182. package/dist/field/lexical/ui/icons/CodeBlock/index.js +14 -9
  183. package/dist/field/lexical/ui/icons/CodeBlock/index.js.map +1 -1
  184. package/dist/field/lexical/ui/icons/DraggableBlock/light.svg +9 -0
  185. package/dist/field/lexical/ui/icons/H1/index.js +8 -6
  186. package/dist/field/lexical/ui/icons/H1/index.js.map +1 -1
  187. package/dist/field/lexical/ui/icons/H2/index.js +8 -6
  188. package/dist/field/lexical/ui/icons/H2/index.js.map +1 -1
  189. package/dist/field/lexical/ui/icons/H3/index.js +8 -6
  190. package/dist/field/lexical/ui/icons/H3/index.js.map +1 -1
  191. package/dist/field/lexical/ui/icons/H4/index.js +8 -6
  192. package/dist/field/lexical/ui/icons/H4/index.js.map +1 -1
  193. package/dist/field/lexical/ui/icons/H5/index.js +8 -6
  194. package/dist/field/lexical/ui/icons/H5/index.js.map +1 -1
  195. package/dist/field/lexical/ui/icons/H6/index.js +8 -6
  196. package/dist/field/lexical/ui/icons/H6/index.js.map +1 -1
  197. package/dist/field/lexical/ui/icons/HorizontalRule/index.js +11 -9
  198. package/dist/field/lexical/ui/icons/HorizontalRule/index.js.map +1 -1
  199. package/dist/field/lexical/ui/icons/IndentDecrease/index.js +25 -18
  200. package/dist/field/lexical/ui/icons/IndentDecrease/index.js.map +1 -1
  201. package/dist/field/lexical/ui/icons/IndentIncrease/index.js +25 -18
  202. package/dist/field/lexical/ui/icons/IndentIncrease/index.js.map +1 -1
  203. package/dist/field/lexical/ui/icons/Italic/index.js +8 -6
  204. package/dist/field/lexical/ui/icons/Italic/index.js.map +1 -1
  205. package/dist/field/lexical/ui/icons/Link/index.js +26 -17
  206. package/dist/field/lexical/ui/icons/Link/index.js.map +1 -1
  207. package/dist/field/lexical/ui/icons/OrderedList/index.js +29 -21
  208. package/dist/field/lexical/ui/icons/OrderedList/index.js.map +1 -1
  209. package/dist/field/lexical/ui/icons/Relationship/index.js +26 -17
  210. package/dist/field/lexical/ui/icons/Relationship/index.js.map +1 -1
  211. package/dist/field/lexical/ui/icons/Strikethrough/index.js +14 -9
  212. package/dist/field/lexical/ui/icons/Strikethrough/index.js.map +1 -1
  213. package/dist/field/lexical/ui/icons/Subscript/index.js +8 -6
  214. package/dist/field/lexical/ui/icons/Subscript/index.js.map +1 -1
  215. package/dist/field/lexical/ui/icons/Superscript/index.js +8 -6
  216. package/dist/field/lexical/ui/icons/Superscript/index.js.map +1 -1
  217. package/dist/field/lexical/ui/icons/Text/index.js +8 -6
  218. package/dist/field/lexical/ui/icons/Text/index.js.map +1 -1
  219. package/dist/field/lexical/ui/icons/Underline/index.js +14 -9
  220. package/dist/field/lexical/ui/icons/Underline/index.js.map +1 -1
  221. package/dist/field/lexical/ui/icons/UnorderedList/index.js +45 -36
  222. package/dist/field/lexical/ui/icons/UnorderedList/index.js.map +1 -1
  223. package/dist/field/lexical/ui/icons/Upload/index.js +24 -18
  224. package/dist/field/lexical/ui/icons/Upload/index.js.map +1 -1
  225. package/dist/generateComponentMap.js +8 -8
  226. package/dist/generateComponentMap.js.map +1 -1
  227. package/dist/index.d.ts.map +1 -1
  228. package/dist/index.js +2 -0
  229. package/dist/index.js.map +1 -1
  230. package/dist/types.d.ts +7 -0
  231. package/dist/types.d.ts.map +1 -1
  232. package/dist/types.js.map +1 -1
  233. package/package.json +17 -13
  234. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.d.ts.map +0 -1
  235. package/dist/field/lexical/plugins/handles/DraggableBlockPlugin/getNodeCloseToPoint.js.map +0 -1
@@ -1,20 +1,22 @@
1
1
  'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js';
3
4
  import { eventFiles } from '@lexical/rich-text';
4
5
  import { $getNearestNodeFromDOMNode, $getNodeByKey } from 'lexical';
5
6
  import * as React from 'react';
6
- import { useCallback, useEffect, useRef, useState } from 'react';
7
+ import { useEffect, useRef, useState } from 'react';
7
8
  import { createPortal } from 'react-dom';
9
+ import { useEditorConfigContext } from '../../../config/client/EditorConfigProvider.js';
8
10
  import { isHTMLElement } from '../../../utils/guard.js';
9
11
  import { Point } from '../../../utils/point.js';
12
+ import { calculateDistanceFromScrollerElem } from '../utils/calculateDistanceFromScrollerElem.js';
13
+ import { getNodeCloseToPoint } from '../utils/getNodeCloseToPoint.js';
10
14
  import { getTopLevelNodeKeys } from '../utils/getTopLevelNodeKeys.js';
11
15
  import { isOnHandleElement } from '../utils/isOnHandleElement.js';
12
16
  import { setHandlePosition } from '../utils/setHandlePosition.js';
13
17
  import { getBoundingClientRectWithoutTransform } from './getBoundingRectWithoutTransform.js';
14
- import { getNodeCloseToPoint } from './getNodeCloseToPoint.js';
15
18
  import './index.scss';
16
19
  import { setTargetLine } from './setTargetLine.js';
17
- const SPACE = -24;
18
20
  const DRAGGABLE_BLOCK_MENU_CLASSNAME = 'draggable-block-menu';
19
21
  const DRAG_DATA_FORMAT = 'application/x-lexical-drag-block';
20
22
  let prevIndex = Infinity;
@@ -41,11 +43,10 @@ function hideTargetLine(targetLineElem, lastTargetBlockElem) {
41
43
  }
42
44
  if (lastTargetBlockElem) {
43
45
  lastTargetBlockElem.style.opacity = '';
44
- lastTargetBlockElem.style.transform = '';
45
46
  // Delete marginBottom and marginTop values we set
46
47
  lastTargetBlockElem.style.marginBottom = '';
47
48
  lastTargetBlockElem.style.marginTop = '';
48
- //lastTargetBlockElem.style.border = 'none'
49
+ //lastTargetBlock.style.border = 'none'
49
50
  }
50
51
  }
51
52
  function useDraggableBlockMenu(editor, anchorElem, isEditable) {
@@ -55,28 +56,9 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
55
56
  const debugHighlightRef = useRef(null);
56
57
  const isDraggingBlockRef = useRef(false);
57
58
  const [draggableBlockElem, setDraggableBlockElem] = useState(null);
58
- const [lastTargetBlockElem, setLastTargetBlockElem] = useState(null);
59
- const calculateDistanceFromScrollerElem = useCallback((pageX, pageY, target, horizontalBuffer = 50, verticalBuffer = 25)=>{
60
- let distanceFromScrollerElem = 0;
61
- // Calculate distance between scrollerElem and target if target is not in scrollerElem
62
- if (scrollerElem && !scrollerElem.contains(target)) {
63
- const { bottom, left, right, top } = scrollerElem.getBoundingClientRect();
64
- const adjustedTop = top + window.scrollY;
65
- const adjustedBottom = bottom + window.scrollY;
66
- if (pageY < adjustedTop - verticalBuffer || pageY > adjustedBottom + verticalBuffer || pageX < left - horizontalBuffer || pageX > right + horizontalBuffer) {
67
- setDraggableBlockElem(null);
68
- return distanceFromScrollerElem;
69
- }
70
- // This is used to allow the _draggableBlockElem to be found when the mouse is in the
71
- // buffer zone around the scrollerElem.
72
- if (pageX < left || pageX > right) {
73
- distanceFromScrollerElem = pageX < left ? pageX - left : pageX - right;
74
- }
75
- }
76
- return distanceFromScrollerElem;
77
- }, [
78
- scrollerElem
79
- ]);
59
+ const [lastTargetBlock, setLastTargetBlock] = useState(null);
60
+ const { editorConfig } = useEditorConfigContext();
61
+ const blockHandleHorizontalOffset = editorConfig?.admin?.hideGutter ? -44 : -8;
80
62
  useEffect(()=>{
81
63
  /**
82
64
  * Handles positioning of the drag handle
@@ -85,7 +67,11 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
85
67
  if (!isHTMLElement(target)) {
86
68
  return;
87
69
  }
88
- const distanceFromScrollerElem = calculateDistanceFromScrollerElem(event.pageX, event.pageY, target);
70
+ const distanceFromScrollerElem = calculateDistanceFromScrollerElem(scrollerElem, event.pageX, event.pageY, target);
71
+ if (distanceFromScrollerElem === -1) {
72
+ setDraggableBlockElem(null);
73
+ return;
74
+ }
89
75
  if (isOnHandleElement(target, DRAGGABLE_BLOCK_MENU_CLASSNAME)) {
90
76
  return;
91
77
  }
@@ -97,13 +83,14 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
97
83
  horizontalOffset: -distanceFromScrollerElem,
98
84
  point: new Point(event.x, event.y),
99
85
  startIndex: getCurrentIndex(topLevelNodeKeys.length),
100
- useEdgeAsDefault: false
86
+ useEdgeAsDefault: false,
87
+ verbose: false
101
88
  });
89
+ prevIndex = foundAtIndex;
102
90
  //if (DEBUG && _draggableBlockElem) {
103
91
  //targetBlockElem.style.border = '3px solid red'
104
92
  // highlightElemOriginalPosition(debugHighlightRef, _draggableBlockElem, anchorElem)
105
93
  //}
106
- prevIndex = foundAtIndex;
107
94
  if (!_draggableBlockElem && !isFoundNodeEmptyParagraph) {
108
95
  return;
109
96
  }
@@ -112,7 +99,7 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
112
99
  }
113
100
  }
114
101
  // Since the draggableBlockElem is outside the actual editor, we need to listen to the document
115
- // to be able to detect when the mouse is outside the editor and respect a buffer around the
102
+ // to be able to detect when the mouse is outside the editor and respect a buffer around
116
103
  // the scrollerElem to avoid the draggableBlockElem disappearing too early.
117
104
  document?.addEventListener('mousemove', onDocumentMouseMove);
118
105
  return ()=>{
@@ -122,16 +109,16 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
122
109
  scrollerElem,
123
110
  anchorElem,
124
111
  editor,
125
- calculateDistanceFromScrollerElem,
126
112
  draggableBlockElem
127
113
  ]);
128
114
  useEffect(()=>{
129
115
  if (menuRef.current) {
130
- setHandlePosition(draggableBlockElem, menuRef.current, anchorElem, SPACE);
116
+ setHandlePosition(draggableBlockElem, menuRef.current, anchorElem, blockHandleHorizontalOffset);
131
117
  }
132
118
  }, [
133
119
  anchorElem,
134
- draggableBlockElem
120
+ draggableBlockElem,
121
+ blockHandleHorizontalOffset
135
122
  ]);
136
123
  useEffect(()=>{
137
124
  function onDragover(event) {
@@ -146,7 +133,7 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
146
133
  if (!isHTMLElement(target)) {
147
134
  return false;
148
135
  }
149
- const distanceFromScrollerElem = calculateDistanceFromScrollerElem(event.pageX, event.pageY, target, 100, 50);
136
+ const distanceFromScrollerElem = calculateDistanceFromScrollerElem(scrollerElem, event.pageX, event.pageY, target, 100, 50);
150
137
  const topLevelNodeKeys = getTopLevelNodeKeys(editor);
151
138
  const { blockElem: targetBlockElem, foundAtIndex, isFoundNodeEmptyParagraph } = getNodeCloseToPoint({
152
139
  anchorElem,
@@ -165,15 +152,26 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
165
152
  return false;
166
153
  }
167
154
  if (draggableBlockElem !== targetBlockElem) {
168
- setTargetLine(SPACE, targetLineElem, targetBlockElem, lastTargetBlockElem, pageY, anchorElem, event, debugHighlightRef, isFoundNodeEmptyParagraph);
155
+ const { isBelow, willStayInSamePosition } = setTargetLine(editorConfig?.admin?.hideGutter ? '0px' : '3rem', blockHandleHorizontalOffset + (editorConfig?.admin?.hideGutter ? menuRef?.current?.getBoundingClientRect()?.width ?? 0 : -menuRef?.current?.getBoundingClientRect()?.width ?? 0), targetLineElem, targetBlockElem, lastTargetBlock, pageY, anchorElem, event, debugHighlightRef, isFoundNodeEmptyParagraph);
169
156
  // Prevent default event to be able to trigger onDrop events
170
157
  // Calling preventDefault() adds the green plus icon to the cursor,
171
158
  // indicating that the drop is allowed.
172
159
  event.preventDefault();
160
+ if (!willStayInSamePosition) {
161
+ setLastTargetBlock({
162
+ boundingBox: targetBlockElem.getBoundingClientRect(),
163
+ elem: targetBlockElem,
164
+ isBelow
165
+ });
166
+ }
173
167
  } else {
174
- hideTargetLine(targetLineElem, lastTargetBlockElem);
168
+ hideTargetLine(targetLineElem, lastTargetBlock?.elem);
169
+ setLastTargetBlock({
170
+ boundingBox: targetBlockElem.getBoundingClientRect(),
171
+ elem: targetBlockElem,
172
+ isBelow: false
173
+ });
175
174
  }
176
- setLastTargetBlockElem(targetBlockElem);
177
175
  return true;
178
176
  }
179
177
  function onDrop(event) {
@@ -194,7 +192,7 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
194
192
  if (!isHTMLElement(target)) {
195
193
  return false;
196
194
  }
197
- const distanceFromScrollerElem = calculateDistanceFromScrollerElem(event.pageX, event.pageY, target, 100, 50);
195
+ const distanceFromScrollerElem = calculateDistanceFromScrollerElem(scrollerElem, event.pageX, event.pageY, target, 100, 50);
198
196
  const { blockElem: targetBlockElem, isFoundNodeEmptyParagraph } = getNodeCloseToPoint({
199
197
  anchorElem,
200
198
  editor,
@@ -237,6 +235,43 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
237
235
  }*/ if (draggableBlockElem !== null) {
238
236
  setDraggableBlockElem(null);
239
237
  }
238
+ // find all previous elements with lexical-block-highlighter class and remove them
239
+ const allPrevHighlighters = document.querySelectorAll('.lexical-block-highlighter');
240
+ allPrevHighlighters.forEach((highlighter)=>{
241
+ highlighter.remove();
242
+ });
243
+ const newInsertedElem = editor.getElementByKey(draggedNode.getKey());
244
+ setTimeout(()=>{
245
+ // add new temp html element to newInsertedElem with the same height and width and the class block-selected
246
+ // to highlight the new inserted element
247
+ const newInsertedElemRect = newInsertedElem.getBoundingClientRect();
248
+ const highlightElem = document.createElement('div');
249
+ highlightElem.className = 'lexical-block-highlighter';
250
+ // if html data-theme is dark, set the highlighter color to white
251
+ if (document.documentElement.getAttribute('data-theme') === 'dark') {
252
+ highlightElem.style.backgroundColor = 'white';
253
+ } else {
254
+ highlightElem.style.backgroundColor = 'black';
255
+ }
256
+ highlightElem.style.transition = 'opacity 0.1s ease-in-out';
257
+ highlightElem.style.zIndex = '1';
258
+ highlightElem.style.pointerEvents = 'none';
259
+ highlightElem.style.boxSizing = 'border-box';
260
+ highlightElem.style.borderRadius = '4px';
261
+ highlightElem.style.position = 'absolute';
262
+ document.body.appendChild(highlightElem);
263
+ highlightElem.style.opacity = '0.1';
264
+ highlightElem.style.height = `${newInsertedElemRect.height + 8}px`;
265
+ highlightElem.style.width = `${newInsertedElemRect.width + 8}px`;
266
+ highlightElem.style.top = `${newInsertedElemRect.top + window.scrollY - 4}px`;
267
+ highlightElem.style.left = `${newInsertedElemRect.left - 4}px`;
268
+ setTimeout(()=>{
269
+ highlightElem.style.opacity = '0';
270
+ setTimeout(()=>{
271
+ highlightElem.remove();
272
+ }, 1000);
273
+ }, 3000);
274
+ }, 120);
240
275
  });
241
276
  return true;
242
277
  }
@@ -249,11 +284,13 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
249
284
  document.removeEventListener('drop', onDrop);
250
285
  };
251
286
  }, [
287
+ scrollerElem,
288
+ blockHandleHorizontalOffset,
252
289
  anchorElem,
253
290
  editor,
254
- lastTargetBlockElem,
255
- calculateDistanceFromScrollerElem,
256
- draggableBlockElem
291
+ lastTargetBlock,
292
+ draggableBlockElem,
293
+ editorConfig?.admin?.hideGutter
257
294
  ]);
258
295
  function onDragStart(event) {
259
296
  const dataTransfer = event.dataTransfer;
@@ -273,23 +310,30 @@ function useDraggableBlockMenu(editor, anchorElem, isEditable) {
273
310
  }
274
311
  function onDragEnd() {
275
312
  isDraggingBlockRef.current = false;
276
- hideTargetLine(targetLineRef.current, lastTargetBlockElem);
313
+ hideTargetLine(targetLineRef.current, lastTargetBlock?.elem);
277
314
  }
278
- return /*#__PURE__*/ createPortal(/*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement("div", {
279
- className: "icon draggable-block-menu",
280
- draggable: true,
281
- onDragEnd: onDragEnd,
282
- onDragStart: onDragStart,
283
- ref: menuRef
284
- }, /*#__PURE__*/ React.createElement("div", {
285
- className: isEditable ? 'icon' : ''
286
- })), /*#__PURE__*/ React.createElement("div", {
287
- className: "draggable-block-target-line",
288
- ref: targetLineRef
289
- }), /*#__PURE__*/ React.createElement("div", {
290
- className: "debug-highlight",
291
- ref: debugHighlightRef
292
- })), anchorElem);
315
+ return /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsxs(React.Fragment, {
316
+ children: [
317
+ /*#__PURE__*/ _jsx("div", {
318
+ className: "icon draggable-block-menu",
319
+ draggable: true,
320
+ onDragEnd: onDragEnd,
321
+ onDragStart: onDragStart,
322
+ ref: menuRef,
323
+ children: /*#__PURE__*/ _jsx("div", {
324
+ className: isEditable ? 'icon' : ''
325
+ })
326
+ }),
327
+ /*#__PURE__*/ _jsx("div", {
328
+ className: "draggable-block-target-line",
329
+ ref: targetLineRef
330
+ }),
331
+ /*#__PURE__*/ _jsx("div", {
332
+ className: "debug-highlight",
333
+ ref: debugHighlightRef
334
+ })
335
+ ]
336
+ }), anchorElem);
293
337
  }
294
338
  export function DraggableBlockPlugin({ anchorElem = document.body }) {
295
339
  const [editor] = useLexicalComposerContext();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\nimport type { DragEvent as ReactDragEvent } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { eventFiles } from '@lexical/rich-text'\nimport { $getNearestNodeFromDOMNode, $getNodeByKey } from 'lexical'\nimport * as React from 'react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { isHTMLElement } from '../../../utils/guard.js'\nimport { Point } from '../../../utils/point.js'\nimport { getTopLevelNodeKeys } from '../utils/getTopLevelNodeKeys.js'\nimport { isOnHandleElement } from '../utils/isOnHandleElement.js'\nimport { setHandlePosition } from '../utils/setHandlePosition.js'\nimport { getBoundingClientRectWithoutTransform } from './getBoundingRectWithoutTransform.js'\nimport { getNodeCloseToPoint } from './getNodeCloseToPoint.js'\nimport './index.scss'\nimport { setTargetLine } from './setTargetLine.js'\n\nconst SPACE = -24\nconst DRAGGABLE_BLOCK_MENU_CLASSNAME = 'draggable-block-menu'\nconst DRAG_DATA_FORMAT = 'application/x-lexical-drag-block'\n\nlet prevIndex = Infinity\n\nfunction getCurrentIndex(keysLength: number): number {\n if (keysLength === 0) {\n return Infinity\n }\n if (prevIndex >= 0 && prevIndex < keysLength) {\n return prevIndex\n }\n\n return Math.floor(keysLength / 2)\n}\n\nfunction setDragImage(dataTransfer: DataTransfer, draggableBlockElem: HTMLElement) {\n const { transform } = draggableBlockElem.style\n\n // Remove dragImage borders\n dataTransfer.setDragImage(draggableBlockElem, 0, 0)\n\n setTimeout(() => {\n draggableBlockElem.style.transform = transform\n })\n}\n\nfunction hideTargetLine(\n targetLineElem: HTMLElement | null,\n lastTargetBlockElem: HTMLElement | null,\n) {\n if (targetLineElem) {\n targetLineElem.style.opacity = '0'\n }\n if (lastTargetBlockElem) {\n lastTargetBlockElem.style.opacity = ''\n lastTargetBlockElem.style.transform = ''\n // Delete marginBottom and marginTop values we set\n lastTargetBlockElem.style.marginBottom = ''\n lastTargetBlockElem.style.marginTop = ''\n //lastTargetBlockElem.style.border = 'none'\n }\n}\n\nfunction useDraggableBlockMenu(\n editor: LexicalEditor,\n anchorElem: HTMLElement,\n isEditable: boolean,\n): JSX.Element {\n const scrollerElem = anchorElem.parentElement\n\n const menuRef = useRef<HTMLDivElement>(null)\n const targetLineRef = useRef<HTMLDivElement>(null)\n const debugHighlightRef = useRef<HTMLDivElement>(null)\n const isDraggingBlockRef = useRef<boolean>(false)\n const [draggableBlockElem, setDraggableBlockElem] = useState<HTMLElement | null>(null)\n const [lastTargetBlockElem, setLastTargetBlockElem] = useState<HTMLElement | null>(null)\n\n const calculateDistanceFromScrollerElem = useCallback(\n (\n pageX: number,\n pageY: number,\n target: HTMLElement,\n horizontalBuffer: number = 50,\n verticalBuffer: number = 25,\n ): number => {\n let distanceFromScrollerElem = 0\n // Calculate distance between scrollerElem and target if target is not in scrollerElem\n if (scrollerElem && !scrollerElem.contains(target)) {\n const { bottom, left, right, top } = scrollerElem.getBoundingClientRect()\n\n const adjustedTop = top + window.scrollY\n const adjustedBottom = bottom + window.scrollY\n\n if (\n pageY < adjustedTop - verticalBuffer ||\n pageY > adjustedBottom + verticalBuffer ||\n pageX < left - horizontalBuffer ||\n pageX > right + horizontalBuffer\n ) {\n setDraggableBlockElem(null)\n return distanceFromScrollerElem\n }\n\n // This is used to allow the _draggableBlockElem to be found when the mouse is in the\n // buffer zone around the scrollerElem.\n if (pageX < left || pageX > right) {\n distanceFromScrollerElem = pageX < left ? pageX - left : pageX - right\n }\n }\n return distanceFromScrollerElem\n },\n [scrollerElem],\n )\n\n useEffect(() => {\n /**\n * Handles positioning of the drag handle\n */\n function onDocumentMouseMove(event: MouseEvent) {\n const target = event.target\n if (!isHTMLElement(target)) {\n return\n }\n\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n event.pageX,\n event.pageY,\n target,\n )\n\n if (isOnHandleElement(target, DRAGGABLE_BLOCK_MENU_CLASSNAME)) {\n return\n }\n\n const topLevelNodeKeys = getTopLevelNodeKeys(editor)\n const {\n blockElem: _draggableBlockElem,\n foundAtIndex,\n isFoundNodeEmptyParagraph,\n } = getNodeCloseToPoint({\n anchorElem,\n cache_threshold: 0,\n editor,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n startIndex: getCurrentIndex(topLevelNodeKeys.length),\n useEdgeAsDefault: false,\n })\n //if (DEBUG && _draggableBlockElem) {\n //targetBlockElem.style.border = '3px solid red'\n // highlightElemOriginalPosition(debugHighlightRef, _draggableBlockElem, anchorElem)\n //}\n prevIndex = foundAtIndex\n\n if (!_draggableBlockElem && !isFoundNodeEmptyParagraph) {\n return\n }\n\n if (draggableBlockElem !== _draggableBlockElem) {\n setDraggableBlockElem(_draggableBlockElem)\n }\n }\n\n // Since the draggableBlockElem is outside the actual editor, we need to listen to the document\n // to be able to detect when the mouse is outside the editor and respect a buffer around the\n // the scrollerElem to avoid the draggableBlockElem disappearing too early.\n document?.addEventListener('mousemove', onDocumentMouseMove)\n\n return () => {\n document?.removeEventListener('mousemove', onDocumentMouseMove)\n }\n }, [scrollerElem, anchorElem, editor, calculateDistanceFromScrollerElem, draggableBlockElem])\n\n useEffect(() => {\n if (menuRef.current) {\n setHandlePosition(draggableBlockElem, menuRef.current, anchorElem, SPACE)\n }\n }, [anchorElem, draggableBlockElem])\n\n useEffect(() => {\n function onDragover(event: DragEvent): boolean {\n if (!isDraggingBlockRef.current) {\n return false\n }\n const [isFileTransfer] = eventFiles(event)\n if (isFileTransfer) {\n return false\n }\n\n const { pageY, target } = event\n if (!isHTMLElement(target)) {\n return false\n }\n\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n event.pageX,\n event.pageY,\n target,\n 100,\n 50,\n )\n\n const topLevelNodeKeys = getTopLevelNodeKeys(editor)\n\n const {\n blockElem: targetBlockElem,\n foundAtIndex,\n isFoundNodeEmptyParagraph,\n } = getNodeCloseToPoint({\n anchorElem,\n editor,\n fuzzy: true,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n startIndex: getCurrentIndex(topLevelNodeKeys.length),\n useEdgeAsDefault: true,\n verbose: true,\n })\n prevIndex = foundAtIndex\n\n const targetLineElem = targetLineRef.current\n // targetBlockElem === null shouldn't happen\n if (targetBlockElem === null || targetLineElem === null) {\n return false\n }\n\n if (draggableBlockElem !== targetBlockElem) {\n setTargetLine(\n SPACE,\n targetLineElem,\n targetBlockElem,\n lastTargetBlockElem,\n pageY,\n anchorElem,\n event,\n debugHighlightRef,\n isFoundNodeEmptyParagraph,\n )\n\n // Prevent default event to be able to trigger onDrop events\n // Calling preventDefault() adds the green plus icon to the cursor,\n // indicating that the drop is allowed.\n event.preventDefault()\n } else {\n hideTargetLine(targetLineElem, lastTargetBlockElem)\n }\n\n setLastTargetBlockElem(targetBlockElem)\n\n return true\n }\n\n function onDrop(event: DragEvent): boolean {\n if (!isDraggingBlockRef.current) {\n return false\n }\n const [isFileTransfer] = eventFiles(event)\n if (isFileTransfer) {\n return false\n }\n const { dataTransfer, pageY, target } = event\n const dragData = dataTransfer?.getData(DRAG_DATA_FORMAT) || ''\n\n editor.update(() => {\n const draggedNode = $getNodeByKey(dragData)\n if (!draggedNode) {\n return false\n }\n if (!isHTMLElement(target)) {\n return false\n }\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n event.pageX,\n event.pageY,\n target,\n 100,\n 50,\n )\n\n const { blockElem: targetBlockElem, isFoundNodeEmptyParagraph } = getNodeCloseToPoint({\n anchorElem,\n editor,\n fuzzy: true,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n useEdgeAsDefault: true,\n })\n\n if (!targetBlockElem) {\n return false\n }\n const targetNode = $getNearestNodeFromDOMNode(targetBlockElem)\n if (!targetNode) {\n return false\n }\n if (targetNode === draggedNode) {\n return true\n }\n\n const { height: targetBlockElemHeight, top: targetBlockElemTop } =\n getBoundingClientRectWithoutTransform(targetBlockElem)\n\n const mouseY = pageY\n const isBelow = mouseY >= targetBlockElemTop + targetBlockElemHeight / 2 + window.scrollY\n\n if (!isFoundNodeEmptyParagraph) {\n if (isBelow) {\n // below targetBlockElem\n targetNode.insertAfter(draggedNode)\n } else {\n // above targetBlockElem\n targetNode.insertBefore(draggedNode)\n }\n } else {\n //\n targetNode.insertBefore(draggedNode)\n targetNode.remove()\n }\n\n /*\n if (pageY >= targetBlockElemTop + targetBlockElemHeight / 2) {\n targetNode.insertAfter(draggedNode)\n } else {\n targetNode.insertBefore(draggedNode)\n }*/\n if (draggableBlockElem !== null) {\n setDraggableBlockElem(null)\n }\n })\n\n return true\n }\n\n // register onDragover event listeners:\n document.addEventListener('dragover', onDragover)\n // register onDrop event listeners:\n document.addEventListener('drop', onDrop)\n\n return () => {\n document.removeEventListener('dragover', onDragover)\n document.removeEventListener('drop', onDrop)\n }\n }, [\n anchorElem,\n editor,\n lastTargetBlockElem,\n calculateDistanceFromScrollerElem,\n draggableBlockElem,\n ])\n\n function onDragStart(event: ReactDragEvent<HTMLDivElement>): void {\n const dataTransfer = event.dataTransfer\n if (!dataTransfer || !draggableBlockElem) {\n return\n }\n setDragImage(dataTransfer, draggableBlockElem)\n let nodeKey = ''\n editor.update(() => {\n const node = $getNearestNodeFromDOMNode(draggableBlockElem)\n if (node) {\n nodeKey = node.getKey()\n }\n })\n isDraggingBlockRef.current = true\n dataTransfer.setData(DRAG_DATA_FORMAT, nodeKey)\n }\n\n function onDragEnd(): void {\n isDraggingBlockRef.current = false\n hideTargetLine(targetLineRef.current, lastTargetBlockElem)\n }\n\n return createPortal(\n <React.Fragment>\n <div\n className=\"icon draggable-block-menu\"\n draggable\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n ref={menuRef}\n >\n <div className={isEditable ? 'icon' : ''} />\n </div>\n <div className=\"draggable-block-target-line\" ref={targetLineRef} />\n <div className=\"debug-highlight\" ref={debugHighlightRef} />\n </React.Fragment>,\n anchorElem,\n )\n}\n\nexport function DraggableBlockPlugin({\n anchorElem = document.body,\n}: {\n anchorElem?: HTMLElement\n}): JSX.Element {\n const [editor] = useLexicalComposerContext()\n return useDraggableBlockMenu(editor, anchorElem, editor._editable)\n}\n"],"names":["useLexicalComposerContext","eventFiles","$getNearestNodeFromDOMNode","$getNodeByKey","React","useCallback","useEffect","useRef","useState","createPortal","isHTMLElement","Point","getTopLevelNodeKeys","isOnHandleElement","setHandlePosition","getBoundingClientRectWithoutTransform","getNodeCloseToPoint","setTargetLine","SPACE","DRAGGABLE_BLOCK_MENU_CLASSNAME","DRAG_DATA_FORMAT","prevIndex","Infinity","getCurrentIndex","keysLength","Math","floor","setDragImage","dataTransfer","draggableBlockElem","transform","style","setTimeout","hideTargetLine","targetLineElem","lastTargetBlockElem","opacity","marginBottom","marginTop","useDraggableBlockMenu","editor","anchorElem","isEditable","scrollerElem","parentElement","menuRef","targetLineRef","debugHighlightRef","isDraggingBlockRef","setDraggableBlockElem","setLastTargetBlockElem","calculateDistanceFromScrollerElem","pageX","pageY","target","horizontalBuffer","verticalBuffer","distanceFromScrollerElem","contains","bottom","left","right","top","getBoundingClientRect","adjustedTop","window","scrollY","adjustedBottom","onDocumentMouseMove","event","topLevelNodeKeys","blockElem","_draggableBlockElem","foundAtIndex","isFoundNodeEmptyParagraph","cache_threshold","horizontalOffset","point","x","y","startIndex","length","useEdgeAsDefault","document","addEventListener","removeEventListener","current","onDragover","isFileTransfer","targetBlockElem","fuzzy","verbose","preventDefault","onDrop","dragData","getData","update","draggedNode","targetNode","height","targetBlockElemHeight","targetBlockElemTop","mouseY","isBelow","insertAfter","insertBefore","remove","onDragStart","nodeKey","node","getKey","setData","onDragEnd","Fragment","div","className","draggable","ref","DraggableBlockPlugin","body","_editable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../src/field/lexical/plugins/handles/DraggableBlockPlugin/index.tsx"],"sourcesContent":["'use client'\nimport type { LexicalEditor } from 'lexical'\nimport type { JSX, DragEvent as ReactDragEvent } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'\nimport { eventFiles } from '@lexical/rich-text'\nimport { $getNearestNodeFromDOMNode, $getNodeByKey } from 'lexical'\nimport * as React from 'react'\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useEditorConfigContext } from '../../../config/client/EditorConfigProvider.js'\nimport { isHTMLElement } from '../../../utils/guard.js'\nimport { Point } from '../../../utils/point.js'\nimport { calculateDistanceFromScrollerElem } from '../utils/calculateDistanceFromScrollerElem.js'\nimport { getNodeCloseToPoint } from '../utils/getNodeCloseToPoint.js'\nimport { getTopLevelNodeKeys } from '../utils/getTopLevelNodeKeys.js'\nimport { isOnHandleElement } from '../utils/isOnHandleElement.js'\nimport { setHandlePosition } from '../utils/setHandlePosition.js'\nimport { getBoundingClientRectWithoutTransform } from './getBoundingRectWithoutTransform.js'\nimport './index.scss'\nimport { setTargetLine } from './setTargetLine.js'\n\nconst DRAGGABLE_BLOCK_MENU_CLASSNAME = 'draggable-block-menu'\nconst DRAG_DATA_FORMAT = 'application/x-lexical-drag-block'\n\nlet prevIndex = Infinity\n\nfunction getCurrentIndex(keysLength: number): number {\n if (keysLength === 0) {\n return Infinity\n }\n if (prevIndex >= 0 && prevIndex < keysLength) {\n return prevIndex\n }\n\n return Math.floor(keysLength / 2)\n}\n\nfunction setDragImage(dataTransfer: DataTransfer, draggableBlockElem: HTMLElement) {\n const { transform } = draggableBlockElem.style\n\n // Remove dragImage borders\n dataTransfer.setDragImage(draggableBlockElem, 0, 0)\n\n setTimeout(() => {\n draggableBlockElem.style.transform = transform\n })\n}\n\nfunction hideTargetLine(\n targetLineElem: HTMLElement | null,\n lastTargetBlockElem: HTMLElement | null,\n) {\n if (targetLineElem) {\n targetLineElem.style.opacity = '0'\n }\n if (lastTargetBlockElem) {\n lastTargetBlockElem.style.opacity = ''\n // Delete marginBottom and marginTop values we set\n lastTargetBlockElem.style.marginBottom = ''\n lastTargetBlockElem.style.marginTop = ''\n //lastTargetBlock.style.border = 'none'\n }\n}\n\nfunction useDraggableBlockMenu(\n editor: LexicalEditor,\n anchorElem: HTMLElement,\n isEditable: boolean,\n): React.ReactElement {\n const scrollerElem = anchorElem.parentElement\n\n const menuRef = useRef<HTMLDivElement>(null)\n const targetLineRef = useRef<HTMLDivElement>(null)\n const debugHighlightRef = useRef<HTMLDivElement>(null)\n const isDraggingBlockRef = useRef<boolean>(false)\n const [draggableBlockElem, setDraggableBlockElem] = useState<HTMLElement | null>(null)\n const [lastTargetBlock, setLastTargetBlock] = useState<{\n boundingBox?: DOMRect\n elem: HTMLElement | null\n isBelow: boolean\n }>(null)\n\n const { editorConfig } = useEditorConfigContext()\n\n const blockHandleHorizontalOffset = editorConfig?.admin?.hideGutter ? -44 : -8\n\n useEffect(() => {\n /**\n * Handles positioning of the drag handle\n */\n function onDocumentMouseMove(event: MouseEvent) {\n const target = event.target\n if (!isHTMLElement(target)) {\n return\n }\n\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n scrollerElem,\n event.pageX,\n event.pageY,\n target,\n )\n if (distanceFromScrollerElem === -1) {\n setDraggableBlockElem(null)\n return\n }\n\n if (isOnHandleElement(target, DRAGGABLE_BLOCK_MENU_CLASSNAME)) {\n return\n }\n\n const topLevelNodeKeys = getTopLevelNodeKeys(editor)\n\n const {\n blockElem: _draggableBlockElem,\n foundAtIndex,\n isFoundNodeEmptyParagraph,\n } = getNodeCloseToPoint({\n anchorElem,\n cache_threshold: 0,\n editor,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n startIndex: getCurrentIndex(topLevelNodeKeys.length),\n useEdgeAsDefault: false,\n verbose: false,\n })\n\n prevIndex = foundAtIndex\n\n //if (DEBUG && _draggableBlockElem) {\n //targetBlockElem.style.border = '3px solid red'\n // highlightElemOriginalPosition(debugHighlightRef, _draggableBlockElem, anchorElem)\n //}\n\n if (!_draggableBlockElem && !isFoundNodeEmptyParagraph) {\n return\n }\n\n if (draggableBlockElem !== _draggableBlockElem) {\n setDraggableBlockElem(_draggableBlockElem)\n }\n }\n\n // Since the draggableBlockElem is outside the actual editor, we need to listen to the document\n // to be able to detect when the mouse is outside the editor and respect a buffer around\n // the scrollerElem to avoid the draggableBlockElem disappearing too early.\n document?.addEventListener('mousemove', onDocumentMouseMove)\n\n return () => {\n document?.removeEventListener('mousemove', onDocumentMouseMove)\n }\n }, [scrollerElem, anchorElem, editor, draggableBlockElem])\n\n useEffect(() => {\n if (menuRef.current) {\n setHandlePosition(\n draggableBlockElem,\n menuRef.current,\n anchorElem,\n blockHandleHorizontalOffset,\n )\n }\n }, [anchorElem, draggableBlockElem, blockHandleHorizontalOffset])\n\n useEffect(() => {\n function onDragover(event: DragEvent): boolean {\n if (!isDraggingBlockRef.current) {\n return false\n }\n const [isFileTransfer] = eventFiles(event)\n if (isFileTransfer) {\n return false\n }\n\n const { pageY, target } = event\n if (!isHTMLElement(target)) {\n return false\n }\n\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n scrollerElem,\n event.pageX,\n event.pageY,\n target,\n 100,\n 50,\n )\n\n const topLevelNodeKeys = getTopLevelNodeKeys(editor)\n\n const {\n blockElem: targetBlockElem,\n foundAtIndex,\n isFoundNodeEmptyParagraph,\n } = getNodeCloseToPoint({\n anchorElem,\n editor,\n fuzzy: true,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n startIndex: getCurrentIndex(topLevelNodeKeys.length),\n useEdgeAsDefault: true,\n verbose: true,\n })\n\n prevIndex = foundAtIndex\n\n const targetLineElem = targetLineRef.current\n // targetBlockElem === null shouldn't happen\n if (targetBlockElem === null || targetLineElem === null) {\n return false\n }\n\n if (draggableBlockElem !== targetBlockElem) {\n const { isBelow, willStayInSamePosition } = setTargetLine(\n editorConfig?.admin?.hideGutter ? '0px' : '3rem',\n blockHandleHorizontalOffset +\n (editorConfig?.admin?.hideGutter\n ? menuRef?.current?.getBoundingClientRect()?.width ?? 0\n : -menuRef?.current?.getBoundingClientRect()?.width ?? 0),\n targetLineElem,\n targetBlockElem,\n lastTargetBlock,\n pageY,\n anchorElem,\n event,\n debugHighlightRef,\n isFoundNodeEmptyParagraph,\n )\n\n // Prevent default event to be able to trigger onDrop events\n // Calling preventDefault() adds the green plus icon to the cursor,\n // indicating that the drop is allowed.\n event.preventDefault()\n\n if (!willStayInSamePosition) {\n setLastTargetBlock({\n boundingBox: targetBlockElem.getBoundingClientRect(),\n elem: targetBlockElem,\n isBelow,\n })\n }\n } else {\n hideTargetLine(targetLineElem, lastTargetBlock?.elem)\n setLastTargetBlock({\n boundingBox: targetBlockElem.getBoundingClientRect(),\n elem: targetBlockElem,\n isBelow: false,\n })\n }\n\n return true\n }\n\n function onDrop(event: DragEvent): boolean {\n if (!isDraggingBlockRef.current) {\n return false\n }\n const [isFileTransfer] = eventFiles(event)\n if (isFileTransfer) {\n return false\n }\n const { dataTransfer, pageY, target } = event\n const dragData = dataTransfer?.getData(DRAG_DATA_FORMAT) || ''\n\n editor.update(() => {\n const draggedNode = $getNodeByKey(dragData)\n if (!draggedNode) {\n return false\n }\n if (!isHTMLElement(target)) {\n return false\n }\n const distanceFromScrollerElem = calculateDistanceFromScrollerElem(\n scrollerElem,\n event.pageX,\n event.pageY,\n target,\n 100,\n 50,\n )\n\n const { blockElem: targetBlockElem, isFoundNodeEmptyParagraph } = getNodeCloseToPoint({\n anchorElem,\n editor,\n fuzzy: true,\n horizontalOffset: -distanceFromScrollerElem,\n point: new Point(event.x, event.y),\n useEdgeAsDefault: true,\n })\n\n if (!targetBlockElem) {\n return false\n }\n const targetNode = $getNearestNodeFromDOMNode(targetBlockElem)\n if (!targetNode) {\n return false\n }\n if (targetNode === draggedNode) {\n return true\n }\n\n const { height: targetBlockElemHeight, top: targetBlockElemTop } =\n getBoundingClientRectWithoutTransform(targetBlockElem)\n\n const mouseY = pageY\n const isBelow = mouseY >= targetBlockElemTop + targetBlockElemHeight / 2 + window.scrollY\n\n if (!isFoundNodeEmptyParagraph) {\n if (isBelow) {\n // below targetBlockElem\n targetNode.insertAfter(draggedNode)\n } else {\n // above targetBlockElem\n targetNode.insertBefore(draggedNode)\n }\n } else {\n //\n targetNode.insertBefore(draggedNode)\n targetNode.remove()\n }\n\n /*\n if (pageY >= targetBlockElemTop + targetBlockElemHeight / 2) {\n targetNode.insertAfter(draggedNode)\n } else {\n targetNode.insertBefore(draggedNode)\n }*/\n if (draggableBlockElem !== null) {\n setDraggableBlockElem(null)\n }\n\n // find all previous elements with lexical-block-highlighter class and remove them\n const allPrevHighlighters = document.querySelectorAll('.lexical-block-highlighter')\n allPrevHighlighters.forEach((highlighter) => {\n highlighter.remove()\n })\n\n const newInsertedElem = editor.getElementByKey(draggedNode.getKey())\n setTimeout(() => {\n // add new temp html element to newInsertedElem with the same height and width and the class block-selected\n // to highlight the new inserted element\n const newInsertedElemRect = newInsertedElem.getBoundingClientRect()\n\n const highlightElem = document.createElement('div')\n highlightElem.className = 'lexical-block-highlighter'\n\n // if html data-theme is dark, set the highlighter color to white\n if (document.documentElement.getAttribute('data-theme') === 'dark') {\n highlightElem.style.backgroundColor = 'white'\n } else {\n highlightElem.style.backgroundColor = 'black'\n }\n\n highlightElem.style.transition = 'opacity 0.1s ease-in-out'\n highlightElem.style.zIndex = '1'\n highlightElem.style.pointerEvents = 'none'\n highlightElem.style.boxSizing = 'border-box'\n highlightElem.style.borderRadius = '4px'\n highlightElem.style.position = 'absolute'\n document.body.appendChild(highlightElem)\n\n highlightElem.style.opacity = '0.1'\n\n highlightElem.style.height = `${newInsertedElemRect.height + 8}px`\n highlightElem.style.width = `${newInsertedElemRect.width + 8}px`\n highlightElem.style.top = `${newInsertedElemRect.top + window.scrollY - 4}px`\n highlightElem.style.left = `${newInsertedElemRect.left - 4}px`\n\n setTimeout(() => {\n highlightElem.style.opacity = '0'\n setTimeout(() => {\n highlightElem.remove()\n }, 1000)\n }, 3000)\n }, 120)\n })\n\n return true\n }\n\n // register onDragover event listeners:\n document.addEventListener('dragover', onDragover)\n // register onDrop event listeners:\n document.addEventListener('drop', onDrop)\n\n return () => {\n document.removeEventListener('dragover', onDragover)\n document.removeEventListener('drop', onDrop)\n }\n }, [\n scrollerElem,\n blockHandleHorizontalOffset,\n anchorElem,\n editor,\n lastTargetBlock,\n draggableBlockElem,\n editorConfig?.admin?.hideGutter,\n ])\n\n function onDragStart(event: ReactDragEvent<HTMLDivElement>): void {\n const dataTransfer = event.dataTransfer\n if (!dataTransfer || !draggableBlockElem) {\n return\n }\n setDragImage(dataTransfer, draggableBlockElem)\n let nodeKey = ''\n editor.update(() => {\n const node = $getNearestNodeFromDOMNode(draggableBlockElem)\n if (node) {\n nodeKey = node.getKey()\n }\n })\n isDraggingBlockRef.current = true\n dataTransfer.setData(DRAG_DATA_FORMAT, nodeKey)\n }\n\n function onDragEnd(): void {\n isDraggingBlockRef.current = false\n hideTargetLine(targetLineRef.current, lastTargetBlock?.elem)\n }\n\n return createPortal(\n <React.Fragment>\n <div\n className=\"icon draggable-block-menu\"\n draggable\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n ref={menuRef}\n >\n <div className={isEditable ? 'icon' : ''} />\n </div>\n <div className=\"draggable-block-target-line\" ref={targetLineRef} />\n <div className=\"debug-highlight\" ref={debugHighlightRef} />\n </React.Fragment>,\n anchorElem,\n )\n}\n\nexport function DraggableBlockPlugin({\n anchorElem = document.body,\n}: {\n anchorElem?: HTMLElement\n}): React.ReactElement {\n const [editor] = useLexicalComposerContext()\n return useDraggableBlockMenu(editor, anchorElem, editor._editable)\n}\n"],"names":["useLexicalComposerContext","eventFiles","$getNearestNodeFromDOMNode","$getNodeByKey","React","useEffect","useRef","useState","createPortal","useEditorConfigContext","isHTMLElement","Point","calculateDistanceFromScrollerElem","getNodeCloseToPoint","getTopLevelNodeKeys","isOnHandleElement","setHandlePosition","getBoundingClientRectWithoutTransform","setTargetLine","DRAGGABLE_BLOCK_MENU_CLASSNAME","DRAG_DATA_FORMAT","prevIndex","Infinity","getCurrentIndex","keysLength","Math","floor","setDragImage","dataTransfer","draggableBlockElem","transform","style","setTimeout","hideTargetLine","targetLineElem","lastTargetBlockElem","opacity","marginBottom","marginTop","useDraggableBlockMenu","editor","anchorElem","isEditable","scrollerElem","parentElement","menuRef","targetLineRef","debugHighlightRef","isDraggingBlockRef","setDraggableBlockElem","lastTargetBlock","setLastTargetBlock","editorConfig","blockHandleHorizontalOffset","admin","hideGutter","onDocumentMouseMove","event","target","distanceFromScrollerElem","pageX","pageY","topLevelNodeKeys","blockElem","_draggableBlockElem","foundAtIndex","isFoundNodeEmptyParagraph","cache_threshold","horizontalOffset","point","x","y","startIndex","length","useEdgeAsDefault","verbose","document","addEventListener","removeEventListener","current","onDragover","isFileTransfer","targetBlockElem","fuzzy","isBelow","willStayInSamePosition","getBoundingClientRect","width","preventDefault","boundingBox","elem","onDrop","dragData","getData","update","draggedNode","targetNode","height","targetBlockElemHeight","top","targetBlockElemTop","mouseY","window","scrollY","insertAfter","insertBefore","remove","allPrevHighlighters","querySelectorAll","forEach","highlighter","newInsertedElem","getElementByKey","getKey","newInsertedElemRect","highlightElem","createElement","className","documentElement","getAttribute","backgroundColor","transition","zIndex","pointerEvents","boxSizing","borderRadius","position","body","appendChild","left","onDragStart","nodeKey","node","setData","onDragEnd","Fragment","div","draggable","ref","DraggableBlockPlugin","_editable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1,3 +1,5 @@
1
+ @import '../../../../../scss/styles.scss';
2
+
1
3
  .draggable-block-menu {
2
4
  border-radius: 4px;
3
5
  padding: 0;
@@ -7,13 +9,14 @@
7
9
  left: 0;
8
10
  top: 0;
9
11
  will-change: transform;
12
+ background-color: var(--theme-bg);
10
13
 
11
14
  &:active {
12
15
  cursor: grabbing;
13
16
  }
14
17
 
15
18
  &:hover {
16
- background: rgba(255, 255, 255, 0.1);
19
+ background-color: var(--theme-elevation-100);
17
20
  .icon {
18
21
  opacity: 1;
19
22
  }
@@ -28,15 +31,21 @@
28
31
 
29
32
  html[data-theme='dark'] & {
30
33
  .icon {
31
- filter: invert(1);
34
+ background-image: url(../../../ui/icons/DraggableBlock/light.svg);
32
35
  }
33
36
  }
34
37
  }
35
38
 
39
+ .rich-text-lexical--show-gutter > .rich-text-lexical__wrap > .editor-container > .editor-scroller > .editor {
40
+ > .draggable-block-target-line {
41
+ left: 3rem;
42
+ }
43
+ }
44
+
36
45
  .draggable-block-target-line {
37
46
  pointer-events: none;
38
47
  background: var(--theme-elevation-200);
39
- border: 1px solid var(--theme-elevation-650);
48
+ //border: 1px solid var(--theme-elevation-650);
40
49
  border-radius: 4px;
41
50
  height: 50px;
42
51
  position: absolute;
@@ -1,3 +1,10 @@
1
1
  /// <reference types="react" resolution-mode="require"/>
2
- export declare function setTargetLine(SPACE: number, targetLineElem: HTMLElement, targetBlockElem: HTMLElement, lastTargetBlockElem: HTMLElement | null, mouseY: number, anchorElem: HTMLElement, event: DragEvent, debugHighlightRef: React.RefObject<HTMLDivElement>, isFoundNodeEmptyParagraph?: boolean): void;
2
+ export declare function setTargetLine(offsetWidth: string, offsetLeft: number, targetLineElem: HTMLElement, targetBlockElem: HTMLElement, lastTargetBlock: {
3
+ boundingBox?: DOMRect;
4
+ elem: HTMLElement | null;
5
+ isBelow: boolean;
6
+ }, mouseY: number, anchorElem: HTMLElement, event: DragEvent, debugHighlightRef: React.RefObject<HTMLDivElement | null>, isFoundNodeEmptyParagraph?: boolean): {
7
+ isBelow: boolean;
8
+ willStayInSamePosition: boolean;
9
+ };
3
10
  //# sourceMappingURL=setTargetLine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setTargetLine.d.ts","sourceRoot":"","sources":["../../../../../../src/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.ts"],"names":[],"mappings":";AAOA,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,WAAW,EAC3B,eAAe,EAAE,WAAW,EAC5B,mBAAmB,EAAE,WAAW,GAAG,IAAI,EACvC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,SAAS,EAChB,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAClD,yBAAyB,GAAE,OAAe,QAwE3C"}
1
+ {"version":3,"file":"setTargetLine.d.ts","sourceRoot":"","sources":["../../../../../../src/field/lexical/plugins/handles/DraggableBlockPlugin/setTargetLine.ts"],"names":[],"mappings":";AASA,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,WAAW,EAC3B,eAAe,EAAE,WAAW,EAC5B,eAAe,EAAE;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;CACjB,EACD,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,SAAS,EAChB,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EACzD,yBAAyB,GAAE,OAAe;;;EA4I3C"}
@@ -1,16 +1,54 @@
1
1
  import { getCollapsedMargins } from '../utils/getCollapsedMargins.js';
2
- import { getBoundingClientRectWithoutTransform } from './getBoundingRectWithoutTransform.js';
3
2
  import { highlightElemOriginalPosition } from './highlightElemOriginalPosition.js';
4
3
  const TARGET_LINE_HALF_HEIGHT = 25;
5
4
  const TEXT_BOX_HORIZONTAL_PADDING = -24;
6
5
  const DEBUG = false;
7
- export function setTargetLine(SPACE, targetLineElem, targetBlockElem, lastTargetBlockElem, mouseY, anchorElem, event, debugHighlightRef, isFoundNodeEmptyParagraph = false) {
8
- const { height: targetBlockElemHeight, top: targetBlockElemTop } = getBoundingClientRectWithoutTransform(targetBlockElem);
6
+ let animationTimer = 0;
7
+ export function setTargetLine(offsetWidth, offsetLeft, targetLineElem, targetBlockElem, lastTargetBlock, mouseY, anchorElem, event, debugHighlightRef, isFoundNodeEmptyParagraph = false) {
8
+ const { height: targetBlockElemHeight, top: targetBlockElemTop } = targetBlockElem.getBoundingClientRect() // used to be getBoundingClientRectWithoutTransform. Not sure what's better, but the normal getBoundingClientRect seems to work fine
9
+ ;
9
10
  const { top: anchorTop, width: anchorWidth } = anchorElem.getBoundingClientRect();
10
11
  const { marginBottom, marginTop } = getCollapsedMargins(targetBlockElem);
11
12
  let lineTop = targetBlockElemTop;
12
13
  const isBelow = mouseY >= targetBlockElemTop + targetBlockElemHeight / 2 + window.scrollY;
13
- if (!isFoundNodeEmptyParagraph) {
14
+ let willStayInSamePosition = false;
15
+ /**
16
+ * Do not run any transform or changes if the actual new line position would be the same (even if it's now inserted BEFORE rather than AFTER - position would still be the same)
17
+ * This prevents unnecessary flickering.
18
+ *
19
+ * We still need to let it run even if the position (IGNORING the transform) would not change, as the transform animation is not finished yet. This is what animationTimer does. Otherwise, the positioning will be inaccurate
20
+ */ if (lastTargetBlock?.elem) {
21
+ if (targetBlockElem !== lastTargetBlock?.elem) {
22
+ if (isBelow && lastTargetBlock?.elem && lastTargetBlock?.elem === targetBlockElem.nextElementSibling) {
23
+ animationTimer++;
24
+ if (animationTimer < 200) {
25
+ willStayInSamePosition = true;
26
+ }
27
+ } else if (!isBelow && lastTargetBlock?.elem && lastTargetBlock?.elem === targetBlockElem.previousElementSibling) {
28
+ animationTimer++;
29
+ if (animationTimer < 200) {
30
+ willStayInSamePosition = true;
31
+ }
32
+ }
33
+ } else {
34
+ animationTimer++;
35
+ const lastBoundingBoxPosition = lastTargetBlock?.boundingBox?.y;
36
+ const currentBoundingBoxPosition = targetBlockElem.getBoundingClientRect().y;
37
+ if (isBelow === lastTargetBlock?.isBelow && lastBoundingBoxPosition === currentBoundingBoxPosition || animationTimer < 200) {
38
+ willStayInSamePosition = false;
39
+ }
40
+ }
41
+ }
42
+ if (willStayInSamePosition) {
43
+ return {
44
+ isBelow,
45
+ willStayInSamePosition
46
+ };
47
+ }
48
+ /**
49
+ * Paragraphs need no isBelow/above handling,
50
+ */ if (!isFoundNodeEmptyParagraph) {
51
+ //if (!isFoundNodeEmptyParagraph) {
14
52
  if (isBelow) {
15
53
  // below targetBlockElem
16
54
  lineTop += targetBlockElemHeight + marginBottom / 2;
@@ -21,7 +59,6 @@ export function setTargetLine(SPACE, targetLineElem, targetBlockElem, lastTarget
21
59
  } else {
22
60
  lineTop += targetBlockElemHeight / 2;
23
61
  }
24
- const targetElemTranslate = 0;
25
62
  let targetElemTranslate2 = 0;
26
63
  if (!isFoundNodeEmptyParagraph) {
27
64
  if (isBelow) {
@@ -30,39 +67,50 @@ export function setTargetLine(SPACE, targetLineElem, targetBlockElem, lastTarget
30
67
  targetElemTranslate2 = TARGET_LINE_HALF_HEIGHT;
31
68
  }
32
69
  }
33
- let top = lineTop - anchorTop + targetElemTranslate2;
34
- if (!isBelow) {
35
- top -= TARGET_LINE_HALF_HEIGHT * 2;
36
- }
37
- const left = TEXT_BOX_HORIZONTAL_PADDING - SPACE;
38
- targetLineElem.style.transform = `translate(${left}px, ${top}px)`;
39
- targetLineElem.style.width = `${anchorWidth - (TEXT_BOX_HORIZONTAL_PADDING - SPACE) * 2}px`;
70
+ const top = lineTop - anchorTop + targetElemTranslate2;
71
+ const left = TEXT_BOX_HORIZONTAL_PADDING - offsetLeft;
72
+ targetLineElem.style.width = `calc(${anchorWidth}px - ${offsetWidth})`;
40
73
  targetLineElem.style.opacity = '.4';
41
74
  /**
42
- * Move around element below or above the line (= the target / targetBlockElem)
75
+ * Move around element below or above the line (= the target / targetBlockElem). Creates "space" for the targetLineElem
76
+ *
77
+ * Not needed for empty paragraphs, as an empty paragraph is enough space for the targetLineElem anyways.
43
78
  */ //targetBlockElem.style.opacity = '0.4'
79
+ const buffer = 12 // creates more spacing/padding so target line is not directly next to the targetBlockElem
80
+ ;
44
81
  if (!isFoundNodeEmptyParagraph) {
45
- // move lastTargetBlockElem down 50px to make space for targetLineElem (which is 50px height)
46
- targetBlockElem.style.transform = `translate(0, ${targetElemTranslate}px)`;
47
82
  if (isBelow) {
48
- // add to existing marginBottom plus the height of targetLineElem
49
- targetBlockElem.style.marginBottom = TARGET_LINE_HALF_HEIGHT * 2 + 'px';
83
+ targetBlockElem.style.marginBottom = TARGET_LINE_HALF_HEIGHT * 2 + buffer + 'px';
84
+ targetLineElem.style.transform = `translate(${left}px, calc(${top}px - ${'0px'}))`;
50
85
  } else {
51
- targetBlockElem.style.marginTop = TARGET_LINE_HALF_HEIGHT * 2 + 'px';
86
+ targetBlockElem.style.marginTop = TARGET_LINE_HALF_HEIGHT * 2 + buffer + 'px';
87
+ targetLineElem.style.transform = `translate(${left}px, calc(${top - TARGET_LINE_HALF_HEIGHT * 2}px - ${'0px'}))`;
52
88
  }
89
+ } else {
90
+ targetLineElem.style.transform = `translate(${left}px, ${top - TARGET_LINE_HALF_HEIGHT}px)`;
53
91
  }
54
92
  if (DEBUG) {
55
93
  //targetBlockElem.style.border = '3px solid red'
56
94
  highlightElemOriginalPosition(debugHighlightRef, targetBlockElem, anchorElem);
57
95
  }
58
- if (lastTargetBlockElem && lastTargetBlockElem !== targetBlockElem) {
59
- lastTargetBlockElem.style.opacity = '';
60
- lastTargetBlockElem.style.transform = '';
61
- // Delete marginBottom and marginTop values we set
62
- lastTargetBlockElem.style.marginBottom = '';
63
- lastTargetBlockElem.style.marginTop = '';
64
- //lastTargetBlockElem.style.border = 'none'
96
+ /**
97
+ * Properly reset previous targetBlockElem styles
98
+ */ lastTargetBlock.elem.style.opacity = '';
99
+ if (lastTargetBlock?.elem === targetBlockElem) {
100
+ if (isBelow) {
101
+ lastTargetBlock.elem.style.marginTop = '';
102
+ } else {
103
+ lastTargetBlock.elem.style.marginBottom = '';
104
+ }
105
+ } else {
106
+ lastTargetBlock.elem.style.marginBottom = '';
107
+ lastTargetBlock.elem.style.marginTop = '';
65
108
  }
109
+ animationTimer = 0;
110
+ return {
111
+ isBelow,
112
+ willStayInSamePosition
113
+ };
66
114
  }
67
115
 
68
116
  //# sourceMappingURL=setTargetLine.js.map