@kopexa/tiptap 17.2.0 → 17.2.2
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/{chunk-E5NW3MJZ.mjs → chunk-3ZPLSXTZ.mjs} +3 -3
- package/dist/{chunk-7SRL3P4B.mjs → chunk-5QFCLKHL.mjs} +7 -7
- package/dist/{chunk-NEHW62L7.mjs → chunk-6552DQWB.mjs} +2 -2
- package/dist/{chunk-5GFFTVMZ.mjs → chunk-DSBJFMHK.mjs} +4 -28
- package/dist/chunk-EAAQE5ZV.mjs +283 -0
- package/dist/chunk-HTJ2RXOG.mjs +32 -0
- package/dist/{chunk-LMCQMSW2.mjs → chunk-KYLBKQ2E.mjs} +12 -154
- package/dist/chunk-N3JE67CS.mjs +81 -0
- package/dist/{chunk-UU6JK5HX.mjs → chunk-SSJMKQ5G.mjs} +33 -20
- package/dist/chunk-Z365KVQY.mjs +34 -0
- package/dist/extensions/image/image-view.d.mts +3 -3
- package/dist/extensions/image/image-view.d.ts +3 -3
- package/dist/extensions/image/image-view.js +13 -181
- package/dist/extensions/image/image-view.mjs +2 -2
- package/dist/extensions/image/index.d.mts +12 -49
- package/dist/extensions/image/index.d.ts +12 -49
- package/dist/extensions/image/index.js +18 -231
- package/dist/extensions/image/index.mjs +3 -3
- package/dist/extensions/image/messages.d.mts +2 -30
- package/dist/extensions/image/messages.d.ts +2 -30
- package/dist/extensions/image/messages.js +4 -32
- package/dist/extensions/image/messages.mjs +1 -1
- package/dist/extensions/image-upload/image-upload-view.d.mts +12 -0
- package/dist/extensions/image-upload/image-upload-view.d.ts +12 -0
- package/dist/extensions/image-upload/image-upload-view.js +338 -0
- package/dist/extensions/image-upload/image-upload-view.mjs +12 -0
- package/dist/extensions/image-upload/index.d.mts +46 -0
- package/dist/extensions/image-upload/index.d.ts +46 -0
- package/dist/extensions/image-upload/index.js +414 -0
- package/dist/extensions/image-upload/index.mjs +16 -0
- package/dist/extensions/image-upload/messages.d.mts +32 -0
- package/dist/extensions/image-upload/messages.d.ts +32 -0
- package/dist/extensions/image-upload/messages.js +61 -0
- package/dist/extensions/image-upload/messages.mjs +7 -0
- package/dist/extensions/math/index.mjs +1 -1
- package/dist/hooks/use-create-editor.js +562 -393
- package/dist/hooks/use-create-editor.mjs +13 -10
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +956 -785
- package/dist/index.mjs +39 -33
- package/dist/presets/basic/editor-header.mjs +14 -14
- package/dist/presets/basic/index.js +953 -784
- package/dist/presets/basic/index.mjs +32 -29
- package/dist/ui/slash-dropdown-menu/index.js +2 -2
- package/dist/ui/slash-dropdown-menu/index.mjs +4 -4
- package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +2 -2
- package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +2 -2
- package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.js +2 -2
- package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.mjs +1 -1
- package/package.json +25 -24
- package/dist/chunk-WAAH3NLG.mjs +0 -77
- package/dist/{chunk-QAE2D4KV.mjs → chunk-FDPXD6VC.mjs} +11 -11
|
@@ -50,9 +50,9 @@ var import_extension_text_style = require("@tiptap/extension-text-style");
|
|
|
50
50
|
var import_extension_typography = require("@tiptap/extension-typography");
|
|
51
51
|
var import_extension_unique_id = require("@tiptap/extension-unique-id");
|
|
52
52
|
var import_extensions = require("@tiptap/extensions");
|
|
53
|
-
var
|
|
53
|
+
var import_react25 = require("@tiptap/react");
|
|
54
54
|
var import_starter_kit = require("@tiptap/starter-kit");
|
|
55
|
-
var
|
|
55
|
+
var import_react26 = require("react");
|
|
56
56
|
|
|
57
57
|
// src/context/editor-file-context.tsx
|
|
58
58
|
var import_react = require("react");
|
|
@@ -414,7 +414,7 @@ var CalloutNode = import_core.Node.create({
|
|
|
414
414
|
});
|
|
415
415
|
|
|
416
416
|
// src/extensions/image/index.ts
|
|
417
|
-
var
|
|
417
|
+
var import_extension_image = require("@tiptap/extension-image");
|
|
418
418
|
var import_react8 = require("@tiptap/react");
|
|
419
419
|
|
|
420
420
|
// src/extensions/image/image-view.tsx
|
|
@@ -432,6 +432,10 @@ var messages2 = (0, import_react_intl3.defineMessages)({
|
|
|
432
432
|
id: "editor.image.loading",
|
|
433
433
|
defaultMessage: "Loading image..."
|
|
434
434
|
},
|
|
435
|
+
uploading: {
|
|
436
|
+
id: "editor.image.uploading",
|
|
437
|
+
defaultMessage: "Uploading..."
|
|
438
|
+
},
|
|
435
439
|
error: {
|
|
436
440
|
id: "editor.image.error",
|
|
437
441
|
defaultMessage: "Failed to load image"
|
|
@@ -440,38 +444,6 @@ var messages2 = (0, import_react_intl3.defineMessages)({
|
|
|
440
444
|
id: "editor.image.upload_error",
|
|
441
445
|
defaultMessage: "Failed to upload image"
|
|
442
446
|
},
|
|
443
|
-
uploading: {
|
|
444
|
-
id: "editor.image.uploading",
|
|
445
|
-
defaultMessage: "Uploading..."
|
|
446
|
-
},
|
|
447
|
-
upload_placeholder: {
|
|
448
|
-
id: "editor.image.upload_placeholder",
|
|
449
|
-
defaultMessage: "Click to upload or drag & drop"
|
|
450
|
-
},
|
|
451
|
-
upload_hint: {
|
|
452
|
-
id: "editor.image.upload_hint",
|
|
453
|
-
defaultMessage: "PNG, JPG, GIF, WebP, SVG"
|
|
454
|
-
},
|
|
455
|
-
alt_text: {
|
|
456
|
-
id: "editor.image.alt_text",
|
|
457
|
-
defaultMessage: "Alt text"
|
|
458
|
-
},
|
|
459
|
-
alt_placeholder: {
|
|
460
|
-
id: "editor.image.alt_placeholder",
|
|
461
|
-
defaultMessage: "Describe the image..."
|
|
462
|
-
},
|
|
463
|
-
files_not_supported: {
|
|
464
|
-
id: "editor.image.files_not_supported",
|
|
465
|
-
defaultMessage: "File upload is not configured"
|
|
466
|
-
},
|
|
467
|
-
file_too_large: {
|
|
468
|
-
id: "editor.image.file_too_large",
|
|
469
|
-
defaultMessage: "File is too large (max {maxSize})"
|
|
470
|
-
},
|
|
471
|
-
invalid_type: {
|
|
472
|
-
id: "editor.image.invalid_type",
|
|
473
|
-
defaultMessage: "Invalid file type"
|
|
474
|
-
},
|
|
475
447
|
retry: {
|
|
476
448
|
id: "editor.image.retry",
|
|
477
449
|
defaultMessage: "Retry"
|
|
@@ -488,7 +460,7 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
488
460
|
var _a;
|
|
489
461
|
const intl = (0, import_react_intl4.useIntl)();
|
|
490
462
|
const fileHandler = useEditorFile();
|
|
491
|
-
const
|
|
463
|
+
const { src, alt, title, uploadState, uploadProgress } = node.attrs;
|
|
492
464
|
const isEditable = (0, import_react6.useEditorState)({
|
|
493
465
|
editor,
|
|
494
466
|
selector: ({ editor: e }) => {
|
|
@@ -496,7 +468,6 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
496
468
|
return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : false;
|
|
497
469
|
}
|
|
498
470
|
});
|
|
499
|
-
const { src, alt, title, uploadState, uploadProgress } = attrs;
|
|
500
471
|
const [resolvedUrl, setResolvedUrl] = (0, import_react7.useState)(null);
|
|
501
472
|
const [resolveState, setResolveState] = (0, import_react7.useState)("idle");
|
|
502
473
|
const needsResolve = (_a = fileHandler == null ? void 0 : fileHandler.isReference(src)) != null ? _a : false;
|
|
@@ -508,7 +479,8 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
508
479
|
return;
|
|
509
480
|
}
|
|
510
481
|
if (!fileHandler) {
|
|
511
|
-
|
|
482
|
+
setResolvedUrl(src);
|
|
483
|
+
setResolveState("resolved");
|
|
512
484
|
return;
|
|
513
485
|
}
|
|
514
486
|
setResolveState("loading");
|
|
@@ -534,156 +506,16 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
534
506
|
to: pos + node.nodeSize
|
|
535
507
|
});
|
|
536
508
|
}, [editor, getPos, node.nodeSize]);
|
|
537
|
-
const fileInputRef = (0, import_react7.useRef)(null);
|
|
538
|
-
const handleFileSelect = (0, import_react7.useCallback)(
|
|
539
|
-
async (file) => {
|
|
540
|
-
if (!fileHandler) return;
|
|
541
|
-
const pos = getPos();
|
|
542
|
-
if (pos === void 0) return;
|
|
543
|
-
editor.view.dispatch(
|
|
544
|
-
editor.state.tr.setNodeMarkup(pos, void 0, {
|
|
545
|
-
...attrs,
|
|
546
|
-
uploadState: "uploading",
|
|
547
|
-
uploadProgress: 0
|
|
548
|
-
})
|
|
549
|
-
);
|
|
550
|
-
try {
|
|
551
|
-
const ref = await fileHandler.upload(file, (percent) => {
|
|
552
|
-
const currentPos = getPos();
|
|
553
|
-
if (currentPos === void 0) return;
|
|
554
|
-
editor.view.dispatch(
|
|
555
|
-
editor.state.tr.setNodeMarkup(currentPos, void 0, {
|
|
556
|
-
...attrs,
|
|
557
|
-
uploadState: "uploading",
|
|
558
|
-
uploadProgress: percent
|
|
559
|
-
})
|
|
560
|
-
);
|
|
561
|
-
});
|
|
562
|
-
const finalPos = getPos();
|
|
563
|
-
if (finalPos === void 0) return;
|
|
564
|
-
editor.view.dispatch(
|
|
565
|
-
editor.state.tr.setNodeMarkup(finalPos, void 0, {
|
|
566
|
-
src: ref,
|
|
567
|
-
uploadState: null,
|
|
568
|
-
uploadProgress: null
|
|
569
|
-
})
|
|
570
|
-
);
|
|
571
|
-
} catch {
|
|
572
|
-
const errorPos = getPos();
|
|
573
|
-
if (errorPos === void 0) return;
|
|
574
|
-
editor.view.dispatch(
|
|
575
|
-
editor.state.tr.setNodeMarkup(errorPos, void 0, {
|
|
576
|
-
...attrs,
|
|
577
|
-
uploadState: "error",
|
|
578
|
-
uploadProgress: null
|
|
579
|
-
})
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
},
|
|
583
|
-
[fileHandler, editor, getPos, attrs]
|
|
584
|
-
);
|
|
585
|
-
const handleInputChange = (0, import_react7.useCallback)(
|
|
586
|
-
(e) => {
|
|
587
|
-
var _a2;
|
|
588
|
-
const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
|
|
589
|
-
if (file) {
|
|
590
|
-
handleFileSelect(file);
|
|
591
|
-
}
|
|
592
|
-
},
|
|
593
|
-
[handleFileSelect]
|
|
594
|
-
);
|
|
595
|
-
const handleDrop = (0, import_react7.useCallback)(
|
|
596
|
-
(e) => {
|
|
597
|
-
e.preventDefault();
|
|
598
|
-
e.stopPropagation();
|
|
599
|
-
const file = e.dataTransfer.files[0];
|
|
600
|
-
if (file == null ? void 0 : file.type.startsWith("image/")) {
|
|
601
|
-
handleFileSelect(file);
|
|
602
|
-
}
|
|
603
|
-
},
|
|
604
|
-
[handleFileSelect]
|
|
605
|
-
);
|
|
606
|
-
const handleDragOver = (0, import_react7.useCallback)((e) => {
|
|
607
|
-
e.preventDefault();
|
|
608
|
-
e.stopPropagation();
|
|
609
|
-
}, []);
|
|
610
|
-
const styles = (0, import_react7.useMemo)(() => (0, import_theme2.imagePlaceholder)({ size: "md" }), []);
|
|
611
509
|
const errorStyles = (0, import_react7.useMemo)(
|
|
612
510
|
() => (0, import_theme2.imagePlaceholder)({ size: "md", variant: "error" }),
|
|
613
511
|
[]
|
|
614
512
|
);
|
|
615
|
-
const
|
|
513
|
+
const loadingStyles = (0, import_react7.useMemo)(
|
|
616
514
|
() => (0, import_theme2.imagePlaceholder)({ size: "md", variant: "uploading" }),
|
|
617
515
|
[]
|
|
618
516
|
);
|
|
619
|
-
const disabledStyles = (0, import_react7.useMemo)(
|
|
620
|
-
() => (0, import_theme2.imagePlaceholder)({ size: "md", variant: "disabled" }),
|
|
621
|
-
[]
|
|
622
|
-
);
|
|
623
|
-
const isEmpty = !src;
|
|
624
|
-
if (isEmpty && !uploadState) {
|
|
625
|
-
if (!fileHandler) {
|
|
626
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: disabledStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: disabledStyles.content(), children: [
|
|
627
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.ImageIcon, { className: disabledStyles.icon() }),
|
|
628
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: disabledStyles.text(), children: intl.formatMessage(messages2.files_not_supported) }),
|
|
629
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
630
|
-
import_button2.IconButton,
|
|
631
|
-
{
|
|
632
|
-
size: "sm",
|
|
633
|
-
variant: "ghost",
|
|
634
|
-
onClick: handleRemove,
|
|
635
|
-
"aria-label": intl.formatMessage(messages2.remove),
|
|
636
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-4" })
|
|
637
|
-
}
|
|
638
|
-
)
|
|
639
|
-
] }) }) });
|
|
640
|
-
}
|
|
641
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
642
|
-
"div",
|
|
643
|
-
{
|
|
644
|
-
className: styles.root(),
|
|
645
|
-
onClick: () => {
|
|
646
|
-
var _a2;
|
|
647
|
-
return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
|
|
648
|
-
},
|
|
649
|
-
onDrop: handleDrop,
|
|
650
|
-
onDragOver: handleDragOver,
|
|
651
|
-
children: [
|
|
652
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: styles.content(), children: [
|
|
653
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.UploadIcon, { className: styles.icon() }),
|
|
654
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: styles.text(), children: intl.formatMessage(messages2.upload_placeholder) }),
|
|
655
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: styles.hint(), children: intl.formatMessage(messages2.upload_hint) })
|
|
656
|
-
] }),
|
|
657
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
658
|
-
"input",
|
|
659
|
-
{
|
|
660
|
-
ref: fileInputRef,
|
|
661
|
-
type: "file",
|
|
662
|
-
accept: "image/*",
|
|
663
|
-
className: "hidden",
|
|
664
|
-
onChange: handleInputChange
|
|
665
|
-
}
|
|
666
|
-
),
|
|
667
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
668
|
-
import_button2.IconButton,
|
|
669
|
-
{
|
|
670
|
-
size: "sm",
|
|
671
|
-
variant: "ghost",
|
|
672
|
-
className: styles.removeButton(),
|
|
673
|
-
onClick: (e) => {
|
|
674
|
-
e.stopPropagation();
|
|
675
|
-
handleRemove();
|
|
676
|
-
},
|
|
677
|
-
"aria-label": intl.formatMessage(messages2.remove),
|
|
678
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-3.5" })
|
|
679
|
-
}
|
|
680
|
-
)
|
|
681
|
-
]
|
|
682
|
-
}
|
|
683
|
-
) });
|
|
684
|
-
}
|
|
685
517
|
if (uploadState === "uploading") {
|
|
686
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className:
|
|
518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: loadingStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: loadingStyles.content(), children: [
|
|
687
519
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative size-12", children: [
|
|
688
520
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
689
521
|
"svg",
|
|
@@ -725,14 +557,14 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
725
557
|
"%"
|
|
726
558
|
] })
|
|
727
559
|
] }),
|
|
728
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className:
|
|
560
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages2.uploading) })
|
|
729
561
|
] }) }) });
|
|
730
562
|
}
|
|
731
563
|
if (uploadState === "error") {
|
|
732
564
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: errorStyles.content(), children: [
|
|
733
565
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.AlertCircleIcon, { className: errorStyles.icon() }),
|
|
734
566
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages2.upload_error) }),
|
|
735
|
-
isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
567
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
736
568
|
import_button2.IconButton,
|
|
737
569
|
{
|
|
738
570
|
size: "sm",
|
|
@@ -741,11 +573,11 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
741
573
|
"aria-label": intl.formatMessage(messages2.remove),
|
|
742
574
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-4" })
|
|
743
575
|
}
|
|
744
|
-
)
|
|
576
|
+
)
|
|
745
577
|
] }) }) });
|
|
746
578
|
}
|
|
747
579
|
if (resolveState === "loading") {
|
|
748
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `${
|
|
580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `${loadingStyles.root()} animate-pulse`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages2.loading) }) }) });
|
|
749
581
|
}
|
|
750
582
|
if (resolveState === "error") {
|
|
751
583
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: errorStyles.content(), children: [
|
|
@@ -800,34 +632,345 @@ function ImageNodeView({ editor, node, getPos }) {
|
|
|
800
632
|
}
|
|
801
633
|
|
|
802
634
|
// src/extensions/image/index.ts
|
|
803
|
-
var ImageNode =
|
|
804
|
-
|
|
635
|
+
var ImageNode = import_extension_image.Image.extend({
|
|
636
|
+
addAttributes() {
|
|
637
|
+
var _a;
|
|
638
|
+
return {
|
|
639
|
+
...(_a = this.parent) == null ? void 0 : _a.call(this),
|
|
640
|
+
// Upload state for drag & drop / paste uploads
|
|
641
|
+
uploadState: {
|
|
642
|
+
default: null,
|
|
643
|
+
rendered: false
|
|
644
|
+
},
|
|
645
|
+
uploadProgress: {
|
|
646
|
+
default: null,
|
|
647
|
+
rendered: false
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
},
|
|
651
|
+
addNodeView() {
|
|
652
|
+
return (0, import_react8.ReactNodeViewRenderer)(ImageNodeView);
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
// src/extensions/image-upload/index.ts
|
|
657
|
+
var import_core2 = require("@tiptap/core");
|
|
658
|
+
var import_react11 = require("@tiptap/react");
|
|
659
|
+
|
|
660
|
+
// src/extensions/image-upload/image-upload-view.tsx
|
|
661
|
+
var import_button3 = require("@kopexa/button");
|
|
662
|
+
var import_icons4 = require("@kopexa/icons");
|
|
663
|
+
var import_theme3 = require("@kopexa/theme");
|
|
664
|
+
var import_react9 = require("@tiptap/react");
|
|
665
|
+
var import_react10 = require("react");
|
|
666
|
+
var import_react_intl6 = require("react-intl");
|
|
667
|
+
|
|
668
|
+
// src/extensions/image-upload/messages.ts
|
|
669
|
+
var import_react_intl5 = require("react-intl");
|
|
670
|
+
var messages3 = (0, import_react_intl5.defineMessages)({
|
|
671
|
+
upload_error: {
|
|
672
|
+
id: "editor.image.upload_error",
|
|
673
|
+
defaultMessage: "Failed to upload image"
|
|
674
|
+
},
|
|
675
|
+
uploading: {
|
|
676
|
+
id: "editor.image.uploading",
|
|
677
|
+
defaultMessage: "Uploading..."
|
|
678
|
+
},
|
|
679
|
+
upload_placeholder: {
|
|
680
|
+
id: "editor.image.upload_placeholder",
|
|
681
|
+
defaultMessage: "Click to upload or drag & drop"
|
|
682
|
+
},
|
|
683
|
+
upload_hint: {
|
|
684
|
+
id: "editor.image.upload_hint",
|
|
685
|
+
defaultMessage: "PNG, JPG, GIF, WebP, SVG"
|
|
686
|
+
},
|
|
687
|
+
click_to_retry: {
|
|
688
|
+
id: "editor.image.click_to_retry",
|
|
689
|
+
defaultMessage: "Click to try again"
|
|
690
|
+
},
|
|
691
|
+
files_not_supported: {
|
|
692
|
+
id: "editor.image.files_not_supported",
|
|
693
|
+
defaultMessage: "File upload is not configured"
|
|
694
|
+
},
|
|
695
|
+
remove: {
|
|
696
|
+
id: "editor.image.remove",
|
|
697
|
+
defaultMessage: "Remove"
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
// src/extensions/image-upload/image-upload-view.tsx
|
|
702
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
703
|
+
function ImageUploadNodeView({ editor, node, getPos }) {
|
|
704
|
+
const intl = (0, import_react_intl6.useIntl)();
|
|
705
|
+
const fileHandler = useEditorFile();
|
|
706
|
+
const isEditable = (0, import_react9.useEditorState)({
|
|
707
|
+
editor,
|
|
708
|
+
selector: ({ editor: e }) => {
|
|
709
|
+
var _a;
|
|
710
|
+
return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
const [uploadState, setUploadState] = (0, import_react10.useState)("idle");
|
|
714
|
+
const [uploadProgress, setUploadProgress] = (0, import_react10.useState)(0);
|
|
715
|
+
const [isDragOver, setIsDragOver] = (0, import_react10.useState)(false);
|
|
716
|
+
const fileInputRef = (0, import_react10.useRef)(null);
|
|
717
|
+
const handleRemove = (0, import_react10.useCallback)(() => {
|
|
718
|
+
const pos = getPos();
|
|
719
|
+
if (pos === void 0) return;
|
|
720
|
+
editor.commands.deleteRange({
|
|
721
|
+
from: pos,
|
|
722
|
+
to: pos + node.nodeSize
|
|
723
|
+
});
|
|
724
|
+
}, [editor, getPos, node.nodeSize]);
|
|
725
|
+
const handleFileSelect = (0, import_react10.useCallback)(
|
|
726
|
+
async (file) => {
|
|
727
|
+
if (!fileHandler) return;
|
|
728
|
+
const pos = getPos();
|
|
729
|
+
if (pos === void 0) return;
|
|
730
|
+
setUploadState("uploading");
|
|
731
|
+
setUploadProgress(0);
|
|
732
|
+
try {
|
|
733
|
+
const ref = await fileHandler.upload(file, (percent) => {
|
|
734
|
+
setUploadProgress(percent);
|
|
735
|
+
});
|
|
736
|
+
const currentPos = getPos();
|
|
737
|
+
if (currentPos === void 0) return;
|
|
738
|
+
editor.chain().focus().deleteRange({ from: currentPos, to: currentPos + node.nodeSize }).insertContentAt(currentPos, {
|
|
739
|
+
type: "image",
|
|
740
|
+
attrs: {
|
|
741
|
+
src: ref,
|
|
742
|
+
alt: file.name.replace(/\.[^/.]+$/, ""),
|
|
743
|
+
title: file.name.replace(/\.[^/.]+$/, "")
|
|
744
|
+
}
|
|
745
|
+
}).run();
|
|
746
|
+
} catch (error) {
|
|
747
|
+
console.error("[ImageUpload] Upload failed:", error);
|
|
748
|
+
setUploadState("error");
|
|
749
|
+
setUploadProgress(0);
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
[fileHandler, editor, getPos, node.nodeSize]
|
|
753
|
+
);
|
|
754
|
+
const handleInputChange = (0, import_react10.useCallback)(
|
|
755
|
+
(e) => {
|
|
756
|
+
var _a;
|
|
757
|
+
const file = (_a = e.target.files) == null ? void 0 : _a[0];
|
|
758
|
+
if (file) {
|
|
759
|
+
handleFileSelect(file);
|
|
760
|
+
}
|
|
761
|
+
e.target.value = "";
|
|
762
|
+
},
|
|
763
|
+
[handleFileSelect]
|
|
764
|
+
);
|
|
765
|
+
const handleDrop = (0, import_react10.useCallback)(
|
|
766
|
+
(e) => {
|
|
767
|
+
e.preventDefault();
|
|
768
|
+
e.stopPropagation();
|
|
769
|
+
setIsDragOver(false);
|
|
770
|
+
const file = e.dataTransfer.files[0];
|
|
771
|
+
if (file == null ? void 0 : file.type.startsWith("image/")) {
|
|
772
|
+
handleFileSelect(file);
|
|
773
|
+
}
|
|
774
|
+
},
|
|
775
|
+
[handleFileSelect]
|
|
776
|
+
);
|
|
777
|
+
const handleDragOver = (0, import_react10.useCallback)((e) => {
|
|
778
|
+
e.preventDefault();
|
|
779
|
+
e.stopPropagation();
|
|
780
|
+
}, []);
|
|
781
|
+
const handleDragEnter = (0, import_react10.useCallback)((e) => {
|
|
782
|
+
e.preventDefault();
|
|
783
|
+
e.stopPropagation();
|
|
784
|
+
setIsDragOver(true);
|
|
785
|
+
}, []);
|
|
786
|
+
const handleDragLeave = (0, import_react10.useCallback)((e) => {
|
|
787
|
+
e.preventDefault();
|
|
788
|
+
e.stopPropagation();
|
|
789
|
+
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
790
|
+
setIsDragOver(false);
|
|
791
|
+
}
|
|
792
|
+
}, []);
|
|
793
|
+
const handleClick = (0, import_react10.useCallback)(() => {
|
|
794
|
+
var _a;
|
|
795
|
+
if (uploadState === "idle" || uploadState === "error") {
|
|
796
|
+
(_a = fileInputRef.current) == null ? void 0 : _a.click();
|
|
797
|
+
}
|
|
798
|
+
}, [uploadState]);
|
|
799
|
+
const styles = (0, import_react10.useMemo)(
|
|
800
|
+
() => (0, import_theme3.imagePlaceholder)({
|
|
801
|
+
size: "md",
|
|
802
|
+
variant: isDragOver ? "default" : void 0
|
|
803
|
+
}),
|
|
804
|
+
[isDragOver]
|
|
805
|
+
);
|
|
806
|
+
const errorStyles = (0, import_react10.useMemo)(
|
|
807
|
+
() => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "error" }),
|
|
808
|
+
[]
|
|
809
|
+
);
|
|
810
|
+
const uploadingStyles = (0, import_react10.useMemo)(
|
|
811
|
+
() => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "uploading" }),
|
|
812
|
+
[]
|
|
813
|
+
);
|
|
814
|
+
const disabledStyles = (0, import_react10.useMemo)(
|
|
815
|
+
() => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "disabled" }),
|
|
816
|
+
[]
|
|
817
|
+
);
|
|
818
|
+
if (!fileHandler) {
|
|
819
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: disabledStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: disabledStyles.content(), children: [
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.ImageIcon, { className: disabledStyles.icon() }),
|
|
821
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: disabledStyles.text(), children: intl.formatMessage(messages3.files_not_supported) }),
|
|
822
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
823
|
+
import_button3.IconButton,
|
|
824
|
+
{
|
|
825
|
+
size: "sm",
|
|
826
|
+
variant: "ghost",
|
|
827
|
+
onClick: handleRemove,
|
|
828
|
+
"aria-label": intl.formatMessage(messages3.remove),
|
|
829
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-4" })
|
|
830
|
+
}
|
|
831
|
+
)
|
|
832
|
+
] }) }) });
|
|
833
|
+
}
|
|
834
|
+
if (uploadState === "uploading") {
|
|
835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: uploadingStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: uploadingStyles.content(), children: [
|
|
836
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative size-12", children: [
|
|
837
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
838
|
+
"svg",
|
|
839
|
+
{
|
|
840
|
+
className: "size-12 -rotate-90",
|
|
841
|
+
viewBox: "0 0 36 36",
|
|
842
|
+
"aria-hidden": "true",
|
|
843
|
+
children: [
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
845
|
+
"circle",
|
|
846
|
+
{
|
|
847
|
+
cx: "18",
|
|
848
|
+
cy: "18",
|
|
849
|
+
r: "16",
|
|
850
|
+
fill: "none",
|
|
851
|
+
className: "stroke-muted",
|
|
852
|
+
strokeWidth: "2"
|
|
853
|
+
}
|
|
854
|
+
),
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
856
|
+
"circle",
|
|
857
|
+
{
|
|
858
|
+
cx: "18",
|
|
859
|
+
cy: "18",
|
|
860
|
+
r: "16",
|
|
861
|
+
fill: "none",
|
|
862
|
+
className: "stroke-primary",
|
|
863
|
+
strokeWidth: "2",
|
|
864
|
+
strokeDasharray: 100,
|
|
865
|
+
strokeDashoffset: 100 - uploadProgress,
|
|
866
|
+
strokeLinecap: "round"
|
|
867
|
+
}
|
|
868
|
+
)
|
|
869
|
+
]
|
|
870
|
+
}
|
|
871
|
+
),
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "absolute inset-0 flex items-center justify-center text-xs font-medium", children: [
|
|
873
|
+
uploadProgress,
|
|
874
|
+
"%"
|
|
875
|
+
] })
|
|
876
|
+
] }),
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: uploadingStyles.text(), children: intl.formatMessage(messages3.uploading) })
|
|
878
|
+
] }) }) });
|
|
879
|
+
}
|
|
880
|
+
if (uploadState === "error") {
|
|
881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: errorStyles.root(), onClick: handleClick, children: [
|
|
882
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: errorStyles.content(), children: [
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.AlertCircleIcon, { className: errorStyles.icon() }),
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages3.upload_error) }),
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: errorStyles.hint(), children: intl.formatMessage(messages3.click_to_retry) })
|
|
886
|
+
] }),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
888
|
+
"input",
|
|
889
|
+
{
|
|
890
|
+
ref: fileInputRef,
|
|
891
|
+
type: "file",
|
|
892
|
+
accept: "image/*",
|
|
893
|
+
className: "hidden",
|
|
894
|
+
onChange: handleInputChange
|
|
895
|
+
}
|
|
896
|
+
),
|
|
897
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
898
|
+
import_button3.IconButton,
|
|
899
|
+
{
|
|
900
|
+
size: "sm",
|
|
901
|
+
variant: "ghost",
|
|
902
|
+
className: errorStyles.removeButton(),
|
|
903
|
+
onClick: (e) => {
|
|
904
|
+
e.stopPropagation();
|
|
905
|
+
handleRemove();
|
|
906
|
+
},
|
|
907
|
+
"aria-label": intl.formatMessage(messages3.remove),
|
|
908
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-3.5" })
|
|
909
|
+
}
|
|
910
|
+
)
|
|
911
|
+
] }) });
|
|
912
|
+
}
|
|
913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
914
|
+
"div",
|
|
915
|
+
{
|
|
916
|
+
className: `${styles.root()} ${isDragOver ? "border-primary bg-primary/10" : ""}`,
|
|
917
|
+
onClick: handleClick,
|
|
918
|
+
onDrop: handleDrop,
|
|
919
|
+
onDragOver: handleDragOver,
|
|
920
|
+
onDragEnter: handleDragEnter,
|
|
921
|
+
onDragLeave: handleDragLeave,
|
|
922
|
+
children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: styles.content(), children: [
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.UploadIcon, { className: styles.icon() }),
|
|
925
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: styles.text(), children: intl.formatMessage(messages3.upload_placeholder) }),
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: styles.hint(), children: intl.formatMessage(messages3.upload_hint) })
|
|
927
|
+
] }),
|
|
928
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
929
|
+
"input",
|
|
930
|
+
{
|
|
931
|
+
ref: fileInputRef,
|
|
932
|
+
type: "file",
|
|
933
|
+
accept: "image/*",
|
|
934
|
+
className: "hidden",
|
|
935
|
+
onChange: handleInputChange
|
|
936
|
+
}
|
|
937
|
+
),
|
|
938
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
939
|
+
import_button3.IconButton,
|
|
940
|
+
{
|
|
941
|
+
size: "sm",
|
|
942
|
+
variant: "ghost",
|
|
943
|
+
className: styles.removeButton(),
|
|
944
|
+
onClick: (e) => {
|
|
945
|
+
e.stopPropagation();
|
|
946
|
+
handleRemove();
|
|
947
|
+
},
|
|
948
|
+
"aria-label": intl.formatMessage(messages3.remove),
|
|
949
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-3.5" })
|
|
950
|
+
}
|
|
951
|
+
)
|
|
952
|
+
]
|
|
953
|
+
}
|
|
954
|
+
) });
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// src/extensions/image-upload/index.ts
|
|
958
|
+
var ImageUploadNode = import_core2.Node.create({
|
|
959
|
+
name: "imageUpload",
|
|
805
960
|
group: "block",
|
|
806
961
|
atom: true,
|
|
807
962
|
draggable: true,
|
|
963
|
+
selectable: true,
|
|
808
964
|
addOptions() {
|
|
809
965
|
return {
|
|
810
|
-
|
|
966
|
+
accept: "image/*",
|
|
967
|
+
maxSize: 0,
|
|
811
968
|
HTMLAttributes: {}
|
|
812
969
|
};
|
|
813
970
|
},
|
|
814
971
|
addAttributes() {
|
|
815
972
|
return {
|
|
816
|
-
|
|
817
|
-
default: null
|
|
818
|
-
},
|
|
819
|
-
alt: {
|
|
820
|
-
default: null
|
|
821
|
-
},
|
|
822
|
-
title: {
|
|
823
|
-
default: null
|
|
824
|
-
},
|
|
825
|
-
width: {
|
|
826
|
-
default: null
|
|
827
|
-
},
|
|
828
|
-
height: {
|
|
829
|
-
default: null
|
|
830
|
-
},
|
|
973
|
+
// Upload state tracking
|
|
831
974
|
uploadState: {
|
|
832
975
|
default: null,
|
|
833
976
|
rendered: false
|
|
@@ -841,35 +984,51 @@ var ImageNode = import_core2.Node.create({
|
|
|
841
984
|
parseHTML() {
|
|
842
985
|
return [
|
|
843
986
|
{
|
|
844
|
-
tag: "
|
|
987
|
+
tag: 'div[data-type="image-upload"]'
|
|
845
988
|
}
|
|
846
989
|
];
|
|
847
990
|
},
|
|
848
991
|
renderHTML({ HTMLAttributes }) {
|
|
849
|
-
return [
|
|
850
|
-
"img",
|
|
851
|
-
(0, import_core2.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes)
|
|
852
|
-
];
|
|
992
|
+
return ["div", { ...HTMLAttributes, "data-type": "image-upload" }];
|
|
853
993
|
},
|
|
854
994
|
addNodeView() {
|
|
855
|
-
return (0,
|
|
995
|
+
return (0, import_react11.ReactNodeViewRenderer)(ImageUploadNodeView);
|
|
856
996
|
},
|
|
857
997
|
addCommands() {
|
|
858
998
|
return {
|
|
859
|
-
|
|
999
|
+
setImageUpload: () => ({ commands }) => {
|
|
860
1000
|
return commands.insertContent({
|
|
861
|
-
type: this.name
|
|
862
|
-
attrs: options
|
|
1001
|
+
type: this.name
|
|
863
1002
|
});
|
|
864
1003
|
}
|
|
865
1004
|
};
|
|
1005
|
+
},
|
|
1006
|
+
addKeyboardShortcuts() {
|
|
1007
|
+
return {
|
|
1008
|
+
Enter: ({ editor }) => {
|
|
1009
|
+
const { selection } = editor.state;
|
|
1010
|
+
const { $from } = selection;
|
|
1011
|
+
const node = $from.nodeAfter;
|
|
1012
|
+
if ((node == null ? void 0 : node.type.name) === "imageUpload" && editor.isActive("imageUpload")) {
|
|
1013
|
+
const nodeEl = editor.view.nodeDOM($from.pos);
|
|
1014
|
+
if (nodeEl instanceof HTMLElement) {
|
|
1015
|
+
const input = nodeEl.querySelector('input[type="file"]');
|
|
1016
|
+
if (input instanceof HTMLElement) {
|
|
1017
|
+
input.click();
|
|
1018
|
+
return true;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
};
|
|
866
1025
|
}
|
|
867
1026
|
});
|
|
868
1027
|
|
|
869
1028
|
// src/extensions/link/index.ts
|
|
870
1029
|
var import_extension_link = __toESM(require("@tiptap/extension-link"));
|
|
871
1030
|
var import_state = require("@tiptap/pm/state");
|
|
872
|
-
var
|
|
1031
|
+
var import_react12 = require("@tiptap/react");
|
|
873
1032
|
var Link = import_extension_link.default.extend({
|
|
874
1033
|
inclusive: false,
|
|
875
1034
|
parseHTML() {
|
|
@@ -897,7 +1056,7 @@ var Link = import_extension_link.default.extend({
|
|
|
897
1056
|
const { schema, doc, tr } = view.state;
|
|
898
1057
|
let range;
|
|
899
1058
|
if (schema.marks.link) {
|
|
900
|
-
range = (0,
|
|
1059
|
+
range = (0, import_react12.getMarkRange)(doc.resolve(pos), schema.marks.link);
|
|
901
1060
|
}
|
|
902
1061
|
if (!range) {
|
|
903
1062
|
return;
|
|
@@ -923,22 +1082,22 @@ var Link = import_extension_link.default.extend({
|
|
|
923
1082
|
|
|
924
1083
|
// src/extensions/math/index.ts
|
|
925
1084
|
var import_core4 = require("@tiptap/core");
|
|
926
|
-
var
|
|
1085
|
+
var import_react18 = require("@tiptap/react");
|
|
927
1086
|
|
|
928
1087
|
// src/extensions/math/math-block-view.tsx
|
|
929
|
-
var
|
|
1088
|
+
var import_button4 = require("@kopexa/button");
|
|
930
1089
|
var import_dialog2 = require("@kopexa/dialog");
|
|
931
|
-
var
|
|
1090
|
+
var import_icons5 = require("@kopexa/icons");
|
|
932
1091
|
var import_label2 = require("@kopexa/label");
|
|
933
|
-
var
|
|
1092
|
+
var import_react13 = require("@tiptap/react");
|
|
934
1093
|
var import_katex = __toESM(require("katex"));
|
|
935
1094
|
var import_katex_min = require("katex/dist/katex.min.css");
|
|
936
|
-
var
|
|
937
|
-
var
|
|
1095
|
+
var import_react14 = require("react");
|
|
1096
|
+
var import_react_intl8 = require("react-intl");
|
|
938
1097
|
|
|
939
1098
|
// src/extensions/math/messages.ts
|
|
940
|
-
var
|
|
941
|
-
var
|
|
1099
|
+
var import_react_intl7 = require("react-intl");
|
|
1100
|
+
var messages4 = (0, import_react_intl7.defineMessages)({
|
|
942
1101
|
title: {
|
|
943
1102
|
id: "editor.math.title",
|
|
944
1103
|
defaultMessage: "Formula",
|
|
@@ -987,28 +1146,28 @@ var messages3 = (0, import_react_intl5.defineMessages)({
|
|
|
987
1146
|
});
|
|
988
1147
|
|
|
989
1148
|
// src/extensions/math/math-block-view.tsx
|
|
990
|
-
var
|
|
1149
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
991
1150
|
function MathBlockView({ editor, node, getPos }) {
|
|
992
|
-
const intl = (0,
|
|
1151
|
+
const intl = (0, import_react_intl8.useIntl)();
|
|
993
1152
|
const attrs = node.attrs;
|
|
994
1153
|
const { latex = "" } = attrs;
|
|
995
|
-
const isEditable = (0,
|
|
1154
|
+
const isEditable = (0, import_react13.useEditorState)({
|
|
996
1155
|
editor,
|
|
997
1156
|
selector: ({ editor: e }) => {
|
|
998
1157
|
var _a;
|
|
999
1158
|
return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
|
|
1000
1159
|
}
|
|
1001
1160
|
});
|
|
1002
|
-
const [isOpen, setIsOpen] = (0,
|
|
1003
|
-
const [localLatex, setLocalLatex] = (0,
|
|
1004
|
-
const [error, setError] = (0,
|
|
1005
|
-
(0,
|
|
1161
|
+
const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
|
|
1162
|
+
const [localLatex, setLocalLatex] = (0, import_react14.useState)(latex);
|
|
1163
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1164
|
+
(0, import_react14.useEffect)(() => {
|
|
1006
1165
|
if (isOpen) {
|
|
1007
1166
|
setLocalLatex(latex);
|
|
1008
1167
|
setError(null);
|
|
1009
1168
|
}
|
|
1010
1169
|
}, [isOpen, latex]);
|
|
1011
|
-
const renderedHtml = (0,
|
|
1170
|
+
const renderedHtml = (0, import_react14.useMemo)(() => {
|
|
1012
1171
|
if (!latex) return null;
|
|
1013
1172
|
try {
|
|
1014
1173
|
return import_katex.default.renderToString(latex, {
|
|
@@ -1020,7 +1179,7 @@ function MathBlockView({ editor, node, getPos }) {
|
|
|
1020
1179
|
return null;
|
|
1021
1180
|
}
|
|
1022
1181
|
}, [latex]);
|
|
1023
|
-
const previewHtml = (0,
|
|
1182
|
+
const previewHtml = (0, import_react14.useMemo)(() => {
|
|
1024
1183
|
if (!localLatex) return null;
|
|
1025
1184
|
try {
|
|
1026
1185
|
setError(null);
|
|
@@ -1030,11 +1189,11 @@ function MathBlockView({ editor, node, getPos }) {
|
|
|
1030
1189
|
output: "html"
|
|
1031
1190
|
});
|
|
1032
1191
|
} catch (_e) {
|
|
1033
|
-
setError(intl.formatMessage(
|
|
1192
|
+
setError(intl.formatMessage(messages4.invalid_latex));
|
|
1034
1193
|
return null;
|
|
1035
1194
|
}
|
|
1036
1195
|
}, [localLatex, intl]);
|
|
1037
|
-
const handleSave = (0,
|
|
1196
|
+
const handleSave = (0, import_react14.useCallback)(() => {
|
|
1038
1197
|
const pos = getPos();
|
|
1039
1198
|
if (pos === void 0) return;
|
|
1040
1199
|
editor.view.dispatch(
|
|
@@ -1042,12 +1201,12 @@ function MathBlockView({ editor, node, getPos }) {
|
|
|
1042
1201
|
);
|
|
1043
1202
|
setIsOpen(false);
|
|
1044
1203
|
}, [editor, localLatex, getPos]);
|
|
1045
|
-
const handleCancel = (0,
|
|
1204
|
+
const handleCancel = (0, import_react14.useCallback)(() => {
|
|
1046
1205
|
setLocalLatex(latex);
|
|
1047
1206
|
setError(null);
|
|
1048
1207
|
setIsOpen(false);
|
|
1049
1208
|
}, [latex]);
|
|
1050
|
-
const handleOpenEditor = (0,
|
|
1209
|
+
const handleOpenEditor = (0, import_react14.useCallback)(
|
|
1051
1210
|
(e) => {
|
|
1052
1211
|
e.stopPropagation();
|
|
1053
1212
|
e.preventDefault();
|
|
@@ -1058,73 +1217,73 @@ function MathBlockView({ editor, node, getPos }) {
|
|
|
1058
1217
|
[isEditable]
|
|
1059
1218
|
);
|
|
1060
1219
|
const isEmpty = !latex;
|
|
1061
|
-
return /* @__PURE__ */ (0,
|
|
1062
|
-
|
|
1220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1221
|
+
import_react13.NodeViewWrapper,
|
|
1063
1222
|
{
|
|
1064
1223
|
className: "my-4 relative group",
|
|
1065
1224
|
"data-type": "math-block",
|
|
1066
1225
|
"data-latex": latex,
|
|
1067
1226
|
children: [
|
|
1068
|
-
/* @__PURE__ */ (0,
|
|
1227
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1069
1228
|
"button",
|
|
1070
1229
|
{
|
|
1071
1230
|
type: "button",
|
|
1072
1231
|
className: "w-full flex items-center justify-center min-h-16 p-4 rounded-md border border-border bg-muted/30 cursor-pointer hover:bg-muted/50 transition-colors",
|
|
1073
1232
|
onClick: handleOpenEditor,
|
|
1074
|
-
children: isEmpty ? /* @__PURE__ */ (0,
|
|
1075
|
-
/* @__PURE__ */ (0,
|
|
1076
|
-
/* @__PURE__ */ (0,
|
|
1077
|
-
] }) : renderedHtml ? /* @__PURE__ */ (0,
|
|
1233
|
+
children: isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-lg font-serif", children: "\u2211" }),
|
|
1235
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm", children: intl.formatMessage(messages4.empty_formula) })
|
|
1236
|
+
] }) : renderedHtml ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1078
1237
|
"div",
|
|
1079
1238
|
{
|
|
1080
1239
|
className: "katex-display",
|
|
1081
1240
|
dangerouslySetInnerHTML: { __html: renderedHtml }
|
|
1082
1241
|
}
|
|
1083
|
-
) : /* @__PURE__ */ (0,
|
|
1242
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-destructive text-sm", children: intl.formatMessage(messages4.invalid_latex) })
|
|
1084
1243
|
}
|
|
1085
1244
|
),
|
|
1086
|
-
isEditable && !isEmpty && /* @__PURE__ */ (0,
|
|
1087
|
-
|
|
1245
|
+
isEditable && !isEmpty && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1246
|
+
import_button4.IconButton,
|
|
1088
1247
|
{
|
|
1089
1248
|
size: "sm",
|
|
1090
1249
|
variant: "ghost",
|
|
1091
1250
|
className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
1092
|
-
"aria-label": intl.formatMessage(
|
|
1251
|
+
"aria-label": intl.formatMessage(messages4.edit),
|
|
1093
1252
|
onClick: handleOpenEditor,
|
|
1094
|
-
children: /* @__PURE__ */ (0,
|
|
1253
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons5.EditIcon, { className: "size-3.5" })
|
|
1095
1254
|
}
|
|
1096
1255
|
),
|
|
1097
|
-
/* @__PURE__ */ (0,
|
|
1098
|
-
/* @__PURE__ */ (0,
|
|
1099
|
-
/* @__PURE__ */ (0,
|
|
1100
|
-
/* @__PURE__ */ (0,
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1102
|
-
/* @__PURE__ */ (0,
|
|
1256
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_dialog2.Dialog.Content, { children: [
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Title, { children: intl.formatMessage(messages4.title) }) }),
|
|
1258
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-4", children: [
|
|
1259
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1260
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_label2.Label, { className: "text-sm", children: intl.formatMessage(messages4.latex_input) }),
|
|
1261
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1103
1262
|
"textarea",
|
|
1104
1263
|
{
|
|
1105
1264
|
className: "w-full min-h-24 p-3 rounded-md border border-input bg-background font-mono text-sm resize-y focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
1106
1265
|
value: localLatex,
|
|
1107
1266
|
onChange: (e) => setLocalLatex(e.target.value),
|
|
1108
|
-
placeholder: intl.formatMessage(
|
|
1267
|
+
placeholder: intl.formatMessage(messages4.latex_placeholder),
|
|
1109
1268
|
spellCheck: false
|
|
1110
1269
|
}
|
|
1111
1270
|
),
|
|
1112
|
-
error && /* @__PURE__ */ (0,
|
|
1271
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-destructive", children: error })
|
|
1113
1272
|
] }),
|
|
1114
|
-
/* @__PURE__ */ (0,
|
|
1115
|
-
/* @__PURE__ */ (0,
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1273
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_label2.Label, { className: "text-sm", children: intl.formatMessage(messages4.preview) }),
|
|
1275
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "min-h-16 p-4 rounded-md border border-border bg-muted/30 flex items-center justify-center", children: previewHtml ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1117
1276
|
"div",
|
|
1118
1277
|
{
|
|
1119
1278
|
className: "katex-display",
|
|
1120
1279
|
dangerouslySetInnerHTML: { __html: previewHtml }
|
|
1121
1280
|
}
|
|
1122
|
-
) : localLatex ? /* @__PURE__ */ (0,
|
|
1281
|
+
) : localLatex ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.invalid_latex) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.latex_placeholder) }) })
|
|
1123
1282
|
] })
|
|
1124
1283
|
] }) }),
|
|
1125
|
-
/* @__PURE__ */ (0,
|
|
1126
|
-
/* @__PURE__ */ (0,
|
|
1127
|
-
/* @__PURE__ */ (0,
|
|
1284
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_dialog2.Dialog.Footer, { children: [
|
|
1285
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_button4.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages4.cancel) }),
|
|
1286
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_button4.Button, { onClick: handleSave, disabled: !!error && !!localLatex, children: intl.formatMessage(messages4.save) })
|
|
1128
1287
|
] })
|
|
1129
1288
|
] }) })
|
|
1130
1289
|
]
|
|
@@ -1134,39 +1293,39 @@ function MathBlockView({ editor, node, getPos }) {
|
|
|
1134
1293
|
|
|
1135
1294
|
// src/extensions/math/inline-math.ts
|
|
1136
1295
|
var import_core3 = require("@tiptap/core");
|
|
1137
|
-
var
|
|
1296
|
+
var import_react17 = require("@tiptap/react");
|
|
1138
1297
|
|
|
1139
1298
|
// src/extensions/math/inline-math-view.tsx
|
|
1140
|
-
var
|
|
1299
|
+
var import_button5 = require("@kopexa/button");
|
|
1141
1300
|
var import_dialog3 = require("@kopexa/dialog");
|
|
1142
1301
|
var import_label3 = require("@kopexa/label");
|
|
1143
|
-
var
|
|
1302
|
+
var import_react15 = require("@tiptap/react");
|
|
1144
1303
|
var import_katex2 = __toESM(require("katex"));
|
|
1145
1304
|
var import_katex_min2 = require("katex/dist/katex.min.css");
|
|
1146
|
-
var
|
|
1147
|
-
var
|
|
1148
|
-
var
|
|
1305
|
+
var import_react16 = require("react");
|
|
1306
|
+
var import_react_intl9 = require("react-intl");
|
|
1307
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1149
1308
|
function InlineMathView({ editor, node, getPos }) {
|
|
1150
|
-
const intl = (0,
|
|
1309
|
+
const intl = (0, import_react_intl9.useIntl)();
|
|
1151
1310
|
const attrs = node.attrs;
|
|
1152
1311
|
const { latex = "" } = attrs;
|
|
1153
|
-
const isEditable = (0,
|
|
1312
|
+
const isEditable = (0, import_react15.useEditorState)({
|
|
1154
1313
|
editor,
|
|
1155
1314
|
selector: ({ editor: e }) => {
|
|
1156
1315
|
var _a;
|
|
1157
1316
|
return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
|
|
1158
1317
|
}
|
|
1159
1318
|
});
|
|
1160
|
-
const [isOpen, setIsOpen] = (0,
|
|
1161
|
-
const [localLatex, setLocalLatex] = (0,
|
|
1162
|
-
const [error, setError] = (0,
|
|
1163
|
-
(0,
|
|
1319
|
+
const [isOpen, setIsOpen] = (0, import_react16.useState)(false);
|
|
1320
|
+
const [localLatex, setLocalLatex] = (0, import_react16.useState)(latex);
|
|
1321
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
1322
|
+
(0, import_react16.useEffect)(() => {
|
|
1164
1323
|
if (isOpen) {
|
|
1165
1324
|
setLocalLatex(latex);
|
|
1166
1325
|
setError(null);
|
|
1167
1326
|
}
|
|
1168
1327
|
}, [isOpen, latex]);
|
|
1169
|
-
const renderedHtml = (0,
|
|
1328
|
+
const renderedHtml = (0, import_react16.useMemo)(() => {
|
|
1170
1329
|
if (!latex) return null;
|
|
1171
1330
|
try {
|
|
1172
1331
|
return import_katex2.default.renderToString(latex, {
|
|
@@ -1178,7 +1337,7 @@ function InlineMathView({ editor, node, getPos }) {
|
|
|
1178
1337
|
return null;
|
|
1179
1338
|
}
|
|
1180
1339
|
}, [latex]);
|
|
1181
|
-
const previewHtml = (0,
|
|
1340
|
+
const previewHtml = (0, import_react16.useMemo)(() => {
|
|
1182
1341
|
if (!localLatex) return null;
|
|
1183
1342
|
try {
|
|
1184
1343
|
setError(null);
|
|
@@ -1188,11 +1347,11 @@ function InlineMathView({ editor, node, getPos }) {
|
|
|
1188
1347
|
output: "html"
|
|
1189
1348
|
});
|
|
1190
1349
|
} catch (_e) {
|
|
1191
|
-
setError(intl.formatMessage(
|
|
1350
|
+
setError(intl.formatMessage(messages4.invalid_latex));
|
|
1192
1351
|
return null;
|
|
1193
1352
|
}
|
|
1194
1353
|
}, [localLatex, intl]);
|
|
1195
|
-
const handleSave = (0,
|
|
1354
|
+
const handleSave = (0, import_react16.useCallback)(() => {
|
|
1196
1355
|
const pos = getPos();
|
|
1197
1356
|
if (pos === void 0) return;
|
|
1198
1357
|
editor.view.dispatch(
|
|
@@ -1200,12 +1359,12 @@ function InlineMathView({ editor, node, getPos }) {
|
|
|
1200
1359
|
);
|
|
1201
1360
|
setIsOpen(false);
|
|
1202
1361
|
}, [editor, localLatex, getPos]);
|
|
1203
|
-
const handleCancel = (0,
|
|
1362
|
+
const handleCancel = (0, import_react16.useCallback)(() => {
|
|
1204
1363
|
setLocalLatex(latex);
|
|
1205
1364
|
setError(null);
|
|
1206
1365
|
setIsOpen(false);
|
|
1207
1366
|
}, [latex]);
|
|
1208
|
-
const handleClick = (0,
|
|
1367
|
+
const handleClick = (0, import_react16.useCallback)(
|
|
1209
1368
|
(e) => {
|
|
1210
1369
|
e.stopPropagation();
|
|
1211
1370
|
e.preventDefault();
|
|
@@ -1216,58 +1375,58 @@ function InlineMathView({ editor, node, getPos }) {
|
|
|
1216
1375
|
[isEditable]
|
|
1217
1376
|
);
|
|
1218
1377
|
const isEmpty = !latex;
|
|
1219
|
-
return /* @__PURE__ */ (0,
|
|
1220
|
-
|
|
1378
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1379
|
+
import_react15.NodeViewWrapper,
|
|
1221
1380
|
{
|
|
1222
1381
|
as: "span",
|
|
1223
1382
|
className: "inline-math-wrapper",
|
|
1224
1383
|
"data-type": "inline-math",
|
|
1225
1384
|
"data-latex": latex,
|
|
1226
1385
|
children: [
|
|
1227
|
-
/* @__PURE__ */ (0,
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1228
1387
|
"span",
|
|
1229
1388
|
{
|
|
1230
1389
|
className: `inline-math cursor-pointer rounded px-0.5 transition-colors ${isEditable ? "hover:bg-primary/10 hover:ring-1 hover:ring-primary/20" : ""} ${isEmpty ? "text-muted-foreground italic" : ""}`,
|
|
1231
1390
|
onClick: handleClick,
|
|
1232
|
-
children: isEmpty ? /* @__PURE__ */ (0,
|
|
1391
|
+
children: isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs", children: "$?$" }) : renderedHtml ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1233
1392
|
"span",
|
|
1234
1393
|
{
|
|
1235
1394
|
dangerouslySetInnerHTML: { __html: renderedHtml }
|
|
1236
1395
|
}
|
|
1237
|
-
) : /* @__PURE__ */ (0,
|
|
1396
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-destructive text-xs", children: latex })
|
|
1238
1397
|
}
|
|
1239
1398
|
),
|
|
1240
|
-
/* @__PURE__ */ (0,
|
|
1241
|
-
/* @__PURE__ */ (0,
|
|
1242
|
-
/* @__PURE__ */ (0,
|
|
1243
|
-
/* @__PURE__ */ (0,
|
|
1244
|
-
/* @__PURE__ */ (0,
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_dialog3.Dialog.Content, { children: [
|
|
1400
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Title, { children: intl.formatMessage(messages4.title) }) }),
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-4", children: [
|
|
1402
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1403
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_label3.Label, { className: "text-sm", children: intl.formatMessage(messages4.latex_input) }),
|
|
1404
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1246
1405
|
"input",
|
|
1247
1406
|
{
|
|
1248
1407
|
type: "text",
|
|
1249
1408
|
className: "w-full p-2 rounded-md border border-input bg-background font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
1250
1409
|
value: localLatex,
|
|
1251
1410
|
onChange: (e) => setLocalLatex(e.target.value),
|
|
1252
|
-
placeholder: intl.formatMessage(
|
|
1411
|
+
placeholder: intl.formatMessage(messages4.latex_placeholder),
|
|
1253
1412
|
spellCheck: false
|
|
1254
1413
|
}
|
|
1255
1414
|
),
|
|
1256
|
-
error && /* @__PURE__ */ (0,
|
|
1415
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs text-destructive", children: error })
|
|
1257
1416
|
] }),
|
|
1258
|
-
/* @__PURE__ */ (0,
|
|
1259
|
-
/* @__PURE__ */ (0,
|
|
1260
|
-
/* @__PURE__ */ (0,
|
|
1417
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_label3.Label, { className: "text-sm", children: intl.formatMessage(messages4.preview) }),
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "min-h-10 p-3 rounded-md border border-border bg-muted/30 flex items-center justify-center", children: previewHtml ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1261
1420
|
"span",
|
|
1262
1421
|
{
|
|
1263
1422
|
dangerouslySetInnerHTML: { __html: previewHtml }
|
|
1264
1423
|
}
|
|
1265
|
-
) : localLatex ? /* @__PURE__ */ (0,
|
|
1424
|
+
) : localLatex ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.invalid_latex) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground text-sm", children: "$...$" }) })
|
|
1266
1425
|
] })
|
|
1267
1426
|
] }) }),
|
|
1268
|
-
/* @__PURE__ */ (0,
|
|
1269
|
-
/* @__PURE__ */ (0,
|
|
1270
|
-
/* @__PURE__ */ (0,
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_dialog3.Dialog.Footer, { children: [
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_button5.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages4.cancel) }),
|
|
1429
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_button5.Button, { onClick: handleSave, disabled: !!error && !!localLatex, children: intl.formatMessage(messages4.save) })
|
|
1271
1430
|
] })
|
|
1272
1431
|
] }) })
|
|
1273
1432
|
]
|
|
@@ -1313,7 +1472,7 @@ var InlineMath = import_core3.Node.create({
|
|
|
1313
1472
|
];
|
|
1314
1473
|
},
|
|
1315
1474
|
addNodeView() {
|
|
1316
|
-
return (0,
|
|
1475
|
+
return (0, import_react17.ReactNodeViewRenderer)(InlineMathView, {
|
|
1317
1476
|
as: "span"
|
|
1318
1477
|
});
|
|
1319
1478
|
},
|
|
@@ -1381,7 +1540,7 @@ var MathBlock = import_core4.Node.create({
|
|
|
1381
1540
|
];
|
|
1382
1541
|
},
|
|
1383
1542
|
addNodeView() {
|
|
1384
|
-
return (0,
|
|
1543
|
+
return (0, import_react18.ReactNodeViewRenderer)(MathBlockView);
|
|
1385
1544
|
},
|
|
1386
1545
|
addCommands() {
|
|
1387
1546
|
return {
|
|
@@ -1425,8 +1584,8 @@ var MathBlock = import_core4.Node.create({
|
|
|
1425
1584
|
// src/extensions/selection/index.ts
|
|
1426
1585
|
var import_state2 = require("@tiptap/pm/state");
|
|
1427
1586
|
var import_view = require("@tiptap/pm/view");
|
|
1428
|
-
var
|
|
1429
|
-
var Selection =
|
|
1587
|
+
var import_react19 = require("@tiptap/react");
|
|
1588
|
+
var Selection = import_react19.Extension.create({
|
|
1430
1589
|
name: "selection",
|
|
1431
1590
|
addProseMirrorPlugins() {
|
|
1432
1591
|
const { editor } = this;
|
|
@@ -1441,7 +1600,7 @@ var Selection = import_react16.Extension.create({
|
|
|
1441
1600
|
if (editor.isFocused === true || !editor.isEditable) {
|
|
1442
1601
|
return null;
|
|
1443
1602
|
}
|
|
1444
|
-
if ((0,
|
|
1603
|
+
if ((0, import_react19.isNodeSelection)(state.selection)) {
|
|
1445
1604
|
return null;
|
|
1446
1605
|
}
|
|
1447
1606
|
return import_view.DecorationSet.create(state.doc, [
|
|
@@ -1458,18 +1617,18 @@ var Selection = import_react16.Extension.create({
|
|
|
1458
1617
|
|
|
1459
1618
|
// src/extensions/toc/index.ts
|
|
1460
1619
|
var import_core5 = require("@tiptap/core");
|
|
1461
|
-
var
|
|
1620
|
+
var import_react23 = require("@tiptap/react");
|
|
1462
1621
|
|
|
1463
1622
|
// src/extensions/toc/toc-view.tsx
|
|
1464
|
-
var
|
|
1465
|
-
var
|
|
1466
|
-
var
|
|
1467
|
-
var
|
|
1468
|
-
var
|
|
1623
|
+
var import_icons7 = require("@kopexa/icons");
|
|
1624
|
+
var import_theme4 = require("@kopexa/theme");
|
|
1625
|
+
var import_react21 = require("@tiptap/react");
|
|
1626
|
+
var import_react22 = require("react");
|
|
1627
|
+
var import_react_intl12 = require("react-intl");
|
|
1469
1628
|
|
|
1470
1629
|
// src/extensions/toc/messages.ts
|
|
1471
|
-
var
|
|
1472
|
-
var
|
|
1630
|
+
var import_react_intl10 = require("react-intl");
|
|
1631
|
+
var messages5 = (0, import_react_intl10.defineMessages)({
|
|
1473
1632
|
title: {
|
|
1474
1633
|
id: "editor.toc.title",
|
|
1475
1634
|
defaultMessage: "Table of Contents",
|
|
@@ -1543,15 +1702,15 @@ var messages4 = (0, import_react_intl8.defineMessages)({
|
|
|
1543
1702
|
});
|
|
1544
1703
|
|
|
1545
1704
|
// src/extensions/toc/toc-settings.tsx
|
|
1546
|
-
var
|
|
1705
|
+
var import_button6 = require("@kopexa/button");
|
|
1547
1706
|
var import_dialog4 = require("@kopexa/dialog");
|
|
1548
|
-
var
|
|
1707
|
+
var import_icons6 = require("@kopexa/icons");
|
|
1549
1708
|
var import_label4 = require("@kopexa/label");
|
|
1550
1709
|
var import_select2 = require("@kopexa/select");
|
|
1551
1710
|
var import_switch = require("@kopexa/switch");
|
|
1552
|
-
var
|
|
1553
|
-
var
|
|
1554
|
-
var
|
|
1711
|
+
var import_react20 = require("react");
|
|
1712
|
+
var import_react_intl11 = require("react-intl");
|
|
1713
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1555
1714
|
var HEADING_LEVELS = [
|
|
1556
1715
|
{ value: "1", label: "H1" },
|
|
1557
1716
|
{ value: "2", label: "H2" },
|
|
@@ -1561,15 +1720,15 @@ var HEADING_LEVELS = [
|
|
|
1561
1720
|
{ value: "6", label: "H6" }
|
|
1562
1721
|
];
|
|
1563
1722
|
function TocSettings({ editor, attrs, getPos }) {
|
|
1564
|
-
const intl = (0,
|
|
1565
|
-
const [isOpen, setIsOpen] = (0,
|
|
1566
|
-
const [localAttrs, setLocalAttrs] = (0,
|
|
1567
|
-
(0,
|
|
1723
|
+
const intl = (0, import_react_intl11.useIntl)();
|
|
1724
|
+
const [isOpen, setIsOpen] = (0, import_react20.useState)(false);
|
|
1725
|
+
const [localAttrs, setLocalAttrs] = (0, import_react20.useState)(attrs);
|
|
1726
|
+
(0, import_react20.useEffect)(() => {
|
|
1568
1727
|
if (isOpen) {
|
|
1569
1728
|
setLocalAttrs(attrs);
|
|
1570
1729
|
}
|
|
1571
1730
|
}, [isOpen, attrs]);
|
|
1572
|
-
const handleSave = (0,
|
|
1731
|
+
const handleSave = (0, import_react20.useCallback)(() => {
|
|
1573
1732
|
const pos = getPos();
|
|
1574
1733
|
if (pos === void 0) return;
|
|
1575
1734
|
editor.view.dispatch(
|
|
@@ -1577,11 +1736,11 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1577
1736
|
);
|
|
1578
1737
|
setIsOpen(false);
|
|
1579
1738
|
}, [editor, localAttrs, getPos]);
|
|
1580
|
-
const handleCancel = (0,
|
|
1739
|
+
const handleCancel = (0, import_react20.useCallback)(() => {
|
|
1581
1740
|
setLocalAttrs(attrs);
|
|
1582
1741
|
setIsOpen(false);
|
|
1583
1742
|
}, [attrs]);
|
|
1584
|
-
const handleMinLevelChange = (0,
|
|
1743
|
+
const handleMinLevelChange = (0, import_react20.useCallback)((value) => {
|
|
1585
1744
|
const minLevel = Number.parseInt(String(value), 10);
|
|
1586
1745
|
setLocalAttrs((prev) => ({
|
|
1587
1746
|
...prev,
|
|
@@ -1590,7 +1749,7 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1590
1749
|
maxLevel: Math.max(prev.maxLevel, minLevel)
|
|
1591
1750
|
}));
|
|
1592
1751
|
}, []);
|
|
1593
|
-
const handleMaxLevelChange = (0,
|
|
1752
|
+
const handleMaxLevelChange = (0, import_react20.useCallback)((value) => {
|
|
1594
1753
|
const maxLevel = Number.parseInt(String(value), 10);
|
|
1595
1754
|
setLocalAttrs((prev) => ({
|
|
1596
1755
|
...prev,
|
|
@@ -1599,10 +1758,10 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1599
1758
|
minLevel: Math.min(prev.minLevel, maxLevel)
|
|
1600
1759
|
}));
|
|
1601
1760
|
}, []);
|
|
1602
|
-
const handleNumberedChange = (0,
|
|
1761
|
+
const handleNumberedChange = (0, import_react20.useCallback)((checked) => {
|
|
1603
1762
|
setLocalAttrs((prev) => ({ ...prev, numbered: checked }));
|
|
1604
1763
|
}, []);
|
|
1605
|
-
const handleStyleChange = (0,
|
|
1764
|
+
const handleStyleChange = (0, import_react20.useCallback)((value) => {
|
|
1606
1765
|
setLocalAttrs((prev) => ({
|
|
1607
1766
|
...prev,
|
|
1608
1767
|
style: String(value)
|
|
@@ -1611,36 +1770,36 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1611
1770
|
if (!editor.isEditable) {
|
|
1612
1771
|
return null;
|
|
1613
1772
|
}
|
|
1614
|
-
return /* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
|
|
1773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1775
|
+
import_button6.IconButton,
|
|
1617
1776
|
{
|
|
1618
1777
|
size: "sm",
|
|
1619
1778
|
variant: "ghost",
|
|
1620
|
-
"aria-label": intl.formatMessage(
|
|
1779
|
+
"aria-label": intl.formatMessage(messages5.settings),
|
|
1621
1780
|
onClick: (e) => {
|
|
1622
1781
|
e.stopPropagation();
|
|
1623
1782
|
e.preventDefault();
|
|
1624
1783
|
setIsOpen(true);
|
|
1625
1784
|
},
|
|
1626
|
-
children: /* @__PURE__ */ (0,
|
|
1785
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons6.SettingsIcon, { className: "size-3.5" })
|
|
1627
1786
|
}
|
|
1628
1787
|
),
|
|
1629
|
-
/* @__PURE__ */ (0,
|
|
1630
|
-
/* @__PURE__ */ (0,
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1632
|
-
/* @__PURE__ */ (0,
|
|
1633
|
-
/* @__PURE__ */ (0,
|
|
1634
|
-
/* @__PURE__ */ (0,
|
|
1635
|
-
/* @__PURE__ */ (0,
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_dialog4.Dialog.Content, { children: [
|
|
1789
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Title, { children: intl.formatMessage(messages5.settings) }) }),
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-4", children: [
|
|
1791
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
1792
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1793
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.min_level) }),
|
|
1794
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1636
1795
|
import_select2.Select,
|
|
1637
1796
|
{
|
|
1638
1797
|
size: "sm",
|
|
1639
1798
|
value: String(localAttrs.minLevel),
|
|
1640
1799
|
onValueChange: handleMinLevelChange,
|
|
1641
1800
|
children: [
|
|
1642
|
-
/* @__PURE__ */ (0,
|
|
1643
|
-
/* @__PURE__ */ (0,
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
|
|
1802
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Content, { children: HEADING_LEVELS.map((level) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1644
1803
|
import_select2.Select.Item,
|
|
1645
1804
|
{
|
|
1646
1805
|
value: level.value,
|
|
@@ -1653,17 +1812,17 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1653
1812
|
}
|
|
1654
1813
|
)
|
|
1655
1814
|
] }),
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1815
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1816
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.max_level) }),
|
|
1817
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1659
1818
|
import_select2.Select,
|
|
1660
1819
|
{
|
|
1661
1820
|
size: "sm",
|
|
1662
1821
|
value: String(localAttrs.maxLevel),
|
|
1663
1822
|
onValueChange: handleMaxLevelChange,
|
|
1664
1823
|
children: [
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
1666
|
-
/* @__PURE__ */ (0,
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Content, { children: HEADING_LEVELS.map((level) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1667
1826
|
import_select2.Select.Item,
|
|
1668
1827
|
{
|
|
1669
1828
|
value: level.value,
|
|
@@ -1677,12 +1836,12 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1677
1836
|
)
|
|
1678
1837
|
] })
|
|
1679
1838
|
] }),
|
|
1680
|
-
/* @__PURE__ */ (0,
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
1839
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1840
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-0.5", children: [
|
|
1841
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.numbered) }),
|
|
1842
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-muted-foreground", children: intl.formatMessage(messages5.numbered_hint) })
|
|
1684
1843
|
] }),
|
|
1685
|
-
/* @__PURE__ */ (0,
|
|
1844
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1686
1845
|
import_switch.Switch,
|
|
1687
1846
|
{
|
|
1688
1847
|
size: "sm",
|
|
@@ -1691,36 +1850,36 @@ function TocSettings({ editor, attrs, getPos }) {
|
|
|
1691
1850
|
}
|
|
1692
1851
|
)
|
|
1693
1852
|
] }),
|
|
1694
|
-
/* @__PURE__ */ (0,
|
|
1695
|
-
/* @__PURE__ */ (0,
|
|
1696
|
-
/* @__PURE__ */ (0,
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.style) }),
|
|
1855
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1697
1856
|
import_select2.Select,
|
|
1698
1857
|
{
|
|
1699
1858
|
size: "sm",
|
|
1700
1859
|
value: localAttrs.style,
|
|
1701
1860
|
onValueChange: handleStyleChange,
|
|
1702
1861
|
children: [
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1705
|
-
/* @__PURE__ */ (0,
|
|
1706
|
-
/* @__PURE__ */ (0,
|
|
1707
|
-
/* @__PURE__ */ (0,
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
|
|
1863
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_select2.Select.Content, { children: [
|
|
1864
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "default", children: intl.formatMessage(messages5.style_default) }),
|
|
1865
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "flat", children: intl.formatMessage(messages5.style_flat) }),
|
|
1866
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "compact", children: intl.formatMessage(messages5.style_compact) })
|
|
1708
1867
|
] })
|
|
1709
1868
|
]
|
|
1710
1869
|
}
|
|
1711
1870
|
)
|
|
1712
1871
|
] })
|
|
1713
1872
|
] }) }),
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
1873
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_dialog4.Dialog.Footer, { children: [
|
|
1874
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_button6.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages5.cancel) }),
|
|
1875
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_button6.Button, { onClick: handleSave, children: intl.formatMessage(messages5.save) })
|
|
1717
1876
|
] })
|
|
1718
1877
|
] }) })
|
|
1719
1878
|
] });
|
|
1720
1879
|
}
|
|
1721
1880
|
|
|
1722
1881
|
// src/extensions/toc/toc-view.tsx
|
|
1723
|
-
var
|
|
1882
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1724
1883
|
function generateHeadingNumbers(headings, minLevel) {
|
|
1725
1884
|
const counters = [0, 0, 0, 0, 0, 0];
|
|
1726
1885
|
return headings.map((heading) => {
|
|
@@ -1742,8 +1901,8 @@ function generateHeadingNumbers(headings, minLevel) {
|
|
|
1742
1901
|
});
|
|
1743
1902
|
}
|
|
1744
1903
|
function TocNodeView({ editor, node, getPos }) {
|
|
1745
|
-
const [headings, setHeadings] = (0,
|
|
1746
|
-
const intl = (0,
|
|
1904
|
+
const [headings, setHeadings] = (0, import_react22.useState)([]);
|
|
1905
|
+
const intl = (0, import_react_intl12.useIntl)();
|
|
1747
1906
|
const attrs = node.attrs;
|
|
1748
1907
|
const {
|
|
1749
1908
|
minLevel = 1,
|
|
@@ -1751,8 +1910,8 @@ function TocNodeView({ editor, node, getPos }) {
|
|
|
1751
1910
|
numbered = false,
|
|
1752
1911
|
style = "default"
|
|
1753
1912
|
} = attrs;
|
|
1754
|
-
const styles = (0,
|
|
1755
|
-
const updateHeadings = (0,
|
|
1913
|
+
const styles = (0, import_react22.useMemo)(() => (0, import_theme4.toc)({ style }), [style]);
|
|
1914
|
+
const updateHeadings = (0, import_react22.useCallback)(() => {
|
|
1756
1915
|
const items = [];
|
|
1757
1916
|
const { doc } = editor.state;
|
|
1758
1917
|
doc.descendants((docNode, pos) => {
|
|
@@ -1772,14 +1931,14 @@ function TocNodeView({ editor, node, getPos }) {
|
|
|
1772
1931
|
const numberedHeadings = generateHeadingNumbers(items, minLevel);
|
|
1773
1932
|
setHeadings(numberedHeadings);
|
|
1774
1933
|
}, [editor, minLevel, maxLevel]);
|
|
1775
|
-
(0,
|
|
1934
|
+
(0, import_react22.useEffect)(() => {
|
|
1776
1935
|
updateHeadings();
|
|
1777
1936
|
editor.on("update", updateHeadings);
|
|
1778
1937
|
return () => {
|
|
1779
1938
|
editor.off("update", updateHeadings);
|
|
1780
1939
|
};
|
|
1781
1940
|
}, [editor, updateHeadings]);
|
|
1782
|
-
const handleClick = (0,
|
|
1941
|
+
const handleClick = (0, import_react22.useCallback)(
|
|
1783
1942
|
(pos, id) => {
|
|
1784
1943
|
var _a;
|
|
1785
1944
|
editor.chain().focus().setTextSelection(pos).run();
|
|
@@ -1800,13 +1959,13 @@ function TocNodeView({ editor, node, getPos }) {
|
|
|
1800
1959
|
const getIndent = (level) => {
|
|
1801
1960
|
return (level - minLevel) * 16;
|
|
1802
1961
|
};
|
|
1803
|
-
return /* @__PURE__ */ (0,
|
|
1804
|
-
/* @__PURE__ */ (0,
|
|
1805
|
-
/* @__PURE__ */ (0,
|
|
1806
|
-
/* @__PURE__ */ (0,
|
|
1807
|
-
/* @__PURE__ */ (0,
|
|
1962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react21.NodeViewWrapper, { className: styles.root(), "data-type": "toc", children: [
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: styles.header(), children: [
|
|
1964
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: styles.headerContent(), children: [
|
|
1965
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons7.ListIcon, { className: styles.headerIcon() }),
|
|
1966
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: styles.headerTitle(), children: intl.formatMessage(messages5.title) })
|
|
1808
1967
|
] }),
|
|
1809
|
-
/* @__PURE__ */ (0,
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: styles.headerActions(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1810
1969
|
TocSettings,
|
|
1811
1970
|
{
|
|
1812
1971
|
editor,
|
|
@@ -1815,7 +1974,7 @@ function TocNodeView({ editor, node, getPos }) {
|
|
|
1815
1974
|
}
|
|
1816
1975
|
) })
|
|
1817
1976
|
] }),
|
|
1818
|
-
isEmpty ? /* @__PURE__ */ (0,
|
|
1977
|
+
isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: styles.emptyState(), children: intl.formatMessage(messages5.empty_state) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("nav", { className: styles.nav(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: styles.list(), children: headings.map((heading) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1819
1978
|
"li",
|
|
1820
1979
|
{
|
|
1821
1980
|
className: styles.item(),
|
|
@@ -1823,14 +1982,14 @@ function TocNodeView({ editor, node, getPos }) {
|
|
|
1823
1982
|
paddingLeft: `${getIndent(heading.level)}px`
|
|
1824
1983
|
},
|
|
1825
1984
|
children: [
|
|
1826
|
-
numbered && heading.number && /* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
1985
|
+
numbered && heading.number && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: styles.itemNumber(), children: heading.number }),
|
|
1986
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1828
1987
|
"button",
|
|
1829
1988
|
{
|
|
1830
1989
|
type: "button",
|
|
1831
1990
|
onClick: () => handleClick(heading.pos, heading.id),
|
|
1832
1991
|
className: styles.itemButton(),
|
|
1833
|
-
children: heading.text || intl.formatMessage(
|
|
1992
|
+
children: heading.text || intl.formatMessage(messages5.empty_heading)
|
|
1834
1993
|
}
|
|
1835
1994
|
)
|
|
1836
1995
|
]
|
|
@@ -1899,7 +2058,7 @@ var TocNode = import_core5.Node.create({
|
|
|
1899
2058
|
];
|
|
1900
2059
|
},
|
|
1901
2060
|
addNodeView() {
|
|
1902
|
-
return (0,
|
|
2061
|
+
return (0, import_react23.ReactNodeViewRenderer)(TocNodeView);
|
|
1903
2062
|
},
|
|
1904
2063
|
addCommands() {
|
|
1905
2064
|
return {
|
|
@@ -1928,7 +2087,7 @@ var TocNode = import_core5.Node.create({
|
|
|
1928
2087
|
|
|
1929
2088
|
// src/extensions/trailing-node/index.ts
|
|
1930
2089
|
var import_state3 = require("@tiptap/pm/state");
|
|
1931
|
-
var
|
|
2090
|
+
var import_react24 = require("@tiptap/react");
|
|
1932
2091
|
function nodeEqualsType({
|
|
1933
2092
|
types,
|
|
1934
2093
|
node
|
|
@@ -1939,7 +2098,7 @@ function nodeEqualsType({
|
|
|
1939
2098
|
}
|
|
1940
2099
|
return node.type === types;
|
|
1941
2100
|
}
|
|
1942
|
-
var TrailingNode =
|
|
2101
|
+
var TrailingNode = import_react24.Extension.create({
|
|
1943
2102
|
name: "trailingNode",
|
|
1944
2103
|
addOptions() {
|
|
1945
2104
|
return {
|
|
@@ -2215,7 +2374,19 @@ var useCreateEditor = ({
|
|
|
2215
2374
|
}) => {
|
|
2216
2375
|
const fileHandlerFromContext = useEditorFile();
|
|
2217
2376
|
const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
|
|
2218
|
-
const
|
|
2377
|
+
const extensions = (0, import_react26.useMemo)(
|
|
2378
|
+
() => getExtensions({
|
|
2379
|
+
editable,
|
|
2380
|
+
placeholder,
|
|
2381
|
+
enableControls,
|
|
2382
|
+
controlResolver,
|
|
2383
|
+
fileHandler
|
|
2384
|
+
}),
|
|
2385
|
+
// Only recreate extensions when these values change
|
|
2386
|
+
// Note: fileHandler and controlResolver are object references, so they should be stable
|
|
2387
|
+
[editable, placeholder, enableControls, controlResolver, fileHandler]
|
|
2388
|
+
);
|
|
2389
|
+
const editor = (0, import_react25.useEditor)({
|
|
2219
2390
|
editorProps: {
|
|
2220
2391
|
attributes: {
|
|
2221
2392
|
autocomplete: "off",
|
|
@@ -2226,13 +2397,7 @@ var useCreateEditor = ({
|
|
|
2226
2397
|
},
|
|
2227
2398
|
immediatelyRender: false,
|
|
2228
2399
|
shouldRerenderOnTransaction: false,
|
|
2229
|
-
extensions
|
|
2230
|
-
editable,
|
|
2231
|
-
placeholder,
|
|
2232
|
-
enableControls,
|
|
2233
|
-
controlResolver,
|
|
2234
|
-
fileHandler
|
|
2235
|
-
}),
|
|
2400
|
+
extensions,
|
|
2236
2401
|
editable,
|
|
2237
2402
|
onUpdate: ({ editor: editor2 }) => {
|
|
2238
2403
|
onChange == null ? void 0 : onChange(editor2.getJSON());
|
|
@@ -2240,7 +2405,7 @@ var useCreateEditor = ({
|
|
|
2240
2405
|
content: safeParseContent(content),
|
|
2241
2406
|
...options
|
|
2242
2407
|
});
|
|
2243
|
-
(0,
|
|
2408
|
+
(0, import_react26.useEffect)(() => {
|
|
2244
2409
|
if (editor && editor.isEditable !== editable) {
|
|
2245
2410
|
editor.setEditable(editable);
|
|
2246
2411
|
}
|
|
@@ -2304,8 +2469,12 @@ function getExtensions({
|
|
|
2304
2469
|
CalloutNode,
|
|
2305
2470
|
MathBlock,
|
|
2306
2471
|
InlineMath,
|
|
2307
|
-
// Image support -
|
|
2308
|
-
ImageNode
|
|
2472
|
+
// Image support - extended with file reference resolution
|
|
2473
|
+
ImageNode.configure({
|
|
2474
|
+
allowBase64: true
|
|
2475
|
+
}),
|
|
2476
|
+
// Image upload placeholder
|
|
2477
|
+
ImageUploadNode,
|
|
2309
2478
|
import_extensions.Placeholder.configure({
|
|
2310
2479
|
placeholder,
|
|
2311
2480
|
emptyNodeClass: "is-empty with-slash"
|