@kopexa/tiptap 17.2.4 → 17.4.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 (65) hide show
  1. package/dist/chunk-4HO7BWDC.mjs +89 -0
  2. package/dist/chunk-552JLRNB.mjs +35 -0
  3. package/dist/chunk-5SMDMQDF.mjs +34 -0
  4. package/dist/{chunk-XKWTI3MA.mjs → chunk-DQK6PA4U.mjs} +11 -2
  5. package/dist/{chunk-3ZPLSXTZ.mjs → chunk-ERPGWXFK.mjs} +1 -1
  6. package/dist/{chunk-NJZK5DRT.mjs → chunk-GDDWW2IQ.mjs} +38 -13
  7. package/dist/{chunk-NSYSECKW.mjs → chunk-GL3RTIER.mjs} +1 -0
  8. package/dist/chunk-H7MS2UMO.mjs +168 -0
  9. package/dist/chunk-JVSH5T4B.mjs +72 -0
  10. package/dist/{chunk-ZYFCSR3E.mjs → chunk-L5RDMV3H.mjs} +3 -3
  11. package/dist/chunk-Q5FK7SFY.mjs +75 -0
  12. package/dist/chunk-QIELBKP3.mjs +104 -0
  13. package/dist/extensions/variable/extract-variables.d.mts +16 -0
  14. package/dist/extensions/variable/extract-variables.d.ts +16 -0
  15. package/dist/extensions/variable/extract-variables.js +58 -0
  16. package/dist/extensions/variable/extract-variables.mjs +7 -0
  17. package/dist/extensions/variable/index.d.mts +38 -0
  18. package/dist/extensions/variable/index.d.ts +38 -0
  19. package/dist/extensions/variable/index.js +190 -0
  20. package/dist/extensions/variable/index.mjs +11 -0
  21. package/dist/extensions/variable/messages.d.mts +69 -0
  22. package/dist/extensions/variable/messages.d.ts +69 -0
  23. package/dist/extensions/variable/messages.js +98 -0
  24. package/dist/extensions/variable/messages.mjs +7 -0
  25. package/dist/extensions/variable/variable-context.d.mts +56 -0
  26. package/dist/extensions/variable/variable-context.d.ts +56 -0
  27. package/dist/extensions/variable/variable-context.js +70 -0
  28. package/dist/extensions/variable/variable-context.mjs +12 -0
  29. package/dist/extensions/variable/variable-filler-dialog.d.mts +43 -0
  30. package/dist/extensions/variable/variable-filler-dialog.d.ts +43 -0
  31. package/dist/extensions/variable/variable-filler-dialog.js +207 -0
  32. package/dist/extensions/variable/variable-filler-dialog.mjs +9 -0
  33. package/dist/extensions/variable/variable-suggestion.d.mts +31 -0
  34. package/dist/extensions/variable/variable-suggestion.d.ts +31 -0
  35. package/dist/extensions/variable/variable-suggestion.js +615 -0
  36. package/dist/extensions/variable/variable-suggestion.mjs +14 -0
  37. package/dist/extensions/variable/variable-view.d.mts +13 -0
  38. package/dist/extensions/variable/variable-view.d.ts +13 -0
  39. package/dist/extensions/variable/variable-view.js +110 -0
  40. package/dist/extensions/variable/variable-view.mjs +11 -0
  41. package/dist/hooks/use-create-editor.d.mts +8 -2
  42. package/dist/hooks/use-create-editor.d.ts +8 -2
  43. package/dist/hooks/use-create-editor.js +163 -7
  44. package/dist/hooks/use-create-editor.mjs +4 -1
  45. package/dist/index.d.mts +5 -0
  46. package/dist/index.d.ts +5 -0
  47. package/dist/index.js +2733 -2164
  48. package/dist/index.mjs +37 -11
  49. package/dist/presets/basic/editor-header.mjs +3 -3
  50. package/dist/presets/basic/index.d.mts +12 -1
  51. package/dist/presets/basic/index.d.ts +12 -1
  52. package/dist/presets/basic/index.js +4203 -3853
  53. package/dist/presets/basic/index.mjs +14 -10
  54. package/dist/ui/bubble-menu/index.js +1 -0
  55. package/dist/ui/bubble-menu/index.mjs +1 -1
  56. package/dist/ui/slash-dropdown-menu/index.js +2 -2
  57. package/dist/ui/slash-dropdown-menu/index.mjs +2 -2
  58. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +2 -2
  59. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +2 -2
  60. package/dist/ui/suggestion-menu/index.js +2 -2
  61. package/dist/ui/suggestion-menu/index.mjs +1 -1
  62. package/dist/ui/suggestion-menu/suggestion-menu.js +2 -2
  63. package/dist/ui/suggestion-menu/suggestion-menu.mjs +1 -1
  64. package/package.json +24 -24
  65. package/dist/{chunk-FDPXD6VC.mjs → chunk-RFWNKE7D.mjs} +3 -3
