@shadow-garden/bapbong-ui 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9,6 +9,13 @@ function shortcutLabel(command, registries) {
9
9
  }
10
10
  return void 0;
11
11
  }
12
+ var TABS_CSS = `
13
+ .bb-tabs{display:inline-flex;align-self:flex-start;border:0.5px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;overflow:hidden}
14
+ .bb-tab{height:30px;padding:0 18px;border:0;border-right:0.5px solid var(--bb-ui-border,#e3e3e0);background:transparent;color:inherit;opacity:.65;font:inherit;font-size:13px;cursor:pointer}
15
+ .bb-tab:last-child{border-right:0}
16
+ .bb-tab:hover{background:var(--bb-ui-hover,#f1efe8);opacity:.9}
17
+ .bb-tab[aria-selected="true"]{background:var(--bb-ui-active-bg,#e6f1fb);color:var(--bb-ui-active-fg,#0c447c);opacity:1}
18
+ `;
12
19
  function injectStyle(id, css) {
13
20
  if (document.getElementById(id)) return;
14
21
  const el5 = document.createElement("style");
@@ -618,6 +625,7 @@ var STYLE3 = `
618
625
  .bb-toolbar{display:flex;gap:10px;align-items:center;flex-wrap:nowrap;overflow:hidden;padding:6px 8px;font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);color:var(--bb-ui-fg,#2c2c2a);background:var(--bb-ui-control-bg,var(--bb-ui-bg,#fff));border-bottom:1px solid var(--bb-ui-border,#e3e3e0);box-sizing:border-box}
619
626
  .bb-toolbar *{box-sizing:border-box}
620
627
  .bb-toolbar-group{display:flex;gap:2px;flex:none}
628
+ .bb-toolbar-group[hidden]{display:none}
621
629
  .bb-toolbar-group+.bb-toolbar-group{padding-left:10px;border-left:1px solid var(--bb-ui-border,#e3e3e0)}
622
630
  .bb-toolbar-more{margin-left:auto;flex:none}
623
631
  .bb-toolbar-pop{position:absolute;z-index:1200;top:100%;left:0;right:0;margin-top:4px;display:flex;flex-wrap:wrap;gap:10px;row-gap:6px;align-items:center;padding:6px 8px;background:var(--bb-ui-menu-bg,#fff);-webkit-backdrop-filter:var(--bb-ui-pop-filter,none);backdrop-filter:var(--bb-ui-pop-filter,none);border:1px solid var(--bb-ui-pop-border,var(--bb-ui-border,#e3e3e0));border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.16);font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);color:var(--bb-ui-fg,#2c2c2a)}
@@ -626,6 +634,9 @@ var STYLE3 = `
626
634
  .bb-toolbar-btn:hover{background:var(--bb-ui-hover,#f1efe8)}
627
635
  .bb-toolbar-btn.is-active{background:var(--bb-ui-active-bg,#e6f1fb);color:var(--bb-ui-active-fg,#0c447c);border-color:var(--bb-ui-active-border,#b5d4f4)}
628
636
  .bb-toolbar-btn:disabled{opacity:.38;cursor:default}
637
+ .bb-toolbar-btn.bb-btn-accent{gap:5px;padding:0 9px;font-size:12.5px;white-space:nowrap;background:var(--bb-ui-active-bg,#e6f1fb);color:var(--bb-ui-active-fg,#0c447c);border-color:var(--bb-ui-active-border,#b5d4f4)}
638
+ .bb-toolbar-btn.bb-btn-accent:hover{background:var(--bb-ui-active-bg,#e6f1fb);border-color:var(--bb-ui-active-fg,#0c447c)}
639
+ .bb-btn-caret{font-size:9px;opacity:.7;line-height:1}
629
640
  .bb-toolbar-select{height:30px;border:1px solid var(--bb-ui-control-border,var(--bb-ui-border,#e3e3e0));border-radius:6px;background:var(--bb-ui-control-bg,var(--bb-ui-bg,#fff));color:inherit;font-family:inherit;font-size:13px;padding:0 6px;cursor:pointer}
630
641
  .bb-toolbar-select:hover{background:var(--bb-ui-hover,#f1efe8)}
631
642
  .bb-i-bold{font-weight:700}.bb-i-italic{font-style:italic}.bb-i-underline{text-decoration:underline}.bb-i-strike{text-decoration:line-through}
@@ -650,6 +661,25 @@ function defaultToolbarGroups(commands) {
650
661
  const rest = names.filter((n) => !n.startsWith("align-"));
651
662
  return [rest, aligns].filter((g2) => g2.length > 0);
652
663
  }
664
+ function foldPlan(candidates, avail, moreWidth, gap) {
665
+ const vis = candidates.filter((c2) => !c2.hidden);
666
+ const rowWidth = vis.reduce((sum, c2) => sum + c2.width, 0) + gap * Math.max(0, vis.length - 1);
667
+ const folded = /* @__PURE__ */ new Set();
668
+ if (rowWidth <= avail + 1) return folded;
669
+ const order = [
670
+ ...vis.filter((c2) => !c2.sticky).reverse(),
671
+ ...vis.filter((c2) => c2.sticky).reverse()
672
+ ];
673
+ const fitsRemaining = () => {
674
+ const rem = vis.filter((c2) => !folded.has(c2.idx));
675
+ return rem.reduce((sum, c2) => sum + c2.width, 0) + gap * rem.length + moreWidth <= avail + 1;
676
+ };
677
+ for (const c2 of order) {
678
+ if (fitsRemaining()) break;
679
+ folded.add(c2.idx);
680
+ }
681
+ return folded;
682
+ }
653
683
  function mountToolbar(host, editor, options = {}) {
654
684
  injectStyle("bb-ui-toolbar-styles", STYLE3);
655
685
  const items = { ...DEFAULT_ITEMS, ...options.items ?? {} };
@@ -660,17 +690,25 @@ function mountToolbar(host, editor, options = {}) {
660
690
  root.className = "bb-toolbar";
661
691
  root.setAttribute("role", "toolbar");
662
692
  const buttons = [];
693
+ const groupList = [];
694
+ const conditionalGroups = [];
663
695
  const selects = [];
664
696
  const colors = [];
665
697
  const splits = [];
666
698
  let latest = null;
667
699
  for (const group of groups) {
668
- const entries = group.filter(
700
+ const spec = Array.isArray(group) ? { entries: group } : group;
701
+ const entries = spec.entries.filter(
669
702
  (e) => typeof e !== "string" || editor.commands.has(e)
670
703
  );
671
704
  if (entries.length === 0) continue;
672
705
  const groupEl = document.createElement("div");
673
706
  groupEl.className = "bb-toolbar-group";
707
+ groupList.push({ el: groupEl, sticky: !!spec.sticky, lastWidth: 0 });
708
+ if (spec.visible) {
709
+ conditionalGroups.push({ el: groupEl, visible: spec.visible });
710
+ groupEl.hidden = true;
711
+ }
674
712
  for (const entry of entries) {
675
713
  if (typeof entry !== "string" && entry.kind === "select") {
676
714
  const sel = document.createElement("select");
@@ -696,12 +734,24 @@ function mountToolbar(host, editor, options = {}) {
696
734
  if (typeof entry !== "string" && entry.kind === "button") {
697
735
  const btn2 = document.createElement("button");
698
736
  btn2.type = "button";
699
- btn2.className = "bb-toolbar-btn";
737
+ btn2.className = "bb-toolbar-btn" + (entry.accent ? " bb-btn-accent" : "");
700
738
  btn2.title = entry.title;
701
739
  btn2.setAttribute("aria-label", entry.title);
702
740
  btn2.setAttribute("aria-haspopup", "dialog");
703
741
  if (entry.svg) btn2.innerHTML = entry.svg;
704
742
  else btn2.textContent = entry.label ?? entry.title;
743
+ if (entry.text) {
744
+ const span = document.createElement("span");
745
+ span.textContent = entry.text;
746
+ btn2.appendChild(span);
747
+ }
748
+ if (entry.caret) {
749
+ const caret = document.createElement("span");
750
+ caret.className = "bb-btn-caret";
751
+ caret.setAttribute("aria-hidden", "true");
752
+ caret.textContent = "\u25BE";
753
+ btn2.appendChild(caret);
754
+ }
705
755
  btn2.addEventListener("mousedown", (e) => e.preventDefault());
706
756
  btn2.addEventListener("click", () => entry.onClick(btn2));
707
757
  groupEl.appendChild(btn2);
@@ -862,19 +912,52 @@ function mountToolbar(host, editor, options = {}) {
862
912
  pop.hidden = !pop.hidden;
863
913
  moreBtn.setAttribute("aria-expanded", String(!pop.hidden));
864
914
  });
865
- const fits = () => root.scrollWidth <= root.clientWidth + 1;
915
+ let gapPx = -1;
916
+ let moreW = -1;
917
+ const anchorIn = (container, idx) => {
918
+ for (let j = idx + 1; j < groupList.length; j++)
919
+ if (groupList[j].el.parentElement === container) return groupList[j].el;
920
+ return container === root ? moreBtn : null;
921
+ };
866
922
  const layout = () => {
867
- while (pop.firstChild) root.insertBefore(pop.firstChild, moreBtn);
868
- moreBtn.style.display = "none";
869
- closePop();
870
- wrap.querySelectorAll(".bb-split-pop").forEach((p) => p.hidden = true);
871
- if (fits()) return;
872
- moreBtn.style.display = "";
873
- const groupEls = Array.from(root.children).filter(
874
- (el5) => el5.classList.contains("bb-toolbar-group")
875
- );
876
- for (let i = groupEls.length - 1; i >= 0 && !fits(); i--) {
877
- pop.insertBefore(groupEls[i], pop.firstChild);
923
+ if (gapPx < 0)
924
+ gapPx = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
925
+ if (moreW < 0) {
926
+ moreBtn.style.visibility = "hidden";
927
+ const prev = moreBtn.style.display;
928
+ moreBtn.style.display = "";
929
+ moreW = moreBtn.offsetWidth;
930
+ moreBtn.style.display = prev;
931
+ moreBtn.style.visibility = "";
932
+ }
933
+ const avail = root.clientWidth;
934
+ const candidates = groupList.map((g2, idx) => {
935
+ const w = g2.el.offsetWidth;
936
+ if (w > 0) g2.lastWidth = w;
937
+ return {
938
+ idx,
939
+ width: g2.lastWidth,
940
+ sticky: g2.sticky,
941
+ hidden: g2.el.hidden
942
+ };
943
+ });
944
+ const folded = foldPlan(candidates, avail, moreW, gapPx);
945
+ let moved = false;
946
+ groupList.forEach((g2, idx) => {
947
+ const inPop = g2.el.parentElement === pop;
948
+ const should = folded.has(idx);
949
+ if (inPop === should) return;
950
+ moved = true;
951
+ if (should) pop.insertBefore(g2.el, anchorIn(pop, idx));
952
+ else root.insertBefore(g2.el, anchorIn(root, idx));
953
+ });
954
+ const showMore = folded.size > 0;
955
+ if (moreBtn.style.display !== "none" !== showMore)
956
+ moreBtn.style.display = showMore ? "" : "none";
957
+ if (!showMore) closePop();
958
+ if (moved) {
959
+ closePop();
960
+ wrap.querySelectorAll(".bb-split-pop").forEach((p) => p.hidden = true);
878
961
  }
879
962
  };
880
963
  let ro = null;
@@ -886,6 +969,15 @@ function mountToolbar(host, editor, options = {}) {
886
969
  layout();
887
970
  const refresh = (state) => {
888
971
  latest = state;
972
+ let visibilityChanged = false;
973
+ for (const g2 of conditionalGroups) {
974
+ const show = g2.visible(state);
975
+ if (show === g2.el.hidden) {
976
+ g2.el.hidden = !show;
977
+ visibilityChanged = true;
978
+ }
979
+ }
980
+ if (visibilityChanged) layout();
889
981
  for (const { name, el: el5 } of buttons) {
890
982
  const cmd = editor.commands.get(name);
891
983
  if (!cmd) continue;
@@ -2157,17 +2249,10 @@ for (const [name, ch] of Object.entries(MATH_AUTOCORRECT))
2157
2249
  if (!SHORTHAND.has(ch)) SHORTHAND.set(ch, `\\${name}`);
2158
2250
  var PREVIEW_PT2 = 10;
2159
2251
  var STYLE10 = `
2160
- .bb-eqp{width:352px;display:flex;flex-direction:column;background:var(--bb-ui-bg,#fff);border:0.5px solid var(--bb-ui-border,#e3e3e0);border-radius:10px;box-shadow:0 4px 16px rgba(0,0,0,.13);user-select:none;overflow:hidden}
2161
- .bb-eqp-tabs{display:flex;align-items:flex-end;gap:2px;padding:5px 5px 0;border-bottom:0.5px solid var(--bb-ui-border,#e3e3e0)}
2162
- .bb-eqp.is-collapsed .bb-eqp-tabs{border-bottom:0}
2163
- .bb-eqp-tab{padding:6px 11px;border:0;border-radius:6px 6px 0 0;background:transparent;color:inherit;font:inherit;font-size:13px;opacity:.65;cursor:pointer}
2164
- .bb-eqp-tab:hover{background:var(--bb-ui-hover,#f1efe8)}
2165
- .bb-eqp-tab[aria-selected="true"]{opacity:1;background:var(--bb-ui-sel,#e6f1fb);color:var(--bb-ui-sel-fg,#0c447c)}
2166
- .bb-eqp-fold{margin-left:auto;margin-bottom:5px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:6px;background:transparent;color:inherit;opacity:.5;cursor:pointer}
2167
- .bb-eqp-fold:hover{background:var(--bb-ui-hover,#f1efe8);opacity:.9}
2252
+ .bb-eqp{width:352px;display:flex;flex-direction:column;background:var(--bb-ui-menu-bg,#fff);-webkit-backdrop-filter:var(--bb-ui-pop-filter,none);backdrop-filter:var(--bb-ui-pop-filter,none);border:1px solid var(--bb-ui-pop-border,var(--bb-ui-border,#e3e3e0));border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.14);user-select:none;overflow:hidden}
2253
+ .bb-eqp-tabs{display:flex;padding:8px 8px 0}
2168
2254
  .bb-eqp-body{padding:8px}
2169
- .bb-eqp.is-collapsed .bb-eqp-body{display:none}
2170
- .bb-eqp-set{width:100%;height:30px;margin-bottom:7px;font:inherit;font-size:13px}
2255
+ .bb-eqp-set{width:100%;height:30px;margin-bottom:7px;border:0.5px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;background:var(--bb-ui-control-bg,#fff);color:inherit;font:inherit;font-size:13px;padding:0 8px}
2171
2256
  .bb-eqp-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:1px;max-height:190px;overflow-y:auto}
2172
2257
  .bb-eqp-sym{padding:5px 0;border:0;border-radius:5px;background:transparent;color:inherit;font-family:"Cambria Math","Times New Roman",Tinos,serif;font-size:16px;line-height:1.2;cursor:pointer}
2173
2258
  .bb-eqp-sym:hover{background:var(--bb-ui-hover,#f1efe8)}
@@ -2182,32 +2267,32 @@ var STYLE10 = `
2182
2267
  .bb-eqp-st-name{font-size:10px;opacity:.6;text-align:center;line-height:1.25}
2183
2268
  .bb-eqp-st svg{display:block}
2184
2269
  `;
2185
- var CHEVRON_UP = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 15l6-6 6 6"/></svg>';
2186
- var CHEVRON_DOWN = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 9l6 6 6-6"/></svg>';
2187
2270
  function equationPanel(options) {
2271
+ injectStyle("bb-ui-tabs", TABS_CSS);
2188
2272
  injectStyle("bb-ui-eqp-styles", STYLE10);
2189
2273
  const root = document.createElement("div");
2190
2274
  root.className = "bb-eqp";
2191
2275
  root.setAttribute("role", "group");
2192
2276
  root.setAttribute("aria-label", "Equation palette");
2193
2277
  root.addEventListener("mousedown", (e) => e.preventDefault());
2278
+ const strip = document.createElement("div");
2279
+ strip.className = "bb-eqp-tabs";
2194
2280
  const tabs = document.createElement("div");
2195
- tabs.className = "bb-eqp-tabs";
2281
+ tabs.className = "bb-tabs";
2196
2282
  tabs.setAttribute("role", "tablist");
2283
+ strip.append(tabs);
2197
2284
  const body = document.createElement("div");
2198
2285
  body.className = "bb-eqp-body";
2199
- let collapsed = false;
2200
2286
  let current3 = "symbols";
2201
2287
  const tabEls = {};
2202
2288
  const mkTab = (id, label) => {
2203
2289
  const b = document.createElement("button");
2204
2290
  b.type = "button";
2205
- b.className = "bb-eqp-tab";
2291
+ b.className = "bb-tab";
2206
2292
  b.textContent = label;
2207
2293
  b.setAttribute("role", "tab");
2208
2294
  b.addEventListener("click", () => {
2209
2295
  current3 = id;
2210
- if (collapsed) setCollapsed(false);
2211
2296
  render();
2212
2297
  });
2213
2298
  tabEls[id] = b;
@@ -2215,22 +2300,7 @@ function equationPanel(options) {
2215
2300
  };
2216
2301
  mkTab("symbols", "Symbols");
2217
2302
  mkTab("structures", "Structures");
2218
- const fold = document.createElement("button");
2219
- fold.type = "button";
2220
- fold.className = "bb-eqp-fold";
2221
- fold.addEventListener("click", () => setCollapsed(!collapsed));
2222
- tabs.append(fold);
2223
- root.append(tabs, body);
2224
- function setCollapsed(next) {
2225
- collapsed = next;
2226
- root.classList.toggle("is-collapsed", collapsed);
2227
- fold.innerHTML = collapsed ? CHEVRON_DOWN : CHEVRON_UP;
2228
- fold.setAttribute(
2229
- "aria-label",
2230
- collapsed ? "Show palette" : "Hide palette"
2231
- );
2232
- fold.setAttribute("aria-expanded", String(!collapsed));
2233
- }
2303
+ root.append(strip, body);
2234
2304
  function symbolsBody() {
2235
2305
  const set = document.createElement("select");
2236
2306
  set.className = "bb-eqp-set";
@@ -2311,14 +2381,9 @@ function equationPanel(options) {
2311
2381
  if (current3 === "symbols") symbolsBody();
2312
2382
  else structuresBody();
2313
2383
  }
2314
- setCollapsed(false);
2315
2384
  render();
2316
2385
  return {
2317
2386
  el: root,
2318
- setCollapsed,
2319
- get collapsed() {
2320
- return collapsed;
2321
- },
2322
2387
  destroy() {
2323
2388
  root.remove();
2324
2389
  }
@@ -2370,6 +2435,178 @@ function tableGridPicker(options) {
2370
2435
  return root;
2371
2436
  }
2372
2437
 
2438
+ // packages/ui/src/lib/table-style-panel.ts
2439
+ import {
2440
+ cellStyleLayer
2441
+ } from "@shadow-garden/bapbong-contracts";
2442
+ var GATES = [
2443
+ { key: "firstRow", label: "Header row" },
2444
+ { key: "lastRow", label: "Total row" },
2445
+ { key: "hBand", label: "Banded rows" },
2446
+ { key: "firstCol", label: "First column" },
2447
+ { key: "lastCol", label: "Last column" },
2448
+ { key: "vBand", label: "Banded columns" }
2449
+ ];
2450
+ var THUMB_ROWS = 4;
2451
+ var THUMB_COLS = 5;
2452
+ var STYLE12 = `
2453
+ .bb-tsp{display:flex;gap:16px;width:432px;max-width:100%;color:var(--bb-ui-fg,#2c2c2a)}
2454
+ .bb-tsp *{box-sizing:border-box}
2455
+ .bb-tsp-opts{flex:0 0 128px;display:flex;flex-direction:column;gap:2px}
2456
+ .bb-tsp-lbl{font-size:12px;opacity:.7;margin-bottom:4px}
2457
+ .bb-tsp-chk{display:flex;align-items:center;gap:7px;font-size:13px;padding:3px 0;cursor:pointer}
2458
+ .bb-tsp-chk input{margin:0}
2459
+ .bb-tsp-chk.is-disabled{opacity:.4;cursor:default}
2460
+ .bb-tsp-sep{height:1px;margin:6px 0;background:var(--bb-ui-border,#e3e3e0)}
2461
+ .bb-tsp-main{flex:1;display:flex;flex-direction:column;gap:8px;min-width:0}
2462
+ .bb-tsp-gallery{display:flex;flex-wrap:wrap;gap:6px}
2463
+ .bb-tsp-tile{padding:3px;border:1px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;background:var(--bb-ui-control-bg,var(--bb-ui-bg,#fff));cursor:pointer;line-height:0}
2464
+ .bb-tsp-tile:hover{border-color:var(--bb-ui-fg,#2c2c2a)}
2465
+ .bb-tsp-tile.is-selected{padding:2px;border:2px solid var(--bb-ui-active-fg,#0c447c)}
2466
+ .bb-tsp-thumb{display:grid;grid-template-columns:repeat(${THUMB_COLS},12px);grid-auto-rows:8px;gap:0}
2467
+ .bb-tsp-none{display:flex;align-items:center;justify-content:center;width:60px;height:32px;font-size:11px;opacity:.7;line-height:1.1}
2468
+ .bb-tsp-empty{font-size:13px;opacity:.65;padding:8px 0}
2469
+ `;
2470
+ function edgeCss(side) {
2471
+ if (!side) return "none";
2472
+ return `1px ${side.style === "double" ? "double" : "solid"} ${side.color}`;
2473
+ }
2474
+ function thumbnail(style, look) {
2475
+ const grid = document.createElement("div");
2476
+ grid.className = "bb-tsp-thumb";
2477
+ const t = style.table.borders ?? {};
2478
+ for (let r = 0; r < THUMB_ROWS; r++) {
2479
+ for (let c2 = 0; c2 < THUMB_COLS; c2++) {
2480
+ const layer = cellStyleLayer(style, look, {
2481
+ row: r,
2482
+ rowCount: THUMB_ROWS,
2483
+ col: c2,
2484
+ colspan: 1,
2485
+ colCount: THUMB_COLS,
2486
+ header: false
2487
+ });
2488
+ const cell = document.createElement("div");
2489
+ const b = layer.borders ?? {};
2490
+ cell.style.borderTop = edgeCss(b.top ?? (r === 0 ? t.top : t.insideH));
2491
+ cell.style.borderBottom = edgeCss(
2492
+ b.bottom ?? (r === THUMB_ROWS - 1 ? t.bottom : void 0)
2493
+ );
2494
+ cell.style.borderLeft = edgeCss(b.left ?? (c2 === 0 ? t.left : t.insideV));
2495
+ cell.style.borderRight = edgeCss(
2496
+ b.right ?? (c2 === THUMB_COLS - 1 ? t.right : void 0)
2497
+ );
2498
+ if (layer.background) cell.style.background = layer.background;
2499
+ grid.appendChild(cell);
2500
+ }
2501
+ }
2502
+ return grid;
2503
+ }
2504
+ function createTableStylePanel(options) {
2505
+ injectStyle("bb-table-style-panel", STYLE12);
2506
+ const root = document.createElement("div");
2507
+ root.className = "bb-tsp";
2508
+ const opts = document.createElement("div");
2509
+ opts.className = "bb-tsp-opts";
2510
+ const optsLbl = document.createElement("div");
2511
+ optsLbl.className = "bb-tsp-lbl";
2512
+ optsLbl.textContent = "Style options";
2513
+ opts.appendChild(optsLbl);
2514
+ const checks = /* @__PURE__ */ new Map();
2515
+ GATES.forEach((g2, i) => {
2516
+ if (i === 3) {
2517
+ const sep = document.createElement("div");
2518
+ sep.className = "bb-tsp-sep";
2519
+ opts.appendChild(sep);
2520
+ }
2521
+ const label = document.createElement("label");
2522
+ label.className = "bb-tsp-chk";
2523
+ const input = document.createElement("input");
2524
+ input.type = "checkbox";
2525
+ input.addEventListener(
2526
+ "change",
2527
+ () => options.onLook({ [g2.key]: input.checked })
2528
+ );
2529
+ label.append(input, document.createTextNode(g2.label));
2530
+ opts.appendChild(label);
2531
+ checks.set(g2.key, input);
2532
+ });
2533
+ const main = document.createElement("div");
2534
+ main.className = "bb-tsp-main";
2535
+ const mainLbl = document.createElement("div");
2536
+ mainLbl.className = "bb-tsp-lbl";
2537
+ mainLbl.textContent = "Table styles";
2538
+ const gallery = document.createElement("div");
2539
+ gallery.className = "bb-tsp-gallery";
2540
+ main.append(mainLbl, gallery);
2541
+ root.append(opts, main);
2542
+ const dialog = new Dialog({
2543
+ title: "Table style",
2544
+ modal: false,
2545
+ anchor: options.anchor
2546
+ });
2547
+ dialog.setContent(root);
2548
+ let drawnKey = "";
2549
+ const draw = () => {
2550
+ const current3 = options.current();
2551
+ const items = options.styles();
2552
+ const key = JSON.stringify([current3, items.map((i) => i.id)]);
2553
+ if (key === drawnKey) return;
2554
+ drawnKey = key;
2555
+ const look = current3?.look ?? null;
2556
+ for (const [gate, input] of checks) {
2557
+ input.checked = look?.[gate] ?? false;
2558
+ input.disabled = !current3;
2559
+ input.closest("label")?.classList.toggle("is-disabled", !current3);
2560
+ }
2561
+ gallery.replaceChildren();
2562
+ if (!current3) {
2563
+ const empty = document.createElement("div");
2564
+ empty.className = "bb-tsp-empty";
2565
+ empty.textContent = "Click inside a table to style it.";
2566
+ gallery.appendChild(empty);
2567
+ return;
2568
+ }
2569
+ const noneTile = document.createElement("button");
2570
+ noneTile.type = "button";
2571
+ noneTile.className = "bb-tsp-tile" + (current3.styleId === null ? " is-selected" : "");
2572
+ noneTile.title = "None";
2573
+ const noneInner = document.createElement("span");
2574
+ noneInner.className = "bb-tsp-none";
2575
+ noneInner.textContent = "None";
2576
+ noneTile.appendChild(noneInner);
2577
+ noneTile.addEventListener("click", () => options.onPick(null));
2578
+ gallery.appendChild(noneTile);
2579
+ for (const item of items) {
2580
+ const tile = document.createElement("button");
2581
+ tile.type = "button";
2582
+ tile.className = "bb-tsp-tile" + (current3.styleId === item.id ? " is-selected" : "");
2583
+ tile.title = item.name;
2584
+ tile.appendChild(thumbnail(item.style, current3.look));
2585
+ tile.addEventListener("click", () => options.onPick(item));
2586
+ gallery.appendChild(tile);
2587
+ }
2588
+ };
2589
+ return {
2590
+ open() {
2591
+ drawnKey = "";
2592
+ draw();
2593
+ dialog.open();
2594
+ },
2595
+ close() {
2596
+ dialog.close();
2597
+ },
2598
+ refresh() {
2599
+ if (dialog.isOpen) draw();
2600
+ },
2601
+ destroy() {
2602
+ dialog.destroy();
2603
+ },
2604
+ get isOpen() {
2605
+ return dialog.isOpen;
2606
+ }
2607
+ };
2608
+ }
2609
+
2373
2610
  // packages/ui/src/lib/page-setup.ts
2374
2611
  var PX_PER_CM = 96 / 2.54;
2375
2612
  var pxToCm = (px) => px / PX_PER_CM;
@@ -2377,7 +2614,7 @@ var cmToPx = (cm) => Math.round(cm * PX_PER_CM);
2377
2614
  function fmtCm(cm) {
2378
2615
  return `${Number(cm.toFixed(3))} cm`;
2379
2616
  }
2380
- var STYLE12 = `
2617
+ var STYLE13 = `
2381
2618
  .bb-ps{display:flex;flex-direction:column;min-width:250px;max-height:min(70vh,460px);overflow-y:auto}
2382
2619
  .bb-ps,.bb-ps *{box-sizing:border-box}
2383
2620
  .bb-ps-row{display:flex;align-items:center;gap:11px;width:100%;padding:7px 10px;border:0;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}
@@ -2503,7 +2740,7 @@ function customRow(icon, title, description, onPick) {
2503
2740
  return presetRow(icon, title, captionLine(description), false, onPick);
2504
2741
  }
2505
2742
  function pageSizePicker(options) {
2506
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2743
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2507
2744
  const root = document.createElement("div");
2508
2745
  root.className = "bb-ps";
2509
2746
  root.setAttribute("role", "menu");
@@ -2532,7 +2769,7 @@ function pageSizePicker(options) {
2532
2769
  return root;
2533
2770
  }
2534
2771
  function orientationPicker(options) {
2535
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2772
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2536
2773
  const root = document.createElement("div");
2537
2774
  root.className = "bb-ps";
2538
2775
  root.setAttribute("role", "menu");
@@ -2555,7 +2792,7 @@ function orientationPicker(options) {
2555
2792
  return root;
2556
2793
  }
2557
2794
  function marginPresetPicker(options) {
2558
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2795
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2559
2796
  const root = document.createElement("div");
2560
2797
  root.className = "bb-ps";
2561
2798
  root.setAttribute("role", "menu");
@@ -2630,7 +2867,7 @@ function readPx(input, fallbackPx) {
2630
2867
  return Number.isFinite(n) && n > 0 ? cmToPx(n) : fallbackPx;
2631
2868
  }
2632
2869
  function openPageSizeDialog(options) {
2633
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2870
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2634
2871
  const dialog = new Dialog({ title: "Paper size", modal: true });
2635
2872
  const form = document.createElement("form");
2636
2873
  form.className = "bb-pd";
@@ -2657,7 +2894,7 @@ function openPageSizeDialog(options) {
2657
2894
  width.input.select();
2658
2895
  }
2659
2896
  function openMarginsDialog(options) {
2660
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2897
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2661
2898
  const dialog = new Dialog({ title: "Margins", modal: true });
2662
2899
  const form = document.createElement("form");
2663
2900
  form.className = "bb-pd";
@@ -2714,7 +2951,7 @@ var PGNUM_FORMATS = [
2714
2951
  ["upperLetter", "A, B, C, D\u2026", "A"]
2715
2952
  ];
2716
2953
  function pageNumberPicker(options) {
2717
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
2954
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2718
2955
  const root = document.createElement("div");
2719
2956
  root.className = "bb-ps";
2720
2957
  root.setAttribute("role", "menu");
@@ -2815,7 +3052,7 @@ function pageNumberPicker(options) {
2815
3052
  return root;
2816
3053
  }
2817
3054
  function sectionPaperPanel(options) {
2818
- injectStyle("bb-ui-pagesetup-styles", STYLE12);
3055
+ injectStyle("bb-ui-pagesetup-styles", STYLE13);
2819
3056
  const root = document.createElement("div");
2820
3057
  root.className = "bb-ps";
2821
3058
  root.setAttribute("role", "menu");
@@ -2884,7 +3121,7 @@ function sectionPaperPanel(options) {
2884
3121
  }
2885
3122
 
2886
3123
  // packages/ui/src/lib/section-chip.ts
2887
- var STYLE13 = `
3124
+ var STYLE14 = `
2888
3125
  .bb-secchip{position:absolute;z-index:8;display:inline-flex;align-items:center;transform:translate(-50%,-50%);white-space:nowrap;background:var(--bb-ui-menu-bg,#fff);-webkit-backdrop-filter:var(--bb-ui-pop-filter,none);backdrop-filter:var(--bb-ui-pop-filter,none);border:1px solid var(--bb-ui-pop-border,var(--bb-ui-border,#e3e3e0));border-radius:10px;padding:1px 2px;box-shadow:0 2px 10px rgba(0,0,0,.12);font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);font-size:11px;color:var(--bb-ui-fg,#2c2c2a)}
2889
3126
  .bb-secchip *{box-sizing:border-box}
2890
3127
  .bb-secchip-title{padding:0 7px;font-size:11px;font-weight:600;opacity:.8}
@@ -2897,7 +3134,7 @@ var STYLE13 = `
2897
3134
  .bb-secchip-x:hover{background:var(--bb-ui-hover,#f1efe8);opacity:1}
2898
3135
  `;
2899
3136
  function createSectionChip(options) {
2900
- injectStyle("bb-ui-section-chip-styles", STYLE13);
3137
+ injectStyle("bb-ui-section-chip-styles", STYLE14);
2901
3138
  const el5 = document.createElement("div");
2902
3139
  el5.className = "bb-secchip";
2903
3140
  const title = document.createElement("span");
@@ -2954,17 +3191,13 @@ var halfToPt = (hp) => hp / 2;
2954
3191
  var ptToHalf = (pt) => Math.round(pt * 2);
2955
3192
  var SCALE_PRESETS = [200, 150, 100, 90, 80, 66, 50, 33];
2956
3193
  var SUPERSUB_SCALE = 0.66;
2957
- var STYLE14 = `
3194
+ var STYLE15 = `
2958
3195
  .bb-fd{display:flex;flex-direction:column;gap:15px;min-width:396px;max-width:430px;color:var(--bb-ui-fg,#2c2c2a)}
2959
3196
  .bb-fd *{box-sizing:border-box}
2960
3197
  /* A segmented control, not a "tab joined to its pane": that pattern needs the
2961
3198
  active tab's background to equal the pane's, and this dialog floats on
2962
3199
  frosted glass whose colour the widget cannot know. Same shape cell-properties
2963
3200
  already uses, so the two dialogs read as one product. */
2964
- .bb-fd-tabs{display:inline-flex;border:0.5px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;overflow:hidden;align-self:flex-start}
2965
- .bb-fd-tab{height:30px;padding:0 18px;border:0;border-right:0.5px solid var(--bb-ui-border,#e3e3e0);background:transparent;color:inherit;opacity:.65;font:inherit;font-size:13px;cursor:pointer}
2966
- .bb-fd-tab:last-child{border-right:0}
2967
- .bb-fd-tab[aria-selected="true"]{background:var(--bb-ui-active-bg,#e6f1fb);color:var(--bb-ui-active-fg,#0c447c);opacity:1}
2968
3201
  .bb-fd-pane{display:flex;flex-direction:column;gap:13px}
2969
3202
  /* A class-level display beats the UA's [hidden]{display:none}; without this
2970
3203
  both tabs render at once. */
@@ -3036,13 +3269,14 @@ function openFontDialog({
3036
3269
  sizes,
3037
3270
  onApply
3038
3271
  }) {
3039
- injectStyle("bb-font-dialog", STYLE14);
3272
+ injectStyle("bb-ui-tabs", TABS_CSS);
3273
+ injectStyle("bb-font-dialog", STYLE15);
3040
3274
  const dialog = new Dialog({ title: "Font", modal: true });
3041
3275
  const root = el("div", "bb-fd");
3042
- const tabs = el("div", "bb-fd-tabs");
3276
+ const tabs = el("div", "bb-tabs");
3043
3277
  tabs.setAttribute("role", "tablist");
3044
- const fontTab = el("button", "bb-fd-tab", "Font");
3045
- const advTab = el("button", "bb-fd-tab", "Advanced");
3278
+ const fontTab = el("button", "bb-tab", "Font");
3279
+ const advTab = el("button", "bb-tab", "Advanced");
3046
3280
  for (const t of [fontTab, advTab]) {
3047
3281
  t.type = "button";
3048
3282
  t.setAttribute("role", "tab");
@@ -3678,7 +3912,7 @@ function searchSymbols(query) {
3678
3912
  }
3679
3913
 
3680
3914
  // packages/ui/src/lib/symbol-dialog.ts
3681
- var STYLE15 = `
3915
+ var STYLE16 = `
3682
3916
  .bb-sd{display:flex;flex-direction:column;gap:12px;width:412px;max-width:100%;color:var(--bb-ui-fg,#2c2c2a)}
3683
3917
  .bb-sd *{box-sizing:border-box}
3684
3918
  .bb-sd-tabs{display:inline-flex;border:0.5px solid var(--bb-ui-control-border,var(--bb-ui-border,#d8d6cf));border-radius:6px;overflow:hidden;align-self:flex-start}
@@ -3739,7 +3973,7 @@ function glyphFor(char) {
3739
3973
  return char;
3740
3974
  }
3741
3975
  function createSymbolDialog(options) {
3742
- injectStyle("bb-symbol-dialog", STYLE15);
3976
+ injectStyle("bb-symbol-dialog", STYLE16);
3743
3977
  let recent = [...options.recent ?? []].slice(0, RECENT_MAX);
3744
3978
  let selected = null;
3745
3979
  const root = el2("div", "bb-sd");
@@ -4017,7 +4251,7 @@ function createSymbolDialog(options) {
4017
4251
  }
4018
4252
 
4019
4253
  // packages/ui/src/lib/symbol-popover.ts
4020
- var STYLE16 = `
4254
+ var STYLE17 = `
4021
4255
  .bb-spk{position:fixed;margin:0;max-width:none;max-height:none;z-index:1300;width:276px;padding:10px;background:var(--bb-ui-menu-bg,#fff);-webkit-backdrop-filter:var(--bb-ui-pop-filter,none);backdrop-filter:var(--bb-ui-pop-filter,none);color:var(--bb-ui-fg,#2c2c2a);border:1px solid var(--bb-ui-pop-border,var(--bb-ui-border,#e3e3e0));border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.16);font-family:var(--bb-ui-font,system-ui,-apple-system,sans-serif);font-size:12px;box-sizing:border-box;display:flex;flex-direction:column;gap:8px}
4022
4256
  .bb-spk *{box-sizing:border-box}
4023
4257
  .bb-spk::backdrop{background:transparent}
@@ -4050,7 +4284,7 @@ function el3(tag, cls, text) {
4050
4284
  return n;
4051
4285
  }
4052
4286
  function openSymbolPopover(options) {
4053
- injectStyle("bb-ui-symbol-popover", STYLE16);
4287
+ injectStyle("bb-ui-symbol-popover", STYLE17);
4054
4288
  const { anchor } = options;
4055
4289
  let recent = [...options.recent ?? []].slice(0, RECENT_MAX);
4056
4290
  let groupId = SYMBOL_GROUPS[0].id;
@@ -4216,7 +4450,7 @@ import {
4216
4450
  formatKey,
4217
4451
  keybindingRows
4218
4452
  } from "@shadow-garden/bapbong-contracts";
4219
- var STYLE17 = `
4453
+ var STYLE18 = `
4220
4454
  .bb-ks{display:flex;flex-direction:column;gap:10px;width:600px;max-width:100%;color:var(--bb-ui-fg,#2c2c2a);font-size:12px}
4221
4455
  .bb-ks *{box-sizing:border-box}
4222
4456
  .bb-ks-top{display:flex;gap:8px;align-items:center}
@@ -4274,7 +4508,7 @@ function highlight(text, q) {
4274
4508
  return out;
4275
4509
  }
4276
4510
  function openKeyboardShortcutsDialog(options) {
4277
- injectStyle("bb-ui-shortcuts-dialog", STYLE17);
4511
+ injectStyle("bb-ui-shortcuts-dialog", STYLE18);
4278
4512
  const dialog = new Dialog({
4279
4513
  title: options.title ?? "Keyboard shortcuts",
4280
4514
  modal: true,
@@ -4400,7 +4634,7 @@ function openKeyboardShortcutsDialog(options) {
4400
4634
  }
4401
4635
 
4402
4636
  // packages/ui/src/lib/scrollbars.ts
4403
- var STYLE18 = `
4637
+ var STYLE19 = `
4404
4638
  @property --bb-scroll-thumb-now {
4405
4639
  syntax: '<color>';
4406
4640
  /* MUST inherit: the thumb pseudo-element never matches .bb-scrolling
@@ -4432,7 +4666,7 @@ var STYLE18 = `
4432
4666
  var installed = null;
4433
4667
  function installScrollbars(root = document) {
4434
4668
  if (installed) return installed;
4435
- injectStyle("bb-ui-scrollbars", STYLE18);
4669
+ injectStyle("bb-ui-scrollbars", STYLE19);
4436
4670
  const quiet = /* @__PURE__ */ new WeakMap();
4437
4671
  const onScroll = (ev) => {
4438
4672
  const el5 = ev.target instanceof HTMLElement ? ev.target : root.documentElement;
@@ -4464,11 +4698,13 @@ export {
4464
4698
  createFindDialog,
4465
4699
  createSectionChip,
4466
4700
  createSymbolDialog,
4701
+ createTableStylePanel,
4467
4702
  defaultMenus,
4468
4703
  defaultToolbarGroups,
4469
4704
  equationGallery,
4470
4705
  equationPanel,
4471
4706
  equationPreviewSvg,
4707
+ foldPlan,
4472
4708
  installScrollbars,
4473
4709
  marginPresetPicker,
4474
4710
  mountMenubar,