@kopexa/tiptap 17.0.17 → 17.2.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 (147) hide show
  1. package/dist/chunk-2U5CQUZH.mjs +91 -0
  2. package/dist/chunk-2V6VOAPI.mjs +139 -0
  3. package/dist/chunk-32SUXCAQ.mjs +115 -0
  4. package/dist/chunk-3VRQUYYW.mjs +169 -0
  5. package/dist/chunk-4CDZ547I.mjs +185 -0
  6. package/dist/chunk-5GFFTVMZ.mjs +62 -0
  7. package/dist/{chunk-FJAGUXEO.mjs → chunk-7SRL3P4B.mjs} +32 -19
  8. package/dist/{chunk-WHJ4B43N.mjs → chunk-7VGROP26.mjs} +69 -25
  9. package/dist/chunk-7VW67NVL.mjs +80 -0
  10. package/dist/chunk-BXHPO3T7.mjs +152 -0
  11. package/dist/{chunk-QF3YHPWM.mjs → chunk-E5NW3MJZ.mjs} +4 -4
  12. package/dist/chunk-FRJX2F4T.mjs +55 -0
  13. package/dist/chunk-IFXRPGIJ.mjs +98 -0
  14. package/dist/chunk-JCV5SEKN.mjs +65 -0
  15. package/dist/chunk-LMCQMSW2.mjs +345 -0
  16. package/dist/chunk-N4CT5RNC.mjs +123 -0
  17. package/dist/{chunk-B2DHYFSH.mjs → chunk-NEHW62L7.mjs} +56 -3
  18. package/dist/chunk-NSYSECKW.mjs +53 -0
  19. package/dist/{chunk-3IKIIRV3.mjs → chunk-QAE2D4KV.mjs} +39 -16
  20. package/dist/chunk-TAM3VMJT.mjs +80 -0
  21. package/dist/chunk-UU6JK5HX.mjs +257 -0
  22. package/dist/chunk-UVHVCION.mjs +168 -0
  23. package/dist/chunk-VF3G2URZ.mjs +83 -0
  24. package/dist/chunk-VRQ6OSAZ.mjs +76 -0
  25. package/dist/chunk-WAAH3NLG.mjs +77 -0
  26. package/dist/chunk-XNDXYI2N.mjs +158 -0
  27. package/dist/context/editor-file-context.d.mts +70 -0
  28. package/dist/context/editor-file-context.d.ts +70 -0
  29. package/dist/context/editor-file-context.js +96 -0
  30. package/dist/context/editor-file-context.mjs +12 -0
  31. package/dist/extensions/callout/callout-settings.d.mts +13 -0
  32. package/dist/extensions/callout/callout-settings.d.ts +13 -0
  33. package/dist/extensions/callout/callout-settings.js +206 -0
  34. package/dist/extensions/callout/callout-settings.mjs +9 -0
  35. package/dist/extensions/callout/callout-view.d.mts +12 -0
  36. package/dist/extensions/callout/callout-view.d.ts +12 -0
  37. package/dist/extensions/callout/callout-view.js +273 -0
  38. package/dist/extensions/callout/callout-view.mjs +12 -0
  39. package/dist/extensions/callout/index.d.mts +44 -0
  40. package/dist/extensions/callout/index.d.ts +44 -0
  41. package/dist/extensions/callout/index.js +380 -0
  42. package/dist/extensions/callout/index.mjs +13 -0
  43. package/dist/extensions/callout/messages.d.mts +59 -0
  44. package/dist/extensions/callout/messages.d.ts +59 -0
  45. package/dist/extensions/callout/messages.js +88 -0
  46. package/dist/extensions/callout/messages.mjs +7 -0
  47. package/dist/extensions/image/image-view.d.mts +15 -0
  48. package/dist/extensions/image/image-view.d.ts +15 -0
  49. package/dist/extensions/image/image-view.js +423 -0
  50. package/dist/extensions/image/image-view.mjs +12 -0
  51. package/dist/extensions/image/index.d.mts +66 -0
  52. package/dist/extensions/image/index.d.ts +66 -0
  53. package/dist/extensions/image/index.js +495 -0
  54. package/dist/extensions/image/index.mjs +16 -0
  55. package/dist/extensions/image/messages.d.mts +56 -0
  56. package/dist/extensions/image/messages.d.ts +56 -0
  57. package/dist/extensions/image/messages.js +85 -0
  58. package/dist/extensions/image/messages.mjs +7 -0
  59. package/dist/extensions/math/index.d.mts +38 -0
  60. package/dist/extensions/math/index.d.ts +38 -0
  61. package/dist/extensions/math/index.js +544 -0
  62. package/dist/extensions/math/index.mjs +17 -0
  63. package/dist/extensions/math/inline-math-view.d.mts +12 -0
  64. package/dist/extensions/math/inline-math-view.d.ts +12 -0
  65. package/dist/extensions/math/inline-math-view.js +232 -0
  66. package/dist/extensions/math/inline-math-view.mjs +11 -0
  67. package/dist/extensions/math/inline-math.d.mts +32 -0
  68. package/dist/extensions/math/inline-math.d.ts +32 -0
  69. package/dist/extensions/math/inline-math.js +304 -0
  70. package/dist/extensions/math/inline-math.mjs +12 -0
  71. package/dist/extensions/math/math-block-view.d.mts +11 -0
  72. package/dist/extensions/math/math-block-view.d.ts +11 -0
  73. package/dist/extensions/math/math-block-view.js +248 -0
  74. package/dist/extensions/math/math-block-view.mjs +11 -0
  75. package/dist/extensions/math/messages.d.mts +49 -0
  76. package/dist/extensions/math/messages.d.ts +49 -0
  77. package/dist/extensions/math/messages.js +78 -0
  78. package/dist/extensions/math/messages.mjs +7 -0
  79. package/dist/extensions/toc/index.d.mts +53 -0
  80. package/dist/extensions/toc/index.d.ts +53 -0
  81. package/dist/extensions/toc/index.js +501 -0
  82. package/dist/extensions/toc/index.mjs +13 -0
  83. package/dist/extensions/toc/messages.d.mts +74 -0
  84. package/dist/extensions/toc/messages.d.ts +74 -0
  85. package/dist/extensions/toc/messages.js +103 -0
  86. package/dist/extensions/toc/messages.mjs +7 -0
  87. package/dist/extensions/toc/toc-settings.d.mts +13 -0
  88. package/dist/extensions/toc/toc-settings.d.ts +13 -0
  89. package/dist/extensions/toc/toc-settings.js +283 -0
  90. package/dist/extensions/toc/toc-settings.mjs +9 -0
  91. package/dist/extensions/toc/toc-view.d.mts +12 -0
  92. package/dist/extensions/toc/toc-view.d.ts +12 -0
  93. package/dist/extensions/toc/toc-view.js +411 -0
  94. package/dist/extensions/toc/toc-view.mjs +12 -0
  95. package/dist/hooks/use-create-editor.d.mts +20 -2
  96. package/dist/hooks/use-create-editor.d.ts +20 -2
  97. package/dist/hooks/use-create-editor.js +2020 -20
  98. package/dist/hooks/use-create-editor.mjs +20 -3
  99. package/dist/index.d.mts +11 -2
  100. package/dist/index.d.ts +11 -2
  101. package/dist/index.js +3948 -1563
  102. package/dist/index.mjs +64 -23
  103. package/dist/presets/basic/editor-header.d.mts +3 -2
  104. package/dist/presets/basic/editor-header.d.ts +3 -2
  105. package/dist/presets/basic/editor-header.js +91 -25
  106. package/dist/presets/basic/editor-header.mjs +14 -14
  107. package/dist/presets/basic/index.d.mts +3 -1
  108. package/dist/presets/basic/index.d.ts +3 -1
  109. package/dist/presets/basic/index.js +3833 -1517
  110. package/dist/presets/basic/index.mjs +41 -22
  111. package/dist/ui/bubble-menu/index.d.mts +13 -0
  112. package/dist/ui/bubble-menu/index.d.ts +13 -0
  113. package/dist/ui/bubble-menu/index.js +671 -0
  114. package/dist/ui/bubble-menu/index.mjs +16 -0
  115. package/dist/ui/color-highlight-popover/color-highlight-popover.mjs +2 -2
  116. package/dist/ui/color-highlight-popover/index.mjs +2 -2
  117. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.mjs +2 -2
  118. package/dist/ui/link-bubble/index.d.mts +13 -0
  119. package/dist/ui/link-bubble/index.d.ts +13 -0
  120. package/dist/ui/link-bubble/index.js +182 -0
  121. package/dist/ui/link-bubble/index.mjs +10 -0
  122. package/dist/ui/link-popover/index.js +66 -23
  123. package/dist/ui/link-popover/index.mjs +3 -3
  124. package/dist/ui/link-popover/link-popover.d.mts +7 -2
  125. package/dist/ui/link-popover/link-popover.d.ts +7 -2
  126. package/dist/ui/link-popover/link-popover.js +66 -23
  127. package/dist/ui/link-popover/link-popover.mjs +3 -3
  128. package/dist/ui/link-popover/use-link-popover.mjs +2 -2
  129. package/dist/ui/slash-dropdown-menu/index.js +53 -3
  130. package/dist/ui/slash-dropdown-menu/index.mjs +6 -6
  131. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +53 -3
  132. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +4 -4
  133. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.d.mts +28 -0
  134. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.d.ts +28 -0
  135. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.js +53 -3
  136. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.mjs +1 -1
  137. package/dist/ui/suggestion-menu/index.mjs +2 -2
  138. package/dist/ui/suggestion-menu/suggestion-menu.mjs +2 -2
  139. package/dist/utils/safe-parse.js +113 -4
  140. package/dist/utils/safe-parse.mjs +1 -1
  141. package/package.json +48 -39
  142. package/dist/chunk-7LHOYNVF.mjs +0 -60
  143. package/dist/chunk-LXOLVGLW.mjs +0 -131
  144. package/dist/{chunk-XL5FS7LN.mjs → chunk-C5RQWJKE.mjs} +3 -3
  145. package/dist/{chunk-JNL4KY45.mjs → chunk-DZLGLP7R.mjs} +3 -3
  146. package/dist/{chunk-LHXRE26G.mjs → chunk-VTKJPVNM.mjs} +3 -3
  147. package/dist/{chunk-XLSZK3WJ.mjs → chunk-ZYFCSR3E.mjs} +3 -3