@@ -0,0 +1,89 @@
1
+ "use client";
2
+ import {
3
+ VariableNodeView
4
+ } from "./chunk-JVSH5T4B.mjs";
5
+
6
+ // src/extensions/variable/index.ts
7
+ import { mergeAttributes, Node } from "@tiptap/core";
8
+ import { ReactNodeViewRenderer } from "@tiptap/react";
9
+ var VariableNode = Node.create({
10
+ name: "variable",
11
+ group: "inline",
12
+ inline: true,
13
+ atom: true,
14
+ selectable: true,
15
+ draggable: true,
16
+ addOptions() {
17
+ return {
18
+ HTMLAttributes: {}
19
+ };
20
+ },
21
+ addAttributes() {
22
+ return {
23
+ name: {
24
+ default: "",
25
+ parseHTML: (element) => element.getAttribute("data-name"),
26
+ renderHTML: (attributes) => ({
27
+ "data-name": attributes.name
28
+ })
29
+ },
30
+ fallback: {
31
+ default: void 0,
32
+ parseHTML: (element) => element.getAttribute("data-fallback"),
33
+ renderHTML: (attributes) => {
34
+ if (!attributes.fallback) return {};
35
+ return {
36
+ "data-fallback": attributes.fallback
37
+ };
38
+ }
39
+ },
40
+ category: {
41
+ default: void 0,
42
+ parseHTML: (element) => element.getAttribute("data-category"),
43
+ renderHTML: (attributes) => {
44
+ if (!attributes.category) return {};
45
+ return {
46
+ "data-category": attributes.category
47
+ };
48
+ }
49
+ }
50
+ };
51
+ },
52
+ parseHTML() {
53
+ return [
54
+ {
55
+ tag: 'span[data-type="variable"]'
56
+ }
57
+ ];
58
+ },
59
+ renderHTML({ node, HTMLAttributes }) {
60
+ const attrs = node.attrs;
61
+ return [
62
+ "span",
63
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
64
+ "data-type": "variable",
65
+ class: "variable-node"
66
+ }),
67
+ `{{${attrs.name}}}`
68
+ ];
69
+ },
70
+ addNodeView() {
71
+ return ReactNodeViewRenderer(VariableNodeView);
72
+ },
73
+ addCommands() {
74
+ return {
75
+ insertVariable: (attrs) => ({ commands }) => {
76
+ return commands.insertContent({
77
+ type: this.name,
78
+ attrs
79
+ });
80
+ }
81
+ };
82
+ }
83
+ });
84
+ var variable_default = VariableNode;
85
+
86
+ export {
87
+ VariableNode,
88
+ variable_default
89
+ };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ // src/extensions/variable/extract-variables.ts
4
+ function extractVariablesFromContent(content) {
5
+ if (!content) return [];
6
+ const variables = /* @__PURE__ */ new Map();
7
+ function scan(node) {
8
+ var _a;
9
+ if (node.type === "variable" && ((_a = node.attrs) == null ? void 0 : _a.name)) {
10
+ const name = node.attrs.name;
11
+ if (!variables.has(name)) {
12
+ variables.set(name, {
13
+ name,
14
+ label: formatVariableName(name),
15
+ category: node.attrs.category || void 0,
16
+ fallback: node.attrs.fallback || void 0
17
+ });
18
+ }
19
+ }
20
+ if (node.content && Array.isArray(node.content)) {
21
+ for (const child of node.content) {
22
+ scan(child);
23
+ }
24
+ }
25
+ }
26
+ scan(content);
27
+ return Array.from(variables.values());
28
+ }
29
+ function formatVariableName(name) {
30
+ return name.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).replace(/\s+/g, " ").trim();
31
+ }
32
+
33
+ export {
34
+ extractVariablesFromContent
35
+ };
@@ -0,0 +1,34 @@
1
+ "use client";
2
+
3
+ // src/extensions/variable/variable-context.tsx
4
+ import * as React from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var VariableContext = React.createContext(null);
7
+ function VariableProvider({
8
+ children,
9
+ variables,
10
+ resolveVariable
11
+ }) {
12
+ const value = React.useMemo(
13
+ () => ({
14
+ variables,
15
+ resolveVariable
16
+ }),
17
+ [variables, resolveVariable]
18
+ );
19
+ return /* @__PURE__ */ jsx(VariableContext.Provider, { value, children });
20
+ }
21
+ function useVariables() {
22
+ return React.useContext(VariableContext);
23
+ }
24
+ function useVariablesWithFallback(fallbackVariables = []) {
25
+ var _a;
26
+ const context = React.useContext(VariableContext);
27
+ return (_a = context == null ? void 0 : context.variables) != null ? _a : fallbackVariables;
28
+ }
29
+
30
+ export {
31
+ VariableProvider,
32
+ useVariables,
33
+ useVariablesWithFallback
34
+ };
@@ -2,6 +2,9 @@
2
2
  import {
3
3
  TrailingNode
4
4
  } from "./chunk-H6LC4LDQ.mjs";
