@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.
Files changed (41) hide show
  1. package/dist/{extension-XZBBjuHO.mjs → extension-CnC8y63H.mjs} +3 -7
  2. package/dist/extension-CnC8y63H.mjs.map +1 -0
  3. package/dist/{extension-B8yvCdun.cjs → extension-dGpPpEvD.cjs} +2 -6
  4. package/dist/index-C4KcMQ0R.d.cts.map +1 -1
  5. package/dist/index-CxX7W63O.d.mts.map +1 -1
  6. package/dist/index.cjs +7 -7
  7. package/dist/index.css +27 -54
  8. package/dist/index.css.map +1 -1
  9. package/dist/index.d.cts +4 -4
  10. package/dist/index.d.cts.map +1 -1
  11. package/dist/index.d.mts +2 -2
  12. package/dist/index.d.mts.map +1 -1
  13. package/dist/index.mjs +7 -7
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/plugins/index.cjs +1 -1
  16. package/dist/plugins/index.d.cts.map +1 -1
  17. package/dist/plugins/index.d.mts.map +1 -1
  18. package/dist/plugins/index.mjs +1 -1
  19. package/dist/{root-BMxsq1NF.mjs → root-CkYaJZpj.mjs} +645 -730
  20. package/dist/root-CkYaJZpj.mjs.map +1 -0
  21. package/dist/{root-CNVO39XG.cjs → root-Gu08xybW.cjs} +723 -832
  22. package/dist/{set-text-alignment-GMXOPMlJ.mjs → set-text-alignment-OA8IMWmO.mjs} +1 -1
  23. package/dist/{set-text-alignment-GMXOPMlJ.mjs.map → set-text-alignment-OA8IMWmO.mjs.map} +1 -1
  24. package/dist/ui/bubble-menu/bubble-menu.css +139 -0
  25. package/dist/ui/index.cjs +32 -57
  26. package/dist/ui/index.d.cts +280 -364
  27. package/dist/ui/index.d.cts.map +1 -1
  28. package/dist/ui/index.d.mts +280 -364
  29. package/dist/ui/index.d.mts.map +1 -1
  30. package/dist/ui/index.mjs +17 -35
  31. package/dist/ui/index.mjs.map +1 -1
  32. package/dist/ui/themes/default.css +27 -54
  33. package/dist/utils/index.cjs +1 -1
  34. package/dist/utils/index.mjs +1 -1
  35. package/package.json +1 -1
  36. package/dist/extension-XZBBjuHO.mjs.map +0 -1
  37. package/dist/root-BMxsq1NF.mjs.map +0 -1
  38. package/dist/ui/button-bubble-menu/button-bubble-menu.css +0 -63
  39. package/dist/ui/image-bubble-menu/image-bubble-menu.css +0 -29
  40. package/dist/ui/link-bubble-menu/link-bubble-menu.css +0 -68
  41. /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-aNb7Ml9N.cjs');
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/item.tsx
750
- function BubbleMenuItem({ name, isActive, onCommand, className, children, ...rest }) {
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
- children
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
- "data-re-bubble-menu-group": "",
867
- children
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/link-selector.tsx
928
- function BubbleMenuLinkSelector({ className, showToggle = true, validateUrl, onLinkApply, onLinkRemove, children, open: controlledOpen, onOpenChange }) {
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 displayHref = currentHref === "#" ? "" : currentHref;
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
- setIsOpen(false);
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
- }, [editor, setIsOpen]);
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
- setLinkHref(editor, "");
1026
- setIsOpen(false);
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
- setLinkHref(editor, "");
1034
- setIsOpen(false);
871
+ editor.commands.updateButton({ href: "#" });
872
+ setIsEditing(false);
1035
873
  focusEditor(editor);
1036
874
  onLinkRemove?.();
1037
875
  return;
1038
876
  }