@@ -0,0 +1,62 @@
1
+ "use client";
2
+
3
+ // src/extensions/image/messages.ts
4
+ import { defineMessages } from "react-intl";
5
+ var messages = defineMessages({
6
+ loading: {
7
+ id: "editor.image.loading",
8
+ defaultMessage: "Loading image..."
9
+ },
10
+ error: {
11
+ id: "editor.image.error",
12
+ defaultMessage: "Failed to load image"
13
+ },
14
+ upload_error: {
15
+ id: "editor.image.upload_error",
16
+ defaultMessage: "Failed to upload image"
17
+ },
18
+ uploading: {
19
+ id: "editor.image.uploading",
20
+ defaultMessage: "Uploading..."
21
+ },
22
+ upload_placeholder: {
23
+ id: "editor.image.upload_placeholder",
24
+ defaultMessage: "Click to upload or drag & drop"
25
+ },
26
+ upload_hint: {
27
+ id: "editor.image.upload_hint",
28
+ defaultMessage: "PNG, JPG, GIF, WebP, SVG"
29
+ },
30
+ alt_text: {
31
+ id: "editor.image.alt_text",
32
+ defaultMessage: "Alt text"
33
+ },
34
+ alt_placeholder: {
35
+ id: "editor.image.alt_placeholder",
36
+ defaultMessage: "Describe the image..."
37
+ },
38
+ files_not_supported: {
39
+ id: "editor.image.files_not_supported",
40
+ defaultMessage: "File upload is not configured"
41
+ },
42
+ file_too_large: {
43
+ id: "editor.image.file_too_large",
44
+ defaultMessage: "File is too large (max {maxSize})"
45
+ },
46
+ invalid_type: {
47
+ id: "editor.image.invalid_type",
48
+ defaultMessage: "Invalid file type"
49
+ },
50
+ retry: {
51
+ id: "editor.image.retry",
52
+ defaultMessage: "Retry"
53
+ },
54
+ remove: {
55
+ id: "editor.image.remove",
56
+ defaultMessage: "Remove"
57
+ }
58
+ });
59
+
60
+ export {
61
+ messages
62
+ };
@@ -1,13 +1,19 @@
1
1
  "use client";
