@react-email/editor 0.0.0-experimental.37 → 0.0.0-experimental.39
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/{extension-XZBBjuHO.mjs → extension-CnC8y63H.mjs} +3 -7
- package/dist/extension-CnC8y63H.mjs.map +1 -0
- package/dist/{extension-B8yvCdun.cjs → extension-dGpPpEvD.cjs} +2 -6
- package/dist/index-C4KcMQ0R.d.cts.map +1 -1
- package/dist/index-CxX7W63O.d.mts.map +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.css +27 -54
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +7 -7
- package/dist/index.mjs.map +1 -1
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.d.cts.map +1 -1
- package/dist/plugins/index.d.mts.map +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/{root-BMxsq1NF.mjs → root-CkYaJZpj.mjs} +645 -730
- package/dist/root-CkYaJZpj.mjs.map +1 -0
- package/dist/{root-CNVO39XG.cjs → root-Gu08xybW.cjs} +723 -832
- package/dist/{set-text-alignment-GMXOPMlJ.mjs → set-text-alignment-OA8IMWmO.mjs} +1 -1
- package/dist/{set-text-alignment-GMXOPMlJ.mjs.map → set-text-alignment-OA8IMWmO.mjs.map} +1 -1
- package/dist/ui/bubble-menu/bubble-menu.css +139 -0
- package/dist/ui/index.cjs +32 -57
- package/dist/ui/index.d.cts +280 -364
- package/dist/ui/index.d.cts.map +1 -1
- package/dist/ui/index.d.mts +280 -364
- package/dist/ui/index.d.mts.map +1 -1
- package/dist/ui/index.mjs +17 -35
- package/dist/ui/index.mjs.map +1 -1
- package/dist/ui/themes/default.css +27 -54
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/extension-XZBBjuHO.mjs.map +0 -1
- package/dist/root-BMxsq1NF.mjs.map +0 -1
- package/dist/ui/button-bubble-menu/button-bubble-menu.css +0 -63
- package/dist/ui/image-bubble-menu/image-bubble-menu.css +0 -29
- package/dist/ui/link-bubble-menu/link-bubble-menu.css +0 -68
- /package/dist/{set-text-alignment-aNb7Ml9N.cjs → set-text-alignment-Cv72txmv.cjs} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
const require_event_bus = require('./event-bus-fb8U7hrl.cjs');
|
|
2
|
-
const require_set_text_alignment = require('./set-text-alignment-
|
|
2
|
+
const require_set_text_alignment = require('./set-text-alignment-Cv72txmv.cjs');
|
|
3
3
|
let _tiptap_react = require("@tiptap/react");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
react = require_event_bus.__toESM(react);
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
7
|
let _tiptap_pm_state = require("@tiptap/pm/state");
|
|
8
|
+
let _tiptap_react_menus = require("@tiptap/react/menus");
|
|
8
9
|
let _radix_ui_react_popover = require("@radix-ui/react-popover");
|
|
9
10
|
_radix_ui_react_popover = require_event_bus.__toESM(_radix_ui_react_popover);
|
|
10
|
-
let _tiptap_react_menus = require("@tiptap/react/menus");
|
|
11
11
|
let _floating_ui_react_dom = require("@floating-ui/react-dom");
|
|
12
12
|
let _tiptap_suggestion = require("@tiptap/suggestion");
|
|
13
13
|
_tiptap_suggestion = require_event_bus.__toESM(_tiptap_suggestion);
|
|
@@ -746,137 +746,28 @@ function useBubbleMenuContext() {
|
|
|
746
746
|
}
|
|
747
747
|
|
|
748
748
|
//#endregion
|
|
749
|
-
//#region src/ui/bubble-menu/
|
|
750
|
-
function
|
|
749
|
+
//#region src/ui/bubble-menu/button-edit-link.tsx
|
|
750
|
+
function BubbleMenuButtonEditLink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
751
|
+
const { setIsEditing } = useBubbleMenuContext();
|
|
751
752
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
752
|
-
type: "button",
|
|
753
|
-
"aria-label": name,
|
|
754
|
-
"aria-pressed": isActive,
|
|
755
|
-
className,
|
|
756
|
-
"data-re-bubble-menu-item": "",
|
|
757
|
-
"data-item": name,
|
|
758
|
-
...isActive ? { "data-active": "" } : {},
|
|
759
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
760
|
-
onClick: onCommand,
|
|
761
753
|
...rest,
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
//#endregion
|
|
767
|
-
//#region src/ui/bubble-menu/align-center.tsx
|
|
768
|
-
function BubbleMenuAlignCenter({ className, children }) {
|
|
769
|
-
const { editor } = useBubbleMenuContext();
|
|
770
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
771
|
-
name: "align-center",
|
|
772
|
-
isActive: (0, _tiptap_react.useEditorState)({
|
|
773
|
-
editor,
|
|
774
|
-
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "center" }) ?? false
|
|
775
|
-
}),
|
|
776
|
-
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "center"),
|
|
777
|
-
className,
|
|
778
|
-
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignCenterIcon, {})
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
//#endregion
|
|
783
|
-
//#region src/ui/bubble-menu/align-left.tsx
|
|
784
|
-
function BubbleMenuAlignLeft({ className, children }) {
|
|
785
|
-
const { editor } = useBubbleMenuContext();
|
|
786
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
787
|
-
name: "align-left",
|
|
788
|
-
isActive: (0, _tiptap_react.useEditorState)({
|
|
789
|
-
editor,
|
|
790
|
-
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "left" }) ?? false
|
|
791
|
-
}),
|
|
792
|
-
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "left"),
|
|
793
|
-
className,
|
|
794
|
-
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignLeftIcon, {})
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
//#endregion
|
|
799
|
-
//#region src/ui/bubble-menu/align-right.tsx
|
|
800
|
-
function BubbleMenuAlignRight({ className, children }) {
|
|
801
|
-
const { editor } = useBubbleMenuContext();
|
|
802
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
803
|
-
name: "align-right",
|
|
804
|
-
isActive: (0, _tiptap_react.useEditorState)({
|
|
805
|
-
editor,
|
|
806
|
-
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "right" }) ?? false
|
|
807
|
-
}),
|
|
808
|
-
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "right"),
|
|
809
|
-
className,
|
|
810
|
-
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignRightIcon, {})
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
//#endregion
|
|
815
|
-
//#region src/ui/bubble-menu/create-mark-bubble-item.tsx
|
|
816
|
-
function createMarkBubbleItem(config) {
|
|
817
|
-
function MarkBubbleItem({ className, children }) {
|
|
818
|
-
const { editor } = useBubbleMenuContext();
|
|
819
|
-
const isActive = (0, _tiptap_react.useEditorState)({
|
|
820
|
-
editor,
|
|
821
|
-
selector: ({ editor: editor$1 }) => {
|
|
822
|
-
if (config.activeParams) return editor$1?.isActive(config.activeName, config.activeParams) ?? false;
|
|
823
|
-
return editor$1?.isActive(config.activeName) ?? false;
|
|
824
|
-
}
|
|
825
|
-
});
|
|
826
|
-
const handleCommand = () => {
|
|
827
|
-
const chain = editor.chain().focus();
|
|
828
|
-
const method = chain[config.command];
|
|
829
|
-
if (method) method.call(chain).run();
|
|
830
|
-
};
|
|
831
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
832
|
-
name: config.name,
|
|
833
|
-
isActive,
|
|
834
|
-
onCommand: handleCommand,
|
|
835
|
-
className,
|
|
836
|
-
children: children ?? config.icon
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
MarkBubbleItem.displayName = `BubbleMenu${config.name.charAt(0).toUpperCase() + config.name.slice(1)}`;
|
|
840
|
-
return MarkBubbleItem;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
//#endregion
|
|
844
|
-
//#region src/ui/bubble-menu/bold.tsx
|
|
845
|
-
const BubbleMenuBold = createMarkBubbleItem({
|
|
846
|
-
name: "bold",
|
|
847
|
-
activeName: "bold",
|
|
848
|
-
command: "toggleBold",
|
|
849
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoldIcon, {})
|
|
850
|
-
});
|
|
851
|
-
|
|
852
|
-
//#endregion
|
|
853
|
-
//#region src/ui/bubble-menu/code.tsx
|
|
854
|
-
const BubbleMenuCode = createMarkBubbleItem({
|
|
855
|
-
name: "code",
|
|
856
|
-
activeName: "code",
|
|
857
|
-
command: "toggleCode",
|
|
858
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeIcon, {})
|
|
859
|
-
});
|
|
860
|
-
|
|
861
|
-
//#endregion
|
|
862
|
-
//#region src/ui/bubble-menu/group.tsx
|
|
863
|
-
function BubbleMenuItemGroup({ className, children }) {
|
|
864
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("fieldset", {
|
|
754
|
+
type: "button",
|
|
755
|
+
"aria-label": "Edit link",
|
|
756
|
+
"data-re-btn-bm-item": "",
|
|
757
|
+
"data-item": "edit-link",
|
|
865
758
|
className,
|
|
866
|
-
|
|
867
|
-
|
|
759
|
+
onMouseDown: (e) => {
|
|
760
|
+
e.preventDefault();
|
|
761
|
+
onMouseDown?.(e);
|
|
762
|
+
},
|
|
763
|
+
onClick: (e) => {
|
|
764
|
+
onClick?.(e);
|
|
765
|
+
setIsEditing(true);
|
|
766
|
+
},
|
|
767
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PencilIcon, {})
|
|
868
768
|
});
|
|
869
769
|
}
|
|
870
770
|
|
|
871
|
-
//#endregion
|
|
872
|
-
//#region src/ui/bubble-menu/italic.tsx
|
|
873
|
-
const BubbleMenuItalic = createMarkBubbleItem({
|
|
874
|
-
name: "italic",
|
|
875
|
-
activeName: "italic",
|
|
876
|
-
command: "toggleItalic",
|
|
877
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItalicIcon, {})
|
|
878
|
-
});
|
|
879
|
-
|
|
880
771
|
//#endregion
|
|
881
772
|
//#region src/ui/bubble-menu/utils.ts
|
|
882
773
|
const SAFE_PROTOCOLS = new Set([
|
|
@@ -924,81 +815,27 @@ function focusEditor(editor) {
|
|
|
924
815
|
}
|
|
925
816
|
|
|
926
817
|
//#endregion
|
|
927
|
-
//#region src/ui/bubble-menu/
|
|
928
|
-
function
|
|
929
|
-
const { editor } = useBubbleMenuContext();
|
|
930
|
-
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
|
|
931
|
-
const isControlled = controlledOpen !== void 0;
|
|
932
|
-
const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
|
|
933
|
-
const setIsOpen = react.useCallback((value) => {
|
|
934
|
-
if (!isControlled) setUncontrolledOpen(value);
|
|
935
|
-
onOpenChange?.(value);
|
|
936
|
-
}, [isControlled, onOpenChange]);
|
|
937
|
-
const editorState = (0, _tiptap_react.useEditorState)({
|
|
938
|
-
editor,
|
|
939
|
-
selector: ({ editor: editor$1 }) => ({
|
|
940
|
-
isLinkActive: editor$1?.isActive("link") ?? false,
|
|
941
|
-
hasLink: Boolean(editor$1?.getAttributes("link").href),
|
|
942
|
-
currentHref: editor$1?.getAttributes("link").href || ""
|
|
943
|
-
})
|
|
944
|
-
});
|
|
945
|
-
const setIsOpenRef = react.useRef(setIsOpen);
|
|
946
|
-
setIsOpenRef.current = setIsOpen;
|
|
947
|
-
react.useEffect(() => {
|
|
948
|
-
const subscription = require_event_bus.editorEventBus.on("bubble-menu:add-link", () => {
|
|
949
|
-
setIsOpenRef.current(true);
|
|
950
|
-
});
|
|
951
|
-
return () => {
|
|
952
|
-
setIsOpenRef.current(false);
|
|
953
|
-
subscription.unsubscribe();
|
|
954
|
-
};
|
|
955
|
-
}, []);
|
|
956
|
-
if (!editorState) return null;
|
|
957
|
-
const handleOpenLink = () => {
|
|
958
|
-
setIsOpen(!isOpen);
|
|
959
|
-
};
|
|
960
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
961
|
-
"data-re-link-selector": "",
|
|
962
|
-
...isOpen ? { "data-open": "" } : {},
|
|
963
|
-
...editorState.hasLink ? { "data-has-link": "" } : {},
|
|
964
|
-
className,
|
|
965
|
-
children: [showToggle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
966
|
-
type: "button",
|
|
967
|
-
"aria-expanded": isOpen,
|
|
968
|
-
"aria-haspopup": "true",
|
|
969
|
-
"aria-label": "Add link",
|
|
970
|
-
"aria-pressed": editorState.isLinkActive && editorState.hasLink,
|
|
971
|
-
"data-re-link-selector-trigger": "",
|
|
972
|
-
onClick: handleOpenLink,
|
|
973
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkIcon, {})
|
|
974
|
-
}), isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkForm, {
|
|
975
|
-
editor,
|
|
976
|
-
currentHref: editorState.currentHref,
|
|
977
|
-
validateUrl,
|
|
978
|
-
onLinkApply,
|
|
979
|
-
onLinkRemove,
|
|
980
|
-
setIsOpen,
|
|
981
|
-
children
|
|
982
|
-
})]
|
|
983
|
-
});
|
|
984
|
-
}
|
|
985
|
-
function LinkForm({ editor, currentHref, validateUrl, onLinkApply, onLinkRemove, setIsOpen, children }) {
|
|
818
|
+
//#region src/ui/bubble-menu/button-form.tsx
|
|
819
|
+
function BubbleMenuButtonForm({ className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
820
|
+
const { editor, isEditing, setIsEditing } = useBubbleMenuContext();
|
|
986
821
|
const inputRef = react.useRef(null);
|
|
987
822
|
const formRef = react.useRef(null);
|
|
988
|
-
const
|
|
823
|
+
const buttonHref = editor.getAttributes("button").href ?? "";
|
|
824
|
+
const displayHref = buttonHref === "#" ? "" : buttonHref;
|
|
989
825
|
const [inputValue, setInputValue] = react.useState(displayHref);
|
|
990
826
|
react.useEffect(() => {
|
|
827
|
+
if (!isEditing) return;
|
|
828
|
+
const currentHref = editor.getAttributes("button").href ?? "";
|
|
829
|
+
setInputValue(currentHref === "#" ? "" : currentHref);
|
|
991
830
|
const timeoutId = setTimeout(() => {
|
|
992
831
|
inputRef.current?.focus();
|
|
993
832
|
}, 0);
|
|
994
833
|
return () => clearTimeout(timeoutId);
|
|
995
|
-
}, []);
|
|
834
|
+
}, [isEditing, editor]);
|
|
996
835
|
react.useEffect(() => {
|
|
836
|
+
if (!isEditing) return;
|
|
997
837
|
const handleKeyDown = (event) => {
|
|
998
|
-
if (event.key === "Escape")
|
|
999
|
-
if (editor.getAttributes("link").href === "#") editor.chain().unsetLink().run();
|
|
1000
|
-
setIsOpen(false);
|
|
1001
|
-
}
|
|
838
|
+
if (event.key === "Escape") setIsEditing(false);
|
|
1002
839
|
};
|
|
1003
840
|
const handleClickOutside = (event) => {
|
|
1004
841
|
if (formRef.current && !formRef.current.contains(event.target)) {
|
|
@@ -1008,7 +845,7 @@ function LinkForm({ editor, currentHref, validateUrl, onLinkApply, onLinkRemove,
|
|
|
1008
845
|
cancelable: true
|
|
1009
846
|
});
|
|
1010
847
|
form.dispatchEvent(submitEvent);
|
|
1011
|
-
|
|
848
|
+
setIsEditing(false);
|
|
1012
849
|
}
|
|
1013
850
|
};
|
|
1014
851
|
document.addEventListener("mousedown", handleClickOutside);
|
|
@@ -1017,391 +854,403 @@ function LinkForm({ editor, currentHref, validateUrl, onLinkApply, onLinkRemove,
|
|
|
1017
854
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1018
855
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
1019
856
|
};
|
|
1020
|
-
}, [
|
|
857
|
+
}, [isEditing, setIsEditing]);
|
|
858
|
+
if (!isEditing) return null;
|
|
1021
859
|
function handleSubmit(e) {
|
|
1022
860
|
e.preventDefault();
|
|
1023
861
|
const value = inputValue.trim();
|
|
1024
862
|
if (value === "") {
|
|
1025
|
-
|
|
1026
|
-
|
|
863
|
+
editor.commands.updateButton({ href: "#" });
|
|
864
|
+
setIsEditing(false);
|
|
1027
865
|
focusEditor(editor);
|
|
1028
866
|
onLinkRemove?.();
|
|
1029
867
|
return;
|
|
1030
868
|
}
|
|
1031
869
|
const finalValue = (validateUrl ?? getUrlFromString)(value);
|
|
1032
870
|
if (!finalValue) {
|
|
1033
|
-
|
|
1034
|
-
|
|
871
|
+
editor.commands.updateButton({ href: "#" });
|
|
872
|
+
setIsEditing(false);
|
|
1035
873
|
focusEditor(editor);
|
|
1036
874
|
onLinkRemove?.();
|
|
1037
875
|
return;
|
|
1038
876
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
877
|
+
editor.commands.updateButton({ href: finalValue });
|
|
878
|
+
setIsEditing(false);
|
|
1041
879
|
focusEditor(editor);
|
|
1042
880
|
onLinkApply?.(finalValue);
|
|
1043
881
|
}
|
|
1044
882
|
function handleUnlink(e) {
|
|
1045
883
|
e.stopPropagation();
|
|
1046
|
-
|
|
1047
|
-
|
|
884
|
+
editor.commands.updateButton({ href: "#" });
|
|
885
|
+
setIsEditing(false);
|
|
1048
886
|
focusEditor(editor);
|
|
1049
887
|
onLinkRemove?.();
|
|
1050
888
|
}
|
|
1051
889
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1052
890
|
ref: formRef,
|
|
1053
|
-
"data-re-
|
|
891
|
+
"data-re-btn-bm-form": "",
|
|
892
|
+
className,
|
|
1054
893
|
onMouseDown: (e) => e.stopPropagation(),
|
|
1055
894
|
onClick: (e) => e.stopPropagation(),
|
|
1056
895
|
onKeyDown: (e) => e.stopPropagation(),
|
|
1057
896
|
onSubmit: handleSubmit,
|
|
1058
|
-
children: [
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
1080
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
|
|
1081
|
-
})
|
|
1082
|
-
]
|
|
897
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
898
|
+
ref: inputRef,
|
|
899
|
+
"data-re-btn-bm-input": "",
|
|
900
|
+
value: inputValue,
|
|
901
|
+
onFocus: (e) => e.stopPropagation(),
|
|
902
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
903
|
+
placeholder: "Paste a link",
|
|
904
|
+
type: "text"
|
|
905
|
+
}), displayHref ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
906
|
+
type: "button",
|
|
907
|
+
"aria-label": "Remove link",
|
|
908
|
+
"data-re-btn-bm-unlink": "",
|
|
909
|
+
onClick: handleUnlink,
|
|
910
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
|
|
911
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
912
|
+
type: "submit",
|
|
913
|
+
"aria-label": "Apply link",
|
|
914
|
+
"data-re-btn-bm-apply": "",
|
|
915
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
916
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
|
|
917
|
+
})]
|
|
1083
918
|
});
|
|
1084
919
|
}
|
|
1085
920
|
|
|
1086
921
|
//#endregion
|
|
1087
|
-
//#region src/ui/bubble-menu/
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
922
|
+
//#region src/ui/bubble-menu/button-toolbar.tsx
|
|
923
|
+
function BubbleMenuButtonToolbar({ children, ...rest }) {
|
|
924
|
+
const { isEditing } = useBubbleMenuContext();
|
|
925
|
+
if (isEditing) return null;
|
|
926
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
927
|
+
"data-re-btn-bm-toolbar": "",
|
|
928
|
+
...rest,
|
|
929
|
+
children
|
|
930
|
+
});
|
|
1093
931
|
}
|
|
1094
|
-
|
|
932
|
+
|
|
933
|
+
//#endregion
|
|
934
|
+
//#region src/ui/bubble-menu/button-unlink.tsx
|
|
935
|
+
function BubbleMenuButtonUnlink({ className, children, onClick, onMouseDown, onLinkRemove, ...rest }) {
|
|
1095
936
|
const { editor } = useBubbleMenuContext();
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
isParagraphActive: (editor$1?.isActive("paragraph") ?? false) && !editor$1?.isActive("bulletList") && !editor$1?.isActive("orderedList"),
|
|
1107
|
-
isHeading1Active: editor$1?.isActive("heading", { level: 1 }) ?? false,
|
|
1108
|
-
isHeading2Active: editor$1?.isActive("heading", { level: 2 }) ?? false,
|
|
1109
|
-
isHeading3Active: editor$1?.isActive("heading", { level: 3 }) ?? false,
|
|
1110
|
-
isBulletListActive: editor$1?.isActive("bulletList") ?? false,
|
|
1111
|
-
isOrderedListActive: editor$1?.isActive("orderedList") ?? false,
|
|
1112
|
-
isBlockquoteActive: editor$1?.isActive("blockquote") ?? false,
|
|
1113
|
-
isCodeBlockActive: editor$1?.isActive("codeBlock") ?? false
|
|
1114
|
-
})
|
|
1115
|
-
});
|
|
1116
|
-
const allItems = react.useMemo(() => [
|
|
1117
|
-
{
|
|
1118
|
-
name: "Text",
|
|
1119
|
-
icon: TextIcon,
|
|
1120
|
-
command: () => editor.chain().focus().clearNodes().toggleNode("paragraph", "paragraph").run(),
|
|
1121
|
-
isActive: editorState?.isParagraphActive ?? false
|
|
1122
|
-
},
|
|
1123
|
-
{
|
|
1124
|
-
name: "Title",
|
|
1125
|
-
icon: Heading1,
|
|
1126
|
-
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 1 }).run(),
|
|
1127
|
-
isActive: editorState?.isHeading1Active ?? false
|
|
1128
|
-
},
|
|
1129
|
-
{
|
|
1130
|
-
name: "Subtitle",
|
|
1131
|
-
icon: Heading2,
|
|
1132
|
-
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 2 }).run(),
|
|
1133
|
-
isActive: editorState?.isHeading2Active ?? false
|
|
1134
|
-
},
|
|
1135
|
-
{
|
|
1136
|
-
name: "Heading",
|
|
1137
|
-
icon: Heading3,
|
|
1138
|
-
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 3 }).run(),
|
|
1139
|
-
isActive: editorState?.isHeading3Active ?? false
|
|
1140
|
-
},
|
|
1141
|
-
{
|
|
1142
|
-
name: "Bullet List",
|
|
1143
|
-
icon: List,
|
|
1144
|
-
command: () => editor.chain().focus().clearNodes().toggleBulletList().run(),
|
|
1145
|
-
isActive: editorState?.isBulletListActive ?? false
|
|
937
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
938
|
+
...rest,
|
|
939
|
+
type: "button",
|
|
940
|
+
"aria-label": "Remove link",
|
|
941
|
+
"data-re-btn-bm-item": "",
|
|
942
|
+
"data-item": "unlink",
|
|
943
|
+
className,
|
|
944
|
+
onMouseDown: (e) => {
|
|
945
|
+
e.preventDefault();
|
|
946
|
+
onMouseDown?.(e);
|
|
1146
947
|
},
|
|
1147
|
-
{
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
948
|
+
onClick: (e) => {
|
|
949
|
+
onClick?.(e);
|
|
950
|
+
editor.commands.updateButton({ href: "#" });
|
|
951
|
+
focusEditor(editor);
|
|
952
|
+
onLinkRemove?.();
|
|
1152
953
|
},
|
|
1153
|
-
{
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
954
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
//#endregion
|
|
959
|
+
//#region src/ui/bubble-menu/triggers.ts
|
|
960
|
+
const bubbleMenuTriggers = {
|
|
961
|
+
textSelection(hideWhenActiveNodes = [], hideWhenActiveMarks = []) {
|
|
962
|
+
return ({ editor, state }) => {
|
|
963
|
+
for (const node of hideWhenActiveNodes) {
|
|
964
|
+
if (editor.isActive(node)) return false;
|
|
965
|
+
const { $from } = state.selection;
|
|
966
|
+
for (let d = $from.depth; d > 0; d--) if ($from.node(d).type.name === node) return false;
|
|
967
|
+
}
|
|
968
|
+
for (const mark of hideWhenActiveMarks) if (editor.isActive(mark)) return false;
|
|
969
|
+
return editor.view.state.selection.content().size > 0;
|
|
970
|
+
};
|
|
971
|
+
},
|
|
972
|
+
node(name) {
|
|
973
|
+
return ({ editor }) => editor.isActive(name);
|
|
974
|
+
},
|
|
975
|
+
nodeWithoutSelection(name) {
|
|
976
|
+
return ({ editor }) => editor.isActive(name) && editor.view.state.selection.content().size === 0;
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
//#endregion
|
|
981
|
+
//#region src/ui/bubble-menu/root.tsx
|
|
982
|
+
const defaultPluginKey = new _tiptap_pm_state.PluginKey("bubbleMenu");
|
|
983
|
+
function BubbleMenuRoot({ shouldShow, pluginKey: pluginKey$1 = defaultPluginKey, hideWhenActiveNodes = [], hideWhenActiveMarks = [], placement = "bottom", offset: offset$1 = 8, onHide, className, children, ...rest }) {
|
|
984
|
+
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
985
|
+
const [isEditing, setIsEditing] = react.useState(false);
|
|
986
|
+
const resolvedShouldShow = shouldShow ?? bubbleMenuTriggers.textSelection(hideWhenActiveNodes, hideWhenActiveMarks);
|
|
987
|
+
if (!editor) return null;
|
|
988
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
|
|
989
|
+
editor,
|
|
990
|
+
pluginKey: pluginKey$1,
|
|
991
|
+
"data-re-bubble-menu": "",
|
|
992
|
+
shouldShow: resolvedShouldShow,
|
|
993
|
+
options: {
|
|
994
|
+
placement,
|
|
995
|
+
offset: offset$1,
|
|
996
|
+
onHide: () => {
|
|
997
|
+
setIsEditing(false);
|
|
998
|
+
onHide?.();
|
|
999
|
+
}
|
|
1158
1000
|
},
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
const contextValue = react.useMemo(() => ({
|
|
1169
|
-
items,
|
|
1170
|
-
activeItem,
|
|
1171
|
-
isOpen,
|
|
1172
|
-
setIsOpen
|
|
1173
|
-
}), [
|
|
1174
|
-
items,
|
|
1175
|
-
activeItem,
|
|
1176
|
-
isOpen,
|
|
1177
|
-
setIsOpen
|
|
1178
|
-
]);
|
|
1179
|
-
if (!editorState || items.length === 0) return null;
|
|
1180
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorContext.Provider, {
|
|
1181
|
-
value: contextValue,
|
|
1182
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Root, {
|
|
1183
|
-
open: isOpen,
|
|
1184
|
-
onOpenChange: setIsOpen,
|
|
1185
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1186
|
-
"data-re-node-selector": "",
|
|
1187
|
-
...isOpen ? { "data-open": "" } : {},
|
|
1188
|
-
className,
|
|
1189
|
-
children
|
|
1190
|
-
})
|
|
1001
|
+
className,
|
|
1002
|
+
...rest,
|
|
1003
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuContext.Provider, {
|
|
1004
|
+
value: {
|
|
1005
|
+
editor,
|
|
1006
|
+
isEditing,
|
|
1007
|
+
setIsEditing
|
|
1008
|
+
},
|
|
1009
|
+
children
|
|
1191
1010
|
})
|
|
1192
1011
|
});
|
|
1193
1012
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1013
|
+
|
|
1014
|
+
//#endregion
|
|
1015
|
+
//#region src/ui/bubble-menu/button-default.tsx
|
|
1016
|
+
const buttonPluginKey = new _tiptap_pm_state.PluginKey("buttonBubbleMenu");
|
|
1017
|
+
function BubbleMenuButtonDefaultInner({ validateUrl, onLinkApply, onLinkRemove }) {
|
|
1018
|
+
const { editor } = useBubbleMenuContext();
|
|
1019
|
+
const buttonHref = (0, _tiptap_react.useEditorState)({
|
|
1020
|
+
editor,
|
|
1021
|
+
selector: ({ editor: e }) => e?.getAttributes("button").href ?? ""
|
|
1201
1022
|
});
|
|
1023
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuButtonToolbar, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuButtonEditLink, {}), (buttonHref ?? "") !== "" && buttonHref !== "#" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuButtonUnlink, { onLinkRemove })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuButtonForm, {
|
|
1024
|
+
validateUrl,
|
|
1025
|
+
onLinkApply,
|
|
1026
|
+
onLinkRemove
|
|
1027
|
+
})] });
|
|
1202
1028
|
}
|
|
1203
|
-
function
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1029
|
+
function BubbleMenuButtonDefault({ placement = "top", offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove, ...rest }) {
|
|
1030
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuRoot, {
|
|
1031
|
+
shouldShow: bubbleMenuTriggers.node("button"),
|
|
1032
|
+
pluginKey: buttonPluginKey,
|
|
1033
|
+
placement,
|
|
1034
|
+
offset: offset$1,
|
|
1035
|
+
onHide,
|
|
1208
1036
|
className,
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
...item.isActive ? { "data-active": "" } : {},
|
|
1215
|
-
onClick: () => {
|
|
1216
|
-
item.command();
|
|
1217
|
-
setIsOpen(false);
|
|
1218
|
-
},
|
|
1219
|
-
children: [
|
|
1220
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {}),
|
|
1221
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: item.name }),
|
|
1222
|
-
item.isActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
|
|
1223
|
-
]
|
|
1224
|
-
}, item.name);
|
|
1037
|
+
...rest,
|
|
1038
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuButtonDefaultInner, {
|
|
1039
|
+
validateUrl,
|
|
1040
|
+
onLinkApply,
|
|
1041
|
+
onLinkRemove
|
|
1225
1042
|
})
|
|
1226
1043
|
});
|
|
1227
1044
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1045
|
+
|
|
1046
|
+
//#endregion
|
|
1047
|
+
//#region src/ui/bubble-menu/item.tsx
|
|
1048
|
+
function BubbleMenuItem({ name, isActive, onCommand, className, children, ...rest }) {
|
|
1049
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1050
|
+
type: "button",
|
|
1051
|
+
"aria-label": name,
|
|
1052
|
+
"aria-pressed": isActive,
|
|
1053
|
+
className,
|
|
1054
|
+
"data-re-bubble-menu-item": "",
|
|
1055
|
+
"data-item": name,
|
|
1056
|
+
...isActive ? { "data-active": "" } : {},
|
|
1057
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
1058
|
+
onClick: onCommand,
|
|
1059
|
+
...rest,
|
|
1060
|
+
children
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
//#endregion
|
|
1065
|
+
//#region src/ui/bubble-menu/align-center.tsx
|
|
1066
|
+
function BubbleMenuAlignCenter({ className, children }) {
|
|
1067
|
+
const { editor } = useBubbleMenuContext();
|
|
1068
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
1069
|
+
name: "align-center",
|
|
1070
|
+
isActive: (0, _tiptap_react.useEditorState)({
|
|
1071
|
+
editor,
|
|
1072
|
+
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "center" }) ?? false
|
|
1073
|
+
}),
|
|
1074
|
+
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "center"),
|
|
1075
|
+
className,
|
|
1076
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignCenterIcon, {})
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
//#endregion
|
|
1081
|
+
//#region src/ui/bubble-menu/align-left.tsx
|
|
1082
|
+
function BubbleMenuAlignLeft({ className, children }) {
|
|
1083
|
+
const { editor } = useBubbleMenuContext();
|
|
1084
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
1085
|
+
name: "align-left",
|
|
1086
|
+
isActive: (0, _tiptap_react.useEditorState)({
|
|
1087
|
+
editor,
|
|
1088
|
+
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "left" }) ?? false
|
|
1089
|
+
}),
|
|
1090
|
+
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "left"),
|
|
1233
1091
|
className,
|
|
1234
|
-
children:
|
|
1092
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignLeftIcon, {})
|
|
1235
1093
|
});
|
|
1236
1094
|
}
|
|
1237
1095
|
|
|
1238
1096
|
//#endregion
|
|
1239
|
-
//#region src/ui/bubble-menu/
|
|
1240
|
-
function
|
|
1241
|
-
const { editor } = (
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
if (editor$1.isActive(node)) return false;
|
|
1250
|
-
const { $from } = state.selection;
|
|
1251
|
-
for (let d = $from.depth; d > 0; d--) if ($from.node(d).type.name === node) return false;
|
|
1252
|
-
}
|
|
1253
|
-
for (const mark of excludeMarks) if (editor$1.isActive(mark)) return false;
|
|
1254
|
-
if (view.dom.classList.contains("dragging")) return false;
|
|
1255
|
-
return editor$1.view.state.selection.content().size > 0;
|
|
1256
|
-
},
|
|
1257
|
-
options: {
|
|
1258
|
-
placement,
|
|
1259
|
-
offset: offset$1,
|
|
1260
|
-
onHide
|
|
1261
|
-
},
|
|
1097
|
+
//#region src/ui/bubble-menu/align-right.tsx
|
|
1098
|
+
function BubbleMenuAlignRight({ className, children }) {
|
|
1099
|
+
const { editor } = useBubbleMenuContext();
|
|
1100
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
1101
|
+
name: "align-right",
|
|
1102
|
+
isActive: (0, _tiptap_react.useEditorState)({
|
|
1103
|
+
editor,
|
|
1104
|
+
selector: ({ editor: editor$1 }) => editor$1?.isActive({ alignment: "right" }) ?? false
|
|
1105
|
+
}),
|
|
1106
|
+
onCommand: () => require_set_text_alignment.setTextAlignment(editor, "right"),
|
|
1262
1107
|
className,
|
|
1263
|
-
|
|
1264
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuContext.Provider, {
|
|
1265
|
-
value: { editor },
|
|
1266
|
-
children
|
|
1267
|
-
})
|
|
1108
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlignRightIcon, {})
|
|
1268
1109
|
});
|
|
1269
1110
|
}
|
|
1270
1111
|
|
|
1271
1112
|
//#endregion
|
|
1272
|
-
//#region src/ui/bubble-menu/
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
})
|
|
1113
|
+
//#region src/ui/bubble-menu/create-mark-bubble-item.tsx
|
|
1114
|
+
function createMarkBubbleItem(config) {
|
|
1115
|
+
function MarkBubbleItem({ className, children }) {
|
|
1116
|
+
const { editor } = useBubbleMenuContext();
|
|
1117
|
+
const isActive = (0, _tiptap_react.useEditorState)({
|
|
1118
|
+
editor,
|
|
1119
|
+
selector: ({ editor: editor$1 }) => {
|
|
1120
|
+
if (config.activeParams) return editor$1?.isActive(config.activeName, config.activeParams) ?? false;
|
|
1121
|
+
return editor$1?.isActive(config.activeName) ?? false;
|
|
1122
|
+
}
|
|
1123
|
+
});
|
|
1124
|
+
const handleCommand = () => {
|
|
1125
|
+
const chain = editor.chain().focus();
|
|
1126
|
+
const method = chain[config.command];
|
|
1127
|
+
if (method) method.call(chain).run();
|
|
1128
|
+
};
|
|
1129
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItem, {
|
|
1130
|
+
name: config.name,
|
|
1131
|
+
isActive,
|
|
1132
|
+
onCommand: handleCommand,
|
|
1133
|
+
className,
|
|
1134
|
+
children: children ?? config.icon
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
MarkBubbleItem.displayName = `BubbleMenu${config.name.charAt(0).toUpperCase() + config.name.slice(1)}`;
|
|
1138
|
+
return MarkBubbleItem;
|
|
1139
|
+
}
|
|
1279
1140
|
|
|
1280
1141
|
//#endregion
|
|
1281
|
-
//#region src/ui/bubble-menu/
|
|
1282
|
-
const
|
|
1283
|
-
name: "
|
|
1284
|
-
activeName: "
|
|
1285
|
-
command: "
|
|
1286
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1142
|
+
//#region src/ui/bubble-menu/bold.tsx
|
|
1143
|
+
const BubbleMenuBold = createMarkBubbleItem({
|
|
1144
|
+
name: "bold",
|
|
1145
|
+
activeName: "bold",
|
|
1146
|
+
command: "toggleBold",
|
|
1147
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoldIcon, {})
|
|
1287
1148
|
});
|
|
1288
1149
|
|
|
1289
1150
|
//#endregion
|
|
1290
|
-
//#region src/ui/bubble-menu/
|
|
1291
|
-
const
|
|
1292
|
-
name: "
|
|
1293
|
-
activeName: "
|
|
1294
|
-
command: "
|
|
1295
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1151
|
+
//#region src/ui/bubble-menu/code.tsx
|
|
1152
|
+
const BubbleMenuCode = createMarkBubbleItem({
|
|
1153
|
+
name: "code",
|
|
1154
|
+
activeName: "code",
|
|
1155
|
+
command: "toggleCode",
|
|
1156
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeIcon, {})
|
|
1296
1157
|
});
|
|
1297
1158
|
|
|
1298
1159
|
//#endregion
|
|
1299
|
-
//#region src/ui/bubble-menu/
|
|
1300
|
-
function
|
|
1301
|
-
|
|
1302
|
-
const [isLinkSelectorOpen, setIsLinkSelectorOpen] = react.useState(false);
|
|
1303
|
-
const has = (item) => !excludeItems.includes(item);
|
|
1304
|
-
const handleNodeSelectorOpenChange = react.useCallback((open) => {
|
|
1305
|
-
setIsNodeSelectorOpen(open);
|
|
1306
|
-
if (open) setIsLinkSelectorOpen(false);
|
|
1307
|
-
}, []);
|
|
1308
|
-
const handleLinkSelectorOpenChange = react.useCallback((open) => {
|
|
1309
|
-
setIsLinkSelectorOpen(open);
|
|
1310
|
-
if (open) setIsNodeSelectorOpen(false);
|
|
1311
|
-
}, []);
|
|
1312
|
-
const handleHide = react.useCallback(() => {
|
|
1313
|
-
setIsNodeSelectorOpen(false);
|
|
1314
|
-
setIsLinkSelectorOpen(false);
|
|
1315
|
-
onHide?.();
|
|
1316
|
-
}, [onHide]);
|
|
1317
|
-
const hasFormattingItems = has("bold") || has("italic") || has("underline") || has("strike") || has("code") || has("uppercase");
|
|
1318
|
-
const hasAlignmentItems = has("align-left") || has("align-center") || has("align-right");
|
|
1319
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuRoot, {
|
|
1320
|
-
excludeNodes,
|
|
1321
|
-
excludeMarks,
|
|
1322
|
-
placement,
|
|
1323
|
-
offset: offset$1,
|
|
1324
|
-
onHide: handleHide,
|
|
1160
|
+
//#region src/ui/bubble-menu/group.tsx
|
|
1161
|
+
function BubbleMenuItemGroup({ className, children }) {
|
|
1162
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("fieldset", {
|
|
1325
1163
|
className,
|
|
1326
|
-
|
|
1327
|
-
children
|
|
1328
|
-
has("node-selector") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuNodeSelector, {
|
|
1329
|
-
open: isNodeSelectorOpen,
|
|
1330
|
-
onOpenChange: handleNodeSelectorOpenChange
|
|
1331
|
-
}),
|
|
1332
|
-
has("link-selector") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkSelector, {
|
|
1333
|
-
open: isLinkSelectorOpen,
|
|
1334
|
-
onOpenChange: handleLinkSelectorOpenChange
|
|
1335
|
-
}),
|
|
1336
|
-
hasFormattingItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuItemGroup, { children: [
|
|
1337
|
-
has("bold") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuBold, {}),
|
|
1338
|
-
has("italic") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItalic, {}),
|
|
1339
|
-
has("underline") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuUnderline, {}),
|
|
1340
|
-
has("strike") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuStrike, {}),
|
|
1341
|
-
has("code") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuCode, {}),
|
|
1342
|
-
has("uppercase") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuUppercase, {})
|
|
1343
|
-
] }),
|
|
1344
|
-
hasAlignmentItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuItemGroup, { children: [
|
|
1345
|
-
has("align-left") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignLeft, {}),
|
|
1346
|
-
has("align-center") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignCenter, {}),
|
|
1347
|
-
has("align-right") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignRight, {})
|
|
1348
|
-
] })
|
|
1349
|
-
]
|
|
1164
|
+
"data-re-bubble-menu-group": "",
|
|
1165
|
+
children
|
|
1350
1166
|
});
|
|
1351
1167
|
}
|
|
1352
1168
|
|
|
1353
1169
|
//#endregion
|
|
1354
|
-
//#region src/ui/
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
}
|
|
1170
|
+
//#region src/ui/bubble-menu/italic.tsx
|
|
1171
|
+
const BubbleMenuItalic = createMarkBubbleItem({
|
|
1172
|
+
name: "italic",
|
|
1173
|
+
activeName: "italic",
|
|
1174
|
+
command: "toggleItalic",
|
|
1175
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItalicIcon, {})
|
|
1176
|
+
});
|
|
1361
1177
|
|
|
1362
1178
|
//#endregion
|
|
1363
|
-
//#region src/ui/
|
|
1364
|
-
function
|
|
1365
|
-
const {
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1179
|
+
//#region src/ui/bubble-menu/link-selector.tsx
|
|
1180
|
+
function BubbleMenuLinkSelector({ className, showToggle = true, validateUrl, onLinkApply, onLinkRemove, children, open: controlledOpen, onOpenChange }) {
|
|
1181
|
+
const { editor } = useBubbleMenuContext();
|
|
1182
|
+
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
|
|
1183
|
+
const isControlled = controlledOpen !== void 0;
|
|
1184
|
+
const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
|
|
1185
|
+
const setIsOpen = react.useCallback((value) => {
|
|
1186
|
+
if (!isControlled) setUncontrolledOpen(value);
|
|
1187
|
+
onOpenChange?.(value);
|
|
1188
|
+
}, [isControlled, onOpenChange]);
|
|
1189
|
+
const editorState = (0, _tiptap_react.useEditorState)({
|
|
1190
|
+
editor,
|
|
1191
|
+
selector: ({ editor: editor$1 }) => ({
|
|
1192
|
+
isLinkActive: editor$1?.isActive("link") ?? false,
|
|
1193
|
+
hasLink: Boolean(editor$1?.getAttributes("link").href),
|
|
1194
|
+
currentHref: editor$1?.getAttributes("link").href || ""
|
|
1195
|
+
})
|
|
1196
|
+
});
|
|
1197
|
+
const setIsOpenRef = react.useRef(setIsOpen);
|
|
1198
|
+
setIsOpenRef.current = setIsOpen;
|
|
1199
|
+
react.useEffect(() => {
|
|
1200
|
+
const subscription = require_event_bus.editorEventBus.on("bubble-menu:add-link", () => {
|
|
1201
|
+
setIsOpenRef.current(true);
|
|
1202
|
+
});
|
|
1203
|
+
return () => {
|
|
1204
|
+
setIsOpenRef.current(false);
|
|
1205
|
+
subscription.unsubscribe();
|
|
1206
|
+
};
|
|
1207
|
+
}, []);
|
|
1208
|
+
if (!editorState) return null;
|
|
1209
|
+
const handleOpenLink = () => {
|
|
1210
|
+
setIsOpen(!isOpen);
|
|
1211
|
+
};
|
|
1212
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1213
|
+
"data-re-link-selector": "",
|
|
1214
|
+
...isOpen ? { "data-open": "" } : {},
|
|
1215
|
+
...editorState.hasLink ? { "data-has-link": "" } : {},
|
|
1372
1216
|
className,
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1217
|
+
children: [showToggle && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1218
|
+
type: "button",
|
|
1219
|
+
"aria-expanded": isOpen,
|
|
1220
|
+
"aria-haspopup": "true",
|
|
1221
|
+
"aria-label": "Add link",
|
|
1222
|
+
"aria-pressed": editorState.isLinkActive && editorState.hasLink,
|
|
1223
|
+
"data-re-link-selector-trigger": "",
|
|
1224
|
+
onClick: handleOpenLink,
|
|
1225
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkIcon, {})
|
|
1226
|
+
}), isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkForm, {
|
|
1227
|
+
editor,
|
|
1228
|
+
currentHref: editorState.currentHref,
|
|
1229
|
+
validateUrl,
|
|
1230
|
+
onLinkApply,
|
|
1231
|
+
onLinkRemove,
|
|
1232
|
+
setIsOpen,
|
|
1233
|
+
children
|
|
1234
|
+
})]
|
|
1382
1235
|
});
|
|
1383
1236
|
}
|
|
1384
|
-
|
|
1385
|
-
//#endregion
|
|
1386
|
-
//#region src/ui/button-bubble-menu/form.tsx
|
|
1387
|
-
function ButtonBubbleMenuForm({ className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
1388
|
-
const { editor, buttonHref, isEditing, setIsEditing } = useButtonBubbleMenuContext();
|
|
1237
|
+
function LinkForm({ editor, currentHref, validateUrl, onLinkApply, onLinkRemove, setIsOpen, children }) {
|
|
1389
1238
|
const inputRef = react.useRef(null);
|
|
1390
1239
|
const formRef = react.useRef(null);
|
|
1391
|
-
const displayHref =
|
|
1240
|
+
const displayHref = currentHref === "#" ? "" : currentHref;
|
|
1392
1241
|
const [inputValue, setInputValue] = react.useState(displayHref);
|
|
1393
1242
|
react.useEffect(() => {
|
|
1394
|
-
if (!isEditing) return;
|
|
1395
|
-
setInputValue(displayHref);
|
|
1396
1243
|
const timeoutId = setTimeout(() => {
|
|
1397
1244
|
inputRef.current?.focus();
|
|
1398
1245
|
}, 0);
|
|
1399
1246
|
return () => clearTimeout(timeoutId);
|
|
1400
|
-
}, [
|
|
1247
|
+
}, []);
|
|
1401
1248
|
react.useEffect(() => {
|
|
1402
|
-
if (!isEditing) return;
|
|
1403
1249
|
const handleKeyDown = (event) => {
|
|
1404
|
-
if (event.key === "Escape")
|
|
1250
|
+
if (event.key === "Escape") {
|
|
1251
|
+
if (editor.getAttributes("link").href === "#") editor.chain().unsetLink().run();
|
|
1252
|
+
setIsOpen(false);
|
|
1253
|
+
}
|
|
1405
1254
|
};
|
|
1406
1255
|
const handleClickOutside = (event) => {
|
|
1407
1256
|
if (formRef.current && !formRef.current.contains(event.target)) {
|
|
@@ -1411,7 +1260,7 @@ function ButtonBubbleMenuForm({ className, validateUrl, onLinkApply, onLinkRemov
|
|
|
1411
1260
|
cancelable: true
|
|
1412
1261
|
});
|
|
1413
1262
|
form.dispatchEvent(submitEvent);
|
|
1414
|
-
|
|
1263
|
+
setIsOpen(false);
|
|
1415
1264
|
}
|
|
1416
1265
|
};
|
|
1417
1266
|
document.addEventListener("mousedown", handleClickOutside);
|
|
@@ -1420,182 +1269,312 @@ function ButtonBubbleMenuForm({ className, validateUrl, onLinkApply, onLinkRemov
|
|
|
1420
1269
|
window.removeEventListener("keydown", handleKeyDown);
|
|
1421
1270
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
1422
1271
|
};
|
|
1423
|
-
}, [
|
|
1424
|
-
if (!isEditing) return null;
|
|
1272
|
+
}, [editor, setIsOpen]);
|
|
1425
1273
|
function handleSubmit(e) {
|
|
1426
1274
|
e.preventDefault();
|
|
1427
1275
|
const value = inputValue.trim();
|
|
1428
1276
|
if (value === "") {
|
|
1429
|
-
editor
|
|
1430
|
-
|
|
1277
|
+
setLinkHref(editor, "");
|
|
1278
|
+
setIsOpen(false);
|
|
1431
1279
|
focusEditor(editor);
|
|
1432
1280
|
onLinkRemove?.();
|
|
1433
1281
|
return;
|
|
1434
1282
|
}
|
|
1435
1283
|
const finalValue = (validateUrl ?? getUrlFromString)(value);
|
|
1436
1284
|
if (!finalValue) {
|
|
1437
|
-
editor
|
|
1438
|
-
|
|
1285
|
+
setLinkHref(editor, "");
|
|
1286
|
+
setIsOpen(false);
|
|
1439
1287
|
focusEditor(editor);
|
|
1440
1288
|
onLinkRemove?.();
|
|
1441
1289
|
return;
|
|
1442
1290
|
}
|
|
1443
|
-
editor
|
|
1444
|
-
|
|
1291
|
+
setLinkHref(editor, finalValue);
|
|
1292
|
+
setIsOpen(false);
|
|
1445
1293
|
focusEditor(editor);
|
|
1446
1294
|
onLinkApply?.(finalValue);
|
|
1447
1295
|
}
|
|
1448
1296
|
function handleUnlink(e) {
|
|
1449
1297
|
e.stopPropagation();
|
|
1450
|
-
editor
|
|
1451
|
-
|
|
1298
|
+
setLinkHref(editor, "");
|
|
1299
|
+
setIsOpen(false);
|
|
1452
1300
|
focusEditor(editor);
|
|
1453
1301
|
onLinkRemove?.();
|
|
1454
1302
|
}
|
|
1455
1303
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1456
1304
|
ref: formRef,
|
|
1457
|
-
"data-re-
|
|
1458
|
-
className,
|
|
1305
|
+
"data-re-link-selector-form": "",
|
|
1459
1306
|
onMouseDown: (e) => e.stopPropagation(),
|
|
1460
1307
|
onClick: (e) => e.stopPropagation(),
|
|
1461
1308
|
onKeyDown: (e) => e.stopPropagation(),
|
|
1462
1309
|
onSubmit: handleSubmit,
|
|
1463
|
-
children: [
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1310
|
+
children: [
|
|
1311
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1312
|
+
ref: inputRef,
|
|
1313
|
+
"data-re-link-selector-input": "",
|
|
1314
|
+
value: inputValue,
|
|
1315
|
+
onFocus: (e) => e.stopPropagation(),
|
|
1316
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
1317
|
+
placeholder: "Paste a link",
|
|
1318
|
+
type: "text"
|
|
1319
|
+
}),
|
|
1320
|
+
children,
|
|
1321
|
+
displayHref ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1322
|
+
type: "button",
|
|
1323
|
+
"aria-label": "Remove link",
|
|
1324
|
+
"data-re-link-selector-unlink": "",
|
|
1325
|
+
onClick: handleUnlink,
|
|
1326
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
|
|
1327
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1328
|
+
type: "submit",
|
|
1329
|
+
"aria-label": "Apply link",
|
|
1330
|
+
"data-re-link-selector-apply": "",
|
|
1331
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1332
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
|
|
1333
|
+
})
|
|
1334
|
+
]
|
|
1484
1335
|
});
|
|
1485
1336
|
}
|
|
1486
1337
|
|
|
1487
1338
|
//#endregion
|
|
1488
|
-
//#region src/ui/
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1339
|
+
//#region src/ui/bubble-menu/node-selector.tsx
|
|
1340
|
+
const NodeSelectorContext = react.createContext(null);
|
|
1341
|
+
function useNodeSelectorContext() {
|
|
1342
|
+
const context = react.useContext(NodeSelectorContext);
|
|
1343
|
+
if (!context) throw new Error("NodeSelector compound components must be used within <NodeSelector.Root>");
|
|
1344
|
+
return context;
|
|
1345
|
+
}
|
|
1346
|
+
function NodeSelectorRoot({ omit = [], open: controlledOpen, onOpenChange, className, children }) {
|
|
1347
|
+
const { editor } = useBubbleMenuContext();
|
|
1348
|
+
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
|
|
1349
|
+
const isControlled = controlledOpen !== void 0;
|
|
1350
|
+
const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
|
|
1351
|
+
const setIsOpen = react.useCallback((value) => {
|
|
1352
|
+
if (!isControlled) setUncontrolledOpen(value);
|
|
1353
|
+
onOpenChange?.(value);
|
|
1354
|
+
}, [isControlled, onOpenChange]);
|
|
1355
|
+
const editorState = (0, _tiptap_react.useEditorState)({
|
|
1493
1356
|
editor,
|
|
1494
|
-
selector: ({ editor:
|
|
1357
|
+
selector: ({ editor: editor$1 }) => ({
|
|
1358
|
+
isParagraphActive: (editor$1?.isActive("paragraph") ?? false) && !editor$1?.isActive("bulletList") && !editor$1?.isActive("orderedList"),
|
|
1359
|
+
isHeading1Active: editor$1?.isActive("heading", { level: 1 }) ?? false,
|
|
1360
|
+
isHeading2Active: editor$1?.isActive("heading", { level: 2 }) ?? false,
|
|
1361
|
+
isHeading3Active: editor$1?.isActive("heading", { level: 3 }) ?? false,
|
|
1362
|
+
isBulletListActive: editor$1?.isActive("bulletList") ?? false,
|
|
1363
|
+
isOrderedListActive: editor$1?.isActive("orderedList") ?? false,
|
|
1364
|
+
isBlockquoteActive: editor$1?.isActive("blockquote") ?? false,
|
|
1365
|
+
isCodeBlockActive: editor$1?.isActive("codeBlock") ?? false
|
|
1366
|
+
})
|
|
1495
1367
|
});
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
options: {
|
|
1503
|
-
placement,
|
|
1504
|
-
offset: offset$1,
|
|
1505
|
-
onHide: () => {
|
|
1506
|
-
setIsEditing(false);
|
|
1507
|
-
onHide?.();
|
|
1508
|
-
}
|
|
1368
|
+
const allItems = react.useMemo(() => [
|
|
1369
|
+
{
|
|
1370
|
+
name: "Text",
|
|
1371
|
+
icon: TextIcon,
|
|
1372
|
+
command: () => editor.chain().focus().clearNodes().toggleNode("paragraph", "paragraph").run(),
|
|
1373
|
+
isActive: editorState?.isParagraphActive ?? false
|
|
1509
1374
|
},
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1375
|
+
{
|
|
1376
|
+
name: "Title",
|
|
1377
|
+
icon: Heading1,
|
|
1378
|
+
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 1 }).run(),
|
|
1379
|
+
isActive: editorState?.isHeading1Active ?? false
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
name: "Subtitle",
|
|
1383
|
+
icon: Heading2,
|
|
1384
|
+
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 2 }).run(),
|
|
1385
|
+
isActive: editorState?.isHeading2Active ?? false
|
|
1386
|
+
},
|
|
1387
|
+
{
|
|
1388
|
+
name: "Heading",
|
|
1389
|
+
icon: Heading3,
|
|
1390
|
+
command: () => editor.chain().focus().clearNodes().toggleHeading({ level: 3 }).run(),
|
|
1391
|
+
isActive: editorState?.isHeading3Active ?? false
|
|
1392
|
+
},
|
|
1393
|
+
{
|
|
1394
|
+
name: "Bullet List",
|
|
1395
|
+
icon: List,
|
|
1396
|
+
command: () => editor.chain().focus().clearNodes().toggleBulletList().run(),
|
|
1397
|
+
isActive: editorState?.isBulletListActive ?? false
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
name: "Numbered List",
|
|
1401
|
+
icon: ListOrdered,
|
|
1402
|
+
command: () => editor.chain().focus().clearNodes().toggleOrderedList().run(),
|
|
1403
|
+
isActive: editorState?.isOrderedListActive ?? false
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
name: "Quote",
|
|
1407
|
+
icon: TextQuote,
|
|
1408
|
+
command: () => editor.chain().focus().clearNodes().toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
|
|
1409
|
+
isActive: editorState?.isBlockquoteActive ?? false
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
name: "Code",
|
|
1413
|
+
icon: Code,
|
|
1414
|
+
command: () => editor.chain().focus().clearNodes().toggleCodeBlock().run(),
|
|
1415
|
+
isActive: editorState?.isCodeBlockActive ?? false
|
|
1416
|
+
}
|
|
1417
|
+
], [editor, editorState]);
|
|
1418
|
+
const items = react.useMemo(() => allItems.filter((item) => !omit.includes(item.name)), [allItems, omit]);
|
|
1419
|
+
const activeItem = react.useMemo(() => items.find((item) => item.isActive) ?? { name: "Multiple" }, [items]);
|
|
1420
|
+
const contextValue = react.useMemo(() => ({
|
|
1421
|
+
items,
|
|
1422
|
+
activeItem,
|
|
1423
|
+
isOpen,
|
|
1424
|
+
setIsOpen
|
|
1425
|
+
}), [
|
|
1426
|
+
items,
|
|
1427
|
+
activeItem,
|
|
1428
|
+
isOpen,
|
|
1429
|
+
setIsOpen
|
|
1430
|
+
]);
|
|
1431
|
+
if (!editorState || items.length === 0) return null;
|
|
1432
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorContext.Provider, {
|
|
1433
|
+
value: contextValue,
|
|
1434
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Root, {
|
|
1435
|
+
open: isOpen,
|
|
1436
|
+
onOpenChange: setIsOpen,
|
|
1437
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1438
|
+
"data-re-node-selector": "",
|
|
1439
|
+
...isOpen ? { "data-open": "" } : {},
|
|
1440
|
+
className,
|
|
1441
|
+
children
|
|
1442
|
+
})
|
|
1520
1443
|
})
|
|
1521
1444
|
});
|
|
1522
1445
|
}
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
"data-re-btn-bm-toolbar": "",
|
|
1531
|
-
...rest,
|
|
1532
|
-
children
|
|
1446
|
+
function NodeSelectorTrigger({ className, children }) {
|
|
1447
|
+
const { activeItem, isOpen, setIsOpen } = useNodeSelectorContext();
|
|
1448
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Trigger, {
|
|
1449
|
+
"data-re-node-selector-trigger": "",
|
|
1450
|
+
className,
|
|
1451
|
+
onClick: () => setIsOpen(!isOpen),
|
|
1452
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: activeItem.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDown, {})] })
|
|
1533
1453
|
});
|
|
1534
1454
|
}
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1541
|
-
...rest,
|
|
1542
|
-
type: "button",
|
|
1543
|
-
"aria-label": "Remove link",
|
|
1544
|
-
"data-re-btn-bm-item": "",
|
|
1545
|
-
"data-item": "unlink",
|
|
1455
|
+
function NodeSelectorContent({ className, align = "start", children }) {
|
|
1456
|
+
const { items, setIsOpen } = useNodeSelectorContext();
|
|
1457
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Content, {
|
|
1458
|
+
align,
|
|
1459
|
+
"data-re-node-selector-content": "",
|
|
1546
1460
|
className,
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1461
|
+
children: children ? children(items, () => setIsOpen(false)) : items.map((item) => {
|
|
1462
|
+
const Icon = item.icon;
|
|
1463
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1464
|
+
type: "button",
|
|
1465
|
+
"data-re-node-selector-item": "",
|
|
1466
|
+
...item.isActive ? { "data-active": "" } : {},
|
|
1467
|
+
onClick: () => {
|
|
1468
|
+
item.command();
|
|
1469
|
+
setIsOpen(false);
|
|
1470
|
+
},
|
|
1471
|
+
children: [
|
|
1472
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {}),
|
|
1473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: item.name }),
|
|
1474
|
+
item.isActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
|
|
1475
|
+
]
|
|
1476
|
+
}, item.name);
|
|
1477
|
+
})
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1480
|
+
function BubbleMenuNodeSelector({ omit = [], className, triggerContent, open, onOpenChange }) {
|
|
1481
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(NodeSelectorRoot, {
|
|
1482
|
+
omit,
|
|
1483
|
+
open,
|
|
1484
|
+
onOpenChange,
|
|
1485
|
+
className,
|
|
1486
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorTrigger, { children: triggerContent }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorContent, {})]
|
|
1558
1487
|
});
|
|
1559
1488
|
}
|
|
1560
1489
|
|
|
1561
1490
|
//#endregion
|
|
1562
|
-
//#region src/ui/
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1491
|
+
//#region src/ui/bubble-menu/strike.tsx
|
|
1492
|
+
const BubbleMenuStrike = createMarkBubbleItem({
|
|
1493
|
+
name: "strike",
|
|
1494
|
+
activeName: "strike",
|
|
1495
|
+
command: "toggleStrike",
|
|
1496
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StrikethroughIcon, {})
|
|
1497
|
+
});
|
|
1498
|
+
|
|
1499
|
+
//#endregion
|
|
1500
|
+
//#region src/ui/bubble-menu/underline.tsx
|
|
1501
|
+
const BubbleMenuUnderline = createMarkBubbleItem({
|
|
1502
|
+
name: "underline",
|
|
1503
|
+
activeName: "underline",
|
|
1504
|
+
command: "toggleUnderline",
|
|
1505
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnderlineIcon, {})
|
|
1506
|
+
});
|
|
1507
|
+
|
|
1508
|
+
//#endregion
|
|
1509
|
+
//#region src/ui/bubble-menu/uppercase.tsx
|
|
1510
|
+
const BubbleMenuUppercase = createMarkBubbleItem({
|
|
1511
|
+
name: "uppercase",
|
|
1512
|
+
activeName: "uppercase",
|
|
1513
|
+
command: "toggleUppercase",
|
|
1514
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CaseUpperIcon, {})
|
|
1515
|
+
});
|
|
1516
|
+
|
|
1517
|
+
//#endregion
|
|
1518
|
+
//#region src/ui/bubble-menu/default.tsx
|
|
1519
|
+
const textPluginKey = new _tiptap_pm_state.PluginKey("textBubbleMenu");
|
|
1520
|
+
function BubbleMenuDefault({ excludeItems = [], hideWhenActiveNodes, hideWhenActiveMarks, placement, offset: offset$1, onHide, className, ...rest }) {
|
|
1521
|
+
const [isNodeSelectorOpen, setIsNodeSelectorOpen] = react.useState(false);
|
|
1522
|
+
const [isLinkSelectorOpen, setIsLinkSelectorOpen] = react.useState(false);
|
|
1523
|
+
const has = (item) => !excludeItems.includes(item);
|
|
1524
|
+
const handleNodeSelectorOpenChange = react.useCallback((open) => {
|
|
1525
|
+
setIsNodeSelectorOpen(open);
|
|
1526
|
+
if (open) setIsLinkSelectorOpen(false);
|
|
1527
|
+
}, []);
|
|
1528
|
+
const handleLinkSelectorOpenChange = react.useCallback((open) => {
|
|
1529
|
+
setIsLinkSelectorOpen(open);
|
|
1530
|
+
if (open) setIsNodeSelectorOpen(false);
|
|
1531
|
+
}, []);
|
|
1532
|
+
const handleHide = react.useCallback(() => {
|
|
1533
|
+
setIsNodeSelectorOpen(false);
|
|
1534
|
+
setIsLinkSelectorOpen(false);
|
|
1535
|
+
onHide?.();
|
|
1536
|
+
}, [onHide]);
|
|
1537
|
+
const hasFormattingItems = has("bold") || has("italic") || has("underline") || has("strike") || has("code") || has("uppercase");
|
|
1538
|
+
const hasAlignmentItems = has("align-left") || has("align-center") || has("align-right");
|
|
1539
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuRoot, {
|
|
1540
|
+
pluginKey: textPluginKey,
|
|
1541
|
+
hideWhenActiveNodes,
|
|
1542
|
+
hideWhenActiveMarks,
|
|
1573
1543
|
placement,
|
|
1574
1544
|
offset: offset$1,
|
|
1575
|
-
onHide,
|
|
1545
|
+
onHide: handleHide,
|
|
1576
1546
|
className,
|
|
1577
1547
|
...rest,
|
|
1578
|
-
children:
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1548
|
+
children: [
|
|
1549
|
+
has("node-selector") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuNodeSelector, {
|
|
1550
|
+
open: isNodeSelectorOpen,
|
|
1551
|
+
onOpenChange: handleNodeSelectorOpenChange
|
|
1552
|
+
}),
|
|
1553
|
+
has("link-selector") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkSelector, {
|
|
1554
|
+
open: isLinkSelectorOpen,
|
|
1555
|
+
onOpenChange: handleLinkSelectorOpenChange
|
|
1556
|
+
}),
|
|
1557
|
+
hasFormattingItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuItemGroup, { children: [
|
|
1558
|
+
has("bold") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuBold, {}),
|
|
1559
|
+
has("italic") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuItalic, {}),
|
|
1560
|
+
has("underline") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuUnderline, {}),
|
|
1561
|
+
has("strike") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuStrike, {}),
|
|
1562
|
+
has("code") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuCode, {}),
|
|
1563
|
+
has("uppercase") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuUppercase, {})
|
|
1564
|
+
] }),
|
|
1565
|
+
hasAlignmentItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuItemGroup, { children: [
|
|
1566
|
+
has("align-left") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignLeft, {}),
|
|
1567
|
+
has("align-center") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignCenter, {}),
|
|
1568
|
+
has("align-right") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuAlignRight, {})
|
|
1569
|
+
] })
|
|
1570
|
+
]
|
|
1583
1571
|
});
|
|
1584
1572
|
}
|
|
1585
1573
|
|
|
1586
1574
|
//#endregion
|
|
1587
|
-
//#region src/ui/
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
const context = react.useContext(ImageBubbleMenuContext);
|
|
1591
|
-
if (!context) throw new Error("ImageBubbleMenu compound components must be used within <ImageBubbleMenu.Root>");
|
|
1592
|
-
return context;
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
|
-
//#endregion
|
|
1596
|
-
//#region src/ui/image-bubble-menu/edit-link.tsx
|
|
1597
|
-
function ImageBubbleMenuEditLink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
1598
|
-
const { setIsEditing } = useImageBubbleMenuContext();
|
|
1575
|
+
//#region src/ui/bubble-menu/image-edit-link.tsx
|
|
1576
|
+
function BubbleMenuImageEditLink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
1577
|
+
const { setIsEditing } = useBubbleMenuContext();
|
|
1599
1578
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1600
1579
|
...rest,
|
|
1601
1580
|
type: "button",
|
|
@@ -1616,41 +1595,9 @@ function ImageBubbleMenuEditLink({ className, children, onClick, onMouseDown, ..
|
|
|
1616
1595
|
}
|
|
1617
1596
|
|
|
1618
1597
|
//#endregion
|
|
1619
|
-
//#region src/ui/
|
|
1620
|
-
function
|
|
1621
|
-
const {
|
|
1622
|
-
const [isEditing, setIsEditing] = react.useState(false);
|
|
1623
|
-
if (!editor) return null;
|
|
1624
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
|
|
1625
|
-
editor,
|
|
1626
|
-
pluginKey: "imageBubbleMenu",
|
|
1627
|
-
"data-re-img-bm": "",
|
|
1628
|
-
shouldShow: ({ editor: e, view }) => e.isActive("image") && !view.dom.classList.contains("dragging"),
|
|
1629
|
-
options: {
|
|
1630
|
-
placement,
|
|
1631
|
-
offset: offset$1,
|
|
1632
|
-
onHide: () => {
|
|
1633
|
-
setIsEditing(false);
|
|
1634
|
-
onHide?.();
|
|
1635
|
-
}
|
|
1636
|
-
},
|
|
1637
|
-
className,
|
|
1638
|
-
...rest,
|
|
1639
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageBubbleMenuContext.Provider, {
|
|
1640
|
-
value: {
|
|
1641
|
-
editor,
|
|
1642
|
-
isEditing,
|
|
1643
|
-
setIsEditing
|
|
1644
|
-
},
|
|
1645
|
-
children
|
|
1646
|
-
})
|
|
1647
|
-
});
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
//#endregion
|
|
1651
|
-
//#region src/ui/image-bubble-menu/toolbar.tsx
|
|
1652
|
-
function ImageBubbleMenuToolbar({ children, ...rest }) {
|
|
1653
|
-
const { isEditing } = useImageBubbleMenuContext();
|
|
1598
|
+
//#region src/ui/bubble-menu/image-toolbar.tsx
|
|
1599
|
+
function BubbleMenuImageToolbar({ children, ...rest }) {
|
|
1600
|
+
const { isEditing } = useBubbleMenuContext();
|
|
1654
1601
|
if (isEditing) return null;
|
|
1655
1602
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1656
1603
|
"data-re-img-bm-toolbar": "",
|
|
@@ -1660,32 +1607,26 @@ function ImageBubbleMenuToolbar({ children, ...rest }) {
|
|
|
1660
1607
|
}
|
|
1661
1608
|
|
|
1662
1609
|
//#endregion
|
|
1663
|
-
//#region src/ui/
|
|
1664
|
-
|
|
1610
|
+
//#region src/ui/bubble-menu/image-default.tsx
|
|
1611
|
+
const imagePluginKey = new _tiptap_pm_state.PluginKey("imageBubbleMenu");
|
|
1612
|
+
function BubbleMenuImageDefault({ excludeItems = [], placement = "top", offset: offset$1, onHide, className, ...rest }) {
|
|
1665
1613
|
const hasEditLink = !excludeItems.includes("edit-link");
|
|
1666
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1614
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuRoot, {
|
|
1615
|
+
shouldShow: bubbleMenuTriggers.node("image"),
|
|
1616
|
+
pluginKey: imagePluginKey,
|
|
1667
1617
|
placement,
|
|
1668
1618
|
offset: offset$1,
|
|
1669
1619
|
onHide,
|
|
1670
1620
|
className,
|
|
1671
1621
|
...rest,
|
|
1672
|
-
children: hasEditLink && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1622
|
+
children: hasEditLink && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuImageToolbar, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuImageEditLink, {}) })
|
|
1673
1623
|
});
|
|
1674
1624
|
}
|
|
1675
1625
|
|
|
1676
1626
|
//#endregion
|
|
1677
|
-
//#region src/ui/
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
const context = react.useContext(LinkBubbleMenuContext);
|
|
1681
|
-
if (!context) throw new Error("LinkBubbleMenu compound components must be used within <LinkBubbleMenu.Root>");
|
|
1682
|
-
return context;
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
|
-
//#endregion
|
|
1686
|
-
//#region src/ui/link-bubble-menu/edit-link.tsx
|
|
1687
|
-
function LinkBubbleMenuEditLink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
1688
|
-
const { setIsEditing } = useLinkBubbleMenuContext();
|
|
1627
|
+
//#region src/ui/bubble-menu/link-edit-link.tsx
|
|
1628
|
+
function BubbleMenuLinkEditLink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
1629
|
+
const { setIsEditing } = useBubbleMenuContext();
|
|
1689
1630
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1690
1631
|
type: "button",
|
|
1691
1632
|
"aria-label": "Edit link",
|
|
@@ -1706,12 +1647,16 @@ function LinkBubbleMenuEditLink({ className, children, onClick, onMouseDown, ...
|
|
|
1706
1647
|
}
|
|
1707
1648
|
|
|
1708
1649
|
//#endregion
|
|
1709
|
-
//#region src/ui/
|
|
1710
|
-
function
|
|
1711
|
-
const { editor,
|
|
1650
|
+
//#region src/ui/bubble-menu/link-form.tsx
|
|
1651
|
+
function BubbleMenuLinkForm({ className, validateUrl, onLinkApply, onLinkRemove, children }) {
|
|
1652
|
+
const { editor, isEditing, setIsEditing } = useBubbleMenuContext();
|
|
1712
1653
|
const inputRef = react.useRef(null);
|
|
1713
1654
|
const formRef = react.useRef(null);
|
|
1714
|
-
const
|
|
1655
|
+
const linkHref = (0, _tiptap_react.useEditorState)({
|
|
1656
|
+
editor,
|
|
1657
|
+
selector: ({ editor: e }) => e?.getAttributes("link").href ?? ""
|
|
1658
|
+
});
|
|
1659
|
+
const displayHref = (linkHref ?? "") === "#" ? "" : linkHref ?? "";
|
|
1715
1660
|
const [inputValue, setInputValue] = react.useState(displayHref);
|
|
1716
1661
|
react.useEffect(() => {
|
|
1717
1662
|
if (!isEditing) return;
|
|
@@ -1812,12 +1757,16 @@ function LinkBubbleMenuForm({ className, validateUrl, onLinkApply, onLinkRemove,
|
|
|
1812
1757
|
}
|
|
1813
1758
|
|
|
1814
1759
|
//#endregion
|
|
1815
|
-
//#region src/ui/
|
|
1816
|
-
function
|
|
1817
|
-
const {
|
|
1760
|
+
//#region src/ui/bubble-menu/link-open-link.tsx
|
|
1761
|
+
function BubbleMenuLinkOpenLink({ className, children, ...rest }) {
|
|
1762
|
+
const { editor } = useBubbleMenuContext();
|
|
1763
|
+
const linkHref = (0, _tiptap_react.useEditorState)({
|
|
1764
|
+
editor,
|
|
1765
|
+
selector: ({ editor: e }) => e?.getAttributes("link").href ?? ""
|
|
1766
|
+
});
|
|
1818
1767
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1819
1768
|
...rest,
|
|
1820
|
-
href: linkHref,
|
|
1769
|
+
href: linkHref ?? "",
|
|
1821
1770
|
target: "_blank",
|
|
1822
1771
|
rel: "noopener noreferrer",
|
|
1823
1772
|
"aria-label": "Open link",
|
|
@@ -1829,46 +1778,9 @@ function LinkBubbleMenuOpenLink({ className, children, ...rest }) {
|
|
|
1829
1778
|
}
|
|
1830
1779
|
|
|
1831
1780
|
//#endregion
|
|
1832
|
-
//#region src/ui/
|
|
1833
|
-
function
|
|
1834
|
-
const {
|
|
1835
|
-
const [isEditing, setIsEditing] = react.useState(false);
|
|
1836
|
-
const linkHref = (0, _tiptap_react.useEditorState)({
|
|
1837
|
-
editor,
|
|
1838
|
-
selector: ({ editor: e }) => e?.getAttributes("link").href ?? ""
|
|
1839
|
-
});
|
|
1840
|
-
if (!editor) return null;
|
|
1841
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
|
|
1842
|
-
editor,
|
|
1843
|
-
pluginKey: "linkBubbleMenu",
|
|
1844
|
-
"data-re-link-bm": "",
|
|
1845
|
-
shouldShow: ({ editor: e }) => e.isActive("link") && e.view.state.selection.content().size === 0,
|
|
1846
|
-
options: {
|
|
1847
|
-
placement,
|
|
1848
|
-
offset: offset$1,
|
|
1849
|
-
onHide: () => {
|
|
1850
|
-
setIsEditing(false);
|
|
1851
|
-
onHide?.();
|
|
1852
|
-
}
|
|
1853
|
-
},
|
|
1854
|
-
className,
|
|
1855
|
-
...rest,
|
|
1856
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkBubbleMenuContext.Provider, {
|
|
1857
|
-
value: {
|
|
1858
|
-
editor,
|
|
1859
|
-
linkHref: linkHref ?? "",
|
|
1860
|
-
isEditing,
|
|
1861
|
-
setIsEditing
|
|
1862
|
-
},
|
|
1863
|
-
children
|
|
1864
|
-
})
|
|
1865
|
-
});
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
//#endregion
|
|
1869
|
-
//#region src/ui/link-bubble-menu/toolbar.tsx
|
|
1870
|
-
function LinkBubbleMenuToolbar({ children, ...rest }) {
|
|
1871
|
-
const { isEditing } = useLinkBubbleMenuContext();
|
|
1781
|
+
//#region src/ui/bubble-menu/link-toolbar.tsx
|
|
1782
|
+
function BubbleMenuLinkToolbar({ children, ...rest }) {
|
|
1783
|
+
const { isEditing } = useBubbleMenuContext();
|
|
1872
1784
|
if (isEditing) return null;
|
|
1873
1785
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1874
1786
|
"data-re-link-bm-toolbar": "",
|
|
@@ -1878,9 +1790,9 @@ function LinkBubbleMenuToolbar({ children, ...rest }) {
|
|
|
1878
1790
|
}
|
|
1879
1791
|
|
|
1880
1792
|
//#endregion
|
|
1881
|
-
//#region src/ui/
|
|
1882
|
-
function
|
|
1883
|
-
const { editor } =
|
|
1793
|
+
//#region src/ui/bubble-menu/link-unlink.tsx
|
|
1794
|
+
function BubbleMenuLinkUnlink({ className, children, onClick, onMouseDown, ...rest }) {
|
|
1795
|
+
const { editor } = useBubbleMenuContext();
|
|
1884
1796
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1885
1797
|
type: "button",
|
|
1886
1798
|
"aria-label": "Remove link",
|
|
@@ -1901,21 +1813,24 @@ function LinkBubbleMenuUnlink({ className, children, onClick, onMouseDown, ...re
|
|
|
1901
1813
|
}
|
|
1902
1814
|
|
|
1903
1815
|
//#endregion
|
|
1904
|
-
//#region src/ui/
|
|
1905
|
-
|
|
1816
|
+
//#region src/ui/bubble-menu/link-default.tsx
|
|
1817
|
+
const linkPluginKey = new _tiptap_pm_state.PluginKey("linkBubbleMenu");
|
|
1818
|
+
function BubbleMenuLinkDefault({ excludeItems = [], placement = "top", offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove, ...rest }) {
|
|
1906
1819
|
const has = (item) => !excludeItems.includes(item);
|
|
1907
1820
|
const hasToolbarItems = has("edit-link") || has("open-link") || has("unlink");
|
|
1908
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1821
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuRoot, {
|
|
1822
|
+
shouldShow: bubbleMenuTriggers.nodeWithoutSelection("link"),
|
|
1823
|
+
pluginKey: linkPluginKey,
|
|
1909
1824
|
placement,
|
|
1910
1825
|
offset: offset$1,
|
|
1911
1826
|
onHide,
|
|
1912
1827
|
className,
|
|
1913
1828
|
...rest,
|
|
1914
|
-
children: [hasToolbarItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1915
|
-
has("edit-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1916
|
-
has("open-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1917
|
-
has("unlink") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1918
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1829
|
+
children: [hasToolbarItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuLinkToolbar, { children: [
|
|
1830
|
+
has("edit-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkEditLink, {}),
|
|
1831
|
+
has("open-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkOpenLink, {}),
|
|
1832
|
+
has("unlink") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkUnlink, {})
|
|
1833
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BubbleMenuLinkForm, {
|
|
1919
1834
|
validateUrl,
|
|
1920
1835
|
onLinkApply,
|
|
1921
1836
|
onLinkRemove
|
|
@@ -2459,6 +2374,36 @@ Object.defineProperty(exports, 'BubbleMenuBold', {
|
|
|
2459
2374
|
return BubbleMenuBold;
|
|
2460
2375
|
}
|
|
2461
2376
|
});
|
|
2377
|
+
Object.defineProperty(exports, 'BubbleMenuButtonDefault', {
|
|
2378
|
+
enumerable: true,
|
|
2379
|
+
get: function () {
|
|
2380
|
+
return BubbleMenuButtonDefault;
|
|
2381
|
+
}
|
|
2382
|
+
});
|
|
2383
|
+
Object.defineProperty(exports, 'BubbleMenuButtonEditLink', {
|
|
2384
|
+
enumerable: true,
|
|
2385
|
+
get: function () {
|
|
2386
|
+
return BubbleMenuButtonEditLink;
|
|
2387
|
+
}
|
|
2388
|
+
});
|
|
2389
|
+
Object.defineProperty(exports, 'BubbleMenuButtonForm', {
|
|
2390
|
+
enumerable: true,
|
|
2391
|
+
get: function () {
|
|
2392
|
+
return BubbleMenuButtonForm;
|
|
2393
|
+
}
|
|
2394
|
+
});
|
|
2395
|
+
Object.defineProperty(exports, 'BubbleMenuButtonToolbar', {
|
|
2396
|
+
enumerable: true,
|
|
2397
|
+
get: function () {
|
|
2398
|
+
return BubbleMenuButtonToolbar;
|
|
2399
|
+
}
|
|
2400
|
+
});
|
|
2401
|
+
Object.defineProperty(exports, 'BubbleMenuButtonUnlink', {
|
|
2402
|
+
enumerable: true,
|
|
2403
|
+
get: function () {
|
|
2404
|
+
return BubbleMenuButtonUnlink;
|
|
2405
|
+
}
|
|
2406
|
+
});
|
|
2462
2407
|
Object.defineProperty(exports, 'BubbleMenuCode', {
|
|
2463
2408
|
enumerable: true,
|
|
2464
2409
|
get: function () {
|
|
@@ -2471,6 +2416,24 @@ Object.defineProperty(exports, 'BubbleMenuDefault', {
|
|
|
2471
2416
|
return BubbleMenuDefault;
|
|
2472
2417
|
}
|
|
2473
2418
|
});
|
|
2419
|
+
Object.defineProperty(exports, 'BubbleMenuImageDefault', {
|
|
2420
|
+
enumerable: true,
|
|
2421
|
+
get: function () {
|
|
2422
|
+
return BubbleMenuImageDefault;
|
|
2423
|
+
}
|
|
2424
|
+
});
|
|
2425
|
+
Object.defineProperty(exports, 'BubbleMenuImageEditLink', {
|
|
2426
|
+
enumerable: true,
|
|
2427
|
+
get: function () {
|
|
2428
|
+
return BubbleMenuImageEditLink;
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
Object.defineProperty(exports, 'BubbleMenuImageToolbar', {
|
|
2432
|
+
enumerable: true,
|
|
2433
|
+
get: function () {
|
|
2434
|
+
return BubbleMenuImageToolbar;
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2474
2437
|
Object.defineProperty(exports, 'BubbleMenuItalic', {
|
|
2475
2438
|
enumerable: true,
|
|
2476
2439
|
get: function () {
|
|
@@ -2489,76 +2452,76 @@ Object.defineProperty(exports, 'BubbleMenuItemGroup', {
|
|
|
2489
2452
|
return BubbleMenuItemGroup;
|
|
2490
2453
|
}
|
|
2491
2454
|
});
|
|
2492
|
-
Object.defineProperty(exports, '
|
|
2455
|
+
Object.defineProperty(exports, 'BubbleMenuLinkDefault', {
|
|
2493
2456
|
enumerable: true,
|
|
2494
2457
|
get: function () {
|
|
2495
|
-
return
|
|
2458
|
+
return BubbleMenuLinkDefault;
|
|
2496
2459
|
}
|
|
2497
2460
|
});
|
|
2498
|
-
Object.defineProperty(exports, '
|
|
2461
|
+
Object.defineProperty(exports, 'BubbleMenuLinkEditLink', {
|
|
2499
2462
|
enumerable: true,
|
|
2500
2463
|
get: function () {
|
|
2501
|
-
return
|
|
2464
|
+
return BubbleMenuLinkEditLink;
|
|
2502
2465
|
}
|
|
2503
2466
|
});
|
|
2504
|
-
Object.defineProperty(exports, '
|
|
2467
|
+
Object.defineProperty(exports, 'BubbleMenuLinkForm', {
|
|
2505
2468
|
enumerable: true,
|
|
2506
2469
|
get: function () {
|
|
2507
|
-
return
|
|
2470
|
+
return BubbleMenuLinkForm;
|
|
2508
2471
|
}
|
|
2509
2472
|
});
|
|
2510
|
-
Object.defineProperty(exports, '
|
|
2473
|
+
Object.defineProperty(exports, 'BubbleMenuLinkOpenLink', {
|
|
2511
2474
|
enumerable: true,
|
|
2512
2475
|
get: function () {
|
|
2513
|
-
return
|
|
2476
|
+
return BubbleMenuLinkOpenLink;
|
|
2514
2477
|
}
|
|
2515
2478
|
});
|
|
2516
|
-
Object.defineProperty(exports, '
|
|
2479
|
+
Object.defineProperty(exports, 'BubbleMenuLinkSelector', {
|
|
2517
2480
|
enumerable: true,
|
|
2518
2481
|
get: function () {
|
|
2519
|
-
return
|
|
2482
|
+
return BubbleMenuLinkSelector;
|
|
2520
2483
|
}
|
|
2521
2484
|
});
|
|
2522
|
-
Object.defineProperty(exports, '
|
|
2485
|
+
Object.defineProperty(exports, 'BubbleMenuLinkToolbar', {
|
|
2523
2486
|
enumerable: true,
|
|
2524
2487
|
get: function () {
|
|
2525
|
-
return
|
|
2488
|
+
return BubbleMenuLinkToolbar;
|
|
2526
2489
|
}
|
|
2527
2490
|
});
|
|
2528
|
-
Object.defineProperty(exports, '
|
|
2491
|
+
Object.defineProperty(exports, 'BubbleMenuLinkUnlink', {
|
|
2529
2492
|
enumerable: true,
|
|
2530
2493
|
get: function () {
|
|
2531
|
-
return
|
|
2494
|
+
return BubbleMenuLinkUnlink;
|
|
2532
2495
|
}
|
|
2533
2496
|
});
|
|
2534
|
-
Object.defineProperty(exports, '
|
|
2497
|
+
Object.defineProperty(exports, 'BubbleMenuNodeSelector', {
|
|
2535
2498
|
enumerable: true,
|
|
2536
2499
|
get: function () {
|
|
2537
|
-
return
|
|
2500
|
+
return BubbleMenuNodeSelector;
|
|
2538
2501
|
}
|
|
2539
2502
|
});
|
|
2540
|
-
Object.defineProperty(exports, '
|
|
2503
|
+
Object.defineProperty(exports, 'BubbleMenuRoot', {
|
|
2541
2504
|
enumerable: true,
|
|
2542
2505
|
get: function () {
|
|
2543
|
-
return
|
|
2506
|
+
return BubbleMenuRoot;
|
|
2544
2507
|
}
|
|
2545
2508
|
});
|
|
2546
|
-
Object.defineProperty(exports, '
|
|
2509
|
+
Object.defineProperty(exports, 'BubbleMenuStrike', {
|
|
2547
2510
|
enumerable: true,
|
|
2548
2511
|
get: function () {
|
|
2549
|
-
return
|
|
2512
|
+
return BubbleMenuStrike;
|
|
2550
2513
|
}
|
|
2551
2514
|
});
|
|
2552
|
-
Object.defineProperty(exports, '
|
|
2515
|
+
Object.defineProperty(exports, 'BubbleMenuUnderline', {
|
|
2553
2516
|
enumerable: true,
|
|
2554
2517
|
get: function () {
|
|
2555
|
-
return
|
|
2518
|
+
return BubbleMenuUnderline;
|
|
2556
2519
|
}
|
|
2557
2520
|
});
|
|
2558
|
-
Object.defineProperty(exports, '
|
|
2521
|
+
Object.defineProperty(exports, 'BubbleMenuUppercase', {
|
|
2559
2522
|
enumerable: true,
|
|
2560
2523
|
get: function () {
|
|
2561
|
-
return
|
|
2524
|
+
return BubbleMenuUppercase;
|
|
2562
2525
|
}
|
|
2563
2526
|
});
|
|
2564
2527
|
Object.defineProperty(exports, 'CODE', {
|
|
@@ -2675,78 +2638,12 @@ Object.defineProperty(exports, 'Heading3', {
|
|
|
2675
2638
|
return Heading3;
|
|
2676
2639
|
}
|
|
2677
2640
|
});
|
|
2678
|
-
Object.defineProperty(exports, 'ImageBubbleMenuDefault', {
|
|
2679
|
-
enumerable: true,
|
|
2680
|
-
get: function () {
|
|
2681
|
-
return ImageBubbleMenuDefault;
|
|
2682
|
-
}
|
|
2683
|
-
});
|
|
2684
|
-
Object.defineProperty(exports, 'ImageBubbleMenuEditLink', {
|
|
2685
|
-
enumerable: true,
|
|
2686
|
-
get: function () {
|
|
2687
|
-
return ImageBubbleMenuEditLink;
|
|
2688
|
-
}
|
|
2689
|
-
});
|
|
2690
|
-
Object.defineProperty(exports, 'ImageBubbleMenuRoot', {
|
|
2691
|
-
enumerable: true,
|
|
2692
|
-
get: function () {
|
|
2693
|
-
return ImageBubbleMenuRoot;
|
|
2694
|
-
}
|
|
2695
|
-
});
|
|
2696
|
-
Object.defineProperty(exports, 'ImageBubbleMenuToolbar', {
|
|
2697
|
-
enumerable: true,
|
|
2698
|
-
get: function () {
|
|
2699
|
-
return ImageBubbleMenuToolbar;
|
|
2700
|
-
}
|
|
2701
|
-
});
|
|
2702
2641
|
Object.defineProperty(exports, 'ItalicIcon', {
|
|
2703
2642
|
enumerable: true,
|
|
2704
2643
|
get: function () {
|
|
2705
2644
|
return ItalicIcon;
|
|
2706
2645
|
}
|
|
2707
2646
|
});
|
|
2708
|
-
Object.defineProperty(exports, 'LinkBubbleMenuDefault', {
|
|
2709
|
-
enumerable: true,
|
|
2710
|
-
get: function () {
|
|
2711
|
-
return LinkBubbleMenuDefault;
|
|
2712
|
-
}
|
|
2713
|
-
});
|
|
2714
|
-
Object.defineProperty(exports, 'LinkBubbleMenuEditLink', {
|
|
2715
|
-
enumerable: true,
|
|
2716
|
-
get: function () {
|
|
2717
|
-
return LinkBubbleMenuEditLink;
|
|
2718
|
-
}
|
|
2719
|
-
});
|
|
2720
|
-
Object.defineProperty(exports, 'LinkBubbleMenuForm', {
|
|
2721
|
-
enumerable: true,
|
|
2722
|
-
get: function () {
|
|
2723
|
-
return LinkBubbleMenuForm;
|
|
2724
|
-
}
|
|
2725
|
-
});
|
|
2726
|
-
Object.defineProperty(exports, 'LinkBubbleMenuOpenLink', {
|
|
2727
|
-
enumerable: true,
|
|
2728
|
-
get: function () {
|
|
2729
|
-
return LinkBubbleMenuOpenLink;
|
|
2730
|
-
}
|
|
2731
|
-
});
|
|
2732
|
-
Object.defineProperty(exports, 'LinkBubbleMenuRoot', {
|
|
2733
|
-
enumerable: true,
|
|
2734
|
-
get: function () {
|
|
2735
|
-
return LinkBubbleMenuRoot;
|
|
2736
|
-
}
|
|
2737
|
-
});
|
|
2738
|
-
Object.defineProperty(exports, 'LinkBubbleMenuToolbar', {
|
|
2739
|
-
enumerable: true,
|
|
2740
|
-
get: function () {
|
|
2741
|
-
return LinkBubbleMenuToolbar;
|
|
2742
|
-
}
|
|
2743
|
-
});
|
|
2744
|
-
Object.defineProperty(exports, 'LinkBubbleMenuUnlink', {
|
|
2745
|
-
enumerable: true,
|
|
2746
|
-
get: function () {
|
|
2747
|
-
return LinkBubbleMenuUnlink;
|
|
2748
|
-
}
|
|
2749
|
-
});
|
|
2750
2647
|
Object.defineProperty(exports, 'LinkIcon', {
|
|
2751
2648
|
enumerable: true,
|
|
2752
2649
|
get: function () {
|
|
@@ -2891,6 +2788,12 @@ Object.defineProperty(exports, 'UnlinkIcon', {
|
|
|
2891
2788
|
return UnlinkIcon;
|
|
2892
2789
|
}
|
|
2893
2790
|
});
|
|
2791
|
+
Object.defineProperty(exports, 'bubbleMenuTriggers', {
|
|
2792
|
+
enumerable: true,
|
|
2793
|
+
get: function () {
|
|
2794
|
+
return bubbleMenuTriggers;
|
|
2795
|
+
}
|
|
2796
|
+
});
|
|
2894
2797
|
Object.defineProperty(exports, 'defaultSlashCommands', {
|
|
2895
2798
|
enumerable: true,
|
|
2896
2799
|
get: function () {
|
|
@@ -2921,21 +2824,9 @@ Object.defineProperty(exports, 'scoreItem', {
|
|
|
2921
2824
|
return scoreItem;
|
|
2922
2825
|
}
|
|
2923
2826
|
});
|
|
2924
|
-
Object.defineProperty(exports, '
|
|
2925
|
-
enumerable: true,
|
|
2926
|
-
get: function () {
|
|
2927
|
-
return useButtonBubbleMenuContext;
|
|
2928
|
-
}
|
|
2929
|
-
});
|
|
2930
|
-
Object.defineProperty(exports, 'useImageBubbleMenuContext', {
|
|
2931
|
-
enumerable: true,
|
|
2932
|
-
get: function () {
|
|
2933
|
-
return useImageBubbleMenuContext;
|
|
2934
|
-
}
|
|
2935
|
-
});
|
|
2936
|
-
Object.defineProperty(exports, 'useLinkBubbleMenuContext', {
|
|
2827
|
+
Object.defineProperty(exports, 'useBubbleMenuContext', {
|
|
2937
2828
|
enumerable: true,
|
|
2938
2829
|
get: function () {
|
|
2939
|
-
return
|
|
2830
|
+
return useBubbleMenuContext;
|
|
2940
2831
|
}
|
|
2941
2832
|
});
|