notra-editor 0.8.0 → 0.8.2

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 (231) hide show
  1. package/dist/components/blockquote-button/blockquote-button.cjs +5 -3
  2. package/dist/components/blockquote-button/blockquote-button.cjs.map +1 -1
  3. package/dist/components/blockquote-button/blockquote-button.mjs +5 -3
  4. package/dist/components/blockquote-button/blockquote-button.mjs.map +1 -1
  5. package/dist/components/code-block-button/code-block-button.cjs +5 -3
  6. package/dist/components/code-block-button/code-block-button.cjs.map +1 -1
  7. package/dist/components/code-block-button/code-block-button.mjs +5 -3
  8. package/dist/components/code-block-button/code-block-button.mjs.map +1 -1
  9. package/dist/components/code-block-view/code-block-shell.cjs +4 -2
  10. package/dist/components/code-block-view/code-block-shell.cjs.map +1 -1
  11. package/dist/components/code-block-view/code-block-shell.mjs +3 -2
  12. package/dist/components/code-block-view/code-block-shell.mjs.map +1 -1
  13. package/dist/components/code-block-view/code-block-view.cjs +6 -4
  14. package/dist/components/code-block-view/code-block-view.cjs.map +1 -1
  15. package/dist/components/code-block-view/code-block-view.mjs +6 -4
  16. package/dist/components/code-block-view/code-block-view.mjs.map +1 -1
  17. package/dist/components/code-block-view/language-select.cjs +9 -7
  18. package/dist/components/code-block-view/language-select.cjs.map +1 -1
  19. package/dist/components/code-block-view/language-select.mjs +9 -7
  20. package/dist/components/code-block-view/language-select.mjs.map +1 -1
  21. package/dist/components/copy-button.cjs +6 -4
  22. package/dist/components/copy-button.cjs.map +1 -1
  23. package/dist/components/copy-button.mjs +6 -4
  24. package/dist/components/copy-button.mjs.map +1 -1
  25. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.cjs +8 -6
  26. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.cjs.map +1 -1
  27. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.mjs +8 -6
  28. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.mjs.map +1 -1
  29. package/dist/components/heading-dropdown-menu/heading-menu-item.cjs +6 -4
  30. package/dist/components/heading-dropdown-menu/heading-menu-item.cjs.map +1 -1
  31. package/dist/components/heading-dropdown-menu/heading-menu-item.mjs +5 -4
  32. package/dist/components/heading-dropdown-menu/heading-menu-item.mjs.map +1 -1
  33. package/dist/components/heading-dropdown-menu/use-heading.cjs +4 -2
  34. package/dist/components/heading-dropdown-menu/use-heading.cjs.map +1 -1
  35. package/dist/components/heading-dropdown-menu/use-heading.mjs +3 -2
  36. package/dist/components/heading-dropdown-menu/use-heading.mjs.map +1 -1
  37. package/dist/components/image-popover/image-input-form.cjs +127 -0
  38. package/dist/components/image-popover/image-input-form.cjs.map +1 -0
  39. package/dist/components/image-popover/image-input-form.d.cts +16 -0
  40. package/dist/components/image-popover/image-input-form.d.ts +16 -0
  41. package/dist/components/image-popover/image-input-form.mjs +103 -0
  42. package/dist/components/image-popover/image-input-form.mjs.map +1 -0
  43. package/dist/components/image-popover/image-popover.cjs +35 -92
  44. package/dist/components/image-popover/image-popover.cjs.map +1 -1
  45. package/dist/components/image-popover/image-popover.mjs +36 -93
  46. package/dist/components/image-popover/image-popover.mjs.map +1 -1
  47. package/dist/components/image-popover/use-image-popover.cjs +2 -0
  48. package/dist/components/image-popover/use-image-popover.cjs.map +1 -1
  49. package/dist/components/image-popover/use-image-popover.mjs +1 -0
  50. package/dist/components/image-popover/use-image-popover.mjs.map +1 -1
  51. package/dist/components/link-popover/link-popover.cjs +10 -8
  52. package/dist/components/link-popover/link-popover.cjs.map +1 -1
  53. package/dist/components/link-popover/link-popover.mjs +10 -8
  54. package/dist/components/link-popover/link-popover.mjs.map +1 -1
  55. package/dist/components/link-popover/use-link-popover.cjs +2 -0
  56. package/dist/components/link-popover/use-link-popover.cjs.map +1 -1
  57. package/dist/components/link-popover/use-link-popover.mjs +1 -0
  58. package/dist/components/link-popover/use-link-popover.mjs.map +1 -1
  59. package/dist/components/list-dropdown-menu/list-dropdown-menu.cjs +8 -6
  60. package/dist/components/list-dropdown-menu/list-dropdown-menu.cjs.map +1 -1
  61. package/dist/components/list-dropdown-menu/list-dropdown-menu.mjs +8 -6
  62. package/dist/components/list-dropdown-menu/list-dropdown-menu.mjs.map +1 -1
  63. package/dist/components/list-dropdown-menu/list-menu-item.cjs +6 -4
  64. package/dist/components/list-dropdown-menu/list-menu-item.cjs.map +1 -1
  65. package/dist/components/list-dropdown-menu/list-menu-item.mjs +5 -4
  66. package/dist/components/list-dropdown-menu/list-menu-item.mjs.map +1 -1
  67. package/dist/components/list-dropdown-menu/use-list.cjs +5 -3
  68. package/dist/components/list-dropdown-menu/use-list.cjs.map +1 -1
  69. package/dist/components/list-dropdown-menu/use-list.mjs +4 -3
  70. package/dist/components/list-dropdown-menu/use-list.mjs.map +1 -1
  71. package/dist/components/mark-button/mark-button.cjs +6 -4
  72. package/dist/components/mark-button/mark-button.cjs.map +1 -1
  73. package/dist/components/mark-button/mark-button.mjs +6 -4
  74. package/dist/components/mark-button/mark-button.mjs.map +1 -1
  75. package/dist/components/mark-button/use-mark.cjs +4 -2
  76. package/dist/components/mark-button/use-mark.cjs.map +1 -1
  77. package/dist/components/mark-button/use-mark.mjs +3 -2
  78. package/dist/components/mark-button/use-mark.mjs.map +1 -1
  79. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.cjs +151 -0
  80. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.cjs.map +1 -0
  81. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.d.cts +9 -0
  82. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.d.ts +9 -0
  83. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.mjs +127 -0
  84. package/dist/components/slash-dropdown-menu/slash-dropdown-menu.mjs.map +1 -0
  85. package/dist/components/slash-dropdown-menu/slash-image-popover.cjs +80 -0
  86. package/dist/components/slash-dropdown-menu/slash-image-popover.cjs.map +1 -0
  87. package/dist/components/slash-dropdown-menu/slash-image-popover.d.cts +11 -0
  88. package/dist/components/slash-dropdown-menu/slash-image-popover.d.ts +11 -0
  89. package/dist/components/slash-dropdown-menu/slash-image-popover.mjs +56 -0
  90. package/dist/components/slash-dropdown-menu/slash-image-popover.mjs.map +1 -0
  91. package/dist/components/slash-dropdown-menu/use-slash-items.cjs +138 -0
  92. package/dist/components/slash-dropdown-menu/use-slash-items.cjs.map +1 -0
  93. package/dist/components/slash-dropdown-menu/use-slash-items.d.cts +11 -0
  94. package/dist/components/slash-dropdown-menu/use-slash-items.d.ts +11 -0
  95. package/dist/components/slash-dropdown-menu/use-slash-items.mjs +125 -0
  96. package/dist/components/slash-dropdown-menu/use-slash-items.mjs.map +1 -0
  97. package/dist/components/suggestion-menu/filter-suggestion-items.cjs +57 -0
  98. package/dist/components/suggestion-menu/filter-suggestion-items.cjs.map +1 -0
  99. package/dist/components/suggestion-menu/filter-suggestion-items.d.cts +6 -0
  100. package/dist/components/suggestion-menu/filter-suggestion-items.d.ts +6 -0
  101. package/dist/components/suggestion-menu/filter-suggestion-items.mjs +32 -0
  102. package/dist/components/suggestion-menu/filter-suggestion-items.mjs.map +1 -0
  103. package/dist/components/suggestion-menu/suggestion-menu-types.cjs +19 -0
  104. package/dist/components/suggestion-menu/suggestion-menu-types.cjs.map +1 -0
  105. package/dist/components/suggestion-menu/suggestion-menu-types.d.cts +22 -0
  106. package/dist/components/suggestion-menu/suggestion-menu-types.d.ts +22 -0
  107. package/dist/components/suggestion-menu/suggestion-menu-types.mjs +1 -0
  108. package/dist/components/suggestion-menu/suggestion-menu-types.mjs.map +1 -0
  109. package/dist/components/suggestion-menu/suggestion-menu.cjs +205 -0
  110. package/dist/components/suggestion-menu/suggestion-menu.cjs.map +1 -0
  111. package/dist/components/suggestion-menu/suggestion-menu.d.cts +27 -0
  112. package/dist/components/suggestion-menu/suggestion-menu.d.ts +27 -0
  113. package/dist/components/suggestion-menu/suggestion-menu.mjs +181 -0
  114. package/dist/components/suggestion-menu/suggestion-menu.mjs.map +1 -0
  115. package/dist/components/toolbar/toolbar.cjs +4 -2
  116. package/dist/components/toolbar/toolbar.cjs.map +1 -1
  117. package/dist/components/toolbar/toolbar.mjs +3 -2
  118. package/dist/components/toolbar/toolbar.mjs.map +1 -1
  119. package/dist/components/ui/button.cjs +5 -3
  120. package/dist/components/ui/button.cjs.map +1 -1
  121. package/dist/components/ui/button.mjs +4 -3
  122. package/dist/components/ui/button.mjs.map +1 -1
  123. package/dist/components/ui/command.cjs +6 -5
  124. package/dist/components/ui/command.cjs.map +1 -1
  125. package/dist/components/ui/command.mjs +5 -5
  126. package/dist/components/ui/command.mjs.map +1 -1
  127. package/dist/components/ui/dialog.cjs +5 -4
  128. package/dist/components/ui/dialog.cjs.map +1 -1
  129. package/dist/components/ui/dialog.mjs +4 -4
  130. package/dist/components/ui/dialog.mjs.map +1 -1
  131. package/dist/components/ui/dropdown-menu.cjs +4 -3
  132. package/dist/components/ui/dropdown-menu.cjs.map +1 -1
  133. package/dist/components/ui/dropdown-menu.mjs +3 -3
  134. package/dist/components/ui/dropdown-menu.mjs.map +1 -1
  135. package/dist/components/ui/input-group.cjs +9 -7
  136. package/dist/components/ui/input-group.cjs.map +1 -1
  137. package/dist/components/ui/input-group.d.cts +1 -1
  138. package/dist/components/ui/input-group.d.ts +1 -1
  139. package/dist/components/ui/input-group.mjs +9 -7
  140. package/dist/components/ui/input-group.mjs.map +1 -1
  141. package/dist/components/ui/input.cjs +3 -1
  142. package/dist/components/ui/input.cjs.map +1 -1
  143. package/dist/components/ui/input.mjs +2 -1
  144. package/dist/components/ui/input.mjs.map +1 -1
  145. package/dist/components/ui/popover.cjs +4 -3
  146. package/dist/components/ui/popover.cjs.map +1 -1
  147. package/dist/components/ui/popover.mjs +3 -3
  148. package/dist/components/ui/popover.mjs.map +1 -1
  149. package/dist/components/ui/separator.cjs +4 -3
  150. package/dist/components/ui/separator.cjs.map +1 -1
  151. package/dist/components/ui/separator.mjs +3 -3
  152. package/dist/components/ui/separator.mjs.map +1 -1
  153. package/dist/components/ui/spacer.cjs +2 -0
  154. package/dist/components/ui/spacer.cjs.map +1 -1
  155. package/dist/components/ui/spacer.mjs +1 -0
  156. package/dist/components/ui/spacer.mjs.map +1 -1
  157. package/dist/components/ui/textarea.cjs +3 -1
  158. package/dist/components/ui/textarea.cjs.map +1 -1
  159. package/dist/components/ui/textarea.mjs +2 -1
  160. package/dist/components/ui/textarea.mjs.map +1 -1
  161. package/dist/components/undo-redo-button/undo-redo-button.cjs +6 -4
  162. package/dist/components/undo-redo-button/undo-redo-button.cjs.map +1 -1
  163. package/dist/components/undo-redo-button/undo-redo-button.mjs +6 -4
  164. package/dist/components/undo-redo-button/undo-redo-button.mjs.map +1 -1
  165. package/dist/components/undo-redo-button/use-undo-redo.cjs +4 -2
  166. package/dist/components/undo-redo-button/use-undo-redo.cjs.map +1 -1
  167. package/dist/components/undo-redo-button/use-undo-redo.mjs +3 -2
  168. package/dist/components/undo-redo-button/use-undo-redo.mjs.map +1 -1
  169. package/dist/extensions/code-block.cjs +8 -6
  170. package/dist/extensions/code-block.cjs.map +1 -1
  171. package/dist/extensions/code-block.mjs +7 -6
  172. package/dist/extensions/code-block.mjs.map +1 -1
  173. package/dist/extensions/editor.cjs +5 -3
  174. package/dist/extensions/editor.cjs.map +1 -1
  175. package/dist/extensions/editor.mjs +4 -3
  176. package/dist/extensions/editor.mjs.map +1 -1
  177. package/dist/extensions/index.cjs +4 -2
  178. package/dist/extensions/index.cjs.map +1 -1
  179. package/dist/extensions/index.mjs +3 -2
  180. package/dist/extensions/index.mjs.map +1 -1
  181. package/dist/extensions/shared.cjs +5 -3
  182. package/dist/extensions/shared.cjs.map +1 -1
  183. package/dist/extensions/shared.mjs +4 -3
  184. package/dist/extensions/shared.mjs.map +1 -1
  185. package/dist/hooks/use-copy-to-clipboard.cjs +3 -2
  186. package/dist/hooks/use-copy-to-clipboard.cjs.map +1 -1
  187. package/dist/hooks/use-copy-to-clipboard.mjs +2 -2
  188. package/dist/hooks/use-copy-to-clipboard.mjs.map +1 -1
  189. package/dist/hooks/use-floating-element.cjs +55 -0
  190. package/dist/hooks/use-floating-element.cjs.map +1 -0
  191. package/dist/hooks/use-floating-element.d.cts +21 -0
  192. package/dist/hooks/use-floating-element.d.ts +21 -0
  193. package/dist/hooks/use-floating-element.mjs +35 -0
  194. package/dist/hooks/use-floating-element.mjs.map +1 -0
  195. package/dist/hooks/use-markdown-editor.cjs +6 -1
  196. package/dist/hooks/use-markdown-editor.cjs.map +1 -1
  197. package/dist/hooks/use-markdown-editor.d.cts +1 -1
  198. package/dist/hooks/use-markdown-editor.d.ts +1 -1
  199. package/dist/hooks/use-markdown-editor.mjs +5 -1
  200. package/dist/hooks/use-markdown-editor.mjs.map +1 -1
  201. package/dist/index.cjs +18 -16
  202. package/dist/index.cjs.map +1 -1
  203. package/dist/index.mjs +17 -16
  204. package/dist/index.mjs.map +1 -1
  205. package/dist/lib/highlight-code-to-html.cjs +2 -0
  206. package/dist/lib/highlight-code-to-html.cjs.map +1 -1
  207. package/dist/lib/highlight-code-to-html.mjs +1 -0
  208. package/dist/lib/highlight-code-to-html.mjs.map +1 -1
  209. package/dist/lib/languages.cjs +4 -2
  210. package/dist/lib/languages.cjs.map +1 -1
  211. package/dist/lib/languages.mjs +3 -2
  212. package/dist/lib/languages.mjs.map +1 -1
  213. package/dist/lib/utils.cjs +2 -0
  214. package/dist/lib/utils.cjs.map +1 -1
  215. package/dist/lib/utils.mjs +1 -0
  216. package/dist/lib/utils.mjs.map +1 -1
  217. package/dist/notra-editor.cjs +17 -13
  218. package/dist/notra-editor.cjs.map +1 -1
  219. package/dist/notra-editor.mjs +17 -13
  220. package/dist/notra-editor.mjs.map +1 -1
  221. package/dist/notra-reader.cjs +9 -7
  222. package/dist/notra-reader.cjs.map +1 -1
  223. package/dist/notra-reader.mjs +8 -7
  224. package/dist/notra-reader.mjs.map +1 -1
  225. package/dist/styles/globals.css +6 -0
  226. package/dist/themes/default/editor.css +50 -0
  227. package/dist/utils/markdown-to-json.cjs +5 -3
  228. package/dist/utils/markdown-to-json.cjs.map +1 -1
  229. package/dist/utils/markdown-to-json.mjs +4 -3
  230. package/dist/utils/markdown-to-json.mjs.map +1 -1
  231. package/package.json +4 -1
