@monolith-forensics/monolith-ui 1.9.1-dev.8 → 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 +8 -8
- package/dist/RichTextEditor/Components/BubbleMenu.js +202 -94
- 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 -2
- package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +157 -30
- package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +4 -7
- package/dist/RichTextEditor/RichTextEditor.d.ts +4 -2
- package/dist/RichTextEditor/RichTextEditor.js +395 -15
- 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
- package/dist/RichTextEditor/Extensions/BubbleMenuExtension.d.ts +0 -7
- package/dist/RichTextEditor/Extensions/BubbleMenuExtension.js +0 -157
|
@@ -1,14 +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 {
|
|
7
|
-
import { useEffect, useRef } from "react";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
8
7
|
import { Button } from "../../Button";
|
|
9
8
|
import TextColors from "../Enums/TextColors";
|
|
10
|
-
|
|
11
|
-
|
|
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;
|
|
12
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;
|
|
13
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;
|
|
14
17
|
let withinUnorderedList = false;
|
|
@@ -24,6 +27,11 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
24
27
|
}
|
|
25
28
|
});
|
|
26
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"));
|
|
27
35
|
let nodeTypeLabel = "Select Type";
|
|
28
36
|
let nodeTypeIcon = null;
|
|
29
37
|
if (withinOrderedList) {
|
|
@@ -38,7 +46,11 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
38
46
|
nodeTypeLabel = "Text";
|
|
39
47
|
nodeTypeIcon = _jsx(CaseSensitiveIcon, { size: 16 });
|
|
40
48
|
}
|
|
41
|
-
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") {
|
|
42
54
|
const level = attrs === null || attrs === void 0 ? void 0 : attrs.level;
|
|
43
55
|
nodeTypeLabel = `Heading ${level}`;
|
|
44
56
|
nodeTypeIcon =
|
|
@@ -50,7 +62,6 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
50
62
|
name: "node_type",
|
|
51
63
|
label: nodeTypeLabel,
|
|
52
64
|
type: "menu",
|
|
53
|
-
arrow: true,
|
|
54
65
|
buttonProps: {
|
|
55
66
|
leftSection: nodeTypeIcon,
|
|
56
67
|
style: { fontSize: 11, padding: "4px" },
|
|
@@ -62,13 +73,17 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
62
73
|
data: {
|
|
63
74
|
Icon: CaseSensitiveIcon,
|
|
64
75
|
command: (editor) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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();
|
|
72
87
|
},
|
|
73
88
|
},
|
|
74
89
|
},
|
|
@@ -132,50 +147,107 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
132
147
|
},
|
|
133
148
|
},
|
|
134
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
|
+
: []),
|
|
135
164
|
],
|
|
136
165
|
dropDownProps: {
|
|
137
166
|
renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(item.data.Icon, { size: 16 }), item.label] })),
|
|
138
167
|
},
|
|
139
168
|
},
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
label: "Color",
|
|
143
|
-
type: "menu",
|
|
144
|
-
arrow: true,
|
|
145
|
-
buttonProps: {
|
|
146
|
-
// leftSection: nodeTypeIcon,
|
|
147
|
-
style: { fontSize: 11, padding: "4px" },
|
|
148
|
-
},
|
|
149
|
-
items: [
|
|
169
|
+
...(supportsColor
|
|
170
|
+
? [
|
|
150
171
|
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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] })),
|
|
155
206
|
},
|
|
156
207
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
+
},
|
|
164
226
|
},
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
+
: []),
|
|
179
251
|
{
|
|
180
252
|
name: Extensions.Bold,
|
|
181
253
|
icon: BoldIcon,
|
|
@@ -212,6 +284,45 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
212
284
|
editor.chain().focus().toggleStrike().run();
|
|
213
285
|
},
|
|
214
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
|
+
: []),
|
|
215
326
|
{
|
|
216
327
|
name: Extensions.ClearFormatting,
|
|
217
328
|
icon: RemoveFormattingIcon,
|
|
@@ -224,12 +335,11 @@ const getMenuItems = (editor, customMenuItems, theme) => {
|
|
|
224
335
|
];
|
|
225
336
|
};
|
|
226
337
|
const BubbleMenuContent = styled.div `
|
|
227
|
-
position: fixed;
|
|
228
338
|
display: flex;
|
|
229
339
|
justify-content: space-between;
|
|
230
340
|
align-items: center;
|
|
231
341
|
padding: 2px;
|
|
232
|
-
gap:
|
|
342
|
+
gap: 4px;
|
|
233
343
|
|
|
234
344
|
color: ${({ theme }) => theme.palette.text.primary};
|
|
235
345
|
background-color: ${({ theme }) => theme.palette.input.background};
|
|
@@ -245,6 +355,11 @@ const BubbleMenuContent = styled.div `
|
|
|
245
355
|
transform: scale(0.25); /* Start at half size */
|
|
246
356
|
animation: fadeInEffect 90ms forwards;
|
|
247
357
|
|
|
358
|
+
button {
|
|
359
|
+
min-width: 28px;
|
|
360
|
+
min-height: 28px;
|
|
361
|
+
}
|
|
362
|
+
|
|
248
363
|
/* Animation to handle the fade in */
|
|
249
364
|
@keyframes fadeInEffect {
|
|
250
365
|
0% {
|
|
@@ -261,7 +376,8 @@ const BubbleItemButton = styled(Button) `
|
|
|
261
376
|
font-size: 0.5rem;
|
|
262
377
|
font-weight: 500;
|
|
263
378
|
padding: 4px;
|
|
264
|
-
height:
|
|
379
|
+
height: 28px;
|
|
380
|
+
width: 28px;
|
|
265
381
|
|
|
266
382
|
&.is-active {
|
|
267
383
|
opacity: 1;
|
|
@@ -272,51 +388,43 @@ const BubbleItemButton = styled(Button) `
|
|
|
272
388
|
background-color: ${({ theme }) => theme.palette.action.hover};
|
|
273
389
|
}
|
|
274
390
|
`;
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
+
};
|
|
399
|
+
const BubbleMenu = ({ className, editor, customMenuItems = [], }) => {
|
|
279
400
|
const theme = useTheme();
|
|
280
|
-
|
|
281
|
-
if (open && onOpen) {
|
|
282
|
-
onOpen(elements.floating);
|
|
283
|
-
}
|
|
284
|
-
}, [open, onOpen, elements.floating]);
|
|
285
|
-
const elementWidth = ((_a = elements.floating) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0;
|
|
401
|
+
const [linkEditorOpen, setLinkEditorOpen] = useState(false);
|
|
286
402
|
const { from, to } = editor.state.selection;
|
|
287
403
|
const selectedText = editor.state.doc.textBetween(from, to, "\n", "\n");
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (
|
|
294
|
-
|
|
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) }) }));
|
|
295
411
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (rightOverflow > -10) {
|
|
299
|
-
left -= rightOverflow + 10; // add some padding
|
|
412
|
+
if (isCodeBlockSelection) {
|
|
413
|
+
return (_jsx(BubbleMenuContent, { className: className, children: _jsx(CodeBlockBubbleTools, { editor: editor, theme: theme }) }));
|
|
300
414
|
}
|
|
301
|
-
return (_jsx(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
var _a;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
style: { width: 135 },
|
|
316
|
-
} }, item.dropDownProps, { children: item.icon
|
|
317
|
-
? (_jsx(item.icon, { size: 14 }))
|
|
318
|
-
: (item.label || item.name) }), item.name));
|
|
319
|
-
}
|
|
320
|
-
}) })) }));
|
|
415
|
+
return (_jsx(BubbleMenuContent, { className: className, children: getMenuItems(editor, customMenuItems, theme, () => setLinkEditorOpen(true)).map((item) => {
|
|
416
|
+
var _a;
|
|
417
|
+
if (item.type === "button") {
|
|
418
|
+
const isActive = (_a = item.isActive) === null || _a === void 0 ? void 0 : _a.call(item, editor);
|
|
419
|
+
return (_jsx(BubbleItemButton, { variant: "subtle", onClick: () => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, editor); }, color: isActive ? "primary" : undefined, selected: isActive, children: item.icon && _jsx(item.icon, { size: 14 }) }, item.name));
|
|
420
|
+
}
|
|
421
|
+
if (item.type === "menu") {
|
|
422
|
+
return (_jsx(DropDownMenu, Object.assign({ data: item.items, size: "xs", arrow: item.arrow, buttonProps: item.buttonProps, variant: "subtle", buttonRender: item.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, selectedText); }, dropDownProps: {
|
|
423
|
+
style: { width: 135 },
|
|
424
|
+
} }, item.dropDownProps, { children: item.icon
|
|
425
|
+
? (_jsx(item.icon, { size: 14 }))
|
|
426
|
+
: (item.label || item.name) }), item.name));
|
|
427
|
+
}
|
|
428
|
+
}) }));
|
|
321
429
|
};
|
|
322
430
|
export default BubbleMenu;
|
|
@@ -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;
|