@blockslides/extension-bubble-menu-preset 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -257,6 +257,8 @@ function buildMenuElement(editor, opts) {
257
257
  let fontSizeSelect = null;
258
258
  let imageAlignSelect = null;
259
259
  let imageDisplaySelect = null;
260
+ let imageCropSelect = null;
261
+ let imageWidthSelect = null;
260
262
  const normalizeFontFamily = (value) => {
261
263
  var _a2;
262
264
  if (!value) return value;
@@ -422,9 +424,11 @@ function buildMenuElement(editor, opts) {
422
424
  });
423
425
  select.disabled = !hasCommand;
424
426
  select.addEventListener("change", () => {
425
- var _a2, _b;
427
+ var _a2, _b, _c;
426
428
  runWithFocus(() => runChainCommand("setFontFamily", select.value));
427
- (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
429
+ if ((_a2 = editor.view) == null ? void 0 : _a2.state) {
430
+ (_c = (_b = editor.commands).setMeta) == null ? void 0 : _c.call(_b, "bubbleMenu", "updatePosition");
431
+ }
428
432
  });
429
433
  fontFamilySelect = select;
430
434
  wrapper.appendChild(select);
@@ -445,9 +449,11 @@ function buildMenuElement(editor, opts) {
445
449
  });
446
450
  select.disabled = !hasCommand;
447
451
  select.addEventListener("change", () => {
448
- var _a2, _b;
452
+ var _a2, _b, _c;
449
453
  runWithFocus(() => runChainCommand("setFontSize", select.value));
450
- (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
454
+ if ((_a2 = editor.view) == null ? void 0 : _a2.state) {
455
+ (_c = (_b = editor.commands).setMeta) == null ? void 0 : _c.call(_b, "bubbleMenu", "updatePosition");
456
+ }
451
457
  });
452
458
  fontSizeSelect = select;
453
459
  wrapper.appendChild(select);
@@ -488,8 +494,12 @@ function buildMenuElement(editor, opts) {
488
494
  (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
489
495
  },
490
496
  onToggle: () => {
491
- var _a2, _b;
492
- return (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
497
+ var _a2, _b, _c;
498
+ console.log("[bubbleMenuPreset onToggle]", {
499
+ editorDestroyed: editor == null ? void 0 : editor.isDestroyed,
500
+ hasSelection: !!((_a2 = editor.state) == null ? void 0 : _a2.selection)
501
+ });
502
+ (_c = (_b = editor.commands).setMeta) == null ? void 0 : _c.call(_b, "bubbleMenu", "updatePosition");
493
503
  }
494
504
  });
495
505
  popovers.push(popover);
@@ -517,8 +527,12 @@ function buildMenuElement(editor, opts) {
517
527
  (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
518
528
  },
519
529
  onToggle: () => {
520
- var _a2, _b;
521
- return (_b = (_a2 = editor.commands).setMeta) == null ? void 0 : _b.call(_a2, "bubbleMenu", "updatePosition");
530
+ var _a2, _b, _c;
531
+ console.log("[bubbleMenuPreset onToggle]", {
532
+ editorDestroyed: editor == null ? void 0 : editor.isDestroyed,
533
+ hasSelection: !!((_a2 = editor.state) == null ? void 0 : _a2.selection)
534
+ });
535
+ (_c = (_b = editor.commands).setMeta) == null ? void 0 : _c.call(_b, "bubbleMenu", "updatePosition");
522
536
  }
523
537
  });
524
538
  popovers.push(popover);
@@ -644,10 +658,13 @@ function buildMenuElement(editor, opts) {
644
658
  });
645
659
  });
646
660
  const alignWrapper = document.createElement("div");
647
- alignWrapper.className = "bs-bmp-select";
661
+ alignWrapper.className = "bs-bmp-select bs-bmp-labeled-select";
662
+ const alignLabel = document.createElement("label");
663
+ alignLabel.className = "bs-bmp-select-label";
664
+ alignLabel.textContent = "Align:";
648
665
  const alignSelect = document.createElement("select");
649
666
  alignSelect.className = "bs-bmp-select-input";
650
- alignSelect.title = "Align image";
667
+ alignSelect.title = "Image alignment";
651
668
  ["left", "center", "right"].forEach((alignment) => {
652
669
  const option = document.createElement("option");
653
670
  option.value = alignment;
@@ -666,18 +683,27 @@ function buildMenuElement(editor, opts) {
666
683
  }
667
684
  (_g = (_f = editor.commands).setMeta) == null ? void 0 : _g.call(_f, "bubbleMenu", "updatePosition");
668
685
  });
686
+ alignWrapper.appendChild(alignLabel);
669
687
  alignWrapper.appendChild(alignSelect);
670
688
  imageToolbar.appendChild(alignWrapper);
671
689
  imageAlignSelect = alignSelect;
672
690
  const displayWrapper = document.createElement("div");
673
- displayWrapper.className = "bs-bmp-select";
691
+ displayWrapper.className = "bs-bmp-select bs-bmp-labeled-select";
692
+ const displayLabel = document.createElement("label");
693
+ displayLabel.className = "bs-bmp-select-label";
694
+ displayLabel.textContent = "Fit:";
674
695
  const displaySelect = document.createElement("select");
675
696
  displaySelect.className = "bs-bmp-select-input";
