neuphlo-editor 2.5.0 → 2.6.0

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 (171) hide show
  1. package/dist/Markdown-BAW0cb-U.d.cts +153 -0
  2. package/dist/Markdown-BAW0cb-U.d.ts +153 -0
  3. package/dist/{chunk-4L7FHW5M.js → chunk-ABL4D65Z.js} +113 -47
  4. package/dist/chunk-ABL4D65Z.js.map +1 -0
  5. package/dist/{chunk-BVFTQKY7.js → chunk-Z2DR2FK3.js} +245 -50
  6. package/dist/chunk-Z2DR2FK3.js.map +1 -0
  7. package/dist/headless/components/editor-bubble-item.d.ts +9 -0
  8. package/dist/headless/components/editor-bubble-item.js +29 -0
  9. package/dist/headless/components/editor-bubble.d.ts +9 -0
  10. package/dist/headless/components/editor-bubble.js +9 -0
  11. package/dist/headless/components/editor-command-item.d.ts +3 -0
  12. package/dist/headless/components/editor-command-item.js +27 -0
  13. package/dist/headless/components/editor-command.d.ts +3 -0
  14. package/dist/headless/components/editor-command.js +136 -0
  15. package/dist/headless/components/editor.d.ts +24 -0
  16. package/dist/headless/components/editor.js +13 -0
  17. package/dist/headless/extensions/AISuggestion/AISuggestion.d.ts +82 -0
  18. package/dist/headless/extensions/AISuggestion/AISuggestion.js +244 -0
  19. package/dist/headless/extensions/AISuggestion/index.d.ts +2 -0
  20. package/dist/headless/extensions/AISuggestion/index.js +1 -0
  21. package/dist/headless/extensions/CodeBlock/CodeBlock.d.ts +1 -0
  22. package/dist/headless/extensions/CodeBlock/CodeBlock.js +6 -0
  23. package/dist/headless/extensions/CodeBlock/index.d.ts +1 -0
  24. package/dist/headless/extensions/CodeBlock/index.js +1 -0
  25. package/dist/headless/extensions/DragHandle/DragHandle.d.ts +9 -0
  26. package/dist/headless/extensions/DragHandle/DragHandle.js +47 -0
  27. package/dist/headless/extensions/DragHandle/index.d.ts +2 -0
  28. package/dist/headless/extensions/DragHandle/index.js +1 -0
  29. package/dist/headless/extensions/Image/Image.d.ts +6 -0
  30. package/dist/headless/extensions/Image/Image.js +197 -0
  31. package/dist/headless/extensions/ImageBlock/ImageBlock.d.ts +23 -0
  32. package/dist/headless/extensions/ImageBlock/ImageBlock.js +242 -0
  33. package/dist/headless/extensions/ImageBlock/index.d.ts +2 -0
  34. package/dist/headless/extensions/ImageBlock/index.js +1 -0
  35. package/dist/headless/extensions/Link/Link.d.ts +2 -0
  36. package/dist/headless/extensions/Link/Link.js +44 -0
  37. package/dist/headless/extensions/Link/index.d.ts +1 -0
  38. package/dist/headless/extensions/Link/index.js +1 -0
  39. package/dist/headless/extensions/Markdown.d.ts +9 -0
  40. package/dist/headless/extensions/Markdown.js +138 -0
  41. package/dist/headless/extensions/MarkdownPaste.d.ts +3 -0
  42. package/dist/headless/extensions/MarkdownPaste.js +168 -0
  43. package/dist/headless/extensions/Mention/index.d.ts +4 -0
  44. package/dist/headless/extensions/Mention/index.js +3 -0
  45. package/dist/headless/extensions/Mention/mention-command.d.ts +8 -0
  46. package/dist/headless/extensions/Mention/mention-command.js +165 -0
  47. package/dist/headless/extensions/Mention/mention-list.d.ts +8 -0
  48. package/dist/headless/extensions/Mention/mention-list.js +150 -0
  49. package/dist/headless/extensions/Mention/mention-node-view.d.ts +2 -0
  50. package/dist/headless/extensions/Mention/mention-node-view.js +92 -0
  51. package/dist/headless/extensions/Mention/mention.d.ts +46 -0
  52. package/dist/headless/extensions/Mention/mention.js +218 -0
  53. package/dist/headless/extensions/Table/index.d.ts +2 -0
  54. package/dist/headless/extensions/Table/index.js +2 -0
  55. package/dist/headless/extensions/VideoBlock/VideoBlock.d.ts +17 -0
  56. package/dist/headless/extensions/VideoBlock/VideoBlock.js +73 -0
  57. package/dist/headless/extensions/VideoBlock/index.d.ts +2 -0
  58. package/dist/headless/extensions/VideoBlock/index.js +1 -0
  59. package/dist/headless/extensions/extension-kit.d.ts +29 -0
  60. package/dist/headless/extensions/extension-kit.js +132 -0
  61. package/dist/headless/extensions/index.d.ts +16 -0
  62. package/dist/headless/extensions/index.js +12 -0
  63. package/dist/headless/extensions/slash-command.d.ts +24 -0
  64. package/dist/headless/extensions/slash-command.js +99 -0
  65. package/dist/headless/index.cjs +143 -2
  66. package/dist/headless/index.cjs.map +1 -1
  67. package/dist/headless/index.d.cts +3 -2
  68. package/dist/headless/index.d.ts +3 -2
  69. package/dist/headless/index.js +5 -1
  70. package/dist/headless/utils/atoms.d.ts +13 -0
  71. package/dist/headless/utils/atoms.js +5 -0
  72. package/dist/headless/utils/store.d.ts +2 -0
  73. package/dist/headless/utils/store.js +4 -0
  74. package/dist/highlight.css +77 -1
  75. package/dist/react/Editor.d.ts +43 -0
  76. package/dist/react/Editor.js +119 -0
  77. package/dist/react/TableOfContents.d.ts +7 -0
  78. package/dist/react/TableOfContents.js +96 -0
  79. package/dist/react/index.cjs +156 -9
  80. package/dist/react/index.cjs.map +1 -1
  81. package/dist/react/index.d.cts +5 -2
  82. package/dist/react/index.d.ts +5 -2
  83. package/dist/react/index.js +14 -4
  84. package/dist/react/index.js.map +1 -1
  85. package/dist/react/menus/DragHandle/BlockActionMenu.d.ts +7 -0
  86. package/dist/react/menus/DragHandle/BlockActionMenu.js +111 -0
  87. package/dist/react/menus/DragHandle/DragHandleMenu.d.ts +7 -0
  88. package/dist/react/menus/DragHandle/DragHandleMenu.js +97 -0
  89. package/dist/react/menus/ImageBlock/ImageBlockLoading.d.ts +2 -0
  90. package/dist/react/menus/ImageBlock/ImageBlockLoading.js +6 -0
  91. package/dist/react/menus/ImageBlock/ImageBlockMenu.d.ts +8 -0
  92. package/dist/react/menus/ImageBlock/ImageBlockMenu.js +75 -0
  93. package/dist/react/menus/ImageBlock/ImageBlockView.d.ts +10 -0
  94. package/dist/react/menus/ImageBlock/ImageBlockView.js +60 -0
  95. package/dist/react/menus/ImageBlock/ImageBlockWidth.d.ts +6 -0
  96. package/dist/react/menus/ImageBlock/ImageBlockWidth.js +29 -0
  97. package/dist/react/menus/ImageBlock/ImageResizeHandle.d.ts +8 -0
  98. package/dist/react/menus/ImageBlock/ImageResizeHandle.js +37 -0
  99. package/dist/react/menus/ImageBlock/ImageUploader.d.ts +7 -0
  100. package/dist/react/menus/ImageBlock/ImageUploader.js +73 -0
  101. package/dist/react/menus/ImageBlock/index.d.ts +4 -0
  102. package/dist/react/menus/ImageBlock/index.js +4 -0
  103. package/dist/react/menus/ImageMenu.d.ts +10 -0
  104. package/dist/react/menus/ImageMenu.js +77 -0
  105. package/dist/react/menus/ImagePopover.d.ts +8 -0
  106. package/dist/react/menus/ImagePopover.js +146 -0
  107. package/dist/react/menus/LinkMenu.d.ts +2 -0
  108. package/dist/react/menus/LinkMenu.js +69 -0
  109. package/dist/react/menus/MenuList.d.ts +10 -0
  110. package/dist/react/menus/MenuList.js +94 -0
  111. package/dist/react/menus/SlashMenu.d.ts +5 -0
  112. package/dist/react/menus/SlashMenu.js +156 -0
  113. package/dist/react/menus/TableMenu.d.ts +5 -0
  114. package/dist/react/menus/TableMenu.js +462 -0
  115. package/dist/react/menus/TaskItem/TaskItemView.d.ts +12 -0
  116. package/dist/react/menus/TaskItem/TaskItemView.js +11 -0
  117. package/dist/react/menus/TextMenu.d.ts +10 -0
  118. package/dist/react/menus/TextMenu.js +139 -0
  119. package/dist/react/menus/VideoBlock/VideoBlockMenu.d.ts +7 -0
  120. package/dist/react/menus/VideoBlock/VideoBlockMenu.js +72 -0
  121. package/dist/react/menus/VideoBlock/VideoBlockView.d.ts +10 -0
  122. package/dist/react/menus/VideoBlock/VideoBlockView.js +87 -0
  123. package/dist/react/menus/VideoBlock/index.d.ts +2 -0
  124. package/dist/react/menus/VideoBlock/index.js +2 -0
  125. package/dist/react/menus/index.d.ts +15 -0
  126. package/dist/react/menus/index.js +9 -0
  127. package/package.json +3 -1
  128. package/dist/chunk-2DWEJI45.js +0 -1296
  129. package/dist/chunk-2DWEJI45.js.map +0 -1
  130. package/dist/chunk-3CLWAYRP.js +0 -1387
  131. package/dist/chunk-3CLWAYRP.js.map +0 -1
  132. package/dist/chunk-457ETWB6.js +0 -1351
  133. package/dist/chunk-457ETWB6.js.map +0 -1
  134. package/dist/chunk-4L7FHW5M.js.map +0 -1
  135. package/dist/chunk-4MV3UUZN.js +0 -1073
  136. package/dist/chunk-4MV3UUZN.js.map +0 -1
  137. package/dist/chunk-62DYB7FY.js +0 -1305
  138. package/dist/chunk-62DYB7FY.js.map +0 -1
  139. package/dist/chunk-BVFTQKY7.js.map +0 -1
  140. package/dist/chunk-DWGPGRTQ.js +0 -1302
  141. package/dist/chunk-DWGPGRTQ.js.map +0 -1
  142. package/dist/chunk-EG7NQJRA.js +0 -1324
  143. package/dist/chunk-EG7NQJRA.js.map +0 -1
  144. package/dist/chunk-FLLPFFI5.js +0 -1296
  145. package/dist/chunk-FLLPFFI5.js.map +0 -1
  146. package/dist/chunk-FVQHB6VC.js +0 -1128
  147. package/dist/chunk-FVQHB6VC.js.map +0 -1
  148. package/dist/chunk-G5E32MLB.js +0 -1352
  149. package/dist/chunk-G5E32MLB.js.map +0 -1
  150. package/dist/chunk-GXJGZHKR.js +0 -1326
  151. package/dist/chunk-GXJGZHKR.js.map +0 -1
  152. package/dist/chunk-KCPPTLGY.js +0 -1299
  153. package/dist/chunk-KCPPTLGY.js.map +0 -1
  154. package/dist/chunk-LHG2NX6C.js +0 -1123
  155. package/dist/chunk-LHG2NX6C.js.map +0 -1
  156. package/dist/chunk-MSNTVITF.js +0 -1352
  157. package/dist/chunk-MSNTVITF.js.map +0 -1
  158. package/dist/chunk-N4RDYJ5Z.js +0 -1351
  159. package/dist/chunk-N4RDYJ5Z.js.map +0 -1
  160. package/dist/chunk-OCNM37WJ.js +0 -1289
  161. package/dist/chunk-OCNM37WJ.js.map +0 -1
  162. package/dist/chunk-P3YFYEUB.js +0 -1351
  163. package/dist/chunk-P3YFYEUB.js.map +0 -1
  164. package/dist/chunk-RW6QBMJB.js +0 -1300
  165. package/dist/chunk-RW6QBMJB.js.map +0 -1
  166. package/dist/chunk-SJQQVB3M.js +0 -1353
  167. package/dist/chunk-SJQQVB3M.js.map +0 -1
  168. package/dist/chunk-SOXTEP7H.js +0 -6705
  169. package/dist/chunk-SOXTEP7H.js.map +0 -1
  170. package/dist/chunk-VPI26I4P.js +0 -1350
  171. package/dist/chunk-VPI26I4P.js.map +0 -1
