notra-editor 0.2.0 → 0.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 (221) hide show
  1. package/README.md +4 -8
  2. package/dist/components/blockquote-button/blockquote-button.cjs +91 -0
  3. package/dist/components/blockquote-button/blockquote-button.cjs.map +1 -0
  4. package/dist/components/blockquote-button/blockquote-button.d.cts +9 -0
  5. package/dist/components/blockquote-button/blockquote-button.d.ts +9 -0
  6. package/dist/components/blockquote-button/blockquote-button.mjs +67 -0
  7. package/dist/components/blockquote-button/blockquote-button.mjs.map +1 -0
  8. package/dist/components/code-block-button/code-block-button.cjs +91 -0
  9. package/dist/components/code-block-button/code-block-button.cjs.map +1 -0
  10. package/dist/components/code-block-button/code-block-button.d.cts +9 -0
  11. package/dist/components/code-block-button/code-block-button.d.ts +9 -0
  12. package/dist/components/code-block-button/code-block-button.mjs +67 -0
  13. package/dist/components/code-block-button/code-block-button.mjs.map +1 -0
  14. package/dist/components/code-block-view.cjs +39 -0
  15. package/dist/components/code-block-view.cjs.map +1 -0
  16. package/dist/components/code-block-view.d.cts +12 -0
  17. package/dist/components/code-block-view.d.ts +12 -0
  18. package/dist/components/code-block-view.mjs +17 -0
  19. package/dist/components/code-block-view.mjs.map +1 -0
  20. package/dist/components/copy-button.cjs +49 -0
  21. package/dist/components/copy-button.cjs.map +1 -0
  22. package/dist/components/copy-button.d.cts +9 -0
  23. package/dist/components/copy-button.d.ts +9 -0
  24. package/dist/components/copy-button.mjs +25 -0
  25. package/dist/components/copy-button.mjs.map +1 -0
  26. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.cjs +67 -0
  27. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.cjs.map +1 -0
  28. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.d.cts +17 -0
  29. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.d.ts +17 -0
  30. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.mjs +51 -0
  31. package/dist/components/heading-dropdown-menu/heading-dropdown-menu.mjs.map +1 -0
  32. package/dist/components/heading-dropdown-menu/heading-menu-item.cjs +56 -0
  33. package/dist/components/heading-dropdown-menu/heading-menu-item.cjs.map +1 -0
  34. package/dist/components/heading-dropdown-menu/heading-menu-item.d.cts +12 -0
  35. package/dist/components/heading-dropdown-menu/heading-menu-item.d.ts +12 -0
  36. package/dist/components/heading-dropdown-menu/heading-menu-item.mjs +32 -0
  37. package/dist/components/heading-dropdown-menu/heading-menu-item.mjs.map +1 -0
  38. package/dist/components/heading-dropdown-menu/use-heading.cjs +109 -0
  39. package/dist/components/heading-dropdown-menu/use-heading.cjs.map +1 -0
  40. package/dist/components/heading-dropdown-menu/use-heading.d.cts +19 -0
  41. package/dist/components/heading-dropdown-menu/use-heading.d.ts +19 -0
  42. package/dist/components/heading-dropdown-menu/use-heading.mjs +83 -0
  43. package/dist/components/heading-dropdown-menu/use-heading.mjs.map +1 -0
  44. package/dist/components/link-popover/link-popover.cjs +148 -0
  45. package/dist/components/link-popover/link-popover.cjs.map +1 -0
  46. package/dist/components/link-popover/link-popover.d.cts +9 -0
  47. package/dist/components/link-popover/link-popover.d.ts +9 -0
  48. package/dist/components/link-popover/link-popover.mjs +129 -0
  49. package/dist/components/link-popover/link-popover.mjs.map +1 -0
  50. package/dist/components/link-popover/use-link-popover.cjs +71 -0
  51. package/dist/components/link-popover/use-link-popover.cjs.map +1 -0
  52. package/dist/components/link-popover/use-link-popover.d.cts +17 -0
  53. package/dist/components/link-popover/use-link-popover.d.ts +17 -0
  54. package/dist/components/link-popover/use-link-popover.mjs +47 -0
  55. package/dist/components/link-popover/use-link-popover.mjs.map +1 -0
  56. package/dist/components/list-dropdown-menu/list-dropdown-menu.cjs +73 -0
  57. package/dist/components/list-dropdown-menu/list-dropdown-menu.cjs.map +1 -0
  58. package/dist/components/list-dropdown-menu/list-dropdown-menu.d.cts +17 -0
  59. package/dist/components/list-dropdown-menu/list-dropdown-menu.d.ts +17 -0
  60. package/dist/components/list-dropdown-menu/list-dropdown-menu.mjs +57 -0
  61. package/dist/components/list-dropdown-menu/list-dropdown-menu.mjs.map +1 -0
  62. package/dist/components/list-dropdown-menu/list-menu-item.cjs +56 -0
  63. package/dist/components/list-dropdown-menu/list-menu-item.cjs.map +1 -0
  64. package/dist/components/list-dropdown-menu/list-menu-item.d.cts +12 -0
  65. package/dist/components/list-dropdown-menu/list-menu-item.d.ts +12 -0
  66. package/dist/components/list-dropdown-menu/list-menu-item.mjs +32 -0
  67. package/dist/components/list-dropdown-menu/list-menu-item.mjs.map +1 -0
  68. package/dist/components/list-dropdown-menu/use-list.cjs +111 -0
  69. package/dist/components/list-dropdown-menu/use-list.cjs.map +1 -0
  70. package/dist/components/list-dropdown-menu/use-list.d.cts +19 -0
  71. package/dist/components/list-dropdown-menu/use-list.d.ts +19 -0
  72. package/dist/components/list-dropdown-menu/use-list.mjs +85 -0
  73. package/dist/components/list-dropdown-menu/use-list.mjs.map +1 -0
  74. package/dist/components/mark-button/mark-button.cjs +72 -0
  75. package/dist/components/mark-button/mark-button.cjs.map +1 -0
  76. package/dist/components/mark-button/mark-button.d.cts +12 -0
  77. package/dist/components/mark-button/mark-button.d.ts +12 -0
  78. package/dist/components/mark-button/mark-button.mjs +48 -0
  79. package/dist/components/mark-button/mark-button.mjs.map +1 -0
  80. package/dist/components/mark-button/use-mark.cjs +71 -0
  81. package/dist/components/mark-button/use-mark.cjs.map +1 -0
  82. package/dist/components/mark-button/use-mark.d.cts +17 -0
  83. package/dist/components/mark-button/use-mark.d.ts +17 -0
  84. package/dist/components/mark-button/use-mark.mjs +47 -0
  85. package/dist/components/mark-button/use-mark.mjs.map +1 -0
  86. package/dist/components/toolbar/toolbar.cjs +77 -0
  87. package/dist/components/toolbar/toolbar.cjs.map +1 -0
  88. package/dist/components/toolbar/toolbar.d.cts +14 -0
  89. package/dist/components/toolbar/toolbar.d.ts +14 -0
  90. package/dist/components/toolbar/toolbar.mjs +51 -0
  91. package/dist/components/toolbar/toolbar.mjs.map +1 -0
  92. package/dist/components/ui/button.cjs +82 -0
  93. package/dist/components/ui/button.cjs.map +1 -0
  94. package/dist/components/ui/button.d.cts +14 -0
  95. package/dist/components/ui/button.d.ts +14 -0
  96. package/dist/components/ui/button.mjs +57 -0
  97. package/dist/components/ui/button.mjs.map +1 -0
  98. package/dist/components/ui/dropdown-menu.cjs +290 -0
  99. package/dist/components/ui/dropdown-menu.cjs.map +1 -0
  100. package/dist/components/ui/dropdown-menu.d.cts +32 -0
  101. package/dist/components/ui/dropdown-menu.d.ts +32 -0
  102. package/dist/components/ui/dropdown-menu.mjs +252 -0
  103. package/dist/components/ui/dropdown-menu.mjs.map +1 -0
  104. package/dist/components/ui/input.cjs +44 -0
  105. package/dist/components/ui/input.cjs.map +1 -0
  106. package/dist/components/ui/input.d.cts +6 -0
  107. package/dist/components/ui/input.d.ts +6 -0
  108. package/dist/components/ui/input.mjs +20 -0
  109. package/dist/components/ui/input.mjs.map +1 -0
  110. package/dist/components/ui/popover.cjs +72 -0
  111. package/dist/components/ui/popover.cjs.map +1 -0
  112. package/dist/components/ui/popover.d.cts +10 -0
  113. package/dist/components/ui/popover.d.ts +10 -0
  114. package/dist/components/ui/popover.mjs +45 -0
  115. package/dist/components/ui/popover.mjs.map +1 -0
  116. package/dist/components/ui/separator.cjs +51 -0
  117. package/dist/components/ui/separator.cjs.map +1 -0
  118. package/dist/components/ui/separator.d.cts +7 -0
  119. package/dist/components/ui/separator.d.ts +7 -0
  120. package/dist/components/ui/separator.mjs +27 -0
  121. package/dist/components/ui/separator.mjs.map +1 -0
  122. package/dist/components/ui/spacer.cjs +32 -0
  123. package/dist/components/ui/spacer.cjs.map +1 -0
  124. package/dist/components/ui/spacer.d.cts +5 -0
  125. package/dist/components/ui/spacer.d.ts +5 -0
  126. package/dist/components/ui/spacer.mjs +8 -0
  127. package/dist/components/ui/spacer.mjs.map +1 -0
  128. package/dist/components/undo-redo-button/undo-redo-button.cjs +63 -0
  129. package/dist/components/undo-redo-button/undo-redo-button.cjs.map +1 -0
  130. package/dist/components/undo-redo-button/undo-redo-button.d.cts +12 -0
  131. package/dist/components/undo-redo-button/undo-redo-button.d.ts +12 -0
  132. package/dist/components/undo-redo-button/undo-redo-button.mjs +39 -0
  133. package/dist/components/undo-redo-button/undo-redo-button.mjs.map +1 -0
  134. package/dist/components/undo-redo-button/use-undo-redo.cjs +68 -0
  135. package/dist/components/undo-redo-button/use-undo-redo.cjs.map +1 -0
  136. package/dist/components/undo-redo-button/use-undo-redo.d.cts +17 -0
  137. package/dist/components/undo-redo-button/use-undo-redo.d.ts +17 -0
  138. package/dist/components/undo-redo-button/use-undo-redo.mjs +44 -0
  139. package/dist/components/undo-redo-button/use-undo-redo.mjs.map +1 -0
  140. package/dist/extensions/code-block.cjs +46 -0
  141. package/dist/extensions/code-block.cjs.map +1 -0
  142. package/dist/extensions/code-block.d.cts +6 -0
  143. package/dist/extensions/code-block.d.ts +6 -0
  144. package/dist/extensions/code-block.mjs +12 -0
  145. package/dist/extensions/code-block.mjs.map +1 -0
  146. package/dist/extensions/editor.cjs +53 -0
  147. package/dist/extensions/editor.cjs.map +1 -0
  148. package/dist/extensions/editor.d.cts +9 -0
  149. package/dist/extensions/editor.d.ts +9 -0
  150. package/dist/extensions/editor.mjs +19 -0
  151. package/dist/extensions/editor.mjs.map +1 -0
  152. package/dist/extensions/index.cjs +32 -0
  153. package/dist/extensions/index.cjs.map +1 -0
  154. package/dist/extensions/index.d.cts +7 -0
  155. package/dist/extensions/index.d.ts +7 -0
  156. package/dist/extensions/index.mjs +7 -0
  157. package/dist/extensions/index.mjs.map +1 -0
  158. package/dist/extensions/shared.cjs +64 -0
  159. package/dist/extensions/shared.cjs.map +1 -0
  160. package/dist/extensions/shared.d.cts +8 -0
  161. package/dist/extensions/shared.d.ts +8 -0
  162. package/dist/extensions/shared.mjs +29 -0
  163. package/dist/extensions/shared.mjs.map +1 -0
  164. package/dist/hooks/use-copy-to-clipboard.cjs +50 -0
  165. package/dist/hooks/use-copy-to-clipboard.cjs.map +1 -0
  166. package/dist/hooks/use-copy-to-clipboard.d.cts +10 -0
  167. package/dist/hooks/use-copy-to-clipboard.d.ts +10 -0
  168. package/dist/hooks/use-copy-to-clipboard.mjs +26 -0
  169. package/dist/hooks/use-copy-to-clipboard.mjs.map +1 -0
  170. package/dist/hooks/use-markdown-editor.cjs +80 -0
  171. package/dist/hooks/use-markdown-editor.cjs.map +1 -0
  172. package/dist/hooks/use-markdown-editor.d.cts +13 -0
  173. package/dist/hooks/use-markdown-editor.d.ts +13 -0
  174. package/dist/hooks/use-markdown-editor.mjs +56 -0
  175. package/dist/hooks/use-markdown-editor.mjs.map +1 -0
  176. package/dist/icons/redo-icon.cjs +54 -0
  177. package/dist/icons/redo-icon.cjs.map +1 -0
  178. package/dist/icons/redo-icon.d.cts +7 -0
  179. package/dist/icons/redo-icon.d.ts +7 -0
  180. package/dist/icons/redo-icon.mjs +30 -0
  181. package/dist/icons/redo-icon.mjs.map +1 -0
  182. package/dist/icons/undo-icon.cjs +54 -0
  183. package/dist/icons/undo-icon.cjs.map +1 -0
  184. package/dist/icons/undo-icon.d.cts +7 -0
  185. package/dist/icons/undo-icon.d.ts +7 -0
  186. package/dist/icons/undo-icon.mjs +30 -0
  187. package/dist/icons/undo-icon.mjs.map +1 -0
  188. package/dist/index.cjs +25 -2127
  189. package/dist/index.cjs.map +1 -1
  190. package/dist/index.d.cts +22 -110
  191. package/dist/index.d.ts +22 -110
  192. package/dist/index.mjs +16 -2098
  193. package/dist/index.mjs.map +1 -1
  194. package/dist/lib/utils.cjs +33 -0
  195. package/dist/lib/utils.cjs.map +1 -0
  196. package/dist/lib/utils.d.cts +5 -0
  197. package/dist/lib/utils.d.ts +5 -0
  198. package/dist/lib/utils.mjs +9 -0
  199. package/dist/lib/utils.mjs.map +1 -0
  200. package/dist/notra-editor.cjs +88 -0
  201. package/dist/notra-editor.cjs.map +1 -0
  202. package/dist/notra-editor.d.cts +17 -0
  203. package/dist/notra-editor.d.ts +17 -0
  204. package/dist/notra-editor.mjs +68 -0
  205. package/dist/notra-editor.mjs.map +1 -0
  206. package/dist/notra-reader.cjs +47 -0
  207. package/dist/notra-reader.cjs.map +1 -0
  208. package/dist/notra-reader.d.cts +11 -0
  209. package/dist/notra-reader.d.ts +11 -0
  210. package/dist/notra-reader.mjs +23 -0
  211. package/dist/notra-reader.mjs.map +1 -0
  212. package/dist/styles/globals.css +1170 -0
  213. package/dist/themes/default/editor.css +2 -116
  214. package/dist/themes/default/reader.css +2 -0
  215. package/dist/utils/markdown-to-json.cjs +50 -0
  216. package/dist/utils/markdown-to-json.cjs.map +1 -0
  217. package/dist/utils/markdown-to-json.d.cts +7 -0
  218. package/dist/utils/markdown-to-json.d.ts +7 -0
  219. package/dist/utils/markdown-to-json.mjs +26 -0
  220. package/dist/utils/markdown-to-json.mjs.map +1 -0
  221. package/package.json +18 -5