2
2
  import {
3
3
  SlashDropdownMenu
4
- } from "./chunk-QF3YHPWM.mjs";
4
+ } from "./chunk-E5NW3MJZ.mjs";
5
+ import {
6
+ LinkBubble
7
+ } from "./chunk-XNDXYI2N.mjs";
5
8
  import {
6
9
  useScrollToHash
7
- } from "./chunk-JNL4KY45.mjs";
10
+ } from "./chunk-DZLGLP7R.mjs";
8
11
  import {
9
12
  EditorHeader
10
- } from "./chunk-3IKIIRV3.mjs";
13
+ } from "./chunk-QAE2D4KV.mjs";
14
+ import {
15
+ BubbleMenu
16
+ } from "./chunk-NSYSECKW.mjs";
11
17
  import {
12
18
  useUiEditorState
13
19
  } from "./chunk-BXJYNSWQ.mjs";
@@ -16,7 +22,7 @@ import {
16
22
  } from "./chunk-REJEJXOZ.mjs";
17
23
  import {
18
24
  useCreateEditor
19
- } from "./chunk-LXOLVGLW.mjs";
25
+ } from "./chunk-UU6JK5HX.mjs";
20
26
 
21
27
  // src/presets/basic/index.tsx
22
28
  import {
@@ -31,17 +37,20 @@ import { useContext } from "react";
31
37
  import { jsx, jsxs } from "react/jsx-runtime";
32
38
  var BasicEditor = ({
33
39
  variant,
40
+ bordered,
34
41
  content,
35
42
  ...options
36
43
  }) => {
37
44
  const editor = useCreateEditor({ content, ...options });
38
- const styles = editorBasic({ variant });
45
+ const styles = editorBasic({ variant, bordered });
39
46
  if (!editor) {
40
47
  return /* @__PURE__ */ jsx(LoadingSpinner, {});
41
48
  }
49
+ const isBottomToolbar = variant === "field";
42
50
  return /* @__PURE__ */ jsx(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ jsx("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ jsxs(EditorContext.Provider, { value: { editor }, children: [
43
- /* @__PURE__ */ jsx(EditorHeader, { editor }),
44
- /* @__PURE__ */ jsx(EditorContentArea, { variant })
51
+ !isBottomToolbar && /* @__PURE__ */ jsx(EditorHeader, { editor, variant }),
52
+ /* @__PURE__ */ jsx(EditorContentArea, { variant }),
53
+ isBottomToolbar && /* @__PURE__ */ jsx(EditorHeader, { editor, variant })
45
54
  ] }) }) });
