payload-richtext-tiptap 0.0.159 → 0.0.161

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 (89) hide show
  1. package/dist/src/fields/TiptapEditor/extensions/Iframe/IframeEmbed.d.ts +2 -7
  2. package/dist/src/fields/TiptapEditor/extensions/Iframe/IframeEmbed.d.ts.map +1 -1
  3. package/dist/src/fields/TiptapEditor/extensions/Iframe/IframeEmbed.js +20 -7
  4. package/dist/src/fields/TiptapEditor/extensions/Iframe/IframeEmbed.js.map +1 -1
  5. package/dist/src/fields/TiptapEditor/extensions/Iframe/iframe.d.ts +2 -2
  6. package/dist/src/fields/TiptapEditor/extensions/Iframe/iframe.d.ts.map +1 -1
  7. package/dist/src/fields/TiptapEditor/extensions/Iframe/iframe.js +42 -30
  8. package/dist/src/fields/TiptapEditor/extensions/Iframe/iframe.js.map +1 -1
  9. package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.d.ts.map +1 -1
  10. package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.js +27 -4
  11. package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.js.map +1 -1
  12. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/PasteHandler.d.ts +4 -0
  13. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/PasteHandler.d.ts.map +1 -0
  14. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/PasteHandler.js +242 -0
  15. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/PasteHandler.js.map +1 -0
  16. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/index.d.ts +2 -0
  17. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/index.d.ts.map +1 -0
  18. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/index.js +3 -0
  19. package/dist/src/fields/TiptapEditor/extensions/PasteHandler/index.js.map +1 -0
  20. package/dist/src/fields/TiptapEditor/extensions/SlashCommand/groups.d.ts +1 -1
  21. package/dist/src/fields/TiptapEditor/extensions/SlashCommand/groups.d.ts.map +1 -1
  22. package/dist/src/fields/TiptapEditor/extensions/SlashCommand/groups.js +108 -84
  23. package/dist/src/fields/TiptapEditor/extensions/SlashCommand/groups.js.map +1 -1
  24. package/dist/src/fields/TiptapEditor/extensions/Table/Table.d.ts.map +1 -1
  25. package/dist/src/fields/TiptapEditor/extensions/Table/Table.js +2 -1
  26. package/dist/src/fields/TiptapEditor/extensions/Table/Table.js.map +1 -1
  27. package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts +3 -3
  28. package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts.map +1 -1
  29. package/dist/src/fields/TiptapEditor/extensions/extension-kit.js +29 -22
  30. package/dist/src/fields/TiptapEditor/extensions/extension-kit.js.map +1 -1
  31. package/dist/src/fields/TiptapEditor/extensions/index.d.ts +50 -49
  32. package/dist/src/fields/TiptapEditor/extensions/index.d.ts.map +1 -1
  33. package/dist/src/fields/TiptapEditor/extensions/index.js +50 -49
  34. package/dist/src/fields/TiptapEditor/extensions/index.js.map +1 -1
  35. package/dist/src/fields/TiptapEditor/extensions/serverside/IFrameServerside.d.ts +2 -2
  36. package/dist/src/fields/TiptapEditor/extensions/serverside/IFrameServerside.d.ts.map +1 -1
  37. package/dist/src/fields/TiptapEditor/extensions/serverside/IFrameServerside.js +26 -8
  38. package/dist/src/fields/TiptapEditor/extensions/serverside/IFrameServerside.js.map +1 -1
  39. package/dist/src/fields/TiptapEditor/extensions/serverside/TableServerside.d.ts +10 -0
  40. package/dist/src/fields/TiptapEditor/extensions/serverside/TableServerside.d.ts.map +1 -0
  41. package/dist/src/fields/TiptapEditor/extensions/serverside/TableServerside.js +90 -0
  42. package/dist/src/fields/TiptapEditor/extensions/serverside/TableServerside.js.map +1 -0
  43. package/dist/src/fields/TiptapEditor/extensions/serverside/index.d.ts +15 -13
  44. package/dist/src/fields/TiptapEditor/extensions/serverside/index.d.ts.map +1 -1
  45. package/dist/src/fields/TiptapEditor/extensions/serverside/index.js +15 -13
  46. package/dist/src/fields/TiptapEditor/extensions/serverside/index.js.map +1 -1
  47. package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.d.ts.map +1 -1
  48. package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.js +9 -0
  49. package/dist/src/fields/TiptapEditor/features/BlockEditor/BlockEditor.js.map +1 -1
  50. package/dist/src/fields/TiptapEditor/features/panels/IframeLinkEditorPanel/IframeLinkEditorPanel.d.ts +2 -2
  51. package/dist/src/fields/TiptapEditor/features/panels/IframeLinkEditorPanel/IframeLinkEditorPanel.d.ts.map +1 -1
  52. package/dist/src/fields/TiptapEditor/features/panels/IframeLinkEditorPanel/IframeLinkEditorPanel.js +20 -18
  53. package/dist/src/fields/TiptapEditor/features/panels/IframeLinkEditorPanel/IframeLinkEditorPanel.js.map +1 -1
  54. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.d.ts +4 -0
  55. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.d.ts.map +1 -0
  56. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.js +32 -0
  57. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.js.map +1 -0
  58. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.d.ts +4 -0
  59. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.d.ts.map +1 -0
  60. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.js +70 -0
  61. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.js.map +1 -0
  62. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.d.ts +10 -0
  63. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.d.ts.map +1 -0
  64. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.js +249 -0
  65. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.js.map +1 -0
  66. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.d.ts +15 -0
  67. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.d.ts.map +1 -0
  68. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.js +291 -0
  69. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.js.map +1 -0
  70. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.d.ts +7 -0
  71. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.d.ts.map +1 -0
  72. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.js +7 -0
  73. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.js.map +1 -0
  74. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.d.ts +28 -0
  75. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.d.ts.map +1 -0
  76. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.js +3 -0
  77. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.js.map +1 -0
  78. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.d.ts +6 -0
  79. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.d.ts.map +1 -0
  80. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.js +222 -0
  81. package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.js.map +1 -0
  82. package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.d.ts +2 -0
  83. package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.d.ts.map +1 -0
  84. package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.js +17 -0
  85. package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.js.map +1 -0
  86. package/dist/src/mobile.css +1 -1
  87. package/dist/src/styles.css +1 -1
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +1 -1
@@ -0,0 +1,249 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { Surface } from '../Surface.js';
4
+ import { DropdownButton } from '../Dropdown/Dropdown.js';
5
+ import { Icon } from '../Icon.js';
6
+ export const SlashMenuList = /*#__PURE__*/ React.forwardRef(({ items, command, showGroups = true }, ref)=>{
7
+ const scrollContainer = useRef(null);
8
+ const activeItem = useRef(null);
9
+ const [selectedIndex, setSelectedIndex] = useState(0);
10
+ const [hoveredIndex, setHoveredIndex] = useState(null);
11
+ const isKeyboardNavigation = useRef(false);
12
+ // Group items by their group property
13
+ const groupedItems = React.useMemo(()=>{
14
+ if (!showGroups) {
15
+ return {
16
+ All: items
17
+ };
18
+ }
19
+ return items.reduce((groups, item)=>{
20
+ const group = item.group || 'Other';
21
+ if (!groups[group]) {
22
+ groups[group] = [];
23
+ }
24
+ groups[group].push(item);
25
+ return groups;
26
+ }, {});
27
+ }, [
28
+ items,
29
+ showGroups
30
+ ]);
31
+ // Flatten grouped items for navigation
32
+ const flatItems = React.useMemo(()=>{
33
+ return Object.values(groupedItems).flat();
34
+ }, [
35
+ groupedItems
36
+ ]);
37
+ // Reset selection when items change
38
+ useEffect(()=>{
39
+ setSelectedIndex(0);
40
+ setHoveredIndex(null);
41
+ }, [
42
+ items
43
+ ]);
44
+ const selectItem = useCallback((index)=>{
45
+ const item = flatItems[index];
46
+ if (item) {
47
+ command(item);
48
+ }
49
+ }, [
50
+ flatItems,
51
+ command
52
+ ]);
53
+ // Expose the handleKeyDown method for external use
54
+ React.useImperativeHandle(ref, ()=>({
55
+ onKeyDown: ({ event })=>{
56
+ handleKeyDown(event);
57
+ return true;
58
+ }
59
+ }));
60
+ // Only scroll on keyboard navigation, not on hover
61
+ const scrollToActiveItem = useCallback(()=>{
62
+ if (activeItem.current && scrollContainer.current) {
63
+ const container = scrollContainer.current;
64
+ const item = activeItem.current;
65
+ const containerRect = container.getBoundingClientRect();
66
+ const itemRect = item.getBoundingClientRect();
67
+ // Only scroll if item is not fully visible
68
+ if (itemRect.top < containerRect.top) {
69
+ container.scrollTop = item.offsetTop - container.offsetTop - 10;
70
+ } else if (itemRect.bottom > containerRect.bottom) {
71
+ container.scrollTop = item.offsetTop - container.offsetTop - container.clientHeight + item.offsetHeight + 10;
72
+ }
73
+ }
74
+ }, []);
75
+ useEffect(()=>{
76
+ // Only scroll on keyboard navigation, not on hover
77
+ if (isKeyboardNavigation.current) {
78
+ scrollToActiveItem();
79
+ isKeyboardNavigation.current = false // Reset flag
80
+ ;
81
+ }
82
+ }, [
83
+ selectedIndex,
84
+ scrollToActiveItem
85
+ ]);
86
+ // Note: Focus is only set when arrow keys are pressed, not on mount
87
+ const createItemClickHandler = useCallback((index)=>{
88
+ return ()=>{
89
+ selectItem(index);
90
+ };
91
+ }, [
92
+ selectItem
93
+ ]);
94
+ const createItemHoverHandler = useCallback((index)=>{
95
+ return ()=>{
96
+ setHoveredIndex(index);
97
+ setSelectedIndex(index) // Update selected index on hover
98
+ ;
99
+ };
100
+ }, []);
101
+ const createItemLeaveHandler = useCallback(()=>{
102
+ return ()=>{
103
+ setHoveredIndex(null);
104
+ };
105
+ }, []);
106
+ // Handle keyboard events directly
107
+ const handleKeyDown = useCallback((event)=>{
108
+ if (event.key === 'ArrowDown') {
109
+ event.preventDefault();
110
+ event.stopPropagation();
111
+ if (!flatItems.length) {
112
+ return;
113
+ }
114
+ isKeyboardNavigation.current = true // Mark as keyboard navigation
115
+ ;
116
+ const newIndex = (selectedIndex + 1) % flatItems.length;
117
+ setSelectedIndex(newIndex);
118
+ setHoveredIndex(null);
119
+ return;
120
+ }
121
+ if (event.key === 'ArrowUp') {
122
+ event.preventDefault();
123
+ event.stopPropagation();
124
+ if (!flatItems.length) {
125
+ return;
126
+ }
127
+ // If at the top and pressing up again, return focus to editor
128
+ if (selectedIndex === 0) {
129
+ // Return focus to editor
130
+ const editorElement = document.querySelector('.ProseMirror');
131
+ if (editorElement) {
132
+ ;
133
+ editorElement.focus();
134
+ }
135
+ return;
136
+ }
137
+ isKeyboardNavigation.current = true // Mark as keyboard navigation
138
+ ;
139
+ const newIndex = selectedIndex - 1;
140
+ setSelectedIndex(newIndex);
141
+ setHoveredIndex(null);
142
+ return;
143
+ }
144
+ if (event.key === 'Enter') {
145
+ event.preventDefault();
146
+ event.stopPropagation();
147
+ if (!flatItems.length || selectedIndex === -1) {
148
+ return;
149
+ }
150
+ console.log('Enter key pressed, selecting item:', selectedIndex);
151
+ selectItem(selectedIndex);
152
+ // Return focus to editor after selection
153
+ setTimeout(()=>{
154
+ const editorElement = document.querySelector('.ProseMirror');
155
+ if (editorElement) {
156
+ ;
157
+ editorElement.focus();
158
+ }
159
+ }, 0);
160
+ return;
161
+ }
162
+ if (event.key === 'Escape') {
163
+ event.preventDefault();
164
+ event.stopPropagation();
165
+ // Let the parent handle closing - it will return focus to editor
166
+ return;
167
+ }
168
+ // For any other key, return focus to editor
169
+ event.preventDefault();
170
+ event.stopPropagation();
171
+ const editorElement = document.querySelector('.ProseMirror');
172
+ if (editorElement) {
173
+ ;
174
+ editorElement.focus();
175
+ }
176
+ }, [
177
+ selectedIndex,
178
+ flatItems,
179
+ selectItem
180
+ ]);
181
+ if (!items.length) {
182
+ return null;
183
+ }
184
+ return /*#__PURE__*/ _jsx(Surface, {
185
+ ref: scrollContainer,
186
+ className: "bg-dark-panel text-dark-text max-h-[min(80vh,24rem)] overflow-auto flex-wrap mb-8 p-3 focus:outline-none focus:ring-0 rounded-lg shadow-lg border border-dark-border animate-slide-up-fade",
187
+ onKeyDown: handleKeyDown,
188
+ onMouseEnter: (e)=>{
189
+ e.stopPropagation();
190
+ },
191
+ onMouseLeave: (e)=>{
192
+ e.stopPropagation();
193
+ },
194
+ role: "menu",
195
+ "aria-label": "Slash command menu",
196
+ "aria-activedescendant": selectedIndex >= 0 ? `menu-item-${selectedIndex}` : undefined,
197
+ tabIndex: 0,
198
+ children: /*#__PURE__*/ _jsx("div", {
199
+ className: "space-y-1",
200
+ children: Object.entries(groupedItems).map(([groupName, groupItems])=>/*#__PURE__*/ _jsxs(React.Fragment, {
201
+ children: [
202
+ showGroups && /*#__PURE__*/ _jsx("div", {
203
+ className: "text-dark-text-muted text-xs px-2 py-1 font-medium tracking-wide select-none uppercase",
204
+ children: groupName
205
+ }),
206
+ groupItems.map((item, itemIndex)=>{
207
+ const flatIndex = flatItems.indexOf(item);
208
+ const isActive = selectedIndex === flatIndex;
209
+ const isHovered = hoveredIndex === flatIndex;
210
+ return /*#__PURE__*/ _jsxs(DropdownButton, {
211
+ ref: isActive ? activeItem : null,
212
+ isActive: isActive || isHovered,
213
+ onClick: createItemClickHandler(flatIndex),
214
+ onMouseEnter: createItemHoverHandler(flatIndex),
215
+ onMouseLeave: createItemLeaveHandler(),
216
+ role: "menuitem",
217
+ id: `menu-item-${flatIndex}`,
218
+ "aria-label": `${item.title}: ${item.subtext}`,
219
+ "aria-selected": isActive,
220
+ tabIndex: -1,
221
+ children: [
222
+ /*#__PURE__*/ _jsx(Icon, {
223
+ icon: item.badge,
224
+ className: "mr-1"
225
+ }),
226
+ /*#__PURE__*/ _jsxs("div", {
227
+ className: "flex flex-col items-start",
228
+ children: [
229
+ /*#__PURE__*/ _jsx("div", {
230
+ className: "text-sm font-medium",
231
+ children: item.title
232
+ }),
233
+ /*#__PURE__*/ _jsx("div", {
234
+ className: "text-xs text-neutral-500",
235
+ children: item.subtext
236
+ })
237
+ ]
238
+ })
239
+ ]
240
+ }, `${item.title}-${itemIndex}`);
241
+ })
242
+ ]
243
+ }, groupName))
244
+ })
245
+ });
246
+ });
247
+ SlashMenuList.displayName = 'SlashMenuList';
248
+
249
+ //# sourceMappingURL=SlashMenuList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react'\r\nimport { SuggestionItem } from './types.js'\r\nimport { Surface } from '../Surface.js'\r\nimport { DropdownButton } from '../Dropdown/Dropdown.js'\r\nimport { Icon } from '../Icon.js'\r\n\r\ninterface SlashMenuListProps {\r\n items: SuggestionItem[]\r\n command: (item: SuggestionItem) => void\r\n showGroups?: boolean\r\n}\r\n\r\nexport const SlashMenuList = React.forwardRef<any, SlashMenuListProps>(\r\n ({ items, command, showGroups = true }, ref) => {\r\n const scrollContainer = useRef<HTMLDivElement>(null)\r\n const activeItem = useRef<HTMLButtonElement>(null)\r\n const [selectedIndex, setSelectedIndex] = useState(0)\r\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)\r\n const isKeyboardNavigation = useRef(false)\r\n\r\n // Group items by their group property\r\n const groupedItems = React.useMemo(() => {\r\n if (!showGroups) {\r\n return { All: items }\r\n }\r\n\r\n return items.reduce(\r\n (groups, item) => {\r\n const group = item.group || 'Other'\r\n if (!groups[group]) {\r\n groups[group] = []\r\n }\r\n groups[group].push(item)\r\n return groups\r\n },\r\n {} as Record<string, SuggestionItem[]>,\r\n )\r\n }, [items, showGroups])\r\n\r\n // Flatten grouped items for navigation\r\n const flatItems = React.useMemo(() => {\r\n return Object.values(groupedItems).flat()\r\n }, [groupedItems])\r\n\r\n // Reset selection when items change\r\n useEffect(() => {\r\n setSelectedIndex(0)\r\n setHoveredIndex(null)\r\n }, [items])\r\n\r\n const selectItem = useCallback(\r\n (index: number) => {\r\n const item = flatItems[index]\r\n if (item) {\r\n command(item)\r\n }\r\n },\r\n [flatItems, command],\r\n )\r\n\r\n // Expose the handleKeyDown method for external use\r\n React.useImperativeHandle(ref, () => ({\r\n onKeyDown: ({ event }: { event: React.KeyboardEvent }) => {\r\n handleKeyDown(event)\r\n return true\r\n },\r\n }))\r\n\r\n // Only scroll on keyboard navigation, not on hover\r\n const scrollToActiveItem = useCallback(() => {\r\n if (activeItem.current && scrollContainer.current) {\r\n const container = scrollContainer.current\r\n const item = activeItem.current\r\n const containerRect = container.getBoundingClientRect()\r\n const itemRect = item.getBoundingClientRect()\r\n\r\n // Only scroll if item is not fully visible\r\n if (itemRect.top < containerRect.top) {\r\n container.scrollTop = item.offsetTop - container.offsetTop - 10\r\n } else if (itemRect.bottom > containerRect.bottom) {\r\n container.scrollTop =\r\n item.offsetTop - container.offsetTop - container.clientHeight + item.offsetHeight + 10\r\n }\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n // Only scroll on keyboard navigation, not on hover\r\n if (isKeyboardNavigation.current) {\r\n scrollToActiveItem()\r\n isKeyboardNavigation.current = false // Reset flag\r\n }\r\n }, [selectedIndex, scrollToActiveItem])\r\n\r\n // Note: Focus is only set when arrow keys are pressed, not on mount\r\n\r\n const createItemClickHandler = useCallback(\r\n (index: number) => {\r\n return () => {\r\n selectItem(index)\r\n }\r\n },\r\n [selectItem],\r\n )\r\n\r\n const createItemHoverHandler = useCallback((index: number) => {\r\n return () => {\r\n setHoveredIndex(index)\r\n setSelectedIndex(index) // Update selected index on hover\r\n }\r\n }, [])\r\n\r\n const createItemLeaveHandler = useCallback(() => {\r\n return () => {\r\n setHoveredIndex(null)\r\n }\r\n }, [])\r\n\r\n // Handle keyboard events directly\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent) => {\r\n if (event.key === 'ArrowDown') {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n if (!flatItems.length) {\r\n return\r\n }\r\n isKeyboardNavigation.current = true // Mark as keyboard navigation\r\n const newIndex = (selectedIndex + 1) % flatItems.length\r\n setSelectedIndex(newIndex)\r\n setHoveredIndex(null)\r\n return\r\n }\r\n\r\n if (event.key === 'ArrowUp') {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n if (!flatItems.length) {\r\n return\r\n }\r\n\r\n // If at the top and pressing up again, return focus to editor\r\n if (selectedIndex === 0) {\r\n // Return focus to editor\r\n const editorElement = document.querySelector('.ProseMirror')\r\n if (editorElement) {\r\n ;(editorElement as HTMLElement).focus()\r\n }\r\n return\r\n }\r\n\r\n isKeyboardNavigation.current = true // Mark as keyboard navigation\r\n const newIndex = selectedIndex - 1\r\n setSelectedIndex(newIndex)\r\n setHoveredIndex(null)\r\n return\r\n }\r\n\r\n if (event.key === 'Enter') {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n if (!flatItems.length || selectedIndex === -1) {\r\n return\r\n }\r\n console.log('Enter key pressed, selecting item:', selectedIndex)\r\n selectItem(selectedIndex)\r\n\r\n // Return focus to editor after selection\r\n setTimeout(() => {\r\n const editorElement = document.querySelector('.ProseMirror')\r\n if (editorElement) {\r\n ;(editorElement as HTMLElement).focus()\r\n }\r\n }, 0)\r\n return\r\n }\r\n\r\n if (event.key === 'Escape') {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n // Let the parent handle closing - it will return focus to editor\r\n return\r\n }\r\n\r\n // For any other key, return focus to editor\r\n event.preventDefault()\r\n event.stopPropagation()\r\n const editorElement = document.querySelector('.ProseMirror')\r\n if (editorElement) {\r\n ;(editorElement as HTMLElement).focus()\r\n }\r\n },\r\n [selectedIndex, flatItems, selectItem],\r\n )\r\n\r\n if (!items.length) {\r\n return null\r\n }\r\n\r\n return (\r\n <Surface\r\n ref={scrollContainer}\r\n className=\"bg-dark-panel text-dark-text max-h-[min(80vh,24rem)] overflow-auto flex-wrap mb-8 p-3 focus:outline-none focus:ring-0 rounded-lg shadow-lg border border-dark-border animate-slide-up-fade\"\r\n onKeyDown={handleKeyDown}\r\n onMouseEnter={(e) => {\r\n e.stopPropagation()\r\n }}\r\n onMouseLeave={(e) => {\r\n e.stopPropagation()\r\n }}\r\n role=\"menu\"\r\n aria-label=\"Slash command menu\"\r\n aria-activedescendant={selectedIndex >= 0 ? `menu-item-${selectedIndex}` : undefined}\r\n tabIndex={0}\r\n >\r\n <div className=\"space-y-1\">\r\n {Object.entries(groupedItems).map(([groupName, groupItems]) => (\r\n <React.Fragment key={groupName}>\r\n {showGroups && (\r\n <div className=\"text-dark-text-muted text-xs px-2 py-1 font-medium tracking-wide select-none uppercase\">\r\n {groupName}\r\n </div>\r\n )}\r\n {groupItems.map((item, itemIndex) => {\r\n const flatIndex = flatItems.indexOf(item)\r\n const isActive = selectedIndex === flatIndex\r\n const isHovered = hoveredIndex === flatIndex\r\n\r\n return (\r\n <DropdownButton\r\n key={`${item.title}-${itemIndex}`}\r\n ref={isActive ? activeItem : null}\r\n isActive={isActive || isHovered}\r\n onClick={createItemClickHandler(flatIndex)}\r\n onMouseEnter={createItemHoverHandler(flatIndex)}\r\n onMouseLeave={createItemLeaveHandler()}\r\n role=\"menuitem\"\r\n id={`menu-item-${flatIndex}`}\r\n aria-label={`${item.title}: ${item.subtext}`}\r\n aria-selected={isActive}\r\n tabIndex={-1}\r\n >\r\n <Icon icon={item.badge} className=\"mr-1\" />\r\n <div className=\"flex flex-col items-start\">\r\n <div className=\"text-sm font-medium\">{item.title}</div>\r\n <div className=\"text-xs text-neutral-500\">{item.subtext}</div>\r\n </div>\r\n </DropdownButton>\r\n )\r\n })}\r\n </React.Fragment>\r\n ))}\r\n </div>\r\n </Surface>\r\n )\r\n },\r\n)\r\n\r\nSlashMenuList.displayName = 'SlashMenuList'\r\n"],"names":["React","useCallback","useEffect","useRef","useState","Surface","DropdownButton","Icon","SlashMenuList","forwardRef","items","command","showGroups","ref","scrollContainer","activeItem","selectedIndex","setSelectedIndex","hoveredIndex","setHoveredIndex","isKeyboardNavigation","groupedItems","useMemo","All","reduce","groups","item","group","push","flatItems","Object","values","flat","selectItem","index","useImperativeHandle","onKeyDown","event","handleKeyDown","scrollToActiveItem","current","container","containerRect","getBoundingClientRect","itemRect","top","scrollTop","offsetTop","bottom","clientHeight","offsetHeight","createItemClickHandler","createItemHoverHandler","createItemLeaveHandler","key","preventDefault","stopPropagation","length","newIndex","editorElement","document","querySelector","focus","console","log","setTimeout","className","onMouseEnter","e","onMouseLeave","role","aria-label","aria-activedescendant","undefined","tabIndex","div","entries","map","groupName","groupItems","Fragment","itemIndex","flatIndex","indexOf","isActive","isHovered","onClick","id","title","subtext","aria-selected","icon","badge","displayName"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+ import { SuggestionItem } from './types.js';
4
+ interface SuggestionMenuProps {
5
+ editor: Editor;
6
+ char: string;
7
+ items: (props: {
8
+ query: string;
9
+ editor: Editor;
10
+ }) => SuggestionItem[];
11
+ children: (props: any) => React.ReactElement;
12
+ }
13
+ export declare const SuggestionMenu: ({ editor, char, items, children }: SuggestionMenuProps) => any;
14
+ export {};
15
+ //# sourceMappingURL=SuggestionMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SuggestionMenu.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAA;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAIrC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG3C,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,cAAc,EAAE,CAAA;IACrE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,KAAK,CAAC,YAAY,CAAA;CAC7C;AAoED,eAAO,MAAM,cAAc,sCAAuC,mBAAmB,QAgRpF,CAAA"}
@@ -0,0 +1,291 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { ReactRenderer } from '@tiptap/react';
3
+ import Suggestion from '@tiptap/suggestion';
4
+ import { PluginKey } from '@tiptap/pm/state';
5
+ import { computePosition, offset, autoUpdate } from '@floating-ui/dom';
6
+ let popupElement = null;
7
+ let cleanupAutoUpdate = null;
8
+ let isPopupVisible = false;
9
+ // Helper functions to manage Floating UI popup
10
+ const initPopup = ()=>{
11
+ if (!popupElement && typeof document !== 'undefined') {
12
+ popupElement = document.createElement('div');
13
+ popupElement.style.position = 'fixed';
14
+ popupElement.style.zIndex = '10000';
15
+ popupElement.style.maxWidth = '16rem';
16
+ popupElement.style.visibility = 'hidden';
17
+ popupElement.style.opacity = '0';
18
+ popupElement.style.transition = 'opacity 200ms';
19
+ popupElement.className = 'slash-command-menu';
20
+ document.body.appendChild(popupElement);
21
+ }
22
+ return popupElement;
23
+ };
24
+ const showPopup = ()=>{
25
+ if (popupElement && !isPopupVisible) {
26
+ isPopupVisible = true;
27
+ popupElement.style.display = 'block';
28
+ popupElement.style.visibility = 'visible';
29
+ popupElement.style.opacity = '1';
30
+ }
31
+ };
32
+ const hidePopup = ()=>{
33
+ if (popupElement) {
34
+ isPopupVisible = false;
35
+ popupElement.style.visibility = 'hidden';
36
+ popupElement.style.opacity = '0';
37
+ // Use setTimeout to wait for transition before hiding completely
38
+ setTimeout(()=>{
39
+ if (popupElement && !isPopupVisible) {
40
+ popupElement.style.display = 'none';
41
+ }
42
+ }, 200);
43
+ }
44
+ };
45
+ const updatePopupPosition = async (getReferenceRect)=>{
46
+ if (!popupElement || !isPopupVisible) return;
47
+ try {
48
+ const rect = getReferenceRect();
49
+ const virtualElement = {
50
+ getBoundingClientRect: ()=>rect
51
+ };
52
+ const { x, y } = await computePosition(virtualElement, popupElement, {
53
+ placement: 'bottom-start',
54
+ strategy: 'fixed',
55
+ middleware: [
56
+ offset({
57
+ mainAxis: 8,
58
+ crossAxis: 16
59
+ })
60
+ ]
61
+ });
62
+ popupElement.style.left = `${x}px`;
63
+ popupElement.style.top = `${y}px`;
64
+ } catch (error) {
65
+ console.error('Error updating popup position:', error);
66
+ }
67
+ };
68
+ export const SuggestionMenu = ({ editor, char, items, children })=>{
69
+ const [suggestionProps, setSuggestionProps] = useState(null);
70
+ const suggestionRef = useRef(null);
71
+ useEffect(()=>{
72
+ if (!editor) return;
73
+ // Clean up existing suggestion if it exists
74
+ if (suggestionRef.current) {
75
+ editor.unregisterPlugin(suggestionRef.current);
76
+ }
77
+ const suggestion = Suggestion({
78
+ editor,
79
+ char,
80
+ allowSpaces: true,
81
+ startOfLine: true,
82
+ pluginKey: new PluginKey('slash-suggestion'),
83
+ allow: ({ state, range })=>{
84
+ const $from = state.doc.resolve(range.from);
85
+ const isRootDepth = $from.depth === 1;
86
+ const isParagraph = $from.parent.type.name === 'paragraph';
87
+ const isStartOfNode = $from.parent.textContent?.charAt(0) === char;
88
+ const isInColumn = editor.isActive('column');
89
+ const afterContent = $from.parent.textContent?.substring($from.parent.textContent?.indexOf(char));
90
+ const isValidAfterContent = !afterContent?.endsWith(' ');
91
+ // Check if drag handle is locked (ContentItemMenu is open)
92
+ const isDragHandleLocked = editor.storage.dragHandle?.lockDragHandle;
93
+ const shouldAllow = (isRootDepth && isParagraph && isStartOfNode || isInColumn && isParagraph && isStartOfNode) && isValidAfterContent && !isDragHandleLocked;
94
+ return shouldAllow;
95
+ },
96
+ command: ({ editor, props })=>{
97
+ const { view, state } = editor;
98
+ const { $head, $from } = view.state.selection;
99
+ const end = $from.pos;
100
+ const from = $head?.nodeBefore ? end - ($head.nodeBefore.text?.substring($head.nodeBefore.text?.indexOf(char)).length ?? 0) : $from.start();
101
+ const tr = state.tr.deleteRange(from, end);
102
+ view.dispatch(tr);
103
+ props.onSelect({
104
+ editor
105
+ });
106
+ view.focus();
107
+ },
108
+ items: ({ query })=>{
109
+ return items({
110
+ query,
111
+ editor
112
+ });
113
+ },
114
+ render: ()=>{
115
+ let component;
116
+ let scrollHandler = null;
117
+ return {
118
+ onStart: (props)=>{
119
+ setSuggestionProps(props);
120
+ props.editor.storage.slashSuggestion = {
121
+ ...props.editor.storage.slashSuggestion,
122
+ isActive: true
123
+ };
124
+ // Temporarily disable drag handle to prevent interference
125
+ props.editor.commands.setMeta('hideDragHandle', true);
126
+ component = new ReactRenderer(children, {
127
+ props,
128
+ editor: props.editor
129
+ });
130
+ const { view } = props.editor;
131
+ // Initialize the popup if needed
132
+ initPopup();
133
+ if (popupElement) {
134
+ // Clear previous content
135
+ popupElement.innerHTML = '';
136
+ // Append the component
137
+ popupElement.appendChild(component.element);
138
+ // Set up positioning
139
+ const getReferenceRect = ()=>{
140
+ const { state } = view;
141
+ const { selection } = state;
142
+ const coords = view.coordsAtPos(selection.from);
143
+ const node = view.nodeDOM(selection.from);
144
+ if (node && node instanceof Element) {
145
+ const rect = node.getBoundingClientRect();
146
+ return new DOMRect(coords.left, coords.top, 0, 0);
147
+ }
148
+ return new DOMRect(coords.left, coords.top, 0, 0);
149
+ };
150
+ // Set up auto-update for positioning
151
+ if (cleanupAutoUpdate) cleanupAutoUpdate();
152
+ cleanupAutoUpdate = autoUpdate({
153
+ getBoundingClientRect: getReferenceRect
154
+ }, popupElement, async ()=>{
155
+ await updatePopupPosition(getReferenceRect);
156
+ });
157
+ scrollHandler = ()=>{
158
+ updatePopupPosition(getReferenceRect);
159
+ };
160
+ view.dom.parentElement?.addEventListener('scroll', scrollHandler);
161
+ // Show the popup
162
+ showPopup();
163
+ }
164
+ },
165
+ onUpdate (props) {
166
+ setSuggestionProps(props);
167
+ component.updateProps(props);
168
+ // Update positioning for the popup
169
+ const { view } = props.editor;
170
+ const { state } = view;
171
+ const { selection } = state;
172
+ const coords = view.coordsAtPos(selection.from);
173
+ const getReferenceRect = ()=>{
174
+ return new DOMRect(coords.left, coords.top, 0, 0);
175
+ };
176
+ updatePopupPosition(getReferenceRect);
177
+ },
178
+ onKeyDown (props) {
179
+ if (props.event.key === 'Escape') {
180
+ hidePopup();
181
+ // Return focus to the editor
182
+ setTimeout(()=>{
183
+ editor.view.focus();
184
+ }, 0);
185
+ return true;
186
+ }
187
+ // Only move focus to menu for arrow keys
188
+ if (props.event.key === 'ArrowDown' || props.event.key === 'ArrowUp') {
189
+ if (!isPopupVisible) {
190
+ showPopup();
191
+ }
192
+ // Focus the menu element for navigation
193
+ setTimeout(()=>{
194
+ const menuElement = component.element.querySelector('[tabindex="0"]');
195
+ if (menuElement) {
196
+ menuElement.focus();
197
+ }
198
+ }, 0);
199
+ return false;
200
+ }
201
+ // Handle Enter key when menu is focused
202
+ if (props.event.key === 'Enter') {
203
+ if (!isPopupVisible) {
204
+ showPopup();
205
+ }
206
+ // Focus the menu element and let it handle Enter
207
+ setTimeout(()=>{
208
+ const menuElement = component.element.querySelector('[tabindex="0"]');
209
+ if (menuElement) {
210
+ menuElement.focus();
211
+ // Trigger Enter key on the menu
212
+ const enterEvent = new KeyboardEvent('keydown', {
213
+ key: 'Enter',
214
+ code: 'Enter',
215
+ keyCode: 13,
216
+ which: 13,
217
+ bubbles: true,
218
+ cancelable: true
219
+ });
220
+ menuElement.dispatchEvent(enterEvent);
221
+ }
222
+ }, 0);
223
+ return false;
224
+ }
225
+ // For any other key (letters, numbers, etc.), ensure editor has focus
226
+ // This handles the case where user types after opening the menu
227
+ if (!isPopupVisible) {
228
+ showPopup();
229
+ }
230
+ // Ensure editor has focus for typing
231
+ setTimeout(()=>{
232
+ editor.view.focus();
233
+ }, 0);
234
+ // Let the editor handle the key normally
235
+ return false;
236
+ },
237
+ onExit (props) {
238
+ // Set slash command as inactive in storage
239
+ ;
240
+ props.editor.storage.slashSuggestion = {
241
+ ...props.editor.storage.slashSuggestion,
242
+ isActive: false
243
+ };
244
+ // Re-enable drag handle
245
+ props.editor.commands.setMeta('hideDragHandle', false);
246
+ // Clean up scroll handler first
247
+ if (scrollHandler) {
248
+ const { view } = props.editor;
249
+ view.dom.parentElement?.removeEventListener('scroll', scrollHandler);
250
+ scrollHandler = null;
251
+ }
252
+ // Clean up auto-update listener
253
+ if (cleanupAutoUpdate) {
254
+ cleanupAutoUpdate();
255
+ cleanupAutoUpdate = null;
256
+ }
257
+ // Hide the popup
258
+ hidePopup();
259
+ // Clean up component
260
+ component?.destroy?.();
261
+ component = null;
262
+ setSuggestionProps(null);
263
+ // Clear popup content
264
+ if (popupElement) {
265
+ popupElement.innerHTML = '';
266
+ }
267
+ // Return focus to the editor
268
+ setTimeout(()=>{
269
+ props.editor.view.focus();
270
+ }, 0);
271
+ }
272
+ };
273
+ }
274
+ });
275
+ editor.registerPlugin(suggestion);
276
+ suggestionRef.current = suggestion;
277
+ return ()=>{
278
+ if (suggestionRef.current) {
279
+ editor.unregisterPlugin(suggestionRef.current);
280
+ suggestionRef.current = null;
281
+ }
282
+ };
283
+ }, [
284
+ editor,
285
+ char,
286
+ items
287
+ ]);
288
+ return null;
289
+ };
290
+
291
+ //# sourceMappingURL=SuggestionMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react'\r\nimport { Editor } from '@tiptap/core'\r\nimport { ReactRenderer } from '@tiptap/react'\r\nimport Suggestion, { SuggestionProps, SuggestionKeyDownProps } from '@tiptap/suggestion'\r\nimport { PluginKey } from '@tiptap/pm/state'\r\nimport { SuggestionItem } from './types.js'\r\nimport { computePosition, offset, autoUpdate } from '@floating-ui/dom'\r\n\r\ninterface SuggestionMenuProps {\r\n editor: Editor\r\n char: string\r\n items: (props: { query: string; editor: Editor }) => SuggestionItem[]\r\n children: (props: any) => React.ReactElement\r\n}\r\n\r\nlet popupElement: HTMLElement | null = null\r\nlet cleanupAutoUpdate: (() => void) | null = null\r\nlet isPopupVisible = false\r\n\r\n// Helper functions to manage Floating UI popup\r\nconst initPopup = () => {\r\n if (!popupElement && typeof document !== 'undefined') {\r\n popupElement = document.createElement('div')\r\n popupElement.style.position = 'fixed'\r\n popupElement.style.zIndex = '10000'\r\n popupElement.style.maxWidth = '16rem'\r\n popupElement.style.visibility = 'hidden'\r\n popupElement.style.opacity = '0'\r\n popupElement.style.transition = 'opacity 200ms'\r\n popupElement.className = 'slash-command-menu'\r\n document.body.appendChild(popupElement)\r\n }\r\n return popupElement\r\n}\r\n\r\nconst showPopup = () => {\r\n if (popupElement && !isPopupVisible) {\r\n isPopupVisible = true\r\n popupElement.style.display = 'block'\r\n popupElement.style.visibility = 'visible'\r\n popupElement.style.opacity = '1'\r\n }\r\n}\r\n\r\nconst hidePopup = () => {\r\n if (popupElement) {\r\n isPopupVisible = false\r\n popupElement.style.visibility = 'hidden'\r\n popupElement.style.opacity = '0'\r\n // Use setTimeout to wait for transition before hiding completely\r\n setTimeout(() => {\r\n if (popupElement && !isPopupVisible) {\r\n popupElement.style.display = 'none'\r\n }\r\n }, 200)\r\n }\r\n}\r\n\r\nconst updatePopupPosition = async (getReferenceRect: () => DOMRect) => {\r\n if (!popupElement || !isPopupVisible) return\r\n\r\n try {\r\n const rect = getReferenceRect()\r\n\r\n const virtualElement = {\r\n getBoundingClientRect: () => rect,\r\n }\r\n\r\n const { x, y } = await computePosition(virtualElement, popupElement, {\r\n placement: 'bottom-start',\r\n strategy: 'fixed',\r\n middleware: [offset({ mainAxis: 8, crossAxis: 16 })],\r\n })\r\n\r\n popupElement.style.left = `${x}px`\r\n popupElement.style.top = `${y}px`\r\n } catch (error) {\r\n console.error('Error updating popup position:', error)\r\n }\r\n}\r\n\r\nexport const SuggestionMenu = ({ editor, char, items, children }: SuggestionMenuProps) => {\r\n const [suggestionProps, setSuggestionProps] = useState<SuggestionProps | null>(null)\r\n const suggestionRef = useRef<any>(null)\r\n\r\n useEffect(() => {\r\n if (!editor) return\r\n\r\n // Clean up existing suggestion if it exists\r\n if (suggestionRef.current) {\r\n editor.unregisterPlugin(suggestionRef.current)\r\n }\r\n\r\n const suggestion = Suggestion({\r\n editor,\r\n char,\r\n allowSpaces: true,\r\n startOfLine: true,\r\n pluginKey: new PluginKey('slash-suggestion'),\r\n allow: ({ state, range }) => {\r\n const $from = state.doc.resolve(range.from)\r\n const isRootDepth = $from.depth === 1\r\n const isParagraph = $from.parent.type.name === 'paragraph'\r\n const isStartOfNode = $from.parent.textContent?.charAt(0) === char\r\n const isInColumn = editor.isActive('column')\r\n\r\n const afterContent = $from.parent.textContent?.substring(\r\n $from.parent.textContent?.indexOf(char),\r\n )\r\n const isValidAfterContent = !afterContent?.endsWith(' ')\r\n\r\n // Check if drag handle is locked (ContentItemMenu is open)\r\n const isDragHandleLocked = (editor.storage as any).dragHandle?.lockDragHandle\r\n\r\n const shouldAllow =\r\n ((isRootDepth && isParagraph && isStartOfNode) ||\r\n (isInColumn && isParagraph && isStartOfNode)) &&\r\n isValidAfterContent &&\r\n !isDragHandleLocked\r\n\r\n return shouldAllow\r\n },\r\n command: ({ editor, props }: { editor: Editor; props: any }) => {\r\n const { view, state } = editor\r\n const { $head, $from } = view.state.selection\r\n\r\n const end = $from.pos\r\n const from = $head?.nodeBefore\r\n ? end -\r\n ($head.nodeBefore.text?.substring($head.nodeBefore.text?.indexOf(char)).length ?? 0)\r\n : $from.start()\r\n\r\n const tr = state.tr.deleteRange(from, end)\r\n view.dispatch(tr)\r\n\r\n props.onSelect({ editor })\r\n view.focus()\r\n },\r\n items: ({ query }: { query: string }) => {\r\n return items({ query, editor })\r\n },\r\n render: () => {\r\n let component: any\r\n let scrollHandler: (() => void) | null = null\r\n\r\n return {\r\n onStart: (props: SuggestionProps) => {\r\n setSuggestionProps(props)\r\n\r\n // Set slash command as active in storage\r\n ;(props.editor.storage as any).slashSuggestion = {\r\n ...(props.editor.storage as any).slashSuggestion,\r\n isActive: true,\r\n }\r\n\r\n // Temporarily disable drag handle to prevent interference\r\n props.editor.commands.setMeta('hideDragHandle', true)\r\n\r\n component = new ReactRenderer(children, {\r\n props,\r\n editor: props.editor,\r\n })\r\n\r\n const { view } = props.editor\r\n\r\n // Initialize the popup if needed\r\n initPopup()\r\n\r\n if (popupElement) {\r\n // Clear previous content\r\n popupElement.innerHTML = ''\r\n // Append the component\r\n popupElement.appendChild(component.element)\r\n\r\n // Set up positioning\r\n const getReferenceRect = () => {\r\n const { state } = view\r\n const { selection } = state\r\n const coords = view.coordsAtPos(selection.from)\r\n const node = view.nodeDOM(selection.from)\r\n\r\n if (node && node instanceof Element) {\r\n const rect = node.getBoundingClientRect()\r\n return new DOMRect(coords.left, coords.top, 0, 0)\r\n }\r\n\r\n return new DOMRect(coords.left, coords.top, 0, 0)\r\n }\r\n\r\n // Set up auto-update for positioning\r\n if (cleanupAutoUpdate) cleanupAutoUpdate()\r\n cleanupAutoUpdate = autoUpdate(\r\n { getBoundingClientRect: getReferenceRect },\r\n popupElement,\r\n async () => {\r\n await updatePopupPosition(getReferenceRect)\r\n },\r\n )\r\n\r\n scrollHandler = () => {\r\n updatePopupPosition(getReferenceRect)\r\n }\r\n\r\n view.dom.parentElement?.addEventListener('scroll', scrollHandler)\r\n\r\n // Show the popup\r\n showPopup()\r\n }\r\n },\r\n\r\n onUpdate(props: SuggestionProps) {\r\n setSuggestionProps(props)\r\n component.updateProps(props)\r\n\r\n // Update positioning for the popup\r\n const { view } = props.editor\r\n const { state } = view\r\n const { selection } = state\r\n const coords = view.coordsAtPos(selection.from)\r\n\r\n const getReferenceRect = () => {\r\n return new DOMRect(coords.left, coords.top, 0, 0)\r\n }\r\n\r\n updatePopupPosition(getReferenceRect)\r\n },\r\n\r\n onKeyDown(props: SuggestionKeyDownProps) {\r\n if (props.event.key === 'Escape') {\r\n hidePopup()\r\n // Return focus to the editor\r\n setTimeout(() => {\r\n editor.view.focus()\r\n }, 0)\r\n return true\r\n }\r\n\r\n // Only move focus to menu for arrow keys\r\n if (props.event.key === 'ArrowDown' || props.event.key === 'ArrowUp') {\r\n if (!isPopupVisible) {\r\n showPopup()\r\n }\r\n\r\n // Focus the menu element for navigation\r\n setTimeout(() => {\r\n const menuElement = component.element.querySelector('[tabindex=\"0\"]')\r\n if (menuElement) {\r\n menuElement.focus()\r\n }\r\n }, 0)\r\n\r\n return false\r\n }\r\n\r\n // Handle Enter key when menu is focused\r\n if (props.event.key === 'Enter') {\r\n if (!isPopupVisible) {\r\n showPopup()\r\n }\r\n\r\n // Focus the menu element and let it handle Enter\r\n setTimeout(() => {\r\n const menuElement = component.element.querySelector('[tabindex=\"0\"]')\r\n if (menuElement) {\r\n menuElement.focus()\r\n // Trigger Enter key on the menu\r\n const enterEvent = new KeyboardEvent('keydown', {\r\n key: 'Enter',\r\n code: 'Enter',\r\n keyCode: 13,\r\n which: 13,\r\n bubbles: true,\r\n cancelable: true,\r\n })\r\n menuElement.dispatchEvent(enterEvent)\r\n }\r\n }, 0)\r\n\r\n return false\r\n }\r\n\r\n // For any other key (letters, numbers, etc.), ensure editor has focus\r\n // This handles the case where user types after opening the menu\r\n if (!isPopupVisible) {\r\n showPopup()\r\n }\r\n\r\n // Ensure editor has focus for typing\r\n setTimeout(() => {\r\n editor.view.focus()\r\n }, 0)\r\n\r\n // Let the editor handle the key normally\r\n return false\r\n },\r\n\r\n onExit(props) {\r\n // Set slash command as inactive in storage\r\n ;(props.editor.storage as any).slashSuggestion = {\r\n ...(props.editor.storage as any).slashSuggestion,\r\n isActive: false,\r\n }\r\n\r\n // Re-enable drag handle\r\n props.editor.commands.setMeta('hideDragHandle', false)\r\n\r\n // Clean up scroll handler first\r\n if (scrollHandler) {\r\n const { view } = props.editor\r\n view.dom.parentElement?.removeEventListener('scroll', scrollHandler)\r\n scrollHandler = null\r\n }\r\n\r\n // Clean up auto-update listener\r\n if (cleanupAutoUpdate) {\r\n cleanupAutoUpdate()\r\n cleanupAutoUpdate = null\r\n }\r\n\r\n // Hide the popup\r\n hidePopup()\r\n\r\n // Clean up component\r\n component?.destroy?.()\r\n component = null\r\n setSuggestionProps(null)\r\n\r\n // Clear popup content\r\n if (popupElement) {\r\n popupElement.innerHTML = ''\r\n }\r\n\r\n // Return focus to the editor\r\n setTimeout(() => {\r\n props.editor.view.focus()\r\n }, 0)\r\n },\r\n }\r\n },\r\n })\r\n\r\n editor.registerPlugin(suggestion)\r\n suggestionRef.current = suggestion\r\n\r\n return () => {\r\n if (suggestionRef.current) {\r\n editor.unregisterPlugin(suggestionRef.current)\r\n suggestionRef.current = null\r\n }\r\n }\r\n }, [editor, char, items])\r\n\r\n return null\r\n}\r\n"],"names":["React","useEffect","useRef","useState","ReactRenderer","Suggestion","PluginKey","computePosition","offset","autoUpdate","popupElement","cleanupAutoUpdate","isPopupVisible","initPopup","document","createElement","style","position","zIndex","maxWidth","visibility","opacity","transition","className","body","appendChild","showPopup","display","hidePopup","setTimeout","updatePopupPosition","getReferenceRect","rect","virtualElement","getBoundingClientRect","x","y","placement","strategy","middleware","mainAxis","crossAxis","left","top","error","console","SuggestionMenu","editor","char","items","children","suggestionProps","setSuggestionProps","suggestionRef","current","unregisterPlugin","suggestion","allowSpaces","startOfLine","pluginKey","allow","state","range","$from","doc","resolve","from","isRootDepth","depth","isParagraph","parent","type","name","isStartOfNode","textContent","charAt","isInColumn","isActive","afterContent","substring","indexOf","isValidAfterContent","endsWith","isDragHandleLocked","storage","dragHandle","lockDragHandle","shouldAllow","command","props","view","$head","selection","end","pos","nodeBefore","text","length","start","tr","deleteRange","dispatch","onSelect","focus","query","render","component","scrollHandler","onStart","slashSuggestion","commands","setMeta","innerHTML","element","coords","coordsAtPos","node","nodeDOM","Element","DOMRect","dom","parentElement","addEventListener","onUpdate","updateProps","onKeyDown","event","key","menuElement","querySelector","enterEvent","KeyboardEvent","code","keyCode","which","bubbles","cancelable","dispatchEvent","onExit","removeEventListener","destroy","registerPlugin"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { SlashDropdownMenu } from './SlashDropdownMenu.js';
2
+ export { SlashCommandTriggerButton } from './SlashCommandTriggerButton.js';
3
+ export { SuggestionMenu } from './SuggestionMenu.js';
4
+ export { SlashMenuList } from './SlashMenuList.js';
5
+ export type { SlashMenuItemType, SuggestionItem, SlashMenuConfig, SlashDropdownMenuProps, SlashCommandTriggerButtonProps, } from './types.js';
6
+ export { getSlashMenuItems, filterSuggestionItems, getDefaultSlashMenuItems } from './utils.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA"}