@apliteni/apliteni-ui 0.77.0 → 0.79.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.
@@ -1445,20 +1445,490 @@ function Denied({
1445
1445
  ] });
1446
1446
  }
1447
1447
 
1448
- // src/Dropdown.tsx
1448
+ // src/DatePicker.tsx
1449
1449
  import {
1450
- Fragment as Fragment4,
1451
1450
  useCallback as useCallback2,
1452
1451
  useEffect as useEffect6,
1453
- useId as useId8,
1452
+ useMemo as useMemo3,
1454
1453
  useRef as useRef10,
1455
1454
  useState as useState6
1456
1455
  } from "react";
1457
- import { icon as icon3, dropdownMatch, dropdownFiltering } from "@apliteni/apliteni-ui";
1458
- import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1456
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1459
1457
  var cx5 = (...a) => a.filter(Boolean).join(" ");
1458
+ var pad = (n) => String(n).padStart(2, "0");
1459
+ var DAY_MS = 864e5;
1460
+ var EN_DASH = "\u2013";
1461
+ var MONTH_RE = /^(\d{4})-(\d{2})$/;
1462
+ var DAY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
1463
+ var PHONE_MAX = 560;
1464
+ function usePhone() {
1465
+ const [phone, setPhone] = useState6(false);
1466
+ useEffect6(() => {
1467
+ const query = typeof window === "undefined" ? null : window.matchMedia?.(`(max-width: ${PHONE_MAX}px)`);
1468
+ if (!query) return;
1469
+ const read = () => setPhone(query.matches);
1470
+ read();
1471
+ query.addEventListener("change", read);
1472
+ return () => query.removeEventListener("change", read);
1473
+ }, []);
1474
+ return phone;
1475
+ }
1476
+ function monthIndexOf(period) {
1477
+ const m = MONTH_RE.exec(period);
1478
+ if (!m) return null;
1479
+ const month = +m[2];
1480
+ return month >= 1 && month <= 12 ? +m[1] * 12 + month - 1 : null;
1481
+ }
1482
+ function dayIndexOf(period) {
1483
+ const m = DAY_RE.exec(period);
1484
+ if (!m) return null;
1485
+ const [y, mo, d] = [+m[1], +m[2], +m[3]];
1486
+ const at = Date.UTC(y, mo - 1, d);
1487
+ const back = new Date(at);
1488
+ if (back.getUTCFullYear() !== y || back.getUTCMonth() !== mo - 1 || back.getUTCDate() !== d) return null;
1489
+ return Math.round(at / DAY_MS);
1490
+ }
1491
+ function toIndex(period, grain, edge = "start") {
1492
+ if (!period) return null;
1493
+ if (grain === "month") {
1494
+ const month2 = monthIndexOf(period);
1495
+ if (month2 != null) return month2;
1496
+ const day2 = dayIndexOf(period);
1497
+ return day2 == null ? null : monthOf(day2);
1498
+ }
1499
+ const day = dayIndexOf(period);
1500
+ if (day != null) return day;
1501
+ const month = monthIndexOf(period);
1502
+ if (month == null) return null;
1503
+ return edge === "start" ? firstDayOf(month) : firstDayOf(month + 1) - 1;
1504
+ }
1505
+ function fromIndex(index, grain) {
1506
+ if (grain === "month") return `${pad4(Math.floor(index / 12))}-${pad(index % 12 + 1)}`;
1507
+ const at = new Date(index * DAY_MS);
1508
+ return `${pad4(at.getUTCFullYear())}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())}`;
1509
+ }
1510
+ var pad4 = (n) => String(n).padStart(4, "0");
1511
+ var monthOf = (dayIndex) => {
1512
+ const at = new Date(dayIndex * DAY_MS);
1513
+ return at.getUTCFullYear() * 12 + at.getUTCMonth();
1514
+ };
1515
+ var firstDayOf = (monthIndex) => Math.round(Date.UTC(Math.floor(monthIndex / 12), monthIndex % 12, 1) / DAY_MS);
1516
+ var daysInMonth = (monthIndex) => firstDayOf(monthIndex + 1) - firstDayOf(monthIndex);
1517
+ function stepMonths(dayIndex, by) {
1518
+ const at = new Date(dayIndex * DAY_MS);
1519
+ const target = monthOf(dayIndex) + by;
1520
+ const day = Math.min(at.getUTCDate(), daysInMonth(target));
1521
+ return firstDayOf(target) + day - 1;
1522
+ }
1523
+ function evenMonthLabels(format) {
1524
+ const raw = Array.from({ length: 12 }, (_, m) => format.format(new Date(Date.UTC(2e3, m, 1))));
1525
+ const bare = raw.map((n) => n.replace(/\.$/, ""));
1526
+ const chars = bare.map((n) => Array.from(n));
1527
+ const cut = chars.map((c) => c.slice(0, Math.min(...chars.map((o) => o.length))).join(""));
1528
+ const even = bare.every((n) => /^\p{L}+$/u.test(n)) && new Set(cut).size === 12;
1529
+ return even ? cut : raw;
1530
+ }
1531
+ var clamp = (index, lo, hi) => Math.min(hi ?? index, Math.max(lo ?? index, index));
1532
+ function DatePicker({
1533
+ mode = "month",
1534
+ value,
1535
+ defaultValue = null,
1536
+ onChange,
1537
+ range,
1538
+ defaultRange,
1539
+ onRangeChange,
1540
+ min,
1541
+ max,
1542
+ disabledPeriods,
1543
+ presets,
1544
+ placeholder,
1545
+ ariaLabel,
1546
+ id,
1547
+ disabled = false,
1548
+ align = "start",
1549
+ locale = "en-GB",
1550
+ weekStartsOn = 1,
1551
+ today,
1552
+ sheet,
1553
+ open: openProp,
1554
+ defaultOpen = false,
1555
+ onOpenChange
1556
+ }) {
1557
+ const grain = mode === "day" || mode === "day-range" ? "day" : "month";
1558
+ const picksRange = mode === "range" || mode === "day-range";
1559
+ const phone = usePhone();
1560
+ const asSheet = sheet ?? phone;
1561
+ const root = useRef10(null);
1562
+ const trigger = useRef10(null);
1563
+ const grid = useRef10(null);
1564
+ const [selfOpen, setSelfOpen] = useState6(defaultOpen);
1565
+ const open = openProp ?? selfOpen;
1566
+ const [selfValue, setSelfValue] = useState6(defaultValue);
1567
+ const picked = value !== void 0 ? value : selfValue;
1568
+ const [selfRange, setSelfRange] = useState6(defaultRange ?? { start: null, end: null });
1569
+ const span = range !== void 0 ? range : selfRange;
1570
+ const names = useMemo3(() => ({
1571
+ month: new Intl.DateTimeFormat(locale, { month: "long", timeZone: "UTC" }),
1572
+ monthShort: new Intl.DateTimeFormat(locale, { month: "short", timeZone: "UTC" }),
1573
+ monthYear: new Intl.DateTimeFormat(locale, { month: "long", year: "numeric", timeZone: "UTC" }),
1574
+ monthYearShort: new Intl.DateTimeFormat(locale, { month: "short", year: "numeric", timeZone: "UTC" }),
1575
+ day: new Intl.DateTimeFormat(locale, { day: "numeric", month: "long", year: "numeric", timeZone: "UTC" }),
1576
+ dayShort: new Intl.DateTimeFormat(locale, { day: "numeric", month: "short", year: "numeric", timeZone: "UTC" }),
1577
+ weekday: new Intl.DateTimeFormat(locale, { weekday: "long", timeZone: "UTC" }),
1578
+ weekdayShort: new Intl.DateTimeFormat(locale, { weekday: "short", timeZone: "UTC" })
1579
+ }), [locale]);
1580
+ const monthLabels = useMemo3(() => evenMonthLabels(names.monthShort), [names]);
1581
+ const at = useCallback2((index) => new Date(
1582
+ grain === "month" ? Date.UTC(Math.floor(index / 12), index % 12, 1) : index * DAY_MS
1583
+ ), [grain]);
1584
+ const lo = toIndex(min, grain, "start");
1585
+ const hi = toIndex(max, grain, "end");
1586
+ const blocked = useMemo3(() => (disabledPeriods ?? []).flatMap((period) => {
1587
+ const from = toIndex(period, grain, "start");
1588
+ const to = toIndex(period, grain, "end");
1589
+ return from == null || to == null ? [] : [[from, to]];
1590
+ }), [disabledPeriods, grain]);
1591
+ const outOfBounds = (index) => lo != null && index < lo || hi != null && index > hi;
1592
+ const isBlocked = (index) => outOfBounds(index) || blocked.some(([from, to]) => index >= from && index <= to);
1593
+ const todayIndex = useMemo3(() => {
1594
+ const given = toIndex(today, "day");
1595
+ const now = given ?? Math.floor(Date.now() / DAY_MS);
1596
+ return grain === "month" ? monthOf(now) : now;
1597
+ }, [today, grain]);
1598
+ const anchor = toIndex(picked, grain) ?? toIndex(picksRange ? span.start ?? span.end : null, grain) ?? todayIndex;
1599
+ const [cursor, setCursor] = useState6(() => clamp(anchor, lo, hi));
1600
+ const land = useRef10(false);
1601
+ const setOpen = useCallback2((next) => {
1602
+ if (openProp === void 0) setSelfOpen(next);
1603
+ onOpenChange?.(next);
1604
+ }, [openProp, onOpenChange]);
1605
+ const close = useRef10(setOpen);
1606
+ useIsoLayoutEffect(() => {
1607
+ close.current = setOpen;
1608
+ });
1609
+ useEffect6(() => {
1610
+ if (open) setCursor(clamp(anchor, lo, hi));
1611
+ }, [open]);
1612
+ useEffect6(() => {
1613
+ if (!open || asSheet) return;
1614
+ const doc = root.current?.ownerDocument ?? document;
1615
+ const onClick = (e) => {
1616
+ if (!root.current?.contains(e.target)) close.current(false);
1617
+ };
1618
+ const onKey2 = (e) => {
1619
+ if (e.key !== "Escape") return;
1620
+ close.current(false);
1621
+ trigger.current?.focus();
1622
+ };
1623
+ doc.addEventListener("click", onClick);
1624
+ doc.addEventListener("keydown", onKey2);
1625
+ return () => {
1626
+ doc.removeEventListener("click", onClick);
1627
+ doc.removeEventListener("keydown", onKey2);
1628
+ };
1629
+ }, [open]);
1630
+ useIsoLayoutEffect(() => {
1631
+ if (!open || !land.current) return;
1632
+ land.current = false;
1633
+ grid.current?.querySelector('[data-dp-cell][tabindex="0"]')?.focus();
1634
+ });
1635
+ const columns = grain === "month" ? 3 : 7;
1636
+ const page = grain === "month" ? Math.floor(cursor / 12) : monthOf(cursor);
1637
+ const caption = grain === "month" ? String(page) : names.monthYear.format(at(firstDayOf(page)));
1638
+ const periodName = useCallback2((index) => grain === "month" ? names.monthYear.format(at(index)) : `${names.weekday.format(at(index))} ${names.day.format(at(index))}`, [grain, names, at]);
1639
+ const count = grain === "month" ? 12 : daysInMonth(page);
1640
+ const first = grain === "month" ? page * 12 : firstDayOf(page);
1641
+ const last = first + count - 1;
1642
+ const cells = useMemo3(() => Array.from({ length: count }, (_, i) => {
1643
+ const index = first + i;
1644
+ const period = fromIndex(index, grain);
1645
+ return {
1646
+ period,
1647
+ index,
1648
+ label: grain === "month" ? monthLabels[index % 12] : String(new Date(index * DAY_MS).getUTCDate()),
1649
+ name: periodName(index),
1650
+ disabled: isBlocked(index)
1651
+ };
1652
+ }), [grain, first, count, monthLabels, at, periodName, lo, hi, blocked]);
1653
+ const lead = grain === "day" ? (new Date(firstDayOf(page) * DAY_MS).getUTCDay() - weekStartsOn + 7) % 7 : 0;
1654
+ const rows = [];
1655
+ const slots = [...Array(lead).fill(null), ...cells];
1656
+ while (slots.length % columns !== 0) slots.push(null);
1657
+ for (let i = 0; i < slots.length; i += columns) rows.push(slots.slice(i, i + columns));
1658
+ const weekdays = grain === "day" ? Array.from({ length: 7 }, (_, i) => {
1659
+ const sample = at(3 + (weekStartsOn + i) % 7);
1660
+ return { short: names.weekdayShort.format(sample), long: names.weekday.format(sample) };
1661
+ }) : [];
1662
+ const startIndex = toIndex(span.start, grain);
1663
+ const endIndex = toIndex(span.end, grain);
1664
+ const edges = startIndex != null && endIndex != null ? [Math.min(startIndex, endIndex), Math.max(startIndex, endIndex)] : [startIndex ?? endIndex, startIndex ?? endIndex];
1665
+ const isEdge = (index) => index === edges[0] || index === edges[1];
1666
+ const inSpan = (index) => edges[0] != null && edges[1] != null && index > edges[0] && index < edges[1];
1667
+ const showsSpan = (cell) => inSpan(cell.index) && !cell.disabled;
1668
+ const isPicked = (index) => picksRange ? isEdge(index) : index === toIndex(picked, grain);
1669
+ function pick(cell) {
1670
+ if (cell.disabled) return;
1671
+ setCursor(cell.index);
1672
+ if (picksRange) {
1673
+ const half = startIndex != null && endIndex == null;
1674
+ const next = half ? cell.index < startIndex ? { start: cell.period, end: span.start } : { start: span.start, end: cell.period } : { start: cell.period, end: null };
1675
+ if (range === void 0) setSelfRange(next);
1676
+ onRangeChange?.(next);
1677
+ if (next.end == null) return;
1678
+ } else {
1679
+ if (value === void 0) setSelfValue(cell.period);
1680
+ onChange?.(cell.period);
1681
+ }
1682
+ dismiss();
1683
+ }
1684
+ function dismiss() {
1685
+ setOpen(false);
1686
+ if (!asSheet) trigger.current?.focus();
1687
+ }
1688
+ function allowed(preset) {
1689
+ const a = toIndex(preset.range.start, grain, "start");
1690
+ const b = toIndex(preset.range.end, grain, "end");
1691
+ if (a == null || b == null) return null;
1692
+ const [from, to] = a <= b ? [a, b] : [b, a];
1693
+ if (hi != null && from > hi || lo != null && to < lo) return null;
1694
+ const ends = [clamp(from, lo, hi), clamp(to, lo, hi)];
1695
+ if (ends.some(isBlocked)) return null;
1696
+ return { start: fromIndex(ends[0], grain), end: fromIndex(ends[1], grain) };
1697
+ }
1698
+ function applyPreset(next) {
1699
+ if (range === void 0) setSelfRange(next);
1700
+ onRangeChange?.(next);
1701
+ const start = toIndex(next.start, grain, "start");
1702
+ if (start != null) setCursor(start);
1703
+ dismiss();
1704
+ }
1705
+ function step(by) {
1706
+ setCursor((now) => clamp(now + by, lo, hi));
1707
+ }
1708
+ function stepPage(by) {
1709
+ setCursor((now) => clamp(grain === "month" ? now + 12 * by : stepMonths(now, by), lo, hi));
1710
+ }
1711
+ function onGridKeyDown(e) {
1712
+ const rowStart = cursor - (cursor - (first - lead)) % columns;
1713
+ const moves = {
1714
+ ArrowLeft: () => step(-1),
1715
+ ArrowRight: () => step(1),
1716
+ ArrowUp: () => step(-columns),
1717
+ ArrowDown: () => step(columns),
1718
+ Home: () => setCursor(clamp(Math.max(rowStart, first), lo, hi)),
1719
+ End: () => setCursor(clamp(Math.min(rowStart + columns - 1, last), lo, hi)),
1720
+ PageUp: () => stepPage(-1),
1721
+ PageDown: () => stepPage(1)
1722
+ };
1723
+ const move = moves[e.key];
1724
+ if (move) {
1725
+ e.preventDefault();
1726
+ land.current = true;
1727
+ move();
1728
+ return;
1729
+ }
1730
+ if (e.key === "Escape" && !asSheet) {
1731
+ e.preventDefault();
1732
+ e.stopPropagation();
1733
+ dismiss();
1734
+ }
1735
+ }
1736
+ const shown = useMemo3(() => {
1737
+ if (picksRange) {
1738
+ const text2 = (period) => {
1739
+ const index2 = toIndex(period, grain);
1740
+ if (index2 == null) return null;
1741
+ return grain === "month" ? names.monthYearShort.format(at(index2)) : names.dayShort.format(at(index2));
1742
+ };
1743
+ const from = text2(span.start);
1744
+ const to = text2(span.end);
1745
+ if (from && to) return `${from} ${EN_DASH} ${to}`;
1746
+ if (from) return `From ${from}`;
1747
+ if (to) return `Until ${to}`;
1748
+ return null;
1749
+ }
1750
+ const index = toIndex(picked, grain);
1751
+ if (index == null) return null;
1752
+ return grain === "month" ? names.monthYear.format(at(index)) : names.day.format(at(index));
1753
+ }, [picksRange, grain, span.start, span.end, picked, names, at]);
1754
+ const empty = placeholder ?? (picksRange ? grain === "month" ? "Select a period" : "Select dates" : grain === "month" ? "Select a month" : "Select a date");
1755
+ const name = ariaLabel || empty;
1756
+ const pageName = (which) => grain === "month" ? String(which) : names.monthYear.format(at(firstDayOf(which)));
1757
+ const stepBack = `${grain === "month" ? "Previous year" : "Previous month"}, ${pageName(page - 1)}`;
1758
+ const stepOn = `${grain === "month" ? "Next year" : "Next month"}, ${pageName(page + 1)}`;
1759
+ function state(cell) {
1760
+ const parts = [cell.name];
1761
+ if (cell.index === todayIndex) parts.push(grain === "month" ? "this month" : "today");
1762
+ if (picksRange) {
1763
+ if (cell.index === edges[0] && cell.index === edges[1]) parts.push("selected");
1764
+ else if (cell.index === edges[0]) parts.push("range start");
1765
+ else if (cell.index === edges[1]) parts.push("range end");
1766
+ else if (inSpan(cell.index)) parts.push("in range");
1767
+ } else if (isPicked(cell.index)) {
1768
+ parts.push("selected");
1769
+ }
1770
+ return parts.join(", ");
1771
+ }
1772
+ const noneBefore = lo != null && first <= lo;
1773
+ const noneAfter = hi != null && last >= hi;
1774
+ const calendar = /* @__PURE__ */ jsxs15("div", { className: cx5("ui-datepicker__body", asSheet && "is-sheet"), children: [
1775
+ picksRange && presets?.length ? /* @__PURE__ */ jsx19("div", { className: "ui-datepicker__presets", role: "group", "aria-label": "Period shortcuts", children: presets.map((preset) => {
1776
+ const within = allowed(preset);
1777
+ return /* @__PURE__ */ jsx19(
1778
+ "button",
1779
+ {
1780
+ type: "button",
1781
+ className: "ui-btn ui-btn--ghost ui-btn--xs ui-datepicker__preset",
1782
+ disabled: within == null,
1783
+ onClick: () => within && applyPreset(within),
1784
+ children: preset.label
1785
+ },
1786
+ preset.label
1787
+ );
1788
+ }) }) : null,
1789
+ /* @__PURE__ */ jsxs15("div", { className: "ui-datepicker__calendar", children: [
1790
+ /* @__PURE__ */ jsxs15("div", { className: "ui-datepicker__head", children: [
1791
+ /* @__PURE__ */ jsx19(
1792
+ "button",
1793
+ {
1794
+ type: "button",
1795
+ className: "ui-btn ui-btn--ghost ui-btn--xs ui-btn--icon ui-datepicker__step",
1796
+ "aria-label": stepBack,
1797
+ disabled: noneBefore,
1798
+ onClick: () => stepPage(-1),
1799
+ children: /* @__PURE__ */ jsx19(Icon, { name: "chevronLeft" })
1800
+ }
1801
+ ),
1802
+ /* @__PURE__ */ jsx19("span", { className: "ui-datepicker__caption", "aria-live": "polite", children: caption }),
1803
+ /* @__PURE__ */ jsx19(
1804
+ "button",
1805
+ {
1806
+ type: "button",
1807
+ className: "ui-btn ui-btn--ghost ui-btn--xs ui-btn--icon ui-datepicker__step",
1808
+ "aria-label": stepOn,
1809
+ disabled: noneAfter,
1810
+ onClick: () => stepPage(1),
1811
+ children: /* @__PURE__ */ jsx19(Icon, { name: "chevronRight" })
1812
+ }
1813
+ )
1814
+ ] }),
1815
+ /* @__PURE__ */ jsxs15(
1816
+ "div",
1817
+ {
1818
+ className: cx5("ui-datepicker__grid", grain === "day" && "is-days"),
1819
+ role: "grid",
1820
+ "aria-label": caption,
1821
+ ref: grid,
1822
+ onKeyDown: onGridKeyDown,
1823
+ children: [
1824
+ weekdays.length > 0 && /* @__PURE__ */ jsx19("div", { className: "ui-datepicker__row", role: "row", children: weekdays.map((weekday) => /* @__PURE__ */ jsx19(
1825
+ "span",
1826
+ {
1827
+ className: "ui-datepicker__weekday",
1828
+ role: "columnheader",
1829
+ "aria-label": weekday.long,
1830
+ children: weekday.short
1831
+ },
1832
+ weekday.long
1833
+ )) }),
1834
+ rows.map((cellsInRow, r) => /* @__PURE__ */ jsx19("div", { className: "ui-datepicker__row", role: "row", children: cellsInRow.map((cell, c) => cell ? /* @__PURE__ */ jsx19(
1835
+ "span",
1836
+ {
1837
+ className: "ui-datepicker__cell",
1838
+ role: "gridcell",
1839
+ "aria-selected": isPicked(cell.index),
1840
+ children: /* @__PURE__ */ jsx19(
1841
+ "button",
1842
+ {
1843
+ type: "button",
1844
+ "data-dp-cell": "",
1845
+ "data-value": cell.period,
1846
+ className: cx5(
1847
+ "ui-datepicker__opt",
1848
+ "ui-focusable",
1849
+ isPicked(cell.index) && "is-selected",
1850
+ showsSpan(cell) && "is-inside",
1851
+ cell.index === todayIndex && "is-today",
1852
+ cell.disabled && "is-disabled"
1853
+ ),
1854
+ tabIndex: cell.index === cursor ? 0 : -1,
1855
+ "aria-disabled": cell.disabled || void 0,
1856
+ "aria-label": state(cell),
1857
+ onClick: () => pick(cell),
1858
+ onFocus: () => setCursor(cell.index),
1859
+ children: /* @__PURE__ */ jsx19("span", { className: "ui-datepicker__num", children: cell.label })
1860
+ }
1861
+ )
1862
+ },
1863
+ cell.period
1864
+ ) : /* @__PURE__ */ jsx19("span", { className: "ui-datepicker__cell is-empty", role: "gridcell" }, `e${r}-${c}`)) }, `r${r}`))
1865
+ ]
1866
+ }
1867
+ )
1868
+ ] })
1869
+ ] });
1870
+ return (
1871
+ // `open` on the root whichever form the panel takes, so the trigger's
1872
+ // chevron flips for the sheet as it does for the popover. The panel rules
1873
+ // it also switches on have no panel to find while the sheet is up.
1874
+ /* @__PURE__ */ jsxs15("div", { className: cx5("ui-dropdown", "ui-datepicker", open && "open"), id, ref: root, children: [
1875
+ /* @__PURE__ */ jsxs15(
1876
+ "button",
1877
+ {
1878
+ type: "button",
1879
+ className: "ui-dropdown__trigger ui-datepicker__trigger",
1880
+ "aria-haspopup": "dialog",
1881
+ "aria-expanded": open,
1882
+ "aria-label": ariaLabel || (shown ? void 0 : name),
1883
+ disabled,
1884
+ ref: trigger,
1885
+ onClick: (e) => {
1886
+ e.stopPropagation();
1887
+ setOpen(!open);
1888
+ },
1889
+ children: [
1890
+ /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__value", children: shown ?? empty }),
1891
+ /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__chevron", "aria-hidden": "true" })
1892
+ ]
1893
+ }
1894
+ ),
1895
+ asSheet ? (
1896
+ // A sheet is the kit's drawer, not a wide popover: the scrim, the close
1897
+ // control, the focus trap, the inert page behind it and the restored
1898
+ // focus all come from <Drawer>, because changing the FORM of the panel
1899
+ // without taking the sheet's affordances left a phone reader with no
1900
+ // visible way out and a Tab that walked into the live page behind it.
1901
+ // why: guidelines/drawer.md
1902
+ /* @__PURE__ */ jsx19(Drawer, { open, side: "bottom", size: "md", title: name, onClose: () => setOpen(false), children: calendar })
1903
+ ) : /* @__PURE__ */ jsx19(
1904
+ "div",
1905
+ {
1906
+ className: cx5("ui-dropdown__panel", "ui-datepicker__panel", align === "end" && "is-end"),
1907
+ role: "dialog",
1908
+ "aria-label": name,
1909
+ inert: !open,
1910
+ onClick: (e) => e.stopPropagation(),
1911
+ children: calendar
1912
+ }
1913
+ )
1914
+ ] })
1915
+ );
1916
+ }
1917
+
1918
+ // src/Dropdown.tsx
1919
+ import {
1920
+ Fragment as Fragment4,
1921
+ useCallback as useCallback3,
1922
+ useEffect as useEffect7,
1923
+ useId as useId8,
1924
+ useRef as useRef11,
1925
+ useState as useState7
1926
+ } from "react";
1927
+ import { icon as icon3, dropdownMatch, dropdownFiltering } from "@apliteni/apliteni-ui";
1928
+ import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1929
+ var cx6 = (...a) => a.filter(Boolean).join(" ");
1460
1930
  var isRow = (it) => Boolean(it) && it !== "---" && !it.separator;
