neuphlo-editor 2.5.1 → 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 (128) 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-ABL4D65Z.js +1454 -0
  4. package/dist/chunk-ABL4D65Z.js.map +1 -0
  5. package/dist/chunk-Z2DR2FK3.js +1582 -0
  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 +0 -6
  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 +13 -9
  128. package/LICENSE +0 -21
@@ -0,0 +1,165 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
3
+ const GRADIENT_MAP = {
4
+ red: "linear-gradient(135deg, #ef4444, #fb7185)",
5
+ coral: "linear-gradient(135deg, #f87171, #fb923c)",
6
+ orange: "linear-gradient(135deg, #f97316, #fbbf24)",
7
+ amber: "linear-gradient(135deg, #f59e0b, #facc15)",
8
+ lime: "linear-gradient(135deg, #84cc16, #4ade80)",
9
+ green: "linear-gradient(135deg, #10b981, #2dd4bf)",
10
+ teal: "linear-gradient(135deg, #14b8a6, #22d3ee)",
11
+ cyan: "linear-gradient(135deg, #06b6d4, #60a5fa)",
12
+ blue: "linear-gradient(135deg, #3b82f6, #818cf8)",
13
+ indigo: "linear-gradient(135deg, #6366f1, #a78bfa)",
14
+ violet: "linear-gradient(135deg, #8b5cf6, #a855f7)",
15
+ purple: "linear-gradient(135deg, #a855f7, #d946ef)",
16
+ fuchsia: "linear-gradient(135deg, #d946ef, #f472b6)",
17
+ pink: "linear-gradient(135deg, #ec4899, #fb7185)",
18
+ slate: "linear-gradient(135deg, #64748b, #71717a)",
19
+ stone: "linear-gradient(135deg, #78716c, #a3a3a3)",
20
+ };
21
+ function isGradientKey(avatar) {
22
+ return !!avatar && avatar in GRADIENT_MAP;
23
+ }
24
+ function isAgentItem(item) {
25
+ return !!item.email?.endsWith("@ai.neuphlo.local");
26
+ }
27
+ function getInitials(name) {
28
+ if (!name)
29
+ return "AG";
30
+ return name.split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase();
31
+ }
32
+ // Simple Avatar component with inline styles
33
+ function Avatar({ src, fallback, isAgent }) {
34
+ const gradient = src && isGradientKey(src) ? GRADIENT_MAP[src] : isAgent ? GRADIENT_MAP.violet : null;
35
+ return (_jsx("div", { style: {
36
+ position: "relative",
37
+ display: "flex",
38
+ height: "24px",
39
+ width: "24px",
40
+ flexShrink: 0,
41
+ overflow: "hidden",
42
+ borderRadius: "9999px",
43
+ }, children: gradient ? (_jsx("div", { style: {
44
+ display: "flex",
45
+ height: "100%",
46
+ width: "100%",
47
+ alignItems: "center",
48
+ justifyContent: "center",
49
+ borderRadius: "9999px",
50
+ background: gradient,
51
+ color: "#ffffff",
52
+ fontSize: "10px",
53
+ fontWeight: 600,
54
+ }, children: fallback })) : src ? (_jsx("img", { style: {
55
+ aspectRatio: "1",
56
+ height: "100%",
57
+ width: "100%",
58
+ }, src: src, alt: fallback })) : (_jsx("div", { style: {
59
+ display: "flex",
60
+ height: "100%",
61
+ width: "100%",
62
+ alignItems: "center",
63
+ justifyContent: "center",
64
+ borderRadius: "9999px",
65
+ backgroundColor: "var(--muted)",
66
+ color: "var(--muted-foreground)",
67
+ fontSize: "10px",
68
+ fontWeight: 600,
69
+ }, children: fallback })) }));
70
+ }
71
+ // Icon component for reference types
72
+ function ReferenceIcon({ type }) {
73
+ if (type === "node") {
74
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { flexShrink: 0 }, children: [_jsx("path", { d: "M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5" }), _jsx("path", { d: "M12 12l8-4.5" }), _jsx("path", { d: "M12 12v9" }), _jsx("path", { d: "M12 12l-8-4.5" })] }));
75
+ }
76
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { flexShrink: 0 }, children: [_jsx("path", { d: "M14 3v4a1 1 0 0 0 1 1h4" }), _jsx("path", { d: "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" }), _jsx("path", { d: "M9 9l1 0" }), _jsx("path", { d: "M9 13l6 0" }), _jsx("path", { d: "M9 17l6 0" })] }));
77
+ }
78
+ export const MentionCommand = forwardRef((props, ref) => {
79
+ const [selectedIndex, setSelectedIndex] = useState(0);
80
+ const selectItem = (index) => {
81
+ const item = props.items[index];
82
+ if (item) {
83
+ props.command(item);
84
+ }
85
+ };
86
+ const upHandler = () => {
87
+ setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length);
88
+ };
89
+ const downHandler = () => {
90
+ setSelectedIndex((selectedIndex + 1) % props.items.length);
91
+ };
92
+ const enterHandler = () => {
93
+ selectItem(selectedIndex);
94
+ };
95
+ useEffect(() => setSelectedIndex(0), [props.items]);
96
+ useImperativeHandle(ref, () => ({
97
+ onKeyDown: ({ event }) => {
98
+ if (event.key === "ArrowUp") {
99
+ upHandler();
100
+ return true;
101
+ }
102
+ if (event.key === "ArrowDown") {
103
+ downHandler();
104
+ return true;
105
+ }
106
+ if (event.key === "Enter") {
107
+ enterHandler();
108
+ return true;
109
+ }
110
+ return false;
111
+ },
112
+ }));
113
+ return (_jsx("div", { id: "mention-list", style: {
114
+ backgroundColor: "var(--popover)",
115
+ color: "var(--foreground)",
116
+ maxHeight: "300px",
117
+ minWidth: "280px",
118
+ overflow: "hidden",
119
+ overflowY: "auto",
120
+ borderRadius: "12px",
121
+ border: "1px solid var(--border)",
122
+ padding: "4px",
123
+ boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
124
+ }, children: props.items.length ? ((() => {
125
+ const agents = props.items.filter(i => !i.type && isAgentItem(i));
126
+ const others = props.items.filter(i => i.type || !isAgentItem(i));
127
+ const sections = [];
128
+ if (agents.length)
129
+ sections.push({ label: "Agents", items: agents, startIndex: 0 });
130
+ if (others.length)
131
+ sections.push({ label: agents.length ? "Members" : null, items: others, startIndex: agents.length });
132
+ return sections.map((section) => (_jsxs("div", { children: [section.label && (_jsx("div", { style: { padding: "6px 8px 2px", fontSize: "11px", fontWeight: 600, color: "var(--muted-foreground)", textTransform: "uppercase", letterSpacing: "0.05em" }, children: section.label })), section.items.map((item, i) => {
133
+ const index = section.startIndex + i;
134
+ const agent = isAgentItem(item);
135
+ return (_jsxs("button", { type: "button", onClick: () => selectItem(index), onMouseEnter: () => setSelectedIndex(index), style: {
136
+ position: "relative",
137
+ display: "flex",
138
+ width: "100%",
139
+ cursor: "default",
140
+ userSelect: "none",
141
+ alignItems: "center",
142
+ gap: "8px",
143
+ borderRadius: "4px",
144
+ padding: "10px 8px",
145
+ fontSize: "14px",
146
+ outline: "none",
147
+ backgroundColor: index === selectedIndex ? "var(--accent)" : "transparent",
148
+ color: index === selectedIndex ? "var(--accent-foreground)" : "inherit",
149
+ border: "none",
150
+ textAlign: "left",
151
+ }, children: [item.type ? (_jsx(ReferenceIcon, { type: item.type })) : (_jsx(Avatar, { src: item.avatar, fallback: getInitials(item.label), isAgent: agent })), _jsx("span", { style: {
152
+ flex: 1,
153
+ overflow: "hidden",
154
+ textOverflow: "ellipsis",
155
+ whiteSpace: "nowrap",
156
+ }, children: item.label })] }, item.id));
157
+ })] }, section.label ?? "default")));
158
+ })()) : (_jsx("div", { style: {
159
+ padding: "24px 0",
160
+ textAlign: "center",
161
+ fontSize: "14px",
162
+ color: "var(--muted-foreground)",
163
+ }, children: "No results found" })) }));
164
+ });
165
+ MentionCommand.displayName = "MentionCommand";
@@ -0,0 +1,8 @@
1
+ import type { MentionItem } from "./mention";
2
+ interface MentionListProps {
3
+ items: MentionItem[];
4
+ command: (item: MentionItem) => void;
5
+ query: string;
6
+ }
7
+ export declare const MentionList: import("react").ForwardRefExoticComponent<MentionListProps & import("react").RefAttributes<any>>;
8
+ export {};
@@ -0,0 +1,150 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
3
+ // Gradient map for agent avatars (avatar field stores a gradient key like "violet")
4
+ const GRADIENT_MAP = {
5
+ red: "linear-gradient(135deg, #ef4444, #fb7185)",
6
+ coral: "linear-gradient(135deg, #f87171, #fb923c)",
7
+ orange: "linear-gradient(135deg, #f97316, #fbbf24)",
8
+ amber: "linear-gradient(135deg, #f59e0b, #facc15)",
9
+ lime: "linear-gradient(135deg, #84cc16, #4ade80)",
10
+ green: "linear-gradient(135deg, #10b981, #2dd4bf)",
11
+ teal: "linear-gradient(135deg, #14b8a6, #22d3ee)",
12
+ cyan: "linear-gradient(135deg, #06b6d4, #60a5fa)",
13
+ blue: "linear-gradient(135deg, #3b82f6, #818cf8)",
14
+ indigo: "linear-gradient(135deg, #6366f1, #a78bfa)",
15
+ violet: "linear-gradient(135deg, #8b5cf6, #a855f7)",
16
+ purple: "linear-gradient(135deg, #a855f7, #d946ef)",
17
+ fuchsia: "linear-gradient(135deg, #d946ef, #f472b6)",
18
+ pink: "linear-gradient(135deg, #ec4899, #fb7185)",
19
+ slate: "linear-gradient(135deg, #64748b, #71717a)",
20
+ stone: "linear-gradient(135deg, #78716c, #a3a3a3)",
21
+ };
22
+ function isAgent(item) {
23
+ return !!item.email?.endsWith("@ai.neuphlo.local");
24
+ }
25
+ function isGradientKey(avatar) {
26
+ return !!avatar && avatar in GRADIENT_MAP;
27
+ }
28
+ function getAgentGradient(item) {
29
+ return GRADIENT_MAP[item.avatar || "violet"] || GRADIENT_MAP.violet;
30
+ }
31
+ function getInitials(name) {
32
+ if (!name)
33
+ return "AG";
34
+ return name.split(/\s+/).map(w => w[0]).join("").slice(0, 2).toUpperCase();
35
+ }
36
+ export const MentionList = forwardRef((props, ref) => {
37
+ const [selectedIndex, setSelectedIndex] = useState(0);
38
+ const selectItem = (index) => {
39
+ const item = props.items[index];
40
+ if (item) {
41
+ props.command(item);
42
+ }
43
+ };
44
+ const upHandler = () => {
45
+ setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length);
46
+ };
47
+ const downHandler = () => {
48
+ setSelectedIndex((selectedIndex + 1) % props.items.length);
49
+ };
50
+ const enterHandler = () => {
51
+ selectItem(selectedIndex);
52
+ };
53
+ useEffect(() => setSelectedIndex(0), [props.items]);
54
+ useImperativeHandle(ref, () => ({
55
+ onKeyDown: ({ event }) => {
56
+ if (event.key === "ArrowUp") {
57
+ upHandler();
58
+ return true;
59
+ }
60
+ if (event.key === "ArrowDown") {
61
+ downHandler();
62
+ return true;
63
+ }
64
+ if (event.key === "Enter") {
65
+ enterHandler();
66
+ return true;
67
+ }
68
+ return false;
69
+ },
70
+ }));
71
+ return (_jsx("div", { id: "mention-list", className: "nph-mention-list", style: {
72
+ background: "white",
73
+ border: "1px solid #e2e8f0",
74
+ borderRadius: "8px",
75
+ boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
76
+ maxHeight: "320px",
77
+ overflowY: "auto",
78
+ padding: "4px",
79
+ }, children: props.items.length ? ((() => {
80
+ const agents = props.items.filter(i => isAgent(i));
81
+ const members = props.items.filter(i => !isAgent(i));
82
+ const sections = [];
83
+ if (agents.length)
84
+ sections.push({ label: "Agents", items: agents, startIndex: 0 });
85
+ if (members.length)
86
+ sections.push({ label: "Members", items: members, startIndex: agents.length });
87
+ return sections.map((section) => (_jsxs("div", { children: [_jsx("div", { style: { padding: "6px 8px 4px", fontSize: "11px", fontWeight: "600", color: "#94a3b8", textTransform: "uppercase", letterSpacing: "0.05em" }, children: section.label }), section.items.map((item, i) => {
88
+ const index = section.startIndex + i;
89
+ return (_jsxs("button", { type: "button", onClick: () => selectItem(index), className: "nph-mention-item", style: {
90
+ display: "flex",
91
+ alignItems: "center",
92
+ gap: "8px",
93
+ width: "100%",
94
+ padding: "8px",
95
+ border: "none",
96
+ borderRadius: "6px",
97
+ background: index === selectedIndex ? "#f1f5f9" : "transparent",
98
+ cursor: "pointer",
99
+ textAlign: "left",
100
+ transition: "background 0.15s",
101
+ }, onMouseEnter: () => setSelectedIndex(index), children: [(isGradientKey(item.avatar) || isAgent(item)) ? (_jsx("div", { style: {
102
+ width: "24px",
103
+ height: "24px",
104
+ borderRadius: "50%",
105
+ background: getAgentGradient(item),
106
+ display: "flex",
107
+ alignItems: "center",
108
+ justifyContent: "center",
109
+ fontSize: "10px",
110
+ fontWeight: "600",
111
+ color: "#ffffff",
112
+ }, children: getInitials(item.label) })) : item.avatar ? (_jsx("img", { src: item.avatar, alt: item.label, style: {
113
+ width: "24px",
114
+ height: "24px",
115
+ borderRadius: "50%",
116
+ objectFit: "cover",
117
+ } })) : (_jsx("div", { style: {
118
+ width: "24px",
119
+ height: "24px",
120
+ borderRadius: "50%",
121
+ background: "#e2e8f0",
122
+ display: "flex",
123
+ alignItems: "center",
124
+ justifyContent: "center",
125
+ fontSize: "10px",
126
+ fontWeight: "600",
127
+ color: "#64748b",
128
+ }, children: item.label.slice(0, 2).toUpperCase() })), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("div", { style: {
129
+ fontSize: "14px",
130
+ fontWeight: "500",
131
+ color: "#0f172a",
132
+ overflow: "hidden",
133
+ textOverflow: "ellipsis",
134
+ whiteSpace: "nowrap",
135
+ }, children: item.label }), item.email && !isAgent(item) && (_jsx("div", { style: {
136
+ fontSize: "12px",
137
+ color: "#64748b",
138
+ overflow: "hidden",
139
+ textOverflow: "ellipsis",
140
+ whiteSpace: "nowrap",
141
+ }, children: item.email }))] })] }, item.id));
142
+ })] }, section.label)));
143
+ })()) : (_jsx("div", { style: {
144
+ padding: "12px",
145
+ fontSize: "14px",
146
+ color: "#64748b",
147
+ textAlign: "center",
148
+ }, children: "No results found" })) }));
149
+ });
150
+ MentionList.displayName = "MentionList";
@@ -0,0 +1,2 @@
1
+ import type { NodeViewProps } from "@tiptap/react";
2
+ export declare const MentionNodeView: (props: NodeViewProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,92 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { NodeViewWrapper } from "@tiptap/react";
3
+ const GRADIENT_MAP = {
4
+ red: "linear-gradient(135deg, #ef4444, #fb7185)",
5
+ coral: "linear-gradient(135deg, #f87171, #fb923c)",
6
+ orange: "linear-gradient(135deg, #f97316, #fbbf24)",
7
+ amber: "linear-gradient(135deg, #f59e0b, #facc15)",
8
+ lime: "linear-gradient(135deg, #84cc16, #4ade80)",
9
+ green: "linear-gradient(135deg, #10b981, #2dd4bf)",
10
+ teal: "linear-gradient(135deg, #14b8a6, #22d3ee)",
11
+ cyan: "linear-gradient(135deg, #06b6d4, #60a5fa)",
12
+ blue: "linear-gradient(135deg, #3b82f6, #818cf8)",
13
+ indigo: "linear-gradient(135deg, #6366f1, #a78bfa)",
14
+ violet: "linear-gradient(135deg, #8b5cf6, #a855f7)",
15
+ purple: "linear-gradient(135deg, #a855f7, #d946ef)",
16
+ fuchsia: "linear-gradient(135deg, #d946ef, #f472b6)",
17
+ pink: "linear-gradient(135deg, #ec4899, #fb7185)",
18
+ slate: "linear-gradient(135deg, #64748b, #71717a)",
19
+ stone: "linear-gradient(135deg, #78716c, #a3a3a3)",
20
+ };
21
+ // Icon components
22
+ function NodeIcon() {
23
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { flexShrink: 0 }, children: [_jsx("path", { d: "M12 3l8 4.5v9l-8 4.5l-8-4.5v-9l8-4.5" }), _jsx("path", { d: "M12 12l8-4.5" }), _jsx("path", { d: "M12 12v9" }), _jsx("path", { d: "M12 12l-8-4.5" })] }));
24
+ }
25
+ function ArticleIcon() {
26
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { flexShrink: 0 }, children: [_jsx("path", { d: "M14 3v4a1 1 0 0 0 1 1h4" }), _jsx("path", { d: "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" }), _jsx("path", { d: "M9 9l1 0" }), _jsx("path", { d: "M9 13l6 0" }), _jsx("path", { d: "M9 17l6 0" })] }));
27
+ }
28
+ export const MentionNodeView = (props) => {
29
+ const { node } = props;
30
+ const { id, label, avatar, type } = node.attrs;
31
+ // Determine styling based on type
32
+ const isNode = type === "node";
33
+ const isArticle = type === "article";
34
+ const isReference = isNode || isArticle;
35
+ const backgroundColor = isArticle
36
+ ? "rgba(249, 115, 22, 0.15)" // Orange for articles
37
+ : isNode
38
+ ? "rgba(107, 114, 128, 0.15)" // Gray for nodes
39
+ : "var(--accent)"; // Default for user mentions
40
+ const color = isArticle
41
+ ? "rgb(234, 88, 12)" // Orange text
42
+ : isNode
43
+ ? "rgb(75, 85, 99)" // Gray text
44
+ : "var(--accent-foreground)"; // Default
45
+ const border = isArticle
46
+ ? "1px solid rgba(249, 115, 22, 0.3)"
47
+ : isNode
48
+ ? "1px solid rgba(107, 114, 128, 0.3)"
49
+ : "none";
50
+ return (_jsxs(NodeViewWrapper, { as: "span", style: {
51
+ display: "inline-flex",
52
+ alignItems: "center",
53
+ gap: "3px",
54
+ backgroundColor,
55
+ color,
56
+ border,
57
+ padding: isReference ? "1px 6px" : "1px 6px 1px 1px",
58
+ borderRadius: "12px",
59
+ fontSize: "13px",
60
+ fontWeight: 500,
61
+ verticalAlign: "middle",
62
+ }, children: [isNode && _jsx(NodeIcon, {}), isArticle && _jsx(ArticleIcon, {}), !isReference && avatar && avatar in GRADIENT_MAP && (_jsx("div", { style: {
63
+ width: "20px",
64
+ height: "20px",
65
+ borderRadius: "50%",
66
+ background: GRADIENT_MAP[avatar],
67
+ color: "#ffffff",
68
+ display: "flex",
69
+ alignItems: "center",
70
+ justifyContent: "center",
71
+ fontSize: "8px",
72
+ fontWeight: 600,
73
+ flexShrink: 0,
74
+ }, children: (label || id).split(/\s+/).map((w) => w[0]).join("").slice(0, 2).toUpperCase() })), !isReference && avatar && !(avatar in GRADIENT_MAP) && (_jsx("img", { src: avatar, alt: label || id, style: {
75
+ width: "20px",
76
+ height: "20px",
77
+ borderRadius: "50%",
78
+ flexShrink: 0,
79
+ } })), !isReference && !avatar && (_jsx("div", { style: {
80
+ width: "20px",
81
+ height: "20px",
82
+ borderRadius: "50%",
83
+ backgroundColor: "var(--muted)",
84
+ color: "var(--muted-foreground)",
85
+ display: "flex",
86
+ alignItems: "center",
87
+ justifyContent: "center",
88
+ fontSize: "10px",
89
+ fontWeight: 600,
90
+ flexShrink: 0,
91
+ }, children: (label || id).slice(0, 2).toUpperCase() })), _jsx("span", { children: label || id })] }));
92
+ };
@@ -0,0 +1,46 @@
1
+ export interface MentionItem {
2
+ id: string;
3
+ label: string;
4
+ avatar?: string;
5
+ email?: string;
6
+ type?: "node" | "article";
7
+ nodeId?: string;
8
+ slug?: string;
9
+ }
10
+ export interface MentionOptions {
11
+ /**
12
+ * Function to fetch/filter mentionable items based on query
13
+ */
14
+ items?: (query: string) => MentionItem[] | Promise<MentionItem[]>;
15
+ /**
16
+ * Custom render function for mention nodes
17
+ */
18
+ renderLabel?: (props: {
19
+ node: any;
20
+ options: any;
21
+ }) => string;
22
+ /**
23
+ * Character that triggers the mention autocomplete (default: @)
24
+ */
25
+ char?: string;
26
+ /**
27
+ * Custom name for the extension (to avoid duplicates)
28
+ */
29
+ name?: string;
30
+ }
31
+ /**
32
+ * Create the mention extension with custom suggestion rendering
33
+ */
34
+ export declare const createMentionExtension: (options?: MentionOptions) => import("@tiptap/core").Node<import("@tiptap/extension-mention").MentionOptions<any, import("@tiptap/extension-mention").MentionNodeAttrs>, any>;
35
+ /**
36
+ * Render function for mention suggestions (autocomplete dropdown)
37
+ */
38
+ export declare const renderMentionSuggestion: () => {
39
+ onStart: (props: any) => void;
40
+ onUpdate: (props: any) => void;
41
+ onKeyDown: ({ event }: {
42
+ event: KeyboardEvent;
43
+ }) => any;
44
+ onExit: () => void;
45
+ };
46
+ export default createMentionExtension;