altitude-design 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -230,6 +230,63 @@ function deriveAccent(accent, surfaces) {
230
230
  "--accent-soft": rgbToHex(mix(hexToRgb(ground), a, dark ? 0.2 : 0.13))
231
231
  };
232
232
  }
233
+ var SURFACES = ["surface-trench", "surface-well", "surface-ground", "surface-raised", "surface-lifted", "surface-floating", "surface-overlay", "surface-modal"];
234
+ var PAIRS = [];
235
+ for (const t of ["ink", "ink-muted", "accent-ink", "positive", "caution", "critical"]) for (const g of SURFACES) PAIRS.push([t, g, 4.5]);
236
+ for (const [t, g] of [
237
+ ["ink", "accent-soft"],
238
+ ["accent-ink", "accent-soft"],
239
+ ["positive", "positive-soft"],
240
+ ["caution", "caution-soft"],
241
+ ["critical", "critical-soft"],
242
+ ["ink", "critical-soft"],
243
+ ["ink", "positive-soft"],
244
+ ["ink", "caution-soft"],
245
+ ["ink-muted", "accent-soft"],
246
+ ["on-accent", "accent"],
247
+ ["on-critical", "critical"]
248
+ ]) PAIRS.push([t, g, 4.5]);
249
+ for (const g of ["surface-ground", "surface-well", "surface-raised", "surface-trench"]) PAIRS.push(["line-control", g, 3], ["accent", g, 3]);
250
+ for (const p of ["presence-1", "presence-2", "presence-3"]) {
251
+ PAIRS.push(["on-presence", p, 4.5]);
252
+ for (const g of SURFACES) PAIRS.push([p, g, 3]);
253
+ }
254
+ var isHex = (v) => /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v);
255
+ function checkScheme(colors) {
256
+ const cs = typeof Element !== "undefined" && colors instanceof Element ? getComputedStyle(colors) : null;
257
+ const get = (n) => (cs ? cs.getPropertyValue("--" + n) : colors[n] ?? "").trim();
258
+ const out = [];
259
+ const seen = /* @__PURE__ */ new Set();
260
+ const ok = (n) => {
261
+ const v = get(n);
262
+ if (isHex(v)) return true;
263
+ if (!seen.has(n)) {
264
+ seen.add(n);
265
+ out.push(v ? `${n} is ${v}: use a 3- or 6-digit hex colour so it can be checked.` : `${n} is missing.`);
266
+ }
267
+ return false;
268
+ };
269
+ const L = (n) => lum(hexToRgb(get(n)));
270
+ for (let i = 1; i < SURFACES.length; i++) {
271
+ const lo = SURFACES[i - 1], hi = SURFACES[i];
272
+ if (!ok(lo) || !ok(hi)) continue;
273
+ if (i <= 3 ? L(hi) <= L(lo) : L(hi) < L(lo)) out.push(`${hi} (${get(hi)}) must be ${i <= 3 ? "lighter than" : "at least as light as"} ${lo} (${get(lo)}).`);
274
+ }
275
+ for (const [t, g, min] of PAIRS) {
276
+ if (!ok(t) || !ok(g)) continue;
277
+ const r = contrast(get(t), get(g));
278
+ if (r < min) out.push(`${t} on ${g} is ${r.toFixed(2)}:1; it needs ${min}:1.`);
279
+ }
280
+ return out;
281
+ }
282
+ var SHADOW_OR_LINE = /^(trench|well|elev-\d|lip-top|lip-bottom|line)$/;
283
+ function schemeCss(sel, tokens) {
284
+ const decl = (keep) => Object.entries(tokens).filter(([k, v]) => keep(k) && typeof v === "string" && /^[\w-]+$/.test(k) && !/[;{}<>]/.test(v)).map(([k, v]) => `--${k}: ${v};`).join(" ");
285
+ const plain = decl((k) => !SHADOW_OR_LINE.test(k)), soft = decl((k) => SHADOW_OR_LINE.test(k));
286
+ let css = plain ? `${sel} { ${plain} }` : "";
287
+ if (soft) css += `@media not (prefers-contrast: more) { ${sel}:not([data-contrast="more"], [data-contrast="more"] *) { ${soft} } }`;
288
+ return css;
289
+ }
233
290
  var AltitudeContext = React.createContext(null);
234
291
  var useAltitude = () => React.useContext(AltitudeContext);