46
55
  };
47
56
  var EditorContentArea = ({ variant }) => {
@@ -52,18 +61,22 @@ var EditorContentArea = ({ variant }) => {
52
61
  if (!editor) {
53
62
  return null;
54
63
  }
55
- return /* @__PURE__ */ jsx("div", { className: styles.wrapper(), children: /* @__PURE__ */ jsx(
56
- EditorContent,
57
- {
58
- editor,
59
- role: "presentation",
60
- className: styles.content(),
61
- style: {
62
- cursor: isDragging ? "grabbing" : "auto"
63
- },
64
- children: /* @__PURE__ */ jsx(SlashDropdownMenu, {})
65
- }
66
- ) });
64
+ return /* @__PURE__ */ jsxs("div", { className: styles.wrapper(), children: [
65
+ /* @__PURE__ */ jsx(
66
+ EditorContent,
67
+ {
68
+ editor,
69
+ role: "presentation",
70
+ className: styles.content(),
71
+ style: {
72
+ cursor: isDragging ? "grabbing" : "auto"
73
+ },
74
+ children: /* @__PURE__ */ jsx(SlashDropdownMenu, {})
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx(BubbleMenu, { editor }),
78
+ /* @__PURE__ */ jsx(LinkBubble, { editor })
79
+ ] });
67
80
  };
68
81
  function LoadingSpinner({ text = "Connecting..." }) {
69
82
  const styles = editorSpinner();
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useLinkPopover
4
- } from "./chunk-LHXRE26G.mjs";
4
+ } from "./chunk-VTKJPVNM.mjs";
5
5
  import {
6
6
  useTiptapEditor
7
7
  } from "./chunk-P55PLOHR.mjs";
@@ -9,14 +9,14 @@ import {
9
9
  // src/ui/link-popover/link-popover.tsx
10
10
  import { IconButton } from "@kopexa/button";
11
11
  import {
12
- CornerDownLeftIcon,
12
+ CheckIcon,
13
+ EditIcon,
13
14
  ExternalLinkIcon,
14
15
  LinkIcon,
15
16
  TrashIcon
16
17
  } from "@kopexa/icons";
17
18
  import { Input } from "@kopexa/input";
18
19
  import { Popover } from "@kopexa/popover";
19
- import { Separator } from "@kopexa/separator";
20
20
  import { ToolbarButton } from "@kopexa/toolbar";
21
21
  import { useCallback, useEffect, useState } from "react";
22
22
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -43,67 +43,110 @@ var LinkMain = ({
43
43
  setLink,
44
44
  removeLink,
45
45
  openLink,
46
- isActive
46
+ isActive,
47
+ onSave
47
48
  }) => {
49
+ const [isEditing, setIsEditing] = useState(!isActive || !url);
50
+ useEffect(() => {
51
+ setIsEditing(!isActive || !url);
52
+ }, [isActive, url]);
48
53
  const handleKeyDown = (event) => {
49
54
  if (event.key === "Enter") {
50
55
  event.preventDefault();
51
56
  setLink();
57
+ setIsEditing(false);
58
+ onSave == null ? void 0 : onSave();
59
+ } else if (event.key === "Escape") {
60
+ event.preventDefault();
61
+ setIsEditing(false);
52
62
  }
53
63
  };
54
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
55
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-2", children: [
64
+ const handleSave = () => {
65
+ setLink();
66
+ setIsEditing(false);
67
+ onSave == null ? void 0 : onSave();
68
+ };
69
+ const handleEdit = () => {
70
+ setIsEditing(true);
71
+ };
72
+ if (isEditing) {
73
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 min-w-[280px]", children: [
56
74
  /* @__PURE__ */ jsx(
57
75
  Input,
58
76
  {
59
77
  type: "url",
60
- placeholder: "Paste a link...",
78
+ placeholder: "Enter URL...",
61
79
  value: url,
62
80
  onChange: (e) => setUrl(e.target.value),
63
81
  onKeyDown: handleKeyDown,
64
82
  autoComplete: "off",
65
83
  autoCorrect: "off",
66
84
  autoCapitalize: "off",
67
- className: "w-full"
85
+ className: "flex-1 h-8 text-sm",
86
+ autoFocus: true
68
87
  }
69
88
  ),
70
89
  /* @__PURE__ */ jsx(
71
90
  IconButton,
72
91
  {
73
92
  type: "button",
74
- onClick: setLink,
75
- "aria-label": "Apply link",
76
- disabled: !url && !isActive,
93
+ size: "sm",
77
94
  variant: "ghost",
78
- color: "default",
79
- children: /* @__PURE__ */ jsx(CornerDownLeftIcon, {})
95
+ onClick: handleSave,
96
+ "aria-label": "Save link",
97
+ disabled: !url,
98
+ children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" })
80
99
  }
81
100
  )
82
- ] }),
83
- /* @__PURE__ */ jsx(Separator, { className: "my-1" }),
84
- /* @__PURE__ */ jsxs("div", { className: "tiptap-button-group", "data-orientation": "horizontal", children: [
101
+ ] });
102
+ }
103
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 min-w-[280px]", children: [
104
+ /* @__PURE__ */ jsx(
105
+ "a",
106
+ {
107
+ href: url,
108
+ target: "_blank",
109
+ rel: "noopener noreferrer",
110
+ className: "flex-1 text-sm text-primary truncate max-w-[200px] hover:underline px-2",
111
+ onClick: (e) => {
112
+ e.preventDefault();
113
+ openLink();
114
+ },
115
+ children: url
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 border-l pl-1 ml-1", children: [
85
119
  /* @__PURE__ */ jsx(
86
120
  IconButton,
87
121
  {
88
122
  type: "button",
123
+ size: "sm",
124
+ variant: "ghost",
89
125
  onClick: openLink,
90
- "aria-label": "Open in new window",
91
- disabled: !url && !isActive,
126
+ "aria-label": "Open link in new tab",
127
+ children: /* @__PURE__ */ jsx(ExternalLinkIcon, { className: "size-4" })
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx(
131
+ IconButton,
132
+ {
133
+ type: "button",
134
+ size: "sm",
92
135
  variant: "ghost",
93
- color: "default",
94
- children: /* @__PURE__ */ jsx(ExternalLinkIcon, {})
136
+ onClick: handleEdit,
137
+ "aria-label": "Edit link",
138
+ children: /* @__PURE__ */ jsx(EditIcon, { className: "size-4" })
95
139
  }
96
140
  ),
97
141
  /* @__PURE__ */ jsx(
98
142
  IconButton,
99
143
  {
100
144
  type: "button",
145
+ size: "sm",
146
+ variant: "ghost",
101
147
  onClick: removeLink,
102
148
  "aria-label": "Remove link",
103
- disabled: !url && !isActive,
104
- variant: "ghost",
105
- color: "default",
106
- children: /* @__PURE__ */ jsx(TrashIcon, {})
149
+ children: /* @__PURE__ */ jsx(TrashIcon, { className: "size-4" })
107
150
  }
108
151
  )
109
152
  ] })
@@ -201,7 +244,8 @@ function LinkPopover({
201
244
  setLink: handleSetLink,
202
245
  removeLink,
203
246
  openLink,
204
- isActive
247
+ isActive,
248
+ onSave: () => setIsOpen(false)
205
249
  }
206
250
  ) })
