altitude-design 0.1.2 → 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/README.md +2 -0
- package/dist/altitude.css +28 -1
- package/dist/altitude.iife.js +5 -3
- package/dist/altitude.no-fonts.css +1659 -0
- package/dist/fonts.css +1 -0
- package/dist/index.cjs +205 -70
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +205 -70
- package/dist/index.js.map +4 -4
- package/dist/types/command.d.ts +5 -1
- package/dist/types/core.d.ts +23 -2
- package/dist/types/empty.d.ts +24 -0
- package/dist/types/index.d.ts +3 -1
- package/package.json +3 -1
package/dist/fonts.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400..700&family=JetBrains+Mono:wght@400;500&display=swap');
|
package/dist/index.cjs
CHANGED
|
@@ -56,6 +56,7 @@ __export(index_exports, {
|
|
|
56
56
|
Drilldown: () => Drilldown,
|
|
57
57
|
DropZone: () => DropZone,
|
|
58
58
|
DropdownMenu: () => DropdownMenu,
|
|
59
|
+
EmptyState: () => EmptyState,
|
|
59
60
|
Field: () => Field,
|
|
60
61
|
HoldButton: () => HoldButton,
|
|
61
62
|
HoverCard: () => HoverCard,
|
|
@@ -98,6 +99,7 @@ __export(index_exports, {
|
|
|
98
99
|
Textarea: () => Textarea,
|
|
99
100
|
Toaster: () => Toaster,
|
|
100
101
|
Tooltip: () => Tooltip,
|
|
102
|
+
checkScheme: () => checkScheme,
|
|
101
103
|
commandScore: () => commandScore,
|
|
102
104
|
contrast: () => contrast,
|
|
103
105
|
deriveAccent: () => deriveAccent,
|
|
@@ -340,6 +342,63 @@ function deriveAccent(accent, surfaces) {
|
|
|
340
342
|
"--accent-soft": rgbToHex(mix(hexToRgb(ground), a, dark ? 0.2 : 0.13))
|
|
341
343
|
};
|
|
342
344
|
}
|
|
345
|
+
var SURFACES = ["surface-trench", "surface-well", "surface-ground", "surface-raised", "surface-lifted", "surface-floating", "surface-overlay", "surface-modal"];
|
|
346
|
+
var PAIRS = [];
|
|
347
|
+
for (const t of ["ink", "ink-muted", "accent-ink", "positive", "caution", "critical"]) for (const g of SURFACES) PAIRS.push([t, g, 4.5]);
|
|
348
|
+
for (const [t, g] of [
|
|
349
|
+
["ink", "accent-soft"],
|
|
350
|
+
["accent-ink", "accent-soft"],
|
|
351
|
+
["positive", "positive-soft"],
|
|
352
|
+
["caution", "caution-soft"],
|
|
353
|
+
["critical", "critical-soft"],
|
|
354
|
+
["ink", "critical-soft"],
|
|
355
|
+
["ink", "positive-soft"],
|
|
356
|
+
["ink", "caution-soft"],
|
|
357
|
+
["ink-muted", "accent-soft"],
|
|
358
|
+
["on-accent", "accent"],
|
|
359
|
+
["on-critical", "critical"]
|
|
360
|
+
]) PAIRS.push([t, g, 4.5]);
|
|
361
|
+
for (const g of ["surface-ground", "surface-well", "surface-raised", "surface-trench"]) PAIRS.push(["line-control", g, 3], ["accent", g, 3]);
|
|
362
|
+
for (const p of ["presence-1", "presence-2", "presence-3"]) {
|
|
363
|
+
PAIRS.push(["on-presence", p, 4.5]);
|
|
364
|
+
for (const g of SURFACES) PAIRS.push([p, g, 3]);
|
|
365
|
+
}
|
|
366
|
+
var isHex = (v) => /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v);
|
|
367
|
+
function checkScheme(colors) {
|
|
368
|
+
const cs = typeof Element !== "undefined" && colors instanceof Element ? getComputedStyle(colors) : null;
|
|
369
|
+
const get = (n) => (cs ? cs.getPropertyValue("--" + n) : colors[n] ?? "").trim();
|
|
370
|
+
const out = [];
|
|
371
|
+
const seen = /* @__PURE__ */ new Set();
|
|
372
|
+
const ok = (n) => {
|
|
373
|
+
const v = get(n);
|
|
374
|
+
if (isHex(v)) return true;
|
|
375
|
+
if (!seen.has(n)) {
|
|
376
|
+
seen.add(n);
|
|
377
|
+
out.push(v ? `${n} is ${v}: use a 3- or 6-digit hex colour so it can be checked.` : `${n} is missing.`);
|
|
378
|
+
}
|
|
379
|
+
return false;
|
|
380
|
+
};
|
|
381
|
+
const L = (n) => lum(hexToRgb(get(n)));
|
|
382
|
+
for (let i = 1; i < SURFACES.length; i++) {
|
|
383
|
+
const lo = SURFACES[i - 1], hi = SURFACES[i];
|
|
384
|
+
if (!ok(lo) || !ok(hi)) continue;
|
|
385
|
+
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)}).`);
|
|
386
|
+
}
|
|
387
|
+
for (const [t, g, min] of PAIRS) {
|
|
388
|
+
if (!ok(t) || !ok(g)) continue;
|
|
389
|
+
const r = contrast(get(t), get(g));
|
|
390
|
+
if (r < min) out.push(`${t} on ${g} is ${r.toFixed(2)}:1; it needs ${min}:1.`);
|
|
391
|
+
}
|
|
392
|
+
return out;
|
|
393
|
+
}
|
|
394
|
+
var SHADOW_OR_LINE = /^(trench|well|elev-\d|lip-top|lip-bottom|line)$/;
|
|
395
|
+
function schemeCss(sel, tokens) {
|
|
396
|
+
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(" ");
|
|
397
|
+
const plain = decl((k) => !SHADOW_OR_LINE.test(k)), soft = decl((k) => SHADOW_OR_LINE.test(k));
|
|
398
|
+
let css = plain ? `${sel} { ${plain} }` : "";
|
|
399
|
+
if (soft) css += `@media not (prefers-contrast: more) { ${sel}:not([data-contrast="more"], [data-contrast="more"] *) { ${soft} } }`;
|
|
400
|
+
return css;
|
|
401
|
+
}
|
|
343
402
|
var AltitudeContext = React.createContext(null);
|
|
344
403
|
var useAltitude = () => React.useContext(AltitudeContext);
|
|
345
404
|
function AltitudeProvider({ scheme, accent, motion = "system", contrast: contrast2 = "system", recede = true, approach = true, className, style, children, ...rest }) {
|
|
@@ -347,6 +406,18 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
|
|
|
347
406
|
const [host, setHost] = React.useState(null);
|
|
348
407
|
const [layers, setLayers] = React.useState(0);
|
|
349
408
|
const [accentVars, setAccentVars] = React.useState(null);
|
|
409
|
+
const custom = scheme && typeof scheme === "object" ? scheme : null;
|
|
410
|
+
const schemeKey = custom ? JSON.stringify(custom) : scheme;
|
|
411
|
+
const scope = React.useId();
|
|
412
|
+
const schemeSel = `.alt-root[data-scheme-id="${scope}"]`;
|
|
413
|
+
const warned = React.useRef("");
|
|
414
|
+
React.useEffect(() => {
|
|
415
|
+
if (!custom || !rootRef.current || warned.current === schemeKey) return;
|
|
416
|
+
warned.current = schemeKey;
|
|
417
|
+
const issues = checkScheme(rootRef.current);
|
|
418
|
+
if (issues.length) console.warn(`Altitude: the scheme "${custom.name}" breaks ${issues.length} of the scheme invariants (see Theming.md):
|
|
419
|
+
` + issues.join("\n"));
|
|
420
|
+
}, [schemeKey]);
|
|
350
421
|
useIsoLayoutEffect(() => {
|
|
351
422
|
if (!accent || !rootRef.current) {
|
|
352
423
|
setAccentVars(null);
|
|
@@ -362,7 +433,7 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
|
|
|
362
433
|
const mo = new MutationObserver(compute);
|
|
363
434
|
mo.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
|
|
364
435
|
return () => mo.disconnect();
|
|
365
|
-
}, [accent,
|
|
436
|
+
}, [accent, schemeKey]);
|
|
366
437
|
const api = React.useMemo(() => ({
|
|
367
438
|
host,
|
|
368
439
|
pushLayer: () => {
|
|
@@ -375,13 +446,16 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
|
|
|
375
446
|
{
|
|
376
447
|
ref: rootRef,
|
|
377
448
|
className: cx("alt-root", className),
|
|
378
|
-
"data-theme": scheme,
|
|
449
|
+
"data-theme": custom ? custom.base ?? "daylight" : scheme,
|
|
450
|
+
"data-scheme": custom?.name,
|
|
451
|
+
"data-scheme-id": custom ? scope : void 0,
|
|
379
452
|
"data-motion": motion === "system" ? void 0 : motion,
|
|
380
453
|
"data-contrast": contrast2 === "more" ? "more" : void 0,
|
|
381
454
|
"data-approach-off": approach ? void 0 : "",
|
|
382
455
|
style: { ...accentVars, ...style },
|
|
383
456
|
...rest
|
|
384
457
|
},
|
|
458
|
+
custom && /* @__PURE__ */ React.createElement("style", null, schemeCss(schemeSel, custom.tokens)),
|
|
385
459
|
/* @__PURE__ */ React.createElement("div", { className: "alt-stage", "data-receded": recede && layers > 0 ? "" : void 0 }, children),
|
|
386
460
|
/* @__PURE__ */ React.createElement("div", { className: "alt-layers", ref: setHost })
|
|
387
461
|
));
|
|
@@ -2058,6 +2132,8 @@ function CommandPalette({
|
|
|
2058
2132
|
filter,
|
|
2059
2133
|
empty,
|
|
2060
2134
|
shortcut = "k",
|
|
2135
|
+
query: queryProp,
|
|
2136
|
+
defaultQuery = "",
|
|
2061
2137
|
onQueryChange,
|
|
2062
2138
|
closeOnSelect = true,
|
|
2063
2139
|
hints = true,
|
|
@@ -2065,7 +2141,8 @@ function CommandPalette({
|
|
|
2065
2141
|
...rest
|
|
2066
2142
|
}) {
|
|
2067
2143
|
const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
|
|
2068
|
-
const [
|
|
2144
|
+
const [innerQuery, setInnerQuery] = React7.useState(defaultQuery);
|
|
2145
|
+
const query = queryProp ?? innerQuery;
|
|
2069
2146
|
const [active, setActive] = React7.useState(0);
|
|
2070
2147
|
const [onset, setOnset] = React7.useState(true);
|
|
2071
2148
|
const [said, setSaid] = React7.useState("");
|
|
@@ -2076,6 +2153,9 @@ function CommandPalette({
|
|
|
2076
2153
|
const rowEls = React7.useRef(/* @__PURE__ */ new Map());
|
|
2077
2154
|
const prevTops = React7.useRef(null);
|
|
2078
2155
|
const byKeyboard = React7.useRef(false);
|
|
2156
|
+
const caretPlaced = React7.useRef(false);
|
|
2157
|
+
const seed = React7.useRef(defaultQuery);
|
|
2158
|
+
seed.current = defaultQuery;
|
|
2079
2159
|
const [panelEl, setPanelEl] = React7.useState(null);
|
|
2080
2160
|
const panelRef = React7.useCallback((el) => {
|
|
2081
2161
|
panel.current = el;
|
|
@@ -2102,11 +2182,15 @@ function CommandPalette({
|
|
|
2102
2182
|
}, [shortcut, isOpen, set]);
|
|
2103
2183
|
React7.useEffect(() => {
|
|
2104
2184
|
if (isOpen) {
|
|
2105
|
-
|
|
2185
|
+
setInnerQuery(seed.current);
|
|
2106
2186
|
setActive(0);
|
|
2107
2187
|
setOnset(true);
|
|
2188
|
+
caretPlaced.current = false;
|
|
2108
2189
|
}
|
|
2109
2190
|
}, [isOpen]);
|
|
2191
|
+
React7.useEffect(() => {
|
|
2192
|
+
setActive(0);
|
|
2193
|
+
}, [query]);
|
|
2110
2194
|
const q = query.trim();
|
|
2111
2195
|
const score = filter ?? itemScore;
|
|
2112
2196
|
const view = items.map((g, gi) => {
|
|
@@ -2224,11 +2308,17 @@ function CommandPalette({
|
|
|
2224
2308
|
leading: /* @__PURE__ */ React7.createElement(SearchIcon, null),
|
|
2225
2309
|
trailing: /* @__PURE__ */ React7.createElement("span", { "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement(Kbd, null, "esc")),
|
|
2226
2310
|
onChange: (e) => {
|
|
2227
|
-
|
|
2311
|
+
setInnerQuery(e.target.value);
|
|
2228
2312
|
setActive(0);
|
|
2229
2313
|
setOnset(false);
|
|
2230
2314
|
onQueryChange?.(e.target.value);
|
|
2231
2315
|
},
|
|
2316
|
+
onFocus: (e) => {
|
|
2317
|
+
if (caretPlaced.current) return;
|
|
2318
|
+
caretPlaced.current = true;
|
|
2319
|
+
const n2 = e.currentTarget.value.length;
|
|
2320
|
+
e.currentTarget.setSelectionRange(n2, n2);
|
|
2321
|
+
},
|
|
2232
2322
|
onKeyDown: onInputKeyDown
|
|
2233
2323
|
}
|
|
2234
2324
|
)), /* @__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(
|
|
@@ -2800,8 +2890,53 @@ function Stepper({ steps, current, onStepChange, orientation = "horizontal", cla
|
|
|
2800
2890
|
})), /* @__PURE__ */ React9.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said));
|
|
2801
2891
|
}
|
|
2802
2892
|
|
|
2803
|
-
// project/components/src/
|
|
2893
|
+
// project/components/src/empty.tsx
|
|
2804
2894
|
var React10 = __toESM(require("react"), 1);
|
|
2895
|
+
function EmptyState({
|
|
2896
|
+
icon: icon2,
|
|
2897
|
+
title,
|
|
2898
|
+
description,
|
|
2899
|
+
action,
|
|
2900
|
+
secondary,
|
|
2901
|
+
size = "md",
|
|
2902
|
+
headingLevel = 3,
|
|
2903
|
+
announce,
|
|
2904
|
+
className,
|
|
2905
|
+
children,
|
|
2906
|
+
...rest
|
|
2907
|
+
}) {
|
|
2908
|
+
const id = React10.useId();
|
|
2909
|
+
const H = `h${headingLevel}`;
|
|
2910
|
+
const words = typeof announce === "string" ? announce : announce && typeof title === "string" ? title : "";
|
|
2911
|
+
const [said, setSaid] = React10.useState("");
|
|
2912
|
+
React10.useEffect(() => {
|
|
2913
|
+
if (!words) {
|
|
2914
|
+
setSaid("");
|
|
2915
|
+
return;
|
|
2916
|
+
}
|
|
2917
|
+
const t = setTimeout(() => setSaid(words), 100);
|
|
2918
|
+
return () => clearTimeout(t);
|
|
2919
|
+
}, [words]);
|
|
2920
|
+
return /* @__PURE__ */ React10.createElement(
|
|
2921
|
+
"section",
|
|
2922
|
+
{
|
|
2923
|
+
className: cx("alt-empty", className),
|
|
2924
|
+
"data-size": size,
|
|
2925
|
+
"aria-labelledby": `${id}-t`,
|
|
2926
|
+
"aria-describedby": description ? `${id}-d` : void 0,
|
|
2927
|
+
...rest
|
|
2928
|
+
},
|
|
2929
|
+
icon2 && /* @__PURE__ */ React10.createElement("span", { className: "alt-empty-icon", "aria-hidden": "true" }, icon2),
|
|
2930
|
+
/* @__PURE__ */ React10.createElement(H, { id: `${id}-t`, className: "alt-empty-title" }, title),
|
|
2931
|
+
description && /* @__PURE__ */ React10.createElement("p", { id: `${id}-d`, className: "alt-empty-desc" }, description),
|
|
2932
|
+
children,
|
|
2933
|
+
(action || secondary) && /* @__PURE__ */ React10.createElement("div", { className: "alt-empty-actions" }, action, secondary),
|
|
2934
|
+
announce && /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said)
|
|
2935
|
+
);
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
// project/components/src/collections.tsx
|
|
2939
|
+
var React11 = __toESM(require("react"), 1);
|
|
2805
2940
|
var dropSnapshots = /* @__PURE__ */ new WeakMap();
|
|
2806
2941
|
var ms2 = (cs, name, fallback) => parseFloat(cs.getPropertyValue(name)) || fallback;
|
|
2807
2942
|
function pagePlace(el) {
|
|
@@ -2823,7 +2958,7 @@ function placeIn(el, host) {
|
|
|
2823
2958
|
return { x: a.x - b.x, y: a.y - b.y };
|
|
2824
2959
|
}
|
|
2825
2960
|
function useCarry(host, selector, attr, durToken = "--dur-travel-3") {
|
|
2826
|
-
const prev =
|
|
2961
|
+
const prev = React11.useRef(null);
|
|
2827
2962
|
useIsoLayoutEffect(() => {
|
|
2828
2963
|
const root = host.current;
|
|
2829
2964
|
if (!root) return;
|
|
@@ -2852,12 +2987,12 @@ var moveItem = (arr, from, to) => {
|
|
|
2852
2987
|
a.splice(to, 0, x);
|
|
2853
2988
|
return a;
|
|
2854
2989
|
};
|
|
2855
|
-
var Table =
|
|
2856
|
-
const wrap =
|
|
2857
|
-
const table =
|
|
2858
|
-
|
|
2859
|
-
const [edges, setEdges] =
|
|
2860
|
-
const measure =
|
|
2990
|
+
var Table = React11.forwardRef(function Table2({ maxHeight, underlay, className, children, ...rest }, ref) {
|
|
2991
|
+
const wrap = React11.useRef(null);
|
|
2992
|
+
const table = React11.useRef(null);
|
|
2993
|
+
React11.useImperativeHandle(ref, () => table.current);
|
|
2994
|
+
const [edges, setEdges] = React11.useState({ top: false, bottom: false });
|
|
2995
|
+
const measure = React11.useCallback(() => {
|
|
2861
2996
|
const el = wrap.current;
|
|
2862
2997
|
if (!el) return;
|
|
2863
2998
|
const top = el.scrollTop > 1, bottom = el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
@@ -2878,7 +3013,7 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
|
|
|
2878
3013
|
}, [measure]);
|
|
2879
3014
|
useCarry(table, "tbody > tr[data-row]", "data-row");
|
|
2880
3015
|
const scrolls = maxHeight !== void 0;
|
|
2881
|
-
return /* @__PURE__ */
|
|
3016
|
+
return /* @__PURE__ */ React11.createElement(
|
|
2882
3017
|
"div",
|
|
2883
3018
|
{
|
|
2884
3019
|
ref: wrap,
|
|
@@ -2890,27 +3025,27 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
|
|
|
2890
3025
|
...scrolls ? { tabIndex: 0, role: "region", "aria-label": rest["aria-label"] } : {}
|
|
2891
3026
|
},
|
|
2892
3027
|
underlay,
|
|
2893
|
-
/* @__PURE__ */
|
|
3028
|
+
/* @__PURE__ */ React11.createElement("table", { ref: table, className: cx("alt-table", className), ...rest }, children)
|
|
2894
3029
|
);
|
|
2895
3030
|
});
|
|
2896
|
-
var TableHeader = ({ className, ...p }) => /* @__PURE__ */
|
|
2897
|
-
var TableBody =
|
|
2898
|
-
return /* @__PURE__ */
|
|
3031
|
+
var TableHeader = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("thead", { className: cx("alt-table-head", className), ...p });
|
|
3032
|
+
var TableBody = React11.forwardRef(function TableBody2({ className, ...p }, ref) {
|
|
3033
|
+
return /* @__PURE__ */ React11.createElement("tbody", { ref, className: cx("alt-table-body", className), ...p });
|
|
2899
3034
|
});
|
|
2900
|
-
var TableFooter = ({ className, ...p }) => /* @__PURE__ */
|
|
2901
|
-
var TableCaption = ({ className, ...p }) => /* @__PURE__ */
|
|
2902
|
-
var TableRow =
|
|
2903
|
-
const [glow, setGlow] =
|
|
2904
|
-
const [delay, setDelay] =
|
|
2905
|
-
const first =
|
|
2906
|
-
|
|
3035
|
+
var TableFooter = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("tfoot", { className: cx("alt-table-foot", className), ...p });
|
|
3036
|
+
var TableCaption = ({ className, ...p }) => /* @__PURE__ */ React11.createElement("caption", { className: cx("alt-table-caption", className), ...p });
|
|
3037
|
+
var TableRow = React11.forwardRef(function TableRow2({ rowId, selected, interactive, relevance, settle, held, className, style, ...rest }, ref) {
|
|
3038
|
+
const [glow, setGlow] = React11.useState(void 0);
|
|
3039
|
+
const [delay, setDelay] = React11.useState(0);
|
|
3040
|
+
const first = React11.useRef(true);
|
|
3041
|
+
React11.useEffect(() => {
|
|
2907
3042
|
const wasFirst = first.current;
|
|
2908
3043
|
first.current = false;
|
|
2909
3044
|
if (settle === void 0 || settle === null || settle === false || wasFirst && settle !== true) return;
|
|
2910
3045
|
setDelay(riseDelay());
|
|
2911
3046
|
setGlow((g) => g === "a" ? "b" : "a");
|
|
2912
3047
|
}, [settle]);
|
|
2913
|
-
return /* @__PURE__ */
|
|
3048
|
+
return /* @__PURE__ */ React11.createElement(
|
|
2914
3049
|
"tr",
|
|
2915
3050
|
{
|
|
2916
3051
|
ref,
|
|
@@ -2926,14 +3061,14 @@ var TableRow = React10.forwardRef(function TableRow2({ rowId, selected, interact
|
|
|
2926
3061
|
}
|
|
2927
3062
|
);
|
|
2928
3063
|
});
|
|
2929
|
-
var SortIcon = () => /* @__PURE__ */
|
|
3064
|
+
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" }));
|
|
2930
3065
|
function TableHead({ align, sort, onSort, className, children, ...rest }) {
|
|
2931
|
-
return /* @__PURE__ */
|
|
3066
|
+
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);
|
|
2932
3067
|
}
|
|
2933
3068
|
function TableCell({ align, className, ...rest }) {
|
|
2934
|
-
return /* @__PURE__ */
|
|
3069
|
+
return /* @__PURE__ */ React11.createElement("td", { className: cx("alt-td", className), "data-align": align, ...rest });
|
|
2935
3070
|
}
|
|
2936
|
-
var GripIcon = () => /* @__PURE__ */
|
|
3071
|
+
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" }));
|
|
2937
3072
|
function DataTable({
|
|
2938
3073
|
columns,
|
|
2939
3074
|
rows,
|
|
@@ -2958,11 +3093,11 @@ function DataTable({
|
|
|
2958
3093
|
}) {
|
|
2959
3094
|
const [sel, setSel] = useControllable(selected, defaultSelected, onSelectedChange);
|
|
2960
3095
|
const [srt, setSrt] = useControllable(sort, defaultSort, onSortChange);
|
|
2961
|
-
const [said, setSaid] =
|
|
2962
|
-
const table =
|
|
2963
|
-
const body =
|
|
3096
|
+
const [said, setSaid] = React11.useState("");
|
|
3097
|
+
const table = React11.useRef(null);
|
|
3098
|
+
const body = React11.useRef(null);
|
|
2964
3099
|
const name = (r) => getRowLabel?.(r) ?? getRowId(r);
|
|
2965
|
-
const view =
|
|
3100
|
+
const view = React11.useMemo(() => {
|
|
2966
3101
|
const col = srt && columns.find((c) => c.key === srt.key);
|
|
2967
3102
|
if (!srt || !col?.sortValue) return rows;
|
|
2968
3103
|
const d = srt.direction === "descending" ? -1 : 1;
|
|
@@ -2979,9 +3114,9 @@ function DataTable({
|
|
|
2979
3114
|
setSaid(next ? `Sorted by ${typeof c.header === "string" ? c.header : c.key}, ${next.direction}.` : "Sort cleared.");
|
|
2980
3115
|
};
|
|
2981
3116
|
const toggle = (id, on) => setSel(on ? [...sel.filter((x) => x !== id), id] : sel.filter((x) => x !== id));
|
|
2982
|
-
const start =
|
|
2983
|
-
const [drag, setDrag] =
|
|
2984
|
-
const [held, setHeld] =
|
|
3117
|
+
const start = React11.useRef(null);
|
|
3118
|
+
const [drag, setDrag] = React11.useState(null);
|
|
3119
|
+
const [held, setHeld] = React11.useState(null);
|
|
2985
3120
|
const rowEls = () => Array.from(body.current?.querySelectorAll("tr[data-row]") ?? []);
|
|
2986
3121
|
const snapshot = (at) => {
|
|
2987
3122
|
if (!table.current) return;
|
|
@@ -3051,24 +3186,24 @@ function DataTable({
|
|
|
3051
3186
|
setSaid(`Move cancelled; ${name(view[index])} is back at position ${held.origin + 1}.`);
|
|
3052
3187
|
}
|
|
3053
3188
|
};
|
|
3054
|
-
|
|
3189
|
+
React11.useEffect(() => {
|
|
3055
3190
|
if (!movable) setHeld(null);
|
|
3056
3191
|
}, [movable]);
|
|
3057
3192
|
const s = start.current;
|
|
3058
3193
|
const h = drag && s ? s.hs[drag.from] : 0;
|
|
3059
3194
|
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;
|
|
3060
3195
|
const span = columns.length + (selectable ? 1 : 0) + (movable ? 1 : 0);
|
|
3061
|
-
return /* @__PURE__ */
|
|
3196
|
+
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(
|
|
3062
3197
|
Table,
|
|
3063
3198
|
{
|
|
3064
3199
|
ref: table,
|
|
3065
3200
|
maxHeight,
|
|
3066
3201
|
"aria-label": rest["aria-label"],
|
|
3067
3202
|
"data-dragging": drag ? "" : void 0,
|
|
3068
|
-
underlay: drag && s ? /* @__PURE__ */
|
|
3203
|
+
underlay: drag && s ? /* @__PURE__ */ React11.createElement("span", { className: "alt-table-slot", "aria-hidden": "true", style: { top: slotTop + (table.current?.offsetTop ?? 0), height: h } }) : null
|
|
3069
3204
|
},
|
|
3070
|
-
/* @__PURE__ */
|
|
3071
|
-
/* @__PURE__ */
|
|
3205
|
+
/* @__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)))),
|
|
3206
|
+
/* @__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) => {
|
|
3072
3207
|
const id = ids[i];
|
|
3073
3208
|
let shift = 0;
|
|
3074
3209
|
if (drag && id !== drag.id && h) {
|
|
@@ -3076,7 +3211,7 @@ function DataTable({
|
|
|
3076
3211
|
if (drag.to < drag.from && i >= drag.to && i < drag.from) shift = h;
|
|
3077
3212
|
}
|
|
3078
3213
|
const following = drag?.id === id;
|
|
3079
|
-
return /* @__PURE__ */
|
|
3214
|
+
return /* @__PURE__ */ React11.createElement(
|
|
3080
3215
|
TableRow,
|
|
3081
3216
|
{
|
|
3082
3217
|
key: id,
|
|
@@ -3091,7 +3226,7 @@ function DataTable({
|
|
|
3091
3226
|
if (!e.target.closest("button, a, input, label, select, textarea")) onRowClick(r);
|
|
3092
3227
|
} : void 0
|
|
3093
3228
|
},
|
|
3094
|
-
movable && /* @__PURE__ */
|
|
3229
|
+
movable && /* @__PURE__ */ React11.createElement(TableCell, { className: "alt-td-grip" }, /* @__PURE__ */ React11.createElement(
|
|
3095
3230
|
"button",
|
|
3096
3231
|
{
|
|
3097
3232
|
type: "button",
|
|
@@ -3107,18 +3242,18 @@ function DataTable({
|
|
|
3107
3242
|
if (held?.id === id && !drag) setTimeout(() => setHeld((x) => x?.id === id && document.activeElement?.closest(`tr[data-row="${CSS.escape(id)}"]`) === null ? null : x), 0);
|
|
3108
3243
|
}
|
|
3109
3244
|
},
|
|
3110
|
-
/* @__PURE__ */
|
|
3245
|
+
/* @__PURE__ */ React11.createElement(GripIcon, null)
|
|
3111
3246
|
)),
|
|
3112
|
-
selectable && /* @__PURE__ */
|
|
3247
|
+
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) })),
|
|
3113
3248
|
columns.map((c, ci) => {
|
|
3114
3249
|
const content = c.cell ? c.cell(r) : String(r[c.key] ?? "");
|
|
3115
|
-
return /* @__PURE__ */
|
|
3250
|
+
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);
|
|
3116
3251
|
})
|
|
3117
3252
|
);
|
|
3118
3253
|
}))
|
|
3119
|
-
), /* @__PURE__ */
|
|
3254
|
+
), /* @__PURE__ */ React11.createElement("span", { className: "alt-sr", "aria-live": "polite" }, selectable && sel.length ? `${sel.length} selected. ` : "", said));
|
|
3120
3255
|
}
|
|
3121
|
-
var BoardCtx =
|
|
3256
|
+
var BoardCtx = React11.createContext(null);
|
|
3122
3257
|
function readBoard(root) {
|
|
3123
3258
|
return Array.from(root.querySelectorAll("[data-board-col]")).map((col) => {
|
|
3124
3259
|
const list = col.querySelector(".alt-board-list");
|
|
@@ -3165,18 +3300,18 @@ function plan(cols, id, cx2, cy, h) {
|
|
|
3165
3300
|
}
|
|
3166
3301
|
return { to: { column: tc.id, index }, shifts, slotTop, gap: tc.gap };
|
|
3167
3302
|
}
|
|
3168
|
-
var Board =
|
|
3169
|
-
const root =
|
|
3170
|
-
|
|
3171
|
-
const hintId =
|
|
3172
|
-
const [carry, setCarry] =
|
|
3173
|
-
const [kb, setKb] =
|
|
3174
|
-
const [landing, setLanding] =
|
|
3175
|
-
const [said, setSaid] =
|
|
3176
|
-
const start =
|
|
3177
|
-
const dragged =
|
|
3303
|
+
var Board = React11.forwardRef(function Board2({ onMove, className, children, ...rest }, ref) {
|
|
3304
|
+
const root = React11.useRef(null);
|
|
3305
|
+
React11.useImperativeHandle(ref, () => root.current);
|
|
3306
|
+
const hintId = React11.useId();
|
|
3307
|
+
const [carry, setCarry] = React11.useState(null);
|
|
3308
|
+
const [kb, setKb] = React11.useState(null);
|
|
3309
|
+
const [landing, setLanding] = React11.useState(null);
|
|
3310
|
+
const [said, setSaid] = React11.useState("");
|
|
3311
|
+
const start = React11.useRef(null);
|
|
3312
|
+
const dragged = React11.useRef(false);
|
|
3178
3313
|
useCarry(root, "[data-board-card]", "data-board-card");
|
|
3179
|
-
|
|
3314
|
+
React11.useEffect(() => {
|
|
3180
3315
|
if (!landing) return;
|
|
3181
3316
|
const t = setTimeout(() => setLanding(null), 450);
|
|
3182
3317
|
return () => clearTimeout(t);
|
|
@@ -3305,17 +3440,17 @@ var Board = React10.forwardRef(function Board2({ onMove, className, children, ..
|
|
|
3305
3440
|
return d;
|
|
3306
3441
|
};
|
|
3307
3442
|
const ctx = { carry, kb, landing, hintId, onPointerDown, onPointerMove, onPointerUp, onKeyDown, onBlur, swallowClick };
|
|
3308
|
-
return /* @__PURE__ */
|
|
3443
|
+
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)));
|
|
3309
3444
|
});
|
|
3310
3445
|
function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollapsedChange, collapsible, className, children, ...rest }) {
|
|
3311
|
-
const ctx =
|
|
3446
|
+
const ctx = React11.useContext(BoardCtx);
|
|
3312
3447
|
const [isCollapsed, setCollapsed] = useControllable(collapsed, defaultCollapsed, onCollapsedChange);
|
|
3313
|
-
const count =
|
|
3448
|
+
const count = React11.Children.toArray(children).filter(React11.isValidElement).length;
|
|
3314
3449
|
const label = typeof title === "string" ? title : id;
|
|
3315
3450
|
const carry = ctx?.carry;
|
|
3316
3451
|
const over = carry ? carry.to.column === id : ctx?.kb?.at.column === id;
|
|
3317
3452
|
const receiving = !!carry && carry.to.column === id && carry.from.column !== id && !isCollapsed;
|
|
3318
|
-
return /* @__PURE__ */
|
|
3453
|
+
return /* @__PURE__ */ React11.createElement(
|
|
3319
3454
|
"section",
|
|
3320
3455
|
{
|
|
3321
3456
|
className: cx("alt-board-col", className),
|
|
@@ -3326,7 +3461,7 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
|
|
|
3326
3461
|
"data-over": over ? "" : void 0,
|
|
3327
3462
|
...rest
|
|
3328
3463
|
},
|
|
3329
|
-
/* @__PURE__ */
|
|
3464
|
+
/* @__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(
|
|
3330
3465
|
Button,
|
|
3331
3466
|
{
|
|
3332
3467
|
variant: "ghost",
|
|
@@ -3338,20 +3473,20 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
|
|
|
3338
3473
|
"data-collapsed": isCollapsed ? "" : void 0,
|
|
3339
3474
|
onClick: () => setCollapsed(!isCollapsed)
|
|
3340
3475
|
},
|
|
3341
|
-
/* @__PURE__ */
|
|
3476
|
+
/* @__PURE__ */ React11.createElement(Icons.ChevronDown, null)
|
|
3342
3477
|
)),
|
|
3343
|
-
isCollapsed ? /* @__PURE__ */
|
|
3478
|
+
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"))
|
|
3344
3479
|
);
|
|
3345
3480
|
}
|
|
3346
|
-
var BoardCard =
|
|
3347
|
-
const ctx =
|
|
3481
|
+
var BoardCard = React11.forwardRef(function BoardCard2({ id, label, heldBy, settle, className, style, onClickCapture, children, ...rest }, ref) {
|
|
3482
|
+
const ctx = React11.useContext(BoardCtx);
|
|
3348
3483
|
const depth = useDepth({ heldBy, settle });
|
|
3349
3484
|
const carry = ctx?.carry;
|
|
3350
3485
|
const following = carry?.id === id;
|
|
3351
3486
|
const carried = following || ctx?.kb?.id === id;
|
|
3352
3487
|
const shift = carry?.shifts[id];
|
|
3353
3488
|
const transform = following ? `translate(${carry.dx}px, ${carry.dy}px)` : shift ? `translateY(${shift}px)` : void 0;
|
|
3354
|
-
return /* @__PURE__ */
|
|
3489
|
+
return /* @__PURE__ */ React11.createElement(
|
|
3355
3490
|
"div",
|
|
3356
3491
|
{
|
|
3357
3492
|
ref,
|