dishui 0.0.76 → 0.0.78

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.
@@ -137,21 +137,7 @@ var f = ({ editor: f, onAddComment: p }) => {
137
137
  },
138
138
  title: "Text color",
139
139
  buttonClassName: "rte-bubble__btn",
140
- icon: /* @__PURE__ */ l("svg", {
141
- width: "14",
142
- height: "14",
143
- viewBox: "0 0 24 24",
144
- fill: "none",
145
- stroke: "currentColor",
146
- strokeWidth: "2",
147
- strokeLinecap: "round",
148
- strokeLinejoin: "round",
149
- children: [
150
- /* @__PURE__ */ c("path", { d: "M4 20h16" }),
151
- /* @__PURE__ */ c("path", { d: "M6 16l4.5-12h1L16 16" }),
152
- /* @__PURE__ */ c("path", { d: "M7.8 12h6.4" })
153
- ]
154
- })
140
+ kind: "text"
155
141
  }),
156
142
  /* @__PURE__ */ c(e, {
157
143
  value: f.getAttributes("highlight").color || "",
@@ -160,17 +146,7 @@ var f = ({ editor: f, onAddComment: p }) => {
160
146
  },
161
147
  title: "Highlight color",
162
148
  buttonClassName: "rte-bubble__btn",
163
- icon: /* @__PURE__ */ l("svg", {
164
- width: "14",
165
- height: "14",
166
- viewBox: "0 0 24 24",
167
- fill: "none",
168
- stroke: "currentColor",
169
- strokeWidth: "2",
170
- strokeLinecap: "round",
171
- strokeLinejoin: "round",
172
- children: [/* @__PURE__ */ c("path", { d: "M12 20h9" }), /* @__PURE__ */ c("path", { d: "M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z" })]
173
- })
149
+ kind: "highlight"
174
150
  }),
175
151
  /* @__PURE__ */ c("div", { className: "rte-bubble__divider" }),