207
251
  ]
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import {
3
+ InlineMathView
4
+ } from "./chunk-BXHPO3T7.mjs";
5
+
6
+ // src/extensions/math/inline-math.ts
7
+ import { InputRule, mergeAttributes, Node } from "@tiptap/core";
8
+ import { ReactNodeViewRenderer } from "@tiptap/react";
9
+ var InlineMath = Node.create({
10
+ name: "inlineMath",
11
+ group: "inline",
12
+ inline: true,
13
+ atom: true,
14
+ addOptions() {
15
+ return {
16
+ HTMLAttributes: {}
17
+ };
18
+ },
19
+ addAttributes() {
20
+ return {
21
+ latex: {
22
+ default: "",
23
+ parseHTML: (element) => element.getAttribute("data-latex") || "",
24
+ renderHTML: (attributes) => ({
25
+ "data-latex": attributes.latex
26
+ })
27
+ }
28
+ };
29
+ },
30
+ parseHTML() {
31
+ return [
32
+ {
33
+ tag: 'span[data-type="inline-math"]'
34
+ }
35
+ ];
36
+ },
37
+ renderHTML({ HTMLAttributes }) {
38
+ return [
39
+ "span",
40
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
41
+ "data-type": "inline-math"
42
+ })
43
+ ];
44
+ },
45
+ addNodeView() {
46
+ return ReactNodeViewRenderer(InlineMathView, {
47
+ as: "span"
48
+ });
49
+ },
50
+ addCommands() {
51
+ return {
52
+ insertInlineMath: (latex = "") => ({ commands }) => {
53
+ return commands.insertContent({
54
+ type: this.name,
55
+ attrs: { latex }
56
+ });
57
+ }
58
+ };
59
+ },
60
+ addInputRules() {
61
+ return [
62
+ // Inline math with $...$
63
+ new InputRule({
64
+ // Match $...$ but not $$...$$
65
+ find: /(?<!\$)\$([^$]+)\$(?!\$)/,
66
+ handler: ({ state, range, match }) => {
67
+ const latex = match[1];
68
+ const { tr } = state;
69
+ tr.replaceWith(range.from, range.to, this.type.create({ latex }));
70
+ }
71
+ })
72
+ ];
73
+ }
74
+ });
75
+ var inline_math_default = InlineMath;
76
+
77
+ export {
78
+ InlineMath,
79
+ inline_math_default
80
+ };
@@ -0,0 +1,152 @@
1
+ "use client";
2
+ import {
3
+ messages
4
+ } from "./chunk-FRJX2F4T.mjs";
5
+
6
+ // src/extensions/math/inline-math-view.tsx
7
+ import { Button } from "@kopexa/button";
8
+ import { Dialog } from "@kopexa/dialog";
9
+ import { Label } from "@kopexa/label";
10
+ import {
11
+ NodeViewWrapper,
12
+ useEditorState
13
+ } from "@tiptap/react";
14
+ import katex from "katex";
15
+ import "katex/dist/katex.min.css";
16
+ import { useCallback, useEffect, useMemo, useState } from "react";
17
+ import { useIntl } from "react-intl";
18
+ import { jsx, jsxs } from "react/jsx-runtime";
19
+ function InlineMathView({ editor, node, getPos }) {
20
+ const intl = useIntl();
21
+ const attrs = node.attrs;
22
+ const { latex = "" } = attrs;
23
+ const isEditable = useEditorState({
24
+ editor,
25
+ selector: ({ editor: e }) => {
26
+ var _a;
27
+ return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
28
+ }
29
+ });
30
+ const [isOpen, setIsOpen] = useState(false);
31
+ const [localLatex, setLocalLatex] = useState(latex);
32
+ const [error, setError] = useState(null);
33
+ useEffect(() => {
34
+ if (isOpen) {
35
+ setLocalLatex(latex);
36
+ setError(null);
37
+ }
38
+ }, [isOpen, latex]);
39
+ const renderedHtml = useMemo(() => {
40
+ if (!latex) return null;
41
+ try {
42
+ return katex.renderToString(latex, {
43
+ throwOnError: false,
44
+ displayMode: false,
45
+ output: "html"
46
+ });
47
+ } catch {
48
+ return null;
49
+ }
50
+ }, [latex]);
51
+ const previewHtml = useMemo(() => {
52
+ if (!localLatex) return null;
53
+ try {
54
+ setError(null);
55
+ return katex.renderToString(localLatex, {
56
+ throwOnError: true,
57
+ displayMode: false,
58
+ output: "html"
59
+ });
60
+ } catch (_e) {
61
+ setError(intl.formatMessage(messages.invalid_latex));
62
+ return null;
63
+ }
64
+ }, [localLatex, intl]);
65
+ const handleSave = useCallback(() => {
66
+ const pos = getPos();
67
+ if (pos === void 0) return;
68
+ editor.view.dispatch(
69
+ editor.state.tr.setNodeMarkup(pos, void 0, { latex: localLatex })
70
+ );
71
+ setIsOpen(false);
72
+ }, [editor, localLatex, getPos]);
73
+ const handleCancel = useCallback(() => {
74
+ setLocalLatex(latex);
75
+ setError(null);
76
+ setIsOpen(false);
77
+ }, [latex]);
78
+ const handleClick = useCallback(
79
+ (e) => {
80
+ e.stopPropagation();
81
+ e.preventDefault();
82
+ if (isEditable) {
83
+ setIsOpen(true);
84
+ }
85
+ },
86
+ [isEditable]
87
+ );
88
+ const isEmpty = !latex;
89
+ return /* @__PURE__ */ jsxs(
90
+ NodeViewWrapper,
91
+ {
92
+ as: "span",
93
+ className: "inline-math-wrapper",
94
+ "data-type": "inline-math",
95
+ "data-latex": latex,
96
+ children: [
97
+ /* @__PURE__ */ jsx(
98
+ "span",
99
+ {
100
+ className: `inline-math cursor-pointer rounded px-0.5 transition-colors ${isEditable ? "hover:bg-primary/10 hover:ring-1 hover:ring-primary/20" : ""} ${isEmpty ? "text-muted-foreground italic" : ""}`,
101
+ onClick: handleClick,
102
+ children: isEmpty ? /* @__PURE__ */ jsx("span", { className: "text-xs", children: "$?$" }) : renderedHtml ? /* @__PURE__ */ jsx(
103
+ "span",
104
+ {
105
+ dangerouslySetInnerHTML: { __html: renderedHtml }
106
+ }
107
+ ) : /* @__PURE__ */ jsx("span", { className: "text-destructive text-xs", children: latex })
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsx(Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
111
+ /* @__PURE__ */ jsx(Dialog.Header, { children: /* @__PURE__ */ jsx(Dialog.Title, { children: intl.formatMessage(messages.title) }) }),
112
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
113
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
114
+ /* @__PURE__ */ jsx(Label, { className: "text-sm", children: intl.formatMessage(messages.latex_input) }),
115
+ /* @__PURE__ */ jsx(
116
+ "input",
117
+ {
118
+ type: "text",
119
+ className: "w-full p-2 rounded-md border border-input bg-background font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
120
+ value: localLatex,
121
+ onChange: (e) => setLocalLatex(e.target.value),
122
+ placeholder: intl.formatMessage(messages.latex_placeholder),
123
+ spellCheck: false
124
+ }
125
+ ),
126
+ error && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: error })
127
+ ] }),
128
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
129
+ /* @__PURE__ */ jsx(Label, { className: "text-sm", children: intl.formatMessage(messages.preview) }),
130
+ /* @__PURE__ */ jsx("div", { className: "min-h-10 p-3 rounded-md border border-border bg-muted/30 flex items-center justify-center", children: previewHtml ? /* @__PURE__ */ jsx(
131
+ "span",
132
+ {
133
+ dangerouslySetInnerHTML: { __html: previewHtml }
134
+ }
135
+ ) : localLatex ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages.invalid_latex) }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: "$...$" }) })
136
+ ] })
137
+ ] }) }),
138
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
139
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages.cancel) }),
140
+ /* @__PURE__ */ jsx(Button, { onClick: handleSave, disabled: !!error && !!localLatex, children: intl.formatMessage(messages.save) })
141
+ ] })
142
+ ] }) })
143
+ ]
144
+ }
145
+ );
146
+ }
147
+ var inline_math_view_default = InlineMathView;
148
+
149
+ export {
150
+ InlineMathView,
151
+ inline_math_view_default
152
+ };
@@ -1,13 +1,13 @@
1
1
  "use client";