676
- displaySelect.title = "Image fit";
677
- ["default", "cover", "contain", "fill"].forEach((mode) => {
697
+ displaySelect.title = "Image size mode";
698
+ const sizeOptions = [
699
+ { value: "fill", label: "Cover" },
700
+ { value: "fit", label: "Contain" },
701
+ { value: "natural", label: "Original" }
702
+ ];
703
+ sizeOptions.forEach(({ value, label }) => {
678
704
  const option = document.createElement("option");
679
- option.value = mode;
680
- option.textContent = mode.charAt(0).toUpperCase() + mode.slice(1);
705
+ option.value = value;
706
+ option.textContent = label;
681
707
  displaySelect.appendChild(option);
682
708
  });
683
709
  displaySelect.addEventListener("change", () => {
@@ -685,30 +711,87 @@ function buildMenuElement(editor, opts) {
685
711
  const value = displaySelect.value;
686
712
  const chain = (_a2 = editor.chain) == null ? void 0 : _a2.call(editor);
687
713
  const runner = typeof (chain == null ? void 0 : chain.focus) === "function" ? chain.focus() : chain;
688
- if (editor.isActive("imageBlock") && typeof (runner == null ? void 0 : runner.setImageBlockLayout) === "function") {
689
- if (value === "cover" && typeof (runner == null ? void 0 : runner.setImageBlockFullBleed) === "function") {
690
- runner.setImageBlockFullBleed(true);
691
- }
692
- (_c = (_b = runner.setImageBlockLayout(value === "default" ? "cover" : value)).run) == null ? void 0 : _c.call(_b);
714
+ if (editor.isActive("imageBlock") && typeof (runner == null ? void 0 : runner.setImageBlockSize) === "function") {
715
+ (_c = (_b = runner.setImageBlockSize(value)).run) == null ? void 0 : _c.call(_b);
693
716
  } else if (typeof (runner == null ? void 0 : runner.updateAttributes) === "function") {
694
- (_e = (_d = runner.updateAttributes("image", { display: value })).run) == null ? void 0 : _e.call(_d);
717
+ (_e = (_d = runner.updateAttributes("image", { size: value })).run) == null ? void 0 : _e.call(_d);
695
718
  }
696
719
  (_g = (_f = editor.commands).setMeta) == null ? void 0 : _g.call(_f, "bubbleMenu", "updatePosition");
697
720
  });
721
+ displayWrapper.appendChild(displayLabel);
698
722
  displayWrapper.appendChild(displaySelect);
699
723
  imageToolbar.appendChild(displayWrapper);
700
724
  imageDisplaySelect = displaySelect;
701
- addImageButton("Full width", "Set image width to 100%", () => {
725
+ const cropWrapper = document.createElement("div");
726
+ cropWrapper.className = "bs-bmp-select bs-bmp-labeled-select";
727
+ const cropLabel = document.createElement("label");
728
+ cropLabel.className = "bs-bmp-select-label";
729
+ cropLabel.textContent = "Position:";
730
+ const cropSelect = document.createElement("select");
731
+ cropSelect.className = "bs-bmp-select-input";
732
+ cropSelect.title = "Focal position";
733
+ ["center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right"].forEach((position) => {
734
+ const option = document.createElement("option");
735
+ option.value = position;
736
+ option.textContent = position.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
737
+ cropSelect.appendChild(option);
738
+ });
739
+ cropSelect.addEventListener("change", () => {
702
740
  var _a2, _b, _c, _d, _e, _f, _g;
741
+ const value = cropSelect.value;
742
+ const chain = (_a2 = editor.chain) == null ? void 0 : _a2.call(editor);
743
+ const runner = typeof (chain == null ? void 0 : chain.focus) === "function" ? chain.focus() : chain;
744
+ if (editor.isActive("imageBlock") && typeof (runner == null ? void 0 : runner.setImageBlockCrop) === "function") {
745
+ (_c = (_b = runner.setImageBlockCrop(value)).run) == null ? void 0 : _c.call(_b);
746
+ } else if (typeof (runner == null ? void 0 : runner.updateAttributes) === "function") {
747
+ (_e = (_d = runner.updateAttributes("image", { crop: value })).run) == null ? void 0 : _e.call(_d);
748
+ }
749
+ (_g = (_f = editor.commands).setMeta) == null ? void 0 : _g.call(_f, "bubbleMenu", "updatePosition");
750
+ });
751
+ cropWrapper.appendChild(cropLabel);
752
+ cropWrapper.appendChild(cropSelect);
753
+ imageToolbar.appendChild(cropWrapper);
754
+ imageCropSelect = cropSelect;
755
+ const widthWrapper = document.createElement("div");
756
+ widthWrapper.className = "bs-bmp-select bs-bmp-labeled-select";
757
+ const widthLabel = document.createElement("label");
758
+ widthLabel.className = "bs-bmp-select-label";
759
+ widthLabel.textContent = "Width:";
760
+ const widthSelect = document.createElement("select");
761
+ widthSelect.className = "bs-bmp-select-input";
762
+ widthSelect.title = "Image width";
763
+ const widthOptions = [
764
+ { value: "auto", label: "Auto" },
765
+ { value: "25%", label: "25%" },
766
+ { value: "33%", label: "33%" },
767
+ { value: "50%", label: "50%" },
768
+ { value: "66%", label: "66%" },
769
+ { value: "75%", label: "75%" },
770
+ { value: "100%", label: "100%" }
771
+ ];
772
+ widthOptions.forEach(({ value, label }) => {
773
+ const option = document.createElement("option");
774
+ option.value = value;
775
+ option.textContent = label;
776
+ widthSelect.appendChild(option);
777
+ });
778
+ widthSelect.addEventListener("change", () => {
779
+ var _a2, _b, _c, _d, _e, _f, _g;
780
+ const value = widthSelect.value;
781
+ const width = value === "auto" ? null : value;
703
782
  const chain = (_a2 = editor.chain) == null ? void 0 : _a2.call(editor);
704
783
  const runner = typeof (chain == null ? void 0 : chain.focus) === "function" ? chain.focus() : chain;
705
784
  if (editor.isActive("imageBlock") && typeof (runner == null ? void 0 : runner.setImageBlockDimensions) === "function") {
706
- (_c = (_b = runner.setImageBlockDimensions({ width: "100%", height: null })).run) == null ? void 0 : _c.call(_b);
785
+ (_c = (_b = runner.setImageBlockDimensions({ width, height: null })).run) == null ? void 0 : _c.call(_b);
707
786
  } else if (typeof (runner == null ? void 0 : runner.updateAttributes) === "function") {
708
- (_e = (_d = runner.updateAttributes("image", { width: "100%", height: null })).run) == null ? void 0 : _e.call(_d);
787
+ (_e = (_d = runner.updateAttributes("image", { width, height: null })).run) == null ? void 0 : _e.call(_d);
709
788
  }
710
789
  (_g = (_f = editor.commands).setMeta) == null ? void 0 : _g.call(_f, "bubbleMenu", "updatePosition");
711
790
  });
791
+ widthWrapper.appendChild(widthLabel);
792
+ widthWrapper.appendChild(widthSelect);
793
+ imageToolbar.appendChild(widthWrapper);
794
+ imageWidthSelect = widthSelect;
712
795
  const { popover: altPopover, show: showAltPopover } = createAltPopover({
713
796
  getCurrentValue: () => {
714
797
  var _a2;
@@ -793,9 +876,13 @@ function buildMenuElement(editor, opts) {
793
876
  const syncImageState = () => {
794
877
  if (!isImageSelection()) return;
795
878
  const attrs = getImageAttrs();
796
- const fitValue = editor.isActive("imageBlock") ? attrs.layout || "cover" : attrs.display || "default";
879
+ const sizeValue = attrs.size || "fill";
880
+ const cropValue = attrs.crop || "center";
881
+ const widthValue = attrs.width || "auto";
797
882
  setSelectValue(imageAlignSelect, attrs.align);
798
- setSelectValue(imageDisplaySelect, fitValue);
883
+ setSelectValue(imageDisplaySelect, sizeValue);
884
+ setSelectValue(imageCropSelect, cropValue);
885
+ setSelectValue(imageWidthSelect, widthValue);
799
886
  };
800
887
  const syncToolbarVisibility = () => {
801
888
  const imageVisible = isImageSelection();
@@ -1125,6 +1212,17 @@ function injectStyles() {
1125
1212
  display: inline-flex;
1126
1213
  align-items: center;
1127
1214
  }
1215
+ .bs-bmp-labeled-select {
1216
+ display: inline-flex;
1217
+ align-items: center;
1218
+ gap: 4px;
1219
+ }
1220
+ .bs-bmp-select-label {
1221
+ font-size: 12px;
1222
+ color: #6b7280;
1223
+ font-weight: 500;
1224
+ white-space: nowrap;
1225
+ }
1128
1226
  .bs-bmp-select-input {
1129
1227
  border: 1px solid #e5e7eb;
1130
1228
  background: #ffffff;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/bubble-menu-preset.ts"],"sourcesContent":["export * from './bubble-menu-preset.js'\nexport { BubbleMenuPreset as default } from './bubble-menu-preset.js'\n\n\n\n\n","import { Extension, isNodeSelection, isTextSelection, posToDOMRect } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\nimport { NodeSelection } from '@blockslides/pm/state'\n\ntype BubbleMenuPresetItem =\n | 'undo'\n | 'redo'\n | 'fontFamily'\n | 'fontSize'\n | 'bold'\n | 'italic'\n | 'underline'\n | 'textColor'\n | 'highlightColor'\n | 'link'\n | 'align'\n\ntype TextAlignValue = 'left' | 'center' | 'right' | 'justify'\n\nexport type BubbleMenuPresetTextAction = 'undo' | 'redo' | 'bold' | 'italic' | 'underline' | 'link'\n\nexport interface BubbleMenuPresetActionContext {\n editor: Editor\n element: HTMLElement\n trigger: HTMLElement\n getTriggerRect: () => DOMRect | null\n getMenuRect: () => DOMRect | null\n getSelectionRect: () => DOMRect | null\n closePopovers: () => void\n defaultAction: () => void\n}\n\nexport interface BubbleMenuPresetImageReplaceContext extends BubbleMenuPresetActionContext {\n getCurrentValue: () => string\n replaceWith: (value: string) => void\n showDefaultPopover: () => void\n}\n\nexport interface BubbleMenuPresetOptions\n extends Omit<BubbleMenuOptions, 'element'> {\n /**\n * Optional custom element to use for the menu. If omitted, a default\n * element with built-in buttons is rendered.\n */\n element?: HTMLElement | null\n\n /**\n * Order of built-in controls to render.\n */\n items?: BubbleMenuPresetItem[]\n\n /**\n * Additional class names to attach to the menu element to allow easy\n * style overrides.\n */\n className?: string\n\n /**\n * Inject default CSS. Set to false to opt out if you provide your own styles.\n */\n injectStyles?: boolean\n\n /**\n * Palette for text color swatches.\n */\n textColors?: string[]\n\n /**\n * Palette for highlight swatches.\n */\n highlightColors?: string[]\n\n /**\n * Fonts exposed in the font picker.\n */\n fonts?: string[]\n\n /**\n * Font sizes (any CSS length, e.g. \"16px\", \"1rem\").\n */\n fontSizes?: string[]\n\n /**\n * Alignments to expose in the align control.\n */\n alignments?: TextAlignValue[]\n\n /**\n * Override text button actions (undo/redo/bold/italic/underline/link).\n * Use defaultAction() to fall back to built-in behavior.\n */\n onTextAction?: (action: BubbleMenuPresetTextAction, ctx: BubbleMenuPresetActionContext) => void\n\n /**\n * Override image replace behavior (e.g., open your own picker).\n * Use showDefaultPopover() or replaceWith() to reuse built-in behavior.\n */\n onImageReplace?: (ctx: BubbleMenuPresetImageReplaceContext) => void\n}\n\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nexport const DEFAULT_ITEMS: BubbleMenuPresetItem[] = [\n 'undo',\n 'redo',\n 'fontFamily',\n 'fontSize',\n 'bold',\n 'italic',\n 'underline',\n 'textColor',\n 'highlightColor',\n 'link',\n 'align',\n]\n\nexport const DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nexport const DEFAULT_FONT_SIZES = [\n '12px',\n '14px',\n '16px',\n '18px',\n '20px',\n '24px',\n '32px',\n '40px',\n '48px',\n '56px',\n '64px',\n '72px',\n]\n\nexport const DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nexport const DEFAULT_COLOR_PALETTE: string[] = [\n '#000000',\n '#434343',\n '#666666',\n '#999999',\n '#b7b7b7',\n '#cccccc',\n '#d9d9d9',\n '#efefef',\n '#f3f3f3',\n '#ffffff',\n '#e60000',\n '#ff0000',\n '#ff9900',\n '#ffff00',\n '#00ff00',\n '#00ffff',\n '#4a86e8',\n '#0000ff',\n '#9900ff',\n '#ff00ff',\n '#f4cccc',\n '#fce5cd',\n '#fff2cc',\n '#d9ead3',\n '#d0e0e3',\n '#cfe2f3',\n '#d9d2e9',\n '#ead1dc',\n '#f9cb9c',\n '#ffe599',\n '#b6d7a8',\n '#a2c4c9',\n '#9fc5e8',\n '#b4a7d6',\n '#d5a6bd',\n '#e06666',\n '#f6b26b',\n '#ffd966',\n '#93c47d',\n '#76a5af',\n '#6fa8dc',\n '#8e7cc3',\n '#c27ba0',\n '#cc0000',\n '#e69138',\n '#f1c232',\n '#6aa84f',\n '#45818e',\n '#3d85c6',\n '#674ea7',\n '#a64d79',\n '#990000',\n '#b45f06',\n '#bf9000',\n '#38761d',\n '#134f5c',\n '#0b5394',\n '#351c75',\n '#741b47',\n '#660000',\n '#783f04',\n '#7f6000',\n '#274e13',\n '#0c343d',\n '#073763',\n '#20124d',\n '#4c1130',\n]\n\nexport const DEFAULT_HIGHLIGHT_PALETTE = DEFAULT_COLOR_PALETTE\n\nconst DEFAULT_LABELS: Record<BubbleMenuPresetItem, string> = {\n undo: 'Undo',\n redo: 'Redo',\n fontFamily: 'Font',\n fontSize: 'Size',\n bold: 'B',\n italic: 'I',\n underline: 'U',\n textColor: 'A',\n highlightColor: 'Hi',\n link: 'Link',\n align: 'Align',\n}\n\nconst ICONS = {\n textColor: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 20h14\"/><path d=\"M7 20l5-14 5 14\"/><path d=\"M10.7 14h2.6\"/></svg>`,\n highlightColor: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m11 18 2-2h6\"/><path d=\"m2 22 3-3h6l3-3-6-6-3 3v6z\"/><path d=\"M14 7l3-3 3 3-3 3z\"/></svg>`,\n}\n\ninterface MenuBuildResult {\n element: HTMLElement\n cleanup: Cleanup\n}\n\nexport const BubbleMenuPreset = Extension.create<BubbleMenuPresetOptions>({\n name: 'bubbleMenuPreset',\n\n addOptions() {\n return {\n element: null,\n items: DEFAULT_ITEMS,\n className: '',\n injectStyles: true,\n textColors: DEFAULT_COLOR_PALETTE,\n highlightColors: DEFAULT_HIGHLIGHT_PALETTE,\n fonts: DEFAULT_FONTS,\n fontSizes: DEFAULT_FONT_SIZES,\n alignments: DEFAULT_ALIGNMENTS,\n pluginKey: 'bubbleMenuPreset',\n updateDelay: 250,\n resizeDelay: 60,\n appendTo: undefined,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\n },\n shouldShow: ({ state, editor }) => {\n const { selection } = state\n const imageSelection =\n (selection instanceof NodeSelection &&\n ['image', 'imageBlock'].includes(selection.node.type.name)) ||\n editor.isActive('image') ||\n editor.isActive('imageBlock')\n\n if (imageSelection) return true\n if (isTextSelection(selection) && !selection.empty && !imageSelection) return true\n return false\n },\n }\n },\n\n addProseMirrorPlugins() {\n const options = this.options\n const editor = this.editor\n\n const usingCustomElement = !!options.element\n const { element, cleanup } =\n options.element && typeof document !== 'undefined'\n ? { element: options.element, cleanup: () => {} }\n : buildMenuElement(editor, {\n items: options.items ?? DEFAULT_ITEMS,\n className: options.className ?? '',\n injectStyles: options.injectStyles !== false,\n textColors: options.textColors ?? DEFAULT_COLOR_PALETTE,\n highlightColors: options.highlightColors ?? DEFAULT_HIGHLIGHT_PALETTE,\n fonts: options.fonts ?? DEFAULT_FONTS,\n fontSizes: options.fontSizes ?? DEFAULT_FONT_SIZES,\n alignments: options.alignments ?? DEFAULT_ALIGNMENTS,\n onTextAction: options.onTextAction,\n onImageReplace: options.onImageReplace,\n })\n\n this.storage.element = element\n this.storage.cleanup = cleanup\n this.storage.usingCustomElement = usingCustomElement\n\n const pluginOptions: BubbleMenuPluginProps = {\n pluginKey: options.pluginKey ?? 'bubbleMenuPreset',\n editor,\n element: element,\n updateDelay: options.updateDelay,\n resizeDelay: options.resizeDelay,\n appendTo: options.appendTo,\n options: options.options,\n getReferencedVirtualElement: options.getReferencedVirtualElement,\n shouldShow: options.shouldShow ?? undefined,\n }\n\n return [BubbleMenuPlugin(pluginOptions)]\n },\n\n onDestroy() {\n const el = this.storage.element as HTMLElement | undefined\n const cleanup = this.storage.cleanup as Cleanup | undefined\n const usingCustomElement = this.storage.usingCustomElement as boolean | undefined\n if (cleanup) {\n cleanup()\n }\n if (el && !usingCustomElement) {\n el.remove()\n }\n },\n})\n\nexport function buildMenuElement(\n editor: Editor,\n opts: {\n items: BubbleMenuPresetItem[]\n className: string\n injectStyles: boolean\n textColors: string[]\n highlightColors: string[]\n fonts: string[]\n fontSizes: string[]\n alignments: TextAlignValue[]\n onTextAction?: BubbleMenuPresetOptions['onTextAction']\n onImageReplace?: BubbleMenuPresetOptions['onImageReplace']\n },\n): MenuBuildResult {\n if (opts.injectStyles) {\n injectStyles()\n }\n\n const element = document.createElement('div')\n element.className = `bs-bubble-menu-preset ${opts.className ?? ''}`.trim()\n element.setAttribute('data-bubble-menu-preset', 'true')\n element.tabIndex = 0\n\n const textToolbar = document.createElement('div')\n textToolbar.className = 'bs-bmp-toolbar'\n\n const imageToolbar = document.createElement('div')\n imageToolbar.className = 'bs-bmp-toolbar bs-bmp-toolbar-image'\n\n let fontFamilySelect: HTMLSelectElement | null = null\n let fontSizeSelect: HTMLSelectElement | null = null\n let imageAlignSelect: HTMLSelectElement | null = null\n let imageDisplaySelect: HTMLSelectElement | null = null\n\n const normalizeFontFamily = (value?: string | null) => {\n if (!value) return value\n // take the first family name and strip quotes\n return value.split(',')[0]?.trim().replace(/^['\"]|['\"]$/g, '') || value\n }\n\n const getComputedFontStyles = () => {\n if (typeof window === 'undefined') return { fontFamily: undefined, fontSize: undefined }\n const sel = window.getSelection()\n const node = sel?.anchorNode\n const el = (node instanceof HTMLElement ? node : node?.parentElement) ?? undefined\n if (!el) return { fontFamily: undefined, fontSize: undefined }\n const styles = window.getComputedStyle(el)\n return {\n fontFamily: normalizeFontFamily(styles.fontFamily || undefined),\n fontSize: styles.fontSize || undefined,\n }\n }\n\n const isImageSelection = () => {\n const sel = editor.state.selection\n if (sel instanceof NodeSelection) {\n return ['image', 'imageBlock'].includes(sel.node.type.name)\n }\n return editor.isActive('image') || editor.isActive('imageBlock')\n }\n\n const getImageAttrs = () => {\n const sel = editor.state.selection\n if (sel instanceof NodeSelection && ['image', 'imageBlock'].includes(sel.node.type.name)) {\n return sel.node.attrs || {}\n }\n if (editor.isActive('imageBlock')) return editor.getAttributes('imageBlock') || {}\n return editor.getAttributes('image') || {}\n }\n\n const ensureOptionExists = (select: HTMLSelectElement, value: string) => {\n const exists = Array.from(select.options).some(opt => opt.value === value)\n if (!exists) {\n const option = document.createElement('option')\n option.value = value\n option.textContent = value\n select.appendChild(option)\n }\n }\n\n const setSelectValue = (select: HTMLSelectElement | null, value?: string | null) => {\n if (!select) return\n if (!value) {\n select.selectedIndex = -1\n return\n }\n ensureOptionExists(select, value)\n select.value = value\n }\n\n const popovers: HTMLElement[] = []\n const cleanupFns: Cleanup[] = []\n\n const getCommand = (name: string): any => (editor.commands as any)?.[name]\n const runChainCommand = (name: string, ...args: any[]) => {\n const chain = (editor.chain as any)?.()\n if (!chain || typeof chain[name] !== 'function') return false\n const runner = typeof chain.focus === 'function' ? chain.focus() : chain\n if (typeof runner[name] !== 'function') return false\n return runner[name](...args).run?.() ?? false\n }\n\n const closePopovers = () => {\n popovers.forEach((p) => {\n p.classList.add('bs-bmp-hidden')\n p.style.display = 'none'\n })\n }\n\n const getMenuRect = () => element.getBoundingClientRect?.() ?? null\n const getSelectionRect = () => {\n const view = (editor as any).view\n if (!view) return null\n const { from, to } = editor.state.selection\n return posToDOMRect(view, from, to)\n }\n const createActionContext = (\n trigger: HTMLElement,\n defaultAction: () => void,\n ): BubbleMenuPresetActionContext => ({\n editor,\n element,\n trigger,\n getTriggerRect: () => trigger.getBoundingClientRect?.() ?? null,\n getMenuRect,\n getSelectionRect,\n closePopovers,\n defaultAction,\n })\n\n const runTextAction = (\n action: BubbleMenuPresetTextAction,\n trigger: HTMLElement,\n defaultAction: () => void,\n ) => {\n if (!opts.onTextAction) {\n defaultAction()\n return\n }\n opts.onTextAction(action, createActionContext(trigger, defaultAction))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n container: HTMLElement,\n item: BubbleMenuPresetItem,\n label: string,\n onClick: (trigger: HTMLElement) => void,\n opts: { disabled?: boolean; title?: string } = {},\n ) => {\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.className = `bs-bmp-btn bs-bmp-btn-${item}`\n btn.textContent = label\n if (opts.title) {\n btn.title = opts.title\n btn.setAttribute('aria-label', opts.title)\n }\n if (opts.disabled) {\n btn.disabled = true\n btn.classList.add('bs-bmp-disabled')\n } else {\n btn.addEventListener('click', () => {\n closePopovers()\n onClick(btn)\n })\n }\n container.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton(\n textToolbar,\n 'undo',\n DEFAULT_LABELS.undo,\n (trigger) =>\n runTextAction('undo', trigger, () => runWithFocus(() => runChainCommand('undo'))),\n {\n disabled: !hasUndo,\n title: 'Undo',\n },\n )\n addButton(\n textToolbar,\n 'redo',\n DEFAULT_LABELS.redo,\n (trigger) =>\n runTextAction('redo', trigger, () => runWithFocus(() => runChainCommand('redo'))),\n {\n disabled: !hasRedo,\n title: 'Redo',\n },\n )\n }\n\n const addFontFamily = () => {\n const hasCommand = typeof getCommand('setFontFamily') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Font family'\n opts.fonts.forEach((font) => {\n const option = document.createElement('option')\n option.value = font\n option.textContent = font\n option.style.fontFamily = font\n select.appendChild(option)\n })\n select.disabled = !hasCommand\n select.addEventListener('change', () => {\n runWithFocus(() => runChainCommand('setFontFamily', select.value))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n fontFamilySelect = select\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addFontSize = () => {\n const hasCommand = typeof getCommand('setFontSize') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Font size'\n opts.fontSizes.forEach((size) => {\n const option = document.createElement('option')\n option.value = size\n option.textContent = size\n select.appendChild(option)\n })\n select.disabled = !hasCommand\n select.addEventListener('change', () => {\n runWithFocus(() => runChainCommand('setFontSize', select.value))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n fontSizeSelect = select\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addToggleMark = (item: BubbleMenuPresetItem, commandName: string, title: string) => {\n const fn = getCommand(commandName) as (() => boolean) | undefined\n const disabled = typeof fn !== 'function'\n addButton(\n textToolbar,\n item,\n DEFAULT_LABELS[item],\n (trigger) =>\n runTextAction(item as BubbleMenuPresetTextAction, trigger, () =>\n runWithFocus(() => runChainCommand(commandName)),\n ),\n { disabled, title },\n )\n }\n\n const addTextColor = () => {\n const hasSet = typeof getCommand('setColor') === 'function'\n const hasUnset = typeof getCommand('unsetColor') === 'function'\n const { popover, toggle, destroy } = createColorPopover({\n label: DEFAULT_LABELS.textColor,\n title: 'Text color',\n colors: opts.textColors,\n onSelect: (color) => {\n if (!hasSet) return\n runWithFocus(() => runChainCommand('setColor', color))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (!hasUnset) return\n runWithFocus(() => runChainCommand('unsetColor'))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onToggle: () => editor.commands.setMeta?.('bubbleMenu', 'updatePosition'),\n })\n popovers.push(popover)\n cleanupFns.push(destroy)\n textToolbar.appendChild(toggle)\n textToolbar.appendChild(popover)\n }\n\n const addHighlightColor = () => {\n const hasToggle = typeof getCommand('toggleHighlight') === 'function'\n const hasUnset = typeof getCommand('unsetHighlight') === 'function'\n const { popover, toggle, destroy } = createColorPopover({\n label: DEFAULT_LABELS.highlightColor,\n title: 'Highlight color',\n colors: opts.highlightColors,\n onSelect: (color) => {\n if (!hasToggle) return\n runWithFocus(() => runChainCommand('toggleHighlight', { color }))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (!hasUnset) return\n runWithFocus(() => runChainCommand('unsetHighlight'))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onToggle: () => editor.commands.setMeta?.('bubbleMenu', 'updatePosition'),\n })\n popovers.push(popover)\n cleanupFns.push(destroy)\n textToolbar.appendChild(toggle)\n textToolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n const { popover: linkPopover, show: showLinkPopover } = createLinkPopover({\n getCurrentValue: () => editor.getAttributes('link')?.href ?? '',\n onSave: (href) => {\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(linkPopover)\n textToolbar.appendChild(linkPopover)\n addButton(\n textToolbar,\n 'link',\n DEFAULT_LABELS.link,\n (trigger) =>\n runTextAction('link', trigger, () => {\n showLinkPopover()\n }),\n { disabled: !hasToggle && !hasUnset, title: 'Insert link' },\n )\n }\n\n const addAlign = () => {\n const hasSet = typeof getCommand('setTextAlign') === 'function'\n const hasToggle = typeof getCommand('toggleTextAlign') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Align'\n opts.alignments.forEach((alignment) => {\n const option = document.createElement('option')\n option.value = alignment\n option.textContent = alignment.charAt(0).toUpperCase() + alignment.slice(1)\n select.appendChild(option)\n })\n select.disabled = !hasSet && !hasToggle\n select.addEventListener('change', () => {\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleTextAlign', select.value))\n } else if (hasSet) {\n runWithFocus(() => runChainCommand('setTextAlign', select.value))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addImageControls = () => {\n const addImageButton = (label: string, title: string, handler: () => void) => {\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.className = 'bs-bmp-btn bs-bmp-btn-image'\n btn.textContent = label\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.addEventListener('click', () => {\n closePopovers()\n handler()\n })\n imageToolbar.appendChild(btn)\n return btn\n }\n\n const replaceImageSource = (next: string) => {\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockMetadata === 'function') {\n runner.setImageBlockMetadata({ src: next }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { src: next }).run?.()\n } else if (typeof runner?.replaceImageBlock === 'function') {\n runner.replaceImageBlock({ src: next }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n }\n\n const { popover: replacePopover, show: showReplacePopover } = createReplacePopover({\n getCurrentValue: () => (getImageAttrs().src as string) ?? '',\n onSave: (next) => {\n replaceImageSource(next)\n },\n })\n popovers.push(replacePopover)\n imageToolbar.appendChild(replacePopover)\n const replaceButton = addImageButton('Replace', 'Replace image', () => {\n const defaultAction = () => showReplacePopover()\n if (!opts.onImageReplace) {\n defaultAction()\n return\n }\n opts.onImageReplace({\n ...createActionContext(replaceButton, defaultAction),\n getCurrentValue: () => (getImageAttrs().src as string) ?? '',\n replaceWith: replaceImageSource,\n showDefaultPopover: defaultAction,\n })\n })\n\n const alignWrapper = document.createElement('div')\n alignWrapper.className = 'bs-bmp-select'\n const alignSelect = document.createElement('select')\n alignSelect.className = 'bs-bmp-select-input'\n alignSelect.title = 'Align image'\n ;['left', 'center', 'right'].forEach((alignment) => {\n const option = document.createElement('option')\n option.value = alignment\n option.textContent = alignment.charAt(0).toUpperCase() + alignment.slice(1)\n alignSelect.appendChild(option)\n })\n alignSelect.addEventListener('change', () => {\n const value = alignSelect.value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockAlignment === 'function') {\n runner.setImageBlockAlignment(value).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { align: value }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n alignWrapper.appendChild(alignSelect)\n imageToolbar.appendChild(alignWrapper)\n imageAlignSelect = alignSelect\n\n const displayWrapper = document.createElement('div')\n displayWrapper.className = 'bs-bmp-select'\n const displaySelect = document.createElement('select')\n displaySelect.className = 'bs-bmp-select-input'\n displaySelect.title = 'Image fit'\n ;['default', 'cover', 'contain', 'fill'].forEach((mode) => {\n const option = document.createElement('option')\n option.value = mode\n option.textContent = mode.charAt(0).toUpperCase() + mode.slice(1)\n displaySelect.appendChild(option)\n })\n displaySelect.addEventListener('change', () => {\n const value = displaySelect.value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockLayout === 'function') {\n if (value === 'cover' && typeof runner?.setImageBlockFullBleed === 'function') {\n runner.setImageBlockFullBleed(true)\n }\n runner.setImageBlockLayout(value === 'default' ? 'cover' : value).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { display: value }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n displayWrapper.appendChild(displaySelect)\n imageToolbar.appendChild(displayWrapper)\n imageDisplaySelect = displaySelect\n\n addImageButton('Full width', 'Set image width to 100%', () => {\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockDimensions === 'function') {\n runner.setImageBlockDimensions({ width: '100%', height: null }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { width: '100%', height: null }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n\n const { popover: altPopover, show: showAltPopover } = createAltPopover({\n getCurrentValue: () => (getImageAttrs().alt as string) ?? '',\n onSave: (next) => {\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockMetadata === 'function') {\n runner.setImageBlockMetadata({ alt: next }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { alt: next }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(altPopover)\n imageToolbar.appendChild(altPopover)\n addImageButton('Alt', 'Set alt text', () => {\n closePopovers()\n showAltPopover()\n })\n\n addImageButton('Delete', 'Delete image', () => {\n editor.chain().focus().deleteSelection().run()\n })\n }\n\n // Build in the order requested.\n opts.items.forEach((item) => {\n switch (item) {\n case 'undo':\n addUndoRedo()\n break\n case 'redo':\n // handled in undo block to keep buttons together; skip.\n break\n case 'fontFamily':\n addFontFamily()\n break\n case 'fontSize':\n addFontSize()\n break\n case 'bold':\n addToggleMark('bold', 'toggleBold', 'Bold')\n break\n case 'italic':\n addToggleMark('italic', 'toggleItalic', 'Italic')\n break\n case 'underline':\n addToggleMark('underline', 'toggleUnderline', 'Underline')\n break\n case 'textColor':\n addTextColor()\n break\n case 'highlightColor':\n addHighlightColor()\n break\n case 'link':\n addLink()\n break\n case 'align':\n addAlign()\n break\n default:\n break\n }\n })\n\n addImageControls()\n\n element.appendChild(textToolbar)\n element.appendChild(imageToolbar)\n\n const syncSelectionState = () => {\n if (isImageSelection()) return\n const attrs = editor.getAttributes('textStyle') || {}\n let family = attrs.fontFamily\n let size = attrs.fontSize\n\n // If not explicitly set via marks, fall back to computed DOM styles\n if (!family || !size) {\n const computed = getComputedFontStyles()\n family = family || computed.fontFamily\n size = size || computed.fontSize\n }\n\n setSelectValue(fontFamilySelect, normalizeFontFamily(family))\n setSelectValue(fontSizeSelect, size)\n }\n\n const syncImageState = () => {\n if (!isImageSelection()) return\n const attrs = getImageAttrs()\n const fitValue = editor.isActive('imageBlock')\n ? (attrs.layout as string | undefined) || 'cover'\n : (attrs.display as string | undefined) || 'default'\n setSelectValue(imageAlignSelect, attrs.align as string | undefined)\n setSelectValue(imageDisplaySelect, fitValue)\n }\n\n const syncToolbarVisibility = () => {\n const imageVisible = isImageSelection()\n textToolbar.style.display = imageVisible ? 'none' : ''\n imageToolbar.style.display = imageVisible ? '' : 'none'\n }\n\n const handleSelectionUpdate = () => {\n syncToolbarVisibility()\n syncSelectionState()\n syncImageState()\n }\n const handleTransaction = ({ transaction }: { transaction?: any }) => {\n if (!transaction || transaction.docChanged || transaction.selectionSet) {\n handleSelectionUpdate()\n }\n }\n\n editor.on('selectionUpdate', handleSelectionUpdate)\n editor.on('transaction', handleTransaction)\n cleanupFns.push(() => {\n editor.off('selectionUpdate', handleSelectionUpdate)\n editor.off('transaction', handleTransaction)\n })\n\n syncToolbarVisibility()\n syncSelectionState()\n syncImageState()\n\n return {\n element,\n cleanup: () => {\n popovers.forEach((p) => p.remove())\n cleanupFns.forEach((fn) => fn())\n element.replaceChildren()\n },\n }\n}\n\nfunction createColorPopover(args: {\n label: string\n title: string\n colors: string[]\n onSelect: (color: string) => void\n onClear: () => void\n onToggle?: () => void\n}): { toggle: HTMLElement; popover: HTMLElement; destroy: () => void } {\n const toggle = document.createElement('button')\n toggle.type = 'button'\n toggle.className = 'bs-bmp-btn bs-bmp-btn-color'\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\n toggle.setAttribute('aria-label', args.title)\n if (args.label === DEFAULT_LABELS.textColor && ICONS.textColor) {\n toggle.innerHTML = ICONS.textColor\n } else if (args.label === DEFAULT_LABELS.highlightColor && ICONS.highlightColor) {\n toggle.innerHTML = ICONS.highlightColor\n } else {\n toggle.textContent = args.label\n }\n\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-hidden'\n popover.setAttribute('role', 'menu')\n\n const header = document.createElement('div')\n header.className = 'bs-bmp-popover-header'\n const noneBtn = document.createElement('button')\n noneBtn.type = 'button'\n noneBtn.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n noneBtn.textContent = 'None'\n noneBtn.addEventListener('click', () => {\n args.onClear()\n hide()\n })\n header.appendChild(noneBtn)\n popover.appendChild(header)\n\n const grid = document.createElement('div')\n grid.className = 'bs-bmp-color-grid'\n const columns = 10\n grid.style.setProperty('--bs-bmp-grid-columns', String(columns))\n\n args.colors.forEach((color) => {\n const swatch = document.createElement('button')\n swatch.type = 'button'\n swatch.className = 'bs-bmp-color-swatch'\n swatch.style.backgroundColor = color\n swatch.setAttribute('aria-label', color)\n swatch.addEventListener('click', (event) => {\n event.stopPropagation()\n args.onSelect(color)\n hide()\n })\n grid.appendChild(swatch)\n })\n\n popover.appendChild(grid)\n\n const customRow = document.createElement('div')\n customRow.className = 'bs-bmp-popover-footer'\n const customLabel = document.createElement('span')\n customLabel.textContent = 'Custom'\n const customInput = document.createElement('input')\n customInput.type = 'color'\n customInput.className = 'bs-bmp-color-input'\n customInput.addEventListener('input', () => {\n args.onSelect(customInput.value)\n })\n customRow.appendChild(customLabel)\n customRow.appendChild(customInput)\n popover.appendChild(customRow)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n toggle.setAttribute('aria-expanded', 'false')\n args.onToggle?.()\n }\n\n const show = () => {\n popover.classList.remove('bs-bmp-hidden')\n toggle.setAttribute('aria-expanded', 'true')\n args.onToggle?.()\n }\n\n const toggleHandler = (event: MouseEvent) => {\n event.stopPropagation()\n if (popover.classList.contains('bs-bmp-hidden')) {\n show()\n } else {\n hide()\n }\n }\n toggle.addEventListener('click', toggleHandler)\n\n const outsideHandler = (event: MouseEvent) => {\n if (popover.contains(event.target as Node) || toggle.contains(event.target as Node)) {\n return\n }\n hide()\n }\n\n document.addEventListener(\n 'click',\n outsideHandler,\n { capture: true },\n )\n\n const destroy = () => {\n document.removeEventListener('click', outsideHandler, { capture: true } as any)\n toggle.removeEventListener('click', toggleHandler)\n }\n\n return { toggle, popover, destroy }\n}\n\nfunction createAltPopover(args: { getCurrentValue: () => string; onSave: (value: string) => void }) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-alt bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'text'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'Describe the image'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Save'\n save.addEventListener('click', () => {\n args.onSave(input.value.trim())\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => popover.classList.add('bs-bmp-hidden')\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction createLinkPopover(args: {\n getCurrentValue: () => string\n onSave: (value: string) => void\n onClear: () => void\n}) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-link bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'url'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'https://...'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const remove = document.createElement('button')\n remove.type = 'button'\n remove.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n remove.textContent = 'Remove'\n remove.addEventListener('click', () => {\n args.onClear()\n hide()\n })\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Save'\n save.addEventListener('click', () => {\n const val = input.value.trim()\n if (!val) return\n args.onSave(val)\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(remove)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n popover.style.display = 'none'\n }\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction createReplacePopover(args: { getCurrentValue: () => string; onSave: (value: string) => void }) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-replace bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'url'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'https://...'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Replace'\n save.addEventListener('click', () => {\n const val = input.value.trim()\n if (!val) return\n args.onSave(val)\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n popover.style.display = 'none'\n }\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction injectStyles() {\n if (typeof document === 'undefined') return\n if (document.getElementById(STYLE_ID)) return\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = `\n.bs-bubble-menu-preset {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n padding: 8px 10px;\n border-radius: 10px;\n box-shadow: 0 10px 30px rgba(0,0,0,0.12);\n color: #111827;\n font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n z-index: 9999;\n}\n.bs-bmp-toolbar {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.bs-bmp-btn {\n border: none;\n background: transparent;\n color: inherit;\n padding: 6px 8px;\n border-radius: 12px;\n cursor: pointer;\n font-size: 13px;\n line-height: 1;\n transition: background-color 120ms ease, color 120ms ease, box-shadow 120ms ease;\n}\n.bs-bmp-btn:hover {\n background: #f3f4f6;\n}\n.bs-bmp-btn:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.bs-bmp-select {\n display: inline-flex;\n align-items: center;\n}\n.bs-bmp-select-input {\n border: 1px solid #e5e7eb;\n background: #ffffff;\n color: inherit;\n padding: 6px 12px 6px 10px;\n border-radius: 12px;\n font-size: 13px;\n outline: none;\n}\n.bs-bmp-select-input:focus {\n border-color: #4f46e5;\n box-shadow: 0 0 0 2px rgba(79,70,229,0.15);\n}\n.bs-bmp-popover {\n position: absolute;\n margin-top: 6px;\n padding: 10px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.18);\n z-index: 999;\n}\n.bs-bmp-hidden {\n display: none !important;\n}\n.bs-bmp-popover-header,\n.bs-bmp-popover-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n}\n.bs-bmp-btn-ghost {\n background: transparent;\n border: none;\n color: inherit;\n padding: 4px 6px;\n border-radius: 8px;\n cursor: pointer;\n}\n.bs-bmp-btn-ghost:hover {\n background: #f3f4f6;\n}\n.bs-bmp-color-grid {\n display: grid;\n grid-template-columns: repeat(var(--bs-bmp-grid-columns, 10), 22px);\n gap: 4px;\n margin-bottom: 8px;\n}\n.bs-bmp-color-swatch {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: 1px solid #e5e7eb;\n cursor: pointer;\n padding: 0;\n}\n.bs-bmp-color-swatch:hover {\n outline: 2px solid #4f46e5;\n outline-offset: 2px;\n}\n.bs-bmp-color-input {\n width: 32px;\n height: 28px;\n padding: 0;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n}\n .bs-bmp-popover-alt,\n .bs-bmp-popover-replace,\n .bs-bmp-popover-link {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 260px;\n}\n.bs-bmp-text-input {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n font-size: 13px;\n}\n.bs-bmp-popover-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n`\n\n document.head.appendChild(style)\n}\n\n\n\n\n\n"],"mappings":"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","names":["_a","opts"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/bubble-menu-preset.ts"],"sourcesContent":["export * from './bubble-menu-preset.js'\nexport { BubbleMenuPreset as default } from './bubble-menu-preset.js'\n\n\n\n\n","import { Extension, isNodeSelection, isTextSelection, posToDOMRect } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\nimport { NodeSelection } from '@blockslides/pm/state'\n\ntype BubbleMenuPresetItem =\n | 'undo'\n | 'redo'\n | 'fontFamily'\n | 'fontSize'\n | 'bold'\n | 'italic'\n | 'underline'\n | 'textColor'\n | 'highlightColor'\n | 'link'\n | 'align'\n\ntype TextAlignValue = 'left' | 'center' | 'right' | 'justify'\n\nexport type BubbleMenuPresetTextAction = 'undo' | 'redo' | 'bold' | 'italic' | 'underline' | 'link'\n\nexport interface BubbleMenuPresetActionContext {\n editor: Editor\n element: HTMLElement\n trigger: HTMLElement\n getTriggerRect: () => DOMRect | null\n getMenuRect: () => DOMRect | null\n getSelectionRect: () => DOMRect | null\n closePopovers: () => void\n defaultAction: () => void\n}\n\nexport interface BubbleMenuPresetImageReplaceContext extends BubbleMenuPresetActionContext {\n getCurrentValue: () => string\n replaceWith: (value: string) => void\n showDefaultPopover: () => void\n}\n\nexport interface BubbleMenuPresetOptions\n extends Omit<BubbleMenuOptions, 'element'> {\n /**\n * Optional custom element to use for the menu. If omitted, a default\n * element with built-in buttons is rendered.\n */\n element?: HTMLElement | null\n\n /**\n * Order of built-in controls to render.\n */\n items?: BubbleMenuPresetItem[]\n\n /**\n * Additional class names to attach to the menu element to allow easy\n * style overrides.\n */\n className?: string\n\n /**\n * Inject default CSS. Set to false to opt out if you provide your own styles.\n */\n injectStyles?: boolean\n\n /**\n * Palette for text color swatches.\n */\n textColors?: string[]\n\n /**\n * Palette for highlight swatches.\n */\n highlightColors?: string[]\n\n /**\n * Fonts exposed in the font picker.\n */\n fonts?: string[]\n\n /**\n * Font sizes (any CSS length, e.g. \"16px\", \"1rem\").\n */\n fontSizes?: string[]\n\n /**\n * Alignments to expose in the align control.\n */\n alignments?: TextAlignValue[]\n\n /**\n * Override text button actions (undo/redo/bold/italic/underline/link).\n * Use defaultAction() to fall back to built-in behavior.\n */\n onTextAction?: (action: BubbleMenuPresetTextAction, ctx: BubbleMenuPresetActionContext) => void\n\n /**\n * Override image replace behavior (e.g., open your own picker).\n * Use showDefaultPopover() or replaceWith() to reuse built-in behavior.\n */\n onImageReplace?: (ctx: BubbleMenuPresetImageReplaceContext) => void\n}\n\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nexport const DEFAULT_ITEMS: BubbleMenuPresetItem[] = [\n 'undo',\n 'redo',\n 'fontFamily',\n 'fontSize',\n 'bold',\n 'italic',\n 'underline',\n 'textColor',\n 'highlightColor',\n 'link',\n 'align',\n]\n\nexport const DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nexport const DEFAULT_FONT_SIZES = [\n '12px',\n '14px',\n '16px',\n '18px',\n '20px',\n '24px',\n '32px',\n '40px',\n '48px',\n '56px',\n '64px',\n '72px',\n]\n\nexport const DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nexport const DEFAULT_COLOR_PALETTE: string[] = [\n '#000000',\n '#434343',\n '#666666',\n '#999999',\n '#b7b7b7',\n '#cccccc',\n '#d9d9d9',\n '#efefef',\n '#f3f3f3',\n '#ffffff',\n '#e60000',\n '#ff0000',\n '#ff9900',\n '#ffff00',\n '#00ff00',\n '#00ffff',\n '#4a86e8',\n '#0000ff',\n '#9900ff',\n '#ff00ff',\n '#f4cccc',\n '#fce5cd',\n '#fff2cc',\n '#d9ead3',\n '#d0e0e3',\n '#cfe2f3',\n '#d9d2e9',\n '#ead1dc',\n '#f9cb9c',\n '#ffe599',\n '#b6d7a8',\n '#a2c4c9',\n '#9fc5e8',\n '#b4a7d6',\n '#d5a6bd',\n '#e06666',\n '#f6b26b',\n '#ffd966',\n '#93c47d',\n '#76a5af',\n '#6fa8dc',\n '#8e7cc3',\n '#c27ba0',\n '#cc0000',\n '#e69138',\n '#f1c232',\n '#6aa84f',\n '#45818e',\n '#3d85c6',\n '#674ea7',\n '#a64d79',\n '#990000',\n '#b45f06',\n '#bf9000',\n '#38761d',\n '#134f5c',\n '#0b5394',\n '#351c75',\n '#741b47',\n '#660000',\n '#783f04',\n '#7f6000',\n '#274e13',\n '#0c343d',\n '#073763',\n '#20124d',\n '#4c1130',\n]\n\nexport const DEFAULT_HIGHLIGHT_PALETTE = DEFAULT_COLOR_PALETTE\n\nconst DEFAULT_LABELS: Record<BubbleMenuPresetItem, string> = {\n undo: 'Undo',\n redo: 'Redo',\n fontFamily: 'Font',\n fontSize: 'Size',\n bold: 'B',\n italic: 'I',\n underline: 'U',\n textColor: 'A',\n highlightColor: 'Hi',\n link: 'Link',\n align: 'Align',\n}\n\nconst ICONS = {\n textColor: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 20h14\"/><path d=\"M7 20l5-14 5 14\"/><path d=\"M10.7 14h2.6\"/></svg>`,\n highlightColor: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m11 18 2-2h6\"/><path d=\"m2 22 3-3h6l3-3-6-6-3 3v6z\"/><path d=\"M14 7l3-3 3 3-3 3z\"/></svg>`,\n}\n\ninterface MenuBuildResult {\n element: HTMLElement\n cleanup: Cleanup\n}\n\nexport const BubbleMenuPreset = Extension.create<BubbleMenuPresetOptions>({\n name: 'bubbleMenuPreset',\n\n addOptions() {\n return {\n element: null,\n items: DEFAULT_ITEMS,\n className: '',\n injectStyles: true,\n textColors: DEFAULT_COLOR_PALETTE,\n highlightColors: DEFAULT_HIGHLIGHT_PALETTE,\n fonts: DEFAULT_FONTS,\n fontSizes: DEFAULT_FONT_SIZES,\n alignments: DEFAULT_ALIGNMENTS,\n pluginKey: 'bubbleMenuPreset',\n updateDelay: 250,\n resizeDelay: 60,\n appendTo: undefined,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\n },\n shouldShow: ({ state, editor }) => {\n const { selection } = state\n const imageSelection =\n (selection instanceof NodeSelection &&\n ['image', 'imageBlock'].includes(selection.node.type.name)) ||\n editor.isActive('image') ||\n editor.isActive('imageBlock')\n\n if (imageSelection) return true\n if (isTextSelection(selection) && !selection.empty && !imageSelection) return true\n return false\n },\n }\n },\n\n addProseMirrorPlugins() {\n const options = this.options\n const editor = this.editor\n\n const usingCustomElement = !!options.element\n const { element, cleanup } =\n options.element && typeof document !== 'undefined'\n ? { element: options.element, cleanup: () => {} }\n : buildMenuElement(editor, {\n items: options.items ?? DEFAULT_ITEMS,\n className: options.className ?? '',\n injectStyles: options.injectStyles !== false,\n textColors: options.textColors ?? DEFAULT_COLOR_PALETTE,\n highlightColors: options.highlightColors ?? DEFAULT_HIGHLIGHT_PALETTE,\n fonts: options.fonts ?? DEFAULT_FONTS,\n fontSizes: options.fontSizes ?? DEFAULT_FONT_SIZES,\n alignments: options.alignments ?? DEFAULT_ALIGNMENTS,\n onTextAction: options.onTextAction,\n onImageReplace: options.onImageReplace,\n })\n\n this.storage.element = element\n this.storage.cleanup = cleanup\n this.storage.usingCustomElement = usingCustomElement\n\n const pluginOptions: BubbleMenuPluginProps = {\n pluginKey: options.pluginKey ?? 'bubbleMenuPreset',\n editor,\n element: element,\n updateDelay: options.updateDelay,\n resizeDelay: options.resizeDelay,\n appendTo: options.appendTo,\n options: options.options,\n getReferencedVirtualElement: options.getReferencedVirtualElement,\n shouldShow: options.shouldShow ?? undefined,\n }\n\n return [BubbleMenuPlugin(pluginOptions)]\n },\n\n onDestroy() {\n const el = this.storage.element as HTMLElement | undefined\n const cleanup = this.storage.cleanup as Cleanup | undefined\n const usingCustomElement = this.storage.usingCustomElement as boolean | undefined\n if (cleanup) {\n cleanup()\n }\n if (el && !usingCustomElement) {\n el.remove()\n }\n },\n})\n\nexport function buildMenuElement(\n editor: Editor,\n opts: {\n items: BubbleMenuPresetItem[]\n className: string\n injectStyles: boolean\n textColors: string[]\n highlightColors: string[]\n fonts: string[]\n fontSizes: string[]\n alignments: TextAlignValue[]\n onTextAction?: BubbleMenuPresetOptions['onTextAction']\n onImageReplace?: BubbleMenuPresetOptions['onImageReplace']\n },\n): MenuBuildResult {\n if (opts.injectStyles) {\n injectStyles()\n }\n\n const element = document.createElement('div')\n element.className = `bs-bubble-menu-preset ${opts.className ?? ''}`.trim()\n element.setAttribute('data-bubble-menu-preset', 'true')\n element.tabIndex = 0\n\n const textToolbar = document.createElement('div')\n textToolbar.className = 'bs-bmp-toolbar'\n\n const imageToolbar = document.createElement('div')\n imageToolbar.className = 'bs-bmp-toolbar bs-bmp-toolbar-image'\n\n let fontFamilySelect: HTMLSelectElement | null = null\n let fontSizeSelect: HTMLSelectElement | null = null\n let imageAlignSelect: HTMLSelectElement | null = null\n let imageDisplaySelect: HTMLSelectElement | null = null\n let imageCropSelect: HTMLSelectElement | null = null\n let imageWidthSelect: HTMLSelectElement | null = null\n\n const normalizeFontFamily = (value?: string | null) => {\n if (!value) return value\n // take the first family name and strip quotes\n return value.split(',')[0]?.trim().replace(/^['\"]|['\"]$/g, '') || value\n }\n\n const getComputedFontStyles = () => {\n if (typeof window === 'undefined') return { fontFamily: undefined, fontSize: undefined }\n const sel = window.getSelection()\n const node = sel?.anchorNode\n const el = (node instanceof HTMLElement ? node : node?.parentElement) ?? undefined\n if (!el) return { fontFamily: undefined, fontSize: undefined }\n const styles = window.getComputedStyle(el)\n return {\n fontFamily: normalizeFontFamily(styles.fontFamily || undefined),\n fontSize: styles.fontSize || undefined,\n }\n }\n\n const isImageSelection = () => {\n const sel = editor.state.selection\n if (sel instanceof NodeSelection) {\n return ['image', 'imageBlock'].includes(sel.node.type.name)\n }\n return editor.isActive('image') || editor.isActive('imageBlock')\n }\n\n const getImageAttrs = () => {\n const sel = editor.state.selection\n if (sel instanceof NodeSelection && ['image', 'imageBlock'].includes(sel.node.type.name)) {\n return sel.node.attrs || {}\n }\n if (editor.isActive('imageBlock')) return editor.getAttributes('imageBlock') || {}\n return editor.getAttributes('image') || {}\n }\n\n const ensureOptionExists = (select: HTMLSelectElement, value: string) => {\n const exists = Array.from(select.options).some(opt => opt.value === value)\n if (!exists) {\n const option = document.createElement('option')\n option.value = value\n option.textContent = value\n select.appendChild(option)\n }\n }\n\n const setSelectValue = (select: HTMLSelectElement | null, value?: string | null) => {\n if (!select) return\n if (!value) {\n select.selectedIndex = -1\n return\n }\n ensureOptionExists(select, value)\n select.value = value\n }\n\n const popovers: HTMLElement[] = []\n const cleanupFns: Cleanup[] = []\n\n const getCommand = (name: string): any => (editor.commands as any)?.[name]\n const runChainCommand = (name: string, ...args: any[]) => {\n const chain = (editor.chain as any)?.()\n if (!chain || typeof chain[name] !== 'function') return false\n const runner = typeof chain.focus === 'function' ? chain.focus() : chain\n if (typeof runner[name] !== 'function') return false\n return runner[name](...args).run?.() ?? false\n }\n\n const closePopovers = () => {\n popovers.forEach((p) => {\n p.classList.add('bs-bmp-hidden')\n p.style.display = 'none'\n })\n }\n\n const getMenuRect = () => element.getBoundingClientRect?.() ?? null\n const getSelectionRect = () => {\n const view = (editor as any).view\n if (!view) return null\n const { from, to } = editor.state.selection\n return posToDOMRect(view, from, to)\n }\n const createActionContext = (\n trigger: HTMLElement,\n defaultAction: () => void,\n ): BubbleMenuPresetActionContext => ({\n editor,\n element,\n trigger,\n getTriggerRect: () => trigger.getBoundingClientRect?.() ?? null,\n getMenuRect,\n getSelectionRect,\n closePopovers,\n defaultAction,\n })\n\n const runTextAction = (\n action: BubbleMenuPresetTextAction,\n trigger: HTMLElement,\n defaultAction: () => void,\n ) => {\n if (!opts.onTextAction) {\n defaultAction()\n return\n }\n opts.onTextAction(action, createActionContext(trigger, defaultAction))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n container: HTMLElement,\n item: BubbleMenuPresetItem,\n label: string,\n onClick: (trigger: HTMLElement) => void,\n opts: { disabled?: boolean; title?: string } = {},\n ) => {\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.className = `bs-bmp-btn bs-bmp-btn-${item}`\n btn.textContent = label\n if (opts.title) {\n btn.title = opts.title\n btn.setAttribute('aria-label', opts.title)\n }\n if (opts.disabled) {\n btn.disabled = true\n btn.classList.add('bs-bmp-disabled')\n } else {\n btn.addEventListener('click', () => {\n closePopovers()\n onClick(btn)\n })\n }\n container.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton(\n textToolbar,\n 'undo',\n DEFAULT_LABELS.undo,\n (trigger) =>\n runTextAction('undo', trigger, () => runWithFocus(() => runChainCommand('undo'))),\n {\n disabled: !hasUndo,\n title: 'Undo',\n },\n )\n addButton(\n textToolbar,\n 'redo',\n DEFAULT_LABELS.redo,\n (trigger) =>\n runTextAction('redo', trigger, () => runWithFocus(() => runChainCommand('redo'))),\n {\n disabled: !hasRedo,\n title: 'Redo',\n },\n )\n }\n\n const addFontFamily = () => {\n const hasCommand = typeof getCommand('setFontFamily') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Font family'\n opts.fonts.forEach((font) => {\n const option = document.createElement('option')\n option.value = font\n option.textContent = font\n option.style.fontFamily = font\n select.appendChild(option)\n })\n select.disabled = !hasCommand\n select.addEventListener('change', () => {\n runWithFocus(() => runChainCommand('setFontFamily', select.value))\n if (editor.view?.state) {\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n }\n })\n fontFamilySelect = select\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addFontSize = () => {\n const hasCommand = typeof getCommand('setFontSize') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Font size'\n opts.fontSizes.forEach((size) => {\n const option = document.createElement('option')\n option.value = size\n option.textContent = size\n select.appendChild(option)\n })\n select.disabled = !hasCommand\n select.addEventListener('change', () => {\n runWithFocus(() => runChainCommand('setFontSize', select.value))\n if (editor.view?.state) {\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n }\n })\n fontSizeSelect = select\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addToggleMark = (item: BubbleMenuPresetItem, commandName: string, title: string) => {\n const fn = getCommand(commandName) as (() => boolean) | undefined\n const disabled = typeof fn !== 'function'\n addButton(\n textToolbar,\n item,\n DEFAULT_LABELS[item],\n (trigger) =>\n runTextAction(item as BubbleMenuPresetTextAction, trigger, () =>\n runWithFocus(() => runChainCommand(commandName)),\n ),\n { disabled, title },\n )\n }\n\n const addTextColor = () => {\n const hasSet = typeof getCommand('setColor') === 'function'\n const hasUnset = typeof getCommand('unsetColor') === 'function'\n const { popover, toggle, destroy } = createColorPopover({\n label: DEFAULT_LABELS.textColor,\n title: 'Text color',\n colors: opts.textColors,\n onSelect: (color) => {\n if (!hasSet) return\n runWithFocus(() => runChainCommand('setColor', color))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (!hasUnset) return\n runWithFocus(() => runChainCommand('unsetColor'))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onToggle: () => {\n console.log('[bubbleMenuPreset onToggle]', {\n editorDestroyed: (editor as any)?.isDestroyed,\n hasSelection: !!editor.state?.selection,\n })\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(popover)\n cleanupFns.push(destroy)\n textToolbar.appendChild(toggle)\n textToolbar.appendChild(popover)\n }\n\n const addHighlightColor = () => {\n const hasToggle = typeof getCommand('toggleHighlight') === 'function'\n const hasUnset = typeof getCommand('unsetHighlight') === 'function'\n const { popover, toggle, destroy } = createColorPopover({\n label: DEFAULT_LABELS.highlightColor,\n title: 'Highlight color',\n colors: opts.highlightColors,\n onSelect: (color) => {\n if (!hasToggle) return\n runWithFocus(() => runChainCommand('toggleHighlight', { color }))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (!hasUnset) return\n runWithFocus(() => runChainCommand('unsetHighlight'))\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onToggle: () => {\n console.log('[bubbleMenuPreset onToggle]', {\n editorDestroyed: (editor as any)?.isDestroyed,\n hasSelection: !!editor.state?.selection,\n })\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(popover)\n cleanupFns.push(destroy)\n textToolbar.appendChild(toggle)\n textToolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n const { popover: linkPopover, show: showLinkPopover } = createLinkPopover({\n getCurrentValue: () => editor.getAttributes('link')?.href ?? '',\n onSave: (href) => {\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n onClear: () => {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(linkPopover)\n textToolbar.appendChild(linkPopover)\n addButton(\n textToolbar,\n 'link',\n DEFAULT_LABELS.link,\n (trigger) =>\n runTextAction('link', trigger, () => {\n showLinkPopover()\n }),\n { disabled: !hasToggle && !hasUnset, title: 'Insert link' },\n )\n }\n\n const addAlign = () => {\n const hasSet = typeof getCommand('setTextAlign') === 'function'\n const hasToggle = typeof getCommand('toggleTextAlign') === 'function'\n const wrapper = document.createElement('div')\n wrapper.className = 'bs-bmp-select'\n const select = document.createElement('select')\n select.className = 'bs-bmp-select-input'\n select.title = 'Align'\n opts.alignments.forEach((alignment) => {\n const option = document.createElement('option')\n option.value = alignment\n option.textContent = alignment.charAt(0).toUpperCase() + alignment.slice(1)\n select.appendChild(option)\n })\n select.disabled = !hasSet && !hasToggle\n select.addEventListener('change', () => {\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleTextAlign', select.value))\n } else if (hasSet) {\n runWithFocus(() => runChainCommand('setTextAlign', select.value))\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n wrapper.appendChild(select)\n textToolbar.appendChild(wrapper)\n }\n\n const addImageControls = () => {\n const addImageButton = (label: string, title: string, handler: () => void) => {\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.className = 'bs-bmp-btn bs-bmp-btn-image'\n btn.textContent = label\n btn.title = title\n btn.setAttribute('aria-label', title)\n btn.addEventListener('click', () => {\n closePopovers()\n handler()\n })\n imageToolbar.appendChild(btn)\n return btn\n }\n\n const replaceImageSource = (next: string) => {\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockMetadata === 'function') {\n runner.setImageBlockMetadata({ src: next }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { src: next }).run?.()\n } else if (typeof runner?.replaceImageBlock === 'function') {\n runner.replaceImageBlock({ src: next }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n }\n\n const { popover: replacePopover, show: showReplacePopover } = createReplacePopover({\n getCurrentValue: () => (getImageAttrs().src as string) ?? '',\n onSave: (next) => {\n replaceImageSource(next)\n },\n })\n popovers.push(replacePopover)\n imageToolbar.appendChild(replacePopover)\n const replaceButton = addImageButton('Replace', 'Replace image', () => {\n const defaultAction = () => showReplacePopover()\n if (!opts.onImageReplace) {\n defaultAction()\n return\n }\n opts.onImageReplace({\n ...createActionContext(replaceButton, defaultAction),\n getCurrentValue: () => (getImageAttrs().src as string) ?? '',\n replaceWith: replaceImageSource,\n showDefaultPopover: defaultAction,\n })\n })\n\n const alignWrapper = document.createElement('div')\n alignWrapper.className = 'bs-bmp-select bs-bmp-labeled-select'\n const alignLabel = document.createElement('label')\n alignLabel.className = 'bs-bmp-select-label'\n alignLabel.textContent = 'Align:'\n const alignSelect = document.createElement('select')\n alignSelect.className = 'bs-bmp-select-input'\n alignSelect.title = 'Image alignment'\n ;['left', 'center', 'right'].forEach((alignment) => {\n const option = document.createElement('option')\n option.value = alignment\n option.textContent = alignment.charAt(0).toUpperCase() + alignment.slice(1)\n alignSelect.appendChild(option)\n })\n alignSelect.addEventListener('change', () => {\n const value = alignSelect.value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockAlignment === 'function') {\n runner.setImageBlockAlignment(value).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { align: value }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n alignWrapper.appendChild(alignLabel)\n alignWrapper.appendChild(alignSelect)\n imageToolbar.appendChild(alignWrapper)\n imageAlignSelect = alignSelect\n\n const displayWrapper = document.createElement('div')\n displayWrapper.className = 'bs-bmp-select bs-bmp-labeled-select'\n const displayLabel = document.createElement('label')\n displayLabel.className = 'bs-bmp-select-label'\n displayLabel.textContent = 'Fit:'\n const displaySelect = document.createElement('select')\n displaySelect.className = 'bs-bmp-select-input'\n displaySelect.title = 'Image size mode'\n const sizeOptions = [\n { value: 'fill', label: 'Cover' },\n { value: 'fit', label: 'Contain' },\n { value: 'natural', label: 'Original' }\n ]\n sizeOptions.forEach(({ value, label }) => {\n const option = document.createElement('option')\n option.value = value\n option.textContent = label\n displaySelect.appendChild(option)\n })\n displaySelect.addEventListener('change', () => {\n const value = displaySelect.value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockSize === 'function') {\n runner.setImageBlockSize(value).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { size: value }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n displayWrapper.appendChild(displayLabel)\n displayWrapper.appendChild(displaySelect)\n imageToolbar.appendChild(displayWrapper)\n imageDisplaySelect = displaySelect\n\n const cropWrapper = document.createElement('div')\n cropWrapper.className = 'bs-bmp-select bs-bmp-labeled-select'\n const cropLabel = document.createElement('label')\n cropLabel.className = 'bs-bmp-select-label'\n cropLabel.textContent = 'Position:'\n const cropSelect = document.createElement('select')\n cropSelect.className = 'bs-bmp-select-input'\n cropSelect.title = 'Focal position'\n ;['center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'].forEach((position) => {\n const option = document.createElement('option')\n option.value = position\n option.textContent = position.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')\n cropSelect.appendChild(option)\n })\n cropSelect.addEventListener('change', () => {\n const value = cropSelect.value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockCrop === 'function') {\n runner.setImageBlockCrop(value).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { crop: value }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n cropWrapper.appendChild(cropLabel)\n cropWrapper.appendChild(cropSelect)\n imageToolbar.appendChild(cropWrapper)\n imageCropSelect = cropSelect\n\n const widthWrapper = document.createElement('div')\n widthWrapper.className = 'bs-bmp-select bs-bmp-labeled-select'\n const widthLabel = document.createElement('label')\n widthLabel.className = 'bs-bmp-select-label'\n widthLabel.textContent = 'Width:'\n const widthSelect = document.createElement('select')\n widthSelect.className = 'bs-bmp-select-input'\n widthSelect.title = 'Image width'\n const widthOptions = [\n { value: 'auto', label: 'Auto' },\n { value: '25%', label: '25%' },\n { value: '33%', label: '33%' },\n { value: '50%', label: '50%' },\n { value: '66%', label: '66%' },\n { value: '75%', label: '75%' },\n { value: '100%', label: '100%' }\n ]\n widthOptions.forEach(({ value, label }) => {\n const option = document.createElement('option')\n option.value = value\n option.textContent = label\n widthSelect.appendChild(option)\n })\n widthSelect.addEventListener('change', () => {\n const value = widthSelect.value\n const width = value === 'auto' ? null : value\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockDimensions === 'function') {\n runner.setImageBlockDimensions({ width, height: null }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { width, height: null }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n })\n widthWrapper.appendChild(widthLabel)\n widthWrapper.appendChild(widthSelect)\n imageToolbar.appendChild(widthWrapper)\n imageWidthSelect = widthSelect\n\n const { popover: altPopover, show: showAltPopover } = createAltPopover({\n getCurrentValue: () => (getImageAttrs().alt as string) ?? '',\n onSave: (next) => {\n const chain = (editor.chain as any)?.()\n const runner = typeof chain?.focus === 'function' ? chain.focus() : chain\n if (editor.isActive('imageBlock') && typeof runner?.setImageBlockMetadata === 'function') {\n runner.setImageBlockMetadata({ alt: next }).run?.()\n } else if (typeof runner?.updateAttributes === 'function') {\n runner.updateAttributes('image', { alt: next }).run?.()\n }\n editor.commands.setMeta?.('bubbleMenu', 'updatePosition')\n },\n })\n popovers.push(altPopover)\n imageToolbar.appendChild(altPopover)\n addImageButton('Alt', 'Set alt text', () => {\n closePopovers()\n showAltPopover()\n })\n\n addImageButton('Delete', 'Delete image', () => {\n editor.chain().focus().deleteSelection().run()\n })\n }\n\n // Build in the order requested.\n opts.items.forEach((item) => {\n switch (item) {\n case 'undo':\n addUndoRedo()\n break\n case 'redo':\n // handled in undo block to keep buttons together; skip.\n break\n case 'fontFamily':\n addFontFamily()\n break\n case 'fontSize':\n addFontSize()\n break\n case 'bold':\n addToggleMark('bold', 'toggleBold', 'Bold')\n break\n case 'italic':\n addToggleMark('italic', 'toggleItalic', 'Italic')\n break\n case 'underline':\n addToggleMark('underline', 'toggleUnderline', 'Underline')\n break\n case 'textColor':\n addTextColor()\n break\n case 'highlightColor':\n addHighlightColor()\n break\n case 'link':\n addLink()\n break\n case 'align':\n addAlign()\n break\n default:\n break\n }\n })\n\n addImageControls()\n\n element.appendChild(textToolbar)\n element.appendChild(imageToolbar)\n\n const syncSelectionState = () => {\n if (isImageSelection()) return\n const attrs = editor.getAttributes('textStyle') || {}\n let family = attrs.fontFamily\n let size = attrs.fontSize\n\n // If not explicitly set via marks, fall back to computed DOM styles\n if (!family || !size) {\n const computed = getComputedFontStyles()\n family = family || computed.fontFamily\n size = size || computed.fontSize\n }\n\n setSelectValue(fontFamilySelect, normalizeFontFamily(family))\n setSelectValue(fontSizeSelect, size)\n }\n\n const syncImageState = () => {\n if (!isImageSelection()) return\n const attrs = getImageAttrs()\n const sizeValue = (attrs.size as string | undefined) || 'fill'\n const cropValue = (attrs.crop as string | undefined) || 'center'\n const widthValue = (attrs.width as string | undefined) || 'auto'\n setSelectValue(imageAlignSelect, attrs.align as string | undefined)\n setSelectValue(imageDisplaySelect, sizeValue)\n setSelectValue(imageCropSelect, cropValue)\n setSelectValue(imageWidthSelect, widthValue)\n }\n\n const syncToolbarVisibility = () => {\n const imageVisible = isImageSelection()\n textToolbar.style.display = imageVisible ? 'none' : ''\n imageToolbar.style.display = imageVisible ? '' : 'none'\n }\n\n const handleSelectionUpdate = () => {\n syncToolbarVisibility()\n syncSelectionState()\n syncImageState()\n }\n const handleTransaction = ({ transaction }: { transaction?: any }) => {\n if (!transaction || transaction.docChanged || transaction.selectionSet) {\n handleSelectionUpdate()\n }\n }\n\n editor.on('selectionUpdate', handleSelectionUpdate)\n editor.on('transaction', handleTransaction)\n cleanupFns.push(() => {\n editor.off('selectionUpdate', handleSelectionUpdate)\n editor.off('transaction', handleTransaction)\n })\n\n syncToolbarVisibility()\n syncSelectionState()\n syncImageState()\n\n return {\n element,\n cleanup: () => {\n popovers.forEach((p) => p.remove())\n cleanupFns.forEach((fn) => fn())\n element.replaceChildren()\n },\n }\n}\n\nfunction createColorPopover(args: {\n label: string\n title: string\n colors: string[]\n onSelect: (color: string) => void\n onClear: () => void\n onToggle?: () => void\n}): { toggle: HTMLElement; popover: HTMLElement; destroy: () => void } {\n const toggle = document.createElement('button')\n toggle.type = 'button'\n toggle.className = 'bs-bmp-btn bs-bmp-btn-color'\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\n toggle.setAttribute('aria-label', args.title)\n if (args.label === DEFAULT_LABELS.textColor && ICONS.textColor) {\n toggle.innerHTML = ICONS.textColor\n } else if (args.label === DEFAULT_LABELS.highlightColor && ICONS.highlightColor) {\n toggle.innerHTML = ICONS.highlightColor\n } else {\n toggle.textContent = args.label\n }\n\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-hidden'\n popover.setAttribute('role', 'menu')\n\n const header = document.createElement('div')\n header.className = 'bs-bmp-popover-header'\n const noneBtn = document.createElement('button')\n noneBtn.type = 'button'\n noneBtn.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n noneBtn.textContent = 'None'\n noneBtn.addEventListener('click', () => {\n args.onClear()\n hide()\n })\n header.appendChild(noneBtn)\n popover.appendChild(header)\n\n const grid = document.createElement('div')\n grid.className = 'bs-bmp-color-grid'\n const columns = 10\n grid.style.setProperty('--bs-bmp-grid-columns', String(columns))\n\n args.colors.forEach((color) => {\n const swatch = document.createElement('button')\n swatch.type = 'button'\n swatch.className = 'bs-bmp-color-swatch'\n swatch.style.backgroundColor = color\n swatch.setAttribute('aria-label', color)\n swatch.addEventListener('click', (event) => {\n event.stopPropagation()\n args.onSelect(color)\n hide()\n })\n grid.appendChild(swatch)\n })\n\n popover.appendChild(grid)\n\n const customRow = document.createElement('div')\n customRow.className = 'bs-bmp-popover-footer'\n const customLabel = document.createElement('span')\n customLabel.textContent = 'Custom'\n const customInput = document.createElement('input')\n customInput.type = 'color'\n customInput.className = 'bs-bmp-color-input'\n customInput.addEventListener('input', () => {\n args.onSelect(customInput.value)\n })\n customRow.appendChild(customLabel)\n customRow.appendChild(customInput)\n popover.appendChild(customRow)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n toggle.setAttribute('aria-expanded', 'false')\n args.onToggle?.()\n }\n\n const show = () => {\n popover.classList.remove('bs-bmp-hidden')\n toggle.setAttribute('aria-expanded', 'true')\n args.onToggle?.()\n }\n\n const toggleHandler = (event: MouseEvent) => {\n event.stopPropagation()\n if (popover.classList.contains('bs-bmp-hidden')) {\n show()\n } else {\n hide()\n }\n }\n toggle.addEventListener('click', toggleHandler)\n\n const outsideHandler = (event: MouseEvent) => {\n if (popover.contains(event.target as Node) || toggle.contains(event.target as Node)) {\n return\n }\n hide()\n }\n\n document.addEventListener(\n 'click',\n outsideHandler,\n { capture: true },\n )\n\n const destroy = () => {\n document.removeEventListener('click', outsideHandler, { capture: true } as any)\n toggle.removeEventListener('click', toggleHandler)\n }\n\n return { toggle, popover, destroy }\n}\n\nfunction createAltPopover(args: { getCurrentValue: () => string; onSave: (value: string) => void }) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-alt bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'text'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'Describe the image'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Save'\n save.addEventListener('click', () => {\n args.onSave(input.value.trim())\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => popover.classList.add('bs-bmp-hidden')\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction createLinkPopover(args: {\n getCurrentValue: () => string\n onSave: (value: string) => void\n onClear: () => void\n}) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-link bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'url'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'https://...'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const remove = document.createElement('button')\n remove.type = 'button'\n remove.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n remove.textContent = 'Remove'\n remove.addEventListener('click', () => {\n args.onClear()\n hide()\n })\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Save'\n save.addEventListener('click', () => {\n const val = input.value.trim()\n if (!val) return\n args.onSave(val)\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(remove)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n popover.style.display = 'none'\n }\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction createReplacePopover(args: { getCurrentValue: () => string; onSave: (value: string) => void }) {\n const popover = document.createElement('div')\n popover.className = 'bs-bmp-popover bs-bmp-popover-replace bs-bmp-hidden'\n\n const input = document.createElement('input')\n input.type = 'url'\n input.className = 'bs-bmp-text-input'\n input.placeholder = 'https://...'\n popover.appendChild(input)\n\n const actions = document.createElement('div')\n actions.className = 'bs-bmp-popover-actions'\n\n const cancel = document.createElement('button')\n cancel.type = 'button'\n cancel.className = 'bs-bmp-btn bs-bmp-btn-ghost'\n cancel.textContent = 'Cancel'\n cancel.addEventListener('click', () => hide())\n\n const save = document.createElement('button')\n save.type = 'button'\n save.className = 'bs-bmp-btn'\n save.textContent = 'Replace'\n save.addEventListener('click', () => {\n const val = input.value.trim()\n if (!val) return\n args.onSave(val)\n hide()\n })\n\n actions.appendChild(cancel)\n actions.appendChild(save)\n popover.appendChild(actions)\n\n const hide = () => {\n popover.classList.add('bs-bmp-hidden')\n popover.style.display = 'none'\n }\n const show = () => {\n input.value = args.getCurrentValue()\n popover.classList.remove('bs-bmp-hidden')\n popover.style.display = ''\n input.focus()\n input.select()\n }\n\n input.addEventListener('keydown', (event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n save.click()\n }\n if (event.key === 'Escape') hide()\n })\n\n hide()\n return { popover, show, hide }\n}\n\nfunction injectStyles() {\n if (typeof document === 'undefined') return\n if (document.getElementById(STYLE_ID)) return\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = `\n.bs-bubble-menu-preset {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n padding: 8px 10px;\n border-radius: 10px;\n box-shadow: 0 10px 30px rgba(0,0,0,0.12);\n color: #111827;\n font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n z-index: 9999;\n}\n.bs-bmp-toolbar {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.bs-bmp-btn {\n border: none;\n background: transparent;\n color: inherit;\n padding: 6px 8px;\n border-radius: 12px;\n cursor: pointer;\n font-size: 13px;\n line-height: 1;\n transition: background-color 120ms ease, color 120ms ease, box-shadow 120ms ease;\n}\n.bs-bmp-btn:hover {\n background: #f3f4f6;\n}\n.bs-bmp-btn:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n.bs-bmp-select {\n display: inline-flex;\n align-items: center;\n}\n.bs-bmp-labeled-select {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n.bs-bmp-select-label {\n font-size: 12px;\n color: #6b7280;\n font-weight: 500;\n white-space: nowrap;\n}\n.bs-bmp-select-input {\n border: 1px solid #e5e7eb;\n background: #ffffff;\n color: inherit;\n padding: 6px 12px 6px 10px;\n border-radius: 12px;\n font-size: 13px;\n outline: none;\n}\n.bs-bmp-select-input:focus {\n border-color: #4f46e5;\n box-shadow: 0 0 0 2px rgba(79,70,229,0.15);\n}\n.bs-bmp-popover {\n position: absolute;\n margin-top: 6px;\n padding: 10px;\n background: #ffffff;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n box-shadow: 0 12px 40px rgba(15, 23, 42, 0.18);\n z-index: 999;\n}\n.bs-bmp-hidden {\n display: none !important;\n}\n.bs-bmp-popover-header,\n.bs-bmp-popover-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 6px;\n}\n.bs-bmp-btn-ghost {\n background: transparent;\n border: none;\n color: inherit;\n padding: 4px 6px;\n border-radius: 8px;\n cursor: pointer;\n}\n.bs-bmp-btn-ghost:hover {\n background: #f3f4f6;\n}\n.bs-bmp-color-grid {\n display: grid;\n grid-template-columns: repeat(var(--bs-bmp-grid-columns, 10), 22px);\n gap: 4px;\n margin-bottom: 8px;\n}\n.bs-bmp-color-swatch {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: 1px solid #e5e7eb;\n cursor: pointer;\n padding: 0;\n}\n.bs-bmp-color-swatch:hover {\n outline: 2px solid #4f46e5;\n outline-offset: 2px;\n}\n.bs-bmp-color-input {\n width: 32px;\n height: 28px;\n padding: 0;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n}\n .bs-bmp-popover-alt,\n .bs-bmp-popover-replace,\n .bs-bmp-popover-link {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 260px;\n}\n.bs-bmp-text-input {\n width: 100%;\n padding: 8px 10px;\n border: 1px solid #e5e7eb;\n border-radius: 10px;\n font-size: 13px;\n}\n.bs-bmp-popover-actions {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n}\n`\n\n document.head.appendChild(style)\n}\n\n\n\n\n\n"],"mappings":"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","names":["_a","opts"]}