@blockslides/extension-bubble-menu-preset 0.1.0 → 0.1.1
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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bubble-menu-preset.ts +1 -1
- package/src/index.ts +1 -0
package/dist/index.cjs
CHANGED
|
@@ -589,7 +589,7 @@ function injectStyles() {
|
|
|
589
589
|
background: #ffffff;
|
|
590
590
|
border: 1px solid #e5e7eb;
|
|
591
591
|
padding: 8px 10px;
|
|
592
|
-
border-radius:
|
|
592
|
+
border-radius: 10px;
|
|
593
593
|
box-shadow: 0 10px 30px rgba(0,0,0,0.12);
|
|
594
594
|
color: #111827;
|
|
595
595
|
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
package/dist/index.cjs.map
CHANGED
|
@@ -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","import { Extension } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\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 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\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nconst 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\nconst DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nconst DEFAULT_FONT_SIZES = ['12px', '14px', '16px', '18px', '20px', '24px', '32px', '40px']\n\nconst DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nconst 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\nconst 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\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 shouldShow: null,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\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 })\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\nfunction 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 },\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 toolbar = document.createElement('div')\n toolbar.className = 'bs-bmp-toolbar'\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) => p.classList.add('bs-bmp-hidden'))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n item: BubbleMenuPresetItem,\n label: string,\n onClick: () => 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()\n })\n }\n toolbar.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton('undo', DEFAULT_LABELS.undo, () => runWithFocus(() => runChainCommand('undo')), {\n disabled: !hasUndo,\n title: 'Undo',\n })\n addButton('redo', DEFAULT_LABELS.redo, () => runWithFocus(() => runChainCommand('redo')), {\n disabled: !hasRedo,\n title: 'Redo',\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 wrapper.appendChild(select)\n toolbar.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 wrapper.appendChild(select)\n toolbar.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 item,\n DEFAULT_LABELS[item],\n () => {\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 toolbar.appendChild(toggle)\n toolbar.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 toolbar.appendChild(toggle)\n toolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n addButton(\n 'link',\n DEFAULT_LABELS.link,\n () => {\n const currentHref = editor.getAttributes('link')?.href ?? ''\n const href = window.prompt('Link URL', currentHref)\n if (href === null) return\n if (!href) {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n return\n }\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\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 toolbar.appendChild(wrapper)\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 element.appendChild(toolbar)\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.textContent = args.label\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\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 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: 20%;\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}\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 8px;\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;\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`\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","import { Extension } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\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 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\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nconst 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\nconst DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nconst DEFAULT_FONT_SIZES = ['12px', '14px', '16px', '18px', '20px', '24px', '32px', '40px']\n\nconst DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nconst 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\nconst 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\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 shouldShow: null,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\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 })\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\nfunction 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 },\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 toolbar = document.createElement('div')\n toolbar.className = 'bs-bmp-toolbar'\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) => p.classList.add('bs-bmp-hidden'))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n item: BubbleMenuPresetItem,\n label: string,\n onClick: () => 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()\n })\n }\n toolbar.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton('undo', DEFAULT_LABELS.undo, () => runWithFocus(() => runChainCommand('undo')), {\n disabled: !hasUndo,\n title: 'Undo',\n })\n addButton('redo', DEFAULT_LABELS.redo, () => runWithFocus(() => runChainCommand('redo')), {\n disabled: !hasRedo,\n title: 'Redo',\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 wrapper.appendChild(select)\n toolbar.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 wrapper.appendChild(select)\n toolbar.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 item,\n DEFAULT_LABELS[item],\n () => {\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 toolbar.appendChild(toggle)\n toolbar.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 toolbar.appendChild(toggle)\n toolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n addButton(\n 'link',\n DEFAULT_LABELS.link,\n () => {\n const currentHref = editor.getAttributes('link')?.href ?? ''\n const href = window.prompt('Link URL', currentHref)\n if (href === null) return\n if (!href) {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n return\n }\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\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 toolbar.appendChild(wrapper)\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 element.appendChild(toolbar)\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.textContent = args.label\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\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 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}\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 8px;\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;\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`\n\n document.head.appendChild(style)\n}\n\n\n\n\n\n"],"mappings":"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","names":["_a","opts"]}
|
package/dist/index.js
CHANGED
|
@@ -564,7 +564,7 @@ function injectStyles() {
|
|
|
564
564
|
background: #ffffff;
|
|
565
565
|
border: 1px solid #e5e7eb;
|
|
566
566
|
padding: 8px 10px;
|
|
567
|
-
border-radius:
|
|
567
|
+
border-radius: 10px;
|
|
568
568
|
box-shadow: 0 10px 30px rgba(0,0,0,0.12);
|
|
569
569
|
color: #111827;
|
|
570
570
|
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bubble-menu-preset.ts"],"sourcesContent":["import { Extension } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\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 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\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nconst 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\nconst DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nconst DEFAULT_FONT_SIZES = ['12px', '14px', '16px', '18px', '20px', '24px', '32px', '40px']\n\nconst DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nconst 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\nconst 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\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 shouldShow: null,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\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 })\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\nfunction 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 },\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 toolbar = document.createElement('div')\n toolbar.className = 'bs-bmp-toolbar'\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) => p.classList.add('bs-bmp-hidden'))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n item: BubbleMenuPresetItem,\n label: string,\n onClick: () => 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()\n })\n }\n toolbar.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton('undo', DEFAULT_LABELS.undo, () => runWithFocus(() => runChainCommand('undo')), {\n disabled: !hasUndo,\n title: 'Undo',\n })\n addButton('redo', DEFAULT_LABELS.redo, () => runWithFocus(() => runChainCommand('redo')), {\n disabled: !hasRedo,\n title: 'Redo',\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 wrapper.appendChild(select)\n toolbar.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 wrapper.appendChild(select)\n toolbar.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 item,\n DEFAULT_LABELS[item],\n () => {\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 toolbar.appendChild(toggle)\n toolbar.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 toolbar.appendChild(toggle)\n toolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n addButton(\n 'link',\n DEFAULT_LABELS.link,\n () => {\n const currentHref = editor.getAttributes('link')?.href ?? ''\n const href = window.prompt('Link URL', currentHref)\n if (href === null) return\n if (!href) {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n return\n }\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\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 toolbar.appendChild(wrapper)\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 element.appendChild(toolbar)\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.textContent = args.label\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\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 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: 20%;\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}\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 8px;\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;\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`\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/bubble-menu-preset.ts"],"sourcesContent":["import { Extension } from '@blockslides/core'\nimport type { Editor } from '@blockslides/core'\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n type BubbleMenuOptions,\n} from '@blockslides/extension-bubble-menu'\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 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\ntype Cleanup = () => void\n\nconst STYLE_ID = 'blockslides-bubble-menu-preset-styles'\n\nconst 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\nconst DEFAULT_FONTS = [\n 'Inter',\n 'Arial',\n 'Helvetica',\n 'Times New Roman',\n 'Georgia',\n 'Courier New',\n 'Monaco',\n]\n\nconst DEFAULT_FONT_SIZES = ['12px', '14px', '16px', '18px', '20px', '24px', '32px', '40px']\n\nconst DEFAULT_ALIGNMENTS: TextAlignValue[] = ['left', 'center', 'right', 'justify']\n\n// A rich palette approximating the attached reference.\nconst 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\nconst 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\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 shouldShow: null,\n options: {\n placement: 'top',\n strategy: 'absolute',\n offset: 8,\n flip: {},\n shift: {},\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 })\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\nfunction 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 },\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 toolbar = document.createElement('div')\n toolbar.className = 'bs-bmp-toolbar'\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) => p.classList.add('bs-bmp-hidden'))\n }\n\n const runWithFocus = (fn?: () => boolean) => {\n if (!fn) return false\n return !!fn()\n }\n\n const addButton = (\n item: BubbleMenuPresetItem,\n label: string,\n onClick: () => 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()\n })\n }\n toolbar.appendChild(btn)\n }\n\n const addUndoRedo = () => {\n const hasUndo = typeof getCommand('undo') === 'function'\n const hasRedo = typeof getCommand('redo') === 'function'\n addButton('undo', DEFAULT_LABELS.undo, () => runWithFocus(() => runChainCommand('undo')), {\n disabled: !hasUndo,\n title: 'Undo',\n })\n addButton('redo', DEFAULT_LABELS.redo, () => runWithFocus(() => runChainCommand('redo')), {\n disabled: !hasRedo,\n title: 'Redo',\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 wrapper.appendChild(select)\n toolbar.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 wrapper.appendChild(select)\n toolbar.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 item,\n DEFAULT_LABELS[item],\n () => {\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 toolbar.appendChild(toggle)\n toolbar.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 toolbar.appendChild(toggle)\n toolbar.appendChild(popover)\n }\n\n const addLink = () => {\n const hasToggle = typeof getCommand('toggleLink') === 'function'\n const hasUnset = typeof getCommand('unsetLink') === 'function'\n addButton(\n 'link',\n DEFAULT_LABELS.link,\n () => {\n const currentHref = editor.getAttributes('link')?.href ?? ''\n const href = window.prompt('Link URL', currentHref)\n if (href === null) return\n if (!href) {\n if (hasUnset) {\n runWithFocus(() => runChainCommand('unsetLink'))\n }\n return\n }\n if (hasToggle) {\n runWithFocus(() => runChainCommand('toggleLink', { href }))\n }\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 toolbar.appendChild(wrapper)\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 element.appendChild(toolbar)\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.textContent = args.label\n toggle.title = args.title\n toggle.setAttribute('aria-expanded', 'false')\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 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}\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 8px;\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;\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`\n\n document.head.appendChild(style)\n}\n\n\n\n\n\n"],"mappings":"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","names":["_a","opts"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockslides/extension-bubble-menu-preset",
|
|
3
3
|
"description": "Opinionated bubble menu preset with built-in formatting actions",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"blockslides",
|
|
7
7
|
"bubble menu",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@blockslides/core": "^0.1.0",
|
|
42
|
-
"@blockslides/extension-bubble-menu": "^0.1.0",
|
|
43
42
|
"@blockslides/extension-link": "^0.1.0",
|
|
44
43
|
"@blockslides/extension-highlight": "^0.1.0",
|
|
45
44
|
"@blockslides/extension-text-align": "^0.1.0",
|
|
46
45
|
"@blockslides/extension-text-style": "^0.1.0",
|
|
46
|
+
"@blockslides/extension-bubble-menu": "^0.1.0",
|
|
47
47
|
"@blockslides/extensions": "^0.1.0",
|
|
48
48
|
"@blockslides/pm": "^0.1.0"
|
|
49
49
|
},
|
|
@@ -696,7 +696,7 @@ function injectStyles() {
|
|
|
696
696
|
background: #ffffff;
|
|
697
697
|
border: 1px solid #e5e7eb;
|
|
698
698
|
padding: 8px 10px;
|
|
699
|
-
border-radius:
|
|
699
|
+
border-radius: 10px;
|
|
700
700
|
box-shadow: 0 10px 30px rgba(0,0,0,0.12);
|
|
701
701
|
color: #111827;
|
|
702
702
|
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
package/src/index.ts
CHANGED