package/README.md CHANGED
@@ -19,7 +19,6 @@ npm install notra-editor
19
19
 
20
20
  ```tsx
21
21
  import { NotraEditor } from 'notra-editor';
22
- import 'notra-editor/themes/default/shared.css';
23
22
  import 'notra-editor/themes/default/editor.css';
24
23
  import { useState } from 'react';
25
24
 
@@ -40,7 +39,6 @@ function App() {
40
39
 
41
40
  ```tsx
42
41
  import { NotraReader } from 'notra-editor';
43
- import 'notra-editor/themes/default/shared.css';
44
42
  import 'notra-editor/themes/default/reader.css';
45
43
 
46
44
  function Article({ markdown }: { markdown: string }) {
@@ -77,16 +75,14 @@ function Article({ markdown }: { markdown: string }) {
77
75
 
78
76
  ## Themes
79
77
 
80
- Import theme CSS files to style the editor and reader:
78
+ Import theme CSS files to style the editor and reader. Each entry already
79
+ includes the shared base styles, so a single import is enough:
81
80
 
82
81
  ```ts
83
- // Shared styles (required for both editor and reader)
84
- import 'notra-editor/themes/default/shared.css';
85
-
86
- // Editor-specific styles
82
+ // Editor styles (includes shared base)
87
83
  import 'notra-editor/themes/default/editor.css';
88
84
 
89
- // Reader-specific styles
85
+ // Reader styles (includes shared base)
90
86
  import 'notra-editor/themes/default/reader.css';
91
87
  ```
92
88
 
@@ -0,0 +1,91 @@
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
+ var blockquote_button_exports = {};
21
+ __export(blockquote_button_exports, {
22
+ BlockquoteButton: () => BlockquoteButton
23
+ });
24
+ module.exports = __toCommonJS(blockquote_button_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_lucide_react = require("lucide-react");
27
+ var import_react = require("react");
28
+ var import_button = require("../ui/button");
29
+ function canToggleBlockquote(editor) {
30
+ if (!editor || !editor.isEditable) return false;
31
+ return editor.can().toggleWrap("blockquote") || editor.can().clearNodes();
32
+ }
33
+ const BlockquoteButton = (0, import_react.forwardRef)(({ editor, onClick, ...buttonProps }, ref) => {
34
+ const [isActive, setIsActive] = (0, import_react.useState)(false);
35
+ const [canToggle, setCanToggle] = (0, import_react.useState)(false);
36
+ (0, import_react.useEffect)(() => {
37
+ if (!editor) return;
38
+ const update = () => {
39
+ setIsActive(editor.isActive("blockquote"));
40
+ setCanToggle(canToggleBlockquote(editor));
41
+ };
42
+ update();
43
+ editor.on("selectionUpdate", update);
44
+ editor.on("transaction", update);
45
+ return () => {
46
+ editor.off("selectionUpdate", update);
47
+ editor.off("transaction", update);
48
+ };
49
+ }, [editor]);
50
+ const handleClick = (0, import_react.useCallback)(
51
+ (event) => {
52
+ onClick?.(event);
53
+ if (event.defaultPrevented) return;
54
+ if (!editor) return;
55
+ if (editor.isActive("blockquote")) {
56
+ editor.chain().focus().lift("blockquote").run();
57
+ } else {
58
+ editor.chain().focus().clearNodes().wrapIn("blockquote").run();
59
+ }
60
+ },
61
+ [editor, onClick]
62
+ );
63
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
64
+ import_button.Button,
65
+ {
66
+ ref,
67
+ "aria-label": "Blockquote",
68
+ "aria-pressed": isActive,
69
+ "data-active-state": isActive ? "on" : "off",
70
+ disabled: !canToggle,
71
+ size: "icon",
72
+ tabIndex: -1,
73
+ type: "button",
74
+ variant: "ghost",
75
+ onClick: handleClick,
76
+ ...buttonProps,
77
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ import_lucide_react.TextQuote,
79
+ {
80
+ className: isActive ? "nt:text-[var(--tt-brand-color-500)]" : void 0
81
+ }
82
+ )
83
+ }
84
+ );
85
+ });
86
+ BlockquoteButton.displayName = "BlockquoteButton";
87
+ // Annotate the CommonJS export names for ESM import in node:
88
+ 0 && (module.exports = {
89
+ BlockquoteButton
90
+ });
91
+ //# sourceMappingURL=blockquote-button.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/blockquote-button/blockquote-button.tsx"],"sourcesContent":["'use client';\n\nimport { TextQuote } from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { Button } from '../ui/button';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface BlockquoteButtonProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nfunction canToggleBlockquote(editor: Editor | null): boolean {\n\tif (!editor || !editor.isEditable) return false;\n\n\treturn editor.can().toggleWrap('blockquote') || editor.can().clearNodes();\n}\n\nexport const BlockquoteButton = forwardRef<\n\tHTMLButtonElement,\n\tBlockquoteButtonProps\n>(({ editor, onClick, ...buttonProps }, ref) => {\n\tconst [isActive, setIsActive] = useState(false);\n\tconst [canToggle, setCanToggle] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tconst update = () => {\n\t\t\tsetIsActive(editor.isActive('blockquote'));\n\t\t\tsetCanToggle(canToggleBlockquote(editor));\n\t\t};\n\n\t\tupdate();\n\n\t\teditor.on('selectionUpdate', update);\n\t\teditor.on('transaction', update);\n\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', update);\n\t\t\teditor.off('transaction', update);\n\t\t};\n\t}, [editor]);\n\n\tconst handleClick = useCallback(\n\t\t(event: React.MouseEvent<HTMLButtonElement>) => {\n\t\t\tonClick?.(event);\n\n\t\t\tif (event.defaultPrevented) return;\n\n\t\t\tif (!editor) return;\n\n\t\t\tif (editor.isActive('blockquote')) {\n\t\t\t\teditor.chain().focus().lift('blockquote').run();\n\t\t\t} else {\n\t\t\t\t// clearNodes first to convert any block type to paragraph,\n\t\t\t\t// then wrap in blockquote\n\t\t\t\teditor.chain().focus().clearNodes().wrapIn('blockquote').run();\n\t\t\t}\n\t\t},\n\t\t[editor, onClick]\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tref={ref}\n\t\t\taria-label=\"Blockquote\"\n\t\t\taria-pressed={isActive}\n\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\tdisabled={!canToggle}\n\t\t\tsize=\"icon\"\n\t\t\ttabIndex={-1}\n\t\t\ttype=\"button\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={handleClick}\n\t\t\t{...buttonProps}\n\t\t>\n\t\t\t<TextQuote\n\t\t\t\tclassName={isActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined}\n\t\t\t/>\n\t\t</Button>\n\t);\n});\n\nBlockquoteButton.displayName = 'BlockquoteButton';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiFG;AA/EH,0BAA0B;AAC1B,mBAA6D;AAE7D,oBAAuB;AAWvB,SAAS,oBAAoB,QAAgC;AAC5D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,SAAO,OAAO,IAAI,EAAE,WAAW,YAAY,KAAK,OAAO,IAAI,EAAE,WAAW;AACzE;AAEO,MAAM,uBAAmB,yBAG9B,CAAC,EAAE,QAAQ,SAAS,GAAG,YAAY,GAAG,QAAQ;AAC/C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAEhD,8BAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAS,MAAM;AACpB,kBAAY,OAAO,SAAS,YAAY,CAAC;AACzC,mBAAa,oBAAoB,MAAM,CAAC;AAAA,IACzC;AAEA,WAAO;AAEP,WAAO,GAAG,mBAAmB,MAAM;AACnC,WAAO,GAAG,eAAe,MAAM;AAE/B,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,MAAM;AACpC,aAAO,IAAI,eAAe,MAAM;AAAA,IACjC;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,kBAAc;AAAA,IACnB,CAAC,UAA+C;AAC/C,gBAAU,KAAK;AAEf,UAAI,MAAM,iBAAkB;AAE5B,UAAI,CAAC,OAAQ;AAEb,UAAI,OAAO,SAAS,YAAY,GAAG;AAClC,eAAO,MAAM,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,IAAI;AAAA,MAC/C,OAAO;AAGN,eAAO,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,YAAY,EAAE,IAAI;AAAA,MAC9D;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,cAAW;AAAA,MACX,gBAAc;AAAA,MACd,qBAAmB,WAAW,OAAO;AAAA,MACrC,UAAU,CAAC;AAAA,MACX,MAAK;AAAA,MACL,UAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,WAAW,wCAAwC;AAAA;AAAA,MAC/D;AAAA;AAAA,EACD;AAEF,CAAC;AAED,iBAAiB,cAAc;","names":[]}
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+
4
+ interface BlockquoteButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
5
+ editor: Editor | null;
6
+ }
7
+ declare const BlockquoteButton: react.ForwardRefExoticComponent<BlockquoteButtonProps & react.RefAttributes<HTMLButtonElement>>;
8
+
9
+ export { BlockquoteButton, type BlockquoteButtonProps };
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+
4
+ interface BlockquoteButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
5
+ editor: Editor | null;
6
+ }
7
+ declare const BlockquoteButton: react.ForwardRefExoticComponent<BlockquoteButtonProps & react.RefAttributes<HTMLButtonElement>>;
8
+
9
+ export { BlockquoteButton, type BlockquoteButtonProps };
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { TextQuote } from "lucide-react";
4
+ import { forwardRef, useCallback, useEffect, useState } from "react";
5
+ import { Button } from "../ui/button";
6
+ function canToggleBlockquote(editor) {
7
+ if (!editor || !editor.isEditable) return false;
8
+ return editor.can().toggleWrap("blockquote") || editor.can().clearNodes();
9
+ }
10
+ const BlockquoteButton = forwardRef(({ editor, onClick, ...buttonProps }, ref) => {
11
+ const [isActive, setIsActive] = useState(false);
12
+ const [canToggle, setCanToggle] = useState(false);
13
+ useEffect(() => {
14
+ if (!editor) return;
15
+ const update = () => {
16
+ setIsActive(editor.isActive("blockquote"));
17
+ setCanToggle(canToggleBlockquote(editor));
18
+ };
19
+ update();
20
+ editor.on("selectionUpdate", update);
21
+ editor.on("transaction", update);
22
+ return () => {
23
+ editor.off("selectionUpdate", update);
24
+ editor.off("transaction", update);
25
+ };
26
+ }, [editor]);
27
+ const handleClick = useCallback(
28
+ (event) => {
29
+ onClick?.(event);
30
+ if (event.defaultPrevented) return;
31
+ if (!editor) return;
32
+ if (editor.isActive("blockquote")) {
33
+ editor.chain().focus().lift("blockquote").run();
34
+ } else {
35
+ editor.chain().focus().clearNodes().wrapIn("blockquote").run();
36
+ }
37
+ },
38
+ [editor, onClick]
39
+ );
40
+ return /* @__PURE__ */ jsx(
41
+ Button,
42
+ {
43
+ ref,
44
+ "aria-label": "Blockquote",
45
+ "aria-pressed": isActive,
46
+ "data-active-state": isActive ? "on" : "off",
47
+ disabled: !canToggle,
48
+ size: "icon",
49
+ tabIndex: -1,
50
+ type: "button",
51
+ variant: "ghost",
52
+ onClick: handleClick,
53
+ ...buttonProps,
54
+ children: /* @__PURE__ */ jsx(
55
+ TextQuote,
56
+ {
57
+ className: isActive ? "nt:text-[var(--tt-brand-color-500)]" : void 0
58
+ }
59
+ )
60
+ }
61
+ );
62
+ });
63
+ BlockquoteButton.displayName = "BlockquoteButton";
64
+ export {
65
+ BlockquoteButton
66
+ };
67
+ //# sourceMappingURL=blockquote-button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/blockquote-button/blockquote-button.tsx"],"sourcesContent":["'use client';\n\nimport { TextQuote } from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { Button } from '../ui/button';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface BlockquoteButtonProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nfunction canToggleBlockquote(editor: Editor | null): boolean {\n\tif (!editor || !editor.isEditable) return false;\n\n\treturn editor.can().toggleWrap('blockquote') || editor.can().clearNodes();\n}\n\nexport const BlockquoteButton = forwardRef<\n\tHTMLButtonElement,\n\tBlockquoteButtonProps\n>(({ editor, onClick, ...buttonProps }, ref) => {\n\tconst [isActive, setIsActive] = useState(false);\n\tconst [canToggle, setCanToggle] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tconst update = () => {\n\t\t\tsetIsActive(editor.isActive('blockquote'));\n\t\t\tsetCanToggle(canToggleBlockquote(editor));\n\t\t};\n\n\t\tupdate();\n\n\t\teditor.on('selectionUpdate', update);\n\t\teditor.on('transaction', update);\n\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', update);\n\t\t\teditor.off('transaction', update);\n\t\t};\n\t}, [editor]);\n\n\tconst handleClick = useCallback(\n\t\t(event: React.MouseEvent<HTMLButtonElement>) => {\n\t\t\tonClick?.(event);\n\n\t\t\tif (event.defaultPrevented) return;\n\n\t\t\tif (!editor) return;\n\n\t\t\tif (editor.isActive('blockquote')) {\n\t\t\t\teditor.chain().focus().lift('blockquote').run();\n\t\t\t} else {\n\t\t\t\t// clearNodes first to convert any block type to paragraph,\n\t\t\t\t// then wrap in blockquote\n\t\t\t\teditor.chain().focus().clearNodes().wrapIn('blockquote').run();\n\t\t\t}\n\t\t},\n\t\t[editor, onClick]\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tref={ref}\n\t\t\taria-label=\"Blockquote\"\n\t\t\taria-pressed={isActive}\n\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\tdisabled={!canToggle}\n\t\t\tsize=\"icon\"\n\t\t\ttabIndex={-1}\n\t\t\ttype=\"button\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={handleClick}\n\t\t\t{...buttonProps}\n\t\t>\n\t\t\t<TextQuote\n\t\t\t\tclassName={isActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined}\n\t\t\t/>\n\t\t</Button>\n\t);\n});\n\nBlockquoteButton.displayName = 'BlockquoteButton';\n"],"mappings":";AAiFG;AA/EH,SAAS,iBAAiB;AAC1B,SAAS,YAAY,aAAa,WAAW,gBAAgB;AAE7D,SAAS,cAAc;AAWvB,SAAS,oBAAoB,QAAgC;AAC5D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,SAAO,OAAO,IAAI,EAAE,WAAW,YAAY,KAAK,OAAO,IAAI,EAAE,WAAW;AACzE;AAEO,MAAM,mBAAmB,WAG9B,CAAC,EAAE,QAAQ,SAAS,GAAG,YAAY,GAAG,QAAQ;AAC/C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,YAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAS,MAAM;AACpB,kBAAY,OAAO,SAAS,YAAY,CAAC;AACzC,mBAAa,oBAAoB,MAAM,CAAC;AAAA,IACzC;AAEA,WAAO;AAEP,WAAO,GAAG,mBAAmB,MAAM;AACnC,WAAO,GAAG,eAAe,MAAM;AAE/B,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,MAAM;AACpC,aAAO,IAAI,eAAe,MAAM;AAAA,IACjC;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAc;AAAA,IACnB,CAAC,UAA+C;AAC/C,gBAAU,KAAK;AAEf,UAAI,MAAM,iBAAkB;AAE5B,UAAI,CAAC,OAAQ;AAEb,UAAI,OAAO,SAAS,YAAY,GAAG;AAClC,eAAO,MAAM,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,IAAI;AAAA,MAC/C,OAAO;AAGN,eAAO,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,YAAY,EAAE,IAAI;AAAA,MAC9D;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,cAAW;AAAA,MACX,gBAAc;AAAA,MACd,qBAAmB,WAAW,OAAO;AAAA,MACrC,UAAU,CAAC;AAAA,MACX,MAAK;AAAA,MACL,UAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,WAAW,wCAAwC;AAAA;AAAA,MAC/D;AAAA;AAAA,EACD;AAEF,CAAC;AAED,iBAAiB,cAAc;","names":[]}
@@ -0,0 +1,91 @@
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
+ var code_block_button_exports = {};
21
+ __export(code_block_button_exports, {
22
+ CodeBlockButton: () => CodeBlockButton
23
+ });
24
+ module.exports = __toCommonJS(code_block_button_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_lucide_react = require("lucide-react");
27
+ var import_react = require("react");
28
+ var import_button = require("../ui/button");
29
+ function canToggleCodeBlock(editor) {
30
+ if (!editor || !editor.isEditable) return false;
31
+ return editor.can().toggleNode("codeBlock", "paragraph") || editor.can().clearNodes();
32
+ }
33
+ const CodeBlockButton = (0, import_react.forwardRef)(({ editor, onClick, ...buttonProps }, ref) => {
34
+ const [isActive, setIsActive] = (0, import_react.useState)(false);
35
+ const [canToggle, setCanToggle] = (0, import_react.useState)(false);
36
+ (0, import_react.useEffect)(() => {
37
+ if (!editor) return;
38
+ const update = () => {
39
+ setIsActive(editor.isActive("codeBlock"));
40
+ setCanToggle(canToggleCodeBlock(editor));
41
+ };
42
+ update();
43
+ editor.on("selectionUpdate", update);
44
+ editor.on("transaction", update);
45
+ return () => {
46
+ editor.off("selectionUpdate", update);
47
+ editor.off("transaction", update);
48
+ };
49
+ }, [editor]);
50
+ const handleClick = (0, import_react.useCallback)(
51
+ (event) => {
52
+ onClick?.(event);
53
+ if (event.defaultPrevented) return;
54
+ if (!editor) return;
55
+ if (editor.isActive("codeBlock")) {
56
+ editor.chain().focus().setNode("paragraph").run();
57
+ } else {
58
+ editor.chain().focus().clearNodes().toggleNode("codeBlock", "paragraph").run();
59
+ }
60
+ },
61
+ [editor, onClick]
62
+ );
63
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
64
+ import_button.Button,
65
+ {
66
+ ref,
67
+ "aria-label": "Code Block",
68
+ "aria-pressed": isActive,
69
+ "data-active-state": isActive ? "on" : "off",
70
+ disabled: !canToggle,
71
+ size: "icon",
72
+ tabIndex: -1,
73
+ type: "button",
74
+ variant: "ghost",
75
+ onClick: handleClick,
76
+ ...buttonProps,
77
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ import_lucide_react.SquareCode,
79
+ {
80
+ className: isActive ? "nt:text-[var(--tt-brand-color-500)]" : void 0
81
+ }
82
+ )
83
+ }
84
+ );
85
+ });
86
+ CodeBlockButton.displayName = "CodeBlockButton";
87
+ // Annotate the CommonJS export names for ESM import in node:
88
+ 0 && (module.exports = {
89
+ CodeBlockButton
90
+ });
91
+ //# sourceMappingURL=code-block-button.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/code-block-button/code-block-button.tsx"],"sourcesContent":["'use client';\n\nimport { SquareCode } from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { Button } from '../ui/button';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface CodeBlockButtonProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nfunction canToggleCodeBlock(editor: Editor | null): boolean {\n\tif (!editor || !editor.isEditable) return false;\n\n\treturn (\n\t\teditor.can().toggleNode('codeBlock', 'paragraph') ||\n\t\teditor.can().clearNodes()\n\t);\n}\n\nexport const CodeBlockButton = forwardRef<\n\tHTMLButtonElement,\n\tCodeBlockButtonProps\n>(({ editor, onClick, ...buttonProps }, ref) => {\n\tconst [isActive, setIsActive] = useState(false);\n\tconst [canToggle, setCanToggle] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tconst update = () => {\n\t\t\tsetIsActive(editor.isActive('codeBlock'));\n\t\t\tsetCanToggle(canToggleCodeBlock(editor));\n\t\t};\n\n\t\tupdate();\n\n\t\teditor.on('selectionUpdate', update);\n\t\teditor.on('transaction', update);\n\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', update);\n\t\t\teditor.off('transaction', update);\n\t\t};\n\t}, [editor]);\n\n\tconst handleClick = useCallback(\n\t\t(event: React.MouseEvent<HTMLButtonElement>) => {\n\t\t\tonClick?.(event);\n\n\t\t\tif (event.defaultPrevented) return;\n\n\t\t\tif (!editor) return;\n\n\t\t\tif (editor.isActive('codeBlock')) {\n\t\t\t\teditor.chain().focus().setNode('paragraph').run();\n\t\t\t} else {\n\t\t\t\t// clearNodes first to convert any block type to paragraph,\n\t\t\t\t// then toggle to codeBlock\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.clearNodes()\n\t\t\t\t\t.toggleNode('codeBlock', 'paragraph')\n\t\t\t\t\t.run();\n\t\t\t}\n\t\t},\n\t\t[editor, onClick]\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tref={ref}\n\t\t\taria-label=\"Code Block\"\n\t\t\taria-pressed={isActive}\n\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\tdisabled={!canToggle}\n\t\t\tsize=\"icon\"\n\t\t\ttabIndex={-1}\n\t\t\ttype=\"button\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={handleClick}\n\t\t\t{...buttonProps}\n\t\t>\n\t\t\t<SquareCode\n\t\t\t\tclassName={isActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined}\n\t\t\t/>\n\t\t</Button>\n\t);\n});\n\nCodeBlockButton.displayName = 'CodeBlockButton';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyFG;AAvFH,0BAA2B;AAC3B,mBAA6D;AAE7D,oBAAuB;AAWvB,SAAS,mBAAmB,QAAgC;AAC3D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,SACC,OAAO,IAAI,EAAE,WAAW,aAAa,WAAW,KAChD,OAAO,IAAI,EAAE,WAAW;AAE1B;AAEO,MAAM,sBAAkB,yBAG7B,CAAC,EAAE,QAAQ,SAAS,GAAG,YAAY,GAAG,QAAQ;AAC/C,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAEhD,8BAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAS,MAAM;AACpB,kBAAY,OAAO,SAAS,WAAW,CAAC;AACxC,mBAAa,mBAAmB,MAAM,CAAC;AAAA,IACxC;AAEA,WAAO;AAEP,WAAO,GAAG,mBAAmB,MAAM;AACnC,WAAO,GAAG,eAAe,MAAM;AAE/B,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,MAAM;AACpC,aAAO,IAAI,eAAe,MAAM;AAAA,IACjC;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,kBAAc;AAAA,IACnB,CAAC,UAA+C;AAC/C,gBAAU,KAAK;AAEf,UAAI,MAAM,iBAAkB;AAE5B,UAAI,CAAC,OAAQ;AAEb,UAAI,OAAO,SAAS,WAAW,GAAG;AACjC,eAAO,MAAM,EAAE,MAAM,EAAE,QAAQ,WAAW,EAAE,IAAI;AAAA,MACjD,OAAO;AAGN,eACE,MAAM,EACN,MAAM,EACN,WAAW,EACX,WAAW,aAAa,WAAW,EACnC,IAAI;AAAA,MACP;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,cAAW;AAAA,MACX,gBAAc;AAAA,MACd,qBAAmB,WAAW,OAAO;AAAA,MACrC,UAAU,CAAC;AAAA,MACX,MAAK;AAAA,MACL,UAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,WAAW,wCAAwC;AAAA;AAAA,MAC/D;AAAA;AAAA,EACD;AAEF,CAAC;AAED,gBAAgB,cAAc;","names":[]}
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+
4
+ interface CodeBlockButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
5
+ editor: Editor | null;
6
+ }
7
+ declare const CodeBlockButton: react.ForwardRefExoticComponent<CodeBlockButtonProps & react.RefAttributes<HTMLButtonElement>>;
8
+
9
+ export { CodeBlockButton, type CodeBlockButtonProps };
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+ import { Editor } from '@tiptap/core';
3
+
4
+ interface CodeBlockButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
5
+ editor: Editor | null;
6
+ }
7
+ declare const CodeBlockButton: react.ForwardRefExoticComponent<CodeBlockButtonProps & react.RefAttributes<HTMLButtonElement>>;
8
+
9
+ export { CodeBlockButton, type CodeBlockButtonProps };
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { SquareCode } from "lucide-react";
4
+ import { forwardRef, useCallback, useEffect, useState } from "react";
5
+ import { Button } from "../ui/button";
6
+ function canToggleCodeBlock(editor) {
7
+ if (!editor || !editor.isEditable) return false;
8
+ return editor.can().toggleNode("codeBlock", "paragraph") || editor.can().clearNodes();
9
+ }
10
+ const CodeBlockButton = forwardRef(({ editor, onClick, ...buttonProps }, ref) => {
11
+ const [isActive, setIsActive] = useState(false);
12
+ const [canToggle, setCanToggle] = useState(false);
13
+ useEffect(() => {
14
+ if (!editor) return;
15
+ const update = () => {
16
+ setIsActive(editor.isActive("codeBlock"));
17
+ setCanToggle(canToggleCodeBlock(editor));
18
+ };
19
+ update();
20
+ editor.on("selectionUpdate", update);
21
+ editor.on("transaction", update);
22
+ return () => {
23
+ editor.off("selectionUpdate", update);
24
+ editor.off("transaction", update);
25
+ };
26
+ }, [editor]);
27
+ const handleClick = useCallback(
28
+ (event) => {
29
+ onClick?.(event);
30
+ if (event.defaultPrevented) return;
31
+ if (!editor) return;
32
+ if (editor.isActive("codeBlock")) {
33
+ editor.chain().focus().setNode("paragraph").run();
34
+ } else {
35
+ editor.chain().focus().clearNodes().toggleNode("codeBlock", "paragraph").run();
36
+ }
37
+ },
38
+ [editor, onClick]
39
+ );
40
+ return /* @__PURE__ */ jsx(
41
+ Button,
42
+ {
43
+ ref,
44
+ "aria-label": "Code Block",
45
+ "aria-pressed": isActive,
46
+ "data-active-state": isActive ? "on" : "off",
47
+ disabled: !canToggle,
48
+ size: "icon",
49
+ tabIndex: -1,
50
+ type: "button",
51
+ variant: "ghost",
52
+ onClick: handleClick,
53
+ ...buttonProps,
54
+ children: /* @__PURE__ */ jsx(
55
+ SquareCode,
56
+ {
57
+ className: isActive ? "nt:text-[var(--tt-brand-color-500)]" : void 0
58
+ }
59
+ )
60
+ }
61
+ );
62
+ });
63
+ CodeBlockButton.displayName = "CodeBlockButton";
64
+ export {
65
+ CodeBlockButton
66
+ };
67
+ //# sourceMappingURL=code-block-button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/code-block-button/code-block-button.tsx"],"sourcesContent":["'use client';\n\nimport { SquareCode } from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { Button } from '../ui/button';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface CodeBlockButtonProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nfunction canToggleCodeBlock(editor: Editor | null): boolean {\n\tif (!editor || !editor.isEditable) return false;\n\n\treturn (\n\t\teditor.can().toggleNode('codeBlock', 'paragraph') ||\n\t\teditor.can().clearNodes()\n\t);\n}\n\nexport const CodeBlockButton = forwardRef<\n\tHTMLButtonElement,\n\tCodeBlockButtonProps\n>(({ editor, onClick, ...buttonProps }, ref) => {\n\tconst [isActive, setIsActive] = useState(false);\n\tconst [canToggle, setCanToggle] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tconst update = () => {\n\t\t\tsetIsActive(editor.isActive('codeBlock'));\n\t\t\tsetCanToggle(canToggleCodeBlock(editor));\n\t\t};\n\n\t\tupdate();\n\n\t\teditor.on('selectionUpdate', update);\n\t\teditor.on('transaction', update);\n\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', update);\n\t\t\teditor.off('transaction', update);\n\t\t};\n\t}, [editor]);\n\n\tconst handleClick = useCallback(\n\t\t(event: React.MouseEvent<HTMLButtonElement>) => {\n\t\t\tonClick?.(event);\n\n\t\t\tif (event.defaultPrevented) return;\n\n\t\t\tif (!editor) return;\n\n\t\t\tif (editor.isActive('codeBlock')) {\n\t\t\t\teditor.chain().focus().setNode('paragraph').run();\n\t\t\t} else {\n\t\t\t\t// clearNodes first to convert any block type to paragraph,\n\t\t\t\t// then toggle to codeBlock\n\t\t\t\teditor\n\t\t\t\t\t.chain()\n\t\t\t\t\t.focus()\n\t\t\t\t\t.clearNodes()\n\t\t\t\t\t.toggleNode('codeBlock', 'paragraph')\n\t\t\t\t\t.run();\n\t\t\t}\n\t\t},\n\t\t[editor, onClick]\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tref={ref}\n\t\t\taria-label=\"Code Block\"\n\t\t\taria-pressed={isActive}\n\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\tdisabled={!canToggle}\n\t\t\tsize=\"icon\"\n\t\t\ttabIndex={-1}\n\t\t\ttype=\"button\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={handleClick}\n\t\t\t{...buttonProps}\n\t\t>\n\t\t\t<SquareCode\n\t\t\t\tclassName={isActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined}\n\t\t\t/>\n\t\t</Button>\n\t);\n});\n\nCodeBlockButton.displayName = 'CodeBlockButton';\n"],"mappings":";AAyFG;AAvFH,SAAS,kBAAkB;AAC3B,SAAS,YAAY,aAAa,WAAW,gBAAgB;AAE7D,SAAS,cAAc;AAWvB,SAAS,mBAAmB,QAAgC;AAC3D,MAAI,CAAC,UAAU,CAAC,OAAO,WAAY,QAAO;AAE1C,SACC,OAAO,IAAI,EAAE,WAAW,aAAa,WAAW,KAChD,OAAO,IAAI,EAAE,WAAW;AAE1B;AAEO,MAAM,kBAAkB,WAG7B,CAAC,EAAE,QAAQ,SAAS,GAAG,YAAY,GAAG,QAAQ;AAC/C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,YAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,UAAM,SAAS,MAAM;AACpB,kBAAY,OAAO,SAAS,WAAW,CAAC;AACxC,mBAAa,mBAAmB,MAAM,CAAC;AAAA,IACxC;AAEA,WAAO;AAEP,WAAO,GAAG,mBAAmB,MAAM;AACnC,WAAO,GAAG,eAAe,MAAM;AAE/B,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,MAAM;AACpC,aAAO,IAAI,eAAe,MAAM;AAAA,IACjC;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAc;AAAA,IACnB,CAAC,UAA+C;AAC/C,gBAAU,KAAK;AAEf,UAAI,MAAM,iBAAkB;AAE5B,UAAI,CAAC,OAAQ;AAEb,UAAI,OAAO,SAAS,WAAW,GAAG;AACjC,eAAO,MAAM,EAAE,MAAM,EAAE,QAAQ,WAAW,EAAE,IAAI;AAAA,MACjD,OAAO;AAGN,eACE,MAAM,EACN,MAAM,EACN,WAAW,EACX,WAAW,aAAa,WAAW,EACnC,IAAI;AAAA,MACP;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,cAAW;AAAA,MACX,gBAAc;AAAA,MACd,qBAAmB,WAAW,OAAO;AAAA,MACrC,UAAU,CAAC;AAAA,MACX,MAAK;AAAA,MACL,UAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS;AAAA,MACR,GAAG;AAAA,MAEJ;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,WAAW,wCAAwC;AAAA;AAAA,MAC/D;AAAA;AAAA,EACD;AAEF,CAAC;AAED,gBAAgB,cAAc;","names":[]}
@@ -0,0 +1,39 @@
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
+ var code_block_view_exports = {};
21
+ __export(code_block_view_exports, {
22
+ CodeBlockShell: () => CodeBlockShell,
23
+ CodeBlockView: () => CodeBlockView
24
+ });
25
+ module.exports = __toCommonJS(code_block_view_exports);
26
+ var import_jsx_runtime = require("react/jsx-runtime");
27
+ var import_react = require("@tiptap/react");
28
+ var import_copy_button = require("./copy-button");
29
+ const CodeBlockShell = ({ value, children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "nt:relative", children: [
30
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "nt:absolute nt:inset-x-0 nt:top-0 nt:flex nt:h-9 nt:items-center nt:justify-end nt:px-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_copy_button.CopyButton, { value }) }),
31
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { className: "nt:!pt-9", children })
32
+ ] });
33
+ const CodeBlockView = ({ node }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.NodeViewWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodeBlockShell, { value: node.textContent, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.NodeViewContent, { as: "code" }) }) });
34
+ // Annotate the CommonJS export names for ESM import in node:
35
+ 0 && (module.exports = {
36
+ CodeBlockShell,
37
+ CodeBlockView
38
+ });
39
+ //# sourceMappingURL=code-block-view.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/code-block-view.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tNodeViewContent,\n\tNodeViewWrapper,\n\ttype NodeViewProps\n} from '@tiptap/react';\n\nimport { CopyButton } from './copy-button';\n\nimport type { ReactNode } from 'react';\n\ninterface CodeBlockShellProps {\n\tvalue: string;\n\tchildren: ReactNode;\n}\n\n// Visual structure shared by editor (NodeView) and reader (nodeMapping).\n// Children is the <code> element (or <NodeViewContent as=\"code\"/>); the\n// shell does not wrap it because each consumer mounts <code> differently.\nexport const CodeBlockShell = ({ value, children }: CodeBlockShellProps) => (\n\t<div className=\"nt:relative\">\n\t\t<div className=\"nt:absolute nt:inset-x-0 nt:top-0 nt:flex nt:h-9 nt:items-center nt:justify-end nt:px-2\">\n\t\t\t<CopyButton value={value} />\n\t\t</div>\n\t\t<pre className=\"nt:!pt-9\">{children}</pre>\n\t</div>\n);\n\n// Editor-side React NodeView. Tiptap mounts content-editable DOM directly\n// onto the <code> rendered by NodeViewContent.\nexport const CodeBlockView = ({ node }: NodeViewProps) => (\n\t<NodeViewWrapper>\n\t\t<CodeBlockShell value={node.textContent}>\n\t\t\t<NodeViewContent<'code'> as=\"code\" />\n\t\t</CodeBlockShell>\n\t</NodeViewWrapper>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBC;AAnBD,mBAIO;AAEP,yBAA2B;AAYpB,MAAM,iBAAiB,CAAC,EAAE,OAAO,SAAS,MAChD,6CAAC,SAAI,WAAU,eACd;AAAA,8CAAC,SAAI,WAAU,2FACd,sDAAC,iCAAW,OAAc,GAC3B;AAAA,EACA,4CAAC,SAAI,WAAU,YAAY,UAAS;AAAA,GACrC;AAKM,MAAM,gBAAgB,CAAC,EAAE,KAAK,MACpC,4CAAC,gCACA,sDAAC,kBAAe,OAAO,KAAK,aAC3B,sDAAC,gCAAwB,IAAG,QAAO,GACpC,GACD;","names":[]}
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { NodeViewProps } from '@tiptap/react';
3
+ import { ReactNode } from 'react';
4
+
5
+ interface CodeBlockShellProps {
6
+ value: string;
7
+ children: ReactNode;
8
+ }
9
+ declare const CodeBlockShell: ({ value, children }: CodeBlockShellProps) => react_jsx_runtime.JSX.Element;
10
+ declare const CodeBlockView: ({ node }: NodeViewProps) => react_jsx_runtime.JSX.Element;
11
+
12
+ export { CodeBlockShell, CodeBlockView };
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { NodeViewProps } from '@tiptap/react';
3
+ import { ReactNode } from 'react';
4
+
5
+ interface CodeBlockShellProps {
6
+ value: string;
7
+ children: ReactNode;
8
+ }
9
+ declare const CodeBlockShell: ({ value, children }: CodeBlockShellProps) => react_jsx_runtime.JSX.Element;
10
+ declare const CodeBlockView: ({ node }: NodeViewProps) => react_jsx_runtime.JSX.Element;
11
+
12
+ export { CodeBlockShell, CodeBlockView };
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import {
4
+ NodeViewContent,
5
+ NodeViewWrapper
6
+ } from "@tiptap/react";
7
+ import { CopyButton } from "./copy-button";
8
+ const CodeBlockShell = ({ value, children }) => /* @__PURE__ */ jsxs("div", { className: "nt:relative", children: [
9
+ /* @__PURE__ */ jsx("div", { className: "nt:absolute nt:inset-x-0 nt:top-0 nt:flex nt:h-9 nt:items-center nt:justify-end nt:px-2", children: /* @__PURE__ */ jsx(CopyButton, { value }) }),
10
+ /* @__PURE__ */ jsx("pre", { className: "nt:!pt-9", children })
11
+ ] });
12
+ const CodeBlockView = ({ node }) => /* @__PURE__ */ jsx(NodeViewWrapper, { children: /* @__PURE__ */ jsx(CodeBlockShell, { value: node.textContent, children: /* @__PURE__ */ jsx(NodeViewContent, { as: "code" }) }) });
13
+ export {
14
+ CodeBlockShell,
15
+ CodeBlockView
16
+ };
17
+ //# sourceMappingURL=code-block-view.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/code-block-view.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tNodeViewContent,\n\tNodeViewWrapper,\n\ttype NodeViewProps\n} from '@tiptap/react';\n\nimport { CopyButton } from './copy-button';\n\nimport type { ReactNode } from 'react';\n\ninterface CodeBlockShellProps {\n\tvalue: string;\n\tchildren: ReactNode;\n}\n\n// Visual structure shared by editor (NodeView) and reader (nodeMapping).\n// Children is the <code> element (or <NodeViewContent as=\"code\"/>); the\n// shell does not wrap it because each consumer mounts <code> differently.\nexport const CodeBlockShell = ({ value, children }: CodeBlockShellProps) => (\n\t<div className=\"nt:relative\">\n\t\t<div className=\"nt:absolute nt:inset-x-0 nt:top-0 nt:flex nt:h-9 nt:items-center nt:justify-end nt:px-2\">\n\t\t\t<CopyButton value={value} />\n\t\t</div>\n\t\t<pre className=\"nt:!pt-9\">{children}</pre>\n\t</div>\n);\n\n// Editor-side React NodeView. Tiptap mounts content-editable DOM directly\n// onto the <code> rendered by NodeViewContent.\nexport const CodeBlockView = ({ node }: NodeViewProps) => (\n\t<NodeViewWrapper>\n\t\t<CodeBlockShell value={node.textContent}>\n\t\t\t<NodeViewContent<'code'> as=\"code\" />\n\t\t</CodeBlockShell>\n\t</NodeViewWrapper>\n);\n"],"mappings":";AAqBC,SAEE,KAFF;AAnBD;AAAA,EACC;AAAA,EACA;AAAA,OAEM;AAEP,SAAS,kBAAkB;AAYpB,MAAM,iBAAiB,CAAC,EAAE,OAAO,SAAS,MAChD,qBAAC,SAAI,WAAU,eACd;AAAA,sBAAC,SAAI,WAAU,2FACd,8BAAC,cAAW,OAAc,GAC3B;AAAA,EACA,oBAAC,SAAI,WAAU,YAAY,UAAS;AAAA,GACrC;AAKM,MAAM,gBAAgB,CAAC,EAAE,KAAK,MACpC,oBAAC,mBACA,8BAAC,kBAAe,OAAO,KAAK,aAC3B,8BAAC,mBAAwB,IAAG,QAAO,GACpC,GACD;","names":[]}
@@ -0,0 +1,49 @@
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
+ var copy_button_exports = {};
21
+ __export(copy_button_exports, {
22
+ CopyButton: () => CopyButton
23
+ });
24
+ module.exports = __toCommonJS(copy_button_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_lucide_react = require("lucide-react");
27
+ var import_use_copy_to_clipboard = require("../hooks/use-copy-to-clipboard");
28
+ var import_button = require("./ui/button");
29
+ const CopyButton = ({ value, className }) => {
30
+ const { isCopied, copyToClipboard } = (0, import_use_copy_to_clipboard.useCopyToClipboard)();
31
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
32
+ import_button.Button,
33
+ {
34
+ className,
35
+ size: "icon",
36
+ variant: "ghost",
37
+ onClick: () => copyToClipboard(value),
38
+ children: [
39
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "nt:sr-only", children: "Copy" }),
40
+ isCopied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Copy, {})
41
+ ]
42
+ }
43
+ );
44
+ };
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ CopyButton
48
+ });
49
+ //# sourceMappingURL=copy-button.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/copy-button.tsx"],"sourcesContent":["'use client';\n\nimport { Check, Copy } from 'lucide-react';\n\nimport { useCopyToClipboard } from '../hooks/use-copy-to-clipboard';\nimport { Button } from './ui/button';\n\ninterface CopyButtonProps {\n\tvalue: string;\n\tclassName?: string;\n}\n\nexport const CopyButton = ({ value, className }: CopyButtonProps) => {\n\tconst { isCopied, copyToClipboard } = useCopyToClipboard();\n\n\treturn (\n\t\t<Button\n\t\t\tclassName={className}\n\t\t\tsize=\"icon\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={() => copyToClipboard(value)}\n\t\t>\n\t\t\t<span className=\"nt:sr-only\">Copy</span>\n\t\t\t{isCopied ? <Check /> : <Copy />}\n\t\t</Button>\n\t);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBE;AAdF,0BAA4B;AAE5B,mCAAmC;AACnC,oBAAuB;AAOhB,MAAM,aAAa,CAAC,EAAE,OAAO,UAAU,MAAuB;AACpE,QAAM,EAAE,UAAU,gBAAgB,QAAI,iDAAmB;AAEzD,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS,MAAM,gBAAgB,KAAK;AAAA,MAEpC;AAAA,oDAAC,UAAK,WAAU,cAAa,kBAAI;AAAA,QAChC,WAAW,4CAAC,6BAAM,IAAK,4CAAC,4BAAK;AAAA;AAAA;AAAA,EAC/B;AAEF;","names":[]}
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface CopyButtonProps {
4
+ value: string;
5
+ className?: string;
6
+ }
7
+ declare const CopyButton: ({ value, className }: CopyButtonProps) => react_jsx_runtime.JSX.Element;
8
+
9
+ export { CopyButton };
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface CopyButtonProps {
4
+ value: string;
5
+ className?: string;
6
+ }
7
+ declare const CopyButton: ({ value, className }: CopyButtonProps) => react_jsx_runtime.JSX.Element;
8
+
9
+ export { CopyButton };
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Check, Copy } from "lucide-react";
4
+ import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
5
+ import { Button } from "./ui/button";
6
+ const CopyButton = ({ value, className }) => {
7
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
8
+ return /* @__PURE__ */ jsxs(
9
+ Button,
10
+ {
11
+ className,
12
+ size: "icon",
13
+ variant: "ghost",
14
+ onClick: () => copyToClipboard(value),
15
+ children: [
16
+ /* @__PURE__ */ jsx("span", { className: "nt:sr-only", children: "Copy" }),
17
+ isCopied ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(Copy, {})
18
+ ]
19
+ }
20
+ );
21
+ };
22
+ export {
23
+ CopyButton
24
+ };
25
+ //# sourceMappingURL=copy-button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/copy-button.tsx"],"sourcesContent":["'use client';\n\nimport { Check, Copy } from 'lucide-react';\n\nimport { useCopyToClipboard } from '../hooks/use-copy-to-clipboard';\nimport { Button } from './ui/button';\n\ninterface CopyButtonProps {\n\tvalue: string;\n\tclassName?: string;\n}\n\nexport const CopyButton = ({ value, className }: CopyButtonProps) => {\n\tconst { isCopied, copyToClipboard } = useCopyToClipboard();\n\n\treturn (\n\t\t<Button\n\t\t\tclassName={className}\n\t\t\tsize=\"icon\"\n\t\t\tvariant=\"ghost\"\n\t\t\tonClick={() => copyToClipboard(value)}\n\t\t>\n\t\t\t<span className=\"nt:sr-only\">Copy</span>\n\t\t\t{isCopied ? <Check /> : <Copy />}\n\t\t</Button>\n\t);\n};\n"],"mappings":";AAgBE,SAMC,KAND;AAdF,SAAS,OAAO,YAAY;AAE5B,SAAS,0BAA0B;AACnC,SAAS,cAAc;AAOhB,MAAM,aAAa,CAAC,EAAE,OAAO,UAAU,MAAuB;AACpE,QAAM,EAAE,UAAU,gBAAgB,IAAI,mBAAmB;AAEzD,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,SAAS,MAAM,gBAAgB,KAAK;AAAA,MAEpC;AAAA,4BAAC,UAAK,WAAU,cAAa,kBAAI;AAAA,QAChC,WAAW,oBAAC,SAAM,IAAK,oBAAC,QAAK;AAAA;AAAA;AAAA,EAC/B;AAEF;","names":[]}