payload-richtext-tiptap 0.0.159 → 0.0.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.js +27 -4
- package/dist/src/fields/TiptapEditor/extensions/Paragraph/Paragraph.js.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts +3 -3
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.d.ts.map +1 -1
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js +23 -21
- package/dist/src/fields/TiptapEditor/extensions/extension-kit.js.map +1 -1
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.d.ts +4 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.js +32 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.d.ts +4 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.js +70 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.d.ts +10 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.js +249 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.d.ts +15 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.js +291 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SuggestionMenu.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.d.ts +7 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.js +7 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/index.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.d.ts +28 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.js +3 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/types.js.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.d.ts +6 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.js +222 -0
- package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/utils.js.map +1 -0
- package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.d.ts +2 -0
- package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.d.ts.map +1 -0
- package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.js +17 -0
- package/dist/src/fields/TiptapEditor/lib/utils/updateImageUrl.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Paragraph.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/Paragraph/Paragraph.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"Paragraph.d.ts","sourceRoot":"","sources":["../../../../../../src/fields/TiptapEditor/extensions/Paragraph/Paragraph.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,0FAsCpB,CAAA;AAEF,eAAe,SAAS,CAAA"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { mergeAttributes } from
|
|
2
|
-
import TiptapParagraph from
|
|
1
|
+
import { mergeAttributes } from '@tiptap/core';
|
|
2
|
+
import TiptapParagraph from '@tiptap/extension-paragraph';
|
|
3
3
|
export const Paragraph = TiptapParagraph.extend({
|
|
4
4
|
addAttributes () {
|
|
5
5
|
return {
|
|
6
6
|
textAlign: {
|
|
7
|
-
default:
|
|
7
|
+
default: ''
|
|
8
8
|
},
|
|
9
9
|
class: {
|
|
10
|
-
default:
|
|
10
|
+
default: ''
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
},
|
|
@@ -17,6 +17,29 @@ export const Paragraph = TiptapParagraph.extend({
|
|
|
17
17
|
mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
|
|
18
18
|
0
|
|
19
19
|
];
|
|
20
|
+
},
|
|
21
|
+
addKeyboardShortcuts () {
|
|
22
|
+
return {
|
|
23
|
+
Backspace: ({ editor })=>{
|
|
24
|
+
const { state } = editor;
|
|
25
|
+
const { selection } = state;
|
|
26
|
+
const { $from, empty } = selection;
|
|
27
|
+
if (!empty) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if ($from.parent.type.name !== 'paragraph') {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const isEmpty = $from.parent.content.size === 0;
|
|
34
|
+
const isAtStart = $from.parentOffset === 0;
|
|
35
|
+
// If the paragraph is empty and we're at the start, delete it
|
|
36
|
+
if (isEmpty && isAtStart) {
|
|
37
|
+
const pos = $from.before();
|
|
38
|
+
return editor.chain().setNodeSelection(pos).deleteSelection().run();
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
20
43
|
}
|
|
21
44
|
});
|
|
22
45
|
export default Paragraph;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/Paragraph/Paragraph.ts"],"sourcesContent":["import { mergeAttributes } from
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/fields/TiptapEditor/extensions/Paragraph/Paragraph.ts"],"sourcesContent":["import { mergeAttributes } from '@tiptap/core'\r\nimport TiptapParagraph from '@tiptap/extension-paragraph'\r\n\r\nexport const Paragraph = TiptapParagraph.extend({\r\n addAttributes() {\r\n return {\r\n textAlign: { default: '' },\r\n class: { default: '' },\r\n }\r\n },\r\n renderHTML({ node, HTMLAttributes }) {\r\n return ['p', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]\r\n },\r\n addKeyboardShortcuts() {\r\n return {\r\n Backspace: ({ editor }) => {\r\n const { state } = editor\r\n const { selection } = state\r\n const { $from, empty } = selection\r\n\r\n if (!empty) {\r\n return false\r\n }\r\n\r\n if ($from.parent.type.name !== 'paragraph') {\r\n return false\r\n }\r\n\r\n const isEmpty = $from.parent.content.size === 0\r\n const isAtStart = $from.parentOffset === 0\r\n\r\n // If the paragraph is empty and we're at the start, delete it\r\n if (isEmpty && isAtStart) {\r\n const pos = $from.before()\r\n return editor.chain().setNodeSelection(pos).deleteSelection().run()\r\n }\r\n\r\n return false\r\n },\r\n }\r\n },\r\n})\r\n\r\nexport default Paragraph\r\n"],"names":["mergeAttributes","TiptapParagraph","Paragraph","extend","addAttributes","textAlign","default","class","renderHTML","node","HTMLAttributes","options","addKeyboardShortcuts","Backspace","editor","state","selection","$from","empty","parent","type","name","isEmpty","content","size","isAtStart","parentOffset","pos","before","chain","setNodeSelection","deleteSelection","run"],"mappings":"AAAA,SAASA,eAAe,QAAQ,eAAc;AAC9C,OAAOC,qBAAqB,8BAA6B;AAEzD,OAAO,MAAMC,YAAYD,gBAAgBE,MAAM,CAAC;IAC9CC;QACE,OAAO;YACLC,WAAW;gBAAEC,SAAS;YAAG;YACzBC,OAAO;gBAAED,SAAS;YAAG;QACvB;IACF;IACAE,YAAW,EAAEC,IAAI,EAAEC,cAAc,EAAE;QACjC,OAAO;YAAC;YAAKV,gBAAgB,IAAI,CAACW,OAAO,CAACD,cAAc,EAAEA;YAAiB;SAAE;IAC/E;IACAE;QACE,OAAO;YACLC,WAAW,CAAC,EAAEC,MAAM,EAAE;gBACpB,MAAM,EAAEC,KAAK,EAAE,GAAGD;gBAClB,MAAM,EAAEE,SAAS,EAAE,GAAGD;gBACtB,MAAM,EAAEE,KAAK,EAAEC,KAAK,EAAE,GAAGF;gBAEzB,IAAI,CAACE,OAAO;oBACV,OAAO;gBACT;gBAEA,IAAID,MAAME,MAAM,CAACC,IAAI,CAACC,IAAI,KAAK,aAAa;oBAC1C,OAAO;gBACT;gBAEA,MAAMC,UAAUL,MAAME,MAAM,CAACI,OAAO,CAACC,IAAI,KAAK;gBAC9C,MAAMC,YAAYR,MAAMS,YAAY,KAAK;gBAEzC,8DAA8D;gBAC9D,IAAIJ,WAAWG,WAAW;oBACxB,MAAME,MAAMV,MAAMW,MAAM;oBACxB,OAAOd,OAAOe,KAAK,GAAGC,gBAAgB,CAACH,KAAKI,eAAe,GAAGC,GAAG;gBACnE;gBAEA,OAAO;YACT;QACF;IACF;AACF,GAAE;AAEF,eAAe9B,UAAS"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { openAssetHQType } from
|
|
1
|
+
import { openAssetHQType } from '../types.js';
|
|
2
2
|
interface ExtensionKitProps {
|
|
3
3
|
openAssetHQHandler: openAssetHQType;
|
|
4
|
-
dir?:
|
|
4
|
+
dir?: 'ltr' | 'rtl';
|
|
5
5
|
}
|
|
6
|
-
export declare const ExtensionKit: ({ dir, openAssetHQHandler
|
|
6
|
+
export declare const ExtensionKit: ({ dir, openAssetHQHandler }: ExtensionKitProps) => (import("@tiptap/core").Node<any, any> | import("@tiptap/core").Extension<any, any> | import("@tiptap/core").Mark<import("@tiptap/extension-subscript").SubscriptExtensionOptions, any>)[];
|
|
7
7
|
export default ExtensionKit;
|
|
8
8
|
//# sourceMappingURL=extension-kit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-kit.d.ts","sourceRoot":"","sources":["../../../../../src/fields/TiptapEditor/extensions/extension-kit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extension-kit.d.ts","sourceRoot":"","sources":["../../../../../src/fields/TiptapEditor/extensions/extension-kit.ts"],"names":[],"mappings":"AAkDA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAI7C,UAAU,iBAAiB;IACzB,kBAAkB,EAAE,eAAe,CAAA;IACnC,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;CACpB;AAED,eAAO,MAAM,YAAY,gCAAyC,iBAAiB,+LA4HlF,CAAA;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { AICommand, AudioBlock, BlockquoteFigure, CharacterCount, Document, Dropcursor, Facebook, Figcaption, FileHandler, Focus, Heading, HorizontalRule, LinkPreview, ImageBlock, InsideLinks, Instagram, Link, Linkedin, Placeholder, Selection, SlashCommand, StarterKit, Subscript, Superscript, TaskItem, TaskList, TextAlign, TextStyle, Tiktok,
|
|
2
|
-
import { ImageUpload } from
|
|
3
|
-
import History from
|
|
4
|
-
import { Markdown } from
|
|
5
|
-
import API from
|
|
6
|
-
import i18next from
|
|
7
|
-
import { getAssetActualSize } from
|
|
8
|
-
export const ExtensionKit = ({ dir =
|
|
1
|
+
import { AICommand, AudioBlock, BlockquoteFigure, CharacterCount, Document, Dropcursor, Facebook, Figcaption, FileHandler, Focus, Heading, HorizontalRule, LinkPreview, ImageBlock, InsideLinks, Instagram, Link, Linkedin, Paragraph, Placeholder, Selection, SlashCommand, StarterKit, Subscript, Superscript, TaskItem, TaskList, TextAlign, TextStyle, Tiktok, Twitter, Typography, Underline, VideoBlock, Youtube, Iframe, BulletList } from './index.js';
|
|
2
|
+
import { ImageUpload } from './ImageUpload/ImageUpload.js';
|
|
3
|
+
import History from '@tiptap/extension-history';
|
|
4
|
+
import { Markdown } from 'tiptap-markdown';
|
|
5
|
+
import API from '../lib/api.js';
|
|
6
|
+
import i18next from 'i18next';
|
|
7
|
+
import { getAssetActualSize } from './ImageUpload/getImageActualSize.js';
|
|
8
|
+
export const ExtensionKit = ({ dir = 'ltr', openAssetHQHandler })=>[
|
|
9
9
|
Markdown,
|
|
10
10
|
Document,
|
|
11
11
|
TaskList,
|
|
@@ -31,13 +31,15 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
31
31
|
horizontalRule: false,
|
|
32
32
|
blockquote: false,
|
|
33
33
|
history: false,
|
|
34
|
-
codeBlock: false
|
|
34
|
+
codeBlock: false,
|
|
35
|
+
paragraph: false
|
|
35
36
|
}),
|
|
37
|
+
Paragraph,
|
|
36
38
|
TextStyle,
|
|
37
39
|
// FontSize,
|
|
38
40
|
// FontFamily,
|
|
39
41
|
// Color,
|
|
40
|
-
TrailingNode,
|
|
42
|
+
// TrailingNode,
|
|
41
43
|
Link.configure({
|
|
42
44
|
openOnClick: false
|
|
43
45
|
}),
|
|
@@ -54,17 +56,17 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
54
56
|
AudioBlock,
|
|
55
57
|
FileHandler.configure({
|
|
56
58
|
allowedMimeTypes: [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
'image/png',
|
|
60
|
+
'image/jpeg',
|
|
61
|
+
'image/gif',
|
|
62
|
+
'image/webp'
|
|
61
63
|
],
|
|
62
64
|
onDrop: (currentEditor, files, pos)=>{
|
|
63
65
|
const file = files[0];
|
|
64
66
|
(async ()=>{
|
|
65
67
|
openAssetHQHandler((asset)=>{
|
|
66
68
|
let title = asset.title;
|
|
67
|
-
if (i18next.language !==
|
|
69
|
+
if (i18next.language !== 'en' && !!asset.title_locale[i18next.language.toUpperCase()]) {
|
|
68
70
|
title = asset.title_locale[i18next.language.toUpperCase()];
|
|
69
71
|
}
|
|
70
72
|
const { actualHeight, actualWidth } = getAssetActualSize(asset);
|
|
@@ -75,7 +77,7 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
75
77
|
actualHeight,
|
|
76
78
|
actualWidth
|
|
77
79
|
}).focus().run();
|
|
78
|
-
}, file,
|
|
80
|
+
}, file, 'image');
|
|
79
81
|
})();
|
|
80
82
|
},
|
|
81
83
|
onPaste: (currentEditor, files)=>{
|
|
@@ -97,10 +99,10 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
97
99
|
return {};
|
|
98
100
|
}
|
|
99
101
|
}).configure({
|
|
100
|
-
defaultAlignment: dir ===
|
|
102
|
+
defaultAlignment: dir === 'rtl' ? 'right' : 'left',
|
|
101
103
|
types: [
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
'heading',
|
|
105
|
+
'paragraph'
|
|
104
106
|
]
|
|
105
107
|
}),
|
|
106
108
|
Subscript,
|
|
@@ -109,7 +111,7 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
109
111
|
Placeholder.configure({
|
|
110
112
|
includeChildren: true,
|
|
111
113
|
showOnlyCurrent: false,
|
|
112
|
-
placeholder: ()=>
|
|
114
|
+
placeholder: ()=>''
|
|
113
115
|
}),
|
|
114
116
|
SlashCommand,
|
|
115
117
|
Focus,
|
|
@@ -117,7 +119,7 @@ export const ExtensionKit = ({ dir = "ltr", openAssetHQHandler })=>[
|
|
|
117
119
|
BlockquoteFigure,
|
|
118
120
|
Dropcursor.configure({
|
|
119
121
|
width: 2,
|
|
120
|
-
class:
|
|
122
|
+
class: 'ProseMirror-dropcursor border-black'
|
|
121
123
|
}),
|
|
122
124
|
History,
|
|
123
125
|
Twitter,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/fields/TiptapEditor/extensions/extension-kit.ts"],"sourcesContent":["import {\r\n AICommand,\r\n AudioBlock,\r\n BlockquoteFigure,\r\n CharacterCount,\r\n Color,\r\n Document,\r\n Dropcursor,\r\n Facebook,\r\n Figcaption,\r\n FileHandler,\r\n Focus,\r\n FontFamily,\r\n FontSize,\r\n Heading,\r\n Highlight,\r\n HorizontalRule,\r\n LinkPreview,\r\n ImageBlock,\r\n InsideLinks,\r\n Instagram,\r\n Link,\r\n Linkedin,\r\n Placeholder,\r\n Selection,\r\n SlashCommand,\r\n StarterKit,\r\n Subscript,\r\n Superscript,\r\n TaskItem,\r\n TaskList,\r\n TextAlign,\r\n TextStyle,\r\n Tiktok,\r\n TrailingNode,\r\n Twitter,\r\n Typography,\r\n Underline,\r\n VideoBlock,\r\n Youtube,\r\n Iframe,\r\n BulletList,\r\n} from
|
|
1
|
+
{"version":3,"sources":["../../../../../src/fields/TiptapEditor/extensions/extension-kit.ts"],"sourcesContent":["import {\r\n AICommand,\r\n AudioBlock,\r\n BlockquoteFigure,\r\n CharacterCount,\r\n Color,\r\n Document,\r\n Dropcursor,\r\n Facebook,\r\n Figcaption,\r\n FileHandler,\r\n Focus,\r\n FontFamily,\r\n FontSize,\r\n Heading,\r\n Highlight,\r\n HorizontalRule,\r\n LinkPreview,\r\n ImageBlock,\r\n InsideLinks,\r\n Instagram,\r\n Link,\r\n Linkedin,\r\n Paragraph,\r\n Placeholder,\r\n Selection,\r\n SlashCommand,\r\n StarterKit,\r\n Subscript,\r\n Superscript,\r\n TaskItem,\r\n TaskList,\r\n TextAlign,\r\n TextStyle,\r\n Tiktok,\r\n TrailingNode,\r\n Twitter,\r\n Typography,\r\n Underline,\r\n VideoBlock,\r\n Youtube,\r\n Iframe,\r\n BulletList,\r\n} from './index.js'\r\n\r\nimport { ImageUpload } from './ImageUpload/ImageUpload.js'\r\n\r\nimport History from '@tiptap/extension-history'\r\nimport { Markdown } from 'tiptap-markdown'\r\nimport API from '../lib/api.js'\r\nimport { openAssetHQType } from '../types.js'\r\nimport i18next from 'i18next'\r\nimport { getAssetActualSize } from './ImageUpload/getImageActualSize.js'\r\n\r\ninterface ExtensionKitProps {\r\n openAssetHQHandler: openAssetHQType\r\n dir?: 'ltr' | 'rtl'\r\n}\r\n\r\nexport const ExtensionKit = ({ dir = 'ltr', openAssetHQHandler }: ExtensionKitProps) => [\r\n Markdown,\r\n Document,\r\n TaskList,\r\n TaskItem.configure({\r\n nested: true,\r\n }),\r\n Selection,\r\n Heading.configure({\r\n levels: [1, 2, 3, 4, 5, 6],\r\n }),\r\n HorizontalRule,\r\n StarterKit.configure({\r\n document: false,\r\n dropcursor: false,\r\n heading: false,\r\n horizontalRule: false,\r\n blockquote: false,\r\n history: false,\r\n codeBlock: false,\r\n paragraph: false,\r\n }),\r\n Paragraph,\r\n TextStyle,\r\n // FontSize,\r\n // FontFamily,\r\n // Color,\r\n // TrailingNode,\r\n Link.configure({\r\n openOnClick: false,\r\n }),\r\n // Highlight.configure({ multicolor: true }),\r\n Underline,\r\n CharacterCount.configure({ limit: 50000 }),\r\n ImageUpload.configure({\r\n openAssetHQHandler,\r\n }),\r\n ImageBlock,\r\n VideoBlock,\r\n AudioBlock,\r\n FileHandler.configure({\r\n allowedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],\r\n onDrop: (currentEditor, files, pos) => {\r\n const file = files[0]\r\n ;(async () => {\r\n openAssetHQHandler(\r\n (asset) => {\r\n let title = asset.title\r\n if (i18next.language !== 'en' && !!asset.title_locale[i18next.language.toUpperCase()]) {\r\n title = asset.title_locale[i18next.language.toUpperCase()]\r\n }\r\n const { actualHeight, actualWidth } = getAssetActualSize(asset)\r\n currentEditor\r\n .chain()\r\n .setImageBlockAt({\r\n pos,\r\n src: asset?.optimizedImageUrl || asset.fullUrl,\r\n caption: title,\r\n actualHeight,\r\n actualWidth,\r\n })\r\n .focus()\r\n .run()\r\n },\r\n file,\r\n 'image',\r\n )\r\n })()\r\n },\r\n onPaste: (currentEditor, files) => {\r\n files.forEach(async () => {\r\n const url = await API.uploadImage()\r\n\r\n return currentEditor\r\n .chain()\r\n .setImageBlockAt({\r\n pos: currentEditor.state.selection.anchor,\r\n src: url,\r\n })\r\n .focus()\r\n .run()\r\n })\r\n },\r\n }),\r\n // Emoji.configure({\r\n // enableEmoticons: true,\r\n // suggestion: emojiSuggestion,\r\n // }),\r\n TextAlign.extend({\r\n addKeyboardShortcuts() {\r\n return {}\r\n },\r\n }).configure({\r\n defaultAlignment: dir === 'rtl' ? 'right' : 'left',\r\n types: ['heading', 'paragraph'],\r\n }),\r\n Subscript,\r\n Superscript,\r\n Typography,\r\n Placeholder.configure({\r\n includeChildren: true,\r\n showOnlyCurrent: false,\r\n placeholder: () => '',\r\n }),\r\n SlashCommand,\r\n Focus,\r\n Figcaption,\r\n BlockquoteFigure,\r\n Dropcursor.configure({\r\n width: 2,\r\n class: 'ProseMirror-dropcursor border-black',\r\n }),\r\n History,\r\n Twitter,\r\n Tiktok,\r\n Instagram,\r\n Facebook,\r\n Linkedin,\r\n Youtube,\r\n InsideLinks,\r\n Iframe,\r\n AICommand,\r\n LinkPreview,\r\n BulletList,\r\n]\r\n\r\nexport default ExtensionKit\r\n"],"names":["AICommand","AudioBlock","BlockquoteFigure","CharacterCount","Document","Dropcursor","Facebook","Figcaption","FileHandler","Focus","Heading","HorizontalRule","LinkPreview","ImageBlock","InsideLinks","Instagram","Link","Linkedin","Paragraph","Placeholder","Selection","SlashCommand","StarterKit","Subscript","Superscript","TaskItem","TaskList","TextAlign","TextStyle","Tiktok","Twitter","Typography","Underline","VideoBlock","Youtube","Iframe","BulletList","ImageUpload","History","Markdown","API","i18next","getAssetActualSize","ExtensionKit","dir","openAssetHQHandler","configure","nested","levels","document","dropcursor","heading","horizontalRule","blockquote","history","codeBlock","paragraph","openOnClick","limit","allowedMimeTypes","onDrop","currentEditor","files","pos","file","asset","title","language","title_locale","toUpperCase","actualHeight","actualWidth","chain","setImageBlockAt","src","optimizedImageUrl","fullUrl","caption","focus","run","onPaste","forEach","url","uploadImage","state","selection","anchor","extend","addKeyboardShortcuts","defaultAlignment","types","includeChildren","showOnlyCurrent","placeholder","width","class"],"mappings":"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"}
|
package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlashCommandTriggerButton.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAK3D,eAAO,MAAM,yBAAyB,uBAAwB,8BAA8B,sBAqB3F,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Button } from '../Button/Button.jsx';
|
|
4
|
+
import { Icon } from '../Icon.js';
|
|
5
|
+
import { Plus } from 'lucide-react';
|
|
6
|
+
export const SlashCommandTriggerButton = ({ editor, config })=>{
|
|
7
|
+
if (!editor) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const handleClick = ()=>{
|
|
11
|
+
// Insert a slash command trigger
|
|
12
|
+
editor.chain().focus().insertContent('/').run();
|
|
13
|
+
};
|
|
14
|
+
return /*#__PURE__*/ _jsxs(Button, {
|
|
15
|
+
variant: "ghost",
|
|
16
|
+
buttonSize: "small",
|
|
17
|
+
onClick: handleClick,
|
|
18
|
+
className: "flex items-center gap-2 text-neutral-500 hover:text-black",
|
|
19
|
+
children: [
|
|
20
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
21
|
+
icon: Plus,
|
|
22
|
+
className: "w-4 h-4"
|
|
23
|
+
}),
|
|
24
|
+
/*#__PURE__*/ _jsx("span", {
|
|
25
|
+
className: "text-sm font-medium",
|
|
26
|
+
children: "Insert"
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=SlashCommandTriggerButton.js.map
|
package/dist/src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashCommandTriggerButton.tsx"],"sourcesContent":["import React from 'react'\r\nimport { Editor } from '@tiptap/core'\r\nimport { SlashCommandTriggerButtonProps } from './types.js'\r\nimport { Button } from '../Button/Button.jsx'\r\nimport { Icon } from '../Icon.js'\r\nimport { Plus } from 'lucide-react'\r\n\r\nexport const SlashCommandTriggerButton = ({ editor, config }: SlashCommandTriggerButtonProps) => {\r\n if (!editor) {\r\n return null\r\n }\r\n\r\n const handleClick = () => {\r\n // Insert a slash command trigger\r\n editor.chain().focus().insertContent('/').run()\r\n }\r\n\r\n return (\r\n <Button\r\n variant=\"ghost\"\r\n buttonSize=\"small\"\r\n onClick={handleClick}\r\n className=\"flex items-center gap-2 text-neutral-500 hover:text-black\"\r\n >\r\n <Icon icon={Plus} className=\"w-4 h-4\" />\r\n <span className=\"text-sm font-medium\">Insert</span>\r\n </Button>\r\n )\r\n}\r\n"],"names":["React","Button","Icon","Plus","SlashCommandTriggerButton","editor","config","handleClick","chain","focus","insertContent","run","variant","buttonSize","onClick","className","icon","span"],"mappings":";AAAA,OAAOA,WAAW,QAAO;AAGzB,SAASC,MAAM,QAAQ,uBAAsB;AAC7C,SAASC,IAAI,QAAQ,aAAY;AACjC,SAASC,IAAI,QAAQ,eAAc;AAEnC,OAAO,MAAMC,4BAA4B,CAAC,EAAEC,MAAM,EAAEC,MAAM,EAAkC;IAC1F,IAAI,CAACD,QAAQ;QACX,OAAO;IACT;IAEA,MAAME,cAAc;QAClB,iCAAiC;QACjCF,OAAOG,KAAK,GAAGC,KAAK,GAAGC,aAAa,CAAC,KAAKC,GAAG;IAC/C;IAEA,qBACE,MAACV;QACCW,SAAQ;QACRC,YAAW;QACXC,SAASP;QACTQ,WAAU;;0BAEV,KAACb;gBAAKc,MAAMb;gBAAMY,WAAU;;0BAC5B,KAACE;gBAAKF,WAAU;0BAAsB;;;;AAG5C,EAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlashDropdownMenu.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,sBAAsB,EAAmC,MAAM,YAAY,CAAA;AA+CpF,eAAO,MAAM,iBAAiB,uBAAwC,sBAAsB,sBAwB3F,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { SuggestionMenu } from './SuggestionMenu.js';
|
|
4
|
+
import { SlashMenuList } from './SlashMenuList.js';
|
|
5
|
+
import { getSlashMenuItems, filterSuggestionItems } from './utils.js';
|
|
6
|
+
const defaultConfig = {
|
|
7
|
+
enabledItems: [
|
|
8
|
+
'text',
|
|
9
|
+
'heading_1',
|
|
10
|
+
'heading_2',
|
|
11
|
+
'heading_3',
|
|
12
|
+
'bullet_list',
|
|
13
|
+
'ordered_list',
|
|
14
|
+
'quote',
|
|
15
|
+
'code_block',
|
|
16
|
+
'image',
|
|
17
|
+
'horizontal_rule',
|
|
18
|
+
'button',
|
|
19
|
+
'custom_html',
|
|
20
|
+
'social',
|
|
21
|
+
'columns',
|
|
22
|
+
'unsubscribe_footer',
|
|
23
|
+
'twitter'
|
|
24
|
+
],
|
|
25
|
+
showGroups: true,
|
|
26
|
+
itemGroups: {
|
|
27
|
+
text: 'Style',
|
|
28
|
+
heading_1: 'Style',
|
|
29
|
+
heading_2: 'Style',
|
|
30
|
+
heading_3: 'Style',
|
|
31
|
+
bullet_list: 'Lists',
|
|
32
|
+
ordered_list: 'Lists',
|
|
33
|
+
quote: 'Style',
|
|
34
|
+
code_block: 'Style',
|
|
35
|
+
image: 'Content',
|
|
36
|
+
horizontal_rule: 'Content',
|
|
37
|
+
button: 'Content',
|
|
38
|
+
custom_html: 'Content',
|
|
39
|
+
social: 'Content',
|
|
40
|
+
columns: 'Layout',
|
|
41
|
+
unsubscribe_footer: 'Content',
|
|
42
|
+
twitter: 'Content'
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export const SlashDropdownMenu = ({ editor, config = defaultConfig })=>{
|
|
46
|
+
if (!editor) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const mergedConfig = {
|
|
50
|
+
...defaultConfig,
|
|
51
|
+
...config
|
|
52
|
+
};
|
|
53
|
+
const getItems = ({ query, editor })=>{
|
|
54
|
+
const allItems = getSlashMenuItems(editor, mergedConfig);
|
|
55
|
+
return filterSuggestionItems(allItems, query);
|
|
56
|
+
};
|
|
57
|
+
return /*#__PURE__*/ _jsx(SuggestionMenu, {
|
|
58
|
+
editor: editor,
|
|
59
|
+
char: "/",
|
|
60
|
+
items: getItems,
|
|
61
|
+
children: (props)=>/*#__PURE__*/ _jsx(SlashMenuList, {
|
|
62
|
+
ref: props.ref,
|
|
63
|
+
items: props.items,
|
|
64
|
+
command: props.command,
|
|
65
|
+
showGroups: mergedConfig.showGroups
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=SlashDropdownMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashDropdownMenu.tsx"],"sourcesContent":["import React from 'react'\r\nimport { Editor } from '@tiptap/core'\r\nimport { SlashDropdownMenuProps, SlashMenuConfig, SuggestionItem } from './types.js'\r\nimport { SuggestionMenu } from './SuggestionMenu.js'\r\nimport { SlashMenuList } from './SlashMenuList.js'\r\nimport { getSlashMenuItems, filterSuggestionItems } from './utils.js'\r\n\r\nconst defaultConfig: SlashMenuConfig = {\r\n enabledItems: [\r\n 'text',\r\n 'heading_1',\r\n 'heading_2',\r\n 'heading_3',\r\n 'bullet_list',\r\n 'ordered_list',\r\n 'quote',\r\n 'code_block',\r\n 'image',\r\n 'horizontal_rule',\r\n 'button',\r\n 'custom_html',\r\n 'social',\r\n 'columns',\r\n 'unsubscribe_footer',\r\n 'twitter',\r\n // 'ai_writer',\r\n ],\r\n showGroups: true,\r\n itemGroups: {\r\n text: 'Style',\r\n heading_1: 'Style',\r\n heading_2: 'Style',\r\n heading_3: 'Style',\r\n bullet_list: 'Lists',\r\n ordered_list: 'Lists',\r\n quote: 'Style',\r\n code_block: 'Style',\r\n image: 'Content',\r\n horizontal_rule: 'Content',\r\n button: 'Content',\r\n custom_html: 'Content',\r\n social: 'Content',\r\n columns: 'Layout',\r\n unsubscribe_footer: 'Content',\r\n twitter: 'Content',\r\n // ai_writer: 'AI',\r\n },\r\n}\r\n\r\nexport const SlashDropdownMenu = ({ editor, config = defaultConfig }: SlashDropdownMenuProps) => {\r\n if (!editor) {\r\n return null\r\n }\r\n\r\n const mergedConfig = { ...defaultConfig, ...config }\r\n\r\n const getItems = ({ query, editor }: { query: string; editor: Editor }) => {\r\n const allItems = getSlashMenuItems(editor, mergedConfig)\r\n return filterSuggestionItems(allItems, query)\r\n }\r\n\r\n return (\r\n <SuggestionMenu editor={editor} char=\"/\" items={getItems}>\r\n {(props: any) => (\r\n <SlashMenuList\r\n ref={props.ref}\r\n items={props.items}\r\n command={props.command}\r\n showGroups={mergedConfig.showGroups}\r\n />\r\n )}\r\n </SuggestionMenu>\r\n )\r\n}\r\n"],"names":["React","SuggestionMenu","SlashMenuList","getSlashMenuItems","filterSuggestionItems","defaultConfig","enabledItems","showGroups","itemGroups","text","heading_1","heading_2","heading_3","bullet_list","ordered_list","quote","code_block","image","horizontal_rule","button","custom_html","social","columns","unsubscribe_footer","twitter","SlashDropdownMenu","editor","config","mergedConfig","getItems","query","allItems","char","items","props","ref","command"],"mappings":";AAAA,OAAOA,WAAW,QAAO;AAGzB,SAASC,cAAc,QAAQ,sBAAqB;AACpD,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,iBAAiB,EAAEC,qBAAqB,QAAQ,aAAY;AAErE,MAAMC,gBAAiC;IACrCC,cAAc;QACZ;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KAED;IACDC,YAAY;IACZC,YAAY;QACVC,MAAM;QACNC,WAAW;QACXC,WAAW;QACXC,WAAW;QACXC,aAAa;QACbC,cAAc;QACdC,OAAO;QACPC,YAAY;QACZC,OAAO;QACPC,iBAAiB;QACjBC,QAAQ;QACRC,aAAa;QACbC,QAAQ;QACRC,SAAS;QACTC,oBAAoB;QACpBC,SAAS;IAEX;AACF;AAEA,OAAO,MAAMC,oBAAoB,CAAC,EAAEC,MAAM,EAAEC,SAAStB,aAAa,EAA0B;IAC1F,IAAI,CAACqB,QAAQ;QACX,OAAO;IACT;IAEA,MAAME,eAAe;QAAE,GAAGvB,aAAa;QAAE,GAAGsB,MAAM;IAAC;IAEnD,MAAME,WAAW,CAAC,EAAEC,KAAK,EAAEJ,MAAM,EAAqC;QACpE,MAAMK,WAAW5B,kBAAkBuB,QAAQE;QAC3C,OAAOxB,sBAAsB2B,UAAUD;IACzC;IAEA,qBACE,KAAC7B;QAAeyB,QAAQA;QAAQM,MAAK;QAAIC,OAAOJ;kBAC7C,CAACK,sBACA,KAAChC;gBACCiC,KAAKD,MAAMC,GAAG;gBACdF,OAAOC,MAAMD,KAAK;gBAClBG,SAASF,MAAME,OAAO;gBACtB7B,YAAYqB,aAAarB,UAAU;;;AAK7C,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SuggestionItem } from './types.js';
|
|
3
|
+
interface SlashMenuListProps {
|
|
4
|
+
items: SuggestionItem[];
|
|
5
|
+
command: (item: SuggestionItem) => void;
|
|
6
|
+
showGroups?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const SlashMenuList: React.ForwardRefExoticComponent<SlashMenuListProps & React.RefAttributes<any>>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=SlashMenuList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlashMenuList.d.ts","sourceRoot":"","sources":["../../../../../../../src/fields/TiptapEditor/features/ui/SlashCommand/SlashMenuList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAK3C,UAAU,kBAAkB;IAC1B,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;IACvC,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,eAAO,MAAM,aAAa,gFAoPzB,CAAA"}
|
|
@@ -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
|