bridgerte 0.9.2 → 0.9.3

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.
@@ -1,18 +1,55 @@
1
- import { defaultMenuSchema as ee, resolveToolbarMenu as te } from "./native-spec.js";
2
- import { g as A, d as G, e as D, r as oe, f as U, h as re, c as ne } from "./index-KRuLtGv9.js";
3
- const j = (e) => Array.from(
1
+ import { defaultMenuSchema as te, resolveToolbarMenu as oe } from "./native-spec.js";
2
+ import { g as C, d as G, e as D, r as re, f as q, h as ne, c as ae } from "./index-BwZ0II4h.js";
3
+ const U = {
4
+ toolbarGroup: `
5
+ <svg
6
+ aria-hidden="true"
7
+ class="lucide lucide-ellipsis"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ width="18"
10
+ height="18"
11
+ viewBox="0 0 24 24"
12
+ fill="none"
13
+ stroke="currentColor"
14
+ stroke-width="2"
15
+ stroke-linecap="round"
16
+ stroke-linejoin="round"
17
+ >
18
+ <circle cx="12" cy="12" r="1" />
19
+ <circle cx="19" cy="12" r="1" />
20
+ <circle cx="5" cy="12" r="1" />
21
+ </svg>
22
+ `,
23
+ chevronDown: `
24
+ <svg
25
+ aria-hidden="true"
26
+ class="lucide lucide-chevron-down"
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ width="12"
29
+ height="12"
30
+ viewBox="0 0 24 24"
31
+ fill="none"
32
+ stroke="currentColor"
33
+ stroke-width="2"
34
+ stroke-linecap="round"
35
+ stroke-linejoin="round"
36
+ >
37
+ <path d="m6 9 6 6 6-6" />
38
+ </svg>
39
+ `
40
+ }, V = (e) => Array.from(
4
41
  e.querySelectorAll(".bridgerte__toolbar-group-menu-item")
5
- ).filter((t) => !t.disabled), ae = (e, t) => {
6
- const i = j(e)[t];
42
+ ).filter((t) => !t.disabled), se = (e, t) => {
43
+ const i = V(e)[t];
7
44
  i && i.focus();
8
- }, se = (e) => {
9
- ae(e, 0);
10
- }, le = (e, t, s, i, p) => {
45
+ }, le = (e) => {
46
+ se(e, 0);
47
+ }, ie = (e, t, s, i, p) => {
11
48
  var l, u;
12
- const a = j(t), r = document.activeElement instanceof HTMLButtonElement ? a.indexOf(document.activeElement) : -1, d = (f) => {
49
+ const a = V(t), r = document.activeElement instanceof HTMLButtonElement ? a.indexOf(document.activeElement) : -1, d = (g) => {
13
50
  var v;
14
51
  if (a.length === 0) return;
15
- const m = ((r >= 0 ? r : 0) + f + a.length) % a.length;
52
+ const m = ((r >= 0 ? r : 0) + g + a.length) % a.length;
16
53
  (v = a[m]) == null || v.focus();
17
54
  };
18
55
  switch (e.key) {
@@ -36,36 +73,36 @@ const j = (e) => Array.from(
36
73
  e.preventDefault(), s.focus(), p();
37
74
  break;
38
75
  }
39
- }, w = "button[data-bridgerte-toolbar-group-id]", ie = "button[data-bridgerte-toolbar-item-id]", de = [
40
- ie,
76
+ }, A = "button[data-bridgerte-toolbar-group-id]", de = "button[data-bridgerte-toolbar-item-id]", ue = [
77
+ de,
41
78
  ".bridgerte__toolbar-group-menu-item"
42
- ].join(","), ue = (e, t) => {
43
- const s = e.map((i) => A(i, t));
79
+ ].join(","), ce = (e, t) => {
80
+ const s = e.map((i) => C(i, t));
44
81
  return {
45
82
  active: s.some((i) => i.active),
46
83
  disabled: s.length > 0 && s.every((i) => i.disabled)
47
84
  };
48
- }, ce = (e, t, s, i, p) => {
49
- const a = A(t, s), r = document.createElement("button"), d = i[t.icon] ?? G[t.icon];
50
- r.type = "button", r.className = "bridgerte__toolbar-button", r.disabled = a.disabled, r.dataset.active = String(a.active), r.dataset.bridgerteToolbarItemId = t.id, r.setAttribute("aria-label", t.label), r.setAttribute("aria-pressed", String(a.active)), p && (r.dataset.tooltip = t.label), D(r, d, t.label), e.append(r);
51
85
  }, pe = (e, t, s, i, p) => {
52
- const a = document.createElement("button"), r = ue(t.items, s), d = t.icon ? i[t.icon] ?? G[t.icon] : void 0, l = document.createElement("span");
53
- a.type = "button", a.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", a.disabled = r.disabled, a.dataset.active = String(r.active), a.dataset.bridgerteToolbarGroupId = t.key, a.dataset.open = "false", a.setAttribute("aria-label", t.title), a.setAttribute("aria-haspopup", "menu"), a.setAttribute("aria-expanded", "false"), a.setAttribute("aria-pressed", String(r.active)), p && (a.dataset.tooltip = t.title), D(a, d, t.title), l.className = "bridgerte__toolbar-group-indicator", l.setAttribute("aria-hidden", "true"), l.textContent = "⌄", a.append(l), e.append(a);
86
+ const a = C(t, s), r = document.createElement("button"), d = i[t.icon] ?? G[t.icon];
87
+ r.type = "button", r.className = "bridgerte__toolbar-button", r.disabled = a.disabled, r.dataset.active = String(a.active), r.dataset.bridgerteToolbarItemId = t.id, r.setAttribute("aria-label", t.label), r.setAttribute("aria-pressed", String(a.active)), p && (r.dataset.tooltip = t.label), D(r, d, t.label), e.append(r);
54
88
  }, be = (e, t, s, i, p) => {
89
+ const a = document.createElement("button"), r = ce(t.items, s), d = t.icon ? i[t.icon] ?? G[t.icon] : U.toolbarGroup, l = document.createElement("span");
90
+ a.type = "button", a.className = "bridgerte__toolbar-button bridgerte__toolbar-group-button", a.disabled = r.disabled, a.dataset.active = String(r.active), a.dataset.bridgerteToolbarGroupId = t.key, a.dataset.open = "false", a.setAttribute("aria-label", t.title), a.setAttribute("aria-haspopup", "menu"), a.setAttribute("aria-expanded", "false"), a.setAttribute("aria-pressed", String(r.active)), p && (a.dataset.tooltip = t.title), D(a, d, t.title), l.className = "bridgerte__toolbar-group-indicator", l.setAttribute("aria-hidden", "true"), l.innerHTML = U.chevronDown, a.append(l), e.append(a);
91
+ }, me = (e, t, s, i, p) => {
55
92
  e.textContent = "";
56
93
  let a = "", r = null;
57
94
  t.forEach((d) => {
58
95
  if (d.type === "separator") {
59
96
  a = "", r = null;
60
- const f = document.createElement("span");
61
- f.className = "bridgerte__toolbar-separator", f.dataset.separatorId = d.key, f.setAttribute("aria-hidden", "true"), e.append(f);
97
+ const g = document.createElement("span");
98
+ g.className = "bridgerte__toolbar-separator", g.dataset.separatorId = d.key, g.setAttribute("aria-hidden", "true"), e.append(g);
62
99
  return;
63
100
  }
64
101
  const l = d.type === "button" ? d.item.group : d.key;
65
102
  (!r || a !== l) && (a = l, r = document.createElement("div"), r.className = "bridgerte__toolbar-group", r.dataset.group = l, d.type === "group" && r.setAttribute("aria-label", d.title), e.append(r));
66
103
  const u = r;
67
104
  if (d.type === "button") {
68
- ce(
105
+ pe(
69
106
  u,
70
107
  d.item,
71
108
  s,
@@ -74,7 +111,7 @@ const j = (e) => Array.from(
74
111
  );
75
112
  return;
76
113
  }
77
- pe(
114
+ be(
78
115
  u,
79
116
  d,
80
117
  s,
@@ -82,101 +119,101 @@ const j = (e) => Array.from(
82
119
  p
83
120
  );
84
121
  });
85
- }, B = (e, t, s, i) => {
122
+ }, S = (e, t, s, i) => {
86
123
  if (e.textContent = "", !t) {
87
124
  e.dataset.visible = "false";
88
125
  return;
89
126
  }
90
127
  t.items.forEach((p) => {
91
- const a = A(p, s), r = document.createElement("button"), d = i[p.icon] ?? G[p.icon], l = document.createElement("span");
92
- r.type = "button", r.className = "bridgerte__toolbar-group-menu-item", r.disabled = a.disabled, r.dataset.active = String(a.active), r.dataset.bridgerteToolbarItemId = p.id, r.setAttribute("role", "menuitem"), r.setAttribute("aria-label", p.label), r.setAttribute("aria-pressed", String(a.active)), D(r, d, p.label), l.className = "bridgerte__toolbar-group-menu-label", l.textContent = p.label, r.append(l), e.append(r);
128
+ const a = C(p, s), r = document.createElement("button"), d = i[p.icon] ?? G[p.icon], l = document.createElement("span");
129
+ r.type = "button", r.className = "bridgerte__menu-item bridgerte__toolbar-group-menu-item", r.disabled = a.disabled, r.dataset.active = String(a.active), r.dataset.bridgerteToolbarItemId = p.id, r.setAttribute("role", "menuitem"), r.setAttribute("aria-label", p.label), r.setAttribute("aria-pressed", String(a.active)), D(r, d, p.label), l.className = "bridgerte__toolbar-group-menu-label", l.textContent = p.label, r.append(l), e.append(r);
93
130
  }), e.dataset.visible = "true", e.style.minWidth = `${t.button.offsetWidth}px`;
94
- }, C = (e, t) => {
95
- e.querySelectorAll(w).forEach((s) => {
131
+ }, B = (e, t) => {
132
+ e.querySelectorAll(A).forEach((s) => {
96
133
  const i = (t == null ? void 0 : t.groupKey) === s.dataset.bridgerteToolbarGroupId;
97
134
  s.dataset.open = String(i), s.setAttribute("aria-expanded", String(i));
98
135
  });
99
- }, $ = (e, t) => e.find((s) => s.type === "group" && s.key === t), me = 4, fe = 8, ge = 6, ve = () => {
136
+ }, $ = (e, t) => e.find((s) => s.type === "group" && s.key === t), ge = 4, fe = 8, ve = 6, he = () => {
100
137
  var e;
101
138
  return typeof window < "u" && ((e = window.matchMedia) == null ? void 0 : e.call(window, "(hover: hover) and (pointer: fine)").matches) === !0;
102
- }, S = (e) => {
103
- const t = e instanceof Element ? e.closest(de) : null;
139
+ }, L = (e) => {
140
+ const t = e instanceof Element ? e.closest(ue) : null;
104
141
  return t instanceof HTMLButtonElement ? t : null;
105
142
  }, ye = (e) => {
106
- const t = e instanceof Element ? e.closest(w) : null;
143
+ const t = e instanceof Element ? e.closest(A) : null;
107
144
  return t instanceof HTMLButtonElement ? t : null;
108
145
  };
109
- function Te(e, t) {
110
- const s = t.placement ?? "top", i = oe(t.menuSchema ?? ee, {
146
+ function xe(e, t) {
147
+ const s = t.placement ?? "top", i = re(t.menuSchema ?? te, {
111
148
  menuLabels: t.menuLabels,
112
149
  payloadPanelConfig: t.payloadPanelConfig
113
- }), p = te(t.toolbarConfig, i), a = p.flatMap((o) => o.type === "button" ? [o.item] : o.type === "group" ? o.items : []), r = t.icons ?? {}, d = ve(), l = document.createElement("div"), u = document.createElement("div"), f = e.closest(".bridgerte") ?? e;
114
- let h = !1, m = null, v = !1, T = t.editor.getCommandStates(), c = null, g = null;
115
- const V = U(e, {
150
+ }), p = oe(t.toolbarConfig, i), a = p.flatMap((o) => o.type === "button" ? [o.item] : o.type === "group" ? o.items : []), r = t.icons ?? {}, d = he(), l = document.createElement("div"), u = document.createElement("div"), g = e.closest(".bridgerte") ?? e;
151
+ let E = !1, m = null, v = !1, T = t.editor.getCommandStates(), c = null, f = null;
152
+ const W = q(e, {
116
153
  targetSelector: [
117
154
  "button[data-bridgerte-toolbar-item-id]",
118
155
  "button[data-bridgerte-toolbar-group-id]"
119
156
  ].join(",")
120
- }), W = U(u, {
157
+ }), z = q(u, {
121
158
  targetSelector: ".bridgerte__toolbar-group-menu-item"
122
159
  }), P = () => {
123
- f.append(l), f.append(u);
124
- }, _ = () => {
125
- g == null || g.setOpen(!1), g == null || g.destroy(), g = null;
160
+ g.append(l), g.append(u);
161
+ }, k = () => {
162
+ f == null || f.setOpen(!1), f == null || f.destroy(), f = null;
126
163
  }, M = () => {
127
- c && (_(), g = ne(c.button, u, {
164
+ c && (k(), f = ae(c.button, u, {
128
165
  placement: s === "bottom" ? "top-start" : "bottom-start",
129
- offset: ge,
166
+ offset: ve,
130
167
  strategy: "fixed"
131
- }), g.setOpen(!0));
132
- }, y = () => {
133
- _(), c = null, B(u, c, T, r), C(e, c);
168
+ }), f.setOpen(!0));
169
+ }, h = () => {
170
+ k(), c = null, S(u, c, T, r), B(e, c);
134
171
  }, N = (o) => {
135
- if (!h && (T = o, c && _(), be(e, p, o, r, d), P(), c)) {
172
+ if (!E && (T = o, c && k(), me(e, p, o, r, d), P(), c)) {
136
173
  const n = Array.from(
137
- e.querySelectorAll(w)
138
- ).find((Z) => Z.dataset.bridgerteToolbarGroupId === (c == null ? void 0 : c.groupKey)), b = $(p, c.groupKey);
174
+ e.querySelectorAll(A)
175
+ ).find((ee) => ee.dataset.bridgerteToolbarGroupId === (c == null ? void 0 : c.groupKey)), b = $(p, c.groupKey);
139
176
  c = n && b ? {
140
177
  groupKey: c.groupKey,
141
178
  button: n,
142
179
  items: b.items
143
- } : null, B(u, c, T, r), C(e, c), c && M();
180
+ } : null, S(u, c, T, r), B(e, c), c && M();
144
181
  }
145
- }, z = () => {
146
- h || N(t.editor.getCommandStates());
147
- }, E = () => {
182
+ }, J = () => {
183
+ E || N(t.editor.getCommandStates());
184
+ }, y = () => {
148
185
  l.dataset.visible = "false", l.textContent = "";
149
- }, J = (o) => {
186
+ }, Q = (o) => {
150
187
  const n = o.dataset.tooltip;
151
188
  if (!d || !n || m) return;
152
189
  const b = o.getBoundingClientRect();
153
190
  l.textContent = n, l.dataset.visible = "true", l.style.left = `${b.left + b.width / 2}px`, l.style.top = `${b.top - fe}px`;
154
- }, K = (o) => {
155
- const n = S(o.target);
156
- n && J(n);
157
191
  }, H = (o) => {
158
- const n = o.relatedTarget, b = S(o.target);
159
- b && n instanceof Node && b.contains(n) || E();
160
- }, I = () => {
161
- m = null, delete e.dataset.dragging, document.removeEventListener("pointermove", R), document.removeEventListener("pointerup", L), document.removeEventListener("pointercancel", L);
192
+ const n = L(o.target);
193
+ n && Q(n);
194
+ }, I = (o) => {
195
+ const n = o.relatedTarget, b = L(o.target);
196
+ b && n instanceof Node && b.contains(n) || y();
197
+ }, K = () => {
198
+ m = null, delete e.dataset.dragging, document.removeEventListener("pointermove", R), document.removeEventListener("pointerup", x), document.removeEventListener("pointercancel", x);
162
199
  }, R = (o) => {
163
200
  if (!m) return;
164
201
  const n = m.startClientX - o.clientX;
165
- Math.abs(n) > me && (m.hasDragged = !0, v = !0, E(), y()), e.scrollLeft = m.startScrollLeft + n;
166
- }, L = (o) => {
202
+ Math.abs(n) > ge && (m.hasDragged = !0, v = !0, y(), h()), e.scrollLeft = m.startScrollLeft + n;
203
+ }, x = (o) => {
167
204
  const n = m;
168
- I(), n && o.type !== "pointercancel" && n.pointerType !== "mouse" && !n.hasDragged && n.startButton && (k(n.startButton), v = !0);
205
+ K(), n && o.type !== "pointercancel" && n.pointerType !== "mouse" && !n.hasDragged && n.startButton && (_(n.startButton), v = !0);
169
206
  }, O = (o) => {
170
207
  if (o.pointerType === "mouse" && o.button !== 0) return;
171
- const n = S(o.target);
208
+ const n = L(o.target);
172
209
  o.preventDefault(), m = {
173
210
  startClientX: o.clientX,
174
211
  startScrollLeft: e.scrollLeft,
175
212
  pointerType: o.pointerType,
176
213
  hasDragged: !1,
177
214
  startButton: n ?? void 0
178
- }, e.dataset.dragging = "true", E(), document.addEventListener("pointermove", R), document.addEventListener("pointerup", L), document.addEventListener("pointercancel", L);
179
- }, k = (o) => {
215
+ }, e.dataset.dragging = "true", y(), document.addEventListener("pointermove", R), document.addEventListener("pointerup", x), document.addEventListener("pointercancel", x);
216
+ }, _ = (o) => {
180
217
  if (!(o instanceof HTMLButtonElement) || o.disabled) return;
181
218
  const n = a.find((b) => b.id === o.dataset.bridgerteToolbarItemId);
182
219
  if (n) {
@@ -186,7 +223,7 @@ function Te(e, t) {
186
223
  menuId: n.id,
187
224
  command: n.command,
188
225
  panel: n.payloadPanel,
189
- currentValues: re(n, t.editor.getCommandStates()),
226
+ currentValues: ne(n, t.editor.getCommandStates()),
190
227
  anchorRect: {
191
228
  x: b.left,
192
229
  y: b.top,
@@ -198,65 +235,65 @@ function Te(e, t) {
198
235
  }
199
236
  t.editor.executeCommand(n.command);
200
237
  }
201
- }, Q = (o) => {
238
+ }, Y = (o) => {
202
239
  const n = $(
203
240
  p,
204
241
  o.dataset.bridgerteToolbarGroupId
205
242
  );
206
243
  if (!(!n || o.disabled)) {
207
244
  if ((c == null ? void 0 : c.groupKey) === n.key) {
208
- y();
245
+ h();
209
246
  return;
210
247
  }
211
248
  c = {
212
249
  groupKey: n.key,
213
250
  button: o,
214
251
  items: n.items
215
- }, E(), B(u, c, T, r), C(e, c), M(), se(u);
252
+ }, y(), S(u, c, T, r), B(e, c), M(), le(u);
216
253
  }
217
- }, x = (o) => {
254
+ }, w = (o) => {
218
255
  if (v) {
219
256
  v = !1, o.preventDefault(), o.stopPropagation();
220
257
  return;
221
258
  }
222
259
  const n = ye(o.target);
223
260
  if (n) {
224
- o.preventDefault(), o.stopPropagation(), Q(n);
261
+ o.preventDefault(), o.stopPropagation(), Y(n);
225
262
  return;
226
263
  }
227
- const b = S(o.target);
228
- b && (o.preventDefault(), o.stopPropagation(), k(b), y());
264
+ const b = L(o.target);
265
+ b && (o.preventDefault(), o.stopPropagation(), _(b), h());
229
266
  }, F = (o) => {
230
267
  o.pointerType === "mouse" && o.button !== 0 || o.preventDefault();
231
268
  }, X = (o) => {
232
269
  const n = o.target;
233
- n instanceof Node && (e.contains(n) || u.contains(n)) || y();
234
- }, q = (o) => {
270
+ n instanceof Node && (e.contains(n) || u.contains(n)) || h();
271
+ }, j = (o) => {
235
272
  if (c && u.contains(document.activeElement)) {
236
- le(
273
+ ie(
237
274
  o,
238
275
  u,
239
276
  c.button,
240
- k,
241
- y
277
+ _,
278
+ h
242
279
  );
243
280
  return;
244
281
  }
245
- o.key === "Escape" && y();
282
+ o.key === "Escape" && h();
246
283
  };
247
- e.classList.add("bridgerte__toolbar"), l.className = "bridgerte__toolbar-tooltip", l.dataset.visible = "false", u.className = "bridgerte__toolbar-group-menu", u.dataset.visible = "false", u.setAttribute("role", "menu"), e.dataset.placement = s, e.setAttribute("role", "toolbar"), e.setAttribute(
284
+ e.classList.add("bridgerte__toolbar"), l.className = "bridgerte__toolbar-tooltip", l.dataset.visible = "false", u.className = "bridgerte__floating-menu bridgerte__toolbar-group-menu", u.dataset.visible = "false", u.setAttribute("role", "menu"), e.dataset.placement = s, e.setAttribute("role", "toolbar"), e.setAttribute(
248
285
  "aria-label",
249
286
  s === "bottom" ? "BridgeRTE tabbar" : "BridgeRTE toolbar"
250
- ), e.addEventListener("pointerdown", O, !0), e.addEventListener("click", x), u.addEventListener("pointerdown", F, !0), u.addEventListener("click", x), document.addEventListener("click", X), document.addEventListener("keydown", q), d && (e.addEventListener("mouseover", K), e.addEventListener("mouseout", H)), e.addEventListener("focusout", E), P();
251
- const Y = t.editor.subscribeCommandStateChange(N);
287
+ ), e.addEventListener("pointerdown", O, !0), e.addEventListener("click", w), u.addEventListener("pointerdown", F, !0), u.addEventListener("click", w), document.addEventListener("click", X), document.addEventListener("keydown", j), d && (e.addEventListener("mouseover", H), e.addEventListener("mouseout", I)), e.addEventListener("focusout", y), P();
288
+ const Z = t.editor.subscribeCommandStateChange(N);
252
289
  return {
253
- update: z,
290
+ update: J,
254
291
  destroy() {
255
- h || (h = !0, I(), Y(), y(), e.removeEventListener("pointerdown", O, !0), e.removeEventListener("click", x), u.removeEventListener("pointerdown", F, !0), u.removeEventListener("click", x), document.removeEventListener("click", X), document.removeEventListener("keydown", q), d && (e.removeEventListener("mouseover", K), e.removeEventListener("mouseout", H)), V(), W(), e.removeEventListener("focusout", E), l.remove(), u.remove(), e.classList.remove("bridgerte__toolbar"), delete e.dataset.placement, e.textContent = "", e.removeAttribute("role"), e.removeAttribute("aria-label"));
292
+ E || (E = !0, K(), Z(), h(), e.removeEventListener("pointerdown", O, !0), e.removeEventListener("click", w), u.removeEventListener("pointerdown", F, !0), u.removeEventListener("click", w), document.removeEventListener("click", X), document.removeEventListener("keydown", j), d && (e.removeEventListener("mouseover", H), e.removeEventListener("mouseout", I)), W(), z(), e.removeEventListener("focusout", y), l.remove(), u.remove(), e.classList.remove("bridgerte__toolbar"), delete e.dataset.placement, e.textContent = "", e.removeAttribute("role"), e.removeAttribute("aria-label"));
256
293
  }
257
294
  };
258
295
  }
259
296
  export {
260
- Te as c
297
+ xe as c
261
298
  };
262
- //# sourceMappingURL=index-DRWIM218.js.map
299
+ //# sourceMappingURL=index-bN5Hs6-3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-bN5Hs6-3.js","sources":["../../dom/src/menuIcon/uiIcons.ts","../../dom/src/richTextToolbar/groupMenuKeyboard.ts","../../dom/src/richTextToolbar/render.ts","../../dom/src/richTextToolbar/index.ts"],"sourcesContent":["/**\n * DOM UI chrome icon 表。\n *\n * 这里放 toolbar 收纳入口、下拉箭头这类控件自身图标。它们不属于 `MenuItem.icon`\n * 跨端 schema,也不应该进入 `defaultMenuIcons` 的 schema 对齐检查。\n */\nexport const defaultMenuUiIcons = {\n toolbarGroup: `\n <svg\n aria-hidden=\"true\"\n class=\"lucide lucide-ellipsis\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n `,\n chevronDown: `\n <svg\n aria-hidden=\"true\"\n class=\"lucide lucide-chevron-down\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n `\n} as const;\n","export const getEnabledGroupMenuButtons = (menuElement: HTMLElement) => (\n Array.from(\n menuElement.querySelectorAll<HTMLButtonElement>('.bridgerte__toolbar-group-menu-item')\n ).filter((button) => !button.disabled)\n);\n\nexport const focusToolbarGroupMenuItem = (menuElement: HTMLElement, index: number) => {\n const buttons = getEnabledGroupMenuButtons(menuElement);\n const nextButton = buttons[index];\n\n if (nextButton) nextButton.focus();\n};\n\nexport const focusFirstToolbarGroupMenuItem = (menuElement: HTMLElement) => {\n /*\n * group menu 使用 ARIA menu 语义,打开后焦点必须进入第一个可操作项。\n * 这样键盘用户可以继续用方向键浏览,而不是停留在展开按钮上。\n */\n focusToolbarGroupMenuItem(menuElement, 0);\n};\n\nexport const handleToolbarGroupMenuKeyDown = (\n event: KeyboardEvent,\n menuElement: HTMLElement,\n returnButton: HTMLButtonElement,\n executeToolbarButton: (button: HTMLButtonElement) => void,\n closeGroupMenu: () => void\n) => {\n const buttons = getEnabledGroupMenuButtons(menuElement);\n const activeIndex = document.activeElement instanceof HTMLButtonElement\n ? buttons.indexOf(document.activeElement)\n : -1;\n const focusByOffset = (offset: number) => {\n if (buttons.length === 0) return;\n\n const baseIndex = activeIndex >= 0 ? activeIndex : 0;\n const nextIndex = (baseIndex + offset + buttons.length) % buttons.length;\n\n buttons[nextIndex]?.focus();\n };\n\n /*\n * ARIA menu 语义要求支持 roving focus。这里不改 toolbar 的横向键盘模型,\n * 只在已打开的纵向收纳菜单内处理上下方向、首尾跳转和执行/关闭。\n */\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusByOffset(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusByOffset(-1);\n break;\n case 'Home':\n event.preventDefault();\n buttons[0]?.focus();\n break;\n case 'End':\n event.preventDefault();\n buttons.at(-1)?.focus();\n break;\n case 'Enter':\n case ' ':\n if (document.activeElement instanceof HTMLButtonElement) {\n event.preventDefault();\n executeToolbarButton(document.activeElement);\n closeGroupMenu();\n returnButton.focus();\n }\n break;\n case 'Escape':\n event.preventDefault();\n returnButton.focus();\n closeGroupMenu();\n break;\n default:\n break;\n }\n};\n","import type { CommandState } from '@bridgerte/core';\nimport type { MenuItem, ResolvedToolbarItem } from '@bridgerte/native-spec';\nimport {\n appendMenuIcon,\n defaultMenuIcons,\n defaultMenuUiIcons\n} from './icons';\nimport { getMenuStateForItem } from '../menuRuntime';\nimport type {\n RichTextToolbarIcons,\n ToolbarGroupMenuState\n} from './type';\n\nexport const toolbarGroupButtonSelector = 'button[data-bridgerte-toolbar-group-id]';\nexport const toolbarButtonSelector = 'button[data-bridgerte-toolbar-item-id]';\n// 可执行按钮同时覆盖 toolbar 主按钮和 group menu 子项,避免浮层子菜单绕过统一命令入口。\nexport const toolbarExecutableButtonSelector = [\n toolbarButtonSelector,\n '.bridgerte__toolbar-group-menu-item'\n].join(',');\n\nconst getGroupMenuState = (items: MenuItem[], commandStates: CommandState[]) => {\n const itemStates = items.map((item) => getMenuStateForItem(item, commandStates));\n\n return {\n active: itemStates.some((state) => state.active),\n disabled: itemStates.length > 0 && itemStates.every((state) => state.disabled)\n };\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 renderToolbarGroupButton = (\n groupElement: HTMLElement,\n toolbarItem: Extract<ResolvedToolbarItem, { type: 'group' }>,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons,\n enableTooltip: boolean\n) => {\n const button = document.createElement('button');\n const groupState = getGroupMenuState(toolbarItem.items, commandStates);\n const iconSvg = toolbarItem.icon\n ? icons[toolbarItem.icon] ?? defaultMenuIcons[toolbarItem.icon]\n : defaultMenuUiIcons.toolbarGroup;\n const indicator = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__toolbar-button bridgerte__toolbar-group-button';\n button.disabled = groupState.disabled;\n button.dataset.active = String(groupState.active);\n button.dataset.bridgerteToolbarGroupId = toolbarItem.key;\n button.dataset.open = 'false';\n button.setAttribute('aria-label', toolbarItem.title);\n button.setAttribute('aria-haspopup', 'menu');\n button.setAttribute('aria-expanded', 'false');\n button.setAttribute('aria-pressed', String(groupState.active));\n if (enableTooltip) button.dataset.tooltip = toolbarItem.title;\n\n appendMenuIcon(button, iconSvg, toolbarItem.title);\n\n indicator.className = 'bridgerte__toolbar-group-indicator';\n indicator.setAttribute('aria-hidden', 'true');\n indicator.innerHTML = defaultMenuUiIcons.chevronDown;\n button.append(indicator);\n groupElement.append(button);\n};\n\n/**\n * 渲染 toolbar 横向主入口。\n *\n * 字符串菜单渲染为按钮,`|` 渲染分割线,group 只渲染一个收纳入口;组内命令交给\n * renderToolbarGroupMenu 渲染,避免 `menuKeys` 退化成另一种横向分隔语法。\n */\nexport const 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 renderToolbarGroupButton(\n activeGroupElement,\n toolbarItem,\n commandStates,\n icons,\n enableTooltip\n );\n });\n};\n\n/**\n * 渲染 group button 打开的纵向收纳菜单。\n *\n * 浮层只展示 MenuItem 子项并复用现有 item id,点击执行仍由 index.ts 统一走 EditorAPI。\n */\nexport const renderToolbarGroupMenu = (\n menuElement: HTMLElement,\n groupMenuState: ToolbarGroupMenuState | null,\n commandStates: CommandState[],\n icons: RichTextToolbarIcons\n) => {\n menuElement.textContent = '';\n\n if (!groupMenuState) {\n menuElement.dataset.visible = 'false';\n return;\n }\n\n groupMenuState.items.forEach((item) => {\n const state = getMenuStateForItem(item, commandStates);\n const button = document.createElement('button');\n const iconSvg = icons[item.icon] ?? defaultMenuIcons[item.icon];\n const labelElement = document.createElement('span');\n\n button.type = 'button';\n button.className = 'bridgerte__menu-item bridgerte__toolbar-group-menu-item';\n button.disabled = state.disabled;\n button.dataset.active = String(state.active);\n button.dataset.bridgerteToolbarItemId = item.id;\n button.setAttribute('role', 'menuitem');\n button.setAttribute('aria-label', item.label);\n button.setAttribute('aria-pressed', String(state.active));\n\n appendMenuIcon(button, iconSvg, item.label);\n labelElement.className = 'bridgerte__toolbar-group-menu-label';\n labelElement.textContent = item.label;\n button.append(labelElement);\n menuElement.append(button);\n });\n\n menuElement.dataset.visible = 'true';\n menuElement.style.minWidth = `${groupMenuState.button.offsetWidth}px`;\n};\n\nexport const syncToolbarGroupButtonState = (\n container: HTMLElement,\n groupMenuState: ToolbarGroupMenuState | null\n) => {\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector).forEach((button) => {\n const open = groupMenuState?.groupKey === button.dataset.bridgerteToolbarGroupId;\n\n button.dataset.open = String(open);\n button.setAttribute('aria-expanded', String(open));\n });\n};\n\nexport const findToolbarGroupMenuItem = (\n toolbarItems: ResolvedToolbarItem[],\n groupKey: string | undefined\n) => toolbarItems.find((item): item is Extract<ResolvedToolbarItem, { type: 'group' }> => (\n item.type === 'group' && item.key === groupKey\n));\n","import type { CommandState } from '@bridgerte/core';\nimport {\n defaultMenuSchema,\n resolveToolbarMenu\n} from '@bridgerte/native-spec';\nimport { createFloatingLayer, type RichTextFloatingLayer } from '../floatingLayer';\nimport { bindTouchPressedState } from '../interactionState';\nimport {\n getPayloadPanelCurrentValues,\n resolveMenuSchemaForDom\n} from '../menuRuntime';\nimport {\n focusFirstToolbarGroupMenuItem,\n handleToolbarGroupMenuKeyDown\n} from './groupMenuKeyboard';\nimport {\n findToolbarGroupMenuItem,\n renderToolbar,\n renderToolbarGroupMenu,\n syncToolbarGroupButtonState,\n toolbarExecutableButtonSelector,\n toolbarGroupButtonSelector\n} from './render';\nimport type {\n RichTextToolbarAPI,\n ToolbarGroupMenuState,\n RichTextToolbarOptions,\n ToolbarDragState\n} from './type';\n\nconst toolbarDragClickThresholdPx = 4;\nconst toolbarTooltipOffsetPx = 8;\nconst toolbarGroupMenuOffsetPx = 6;\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>(toolbarExecutableButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\n};\n\nconst getToolbarGroupButtonFromTarget = (target: EventTarget | null) => {\n const button = target instanceof Element\n ? target.closest<HTMLButtonElement>(toolbarGroupButtonSelector)\n : null;\n\n return button instanceof HTMLButtonElement ? button : null;\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 groupMenuElement = 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 let latestCommandStates = options.editor.getCommandStates();\n let groupMenuState: ToolbarGroupMenuState | null = null;\n let groupMenuFloatingLayer: RichTextFloatingLayer | null = null;\n const clearToolbarPressedState = bindTouchPressedState(container, {\n targetSelector: [\n 'button[data-bridgerte-toolbar-item-id]',\n 'button[data-bridgerte-toolbar-group-id]'\n ].join(',')\n });\n const clearGroupMenuPressedState = bindTouchPressedState(groupMenuElement, {\n targetSelector: '.bridgerte__toolbar-group-menu-item'\n });\n\n const mountToolbarOverlays = () => {\n // 独立 toolbar 可能不在 `.bridgerte` 内,渲染按钮会清空 container,需要把浮层重新挂回去。\n overlayHost.append(tooltipElement);\n overlayHost.append(groupMenuElement);\n };\n\n const closeGroupMenuFloatingLayer = () => {\n groupMenuFloatingLayer?.setOpen(false);\n groupMenuFloatingLayer?.destroy();\n groupMenuFloatingLayer = null;\n };\n\n const openGroupMenuFloatingLayer = () => {\n if (!groupMenuState) return;\n\n closeGroupMenuFloatingLayer();\n /*\n * group menu 和 hoverbar/mention/slash 一样属于轻浮层,必须走 floatingLayer。\n * 这里按 toolbar placement 给出首选方向,真正的翻转、键盘可视区和左右夹紧交给\n * createFloatingLayer 内部的 visualViewport + flip + shift + clamp 统一处理。\n */\n groupMenuFloatingLayer = createFloatingLayer(groupMenuState.button, groupMenuElement, {\n placement: placement === 'bottom' ? 'top-start' : 'bottom-start',\n offset: toolbarGroupMenuOffsetPx,\n strategy: 'fixed'\n });\n groupMenuFloatingLayer.setOpen(true);\n };\n\n const closeGroupMenu = () => {\n closeGroupMenuFloatingLayer();\n groupMenuState = null;\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n };\n\n const renderStates = (states: CommandState[]) => {\n if (destroyed) return;\n\n latestCommandStates = states;\n if (groupMenuState) closeGroupMenuFloatingLayer();\n renderToolbar(container, toolbarItems, states, icons, enableTooltip);\n mountToolbarOverlays();\n if (groupMenuState) {\n const nextButton = Array.from(\n container.querySelectorAll<HTMLButtonElement>(toolbarGroupButtonSelector)\n ).find((button) => button.dataset.bridgerteToolbarGroupId === groupMenuState?.groupKey);\n const nextGroupItem = findToolbarGroupMenuItem(toolbarItems, groupMenuState.groupKey);\n\n groupMenuState = nextButton && nextGroupItem\n ? {\n groupKey: groupMenuState.groupKey,\n button: nextButton,\n items: nextGroupItem.items\n }\n : null;\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n if (groupMenuState) openGroupMenuFloatingLayer();\n }\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 closeGroupMenu();\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 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 toggleGroupMenu = (button: HTMLButtonElement) => {\n const groupItem = findToolbarGroupMenuItem(\n toolbarItems,\n button.dataset.bridgerteToolbarGroupId\n );\n\n if (!groupItem || button.disabled) return;\n\n if (groupMenuState?.groupKey === groupItem.key) {\n closeGroupMenu();\n return;\n }\n\n groupMenuState = {\n groupKey: groupItem.key,\n button,\n items: groupItem.items\n };\n hideTooltip();\n renderToolbarGroupMenu(groupMenuElement, groupMenuState, latestCommandStates, icons);\n syncToolbarGroupButtonState(container, groupMenuState);\n openGroupMenuFloatingLayer();\n focusFirstToolbarGroupMenuItem(groupMenuElement);\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 groupButton = getToolbarGroupButtonFromTarget(event.target);\n if (groupButton) {\n event.preventDefault();\n event.stopPropagation();\n toggleGroupMenu(groupButton);\n return;\n }\n\n const button = getToolbarButtonFromTarget(event.target);\n if (!button) return;\n\n event.preventDefault();\n event.stopPropagation();\n executeToolbarButton(button);\n closeGroupMenu();\n };\n\n const handleGroupMenuPointerDown = (event: PointerEvent) => {\n /*\n * group 菜单浮层挂在 toolbar 容器外,不能复用容器级 pointerdown。\n * 子菜单点击仍要保留编辑区 selection,否则格式命令会丢失原选区。\n */\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n\n event.preventDefault();\n };\n\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target;\n\n if (\n target instanceof Node\n && (container.contains(target) || groupMenuElement.contains(target))\n ) return;\n\n closeGroupMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (groupMenuState && groupMenuElement.contains(document.activeElement)) {\n handleToolbarGroupMenuKeyDown(\n event,\n groupMenuElement,\n groupMenuState.button,\n executeToolbarButton,\n closeGroupMenu\n );\n return;\n }\n\n if (event.key !== 'Escape') return;\n\n closeGroupMenu();\n };\n\n container.classList.add('bridgerte__toolbar');\n tooltipElement.className = 'bridgerte__toolbar-tooltip';\n tooltipElement.dataset.visible = 'false';\n groupMenuElement.className = 'bridgerte__floating-menu bridgerte__toolbar-group-menu';\n groupMenuElement.dataset.visible = 'false';\n groupMenuElement.setAttribute('role', 'menu');\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 groupMenuElement.addEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.addEventListener('click', handleClick);\n document.addEventListener('click', handleDocumentClick);\n document.addEventListener('keydown', handleKeyDown);\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 closeGroupMenu();\n container.removeEventListener('pointerdown', handlePointerDown, true);\n container.removeEventListener('click', handleClick);\n groupMenuElement.removeEventListener('pointerdown', handleGroupMenuPointerDown, true);\n groupMenuElement.removeEventListener('click', handleClick);\n document.removeEventListener('click', handleDocumentClick);\n document.removeEventListener('keydown', handleKeyDown);\n if (enableTooltip) {\n container.removeEventListener('mouseover', handleTooltipTarget);\n container.removeEventListener('mouseout', handleTooltipLeave);\n }\n clearToolbarPressedState();\n clearGroupMenuPressedState();\n container.removeEventListener('focusout', hideTooltip);\n tooltipElement.remove();\n groupMenuElement.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":["defaultMenuUiIcons","getEnabledGroupMenuButtons","menuElement","button","focusToolbarGroupMenuItem","index","nextButton","focusFirstToolbarGroupMenuItem","handleToolbarGroupMenuKeyDown","event","returnButton","executeToolbarButton","closeGroupMenu","buttons","activeIndex","focusByOffset","offset","nextIndex","_a","_b","toolbarGroupButtonSelector","toolbarButtonSelector","toolbarExecutableButtonSelector","getGroupMenuState","items","commandStates","itemStates","item","getMenuStateForItem","state","renderToolbarButton","groupElement","icons","enableTooltip","iconSvg","defaultMenuIcons","appendMenuIcon","renderToolbarGroupButton","toolbarItem","groupState","indicator","renderToolbar","toolbarElement","toolbarItems","currentGroup","separatorElement","nextGroup","activeGroupElement","renderToolbarGroupMenu","groupMenuState","labelElement","syncToolbarGroupButtonState","container","open","findToolbarGroupMenuItem","groupKey","toolbarDragClickThresholdPx","toolbarTooltipOffsetPx","toolbarGroupMenuOffsetPx","canUseHoverTooltip","getToolbarButtonFromTarget","target","getToolbarGroupButtonFromTarget","createRichTextToolbar","options","placement","menuSchema","resolveMenuSchemaForDom","defaultMenuSchema","resolveToolbarMenu","executableMenuItems","tooltipElement","groupMenuElement","overlayHost","destroyed","dragState","shouldSuppressNextClick","latestCommandStates","groupMenuFloatingLayer","clearToolbarPressedState","bindTouchPressedState","clearGroupMenuPressedState","mountToolbarOverlays","closeGroupMenuFloatingLayer","openGroupMenuFloatingLayer","createFloatingLayer","renderStates","states","nextGroupItem","update","hideTooltip","showTooltip","tooltipText","buttonRect","handleTooltipTarget","handleTooltipLeave","relatedTarget","stopToolbarDrag","handlePointerMove","handlePointerUp","deltaX","currentDragState","handlePointerDown","startButton","menuItem","getPayloadPanelCurrentValues","toggleGroupMenu","groupItem","handleClick","groupButton","handleGroupMenuPointerDown","handleDocumentClick","handleKeyDown","unsubscribe"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ "use strict";const q=require("./native-spec.cjs"),m=require("./index-BaOlPu8L.cjs"),X={toolbarGroup:`
2
+ <svg
3
+ aria-hidden="true"
4
+ class="lucide lucide-ellipsis"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ width="18"
7
+ height="18"
8
+ viewBox="0 0 24 24"
9
+ fill="none"
10
+ stroke="currentColor"
11
+ stroke-width="2"
12
+ stroke-linecap="round"
13
+ stroke-linejoin="round"
14
+ >
15
+ <circle cx="12" cy="12" r="1" />
16
+ <circle cx="19" cy="12" r="1" />
17
+ <circle cx="5" cy="12" r="1" />
18
+ </svg>
19
+ `,chevronDown:`
20
+ <svg
21
+ aria-hidden="true"
22
+ class="lucide lucide-chevron-down"
23
+ xmlns="http://www.w3.org/2000/svg"
24
+ width="12"
25
+ height="12"
26
+ viewBox="0 0 24 24"
27
+ fill="none"
28
+ stroke="currentColor"
29
+ stroke-width="2"
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ >
33
+ <path d="m6 9 6 6 6-6" />
34
+ </svg>
35
+ `},U=e=>Array.from(e.querySelectorAll(".bridgerte__toolbar-group-menu-item")).filter(t=>!t.disabled),Z=(e,t)=>{const i=U(e)[t];i&&i.focus()},ee=e=>{Z(e,0)},te=(e,t,s,i,p)=>{var l,d;const a=U(t),r=document.activeElement instanceof HTMLButtonElement?a.indexOf(document.activeElement):-1,u=f=>{var h;if(a.length===0)return;const g=((r>=0?r:0)+f+a.length)%a.length;(h=a[g])==null||h.focus()};switch(e.key){case"ArrowDown":e.preventDefault(),u(1);break;case"ArrowUp":e.preventDefault(),u(-1);break;case"Home":e.preventDefault(),(l=a[0])==null||l.focus();break;case"End":e.preventDefault(),(d=a.at(-1))==null||d.focus();break;case"Enter":case" ":document.activeElement instanceof HTMLButtonElement&&(e.preventDefault(),i(document.activeElement),p(),s.focus());break;case"Escape":e.preventDefault(),s.focus(),p();break}},G="button[data-bridgerte-toolbar-group-id]",oe="button[data-bridgerte-toolbar-item-id]",re=[oe,".bridgerte__toolbar-group-menu-item"].join(","),ne=(e,t)=>{const s=e.map(i=>m.getMenuStateForItem(i,t));return{active:s.some(i=>i.active),disabled:s.length>0&&s.every(i=>i.disabled)}},ae=(e,t,s,i,p)=>{const a=m.getMenuStateForItem(t,s),r=document.createElement("button"),u=i[t.icon]??m.defaultMenuIcons[t.icon];r.type="button",r.className="bridgerte__toolbar-button",r.disabled=a.disabled,r.dataset.active=String(a.active),r.dataset.bridgerteToolbarItemId=t.id,r.setAttribute("aria-label",t.label),r.setAttribute("aria-pressed",String(a.active)),p&&(r.dataset.tooltip=t.label),m.appendMenuIcon(r,u,t.label),e.append(r)},se=(e,t,s,i,p)=>{const a=document.createElement("button"),r=ne(t.items,s),u=t.icon?i[t.icon]??m.defaultMenuIcons[t.icon]:X.toolbarGroup,l=document.createElement("span");a.type="button",a.className="bridgerte__toolbar-button bridgerte__toolbar-group-button",a.disabled=r.disabled,a.dataset.active=String(r.active),a.dataset.bridgerteToolbarGroupId=t.key,a.dataset.open="false",a.setAttribute("aria-label",t.title),a.setAttribute("aria-haspopup","menu"),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-pressed",String(r.active)),p&&(a.dataset.tooltip=t.title),m.appendMenuIcon(a,u,t.title),l.className="bridgerte__toolbar-group-indicator",l.setAttribute("aria-hidden","true"),l.innerHTML=X.chevronDown,a.append(l),e.append(a)},le=(e,t,s,i,p)=>{e.textContent="";let a="",r=null;t.forEach(u=>{if(u.type==="separator"){a="",r=null;const f=document.createElement("span");f.className="bridgerte__toolbar-separator",f.dataset.separatorId=u.key,f.setAttribute("aria-hidden","true"),e.append(f);return}const l=u.type==="button"?u.item.group:u.key;(!r||a!==l)&&(a=l,r=document.createElement("div"),r.className="bridgerte__toolbar-group",r.dataset.group=l,u.type==="group"&&r.setAttribute("aria-label",u.title),e.append(r));const d=r;if(u.type==="button"){ae(d,u.item,s,i,p);return}se(d,u,s,i,p)})},B=(e,t,s,i)=>{if(e.textContent="",!t){e.dataset.visible="false";return}t.items.forEach(p=>{const a=m.getMenuStateForItem(p,s),r=document.createElement("button"),u=i[p.icon]??m.defaultMenuIcons[p.icon],l=document.createElement("span");r.type="button",r.className="bridgerte__menu-item bridgerte__toolbar-group-menu-item",r.disabled=a.disabled,r.dataset.active=String(a.active),r.dataset.bridgerteToolbarItemId=p.id,r.setAttribute("role","menuitem"),r.setAttribute("aria-label",p.label),r.setAttribute("aria-pressed",String(a.active)),m.appendMenuIcon(r,u,p.label),l.className="bridgerte__toolbar-group-menu-label",l.textContent=p.label,r.append(l),e.append(r)}),e.dataset.visible="true",e.style.minWidth=`${t.button.offsetWidth}px`},C=(e,t)=>{e.querySelectorAll(G).forEach(s=>{const i=(t==null?void 0:t.groupKey)===s.dataset.bridgerteToolbarGroupId;s.dataset.open=String(i),s.setAttribute("aria-expanded",String(i))})},j=(e,t)=>e.find(s=>s.type==="group"&&s.key===t),ie=4,ue=8,de=6,ce=()=>{var e;return typeof window<"u"&&((e=window.matchMedia)==null?void 0:e.call(window,"(hover: hover) and (pointer: fine)").matches)===!0},S=e=>{const t=e instanceof Element?e.closest(re):null;return t instanceof HTMLButtonElement?t:null},pe=e=>{const t=e instanceof Element?e.closest(G):null;return t instanceof HTMLButtonElement?t:null};function be(e,t){const s=t.placement??"top",i=m.resolveMenuSchemaForDom(t.menuSchema??q.defaultMenuSchema,{menuLabels:t.menuLabels,payloadPanelConfig:t.payloadPanelConfig}),p=q.resolveToolbarMenu(t.toolbarConfig,i),a=p.flatMap(o=>o.type==="button"?[o.item]:o.type==="group"?o.items:[]),r=t.icons??{},u=ce(),l=document.createElement("div"),d=document.createElement("div"),f=e.closest(".bridgerte")??e;let T=!1,g=null,h=!1,x=t.editor.getCommandStates(),c=null,v=null;const $=m.bindTouchPressedState(e,{targetSelector:["button[data-bridgerte-toolbar-item-id]","button[data-bridgerte-toolbar-group-id]"].join(",")}),V=m.bindTouchPressedState(d,{targetSelector:".bridgerte__toolbar-group-menu-item"}),D=()=>{f.append(l),f.append(d)},k=()=>{v==null||v.setOpen(!1),v==null||v.destroy(),v=null},M=()=>{c&&(k(),v=m.createFloatingLayer(c.button,d,{placement:s==="bottom"?"top-start":"bottom-start",offset:de,strategy:"fixed"}),v.setOpen(!0))},y=()=>{k(),c=null,B(d,c,x,r),C(e,c)},A=o=>{if(!T&&(x=o,c&&k(),le(e,p,o,r,u),D(),c)){const n=Array.from(e.querySelectorAll(G)).find(Y=>Y.dataset.bridgerteToolbarGroupId===(c==null?void 0:c.groupKey)),b=j(p,c.groupKey);c=n&&b?{groupKey:c.groupKey,button:n,items:b.items}:null,B(d,c,x,r),C(e,c),c&&M()}},W=()=>{T||A(t.editor.getCommandStates())},E=()=>{l.dataset.visible="false",l.textContent=""},z=o=>{const n=o.dataset.tooltip;if(!u||!n||g)return;const b=o.getBoundingClientRect();l.textContent=n,l.dataset.visible="true",l.style.left=`${b.left+b.width/2}px`,l.style.top=`${b.top-ue}px`},P=o=>{const n=S(o.target);n&&z(n)},I=o=>{const n=o.relatedTarget,b=S(o.target);b&&n instanceof Node&&b.contains(n)||E()},N=()=>{g=null,delete e.dataset.dragging,document.removeEventListener("pointermove",H),document.removeEventListener("pointerup",w),document.removeEventListener("pointercancel",w)},H=o=>{if(!g)return;const n=g.startClientX-o.clientX;Math.abs(n)>ie&&(g.hasDragged=!0,h=!0,E(),y()),e.scrollLeft=g.startScrollLeft+n},w=o=>{const n=g;N(),n&&o.type!=="pointercancel"&&n.pointerType!=="mouse"&&!n.hasDragged&&n.startButton&&(_(n.startButton),h=!0)},K=o=>{if(o.pointerType==="mouse"&&o.button!==0)return;const n=S(o.target);o.preventDefault(),g={startClientX:o.clientX,startScrollLeft:e.scrollLeft,pointerType:o.pointerType,hasDragged:!1,startButton:n??void 0},e.dataset.dragging="true",E(),document.addEventListener("pointermove",H),document.addEventListener("pointerup",w),document.addEventListener("pointercancel",w)},_=o=>{if(!(o instanceof HTMLButtonElement)||o.disabled)return;const n=a.find(b=>b.id===o.dataset.bridgerteToolbarItemId);if(n){if(n.payloadPanel){const b=o.getBoundingClientRect();t.editor.requestPayloadPanel({menuId:n.id,command:n.command,panel:n.payloadPanel,currentValues:m.getPayloadPanelCurrentValues(n,t.editor.getCommandStates()),anchorRect:{x:b.left,y:b.top,width:b.width,height:b.height}});return}t.editor.executeCommand(n.command)}},J=o=>{const n=j(p,o.dataset.bridgerteToolbarGroupId);if(!(!n||o.disabled)){if((c==null?void 0:c.groupKey)===n.key){y();return}c={groupKey:n.key,button:o,items:n.items},E(),B(d,c,x,r),C(e,c),M(),ee(d)}},L=o=>{if(h){h=!1,o.preventDefault(),o.stopPropagation();return}const n=pe(o.target);if(n){o.preventDefault(),o.stopPropagation(),J(n);return}const b=S(o.target);b&&(o.preventDefault(),o.stopPropagation(),_(b),y())},R=o=>{o.pointerType==="mouse"&&o.button!==0||o.preventDefault()},F=o=>{const n=o.target;n instanceof Node&&(e.contains(n)||d.contains(n))||y()},O=o=>{if(c&&d.contains(document.activeElement)){te(o,d,c.button,_,y);return}o.key==="Escape"&&y()};e.classList.add("bridgerte__toolbar"),l.className="bridgerte__toolbar-tooltip",l.dataset.visible="false",d.className="bridgerte__floating-menu bridgerte__toolbar-group-menu",d.dataset.visible="false",d.setAttribute("role","menu"),e.dataset.placement=s,e.setAttribute("role","toolbar"),e.setAttribute("aria-label",s==="bottom"?"BridgeRTE tabbar":"BridgeRTE toolbar"),e.addEventListener("pointerdown",K,!0),e.addEventListener("click",L),d.addEventListener("pointerdown",R,!0),d.addEventListener("click",L),document.addEventListener("click",F),document.addEventListener("keydown",O),u&&(e.addEventListener("mouseover",P),e.addEventListener("mouseout",I)),e.addEventListener("focusout",E),D();const Q=t.editor.subscribeCommandStateChange(A);return{update:W,destroy(){T||(T=!0,N(),Q(),y(),e.removeEventListener("pointerdown",K,!0),e.removeEventListener("click",L),d.removeEventListener("pointerdown",R,!0),d.removeEventListener("click",L),document.removeEventListener("click",F),document.removeEventListener("keydown",O),u&&(e.removeEventListener("mouseover",P),e.removeEventListener("mouseout",I)),$(),V(),e.removeEventListener("focusout",E),l.remove(),d.remove(),e.classList.remove("bridgerte__toolbar"),delete e.dataset.placement,e.textContent="",e.removeAttribute("role"),e.removeAttribute("aria-label"))}}}exports.createRichTextToolbar=be;
36
+ //# sourceMappingURL=index-hd9Zi2DV.cjs.map