@monolith-forensics/monolith-ui 1.9.1-dev.1 → 1.9.1-dev.11
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/StyledInnerItemContainer.js +1 -0
- package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +23 -0
- package/dist/RichTextEditor/Components/BubbleMenu.d.ts +8 -8
- package/dist/RichTextEditor/Components/BubbleMenu.js +195 -93
- 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/Enums/Controls.d.ts +5 -1
- package/dist/RichTextEditor/Enums/Controls.js +4 -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 +2 -0
- package/dist/RichTextEditor/Enums/SlashCommands.js +2 -0
- package/dist/RichTextEditor/Extensions/SlashCommandList.js +0 -1
- package/dist/RichTextEditor/Extensions/getSlashCommand.js +25 -1
- package/dist/RichTextEditor/Extensions/getTiptapExtensions.d.ts +10 -2
- package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +158 -31
- package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +6 -109
- package/dist/RichTextEditor/Plugins/UploadImagesPlugin.js +1 -0
- package/dist/RichTextEditor/RichTextEditor.d.ts +4 -2
- package/dist/RichTextEditor/RichTextEditor.js +323 -13
- package/dist/RichTextEditor/Toolbar/Control.d.ts +6 -2
- package/dist/RichTextEditor/Toolbar/Control.js +13 -6
- package/dist/RichTextEditor/Toolbar/Controls.d.ts +2 -0
- package/dist/RichTextEditor/Toolbar/Controls.js +14 -0
- package/dist/RichTextEditor/Toolbar/ControlsGroup.js +1 -0
- package/dist/RichTextEditor/Toolbar/Toolbar.js +61 -9
- 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/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
|
@@ -8,17 +8,77 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { useEffect, useRef, useState } from "react";
|
|
11
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
12
12
|
import styled from "styled-components";
|
|
13
13
|
import { EditorContent, useEditor } from "@tiptap/react";
|
|
14
|
+
import { BubbleMenu as TiptapBubbleMenu, } from "@tiptap/react/menus";
|
|
15
|
+
import { isTextSelection } from "@tiptap/core";
|
|
14
16
|
import { DOMParser as ProseMirrorDOMParser } from "@tiptap/pm/model";
|
|
17
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
15
18
|
import { Toolbar } from "./Toolbar";
|
|
16
|
-
import getTipTapExtensions from "./Extensions/getTiptapExtensions";
|
|
17
|
-
import { Extensions, SlashCommands } from "./Enums";
|
|
19
|
+
import getTipTapExtensions, { resolveExtensions, } from "./Extensions/getTiptapExtensions";
|
|
20
|
+
import { Controls, Extensions, SlashCommands } from "./Enums";
|
|
18
21
|
import { addImagePlaceholder, removeImagePlaceholder, startImageUpload, } from "./Plugins/UploadImagesPlugin";
|
|
19
22
|
import SaveBadge from "./Components/SaveBadge";
|
|
23
|
+
import BubbleMenuContent from "./Components/BubbleMenu";
|
|
20
24
|
import Fonts from "./Enums/Fonts";
|
|
21
25
|
import RichTextEditorContext from "./Contexts/RichTextEditorContext";
|
|
26
|
+
import { getLinkAttributesAtPosition, getLinkRangeAtPosition, openLink, } from "./Utils/linkUtils";
|
|
27
|
+
const codeBlockFallbacks = {
|
|
28
|
+
light: {
|
|
29
|
+
background: "#f6f8fa",
|
|
30
|
+
text: "#24292f",
|
|
31
|
+
border: "#d0d7de",
|
|
32
|
+
selection: "#0969da2e",
|
|
33
|
+
syntax: {
|
|
34
|
+
comment: "#6e7781",
|
|
35
|
+
punctuation: "#24292f",
|
|
36
|
+
property: "#0550ae",
|
|
37
|
+
selector: "#116329",
|
|
38
|
+
operator: "#cf222e",
|
|
39
|
+
keyword: "#cf222e",
|
|
40
|
+
string: "#0a3069",
|
|
41
|
+
number: "#0550ae",
|
|
42
|
+
function: "#8250df",
|
|
43
|
+
variable: "#953800",
|
|
44
|
+
tag: "#116329",
|
|
45
|
+
attribute: "#0550ae",
|
|
46
|
+
literal: "#0550ae",
|
|
47
|
+
deleted: "#82071e",
|
|
48
|
+
inserted: "#116329",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
dark: {
|
|
52
|
+
background: "#0d1117",
|
|
53
|
+
text: "#c9d1d9",
|
|
54
|
+
border: "#30363d",
|
|
55
|
+
selection: "#1f6feb40",
|
|
56
|
+
syntax: {
|
|
57
|
+
comment: "#8b949e",
|
|
58
|
+
punctuation: "#c9d1d9",
|
|
59
|
+
property: "#79c0ff",
|
|
60
|
+
selector: "#7ee787",
|
|
61
|
+
operator: "#ff7b72",
|
|
62
|
+
keyword: "#ff7b72",
|
|
63
|
+
string: "#a5d6ff",
|
|
64
|
+
number: "#79c0ff",
|
|
65
|
+
function: "#d2a8ff",
|
|
66
|
+
variable: "#ffa657",
|
|
67
|
+
tag: "#7ee787",
|
|
68
|
+
attribute: "#79c0ff",
|
|
69
|
+
literal: "#79c0ff",
|
|
70
|
+
deleted: "#ffa198",
|
|
71
|
+
inserted: "#aff5b4",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const getCodeBlockTheme = (theme) => {
|
|
76
|
+
if (theme.palette.codeBlock)
|
|
77
|
+
return theme.palette.codeBlock;
|
|
78
|
+
return theme.palette.mode === "DARK"
|
|
79
|
+
? codeBlockFallbacks.dark
|
|
80
|
+
: codeBlockFallbacks.light;
|
|
81
|
+
};
|
|
22
82
|
const getImageFilesFromClipboard = (clipboardData) => {
|
|
23
83
|
return Array.from(clipboardData.files).filter((file) => file.type.includes("image/"));
|
|
24
84
|
};
|
|
@@ -317,6 +377,158 @@ const StyledContent = styled.div `
|
|
|
317
377
|
margin: 0;
|
|
318
378
|
line-height: 1.5rem;
|
|
319
379
|
}
|
|
380
|
+
.editor-inline-code,
|
|
381
|
+
:not(pre) > code {
|
|
382
|
+
padding: 0.1rem 0.25rem;
|
|
383
|
+
border: 1px solid ${({ theme }) => theme.palette.divider};
|
|
384
|
+
border-radius: 4px;
|
|
385
|
+
background-color: ${({ theme }) => theme.palette.action.hover};
|
|
386
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
|
387
|
+
font-family:
|
|
388
|
+
ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
389
|
+
"Liberation Mono", "Courier New", monospace;
|
|
390
|
+
font-size: 0.9em;
|
|
391
|
+
box-decoration-break: clone;
|
|
392
|
+
}
|
|
393
|
+
.editor-code-block {
|
|
394
|
+
position: relative;
|
|
395
|
+
margin: 0.5rem 0;
|
|
396
|
+
padding: 1rem 0.875rem;
|
|
397
|
+
overflow-x: auto;
|
|
398
|
+
border: 1px solid ${({ theme }) => getCodeBlockTheme(theme).border};
|
|
399
|
+
border-radius: 6px;
|
|
400
|
+
background-color: ${({ theme }) => getCodeBlockTheme(theme).background};
|
|
401
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).text};
|
|
402
|
+
font-family:
|
|
403
|
+
ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
404
|
+
"Liberation Mono", "Courier New", monospace;
|
|
405
|
+
font-size: 0.85rem;
|
|
406
|
+
line-height: 1.45rem;
|
|
407
|
+
white-space: pre;
|
|
408
|
+
|
|
409
|
+
::selection {
|
|
410
|
+
background-color: ${({ theme }) => getCodeBlockTheme(theme).selection};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
&[data-wrap="true"] {
|
|
414
|
+
white-space: pre-wrap;
|
|
415
|
+
word-break: break-word;
|
|
416
|
+
overflow-wrap: anywhere;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
code {
|
|
420
|
+
display: block;
|
|
421
|
+
min-width: max-content;
|
|
422
|
+
padding: 0;
|
|
423
|
+
border: 0;
|
|
424
|
+
background-color: transparent;
|
|
425
|
+
color: inherit;
|
|
426
|
+
font: inherit;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
&[data-wrap="true"] code {
|
|
430
|
+
min-width: 0;
|
|
431
|
+
white-space: inherit;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.editor-code-block-actions {
|
|
435
|
+
display: flex;
|
|
436
|
+
align-items: center;
|
|
437
|
+
position: absolute;
|
|
438
|
+
top: 0.4rem;
|
|
439
|
+
right: 0.4rem;
|
|
440
|
+
z-index: 1;
|
|
441
|
+
gap: 0.25rem;
|
|
442
|
+
opacity: 0;
|
|
443
|
+
transition: opacity 120ms ease-in-out;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
&:hover .editor-code-block-actions,
|
|
447
|
+
&:focus-within .editor-code-block-actions {
|
|
448
|
+
opacity: 1;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.hljs-comment,
|
|
452
|
+
.hljs-quote {
|
|
453
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.comment};
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.hljs-punctuation {
|
|
457
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.punctuation};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.hljs-property,
|
|
461
|
+
.hljs-attr,
|
|
462
|
+
.hljs-attribute,
|
|
463
|
+
.hljs-doctag {
|
|
464
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.property};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.hljs-selector-tag,
|
|
468
|
+
.hljs-selector-id,
|
|
469
|
+
.hljs-selector-class,
|
|
470
|
+
.hljs-selector-attr,
|
|
471
|
+
.hljs-selector-pseudo {
|
|
472
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.selector};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.hljs-operator,
|
|
476
|
+
.hljs-params {
|
|
477
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.operator};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.hljs-keyword,
|
|
481
|
+
.hljs-meta .hljs-keyword,
|
|
482
|
+
.hljs-template-tag,
|
|
483
|
+
.hljs-template-variable {
|
|
484
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.keyword};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.hljs-string,
|
|
488
|
+
.hljs-regexp {
|
|
489
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.string};
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.hljs-number {
|
|
493
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.number};
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.hljs-title,
|
|
497
|
+
.hljs-title.function_,
|
|
498
|
+
.hljs-title.class_ {
|
|
499
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.function};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.hljs-variable,
|
|
503
|
+
.hljs-name,
|
|
504
|
+
.hljs-section,
|
|
505
|
+
.hljs-symbol {
|
|
506
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.variable};
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.hljs-tag {
|
|
510
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.tag};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.hljs-built_in,
|
|
514
|
+
.hljs-type,
|
|
515
|
+
.hljs-literal {
|
|
516
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.literal};
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.hljs-meta,
|
|
520
|
+
.hljs-link {
|
|
521
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.attribute};
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.hljs-deletion {
|
|
525
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.deleted};
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.hljs-addition {
|
|
529
|
+
color: ${({ theme }) => getCodeBlockTheme(theme).syntax.inserted};
|
|
530
|
+
}
|
|
531
|
+
}
|
|
320
532
|
ul {
|
|
321
533
|
margin: 0;
|
|
322
534
|
}
|
|
@@ -330,8 +542,6 @@ const StyledContent = styled.div `
|
|
|
330
542
|
color: ${({ theme }) => theme.palette.text.primary};
|
|
331
543
|
text-decoration: underline;
|
|
332
544
|
cursor: pointer;
|
|
333
|
-
// Set title attribute
|
|
334
|
-
title: "Click to open link";
|
|
335
545
|
}
|
|
336
546
|
img {
|
|
337
547
|
max-width: 100%;
|
|
@@ -543,16 +753,99 @@ const StyledContent = styled.div `
|
|
|
543
753
|
margin: 0 0.125rem;
|
|
544
754
|
}
|
|
545
755
|
`;
|
|
546
|
-
export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = "", value, readOnly = false, font, showToolbar = true, saving = false, extensions = [], slashCommands = [], bubbleMenuOptions, toolbarOptions, autoFocus, onChange, handleImageUpload, handleImageUrlUpload, style, }) => {
|
|
756
|
+
export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = "", value, readOnly = false, font, showToolbar = true, saving = false, disabledExtensions = [], extensionPreset = "basic", extensions = [], slashCommands = [], bubbleMenuOptions, toolbarOptions, autoFocus, onChange, handleImageUpload, handleImageUrlUpload, style, }) => {
|
|
757
|
+
const resolvedExtensions = useMemo(() => resolveExtensions({
|
|
758
|
+
disabledExtensions,
|
|
759
|
+
extensionPreset,
|
|
760
|
+
extensions,
|
|
761
|
+
}), [disabledExtensions, extensionPreset, extensions]);
|
|
762
|
+
const resolvedExtensionSet = useMemo(() => new Set(resolvedExtensions), [resolvedExtensions]);
|
|
763
|
+
const resolvedSlashCommands = useMemo(() => slashCommands.filter((command) => {
|
|
764
|
+
if (command === SlashCommands.Code) {
|
|
765
|
+
return resolvedExtensionSet.has(Extensions.Code);
|
|
766
|
+
}
|
|
767
|
+
if (command === SlashCommands.CodeBlock) {
|
|
768
|
+
return resolvedExtensionSet.has(Extensions.CodeBlock);
|
|
769
|
+
}
|
|
770
|
+
return true;
|
|
771
|
+
}), [resolvedExtensionSet, slashCommands]);
|
|
772
|
+
const resolvedToolbarOptions = useMemo(() => {
|
|
773
|
+
if (!(toolbarOptions === null || toolbarOptions === void 0 ? void 0 : toolbarOptions.controls))
|
|
774
|
+
return toolbarOptions;
|
|
775
|
+
const controlExtensionMap = {
|
|
776
|
+
[Controls.BOLD]: Extensions.Bold,
|
|
777
|
+
[Controls.ITALIC]: Extensions.Italic,
|
|
778
|
+
[Controls.UNDERLINE]: Extensions.Underline,
|
|
779
|
+
[Controls.STRIKE]: Extensions.Strike,
|
|
780
|
+
[Controls.CODE]: Extensions.Code,
|
|
781
|
+
[Controls.CODE_BLOCK]: Extensions.CodeBlock,
|
|
782
|
+
[Controls.BULLET_LIST]: Extensions.BulletList,
|
|
783
|
+
[Controls.ORDERED_LIST]: Extensions.OrderedList,
|
|
784
|
+
[Controls.COLOR]: Extensions.Color,
|
|
785
|
+
[Controls.HIGHLIGHT]: Extensions.Highlight,
|
|
786
|
+
[Controls.LINK]: Extensions.Link,
|
|
787
|
+
[Controls.TEXT_ALIGN_LEFT]: Extensions.TextAlign,
|
|
788
|
+
[Controls.TEXT_ALIGN_CENTER]: Extensions.TextAlign,
|
|
789
|
+
[Controls.TEXT_ALIGN_RIGHT]: Extensions.TextAlign,
|
|
790
|
+
[Controls.TEXT_ALIGN_JUSTIFIED]: Extensions.TextAlign,
|
|
791
|
+
};
|
|
792
|
+
return Object.assign(Object.assign({}, toolbarOptions), { controls: toolbarOptions.controls.filter((control) => {
|
|
793
|
+
if (typeof control !== "string")
|
|
794
|
+
return true;
|
|
795
|
+
const extension = controlExtensionMap[control];
|
|
796
|
+
return !extension || resolvedExtensionSet.has(extension);
|
|
797
|
+
}) });
|
|
798
|
+
}, [resolvedExtensionSet, toolbarOptions]);
|
|
547
799
|
const isControlled = value !== undefined;
|
|
548
|
-
const hasImageExtension =
|
|
549
|
-
const hasSlashCommandExtension =
|
|
550
|
-
const
|
|
800
|
+
const hasImageExtension = resolvedExtensionSet.has(Extensions.Image);
|
|
801
|
+
const hasSlashCommandExtension = resolvedExtensionSet.has(Extensions.SlashCommand);
|
|
802
|
+
const hasBubbleMenuExtension = resolvedExtensionSet.has(Extensions.BubbleMenu);
|
|
803
|
+
const hasImageSlashCommand = hasSlashCommandExtension &&
|
|
804
|
+
resolvedSlashCommands.includes(SlashCommands.Image);
|
|
551
805
|
const onChangeRef = useRef(onChange);
|
|
806
|
+
const bubbleMenuPortalRef = useRef(null);
|
|
552
807
|
const [fontState, setFontState] = useState(font || Fonts.DEFAULT);
|
|
553
808
|
useEffect(() => {
|
|
554
809
|
onChangeRef.current = onChange;
|
|
555
810
|
}, [onChange]);
|
|
811
|
+
const getBubbleMenuPortalRoot = useCallback(() => {
|
|
812
|
+
if (bubbleMenuPortalRef.current) {
|
|
813
|
+
return bubbleMenuPortalRef.current;
|
|
814
|
+
}
|
|
815
|
+
const portal = document.createElement("div");
|
|
816
|
+
portal.setAttribute("data-monolith-bubble-menu-portal", "");
|
|
817
|
+
document.body.appendChild(portal);
|
|
818
|
+
bubbleMenuPortalRef.current = portal;
|
|
819
|
+
return portal;
|
|
820
|
+
}, []);
|
|
821
|
+
useEffect(() => {
|
|
822
|
+
return () => {
|
|
823
|
+
var _a;
|
|
824
|
+
(_a = bubbleMenuPortalRef.current) === null || _a === void 0 ? void 0 : _a.remove();
|
|
825
|
+
bubbleMenuPortalRef.current = null;
|
|
826
|
+
};
|
|
827
|
+
}, []);
|
|
828
|
+
const shouldShowBubbleMenu = useCallback(({ editor, element, view, state, from, to }) => {
|
|
829
|
+
const { selection } = state;
|
|
830
|
+
const isChildOfMenu = element.contains(document.activeElement);
|
|
831
|
+
const hasEditorFocus = view.hasFocus() || isChildOfMenu;
|
|
832
|
+
const selectedText = state.doc.textBetween(from, to).trim();
|
|
833
|
+
const isEmptyTextBlock = !selectedText && isTextSelection(state.selection);
|
|
834
|
+
if (!hasEditorFocus ||
|
|
835
|
+
selection.empty ||
|
|
836
|
+
isEmptyTextBlock ||
|
|
837
|
+
!editor.isEditable) {
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
return true;
|
|
841
|
+
}, []);
|
|
842
|
+
const bubbleMenuPositionOptions = useMemo(() => ({
|
|
843
|
+
strategy: "fixed",
|
|
844
|
+
placement: "top",
|
|
845
|
+
offset: 8,
|
|
846
|
+
flip: false,
|
|
847
|
+
shift: { padding: 10 },
|
|
848
|
+
}), []);
|
|
556
849
|
if (hasImageSlashCommand && !hasImageExtension) {
|
|
557
850
|
throw new Error("Extensions.Image is required when using the Image slash command.");
|
|
558
851
|
}
|
|
@@ -566,12 +859,29 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
|
|
|
566
859
|
editable: !readOnly,
|
|
567
860
|
shouldRerenderOnTransaction: true,
|
|
568
861
|
extensions: getTipTapExtensions({
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
862
|
+
disabledExtensions,
|
|
863
|
+
extensions: resolvedExtensions,
|
|
864
|
+
slashCommands: resolvedSlashCommands,
|
|
572
865
|
handleImageUpload,
|
|
573
866
|
}),
|
|
574
867
|
editorProps: {
|
|
868
|
+
handleClick: (view, pos, event) => {
|
|
869
|
+
const linkRange = getLinkRangeAtPosition(view.state, pos);
|
|
870
|
+
const linkAttributes = getLinkAttributesAtPosition(view.state, pos);
|
|
871
|
+
if (!linkRange || !(linkAttributes === null || linkAttributes === void 0 ? void 0 : linkAttributes.href))
|
|
872
|
+
return false;
|
|
873
|
+
const mouseEvent = event;
|
|
874
|
+
mouseEvent.preventDefault();
|
|
875
|
+
mouseEvent.stopPropagation();
|
|
876
|
+
const shouldOpenLink = mouseEvent.metaKey || mouseEvent.ctrlKey || !view.editable;
|
|
877
|
+
if (shouldOpenLink) {
|
|
878
|
+
openLink(linkAttributes.href);
|
|
879
|
+
return true;
|
|
880
|
+
}
|
|
881
|
+
view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, linkRange.from, linkRange.to)));
|
|
882
|
+
view.focus();
|
|
883
|
+
return true;
|
|
884
|
+
},
|
|
575
885
|
handlePaste: (view, event) => {
|
|
576
886
|
if (!hasImageExtension || !handleImageUpload)
|
|
577
887
|
return false;
|
|
@@ -632,5 +942,5 @@ export const RichTextEditor = ({ className, editorInstanceRef, defaultValue = ""
|
|
|
632
942
|
return (_jsx(StyledContent, { className: className, children: _jsxs(RichTextEditorContext.Provider, { value: {
|
|
633
943
|
font: fontState,
|
|
634
944
|
setFont: setFontState,
|
|
635
|
-
}, children: [showToolbar && (_jsx(Toolbar, { editor: editor, toolbarOptions:
|
|
945
|
+
}, children: [showToolbar && (_jsx(Toolbar, { editor: editor, toolbarOptions: resolvedToolbarOptions })), saving && _jsx(SaveBadge, {}), editor && hasBubbleMenuExtension && (_jsx(TiptapBubbleMenu, { editor: editor, pluginKey: "bubbleMenu", updateDelay: 200, appendTo: getBubbleMenuPortalRoot, shouldShow: shouldShowBubbleMenu, options: bubbleMenuPositionOptions, children: _jsx(BubbleMenuContent, { editor: editor, customMenuItems: bubbleMenuOptions === null || bubbleMenuOptions === void 0 ? void 0 : bubbleMenuOptions.customMenuItems }) })), _jsx(EditorContent, { className: "editor-content", editor: editor, "data-font": fontState || null, style: style })] }) }));
|
|
636
946
|
};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { Editor } from "@tiptap/react";
|
|
2
|
+
import { ButtonProps } from "../../Button";
|
|
2
3
|
export type ControlProps = {
|
|
3
4
|
className?: string;
|
|
4
5
|
editor: Editor | null;
|
|
5
6
|
isActive?: any;
|
|
6
|
-
operation
|
|
7
|
+
operation?: {
|
|
7
8
|
name: string;
|
|
8
9
|
attributes?: any;
|
|
9
10
|
};
|
|
11
|
+
onClick?: (editor: Editor | null) => void;
|
|
12
|
+
disabled?: boolean;
|
|
10
13
|
label: string;
|
|
11
14
|
icon: any;
|
|
15
|
+
size?: ButtonProps["size"];
|
|
12
16
|
};
|
|
13
|
-
export declare const Control: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<ControlProps, never>> & string & Omit<({ className, editor, isActive, operation, label, icon: Icon, }: ControlProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
|
|
17
|
+
export declare const Control: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<ControlProps, never>> & string & Omit<({ className, editor, isActive, operation, onClick, disabled, label, icon: Icon, size, }: ControlProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
|
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import styled from "styled-components";
|
|
3
3
|
import Labels from "./Labels";
|
|
4
|
-
|
|
4
|
+
import { Button } from "../../Button";
|
|
5
|
+
export const Control = styled(({ className, editor, isActive, operation, onClick, disabled, label, icon: Icon, size = "xs", }) => {
|
|
5
6
|
var _a;
|
|
6
7
|
const _label = Labels[label];
|
|
7
8
|
const active = (isActive === null || isActive === void 0 ? void 0 : isActive.name)
|
|
8
9
|
? (_a = editor === null || editor === void 0 ? void 0 : editor.isActive) === null || _a === void 0 ? void 0 : _a.call(editor, isActive.name, isActive.attributes)
|
|
9
10
|
: false;
|
|
10
|
-
return (_jsx(
|
|
11
|
+
return (_jsx(Button, { className: className + (active ? " active" : ""), "aria-label": _label, "data-active": active, title: _label, disabled: disabled, onClick: () => {
|
|
12
|
+
if (onClick) {
|
|
13
|
+
onClick(editor);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (!operation)
|
|
17
|
+
return;
|
|
11
18
|
const focus = editor === null || editor === void 0 ? void 0 : editor.chain().focus();
|
|
12
19
|
focus[operation.name](operation.attributes).run();
|
|
13
|
-
}, children: _jsx(Icon, { size: "16px" }) }));
|
|
20
|
+
}, size: size, children: _jsx(Icon, { size: "16px" }) }));
|
|
14
21
|
}) `
|
|
15
22
|
display: flex;
|
|
16
23
|
justify-content: center;
|
|
17
24
|
align-items: center;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
|
|
26
|
+
padding: 5px;
|
|
27
|
+
|
|
21
28
|
background-color: transparent;
|
|
22
29
|
cursor: pointer;
|
|
23
30
|
color: ${({ theme }) => theme.palette.text.primary};
|
|
@@ -8,6 +8,8 @@ export declare const BoldControl: ({ editor }: ControlProps) => import("react/js
|
|
|
8
8
|
export declare const ItalicControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export declare const UnderlineControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export declare const StrikeThroughControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const CodeControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare const CodeBlockControl: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
13
|
export declare const Heading1Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
14
|
export declare const Heading2Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
15
|
export declare const Heading3Control: ({ editor }: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { IconBold, IconItalic, IconUnderline, IconStrikethrough, IconH1, IconH2, IconH3, IconH4, IconList, IconListNumbers, IconAlignLeft, IconAlignRight, IconAlignCenter, IconAlignJustified, IconCornerUpLeft, IconCornerUpRight, } from "@tabler/icons-react";
|
|
3
|
+
import { CodeIcon } from "lucide-react";
|
|
4
|
+
import { SquareCodeIcon } from "lucide-react";
|
|
3
5
|
import { Control } from "./Control";
|
|
6
|
+
import { hasInlineCode, toggleInlineCode } from "../Utils/codeUtils";
|
|
7
|
+
import { hasSyntaxHighlightedCodeBlock, toggleCodeBlock, } from "../Utils/codeBlockUtils";
|
|
4
8
|
export const UndoControl = ({ editor }) => {
|
|
5
9
|
return (_jsx(Control, { editor: editor, label: "undoControlLabel", operation: {
|
|
6
10
|
name: "undo",
|
|
@@ -39,6 +43,16 @@ export const StrikeThroughControl = ({ editor }) => {
|
|
|
39
43
|
name: "toggleStrike",
|
|
40
44
|
}, icon: IconStrikethrough }));
|
|
41
45
|
};
|
|
46
|
+
export const CodeControl = ({ editor }) => {
|
|
47
|
+
return (_jsx(Control, { editor: editor, label: "codeControlLabel", isActive: {
|
|
48
|
+
name: "code",
|
|
49
|
+
}, onClick: toggleInlineCode, disabled: !hasInlineCode(editor), icon: CodeIcon }));
|
|
50
|
+
};
|
|
51
|
+
export const CodeBlockControl = ({ editor }) => {
|
|
52
|
+
return (_jsx(Control, { editor: editor, label: "codeBlockControlLabel", isActive: {
|
|
53
|
+
name: "codeBlock",
|
|
54
|
+
}, onClick: toggleCodeBlock, disabled: !hasSyntaxHighlightedCodeBlock(editor), icon: SquareCodeIcon }));
|
|
55
|
+
};
|
|
42
56
|
export const Heading1Control = ({ editor }) => {
|
|
43
57
|
return (_jsx(Control, { editor: editor, label: "h1ControlLabel", isActive: {
|
|
44
58
|
name: "heading",
|
|
@@ -1,33 +1,41 @@
|
|
|
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 ControlsGroup from "./ControlsGroup";
|
|
4
|
-
import { UndoControl, RedoControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, Heading1Control, Heading2Control, Heading3Control, Heading4Control, BulletListControl, OrderedListControl, AlignLeftControl, AlignCenterControl, AlignRightControl, AlignJustifiedControl, } from "./Controls";
|
|
4
|
+
import { UndoControl, RedoControl, BoldControl, ItalicControl, UnderlineControl, StrikeThroughControl, CodeControl, CodeBlockControl, Heading1Control, Heading2Control, Heading3Control, Heading4Control, BulletListControl, OrderedListControl, AlignLeftControl, AlignCenterControl, AlignRightControl, AlignJustifiedControl, } from "./Controls";
|
|
5
5
|
import { Controls } from "../Enums";
|
|
6
6
|
import { DropDownMenu } from "../../DropDownMenu";
|
|
7
7
|
import Fonts from "../Enums/Fonts";
|
|
8
|
-
import { useContext } from "react";
|
|
8
|
+
import { useContext, useState } from "react";
|
|
9
9
|
import RichTextEditorContext from "../Contexts/RichTextEditorContext";
|
|
10
10
|
import { Button } from "../../Button";
|
|
11
|
+
import { Popover } from "../../Popover";
|
|
11
12
|
import TextColors from "../Enums/TextColors";
|
|
12
|
-
import
|
|
13
|
+
import HighlightColors from "../Enums/HighlightColors";
|
|
14
|
+
import LinkEditor from "../Components/LinkEditor";
|
|
15
|
+
import CodeBlockWrapButton from "../Components/CodeBlockWrapButton";
|
|
16
|
+
import CodeBlockFormatButton from "../Components/CodeBlockFormatButton";
|
|
17
|
+
import { hasSyntaxHighlightedCodeBlock } from "../Utils/codeBlockUtils";
|
|
18
|
+
import { HighlighterIcon, LinkIcon, PaletteIcon, SquircleIcon, TypeIcon, } from "lucide-react";
|
|
13
19
|
export const Toolbar = styled(({ className, editor, toolbarOptions }) => {
|
|
14
20
|
var _a;
|
|
15
21
|
const theme = useTheme();
|
|
16
22
|
const { controls } = toolbarOptions || {};
|
|
23
|
+
const [linkPopoverOpen, setLinkPopoverOpen] = useState(false);
|
|
17
24
|
const customItems = controls === null || controls === void 0 ? void 0 : controls.filter((control) => typeof control !== "string" &&
|
|
18
25
|
(control.type === "menu" || control.type === "button"));
|
|
19
26
|
const { font, setFont } = useContext(RichTextEditorContext);
|
|
27
|
+
const showCodeBlockLanguageSelect = (editor === null || editor === void 0 ? void 0 : editor.isActive("codeBlock")) && hasSyntaxHighlightedCodeBlock(editor);
|
|
20
28
|
return (_jsxs("div", { className: className, children: [(_a = customItems === null || customItems === void 0 ? void 0 : customItems.map) === null || _a === void 0 ? void 0 : _a.call(customItems, (item, index) => {
|
|
21
29
|
var _a, _b;
|
|
22
30
|
if (item.type === "button") {
|
|
23
|
-
return (_jsx(Button, Object.assign({}, item.options, { children: (_a = item === null || item === void 0 ? void 0 : item.options) === null || _a === void 0 ? void 0 : _a.label }), index));
|
|
31
|
+
return (_jsx(Button, Object.assign({ size: "xs" }, item.options, { children: (_a = item === null || item === void 0 ? void 0 : item.options) === null || _a === void 0 ? void 0 : _a.label }), index));
|
|
24
32
|
}
|
|
25
33
|
else if (item.type === "menu") {
|
|
26
34
|
return (_jsx(DropDownMenu, Object.assign({ dropDownProps: {
|
|
27
35
|
style: {
|
|
28
36
|
width: 135,
|
|
29
37
|
},
|
|
30
|
-
} }, item.options, { children: (_b = item === null || item === void 0 ? void 0 : item.options) === null || _b === void 0 ? void 0 : _b.label }), index));
|
|
38
|
+
} }, item.options, { size: "xs", children: (_b = item === null || item === void 0 ? void 0 : item.options) === null || _b === void 0 ? void 0 : _b.label }), index));
|
|
31
39
|
}
|
|
32
40
|
}), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.FONT)) && (_jsx(DropDownMenu, { data: Object.values(Fonts).map((font) => ({
|
|
33
41
|
label: font,
|
|
@@ -35,12 +43,13 @@ export const Toolbar = styled(({ className, editor, toolbarOptions }) => {
|
|
|
35
43
|
onClick: () => {
|
|
36
44
|
setFont(font);
|
|
37
45
|
},
|
|
38
|
-
})), size: "
|
|
46
|
+
})), size: "xs", variant: "outlined", dropDownProps: {
|
|
39
47
|
style: {
|
|
40
48
|
width: 135,
|
|
41
49
|
},
|
|
42
50
|
}, buttonProps: {
|
|
43
51
|
title: "Select Font",
|
|
52
|
+
leftSection: _jsx(TypeIcon, { size: 12 }),
|
|
44
53
|
}, children: (font || Fonts.DEFAULT) })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDO)) && _jsx(UndoControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.REDO)) && _jsx(RedoControl, { editor: editor })] }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.COLOR)) && (_jsx(DropDownMenu, { data: [
|
|
45
54
|
{
|
|
46
55
|
label: "Default",
|
|
@@ -66,20 +75,63 @@ export const Toolbar = styled(({ className, editor, toolbarOptions }) => {
|
|
|
66
75
|
? theme.palette.text.primary
|
|
67
76
|
: item.value,
|
|
68
77
|
borderRadius: "3px",
|
|
69
|
-
} }), item.label] })), size: "
|
|
78
|
+
} }), item.label] })), size: "xs", variant: "outlined", buttonProps: {
|
|
70
79
|
title: "Select Color",
|
|
80
|
+
style: { padding: "1px 6px" },
|
|
81
|
+
}, dropDownProps: {
|
|
82
|
+
style: {
|
|
83
|
+
width: 120,
|
|
84
|
+
},
|
|
85
|
+
}, children: _jsx(PaletteIcon, { size: 14 }) })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HIGHLIGHT)) && (_jsx(DropDownMenu, { data: [
|
|
86
|
+
{
|
|
87
|
+
label: "Default",
|
|
88
|
+
value: "default",
|
|
89
|
+
onClick: () => {
|
|
90
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().unsetHighlight().run();
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
...Object.keys(HighlightColors).map((color) => {
|
|
94
|
+
const colorKey = color;
|
|
95
|
+
return {
|
|
96
|
+
label: color,
|
|
97
|
+
value: HighlightColors[colorKey],
|
|
98
|
+
onClick: () => {
|
|
99
|
+
editor === null || editor === void 0 ? void 0 : editor.chain().focus().setHighlight({ color: HighlightColors[colorKey] }).run();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}),
|
|
103
|
+
], renderOption: (item) => (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [_jsx(SquircleIcon, { size: 12, color: item.value === "default"
|
|
104
|
+
? theme.palette.text.primary
|
|
105
|
+
: item.value, style: {
|
|
106
|
+
backgroundColor: item.value === "default"
|
|
107
|
+
? "transparent"
|
|
108
|
+
: item.value,
|
|
109
|
+
borderRadius: "3px",
|
|
110
|
+
} }), item.label] })), size: "xs", variant: "outlined", buttonProps: {
|
|
111
|
+
title: "Select Highlight",
|
|
112
|
+
style: { padding: "1px 6px" },
|
|
71
113
|
}, dropDownProps: {
|
|
72
114
|
style: {
|
|
73
115
|
width: 100,
|
|
116
|
+
height: 210,
|
|
74
117
|
},
|
|
75
|
-
}, children:
|
|
118
|
+
}, children: _jsx(HighlighterIcon, { size: 14 }) })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.LINK)) && (_jsxs(Popover, { opened: linkPopoverOpen, onChange: setLinkPopoverOpen, position: "bottom", width: 330, trapFocus: true, children: [_jsx(Popover.Target, { children: _jsx(Button, { size: "xs", variant: "outlined", title: "Link", "aria-label": "Link", selected: linkPopoverOpen || Boolean(editor === null || editor === void 0 ? void 0 : editor.isActive("link")), disabled: !editor, style: { padding: "1px 6px" }, children: _jsx(LinkIcon, { size: 14 }) }) }), _jsx(Popover.Dropdown, { children: editor && (_jsx(LinkEditor, { editor: editor, autoFocus: linkPopoverOpen, onClose: () => setLinkPopoverOpen(false) })) })] })), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BOLD)) && _jsx(BoldControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ITALIC)) && (_jsx(ItalicControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.UNDERLINE)) && (_jsx(UnderlineControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.STRIKE)) && (_jsx(StrikeThroughControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE)) && _jsx(CodeControl, { editor: editor }), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) && (_jsx(CodeBlockControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.CODE_BLOCK)) &&
|
|
119
|
+
showCodeBlockLanguageSelect && (_jsxs(_Fragment, { children: [_jsx(CodeBlockWrapButton, { editor: editor }), _jsx(CodeBlockFormatButton, { editor: editor })] }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_1)) && (_jsx(Heading1Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_2)) && (_jsx(Heading2Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_3)) && (_jsx(Heading3Control, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.HEADING_4)) && (_jsx(Heading4Control, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.BULLET_LIST)) && (_jsx(BulletListControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.ORDERED_LIST)) && (_jsx(OrderedListControl, { editor: editor }))] }), _jsxs(ControlsGroup, { children: [(controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_LEFT)) && (_jsx(AlignLeftControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_CENTER)) && (_jsx(AlignCenterControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_RIGHT)) && (_jsx(AlignRightControl, { editor: editor })), (controls === null || controls === void 0 ? void 0 : controls.includes(Controls.TEXT_ALIGN_JUSTIFIED)) && (_jsx(AlignJustifiedControl, { editor: editor }))] })] }));
|
|
76
120
|
}) `
|
|
77
121
|
display: flex;
|
|
78
122
|
flex-direction: row;
|
|
123
|
+
flex-wrap: wrap;
|
|
79
124
|
justify-content: center;
|
|
80
125
|
align-items: center;
|
|
81
126
|
gap: 5px;
|
|
127
|
+
row-gap: 6px;
|
|
128
|
+
width: 100%;
|
|
82
129
|
margin-bottom: 10px;
|
|
83
130
|
border-radius: 5px 5px 0 0;
|
|
84
131
|
border: 1px solid transparent;
|
|
132
|
+
|
|
133
|
+
> button,
|
|
134
|
+
> .mfui-DropDownMenu {
|
|
135
|
+
flex: 0 0 auto;
|
|
136
|
+
}
|
|
85
137
|
`;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Editor } from "@tiptap/react";
|
|
2
|
+
export type CodeBlockLanguage = {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const DEFAULT_CODE_BLOCK_LANGUAGE = "plaintext";
|
|
7
|
+
export declare const CODE_BLOCK_LANGUAGES: CodeBlockLanguage[];
|
|
8
|
+
export declare const getCodeBlockLanguage: (editor: Editor | null) => string;
|
|
9
|
+
export declare const getCodeBlockLanguageOption: (language?: string) => CodeBlockLanguage;
|
|
10
|
+
export declare const canFormatCodeBlockLanguage: (language?: string) => boolean;
|
|
11
|
+
export declare const formatCodeBlockText: (text: string, language?: string) => Promise<string>;
|
|
12
|
+
export declare const hasSyntaxHighlightedCodeBlock: (editor: Editor | null) => boolean;
|
|
13
|
+
export declare const setCodeBlockLanguage: (editor: Editor | null, language: string) => void;
|
|
14
|
+
export declare const getCodeBlockWrap: (editor: Editor | null) => boolean;
|
|
15
|
+
export declare const toggleCodeBlockWrap: (editor: Editor | null) => void;
|
|
16
|
+
export declare const toggleCodeBlock: (editor: Editor | null) => void;
|
|
17
|
+
export declare const getActiveCodeBlockText: (editor: Editor | null) => string;
|
|
18
|
+
export declare const replaceCodeBlockContent: (editor: Editor, from: number, to: number, text: string) => boolean;
|
|
19
|
+
export declare const formatActiveCodeBlock: (editor: Editor | null) => Promise<void>;
|
|
20
|
+
export declare const copyCodeBlockText: (text: string) => Promise<void>;
|