@monolith-forensics/monolith-ui 1.9.1-dev.9 → 1.9.3-dev.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.
- package/dist/DropDownMenu/components/MenuItemList.js +32 -12
- package/dist/DropDownMenu/components/StyledContent.js +1 -1
- package/dist/DropDownMenu/components/StyledInnerItemContainer.js +1 -0
- package/dist/FileViewer/FileViewer.js +32 -8
- package/dist/FileViewer/viewers/ImageViewer.d.ts +1 -0
- package/dist/FileViewer/viewers/ImageViewer.js +36 -15
- package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +23 -0
- package/dist/RichTextEditor/Components/BubbleMenu.d.ts +3 -3
- package/dist/RichTextEditor/Components/BubbleMenu.js +190 -51
- package/dist/RichTextEditor/Components/CodeBlockBaseButton.d.ts +18 -0
- package/dist/RichTextEditor/Components/CodeBlockBaseButton.js +6 -0
- package/dist/RichTextEditor/Components/CodeBlockCopyButton.d.ts +9 -0
- package/dist/RichTextEditor/Components/CodeBlockCopyButton.js +42 -0
- package/dist/RichTextEditor/Components/CodeBlockFormatButton.d.ts +10 -0
- package/dist/RichTextEditor/Components/CodeBlockFormatButton.js +60 -0
- package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.d.ts +9 -0
- package/dist/RichTextEditor/Components/CodeBlockLanguageSelect.js +30 -0
- package/dist/RichTextEditor/Components/CodeBlockNodeView.d.ts +3 -0
- package/dist/RichTextEditor/Components/CodeBlockNodeView.js +28 -0
- package/dist/RichTextEditor/Components/CodeBlockWrapButton.d.ts +10 -0
- package/dist/RichTextEditor/Components/CodeBlockWrapButton.js +17 -0
- package/dist/RichTextEditor/Components/LinkEditor.d.ts +8 -0
- package/dist/RichTextEditor/Components/LinkEditor.js +94 -0
- package/dist/RichTextEditor/Components/TableCornerMenu.d.ts +16 -0
- package/dist/RichTextEditor/Components/TableCornerMenu.js +202 -0
- package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.d.ts +2 -0
- package/dist/RichTextEditor/Components/TableTools/TableCornerMenu.js +19 -0
- package/dist/RichTextEditor/Components/TableTools/TableInsertControls.d.ts +2 -0
- package/dist/RichTextEditor/Components/TableTools/TableInsertControls.js +24 -0
- package/dist/RichTextEditor/Components/TableTools/TableRails.d.ts +2 -0
- package/dist/RichTextEditor/Components/TableTools/TableRails.js +180 -0
- package/dist/RichTextEditor/Components/TableTools/TableToolMenu.d.ts +5 -0
- package/dist/RichTextEditor/Components/TableTools/TableToolMenu.js +6 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.actions.d.ts +5 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.actions.js +183 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.commands.d.ts +16 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.commands.js +217 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.constants.d.ts +8 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.constants.js +11 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.d.ts +3 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.d.ts +23 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.geometry.js +75 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.js +3 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.d.ts +16 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.selectors.js +53 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.styled.d.ts +40 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.styled.js +167 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.types.d.ts +76 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.types.js +1 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.utils.d.ts +4 -0
- package/dist/RichTextEditor/Components/TableTools/TableTools.utils.js +4 -0
- package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.d.ts +2 -0
- package/dist/RichTextEditor/Components/TableTools/TableToolsPopover.js +12 -0
- package/dist/RichTextEditor/Components/TableTools/index.d.ts +3 -0
- package/dist/RichTextEditor/Components/TableTools/index.js +2 -0
- package/dist/RichTextEditor/Components/TableTools.d.ts +44 -0
- package/dist/RichTextEditor/Components/TableTools.js +790 -0
- package/dist/RichTextEditor/Enums/Controls.d.ts +7 -1
- package/dist/RichTextEditor/Enums/Controls.js +6 -0
- package/dist/RichTextEditor/Enums/Extensions.d.ts +4 -0
- package/dist/RichTextEditor/Enums/Extensions.js +4 -0
- package/dist/RichTextEditor/Enums/HighlightColors.d.ts +9 -0
- package/dist/RichTextEditor/Enums/HighlightColors.js +10 -0
- package/dist/RichTextEditor/Enums/SlashCommands.d.ts +4 -1
- package/dist/RichTextEditor/Enums/SlashCommands.js +3 -0
- package/dist/RichTextEditor/Extensions/SlashCommandList.js +0 -1
- package/dist/RichTextEditor/Extensions/getSlashCommand.js +39 -1
- package/dist/RichTextEditor/Extensions/getTiptapExtensions.d.ts +10 -0
- package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +157 -24
- package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +4 -7
- package/dist/RichTextEditor/RichTextEditor.d.ts +3 -1
- package/dist/RichTextEditor/RichTextEditor.js +352 -14
- package/dist/RichTextEditor/Toolbar/Control.d.ts +6 -2
- package/dist/RichTextEditor/Toolbar/Control.js +13 -6
- package/dist/RichTextEditor/Toolbar/Controls.d.ts +6 -0
- package/dist/RichTextEditor/Toolbar/Controls.js +118 -1
- package/dist/RichTextEditor/Toolbar/ControlsGroup.js +17 -6
- package/dist/RichTextEditor/Toolbar/Labels.d.ts +1 -0
- package/dist/RichTextEditor/Toolbar/Labels.js +1 -0
- package/dist/RichTextEditor/Toolbar/Toolbar.d.ts +1 -2
- package/dist/RichTextEditor/Toolbar/Toolbar.js +32 -67
- package/dist/RichTextEditor/Utils/codeBlockUtils.d.ts +20 -0
- package/dist/RichTextEditor/Utils/codeBlockUtils.js +137 -0
- package/dist/RichTextEditor/Utils/codeUtils.d.ts +3 -0
- package/dist/RichTextEditor/Utils/codeUtils.js +12 -0
- package/dist/RichTextEditor/Utils/linkUtils.d.ts +19 -0
- package/dist/RichTextEditor/Utils/linkUtils.js +57 -0
- package/dist/RichTextEditor/Utils/tableUtils.d.ts +1 -0
- package/dist/RichTextEditor/Utils/tableUtils.js +1 -0
- package/dist/theme/variants.js +46 -0
- package/package.json +8 -1
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import styled, { useTheme } from "styled-components";
|
|
3
3
|
import { Extensions } from "../Enums";
|
|
4
|
-
import { BoldIcon, ItalicIcon, UnderlineIcon, CaseSensitiveIcon, ListIcon, ListOrderedIcon, StrikethroughIcon, Heading1Icon, Heading2Icon, Heading3Icon, Heading4Icon, RemoveFormattingIcon, SquircleIcon, } from "lucide-react";
|
|
4
|
+
import { BoldIcon, CodeIcon, ItalicIcon, UnderlineIcon, CaseSensitiveIcon, ListIcon, ListOrderedIcon, SquareCodeIcon, StrikethroughIcon, Heading1Icon, Heading2Icon, Heading3Icon, Heading4Icon, HighlighterIcon, LinkIcon, PaletteIcon, RemoveFormattingIcon, SquircleIcon, } from "lucide-react";
|
|
5
5
|
import { DropDownMenu, } from "../../DropDownMenu";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
6
7
|
import { Button } from "../../Button";
|
|
7
8
|
import TextColors from "../Enums/TextColors";
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
import HighlightColors from "../Enums/HighlightColors";
|
|
10
|
+
import LinkEditor from "./LinkEditor";
|
|
11
|
+
import { hasInlineCode, toggleInlineCode } from "../Utils/codeUtils";
|
|
12
|
+
import { hasSyntaxHighlightedCodeBlock, toggleCodeBlock, } from "../Utils/codeBlockUtils";
|
|
13
|
+
const getMenuItems = (editor, customMenuItems, theme, openLinkEditor) => {
|
|
14
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
10
15
|
const node = (_c = (_b = (_a = editor === null || editor === void 0 ? void 0 : editor.state) === null || _a === void 0 ? void 0 : _a.selection) === null || _b === void 0 ? void 0 : _b.$from) === null || _c === void 0 ? void 0 : _c.parent;
|
|
11
16
|
const pos = (_e = (_d = editor === null || editor === void 0 ? void 0 : editor.state) === null || _d === void 0 ? void 0 : _d.selection) === null || _e === void 0 ? void 0 : _e.$from;
|
|
12
17
|
let withinUnorderedList = false;
|
|
@@ -22,6 +27,11 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
22
27
|
}
|
|
23
28
|
});
|
|
24
29
|
const attrs = node === null || node === void 0 ? void 0 : node.attrs;
|
|
30
|
+
const supportsSyntaxCodeBlock = hasSyntaxHighlightedCodeBlock(editor);
|
|
31
|
+
const supportsInlineCode = hasInlineCode(editor);
|
|
32
|
+
const supportsColor = Boolean(editor.extensionManager.extensions.find((extension) => extension.name === "color"));
|
|
33
|
+
const supportsHighlight = Boolean(editor.extensionManager.extensions.find((extension) => extension.name === "highlight"));
|
|
34
|
+
const supportsLink = Boolean(editor.extensionManager.extensions.find((extension) => extension.name === "link"));
|
|
25
35
|
let nodeTypeLabel = "Select Type";
|
|
26
36
|
let nodeTypeIcon = null;
|
|
27
37
|
if (withinOrderedList) {
|
|
@@ -36,7 +46,11 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
36
46
|
nodeTypeLabel = "Text";
|
|
37
47
|
nodeTypeIcon = _jsx(CaseSensitiveIcon, { size: 16 });
|
|
38
48
|
}
|
|
39
|
-
else if (((_g = node === null || node === void 0 ? void 0 : node.type) === null || _g === void 0 ? void 0 : _g.name) === "
|
|
49
|
+
else if (((_g = node === null || node === void 0 ? void 0 : node.type) === null || _g === void 0 ? void 0 : _g.name) === "codeBlock") {
|
|
50
|
+
nodeTypeLabel = "Code Block";
|
|
51
|
+
nodeTypeIcon = _jsx(SquareCodeIcon, { size: 16 });
|
|
52
|
+
}
|
|
53
|
+
else if (((_h = node === null || node === void 0 ? void 0 : node.type) === null || _h === void 0 ? void 0 : _h.name) === "heading") {
|
|
40
54
|
const level = attrs === null || attrs === void 0 ? void 0 : attrs.level;
|
|
41
55
|
nodeTypeLabel = `Heading ${level}`;
|
|
42
56
|
nodeTypeIcon =
|
|
@@ -48,7 +62,6 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
48
62
|
name: "node_type",
|
|
49
63
|
label: nodeTypeLabel,
|
|
50
64
|
type: "menu",
|
|
51
|
-
arrow: true,
|
|
52
65
|
buttonProps: {
|
|
53
66
|
leftSection: nodeTypeIcon,
|
|
54
67
|
style: { fontSize: 11, padding: "4px" },
|
|
@@ -60,13 +73,17 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
60
73
|
data: {
|
|
61
74
|
Icon: CaseSensitiveIcon,
|
|
62
75
|
command: (editor) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
if (editor.isActive("bulletList") ||
|
|
77
|
+
editor.isActive("orderedList")) {
|
|
78
|
+
editor
|
|
79
|
+
.chain()
|
|
80
|
+
.focus()
|
|
81
|
+
.liftListItem("listItem")
|
|
82
|
+
.setParagraph()
|
|
83
|
+
.run();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
editor.chain().focus().setParagraph().run();
|
|
70
87
|
},
|
|
71
88
|
},
|
|
72
89
|
},
|
|
@@ -130,50 +147,107 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
130
147
|
},
|
|
131
148
|
},
|
|
132
149
|
},
|
|
150
|
+
...(supportsSyntaxCodeBlock
|
|
151
|
+
? [
|
|
152
|
+
{
|
|
153
|
+
label: "Code Block",
|
|
154
|
+
value: "code_block",
|
|
155
|
+
data: {
|
|
156
|
+
Icon: SquareCodeIcon,
|
|
157
|
+
command: (editor) => {
|
|
158
|
+
toggleCodeBlock(editor);
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
]
|
|
163
|
+
: []),
|
|
133
164
|
],
|
|
134
165
|
dropDownProps: {
|
|
135
166
|
renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(item.data.Icon, { size: 16 }), item.label] })),
|
|
136
167
|
},
|
|
137
168
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
label: "Color",
|
|
141
|
-
type: "menu",
|
|
142
|
-
arrow: true,
|
|
143
|
-
buttonProps: {
|
|
144
|
-
// leftSection: nodeTypeIcon,
|
|
145
|
-
style: { fontSize: 11, padding: "4px" },
|
|
146
|
-
},
|
|
147
|
-
items: [
|
|
169
|
+
...(supportsColor
|
|
170
|
+
? [
|
|
148
171
|
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
name: "color",
|
|
173
|
+
label: _jsx(PaletteIcon, { size: 14 }),
|
|
174
|
+
type: "menu",
|
|
175
|
+
buttonProps: {
|
|
176
|
+
style: { padding: "1px 6px" },
|
|
177
|
+
},
|
|
178
|
+
items: [
|
|
179
|
+
{
|
|
180
|
+
label: "Default",
|
|
181
|
+
value: "default",
|
|
182
|
+
onClick: () => {
|
|
183
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetColor().run();
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
...Object.keys(TextColors).map((color) => {
|
|
187
|
+
const colorKey = color;
|
|
188
|
+
return {
|
|
189
|
+
label: color,
|
|
190
|
+
value: TextColors[colorKey],
|
|
191
|
+
onClick: () => {
|
|
192
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().setColor(TextColors[colorKey]).run();
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}),
|
|
196
|
+
],
|
|
197
|
+
dropDownProps: {
|
|
198
|
+
renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(SquircleIcon, { size: 12, color: item.value === "default"
|
|
199
|
+
? theme.palette.text.primary
|
|
200
|
+
: item.value, style: {
|
|
201
|
+
backgroundColor: item.value === "default"
|
|
202
|
+
? theme.palette.text.primary
|
|
203
|
+
: item.value,
|
|
204
|
+
borderRadius: "3px",
|
|
205
|
+
} }), item.label] })),
|
|
153
206
|
},
|
|
154
207
|
},
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
208
|
+
]
|
|
209
|
+
: []),
|
|
210
|
+
...(supportsHighlight
|
|
211
|
+
? [
|
|
212
|
+
{
|
|
213
|
+
name: Extensions.Highlight,
|
|
214
|
+
label: _jsx(HighlighterIcon, { size: 14 }),
|
|
215
|
+
type: "menu",
|
|
216
|
+
buttonProps: {
|
|
217
|
+
style: { padding: "1px 6px" },
|
|
218
|
+
},
|
|
219
|
+
items: [
|
|
220
|
+
{
|
|
221
|
+
label: "Default",
|
|
222
|
+
value: "default",
|
|
223
|
+
onClick: () => {
|
|
224
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetHighlight().run();
|
|
225
|
+
},
|
|
162
226
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
227
|
+
...Object.keys(HighlightColors).map((color) => {
|
|
228
|
+
const colorKey = color;
|
|
229
|
+
return {
|
|
230
|
+
label: color,
|
|
231
|
+
value: HighlightColors[colorKey],
|
|
232
|
+
onClick: () => {
|
|
233
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().setHighlight({ color: HighlightColors[colorKey] }).run();
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
}),
|
|
237
|
+
],
|
|
238
|
+
dropDownProps: {
|
|
239
|
+
renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(SquircleIcon, { size: 12, color: item.value === "default"
|
|
240
|
+
? theme.palette.text.primary
|
|
241
|
+
: item.value, style: {
|
|
242
|
+
backgroundColor: item.value === "default"
|
|
243
|
+
? "transparent"
|
|
244
|
+
: item.value,
|
|
245
|
+
borderRadius: "3px",
|
|
246
|
+
} }), item.label] })),
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
]
|
|
250
|
+
: []),
|
|
177
251
|
{
|
|
178
252
|
name: Extensions.Bold,
|
|
179
253
|
icon: BoldIcon,
|
|
@@ -210,6 +284,45 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
210
284
|
editor.chain().focus().toggleStrike().run();
|
|
211
285
|
},
|
|
212
286
|
},
|
|
287
|
+
...(supportsLink
|
|
288
|
+
? [
|
|
289
|
+
{
|
|
290
|
+
name: Extensions.Link,
|
|
291
|
+
icon: LinkIcon,
|
|
292
|
+
type: "button",
|
|
293
|
+
isActive: (editor) => editor.isActive("link"),
|
|
294
|
+
onClick: () => {
|
|
295
|
+
openLinkEditor();
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
]
|
|
299
|
+
: []),
|
|
300
|
+
...(supportsInlineCode
|
|
301
|
+
? [
|
|
302
|
+
{
|
|
303
|
+
name: Extensions.Code,
|
|
304
|
+
icon: CodeIcon,
|
|
305
|
+
type: "button",
|
|
306
|
+
isActive: (editor) => editor.isActive("code"),
|
|
307
|
+
onClick: (editor) => {
|
|
308
|
+
toggleInlineCode(editor);
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
]
|
|
312
|
+
: []),
|
|
313
|
+
...(supportsSyntaxCodeBlock
|
|
314
|
+
? [
|
|
315
|
+
{
|
|
316
|
+
name: Extensions.CodeBlock,
|
|
317
|
+
icon: SquareCodeIcon,
|
|
318
|
+
type: "button",
|
|
319
|
+
isActive: (editor) => editor.isActive("codeBlock"),
|
|
320
|
+
onClick: (editor) => {
|
|
321
|
+
toggleCodeBlock(editor);
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
]
|
|
325
|
+
: []),
|
|
213
326
|
{
|
|
214
327
|
name: Extensions.ClearFormatting,
|
|
215
328
|
icon: RemoveFormattingIcon,
|
|
@@ -226,7 +339,7 @@ const BubbleMenuContent = styled.div `
|
|
|
226
339
|
justify-content: space-between;
|
|
227
340
|
align-items: center;
|
|
228
341
|
padding: 2px;
|
|
229
|
-
gap:
|
|
342
|
+
gap: 4px;
|
|
230
343
|
|
|
231
344
|
color: ${({ theme }) => theme.palette.text.primary};
|
|
232
345
|
background-color: ${({ theme }) => theme.palette.input.background};
|
|
@@ -242,6 +355,11 @@ const BubbleMenuContent = styled.div `
|
|
|
242
355
|
transform: scale(0.25); /* Start at half size */
|
|
243
356
|
animation: fadeInEffect 90ms forwards;
|
|
244
357
|
|
|
358
|
+
button {
|
|
359
|
+
min-width: 28px;
|
|
360
|
+
min-height: 28px;
|
|
361
|
+
}
|
|
362
|
+
|
|
245
363
|
/* Animation to handle the fade in */
|
|
246
364
|
@keyframes fadeInEffect {
|
|
247
365
|
0% {
|
|
@@ -258,7 +376,8 @@ const BubbleItemButton = styled(Button) `
|
|
|
258
376
|
font-size: 0.5rem;
|
|
259
377
|
font-weight: 500;
|
|
260
378
|
padding: 4px;
|
|
261
|
-
height:
|
|
379
|
+
height: 28px;
|
|
380
|
+
width: 28px;
|
|
262
381
|
|
|
263
382
|
&.is-active {
|
|
264
383
|
opacity: 1;
|
|
@@ -269,11 +388,31 @@ const BubbleItemButton = styled(Button) `
|
|
|
269
388
|
background-color: ${({ theme }) => theme.palette.action.hover};
|
|
270
389
|
}
|
|
271
390
|
`;
|
|
391
|
+
const CodeBlockBubbleTools = ({ editor, theme, }) => {
|
|
392
|
+
const nodeTypeMenu = getMenuItems(editor, [], theme, () => undefined).find((item) => item.name === "node_type");
|
|
393
|
+
return (_jsx(_Fragment, { children: (nodeTypeMenu === null || nodeTypeMenu === void 0 ? void 0 : nodeTypeMenu.type) === "menu" && (_jsx(DropDownMenu, Object.assign({ data: nodeTypeMenu.items, size: "xs", arrow: nodeTypeMenu.arrow, buttonProps: nodeTypeMenu.buttonProps, variant: "subtle", buttonRender: nodeTypeMenu.buttonRender, onItemSelect: (item) => { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.data) === null || _a === void 0 ? void 0 : _a.command) === null || _b === void 0 ? void 0 : _b.call(_a, editor, ""); }, dropDownProps: {
|
|
394
|
+
style: { width: 135 },
|
|
395
|
+
} }, nodeTypeMenu.dropDownProps, { children: nodeTypeMenu.icon
|
|
396
|
+
? (_jsx(nodeTypeMenu.icon, { size: 14 }))
|
|
397
|
+
: (nodeTypeMenu.label || nodeTypeMenu.name) }))) }));
|
|
398
|
+
};
|
|
272
399
|
const BubbleMenu = ({ className, editor, customMenuItems = [], }) => {
|
|
273
400
|
const theme = useTheme();
|
|
401
|
+
const [linkEditorOpen, setLinkEditorOpen] = useState(false);
|
|
274
402
|
const { from, to } = editor.state.selection;
|
|
275
403
|
const selectedText = editor.state.doc.textBetween(from, to, "\n", "\n");
|
|
276
|
-
|
|
404
|
+
const isLinkSelection = editor.isActive("link");
|
|
405
|
+
const isCodeBlockSelection = editor.isActive("codeBlock") && hasSyntaxHighlightedCodeBlock(editor);
|
|
406
|
+
useEffect(() => {
|
|
407
|
+
setLinkEditorOpen(false);
|
|
408
|
+
}, [from, to]);
|
|
409
|
+
if (isLinkSelection || linkEditorOpen) {
|
|
410
|
+
return (_jsx(BubbleMenuContent, { className: className, children: _jsx(LinkEditor, { editor: editor, autoFocus: true, onClose: () => setLinkEditorOpen(false) }) }));
|
|
411
|
+
}
|
|
412
|
+
if (isCodeBlockSelection) {
|
|
413
|
+
return (_jsx(BubbleMenuContent, { className: className, children: _jsx(CodeBlockBubbleTools, { editor: editor, theme: theme }) }));
|
|
414
|
+
}
|
|
415
|
+
return (_jsx(BubbleMenuContent, { className: className, children: getMenuItems(editor, customMenuItems, theme, () => setLinkEditorOpen(true)).map((item) => {
|
|
277
416
|
var _a;
|
|
278
417
|
if (item.type === "button") {
|
|
279
418
|
const isActive = (_a = item.isActive) === null || _a === void 0 ? void 0 : _a.call(item, editor);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const CodeBlockBaseButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
2
|
+
ref?: import("react").RefObject<HTMLButtonElement>;
|
|
3
|
+
children?: import("react").ReactNode | string;
|
|
4
|
+
className?: string;
|
|
5
|
+
loading?: boolean;
|
|
6
|
+
leftSection?: import("react").ReactNode;
|
|
7
|
+
rightSection?: import("react").ReactNode;
|
|
8
|
+
href?: string | null;
|
|
9
|
+
download?: string | null;
|
|
10
|
+
fullWidth?: boolean;
|
|
11
|
+
size?: import("../../core").Size;
|
|
12
|
+
variant?: import("../../core").Variant;
|
|
13
|
+
color?: import("../../Button").ButtonColor;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
selected?: boolean;
|
|
16
|
+
justify?: "start" | "center" | "end";
|
|
17
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
18
|
+
}, never>> & string & Omit<import("react").FC<import("../../Button").ButtonProps>, keyof import("react").Component<any, {}, any>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/react";
|
|
2
|
+
type CodeBlockCopyButtonProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
editor?: Editor | null;
|
|
5
|
+
text?: string;
|
|
6
|
+
size?: "xs" | "sm";
|
|
7
|
+
};
|
|
8
|
+
declare const CodeBlockCopyButton: ({ className, editor, text, size, }: CodeBlockCopyButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default CodeBlockCopyButton;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
13
|
+
import { copyCodeBlockText, getActiveCodeBlockText, } from "../Utils/codeBlockUtils";
|
|
14
|
+
import { CodeBlockBaseButton } from "./CodeBlockBaseButton";
|
|
15
|
+
const CodeBlockCopyButton = ({ className, editor, text, size = "xs", }) => {
|
|
16
|
+
const [copied, setCopied] = useState(false);
|
|
17
|
+
const [copyFailed, setCopyFailed] = useState(false);
|
|
18
|
+
const code = text !== null && text !== void 0 ? text : getActiveCodeBlockText(editor || null);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!copied && !copyFailed)
|
|
21
|
+
return;
|
|
22
|
+
const timeout = window.setTimeout(() => {
|
|
23
|
+
setCopied(false);
|
|
24
|
+
setCopyFailed(false);
|
|
25
|
+
}, 1400);
|
|
26
|
+
return () => window.clearTimeout(timeout);
|
|
27
|
+
}, [copied, copyFailed]);
|
|
28
|
+
return (_jsx(CodeBlockBaseButton, { className: className, size: size, variant: "outlined", title: copyFailed ? "Unable to copy" : copied ? "Copied" : "Copy code", "aria-label": copyFailed ? "Unable to copy code" : copied ? "Copied" : "Copy code", disabled: !code, onClick: (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
event.preventDefault();
|
|
30
|
+
event.stopPropagation();
|
|
31
|
+
try {
|
|
32
|
+
yield copyCodeBlockText(code);
|
|
33
|
+
setCopied(true);
|
|
34
|
+
setCopyFailed(false);
|
|
35
|
+
}
|
|
36
|
+
catch (_a) {
|
|
37
|
+
setCopied(false);
|
|
38
|
+
setCopyFailed(true);
|
|
39
|
+
}
|
|
40
|
+
}), children: copied ? _jsx(CheckIcon, { size: 14 }) : _jsx(CopyIcon, { size: 14 }) }));
|
|
41
|
+
};
|
|
42
|
+
export default CodeBlockCopyButton;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/react";
|
|
2
|
+
type CodeBlockFormatButtonProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
editor?: Editor | null;
|
|
5
|
+
language?: string;
|
|
6
|
+
onFormat?: () => Promise<void>;
|
|
7
|
+
size?: "xs" | "sm";
|
|
8
|
+
};
|
|
9
|
+
declare const CodeBlockFormatButton: ({ className, editor, language, onFormat, size, }: CodeBlockFormatButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default CodeBlockFormatButton;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { CheckIcon, TriangleAlertIcon, WandSparklesIcon } from "lucide-react";
|
|
13
|
+
import { canFormatCodeBlockLanguage, formatActiveCodeBlock, getCodeBlockLanguage, } from "../Utils/codeBlockUtils";
|
|
14
|
+
import { CodeBlockBaseButton } from "./CodeBlockBaseButton";
|
|
15
|
+
const CodeBlockFormatButton = ({ className, editor, language, onFormat, size = "xs", }) => {
|
|
16
|
+
const [formatted, setFormatted] = useState(false);
|
|
17
|
+
const [formatFailed, setFormatFailed] = useState(false);
|
|
18
|
+
const codeLanguage = language !== null && language !== void 0 ? language : getCodeBlockLanguage(editor || null);
|
|
19
|
+
const canFormat = canFormatCodeBlockLanguage(codeLanguage);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!formatted && !formatFailed)
|
|
22
|
+
return;
|
|
23
|
+
const timeout = window.setTimeout(() => {
|
|
24
|
+
setFormatted(false);
|
|
25
|
+
setFormatFailed(false);
|
|
26
|
+
}, 1400);
|
|
27
|
+
return () => window.clearTimeout(timeout);
|
|
28
|
+
}, [formatted, formatFailed]);
|
|
29
|
+
return (_jsx(CodeBlockBaseButton, { className: className, size: size, variant: "outlined", title: !canFormat
|
|
30
|
+
? "Formatting is not supported for this language"
|
|
31
|
+
: formatFailed
|
|
32
|
+
? "Unable to format code"
|
|
33
|
+
: formatted
|
|
34
|
+
? "Formatted"
|
|
35
|
+
: "Format code", "aria-label": !canFormat
|
|
36
|
+
? "Formatting is not supported for this language"
|
|
37
|
+
: formatFailed
|
|
38
|
+
? "Unable to format code"
|
|
39
|
+
: formatted
|
|
40
|
+
? "Formatted"
|
|
41
|
+
: "Format code", disabled: !canFormat || (!onFormat && !(editor === null || editor === void 0 ? void 0 : editor.isActive("codeBlock"))), onClick: (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
event.stopPropagation();
|
|
44
|
+
try {
|
|
45
|
+
if (onFormat) {
|
|
46
|
+
yield onFormat();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
yield formatActiveCodeBlock(editor || null);
|
|
50
|
+
}
|
|
51
|
+
setFormatted(true);
|
|
52
|
+
setFormatFailed(false);
|
|
53
|
+
}
|
|
54
|
+
catch (_a) {
|
|
55
|
+
setFormatted(false);
|
|
56
|
+
setFormatFailed(true);
|
|
57
|
+
}
|
|
58
|
+
}), children: formatted ? (_jsx(CheckIcon, { size: 14 })) : formatFailed ? (_jsx(TriangleAlertIcon, { size: 14 })) : (_jsx(WandSparklesIcon, { size: 14 })) }));
|
|
59
|
+
};
|
|
60
|
+
export default CodeBlockFormatButton;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/react";
|
|
2
|
+
type CodeBlockLanguageSelectProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
editor?: Editor | null;
|
|
5
|
+
language?: string;
|
|
6
|
+
onLanguageChange?: (language: string) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const CodeBlockLanguageSelect: ({ className, editor, language, onLanguageChange, }: CodeBlockLanguageSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default CodeBlockLanguageSelect;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CodeXmlIcon } from "lucide-react";
|
|
3
|
+
import { DropDownMenu } from "../../DropDownMenu";
|
|
4
|
+
import { CODE_BLOCK_LANGUAGES, getCodeBlockLanguage, getCodeBlockLanguageOption, setCodeBlockLanguage, } from "../Utils/codeBlockUtils";
|
|
5
|
+
import { useTheme } from "styled-components";
|
|
6
|
+
const CodeBlockLanguageSelect = ({ className, editor, language, onLanguageChange, }) => {
|
|
7
|
+
const theme = useTheme();
|
|
8
|
+
const codeLanguage = language !== null && language !== void 0 ? language : getCodeBlockLanguage(editor || null);
|
|
9
|
+
const selectedLanguage = getCodeBlockLanguageOption(codeLanguage);
|
|
10
|
+
return (_jsx(DropDownMenu, { className: className, data: CODE_BLOCK_LANGUAGES, value: [selectedLanguage], enableSelectedOptionStyling: true, size: "xs", variant: "outlined", disabled: !onLanguageChange && !(editor === null || editor === void 0 ? void 0 : editor.isActive("codeBlock")), onItemSelect: (item) => {
|
|
11
|
+
if (onLanguageChange) {
|
|
12
|
+
onLanguageChange(item.value);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setCodeBlockLanguage(editor || null, item.value);
|
|
16
|
+
}, buttonProps: {
|
|
17
|
+
title: "Select code language",
|
|
18
|
+
leftSection: _jsx(CodeXmlIcon, { size: 12 }),
|
|
19
|
+
style: {
|
|
20
|
+
padding: "1px 6px",
|
|
21
|
+
backgroundColor: theme.palette.background.paper,
|
|
22
|
+
},
|
|
23
|
+
}, dropDownProps: {
|
|
24
|
+
style: {
|
|
25
|
+
width: 150,
|
|
26
|
+
height: 250,
|
|
27
|
+
},
|
|
28
|
+
}, children: selectedLanguage.label }));
|
|
29
|
+
};
|
|
30
|
+
export default CodeBlockLanguageSelect;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { NodeViewContent, NodeViewWrapper, } from "@tiptap/react";
|
|
12
|
+
import CodeBlockCopyButton from "./CodeBlockCopyButton";
|
|
13
|
+
import CodeBlockWrapButton from "./CodeBlockWrapButton";
|
|
14
|
+
import CodeBlockFormatButton from "./CodeBlockFormatButton";
|
|
15
|
+
import CodeBlockLanguageSelect from "./CodeBlockLanguageSelect";
|
|
16
|
+
import { formatCodeBlockText, replaceCodeBlockContent, } from "../Utils/codeBlockUtils";
|
|
17
|
+
const CodeBlockNodeView = ({ editor, getPos, node, updateAttributes, }) => {
|
|
18
|
+
const language = node.attrs.language;
|
|
19
|
+
const wrap = Boolean(node.attrs.wrap);
|
|
20
|
+
return (_jsxs(NodeViewWrapper, { as: "pre", className: "editor-code-block", "data-language": language || "plaintext", "data-wrap": wrap ? "true" : "false", children: [_jsxs("div", { className: "editor-code-block-actions", contentEditable: false, children: [_jsx(CodeBlockLanguageSelect, { language: language, onLanguageChange: (language) => updateAttributes({ language }) }), _jsx(CodeBlockWrapButton, { active: wrap, onToggle: () => updateAttributes({ wrap: !wrap }) }), _jsx(CodeBlockFormatButton, { className: "editor-code-block-action", language: language, onFormat: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
const pos = getPos();
|
|
22
|
+
if (typeof pos !== "number")
|
|
23
|
+
return;
|
|
24
|
+
const formatted = yield formatCodeBlockText(node.textContent, language);
|
|
25
|
+
replaceCodeBlockContent(editor, pos + 1, pos + node.nodeSize - 1, formatted);
|
|
26
|
+
}) }), _jsx(CodeBlockCopyButton, { className: "editor-code-block-action", text: node.textContent })] }), _jsx(NodeViewContent, { as: "code", className: `hljs language-${language || "plaintext"}`, spellCheck: false })] }));
|
|
27
|
+
};
|
|
28
|
+
export default CodeBlockNodeView;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/react";
|
|
2
|
+
type CodeBlockWrapButtonProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
editor?: Editor | null;
|
|
5
|
+
active?: boolean;
|
|
6
|
+
onToggle?: () => void;
|
|
7
|
+
size?: "xs" | "sm";
|
|
8
|
+
};
|
|
9
|
+
declare const CodeBlockWrapButton: ({ className, editor, active, onToggle, size, }: CodeBlockWrapButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default CodeBlockWrapButton;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { WrapTextIcon } from "lucide-react";
|
|
3
|
+
import { getCodeBlockWrap, toggleCodeBlockWrap } from "../Utils/codeBlockUtils";
|
|
4
|
+
import { CodeBlockBaseButton } from "./CodeBlockBaseButton";
|
|
5
|
+
const CodeBlockWrapButton = ({ className, editor, active, onToggle, size = "xs", }) => {
|
|
6
|
+
const isWrapped = active !== null && active !== void 0 ? active : getCodeBlockWrap(editor || null);
|
|
7
|
+
return (_jsx(CodeBlockBaseButton, { className: className, size: size, variant: "outlined", title: isWrapped ? "Disable code wrapping" : "Enable code wrapping", "aria-label": isWrapped ? "Disable code wrapping" : "Enable code wrapping", selected: isWrapped, disabled: !onToggle && !(editor === null || editor === void 0 ? void 0 : editor.isActive("codeBlock")), onClick: (event) => {
|
|
8
|
+
event.preventDefault();
|
|
9
|
+
event.stopPropagation();
|
|
10
|
+
if (onToggle) {
|
|
11
|
+
onToggle();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
toggleCodeBlockWrap(editor || null);
|
|
15
|
+
}, children: _jsx(WrapTextIcon, { size: 14 }) }));
|
|
16
|
+
};
|
|
17
|
+
export default CodeBlockWrapButton;
|