1461
- var Glyph2 = ({ name, className, hidden }) => /* @__PURE__ */ jsx19(
1931
+ var Glyph2 = ({ name, className, hidden }) => /* @__PURE__ */ jsx20(
1462
1932
  "span",
1463
1933
  {
1464
1934
  className,
@@ -1471,7 +1941,7 @@ function RowBadge({ badge }) {
1471
1941
  const given = typeof badge === "string" ? "" : badge.tone || "";
1472
1942
  let tone = given || (/^live$/i.test(String(text2)) ? "live" : "neutral");
1473
1943
  if (!given && tone === "neutral" && /^(?:off|unset|disabled|archive|archived)$/i.test(text2)) tone = "state";
1474
- return /* @__PURE__ */ jsx19("span", { className: `ui-dropdown__badge is-${tone}`, children: text2 });
1944
+ return /* @__PURE__ */ jsx20("span", { className: `ui-dropdown__badge is-${tone}`, children: text2 });
1475
1945
  }
1476
1946
  var keyOf = (it) => it.value != null ? `v:${it.value}` : `l:${it.label}`;
1477
1947
  var itemsIn = (panel) => Array.from(panel?.querySelectorAll("[data-dd-item]") ?? []).filter((el) => el.getAttribute("aria-disabled") !== "true" && !el.hidden);
@@ -1507,24 +1977,24 @@ function Dropdown({
1507
1977
  onSelect,
1508
1978
  row
1509
1979
  }) {
1510
- const [selfOpen, setSelfOpen] = useState6(defaultOpen);
1980
+ const [selfOpen, setSelfOpen] = useState7(defaultOpen);
1511
1981
  const open = openProp ?? selfOpen;
1512
- const [pick, setPick] = useState6(null);
1513
- const [query, setQuery] = useState6(() => search && search !== true ? search.query || "" : "");
1514
- const [activeKey, setActiveKey] = useState6(null);
1515
- const root = useRef10(null);
1516
- const panel = useRef10(null);
1517
- const trigger = useRef10(null);
1518
- const field = useRef10(null);
1519
- const landOn = useRef10(null);
1520
- const at = useRef10("");
1982
+ const [pick, setPick] = useState7(null);
1983
+ const [query, setQuery] = useState7(() => search && search !== true ? search.query || "" : "");
1984
+ const [activeKey, setActiveKey] = useState7(null);
1985
+ const root = useRef11(null);
1986
+ const panel = useRef11(null);
1987
+ const trigger = useRef11(null);
1988
+ const field = useRef11(null);
1989
+ const landOn = useRef11(null);
1990
+ const at = useRef11("");
1521
1991
  const auto = useId8().replace(/:/g, "");
1522
1992
  const uid = id ?? auto;
1523
- const setOpen = useCallback2((next) => {
1993
+ const setOpen = useCallback3((next) => {
1524
1994
  if (openProp === void 0) setSelfOpen(next);
1525
1995
  onOpenChange?.(next);
1526
1996
  }, [openProp, onOpenChange]);
1527
- const close = useRef10(setOpen);
1997
+ const close = useRef11(setOpen);
1528
1998
  useIsoLayoutEffect(() => {
1529
1999
  close.current = setOpen;
1530
2000
  });
@@ -1538,7 +2008,7 @@ function Dropdown({
1538
2008
  const given = rows.find((it) => it.selected);
1539
2009
  const givenKey = given ? keyOf(given) : null;
1540
2010
  const pickedKey = pick && pick.against === givenKey ? pick.key : null;
1541
- useEffect6(() => {
2011
+ useEffect7(() => {
1542
2012
  if (pick && pick.against !== givenKey) setPick(null);
1543
2013
  }, [givenKey, pick]);
1544
2014
  const picked = pickedKey != null ? rows.find((it) => keyOf(it) === pickedKey) : void 0;
@@ -1552,7 +2022,7 @@ function Dropdown({
1552
2022
  const rowIds = /* @__PURE__ */ new Map();
1553
2023
  rows.forEach((it, i) => rowIds.set(it, `${uid}-opt-${i}`));
1554
2024
  const listId = `${uid}-list`;
1555
- useEffect6(() => {
2025
+ useEffect7(() => {
1556
2026
  if (!open) return;
1557
2027
  const mine = () => close.current(false);
1558
2028
  for (const other of [...openNow]) other();
@@ -1561,7 +2031,7 @@ function Dropdown({
1561
2031
  openNow.delete(mine);
1562
2032
  };
1563
2033
  }, [open]);
1564
- useEffect6(() => {
2034
+ useEffect7(() => {
1565
2035
  if (!open) return;
1566
2036
  const doc = root.current?.ownerDocument ?? document;
1567
2037
  const onClick = (e) => {
@@ -1686,13 +2156,13 @@ function Dropdown({
1686
2156
  };
1687
2157
  function renderRow(entry, key) {
1688
2158
  if (!isRow(entry)) {
1689
- return /* @__PURE__ */ jsx19("div", { className: "ui-dropdown__sep", role: "separator", hidden: filtering || void 0 }, key);
2159
+ return /* @__PURE__ */ jsx20("div", { className: "ui-dropdown__sep", role: "separator", hidden: filtering || void 0 }, key);
1690
2160
  }
1691
2161
  const disabled = !!entry.disabled;
1692
2162
  const selected = selectedOf(entry);
1693
2163
  const asLink = !!entry.href && !disabled && !asOption;
1694
2164
  const props = {
1695
- className: cx5(
2165
+ className: cx6(
1696
2166
  "ui-dropdown__item",
1697
2167
  selected && "is-selected",
1698
2168
  disabled && "is-disabled",
@@ -1708,23 +2178,23 @@ function Dropdown({
1708
2178
  ...asLink ? { href: entry.href, ...entry.target ? { target: entry.target } : null } : null,
1709
2179
  ...sx ? { id: rowIds.get(entry), hidden: hiddenBy(entry) || void 0 } : null,
1710
2180
  onClick: (e) => choose(entry, e),
1711
- children: /* @__PURE__ */ jsxs15(Fragment5, { children: [
1712
- entry.icon && /* @__PURE__ */ jsx19(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
1713
- /* @__PURE__ */ jsxs15("span", { className: "ui-dropdown__main", children: [
1714
- /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__label", children: entry.label }),
1715
- entry.description && /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__desc", children: entry.description })
2181
+ children: /* @__PURE__ */ jsxs16(Fragment5, { children: [
2182
+ entry.icon && /* @__PURE__ */ jsx20(Glyph2, { name: entry.icon, className: "ui-dropdown__ic" }),
2183
+ /* @__PURE__ */ jsxs16("span", { className: "ui-dropdown__main", children: [
2184
+ /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__label", children: entry.label }),
2185
+ entry.description && /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__desc", children: entry.description })
1716
2186
  ] }),
1717
- entry.badge ? /* @__PURE__ */ jsx19(RowBadge, { badge: entry.badge }) : null,
1718
- asOption && /* @__PURE__ */ jsx19(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
2187
+ entry.badge ? /* @__PURE__ */ jsx20(RowBadge, { badge: entry.badge }) : null,
2188
+ asOption && /* @__PURE__ */ jsx20(Glyph2, { name: "check", className: "ui-dropdown__tick", hidden: true })
1719
2189
  ] })
1720
2190
  };
1721
- if (row) return /* @__PURE__ */ jsx19(Fragment4, { children: row(entry, props) }, key);
2191
+ if (row) return /* @__PURE__ */ jsx20(Fragment4, { children: row(entry, props) }, key);
1722
2192
  const Tag = asLink ? "a" : "div";
1723
- return /* @__PURE__ */ jsx19(Tag, { ...props }, key);
2193
+ return /* @__PURE__ */ jsx20(Tag, { ...props }, key);
1724
2194
  }
1725
2195
  const body = sections?.length ? sections.map((section, si) => {
1726
2196
  const gone = filtering && !(section.items || []).some((it) => isRow(it) && !hiddenBy(it));
1727
- return /* @__PURE__ */ jsxs15(
2197
+ return /* @__PURE__ */ jsxs16(
1728
2198
  "div",
1729
2199
  {
1730
2200
  className: "ui-dropdown__section",
@@ -1732,7 +2202,7 @@ function Dropdown({
1732
2202
  "aria-label": section.label || void 0,
1733
2203
  hidden: gone || void 0,
1734
2204
  children: [
1735
- section.label && /* @__PURE__ */ jsx19("div", { className: "ui-dropdown__group", role: "presentation", children: section.label }),
2205
+ section.label && /* @__PURE__ */ jsx20("div", { className: "ui-dropdown__group", role: "presentation", children: section.label }),
1736
2206
  (section.items || []).map((entry, i) => renderRow(entry, `s${si}-${i}`))
1737
2207
  ]
1738
2208
  },
@@ -1740,16 +2210,16 @@ function Dropdown({
1740
2210
  );
1741
2211
  }) : (items || []).map((entry, i) => renderRow(entry, `i${i}`));
1742
2212
  const cap = scroll && scroll !== true ? { maxHeight: typeof scroll === "number" ? `${scroll}px` : scroll } : void 0;
1743
- const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
1744
- /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
1745
- /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__none-hint", children: sx.hint })
2213
+ const none = sx && filtering && !visible.length ? /* @__PURE__ */ jsxs16(Fragment5, { children: [
2214
+ /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__none-title", children: sx.empty.replace("{q}", () => query.trim()) }),
2215
+ /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__none-hint", children: sx.hint })
1746
2216
  ] }) : null;
1747
- return /* @__PURE__ */ jsxs15("div", { className: cx5("ui-dropdown", open && "open"), id, ref: root, onKeyDown, children: [
1748
- /* @__PURE__ */ jsxs15(
2217
+ return /* @__PURE__ */ jsxs16("div", { className: cx6("ui-dropdown", open && "open"), id, ref: root, onKeyDown, children: [
2218
+ /* @__PURE__ */ jsxs16(
1749
2219
  "button",
1750
2220
  {
1751
2221
  type: "button",
1752
- className: cx5("ui-dropdown__trigger", triggerClass),
2222
+ className: cx6("ui-dropdown__trigger", triggerClass),
1753
2223
  "data-dropdown-trigger": "",
1754
2224
  "aria-haspopup": sx ? "dialog" : listRole,
1755
2225
  "aria-expanded": open,
@@ -1760,18 +2230,18 @@ function Dropdown({
1760
2230
  setOpen(!open);
1761
2231
  },
1762
2232
  children: [
1763
- triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs15(Fragment5, { children: [
1764
- label && /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__pre", children: label }),
1765
- /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__value", children: shown != null ? shown : placeholder })
2233
+ triggerContent != null ? triggerContent : /* @__PURE__ */ jsxs16(Fragment5, { children: [
2234
+ label && /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__pre", children: label }),
2235
+ /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__value", children: shown != null ? shown : placeholder })
1766
2236
  ] }),
1767
- chevron && /* @__PURE__ */ jsx19("span", { className: "ui-dropdown__chevron", "aria-hidden": "true" })
2237
+ chevron && /* @__PURE__ */ jsx20("span", { className: "ui-dropdown__chevron", "aria-hidden": "true" })
1768
2238
  ]
1769
2239
  }
1770
2240
  ),
1771
- /* @__PURE__ */ jsxs15(
2241
+ /* @__PURE__ */ jsxs16(
1772
2242
  "div",
1773
2243
  {
1774
- className: cx5(
2244
+ className: cx6(
1775
2245
  "ui-dropdown__panel",
1776
2246
  align === "end" && "is-end",
1777
2247
  direction === "up" && "is-up",
@@ -1788,10 +2258,10 @@ function Dropdown({
1788
2258
  onMouseMove,
1789
2259
  children: [
1790
2260
  header,
1791
- sx ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
1792
- /* @__PURE__ */ jsxs15("div", { className: "ui-dropdown__search", children: [
1793
- /* @__PURE__ */ jsx19(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
1794
- /* @__PURE__ */ jsx19(
2261
+ sx ? /* @__PURE__ */ jsxs16(Fragment5, { children: [
2262
+ /* @__PURE__ */ jsxs16("div", { className: "ui-dropdown__search", children: [
2263
+ /* @__PURE__ */ jsx20(Glyph2, { name: "search", className: "ui-dropdown__search-ic", hidden: true }),
2264
+ /* @__PURE__ */ jsx20(
1795
2265
  "input",
1796
2266
  {
1797
2267
  className: "ui-dropdown__search-input",
@@ -1815,8 +2285,8 @@ function Dropdown({
1815
2285
  }
1816
2286
  )
1817
2287
  ] }),
1818
- /* @__PURE__ */ jsx19("div", { className: "ui-dropdown__list", role: "listbox", id: listId, "aria-label": name, style: cap, children: body }),
1819
- /* @__PURE__ */ jsx19(
2288
+ /* @__PURE__ */ jsx20("div", { className: "ui-dropdown__list", role: "listbox", id: listId, "aria-label": name, style: cap, children: body }),
2289
+ /* @__PURE__ */ jsx20(
1820
2290
  "div",
1821
2291
  {
1822
2292
  className: "ui-dropdown__none",
@@ -1841,7 +2311,7 @@ function strip(o) {
1841
2311
  }
1842
2312
 
1843
2313
  // src/BackLink.tsx
1844
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2314
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
1845
2315
  var BARE = "Back";
1846
2316
  var SCRIPTED = /^javascript:/i;
1847
2317
  var LEADING = /^[\u0000-\u0020]+/;
@@ -1860,7 +2330,7 @@ function BackLink({
1860
2330
  const name = text(label).replace(SAID, "");
1861
2331
  const bare = !name || name.toLowerCase() === BARE.toLowerCase();
1862
2332
  const Tag = as ?? "a";
1863
- return /* @__PURE__ */ jsxs16(
2333
+ return /* @__PURE__ */ jsxs17(
1864
2334
  Tag,
1865
2335
  {
1866
2336
  className: ["ui-back", className].filter(Boolean).join(" "),
@@ -1868,8 +2338,8 @@ function BackLink({
1868
2338
  "aria-label": bare ? void 0 : `${BARE} to ${name}`,
1869
2339
  ...rest,
1870
2340
  children: [
1871
- /* @__PURE__ */ jsx20(Icon, { name: "chevronLeft" }),
1872
- /* @__PURE__ */ jsx20("span", { className: "ui-back__label", children: bare ? BARE : name })
2341
+ /* @__PURE__ */ jsx21(Icon, { name: "chevronLeft" }),
2342
+ /* @__PURE__ */ jsx21("span", { className: "ui-back__label", children: bare ? BARE : name })
1873
2343
  ]
1874
2344
  }
1875
2345
  );
@@ -1877,41 +2347,41 @@ function BackLink({
1877
2347
 
1878
2348
  // src/TableValues.tsx
1879
2349
  import { formatNumericValue, formatDeltaValue } from "@apliteni/apliteni-ui";
1880
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
2350
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1881
2351
  function NumericValue(props) {
1882
2352
  const value = formatNumericValue(props);
1883
- return /* @__PURE__ */ jsx21("span", { children: /* @__PURE__ */ jsxs17("span", { className: "ui-value", "aria-label": value.missing, children: [
2353
+ return /* @__PURE__ */ jsx22("span", { children: /* @__PURE__ */ jsxs18("span", { className: "ui-value", "aria-label": value.missing, children: [
1884
2354
  value.text,
1885
- value.unit && /* @__PURE__ */ jsx21("span", { className: "ui-value__unit", children: value.unit })
2355
+ value.unit && /* @__PURE__ */ jsx22("span", { className: "ui-value__unit", children: value.unit })
1886
2356
  ] }) });
1887
2357
  }
1888
2358
  function DeltaValue(props) {
1889
2359
  const value = formatDeltaValue(props);
1890
- return /* @__PURE__ */ jsx21("span", { children: /* @__PURE__ */ jsx21("span", { className: value.className, "aria-describedby": value.basisId || void 0, children: value.text }) });
2360
+ return /* @__PURE__ */ jsx22("span", { children: /* @__PURE__ */ jsx22("span", { className: value.className, "aria-describedby": value.basisId || void 0, children: value.text }) });
1891
2361
  }
1892
2362
  function RowIdentity({ symbol, name, logo, href }) {
1893
2363
  const Tag = href ? "a" : "span";
1894
- return /* @__PURE__ */ jsxs17(Tag, { className: "ui-identity", href, children: [
1895
- /* @__PURE__ */ jsxs17("span", { className: "ui-identity__logo", "aria-hidden": "true", children: [
1896
- /* @__PURE__ */ jsx21("span", { children: symbol.slice(0, 1) }),
1897
- logo && /* @__PURE__ */ jsx21("img", { src: logo, alt: "", onLoad: (e) => {
2364
+ return /* @__PURE__ */ jsxs18(Tag, { className: "ui-identity", href, children: [
2365
+ /* @__PURE__ */ jsxs18("span", { className: "ui-identity__logo", "aria-hidden": "true", children: [
2366
+ /* @__PURE__ */ jsx22("span", { children: symbol.slice(0, 1) }),
2367
+ logo && /* @__PURE__ */ jsx22("img", { src: logo, alt: "", onLoad: (e) => {
1898
2368
  e.currentTarget.hidden = false;
1899
2369
  }, onError: (e) => {
1900
2370
  e.currentTarget.hidden = true;
1901
2371
  } })
1902
2372
  ] }),
1903
- /* @__PURE__ */ jsx21("span", { className: "ui-identity__symbol", children: symbol }),
1904
- /* @__PURE__ */ jsx21("span", { className: "ui-identity__name", children: name })
2373
+ /* @__PURE__ */ jsx22("span", { className: "ui-identity__symbol", children: symbol }),
2374
+ /* @__PURE__ */ jsx22("span", { className: "ui-identity__name", children: name })
1905
2375
  ] });
1906
2376
  }
1907
2377
 
1908
2378
  // src/Segmented.tsx
1909
2379
  import { segmentedNextIndex } from "@apliteni/apliteni-ui";
1910
- import { jsx as jsx22 } from "react/jsx-runtime";
2380
+ import { jsx as jsx23 } from "react/jsx-runtime";
1911
2381
  function Segmented({ options, value, onChange, label, appearance = "pill", disabled = false }) {
1912
2382
  const enabled = options.filter((o) => !o.disabled);
1913
2383
  const tabValue = enabled.some((o) => o.value === value) ? value : enabled[0]?.value;
1914
- return /* @__PURE__ */ jsx22("div", { className: `ui-seg${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx22(
2384
+ return /* @__PURE__ */ jsx23("div", { className: `ui-seg${appearance === "underline" ? " ui-seg--underline" : ""}`, role: "toolbar", "aria-label": label, children: options.map((option) => /* @__PURE__ */ jsx23(
1915
2385
  "button",
1916
2386
  {
1917
2387
  type: "button",
@@ -1937,13 +2407,13 @@ function Segmented({ options, value, onChange, label, appearance = "pill", disab
1937
2407
  }
1938
2408
 
1939
2409
  // src/FilterBar.tsx
1940
- import { useRef as useRef11, useState as useState7 } from "react";
2410
+ import { useRef as useRef12, useState as useState8 } from "react";
1941
2411
  import { filterChipText, filterChipName, filterChipUnset } from "@apliteni/apliteni-ui";
1942
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
2412
+ import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
1943
2413
  function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters", disabled = false, busy = false, onRemove, onClear, onChange }) {
1944
- const bar = useRef11(null);
1945
- const focused = useRef11(null);
1946
- const [opened, setOpened] = useState7({});
2414
+ const bar = useRef12(null);
2415
+ const focused = useRef12(null);
2416
+ const [opened, setOpened] = useState8({});
1947
2417
  const blocked = disabled || busy;
1948
2418
  useIsoLayoutEffect(() => {
1949
2419
  const stale = Object.keys(opened).filter((id) => !filters.some((filter) => filter.id === id && filter.open === opened[id].against));
@@ -1956,7 +2426,7 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
1956
2426
  focused.current = null;
1957
2427
  (target || bar.current)?.focus();
1958
2428
  });
1959
- return /* @__PURE__ */ jsx23("div", { children: /* @__PURE__ */ jsxs18(
2429
+ return /* @__PURE__ */ jsx24("div", { children: /* @__PURE__ */ jsxs19(
1960
2430
  "fieldset",
1961
2431
  {
1962
2432
  ref: bar,
@@ -1969,8 +2439,8 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
1969
2439
  if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) focused.current = null;
1970
2440
  },
1971
2441
  children: [
1972
- /* @__PURE__ */ jsx23("legend", { className: "ui-filter-bar__legend", children: label }),
1973
- filters.map((filter, index) => /* @__PURE__ */ jsxs18(
2442
+ /* @__PURE__ */ jsx24("legend", { className: "ui-filter-bar__legend", children: label }),
2443
+ filters.map((filter, index) => /* @__PURE__ */ jsxs19(
1974
2444
  "fieldset",
1975
2445
  {
1976
2446
  className: "ui-filter-bar__chip",
@@ -1980,14 +2450,14 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
1980
2450
  focused.current = { id: filter.id, index };
1981
2451
  },
1982
2452
  children: [
1983
- /* @__PURE__ */ jsx23("legend", { className: "ui-filter-bar__legend", children: filter.label }),
1984
- /* @__PURE__ */ jsx23(
2453
+ /* @__PURE__ */ jsx24("legend", { className: "ui-filter-bar__legend", children: filter.label }),
2454
+ /* @__PURE__ */ jsx24(
1985
2455
  Dropdown,
1986
2456
  {
1987
2457
  items: filter.items,
1988
2458
  variant: "select",
1989
2459
  ariaLabel: filterChipName(filter),
1990
- triggerContent: /* @__PURE__ */ jsx23("span", { className: filterChipUnset(filter) ? "ui-dropdown__value is-placeholder" : "ui-dropdown__value", children: filterChipText(filter) }),
2460
+ triggerContent: /* @__PURE__ */ jsx24("span", { className: filterChipUnset(filter) ? "ui-dropdown__value is-placeholder" : "ui-dropdown__value", children: filterChipText(filter) }),
1991
2461
  open: !blocked && !filter.disabled && (opened[filter.id] && opened[filter.id].against === filter.open ? opened[filter.id].open : !!filter.open),
1992
2462
  onOpenChange: (open) => setOpened((previous) => ({ ...previous, [filter.id]: { open, against: filter.open } })),
1993
2463
  onSelect: (value) => {
@@ -1995,7 +2465,7 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
1995
2465
  }
1996
2466
  }
1997
2467
  ),
1998
- /* @__PURE__ */ jsx23(
2468
+ /* @__PURE__ */ jsx24(
1999
2469
  "button",
2000
2470
  {
2001
2471
  type: "button",
@@ -2012,9 +2482,9 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
2012
2482
  },
2013
2483
  filter.id
2014
2484
  )),
2015
- /* @__PURE__ */ jsx23("span", { "data-filter-clear": "", onFocus: () => {
2485
+ /* @__PURE__ */ jsx24("span", { "data-filter-clear": "", onFocus: () => {
2016
2486
  focused.current = { id: null, index: 0 };
2017
- }, children: /* @__PURE__ */ jsx23(Button, { size: "sm", variant: "ghost", disabled: !filters.length, onClick: () => {
2487
+ }, children: /* @__PURE__ */ jsx24(Button, { size: "sm", variant: "ghost", disabled: !filters.length, onClick: () => {
2018
2488
  if (!blocked) onClear();
2019
2489
  }, children: clearLabel }) })
2020
2490
  ]
@@ -2023,37 +2493,37 @@ function FilterBar({ filters, label = "Filters", clearLabel = "Clear all filters
2023
2493
  }
2024
2494
 
2025
2495
  // src/KeyValueList.tsx
2026
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
2496
+ import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
2027
2497
  function detail({ value, redacted }) {
2028
- if (redacted) return /* @__PURE__ */ jsxs19("span", { className: "ui-kv__hidden", children: [
2029
- /* @__PURE__ */ jsx24(Icon, { name: "eyeOff" }),
2498
+ if (redacted) return /* @__PURE__ */ jsxs20("span", { className: "ui-kv__hidden", children: [
2499
+ /* @__PURE__ */ jsx25(Icon, { name: "eyeOff" }),
2030
2500
  "Hidden"
2031
2501
  ] });
2032
2502
  if (value == null) return "\u2014";
2033
2503
  return typeof value === "boolean" ? String(value) : value;
2034
2504
  }
2035
2505
  function KeyValueList({ rows, columns = 1, className, ...rest }) {
2036
- return /* @__PURE__ */ jsx24("dl", { ...rest, className: ["ui-kv", columns === 2 && "ui-kv--two-columns", className].filter(Boolean).join(" "), children: rows.map((row, index) => /* @__PURE__ */ jsxs19("div", { className: "ui-drawer__row", children: [
2037
- /* @__PURE__ */ jsx24("dt", { children: row.label }),
2038
- /* @__PURE__ */ jsx24("dd", { children: detail(row) })
2506
+ return /* @__PURE__ */ jsx25("dl", { ...rest, className: ["ui-kv", columns === 2 && "ui-kv--two-columns", className].filter(Boolean).join(" "), children: rows.map((row, index) => /* @__PURE__ */ jsxs20("div", { className: "ui-drawer__row", children: [
2507
+ /* @__PURE__ */ jsx25("dt", { children: row.label }),
2508
+ /* @__PURE__ */ jsx25("dd", { children: detail(row) })
2039
2509
  ] }, index)) });
2040
2510
  }
2041
2511
  function DrawerSection({ title, headingLevel = 3, className, children, ...rest }) {
2042
2512
  const Heading = `h${headingLevel}`;
2043
- return /* @__PURE__ */ jsxs19("section", { ...rest, className: ["ui-drawer__section", className].filter(Boolean).join(" "), children: [
2044
- title != null && /* @__PURE__ */ jsx24(Heading, { className: "ui-drawer__section-title", children: title }),
2513
+ return /* @__PURE__ */ jsxs20("section", { ...rest, className: ["ui-drawer__section", className].filter(Boolean).join(" "), children: [
2514
+ title != null && /* @__PURE__ */ jsx25(Heading, { className: "ui-drawer__section-title", children: title }),
2045
2515
  children
2046
2516
  ] });
2047
2517
  }
2048
2518
 
2049
2519
  // src/Snippet.tsx
2050
- import { useEffect as useEffect7, useRef as useRef12, useState as useState8 } from "react";
2051
- import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
2520
+ import { useEffect as useEffect8, useRef as useRef13, useState as useState9 } from "react";
2521
+ import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2052
2522
  function Snippet({ label = "shell", code = "", children, copy = true, reveal = false, copyLabel = "Copy code" }) {
2053
- const [status, setStatus] = useState8("idle");
2054
- const request = useRef12(0);
2055
- const timer = useRef12(void 0);
2056
- useEffect7(() => {
2523
+ const [status, setStatus] = useState9("idle");
2524
+ const request = useRef13(0);
2525
+ const timer = useRef13(void 0);
2526
+ useEffect8(() => {
2057
2527
  setStatus("idle");
2058
2528
  return () => {
2059
2529
  request.current++;
@@ -2073,11 +2543,11 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
2073
2543
  if (current === request.current) setStatus("failed");
2074
2544
  }
2075
2545
  }
2076
- return /* @__PURE__ */ jsxs20("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
2077
- /* @__PURE__ */ jsxs20("div", { className: "ui-snippet__bar", children: [
2078
- /* @__PURE__ */ jsx25("span", { children: label }),
2079
- copy && /* @__PURE__ */ jsxs20(Fragment6, { children: [
2080
- /* @__PURE__ */ jsx25(
2546
+ return /* @__PURE__ */ jsxs21("div", { className: reveal ? "ui-snippet ui-snippet--reveal" : "ui-snippet", children: [
2547
+ /* @__PURE__ */ jsxs21("div", { className: "ui-snippet__bar", children: [
2548
+ /* @__PURE__ */ jsx26("span", { children: label }),
2549
+ copy && /* @__PURE__ */ jsxs21(Fragment6, { children: [
2550
+ /* @__PURE__ */ jsx26(
2081
2551
  "button",
2082
2552
  {
2083
2553
  type: "button",
@@ -2085,31 +2555,31 @@ function Snippet({ label = "shell", code = "", children, copy = true, reveal = f
2085
2555
  "aria-label": copyLabel,
2086
2556
  title: copyLabel,
2087
2557
  onClick: handleCopy,
2088
- children: /* @__PURE__ */ jsx25(Icon, { name: status === "idle" ? "copy" : "check" })
2558
+ children: /* @__PURE__ */ jsx26(Icon, { name: status === "idle" ? "copy" : "check" })
2089
2559
  }
2090
2560
  ),
2091
- /* @__PURE__ */ jsx25("span", { className: "ui-sr ui-snippet__status", role: "status", "aria-live": "polite", children: status === "copied" ? "Copied" : status === "failed" ? "Copy failed" : "" })
2561
+ /* @__PURE__ */ jsx26("span", { className: "ui-sr ui-snippet__status", role: "status", "aria-live": "polite", children: status === "copied" ? "Copied" : status === "failed" ? "Copy failed" : "" })
2092
2562
  ] })
2093
2563
  ] }),
2094
- /* @__PURE__ */ jsx25("pre", { children: children ?? code })
2564
+ /* @__PURE__ */ jsx26("pre", { children: children ?? code })
2095
2565
  ] });
2096
2566
  }
2097
2567
 
2098
2568
  // src/Tabs.tsx
2099
- import { useEffect as useEffect8, useId as useId9, useRef as useRef13 } from "react";
2569
+ import { useEffect as useEffect9, useId as useId9, useRef as useRef14 } from "react";
2100
2570
  import { playEntrance } from "@apliteni/apliteni-ui/motion";
2101
- import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2571
+ import { Fragment as Fragment7, jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2102
2572
  function Tabs({ items, value, onChange, label }) {
2103
2573
  const id = useId9();
2104
- const previous = useRef13(value);
2105
- const activePanel = useRef13(null);
2106
- const buttons = useRef13([]);
2107
- useEffect8(() => {
2574
+ const previous = useRef14(value);
2575
+ const activePanel = useRef14(null);
2576
+ const buttons = useRef14([]);
2577
+ useEffect9(() => {
2108
2578
  if (previous.current !== value) playEntrance(activePanel.current);
2109
2579
  previous.current = value;
2110
2580
  }, [value]);
2111
- return /* @__PURE__ */ jsxs21("div", { className: "ui-tabs", children: [
2112
- /* @__PURE__ */ jsx26("div", { className: "ui-tabs__list", role: "tablist", "aria-label": label, children: items.map((item, i) => /* @__PURE__ */ jsxs21(
2581
+ return /* @__PURE__ */ jsxs22("div", { className: "ui-tabs", children: [
2582
+ /* @__PURE__ */ jsx27("div", { className: "ui-tabs__list", role: "tablist", "aria-label": label, children: items.map((item, i) => /* @__PURE__ */ jsxs22(
2113
2583
  "button",
2114
2584
  {
2115
2585
  type: "button",
@@ -2147,7 +2617,7 @@ function Tabs({ items, value, onChange, label }) {
2147
2617
  },
2148
2618
  children: [
2149
2619
  item.label,
2150
- item.count != null && /* @__PURE__ */ jsxs21(Fragment7, { children: [
2620
+ item.count != null && /* @__PURE__ */ jsxs22(Fragment7, { children: [
2151
2621
  " ",
2152
2622
  item.count
2153
2623
  ] })
@@ -2155,7 +2625,7 @@ function Tabs({ items, value, onChange, label }) {
2155
2625
  },
2156
2626
  item.value
2157
2627
  )) }),
2158
- /* @__PURE__ */ jsx26("div", { className: "ui-tabs__panels", children: items.map((item, i) => /* @__PURE__ */ jsx26(
2628
+ /* @__PURE__ */ jsx27("div", { className: "ui-tabs__panels", children: items.map((item, i) => /* @__PURE__ */ jsx27(
2159
2629
  "div",
2160
2630
  {
2161
2631
  className: "ui-tabs__panel",
@@ -2173,14 +2643,14 @@ function Tabs({ items, value, onChange, label }) {
2173
2643
  }
2174
2644
 
2175
2645
  // src/Timeline.tsx
2176
- import { useEffect as useEffect9, useRef as useRef14 } from "react";
2646
+ import { useEffect as useEffect10, useRef as useRef15 } from "react";
2177
2647
  import { playEntrance as playEntrance2, prefersReducedMotion } from "@apliteni/apliteni-ui/motion";
2178
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2648
+ import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2179
2649
  var kindIcons = { person: "user", rule: "bolt", reversal: "refresh" };
2180
2650
  function Timeline({ events, className, ...rest }) {
2181
- const previousIds = useRef14(new Set(events.map((event) => event.id)));
2182
- const rows = useRef14(/* @__PURE__ */ new Map());
2183
- useEffect9(() => {
2651
+ const previousIds = useRef15(new Set(events.map((event) => event.id)));
2652
+ const rows = useRef15(/* @__PURE__ */ new Map());
2653
+ useEffect10(() => {
2184
2654
  if (previousIds.current.size > 0 && !prefersReducedMotion()) {
2185
2655
  for (const event of events) {
2186
2656
  if (previousIds.current.has(event.id)) continue;
@@ -2192,7 +2662,7 @@ function Timeline({ events, className, ...rest }) {
2192
2662
  }
2193
2663
  previousIds.current = new Set(events.map((event) => event.id));
2194
2664
  }, [events]);
2195
- return /* @__PURE__ */ jsx27("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__ */ jsxs22(
2665
+ return /* @__PURE__ */ jsx28("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__ */ jsxs23(
2196
2666
  "li",
2197
2667
  {
2198
2668
  className: "ui-timeline__event",
@@ -2201,20 +2671,20 @@ function Timeline({ events, className, ...rest }) {
2201
2671
  else rows.current.delete(event.id);
2202
2672
  },
2203
2673
  children: [
2204
- /* @__PURE__ */ jsx27("span", { "aria-hidden": "true", className: [
2674
+ /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: [
2205
2675
  "ui-timeline__marker",
2206
2676
  event.kind && "ui-timeline__marker--kind",
2207
2677
  event.kind === "reversal" && "ui-timeline__marker--reversal"
2208
- ].filter(Boolean).join(" "), children: event.kind && /* @__PURE__ */ jsx27(Icon, { name: kindIcons[event.kind] }) }),
2209
- /* @__PURE__ */ jsxs22("div", { className: "ui-timeline__head", children: [
2210
- /* @__PURE__ */ jsx27("span", { className: "ui-timeline__actor", children: event.actor }),
2211
- /* @__PURE__ */ jsx27("time", { dateTime: event.dateTime, children: event.timestamp }),
2212
- index === events.length - 1 && event.relativeTimestamp && /* @__PURE__ */ jsx27("span", { className: "ui-timeline__relative", children: event.relativeTimestamp })
2678
+ ].filter(Boolean).join(" "), children: event.kind && /* @__PURE__ */ jsx28(Icon, { name: kindIcons[event.kind] }) }),
2679
+ /* @__PURE__ */ jsxs23("div", { className: "ui-timeline__head", children: [
2680
+ /* @__PURE__ */ jsx28("span", { className: "ui-timeline__actor", children: event.actor }),
2681
+ /* @__PURE__ */ jsx28("time", { dateTime: event.dateTime, children: event.timestamp }),
2682
+ index === events.length - 1 && event.relativeTimestamp && /* @__PURE__ */ jsx28("span", { className: "ui-timeline__relative", children: event.relativeTimestamp })
2213
2683
  ] }),
2214
- /* @__PURE__ */ jsx27("p", { className: "ui-timeline__description", children: event.description }),
2215
- (event.meta != null || event.undo) && /* @__PURE__ */ jsxs22("div", { className: "ui-timeline__meta", children: [
2216
- event.meta != null && /* @__PURE__ */ jsx27("span", { children: event.meta }),
2217
- event.undo && /* @__PURE__ */ jsx27(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" })
2684
+ /* @__PURE__ */ jsx28("p", { className: "ui-timeline__description", children: event.description }),
2685
+ (event.meta != null || event.undo) && /* @__PURE__ */ jsxs23("div", { className: "ui-timeline__meta", children: [
2686
+ event.meta != null && /* @__PURE__ */ jsx28("span", { children: event.meta }),
2687
+ event.undo && /* @__PURE__ */ jsx28(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" })
2218
2688
  ] })
2219
2689
  ]
2220
2690
  },
@@ -2223,20 +2693,20 @@ function Timeline({ events, className, ...rest }) {
2223
2693
  }
2224
2694
 
2225
2695
  // src/Field.tsx
2226
- import { forwardRef as forwardRef6, useEffect as useEffect10, useId as useId10, useRef as useRef15, useState as useState9 } from "react";
2696
+ import { forwardRef as forwardRef6, useEffect as useEffect11, useId as useId10, useRef as useRef16, useState as useState10 } from "react";
2227
2697
  import { esc, icon as icon4 } from "@apliteni/apliteni-ui";
2228
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2698
+ import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2229
2699
  function messages(id, hint, error) {
2230
2700
  return [error && `${id}-error`, hint && `${id}-hint`].filter(Boolean).join(" ") || void 0;
2231
2701
  }
2232
2702
  function Frame({ id, label, hint, error, required, children }) {
2233
- return /* @__PURE__ */ jsxs23("div", { className: "ui-field", children: [
2234
- /* @__PURE__ */ jsxs23("label", { className: "ui-field__label", htmlFor: id, children: [
2703
+ return /* @__PURE__ */ jsxs24("div", { className: "ui-field", children: [
2704
+ /* @__PURE__ */ jsxs24("label", { className: "ui-field__label", htmlFor: id, children: [
2235
2705
  label,
2236
- required && /* @__PURE__ */ jsx28("span", { className: "ui-field__req", "aria-hidden": "true", children: "*" })
2706
+ required && /* @__PURE__ */ jsx29("span", { className: "ui-field__req", "aria-hidden": "true", children: "*" })
2237
2707
  ] }),
2238
2708
  children,
2239
- error && /* @__PURE__ */ jsx28(
2709
+ error && /* @__PURE__ */ jsx29(
2240
2710
  "div",
2241
2711
  {
2242
2712
  id: `${id}-error`,
@@ -2245,7 +2715,7 @@ function Frame({ id, label, hint, error, required, children }) {
2245
2715
  dangerouslySetInnerHTML: { __html: icon4("alert") + esc(error) }
2246
2716
  }
2247
2717
  ),
2248
- hint && /* @__PURE__ */ jsx28("div", { id: `${id}-hint`, className: "ui-field__hint", children: hint })
2718
+ hint && /* @__PURE__ */ jsx29("div", { id: `${id}-hint`, className: "ui-field__hint", children: hint })
2249
2719
  ] });
2250
2720
  }
2251
2721
  function wiring(id, hint, error) {
@@ -2254,13 +2724,13 @@ function wiring(id, hint, error) {
2254
2724
  function Field({ id: suppliedId, label, hint, error, required, children }) {
2255
2725
  const generatedId = useId10();
2256
2726
  const id = suppliedId ?? generatedId;
2257
- return /* @__PURE__ */ jsx28(Frame, { ...{ id, label, hint, error, required }, children: children({ ...wiring(id, hint, error), required }) });
2727
+ return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: children({ ...wiring(id, hint, error), required }) });
2258
2728
  }
2259
2729
  var TextField = forwardRef6(function TextField2({ label, hint, error, required, type = "text", unit, icon: glyph, className = "", ...props }, ref) {
2260
2730
  const id = useId10();
2261
2731
  const hasUnit = type === "number" && !!unit;
2262
2732
  const describedBy = [messages(id, hint, error), hasUnit ? `${id}-unit` : ""].filter(Boolean).join(" ") || void 0;
2263
- const control = /* @__PURE__ */ jsx28(
2733
+ const control = /* @__PURE__ */ jsx29(
2264
2734
  "input",
2265
2735
  {
2266
2736
  ref,
@@ -2273,19 +2743,19 @@ var TextField = forwardRef6(function TextField2({ label, hint, error, required,
2273
2743
  className: `ui-input${error ? " is-invalid" : ""} ${className}`
2274
2744
  }
2275
2745
  );
2276
- const unitSpan = hasUnit ? /* @__PURE__ */ jsx28("span", { id: `${id}-unit`, className: "ui-field-number__unit", children: unit }) : null;
2277
- return /* @__PURE__ */ jsx28(Frame, { ...{ id, label, hint, error, required }, children: glyph ? /* @__PURE__ */ jsxs23("div", { className: `ui-input-group${hasUnit ? " ui-field-number" : ""}`, children: [
2278
- /* @__PURE__ */ jsx28("span", { className: "ui-input-group__icon", dangerouslySetInnerHTML: { __html: icon4(glyph) } }),
2746
+ const unitSpan = hasUnit ? /* @__PURE__ */ jsx29("span", { id: `${id}-unit`, className: "ui-field-number__unit", children: unit }) : null;
2747
+ return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: glyph ? /* @__PURE__ */ jsxs24("div", { className: `ui-input-group${hasUnit ? " ui-field-number" : ""}`, children: [
2748
+ /* @__PURE__ */ jsx29("span", { className: "ui-input-group__icon", dangerouslySetInnerHTML: { __html: icon4(glyph) } }),
2279
2749
  control,
2280
2750
  unitSpan
2281
- ] }) : hasUnit ? /* @__PURE__ */ jsxs23("div", { className: "ui-field-number", children: [
2751
+ ] }) : hasUnit ? /* @__PURE__ */ jsxs24("div", { className: "ui-field-number", children: [
2282
2752
  control,
2283
2753
  unitSpan
2284
2754
  ] }) : control });
2285
2755
  });
2286
2756
  function TextArea({ label, hint, error, required, className = "", ...props }) {
2287
2757
  const id = useId10();
2288
- return /* @__PURE__ */ jsx28(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx28(
2758
+ return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx29(
2289
2759
  "textarea",
2290
2760
  {
2291
2761
  rows: 4,
@@ -2298,7 +2768,7 @@ function TextArea({ label, hint, error, required, className = "", ...props }) {
2298
2768
  }
2299
2769
  function SelectField({ label, hint, error, required, className = "", children, ...props }) {
2300
2770
  const id = useId10();
2301
- return /* @__PURE__ */ jsx28(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx28(
2771
+ return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsx29(
2302
2772
  "select",
2303
2773
  {
2304
2774
  ...props,
@@ -2311,10 +2781,10 @@ function SelectField({ label, hint, error, required, className = "", children, .
2311
2781
  }
2312
2782
  function FileField({ label, hint, error, required, disabled, onFileChange, className = "", ...props }) {
2313
2783
  const id = useId10();
2314
- const input = useRef15(null);
2315
- const [file, setFile] = useState9(null);
2316
- const [dragging, setDragging] = useState9(false);
2317
- useEffect10(() => {
2784
+ const input = useRef16(null);
2785
+ const [file, setFile] = useState10(null);
2786
+ const [dragging, setDragging] = useState10(false);
2787
+ useEffect11(() => {
2318
2788
  const form = input.current?.form;
2319
2789
  const reset = () => {
2320
2790
  setFile(null);
@@ -2327,7 +2797,7 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2327
2797
  setFile(next);
2328
2798
  onFileChange?.(next);
2329
2799
  };
2330
- return /* @__PURE__ */ jsx28(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsxs23(
2800
+ return /* @__PURE__ */ jsx29(Frame, { ...{ id, label, hint, error, required }, children: /* @__PURE__ */ jsxs24(
2331
2801
  "div",
2332
2802
  {
2333
2803
  className: `ui-file${dragging && !disabled ? " is-dragging" : ""}${file ? " has-file" : ""}${error ? " is-invalid" : ""}${disabled ? " is-disabled" : ""}`,
@@ -2348,12 +2818,12 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2348
2818
  update(transfer.files[0]);
2349
2819
  },
2350
2820
  children: [
2351
- /* @__PURE__ */ jsx28("span", { className: "ui-file__glyph", children: /* @__PURE__ */ jsx28(Icon, { name: "upload" }) }),
2352
- /* @__PURE__ */ jsx28("div", { "aria-live": "polite", children: file ? file.name : "Drop a file here" }),
2353
- /* @__PURE__ */ jsx28("div", { children: "or choose one from your device" }),
2354
- /* @__PURE__ */ jsxs23("span", { className: "ui-file__choose", children: [
2355
- /* @__PURE__ */ jsx28("span", { className: "ui-btn ui-btn--secondary ui-btn--sm", "aria-hidden": "true", "aria-disabled": disabled || void 0, children: file ? "Replace file" : "Choose file" }),
2356
- /* @__PURE__ */ jsx28(
2821
+ /* @__PURE__ */ jsx29("span", { className: "ui-file__glyph", children: /* @__PURE__ */ jsx29(Icon, { name: "upload" }) }),
2822
+ /* @__PURE__ */ jsx29("div", { "aria-live": "polite", children: file ? file.name : "Drop a file here" }),
2823
+ /* @__PURE__ */ jsx29("div", { children: "or choose one from your device" }),
2824
+ /* @__PURE__ */ jsxs24("span", { className: "ui-file__choose", children: [
2825
+ /* @__PURE__ */ jsx29("span", { className: "ui-btn ui-btn--secondary ui-btn--sm", "aria-hidden": "true", "aria-disabled": disabled || void 0, children: file ? "Replace file" : "Choose file" }),
2826
+ /* @__PURE__ */ jsx29(
2357
2827
  "input",
2358
2828
  {
2359
2829
  ...props,
@@ -2372,14 +2842,165 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2372
2842
  ) });
2373
2843
  }
2374
2844
 
2845
+ // src/FileDrop.tsx
2846
+ import { useRef as useRef17, useState as useState11 } from "react";
2847
+ import { Fragment as Fragment8, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
2848
+ var MARKS = {
2849
+ uploading: "clock",
2850
+ done: "circleCheck",
2851
+ error: "circleAlert"
2852
+ };
2853
+ var WORDS = {
2854
+ uploading: "Uploading",
2855
+ done: "Uploaded",
2856
+ error: "Upload failed"
2857
+ };
2858
+ var splitName = (name) => {
2859
+ const cut = name.lastIndexOf(".");
2860
+ return cut > 0 ? [name.slice(0, cut), name.slice(cut)] : [name, ""];
2861
+ };
2862
+ var carriesFiles = (event) => Array.from(event.dataTransfer.types).includes("Files");
2863
+ var cx7 = (...a) => a.filter(Boolean).join(" ");
2864
+ function FileDrop({
2865
+ label = "Upload",
2866
+ note,
2867
+ accept,
2868
+ dropLabel = "Drop to upload",
2869
+ removeLabel = "Remove file",
2870
+ retryLabel = "Retry",
2871
+ file,
2872
+ dragging,
2873
+ disabled,
2874
+ onFile,
2875
+ onRemove,
2876
+ onRetry,
2877
+ children,
2878
+ className
2879
+ }) {
2880
+ const input = useRef17(null);
2881
+ const [over, setOver] = useState11(false);
2882
+ const status = file?.status ?? "uploading";
2883
+ const word = status === "error" ? file?.error ?? WORDS.error : file?.state ?? WORDS[status];
2884
+ const [stem, ext] = splitName(file?.name ?? "");
2885
+ const hasBar = status === "uploading" && file?.progress !== void 0;
2886
+ const showWord = !hasBar;
2887
+ const showSize = Boolean(file?.size) && status !== "error";
2888
+ const showTarget = (dragging ?? over) && !disabled;
2889
+ const take = (chosen) => {
2890
+ if (chosen && !disabled) onFile?.(chosen);
2891
+ };
2892
+ return /* @__PURE__ */ jsxs25(
2893
+ "div",
2894
+ {
2895
+ className: cx7("ui-drop", disabled && "is-disabled", className),
2896
+ onDragOver: (event) => {
2897
+ if (disabled || !carriesFiles(event)) return;
2898
+ event.preventDefault();
2899
+ setOver(true);
2900
+ },
2901
+ onDragLeave: (event) => {
2902
+ if (!event.currentTarget.contains(event.relatedTarget)) setOver(false);
2903
+ },
2904
+ onDrop: (event) => {
2905
+ if (disabled || !carriesFiles(event)) return;
2906
+ event.preventDefault();
2907
+ setOver(false);
2908
+ take(event.dataTransfer.files[0]);
2909
+ },
2910
+ children: [
2911
+ children,
2912
+ /* @__PURE__ */ jsxs25("div", { className: "ui-drop__row", children: [
2913
+ file ? /* @__PURE__ */ jsxs25("div", { className: cx7("ui-drop__file", status === "error" && "ui-drop__file--failed"), children: [
2914
+ /* @__PURE__ */ jsxs25("div", { className: "ui-drop__line", children: [
2915
+ /* @__PURE__ */ jsxs25("span", { className: "ui-drop__name", title: file.name, children: [
2916
+ /* @__PURE__ */ jsx30("span", { className: "ui-drop__stem", children: stem }),
2917
+ /* @__PURE__ */ jsx30("span", { className: "ui-drop__ext", children: ext })
2918
+ ] }),
2919
+ (onRemove || status === "error" && onRetry) && /* @__PURE__ */ jsxs25("span", { className: "ui-drop__actions", children: [
2920
+ status === "error" && onRetry && /* @__PURE__ */ jsx30(Button, { size: "sm", icon: "refresh", onClick: onRetry, disabled, children: retryLabel }),
2921
+ onRemove && /* @__PURE__ */ jsx30(
2922
+ Button,
2923
+ {
2924
+ variant: "ghost",
2925
+ size: "sm",
2926
+ icon: "x",
2927
+ iconOnly: true,
2928
+ "aria-label": removeLabel,
2929
+ onClick: onRemove,
2930
+ disabled
2931
+ }
2932
+ )
2933
+ ] })
2934
+ ] }),
2935
+ (showSize || showWord) && /* @__PURE__ */ jsxs25(
2936
+ "div",
2937
+ {
2938
+ className: cx7("ui-drop__facts", status === "error" && "ui-drop__error"),
2939
+ role: status === "error" ? "alert" : void 0,
2940
+ children: [
2941
+ showSize && /* @__PURE__ */ jsx30("span", { className: "ui-drop__size", children: file.size }),
2942
+ showWord && /* @__PURE__ */ jsxs25("span", { className: "ui-drop__state", children: [
2943
+ /* @__PURE__ */ jsx30(Icon, { name: MARKS[status] }),
2944
+ /* @__PURE__ */ jsx30("span", { className: "ui-drop__word", title: word, children: word })
2945
+ ] })
2946
+ ]
2947
+ }
2948
+ ),
2949
+ hasBar && /* @__PURE__ */ jsx30(
2950
+ "span",
2951
+ {
2952
+ className: "ui-drop__bar",
2953
+ role: "progressbar",
2954
+ "aria-label": `${word} ${file.name}`,
2955
+ "aria-valuenow": file.progress,
2956
+ "aria-valuemin": 0,
2957
+ "aria-valuemax": 100,
2958
+ children: /* @__PURE__ */ jsx30("span", { style: { width: `${file.progress}%` } })
2959
+ }
2960
+ )
2961
+ ] }) : /* @__PURE__ */ jsxs25(Fragment8, { children: [
2962
+ /* @__PURE__ */ jsx30(
2963
+ Button,
2964
+ {
2965
+ size: "sm",
2966
+ icon: "upload",
2967
+ disabled,
2968
+ onClick: () => input.current?.click(),
2969
+ children: label
2970
+ }
2971
+ ),
2972
+ note && /* @__PURE__ */ jsx30("p", { className: "ui-drop__note", children: note })
2973
+ ] }),
2974
+ /* @__PURE__ */ jsx30(
2975
+ "input",
2976
+ {
2977
+ ref: input,
2978
+ type: "file",
2979
+ accept,
2980
+ disabled,
2981
+ hidden: true,
2982
+ tabIndex: -1,
2983
+ onChange: (event) => {
2984
+ take(event.currentTarget.files?.[0]);
2985
+ event.currentTarget.value = "";
2986
+ }
2987
+ }
2988
+ )
2989
+ ] }),
2990
+ showTarget && /* @__PURE__ */ jsx30("div", { className: "ui-drop__target", "aria-hidden": "true", children: dropLabel })
2991
+ ]
2992
+ }
2993
+ );
2994
+ }
2995
+
2375
2996
  // src/SearchField.tsx
2376
2997
  import { forwardRef as forwardRef7 } from "react";
2377
2998
  import { icon as icon5 } from "@apliteni/apliteni-ui";
2378
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2999
+ import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
2379
3000
  var SearchField = forwardRef7(function SearchField2({ ariaLabel, className, ...props }, ref) {
2380
- return /* @__PURE__ */ jsxs24("div", { className: "ui-input-group", children: [
2381
- /* @__PURE__ */ jsx29("span", { className: "ui-input-group__icon", dangerouslySetInnerHTML: { __html: icon5("search") } }),
2382
- /* @__PURE__ */ jsx29(
3001
+ return /* @__PURE__ */ jsxs26("div", { className: "ui-input-group", children: [
3002
+ /* @__PURE__ */ jsx31("span", { className: "ui-input-group__icon", dangerouslySetInnerHTML: { __html: icon5("search") } }),
3003
+ /* @__PURE__ */ jsx31(
2383
3004
  "input",
2384
3005
  {
2385
3006
  ref,
@@ -2393,9 +3014,9 @@ var SearchField = forwardRef7(function SearchField2({ ariaLabel, className, ...p
2393
3014
  });
2394
3015
 
2395
3016
  // src/Toast.tsx
2396
- import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect11, useLayoutEffect as useLayoutEffect4, useRef as useRef16, useState as useState10 } from "react";
3017
+ import { createContext as createContext2, useCallback as useCallback4, useContext as useContext2, useEffect as useEffect12, useLayoutEffect as useLayoutEffect4, useRef as useRef18, useState as useState12 } from "react";
2397
3018
  import { createPortal as createPortal4 } from "react-dom";
2398
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
3019
+ import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
2399
3020
  var Context = createContext2(null);
2400
3021
  var glyphs = { success: "circleCheck", danger: "circleX", warn: "circleAlert", info: "info", neutral: "bolt" };
2401
3022
  function useToast() {
@@ -2404,21 +3025,21 @@ function useToast() {
2404
3025
  return push;
2405
3026
  }
2406
3027
  function Notice({ notice, remove }) {
2407
- const root = useRef16(null);
2408
- const [leaving2, setLeaving] = useState10(false);
2409
- const dismissed = useRef16(false);
2410
- const remaining = useRef16(5e3);
2411
- const [hovered, setHovered] = useState10(false);
2412
- const [focused, setFocused] = useState10(false);
3028
+ const root = useRef18(null);
3029
+ const [leaving2, setLeaving] = useState12(false);
3030
+ const dismissed = useRef18(false);
3031
+ const remaining = useRef18(5e3);
3032
+ const [hovered, setHovered] = useState12(false);
3033
+ const [focused, setFocused] = useState12(false);
2413
3034
  const paused = hovered || focused;
2414
3035
  const tone = notice.tone ?? "success";
2415
- const dismiss = useCallback3(() => {
3036
+ const dismiss = useCallback4(() => {
2416
3037
  if (dismissed.current) return;
2417
3038
  dismissed.current = true;
2418
3039
  if (typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches) remove();
2419
3040
  else setLeaving(true);
2420
3041
  }, [remove]);
2421
- useEffect11(() => {
3042
+ useEffect12(() => {
2422
3043
  if (leaving2) {
2423
3044
  const element = root.current;
2424
3045
  const finish = (event) => {
@@ -2432,7 +3053,7 @@ function Notice({ notice, remove }) {
2432
3053
  };
2433
3054
  }
2434
3055
  }, [leaving2, remove]);
2435
- useEffect11(() => {
3056
+ useEffect12(() => {
2436
3057
  if (leaving2 || notice.action || paused) return;
2437
3058
  const started = Date.now();
2438
3059
  const timer = setTimeout(dismiss, remaining.current);
@@ -2441,7 +3062,7 @@ function Notice({ notice, remove }) {
2441
3062
  remaining.current = Math.max(0, remaining.current - (Date.now() - started));
2442
3063
  };
2443
3064
  }, [dismiss, leaving2, notice.action, paused]);
2444
- return /* @__PURE__ */ jsxs25(
3065
+ return /* @__PURE__ */ jsxs27(
2445
3066
  "div",
2446
3067
  {
2447
3068
  ref: root,
@@ -2455,12 +3076,12 @@ function Notice({ notice, remove }) {
2455
3076
  if (!event.currentTarget.contains(event.relatedTarget)) setFocused(false);
2456
3077
  },
2457
3078
  children: [
2458
- /* @__PURE__ */ jsx30("span", { className: "ui-toast__icon", children: /* @__PURE__ */ jsx30(Icon, { name: glyphs[tone] }) }),
2459
- /* @__PURE__ */ jsxs25("div", { className: "ui-toast__body", children: [
2460
- /* @__PURE__ */ jsx30("div", { className: "ui-toast__title", children: notice.title }),
2461
- notice.text && /* @__PURE__ */ jsx30("div", { className: "ui-toast__text", children: notice.text })
3079
+ /* @__PURE__ */ jsx32("span", { className: "ui-toast__icon", children: /* @__PURE__ */ jsx32(Icon, { name: glyphs[tone] }) }),
3080
+ /* @__PURE__ */ jsxs27("div", { className: "ui-toast__body", children: [
3081
+ /* @__PURE__ */ jsx32("div", { className: "ui-toast__title", children: notice.title }),
3082
+ notice.text && /* @__PURE__ */ jsx32("div", { className: "ui-toast__text", children: notice.text })
2462
3083
  ] }),
2463
- notice.action && /* @__PURE__ */ jsx30(
3084
+ notice.action && /* @__PURE__ */ jsx32(
2464
3085
  "button",
2465
3086
  {
2466
3087
  type: "button",
@@ -2475,8 +3096,8 @@ function Notice({ notice, remove }) {
2475
3096
  children: notice.action.label
2476
3097
  }
2477
3098
  ),
2478
- /* @__PURE__ */ jsx30("button", { type: "button", className: "ui-toast__close", "aria-label": "Dismiss", disabled: leaving2, onClick: dismiss, children: /* @__PURE__ */ jsx30(Icon, { name: "x" }) }),
2479
- !notice.action && /* @__PURE__ */ jsx30(
3099
+ /* @__PURE__ */ jsx32("button", { type: "button", className: "ui-toast__close", "aria-label": "Dismiss", disabled: leaving2, onClick: dismiss, children: /* @__PURE__ */ jsx32(Icon, { name: "x" }) }),
3100
+ !notice.action && /* @__PURE__ */ jsx32(
2480
3101
  "span",
2481
3102
  {
2482
3103
  className: "ui-toast__timer is-running",
@@ -2509,41 +3130,41 @@ function usePublishedReach(stack2, count) {
2509
3130
  }, [stack2, count]);
2510
3131
  }
2511
3132
  function Toast({ children }) {
2512
- const [entries, setEntries] = useState10([]);
2513
- const nextId = useRef16(0);
2514
- const stack2 = useRef16(null);
2515
- const push = useCallback3((notice) => {
3133
+ const [entries, setEntries] = useState12([]);
3134
+ const nextId = useRef18(0);
3135
+ const stack2 = useRef18(null);
3136
+ const push = useCallback4((notice) => {
2516
3137
  const id = nextId.current++;
2517
3138
  const remove = () => setEntries((current) => current.filter((entry) => entry.id !== id));
2518
3139
  setEntries((current) => [...current, { id, notice, remove }]);
2519
3140
  }, []);
2520
3141
  usePublishedReach(stack2, entries.length);
2521
- return /* @__PURE__ */ jsxs25(Context.Provider, { value: push, children: [
3142
+ return /* @__PURE__ */ jsxs27(Context.Provider, { value: push, children: [
2522
3143
  children,
2523
3144
  typeof document !== "undefined" && createPortal4(
2524
- /* @__PURE__ */ jsx30("div", { className: "ui-toast-stack rx-toast-stack", ref: stack2, children: entries.map((entry) => /* @__PURE__ */ jsx30(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
3145
+ /* @__PURE__ */ jsx32("div", { className: "ui-toast-stack rx-toast-stack", ref: stack2, children: entries.map((entry) => /* @__PURE__ */ jsx32(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
2525
3146
  document.body
2526
3147
  )
2527
3148
  ] });
2528
3149
  }
2529
3150
 
2530
3151
  // src/AppShell.tsx
2531
- import { useEffect as useEffect13, useId as useId12, useState as useState12 } from "react";
3152
+ import { useEffect as useEffect14, useId as useId12, useState as useState14 } from "react";
2532
3153
  import { applyTheme, paletteHotkey, prism, railCollapsed, themeIcon, themeName } from "@apliteni/apliteni-ui";
2533
3154
 
2534
3155
  // src/SidebarNav.tsx
2535
- import { forwardRef as forwardRef8, useEffect as useEffect12, useId as useId11, useState as useState11 } from "react";
3156
+ import { forwardRef as forwardRef8, useEffect as useEffect13, useId as useId11, useState as useState13 } from "react";
2536
3157
  import { ENTRANCE_FALLBACK_MS } from "@apliteni/apliteni-ui/motion";
2537
- import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
3158
+ import { Fragment as Fragment9, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
2538
3159
  var badgeText = (badge) => typeof badge === "object" ? badge.text : badge;
2539
3160
  function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
2540
3161
  const uid = useId11();
2541
3162
  const group = !sub && !!item.items?.length;
2542
3163
  const childActive = group && item.items.some((child) => child.id === active);
2543
- const [expanded, setExpanded] = useState11();
3164
+ const [expanded, setExpanded] = useState13();
2544
3165
  const open = expanded ?? item.defaultOpen ?? childActive;
2545
- const [entering, setEntering] = useState11(false);
2546
- useEffect12(() => {
3166
+ const [entering, setEntering] = useState13(false);
3167
+ useEffect13(() => {
2547
3168
  if (!entering) return;
2548
3169
  const timer = setTimeout(() => setEntering(false), ENTRANCE_FALLBACK_MS);
2549
3170
  return () => clearTimeout(timer);
@@ -2560,15 +3181,15 @@ function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
2560
3181
  item.disabled && "is-disabled",
2561
3182
  item.danger && "is-danger"
2562
3183
  ].filter(Boolean).join(" ");
2563
- const children = /* @__PURE__ */ jsxs26(Fragment8, { children: [
2564
- (item.leading ?? item.icon) && /* @__PURE__ */ jsx31("span", { className: "ui-nav__ic", children: item.leading ?? /* @__PURE__ */ jsx31(Icon, { name: item.icon }) }),
2565
- /* @__PURE__ */ jsx31("span", { className: "ui-nav__label", children: item.label }),
2566
- count != null && count !== "" && /* @__PURE__ */ jsx31("span", { className: `ui-nav__badge is-${typeof item.badge === "object" ? item.badge.tone ?? "neutral" : "neutral"}`, children: count }),
2567
- group && /* @__PURE__ */ jsx31("span", { className: "ui-nav__caret", "aria-hidden": "true" })
3184
+ const children = /* @__PURE__ */ jsxs28(Fragment9, { children: [
3185
+ (item.leading ?? item.icon) && /* @__PURE__ */ jsx33("span", { className: "ui-nav__ic", children: item.leading ?? /* @__PURE__ */ jsx33(Icon, { name: item.icon }) }),
3186
+ /* @__PURE__ */ jsx33("span", { className: "ui-nav__label", children: item.label }),
3187
+ count != null && count !== "" && /* @__PURE__ */ jsx33("span", { className: `ui-nav__badge is-${typeof item.badge === "object" ? item.badge.tone ?? "neutral" : "neutral"}`, children: count }),
3188
+ group && /* @__PURE__ */ jsx33("span", { className: "ui-nav__caret", "aria-hidden": "true" })
2568
3189
  ] });
2569
3190
  const common = { className, "aria-label": name, title: collapsed ? name : void 0, children };
2570
- if (group) return /* @__PURE__ */ jsxs26("li", { className: `ui-nav__group${open ? " is-open" : ""}`, children: [
2571
- /* @__PURE__ */ jsx31(
3191
+ if (group) return /* @__PURE__ */ jsxs28("li", { className: `ui-nav__group${open ? " is-open" : ""}`, children: [
3192
+ /* @__PURE__ */ jsx33(
2572
3193
  "button",
2573
3194
  {
2574
3195
  ...common,
@@ -2582,22 +3203,22 @@ function Row({ item, active, activeIs, collapsed, renderLink, sub }) {
2582
3203
  }
2583
3204
  }
2584
3205
  ),
2585
- /* @__PURE__ */ jsx31("ul", { id: uid, className: `ui-nav__sub${entering ? " is-entering" : ""}`, hidden: !open, onAnimationEnd: () => setEntering(false), children: item.items.map((child) => /* @__PURE__ */ jsx31(Row, { item: child, active, activeIs, collapsed, renderLink, sub: true }, child.id)) })
3206
+ /* @__PURE__ */ jsx33("ul", { id: uid, className: `ui-nav__sub${entering ? " is-entering" : ""}`, hidden: !open, onAnimationEnd: () => setEntering(false), children: item.items.map((child) => /* @__PURE__ */ jsx33(Row, { item: child, active, activeIs, collapsed, renderLink, sub: true }, child.id)) })
2586
3207
  ] });
2587
- if (item.disabled) return /* @__PURE__ */ jsx31("li", { children: /* @__PURE__ */ jsx31("span", { ...common, role: "link", "aria-disabled": "true" }) });
3208
+ if (item.disabled) return /* @__PURE__ */ jsx33("li", { children: /* @__PURE__ */ jsx33("span", { ...common, role: "link", "aria-disabled": "true" }) });
2588
3209
  const props = {
2589
3210
  ...common,
2590
3211
  href: item.href ?? `#${item.id}`,
2591
3212
  target: item.target,
2592
3213
  "aria-current": isActive ? activeIs === "section" ? "true" : "page" : void 0
2593
3214
  };
2594
- return /* @__PURE__ */ jsx31("li", { children: renderLink ? renderLink(item, props) : /* @__PURE__ */ jsx31("a", { ...props }) });
3215
+ return /* @__PURE__ */ jsx33("li", { children: renderLink ? renderLink(item, props) : /* @__PURE__ */ jsx33("a", { ...props }) });
2595
3216
  }
2596
3217
  function Section({ section, ...props }) {
2597
3218
  const uid = useId11();
2598
- return /* @__PURE__ */ jsxs26("div", { className: "ui-nav__section", children: [
2599
- section.label && /* @__PURE__ */ jsx31("div", { className: "ui-nav__cap", id: uid, "aria-hidden": props.collapsed || void 0, children: section.label }),
2600
- /* @__PURE__ */ jsx31("ul", { className: "ui-nav__list", "aria-labelledby": section.label ? uid : void 0, children: section.items.map((item) => /* @__PURE__ */ jsx31(Row, { item, ...props }, item.id)) })
3219
+ return /* @__PURE__ */ jsxs28("div", { className: "ui-nav__section", children: [
3220
+ section.label && /* @__PURE__ */ jsx33("div", { className: "ui-nav__cap", id: uid, "aria-hidden": props.collapsed || void 0, children: section.label }),
3221
+ /* @__PURE__ */ jsx33("ul", { className: "ui-nav__list", "aria-labelledby": section.label ? uid : void 0, children: section.items.map((item) => /* @__PURE__ */ jsx33(Row, { item, ...props }, item.id)) })
2601
3222
  ] });
2602
3223
  }
2603
3224
  var SidebarNav = forwardRef8(function SidebarNav2({
@@ -2612,8 +3233,8 @@ var SidebarNav = forwardRef8(function SidebarNav2({
2612
3233
  "aria-label": label = "Sidebar",
2613
3234
  ...rest
2614
3235
  }, ref) {
2615
- return /* @__PURE__ */ jsxs26("nav", { ...rest, ref, "aria-label": label, className: ["ui-nav", "ui-nav--side", collapsed && "is-collapsed", className].filter(Boolean).join(" "), children: [
2616
- (sections?.length ? sections : [{ items }]).map((section, index) => /* @__PURE__ */ jsx31(
3236
+ return /* @__PURE__ */ jsxs28("nav", { ...rest, ref, "aria-label": label, className: ["ui-nav", "ui-nav--side", collapsed && "is-collapsed", className].filter(Boolean).join(" "), children: [
3237
+ (sections?.length ? sections : [{ items }]).map((section, index) => /* @__PURE__ */ jsx33(
2617
3238
  Section,
2618
3239
  {
2619
3240
  section,
@@ -2624,12 +3245,12 @@ var SidebarNav = forwardRef8(function SidebarNav2({
2624
3245
  },
2625
3246
  index
2626
3247
  )),
2627
- footer && /* @__PURE__ */ jsx31("div", { className: "ui-nav__foot", children: footer })
3248
+ footer && /* @__PURE__ */ jsx33("div", { className: "ui-nav__foot", children: footer })
2628
3249
  ] });
2629
3250
  });
2630
3251
 
2631
3252
  // src/AppShell.tsx
2632
- import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
3253
+ import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
2633
3254
  var path = (value) => value.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
2634
3255
  function AppShell({
2635
3256
  sections,
@@ -2651,20 +3272,20 @@ function AppShell({
2651
3272
  renderLink
2652
3273
  }) {
2653
3274
  const uid = useId12();
2654
- const [collapsed, setCollapsed] = useState12(defaultCollapsed);
2655
- const [search, setSearch] = useState12(false);
2656
- const [more, setMore] = useState12(false);
2657
- const [theme, setTheme] = useState12("dark");
3275
+ const [collapsed, setCollapsed] = useState14(defaultCollapsed);
3276
+ const [search, setSearch] = useState14(false);
3277
+ const [more, setMore] = useState14(false);
3278
+ const [theme, setTheme] = useState14("dark");
2658
3279
  const current = path(pathname);
2659
3280
  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];
2660
- useEffect13(() => {
3281
+ useEffect14(() => {
2661
3282
  setCollapsed(railCollapsed() ?? defaultCollapsed);
2662
3283
  }, [defaultCollapsed]);
2663
- useEffect13(() => {
3284
+ useEffect14(() => {
2664
3285
  setMore(false);
2665
3286
  setSearch(false);
2666
3287
  }, [pathname]);
2667
- useEffect13(() => {
3288
+ useEffect14(() => {
2668
3289
  const root = document.documentElement;
2669
3290
  const sync2 = () => setTheme(root.getAttribute("data-theme") === "light" ? "light" : "dark");
2670
3291
  sync2();
@@ -2672,7 +3293,7 @@ function AppShell({
2672
3293
  observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
2673
3294
  return () => observer.disconnect();
2674
3295
  }, []);
2675
- useEffect13(() => {
3296
+ useEffect14(() => {
2676
3297
  const hotkey = (event) => {
2677
3298
  if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey || event.key.toLowerCase() !== "k") return;
2678
3299
  const target = event.target;
@@ -2702,15 +3323,15 @@ function AppShell({
2702
3323
  onClick: (event) => {
2703
3324
  if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) setMore(false);
2704
3325
  },
2705
- children: /* @__PURE__ */ jsxs27(Fragment9, { children: [
2706
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx32(Icon, { name: section.icon }) }),
2707
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__label", children: section.label }),
2708
- section.count != null && /* @__PURE__ */ jsx32("span", { className: "ui-nav__badge is-neutral", children: section.count })
3326
+ children: /* @__PURE__ */ jsxs29(Fragment10, { children: [
3327
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx34(Icon, { name: section.icon }) }),
3328
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__label", children: section.label }),
3329
+ section.count != null && /* @__PURE__ */ jsx34("span", { className: "ui-nav__badge is-neutral", children: section.count })
2709
3330
  ] })
2710
3331
  };
2711
- return /* @__PURE__ */ jsx32("li", { children: renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx32("a", { ...linkProps }) }, section.href);
3332
+ return /* @__PURE__ */ jsx34("li", { children: renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx34("a", { ...linkProps }) }, section.href);
2712
3333
  });
2713
- const sidebar = (items, label) => /* @__PURE__ */ jsx32(
3334
+ const sidebar = (items, label) => /* @__PURE__ */ jsx34(
2714
3335
  SidebarNav,
2715
3336
  {
2716
3337
  "aria-label": label,
@@ -2722,7 +3343,7 @@ function AppShell({
2722
3343
  const linkProps = { ...props, onClick: (event) => {
2723
3344
  if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) setMore(false);
2724
3345
  } };
2725
- return renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx32("a", { ...linkProps });
3346
+ return renderLink ? renderLink(section, linkProps) : /* @__PURE__ */ jsx34("a", { ...linkProps });
2726
3347
  }
2727
3348
  }
2728
3349
  );
@@ -2730,33 +3351,33 @@ function AppShell({
2730
3351
  const visible = sections.length > 4 ? sections.slice(0, 3) : sections;
2731
3352
  const remaining = sections.slice(visible.length);
2732
3353
  const initials = account.name.trim().split(/\s+/).map((part) => part[0]).slice(0, 2).join("");
2733
- return /* @__PURE__ */ jsxs27("div", { className: `ui-app ui-app--topbar ui-react-app${collapsed ? " is-collapsed" : ""}`, children: [
2734
- /* @__PURE__ */ jsxs27("div", { className: "ui-app__rail", children: [
2735
- /* @__PURE__ */ jsx32("div", { className: "ui-app__head", children: /* @__PURE__ */ jsxs27("a", { className: "ui-app__brand", href: brandHref, "aria-label": word, children: [
2736
- brand ?? /* @__PURE__ */ jsx32("i", { "aria-hidden": "true", className: "ui-react-app__mark", dangerouslySetInnerHTML: { __html: prism(uid, 24) } }),
2737
- /* @__PURE__ */ jsx32("span", { children: word })
3354
+ return /* @__PURE__ */ jsxs29("div", { className: `ui-app ui-app--topbar ui-react-app${collapsed ? " is-collapsed" : ""}`, children: [
3355
+ /* @__PURE__ */ jsxs29("div", { className: "ui-app__rail", children: [
3356
+ /* @__PURE__ */ jsx34("div", { className: "ui-app__head", children: /* @__PURE__ */ jsxs29("a", { className: "ui-app__brand", href: brandHref, "aria-label": word, children: [
3357
+ brand ?? /* @__PURE__ */ jsx34("i", { "aria-hidden": "true", className: "ui-react-app__mark", dangerouslySetInnerHTML: { __html: prism(uid, 24) } }),
3358
+ /* @__PURE__ */ jsx34("span", { children: word })
2738
3359
  ] }) }),
2739
3360
  sidebar(sections, "Sections"),
2740
- /* @__PURE__ */ jsx32("div", { className: "ui-app__foot", children: /* @__PURE__ */ jsx32("div", { className: "ui-app__fold-row", children: /* @__PURE__ */ jsxs27("button", { type: "button", className: "ui-nav__item ui-app__fold", "aria-expanded": !collapsed, "aria-label": foldLabel, onClick: fold, children: [
2741
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsxs27("svg", { className: "ui-icon", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2742
- /* @__PURE__ */ jsx32("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
2743
- /* @__PURE__ */ jsx32("path", { className: "ui-app__fold-seam", d: "M9 3v18" }),
2744
- /* @__PURE__ */ jsx32("path", { className: "ui-app__fold-arrow", d: "m16 15-3-3 3-3" })
3361
+ /* @__PURE__ */ jsx34("div", { className: "ui-app__foot", children: /* @__PURE__ */ jsx34("div", { className: "ui-app__fold-row", children: /* @__PURE__ */ jsxs29("button", { type: "button", className: "ui-nav__item ui-app__fold", "aria-expanded": !collapsed, "aria-label": foldLabel, onClick: fold, children: [
3362
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsxs29("svg", { className: "ui-icon", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
3363
+ /* @__PURE__ */ jsx34("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
3364
+ /* @__PURE__ */ jsx34("path", { className: "ui-app__fold-seam", d: "M9 3v18" }),
3365
+ /* @__PURE__ */ jsx34("path", { className: "ui-app__fold-arrow", d: "m16 15-3-3 3-3" })
2745
3366
  ] }) }),
2746
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__label", children: foldLabel })
3367
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__label", children: foldLabel })
2747
3368
  ] }) }) })
2748
3369
  ] }),
2749
- /* @__PURE__ */ jsxs27("div", { className: "ui-app__well", children: [
2750
- /* @__PURE__ */ jsxs27("header", { className: "ui-app__bar", children: [
2751
- /* @__PURE__ */ jsxs27("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
2752
- /* @__PURE__ */ jsx32("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx32(Icon, { name: "search" }) }),
2753
- /* @__PURE__ */ jsx32("span", { className: "ui-app__search-txt", children: "Search or run a command\u2026" }),
2754
- /* @__PURE__ */ jsx32("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
3370
+ /* @__PURE__ */ jsxs29("div", { className: "ui-app__well", children: [
3371
+ /* @__PURE__ */ jsxs29("header", { className: "ui-app__bar", children: [
3372
+ /* @__PURE__ */ jsxs29("button", { type: "button", className: "ui-app__search", "aria-haspopup": "dialog", onClick: () => setSearch(true), children: [
3373
+ /* @__PURE__ */ jsx34("span", { className: "ui-app__search-ic", children: /* @__PURE__ */ jsx34(Icon, { name: "search" }) }),
3374
+ /* @__PURE__ */ jsx34("span", { className: "ui-app__search-txt", children: "Search or run a command\u2026" }),
3375
+ /* @__PURE__ */ jsx34("kbd", { className: "ui-cmdk__key", children: paletteHotkey() })
2755
3376
  ] }),
2756
- /* @__PURE__ */ jsx32("span", { className: "ui-app__bar-gap" }),
3377
+ /* @__PURE__ */ jsx34("span", { className: "ui-app__bar-gap" }),
2757
3378
  bandControl,
2758
- /* @__PURE__ */ jsx32("button", { type: "button", className: "toggle", "aria-label": themeName(theme), title: themeName(theme), onClick: () => applyTheme(theme === "light" ? "dark" : "light"), children: /* @__PURE__ */ jsx32("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: themeIcon(theme) } }) }),
2759
- /* @__PURE__ */ jsx32("div", { className: "ui-app__user ui-app__user--bar", children: /* @__PURE__ */ jsx32(
3379
+ /* @__PURE__ */ jsx34("button", { type: "button", className: "toggle", "aria-label": themeName(theme), title: themeName(theme), onClick: () => applyTheme(theme === "light" ? "dark" : "light"), children: /* @__PURE__ */ jsx34("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: themeIcon(theme) } }) }),
3380
+ /* @__PURE__ */ jsx34("div", { className: "ui-app__user ui-app__user--bar", children: /* @__PURE__ */ jsx34(
2760
3381
  Dropdown,
2761
3382
  {
2762
3383
  variant: "menu",
@@ -2765,27 +3386,27 @@ function AppShell({
2765
3386
  ariaLabel: `Signed in as ${account.name}, ${account.email}`,
2766
3387
  triggerClass: "ui-app__user-trigger",
2767
3388
  panelClass: "ui-app__user-panel",
2768
- triggerContent: /* @__PURE__ */ jsx32("span", { className: "ui-app__av", "aria-hidden": "true", children: initials }),
2769
- header: /* @__PURE__ */ jsxs27("div", { className: "ui-dropdown__head", children: [
2770
- /* @__PURE__ */ jsx32("b", { children: account.name }),
2771
- /* @__PURE__ */ jsx32("span", { children: account.email })
3389
+ triggerContent: /* @__PURE__ */ jsx34("span", { className: "ui-app__av", "aria-hidden": "true", children: initials }),
3390
+ header: /* @__PURE__ */ jsxs29("div", { className: "ui-dropdown__head", children: [
3391
+ /* @__PURE__ */ jsx34("b", { children: account.name }),
3392
+ /* @__PURE__ */ jsx34("span", { children: account.email })
2772
3393
  ] }),
2773
3394
  items: [{ label: "Sign out", icon: "logout", danger: true }],
2774
3395
  onSelect: onSignOut
2775
3396
  }
2776
3397
  ) })
2777
3398
  ] }),
2778
- /* @__PURE__ */ jsxs27("main", { className: `ui-app__main${width === "wide" ? " ui-app__main--wide" : ""}`, children: [
2779
- back && /* @__PURE__ */ jsx32(BackLink, { ...back }),
2780
- /* @__PURE__ */ jsx32("h1", { children: title }),
2781
- lede && /* @__PURE__ */ jsx32("p", { className: "ui-app__sub", children: lede }),
2782
- actions && /* @__PURE__ */ jsx32("div", { className: "ui-react-app__actions", children: actions }),
2783
- /* @__PURE__ */ jsx32("div", { className: "ui-app__body", children })
3399
+ /* @__PURE__ */ jsxs29("main", { className: `ui-app__main${width === "wide" ? " ui-app__main--wide" : ""}`, children: [
3400
+ back && /* @__PURE__ */ jsx34(BackLink, { ...back }),
3401
+ /* @__PURE__ */ jsx34("h1", { children: title }),
3402
+ lede && /* @__PURE__ */ jsx34("p", { className: "ui-app__sub", children: lede }),
3403
+ actions && /* @__PURE__ */ jsx34("div", { className: "ui-react-app__actions", children: actions }),
3404
+ /* @__PURE__ */ jsx34("div", { className: "ui-app__body", children })
2784
3405
  ] })
2785
3406
  ] }),
2786
- /* @__PURE__ */ jsx32("nav", { className: "ui-nav ui-react-app__bottom", "aria-label": "Sections on mobile", children: /* @__PURE__ */ jsxs27("ul", { className: "ui-nav__list", children: [
3407
+ /* @__PURE__ */ jsx34("nav", { className: "ui-nav ui-react-app__bottom", "aria-label": "Sections on mobile", children: /* @__PURE__ */ jsxs29("ul", { className: "ui-nav__list", children: [
2787
3408
  links(visible),
2788
- remaining.length > 0 && /* @__PURE__ */ jsx32("li", { children: /* @__PURE__ */ jsxs27(
3409
+ remaining.length > 0 && /* @__PURE__ */ jsx34("li", { children: /* @__PURE__ */ jsxs29(
2789
3410
  "button",
2790
3411
  {
2791
3412
  type: "button",
@@ -2794,20 +3415,20 @@ function AppShell({
2794
3415
  "aria-expanded": more,
2795
3416
  onClick: () => setMore(true),
2796
3417
  children: [
2797
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx32(Icon, { name: "moreHorizontal" }) }),
2798
- /* @__PURE__ */ jsx32("span", { className: "ui-nav__label", children: "More" })
3418
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__ic", children: /* @__PURE__ */ jsx34(Icon, { name: "moreHorizontal" }) }),
3419
+ /* @__PURE__ */ jsx34("span", { className: "ui-nav__label", children: "More" })
2799
3420
  ]
2800
3421
  }
2801
3422
  ) })
2802
3423
  ] }) }),
2803
- /* @__PURE__ */ jsx32(Drawer, { open: more, onClose: () => setMore(false), title: "More sections", side: "bottom", children: sidebar(remaining, "More sections") }),
2804
- /* @__PURE__ */ jsx32(CommandPalette, { ...palette ?? { groups: [{ items: sections.map((section) => ({ id: section.href, ...section })) }] }, open: search, onClose: () => setSearch(false) })
3424
+ /* @__PURE__ */ jsx34(Drawer, { open: more, onClose: () => setMore(false), title: "More sections", side: "bottom", children: sidebar(remaining, "More sections") }),
3425
+ /* @__PURE__ */ jsx34(CommandPalette, { ...palette ?? { groups: [{ items: sections.map((section) => ({ id: section.href, ...section })) }] }, open: search, onClose: () => setSearch(false) })
2805
3426
  ] });
2806
3427
  }
2807
3428
 
2808
3429
  // src/EmptyState.tsx
2809
3430
  import { icon as kitIcon2, illo } from "@apliteni/apliteni-ui";
2810
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3431
+ import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
2811
3432
  var cases = {
2812
3433
  "first-run": { title: "Nothing needs you yet", sub: "New items will appear here when they need your attention.", icon: "check" },
2813
3434
  "no-matches": { title: "No results in this view", sub: "Try another search or clear your filters.", icon: "search" },
@@ -2819,18 +3440,18 @@ function EmptyState({ variant = "first-run", title, sub, icon: icon7, art, actio
2819
3440
  const heading = title ?? preset.title;
2820
3441
  const guidance = sub ?? preset.sub;
2821
3442
  const glyph = icon7 ?? preset.icon;
2822
- return /* @__PURE__ */ jsxs28("div", { className: "ui-empty", children: [
2823
- art ? typeof art === "string" ? /* @__PURE__ */ jsx33("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx33("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx33("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon2(glyph) } }) : null,
2824
- heading && /* @__PURE__ */ jsx33("div", { className: "ui-empty__title", children: heading }),
2825
- guidance && /* @__PURE__ */ jsx33("div", { className: "ui-empty__sub", children: guidance }),
2826
- actions && /* @__PURE__ */ jsx33("div", { className: "ui-empty__actions", children: actions })
3443
+ return /* @__PURE__ */ jsxs30("div", { className: "ui-empty", children: [
3444
+ art ? typeof art === "string" ? /* @__PURE__ */ jsx35("div", { className: "ui-empty__art", dangerouslySetInnerHTML: { __html: /<svg/.test(art) ? art : illo(art) } }) : /* @__PURE__ */ jsx35("div", { className: "ui-empty__art", "aria-hidden": "true", children: art }) : glyph ? /* @__PURE__ */ jsx35("div", { className: "ui-empty__icon", dangerouslySetInnerHTML: { __html: kitIcon2(glyph) } }) : null,
3445
+ heading && /* @__PURE__ */ jsx35("div", { className: "ui-empty__title", children: heading }),
3446
+ guidance && /* @__PURE__ */ jsx35("div", { className: "ui-empty__sub", children: guidance }),
3447
+ actions && /* @__PURE__ */ jsx35("div", { className: "ui-empty__actions", children: actions })
2827
3448
  ] });
2828
3449
  }
2829
3450
 
2830
3451
  // src/ThemeToggle.tsx
2831
3452
  import { useSyncExternalStore } from "react";
2832
3453
  import { icon as icon6 } from "@apliteni/apliteni-ui";
2833
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
3454
+ import { jsx as jsx36, jsxs as jsxs31 } from "react/jsx-runtime";
2834
3455
  var STORAGE_KEY = "apliteni-strategy-theme";
2835
3456
  var CHOICE_EVENT = "apliteni-theme-choice";
2836
3457
  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')})()`;
@@ -2888,10 +3509,10 @@ function ThemeToggle({ labelled = false }) {
2888
3509
  }
2889
3510
  window.dispatchEvent(new Event(CHOICE_EVENT));
2890
3511
  };
2891
- const button = /* @__PURE__ */ jsx34("button", { type: "button", className: "toggle", "aria-label": name, title: name, onClick: toggle, children: /* @__PURE__ */ jsx34("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon6(theme === "auto" ? "monitor" : theme === "light" ? "sun" : "moon") } }) });
2892
- return labelled ? /* @__PURE__ */ jsxs29("span", { className: "ui-theme-toggle", children: [
3512
+ const button = /* @__PURE__ */ jsx36("button", { type: "button", className: "toggle", "aria-label": name, title: name, onClick: toggle, children: /* @__PURE__ */ jsx36("span", { className: "ic", "aria-hidden": "true", dangerouslySetInnerHTML: { __html: icon6(theme === "auto" ? "monitor" : theme === "light" ? "sun" : "moon") } }) });
3513
+ return labelled ? /* @__PURE__ */ jsxs31("span", { className: "ui-theme-toggle", children: [
2893
3514
  button,
2894
- /* @__PURE__ */ jsxs29("span", { children: [
3515
+ /* @__PURE__ */ jsxs31("span", { children: [
2895
3516
  label,
2896
3517
  " theme"
2897
3518
  ] })
@@ -2899,11 +3520,11 @@ function ThemeToggle({ labelled = false }) {
2899
3520
  }
2900
3521
 
2901
3522
  // src/Success.tsx
2902
- import { forwardRef as forwardRef9, useEffect as useEffect14, useRef as useRef17, useState as useState13 } from "react";
2903
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
3523
+ import { forwardRef as forwardRef9, useEffect as useEffect15, useRef as useRef19, useState as useState15 } from "react";
3524
+ import { jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
2904
3525
  var SuccessCheck = forwardRef9(function SuccessCheck2({ variant = "line", className, ...rest }, ref) {
2905
3526
  const circled = variant === "circled";
2906
- return /* @__PURE__ */ jsxs30(
3527
+ return /* @__PURE__ */ jsxs32(
2907
3528
  "svg",
2908
3529
  {
2909
3530
  ...rest,
@@ -2915,18 +3536,18 @@ var SuccessCheck = forwardRef9(function SuccessCheck2({ variant = "line", classN
2915
3536
  "aria-hidden": "true",
2916
3537
  focusable: "false",
2917
3538
  children: [
2918
- circled && /* @__PURE__ */ jsx35("path", { className: "ui-sx__circle", d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2919
- /* @__PURE__ */ jsx35("path", { className: "ui-sx__tick", d: circled ? "M22 4L12 14.01l-3-3" : "M20 6L9 17l-5-5" })
3539
+ circled && /* @__PURE__ */ jsx37("path", { className: "ui-sx__circle", d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
3540
+ /* @__PURE__ */ jsx37("path", { className: "ui-sx__tick", d: circled ? "M22 4L12 14.01l-3-3" : "M20 6L9 17l-5-5" })
2920
3541
  ]
2921
3542
  }
2922
3543
  );
2923
3544
  });
2924
3545
  var SuccessPanel = forwardRef9(function SuccessPanel2({ title = "Done", sub, check = "line", className, ...rest }, ref) {
2925
3546
  const circled = check === "circled";
2926
- return /* @__PURE__ */ jsxs30("div", { ...rest, ref, className: ["ui-success", className].filter(Boolean).join(" "), children: [
2927
- /* @__PURE__ */ jsx35("div", { className: ["ui-success__check", circled && "ui-success__check--circled"].filter(Boolean).join(" "), children: /* @__PURE__ */ jsx35(SuccessCheck, { variant: circled ? "circled" : "line" }) }),
2928
- /* @__PURE__ */ jsx35("div", { className: "ui-success__title", children: title }),
2929
- sub && /* @__PURE__ */ jsx35("div", { className: "ui-success__sub", children: sub })
3547
+ return /* @__PURE__ */ jsxs32("div", { ...rest, ref, className: ["ui-success", className].filter(Boolean).join(" "), children: [
3548
+ /* @__PURE__ */ jsx37("div", { className: ["ui-success__check", circled && "ui-success__check--circled"].filter(Boolean).join(" "), children: /* @__PURE__ */ jsx37(SuccessCheck, { variant: circled ? "circled" : "line" }) }),
3549
+ /* @__PURE__ */ jsx37("div", { className: "ui-success__title", children: title }),
3550
+ sub && /* @__PURE__ */ jsx37("div", { className: "ui-success__sub", children: sub })
2930
3551
  ] });
2931
3552
  });
2932
3553
  var pieces = [
@@ -2946,12 +3567,12 @@ var pieces = [
2946
3567
  [80, 0.36, -20, "c", 1.05]
2947
3568
  ];
2948
3569
  function Countdown({ seconds, label = "Redirecting", onDone }) {
2949
- const [remaining, setRemaining] = useState13(seconds);
2950
- const callback = useRef17(onDone);
2951
- useEffect14(() => {
3570
+ const [remaining, setRemaining] = useState15(seconds);
3571
+ const callback = useRef19(onDone);
3572
+ useEffect15(() => {
2952
3573
  callback.current = onDone;
2953
3574
  }, [onDone]);
2954
- useEffect14(() => {
3575
+ useEffect15(() => {
2955
3576
  let count = seconds;
2956
3577
  const timer = setInterval(() => {
2957
3578
  count -= 1;
@@ -2963,12 +3584,12 @@ function Countdown({ seconds, label = "Redirecting", onDone }) {
2963
3584
  }, 1e3);
2964
3585
  return () => clearInterval(timer);
2965
3586
  }, [seconds]);
2966
- return /* @__PURE__ */ jsxs30("div", { className: "ui-sx__count", "data-sx-count": "", style: { "--sx-secs": `${seconds}s` }, children: [
2967
- /* @__PURE__ */ jsx35("span", { className: "ui-sx__count-ring", "aria-hidden": "true" }),
2968
- /* @__PURE__ */ jsxs30("span", { className: "ui-sx__count-text", children: [
3587
+ return /* @__PURE__ */ jsxs32("div", { className: "ui-sx__count", "data-sx-count": "", style: { "--sx-secs": `${seconds}s` }, children: [
3588
+ /* @__PURE__ */ jsx37("span", { className: "ui-sx__count-ring", "aria-hidden": "true" }),
3589
+ /* @__PURE__ */ jsxs32("span", { className: "ui-sx__count-text", children: [
2969
3590
  label,
2970
3591
  " in ",
2971
- /* @__PURE__ */ jsx35("b", { "data-sx-num": "", children: remaining }),
3592
+ /* @__PURE__ */ jsx37("b", { "data-sx-num": "", children: remaining }),
2972
3593
  "s"
2973
3594
  ] })
2974
3595
  ] });
@@ -2995,7 +3616,7 @@ var Success = forwardRef9(function Success2({
2995
3616
  const seconds = countdown?.seconds;
2996
3617
  const duration = seconds != null && Number.isFinite(seconds) && seconds >= 1 ? Math.floor(seconds) : 5;
2997
3618
  const mark = check === "circled" ? "circled" : "line";
2998
- return /* @__PURE__ */ jsxs30(
3619
+ return /* @__PURE__ */ jsxs32(
2999
3620
  "div",
3000
3621
  {
3001
3622
  role: "status",
@@ -3004,16 +3625,16 @@ var Success = forwardRef9(function Success2({
3004
3625
  ref,
3005
3626
  className: ["ui-sx", `ui-sx--${layout}`, `ui-sx--check-${mark}`, confetti && "ui-sx--confetti", className].filter(Boolean).join(" "),
3006
3627
  children: [
3007
- confetti && /* @__PURE__ */ jsx35("div", { className: "ui-sx__confetti", "aria-hidden": "true", children: pieces.map(
3008
- ([x, d, r, t, s], index) => /* @__PURE__ */ jsx35("i", { className: `ui-sx__piece ui-sx__piece--${t}`, style: { left: `${x}%`, "--sx-d": `${d}s`, "--sx-r": `${r}deg`, "--sx-s": s } }, index)
3628
+ confetti && /* @__PURE__ */ jsx37("div", { className: "ui-sx__confetti", "aria-hidden": "true", children: pieces.map(
3629
+ ([x, d, r, t, s], index) => /* @__PURE__ */ jsx37("i", { className: `ui-sx__piece ui-sx__piece--${t}`, style: { left: `${x}%`, "--sx-d": `${d}s`, "--sx-r": `${r}deg`, "--sx-s": s } }, index)
3009
3630
  ) }),
3010
- /* @__PURE__ */ jsxs30("div", { className: "ui-sx__inner", children: [
3011
- /* @__PURE__ */ jsx35("div", { className: "ui-sx__visual", children: /* @__PURE__ */ jsx35(SuccessCheck, { variant: mark }) }),
3012
- /* @__PURE__ */ jsxs30("div", { className: "ui-sx__content", children: [
3013
- /* @__PURE__ */ jsx35(Heading, { className: "ui-sx__title", children: title }),
3014
- body && /* @__PURE__ */ jsx35("p", { className: "ui-sx__body", children: body }),
3015
- hasActions && /* @__PURE__ */ jsx35("div", { className: "ui-sx__actions", children: actions }),
3016
- countdown && /* @__PURE__ */ jsx35(Countdown, { seconds: duration, label: countdown.label, onDone: onCountdownEnd }, duration)
3631
+ /* @__PURE__ */ jsxs32("div", { className: "ui-sx__inner", children: [
3632
+ /* @__PURE__ */ jsx37("div", { className: "ui-sx__visual", children: /* @__PURE__ */ jsx37(SuccessCheck, { variant: mark }) }),
3633
+ /* @__PURE__ */ jsxs32("div", { className: "ui-sx__content", children: [
3634
+ /* @__PURE__ */ jsx37(Heading, { className: "ui-sx__title", children: title }),
3635
+ body && /* @__PURE__ */ jsx37("p", { className: "ui-sx__body", children: body }),
3636
+ hasActions && /* @__PURE__ */ jsx37("div", { className: "ui-sx__actions", children: actions }),
3637
+ countdown && /* @__PURE__ */ jsx37(Countdown, { seconds: duration, label: countdown.label, onDone: onCountdownEnd }, duration)
3017
3638
  ] })
3018
3639
  ] })
3019
3640
  ]
@@ -3037,6 +3658,7 @@ export {
3037
3658
  Confirm,
3038
3659
  DEFAULT_PAGE_SIZE3 as DEFAULT_PAGE_SIZE,
3039
3660
  DataTable,
3661
+ DatePicker,
3040
3662
  DeltaValue,
3041
3663
  Denied,
3042
3664
  Drawer,
@@ -3044,6 +3666,7 @@ export {
3044
3666
  Dropdown,
3045
3667
  EmptyState,
3046
3668
  Field,
3669
+ FileDrop,
3047
3670
  FileField,
3048
3671
  FilterBar,
3049
3672
  Icon,