@tnd028/strapi-plugin-tiptap-editor 0.0.1

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 (126) hide show
  1. package/README.md +3 -0
  2. package/dist/_chunks/Alignment-B0f2-LO0.js +135 -0
  3. package/dist/_chunks/Alignment-qMOzO-n2.mjs +133 -0
  4. package/dist/_chunks/Blockquote-9wBGDz3L.mjs +34 -0
  5. package/dist/_chunks/Blockquote-DeGUfK27.js +36 -0
  6. package/dist/_chunks/Bold-C-0g6Ayd.mjs +46 -0
  7. package/dist/_chunks/Bold-ClnPsPHt.js +48 -0
  8. package/dist/_chunks/ColorAndHighlight-BMmtoSpj.js +217 -0
  9. package/dist/_chunks/ColorAndHighlight-t1Ui5tcL.mjs +215 -0
  10. package/dist/_chunks/Emoji-Bm1_vSh5.mjs +263 -0
  11. package/dist/_chunks/Emoji-C-LQZ4Z3.js +265 -0
  12. package/dist/_chunks/Heading-BDJqd1Qw.js +125 -0
  13. package/dist/_chunks/Heading-BycRob5M.mjs +123 -0
  14. package/dist/_chunks/HorizontalRule-CJlDmdma.js +34 -0
  15. package/dist/_chunks/HorizontalRule-CzQCeC3b.mjs +32 -0
  16. package/dist/_chunks/Iframe-DCBWSb0v.mjs +165 -0
  17. package/dist/_chunks/Iframe-Dyn_2cMB.js +167 -0
  18. package/dist/_chunks/ImagePlaceholder-C14kojd5.js +71 -0
  19. package/dist/_chunks/ImagePlaceholder-DtrSuhf_.mjs +69 -0
  20. package/dist/_chunks/Italic-BfpKX0KX.mjs +34 -0
  21. package/dist/_chunks/Italic-DdhVL78v.js +36 -0
  22. package/dist/_chunks/Link-BuYDqSqo.js +61 -0
  23. package/dist/_chunks/Link-DUV5Ybep.mjs +59 -0
  24. package/dist/_chunks/Lists-BKopoFR6.js +107 -0
  25. package/dist/_chunks/Lists-DsKxj3MD.mjs +105 -0
  26. package/dist/_chunks/Redo-1mEX1yOd.js +35 -0
  27. package/dist/_chunks/Redo-Ca3VQxSe.mjs +33 -0
  28. package/dist/_chunks/SearchAndReplace-DmU5DlWv.mjs +347 -0
  29. package/dist/_chunks/SearchAndReplace-DzNdbTWJ.js +349 -0
  30. package/dist/_chunks/Strikethrough-BygxCHak.mjs +121 -0
  31. package/dist/_chunks/Strikethrough-DQfR4OFk.js +123 -0
  32. package/dist/_chunks/Table-BhbZ2Blv.mjs +123 -0
  33. package/dist/_chunks/Table-DLaqBAbz.js +125 -0
  34. package/dist/_chunks/TiptapEditorInput-BDE09h5-.mjs +6802 -0
  35. package/dist/_chunks/TiptapEditorInput-vfLsCt1p.js +6854 -0
  36. package/dist/_chunks/Undo-BuT4OkoE.js +32 -0
  37. package/dist/_chunks/Undo-PL5n4axf.mjs +30 -0
  38. package/dist/_chunks/en-B4KWt_jN.js +4 -0
  39. package/dist/_chunks/en-Byx4XI2L.mjs +4 -0
  40. package/dist/_chunks/index-ku90UbIF.mjs +1397 -0
  41. package/dist/_chunks/index-wYDv8vsJ.js +1398 -0
  42. package/dist/admin/index.js +6 -0
  43. package/dist/admin/index.mjs +6 -0
  44. package/dist/admin/src/components/ContentEditorInput.d.ts +10 -0
  45. package/dist/admin/src/components/GlobalStyling.d.ts +4 -0
  46. package/dist/admin/src/components/Initializer.d.ts +5 -0
  47. package/dist/admin/src/components/MediaLibraryModal.d.ts +27 -0
  48. package/dist/admin/src/components/PluginIcon.d.ts +2 -0
  49. package/dist/admin/src/components/TextEditorInput.d.ts +10 -0
  50. package/dist/admin/src/components/TiptapEditorInput.d.ts +6 -0
  51. package/dist/admin/src/components/editor/BaseEditor.d.ts +22 -0
  52. package/dist/admin/src/components/editor/ContentEditor.d.ts +10 -0
  53. package/dist/admin/src/components/editor/TextEditor.d.ts +10 -0
  54. package/dist/admin/src/components/editor/extensions/Heading.d.ts +2 -0
  55. package/dist/admin/src/components/editor/extensions/Iframe.d.ts +24 -0
  56. package/dist/admin/src/components/editor/extensions/Image.d.ts +3 -0
  57. package/dist/admin/src/components/editor/extensions/ImagePlaceholder.d.ts +15 -0
  58. package/dist/admin/src/components/editor/extensions/custom-component/CustomComponentEditPopover.d.ts +1 -0
  59. package/dist/admin/src/components/editor/extensions/custom-component/CustomComponentExtension.d.ts +3 -0
  60. package/dist/admin/src/components/editor/extensions/custom-component/CustomComponentInsertPopover.d.ts +13 -0
  61. package/dist/admin/src/components/editor/extensions/custom-component/CustomComponentRenderer.d.ts +1 -0
  62. package/dist/admin/src/components/editor/extensions/custom-component/Store.d.ts +20 -0
  63. package/dist/admin/src/components/editor/extensions/custom-component/types.d.ts +33 -0
  64. package/dist/admin/src/components/editor/extensions/fileHandler.d.ts +12 -0
  65. package/dist/admin/src/components/editor/extensions/link.d.ts +1 -0
  66. package/dist/admin/src/components/editor/extensions/noNewLine.d.ts +2 -0
  67. package/dist/admin/src/components/editor/extensions/resetMarksOnEnter.d.ts +2 -0
  68. package/dist/admin/src/components/editor/extensions/searchAndReplace.d.ts +53 -0
  69. package/dist/admin/src/components/editor/partials/EditorProvider.d.ts +13 -0
  70. package/dist/admin/src/components/editor/partials/LinkBubbleMenu.d.ts +5 -0
  71. package/dist/admin/src/components/editor/partials/LinkEditBlock.d.ts +9 -0
  72. package/dist/admin/src/components/editor/partials/LinkPopoverBlock.d.ts +8 -0
  73. package/dist/admin/src/components/editor/partials/ToolbarButton.d.ts +11 -0
  74. package/dist/admin/src/components/editor/partials/ToolbarButtons.d.ts +25 -0
  75. package/dist/admin/src/components/editor/toolbars/Alignment.d.ts +1 -0
  76. package/dist/admin/src/components/editor/toolbars/Blockquote.d.ts +4 -0
  77. package/dist/admin/src/components/editor/toolbars/Bold.d.ts +4 -0
  78. package/dist/admin/src/components/editor/toolbars/BulletList.d.ts +4 -0
  79. package/dist/admin/src/components/editor/toolbars/ColorAndHighlight.d.ts +5 -0
  80. package/dist/admin/src/components/editor/toolbars/Emoji.d.ts +4 -0
  81. package/dist/admin/src/components/editor/toolbars/Heading.d.ts +1 -0
  82. package/dist/admin/src/components/editor/toolbars/HorizontalRule.d.ts +4 -0
  83. package/dist/admin/src/components/editor/toolbars/Iframe.d.ts +3 -0
  84. package/dist/admin/src/components/editor/toolbars/ImagePlaceholder.d.ts +4 -0
  85. package/dist/admin/src/components/editor/toolbars/Italic.d.ts +4 -0
  86. package/dist/admin/src/components/editor/toolbars/Link.d.ts +4 -0
  87. package/dist/admin/src/components/editor/toolbars/Lists.d.ts +1 -0
  88. package/dist/admin/src/components/editor/toolbars/OrderedList.d.ts +4 -0
  89. package/dist/admin/src/components/editor/toolbars/Redo.d.ts +4 -0
  90. package/dist/admin/src/components/editor/toolbars/SearchAndReplace.d.ts +1 -0
  91. package/dist/admin/src/components/editor/toolbars/Strikethrough.d.ts +4 -0
  92. package/dist/admin/src/components/editor/toolbars/Table.d.ts +1 -0
  93. package/dist/admin/src/components/editor/toolbars/Undo.d.ts +4 -0
  94. package/dist/admin/src/components/editor/useEditor.d.ts +18 -0
  95. package/dist/admin/src/components/editor/utils.d.ts +28 -0
  96. package/dist/admin/src/components/ui/button.d.ts +9 -0
  97. package/dist/admin/src/components/ui/dropdown-menu.d.ts +27 -0
  98. package/dist/admin/src/components/ui/input.d.ts +6 -0
  99. package/dist/admin/src/components/ui/label.d.ts +7 -0
  100. package/dist/admin/src/components/ui/separator.d.ts +7 -0
  101. package/dist/admin/src/components/ui/toggle.d.ts +17 -0
  102. package/dist/admin/src/components/ui/tooltip.d.ts +7 -0
  103. package/dist/admin/src/config/index.d.ts +2 -0
  104. package/dist/admin/src/config/pluginConfig.d.ts +20 -0
  105. package/dist/admin/src/config/types.d.ts +109 -0
  106. package/dist/admin/src/errorSlicer.d.ts +4 -0
  107. package/dist/admin/src/exports.d.ts +4 -0
  108. package/dist/admin/src/hooks/useDebounceCallback.d.ts +9 -0
  109. package/dist/admin/src/index.d.ts +25 -0
  110. package/dist/admin/src/pluginId.d.ts +5 -0
  111. package/dist/admin/src/theme/additional.d.ts +1 -0
  112. package/dist/admin/src/theme/colorScheme.d.ts +2 -0
  113. package/dist/admin/src/theme/colors.d.ts +1 -0
  114. package/dist/admin/src/theme/common.d.ts +1 -0
  115. package/dist/admin/src/theme/index.d.ts +2 -0
  116. package/dist/admin/src/types.d.ts +15 -0
  117. package/dist/admin/src/utils/dom.d.ts +7 -0
  118. package/dist/admin/src/utils/getTranslation.d.ts +7 -0
  119. package/dist/admin/src/utils/isImageResponsive.d.ts +8 -0
  120. package/dist/admin/src/utils/localStorage.d.ts +21 -0
  121. package/dist/admin/src/utils/prefixWithBackendUrl.d.ts +6 -0
  122. package/dist/admin/src/utils/utils.d.ts +7 -0
  123. package/dist/server/index.js +15 -0
  124. package/dist/server/index.mjs +16 -0
  125. package/dist/server/src/index.d.ts +7 -0
  126. package/package.json +116 -0
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const lucideReact = require("lucide-react");
6
+ const TiptapEditorInput = require("./TiptapEditorInput-vfLsCt1p.js");
7
+ const designSystem = require("@strapi/design-system");
8
+ const styled = require("styled-components");
9
+ const Emoji = require("@tiptap/extension-emoji");
10
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
12
+ const EmojiIcon = styled__default.default(lucideReact.Smile)`
13
+ width: 16px;
14
+ height: 16px;
15
+ `;
16
+ const PopoverContent = styled__default.default(designSystem.Popover.Content)`
17
+ padding: 0;
18
+ background: ${({ theme }) => theme.colors.neutral0};
19
+ border: 1px solid ${({ theme }) => theme.colors.neutral200};
20
+ box-shadow: ${({ theme }) => theme.shadows.filterShadow};
21
+ border-radius: 4px;
22
+ width: 320px;
23
+ max-width: 90vw;
24
+ display: flex;
25
+ flex-direction: column;
26
+ overflow: hidden;
27
+ `;
28
+ const SearchContainer = styled__default.default.div`
29
+ padding: 8px;
30
+ border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 8px;
34
+ background-color: ${({ theme }) => theme.colors.neutral0};
35
+ `;
36
+ const SearchIcon = styled__default.default(lucideReact.Search)`
37
+ width: 14px;
38
+ height: 14px;
39
+ color: ${({ theme }) => theme.colors.neutral500};
40
+ `;
41
+ const SearchInput = styled__default.default.input`
42
+ border: none;
43
+ background: none;
44
+ outline: none;
45
+ width: 100%;
46
+ font-size: 13px;
47
+ color: ${({ theme }) => theme.colors.neutral800};
48
+
49
+ &::placeholder {
50
+ color: ${({ theme }) => theme.colors.neutral500};
51
+ }
52
+ `;
53
+ const ScrollContainer = styled__default.default.div`
54
+ max-height: 280px;
55
+ height: 280px;
56
+ overflow-y: auto;
57
+ padding: 12px;
58
+ scroll-behavior: smooth;
59
+ `;
60
+ const EmojiGrid = styled__default.default.div`
61
+ display: grid;
62
+ grid-template-columns: repeat(8, 1fr);
63
+ gap: 4px;
64
+ margin-bottom: 12px;
65
+ `;
66
+ const EmojiItem = styled__default.default.button`
67
+ border: none;
68
+ background: none;
69
+ font-size: 20px;
70
+ cursor: pointer;
71
+ padding: 4px;
72
+ width: 32px;
73
+ height: 32px;
74
+ border-radius: 4px;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+
79
+ &:hover {
80
+ background-color: ${({ theme }) => theme.colors.neutral100};
81
+ }
82
+ `;
83
+ const TabBar = styled__default.default.div`
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: space-between;
87
+ padding: 8px 12px;
88
+ border-bottom: 1px solid ${({ theme }) => theme.colors.neutral200};
89
+ background-color: ${({ theme }) => theme.colors.neutral100};
90
+ `;
91
+ const TabButton = styled__default.default.button`
92
+ border: none;
93
+ background: none;
94
+ padding: 4px;
95
+ border-radius: 4px;
96
+ cursor: pointer;
97
+ color: ${({ theme, $isActive }) => $isActive ? theme.colors.primary600 : theme.colors.neutral500};
98
+ background-color: ${({ theme, $isActive }) => $isActive ? theme.colors.primary100 : "transparent"};
99
+
100
+ &:hover {
101
+ background-color: ${({ theme }) => theme.colors.neutral200};
102
+ color: ${({ theme }) => theme.colors.neutral700};
103
+ }
104
+
105
+ svg {
106
+ width: 18px;
107
+ height: 18px;
108
+ }
109
+ `;
110
+ const SectionTitle = styled__default.default.div`
111
+ font-size: 11px;
112
+ font-weight: 600;
113
+ text-transform: uppercase;
114
+ color: ${({ theme }) => theme.colors.neutral500};
115
+ margin-bottom: 4px;
116
+ margin-top: 4px;
117
+ `;
118
+ const CATEGORIES = [
119
+ { id: "recent", icon: lucideReact.Clock, title: "Recent", tags: [] },
120
+ { id: "smileys", icon: lucideReact.Smile, title: "Smileys & People", tags: ["face", "smile", "person", "joy", "happy", "sad", "mad", "hand", "body"] },
121
+ { id: "nature", icon: lucideReact.Cat, title: "Animals & Nature", tags: ["animal", "nature", "cat", "dog", "plant", "flower", "weather"] },
122
+ { id: "food", icon: lucideReact.Coffee, title: "Food & Drink", tags: ["food", "drink", "fruit", "vegetable", "meal"] },
123
+ { id: "activity", icon: lucideReact.Activity, title: "Activity", tags: ["activity", "sport", "game", "play"] },
124
+ { id: "travel", icon: lucideReact.Car, title: "Travel & Places", tags: ["travel", "place", "car", "vehicle", "building", "map"] },
125
+ { id: "objects", icon: lucideReact.Lightbulb, title: "Objects", tags: ["object", "tool", "computer", "device", "light"] },
126
+ { id: "symbols", icon: lucideReact.Hash, title: "Symbols", tags: ["symbol", "shape", "sign", "arrow"] },
127
+ { id: "flags", icon: lucideReact.Flag, title: "Flags", tags: ["flag"] }
128
+ ];
129
+ const EmojiToolbar = React.forwardRef(
130
+ ({ className, onClick, children, ...props }, ref) => {
131
+ const { editor } = TiptapEditorInput.useEditorContext();
132
+ const [open, setOpen] = React.useState(false);
133
+ const [activeCategory, setActiveCategory] = React.useState("recent");
134
+ const [recent, setRecent] = React.useState([]);
135
+ const [searchQuery, setSearchQuery] = React.useState("");
136
+ const searchInputRef = React.useRef(null);
137
+ const scrollRef = React.useRef(null);
138
+ React.useEffect(() => {
139
+ const stored = localStorage.getItem("tiptap-recent-emojis");
140
+ if (stored) {
141
+ try {
142
+ const parsed = JSON.parse(stored);
143
+ setRecent(parsed);
144
+ if (parsed.length === 0) {
145
+ setActiveCategory("smileys");
146
+ }
147
+ } catch (e) {
148
+ console.error("Failed to parse recent emojis", e);
149
+ setActiveCategory("smileys");
150
+ }
151
+ } else {
152
+ setActiveCategory("smileys");
153
+ }
154
+ }, []);
155
+ React.useEffect(() => {
156
+ if (open) {
157
+ setTimeout(() => {
158
+ searchInputRef.current?.focus();
159
+ }, 100);
160
+ } else {
161
+ setSearchQuery("");
162
+ }
163
+ }, [open]);
164
+ const handleEmojiSelect = (emoji) => {
165
+ editor.chain().focus().setEmoji(emoji.name).run();
166
+ const newRecent = [emoji.name, ...recent.filter((n) => n !== emoji.name)].slice(0, 24);
167
+ setRecent(newRecent);
168
+ localStorage.setItem("tiptap-recent-emojis", JSON.stringify(newRecent));
169
+ setOpen(false);
170
+ };
171
+ const scrollToCategory = (catId) => {
172
+ setActiveCategory(catId);
173
+ const element = document.getElementById(`emoji-category-${catId}`);
174
+ if (element && scrollRef.current) {
175
+ scrollRef.current.scrollTop = element.offsetTop - scrollRef.current.offsetTop - 10;
176
+ }
177
+ };
178
+ const categorizedEmojis = React.useMemo(() => {
179
+ const groups = {};
180
+ groups["recent"] = recent.map((name) => Emoji.gitHubEmojis.find((e) => e.name === name)).filter(Boolean);
181
+ CATEGORIES.slice(1).forEach((cat) => {
182
+ groups[cat.id] = Emoji.gitHubEmojis.filter(
183
+ (emoji) => emoji.tags.some((tag) => cat.tags.some((catTag) => tag.includes(catTag)))
184
+ ).slice(0, 100);
185
+ });
186
+ return groups;
187
+ }, [recent]);
188
+ const searchResults = React.useMemo(() => {
189
+ if (!searchQuery.trim()) return [];
190
+ const query = searchQuery.toLowerCase();
191
+ return Emoji.gitHubEmojis.filter(
192
+ (e) => e.name.toLowerCase().includes(query) || e.shortcodes.some((s) => s.includes(query)) || e.tags.some((t) => t.includes(query))
193
+ ).slice(0, 100);
194
+ }, [searchQuery]);
195
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Popover.Root, { open, onOpenChange: setOpen, children: [
196
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Popover.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
197
+ TiptapEditorInput.ToolbarButton,
198
+ {
199
+ tooltip: "Insert Emoji",
200
+ "aria-label": "Insert emoji",
201
+ ref,
202
+ isActive: open,
203
+ ...props,
204
+ children: children || /* @__PURE__ */ jsxRuntime.jsx(EmojiIcon, {})
205
+ }
206
+ ) }),
207
+ /* @__PURE__ */ jsxRuntime.jsxs(PopoverContent, { align: "start", sideOffset: 4, children: [
208
+ /* @__PURE__ */ jsxRuntime.jsx(TabBar, { children: CATEGORIES.map((cat) => {
209
+ const Icon = cat.icon;
210
+ return /* @__PURE__ */ jsxRuntime.jsx(
211
+ TabButton,
212
+ {
213
+ $isActive: activeCategory === cat.id && !searchQuery,
214
+ onClick: () => scrollToCategory(cat.id),
215
+ title: cat.title,
216
+ type: "button",
217
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {})
218
+ },
219
+ cat.id
220
+ );
221
+ }) }),
222
+ /* @__PURE__ */ jsxRuntime.jsxs(SearchContainer, { children: [
223
+ /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, {}),
224
+ /* @__PURE__ */ jsxRuntime.jsx(
225
+ SearchInput,
226
+ {
227
+ ref: searchInputRef,
228
+ placeholder: "Search emojis...",
229
+ value: searchQuery,
230
+ onChange: (e) => setSearchQuery(e.target.value)
231
+ }
232
+ )
233
+ ] }),
234
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollContainer, { ref: scrollRef, children: searchQuery ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: searchResults.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmojiGrid, { children: searchResults.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
235
+ EmojiItem,
236
+ {
237
+ onClick: () => handleEmojiSelect(item),
238
+ title: item.name,
239
+ type: "button",
240
+ children: item.emoji
241
+ },
242
+ item.name
243
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", color: "#666", fontSize: "13px", paddingTop: "20px" }, children: "No results found" }) }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: CATEGORIES.map((cat) => {
244
+ const emojis = categorizedEmojis[cat.id];
245
+ if (!emojis || emojis.length === 0) return null;
246
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: `emoji-category-${cat.id}`, children: [
247
+ /* @__PURE__ */ jsxRuntime.jsx(SectionTitle, { children: cat.title }),
248
+ /* @__PURE__ */ jsxRuntime.jsx(EmojiGrid, { children: emojis.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
249
+ EmojiItem,
250
+ {
251
+ onClick: () => handleEmojiSelect(item),
252
+ title: item.name,
253
+ type: "button",
254
+ children: item.emoji
255
+ },
256
+ item.name
257
+ )) })
258
+ ] }, cat.id);
259
+ }) }) })
260
+ ] })
261
+ ] });
262
+ }
263
+ );
264
+ EmojiToolbar.displayName = "EmojiToolbar";
265
+ exports.EmojiToolbar = EmojiToolbar;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const lucideReact = require("lucide-react");
5
+ const styled = require("styled-components");
6
+ const TiptapEditorInput = require("./TiptapEditorInput-vfLsCt1p.js");
7
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
8
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
9
+ const DropdownMenuItemStyled = styled__default.default(TiptapEditorInput.DropdownMenuItem)`
10
+ display: flex;
11
+ align-items: center;
12
+ gap: 2px;
13
+ padding: 6px 8px 6px 4px;
14
+ font-size: 14px;
15
+
16
+ &:hover {
17
+ background-color: ${(props) => props.theme.colors.neutral100};
18
+ }
19
+
20
+ &:focus {
21
+ background-color: ${(props) => props.theme.colors.neutral100};
22
+ }
23
+
24
+ svg {
25
+ width: 16px;
26
+ height: 16px;
27
+ }
28
+ `;
29
+ const CheckIcon = styled__default.default(lucideReact.Check)`
30
+ width: 12px;
31
+ height: 12px;
32
+ color: ${(props) => props.theme.colors.primary500};
33
+ `;
34
+ const IconWrapper = styled__default.default.div`
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ width: 16px;
39
+ height: 20px;
40
+ margin-right: 4px;
41
+ `;
42
+ const HeadingToolbar = () => {
43
+ const { editor } = TiptapEditorInput.useEditorContext();
44
+ const { extensions = [] } = editor.extensionManager ?? [];
45
+ const headingItems = [1, 2, 3, 4, 5, 6].map((level) => {
46
+ const Icon = [lucideReact.Heading1, lucideReact.Heading2, lucideReact.Heading3, lucideReact.Heading4, lucideReact.Heading5, lucideReact.Heading6][level - 1];
47
+ return {
48
+ action: () => editor.commands.toggleHeading({ level }),
49
+ isActive: () => editor.isActive("heading", { level }) && !editor.getAttributes("heading").class,
50
+ disabled: !editor.can().toggleHeading({ level }),
51
+ title: `Heading ${level}`,
52
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
53
+ shortcutKeys: ["alt", "mod", `${level}`]
54
+ };
55
+ });
56
+ [1, 2, 3, 4, 5, 6].map((level) => {
57
+ return {
58
+ action: () => {
59
+ if (editor.isActive("heading", { level })) {
60
+ const currentClass = editor.getAttributes("heading").class;
61
+ if (currentClass === `display-${level}`) {
62
+ editor.commands.toggleHeading({ level });
63
+ } else {
64
+ editor.chain().focus().updateAttributes("heading", { class: `display-${level}` }).run();
65
+ }
66
+ } else {
67
+ editor.chain().focus().setHeading({ level }).updateAttributes("heading", { class: `display-${level}` }).run();
68
+ }
69
+ },
70
+ isActive: () => editor.isActive("heading", { level }) && editor.getAttributes("heading").class === `display-${level}`,
71
+ disabled: !editor.can().toggleHeading({ level }),
72
+ // Approximation
73
+ title: `Display ${level}`,
74
+ // Visual distinction for Display icons could be different, but for now using Type icon or reusing headings with a distinction
75
+ icon: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: [
76
+ "D",
77
+ level
78
+ ] }),
79
+ shortcutKeys: []
80
+ };
81
+ });
82
+ const items = [
83
+ ...headingItems
84
+ // ...displayItems,
85
+ ];
86
+ const isDisabled = items.every((item) => item.disabled);
87
+ const activeItem = items.find((k) => k.isActive());
88
+ return /* @__PURE__ */ jsxRuntime.jsxs(TiptapEditorInput.DropdownMenu, { children: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(TiptapEditorInput.DropdownMenuTrigger, { disabled: isDisabled, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
90
+ TiptapEditorInput.ToolbarButton,
91
+ {
92
+ tooltip: "Text Heading",
93
+ "aria-label": "Text Heading",
94
+ disabled: isDisabled,
95
+ hasArrow: true,
96
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { children: activeItem ? activeItem.icon : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Heading, {}) })
97
+ }
98
+ ) }),
99
+ /* @__PURE__ */ jsxRuntime.jsx(
100
+ TiptapEditorInput.DropdownMenuContent,
101
+ {
102
+ align: "start",
103
+ loop: true,
104
+ onCloseAutoFocus: (e) => {
105
+ e.preventDefault();
106
+ },
107
+ children: /* @__PURE__ */ jsxRuntime.jsx(TiptapEditorInput.DropdownMenuGroup, { children: items.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
108
+ DropdownMenuItemStyled,
109
+ {
110
+ onSelect: () => {
111
+ option.action();
112
+ },
113
+ children: [
114
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: 12, height: 12, display: "flex", alignItems: "center", justifyContent: "center" }, children: option.isActive() && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) }),
115
+ /* @__PURE__ */ jsxRuntime.jsx(IconWrapper, { children: option.icon }),
116
+ option.title
117
+ ]
118
+ },
119
+ index
120
+ )) })
121
+ }
122
+ )
123
+ ] });
124
+ };
125
+ exports.HeadingToolbar = HeadingToolbar;
@@ -0,0 +1,123 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, Heading, Check } from "lucide-react";
3
+ import styled from "styled-components";
4
+ import { u as useEditorContext, D as DropdownMenu, a as DropdownMenuTrigger, T as ToolbarButton, b as DropdownMenuContent, c as DropdownMenuGroup, d as DropdownMenuItem } from "./TiptapEditorInput-BDE09h5-.mjs";
5
+ const DropdownMenuItemStyled = styled(DropdownMenuItem)`
6
+ display: flex;
7
+ align-items: center;
8
+ gap: 2px;
9
+ padding: 6px 8px 6px 4px;
10
+ font-size: 14px;
11
+
12
+ &:hover {
13
+ background-color: ${(props) => props.theme.colors.neutral100};
14
+ }
15
+
16
+ &:focus {
17
+ background-color: ${(props) => props.theme.colors.neutral100};
18
+ }
19
+
20
+ svg {
21
+ width: 16px;
22
+ height: 16px;
23
+ }
24
+ `;
25
+ const CheckIcon = styled(Check)`
26
+ width: 12px;
27
+ height: 12px;
28
+ color: ${(props) => props.theme.colors.primary500};
29
+ `;
30
+ const IconWrapper = styled.div`
31
+ display: flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ width: 16px;
35
+ height: 20px;
36
+ margin-right: 4px;
37
+ `;
38
+ const HeadingToolbar = () => {
39
+ const { editor } = useEditorContext();
40
+ const { extensions = [] } = editor.extensionManager ?? [];
41
+ const headingItems = [1, 2, 3, 4, 5, 6].map((level) => {
42
+ const Icon = [Heading1, Heading2, Heading3, Heading4, Heading5, Heading6][level - 1];
43
+ return {
44
+ action: () => editor.commands.toggleHeading({ level }),
45
+ isActive: () => editor.isActive("heading", { level }) && !editor.getAttributes("heading").class,
46
+ disabled: !editor.can().toggleHeading({ level }),
47
+ title: `Heading ${level}`,
48
+ icon: /* @__PURE__ */ jsx(Icon, {}),
49
+ shortcutKeys: ["alt", "mod", `${level}`]
50
+ };
51
+ });
52
+ [1, 2, 3, 4, 5, 6].map((level) => {
53
+ return {
54
+ action: () => {
55
+ if (editor.isActive("heading", { level })) {
56
+ const currentClass = editor.getAttributes("heading").class;
57
+ if (currentClass === `display-${level}`) {
58
+ editor.commands.toggleHeading({ level });
59
+ } else {
60
+ editor.chain().focus().updateAttributes("heading", { class: `display-${level}` }).run();
61
+ }
62
+ } else {
63
+ editor.chain().focus().setHeading({ level }).updateAttributes("heading", { class: `display-${level}` }).run();
64
+ }
65
+ },
66
+ isActive: () => editor.isActive("heading", { level }) && editor.getAttributes("heading").class === `display-${level}`,
67
+ disabled: !editor.can().toggleHeading({ level }),
68
+ // Approximation
69
+ title: `Display ${level}`,
70
+ // Visual distinction for Display icons could be different, but for now using Type icon or reusing headings with a distinction
71
+ icon: /* @__PURE__ */ jsxs("span", { style: { fontSize: "10px", fontWeight: "bold" }, children: [
72
+ "D",
73
+ level
74
+ ] }),
75
+ shortcutKeys: []
76
+ };
77
+ });
78
+ const items = [
79
+ ...headingItems
80
+ // ...displayItems,
81
+ ];
82
+ const isDisabled = items.every((item) => item.disabled);
83
+ const activeItem = items.find((k) => k.isActive());
84
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
85
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { disabled: isDisabled, asChild: true, children: /* @__PURE__ */ jsx(
86
+ ToolbarButton,
87
+ {
88
+ tooltip: "Text Heading",
89
+ "aria-label": "Text Heading",
90
+ disabled: isDisabled,
91
+ hasArrow: true,
92
+ children: /* @__PURE__ */ jsx(IconWrapper, { children: activeItem ? activeItem.icon : /* @__PURE__ */ jsx(Heading, {}) })
93
+ }
94
+ ) }),
95
+ /* @__PURE__ */ jsx(
96
+ DropdownMenuContent,
97
+ {
98
+ align: "start",
99
+ loop: true,
100
+ onCloseAutoFocus: (e) => {
101
+ e.preventDefault();
102
+ },
103
+ children: /* @__PURE__ */ jsx(DropdownMenuGroup, { children: items.map((option, index) => /* @__PURE__ */ jsxs(
104
+ DropdownMenuItemStyled,
105
+ {
106
+ onSelect: () => {
107
+ option.action();
108
+ },
109
+ children: [
110
+ /* @__PURE__ */ jsx("div", { style: { width: 12, height: 12, display: "flex", alignItems: "center", justifyContent: "center" }, children: option.isActive() && /* @__PURE__ */ jsx(CheckIcon, {}) }),
111
+ /* @__PURE__ */ jsx(IconWrapper, { children: option.icon }),
112
+ option.title
113
+ ]
114
+ },
115
+ index
116
+ )) })
117
+ }
118
+ )
119
+ ] });
120
+ };
121
+ export {
122
+ HeadingToolbar
123
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const lucideReact = require("lucide-react");
6
+ const TiptapEditorInput = require("./TiptapEditorInput-vfLsCt1p.js");
7
+ const styled = require("styled-components");
8
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
9
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
10
+ const SeparatorHorizontalIcon = styled__default.default(lucideReact.SeparatorHorizontal)`
11
+ width: 16px;
12
+ height: 16px;
13
+ `;
14
+ const HorizontalRuleToolbar = React.forwardRef(
15
+ ({ className, onClick, children, ...props }, ref) => {
16
+ const { editor } = TiptapEditorInput.useEditorContext();
17
+ return /* @__PURE__ */ jsxRuntime.jsx(
18
+ TiptapEditorInput.ToolbarButton,
19
+ {
20
+ tooltip: "Horizontal Rule",
21
+ "aria-label": "Insert horizontal rule",
22
+ onClick: (e) => {
23
+ editor?.chain().focus().setHorizontalRule().run();
24
+ onClick?.(e);
25
+ },
26
+ ref,
27
+ ...props,
28
+ children: children || /* @__PURE__ */ jsxRuntime.jsx(SeparatorHorizontalIcon, {})
29
+ }
30
+ );
31
+ }
32
+ );
33
+ HorizontalRuleToolbar.displayName = "HorizontalRuleToolbar";
34
+ exports.HorizontalRuleToolbar = HorizontalRuleToolbar;
@@ -0,0 +1,32 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
3
+ import { SeparatorHorizontal } from "lucide-react";
4
+ import { u as useEditorContext, T as ToolbarButton } from "./TiptapEditorInput-BDE09h5-.mjs";
5
+ import styled from "styled-components";
6
+ const SeparatorHorizontalIcon = styled(SeparatorHorizontal)`
7
+ width: 16px;
8
+ height: 16px;
9
+ `;
10
+ const HorizontalRuleToolbar = forwardRef(
11
+ ({ className, onClick, children, ...props }, ref) => {
12
+ const { editor } = useEditorContext();
13
+ return /* @__PURE__ */ jsx(
14
+ ToolbarButton,
15
+ {
16
+ tooltip: "Horizontal Rule",
17
+ "aria-label": "Insert horizontal rule",
18
+ onClick: (e) => {
19
+ editor?.chain().focus().setHorizontalRule().run();
20
+ onClick?.(e);
21
+ },
22
+ ref,
23
+ ...props,
24
+ children: children || /* @__PURE__ */ jsx(SeparatorHorizontalIcon, {})
25
+ }
26
+ );
27
+ }
28
+ );
29
+ HorizontalRuleToolbar.displayName = "HorizontalRuleToolbar";
30
+ export {
31
+ HorizontalRuleToolbar
32
+ };