@vaam-apps/ui 0.1.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/CHANGELOG.md +104 -0
- package/LICENSE +21 -0
- package/README.md +286 -0
- package/dist/components/data/code.d.ts +37 -0
- package/dist/components/data/code.d.ts.map +1 -0
- package/dist/components/data/code.js +37 -0
- package/dist/components/data/code.js.map +1 -0
- package/dist/components/data/copy-button.d.ts +39 -0
- package/dist/components/data/copy-button.d.ts.map +1 -0
- package/dist/components/data/copy-button.js +50 -0
- package/dist/components/data/copy-button.js.map +1 -0
- package/dist/components/data/detail-row.d.ts +69 -0
- package/dist/components/data/detail-row.d.ts.map +1 -0
- package/dist/components/data/detail-row.js +27 -0
- package/dist/components/data/detail-row.js.map +1 -0
- package/dist/components/data/id-display.d.ts +33 -0
- package/dist/components/data/id-display.d.ts.map +1 -0
- package/dist/components/data/id-display.js +25 -0
- package/dist/components/data/id-display.js.map +1 -0
- package/dist/components/data/masked-value.d.ts +47 -0
- package/dist/components/data/masked-value.d.ts.map +1 -0
- package/dist/components/data/masked-value.js +46 -0
- package/dist/components/data/masked-value.js.map +1 -0
- package/dist/components/data/money.d.ts +28 -0
- package/dist/components/data/money.d.ts.map +1 -0
- package/dist/components/data/money.js +22 -0
- package/dist/components/data/money.js.map +1 -0
- package/dist/components/data/phone-display.d.ts +45 -0
- package/dist/components/data/phone-display.d.ts.map +1 -0
- package/dist/components/data/phone-display.js +23 -0
- package/dist/components/data/phone-display.js.map +1 -0
- package/dist/components/data/stat-tile.d.ts +33 -0
- package/dist/components/data/stat-tile.d.ts.map +1 -0
- package/dist/components/data/stat-tile.js +18 -0
- package/dist/components/data/stat-tile.js.map +1 -0
- package/dist/components/data/timestamp-display.d.ts +14 -0
- package/dist/components/data/timestamp-display.d.ts.map +1 -0
- package/dist/components/data/timestamp-display.js +77 -0
- package/dist/components/data/timestamp-display.js.map +1 -0
- package/dist/components/patterns/inline-banner.d.ts +22 -0
- package/dist/components/patterns/inline-banner.d.ts.map +1 -0
- package/dist/components/patterns/inline-banner.js +11 -0
- package/dist/components/patterns/inline-banner.js.map +1 -0
- package/dist/components/patterns/inline-empty-state.d.ts +20 -0
- package/dist/components/patterns/inline-empty-state.d.ts.map +1 -0
- package/dist/components/patterns/inline-empty-state.js +11 -0
- package/dist/components/patterns/inline-empty-state.js.map +1 -0
- package/dist/components/patterns/live-row.d.ts +23 -0
- package/dist/components/patterns/live-row.d.ts.map +1 -0
- package/dist/components/patterns/live-row.js +48 -0
- package/dist/components/patterns/live-row.js.map +1 -0
- package/dist/components/patterns/payload-inspector.d.ts +25 -0
- package/dist/components/patterns/payload-inspector.d.ts.map +1 -0
- package/dist/components/patterns/payload-inspector.js +33 -0
- package/dist/components/patterns/payload-inspector.js.map +1 -0
- package/dist/components/patterns/route-skeleton.d.ts +15 -0
- package/dist/components/patterns/route-skeleton.d.ts.map +1 -0
- package/dist/components/patterns/route-skeleton.js +7 -0
- package/dist/components/patterns/route-skeleton.js.map +1 -0
- package/dist/components/patterns/screen-layout.d.ts +14 -0
- package/dist/components/patterns/screen-layout.d.ts.map +1 -0
- package/dist/components/patterns/screen-layout.js +11 -0
- package/dist/components/patterns/screen-layout.js.map +1 -0
- package/dist/components/patterns/stale-write-banner.d.ts +26 -0
- package/dist/components/patterns/stale-write-banner.d.ts.map +1 -0
- package/dist/components/patterns/stale-write-banner.js +28 -0
- package/dist/components/patterns/stale-write-banner.js.map +1 -0
- package/dist/components/patterns/state-timeline.d.ts +58 -0
- package/dist/components/patterns/state-timeline.d.ts.map +1 -0
- package/dist/components/patterns/state-timeline.js +103 -0
- package/dist/components/patterns/state-timeline.js.map +1 -0
- package/dist/components/primitives/badge.d.ts +27 -0
- package/dist/components/primitives/badge.d.ts.map +1 -0
- package/dist/components/primitives/badge.js +33 -0
- package/dist/components/primitives/badge.js.map +1 -0
- package/dist/components/primitives/button.d.ts +12 -0
- package/dist/components/primitives/button.d.ts.map +1 -0
- package/dist/components/primitives/button.js +42 -0
- package/dist/components/primitives/button.js.map +1 -0
- package/dist/components/primitives/calendar.d.ts +39 -0
- package/dist/components/primitives/calendar.d.ts.map +1 -0
- package/dist/components/primitives/calendar.js +102 -0
- package/dist/components/primitives/calendar.js.map +1 -0
- package/dist/components/primitives/card.d.ts +24 -0
- package/dist/components/primitives/card.d.ts.map +1 -0
- package/dist/components/primitives/card.js +28 -0
- package/dist/components/primitives/card.js.map +1 -0
- package/dist/components/primitives/checkbox.d.ts +42 -0
- package/dist/components/primitives/checkbox.d.ts.map +1 -0
- package/dist/components/primitives/checkbox.js +31 -0
- package/dist/components/primitives/checkbox.js.map +1 -0
- package/dist/components/primitives/chip-select.d.ts +38 -0
- package/dist/components/primitives/chip-select.d.ts.map +1 -0
- package/dist/components/primitives/chip-select.js +25 -0
- package/dist/components/primitives/chip-select.js.map +1 -0
- package/dist/components/primitives/command-menu.d.ts +54 -0
- package/dist/components/primitives/command-menu.d.ts.map +1 -0
- package/dist/components/primitives/command-menu.js +24 -0
- package/dist/components/primitives/command-menu.js.map +1 -0
- package/dist/components/primitives/confirm-dialog.d.ts +52 -0
- package/dist/components/primitives/confirm-dialog.d.ts.map +1 -0
- package/dist/components/primitives/confirm-dialog.js +30 -0
- package/dist/components/primitives/confirm-dialog.js.map +1 -0
- package/dist/components/primitives/date-picker.d.ts +68 -0
- package/dist/components/primitives/date-picker.d.ts.map +1 -0
- package/dist/components/primitives/date-picker.js +107 -0
- package/dist/components/primitives/date-picker.js.map +1 -0
- package/dist/components/primitives/dialog.d.ts +50 -0
- package/dist/components/primitives/dialog.d.ts.map +1 -0
- package/dist/components/primitives/dialog.js +90 -0
- package/dist/components/primitives/dialog.js.map +1 -0
- package/dist/components/primitives/drawer.d.ts +71 -0
- package/dist/components/primitives/drawer.d.ts.map +1 -0
- package/dist/components/primitives/drawer.js +93 -0
- package/dist/components/primitives/drawer.js.map +1 -0
- package/dist/components/primitives/dropdown-menu.d.ts +40 -0
- package/dist/components/primitives/dropdown-menu.d.ts.map +1 -0
- package/dist/components/primitives/dropdown-menu.js +53 -0
- package/dist/components/primitives/dropdown-menu.js.map +1 -0
- package/dist/components/primitives/form-field.d.ts +94 -0
- package/dist/components/primitives/form-field.d.ts.map +1 -0
- package/dist/components/primitives/form-field.js +27 -0
- package/dist/components/primitives/form-field.js.map +1 -0
- package/dist/components/primitives/inline-confirm.d.ts +62 -0
- package/dist/components/primitives/inline-confirm.d.ts.map +1 -0
- package/dist/components/primitives/inline-confirm.js +11 -0
- package/dist/components/primitives/inline-confirm.js.map +1 -0
- package/dist/components/primitives/input.d.ts +4 -0
- package/dist/components/primitives/input.d.ts.map +1 -0
- package/dist/components/primitives/input.js +13 -0
- package/dist/components/primitives/input.js.map +1 -0
- package/dist/components/primitives/label.d.ts +26 -0
- package/dist/components/primitives/label.d.ts.map +1 -0
- package/dist/components/primitives/label.js +33 -0
- package/dist/components/primitives/label.js.map +1 -0
- package/dist/components/primitives/pagination.d.ts +54 -0
- package/dist/components/primitives/pagination.d.ts.map +1 -0
- package/dist/components/primitives/pagination.js +31 -0
- package/dist/components/primitives/pagination.js.map +1 -0
- package/dist/components/primitives/popover.d.ts +12 -0
- package/dist/components/primitives/popover.d.ts.map +1 -0
- package/dist/components/primitives/popover.js +22 -0
- package/dist/components/primitives/popover.js.map +1 -0
- package/dist/components/primitives/progress.d.ts +25 -0
- package/dist/components/primitives/progress.d.ts.map +1 -0
- package/dist/components/primitives/progress.js +25 -0
- package/dist/components/primitives/progress.js.map +1 -0
- package/dist/components/primitives/radio-group.d.ts +47 -0
- package/dist/components/primitives/radio-group.d.ts.map +1 -0
- package/dist/components/primitives/radio-group.js +11 -0
- package/dist/components/primitives/radio-group.js.map +1 -0
- package/dist/components/primitives/select.d.ts +39 -0
- package/dist/components/primitives/select.d.ts.map +1 -0
- package/dist/components/primitives/select.js +142 -0
- package/dist/components/primitives/select.js.map +1 -0
- package/dist/components/primitives/separator.d.ts +9 -0
- package/dist/components/primitives/separator.d.ts.map +1 -0
- package/dist/components/primitives/separator.js +16 -0
- package/dist/components/primitives/separator.js.map +1 -0
- package/dist/components/primitives/side-nav.d.ts +65 -0
- package/dist/components/primitives/side-nav.d.ts.map +1 -0
- package/dist/components/primitives/side-nav.js +100 -0
- package/dist/components/primitives/side-nav.js.map +1 -0
- package/dist/components/primitives/skeleton.d.ts +22 -0
- package/dist/components/primitives/skeleton.d.ts.map +1 -0
- package/dist/components/primitives/skeleton.js +25 -0
- package/dist/components/primitives/skeleton.js.map +1 -0
- package/dist/components/primitives/spinner.d.ts +20 -0
- package/dist/components/primitives/spinner.d.ts.map +1 -0
- package/dist/components/primitives/spinner.js +21 -0
- package/dist/components/primitives/spinner.js.map +1 -0
- package/dist/components/primitives/switch.d.ts +29 -0
- package/dist/components/primitives/switch.d.ts.map +1 -0
- package/dist/components/primitives/switch.js +24 -0
- package/dist/components/primitives/switch.js.map +1 -0
- package/dist/components/primitives/table.d.ts +23 -0
- package/dist/components/primitives/table.d.ts.map +1 -0
- package/dist/components/primitives/table.js +81 -0
- package/dist/components/primitives/table.js.map +1 -0
- package/dist/components/primitives/tabs.d.ts +38 -0
- package/dist/components/primitives/tabs.d.ts.map +1 -0
- package/dist/components/primitives/tabs.js +84 -0
- package/dist/components/primitives/tabs.js.map +1 -0
- package/dist/components/primitives/textarea.d.ts +4 -0
- package/dist/components/primitives/textarea.d.ts.map +1 -0
- package/dist/components/primitives/textarea.js +11 -0
- package/dist/components/primitives/textarea.js.map +1 -0
- package/dist/components/primitives/toast.d.ts +24 -0
- package/dist/components/primitives/toast.d.ts.map +1 -0
- package/dist/components/primitives/toast.js +58 -0
- package/dist/components/primitives/toast.js.map +1 -0
- package/dist/components/primitives/tooltip.d.ts +30 -0
- package/dist/components/primitives/tooltip.d.ts.map +1 -0
- package/dist/components/primitives/tooltip.js +6 -0
- package/dist/components/primitives/tooltip.js.map +1 -0
- package/dist/components/status/state-chip.d.ts +53 -0
- package/dist/components/status/state-chip.d.ts.map +1 -0
- package/dist/components/status/state-chip.js +8 -0
- package/dist/components/status/state-chip.js.map +1 -0
- package/dist/components/status/state-mark.d.ts +21 -0
- package/dist/components/status/state-mark.d.ts.map +1 -0
- package/dist/components/status/state-mark.js +90 -0
- package/dist/components/status/state-mark.js.map +1 -0
- package/dist/components/status/status-pill.d.ts +62 -0
- package/dist/components/status/status-pill.d.ts.map +1 -0
- package/dist/components/status/status-pill.js +65 -0
- package/dist/components/status/status-pill.js.map +1 -0
- package/dist/components/status/status-tokens.d.ts +110 -0
- package/dist/components/status/status-tokens.d.ts.map +1 -0
- package/dist/components/status/status-tokens.js +102 -0
- package/dist/components/status/status-tokens.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cn.d.ts +11 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +78 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/money.d.ts +73 -0
- package/dist/lib/money.d.ts.map +1 -0
- package/dist/lib/money.js +123 -0
- package/dist/lib/money.js.map +1 -0
- package/dist/lib/omit-undefined.d.ts +17 -0
- package/dist/lib/omit-undefined.d.ts.map +1 -0
- package/dist/lib/omit-undefined.js +24 -0
- package/dist/lib/omit-undefined.js.map +1 -0
- package/package.json +100 -0
- package/src/components/data/code.tsx +43 -0
- package/src/components/data/copy-button.tsx +97 -0
- package/src/components/data/detail-row.tsx +113 -0
- package/src/components/data/id-display.tsx +49 -0
- package/src/components/data/masked-value.tsx +96 -0
- package/src/components/data/money.tsx +46 -0
- package/src/components/data/phone-display.tsx +60 -0
- package/src/components/data/stat-tile.tsx +68 -0
- package/src/components/data/timestamp-display.tsx +106 -0
- package/src/components/patterns/inline-banner.tsx +60 -0
- package/src/components/patterns/inline-empty-state.tsx +45 -0
- package/src/components/patterns/live-row.tsx +75 -0
- package/src/components/patterns/payload-inspector.tsx +157 -0
- package/src/components/patterns/route-skeleton.tsx +77 -0
- package/src/components/patterns/screen-layout.tsx +44 -0
- package/src/components/patterns/stale-write-banner.tsx +44 -0
- package/src/components/patterns/state-timeline.tsx +229 -0
- package/src/components/primitives/badge.tsx +40 -0
- package/src/components/primitives/button.tsx +54 -0
- package/src/components/primitives/calendar.tsx +136 -0
- package/src/components/primitives/card.tsx +70 -0
- package/src/components/primitives/checkbox.tsx +101 -0
- package/src/components/primitives/chip-select.tsx +105 -0
- package/src/components/primitives/command-menu.tsx +92 -0
- package/src/components/primitives/confirm-dialog.tsx +109 -0
- package/src/components/primitives/date-picker.tsx +271 -0
- package/src/components/primitives/dialog.tsx +195 -0
- package/src/components/primitives/drawer.tsx +326 -0
- package/src/components/primitives/dropdown-menu.tsx +128 -0
- package/src/components/primitives/form-field.tsx +136 -0
- package/src/components/primitives/inline-confirm.tsx +118 -0
- package/src/components/primitives/input.tsx +21 -0
- package/src/components/primitives/label.tsx +43 -0
- package/src/components/primitives/pagination.tsx +110 -0
- package/src/components/primitives/popover.tsx +41 -0
- package/src/components/primitives/progress.tsx +66 -0
- package/src/components/primitives/radio-group.tsx +90 -0
- package/src/components/primitives/select.tsx +254 -0
- package/src/components/primitives/separator.tsx +49 -0
- package/src/components/primitives/side-nav.tsx +253 -0
- package/src/components/primitives/skeleton.tsx +25 -0
- package/src/components/primitives/spinner.tsx +39 -0
- package/src/components/primitives/switch.tsx +74 -0
- package/src/components/primitives/table.tsx +157 -0
- package/src/components/primitives/tabs.tsx +163 -0
- package/src/components/primitives/textarea.tsx +21 -0
- package/src/components/primitives/toast.tsx +117 -0
- package/src/components/primitives/tooltip.tsx +38 -0
- package/src/components/status/state-chip.tsx +70 -0
- package/src/components/status/state-mark.tsx +154 -0
- package/src/components/status/status-pill.tsx +153 -0
- package/src/components/status/status-tokens.ts +173 -0
- package/src/index.ts +96 -0
- package/src/lib/cn.ts +168 -0
- package/src/lib/money.ts +164 -0
- package/src/lib/omit-undefined.ts +25 -0
- package/src/styles/theme.css +381 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type TableRowProps } from "../primitives/table.js";
|
|
2
|
+
import type { StatusHue } from "../status/status-tokens.js";
|
|
3
|
+
export interface LiveRowProps extends TableRowProps {
|
|
4
|
+
/** Any value that changes to trigger a wash — pass the row's `@version`, an exact change key immune to clock skew. */
|
|
5
|
+
washTrigger: string | number;
|
|
6
|
+
/** The destination state's hue, so the wash tints toward where the row landed. */
|
|
7
|
+
washHue?: StatusHue;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The row-level half of the design doc's `LiveTable`/`LiveRow` contract
|
|
11
|
+
* (§5.3, §6.5 rule 4): "in-place status change never moves a row" — this
|
|
12
|
+
* wraps `TableRow` with the 240ms wash-then-decay on a status change,
|
|
13
|
+
* nothing else moves or resizes. The full `LiveTable` (scroll-position-
|
|
14
|
+
* dependent buffered insertion, the sticky "N new" pill, sort-mode
|
|
15
|
+
* switching) is a later, screen-level task — this is the reusable unit it
|
|
16
|
+
* will be built on, shipped now so the wash behaviour isn't retrofitted
|
|
17
|
+
* per-screen later.
|
|
18
|
+
*
|
|
19
|
+
* Reduced motion (§3.8 rule 3): the wash becomes a static hold instead of
|
|
20
|
+
* a timed decay — the signal must survive, only the animation may not.
|
|
21
|
+
*/
|
|
22
|
+
export declare function LiveRow({ washTrigger, washHue, className, children, ...props }: LiveRowProps): import("react").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=live-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-row.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/live-row.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,sHAAsH;IACtH,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,kFAAkF;IAClF,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,EACtB,WAAW,EACX,OAAmB,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,YAAY,+BA+Bd"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
import { TableRow } from "../primitives/table.js";
|
|
6
|
+
const WASH_BG_CLASS = {
|
|
7
|
+
neutral: "bg-state-neutral-fg/10",
|
|
8
|
+
success: "bg-state-success-fg/10",
|
|
9
|
+
warning: "bg-state-warning-fg/10",
|
|
10
|
+
danger: "bg-state-danger-fg/10",
|
|
11
|
+
uncertain: "bg-state-uncertain-fg/10",
|
|
12
|
+
expired: "bg-state-expired-fg/10",
|
|
13
|
+
parked: "bg-state-parked-fg/10",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The row-level half of the design doc's `LiveTable`/`LiveRow` contract
|
|
17
|
+
* (§5.3, §6.5 rule 4): "in-place status change never moves a row" — this
|
|
18
|
+
* wraps `TableRow` with the 240ms wash-then-decay on a status change,
|
|
19
|
+
* nothing else moves or resizes. The full `LiveTable` (scroll-position-
|
|
20
|
+
* dependent buffered insertion, the sticky "N new" pill, sort-mode
|
|
21
|
+
* switching) is a later, screen-level task — this is the reusable unit it
|
|
22
|
+
* will be built on, shipped now so the wash behaviour isn't retrofitted
|
|
23
|
+
* per-screen later.
|
|
24
|
+
*
|
|
25
|
+
* Reduced motion (§3.8 rule 3): the wash becomes a static hold instead of
|
|
26
|
+
* a timed decay — the signal must survive, only the animation may not.
|
|
27
|
+
*/
|
|
28
|
+
export function LiveRow({ washTrigger, washHue = "neutral", className, children, ...props }) {
|
|
29
|
+
const [washing, setWashing] = useState(false);
|
|
30
|
+
const previousTrigger = useRef(washTrigger);
|
|
31
|
+
const reducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (previousTrigger.current === washTrigger)
|
|
34
|
+
return;
|
|
35
|
+
previousTrigger.current = washTrigger;
|
|
36
|
+
setWashing(true);
|
|
37
|
+
const holdMs = reducedMotion ? 1200 : 400 + 240 + 600;
|
|
38
|
+
const timeout = setTimeout(() => setWashing(false), holdMs);
|
|
39
|
+
return () => clearTimeout(timeout);
|
|
40
|
+
}, [washTrigger, reducedMotion]);
|
|
41
|
+
return (_jsx(TableRow, { className: cn(washing && [
|
|
42
|
+
WASH_BG_CLASS[washHue],
|
|
43
|
+
reducedMotion
|
|
44
|
+
? "transition-none"
|
|
45
|
+
: "transition-colors duration-[var(--dur-state)] ease-out",
|
|
46
|
+
], className), ...props, children: children }));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=live-row.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-row.js","sourceRoot":"","sources":["../../../src/components/patterns/live-row.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAsB,MAAM,qBAAqB,CAAC;AAUnE,MAAM,aAAa,GAA8B;IAC/C,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,wBAAwB;IACjC,MAAM,EAAE,uBAAuB;IAC/B,SAAS,EAAE,0BAA0B;IACrC,OAAO,EAAE,wBAAwB;IACjC,MAAM,EAAE,uBAAuB;CAChC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,OAAO,CAAC,EACtB,WAAW,EACX,OAAO,GAAG,SAAS,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACK;IACb,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,aAAa,GACjB,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO,CAAC;IAEjG,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,eAAe,CAAC,OAAO,KAAK,WAAW;YAAE,OAAO;QACpD,eAAe,CAAC,OAAO,GAAG,WAAW,CAAC;QACtC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;QACtD,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAEjC,OAAO,CACL,KAAC,QAAQ,IACP,SAAS,EAAE,EAAE,CACX,OAAO,IAAI;YACT,aAAa,CAAC,OAAO,CAAC;YACtB,aAAa;gBACX,CAAC,CAAC,iBAAiB;gBACnB,CAAC,CAAC,wDAAwD;SAC7D,EACD,SAAS,CACV,KACG,KAAK,YAER,QAAQ,GACA,CACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface PayloadExchange {
|
|
2
|
+
direction: "request" | "response" | "callback";
|
|
3
|
+
method?: string;
|
|
4
|
+
url?: string;
|
|
5
|
+
status?: number;
|
|
6
|
+
durationMs?: number;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
body?: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PayloadInspectorProps {
|
|
12
|
+
exchanges: PayloadExchange[];
|
|
13
|
+
defaultOpen?: number;
|
|
14
|
+
/** Bodies over this size collapse behind an explicit "load full payload" action. */
|
|
15
|
+
maxInlineBytes?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Raw provider request/response and DLR bodies, verbatim (design doc §5.3).
|
|
19
|
+
* No syntax-highlighting palette on purpose (§1.3): a rainbow JSON block
|
|
20
|
+
* would be the loudest thing on a diagnostic screen. Uses native
|
|
21
|
+
* `<details>` for the accordion behaviour — free keyboard/ARIA semantics,
|
|
22
|
+
* no extra Radix dependency needed for a plain expand/collapse.
|
|
23
|
+
*/
|
|
24
|
+
export declare function PayloadInspector({ exchanges, defaultOpen, maxInlineBytes, }: PayloadInspectorProps): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=payload-inspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-inspector.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/payload-inspector.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA+ED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,WAAe,EACf,cAAuB,GACxB,EAAE,qBAAqB,+BAoCvB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
// D18: `Tabs` was rebuilt as `ValueTabs` (Headless UI `TabGroup` behind a
|
|
6
|
+
// value-based adapter) — aliased on import so nothing below this line
|
|
7
|
+
// changes; see tabs.tsx's own module doc for the full mechanism.
|
|
8
|
+
import { ValueTabs as Tabs, ValueTabsContent as TabsContent, ValueTabsList as TabsList, ValueTabsTrigger as TabsTrigger, } from "../primitives/tabs.js";
|
|
9
|
+
function StatusChip({ status }) {
|
|
10
|
+
if (status == null)
|
|
11
|
+
return null;
|
|
12
|
+
const ok = status < 400;
|
|
13
|
+
return (_jsx("span", { className: cn("rounded-sm border px-1.5 py-0.5 font-mono text-caption", ok
|
|
14
|
+
? "border-edge text-muted-foreground"
|
|
15
|
+
: "border-state-danger-border text-state-danger-fg"), children: status }));
|
|
16
|
+
}
|
|
17
|
+
function ExchangeBody({ exchange, maxInlineBytes, }) {
|
|
18
|
+
const [forceLoad, setForceLoad] = useState(false);
|
|
19
|
+
const body = exchange.body ?? "";
|
|
20
|
+
const oversized = !forceLoad && body.length > maxInlineBytes;
|
|
21
|
+
return (_jsxs(Tabs, { defaultValue: "body", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "body", children: "Body" }), _jsx(TabsTrigger, { value: "headers", children: "Headers" }), exchange.error != null && _jsx(TabsTrigger, { value: "error", children: "Error" })] }), _jsx(TabsContent, { value: "body", children: body.length === 0 ? (_jsx("p", { className: "py-3 text-caption text-subtle-foreground", children: "No response body was recorded." })) : oversized ? (_jsxs("button", { type: "button", onClick: () => setForceLoad(true), className: "py-3 text-caption text-foreground underline", children: ["Load full payload (", (body.length / 1024).toFixed(1), " KB)"] })) : (_jsx("pre", { className: "max-h-96 overflow-auto rounded-sm bg-base-100 p-3 font-mono text-[12px] text-foreground", children: body })) }), _jsx(TabsContent, { value: "headers", children: exchange.headers == null || Object.keys(exchange.headers).length === 0 ? (_jsx("p", { className: "py-3 text-caption text-subtle-foreground", children: "No headers recorded." })) : (_jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 py-2 font-mono text-[12px]", children: Object.entries(exchange.headers).map(([key, value]) => (_jsxs("div", { className: "contents", children: [_jsx("dt", { className: "text-subtle-foreground", children: key }), _jsx("dd", { className: "break-all text-foreground", children: value })] }, key))) })) }), exchange.error != null && (_jsx(TabsContent, { value: "error", children: _jsx("pre", { className: "max-h-96 overflow-auto rounded-sm border border-state-danger-border bg-state-danger-bg p-3 font-mono text-[12px] text-state-danger-fg", children: exchange.error }) }))] }));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Raw provider request/response and DLR bodies, verbatim (design doc §5.3).
|
|
25
|
+
* No syntax-highlighting palette on purpose (§1.3): a rainbow JSON block
|
|
26
|
+
* would be the loudest thing on a diagnostic screen. Uses native
|
|
27
|
+
* `<details>` for the accordion behaviour — free keyboard/ARIA semantics,
|
|
28
|
+
* no extra Radix dependency needed for a plain expand/collapse.
|
|
29
|
+
*/
|
|
30
|
+
export function PayloadInspector({ exchanges, defaultOpen = 0, maxInlineBytes = 262144, }) {
|
|
31
|
+
return (_jsx("div", { className: "flex flex-col gap-2", children: exchanges.map((exchange, i) => (_jsxs("details", { open: i === defaultOpen, className: "rounded-sm border border-edge bg-surface-2", children: [_jsxs("summary", { className: "flex cursor-pointer list-none items-center gap-2 px-3 py-2 text-body", children: [_jsx("span", { className: "font-mono text-micro text-muted-foreground", children: exchange.direction }), exchange.method != null && (_jsx("span", { className: "font-mono text-caption text-foreground", children: exchange.method })), exchange.url != null && (_jsx("span", { className: "truncate font-mono text-caption text-subtle-foreground", children: exchange.url })), _jsxs("span", { className: "ml-auto flex items-center gap-2", children: [_jsx(StatusChip, { status: exchange.status }), exchange.durationMs != null && (_jsxs("span", { className: "font-mono text-caption text-subtle-foreground", children: [exchange.durationMs, "ms"] }))] })] }), _jsx("div", { className: "border-edge border-t px-3 pb-3", children: _jsx(ExchangeBody, { exchange: exchange, maxInlineBytes: maxInlineBytes }) })] }, i))) }));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=payload-inspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-inspector.js","sourceRoot":"","sources":["../../../src/components/patterns/payload-inspector.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface RouteSkeletonProps {
|
|
2
|
+
/** How many table-row-shaped blocks to render. Doesn't need to match the
|
|
3
|
+
* real screen's row height exactly (`Skeleton`'s own doc asks for that
|
|
4
|
+
* only where a skeleton stands in for an already-mounted, known-shape
|
|
5
|
+
* table) — this fallback exists for a `<main>` that hasn't rendered
|
|
6
|
+
* *anything* app-specific yet, not a loading row inside a mounted
|
|
7
|
+
* table. */
|
|
8
|
+
rows?: number;
|
|
9
|
+
/** Whether to render a filter-bar-shaped skeleton row above the table
|
|
10
|
+
* rows — most of the eight screens this serves have one (a search box,
|
|
11
|
+
* a couple of selects); a couple don't. */
|
|
12
|
+
withFilterBar?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function RouteSkeleton({ rows, withFilterBar }: RouteSkeletonProps): import("react").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=route-skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/route-skeleton.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,kBAAkB;IACjC;;;;;gBAKY;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;+CAE2C;IAC3C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAQ,EAAE,aAAoB,EAAE,EAAE,kBAAkB,+BAgCnF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Skeleton } from "../primitives/skeleton.js";
|
|
3
|
+
import { ScreenStack } from "./screen-layout.js";
|
|
4
|
+
export function RouteSkeleton({ rows = 6, withFilterBar = true }) {
|
|
5
|
+
return (_jsxs(ScreenStack, { children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-7 w-48" }), _jsx(Skeleton, { className: "h-4 w-80" })] }), withFilterBar && (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Skeleton, { className: "h-9 w-64" }), _jsx(Skeleton, { className: "h-9 w-32" }), _jsx(Skeleton, { className: "h-9 w-32" })] })), _jsx("div", { className: "flex flex-col gap-2", children: Array.from({ length: rows }, (_, i) => (_jsx(Skeleton, { className: "h-11 w-full" }, i))) })] }));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=route-skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-skeleton.js","sourceRoot":"","sources":["../../../src/components/patterns/route-skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA2C9C,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,aAAa,GAAG,IAAI,EAAsB;IAClF,OAAO,CACL,MAAC,WAAW,eAWV,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,EACL,aAAa,IAAI,CAChB,eAAK,SAAS,EAAC,mCAAmC,aAChD,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,CACP,EACD,cAAK,SAAS,EAAC,qBAAqB,YACjC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAEtC,KAAC,QAAQ,IAAS,SAAS,EAAC,aAAa,IAA1B,CAAC,CAA4B,CAC7C,CAAC,GACE,IACM,CACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface ScreenStackProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
/** The page-level vertical rhythm every screen composes its sections into. */
|
|
7
|
+
export declare function ScreenStack({ children, className }: ScreenStackProps): import("react").JSX.Element;
|
|
8
|
+
export interface ScreenHeaderProps {
|
|
9
|
+
title: ReactNode;
|
|
10
|
+
description?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/** A screen's own `<h1>` + one-line description, styled once. */
|
|
13
|
+
export declare function ScreenHeader({ title, description }: ScreenHeaderProps): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=screen-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-layout.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/screen-layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBvC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAEpE;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,iBAAiB,+BASrE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
/** The page-level vertical rhythm every screen composes its sections into. */
|
|
4
|
+
export function ScreenStack({ children, className }) {
|
|
5
|
+
return _jsx("div", { className: cn("flex flex-col gap-6", className), children: children });
|
|
6
|
+
}
|
|
7
|
+
/** A screen's own `<h1>` + one-line description, styled once. */
|
|
8
|
+
export function ScreenHeader({ title, description }) {
|
|
9
|
+
return (_jsxs("header", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "font-medium text-foreground text-title", children: title }), description != null && (_jsx("p", { className: "max-w-xl text-body text-muted-foreground", children: description }))] }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=screen-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-layout.js","sourceRoot":"","sources":["../../../src/components/patterns/screen-layout.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAsBlC,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAoB;IACnE,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAO,CAAC;AAChF,CAAC;AAOD,iEAAiE;AACjE,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,WAAW,EAAqB;IACpE,OAAO,CACL,kBAAQ,SAAS,EAAC,qBAAqB,aACrC,aAAI,SAAS,EAAC,wCAAwC,YAAE,KAAK,GAAM,EAClE,WAAW,IAAI,IAAI,IAAI,CACtB,YAAG,SAAS,EAAC,0CAA0C,YAAE,WAAW,GAAK,CAC1E,IACM,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Someone else changed this row since it loaded" — the banner for a
|
|
3
|
+
* `412 Precondition Failed` save.
|
|
4
|
+
*
|
|
5
|
+
* Shared rather than route-local because the thing it reports is not
|
|
6
|
+
* route-local: #59 gave `@version` to ten operator-editable models and
|
|
7
|
+
* threaded ETag/`If-Match` through the generated REST layer, so *every*
|
|
8
|
+
* edit screen in the console can lose this race. `apps/` and `users/` each
|
|
9
|
+
* hand-rolled it; the rest will need it as their edit screens land.
|
|
10
|
+
*
|
|
11
|
+
* The two hand-rolled copies differed in exactly one way — one hardcoded
|
|
12
|
+
* its sentence, the other took a `message` prop. The prop version is
|
|
13
|
+
* strictly more general, so it wins, with the hardcoded sentence as the
|
|
14
|
+
* default so the common case stays a one-line call.
|
|
15
|
+
*
|
|
16
|
+
* `warning`, not `danger`: nothing was lost and nothing is broken. The
|
|
17
|
+
* write was *refused* precisely so the other operator's edit survives —
|
|
18
|
+
* which is the mechanism working, not failing. Reloading resolves it.
|
|
19
|
+
* `packages/gateway/src/errors.ts`'s `isStaleWriteError` exists to
|
|
20
|
+
* distinguish this from a genuine conflict for the same reason.
|
|
21
|
+
*/
|
|
22
|
+
export declare function StaleWriteBanner({ message, onReload, }: {
|
|
23
|
+
message?: string | undefined;
|
|
24
|
+
onReload: () => void;
|
|
25
|
+
}): import("react").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=stale-write-banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-write-banner.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/stale-write-banner.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,OAAoF,EACpF,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,+BAaA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "../primitives/button.js";
|
|
3
|
+
import { InlineBanner } from "./inline-banner.js";
|
|
4
|
+
/**
|
|
5
|
+
* "Someone else changed this row since it loaded" — the banner for a
|
|
6
|
+
* `412 Precondition Failed` save.
|
|
7
|
+
*
|
|
8
|
+
* Shared rather than route-local because the thing it reports is not
|
|
9
|
+
* route-local: #59 gave `@version` to ten operator-editable models and
|
|
10
|
+
* threaded ETag/`If-Match` through the generated REST layer, so *every*
|
|
11
|
+
* edit screen in the console can lose this race. `apps/` and `users/` each
|
|
12
|
+
* hand-rolled it; the rest will need it as their edit screens land.
|
|
13
|
+
*
|
|
14
|
+
* The two hand-rolled copies differed in exactly one way — one hardcoded
|
|
15
|
+
* its sentence, the other took a `message` prop. The prop version is
|
|
16
|
+
* strictly more general, so it wins, with the hardcoded sentence as the
|
|
17
|
+
* default so the common case stays a one-line call.
|
|
18
|
+
*
|
|
19
|
+
* `warning`, not `danger`: nothing was lost and nothing is broken. The
|
|
20
|
+
* write was *refused* precisely so the other operator's edit survives —
|
|
21
|
+
* which is the mechanism working, not failing. Reloading resolves it.
|
|
22
|
+
* `packages/gateway/src/errors.ts`'s `isStaleWriteError` exists to
|
|
23
|
+
* distinguish this from a genuine conflict for the same reason.
|
|
24
|
+
*/
|
|
25
|
+
export function StaleWriteBanner({ message = "Someone else changed this row since it loaded. Reload to see their edit.", onReload, }) {
|
|
26
|
+
return (_jsxs(InlineBanner, { variant: "warning", className: "flex items-center justify-between gap-3", children: [_jsx("span", { children: message }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: onReload, children: "Reload" })] }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=stale-write-banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-write-banner.js","sourceRoot":"","sources":["../../../src/components/patterns/stale-write-banner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,OAAO,GAAG,0EAA0E,EACpF,QAAQ,GAIT;IACC,OAAO,CACL,MAAC,YAAY,IAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,yCAAyC,aACjF,yBAAO,OAAO,GAAQ,EAKtB,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,IAAI,EAAC,OAAO,EAAE,QAAQ,uBAE5D,IACI,CAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { StatusSystem } from "../status/status-tokens.js";
|
|
2
|
+
import { type PayloadExchange } from "./payload-inspector.js";
|
|
3
|
+
export interface StateTransition<S extends string = string> {
|
|
4
|
+
toState: S;
|
|
5
|
+
/** ISO 8601 timestamp. */
|
|
6
|
+
at: string;
|
|
7
|
+
actor?: string;
|
|
8
|
+
providerKey?: string;
|
|
9
|
+
workerNode?: string;
|
|
10
|
+
attempt?: number;
|
|
11
|
+
maxAttempts?: number;
|
|
12
|
+
payload?: PayloadExchange[];
|
|
13
|
+
}
|
|
14
|
+
export interface StateTimelineProps<S extends string = string> {
|
|
15
|
+
transitions: StateTransition<S>[];
|
|
16
|
+
/** The state machine's presentation table — the same one its
|
|
17
|
+
* `createStatusPill` is bound to, so a timeline and a pill can never
|
|
18
|
+
* disagree about what a state looks like. */
|
|
19
|
+
system: StatusSystem<S>;
|
|
20
|
+
currentState: S;
|
|
21
|
+
/** Whether the timeline has stopped. Passed in rather than derived from
|
|
22
|
+
* `system[currentState].family`: terminality is the server's fact, and
|
|
23
|
+
* a presentational table is the wrong place to learn it from — see
|
|
24
|
+
* `status-tokens.ts`'s own warning. */
|
|
25
|
+
isTerminal: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Any IANA zone name, e.g. `"UTC"`, `"Africa/Douala"`, `"America/New_York"`.
|
|
28
|
+
* The UTC-offset suffix is derived from the zone and the instant, so it
|
|
29
|
+
* stays correct across DST and for zones this library has never heard
|
|
30
|
+
* of. (It used to be a two-value union with the suffix hard-coded as
|
|
31
|
+
* `"Z"` or `"+01"` — correct only for the two zones that union named.)
|
|
32
|
+
*/
|
|
33
|
+
timezone?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Per-state explanatory notes, rendered beneath the node that entered
|
|
36
|
+
* that state.
|
|
37
|
+
*
|
|
38
|
+
* The point is states that look like bugs to anyone who does not
|
|
39
|
+
* already know the product decision behind them — "we never learned the
|
|
40
|
+
* outcome, and deliberately will not retry". Without the note the
|
|
41
|
+
* operator's next move is to open a SQL client, which is the outcome a
|
|
42
|
+
* timeline exists to prevent. Supplied by the caller because the
|
|
43
|
+
* explanation is domain knowledge, not presentation.
|
|
44
|
+
*/
|
|
45
|
+
annotations?: Partial<Record<S, string>> | undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A record's transition history: one node per state entered, with elapsed
|
|
49
|
+
* time between them, optional per-transition metadata, and an optional
|
|
50
|
+
* payload inspector.
|
|
51
|
+
*
|
|
52
|
+
* Generic over the state machine — pass the same [`StatusSystem`] its
|
|
53
|
+
* pill is bound to. It used to be hard-wired to one application's message
|
|
54
|
+
* states, including that application's own explanatory notes and a
|
|
55
|
+
* two-value timezone union; all three are now the caller's.
|
|
56
|
+
*/
|
|
57
|
+
export declare function StateTimeline<S extends string>({ transitions, system, currentState, isTerminal, timezone, annotations, }: StateTimelineProps<S>): import("react").JSX.Element;
|
|
58
|
+
//# sourceMappingURL=state-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-timeline.d.ts","sourceRoot":"","sources":["../../../src/components/patterns/state-timeline.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAE7E,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxD,OAAO,EAAE,CAAC,CAAC;IACX,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC3D,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC;;iDAE6C;IAC7C,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IACxB,YAAY,EAAE,CAAC,CAAC;IAChB;;;2CAGuC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CACtD;AA8DD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,WAAW,EACX,MAAM,EACN,YAAY,EACZ,UAAU,EACV,QAAgB,EAChB,WAAW,GACZ,EAAE,kBAAkB,CAAC,CAAC,CAAC,+BAiGvB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Info } from "lucide-react";
|
|
3
|
+
import { cn } from "../../lib/cn.js";
|
|
4
|
+
import { Skeleton } from "../primitives/skeleton.js";
|
|
5
|
+
import { StateMark } from "../status/state-mark.js";
|
|
6
|
+
import { PayloadInspector } from "./payload-inspector.js";
|
|
7
|
+
/**
|
|
8
|
+
* `2026-09-11 14:03:07 +01` — sortable, unambiguous, and carrying its own
|
|
9
|
+
* offset so a screenshot pasted into a ticket is still interpretable.
|
|
10
|
+
*
|
|
11
|
+
* The offset is read out of `Intl`'s own `shortOffset` part rather than
|
|
12
|
+
* assumed from the zone name: it is the only way to be right across DST
|
|
13
|
+
* and across zones this component has never been told about. `UTC` keeps
|
|
14
|
+
* its conventional `Z` rather than the `GMT` that `shortOffset` yields.
|
|
15
|
+
*/
|
|
16
|
+
function formatAbsolute(iso, timezone) {
|
|
17
|
+
const date = new Date(iso);
|
|
18
|
+
const formatter = new Intl.DateTimeFormat("en-CA", {
|
|
19
|
+
timeZone: timezone,
|
|
20
|
+
year: "numeric",
|
|
21
|
+
month: "2-digit",
|
|
22
|
+
day: "2-digit",
|
|
23
|
+
hour: "2-digit",
|
|
24
|
+
minute: "2-digit",
|
|
25
|
+
second: "2-digit",
|
|
26
|
+
hourCycle: "h23",
|
|
27
|
+
timeZoneName: "shortOffset",
|
|
28
|
+
});
|
|
29
|
+
const parts = formatter.formatToParts(date);
|
|
30
|
+
const stamp = parts
|
|
31
|
+
.filter((part) => part.type !== "timeZoneName" && part.type !== "literal")
|
|
32
|
+
.reduce((acc, part) => {
|
|
33
|
+
acc.push(part.value);
|
|
34
|
+
return acc;
|
|
35
|
+
}, []);
|
|
36
|
+
const [year, month, day, hour, minute, second] = stamp;
|
|
37
|
+
// "GMT+1" / "GMT-05:00" / "GMT" → "+01" / "-05:00" / "Z".
|
|
38
|
+
const raw = parts.find((part) => part.type === "timeZoneName")?.value ?? "";
|
|
39
|
+
const offset = raw === "GMT" ? "Z" : raw.replace(/^GMT/, "").replace(/^([+-])(\d)$/, "$10$2");
|
|
40
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second} ${offset}`;
|
|
41
|
+
}
|
|
42
|
+
function formatElapsed(ms) {
|
|
43
|
+
if (ms < 1000)
|
|
44
|
+
return `+${ms}ms`;
|
|
45
|
+
if (ms < 60_000)
|
|
46
|
+
return `+${(ms / 1000).toFixed(3)}s`;
|
|
47
|
+
const totalSeconds = Math.round(ms / 1000);
|
|
48
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
49
|
+
const seconds = totalSeconds % 60;
|
|
50
|
+
if (minutes < 60)
|
|
51
|
+
return `+${minutes}m ${String(seconds).padStart(2, "0")}s`;
|
|
52
|
+
const hours = Math.floor(minutes / 60);
|
|
53
|
+
return `+${hours}h ${String(minutes % 60).padStart(2, "0")}m`;
|
|
54
|
+
}
|
|
55
|
+
function AnnotationNode({ text }) {
|
|
56
|
+
return (_jsxs("li", { className: "relative flex gap-3 pb-4 pl-0", children: [_jsx("div", { className: "flex w-4 shrink-0 justify-center", children: _jsx(Info, { size: 14, strokeWidth: 1.5, className: "mt-0.5 text-muted-foreground" }) }), _jsx("div", { className: "min-w-0 flex-1 rounded-sm border border-edge bg-surface-2 px-3 py-2 text-caption text-muted-foreground", children: text })] }));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A record's transition history: one node per state entered, with elapsed
|
|
60
|
+
* time between them, optional per-transition metadata, and an optional
|
|
61
|
+
* payload inspector.
|
|
62
|
+
*
|
|
63
|
+
* Generic over the state machine — pass the same [`StatusSystem`] its
|
|
64
|
+
* pill is bound to. It used to be hard-wired to one application's message
|
|
65
|
+
* states, including that application's own explanatory notes and a
|
|
66
|
+
* two-value timezone union; all three are now the caller's.
|
|
67
|
+
*/
|
|
68
|
+
export function StateTimeline({ transitions, system, currentState, isTerminal, timezone = "UTC", annotations, }) {
|
|
69
|
+
if (transitions.length === 0) {
|
|
70
|
+
return (_jsx("ol", { className: "flex flex-col gap-0", children: [0, 1, 2].map((i) => (_jsxs("li", { className: "flex items-center gap-3 py-2", children: [_jsx(Skeleton, { className: "h-4 w-4 rounded-full" }), _jsx(Skeleton, { className: "h-4 w-40" })] }, i))) }));
|
|
71
|
+
}
|
|
72
|
+
const rows = [];
|
|
73
|
+
transitions.forEach((transition, i) => {
|
|
74
|
+
const previous = transitions[i - 1];
|
|
75
|
+
const elapsedMs = previous
|
|
76
|
+
? new Date(transition.at).getTime() - new Date(previous.at).getTime()
|
|
77
|
+
: null;
|
|
78
|
+
const meta = system[transition.toState];
|
|
79
|
+
const isLast = i === transitions.length - 1;
|
|
80
|
+
rows.push(_jsxs("li", { className: "relative flex gap-3 pb-6 last:pb-0", children: [_jsxs("div", { className: "flex w-4 shrink-0 flex-col items-center", children: [_jsx(StateMark, { meta: meta, size: 16, className: "text-foreground" }), !isLast && _jsx("span", { className: "mt-1 w-px flex-1 bg-[var(--state-mark-rail,var(--edge))]" })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [_jsxs("p", { className: "font-medium text-body text-foreground", children: [meta.label, " ", _jsx("span", { className: "font-mono text-subtle-foreground", children: transition.toState })] }), _jsxs("div", { className: "shrink-0 text-right", children: [_jsx("p", { className: "font-mono text-caption text-foreground", children: formatAbsolute(transition.at, timezone) }), elapsedMs != null && (_jsx("p", { className: "font-mono text-caption text-subtle-foreground", children: formatElapsed(elapsedMs) }))] })] }), (transition.providerKey || transition.workerNode || transition.attempt) != null && (_jsx("p", { className: "mt-1 font-mono text-caption text-subtle-foreground", children: [
|
|
81
|
+
transition.providerKey,
|
|
82
|
+
transition.workerNode,
|
|
83
|
+
transition.attempt != null
|
|
84
|
+
? `attempt ${transition.attempt}${transition.maxAttempts ? `/${transition.maxAttempts}` : ""}`
|
|
85
|
+
: null,
|
|
86
|
+
]
|
|
87
|
+
.filter(Boolean)
|
|
88
|
+
.join(" · ") })), transition.payload != null && transition.payload.length > 0 && (_jsx("div", { className: "mt-2", children: _jsx(PayloadInspector, { exchanges: transition.payload, defaultOpen: -1 }) }))] })] }, `${transition.toState}-${transition.at}`));
|
|
89
|
+
const annotation = annotations?.[transition.toState];
|
|
90
|
+
if (annotation != null) {
|
|
91
|
+
rows.push(_jsx(AnnotationNode, { text: annotation }, `${transition.toState}-annotation`));
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// In-flight cap (design doc §5.3): the rail continues past the last node
|
|
95
|
+
// as a dashed segment ending in the current-state glyph, so "still
|
|
96
|
+
// moving" is readable without parsing. A terminal timeline instead ends
|
|
97
|
+
// the last node's own rail segment (no trailing cap at all).
|
|
98
|
+
if (!isTerminal) {
|
|
99
|
+
rows.push(_jsxs("li", { className: "relative flex gap-3", children: [_jsx("div", { className: "flex w-4 shrink-0 justify-center", children: _jsx("span", { className: "h-6 w-px border-edge-strong border-l border-dashed", "aria-hidden": "true" }) }), _jsxs("div", { className: "flex items-center gap-2 text-caption text-subtle-foreground", children: [_jsx(StateMark, { meta: system[currentState], size: 12, className: "text-muted-foreground" }), _jsx("span", { children: "still moving" })] })] }, "in-flight-cap"));
|
|
100
|
+
}
|
|
101
|
+
return _jsx("ol", { className: cn("flex flex-col"), children: rows });
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=state-timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-timeline.js","sourceRoot":"","sources":["../../../src/components/patterns/state-timeline.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type { HTMLAttributes } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Non-status tags only: app name, provider key, role, environment, sender
|
|
5
|
+
* ID. Never use `Badge` for a message or job state — that's `StatusPill`'s
|
|
6
|
+
* job (design doc §5.2); mixing them is how the status language erodes.
|
|
7
|
+
*
|
|
8
|
+
* D11: `cva()` replaces the previous `variant === "x" && "..."` conditional
|
|
9
|
+
* chain, same classes. One deliberate D8 diff, not a byte-identical carry-
|
|
10
|
+
* over: the previous base string hard-coded `rounded-sm`, which fought
|
|
11
|
+
* daisyUI's own `.badge` rule (`border-radius: var(--radius-selector)`,
|
|
12
|
+
* confirmed by reading `daisyui/components/badge.css` directly) at equal
|
|
13
|
+
* specificity — a redundant override, not a deliberate choice, and for the
|
|
14
|
+
* wrong tier besides: `--radius-selector` (8px) is this register's
|
|
15
|
+
* small-control tier, `--radius-sm` now aliases `--radius-field` (12px).
|
|
16
|
+
* Dropping the override lets daisyUI's own class govern radius, which is
|
|
17
|
+
* exactly constraint 7 ("DaisyUI does the work") and the correct tier for
|
|
18
|
+
* a tag-sized control.
|
|
19
|
+
*/
|
|
20
|
+
export declare const badgeVariants: (props?: ({
|
|
21
|
+
variant?: "neutral" | "outline" | null | undefined;
|
|
22
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
23
|
+
export type BadgeVariant = NonNullable<VariantProps<typeof badgeVariants>["variant"]>;
|
|
24
|
+
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
|
|
25
|
+
}
|
|
26
|
+
export declare function Badge({ className, variant, ...props }: BadgeProps): import("react").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa;;8EAQxB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAEtF,MAAM,WAAW,UACf,SAAQ,cAAc,CAAC,eAAe,CAAC,EACrC,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG;AAEzC,wBAAgB,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAEjE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { cn } from "../../lib/cn.js";
|
|
4
|
+
/**
|
|
5
|
+
* Non-status tags only: app name, provider key, role, environment, sender
|
|
6
|
+
* ID. Never use `Badge` for a message or job state — that's `StatusPill`'s
|
|
7
|
+
* job (design doc §5.2); mixing them is how the status language erodes.
|
|
8
|
+
*
|
|
9
|
+
* D11: `cva()` replaces the previous `variant === "x" && "..."` conditional
|
|
10
|
+
* chain, same classes. One deliberate D8 diff, not a byte-identical carry-
|
|
11
|
+
* over: the previous base string hard-coded `rounded-sm`, which fought
|
|
12
|
+
* daisyUI's own `.badge` rule (`border-radius: var(--radius-selector)`,
|
|
13
|
+
* confirmed by reading `daisyui/components/badge.css` directly) at equal
|
|
14
|
+
* specificity — a redundant override, not a deliberate choice, and for the
|
|
15
|
+
* wrong tier besides: `--radius-selector` (8px) is this register's
|
|
16
|
+
* small-control tier, `--radius-sm` now aliases `--radius-field` (12px).
|
|
17
|
+
* Dropping the override lets daisyUI's own class govern radius, which is
|
|
18
|
+
* exactly constraint 7 ("DaisyUI does the work") and the correct tier for
|
|
19
|
+
* a tag-sized control.
|
|
20
|
+
*/
|
|
21
|
+
export const badgeVariants = cva("badge font-mono text-caption", {
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
neutral: "badge-neutral",
|
|
25
|
+
outline: "badge-outline",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: { variant: "neutral" },
|
|
29
|
+
});
|
|
30
|
+
export function Badge({ className, variant, ...props }) {
|
|
31
|
+
return _jsx("span", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/components/primitives/badge.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,8BAA8B,EAAE;IAC/D,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,eAAe;SACzB;KACF;IACD,eAAe,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;CACxC,CAAC,CAAC;AAQH,MAAM,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAc;IAChE,OAAO,eAAM,SAAS,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
3
|
+
export declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "destructive" | "ghost" | "primary" | "secondary" | null | undefined;
|
|
5
|
+
size?: "icon" | "md" | "sm" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>["variant"]>;
|
|
8
|
+
export type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>["size"]>;
|
|
9
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
10
|
+
}
|
|
11
|
+
export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
12
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/primitives/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAuBlD,eAAO,MAAM,cAAc;;;8EAezB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACxF,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAElF,MAAM,WAAW,WACf,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,YAAY,CAAC,OAAO,cAAc,CAAC;CAAG;AAE1C,eAAO,MAAM,MAAM,2GAIlB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
// daisyUI does the heavy lifting (`btn-primary`, `btn-outline`, `btn-ghost`,
|
|
6
|
+
// `btn-error`); the design doc's rule (§5.1) is that there is no
|
|
7
|
+
// "success"/"warning" button variant — those hues are reserved for status,
|
|
8
|
+
// so only these four exist. `btn-primary` is genuinely the achromatic
|
|
9
|
+
// inverse fill (§1.3: near-black on light, near-white on dark) — `neutral`
|
|
10
|
+
// is a *different*, deliberately quieter token (this theme's surface-3-ish
|
|
11
|
+
// fill, used for badges) and using it here read as a washed-out primary
|
|
12
|
+
// button in light theme; caught visually, not by inspection.
|
|
13
|
+
//
|
|
14
|
+
// D4/D11: rebuilt on `cva()` per docs/design/console-redesign.md §6.3 —
|
|
15
|
+
// `Slot`/`asChild` are gone (nothing in this repo used `<Button asChild>`,
|
|
16
|
+
// confirmed by grep before removing it), and `buttonVariants` is exported
|
|
17
|
+
// standalone so a link that must look like a button reaches for the class
|
|
18
|
+
// string directly: `<a className={buttonVariants({ variant: "secondary" })}>`.
|
|
19
|
+
// `rounded-field` in the base string is the one deliberate D8 addition —
|
|
20
|
+
// daisyUI's own `.btn` class already applies `--radius-field` per corner
|
|
21
|
+
// internally, so this doesn't change the rendered radius, only makes the
|
|
22
|
+
// D8 register explicit at the call site, matching §6.3's own sketch
|
|
23
|
+
// verbatim.
|
|
24
|
+
export const buttonVariants = cva("btn font-sans font-semibold rounded-field", {
|
|
25
|
+
variants: {
|
|
26
|
+
variant: {
|
|
27
|
+
primary: "btn-primary",
|
|
28
|
+
secondary: "btn-outline",
|
|
29
|
+
ghost: "btn-ghost",
|
|
30
|
+
destructive: "btn-error",
|
|
31
|
+
},
|
|
32
|
+
size: {
|
|
33
|
+
sm: "btn-sm",
|
|
34
|
+
md: "",
|
|
35
|
+
icon: "btn-square btn-sm",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: { variant: "primary", size: "md" },
|
|
39
|
+
});
|
|
40
|
+
export const Button = forwardRef(({ className, variant, size, ...props }, ref) => (_jsx("button", { ref: ref, className: cn(buttonVariants({ variant, size }), className), ...props })));
|
|
41
|
+
Button.displayName = "Button";
|
|
42
|
+
//# sourceMappingURL=button.js.map
|