@apliteni/apliteni-ui 0.117.0 → 0.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.117.0",
3
+ "version": "0.119.0",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
package/react/README.md CHANGED
@@ -636,7 +636,7 @@ AppShell includes the kit’s rail and top band. Pass the current router pathnam
636
636
 
637
637
  ## Tooltip
638
638
 
639
- Tooltip accepts text and inline children, without nested controls. Hovering or focusing opens it; pressing Escape, moving focus away, or moving the mouse away closes it. On touch devices, tapping toggles it. It uses the kit’s tooltip styles and moves below the trigger when there is not enough space above. Keep the same information elsewhere on the page.
639
+ Tooltip accepts `text` (a label shorthand), or `label`, `value`, and `detail`, with inline children without nested controls. Hovering or focusing opens it; pressing Escape, moving focus away, or moving the mouse away closes it. On touch devices, tapping toggles it. It uses the kit’s tooltip styles and moves below the trigger when there is not enough space above. Keep the same information elsewhere on the page.
640
640
 
641
641
  ```tsx
642
642
  <Tooltip text="Updated daily">Balance</Tooltip>
@@ -837,11 +837,15 @@ type ThemeToggleProps = {
837
837
  declare function ThemeToggle({ labelled }: ThemeToggleProps): react.JSX.Element;
838
838
 
839
839
  type TooltipProps = {
840
- text: string;
840
+ text?: string;
841
+ label?: string;
842
+ value?: string;
843
+ detail?: string;
844
+ placement?: 'top' | 'bottom';
841
845
  /** Inline content without nested controls. */
842
846
  children: ReactNode;
843
847
  };
844
- declare function Tooltip({ text, children }: TooltipProps): react.JSX.Element;
848
+ declare function Tooltip({ text, label, value, detail, placement, children }: TooltipProps): react.JSX.Element;
845
849
 
846
850
  type SuccessMark = 'line' | 'circled';
847
851
  type SuccessCheckProps = Omit<SVGAttributes<SVGSVGElement>, 'children'> & {
@@ -271,11 +271,9 @@ function Callout({ variant, icon: icon7 = calloutIcons[variant ?? "neutral"], ch
271
271
  // src/primitives/StatBand.tsx
272
272
  import { useId as useId2 } from "react";
273
273
 
274
- // src/Tooltip.tsx
275
- import { useEffect, useId, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "react";
276
-
277
274
  // src/tip.ts
278
- function placeTip(host, mark, tip, bound) {
275
+ var TIP_GAP = 8;
276
+ function placeTip(host, mark, tip, bound, placement = "top") {
279
277
  const mrect = mark.getBoundingClientRect();
280
278
  const rect = host.getBoundingClientRect();
281
279
  const view = host.ownerDocument.documentElement;
@@ -296,10 +294,13 @@ function placeTip(host, mark, tip, bound) {
296
294
  clip.right = Math.min(clip.right, edge.right);
297
295
  clip.bottom = Math.min(clip.bottom, edge.bottom);
298
296
  }
299
- const gap = parseFloat(getComputedStyle(tip).getPropertyValue("--ui-tip-gap")) || 8;
297
+ const declared = parseFloat(getComputedStyle(tip).getPropertyValue("--ui-tip-gap"));
298
+ const gap = Number.isFinite(declared) ? declared : TIP_GAP;
300
299
  const above = mrect.top - clip.top;
301
300
  const below = clip.bottom - mrect.bottom;
302
- const isBelow = above < tip.offsetHeight + gap && below > above;
301
+ const prefersBelow = placement === "bottom";
302
+ const flip = prefersBelow ? below < tip.offsetHeight + gap && above > below : above < tip.offsetHeight + gap && below > above;
303
+ const isBelow = prefersBelow !== flip;
303
304
  tip.classList.toggle("is-below", isBelow);
304
305
  const centre = mrect.left + mrect.width / 2;
305
306
  const ideal = centre - tip.offsetWidth / 2;
@@ -310,79 +311,196 @@ function placeTip(host, mark, tip, bound) {
310
311
  }
311
312
 
312
313
  // src/Tooltip.tsx
313
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
314
- function Tooltip({ text: text2, children }) {
314
+ import { useEffect, useId, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState } from "react";
315
+ import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
316
+ var DOC_EVENTS = ["pointerdown", "pointercancel", "click", "keydown", "touchend"];
317
+ var CAPTURED = /* @__PURE__ */ new Set(["pointerdown", "pointercancel"]);
318
+ var wirings = /* @__PURE__ */ new WeakMap();
319
+ function wireDocument(doc, handlers) {
320
+ let wiring2 = wirings.get(doc);
321
+ if (!wiring2) {
322
+ const members2 = /* @__PURE__ */ new Set();
323
+ const offs = DOC_EVENTS.map((type) => {
324
+ const relay = (event) => {
325
+ for (const member of [...members2]) member[type](event);
326
+ };
327
+ doc.addEventListener(type, relay, CAPTURED.has(type));
328
+ return () => doc.removeEventListener(type, relay, CAPTURED.has(type));
329
+ });
330
+ wiring2 = { members: members2, off: () => offs.forEach((off2) => off2()) };
331
+ wirings.set(doc, wiring2);
332
+ }
333
+ const { members, off } = wiring2;
334
+ members.add(handlers);
335
+ return () => {
336
+ members.delete(handlers);
337
+ if (members.size) return;
338
+ off();
339
+ wirings.delete(doc);
340
+ };
341
+ }
342
+ var Text = ({ label = "", value = "", detail: detail2 = "" }) => /* @__PURE__ */ jsxs6(Fragment, { children: [
343
+ /* @__PURE__ */ jsx10("span", { className: "ui-tip__label", hidden: !label, children: label }),
344
+ /* @__PURE__ */ jsx10("span", { className: "ui-tip__value", hidden: !value, children: value }),
345
+ /* @__PURE__ */ jsx10("span", { className: "ui-tip__detail", hidden: !detail2, children: detail2 })
346
+ ] });
347
+ function Tooltip({ text: text2, label = text2, value, detail: detail2, placement = "top", children }) {
315
348
  const id = useId();
316
349
  const host = useRef2(null);
317
350
  const trigger = useRef2(null);
318
351
  const tip = useRef2(null);
319
352
  const ignoreMouseUntil = useRef2(0);
320
353
  const touchMoved = useRef2(false);
321
- const [open, setOpen] = useState(false);
322
- const place = () => placeTip(host.current, trigger.current, tip.current);
354
+ const pointerKind = useRef2("");
355
+ const pendingClick = useRef2(null);
356
+ const dismissed = useRef2(null);
357
+ const [mark, setMark] = useState(null);
358
+ const active = useRef2(null);
359
+ active.current = mark;
360
+ const open = mark !== null;
361
+ function close(reset = false) {
362
+ dismissed.current = reset ? null : active.current;
363
+ setMark(null);
364
+ }
365
+ function show(target) {
366
+ if (target && target !== dismissed.current) {
367
+ dismissed.current = null;
368
+ setMark(target);
369
+ }
370
+ }
371
+ function markOf(target) {
372
+ if (!(target instanceof Element)) return null;
373
+ return trigger.current?.contains(target) ? trigger.current : null;
374
+ }
375
+ function place() {
376
+ const h = host.current;
377
+ const t = tip.current;
378
+ const target = active.current;
379
+ if (!h || !t || !target) return;
380
+ const anchor = target.querySelector("[data-tip-anchor]") || target;
381
+ placeTip(h, anchor, t, void 0, placement);
382
+ }
323
383
  useLayoutEffect2(() => {
324
- if (open) place();
325
- }, [open, text2]);
384
+ if (!mark) return;
385
+ if (!host.current?.contains(mark)) {
386
+ close(true);
387
+ return;
388
+ }
389
+ place();
390
+ });
391
+ const shared = useRef2({});
392
+ shared.current.keydown = (event) => {
393
+ ignoreMouseUntil.current = 0;
394
+ pointerKind.current = "";
395
+ pendingClick.current = null;
396
+ if (event.key === "Escape") close();
397
+ };
398
+ shared.current.touchend = (event) => {
399
+ if (!host.current?.contains(event.target)) close(true);
400
+ };
401
+ shared.current.pointerdown = (event) => {
402
+ pointerKind.current = event.pointerType;
403
+ if (event.pointerType === "touch" || event.pointerType === "pen") ignoreMouseUntil.current = Date.now() + 800;
404
+ };
405
+ shared.current.pointercancel = () => {
406
+ pendingClick.current = null;
407
+ };
408
+ shared.current.click = (event) => {
409
+ if ((pointerKind.current === "touch" || pointerKind.current === "pen") && !host.current?.contains(event.target)) close(true);
410
+ };
411
+ useEffect(() => wireDocument(host.current.ownerDocument, shared.current), []);
326
412
  useEffect(() => {
327
413
  if (!open) return;
328
- const doc = host.current.ownerDocument;
329
- const view = doc.defaultView;
330
- const escape = (event) => {
331
- if (event.key === "Escape") setOpen(false);
332
- };
333
- doc.addEventListener("keydown", escape);
334
- view.addEventListener("scroll", place, true);
335
- view.addEventListener("resize", place);
414
+ const view = host.current.ownerDocument.defaultView;
415
+ const reposition = () => place();
416
+ view.addEventListener("scroll", reposition, true);
417
+ view.addEventListener("resize", reposition);
336
418
  return () => {
337
- doc.removeEventListener("keydown", escape);
338
- view.removeEventListener("scroll", place, true);
339
- view.removeEventListener("resize", place);
419
+ view.removeEventListener("scroll", reposition, true);
420
+ view.removeEventListener("resize", reposition);
340
421
  };
341
- }, [open]);
342
- return /* @__PURE__ */ jsxs6("span", { ref: host, className: "ui-tip-host", style: { display: "inline-block" }, children: [
343
- /* @__PURE__ */ jsx10(
344
- "span",
345
- {
346
- ref: trigger,
347
- className: "ui-focusable",
348
- tabIndex: 0,
349
- "aria-describedby": id,
350
- onMouseEnter: () => {
351
- if (Date.now() > ignoreMouseUntil.current) setOpen(true);
352
- },
353
- onMouseLeave: () => {
354
- if (Date.now() > ignoreMouseUntil.current) setOpen(false);
355
- },
356
- onFocus: () => {
357
- if (Date.now() > ignoreMouseUntil.current) setOpen(true);
358
- },
359
- onBlur: () => setOpen(false),
360
- onKeyDown: (event) => {
361
- if (event.key === "Escape") setOpen(false);
362
- },
363
- onTouchStart: () => {
364
- ignoreMouseUntil.current = Date.now() + 800;
365
- touchMoved.current = false;
366
- },
367
- onTouchMove: () => {
368
- touchMoved.current = true;
369
- },
370
- onTouchCancel: () => {
371
- touchMoved.current = true;
372
- },
373
- onTouchEnd: () => {
374
- ignoreMouseUntil.current = Date.now() + 800;
375
- if (!touchMoved.current) setOpen((value) => !value);
376
- },
377
- children
378
- }
379
- ),
380
- /* @__PURE__ */ jsx10("span", { ref: tip, id, role: "tooltip", className: `ui-tip${open ? " is-open" : ""}`, children: /* @__PURE__ */ jsx10("span", { className: "ui-tip__label", children: text2 }) })
381
- ] });
422
+ }, [open, placement]);
423
+ return /* @__PURE__ */ jsxs6(
424
+ "span",
425
+ {
426
+ ref: host,
427
+ className: "ui-tip-host",
428
+ style: { display: "inline-block" },
429
+ onMouseOver: (event) => {
430
+ if (Date.now() <= ignoreMouseUntil.current) return;
431
+ const target = markOf(event.target);
432
+ if (target) show(target);
433
+ else setMark(null);
434
+ },
435
+ onMouseLeave: () => {
436
+ if (Date.now() > ignoreMouseUntil.current) close(true);
437
+ },
438
+ onFocus: (event) => {
439
+ if (Date.now() > ignoreMouseUntil.current) show(markOf(event.target));
440
+ },
441
+ onBlur: (event) => {
442
+ if (!markOf(event.relatedTarget)) close(true);
443
+ },
444
+ onPointerOver: (event) => {
445
+ if (event.pointerType === "touch" || event.pointerType === "pen") ignoreMouseUntil.current = Date.now() + 800;
446
+ else if (event.pointerType === "mouse") {
447
+ ignoreMouseUntil.current = 0;
448
+ show(markOf(event.target));
449
+ }
450
+ },
451
+ onClickCapture: (event) => {
452
+ const touched = pendingClick.current;
453
+ pendingClick.current = null;
454
+ if (pointerKind.current !== "pen") return;
455
+ const target = markOf(event.target);
456
+ const opening = touched ? touched === "open" : !!target && target !== mark;
457
+ if (!opening) {
458
+ if (!touched) close();
459
+ return;
460
+ }
461
+ event.preventDefault();
462
+ event.stopPropagation();
463
+ const doc = host.current.ownerDocument;
464
+ pointerKind.current = "";
465
+ doc.documentElement.dispatchEvent(new MouseEvent("click", { bubbles: true }));
466
+ pointerKind.current = "touch";
467
+ dismissed.current = null;
468
+ show(target);
469
+ },
470
+ onTouchStart: () => {
471
+ ignoreMouseUntil.current = Date.now() + 800;
472
+ touchMoved.current = false;
473
+ pendingClick.current = null;
474
+ },
475
+ onTouchMove: () => {
476
+ touchMoved.current = true;
477
+ },
478
+ onTouchCancel: () => {
479
+ touchMoved.current = true;
480
+ },
481
+ onTouchEnd: (event) => {
482
+ ignoreMouseUntil.current = Date.now() + 800;
483
+ if (touchMoved.current) return;
484
+ const target = markOf(event.target);
485
+ if (!target || target === mark) {
486
+ pendingClick.current = "close";
487
+ close();
488
+ } else {
489
+ pendingClick.current = "open";
490
+ dismissed.current = null;
491
+ show(target);
492
+ }
493
+ },
494
+ children: [
495
+ /* @__PURE__ */ jsx10("span", { ref: trigger, className: "ui-focusable", tabIndex: 0, "aria-describedby": id, children }),
496
+ /* @__PURE__ */ jsx10("span", { ref: tip, id, "data-tip": "", role: "tooltip", className: `ui-tip${open ? " is-open" : ""}`, children: /* @__PURE__ */ jsx10(Text, { label, value, detail: detail2 }) })
497
+ ]
498
+ }
499
+ );
382
500
  }
383
501
 
384
502
  // src/primitives/StatBand.tsx
385
- import { Fragment, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
503
+ import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
386
504
  var GLYPH = { up: "arrowUp", down: "arrowDown", flat: "minus" };
387
505
  var directionOf = (text2) => {
388
506
  const t = text2.trim();
@@ -391,7 +509,7 @@ var directionOf = (text2) => {
391
509
  var hasChange = (d) => !!d && d.value != null && d.value !== "";
392
510
  function ContextRow({ caption, delta, basisId }) {
393
511
  if (!hasChange(delta)) return caption ? /* @__PURE__ */ jsx11("dd", { className: "ui-stat__caption", children: caption }) : null;
394
- const lead = caption ? /* @__PURE__ */ jsxs7(Fragment, { children: [
512
+ const lead = caption ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
395
513
  /* @__PURE__ */ jsx11("span", { className: "ui-stat__caption", children: caption }),
396
514
  " "
397
515
  ] }) : null;
@@ -401,7 +519,7 @@ function ContextRow({ caption, delta, basisId }) {
401
519
  lead,
402
520
  /* @__PURE__ */ jsx11(Icon, { name: GLYPH[dir] }),
403
521
  delta.tooltip ? /* @__PURE__ */ jsx11(Tooltip, { text: delta.tooltip, children: /* @__PURE__ */ jsx11("span", { className: "ui-stat__change", children: delta.value }) }) : /* @__PURE__ */ jsx11("span", { className: "ui-stat__change", children: delta.value }),
404
- own ? /* @__PURE__ */ jsxs7(Fragment, { children: [
522
+ own ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
405
523
  " ",
406
524
  /* @__PURE__ */ jsx11("span", { className: "ui-stat__basis", children: own })
407
525
  ] }) : null
@@ -672,7 +790,7 @@ function Modal({ open, title, onClose, footer, children, initialFocusRef, role =
672
790
  }
673
791
 
674
792
  // src/Confirm.tsx
675
- import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
793
+ import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
676
794
  function Confirm({
677
795
  open,
678
796
  title,
@@ -693,7 +811,7 @@ function Confirm({
693
811
  onClose: onCancel,
694
812
  role: "alertdialog",
695
813
  initialFocusRef: safeAction,
696
- footer: /* @__PURE__ */ jsxs9(Fragment2, { children: [
814
+ footer: /* @__PURE__ */ jsxs9(Fragment3, { children: [
697
815
  /* @__PURE__ */ jsx13(Button, { ref: safeAction, variant: "ghost", onClick: onCancel, children: cancelLabel }),
698
816
  /* @__PURE__ */ jsx13(Button, { variant: danger ? "danger" : "primary", busy, onClick: onConfirm, children: confirmLabel })
699
817
  ] }),
@@ -1173,7 +1291,7 @@ function Pagination({
1173
1291
  }
1174
1292
 
1175
1293
  // src/DataTable.tsx
1176
- import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
1294
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
1177
1295
  var NO_SORT = { key: void 0, dir: -1 };
1178
1296
  function sortTableRows(rows, sort) {
1179
1297
  if (sort.key === void 0) return [...rows];
@@ -1280,14 +1398,14 @@ function DataTable({
1280
1398
  strokeLinejoin: "round",
1281
1399
  "aria-hidden": "true",
1282
1400
  focusable: "false",
1283
- children: sort.key === k ? /* @__PURE__ */ jsx17("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
1401
+ children: sort.key === k ? /* @__PURE__ */ jsx17("path", { d: "m8 10 4 4 4-4" }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
1284
1402
  /* @__PURE__ */ jsx17("path", { d: "m8 9 4-4 4 4" }),
1285
1403
  /* @__PURE__ */ jsx17("path", { d: "m8 15 4 4 4-4" })
1286
1404
  ] })
1287
1405
  }
1288
1406
  );
1289
1407
  const pageAllOn = selectable && slice.length > 0 && slice.every((r) => selected.has(r.name));
1290
- return /* @__PURE__ */ jsxs13(Fragment3, { children: [
1408
+ return /* @__PURE__ */ jsxs13(Fragment4, { children: [
1291
1409
  /* @__PURE__ */ jsx17(
1292
1410
  "div",
1293
1411
  {
@@ -1890,15 +2008,16 @@ function DatePicker({
1890
2008
  // `open` on the root whichever form the panel takes, so the trigger's
1891
2009
  // chevron flips for the sheet as it does for the popover. The panel rules
1892
2010
  // it also switches on have no panel to find while the sheet is up.
1893
- /* @__PURE__ */ jsxs15("div", { className: cx5("ui-dropdown", "ui-datepicker", open && "open"), id, ref: root, children: [
2011
+ /* @__PURE__ */ jsxs15("div", { className: cx5("ui-dropdown", "ui-datepicker", open && "open"), ref: root, children: [
1894
2012
  /* @__PURE__ */ jsxs15(
1895
2013
  "button",
1896
2014
  {
1897
2015
  type: "button",
1898
2016
  className: "ui-dropdown__trigger ui-datepicker__trigger",
2017
+ id,
1899
2018
  "aria-haspopup": "dialog",
1900
2019
  "aria-expanded": open,
1901
- "aria-label": ariaLabel || (shown ? void 0 : name),
2020
+ "aria-label": ariaLabel || void 0,
1902
2021
  disabled,
1903
2022
  ref: trigger,
1904
2023
  onClick: (e) => {
@@ -1936,7 +2055,7 @@ function DatePicker({
1936
2055
 
1937
2056
  // src/Dropdown.tsx
1938
2057
  import {
1939
- Fragment as Fragment4,
2058
+ Fragment as Fragment5,
1940
2059
  useCallback as useCallback4,
1941
2060
  useEffect as useEffect7,
1942
2061
  useId as useId7,
@@ -1953,7 +2072,7 @@ import {
1953
2072
  dropdownHeightFit,
1954
2073
  filterPanelRow
1955
2074
  } from "@apliteni/apliteni-ui";
1956
- import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2075
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1957
2076
  var EXIT_SLACK_MS2 = 50;
1958
2077
  var SETTLE_MS = 450;
1959
2078
  var inPanel = (node) => {
@@ -2379,7 +2498,7 @@ function Dropdown({
2379
2498
  ...asLink ? { href: entry.href, ...entry.target ? { target: entry.target } : null } : null,
2380
2499
  ...sx ? { id: rowIds.get(entry), hidden: hiddenBy(entry) || void 0 } : null,
2381
2500
  onClick: (e) => choose(entry, e),
2382
- children: /* @__PURE__ */ jsxs16(Fragment5, { children: [
2501
+ children: /* @__PURE__ */ jsxs16(Fragment6, { children: [
2383
2502
  entry.icon && /* @__PURE__ */ jsx20(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
2384
2503
  /* @__PURE__ */ jsxs16("span", { className: "ui-dropdown__main", children: [
2385
2504
  /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__label", children: entry.label }),
@@ -2389,7 +2508,7 @@ function Dropdown({
2389
2508
  asOption && /* @__PURE__ */ jsx20(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
2390
2509
  ] })
2391
2510
  };
2392
- if (row) return /* @__PURE__ */ jsx20(Fragment4, { children: row(entry, props) }, key);
2511
+ if (row) return /* @__PURE__ */ jsx20(Fragment5, { children: row(entry, props) }, key);
2393
2512
  const Tag = asLink ? "a" : "div";
2394
2513
  return /* @__PURE__ */ jsx20(Tag, { ...props }, key);
2395
2514
  }
@@ -2411,7 +2530,7 @@ function Dropdown({
2411
2530
  );
2412
2531
  }) : (items || []).map((entry, i) => renderRow(entry, `i${i}`));
2413
2532
  const cap = scroll && scroll !== true ? { "--ui-dropdown-cap": typeof scroll === "number" ? `${scroll}px` : scroll } : void 0;
2414
- const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs16(Fragment5, { children: [
2533
+ const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
2415
2534
  /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
2416
2535
  /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__none-hint", children: sx.hint })
2417
2536
  ] }) : null;
@@ -2432,7 +2551,7 @@ function Dropdown({
2432
2551
  setOpen(!open);
2433
2552
  },
2434
2553
  children: [
2435
- triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs16(Fragment5, { children: [
2554
+ triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs16(Fragment6, { children: [
2436
2555
  label && /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__pre", children: label }),
2437
2556
  /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__value", children: shown != null ? shown : placeholder })
2438
2557
  ] }),
@@ -2460,7 +2579,7 @@ function Dropdown({
2460
2579
  onMouseMove,
2461
2580
  children: [
2462
2581
  header,
2463
- sx ? /* @__PURE__ */ jsxs16(Fragment5, { children: [
2582
+ sx ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
2464
2583
  /* @__PURE__ */ jsxs16("div", { className: "ui-dropdown__search", children: [
2465
2584
  /* @__PURE__ */ jsx20(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
2466
2585
  /* @__PURE__ */ jsx20(
@@ -2611,7 +2730,7 @@ function Segmented({ options, value, onChange, label, appearance = "pill", size,
2611
2730
  // src/FilterBar.tsx
2612
2731
  import { useRef as useRef12, useState as useState8 } from "react";
2613
2732
  import { filterChipText, filterChipName, filterChipUnset, filterChipItems, focusNextStop } from "@apliteni/apliteni-ui";
2614
- import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
2733
+ import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
2615
2734
  var SEARCH_AT = 10;
2616
2735
  var isRow2 = (entry) => entry !== "---" && !entry.separator;
2617
2736
  function FilterBar({ filters, label = "Filters", clearLabel = "Clear all", clearVariant = "ghost", add, addLabel = "Filter", disabled = false, busy = false, onRemove, onClear, onChange, onAdd }) {
@@ -2718,7 +2837,7 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all", clear
2718
2837
  variant: "menu",
2719
2838
  sections,
2720
2839
  ariaLabel: addLabel,
2721
- triggerContent: /* @__PURE__ */ jsxs19(Fragment6, { children: [
2840
+ triggerContent: /* @__PURE__ */ jsxs19(Fragment7, { children: [
2722
2841
  /* @__PURE__ */ jsx24(Icon, { name: "plus" }),
2723
2842
  addLabel
2724
2843
  ] }),
@@ -2769,7 +2888,7 @@ function DrawerSection({ title, headingLevel = 3, className, children, ...rest }
2769
2888
 
2770
2889
  // src/Snippet.tsx
2771
2890
  import { useEffect as useEffect8, useRef as useRef13, useState as useState9 } from "react";
2772
- import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2891
+ import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2773
2892
  function Snippet({ label = "shell", code = "", children, copy = true, reveal = false, copyLabel = "Copy code" }) {
2774
2893
  const [status, setStatus] = useState9("idle");
2775
2894
  const request = useRef13(0);
@@ -2797,7 +2916,7 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
2797
2916
  return /* @__PURE__ */ jsxs21("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
2798
2917
  /* @__PURE__ */ jsxs21("div", { className: "ui-snippet__bar", children: [
2799
2918
  /* @__PURE__ */ jsx26("span", { children: label }),
2800
- copy && /* @__PURE__ */ jsxs21(Fragment7, { children: [
2919
+ copy && /* @__PURE__ */ jsxs21(Fragment8, { children: [
2801
2920
  /* @__PURE__ */ jsx26(
2802
2921
  "button",
2803
2922
  {
@@ -2819,7 +2938,7 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
2819
2938
  // src/Tabs.tsx
2820
2939
  import { useEffect as useEffect9, useId as useId8, useRef as useRef14 } from "react";
2821
2940
  import { playEntrance } from "@apliteni/apliteni-ui/motion";
2822
- import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2941
+ import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2823
2942
  function Tabs({ items, value, onChange, label }) {
2824
2943
  const id = useId8();
2825
2944
  const previous = useRef14(value);
@@ -2868,7 +2987,7 @@ function Tabs({ items, value, onChange, label }) {
2868
2987
  },
2869
2988
  children: [
2870
2989
  item.label,
2871
- item.count != null && /* @__PURE__ */ jsxs22(Fragment8, { children: [
2990
+ item.count != null && /* @__PURE__ */ jsxs22(Fragment9, { children: [
2872
2991
  " ",
2873
2992
  item.count
2874
2993
  ] })
@@ -3095,7 +3214,7 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
3095
3214
 
3096
3215
  // src/FileDrop.tsx
3097
3216
  import { useRef as useRef17, useState as useState11 } from "react";
3098
- import { Fragment as Fragment9, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
3217
+ import { Fragment as Fragment10, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
3099
3218
  var MARKS = {
3100
3219
  uploading: "clock",
3101
3220
  done: "circleCheck",
@@ -3207,7 +3326,7 @@ function FileDrop({
3207
3326
  children: /* @__PURE__ */ jsx30("span", { style: { width: `${file.progress}%` } })
3208
3327
  }
3209
3328
  )
3210
- ] }) : /* @__PURE__ */ jsxs25(Fragment9, { children: [
3329
+ ] }) : /* @__PURE__ */ jsxs25(Fragment10, { children: [
3211
3330
  /* @__PURE__ */ jsx30(
3212
3331
  Button,
3213
3332
  {
@@ -3404,7 +3523,7 @@ import { applyTheme, paletteHotkey, prism, railCollapsed, themeIcon, themeName }
3404
3523
  // src/SidebarNav.tsx
3405
3524
  import { forwardRef as forwardRef8, useEffect as useEffect13, useId as useId10, useState as useState13 } from "react";
3406
3525
  import { ENTRANCE_FALLBACK_MS } from "@apliteni/apliteni-ui/motion";
3407
- import { Fragment as Fragment10, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3526
+ import { Fragment as Fragment11, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3408
3527
  var badgeText = (badge) => typeof badge === "object" ? badge.text : badge;
3409
3528
  function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
3410
3529
  const uid = useId10();
@@ -3430,7 +3549,7 @@ function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
3430
3549
  item.disabled && "is-disabled",
3431
3550
  item.danger && "is-danger"
3432
3551
  ].filter(Boolean).join(" ");
3433
- const children = /* @__PURE__ */ jsxs28(Fragment10, { children: [
3552
+ const children = /* @__PURE__ */ jsxs28(Fragment11, { children: [
3434
3553
  (item.leading ?? item.icon) && /* @__PURE__ */ jsx33("span", { className: "ui-nav__ic", children: item.leading ?? /* @__PURE__ */ jsx33(Icon, { name: item.icon }) }),
3435
3554
  /* @__PURE__ */ jsx33("span", { className: "ui-nav__label", children: item.label }),
3436
3555
  count != null && count !== "" && /* @__PURE__ */ jsx33("span", { className: `ui-nav__badge is-${typeof item.badge === "object" ? item.badge.tone ?? "neutral" : "neutral"}`, children: count }),
@@ -3499,7 +3618,7 @@ var SidebarNav = forwardRef8(function SidebarNav2({
3499
3618
  });
3500
3619
 
3501
3620
  // src/AppShell.tsx
3502
- import { Fragment as Fragment11, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
3621
+ import { Fragment as Fragment12, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
3503
3622
  var path = (value) => value.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
3504
3623
  function AppShell({
3505
3624
  sections,
@@ -3574,7 +3693,7 @@ function AppShell({
3574
3693
  onClick: (event) => {
3575
3694
  if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) setMore(false);
3576
3695
  },
3577
- children: /* @__PURE__ */ jsxs29(Fragment11, { children: [
3696
+ children: /* @__PURE__ */ jsxs29(Fragment12, { children: [
3578
3697
  /* @__PURE__ */ jsx34("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx34(Icon, { name: section.icon }) }),
3579
3698
  /* @__PURE__ */ jsx34("span", { className: "ui-nav__label", children: section.label }),
3580
3699
  section.count != null && /* @__PURE__ */ jsx34("span", { className: "ui-nav__badge is-neutral", children: section.count })
@@ -3908,7 +4027,7 @@ import {
3908
4027
  useState as useState16
3909
4028
  } from "react";
3910
4029
  import { CHART_FLOOR, bridgeWalk, chartScale, pointTarget } from "@apliteni/apliteni-ui";
3911
- import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
4030
+ import { Fragment as Fragment13, jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
3912
4031
  var HEIGHT = { months: 216, bridge: 216, spark: 32 };
3913
4032
  var PAD = 2;
3914
4033
  var ZERO_INSET = 1.5;
@@ -4538,7 +4657,7 @@ function Chart(props) {
4538
4657
  `${column.label}-${i}`
4539
4658
  )) })
4540
4659
  ] }) }),
4541
- /* @__PURE__ */ jsx38("span", { ref: tipEl, className: cx8("ui-tip", openId && "is-open"), role: open ? "tooltip" : void 0, children: open && /* @__PURE__ */ jsxs33(Fragment12, { children: [
4660
+ /* @__PURE__ */ jsx38("span", { ref: tipEl, className: cx8("ui-tip", openId && "is-open"), role: open ? "tooltip" : void 0, children: open && /* @__PURE__ */ jsxs33(Fragment13, { children: [
4542
4661
  /* @__PURE__ */ jsx38("span", { className: "ui-tip__label", children: spark ? columns[open.column]?.label : `${open.name}, ${columns[open.column]?.label}` }),
4543
4662
  /* @__PURE__ */ jsx38("span", { className: "ui-tip__value", children: format(open.value) }),
4544
4663
  (stateOf(columns[open.column]) || open.detail) && /* @__PURE__ */ jsx38("span", { className: "ui-tip__detail", children: stateOf(columns[open.column]) || open.detail })
@@ -4561,7 +4680,7 @@ function Chart(props) {
4561
4680
  /* @__PURE__ */ jsx38("tbody", { children: tableRows.map((row, i) => /* @__PURE__ */ jsxs33("tr", { "aria-current": pick === i ? true : void 0, children: [
4562
4681
  /* @__PURE__ */ jsxs33("th", { scope: "row", children: [
4563
4682
  row.column.label,
4564
- row.column.estimated && /* @__PURE__ */ jsxs33(Fragment12, { children: [
4683
+ row.column.estimated && /* @__PURE__ */ jsxs33(Fragment13, { children: [
4565
4684
  " ",
4566
4685
  /* @__PURE__ */ jsx38("span", { className: "ui-chart__state", children: stateOf(row.column) })
4567
4686
  ] })