bridgerte 0.9.1 → 0.9.2
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/README.md +8 -5
- package/dist/bridge.d.ts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/dom.cjs +1 -1
- package/dist/dom.d.ts +12 -2
- package/dist/dom.js +2 -2
- package/dist/index-CkgUKPh3.cjs +3 -0
- package/dist/index-CkgUKPh3.cjs.map +1 -0
- package/dist/index-CqOH1_5N.cjs +2 -0
- package/dist/index-CqOH1_5N.cjs.map +1 -0
- package/dist/index-DRWIM218.js +262 -0
- package/dist/index-DRWIM218.js.map +1 -0
- package/dist/{index-BQAzp56J.js → index-KRuLtGv9.js} +774 -759
- package/dist/index-KRuLtGv9.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js +2 -2
- package/dist/native-spec.d.ts +2 -2
- package/dist/style.css +1 -1
- package/dist/webview.cjs +1 -1
- package/dist/webview.d.ts +2 -2
- package/dist/webview.js +1 -1
- package/package.json +1 -1
- package/dist/index-BQAzp56J.js.map +0 -1
- package/dist/index-Bui5UnkQ.cjs +0 -3
- package/dist/index-Bui5UnkQ.cjs.map +0 -1
- package/dist/index-CeYJbOQi.js +0 -137
- package/dist/index-CeYJbOQi.js.map +0 -1
- package/dist/index-DAlyGWXO.cjs +0 -2
- package/dist/index-DAlyGWXO.cjs.map +0 -1
package/dist/index-CeYJbOQi.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { defaultMenuSchema as R, resolveToolbarMenu as k } from "./native-spec.js";
|
|
2
|
-
import { r as N, d as X, g as H, e as F, f as G, h as O } from "./index-BQAzp56J.js";
|
|
3
|
-
const U = 4, V = 8, $ = "button[data-bridgerte-toolbar-item-id]", q = () => {
|
|
4
|
-
var e;
|
|
5
|
-
return typeof window < "u" && ((e = window.matchMedia) == null ? void 0 : e.call(window, "(hover: hover) and (pointer: fine)").matches) === !0;
|
|
6
|
-
}, h = (e) => {
|
|
7
|
-
const r = e instanceof Element ? e.closest($) : null;
|
|
8
|
-
return r instanceof HTMLButtonElement ? r : null;
|
|
9
|
-
}, M = (e, r, c, m, p) => {
|
|
10
|
-
const i = F(r, c), a = document.createElement("button"), n = m[r.icon] ?? G[r.icon];
|
|
11
|
-
a.type = "button", a.className = "bridgerte__toolbar-button", a.disabled = i.disabled, a.dataset.active = String(i.active), a.dataset.bridgerteToolbarItemId = r.id, a.setAttribute("aria-label", r.label), a.setAttribute("aria-pressed", String(i.active)), p && (a.dataset.tooltip = r.label), O(a, n, r.label), e.append(a);
|
|
12
|
-
}, j = (e, r, c, m, p) => {
|
|
13
|
-
e.textContent = "";
|
|
14
|
-
let i = "", a = null;
|
|
15
|
-
r.forEach((n) => {
|
|
16
|
-
if (n.type === "separator") {
|
|
17
|
-
i = "", a = null;
|
|
18
|
-
const d = document.createElement("span");
|
|
19
|
-
d.className = "bridgerte__toolbar-separator", d.dataset.separatorId = n.key, d.setAttribute("aria-hidden", "true"), e.append(d);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const s = n.type === "button" ? n.item.group : n.key;
|
|
23
|
-
(!a || i !== s) && (i = s, a = document.createElement("div"), a.className = "bridgerte__toolbar-group", a.dataset.group = s, n.type === "group" && a.setAttribute("aria-label", n.title), e.append(a));
|
|
24
|
-
const g = a;
|
|
25
|
-
if (n.type === "button") {
|
|
26
|
-
M(
|
|
27
|
-
g,
|
|
28
|
-
n.item,
|
|
29
|
-
c,
|
|
30
|
-
m,
|
|
31
|
-
p
|
|
32
|
-
);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
n.items.forEach((d) => {
|
|
36
|
-
M(
|
|
37
|
-
g,
|
|
38
|
-
d,
|
|
39
|
-
c,
|
|
40
|
-
m,
|
|
41
|
-
p
|
|
42
|
-
);
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
function J(e, r) {
|
|
47
|
-
const c = r.placement ?? "top", m = N(r.menuSchema ?? R, {
|
|
48
|
-
menuLabels: r.menuLabels,
|
|
49
|
-
payloadPanelConfig: r.payloadPanelConfig
|
|
50
|
-
}), p = k(r.toolbarConfig, m), i = p.flatMap((t) => t.type === "button" ? [t.item] : t.type === "group" ? t.items : []), a = r.icons ?? {}, n = q(), s = document.createElement("div"), g = e.closest(".bridgerte") ?? e;
|
|
51
|
-
let d = !1, u = null, f = !1;
|
|
52
|
-
const _ = X(e, {
|
|
53
|
-
targetSelector: "button[data-bridgerte-toolbar-item-id]"
|
|
54
|
-
}), T = () => {
|
|
55
|
-
g.append(s);
|
|
56
|
-
}, E = (t) => {
|
|
57
|
-
d || (j(e, p, t, a, n), T());
|
|
58
|
-
}, w = () => {
|
|
59
|
-
d || E(r.editor.getCommandStates());
|
|
60
|
-
}, b = () => {
|
|
61
|
-
s.dataset.visible = "false", s.textContent = "";
|
|
62
|
-
}, D = (t) => {
|
|
63
|
-
const o = t.dataset.tooltip;
|
|
64
|
-
if (!n || !o || u) return;
|
|
65
|
-
const l = t.getBoundingClientRect();
|
|
66
|
-
s.textContent = o, s.dataset.visible = "true", s.style.left = `${l.left + l.width / 2}px`, s.style.top = `${l.top - V}px`;
|
|
67
|
-
}, y = (t) => {
|
|
68
|
-
const o = h(t.target);
|
|
69
|
-
o && D(o);
|
|
70
|
-
}, L = (t) => {
|
|
71
|
-
const o = t.relatedTarget, l = h(t.target);
|
|
72
|
-
l && o instanceof Node && l.contains(o) || b();
|
|
73
|
-
}, C = () => {
|
|
74
|
-
u = null, delete e.dataset.dragging, document.removeEventListener("pointermove", S), document.removeEventListener("pointerup", v), document.removeEventListener("pointercancel", v);
|
|
75
|
-
}, S = (t) => {
|
|
76
|
-
if (!u) return;
|
|
77
|
-
const o = u.startClientX - t.clientX;
|
|
78
|
-
Math.abs(o) > U && (u.hasDragged = !0, f = !0, b()), e.scrollLeft = u.startScrollLeft + o;
|
|
79
|
-
}, v = (t) => {
|
|
80
|
-
const o = u;
|
|
81
|
-
C(), o && t.type !== "pointercancel" && o.pointerType !== "mouse" && !o.hasDragged && o.startButton && (P(o.startButton), f = !0);
|
|
82
|
-
}, x = (t) => {
|
|
83
|
-
if (t.pointerType === "mouse" && t.button !== 0) return;
|
|
84
|
-
const o = h(t.target);
|
|
85
|
-
t.preventDefault(), u = {
|
|
86
|
-
startClientX: t.clientX,
|
|
87
|
-
startScrollLeft: e.scrollLeft,
|
|
88
|
-
pointerType: t.pointerType,
|
|
89
|
-
hasDragged: !1,
|
|
90
|
-
startButton: o ?? void 0
|
|
91
|
-
}, e.dataset.dragging = "true", b(), document.addEventListener("pointermove", S), document.addEventListener("pointerup", v), document.addEventListener("pointercancel", v);
|
|
92
|
-
}, P = (t) => {
|
|
93
|
-
if (!(t instanceof HTMLButtonElement) || t.disabled) return;
|
|
94
|
-
const o = i.find((l) => l.id === t.dataset.bridgerteToolbarItemId);
|
|
95
|
-
if (o) {
|
|
96
|
-
if (r.editor.focus(), o.payloadPanel) {
|
|
97
|
-
const l = t.getBoundingClientRect();
|
|
98
|
-
r.editor.requestPayloadPanel({
|
|
99
|
-
menuId: o.id,
|
|
100
|
-
command: o.command,
|
|
101
|
-
panel: o.payloadPanel,
|
|
102
|
-
currentValues: H(o, r.editor.getCommandStates()),
|
|
103
|
-
anchorRect: {
|
|
104
|
-
x: l.left,
|
|
105
|
-
y: l.top,
|
|
106
|
-
width: l.width,
|
|
107
|
-
height: l.height
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
r.editor.executeCommand(o.command);
|
|
113
|
-
}
|
|
114
|
-
}, B = (t) => {
|
|
115
|
-
if (f) {
|
|
116
|
-
f = !1, t.preventDefault(), t.stopPropagation();
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
const o = h(t.target);
|
|
120
|
-
o && P(o);
|
|
121
|
-
};
|
|
122
|
-
e.classList.add("bridgerte__toolbar"), s.className = "bridgerte__toolbar-tooltip", s.dataset.visible = "false", e.dataset.placement = c, e.setAttribute("role", "toolbar"), e.setAttribute(
|
|
123
|
-
"aria-label",
|
|
124
|
-
c === "bottom" ? "BridgeRTE tabbar" : "BridgeRTE toolbar"
|
|
125
|
-
), e.addEventListener("pointerdown", x, !0), e.addEventListener("click", B), n && (e.addEventListener("mouseover", y), e.addEventListener("mouseout", L)), e.addEventListener("focusout", b), T();
|
|
126
|
-
const A = r.editor.subscribeCommandStateChange(E);
|
|
127
|
-
return {
|
|
128
|
-
update: w,
|
|
129
|
-
destroy() {
|
|
130
|
-
d || (d = !0, C(), A(), e.removeEventListener("pointerdown", x, !0), e.removeEventListener("click", B), n && (e.removeEventListener("mouseover", y), e.removeEventListener("mouseout", L)), _(), e.removeEventListener("focusout", b), s.remove(), e.classList.remove("bridgerte__toolbar"), delete e.dataset.placement, e.textContent = "", e.removeAttribute("role"), e.removeAttribute("aria-label"));
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
export {
|
|
135
|
-
J as c
|
|
136
|
-
};
|
|
137
|
-
//# sourceMappingURL=index-CeYJbOQi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-CeYJbOQi.js","sources":["../../dom/src/richTextToolbar/index.ts"],"sourcesContent":["import type { CommandState } from '@bridgerte/core';\nimport {\n defaultMenuSchema,\n resolveToolbarMenu,\n type MenuItem,\n type ResolvedToolbarItem\n} from '@bridgerte/native-spec';\nimport {\n appendMenuIcon,\n defaultMenuIcons\n} from './icons';\nimport { bindTouchPressedState } from '../interactionState';\nimport {\n getMenuStateForItem,\n getPayloadPanelCurrentValues,\n resolveMenuSchemaForDom\n} from '../menuRuntime';\nimport type {\n RichTextToolbarAPI,\n RichTextToolbarIcons,\n RichTextToolbarOptions,\n ToolbarDragState\n} from './type';\n\nconst toolbarDragClickThresholdPx = 4;\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\n\nexport type * from './type';\n\nconst canUseHoverTooltip = () => (\n typeof window !== 'undefined'\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\n);\n\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\n /*\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\n */\n const button = target instanceof Element\n ? target.closest<HTMLButtonElement>(toolbarButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\n};\n\nconst renderToolbarButton = (\n groupElement: HTMLElement,\n item: MenuItem,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n const state = getMenuStateForItem(item, commandStates);\n const button = document.createElement('button');\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\n\n button.type = 'button';\n button.className = 'bridgerte__toolbar-button';\n button.disabled = state.disabled;\n button.dataset.active = String(state.active);\n button.dataset.bridgerteToolbarItemId = item.id;\n button.setAttribute('aria-label', item.label);\n button.setAttribute('aria-pressed', String(state.active));\n if (enableTooltip) button.dataset.tooltip = item.label;\n\n appendMenuIcon(button, iconSvg, item.label);\n\n groupElement.append(button);\n};\n\nconst renderToolbar = (\n toolbarElement: HTMLElement,\n toolbarItems: ResolvedToolbarItem[],\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n toolbarElement.textContent = '';\n\n let currentGroup = '';\n let groupElement: HTMLDivElement | null = null;\n\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n currentGroup = '';\n groupElement = null;\n\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\n separatorElement.setAttribute('aria-hidden', 'true');\n toolbarElement.append(separatorElement);\n return;\n }\n\n const nextGroup = toolbarItem.type === 'button' ? toolbarItem.item.group : toolbarItem.key;\n\n if (!groupElement || currentGroup !== nextGroup) {\n currentGroup = nextGroup;\n groupElement = document.createElement('div');\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = nextGroup;\n if (toolbarItem.type === 'group') {\n groupElement.setAttribute('aria-label', toolbarItem.title);\n }\n toolbarElement.append(groupElement);\n }\n\n const activeGroupElement = groupElement;\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n activeGroupElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n toolbarItem.items.forEach((item) => {\n renderToolbarButton(\n activeGroupElement,\n item,\n commandStates,\n icons,\n enableTooltip\n );\n });\n });\n};\n\n/**\n * 创建独立菜单实例。\n *\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\n */\nexport function createRichTextToolbar(\n container: HTMLElement,\n options: RichTextToolbarOptions\n): RichTextToolbarAPI {\n const placement = options.placement ?? 'top';\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\n menuLabels: options.menuLabels,\n payloadPanelConfig: options.payloadPanelConfig\n });\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\n /*\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\n */\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\n toolbarItem.type === 'button' ? [toolbarItem.item]\n : toolbarItem.type === 'group' ? toolbarItem.items\n : []\n ));\n const icons = options.icons ?? {};\n /*\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\n */\n const enableTooltip = canUseHoverTooltip();\n const tooltipElement = document.createElement('div');\n const overlayHost = container.closest('.bridgerte') ?? container;\n let destroyed = false;\n let dragState: ToolbarDragState | null = null;\n let shouldSuppressNextClick = false;\n const clearToolbarPressedState = bindTouchPressedState(container, {\n targetSelector: 'button[data-bridgerte-toolbar-item-id]'\n });\n\n const mountToolbarOverlays = () => {\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\n overlayHost.append(tooltipElement);\n };\n\n const renderStates = (states: CommandState[]) => {\n if (destroyed) return;\n\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\n mountToolbarOverlays();\n };\n\n const update = () => {\n if (destroyed) return;\n\n renderStates(options.editor.getCommandStates());\n };\n\n const hideTooltip = () => {\n tooltipElement.dataset.visible = 'false';\n tooltipElement.textContent = '';\n };\n\n const showTooltip = (button: HTMLButtonElement) => {\n const tooltipText = button.dataset.tooltip;\n\n if (!enableTooltip || !tooltipText || dragState) return;\n\n const buttonRect = button.getBoundingClientRect();\n\n tooltipElement.textContent = tooltipText;\n tooltipElement.dataset.visible = 'true';\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\n };\n\n const handleTooltipTarget = (event: Event) => {\n const button = getToolbarButtonFromTarget(event.target);\n\n if (button) {\n showTooltip(button);\n }\n };\n\n const handleTooltipLeave = (event: MouseEvent) => {\n const relatedTarget = event.relatedTarget;\n const button = getToolbarButtonFromTarget(event.target);\n\n if (\n button\n && relatedTarget instanceof Node\n && button.contains(relatedTarget)\n ) return;\n\n hideTooltip();\n };\n\n const stopToolbarDrag = () => {\n dragState = null;\n\n delete container.dataset.dragging;\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n document.removeEventListener('pointercancel', handlePointerUp);\n };\n\n const handlePointerMove = (event: PointerEvent) => {\n if (!dragState) return;\n\n const deltaX = dragState.startClientX - event.clientX;\n\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\n dragState.hasDragged = true;\n shouldSuppressNextClick = true;\n hideTooltip();\n }\n\n container.scrollLeft = dragState.startScrollLeft + deltaX;\n };\n\n const handlePointerUp = (event: PointerEvent) => {\n const currentDragState = dragState;\n\n stopToolbarDrag();\n if (\n currentDragState\n && event.type !== 'pointercancel'\n && currentDragState.pointerType !== 'mouse'\n && !currentDragState.hasDragged\n && currentDragState.startButton\n ) {\n executeToolbarButton(currentDragState.startButton);\n shouldSuppressNextClick = true;\n }\n };\n\n const handlePointerDown = (event: PointerEvent) => {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n\n const startButton = getToolbarButtonFromTarget(event.target);\n\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\n event.preventDefault();\n dragState = {\n startClientX: event.clientX,\n startScrollLeft: container.scrollLeft,\n pointerType: event.pointerType,\n hasDragged: false,\n startButton: startButton ?? undefined\n };\n container.dataset.dragging = 'true';\n hideTooltip();\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n document.addEventListener('pointercancel', handlePointerUp);\n };\n\n const executeToolbarButton = (button: HTMLButtonElement) => {\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\n\n const menuItem = executableMenuItems.find((item) => (\n item.id === button.dataset.bridgerteToolbarItemId\n ));\n\n if (!menuItem) return;\n\n options.editor.focus();\n if (menuItem.payloadPanel) {\n const buttonRect = button.getBoundingClientRect();\n\n /*\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\n * 字体、链接等参数菜单各自发明一套协议。\n */\n options.editor.requestPayloadPanel({\n menuId: menuItem.id,\n command: menuItem.command,\n panel: menuItem.payloadPanel,\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\n anchorRect: {\n x: buttonRect.left,\n y: buttonRect.top,\n width: buttonRect.width,\n height: buttonRect.height\n }\n });\n return;\n }\n\n options.editor.executeCommand(menuItem.command);\n };\n\n const handleClick = (event: MouseEvent) => {\n if (shouldSuppressNextClick) {\n shouldSuppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n const button = getToolbarButtonFromTarget(event.target);\n if (!button) return;\n\n executeToolbarButton(button);\n };\n\n container.classList.add('bridgerte__toolbar');\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\n tooltipElement.dataset.visible = 'false';\n container.dataset.placement = placement;\n container.setAttribute('role', 'toolbar');\n container.setAttribute(\n 'aria-label',\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\n );\n container.addEventListener('pointerdown', handlePointerDown, true);\n container.addEventListener('click', handleClick);\n if (enableTooltip) {\n container.addEventListener('mouseover', handleTooltipTarget);\n container.addEventListener('mouseout', handleTooltipLeave);\n }\n container.addEventListener('focusout', hideTooltip);\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\n mountToolbarOverlays();\n\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\n\n return {\n update,\n destroy() {\n if (destroyed) return;\n\n destroyed = true;\n stopToolbarDrag();\n unsubscribe();\n container.removeEventListener('pointerdown', handlePointerDown, true);\n container.removeEventListener('click', handleClick);\n if (enableTooltip) {\n container.removeEventListener('mouseover', handleTooltipTarget);\n container.removeEventListener('mouseout', handleTooltipLeave);\n }\n clearToolbarPressedState();\n container.removeEventListener('focusout', hideTooltip);\n tooltipElement.remove();\n container.classList.remove('bridgerte__toolbar');\n delete container.dataset.placement;\n container.textContent = '';\n container.removeAttribute('role');\n container.removeAttribute('aria-label');\n }\n };\n}\n"],"names":["toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarButtonSelector","canUseHoverTooltip","_a","getToolbarButtonFromTarget","target","button","renderToolbarButton","groupElement","item","commandStates","icons","enableTooltip","state","getMenuStateForItem","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbar","toolbarElement","toolbarItems","currentGroup","toolbarItem","separatorElement","nextGroup","activeGroupElement","createRichTextToolbar","container","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","clearToolbarPressedState","bindTouchPressedState","mountToolbarOverlays","renderStates","states","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","event","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","executeToolbarButton","handlePointerDown","startButton","menuItem","getPayloadPanelCurrentValues","handleClick","unsubscribe"],"mappings":"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"}
|
package/dist/index-DAlyGWXO.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const _=require("./native-spec.cjs"),b=require("./index-Bui5UnkQ.cjs"),N=4,X=8,H="button[data-bridgerte-toolbar-item-id]",q=()=>{var e;return typeof window<"u"&&((e=window.matchMedia)==null?void 0:e.call(window,"(hover: hover) and (pointer: fine)").matches)===!0},T=e=>{const r=e instanceof Element?e.closest(H):null;return r instanceof HTMLButtonElement?r:null},w=(e,r,c,m,p)=>{const i=b.getMenuStateForItem(r,c),a=document.createElement("button"),n=m[r.icon]??b.defaultMenuIcons[r.icon];a.type="button",a.className="bridgerte__toolbar-button",a.disabled=i.disabled,a.dataset.active=String(i.active),a.dataset.bridgerteToolbarItemId=r.id,a.setAttribute("aria-label",r.label),a.setAttribute("aria-pressed",String(i.active)),p&&(a.dataset.tooltip=r.label),b.appendMenuIcon(a,n,r.label),e.append(a)},F=(e,r,c,m,p)=>{e.textContent="";let i="",a=null;r.forEach(n=>{if(n.type==="separator"){i="",a=null;const d=document.createElement("span");d.className="bridgerte__toolbar-separator",d.dataset.separatorId=n.key,d.setAttribute("aria-hidden","true"),e.append(d);return}const s=n.type==="button"?n.item.group:n.key;(!a||i!==s)&&(i=s,a=document.createElement("div"),a.className="bridgerte__toolbar-group",a.dataset.group=s,n.type==="group"&&a.setAttribute("aria-label",n.title),e.append(a));const f=a;if(n.type==="button"){w(f,n.item,c,m,p);return}n.items.forEach(d=>{w(f,d,c,m,p)})})};function G(e,r){const c=r.placement??"top",m=b.resolveMenuSchemaForDom(r.menuSchema??_.defaultMenuSchema,{menuLabels:r.menuLabels,payloadPanelConfig:r.payloadPanelConfig}),p=_.resolveToolbarMenu(r.toolbarConfig,m),i=p.flatMap(t=>t.type==="button"?[t.item]:t.type==="group"?t.items:[]),a=r.icons??{},n=q(),s=document.createElement("div"),f=e.closest(".bridgerte")??e;let d=!1,u=null,v=!1;const D=b.bindTouchPressedState(e,{targetSelector:"button[data-bridgerte-toolbar-item-id]"}),E=()=>{f.append(s)},y=t=>{d||(F(e,p,t,a,n),E())},R=()=>{d||y(r.editor.getCommandStates())},g=()=>{s.dataset.visible="false",s.textContent=""},A=t=>{const o=t.dataset.tooltip;if(!n||!o||u)return;const l=t.getBoundingClientRect();s.textContent=o,s.dataset.visible="true",s.style.left=`${l.left+l.width/2}px`,s.style.top=`${l.top-X}px`},L=t=>{const o=T(t.target);o&&A(o)},S=t=>{const o=t.relatedTarget,l=T(t.target);l&&o instanceof Node&&l.contains(o)||g()},C=()=>{u=null,delete e.dataset.dragging,document.removeEventListener("pointermove",x),document.removeEventListener("pointerup",h),document.removeEventListener("pointercancel",h)},x=t=>{if(!u)return;const o=u.startClientX-t.clientX;Math.abs(o)>N&&(u.hasDragged=!0,v=!0,g()),e.scrollLeft=u.startScrollLeft+o},h=t=>{const o=u;C(),o&&t.type!=="pointercancel"&&o.pointerType!=="mouse"&&!o.hasDragged&&o.startButton&&(B(o.startButton),v=!0)},P=t=>{if(t.pointerType==="mouse"&&t.button!==0)return;const o=T(t.target);t.preventDefault(),u={startClientX:t.clientX,startScrollLeft:e.scrollLeft,pointerType:t.pointerType,hasDragged:!1,startButton:o??void 0},e.dataset.dragging="true",g(),document.addEventListener("pointermove",x),document.addEventListener("pointerup",h),document.addEventListener("pointercancel",h)},B=t=>{if(!(t instanceof HTMLButtonElement)||t.disabled)return;const o=i.find(l=>l.id===t.dataset.bridgerteToolbarItemId);if(o){if(r.editor.focus(),o.payloadPanel){const l=t.getBoundingClientRect();r.editor.requestPayloadPanel({menuId:o.id,command:o.command,panel:o.payloadPanel,currentValues:b.getPayloadPanelCurrentValues(o,r.editor.getCommandStates()),anchorRect:{x:l.left,y:l.top,width:l.width,height:l.height}});return}r.editor.executeCommand(o.command)}},M=t=>{if(v){v=!1,t.preventDefault(),t.stopPropagation();return}const o=T(t.target);o&&B(o)};e.classList.add("bridgerte__toolbar"),s.className="bridgerte__toolbar-tooltip",s.dataset.visible="false",e.dataset.placement=c,e.setAttribute("role","toolbar"),e.setAttribute("aria-label",c==="bottom"?"BridgeRTE tabbar":"BridgeRTE toolbar"),e.addEventListener("pointerdown",P,!0),e.addEventListener("click",M),n&&(e.addEventListener("mouseover",L),e.addEventListener("mouseout",S)),e.addEventListener("focusout",g),E();const k=r.editor.subscribeCommandStateChange(y);return{update:R,destroy(){d||(d=!0,C(),k(),e.removeEventListener("pointerdown",P,!0),e.removeEventListener("click",M),n&&(e.removeEventListener("mouseover",L),e.removeEventListener("mouseout",S)),D(),e.removeEventListener("focusout",g),s.remove(),e.classList.remove("bridgerte__toolbar"),delete e.dataset.placement,e.textContent="",e.removeAttribute("role"),e.removeAttribute("aria-label"))}}}exports.createRichTextToolbar=G;
|
|
2
|
-
//# sourceMappingURL=index-DAlyGWXO.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DAlyGWXO.cjs","sources":["../../dom/src/richTextToolbar/index.ts"],"sourcesContent":["import type { CommandState } from '@bridgerte/core';\nimport {\n defaultMenuSchema,\n resolveToolbarMenu,\n type MenuItem,\n type ResolvedToolbarItem\n} from '@bridgerte/native-spec';\nimport {\n appendMenuIcon,\n defaultMenuIcons\n} from './icons';\nimport { bindTouchPressedState } from '../interactionState';\nimport {\n getMenuStateForItem,\n getPayloadPanelCurrentValues,\n resolveMenuSchemaForDom\n} from '../menuRuntime';\nimport type {\n RichTextToolbarAPI,\n RichTextToolbarIcons,\n RichTextToolbarOptions,\n ToolbarDragState\n} from './type';\n\nconst toolbarDragClickThresholdPx = 4;\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\n\nexport type * from './type';\n\nconst canUseHoverTooltip = () => (\n typeof window !== 'undefined'\n && window.matchMedia?.('(hover: hover) and (pointer: fine)').matches === true\n);\n\nconst getToolbarButtonFromTarget = (target: EventTarget | null) => {\n /*\n * 图标覆盖常用 SVG,H5 pointer 事件可能落在 svg/path 上。\n * 这里用 Element 而不是 HTMLElement,保证触屏兜底和 click 都能向上命中真实按钮。\n */\n const button = target instanceof Element\n ? target.closest<HTMLButtonElement>(toolbarButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\n};\n\nconst renderToolbarButton = (\n groupElement: HTMLElement,\n item: MenuItem,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n const state = getMenuStateForItem(item, commandStates);\n const button = document.createElement('button');\n // icon 兜底顺序固定为:业务覆盖 > DOM 默认 SVG > label 文本。\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\n\n button.type = 'button';\n button.className = 'bridgerte__toolbar-button';\n button.disabled = state.disabled;\n button.dataset.active = String(state.active);\n button.dataset.bridgerteToolbarItemId = item.id;\n button.setAttribute('aria-label', item.label);\n button.setAttribute('aria-pressed', String(state.active));\n if (enableTooltip) button.dataset.tooltip = item.label;\n\n appendMenuIcon(button, iconSvg, item.label);\n\n groupElement.append(button);\n};\n\nconst renderToolbar = (\n toolbarElement: HTMLElement,\n toolbarItems: ResolvedToolbarItem[],\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n toolbarElement.textContent = '';\n\n let currentGroup = '';\n let groupElement: HTMLDivElement | null = null;\n\n toolbarItems.forEach((toolbarItem) => {\n if (toolbarItem.type === 'separator') {\n currentGroup = '';\n groupElement = null;\n\n const separatorElement = document.createElement('span');\n\n separatorElement.className = 'bridgerte__toolbar-separator';\n separatorElement.dataset.separatorId = toolbarItem.key;\n separatorElement.setAttribute('aria-hidden', 'true');\n toolbarElement.append(separatorElement);\n return;\n }\n\n const nextGroup = toolbarItem.type === 'button' ? toolbarItem.item.group : toolbarItem.key;\n\n if (!groupElement || currentGroup !== nextGroup) {\n currentGroup = nextGroup;\n groupElement = document.createElement('div');\n groupElement.className = 'bridgerte__toolbar-group';\n groupElement.dataset.group = nextGroup;\n if (toolbarItem.type === 'group') {\n groupElement.setAttribute('aria-label', toolbarItem.title);\n }\n toolbarElement.append(groupElement);\n }\n\n const activeGroupElement = groupElement;\n\n if (toolbarItem.type === 'button') {\n renderToolbarButton(\n activeGroupElement,\n toolbarItem.item,\n commandStates,\n icons,\n enableTooltip\n );\n return;\n }\n\n toolbarItem.items.forEach((item) => {\n renderToolbarButton(\n activeGroupElement,\n item,\n commandStates,\n icons,\n enableTooltip\n );\n });\n });\n};\n\n/**\n * 创建独立菜单实例。\n *\n * toolbar/tabbar 只订阅 EditorAPI 状态并派发命令,不接触编辑器内部 DOM 或 Lexical 实例。\n */\nexport function createRichTextToolbar(\n container: HTMLElement,\n options: RichTextToolbarOptions\n): RichTextToolbarAPI {\n const placement = options.placement ?? 'top';\n const menuSchema = resolveMenuSchemaForDom(options.menuSchema ?? defaultMenuSchema, {\n menuLabels: options.menuLabels,\n payloadPanelConfig: options.payloadPanelConfig\n });\n const toolbarItems = resolveToolbarMenu(options.toolbarConfig, menuSchema);\n /*\n * click 事件只需要能执行命令的菜单项。分割线和 group 容器是渲染结构,\n * 先在这里摊平,后续点击时就不用理解 toolbarConfig 的展示层级。\n */\n const executableMenuItems = toolbarItems.flatMap((toolbarItem) => (\n toolbarItem.type === 'button' ? [toolbarItem.item]\n : toolbarItem.type === 'group' ? toolbarItem.items\n : []\n ));\n const icons = options.icons ?? {};\n /*\n * tooltip 只属于 PC 精细指针体验。H5 上即使没有原生 title,部分浏览器也会把 hover/mouseover\n * 模拟成首触摸状态,导致第一次点像是只唤醒提示;所以触屏端不写 tooltip 数据也不挂监听。\n */\n const enableTooltip = canUseHoverTooltip();\n const tooltipElement = document.createElement('div');\n const overlayHost = container.closest('.bridgerte') ?? container;\n let destroyed = false;\n let dragState: ToolbarDragState | null = null;\n let shouldSuppressNextClick = false;\n const clearToolbarPressedState = bindTouchPressedState(container, {\n targetSelector: 'button[data-bridgerte-toolbar-item-id]'\n });\n\n const mountToolbarOverlays = () => {\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\n overlayHost.append(tooltipElement);\n };\n\n const renderStates = (states: CommandState[]) => {\n if (destroyed) return;\n\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\n mountToolbarOverlays();\n };\n\n const update = () => {\n if (destroyed) return;\n\n renderStates(options.editor.getCommandStates());\n };\n\n const hideTooltip = () => {\n tooltipElement.dataset.visible = 'false';\n tooltipElement.textContent = '';\n };\n\n const showTooltip = (button: HTMLButtonElement) => {\n const tooltipText = button.dataset.tooltip;\n\n if (!enableTooltip || !tooltipText || dragState) return;\n\n const buttonRect = button.getBoundingClientRect();\n\n tooltipElement.textContent = tooltipText;\n tooltipElement.dataset.visible = 'true';\n tooltipElement.style.left = `${buttonRect.left + buttonRect.width / 2}px`;\n tooltipElement.style.top = `${buttonRect.top - toolbarTooltipOffsetPx}px`;\n };\n\n const handleTooltipTarget = (event: Event) => {\n const button = getToolbarButtonFromTarget(event.target);\n\n if (button) {\n showTooltip(button);\n }\n };\n\n const handleTooltipLeave = (event: MouseEvent) => {\n const relatedTarget = event.relatedTarget;\n const button = getToolbarButtonFromTarget(event.target);\n\n if (\n button\n && relatedTarget instanceof Node\n && button.contains(relatedTarget)\n ) return;\n\n hideTooltip();\n };\n\n const stopToolbarDrag = () => {\n dragState = null;\n\n delete container.dataset.dragging;\n // 拖动过程中监听挂在 document 上,松手或 destroy 必须统一清掉,避免离开 toolbar 后残留滚动状态。\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n document.removeEventListener('pointercancel', handlePointerUp);\n };\n\n const handlePointerMove = (event: PointerEvent) => {\n if (!dragState) return;\n\n const deltaX = dragState.startClientX - event.clientX;\n\n if (Math.abs(deltaX) > toolbarDragClickThresholdPx) {\n dragState.hasDragged = true;\n shouldSuppressNextClick = true;\n hideTooltip();\n }\n\n container.scrollLeft = dragState.startScrollLeft + deltaX;\n };\n\n const handlePointerUp = (event: PointerEvent) => {\n const currentDragState = dragState;\n\n stopToolbarDrag();\n if (\n currentDragState\n && event.type !== 'pointercancel'\n && currentDragState.pointerType !== 'mouse'\n && !currentDragState.hasDragged\n && currentDragState.startButton\n ) {\n executeToolbarButton(currentDragState.startButton);\n shouldSuppressNextClick = true;\n }\n };\n\n const handlePointerDown = (event: PointerEvent) => {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n\n const startButton = getToolbarButtonFromTarget(event.target);\n\n // 点击和拖动 toolbar 都要保留编辑区 selection,命令才能继续作用在原选区。\n event.preventDefault();\n dragState = {\n startClientX: event.clientX,\n startScrollLeft: container.scrollLeft,\n pointerType: event.pointerType,\n hasDragged: false,\n startButton: startButton ?? undefined\n };\n container.dataset.dragging = 'true';\n hideTooltip();\n // pointermove 放到 document,保证用户按住 X 轴拖出 toolbar 后仍能完成滚动和释放。\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n document.addEventListener('pointercancel', handlePointerUp);\n };\n\n const executeToolbarButton = (button: HTMLButtonElement) => {\n if (!(button instanceof HTMLButtonElement) || button.disabled) return;\n\n const menuItem = executableMenuItems.find((item) => (\n item.id === button.dataset.bridgerteToolbarItemId\n ));\n\n if (!menuItem) return;\n\n options.editor.focus();\n if (menuItem.payloadPanel) {\n const buttonRect = button.getBoundingClientRect();\n\n /*\n * 带 payloadPanel 的菜单不直接执行基础 command,而是发起参数请求。\n * DOM 内置面板和业务/RN/Flutter 自绘都走同一个 request,避免后续颜色、\n * 字体、链接等参数菜单各自发明一套协议。\n */\n options.editor.requestPayloadPanel({\n menuId: menuItem.id,\n command: menuItem.command,\n panel: menuItem.payloadPanel,\n currentValues: getPayloadPanelCurrentValues(menuItem, options.editor.getCommandStates()),\n anchorRect: {\n x: buttonRect.left,\n y: buttonRect.top,\n width: buttonRect.width,\n height: buttonRect.height\n }\n });\n return;\n }\n\n options.editor.executeCommand(menuItem.command);\n };\n\n const handleClick = (event: MouseEvent) => {\n if (shouldSuppressNextClick) {\n shouldSuppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n const button = getToolbarButtonFromTarget(event.target);\n if (!button) return;\n\n executeToolbarButton(button);\n };\n\n container.classList.add('bridgerte__toolbar');\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\n tooltipElement.dataset.visible = 'false';\n container.dataset.placement = placement;\n container.setAttribute('role', 'toolbar');\n container.setAttribute(\n 'aria-label',\n placement === 'bottom' ? 'BridgeRTE tabbar' : 'BridgeRTE toolbar'\n );\n container.addEventListener('pointerdown', handlePointerDown, true);\n container.addEventListener('click', handleClick);\n if (enableTooltip) {\n container.addEventListener('mouseover', handleTooltipTarget);\n container.addEventListener('mouseout', handleTooltipLeave);\n }\n container.addEventListener('focusout', hideTooltip);\n // 浮层挂在最近的编辑器根容器下,既能继承变量,也不会操作编辑内容 DOM。\n mountToolbarOverlays();\n\n // 独立 toolbar 只订阅 public API 状态,不依赖 DOM 编辑器内部实现。\n const unsubscribe = options.editor.subscribeCommandStateChange(renderStates);\n\n return {\n update,\n destroy() {\n if (destroyed) return;\n\n destroyed = true;\n stopToolbarDrag();\n unsubscribe();\n container.removeEventListener('pointerdown', handlePointerDown, true);\n container.removeEventListener('click', handleClick);\n if (enableTooltip) {\n container.removeEventListener('mouseover', handleTooltipTarget);\n container.removeEventListener('mouseout', handleTooltipLeave);\n }\n clearToolbarPressedState();\n container.removeEventListener('focusout', hideTooltip);\n tooltipElement.remove();\n container.classList.remove('bridgerte__toolbar');\n delete container.dataset.placement;\n container.textContent = '';\n container.removeAttribute('role');\n container.removeAttribute('aria-label');\n }\n };\n}\n"],"names":["toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarButtonSelector","canUseHoverTooltip","_a","getToolbarButtonFromTarget","target","button","renderToolbarButton","groupElement","item","commandStates","icons","enableTooltip","state","getMenuStateForItem","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbar","toolbarElement","toolbarItems","currentGroup","toolbarItem","separatorElement","nextGroup","activeGroupElement","createRichTextToolbar","container","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","clearToolbarPressedState","bindTouchPressedState","mountToolbarOverlays","renderStates","states","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","event","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","executeToolbarButton","handlePointerDown","startButton","menuItem","getPayloadPanelCurrentValues","handleClick","unsubscribe"],"mappings":"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"}
|