@@ -0,0 +1,22 @@
1
+ import { Editor, Range } from '@tiptap/react';
2
+
3
+ type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
4
+ interface SuggestionItem {
5
+ /** Main label shown in the menu. */
6
+ title: string;
7
+ /** Secondary description shown under the title. */
8
+ subtext?: string;
9
+ /** Icon component (lucide-react). */
10
+ badge?: IconComponent;
11
+ /** Group label used by callers that render grouped lists. */
12
+ group?: string;
13
+ /** Extra search keywords. */
14
+ keywords?: string[];
15
+ /** Invoked when the item is chosen. */
16
+ onSelect: (props: {
17
+ editor: Editor;
18
+ range: Range;
19
+ }) => void;
20
+ }
21
+
22
+ export type { IconComponent, SuggestionItem };
@@ -0,0 +1,22 @@
1
+ import { Editor, Range } from '@tiptap/react';
2
+
3
+ type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
4
+ interface SuggestionItem {
5
+ /** Main label shown in the menu. */
6
+ title: string;
7
+ /** Secondary description shown under the title. */
8
+ subtext?: string;
9
+ /** Icon component (lucide-react). */
10
+ badge?: IconComponent;
11
+ /** Group label used by callers that render grouped lists. */
12
+ group?: string;
13
+ /** Extra search keywords. */
14
+ keywords?: string[];
15
+ /** Invoked when the item is chosen. */
16
+ onSelect: (props: {
17
+ editor: Editor;
18
+ range: Range;
19
+ }) => void;
20
+ }
21
+
22
+ export type { IconComponent, SuggestionItem };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=suggestion-menu-types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/components/suggestion-menu/suggestion-menu.tsx
22
+ var suggestion_menu_exports = {};
23
+ __export(suggestion_menu_exports, {
24
+ SuggestionMenu: () => SuggestionMenu
25
+ });
26
+ module.exports = __toCommonJS(suggestion_menu_exports);
27
+ var import_react = require("@floating-ui/react");
28
+ var import_state = require("@tiptap/pm/state");
29
+ var import_suggestion = require("@tiptap/suggestion");
30
+ var import_react2 = require("react");
31
+ var import_use_floating_element = require("../../hooks/use-floating-element.cjs");
32
+ var import_jsx_runtime = require("react/jsx-runtime");
33
+ var FLOATING_Z_INDEX = 1e3;
34
+ function SuggestionMenu({
35
+ editor,
36
+ char,
37
+ pluginKey,
38
+ items: itemsFn,
39
+ decorationClass,
40
+ decorationContent,
41
+ selector = "notra-suggestion-menu",
42
+ maxHeight = 384,
43
+ children
44
+ }) {
45
+ const [open, setOpen] = (0, import_react2.useState)(false);
46
+ const [decorationNode, setDecorationNode] = (0, import_react2.useState)(
47
+ null
48
+ );
49
+ const [items, setItems] = (0, import_react2.useState)([]);
50
+ const [query, setQuery] = (0, import_react2.useState)("");
51
+ const [selectedIndex, setSelectedIndex] = (0, import_react2.useState)(0);
52
+ const commandRef = (0, import_react2.useRef)(null);
53
+ (0, import_react2.useEffect)(() => {
54
+ setSelectedIndex(0);
55
+ }, [query, items.length]);
56
+ const close = (0, import_react2.useCallback)(() => {
57
+ setOpen(false);
58
+ }, []);
59
+ const middleware = (0, import_react2.useMemo)(
60
+ () => [
61
+ (0, import_react.offset)(8),
62
+ (0, import_react.flip)({ mainAxis: true, crossAxis: false }),
63
+ (0, import_react.shift)({ padding: 8 }),
64
+ (0, import_react.size)({
65
+ apply({ availableHeight, elements }) {
66
+ const next = Math.min(availableHeight, maxHeight);
67
+ elements.floating.style.setProperty(
68
+ "--suggestion-menu-max-height",
69
+ `${next}px`
70
+ );
71
+ }
72
+ })
73
+ ],
74
+ [maxHeight]
75
+ );
76
+ const { setFloatingRef, style, getFloatingProps, isMounted } = (0, import_use_floating_element.useFloatingElement)(open, decorationNode, FLOATING_Z_INDEX, {
77
+ placement: "bottom-start",
78
+ middleware,
79
+ onOpenChange: (next) => {
80
+ if (!next) close();
81
+ }
82
+ });
83
+ const itemsFnRef = (0, import_react2.useRef)(itemsFn);
84
+ const decorationClassRef = (0, import_react2.useRef)(decorationClass);
85
+ const decorationContentRef = (0, import_react2.useRef)(decorationContent);
86
+ (0, import_react2.useEffect)(() => {
87
+ itemsFnRef.current = itemsFn;
88
+ decorationClassRef.current = decorationClass;
89
+ decorationContentRef.current = decorationContent;
90
+ }, [itemsFn, decorationClass, decorationContent]);
91
+ const itemsRef = (0, import_react2.useRef)([]);
92
+ const selectedIndexRef = (0, import_react2.useRef)(0);
93
+ (0, import_react2.useEffect)(() => {
94
+ itemsRef.current = items;
95
+ }, [items]);
96
+ (0, import_react2.useEffect)(() => {
97
+ selectedIndexRef.current = selectedIndex;
98
+ }, [selectedIndex]);
99
+ (0, import_react2.useEffect)(() => {
100
+ if (!editor || editor.isDestroyed) return;
101
+ const key = new import_state.PluginKey(pluginKey);
102
+ const plugin = (0, import_suggestion.Suggestion)({
103
+ editor,
104
+ char,
105
+ pluginKey: key,
106
+ decorationClass: decorationClassRef.current,
107
+ decorationContent: decorationContentRef.current,
108
+ items: ({ query: query2, editor: editor2 }) => itemsFnRef.current({ query: query2, editor: editor2 }),
109
+ allow: ({ state, range }) => {
110
+ const $from = state.doc.resolve(range.from);
111
+ for (let depth = $from.depth; depth > 0; depth--) {
112
+ const name = $from.node(depth).type.name;
113
+ if (name === "image" || name === "codeBlock") return false;
114
+ }
115
+ return true;
116
+ },
117
+ command: ({ editor: editor2, range, props }) => {
118
+ editor2.chain().focus().deleteRange(range).run();
119
+ props.onSelect({ editor: editor2, range });
120
+ },
121
+ render: () => ({
122
+ onStart: (props) => {
123
+ setDecorationNode(props.decorationNode ?? null);
124
+ setItems(props.items);
125
+ setQuery(props.query);
126
+ commandRef.current = (item) => props.command(item);
127
+ setOpen(true);
128
+ },
129
+ onUpdate: (props) => {
130
+ setDecorationNode(props.decorationNode ?? null);
131
+ setItems(props.items);
132
+ setQuery(props.query);
133
+ commandRef.current = (item) => props.command(item);
134
+ },
135
+ onKeyDown: ({ event }) => {
136
+ const list = itemsRef.current;
137
+ if (event.key === "ArrowDown") {
138
+ if (list.length > 0) {
139
+ setSelectedIndex((selectedIndexRef.current + 1) % list.length);
140
+ }
141
+ return true;
142
+ }
143
+ if (event.key === "ArrowUp") {
144
+ if (list.length > 0) {
145
+ setSelectedIndex(
146
+ (selectedIndexRef.current - 1 + list.length) % list.length
147
+ );
148
+ }
149
+ return true;
150
+ }
151
+ if (event.key === "Enter") {
152
+ const item = list[selectedIndexRef.current];
153
+ if (item && commandRef.current) {
154
+ commandRef.current(item);
155
+ }
156
+ return true;
157
+ }
158
+ if (event.key === "Escape") {
159
+ close();
160
+ return true;
161
+ }
162
+ return false;
163
+ },
164
+ onExit: () => {
165
+ setDecorationNode(null);
166
+ setItems([]);
167
+ setQuery("");
168
+ commandRef.current = null;
169
+ setOpen(false);
170
+ }
171
+ })
172
+ });
173
+ editor.registerPlugin(plugin);
174
+ return () => {
175
+ if (!editor.isDestroyed) {
176
+ editor.unregisterPlugin(key);
177
+ }
178
+ };
179
+ }, [editor, char, pluginKey, close]);
180
+ const handleSelect = (0, import_react2.useCallback)((item) => {
181
+ if (commandRef.current) {
182
+ commandRef.current(item);
183
+ }
184
+ }, []);
185
+ if (!isMounted || !open) return null;
186
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
187
+ "div",
188
+ {
189
+ ref: setFloatingRef,
190
+ "aria-label": "Suggestions",
191
+ className: "notra-suggestion-menu",
192
+ "data-selector": selector,
193
+ role: "listbox",
194
+ style,
195
+ ...getFloatingProps(),
196
+ onPointerDown: (e) => e.preventDefault(),
197
+ children: children({ items, selectedIndex, onSelect: handleSelect })
198
+ }
199
+ );
200
+ }
201
+ // Annotate the CommonJS export names for ESM import in node:
202
+ 0 && (module.exports = {
203
+ SuggestionMenu
204
+ });
205
+ //# sourceMappingURL=suggestion-menu.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["'use client';\n\nimport { flip, offset, shift, size } from '@floating-ui/react';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { Suggestion } from '@tiptap/suggestion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useFloatingElement } from '../../hooks/use-floating-element.js';\n\nimport type { SuggestionItem } from './suggestion-menu-types.js';\nimport type { Editor } from '@tiptap/react';\nimport type {\n\tSuggestionKeyDownProps,\n\tSuggestionProps\n} from '@tiptap/suggestion';\nimport type { ReactNode } from 'react';\n\nexport interface SuggestionMenuRenderProps {\n\titems: SuggestionItem[];\n\tselectedIndex: number;\n\tonSelect: (item: SuggestionItem) => void;\n}\n\nexport interface SuggestionMenuProps {\n\teditor: Editor | null;\n\tchar: string;\n\tpluginKey: string;\n\titems: (ctx: { query: string; editor: Editor }) => SuggestionItem[];\n\tdecorationClass?: string;\n\tdecorationContent?: string;\n\tselector?: string;\n\tmaxHeight?: number;\n\tchildren: (renderProps: SuggestionMenuRenderProps) => ReactNode;\n}\n\nconst FLOATING_Z_INDEX = 1000;\n\nexport function SuggestionMenu({\n\teditor,\n\tchar,\n\tpluginKey,\n\titems: itemsFn,\n\tdecorationClass,\n\tdecorationContent,\n\tselector = 'notra-suggestion-menu',\n\tmaxHeight = 384,\n\tchildren\n}: SuggestionMenuProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [decorationNode, setDecorationNode] = useState<HTMLElement | null>(\n\t\tnull\n\t);\n\tconst [items, setItems] = useState<SuggestionItem[]>([]);\n\tconst [query, setQuery] = useState('');\n\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\tconst commandRef = useRef<((item: SuggestionItem) => void) | null>(null);\n\n\t// Reset selection when the visible item list changes.\n\tuseEffect(() => {\n\t\tsetSelectedIndex(0);\n\t}, [query, items.length]);\n\n\tconst close = useCallback(() => {\n\t\tsetOpen(false);\n\t}, []);\n\n\tconst middleware = useMemo(\n\t\t() => [\n\t\t\toffset(8),\n\t\t\tflip({ mainAxis: true, crossAxis: false }),\n\t\t\tshift({ padding: 8 }),\n\t\t\tsize({\n\t\t\t\tapply({ availableHeight, elements }) {\n\t\t\t\t\tconst next = Math.min(availableHeight, maxHeight);\n\n\t\t\t\t\telements.floating.style.setProperty(\n\t\t\t\t\t\t'--suggestion-menu-max-height',\n\t\t\t\t\t\t`${next}px`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t})\n\t\t],\n\t\t[maxHeight]\n\t);\n\n\tconst { setFloatingRef, style, getFloatingProps, isMounted } =\n\t\tuseFloatingElement(open, decorationNode, FLOATING_Z_INDEX, {\n\t\t\tplacement: 'bottom-start',\n\t\t\tmiddleware,\n\t\t\tonOpenChange: (next) => {\n\t\t\t\tif (!next) close();\n\t\t\t}\n\t\t});\n\n\t// Stable refs for the latest render-callback inputs (the suggestion plugin\n\t// is registered once per editor; we don't want to re-register every render).\n\tconst itemsFnRef = useRef(itemsFn);\n\tconst decorationClassRef = useRef(decorationClass);\n\tconst decorationContentRef = useRef(decorationContent);\n\n\tuseEffect(() => {\n\t\titemsFnRef.current = itemsFn;\n\t\tdecorationClassRef.current = decorationClass;\n\t\tdecorationContentRef.current = decorationContent;\n\t}, [itemsFn, decorationClass, decorationContent]);\n\n\tconst itemsRef = useRef<SuggestionItem[]>([]);\n\tconst selectedIndexRef = useRef(0);\n\n\tuseEffect(() => {\n\t\titemsRef.current = items;\n\t}, [items]);\n\n\tuseEffect(() => {\n\t\tselectedIndexRef.current = selectedIndex;\n\t}, [selectedIndex]);\n\n\tuseEffect(() => {\n\t\tif (!editor || editor.isDestroyed) return;\n\n\t\tconst key = new PluginKey(pluginKey);\n\n\t\tconst plugin = Suggestion<SuggestionItem>({\n\t\t\teditor,\n\t\t\tchar,\n\t\t\tpluginKey: key,\n\t\t\tdecorationClass: decorationClassRef.current,\n\t\t\tdecorationContent: decorationContentRef.current,\n\n\t\t\titems: ({ query, editor }) => itemsFnRef.current({ query, editor }),\n\n\t\t\tallow: ({ state, range }) => {\n\t\t\t\tconst $from = state.doc.resolve(range.from);\n\n\t\t\t\tfor (let depth = $from.depth; depth > 0; depth--) {\n\t\t\t\t\tconst name = $from.node(depth).type.name;\n\n\t\t\t\t\tif (name === 'image' || name === 'codeBlock') return false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tcommand: ({ editor, range, props }) => {\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t\tprops.onSelect({ editor, range });\n\t\t\t},\n\n\t\t\trender: () => ({\n\t\t\t\tonStart: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t\tsetOpen(true);\n\t\t\t\t},\n\t\t\t\tonUpdate: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t},\n\t\t\t\tonKeyDown: ({ event }: SuggestionKeyDownProps) => {\n\t\t\t\t\tconst list = itemsRef.current;\n\n\t\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex((selectedIndexRef.current + 1) % list.length);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t\t\t\t(selectedIndexRef.current - 1 + list.length) % list.length\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\t\tconst item = list[selectedIndexRef.current];\n\n\t\t\t\t\t\tif (item && commandRef.current) {\n\t\t\t\t\t\t\tcommandRef.current(item);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\t\tclose();\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tonExit: () => {\n\t\t\t\t\tsetDecorationNode(null);\n\t\t\t\t\tsetItems([]);\n\t\t\t\t\tsetQuery('');\n\t\t\t\t\tcommandRef.current = null;\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\teditor.registerPlugin(plugin);\n\n\t\treturn () => {\n\t\t\tif (!editor.isDestroyed) {\n\t\t\t\teditor.unregisterPlugin(key);\n\t\t\t}\n\t\t};\n\t}, [editor, char, pluginKey, close]);\n\n\tconst handleSelect = useCallback((item: SuggestionItem) => {\n\t\tif (commandRef.current) {\n\t\t\tcommandRef.current(item);\n\t\t}\n\t}, []);\n\n\tif (!isMounted || !open) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={setFloatingRef}\n\t\t\taria-label=\"Suggestions\"\n\t\t\tclassName=\"notra-suggestion-menu\"\n\t\t\tdata-selector={selector}\n\t\t\trole=\"listbox\"\n\t\t\tstyle={style}\n\t\t\t{...getFloatingProps()}\n\t\t\tonPointerDown={(e) => e.preventDefault()}\n\t\t>\n\t\t\t{children({ items, selectedIndex, onSelect: handleSelect })}\n\t\t</div>\n\t);\n}\n"],"mappings":"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","names":["import_react","query","editor"]}
@@ -0,0 +1,27 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SuggestionItem } from './suggestion-menu-types.cjs';
3
+ import { Editor } from '@tiptap/react';
4
+ import { ReactNode } from 'react';
5
+
6
+ interface SuggestionMenuRenderProps {
7
+ items: SuggestionItem[];
8
+ selectedIndex: number;
9
+ onSelect: (item: SuggestionItem) => void;
10
+ }
11
+ interface SuggestionMenuProps {
12
+ editor: Editor | null;
13
+ char: string;
14
+ pluginKey: string;
15
+ items: (ctx: {
16
+ query: string;
17
+ editor: Editor;
18
+ }) => SuggestionItem[];
19
+ decorationClass?: string;
20
+ decorationContent?: string;
21
+ selector?: string;
22
+ maxHeight?: number;
23
+ children: (renderProps: SuggestionMenuRenderProps) => ReactNode;
24
+ }
25
+ declare function SuggestionMenu({ editor, char, pluginKey, items: itemsFn, decorationClass, decorationContent, selector, maxHeight, children }: SuggestionMenuProps): react_jsx_runtime.JSX.Element | null;
26
+
27
+ export { SuggestionMenu, type SuggestionMenuProps, type SuggestionMenuRenderProps };
@@ -0,0 +1,27 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SuggestionItem } from './suggestion-menu-types.js';
3
+ import { Editor } from '@tiptap/react';
4
+ import { ReactNode } from 'react';
5
+
6
+ interface SuggestionMenuRenderProps {
7
+ items: SuggestionItem[];
8
+ selectedIndex: number;
9
+ onSelect: (item: SuggestionItem) => void;
10
+ }
11
+ interface SuggestionMenuProps {
12
+ editor: Editor | null;
13
+ char: string;
14
+ pluginKey: string;
15
+ items: (ctx: {
16
+ query: string;
17
+ editor: Editor;
18
+ }) => SuggestionItem[];
19
+ decorationClass?: string;
20
+ decorationContent?: string;
21
+ selector?: string;
22
+ maxHeight?: number;
23
+ children: (renderProps: SuggestionMenuRenderProps) => ReactNode;
24
+ }
25
+ declare function SuggestionMenu({ editor, char, pluginKey, items: itemsFn, decorationClass, decorationContent, selector, maxHeight, children }: SuggestionMenuProps): react_jsx_runtime.JSX.Element | null;
26
+
27
+ export { SuggestionMenu, type SuggestionMenuProps, type SuggestionMenuRenderProps };
@@ -0,0 +1,181 @@
1
+ "use client";
2
+
3
+ // src/components/suggestion-menu/suggestion-menu.tsx
4
+ import { flip, offset, shift, size } from "@floating-ui/react";
5
+ import { PluginKey } from "@tiptap/pm/state";
6
+ import { Suggestion } from "@tiptap/suggestion";
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { useFloatingElement } from "../../hooks/use-floating-element.mjs";
9
+ import { jsx } from "react/jsx-runtime";
10
+ var FLOATING_Z_INDEX = 1e3;
11
+ function SuggestionMenu({
12
+ editor,
13
+ char,
14
+ pluginKey,
15
+ items: itemsFn,
16
+ decorationClass,
17
+ decorationContent,
18
+ selector = "notra-suggestion-menu",
19
+ maxHeight = 384,
20
+ children
21
+ }) {
22
+ const [open, setOpen] = useState(false);
23
+ const [decorationNode, setDecorationNode] = useState(
24
+ null
25
+ );
26
+ const [items, setItems] = useState([]);
27
+ const [query, setQuery] = useState("");
28
+ const [selectedIndex, setSelectedIndex] = useState(0);
29
+ const commandRef = useRef(null);
30
+ useEffect(() => {
31
+ setSelectedIndex(0);
32
+ }, [query, items.length]);
33
+ const close = useCallback(() => {
34
+ setOpen(false);
35
+ }, []);
36
+ const middleware = useMemo(
37
+ () => [
38
+ offset(8),
39
+ flip({ mainAxis: true, crossAxis: false }),
40
+ shift({ padding: 8 }),
41
+ size({
42
+ apply({ availableHeight, elements }) {
43
+ const next = Math.min(availableHeight, maxHeight);
44
+ elements.floating.style.setProperty(
45
+ "--suggestion-menu-max-height",
46
+ `${next}px`
47
+ );
48
+ }
49
+ })
50
+ ],
51
+ [maxHeight]
52
+ );
53
+ const { setFloatingRef, style, getFloatingProps, isMounted } = useFloatingElement(open, decorationNode, FLOATING_Z_INDEX, {
54
+ placement: "bottom-start",
55
+ middleware,
56
+ onOpenChange: (next) => {
57
+ if (!next) close();
58
+ }
59
+ });
60
+ const itemsFnRef = useRef(itemsFn);
61
+ const decorationClassRef = useRef(decorationClass);
62
+ const decorationContentRef = useRef(decorationContent);
63
+ useEffect(() => {
64
+ itemsFnRef.current = itemsFn;
65
+ decorationClassRef.current = decorationClass;
66
+ decorationContentRef.current = decorationContent;
67
+ }, [itemsFn, decorationClass, decorationContent]);
68
+ const itemsRef = useRef([]);
69
+ const selectedIndexRef = useRef(0);
70
+ useEffect(() => {
71
+ itemsRef.current = items;
72
+ }, [items]);
73
+ useEffect(() => {
74
+ selectedIndexRef.current = selectedIndex;
75
+ }, [selectedIndex]);
76
+ useEffect(() => {
77
+ if (!editor || editor.isDestroyed) return;
78
+ const key = new PluginKey(pluginKey);
79
+ const plugin = Suggestion({
80
+ editor,
81
+ char,
82
+ pluginKey: key,
83
+ decorationClass: decorationClassRef.current,
84
+ decorationContent: decorationContentRef.current,
85
+ items: ({ query: query2, editor: editor2 }) => itemsFnRef.current({ query: query2, editor: editor2 }),
86
+ allow: ({ state, range }) => {
87
+ const $from = state.doc.resolve(range.from);
88
+ for (let depth = $from.depth; depth > 0; depth--) {
89
+ const name = $from.node(depth).type.name;
90
+ if (name === "image" || name === "codeBlock") return false;
91
+ }
92
+ return true;
93
+ },
94
+ command: ({ editor: editor2, range, props }) => {
95
+ editor2.chain().focus().deleteRange(range).run();
96
+ props.onSelect({ editor: editor2, range });
97
+ },
98
+ render: () => ({
99
+ onStart: (props) => {
100
+ setDecorationNode(props.decorationNode ?? null);
101
+ setItems(props.items);
102
+ setQuery(props.query);
103
+ commandRef.current = (item) => props.command(item);
104
+ setOpen(true);
105
+ },
106
+ onUpdate: (props) => {
107
+ setDecorationNode(props.decorationNode ?? null);
108
+ setItems(props.items);
109
+ setQuery(props.query);
110
+ commandRef.current = (item) => props.command(item);
111
+ },
112
+ onKeyDown: ({ event }) => {
113
+ const list = itemsRef.current;
114
+ if (event.key === "ArrowDown") {
115
+ if (list.length > 0) {
116
+ setSelectedIndex((selectedIndexRef.current + 1) % list.length);
117
+ }
118
+ return true;
119
+ }
120
+ if (event.key === "ArrowUp") {
121
+ if (list.length > 0) {
122
+ setSelectedIndex(
123
+ (selectedIndexRef.current - 1 + list.length) % list.length
124
+ );
125
+ }
126
+ return true;
127
+ }
128
+ if (event.key === "Enter") {
129
+ const item = list[selectedIndexRef.current];
130
+ if (item && commandRef.current) {
131
+ commandRef.current(item);
132
+ }
133
+ return true;
134
+ }
135
+ if (event.key === "Escape") {
136
+ close();
137
+ return true;
138
+ }
139
+ return false;
140
+ },
141
+ onExit: () => {
142
+ setDecorationNode(null);
143
+ setItems([]);
144
+ setQuery("");
145
+ commandRef.current = null;
146
+ setOpen(false);
147
+ }
148
+ })
149
+ });
150
+ editor.registerPlugin(plugin);
151
+ return () => {
152
+ if (!editor.isDestroyed) {
153
+ editor.unregisterPlugin(key);
154
+ }
155
+ };
156
+ }, [editor, char, pluginKey, close]);
157
+ const handleSelect = useCallback((item) => {
158
+ if (commandRef.current) {
159
+ commandRef.current(item);
160
+ }
161
+ }, []);
162
+ if (!isMounted || !open) return null;
163
+ return /* @__PURE__ */ jsx(
164
+ "div",
165
+ {
166
+ ref: setFloatingRef,
167
+ "aria-label": "Suggestions",
168
+ className: "notra-suggestion-menu",
169
+ "data-selector": selector,
170
+ role: "listbox",
171
+ style,
172
+ ...getFloatingProps(),
173
+ onPointerDown: (e) => e.preventDefault(),
174
+ children: children({ items, selectedIndex, onSelect: handleSelect })
175
+ }
176
+ );
177
+ }
178
+ export {
179
+ SuggestionMenu
180
+ };
181
+ //# sourceMappingURL=suggestion-menu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["'use client';\n\nimport { flip, offset, shift, size } from '@floating-ui/react';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { Suggestion } from '@tiptap/suggestion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useFloatingElement } from '../../hooks/use-floating-element.js';\n\nimport type { SuggestionItem } from './suggestion-menu-types.js';\nimport type { Editor } from '@tiptap/react';\nimport type {\n\tSuggestionKeyDownProps,\n\tSuggestionProps\n} from '@tiptap/suggestion';\nimport type { ReactNode } from 'react';\n\nexport interface SuggestionMenuRenderProps {\n\titems: SuggestionItem[];\n\tselectedIndex: number;\n\tonSelect: (item: SuggestionItem) => void;\n}\n\nexport interface SuggestionMenuProps {\n\teditor: Editor | null;\n\tchar: string;\n\tpluginKey: string;\n\titems: (ctx: { query: string; editor: Editor }) => SuggestionItem[];\n\tdecorationClass?: string;\n\tdecorationContent?: string;\n\tselector?: string;\n\tmaxHeight?: number;\n\tchildren: (renderProps: SuggestionMenuRenderProps) => ReactNode;\n}\n\nconst FLOATING_Z_INDEX = 1000;\n\nexport function SuggestionMenu({\n\teditor,\n\tchar,\n\tpluginKey,\n\titems: itemsFn,\n\tdecorationClass,\n\tdecorationContent,\n\tselector = 'notra-suggestion-menu',\n\tmaxHeight = 384,\n\tchildren\n}: SuggestionMenuProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [decorationNode, setDecorationNode] = useState<HTMLElement | null>(\n\t\tnull\n\t);\n\tconst [items, setItems] = useState<SuggestionItem[]>([]);\n\tconst [query, setQuery] = useState('');\n\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\tconst commandRef = useRef<((item: SuggestionItem) => void) | null>(null);\n\n\t// Reset selection when the visible item list changes.\n\tuseEffect(() => {\n\t\tsetSelectedIndex(0);\n\t}, [query, items.length]);\n\n\tconst close = useCallback(() => {\n\t\tsetOpen(false);\n\t}, []);\n\n\tconst middleware = useMemo(\n\t\t() => [\n\t\t\toffset(8),\n\t\t\tflip({ mainAxis: true, crossAxis: false }),\n\t\t\tshift({ padding: 8 }),\n\t\t\tsize({\n\t\t\t\tapply({ availableHeight, elements }) {\n\t\t\t\t\tconst next = Math.min(availableHeight, maxHeight);\n\n\t\t\t\t\telements.floating.style.setProperty(\n\t\t\t\t\t\t'--suggestion-menu-max-height',\n\t\t\t\t\t\t`${next}px`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t})\n\t\t],\n\t\t[maxHeight]\n\t);\n\n\tconst { setFloatingRef, style, getFloatingProps, isMounted } =\n\t\tuseFloatingElement(open, decorationNode, FLOATING_Z_INDEX, {\n\t\t\tplacement: 'bottom-start',\n\t\t\tmiddleware,\n\t\t\tonOpenChange: (next) => {\n\t\t\t\tif (!next) close();\n\t\t\t}\n\t\t});\n\n\t// Stable refs for the latest render-callback inputs (the suggestion plugin\n\t// is registered once per editor; we don't want to re-register every render).\n\tconst itemsFnRef = useRef(itemsFn);\n\tconst decorationClassRef = useRef(decorationClass);\n\tconst decorationContentRef = useRef(decorationContent);\n\n\tuseEffect(() => {\n\t\titemsFnRef.current = itemsFn;\n\t\tdecorationClassRef.current = decorationClass;\n\t\tdecorationContentRef.current = decorationContent;\n\t}, [itemsFn, decorationClass, decorationContent]);\n\n\tconst itemsRef = useRef<SuggestionItem[]>([]);\n\tconst selectedIndexRef = useRef(0);\n\n\tuseEffect(() => {\n\t\titemsRef.current = items;\n\t}, [items]);\n\n\tuseEffect(() => {\n\t\tselectedIndexRef.current = selectedIndex;\n\t}, [selectedIndex]);\n\n\tuseEffect(() => {\n\t\tif (!editor || editor.isDestroyed) return;\n\n\t\tconst key = new PluginKey(pluginKey);\n\n\t\tconst plugin = Suggestion<SuggestionItem>({\n\t\t\teditor,\n\t\t\tchar,\n\t\t\tpluginKey: key,\n\t\t\tdecorationClass: decorationClassRef.current,\n\t\t\tdecorationContent: decorationContentRef.current,\n\n\t\t\titems: ({ query, editor }) => itemsFnRef.current({ query, editor }),\n\n\t\t\tallow: ({ state, range }) => {\n\t\t\t\tconst $from = state.doc.resolve(range.from);\n\n\t\t\t\tfor (let depth = $from.depth; depth > 0; depth--) {\n\t\t\t\t\tconst name = $from.node(depth).type.name;\n\n\t\t\t\t\tif (name === 'image' || name === 'codeBlock') return false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tcommand: ({ editor, range, props }) => {\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t\tprops.onSelect({ editor, range });\n\t\t\t},\n\n\t\t\trender: () => ({\n\t\t\t\tonStart: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t\tsetOpen(true);\n\t\t\t\t},\n\t\t\t\tonUpdate: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t},\n\t\t\t\tonKeyDown: ({ event }: SuggestionKeyDownProps) => {\n\t\t\t\t\tconst list = itemsRef.current;\n\n\t\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex((selectedIndexRef.current + 1) % list.length);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t\t\t\t(selectedIndexRef.current - 1 + list.length) % list.length\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\t\tconst item = list[selectedIndexRef.current];\n\n\t\t\t\t\t\tif (item && commandRef.current) {\n\t\t\t\t\t\t\tcommandRef.current(item);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\t\tclose();\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tonExit: () => {\n\t\t\t\t\tsetDecorationNode(null);\n\t\t\t\t\tsetItems([]);\n\t\t\t\t\tsetQuery('');\n\t\t\t\t\tcommandRef.current = null;\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\teditor.registerPlugin(plugin);\n\n\t\treturn () => {\n\t\t\tif (!editor.isDestroyed) {\n\t\t\t\teditor.unregisterPlugin(key);\n\t\t\t}\n\t\t};\n\t}, [editor, char, pluginKey, close]);\n\n\tconst handleSelect = useCallback((item: SuggestionItem) => {\n\t\tif (commandRef.current) {\n\t\t\tcommandRef.current(item);\n\t\t}\n\t}, []);\n\n\tif (!isMounted || !open) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={setFloatingRef}\n\t\t\taria-label=\"Suggestions\"\n\t\t\tclassName=\"notra-suggestion-menu\"\n\t\t\tdata-selector={selector}\n\t\t\trole=\"listbox\"\n\t\t\tstyle={style}\n\t\t\t{...getFloatingProps()}\n\t\t\tonPointerDown={(e) => e.preventDefault()}\n\t\t>\n\t\t\t{children({ items, selectedIndex, onSelect: handleSelect })}\n\t\t</div>\n\t);\n}\n"],"mappings":"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","names":["query","editor"]}
@@ -16,6 +16,8 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components/toolbar/toolbar.tsx
19
21
  var toolbar_exports = {};
