@sentropic/design-system-react 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AreaChart.d.ts +16 -2
- package/dist/AreaChart.d.ts.map +1 -1
- package/dist/AreaChart.js +96 -1
- package/dist/AreaChart.js.map +1 -1
- package/dist/BarChart.d.ts +16 -2
- package/dist/BarChart.d.ts.map +1 -1
- package/dist/BarChart.js +90 -1
- package/dist/BarChart.js.map +1 -1
- package/dist/DataTable.d.ts +49 -2
- package/dist/DataTable.d.ts.map +1 -1
- package/dist/DataTable.js +144 -1
- package/dist/DataTable.js.map +1 -1
- package/dist/DonutChart.d.ts +19 -2
- package/dist/DonutChart.d.ts.map +1 -1
- package/dist/DonutChart.js +61 -1
- package/dist/DonutChart.js.map +1 -1
- package/dist/LineChart.d.ts +17 -2
- package/dist/LineChart.d.ts.map +1 -1
- package/dist/LineChart.js +92 -1
- package/dist/LineChart.js.map +1 -1
- package/dist/ScatterPlot.d.ts +19 -2
- package/dist/ScatterPlot.d.ts.map +1 -1
- package/dist/ScatterPlot.js +55 -1
- package/dist/ScatterPlot.js.map +1 -1
- package/dist/Sparkline.d.ts +13 -2
- package/dist/Sparkline.d.ts.map +1 -1
- package/dist/Sparkline.js +32 -1
- package/dist/Sparkline.js.map +1 -1
- package/dist/StackedBarChart.d.ts +20 -2
- package/dist/StackedBarChart.d.ts.map +1 -1
- package/dist/StackedBarChart.js +78 -1
- package/dist/StackedBarChart.js.map +1 -1
- package/dist/catalog.d.ts +41 -95
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +61 -78
- package/dist/catalog.js.map +1 -1
- package/dist/chartScale.d.ts +25 -0
- package/dist/chartScale.d.ts.map +1 -0
- package/dist/chartScale.js +71 -0
- package/dist/chartScale.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/styles.css +24 -0
- package/package.json +1 -1
package/dist/catalog.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { classNames } from "./classNames.js";
|
|
4
|
+
// Normalises an action item so the rest of the component only deals with the
|
|
5
|
+
// React-native shape: `id` (from id|value) and `variant` (from variant|danger).
|
|
6
|
+
function actionId(item, index, prefix = "item") {
|
|
7
|
+
return item.id ?? item.value ?? (index === undefined ? undefined : `${prefix}-${index}`);
|
|
8
|
+
}
|
|
9
|
+
function isDangerAction(item) {
|
|
10
|
+
return item.variant === "danger" || item.danger === true;
|
|
11
|
+
}
|
|
4
12
|
const DATA_TONES = [
|
|
5
13
|
"category1",
|
|
6
14
|
"category2",
|
|
@@ -137,21 +145,12 @@ function pct(value, min = 0, max = 100) {
|
|
|
137
145
|
return 0;
|
|
138
146
|
return clamp(((value - min) / (max - min)) * 100, 0, 100);
|
|
139
147
|
}
|
|
140
|
-
function
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
.map((value, index) => {
|
|
145
|
-
const x = ys.length === 1 ? width / 2 : (index / (ys.length - 1)) * width;
|
|
146
|
-
const y = height - (value / max) * height;
|
|
147
|
-
return `${x},${y}`;
|
|
148
|
-
})
|
|
149
|
-
.join(" ");
|
|
150
|
-
}
|
|
151
|
-
export function Accordion({ items, openIds, defaultOpenIds = [], allowMultiple = true, onChange, className, ...rest }) {
|
|
152
|
-
const [open, setOpen] = useControlled(openIds, defaultOpenIds, onChange);
|
|
148
|
+
export function Accordion({ items, openIds, defaultOpenIds, open: openAlias, allowMultiple, multiple, onChange, className, ...rest }) {
|
|
149
|
+
const initialOpen = defaultOpenIds ?? openAlias ?? [];
|
|
150
|
+
const resolvedAllowMultiple = allowMultiple ?? multiple ?? true;
|
|
151
|
+
const [open, setOpen] = useControlled(openIds, initialOpen, onChange);
|
|
153
152
|
const toggle = (id) => {
|
|
154
|
-
const next = open.includes(id) ? open.filter((value) => value !== id) :
|
|
153
|
+
const next = open.includes(id) ? open.filter((value) => value !== id) : resolvedAllowMultiple ? [...open, id] : [id];
|
|
155
154
|
setOpen(next);
|
|
156
155
|
};
|
|
157
156
|
return (_jsx("div", { ...rest, className: classNames("st-accordion", className), children: items.map((item, index) => {
|
|
@@ -165,46 +164,6 @@ export function Accordion({ items, openIds, defaultOpenIds = [], allowMultiple =
|
|
|
165
164
|
export function Alert({ tone = "info", title, message, actions, children, className, ...rest }) {
|
|
166
165
|
return (_jsxs("section", { ...rest, className: classNames("st-alert", `st-alert--${tone}`, className), role: tone === "warning" || tone === "error" ? "alert" : "status", children: [_jsxs("div", { className: "st-alert__content", children: [_jsx("h2", { className: "st-alert__title", children: title }), message ? _jsx("p", { className: "st-alert__message", children: message }) : null, children] }), actions ? _jsx("div", { className: "st-alert__actions", children: actions }) : null] }));
|
|
167
166
|
}
|
|
168
|
-
function LinearChart({ data, label, width = 320, height = 160, className, type }) {
|
|
169
|
-
const classBase = type === "areaChart" ? "st-areaChart" : "st-lineChart";
|
|
170
|
-
const points = pointsFrom(data, width, height);
|
|
171
|
-
const accessibleLabel = label ?? (type === "areaChart" ? "Area chart" : "Line chart");
|
|
172
|
-
return (_jsxs("figure", { className: classNames(classBase, className), "aria-label": accessibleLabel, children: [_jsx("span", { className: "st-visually-hidden", children: accessibleLabel }), _jsxs("svg", { viewBox: `0 0 `, "aria-hidden": "true", children: [_jsx("polyline", { className: `${classBase}__line`, points: points, fill: "none" }), type === "areaChart" ? _jsx("polygon", { className: "st-areaChart__area", points: `0,${height} ${points} ${width},${height}` }) : null, data.map((datum, index) => (_jsx("circle", { className: `${classBase}__dot`, cx: points.split(" ")[index]?.split(",")[0], cy: points.split(" ")[index]?.split(",")[1], r: "4" }, index)))] })] }));
|
|
173
|
-
}
|
|
174
|
-
export function AreaChart(props) {
|
|
175
|
-
return _jsx(LinearChart, { ...props, type: "areaChart" });
|
|
176
|
-
}
|
|
177
|
-
export function LineChart(props) {
|
|
178
|
-
return _jsx(LinearChart, { ...props, type: "lineChart" });
|
|
179
|
-
}
|
|
180
|
-
export function BarChart({ data, label = "Bar chart", width = 320, height = 160, className, ...rest }) {
|
|
181
|
-
const max = Math.max(...data.map((datum) => datum.value ?? datum.y ?? 0), 1);
|
|
182
|
-
return (_jsxs("figure", { ...rest, className: classNames("st-barChart", className), "aria-label": label, children: [_jsx("span", { className: "st-visually-hidden", children: label }), _jsx("svg", { viewBox: `0 0 `, "aria-hidden": "true", children: data.map((datum, index) => {
|
|
183
|
-
const value = datum.value ?? datum.y ?? 0;
|
|
184
|
-
const barWidth = width / Math.max(data.length, 1) - 8;
|
|
185
|
-
const barHeight = (value / max) * height;
|
|
186
|
-
return (_jsx("rect", { className: classNames("st-barChart__bar", `st-barChart__bar--${datum.tone ?? DATA_TONES[index % DATA_TONES.length]}`), x: index * (barWidth + 8) + 4, y: height - barHeight, width: barWidth, height: barHeight }, index));
|
|
187
|
-
}) })] }));
|
|
188
|
-
}
|
|
189
|
-
export function DonutChart({ data, label = "Donut chart", className, ...rest }) {
|
|
190
|
-
const total = data.reduce((sum, datum) => sum + (datum.value ?? datum.y ?? 0), 0);
|
|
191
|
-
return (_jsxs("figure", { ...rest, className: classNames("st-donutChart", className), "aria-label": label, children: [_jsx("span", { className: "st-visually-hidden", children: label }), _jsxs("svg", { viewBox: "0 0 120 120", "aria-hidden": "true", children: [data.map((datum, index) => (_jsx("circle", { className: classNames("st-donutChart__slice", `st-donutChart__slice--${datum.tone ?? DATA_TONES[index % DATA_TONES.length]}`), cx: "60", cy: "60", r: 36 - index * 3, fill: "none", strokeWidth: "8" }, index))), _jsx("text", { className: "st-donutChart__center", x: "60", y: "64", textAnchor: "middle", children: total })] })] }));
|
|
192
|
-
}
|
|
193
|
-
export function ScatterPlot({ data, label = "Scatter chart", className, ...rest }) {
|
|
194
|
-
return (_jsxs("figure", { ...rest, className: classNames("st-scatterPlot", className), "aria-label": label, children: [_jsx("span", { className: "st-visually-hidden", children: label }), _jsx("svg", { viewBox: "0 0 320 160", "aria-hidden": "true", children: data.map((datum, index) => (_jsx("circle", { className: classNames("st-scatterPlot__point", `st-scatterPlot__point--${datum.tone ?? DATA_TONES[index % DATA_TONES.length]}`), cx: clamp(datum.x * 24 + 24, 12, 308), cy: clamp(148 - datum.y * 24, 12, 148), r: "5", children: _jsx("title", { children: datum.label ?? `${datum.x}, ${datum.y}` }) }, index))) })] }));
|
|
195
|
-
}
|
|
196
|
-
export function StackedBarChart({ data, label = "Stacked bar chart", className, ...rest }) {
|
|
197
|
-
return (_jsxs("figure", { ...rest, className: classNames("st-stackedBar", className), "aria-label": label, children: [_jsx("span", { className: "st-visually-hidden", children: label }), _jsx("svg", { viewBox: "0 0 320 160", "aria-hidden": "true", children: data.map((bar, barIndex) => {
|
|
198
|
-
let x = 16;
|
|
199
|
-
const total = Math.max(bar.segments.reduce((sum, segment) => sum + segment.value, 0), 1);
|
|
200
|
-
return (_jsxs("g", { transform: `translate(0 ${barIndex * 32 + 16})`, children: [bar.segments.map((segment, index) => {
|
|
201
|
-
const width = (segment.value / total) * 220;
|
|
202
|
-
const rect = (_jsx("rect", { className: classNames("st-stackedBar__seg", `st-stackedBar__seg--${segment.tone ?? DATA_TONES[index % DATA_TONES.length]}`), x: x, y: "0", width: width, height: "20" }, segment.label));
|
|
203
|
-
x += width;
|
|
204
|
-
return rect;
|
|
205
|
-
}), _jsx("text", { className: "st-stackedBar__categoryLabel", x: "250", y: "15", children: bar.label })] }, bar.label));
|
|
206
|
-
}) })] }));
|
|
207
|
-
}
|
|
208
167
|
export function AspectRatio({ ratio = "16 / 9", className, style, children, ...rest }) {
|
|
209
168
|
const aspectRatio = typeof ratio === "number" ? String(ratio) : ratio;
|
|
210
169
|
return (_jsx("div", { ...rest, className: classNames("st-aspectRatio", className), style: { aspectRatio, ...style }, children: children }));
|
|
@@ -292,11 +251,12 @@ export function Combobox({ label, options, value, size = "md", placeholder = "Se
|
|
|
292
251
|
selectOption(option);
|
|
293
252
|
}, children: option.label }, option.value)))) : (_jsx("li", { className: "st-combobox__empty", role: "option", "aria-disabled": "true", "aria-selected": "false", children: noResultsLabel })) })) : null] }));
|
|
294
253
|
}
|
|
295
|
-
export function ContentSwitcher({ items, value, activeId, onChange, size = "md", className, ...rest }) {
|
|
254
|
+
export function ContentSwitcher({ items, value, activeId, onChange, onchange, size = "md", className, ...rest }) {
|
|
255
|
+
const handleChange = onChange ?? onchange;
|
|
296
256
|
const current = value ?? activeId ?? idFrom(items[0] ?? {}, 0, "content");
|
|
297
257
|
return (_jsx("div", { ...rest, className: classNames("st-contentSwitcher", `st-contentSwitcher--${size}`, className), role: "group", children: items.map((item, index) => {
|
|
298
258
|
const itemId = idFrom(item, index, "content");
|
|
299
|
-
return (_jsx("button", { type: "button", className: classNames("st-contentSwitcher__option st-contentSwitcher__button", itemId === current && "st-contentSwitcher__option--selected"), disabled: item.disabled, "aria-pressed": itemId === current, onClick: () =>
|
|
259
|
+
return (_jsx("button", { type: "button", className: classNames("st-contentSwitcher__option st-contentSwitcher__button", itemId === current && "st-contentSwitcher__option--selected"), disabled: item.disabled, "aria-pressed": itemId === current, onClick: () => handleChange?.(itemId), children: item.label }, itemId));
|
|
300
260
|
}) }));
|
|
301
261
|
}
|
|
302
262
|
export function CopyButton({ text: copyText, value, label = "Copy", copiedLabel = "Copied", size = "md", className, onClick, ...rest }) {
|
|
@@ -307,11 +267,6 @@ export function CopyButton({ text: copyText, value, label = "Copy", copiedLabel
|
|
|
307
267
|
onClick?.(event);
|
|
308
268
|
}, children: _jsx("span", { className: "st-copyButton__label", children: copied ? copiedLabel : label }) }));
|
|
309
269
|
}
|
|
310
|
-
export function DataTable({ columns, rows, caption, size = "md", className, pageSize, page = 1, totalItems, ...rest }) {
|
|
311
|
-
const visibleRows = pageSize ? rows.slice((page - 1) * pageSize, page * pageSize) : rows;
|
|
312
|
-
const total = totalItems ?? rows.length;
|
|
313
|
-
return (_jsxs("div", { className: "st-dataTable-wrap", children: [_jsxs("table", { ...rest, className: classNames("st-dataTable", `st-dataTable--${size}`, className), children: [caption ? _jsx("caption", { children: caption }) : null, _jsx("thead", { children: _jsx("tr", { children: columns.map((column) => _jsx("th", { children: column.label }, column.key)) }) }), _jsx("tbody", { children: visibleRows.map((row) => (_jsx("tr", { children: columns.map((column) => (_jsx("td", { className: classNames(column.align === "center" && "st-dataTable__cell--center", column.align === "end" && "st-dataTable__cell--end"), children: column.render?.(row, column) ?? text(row[column.key]) }, column.key))) }, row.id))) })] }), pageSize ? _jsx("div", { className: "st-dataTable__pagerStatus", children: `${(page - 1) * pageSize + 1}-${Math.min(page * pageSize, total)} of ${total}` }) : null] }));
|
|
314
|
-
}
|
|
315
270
|
export function DatePicker({ label, value, size = "md", className, ...rest }) {
|
|
316
271
|
return (_jsx("div", { ...rest, className: classNames("st-datepicker", `st-datepicker--${size}`, className), children: _jsx(Field, { label: label, children: (inputId) => _jsx("input", { id: inputId, className: "st-control st-datepicker__control", type: "date", defaultValue: value }) }) }));
|
|
317
272
|
}
|
|
@@ -338,7 +293,8 @@ export function Drawer({ open = false, title, description, footer, placement = "
|
|
|
338
293
|
onClose?.();
|
|
339
294
|
}, children: _jsxs("aside", { ...rest, ref: panelRef, className: classNames("st-drawer", `st-drawer--${placement}`, className), role: "dialog", "aria-modal": "true", "aria-label": text(title) || "Drawer", tabIndex: -1, onKeyDown: (event) => trapTabKey(event, panelRef.current), children: [_jsxs("div", { className: "st-drawer__header", children: [title ? _jsx("h2", { className: "st-drawer__title", children: title }) : null, _jsx("button", { ref: closeRef, type: "button", className: "st-drawer__close", onClick: onClose, "aria-label": "Close", children: "x" })] }), description ? _jsx("p", { className: "st-drawer__description", children: description }) : null, _jsx("div", { className: "st-drawer__body", children: children }), footer ? _jsx("div", { className: "st-drawer__footer", children: footer }) : null] }) }));
|
|
340
295
|
}
|
|
341
|
-
export function Dropdown({ label = "Select", options, value, open: controlledOpen, placeholder = "Select", onSelect, className, ...rest }) {
|
|
296
|
+
export function Dropdown({ label = "Select", options, value, open: controlledOpen, placeholder = "Select", onSelect, onselect, className, ...rest }) {
|
|
297
|
+
const handleSelect = onSelect ?? onselect;
|
|
342
298
|
const hostRef = React.useRef(null);
|
|
343
299
|
const itemRefs = React.useRef([]);
|
|
344
300
|
const [open, setOpen] = useControlled(controlledOpen, false);
|
|
@@ -358,7 +314,7 @@ export function Dropdown({ label = "Select", options, value, open: controlledOpe
|
|
|
358
314
|
setCurrent(option.value);
|
|
359
315
|
setOpen(false);
|
|
360
316
|
setActiveIndex(-1);
|
|
361
|
-
|
|
317
|
+
handleSelect?.(option.value);
|
|
362
318
|
};
|
|
363
319
|
useOutsideMouseDown(open, hostRef, () => setOpen(false));
|
|
364
320
|
useEscape(open, () => setOpen(false));
|
|
@@ -392,8 +348,30 @@ export function Dropdown({ label = "Select", options, value, open: controlledOpe
|
|
|
392
348
|
export function EmptyState({ title, message, action, children, className, ...rest }) {
|
|
393
349
|
return (_jsx("section", { ...rest, className: classNames("st-empty-state st-emptyState", className), children: _jsxs("div", { className: "st-empty-state__content", children: [_jsx("h2", { className: "st-empty-state__title st-emptyState__title", children: title }), message ? _jsx("p", { className: "st-empty-state__message st-emptyState__message", children: message }) : null, children, action ? _jsx("div", { className: "st-empty-state__action", children: action }) : null] }) }));
|
|
394
350
|
}
|
|
351
|
+
function formatFileSize(bytes) {
|
|
352
|
+
if (typeof bytes !== "number" || !Number.isFinite(bytes) || bytes < 0)
|
|
353
|
+
return "";
|
|
354
|
+
if (bytes === 0)
|
|
355
|
+
return "0 B";
|
|
356
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
357
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
|
|
358
|
+
const value = bytes / Math.pow(1024, i);
|
|
359
|
+
const formatted = value >= 10 || i === 0 ? value.toFixed(0) : value.toFixed(1);
|
|
360
|
+
return `${formatted} ${units[i]}`;
|
|
361
|
+
}
|
|
362
|
+
function fileItemName(item) {
|
|
363
|
+
return item.file?.name ?? item.name;
|
|
364
|
+
}
|
|
365
|
+
function fileItemSize(item) {
|
|
366
|
+
return item.file?.size ?? item.size;
|
|
367
|
+
}
|
|
395
368
|
export function FileUploader({ label = "Upload", items = [], disabled = false, className, ...rest }) {
|
|
396
|
-
return (_jsxs("div", { ...rest, className: classNames("st-fileUploader-field", className), children: [_jsxs("div", { className: classNames("st-fileUploader__dropzone", disabled && "st-fileUploader__dropzone--disabled"), children: [_jsx("span", { className: "st-fileUploader__trigger", children: label }), _jsx("input", { className: "st-fileUploader__input", type: "file", disabled: disabled, "aria-label": text(label) })] }), _jsx("ul", { className: "st-fileUploader__list", children: items.map((item, index) =>
|
|
369
|
+
return (_jsxs("div", { ...rest, className: classNames("st-fileUploader-field", className), children: [_jsxs("div", { className: classNames("st-fileUploader__dropzone", disabled && "st-fileUploader__dropzone--disabled"), children: [_jsx("span", { className: "st-fileUploader__trigger", children: label }), _jsx("input", { className: "st-fileUploader__input", type: "file", disabled: disabled, "aria-label": text(label) })] }), _jsx("ul", { className: "st-fileUploader__list", children: items.map((item, index) => {
|
|
370
|
+
const name = fileItemName(item);
|
|
371
|
+
const size = fileItemSize(item);
|
|
372
|
+
const sizeLabel = formatFileSize(size);
|
|
373
|
+
return (_jsxs("li", { className: classNames("st-fileUploader__item", item.status && `st-fileUploader__item--${item.status}`), children: [_jsx("span", { className: "st-fileUploader__itemName st-fileUploader__name", children: name }), sizeLabel ? _jsx("span", { className: "st-fileUploader__itemSize", children: sizeLabel }) : null, item.error ? _jsx("span", { className: "st-fileUploader__itemError", children: item.error }) : null] }, item.id ?? name ?? index));
|
|
374
|
+
}) })] }));
|
|
397
375
|
}
|
|
398
376
|
export function Footer({ brand, columns, links, copyright, className, ...rest }) {
|
|
399
377
|
const groups = columns ?? (links ? [{ links }] : []);
|
|
@@ -805,11 +783,15 @@ export function Link({ muted = false, standalone = false, disabled = false, clas
|
|
|
805
783
|
export function LoadingState({ label, title, variant = "spinner", className, ...rest }) {
|
|
806
784
|
return (_jsxs("section", { ...rest, className: classNames("st-loading", `st-loading--${variant}`, className), "aria-live": "polite", children: [_jsx("span", { className: "st-loading__spinner", "aria-hidden": "true" }), _jsx("span", { className: "st-loading__label", children: label ?? title ?? "Loading" })] }));
|
|
807
785
|
}
|
|
786
|
+
function itemKind(item) {
|
|
787
|
+
const tagged = item;
|
|
788
|
+
return tagged.type ?? tagged.kind;
|
|
789
|
+
}
|
|
808
790
|
function isDivider(item) {
|
|
809
|
-
return
|
|
791
|
+
return itemKind(item) === "divider";
|
|
810
792
|
}
|
|
811
793
|
function isGroup(item) {
|
|
812
|
-
return
|
|
794
|
+
return itemKind(item) === "group";
|
|
813
795
|
}
|
|
814
796
|
export function Menu({ items, dense = false, onSelect, className, role, ...rest }) {
|
|
815
797
|
const rootRef = React.useRef(null);
|
|
@@ -843,19 +825,21 @@ export function Menu({ items, dense = false, onSelect, className, role, ...rest
|
|
|
843
825
|
if (isDivider(item))
|
|
844
826
|
return _jsx("div", { className: "st-menu__divider", role: "separator" }, item.id ?? index);
|
|
845
827
|
if (isGroup(item)) {
|
|
846
|
-
return (_jsxs("section", { className: "st-menu__group", children: [_jsx("h3", { children: item.label }), item.items.map((child) => (_jsx("button", { type: "button", role: "menuitem", className: "st-menu__item", disabled: child.disabled, onClick: () => onSelect?.(child), onKeyDown: (event) => handleItemKeyDown(event, child), children: _jsx("span", { className: "st-menu__itemLabel", children: child.label }) }, child
|
|
828
|
+
return (_jsxs("section", { className: "st-menu__group", children: [_jsx("h3", { children: item.label }), (item.items ?? []).map((child) => (_jsx("button", { type: "button", role: "menuitem", className: classNames("st-menu__item", isDangerAction(child) && "st-menu__item--danger"), disabled: child.disabled, onClick: () => onSelect?.(child), onKeyDown: (event) => handleItemKeyDown(event, child), children: _jsx("span", { className: "st-menu__itemLabel", children: child.label }) }, actionId(child) ?? text(child.label))))] }, item.id ?? index));
|
|
847
829
|
}
|
|
848
|
-
|
|
830
|
+
const action = item;
|
|
831
|
+
return (_jsx("button", { type: "button", role: "menuitem", disabled: action.disabled, className: classNames("st-menu__item", isDangerAction(action) && "st-menu__item--danger"), onClick: () => onSelect?.(action), onKeyDown: (event) => handleItemKeyDown(event, action), children: _jsx("span", { className: "st-menu__itemLabel", children: action.label }) }, actionId(action) ?? text(action.label) ?? index));
|
|
849
832
|
}) }));
|
|
850
833
|
}
|
|
851
834
|
export function MenuPopover({ trigger, items = [], open = true, placement = "bottom-start", children, className, ...rest }) {
|
|
852
835
|
return (_jsxs("div", { ...rest, className: classNames("st-menuPopover", `st-menuPopover--${placement}`, className), children: [trigger, open ? _jsx("div", { className: "st-menuPopover__content", children: items.length ? _jsx(Menu, { items: items, role: "presentation" }) : children }) : null] }));
|
|
853
836
|
}
|
|
854
|
-
export function MenuTriggerButton({ open
|
|
855
|
-
|
|
837
|
+
export function MenuTriggerButton({ open, expanded, type = "button", className, children, ...rest }) {
|
|
838
|
+
const isOpen = open ?? expanded ?? false;
|
|
839
|
+
return (_jsx("button", { ...rest, type: type, className: classNames("st-menuTriggerButton st-button st-button--secondary st-button--sm", className), "aria-expanded": isOpen, children: children }));
|
|
856
840
|
}
|
|
857
841
|
export function MessageActions({ actions, visibility = "always", className, ...rest }) {
|
|
858
|
-
return (_jsx("nav", { ...rest, className: classNames("st-messageActions", visibility === "hover" && "st-messageActions--hoverOnly", className), "aria-label": "Message actions", children: actions.map((action, index) => (_jsx("button", { type: "button", className: classNames("st-button st-button--ghost st-button--sm", action.variant === "danger" && "st-button--danger"), disabled: action.disabled, onClick: action.onClick, children: action.label }, action.id ?? index))) }));
|
|
842
|
+
return (_jsx("nav", { ...rest, className: classNames("st-messageActions", visibility === "hover" && "st-messageActions--hoverOnly", className), "aria-label": "Message actions", children: actions.map((action, index) => (_jsx("button", { type: "button", className: classNames("st-button st-button--ghost st-button--sm", action.variant === "danger" && "st-button--danger"), disabled: action.disabled, "aria-label": action.label == null && action.icon != null ? text(action.id) || undefined : undefined, onClick: action.onClick, children: action.label ?? action.icon }, action.id ?? index))) }));
|
|
859
843
|
}
|
|
860
844
|
export function MessageStatusBadge({ status, tone, labels, className, ...rest }) {
|
|
861
845
|
const normalized = status === "sent" ? "completed" : status === "streaming" ? "processing" : status === "error" ? "failed" : status;
|
|
@@ -930,8 +914,9 @@ export function Pagination({ page, pageSize = 10, totalItems, totalPages, pageCo
|
|
|
930
914
|
const visiblePages = Array.from({ length: pages }, (_, index) => index + 1);
|
|
931
915
|
return (_jsxs("nav", { ...rest, className: classNames("st-pagination", className), "aria-label": "Pagination", children: [_jsx("button", { type: "button", disabled: page <= 1, onClick: () => onPageChange?.(page - 1), children: "Previous" }), _jsx("span", { className: "st-pagination__page--active", children: totalItems ? `${start}-${end} of ${totalItems}` : `Page ${page} of ${pages}` }), _jsx("span", { className: "st-pagination__pages", children: visiblePages.map((pageNumber) => (_jsx("button", { type: "button", className: classNames("st-pagination__page", pageNumber === page && "st-pagination__page--active"), "aria-label": `Page ${pageNumber}`, "aria-current": pageNumber === page ? "page" : undefined, onClick: () => onPageChange?.(pageNumber), children: pageNumber }, pageNumber))) }), _jsx("button", { type: "button", disabled: page >= pages, onClick: () => onPageChange?.(page + 1), children: "Next" })] }));
|
|
932
916
|
}
|
|
933
|
-
export function PaginationNav({ page = 1, totalPages
|
|
934
|
-
|
|
917
|
+
export function PaginationNav({ page = 1, totalPages, pageCount, previousHref, nextHref, className, ...rest }) {
|
|
918
|
+
const pages = totalPages ?? pageCount ?? 1;
|
|
919
|
+
return (_jsxs("nav", { ...rest, className: classNames("st-paginationNav", className), "aria-label": "Pagination navigation", children: [previousHref ? _jsx("a", { href: previousHref, children: "Previous" }) : _jsx("button", { type: "button", disabled: page <= 1, children: "Previous" }), _jsx("ol", { className: "st-paginationNav__list", children: Array.from({ length: pages }, (_, index) => index + 1).map((item) => (_jsx("li", { children: _jsxs("button", { type: "button", className: classNames("st-paginationNav__page", item === page && "st-paginationNav__page--active"), children: ["Page ", item] }) }, item))) }), nextHref ? _jsx("a", { href: nextHref, children: "Next" }) : _jsx("button", { type: "button", disabled: page >= pages, children: "Next" })] }));
|
|
935
920
|
}
|
|
936
921
|
export function PasswordInput({ label, helperText, errorText, size = "md", className, ...rest }) {
|
|
937
922
|
const [shown, setShown] = React.useState(false);
|
|
@@ -978,9 +963,6 @@ export function Slider({ label, size = "md", value, defaultValue, min = 0, max =
|
|
|
978
963
|
const numeric = Number(value ?? defaultValue ?? 0);
|
|
979
964
|
return (_jsxs("div", { className: classNames("st-slider", `st-slider--${size}`, className), children: [_jsxs("div", { className: "st-slider__header", children: [label ? _jsx("label", { className: "st-field__label", children: label }) : null, _jsx("span", { className: "st-slider__value", children: numeric })] }), _jsx("input", { ...rest, className: "st-slider__input", type: "range", min: min, max: max, defaultValue: defaultValue, value: value })] }));
|
|
980
965
|
}
|
|
981
|
-
export function Sparkline({ data, label = "Sparkline", tone = "neutral", className, ...rest }) {
|
|
982
|
-
return (_jsxs("figure", { ...rest, className: classNames("st-sparkline", `st-sparkline--${tone}`, className), "aria-label": label, children: [_jsx("span", { className: "st-visually-hidden", children: label }), _jsx("svg", { viewBox: "0 0 120 40", "aria-hidden": "true", children: _jsx("polyline", { className: "st-sparkline__line", points: pointsFrom(data, 120, 40), fill: "none" }) })] }));
|
|
983
|
-
}
|
|
984
966
|
export function StreamingMessage({ text: messageText, events = [], mode = "live", className, ...rest }) {
|
|
985
967
|
return (_jsxs("section", { ...rest, className: classNames("st-streamingMessage", `st-streamingMessage--${mode}`, className), children: [_jsx("div", { className: "st-streamingMessage__text", children: messageText }), _jsx("ul", { className: "st-streamingMessage__trailList", children: events.map((event) => _jsx("li", { children: event.label }, event.id)) })] }));
|
|
986
968
|
}
|
|
@@ -993,11 +975,12 @@ export function Switch({ label, helperText, className, ...rest }) {
|
|
|
993
975
|
export function Table({ columns, rows, caption = "Table", className, ...rest }) {
|
|
994
976
|
return (_jsx("div", { className: "st-table-wrap", children: _jsxs("table", { ...rest, className: classNames("st-table", className), children: [_jsx("caption", { children: caption }), _jsx("thead", { children: _jsx("tr", { children: columns.map((column) => _jsx("th", { children: column.label }, column.key)) }) }), _jsx("tbody", { children: rows.map((row, index) => (_jsx("tr", { children: columns.map((column) => _jsx("td", { className: classNames(column.align === "center" && "st-table__cell--center", (column.align === "right" || column.align === "end") && "st-table__cell--right"), children: text(row[column.key]) }, column.key)) }, text(row.id) || index))) })] }) }));
|
|
995
977
|
}
|
|
996
|
-
export function Tabs({ items, activeValue, activeId, label = "Tabs", onChange, className, ...rest }) {
|
|
978
|
+
export function Tabs({ items, activeValue, activeId, label = "Tabs", onChange, onchange, className, ...rest }) {
|
|
979
|
+
const handleChange = onChange ?? onchange;
|
|
997
980
|
const reactId = React.useId();
|
|
998
981
|
const tabRefs = React.useRef([]);
|
|
999
982
|
const first = items.find((item) => !item.disabled) ?? items[0];
|
|
1000
|
-
const [current, setCurrent] = useControlled(activeValue ?? activeId, idFrom(first ?? {}, 0, "tab"),
|
|
983
|
+
const [current, setCurrent] = useControlled(activeValue ?? activeId, idFrom(first ?? {}, 0, "tab"), handleChange);
|
|
1001
984
|
const itemIds = items.map((item, index) => idFrom(item, index, "tab"));
|
|
1002
985
|
const activeIndex = Math.max(0, itemIds.indexOf(current));
|
|
1003
986
|
const active = items[activeIndex] ?? first;
|