2
- import {
3
- useSlashDropdownMenu
4
- } from "./chunk-B2DHYFSH.mjs";
5
2
  import {
6
3
  SuggestionMenu
7
- } from "./chunk-XLSZK3WJ.mjs";
4
+ } from "./chunk-ZYFCSR3E.mjs";
8
5
  import {
9
6
  filterSuggestionItems
10
7
  } from "./chunk-CNVACBGT.mjs";
8
+ import {
9
+ useSlashDropdownMenu
10
+ } from "./chunk-NEHW62L7.mjs";
11
11
 
12
12
  // src/ui/slash-dropdown-menu/slash-dropdown-menu.tsx
13
13
  import { Button } from "@kopexa/button";
@@ -0,0 +1,55 @@
1
+ "use client";
2
+
3
+ // src/extensions/math/messages.ts
4
+ import { defineMessages } from "react-intl";
5
+ var messages = defineMessages({
6
+ title: {
7
+ id: "editor.math.title",
8
+ defaultMessage: "Formula",
9
+ description: "Math block title"
10
+ },
11
+ edit: {
12
+ id: "editor.math.edit",
13
+ defaultMessage: "Edit",
14
+ description: "Edit button label"
15
+ },
16
+ preview: {
17
+ id: "editor.math.preview",
18
+ defaultMessage: "Preview",
19
+ description: "Preview section label"
20
+ },
21
+ latex_input: {
22
+ id: "editor.math.latex_input",
23
+ defaultMessage: "LaTeX",
24
+ description: "LaTeX input label"
25
+ },
26
+ latex_placeholder: {
27
+ id: "editor.math.latex_placeholder",
28
+ defaultMessage: "Enter LaTeX formula...",
29
+ description: "LaTeX input placeholder"
30
+ },
31
+ invalid_latex: {
32
+ id: "editor.math.invalid_latex",
33
+ defaultMessage: "Invalid LaTeX syntax",
34
+ description: "Error message for invalid LaTeX"
35
+ },
36
+ empty_formula: {
37
+ id: "editor.math.empty_formula",
38
+ defaultMessage: "Click to add formula",
39
+ description: "Placeholder for empty formula"
40
+ },
41
+ save: {
42
+ id: "editor.math.save",
43
+ defaultMessage: "Save",
44
+ description: "Save button label"
45
+ },
46
+ cancel: {
47
+ id: "editor.math.cancel",
48
+ defaultMessage: "Cancel",
49
+ description: "Cancel button label"
50
+ }
51
+ });
52
+
53
+ export {
54
+ messages
55
+ };