235
292
  function AltitudeProvider({ scheme, accent, motion = "system", contrast: contrast2 = "system", recede = true, approach = true, className, style, children, ...rest }) {
@@ -237,6 +294,18 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
237
294
  const [host, setHost] = React.useState(null);
238
295
  const [layers, setLayers] = React.useState(0);
239
296
  const [accentVars, setAccentVars] = React.useState(null);
297
+ const custom = scheme && typeof scheme === "object" ? scheme : null;
298
+ const schemeKey = custom ? JSON.stringify(custom) : scheme;
299
+ const scope = React.useId();
300
+ const schemeSel = `.alt-root[data-scheme-id="${scope}"]`;
301
+ const warned = React.useRef("");
302
+ React.useEffect(() => {
303
+ if (!custom || !rootRef.current || warned.current === schemeKey) return;
304
+ warned.current = schemeKey;
305
+ const issues = checkScheme(rootRef.current);
306
+ if (issues.length) console.warn(`Altitude: the scheme "${custom.name}" breaks ${issues.length} of the scheme invariants (see Theming.md):
307
+ ` + issues.join("\n"));
308
+ }, [schemeKey]);
240
309
  useIsoLayoutEffect(() => {
241
310
  if (!accent || !rootRef.current) {
242
311
  setAccentVars(null);
@@ -252,7 +321,7 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
252
321
  const mo = new MutationObserver(compute);
253
322
  mo.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
254
323
  return () => mo.disconnect();
255
- }, [accent, scheme]);
324
+ }, [accent, schemeKey]);
256
325
  const api = React.useMemo(() => ({
257
326
  host,
258
327
  pushLayer: () => {
@@ -265,13 +334,16 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
265
334
  {
266
335
  ref: rootRef,
267
336
  className: cx("alt-root", className),
268
- "data-theme": scheme,
337
+ "data-theme": custom ? custom.base ?? "daylight" : scheme,
338
+ "data-scheme": custom?.name,
339
+ "data-scheme-id": custom ? scope : void 0,
269
340
  "data-motion": motion === "system" ? void 0 : motion,
270
341
  "data-contrast": contrast2 === "more" ? "more" : void 0,
271
342
  "data-approach-off": approach ? void 0 : "",
272
343
  style: { ...accentVars, ...style },
273
344
  ...rest
274
345
  },
346
+ custom && /* @__PURE__ */ React.createElement("style", null, schemeCss(schemeSel, custom.tokens)),
275
347
  /* @__PURE__ */ React.createElement("div", { className: "alt-stage", "data-receded": recede && layers > 0 ? "" : void 0 }, children),
276
348
  /* @__PURE__ */ React.createElement("div", { className: "alt-layers", ref: setHost })
277
349
  ));
@@ -1948,6 +2020,8 @@ function CommandPalette({
1948
2020
  filter,
1949
2021
  empty,
1950
2022
  shortcut = "k",
2023
+ query: queryProp,
2024
+ defaultQuery = "",
1951
2025
  onQueryChange,
1952
2026
  closeOnSelect = true,
1953
2027
  hints = true,
@@ -1955,7 +2029,8 @@ function CommandPalette({
1955
2029
  ...rest
1956
2030
  }) {
1957
2031
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1958
- const [query, setQuery] = React7.useState("");
2032
+ const [innerQuery, setInnerQuery] = React7.useState(defaultQuery);
2033
+ const query = queryProp ?? innerQuery;
1959
2034
  const [active, setActive] = React7.useState(0);
1960
2035
  const [onset, setOnset] = React7.useState(true);
1961
2036
  const [said, setSaid] = React7.useState("");
@@ -1966,6 +2041,9 @@ function CommandPalette({
1966
2041
  const rowEls = React7.useRef(/* @__PURE__ */ new Map());
1967
2042
  const prevTops = React7.useRef(null);
1968
2043
  const byKeyboard = React7.useRef(false);
2044
+ const caretPlaced = React7.useRef(false);
2045
+ const seed = React7.useRef(defaultQuery);
2046
+ seed.current = defaultQuery;
1969
2047
  const [panelEl, setPanelEl] = React7.useState(null);
1970
2048
  const panelRef = React7.useCallback((el) => {
1971
2049
  panel.current = el;
@@ -1992,11 +2070,15 @@ function CommandPalette({
1992
2070
  }, [shortcut, isOpen, set]);
1993
2071
  React7.useEffect(() => {
1994
2072
  if (isOpen) {
1995
- setQuery("");
2073
+ setInnerQuery(seed.current);
1996
2074
  setActive(0);
1997
2075
  setOnset(true);
2076
+ caretPlaced.current = false;
1998
2077
  }
1999
2078
  }, [isOpen]);
2079
+ React7.useEffect(() => {
2080
+ setActive(0);
2081
+ }, [query]);
2000
2082
  const q = query.trim();
2001
2083
  const score = filter ?? itemScore;
2002
2084
  const view = items.map((g, gi) => {
@@ -2114,11 +2196,17 @@ function CommandPalette({
2114
2196
  leading: /* @__PURE__ */ React7.createElement(SearchIcon, null),
2115
2197
  trailing: /* @__PURE__ */ React7.createElement("span", { "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement(Kbd, null, "esc")),
2116
2198
  onChange: (e) => {
2117
- setQuery(e.target.value);
2199
+ setInnerQuery(e.target.value);
2118
2200
  setActive(0);
2119
2201
  setOnset(false);
2120
2202
  onQueryChange?.(e.target.value);
2121
2203
  },
2204
+ onFocus: (e) => {
2205
+ if (caretPlaced.current) return;
2206
+ caretPlaced.current = true;
2207
+ const n2 = e.currentTarget.value.length;
2208
+ e.currentTarget.setSelectionRange(n2, n2);
2209
+ },
2122
2210
  onKeyDown: onInputKeyDown
2123
2211
  }
2124
2212
  )), /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-viewport", ref: viewport }, /* @__PURE__ */ React7.createElement("div", { ref: sizer }, /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-list", ref: list, role: "listbox", id: `${id}-list`, "aria-label": "Results" }, /* @__PURE__ */ React7.createElement(
@@ -2690,8 +2778,53 @@ function Stepper({ steps, current, onStepChange, orientation = "horizontal", cla
2690
2778
  })), /* @__PURE__ */ React9.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said));
2691
2779
  }
2692
2780
 
2693
- // project/components/src/collections.tsx
2781
+ // project/components/src/empty.tsx
2694
2782
  import * as React10 from "react";
2783
+ function EmptyState({
2784
+ icon: icon2,
2785
+ title,
2786
+ description,
2787
+ action,
2788
+ secondary,
2789
+ size = "md",
2790
+ headingLevel = 3,
2791
+ announce,
2792
+ className,
2793
+ children,
2794
+ ...rest
2795
+ }) {
2796
+ const id = React10.useId();
2797
+ const H = `h${headingLevel}`;
2798
+ const words = typeof announce === "string" ? announce : announce && typeof title === "string" ? title : "";
2799
+ const [said, setSaid] = React10.useState("");
2800
+ React10.useEffect(() => {
2801
+ if (!words) {
2802
+ setSaid("");
2803
+ return;
2804
+ }
2805
+ const t = setTimeout(() => setSaid(words), 100);
2806
+ return () => clearTimeout(t);
2807
+ }, [words]);
2808
+ return /* @__PURE__ */ React10.createElement(
2809
+ "section",
2810
+ {
2811
+ className: cx("alt-empty", className),
2812
+ "data-size": size,
2813
+ "aria-labelledby": `${id}-t`,
2814
+ "aria-describedby": description ? `${id}-d` : void 0,
2815
+ ...rest
2816
+ },
2817
+ icon2 && /* @__PURE__ */ React10.createElement("span", { className: "alt-empty-icon", "aria-hidden": "true" }, icon2),
2818
+ /* @__PURE__ */ React10.createElement(H, { id: `${id}-t`, className: "alt-empty-title" }, title),
2819
+ description && /* @__PURE__ */ React10.createElement("p", { id: `${id}-d`, className: "alt-empty-desc" }, description),
2820
+ children,
2821
+ (action || secondary) && /* @__PURE__ */ React10.createElement("div", { className: "alt-empty-actions" }, action, secondary),
2822
+ announce && /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said)
2823
+ );
2824
+ }
2825
+
2826
+ // project/components/src/collections.tsx
2827
+ import * as React11 from "react";
2695
2828
  var dropSnapshots = /* @__PURE__ */ new WeakMap();
2696
2829
  var ms2 = (cs, name, fallback) => parseFloat(cs.getPropertyValue(name)) || fallback;
2697
2830
  function pagePlace(el) {
@@ -2713,7 +2846,7 @@ function placeIn(el, host) {
2713
2846
  return { x: a.x - b.x, y: a.y - b.y };
2714
2847
  }
2715
2848
  function useCarry(host, selector, attr, durToken = "--dur-travel-3") {
2716
- const prev = React10.useRef(null);
2849
+ const prev = React11.useRef(null);
2717
2850
  useIsoLayoutEffect(() => {
2718
2851
  const root = host.current;
2719
2852
  if (!root) return;
@@ -2742,12 +2875,12 @@ var moveItem = (arr, from, to) => {
2742
2875
  a.splice(to, 0, x);
2743
2876
  return a;
2744
2877
  };
2745
- var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className, children, ...rest }, ref) {
2746
- const wrap = React10.useRef(null);
2747
- const table = React10.useRef(null);
2748
- React10.useImperativeHandle(ref, () => table.current);
2749
- const [edges, setEdges] = React10.useState({ top: false, bottom: false });
2750
- const measure = React10.useCallback(() => {
2878
+ var Table = React11.forwardRef(function Table2({ maxHeight, underlay, className, children, ...rest }, ref) {
2879
+ const wrap = React11.useRef(null);
2880
+ const table = React11.useRef(null);
2881
+ React11.useImperativeHandle(ref, () => table.current);
2882
+ const [edges, setEdges] = React11.useState({ top: false, bottom: false });
2883
+ const measure = React11.useCallback(() => {
2751
2884
  const el = wrap.current;
2752
2885
  if (!el) return;
2753
2886
  const top = el.scrollTop > 1, bottom = el.scrollTop + el.clientHeight < el.scrollHeight - 1;
@@ -2768,7 +2901,7 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
2768
2901
  }, [measure]);
2769
2902
  useCarry(table, "tbody > tr[data-row]", "data-row");
2770
2903
  const scrolls = maxHeight !== void 0;
2771
- return /* @__PURE__ */ React10.createElement(
2904
+ return /* @__PURE__ */ React11.createElement(
2772
2905
  "div",
2773
2906
  {
2774
2907
  ref: wrap,
@@ -2780,27 +2913,27 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
2780
2913
  ...scrolls ? { tabIndex: 0, role: "region", "aria-label": rest["aria-label"] } : {}
2781
2914
  },
2782
2915
  underlay,
2783
- /* @__PURE__ */ React10.createElement("table", { ref: table, className: cx("alt-table", className), ...rest }, children)
2916
+ /* @__PURE__ */ React11.createElement("table", { ref: table, className: cx("alt-table", className), ...rest }, children)
2784
2917
  );
2785
2918
  });
2786
- var TableHeader = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("thead", { className: cx("alt-table-head", className), ...p });
2787
- var TableBody = React10.forwardRef(function TableBody2({ className, ...p }, ref) {
2788
- return /* @__PURE__ */ React10.createElement("tbody", { ref, className: cx("alt-table-body", className), ...p });
2919
+ var TableHeader = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("thead", { className: cx("alt-table-head", className), ...p });
2920
+ var TableBody = React11.forwardRef(function TableBody2({ className, ...p }, ref) {
2921
+ return /* @__PURE__ */ React11.createElement("tbody", { ref, className: cx("alt-table-body", className), ...p });
2789
2922
  });
2790
- var TableFooter = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("tfoot", { className: cx("alt-table-foot", className), ...p });
2791
- var TableCaption = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("caption", { className: cx("alt-table-caption", className), ...p });
2792
- var TableRow = React10.forwardRef(function TableRow2({ rowId, selected, interactive, relevance, settle, held, className, style, ...rest }, ref) {
2793
- const [glow, setGlow] = React10.useState(void 0);
2794
- const [delay, setDelay] = React10.useState(0);
2795
- const first = React10.useRef(true);
2796
- React10.useEffect(() => {
2923
+ var TableFooter = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("tfoot", { className: cx("alt-table-foot", className), ...p });
2924
+ var TableCaption = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("caption", { className: cx("alt-table-caption", className), ...p });
2925
+ var TableRow = React11.forwardRef(function TableRow2({ rowId, selected, interactive, relevance, settle, held, className, style, ...rest }, ref) {
2926
+ const [glow, setGlow] = React11.useState(void 0);
2927
+ const [delay, setDelay] = React11.useState(0);
2928
+ const first = React11.useRef(true);
2929
+ React11.useEffect(() => {
2797
2930
  const wasFirst = first.current;
2798
2931
  first.current = false;
2799
2932
  if (settle === void 0 || settle === null || settle === false || wasFirst && settle !== true) return;
2800
2933
  setDelay(riseDelay());
2801
2934
  setGlow((g) => g === "a" ? "b" : "a");
2802
2935
  }, [settle]);
2803
- return /* @__PURE__ */ React10.createElement(
2936
+ return /* @__PURE__ */ React11.createElement(
2804
2937
  "tr",
2805
2938
  {
2806
2939
  ref,
@@ -2816,14 +2949,14 @@ var TableRow = React10.forwardRef(function TableRow2({ rowId, selected, interact
2816
2949
  }
2817
2950
  );
2818
2951
  });
2819
- var SortIcon = () => /* @__PURE__ */ React10.createElement("svg", { className: "alt-table-sort-icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React10.createElement("path", { d: "M6 15l6-6 6 6" }));
2952
+ var SortIcon = () => /* @__PURE__ */ React11.createElement("svg", { className: "alt-table-sort-icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React11.createElement("path", { d: "M6 15l6-6 6 6" }));
2820
2953
  function TableHead({ align, sort, onSort, className, children, ...rest }) {
2821
- return /* @__PURE__ */ React10.createElement("th", { scope: "col", className: cx("alt-th", className), "data-align": align, "aria-sort": onSort ? sort ?? "none" : void 0, ...rest }, onSort ? /* @__PURE__ */ React10.createElement("button", { type: "button", className: "alt-table-sort", "data-sort": sort ?? "none", onClick: onSort }, children, /* @__PURE__ */ React10.createElement(SortIcon, null)) : children);
2954
+ return /* @__PURE__ */ React11.createElement("th", { scope: "col", className: cx("alt-th", className), "data-align": align, "aria-sort": onSort ? sort ?? "none" : void 0, ...rest }, onSort ? /* @__PURE__ */ React11.createElement("button", { type: "button", className: "alt-table-sort", "data-sort": sort ?? "none", onClick: onSort }, children, /* @__PURE__ */ React11.createElement(SortIcon, null)) : children);
2822
2955
  }
2823
2956
  function TableCell({ align, className, ...rest }) {
2824
- return /* @__PURE__ */ React10.createElement("td", { className: cx("alt-td", className), "data-align": align, ...rest });
2957
+ return /* @__PURE__ */ React11.createElement("td", { className: cx("alt-td", className), "data-align": align, ...rest });
2825
2958
  }
2826
- var GripIcon = () => /* @__PURE__ */ React10.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor", "aria-hidden": "true" }, /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "13", r: "1.3" }));
2959
+ var GripIcon = () => /* @__PURE__ */ React11.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor", "aria-hidden": "true" }, /* @__PURE__ */ React11.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React11.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React11.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React11.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React11.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React11.createElement("circle", { cx: "9", cy: "13", r: "1.3" }));
2827
2960
  function DataTable({
2828
2961
  columns,
2829
2962
  rows,
@@ -2848,11 +2981,11 @@ function DataTable({
2848
2981
  }) {
2849
2982
  const [sel, setSel] = useControllable(selected, defaultSelected, onSelectedChange);
2850
2983
  const [srt, setSrt] = useControllable(sort, defaultSort, onSortChange);
2851
- const [said, setSaid] = React10.useState("");
2852
- const table = React10.useRef(null);
2853
- const body = React10.useRef(null);
2984
+ const [said, setSaid] = React11.useState("");
2985
+ const table = React11.useRef(null);
2986
+ const body = React11.useRef(null);
2854
2987
  const name = (r) => getRowLabel?.(r) ?? getRowId(r);
2855
- const view = React10.useMemo(() => {
2988
+ const view = React11.useMemo(() => {
2856
2989
  const col = srt && columns.find((c) => c.key === srt.key);
2857
2990
  if (!srt || !col?.sortValue) return rows;
2858
2991
  const d = srt.direction === "descending" ? -1 : 1;
@@ -2869,9 +3002,9 @@ function DataTable({
2869
3002
  setSaid(next ? `Sorted by ${typeof c.header === "string" ? c.header : c.key}, ${next.direction}.` : "Sort cleared.");
2870
3003
  };
2871
3004
  const toggle = (id, on) => setSel(on ? [...sel.filter((x) => x !== id), id] : sel.filter((x) => x !== id));
2872
- const start = React10.useRef(null);
2873
- const [drag, setDrag] = React10.useState(null);
2874
- const [held, setHeld] = React10.useState(null);
3005
+ const start = React11.useRef(null);
3006
+ const [drag, setDrag] = React11.useState(null);
3007
+ const [held, setHeld] = React11.useState(null);
2875
3008
  const rowEls = () => Array.from(body.current?.querySelectorAll("tr[data-row]") ?? []);
2876
3009
  const snapshot = (at) => {
2877
3010
  if (!table.current) return;
@@ -2941,24 +3074,24 @@ function DataTable({
2941
3074
  setSaid(`Move cancelled; ${name(view[index])} is back at position ${held.origin + 1}.`);
2942
3075
  }
2943
3076
  };
2944
- React10.useEffect(() => {
3077
+ React11.useEffect(() => {
2945
3078
  if (!movable) setHeld(null);
2946
3079
  }, [movable]);
2947
3080
  const s = start.current;
2948
3081
  const h = drag && s ? s.hs[drag.from] : 0;
2949
3082
  const slotTop = drag && s ? drag.to <= drag.from ? s.tops[drag.to] : s.tops[drag.to] + s.hs[drag.to] - s.hs[drag.from] : 0;
2950
3083
  const span = columns.length + (selectable ? 1 : 0) + (movable ? 1 : 0);
2951
- return /* @__PURE__ */ React10.createElement("div", { className: cx("alt-data-table", className) }, (selectable || toolbar) && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-tools" }, sel.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-selection" }, /* @__PURE__ */ React10.createElement(Badge, { variant: "count", tone: "accent", "aria-hidden": "true" }, sel.length), /* @__PURE__ */ React10.createElement("span", null, "selected"), actions?.(sel), /* @__PURE__ */ React10.createElement(Button, { size: "sm", variant: "ghost", onClick: () => setSel([]) }, "Clear")), toolbar && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-tools-end" }, toolbar)), /* @__PURE__ */ React10.createElement(
3084
+ return /* @__PURE__ */ React11.createElement("div", { className: cx("alt-data-table", className) }, (selectable || toolbar) && /* @__PURE__ */ React11.createElement("div", { className: "alt-table-tools" }, sel.length > 0 && /* @__PURE__ */ React11.createElement("div", { className: "alt-table-selection" }, /* @__PURE__ */ React11.createElement(Badge, { variant: "count", tone: "accent", "aria-hidden": "true" }, sel.length), /* @__PURE__ */ React11.createElement("span", null, "selected"), actions?.(sel), /* @__PURE__ */ React11.createElement(Button, { size: "sm", variant: "ghost", onClick: () => setSel([]) }, "Clear")), toolbar && /* @__PURE__ */ React11.createElement("div", { className: "alt-table-tools-end" }, toolbar)), /* @__PURE__ */ React11.createElement(
2952
3085
  Table,
2953
3086
  {
2954
3087
  ref: table,
2955
3088
  maxHeight,
2956
3089
  "aria-label": rest["aria-label"],
2957
3090
  "data-dragging": drag ? "" : void 0,
2958
- underlay: drag && s ? /* @__PURE__ */ React10.createElement("span", { className: "alt-table-slot", "aria-hidden": "true", style: { top: slotTop + (table.current?.offsetTop ?? 0), height: h } }) : null
3091
+ underlay: drag && s ? /* @__PURE__ */ React11.createElement("span", { className: "alt-table-slot", "aria-hidden": "true", style: { top: slotTop + (table.current?.offsetTop ?? 0), height: h } }) : null
2959
3092
  },
2960
- /* @__PURE__ */ React10.createElement(TableHeader, null, /* @__PURE__ */ React10.createElement(TableRow, null, movable && /* @__PURE__ */ React10.createElement(TableHead, { className: "alt-th-grip" }, /* @__PURE__ */ React10.createElement("span", { className: "alt-sr" }, "Move")), selectable && /* @__PURE__ */ React10.createElement(TableHead, { className: "alt-th-check" }, /* @__PURE__ */ React10.createElement(Checkbox, { "aria-label": "Select all rows", checked: all, indeterminate: some, onCheckedChange: (on) => setSel(on ? Array.from(/* @__PURE__ */ new Set([...sel, ...ids])) : sel.filter((x) => !ids.includes(x))) })), columns.map((c) => /* @__PURE__ */ React10.createElement(TableHead, { key: c.key, align: c.align, style: { width: c.width }, sort: srt?.key === c.key ? srt.direction : "none", onSort: c.sortValue ? () => cycle(c) : void 0 }, c.header)))),
2961
- /* @__PURE__ */ React10.createElement(TableBody, { ref: body }, !view.length && /* @__PURE__ */ React10.createElement("tr", null, /* @__PURE__ */ React10.createElement("td", { className: "alt-td alt-table-empty", colSpan: span }, empty)), view.map((r, i) => {
3093
+ /* @__PURE__ */ React11.createElement(TableHeader, null, /* @__PURE__ */ React11.createElement(TableRow, null, movable && /* @__PURE__ */ React11.createElement(TableHead, { className: "alt-th-grip" }, /* @__PURE__ */ React11.createElement("span", { className: "alt-sr" }, "Move")), selectable && /* @__PURE__ */ React11.createElement(TableHead, { className: "alt-th-check" }, /* @__PURE__ */ React11.createElement(Checkbox, { "aria-label": "Select all rows", checked: all, indeterminate: some, onCheckedChange: (on) => setSel(on ? Array.from(/* @__PURE__ */ new Set([...sel, ...ids])) : sel.filter((x) => !ids.includes(x))) })), columns.map((c) => /* @__PURE__ */ React11.createElement(TableHead, { key: c.key, align: c.align, style: { width: c.width }, sort: srt?.key === c.key ? srt.direction : "none", onSort: c.sortValue ? () => cycle(c) : void 0 }, c.header)))),
3094
+ /* @__PURE__ */ React11.createElement(TableBody, { ref: body }, !view.length && /* @__PURE__ */ React11.createElement("tr", null, /* @__PURE__ */ React11.createElement("td", { className: "alt-td alt-table-empty", colSpan: span }, empty)), view.map((r, i) => {
2962
3095
  const id = ids[i];
2963
3096
  let shift = 0;
2964
3097
  if (drag && id !== drag.id && h) {
@@ -2966,7 +3099,7 @@ function DataTable({
2966
3099
  if (drag.to < drag.from && i >= drag.to && i < drag.from) shift = h;
2967
3100
  }
2968
3101
  const following = drag?.id === id;
2969
- return /* @__PURE__ */ React10.createElement(
3102
+ return /* @__PURE__ */ React11.createElement(
2970
3103
  TableRow,
2971
3104
  {
2972
3105
  key: id,
@@ -2981,7 +3114,7 @@ function DataTable({
2981
3114
  if (!e.target.closest("button, a, input, label, select, textarea")) onRowClick(r);
2982
3115
  } : void 0
2983
3116
  },
2984
- movable && /* @__PURE__ */ React10.createElement(TableCell, { className: "alt-td-grip" }, /* @__PURE__ */ React10.createElement(
3117
+ movable && /* @__PURE__ */ React11.createElement(TableCell, { className: "alt-td-grip" }, /* @__PURE__ */ React11.createElement(
2985
3118
  "button",
2986
3119
  {
2987
3120
  type: "button",
@@ -2997,18 +3130,18 @@ function DataTable({
2997
3130
  if (held?.id === id && !drag) setTimeout(() => setHeld((x) => x?.id === id && document.activeElement?.closest(`tr[data-row="${CSS.escape(id)}"]`) === null ? null : x), 0);
2998
3131
  }
2999
3132
  },
3000
- /* @__PURE__ */ React10.createElement(GripIcon, null)
3133
+ /* @__PURE__ */ React11.createElement(GripIcon, null)
3001
3134
  )),
3002
- selectable && /* @__PURE__ */ React10.createElement(TableCell, { className: "alt-td-check" }, /* @__PURE__ */ React10.createElement(Checkbox, { "aria-label": `Select ${name(r)}`, checked: chosen.has(id), onCheckedChange: (on) => toggle(id, on) })),
3135
+ selectable && /* @__PURE__ */ React11.createElement(TableCell, { className: "alt-td-check" }, /* @__PURE__ */ React11.createElement(Checkbox, { "aria-label": `Select ${name(r)}`, checked: chosen.has(id), onCheckedChange: (on) => toggle(id, on) })),
3003
3136
  columns.map((c, ci) => {
3004
3137
  const content = c.cell ? c.cell(r) : String(r[c.key] ?? "");
3005
- return /* @__PURE__ */ React10.createElement(TableCell, { key: c.key, align: c.align }, onRowClick && ci === 0 ? /* @__PURE__ */ React10.createElement("button", { type: "button", className: "alt-table-rowbtn", onClick: () => onRowClick(r) }, content) : content);
3138
+ return /* @__PURE__ */ React11.createElement(TableCell, { key: c.key, align: c.align }, onRowClick && ci === 0 ? /* @__PURE__ */ React11.createElement("button", { type: "button", className: "alt-table-rowbtn", onClick: () => onRowClick(r) }, content) : content);
3006
3139
  })
3007
3140
  );
3008
3141
  }))
3009
- ), /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "polite" }, selectable && sel.length ? `${sel.length} selected. ` : "", said));
3142
+ ), /* @__PURE__ */ React11.createElement("span", { className: "alt-sr", "aria-live": "polite" }, selectable && sel.length ? `${sel.length} selected. ` : "", said));
3010
3143
  }
3011
- var BoardCtx = React10.createContext(null);
3144
+ var BoardCtx = React11.createContext(null);
3012
3145
  function readBoard(root) {
3013
3146
  return Array.from(root.querySelectorAll("[data-board-col]")).map((col) => {
3014
3147
  const list = col.querySelector(".alt-board-list");
@@ -3055,18 +3188,18 @@ function plan(cols, id, cx2, cy, h) {
3055
3188
  }
3056
3189
  return { to: { column: tc.id, index }, shifts, slotTop, gap: tc.gap };
3057
3190
  }
3058
- var Board = React10.forwardRef(function Board2({ onMove, className, children, ...rest }, ref) {
3059
- const root = React10.useRef(null);
3060
- React10.useImperativeHandle(ref, () => root.current);
3061
- const hintId = React10.useId();
3062
- const [carry, setCarry] = React10.useState(null);
3063
- const [kb, setKb] = React10.useState(null);
3064
- const [landing, setLanding] = React10.useState(null);
3065
- const [said, setSaid] = React10.useState("");
3066
- const start = React10.useRef(null);
3067
- const dragged = React10.useRef(false);
3191
+ var Board = React11.forwardRef(function Board2({ onMove, className, children, ...rest }, ref) {
3192
+ const root = React11.useRef(null);
3193
+ React11.useImperativeHandle(ref, () => root.current);
3194
+ const hintId = React11.useId();
3195
+ const [carry, setCarry] = React11.useState(null);
3196
+ const [kb, setKb] = React11.useState(null);
3197
+ const [landing, setLanding] = React11.useState(null);
3198
+ const [said, setSaid] = React11.useState("");
3199
+ const start = React11.useRef(null);
3200
+ const dragged = React11.useRef(false);
3068
3201
  useCarry(root, "[data-board-card]", "data-board-card");
3069
- React10.useEffect(() => {
3202
+ React11.useEffect(() => {
3070
3203
  if (!landing) return;
3071
3204
  const t = setTimeout(() => setLanding(null), 450);
3072
3205
  return () => clearTimeout(t);
@@ -3195,17 +3328,17 @@ var Board = React10.forwardRef(function Board2({ onMove, className, children, ..
3195
3328
  return d;
3196
3329
  };
3197
3330
  const ctx = { carry, kb, landing, hintId, onPointerDown, onPointerMove, onPointerUp, onKeyDown, onBlur, swallowClick };
3198
- return /* @__PURE__ */ React10.createElement(BoardCtx.Provider, { value: ctx }, /* @__PURE__ */ React10.createElement("div", { ref: root, role: "group", "aria-label": rest["aria-label"] ?? "Board", className: cx("alt-board", className), "data-carrying": carry || kb ? "" : void 0, ...rest }, children, /* @__PURE__ */ React10.createElement("span", { id: hintId, className: "alt-sr" }, "Press Space to pick up. While holding a card, use the arrow keys to move it, Space to drop it, Escape to cancel."), /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, said)));
3331
+ return /* @__PURE__ */ React11.createElement(BoardCtx.Provider, { value: ctx }, /* @__PURE__ */ React11.createElement("div", { ref: root, role: "group", "aria-label": rest["aria-label"] ?? "Board", className: cx("alt-board", className), "data-carrying": carry || kb ? "" : void 0, ...rest }, children, /* @__PURE__ */ React11.createElement("span", { id: hintId, className: "alt-sr" }, "Press Space to pick up. While holding a card, use the arrow keys to move it, Space to drop it, Escape to cancel."), /* @__PURE__ */ React11.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, said)));
3199
3332
  });
3200
3333
  function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollapsedChange, collapsible, className, children, ...rest }) {
3201
- const ctx = React10.useContext(BoardCtx);
3334
+ const ctx = React11.useContext(BoardCtx);
3202
3335
  const [isCollapsed, setCollapsed] = useControllable(collapsed, defaultCollapsed, onCollapsedChange);
3203
- const count = React10.Children.toArray(children).filter(React10.isValidElement).length;
3336
+ const count = React11.Children.toArray(children).filter(React11.isValidElement).length;
3204
3337
  const label = typeof title === "string" ? title : id;
3205
3338
  const carry = ctx?.carry;
3206
3339
  const over = carry ? carry.to.column === id : ctx?.kb?.at.column === id;
3207
3340
  const receiving = !!carry && carry.to.column === id && carry.from.column !== id && !isCollapsed;
3208
- return /* @__PURE__ */ React10.createElement(
3341
+ return /* @__PURE__ */ React11.createElement(
3209
3342
  "section",
3210
3343
  {
3211
3344
  className: cx("alt-board-col", className),
@@ -3216,7 +3349,7 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
3216
3349
  "data-over": over ? "" : void 0,
3217
3350
  ...rest
3218
3351
  },
3219
- /* @__PURE__ */ React10.createElement("header", { className: "alt-board-head" }, /* @__PURE__ */ React10.createElement("h3", { className: "alt-board-title" }, title), /* @__PURE__ */ React10.createElement("span", { className: "alt-board-count", "aria-label": `${count} ${count === 1 ? "card" : "cards"}` }, count), collapsible && /* @__PURE__ */ React10.createElement(
3352
+ /* @__PURE__ */ React11.createElement("header", { className: "alt-board-head" }, /* @__PURE__ */ React11.createElement("h3", { className: "alt-board-title" }, title), /* @__PURE__ */ React11.createElement("span", { className: "alt-board-count", "aria-label": `${count} ${count === 1 ? "card" : "cards"}` }, count), collapsible && /* @__PURE__ */ React11.createElement(
3220
3353
  Button,
3221
3354
  {
3222
3355
  variant: "ghost",
@@ -3228,20 +3361,20 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
3228
3361
  "data-collapsed": isCollapsed ? "" : void 0,
3229
3362
  onClick: () => setCollapsed(!isCollapsed)
3230
3363
  },
3231
- /* @__PURE__ */ React10.createElement(Icons.ChevronDown, null)
3364
+ /* @__PURE__ */ React11.createElement(Icons.ChevronDown, null)
3232
3365
  )),
3233
- isCollapsed ? /* @__PURE__ */ React10.createElement(Pile, { count: Math.max(count, 1), className: "alt-board-pile" }, /* @__PURE__ */ React10.createElement("div", { className: "alt-board-pile-face" }, /* @__PURE__ */ React10.createElement("b", null, title), /* @__PURE__ */ React10.createElement("span", null, count ? `${count} ${count === 1 ? "card" : "cards"}` : "No cards"))) : /* @__PURE__ */ React10.createElement("div", { className: "alt-board-list", style: receiving ? { paddingBottom: carry.h + carry.gap } : void 0 }, carry && carry.to.column === id && /* @__PURE__ */ React10.createElement("span", { className: "alt-board-slot", "aria-hidden": "true", style: { top: carry.slotTop, height: carry.h } }), children, !count && !carry && /* @__PURE__ */ React10.createElement("div", { className: "alt-board-empty" }, "No cards"))
3366
+ isCollapsed ? /* @__PURE__ */ React11.createElement(Pile, { count: Math.max(count, 1), className: "alt-board-pile" }, /* @__PURE__ */ React11.createElement("div", { className: "alt-board-pile-face" }, /* @__PURE__ */ React11.createElement("b", null, title), /* @__PURE__ */ React11.createElement("span", null, count ? `${count} ${count === 1 ? "card" : "cards"}` : "No cards"))) : /* @__PURE__ */ React11.createElement("div", { className: "alt-board-list", style: receiving ? { paddingBottom: carry.h + carry.gap } : void 0 }, carry && carry.to.column === id && /* @__PURE__ */ React11.createElement("span", { className: "alt-board-slot", "aria-hidden": "true", style: { top: carry.slotTop, height: carry.h } }), children, !count && !carry && /* @__PURE__ */ React11.createElement("div", { className: "alt-board-empty" }, "No cards"))
3234
3367
  );
3235
3368
  }
3236
- var BoardCard = React10.forwardRef(function BoardCard2({ id, label, heldBy, settle, className, style, onClickCapture, children, ...rest }, ref) {
3237
- const ctx = React10.useContext(BoardCtx);
3369
+ var BoardCard = React11.forwardRef(function BoardCard2({ id, label, heldBy, settle, className, style, onClickCapture, children, ...rest }, ref) {
3370
+ const ctx = React11.useContext(BoardCtx);
3238
3371
  const depth = useDepth({ heldBy, settle });
3239
3372
  const carry = ctx?.carry;
3240
3373
  const following = carry?.id === id;
3241
3374
  const carried = following || ctx?.kb?.id === id;
3242
3375
  const shift = carry?.shifts[id];
3243
3376
  const transform = following ? `translate(${carry.dx}px, ${carry.dy}px)` : shift ? `translateY(${shift}px)` : void 0;
3244
- return /* @__PURE__ */ React10.createElement(
3377
+ return /* @__PURE__ */ React11.createElement(
3245
3378
  "div",
3246
3379
  {
3247
3380
  ref,
@@ -3301,6 +3434,7 @@ export {
3301
3434
  Drilldown,
3302
3435
  DropZone,
3303
3436
  DropdownMenu,
3437
+ EmptyState,
3304
3438
  Field,
3305
3439
  HoldButton,
3306
3440
  HoverCard,
@@ -3343,6 +3477,7 @@ export {
3343
3477
  Textarea,
3344
3478
  Toaster,
3345
3479
  Tooltip,
3480
+ checkScheme,
3346
3481
  commandScore,
3347
3482
  contrast,
3348
3483
  deriveAccent,