5
+ import {
6
+ VariableNode
7
+ } from "./chunk-4HO7BWDC.mjs";
5
8
  import {
6
9
  MathBlock
7
10
  } from "./chunk-2U5CQUZH.mjs";
@@ -68,6 +71,7 @@ var useCreateEditor = ({
68
71
  enableControls = false,
69
72
  controlResolver,
70
73
  fileHandler: fileHandlerProp,
74
+ enableVariables = false,
71
75
  ...options
72
76
  }) => {
73
77
  const fileHandlerFromContext = useEditorFile();
@@ -78,7 +82,8 @@ var useCreateEditor = ({
78
82
  placeholder,
79
83
  enableControls,
80
84
  controlResolver,
81
- fileHandler
85
+ fileHandler,
86
+ enableVariables
82
87
  })
83
88
  );
84
89
  const editor = useEditor({
@@ -112,7 +117,8 @@ function getExtensions({
112
117
  placeholder,
113
118
  enableControls = false,
114
119
  controlResolver,
115
- fileHandler
120
+ fileHandler,
121
+ enableVariables = false
116
122
  }) {
117
123
  const extensions = [
118
124
  StarterKit.configure({
@@ -178,6 +184,9 @@ function getExtensions({
178
184
  if (enableControls) {
179
185
  extensions.push(ControlKit.configure({ resolver: controlResolver }));
180
186
  }
187
+ if (enableVariables) {
188
+ extensions.push(VariableNode);
189
+ }
181
190
  if (fileHandler) {
182
191
  extensions.push(
183
192
  FileHandler.configure({
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-6552DQWB.mjs";
5
5
  import {
6
6
  SuggestionMenu
7
- } from "./chunk-ZYFCSR3E.mjs";
7
+ } from "./chunk-L5RDMV3H.mjs";
8
8
  import {
9
9
  filterSuggestionItems
10
10
  } from "./chunk-CNVACBGT.mjs";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  SlashDropdownMenu
4
- } from "./chunk-3ZPLSXTZ.mjs";
4
+ } from "./chunk-ERPGWXFK.mjs";
5
5
  import {
6
6
  useScrollToHash
7
7
  } from "./chunk-DZLGLP7R.mjs";
@@ -10,10 +10,13 @@ import {
10
10
  } from "./chunk-XNDXYI2N.mjs";
11
11
  import {
12
12
  BubbleMenu
13
- } from "./chunk-NSYSECKW.mjs";
13
+ } from "./chunk-GL3RTIER.mjs";
14
+ import {
15
+ VariableSuggestion
16
+ } from "./chunk-H7MS2UMO.mjs";
14
17
  import {
15
18
  EditorHeader
16
- } from "./chunk-FDPXD6VC.mjs";
19
+ } from "./chunk-RFWNKE7D.mjs";
17
20
  import {
18
21
  useUiEditorState
19
22
  } from "./chunk-BXJYNSWQ.mjs";
@@ -22,7 +25,10 @@ import {
22
25
  } from "./chunk-REJEJXOZ.mjs";
23
26
  import {
24
27
  useCreateEditor
25
- } from "./chunk-XKWTI3MA.mjs";
28
+ } from "./chunk-DQK6PA4U.mjs";
29
+ import {
30
+ VariableProvider
31
+ } from "./chunk-5SMDMQDF.mjs";
26
32
 
27
33
  // src/presets/basic/index.tsx
28
34
  import {
@@ -33,27 +39,42 @@ import {
33
39
  EditorContent,
34
40
  EditorContext
35
41
  } from "@tiptap/react";
36
- import { useContext } from "react";
42
+ import { useCallback, useContext } from "react";
37
43
  import { jsx, jsxs } from "react/jsx-runtime";
38
44
  var BasicEditor = ({
39
45
  variant,
40
46
  bordered,
41
47
  content,
48
+ variables,
49
+ variableValues,
42
50
  ...options
43
51
  }) => {
44
- const editor = useCreateEditor({ content, ...options });
52
+ const editor = useCreateEditor({
53
+ content,
54
+ enableVariables: !!(variables == null ? void 0 : variables.length),
55
+ ...options
56
+ });
45
57
  const styles = editorBasic({ variant, bordered });
58
+ const resolveVariable = useCallback(
59
+ (name) => variableValues == null ? void 0 : variableValues[name],
60
+ [variableValues]
61
+ );
46
62
  if (!editor) {
47
63
  return /* @__PURE__ */ jsx(LoadingSpinner, {});
48
64
  }
49
65
  const isBottomToolbar = variant === "field";
50
- return /* @__PURE__ */ jsx(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ jsx("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ jsxs(EditorContext.Provider, { value: { editor }, children: [
66
+ const hasVariables = variables && variables.length > 0;
67
+ const editorContent = /* @__PURE__ */ jsx(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ jsx("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ jsxs(EditorContext.Provider, { value: { editor }, children: [
51
68
  !isBottomToolbar && /* @__PURE__ */ jsx(EditorHeader, { editor, variant }),
52
- /* @__PURE__ */ jsx(EditorContentArea, { variant }),
69
+ /* @__PURE__ */ jsx(EditorContentArea, { variant, variables }),
53
70
  isBottomToolbar && /* @__PURE__ */ jsx(EditorHeader, { editor, variant })
54
71
  ] }) }) });
72
+ if (hasVariables) {
73
+ return /* @__PURE__ */ jsx(VariableProvider, { variables, resolveVariable, children: editorContent });
74
+ }
75
+ return editorContent;
55
76
  };
56
- var EditorContentArea = ({ variant }) => {
77
+ var EditorContentArea = ({ variant, variables }) => {
57
78
  const styles = editorBasic({ variant });
58
79
  const { editor } = useContext(EditorContext);
59
80
  const { isDragging } = useUiEditorState(editor);
@@ -61,8 +82,9 @@ var EditorContentArea = ({ variant }) => {
61
82
  if (!editor) {
62
83
  return null;
63
84
  }
85
+ const isEditable = editor.isEditable;
64
86
  return /* @__PURE__ */ jsxs("div", { className: styles.wrapper(), children: [
65
- /* @__PURE__ */ jsx(
87
+ /* @__PURE__ */ jsxs(
66
88
  EditorContent,
67
89
  {
68
90
  editor,
@@ -71,11 +93,14 @@ var EditorContentArea = ({ variant }) => {
71
93
  style: {
72
94
  cursor: isDragging ? "grabbing" : "auto"
73
95
  },
74
- children: /* @__PURE__ */ jsx(SlashDropdownMenu, {})
96
+ children: [
97
+ isEditable && /* @__PURE__ */ jsx(SlashDropdownMenu, {}),
98
+ isEditable && variables && variables.length > 0 && /* @__PURE__ */ jsx(VariableSuggestion, { editor, variables })
99
+ ]
75
100
  }
76
101
  ),
77
- /* @__PURE__ */ jsx(BubbleMenu, { editor }),
78
- /* @__PURE__ */ jsx(LinkBubble, { editor })
102
+ isEditable && /* @__PURE__ */ jsx(BubbleMenu, { editor }),
103
+ isEditable && /* @__PURE__ */ jsx(LinkBubble, { editor })
79
104
  ] });
80
105
  };
81
106
  function LoadingSpinner({ text = "Connecting..." }) {
@@ -24,6 +24,7 @@ function BubbleMenu({ editor }) {
24
24
  if (empty) return false;
25
25
  if (e.isActive("codeBlock")) return false;
26
26
  if (e.isActive("link")) return false;
27
+ if (e.isActive("variable")) return false;
27
28
  if (!e.isEditable) return false;
28
29
  return true;
29
30
  },
@@ -0,0 +1,168 @@
1
+ "use client";
2
+ import {
3
+ SuggestionMenu
4
+ } from "./chunk-L5RDMV3H.mjs";
5
+
6
+ // src/extensions/variable/variable-suggestion.tsx
7
+ import { getElementOverflowPosition } from "@kopexa/editor-utils";
8
+ import { slashDropdownMenu } from "@kopexa/theme";
9
+ import { PluginKey } from "@tiptap/pm/state";
10
+ import * as React from "react";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var VariableSuggestionPluginKey = new PluginKey("variableSuggestion");
13
+ function VariableSuggestion({
14
+ editor,
15
+ variables
16
+ }) {
17
+ const getItems = React.useCallback(
18
+ ({ query }) => {
19
+ const normalizedQuery = query.toLowerCase().trim();
20
+ const items = [];
21
+ const matchingVariables = variables.filter((variable) => {
22
+ var _a, _b;
23
+ if (!normalizedQuery) return true;
24
+ return variable.name.toLowerCase().includes(normalizedQuery) || variable.label.toLowerCase().includes(normalizedQuery) || ((_a = variable.category) == null ? void 0 : _a.toLowerCase().includes(normalizedQuery)) || ((_b = variable.description) == null ? void 0 : _b.toLowerCase().includes(normalizedQuery));
25
+ });
26
+ for (const variable of matchingVariables) {
27
+ items.push({
28
+ title: variable.label,
29
+ subtext: variable.name,
30
+ group: variable.category,
31
+ keywords: [variable.name, variable.label, variable.category].filter(
32
+ Boolean
33
+ ),
34
+ onSelect: ({ editor: editor2 }) => {
35
+ const attrs = {
36
+ name: variable.name,
37
+ fallback: variable.fallback,
38
+ category: variable.category
39
+ };
40
+ editor2.chain().focus().insertVariable(attrs).run();
41
+ }
42
+ });
43
+ }
44
+ if (normalizedQuery && !variables.some((v) => v.name.toLowerCase() === normalizedQuery)) {
45
+ items.push({
46
+ title: `Neue Variable "${query}"`,
47
+ subtext: query,
48
+ group: "Neu",
49
+ onSelect: ({ editor: editor2 }) => {
50
+ const attrs = {
51
+ name: query
52
+ };
53
+ editor2.chain().focus().insertVariable(attrs).run();
54
+ }
55
+ });
56
+ }
57
+ return items;
58
+ },
59
+ [variables]
60
+ );
61
+ return /* @__PURE__ */ jsx(
62
+ SuggestionMenu,
63
+ {
64
+ editor,
65
+ pluginKey: VariableSuggestionPluginKey,
66
+ char: "{{",
67
+ items: getItems,
68
+ allowSpaces: false,
69
+ selector: "tiptap-variable-suggestion-menu",
70
+ children: (props) => /* @__PURE__ */ jsx(VariableList, { ...props })
71
+ }
72
+ );
73
+ }
74
+ var VariableItem = ({
75
+ item,
76
+ isSelected,
77
+ onSelect
78
+ }) => {
79
+ const itemRef = React.useRef(null);
80
+ React.useEffect(() => {
81
+ const selector = document.querySelector(
82
+ '[data-selector="tiptap-variable-suggestion-menu"]'
83
+ );
84
+ if (!itemRef.current || !isSelected || !selector) return;
85
+ const overflow = getElementOverflowPosition(itemRef.current, selector);
86
+ if (overflow === "top") {
87
+ itemRef.current.scrollIntoView(true);
88
+ } else if (overflow === "bottom") {
89
+ itemRef.current.scrollIntoView(false);
90
+ }
91
+ }, [isSelected]);
92
+ return /* @__PURE__ */ jsxs(
93
+ "button",
94
+ {
95
+ ref: itemRef,
96
+ type: "button",
97
+ "data-active-state": isSelected ? "on" : "off",
98
+ onClick: onSelect,
99
+ className: "w-full flex items-center justify-between gap-3 px-2 py-1.5 text-sm rounded-sm outline-none hover:bg-muted data-[active-state=on]:bg-muted",
100
+ children: [
101
+ /* @__PURE__ */ jsx("span", { className: "font-medium truncate", children: item.title }),
102
+ /* @__PURE__ */ jsx("code", { className: "text-xs text-muted-foreground font-mono shrink-0", children: item.subtext })
103
+ ]
104
+ }
105
+ );
106
+ };
107
+ var VariableList = ({
108
+ items,
109
+ selectedIndex,
110
+ onSelect
111
+ }) => {
112
+ const styles = slashDropdownMenu();
113
+ const renderedItems = React.useMemo(() => {
114
+ const rendered = [];
115
+ const groups = {};
116
+ items.forEach((item, index) => {
117
+ const groupLabel = item.group || "";
118
+ if (!groups[groupLabel]) {
119
+ groups[groupLabel] = { items: [], indices: [] };
120
+ }
121
+ groups[groupLabel].items.push(item);
122
+ groups[groupLabel].indices.push(index);
123
+ });
124
+ Object.entries(groups).forEach(([groupLabel, groupData], groupIndex) => {
125
+ const groupItems = groupData.items.map((item, itemIndex) => {
126
+ const originalIndex = groupData.indices[itemIndex];
127
+ return /* @__PURE__ */ jsx(
128
+ VariableItem,
129
+ {
130
+ item,
131
+ isSelected: originalIndex === selectedIndex,
132
+ onSelect: () => onSelect(item)
133
+ },
134
+ `item-${originalIndex}-${item.title}`
135
+ );
136
+ });
137
+ if (groupLabel) {
138
+ rendered.push(
139
+ /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
140
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: groupLabel }),
141
+ groupItems
142
+ ] }, `group-${groupIndex}-${groupLabel}`)
143
+ );
144
+ } else {
145
+ rendered.push(...groupItems);
146
+ }
147
+ });
148
+ return rendered;
149
+ }, [items, selectedIndex, onSelect]);
150
+ if (!renderedItems.length) {
151
+ return null;
152
+ }
153
+ return /* @__PURE__ */ jsx(
154
+ "div",
155
+ {
156
+ className: styles.card(),
157
+ style: {
158
+ maxHeight: "var(--suggestion-menu-max-height)",
159
+ minWidth: "240px"
160
+ },
161
+ children: /* @__PURE__ */ jsx("div", { className: styles.body(), children: renderedItems })
162
+ }
163
+ );
164
+ };
165
+
166
+ export {
167
+ VariableSuggestion
168
+ };
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ import {
3
+ useVariables
4
+ } from "./chunk-5SMDMQDF.mjs";
5
+
6
+ // src/extensions/variable/variable-view.tsx
7
+ import { variableNode } from "@kopexa/theme";
8
+ import {
9
+ NodeViewWrapper,
10
+ useEditorState
11
+ } from "@tiptap/react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ function VariableNodeView({ node, editor }) {
14
+ var _a;
15
+ const attrs = node.attrs;
16
+ const { name, fallback, category } = attrs;
17
+ const context = useVariables();
18
+ const isEditable = useEditorState({
19
+ editor,
20
+ selector: ({ editor: e }) => {
21
+ var _a2;
22
+ return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : true;
23
+ }
24
+ });
25
+ const resolvedValue = (_a = context == null ? void 0 : context.resolveVariable) == null ? void 0 : _a.call(context, name);
26
+ const hasValue = resolvedValue !== void 0 && resolvedValue !== "";
27
+ const displayValue = resolvedValue || fallback;
28
+ const styles = variableNode({ resolved: hasValue });
29
+ if (!isEditable && hasValue) {
30
+ return /* @__PURE__ */ jsx(
31
+ NodeViewWrapper,
32
+ {
33
+ as: "span",
34
+ "data-type": "variable",
35
+ "data-name": name,
36
+ style: { userSelect: "text" },
37
+ children: displayValue
38
+ }
39
+ );
40
+ }
41
+ return /* @__PURE__ */ jsx(
42
+ NodeViewWrapper,
43
+ {
44
+ as: "span",
45
+ className: styles.wrapper(),
46
+ "data-type": "variable",
47
+ "data-name": name,
48
+ "data-category": category,
49
+ "data-resolved": hasValue ? "true" : "false",
50
+ children: hasValue ? /* @__PURE__ */ jsx("span", { className: styles.chip(), title: `{{${name}}}`, children: /* @__PURE__ */ jsx("span", { className: styles.value(), children: displayValue }) }) : /* @__PURE__ */ jsxs(
51
+ "span",
52
+ {
53
+ className: styles.chip(),
54
+ title: fallback ? `Fallback: ${fallback}` : void 0,
55
+ children: [
56
+ /* @__PURE__ */ jsx("span", { className: styles.bracket(), children: "{" }),
57
+ /* @__PURE__ */ jsx("span", { className: styles.bracket(), children: "{" }),
58
+ /* @__PURE__ */ jsx("span", { className: styles.name(), children: name }),
59
+ /* @__PURE__ */ jsx("span", { className: styles.bracket(), children: "}" }),
60
+ /* @__PURE__ */ jsx("span", { className: styles.bracket(), children: "}" })
61
+ ]
62
+ }
63
+ )
64
+ }
65
+ );
66
+ }
67
+ var variable_view_default = VariableNodeView;
68
+
69
+ export {
70
+ VariableNodeView,
71
+ variable_view_default
72
+ };
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-42HKGCOO.mjs";
14
14
 
15
15
  // src/ui/suggestion-menu/suggestion-menu.tsx
16
- import { flip, offset, shift, size } from "@floating-ui/react";
16
+ import { FloatingPortal, flip, offset, shift, size } from "@floating-ui/react";
17
17
  import { PluginKey } from "@tiptap/pm/state";
18
18
  import {
19
19
  Suggestion,
@@ -191,7 +191,7 @@ var SuggestionMenu = ({
191
191
  if (!isMounted || !show || !editor) {
192
192
  return null;
193
193
  }
194
- return /* @__PURE__ */ jsx(
194
+ return /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(
195
195
  "div",
196
196
  {
197
197
  ref,
@@ -208,7 +208,7 @@ var SuggestionMenu = ({
208
208
  onSelect
209
209
  })
210
210
  }
211
- );
211
+ ) });
212
212
  };
213
213
 
214
214
  export {
@@ -0,0 +1,75 @@
1
+ "use client";
2
+
3
+ // src/extensions/variable/messages.ts
4
+ import { defineMessages } from "react-intl";
5
+ var messages = defineMessages({
6
+ title: {
7
+ id: "editor.variable.title",
8
+ defaultMessage: "Variables",
9
+ description: "Title for the variables section"
10
+ },
11
+ insert: {
12
+ id: "editor.variable.insert",
13
+ defaultMessage: "Insert variable",
14
+ description: "Insert variable button label"
15
+ },
16
+ empty_state: {
17
+ id: "editor.variable.empty_state",
18
+ defaultMessage: "No variables available",
19
+ description: "Empty state when no variables are defined"
20
+ },
21
+ hint: {
22
+ id: "editor.variable.hint",
23
+ defaultMessage: "Type {{ to insert a variable",
24
+ description: "Hint for inserting variables"
25
+ },
26
+ save: {
27
+ id: "editor.variable.save",
28
+ defaultMessage: "Save",
29
+ description: "Save button label"
30
+ },
31
+ cancel: {
32
+ id: "editor.variable.cancel",
33
+ defaultMessage: "Cancel",
34
+ description: "Cancel button label"
35
+ },
36
+ category_company: {
37
+ id: "editor.variable.category.company",
38
+ defaultMessage: "Company",
39
+ description: "Company variables category"
40
+ },
41
+ category_user: {
42
+ id: "editor.variable.category.user",
43
+ defaultMessage: "User",
44
+ description: "User variables category"
45
+ },
46
+ category_date: {
47
+ id: "editor.variable.category.date",
48
+ defaultMessage: "Date",
49
+ description: "Date variables category"
50
+ },
51
+ category_document: {
52
+ id: "editor.variable.category.document",
53
+ defaultMessage: "Document",
54
+ description: "Document variables category"
55
+ },
56
+ category_other: {
57
+ id: "editor.variable.category.other",
58
+ defaultMessage: "Other",
59
+ description: "Other variables category"
60
+ },
61
+ filler_title: {
62
+ id: "editor.variable.filler.title",
63
+ defaultMessage: "Fill in Variables",
64
+ description: "Title for the variable filler dialog"
65
+ },
66
+ filler_filled: {
67
+ id: "editor.variable.filler.filled",
68
+ defaultMessage: "filled",
69
+ description: "Label for filled count"
70
+ }
71
+ });
72
+
73
+ export {
74
+ messages
75
+ };