20
22
  __export(toolbar_exports, {
21
23
  Toolbar: () => Toolbar,
@@ -23,9 +25,9 @@ __export(toolbar_exports, {
23
25
  ToolbarSeparator: () => ToolbarSeparator
24
26
  });
25
27
  module.exports = __toCommonJS(toolbar_exports);
26
- var import_jsx_runtime = require("react/jsx-runtime");
27
28
  var import_react = require("react");
28
- const Toolbar = (0, import_react.forwardRef)(
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ var Toolbar = (0, import_react.forwardRef)(
29
31
  ({ children, className, variant = "fixed", ...props }, ref) => {
30
32
  const classNames = ["tiptap-toolbar", className].filter(Boolean).join(" ");
31
33
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/toolbar/toolbar.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nexport interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tvariant?: 'fixed' | 'floating';\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n\t({ children, className, variant = 'fixed', ...props }, ref) => {\n\t\tconst classNames = ['tiptap-toolbar', className].filter(Boolean).join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\taria-label=\"toolbar\"\n\t\t\t\tclassName={classNames}\n\t\t\t\tdata-variant={variant}\n\t\t\t\trole=\"toolbar\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nToolbar.displayName = 'Toolbar';\n\nexport function ToolbarGroup({\n\tchildren,\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\tconst classNames = ['tiptap-toolbar-group', className]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\treturn (\n\t\t<div className={classNames} role=\"group\" {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport interface ToolbarSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n\torientation?: 'horizontal' | 'vertical';\n}\n\nexport function ToolbarSeparator({\n\torientation = 'vertical',\n\tclassName,\n\t...props\n}: ToolbarSeparatorProps) {\n\tconst classNames = ['tiptap-separator', className].filter(Boolean).join(' ');\n\n\treturn (\n\t\t<div\n\t\t\taria-orientation={orientation === 'vertical' ? orientation : undefined}\n\t\t\tclassName={classNames}\n\t\t\tdata-orientation={orientation}\n\t\t\trole=\"separator\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWG;AAXH,mBAA2B;AAMpB,MAAM,cAAU;AAAA,EACtB,CAAC,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC9D,UAAM,aAAa,CAAC,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEzE,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,cAAW;AAAA,QACX,WAAW;AAAA,QACX,gBAAc;AAAA,QACd,MAAK;AAAA,QACJ,GAAG;AAAA,QAEH;AAAA;AAAA,IACF;AAAA,EAEF;AACD;AAEA,QAAQ,cAAc;AAEf,SAAS,aAAa;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAyC;AACxC,QAAM,aAAa,CAAC,wBAAwB,SAAS,EACnD,OAAO,OAAO,EACd,KAAK,GAAG;AAEV,SACC,4CAAC,SAAI,WAAW,YAAY,MAAK,SAAS,GAAG,OAC3C,UACF;AAEF;AAMO,SAAS,iBAAiB;AAAA,EAChC,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACJ,GAA0B;AACzB,QAAM,aAAa,CAAC,oBAAoB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE3E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,oBAAkB,gBAAgB,aAAa,cAAc;AAAA,MAC7D,WAAW;AAAA,MACX,oBAAkB;AAAA,MAClB,MAAK;AAAA,MACJ,GAAG;AAAA;AAAA,EACL;AAEF;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/toolbar/toolbar.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nexport interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tvariant?: 'fixed' | 'floating';\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n\t({ children, className, variant = 'fixed', ...props }, ref) => {\n\t\tconst classNames = ['tiptap-toolbar', className].filter(Boolean).join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\taria-label=\"toolbar\"\n\t\t\t\tclassName={classNames}\n\t\t\t\tdata-variant={variant}\n\t\t\t\trole=\"toolbar\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nToolbar.displayName = 'Toolbar';\n\nexport function ToolbarGroup({\n\tchildren,\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\tconst classNames = ['tiptap-toolbar-group', className]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\treturn (\n\t\t<div className={classNames} role=\"group\" {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport interface ToolbarSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n\torientation?: 'horizontal' | 'vertical';\n}\n\nexport function ToolbarSeparator({\n\torientation = 'vertical',\n\tclassName,\n\t...props\n}: ToolbarSeparatorProps) {\n\tconst classNames = ['tiptap-separator', className].filter(Boolean).join(' ');\n\n\treturn (\n\t\t<div\n\t\t\taria-orientation={orientation === 'vertical' ? orientation : undefined}\n\t\t\tclassName={classNames}\n\t\t\tdata-orientation={orientation}\n\t\t\trole=\"separator\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2B;AAWxB;AALI,IAAM,cAAU;AAAA,EACtB,CAAC,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC9D,UAAM,aAAa,CAAC,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEzE,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,cAAW;AAAA,QACX,WAAW;AAAA,QACX,gBAAc;AAAA,QACd,MAAK;AAAA,QACJ,GAAG;AAAA,QAEH;AAAA;AAAA,IACF;AAAA,EAEF;AACD;AAEA,QAAQ,cAAc;AAEf,SAAS,aAAa;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAyC;AACxC,QAAM,aAAa,CAAC,wBAAwB,SAAS,EACnD,OAAO,OAAO,EACd,KAAK,GAAG;AAEV,SACC,4CAAC,SAAI,WAAW,YAAY,MAAK,SAAS,GAAG,OAC3C,UACF;AAEF;AAMO,SAAS,iBAAiB;AAAA,EAChC,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACJ,GAA0B;AACzB,QAAM,aAAa,CAAC,oBAAoB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE3E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,oBAAkB,gBAAgB,aAAa,cAAc;AAAA,MAC7D,WAAW;AAAA,MACX,oBAAkB;AAAA,MAClB,MAAK;AAAA,MACJ,GAAG;AAAA;AAAA,EACL;AAEF;","names":[]}
@@ -1,6 +1,7 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ // src/components/toolbar/toolbar.tsx
2
2
  import { forwardRef } from "react";
3
- const Toolbar = forwardRef(
3
+ import { jsx } from "react/jsx-runtime";
4
+ var Toolbar = forwardRef(
4
5
  ({ children, className, variant = "fixed", ...props }, ref) => {
5
6
  const classNames = ["tiptap-toolbar", className].filter(Boolean).join(" ");
6
7
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/toolbar/toolbar.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nexport interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tvariant?: 'fixed' | 'floating';\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n\t({ children, className, variant = 'fixed', ...props }, ref) => {\n\t\tconst classNames = ['tiptap-toolbar', className].filter(Boolean).join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\taria-label=\"toolbar\"\n\t\t\t\tclassName={classNames}\n\t\t\t\tdata-variant={variant}\n\t\t\t\trole=\"toolbar\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nToolbar.displayName = 'Toolbar';\n\nexport function ToolbarGroup({\n\tchildren,\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\tconst classNames = ['tiptap-toolbar-group', className]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\treturn (\n\t\t<div className={classNames} role=\"group\" {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport interface ToolbarSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n\torientation?: 'horizontal' | 'vertical';\n}\n\nexport function ToolbarSeparator({\n\torientation = 'vertical',\n\tclassName,\n\t...props\n}: ToolbarSeparatorProps) {\n\tconst classNames = ['tiptap-separator', className].filter(Boolean).join(' ');\n\n\treturn (\n\t\t<div\n\t\t\taria-orientation={orientation === 'vertical' ? orientation : undefined}\n\t\t\tclassName={classNames}\n\t\t\tdata-orientation={orientation}\n\t\t\trole=\"separator\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"AAWG;AAXH,SAAS,kBAAkB;AAMpB,MAAM,UAAU;AAAA,EACtB,CAAC,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC9D,UAAM,aAAa,CAAC,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEzE,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,cAAW;AAAA,QACX,WAAW;AAAA,QACX,gBAAc;AAAA,QACd,MAAK;AAAA,QACJ,GAAG;AAAA,QAEH;AAAA;AAAA,IACF;AAAA,EAEF;AACD;AAEA,QAAQ,cAAc;AAEf,SAAS,aAAa;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAyC;AACxC,QAAM,aAAa,CAAC,wBAAwB,SAAS,EACnD,OAAO,OAAO,EACd,KAAK,GAAG;AAEV,SACC,oBAAC,SAAI,WAAW,YAAY,MAAK,SAAS,GAAG,OAC3C,UACF;AAEF;AAMO,SAAS,iBAAiB;AAAA,EAChC,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACJ,GAA0B;AACzB,QAAM,aAAa,CAAC,oBAAoB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE3E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,oBAAkB,gBAAgB,aAAa,cAAc;AAAA,MAC7D,WAAW;AAAA,MACX,oBAAkB;AAAA,MAClB,MAAK;AAAA,MACJ,GAAG;AAAA;AAAA,EACL;AAEF;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/toolbar/toolbar.tsx"],"sourcesContent":["import { forwardRef } from 'react';\n\nexport interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tvariant?: 'fixed' | 'floating';\n}\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n\t({ children, className, variant = 'fixed', ...props }, ref) => {\n\t\tconst classNames = ['tiptap-toolbar', className].filter(Boolean).join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\taria-label=\"toolbar\"\n\t\t\t\tclassName={classNames}\n\t\t\t\tdata-variant={variant}\n\t\t\t\trole=\"toolbar\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nToolbar.displayName = 'Toolbar';\n\nexport function ToolbarGroup({\n\tchildren,\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\tconst classNames = ['tiptap-toolbar-group', className]\n\t\t.filter(Boolean)\n\t\t.join(' ');\n\n\treturn (\n\t\t<div className={classNames} role=\"group\" {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport interface ToolbarSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {\n\torientation?: 'horizontal' | 'vertical';\n}\n\nexport function ToolbarSeparator({\n\torientation = 'vertical',\n\tclassName,\n\t...props\n}: ToolbarSeparatorProps) {\n\tconst classNames = ['tiptap-separator', className].filter(Boolean).join(' ');\n\n\treturn (\n\t\t<div\n\t\t\taria-orientation={orientation === 'vertical' ? orientation : undefined}\n\t\t\tclassName={classNames}\n\t\t\tdata-orientation={orientation}\n\t\t\trole=\"separator\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAWxB;AALI,IAAM,UAAU;AAAA,EACtB,CAAC,EAAE,UAAU,WAAW,UAAU,SAAS,GAAG,MAAM,GAAG,QAAQ;AAC9D,UAAM,aAAa,CAAC,kBAAkB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEzE,WACC;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,cAAW;AAAA,QACX,WAAW;AAAA,QACX,gBAAc;AAAA,QACd,MAAK;AAAA,QACJ,GAAG;AAAA,QAEH;AAAA;AAAA,IACF;AAAA,EAEF;AACD;AAEA,QAAQ,cAAc;AAEf,SAAS,aAAa;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAyC;AACxC,QAAM,aAAa,CAAC,wBAAwB,SAAS,EACnD,OAAO,OAAO,EACd,KAAK,GAAG;AAEV,SACC,oBAAC,SAAI,WAAW,YAAY,MAAK,SAAS,GAAG,OAC3C,UACF;AAEF;AAMO,SAAS,iBAAiB;AAAA,EAChC,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACJ,GAA0B;AACzB,QAAM,aAAa,CAAC,oBAAoB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE3E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,oBAAkB,gBAAgB,aAAa,cAAc;AAAA,MAC7D,WAAW;AAAA,MACX,oBAAkB;AAAA,MAClB,MAAK;AAAA,MACJ,GAAG;AAAA;AAAA,EACL;AAEF;","names":[]}
@@ -16,17 +16,19 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/components/ui/button.tsx
19
21
  var button_exports = {};
20
22
  __export(button_exports, {
21
23
  Button: () => Button,
22
24
  buttonVariants: () => buttonVariants
23
25
  });
24
26
  module.exports = __toCommonJS(button_exports);
25
- var import_jsx_runtime = require("react/jsx-runtime");
26
27
  var import_class_variance_authority = require("class-variance-authority");
27
28
  var import_radix_ui = require("radix-ui");
28
- var import_utils = require("../../lib/utils");
29
- const buttonVariants = (0, import_class_variance_authority.cva)(
29
+ var import_utils = require("../../lib/utils.cjs");
30
+ var import_jsx_runtime = require("react/jsx-runtime");
31
+ var buttonVariants = (0, import_class_variance_authority.cva)(
30
32
  "nt:group/button nt:inline-flex nt:shrink-0 nt:items-center nt:justify-center nt:rounded-lg nt:border nt:border-transparent nt:bg-clip-padding nt:text-sm nt:font-medium nt:whitespace-nowrap nt:transition-all nt:outline-none nt:select-none nt:focus-visible:border-ring nt:focus-visible:ring-3 nt:focus-visible:ring-ring/50 nt:active:not-aria-[haspopup]:translate-y-px nt:disabled:pointer-events-none nt:disabled:opacity-50 nt:aria-invalid:border-destructive nt:aria-invalid:ring-3 nt:aria-invalid:ring-destructive/20 nt:dark:aria-invalid:border-destructive/50 nt:dark:aria-invalid:ring-destructive/40 nt:[&_svg]:pointer-events-none nt:[&_svg]:shrink-0 nt:[&_svg:not([class*=size-])]:size-4",
31
33
  {
32
34
  variants: {