1039
- setLinkHref(editor, finalValue);
1040
- setIsOpen(false);
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
- setLinkHref(editor, "");
1047
- setIsOpen(false);
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-link-selector-form": "",
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
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1060
- ref: inputRef,
1061
- "data-re-link-selector-input": "",
1062
- value: inputValue,
1063
- onFocus: (e) => e.stopPropagation(),
1064
- onChange: (e) => setInputValue(e.target.value),
1065
- placeholder: "Paste a link",
1066
- type: "text"
1067
- }),
1068
- children,
1069
- displayHref ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1070
- type: "button",
1071
- "aria-label": "Remove link",
1072
- "data-re-link-selector-unlink": "",
1073
- onClick: handleUnlink,
1074
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
1075
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1076
- type: "submit",
1077
- "aria-label": "Apply link",
1078
- "data-re-link-selector-apply": "",
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/node-selector.tsx
1088
- const NodeSelectorContext = react.createContext(null);
1089
- function useNodeSelectorContext() {
1090
- const context = react.useContext(NodeSelectorContext);
1091
- if (!context) throw new Error("NodeSelector compound components must be used within <NodeSelector.Root>");
1092
- return context;
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
- function NodeSelectorRoot({ omit = [], open: controlledOpen, onOpenChange, className, children }) {
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
- const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
1097
- const isControlled = controlledOpen !== void 0;
1098
- const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1099
- const setIsOpen = react.useCallback((value) => {
1100
- if (!isControlled) setUncontrolledOpen(value);
1101
- onOpenChange?.(value);
1102
- }, [isControlled, onOpenChange]);
1103
- const editorState = (0, _tiptap_react.useEditorState)({
1104
- editor,
1105
- selector: ({ editor: editor$1 }) => ({
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
- name: "Numbered List",
1149
- icon: ListOrdered,
1150
- command: () => editor.chain().focus().clearNodes().toggleOrderedList().run(),
1151
- isActive: editorState?.isOrderedListActive ?? false
948
+ onClick: (e) => {
949
+ onClick?.(e);
950
+ editor.commands.updateButton({ href: "#" });
951
+ focusEditor(editor);
952
+ onLinkRemove?.();
1152
953
  },
1153
- {
1154
- name: "Quote",
1155
- icon: TextQuote,
1156
- command: () => editor.chain().focus().clearNodes().toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
1157
- isActive: editorState?.isBlockquoteActive ?? false
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
- name: "Code",
1161
- icon: Code,
1162
- command: () => editor.chain().focus().clearNodes().toggleCodeBlock().run(),
1163
- isActive: editorState?.isCodeBlockActive ?? false
1164
- }
1165
- ], [editor, editorState]);
1166
- const items = react.useMemo(() => allItems.filter((item) => !omit.includes(item.name)), [allItems, omit]);
1167
- const activeItem = react.useMemo(() => items.find((item) => item.isActive) ?? { name: "Multiple" }, [items]);
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
- function NodeSelectorTrigger({ className, children }) {
1195
- const { activeItem, isOpen, setIsOpen } = useNodeSelectorContext();
1196
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Trigger, {
1197
- "data-re-node-selector-trigger": "",
1198
- className,
1199
- onClick: () => setIsOpen(!isOpen),
1200
- 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, {})] })
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 NodeSelectorContent({ className, align = "start", children }) {
1204
- const { items, setIsOpen } = useNodeSelectorContext();
1205
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Content, {
1206
- align,
1207
- "data-re-node-selector-content": "",
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
- children: children ? children(items, () => setIsOpen(false)) : items.map((item) => {
1210
- const Icon = item.icon;
1211
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1212
- type: "button",
1213
- "data-re-node-selector-item": "",
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
- function BubbleMenuNodeSelector({ omit = [], className, triggerContent, open, onOpenChange }) {
1229
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(NodeSelectorRoot, {
1230
- omit,
1231
- open,
1232
- onOpenChange,
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: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorTrigger, { children: triggerContent }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeSelectorContent, {})]
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/root.tsx
1240
- function BubbleMenuRoot({ excludeNodes = [], excludeMarks = [], placement = "bottom", offset: offset$1 = 8, onHide, className, children, ...rest }) {
1241
- const { editor } = (0, _tiptap_react.useCurrentEditor)();
1242
- if (!editor) return null;
1243
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
1244
- editor,
1245
- pluginKey: "textBubbleMenu",
1246
- "data-re-bubble-menu": "",
1247
- shouldShow: ({ editor: editor$1, view, state }) => {
1248
- for (const node of excludeNodes) {
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
- ...rest,
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/strike.tsx
1273
- const BubbleMenuStrike = createMarkBubbleItem({
1274
- name: "strike",
1275
- activeName: "strike",
1276
- command: "toggleStrike",
1277
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StrikethroughIcon, {})
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/underline.tsx
1282
- const BubbleMenuUnderline = createMarkBubbleItem({
1283
- name: "underline",
1284
- activeName: "underline",
1285
- command: "toggleUnderline",
1286
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnderlineIcon, {})
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/uppercase.tsx
1291
- const BubbleMenuUppercase = createMarkBubbleItem({
1292
- name: "uppercase",
1293
- activeName: "uppercase",
1294
- command: "toggleUppercase",
1295
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CaseUpperIcon, {})
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/default.tsx
1300
- function BubbleMenuDefault({ excludeItems = [], excludeNodes, excludeMarks, placement, offset: offset$1, onHide, className, ...rest }) {
1301
- const [isNodeSelectorOpen, setIsNodeSelectorOpen] = react.useState(false);
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
- ...rest,
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/button-bubble-menu/context.tsx
1355
- const ButtonBubbleMenuContext = react.createContext(null);
1356
- function useButtonBubbleMenuContext() {
1357
- const context = react.useContext(ButtonBubbleMenuContext);
1358
- if (!context) throw new Error("ButtonBubbleMenu compound components must be used within <ButtonBubbleMenu.Root>");
1359
- return context;
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/button-bubble-menu/edit-link.tsx
1364
- function ButtonBubbleMenuEditLink({ className, children, onClick, onMouseDown, ...rest }) {
1365
- const { setIsEditing } = useButtonBubbleMenuContext();
1366
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1367
- ...rest,
1368
- type: "button",
1369
- "aria-label": "Edit link",
1370
- "data-re-btn-bm-item": "",
1371
- "data-item": "edit-link",
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
- onMouseDown: (e) => {
1374
- e.preventDefault();
1375
- onMouseDown?.(e);
1376
- },
1377
- onClick: (e) => {
1378
- onClick?.(e);
1379
- setIsEditing(true);
1380
- },
1381
- children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PencilIcon, {})
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 = buttonHref === "#" ? "" : buttonHref;
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
- }, [isEditing, displayHref]);
1247
+ }, []);
1401
1248
  react.useEffect(() => {
1402
- if (!isEditing) return;
1403
1249
  const handleKeyDown = (event) => {
1404
- if (event.key === "Escape") setIsEditing(false);
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
- setIsEditing(false);
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
- }, [isEditing, setIsEditing]);
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.commands.updateButton({ href: "#" });
1430
- setIsEditing(false);
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.commands.updateButton({ href: "#" });
1438
- setIsEditing(false);
1285
+ setLinkHref(editor, "");
1286
+ setIsOpen(false);
1439
1287
  focusEditor(editor);
1440
1288
  onLinkRemove?.();
1441
1289
  return;
1442
1290
  }
1443
- editor.commands.updateButton({ href: finalValue });
1444
- setIsEditing(false);
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.commands.updateButton({ href: "#" });
1451
- setIsEditing(false);
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-btn-bm-form": "",
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: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1464
- ref: inputRef,
1465
- "data-re-btn-bm-input": "",
1466
- value: inputValue,
1467
- onFocus: (e) => e.stopPropagation(),
1468
- onChange: (e) => setInputValue(e.target.value),
1469
- placeholder: "Paste a link",
1470
- type: "text"
1471
- }), displayHref ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1472
- type: "button",
1473
- "aria-label": "Remove link",
1474
- "data-re-btn-bm-unlink": "",
1475
- onClick: handleUnlink,
1476
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
1477
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1478
- type: "submit",
1479
- "aria-label": "Apply link",
1480
- "data-re-btn-bm-apply": "",
1481
- onMouseDown: (e) => e.stopPropagation(),
1482
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check, {})
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/button-bubble-menu/root.tsx
1489
- function ButtonBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children, ...rest }) {
1490
- const { editor } = (0, _tiptap_react.useCurrentEditor)();
1491
- const [isEditing, setIsEditing] = react.useState(false);
1492
- const buttonHref = (0, _tiptap_react.useEditorState)({
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: e }) => e?.getAttributes("button").href ?? ""
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
- if (!editor) return null;
1497
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
1498
- editor,
1499
- pluginKey: "buttonBubbleMenu",
1500
- "data-re-btn-bm": "",
1501
- shouldShow: ({ editor: e, view }) => e.isActive("button") && !view.dom.classList.contains("dragging"),
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
- className,
1511
- ...rest,
1512
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuContext.Provider, {
1513
- value: {
1514
- editor,
1515
- buttonHref: buttonHref ?? "",
1516
- isEditing,
1517
- setIsEditing
1518
- },
1519
- children
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
- //#endregion
1525
- //#region src/ui/button-bubble-menu/toolbar.tsx
1526
- function ButtonBubbleMenuToolbar({ children, ...rest }) {
1527
- const { isEditing } = useButtonBubbleMenuContext();
1528
- if (isEditing) return null;
1529
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
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
- //#endregion
1537
- //#region src/ui/button-bubble-menu/unlink.tsx
1538
- function ButtonBubbleMenuUnlink({ className, children, onClick, onMouseDown, onLinkRemove, ...rest }) {
1539
- const { editor } = useButtonBubbleMenuContext();
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
- onMouseDown: (e) => {
1548
- e.preventDefault();
1549
- onMouseDown?.(e);
1550
- },
1551
- onClick: (e) => {
1552
- onClick?.(e);
1553
- editor.commands.updateButton({ href: "#" });
1554
- focusEditor(editor);
1555
- onLinkRemove?.();
1556
- },
1557
- children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnlinkIcon, {})
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/button-bubble-menu/default.tsx
1563
- function ButtonBubbleMenuDefaultInner({ validateUrl, onLinkApply, onLinkRemove }) {
1564
- const { buttonHref } = useButtonBubbleMenuContext();
1565
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ButtonBubbleMenuToolbar, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuEditLink, {}), buttonHref !== "" && buttonHref !== "#" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuUnlink, { onLinkRemove })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuForm, {
1566
- validateUrl,
1567
- onLinkApply,
1568
- onLinkRemove
1569
- })] });
1570
- }
1571
- function ButtonBubbleMenuDefault({ placement, offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove, ...rest }) {
1572
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuRoot, {
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: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuDefaultInner, {
1579
- validateUrl,
1580
- onLinkApply,
1581
- onLinkRemove
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/image-bubble-menu/context.tsx
1588
- const ImageBubbleMenuContext = react.createContext(null);
1589
- function useImageBubbleMenuContext() {
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/image-bubble-menu/root.tsx
1620
- function ImageBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children, ...rest }) {
1621
- const { editor } = (0, _tiptap_react.useCurrentEditor)();
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/image-bubble-menu/default.tsx
1664
- function ImageBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className, ...rest }) {
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)(ImageBubbleMenuRoot, {
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)(ImageBubbleMenuToolbar, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageBubbleMenuEditLink, {}) })
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/link-bubble-menu/context.tsx
1678
- const LinkBubbleMenuContext = react.createContext(null);
1679
- function useLinkBubbleMenuContext() {
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/link-bubble-menu/form.tsx
1710
- function LinkBubbleMenuForm({ className, validateUrl, onLinkApply, onLinkRemove, children }) {
1711
- const { editor, linkHref, isEditing, setIsEditing } = useLinkBubbleMenuContext();
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 displayHref = linkHref === "#" ? "" : linkHref;
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/link-bubble-menu/open-link.tsx
1816
- function LinkBubbleMenuOpenLink({ className, children, ...rest }) {
1817
- const { linkHref } = useLinkBubbleMenuContext();
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/link-bubble-menu/root.tsx
1833
- function LinkBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children, ...rest }) {
1834
- const { editor } = (0, _tiptap_react.useCurrentEditor)();
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/link-bubble-menu/unlink.tsx
1882
- function LinkBubbleMenuUnlink({ className, children, onClick, onMouseDown, ...rest }) {
1883
- const { editor } = useLinkBubbleMenuContext();
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/link-bubble-menu/default.tsx
1905
- function LinkBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove, ...rest }) {
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)(LinkBubbleMenuRoot, {
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)(LinkBubbleMenuToolbar, { children: [
1915
- has("edit-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkBubbleMenuEditLink, {}),
1916
- has("open-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkBubbleMenuOpenLink, {}),
1917
- has("unlink") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkBubbleMenuUnlink, {})
1918
- ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkBubbleMenuForm, {
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, 'BubbleMenuLinkSelector', {
2455
+ Object.defineProperty(exports, 'BubbleMenuLinkDefault', {
2493
2456
  enumerable: true,
2494
2457
  get: function () {
2495
- return BubbleMenuLinkSelector;
2458
+ return BubbleMenuLinkDefault;
2496
2459
  }
2497
2460
  });
2498
- Object.defineProperty(exports, 'BubbleMenuNodeSelector', {
2461
+ Object.defineProperty(exports, 'BubbleMenuLinkEditLink', {
2499
2462
  enumerable: true,
2500
2463
  get: function () {
2501
- return BubbleMenuNodeSelector;
2464
+ return BubbleMenuLinkEditLink;
2502
2465
  }
2503
2466
  });
2504
- Object.defineProperty(exports, 'BubbleMenuRoot', {
2467
+ Object.defineProperty(exports, 'BubbleMenuLinkForm', {
2505
2468
  enumerable: true,
2506
2469
  get: function () {
2507
- return BubbleMenuRoot;
2470
+ return BubbleMenuLinkForm;
2508
2471
  }
2509
2472
  });
2510
- Object.defineProperty(exports, 'BubbleMenuStrike', {
2473
+ Object.defineProperty(exports, 'BubbleMenuLinkOpenLink', {
2511
2474
  enumerable: true,
2512
2475
  get: function () {
2513
- return BubbleMenuStrike;
2476
+ return BubbleMenuLinkOpenLink;
2514
2477
  }
2515
2478
  });
2516
- Object.defineProperty(exports, 'BubbleMenuUnderline', {
2479
+ Object.defineProperty(exports, 'BubbleMenuLinkSelector', {
2517
2480
  enumerable: true,
2518
2481
  get: function () {
2519
- return BubbleMenuUnderline;
2482
+ return BubbleMenuLinkSelector;
2520
2483
  }
2521
2484
  });
2522
- Object.defineProperty(exports, 'BubbleMenuUppercase', {
2485
+ Object.defineProperty(exports, 'BubbleMenuLinkToolbar', {
2523
2486
  enumerable: true,
2524
2487
  get: function () {
2525
- return BubbleMenuUppercase;
2488
+ return BubbleMenuLinkToolbar;
2526
2489
  }
2527
2490
  });
2528
- Object.defineProperty(exports, 'ButtonBubbleMenuDefault', {
2491
+ Object.defineProperty(exports, 'BubbleMenuLinkUnlink', {
2529
2492
  enumerable: true,
2530
2493
  get: function () {
2531
- return ButtonBubbleMenuDefault;
2494
+ return BubbleMenuLinkUnlink;
2532
2495
  }
2533
2496
  });
2534
- Object.defineProperty(exports, 'ButtonBubbleMenuEditLink', {
2497
+ Object.defineProperty(exports, 'BubbleMenuNodeSelector', {
2535
2498
  enumerable: true,
2536
2499
  get: function () {
2537
- return ButtonBubbleMenuEditLink;
2500
+ return BubbleMenuNodeSelector;
2538
2501
  }
2539
2502
  });
2540
- Object.defineProperty(exports, 'ButtonBubbleMenuForm', {
2503
+ Object.defineProperty(exports, 'BubbleMenuRoot', {
2541
2504
  enumerable: true,
2542
2505
  get: function () {
2543
- return ButtonBubbleMenuForm;
2506
+ return BubbleMenuRoot;
2544
2507
  }
2545
2508
  });
2546
- Object.defineProperty(exports, 'ButtonBubbleMenuRoot', {
2509
+ Object.defineProperty(exports, 'BubbleMenuStrike', {
2547
2510
  enumerable: true,
2548
2511
  get: function () {
2549
- return ButtonBubbleMenuRoot;
2512
+ return BubbleMenuStrike;
2550
2513
  }
2551
2514
  });
2552
- Object.defineProperty(exports, 'ButtonBubbleMenuToolbar', {
2515
+ Object.defineProperty(exports, 'BubbleMenuUnderline', {
2553
2516
  enumerable: true,
2554
2517
  get: function () {
2555
- return ButtonBubbleMenuToolbar;
2518
+ return BubbleMenuUnderline;
2556
2519
  }
2557
2520
  });
2558
- Object.defineProperty(exports, 'ButtonBubbleMenuUnlink', {
2521
+ Object.defineProperty(exports, 'BubbleMenuUppercase', {
2559
2522
  enumerable: true,
2560
2523
  get: function () {
2561
- return ButtonBubbleMenuUnlink;
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, 'useButtonBubbleMenuContext', {
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 useLinkBubbleMenuContext;
2830
+ return useBubbleMenuContext;
2940
2831
  }
2941
2832
  });