176
152
  /* @__PURE__ */ c("select", {
@@ -1 +1 @@
1
- {"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { ColorPicker } from './Toolbar/ColorPicker';\nimport { FONT_FAMILIES, FONT_SIZES } from './Toolbar/SelectDropdown';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (editor.isDestroyed) return;\n const doc = editor.view.dom.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n let frame: number | null = null;\n const hide = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = null;\n setVisible(false);\n };\n const update = () => {\n frame = null;\n if (editor.isDestroyed) { hide(); return; }\n const { from, to } = editor.state.selection;\n if (!editor.isEditable || !(editor.state.selection instanceof TextSelection) || from === to || (!editor.isFocused && !ref.current?.contains(doc.activeElement))) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest<HTMLElement>('.rte-editor-wrapper');\n if (!wrapperEl) { hide(); return; }\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left - wrapperEl.clientLeft + wrapperEl.scrollLeft;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - wrapperEl.clientTop + wrapperEl.scrollTop - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n const scheduleUpdate = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = win.requestAnimationFrame(update);\n };\n const onBlur = ({ event }: { event: FocusEvent }) => {\n if (event.relatedTarget instanceof Node && ref.current?.contains(event.relatedTarget)) return;\n hide();\n };\n editor.on('transaction', scheduleUpdate);\n editor.on('selectionUpdate', scheduleUpdate);\n editor.on('focus', scheduleUpdate);\n editor.on('blur', onBlur);\n editor.on('destroy', hide);\n doc.addEventListener('scroll', scheduleUpdate, true);\n win.addEventListener('resize', scheduleUpdate);\n update();\n return () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n editor.off('transaction', scheduleUpdate);\n editor.off('selectionUpdate', scheduleUpdate);\n editor.off('focus', scheduleUpdate);\n editor.off('blur', onBlur);\n editor.off('destroy', hide);\n doc.removeEventListener('scroll', scheduleUpdate, true);\n win.removeEventListener('resize', scheduleUpdate);\n };\n }, [editor]);\n\n // Keep the bubble inside the wrapper horizontally: with the extra color /\n // font controls it can be wider than a phone-size editor, and transform:\n // translateX(-50%) would otherwise clip it at either edge.\n useLayoutEffect(() => {\n if (!visible || !ref.current) return;\n const el = ref.current;\n const wrapper = el.parentElement;\n if (!wrapper) return;\n const w = wrapper.clientWidth;\n const half = el.offsetWidth / 2;\n const min = Math.min(half + 4, w / 2);\n const max = Math.max(w - half - 4, w / 2);\n const clamped = Math.min(Math.max(pos.x, min), max);\n if (clamped !== pos.x) setPos((p) => ({ ...p, x: clamped }));\n }, [visible, pos.x]);\n\n if (!visible || editor.isDestroyed || !editor.isEditable) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean | undefined, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={() => { if (!editor.isDestroyed && editor.isEditable) onClick(); }}\n title={title}\n aria-label={title}\n aria-pressed={isActive}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" role=\"group\" aria-label=\"Selection formatting\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !editor.isFocused) setVisible(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n editor.commands.focus();\n setVisible(false);\n }\n }}\n style={{ left: pos.x, top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}>&lt;/&gt;</span>)}\n {btn(() => {\n const url = window.prompt('URL:', editor.getAttributes('link').href || '');\n if (url === null || editor.isDestroyed || !editor.isEditable) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (url.trim() === '') chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n <div className=\"rte-bubble__divider\" />\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().setColor(color).run();\n else editor.chain().focus().unsetColor().run();\n }}\n title=\"Text color\"\n buttonClassName=\"rte-bubble__btn\"\n icon={\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 20h16\" /><path d=\"M6 16l4.5-12h1L16 16\" /><path d=\"M7.8 12h6.4\" />\n </svg>\n }\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().toggleHighlight({ color }).run();\n else editor.chain().focus().unsetHighlight().run();\n }}\n title=\"Highlight color\"\n buttonClassName=\"rte-bubble__btn\"\n icon={\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 20h9\" /><path d=\"M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z\" />\n </svg>\n }\n />\n <div className=\"rte-bubble__divider\" />\n <select\n className=\"rte-bubble__select\"\n value={editor.getAttributes('textStyle').fontFamily || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) editor.chain().focus().setFontFamily(e.target.value).run();\n else editor.chain().focus().unsetFontFamily().run();\n }}\n title=\"Font family\"\n aria-label=\"Font family\"\n >\n {FONT_FAMILIES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n <select\n className=\"rte-bubble__select rte-bubble__select--size\"\n value={editor.getAttributes('textStyle').fontSize || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) (editor.chain().focus() as any).setFontSize(e.target.value).run();\n else (editor.chain().focus() as any).unsetFontSize().run();\n }}\n title=\"Font size\"\n aria-label=\"Font size\"\n >\n {FONT_SIZES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', undefined,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { ColorPicker } from './Toolbar/ColorPicker';\nimport { FONT_FAMILIES, FONT_SIZES } from './Toolbar/SelectDropdown';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (editor.isDestroyed) return;\n const doc = editor.view.dom.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n let frame: number | null = null;\n const hide = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = null;\n setVisible(false);\n };\n const update = () => {\n frame = null;\n if (editor.isDestroyed) { hide(); return; }\n const { from, to } = editor.state.selection;\n if (!editor.isEditable || !(editor.state.selection instanceof TextSelection) || from === to || (!editor.isFocused && !ref.current?.contains(doc.activeElement))) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest<HTMLElement>('.rte-editor-wrapper');\n if (!wrapperEl) { hide(); return; }\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left - wrapperEl.clientLeft + wrapperEl.scrollLeft;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - wrapperEl.clientTop + wrapperEl.scrollTop - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n const scheduleUpdate = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = win.requestAnimationFrame(update);\n };\n const onBlur = ({ event }: { event: FocusEvent }) => {\n if (event.relatedTarget instanceof Node && ref.current?.contains(event.relatedTarget)) return;\n hide();\n };\n editor.on('transaction', scheduleUpdate);\n editor.on('selectionUpdate', scheduleUpdate);\n editor.on('focus', scheduleUpdate);\n editor.on('blur', onBlur);\n editor.on('destroy', hide);\n doc.addEventListener('scroll', scheduleUpdate, true);\n win.addEventListener('resize', scheduleUpdate);\n update();\n return () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n editor.off('transaction', scheduleUpdate);\n editor.off('selectionUpdate', scheduleUpdate);\n editor.off('focus', scheduleUpdate);\n editor.off('blur', onBlur);\n editor.off('destroy', hide);\n doc.removeEventListener('scroll', scheduleUpdate, true);\n win.removeEventListener('resize', scheduleUpdate);\n };\n }, [editor]);\n\n // Keep the bubble inside the wrapper horizontally: with the extra color /\n // font controls it can be wider than a phone-size editor, and transform:\n // translateX(-50%) would otherwise clip it at either edge.\n useLayoutEffect(() => {\n if (!visible || !ref.current) return;\n const el = ref.current;\n const wrapper = el.parentElement;\n if (!wrapper) return;\n const w = wrapper.clientWidth;\n const half = el.offsetWidth / 2;\n const min = Math.min(half + 4, w / 2);\n const max = Math.max(w - half - 4, w / 2);\n const clamped = Math.min(Math.max(pos.x, min), max);\n if (clamped !== pos.x) setPos((p) => ({ ...p, x: clamped }));\n }, [visible, pos.x]);\n\n if (!visible || editor.isDestroyed || !editor.isEditable) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean | undefined, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={() => { if (!editor.isDestroyed && editor.isEditable) onClick(); }}\n title={title}\n aria-label={title}\n aria-pressed={isActive}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" role=\"group\" aria-label=\"Selection formatting\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !editor.isFocused) setVisible(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n editor.commands.focus();\n setVisible(false);\n }\n }}\n style={{ left: pos.x, top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}>&lt;/&gt;</span>)}\n {btn(() => {\n const url = window.prompt('URL:', editor.getAttributes('link').href || '');\n if (url === null || editor.isDestroyed || !editor.isEditable) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (url.trim() === '') chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n <div className=\"rte-bubble__divider\" />\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().setColor(color).run();\n else editor.chain().focus().unsetColor().run();\n }}\n title=\"Text color\"\n buttonClassName=\"rte-bubble__btn\"\n kind=\"text\"\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().toggleHighlight({ color }).run();\n else editor.chain().focus().unsetHighlight().run();\n }}\n title=\"Highlight color\"\n buttonClassName=\"rte-bubble__btn\"\n kind=\"highlight\"\n />\n <div className=\"rte-bubble__divider\" />\n <select\n className=\"rte-bubble__select\"\n value={editor.getAttributes('textStyle').fontFamily || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) editor.chain().focus().setFontFamily(e.target.value).run();\n else editor.chain().focus().unsetFontFamily().run();\n }}\n title=\"Font family\"\n aria-label=\"Font family\"\n >\n {FONT_FAMILIES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n <select\n className=\"rte-bubble__select rte-bubble__select--size\"\n value={editor.getAttributes('textStyle').fontSize || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) (editor.chain().focus() as any).setFontSize(e.target.value).run();\n else (editor.chain().focus() as any).unsetFontSize().run();\n }}\n title=\"Font size\"\n aria-label=\"Font size\"\n >\n {FONT_SIZES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', undefined,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
@@ -3,7 +3,8 @@ interface ColorPickerProps {
3
3
  value: string;
4
4
  onChange: (color: string) => void;
5
5
  title?: string;
6
- icon: React.ReactNode;
6
+ icon?: React.ReactNode;
7
+ kind?: 'text' | 'highlight';
7
8
  /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */
8
9
  buttonClassName?: string;
9
10
  }
@@ -1,47 +1,82 @@
1
- import { useEffect as e, useRef as t, useState as n } from "react";
2
- import { jsx as r, jsxs as i } from "react/jsx-runtime";
1
+ import { useEffect as e, useId as t, useRef as n, useState as r } from "react";
2
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
3
3
  //#region src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx
4
- var a = /* @__PURE__ */ "#000000.#434343.#666666.#999999.#cccccc.#eeeeee.#ffffff.#ff0000.#ff4500.#ff8c00.#ffd700.#32cd32.#00bfff.#8a2be2.#ff69b4.#dc143c.#ff6347.#ffa500.#9acd32.#20b2aa.#4169e1.#9370db.#db7093.#b22222.#d2691e.#daa520.#228b22.#008b8b.#191970.#4b0082".split("."), o = ({ value: o, onChange: s, title: c, icon: l, buttonClassName: u = "rte-toolbar__btn" }) => {
5
- let [d, f] = n(!1), p = t(null);
4
+ var o = /* @__PURE__ */ "#000000.#434343.#666666.#999999.#cccccc.#eeeeee.#ffffff.#ff0000.#ff4500.#ff8c00.#ffd700.#32cd32.#00bfff.#8a2be2.#ff69b4.#dc143c.#ff6347.#ffa500.#9acd32.#20b2aa.#4169e1.#9370db.#db7093.#b22222.#d2691e.#daa520.#228b22.#008b8b.#191970.#4b0082".split("."), s = ({ value: s, onChange: c, title: l, icon: u, kind: d = "text", buttonClassName: f = "rte-toolbar__btn" }) => {
5
+ let [p, m] = r(!1), h = n(null), g = n(null), _ = t(), v = l || (d === "text" ? "Text color" : "Highlight color"), y = `${v}: ${s || (d === "text" ? "Default" : "None")}`;
6
6
  return e(() => {
7
7
  let e = (e) => {
8
- p.current && !p.current.contains(e.target) && f(!1);
8
+ h.current && !h.current.contains(e.target) && m(!1);
9
9
  };
10
10
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
11
- }, []), /* @__PURE__ */ i("div", {
12
- ref: p,
11
+ }, []), /* @__PURE__ */ a("div", {
12
+ ref: h,
13
13
  className: "rte-toolbar__color-picker",
14
+ onBlur: (e) => {
15
+ e.currentTarget.contains(e.relatedTarget) || m(!1);
16
+ },
17
+ onKeyDown: (e) => {
18
+ e.key === "Escape" && p && (e.preventDefault(), e.stopPropagation(), m(!1), g.current?.focus());
19
+ },
14
20
  children: [/* @__PURE__ */ i("button", {
15
21
  type: "button",
16
- className: u,
17
- onClick: () => f(!d),
18
- title: c,
19
- children: [l, /* @__PURE__ */ r("span", {
20
- className: "rte-toolbar__color-indicator",
21
- style: { backgroundColor: o || "#000" }
22
- })]
23
- }), d && /* @__PURE__ */ i("div", {
22
+ ref: g,
23
+ className: `${f} rte-toolbar__color-trigger`,
24
+ onClick: () => m(!p),
25
+ title: y,
26
+ "aria-label": y,
27
+ "aria-expanded": p,
28
+ "aria-controls": p ? _ : void 0,
29
+ children: /* @__PURE__ */ a("span", {
30
+ className: `rte-toolbar__color-icon rte-toolbar__color-icon--${d}`,
31
+ "aria-hidden": "true",
32
+ children: [u || (d === "text" ? /* @__PURE__ */ i("span", {
33
+ className: "rte-toolbar__color-letter",
34
+ children: "A"
35
+ }) : /* @__PURE__ */ i("svg", {
36
+ width: "18",
37
+ height: "16",
38
+ viewBox: "0 0 24 24",
39
+ fill: "none",
40
+ stroke: "currentColor",
41
+ strokeWidth: "2",
42
+ strokeLinecap: "round",
43
+ strokeLinejoin: "round",
44
+ children: /* @__PURE__ */ i("path", { d: "m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6" })
45
+ })), /* @__PURE__ */ i("span", {
46
+ className: `rte-toolbar__color-indicator${s ? "" : " rte-toolbar__color-indicator--empty"}`,
47
+ style: { backgroundColor: s || void 0 }
48
+ })]
49
+ })
50
+ }), p && /* @__PURE__ */ a("div", {
51
+ id: _,
24
52
  className: "rte-toolbar__color-dropdown",
25
- children: [a.map((e) => /* @__PURE__ */ r("button", {
53
+ role: "group",
54
+ "aria-label": v,
55
+ children: [o.map((e) => /* @__PURE__ */ i("button", {
26
56
  type: "button",
27
- className: `rte-toolbar__color-swatch ${e === o ? "rte-toolbar__color-swatch--active" : ""}`,
57
+ className: `rte-toolbar__color-swatch ${e === s ? "rte-toolbar__color-swatch--active" : ""}`,
28
58
  style: { backgroundColor: e },
29
59
  onClick: () => {
30
- s(e), f(!1);
60
+ c(e), m(!1);
31
61
  },
32
- title: e
33
- }, e)), /* @__PURE__ */ r("button", {
62
+ title: `${v}: ${e}`,
63
+ "aria-label": `${v}: ${e}`,
64
+ "aria-pressed": e.toLowerCase() === s.toLowerCase()
65
+ }, e)), /* @__PURE__ */ i("button", {
34
66
  type: "button",
35
67
  className: "rte-toolbar__color-clear",
36
68
  onClick: () => {
37
- s(""), f(!1);
69
+ c(""), m(!1);
38
70
  },
71
+ title: `Clear ${v}`,
72
+ "aria-label": `Clear ${v}`,
73
+ "aria-pressed": !s,
39
74
  children: "Clear"
40
75
  })]
41
76
  })]
42
77
  });
43
78
  };
44
79
  //#endregion
45
- export { o as ColorPicker };
80
+ export { s as ColorPicker };
46
81
 
47
82
  //# sourceMappingURL=ColorPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPicker.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon: React.ReactNode;\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, buttonClassName = 'rte-toolbar__btn' }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\">\n <button\n type=\"button\"\n className={buttonClassName}\n onClick={() => setIsOpen(!isOpen)}\n title={title}\n >\n {icon}\n <span\n className=\"rte-toolbar__color-indicator\"\n style={{ backgroundColor: value || '#000' }}\n />\n </button>\n {isOpen && (\n <div className=\"rte-toolbar__color-dropdown\">\n {COLORS.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`rte-toolbar__color-swatch ${c === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: c }}\n onClick={() => { onChange(c); setIsOpen(false); }}\n title={c}\n />\n ))}\n <button\n type=\"button\"\n className=\"rte-toolbar__color-clear\"\n onClick={() => { onChange(''); setIsOpen(false); }}\n >\n Clear\n </button>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;AAWA,IAAM,IAAS,2QAMf,GAEa,KAA2C,EAAE,UAAO,aAAU,UAAO,SAAM,qBAAkB,yBAAyB;CACjI,IAAM,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAM,EAAuB,IAAI;CAYvC,OAVA,QAAgB;EACd,IAAM,KAAW,MAAkB;GACjC,AAAI,EAAI,WAAW,CAAC,EAAI,QAAQ,SAAS,EAAE,MAAc,KACvD,EAAU,EAAK;EAEnB;EAEA,OADA,SAAS,iBAAiB,aAAa,CAAO,SACjC,SAAS,oBAAoB,aAAa,CAAO;CAChE,GAAG,CAAC,CAAC,GAGH,kBAAC,OAAD;EAAU;EAAK,WAAU;EAAzB,UAAA,CACE,kBAAC,UAAD;GACE,MAAK;GACL,WAAW;GACX,eAAe,EAAU,CAAC,CAAM;GACzB;GAJT,UAAA,CAMG,GACD,kBAAC,QAAD;IACE,WAAU;IACV,OAAO,EAAE,iBAAiB,KAAS,OAAO;GAC3C,CAAA,CACK;EACP,CAAA,GAAA,KACC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,EAAO,KAAK,MACX,kBAAC,UAAD;IAEE,MAAK;IACL,WAAW,6BAA6B,MAAM,IAAQ,sCAAsC;IAC5F,OAAO,EAAE,iBAAiB,EAAE;IAC5B,eAAe;KAAe,AAAb,EAAS,CAAC,GAAG,EAAU,EAAK;IAAG;IAChD,OAAO;GACR,GANM,CAMN,CACF,GACD,kBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,eAAe;KAAgB,AAAd,EAAS,EAAE,GAAG,EAAU,EAAK;IAAG;IAClD,UAAA;GAEO,CAAA,CACL;EAEJ,CAAA,CAAA;;AAET"}
1
+ {"version":3,"file":"ColorPicker.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon?: React.ReactNode;\n kind?: 'text' | 'highlight';\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, kind = 'text', buttonClassName = 'rte-toolbar__btn' }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const paletteId = useId();\n const label = title || (kind === 'text' ? 'Text color' : 'Highlight color');\n const description = `${label}: ${value || (kind === 'text' ? 'Default' : 'None')}`;\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget)) setIsOpen(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault();\n event.stopPropagation();\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`${buttonClassName} rte-toolbar__color-trigger`}\n onClick={() => setIsOpen(!isOpen)}\n title={description}\n aria-label={description}\n aria-expanded={isOpen}\n aria-controls={isOpen ? paletteId : undefined}\n >\n <span className={`rte-toolbar__color-icon rte-toolbar__color-icon--${kind}`} aria-hidden=\"true\">\n {icon || (kind === 'text' ? <span className=\"rte-toolbar__color-letter\">A</span> : (\n <svg width=\"18\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6\" />\n </svg>\n ))}\n <span\n className={`rte-toolbar__color-indicator${value ? '' : ' rte-toolbar__color-indicator--empty'}`}\n style={{ backgroundColor: value || undefined }}\n />\n </span>\n </button>\n {isOpen && (\n <div id={paletteId} className=\"rte-toolbar__color-dropdown\" role=\"group\" aria-label={label}>\n {COLORS.map((c) => (\n <button\n key={c}\n type=\"button\"\n className={`rte-toolbar__color-swatch ${c === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: c }}\n onClick={() => { onChange(c); setIsOpen(false); }}\n title={`${label}: ${c}`}\n aria-label={`${label}: ${c}`}\n aria-pressed={c.toLowerCase() === value.toLowerCase()}\n />\n ))}\n <button\n type=\"button\"\n className=\"rte-toolbar__color-clear\"\n onClick={() => { onChange(''); setIsOpen(false); }}\n title={`Clear ${label}`}\n aria-label={`Clear ${label}`}\n aria-pressed={!value}\n >\n Clear\n </button>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;AAYA,IAAM,IAAS,2QAMf,GAEa,KAA2C,EAAE,UAAO,aAAU,UAAO,SAAM,UAAO,QAAQ,qBAAkB,yBAAyB;CAChJ,IAAM,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAM,EAAuB,IAAI,GACjC,IAAa,EAA0B,IAAI,GAC3C,IAAY,EAAM,GAClB,IAAQ,MAAU,MAAS,SAAS,eAAe,oBACnD,IAAc,GAAG,EAAM,IAAI,MAAU,MAAS,SAAS,YAAY;CAYzE,OAVA,QAAgB;EACd,IAAM,KAAW,MAAkB;GACjC,AAAI,EAAI,WAAW,CAAC,EAAI,QAAQ,SAAS,EAAE,MAAc,KACvD,EAAU,EAAK;EAEnB;EAEA,OADA,SAAS,iBAAiB,aAAa,CAAO,SACjC,SAAS,oBAAoB,aAAa,CAAO;CAChE,GAAG,CAAC,CAAC,GAGH,kBAAC,OAAD;EAAU;EAAK,WAAU;EACvB,SAAS,MAAU;GACjB,AAAK,EAAM,cAAc,SAAS,EAAM,aAAa,KAAG,EAAU,EAAK;EACzE;EACA,YAAY,MAAU;GACpB,AAAI,EAAM,QAAQ,YAAY,MAC5B,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAU,EAAK,GACf,EAAW,SAAS,MAAM;EAE9B;EAXF,UAAA,CAYE,kBAAC,UAAD;GACE,MAAK;GACL,KAAK;GACL,WAAW,GAAG,EAAgB;GAC9B,eAAe,EAAU,CAAC,CAAM;GAChC,OAAO;GACP,cAAY;GACZ,iBAAe;GACf,iBAAe,IAAS,IAAY,KAAA;GAEpC,UAAA,kBAAC,QAAD;IAAM,WAAW,oDAAoD;IAAQ,eAAY;IAAzF,UAAA,CACG,MAAS,MAAS,SAAS,kBAAC,QAAD;KAAM,WAAU;KAA4B,UAAA;IAAO,CAAA,IAC7E,kBAAC,OAAD;KAAK,OAAM;KAAK,QAAO;KAAK,SAAQ;KAAY,MAAK;KAAO,QAAO;KAAe,aAAY;KAAI,eAAc;KAAQ,gBAAe;KACrI,UAAA,kBAAC,QAAD,EAAM,GAAE,uDAAwD,CAAA;IAC7D,CAAA,IAEP,kBAAC,QAAD;KACE,WAAW,+BAA+B,IAAQ,KAAK;KACvD,OAAO,EAAE,iBAAiB,KAAS,KAAA,EAAU;IAC9C,CAAA,CACG;;EACA,CAAA,GACP,KACC,kBAAC,OAAD;GAAK,IAAI;GAAW,WAAU;GAA8B,MAAK;GAAQ,cAAY;GAArF,UAAA,CACG,EAAO,KAAK,MACX,kBAAC,UAAD;IAEE,MAAK;IACL,WAAW,6BAA6B,MAAM,IAAQ,sCAAsC;IAC5F,OAAO,EAAE,iBAAiB,EAAE;IAC5B,eAAe;KAAe,AAAb,EAAS,CAAC,GAAG,EAAU,EAAK;IAAG;IAChD,OAAO,GAAG,EAAM,IAAI;IACpB,cAAY,GAAG,EAAM,IAAI;IACzB,gBAAc,EAAE,YAAY,MAAM,EAAM,YAAY;GACrD,GARM,CAQN,CACF,GACD,kBAAC,UAAD;IACE,MAAK;IACL,WAAU;IACV,eAAe;KAAgB,AAAd,EAAS,EAAE,GAAG,EAAU,EAAK;IAAG;IACjD,OAAO,SAAS;IAChB,cAAY,SAAS;IACrB,gBAAc,CAAC;IAChB,UAAA;GAEO,CAAA,CACL;EAEJ,CAAA,CAAA;;AAET"}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { RichTextEditorLabels } from '../types';
3
3
  interface FloatingDialogMenuProps {
4
4
  labels: RichTextEditorLabels;
5
- onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float') => void;
5
+ onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float', focusEditor?: boolean) => void;
6
6
  }
7
7
  export declare const FloatingDialogMenu: React.FC<FloatingDialogMenuProps>;
8
8
  export {};
@@ -1,7 +1,8 @@
1
1
  import { useEffect as e, useRef as t, useState as n } from "react";
2
2
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
3
+ import { flushSync as a } from "react-dom";
3
4
  //#region src/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.tsx
4
- var a = [
5
+ var o = [
5
6
  {
6
7
  key: "block",
7
8
  labelKey: "layoutBlock",
@@ -176,21 +177,25 @@ var a = [
176
177
  ]
177
178
  })
178
179
  }
179
- ], o = ({ labels: o, onInsert: s }) => {
180
- let [c, l] = n(!1), u = t(null);
180
+ ], s = ({ labels: s, onInsert: c }) => {
181
+ let [l, u] = n(!1), d = t(null), f = t("");
181
182
  return e(() => {
182
183
  let e = (e) => {
183
- u.current && !u.current.contains(e.target) && l(!1);
184
+ d.current && !d.current.contains(e.target) && u(!1);
184
185
  };
185
- return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
186
+ return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
186
187
  }, []), /* @__PURE__ */ i("div", {
187
- ref: u,
188
+ ref: d,
188
189
  className: "rte-toolbar__template-menu",
190
+ onPointerDown: (e) => {
191
+ f.current = e.pointerType;
192
+ },
189
193
  children: [/* @__PURE__ */ i("button", {
190
194
  type: "button",
191
- className: `rte-toolbar__btn ${c ? "rte-toolbar__btn--active" : ""}`,
192
- onClick: () => l(!c),
193
- title: o.floatingDialog || "Floating Dialog",
195
+ className: `rte-toolbar__btn ${l ? "rte-toolbar__btn--active" : ""}`,
196
+ "aria-expanded": l,
197
+ onClick: () => u(!l),
198
+ title: s.floatingDialog || "Floating Dialog",
194
199
  style: {
195
200
  width: "auto",
196
201
  padding: "0 6px",
@@ -232,14 +237,15 @@ var a = [
232
237
  strokeWidth: "2.5",
233
238
  children: /* @__PURE__ */ r("polyline", { points: "6 9 12 15 18 9" })
234
239
  })]
235
- }), c && /* @__PURE__ */ r("div", {
240
+ }), l && /* @__PURE__ */ r("div", {
236
241
  className: "rte-toolbar__template-dropdown",
237
242
  style: { minWidth: 140 },
238
- children: a.map((e) => /* @__PURE__ */ i("button", {
243
+ children: o.map((e) => /* @__PURE__ */ i("button", {
239
244
  type: "button",
240
245
  className: "rte-toolbar__template-item",
241
- onClick: () => {
242
- s(e.key), l(!1);
246
+ onClick: (t) => {
247
+ let n = t.detail === 0 || f.current !== "touch";
248
+ a(() => u(!1)), c(e.key, n);
243
249
  },
244
250
  children: [/* @__PURE__ */ r("span", {
245
251
  className: "rte-toolbar__template-icon",
@@ -248,12 +254,12 @@ var a = [
248
254
  alignItems: "center"
249
255
  },
250
256
  children: e.icon
251
- }), /* @__PURE__ */ r("span", { children: o[e.labelKey] || e.labelKey })]
257
+ }), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
252
258
  }, e.key))
253
259
  })]
254
260
  });
255
261
  };
256
262
  //#endregion
257
- export { o as FloatingDialogMenu };
263
+ export { s as FloatingDialogMenu };
258
264
 
259
265
  //# sourceMappingURL=FloatingDialogMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingDialogMenu.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport type { RichTextEditorLabels } from '../types';\n\ninterface FloatingDialogMenuProps {\n labels: RichTextEditorLabels;\n onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float') => void;\n}\n\nconst DIALOG_LAYOUT_OPTIONS: { key: 'block' | 'wrap-left' | 'wrap-right' | 'float'; labelKey: keyof RichTextEditorLabels; icon: React.ReactNode }[] = [\n {\n key: 'block', labelKey: 'layoutBlock',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" /><line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"3\" /><line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\" /></svg>,\n },\n {\n key: 'wrap-left', labelKey: 'layoutWrapLeft',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"2\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"15\" y1=\"5\" x2=\"22\" y2=\"5\" /><line x1=\"15\" y1=\"8\" x2=\"22\" y2=\"8\" /><line x1=\"15\" y1=\"11\" x2=\"22\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'wrap-right', labelKey: 'layoutWrapRight',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"12\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"2\" y1=\"5\" x2=\"9\" y2=\"5\" /><line x1=\"2\" y1=\"8\" x2=\"9\" y2=\"8\" /><line x1=\"2\" y1=\"11\" x2=\"9\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'float', labelKey: 'layoutFloat',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M2 2h4M18 2h4M2 22h4M18 22h4\" strokeDasharray=\"2 2\" /><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\" strokeDasharray=\"2 2\" /><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\" strokeDasharray=\"2 2\" /></svg>,\n },\n];\n\nexport const FloatingDialogMenu: React.FC<FloatingDialogMenuProps> = ({ labels, onInsert }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.floatingDialog || 'Floating Dialog'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"13\" height=\"10\" rx=\"2\" />\n <path d=\"M9 10h11a2 2 0 012 2v6a2 2 0 01-2 2H9a2 2 0 01-2-2v-2\" />\n <line x1=\"7\" y1=\"14\" x2=\"13\" y2=\"14\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"rte-toolbar__template-dropdown\" style={{ minWidth: 140 }}>\n {DIALOG_LAYOUT_OPTIONS.map((opt) => (\n <button\n key={opt.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={() => { onInsert(opt.key); setIsOpen(false); }}\n >\n <span className=\"rte-toolbar__template-icon\" style={{ display: 'flex', alignItems: 'center' }}>{opt.icon}</span>\n <span>{labels[opt.labelKey] || opt.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"FloatingDialogMenu.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\n\ninterface FloatingDialogMenuProps {\n labels: RichTextEditorLabels;\n onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float', focusEditor?: boolean) => void;\n}\n\nconst DIALOG_LAYOUT_OPTIONS: { key: 'block' | 'wrap-left' | 'wrap-right' | 'float'; labelKey: keyof RichTextEditorLabels; icon: React.ReactNode }[] = [\n {\n key: 'block', labelKey: 'layoutBlock',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" /><line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"3\" /><line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\" /></svg>,\n },\n {\n key: 'wrap-left', labelKey: 'layoutWrapLeft',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"2\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"15\" y1=\"5\" x2=\"22\" y2=\"5\" /><line x1=\"15\" y1=\"8\" x2=\"22\" y2=\"8\" /><line x1=\"15\" y1=\"11\" x2=\"22\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'wrap-right', labelKey: 'layoutWrapRight',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"12\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"2\" y1=\"5\" x2=\"9\" y2=\"5\" /><line x1=\"2\" y1=\"8\" x2=\"9\" y2=\"8\" /><line x1=\"2\" y1=\"11\" x2=\"9\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'float', labelKey: 'layoutFloat',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M2 2h4M18 2h4M2 22h4M18 22h4\" strokeDasharray=\"2 2\" /><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\" strokeDasharray=\"2 2\" /><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\" strokeDasharray=\"2 2\" /></svg>,\n },\n];\n\nexport const FloatingDialogMenu: React.FC<FloatingDialogMenuProps> = ({ labels, onInsert }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const pointerType = useRef('');\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false);\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.floatingDialog || 'Floating Dialog'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"13\" height=\"10\" rx=\"2\" />\n <path d=\"M9 10h11a2 2 0 012 2v6a2 2 0 01-2 2H9a2 2 0 01-2-2v-2\" />\n <line x1=\"7\" y1=\"14\" x2=\"13\" y2=\"14\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"rte-toolbar__template-dropdown\" style={{ minWidth: 140 }}>\n {DIALOG_LAYOUT_OPTIONS.map((opt) => (\n <button\n key={opt.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => {\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onInsert(opt.key, focusEditor);\n }}\n >\n <span className=\"rte-toolbar__template-icon\" style={{ display: 'flex', alignItems: 'center' }}>{opt.icon}</span>\n <span>{labels[opt.labelKey] || opt.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -8,7 +8,7 @@ export declare const MD_TEMPLATES: {
8
8
  }[];
9
9
  interface MarkdownTemplateMenuProps {
10
10
  labels: RichTextEditorLabels;
11
- onSelect: (content: string) => void;
11
+ onSelect: (content: string, focusEditor?: boolean) => void;
12
12
  }
13
13
  export declare const MarkdownTemplateMenu: React.FC<MarkdownTemplateMenuProps>;
14
14
  export {};
@@ -1,7 +1,8 @@
1
1
  import { useEffect as e, useRef as t, useState as n } from "react";
2
2
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
3
+ import { flushSync as a } from "react-dom";
3
4
  //#region src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx
4
- var a = [
5
+ var o = [
5
6
  {
6
7
  key: "flowchart",
7
8
  labelKey: "mdTplFlowchart",
@@ -62,21 +63,28 @@ var a = [
62
63
  icon: "🎨",
63
64
  content: "## Mixed Content Example\n\n### Architecture Overview\n\n```mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n```\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\log n)$ with proper indexing.\n\n### Implementation\n\n```python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n```\n\n### Project Status\n\n```mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n```\n"
64
65
  }
65
- ], o = ({ labels: o, onSelect: s }) => {
66
- let [c, l] = n(!1), u = t(null);
66
+ ], s = ({ labels: s, onSelect: c }) => {
67
+ let [l, u] = n(!1), d = t(null), f = t(""), p = (e, t) => {
68
+ let n = e.detail === 0 || f.current !== "touch";
69
+ a(() => u(!1)), c(t, n);
70
+ };
67
71
  return e(() => {
68
72
  let e = (e) => {
69
- u.current && !u.current.contains(e.target) && l(!1);
73
+ d.current && !d.current.contains(e.target) && u(!1);
70
74
  };
71
- return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
75
+ return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
72
76
  }, []), /* @__PURE__ */ i("div", {
73
- ref: u,
77
+ ref: d,
74
78
  className: "rte-toolbar__template-menu",
79
+ onPointerDown: (e) => {
80
+ f.current = e.pointerType;
81
+ },
75
82
  children: [/* @__PURE__ */ i("button", {
76
83
  type: "button",
77
- className: `rte-toolbar__btn ${c ? "rte-toolbar__btn--active" : ""}`,
78
- onClick: () => l(!c),
79
- title: o.mdTemplates || "Markdown Templates",
84
+ className: `rte-toolbar__btn ${l ? "rte-toolbar__btn--active" : ""}`,
85
+ "aria-expanded": l,
86
+ onClick: () => u(!l),
87
+ title: s.mdTemplates || "Markdown Templates",
80
88
  style: {
81
89
  width: "auto",
82
90
  padding: "0 6px",
@@ -126,14 +134,14 @@ var a = [
126
134
  strokeWidth: "2.5",
127
135
  children: /* @__PURE__ */ r("polyline", { points: "6 9 12 15 18 9" })
128
136
  })]
129
- }), c && /* @__PURE__ */ i("div", {
137
+ }), l && /* @__PURE__ */ i("div", {
130
138
  className: "rte-toolbar__template-dropdown",
131
139
  children: [
132
140
  /* @__PURE__ */ r("div", {
133
141
  className: "rte-toolbar__template-group-label",
134
142
  children: "Mermaid"
135
143
  }),
136
- a.filter((e) => [
144
+ o.filter((e) => [
137
145
  "flowchart",
138
146
  "sequence",
139
147
  "pie",
@@ -142,53 +150,47 @@ var a = [
142
150
  ].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
143
151
  type: "button",
144
152
  className: "rte-toolbar__template-item",
145
- onClick: () => {
146
- s(e.content), l(!1);
147
- },
153
+ onClick: (t) => p(t, e.content),
148
154
  children: [/* @__PURE__ */ r("span", {
149
155
  className: "rte-toolbar__template-icon",
150
156
  children: e.icon
151
- }), /* @__PURE__ */ r("span", { children: o[e.labelKey] || e.labelKey })]
157
+ }), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
152
158
  }, e.key)),
153
159
  /* @__PURE__ */ r("div", {
154
160
  className: "rte-toolbar__template-group-label",
155
161
  children: "Code"
156
162
  }),
157
- a.filter((e) => [
163
+ o.filter((e) => [
158
164
  "python",
159
165
  "typescript",
160
166
  "rust"
161
167
  ].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
162
168
  type: "button",
163
169
  className: "rte-toolbar__template-item",
164
- onClick: () => {
165
- s(e.content), l(!1);
166
- },
170
+ onClick: (t) => p(t, e.content),
167
171
  children: [/* @__PURE__ */ r("span", {
168
172
  className: "rte-toolbar__template-icon",
169
173
  children: e.icon
170
- }), /* @__PURE__ */ r("span", { children: o[e.labelKey] || e.labelKey })]
174
+ }), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
171
175
  }, e.key)),
172
176
  /* @__PURE__ */ r("div", {
173
177
  className: "rte-toolbar__template-group-label",
174
178
  children: "Math / Mixed"
175
179
  }),
176
- a.filter((e) => ["math", "mixed"].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
180
+ o.filter((e) => ["math", "mixed"].includes(e.key)).map((e) => /* @__PURE__ */ i("button", {
177
181
  type: "button",
178
182
  className: "rte-toolbar__template-item",
179
- onClick: () => {
180
- s(e.content), l(!1);
181
- },
183
+ onClick: (t) => p(t, e.content),
182
184
  children: [/* @__PURE__ */ r("span", {
183
185
  className: "rte-toolbar__template-icon",
184
186
  children: e.icon
185
- }), /* @__PURE__ */ r("span", { children: o[e.labelKey] || e.labelKey })]
187
+ }), /* @__PURE__ */ r("span", { children: s[e.labelKey] || e.labelKey })]
186
188
  }, e.key))
187
189
  ]
188
190
  })]
189
191
  });
190
192
  };
191
193
  //#endregion
192
- export { a as MD_TEMPLATES, o as MarkdownTemplateMenu };
194
+ export { o as MD_TEMPLATES, s as MarkdownTemplateMenu };
193
195
 
194
196
  //# sourceMappingURL=MarkdownTemplates.js.map