@santi020k/lumen-react 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +666 -13
- package/dist/ai-surfaces.d.ts +49 -0
- package/dist/ai-surfaces.d.ts.map +1 -0
- package/dist/ai-surfaces.js +88 -0
- package/dist/amount-field.d.ts +11 -0
- package/dist/amount-field.d.ts.map +1 -0
- package/dist/amount-field.js +37 -0
- package/dist/attachments.d.ts +17 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +23 -0
- package/dist/bullet-chart.d.ts +14 -0
- package/dist/bullet-chart.d.ts.map +1 -0
- package/dist/bullet-chart.js +22 -0
- package/dist/change-summary.d.ts +14 -0
- package/dist/change-summary.d.ts.map +1 -0
- package/dist/change-summary.js +4 -0
- package/dist/chart-inspection.d.ts +10 -0
- package/dist/chart-inspection.d.ts.map +1 -0
- package/dist/chart-inspection.js +11 -0
- package/dist/chart-interaction.d.ts +17 -0
- package/dist/chart-interaction.d.ts.map +1 -0
- package/dist/chart-interaction.js +50 -0
- package/dist/chart-label.d.ts +3 -0
- package/dist/chart-label.d.ts.map +1 -0
- package/dist/chart-label.js +1 -0
- package/dist/chart-recipes.d.ts +8 -0
- package/dist/chart-recipes.d.ts.map +1 -1
- package/dist/chart-recipes.js +35 -0
- package/dist/combobox.d.ts +9 -0
- package/dist/combobox.d.ts.map +1 -0
- package/dist/combobox.js +137 -0
- package/dist/comparison-chart.d.ts +13 -0
- package/dist/comparison-chart.d.ts.map +1 -0
- package/dist/comparison-chart.js +18 -0
- package/dist/components.d.ts +106 -70
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -1949
- package/dist/dashboard.d.ts +20 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +19 -0
- package/dist/data-table-range-model.d.ts +8 -0
- package/dist/data-table-range-model.d.ts.map +1 -0
- package/dist/data-table-range-model.js +31 -0
- package/dist/data-table-range.d.ts +17 -0
- package/dist/data-table-range.d.ts.map +1 -0
- package/dist/data-table-range.js +8 -0
- package/dist/data-table-saved-views.d.ts +30 -0
- package/dist/data-table-saved-views.d.ts.map +1 -0
- package/dist/data-table-saved-views.js +49 -0
- package/dist/data-table-selection-model.d.ts +23 -0
- package/dist/data-table-selection-model.d.ts.map +1 -0
- package/dist/data-table-selection-model.js +36 -0
- package/dist/data-table-selection.d.ts +11 -0
- package/dist/data-table-selection.d.ts.map +1 -0
- package/dist/data-table-selection.js +10 -0
- package/dist/data-table-state.d.ts +6 -0
- package/dist/data-table-state.d.ts.map +1 -0
- package/dist/data-table-state.js +38 -0
- package/dist/data-table-view.d.ts +88 -0
- package/dist/data-table-view.d.ts.map +1 -0
- package/dist/data-table-view.js +1 -0
- package/dist/data-table.d.ts +60 -0
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +1 -0
- package/dist/date-range-calendar.d.ts +29 -0
- package/dist/date-range-calendar.d.ts.map +1 -0
- package/dist/date-range-calendar.js +69 -0
- package/dist/date-range-input.d.ts +25 -0
- package/dist/date-range-input.d.ts.map +1 -0
- package/dist/date-range-input.js +195 -0
- package/dist/device-frame.d.ts +13 -0
- package/dist/device-frame.d.ts.map +1 -0
- package/dist/device-frame.js +23 -0
- package/dist/dialog-lifecycle.d.ts +3 -0
- package/dist/dialog-lifecycle.d.ts.map +1 -0
- package/dist/dialog-lifecycle.js +70 -0
- package/dist/expanded-charts.d.ts +26 -0
- package/dist/expanded-charts.d.ts.map +1 -0
- package/dist/expanded-charts.js +46 -0
- package/dist/floating-panel.d.ts +11 -0
- package/dist/floating-panel.d.ts.map +1 -0
- package/dist/floating-panel.js +1 -0
- package/dist/form-workflow.d.ts +77 -0
- package/dist/form-workflow.d.ts.map +1 -0
- package/dist/form-workflow.js +337 -0
- package/dist/hooks.d.ts +24 -21
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +1 -2468
- package/dist/image-comparison.d.ts +20 -0
- package/dist/image-comparison.d.ts.map +1 -0
- package/dist/image-comparison.js +55 -0
- package/dist/index.d.ts +25 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/interval-charts.d.ts +21 -0
- package/dist/interval-charts.d.ts.map +1 -0
- package/dist/interval-charts.js +23 -0
- package/dist/media-selection.d.ts +18 -0
- package/dist/media-selection.d.ts.map +1 -0
- package/dist/media-selection.js +12 -0
- package/dist/media-viewport.d.ts +16 -0
- package/dist/media-viewport.d.ts.map +1 -0
- package/dist/media-viewport.js +37 -0
- package/dist/motion.d.ts +597 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +22 -0
- package/dist/review-workflow.d.ts +32 -0
- package/dist/review-workflow.d.ts.map +1 -0
- package/dist/review-workflow.js +76 -0
- package/dist/rich-text-editor.d.ts +21 -0
- package/dist/rich-text-editor.d.ts.map +1 -0
- package/dist/rich-text-editor.js +143 -0
- package/dist/select-form.d.ts +3 -0
- package/dist/select-form.d.ts.map +1 -0
- package/dist/select-form.js +1 -0
- package/dist/server-components.d.ts +24 -4
- package/dist/server-components.d.ts.map +1 -1
- package/dist/server-components.js +11 -3
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/toast-context.d.ts +4 -0
- package/dist/toast-context.d.ts.map +1 -0
- package/dist/toast-context.js +10 -0
- package/dist/toast-provider.d.ts +3 -0
- package/dist/toast-provider.d.ts.map +1 -0
- package/dist/toast-provider.js +3 -0
- package/dist/use-copy-feedback.d.ts +17 -0
- package/dist/use-copy-feedback.d.ts.map +1 -0
- package/dist/use-copy-feedback.js +54 -0
- package/dist/virtual-list-data.d.ts +13 -0
- package/dist/virtual-list-data.d.ts.map +1 -0
- package/dist/virtual-list-data.js +87 -0
- package/dist/virtual-list.d.ts +14 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +24 -0
- package/dist/visual-interactions.d.ts +16 -0
- package/dist/visual-interactions.d.ts.map +1 -0
- package/dist/visual-interactions.js +30 -0
- package/dist/world-map.d.ts +26 -0
- package/dist/world-map.d.ts.map +1 -0
- package/dist/world-map.js +81 -0
- package/package.json +99 -11
- package/styles/critical.css +634 -61
- package/styles/data-table-view.css +36 -0
package/dist/components.js
CHANGED
|
@@ -1,1949 +1,4 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { alignLumenChartSeries, composeClassName, createLumenBarGeometry, createLumenHeatmapGeometry, createLumenLineGeometry, createLumenPieGeometry, createLumenRangeGeometry, createLumenScatterGeometry, formatLumenChartSummary, formatLumenLanguageLabel, getLumenChartAxisPadding, getLumenChartCategories, getLumenChartDomain, getLumenChartTicks, getLumenChartToneClassName, getLumenIcon, getLumenPhoneCountries, getLumenPieChartVariantClassName, hasLumenChartData, hasLumenPieData, lumenCodeTokenClassNames, lumenIllustrations, normalizeLumenFormErrors, resolveLumenChartLabels, resolveLumenChartTone, resolveLumenPhoneNumber, scaleLumenChartValue, tokenizeLumenCode } from '@santi020k/lumen-core';
|
|
5
|
-
import { renderSVG } from 'uqr';
|
|
6
|
-
import { formatReactChartTableValue } from './chart-recipes.js';
|
|
7
|
-
import { useCalendar, useDialog, useDropdownMenu, useInputOTP, useLanguageToggle, usePopover, useResizable, useSelect, useTabs, useTooltip } from './hooks.js';
|
|
8
|
-
import { renderIconSvg } from './icon-svg.js';
|
|
9
|
-
import { IconView } from './icon-view.js';
|
|
10
|
-
import { resolveReactPhoneInputCountry, resolveReactPhoneInputValue } from './phone-recipes.js';
|
|
11
|
-
import { Input, Label } from './server-components.js';
|
|
12
|
-
export { Badge, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Container, Direction, Grid, Input, Label, Progress, Separator, Skeleton, Spinner, Stack, Textarea, Typography, VisuallyHidden } from './server-components.js';
|
|
13
|
-
const getChartCategoryKey = (value) => `${typeof value}:${String(value)}`;
|
|
14
|
-
const setRefValue = (ref, value) => {
|
|
15
|
-
if (typeof ref === 'function') {
|
|
16
|
-
ref(value);
|
|
17
|
-
}
|
|
18
|
-
else if (ref) {
|
|
19
|
-
ref.current = value;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const emptyOptions = [];
|
|
23
|
-
const emptyStringOptions = [];
|
|
24
|
-
const emptyDataTableColumns = [];
|
|
25
|
-
const emptyDataTableRows = [];
|
|
26
|
-
const emptyChartSeries = [];
|
|
27
|
-
const emptyHeatmapData = [];
|
|
28
|
-
const emptyRangeData = [];
|
|
29
|
-
const emptyComboSeries = [];
|
|
30
|
-
const emptyPieSeries = {
|
|
31
|
-
data: [],
|
|
32
|
-
id: 'pie',
|
|
33
|
-
label: 'Values'
|
|
34
|
-
};
|
|
35
|
-
const emptyChartValues = [];
|
|
36
|
-
const variantClass = (base, variant, defaultVariant = 'default') => (variant === defaultVariant ? false : `${base}--${variant}`);
|
|
37
|
-
const renderLucideIcon = (name, className) => {
|
|
38
|
-
const icon = getLumenIcon(name);
|
|
39
|
-
return icon ? renderIconSvg(icon, className) : null;
|
|
40
|
-
};
|
|
41
|
-
const resolveSurface = (glass) => glass ? 'glass' : 'default';
|
|
42
|
-
const glassIntensityClass = (glass) => glass === 'subtle' ?
|
|
43
|
-
'ui-glass-subtle' :
|
|
44
|
-
glass === 'strong' && 'ui-glass-strong';
|
|
45
|
-
const glassSurfaceClass = (base, glass) => resolveSurface(glass) === 'glass' &&
|
|
46
|
-
composeClassName(`${base}--glass`, glassIntensityClass(glass));
|
|
47
|
-
const glassClass = (base, glass) => Boolean(glass) &&
|
|
48
|
-
composeClassName(`${base}--glass`, glassIntensityClass(glass));
|
|
49
|
-
const normalizeOption = (option) => typeof option === 'string' ? { label: option, value: option } : option;
|
|
50
|
-
const isDataTableCellObject = (cell) => typeof cell === 'object' && cell !== null;
|
|
51
|
-
const formatDataTableCell = (cell) => {
|
|
52
|
-
const value = isDataTableCellObject(cell) ? (cell.label ?? cell.value) : cell;
|
|
53
|
-
return value === undefined || value === null ? '' : String(value);
|
|
54
|
-
};
|
|
55
|
-
const getDataTableSortValue = (cell) => {
|
|
56
|
-
if (!isDataTableCellObject(cell) ||
|
|
57
|
-
cell.sortValue === undefined ||
|
|
58
|
-
cell.sortValue === null)
|
|
59
|
-
return undefined;
|
|
60
|
-
return String(cell.sortValue);
|
|
61
|
-
};
|
|
62
|
-
const compareDataTableCells = (left, right, sortType) => {
|
|
63
|
-
const leftValue = getDataTableSortValue(left) ?? formatDataTableCell(left);
|
|
64
|
-
const rightValue = getDataTableSortValue(right) ?? formatDataTableCell(right);
|
|
65
|
-
if (sortType === 'number') {
|
|
66
|
-
return Number(leftValue.replaceAll(',', '')) -
|
|
67
|
-
Number(rightValue.replaceAll(',', ''));
|
|
68
|
-
}
|
|
69
|
-
return leftValue.localeCompare(rightValue, undefined, {
|
|
70
|
-
numeric: true,
|
|
71
|
-
sensitivity: 'base'
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
const getDataTableRowValue = (row, index) => String(row.rowValue ?? row.value ?? row.id ?? index);
|
|
75
|
-
const toInputValue = (value) => {
|
|
76
|
-
if (value === undefined)
|
|
77
|
-
return undefined;
|
|
78
|
-
return String(value);
|
|
79
|
-
};
|
|
80
|
-
const composeHandlers = (userHandler, lumenHandler) => (event) => {
|
|
81
|
-
userHandler?.(event);
|
|
82
|
-
lumenHandler?.(event);
|
|
83
|
-
};
|
|
84
|
-
const Primitive = ({ as, className, uiClassName, ...props }) => {
|
|
85
|
-
const Tag = as ?? 'div';
|
|
86
|
-
const safeClassName = typeof className === 'string' ? className : undefined;
|
|
87
|
-
return (_jsx(Tag, { className: composeClassName(uiClassName, safeClassName), ...props }));
|
|
88
|
-
};
|
|
89
|
-
const DropdownMenuContext = createContext(null);
|
|
90
|
-
const PopoverContext = createContext(null);
|
|
91
|
-
const TabsContext = createContext(null);
|
|
92
|
-
const TooltipContext = createContext(null);
|
|
93
|
-
const requireContext = (context, componentName) => {
|
|
94
|
-
if (!context) {
|
|
95
|
-
throw new Error(`${componentName} must be used inside its matching Lumen root component.`);
|
|
96
|
-
}
|
|
97
|
-
return context;
|
|
98
|
-
};
|
|
99
|
-
export const Accordion = ({ className, variant = 'default', ...props }) => (_jsx("div", { className: composeClassName('ui-accordion', variant === 'flush' && 'ui-accordion--flush', className), "data-variant": variant, ...props }));
|
|
100
|
-
export const Alert = ({ className, glass = false, variant = 'default', ...props }) => (_jsx("aside", { className: composeClassName('ui-alert', variantClass('ui-alert', variant), glassClass('ui-alert', glass), className), "data-variant": variant, ...props }));
|
|
101
|
-
export const AlertDialog = ({ className, defaultOpen, glass = false, onClick, onClose, onOpenChange, open, ...props }) => {
|
|
102
|
-
const dialog = useDialog({ alert: true, defaultOpen, onOpenChange, open });
|
|
103
|
-
return (_jsx("dialog", { ...dialog.dialogProps, ...props, className: composeClassName('ui-dialog ui-alert-dialog', glassSurfaceClass('ui-dialog', glass), className), "data-surface": resolveSurface(glass), onClick: composeHandlers(onClick, dialog.dialogProps.onClick), onClose: composeHandlers(onClose, dialog.dialogProps.onClose) }));
|
|
104
|
-
};
|
|
105
|
-
export const Agenda = ({ className, glass = false, ...props }) => (_jsx("section", { className: composeClassName('ui-agenda', glassClass('ui-agenda', glass), className), ...props }));
|
|
106
|
-
export const AspectRatio = ({ className, ratio = '16 / 9', style, ...props }) => (_jsx("div", { className: composeClassName('ui-aspect-ratio', className), style: { aspectRatio: ratio, ...style }, ...props }));
|
|
107
|
-
export const Autocomplete = ({ className, type = 'search', ...props }) => (_jsx("input", { "aria-autocomplete": "list", className: composeClassName('ui-input ui-autocomplete', className), role: "combobox", type: type, ...props }));
|
|
108
|
-
export const Attachment = ({ className, glass = false, href, ...props }) => {
|
|
109
|
-
const nextClassName = composeClassName('ui-attachment', glassClass('ui-attachment', glass), className);
|
|
110
|
-
return href ?
|
|
111
|
-
(_jsx("a", { className: nextClassName, href: href, ...props })) :
|
|
112
|
-
(_jsx("article", { className: nextClassName, ...props }));
|
|
113
|
-
};
|
|
114
|
-
export const Avatar = ({ alt = '', children, className, fallback, src, ...props }) => (_jsxs("span", { className: composeClassName('ui-avatar', className), ...props, children: [src ? _jsx("img", { alt: alt, src: src }) : _jsx("span", { children: fallback }), children] }));
|
|
115
|
-
export const Breadcrumb = ({ 'aria-label': ariaLabel = 'Breadcrumb', className, ...props }) => (_jsx("nav", { "aria-label": ariaLabel, className: composeClassName('ui-breadcrumb', className), ...props }));
|
|
116
|
-
export const Bubble = ({ className, from = 'assistant', glass = false, ...props }) => (_jsx("article", { className: composeClassName('ui-bubble', from === 'user' && 'ui-bubble--user', glassClass('ui-bubble', glass), className), "data-from": from, ...props }));
|
|
117
|
-
/* eslint-disable complexity -- The compatibility path resolves native, slotted, loading, size, and disabled states in one public component. */
|
|
118
|
-
export const Button = ({ asChild = false, children, className, disabled, loading = false, ref, size = 'default', type = 'button', variant = 'default', ...props }) => {
|
|
119
|
-
const buttonClassName = composeClassName('ui-button', `ui-button--${variant}`, size === 'default' ? 'ui-button--default-size' : `ui-button--${size}`, disabled && 'ui-button--disabled', loading && 'ui-button--loading', className);
|
|
120
|
-
if (asChild) {
|
|
121
|
-
const child = Children.only(children);
|
|
122
|
-
if (!isValidElement(child)) {
|
|
123
|
-
throw new TypeError('Button with asChild requires exactly one React element child.');
|
|
124
|
-
}
|
|
125
|
-
const ChildComponent = child.type;
|
|
126
|
-
return (_jsxs(ChildComponent, { ...child.props, ...props, "aria-busy": loading ? true : undefined, "aria-disabled": disabled ? true : undefined, className: composeClassName(buttonClassName, child.props.className), "data-slot": "button", ref: ref, children: [loading && _jsx("span", { "aria-hidden": "true", className: "ui-spinner" }), child.props.children] }));
|
|
127
|
-
}
|
|
128
|
-
return (_jsxs("button", { "aria-busy": loading || undefined, className: buttonClassName, "data-slot": "button", disabled: disabled, ref: ref, type: type, ...props, children: [loading && _jsx("span", { "aria-hidden": "true", className: "ui-spinner" }), children] }));
|
|
129
|
-
};
|
|
130
|
-
export const ButtonGroup = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-button-group', className), ...props }));
|
|
131
|
-
export const Calendar = ({ className, defaultValue, disabled = false, glass = false, locale, max, min, month, name, onValueChange, value, ...props }) => {
|
|
132
|
-
const calendar = useCalendar({
|
|
133
|
-
defaultValue,
|
|
134
|
-
disabled,
|
|
135
|
-
locale,
|
|
136
|
-
max,
|
|
137
|
-
min,
|
|
138
|
-
month,
|
|
139
|
-
name,
|
|
140
|
-
onValueChange,
|
|
141
|
-
value
|
|
142
|
-
});
|
|
143
|
-
return (_jsxs("div", { ...props, ...calendar.rootProps, className: composeClassName(calendar.rootProps.className, glassClass('ui-calendar', glass), className), "data-ui-glass-track": glass ? true : undefined, children: [_jsx("input", { ...calendar.inputProps }), _jsxs("div", { className: "ui-calendar__header", children: [_jsx("button", { ...calendar.previousProps, type: "button", children: _jsx("span", { "aria-hidden": "true", children: "\u2039" }) }), _jsx("strong", { ...calendar.labelProps, children: calendar.label }), _jsx("button", { ...calendar.nextProps, type: "button", children: _jsx("span", { "aria-hidden": "true", children: "\u203A" }) })] }), _jsxs("table", { ...calendar.gridProps, children: [_jsx("thead", { children: _jsx("tr", { role: "row", children: calendar.weekdays.map(weekday => (_jsx("th", { role: "columnheader", scope: "col", children: weekday }, weekday))) }) }), _jsx("tbody", { children: calendar.weeks.map(week => (_jsx("tr", { role: "row", children: week.map(day => (_jsx("td", { ...calendar.getDayProps(day), children: day.day }, day.date))) }, week[0]?.date ?? 'week'))) })] })] }));
|
|
144
|
-
};
|
|
145
|
-
export const Carousel = ({ className, glass = false, ...props }) => (_jsx("section", { className: composeClassName('ui-carousel', glassClass('ui-carousel', glass), className), "data-ui-carousel": true, ...props }));
|
|
146
|
-
const ChartHeader = ({ description, heading, value }) => {
|
|
147
|
-
if (!heading && !description && !value)
|
|
148
|
-
return null;
|
|
149
|
-
return (_jsxs("header", { children: [_jsxs("div", { className: "ui-chart__heading", children: [heading && _jsx("h3", { children: heading }), description && _jsx("p", { children: description })] }), value && _jsx("strong", { "data-ui-chart-value": true, children: value })] }));
|
|
150
|
-
};
|
|
151
|
-
export const Chart = ({ caption, children, className, description, glass = false, heading, presentation = 'default', summary, value, ...props }) => (_jsxs("figure", { className: composeClassName('ui-chart', presentation === 'bare' && 'ui-chart--bare', glassClass('ui-chart', glass), className), ...props, children: [_jsx(ChartHeader, { description: description, heading: heading, value: value }), summary && _jsx("p", { className: "ui-sr-only", "data-ui-chart-summary": true, children: summary }), children, caption && _jsx("figcaption", { children: caption })] }));
|
|
152
|
-
const ChartLegend = ({ label = 'Chart legend', series }) => (_jsx("ul", { "aria-label": label, className: "ui-chart__legend", children: series.map((item, index) => (_jsxs("li", { className: getLumenChartToneClassName(item.tone, index), children: [_jsx("span", { "aria-hidden": "true" }), item.label] }, item.id))) }));
|
|
153
|
-
const ChartDataTable = ({ categories, formatCategory = String, formatValue = String, labels, series }) => {
|
|
154
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
155
|
-
return (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: resolvedLabels.viewData }), _jsx("div", { children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: resolvedLabels.category }), series.map(item => (_jsx("th", { scope: "col", children: item.label }, item.id)))] }) }), _jsx("tbody", { children: categories.map(category => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: series
|
|
156
|
-
.flatMap(item => item.data)
|
|
157
|
-
.find(datum => datum.x === category)?.xLabel ??
|
|
158
|
-
formatCategory(category) }), series.map(item => {
|
|
159
|
-
const datum = item.data.find(candidate => candidate.x === category);
|
|
160
|
-
return (_jsx("td", { children: datum?.label ?? formatReactChartTableValue(datum?.y, formatValue, resolvedLabels.notAvailable) }, item.id));
|
|
161
|
-
})] }, getChartCategoryKey(category)))) })] }) })] }));
|
|
162
|
-
};
|
|
163
|
-
const formatChartPercentage = (percentage) => new Intl.NumberFormat(undefined, {
|
|
164
|
-
maximumFractionDigits: percentage < 0.01 ? 1 : 0,
|
|
165
|
-
style: 'percent'
|
|
166
|
-
}).format(percentage);
|
|
167
|
-
export const Sparkline = ({ area = false, className, label = 'Trend', showEndpoint = true, tone, values = emptyChartValues, ...props }) => {
|
|
168
|
-
const geometry = createLumenLineGeometry(values.map((value, index) => ({ x: index, y: value })), { height: 40, padding: 3, width: 120 });
|
|
169
|
-
const resolvedTone = resolveLumenChartTone(tone);
|
|
170
|
-
const endpoint = geometry.points.at(-1);
|
|
171
|
-
return (_jsxs("span", { "aria-label": label, className: composeClassName('ui-sparkline', `ui-chart-tone--${resolvedTone}`, className), role: "img", ...props, children: [_jsxs("svg", { "aria-hidden": "true", preserveAspectRatio: "none", viewBox: "0 0 120 40", children: [area &&
|
|
172
|
-
geometry.areaPaths.map(path => (_jsx("path", { className: "ui-sparkline__area", d: path }, path))), _jsx("path", { className: "ui-sparkline__line", d: geometry.path }), showEndpoint && endpoint && (_jsx("circle", { className: "ui-sparkline__endpoint", cx: endpoint.xCoordinate, cy: endpoint.yCoordinate, r: "2.5" }))] }), _jsx("span", { className: "ui-sr-only", children: label })] }));
|
|
173
|
-
};
|
|
174
|
-
/* eslint-disable complexity -- Chart renderers keep optional semantic and SVG layers colocated. */
|
|
175
|
-
export const BarChart = ({ categoryWidth, className, emptyLabel, formatCategory = String, formatValue = String, layout = 'grouped', labels, orientation = 'vertical', series = emptyChartSeries, showLegend = series.length > 1, showTable = true, summary, ...props }) => {
|
|
176
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
177
|
-
const geometry = createLumenBarGeometry(series, {
|
|
178
|
-
...(categoryWidth === undefined ? {} : { categoryWidth }),
|
|
179
|
-
layout,
|
|
180
|
-
orientation
|
|
181
|
-
});
|
|
182
|
-
const hasData = hasLumenChartData(series);
|
|
183
|
-
const ticks = getLumenChartTicks(geometry.domain);
|
|
184
|
-
const categories = geometry.categories.map(category => category.category);
|
|
185
|
-
const margin = orientation === 'horizontal' ?
|
|
186
|
-
{
|
|
187
|
-
bottom: 24,
|
|
188
|
-
left: Math.max(64, Math.min(240, categoryWidth ?? 112)),
|
|
189
|
-
right: 20,
|
|
190
|
-
top: 16
|
|
191
|
-
} :
|
|
192
|
-
{ bottom: 52, left: 52, right: 16, top: 16 };
|
|
193
|
-
return (_jsxs(Chart, { className: composeClassName('ui-bar-chart', className), summary: summary ?? formatLumenChartSummary(series, formatValue, resolvedLabels), ...props, children: [showLegend && hasData && _jsx(ChartLegend, { label: resolvedLabels.chartLegend, series: series }), !hasData && (_jsx("p", { className: "ui-chart__empty", role: "status", children: emptyLabel ?? resolvedLabels.empty })), _jsx("div", { className: "ui-chart__plot", hidden: !hasData, children: _jsxs("svg", { "aria-hidden": "true", preserveAspectRatio: "xMidYMid meet", viewBox: `0 0 ${geometry.width} ${geometry.height}`, children: [_jsx("g", { className: "ui-chart__grid", children: ticks.map(tick => {
|
|
194
|
-
const coordinate = orientation === 'horizontal' ?
|
|
195
|
-
scaleLumenChartValue(tick, geometry.domain, margin.left, geometry.width - margin.right) :
|
|
196
|
-
scaleLumenChartValue(tick, geometry.domain, geometry.height - margin.bottom, margin.top);
|
|
197
|
-
return orientation === 'horizontal' ?
|
|
198
|
-
(_jsx("line", { x1: coordinate, x2: coordinate, y1: margin.top, y2: geometry.height - margin.bottom }, tick)) :
|
|
199
|
-
(_jsx("line", { x1: margin.left, x2: geometry.width - margin.right, y1: coordinate, y2: coordinate }, tick));
|
|
200
|
-
}) }), _jsx("g", { className: "ui-chart__axis-labels", children: geometry.categories.map(category => (_jsx("text", { dominantBaseline: orientation === 'horizontal' ? 'middle' : undefined, textAnchor: orientation === 'horizontal' ? 'end' : 'middle', x: category.x, y: category.y, children: String(category.label) }, getChartCategoryKey(category.label)))) }), _jsx("g", { className: "ui-bar-chart__marks", children: geometry.marks.map(mark => (_jsx("rect", { className: getLumenChartToneClassName(mark.tone), height: mark.height, rx: "4", width: mark.width, x: mark.x, y: mark.y, children: _jsx("title", { children: `${series
|
|
201
|
-
.flatMap(item => item.data)
|
|
202
|
-
.find(datum => datum.x === mark.category)?.xLabel ??
|
|
203
|
-
formatCategory(mark.category)} · ${mark.seriesLabel}: ${formatValue(mark.value)}` }) }, `${mark.seriesId}:${getChartCategoryKey(mark.category)}`))) })] }) }), showTable && hasData && (_jsx(ChartDataTable, { categories: categories, formatCategory: formatCategory, formatValue: formatValue, labels: resolvedLabels, series: series }))] }));
|
|
204
|
-
};
|
|
205
|
-
const getLineChartMarkerStep = (markers, categoryCount) => {
|
|
206
|
-
if (markers === false || markers === 'none')
|
|
207
|
-
return Number.POSITIVE_INFINITY;
|
|
208
|
-
if (typeof markers === 'number')
|
|
209
|
-
return Math.max(1, Math.round(markers));
|
|
210
|
-
if (markers === 'auto')
|
|
211
|
-
return Math.max(1, Math.ceil(categoryCount / 24));
|
|
212
|
-
return 1;
|
|
213
|
-
};
|
|
214
|
-
export const LineChart = ({ area = false, className, emptyLabel, formatCategory = String, formatValue = String, labels, markers = 'auto', referenceValue, series = emptyChartSeries, showLegend = series.length > 1, showTable = true, summary, ...props }) => {
|
|
215
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
216
|
-
const width = 640;
|
|
217
|
-
const height = 320;
|
|
218
|
-
const padding = 44;
|
|
219
|
-
const categories = getLumenChartCategories(series);
|
|
220
|
-
const hasData = hasLumenChartData(series);
|
|
221
|
-
const alignedSeries = series.map(item => ({
|
|
222
|
-
...item,
|
|
223
|
-
data: alignLumenChartSeries(item, categories).data
|
|
224
|
-
}));
|
|
225
|
-
const domain = getLumenChartDomain([
|
|
226
|
-
...alignedSeries.flatMap(item => item.data.map(datum => datum.y)),
|
|
227
|
-
referenceValue ?? null
|
|
228
|
-
], false);
|
|
229
|
-
const ticks = getLumenChartTicks(domain);
|
|
230
|
-
const paddingLeft = getLumenChartAxisPadding(ticks.map(tick => formatValue(tick)));
|
|
231
|
-
const geometries = alignedSeries.map(item => createLumenLineGeometry(item.data, {
|
|
232
|
-
domain,
|
|
233
|
-
height,
|
|
234
|
-
includeZero: false,
|
|
235
|
-
padding,
|
|
236
|
-
paddingLeft,
|
|
237
|
-
width
|
|
238
|
-
}));
|
|
239
|
-
const labelStep = Math.max(1, Math.ceil(categories.length / 8));
|
|
240
|
-
const markerStep = getLineChartMarkerStep(markers, categories.length);
|
|
241
|
-
const referenceY = referenceValue === undefined ?
|
|
242
|
-
undefined :
|
|
243
|
-
scaleLumenChartValue(referenceValue, domain, height - padding, padding);
|
|
244
|
-
return (_jsxs(Chart, { className: composeClassName('ui-line-chart', className), summary: summary ?? formatLumenChartSummary(series, formatValue, resolvedLabels), ...props, children: [showLegend && hasData && _jsx(ChartLegend, { label: resolvedLabels.chartLegend, series: series }), !hasData && (_jsx("p", { className: "ui-chart__empty", role: "status", children: emptyLabel ?? resolvedLabels.empty })), _jsx("div", { className: "ui-chart__plot", hidden: !hasData, children: _jsxs("svg", { "aria-hidden": "true", preserveAspectRatio: "xMidYMid meet", viewBox: `0 0 ${width} ${height}`, children: [_jsx("g", { className: "ui-chart__grid", children: ticks.map(tick => {
|
|
245
|
-
const y = scaleLumenChartValue(tick, domain, height - padding, padding);
|
|
246
|
-
return (_jsxs(Fragment, { children: [_jsx("line", { x1: paddingLeft, x2: width - padding, y1: y, y2: y }), _jsx("text", { x: paddingLeft - 8, y: y, children: formatValue(tick) })] }, tick));
|
|
247
|
-
}) }), _jsx("g", { className: "ui-chart__axis-labels", children: categories.map((category, index) => {
|
|
248
|
-
if (index % labelStep !== 0 && index !== categories.length - 1)
|
|
249
|
-
return null;
|
|
250
|
-
const denominator = Math.max(1, categories.length - 1);
|
|
251
|
-
const x = paddingLeft + (index / denominator) * (width - paddingLeft - padding);
|
|
252
|
-
return (_jsx("text", { textAnchor: "middle", x: x, y: height - 14, children: series
|
|
253
|
-
.flatMap(item => item.data)
|
|
254
|
-
.find(datum => datum.x === category)?.xLabel ??
|
|
255
|
-
formatCategory(category) }, getChartCategoryKey(category)));
|
|
256
|
-
}) }), referenceY !== undefined && (_jsx("line", { className: "ui-chart__reference", x1: paddingLeft, x2: width - padding, y1: referenceY, y2: referenceY })), geometries.map((geometry, index) => {
|
|
257
|
-
const item = series[index];
|
|
258
|
-
if (!item)
|
|
259
|
-
return null;
|
|
260
|
-
const tone = resolveLumenChartTone(item.tone, index);
|
|
261
|
-
return (_jsxs("g", { className: composeClassName('ui-line-chart__series', getLumenChartToneClassName(tone)), children: [area &&
|
|
262
|
-
geometry.areaPaths.map(path => (_jsx("path", { className: "ui-line-chart__area", d: path }, path))), _jsx("path", { className: "ui-line-chart__line", d: geometry.path }), Number.isFinite(markerStep) &&
|
|
263
|
-
geometry.points.map((point, pointIndex) => pointIndex % markerStep === 0 && (_jsx("circle", { className: "ui-line-chart__point", cx: point.xCoordinate, cy: point.yCoordinate, r: "3", children: _jsx("title", { children: `${point.xLabel ?? formatCategory(point.x)} · ${item.label}: ${formatValue(point.y ?? 0)}` }) }, getChartCategoryKey(point.x))))] }, item.id));
|
|
264
|
-
})] }) }), showTable && hasData && (_jsx(ChartDataTable, { categories: categories, formatCategory: formatCategory, formatValue: formatValue, labels: resolvedLabels, series: series }))] }));
|
|
265
|
-
};
|
|
266
|
-
export const PieChart = ({ centerLabel, centerValue, className, labels, series = emptyPieSeries, showLegend = true, showTable = true, summary, valueFormatter = String, variant = 'donut', ...props }) => {
|
|
267
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
268
|
-
const geometry = createLumenPieGeometry(series.data, { variant });
|
|
269
|
-
const hasData = hasLumenPieData(series.data);
|
|
270
|
-
const renderedSeries = {
|
|
271
|
-
...series,
|
|
272
|
-
data: series.data.filter(datum => datum.y !== null && Number.isFinite(datum.y) && datum.y > 0)
|
|
273
|
-
};
|
|
274
|
-
const hasCenterLabel = centerLabel !== null && centerLabel !== undefined;
|
|
275
|
-
const hasCenterValue = centerValue !== null && centerValue !== undefined;
|
|
276
|
-
return (_jsxs(Chart, { className: composeClassName('ui-pie-chart', getLumenPieChartVariantClassName(variant), className), summary: summary ?? formatLumenChartSummary([renderedSeries], valueFormatter, resolvedLabels), ...props, children: [showLegend && hasData && (_jsx("ul", { "aria-label": resolvedLabels.chartLegend, className: "ui-chart__legend", children: geometry.slices.map(slice => (_jsxs("li", { className: getLumenChartToneClassName(slice.tone), children: [_jsx("span", { "aria-hidden": "true" }), slice.label] }, `${typeof slice.x}:${String(slice.x)}`))) })), !hasData && (_jsx("p", { className: "ui-chart__empty", role: "status", children: resolvedLabels.empty })), _jsxs("div", { className: "ui-chart__plot ui-pie-chart__plot", hidden: !hasData, children: [_jsx("svg", { "aria-hidden": "true", preserveAspectRatio: "xMidYMid meet", viewBox: `0 0 ${geometry.size} ${geometry.size}`, children: _jsx("g", { className: "ui-pie-chart__slices", children: geometry.slices.map(slice => (_jsx("path", { className: getLumenChartToneClassName(slice.tone), d: slice.path, fillRule: "evenodd", children: _jsx("title", { children: `${slice.label}: ${valueFormatter(slice.value)} (${formatChartPercentage(slice.percentage)})` }) }, `${typeof slice.x}:${String(slice.x)}`))) }) }), variant === 'donut' && (hasCenterLabel || hasCenterValue) && (_jsxs(_Fragment, { children: [_jsxs("div", { "aria-hidden": "true", className: "ui-pie-chart__center", children: [hasCenterValue && _jsx("strong", { children: centerValue }), hasCenterLabel && _jsx("span", { children: centerLabel })] }), _jsxs("div", { className: "ui-sr-only", children: [centerValue, ' ', centerLabel] })] }))] }), showTable && hasData && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: resolvedLabels.viewData }), _jsx("div", { children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: resolvedLabels.category }), _jsx("th", { scope: "col", children: resolvedLabels.value }), _jsx("th", { scope: "col", children: "Share" })] }) }), _jsx("tbody", { children: geometry.slices.map(slice => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: slice.label }), _jsx("td", { children: valueFormatter(slice.value) }), _jsx("td", { children: formatChartPercentage(slice.percentage) })] }, `${typeof slice.x}:${String(slice.x)}`))) })] }) })] }))] }));
|
|
277
|
-
};
|
|
278
|
-
export const ScatterChart = ({ className, formatValue = String, labels, series = emptyChartSeries, showLegend = series.length > 1, showTable = true, summary, xScale = 'linear', ...props }) => {
|
|
279
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
280
|
-
const geometry = createLumenScatterGeometry(series, { xScale });
|
|
281
|
-
const renderedSeries = series.map(item => ({
|
|
282
|
-
...item,
|
|
283
|
-
data: geometry.points.filter(point => point.seriesId === item.id)
|
|
284
|
-
})).filter(item => item.data.length > 0);
|
|
285
|
-
const hasData = geometry.points.length > 0;
|
|
286
|
-
return (_jsxs(Chart, { className: composeClassName('ui-scatter-chart', className), summary: summary ?? formatLumenChartSummary(renderedSeries, formatValue, resolvedLabels), ...props, children: [showLegend && hasData && _jsx(ChartLegend, { label: resolvedLabels.chartLegend, series: series }), !hasData && _jsx("p", { className: "ui-chart__empty", role: "status", children: resolvedLabels.empty }), _jsx("div", { className: "ui-chart__plot", hidden: !hasData, children: _jsx("svg", { "aria-hidden": "true", viewBox: `0 0 ${geometry.width} ${geometry.height}`, children: _jsx("g", { className: "ui-scatter-chart__marks", children: geometry.points.map((point, pointIndex) => (_jsx("circle", { className: getLumenChartToneClassName(point.tone), cx: point.xCoordinate, cy: point.yCoordinate, r: point.radius, children: _jsx("title", { children: `${point.xLabel ?? point.x} · ${point.seriesLabel}: ${point.label ?? formatValue(point.y ?? 0)}` }) }, `${point.seriesId}:${point.id ?? `${getChartCategoryKey(point.x)}:${pointIndex}`}`))) }) }) }), showTable && hasData && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: resolvedLabels.viewData }), _jsx("div", { children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: resolvedLabels.x }), _jsx("th", { scope: "col", children: resolvedLabels.series }), _jsx("th", { scope: "col", children: resolvedLabels.value }), _jsx("th", { scope: "col", children: resolvedLabels.size })] }) }), _jsx("tbody", { children: geometry.points.map((point, pointIndex) => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: point.xLabel ?? point.x }), _jsx("td", { children: point.seriesLabel }), _jsx("td", { children: point.label ?? formatValue(point.y ?? 0) }), _jsx("td", { children: formatReactChartTableValue(point.size, formatValue, resolvedLabels.notAvailable) })] }, `${point.seriesId}:${point.id ?? `${getChartCategoryKey(point.x)}:${pointIndex}`}`))) })] }) })] }))] }));
|
|
287
|
-
};
|
|
288
|
-
export const Heatmap = ({ className, data = emptyHeatmapData, formatValue = String, labels, showTable = true, summary, ...props }) => {
|
|
289
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
290
|
-
const geometry = createLumenHeatmapGeometry(data);
|
|
291
|
-
const availableCells = geometry.cells.filter(cell => cell.value !== null && Number.isFinite(cell.value));
|
|
292
|
-
const hasData = availableCells.length > 0;
|
|
293
|
-
return (_jsxs(Chart, { className: composeClassName('ui-heatmap', className), summary: summary ?? resolvedLabels.formatHeatmapSummary(availableCells.length), ...props, children: [!hasData && _jsx("p", { className: "ui-chart__empty", role: "status", children: resolvedLabels.empty }), _jsx("div", { className: "ui-chart__plot", hidden: !hasData, children: _jsx("svg", { "aria-hidden": "true", viewBox: `0 0 ${geometry.width} ${geometry.height}`, children: _jsx("g", { className: "ui-heatmap__cells", children: availableCells.map(cell => _jsx("rect", { height: Math.max(0, cell.height - 2), opacity: Math.max(0.12, cell.ratio), width: Math.max(0, cell.width - 2), x: cell.xCoordinate + 1, y: cell.yCoordinate + 1, children: _jsx("title", { children: `${cell.xLabel ?? cell.x} · ${cell.yLabel ?? cell.y}: ${cell.label ?? formatValue(cell.value ?? 0)}` }) }, cell.id ?? `${getChartCategoryKey(cell.x)}:${getChartCategoryKey(cell.y)}`)) }) }) }), showTable && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: resolvedLabels.viewData }), _jsx("div", { children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: resolvedLabels.column }), _jsx("th", { scope: "col", children: resolvedLabels.row }), _jsx("th", { scope: "col", children: resolvedLabels.value })] }) }), _jsx("tbody", { children: data.map(cell => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: cell.xLabel ?? cell.x }), _jsx("td", { children: cell.yLabel ?? cell.y }), _jsx("td", { children: cell.label ?? (cell.value === null || !Number.isFinite(cell.value) ?
|
|
294
|
-
resolvedLabels.notAvailable :
|
|
295
|
-
formatValue(cell.value)) })] }, cell.id ?? `${getChartCategoryKey(cell.x)}:${getChartCategoryKey(cell.y)}`))) })] }) })] }))] }));
|
|
296
|
-
};
|
|
297
|
-
export const RangeChart = ({ className, data = emptyRangeData, formatValue = String, labels, showTable = true, summary, tone = 'series-1', ...props }) => {
|
|
298
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
299
|
-
const width = 640;
|
|
300
|
-
const height = 320;
|
|
301
|
-
const padding = 44;
|
|
302
|
-
const geometry = createLumenRangeGeometry(data, { height, padding, width });
|
|
303
|
-
return (_jsxs(Chart, { className: composeClassName('ui-range-chart', getLumenChartToneClassName(tone), className), summary: summary ?? resolvedLabels.formatRangeSummary(geometry.points.length), ...props, children: [geometry.points.length === 0 && _jsx("p", { className: "ui-chart__empty", role: "status", children: resolvedLabels.empty }), _jsx("div", { className: "ui-chart__plot", hidden: geometry.points.length === 0, children: _jsxs("svg", { "aria-hidden": "true", viewBox: `0 0 ${width} ${height}`, children: [_jsx("path", { className: "ui-range-chart__area", d: geometry.areaPath }), geometry.points.map(point => (_jsx("line", { className: "ui-range-chart__interval", x1: point.xCoordinate, x2: point.xCoordinate, y1: point.highCoordinate, y2: point.lowCoordinate, children: _jsx("title", { children: `${point.xLabel ?? point.x}: ${point.label ?? `${formatValue(point.low ?? 0)}–${formatValue(point.high ?? 0)}`}` }) }, point.id ?? getChartCategoryKey(point.x))))] }) }), showTable && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: resolvedLabels.viewData }), _jsx("div", { children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: resolvedLabels.category }), _jsx("th", { scope: "col", children: resolvedLabels.low }), _jsx("th", { scope: "col", children: resolvedLabels.high })] }) }), _jsx("tbody", { children: data.map(item => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: item.xLabel ?? item.x }), _jsx("td", { children: item.low === null || !Number.isFinite(item.low) ?
|
|
304
|
-
resolvedLabels.notAvailable :
|
|
305
|
-
formatValue(item.low) }), _jsx("td", { children: item.high === null || !Number.isFinite(item.high) ?
|
|
306
|
-
resolvedLabels.notAvailable :
|
|
307
|
-
formatValue(item.high) })] }, item.id ?? getChartCategoryKey(item.x)))) })] }) })] }))] }));
|
|
308
|
-
};
|
|
309
|
-
export const ComboChart = ({ className, formatValue = String, labels, series = emptyComboSeries, showLegend = true, showTable = true, summary, ...props }) => {
|
|
310
|
-
const resolvedLabels = resolveLumenChartLabels(labels);
|
|
311
|
-
const width = 640;
|
|
312
|
-
const height = 320;
|
|
313
|
-
const padding = 44;
|
|
314
|
-
const categories = getLumenChartCategories(series);
|
|
315
|
-
const alignedSeries = series.map(item => ({
|
|
316
|
-
...item,
|
|
317
|
-
data: alignLumenChartSeries(item, categories).data
|
|
318
|
-
}));
|
|
319
|
-
const domain = getLumenChartDomain(alignedSeries.flatMap(item => item.data.map(datum => datum.y)));
|
|
320
|
-
const barSeries = alignedSeries.filter(item => item.mark === 'bar');
|
|
321
|
-
const lineSeries = alignedSeries.filter(item => item.mark !== 'bar');
|
|
322
|
-
const bars = createLumenBarGeometry(barSeries, { domain, height, width });
|
|
323
|
-
const categoryPositions = new Map(bars.categories.map(category => [getChartCategoryKey(category.category), category.x]));
|
|
324
|
-
const drawableWidth = width - padding * 2;
|
|
325
|
-
const alignComboLineDatum = (datum) => {
|
|
326
|
-
if (barSeries.length === 0)
|
|
327
|
-
return datum;
|
|
328
|
-
return {
|
|
329
|
-
...datum,
|
|
330
|
-
x: ((categoryPositions.get(`${typeof datum.x}:${String(datum.x)}`) ?? padding) - padding) / drawableWidth
|
|
331
|
-
};
|
|
332
|
-
};
|
|
333
|
-
const lineGeometryOptions = {
|
|
334
|
-
domain,
|
|
335
|
-
height,
|
|
336
|
-
padding,
|
|
337
|
-
width,
|
|
338
|
-
...(barSeries.length === 0 ?
|
|
339
|
-
{} :
|
|
340
|
-
{
|
|
341
|
-
xDomain: { max: 1, min: 0 },
|
|
342
|
-
xScale: 'linear'
|
|
343
|
-
})
|
|
344
|
-
};
|
|
345
|
-
const lines = lineSeries.map(item => createLumenLineGeometry(item.data.map(alignComboLineDatum), lineGeometryOptions));
|
|
346
|
-
const hasData = hasLumenChartData(series);
|
|
347
|
-
return (_jsxs(Chart, { className: composeClassName('ui-combo-chart', className), summary: summary ?? formatLumenChartSummary(series, formatValue, resolvedLabels), ...props, children: [showLegend && hasData && _jsx(ChartLegend, { label: resolvedLabels.chartLegend, series: series }), !hasData && _jsx("p", { className: "ui-chart__empty", role: "status", children: resolvedLabels.empty }), _jsx("div", { className: "ui-chart__plot", hidden: !hasData, children: _jsxs("svg", { "aria-hidden": "true", viewBox: `0 0 ${width} ${height}`, children: [_jsx("g", { className: "ui-bar-chart__marks", children: bars.marks.map(mark => _jsx("rect", { className: getLumenChartToneClassName(mark.tone), height: mark.height, rx: "4", width: mark.width, x: mark.x, y: mark.y, children: _jsx("title", { children: `${mark.seriesLabel}: ${formatValue(mark.value)}` }) }, `${mark.seriesId}:${getChartCategoryKey(mark.category)}`)) }), lines.map((geometry, index) => {
|
|
348
|
-
const item = lineSeries[index];
|
|
349
|
-
if (!item)
|
|
350
|
-
return null;
|
|
351
|
-
const tone = resolveLumenChartTone(item.tone, index + barSeries.length);
|
|
352
|
-
return (_jsxs("g", { className: composeClassName('ui-line-chart__series', getLumenChartToneClassName(tone)), children: [item.mark === 'area' && geometry.areaPaths.map(path => (_jsx("path", { className: "ui-line-chart__area", d: path }, path))), _jsx("path", { className: "ui-line-chart__line", d: geometry.path })] }, item.id));
|
|
353
|
-
})] }) }), showTable && hasData && (_jsx(ChartDataTable, { categories: categories, formatValue: formatValue, labels: resolvedLabels, series: series }))] }));
|
|
354
|
-
};
|
|
355
|
-
export const Checkbox = ({ className, ref, ...props }) => (_jsx("input", { className: composeClassName('ui-checkbox', className), ref: ref, type: "checkbox", ...props }));
|
|
356
|
-
export const CheckboxGroup = ({ children, className, invalid = false, legend, orientation = 'vertical', ...props }) => (_jsxs("fieldset", { "aria-invalid": invalid || undefined, className: composeClassName('ui-checkbox-group', `ui-checkbox-group--${orientation}`, className), "data-invalid": invalid ? 'true' : undefined, "data-orientation": orientation, "data-ui-checkbox-group": true, ...props, children: [legend && _jsx("legend", { children: legend }), children] }));
|
|
357
|
-
export const Collapsible = ({ className, ...props }) => (_jsx("details", { className: composeClassName('ui-collapsible', className), "data-ui-collapsible": true, ...props }));
|
|
358
|
-
const renderCodeToken = (token) => {
|
|
359
|
-
if (!token.kind)
|
|
360
|
-
return token.value;
|
|
361
|
-
return (_jsx("span", { className: lumenCodeTokenClassNames[token.kind], children: token.value }, `${token.start}-${token.kind}`));
|
|
362
|
-
};
|
|
363
|
-
const renderCodeChildren = (code, children, language) => code === undefined ?
|
|
364
|
-
children :
|
|
365
|
-
tokenizeLumenCode(code, language).map(renderCodeToken);
|
|
366
|
-
const renderCodeCopyButton = () => (_jsxs("button", { "aria-label": "Copy code to clipboard", className: "ui-code__copy", "data-ui-code-copy": true, type: "button", children: [renderLucideIcon('copy', 'ui-code__copy-icon'), renderLucideIcon('check', 'ui-code__check-icon')] }));
|
|
367
|
-
const renderCodeHeader = ({ copy, label, language }) => {
|
|
368
|
-
if (!copy && !label && !language)
|
|
369
|
-
return null;
|
|
370
|
-
return (_jsxs("figcaption", { className: "ui-code__header", children: [_jsxs("span", { "aria-hidden": "true", className: "ui-code__dots", children: [_jsx("span", { className: "ui-code__dot ui-code__dot--red" }), _jsx("span", { className: "ui-code__dot ui-code__dot--yellow" }), _jsx("span", { className: "ui-code__dot ui-code__dot--green" })] }), _jsxs("span", { className: "ui-code__meta", children: [language && _jsx("span", { className: "ui-code__language", children: language }), label && _jsx("span", { className: "ui-code__label", children: label })] }), copy && renderCodeCopyButton()] }));
|
|
371
|
-
};
|
|
372
|
-
export const Code = ({ children, className, code, copy = false, highlighted = false, label, language, theme = 'auto', variant = 'inline', wrap = false, ...props }) => {
|
|
373
|
-
const codeChildren = renderCodeChildren(code, children, language);
|
|
374
|
-
if (variant === 'block') {
|
|
375
|
-
return (_jsxs("figure", { className: composeClassName('ui-code ui-code--block', wrap && 'ui-code--wrap', className), "data-code-theme": theme, "data-language": language, "data-slot": "code", "data-ui-code": true, ...props, children: [renderCodeHeader({ copy, label, language }), highlighted ?
|
|
376
|
-
(children) :
|
|
377
|
-
(_jsx("pre", { children: _jsx("code", { children: codeChildren }) }))] }));
|
|
378
|
-
}
|
|
379
|
-
return (_jsx("code", { className: composeClassName('ui-code ui-code--inline', className), "data-code-theme": theme, "data-language": language, "data-slot": "code", ...props, children: code ?? children }));
|
|
380
|
-
};
|
|
381
|
-
const dispatchCopyToast = (enabled, title, variant) => {
|
|
382
|
-
if (!enabled)
|
|
383
|
-
return;
|
|
384
|
-
document.dispatchEvent(new CustomEvent('ui:toast', {
|
|
385
|
-
detail: { title, variant }
|
|
386
|
-
}));
|
|
387
|
-
};
|
|
388
|
-
const resolveCopyText = (target, value) => {
|
|
389
|
-
if (value !== undefined)
|
|
390
|
-
return value;
|
|
391
|
-
if (!target)
|
|
392
|
-
return undefined;
|
|
393
|
-
const targetElement = document.querySelector(target);
|
|
394
|
-
return targetElement?.innerText ?? targetElement?.textContent ?? undefined;
|
|
395
|
-
};
|
|
396
|
-
const resolveCopyFeedback = (content, fallback) => (content ?? fallback);
|
|
397
|
-
export const CopyButton = ({ children = 'Copy', className, copiedContent, copiedLabel = 'Copied to clipboard', errorContent, errorLabel = 'Could not copy to clipboard', label = 'Copy to clipboard', onClick, resetAfter = 2000, size = 'default', target, toast = false, value, variant = 'outline', ...props }) => {
|
|
398
|
-
const [state, setState] = useState('idle');
|
|
399
|
-
const resetTimerRef = useRef(undefined);
|
|
400
|
-
useEffect(() => () => {
|
|
401
|
-
globalThis.clearTimeout(resetTimerRef.current);
|
|
402
|
-
}, []);
|
|
403
|
-
const handleClick = async (event) => {
|
|
404
|
-
onClick?.(event);
|
|
405
|
-
if (event.defaultPrevented)
|
|
406
|
-
return;
|
|
407
|
-
const button = event.currentTarget;
|
|
408
|
-
const text = resolveCopyText(target, value);
|
|
409
|
-
try {
|
|
410
|
-
if (text === undefined)
|
|
411
|
-
throw new Error(errorLabel);
|
|
412
|
-
await navigator.clipboard.writeText(text);
|
|
413
|
-
setState('copied');
|
|
414
|
-
button.dispatchEvent(new CustomEvent('ui:copy-success', {
|
|
415
|
-
bubbles: true,
|
|
416
|
-
detail: { value: text }
|
|
417
|
-
}));
|
|
418
|
-
dispatchCopyToast(toast, copiedLabel, 'success');
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
setState('error');
|
|
422
|
-
button.dispatchEvent(new CustomEvent('ui:copy-error', {
|
|
423
|
-
bubbles: true,
|
|
424
|
-
detail: { error }
|
|
425
|
-
}));
|
|
426
|
-
dispatchCopyToast(toast, errorLabel, 'destructive');
|
|
427
|
-
}
|
|
428
|
-
globalThis.clearTimeout(resetTimerRef.current);
|
|
429
|
-
resetTimerRef.current = globalThis.setTimeout(() => {
|
|
430
|
-
setState('idle');
|
|
431
|
-
}, resetAfter);
|
|
432
|
-
};
|
|
433
|
-
const accessibleLabel = {
|
|
434
|
-
copied: copiedLabel,
|
|
435
|
-
error: errorLabel,
|
|
436
|
-
idle: label
|
|
437
|
-
}[state];
|
|
438
|
-
return (_jsxs(Button, { "aria-label": accessibleLabel, className: composeClassName('ui-copy-button', className), "data-slot": "copy-button", "data-state": state, "data-ui-copy-button": true, onClick: handleClick, size: size, variant: variant, ...props, children: [_jsx("span", { "aria-hidden": "true", "data-slot": "copy-idle", hidden: state !== 'idle', children: children }), _jsx("span", { "aria-hidden": "true", "data-slot": "copy-copied", hidden: state !== 'copied', children: resolveCopyFeedback(copiedContent, copiedLabel) }), _jsx("span", { "aria-hidden": "true", "data-slot": "copy-error", hidden: state !== 'error', children: resolveCopyFeedback(errorContent, errorLabel) })] }));
|
|
439
|
-
};
|
|
440
|
-
export const Combobox = ({ className, defaultValue, id, label, list, onBlur, onChange, onFocus, onKeyDown, options = emptyStringOptions, type = 'text', value: valueProp, wrapperClassName, ...props }) => {
|
|
441
|
-
const inputId = id ?? `${list}-input`;
|
|
442
|
-
const rootRef = useRef(null);
|
|
443
|
-
const [open, setOpen] = useState(false);
|
|
444
|
-
const [value, setValue] = useState(() => String(defaultValue ?? ''));
|
|
445
|
-
const renderedValue = valueProp ?? value;
|
|
446
|
-
const query = String(renderedValue).trim().toLowerCase();
|
|
447
|
-
const visibleOptions = useMemo(() => options.filter(option => !query || option.toLowerCase().includes(query)), [options, query]);
|
|
448
|
-
const selectOption = (option) => {
|
|
449
|
-
if (valueProp === undefined) {
|
|
450
|
-
setValue(option);
|
|
451
|
-
}
|
|
452
|
-
setOpen(false);
|
|
453
|
-
};
|
|
454
|
-
const getVisibleOptions = () => [
|
|
455
|
-
...(rootRef.current?.querySelectorAll('[data-ui-combobox-option]:not([hidden]):not([disabled])') ?? [])
|
|
456
|
-
];
|
|
457
|
-
const focusInputEdgeOption = (key) => {
|
|
458
|
-
const options = getVisibleOptions();
|
|
459
|
-
options[key === 'ArrowUp' ? options.length - 1 : 0]?.focus();
|
|
460
|
-
};
|
|
461
|
-
const focusOption = (option, key) => {
|
|
462
|
-
const options = getVisibleOptions();
|
|
463
|
-
if (!options.length)
|
|
464
|
-
return;
|
|
465
|
-
const currentIndex = Math.max(0, options.indexOf(option));
|
|
466
|
-
let nextIndex = (currentIndex - 1 + options.length) % options.length;
|
|
467
|
-
if (key === 'Home')
|
|
468
|
-
nextIndex = 0;
|
|
469
|
-
else if (key === 'End')
|
|
470
|
-
nextIndex = options.length - 1;
|
|
471
|
-
else if (key === 'ArrowDown')
|
|
472
|
-
nextIndex = (currentIndex + 1) % options.length;
|
|
473
|
-
options[nextIndex]?.focus();
|
|
474
|
-
};
|
|
475
|
-
return (_jsxs("div", { className: composeClassName('ui-combobox', wrapperClassName), "data-ui-combobox": true, onBlur: event => {
|
|
476
|
-
const nextTarget = event.relatedTarget;
|
|
477
|
-
if (!nextTarget || !event.currentTarget.contains(nextTarget)) {
|
|
478
|
-
setOpen(false);
|
|
479
|
-
}
|
|
480
|
-
}, ref: rootRef, children: [label && (_jsx("label", { className: "ui-label", htmlFor: inputId, children: label })), _jsx("input", { "aria-autocomplete": "list", "aria-controls": list, "aria-expanded": open, className: composeClassName('ui-input', className), id: inputId, role: "combobox", type: type, value: renderedValue, onBlur: onBlur, onChange: event => {
|
|
481
|
-
if (valueProp === undefined) {
|
|
482
|
-
setValue(event.currentTarget.value);
|
|
483
|
-
}
|
|
484
|
-
setOpen(true);
|
|
485
|
-
onChange?.(event);
|
|
486
|
-
}, onFocus: event => {
|
|
487
|
-
setOpen(true);
|
|
488
|
-
onFocus?.(event);
|
|
489
|
-
}, onKeyDown: event => {
|
|
490
|
-
if (event.key === 'Escape') {
|
|
491
|
-
setOpen(false);
|
|
492
|
-
}
|
|
493
|
-
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
494
|
-
const key = event.key;
|
|
495
|
-
event.preventDefault();
|
|
496
|
-
setOpen(true);
|
|
497
|
-
globalThis.queueMicrotask(() => {
|
|
498
|
-
focusInputEdgeOption(key);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
if (event.key === 'Enter' && visibleOptions[0]) {
|
|
502
|
-
event.preventDefault();
|
|
503
|
-
selectOption(visibleOptions[0]);
|
|
504
|
-
}
|
|
505
|
-
onKeyDown?.(event);
|
|
506
|
-
}, ...props }), _jsx("div", { className: "ui-combobox__list", hidden: !open, id: list, role: "listbox", children: visibleOptions.map(option => (_jsx("button", { "data-ui-combobox-option": true, "data-value": option, role: "option", tabIndex: -1, type: "button", onClick: () => {
|
|
507
|
-
selectOption(option);
|
|
508
|
-
}, onKeyDown: event => {
|
|
509
|
-
if (event.key === 'Escape') {
|
|
510
|
-
setOpen(false);
|
|
511
|
-
rootRef.current?.querySelector('input[role="combobox"]')?.focus();
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
515
|
-
event.preventDefault();
|
|
516
|
-
rootRef.current?.querySelector('input[role="combobox"]')?.focus();
|
|
517
|
-
selectOption(option);
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
if (!['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key))
|
|
521
|
-
return;
|
|
522
|
-
event.preventDefault();
|
|
523
|
-
focusOption(event.currentTarget, event.key);
|
|
524
|
-
}, onMouseDown: event => {
|
|
525
|
-
event.preventDefault();
|
|
526
|
-
}, children: option }, option))) })] }));
|
|
527
|
-
};
|
|
528
|
-
export const Command = ({ className, glass = false, ...props }) => (_jsx("div", { className: composeClassName('ui-command', glassClass('ui-command', glass), className), "data-ui-command": true, ...props }));
|
|
529
|
-
export const ContextMenu = ({ className, glass = false, ...props }) => (_jsx("menu", { className: composeClassName('ui-menu', glassSurfaceClass('ui-menu', glass), className), "data-surface": resolveSurface(glass), "data-ui-context-menu": true, role: props.role ?? 'menu', ...props }));
|
|
530
|
-
export const ColorPicker = ({ className, type = 'color', ...props }) => (_jsx("input", { className: composeClassName('ui-color-picker', className), type: type, ...props }));
|
|
531
|
-
export const DataTable = ({ children, className, columns = emptyDataTableColumns, glass = false, name, rows = emptyDataTableRows, selectable = false, ...props }) => {
|
|
532
|
-
const [sort, setSort] = useState(null);
|
|
533
|
-
const sortedRows = useMemo(() => {
|
|
534
|
-
if (!sort)
|
|
535
|
-
return rows;
|
|
536
|
-
const column = columns.find(candidate => candidate.key === sort.key);
|
|
537
|
-
if (!column)
|
|
538
|
-
return rows;
|
|
539
|
-
const direction = sort.direction === 'ascending' ? 1 : -1;
|
|
540
|
-
return [...rows].sort((left, right) => compareDataTableCells(left[column.key], right[column.key], column.sort) * direction);
|
|
541
|
-
}, [columns, rows, sort]);
|
|
542
|
-
const toggleSort = (column) => {
|
|
543
|
-
setSort(current => ({
|
|
544
|
-
direction: current?.key === column.key && current.direction === 'ascending' ?
|
|
545
|
-
'descending' :
|
|
546
|
-
'ascending',
|
|
547
|
-
key: column.key
|
|
548
|
-
}));
|
|
549
|
-
};
|
|
550
|
-
return (_jsx("div", { className: composeClassName('ui-data-table', glassClass('ui-data-table', glass), className), "data-ui-datatable": true, "data-ui-datatable-name": name, "data-ui-datatable-selectable": selectable ? 'true' : undefined, "data-ui-glass-track": glass ? true : undefined, ...props, children: columns.length > 0 ?
|
|
551
|
-
(_jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: columns.map(column => {
|
|
552
|
-
const direction = sort?.key === column.key ?
|
|
553
|
-
sort.direction :
|
|
554
|
-
undefined;
|
|
555
|
-
const label = column.header ?? column.label ?? column.key;
|
|
556
|
-
return (_jsx("th", { "aria-sort": direction ?? (column.sortable ? 'none' : undefined), "data-ui-datatable-sort-type": column.sort, "data-ui-datatable-sortable": column.sortable ? 'true' : undefined, scope: "col", children: column.sortable ?
|
|
557
|
-
(_jsx("button", { className: "ui-data-table__sort", "data-ui-datatable-sort": true, onClick: () => {
|
|
558
|
-
toggleSort(column);
|
|
559
|
-
}, type: "button", children: label })) :
|
|
560
|
-
label }, column.key));
|
|
561
|
-
}) }) }), _jsx("tbody", { children: sortedRows.map((row, rowIndex) => (_jsx("tr", { "data-ui-datatable-row": true, "data-value": getDataTableRowValue(row, rowIndex), children: columns.map(column => (_jsx("td", { "data-sort-value": getDataTableSortValue(row[column.key]), children: formatDataTableCell(row[column.key]) }, column.key))) }, getDataTableRowValue(row, rowIndex)))) })] })) :
|
|
562
|
-
children }));
|
|
563
|
-
};
|
|
564
|
-
const formatDatePickerDisplayValue = (value, placeholder) => {
|
|
565
|
-
if (!value || !/^\d{4}-\d{2}-\d{2}$/.test(value))
|
|
566
|
-
return placeholder;
|
|
567
|
-
const date = new Date(`${value}T00:00:00.000Z`);
|
|
568
|
-
if (Number.isNaN(date.getTime()))
|
|
569
|
-
return placeholder;
|
|
570
|
-
return new Intl.DateTimeFormat(undefined, {
|
|
571
|
-
day: 'numeric',
|
|
572
|
-
month: 'short',
|
|
573
|
-
timeZone: 'UTC',
|
|
574
|
-
year: 'numeric'
|
|
575
|
-
}).format(date);
|
|
576
|
-
};
|
|
577
|
-
const stringifyDatePickerConstraint = (value) => (value === undefined ? undefined : String(value));
|
|
578
|
-
/* eslint-disable complexity -- DatePicker coordinates controlled input, disclosure, Calendar, and native form contracts. */
|
|
579
|
-
export const DatePicker = ({ className, defaultValue, disabled, glass = false, id, inputRef, max, min, name, onChange, onInvalid, onValueChange, placeholder, required, value, ...props }) => {
|
|
580
|
-
const generatedId = useId();
|
|
581
|
-
const datePickerId = id ?? generatedId;
|
|
582
|
-
const triggerId = `${datePickerId}-trigger`;
|
|
583
|
-
const popoverId = `${datePickerId}-popover`;
|
|
584
|
-
const rootRef = useRef(null);
|
|
585
|
-
const nativeInputRef = useRef(null);
|
|
586
|
-
const triggerRef = useRef(null);
|
|
587
|
-
const [internalValue, setInternalValue] = useState(defaultValue ?? '');
|
|
588
|
-
const [open, setOpen] = useState(false);
|
|
589
|
-
const selectedValue = value ?? internalValue;
|
|
590
|
-
const hasSelectedValue = selectedValue !== '';
|
|
591
|
-
const placeholderText = placeholder ?? 'Choose a date';
|
|
592
|
-
const maxStr = stringifyDatePickerConstraint(max);
|
|
593
|
-
const minStr = stringifyDatePickerConstraint(min);
|
|
594
|
-
const accessibleLabel = props['aria-label'];
|
|
595
|
-
useEffect(() => {
|
|
596
|
-
if (!open)
|
|
597
|
-
return;
|
|
598
|
-
const handlePointerDown = (event) => {
|
|
599
|
-
if (event.target instanceof Node &&
|
|
600
|
-
!rootRef.current?.contains(event.target))
|
|
601
|
-
setOpen(false);
|
|
602
|
-
};
|
|
603
|
-
const handleKeyDown = (event) => {
|
|
604
|
-
if (event.key !== 'Escape')
|
|
605
|
-
return;
|
|
606
|
-
setOpen(false);
|
|
607
|
-
triggerRef.current?.focus();
|
|
608
|
-
};
|
|
609
|
-
document.addEventListener('mousedown', handlePointerDown);
|
|
610
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
611
|
-
return () => {
|
|
612
|
-
document.removeEventListener('mousedown', handlePointerDown);
|
|
613
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
614
|
-
};
|
|
615
|
-
}, [open]);
|
|
616
|
-
const selectDate = (nextValue) => {
|
|
617
|
-
if (value === undefined)
|
|
618
|
-
setInternalValue(nextValue);
|
|
619
|
-
onValueChange?.(nextValue);
|
|
620
|
-
if (nativeInputRef.current) {
|
|
621
|
-
nativeInputRef.current.value = nextValue;
|
|
622
|
-
nativeInputRef.current.dispatchEvent(new Event('input', { bubbles: true }));
|
|
623
|
-
nativeInputRef.current.dispatchEvent(new Event('change', { bubbles: true }));
|
|
624
|
-
}
|
|
625
|
-
setOpen(false);
|
|
626
|
-
globalThis.setTimeout(() => triggerRef.current?.focus());
|
|
627
|
-
};
|
|
628
|
-
return (_jsxs("div", { className: composeClassName('ui-date-picker-field', glass && 'ui-date-picker-field--glass', glass === 'subtle' && 'ui-glass-subtle', glass === 'strong' && 'ui-glass-strong', className), "data-placeholder": hasSelectedValue ? undefined : 'true', "data-ui-date-picker": true, "data-ui-glass-track": glass ? true : undefined, ref: rootRef, children: [_jsx("input", { "aria-hidden": "true", className: "ui-date-picker ui-date-picker__native", "data-ui-date-picker-native": true, "data-ui-enhanced": "true", disabled: disabled, id: datePickerId, max: max, min: min, name: name, onChange: event => {
|
|
629
|
-
if (value === undefined)
|
|
630
|
-
setInternalValue(event.currentTarget.value);
|
|
631
|
-
onChange?.(event);
|
|
632
|
-
}, onInvalid: event => {
|
|
633
|
-
event.preventDefault();
|
|
634
|
-
triggerRef.current?.setAttribute('aria-invalid', 'true');
|
|
635
|
-
triggerRef.current?.focus();
|
|
636
|
-
onInvalid?.(event);
|
|
637
|
-
}, ref: node => {
|
|
638
|
-
nativeInputRef.current = node;
|
|
639
|
-
setRefValue(inputRef, node);
|
|
640
|
-
}, required: required, tabIndex: -1, type: "date", value: selectedValue, ...props }), _jsxs("div", { className: "ui-date-picker__control", "data-ui-date-picker-control": true, children: [_jsxs("button", { "aria-controls": popoverId, "aria-expanded": open, "aria-haspopup": "dialog", "aria-label": accessibleLabel, "aria-required": required ?? undefined, className: "ui-input ui-date-picker ui-date-picker__trigger", "data-ui-date-picker-trigger": true, disabled: disabled, id: triggerId, onClick: () => {
|
|
641
|
-
setOpen(current => !current);
|
|
642
|
-
}, onKeyDown: event => {
|
|
643
|
-
if (event.key !== 'ArrowDown')
|
|
644
|
-
return;
|
|
645
|
-
event.preventDefault();
|
|
646
|
-
setOpen(true);
|
|
647
|
-
}, ref: triggerRef, type: "button", children: [_jsx("span", { "data-ui-date-picker-value": true, children: formatDatePickerDisplayValue(selectedValue, placeholderText) }), _jsx("svg", { "aria-hidden": "true", className: "ui-date-picker__icon", fill: "none", viewBox: "0 0 24 24", children: _jsx("path", { d: "M7 2v3M17 2v3M3.5 9h17M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" }) })] }), _jsx("div", { "aria-label": "Choose date", className: "ui-date-picker__popover", "data-state": open ? 'open' : 'closed', "data-ui-date-picker-popover": true, hidden: !open, id: popoverId, role: "dialog", children: _jsx(Calendar, { disabled: disabled, max: maxStr, min: minStr, onValueChange: selectDate, value: selectedValue }) })] })] }));
|
|
648
|
-
};
|
|
649
|
-
const setDateRangeConstraint = (input, property, value) => {
|
|
650
|
-
if (value)
|
|
651
|
-
input[property] = value;
|
|
652
|
-
else
|
|
653
|
-
input.removeAttribute(property);
|
|
654
|
-
};
|
|
655
|
-
const getDateRangeState = (start, end) => {
|
|
656
|
-
if (!start)
|
|
657
|
-
return 'empty';
|
|
658
|
-
return end ? 'complete' : 'selecting-end';
|
|
659
|
-
};
|
|
660
|
-
const syncDateRangePickerElement = (root) => {
|
|
661
|
-
const inputs = [
|
|
662
|
-
...root.querySelectorAll('[data-ui-date-picker-native]')
|
|
663
|
-
];
|
|
664
|
-
const start = inputs[0];
|
|
665
|
-
const end = inputs.at(-1);
|
|
666
|
-
if (!(start && end) || start === end)
|
|
667
|
-
return {};
|
|
668
|
-
const datePickers = root.querySelectorAll('[data-ui-date-picker]');
|
|
669
|
-
datePickers[0]?.setAttribute('data-range-part', 'start');
|
|
670
|
-
datePickers[datePickers.length - 1]?.setAttribute('data-range-part', 'end');
|
|
671
|
-
setDateRangeConstraint(end, 'min', start.value);
|
|
672
|
-
setDateRangeConstraint(start, 'max', end.value);
|
|
673
|
-
root.dataset.rangeState = getDateRangeState(start.value, end.value);
|
|
674
|
-
const range = {};
|
|
675
|
-
if (end.value)
|
|
676
|
-
range.end = end.value;
|
|
677
|
-
if (start.value)
|
|
678
|
-
range.start = start.value;
|
|
679
|
-
return range;
|
|
680
|
-
};
|
|
681
|
-
export const DateRangePicker = ({ className, onInput, onRangeChange, ...props }) => {
|
|
682
|
-
const rootRef = useRef(null);
|
|
683
|
-
useEffect(() => {
|
|
684
|
-
if (rootRef.current)
|
|
685
|
-
syncDateRangePickerElement(rootRef.current);
|
|
686
|
-
});
|
|
687
|
-
return (_jsx("div", { className: composeClassName('ui-date-range-picker', className), "data-ui-date-range-picker": true, onInput: event => {
|
|
688
|
-
onInput?.(event);
|
|
689
|
-
onRangeChange?.(syncDateRangePickerElement(event.currentTarget));
|
|
690
|
-
}, ref: rootRef, ...props }));
|
|
691
|
-
};
|
|
692
|
-
export const Dialog = ({ className, defaultOpen, glass = false, layout = 'centered', onClick, onClose, onOpenChange, open, ...props }) => {
|
|
693
|
-
const dialog = useDialog({ defaultOpen, onOpenChange, open });
|
|
694
|
-
return (_jsx("dialog", { ...dialog.dialogProps, ...props, className: composeClassName('ui-dialog', layout === 'fullscreen' && 'ui-dialog--fullscreen', glassSurfaceClass('ui-dialog', glass), className), "data-layout": layout, "data-surface": resolveSurface(glass), onClick: composeHandlers(onClick, dialog.dialogProps.onClick), onClose: composeHandlers(onClose, dialog.dialogProps.onClose) }));
|
|
695
|
-
};
|
|
696
|
-
export const Drawer = ({ className, glass = false, ...props }) => (_jsx("dialog", { className: composeClassName('ui-drawer', glassSurfaceClass('ui-drawer', glass), className), "data-surface": resolveSurface(glass), "data-ui-drawer": true, ...props }));
|
|
697
|
-
export const DropdownMenu = ({ children, className, defaultOpen, glass = false, onOpenChange, open, ...props }) => {
|
|
698
|
-
const menu = useDropdownMenu({ defaultOpen, onOpenChange, open });
|
|
699
|
-
return (_jsx(DropdownMenuContext.Provider, { value: menu, children: _jsx("menu", { ...menu.rootProps, ...props, className: composeClassName('ui-menu', glassSurfaceClass('ui-menu', glass), className), "data-surface": resolveSurface(glass), "data-ui-dropdown-menu": true, children: children }) }));
|
|
700
|
-
};
|
|
701
|
-
export const DropdownMenuTrigger = ({ onClick, onKeyDown, ...props }) => {
|
|
702
|
-
const menu = requireContext(useContext(DropdownMenuContext), 'DropdownMenuTrigger');
|
|
703
|
-
return (_jsx("button", { ...menu.triggerProps, ...props, onClick: composeHandlers(onClick, menu.triggerProps.onClick), onKeyDown: composeHandlers(onKeyDown, menu.triggerProps.onKeyDown), type: props.type ?? 'button' }));
|
|
704
|
-
};
|
|
705
|
-
export const DropdownMenuContent = ({ className, onKeyDown, ...props }) => {
|
|
706
|
-
const menu = requireContext(useContext(DropdownMenuContext), 'DropdownMenuContent');
|
|
707
|
-
return (_jsx("div", { ...menu.panelProps, ...props, className: composeClassName('ui-menu__content', className), onKeyDown: composeHandlers(onKeyDown, menu.panelProps.onKeyDown), role: props.role ?? 'menu' }));
|
|
708
|
-
};
|
|
709
|
-
export const DropdownMenuItem = ({ children, className, disabled = false, onClick, status, ...props }) => {
|
|
710
|
-
const menu = requireContext(useContext(DropdownMenuContext), 'DropdownMenuItem');
|
|
711
|
-
return (_jsxs("button", { ...props, "aria-disabled": disabled || undefined, className: composeClassName('ui-menu__item', className), disabled: disabled, onClick: event => {
|
|
712
|
-
onClick?.(event);
|
|
713
|
-
if (!event.defaultPrevented && !disabled)
|
|
714
|
-
menu.close();
|
|
715
|
-
}, role: props.role ?? 'menuitem', type: props.type ?? 'button', children: [_jsx("span", { className: "ui-menu__item-label", children: children }), status && _jsx("span", { className: "ui-menu__item-status", children: status })] }));
|
|
716
|
-
};
|
|
717
|
-
export const DropdownMenuSeparator = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-menu__separator', className), role: props.role ?? 'separator', ...props }));
|
|
718
|
-
export const Empty = ({ className, glass = false, variant = 'default', ...props }) => (_jsx("section", { className: composeClassName('ui-empty', variant === 'compact' && 'ui-empty--compact', glassClass('ui-empty', glass), className), "data-variant": variant, ...props }));
|
|
719
|
-
const renderIllustrationElement = (element, index) => {
|
|
720
|
-
if (element.kind === 'circle') {
|
|
721
|
-
return _jsx("circle", { cx: element.cx, cy: element.cy, r: element.r }, index);
|
|
722
|
-
}
|
|
723
|
-
if (element.kind === 'rounded-rect') {
|
|
724
|
-
return (_jsx("rect", { height: element.height, rx: element.radius, width: element.width, x: element.x, y: element.y }, index));
|
|
725
|
-
}
|
|
726
|
-
const pointPairs = [];
|
|
727
|
-
for (let pointIndex = 0; pointIndex < element.points.length; pointIndex += 2) {
|
|
728
|
-
const x = element.points[pointIndex];
|
|
729
|
-
const y = element.points[pointIndex + 1];
|
|
730
|
-
if (x === undefined || y === undefined)
|
|
731
|
-
break;
|
|
732
|
-
pointPairs.push(`${x},${y}`);
|
|
733
|
-
}
|
|
734
|
-
return createElement(element.kind, { key: index, points: pointPairs.join(' ') });
|
|
735
|
-
};
|
|
736
|
-
export const Illustration = ({ className, label, size = 'md', tone = 'auto', variant = 'empty', ...props }) => (_jsx("span", { "aria-hidden": label ? undefined : true, "aria-label": label, className: composeClassName('ui-illustration', `ui-illustration--${variant}`, `ui-illustration--${tone}`, `ui-illustration--${size}`, className), role: label ? 'img' : undefined, ...props, children: _jsxs("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 120 120", children: [_jsx("circle", { className: "ui-illustration__wash", cx: "60", cy: "60", r: "48" }), lumenIllustrations[variant].elements.map(renderIllustrationElement)] }) }));
|
|
737
|
-
const resolveErrorStateAnnouncement = (announce, ariaLive, role) => {
|
|
738
|
-
if (announce === 'assertive') {
|
|
739
|
-
return { 'aria-live': ariaLive ?? 'assertive', role: role ?? 'alert' };
|
|
740
|
-
}
|
|
741
|
-
if (announce === 'polite') {
|
|
742
|
-
return { 'aria-live': ariaLive ?? 'polite', role: role ?? 'status' };
|
|
743
|
-
}
|
|
744
|
-
return {
|
|
745
|
-
...(ariaLive ? { 'aria-live': ariaLive } : {}),
|
|
746
|
-
...(role ? { role } : {})
|
|
747
|
-
};
|
|
748
|
-
};
|
|
749
|
-
const ErrorStateGraphic = ({ graphic, kind, layout }) => {
|
|
750
|
-
if (graphic === false)
|
|
751
|
-
return null;
|
|
752
|
-
return (_jsx("div", { "aria-hidden": "true", className: "ui-error-state__graphic", "data-slot": "error-state-graphic", children: graphic ?? (_jsx(Illustration, { size: layout === 'compact' ? 'sm' : 'md', variant: kind })) }));
|
|
753
|
-
};
|
|
754
|
-
const ErrorStateContent = ({ children, description, headingLevel, reference, referenceLabel, title, titleId }) => (_jsxs("div", { className: "ui-error-state__content", "data-slot": "error-state-content", children: [createElement(`h${headingLevel}`, {
|
|
755
|
-
className: 'ui-error-state__title',
|
|
756
|
-
'data-slot': 'error-state-title',
|
|
757
|
-
id: titleId
|
|
758
|
-
}, title), description && (_jsx("p", { className: "ui-error-state__description", "data-slot": "error-state-description", children: description })), children && (_jsx("div", { className: "ui-error-state__details", "data-slot": "error-state-details", children: children })), reference && (_jsxs("p", { className: "ui-error-state__reference", "data-slot": "error-state-reference", children: [_jsxs("span", { children: [referenceLabel, ":"] }), ' ', _jsx("code", { children: reference })] }))] }));
|
|
759
|
-
const ErrorStateActions = ({ actions }) => actions ?
|
|
760
|
-
(_jsx("div", { className: "ui-error-state__actions", "data-slot": "error-state-actions", children: actions })) :
|
|
761
|
-
null;
|
|
762
|
-
export const ErrorState = ({ 'aria-live': ariaLive, actions, announce, children, className, description, graphic, headingLevel, id, kind, layout, reference, referenceLabel, role, title, ...props }) => {
|
|
763
|
-
const resolvedAnnounce = announce ?? 'off';
|
|
764
|
-
const resolvedHeadingLevel = headingLevel ?? 2;
|
|
765
|
-
const resolvedKind = kind ?? 'error';
|
|
766
|
-
const resolvedLayout = layout ?? 'default';
|
|
767
|
-
const resolvedReferenceLabel = referenceLabel ?? 'Reference';
|
|
768
|
-
const titleId = id ? `${id}-title` : undefined;
|
|
769
|
-
const announcementProps = resolveErrorStateAnnouncement(resolvedAnnounce, ariaLive, role);
|
|
770
|
-
return (_jsxs("section", { "aria-label": titleId ? undefined : title, "aria-labelledby": titleId, className: composeClassName('ui-error-state', `ui-error-state--${resolvedKind}`, `ui-error-state--${resolvedLayout}`, className), "data-kind": resolvedKind, "data-layout": resolvedLayout, "data-ui-error-state": true, id: id, ...announcementProps, ...props, children: [_jsx(ErrorStateGraphic, { graphic: graphic, kind: resolvedKind, layout: resolvedLayout }), _jsx(ErrorStateContent, { description: description, headingLevel: resolvedHeadingLevel, reference: reference, referenceLabel: resolvedReferenceLabel, title: title, titleId: titleId, children: children }), _jsx(ErrorStateActions, { actions: actions })] }));
|
|
771
|
-
};
|
|
772
|
-
export const KanbanBoard = ({ className, tabIndex = 0, ...props }) => (_jsx("section", { "aria-orientation": "horizontal", className: composeClassName('ui-kanban-board ui-kanban', className), "data-ui-kanban": true, tabIndex: tabIndex, ...props }));
|
|
773
|
-
export const KanbanColumn = ({ className, value, ...props }) => (_jsx("section", { className: composeClassName('ui-kanban__column', className), "data-ui-kanban-column": value, ...props }));
|
|
774
|
-
export const ErrorSummary = ({ className, errors, heading = 'There is a problem', id = 'ui-error-summary', ...props }) => {
|
|
775
|
-
const normalizedErrors = normalizeLumenFormErrors(errors);
|
|
776
|
-
const allErrors = [
|
|
777
|
-
...normalizedErrors.form.map(message => ({ message })),
|
|
778
|
-
...normalizedErrors.fields
|
|
779
|
-
];
|
|
780
|
-
const headingId = `${id}-heading`;
|
|
781
|
-
return (_jsxs("section", { "aria-labelledby": headingId, className: composeClassName('ui-error-summary', className), "data-ui-error-summary": true, hidden: allErrors.length === 0, id: id, tabIndex: -1, ...props, children: [_jsx("h2", { id: headingId, children: heading }), _jsx("ul", { children: allErrors.map(error => (_jsx("li", { children: error.controlId ?
|
|
782
|
-
(_jsx("a", { href: `#${error.controlId}`, children: error.message })) :
|
|
783
|
-
(error.message) }, `${error.name ?? 'form'}:${error.controlId ?? ''}:${error.message}`))) })] }));
|
|
784
|
-
};
|
|
785
|
-
export const Field = ({ 'aria-describedby': ariaDescribedby, className, controlId, describedBy, glass = false, invalid = false, ...props }) => {
|
|
786
|
-
const fieldDescribedBy = [ariaDescribedby, describedBy].filter(Boolean).join(' ') || undefined;
|
|
787
|
-
return (_jsx("div", { "aria-describedby": ariaDescribedby, className: composeClassName('ui-field', glassClass('ui-field', glass), className), "data-invalid": invalid ? 'true' : undefined, "data-ui-field": true, "data-ui-field-control": controlId, "data-ui-field-describedby": fieldDescribedBy, ...props }));
|
|
788
|
-
};
|
|
789
|
-
export const FieldError = ({ children, className, hidden, message, ...props }) => {
|
|
790
|
-
const content = message ?? children;
|
|
791
|
-
return (_jsx("p", { className: composeClassName('ui-field-error', className), "data-ui-field-error": true, hidden: hidden ?? !content, ...props, children: content }));
|
|
792
|
-
};
|
|
793
|
-
export const Form = ({ 'aria-busy': ariaBusy, className, enhance = false, status = 'idle', ...props }) => (_jsx("form", { "aria-busy": ariaBusy ?? (status === 'submitting' ? true : undefined), className: composeClassName('ui-form', className), "data-status": status, "data-ui-form": enhance ? true : undefined, ...props }));
|
|
794
|
-
export const HoverCard = ({ className, glass = false, ...props }) => (_jsx("aside", { className: composeClassName('ui-hover-card', glassSurfaceClass('ui-hover-card', glass), className), "data-surface": resolveSurface(glass), "data-ui-hover-card": true, ...props }));
|
|
795
|
-
export const Icon = ({ name, ...props }) => (_jsx(IconView, { ...props, icon: name ? getLumenIcon(name) : undefined }));
|
|
796
|
-
const getPasswordFieldDescribedBy = (ariaDescribedBy, hintId, errorId) => [ariaDescribedBy, hintId, errorId].filter(Boolean).join(' ') || undefined;
|
|
797
|
-
const usePasswordVisibility = (inputRef) => {
|
|
798
|
-
const [visible, setVisible] = useState(false);
|
|
799
|
-
useEffect(() => {
|
|
800
|
-
const form = inputRef.current?.form;
|
|
801
|
-
if (!form)
|
|
802
|
-
return;
|
|
803
|
-
const handleReset = () => {
|
|
804
|
-
setVisible(false);
|
|
805
|
-
};
|
|
806
|
-
const hideAfterSuccess = () => {
|
|
807
|
-
if (form.dataset.status === 'success')
|
|
808
|
-
setVisible(false);
|
|
809
|
-
};
|
|
810
|
-
form.addEventListener('reset', handleReset);
|
|
811
|
-
const observer = new MutationObserver(hideAfterSuccess);
|
|
812
|
-
observer.observe(form, {
|
|
813
|
-
attributeFilter: ['data-status'],
|
|
814
|
-
attributes: true
|
|
815
|
-
});
|
|
816
|
-
return () => {
|
|
817
|
-
form.removeEventListener('reset', handleReset);
|
|
818
|
-
observer.disconnect();
|
|
819
|
-
};
|
|
820
|
-
}, [inputRef]);
|
|
821
|
-
const toggleVisibility = () => {
|
|
822
|
-
setVisible(current => !current);
|
|
823
|
-
inputRef.current?.focus({ preventScroll: true });
|
|
824
|
-
};
|
|
825
|
-
return { toggleVisibility, visible };
|
|
826
|
-
};
|
|
827
|
-
const PasswordFieldControl = ({ controlId, describedBy, error, forwardedRef, hideLabel, inputProps, inputRef, name, showLabel, toggleVisibility, visible }) => (_jsxs("div", { className: "ui-password-field__control", "data-ui-password-field": true, children: [_jsx(Input, { ...inputProps, "aria-describedby": describedBy, "aria-invalid": error ? true : undefined, id: controlId, name: name, ref: node => {
|
|
828
|
-
inputRef.current = node;
|
|
829
|
-
setRefValue(forwardedRef, node);
|
|
830
|
-
}, type: visible ? 'text' : 'password' }), _jsx(Button, { "aria-controls": controlId, "aria-label": visible ? hideLabel : showLabel, "aria-pressed": visible, "data-ui-password-toggle": true, onClick: toggleVisibility, size: "icon", type: "button", variant: "ghost", children: _jsx("span", { "aria-hidden": "true", children: visible ? 'Hide' : 'Show' }) })] }));
|
|
831
|
-
const PasswordFieldMessages = ({ error, errorId, hint, hintId }) => (_jsxs(_Fragment, { children: [hint && (_jsx("p", { className: "ui-field__hint", "data-ui-field-hint": true, id: hintId, children: hint })), _jsx(FieldError, { id: errorId, message: error })] }));
|
|
832
|
-
export const PasswordField = ({ 'aria-describedby': ariaDescribedby, className, error, hideLabel = 'Hide password', hint, id, label = 'Password', name, ref, showLabel = 'Show password', ...props }) => {
|
|
833
|
-
const generatedId = useId();
|
|
834
|
-
const controlId = id ?? `ui-password-${generatedId}`;
|
|
835
|
-
const hintId = hint ? `${controlId}-hint` : undefined;
|
|
836
|
-
const errorId = `${controlId}-error`;
|
|
837
|
-
const describedBy = getPasswordFieldDescribedBy(ariaDescribedby, hintId, error ? errorId : undefined);
|
|
838
|
-
const inputRef = useRef(null);
|
|
839
|
-
const { toggleVisibility, visible } = usePasswordVisibility(inputRef);
|
|
840
|
-
return (_jsxs(Field, { className: composeClassName('ui-password-field', className), controlId: controlId, invalid: Boolean(error), ...(describedBy ? { describedBy } : {}), children: [_jsx(Label, { htmlFor: controlId, children: label }), _jsx(PasswordFieldControl, { controlId: controlId, describedBy: describedBy, error: error, forwardedRef: ref, hideLabel: hideLabel, inputProps: props, inputRef: inputRef, name: name, showLabel: showLabel, toggleVisibility: toggleVisibility, visible: visible }), _jsx(PasswordFieldMessages, { error: error, errorId: errorId, hint: hint, hintId: hintId })] }));
|
|
841
|
-
};
|
|
842
|
-
export const InputGroup = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-input-group', className), ...props }));
|
|
843
|
-
export const InputOTP = ({ 'aria-invalid': ariaInvalid, className, defaultValue, disabled = false, inputClassName, inputMode = 'numeric', length = 6, maxLength = length, pattern = '[0-9]*', ref, value, ...props }) => {
|
|
844
|
-
const otp = useInputOTP({
|
|
845
|
-
defaultValue: toInputValue(defaultValue),
|
|
846
|
-
disabled,
|
|
847
|
-
inputMode,
|
|
848
|
-
inputRef: ref,
|
|
849
|
-
invalid: ariaInvalid === true || ariaInvalid === 'true',
|
|
850
|
-
length,
|
|
851
|
-
pattern,
|
|
852
|
-
value: toInputValue(value)
|
|
853
|
-
});
|
|
854
|
-
return (_jsxs("div", { ...otp.rootProps, className: composeClassName(otp.rootProps.className, className), children: [_jsx("input", { ...otp.getInputProps({
|
|
855
|
-
...props,
|
|
856
|
-
'aria-invalid': ariaInvalid,
|
|
857
|
-
className: inputClassName,
|
|
858
|
-
disabled,
|
|
859
|
-
inputMode,
|
|
860
|
-
maxLength,
|
|
861
|
-
pattern
|
|
862
|
-
}) }), _jsx("div", { ...otp.segmentsProps, children: otp.segmentIndexes.map(index => (_jsx("button", { ...otp.getSegmentProps(index), type: "button", children: _jsx("span", { "data-ui-input-otp-char": true, children: otp.getSegmentChar(index) }) }, index))) })] }));
|
|
863
|
-
};
|
|
864
|
-
export const NumberField = ({ className, ref, type = 'number', ...props }) => (_jsx("input", { className: composeClassName('ui-input ui-number-field', className), ref: ref, type: type, ...props }));
|
|
865
|
-
export const Item = ({ as = 'div', className, glass = false, ...props }) => createElement(as, {
|
|
866
|
-
className: composeClassName('ui-item', glassClass('ui-item', glass), className),
|
|
867
|
-
'data-slot': 'item',
|
|
868
|
-
...props
|
|
869
|
-
});
|
|
870
|
-
export const Kbd = ({ className, ...props }) => (_jsx("kbd", { className: composeClassName('ui-kbd', className), ...props }));
|
|
871
|
-
export const Marker = ({ className, variant = 'default', ...props }) => (_jsx("span", { className: composeClassName('ui-marker', variantClass('ui-marker', variant), className), "data-variant": variant, ...props }));
|
|
872
|
-
export const Menubar = ({ className, glass = false, ...props }) => (_jsx("nav", { className: composeClassName('ui-menubar', glassSurfaceClass('ui-menubar', glass), className), "data-surface": resolveSurface(glass), "data-ui-menubar": true, ...props }));
|
|
873
|
-
export const Message = ({ className, from = 'assistant', ...props }) => (_jsx("article", { className: composeClassName('ui-message', `ui-message--${from}`, className), "data-from": from, ...props }));
|
|
874
|
-
export const MessageScroller = ({ className, glass = false, ...props }) => (_jsx("div", { className: composeClassName('ui-message-scroller', glassClass('ui-message-scroller', glass), className), ...props }));
|
|
875
|
-
export const NativeSelect = ({ children, className, defaultValue, options = emptyOptions, placeholder, ref, value, visualSize = 'default', ...props }) => {
|
|
876
|
-
const placeholderDefaultValue = placeholder && value === undefined && defaultValue === undefined ?
|
|
877
|
-
'' :
|
|
878
|
-
undefined;
|
|
879
|
-
return (_jsxs("select", { className: composeClassName('ui-select', visualSize === 'sm' && 'ui-select--sm', visualSize === 'lg' && 'ui-select--lg', className), defaultValue: defaultValue ?? placeholderDefaultValue, ref: ref, value: value, ...props, children: [placeholder && (_jsx("option", { disabled: true, value: "", children: placeholder })), children, options.map(normalizeOption).map(option => (_jsx("option", { disabled: option.disabled, value: option.value, children: option.label }, option.value)))] }));
|
|
880
|
-
};
|
|
881
|
-
const phoneInputSizeModifiers = (size) => {
|
|
882
|
-
if (size === 'sm') {
|
|
883
|
-
return { inputClass: 'ui-input--sm', selectClass: 'ui-select--sm' };
|
|
884
|
-
}
|
|
885
|
-
if (size === 'lg') {
|
|
886
|
-
return { inputClass: 'ui-input--lg', selectClass: 'ui-select--lg' };
|
|
887
|
-
}
|
|
888
|
-
return { inputClass: undefined, selectClass: undefined };
|
|
889
|
-
};
|
|
890
|
-
const getPhoneInputOptions = (locale) => locale === undefined ? {} : { locale };
|
|
891
|
-
const getBooleanAttribute = (value) => value ? true : undefined;
|
|
892
|
-
const getPhoneErrorId = (invalid, name) => (invalid ? `${name}-error` : undefined);
|
|
893
|
-
const PhoneInputError = ({ invalid, message, name }) => invalid ?
|
|
894
|
-
(_jsx("span", { className: "ui-visually-hidden", id: `${name}-error`, role: "alert", children: message })) :
|
|
895
|
-
null;
|
|
896
|
-
const MetadataPhoneInput = ({ className, countryOptions, countryLabel, countryName, defaultCountryValue, defaultValue, invalidNumberMessage, locale, name, onValueChange, placeholder, showValidationError, size, value, ...props }) => {
|
|
897
|
-
const { selectClass, inputClass } = phoneInputSizeModifiers(size);
|
|
898
|
-
const phoneOptions = useMemo(() => getPhoneInputOptions(locale), [locale]);
|
|
899
|
-
const metadataCountries = useMemo(() => countryOptions ?? getLumenPhoneCountries(phoneOptions), [countryOptions, phoneOptions]);
|
|
900
|
-
const initialCountry = useMemo(() => resolveReactPhoneInputCountry(metadataCountries, defaultCountryValue, locale, value), [defaultCountryValue, locale, metadataCountries, value]);
|
|
901
|
-
const [internalValue, setInternalValue] = useState(() => (defaultValue ?
|
|
902
|
-
resolveReactPhoneInputValue(metadataCountries, initialCountry, defaultValue, phoneOptions) :
|
|
903
|
-
{ country: initialCountry, e164: null, isValid: false, nationalNumber: '' }));
|
|
904
|
-
const phoneValue = value === undefined || value.country.regionCode === initialCountry.regionCode ?
|
|
905
|
-
value ?? internalValue :
|
|
906
|
-
resolveReactPhoneInputValue(metadataCountries, initialCountry, value.nationalNumber, phoneOptions);
|
|
907
|
-
const resolvedOptions = metadataCountries.map(country => ({
|
|
908
|
-
disabled: false,
|
|
909
|
-
label: country.pickerLabel,
|
|
910
|
-
value: country.regionCode
|
|
911
|
-
}));
|
|
912
|
-
const commitValue = (nextValue) => {
|
|
913
|
-
if (value === undefined)
|
|
914
|
-
setInternalValue(nextValue);
|
|
915
|
-
onValueChange?.(nextValue);
|
|
916
|
-
};
|
|
917
|
-
const handleCountryChange = (event) => {
|
|
918
|
-
const selectedCountry = metadataCountries.find(country => (country.regionCode === event.currentTarget.value ||
|
|
919
|
-
country.callingCode === event.currentTarget.value));
|
|
920
|
-
if (selectedCountry) {
|
|
921
|
-
commitValue(resolveLumenPhoneNumber(selectedCountry, phoneValue.nationalNumber, phoneOptions));
|
|
922
|
-
}
|
|
923
|
-
};
|
|
924
|
-
const handleNumberChange = (event) => {
|
|
925
|
-
commitValue(resolveReactPhoneInputValue(metadataCountries, phoneValue.country, event.currentTarget.value, phoneOptions));
|
|
926
|
-
};
|
|
927
|
-
const invalid = showValidationError && phoneValue.nationalNumber.length > 0 && !phoneValue.isValid;
|
|
928
|
-
return (_jsxs("div", { className: composeClassName('ui-phone-input ui-input-group', className), "data-invalid": getBooleanAttribute(invalid), ...props, children: [_jsx("select", { "aria-label": countryLabel, className: composeClassName('ui-select ui-phone-input__country', selectClass), name: countryName, onChange: handleCountryChange, value: phoneValue.country.regionCode, children: resolvedOptions.map(option => (_jsx("option", { disabled: option.disabled, value: option.value, children: option.label }, option.value))) }), _jsx("input", { autoComplete: "tel", "aria-errormessage": getPhoneErrorId(invalid, name), "aria-invalid": getBooleanAttribute(invalid), className: composeClassName('ui-input ui-phone-input__number', inputClass), inputMode: "tel", name: name, onChange: handleNumberChange, placeholder: placeholder, type: "tel", value: phoneValue.nationalNumber }), _jsx(PhoneInputError, { invalid: invalid, message: invalidNumberMessage, name: name })] }));
|
|
929
|
-
};
|
|
930
|
-
const LegacyPhoneInput = ({ className, countries, countryOptions: _countryOptions, countryLabel = 'Country code', countryName = 'country', defaultCountryValue, defaultValue, invalidNumberMessage: _invalidNumberMessage, locale: _locale, name = 'phone', onValueChange: _onValueChange, placeholder = 'Phone number', showValidationError: _showValidationError, size = 'default', value: _value, ...props }) => {
|
|
931
|
-
const { inputClass, selectClass } = phoneInputSizeModifiers(size);
|
|
932
|
-
return (_jsxs("div", { className: composeClassName('ui-phone-input ui-input-group', className), ...props, children: [_jsx("select", { "aria-label": countryLabel, className: composeClassName('ui-select ui-phone-input__country', selectClass), defaultValue: defaultCountryValue, name: countryName, children: countries.map(normalizeOption).map(option => (_jsx("option", { disabled: option.disabled, value: option.value, children: option.label }, option.value))) }), _jsx("input", { autoComplete: "tel", className: composeClassName('ui-input ui-phone-input__number', inputClass), defaultValue: defaultValue, inputMode: "tel", name: name, placeholder: placeholder, type: "tel" })] }));
|
|
933
|
-
};
|
|
934
|
-
export const PhoneInput = (props) => {
|
|
935
|
-
if (props.countries) {
|
|
936
|
-
return _jsx(LegacyPhoneInput, { ...props, countries: props.countries });
|
|
937
|
-
}
|
|
938
|
-
return (_jsx(MetadataPhoneInput, { ...props, countryLabel: props.countryLabel ?? 'Country code', countryName: props.countryName ?? 'country', defaultCountryValue: props.defaultCountryValue ?? 'US', invalidNumberMessage: props.invalidNumberMessage ?? 'Enter a complete phone number.', name: props.name ?? 'phone', placeholder: props.placeholder ?? 'Phone number', showValidationError: props.showValidationError ?? true, size: props.size ?? 'default' }));
|
|
939
|
-
};
|
|
940
|
-
export const NavigationMenu = ({ className, glass = false, variant = 'default', ...props }) => (_jsx("nav", { className: composeClassName('ui-navigation-menu', variant === 'unstyled' && 'ui-navigation-menu--unstyled', glassSurfaceClass('ui-navigation-menu', glass), className), "data-slot": "navigation-menu", "data-surface": resolveSurface(glass), "data-ui-navigation-menu": true, "data-variant": variant, ...props }));
|
|
941
|
-
export const ContextNavigation = ({ children, className, context, variant = 'default', ...props }) => (_jsxs("div", { className: composeClassName('ui-context-navigation', variant === 'unstyled' && 'ui-context-navigation--unstyled', className), "data-slot": "context-navigation", "data-variant": variant, ...props, children: [context && (_jsx("div", { className: "ui-context-navigation__context", "data-slot": "context-navigation-context", children: context })), children] }));
|
|
942
|
-
export const Pagination = ({ 'aria-label': ariaLabel = 'Pagination', className, ...props }) => (_jsx("nav", { "aria-label": ariaLabel, className: composeClassName('ui-pagination', className), ...props }));
|
|
943
|
-
export const Popover = ({ children, className, defaultOpen, glass = false, onOpenChange, open, ...props }) => {
|
|
944
|
-
const popover = usePopover({ defaultOpen, onOpenChange, open });
|
|
945
|
-
return (_jsx(PopoverContext.Provider, { value: popover, children: _jsx("div", { ...popover.rootProps, ...props, className: composeClassName('ui-popover', glassSurfaceClass('ui-popover', glass), className), "data-surface": resolveSurface(glass), "data-ui-popover": true, children: children }) }));
|
|
946
|
-
};
|
|
947
|
-
export const PopoverTrigger = ({ onClick, onKeyDown, ...props }) => {
|
|
948
|
-
const popover = requireContext(useContext(PopoverContext), 'PopoverTrigger');
|
|
949
|
-
return (_jsx("button", { ...popover.triggerProps, ...props, onClick: composeHandlers(onClick, popover.triggerProps.onClick), onKeyDown: composeHandlers(onKeyDown, popover.triggerProps.onKeyDown), type: props.type ?? 'button' }));
|
|
950
|
-
};
|
|
951
|
-
export const PopoverPanel = ({ onKeyDown, ...props }) => {
|
|
952
|
-
const popover = requireContext(useContext(PopoverContext), 'PopoverPanel');
|
|
953
|
-
return (_jsx("div", { ...popover.panelProps, ...props, onKeyDown: composeHandlers(onKeyDown, popover.panelProps.onKeyDown) }));
|
|
954
|
-
};
|
|
955
|
-
export const RadioGroup = ({ className, ...props }) => (_jsx("fieldset", { className: composeClassName('ui-radio-group', className), "data-ui-radio-group": true, ...props }));
|
|
956
|
-
const renderResizablePane = (child, index, panelProps) => {
|
|
957
|
-
if (isValidElement(child)) {
|
|
958
|
-
const childProps = child.props;
|
|
959
|
-
return cloneElement(child, {
|
|
960
|
-
...panelProps,
|
|
961
|
-
className: composeClassName(childProps.className, panelProps.className),
|
|
962
|
-
style: {
|
|
963
|
-
...childProps.style,
|
|
964
|
-
...panelProps.style
|
|
965
|
-
}
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
return _jsx("div", { ...panelProps, children: child });
|
|
969
|
-
};
|
|
970
|
-
export const Resizable = ({ children, className, defaultSizes, direction = 'horizontal', maxSize, minSize, resetOnDoubleClick = true, ...props }) => {
|
|
971
|
-
const panes = Children.toArray(children);
|
|
972
|
-
const resizable = useResizable({
|
|
973
|
-
defaultSizes,
|
|
974
|
-
direction,
|
|
975
|
-
maxSize,
|
|
976
|
-
minSize,
|
|
977
|
-
panelCount: panes.length,
|
|
978
|
-
resetOnDoubleClick
|
|
979
|
-
});
|
|
980
|
-
return (_jsx("div", { ...props, ...resizable.rootProps, className: composeClassName(resizable.rootProps.className, className), children: panes.map((child, index) => (_jsxs(Fragment, { children: [renderResizablePane(child, index, resizable.getPanelProps(index)), index < panes.length - 1 && (_jsx("button", { ...resizable.getHandleProps(index), type: "button" }))] }, index))) }));
|
|
981
|
-
};
|
|
982
|
-
export const RichTextEditor = ({ className, glass = false, ...props }) => (_jsx("section", { className: composeClassName('ui-rich-text-editor', glassClass('ui-rich-text-editor', glass), className), "data-ui-rich-text-editor": true, ...props }));
|
|
983
|
-
export const ScrollArea = ({ className, glass = false, ...props }) => (_jsx("div", { className: composeClassName('ui-scroll-area', glassClass('ui-scroll-area', glass), className), ...props }));
|
|
984
|
-
export const ScrollProgress = ({ 'aria-label': ariaLabel = 'Reading progress', className, position = 'top', ...props }) => {
|
|
985
|
-
const rootRef = useRef(null);
|
|
986
|
-
useEffect(() => {
|
|
987
|
-
const root = rootRef.current;
|
|
988
|
-
if (!root)
|
|
989
|
-
return;
|
|
990
|
-
let frame = 0;
|
|
991
|
-
const update = () => {
|
|
992
|
-
frame = 0;
|
|
993
|
-
const scrollingElement = document.scrollingElement ?? document.documentElement;
|
|
994
|
-
const maximum = scrollingElement.scrollHeight - scrollingElement.clientHeight;
|
|
995
|
-
const percentage = maximum > 0 ?
|
|
996
|
-
Math.min(100, Math.max(0, (scrollingElement.scrollTop / maximum) * 100)) :
|
|
997
|
-
0;
|
|
998
|
-
const bar = root.querySelector('.ui-scroll-progress__bar');
|
|
999
|
-
root.setAttribute('aria-valuenow', `${Math.round(percentage)}`);
|
|
1000
|
-
if (bar)
|
|
1001
|
-
bar.style.transform = `scaleX(${percentage / 100})`;
|
|
1002
|
-
};
|
|
1003
|
-
const scheduleUpdate = () => {
|
|
1004
|
-
if (frame)
|
|
1005
|
-
return;
|
|
1006
|
-
frame = window.requestAnimationFrame(update);
|
|
1007
|
-
};
|
|
1008
|
-
scheduleUpdate();
|
|
1009
|
-
window.addEventListener('resize', scheduleUpdate, { passive: true });
|
|
1010
|
-
window.addEventListener('scroll', scheduleUpdate, { passive: true });
|
|
1011
|
-
return () => {
|
|
1012
|
-
if (frame)
|
|
1013
|
-
window.cancelAnimationFrame(frame);
|
|
1014
|
-
window.removeEventListener('resize', scheduleUpdate);
|
|
1015
|
-
window.removeEventListener('scroll', scheduleUpdate);
|
|
1016
|
-
};
|
|
1017
|
-
}, []);
|
|
1018
|
-
return (_jsx("div", { "aria-label": ariaLabel, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": 0, className: composeClassName('ui-scroll-progress', position === 'bottom' && 'ui-scroll-progress--bottom', className), "data-position": position, "data-ui-scroll-progress": true, ref: rootRef, role: "progressbar", ...props, children: _jsx("span", { className: "ui-scroll-progress__bar" }) }));
|
|
1019
|
-
};
|
|
1020
|
-
export const Schedule = ({ className, glass = false, ...props }) => (_jsx("section", { className: composeClassName('ui-schedule', glassClass('ui-schedule', glass), className), "data-ui-schedule": true, ...props }));
|
|
1021
|
-
export const SearchField = ({ className, ref, type = 'search', ...props }) => (_jsx("input", { className: composeClassName('ui-input ui-search-field', className), ref: ref, type: type, ...props }));
|
|
1022
|
-
const getSelectSizeClass = (size) => {
|
|
1023
|
-
if (size === 'sm')
|
|
1024
|
-
return 'ui-select--sm';
|
|
1025
|
-
if (size === 'lg')
|
|
1026
|
-
return 'ui-select--lg';
|
|
1027
|
-
return false;
|
|
1028
|
-
};
|
|
1029
|
-
export const Select = ({ children, className, defaultValue, disabled = false, glass = false, id, inputRef, name, onChange, onValueChange, options = emptyOptions, placeholder, required = false, size = 'default', value, ...props }) => {
|
|
1030
|
-
const select = useSelect({
|
|
1031
|
-
defaultValue,
|
|
1032
|
-
disabled,
|
|
1033
|
-
id,
|
|
1034
|
-
name,
|
|
1035
|
-
onValueChange,
|
|
1036
|
-
options,
|
|
1037
|
-
placeholder,
|
|
1038
|
-
required,
|
|
1039
|
-
value
|
|
1040
|
-
});
|
|
1041
|
-
const sizeClass = getSelectSizeClass(size);
|
|
1042
|
-
return (_jsxs("div", { ...select.rootProps, className: composeClassName('ui-select-field', glassClass('ui-select-field', glass), className), "data-ui-glass-track": glass ? true : undefined, children: [_jsxs("select", { ...select.nativeSelectProps, ...props, className: composeClassName('ui-select ui-select__native', sizeClass), onChange: composeHandlers(onChange, select.nativeSelectProps.onChange), ref: inputRef, children: [placeholder && (_jsx("option", { "data-ui-select-placeholder": true, disabled: true, value: "", children: placeholder })), children, select.options.map(option => (_jsx("option", { disabled: option.disabled, value: option.value, children: option.label }, option.value)))] }), _jsxs("div", { ...select.controlProps, className: "ui-select__control", children: [_jsx("button", { ...select.triggerProps, className: composeClassName('ui-select ui-select__trigger', sizeClass), type: select.triggerProps.type ?? 'button', children: _jsx("span", { "data-ui-select-value": true, children: select.triggerText }) }), _jsx("div", { ...select.listProps, className: "ui-select__list", children: select.options.map(option => {
|
|
1043
|
-
const optionProps = select.getOptionProps(option);
|
|
1044
|
-
return (_jsx("button", { ...optionProps, type: optionProps.type ?? 'button', children: option.label }, option.value));
|
|
1045
|
-
}) })] })] }));
|
|
1046
|
-
};
|
|
1047
|
-
const groupListBoxOptions = (options) => {
|
|
1048
|
-
const groups = [];
|
|
1049
|
-
options.forEach((option, index) => {
|
|
1050
|
-
const currentGroup = groups.at(-1);
|
|
1051
|
-
if (!currentGroup || currentGroup.label !== option.section) {
|
|
1052
|
-
groups.push({
|
|
1053
|
-
...(option.section ? { label: option.section } : {}),
|
|
1054
|
-
options: [{ ...option, index }]
|
|
1055
|
-
});
|
|
1056
|
-
return;
|
|
1057
|
-
}
|
|
1058
|
-
currentGroup.options.push({ ...option, index });
|
|
1059
|
-
});
|
|
1060
|
-
return groups;
|
|
1061
|
-
};
|
|
1062
|
-
const getListBoxGroupKey = (group) => {
|
|
1063
|
-
const values = group.options.map(option => option.value).join('|');
|
|
1064
|
-
return group.label ? `${group.label}:${values}` : values;
|
|
1065
|
-
};
|
|
1066
|
-
const optionalTrue = (value) => value ? true : undefined;
|
|
1067
|
-
const ListBoxNativeOptions = ({ groups }) => groups.map(group => {
|
|
1068
|
-
const options = group.options.map(option => (_jsx("option", { disabled: option.disabled, value: option.value, children: option.label }, option.value)));
|
|
1069
|
-
return group.label ?
|
|
1070
|
-
(_jsx("optgroup", { label: group.label, children: options }, getListBoxGroupKey(group))) :
|
|
1071
|
-
(_jsx(Fragment, { children: options }, getListBoxGroupKey(group)));
|
|
1072
|
-
});
|
|
1073
|
-
const ListBoxVisibleOptions = ({ activeIndex, controlId, emptyMessage, groups, loading, onSelect, selectedValues }) => {
|
|
1074
|
-
if (loading)
|
|
1075
|
-
return null;
|
|
1076
|
-
if (!groups.length) {
|
|
1077
|
-
return (_jsx("div", { "aria-disabled": "true", className: "ui-list-box__empty", role: "option", children: emptyMessage }));
|
|
1078
|
-
}
|
|
1079
|
-
return groups.map(group => {
|
|
1080
|
-
const groupKey = getListBoxGroupKey(group);
|
|
1081
|
-
const safeGroupKey = groupKey.replaceAll(/[^a-zA-Z0-9_-]/g, '-');
|
|
1082
|
-
const groupLabelId = group.label ? `${controlId}-group-${safeGroupKey}` : undefined;
|
|
1083
|
-
const options = group.options.map(option => (_jsx("div", { "aria-disabled": option.disabled ? true : undefined, "aria-selected": selectedValues.has(option.value), className: composeClassName('ui-list-box__option', option.index === activeIndex && 'ui-list-box__option--active'), "data-active": option.index === activeIndex ? 'true' : undefined, "data-ui-list-box-option": true, "data-value": option.value, onClick: () => {
|
|
1084
|
-
onSelect(option.index);
|
|
1085
|
-
}, role: "option", children: option.label }, option.value)));
|
|
1086
|
-
if (!group.label)
|
|
1087
|
-
return _jsx(Fragment, { children: options }, groupKey);
|
|
1088
|
-
return (_jsxs("div", { "aria-labelledby": groupLabelId, role: "group", children: [_jsx("div", { className: "ui-list-box__section", id: groupLabelId, children: group.label }), options] }, groupKey));
|
|
1089
|
-
});
|
|
1090
|
-
};
|
|
1091
|
-
const normalizeListBoxValues = (value) => {
|
|
1092
|
-
if (value === undefined)
|
|
1093
|
-
return [];
|
|
1094
|
-
return Array.isArray(value) ? value : [value];
|
|
1095
|
-
};
|
|
1096
|
-
const findLastEnabledOptionIndex = (options) => {
|
|
1097
|
-
let lastEnabledIndex = -1;
|
|
1098
|
-
for (const [index, option] of options.entries()) {
|
|
1099
|
-
if (!option.disabled)
|
|
1100
|
-
lastEnabledIndex = index;
|
|
1101
|
-
}
|
|
1102
|
-
return lastEnabledIndex;
|
|
1103
|
-
};
|
|
1104
|
-
const getListBoxSelectedValues = (controlledValue, internalValues) => controlledValue === undefined ?
|
|
1105
|
-
internalValues :
|
|
1106
|
-
normalizeListBoxValues(controlledValue);
|
|
1107
|
-
const getListBoxSelectValue = (multiple, selectedValues) => (multiple ? selectedValues : (selectedValues[0] ?? ''));
|
|
1108
|
-
const ListBoxLabel = ({ controlId, label }) => label ?
|
|
1109
|
-
(_jsx("label", { className: "ui-label", htmlFor: controlId, children: label })) :
|
|
1110
|
-
null;
|
|
1111
|
-
const normalizeListBoxProps = ({ disabled = false, emptyMessage = 'No options available', loading = false, loadingMessage = 'Loading options', multiple = false, options = emptyOptions, required = false, selectionFollowsFocus = false, ...props }) => ({
|
|
1112
|
-
disabled,
|
|
1113
|
-
emptyMessage,
|
|
1114
|
-
loading,
|
|
1115
|
-
loadingMessage,
|
|
1116
|
-
multiple,
|
|
1117
|
-
options,
|
|
1118
|
-
required,
|
|
1119
|
-
selectionFollowsFocus,
|
|
1120
|
-
...props
|
|
1121
|
-
});
|
|
1122
|
-
export const ListBox = (inputProps) => {
|
|
1123
|
-
const { className, defaultValue, disabled, emptyMessage, id, label, loading, loadingMessage, multiple, name, onValueChange, options, ref, required, selectionFollowsFocus, value, ...props } = normalizeListBoxProps(inputProps);
|
|
1124
|
-
const generatedId = useId();
|
|
1125
|
-
const controlId = id ?? `ui-list-box-${generatedId}`;
|
|
1126
|
-
const normalizedOptions = options.map(option => typeof option === 'string' ? { label: option, value: option } : option);
|
|
1127
|
-
const optionGroups = groupListBoxOptions(normalizedOptions);
|
|
1128
|
-
const [internalValues, setInternalValues] = useState(() => normalizeListBoxValues(defaultValue));
|
|
1129
|
-
const selectedValues = getListBoxSelectedValues(value, internalValues);
|
|
1130
|
-
const selectedSet = new Set(selectedValues);
|
|
1131
|
-
const firstEnabledIndex = Math.max(0, normalizedOptions.findIndex(option => !option.disabled));
|
|
1132
|
-
const [activeIndex, setActiveIndex] = useState(firstEnabledIndex);
|
|
1133
|
-
const selectRef = useRef(null);
|
|
1134
|
-
const typeaheadRef = useRef('');
|
|
1135
|
-
const typeaheadTimerRef = useRef(undefined);
|
|
1136
|
-
const commitValues = (nextValues) => {
|
|
1137
|
-
if (value === undefined) {
|
|
1138
|
-
setInternalValues(nextValues);
|
|
1139
|
-
}
|
|
1140
|
-
onValueChange?.(nextValues);
|
|
1141
|
-
const select = selectRef.current;
|
|
1142
|
-
if (!select)
|
|
1143
|
-
return;
|
|
1144
|
-
for (const option of select.options) {
|
|
1145
|
-
option.selected = nextValues.includes(option.value);
|
|
1146
|
-
}
|
|
1147
|
-
select.dispatchEvent(new Event('input', { bubbles: true }));
|
|
1148
|
-
select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
1149
|
-
};
|
|
1150
|
-
const selectOption = (index) => {
|
|
1151
|
-
const option = normalizedOptions[index];
|
|
1152
|
-
if (!option || option.disabled || disabled || loading)
|
|
1153
|
-
return;
|
|
1154
|
-
const optionValue = option.value;
|
|
1155
|
-
let nextValues;
|
|
1156
|
-
if (!multiple) {
|
|
1157
|
-
nextValues = [optionValue];
|
|
1158
|
-
}
|
|
1159
|
-
else if (selectedSet.has(optionValue)) {
|
|
1160
|
-
nextValues = selectedValues.filter(selectedValue => selectedValue !== optionValue);
|
|
1161
|
-
}
|
|
1162
|
-
else {
|
|
1163
|
-
nextValues = [...selectedValues, optionValue];
|
|
1164
|
-
}
|
|
1165
|
-
commitValues(nextValues);
|
|
1166
|
-
};
|
|
1167
|
-
const moveActive = (direction) => {
|
|
1168
|
-
if (!normalizedOptions.length || loading)
|
|
1169
|
-
return;
|
|
1170
|
-
let nextIndex = activeIndex;
|
|
1171
|
-
for (const _option of normalizedOptions) {
|
|
1172
|
-
nextIndex =
|
|
1173
|
-
(nextIndex + direction + normalizedOptions.length) %
|
|
1174
|
-
normalizedOptions.length;
|
|
1175
|
-
if (!normalizedOptions[nextIndex]?.disabled) {
|
|
1176
|
-
setActiveIndex(nextIndex);
|
|
1177
|
-
if (selectionFollowsFocus)
|
|
1178
|
-
selectOption(nextIndex);
|
|
1179
|
-
return;
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
};
|
|
1183
|
-
useEffect(() => () => {
|
|
1184
|
-
if (typeaheadTimerRef.current)
|
|
1185
|
-
clearTimeout(typeaheadTimerRef.current);
|
|
1186
|
-
}, []);
|
|
1187
|
-
useEffect(() => {
|
|
1188
|
-
const select = selectRef.current;
|
|
1189
|
-
const form = select?.form;
|
|
1190
|
-
if (!form || value !== undefined)
|
|
1191
|
-
return;
|
|
1192
|
-
const handleReset = () => {
|
|
1193
|
-
setInternalValues(normalizeListBoxValues(defaultValue));
|
|
1194
|
-
setActiveIndex(firstEnabledIndex);
|
|
1195
|
-
};
|
|
1196
|
-
form.addEventListener('reset', handleReset);
|
|
1197
|
-
return () => {
|
|
1198
|
-
form.removeEventListener('reset', handleReset);
|
|
1199
|
-
};
|
|
1200
|
-
}, [defaultValue, firstEnabledIndex, value]);
|
|
1201
|
-
const handleNavigationKey = (key) => {
|
|
1202
|
-
if (key === 'ArrowDown')
|
|
1203
|
-
moveActive(1);
|
|
1204
|
-
else if (key === 'ArrowUp')
|
|
1205
|
-
moveActive(-1);
|
|
1206
|
-
else if (key === 'Home') {
|
|
1207
|
-
setActiveIndex(firstEnabledIndex);
|
|
1208
|
-
if (selectionFollowsFocus)
|
|
1209
|
-
selectOption(firstEnabledIndex);
|
|
1210
|
-
}
|
|
1211
|
-
else if (key === 'End') {
|
|
1212
|
-
const lastEnabledIndex = findLastEnabledOptionIndex(normalizedOptions);
|
|
1213
|
-
if (lastEnabledIndex >= 0) {
|
|
1214
|
-
setActiveIndex(lastEnabledIndex);
|
|
1215
|
-
if (selectionFollowsFocus)
|
|
1216
|
-
selectOption(lastEnabledIndex);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
else if (key === 'Enter' || key === ' ')
|
|
1220
|
-
selectOption(activeIndex);
|
|
1221
|
-
else
|
|
1222
|
-
return false;
|
|
1223
|
-
return true;
|
|
1224
|
-
};
|
|
1225
|
-
const handleTypeaheadKey = (event) => {
|
|
1226
|
-
if (event.key.length !== 1 ||
|
|
1227
|
-
event.ctrlKey ||
|
|
1228
|
-
event.metaKey ||
|
|
1229
|
-
event.altKey)
|
|
1230
|
-
return false;
|
|
1231
|
-
typeaheadRef.current += event.key.toLowerCase();
|
|
1232
|
-
if (typeaheadTimerRef.current)
|
|
1233
|
-
clearTimeout(typeaheadTimerRef.current);
|
|
1234
|
-
typeaheadTimerRef.current = setTimeout(() => {
|
|
1235
|
-
typeaheadRef.current = '';
|
|
1236
|
-
}, 700);
|
|
1237
|
-
const nextIndex = normalizedOptions.findIndex(option => !option.disabled &&
|
|
1238
|
-
option.label.toLowerCase().startsWith(typeaheadRef.current));
|
|
1239
|
-
if (nextIndex >= 0) {
|
|
1240
|
-
setActiveIndex(nextIndex);
|
|
1241
|
-
if (selectionFollowsFocus)
|
|
1242
|
-
selectOption(nextIndex);
|
|
1243
|
-
}
|
|
1244
|
-
return true;
|
|
1245
|
-
};
|
|
1246
|
-
const handleListKeyDown = (event) => {
|
|
1247
|
-
if (handleNavigationKey(event.key) || handleTypeaheadKey(event))
|
|
1248
|
-
event.preventDefault();
|
|
1249
|
-
};
|
|
1250
|
-
return (_jsxs("div", { className: composeClassName('ui-list-box', className), "data-multiple": multiple ? 'true' : undefined, "data-ui-list-box": true, children: [_jsx(ListBoxLabel, { controlId: controlId, label: label }), _jsx("select", { ...props, className: "ui-list-box__native", "data-ui-enhanced": true, "data-ui-list-box-native": true, disabled: disabled || loading, id: controlId, multiple: multiple, name: name, ref: node => {
|
|
1251
|
-
selectRef.current = node;
|
|
1252
|
-
setRefValue(ref, node);
|
|
1253
|
-
}, required: required, value: getListBoxSelectValue(multiple, selectedValues), children: _jsx(ListBoxNativeOptions, { groups: optionGroups }) }), _jsx("div", { "aria-busy": optionalTrue(loading), "aria-disabled": optionalTrue(disabled || loading), "aria-multiselectable": optionalTrue(multiple), className: "ui-list-box__list", "data-ui-list-box-list": true, onKeyDown: handleListKeyDown, role: "listbox", tabIndex: disabled || loading ? undefined : 0, children: _jsx(ListBoxVisibleOptions, { activeIndex: activeIndex, controlId: controlId, emptyMessage: emptyMessage, groups: optionGroups, loading: loading, onSelect: index => {
|
|
1254
|
-
setActiveIndex(index);
|
|
1255
|
-
selectOption(index);
|
|
1256
|
-
}, selectedValues: selectedSet }) }), loading ?
|
|
1257
|
-
(_jsx("p", { className: "ui-list-box__status", role: "status", children: loadingMessage })) :
|
|
1258
|
-
null] }));
|
|
1259
|
-
};
|
|
1260
|
-
export const Sheet = ({ className, glass = false, ...props }) => (_jsx("dialog", { className: composeClassName('ui-sheet', glassSurfaceClass('ui-sheet', glass), className), "data-surface": resolveSurface(glass), "data-ui-sheet": true, ...props }));
|
|
1261
|
-
export const Sidebar = ({ className, glass = false, variant = 'default', ...props }) => (_jsx("aside", { className: composeClassName('ui-sidebar', variant === 'unstyled' && 'ui-sidebar--unstyled', glassSurfaceClass('ui-sidebar', glass), className), "data-slot": "sidebar", "data-surface": resolveSurface(glass), "data-variant": variant, ...props }));
|
|
1262
|
-
export const Slider = ({ className, ref, type = 'range', ...props }) => (_jsx("input", { className: composeClassName('ui-slider', className), ref: ref, type: type, ...props }));
|
|
1263
|
-
export const ToastViewport = ({ 'aria-atomic': ariaAtomic = 'false', 'aria-label': ariaLabel = 'Notifications', 'aria-live': ariaLive = 'polite', className, maxCount = 3, placement = 'bottom-right', ...props }) => (_jsx("div", { "aria-atomic": ariaAtomic, "aria-label": ariaLabel, "aria-live": ariaLive, className: composeClassName('ui-tvp', className), "data-placement": placement, "data-ui-toast-viewport": true, "data-ui-toast-max": maxCount, ...props }));
|
|
1264
|
-
export const Switch = ({ className, ref, role = 'switch', ...props }) => (_jsx("input", { className: composeClassName('ui-switch', className), ref: ref, role: role, type: "checkbox", ...props }));
|
|
1265
|
-
export const Table = ({ className, glass = false, layout = 'scroll', ...props }) => (_jsx("div", { className: composeClassName('ui-table-wrap', glassClass('ui-table-wrap', glass), layout === 'records' && 'ui-table-wrap--records', className), "data-slot": "table", ...props }));
|
|
1266
|
-
export const Tabs = ({ children, className, defaultValue, glass = false, onValueChange, orientation, value, ...props }) => {
|
|
1267
|
-
const tabs = useTabs({ defaultValue, onValueChange, orientation, value });
|
|
1268
|
-
return (_jsx(TabsContext.Provider, { value: tabs, children: _jsx("div", { ...tabs.rootProps, ...props, className: composeClassName('ui-tabs', glassClass('ui-tabs', glass), className), children: children }) }));
|
|
1269
|
-
};
|
|
1270
|
-
export const TabsList = ({ ...props }) => {
|
|
1271
|
-
const tabs = requireContext(useContext(TabsContext), 'TabsList');
|
|
1272
|
-
return _jsx("div", { ...tabs.listProps, ...props });
|
|
1273
|
-
};
|
|
1274
|
-
export const TabsTrigger = ({ onClick, onKeyDown, value, ...props }) => {
|
|
1275
|
-
const tabs = requireContext(useContext(TabsContext), 'TabsTrigger');
|
|
1276
|
-
return (_jsx("button", { ...tabs.getTriggerProps(value, props), onClick: composeHandlers(onClick, tabs.getTriggerProps(value).onClick), onKeyDown: composeHandlers(onKeyDown, tabs.getTriggerProps(value).onKeyDown), type: props.type ?? 'button' }));
|
|
1277
|
-
};
|
|
1278
|
-
export const TabsPanel = ({ value, ...props }) => {
|
|
1279
|
-
const tabs = requireContext(useContext(TabsContext), 'TabsPanel');
|
|
1280
|
-
return _jsx("div", { ...tabs.getPanelProps(value, props) });
|
|
1281
|
-
};
|
|
1282
|
-
const emptyCodeTabItems = [];
|
|
1283
|
-
export const CodeTabs = ({ ariaLabel = 'Code examples', className, copy = true, initialValue, items = emptyCodeTabItems, storageKey, theme = 'auto', wrap = true, ...props }) => {
|
|
1284
|
-
const selectedValue = initialValue ?? items[0]?.value;
|
|
1285
|
-
const [value, setValue] = useState(() => {
|
|
1286
|
-
let storedValue = null;
|
|
1287
|
-
if (storageKey && typeof localStorage !== 'undefined') {
|
|
1288
|
-
try {
|
|
1289
|
-
storedValue = localStorage.getItem(storageKey);
|
|
1290
|
-
}
|
|
1291
|
-
catch {
|
|
1292
|
-
// Storage can be unavailable in privacy modes; tab selection should still work.
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
return storedValue && items.some(item => item.value === storedValue) ?
|
|
1296
|
-
storedValue :
|
|
1297
|
-
(selectedValue ?? '');
|
|
1298
|
-
});
|
|
1299
|
-
useEffect(() => {
|
|
1300
|
-
const synchronize = (event) => {
|
|
1301
|
-
const detail = event.detail;
|
|
1302
|
-
if (storageKey &&
|
|
1303
|
-
detail.storageKey === storageKey &&
|
|
1304
|
-
detail.value &&
|
|
1305
|
-
items.some(item => item.value === detail.value)) {
|
|
1306
|
-
setValue(detail.value);
|
|
1307
|
-
}
|
|
1308
|
-
};
|
|
1309
|
-
document.addEventListener('ui:tabs-change', synchronize);
|
|
1310
|
-
return () => {
|
|
1311
|
-
document.removeEventListener('ui:tabs-change', synchronize);
|
|
1312
|
-
};
|
|
1313
|
-
}, [items, storageKey]);
|
|
1314
|
-
const selectValue = (nextValue) => {
|
|
1315
|
-
setValue(nextValue);
|
|
1316
|
-
if (storageKey) {
|
|
1317
|
-
try {
|
|
1318
|
-
localStorage.setItem(storageKey, nextValue);
|
|
1319
|
-
}
|
|
1320
|
-
catch {
|
|
1321
|
-
// Storage can be unavailable in privacy modes; tab selection should still work.
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
document.dispatchEvent(new CustomEvent('ui:tabs-change', {
|
|
1325
|
-
detail: { storageKey, value: nextValue }
|
|
1326
|
-
}));
|
|
1327
|
-
};
|
|
1328
|
-
return (_jsxs(Tabs, { className: composeClassName('ui-code-tabs', className), "data-slot": "code-tabs", "data-storage-key": storageKey, onValueChange: selectValue, value: value, ...props, children: [_jsx(TabsList, { "aria-label": ariaLabel, className: "ui-code-tabs__list", children: items.map(item => (_jsx(TabsTrigger, { className: "ui-code-tabs__tab", value: item.value, children: item.label }, item.value))) }), items.map(item => (_jsx(TabsPanel, { className: "ui-code-tabs__panel", value: item.value, children: _jsx(Code, { code: item.code, copy: copy, ...(item.language === undefined ?
|
|
1329
|
-
{} :
|
|
1330
|
-
{ language: item.language }), theme: theme, variant: "block", wrap: wrap }) }, item.value)))] }));
|
|
1331
|
-
};
|
|
1332
|
-
export const TagGroup = ({ className, role = 'list', ...props }) => (_jsx("div", { className: composeClassName('ui-tag-group', className), role: role, ...props }));
|
|
1333
|
-
export const ThemeBuilder = ({ className, glass = false, ...props }) => (_jsx("section", { className: composeClassName('ui-theme-builder', glassClass('ui-theme-builder', glass), className), "data-ui-theme-builder": true, ...props }));
|
|
1334
|
-
export const TimeField = ({ className, ref, type = 'time', ...props }) => (_jsx("input", { className: composeClassName('ui-input ui-time-field', className), ref: ref, type: type, ...props }));
|
|
1335
|
-
export const Toast = ({ 'aria-live': ariaLive, className, glass = false, role, variant = 'default', ...props }) => (_jsx("aside", { "aria-live": ariaLive ?? (variant === 'destructive' ? 'assertive' : 'polite'), className: composeClassName('ui-toast', variantClass('ui-toast', variant), glassSurfaceClass('ui-toast', glass), className), "data-surface": resolveSurface(glass), "data-ui-toast": true, "data-variant": variant, role: role ?? (variant === 'destructive' ? 'alert' : 'status'), ...props }));
|
|
1336
|
-
export const Toggle = ({ className, controlled = false, pressed = false, type = 'button', ...props }) => (_jsx("button", { "aria-pressed": pressed, className: composeClassName('ui-toggle', className), "data-ui-controlled": controlled || undefined, "data-ui-toggle": true, type: type, ...props }));
|
|
1337
|
-
export const ToggleGroup = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-toggle-group', className), "data-ui-toggle-group": true, ...props }));
|
|
1338
|
-
export const Tooltip = ({ children, className, defaultOpen, delay, onKeyDown, onMouseEnter, onMouseLeave, onOpenChange, open, ...props }) => {
|
|
1339
|
-
const tooltip = useTooltip({ defaultOpen, delay, onOpenChange, open });
|
|
1340
|
-
return (_jsx(TooltipContext.Provider, { value: tooltip, children: _jsx("span", { ...tooltip.rootProps, ...props, className: composeClassName('ui-tooltip', className), onKeyDown: composeHandlers(onKeyDown, tooltip.rootProps.onKeyDown), onMouseEnter: composeHandlers(onMouseEnter, tooltip.rootProps.onMouseEnter), onMouseLeave: composeHandlers(onMouseLeave, tooltip.rootProps.onMouseLeave), children: children }) }));
|
|
1341
|
-
};
|
|
1342
|
-
export const TooltipContent = ({ ...props }) => {
|
|
1343
|
-
const tooltip = requireContext(useContext(TooltipContext), 'TooltipContent');
|
|
1344
|
-
return _jsx("span", { ...tooltip.tooltipProps, ...props });
|
|
1345
|
-
};
|
|
1346
|
-
export const Tree = ({ className, glass = false, role = 'tree', ...props }) => (_jsx("div", { className: composeClassName('ui-tree', glassClass('ui-tree', glass), className), role: role, ...props }));
|
|
1347
|
-
export const TreeGrid = ({ className, glass = false, role = 'treegrid', ...props }) => (_jsx("div", { className: composeClassName('ui-tree-grid', glassClass('ui-tree-grid', glass), className), role: role, ...props }));
|
|
1348
|
-
export const VirtualList = ({ className, glass = false, itemSize, overscan, ...props }) => (_jsx("div", { className: composeClassName('ui-virtual-list', glassClass('ui-virtual-list', glass), className), "data-ui-item-size": itemSize, "data-ui-overscan": overscan, "data-ui-virtual-list": true, ...props }));
|
|
1349
|
-
export const BackToTop = ({ className, type = 'button', ...props }) => (_jsx("button", { className: composeClassName('ui-back-to-top', className), type: type, ...props }));
|
|
1350
|
-
export const Callout = ({ className, ...props }) => (_jsx("aside", { className: composeClassName('ui-callout', className), ...props }));
|
|
1351
|
-
export const Eyebrow = ({ className, ...props }) => (_jsx("p", { className: composeClassName('ui-eyebrow', className), ...props }));
|
|
1352
|
-
export const FloatingBadge = ({ className, ...props }) => (_jsx("span", { className: composeClassName('ui-floating-badge', className), ...props }));
|
|
1353
|
-
export const FormattedDate = ({ className, ...props }) => (_jsx("time", { className: composeClassName('ui-formatted-date', className), ...props }));
|
|
1354
|
-
export const Image = ({ as, className, fit = 'cover', invertOnDark = false, loading, radius = 'lg', ...props }) => {
|
|
1355
|
-
const Component = as ?? 'img';
|
|
1356
|
-
const resolvedLoading = loading ?? (as ? undefined : 'lazy');
|
|
1357
|
-
return createElement(Component, {
|
|
1358
|
-
...props,
|
|
1359
|
-
className: composeClassName('ui-image', invertOnDark && 'ui-image--invert-dark', `ui-image--fit-${fit}`, `ui-image--radius-${radius}`, className),
|
|
1360
|
-
...(resolvedLoading ? { loading: resolvedLoading } : {})
|
|
1361
|
-
});
|
|
1362
|
-
};
|
|
1363
|
-
export const Link = ({ className, newTab = false, ref, rel, target, variant = 'default', ...props }) => (_jsx("a", { className: composeClassName('ui-link', variant === 'inherit' && 'ui-link--inherit', className), "data-slot": "link", "data-variant": variant, ref: ref, rel: newTab ?
|
|
1364
|
-
[
|
|
1365
|
-
...new Set(`${rel ?? ''} noopener noreferrer`.trim().split(/\s+/))
|
|
1366
|
-
].join(' ') :
|
|
1367
|
-
rel, target: newTab ? '_blank' : target, ...props }));
|
|
1368
|
-
export const Pill = ({ className, count, children, href, variant = 'neutral', ...props }) => {
|
|
1369
|
-
const content = (_jsxs(_Fragment, { children: [children, count !== undefined && _jsx("span", { className: "ui-pill__count", children: count })] }));
|
|
1370
|
-
return href ?
|
|
1371
|
-
(_jsx("a", { className: composeClassName('ui-pill', variantClass('ui-pill', variant, 'neutral'), className), "data-variant": variant, href: href, ...props, children: content })) :
|
|
1372
|
-
(_jsx("span", { className: composeClassName('ui-pill', variantClass('ui-pill', variant, 'neutral'), className), "data-variant": variant, ...props, children: content }));
|
|
1373
|
-
};
|
|
1374
|
-
export const Prose = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-prose', className), ...props }));
|
|
1375
|
-
export const SkipLink = ({ className, ...props }) => (_jsx("a", { className: composeClassName('ui-skip-link', className), ...props }));
|
|
1376
|
-
export const ThemeToggle = ({ className, type = 'button', ...props }) => (_jsxs("button", { className: composeClassName('ui-theme-toggle', className), "data-slot": "theme-toggle", type: type, ...props, children: [_jsx("span", { className: "ui-sr-only", children: "Toggle color theme" }), _jsx(Icon, { className: "ui-theme-toggle__sun", name: "sun" }), _jsx(Icon, { className: "ui-theme-toggle__moon", name: "moon" })] }));
|
|
1377
|
-
export const LanguageToggle = ({ children, className, defaultValue, labelTemplate = 'Change language from {current} to {next}', locales, onClick, onValueChange, storageKey, type = 'button', value, ...props }) => {
|
|
1378
|
-
const language = useLanguageToggle({
|
|
1379
|
-
defaultValue,
|
|
1380
|
-
locales,
|
|
1381
|
-
onValueChange,
|
|
1382
|
-
storageKey,
|
|
1383
|
-
value
|
|
1384
|
-
});
|
|
1385
|
-
const accessibleLabel = formatLumenLanguageLabel(labelTemplate, language.currentLocale, language.nextLocale);
|
|
1386
|
-
return (_jsx("button", { "aria-label": accessibleLabel, className: composeClassName('ui-language-toggle', className), "data-ui-language-next-value": language.nextLocale.value, "data-ui-language-toggle": true, "data-ui-language-value": language.value, onClick: event => {
|
|
1387
|
-
onClick?.(event);
|
|
1388
|
-
if (event.defaultPrevented)
|
|
1389
|
-
return;
|
|
1390
|
-
language.selectNext();
|
|
1391
|
-
event.currentTarget.dispatchEvent(new CustomEvent('ui:language-change', {
|
|
1392
|
-
bubbles: true,
|
|
1393
|
-
detail: {
|
|
1394
|
-
previousValue: language.currentLocale.value,
|
|
1395
|
-
value: language.nextLocale.value
|
|
1396
|
-
}
|
|
1397
|
-
}));
|
|
1398
|
-
}, type: type, ...props, children: children ?? (_jsx("span", { lang: language.nextLocale.value, children: language.nextLocale.label })) }));
|
|
1399
|
-
};
|
|
1400
|
-
const particleDensityConfig = { high: 40, low: 15, medium: 25 };
|
|
1401
|
-
const particleTones = [
|
|
1402
|
-
'var(--brand)',
|
|
1403
|
-
'var(--accent)',
|
|
1404
|
-
'var(--glow, var(--brand))'
|
|
1405
|
-
];
|
|
1406
|
-
const createParticles = (density) => Array.from({ length: particleDensityConfig[density] }, (_, index) => {
|
|
1407
|
-
const size = Math.random() * 12 + 8;
|
|
1408
|
-
const left = Math.random() * 100;
|
|
1409
|
-
const top = Math.random() * 100;
|
|
1410
|
-
return {
|
|
1411
|
-
id: `${index}-${left}-${top}`,
|
|
1412
|
-
style: {
|
|
1413
|
-
'--ui-particle-delay': `${Math.random() * 8}s`,
|
|
1414
|
-
'--ui-particle-duration': `${20 + Math.random() * 15}s`,
|
|
1415
|
-
'--ui-particle-left': `${left}%`,
|
|
1416
|
-
'--ui-particle-size': `${size}px`,
|
|
1417
|
-
'--ui-particle-tone': particleTones[Math.floor(Math.random() * particleTones.length)],
|
|
1418
|
-
'--ui-particle-top': `${top}%`
|
|
1419
|
-
}
|
|
1420
|
-
};
|
|
1421
|
-
});
|
|
1422
|
-
export const Particles = ({ children, className, density = 'medium', ...props }) => {
|
|
1423
|
-
const [particles, setParticles] = useState([]);
|
|
1424
|
-
useEffect(() => {
|
|
1425
|
-
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches)
|
|
1426
|
-
return;
|
|
1427
|
-
// Particle geometry is client-only to keep SSR output stable while retaining per-load variation.
|
|
1428
|
-
// eslint-disable-next-line @eslint-react/set-state-in-effect
|
|
1429
|
-
setParticles(createParticles(density));
|
|
1430
|
-
}, [density]);
|
|
1431
|
-
return (_jsxs("div", { "aria-hidden": "true", className: composeClassName('ui-particles', className), "data-ui-particles": density, ...props, children: [children, particles.map(particle => (_jsx("span", { className: "ui-particles__particle", style: particle.style }, particle.id)))] }));
|
|
1432
|
-
};
|
|
1433
|
-
const parseMotionDuration = (value) => {
|
|
1434
|
-
const parsedDuration = Number.parseFloat(value);
|
|
1435
|
-
if (!Number.isFinite(parsedDuration))
|
|
1436
|
-
return 300;
|
|
1437
|
-
return value.endsWith('ms') ? parsedDuration : parsedDuration * 1000;
|
|
1438
|
-
};
|
|
1439
|
-
export const ScrollReveal = ({ animation = 'fade', className, delay = 0, duration = 'slow', once = true, style, threshold = 0.15, ...props }) => {
|
|
1440
|
-
const rootRef = useRef(null);
|
|
1441
|
-
useEffect(() => {
|
|
1442
|
-
const root = rootRef.current;
|
|
1443
|
-
if (!root)
|
|
1444
|
-
return;
|
|
1445
|
-
root.dataset.uiScrollRevealBound = 'true';
|
|
1446
|
-
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches ||
|
|
1447
|
-
typeof IntersectionObserver === 'undefined') {
|
|
1448
|
-
root.classList.add('is-revealed');
|
|
1449
|
-
return;
|
|
1450
|
-
}
|
|
1451
|
-
const observer = new IntersectionObserver(([entry]) => {
|
|
1452
|
-
if (!entry)
|
|
1453
|
-
return;
|
|
1454
|
-
root.classList.toggle('is-revealed', entry.isIntersecting);
|
|
1455
|
-
if (entry.isIntersecting && once)
|
|
1456
|
-
observer.disconnect();
|
|
1457
|
-
}, { threshold: Math.min(1, Math.max(0, threshold)) });
|
|
1458
|
-
observer.observe(root);
|
|
1459
|
-
return () => {
|
|
1460
|
-
observer.disconnect();
|
|
1461
|
-
};
|
|
1462
|
-
}, [once, threshold]);
|
|
1463
|
-
return (_jsx("div", { className: composeClassName('ui-scroll-reveal', `ui-scroll-reveal-${animation}`, `ui-motion-duration-${duration}`, className), "data-ui-reveal-once": String(once), "data-ui-reveal-threshold": Math.min(1, Math.max(0, threshold)), "data-ui-scroll-reveal": true, ref: rootRef, style: {
|
|
1464
|
-
...style,
|
|
1465
|
-
'--ui-reveal-delay': `${Math.max(0, delay)}ms`
|
|
1466
|
-
}, ...props }));
|
|
1467
|
-
};
|
|
1468
|
-
export const RevealGroup = ({ animation = 'slide-up', className, delay = 0, duration = 'slow', once = true, stagger = 80, style, threshold = 0.15, ...props }) => {
|
|
1469
|
-
const rootRef = useRef(null);
|
|
1470
|
-
useEffect(() => {
|
|
1471
|
-
const root = rootRef.current;
|
|
1472
|
-
if (!root)
|
|
1473
|
-
return;
|
|
1474
|
-
root.dataset.uiScrollRevealBound = 'true';
|
|
1475
|
-
for (const [index, child] of [...root.children].entries()) {
|
|
1476
|
-
if (child instanceof HTMLElement) {
|
|
1477
|
-
child.style.setProperty('--ui-reveal-index', String(index));
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches ||
|
|
1481
|
-
typeof IntersectionObserver === 'undefined') {
|
|
1482
|
-
root.classList.add('is-revealed');
|
|
1483
|
-
return;
|
|
1484
|
-
}
|
|
1485
|
-
const observer = new IntersectionObserver(([entry]) => {
|
|
1486
|
-
if (!entry)
|
|
1487
|
-
return;
|
|
1488
|
-
root.classList.toggle('is-revealed', entry.isIntersecting);
|
|
1489
|
-
if (entry.isIntersecting && once)
|
|
1490
|
-
observer.disconnect();
|
|
1491
|
-
}, { threshold: Math.min(1, Math.max(0, threshold)) });
|
|
1492
|
-
observer.observe(root);
|
|
1493
|
-
return () => {
|
|
1494
|
-
observer.disconnect();
|
|
1495
|
-
};
|
|
1496
|
-
}, [once, threshold]);
|
|
1497
|
-
return (_jsx("div", { className: composeClassName('ui-reveal-group', `ui-reveal-group-${animation}`, `ui-motion-duration-${duration}`, className), "data-ui-reveal-group": true, "data-ui-reveal-once": String(once), "data-ui-reveal-threshold": Math.min(1, Math.max(0, threshold)), ref: rootRef, style: {
|
|
1498
|
-
...style,
|
|
1499
|
-
'--ui-reveal-delay': `${Math.max(0, delay)}ms`,
|
|
1500
|
-
'--ui-reveal-stagger': `${Math.max(0, stagger)}ms`
|
|
1501
|
-
}, ...props }));
|
|
1502
|
-
};
|
|
1503
|
-
export const AnimatedNumber = ({ className, decimals = 0, duration = 'slow', from = 0, locale, prefix = '', suffix = '', value, ...props }) => {
|
|
1504
|
-
const outputRef = useRef(null);
|
|
1505
|
-
const safeDecimals = Math.max(0, Math.min(20, Math.floor(decimals)));
|
|
1506
|
-
const formatter = useMemo(() => new Intl.NumberFormat(locale, {
|
|
1507
|
-
maximumFractionDigits: safeDecimals,
|
|
1508
|
-
minimumFractionDigits: safeDecimals
|
|
1509
|
-
}), [locale, safeDecimals]);
|
|
1510
|
-
const formattedValue = `${prefix}${formatter.format(value)}${suffix}`;
|
|
1511
|
-
useEffect(() => {
|
|
1512
|
-
const output = outputRef.current;
|
|
1513
|
-
if (!output)
|
|
1514
|
-
return;
|
|
1515
|
-
const format = (current) => `${prefix}${formatter.format(current)}${suffix}`;
|
|
1516
|
-
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches ||
|
|
1517
|
-
typeof IntersectionObserver === 'undefined') {
|
|
1518
|
-
output.textContent = format(value);
|
|
1519
|
-
return;
|
|
1520
|
-
}
|
|
1521
|
-
output.textContent = format(from);
|
|
1522
|
-
const root = output.parentElement;
|
|
1523
|
-
if (!root)
|
|
1524
|
-
return;
|
|
1525
|
-
const observer = new IntersectionObserver(entries => {
|
|
1526
|
-
if (!entries.some(entry => entry.isIntersecting))
|
|
1527
|
-
return;
|
|
1528
|
-
observer.disconnect();
|
|
1529
|
-
const durationValue = getComputedStyle(root)
|
|
1530
|
-
.getPropertyValue('--ui-motion-duration')
|
|
1531
|
-
.trim();
|
|
1532
|
-
const durationMs = parseMotionDuration(durationValue);
|
|
1533
|
-
const startedAt = performance.now();
|
|
1534
|
-
const update = (now) => {
|
|
1535
|
-
const progress = Math.min(1, (now - startedAt) / Math.max(1, durationMs));
|
|
1536
|
-
const eased = 1 - Math.pow(1 - progress, 3);
|
|
1537
|
-
output.textContent = format(from + (value - from) * eased);
|
|
1538
|
-
if (progress < 1) {
|
|
1539
|
-
requestAnimationFrame(update);
|
|
1540
|
-
}
|
|
1541
|
-
else {
|
|
1542
|
-
output.textContent = format(value);
|
|
1543
|
-
}
|
|
1544
|
-
};
|
|
1545
|
-
requestAnimationFrame(update);
|
|
1546
|
-
}, { threshold: 0.15 });
|
|
1547
|
-
observer.observe(root);
|
|
1548
|
-
return () => {
|
|
1549
|
-
observer.disconnect();
|
|
1550
|
-
};
|
|
1551
|
-
}, [formatter, from, prefix, suffix, value]);
|
|
1552
|
-
return (_jsxs("span", { className: composeClassName('ui-animated-number', `ui-motion-duration-${duration}`, className), "data-ui-animated-number": true, ...props, children: [_jsx("span", { "aria-hidden": "true", "data-ui-animated-number-output": true, ref: outputRef, children: formattedValue }), _jsx("span", { className: "ui-sr-only", children: formattedValue })] }));
|
|
1553
|
-
};
|
|
1554
|
-
export const Stat = ({ as, className, label, value, variant = 'default', children, ...props }) => (_jsxs(Primitive, { ...(as ? { as } : {}), className: composeClassName(variant !== 'default' && `ui-stat--${variant}`, className), "data-slot": "stat", "data-variant": variant, ...props, uiClassName: "ui-stat", children: [label && (_jsx("div", { className: "ui-stat-label", "data-slot": "stat-label", children: label })), value && (_jsx("div", { className: "ui-stat-value", "data-slot": "stat-value", children: value })), children] }));
|
|
1555
|
-
export const StatLabel = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "stat-label", ...props, uiClassName: "ui-stat-label" }));
|
|
1556
|
-
export const StatValue = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "stat-value", ...props, uiClassName: "ui-stat-value" }));
|
|
1557
|
-
export const StatDescription = ({ as, ...props }) => (_jsx(Primitive, { ...(as ? { as } : {}), "data-slot": "stat-description", ...props, uiClassName: "ui-stat-description" }));
|
|
1558
|
-
export const StatIcon = ({ className, ...props }) => (_jsx("span", { className: composeClassName('ui-stat-icon', className), "data-slot": "stat-icon", ...props }));
|
|
1559
|
-
export const StatTrend = ({ className, tone = 'neutral', ...props }) => (_jsx("span", { className: composeClassName('ui-stat-trend', `ui-stat-trend--${tone}`, className), "data-slot": "stat-trend", "data-tone": tone, ...props }));
|
|
1560
|
-
export const Meter = ({ className, ...props }) => (_jsx("meter", { className: composeClassName('ui-meter', className), ...props }));
|
|
1561
|
-
export const Note = ({ className, label, borderPosition = 'left', children, ...props }) => (_jsxs("div", { className: composeClassName('ui-note', `ui-note--border-${borderPosition}`, className), ...props, children: [label && _jsx("p", { className: "ui-note__label", children: label }), _jsx("div", { className: "ui-note__content", children: children })] }));
|
|
1562
|
-
export const Rating = ({ className, value = 0, max = 5, readonly = false, ...props }) => {
|
|
1563
|
-
const stars = Array.from({ length: max }, (_, i) => i + 1);
|
|
1564
|
-
return (_jsx("div", { className: composeClassName('ui-rating', readonly && 'ui-rating--readonly', className), "data-ui-rating": true, "data-value": value, "data-max": max, "data-readonly": readonly ? 'true' : 'false', ...props, children: stars.map(star => (_jsx("button", { type: "button", className: "ui-rating__star", "data-active": star <= value ? 'true' : 'false', disabled: readonly, "aria-label": `Rate ${star} out of ${max}`, children: _jsx("svg", { viewBox: "0 0 24 24", width: "24", height: "24", stroke: "currentColor", strokeWidth: "2", fill: "none", strokeLinecap: "round", strokeLinejoin: "round", className: "ui-icon", children: _jsx("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }) }) }, star))) }));
|
|
1565
|
-
};
|
|
1566
|
-
export const Timeline = ({ className, ...props }) => (_jsx("ol", { className: composeClassName('ui-timeline', className), ...props }));
|
|
1567
|
-
export const TimelineItem = ({ className, children, dot, ...props }) => (_jsxs("li", { className: composeClassName('ui-timeline-item', className), ...props, children: [_jsx("div", { className: "ui-timeline-item__tail" }), _jsx("div", { className: "ui-timeline-item__dot", children: dot }), _jsx("div", { className: "ui-timeline-item__content", children: children })] }));
|
|
1568
|
-
export const AnimatedLogo = ({ animation = 'reveal', className, ...props }) => (_jsx("span", { className: composeClassName('ui-animated-logo', className), "data-animation": animation, "data-ui-animated-logo": true, ...props }));
|
|
1569
|
-
export const Graphic = ({ children, className, label, size = 'md', tone = 'brand', variant = 'orbit', ...props }) => (_jsx("div", { "aria-hidden": label ? undefined : true, "aria-label": label, className: composeClassName('ui-graphic', `ui-graphic--${variant}`, `ui-graphic--${tone}`, `ui-graphic--${size}`, className), role: label ? 'img' : undefined, ...props, children: _jsx("div", { className: "ui-graphic__content", children: children }) }));
|
|
1570
|
-
export const Backdrop = ({ children, className, intensity = 'medium', tone = 'brand', variant = 'aurora', ...props }) => (_jsx("div", { className: composeClassName('ui-backdrop', `ui-backdrop--${variant}`, `ui-backdrop--${tone}`, `ui-backdrop--${intensity}`, className), ...props, children: _jsx("div", { className: "ui-backdrop__content", children: children }) }));
|
|
1571
|
-
export const AnimatedPortrait = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-animated-portrait relative isolate w-full animate-reveal-lcp motion-reduce:animate-none', className), ...props }));
|
|
1572
|
-
const getButtonLinkVariantClass = (variant) => {
|
|
1573
|
-
if (variant === 'unstyled')
|
|
1574
|
-
return 'ui-button-link--unstyled';
|
|
1575
|
-
if (variant === 'inline')
|
|
1576
|
-
return 'ui-button ui-button--inline';
|
|
1577
|
-
return `ui-button ui-button--${variant} min-h-11 rounded-full border`;
|
|
1578
|
-
};
|
|
1579
|
-
export const ButtonLink = ({ asChild = false, children, className, ref, shape = 'default', variant = 'primary', ...props }) => {
|
|
1580
|
-
const variantClass = getButtonLinkVariantClass(variant);
|
|
1581
|
-
const shapeClass = shape === 'icon' && variant !== 'inline' ?
|
|
1582
|
-
'ui-button-link--icon' :
|
|
1583
|
-
undefined;
|
|
1584
|
-
const buttonLinkClassName = composeClassName('ui-button-link', variant !== 'unstyled' &&
|
|
1585
|
-
'group inline-flex cursor-pointer items-center justify-center gap-2 text-sm font-semibold tracking-[0.01em]', variantClass, shapeClass, className);
|
|
1586
|
-
if (asChild) {
|
|
1587
|
-
const child = Children.only(children);
|
|
1588
|
-
if (!isValidElement(child)) {
|
|
1589
|
-
throw new Error('ButtonLink with asChild requires exactly one valid React element child.');
|
|
1590
|
-
}
|
|
1591
|
-
const ChildComponent = child.type;
|
|
1592
|
-
return (_jsx(ChildComponent, { ...child.props, ...props, className: composeClassName(buttonLinkClassName, child.props.className), "data-slot": "button-link", ref: ref, children: child.props.children }));
|
|
1593
|
-
}
|
|
1594
|
-
return (_jsx("a", { className: buttonLinkClassName, "data-slot": "button-link", ref: ref, ...props, children: children }));
|
|
1595
|
-
};
|
|
1596
|
-
export const CoverImage = ({ className, hover = false, showBottomGradient = false, children, ...props }) => (_jsxs("div", { className: composeClassName('ui-cover-image relative overflow-hidden bg-surface-muted', hover && 'ui-cover-image--hover', className), ...props, children: [children, showBottomGradient && (_jsx("div", { "aria-hidden": "true", className: "ui-cover-image__bottom-gradient" }))] }));
|
|
1597
|
-
export const GradientDivider = ({ className, ...props }) => (_jsx("div", { "aria-hidden": "true", className: composeClassName('ui-gradient-divider pointer-events-none flex justify-center', className), ...props, children: _jsx("div", { className: "\n via-brand/40 h-px w-full max-w-5xl bg-linear-to-r from-transparent\n to-transparent\n " }) }));
|
|
1598
|
-
const emptySteps = [];
|
|
1599
|
-
const normalizeStep = (step) => typeof step === 'string' ? { description: undefined, title: step } : step;
|
|
1600
|
-
export const Stepper = ({ children, className, currentStep = 0, orientation = 'horizontal', steps = emptySteps, ...props }) => (_jsxs("ol", { className: composeClassName('ui-stepper', orientation === 'vertical' && 'ui-stepper--vertical', className), "data-orientation": orientation, ...props, children: [steps.map(normalizeStep).map((step, index) => {
|
|
1601
|
-
let state = 'upcoming';
|
|
1602
|
-
if (index < currentStep) {
|
|
1603
|
-
state = 'complete';
|
|
1604
|
-
}
|
|
1605
|
-
else if (index === currentStep) {
|
|
1606
|
-
state = 'current';
|
|
1607
|
-
}
|
|
1608
|
-
return (_jsxs("li", { "aria-current": state === 'current' ? 'step' : undefined, className: "ui-stepper__step", "data-state": state, children: [_jsx("span", { className: "ui-stepper__marker", children: index + 1 }), _jsxs("span", { className: "ui-stepper__content", children: [_jsx("span", { className: "ui-stepper__title", children: step.title }), step.description && (_jsx("span", { className: "ui-stepper__description", children: step.description }))] })] }, step.title));
|
|
1609
|
-
}), children] }));
|
|
1610
|
-
export const FileUpload = ({ children, className, hint, id, inputClassName, label = 'Choose a file or drag it here', onChange, ref, ...props }) => {
|
|
1611
|
-
const generatedId = useId();
|
|
1612
|
-
const inputId = id ?? `ui-file-upload-${generatedId.replaceAll(':', '')}`;
|
|
1613
|
-
const [selectedFiles, setSelectedFiles] = useState([]);
|
|
1614
|
-
const selectedFileText = selectedFiles.length > 1 ?
|
|
1615
|
-
`${selectedFiles.length} files selected` :
|
|
1616
|
-
(selectedFiles[0] ?? '');
|
|
1617
|
-
return (_jsxs("label", { className: composeClassName('ui-file-upload', className), "data-state": selectedFiles.length > 0 ? 'selected' : 'idle', "data-ui-file-upload": true, htmlFor: inputId, children: [_jsx("input", { className: composeClassName('ui-file-upload__input', inputClassName), "data-ui-file-upload-input": true, id: inputId, onChange: event => {
|
|
1618
|
-
setSelectedFiles([...(event.currentTarget.files ?? [])].map(file => file.name));
|
|
1619
|
-
onChange?.(event);
|
|
1620
|
-
}, ref: ref, type: "file", ...props }), _jsxs("svg", { "aria-hidden": "true", className: "ui-file-upload__icon", fill: "none", focusable: "false", viewBox: "0 0 24 24", children: [_jsx("path", { d: "M12 16V4m0 0L8 8m4-4 4 4" }), _jsx("path", { d: "M5 14v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-4" })] }), _jsx("span", { className: "ui-file-upload__prompt", children: children ?? label }), hint && _jsx("span", { className: "ui-file-upload__hint", children: hint }), _jsx("span", { "aria-live": "polite", className: "ui-file-upload__files", "data-ui-file-upload-files": true, children: selectedFileText })] }));
|
|
1621
|
-
};
|
|
1622
|
-
const emptyTourSteps = [];
|
|
1623
|
-
export const Tour = ({ children, className, closeLabel = 'Done', hidden = true, nextLabel = 'Next', steps = emptyTourSteps, ...props }) => (_jsxs("div", { className: composeClassName('ui-tour', className), "data-ui-tour": true, hidden: hidden, ...props, children: [_jsx("div", { "aria-hidden": "true", className: "ui-tour__backdrop", "data-ui-tour-backdrop": true }), _jsxs("div", { className: "ui-tour__popover", "data-ui-tour-popover": true, role: "dialog", children: [steps.map((step, index) => (_jsxs("div", { className: "ui-tour__step", "data-target": step.target, "data-ui-tour-step": true, hidden: index !== 0, children: [step.title && _jsx("p", { className: "ui-tour__title", children: step.title }), _jsx("p", { className: "ui-tour__content", children: step.content }), _jsxs("div", { className: "ui-tour__actions", children: [_jsx("button", { className: "ui-button ui-button--ghost ui-button--sm", "data-ui-tour-close": true, type: "button", children: closeLabel }), index < steps.length - 1 && (_jsx("button", { className: "ui-button ui-button--default ui-button--sm", "data-ui-tour-next": true, type: "button", children: nextLabel }))] })] }, step.target))), children] })] }));
|
|
1624
|
-
const emptyAnchorLinks = [];
|
|
1625
|
-
const createAnchorRef = () => {
|
|
1626
|
-
let cleanup;
|
|
1627
|
-
return (root) => {
|
|
1628
|
-
cleanup?.();
|
|
1629
|
-
cleanup = undefined;
|
|
1630
|
-
if (!root)
|
|
1631
|
-
return;
|
|
1632
|
-
const links = [...root.querySelectorAll('a[href^="#"]')];
|
|
1633
|
-
const targets = links.flatMap(link => {
|
|
1634
|
-
const id = decodeURIComponent(link.getAttribute('href')?.slice(1) ?? '');
|
|
1635
|
-
const target = id ? document.getElementById(id) : null;
|
|
1636
|
-
return target ? [{ link, target }] : [];
|
|
1637
|
-
});
|
|
1638
|
-
if (!targets.length)
|
|
1639
|
-
return;
|
|
1640
|
-
const abortController = new AbortController();
|
|
1641
|
-
let frame = 0;
|
|
1642
|
-
const setActive = (active) => {
|
|
1643
|
-
for (const link of links) {
|
|
1644
|
-
const isActive = link === active;
|
|
1645
|
-
link.dataset.active = String(isActive);
|
|
1646
|
-
if (isActive) {
|
|
1647
|
-
link.setAttribute('aria-current', 'location');
|
|
1648
|
-
}
|
|
1649
|
-
else {
|
|
1650
|
-
link.removeAttribute('aria-current');
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
};
|
|
1654
|
-
const update = () => {
|
|
1655
|
-
frame = 0;
|
|
1656
|
-
const scrollingElement = document.scrollingElement ?? document.documentElement;
|
|
1657
|
-
const atEnd = scrollingElement.scrollTop + scrollingElement.clientHeight >=
|
|
1658
|
-
scrollingElement.scrollHeight - 1;
|
|
1659
|
-
const offset = Number(root.dataset.uiAnchorOffset) || 0;
|
|
1660
|
-
let active = targets[0]?.link;
|
|
1661
|
-
if (atEnd) {
|
|
1662
|
-
active = targets.at(-1)?.link;
|
|
1663
|
-
}
|
|
1664
|
-
else {
|
|
1665
|
-
for (const item of targets) {
|
|
1666
|
-
if (item.target.getBoundingClientRect().top > offset)
|
|
1667
|
-
break;
|
|
1668
|
-
active = item.link;
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
if (active)
|
|
1672
|
-
setActive(active);
|
|
1673
|
-
};
|
|
1674
|
-
const requestUpdate = () => {
|
|
1675
|
-
if (frame)
|
|
1676
|
-
return;
|
|
1677
|
-
frame = requestAnimationFrame(update);
|
|
1678
|
-
};
|
|
1679
|
-
for (const { link } of targets) {
|
|
1680
|
-
link.addEventListener('click', () => {
|
|
1681
|
-
setActive(link);
|
|
1682
|
-
}, {
|
|
1683
|
-
signal: abortController.signal
|
|
1684
|
-
});
|
|
1685
|
-
}
|
|
1686
|
-
window.addEventListener('resize', requestUpdate, {
|
|
1687
|
-
passive: true,
|
|
1688
|
-
signal: abortController.signal
|
|
1689
|
-
});
|
|
1690
|
-
window.addEventListener('scroll', requestUpdate, {
|
|
1691
|
-
passive: true,
|
|
1692
|
-
signal: abortController.signal
|
|
1693
|
-
});
|
|
1694
|
-
update();
|
|
1695
|
-
cleanup = () => {
|
|
1696
|
-
abortController.abort();
|
|
1697
|
-
if (frame)
|
|
1698
|
-
cancelAnimationFrame(frame);
|
|
1699
|
-
};
|
|
1700
|
-
};
|
|
1701
|
-
};
|
|
1702
|
-
export const Anchor = ({ 'aria-label': ariaLabel = 'On this page', activationOffset = 96, children, className, items = emptyAnchorLinks, ...props }) => {
|
|
1703
|
-
const anchorRef = createAnchorRef();
|
|
1704
|
-
return (_jsxs("nav", { "aria-label": ariaLabel, className: composeClassName('ui-anchor', className), "data-ui-anchor": true, "data-ui-anchor-offset": Math.max(0, activationOffset), ref: anchorRef, ...props, children: [items.length > 0 && (_jsx("ol", { children: items.map((item, index) => (_jsx("li", { children: _jsxs("a", { "aria-current": index === 0 ? 'location' : undefined, "data-active": index === 0 ? 'true' : 'false', "data-depth": item.depth, href: item.href, children: [item.index !== undefined && (_jsx("span", { className: "ui-anchor__index", children: item.index })), _jsxs("span", { className: "ui-anchor__content", children: [_jsx("span", { className: "ui-anchor__label", children: item.label }), item.description && (_jsx("span", { className: "ui-anchor__description", children: item.description }))] })] }) }, item.href))) })), children] }));
|
|
1705
|
-
};
|
|
1706
|
-
export const Segmented = ({ children, className, defaultValue, name = 'segmented', onValueChange, options = emptyOptions, size = 'default', value = defaultValue, ...props }) => (_jsxs("div", { className: composeClassName('ui-segmented', size === 'sm' && 'ui-segmented--sm', size === 'lg' && 'ui-segmented--lg', className), role: "group", ...props, children: [options.map(normalizeOption).map(option => (_jsxs("label", { className: "ui-segmented__option", children: [_jsx("input", { defaultChecked: value === option.value, className: "ui-segmented__input", disabled: option.disabled, name: name, type: "radio", value: option.value, onChange: () => onValueChange?.(option.value) }), _jsx("span", { className: "ui-segmented__label", children: option.label })] }, option.value))), children] }));
|
|
1707
|
-
export const Toolbar = ({ 'aria-label': ariaLabel = 'Toolbar', className, orientation = 'horizontal', ...props }) => (_jsx("div", { "aria-label": ariaLabel, "aria-orientation": orientation, className: composeClassName('ui-toolbar', orientation === 'vertical' && 'ui-toolbar--vertical', className), "data-orientation": orientation, "data-ui-toolbar": true, role: "toolbar", ...props }));
|
|
1708
|
-
const emptyDescriptionsItems = [];
|
|
1709
|
-
export const Descriptions = ({ children, className, columns = 1, items = emptyDescriptionsItems, style, ...props }) => (_jsxs("dl", { className: composeClassName('ui-descriptions', className), "data-columns": columns, style: { ['--ui-descriptions-columns']: columns, ...style }, ...props, children: [items.map((item, index) => (_jsxs("div", { className: "ui-descriptions__item", children: [_jsx("dt", { className: "ui-descriptions__term", children: item.label }), _jsx("dd", { className: "ui-descriptions__detail", children: item.value })] }, index))), children] }));
|
|
1710
|
-
export const Popconfirm = ({ cancelLabel = 'Cancel', children, className, confirmLabel = 'Confirm', title = 'Are you sure?', ...props }) => (_jsxs("div", { className: composeClassName('ui-popover ui-popconfirm', className), "data-surface": "default", "data-ui-popconfirm": true, "data-ui-popover": true, ...props, children: [_jsx("span", { "aria-expanded": "false", "aria-haspopup": "dialog", className: "ui-popconfirm__trigger", "data-ui-trigger": true, children: children }), _jsxs("div", { className: "ui-popover__panel ui-popconfirm__panel", "data-ui-panel": true, hidden: true, role: "dialog", children: [_jsx("p", { className: "ui-popconfirm__message", children: title }), _jsxs("div", { className: "ui-popconfirm__actions", children: [_jsx("button", { className: "ui-button ui-button--ghost ui-button--sm", "data-ui-popconfirm-cancel": true, type: "button", children: cancelLabel }), _jsx("button", { className: "ui-button ui-button--destructive ui-button--sm", "data-ui-popconfirm-confirm": true, type: "button", children: confirmLabel })] })] })] }));
|
|
1711
|
-
const emptyTransferItems = [];
|
|
1712
|
-
const renderTransferItems = (items) => items.map(item => (_jsx("li", { className: "ui-transfer__item", children: _jsxs("label", { className: "ui-transfer__option", children: [_jsx("input", { className: "ui-checkbox", "data-ui-transfer-item": true, type: "checkbox", value: item.key }), _jsx("span", { children: item.label })] }) }, item.key)));
|
|
1713
|
-
export const Transfer = ({ className, items = emptyTransferItems, name, sourceTitle = 'Available', targetItems = emptyTransferItems, targetTitle = 'Selected', ...props }) => (_jsxs("div", { className: composeClassName('ui-transfer', className), "data-ui-transfer": true, "data-ui-transfer-name": name, ...props, children: [_jsxs("div", { className: "ui-transfer__panel", children: [_jsx("p", { className: "ui-transfer__title", children: sourceTitle }), _jsx("ul", { className: "ui-transfer__list", "data-side": "source", "data-ui-transfer-list": true, children: renderTransferItems(items) })] }), _jsxs("div", { className: "ui-transfer__controls", children: [_jsx("button", { "aria-label": `Move to ${targetTitle}`, className: "ui-button ui-button--outline ui-button--icon", "data-ui-transfer-move": "target", type: "button", children: _jsx(Icon, { name: "chevron-right" }) }), _jsx("button", { "aria-label": `Move to ${sourceTitle}`, className: "ui-button ui-button--outline ui-button--icon", "data-ui-transfer-move": "source", type: "button", children: _jsx(Icon, { name: "chevron-left" }) })] }), _jsxs("div", { className: "ui-transfer__panel", children: [_jsx("p", { className: "ui-transfer__title", children: targetTitle }), _jsx("ul", { className: "ui-transfer__list", "data-side": "target", "data-ui-transfer-list": true, children: renderTransferItems(targetItems) })] })] }));
|
|
1714
|
-
const buildCascaderColumns = (options, idPrefix) => {
|
|
1715
|
-
const columns = [];
|
|
1716
|
-
let count = 0;
|
|
1717
|
-
const build = (items, root) => {
|
|
1718
|
-
count += 1;
|
|
1719
|
-
const id = `${idPrefix}-column-${count}`;
|
|
1720
|
-
const rendered = items.map(item => ({
|
|
1721
|
-
label: item.label,
|
|
1722
|
-
value: item.value
|
|
1723
|
-
}));
|
|
1724
|
-
columns.push({ id, options: rendered, root });
|
|
1725
|
-
for (const [index, item] of items.entries()) {
|
|
1726
|
-
const renderedOption = rendered[index];
|
|
1727
|
-
if (item.children && item.children.length > 0 && renderedOption) {
|
|
1728
|
-
renderedOption.nextId = build(item.children, false);
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
return id;
|
|
1732
|
-
};
|
|
1733
|
-
if (options.length > 0)
|
|
1734
|
-
build(options, true);
|
|
1735
|
-
return columns;
|
|
1736
|
-
};
|
|
1737
|
-
const emptyCascaderOptions = [];
|
|
1738
|
-
export const Cascader = ({ children, className, id, name, options = emptyCascaderOptions, placeholder = 'Select…', ...props }) => {
|
|
1739
|
-
const generatedId = useId().replaceAll(':', '');
|
|
1740
|
-
const cascaderId = id ?? `ui-cascader-${generatedId}`;
|
|
1741
|
-
const panelId = `${cascaderId}-panel`;
|
|
1742
|
-
const columns = buildCascaderColumns(options, cascaderId);
|
|
1743
|
-
return (_jsxs("div", { className: composeClassName('ui-cascader', className), "data-surface": "default", "data-ui-cascader": true, "data-ui-popover": true, id: id, ...props, children: [_jsx("button", { "aria-controls": panelId, "aria-expanded": "false", "aria-haspopup": "listbox", className: "ui-select ui-select__trigger ui-cascader__trigger", "data-ui-trigger": true, role: "combobox", type: "button", children: _jsx("span", { "data-ui-cascader-placeholder": placeholder, "data-ui-cascader-value": true, children: placeholder }) }), _jsxs("div", { className: "ui-cascader__panel", "data-ui-panel": true, hidden: true, id: panelId, children: [columns.map(column => (_jsx("ol", { "aria-label": column.root ? 'Options' : 'Sub-options', className: "ui-cascader__column", hidden: !column.root, id: column.id, role: "listbox", children: column.options.map(option => (_jsx("li", { role: "presentation", children: _jsxs("button", { "aria-selected": "false", className: "ui-cascader__option", "data-ui-cascader-next": option.nextId ? `#${option.nextId}` : undefined, "data-ui-cascader-option": true, "data-value": option.value, role: "option", type: "button", children: [_jsx("span", { children: option.label }), option.nextId && _jsx("span", { "aria-hidden": "true", children: "\u203A" })] }) }, option.value))) }, column.id))), children] }), name && _jsx("input", { "data-ui-cascader-input": true, name: name, type: "hidden" })] }));
|
|
1744
|
-
};
|
|
1745
|
-
const flattenTreeSelect = (nodes, depth = 0, acc = []) => {
|
|
1746
|
-
for (const node of nodes) {
|
|
1747
|
-
acc.push({ depth, label: node.label, value: node.value });
|
|
1748
|
-
if (node.children && node.children.length > 0)
|
|
1749
|
-
flattenTreeSelect(node.children, depth + 1, acc);
|
|
1750
|
-
}
|
|
1751
|
-
return acc;
|
|
1752
|
-
};
|
|
1753
|
-
const emptyTreeSelectNodes = [];
|
|
1754
|
-
export const TreeSelect = ({ children, className, name, placeholder = 'Select…', treeData = emptyTreeSelectNodes, ...props }) => (_jsxs("div", { className: composeClassName('ui-tree-select', className), "data-surface": "default", "data-ui-popover": true, "data-ui-tree-select": true, ...props, children: [_jsx("button", { "aria-expanded": "false", "aria-haspopup": "tree", className: "ui-select ui-select__trigger ui-tree-select__trigger", "data-ui-trigger": true, type: "button", children: _jsx("span", { "data-ui-tree-select-placeholder": placeholder, "data-ui-tree-select-value": true, children: placeholder }) }), _jsxs("div", { className: "ui-tree-select__panel", "data-ui-panel": true, hidden: true, children: [_jsx("div", { className: "ui-tree-select__tree", role: "tree", children: flattenTreeSelect(treeData).map(row => (_jsx("button", { className: "ui-tree-select__option", "data-value": row.value, role: "treeitem", style: { ['--ui-tree-depth']: row.depth }, type: "button", children: row.label }, row.value))) }), children] }), name && _jsx("input", { "data-ui-tree-select-input": true, name: name, type: "hidden" })] }));
|
|
1755
|
-
export const Mentions = ({ className, defaultValue = '', label = 'Mentions', name, onValueChange, options = emptyOptions, placeholder, trigger = '@', value, ...props }) => {
|
|
1756
|
-
const generatedId = useId();
|
|
1757
|
-
const inputRef = useRef(null);
|
|
1758
|
-
const [activeIndex, setActiveIndex] = useState(-1);
|
|
1759
|
-
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
1760
|
-
const [query, setQuery] = useState(null);
|
|
1761
|
-
const currentValue = value ?? internalValue;
|
|
1762
|
-
const listId = `ui-mentions-${generatedId}-list`;
|
|
1763
|
-
const escapedTrigger = trigger.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1764
|
-
const normalizedOptions = options.map(normalizeOption);
|
|
1765
|
-
const visibleOptions = query === null ?
|
|
1766
|
-
[] :
|
|
1767
|
-
normalizedOptions.filter(option => option.value.toLowerCase().startsWith(query));
|
|
1768
|
-
const expanded = visibleOptions.length > 0;
|
|
1769
|
-
const resolvedActiveIndex = expanded ?
|
|
1770
|
-
Math.min(Math.max(activeIndex, 0), visibleOptions.length - 1) :
|
|
1771
|
-
-1;
|
|
1772
|
-
const activeOption = visibleOptions[resolvedActiveIndex];
|
|
1773
|
-
const setNextValue = (nextValue) => {
|
|
1774
|
-
if (value === undefined)
|
|
1775
|
-
setInternalValue(nextValue);
|
|
1776
|
-
onValueChange?.(nextValue);
|
|
1777
|
-
};
|
|
1778
|
-
const closeList = () => {
|
|
1779
|
-
setQuery(null);
|
|
1780
|
-
setActiveIndex(-1);
|
|
1781
|
-
};
|
|
1782
|
-
const insertMention = (mention) => {
|
|
1783
|
-
const caret = inputRef.current?.selectionStart ?? currentValue.length;
|
|
1784
|
-
const before = currentValue
|
|
1785
|
-
.slice(0, caret)
|
|
1786
|
-
.replace(new RegExp(`${escapedTrigger}\\w*$`), `${trigger}${mention} `);
|
|
1787
|
-
const nextValue = before + currentValue.slice(caret);
|
|
1788
|
-
setNextValue(nextValue);
|
|
1789
|
-
closeList();
|
|
1790
|
-
requestAnimationFrame(() => {
|
|
1791
|
-
inputRef.current?.focus();
|
|
1792
|
-
inputRef.current?.setSelectionRange(before.length, before.length);
|
|
1793
|
-
});
|
|
1794
|
-
};
|
|
1795
|
-
const handleKeyDown = (event) => {
|
|
1796
|
-
if (event.key === 'Escape' && expanded) {
|
|
1797
|
-
event.preventDefault();
|
|
1798
|
-
closeList();
|
|
1799
|
-
return;
|
|
1800
|
-
}
|
|
1801
|
-
if (expanded && (event.key === 'ArrowDown' || event.key === 'ArrowUp' ||
|
|
1802
|
-
event.key === 'End' || event.key === 'Home')) {
|
|
1803
|
-
event.preventDefault();
|
|
1804
|
-
setActiveIndex(current => {
|
|
1805
|
-
if (event.key === 'Home')
|
|
1806
|
-
return 0;
|
|
1807
|
-
if (event.key === 'End')
|
|
1808
|
-
return visibleOptions.length - 1;
|
|
1809
|
-
if (event.key === 'ArrowDown')
|
|
1810
|
-
return (current + 1) % visibleOptions.length;
|
|
1811
|
-
return (current - 1 + visibleOptions.length) % visibleOptions.length;
|
|
1812
|
-
});
|
|
1813
|
-
return;
|
|
1814
|
-
}
|
|
1815
|
-
if (event.key === 'Enter' && activeOption) {
|
|
1816
|
-
event.preventDefault();
|
|
1817
|
-
insertMention(activeOption.value);
|
|
1818
|
-
}
|
|
1819
|
-
};
|
|
1820
|
-
return (_jsxs("div", { className: composeClassName('ui-mentions', className), "data-ui-mentions": true, "data-ui-mentions-trigger": trigger, ...props, children: [_jsx("textarea", { "aria-activedescendant": activeOption ? `${listId}-option-${resolvedActiveIndex}` : undefined, "aria-autocomplete": "list", "aria-controls": listId, "aria-expanded": expanded, "aria-label": label, className: "ui-textarea ui-mentions__input", "data-ui-mentions-input": true, name: name, onBlur: closeList, onChange: event => {
|
|
1821
|
-
const nextValue = event.currentTarget.value;
|
|
1822
|
-
const match = new RegExp(`${escapedTrigger}(\\w*)$`)
|
|
1823
|
-
.exec(nextValue.slice(0, event.currentTarget.selectionStart));
|
|
1824
|
-
const nextQuery = match ? (match[1] ?? '').toLowerCase() : null;
|
|
1825
|
-
setNextValue(nextValue);
|
|
1826
|
-
setQuery(nextQuery);
|
|
1827
|
-
setActiveIndex(nextQuery === null ? -1 : 0);
|
|
1828
|
-
}, onKeyDown: handleKeyDown, placeholder: placeholder, ref: inputRef, role: "combobox", rows: 3, value: currentValue }), _jsx("ul", { className: "ui-mentions__list", "data-ui-mentions-list": true, hidden: !expanded, id: listId, role: "listbox", children: visibleOptions.map((option, index) => (_jsx("li", { children: _jsx("button", { "aria-selected": index === resolvedActiveIndex, className: "ui-mentions__option", "data-ui-mentions-option": true, "data-value": option.value, id: `${listId}-option-${index}`, onClick: () => {
|
|
1829
|
-
insertMention(option.value);
|
|
1830
|
-
}, onMouseDown: event => {
|
|
1831
|
-
event.preventDefault();
|
|
1832
|
-
}, role: "option", type: "button", children: option.label }) }, option.value))) })] }));
|
|
1833
|
-
};
|
|
1834
|
-
export const QRCode = ({ children, className, size = 160, src, style, value, ...props }) => {
|
|
1835
|
-
const qrSvg = !src && value ? renderSVG(value) : null;
|
|
1836
|
-
const qrSrc = qrSvg ?
|
|
1837
|
-
`data:image/svg+xml;utf8,${encodeURIComponent(qrSvg)}` :
|
|
1838
|
-
src;
|
|
1839
|
-
return (_jsxs("figure", { className: composeClassName('ui-qr-code', className), "data-ui-qr-code": true, style: { ['--ui-qr-code-size']: `${size}px`, ...style }, ...props, children: [_jsx("div", { className: "ui-qr-code__frame", children: qrSrc ?
|
|
1840
|
-
(_jsx("img", { alt: value ? `QR code for ${value}` : 'QR code', className: "ui-qr-code__image", height: size, src: qrSrc, width: size })) :
|
|
1841
|
-
(children) }), value && _jsx("figcaption", { className: "ui-qr-code__value", children: value })] }));
|
|
1842
|
-
};
|
|
1843
|
-
export const Watermark = ({ children, className, content, gap = 120, rotate = -22, style, text = 'Confidential', ...props }) => {
|
|
1844
|
-
const watermarkText = content ?? text;
|
|
1845
|
-
const tileSize = Math.max(1, gap);
|
|
1846
|
-
const watermarkXmlEntities = {
|
|
1847
|
-
'&': '&',
|
|
1848
|
-
'<': '<',
|
|
1849
|
-
'>': '>',
|
|
1850
|
-
'"': '"',
|
|
1851
|
-
'\'': '''
|
|
1852
|
-
};
|
|
1853
|
-
const escapedWatermarkText = watermarkText.replaceAll(/[&<>"']/g, character => watermarkXmlEntities[character] ?? character);
|
|
1854
|
-
const watermarkSvg = [
|
|
1855
|
-
'<svg xmlns="http://www.w3.org/2000/svg"',
|
|
1856
|
-
` width="${tileSize}" height="${tileSize}" viewBox="0 0 ${tileSize} ${tileSize}">`,
|
|
1857
|
-
`<text x="${tileSize / 2}" y="${tileSize / 2}" dominant-baseline="middle" text-anchor="middle"`,
|
|
1858
|
-
` transform="rotate(${rotate} ${tileSize / 2} ${tileSize / 2})"`,
|
|
1859
|
-
' fill="black" font-family="Montserrat, Avenir Next, Segoe UI, sans-serif" font-size="16" font-weight="500" letter-spacing="1.6">',
|
|
1860
|
-
`${escapedWatermarkText}</text></svg>`
|
|
1861
|
-
].join('');
|
|
1862
|
-
const watermarkImage = `url("data:image/svg+xml,${encodeURIComponent(watermarkSvg)}")`;
|
|
1863
|
-
return (_jsxs("div", { className: composeClassName('ui-watermark', className), "data-ui-watermark": true, style: {
|
|
1864
|
-
['--ui-watermark-gap']: `${tileSize}px`,
|
|
1865
|
-
['--ui-watermark-image']: watermarkImage,
|
|
1866
|
-
...style
|
|
1867
|
-
}, ...props, children: [children, _jsx("div", { "aria-hidden": "true", className: "ui-watermark__overlay", "data-text": watermarkText })] }));
|
|
1868
|
-
};
|
|
1869
|
-
export const Affix = ({ className, offset = 0, offsetBottom, offsetTop, position: positionProp, style, ...props }) => {
|
|
1870
|
-
const position = positionProp ?? (offsetBottom === undefined ? 'top' : 'bottom');
|
|
1871
|
-
const resolvedOffset = offsetBottom ?? offsetTop ?? offset;
|
|
1872
|
-
return (_jsx("div", { className: composeClassName('ui-affix', position === 'bottom' && 'ui-affix--bottom', className), "data-position": position, style: {
|
|
1873
|
-
['--ui-affix-offset']: `${resolvedOffset}px`,
|
|
1874
|
-
...style
|
|
1875
|
-
}, ...props }));
|
|
1876
|
-
};
|
|
1877
|
-
const emptySpeedDialActions = [];
|
|
1878
|
-
const speedDialNavigationKeys = [
|
|
1879
|
-
'ArrowDown',
|
|
1880
|
-
'ArrowLeft',
|
|
1881
|
-
'ArrowRight',
|
|
1882
|
-
'ArrowUp',
|
|
1883
|
-
'End',
|
|
1884
|
-
'Home'
|
|
1885
|
-
];
|
|
1886
|
-
const getSpeedDialNavigationIndex = (key, currentIndex, itemCount) => {
|
|
1887
|
-
if (key === 'Home')
|
|
1888
|
-
return 0;
|
|
1889
|
-
if (key === 'End')
|
|
1890
|
-
return itemCount - 1;
|
|
1891
|
-
if (key === 'ArrowDown' || key === 'ArrowRight')
|
|
1892
|
-
return (currentIndex + 1) % itemCount;
|
|
1893
|
-
return (currentIndex - 1 + itemCount) % itemCount;
|
|
1894
|
-
};
|
|
1895
|
-
export const SpeedDial = ({ actions = emptySpeedDialActions, children, className, defaultOpen = false, direction = 'up', label = 'Actions', onBlur, ...props }) => {
|
|
1896
|
-
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
1897
|
-
const menuRef = useRef(null);
|
|
1898
|
-
const triggerRef = useRef(null);
|
|
1899
|
-
const close = (restoreFocus = false) => {
|
|
1900
|
-
setIsOpen(false);
|
|
1901
|
-
if (restoreFocus)
|
|
1902
|
-
triggerRef.current?.focus();
|
|
1903
|
-
};
|
|
1904
|
-
const focusAction = (position) => {
|
|
1905
|
-
setIsOpen(true);
|
|
1906
|
-
requestAnimationFrame(() => {
|
|
1907
|
-
const items = menuRef.current?.querySelectorAll('[role="menuitem"], button:not([disabled]), a[href]');
|
|
1908
|
-
const target = position === 'first' ? items?.[0] : items?.[items.length - 1];
|
|
1909
|
-
target?.focus();
|
|
1910
|
-
});
|
|
1911
|
-
};
|
|
1912
|
-
return (_jsxs("div", { className: composeClassName('ui-speed-dial', `ui-speed-dial--${direction}`, className), ...props, "data-direction": direction, "data-state": isOpen ? 'open' : 'closed', "data-ui-bound": "true", "data-ui-speed-dial": true, onBlur: event => {
|
|
1913
|
-
onBlur?.(event);
|
|
1914
|
-
if (!event.currentTarget.contains(event.relatedTarget))
|
|
1915
|
-
close();
|
|
1916
|
-
}, children: [_jsx("button", { "aria-expanded": isOpen, "aria-haspopup": "menu", "aria-label": label, className: "ui-speed-dial__trigger", "data-ui-speed-dial-trigger": true, onClick: () => {
|
|
1917
|
-
setIsOpen(open => !open);
|
|
1918
|
-
}, onKeyDown: event => {
|
|
1919
|
-
if (event.key === 'Escape')
|
|
1920
|
-
close();
|
|
1921
|
-
if (['ArrowDown', 'ArrowRight'].includes(event.key)) {
|
|
1922
|
-
event.preventDefault();
|
|
1923
|
-
focusAction('first');
|
|
1924
|
-
return;
|
|
1925
|
-
}
|
|
1926
|
-
if (['ArrowLeft', 'ArrowUp'].includes(event.key)) {
|
|
1927
|
-
event.preventDefault();
|
|
1928
|
-
focusAction('last');
|
|
1929
|
-
}
|
|
1930
|
-
}, ref: triggerRef, type: "button", children: _jsx("span", { "aria-hidden": "true", className: "ui-speed-dial__icon" }) }), _jsxs("menu", { "aria-label": label, className: "ui-speed-dial__actions", "data-ui-speed-dial-actions": true, onClick: event => {
|
|
1931
|
-
if (event.target.closest('[role="menuitem"], button, a'))
|
|
1932
|
-
close();
|
|
1933
|
-
}, onKeyDown: event => {
|
|
1934
|
-
const items = [
|
|
1935
|
-
...(menuRef.current?.querySelectorAll('[role="menuitem"], button:not([disabled]), a[href]') ?? [])
|
|
1936
|
-
];
|
|
1937
|
-
if (event.key === 'Escape') {
|
|
1938
|
-
event.preventDefault();
|
|
1939
|
-
close(true);
|
|
1940
|
-
return;
|
|
1941
|
-
}
|
|
1942
|
-
if (!speedDialNavigationKeys.includes(event.key))
|
|
1943
|
-
return;
|
|
1944
|
-
const currentIndex = items.indexOf(document.activeElement);
|
|
1945
|
-
const targetIndex = getSpeedDialNavigationIndex(event.key, currentIndex, items.length);
|
|
1946
|
-
event.preventDefault();
|
|
1947
|
-
items[targetIndex]?.focus();
|
|
1948
|
-
}, ref: menuRef, role: "menu", children: [actions.map((action, index) => (_jsx("li", { role: "presentation", style: { '--ui-speed-dial-index': index }, children: _jsxs("button", { "aria-label": action.label, className: "ui-speed-dial__action", "data-icon": action.icon, "data-value": action.value ?? action.label, role: "menuitem", type: "button", children: [action.icon && (_jsx("span", { "aria-hidden": "true", className: "ui-speed-dial__action-icon ui-icon", children: renderLucideIcon(action.icon, `ui-icon__svg lucide-${action.icon}`) })), _jsx("span", { className: "ui-speed-dial__action-label", children: action.label })] }) }, action.value ?? action.label))), children] })] }));
|
|
1949
|
-
};
|
|
1
|
+
"use client";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{Children,cloneElement,createContext,createElement,Fragment,isValidElement,use,useCallback,useEffect,useId,useLayoutEffect,useMemo,useRef,useState}from"react";import{alignLumenChartSeries,bindLumenTabIndicator,composeClassName,createLumenBarGeometry,createLumenChartDatumActivation,createLumenHeatmapDatumActivation,createLumenHeatmapModel,createLumenLineChartModel,createLumenLineGeometry,createLumenMessageScrollerController,createLumenPieGeometry,createLumenRangeDatumActivation,createLumenRangeGeometry,createLumenScatterGeometry,createLumenScatterReferences,formatLumenChartSummary,formatLumenLanguageLabel,formatLumenPhoneNumber,getLumenChartCategories,getLumenChartCategoryLabel,getLumenChartCategoryTicks,getLumenChartDomain,getLumenChartMotionKey,getLumenChartTicks,getLumenChartToneClassName,getLumenHeatmapColor,getLumenIcon,getLumenPhoneCountries,getLumenPhoneFlagSource,getLumenPieChartVariantClassName,hasLumenChartData,hasLumenPieData,lumenCodeTokenClassNames,lumenIllustrations,normalizeLumenFormErrors,resolveLumenChartLabels,resolveLumenChartTone,resolveLumenPhoneNumber,scaleLumenChartValue,tokenizeLumenCode}from"@santi020k/lumen-core";import{parseLumenDate as parseCalendarDate,resolveLumenDateLabels as resolveDateControlLabels,resolveLumenDateLocale as getCalendarLocale}from"@santi020k/lumen-core";import{renderSVG}from"uqr";import{ChartInspection}from"./chart-inspection.js";import{ChartInteraction}from"./chart-interaction.js";import{getChartPlotLabel}from"./chart-label.js";import{createReactChartDatumAction,formatReactChartTableValue,readReactChartDatumActivation}from"./chart-recipes.js";import{useCalendar,useDialog,useDropdownMenu,useInputOTP,useLanguageToggle,usePopover,useResizable,useSelect,useTabs,useTooltip}from"./hooks.js";import{renderIconSvg}from"./icon-svg.js";import{IconView}from"./icon-view.js";import{resolveReactPhoneInputCountry,resolveReactPhoneInputValue}from"./phone-recipes.js";import{Input,Label}from"./server-components.js";import{useCopyFeedback}from"./use-copy-feedback.js";import{Badge,Card,CardContent,CardDescription,CardFooter,CardHeader,CardTitle,Container,Direction,Grid,Input as Input2,Label as Label2,Progress,Separator,Skeleton,Spinner,Stack,Textarea,Typography,VisuallyHidden}from"./server-components.js";const getChartCategoryKey=value=>`${typeof value}:${String(value)}`,setRefValue=(ref,value)=>{typeof ref=="function"?ref(value):ref&&(ref.current=value)},emptyOptions=[],emptyChartSeries=[],emptyHeatmapData=[],emptyRangeData=[],emptyComboSeries=[],emptyPieSeries={data:[],id:"pie",label:"Values"},emptyChartValues=[],variantClass=(base,variant,defaultVariant="default")=>variant===defaultVariant?!1:`${base}--${variant}`,renderLucideIcon=(name,className)=>{const icon=getLumenIcon(name);return icon?renderIconSvg(icon,className):null},resolveSurface=glass=>glass?"glass":"default",glassIntensityClass=glass=>glass==="subtle"?"ui-glass-subtle":glass==="strong"&&"ui-glass-strong",glassSurfaceClass=(base,glass)=>resolveSurface(glass)==="glass"&&composeClassName(`${base}--glass`,glassIntensityClass(glass)),glassClass=(base,glass)=>!!glass&&composeClassName(`${base}--glass`,glassIntensityClass(glass)),normalizeOption=option=>typeof option=="string"?{label:option,value:option}:option,toInputValue=value=>{if(value!==void 0)return String(value)},composeHandlers=(userHandler,lumenHandler)=>event=>{userHandler?.(event),lumenHandler?.(event)},Primitive=({as,className,uiClassName,...props})=>_jsx(as??"div",{className:composeClassName(uiClassName,typeof className=="string"?className:void 0),...props}),DropdownMenuContext=createContext(null),PopoverContext=createContext(null),TabsContext=createContext(null),TooltipContext=createContext(null),requireContext=(context,componentName)=>{if(!context)throw new Error(`${componentName} must be used inside its matching Lumen root component.`);return context},Accordion=({className,variant="default",...props})=>_jsx("div",{className:composeClassName("ui-accordion",variant==="flush"&&"ui-accordion--flush",className),"data-variant":variant,...props}),Alert=({className,glass=!1,variant="default",...props})=>_jsx("aside",{className:composeClassName("ui-alert",variantClass("ui-alert",variant),glassClass("ui-alert",glass),className),"data-variant":variant,...props}),AlertDialog=({className,defaultOpen,dismissOnEscape,dismissOnOutsidePress,glass=!1,onCancel,onClick,onClose,onOpenChange,onPointerDown,open,...props})=>{const dialog=useDialog({alert:!0,defaultOpen,dismissOnEscape,dismissOnOutsidePress,onOpenChange,open});return _jsx("dialog",{...dialog.dialogProps,...props,className:composeClassName("ui-dialog ui-alert-dialog",glassSurfaceClass("ui-dialog",glass),className),"data-surface":resolveSurface(glass),onCancel:composeHandlers(onCancel,dialog.dialogProps.onCancel),onPointerDown:composeHandlers(onPointerDown,dialog.dialogProps.onPointerDown),onClick:composeHandlers(onClick,dialog.dialogProps.onClick),onClose:composeHandlers(onClose,dialog.dialogProps.onClose)})},Agenda=({className,glass=!1,...props})=>_jsx("section",{className:composeClassName("ui-agenda",glassClass("ui-agenda",glass),className),...props}),AspectRatio=({className,ratio="16 / 9",style,...props})=>_jsx("div",{className:composeClassName("ui-aspect-ratio",className),style:{aspectRatio:ratio,...style},...props}),Autocomplete=({className,type="search",...props})=>_jsx("input",{"aria-autocomplete":"list",className:composeClassName("ui-input ui-autocomplete",className),role:"combobox",type,...props}),Attachment=({className,glass=!1,href,...props})=>{const nextClassName=composeClassName("ui-attachment",glassClass("ui-attachment",glass),className);return href?_jsx("a",{className:nextClassName,href,...props}):_jsx("article",{className:nextClassName,...props})},Avatar=({alt="",children,className,fallback,src,...props})=>_jsxs("span",{className:composeClassName("ui-avatar",className),...props,children:[src?_jsx("img",{alt,src}):_jsx("span",{children:fallback}),children]}),Breadcrumb=({"aria-label":ariaLabel="Breadcrumb",className,...props})=>_jsx("nav",{"aria-label":ariaLabel,className:composeClassName("ui-breadcrumb",className),...props}),Bubble=({className,from="assistant",glass=!1,...props})=>_jsx("article",{className:composeClassName("ui-bubble",from==="user"&&"ui-bubble--user",glassClass("ui-bubble",glass),className),"data-from":from,...props}),Button=({asChild=!1,children,className,disabled,loading=!1,ref,size="default",type="button",variant="default",...props})=>{const isDisabled=disabled===!0||loading,buttonClassName=composeClassName("ui-button",`ui-button--${variant}`,size==="default"?"ui-button--default-size":`ui-button--${size}`,isDisabled&&"ui-button--disabled",loading&&"ui-button--loading",className);if(asChild){const child=children;if(!isValidElement(child))throw new TypeError("Button with asChild requires exactly one React element child.");const ChildComponent=child.type;return _jsxs(ChildComponent,{...child.props,...props,"aria-busy":loading?!0:void 0,"aria-disabled":isDisabled?!0:void 0,className:composeClassName(buttonClassName,child.props.className),"data-slot":"button",onClickCapture:isDisabled?event=>{event.preventDefault(),event.stopPropagation()}:props.onClickCapture??child.props.onClickCapture,onKeyDownCapture:isDisabled?event=>{(event.key==="Enter"||event.key===" ")&&(event.preventDefault(),event.stopPropagation())}:props.onKeyDownCapture??child.props.onKeyDownCapture,ref,tabIndex:isDisabled?-1:props.tabIndex??child.props.tabIndex,children:[loading&&_jsx("span",{"aria-hidden":"true",className:"ui-spinner"}),_jsx("span",{className:"ui-button__content",children:child.props.children})]})}return _jsxs("button",{"aria-busy":loading||void 0,className:buttonClassName,"data-slot":"button",disabled:isDisabled,ref,type,...props,children:[loading&&_jsx("span",{"aria-hidden":"true",className:"ui-spinner"}),_jsx("span",{className:"ui-button__content",children})]})},ButtonGroup=({className,...props})=>_jsx("div",{className:composeClassName("ui-button-group",className),...props}),Calendar=({className,defaultValue,disabled=!1,glass=!1,labels,locale,max,min,month,name,onValueChange,readOnly,value,...props})=>{const calendar=useCalendar({defaultValue,disabled,labels,locale,max,min,month,name,onValueChange,readOnly,value});return _jsxs("div",{...props,...calendar.rootProps,className:composeClassName(calendar.rootProps.className,glassClass("ui-calendar",glass),className),"data-ui-glass-track":glass?!0:void 0,children:[_jsx("input",{...calendar.inputProps}),_jsxs("div",{className:"ui-calendar__header",children:[_jsx("button",{...calendar.previousProps,type:"button",children:_jsx("span",{"aria-hidden":"true",children:"\u2039"})}),_jsx("strong",{...calendar.labelProps,children:calendar.label}),_jsx("button",{...calendar.nextProps,type:"button",children:_jsx("span",{"aria-hidden":"true",children:"\u203A"})})]}),_jsxs("table",{...calendar.gridProps,children:[_jsx("thead",{children:_jsx("tr",{role:"row",children:calendar.weekdays.map(weekday=>_jsx("th",{role:"columnheader",scope:"col",children:weekday},weekday))})}),_jsx("tbody",{children:calendar.weeks.map(week=>_jsx("tr",{role:"row",children:week.map(day=>_jsx("td",{...calendar.getDayProps(day),children:day.day},day.date))},week[0]?.date??"week"))})]})]})},Carousel=({className,glass=!1,...props})=>_jsx("section",{className:composeClassName("ui-carousel",glassClass("ui-carousel",glass),className),"data-ui-carousel":!0,...props}),ChartHeader=({description,heading,value})=>!heading&&!description&&!value?null:_jsxs("header",{children:[_jsxs("div",{className:"ui-chart__heading",children:[heading&&_jsx("h3",{children:heading}),description&&_jsx("p",{children:description})]}),value&&_jsx("strong",{"data-ui-chart-value":!0,children:value})]}),Chart=({caption,children,className,description,glass=!1,heading,presentation="default",summary,value,...props})=>_jsxs("figure",{className:composeClassName("ui-chart",presentation==="bare"&&"ui-chart--bare",glassClass("ui-chart",glass),className),...props,children:[_jsx(ChartHeader,{description,heading,value}),summary&&_jsx("p",{className:"ui-sr-only","data-ui-chart-summary":!0,children:summary}),children,caption&&_jsx("figcaption",{children:caption})]}),DatumChart=({onClick,onDatumActivate,...props})=>_jsx(Chart,{...props,"data-ui-chart-activation":onDatumActivate?!0:void 0,"data-ui-chart-adapter":onDatumActivate?"react":void 0,onClick:event=>{if(onClick?.(event),event.defaultPrevented||event.button!==0||!onDatumActivate)return;const detail=readReactChartDatumActivation(event.currentTarget,event.target);detail&&onDatumActivate(detail)}}),ChartDatumActions=({actions,label})=>{const available=actions.filter(action=>action!==null);return available.length===0?null:_jsxs("details",{className:"ui-chart__actions","data-ui-chart-actions":!0,children:[_jsx("summary",{children:label}),_jsx("ul",{children:available.map(action=>_jsx("li",{children:_jsx(Button,{variant:"ghost","data-ui-chart-datum":action.serialized,children:action.label})},action.key))})]})},ChartLegend=({label="Chart legend",series})=>_jsx("ul",{"aria-label":label,className:"ui-chart__legend",children:series.map((item,index)=>_jsxs("li",{className:getLumenChartToneClassName(item.tone,index),children:[_jsx("span",{"aria-hidden":"true"}),item.label]},item.id))}),ChartDataTable=({categories,formatCategory,formatValue=String,labels,series})=>{const resolvedLabels=resolveLumenChartLabels(labels),alignedSeries=series.map(item=>alignLumenChartSeries(item,categories));return _jsxs("details",{className:"ui-chart__data",children:[_jsx("summary",{children:resolvedLabels.viewData}),_jsx("div",{"aria-label":resolvedLabels.chartData,role:"group",tabIndex:0,children:_jsxs("table",{children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{scope:"col",children:resolvedLabels.category}),series.map(item=>_jsx("th",{scope:"col",children:item.label},item.id))]})}),_jsx("tbody",{children:categories.map(category=>_jsxs("tr",{children:[_jsx("th",{scope:"row",children:getLumenChartCategoryLabel(alignedSeries,category,formatCategory,"detail")}),alignedSeries.map(item=>{const datum=item.data.find(candidate=>candidate.x===category);return _jsx("td",{children:datum?.label??formatReactChartTableValue(datum?.y,formatValue,resolvedLabels.notAvailable)},item.id)})]},getChartCategoryKey(category)))})]})})]})},formatChartPercentage=percentage=>new Intl.NumberFormat(void 0,{maximumFractionDigits:percentage<.01?1:0,style:"percent"}).format(percentage),Sparkline=({area=!1,className,label="Trend",showEndpoint=!0,tone,values=emptyChartValues,...props})=>{const geometry=createLumenLineGeometry(values.map((value,index)=>({x:index,y:value})),{height:40,padding:3,width:120}),resolvedTone=resolveLumenChartTone(tone),endpoint=geometry.points.at(-1);return _jsxs("span",{"aria-label":label,className:composeClassName("ui-sparkline",`ui-chart-tone--${resolvedTone}`,className),role:"img",...props,children:[_jsxs("svg",{"aria-hidden":"true",preserveAspectRatio:"none",viewBox:"0 0 120 40",children:[area&&geometry.areaPaths.map(path=>_jsx("path",{className:"ui-sparkline__area",d:path},path)),_jsx("path",{className:"ui-sparkline__line",d:geometry.path})]}),showEndpoint&&endpoint&&_jsx("span",{"aria-hidden":"true",className:"ui-sparkline__endpoint",style:{left:`${endpoint.xCoordinate/120*100}%`,top:`${endpoint.yCoordinate/40*100}%`}}),_jsx("span",{className:"ui-sr-only",children:label})]})},BarChart=({categoryWidth,className,onDatumActivate,emptyLabel,formatCategory,formatValue=String,layout="grouped",labels,orientation="vertical",series=emptyChartSeries,showLegend=series.length>1,showTable=!0,summary,...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),categories=getLumenChartCategories(series),alignedSeries=series.map(item=>alignLumenChartSeries(item,categories)),motionKeys=new Map(alignedSeries.flatMap(item=>item.data.map(point=>[JSON.stringify([item.id,point.x]),getLumenChartMotionKey(item.id,point)]))),geometry=createLumenBarGeometry(alignedSeries,{width:480,height:240,categoryWidth:categoryWidth??160,...formatCategory===void 0?{}:{formatCategory},formatValue,layout,orientation}),hasData=hasLumenChartData(alignedSeries),ticks=getLumenChartTicks(geometry.domain),margin=geometry.margin,categoryTicks=getLumenChartCategoryTicks(geometry.categories.map(category=>String(category.label)),{end:geometry.width-margin.right,positions:geometry.categories.map(category=>category.x),start:margin.left}),valueTicks=getLumenChartCategoryTicks(ticks.map(tick=>formatValue(tick)),{end:geometry.width-margin.right,minimumGap:48,positions:ticks.map(tick=>scaleLumenChartValue(tick,geometry.domain,margin.left,geometry.width-margin.right)),start:margin.left}),datumActions=onDatumActivate?geometry.marks.map(mark=>{const item=alignedSeries.find(candidate=>candidate.id===mark.seriesId),datum=item?.data.find(candidate=>candidate.x===mark.category);return item&&datum?createReactChartDatumAction(createLumenChartDatumActivation(item.id,datum),`${getLumenChartCategoryLabel(alignedSeries,mark.category,formatCategory,"detail")} \xB7 ${mark.seriesLabel}: ${formatValue(mark.value)}`,resolvedLabels):null}):[];return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-bar-chart",className),summary:summary??formatLumenChartSummary(alignedSeries,formatValue,resolvedLabels),...props,children:[showLegend&&hasData&&_jsx(ChartLegend,{label:resolvedLabels.chartLegend,series}),!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:emptyLabel??resolvedLabels.empty}),_jsx("div",{"aria-label":resolvedLabels.chartData,className:"ui-chart__plot",role:"region",tabIndex:0,hidden:!hasData,children:_jsxs("svg",{"aria-hidden":"true",preserveAspectRatio:"xMidYMid meet",viewBox:`0 0 ${geometry.width} ${geometry.height}`,children:[_jsx("g",{className:"ui-chart__grid",children:ticks.map(tick=>{const coordinate=orientation==="horizontal"?scaleLumenChartValue(tick,geometry.domain,margin.left,geometry.width-margin.right):scaleLumenChartValue(tick,geometry.domain,geometry.height-margin.bottom,margin.top);return orientation==="horizontal"?_jsx("line",{x1:coordinate,x2:coordinate,y1:margin.top,y2:geometry.height-margin.bottom},tick):_jsxs(Fragment,{children:[_jsx("line",{x1:margin.left,x2:geometry.width-margin.right,y1:coordinate,y2:coordinate}),_jsx("text",{x:margin.left-8,y:coordinate,children:formatValue(tick)})]},tick)})}),_jsx("g",{className:"ui-chart__axis-labels",children:orientation==="horizontal"?geometry.categories.map(category=>_jsx("text",{dominantBaseline:"middle",textAnchor:"end",x:category.x,y:category.y,children:getLumenChartCategoryTicks([String(category.label)],{end:margin.left-16,start:0})[0]?.label},getChartCategoryKey(category.category))):categoryTicks.map(tick=>_jsx("text",{textAnchor:tick.textAnchor,x:tick.position,y:geometry.height-20,children:tick.label},tick.index))}),orientation==="horizontal"&&_jsx("g",{className:"ui-chart__axis-labels",children:valueTicks.map(tick=>_jsx("text",{textAnchor:tick.textAnchor,x:tick.position,y:geometry.height-6,children:tick.label},tick.index))}),_jsxs("g",{className:"ui-bar-chart__marks",children:[geometry.marks.map((mark,index)=>_jsx("rect",{className:getLumenChartToneClassName(mark.tone),"data-ui-chart-motion-key":motionKeys.get(JSON.stringify([mark.seriesId,mark.category])),"data-ui-chart-datum":datumActions[index]?.serialized,height:mark.height,rx:"4",width:mark.width,x:mark.x,y:mark.y,children:_jsx("title",{children:`${getLumenChartCategoryLabel(alignedSeries,mark.category,formatCategory,"detail")} \xB7 ${mark.seriesLabel}: ${formatValue(mark.value)}`})},`${mark.seriesId}:${getChartCategoryKey(mark.category)}`)),onDatumActivate&&geometry.marks.map((mark,index)=>_jsx("rect",{className:"ui-chart__datum-hit",width:Math.max(12,mark.width),height:Math.max(12,mark.height),x:mark.x-Math.max(0,12-mark.width)/2,y:mark.y-Math.max(0,12-mark.height)/2,"data-ui-chart-datum":datumActions[index]?.serialized},`${mark.seriesId}:${getChartCategoryKey(mark.category)}`))]})]})}),showTable&&hasData&&_jsx(ChartDataTable,{categories,...formatCategory===void 0?{}:{formatCategory},formatValue,labels:resolvedLabels,series}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},getLineChartMarkerStep=(markers,categoryCount)=>markers===!1||markers==="none"?Number.POSITIVE_INFINITY:typeof markers=="number"?Math.max(1,Math.round(markers)):markers==="auto"?Math.max(1,Math.ceil(categoryCount/24)):1,LineChart=({area=!1,onDatumActivate,annotations,domain:requestedDomain,height:requestedHeight,width:requestedWidth,xDomain,xScale="categorical",interactive=!1,syncGroup,cursor,onCursorChange,className,emptyLabel,formatCategory,formatValue=String,labels,markers="auto",referenceValue,series=emptyChartSeries,showLegend=series.length>1,showTable=!0,summary,...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),model=createLumenLineChartModel(series,{xScale,formatValue,...annotations?{annotations}:{},...requestedDomain?{domain:requestedDomain}:{},...requestedHeight===void 0?{}:{height:requestedHeight},...requestedWidth===void 0?{}:{width:requestedWidth},...xDomain?{xDomain}:{},...referenceValue===void 0?{}:{referenceValue},...formatCategory?{formatCategory}:{}}),{width,height,padding,paddingLeft,categories,categoryTicks,domain,geometries,ticks,series:alignedSeries}=model,hasData=hasLumenChartData(alignedSeries),markerStep=getLineChartMarkerStep(markers,categories.length),pointActions=onDatumActivate?geometries.map((geometry,index)=>{const item=alignedSeries[index];return item?geometry.points.map(point=>createReactChartDatumAction(createLumenChartDatumActivation(item.id,point),`${getLumenChartCategoryLabel(alignedSeries,point.x,formatCategory,"detail")} \xB7 ${item.label}: ${formatValue(point.y??0)}`,resolvedLabels)):[]}):[],datumActions=pointActions.flat(),referenceY=referenceValue===void 0?void 0:scaleLumenChartValue(referenceValue,domain,height-padding,padding);return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-line-chart",className),summary:summary??formatLumenChartSummary(alignedSeries,formatValue,resolvedLabels),...props,children:[_jsxs(ChartInteraction,{interactive,model,showLegend,...syncGroup?{syncGroup}:{},...cursor===void 0?{}:{cursor},...onCursorChange?{onCursorChange}:{},children:[showLegend&&hasData&&(interactive?_jsx("ul",{className:"ui-chart__legend","aria-label":resolvedLabels.chartLegend,children:series.map((item,index)=>_jsx("li",{className:getLumenChartToneClassName(item.tone,index),children:_jsx(Button,{"aria-pressed":"true","data-ui-chart-toggle":item.id,disabled:!0,size:"sm",variant:"ghost",children:item.label})},item.id))}):_jsx(ChartLegend,{label:resolvedLabels.chartLegend,series})),!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:emptyLabel??resolvedLabels.empty}),_jsx("div",{"aria-label":getChartPlotLabel(props["aria-label"],props.heading,resolvedLabels.chartData),className:"ui-chart__plot","data-ui-chart-interaction-plot":interactive||void 0,role:"region",tabIndex:0,hidden:!hasData,children:_jsxs("svg",{"aria-hidden":"true",preserveAspectRatio:"xMidYMid meet",viewBox:`0 0 ${width} ${height}`,children:[_jsx("g",{className:"ui-chart__grid",children:ticks.map(tick=>{const y=scaleLumenChartValue(tick,domain,height-padding,padding);return _jsxs(Fragment,{children:[_jsx("line",{x1:paddingLeft,x2:width-padding,y1:y,y2:y}),_jsx("text",{x:paddingLeft-8,y,children:formatValue(tick)})]},tick)})}),_jsx("g",{className:"ui-chart__axis-labels",children:categoryTicks.map(tick=>_jsx("text",{textAnchor:tick.textAnchor,x:tick.position,y:height-14,children:tick.label},tick.index))}),_jsxs("svg",{x:paddingLeft,y:padding,width:width-padding-paddingLeft,height:height-2*padding,viewBox:`${paddingLeft} ${padding} ${width-padding-paddingLeft} ${height-2*padding}`,overflow:"hidden",children:[referenceY!==void 0&&_jsx("line",{className:"ui-chart__reference",x1:paddingLeft,x2:width-padding,y1:referenceY,y2:referenceY}),geometries.map((geometry,index)=>{const item=series[index];if(!item)return null;const tone=resolveLumenChartTone(item.tone,index);return _jsxs("g",{className:composeClassName("ui-line-chart__series",getLumenChartToneClassName(tone)),"data-ui-chart-series":item.id,children:[area&&geometry.areaPaths.length>0&&_jsx("path",{"data-ui-chart-motion-key":JSON.stringify(["area",item.id]),className:"ui-line-chart__area",d:geometry.areaPaths.join(" ")}),_jsx("path",{"data-ui-chart-motion-key":JSON.stringify(["path",item.id]),className:"ui-line-chart__line",d:geometry.path}),Number.isFinite(markerStep)&&geometry.points.map((point,pointIndex)=>pointIndex%markerStep===0&&_jsx("circle",{"data-ui-chart-datum":pointActions[index]?.[pointIndex]?.serialized,"data-ui-chart-motion-key":getLumenChartMotionKey(item.id,point),className:"ui-line-chart__point",cx:point.xCoordinate,cy:point.yCoordinate,r:"3",children:_jsx("title",{children:`${getLumenChartCategoryLabel(alignedSeries,point.x,formatCategory,"detail")} \xB7 ${item.label}: ${formatValue(point.y??0)}`})},point.id??getChartCategoryKey(point.x))),onDatumActivate&&geometry.points.map((point,pointIndex)=>_jsx("circle",{className:"ui-chart__datum-hit",cx:point.xCoordinate,cy:point.yCoordinate,r:"10","data-ui-chart-datum":pointActions[index]?.[pointIndex]?.serialized},point.id??getChartCategoryKey(point.x)))]},item.id)})]}),model.annotationMarks.map(mark=>_jsx("g",{className:composeClassName("ui-chart__annotation",getLumenChartToneClassName(mark.tone)),children:mark.axis==="x"?_jsxs(_Fragment,{children:[_jsx("line",{x1:mark.coordinate,x2:mark.coordinate,y1:padding,y2:height-padding}),_jsx("text",{x:mark.coordinate+4,y:padding-8,children:mark.label})]}):_jsxs(_Fragment,{children:[_jsx("line",{x1:paddingLeft,x2:width-padding,y1:mark.coordinate,y2:mark.coordinate}),_jsx("text",{textAnchor:"end",x:width-padding,y:mark.coordinate-8,children:mark.label})]})},mark.id)),interactive&&_jsx("line",{className:"ui-chart__crosshair","data-ui-chart-crosshair":!0,style:{display:"none"},y1:padding,y2:height-padding})]})}),model.annotationMarks.length>0&&_jsx("ul",{className:"ui-sr-only",children:model.annotationMarks.map(mark=>_jsxs("li",{children:[mark.label,":"," ",mark.axis==="x"?getLumenChartCategoryLabel(alignedSeries,mark.value,formatCategory,"detail"):formatValue(Number(mark.value))]},mark.id))}),interactive&&hasData&&_jsx(ChartInspection,{model,...formatCategory?{formatCategory}:{},formatValue,labels:resolvedLabels})]}),showTable&&hasData&&_jsx(ChartDataTable,{categories,...formatCategory===void 0?{}:{formatCategory},formatValue,labels:resolvedLabels,series}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},PieChart=({centerLabel,centerValue,className,onDatumActivate,labels,series=emptyPieSeries,showLegend=!0,showTable=!0,summary,valueFormatter=String,variant="donut",...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),geometry=createLumenPieGeometry(series.data,{variant}),hasData=hasLumenPieData(series.data),renderedSeries={...series,data:series.data.filter(datum=>datum.y!==null&&Number.isFinite(datum.y)&&datum.y>0)},hasCenterLabel=centerLabel!=null,hasCenterValue=centerValue!=null,datumActions=onDatumActivate?geometry.slices.map((slice,index)=>{const datum=renderedSeries.data[index];return datum?createReactChartDatumAction(createLumenChartDatumActivation(series.id,datum),`${slice.label} \xB7 ${series.label}: ${valueFormatter(slice.value)}`,resolvedLabels):null}):[];return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-pie-chart",getLumenPieChartVariantClassName(variant),className),summary:summary??formatLumenChartSummary([renderedSeries],valueFormatter,resolvedLabels),...props,children:[showLegend&&hasData&&_jsx("ul",{"aria-label":resolvedLabels.chartLegend,className:"ui-chart__legend",children:geometry.slices.map(slice=>_jsxs("li",{className:getLumenChartToneClassName(slice.tone),children:[_jsx("span",{"aria-hidden":"true"}),slice.label]},`${typeof slice.x}:${String(slice.x)}`))}),!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:resolvedLabels.empty}),_jsxs("div",{className:"ui-chart__plot ui-pie-chart__plot",hidden:!hasData,children:[_jsx("svg",{"aria-hidden":"true",preserveAspectRatio:"xMidYMid meet",viewBox:`0 0 ${geometry.size} ${geometry.size}`,children:_jsx("g",{className:"ui-pie-chart__slices",children:geometry.slices.map((slice,index)=>_jsx("path",{className:getLumenChartToneClassName(slice.tone),"data-ui-chart-datum":datumActions[index]?.serialized,d:slice.path,fillRule:"evenodd",children:_jsx("title",{children:`${slice.label}: ${valueFormatter(slice.value)} (${formatChartPercentage(slice.percentage)})`})},`${typeof slice.x}:${String(slice.x)}`))})}),variant==="donut"&&(hasCenterLabel||hasCenterValue)&&_jsxs(_Fragment,{children:[_jsxs("div",{"aria-hidden":"true",className:"ui-pie-chart__center",children:[hasCenterValue&&_jsx("strong",{children:centerValue}),hasCenterLabel&&_jsx("span",{children:centerLabel})]}),_jsxs("div",{className:"ui-sr-only",children:[centerValue," ",centerLabel]})]})]}),showTable&&hasData&&_jsxs("details",{className:"ui-chart__data",children:[_jsx("summary",{children:resolvedLabels.viewData}),_jsx("div",{"aria-label":resolvedLabels.chartData,role:"group",tabIndex:0,children:_jsxs("table",{children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{scope:"col",children:resolvedLabels.category}),_jsx("th",{scope:"col",children:resolvedLabels.value}),_jsx("th",{scope:"col",children:"Share"})]})}),_jsx("tbody",{children:geometry.slices.map(slice=>_jsxs("tr",{children:[_jsx("th",{scope:"row",children:slice.label}),_jsx("td",{children:valueFormatter(slice.value)}),_jsx("td",{children:formatChartPercentage(slice.percentage)})]},`${typeof slice.x}:${String(slice.x)}`))})]})})]}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},emptyScatterReferences=[],ScatterPlotClip=({children,width,height})=>{const plotId=useId();return _jsxs(_Fragment,{children:[_jsx("defs",{children:_jsx("clipPath",{id:plotId,children:_jsx("rect",{x:"44",y:"44",width:width-88,height:height-88})})}),_jsx("g",{clipPath:`url(#${plotId})`,children})]})},ScatterChart=({className,onDatumActivate,formatValue=String,formatX=String,formatY=formatValue,xDomain,domain,references=emptyScatterReferences,labels,series=emptyChartSeries,showLegend=series.length>1,showTable=!0,summary,xScale="linear",...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),geometry=createLumenScatterGeometry(series,{xScale,...xDomain?{xDomain}:{},...domain?{domain}:{}}),referenceGeometry=createLumenScatterReferences(references,geometry,xScale),renderedSeries=series.map(item=>({...item,data:geometry.points.filter(point=>point.seriesId===item.id)})).filter(item=>item.data.length>0),hasData=geometry.points.length>0,datumActions=onDatumActivate?geometry.points.map(point=>createReactChartDatumAction(createLumenChartDatumActivation(point.seriesId,point),`${point.xLabel??formatX(point.x)} \xB7 ${point.seriesLabel}: ${point.label??formatY(point.y??0)}`,resolvedLabels)):[];return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-scatter-chart",className),summary:summary??formatLumenChartSummary(renderedSeries,formatY,resolvedLabels),...props,children:[showLegend&&hasData&&_jsx(ChartLegend,{label:resolvedLabels.chartLegend,series}),!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:resolvedLabels.empty}),_jsx("div",{"aria-label":resolvedLabels.chartData,className:"ui-chart__plot",role:"region",tabIndex:0,hidden:!hasData,children:_jsxs("svg",{"aria-hidden":"true",viewBox:`0 0 ${geometry.width} ${geometry.height}`,children:[_jsxs(ScatterPlotClip,{width:geometry.width,height:geometry.height,children:[_jsx("g",{className:"ui-scatter-chart__references",children:referenceGeometry.map(reference=>reference.region?_jsx("rect",{x:Math.min(reference.x1,reference.x2),y:Math.min(reference.y1,reference.y2),width:Math.abs(reference.x2-reference.x1),height:Math.abs(reference.y2-reference.y1),children:_jsx("title",{children:reference.label})},reference.id):_jsx("line",{x1:reference.x1,x2:reference.x2,y1:reference.y1,y2:reference.y2,children:_jsx("title",{children:reference.label})},reference.id))}),_jsx("g",{className:"ui-scatter-chart__marks",children:geometry.points.map((point,pointIndex)=>_jsx("circle",{"data-ui-chart-datum":datumActions[pointIndex]?.serialized,className:getLumenChartToneClassName(point.tone),cx:point.xCoordinate,cy:point.yCoordinate,r:point.radius,children:_jsx("title",{children:`${point.xLabel??formatX(point.x)} \xB7 ${point.seriesLabel}: ${point.label??formatY(point.y??0)}`})},`${point.seriesId}:${point.id??`${getChartCategoryKey(point.x)}:${pointIndex}`}`))})]}),onDatumActivate&&geometry.points.map((point,index)=>point.xCoordinate>=44&&point.xCoordinate<=geometry.width-44&&point.yCoordinate>=44&&point.yCoordinate<=geometry.height-44?_jsx("circle",{className:"ui-chart__datum-hit",cx:point.xCoordinate,cy:point.yCoordinate,r:Math.max(10,point.radius),"data-ui-chart-datum":datumActions[index]?.serialized},`${point.seriesId}:${point.id??getChartCategoryKey(point.x)}`):null)]})}),referenceGeometry.length>0&&_jsx("ul",{className:"ui-scatter-chart__reference-labels",children:referenceGeometry.map(reference=>_jsx("li",{children:reference.label},reference.id))}),showTable&&hasData&&_jsxs("details",{className:"ui-chart__data",children:[_jsx("summary",{children:resolvedLabels.viewData}),_jsx("div",{"aria-label":resolvedLabels.chartData,role:"group",tabIndex:0,children:_jsxs("table",{children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{scope:"col",children:resolvedLabels.x}),_jsx("th",{scope:"col",children:resolvedLabels.series}),_jsx("th",{scope:"col",children:resolvedLabels.value}),_jsx("th",{scope:"col",children:resolvedLabels.size})]})}),_jsx("tbody",{children:geometry.points.map((point,pointIndex)=>_jsxs("tr",{children:[_jsx("th",{scope:"row",children:point.xLabel??formatX(point.x)}),_jsx("td",{children:point.seriesLabel}),_jsx("td",{children:point.label??formatY(point.y??0)}),_jsx("td",{children:formatReactChartTableValue(point.size,formatValue,resolvedLabels.notAvailable)})]},`${point.seriesId}:${point.id??`${getChartCategoryKey(point.x)}:${pointIndex}`}`))})]})})]}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},Heatmap=({onDatumActivate,colorScale="sequential",midpoint=0,domain,showLegend=!0,className,data=emptyHeatmapData,formatValue=String,labels,showTable=!0,summary,...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),geometry=createLumenHeatmapModel(data,{colorScale,midpoint,...domain?{domain}:{}}),availableCells=geometry.cells.filter(cell=>cell.value!==null&&Number.isFinite(cell.value)),hasData=availableCells.length>0,datumActions=onDatumActivate?availableCells.map(cell=>createReactChartDatumAction(createLumenHeatmapDatumActivation(cell),`${cell.xLabel??cell.x} \xB7 ${cell.yLabel??cell.y}: ${cell.label??formatValue(cell.value??0)}`,resolvedLabels)):[],datumActionByCell=new Map(availableCells.map((cell,index)=>[cell,datumActions[index]]));return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-heatmap",className),summary:summary??resolvedLabels.formatHeatmapSummary(availableCells.length),...props,children:[!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:resolvedLabels.empty}),_jsx("div",{"aria-label":getChartPlotLabel(props["aria-label"],props.heading,resolvedLabels.chartData),className:"ui-chart__plot",role:"region",tabIndex:0,hidden:geometry.cells.length===0,children:_jsxs("svg",{"aria-hidden":"true",viewBox:`0 0 ${geometry.width} ${geometry.height}`,children:[_jsxs("g",{className:"ui-chart__axis-labels",children:[geometry.xTicks.map(tick=>_jsx("text",{textAnchor:tick.textAnchor,x:tick.position,y:"298",children:tick.label},tick.index)),geometry.yTicks.map(tick=>_jsx("text",{className:"ui-heatmap__row-label",textAnchor:"end",dominantBaseline:"middle",x:"108",y:tick.position,children:tick.label},getChartCategoryKey(tick.value)))]}),_jsx("g",{className:"ui-heatmap__cells",children:geometry.cells.map(cell=>{const missing=cell.value===null||!Number.isFinite(cell.value);return _jsxs("g",{children:[_jsx("rect",{"data-ui-chart-datum":datumActionByCell.get(cell)?.serialized,height:Math.max(0,cell.height-2),width:Math.max(0,cell.width-2),x:cell.xCoordinate+1,y:cell.yCoordinate+1,style:{fill:getLumenHeatmapColor(cell.value,geometry.domain,colorScale,geometry.midpoint)},children:_jsx("title",{children:`${cell.xLabel??cell.x} \xB7 ${cell.yLabel??cell.y}: ${missing?resolvedLabels.notAvailable:cell.label??formatValue(cell.value??0)}`})}),missing&&_jsx("text",{className:"ui-heatmap__missing",textAnchor:"middle",dominantBaseline:"middle",x:cell.xCoordinate+cell.width/2,y:cell.yCoordinate+cell.height/2,children:"\xD7"})]},JSON.stringify([cell.x,cell.y]))})})]})}),showLegend&&geometry.cells.length>0&&_jsxs("div",{className:"ui-heatmap__legend","aria-label":resolvedLabels.chartLegend,children:[_jsx("span",{children:formatValue(geometry.domain.min)}),_jsx("span",{style:{background:geometry.legendBackground},className:"ui-heatmap__scale",children:colorScale==="diverging"&&_jsx("span",{style:{left:`${geometry.midpointPercent}%`},children:formatValue(geometry.midpoint)})}),_jsx("span",{children:formatValue(geometry.domain.max)}),_jsxs("span",{children:["\xD7",resolvedLabels.notAvailable]})]}),showTable&&_jsxs("details",{className:"ui-chart__data",children:[_jsx("summary",{children:resolvedLabels.viewData}),_jsx("div",{"aria-label":resolvedLabels.chartData,role:"group",tabIndex:0,children:_jsxs("table",{children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{scope:"col",children:resolvedLabels.column}),_jsx("th",{scope:"col",children:resolvedLabels.row}),_jsx("th",{scope:"col",children:resolvedLabels.value})]})}),_jsx("tbody",{children:geometry.cells.map(cell=>_jsxs("tr",{children:[_jsx("th",{scope:"row",children:cell.xLabel??cell.x}),_jsx("td",{children:cell.yLabel??cell.y}),_jsx("td",{children:cell.label??(cell.value===null||!Number.isFinite(cell.value)?resolvedLabels.notAvailable:formatValue(cell.value))})]},cell.id??`${getChartCategoryKey(cell.x)}:${getChartCategoryKey(cell.y)}`))})]})})]}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},RangeChart=({className,onDatumActivate,data=emptyRangeData,formatValue=String,labels,showTable=!0,summary,tone="series-1",...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),width=640,height=320,padding=44,geometry=createLumenRangeGeometry(data,{height,padding,width}),categoryTicks=getLumenChartCategoryTicks(geometry.points.map(point=>String(point.xLabel??point.x)),{start:padding,end:width-padding,positions:geometry.points.map(point=>point.xCoordinate)}),ticks=getLumenChartTicks(geometry.domain),datumActions=onDatumActivate?geometry.points.map(point=>createReactChartDatumAction(createLumenRangeDatumActivation(point),`${point.xLabel??point.x}: ${point.label??`${formatValue(point.low??0)}\u2013${formatValue(point.high??0)}`}`,resolvedLabels)):[];return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-range-chart",getLumenChartToneClassName(tone),className),summary:summary??resolvedLabels.formatRangeSummary(geometry.points.length),...props,children:[geometry.points.length===0&&_jsx("p",{className:"ui-chart__empty",role:"status",children:resolvedLabels.empty}),_jsx("div",{"aria-label":resolvedLabels.chartData,className:"ui-chart__plot",role:"region",tabIndex:0,hidden:geometry.points.length===0,children:_jsxs("svg",{"aria-hidden":"true",viewBox:`0 0 ${width} ${height}`,children:[_jsx("g",{className:"ui-chart__grid",children:ticks.map(tick=>{const y=scaleLumenChartValue(tick,geometry.domain,height-padding,padding);return _jsxs("g",{children:[_jsx("line",{x1:padding,x2:width-padding,y1:y,y2:y}),_jsx("text",{x:padding-8,y,children:formatValue(tick)})]},tick)})}),_jsx("g",{className:"ui-chart__axis-labels",children:categoryTicks.map(tick=>_jsx("text",{x:tick.position,y:height-12,textAnchor:tick.textAnchor,children:tick.label},tick.index))}),_jsx("path",{className:"ui-range-chart__area",d:geometry.areaPath}),geometry.points.map((point,index)=>_jsx("line",{"data-ui-chart-datum":datumActions[index]?.serialized,className:"ui-range-chart__interval",x1:point.xCoordinate,x2:point.xCoordinate,y1:point.highCoordinate,y2:point.lowCoordinate,children:_jsx("title",{children:`${point.xLabel??point.x}: ${point.label??`${formatValue(point.low??0)}\u2013${formatValue(point.high??0)}`}`})},point.id??getChartCategoryKey(point.x))),onDatumActivate&&geometry.points.map((point,index)=>_jsx("rect",{className:"ui-chart__datum-hit",x:point.xCoordinate-10,y:Math.min(point.highCoordinate,point.lowCoordinate)-Math.max(0,20-Math.abs(point.highCoordinate-point.lowCoordinate))/2,width:"20",height:Math.max(20,Math.abs(point.highCoordinate-point.lowCoordinate)),"data-ui-chart-datum":datumActions[index]?.serialized},point.id??getChartCategoryKey(point.x)))]})}),showTable&&_jsxs("details",{className:"ui-chart__data",children:[_jsx("summary",{children:resolvedLabels.viewData}),_jsx("div",{"aria-label":resolvedLabels.chartData,role:"group",tabIndex:0,children:_jsxs("table",{children:[_jsx("thead",{children:_jsxs("tr",{children:[_jsx("th",{scope:"col",children:resolvedLabels.category}),_jsx("th",{scope:"col",children:resolvedLabels.low}),_jsx("th",{scope:"col",children:resolvedLabels.high})]})}),_jsx("tbody",{children:data.map(item=>_jsxs("tr",{children:[_jsx("th",{scope:"row",children:item.xLabel??item.x}),_jsx("td",{children:item.low===null||!Number.isFinite(item.low)?resolvedLabels.notAvailable:formatValue(item.low)}),_jsx("td",{children:item.high===null||!Number.isFinite(item.high)?resolvedLabels.notAvailable:formatValue(item.high)})]},item.id??getChartCategoryKey(item.x)))})]})})]}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},ComboChart=({className,onDatumActivate,formatValue=String,labels,series=emptyComboSeries,showLegend=!0,showTable=!0,summary,...props})=>{const resolvedLabels=resolveLumenChartLabels(labels),width=640,height=320,padding=44,categories=getLumenChartCategories(series),alignedSeries=series.map(item=>({...item,data:alignLumenChartSeries(item,categories).data})),domain=getLumenChartDomain(alignedSeries.flatMap(item=>item.data.map(datum=>datum.y))),barSeries=alignedSeries.filter(item=>item.mark==="bar"),lineSeries=alignedSeries.filter(item=>item.mark!=="bar"),bars=createLumenBarGeometry(barSeries,{domain,height,width}),categoryPositions=new Map(bars.categories.map(category=>[getChartCategoryKey(category.category),category.x])),drawableWidth=width-padding*2,alignComboLineDatum=datum=>barSeries.length===0?datum:{...datum,x:((categoryPositions.get(`${typeof datum.x}:${String(datum.x)}`)??padding)-padding)/drawableWidth},lineGeometryOptions={domain,height,padding,width,...barSeries.length===0?{}:{paddingBottom:bars.margin.bottom,paddingTop:bars.margin.top,xDomain:{max:1,min:0},xScale:"linear"}},lines=lineSeries.map(item=>createLumenLineGeometry(item.data.map(alignComboLineDatum),lineGeometryOptions)),hasData=hasLumenChartData(series),barActions=onDatumActivate?bars.marks.map(mark=>{const item=barSeries.find(candidate=>candidate.id===mark.seriesId),datum=item?.data.find(candidate=>candidate.x===mark.category);return item&&datum?createReactChartDatumAction(createLumenChartDatumActivation(item.id,datum),`${datum.xLabel??datum.x} \xB7 ${item.label}: ${datum.label??formatValue(mark.value)}`,resolvedLabels):null}):[],pointActions=onDatumActivate?lines.map((geometry,index)=>{const item=lineSeries[index];return geometry.points.map(point=>{const datum=item?.data.find(candidate=>alignComboLineDatum(candidate).x===point.x);return item&&datum?createReactChartDatumAction(createLumenChartDatumActivation(item.id,datum),`${datum.xLabel??datum.x} \xB7 ${item.label}: ${datum.label??formatValue(point.y??0)}`,resolvedLabels):null})}):[],plotTop=barSeries.length>0?bars.margin.top:padding,plotBottom=height-(barSeries.length>0?bars.margin.bottom:padding),plotLeft=barSeries.length>0?bars.margin.left:padding,plotRight=width-(barSeries.length>0?bars.margin.right:padding),ticks=getLumenChartTicks(domain),categoryLabels=categories.map(category=>getLumenChartCategoryLabel(series,category)),categoryTicks=getLumenChartCategoryTicks(categoryLabels,{start:plotLeft,end:plotRight,...barSeries.length>0?{positions:bars.categories.map(category=>category.x)}:{}}),datumActions=[...barActions,...pointActions.flat()];return _jsxs(DatumChart,{onDatumActivate,className:composeClassName("ui-combo-chart",className),summary:summary??formatLumenChartSummary(series,formatValue,resolvedLabels),...props,children:[showLegend&&hasData&&_jsx(ChartLegend,{label:resolvedLabels.chartLegend,series}),!hasData&&_jsx("p",{className:"ui-chart__empty",role:"status",children:resolvedLabels.empty}),_jsx("div",{"aria-label":resolvedLabels.chartData,className:"ui-chart__plot",role:"region",tabIndex:0,hidden:!hasData,children:_jsxs("svg",{"aria-hidden":"true",viewBox:`0 0 ${width} ${height}`,children:[_jsx("g",{className:"ui-chart__grid",children:ticks.map(tick=>{const y=scaleLumenChartValue(tick,domain,plotBottom,plotTop);return _jsxs("g",{children:[_jsx("line",{x1:plotLeft,x2:plotRight,y1:y,y2:y}),_jsx("text",{x:plotLeft-8,y,children:formatValue(tick)})]},tick)})}),_jsx("g",{className:"ui-chart__axis-labels",children:categoryTicks.map(tick=>_jsx("text",{x:tick.position,y:height-12,textAnchor:tick.textAnchor,children:tick.label},tick.index))}),_jsxs("g",{className:"ui-bar-chart__marks",children:[bars.marks.map((mark,index)=>_jsx("rect",{"data-ui-chart-datum":barActions[index]?.serialized,className:getLumenChartToneClassName(mark.tone),height:mark.height,rx:"4",width:mark.width,x:mark.x,y:mark.y,children:_jsx("title",{children:`${mark.seriesLabel}: ${formatValue(mark.value)}`})},`${mark.seriesId}:${getChartCategoryKey(mark.category)}`)),onDatumActivate&&bars.marks.map((mark,index)=>_jsx("rect",{className:"ui-chart__datum-hit",width:Math.max(12,mark.width),height:Math.max(12,mark.height),x:mark.x-Math.max(0,12-mark.width)/2,y:mark.y-Math.max(0,12-mark.height)/2,"data-ui-chart-datum":barActions[index]?.serialized},`${mark.seriesId}:${getChartCategoryKey(mark.category)}`))]}),lines.map((geometry,index)=>{const item=lineSeries[index];if(!item)return null;const tone=resolveLumenChartTone(item.tone,index+barSeries.length);return _jsxs("g",{className:composeClassName("ui-line-chart__series",getLumenChartToneClassName(tone)),children:[item.mark==="area"&&geometry.areaPaths.map(path=>_jsx("path",{className:"ui-line-chart__area",d:path},path)),_jsx("path",{className:"ui-line-chart__line",d:geometry.path}),geometry.points.map(point=>_jsx("circle",{className:"ui-line-chart__point",cx:point.xCoordinate,cy:point.yCoordinate,r:"3.5"},point.id??getChartCategoryKey(point.x))),onDatumActivate&&geometry.points.map((point,pointIndex)=>_jsx("circle",{className:"ui-chart__datum-hit",cx:point.xCoordinate,cy:point.yCoordinate,r:"10","data-ui-chart-datum":pointActions[index]?.[pointIndex]?.serialized},point.id??getChartCategoryKey(point.x)))]},item.id)})]})}),showTable&&hasData&&_jsx(ChartDataTable,{categories,formatValue,labels:resolvedLabels,series}),onDatumActivate&&_jsx(ChartDatumActions,{actions:datumActions,label:resolvedLabels.exploreData})]})},Checkbox=({className,ref,...props})=>_jsx("input",{className:composeClassName("ui-checkbox",className),ref,type:"checkbox",...props}),CheckboxGroup=({children,className,invalid=!1,legend,orientation="vertical",...props})=>_jsxs("fieldset",{"aria-invalid":invalid||void 0,className:composeClassName("ui-checkbox-group",`ui-checkbox-group--${orientation}`,className),"data-invalid":invalid?"true":void 0,"data-orientation":orientation,"data-ui-checkbox-group":!0,...props,children:[legend&&_jsx("legend",{children:legend}),children]}),Collapsible=({className,...props})=>_jsx("details",{className:composeClassName("ui-collapsible",className),"data-ui-collapsible":!0,...props}),renderCodeToken=token=>token.kind?_jsx("span",{className:lumenCodeTokenClassNames[token.kind],children:token.value},`${token.start}-${token.kind}`):token.value,renderCodeChildren=(code,children,language)=>code===void 0?children:tokenizeLumenCode(code,language).map(renderCodeToken),CodeCopyButton=({code,copyLabel,copiedLabel,errorLabel})=>{const{accessibleLabel,handleClick,state}=useCopyFeedback({copiedLabel,errorLabel,getValue:button=>{if(code!==void 0)return code;const content=button.closest("[data-ui-code]")?.querySelector("pre code, code");return content?.innerText??content?.textContent??void 0},label:copyLabel});return _jsxs(_Fragment,{children:[_jsxs("button",{"aria-label":accessibleLabel,className:composeClassName("ui-code__copy",state==="copied"&&"ui-code__copy--copied"),"data-state":state,"data-ui-code-copy":!0,onClick:handleClick,title:accessibleLabel,type:"button",children:[renderLucideIcon("copy","ui-code__copy-icon"),renderLucideIcon("check","ui-code__check-icon")]}),_jsx("span",{"aria-live":"polite",className:"ui-sr-only",role:"status",children:state==="idle"?"":accessibleLabel})]})},codeRegionProps=(wrap,codeLabel)=>wrap?{}:{"aria-label":codeLabel,role:"region",tabIndex:0},decorateCodeRegion=(pre,codeLabel)=>{const generated=new Map,attributes={tabindex:"0",role:"region"};pre.hasAttribute("aria-labelledby")||(attributes["aria-label"]=codeLabel);for(const[name,value]of Object.entries(attributes))pre.hasAttribute(name)||(pre.setAttribute(name,value),generated.set(name,value));const releaseOwnership=records=>{for(const record of records)record.attributeName&&generated.delete(record.attributeName)},Observer=pre.ownerDocument.defaultView?.MutationObserver,observer=Observer?new Observer(releaseOwnership):void 0;return observer?.observe(pre,{attributes:!0,attributeFilter:[...generated.keys()]}),()=>{releaseOwnership(observer?.takeRecords()??[]),observer?.disconnect();for(const[name,value]of generated)pre.getAttribute(name)===value&&pre.removeAttribute(name)}},HighlightedCode=({children,codeLabel,wrap})=>{const containerRef=useRef(null);return useLayoutEffect(()=>{if(wrap||!containerRef.current)return;const restore=[...containerRef.current.querySelectorAll("pre")].map(pre=>decorateCodeRegion(pre,codeLabel));return()=>{for(const cleanup of restore)cleanup()}},[children,codeLabel,wrap]),_jsx("div",{ref:containerRef,children})},resolveCodeLabels=({codeLabel,copyLabel,copiedLabel,errorLabel})=>({codeLabel:codeLabel??"Code example",copyLabel:copyLabel??"Copy code to clipboard",copiedLabel:copiedLabel??"Code copied to clipboard",errorLabel:errorLabel??"Could not copy code. Select and copy it manually."}),renderCodeHeader=({code,copy,copyLabel,copiedLabel,errorLabel,label,language})=>!copy&&!label&&!language?null:_jsxs("figcaption",{className:"ui-code__header",children:[_jsxs("span",{"aria-hidden":"true",className:"ui-code__dots",children:[_jsx("span",{className:"ui-code__dot ui-code__dot--red"}),_jsx("span",{className:"ui-code__dot ui-code__dot--yellow"}),_jsx("span",{className:"ui-code__dot ui-code__dot--green"})]}),_jsxs("span",{className:"ui-code__meta",children:[language&&_jsx("span",{className:"ui-code__language",children:language}),label&&_jsx("span",{className:"ui-code__label",children:label})]}),copy&&_jsx(CodeCopyButton,{code,copiedLabel,copyLabel,errorLabel})]}),Code=({children,className,code,copy=!1,codeLabel,copyLabel,copiedLabel,errorLabel,highlighted=!1,label,language,theme="auto",variant="inline",wrap=!1,...props})=>{const labels=resolveCodeLabels({codeLabel,copyLabel,copiedLabel,errorLabel}),codeChildren=renderCodeChildren(code,children,language);return variant==="block"?_jsxs("figure",{className:composeClassName("ui-code ui-code--block",wrap&&"ui-code--wrap",className),"data-code-theme":theme,"data-language":language,"data-slot":"code","data-ui-code":!0,...props,children:[renderCodeHeader({code,copy,...labels,label,language}),highlighted?_jsx(HighlightedCode,{codeLabel:labels.codeLabel,wrap,children}):_jsx("pre",{...codeRegionProps(wrap,labels.codeLabel),children:_jsx("code",{children:codeChildren})})]}):_jsx("code",{className:composeClassName("ui-code ui-code--inline",className),"data-code-theme":theme,"data-language":language,"data-slot":"code",...props,children:code??children})},resolveCopyText=(button,target,value)=>{if(value!==void 0)return value;if(!target)return;const targetElement=button.ownerDocument.querySelector(target);return targetElement?.innerText??targetElement?.textContent??void 0},resolveCopyFeedback=(content,fallback)=>content??fallback,CopyButton=({children="Copy",className,copiedContent,copiedLabel="Copied to clipboard",errorContent,errorLabel="Could not copy to clipboard",label="Copy to clipboard",onClick,resetAfter=2e3,size="default",target,toast=!1,value,variant="outline",...props})=>{const{accessibleLabel,handleClick,state}=useCopyFeedback({copiedLabel,errorLabel,getValue:button=>resolveCopyText(button,target,value),label,onClick,resetAfter,toast});return _jsxs(Button,{"aria-label":accessibleLabel,className:composeClassName("ui-copy-button",className),"data-slot":"copy-button","data-state":state,"data-ui-copy-button":!0,onClick:handleClick,size,variant,...props,children:[_jsx("span",{"aria-hidden":"true","data-slot":"copy-idle",hidden:state!=="idle",children}),_jsx("span",{"aria-hidden":"true","data-slot":"copy-copied",hidden:state!=="copied",children:resolveCopyFeedback(copiedContent,copiedLabel)}),_jsx("span",{"aria-hidden":"true","data-slot":"copy-error",hidden:state!=="error",children:resolveCopyFeedback(errorContent,errorLabel)})]})};import{Combobox}from"./combobox.js";const Command=({className,glass=!1,...props})=>_jsx("div",{className:composeClassName("ui-command",glassClass("ui-command",glass),className),"data-ui-command":!0,...props}),ContextMenu=({className,glass=!1,...props})=>_jsx("menu",{className:composeClassName("ui-menu",glassSurfaceClass("ui-menu",glass),className),"data-surface":resolveSurface(glass),"data-ui-context-menu":!0,role:props.role??"menu",...props}),ColorPicker=({className,type="color",...props})=>_jsx("input",{className:composeClassName("ui-color-picker",className),type,...props}),formatDatePickerDisplayValue=(value,placeholder,locale,formatDate)=>{const date=parseCalendarDate(value);return!date||!value?placeholder:formatDate?formatDate(value):new Intl.DateTimeFormat(getCalendarLocale(locale||"en"),{day:"numeric",month:"short",timeZone:"UTC",year:"numeric"}).format(date)},stringifyDatePickerConstraint=value=>value===void 0?void 0:String(value),useDatePickerDisclosure=unavailable=>{const[state,setState]=useState({unavailable,open:!1});state.unavailable!==unavailable&&setState({unavailable,open:!1});const setOpen=useCallback(open=>{setState({unavailable,open:open&&!unavailable})},[unavailable]);return{open:state.open&&!unavailable,setOpen}},DatePicker=({className,defaultValue,disabled,formatDate,glass=!1,id,inputRef,labels,locale,max,min,name,onChange,onInvalid,onValueChange,placeholder,readOnly,required,value,...props})=>{const generatedId=useId(),datePickerId=id??generatedId,nativeInputId=`${datePickerId}-native`,popoverId=`${datePickerId}-popover`,rootRef=useRef(null),nativeInputRef=useRef(null),triggerRef=useRef(null),[internalValue,setInternalValue]=useState(defaultValue??""),{open:isOpen,setOpen}=useDatePickerDisclosure(disabled===!0||readOnly===!0),selectedValue=value??internalValue,hasSelectedValue=selectedValue!=="",dateLabels={...resolveDateControlLabels(locale||"en"),...labels},placeholderText=placeholder??dateLabels.chooseDate,maxStr=stringifyDatePickerConstraint(max),minStr=stringifyDatePickerConstraint(min),accessibleLabel=props["aria-label"];useEffect(()=>{const owner=nativeInputRef.current?.form;let active=!0,resetTimer;const reset=event=>{globalThis.clearTimeout(resetTimer),resetTimer=globalThis.setTimeout(()=>{!active||event.defaultPrevented||!nativeInputRef.current?.isConnected||(value===void 0&&setInternalValue(defaultValue??""),setOpen(!1))})};return owner?.addEventListener("reset",reset),()=>{active=!1,globalThis.clearTimeout(resetTimer),owner?.removeEventListener("reset",reset)}},[defaultValue,props.form,value,setOpen]),useEffect(()=>{if(!isOpen)return;const root=rootRef.current;if(!root)return;const owner=root.ownerDocument,handlePointerDown=event=>{event.composedPath().includes(root)||setOpen(!1)};return owner.addEventListener("mousedown",handlePointerDown),rootRef.current?.querySelector('[role="gridcell"][tabindex="0"]')?.focus({preventScroll:!0}),()=>{owner.removeEventListener("mousedown",handlePointerDown)}},[isOpen,setOpen]);const selectDate=nextValue=>{disabled||readOnly||(value===void 0&&setInternalValue(nextValue),onValueChange?.(nextValue),nativeInputRef.current&&(Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set?.call(nativeInputRef.current,nextValue),nativeInputRef.current.dispatchEvent(new Event("input",{bubbles:!0})),nativeInputRef.current.dispatchEvent(new Event("change",{bubbles:!0}))),setOpen(!1),globalThis.setTimeout(()=>triggerRef.current?.focus()))};return _jsxs("div",{className:composeClassName("ui-date-picker-field",glass&&"ui-date-picker-field--glass",glass==="subtle"&&"ui-glass-subtle",glass==="strong"&&"ui-glass-strong",className),"data-placeholder":hasSelectedValue?void 0:"true","data-ui-date-picker":!0,"data-ui-glass-track":glass?!0:void 0,ref:rootRef,onKeyDown:event=>{!isOpen||event.key!=="Escape"||(event.preventDefault(),event.stopPropagation(),setOpen(!1),triggerRef.current?.focus({preventScroll:!0}))},children:[_jsx("input",{"aria-hidden":"true",className:"ui-date-picker ui-date-picker__native","data-ui-date-picker-native":!0,"data-ui-enhanced":"true",disabled,id:nativeInputId,max,min,name,onChange:event=>{value===void 0&&setInternalValue(event.currentTarget.value),onChange?.(event)},onInvalid:event=>{event.preventDefault(),triggerRef.current?.setAttribute("aria-invalid","true"),triggerRef.current?.focus(),onInvalid?.(event)},ref:node=>{nativeInputRef.current=node,setRefValue(inputRef,node)},required,readOnly,tabIndex:-1,type:"date",value:selectedValue,...props}),_jsxs("div",{className:"ui-date-picker__control","data-ui-date-picker-control":!0,children:[_jsxs("button",{"aria-controls":popoverId,"aria-expanded":isOpen,"aria-haspopup":"dialog","aria-label":accessibleLabel,"aria-labelledby":props["aria-labelledby"],"aria-describedby":props["aria-describedby"],"aria-disabled":readOnly?!0:void 0,"aria-required":required??void 0,className:"ui-input ui-date-picker ui-date-picker__trigger","data-ui-date-picker-trigger":!0,disabled,id:datePickerId,onClick:()=>{disabled||readOnly||setOpen(!isOpen)},onKeyDown:event=>{event.key!=="ArrowDown"||disabled||readOnly||(event.preventDefault(),setOpen(!0))},ref:triggerRef,type:"button",children:[_jsx("span",{"data-ui-date-picker-value":!0,children:formatDatePickerDisplayValue(selectedValue,placeholderText,locale,formatDate)}),_jsx("svg",{"aria-hidden":"true",className:"ui-date-picker__icon",fill:"none",viewBox:"0 0 24 24",children:_jsx("path",{d:"M7 2v3M17 2v3M3.5 9h17M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"})})]}),_jsx("div",{"aria-label":dateLabels.chooseDate,className:"ui-date-picker__popover","data-state":isOpen?"open":"closed","data-ui-date-picker-popover":!0,hidden:!isOpen,id:popoverId,role:"dialog",children:_jsx(Calendar,{disabled,readOnly,labels:dateLabels,locale,max:maxStr,min:minStr,onValueChange:selectDate,value:selectedValue})})]})]})},setDateRangeConstraint=(input,property,value)=>{value?input[property]=value:input.removeAttribute(property)},getDateRangeState=(start,end)=>start?end?"complete":"selecting-end":"empty",syncDateRangePickerElement=root=>{const inputs=[...root.querySelectorAll("[data-ui-date-picker-native]")],start=inputs[0],end=inputs.at(-1);if(!(start&&end)||start===end)return{};const datePickers=root.querySelectorAll("[data-ui-date-picker]");datePickers[0]?.setAttribute("data-range-part","start"),datePickers[datePickers.length-1]?.setAttribute("data-range-part","end"),setDateRangeConstraint(end,"min",start.value),setDateRangeConstraint(start,"max",end.value),root.dataset.rangeState=getDateRangeState(start.value,end.value);const range={};return end.value&&(range.end=end.value),start.value&&(range.start=start.value),range},DateRangePicker=({className,onInput,onRangeChange,...props})=>{const rootRef=useRef(null);return useEffect(()=>{rootRef.current&&syncDateRangePickerElement(rootRef.current)}),_jsx("div",{className:composeClassName("ui-date-range-picker",className),"data-ui-date-range-picker":!0,onInput:event=>{onInput?.(event),onRangeChange?.(syncDateRangePickerElement(event.currentTarget))},ref:rootRef,...props})},DialogCloseContext=createContext(null),DialogHeader=({className,...props})=>_jsx("header",{...props,className:composeClassName("ui-dialog-header",className),"data-slot":"dialog-header"}),DialogTitle=({as:Tag="h2",className,...props})=>_jsx(Tag,{...props,className:composeClassName("ui-dialog-title",className),"data-slot":"dialog-title"}),DialogBody=({className,...props})=>_jsx("div",{...props,className:composeClassName("ui-dialog-body",className),"data-slot":"dialog-body"}),DialogFooter=({className,...props})=>_jsx("footer",{...props,className:composeClassName("ui-dialog-footer",className),"data-slot":"dialog-footer"}),DialogClose=({className,onClick,...props})=>{const close=use(DialogCloseContext);return _jsx(Button,{...props,className:composeClassName("ui-dialog-close",className),"data-slot":"dialog-close",onClick:event=>{onClick?.(event),!event.defaultPrevented&&(close?close():event.currentTarget.closest("dialog")?.close())}})},Dialog=({children,className,defaultOpen,dismissOnEscape,dismissOnOutsidePress,glass=!1,layout="centered",onCancel,onClick,onClose,onOpenChange,onPointerDown,open,...props})=>{const dialog=useDialog({defaultOpen,dismissOnEscape,dismissOnOutsidePress,onOpenChange,open});return _jsx("dialog",{...dialog.dialogProps,...props,className:composeClassName("ui-dialog",layout==="fullscreen"&&"ui-dialog--fullscreen",glassSurfaceClass("ui-dialog",glass),className),"data-layout":layout,"data-surface":resolveSurface(glass),onCancel:composeHandlers(onCancel,dialog.dialogProps.onCancel),onPointerDown:composeHandlers(onPointerDown,dialog.dialogProps.onPointerDown),onClick:composeHandlers(onClick,dialog.dialogProps.onClick),onClose:composeHandlers(onClose,dialog.dialogProps.onClose),children:_jsx(DialogCloseContext,{value:dialog.close,children})})},Drawer=({className,glass=!1,...props})=>_jsx("dialog",{className:composeClassName("ui-drawer",glassSurfaceClass("ui-drawer",glass),className),"data-surface":resolveSurface(glass),"data-ui-drawer":!0,...props}),DropdownMenu=({children,className,collisionPadding,defaultOpen,glass=!1,offset,onOpenChange,open,placement,positioning,...props})=>{const menu=useDropdownMenu({collisionPadding,defaultOpen,offset,onOpenChange,open,placement,positioning});return _jsx(DropdownMenuContext,{value:menu,children:_jsx("menu",{...menu.rootProps,...props,className:composeClassName("ui-menu",glassSurfaceClass("ui-menu",glass),className),"data-surface":resolveSurface(glass),"data-ui-dropdown-menu":!0,children})})},DropdownMenuTrigger=({onClick,onKeyDown,...props})=>{const menu=requireContext(use(DropdownMenuContext),"DropdownMenuTrigger");return _jsx("button",{...menu.triggerProps,...props,onClick:composeHandlers(onClick,menu.triggerProps.onClick),onKeyDown:composeHandlers(onKeyDown,menu.triggerProps.onKeyDown),type:props.type??"button"})},DropdownMenuContent=({className,onKeyDown,...props})=>{const menu=requireContext(use(DropdownMenuContext),"DropdownMenuContent");return _jsx("div",{...menu.panelProps,...props,className:composeClassName("ui-menu__content",className),onKeyDown:composeHandlers(onKeyDown,menu.panelProps.onKeyDown),role:props.role??"menu"})},DropdownMenuItem=({children,className,disabled=!1,onClick,status,...props})=>{const menu=requireContext(use(DropdownMenuContext),"DropdownMenuItem");return _jsxs("button",{...props,"aria-disabled":disabled||void 0,className:composeClassName("ui-menu__item",className),disabled,onClick:event=>{onClick?.(event),!event.defaultPrevented&&!disabled&&menu.close()},role:props.role??"menuitem",type:props.type??"button",children:[_jsx("span",{className:"ui-menu__item-label",children}),status&&_jsx("span",{className:"ui-menu__item-status",children:status})]})},DropdownMenuSeparator=({className,...props})=>_jsx("div",{className:composeClassName("ui-menu__separator",className),role:props.role??"separator",...props}),Empty=({className,glass=!1,variant="default",...props})=>_jsx("section",{className:composeClassName("ui-empty",variant==="compact"&&"ui-empty--compact",glassClass("ui-empty",glass),className),"data-variant":variant,...props}),renderIllustrationElement=(element,index)=>{if(element.kind==="circle")return _jsx("circle",{cx:element.cx,cy:element.cy,r:element.r},index);if(element.kind==="rounded-rect")return _jsx("rect",{height:element.height,rx:element.radius,width:element.width,x:element.x,y:element.y},index);const pointPairs=[];for(let pointIndex=0;pointIndex<element.points.length;pointIndex+=2){const x=element.points[pointIndex],y=element.points[pointIndex+1];if(x===void 0||y===void 0)break;pointPairs.push(`${x},${y}`)}return createElement(element.kind,{key:index,points:pointPairs.join(" ")})},Illustration=({className,label,size="md",tone="auto",variant="empty",...props})=>_jsx("span",{"aria-hidden":label?void 0:!0,"aria-label":label,className:composeClassName("ui-illustration",`ui-illustration--${variant}`,`ui-illustration--${tone}`,`ui-illustration--${size}`,className),role:label?"img":void 0,...props,children:_jsxs("svg",{"aria-hidden":"true",fill:"none",viewBox:"0 0 120 120",children:[_jsx("circle",{className:"ui-illustration__wash",cx:"60",cy:"60",r:"48"}),lumenIllustrations[variant].elements.map(renderIllustrationElement)]})}),resolveErrorStateAnnouncement=(announce,ariaLive,role)=>announce==="assertive"?{"aria-live":ariaLive??"assertive",role:role??"alert"}:announce==="polite"?{"aria-live":ariaLive??"polite",role:role??"status"}:{...ariaLive?{"aria-live":ariaLive}:{},...role?{role}:{}},ErrorStateGraphic=({graphic,kind,layout})=>graphic===!1?null:_jsx("div",{"aria-hidden":"true",className:"ui-error-state__graphic","data-slot":"error-state-graphic",children:graphic??_jsx(Illustration,{size:layout==="compact"?"sm":"md",variant:kind})}),ErrorStateContent=({children,description,headingLevel,reference,referenceLabel,title,titleId})=>_jsxs("div",{className:"ui-error-state__content","data-slot":"error-state-content",children:[createElement(`h${headingLevel}`,{className:"ui-error-state__title","data-slot":"error-state-title",id:titleId},title),description&&_jsx("p",{className:"ui-error-state__description","data-slot":"error-state-description",children:description}),children&&_jsx("div",{className:"ui-error-state__details","data-slot":"error-state-details",children}),reference&&_jsxs("p",{className:"ui-error-state__reference","data-slot":"error-state-reference",children:[_jsxs("span",{children:[referenceLabel,":"]})," ",_jsx("code",{children:reference})]})]}),ErrorStateActions=({actions})=>actions?_jsx("div",{className:"ui-error-state__actions","data-slot":"error-state-actions",children:actions}):null,ErrorState=({"aria-live":ariaLive,actions,announce,children,className,description,graphic,headingLevel,id,kind,layout,reference,referenceLabel,role,title,...props})=>{const resolvedAnnounce=announce??"off",resolvedHeadingLevel=headingLevel??2,resolvedKind=kind??"error",resolvedLayout=layout??"default",resolvedReferenceLabel=referenceLabel??"Reference",titleId=id?`${id}-title`:void 0,announcementProps=resolveErrorStateAnnouncement(resolvedAnnounce,ariaLive,role);return _jsxs("section",{"aria-label":titleId?void 0:title,"aria-labelledby":titleId,className:composeClassName("ui-error-state",`ui-error-state--${resolvedKind}`,`ui-error-state--${resolvedLayout}`,className),"data-kind":resolvedKind,"data-layout":resolvedLayout,"data-ui-error-state":!0,id,...announcementProps,...props,children:[_jsx(ErrorStateGraphic,{graphic,kind:resolvedKind,layout:resolvedLayout}),_jsx(ErrorStateContent,{description,headingLevel:resolvedHeadingLevel,reference,referenceLabel:resolvedReferenceLabel,title,titleId,children}),_jsx(ErrorStateActions,{actions})]})},KanbanBoard=({className,tabIndex=0,...props})=>_jsx("section",{"aria-orientation":"horizontal",className:composeClassName("ui-kanban-board ui-kanban",className),"data-ui-kanban":!0,tabIndex,...props}),KanbanColumn=({className,value,...props})=>_jsx("section",{className:composeClassName("ui-kanban__column",className),"data-ui-kanban-column":value,...props}),ErrorSummary=({className,errors,heading="There is a problem",id="ui-error-summary",...props})=>{const normalizedErrors=normalizeLumenFormErrors(errors),allErrors=[...normalizedErrors.form.map(message=>({message})),...normalizedErrors.fields],headingId=`${id}-heading`;return _jsxs("section",{"aria-labelledby":headingId,className:composeClassName("ui-error-summary",className),"data-ui-error-summary":!0,hidden:allErrors.length===0,id,tabIndex:-1,...props,children:[_jsx("h2",{id:headingId,children:heading}),_jsx("ul",{children:allErrors.map(error=>_jsx("li",{children:error.controlId?_jsx("a",{href:`#${error.controlId}`,children:error.message}):error.message},`${error.name??"form"}:${error.controlId??""}:${error.message}`))})]})},Field=({"aria-describedby":ariaDescribedby,className,controlId,describedBy,glass=!1,invalid=!1,...props})=>{const fieldDescribedBy=[ariaDescribedby,describedBy].filter(Boolean).join(" ")||void 0;return _jsx("div",{"aria-describedby":ariaDescribedby,className:composeClassName("ui-field",glassClass("ui-field",glass),className),"data-invalid":invalid?"true":void 0,"data-ui-field":!0,"data-ui-field-control":controlId,"data-ui-field-describedby":fieldDescribedBy,...props})},FieldError=({children,className,hidden,message,...props})=>{const content=message??children;return _jsx("p",{className:composeClassName("ui-field-error",className),"data-ui-field-error":!0,hidden:hidden??!content,...props,children:content})},Form=({"aria-busy":ariaBusy,className,enhance=!1,status="idle",...props})=>_jsx("form",{"aria-busy":ariaBusy??(status==="submitting"?!0:void 0),className:composeClassName("ui-form",className),"data-status":status,"data-ui-form":enhance?!0:void 0,...props}),HoverCard=({className,glass=!1,...props})=>_jsx("aside",{className:composeClassName("ui-hover-card",glassSurfaceClass("ui-hover-card",glass),className),"data-surface":resolveSurface(glass),"data-ui-hover-card":!0,...props}),Icon=({name,...props})=>_jsx(IconView,{...props,icon:name?getLumenIcon(name):void 0}),getPasswordFieldDescribedBy=(ariaDescribedBy,hintId,errorId)=>[ariaDescribedBy,hintId,errorId].filter(Boolean).join(" ")||void 0,usePasswordVisibility=inputRef=>{const[visible,setVisible]=useState(!1);return useEffect(()=>{const form=inputRef.current?.form;if(!form)return;const handleReset=()=>{setVisible(!1)},hideAfterSuccess=()=>{form.dataset.status==="success"&&setVisible(!1)};form.addEventListener("reset",handleReset);const observer=new MutationObserver(hideAfterSuccess);return observer.observe(form,{attributeFilter:["data-status"],attributes:!0}),()=>{form.removeEventListener("reset",handleReset),observer.disconnect()}},[inputRef]),{toggleVisibility:()=>{setVisible(current=>!current),inputRef.current?.focus({preventScroll:!0})},visible}},PasswordFieldControl=({controlId,describedBy,error,forwardedRef,hideLabel,inputProps,inputRef,name,showLabel,toggleVisibility,visible})=>_jsxs("div",{className:"ui-password-field__control","data-ui-password-field":!0,children:[_jsx(Input,{...inputProps,"aria-describedby":describedBy,"aria-invalid":error?!0:void 0,id:controlId,name,ref:node=>{inputRef.current=node,setRefValue(forwardedRef,node)},type:visible?"text":"password"}),_jsx(Button,{"aria-controls":controlId,"aria-label":visible?hideLabel:showLabel,"aria-pressed":visible,"data-ui-password-toggle":!0,onClick:toggleVisibility,size:"icon",type:"button",variant:"ghost",children:_jsx("span",{"aria-hidden":"true",children:visible?"Hide":"Show"})})]}),PasswordFieldMessages=({error,errorId,hint,hintId})=>_jsxs(_Fragment,{children:[hint&&_jsx("p",{className:"ui-field__hint","data-ui-field-hint":!0,id:hintId,children:hint}),_jsx(FieldError,{id:errorId,message:error})]}),PasswordField=({"aria-describedby":ariaDescribedby,className,error,hideLabel="Hide password",hint,id,label="Password",name,ref,showLabel="Show password",...props})=>{const generatedId=useId(),controlId=id??`ui-password-${generatedId}`,hintId=hint?`${controlId}-hint`:void 0,errorId=`${controlId}-error`,describedBy=getPasswordFieldDescribedBy(ariaDescribedby,hintId,error?errorId:void 0),inputRef=useRef(null),{toggleVisibility,visible}=usePasswordVisibility(inputRef);return _jsxs(Field,{className:composeClassName("ui-password-field",className),controlId,invalid:!!error,...describedBy?{describedBy}:{},children:[_jsx(Label,{htmlFor:controlId,children:label}),_jsx(PasswordFieldControl,{controlId,describedBy,error,forwardedRef:ref,hideLabel,inputProps:props,inputRef,name,showLabel,toggleVisibility,visible}),_jsx(PasswordFieldMessages,{error,errorId,hint,hintId})]})},InputGroup=({className,...props})=>_jsx("div",{className:composeClassName("ui-input-group",className),...props}),InputOTP=({"aria-invalid":ariaInvalid,className,defaultValue,disabled=!1,inputClassName,inputMode="numeric",length=6,maxLength=length,pattern="[0-9]*",ref,value,...props})=>{const otp=useInputOTP({defaultValue:toInputValue(defaultValue),disabled,inputMode,inputRef:ref,invalid:ariaInvalid===!0||ariaInvalid==="true",length,pattern,value:toInputValue(value)});return _jsxs("div",{...otp.rootProps,className:composeClassName(otp.rootProps.className,className),children:[_jsx("input",{...otp.getInputProps({...props,"aria-invalid":ariaInvalid,className:inputClassName,disabled,inputMode,maxLength,pattern})}),_jsx("div",{...otp.segmentsProps,children:otp.segmentIndexes.map(index=>_jsx("button",{...otp.getSegmentProps(index),type:"button",children:_jsx("span",{"data-ui-input-otp-char":!0,children:otp.getSegmentChar(index)})},index))})]})},NumberField=({className,ref,type="number",...props})=>_jsx("input",{className:composeClassName("ui-input ui-number-field",className),ref,type,...props}),Item=({as="div",className,glass=!1,...props})=>createElement(as,{className:composeClassName("ui-item",glassClass("ui-item",glass),className),"data-slot":"item",...props}),Kbd=({className,...props})=>_jsx("kbd",{className:composeClassName("ui-kbd",className),...props}),Marker=({className,variant="default",...props})=>_jsx("span",{className:composeClassName("ui-marker",variantClass("ui-marker",variant),className),"data-variant":variant,...props}),Menubar=({className,glass=!1,...props})=>_jsx("nav",{className:composeClassName("ui-menubar",glassSurfaceClass("ui-menubar",glass),className),"data-surface":resolveSurface(glass),"data-ui-menubar":!0,...props}),Message=({className,from="assistant",...props})=>_jsx("article",{className:composeClassName("ui-message",`ui-message--${from}`,className),"data-from":from,...props}),MessageScroller=({className,glass=!1,autoScroll=!1,scrollThreshold=32,...props})=>{const rootRef=useRef(null);return useEffect(()=>{const root=rootRef.current;return!root||!autoScroll?void 0:createLumenMessageScrollerController(root,{threshold:scrollThreshold}).destroy},[autoScroll,scrollThreshold]),_jsx("div",{ref:rootRef,className:composeClassName("ui-message-scroller",glassClass("ui-message-scroller",glass),className),...props})},NativeSelect=({children,className,defaultValue,options=emptyOptions,placeholder,ref,value,visualSize="default",...props})=>{const placeholderDefaultValue=placeholder&&value===void 0&&defaultValue===void 0?"":void 0;return _jsxs("select",{className:composeClassName("ui-select",visualSize==="sm"&&"ui-select--sm",visualSize==="lg"&&"ui-select--lg",className),defaultValue:defaultValue??placeholderDefaultValue,ref,value,...props,children:[placeholder&&_jsx("option",{disabled:!0,value:"",children:placeholder}),children,options.map(normalizeOption).map(option=>_jsx("option",{disabled:option.disabled,value:option.value,children:option.label},option.value))]})},emptyPhoneInputProps={},phoneInputSizeModifiers=visualSize=>visualSize==="sm"?{inputClass:"ui-input--sm",selectClass:"ui-select--sm"}:visualSize==="lg"?{inputClass:"ui-input--lg",selectClass:"ui-select--lg"}:{inputClass:void 0,selectClass:void 0},getPhoneInputOptions=locale=>locale===void 0?{}:{locale},getBooleanAttribute=value=>value?!0:void 0,CountryFlag=({regionCode,decorative=!1,className,...props})=>{const source=getLumenPhoneFlagSource(regionCode);return _jsx("span",{...props,"aria-hidden":decorative||void 0,"aria-label":decorative?void 0:props["aria-label"]??regionCode.toUpperCase(),className:composeClassName("ui-country-flag",className),"data-slot":"country-flag",role:decorative?void 0:"img",children:source?_jsx("img",{alt:"",height:18,src:source,width:24}):regionCode.toUpperCase().slice(0,2)})},PhoneNumber=({value,link=!1,className,...props})=>{const content=_jsxs(_Fragment,{children:[_jsx(CountryFlag,{decorative:!0,regionCode:value.country.regionCode}),_jsx("span",{children:formatLumenPhoneNumber(value)||"\u2014"})]}),classes=composeClassName("ui-phone-number",className);return link&&value.isValid&&value.e164?_jsx("a",{...props,className:classes,href:`tel:${value.e164}`,title:value.country.displayName,children:content}):_jsx("span",{...props,className:classes,title:value.country.displayName,children:content})},resolvePhoneError=(errorMessage,showValidationError,value,invalidNumberMessage)=>{if(errorMessage)return errorMessage;if(showValidationError&&value.nationalNumber.length>0&&!value.isValid)return invalidNumberMessage},resolvePhoneAria=(inputProps,invalid,errorId)=>({"aria-describedby":[inputProps["aria-describedby"],invalid?errorId:void 0].filter(Boolean).join(" ")||void 0,"aria-errormessage":invalid?errorId:inputProps["aria-errormessage"],"aria-invalid":invalid?!0:inputProps["aria-invalid"]}),PhoneNumberInput=({controlId,errorId,hasExplicitId,inputClass,inputProps,inputRef,invalid,isDisabled,isReadOnly,name,numberRef,onChange,phoneValue,placeholder,required})=>_jsx("input",{...inputProps,...resolvePhoneAria(inputProps,invalid,errorId),autoComplete:inputProps.autoComplete??"tel-national","aria-label":inputProps["aria-label"]??(hasExplicitId?void 0:placeholder),className:composeClassName("ui-input ui-phone-input__number",inputClass,inputProps.className),disabled:isDisabled,id:controlId,inputMode:"tel",name,onChange,placeholder,readOnly:isReadOnly,ref:node=>{numberRef.current=node,setRefValue(inputRef,node)},required:required??inputProps.required,type:"tel",value:phoneValue.nationalNumber}),PhoneCountryValue=({disabled,readOnly,form,name,value})=>readOnly&&!disabled?_jsx("input",{form,name,type:"hidden",value}):null,MetadataPhoneInput=({className,countryOptions,countryLabel,countryName,disabled,readOnly,required,errorMessage,id,inputProps=emptyPhoneInputProps,inputRef,defaultCountryValue,defaultValue,invalidNumberMessage,locale,name,onValueChange,placeholder,showValidationError,visualSize,value,...props})=>{const{selectClass,inputClass}=phoneInputSizeModifiers(visualSize),isDisabled=[disabled,inputProps.disabled].some(Boolean),isReadOnly=[readOnly,inputProps.readOnly].some(Boolean),generatedId=useId(),controlId=id??inputProps.id??generatedId,errorId=`${generatedId}-error`,numberRef=useRef(null),selectRef=useRef(null),phoneOptions=useMemo(()=>getPhoneInputOptions(locale),[locale]),metadataCountries=useMemo(()=>countryOptions??getLumenPhoneCountries(phoneOptions),[countryOptions,phoneOptions]),initialCountry=useMemo(()=>resolveReactPhoneInputCountry(metadataCountries,defaultCountryValue,locale,value),[defaultCountryValue,locale,metadataCountries,value]),[internalValue,setInternalValue]=useState(()=>defaultValue?resolveReactPhoneInputValue(metadataCountries,initialCountry,defaultValue,phoneOptions):{country:initialCountry,e164:null,isValid:!1,nationalNumber:""}),phoneValue=value===void 0||value.country.regionCode===initialCountry.regionCode?value??internalValue:resolveReactPhoneInputValue(metadataCountries,initialCountry,value.nationalNumber,phoneOptions),resolvedOptions=metadataCountries.map(country=>({disabled:!1,label:`${country.displayName} (${country.callingCode})`,value:country.regionCode})),commitValue=nextValue=>{value===void 0&&setInternalValue(nextValue),onValueChange?.(nextValue)},handleCountryChange=event=>{const selectedCountry=metadataCountries.find(country=>country.regionCode===event.currentTarget.value||country.callingCode===event.currentTarget.value);selectedCountry&&commitValue(resolveLumenPhoneNumber(selectedCountry,phoneValue.nationalNumber,phoneOptions))},handleNumberChange=event=>{commitValue(resolveReactPhoneInputValue(metadataCountries,phoneValue.country,event.currentTarget.value,phoneOptions))},effectiveError=resolvePhoneError(errorMessage,showValidationError,phoneValue,invalidNumberMessage),invalid=!!effectiveError;return useEffect(()=>{numberRef.current?.setCustomValidity(effectiveError??"")},[effectiveError]),useEffect(()=>{const form=numberRef.current?.form;let active=!0,resetTimer;const reset=event=>{globalThis.clearTimeout(resetTimer),resetTimer=globalThis.setTimeout(()=>{const input=numberRef.current;if(!active||event.defaultPrevented||!input?.isConnected)return;if(value===void 0){const country=resolveReactPhoneInputCountry(metadataCountries,defaultCountryValue,locale,void 0);setInternalValue(resolveReactPhoneInputValue(metadataCountries,country,defaultValue??"",phoneOptions));return}const select=selectRef.current;select&&(select.value=phoneValue.country.regionCode),input.value=phoneValue.nationalNumber})};return form?.addEventListener("reset",reset),()=>{active=!1,globalThis.clearTimeout(resetTimer),form?.removeEventListener("reset",reset)}},[defaultCountryValue,defaultValue,inputProps.form,locale,metadataCountries,phoneOptions,phoneValue,value]),_jsxs(_Fragment,{children:[_jsxs("div",{className:composeClassName("ui-phone-input ui-input-group",className),"data-disabled":getBooleanAttribute(isDisabled),"data-invalid":getBooleanAttribute(invalid),"data-phone-enhanced":"true","data-readonly":getBooleanAttribute(isReadOnly),"data-size":visualSize,"data-slot":"phone-input",...props,children:[_jsxs("span",{className:"ui-phone-input__picker","data-slot":"phone-country",children:[_jsxs("span",{"aria-hidden":"true",className:"ui-phone-input__selection",children:[_jsx(CountryFlag,{decorative:!0,regionCode:phoneValue.country.regionCode}),_jsx("span",{children:phoneValue.country.callingCode}),_jsx("span",{className:"ui-phone-input__chevron"})]}),_jsx("select",{"aria-label":countryLabel,className:composeClassName("ui-select ui-phone-input__country",selectClass),disabled:isDisabled||isReadOnly||metadataCountries.length===0,form:inputProps.form,name:countryName,onChange:handleCountryChange,ref:selectRef,value:phoneValue.country.regionCode,children:resolvedOptions.map(option=>_jsx("option",{disabled:option.disabled,value:option.value,children:option.label},option.value))})]}),_jsx(PhoneNumberInput,{controlId,errorId,hasExplicitId:[id,inputProps.id].some(Boolean),inputClass,inputProps,inputRef,invalid,isDisabled,isReadOnly,name,numberRef,onChange:handleNumberChange,phoneValue,placeholder,required}),_jsx(PhoneCountryValue,{disabled:isDisabled,form:inputProps.form,name:countryName,readOnly:isReadOnly,value:phoneValue.country.regionCode})]}),effectiveError&&_jsx("span",{className:"ui-phone-input__error",id:errorId,role:"alert",children:effectiveError})]})},resolveLegacyPhoneAttributes=(inputProps,props)=>({autoComplete:inputProps.autoComplete??"tel-national",disabled:props.disabled??inputProps.disabled,id:props.id??inputProps.id,readOnly:props.readOnly??inputProps.readOnly,required:props.required??inputProps.required}),resolveLegacyPhoneCountry=(options,value)=>options.find(option=>option.value===value)?.value??options.find(option=>!option.disabled)?.value??"",useLegacyPhoneCountry=(countries,defaultCountryValue,form)=>{const options=countries.map(normalizeOption),[countryValue,setCountryValue]=useState(()=>resolveLegacyPhoneCountry(options,defaultCountryValue)),submissionCountry=resolveLegacyPhoneCountry(options,countryValue),countryRef=useRef(null);return useEffect(()=>{const form2=countryRef.current?.form;let active=!0;queueMicrotask(()=>{active&&setCountryValue(countryRef.current?.value??"")});const reset=event=>{queueMicrotask(()=>{active&&!event.defaultPrevented&&setCountryValue(countryRef.current?.value??"")})};return form2?.addEventListener("reset",reset),()=>{active=!1,form2?.removeEventListener("reset",reset)}},[countries,defaultCountryValue,form]),{countryRef,options,setCountryValue,submissionCountry}},LegacyPhoneInput=({className,countries,countryOptions:_countryOptions,disabled,readOnly,required,errorMessage:_errorMessage,id,inputProps=emptyPhoneInputProps,inputRef,countryLabel="Country code",countryName="country",defaultCountryValue,defaultValue,invalidNumberMessage:_invalidNumberMessage,locale:_locale,name="phone",onValueChange:_onValueChange,placeholder="Phone number",showValidationError:_showValidationError,visualSize="default",value:_value,...props})=>{const{inputClass,selectClass}=phoneInputSizeModifiers(visualSize),numberAttributes=resolveLegacyPhoneAttributes(inputProps,{disabled,readOnly,required,id}),{countryRef,options,setCountryValue,submissionCountry}=useLegacyPhoneCountry(countries,defaultCountryValue,inputProps.form);return _jsxs("div",{className:composeClassName("ui-phone-input ui-input-group",className),...props,"data-disabled":getBooleanAttribute([disabled,inputProps.disabled].some(Boolean)),"data-readonly":getBooleanAttribute([readOnly,inputProps.readOnly].some(Boolean)),"data-size":visualSize,"data-slot":"phone-input",children:[_jsx("span",{className:"ui-phone-input__picker",children:_jsx("select",{"aria-label":countryLabel,className:composeClassName("ui-select ui-phone-input__country",selectClass),defaultValue:defaultCountryValue,disabled:[disabled,readOnly,inputProps.disabled,inputProps.readOnly].some(Boolean),form:inputProps.form,name:countryName,onChange:event=>{setCountryValue(event.currentTarget.value)},ref:countryRef,children:options.map(option=>_jsx("option",{disabled:option.disabled,value:option.value,children:option.label},option.value))})}),_jsx("input",{...inputProps,...numberAttributes,ref:inputRef,className:composeClassName("ui-input ui-phone-input__number",inputClass),defaultValue,inputMode:"tel",name,placeholder,type:"tel"}),_jsx(PhoneCountryValue,{disabled:[disabled,inputProps.disabled].some(Boolean),form:inputProps.form,name:countryName,readOnly:[readOnly,inputProps.readOnly].some(Boolean),value:submissionCountry})]})},PhoneInput=props=>props.countries?_jsx(LegacyPhoneInput,{...props,countries:props.countries}):_jsx(MetadataPhoneInput,{...props,countryLabel:props.countryLabel??"Country code",countryName:props.countryName??"country",defaultCountryValue:props.defaultCountryValue??"US",invalidNumberMessage:props.invalidNumberMessage??"Enter a complete phone number.",name:props.name??"phone",placeholder:props.placeholder??"Phone number",showValidationError:props.showValidationError??!0,visualSize:props.visualSize??"default"}),NavigationMenu=({className,glass=!1,variant="default",...props})=>_jsx("nav",{className:composeClassName("ui-navigation-menu",variant==="unstyled"&&"ui-navigation-menu--unstyled",glassSurfaceClass("ui-navigation-menu",glass),className),"data-slot":"navigation-menu","data-surface":resolveSurface(glass),"data-ui-navigation-menu":!0,"data-variant":variant,...props}),ContextNavigation=({children,className,context,variant="default",...props})=>_jsxs("div",{className:composeClassName("ui-context-navigation",variant==="unstyled"&&"ui-context-navigation--unstyled",className),"data-slot":"context-navigation","data-variant":variant,...props,children:[context&&_jsx("div",{className:"ui-context-navigation__context","data-slot":"context-navigation-context",children:context}),children]}),Pagination=({"aria-label":ariaLabel="Pagination",className,...props})=>_jsx("nav",{"aria-label":ariaLabel,className:composeClassName("ui-pagination",className),...props}),Popover=({children,className,collisionPadding,defaultOpen,glass=!1,offset,onOpenChange,open,placement,positioning,...props})=>{const popover=usePopover({collisionPadding,defaultOpen,offset,onOpenChange,open,placement,positioning});return _jsx(PopoverContext,{value:popover,children:_jsx("div",{...popover.rootProps,...props,className:composeClassName("ui-popover",glassSurfaceClass("ui-popover",glass),className),"data-surface":resolveSurface(glass),"data-ui-popover":!0,children})})},PopoverTrigger=({onClick,onKeyDown,...props})=>{const popover=requireContext(use(PopoverContext),"PopoverTrigger");return _jsx(Button,{...popover.triggerProps,...props,onClick:composeHandlers(onClick,popover.triggerProps.onClick),onKeyDown:composeHandlers(onKeyDown,popover.triggerProps.onKeyDown),type:props.type??"button"})},PopoverPanel=({className,onKeyDown,...props})=>{const popover=requireContext(use(PopoverContext),"PopoverPanel");return _jsx("div",{...popover.panelProps,...props,className:composeClassName("ui-popover__panel",className),onKeyDown:composeHandlers(onKeyDown,popover.panelProps.onKeyDown)})},RadioGroup=({className,...props})=>_jsx("fieldset",{className:composeClassName("ui-radio-group",className),"data-ui-radio-group":!0,...props}),renderResizablePane=(child,index,panelProps)=>{if(isValidElement(child)){const childProps=child.props;return cloneElement(child,{...panelProps,className:composeClassName(childProps.className,panelProps.className),style:{...childProps.style,...panelProps.style}})}return _jsx("div",{...panelProps,children:child})},Resizable=({children,className,defaultSizes,direction="horizontal",maxSize,minSize,resetOnDoubleClick=!0,...props})=>{const panes=Children.toArray(children),resizable=useResizable({defaultSizes,direction,maxSize,minSize,panelCount:panes.length,resetOnDoubleClick});return _jsx("div",{...props,...resizable.rootProps,className:composeClassName(resizable.rootProps.className,className),children:panes.map((child,index)=>_jsxs(Fragment,{children:[renderResizablePane(child,index,resizable.getPanelProps(index)),index<panes.length-1&&_jsx("button",{...resizable.getHandleProps(index),type:"button"})]},index))})},RichTextEditor=({className,glass=!1,...props})=>_jsx("section",{className:composeClassName("ui-rich-text-editor",glassClass("ui-rich-text-editor",glass),className),"data-ui-rich-text-editor":!0,...props}),ScrollArea=({className,glass=!1,...props})=>_jsx("div",{className:composeClassName("ui-scroll-area",glassClass("ui-scroll-area",glass),className),...props}),ScrollProgress=({"aria-label":ariaLabel="Reading progress",className,position="top",...props})=>{const rootRef=useRef(null);return useEffect(()=>{const root=rootRef.current;if(!root)return;let frame=0;const update=()=>{frame=0;const scrollingElement=document.scrollingElement??document.documentElement,maximum=scrollingElement.scrollHeight-scrollingElement.clientHeight,percentage=maximum>0?Math.min(100,Math.max(0,scrollingElement.scrollTop/maximum*100)):0,bar=root.querySelector(".ui-scroll-progress__bar");root.setAttribute("aria-valuenow",`${Math.round(percentage)}`),bar&&(bar.style.transform=`scaleX(${percentage/100})`)},scheduleUpdate=()=>{frame||(frame=window.requestAnimationFrame(update))};return scheduleUpdate(),window.addEventListener("resize",scheduleUpdate,{passive:!0}),window.addEventListener("scroll",scheduleUpdate,{passive:!0}),()=>{frame&&window.cancelAnimationFrame(frame),window.removeEventListener("resize",scheduleUpdate),window.removeEventListener("scroll",scheduleUpdate)}},[]),_jsx("div",{"aria-label":ariaLabel,"aria-valuemax":100,"aria-valuemin":0,"aria-valuenow":0,className:composeClassName("ui-scroll-progress",position==="bottom"&&"ui-scroll-progress--bottom",className),"data-position":position,"data-ui-scroll-progress":!0,ref:rootRef,role:"progressbar",...props,children:_jsx("span",{className:"ui-scroll-progress__bar"})})},Schedule=({className,glass=!1,...props})=>_jsx("section",{className:composeClassName("ui-schedule",glassClass("ui-schedule",glass),className),"data-ui-schedule":!0,...props}),SearchField=({className,ref,type="search",...props})=>_jsx("input",{className:composeClassName("ui-input ui-search-field",className),ref,type,...props}),getSelectSizeClass=size=>size==="sm"?"ui-select--sm":size==="lg"?"ui-select--lg":!1,Select=({children,className,defaultValue,disabled=!1,glass=!1,id,inputRef,name,onChange,onValueChange,options=emptyOptions,placeholder,required=!1,visualSize="default",value,...props})=>{const select=useSelect({defaultValue,disabled,id,name,onValueChange,options,placeholder,required,value}),sizeClass=getSelectSizeClass(visualSize);return _jsxs("div",{...select.rootProps,className:composeClassName("ui-select-field",glassClass("ui-select-field",glass),className),"data-ui-glass-track":glass?!0:void 0,children:[_jsxs("select",{...select.nativeSelectProps,...props,className:composeClassName("ui-select ui-select__native",sizeClass),onChange:composeHandlers(onChange,select.nativeSelectProps.onChange),ref:inputRef,children:[placeholder&&_jsx("option",{"data-ui-select-placeholder":!0,disabled:!0,value:"",children:placeholder}),children,select.options.map(option=>_jsx("option",{disabled:option.disabled,value:option.value,children:option.label},option.value))]}),_jsxs("div",{...select.controlProps,className:"ui-select__control",children:[_jsx("button",{...select.triggerProps,"aria-label":props["aria-label"],"aria-labelledby":props["aria-labelledby"],"aria-describedby":props["aria-describedby"],"aria-invalid":props["aria-invalid"],"aria-errormessage":props["aria-errormessage"],className:composeClassName("ui-select ui-select__trigger",sizeClass),type:select.triggerProps.type??"button",children:_jsx("span",{"data-ui-select-value":!0,children:select.triggerText})}),_jsx("div",{...select.listProps,className:"ui-select__list",children:select.options.map(option=>{const optionProps=select.getOptionProps(option);return _jsx("button",{...optionProps,type:optionProps.type??"button",children:option.label},option.value)})})]})]})},groupListBoxOptions=options=>{const groups=[];return options.forEach((option,index)=>{const currentGroup=groups.at(-1);if(!currentGroup||currentGroup.label!==option.section){groups.push({...option.section?{label:option.section}:{},options:[{...option,index}]});return}currentGroup.options.push({...option,index})}),groups},getListBoxGroupKey=group=>{const values=group.options.map(option=>option.value).join("|");return group.label?`${group.label}:${values}`:values},optionalTrue=value=>value?!0:void 0,ListBoxNativeOptions=({groups})=>groups.map(group=>{const options=group.options.map(option=>_jsx("option",{disabled:option.disabled,value:option.value,children:option.label},option.value));return group.label?_jsx("optgroup",{label:group.label,children:options},getListBoxGroupKey(group)):_jsx(Fragment,{children:options},getListBoxGroupKey(group))}),ListBoxVisibleOptions=({activeIndex,controlId,emptyMessage,groups,loading,onSelect,selectedValues})=>loading?null:groups.length?groups.map(group=>{const groupKey=getListBoxGroupKey(group),safeGroupKey=groupKey.replaceAll(/[^a-zA-Z0-9_-]/g,"-"),groupLabelId=group.label?`${controlId}-group-${safeGroupKey}`:void 0,options=group.options.map(option=>_jsx("div",{"aria-disabled":option.disabled?!0:void 0,"aria-selected":selectedValues.has(option.value),className:composeClassName("ui-list-box__option",option.index===activeIndex&&"ui-list-box__option--active"),"data-active":option.index===activeIndex?"true":void 0,"data-ui-list-box-option":!0,"data-value":option.value,onClick:()=>{onSelect(option.index)},role:"option",children:option.label},option.value));return group.label?_jsxs("div",{"aria-labelledby":groupLabelId,role:"group",children:[_jsx("div",{className:"ui-list-box__section",id:groupLabelId,children:group.label}),options]},groupKey):_jsx(Fragment,{children:options},groupKey)}):_jsx("div",{"aria-disabled":"true",className:"ui-list-box__empty",role:"option",children:emptyMessage}),normalizeListBoxValues=value=>value===void 0?[]:Array.isArray(value)?value:[value],findLastEnabledOptionIndex=options=>{let lastEnabledIndex=-1;for(const[index,option]of options.entries())option.disabled||(lastEnabledIndex=index);return lastEnabledIndex},getListBoxSelectedValues=(controlledValue,internalValues)=>controlledValue===void 0?internalValues:normalizeListBoxValues(controlledValue),getListBoxSelectValue=(multiple,selectedValues)=>multiple?selectedValues:selectedValues[0]??"",ListBoxLabel=({controlId,label})=>label?_jsx("label",{className:"ui-label",htmlFor:controlId,children:label}):null,normalizeListBoxProps=({disabled=!1,emptyMessage="No options available",loading=!1,loadingMessage="Loading options",multiple=!1,options=emptyOptions,required=!1,selectionFollowsFocus=!1,...props})=>({disabled,emptyMessage,loading,loadingMessage,multiple,options,required,selectionFollowsFocus,...props}),ListBox=inputProps=>{const{className,defaultValue,disabled,emptyMessage,id,label,loading,loadingMessage,multiple,name,onValueChange,options,ref,required,selectionFollowsFocus,value,...props}=normalizeListBoxProps(inputProps),generatedId=useId(),controlId=id??`ui-list-box-${generatedId}`,normalizedOptions=options.map(option=>typeof option=="string"?{label:option,value:option}:option),optionGroups=groupListBoxOptions(normalizedOptions),[internalValues,setInternalValues]=useState(()=>normalizeListBoxValues(defaultValue)),selectedValues=getListBoxSelectedValues(value,internalValues),selectedSet=new Set(selectedValues),firstEnabledIndex=Math.max(0,normalizedOptions.findIndex(option=>!option.disabled)),[activeIndex,setActiveIndex]=useState(firstEnabledIndex),selectRef=useRef(null),typeaheadRef=useRef(""),typeaheadTimerRef=useRef(void 0),commitValues=nextValues=>{value===void 0&&setInternalValues(nextValues),onValueChange?.(nextValues);const select=selectRef.current;if(select){for(const option of select.options)option.selected=nextValues.includes(option.value);select.dispatchEvent(new Event("input",{bubbles:!0})),select.dispatchEvent(new Event("change",{bubbles:!0}))}},selectOption=index=>{const option=normalizedOptions[index];if(!option||option.disabled||disabled||loading)return;const optionValue=option.value;let nextValues;multiple?selectedSet.has(optionValue)?nextValues=selectedValues.filter(selectedValue=>selectedValue!==optionValue):nextValues=[...selectedValues,optionValue]:nextValues=[optionValue],commitValues(nextValues)},moveActive=direction=>{if(!normalizedOptions.length||loading)return;let nextIndex=activeIndex;for(const _option of normalizedOptions)if(nextIndex=(nextIndex+direction+normalizedOptions.length)%normalizedOptions.length,!normalizedOptions[nextIndex]?.disabled){setActiveIndex(nextIndex),selectionFollowsFocus&&selectOption(nextIndex);return}};useEffect(()=>()=>{typeaheadTimerRef.current&&clearTimeout(typeaheadTimerRef.current)},[]),useEffect(()=>{const form=selectRef.current?.form;if(!form||value!==void 0)return;const handleReset=()=>{setInternalValues(normalizeListBoxValues(defaultValue)),setActiveIndex(firstEnabledIndex)};return form.addEventListener("reset",handleReset),()=>{form.removeEventListener("reset",handleReset)}},[defaultValue,firstEnabledIndex,value]);const handleNavigationKey=key=>{if(key==="ArrowDown")moveActive(1);else if(key==="ArrowUp")moveActive(-1);else if(key==="Home")setActiveIndex(firstEnabledIndex),selectionFollowsFocus&&selectOption(firstEnabledIndex);else if(key==="End"){const lastEnabledIndex=findLastEnabledOptionIndex(normalizedOptions);lastEnabledIndex>=0&&(setActiveIndex(lastEnabledIndex),selectionFollowsFocus&&selectOption(lastEnabledIndex))}else if(key==="Enter"||key===" ")selectOption(activeIndex);else return!1;return!0},handleTypeaheadKey=event=>{if(event.key.length!==1||event.ctrlKey||event.metaKey||event.altKey)return!1;typeaheadRef.current+=event.key.toLowerCase(),typeaheadTimerRef.current&&clearTimeout(typeaheadTimerRef.current),typeaheadTimerRef.current=setTimeout(()=>{typeaheadRef.current=""},700);const nextIndex=normalizedOptions.findIndex(option=>!option.disabled&&option.label.toLowerCase().startsWith(typeaheadRef.current));return nextIndex>=0&&(setActiveIndex(nextIndex),selectionFollowsFocus&&selectOption(nextIndex)),!0},handleListKeyDown=event=>{(handleNavigationKey(event.key)||handleTypeaheadKey(event))&&event.preventDefault()};return _jsxs("div",{className:composeClassName("ui-list-box",className),"data-multiple":multiple?"true":void 0,"data-ui-list-box":!0,children:[_jsx(ListBoxLabel,{controlId,label}),_jsx("select",{...props,className:"ui-list-box__native","data-ui-enhanced":!0,"data-ui-list-box-native":!0,disabled:disabled||loading,id:controlId,multiple,name,ref:node=>{selectRef.current=node,setRefValue(ref,node)},required,value:getListBoxSelectValue(multiple,selectedValues),children:_jsx(ListBoxNativeOptions,{groups:optionGroups})}),_jsx("div",{"aria-busy":optionalTrue(loading),"aria-disabled":optionalTrue(disabled||loading),"aria-multiselectable":optionalTrue(multiple),className:"ui-list-box__list","data-ui-list-box-list":!0,onKeyDown:handleListKeyDown,role:"listbox",tabIndex:disabled||loading?void 0:0,children:_jsx(ListBoxVisibleOptions,{activeIndex,controlId,emptyMessage,groups:optionGroups,loading,onSelect:index=>{setActiveIndex(index),selectOption(index)},selectedValues:selectedSet})}),loading?_jsx("p",{className:"ui-list-box__status",role:"status",children:loadingMessage}):null]})},Sheet=({className,glass=!1,...props})=>_jsx("dialog",{className:composeClassName("ui-sheet",glassSurfaceClass("ui-sheet",glass),className),"data-surface":resolveSurface(glass),"data-ui-sheet":!0,...props}),Sidebar=({className,glass=!1,variant="default",...props})=>_jsx("aside",{className:composeClassName("ui-sidebar",variant==="unstyled"&&"ui-sidebar--unstyled",glassSurfaceClass("ui-sidebar",glass),className),"data-slot":"sidebar","data-surface":resolveSurface(glass),"data-variant":variant,...props}),Slider=({className,ref,type="range",...props})=>_jsx("input",{className:composeClassName("ui-slider",className),ref,type,...props}),ToastViewport=({"aria-atomic":ariaAtomic="false","aria-label":ariaLabel="Notifications","aria-live":ariaLive="polite",className,maxCount=3,placement="bottom-right",...props})=>_jsx("div",{"aria-atomic":ariaAtomic,"aria-label":ariaLabel,"aria-live":ariaLive,className:composeClassName("ui-tvp",className),"data-placement":placement,"data-ui-toast-viewport":!0,"data-ui-toast-max":maxCount,...props}),Switch=({className,ref,role="switch",...props})=>_jsx("input",{className:composeClassName("ui-switch",className),ref,role,type:"checkbox",...props}),Table=({className,glass=!1,layout="scroll",...props})=>_jsx("div",{className:composeClassName("ui-table-wrap",glassClass("ui-table-wrap",glass),layout==="records"&&"ui-table-wrap--records",className),"data-slot":"table",...props}),Tabs=({children,className,defaultValue,glass=!1,indicator=!1,onValueChange,orientation,value,...props})=>{const tabs=useTabs({defaultValue,onValueChange,orientation,value}),indicatorRef=useRef(null);return useEffect(()=>{if(indicator&&indicatorRef.current)return bindLumenTabIndicator(indicatorRef.current)},[indicator]),_jsx(TabsContext,{value:tabs,children:_jsx("div",{ref:indicatorRef,...tabs.rootProps,...props,className:composeClassName("ui-tabs",glassClass("ui-tabs",glass),className),children})})},TabsList=({...props})=>{const tabs=requireContext(use(TabsContext),"TabsList");return _jsx("div",{...tabs.listProps,...props})},TabsTrigger=({onClick,onKeyDown,value,...props})=>{const tabs=requireContext(use(TabsContext),"TabsTrigger");return _jsx("button",{...tabs.getTriggerProps(value,props),onClick:composeHandlers(onClick,tabs.getTriggerProps(value).onClick),onKeyDown:composeHandlers(onKeyDown,tabs.getTriggerProps(value).onKeyDown),type:props.type??"button"})},TabsPanel=({value,...props})=>{const tabs=requireContext(use(TabsContext),"TabsPanel");return _jsx("div",{...tabs.getPanelProps(value,props)})},emptyCodeTabItems=[],CodeTabs=({ariaLabel="Code examples",className,copy=!0,codeLabel,copyLabel,copiedLabel,errorLabel,initialValue,items=emptyCodeTabItems,storageKey,theme="auto",wrap=!0,...props})=>{const labels=resolveCodeLabels({codeLabel,copyLabel,copiedLabel,errorLabel}),selectedValue=initialValue??items[0]?.value,[value,setValue]=useState(()=>{let storedValue=null;if(storageKey&&typeof localStorage<"u")try{storedValue=localStorage.getItem(storageKey)}catch{}return storedValue&&items.some(item=>item.value===storedValue)?storedValue:selectedValue??""});useEffect(()=>{const synchronize=event=>{const detail=event.detail;storageKey&&detail.storageKey===storageKey&&detail.value&&items.some(item=>item.value===detail.value)&&setValue(detail.value)};return document.addEventListener("ui:tabs-change",synchronize),()=>{document.removeEventListener("ui:tabs-change",synchronize)}},[items,storageKey]);const selectValue=nextValue=>{if(setValue(nextValue),storageKey)try{localStorage.setItem(storageKey,nextValue)}catch{}document.dispatchEvent(new CustomEvent("ui:tabs-change",{detail:{storageKey,value:nextValue}}))};return _jsxs(Tabs,{className:composeClassName("ui-code-tabs",className),"data-slot":"code-tabs","data-storage-key":storageKey,onValueChange:selectValue,value,...props,children:[_jsx(TabsList,{"aria-label":ariaLabel,className:"ui-code-tabs__list",children:items.map(item=>_jsx(TabsTrigger,{className:"ui-code-tabs__tab",value:item.value,children:item.label},item.value))}),items.map(item=>_jsx(TabsPanel,{className:"ui-code-tabs__panel",value:item.value,children:_jsx(Code,{code:item.code,copy,...labels,...item.language===void 0?{}:{language:item.language},theme,variant:"block",wrap})},item.value))]})},TagGroup=({className,role="list",...props})=>_jsx("div",{className:composeClassName("ui-tag-group",className),role,...props}),ThemeBuilder=({className,glass=!1,...props})=>_jsx("section",{className:composeClassName("ui-theme-builder",glassClass("ui-theme-builder",glass),className),"data-ui-theme-builder":!0,...props}),TimeField=({className,ref,type="time",...props})=>_jsx("input",{className:composeClassName("ui-input ui-time-field",className),ref,type,...props}),Toast=({"aria-live":ariaLive,className,glass=!1,role,variant="default",...props})=>_jsx("aside",{"aria-live":ariaLive??(variant==="destructive"?"assertive":"polite"),className:composeClassName("ui-toast",variantClass("ui-toast",variant),glassSurfaceClass("ui-toast",glass),className),"data-surface":resolveSurface(glass),"data-ui-toast":!0,"data-variant":variant,role:role??(variant==="destructive"?"alert":"status"),...props}),Toggle=({className,controlled=!1,pressed=!1,type="button",...props})=>_jsx("button",{"aria-pressed":pressed,className:composeClassName("ui-toggle",className),"data-ui-controlled":controlled||void 0,"data-ui-toggle":!0,type,...props}),ToggleGroup=({className,...props})=>_jsx("div",{className:composeClassName("ui-toggle-group",className),"data-ui-toggle-group":!0,...props}),Tooltip=({children,className,defaultOpen,delay,onKeyDown,onMouseEnter,onMouseLeave,onOpenChange,open,...props})=>{const tooltip=useTooltip({defaultOpen,delay,onOpenChange,open});return _jsx(TooltipContext,{value:tooltip,children:_jsx("span",{...tooltip.rootProps,...props,className:composeClassName("ui-tooltip",className),onKeyDown:composeHandlers(onKeyDown,tooltip.rootProps.onKeyDown),onMouseEnter:composeHandlers(onMouseEnter,tooltip.rootProps.onMouseEnter),onMouseLeave:composeHandlers(onMouseLeave,tooltip.rootProps.onMouseLeave),children})})},TooltipContent=({...props})=>{const tooltip=requireContext(use(TooltipContext),"TooltipContent");return _jsx("span",{...tooltip.tooltipProps,...props})},Tree=({className,glass=!1,role="tree",...props})=>_jsx("div",{className:composeClassName("ui-tree",glassClass("ui-tree",glass),className),role,...props}),TreeGrid=({className,glass=!1,role="treegrid",...props})=>_jsx("div",{className:composeClassName("ui-tree-grid",glassClass("ui-tree-grid",glass),className),role,...props});import{VirtualList}from"./virtual-list.js";const BackToTop=({className,type="button",...props})=>_jsx("button",{className:composeClassName("ui-back-to-top",className),type,...props}),Callout=({className,...props})=>_jsx("aside",{className:composeClassName("ui-callout",className),...props}),Eyebrow=({className,...props})=>_jsx("p",{className:composeClassName("ui-eyebrow",className),...props}),FloatingBadge=({className,...props})=>_jsx("span",{className:composeClassName("ui-floating-badge",className),...props}),FormattedDate=({className,...props})=>_jsx("time",{className:composeClassName("ui-formatted-date",className),...props}),Image=({as,className,fit="cover",invertOnDark=!1,loading,radius="lg",...props})=>{const Component=as??"img",resolvedLoading=loading??(as?void 0:"lazy");return createElement(Component,{...props,className:composeClassName("ui-image",invertOnDark&&"ui-image--invert-dark",`ui-image--fit-${fit}`,`ui-image--radius-${radius}`,className),...resolvedLoading?{loading:resolvedLoading}:{}})},Link=({className,newTab=!1,ref,rel,target,variant="default",...props})=>_jsx("a",{className:composeClassName("ui-link",variant==="inherit"&&"ui-link--inherit",className),"data-slot":"link","data-variant":variant,ref,rel:newTab?[...new Set(`${rel??""} noopener noreferrer`.trim().split(/\s+/))].join(" "):rel,target:newTab?"_blank":target,...props}),Pill=({className,count,children,href,variant="neutral",...props})=>{const content=_jsxs(_Fragment,{children:[children,count!==void 0&&_jsx("span",{className:"ui-pill__count",children:count})]});return href?_jsx("a",{className:composeClassName("ui-pill",variantClass("ui-pill",variant,"neutral"),className),"data-variant":variant,href,...props,children:content}):_jsx("span",{className:composeClassName("ui-pill",variantClass("ui-pill",variant,"neutral"),className),"data-variant":variant,...props,children:content})},Prose=({className,...props})=>_jsx("div",{className:composeClassName("ui-prose",className),...props}),SkipLink=({className,...props})=>_jsx("a",{className:composeClassName("ui-skip-link",className),...props}),ThemeToggle=({className,type="button",...props})=>_jsxs("button",{className:composeClassName("ui-theme-toggle",className),"data-slot":"theme-toggle",type,...props,children:[_jsx("span",{className:"ui-sr-only",children:"Toggle color theme"}),_jsx(Icon,{className:"ui-theme-toggle__sun",name:"sun"}),_jsx(Icon,{className:"ui-theme-toggle__moon",name:"moon"})]}),LanguageToggle=({children,className,defaultValue,labelTemplate="Change language from {current} to {next}",locales,onClick,onValueChange,storageKey,type="button",value,...props})=>{const language=useLanguageToggle({defaultValue,locales,onValueChange,storageKey,value}),accessibleLabel=formatLumenLanguageLabel(labelTemplate,language.currentLocale,language.nextLocale);return _jsx("button",{"aria-label":accessibleLabel,className:composeClassName("ui-language-toggle",className),"data-ui-language-next-value":language.nextLocale.value,"data-ui-language-toggle":!0,"data-ui-language-value":language.value,onClick:event=>{onClick?.(event),!event.defaultPrevented&&(language.selectNext(),event.currentTarget.dispatchEvent(new CustomEvent("ui:language-change",{bubbles:!0,detail:{previousValue:language.currentLocale.value,value:language.nextLocale.value}})))},type,...props,children:children??_jsx("span",{lang:language.nextLocale.value,children:language.nextLocale.label})})},particleDensityConfig={high:40,low:15,medium:25},particleTones=["var(--brand)","var(--accent)","var(--glow, var(--brand))"],createParticles=density=>Array.from({length:particleDensityConfig[density]},(_,index)=>{const size=Math.random()*12+8,left=Math.random()*100,top=Math.random()*100;return{id:`${index}-${left}-${top}`,style:{"--ui-particle-delay":`${Math.random()*8}s`,"--ui-particle-duration":`${20+Math.random()*15}s`,"--ui-particle-left":`${left}%`,"--ui-particle-size":`${size}px`,"--ui-particle-tone":particleTones[Math.floor(Math.random()*particleTones.length)],"--ui-particle-top":`${top}%`}}}),Particles=({children,className,density="medium",...props})=>{const[particles,setParticles]=useState([]);return useEffect(()=>{window.matchMedia("(prefers-reduced-motion: reduce)").matches||setParticles(createParticles(density))},[density]),_jsxs("div",{"aria-hidden":"true",className:composeClassName("ui-particles",className),"data-ui-particles":density,...props,children:[children,particles.map(particle=>_jsx("span",{className:"ui-particles__particle",style:particle.style},particle.id))]})},parseMotionDuration=value=>{const parsedDuration=Number.parseFloat(value);return Number.isFinite(parsedDuration)?value.endsWith("ms")?parsedDuration:parsedDuration*1e3:300},ScrollReveal=({animation="fade",className,delay=0,duration="slow",once=!0,style,threshold=.15,...props})=>{const rootRef=useRef(null);return useEffect(()=>{const root=rootRef.current;if(!root)return;if(root.dataset.uiScrollRevealBound="true",window.matchMedia("(prefers-reduced-motion: reduce)").matches||typeof IntersectionObserver>"u"){root.classList.add("is-revealed");return}const observer=new IntersectionObserver(([entry])=>{entry&&(root.classList.toggle("is-revealed",entry.isIntersecting),entry.isIntersecting&&once&&observer.disconnect())},{threshold:Math.min(1,Math.max(0,threshold))});return observer.observe(root),()=>{observer.disconnect()}},[once,threshold]),_jsx("div",{className:composeClassName("ui-scroll-reveal",`ui-scroll-reveal-${animation}`,`ui-motion-duration-${duration}`,className),"data-ui-reveal-once":String(once),"data-ui-reveal-threshold":Math.min(1,Math.max(0,threshold)),"data-ui-scroll-reveal":!0,ref:rootRef,style:{...style,"--ui-reveal-delay":`${Math.max(0,delay)}ms`},...props})},RevealGroup=({animation="slide-up",className,delay=0,duration="slow",once=!0,stagger=80,style,threshold=.15,...props})=>{const rootRef=useRef(null);return useEffect(()=>{const root=rootRef.current;if(!root)return;root.dataset.uiScrollRevealBound="true";for(const[index,child]of[...root.children].entries())child instanceof HTMLElement&&child.style.setProperty("--ui-reveal-index",String(index));if(window.matchMedia("(prefers-reduced-motion: reduce)").matches||typeof IntersectionObserver>"u"){root.classList.add("is-revealed");return}const observer=new IntersectionObserver(([entry])=>{entry&&(root.classList.toggle("is-revealed",entry.isIntersecting),entry.isIntersecting&&once&&observer.disconnect())},{threshold:Math.min(1,Math.max(0,threshold))});return observer.observe(root),()=>{observer.disconnect()}},[once,threshold]),_jsx("div",{className:composeClassName("ui-reveal-group",`ui-reveal-group-${animation}`,`ui-motion-duration-${duration}`,className),"data-ui-reveal-group":!0,"data-ui-reveal-once":String(once),"data-ui-reveal-threshold":Math.min(1,Math.max(0,threshold)),ref:rootRef,style:{...style,"--ui-reveal-delay":`${Math.max(0,delay)}ms`,"--ui-reveal-stagger":`${Math.max(0,stagger)}ms`},...props})},AnimatedNumber=({className,decimals=0,duration="slow",from=0,locale,prefix="",suffix="",value,...props})=>{const outputRef=useRef(null),safeDecimals=Math.max(0,Math.min(20,Math.floor(decimals))),formatter=useMemo(()=>new Intl.NumberFormat(locale,{maximumFractionDigits:safeDecimals,minimumFractionDigits:safeDecimals}),[locale,safeDecimals]),formattedValue=`${prefix}${formatter.format(value)}${suffix}`;return useEffect(()=>{const output=outputRef.current;if(!output)return;const format=current=>`${prefix}${formatter.format(current)}${suffix}`;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches||typeof IntersectionObserver>"u"){output.textContent=format(value);return}output.textContent=format(from);const root=output.parentElement;if(!root)return;const observer=new IntersectionObserver(entries=>{if(!entries.some(entry=>entry.isIntersecting))return;observer.disconnect();const durationValue=getComputedStyle(root).getPropertyValue("--ui-motion-duration").trim(),durationMs=parseMotionDuration(durationValue),startedAt=performance.now(),update=now=>{const progress=Math.min(1,(now-startedAt)/Math.max(1,durationMs)),eased=1-Math.pow(1-progress,3);output.textContent=format(from+(value-from)*eased),progress<1?requestAnimationFrame(update):output.textContent=format(value)};requestAnimationFrame(update)},{threshold:.15});return observer.observe(root),()=>{observer.disconnect()}},[formatter,from,prefix,suffix,value]),_jsxs("span",{className:composeClassName("ui-animated-number",`ui-motion-duration-${duration}`,className),"data-ui-animated-number":!0,...props,children:[_jsx("span",{"aria-hidden":"true","data-ui-animated-number-output":!0,ref:outputRef,children:formattedValue}),_jsx("span",{className:"ui-sr-only",children:formattedValue})]})},Stat=({as,className,label,value,variant="default",children,...props})=>_jsxs(Primitive,{...as?{as}:{},className:composeClassName(variant!=="default"&&`ui-stat--${variant}`,className),"data-slot":"stat","data-variant":variant,...props,uiClassName:"ui-stat",children:[label&&_jsx("div",{className:"ui-stat-label","data-slot":"stat-label",children:label}),value&&_jsx("div",{className:"ui-stat-value","data-slot":"stat-value",children:value}),children]}),StatLabel=({as,...props})=>_jsx(Primitive,{...as?{as}:{},"data-slot":"stat-label",...props,uiClassName:"ui-stat-label"}),StatValue=({as,...props})=>_jsx(Primitive,{...as?{as}:{},"data-slot":"stat-value",...props,uiClassName:"ui-stat-value"}),StatDescription=({as,...props})=>_jsx(Primitive,{...as?{as}:{},"data-slot":"stat-description",...props,uiClassName:"ui-stat-description"}),StatIcon=({className,...props})=>_jsx("span",{className:composeClassName("ui-stat-icon",className),"data-slot":"stat-icon",...props}),StatTrend=({className,tone="neutral",...props})=>_jsx("span",{className:composeClassName("ui-stat-trend",`ui-stat-trend--${tone}`,className),"data-slot":"stat-trend","data-tone":tone,...props}),Meter=({className,...props})=>_jsx("meter",{className:composeClassName("ui-meter",className),...props}),Note=({className,label,borderPosition="left",children,...props})=>_jsxs("div",{className:composeClassName("ui-note",`ui-note--border-${borderPosition}`,className),...props,children:[label&&_jsx("p",{className:"ui-note__label",children:label}),_jsx("div",{className:"ui-note__content",children})]}),Rating=({className,value=0,max=5,readonly=!1,...props})=>{const stars=Array.from({length:max},(_,i)=>i+1);return _jsx("div",{className:composeClassName("ui-rating",readonly&&"ui-rating--readonly",className),"data-ui-rating":!0,"data-value":value,"data-max":max,"data-readonly":readonly?"true":"false",...props,children:stars.map(star=>_jsx("button",{type:"button",className:"ui-rating__star","data-active":star<=value?"true":"false",disabled:readonly,"aria-label":`Rate ${star} out of ${max}`,children:_jsx("svg",{viewBox:"0 0 24 24",width:"24",height:"24",stroke:"currentColor",strokeWidth:"2",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",className:"ui-icon",children:_jsx("polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"})})},star))})},Timeline=({className,...props})=>_jsx("ol",{className:composeClassName("ui-timeline",className),...props}),TimelineItem=({className,children,dot,...props})=>_jsxs("li",{className:composeClassName("ui-timeline-item",className),...props,children:[_jsx("div",{className:"ui-timeline-item__tail"}),_jsx("div",{className:"ui-timeline-item__dot",children:dot}),_jsx("div",{className:"ui-timeline-item__content",children})]}),AnimatedLogo=({animation="reveal",className,...props})=>_jsx("span",{className:composeClassName("ui-animated-logo",className),"data-animation":animation,"data-ui-animated-logo":!0,...props}),Graphic=({children,className,label,size="md",tone="brand",variant="orbit",...props})=>_jsx("div",{"aria-hidden":label?void 0:!0,"aria-label":label,className:composeClassName("ui-graphic",`ui-graphic--${variant}`,`ui-graphic--${tone}`,`ui-graphic--${size}`,className),role:label?"img":void 0,...props,children:_jsx("div",{className:"ui-graphic__content",children})}),Backdrop=({children,className,intensity="medium",tone="brand",variant="aurora",...props})=>_jsx("div",{className:composeClassName("ui-backdrop",`ui-backdrop--${variant}`,`ui-backdrop--${tone}`,`ui-backdrop--${intensity}`,className),...props,children:_jsx("div",{className:"ui-backdrop__content",children})}),AnimatedPortrait=({className,...props})=>_jsx("div",{className:composeClassName("ui-animated-portrait relative isolate w-full animate-reveal-lcp motion-reduce:animate-none",className),...props}),getButtonLinkVariantClass=variant=>variant==="unstyled"?"ui-button-link--unstyled":variant==="inline"?"ui-button ui-button--inline":`ui-button ui-button--${variant} min-h-11 rounded-full border`,ButtonLink=({asChild=!1,children,className,ref,shape="default",variant="primary",...props})=>{const variantClass2=getButtonLinkVariantClass(variant),buttonLinkClassName=composeClassName("ui-button-link",variant!=="unstyled"&&"group inline-flex cursor-pointer items-center justify-center gap-2 text-sm font-semibold tracking-[0.01em]",variantClass2,shape==="icon"&&variant!=="inline"?"ui-button-link--icon":void 0,className);if(asChild){const child=children;if(!isValidElement(child))throw new Error("ButtonLink with asChild requires exactly one valid React element child.");const ChildComponent=child.type;return _jsx(ChildComponent,{...child.props,...props,className:composeClassName(buttonLinkClassName,child.props.className),"data-slot":"button-link",ref,children:child.props.children})}return _jsx("a",{className:buttonLinkClassName,"data-slot":"button-link",ref,...props,children})},CoverImage=({className,hover=!1,showBottomGradient=!1,children,...props})=>_jsxs("div",{className:composeClassName("ui-cover-image relative overflow-hidden bg-surface-muted",hover&&"ui-cover-image--hover",className),...props,children:[children,showBottomGradient&&_jsx("div",{"aria-hidden":"true",className:"ui-cover-image__bottom-gradient"})]}),GradientDivider=({className,...props})=>_jsx("div",{"aria-hidden":"true",className:composeClassName("ui-gradient-divider pointer-events-none flex justify-center",className),...props,children:_jsx("div",{className:`
|
|
2
|
+
via-brand/40 h-px w-full max-w-5xl bg-linear-to-r from-transparent
|
|
3
|
+
to-transparent
|
|
4
|
+
`})}),emptySteps=[],normalizeStep=step=>typeof step=="string"?{description:void 0,title:step}:step,Stepper=({children,className,currentStep=0,orientation="horizontal",steps=emptySteps,...props})=>_jsxs("ol",{className:composeClassName("ui-stepper",orientation==="vertical"&&"ui-stepper--vertical",className),"data-orientation":orientation,...props,children:[steps.map(normalizeStep).map((step,index)=>{let state="upcoming";return index<currentStep?state="complete":index===currentStep&&(state="current"),_jsxs("li",{"aria-current":state==="current"?"step":void 0,className:"ui-stepper__step","data-state":state,children:[_jsx("span",{className:"ui-stepper__marker",children:index+1}),_jsxs("span",{className:"ui-stepper__content",children:[_jsx("span",{className:"ui-stepper__title",children:step.title}),step.description&&_jsx("span",{className:"ui-stepper__description",children:step.description})]})]},step.title)}),children]}),FileUpload=({children,className,hint,id,inputClassName,label="Choose a file or drag it here",selectedFilesLabel="{count} files selected",onChange,ref,...props})=>{const generatedId=useId(),inputId=id??`ui-file-upload-${generatedId.replaceAll(":","")}`,[selectedFiles,setSelectedFiles]=useState([]),inputRef=useRef(null);useEffect(()=>{const owner=inputRef.current?.ownerDocument;let active=!0;const reset=event=>{event.target===inputRef.current?.form&&queueMicrotask(()=>{active&&!event.defaultPrevented&&setSelectedFiles([])})};return owner?.addEventListener("reset",reset),()=>{active=!1,owner?.removeEventListener("reset",reset)}},[props.form]);const selectedFileText=selectedFiles.length>1?selectedFilesLabel.replaceAll("{count}",String(selectedFiles.length)):selectedFiles[0]??"";return _jsxs("label",{className:composeClassName("ui-file-upload",className),"data-state":selectedFiles.length>0?"selected":"idle","data-ui-file-upload":!0,htmlFor:inputId,children:[_jsx("input",{className:composeClassName("ui-file-upload__input",inputClassName),"data-ui-file-upload-input":!0,id:inputId,onChange:event=>{setSelectedFiles([...event.currentTarget.files??[]].map(file=>file.name)),onChange?.(event)},ref:element=>{if(inputRef.current=element,typeof ref=="function")return ref(element);ref&&(ref.current=element)},type:"file",...props,defaultValue:void 0,value:void 0}),_jsxs("svg",{"aria-hidden":"true",className:"ui-file-upload__icon",fill:"none",focusable:"false",viewBox:"0 0 24 24",children:[_jsx("path",{d:"M12 16V4m0 0L8 8m4-4 4 4"}),_jsx("path",{d:"M5 14v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-4"})]}),_jsx("span",{className:"ui-file-upload__prompt",children:children??label}),hint&&_jsx("span",{className:"ui-file-upload__hint",children:hint}),_jsx("span",{"aria-live":"polite",className:"ui-file-upload__files","data-ui-file-upload-files":!0,children:selectedFileText})]})},emptyTourSteps=[],Tour=({children,className,closeLabel="Done",hidden=!0,nextLabel="Next",steps=emptyTourSteps,...props})=>_jsxs("div",{className:composeClassName("ui-tour",className),"data-ui-tour":!0,hidden,...props,children:[_jsx("div",{"aria-hidden":"true",className:"ui-tour__backdrop","data-ui-tour-backdrop":!0}),_jsxs("div",{className:"ui-tour__popover","data-ui-tour-popover":!0,role:"dialog",children:[steps.map((step,index)=>_jsxs("div",{className:"ui-tour__step","data-target":step.target,"data-ui-tour-step":!0,hidden:index!==0,children:[step.title&&_jsx("p",{className:"ui-tour__title",children:step.title}),_jsx("p",{className:"ui-tour__content",children:step.content}),_jsxs("div",{className:"ui-tour__actions",children:[_jsx("button",{className:"ui-button ui-button--ghost ui-button--sm","data-ui-tour-close":!0,type:"button",children:closeLabel}),index<steps.length-1&&_jsx("button",{className:"ui-button ui-button--default ui-button--sm","data-ui-tour-next":!0,type:"button",children:nextLabel})]})]},step.target)),children]})]}),emptyAnchorLinks=[],createAnchorRef=()=>{let cleanup;return root=>{if(cleanup?.(),cleanup=void 0,!root)return;const links=[...root.querySelectorAll('a[href^="#"]')],targets=links.flatMap(link=>{const id=decodeURIComponent(link.getAttribute("href")?.slice(1)??""),target=id?document.getElementById(id):null;return target?[{link,target}]:[]});if(!targets.length)return;const abortController=new AbortController;let frame=0;const setActive=active=>{for(const link of links){const isActive=link===active;link.dataset.active=String(isActive),isActive?link.setAttribute("aria-current","location"):link.removeAttribute("aria-current")}},update=()=>{frame=0;const scrollingElement=document.scrollingElement??document.documentElement,atEnd=scrollingElement.scrollTop+scrollingElement.clientHeight>=scrollingElement.scrollHeight-1,offset=Number(root.dataset.uiAnchorOffset)||0;let active=targets[0]?.link;if(atEnd)active=targets.at(-1)?.link;else for(const item of targets){if(item.target.getBoundingClientRect().top>offset)break;active=item.link}active&&setActive(active)},requestUpdate=()=>{frame||(frame=requestAnimationFrame(update))};for(const{link}of targets)link.addEventListener("click",()=>{setActive(link)},{signal:abortController.signal});window.addEventListener("resize",requestUpdate,{passive:!0,signal:abortController.signal}),window.addEventListener("scroll",requestUpdate,{passive:!0,signal:abortController.signal}),update(),cleanup=()=>{abortController.abort(),frame&&cancelAnimationFrame(frame)}}},Anchor=({"aria-label":ariaLabel="On this page",activationOffset=96,children,className,items=emptyAnchorLinks,...props})=>{const anchorRef=createAnchorRef();return _jsxs("nav",{"aria-label":ariaLabel,className:composeClassName("ui-anchor",className),"data-ui-anchor":!0,"data-ui-anchor-offset":Math.max(0,activationOffset),ref:anchorRef,...props,children:[items.length>0&&_jsx("ol",{children:items.map((item,index)=>_jsx("li",{children:_jsxs("a",{"aria-current":index===0?"location":void 0,"data-active":index===0?"true":"false","data-depth":item.depth,href:item.href,children:[item.index!==void 0&&_jsx("span",{className:"ui-anchor__index",children:item.index}),_jsxs("span",{className:"ui-anchor__content",children:[_jsx("span",{className:"ui-anchor__label",children:item.label}),item.description&&_jsx("span",{className:"ui-anchor__description",children:item.description})]})]})},item.href))}),children]})},Segmented=({children,className,defaultValue,name="segmented",onValueChange,options=emptyOptions,visualSize="default",value,...props})=>_jsxs("div",{className:composeClassName("ui-segmented",visualSize==="sm"&&"ui-segmented--sm",visualSize==="lg"&&"ui-segmented--lg",className),role:"group",...props,children:[options.map(normalizeOption).map(option=>_jsxs("label",{className:"ui-segmented__option",children:[_jsx("input",{checked:value===void 0?void 0:value===option.value,defaultChecked:value===void 0?defaultValue===option.value:void 0,className:"ui-segmented__input",disabled:option.disabled,name,type:"radio",value:option.value,onChange:()=>onValueChange?.(option.value)}),_jsx("span",{className:"ui-segmented__label",children:option.label})]},option.value)),children]}),Toolbar=({"aria-label":ariaLabel="Toolbar",className,orientation="horizontal",...props})=>_jsx("div",{"aria-label":ariaLabel,"aria-orientation":orientation,className:composeClassName("ui-toolbar",orientation==="vertical"&&"ui-toolbar--vertical",className),"data-orientation":orientation,"data-ui-toolbar":!0,role:"toolbar",...props}),emptyDescriptionsItems=[],Descriptions=({children,className,columns=1,items=emptyDescriptionsItems,style,...props})=>_jsxs("dl",{className:composeClassName("ui-descriptions",className),"data-columns":columns,style:{"--ui-descriptions-columns":columns,...style},...props,children:[items.map((item,index)=>_jsxs("div",{className:"ui-descriptions__item",children:[_jsx("dt",{className:"ui-descriptions__term",children:item.label}),_jsx("dd",{className:"ui-descriptions__detail",children:item.value})]},index)),children]}),Popconfirm=({cancelLabel="Cancel",children,className,confirmLabel="Confirm",title="Are you sure?",...props})=>_jsxs("div",{className:composeClassName("ui-popover ui-popconfirm",className),"data-surface":"default","data-ui-popconfirm":!0,"data-ui-popover":!0,...props,children:[_jsx("span",{"aria-expanded":"false","aria-haspopup":"dialog",className:"ui-popconfirm__trigger","data-ui-trigger":!0,children}),_jsxs("div",{className:"ui-popover__panel ui-popconfirm__panel","data-ui-panel":!0,hidden:!0,role:"dialog",children:[_jsx("p",{className:"ui-popconfirm__message",children:title}),_jsxs("div",{className:"ui-popconfirm__actions",children:[_jsx("button",{className:"ui-button ui-button--ghost ui-button--sm","data-ui-popconfirm-cancel":!0,type:"button",children:cancelLabel}),_jsx("button",{className:"ui-button ui-button--destructive ui-button--sm","data-ui-popconfirm-confirm":!0,type:"button",children:confirmLabel})]})]})]}),emptyTransferItems=[],renderTransferItems=items=>items.map(item=>_jsx("li",{className:"ui-transfer__item",children:_jsxs("label",{className:"ui-transfer__option",children:[_jsx("input",{className:"ui-checkbox","data-ui-transfer-item":!0,type:"checkbox",value:item.key}),_jsx("span",{children:item.label})]})},item.key)),Transfer=({className,items=emptyTransferItems,name,sourceTitle="Available",targetItems=emptyTransferItems,targetTitle="Selected",...props})=>_jsxs("div",{className:composeClassName("ui-transfer",className),"data-ui-transfer":!0,"data-ui-transfer-name":name,...props,children:[_jsxs("div",{className:"ui-transfer__panel",children:[_jsx("p",{className:"ui-transfer__title",children:sourceTitle}),_jsx("ul",{className:"ui-transfer__list","data-side":"source","data-ui-transfer-list":!0,children:renderTransferItems(items)})]}),_jsxs("div",{className:"ui-transfer__controls",children:[_jsx("button",{"aria-label":`Move to ${targetTitle}`,className:"ui-button ui-button--outline ui-button--icon","data-ui-transfer-move":"target",type:"button",children:_jsx(Icon,{name:"chevron-right"})}),_jsx("button",{"aria-label":`Move to ${sourceTitle}`,className:"ui-button ui-button--outline ui-button--icon","data-ui-transfer-move":"source",type:"button",children:_jsx(Icon,{name:"chevron-left"})})]}),_jsxs("div",{className:"ui-transfer__panel",children:[_jsx("p",{className:"ui-transfer__title",children:targetTitle}),_jsx("ul",{className:"ui-transfer__list","data-side":"target","data-ui-transfer-list":!0,children:renderTransferItems(targetItems)})]})]}),buildCascaderColumns=(options,idPrefix)=>{const columns=[];let count=0;const build=(items,root)=>{count+=1;const id=`${idPrefix}-column-${count}`,rendered=items.map(item=>({label:item.label,value:item.value}));columns.push({id,options:rendered,root});for(const[index,item]of items.entries()){const renderedOption=rendered[index];item.children&&item.children.length>0&&renderedOption&&(renderedOption.nextId=build(item.children,!1))}return id};return options.length>0&&build(options,!0),columns},emptyCascaderOptions=[],Cascader=({children,className,id,name,options=emptyCascaderOptions,placeholder="Select\u2026",...props})=>{const generatedId=useId().replaceAll(":",""),cascaderId=id??`ui-cascader-${generatedId}`,panelId=`${cascaderId}-panel`,columns=buildCascaderColumns(options,cascaderId);return _jsxs("div",{className:composeClassName("ui-cascader",className),"data-surface":"default","data-ui-cascader":!0,"data-ui-popover":!0,id,...props,children:[_jsx("button",{"aria-controls":panelId,"aria-expanded":"false","aria-haspopup":"listbox",className:"ui-select ui-select__trigger ui-cascader__trigger","data-ui-trigger":!0,role:"combobox",type:"button",children:_jsx("span",{"data-ui-cascader-placeholder":placeholder,"data-ui-cascader-value":!0,children:placeholder})}),_jsxs("div",{className:"ui-cascader__panel","data-ui-panel":!0,hidden:!0,id:panelId,children:[columns.map(column=>_jsx("ol",{"aria-label":column.root?"Options":"Sub-options",className:"ui-cascader__column",hidden:!column.root,id:column.id,role:"listbox",children:column.options.map(option=>_jsx("li",{role:"presentation",children:_jsxs("button",{"aria-selected":"false",className:"ui-cascader__option","data-ui-cascader-next":option.nextId?`#${option.nextId}`:void 0,"data-ui-cascader-option":!0,"data-value":option.value,role:"option",type:"button",children:[_jsx("span",{children:option.label}),option.nextId&&_jsx("span",{"aria-hidden":"true",children:"\u203A"})]})},option.value))},column.id)),children]}),name&&_jsx("input",{"data-ui-cascader-input":!0,name,type:"hidden"})]})},flattenTreeSelect=(nodes,depth=0,acc=[])=>{for(const node of nodes)acc.push({depth,label:node.label,value:node.value}),node.children&&node.children.length>0&&flattenTreeSelect(node.children,depth+1,acc);return acc},emptyTreeSelectNodes=[],TreeSelect=({children,className,name,placeholder="Select\u2026",treeData=emptyTreeSelectNodes,...props})=>_jsxs("div",{className:composeClassName("ui-tree-select",className),"data-surface":"default","data-ui-popover":!0,"data-ui-tree-select":!0,...props,children:[_jsx("button",{"aria-expanded":"false","aria-haspopup":"tree",className:"ui-select ui-select__trigger ui-tree-select__trigger","data-ui-trigger":!0,type:"button",children:_jsx("span",{"data-ui-tree-select-placeholder":placeholder,"data-ui-tree-select-value":!0,children:placeholder})}),_jsxs("div",{className:"ui-tree-select__panel","data-ui-panel":!0,hidden:!0,children:[_jsx("div",{className:"ui-tree-select__tree",role:"tree",children:flattenTreeSelect(treeData).map(row=>_jsx("button",{className:"ui-tree-select__option","data-value":row.value,role:"treeitem",style:{"--ui-tree-depth":row.depth},type:"button",children:row.label},row.value))}),children]}),name&&_jsx("input",{"data-ui-tree-select-input":!0,name,type:"hidden"})]}),Mentions=({className,defaultValue="",label="Mentions",name,onValueChange,options=emptyOptions,placeholder,trigger="@",value,...props})=>{const generatedId=useId(),inputRef=useRef(null),pendingCaretRef=useRef(null),[activeIndex,setActiveIndex]=useState(-1),[internalValue,setInternalValue]=useState(defaultValue),[query,setQuery]=useState(null),currentValue=value??internalValue;useLayoutEffect(()=>{const pending=pendingCaretRef.current,input=inputRef.current;pending&&(pendingCaretRef.current=null,!(!input||currentValue!==pending.value)&&(input.focus(),input.setSelectionRange(pending.position,pending.position)))},[currentValue]);const listId=`ui-mentions-${generatedId}-list`,escapedTrigger=trigger.replaceAll(/[.*+?^${}()|[\]\\]/g,"\\$&"),normalizedOptions=options.map(normalizeOption),visibleOptions=query===null?[]:normalizedOptions.filter(option=>option.value.toLowerCase().startsWith(query)),expanded=visibleOptions.length>0,resolvedActiveIndex=expanded?Math.min(Math.max(activeIndex,0),visibleOptions.length-1):-1,activeOption=visibleOptions[resolvedActiveIndex],setNextValue=nextValue=>{value===void 0&&setInternalValue(nextValue),onValueChange?.(nextValue)},closeList=()=>{setQuery(null),setActiveIndex(-1)},insertMention=mention=>{const caret=inputRef.current?.selectionStart??currentValue.length,before=currentValue.slice(0,caret).replace(new RegExp(`${escapedTrigger}\\w*$`),`${trigger}${mention} `),nextValue=before+currentValue.slice(caret);pendingCaretRef.current={position:before.length,value:nextValue},setNextValue(nextValue),closeList()},handleKeyDown=event=>{if(event.key==="Escape"&&expanded){event.preventDefault(),closeList();return}if(expanded&&(event.key==="ArrowDown"||event.key==="ArrowUp"||event.key==="End"||event.key==="Home")){event.preventDefault(),setActiveIndex(current=>event.key==="Home"?0:event.key==="End"?visibleOptions.length-1:event.key==="ArrowDown"?(current+1)%visibleOptions.length:(current-1+visibleOptions.length)%visibleOptions.length);return}event.key==="Enter"&&activeOption&&(event.preventDefault(),insertMention(activeOption.value))};return _jsxs("div",{className:composeClassName("ui-mentions",className),"data-ui-mentions":!0,"data-ui-mentions-trigger":trigger,...props,children:[_jsx("textarea",{"aria-activedescendant":activeOption?`${listId}-option-${resolvedActiveIndex}`:void 0,"aria-autocomplete":"list","aria-controls":listId,"aria-expanded":expanded,"aria-label":label,className:"ui-textarea ui-mentions__input","data-ui-mentions-input":!0,name,onBlur:()=>{pendingCaretRef.current=null,closeList()},onChange:event=>{pendingCaretRef.current=null;const nextValue=event.currentTarget.value,match=new RegExp(`${escapedTrigger}(\\w*)$`).exec(nextValue.slice(0,event.currentTarget.selectionStart)),nextQuery=match?(match[1]??"").toLowerCase():null;setNextValue(nextValue),setQuery(nextQuery),setActiveIndex(nextQuery===null?-1:0)},onKeyDown:handleKeyDown,placeholder,ref:inputRef,role:"combobox",rows:3,value:currentValue}),_jsx("ul",{className:"ui-mentions__list","data-ui-mentions-list":!0,hidden:!expanded,id:listId,role:"listbox",children:visibleOptions.map((option,index)=>_jsx("li",{children:_jsx("button",{"aria-selected":index===resolvedActiveIndex,className:"ui-mentions__option","data-ui-mentions-option":!0,"data-value":option.value,id:`${listId}-option-${index}`,onClick:()=>{insertMention(option.value)},onMouseDown:event=>{event.preventDefault()},role:"option",tabIndex:-1,type:"button",children:option.label})},option.value))})]})},QRCode=({children,className,size=160,src,style,value,...props})=>{const qrSvg=!src&&value?renderSVG(value):null,qrSrc=qrSvg?`data:image/svg+xml;utf8,${encodeURIComponent(qrSvg)}`:src;return _jsxs("figure",{className:composeClassName("ui-qr-code",className),"data-ui-qr-code":!0,style:{"--ui-qr-code-size":`${size}px`,...style},...props,children:[_jsx("div",{className:"ui-qr-code__frame",children:qrSrc?_jsx("img",{alt:value?`QR code for ${value}`:"QR code",className:"ui-qr-code__image",height:size,src:qrSrc,width:size}):children}),value&&_jsx("figcaption",{className:"ui-qr-code__value",children:value})]})},Watermark=({children,className,content,gap=120,rotate=-22,style,text="Confidential",...props})=>{const watermarkText=content??text,tileSize=Math.max(1,gap),watermarkXmlEntities={"&":"&","<":"<",">":">",'"':""","'":"'"},escapedWatermarkText=watermarkText.replaceAll(/[&<>"']/g,character=>watermarkXmlEntities[character]??character),watermarkSvg=['<svg xmlns="http://www.w3.org/2000/svg"',` width="${tileSize}" height="${tileSize}" viewBox="0 0 ${tileSize} ${tileSize}">`,`<text x="${tileSize/2}" y="${tileSize/2}" dominant-baseline="middle" text-anchor="middle"`,` transform="rotate(${rotate} ${tileSize/2} ${tileSize/2})"`,' fill="black" font-family="Montserrat, Avenir Next, Segoe UI, sans-serif" font-size="16" font-weight="500" letter-spacing="1.6">',`${escapedWatermarkText}</text></svg>`].join(""),watermarkImage=`url("data:image/svg+xml,${encodeURIComponent(watermarkSvg)}")`;return _jsxs("div",{className:composeClassName("ui-watermark",className),"data-ui-watermark":!0,style:{"--ui-watermark-gap":`${tileSize}px`,"--ui-watermark-image":watermarkImage,...style},...props,children:[children,_jsx("div",{"aria-hidden":"true",className:"ui-watermark__overlay","data-text":watermarkText})]})},Affix=({className,offset=0,offsetBottom,offsetTop,position:positionProp,style,...props})=>{const position=positionProp??(offsetBottom===void 0?"top":"bottom"),resolvedOffset=offsetBottom??offsetTop??offset;return _jsx("div",{className:composeClassName("ui-affix",position==="bottom"&&"ui-affix--bottom",className),"data-position":position,style:{"--ui-affix-offset":`${resolvedOffset}px`,...style},...props})},emptySpeedDialActions=[],speedDialNavigationKeys=["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","End","Home"],getSpeedDialNavigationIndex=(key,currentIndex,itemCount)=>key==="Home"?0:key==="End"?itemCount-1:key==="ArrowDown"||key==="ArrowRight"?(currentIndex+1)%itemCount:(currentIndex-1+itemCount)%itemCount,SpeedDial=({actions=emptySpeedDialActions,children,className,defaultOpen=!1,direction="up",label="Actions",onBlur,...props})=>{const[isOpen,setIsOpen]=useState(defaultOpen),menuRef=useRef(null),triggerRef=useRef(null),close=(restoreFocus=!1)=>{setIsOpen(!1),restoreFocus&&triggerRef.current?.focus()},focusAction=position=>{setIsOpen(!0),requestAnimationFrame(()=>{const items=menuRef.current?.querySelectorAll('[role="menuitem"], button:not([disabled]), a[href]');(position==="first"?items?.[0]:items?.[items.length-1])?.focus()})};return _jsxs("div",{className:composeClassName("ui-speed-dial",`ui-speed-dial--${direction}`,className),...props,"data-direction":direction,"data-state":isOpen?"open":"closed","data-ui-bound":"true","data-ui-speed-dial":!0,onBlur:event=>{onBlur?.(event),event.currentTarget.contains(event.relatedTarget)||close()},children:[_jsx("button",{"aria-expanded":isOpen,"aria-haspopup":"menu","aria-label":label,className:"ui-speed-dial__trigger","data-ui-speed-dial-trigger":!0,onClick:()=>{setIsOpen(open=>!open)},onKeyDown:event=>{if(event.key==="Escape"&&close(),["ArrowDown","ArrowRight"].includes(event.key)){event.preventDefault(),focusAction("first");return}["ArrowLeft","ArrowUp"].includes(event.key)&&(event.preventDefault(),focusAction("last"))},ref:triggerRef,type:"button",children:_jsx("span",{"aria-hidden":"true",className:"ui-speed-dial__icon"})}),_jsxs("menu",{"aria-label":label,className:"ui-speed-dial__actions","data-ui-speed-dial-actions":!0,onClick:event=>{event.target.closest('[role="menuitem"], button, a')&&close()},onKeyDown:event=>{const items=[...menuRef.current?.querySelectorAll('[role="menuitem"], button:not([disabled]), a[href]')??[]];if(event.key==="Escape"){event.preventDefault(),close(!0);return}if(!speedDialNavigationKeys.includes(event.key))return;const currentIndex=items.indexOf(document.activeElement),targetIndex=getSpeedDialNavigationIndex(event.key,currentIndex,items.length);event.preventDefault(),items[targetIndex]?.focus()},ref:menuRef,role:"menu",children:[actions.map((action,index)=>_jsx("li",{role:"presentation",style:{"--ui-speed-dial-index":index},children:_jsxs("button",{"aria-label":action.label,className:"ui-speed-dial__action","data-icon":action.icon,"data-value":action.value??action.label,role:"menuitem",type:"button",children:[action.icon&&_jsx("span",{"aria-hidden":"true",className:"ui-speed-dial__action-icon ui-icon",children:renderLucideIcon(action.icon,`ui-icon__svg lucide-${action.icon}`)}),_jsx("span",{className:"ui-speed-dial__action-label",children:action.label})]})},action.value??action.label)),children]})]})},DescriptionItem=({className,...props})=>_jsx("div",{...props,className:composeClassName("ui-description-item","ui-descriptions__item",className),"data-slot":"description-item"}),DescriptionTerm=({className,...props})=>_jsx("dt",{...props,className:composeClassName("ui-description-term","ui-descriptions__term",className),"data-slot":"description-term"}),DescriptionDetail=({className,...props})=>_jsx("dd",{...props,className:composeClassName("ui-description-detail","ui-descriptions__detail",className),"data-slot":"description-detail"});export{Accordion,Affix,Agenda,Alert,AlertDialog,Anchor,AnimatedLogo,AnimatedNumber,AnimatedPortrait,AspectRatio,Attachment,Autocomplete,Avatar,BackToTop,Backdrop,Badge,BarChart,Breadcrumb,Bubble,Button,ButtonGroup,ButtonLink,Calendar,Callout,Card,CardContent,CardDescription,CardFooter,CardHeader,CardTitle,Carousel,Cascader,Chart,Checkbox,CheckboxGroup,Code,CodeTabs,Collapsible,ColorPicker,ComboChart,Combobox,Command,Container,ContextMenu,ContextNavigation,CopyButton,CountryFlag,CoverImage,DatePicker,DateRangePicker,DescriptionDetail,DescriptionItem,DescriptionTerm,Descriptions,Dialog,DialogBody,DialogClose,DialogFooter,DialogHeader,DialogTitle,Direction,Drawer,DropdownMenu,DropdownMenuContent,DropdownMenuItem,DropdownMenuSeparator,DropdownMenuTrigger,Empty,ErrorState,ErrorSummary,Eyebrow,Field,FieldError,FileUpload,FloatingBadge,Form,FormattedDate,GradientDivider,Graphic,Grid,Heatmap,HoverCard,Icon,Illustration,Image,Input2 as Input,InputGroup,InputOTP,Item,KanbanBoard,KanbanColumn,Kbd,Label2 as Label,LanguageToggle,LineChart,Link,ListBox,Marker,Mentions,Menubar,Message,MessageScroller,Meter,NativeSelect,NavigationMenu,Note,NumberField,Pagination,Particles,PasswordField,PhoneInput,PhoneNumber,PieChart,Pill,Popconfirm,Popover,PopoverPanel,PopoverTrigger,Progress,Prose,QRCode,RadioGroup,RangeChart,Rating,Resizable,RevealGroup,RichTextEditor,ScatterChart,Schedule,ScrollArea,ScrollProgress,ScrollReveal,SearchField,Segmented,Select,Separator,Sheet,Sidebar,Skeleton,SkipLink,Slider,Sparkline,SpeedDial,Spinner,Stack,Stat,StatDescription,StatIcon,StatLabel,StatTrend,StatValue,Stepper,Switch,Table,Tabs,TabsList,TabsPanel,TabsTrigger,TagGroup,Textarea,ThemeBuilder,ThemeToggle,TimeField,Timeline,TimelineItem,Toast,ToastViewport,Toggle,ToggleGroup,Toolbar,Tooltip,TooltipContent,Tour,Transfer,Tree,TreeGrid,TreeSelect,Typography,VirtualList,VisuallyHidden,Watermark};
|