@ciridae/ui 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/auth.d.ts +10 -0
- package/dist/app/auth.js +60 -0
- package/dist/app/error-boundary.d.ts +18 -0
- package/dist/app/error-boundary.js +45 -0
- package/dist/app/feedback.d.ts +12 -0
- package/dist/app/feedback.js +128 -0
- package/dist/app/index.d.ts +8 -0
- package/dist/app/index.js +8 -0
- package/dist/app/request-errors.d.ts +63 -0
- package/dist/app/request-errors.js +172 -0
- package/dist/app/sentry.d.ts +18 -0
- package/dist/app/sentry.js +52 -0
- package/dist/app/telemetry.d.ts +7 -0
- package/dist/app/telemetry.js +28 -0
- package/dist/app/trail.d.ts +9 -0
- package/dist/app/trail.js +18 -0
- package/dist/chat/chat-query-keys.d.ts +3 -3
- package/dist/chat/contract.d.ts +15 -15
- package/dist/chat/conversation-items-query-options.d.ts +114 -114
- package/dist/chat/conversation-source.d.ts +89 -0
- package/dist/chat/conversation-source.js +1 -0
- package/dist/chat/describe-tool-call.d.ts +3 -3
- package/dist/chat/describe-tool-call.js +3 -3
- package/dist/chat/message-text.d.ts +1 -1
- package/dist/chat/message-text.js +116 -48
- package/dist/chat/use-conversation-list.d.ts +6 -6
- package/dist/ciridae.css +16 -4
- package/dist/components/activity-feed.d.ts +3 -2
- package/dist/components/activity-feed.js +1 -0
- package/dist/components/agent-work.d.ts +3 -3
- package/dist/components/app-frame.d.ts +91 -0
- package/dist/components/app-frame.js +134 -0
- package/dist/components/app-navigation.d.ts +30 -3
- package/dist/components/app-navigation.js +105 -14
- package/dist/components/badge.d.ts +30 -5
- package/dist/components/badge.js +134 -15
- package/dist/components/brand-icons.d.ts +3 -3
- package/dist/components/bulk-action-bar.d.ts +1 -1
- package/dist/components/bulk-action-bar.js +3 -3
- package/dist/components/button.d.ts +12 -5
- package/dist/components/button.js +77 -44
- package/dist/components/calendar.d.ts +1 -1
- package/dist/components/calendar.js +44 -17
- package/dist/components/centered-page.d.ts +1 -1
- package/dist/components/centered-page.js +2 -2
- package/dist/components/chart.d.ts +22 -2
- package/dist/components/chart.js +251 -51
- package/dist/components/chat-client-source.d.ts +16 -0
- package/dist/components/chat-client-source.js +297 -0
- package/dist/components/chat-page.d.ts +9 -8
- package/dist/components/chat-page.js +7 -11
- package/dist/components/chat-sheet-controller.d.ts +11 -14
- package/dist/components/chat-sheet-controller.js +3 -3
- package/dist/components/chat-sheet.d.ts +18 -11
- package/dist/components/chat-sheet.js +188 -289
- package/dist/components/chat.d.ts +109 -19
- package/dist/components/chat.js +520 -124
- package/dist/components/checkbox-item.d.ts +6 -3
- package/dist/components/checkbox-item.js +9 -5
- package/dist/components/checkbox-list.d.ts +1 -1
- package/dist/components/chip.d.ts +6 -1
- package/dist/components/chip.js +27 -1
- package/dist/components/collapsible.d.ts +1 -1
- package/dist/components/color-theme.d.ts +1 -1
- package/dist/components/column-settings.d.ts +1 -1
- package/dist/components/column-settings.js +1 -1
- package/dist/components/command-menu.d.ts +5 -1
- package/dist/components/command-menu.js +98 -32
- package/dist/components/command-palette.d.ts +7 -3
- package/dist/components/command-palette.js +20 -11
- package/dist/components/copyable-id.d.ts +22 -5
- package/dist/components/copyable-id.js +46 -6
- package/dist/components/data-display.d.ts +39 -8
- package/dist/components/data-display.js +138 -19
- package/dist/components/data-grid.d.ts +23 -11
- package/dist/components/data-grid.js +61 -26
- package/dist/components/date-range-picker.d.ts +1 -1
- package/dist/components/date-range-picker.js +9 -20
- package/dist/components/date-time.d.ts +1 -1
- package/dist/components/dialog-height-context.d.ts +1 -1
- package/dist/components/document-viewer.d.ts +2 -2
- package/dist/components/drawer.d.ts +11 -6
- package/dist/components/drawer.js +91 -54
- package/dist/components/dropzone.d.ts +4 -4
- package/dist/components/editable-field.d.ts +12 -3
- package/dist/components/editable-field.js +57 -27
- package/dist/components/email-input.d.ts +1 -1
- package/dist/components/email-input.js +6 -5
- package/dist/components/environment-frame.d.ts +2 -2
- package/dist/components/environment-frame.js +37 -6
- package/dist/components/expandable-text.d.ts +1 -1
- package/dist/components/feedback-screenshot.d.ts +1 -1
- package/dist/components/feedback-sheet.d.ts +18 -3
- package/dist/components/feedback-sheet.js +216 -55
- package/dist/components/field-context.d.ts +1 -1
- package/dist/components/filter-bar.d.ts +3 -3
- package/dist/components/filter-bar.js +43 -29
- package/dist/components/form-controls.d.ts +12 -3
- package/dist/components/form-controls.js +46 -22
- package/dist/components/form-layout.d.ts +14 -10
- package/dist/components/form-layout.js +68 -23
- package/dist/components/glass-menu.d.ts +3 -0
- package/dist/components/glass-menu.js +63 -0
- package/dist/components/gradient-edge.d.ts +9 -0
- package/dist/components/gradient-edge.js +31 -0
- package/dist/components/hotkeys.d.ts +2 -2
- package/dist/components/icon.d.ts +1 -1
- package/dist/components/input.d.ts +7 -5
- package/dist/components/input.js +29 -17
- package/dist/components/keyboard-shortcuts.d.ts +2 -2
- package/dist/components/keycap.d.ts +10 -6
- package/dist/components/keycap.js +57 -19
- package/dist/components/layout.d.ts +13 -13
- package/dist/components/lightbox.d.ts +9 -3
- package/dist/components/lightbox.js +13 -9
- package/dist/components/link.d.ts +1 -1
- package/dist/components/locale.d.ts +42 -2
- package/dist/components/locale.js +43 -3
- package/dist/components/log-entry.d.ts +40 -0
- package/dist/components/log-entry.js +146 -0
- package/dist/components/log-list.d.ts +3 -3
- package/dist/components/mention-input.d.ts +2 -2
- package/dist/components/mention-input.js +4 -3
- package/dist/components/menu.d.ts +7 -3
- package/dist/components/menu.js +34 -37
- package/dist/components/meter.d.ts +10 -2
- package/dist/components/meter.js +64 -6
- package/dist/components/navigation.d.ts +21 -4
- package/dist/components/navigation.js +84 -19
- package/dist/components/notification-tray.d.ts +1 -1
- package/dist/components/notification-tray.js +5 -4
- package/dist/components/overlays.d.ts +6 -4
- package/dist/components/overlays.js +69 -40
- package/dist/components/page-frame.d.ts +4 -4
- package/dist/components/page-frame.js +1 -1
- package/dist/components/panel.d.ts +4 -4
- package/dist/components/panel.js +18 -12
- package/dist/components/profile-header.d.ts +1 -1
- package/dist/components/progress.d.ts +1 -1
- package/dist/components/project-avatar.d.ts +1 -1
- package/dist/components/radio-card.d.ts +2 -2
- package/dist/components/radio-card.js +10 -9
- package/dist/components/record.d.ts +29 -5
- package/dist/components/record.js +147 -18
- package/dist/components/resolved-file-url.d.ts +19 -0
- package/dist/components/resolved-file-url.js +49 -0
- package/dist/components/scroll-area.d.ts +1 -1
- package/dist/components/secret-dialog.d.ts +1 -1
- package/dist/components/segmented-bar.d.ts +4 -2
- package/dist/components/segmented-bar.js +16 -6
- package/dist/components/select.d.ts +9 -6
- package/dist/components/select.js +103 -127
- package/dist/components/settings.d.ts +4 -4
- package/dist/components/shell-skeleton.d.ts +1 -1
- package/dist/components/shell-skeleton.js +1 -1
- package/dist/components/shell.d.ts +21 -21
- package/dist/components/shell.js +43 -43
- package/dist/components/side-panel.d.ts +3 -3
- package/dist/components/sidebar.d.ts +13 -8
- package/dist/components/sidebar.js +55 -27
- package/dist/components/single-line-text.d.ts +2 -0
- package/dist/components/single-line-text.js +16 -0
- package/dist/components/site-banner.d.ts +5 -2
- package/dist/components/site-banner.js +17 -6
- package/dist/components/skeleton.d.ts +8 -7
- package/dist/components/skeleton.js +28 -16
- package/dist/components/skeletons.d.ts +17 -5
- package/dist/components/skeletons.js +71 -8
- package/dist/components/stages.d.ts +83 -11
- package/dist/components/stages.js +512 -156
- package/dist/components/stat-card.d.ts +12 -4
- package/dist/components/stat-card.js +92 -37
- package/dist/components/status-banner.d.ts +1 -1
- package/dist/components/status-banner.js +1 -1
- package/dist/components/status.d.ts +2 -2
- package/dist/components/steps.d.ts +1 -1
- package/dist/components/switch.d.ts +1 -1
- package/dist/components/tabs.d.ts +8 -8
- package/dist/components/tabs.js +26 -13
- package/dist/components/theme-customizer.d.ts +2 -2
- package/dist/components/theme-toggle.d.ts +4 -0
- package/dist/components/theme-toggle.js +67 -0
- package/dist/components/toast.d.ts +10 -3
- package/dist/components/toast.js +78 -29
- package/dist/components/use-new-version-available.d.ts +6 -0
- package/dist/components/use-new-version-available.js +29 -0
- package/dist/components/user-chip.d.ts +3 -3
- package/dist/components/wizard.d.ts +2 -2
- package/dist/feedback/contract.d.ts +136 -136
- package/dist/feedback/feedback-controller.d.ts +6 -6
- package/dist/feedback/generated/zod.gen.d.ts +28 -28
- package/dist/feedback/operator-contract.d.ts +11 -11
- package/dist/feedback/operator-controller.d.ts +32 -13
- package/dist/feedback/operator-controller.js +44 -11
- package/dist/preset.js +289 -33
- package/dist/styled-system/styles.css +3294 -1079
- package/dist/styled-system/tokens/index.mjs +598 -22
- package/dist/styled-system/tokens/tokens.d.ts +11 -11
- package/dist/styled-system/types/prop-type.d.ts +2 -2
- package/dist/styles.css +16 -4
- package/dist/theme/color.d.ts +3 -0
- package/dist/theme/color.js +5 -0
- package/dist/theme/derive.d.ts +9 -2
- package/dist/theme/derive.js +72 -12
- package/dist/theme/palettes.d.ts +49 -6
- package/dist/theme/palettes.js +84 -15
- package/dist/theme/tokens.d.ts +3 -3
- package/dist/theme/tokens.js +107 -32
- package/package.json +40 -3
|
@@ -7,7 +7,7 @@ export type TrendProps = {
|
|
|
7
7
|
arrow?: boolean;
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
};
|
|
10
|
-
export declare function Trend({ direction, tone, arrow, children }: TrendProps): import("
|
|
10
|
+
export declare function Trend({ direction, tone, arrow, children }: TrendProps): import("react").JSX.Element;
|
|
11
11
|
export type SparklineProps = Omit<ComponentProps<"div">, "children"> & {
|
|
12
12
|
values: readonly number[];
|
|
13
13
|
/** The value at the box's foot; by default far enough under the lowest that the line floats. */
|
|
@@ -17,8 +17,11 @@ export type SparklineProps = Omit<ComponentProps<"div">, "children"> & {
|
|
|
17
17
|
strokeWidth?: number;
|
|
18
18
|
endPointSize?: number;
|
|
19
19
|
};
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* A run of values as a line filling its box; decorative, as the figure beside it says what it
|
|
22
|
+
* shows. Under two values there is no line, and a dashed rule stands in for it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function Sparkline({ values, low: ownLow, high: ownHigh, strokeWidth, endPointSize, className, ...props }: SparklineProps): import("react").JSX.Element;
|
|
22
25
|
export type MetricCardProps = Omit<useRender.ComponentProps<"div">, "children" | "onSelect"> & {
|
|
23
26
|
label: ReactNode;
|
|
24
27
|
value: ReactNode;
|
|
@@ -30,5 +33,10 @@ export type MetricCardProps = Omit<useRender.ComponentProps<"div">, "children" |
|
|
|
30
33
|
onSelect?: () => void;
|
|
31
34
|
/** Makes the card a link; a router's link as `render` routes it. */
|
|
32
35
|
href?: string;
|
|
36
|
+
/**
|
|
37
|
+
* `card` (the default) frames it on its own; in a row of tiles, `left` rules its leading edge
|
|
38
|
+
* and `none` leaves it bare.
|
|
39
|
+
*/
|
|
40
|
+
divider?: "card" | "left" | "none";
|
|
33
41
|
};
|
|
34
|
-
export declare function MetricCard({ label, value, change, sparkline, onSelect, href, render, className, ...props }: MetricCardProps): import("
|
|
42
|
+
export declare function MetricCard({ label, value, change, sparkline, onSelect, href, divider, render, className, ...props }: MetricCardProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -2,12 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
/*
|
|
3
3
|
* Figures for a dashboard. `MetricCard` is one figure: its label, its value, how it changed
|
|
4
4
|
* (`Trend`) and its recent run (`Sparkline`); it can open what it counts. `Sparkline` is a blue
|
|
5
|
-
* line over
|
|
6
|
-
* point
|
|
5
|
+
* line over an area that fades to its foot, stretched to its box: the stroke keeps its width, and
|
|
6
|
+
* the area and end point are HTML, so none of them distorts.
|
|
7
7
|
*/
|
|
8
8
|
import { useRender } from "@base-ui/react/use-render";
|
|
9
9
|
import { ArrowDownIcon, ArrowRightIcon, ArrowUpIcon } from "@phosphor-icons/react";
|
|
10
|
-
import { css, cx } from "#primitives/css";
|
|
10
|
+
import { css, cva, cx } from "#primitives/css";
|
|
11
11
|
import { icon } from "./icon.js";
|
|
12
12
|
import { cardSurface } from "./panel.js";
|
|
13
13
|
/* A change beside a figure: which way it moved, and separately whether that is good. */
|
|
@@ -20,17 +20,28 @@ const trend = css({
|
|
|
20
20
|
fontWeight: "medium",
|
|
21
21
|
"&[data-tone=good]": { color: "accent.green" },
|
|
22
22
|
"&[data-tone=bad]": { color: "accent.red" },
|
|
23
|
-
"&[data-tone=neutral]": { color: "fg.
|
|
23
|
+
"&[data-tone=neutral]": { color: "fg.label" },
|
|
24
24
|
"& > svg": { flexShrink: "0" },
|
|
25
25
|
});
|
|
26
26
|
const trendText = css({ minWidth: "0", overflow: "hidden", textOverflow: "ellipsis" });
|
|
27
27
|
const TREND_ARROWS = { up: ArrowUpIcon, down: ArrowDownIcon, flat: ArrowRightIcon };
|
|
28
28
|
export function Trend({ direction, tone = "neutral", arrow = true, children }) {
|
|
29
29
|
const Arrow = TREND_ARROWS[direction];
|
|
30
|
-
return (_jsxs("span", { className: trend, "data-tone": tone, "data-ciridae-ui": "", children: [arrow && _jsx(Arrow, { className: icon({ size: "compact" }), weight: "bold", "aria-hidden": "true" }), _jsx("span", { className: trendText, children: children })] }));
|
|
30
|
+
return (_jsxs("span", { className: trend, "data-tone": tone, "data-ciridae-ui": "", children: [arrow && _jsx(Arrow, { className: icon({ size: "compact" }), weight: "bold", "aria-hidden": "true" }), _jsx("span", { className: trendText, "data-trend-text": "", children: children })] }));
|
|
31
31
|
}
|
|
32
|
-
/*
|
|
33
|
-
|
|
32
|
+
/*
|
|
33
|
+
* Sparkline: drawn into a 100x100 box that stretches to its plot. The plot fills the box unless
|
|
34
|
+
* `--sparkline-plot-width` and `--sparkline-plot-height` size it, at the box's foot and start, so
|
|
35
|
+
* the end point's ring has room above and after the line.
|
|
36
|
+
*/
|
|
37
|
+
const plot = css({ position: "relative", color: "chart.trend" });
|
|
38
|
+
const plotArea = css({
|
|
39
|
+
position: "absolute",
|
|
40
|
+
insetInlineStart: "0",
|
|
41
|
+
bottom: "0",
|
|
42
|
+
width: "var(--sparkline-plot-width, 100%)",
|
|
43
|
+
height: "var(--sparkline-plot-height, 100%)",
|
|
44
|
+
});
|
|
34
45
|
const svg = css({
|
|
35
46
|
position: "absolute",
|
|
36
47
|
inset: "0",
|
|
@@ -38,16 +49,31 @@ const svg = css({
|
|
|
38
49
|
height: "100%",
|
|
39
50
|
overflow: "visible",
|
|
40
51
|
});
|
|
52
|
+
// The area under the line, clipped to it, so its gradient runs top to foot whatever the box.
|
|
53
|
+
const area = css({ position: "absolute", inset: "0", background: "token(gradients.chart.area)" });
|
|
54
|
+
// The ring is the tile's face, so the point reads as cut out of the line.
|
|
41
55
|
const endPoint = css({
|
|
42
56
|
position: "absolute",
|
|
43
57
|
borderRadius: "round",
|
|
44
|
-
background: "
|
|
58
|
+
background: "chart.trend",
|
|
45
59
|
borderStyle: "solid",
|
|
46
|
-
borderColor: "bg.
|
|
60
|
+
borderColor: "bg.surface",
|
|
47
61
|
translate: "-50% -50%",
|
|
48
62
|
});
|
|
49
|
-
|
|
63
|
+
// No run to draw: a dashed rule across the middle holds the line's place.
|
|
64
|
+
const noRun = css({
|
|
65
|
+
position: "absolute",
|
|
66
|
+
insetInline: "0",
|
|
67
|
+
top: "50%",
|
|
68
|
+
borderTop: "2px dashed token(colors.border.divider)",
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* A run of values as a line filling its box; decorative, as the figure beside it says what it
|
|
72
|
+
* shows. Under two values there is no line, and a dashed rule stands in for it.
|
|
73
|
+
*/
|
|
50
74
|
export function Sparkline({ values, low: ownLow, high: ownHigh, strokeWidth = 1.5, endPointSize = 6, className, ...props }) {
|
|
75
|
+
if (values.length < 2)
|
|
76
|
+
return (_jsx("div", { "aria-hidden": "true", ...props, className: cx(plot, className), "data-ciridae-ui": "", children: _jsx("span", { className: noRun }) }));
|
|
51
77
|
const lowest = Math.min(...values);
|
|
52
78
|
const high = ownHigh ?? Math.max(...values);
|
|
53
79
|
const low = ownLow ?? lowest - (high - lowest) * 0.4;
|
|
@@ -56,31 +82,60 @@ export function Sparkline({ values, low: ownLow, high: ownHigh, strokeWidth = 1.
|
|
|
56
82
|
const step = 100 / Math.max(values.length - 1, 1);
|
|
57
83
|
const points = tops.map((top, index) => `${index * step},${top}`).join(" ");
|
|
58
84
|
const lastTop = tops[tops.length - 1] ?? 100;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
const areaOutline = tops.map((top, index) => `${index * step}% ${top}%`).join(", ");
|
|
86
|
+
return (_jsx("div", { "aria-hidden": "true", ...props, className: cx(plot, className), "data-ciridae-ui": "", children: _jsxs("span", { className: plotArea, children: [_jsx("span", { className: area, style: { clipPath: `polygon(0% 100%, ${areaOutline}, 100% 100%)` } }), _jsx("svg", { className: svg, viewBox: "0 0 100 100", preserveAspectRatio: "none", children: _jsx("polyline", { points: points, fill: "none", stroke: "currentColor", strokeWidth: strokeWidth, strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" }) }), _jsx("span", { className: endPoint, style: {
|
|
87
|
+
insetInlineStart: "100%",
|
|
88
|
+
top: `${lastTop}%`,
|
|
89
|
+
width: endPointSize,
|
|
90
|
+
height: endPointSize,
|
|
91
|
+
borderWidth: strokeWidth,
|
|
92
|
+
} })] }) }));
|
|
66
93
|
}
|
|
67
|
-
/*
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
/*
|
|
95
|
+
* Metric card: a figure with its change, and its run beside it. A tile in a row of them drops the
|
|
96
|
+
* card for a rule on its leading edge, or for nothing, and its label steps back to the label grey.
|
|
97
|
+
* The change's words are the label grey too, the kit's Stat tile: its arrow carries the tone.
|
|
98
|
+
* The run sits in the kit's 88x32 chart slot, its line in the slot's lower 84x25.
|
|
99
|
+
*/
|
|
100
|
+
const metricCard = cva({
|
|
101
|
+
base: {
|
|
102
|
+
display: "flex",
|
|
103
|
+
gap: "layout.contentGap",
|
|
104
|
+
padding: "panel.comfortable",
|
|
105
|
+
color: "fg.primary",
|
|
106
|
+
font: "inherit",
|
|
107
|
+
textAlign: "start",
|
|
108
|
+
textDecoration: "none",
|
|
109
|
+
lineHeight: "tight",
|
|
110
|
+
"&:is(button, a)": { cursor: "pointer" },
|
|
111
|
+
_focusVisible: { focusRing: "outer" },
|
|
112
|
+
"& [data-trend-text]": { color: "fg.label" },
|
|
113
|
+
"& > [data-sparkline]": {
|
|
114
|
+
"--sparkline-plot-width": "token(sizes.sparkline.plotWidth)",
|
|
115
|
+
"--sparkline-plot-height": "token(sizes.sparkline.plotHeight)",
|
|
116
|
+
width: "sparkline.width",
|
|
117
|
+
height: "sparkline.height",
|
|
118
|
+
flexShrink: "0",
|
|
119
|
+
alignSelf: "flex-end",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
variants: {
|
|
123
|
+
divider: {
|
|
124
|
+
card: { ...cardSurface, "&:is(button, a)": { _hover: { borderColor: "border.glass" } } },
|
|
125
|
+
left: {
|
|
126
|
+
minWidth: "0",
|
|
127
|
+
border: "0",
|
|
128
|
+
borderInlineStart: "1px solid token(colors.border.panel)",
|
|
129
|
+
background: "transparent",
|
|
130
|
+
"& [data-metric-label]": { color: "fg.label" },
|
|
131
|
+
},
|
|
132
|
+
none: {
|
|
133
|
+
minWidth: "0",
|
|
134
|
+
border: "0",
|
|
135
|
+
background: "transparent",
|
|
136
|
+
"& [data-metric-label]": { color: "fg.label" },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
84
139
|
},
|
|
85
140
|
});
|
|
86
141
|
const metricCopy = css({
|
|
@@ -97,7 +152,7 @@ const metricValue = css({
|
|
|
97
152
|
lineHeight: "tight",
|
|
98
153
|
fontVariantNumeric: "tabular-nums",
|
|
99
154
|
});
|
|
100
|
-
export function MetricCard({ label, value, change, sparkline, onSelect, href, render, className, ...props }) {
|
|
155
|
+
export function MetricCard({ label, value, change, sparkline, onSelect, href, divider = "card", render, className, ...props }) {
|
|
101
156
|
return useRender({
|
|
102
157
|
defaultTagName: href !== undefined ? "a" : onSelect !== undefined ? "button" : "div",
|
|
103
158
|
render,
|
|
@@ -109,9 +164,9 @@ export function MetricCard({ label, value, change, sparkline, onSelect, href, re
|
|
|
109
164
|
: {}),
|
|
110
165
|
...props,
|
|
111
166
|
onClick: onSelect,
|
|
112
|
-
className: cx(metricCard, className),
|
|
167
|
+
className: cx(metricCard({ divider }), className),
|
|
113
168
|
"data-ciridae-ui": "",
|
|
114
|
-
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: metricCopy, children: [_jsx("span", { className: metricLabel, children: label }), _jsx("span", { className: metricValue, children: value }), change && _jsx(Trend, { ...change })] }), sparkline && _jsx(Sparkline, { values: sparkline, "data-sparkline": "" })] })),
|
|
169
|
+
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: metricCopy, children: [_jsx("span", { className: metricLabel, "data-metric-label": "", children: label }), _jsx("span", { className: metricValue, children: value }), change && _jsx(Trend, { ...change })] }), sparkline && _jsx(Sparkline, { values: sparkline, "data-sparkline": "" })] })),
|
|
115
170
|
},
|
|
116
171
|
});
|
|
117
172
|
}
|
|
@@ -14,4 +14,4 @@ export type StatusBannerProps = Omit<ComponentProps<"div">, "title"> & {
|
|
|
14
14
|
/** The locale's "Dismiss" by default. */
|
|
15
15
|
dismissLabel?: string;
|
|
16
16
|
};
|
|
17
|
-
export declare function StatusBanner({ title, description, tone, emphasis, action, onDismiss, dismissLabel, className, ...props }: StatusBannerProps): import("
|
|
17
|
+
export declare function StatusBanner({ title, description, tone, emphasis, action, onDismiss, dismissLabel, className, ...props }: StatusBannerProps): import("react").JSX.Element;
|
|
@@ -70,7 +70,7 @@ const bannerIcon = cva({
|
|
|
70
70
|
neutral: { color: "fg.muted" },
|
|
71
71
|
info: { color: "accent.blue" },
|
|
72
72
|
success: { color: "accent.green" },
|
|
73
|
-
warning: { color: "accent.
|
|
73
|
+
warning: { color: "accent.yellowIcon" },
|
|
74
74
|
danger: { color: "accent.red" },
|
|
75
75
|
},
|
|
76
76
|
},
|
|
@@ -21,12 +21,12 @@ export type StatusProps = ComponentProps<"span"> & {
|
|
|
21
21
|
/** Shows only the icon, with the children as its tooltip and accessible name. */
|
|
22
22
|
iconOnly?: boolean;
|
|
23
23
|
};
|
|
24
|
-
export declare function Status({ variant, iconOnly, className, style, ...props }: StatusProps): import("
|
|
24
|
+
export declare function Status({ variant, iconOnly, className, style, ...props }: StatusProps): import("react").JSX.Element;
|
|
25
25
|
export type PendingTextProps = Omit<ComponentProps<"span">, "children"> & {
|
|
26
26
|
children: ReactNode;
|
|
27
27
|
/** `centered` holds the place of a page or panel that is still loading. */
|
|
28
28
|
placement?: "inline" | "centered";
|
|
29
29
|
};
|
|
30
30
|
/** Work in progress, named: the spinner and a label such as "Signing in…", announced as a status. */
|
|
31
|
-
export declare function PendingText({ children, placement, className, ...props }: PendingTextProps): import("
|
|
31
|
+
export declare function PendingText({ children, placement, className, ...props }: PendingTextProps): import("react").JSX.Element;
|
|
32
32
|
export {};
|
|
@@ -3,4 +3,4 @@ import type { ComponentProps } from "react";
|
|
|
3
3
|
export type SwitchProps = Omit<ComponentProps<typeof BaseSwitch.Root>, "className"> & {
|
|
4
4
|
className?: string;
|
|
5
5
|
};
|
|
6
|
-
export declare function Switch({ className, ...props }: SwitchProps): import("
|
|
6
|
+
export declare function Switch({ className, ...props }: SwitchProps): import("react").JSX.Element;
|
|
@@ -2,11 +2,11 @@ import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
|
2
2
|
import type { ComponentProps, ReactNode } from "react";
|
|
3
3
|
export declare function TabsRoot({ className, ...props }: Omit<ComponentProps<typeof BaseTabs.Root>, "className"> & {
|
|
4
4
|
className?: string;
|
|
5
|
-
}): import("
|
|
6
|
-
export declare const TabsPanel: import("
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare const TabsPanel: import("react").ForwardRefExoticComponent<Omit<import("@base-ui/react").TabsPanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
7
7
|
export declare function TabsGroup({ border, className, ...props }: ComponentProps<"span"> & {
|
|
8
8
|
border?: "control" | "glass";
|
|
9
|
-
}): import("
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
10
|
export declare function TabsList({ className, variant, overflow: ownOverflow, children, ...props }: Omit<ComponentProps<typeof BaseTabs.List>, "className"> & {
|
|
11
11
|
className?: string;
|
|
12
12
|
/**
|
|
@@ -19,7 +19,7 @@ export declare function TabsList({ className, variant, overflow: ownOverflow, ch
|
|
|
19
19
|
* scrolls the row. `menu` in a `TabsBar`, `scroll` elsewhere.
|
|
20
20
|
*/
|
|
21
21
|
overflow?: "menu" | "scroll";
|
|
22
|
-
}): import("
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
23
|
export type TabsTabProps = Omit<ComponentProps<typeof BaseTabs.Tab>, "className"> & {
|
|
24
24
|
className?: string;
|
|
25
25
|
/** Tint the tab icon bronze while inactive, as the Projects hub type tabs do. */
|
|
@@ -32,17 +32,17 @@ export type TabsTabProps = Omit<ComponentProps<typeof BaseTabs.Tab>, "className"
|
|
|
32
32
|
/** Muted after the label, such as how many rows the tab holds. */
|
|
33
33
|
count?: ReactNode;
|
|
34
34
|
};
|
|
35
|
-
export declare function TabsTab({ className, iconTone, href, render, count: tabCount, children, ...props }: TabsTabProps): import("
|
|
35
|
+
export declare function TabsTab({ className, iconTone, href, render, count: tabCount, children, ...props }: TabsTabProps): import("react").JSX.Element;
|
|
36
36
|
/**
|
|
37
37
|
* Wraps a page's `TabsBar` and the section below it, so the section can place its controls on the
|
|
38
38
|
* tab row with `TabsBarActions` while keeping its own state.
|
|
39
39
|
*/
|
|
40
40
|
export declare function TabsBarProvider({ children }: {
|
|
41
41
|
children: ReactNode;
|
|
42
|
-
}): import("
|
|
42
|
+
}): import("react").JSX.Element;
|
|
43
43
|
/** Section tabs (a `TabsRoot`) with a slot at the end of the row for the open section's controls. */
|
|
44
|
-
export declare function TabsBar({ className, children, ...props }: ComponentProps<"div">): import("
|
|
44
|
+
export declare function TabsBar({ className, children, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
45
45
|
/** Renders the open section's controls at the end of the nearest `TabsBar` row. */
|
|
46
46
|
export declare function TabsBarActions({ children }: {
|
|
47
47
|
children: ReactNode;
|
|
48
|
-
}): import("
|
|
48
|
+
}): import("react").ReactPortal | null;
|
package/dist/components/tabs.js
CHANGED
|
@@ -22,14 +22,15 @@ const list = css({
|
|
|
22
22
|
overflowX: "auto",
|
|
23
23
|
scrollbarWidth: "none",
|
|
24
24
|
});
|
|
25
|
-
/** Finalization "
|
|
25
|
+
/** Finalization "View tabs": tabs sit inside a grey pill well with a hairline inset. */
|
|
26
26
|
const containedList = css({
|
|
27
27
|
width: "max-content",
|
|
28
28
|
padding: "control.trackInset",
|
|
29
29
|
border: "1px solid token(colors.border.control)",
|
|
30
30
|
borderRadius: "pill",
|
|
31
|
-
background: "bg.
|
|
32
|
-
gap
|
|
31
|
+
background: "bg.field",
|
|
32
|
+
// Raised over the base list's own gap, as the text list's is.
|
|
33
|
+
"&[data-variant=contained]": { gap: "control.trackInset" },
|
|
33
34
|
});
|
|
34
35
|
/* Text tabs: words only, the open one in the primary text, for a tray's or a sheet's filters. */
|
|
35
36
|
const textList = css({ "&[data-variant=text]": { gap: "layout.contentGap" } });
|
|
@@ -48,8 +49,9 @@ const tab = css({
|
|
|
48
49
|
alignItems: "center",
|
|
49
50
|
justifyContent: "center",
|
|
50
51
|
gap: "control.iconGap",
|
|
51
|
-
height: "control.
|
|
52
|
+
height: "control.restingTab",
|
|
52
53
|
paddingInline: "control.tabInline",
|
|
54
|
+
// The open tab's edge's own 1px, kept at rest too so a tab keeps its width as it opens.
|
|
53
55
|
border: "1px solid transparent",
|
|
54
56
|
borderRadius: "pill",
|
|
55
57
|
background: "transparent",
|
|
@@ -62,19 +64,26 @@ const tab = css({
|
|
|
62
64
|
cursor: "pointer",
|
|
63
65
|
flexShrink: "0",
|
|
64
66
|
"&[data-icon-tone=bronze] svg": { color: "accent.bronze" },
|
|
65
|
-
|
|
67
|
+
// The open tab is raised on the secondary button's face, with its gradient edge and soft shadow.
|
|
68
|
+
_before: { display: "none", background: "token(gradients.border.raised)" },
|
|
66
69
|
_hover: {
|
|
67
|
-
background: "bg.
|
|
70
|
+
background: "bg.controlHover",
|
|
68
71
|
color: "fg.primary",
|
|
69
72
|
"& svg": { color: "inherit" },
|
|
70
|
-
_before: { display: "block" },
|
|
71
73
|
},
|
|
72
74
|
"&[data-active]": {
|
|
73
|
-
background: "
|
|
75
|
+
background: "token(gradients.raised)",
|
|
76
|
+
boxShadow: "soft",
|
|
74
77
|
color: "fg.primary",
|
|
75
78
|
"& svg": { color: "inherit" },
|
|
76
79
|
_before: { display: "block" },
|
|
77
80
|
},
|
|
81
|
+
// On a face, the words read in the primary ink in light, where only the open tab is raised, and
|
|
82
|
+
// the open tab stands 2px taller than the rest.
|
|
83
|
+
"[data-variant=plain] > &, [data-variant=contained] > &": {
|
|
84
|
+
_light: { color: "fg.primary" },
|
|
85
|
+
"&[data-active]": { height: "control.small", _phone: { height: "control.compact" } },
|
|
86
|
+
},
|
|
78
87
|
// Words only: no face, no inset, and focus underlines the word rather than boxing it.
|
|
79
88
|
"[data-variant=text] > &": {
|
|
80
89
|
height: "auto",
|
|
@@ -83,8 +92,8 @@ const tab = css({
|
|
|
83
92
|
border: "0",
|
|
84
93
|
background: "transparent",
|
|
85
94
|
_hover: { background: "transparent" },
|
|
86
|
-
"&[data-active]": { background: "transparent" },
|
|
87
|
-
// No
|
|
95
|
+
"&[data-active]": { background: "transparent", boxShadow: "none" },
|
|
96
|
+
// No edge either: the open word is the only mark.
|
|
88
97
|
"&::before, &:hover::before, &[data-active]::before": { display: "none" },
|
|
89
98
|
_focusVisible: {
|
|
90
99
|
boxShadow: "none",
|
|
@@ -103,7 +112,11 @@ const tab = css({
|
|
|
103
112
|
marginBottom: "-1px",
|
|
104
113
|
background: "transparent",
|
|
105
114
|
_hover: { background: "transparent" },
|
|
106
|
-
"&[data-active]": {
|
|
115
|
+
"&[data-active]": {
|
|
116
|
+
background: "transparent",
|
|
117
|
+
boxShadow: "none",
|
|
118
|
+
borderBottomColor: "fg.primary",
|
|
119
|
+
},
|
|
107
120
|
"&::before, &:hover::before, &[data-active]::before": { display: "none" },
|
|
108
121
|
_phone: { height: "control.search", paddingInline: "none" },
|
|
109
122
|
},
|
|
@@ -190,7 +203,7 @@ export function TabsList({ className, variant = "plain", overflow: ownOverflow,
|
|
|
190
203
|
const overflow = ownOverflow ?? (inBar ? "menu" : "scroll");
|
|
191
204
|
const { labels } = useCiridaeLocale();
|
|
192
205
|
const { listRef, moreRef, overflowed, activeHidden, activate } = useOverflowedTabs(overflow === "menu", children);
|
|
193
|
-
return (_jsxs(BaseTabs.List, { ...props, ref: listRef, className: cx(list, variant === "contained" && containedList, variant === "text" && textList, variant === "underline" && underlineList, className), "data-ciridae-ui": "", "data-variant": variant, children: [children, overflow === "menu" && overflowed.length > 0 && (_jsx(Menu, { align: "end", trigger: _jsx("button", { type: "button", ref: moreRef, className: tab, "aria-label": labels.common.moreTabs, "data-ciridae-ui": "", "data-edge": "
|
|
206
|
+
return (_jsxs(BaseTabs.List, { ...props, ref: listRef, className: cx(list, variant === "contained" && containedList, variant === "text" && textList, variant === "underline" && underlineList, className), "data-ciridae-ui": "", "data-variant": variant, children: [children, overflow === "menu" && overflowed.length > 0 && (_jsx(Menu, { align: "end", trigger: _jsx("button", { type: "button", ref: moreRef, className: tab, "aria-label": labels.common.moreTabs, "data-ciridae-ui": "", "data-edge": "gradient", "data-active": activeHidden || undefined, children: _jsx(DotsThreeIcon, { className: icon({ size: "small" }), weight: "bold" }) }), items: overflowed.map((item) => ({
|
|
194
207
|
label: item.label,
|
|
195
208
|
meta: item.count,
|
|
196
209
|
onSelect: () => activate(item.index),
|
|
@@ -198,7 +211,7 @@ export function TabsList({ className, variant = "plain", overflow: ownOverflow,
|
|
|
198
211
|
}
|
|
199
212
|
export function TabsTab({ className, iconTone, href, render, count: tabCount, children, ...props }) {
|
|
200
213
|
const link = href !== undefined || render !== undefined;
|
|
201
|
-
return (_jsxs(BaseTabs.Tab, { ...props, render: render ?? (href !== undefined ? _jsx("a", { href: href }) : undefined), nativeButton: link ? false : props.nativeButton, className: cx(tab, className), "data-ciridae-ui": "", "data-edge": "
|
|
214
|
+
return (_jsxs(BaseTabs.Tab, { ...props, render: render ?? (href !== undefined ? _jsx("a", { href: href }) : undefined), nativeButton: link ? false : props.nativeButton, className: cx(tab, className), "data-ciridae-ui": "", "data-edge": "gradient", "data-icon-tone": iconTone, children: [children, tabCount !== undefined && tabCount !== null && (_jsx("span", { className: count, "data-tab-count": "", children: tabCount }))] }));
|
|
202
215
|
}
|
|
203
216
|
/*
|
|
204
217
|
* A page's tabs share one row with the open section's controls: tabs that do not fit go into the
|
|
@@ -40,7 +40,7 @@ export type UseThemeCustomizationOptions<Value extends ThemeCustomization> = {
|
|
|
40
40
|
*/
|
|
41
41
|
export declare function useThemeCustomization<Value extends ThemeCustomization>({ defaultValue, fonts, persistKey, parse, }: UseThemeCustomizationOptions<Value>): {
|
|
42
42
|
value: Value;
|
|
43
|
-
setValue: import("
|
|
43
|
+
setValue: import("react").Dispatch<import("react").SetStateAction<Value>>;
|
|
44
44
|
reset: () => void;
|
|
45
45
|
theme: Pick<CiridaeTheme, "fonts" | "palette">;
|
|
46
46
|
};
|
|
@@ -50,4 +50,4 @@ export type ThemeCustomizerProps<Value extends ThemeCustomization> = Omit<Compon
|
|
|
50
50
|
fonts: ThemeFontOptions;
|
|
51
51
|
labels?: Partial<CiridaeLabels["themeCustomizer"]>;
|
|
52
52
|
};
|
|
53
|
-
export declare function ThemeCustomizer<Value extends ThemeCustomization>({ value, onValueChange, fonts, labels: ownLabels, className, ...props }: ThemeCustomizerProps<Value>): import("
|
|
53
|
+
export declare function ThemeCustomizer<Value extends ThemeCustomization>({ value, onValueChange, fonts, labels: ownLabels, className, ...props }: ThemeCustomizerProps<Value>): import("react").JSX.Element;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CircleHalfIcon, MoonIcon, SunIcon } from "@phosphor-icons/react";
|
|
3
|
+
import { css, cx } from "#primitives/css";
|
|
4
|
+
import { useColorTheme } from "./color-theme.js";
|
|
5
|
+
import { faceEdge } from "./gradient-edge.js";
|
|
6
|
+
import { icon } from "./icon.js";
|
|
7
|
+
import { useCiridaeLocale } from "./locale.js";
|
|
8
|
+
/*
|
|
9
|
+
* Light, dark or the system's theme, as three icon segments in a pale track: the chosen one is
|
|
10
|
+
* raised on the secondary button's face, its icon in the primary ink, the others a step quieter.
|
|
11
|
+
*/
|
|
12
|
+
const track = css({
|
|
13
|
+
display: "inline-flex",
|
|
14
|
+
alignItems: "center",
|
|
15
|
+
gap: "control.trackInset",
|
|
16
|
+
padding: "control.trackInset",
|
|
17
|
+
// The design lays the track's edge over its inset, and rounds it to its options' corners.
|
|
18
|
+
border: "0",
|
|
19
|
+
borderRadius: "calc(token(radii.inset) + token(spacing.control.trackInset))",
|
|
20
|
+
background: "token(gradients.panel)",
|
|
21
|
+
});
|
|
22
|
+
const option = css({
|
|
23
|
+
display: "inline-grid",
|
|
24
|
+
placeItems: "center",
|
|
25
|
+
width: "control.small",
|
|
26
|
+
height: "calc(token(sizes.control.small) - 2 * token(spacing.control.trackInset))",
|
|
27
|
+
padding: "none",
|
|
28
|
+
border: "0",
|
|
29
|
+
borderRadius: "inset",
|
|
30
|
+
background: "transparent",
|
|
31
|
+
color: "fg.secondary",
|
|
32
|
+
cursor: "pointer",
|
|
33
|
+
transitionProperty: "background, color",
|
|
34
|
+
transitionDuration: "fast",
|
|
35
|
+
_hover: { color: "fg.primary" },
|
|
36
|
+
_focusVisible: { focusRing: "outer" },
|
|
37
|
+
_before: { display: "none", background: "token(gradients.border.raised)" },
|
|
38
|
+
"&[aria-pressed=true]": {
|
|
39
|
+
background: "token(gradients.raised)",
|
|
40
|
+
color: "fg.primary",
|
|
41
|
+
_before: { display: "block" },
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
/** Sets the color theme the `ThemeProvider` keeps: light, dark, or the operating system's. */
|
|
45
|
+
export function ThemeToggle({ className }) {
|
|
46
|
+
const { preference, setPreference } = useColorTheme();
|
|
47
|
+
const { labels } = useCiridaeLocale();
|
|
48
|
+
const trackEdge = faceEdge("raised");
|
|
49
|
+
const choices = [
|
|
50
|
+
{
|
|
51
|
+
value: "light",
|
|
52
|
+
label: labels.themeCustomizer.light,
|
|
53
|
+
glyph: _jsx(SunIcon, { className: icon({ size: "small" }) }),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: "dark",
|
|
57
|
+
label: labels.themeCustomizer.dark,
|
|
58
|
+
glyph: _jsx(MoonIcon, { className: icon({ size: "small" }) }),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
value: "system",
|
|
62
|
+
label: labels.themeCustomizer.system,
|
|
63
|
+
glyph: _jsx(CircleHalfIcon, { className: icon({ size: "small" }) }),
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
return (_jsx("div", { role: "group", "aria-label": labels.themeCustomizer.colorTheme, className: cx(track, trackEdge.className, className), "data-ciridae-ui": "", "data-edge": trackEdge["data-edge"], children: choices.map((choice) => (_jsx("button", { type: "button", "aria-label": choice.label, "aria-pressed": preference === choice.value, className: option, "data-ciridae-ui": "", "data-edge": "gradient", onClick: () => setPreference(choice.value), children: choice.glyph }, choice.value))) }));
|
|
67
|
+
}
|
|
@@ -2,7 +2,7 @@ import { toast, type ToasterProps } from "sonner";
|
|
|
2
2
|
import type { ComponentProps, ReactNode } from "react";
|
|
3
3
|
export { toast };
|
|
4
4
|
/** The toast stack, in the kit's look: mount one at the app's root. */
|
|
5
|
-
export declare function Toaster(props: ToasterProps): import("
|
|
5
|
+
export declare function Toaster(props: ToasterProps): import("react").JSX.Element;
|
|
6
6
|
export type ToastVariant = "success" | "progress" | "info" | "warning" | "error";
|
|
7
7
|
export type ToastOptions = {
|
|
8
8
|
title: ReactNode;
|
|
@@ -11,11 +11,18 @@ export type ToastOptions = {
|
|
|
11
11
|
variant?: ToastVariant;
|
|
12
12
|
/** Milliseconds it stays; `0` keeps it until dismissed. An error stays by default. */
|
|
13
13
|
timeout?: number;
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* One small secondary button, such as Undo; its children are the label. It closes the toast, and
|
|
16
|
+
* takes the close button's place.
|
|
17
|
+
*/
|
|
15
18
|
actionProps?: Pick<ComponentProps<"button">, "children" | "onClick">;
|
|
19
|
+
/** Replaces the toast already shown with this id, such as a progress toast moving along. */
|
|
20
|
+
id?: string | number;
|
|
21
|
+
/** How far a `progress` toast is, 0 to 100, shown as a track and a percentage after its message. */
|
|
22
|
+
percent?: number;
|
|
16
23
|
};
|
|
17
24
|
/** Raises a toast with the kit's options, returning its id. */
|
|
18
|
-
declare function addToast({ title:
|
|
25
|
+
declare function addToast({ title: ownMessage, description: detail, variant, timeout, actionProps, id, percent, }: ToastOptions): string | number;
|
|
19
26
|
/** The kit's toast calls: `add` raises one and returns its id, `close` dismisses it. */
|
|
20
27
|
export declare function useToast(): {
|
|
21
28
|
add: typeof addToast;
|