@@ -0,0 +1,153 @@
1
+ import * as _tiptap_core from '@tiptap/core';
2
+ import { Range, Extension } from '@tiptap/core';
3
+ import * as react from 'react';
4
+ import { FC, ReactNode } from 'react';
5
+ import { EditorProviderProps } from '@tiptap/react';
6
+ import * as _tiptap_extension_mention from '@tiptap/extension-mention';
7
+ import { MarkdownSerializer } from '@tiptap/pm/markdown';
8
+
9
+ interface EditorRootProps {
10
+ readonly children: ReactNode;
11
+ }
12
+ declare const EditorRoot: FC<EditorRootProps>;
13
+ type EditorContentProps = EditorProviderProps & {
14
+ readonly children?: ReactNode;
15
+ readonly className?: string;
16
+ readonly initialContent?: any;
17
+ };
18
+ declare const EditorContent: react.ForwardRefExoticComponent<{
19
+ children?: ReactNode;
20
+ slotBefore?: ReactNode;
21
+ slotAfter?: ReactNode;
22
+ editorContainerProps?: react.HTMLAttributes<HTMLDivElement>;
23
+ } & Partial<_tiptap_core.EditorOptions> & {
24
+ immediatelyRender?: boolean;
25
+ shouldRerenderOnTransaction?: boolean;
26
+ } & {
27
+ readonly children?: ReactNode;
28
+ readonly className?: string;
29
+ readonly initialContent?: any;
30
+ } & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ declare module "@tiptap/core" {
33
+ interface Commands<ReturnType> {
34
+ imageBlock: {
35
+ setImageBlock: (attributes: {
36
+ src: string;
37
+ }) => ReturnType;
38
+ setImageBlockAt: (attributes: {
39
+ src: string;
40
+ pos: number | Range;
41
+ }) => ReturnType;
42
+ setImageBlockAlign: (align: "left" | "center" | "right") => ReturnType;
43
+ setImageBlockWidth: (width: number) => ReturnType;
44
+ };
45
+ }
46
+ }
47
+
48
+ /**
49
+ * TipTap AI Suggestion Extension
50
+ *
51
+ * This extension provides inline AI-powered text completions that appear
52
+ * as ghost text at the cursor position.
53
+ *
54
+ * Usage:
55
+ * ```ts
56
+ * import { AISuggestion } from 'neuphlo-editor'
57
+ *
58
+ * const editor = new Editor({
59
+ * extensions: [
60
+ * AISuggestion.configure({
61
+ * onFetchSuggestion: async (context) => {
62
+ * // Call your AI API here
63
+ * const response = await fetch('/api/complete', {
64
+ * method: 'POST',
65
+ * body: JSON.stringify({ text: context }),
66
+ * })
67
+ * const data = await response.json()
68
+ * return data.completion
69
+ * },
70
+ * debounceMs: 2000,
71
+ * }),
72
+ * ],
73
+ * })
74
+ * ```
75
+ */
76
+
77
+ declare module "@tiptap/core" {
78
+ interface Commands<ReturnType> {
79
+ aiSuggestion: {
80
+ /**
81
+ * Accept the current AI suggestion
82
+ */
83
+ acceptAISuggestion: () => ReturnType;
84
+ /**
85
+ * Dismiss the current AI suggestion
86
+ */
87
+ dismissAISuggestion: () => ReturnType;
88
+ /**
89
+ * Manually trigger a suggestion fetch
90
+ */
91
+ triggerAISuggestion: () => ReturnType;
92
+ /**
93
+ * Set a suggestion programmatically
94
+ */
95
+ setAISuggestion: (text: string) => ReturnType;
96
+ };
97
+ }
98
+ }
99
+
100
+ interface MentionItem {
101
+ id: string;
102
+ label: string;
103
+ avatar?: string;
104
+ email?: string;
105
+ type?: "node" | "article";
106
+ nodeId?: string;
107
+ slug?: string;
108
+ }
109
+ interface MentionOptions {
110
+ /**
111
+ * Function to fetch/filter mentionable items based on query
112
+ */
113
+ items?: (query: string) => MentionItem[] | Promise<MentionItem[]>;
114
+ /**
115
+ * Custom render function for mention nodes
116
+ */
117
+ renderLabel?: (props: {
118
+ node: any;
119
+ options: any;
120
+ }) => string;
121
+ /**
122
+ * Character that triggers the mention autocomplete (default: @)
123
+ */
124
+ char?: string;
125
+ /**
126
+ * Custom name for the extension (to avoid duplicates)
127
+ */
128
+ name?: string;
129
+ }
130
+ /**
131
+ * Create the mention extension with custom suggestion rendering
132
+ */
133
+ declare const createMentionExtension: (options?: MentionOptions) => _tiptap_core.Node<_tiptap_extension_mention.MentionOptions<any, _tiptap_extension_mention.MentionNodeAttrs>, any>;
134
+ /**
135
+ * Render function for mention suggestions (autocomplete dropdown)
136
+ */
137
+ declare const renderMentionSuggestion: () => {
138
+ onStart: (props: any) => void;
139
+ onUpdate: (props: any) => void;
140
+ onKeyDown: ({ event }: {
141
+ event: KeyboardEvent;
142
+ }) => any;
143
+ onExit: () => void;
144
+ };
145
+
146
+ declare function markdownToHtml(input: string | null | undefined): string;
147
+ interface MarkdownStorage {
148
+ serializer: MarkdownSerializer | null;
149
+ getMarkdown: () => string;
150
+ }
151
+ declare const Markdown: Extension<any, MarkdownStorage>;
152
+
153
+ export { EditorRoot as E, type MentionItem as M, EditorContent as a, type EditorContentProps as b, Markdown as c, type MarkdownStorage as d, createMentionExtension as e, type MentionOptions as f, markdownToHtml as m, renderMentionSuggestion as r };
@@ -0,0 +1,153 @@
1
+ import * as _tiptap_core from '@tiptap/core';
2
+ import { Range, Extension } from '@tiptap/core';
3
+ import * as react from 'react';
4
+ import { FC, ReactNode } from 'react';
5
+ import { EditorProviderProps } from '@tiptap/react';
6
+ import * as _tiptap_extension_mention from '@tiptap/extension-mention';
7
+ import { MarkdownSerializer } from '@tiptap/pm/markdown';
8
+
9
+ interface EditorRootProps {
10
+ readonly children: ReactNode;
11
+ }
12
+ declare const EditorRoot: FC<EditorRootProps>;
13
+ type EditorContentProps = EditorProviderProps & {
14
+ readonly children?: ReactNode;
15
+ readonly className?: string;
16
+ readonly initialContent?: any;
17
+ };
18
+ declare const EditorContent: react.ForwardRefExoticComponent<{
19
+ children?: ReactNode;
20
+ slotBefore?: ReactNode;
21
+ slotAfter?: ReactNode;
22
+ editorContainerProps?: react.HTMLAttributes<HTMLDivElement>;
23
+ } & Partial<_tiptap_core.EditorOptions> & {
24
+ immediatelyRender?: boolean;
25
+ shouldRerenderOnTransaction?: boolean;
26
+ } & {
27
+ readonly children?: ReactNode;
28
+ readonly className?: string;
29
+ readonly initialContent?: any;
30
+ } & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ declare module "@tiptap/core" {
33
+ interface Commands<ReturnType> {
34
+ imageBlock: {
35
+ setImageBlock: (attributes: {
36
+ src: string;
37
+ }) => ReturnType;
38
+ setImageBlockAt: (attributes: {
39
+ src: string;
40
+ pos: number | Range;
41
+ }) => ReturnType;
42
+ setImageBlockAlign: (align: "left" | "center" | "right") => ReturnType;
43
+ setImageBlockWidth: (width: number) => ReturnType;
44
+ };
45
+ }
46
+ }
47
+
48
+ /**
49
+ * TipTap AI Suggestion Extension
50
+ *
51
+ * This extension provides inline AI-powered text completions that appear
52
+ * as ghost text at the cursor position.
53
+ *
54
+ * Usage:
55
+ * ```ts
56
+ * import { AISuggestion } from 'neuphlo-editor'
57
+ *
58
+ * const editor = new Editor({
59
+ * extensions: [
60
+ * AISuggestion.configure({
61
+ * onFetchSuggestion: async (context) => {
62
+ * // Call your AI API here
63
+ * const response = await fetch('/api/complete', {
64
+ * method: 'POST',
65
+ * body: JSON.stringify({ text: context }),
66
+ * })
67
+ * const data = await response.json()
68
+ * return data.completion
69
+ * },
70
+ * debounceMs: 2000,
71
+ * }),
72
+ * ],
73
+ * })
74
+ * ```
75
+ */
76
+
77
+ declare module "@tiptap/core" {
78
+ interface Commands<ReturnType> {
79
+ aiSuggestion: {
80
+ /**
81
+ * Accept the current AI suggestion
82
+ */
83
+ acceptAISuggestion: () => ReturnType;
84
+ /**
85
+ * Dismiss the current AI suggestion
86
+ */
87
+ dismissAISuggestion: () => ReturnType;
88
+ /**
89
+ * Manually trigger a suggestion fetch
90
+ */
91
+ triggerAISuggestion: () => ReturnType;
92
+ /**
93
+ * Set a suggestion programmatically
94
+ */
95
+ setAISuggestion: (text: string) => ReturnType;
96
+ };
97
+ }
98
+ }
99
+
100
+ interface MentionItem {
101
+ id: string;
102
+ label: string;
103
+ avatar?: string;
104
+ email?: string;
105
+ type?: "node" | "article";
106
+ nodeId?: string;
107
+ slug?: string;
108
+ }
109
+ interface MentionOptions {
110
+ /**
111
+ * Function to fetch/filter mentionable items based on query
112
+ */
113
+ items?: (query: string) => MentionItem[] | Promise<MentionItem[]>;
114
+ /**
115
+ * Custom render function for mention nodes
116
+ */
117
+ renderLabel?: (props: {
118
+ node: any;
119
+ options: any;
120
+ }) => string;
121
+ /**
122
+ * Character that triggers the mention autocomplete (default: @)
123
+ */
124
+ char?: string;
125
+ /**
126
+ * Custom name for the extension (to avoid duplicates)
127
+ */
128
+ name?: string;
129
+ }
130
+ /**
131
+ * Create the mention extension with custom suggestion rendering
132
+ */
133
+ declare const createMentionExtension: (options?: MentionOptions) => _tiptap_core.Node<_tiptap_extension_mention.MentionOptions<any, _tiptap_extension_mention.MentionNodeAttrs>, any>;
134
+ /**
135
+ * Render function for mention suggestions (autocomplete dropdown)
136
+ */
137
+ declare const renderMentionSuggestion: () => {
138
+ onStart: (props: any) => void;
139
+ onUpdate: (props: any) => void;
140
+ onKeyDown: ({ event }: {
141
+ event: KeyboardEvent;
142
+ }) => any;
143
+ onExit: () => void;
144
+ };
145
+
146
+ declare function markdownToHtml(input: string | null | undefined): string;
147
+ interface MarkdownStorage {
148
+ serializer: MarkdownSerializer | null;
149
+ getMarkdown: () => string;
150
+ }
151
+ declare const Markdown: Extension<any, MarkdownStorage>;
152
+
153
+ export { EditorRoot as E, type MentionItem as M, EditorContent as a, type EditorContentProps as b, Markdown as c, type MarkdownStorage as d, createMentionExtension as e, type MentionOptions as f, markdownToHtml as m, renderMentionSuggestion as r };
@@ -570,7 +570,36 @@ import Mention from "@tiptap/extension-mention";
570
570
  // src/headless/extensions/Mention/mention-command.tsx
