@apliteni/apliteni-ui 0.57.0 → 0.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -189,8 +189,110 @@ function Callout({ variant, icon: icon6 = calloutIcons[variant ?? "neutral"], ch
189
189
  }
190
190
 
191
191
  // src/primitives/StatBand.tsx
192
- import { useId } from "react";
193
- import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
192
+ import { useId as useId2 } from "react";
193
+
194
+ // src/Tooltip.tsx
195
+ import { useEffect, useId, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "react";
196
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
197
+ function Tooltip({ text: text2, children }) {
198
+ const id = useId();
199
+ const host = useRef2(null);
200
+ const trigger = useRef2(null);
201
+ const tip = useRef2(null);
202
+ const ignoreMouseUntil = useRef2(0);
203
+ const touchMoved = useRef2(false);
204
+ const [open, setOpen] = useState(false);
205
+ function place() {
206
+ const h = host.current;
207
+ const t = tip.current;
208
+ const mark = trigger.current.getBoundingClientRect();
209
+ const rect = h.getBoundingClientRect();
210
+ const view = h.ownerDocument.documentElement;
211
+ const clip = { top: 0, left: 0, right: view.clientWidth, bottom: view.clientHeight };
212
+ for (let el = h; el && el !== h.ownerDocument.body; el = el.parentElement) {
213
+ const style = getComputedStyle(el);
214
+ if (![style.overflow, style.overflowX, style.overflowY].some((v) => v && v !== "visible")) continue;
215
+ const bounds = el.getBoundingClientRect();
216
+ clip.top = Math.max(clip.top, bounds.top);
217
+ clip.left = Math.max(clip.left, bounds.left);
218
+ clip.right = Math.min(clip.right, bounds.right);
219
+ clip.bottom = Math.min(clip.bottom, bounds.bottom);
220
+ }
221
+ const gap = parseFloat(getComputedStyle(t).getPropertyValue("--ui-tip-gap")) || 8;
222
+ const above = mark.top - clip.top;
223
+ const below = clip.bottom - mark.bottom;
224
+ const isBelow = above < t.offsetHeight + gap && below > above;
225
+ t.classList.toggle("is-below", isBelow);
226
+ const centre = mark.left + mark.width / 2;
227
+ const ideal = centre - t.offsetWidth / 2;
228
+ const left = Math.max(clip.left, Math.min(ideal, clip.right - t.offsetWidth));
229
+ t.style.setProperty("--ui-tip-x", `${centre - rect.left - h.clientLeft + h.scrollLeft}px`);
230
+ t.style.setProperty("--ui-tip-y", `${(isBelow ? mark.bottom : mark.top) - rect.top - h.clientTop + h.scrollTop}px`);
231
+ t.style.setProperty("--ui-tip-shift", `${left - ideal}px`);
232
+ }
233
+ useLayoutEffect2(() => {
234
+ if (open) place();
235
+ }, [open, text2]);
236
+ useEffect(() => {
237
+ if (!open) return;
238
+ const doc = host.current.ownerDocument;
239
+ const view = doc.defaultView;
240
+ const escape = (event) => {
241
+ if (event.key === "Escape") setOpen(false);
242
+ };
243
+ doc.addEventListener("keydown", escape);
244
+ view.addEventListener("scroll", place, true);
245
+ view.addEventListener("resize", place);
246
+ return () => {
247
+ doc.removeEventListener("keydown", escape);
248
+ view.removeEventListener("scroll", place, true);
249
+ view.removeEventListener("resize", place);
250
+ };
251
+ }, [open]);
252
+ return /* @__PURE__ */ jsxs4("span", { ref: host, className: "ui-tip-host", style: { display: "inline-block" }, children: [
253
+ /* @__PURE__ */ jsx6(
254
+ "span",
255
+ {
256
+ ref: trigger,
257
+ className: "ui-focusable",
258
+ tabIndex: 0,
259
+ "aria-describedby": id,
260
+ onMouseEnter: () => {
261
+ if (Date.now() > ignoreMouseUntil.current) setOpen(true);
262
+ },
263
+ onMouseLeave: () => {
264
+ if (Date.now() > ignoreMouseUntil.current) setOpen(false);
265
+ },
266
+ onFocus: () => {
267
+ if (Date.now() > ignoreMouseUntil.current) setOpen(true);
268
+ },
269
+ onBlur: () => setOpen(false),
270
+ onKeyDown: (event) => {
271
+ if (event.key === "Escape") setOpen(false);
272
+ },
273
+ onTouchStart: () => {
274
+ ignoreMouseUntil.current = Date.now() + 800;
275
+ touchMoved.current = false;
276
+ },
277
+ onTouchMove: () => {
278
+ touchMoved.current = true;
279
+ },
280
+ onTouchCancel: () => {
281
+ touchMoved.current = true;
282
+ },
283
+ onTouchEnd: () => {
284
+ ignoreMouseUntil.current = Date.now() + 800;
285
+ if (!touchMoved.current) setOpen((value) => !value);
286
+ },
287
+ children
288
+ }
289
+ ),
290
+ /* @__PURE__ */ jsx6("span", { ref: tip, id, role: "tooltip", className: `ui-tip${open ? " is-open" : ""}`, children: /* @__PURE__ */ jsx6("span", { className: "ui-tip__label", children: text2 }) })
291
+ ] });
292
+ }
293
+
294
+ // src/primitives/StatBand.tsx
295
+ import { Fragment, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
194
296
  var GLYPH = { up: "arrowUp", down: "arrowDown", flat: "minus" };
195
297
  var directionOf = (text2) => {
196
298
  const t = text2.trim();
@@ -199,53 +301,53 @@ var directionOf = (text2) => {
199
301
  var hasChange = (d) => !!d && d.value != null && d.value !== "";
200
302
  function Delta({ delta, basisId }) {
201
303
  if (!hasChange(delta)) {
202
- return /* @__PURE__ */ jsx6("dd", { className: "ui-stat__delta ui-stat__delta--none", children: delta.none || "No earlier figure" });
304
+ return /* @__PURE__ */ jsx7("dd", { className: "ui-stat__delta ui-stat__delta--none", children: delta.none || "No earlier figure" });
203
305
  }
204
306
  const dir = delta.direction && GLYPH[delta.direction] ? delta.direction : directionOf(delta.value);
205
- return /* @__PURE__ */ jsxs4("dd", { className: "ui-stat__delta", "aria-describedby": !delta.basis && basisId ? basisId : void 0, children: [
206
- /* @__PURE__ */ jsx6(Icon, { name: GLYPH[dir] }),
207
- /* @__PURE__ */ jsx6("span", { className: "ui-stat__change", children: delta.value }),
208
- delta.basis ? /* @__PURE__ */ jsxs4(Fragment, { children: [
307
+ return /* @__PURE__ */ jsxs5("dd", { className: "ui-stat__delta", "aria-describedby": !delta.basis && basisId ? basisId : void 0, children: [
308
+ /* @__PURE__ */ jsx7(Icon, { name: GLYPH[dir] }),
309
+ delta.tooltip ? /* @__PURE__ */ jsx7(Tooltip, { text: delta.tooltip, children: /* @__PURE__ */ jsx7("span", { className: "ui-stat__change", children: delta.value }) }) : /* @__PURE__ */ jsx7("span", { className: "ui-stat__change", children: delta.value }),
310
+ delta.basis ? /* @__PURE__ */ jsxs5(Fragment, { children: [
209
311
  " ",
210
- /* @__PURE__ */ jsx6("span", { className: "ui-stat__basis", children: delta.basis })
312
+ /* @__PURE__ */ jsx7("span", { className: "ui-stat__basis", children: delta.basis })
211
313
  ] }) : null
212
314
  ] });
213
315
  }
214
- function StatBand({ stats, variant = "tiles", basis, label, id }) {
215
- const auto = useId();
316
+ function StatBand({ stats, variant = "tiles", basis, basisId: sharedBasisId, label, id }) {
317
+ const auto = useId2();
216
318
  const v = ["band", "tiles", "open"].includes(variant) ? variant : "tiles";
217
- const basisId = basis ? `${id || auto}-basis` : void 0;
319
+ const basisId = basis ? `${id || auto}-basis` : sharedBasisId;
218
320
  const root = ["ui-stats", `ui-stats--${v}`, v === "band" && "ui-card"].filter(Boolean).join(" ");
219
- return /* @__PURE__ */ jsxs4("div", { className: root, role: label ? "group" : void 0, "aria-label": label || void 0, children: [
220
- basis ? /* @__PURE__ */ jsx6("p", { className: "ui-stats__basis", id: basisId, children: basis }) : null,
221
- /* @__PURE__ */ jsx6("dl", { className: "ui-stats__list", children: stats.map((s, i) => {
321
+ return /* @__PURE__ */ jsxs5("div", { className: root, role: label ? "group" : void 0, "aria-label": label || void 0, children: [
322
+ basis ? /* @__PURE__ */ jsx7("p", { className: "ui-stats__basis", id: basisId, children: basis }) : null,
323
+ /* @__PURE__ */ jsx7("dl", { className: "ui-stats__list", children: stats.map((s, i) => {
222
324
  const tone = hasChange(s.delta) && (s.delta.tone === "good" || s.delta.tone === "bad") ? s.delta.tone : "";
223
325
  const cls = ["ui-stat", tone && `ui-stat--${tone}`, v === "tiles" && "ui-card ui-card--pad-sm"].filter(Boolean).join(" ");
224
- return /* @__PURE__ */ jsxs4("div", { className: cls, children: [
225
- /* @__PURE__ */ jsx6("dt", { className: "ui-stat__label", children: s.label }),
226
- /* @__PURE__ */ jsx6("dd", { className: "ui-stat__value", children: s.value }),
227
- s.delta ? /* @__PURE__ */ jsx6(Delta, { delta: s.delta, basisId }) : null,
228
- s.trend ? /* @__PURE__ */ jsx6("dd", { className: "ui-stat__trend", children: s.trend }) : null
326
+ return /* @__PURE__ */ jsxs5("div", { className: cls, children: [
327
+ /* @__PURE__ */ jsx7("dt", { className: "ui-stat__label", children: s.label }),
328
+ /* @__PURE__ */ jsx7("dd", { className: "ui-stat__value", children: s.value }),
329
+ s.delta ? /* @__PURE__ */ jsx7(Delta, { delta: s.delta, basisId }) : null,
330
+ s.trend ? /* @__PURE__ */ jsx7("dd", { className: "ui-stat__trend", children: s.trend }) : null
229
331
  ] }, `${s.label}-${i}`);
230
332
  }) })
231
333
  ] });
232
334
  }
233
335
 
234
336
  // src/Confirm.tsx
235
- import { useRef as useRef4 } from "react";
337
+ import { useRef as useRef5 } from "react";
236
338
 
237
339
  // src/Modal.tsx
238
- import { useId as useId2, useRef as useRef3 } from "react";
340
+ import { useId as useId3, useRef as useRef4 } from "react";
239
341
  import { createPortal } from "react-dom";
240
342
 
241
343
  // src/dialog.ts
242
344
  import {
243
345
  createContext,
244
346
  useContext,
245
- useEffect,
246
- useLayoutEffect as useLayoutEffect2,
247
- useRef as useRef2,
248
- useState
347
+ useEffect as useEffect2,
348
+ useLayoutEffect as useLayoutEffect3,
349
+ useRef as useRef3,
350
+ useState as useState2
249
351
  } from "react";
250
352
  var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]), details > summary:first-of-type';
251
353
  function tabbable(el) {
@@ -266,7 +368,7 @@ var dismissOnScrim = (onClose) => (e) => {
266
368
  e.preventDefault();
267
369
  onClose();
268
370
  };
269
- var useIsoLayoutEffect = typeof document === "undefined" ? useEffect : useLayoutEffect2;
371
+ var useIsoLayoutEffect = typeof document === "undefined" ? useEffect2 : useLayoutEffect3;
270
372
  function transitionMs(el) {
271
373
  const cs = getComputedStyle(el);
272
374
  const times = (list) => list.split(",").map((t) => {
@@ -375,8 +477,8 @@ function exit(entry) {
375
477
  }
376
478
  var EXIT_SLACK_MS = 50;
377
479
  function usePresence(open, root, panel) {
378
- const [present, setPresent] = useState(open);
379
- const [entered, setEntered] = useState(false);
480
+ const [present, setPresent] = useState2(open);
481
+ const [entered, setEntered] = useState2(false);
380
482
  if (open && !present) setPresent(true);
381
483
  const shown = open && entered;
382
484
  useIsoLayoutEffect(() => {
@@ -425,12 +527,12 @@ function usePresence(open, root, panel) {
425
527
  }
426
528
  function useDialog(active, { root, panel, body, initialFocus }, onClose) {
427
529
  const parent = useContext(DialogScope);
428
- const [scope] = useState(() => ({ parent }));
429
- const close = useRef2(onClose);
530
+ const [scope] = useState2(() => ({ parent }));
531
+ const close = useRef3(onClose);
430
532
  useIsoLayoutEffect(() => {
431
533
  close.current = onClose;
432
534
  });
433
- useEffect(() => {
535
+ useEffect2(() => {
434
536
  if (!active || !root.current || !panel.current) return;
435
537
  const entry = {
436
538
  scope,
@@ -449,19 +551,19 @@ function useDialog(active, { root, panel, body, initialFocus }, onClose) {
449
551
  }
450
552
 
451
553
  // src/Modal.tsx
452
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
554
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
453
555
  function Modal({ open, title, onClose, footer, children, initialFocusRef, role = "dialog" }) {
454
- const id = useId2();
556
+ const id = useId3();
455
557
  const titleId = `${id}-title`;
456
558
  const bodyId = `${id}-body`;
457
- const root = useRef3(null);
458
- const panel = useRef3(null);
459
- const body = useRef3(null);
559
+ const root = useRef4(null);
560
+ const panel = useRef4(null);
561
+ const body = useRef4(null);
460
562
  const { mounted, shown } = usePresence(open, root, panel);
461
563
  const scope = useDialog(shown, { root, panel, body, initialFocus: initialFocusRef }, onClose);
462
564
  if (!mounted) return null;
463
565
  return createPortal(
464
- /* @__PURE__ */ jsx7(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsx7("div", { className: shown ? "rx-scrim is-open" : "rx-scrim", ref: root, onMouseDown: dismissOnScrim(onClose), children: /* @__PURE__ */ jsxs5(
566
+ /* @__PURE__ */ jsx8(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsx8("div", { className: shown ? "rx-scrim is-open" : "rx-scrim", ref: root, onMouseDown: dismissOnScrim(onClose), children: /* @__PURE__ */ jsxs6(
465
567
  "div",
466
568
  {
467
569
  className: "rx-modal",
@@ -472,12 +574,12 @@ function Modal({ open, title, onClose, footer, children, initialFocusRef, role =
472
574
  tabIndex: -1,
473
575
  ref: panel,
474
576
  children: [
475
- /* @__PURE__ */ jsxs5("div", { className: "rx-modal__head", children: [
476
- /* @__PURE__ */ jsx7("h2", { className: "rx-modal__title", id: titleId, children: title }),
477
- /* @__PURE__ */ jsx7(Button, { variant: "ghost", size: "sm", iconOnly: true, icon: "x", "aria-label": "Close", onClick: onClose })
577
+ /* @__PURE__ */ jsxs6("div", { className: "rx-modal__head", children: [
578
+ /* @__PURE__ */ jsx8("h2", { className: "rx-modal__title", id: titleId, children: title }),
579
+ /* @__PURE__ */ jsx8(Button, { variant: "ghost", size: "sm", iconOnly: true, icon: "x", "aria-label": "Close", onClick: onClose })
478
580
  ] }),
479
- /* @__PURE__ */ jsx7("div", { className: "rx-modal__body", id: bodyId, ref: body, children }),
480
- footer && /* @__PURE__ */ jsx7("div", { className: "rx-modal__foot", children: footer })
581
+ /* @__PURE__ */ jsx8("div", { className: "rx-modal__body", id: bodyId, ref: body, children }),
582
+ footer && /* @__PURE__ */ jsx8("div", { className: "rx-modal__foot", children: footer })
481
583
  ]
482
584
  }
483
585
  ) }) }),
@@ -486,7 +588,7 @@ function Modal({ open, title, onClose, footer, children, initialFocusRef, role =
486
588
  }
487
589
 
488
590
  // src/Confirm.tsx
489
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
591
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
490
592
  function Confirm({
491
593
  open,
492
594
  title,
@@ -498,8 +600,8 @@ function Confirm({
498
600
  onConfirm,
499
601
  onCancel
500
602
  }) {
501
- const safeAction = useRef4(null);
502
- return /* @__PURE__ */ jsx8(
603
+ const safeAction = useRef5(null);
604
+ return /* @__PURE__ */ jsx9(
503
605
  Modal,
504
606
  {
505
607
  open,
@@ -507,9 +609,9 @@ function Confirm({
507
609
  onClose: onCancel,
508
610
  role: "alertdialog",
509
611
  initialFocusRef: safeAction,
510
- footer: /* @__PURE__ */ jsxs6(Fragment2, { children: [
511
- /* @__PURE__ */ jsx8(Button, { ref: safeAction, variant: "ghost", onClick: onCancel, children: cancelLabel }),
512
- /* @__PURE__ */ jsx8(Button, { variant: danger ? "danger" : "primary", busy, onClick: onConfirm, children: confirmLabel })
612
+ footer: /* @__PURE__ */ jsxs7(Fragment2, { children: [
613
+ /* @__PURE__ */ jsx9(Button, { ref: safeAction, variant: "ghost", onClick: onCancel, children: cancelLabel }),
614
+ /* @__PURE__ */ jsx9(Button, { variant: danger ? "danger" : "primary", busy, onClick: onConfirm, children: confirmLabel })
513
615
  ] }),
514
616
  children: body
515
617
  }
@@ -517,9 +619,9 @@ function Confirm({
517
619
  }
518
620
 
519
621
  // src/Drawer.tsx
520
- import { useId as useId3, useRef as useRef5 } from "react";
622
+ import { useId as useId4, useRef as useRef6 } from "react";
521
623
  import { createPortal as createPortal2 } from "react-dom";
522
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
624
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
523
625
  function Drawer({
524
626
  open,
525
627
  title,
@@ -530,18 +632,18 @@ function Drawer({
530
632
  children,
531
633
  closeLabel = "Close"
532
634
  }) {
533
- const root = useRef5(null);
534
- const panel = useRef5(null);
535
- const body = useRef5(null);
536
- const titleId = useId3();
635
+ const root = useRef6(null);
636
+ const panel = useRef6(null);
637
+ const body = useRef6(null);
638
+ const titleId = useId4();
537
639
  const { mounted, shown } = usePresence(open, root, panel);
538
640
  const scope = useDialog(shown, { root, panel, body }, onClose);
539
641
  if (!mounted) return null;
540
642
  const cls = ["ui-drawer", `ui-drawer--${side}`, `ui-drawer--${size}`, shown && "is-open"].filter(Boolean).join(" ");
541
643
  return createPortal2(
542
- /* @__PURE__ */ jsx9(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs7("div", { className: cls, ref: root, children: [
543
- /* @__PURE__ */ jsx9("div", { className: "ui-drawer__scrim", onMouseDown: dismissOnScrim(onClose) }),
544
- /* @__PURE__ */ jsxs7(
644
+ /* @__PURE__ */ jsx10(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs8("div", { className: cls, ref: root, children: [
645
+ /* @__PURE__ */ jsx10("div", { className: "ui-drawer__scrim", onMouseDown: dismissOnScrim(onClose) }),
646
+ /* @__PURE__ */ jsxs8(
545
647
  "aside",
546
648
  {
547
649
  className: "ui-drawer__panel",
@@ -551,12 +653,12 @@ function Drawer({
551
653
  tabIndex: -1,
552
654
  ref: panel,
553
655
  children: [
554
- /* @__PURE__ */ jsxs7("header", { className: "ui-drawer__header", children: [
555
- /* @__PURE__ */ jsx9("h2", { className: "ui-drawer__title", id: titleId, children: title }),
556
- /* @__PURE__ */ jsx9("button", { type: "button", className: "ui-drawer__close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx9(Icon, { name: "x" }) })
656
+ /* @__PURE__ */ jsxs8("header", { className: "ui-drawer__header", children: [
657
+ /* @__PURE__ */ jsx10("h2", { className: "ui-drawer__title", id: titleId, children: title }),
658
+ /* @__PURE__ */ jsx10("button", { type: "button", className: "ui-drawer__close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx10(Icon, { name: "x" }) })
557
659
  ] }),
558
- /* @__PURE__ */ jsx9("div", { className: "ui-drawer__body", ref: body, children }),
559
- footer && /* @__PURE__ */ jsx9("footer", { className: "ui-drawer__footer", children: footer })
660
+ /* @__PURE__ */ jsx10("div", { className: "ui-drawer__body", ref: body, children }),
661
+ footer && /* @__PURE__ */ jsx10("footer", { className: "ui-drawer__footer", children: footer })
560
662
  ]
561
663
  }
562
664
  )
@@ -566,12 +668,12 @@ function Drawer({
566
668
  }
567
669
 
568
670
  // src/CommandPalette.tsx
569
- import { useCallback, useEffect as useEffect2, useId as useId4, useMemo, useRef as useRef6, useState as useState2 } from "react";
671
+ import { useCallback, useEffect as useEffect3, useId as useId5, useMemo, useRef as useRef7, useState as useState3 } from "react";
570
672
  import { createPortal as createPortal3 } from "react-dom";
571
673
  import { rankGroups, icon as icon2 } from "@apliteni/apliteni-ui";
572
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
674
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
573
675
  var cx2 = (...a) => a.filter(Boolean).join(" ");
574
- var Glyph = ({ name, className }) => /* @__PURE__ */ jsx10("span", { className, "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon2(name) } });
676
+ var Glyph = ({ name, className }) => /* @__PURE__ */ jsx11("span", { className, "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon2(name) } });
575
677
  var keysOf = (shortcut) => shortcut == null ? [] : Array.isArray(shortcut) ? shortcut : [shortcut];
576
678
  function CommandPalette({
577
679
  open,
@@ -586,13 +688,13 @@ function CommandPalette({
586
688
  rank = true,
587
689
  onQueryChange
588
690
  }) {
589
- const uid = useId4().replace(/:/g, "");
590
- const root = useRef6(null);
591
- const panel = useRef6(null);
592
- const search = useRef6(null);
593
- const [query, setQuery] = useState2("");
594
- const [at, setAt] = useState2(0);
595
- useEffect2(() => {
691
+ const uid = useId5().replace(/:/g, "");
692
+ const root = useRef7(null);
693
+ const panel = useRef7(null);
694
+ const search = useRef7(null);
695
+ const [query, setQuery] = useState3("");
696
+ const [at, setAt] = useState3(0);
697
+ useEffect3(() => {
596
698
  if (open) {
597
699
  setQuery("");
598
700
  setAt(0);
@@ -604,7 +706,7 @@ function CommandPalette({
604
706
  );
605
707
  const rows = useMemo(() => shown.flatMap((g) => g.items).filter((it) => !isDisabled(it)), [shown]);
606
708
  const active = rows[Math.min(at, rows.length - 1)];
607
- useEffect2(() => {
709
+ useEffect3(() => {
608
710
  setAt(0);
609
711
  }, [query]);
610
712
  const scope = useDialog(open, { root, panel, body: search }, onClose);
@@ -636,9 +738,9 @@ function CommandPalette({
636
738
  const listId = `${uid}-list`;
637
739
  let n = 0;
638
740
  return createPortal3(
639
- /* @__PURE__ */ jsx10(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs8("div", { className: cx2("ui-cmdk", density === "roomy" && "ui-cmdk--roomy", "is-open"), ref: root, children: [
640
- /* @__PURE__ */ jsx10("div", { className: "ui-cmdk__scrim", onMouseDown: dismissOnScrim(onClose) }),
641
- /* @__PURE__ */ jsxs8(
741
+ /* @__PURE__ */ jsx11(DialogScope.Provider, { value: scope, children: /* @__PURE__ */ jsxs9("div", { className: cx2("ui-cmdk", density === "roomy" && "ui-cmdk--roomy", "is-open"), ref: root, children: [
742
+ /* @__PURE__ */ jsx11("div", { className: "ui-cmdk__scrim", onMouseDown: dismissOnScrim(onClose) }),
743
+ /* @__PURE__ */ jsxs9(
642
744
  "div",
643
745
  {
644
746
  className: "ui-cmdk__panel",
@@ -649,9 +751,9 @@ function CommandPalette({
649
751
  ref: panel,
650
752
  onKeyDown,
651
753
  children: [
652
- /* @__PURE__ */ jsxs8("div", { className: "ui-cmdk__search", ref: search, children: [
653
- /* @__PURE__ */ jsx10(Glyph, { name: "search", className: "ui-cmdk__search-ic" }),
654
- /* @__PURE__ */ jsx10(
754
+ /* @__PURE__ */ jsxs9("div", { className: "ui-cmdk__search", ref: search, children: [
755
+ /* @__PURE__ */ jsx11(Glyph, { name: "search", className: "ui-cmdk__search-ic" }),
756
+ /* @__PURE__ */ jsx11(
655
757
  "input",
656
758
  {
657
759
  className: "ui-cmdk__input",
@@ -673,19 +775,19 @@ function CommandPalette({
673
775
  }
674
776
  )
675
777
  ] }),
676
- /* @__PURE__ */ jsx10("div", { className: "ui-cmdk__list", id: listId, role: "listbox", "aria-label": `${label} results`, children: shown.map((group, gi) => /* @__PURE__ */ jsxs8(
778
+ /* @__PURE__ */ jsx11("div", { className: "ui-cmdk__list", id: listId, role: "listbox", "aria-label": `${label} results`, children: shown.map((group, gi) => /* @__PURE__ */ jsxs9(
677
779
  "div",
678
780
  {
679
781
  className: "ui-cmdk__group",
680
782
  role: "group",
681
783
  "aria-labelledby": group.label ? `${uid}-g${gi}` : void 0,
682
784
  children: [
683
- group.label && /* @__PURE__ */ jsx10("div", { className: "ui-cmdk__group-head", id: `${uid}-g${gi}`, children: group.label }),
785
+ group.label && /* @__PURE__ */ jsx11("div", { className: "ui-cmdk__group-head", id: `${uid}-g${gi}`, children: group.label }),
684
786
  group.items.map((item) => {
685
787
  const disabled = isDisabled(item);
686
788
  const id = `${uid}-o${n++}`;
687
789
  const on = item === active;
688
- return /* @__PURE__ */ jsxs8(
790
+ return /* @__PURE__ */ jsxs9(
689
791
  "div",
690
792
  {
691
793
  id,
@@ -705,13 +807,13 @@ function CommandPalette({
705
807
  },
706
808
  onClick: (e) => run(item, e.metaKey || e.ctrlKey),
707
809
  children: [
708
- item.icon && /* @__PURE__ */ jsx10(Glyph, { name: item.icon, className: "ui-cmdk__ic" }),
709
- /* @__PURE__ */ jsxs8("span", { className: "ui-cmdk__main", children: [
710
- /* @__PURE__ */ jsx10("span", { className: "ui-cmdk__label", children: item.label }),
711
- item.description && /* @__PURE__ */ jsx10("span", { className: "ui-cmdk__desc", children: item.description })
810
+ item.icon && /* @__PURE__ */ jsx11(Glyph, { name: item.icon, className: "ui-cmdk__ic" }),
811
+ /* @__PURE__ */ jsxs9("span", { className: "ui-cmdk__main", children: [
812
+ /* @__PURE__ */ jsx11("span", { className: "ui-cmdk__label", children: item.label }),
813
+ item.description && /* @__PURE__ */ jsx11("span", { className: "ui-cmdk__desc", children: item.description })
712
814
  ] }),
713
- item.badge && /* @__PURE__ */ jsx10("span", { className: "ui-cmdk__badge", children: item.badge }),
714
- keysOf(item.shortcut).length > 0 && /* @__PURE__ */ jsx10("span", { className: "ui-cmdk__keys", "aria-hidden": "true", children: keysOf(item.shortcut).map((k) => /* @__PURE__ */ jsx10("kbd", { className: "ui-cmdk__key", children: k }, k)) })
815
+ item.badge && /* @__PURE__ */ jsx11("span", { className: "ui-cmdk__badge", children: item.badge }),
816
+ keysOf(item.shortcut).length > 0 && /* @__PURE__ */ jsx11("span", { className: "ui-cmdk__keys", "aria-hidden": "true", children: keysOf(item.shortcut).map((k) => /* @__PURE__ */ jsx11("kbd", { className: "ui-cmdk__key", children: k }, k)) })
715
817
  ]
716
818
  },
717
819
  item.id
@@ -721,20 +823,20 @@ function CommandPalette({
721
823
  },
722
824
  group.label ?? `g${gi}`
723
825
  )) }),
724
- /* @__PURE__ */ jsx10("p", { className: "ui-cmdk__empty", hidden: countOf(shown) > 0, children: empty }),
725
- /* @__PURE__ */ jsx10("p", { className: "ui-sr", role: "status", "aria-live": "polite", children: countOf(shown) === 0 ? "No results" : `${countOf(shown)} result${countOf(shown) === 1 ? "" : "s"}` }),
726
- hint && /* @__PURE__ */ jsxs8("div", { className: "ui-cmdk__foot", "aria-hidden": "true", children: [
727
- /* @__PURE__ */ jsxs8("span", { children: [
728
- /* @__PURE__ */ jsx10("kbd", { className: "ui-cmdk__key", children: "\u2191" }),
729
- /* @__PURE__ */ jsx10("kbd", { className: "ui-cmdk__key", children: "\u2193" }),
826
+ /* @__PURE__ */ jsx11("p", { className: "ui-cmdk__empty", hidden: countOf(shown) > 0, children: empty }),
827
+ /* @__PURE__ */ jsx11("p", { className: "ui-sr", role: "status", "aria-live": "polite", children: countOf(shown) === 0 ? "No results" : `${countOf(shown)} result${countOf(shown) === 1 ? "" : "s"}` }),
828
+ hint && /* @__PURE__ */ jsxs9("div", { className: "ui-cmdk__foot", "aria-hidden": "true", children: [
829
+ /* @__PURE__ */ jsxs9("span", { children: [
830
+ /* @__PURE__ */ jsx11("kbd", { className: "ui-cmdk__key", children: "\u2191" }),
831
+ /* @__PURE__ */ jsx11("kbd", { className: "ui-cmdk__key", children: "\u2193" }),
730
832
  " move"
731
833
  ] }),
732
- /* @__PURE__ */ jsxs8("span", { children: [
733
- /* @__PURE__ */ jsx10("kbd", { className: "ui-cmdk__key", children: "\u21B5" }),
834
+ /* @__PURE__ */ jsxs9("span", { children: [
835
+ /* @__PURE__ */ jsx11("kbd", { className: "ui-cmdk__key", children: "\u21B5" }),
734
836
  " run"
735
837
  ] }),
736
- /* @__PURE__ */ jsxs8("span", { children: [
737
- /* @__PURE__ */ jsx10("kbd", { className: "ui-cmdk__key", children: "esc" }),
838
+ /* @__PURE__ */ jsxs9("span", { children: [
839
+ /* @__PURE__ */ jsx11("kbd", { className: "ui-cmdk__key", children: "esc" }),
738
840
  " close"
739
841
  ] })
740
842
  ] })
@@ -759,13 +861,13 @@ function rowId(uid, groups, item) {
759
861
  }
760
862
 
761
863
  // src/DataTable.tsx
762
- import { useMemo as useMemo2, useState as useState4 } from "react";
864
+ import { useEffect as useEffect5, useId as useId7, useMemo as useMemo2, useRef as useRef9, useState as useState5 } from "react";
763
865
  import { DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE2 } from "@apliteni/apliteni-ui";
764
866
 
765
867
  // src/Pagination.tsx
766
- import { useEffect as useEffect3, useId as useId5, useRef as useRef7, useState as useState3 } from "react";
868
+ import { useEffect as useEffect4, useId as useId6, useRef as useRef8, useState as useState4 } from "react";
767
869
  import { DEFAULT_PAGE_SIZE } from "@apliteni/apliteni-ui";
768
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
870
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
769
871
  var GHOST_SM = "ui-btn ui-btn--ghost ui-btn--sm";
770
872
  var VARIANTS = ["steps", "numbered", "jump"];
771
873
  var cx3 = (...a) => a.filter(Boolean).join(" ");
@@ -807,11 +909,11 @@ function Pagination({
807
909
  onPageChange,
808
910
  onPageSizeChange
809
911
  }) {
810
- const auto = useId5();
811
- const [draft, setDraft] = useState3("");
812
- const [drafting, setDrafting] = useState3(false);
813
- const nav = useRef7(null);
814
- const pressed = useRef7(null);
912
+ const auto = useId6();
913
+ const [draft, setDraft] = useState4("");
914
+ const [drafting, setDrafting] = useState4(false);
915
+ const nav = useRef8(null);
916
+ const pressed = useRef8(null);
815
917
  const uid = id ?? auto;
816
918
  const kind = VARIANTS.includes(variant) ? variant : "steps";
817
919
  const size = sizeOf(pageSize, DEFAULT_PAGE_SIZE);
@@ -820,7 +922,7 @@ function Pagination({
820
922
  const rows = counted ? Math.max(0, asRows) : null;
821
923
  const last = counted ? Math.max(1, Math.ceil(rows / size)) : null;
822
924
  const at = counted ? Math.min(Math.max(1, int(page, 1)), last) : Math.min(Math.max(1, int(page, 1)), CAP - 1);
823
- const [draftFor, setDraftFor] = useState3(at);
925
+ const [draftFor, setDraftFor] = useState4(at);
824
926
  if (draftFor !== at) {
825
927
  setDraftFor(at);
826
928
  setDraft("");
@@ -828,7 +930,7 @@ function Pagination({
828
930
  }
829
931
  const offered = (Array.isArray(pageSizes) ? pageSizes : []).slice(0, 12).map((s) => int(s, 0)).filter((s) => s > 0);
830
932
  const sizes = offered.length ? [.../* @__PURE__ */ new Set([...offered, size])].sort((a, b) => a - b) : [];
831
- useEffect3(() => {
933
+ useEffect4(() => {
832
934
  const was = pressed.current;
833
935
  if (!was || loading) return;
834
936
  pressed.current = null;
@@ -857,7 +959,7 @@ function Pagination({
857
959
  const step = (label_, target, disabled) => (
858
960
  // A control at an end is disabled and stays where it is: removing it slides
859
961
  // the next control under a pointer already travelling toward it.
860
- /* @__PURE__ */ jsx11(
962
+ /* @__PURE__ */ jsx12(
861
963
  "button",
862
964
  {
863
965
  type: "button",
@@ -896,14 +998,14 @@ function Pagination({
896
998
  if (single) {
897
999
  steps = null;
898
1000
  } else if (!counted) {
899
- steps = /* @__PURE__ */ jsxs9("div", { className: "ui-pager__steps", children: [
1001
+ steps = /* @__PURE__ */ jsxs10("div", { className: "ui-pager__steps", children: [
900
1002
  step("Prev", Math.max(1, at - 1), atStart),
901
1003
  step("Next", at + 1, !hasMore)
902
1004
  ] });
903
1005
  } else {
904
1006
  let middle = null;
905
1007
  if (kind === "numbered") {
906
- middle = slotsFor(at, last).map((n, i) => n == null ? /* @__PURE__ */ jsx11("span", { className: "ui-pager__gap", "aria-hidden": "true", children: "\u2026" }, `gap${i}`) : /* @__PURE__ */ jsx11(
1008
+ middle = slotsFor(at, last).map((n, i) => n == null ? /* @__PURE__ */ jsx12("span", { className: "ui-pager__gap", "aria-hidden": "true", children: "\u2026" }, `gap${i}`) : /* @__PURE__ */ jsx12(
907
1009
  "button",
908
1010
  {
909
1011
  type: "button",
@@ -918,9 +1020,9 @@ function Pagination({
918
1020
  n
919
1021
  ));
920
1022
  } else if (kind === "jump") {
921
- middle = /* @__PURE__ */ jsxs9("span", { className: "ui-pager__jump", children: [
922
- /* @__PURE__ */ jsx11("label", { htmlFor: `${uid}-jump`, children: "Page" }),
923
- /* @__PURE__ */ jsx11(
1023
+ middle = /* @__PURE__ */ jsxs10("span", { className: "ui-pager__jump", children: [
1024
+ /* @__PURE__ */ jsx12("label", { htmlFor: `${uid}-jump`, children: "Page" }),
1025
+ /* @__PURE__ */ jsx12(
924
1026
  "input",
925
1027
  {
926
1028
  className: "ui-input ui-pager__jump-input",
@@ -943,13 +1045,13 @@ function Pagination({
943
1045
  }
944
1046
  }
945
1047
  ),
946
- /* @__PURE__ */ jsxs9("span", { className: "ui-pager__jump-of", children: [
1048
+ /* @__PURE__ */ jsxs10("span", { className: "ui-pager__jump-of", children: [
947
1049
  "of ",
948
1050
  fmt(last)
949
1051
  ] })
950
1052
  ] });
951
1053
  }
952
- steps = /* @__PURE__ */ jsxs9("div", { className: "ui-pager__steps", children: [
1054
+ steps = /* @__PURE__ */ jsxs10("div", { className: "ui-pager__steps", children: [
953
1055
  ends ? step("First", 1, atStart) : null,
954
1056
  step("Prev", Math.max(1, at - 1), atStart),
955
1057
  middle,
@@ -957,7 +1059,7 @@ function Pagination({
957
1059
  ends ? step("Last", last, atEnd) : null
958
1060
  ] });
959
1061
  }
960
- return /* @__PURE__ */ jsxs9(
1062
+ return /* @__PURE__ */ jsxs10(
961
1063
  "nav",
962
1064
  {
963
1065
  ref: nav,
@@ -965,10 +1067,10 @@ function Pagination({
965
1067
  "aria-label": label,
966
1068
  "aria-busy": loading ? true : void 0,
967
1069
  children: [
968
- /* @__PURE__ */ jsx11("p", { className: "ui-pager__status", "aria-live": "polite", "aria-atomic": "true", children: status }),
969
- sizes.length ? /* @__PURE__ */ jsxs9("div", { className: "ui-pager__size", children: [
970
- /* @__PURE__ */ jsx11("label", { className: "ui-pager__size-label", htmlFor: `${uid}-size`, children: "Rows" }),
971
- /* @__PURE__ */ jsx11(
1070
+ /* @__PURE__ */ jsx12("p", { className: "ui-pager__status", "aria-live": "polite", "aria-atomic": "true", children: status }),
1071
+ sizes.length ? /* @__PURE__ */ jsxs10("div", { className: "ui-pager__size", children: [
1072
+ /* @__PURE__ */ jsx12("label", { className: "ui-pager__size-label", htmlFor: `${uid}-size`, children: "Rows" }),
1073
+ /* @__PURE__ */ jsx12(
972
1074
  "select",
973
1075
  {
974
1076
  className: "ui-select ui-pager__size-select",
@@ -976,7 +1078,7 @@ function Pagination({
976
1078
  disabled: loading,
977
1079
  value: size,
978
1080
  onChange: (e) => onPageSizeChange?.(Number(e.target.value)),
979
- children: sizes.map((s) => /* @__PURE__ */ jsx11("option", { value: s, children: fmt(s) }, s))
1081
+ children: sizes.map((s) => /* @__PURE__ */ jsx12("option", { value: s, children: fmt(s) }, s))
980
1082
  }
981
1083
  )
982
1084
  ] }) : null,
@@ -987,7 +1089,7 @@ function Pagination({
987
1089
  }
988
1090
 
989
1091
  // src/DataTable.tsx
990
- import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1092
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
991
1093
  var NO_SORT = { key: void 0, dir: -1 };
992
1094
  function sortTableRows(rows, sort) {
993
1095
  if (sort.key === void 0) return [...rows];
@@ -1022,16 +1124,42 @@ function DataTable({
1022
1124
  total,
1023
1125
  hasMore = false
1024
1126
  }) {
1025
- const [localSort, setLocalSort] = useState4(
1127
+ const scrollable = stickyHeader || pinnedIdentity;
1128
+ const scrollId = useId7();
1129
+ const scrollRegion = useRef9(null);
1130
+ const [columnScroll, setColumnScroll] = useState5({ overflow: false, start: true, end: false });
1131
+ const measureColumns = () => {
1132
+ const region = scrollRegion.current;
1133
+ if (region) setColumnScroll({
1134
+ overflow: region.scrollWidth > region.clientWidth + 1,
1135
+ start: region.scrollLeft <= 1,
1136
+ end: region.scrollLeft + region.clientWidth >= region.scrollWidth - 1
1137
+ });
1138
+ };
1139
+ useEffect5(() => {
1140
+ if (!scrollable) return;
1141
+ const region = scrollRegion.current;
1142
+ if (!region) return;
1143
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measureColumns);
1144
+ observer?.observe(region);
1145
+ if (region.firstElementChild) observer?.observe(region.firstElementChild);
1146
+ measureColumns();
1147
+ return () => observer?.disconnect();
1148
+ }, [scrollable, columns, rows]);
1149
+ const scrollColumns = (direction) => {
1150
+ const region = scrollRegion.current;
1151
+ if (region) region.scrollBy({ left: direction * region.clientWidth / 2, behavior: "instant" });
1152
+ };
1153
+ const [localSort, setLocalSort] = useState5(
1026
1154
  { key: columns.find((c) => c.sortable)?.key, dir: -1 }
1027
1155
  );
1028
1156
  const owned = controlledPage === void 0;
1029
1157
  const sort = controlledSort ?? (owned ? localSort : NO_SORT);
1030
1158
  const sortIsKnown = owned || controlledSort !== void 0;
1031
- const [localPage, setLocalPage] = useState4(1);
1032
- const [localSize, setLocalSize] = useState4(DEFAULT_PAGE_SIZE2);
1159
+ const [localPage, setLocalPage] = useState5(1);
1160
+ const [localSize, setLocalSize] = useState5(DEFAULT_PAGE_SIZE2);
1033
1161
  const size = sizeOf(pageSize, owned ? localSize : rows.length || DEFAULT_PAGE_SIZE2);
1034
- const [pagedSort, setPagedSort] = useState4(sort);
1162
+ const [pagedSort, setPagedSort] = useState5(sort);
1035
1163
  if (pagedSort.key !== sort.key || pagedSort.dir !== sort.dir) {
1036
1164
  setPagedSort(sort);
1037
1165
  setLocalPage(1);
@@ -1054,7 +1182,7 @@ function DataTable({
1054
1182
  onSortChange?.(next);
1055
1183
  toFirstPage();
1056
1184
  };
1057
- const caret = (k) => /* @__PURE__ */ jsx12(
1185
+ const caret = (k) => /* @__PURE__ */ jsx13(
1058
1186
  "svg",
1059
1187
  {
1060
1188
  className: "rx-caret",
@@ -1066,29 +1194,36 @@ function DataTable({
1066
1194
  strokeLinejoin: "round",
1067
1195
  "aria-hidden": "true",
1068
1196
  focusable: "false",
1069
- children: sort.key === k ? /* @__PURE__ */ jsx12("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs10(Fragment3, { children: [
1070
- /* @__PURE__ */ jsx12("path", { d: "m8 9 4-4 4 4" }),
1071
- /* @__PURE__ */ jsx12("path", { d: "m8 15 4 4 4-4" })
1197
+ children: sort.key === k ? /* @__PURE__ */ jsx13("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs11(Fragment3, { children: [
1198
+ /* @__PURE__ */ jsx13("path", { d: "m8 9 4-4 4 4" }),
1199
+ /* @__PURE__ */ jsx13("path", { d: "m8 15 4 4 4-4" })
1072
1200
  ] })
1073
1201
  }
1074
1202
  );
1075
1203
  const pageAllOn = selectable && slice.length > 0 && slice.every((r) => selected.has(r.name));
1076
- return /* @__PURE__ */ jsxs10(Fragment3, { children: [
1077
- /* @__PURE__ */ jsx12(
1204
+ return /* @__PURE__ */ jsxs11(Fragment3, { children: [
1205
+ scrollable && columnScroll.overflow && /* @__PURE__ */ jsxs11("div", { className: "ui-card__row", role: "group", "aria-label": `${scrollLabel} columns`, children: [
1206
+ /* @__PURE__ */ jsx13(Button, { size: "sm", icon: "arrowLeft", "aria-controls": scrollId, disabled: columnScroll.start, onClick: () => scrollColumns(-1), children: "Previous columns" }),
1207
+ /* @__PURE__ */ jsx13(Button, { size: "sm", iconRight: "arrowRight", "aria-controls": scrollId, disabled: columnScroll.end, onClick: () => scrollColumns(1), children: "More columns" })
1208
+ ] }),
1209
+ /* @__PURE__ */ jsx13(
1078
1210
  "div",
1079
1211
  {
1212
+ id: scrollId,
1213
+ ref: scrollRegion,
1214
+ onScroll: measureColumns,
1080
1215
  className: stickyHeader || pinnedIdentity ? "ui-table-scroll" : void 0,
1081
1216
  role: stickyHeader || pinnedIdentity ? "region" : void 0,
1082
1217
  "aria-label": stickyHeader || pinnedIdentity ? scrollLabel : void 0,
1083
1218
  tabIndex: stickyHeader || pinnedIdentity ? 0 : void 0,
1084
- children: /* @__PURE__ */ jsxs10(
1219
+ children: /* @__PURE__ */ jsxs11(
1085
1220
  "table",
1086
1221
  {
1087
1222
  className: ["ui-table ui-table--hover", (density === "dense" || !density && dense) && "ui-table--dense", density === "compact" && "ui-table--compact", stickyHeader && "ui-table--sticky", pinnedIdentity && "ui-table--pinned"].filter(Boolean).join(" "),
1088
1223
  "aria-busy": loading || void 0,
1089
1224
  children: [
1090
- /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
1091
- selectable ? /* @__PURE__ */ jsx12("th", { scope: "col", className: "ui-table__selection", children: /* @__PURE__ */ jsx12(
1225
+ /* @__PURE__ */ jsx13("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
1226
+ selectable ? /* @__PURE__ */ jsx13("th", { scope: "col", className: "ui-table__selection", children: /* @__PURE__ */ jsx13(
1092
1227
  "input",
1093
1228
  {
1094
1229
  type: "checkbox",
@@ -1101,13 +1236,13 @@ function DataTable({
1101
1236
  // The sort control is a real <button> inside the header cell. It used to be
1102
1237
  // role="button" ON the <th>, which threw away the columnheader role and put
1103
1238
  // aria-sort on a role that forbids it.
1104
- /* @__PURE__ */ jsx12(
1239
+ /* @__PURE__ */ jsx13(
1105
1240
  "th",
1106
1241
  {
1107
1242
  scope: "col",
1108
1243
  className: [pinnedIdentity && columnIndex === 0 && "ui-table__identity", c.num && "ui-table__num", c.sortable && "rx-sortable"].filter(Boolean).join(" "),
1109
1244
  "aria-sort": sort.key === c.key ? sort.dir === 1 ? "ascending" : "descending" : c.sortable && sortIsKnown ? "none" : void 0,
1110
- children: c.sortable ? /* @__PURE__ */ jsxs10("button", { type: "button", className: "rx-sort", onClick: () => onSort(c.key), children: [
1245
+ children: c.sortable ? /* @__PURE__ */ jsxs11("button", { type: "button", className: "rx-sort", onClick: () => onSort(c.key), children: [
1111
1246
  c.label,
1112
1247
  caret(c.key)
1113
1248
  ] }) : c.label
@@ -1116,10 +1251,10 @@ function DataTable({
1116
1251
  )
1117
1252
  ))
1118
1253
  ] }) }),
1119
- /* @__PURE__ */ jsxs10("tbody", { children: [
1120
- !slice.length && /* @__PURE__ */ jsx12("tr", { children: /* @__PURE__ */ jsx12("td", { colSpan: columns.length + (selectable ? 1 : 0), children: loading ? "Loading rows\u2026" : empty }) }),
1121
- slice.map((r) => /* @__PURE__ */ jsxs10("tr", { children: [
1122
- selectable ? /* @__PURE__ */ jsx12("td", { className: "ui-table__selection", children: /* @__PURE__ */ jsx12(
1254
+ /* @__PURE__ */ jsxs11("tbody", { children: [
1255
+ !slice.length && /* @__PURE__ */ jsx13("tr", { children: /* @__PURE__ */ jsx13("td", { colSpan: columns.length + (selectable ? 1 : 0), children: loading ? "Loading rows\u2026" : empty }) }),
1256
+ slice.map((r) => /* @__PURE__ */ jsxs11("tr", { children: [
1257
+ selectable ? /* @__PURE__ */ jsx13("td", { className: "ui-table__selection", children: /* @__PURE__ */ jsx13(
1123
1258
  "input",
1124
1259
  {
1125
1260
  type: "checkbox",
@@ -1128,7 +1263,7 @@ function DataTable({
1128
1263
  onChange: () => onToggle(r.name)
1129
1264
  }
1130
1265
  ) }) : null,
1131
- columns.map((c, columnIndex) => /* @__PURE__ */ jsx12("td", { className: [c.num && "ui-table__num", pinnedIdentity && columnIndex === 0 && "ui-table__identity"].filter(Boolean).join(" "), children: c.render ? c.render(r) : String(r[c.key]) }, c.key))
1266
+ columns.map((c, columnIndex) => /* @__PURE__ */ jsx13("td", { className: [c.num && "ui-table__num", pinnedIdentity && columnIndex === 0 && "ui-table__identity"].filter(Boolean).join(" "), children: c.render ? c.render(r) : String(r[c.key]) }, c.key))
1132
1267
  ] }, r.name))
1133
1268
  ] })
1134
1269
  ]
@@ -1136,7 +1271,7 @@ function DataTable({
1136
1271
  )
1137
1272
  }
1138
1273
  ),
1139
- pager ? /* @__PURE__ */ jsx12(
1274
+ pager ? /* @__PURE__ */ jsx13(
1140
1275
  Pagination,
1141
1276
  {
1142
1277
  page,
@@ -1161,7 +1296,7 @@ function DataTable({
1161
1296
  import { PAGE_SIZES as KIT_PAGE_SIZES, DEFAULT_PAGE_SIZE as KIT_DEFAULT_PAGE_SIZE } from "@apliteni/apliteni-ui";
1162
1297
 
1163
1298
  // src/Loading.tsx
1164
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1299
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1165
1300
  var cx4 = (...a) => a.filter(Boolean).join(" ");
1166
1301
  function Skeleton({ lines = 3, width, height, radius, className }) {
1167
1302
  const widths = Array.isArray(lines) ? lines : null;
@@ -1171,19 +1306,19 @@ function Skeleton({ lines = 3, width, height, radius, className }) {
1171
1306
  if (!w && !height && !radius) return void 0;
1172
1307
  return { ...w && { width: w }, ...height && { height }, ...radius && { borderRadius: radius } };
1173
1308
  };
1174
- return /* @__PURE__ */ jsx13("div", { className: cx4("ui-skel", className), "aria-hidden": "true", children: Array.from({ length: n }, (_, i) => /* @__PURE__ */ jsx13("span", { className: "ui-skel__bar m-skeleton", style: styleFor(i) }, i)) });
1309
+ return /* @__PURE__ */ jsx14("div", { className: cx4("ui-skel", className), "aria-hidden": "true", children: Array.from({ length: n }, (_, i) => /* @__PURE__ */ jsx14("span", { className: "ui-skel__bar m-skeleton", style: styleFor(i) }, i)) });
1175
1310
  }
1176
1311
  function SkeletonTable({ rows = 5, cols = 4, head = true }) {
1177
- const cells = Array.from({ length: Math.max(1, cols) }, (_, i) => /* @__PURE__ */ jsx13("span", { className: "ui-skel__bar m-skeleton" }, i));
1178
- return /* @__PURE__ */ jsxs11(
1312
+ const cells = Array.from({ length: Math.max(1, cols) }, (_, i) => /* @__PURE__ */ jsx14("span", { className: "ui-skel__bar m-skeleton" }, i));
1313
+ return /* @__PURE__ */ jsxs12(
1179
1314
  "div",
1180
1315
  {
1181
1316
  className: "ui-skel ui-skel--table",
1182
1317
  style: { "--skel-cols": Math.max(1, cols) },
1183
1318
  "aria-hidden": "true",
1184
1319
  children: [
1185
- head && /* @__PURE__ */ jsx13("div", { className: "ui-skel__row ui-skel__row--head", children: cells }),
1186
- Array.from({ length: Math.max(1, rows) }, (_, i) => /* @__PURE__ */ jsx13("div", { className: "ui-skel__row", children: cells }, i))
1320
+ head && /* @__PURE__ */ jsx14("div", { className: "ui-skel__row ui-skel__row--head", children: cells }),
1321
+ Array.from({ length: Math.max(1, rows) }, (_, i) => /* @__PURE__ */ jsx14("div", { className: "ui-skel__row", children: cells }, i))
1187
1322
  ]
1188
1323
  }
1189
1324
  );
@@ -1196,7 +1331,7 @@ function BusyRegion({
1196
1331
  className,
1197
1332
  children
1198
1333
  }) {
1199
- return /* @__PURE__ */ jsxs11(
1334
+ return /* @__PURE__ */ jsxs12(
1200
1335
  "div",
1201
1336
  {
1202
1337
  className: cx4("ui-busy", className),
@@ -1204,8 +1339,8 @@ function BusyRegion({
1204
1339
  "aria-live": "polite",
1205
1340
  "aria-busy": busy,
1206
1341
  children: [
1207
- /* @__PURE__ */ jsx13("span", { className: "ui-sr", children: busy ? label : message }),
1208
- /* @__PURE__ */ jsx13("div", { className: "ui-busy__body", children: busy ? placeholder ?? /* @__PURE__ */ jsx13(Skeleton, { lines: 3 }) : children })
1342
+ /* @__PURE__ */ jsx14("span", { className: "ui-sr", children: busy ? label : message }),
1343
+ /* @__PURE__ */ jsx14("div", { className: "ui-busy__body", children: busy ? placeholder ?? /* @__PURE__ */ jsx14(Skeleton, { lines: 3 }) : children })
1209
1344
  ]
1210
1345
  }
1211
1346
  );
@@ -1218,15 +1353,15 @@ function Denied({
1218
1353
  className,
1219
1354
  children
1220
1355
  }) {
1221
- return /* @__PURE__ */ jsxs11("div", { className: cx4("ui-denied", className), children: [
1222
- /* @__PURE__ */ jsx13("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx13(Icon, { name: icon6 }) }),
1223
- /* @__PURE__ */ jsx13("div", { className: "ui-denied__title", children: title }),
1224
- sub && /* @__PURE__ */ jsx13("div", { className: "ui-denied__sub", children: sub }),
1225
- need && /* @__PURE__ */ jsxs11("div", { className: "ui-denied__need", children: [
1356
+ return /* @__PURE__ */ jsxs12("div", { className: cx4("ui-denied", className), children: [
1357
+ /* @__PURE__ */ jsx14("div", { className: "ui-denied__seal", children: /* @__PURE__ */ jsx14(Icon, { name: icon6 }) }),
1358
+ /* @__PURE__ */ jsx14("div", { className: "ui-denied__title", children: title }),
1359
+ sub && /* @__PURE__ */ jsx14("div", { className: "ui-denied__sub", children: sub }),
1360
+ need && /* @__PURE__ */ jsxs12("div", { className: "ui-denied__need", children: [
1226
1361
  "Needs ",
1227
- /* @__PURE__ */ jsx13("code", { className: "ui-code", children: need })
1362
+ /* @__PURE__ */ jsx14("code", { className: "ui-code", children: need })
1228
1363
  ] }),
1229
- children && /* @__PURE__ */ jsx13("div", { className: "ui-denied__actions", children })
1364
+ children && /* @__PURE__ */ jsx14("div", { className: "ui-denied__actions", children })
1230
1365
  ] });
1231
1366
  }
1232
1367
 
@@ -1234,16 +1369,16 @@ function Denied({
1234
1369
  import {
1235
1370
  Fragment as Fragment4,
1236
1371
  useCallback as useCallback2,
1237
- useEffect as useEffect4,
1238
- useId as useId6,
1239
- useRef as useRef8,
1240
- useState as useState5
1372
+ useEffect as useEffect6,
1373
+ useId as useId8,
1374
+ useRef as useRef10,
1375
+ useState as useState6
1241
1376
  } from "react";
1242
1377
  import { icon as icon3, dropdownMatch, dropdownFiltering } from "@apliteni/apliteni-ui";
1243
- import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1378
+ import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1244
1379
  var cx5 = (...a) => a.filter(Boolean).join(" ");
1245
1380
  var isRow = (it) => Boolean(it) && it !== "---" && !it.separator;
1246
- var Glyph2 = ({ name, className, hidden }) => /* @__PURE__ */ jsx14(
1381
+ var Glyph2 = ({ name, className, hidden }) => /* @__PURE__ */ jsx15(
1247
1382
  "span",
1248
1383
  {
1249
1384
  className,
@@ -1256,7 +1391,7 @@ function RowBadge({ badge }) {
1256
1391
  const given = typeof badge === "string" ? "" : badge.tone || "";
1257
1392
  let tone = given || (/^live$/i.test(String(text2)) ? "live" : "neutral");
1258
1393
  if (!given && tone === "neutral" && /^(?:off|unset|disabled|archive|archived)$/i.test(text2)) tone = "state";
1259
- return /* @__PURE__ */ jsx14("span", { className: `ui-dropdown__badge is-${tone}`, children: text2 });
1394
+ return /* @__PURE__ */ jsx15("span", { className: `ui-dropdown__badge is-${tone}`, children: text2 });
1260
1395
  }
1261
1396
  var keyOf = (it) => it.value != null ? `v:${it.value}` : `l:${it.label}`;
1262
1397
  var itemsIn = (panel) => Array.from(panel?.querySelectorAll("[data-dd-item]") ?? []).filter((el) => el.getAttribute("aria-disabled") !== "true" && !el.hidden);
@@ -1292,24 +1427,24 @@ function Dropdown({
1292
1427
  onSelect,
1293
1428
  row
1294
1429
  }) {
1295
- const [selfOpen, setSelfOpen] = useState5(defaultOpen);
1430
+ const [selfOpen, setSelfOpen] = useState6(defaultOpen);
1296
1431
  const open = openProp ?? selfOpen;
1297
- const [pick, setPick] = useState5(null);
1298
- const [query, setQuery] = useState5(() => search && search !== true ? search.query || "" : "");
1299
- const [activeKey, setActiveKey] = useState5(null);
1300
- const root = useRef8(null);
1301
- const panel = useRef8(null);
1302
- const trigger = useRef8(null);
1303
- const field = useRef8(null);
1304
- const landOn = useRef8(null);
1305
- const at = useRef8("");
1306
- const auto = useId6().replace(/:/g, "");
1432
+ const [pick, setPick] = useState6(null);
1433
+ const [query, setQuery] = useState6(() => search && search !== true ? search.query || "" : "");
1434
+ const [activeKey, setActiveKey] = useState6(null);
1435
+ const root = useRef10(null);
1436
+ const panel = useRef10(null);
1437
+ const trigger = useRef10(null);
1438
+ const field = useRef10(null);
1439
+ const landOn = useRef10(null);
1440
+ const at = useRef10("");
1441
+ const auto = useId8().replace(/:/g, "");
1307
1442
  const uid = id ?? auto;
1308
1443
  const setOpen = useCallback2((next) => {
1309
1444
  if (openProp === void 0) setSelfOpen(next);
1310
1445
  onOpenChange?.(next);
1311
1446
  }, [openProp, onOpenChange]);
1312
- const close = useRef8(setOpen);
1447
+ const close = useRef10(setOpen);
1313
1448
  useIsoLayoutEffect(() => {
1314
1449
  close.current = setOpen;
1315
1450
  });
@@ -1323,7 +1458,7 @@ function Dropdown({
1323
1458
  const given = rows.find((it) => it.selected);
1324
1459
  const givenKey = given ? keyOf(given) : null;
1325
1460
  const pickedKey = pick && pick.against === givenKey ? pick.key : null;
1326
- useEffect4(() => {
1461
+ useEffect6(() => {
1327
1462
  if (pick && pick.against !== givenKey) setPick(null);
1328
1463
  }, [givenKey, pick]);
1329
1464
  const picked = pickedKey != null ? rows.find((it) => keyOf(it) === pickedKey) : void 0;
@@ -1337,7 +1472,7 @@ function Dropdown({
1337
1472
  const rowIds = /* @__PURE__ */ new Map();
1338
1473
  rows.forEach((it, i) => rowIds.set(it, `${uid}-opt-${i}`));
1339
1474
  const listId = `${uid}-list`;
1340
- useEffect4(() => {
1475
+ useEffect6(() => {
1341
1476
  if (!open) return;
1342
1477
  const mine = () => close.current(false);
1343
1478
  for (const other of [...openNow]) other();
@@ -1346,7 +1481,7 @@ function Dropdown({
1346
1481
  openNow.delete(mine);
1347
1482
  };
1348
1483
  }, [open]);
1349
- useEffect4(() => {
1484
+ useEffect6(() => {
1350
1485
  if (!open) return;
1351
1486
  const doc = root.current?.ownerDocument ?? document;
1352
1487
  const onClick = (e) => {
@@ -1471,7 +1606,7 @@ function Dropdown({
1471
1606
  };
1472
1607
  function renderRow(entry, key) {
1473
1608
  if (!isRow(entry)) {
1474
- return /* @__PURE__ */ jsx14("div", { className: "ui-dropdown__sep", role: "separator", hidden: filtering || void 0 }, key);
1609
+ return /* @__PURE__ */ jsx15("div", { className: "ui-dropdown__sep", role: "separator", hidden: filtering || void 0 }, key);
1475
1610
  }
1476
1611
  const disabled = !!entry.disabled;
1477
1612
  const selected = selectedOf(entry);
@@ -1493,23 +1628,23 @@ function Dropdown({
1493
1628
  ...asLink ? { href: entry.href, ...entry.target ? { target: entry.target } : null } : null,
1494
1629
  ...sx ? { id: rowIds.get(entry), hidden: hiddenBy(entry) || void 0 } : null,
1495
1630
  onClick: (e) => choose(entry, e),
1496
- children: /* @__PURE__ */ jsxs12(Fragment5, { children: [
1497
- entry.icon && /* @__PURE__ */ jsx14(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
1498
- /* @__PURE__ */ jsxs12("span", { className: "ui-dropdown__main", children: [
1499
- /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__label", children: entry.label }),
1500
- entry.description && /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__desc", children: entry.description })
1631
+ children: /* @__PURE__ */ jsxs13(Fragment5, { children: [
1632
+ entry.icon && /* @__PURE__ */ jsx15(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
1633
+ /* @__PURE__ */ jsxs13("span", { className: "ui-dropdown__main", children: [
1634
+ /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__label", children: entry.label }),
1635
+ entry.description && /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__desc", children: entry.description })
1501
1636
  ] }),
1502
- entry.badge ? /* @__PURE__ */ jsx14(RowBadge, { badge: entry.badge }) : null,
1503
- asOption && /* @__PURE__ */ jsx14(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
1637
+ entry.badge ? /* @__PURE__ */ jsx15(RowBadge, { badge: entry.badge }) : null,
1638
+ asOption && /* @__PURE__ */ jsx15(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
1504
1639
  ] })
1505
1640
  };
1506
- if (row) return /* @__PURE__ */ jsx14(Fragment4, { children: row(entry, props) }, key);
1641
+ if (row) return /* @__PURE__ */ jsx15(Fragment4, { children: row(entry, props) }, key);
1507
1642
  const Tag = asLink ? "a" : "div";
1508
- return /* @__PURE__ */ jsx14(Tag, { ...props }, key);
1643
+ return /* @__PURE__ */ jsx15(Tag, { ...props }, key);
1509
1644
  }
1510
1645
  const body = sections?.length ? sections.map((section, si) => {
1511
1646
  const gone = filtering && !(section.items || []).some((it) => isRow(it) && !hiddenBy(it));
1512
- return /* @__PURE__ */ jsxs12(
1647
+ return /* @__PURE__ */ jsxs13(
1513
1648
  "div",
1514
1649
  {
1515
1650
  className: "ui-dropdown__section",
@@ -1517,7 +1652,7 @@ function Dropdown({
1517
1652
  "aria-label": section.label || void 0,
1518
1653
  hidden: gone || void 0,
1519
1654
  children: [
1520
- section.label && /* @__PURE__ */ jsx14("div", { className: "ui-dropdown__group", role: "presentation", children: section.label }),
1655
+ section.label && /* @__PURE__ */ jsx15("div", { className: "ui-dropdown__group", role: "presentation", children: section.label }),
1521
1656
  (section.items || []).map((entry, i) => renderRow(entry, `s${si}-${i}`))
1522
1657
  ]
1523
1658
  },
@@ -1525,12 +1660,12 @@ function Dropdown({
1525
1660
  );
1526
1661
  }) : (items || []).map((entry, i) => renderRow(entry, `i${i}`));
1527
1662
  const cap = scroll && scroll !== true ? { maxHeight: typeof scroll === "number" ? `${scroll}px` : scroll } : void 0;
1528
- const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
1529
- /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
1530
- /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__none-hint", children: sx.hint })
1663
+ const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
1664
+ /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
1665
+ /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__none-hint", children: sx.hint })
1531
1666
  ] }) : null;
1532
- return /* @__PURE__ */ jsxs12("div", { className: cx5("ui-dropdown", open && "open"), id, ref: root, onKeyDown, children: [
1533
- /* @__PURE__ */ jsxs12(
1667
+ return /* @__PURE__ */ jsxs13("div", { className: cx5("ui-dropdown", open && "open"), id, ref: root, onKeyDown, children: [
1668
+ /* @__PURE__ */ jsxs13(
1534
1669
  "button",
1535
1670
  {
1536
1671
  type: "button",
@@ -1545,15 +1680,15 @@ function Dropdown({
1545
1680
  setOpen(!open);
1546
1681
  },
1547
1682
  children: [
1548
- triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs12(Fragment5, { children: [
1549
- label && /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__pre", children: label }),
1550
- /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__value", children: shown != null ? shown : placeholder })
1683
+ triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs13(Fragment5, { children: [
1684
+ label && /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__pre", children: label }),
1685
+ /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__value", children: shown != null ? shown : placeholder })
1551
1686
  ] }),
1552
- chevron && /* @__PURE__ */ jsx14("span", { className: "ui-dropdown__chevron", "aria-hidden": "true" })
1687
+ chevron && /* @__PURE__ */ jsx15("span", { className: "ui-dropdown__chevron", "aria-hidden": "true" })
1553
1688
  ]
1554
1689
  }
1555
1690
  ),
1556
- /* @__PURE__ */ jsxs12(
1691
+ /* @__PURE__ */ jsxs13(
1557
1692
  "div",
1558
1693
  {
1559
1694
  className: cx5(
@@ -1573,10 +1708,10 @@ function Dropdown({
1573
1708
  onMouseMove,
1574
1709
  children: [
1575
1710
  header,
1576
- sx ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
1577
- /* @__PURE__ */ jsxs12("div", { className: "ui-dropdown__search", children: [
1578
- /* @__PURE__ */ jsx14(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
1579
- /* @__PURE__ */ jsx14(
1711
+ sx ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
1712
+ /* @__PURE__ */ jsxs13("div", { className: "ui-dropdown__search", children: [
1713
+ /* @__PURE__ */ jsx15(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
1714
+ /* @__PURE__ */ jsx15(
1580
1715
  "input",
1581
1716
  {
1582
1717
  className: "ui-dropdown__search-input",
@@ -1600,8 +1735,8 @@ function Dropdown({
1600
1735
  }
1601
1736
  )
1602
1737
  ] }),
1603
- /* @__PURE__ */ jsx14("div", { className: "ui-dropdown__list", role: "listbox", id: listId, "aria-label": name, style: cap, children: body }),
1604
- /* @__PURE__ */ jsx14(
1738
+ /* @__PURE__ */ jsx15("div", { className: "ui-dropdown__list", role: "listbox", id: listId, "aria-label": name, style: cap, children: body }),
1739
+ /* @__PURE__ */ jsx15(
1605
1740
  "div",
1606
1741
  {
1607
1742
  className: "ui-dropdown__none",
@@ -1626,7 +1761,7 @@ function strip(o) {
1626
1761
  }
1627
1762
 
1628
1763
  // src/BackLink.tsx
1629
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1764
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1630
1765
  var BARE = "Back";
1631
1766
  var SCRIPTED = /^javascript:/i;
1632
1767
  var LEADING = /^[\u0000-\u0020]+/;
@@ -1645,7 +1780,7 @@ function BackLink({
1645
1780
  const name = text(label).replace(SAID, "");
1646
1781
  const bare = !name || name.toLowerCase() === BARE.toLowerCase();
1647
1782
  const Tag = as ?? "a";
1648
- return /* @__PURE__ */ jsxs13(
1783
+ return /* @__PURE__ */ jsxs14(
1649
1784
  Tag,
1650
1785
  {
1651
1786
  className: ["ui-back", className].filter(Boolean).join(" "),
@@ -1653,8 +1788,8 @@ function BackLink({
1653
1788
  "aria-label": bare ? void 0 : `${BARE} to ${name}`,
1654
1789
  ...rest,
1655
1790
  children: [
1656
- /* @__PURE__ */ jsx15(Icon, { name: "chevronLeft" }),
1657
- /* @__PURE__ */ jsx15("span", { className: "ui-back__label", children: bare ? BARE : name })
1791
+ /* @__PURE__ */ jsx16(Icon, { name: "chevronLeft" }),
1792
+ /* @__PURE__ */ jsx16("span", { className: "ui-back__label", children: bare ? BARE : name })
1658
1793
  ]
1659
1794
  }
1660
1795
  );
@@ -1662,42 +1797,43 @@ function BackLink({
1662
1797
 
1663
1798
  // src/TableValues.tsx
1664
1799
  import { numericValue, deltaValue } from "@apliteni/apliteni-ui";
1665
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1800
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1666
1801
  function NumericValue(props) {
1667
- return /* @__PURE__ */ jsx16("span", { dangerouslySetInnerHTML: { __html: numericValue(props) } });
1802
+ return /* @__PURE__ */ jsx17("span", { dangerouslySetInnerHTML: { __html: numericValue(props) } });
1668
1803
  }
1669
1804
  function DeltaValue(props) {
1670
- return /* @__PURE__ */ jsx16("span", { dangerouslySetInnerHTML: { __html: deltaValue(props) } });
1805
+ return /* @__PURE__ */ jsx17("span", { dangerouslySetInnerHTML: { __html: deltaValue(props) } });
1671
1806
  }
1672
1807
  function RowIdentity({ symbol, name, logo, href }) {
1673
1808
  const Tag = href ? "a" : "span";
1674
- return /* @__PURE__ */ jsxs14(Tag, { className: "ui-identity", href, children: [
1675
- /* @__PURE__ */ jsxs14("span", { className: "ui-identity__logo", "aria-hidden": "true", children: [
1676
- /* @__PURE__ */ jsx16("span", { children: symbol.slice(0, 1) }),
1677
- logo && /* @__PURE__ */ jsx16("img", { src: logo, alt: "", onLoad: (e) => {
1809
+ return /* @__PURE__ */ jsxs15(Tag, { className: "ui-identity", href, children: [
1810
+ /* @__PURE__ */ jsxs15("span", { className: "ui-identity__logo", "aria-hidden": "true", children: [
1811
+ /* @__PURE__ */ jsx17("span", { children: symbol.slice(0, 1) }),
1812
+ logo && /* @__PURE__ */ jsx17("img", { src: logo, alt: "", onLoad: (e) => {
1678
1813
  e.currentTarget.hidden = false;
1679
1814
  }, onError: (e) => {
1680
1815
  e.currentTarget.hidden = true;
1681
1816
  } })
1682
1817
  ] }),
1683
- /* @__PURE__ */ jsx16("span", { className: "ui-identity__symbol", children: symbol }),
1684
- /* @__PURE__ */ jsx16("span", { className: "ui-identity__name", children: name })
1818
+ /* @__PURE__ */ jsx17("span", { className: "ui-identity__symbol", children: symbol }),
1819
+ /* @__PURE__ */ jsx17("span", { className: "ui-identity__name", children: name })
1685
1820
  ] });
1686
1821
  }
1687
1822
 
1688
1823
  // src/Segmented.tsx
1689
1824
  import { segmentedNextIndex } from "@apliteni/apliteni-ui";
1690
- import { jsx as jsx17 } from "react/jsx-runtime";
1825
+ import { jsx as jsx18 } from "react/jsx-runtime";
1691
1826
  function Segmented({ options, value, onChange, label, appearance = "pill", disabled = false }) {
1692
1827
  const enabled = options.filter((o) => !o.disabled);
1693
1828
  const tabValue = enabled.some((o) => o.value === value) ? value : enabled[0]?.value;
1694
- return /* @__PURE__ */ jsx17("div", { className: `ui-seg${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx17(
1829
+ return /* @__PURE__ */ jsx18("div", { className: `ui-seg${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx18(
1695
1830
  "button",
1696
1831
  {
1697
1832
  type: "button",
1698
1833
  "data-value": option.value,
1699
1834
  disabled: disabled || option.disabled,
1700
1835
  className: value === option.value ? "is-active" : void 0,
1836
+ "aria-label": option.ariaLabel,
1701
1837
  "aria-pressed": value === option.value,
1702
1838
  tabIndex: option.value === tabValue ? 0 : -1,
1703
1839
  onClick: () => onChange(option.value),
@@ -1716,16 +1852,16 @@ function Segmented({ options, value, onChange, label, appearance = "pill", disab
1716
1852
  }
1717
1853
 
1718
1854
  // src/FilterBar.tsx
1719
- import { useLayoutEffect as useLayoutEffect3, useRef as useRef9 } from "react";
1855
+ import { useLayoutEffect as useLayoutEffect4, useRef as useRef11 } from "react";
1720
1856
  import { filterBar, initFilterBar } from "@apliteni/apliteni-ui";
1721
- import { jsx as jsx18 } from "react/jsx-runtime";
1857
+ import { jsx as jsx19 } from "react/jsx-runtime";
1722
1858
  function FilterBar(props) {
1723
- const host = useRef9(null);
1724
- const latest = useRef9(props);
1859
+ const host = useRef11(null);
1860
+ const latest = useRef11(props);
1725
1861
  latest.current = props;
1726
- const controller = useRef9(null);
1727
- const initial = useRef9({ __html: filterBar(props) });
1728
- useLayoutEffect3(() => {
1862
+ const controller = useRef11(null);
1863
+ const initial = useRef11({ __html: filterBar(props) });
1864
+ useLayoutEffect4(() => {
1729
1865
  const el = host.current;
1730
1866
  controller.current = initFilterBar(el, latest.current);
1731
1867
  const remove = (e) => latest.current.onRemove(e.detail.id);
@@ -1744,44 +1880,44 @@ function FilterBar(props) {
1744
1880
  el.removeEventListener("ui-filter-change", change);
1745
1881
  };
1746
1882
  }, []);
1747
- useLayoutEffect3(() => {
1883
+ useLayoutEffect4(() => {
1748
1884
  controller.current?.update(props);
1749
1885
  }, [props.filters, props.label, props.clearLabel, props.disabled, props.busy]);
1750
- return /* @__PURE__ */ jsx18("div", { ref: host, dangerouslySetInnerHTML: initial.current });
1886
+ return /* @__PURE__ */ jsx19("div", { ref: host, dangerouslySetInnerHTML: initial.current });
1751
1887
  }
1752
1888
 
1753
1889
  // src/KeyValueList.tsx
1754
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1890
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1755
1891
  function detail({ value, redacted }) {
1756
- if (redacted) return /* @__PURE__ */ jsxs15("span", { className: "ui-kv__hidden", children: [
1757
- /* @__PURE__ */ jsx19(Icon, { name: "eyeOff" }),
1892
+ if (redacted) return /* @__PURE__ */ jsxs16("span", { className: "ui-kv__hidden", children: [
1893
+ /* @__PURE__ */ jsx20(Icon, { name: "eyeOff" }),
1758
1894
  "Hidden"
1759
1895
  ] });
1760
1896
  if (value == null) return "\u2014";
1761
1897
  return typeof value === "boolean" ? String(value) : value;
1762
1898
  }
1763
1899
  function KeyValueList({ rows, columns = 1, className, ...rest }) {
1764
- return /* @__PURE__ */ jsx19("dl", { ...rest, className: ["ui-drawer__rows", "ui-kv", columns === 2 && "ui-kv--two-columns", className].filter(Boolean).join(" "), children: rows.map((row, index) => /* @__PURE__ */ jsxs15("div", { className: "ui-drawer__row", children: [
1765
- /* @__PURE__ */ jsx19("dt", { children: row.label }),
1766
- /* @__PURE__ */ jsx19("dd", { children: detail(row) })
1900
+ return /* @__PURE__ */ jsx20("dl", { ...rest, className: ["ui-kv", columns === 2 && "ui-kv--two-columns", className].filter(Boolean).join(" "), children: rows.map((row, index) => /* @__PURE__ */ jsxs16("div", { className: "ui-drawer__row", children: [
1901
+ /* @__PURE__ */ jsx20("dt", { children: row.label }),
1902
+ /* @__PURE__ */ jsx20("dd", { children: detail(row) })
1767
1903
  ] }, index)) });
1768
1904
  }
1769
1905
  function DrawerSection({ title, headingLevel = 3, className, children, ...rest }) {
1770
1906
  const Heading = `h${headingLevel}`;
1771
- return /* @__PURE__ */ jsxs15("section", { ...rest, className: ["ui-drawer__section", className].filter(Boolean).join(" "), children: [
1772
- title != null && /* @__PURE__ */ jsx19(Heading, { className: "ui-drawer__section-title", children: title }),
1907
+ return /* @__PURE__ */ jsxs16("section", { ...rest, className: ["ui-drawer__section", className].filter(Boolean).join(" "), children: [
1908
+ title != null && /* @__PURE__ */ jsx20(Heading, { className: "ui-drawer__section-title", children: title }),
1773
1909
  children
1774
1910
  ] });
1775
1911
  }
1776
1912
 
1777
1913
  // src/Snippet.tsx
1778
- import { useEffect as useEffect5, useRef as useRef10, useState as useState6 } from "react";
1779
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1914
+ import { useEffect as useEffect7, useRef as useRef12, useState as useState7 } from "react";
1915
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1780
1916
  function Snippet({ label = "shell", code = "", reveal = false, copyLabel = "Copy" }) {
1781
- const [status, setStatus] = useState6("idle");
1782
- const request = useRef10(0);
1783
- const timer = useRef10(void 0);
1784
- useEffect5(() => {
1917
+ const [status, setStatus] = useState7("idle");
1918
+ const request = useRef12(0);
1919
+ const timer = useRef12(void 0);
1920
+ useEffect7(() => {
1785
1921
  setStatus("idle");
1786
1922
  return () => {
1787
1923
  request.current++;
@@ -1801,33 +1937,33 @@ function Snippet({ label = "shell", code = "", reveal = false, copyLabel = "Copy
1801
1937
  if (current === request.current) setStatus("failed");
1802
1938
  }
1803
1939
  }
1804
- return /* @__PURE__ */ jsxs16("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
1805
- /* @__PURE__ */ jsxs16("div", { className: "ui-snippet__bar", children: [
1806
- /* @__PURE__ */ jsx20("span", { children: label }),
1807
- /* @__PURE__ */ jsxs16("button", { type: "button", className: "ui-snippet__copy", "aria-live": "polite", "aria-atomic": "true", onClick: copy, children: [
1808
- /* @__PURE__ */ jsx20(Icon, { name: status === "copied" ? "check" : "copy" }),
1940
+ return /* @__PURE__ */ jsxs17("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
1941
+ /* @__PURE__ */ jsxs17("div", { className: "ui-snippet__bar", children: [
1942
+ /* @__PURE__ */ jsx21("span", { children: label }),
1943
+ /* @__PURE__ */ jsxs17("button", { type: "button", className: "ui-snippet__copy", "aria-live": "polite", "aria-atomic": "true", onClick: copy, children: [
1944
+ /* @__PURE__ */ jsx21(Icon, { name: status === "copied" ? "check" : "copy" }),
1809
1945
  status === "copied" ? "Copied" : status === "failed" ? "Copy failed" : copyLabel
1810
1946
  ] })
1811
1947
  ] }),
1812
- /* @__PURE__ */ jsx20("pre", { children: code })
1948
+ /* @__PURE__ */ jsx21("pre", { children: code })
1813
1949
  ] });
1814
1950
  }
1815
1951
 
1816
1952
  // src/Tabs.tsx
1817
- import { useEffect as useEffect6, useId as useId7, useRef as useRef11 } from "react";
1953
+ import { useEffect as useEffect8, useId as useId9, useRef as useRef13 } from "react";
1818
1954
  import { playEntrance } from "@apliteni/apliteni-ui/motion";
1819
- import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1955
+ import { Fragment as Fragment6, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1820
1956
  function Tabs({ items, value, onChange, label }) {
1821
- const id = useId7();
1822
- const previous = useRef11(value);
1823
- const activePanel = useRef11(null);
1824
- const buttons = useRef11([]);
1825
- useEffect6(() => {
1957
+ const id = useId9();
1958
+ const previous = useRef13(value);
1959
+ const activePanel = useRef13(null);
1960
+ const buttons = useRef13([]);
1961
+ useEffect8(() => {
1826
1962
  if (previous.current !== value) playEntrance(activePanel.current);
1827
1963
  previous.current = value;
1828
1964
  }, [value]);
1829
- return /* @__PURE__ */ jsxs17("div", { className: "ui-tabs", children: [
1830
- /* @__PURE__ */ jsx21("div", { className: "ui-tabs__list", role: "tablist", "aria-label": label, children: items.map((item, i) => /* @__PURE__ */ jsxs17(
1965
+ return /* @__PURE__ */ jsxs18("div", { className: "ui-tabs", children: [
1966
+ /* @__PURE__ */ jsx22("div", { className: "ui-tabs__list", role: "tablist", "aria-label": label, children: items.map((item, i) => /* @__PURE__ */ jsxs18(
1831
1967
  "button",
1832
1968
  {
1833
1969
  type: "button",
@@ -1865,7 +2001,7 @@ function Tabs({ items, value, onChange, label }) {
1865
2001
  },
1866
2002
  children: [
1867
2003
  item.label,
1868
- item.count != null && /* @__PURE__ */ jsxs17(Fragment6, { children: [
2004
+ item.count != null && /* @__PURE__ */ jsxs18(Fragment6, { children: [
1869
2005
  " ",
1870
2006
  item.count
1871
2007
  ] })
@@ -1873,7 +2009,7 @@ function Tabs({ items, value, onChange, label }) {
1873
2009
  },
1874
2010
  item.value
1875
2011
  )) }),
1876
- /* @__PURE__ */ jsx21("div", { className: "ui-tabs__panels", children: items.map((item, i) => /* @__PURE__ */ jsx21(
2012
+ /* @__PURE__ */ jsx22("div", { className: "ui-tabs__panels", children: items.map((item, i) => /* @__PURE__ */ jsx22(
1877
2013
  "div",
1878
2014
  {
1879
2015
  className: "ui-tabs__panel",
@@ -1891,14 +2027,14 @@ function Tabs({ items, value, onChange, label }) {
1891
2027
  }
1892
2028
 
1893
2029
  // src/Timeline.tsx
1894
- import { useEffect as useEffect7, useRef as useRef12 } from "react";
2030
+ import { useEffect as useEffect9, useRef as useRef14 } from "react";
1895
2031
  import { playEntrance as playEntrance2, prefersReducedMotion } from "@apliteni/apliteni-ui/motion";
1896
- import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
2032
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
1897
2033
  var kindIcons = { person: "user", rule: "bolt", reversal: "refresh" };
1898
2034
  function Timeline({ events, className, ...rest }) {
1899
- const previousIds = useRef12(new Set(events.map((event) => event.id)));
1900
- const rows = useRef12(/* @__PURE__ */ new Map());
1901
- useEffect7(() => {
2035
+ const previousIds = useRef14(new Set(events.map((event) => event.id)));
2036
+ const rows = useRef14(/* @__PURE__ */ new Map());
2037
+ useEffect9(() => {
1902
2038
  if (previousIds.current.size > 0 && !prefersReducedMotion()) {
1903
2039
  for (const event of events) {
1904
2040
  if (previousIds.current.has(event.id)) continue;
@@ -1910,7 +2046,7 @@ function Timeline({ events, className, ...rest }) {
1910
2046
  }
1911
2047
  previousIds.current = new Set(events.map((event) => event.id));
1912
2048
  }, [events]);
1913
- return /* @__PURE__ */ jsx22("ol", { ...rest, role: "list", className: ["ui-timeline", events.some((event) => event.kind) && "ui-timeline--kinds", className].filter(Boolean).join(" "), children: events.map((event, index) => /* @__PURE__ */ jsxs18(
2049
+ return /* @__PURE__ */ jsx23("ol", { ...rest, role: "list", className: ["ui-timeline", events.some((event) => event.kind) && "ui-timeline--kinds", className].filter(Boolean).join(" "), children: events.map((event, index) => /* @__PURE__ */ jsxs19(
1914
2050
  "li",
1915
2051
  {
1916
2052
  className: "ui-timeline__event",
@@ -1919,20 +2055,20 @@ function Timeline({ events, className, ...rest }) {
1919
2055
  else rows.current.delete(event.id);
1920
2056
  },
1921
2057
  children: [
1922
- /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: [
2058
+ /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: [
1923
2059
  "ui-timeline__marker",
1924
2060
  event.kind && "ui-timeline__marker--kind",
1925
2061
  event.kind === "reversal" && "ui-timeline__marker--reversal"
1926
- ].filter(Boolean).join(" "), children: event.kind && /* @__PURE__ */ jsx22(Icon, { name: kindIcons[event.kind] }) }),
1927
- /* @__PURE__ */ jsxs18("div", { className: "ui-timeline__head", children: [
1928
- /* @__PURE__ */ jsx22("span", { className: "ui-timeline__actor", children: event.actor }),
1929
- /* @__PURE__ */ jsx22("time", { dateTime: event.dateTime, children: event.timestamp }),
1930
- index === events.length - 1 && event.relativeTimestamp && /* @__PURE__ */ jsx22("span", { className: "ui-timeline__relative", children: event.relativeTimestamp })
2062
+ ].filter(Boolean).join(" "), children: event.kind && /* @__PURE__ */ jsx23(Icon, { name: kindIcons[event.kind] }) }),
2063
+ /* @__PURE__ */ jsxs19("div", { className: "ui-timeline__head", children: [
2064
+ /* @__PURE__ */ jsx23("span", { className: "ui-timeline__actor", children: event.actor }),
2065
+ /* @__PURE__ */ jsx23("time", { dateTime: event.dateTime, children: event.timestamp }),
2066
+ index === events.length - 1 && event.relativeTimestamp && /* @__PURE__ */ jsx23("span", { className: "ui-timeline__relative", children: event.relativeTimestamp })
1931
2067
  ] }),
1932
- /* @__PURE__ */ jsx22("p", { className: "ui-timeline__description", children: event.description }),
1933
- (event.meta != null || event.undo) && /* @__PURE__ */ jsxs18("div", { className: "ui-timeline__meta", children: [
1934
- event.meta != null && /* @__PURE__ */ jsx22("span", { children: event.meta }),
1935
- event.undo && /* @__PURE__ */ jsx22(Button, { variant: "ghost", size: "xs", className: "ui-btn ui-btn--ghost ui-btn--xs ui-timeline__undo", "aria-label": event.undo.label, onClick: event.undo.onUndo, children: "Undo" })
2068
+ /* @__PURE__ */ jsx23("p", { className: "ui-timeline__description", children: event.description }),
2069
+ (event.meta != null || event.undo) && /* @__PURE__ */ jsxs19("div", { className: "ui-timeline__meta", children: [
2070
+ event.meta != null && /* @__PURE__ */ jsx23("span", { children: event.meta }),
2071
+ event.undo && /* @__PURE__ */ jsx23(Button, { variant: "ghost", size: "xs", className: "ui-btn ui-btn--ghost ui-btn--xs ui-timeline__undo", "aria-label": event.undo.label, onClick: event.undo.onUndo, children: "Undo" })
1936
2072
  ] })
1937
2073
  ]
1938
2074
  },
@@ -1941,20 +2077,20 @@ function Timeline({ events, className, ...rest }) {
1941
2077
  }
1942
2078
 
1943
2079
  // src/Field.tsx
1944
- import { useEffect as useEffect8, useId as useId8, useRef as useRef13, useState as useState7 } from "react";
2080
+ import { useEffect as useEffect10, useId as useId10, useRef as useRef15, useState as useState8 } from "react";
1945
2081
  import { esc, icon as icon4 } from "@apliteni/apliteni-ui";
1946
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
2082
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1947
2083
  function messages(id, hint, error) {
1948
2084
  return [error && `${id}-error`, hint && `${id}-hint`].filter(Boolean).join(" ") || void 0;
1949
2085
  }
1950
2086
  function Frame({ id, label, hint, error, required, children }) {
1951
- return /* @__PURE__ */ jsxs19("div", { className: "ui-field", children: [
1952
- /* @__PURE__ */ jsxs19("label", { className: "ui-field__label", htmlFor: id, children: [
2087
+ return /* @__PURE__ */ jsxs20("div", { className: "ui-field", children: [
2088
+ /* @__PURE__ */ jsxs20("label", { className: "ui-field__label", htmlFor: id, children: [
1953
2089
  label,
1954
- required && /* @__PURE__ */ jsx23("span", { className: "ui-field__req", "aria-hidden": "true", children: "*" })
2090
+ required && /* @__PURE__ */ jsx24("span", { className: "ui-field__req", "aria-hidden": "true", children: "*" })
1955
2091
  ] }),
1956
2092
  children,
1957
- error && /* @__PURE__ */ jsx23(
2093
+ error && /* @__PURE__ */ jsx24(
1958
2094
  "div",
1959
2095
  {
1960
2096
  id: `${id}-error`,
@@ -1963,17 +2099,17 @@ function Frame({ id, label, hint, error, required, children }) {
1963
2099
  dangerouslySetInnerHTML: { __html: icon4("alert") + esc(error) }
1964
2100
  }
1965
2101
  ),
1966
- hint && /* @__PURE__ */ jsx23("div", { id: `${id}-hint`, className: "ui-field__hint", children: hint })
2102
+ hint && /* @__PURE__ */ jsx24("div", { id: `${id}-hint`, className: "ui-field__hint", children: hint })
1967
2103
  ] });
1968
2104
  }
1969
2105
  function wiring(id, hint, error) {
1970
2106
  return { id, "aria-describedby": messages(id, hint, error), "aria-invalid": error ? true : void 0 };
1971
2107
  }
1972
2108
  function TextField({ label, hint, error, required, type = "text", unit, className = "", ...props }) {
1973
- const id = useId8();
2109
+ const id = useId10();
1974
2110
  const hasUnit = type === "number" && !!unit;
1975
2111
  const describedBy = [messages(id, hint, error), hasUnit ? `${id}-unit` : ""].filter(Boolean).join(" ") || void 0;
1976
- const control = /* @__PURE__ */ jsx23(
2112
+ const control = /* @__PURE__ */ jsx24(
1977
2113
  "input",
1978
2114
  {
1979
2115
  ...props,
@@ -1985,14 +2121,14 @@ function TextField({ label, hint, error, required, type = "text", unit, classNam
1985
2121
  className: `ui-input${error ? " is-invalid" : ""} ${className}`
1986
2122
  }
1987
2123
  );
1988
- return /* @__PURE__ */ jsx23(Frame, { ...{ id, label, hint, error, required }, children: hasUnit ? /* @__PURE__ */ jsxs19("div", { className: "ui-field-number", children: [
2124
+ return /* @__PURE__ */ jsx24(Frame, { ...{ id, label, hint, error, required }, children: hasUnit ? /* @__PURE__ */ jsxs20("div", { className: "ui-field-number", children: [
1989
2125
  control,
1990
- /* @__PURE__ */ jsx23("span", { id: `${id}-unit`, className: "ui-field-number__unit", children: unit })
2126
+ /* @__PURE__ */ jsx24("span", { id: `${id}-unit`, className: "ui-field-number__unit", children: unit })
1991
2127
  ] }) : control });
1992
2128
  }
1993
2129
  function TextArea({ label, hint, error, required, className = "", ...props }) {
1994
- const id = useId8();
1995
- return /* @__PURE__ */ jsx23(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx23(
2130
+ const id = useId10();
2131
+ return /* @__PURE__ */ jsx24(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx24(
1996
2132
  "textarea",
1997
2133
  {
1998
2134
  rows: 4,
@@ -2004,8 +2140,8 @@ function TextArea({ label, hint, error, required, className = "", ...props }) {
2004
2140
  ) });
2005
2141
  }
2006
2142
  function SelectField({ label, hint, error, required, className = "", children, ...props }) {
2007
- const id = useId8();
2008
- return /* @__PURE__ */ jsx23(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx23(
2143
+ const id = useId10();
2144
+ return /* @__PURE__ */ jsx24(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx24(
2009
2145
  "select",
2010
2146
  {
2011
2147
  ...props,
@@ -2017,11 +2153,11 @@ function SelectField({ label, hint, error, required, className = "", children, .
2017
2153
  ) });
2018
2154
  }
2019
2155
  function FileField({ label, hint, error, required, disabled, onFileChange, className = "", ...props }) {
2020
- const id = useId8();
2021
- const input = useRef13(null);
2022
- const [file, setFile] = useState7(null);
2023
- const [dragging, setDragging] = useState7(false);
2024
- useEffect8(() => {
2156
+ const id = useId10();
2157
+ const input = useRef15(null);
2158
+ const [file, setFile] = useState8(null);
2159
+ const [dragging, setDragging] = useState8(false);
2160
+ useEffect10(() => {
2025
2161
  const form = input.current?.form;
2026
2162
  const reset = () => {
2027
2163
  setFile(null);
@@ -2034,7 +2170,7 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2034
2170
  setFile(next);
2035
2171
  onFileChange?.(next);
2036
2172
  };
2037
- return /* @__PURE__ */ jsx23(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsxs19(
2173
+ return /* @__PURE__ */ jsx24(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsxs20(
2038
2174
  "div",
2039
2175
  {
2040
2176
  className: `ui-file${dragging && !disabled ? " is-dragging" : ""}${file ? " has-file" : ""}${error ? " is-invalid" : ""}${disabled ? " is-disabled" : ""}`,
@@ -2055,12 +2191,12 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2055
2191
  update(transfer.files[0]);
2056
2192
  },
2057
2193
  children: [
2058
- /* @__PURE__ */ jsx23("span", { className: "ui-file__glyph", children: /* @__PURE__ */ jsx23(Icon, { name: "upload" }) }),
2059
- /* @__PURE__ */ jsx23("div", { "aria-live": "polite", children: file ? file.name : "Drop a file here" }),
2060
- /* @__PURE__ */ jsx23("div", { children: "or choose one from your device" }),
2061
- /* @__PURE__ */ jsxs19("span", { className: "ui-file__choose", children: [
2062
- /* @__PURE__ */ jsx23("span", { className: "ui-btn ui-btn--secondary ui-btn--sm", "aria-hidden": "true", "aria-disabled": disabled || void 0, children: file ? "Replace file" : "Choose file" }),
2063
- /* @__PURE__ */ jsx23(
2194
+ /* @__PURE__ */ jsx24("span", { className: "ui-file__glyph", children: /* @__PURE__ */ jsx24(Icon, { name: "upload" }) }),
2195
+ /* @__PURE__ */ jsx24("div", { "aria-live": "polite", children: file ? file.name : "Drop a file here" }),
2196
+ /* @__PURE__ */ jsx24("div", { children: "or choose one from your device" }),
2197
+ /* @__PURE__ */ jsxs20("span", { className: "ui-file__choose", children: [
2198
+ /* @__PURE__ */ jsx24("span", { className: "ui-btn ui-btn--secondary ui-btn--sm", "aria-hidden": "true", "aria-disabled": disabled || void 0, children: file ? "Replace file" : "Choose file" }),
2199
+ /* @__PURE__ */ jsx24(
2064
2200
  "input",
2065
2201
  {
2066
2202
  ...props,
@@ -2080,9 +2216,9 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2080
2216
  }
2081
2217
 
2082
2218
  // src/Toast.tsx
2083
- import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect9, useLayoutEffect as useLayoutEffect4, useRef as useRef14, useState as useState8 } from "react";
2219
+ import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect11, useLayoutEffect as useLayoutEffect5, useRef as useRef16, useState as useState9 } from "react";
2084
2220
  import { createPortal as createPortal4 } from "react-dom";
2085
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
2221
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
2086
2222
  var Context = createContext2(null);
2087
2223
  var glyphs = { success: "circleCheck", danger: "circleX", warn: "circleAlert", info: "info", neutral: "bolt" };
2088
2224
  function useToast() {
@@ -2091,12 +2227,12 @@ function useToast() {
2091
2227
  return push;
2092
2228
  }
2093
2229
  function Notice({ notice, remove }) {
2094
- const root = useRef14(null);
2095
- const [leaving2, setLeaving] = useState8(false);
2096
- const dismissed = useRef14(false);
2097
- const remaining = useRef14(5e3);
2098
- const [hovered, setHovered] = useState8(false);
2099
- const [focused, setFocused] = useState8(false);
2230
+ const root = useRef16(null);
2231
+ const [leaving2, setLeaving] = useState9(false);
2232
+ const dismissed = useRef16(false);
2233
+ const remaining = useRef16(5e3);
2234
+ const [hovered, setHovered] = useState9(false);
2235
+ const [focused, setFocused] = useState9(false);
2100
2236
  const paused = hovered || focused;
2101
2237
  const tone = notice.tone ?? "success";
2102
2238
  const dismiss = useCallback3(() => {
@@ -2105,7 +2241,7 @@ function Notice({ notice, remove }) {
2105
2241
  if (typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches) remove();
2106
2242
  else setLeaving(true);
2107
2243
  }, [remove]);
2108
- useEffect9(() => {
2244
+ useEffect11(() => {
2109
2245
  if (leaving2) {
2110
2246
  const element = root.current;
2111
2247
  const finish = (event) => {
@@ -2119,7 +2255,7 @@ function Notice({ notice, remove }) {
2119
2255
  };
2120
2256
  }
2121
2257
  }, [leaving2, remove]);
2122
- useEffect9(() => {
2258
+ useEffect11(() => {
2123
2259
  if (leaving2 || notice.action || paused) return;
2124
2260
  const started = Date.now();
2125
2261
  const timer = setTimeout(dismiss, remaining.current);
@@ -2128,7 +2264,7 @@ function Notice({ notice, remove }) {
2128
2264
  remaining.current = Math.max(0, remaining.current - (Date.now() - started));
2129
2265
  };
2130
2266
  }, [dismiss, leaving2, notice.action, paused]);
2131
- return /* @__PURE__ */ jsxs20(
2267
+ return /* @__PURE__ */ jsxs21(
2132
2268
  "div",
2133
2269
  {
2134
2270
  ref: root,
@@ -2142,12 +2278,12 @@ function Notice({ notice, remove }) {
2142
2278
  if (!event.currentTarget.contains(event.relatedTarget)) setFocused(false);
2143
2279
  },
2144
2280
  children: [
2145
- /* @__PURE__ */ jsx24("span", { className: "ui-toast__icon", children: /* @__PURE__ */ jsx24(Icon, { name: glyphs[tone] }) }),
2146
- /* @__PURE__ */ jsxs20("div", { className: "ui-toast__body", children: [
2147
- /* @__PURE__ */ jsx24("div", { className: "ui-toast__title", children: notice.title }),
2148
- notice.text && /* @__PURE__ */ jsx24("div", { className: "ui-toast__text", children: notice.text })
2281
+ /* @__PURE__ */ jsx25("span", { className: "ui-toast__icon", children: /* @__PURE__ */ jsx25(Icon, { name: glyphs[tone] }) }),
2282
+ /* @__PURE__ */ jsxs21("div", { className: "ui-toast__body", children: [
2283
+ /* @__PURE__ */ jsx25("div", { className: "ui-toast__title", children: notice.title }),
2284
+ notice.text && /* @__PURE__ */ jsx25("div", { className: "ui-toast__text", children: notice.text })
2149
2285
  ] }),
2150
- notice.action && /* @__PURE__ */ jsx24(
2286
+ notice.action && /* @__PURE__ */ jsx25(
2151
2287
  "button",
2152
2288
  {
2153
2289
  type: "button",
@@ -2162,8 +2298,8 @@ function Notice({ notice, remove }) {
2162
2298
  children: notice.action.label
2163
2299
  }
2164
2300
  ),
2165
- /* @__PURE__ */ jsx24("button", { type: "button", className: "ui-toast__close", "aria-label": "Dismiss", disabled: leaving2, onClick: dismiss, children: /* @__PURE__ */ jsx24(Icon, { name: "x" }) }),
2166
- !notice.action && /* @__PURE__ */ jsx24(
2301
+ /* @__PURE__ */ jsx25("button", { type: "button", className: "ui-toast__close", "aria-label": "Dismiss", disabled: leaving2, onClick: dismiss, children: /* @__PURE__ */ jsx25(Icon, { name: "x" }) }),
2302
+ !notice.action && /* @__PURE__ */ jsx25(
2167
2303
  "span",
2168
2304
  {
2169
2305
  className: "ui-toast__timer is-running",
@@ -2177,7 +2313,7 @@ function Notice({ notice, remove }) {
2177
2313
  }
2178
2314
  var REACH = "--rx-toast-stack";
2179
2315
  function usePublishedReach(stack2, count) {
2180
- useLayoutEffect4(() => {
2316
+ useLayoutEffect5(() => {
2181
2317
  const element = stack2.current;
2182
2318
  const view = element?.ownerDocument.defaultView;
2183
2319
  const root = element?.ownerDocument.documentElement;
@@ -2196,28 +2332,28 @@ function usePublishedReach(stack2, count) {
2196
2332
  }, [stack2, count]);
2197
2333
  }
2198
2334
  function Toast({ children }) {
2199
- const [entries, setEntries] = useState8([]);
2200
- const nextId = useRef14(0);
2201
- const stack2 = useRef14(null);
2335
+ const [entries, setEntries] = useState9([]);
2336
+ const nextId = useRef16(0);
2337
+ const stack2 = useRef16(null);
2202
2338
  const push = useCallback3((notice) => {
2203
2339
  const id = nextId.current++;
2204
2340
  const remove = () => setEntries((current) => current.filter((entry) => entry.id !== id));
2205
2341
  setEntries((current) => [...current, { id, notice, remove }]);
2206
2342
  }, []);
2207
2343
  usePublishedReach(stack2, entries.length);
2208
- return /* @__PURE__ */ jsxs20(Context.Provider, { value: push, children: [
2344
+ return /* @__PURE__ */ jsxs21(Context.Provider, { value: push, children: [
2209
2345
  children,
2210
2346
  typeof document !== "undefined" && createPortal4(
2211
- /* @__PURE__ */ jsx24("div", { className: "ui-toast-stack rx-toast-stack", ref: stack2, children: entries.map((entry) => /* @__PURE__ */ jsx24(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
2347
+ /* @__PURE__ */ jsx25("div", { className: "ui-toast-stack rx-toast-stack", ref: stack2, children: entries.map((entry) => /* @__PURE__ */ jsx25(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
2212
2348
  document.body
2213
2349
  )
2214
2350
  ] });
2215
2351
  }
2216
2352
 
2217
2353
  // src/AppShell.tsx
2218
- import { useEffect as useEffect10, useId as useId9, useState as useState9 } from "react";
2354
+ import { useEffect as useEffect12, useId as useId11, useState as useState10 } from "react";
2219
2355
  import { applyTheme, paletteHotkey, prism, railCollapsed, themeIcon, themeName } from "@apliteni/apliteni-ui";
2220
- import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
2356
+ import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
2221
2357
  var path = (value) => value.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
2222
2358
  function AppShell({
2223
2359
  sections,
@@ -2238,21 +2374,21 @@ function AppShell({
2238
2374
  palette,
2239
2375
  renderLink
2240
2376
  }) {
2241
- const uid = useId9();
2242
- const [collapsed, setCollapsed] = useState9(defaultCollapsed);
2243
- const [search, setSearch] = useState9(false);
2244
- const [more, setMore] = useState9(false);
2245
- const [theme, setTheme] = useState9("dark");
2377
+ const uid = useId11();
2378
+ const [collapsed, setCollapsed] = useState10(defaultCollapsed);
2379
+ const [search, setSearch] = useState10(false);
2380
+ const [more, setMore] = useState10(false);
2381
+ const [theme, setTheme] = useState10("dark");
2246
2382
  const current = path(pathname);
2247
2383
  const active = sections.filter((section) => current === path(section.href) || path(section.href) !== "/" && current.startsWith(`${path(section.href)}/`)).sort((a, b) => path(b.href).length - path(a.href).length)[0];
2248
- useEffect10(() => {
2384
+ useEffect12(() => {
2249
2385
  setCollapsed(railCollapsed() ?? defaultCollapsed);
2250
2386
  }, [defaultCollapsed]);
2251
- useEffect10(() => {
2387
+ useEffect12(() => {
2252
2388
  setMore(false);
2253
2389
  setSearch(false);
2254
2390
  }, [pathname]);
2255
- useEffect10(() => {
2391
+ useEffect12(() => {
2256
2392
  const root = document.documentElement;
2257
2393
  const sync2 = () => setTheme(root.getAttribute("data-theme") === "light" ? "light" : "dark");
2258
2394
  sync2();
@@ -2260,7 +2396,7 @@ function AppShell({
2260
2396
  observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
2261
2397
  return () => observer.disconnect();
2262
2398
  }, []);
2263
- useEffect10(() => {
2399
+ useEffect12(() => {
2264
2400
  const hotkey = (event) => {
2265
2401
  if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey || event.key.toLowerCase() !== "k") return;
2266
2402
  const target = event.target;
@@ -2288,44 +2424,44 @@ function AppShell({
2288
2424
  onClick: (event) => {
2289
2425
  if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) setMore(false);
2290
2426
  },
2291
- children: /* @__PURE__ */ jsxs21(Fragment7, { children: [
2292
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx25(Icon, { name: section.icon }) }),
2293
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: section.label }),
2294
- section.count != null && /* @__PURE__ */ jsx25("span", { className: "ui-nav__badge", children: section.count })
2427
+ children: /* @__PURE__ */ jsxs22(Fragment7, { children: [
2428
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx26(Icon, { name: section.icon }) }),
2429
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__label", children: section.label }),
2430
+ section.count != null && /* @__PURE__ */ jsx26("span", { className: "ui-nav__badge", children: section.count })
2295
2431
  ] })
2296
2432
  };
2297
- return /* @__PURE__ */ jsx25("li", { children: renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx25("a", { ...linkProps }) }, section.href);
2433
+ return /* @__PURE__ */ jsx26("li", { children: renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx26("a", { ...linkProps }) }, section.href);
2298
2434
  });
2299
2435
  const foldLabel = collapsed ? "Expand sidebar" : "Collapse sidebar";
2300
2436
  const visible = sections.length > 4 ? sections.slice(0, 3) : sections;
2301
2437
  const remaining = sections.slice(visible.length);
2302
2438
  const initials = account.name.trim().split(/\s+/).map((part) => part[0]).slice(0, 2).join("");
2303
- return /* @__PURE__ */ jsxs21("div", { className: `ui-app ui-app--topbar ui-react-app${collapsed ? " is-collapsed" : ""}`, children: [
2304
- /* @__PURE__ */ jsxs21("div", { className: "ui-app__rail", children: [
2305
- /* @__PURE__ */ jsx25("div", { className: "ui-app__head", children: /* @__PURE__ */ jsxs21("a", { className: "ui-app__brand", href: brandHref, "aria-label": word, children: [
2306
- brand ?? /* @__PURE__ */ jsx25("i", { "aria-hidden": "true", className: "ui-react-app__mark", dangerouslySetInnerHTML: { __html: prism(uid, 24) } }),
2307
- /* @__PURE__ */ jsx25("span", { children: word })
2439
+ return /* @__PURE__ */ jsxs22("div", { className: `ui-app ui-app--topbar ui-react-app${collapsed ? " is-collapsed" : ""}`, children: [
2440
+ /* @__PURE__ */ jsxs22("div", { className: "ui-app__rail", children: [
2441
+ /* @__PURE__ */ jsx26("div", { className: "ui-app__head", children: /* @__PURE__ */ jsxs22("a", { className: "ui-app__brand", href: brandHref, "aria-label": word, children: [
2442
+ brand ?? /* @__PURE__ */ jsx26("i", { "aria-hidden": "true", className: "ui-react-app__mark", dangerouslySetInnerHTML: { __html: prism(uid, 24) } }),
2443
+ /* @__PURE__ */ jsx26("span", { children: word })
2308
2444
  ] }) }),
2309
- /* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-nav--side", "aria-label": "Sections", children: /* @__PURE__ */ jsx25("ul", { className: "ui-nav__list", children: links(sections) }) }),
2310
- /* @__PURE__ */ jsx25("div", { className: "ui-app__foot", children: /* @__PURE__ */ jsx25("div", { className: "ui-app__fold-row", children: /* @__PURE__ */ jsxs21("button", { type: "button", className: "ui-nav__item ui-app__fold", "aria-expanded": !collapsed, "aria-label": foldLabel, onClick: fold, children: [
2311
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsxs21("svg", { className: "ui-icon", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
2312
- /* @__PURE__ */ jsx25("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2313
- /* @__PURE__ */ jsx25("path", { className: "ui-app__fold-seam", d: "M9 3v18" })
2445
+ /* @__PURE__ */ jsx26("nav", { className: "ui-nav ui-nav--side", "aria-label": "Sections", children: /* @__PURE__ */ jsx26("ul", { className: "ui-nav__list", children: links(sections) }) }),
2446
+ /* @__PURE__ */ jsx26("div", { className: "ui-app__foot", children: /* @__PURE__ */ jsx26("div", { className: "ui-app__fold-row", children: /* @__PURE__ */ jsxs22("button", { type: "button", className: "ui-nav__item ui-app__fold", "aria-expanded": !collapsed, "aria-label": foldLabel, onClick: fold, children: [
2447
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsxs22("svg", { className: "ui-icon", viewBox: "0 0 24 24", "aria-hidden": "true", children: [
2448
+ /* @__PURE__ */ jsx26("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2449
+ /* @__PURE__ */ jsx26("path", { className: "ui-app__fold-seam", d: "M9 3v18" })
2314
2450
  ] }) }),
2315
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: foldLabel })
2451
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__label", children: foldLabel })
2316
2452
  ] }) }) })
2317
2453
  ] }),
2318
- /* @__PURE__ */ jsxs21("div", { className: "ui-app__well", children: [
2319
- /* @__PURE__ */ jsxs21("header", { className: "ui-app__bar", children: [
2320
- /* @__PURE__ */ jsxs21("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
2321
- /* @__PURE__ */ jsx25("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx25(Icon, { name: "search" }) }),
2322
- /* @__PURE__ */ jsx25("span", { className: "ui-app__search-txt", children: "Search or run a command\u2026" }),
2323
- /* @__PURE__ */ jsx25("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
2454
+ /* @__PURE__ */ jsxs22("div", { className: "ui-app__well", children: [
2455
+ /* @__PURE__ */ jsxs22("header", { className: "ui-app__bar", children: [
2456
+ /* @__PURE__ */ jsxs22("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
2457
+ /* @__PURE__ */ jsx26("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx26(Icon, { name: "search" }) }),
2458
+ /* @__PURE__ */ jsx26("span", { className: "ui-app__search-txt", children: "Search or run a command\u2026" }),
2459
+ /* @__PURE__ */ jsx26("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
2324
2460
  ] }),
2325
- /* @__PURE__ */ jsx25("span", { className: "ui-app__bar-gap" }),
2461
+ /* @__PURE__ */ jsx26("span", { className: "ui-app__bar-gap" }),
2326
2462
  bandControl,
2327
- /* @__PURE__ */ jsx25("button", { type: "button", className: "toggle", "aria-label": themeName(theme), title: themeName(theme), onClick: () => applyTheme(theme === "light" ? "dark" : "light"), children: /* @__PURE__ */ jsx25("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: themeIcon(theme) } }) }),
2328
- /* @__PURE__ */ jsx25("div", { className: "ui-app__user ui-app__user--bar", children: /* @__PURE__ */ jsx25(
2463
+ /* @__PURE__ */ jsx26("button", { type: "button", className: "toggle", "aria-label": themeName(theme), title: themeName(theme), onClick: () => applyTheme(theme === "light" ? "dark" : "light"), children: /* @__PURE__ */ jsx26("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: themeIcon(theme) } }) }),
2464
+ /* @__PURE__ */ jsx26("div", { className: "ui-app__user ui-app__user--bar", children: /* @__PURE__ */ jsx26(
2329
2465
  Dropdown,
2330
2466
  {
2331
2467
  variant: "menu",
@@ -2334,27 +2470,27 @@ function AppShell({
2334
2470
  ariaLabel: `Signed in as ${account.name}, ${account.email}`,
2335
2471
  triggerClass: "ui-app__user-trigger",
2336
2472
  panelClass: "ui-app__user-panel",
2337
- triggerContent: /* @__PURE__ */ jsx25("span", { className: "ui-app__av", "aria-hidden": "true", children: initials }),
2338
- header: /* @__PURE__ */ jsxs21("div", { className: "ui-dropdown__head", children: [
2339
- /* @__PURE__ */ jsx25("b", { children: account.name }),
2340
- /* @__PURE__ */ jsx25("span", { children: account.email })
2473
+ triggerContent: /* @__PURE__ */ jsx26("span", { className: "ui-app__av", "aria-hidden": "true", children: initials }),
2474
+ header: /* @__PURE__ */ jsxs22("div", { className: "ui-dropdown__head", children: [
2475
+ /* @__PURE__ */ jsx26("b", { children: account.name }),
2476
+ /* @__PURE__ */ jsx26("span", { children: account.email })
2341
2477
  ] }),
2342
2478
  items: [{ label: "Sign out", icon: "logout", danger: true }],
2343
2479
  onSelect: onSignOut
2344
2480
  }
2345
2481
  ) })
2346
2482
  ] }),
2347
- /* @__PURE__ */ jsxs21("main", { className: `ui-app__main${width === "wide" ? " ui-app__main--wide" : ""}`, children: [
2348
- back && /* @__PURE__ */ jsx25(BackLink, { ...back }),
2349
- /* @__PURE__ */ jsx25("h1", { children: title }),
2350
- lede && /* @__PURE__ */ jsx25("p", { className: "ui-app__sub", children: lede }),
2351
- actions && /* @__PURE__ */ jsx25("div", { className: "ui-react-app__actions", children: actions }),
2352
- /* @__PURE__ */ jsx25("div", { className: "ui-app__body", children })
2483
+ /* @__PURE__ */ jsxs22("main", { className: `ui-app__main${width === "wide" ? " ui-app__main--wide" : ""}`, children: [
2484
+ back && /* @__PURE__ */ jsx26(BackLink, { ...back }),
2485
+ /* @__PURE__ */ jsx26("h1", { children: title }),
2486
+ lede && /* @__PURE__ */ jsx26("p", { className: "ui-app__sub", children: lede }),
2487
+ actions && /* @__PURE__ */ jsx26("div", { className: "ui-react-app__actions", children: actions }),
2488
+ /* @__PURE__ */ jsx26("div", { className: "ui-app__body", children })
2353
2489
  ] })
2354
2490
  ] }),
2355
- /* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-react-app__bottom", "aria-label": "Sections on mobile", children: /* @__PURE__ */ jsxs21("ul", { className: "ui-nav__list", children: [
2491
+ /* @__PURE__ */ jsx26("nav", { className: "ui-nav ui-react-app__bottom", "aria-label": "Sections on mobile", children: /* @__PURE__ */ jsxs22("ul", { className: "ui-nav__list", children: [
2356
2492
  links(visible),
2357
- remaining.length > 0 && /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsxs21(
2493
+ remaining.length > 0 && /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsxs22(
2358
2494
  "button",
2359
2495
  {
2360
2496
  type: "button",
@@ -2363,20 +2499,20 @@ function AppShell({
2363
2499
  "aria-expanded": more,
2364
2500
  onClick: () => setMore(true),
2365
2501
  children: [
2366
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx25(Icon, { name: "moreHorizontal" }) }),
2367
- /* @__PURE__ */ jsx25("span", { className: "ui-nav__label", children: "More" })
2502
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx26(Icon, { name: "moreHorizontal" }) }),
2503
+ /* @__PURE__ */ jsx26("span", { className: "ui-nav__label", children: "More" })
2368
2504
  ]
2369
2505
  }
2370
2506
  ) })
2371
2507
  ] }) }),
2372
- /* @__PURE__ */ jsx25(Drawer, { open: more, onClose: () => setMore(false), title: "More sections", side: "bottom", children: /* @__PURE__ */ jsx25("nav", { className: "ui-nav ui-nav--side", "aria-label": "More sections", children: /* @__PURE__ */ jsx25("ul", { className: "ui-nav__list", children: links(remaining) }) }) }),
2373
- /* @__PURE__ */ jsx25(CommandPalette, { ...palette ?? { groups: [{ items: sections.map((section) => ({ id: section.href, ...section })) }] }, open: search, onClose: () => setSearch(false) })
2508
+ /* @__PURE__ */ jsx26(Drawer, { open: more, onClose: () => setMore(false), title: "More sections", side: "bottom", children: /* @__PURE__ */ jsx26("nav", { className: "ui-nav ui-nav--side", "aria-label": "More sections", children: /* @__PURE__ */ jsx26("ul", { className: "ui-nav__list", children: links(remaining) }) }) }),
2509
+ /* @__PURE__ */ jsx26(CommandPalette, { ...palette ?? { groups: [{ items: sections.map((section) => ({ id: section.href, ...section })) }] }, open: search, onClose: () => setSearch(false) })
2374
2510
  ] });
2375
2511
  }
2376
2512
 
2377
2513
  // src/EmptyState.tsx
2378
2514
  import { icon as kitIcon2, illo } from "@apliteni/apliteni-ui";
2379
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
2515
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
2380
2516
  var cases = {
2381
2517
  "first-run": { title: "Nothing needs you yet", sub: "New items will appear here when they need your attention.", icon: "check" },
2382
2518
  "no-matches": { title: "No results in this view", sub: "Try another search or clear your filters.", icon: "search" },
@@ -2388,18 +2524,18 @@ function EmptyState({ variant = "first-run", title, sub, icon: icon6, art, actio
2388
2524
  const heading = title ?? preset.title;
2389
2525
  const guidance = sub ?? preset.sub;
2390
2526
  const glyph = icon6 ?? preset.icon;
2391
- return /* @__PURE__ */ jsxs22("div", { className: "ui-empty", children: [
2392
- art ? typeof art === "string" ? /* @__PURE__ */ jsx26("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx26("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx26("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon2(glyph) } }) : null,
2393
- heading && /* @__PURE__ */ jsx26("div", { className: "ui-empty__title", children: heading }),
2394
- guidance && /* @__PURE__ */ jsx26("div", { className: "ui-empty__sub", children: guidance }),
2395
- actions && /* @__PURE__ */ jsx26("div", { className: "ui-empty__actions", children: actions })
2527
+ return /* @__PURE__ */ jsxs23("div", { className: "ui-empty", children: [
2528
+ art ? typeof art === "string" ? /* @__PURE__ */ jsx27("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx27("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx27("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon2(glyph) } }) : null,
2529
+ heading && /* @__PURE__ */ jsx27("div", { className: "ui-empty__title", children: heading }),
2530
+ guidance && /* @__PURE__ */ jsx27("div", { className: "ui-empty__sub", children: guidance }),
2531
+ actions && /* @__PURE__ */ jsx27("div", { className: "ui-empty__actions", children: actions })
2396
2532
  ] });
2397
2533
  }
2398
2534
 
2399
2535
  // src/ThemeToggle.tsx
2400
2536
  import { useSyncExternalStore } from "react";
2401
2537
  import { icon as icon5 } from "@apliteni/apliteni-ui";
2402
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
2538
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
2403
2539
  var STORAGE_KEY = "apliteni-strategy-theme";
2404
2540
  var CHOICE_EVENT = "apliteni-theme-choice";
2405
2541
  var THEME_INIT_SCRIPT = `(()=>{let t;try{t=localStorage.getItem('apliteni-strategy-theme')}catch{}document.documentElement.setAttribute('data-theme',t==='dark'||t==='light'?t:window.matchMedia?.('(prefers-color-scheme: light)').matches?'light':'dark')})()`;
@@ -2457,116 +2593,16 @@ function ThemeToggle({ labelled = false }) {
2457
2593
  }
2458
2594
  window.dispatchEvent(new Event(CHOICE_EVENT));
2459
2595
  };
2460
- const button = /* @__PURE__ */ jsx27("button", { type: "button", className: "toggle", "aria-label": name, title: name, onClick: toggle, children: /* @__PURE__ */ jsx27("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon5(theme === "auto" ? "monitor" : theme === "light" ? "sun" : "moon") } }) });
2461
- return labelled ? /* @__PURE__ */ jsxs23("span", { className: "ui-theme-toggle", children: [
2596
+ const button = /* @__PURE__ */ jsx28("button", { type: "button", className: "toggle", "aria-label": name, title: name, onClick: toggle, children: /* @__PURE__ */ jsx28("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon5(theme === "auto" ? "monitor" : theme === "light" ? "sun" : "moon") } }) });
2597
+ return labelled ? /* @__PURE__ */ jsxs24("span", { className: "ui-theme-toggle", children: [
2462
2598
  button,
2463
- /* @__PURE__ */ jsxs23("span", { children: [
2599
+ /* @__PURE__ */ jsxs24("span", { children: [
2464
2600
  label,
2465
2601
  " theme"
2466
2602
  ] })
2467
2603
  ] }) : button;
2468
2604
  }
2469
2605
 
2470
- // src/Tooltip.tsx
2471
- import { useEffect as useEffect11, useId as useId10, useLayoutEffect as useLayoutEffect5, useRef as useRef15, useState as useState10 } from "react";
2472
- import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
2473
- function Tooltip({ text: text2, children }) {
2474
- const id = useId10();
2475
- const host = useRef15(null);
2476
- const trigger = useRef15(null);
2477
- const tip = useRef15(null);
2478
- const ignoreMouseUntil = useRef15(0);
2479
- const touchMoved = useRef15(false);
2480
- const [open, setOpen] = useState10(false);
2481
- function place() {
2482
- const h = host.current;
2483
- const t = tip.current;
2484
- const mark = trigger.current.getBoundingClientRect();
2485
- const rect = h.getBoundingClientRect();
2486
- const view = h.ownerDocument.documentElement;
2487
- const clip = { top: 0, left: 0, right: view.clientWidth, bottom: view.clientHeight };
2488
- for (let el = h; el && el !== h.ownerDocument.body; el = el.parentElement) {
2489
- const style = getComputedStyle(el);
2490
- if (![style.overflow, style.overflowX, style.overflowY].some((v) => v && v !== "visible")) continue;
2491
- const bounds = el.getBoundingClientRect();
2492
- clip.top = Math.max(clip.top, bounds.top);
2493
- clip.left = Math.max(clip.left, bounds.left);
2494
- clip.right = Math.min(clip.right, bounds.right);
2495
- clip.bottom = Math.min(clip.bottom, bounds.bottom);
2496
- }
2497
- const gap = parseFloat(getComputedStyle(t).getPropertyValue("--ui-tip-gap")) || 8;
2498
- const above = mark.top - clip.top;
2499
- const below = clip.bottom - mark.bottom;
2500
- const isBelow = above < t.offsetHeight + gap && below > above;
2501
- t.classList.toggle("is-below", isBelow);
2502
- const centre = mark.left + mark.width / 2;
2503
- const ideal = centre - t.offsetWidth / 2;
2504
- const left = Math.max(clip.left, Math.min(ideal, clip.right - t.offsetWidth));
2505
- t.style.setProperty("--ui-tip-x", `${centre - rect.left - h.clientLeft + h.scrollLeft}px`);
2506
- t.style.setProperty("--ui-tip-y", `${(isBelow ? mark.bottom : mark.top) - rect.top - h.clientTop + h.scrollTop}px`);
2507
- t.style.setProperty("--ui-tip-shift", `${left - ideal}px`);
2508
- }
2509
- useLayoutEffect5(() => {
2510
- if (open) place();
2511
- }, [open, text2]);
2512
- useEffect11(() => {
2513
- if (!open) return;
2514
- const doc = host.current.ownerDocument;
2515
- const view = doc.defaultView;
2516
- const escape = (event) => {
2517
- if (event.key === "Escape") setOpen(false);
2518
- };
2519
- doc.addEventListener("keydown", escape);
2520
- view.addEventListener("scroll", place, true);
2521
- view.addEventListener("resize", place);
2522
- return () => {
2523
- doc.removeEventListener("keydown", escape);
2524
- view.removeEventListener("scroll", place, true);
2525
- view.removeEventListener("resize", place);
2526
- };
2527
- }, [open]);
2528
- return /* @__PURE__ */ jsxs24("span", { ref: host, className: "ui-tip-host", style: { display: "inline-block" }, children: [
2529
- /* @__PURE__ */ jsx28(
2530
- "span",
2531
- {
2532
- ref: trigger,
2533
- className: "ui-focusable",
2534
- tabIndex: 0,
2535
- "aria-describedby": id,
2536
- onMouseEnter: () => {
2537
- if (Date.now() > ignoreMouseUntil.current) setOpen(true);
2538
- },
2539
- onMouseLeave: () => {
2540
- if (Date.now() > ignoreMouseUntil.current) setOpen(false);
2541
- },
2542
- onFocus: () => {
2543
- if (Date.now() > ignoreMouseUntil.current) setOpen(true);
2544
- },
2545
- onBlur: () => setOpen(false),
2546
- onKeyDown: (event) => {
2547
- if (event.key === "Escape") setOpen(false);
2548
- },
2549
- onTouchStart: () => {
2550
- ignoreMouseUntil.current = Date.now() + 800;
2551
- touchMoved.current = false;
2552
- },
2553
- onTouchMove: () => {
2554
- touchMoved.current = true;
2555
- },
2556
- onTouchCancel: () => {
2557
- touchMoved.current = true;
2558
- },
2559
- onTouchEnd: () => {
2560
- ignoreMouseUntil.current = Date.now() + 800;
2561
- if (!touchMoved.current) setOpen((value) => !value);
2562
- },
2563
- children
2564
- }
2565
- ),
2566
- /* @__PURE__ */ jsx28("span", { ref: tip, id, role: "tooltip", className: `ui-tip${open ? " is-open" : ""}`, children: /* @__PURE__ */ jsx28("span", { className: "ui-tip__label", children: text2 }) })
2567
- ] });
2568
- }
2569
-
2570
2606
  // src/index.ts
2571
2607
  var PAGE_SIZES = KIT_PAGE_SIZES;
2572
2608
  var DEFAULT_PAGE_SIZE3 = KIT_DEFAULT_PAGE_SIZE;