571
571
  import { forwardRef as forwardRef5, useEffect as useEffect2, useImperativeHandle, useState as useState2 } from "react";
572
572
  import { jsx as jsx6, jsxs } from "react/jsx-runtime";
573
- function Avatar({ src, fallback }) {
573
+ var GRADIENT_MAP = {
574
+ red: "linear-gradient(135deg, #ef4444, #fb7185)",
575
+ coral: "linear-gradient(135deg, #f87171, #fb923c)",
576
+ orange: "linear-gradient(135deg, #f97316, #fbbf24)",
577
+ amber: "linear-gradient(135deg, #f59e0b, #facc15)",
578
+ lime: "linear-gradient(135deg, #84cc16, #4ade80)",
579
+ green: "linear-gradient(135deg, #10b981, #2dd4bf)",
580
+ teal: "linear-gradient(135deg, #14b8a6, #22d3ee)",
581
+ cyan: "linear-gradient(135deg, #06b6d4, #60a5fa)",
582
+ blue: "linear-gradient(135deg, #3b82f6, #818cf8)",
583
+ indigo: "linear-gradient(135deg, #6366f1, #a78bfa)",
584
+ violet: "linear-gradient(135deg, #8b5cf6, #a855f7)",
585
+ purple: "linear-gradient(135deg, #a855f7, #d946ef)",
586
+ fuchsia: "linear-gradient(135deg, #d946ef, #f472b6)",
587
+ pink: "linear-gradient(135deg, #ec4899, #fb7185)",
588
+ slate: "linear-gradient(135deg, #64748b, #71717a)",
589
+ stone: "linear-gradient(135deg, #78716c, #a3a3a3)"
590
+ };
591
+ function isGradientKey(avatar) {
592
+ return !!avatar && avatar in GRADIENT_MAP;
593
+ }
594
+ function isAgentItem(item) {
595
+ return !!item.email?.endsWith("@ai.neuphlo.local");
596
+ }
597
+ function getInitials(name) {
598
+ if (!name) return "AG";
599
+ return name.split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase();
600
+ }
601
+ function Avatar({ src, fallback, isAgent }) {
602
+ const gradient = src && isGradientKey(src) ? GRADIENT_MAP[src] : isAgent ? GRADIENT_MAP.violet : null;
574
603
  return /* @__PURE__ */ jsx6("div", { style: {
575
604
  position: "relative",
576
605
  display: "flex",
@@ -579,7 +608,18 @@ function Avatar({ src, fallback }) {
579
608
  flexShrink: 0,
580
609
  overflow: "hidden",
581
610
  borderRadius: "9999px"
582
- }, children: src ? /* @__PURE__ */ jsx6(
611
+ }, children: gradient ? /* @__PURE__ */ jsx6("div", { style: {
612
+ display: "flex",
613
+ height: "100%",
614
+ width: "100%",
615
+ alignItems: "center",
616
+ justifyContent: "center",
617
+ borderRadius: "9999px",
618
+ background: gradient,
619
+ color: "#ffffff",
620
+ fontSize: "10px",
621
+ fontWeight: 600
622
+ }, children: fallback }) : src ? /* @__PURE__ */ jsx6(
583
623
  "img",
584
624
  {
585
625
  style: {
@@ -671,47 +711,62 @@ var MentionCommand = forwardRef5((props, ref) => {
671
711
  padding: "4px",
672
712
  boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
673
713
  },
674
- children: props.items.length ? props.items.map((item, index) => /* @__PURE__ */ jsxs(
675
- "button",
676
- {
677
- type: "button",
678
- onClick: () => selectItem(index),
679
- onMouseEnter: () => setSelectedIndex(index),
680
- style: {
681
- position: "relative",
682
- display: "flex",
683
- width: "100%",
684
- cursor: "default",
685
- userSelect: "none",
686
- alignItems: "center",
687
- gap: "8px",
688
- borderRadius: "4px",
689
- padding: "10px 8px",
690
- fontSize: "14px",
691
- outline: "none",
692
- backgroundColor: index === selectedIndex ? "var(--accent)" : "transparent",
693
- color: index === selectedIndex ? "var(--accent-foreground)" : "inherit",
694
- border: "none",
695
- textAlign: "left"
696
- },
697
- children: [
698
- item.type ? /* @__PURE__ */ jsx6(ReferenceIcon, { type: item.type }) : /* @__PURE__ */ jsx6(
699
- Avatar,
714
+ children: props.items.length ? (() => {
715
+ const agents = props.items.filter((i) => !i.type && isAgentItem(i));
716
+ const others = props.items.filter((i) => i.type || !isAgentItem(i));
717
+ const sections = [];
718
+ if (agents.length) sections.push({ label: "Agents", items: agents, startIndex: 0 });
719
+ if (others.length) sections.push({ label: agents.length ? "Members" : null, items: others, startIndex: agents.length });
720
+ return sections.map((section) => /* @__PURE__ */ jsxs("div", { children: [
721
+ section.label && /* @__PURE__ */ jsx6("div", { style: { padding: "6px 8px 2px", fontSize: "11px", fontWeight: 600, color: "var(--muted-foreground)", textTransform: "uppercase", letterSpacing: "0.05em" }, children: section.label }),
722
+ section.items.map((item, i) => {
723
+ const index = section.startIndex + i;
724
+ const agent = isAgentItem(item);
725
+ return /* @__PURE__ */ jsxs(
726
+ "button",
700
727
  {
701
- src: item.avatar,
702
- fallback: item.label.slice(0, 2).toUpperCase()
703
- }
704
- ),
705
- /* @__PURE__ */ jsx6("span", { style: {
706
- flex: 1,
707
- overflow: "hidden",
708
- textOverflow: "ellipsis",
709
- whiteSpace: "nowrap"
710
- }, children: item.label })
711
- ]
712
- },
713
- item.id
714
- )) : /* @__PURE__ */ jsx6("div", { style: {
728
+ type: "button",
729
+ onClick: () => selectItem(index),
730
+ onMouseEnter: () => setSelectedIndex(index),
731
+ style: {
732
+ position: "relative",
733
+ display: "flex",
734
+ width: "100%",
735
+ cursor: "default",
736
+ userSelect: "none",
737
+ alignItems: "center",
738
+ gap: "8px",
739
+ borderRadius: "4px",
740
+ padding: "10px 8px",
741
+ fontSize: "14px",
742
+ outline: "none",
743
+ backgroundColor: index === selectedIndex ? "var(--accent)" : "transparent",
744
+ color: index === selectedIndex ? "var(--accent-foreground)" : "inherit",
745
+ border: "none",
746
+ textAlign: "left"
747
+ },
748
+ children: [
749
+ item.type ? /* @__PURE__ */ jsx6(ReferenceIcon, { type: item.type }) : /* @__PURE__ */ jsx6(
750
+ Avatar,
751
+ {
752
+ src: item.avatar,
753
+ fallback: getInitials(item.label),
754
+ isAgent: agent
755
+ }
756
+ ),
757
+ /* @__PURE__ */ jsx6("span", { style: {
758
+ flex: 1,
759
+ overflow: "hidden",
760
+ textOverflow: "ellipsis",
761
+ whiteSpace: "nowrap"
762
+ }, children: item.label })
763
+ ]
764
+ },
765
+ item.id
766
+ );
767
+ })
768
+ ] }, section.label ?? "default"));
769
+ })() : /* @__PURE__ */ jsx6("div", { style: {
715
770
  padding: "24px 0",
716
771
  textAlign: "center",
717
772
  fontSize: "14px",
@@ -725,7 +780,7 @@ MentionCommand.displayName = "MentionCommand";
725
780
  // src/headless/extensions/Mention/mention-node-view.tsx
726
781
  import { NodeViewWrapper } from "@tiptap/react";
727
782
  import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
728
- var GRADIENT_MAP = {
783
+ var GRADIENT_MAP2 = {
729
784
  red: "linear-gradient(135deg, #ef4444, #fb7185)",
730
785
  coral: "linear-gradient(135deg, #f87171, #fb923c)",
731
786
  orange: "linear-gradient(135deg, #f97316, #fbbf24)",
@@ -789,14 +844,14 @@ var MentionNodeView = (props) => {
789
844
  children: [
790
845
  isNode && /* @__PURE__ */ jsx7(NodeIcon, {}),
791
846
  isArticle && /* @__PURE__ */ jsx7(ArticleIcon, {}),
792
- !isReference && avatar && avatar in GRADIENT_MAP && /* @__PURE__ */ jsx7(
847
+ !isReference && avatar && avatar in GRADIENT_MAP2 && /* @__PURE__ */ jsx7(
793
848
  "div",
794
849
  {
795
850
  style: {
796
851
  width: "20px",
797
852
  height: "20px",
798
853
  borderRadius: "50%",
799
- background: GRADIENT_MAP[avatar],
854
+ background: GRADIENT_MAP2[avatar],
800
855
  color: "#ffffff",
801
856
  display: "flex",
802
857
  alignItems: "center",
@@ -808,7 +863,7 @@ var MentionNodeView = (props) => {
808
863
  children: (label || id).split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase()
809
864
  }
810
865
  ),
811
- !isReference && avatar && !(avatar in GRADIENT_MAP) && /* @__PURE__ */ jsx7(
866
+ !isReference && avatar && !(avatar in GRADIENT_MAP2) && /* @__PURE__ */ jsx7(
812
867
  "img",
813
868
  {
814
869
  src: avatar,
@@ -851,6 +906,17 @@ var createMentionExtension = (options) => {
851
906
  const extensionName = options?.name ?? "mention";
852
907
  return Mention.extend({
853
908
  name: extensionName,
909
+ addStorage() {
910
+ return {
911
+ markdown: {
912
+ serialize(state, node) {
913
+ const label = String(node.attrs.label ?? node.attrs.id ?? "");
914
+ const id = String(node.attrs.id ?? "");
915
+ state.write(`@[${label}](mention:${id})`);
916
+ }
917
+ }
918
+ };
919
+ },
854
920
  addAttributes() {
855
921
  return {
856
922
  id: {
@@ -1385,4 +1451,4 @@ export {
1385
1451
  handleCommandNavigation,
1386
1452
  useCurrentEditor4 as useCurrentEditor
1387
1453
  };
1388
- //# sourceMappingURL=chunk-4L7FHW5M.js.map
1454
+ //# sourceMappingURL=chunk-ABL4D65Z.js.map