@surflane/ui 0.8.0 → 0.10.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 +5 -5
- package/dist/accordion.d.ts +33 -17
- package/dist/accordion.js +10 -11
- package/dist/alert-dialog.d.ts +8 -4
- package/dist/alert-dialog.js +3 -4
- package/dist/app-shell.d.ts +81 -44
- package/dist/app-shell.js +67 -29
- package/dist/autocomplete.d.ts +117 -61
- package/dist/autocomplete.js +8 -8
- package/dist/avatar.d.ts +34 -17
- package/dist/avatar.js +8 -9
- package/dist/badge.d.ts +6 -10
- package/dist/badge.js +5 -6
- package/dist/bottom-navigation.d.ts +11 -41
- package/dist/bottom-navigation.js +9 -10
- package/dist/breadcrumbs.d.ts +21 -5
- package/dist/breadcrumbs.js +12 -14
- package/dist/button.d.ts +15 -8
- package/dist/button.js +8 -9
- package/dist/card.d.ts +610 -35
- package/dist/card.js +12 -12
- package/dist/chart.d.ts +9 -32
- package/dist/chart.js +65 -26
- package/dist/checkbox-group.d.ts +4 -1
- package/dist/checkbox-group.js +3 -4
- package/dist/checkbox.d.ts +13 -4
- package/dist/checkbox.js +6 -6
- package/dist/choice-label.d.ts +3 -11
- package/dist/choice-label.js +4 -4
- package/dist/class-names.d.ts +6 -0
- package/dist/class-names.js +18 -0
- package/dist/code.d.ts +13 -10
- package/dist/code.js +8 -5
- package/dist/collapsible.d.ts +25 -12
- package/dist/collapsible.js +7 -8
- package/dist/combobox.d.ts +145 -73
- package/dist/combobox.js +27 -27
- package/dist/context-menu.d.ts +106 -54
- package/dist/context-menu.js +4 -5
- package/dist/css/accordion.css +1 -1
- package/dist/css/alert-dialog.css +2 -2
- package/dist/css/all.css +7 -5
- package/dist/css/app-shell.css +1 -1
- package/dist/css/autocomplete.css +1 -1
- package/dist/css/avatar.css +2 -2
- package/dist/css/badge.css +2 -2
- package/dist/css/bottom-navigation.css +1 -1
- package/dist/css/breadcrumbs.css +3 -3
- package/dist/css/button.css +1 -1
- package/dist/css/card.css +3 -3
- package/dist/css/chart.css +2 -2
- package/dist/css/checkbox-group.css +1 -1
- package/dist/css/checkbox.css +1 -1
- package/dist/css/choice-label.css +1 -1
- package/dist/css/code.css +2 -2
- package/dist/css/collapsible.css +1 -1
- package/dist/css/combobox.css +1 -1
- package/dist/css/context-menu.css +1 -1
- package/dist/css/date-picker.css +1 -1
- package/dist/css/dialog.css +2 -2
- package/dist/css/drawer.css +2 -2
- package/dist/css/empty-state.css +2 -2
- package/dist/css/field.css +1 -1
- package/dist/css/fieldset.css +1 -1
- package/dist/css/file-upload.css +2 -2
- package/dist/css/filter-bar.css +1 -1
- package/dist/css/form.css +1 -1
- package/dist/css/icon.css +1 -1
- package/dist/css/inline-message.css +2 -2
- package/dist/css/input.css +1 -1
- package/dist/css/layout.css +2 -2
- package/dist/css/link.css +2 -2
- package/dist/css/list.css +2 -2
- package/dist/css/markdown.css +4 -4
- package/dist/css/menu.css +1 -1
- package/dist/css/menubar.css +1 -1
- package/dist/css/meter.css +1 -1
- package/dist/css/native-select.css +1 -1
- package/dist/css/navigation-menu.css +1 -1
- package/dist/css/number-field.css +1 -1
- package/dist/css/otp-field.css +1 -1
- package/dist/css/page-header.css +3 -3
- package/dist/css/pagination.css +2 -2
- package/dist/css/popover.css +1 -1
- package/dist/css/preview-card.css +2 -2
- package/dist/css/progress.css +1 -1
- package/dist/css/radio-group.css +1 -1
- package/dist/css/rules/accordion.css +5 -5
- package/dist/css/rules/alert-dialog.css +9 -9
- package/dist/css/rules/app-shell.css +274 -82
- package/dist/css/rules/avatar.css +7 -7
- package/dist/css/rules/badge.css +6 -6
- package/dist/css/rules/bar.css +11 -11
- package/dist/css/rules/base.css +30 -30
- package/dist/css/rules/bottom-navigation.css +57 -56
- package/dist/css/rules/breadcrumbs.css +2 -2
- package/dist/css/rules/button.css +66 -65
- package/dist/css/rules/card.css +3 -3
- package/dist/css/rules/chart.css +134 -124
- package/dist/css/rules/checkbox.css +5 -5
- package/dist/css/rules/choice-label.css +19 -18
- package/dist/css/rules/choice.css +65 -60
- package/dist/css/rules/code.css +2 -2
- package/dist/css/rules/collapsible.css +2 -2
- package/dist/css/rules/combobox.css +87 -83
- package/dist/css/rules/context-menu.css +1 -1
- package/dist/css/rules/date-picker.css +150 -144
- package/dist/css/rules/dialog.css +85 -79
- package/dist/css/rules/disclosure.css +49 -47
- package/dist/css/rules/drawer.css +6 -6
- package/dist/css/rules/empty-state.css +2 -2
- package/dist/css/rules/field-control.css +51 -42
- package/dist/css/rules/field.css +26 -24
- package/dist/css/rules/fieldset.css +8 -8
- package/dist/css/rules/file-upload.css +73 -72
- package/dist/css/rules/filter-bar.css +19 -18
- package/dist/css/rules/form.css +3 -3
- package/dist/css/rules/gauge.css +22 -22
- package/dist/css/rules/icon.css +16 -11
- package/dist/css/rules/inline-message.css +3 -3
- package/dist/css/rules/input-group.css +44 -43
- package/dist/css/rules/input.css +11 -11
- package/dist/css/rules/item.css +7 -7
- package/dist/css/rules/link.css +2 -2
- package/dist/css/rules/list.css +3 -3
- package/dist/css/rules/markdown.css +27 -27
- package/dist/css/rules/menu.css +45 -42
- package/dist/css/rules/menubar.css +6 -6
- package/dist/css/rules/navigation-menu.css +69 -66
- package/dist/css/rules/number-field.css +22 -21
- package/dist/css/rules/otp-field.css +28 -27
- package/dist/css/rules/panel.css +105 -100
- package/dist/css/rules/popover.css +23 -20
- package/dist/css/rules/popup.css +15 -14
- package/dist/css/rules/preview-card.css +20 -19
- package/dist/css/rules/progress.css +3 -3
- package/dist/css/rules/radio-group.css +8 -8
- package/dist/css/rules/scroll-area.css +50 -39
- package/dist/css/rules/select.css +39 -36
- package/dist/css/rules/sizing.css +119 -116
- package/dist/css/rules/skeleton.css +11 -11
- package/dist/css/rules/slider.css +43 -43
- package/dist/css/rules/sparkline.css +21 -21
- package/dist/css/rules/spinner.css +9 -9
- package/dist/css/rules/stat.css +32 -32
- package/dist/css/rules/switch.css +28 -21
- package/dist/css/rules/syntax-highlighter.css +37 -36
- package/dist/css/rules/table.css +10 -10
- package/dist/css/rules/tabs.css +53 -52
- package/dist/css/rules/textarea.css +9 -7
- package/dist/css/rules/toast.css +94 -90
- package/dist/css/rules/toggle.css +12 -12
- package/dist/css/rules/toolbar.css +27 -27
- package/dist/css/rules/tooltip.css +14 -14
- package/dist/css/rules/tree.css +38 -38
- package/dist/css/scroll-area.css +1 -1
- package/dist/css/select.css +1 -1
- package/dist/css/separator.css +2 -2
- package/dist/css/sheet.css +2 -2
- package/dist/css/sizing.css +1 -1
- package/dist/css/skeleton.css +1 -1
- package/dist/css/slider.css +1 -1
- package/dist/css/sparkline.css +1 -1
- package/dist/css/spinner.css +1 -1
- package/dist/css/stat.css +1 -1
- package/dist/css/styles.css +17 -17
- package/dist/css/switch.css +1 -1
- package/dist/css/syntax-highlighter.css +1 -1
- package/dist/css/table.css +2 -2
- package/dist/css/tabs.css +1 -1
- package/dist/css/textarea.css +1 -1
- package/dist/css/toast.css +1 -1
- package/dist/css/toggle-group.css +1 -1
- package/dist/css/toggle.css +1 -1
- package/dist/css/toolbar.css +1 -1
- package/dist/css/tooltip.css +1 -1
- package/dist/css/tree.css +1 -1
- package/dist/css/typography.css +2 -2
- package/dist/date-picker.js +28 -8
- package/dist/dialog.d.ts +20 -8
- package/dist/dialog.js +11 -12
- package/dist/drawer.d.ts +12 -4
- package/dist/drawer.js +5 -5
- package/dist/element-part.d.ts +8 -0
- package/dist/element-part.js +21 -0
- package/dist/empty-state.d.ts +602 -24
- package/dist/empty-state.js +9 -9
- package/dist/field.d.ts +60 -36
- package/dist/field.js +6 -6
- package/dist/fieldset.d.ts +19 -11
- package/dist/fieldset.js +2 -2
- package/dist/file-upload.d.ts +8 -23
- package/dist/file-upload.js +21 -16
- package/dist/filter-bar.d.ts +30 -10
- package/dist/filter-bar.js +16 -18
- package/dist/form.js +1 -1
- package/dist/icon.d.ts +9 -2
- package/dist/icon.js +6 -6
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -3
- package/dist/inline-message.d.ts +51 -27
- package/dist/inline-message.js +10 -11
- package/dist/input.d.ts +4 -2
- package/dist/input.js +3 -4
- package/dist/layout.d.ts +24 -12
- package/dist/layout.js +27 -27
- package/dist/link.d.ts +3 -1
- package/dist/link.js +3 -4
- package/dist/list.d.ts +43 -27
- package/dist/list.js +12 -13
- package/dist/markdown.d.ts +14 -6
- package/dist/markdown.js +28 -11
- package/dist/menu.d.ts +113 -57
- package/dist/menu.js +24 -25
- package/dist/menubar.d.ts +5 -3
- package/dist/menubar.js +1 -1
- package/dist/meter.d.ts +46 -26
- package/dist/meter.js +5 -5
- package/dist/native-select.d.ts +4 -2
- package/dist/native-select.js +2 -2
- package/dist/navigation-menu.d.ts +76 -40
- package/dist/navigation-menu.js +15 -16
- package/dist/number-field.d.ts +44 -19
- package/dist/number-field.js +12 -13
- package/dist/otp-field.d.ts +26 -9
- package/dist/otp-field.js +10 -11
- package/dist/page-header.js +3 -4
- package/dist/pagination.d.ts +11 -8
- package/dist/pagination.js +4 -5
- package/dist/panel.d.ts +3 -1
- package/dist/panel.js +5 -6
- package/dist/parts.d.ts +5 -7
- package/dist/parts.js +8 -16
- package/dist/popover.d.ts +20 -12
- package/dist/popover.js +3 -3
- package/dist/preview-card.d.ts +22 -10
- package/dist/preview-card.js +7 -8
- package/dist/progress.d.ts +46 -26
- package/dist/progress.js +5 -5
- package/dist/radio-group.d.ts +16 -8
- package/dist/radio-group.js +5 -5
- package/dist/scroll-area.d.ts +4 -2
- package/dist/scroll-area.js +6 -6
- package/dist/select.d.ts +3 -1
- package/dist/select.js +5 -5
- package/dist/separator.d.ts +5 -2
- package/dist/separator.js +3 -4
- package/dist/sheet.d.ts +12 -4
- package/dist/sheet.js +5 -5
- package/dist/size.d.ts +7 -0
- package/dist/size.js +9 -0
- package/dist/sizing.d.ts +8 -3
- package/dist/sizing.js +8 -10
- package/dist/skeleton.d.ts +3 -3
- package/dist/skeleton.js +4 -6
- package/dist/slider.d.ts +55 -31
- package/dist/slider.js +7 -7
- package/dist/sparkline.d.ts +5 -20
- package/dist/sparkline.js +5 -7
- package/dist/spinner.d.ts +4 -6
- package/dist/spinner.js +7 -8
- package/dist/stat.d.ts +34 -42
- package/dist/stat.js +9 -10
- package/dist/status.js +0 -1
- package/dist/switch.d.ts +17 -8
- package/dist/switch.js +4 -5
- package/dist/syntax-context.d.ts +11 -2
- package/dist/syntax-context.js +34 -1
- package/dist/syntax-engine.js +9 -1
- package/dist/syntax-highlighter.d.ts +3 -7
- package/dist/syntax-highlighter.js +37 -26
- package/dist/syntax-highlighting.d.ts +14 -1
- package/dist/syntax-highlighting.js +54 -3
- package/dist/table.d.ts +111 -75
- package/dist/table.js +32 -33
- package/dist/tabs.d.ts +46 -26
- package/dist/tabs.js +5 -5
- package/dist/textarea.d.ts +4 -2
- package/dist/textarea.js +3 -4
- package/dist/toast.d.ts +76 -42
- package/dist/toast.js +28 -28
- package/dist/toggle-group.js +1 -1
- package/dist/toggle.js +1 -1
- package/dist/tone-transition.d.ts +1 -1
- package/dist/tone-transition.js +9 -8
- package/dist/toolbar.d.ts +55 -31
- package/dist/toolbar.js +6 -6
- package/dist/tooltip.d.ts +4 -1
- package/dist/tooltip.js +2 -2
- package/dist/tree.d.ts +12 -1
- package/dist/tree.js +13 -9
- package/dist/typography.d.ts +3 -1
- package/dist/typography.js +6 -8
- package/package.json +6 -5
package/dist/card.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
'use client';
|
|
2
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
2
|
import * as React from 'react';
|
|
4
3
|
import { Surface } from './layout.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
});
|
|
9
|
-
|
|
4
|
+
import { cx } from './class-names.js';
|
|
5
|
+
import { elementPart } from './element-part.js';
|
|
6
|
+
const CardRoot = function CardRoot({ className, padding, ref, ...props }) {
|
|
7
|
+
return (_jsx(Surface, { ...props, padding: padding, ref: ref, className: cx('surf-card', className) }));
|
|
8
|
+
};
|
|
9
|
+
const CardTitle = function CardTitle({ level = 3, className, ref, ...props }) {
|
|
10
10
|
return React.createElement(`h${level}`, {
|
|
11
11
|
...props,
|
|
12
12
|
ref,
|
|
13
|
-
className: cx('
|
|
13
|
+
className: cx('surf-card-title', className),
|
|
14
14
|
});
|
|
15
|
-
}
|
|
15
|
+
};
|
|
16
16
|
export const Card = {
|
|
17
17
|
Root: CardRoot,
|
|
18
|
-
Header: /* @__PURE__ */
|
|
18
|
+
Header: /* @__PURE__ */ elementPart('div', 'surf-card-header'),
|
|
19
19
|
Title: CardTitle,
|
|
20
|
-
Description: /* @__PURE__ */
|
|
21
|
-
Body: /* @__PURE__ */
|
|
22
|
-
Footer: /* @__PURE__ */
|
|
20
|
+
Description: /* @__PURE__ */ elementPart('p', 'surf-card-description'),
|
|
21
|
+
Body: /* @__PURE__ */ elementPart('div', 'surf-card-body'),
|
|
22
|
+
Footer: /* @__PURE__ */ elementPart('div', 'surf-card-footer'),
|
|
23
23
|
};
|
|
24
24
|
// Flat names for React Server Components, which cannot dot into client exports.
|
|
25
25
|
export { CardRoot, CardTitle };
|
package/dist/chart.d.ts
CHANGED
|
@@ -25,13 +25,11 @@ export type ChartProps = Omit<React.ComponentPropsWithoutRef<'figure'>, 'childre
|
|
|
25
25
|
* for categories that color must separate, such as buckets or sectors. */
|
|
26
26
|
palette?: 'neutral' | 'categorical';
|
|
27
27
|
locale?: string;
|
|
28
|
+
/** Formats a value for the readout, the table and the value axis ticks. The unit
|
|
29
|
+
* follows it in the readout and the table, and names the axis. */
|
|
28
30
|
formatValue?: (value: number) => string;
|
|
29
31
|
/** Text the chart shows or announces; pass translations here. */
|
|
30
32
|
labels?: Partial<ChartLabels>;
|
|
31
|
-
/** @deprecated Use labels.missing. */
|
|
32
|
-
missingLabel?: string;
|
|
33
|
-
/** @deprecated Use labels.empty. */
|
|
34
|
-
emptyLabel?: string;
|
|
35
33
|
hiddenSeries?: readonly string[];
|
|
36
34
|
defaultHiddenSeries?: readonly string[];
|
|
37
35
|
onHiddenSeriesChange?: (keys: string[]) => void;
|
|
@@ -50,34 +48,13 @@ export type ChartLabels = {
|
|
|
50
48
|
inspectHint: string;
|
|
51
49
|
/** The data table's only row when there is no data. */
|
|
52
50
|
noRows: string;
|
|
51
|
+
/** The legend list, given the chart's title. */
|
|
52
|
+
legend: (title: string) => string;
|
|
53
|
+
/** A legend button that shows or hides a series. */
|
|
54
|
+
series: (label: string) => string;
|
|
53
55
|
};
|
|
54
56
|
/** Cartesian trends with a persistent, keyboard-readable tooltip region and a
|
|
55
57
|
* full data-table alternative. Missing values are gaps, never fabricated zeros. */
|
|
56
|
-
export declare const Chart:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
data: readonly ChartDatum[];
|
|
60
|
-
series: readonly ChartSeries[];
|
|
61
|
-
unit: string;
|
|
62
|
-
xLabel: string;
|
|
63
|
-
yLabel: string;
|
|
64
|
-
type?: "line" | "bar" | "area";
|
|
65
|
-
height?: number;
|
|
66
|
-
/** Keeps 0 on the value axis. Turn it off for values far from zero, such as
|
|
67
|
-
* prices, so the line uses the height; bars always start at zero. */
|
|
68
|
-
includeZero?: boolean;
|
|
69
|
-
/** neutral tells series apart by ink, dashes and markers. categorical adds six hues,
|
|
70
|
-
* for categories that color must separate, such as buckets or sectors. */
|
|
71
|
-
palette?: "neutral" | "categorical";
|
|
72
|
-
locale?: string;
|
|
73
|
-
formatValue?: (value: number) => string;
|
|
74
|
-
/** Text the chart shows or announces; pass translations here. */
|
|
75
|
-
labels?: Partial<ChartLabels>;
|
|
76
|
-
/** @deprecated Use labels.missing. */
|
|
77
|
-
missingLabel?: string;
|
|
78
|
-
/** @deprecated Use labels.empty. */
|
|
79
|
-
emptyLabel?: string;
|
|
80
|
-
hiddenSeries?: readonly string[];
|
|
81
|
-
defaultHiddenSeries?: readonly string[];
|
|
82
|
-
onHiddenSeriesChange?: (keys: string[]) => void;
|
|
83
|
-
} & React.RefAttributes<HTMLElement>>;
|
|
58
|
+
export declare const Chart: ({ title, description, data, series, unit, xLabel, yLabel, type, height, includeZero, palette, locale, formatValue, labels, hiddenSeries, defaultHiddenSeries, onHiddenSeriesChange, className, ref, ...props }: ChartProps & {
|
|
59
|
+
ref?: React.Ref<HTMLElement>;
|
|
60
|
+
}) => React.JSX.Element;
|
package/dist/chart.js
CHANGED
|
@@ -18,6 +18,8 @@ const chartLabels = {
|
|
|
18
18
|
tableCaption: (unit) => `All input measurements, including hidden series. Unit: ${unit}.`,
|
|
19
19
|
inspectHint: 'Hover, touch or use chart arrow keys to inspect a measurement.',
|
|
20
20
|
noRows: 'No rows.',
|
|
21
|
+
legend: (title) => `${title} series`,
|
|
22
|
+
series: (label) => `${label} series`,
|
|
21
23
|
};
|
|
22
24
|
/** The round step at or above a raw step: 1, 2, 2.5 or 5 times a power of ten. */
|
|
23
25
|
function roundStep(raw) {
|
|
@@ -26,22 +28,56 @@ function roundStep(raw) {
|
|
|
26
28
|
const power = 10 ** Math.floor(Math.log10(raw));
|
|
27
29
|
return power * ([1, 2, 2.5, 5, 10].find((f) => f * power >= raw) ?? 10);
|
|
28
30
|
}
|
|
31
|
+
/** The smallest round step that spans low to high in at most five intervals, so the
|
|
32
|
+
* top tick is the round value just above the highest one. */
|
|
33
|
+
function axisStep(low, high) {
|
|
34
|
+
let step = roundStep((high - low) / 5);
|
|
35
|
+
while (step && Math.ceil(high / step) - Math.floor(low / step) > 5)
|
|
36
|
+
step = roundStep(step * 1.01);
|
|
37
|
+
return step;
|
|
38
|
+
}
|
|
29
39
|
const dashes = [undefined, '7 4', '2 4', '10 3 2 3', '12 5', '4 3'];
|
|
40
|
+
/** True once the font of the tick labels has loaded. Recharts measures a label to keep
|
|
41
|
+
* it inside the chart and caches that width; measured in the fallback font, the last
|
|
42
|
+
* label overflows by a few pixels once the real font arrives. */
|
|
43
|
+
function useFontReady(element, text) {
|
|
44
|
+
const [ready, setReady] = React.useState(false);
|
|
45
|
+
React.useEffect(() => {
|
|
46
|
+
if (!element)
|
|
47
|
+
return;
|
|
48
|
+
if (!document.fonts)
|
|
49
|
+
return setReady(true);
|
|
50
|
+
let live = true;
|
|
51
|
+
const family = getComputedStyle(element).fontFamily;
|
|
52
|
+
// load() starts the download of the faces that draw this text and waits for them.
|
|
53
|
+
void document.fonts
|
|
54
|
+
.load(`12px ${family}`, text || ' ')
|
|
55
|
+
.catch(() => [])
|
|
56
|
+
.then(() => {
|
|
57
|
+
if (live)
|
|
58
|
+
setReady(true);
|
|
59
|
+
});
|
|
60
|
+
return () => {
|
|
61
|
+
live = false;
|
|
62
|
+
};
|
|
63
|
+
}, [element, text]);
|
|
64
|
+
return ready;
|
|
65
|
+
}
|
|
30
66
|
function Marker({ cx, cy, color, index, }) {
|
|
31
67
|
if (typeof cx !== 'number' ||
|
|
32
68
|
typeof cy !== 'number' ||
|
|
33
69
|
!Number.isFinite(cx) ||
|
|
34
70
|
!Number.isFinite(cy))
|
|
35
71
|
return null;
|
|
36
|
-
const props = { fill: 'var(--canvas)', stroke: color, strokeWidth: 1.8 };
|
|
72
|
+
const props = { fill: 'var(--surf-canvas)', stroke: color, strokeWidth: 1.8 };
|
|
37
73
|
return index % 3 === 0 ? (_jsx("circle", { cx: cx, cy: cy, r: 3.5, ...props })) : index % 3 === 1 ? (_jsx("rect", { x: cx - 3.5, y: cy - 3.5, width: 7, height: 7, ...props })) : (_jsx("path", { d: `M${cx},${cy - 4.5}l4.5,8h-9Z`, ...props }));
|
|
38
74
|
}
|
|
39
75
|
function Pattern({ id, index, color, }) {
|
|
40
|
-
return (_jsxs("pattern", { id: id, patternUnits: 'userSpaceOnUse', width: '8', height: '8', children: [_jsx("rect", { width: '8', height: '8', fill: color }), index % 3 === 1 ? (_jsx("path", { d: 'M-2 2L2-2M0 8L8 0M6 10L10 6', stroke: 'var(--canvas)', strokeWidth: '1.5' })) : index % 3 === 2 ? (_jsx("circle", { cx: '4', cy: '4', r: '1.4', fill: 'var(--canvas)' })) : null] }));
|
|
76
|
+
return (_jsxs("pattern", { id: id, patternUnits: 'userSpaceOnUse', width: '8', height: '8', children: [_jsx("rect", { width: '8', height: '8', fill: color }), index % 3 === 1 ? (_jsx("path", { d: 'M-2 2L2-2M0 8L8 0M6 10L10 6', stroke: 'var(--surf-canvas)', strokeWidth: '1.5' })) : index % 3 === 2 ? (_jsx("circle", { cx: '4', cy: '4', r: '1.4', fill: 'var(--surf-canvas)' })) : null] }));
|
|
41
77
|
}
|
|
42
78
|
/** A series' swatch, as the legend and the floating values draw it. */
|
|
43
79
|
function SeriesMark({ type, index, color, pattern, }) {
|
|
44
|
-
return (_jsx("svg", { className: '
|
|
80
|
+
return (_jsx("svg", { className: 'surf-chart-mark', viewBox: '0 0 32 20', "aria-hidden": 'true', focusable: 'false', children: type === 'bar' ? (_jsxs(_Fragment, { children: [_jsx("defs", { children: _jsx(Pattern, { id: pattern, color: color, index: index }) }), _jsx("rect", { x: '4', y: '3', width: '24', height: '14', rx: '2', fill: `url(#${pattern})` })] })) : (_jsxs(_Fragment, { children: [_jsx("path", { d: 'M1 10h30', stroke: color, strokeWidth: '2', strokeDasharray: dashes[index % dashes.length] }), _jsx(Marker, { cx: 16, cy: 10, index: index, color: color })] })) }));
|
|
45
81
|
}
|
|
46
82
|
/** The active point's values beside it, for pointer and touch users. The readout
|
|
47
83
|
* below the plot announces the same values, so this copy stays out of the
|
|
@@ -61,29 +97,25 @@ function FloatingValues({ host, hidden, render, }) {
|
|
|
61
97
|
}, [shown, label, plot?.width]);
|
|
62
98
|
if (!shown || !point || !plot)
|
|
63
99
|
return null;
|
|
64
|
-
// The gap between the point and the box, in px: the --space-3 step.
|
|
100
|
+
// The gap between the point and the box, in px: the --surf-space-3 step.
|
|
65
101
|
const gap = 12;
|
|
66
102
|
const start = point.x > plot.x + plot.width / 2;
|
|
67
103
|
const left = Math.min(Math.max(start ? point.x - gap - width : point.x + gap, plot.x), plot.x + plot.width - width);
|
|
68
|
-
return createPortal(_jsx("div", { ref: box, className: '
|
|
104
|
+
return createPortal(_jsx("div", { ref: box, className: 'surf-chart-tooltip', "aria-hidden": 'true', style: { left, top: plot.y, visibility: width ? undefined : 'hidden' }, children: render(String(label)) }), host);
|
|
69
105
|
}
|
|
70
106
|
/** Cartesian trends with a persistent, keyboard-readable tooltip region and a
|
|
71
107
|
* full data-table alternative. Missing values are gaps, never fabricated zeros. */
|
|
72
|
-
export const Chart =
|
|
73
|
-
const text = {
|
|
74
|
-
...chartLabels,
|
|
75
|
-
...(missingLabel === undefined ? {} : { missing: missingLabel }),
|
|
76
|
-
...(emptyLabel === undefined ? {} : { empty: emptyLabel }),
|
|
77
|
-
...labels,
|
|
78
|
-
};
|
|
108
|
+
export const Chart = function Chart({ title, description, data, series, unit, xLabel, yLabel, type = 'line', height = 280, includeZero = true, palette = 'neutral', locale = 'en-US', formatValue, labels, hiddenSeries, defaultHiddenSeries = [], onHiddenSeriesChange, className, ref, ...props }) {
|
|
109
|
+
const text = { ...chartLabels, ...labels };
|
|
79
110
|
const id = React.useId().replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
80
111
|
const colorFor = (index) => palette === 'categorical'
|
|
81
|
-
? `var(--chart-category-${(index % 6) + 1})`
|
|
82
|
-
: `var(--chart-series-${(index % 3) + 1})`;
|
|
112
|
+
? `var(--surf-chart-category-${(index % 6) + 1})`
|
|
113
|
+
: `var(--surf-chart-series-${(index % 3) + 1})`;
|
|
83
114
|
const [internalHidden, setInternalHidden] = React.useState(defaultHiddenSeries);
|
|
84
115
|
const hidden = new Set(hiddenSeries ?? internalHidden);
|
|
85
116
|
const visible = series.filter((s) => !hidden.has(s.key));
|
|
86
117
|
const [host, setHost] = React.useState(null);
|
|
118
|
+
const fontsReady = useFontReady(host, data.map((d) => d.label).join(''));
|
|
87
119
|
const [floatHost, setFloatHost] = React.useState(null);
|
|
88
120
|
const [dismissed, setDismissed] = React.useState(false);
|
|
89
121
|
const firstLegend = React.useRef(null);
|
|
@@ -130,15 +162,17 @@ export const Chart = /* @__PURE__ */ React.forwardRef(function Chart({ title, de
|
|
|
130
162
|
const values = rows
|
|
131
163
|
.flatMap((row) => visible.map((s) => row.values[s.key]))
|
|
132
164
|
.filter((value) => typeof value === 'number');
|
|
133
|
-
// Bars grow from zero, so they always keep it on the axis.
|
|
165
|
+
// Bars grow from zero, so they always keep it on the axis. Either way the axis
|
|
134
166
|
// spans the values, widened to round steps so its ticks read cleanly.
|
|
135
167
|
const keepZero = includeZero || type === 'bar';
|
|
136
168
|
const start = keepZero ? 0 : (values[0] ?? 0);
|
|
137
169
|
const low = values.reduce((a, b) => Math.min(a, b), start), high = values.reduce((a, b) => Math.max(a, b), start);
|
|
138
|
-
const step =
|
|
170
|
+
const step = axisStep(low, high);
|
|
139
171
|
const min = step ? Math.floor(low / step) * step : low, max = step ? Math.ceil(high / step) * step : high;
|
|
140
172
|
const ticks = step
|
|
141
|
-
? Array.from({ length: Math.round((max - min) / step) + 1 },
|
|
173
|
+
? Array.from({ length: Math.round((max - min) / step) + 1 },
|
|
174
|
+
// Rounded, so float steps never print as 0.30000000000000004.
|
|
175
|
+
(_, index) => Number((min + index * step).toPrecision(12)))
|
|
142
176
|
: undefined;
|
|
143
177
|
const hasValues = values.length > 0;
|
|
144
178
|
const changeHidden = (next) => {
|
|
@@ -150,23 +184,28 @@ export const Chart = /* @__PURE__ */ React.forwardRef(function Chart({ title, de
|
|
|
150
184
|
.filter((s) => (s.key === key ? !hidden.has(key) : hidden.has(s.key)))
|
|
151
185
|
.map((s) => s.key));
|
|
152
186
|
const chartHeight = Number.isFinite(height) ? Math.max(200, height) : 280;
|
|
153
|
-
return (_jsxs("figure", { ...props, ref: ref, className: cx('
|
|
187
|
+
return (_jsxs("figure", { ...props, ref: ref, className: cx('surf-chart', className), "aria-labelledby": `${id}-title`, children: [_jsxs("figcaption", { className: 'surf-chart-caption', children: [_jsx("strong", { id: `${id}-title`, children: title }), _jsx("p", { id: `${id}-summary`, children: description })] }), _jsxs("div", { className: 'surf-chart-frame', children: [_jsxs("div", { className: 'surf-chart-key', children: [_jsxs("p", { className: 'surf-chart-axis-label', children: [yLabel, " (", unit, ")"] }), _jsx("ul", { className: 'surf-chart-legend', "aria-label": text.legend(title), children: series.map((s, index) => (_jsx("li", { children: _jsxs("button", { ref: index === 0 ? firstLegend : undefined, type: 'button', className: 'surf-chart-legend-button', "aria-label": text.series(s.label), "aria-pressed": !hidden.has(s.key), onClick: () => toggle(s.key), children: [_jsx(SeriesMark, { type: type, index: index, color: colorFor(index), pattern: `${id}-legend-${index}` }), _jsx("span", { children: s.label })] }) }, s.key))) })] }), hasValues ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: 'surf-chart-plot', onKeyDownCapture: (event) => {
|
|
154
188
|
if (event.key === 'Escape')
|
|
155
189
|
setDismissed(true);
|
|
156
190
|
else if (event.key === 'ArrowLeft' ||
|
|
157
191
|
event.key === 'ArrowRight')
|
|
158
192
|
setDismissed(false);
|
|
159
|
-
}, onMouseMoveCapture: () => setDismissed(false), onTouchStartCapture: () => setDismissed(false), onFocusCapture: () => setDismissed(false), children: [_jsx(ResponsiveContainer, { width: '100%', height: chartHeight, minWidth: 0, initialDimension: { width: 320, height: chartHeight }, children: _jsxs(ComposedChart, { data: rows, accessibilityLayer: true, role: 'application', "aria-label": title, "aria-describedby": `${id}-summary ${id}-keys`, margin: { top: 16, right: 20, bottom: 8, left: 0 }, children: [_jsx("defs", { children: series.map((s, index) => (_jsx(Pattern, { id: `${id}-pattern-${index}`, index: index, color: colorFor(index) }, s.key))) }), _jsx(CartesianGrid, { vertical: false, stroke: 'var(--line)' }), _jsx(XAxis, { dataKey: 'id', tickFormatter: (value) => {
|
|
193
|
+
}, onMouseMoveCapture: () => setDismissed(false), onTouchStartCapture: () => setDismissed(false), onFocusCapture: () => setDismissed(false), children: [_jsx(ResponsiveContainer, { width: '100%', height: chartHeight, minWidth: 0, initialDimension: { width: 320, height: chartHeight }, children: _jsxs(ComposedChart, { data: rows, accessibilityLayer: true, role: 'application', "aria-label": title, "aria-describedby": `${id}-summary ${id}-keys`, margin: { top: 16, right: 20, bottom: 8, left: 0 }, children: [_jsx("defs", { children: series.map((s, index) => (_jsx(Pattern, { id: `${id}-pattern-${index}`, index: index, color: colorFor(index) }, s.key))) }), _jsx(CartesianGrid, { vertical: false, stroke: 'var(--surf-line)' }), _jsx(XAxis, { dataKey: 'id', tickFormatter: (value) => {
|
|
160
194
|
const label = byId.get(String(value))?.label ?? String(value);
|
|
161
195
|
// minTickGap already drops ticks that would overlap; the cap
|
|
162
196
|
// only keeps one very long label from crowding the axis.
|
|
163
197
|
return label.length > 24
|
|
164
198
|
? label.slice(0, 23) + '…'
|
|
165
199
|
: label;
|
|
166
|
-
}, tick:
|
|
200
|
+
}, tick: fontsReady && {
|
|
201
|
+
fill: 'var(--surf-ink-muted)',
|
|
202
|
+
fontSize: 12,
|
|
203
|
+
}, tickLine: false, axisLine: { stroke: 'var(--surf-line)' }, minTickGap: 24, interval: 'preserveStartEnd' }), _jsx(YAxis, { width: 56, tickFormatter: (value) => formatValue
|
|
204
|
+
? formatValue(Number(value))
|
|
205
|
+
: compact.format(Number(value)), tick: { fill: 'var(--surf-ink-muted)', fontSize: 12 }, tickLine: false, axisLine: false, domain: [min, max === min ? max + 1 : max], ticks: ticks }), _jsx(ReferenceLine, { y: 0, stroke: 'var(--surf-ink-muted)' }), host && (_jsx(Tooltip, { portal: host, isAnimationActive: false, active: dismissed ? false : undefined, filterNull: false, cursor: dismissed
|
|
167
206
|
? false
|
|
168
207
|
: {
|
|
169
|
-
stroke: 'var(--control-border)',
|
|
208
|
+
stroke: 'var(--surf-control-border)',
|
|
170
209
|
fill: 'transparent',
|
|
171
210
|
}, wrapperStyle: {
|
|
172
211
|
position: 'static',
|
|
@@ -176,7 +215,7 @@ export const Chart = /* @__PURE__ */ React.forwardRef(function Chart({ title, de
|
|
|
176
215
|
const row = tooltip.active && !dismissed
|
|
177
216
|
? byId.get(String(tooltip.label))
|
|
178
217
|
: undefined;
|
|
179
|
-
return (_jsx("div", { className: '
|
|
218
|
+
return (_jsx("div", { className: 'surf-chart-readout', "data-chart-readout": row?.id, children: row ? (_jsxs(_Fragment, { children: [_jsx("strong", { children: row.label }), _jsx("ul", { children: visible.map((s) => (_jsxs("li", { children: [s.label, ": ", format(row.values[s.key])] }, s.key))) })] })) : (_jsx("span", { children: text.inspectHint })) }));
|
|
180
219
|
} })), series.map((s, index) => {
|
|
181
220
|
const common = {
|
|
182
221
|
name: s.label,
|
|
@@ -194,9 +233,9 @@ export const Chart = /* @__PURE__ */ React.forwardRef(function Chart({ title, de
|
|
|
194
233
|
const row = byId.get(label);
|
|
195
234
|
if (!row)
|
|
196
235
|
return null;
|
|
197
|
-
return (_jsxs(_Fragment, { children: [_jsx("strong", { children: row.label }), _jsx("ul", { children: series.map((s, index) => hidden.has(s.key) ? null : (_jsxs("li", { children: [_jsx(SeriesMark, { type: type, index: index, color: colorFor(index), pattern: `${id}-float-${index}` }), _jsx("span", { children: s.label }), _jsx("span", { className: '
|
|
198
|
-
} })] }) }), _jsx("div", { className: '
|
|
236
|
+
return (_jsxs(_Fragment, { children: [_jsx("strong", { children: row.label }), _jsx("ul", { children: series.map((s, index) => hidden.has(s.key) ? null : (_jsxs("li", { children: [_jsx(SeriesMark, { type: type, index: index, color: colorFor(index), pattern: `${id}-float-${index}` }), _jsx("span", { children: s.label }), _jsx("span", { className: 'surf-chart-tooltip-value', children: format(row.values[s.key]) })] }, s.key))) })] }));
|
|
237
|
+
} })] }) }), _jsx("div", { className: 'surf-chart-float', ref: setFloatHost })] }), _jsx("p", { className: 'surf-chart-axis-label surf-chart-x-label', children: xLabel })] })) : (_jsx("div", { className: 'surf-chart-empty', role: 'status', children: visible.length === 0 && series.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("p", { children: text.noSeries }), _jsx(Button, { variant: 'outline', onClick: () => {
|
|
199
238
|
setRestoreRequested(true);
|
|
200
239
|
changeHidden([]);
|
|
201
|
-
}, children: text.showAll })] })) : (_jsx("p", { children: text.empty })) }))] }), hasValues && (_jsx("p", { className: '
|
|
202
|
-
}
|
|
240
|
+
}, children: text.showAll })] })) : (_jsx("p", { children: text.empty })) }))] }), hasValues && (_jsx("p", { className: 'surf-chart-help', id: `${id}-keys`, children: text.keyboardHelp })), _jsx("div", { className: 'surf-chart-inspector', ref: setHost, role: 'status', "aria-live": 'polite', "aria-atomic": 'true', "aria-label": text.values(title), hidden: !hasValues }), _jsxs("details", { className: 'surf-chart-table', children: [_jsx("summary", { children: text.viewTable }), _jsx(Table.Container, { label: text.table(title), orientation: 'both', scrollChain: 'contain', children: _jsxs(Table.Root, { children: [_jsx(Table.Caption, { children: text.tableCaption(unit) }), _jsx(Table.Head, { children: _jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'col', children: xLabel }), series.map((s) => (_jsxs(Table.HeaderCell, { scope: 'col', children: [s.label, " (", unit, ")"] }, s.key)))] }) }), _jsx(Table.Body, { children: rows.length ? (rows.map((row) => (_jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'row', children: row.label }), series.map((s) => (_jsx(Table.Cell, { children: format(row.values[s.key]) }, s.key)))] }, row.id)))) : (_jsx(Table.Row, { children: _jsx(Table.Cell, { colSpan: series.length + 1, children: text.noRows }) })) })] }) })] })] }));
|
|
241
|
+
};
|
package/dist/checkbox-group.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
|
|
2
|
+
import { CheckboxGroup as BaseCheckboxGroup } from '@base-ui/react/checkbox-group';
|
|
3
|
+
export declare const CheckboxGroup: ({ value, defaultValue, onValueChange, className, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCheckboxGroup> & {
|
|
4
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCheckboxGroup>>;
|
|
5
|
+
}) => React.JSX.Element;
|
package/dist/checkbox-group.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from 'react';
|
|
4
3
|
import { CheckboxGroup as BaseCheckboxGroup } from '@base-ui/react/checkbox-group';
|
|
5
4
|
import { skin } from './parts.js';
|
|
6
5
|
import { useRootRef, useResetValue } from './form-state.js';
|
|
7
6
|
import { ChoiceResetPaint } from './choice.js';
|
|
8
|
-
export const CheckboxGroup =
|
|
7
|
+
export const CheckboxGroup = function CheckboxGroup({ value, defaultValue = [], onValueChange, className, ref, ...props }) {
|
|
9
8
|
const [element, attach] = useRootRef(ref);
|
|
10
9
|
const [selected, setSelected, revision] = useResetValue(value, defaultValue, element);
|
|
11
|
-
return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseCheckboxGroup, { ...props, ref: attach, value: selected, className: skin('
|
|
10
|
+
return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseCheckboxGroup, { ...props, ref: attach, value: selected, className: skin('surf-choice-group', className), onValueChange: (next, event) => {
|
|
12
11
|
onValueChange?.(next, event);
|
|
13
12
|
if (value === undefined && !event.isCanceled)
|
|
14
13
|
setSelected(next);
|
|
15
14
|
} }) }));
|
|
16
|
-
}
|
|
15
|
+
};
|
package/dist/checkbox.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
|
|
2
3
|
import { type ChoiceSize } from './choice.js';
|
|
3
|
-
declare const CheckboxRoot:
|
|
4
|
-
|
|
4
|
+
declare const CheckboxRoot: ({ size, checked, defaultChecked, onCheckedChange, className, form, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCheckbox.Root> & ChoiceSize & {
|
|
5
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCheckbox.Root>>;
|
|
6
|
+
}) => React.JSX.Element;
|
|
7
|
+
declare const CheckboxIndicator: ({ className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCheckbox.Indicator> & {
|
|
8
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCheckbox.Indicator>>;
|
|
9
|
+
}) => React.JSX.Element;
|
|
5
10
|
export declare const Checkbox: {
|
|
6
|
-
Root:
|
|
7
|
-
|
|
11
|
+
Root: ({ size, checked, defaultChecked, onCheckedChange, className, form, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCheckbox.Root> & ChoiceSize & {
|
|
12
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCheckbox.Root>>;
|
|
13
|
+
}) => React.JSX.Element;
|
|
14
|
+
Indicator: ({ className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCheckbox.Indicator> & {
|
|
15
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCheckbox.Indicator>>;
|
|
16
|
+
}) => React.JSX.Element;
|
|
8
17
|
};
|
|
9
18
|
export { CheckboxIndicator, CheckboxRoot };
|
package/dist/checkbox.js
CHANGED
|
@@ -6,20 +6,20 @@ import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
|
|
|
6
6
|
import { skin } from './parts.js';
|
|
7
7
|
import { useRootRef, useResetValue } from './form-state.js';
|
|
8
8
|
import { ChoiceResetPaint } from './choice.js';
|
|
9
|
-
const CheckboxRoot =
|
|
9
|
+
const CheckboxRoot = function CheckboxRoot({ size, checked, defaultChecked = false, onCheckedChange, className, form, ref, ...props }) {
|
|
10
10
|
React.useContext(ChoiceResetPaint);
|
|
11
11
|
const scheme = useComponentSize(size);
|
|
12
12
|
const [element, attach] = useRootRef(ref);
|
|
13
13
|
const [selected, setSelected] = useResetValue(checked, defaultChecked, element, form);
|
|
14
|
-
return (_jsx(BaseCheckbox.Root, { ...props, "data-ui-size": size ? scheme : undefined, form: form, ref: attach, checked: selected, className: skin('
|
|
14
|
+
return (_jsx(BaseCheckbox.Root, { ...props, "data-ui-size": size ? scheme : undefined, form: form, ref: attach, checked: selected, className: skin('surf-checkbox', className), onCheckedChange: (next, event) => {
|
|
15
15
|
onCheckedChange?.(next, event);
|
|
16
16
|
if (checked === undefined && !event.isCanceled)
|
|
17
17
|
setSelected(next);
|
|
18
18
|
} }));
|
|
19
|
-
}
|
|
20
|
-
const CheckboxIndicator =
|
|
21
|
-
return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, className: skin('
|
|
22
|
-
}
|
|
19
|
+
};
|
|
20
|
+
const CheckboxIndicator = function CheckboxIndicator({ className, children, ref, ...props }) {
|
|
21
|
+
return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, className: skin('surf-checkbox-indicator', className), children: children ?? (_jsxs("svg", { width: '14', height: '14', viewBox: '0 0 20 20', fill: 'none', stroke: 'currentColor', strokeWidth: '2', "aria-hidden": 'true', children: [_jsx("path", { className: 'surf-checkbox-check', d: 'm4 10 4 4 8-8' }), _jsx("path", { className: 'surf-checkbox-mixed', d: 'M4 10h12' })] })) }));
|
|
22
|
+
};
|
|
23
23
|
export const Checkbox = {
|
|
24
24
|
...BaseCheckbox,
|
|
25
25
|
Root: CheckboxRoot,
|
package/dist/choice-label.d.ts
CHANGED
|
@@ -12,14 +12,6 @@ export type ChoiceLabelProps = Omit<React.ComponentPropsWithoutRef<'label'>, 'ch
|
|
|
12
12
|
};
|
|
13
13
|
/** A checkbox, radio or switch with its label, and an optional description below it.
|
|
14
14
|
* The whole label toggles the control; the control sits on the first line. */
|
|
15
|
-
export declare const ChoiceLabel:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"aria-labelledby"?: string;
|
|
19
|
-
"aria-describedby"?: string;
|
|
20
|
-
}>;
|
|
21
|
-
/** The label text; it alone names the control. */
|
|
22
|
-
children: React.ReactNode;
|
|
23
|
-
/** A longer explanation, read as the control's description. */
|
|
24
|
-
description?: React.ReactNode;
|
|
25
|
-
} & React.RefAttributes<HTMLLabelElement>>;
|
|
15
|
+
export declare const ChoiceLabel: ({ control, children, description, className, ref, ...props }: ChoiceLabelProps & {
|
|
16
|
+
ref?: React.Ref<HTMLLabelElement>;
|
|
17
|
+
}) => React.JSX.Element;
|
package/dist/choice-label.js
CHANGED
|
@@ -4,11 +4,11 @@ import * as React from 'react';
|
|
|
4
4
|
import { cx } from './parts.js';
|
|
5
5
|
/** A checkbox, radio or switch with its label, and an optional description below it.
|
|
6
6
|
* The whole label toggles the control; the control sits on the first line. */
|
|
7
|
-
export const ChoiceLabel =
|
|
7
|
+
export const ChoiceLabel = function ChoiceLabel({ control, children, description, className, ref, ...props }) {
|
|
8
8
|
const id = React.useId();
|
|
9
|
-
return (_jsxs("label", { ...props, ref: ref, className: cx('
|
|
9
|
+
return (_jsxs("label", { ...props, ref: ref, className: cx('surf-choice-label', className), children: [_jsx("span", { className: 'surf-choice-control', children: React.cloneElement(control, {
|
|
10
10
|
'aria-labelledby': control.props['aria-labelledby'] ?? `${id}-label`,
|
|
11
11
|
'aria-describedby': control.props['aria-describedby'] ??
|
|
12
12
|
(description ? `${id}-description` : undefined),
|
|
13
|
-
}) }), _jsxs("span", { className: '
|
|
14
|
-
}
|
|
13
|
+
}) }), _jsxs("span", { className: 'surf-choice-text', children: [_jsx("span", { id: `${id}-label`, children: children }), description && (_jsx("span", { className: 'surf-choice-description', id: `${id}-description`, children: description }))] })] }));
|
|
14
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Joins class names, skipping empty ones. */
|
|
2
|
+
export declare function cx(...classes: (string | false | null | undefined)[]): string;
|
|
3
|
+
/** The data-size value: a deprecated short spelling (sm, md, lg, icon-sm, icon-xs,
|
|
4
|
+
* icon-lg) renders as its full name, so both spellings meet the same CSS; other values
|
|
5
|
+
* such as xs or icon pass through. */
|
|
6
|
+
export declare function sizeName<Size extends string>(size?: Size): import("./size.js").ComponentSize | Size | "icon-small" | "icon-large" | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Class and data attribute helpers, with no React: server components use them too.
|
|
2
|
+
import { normalizeSize } from './size.js';
|
|
3
|
+
/** Joins class names, skipping empty ones. */
|
|
4
|
+
export function cx(...classes) {
|
|
5
|
+
return classes.filter(Boolean).join(' ');
|
|
6
|
+
}
|
|
7
|
+
/** The data-size value: a deprecated short spelling (sm, md, lg, icon-sm, icon-xs,
|
|
8
|
+
* icon-lg) renders as its full name, so both spellings meet the same CSS; other values
|
|
9
|
+
* such as xs or icon pass through. */
|
|
10
|
+
export function sizeName(size) {
|
|
11
|
+
return size === 'sm' || size === 'md' || size === 'lg'
|
|
12
|
+
? normalizeSize(size)
|
|
13
|
+
: size === 'icon-sm' || size === 'icon-xs'
|
|
14
|
+
? 'icon-small'
|
|
15
|
+
: size === 'icon-lg'
|
|
16
|
+
? 'icon-large'
|
|
17
|
+
: size;
|
|
18
|
+
}
|
package/dist/code.d.ts
CHANGED
|
@@ -4,18 +4,21 @@ export type CodeBlockProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'childr
|
|
|
4
4
|
label?: string;
|
|
5
5
|
language?: string;
|
|
6
6
|
wrap?: boolean;
|
|
7
|
+
/** The copy button's text: the action, then the result. */
|
|
8
|
+
labels?: Partial<CodeBlockLabels>;
|
|
9
|
+
/** @deprecated Use `labels.copy`. Removed in a later minor. */
|
|
7
10
|
copyLabel?: string;
|
|
11
|
+
/** @deprecated Use `labels.copied`. Removed in a later minor. */
|
|
8
12
|
copiedLabel?: string;
|
|
13
|
+
/** @deprecated Use `labels.copyError`. Removed in a later minor. */
|
|
9
14
|
copyErrorLabel?: string;
|
|
10
15
|
onCopy?: (code: string) => void | Promise<void>;
|
|
11
16
|
};
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
onCopy?: (code: string) => void | Promise<void>;
|
|
21
|
-
} & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export type CodeBlockLabels = {
|
|
18
|
+
copy: string;
|
|
19
|
+
copied: string;
|
|
20
|
+
copyError: string;
|
|
21
|
+
};
|
|
22
|
+
export declare const CodeBlock: ({ code, label, language, wrap, labels, copyLabel: legacyCopyLabel, copiedLabel: legacyCopiedLabel, copyErrorLabel: legacyCopyErrorLabel, onCopy, className, ref, ...props }: CodeBlockProps & {
|
|
23
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
24
|
+
}) => React.JSX.Element;
|
package/dist/code.js
CHANGED
|
@@ -9,7 +9,10 @@ import { ScrollArea } from './scroll-area.js';
|
|
|
9
9
|
const copyIcons = { idle: 'copy', copied: 'check', failed: 'alert' };
|
|
10
10
|
// Feedback stays inside the copy button and returns to the action after this long.
|
|
11
11
|
const copyFeedbackDuration = 2000;
|
|
12
|
-
export const CodeBlock =
|
|
12
|
+
export const CodeBlock = function CodeBlock({ code, label = 'Code', language, wrap = false, labels, copyLabel: legacyCopyLabel, copiedLabel: legacyCopiedLabel, copyErrorLabel: legacyCopyErrorLabel, onCopy, className, ref, ...props }) {
|
|
13
|
+
const copyLabel = labels?.copy ?? legacyCopyLabel ?? 'Copy code';
|
|
14
|
+
const copiedLabel = labels?.copied ?? legacyCopiedLabel ?? 'Copied';
|
|
15
|
+
const copyErrorLabel = labels?.copyError ?? legacyCopyErrorLabel ?? 'Copy unavailable';
|
|
13
16
|
const [state, setState] = React.useState('idle');
|
|
14
17
|
// After the first copy, each change of label fades in; the first render does not.
|
|
15
18
|
const [used, setUsed] = React.useState(false);
|
|
@@ -74,11 +77,11 @@ export const CodeBlock = /* @__PURE__ */ React.forwardRef(function CodeBlock({ c
|
|
|
74
77
|
}, copyFeedbackDuration);
|
|
75
78
|
}
|
|
76
79
|
const icon = state === 'copied' || state === 'failed' ? state : 'idle';
|
|
77
|
-
return (_jsxs("div", { ...props, ref: ref, "data-wrap": wrap || undefined, className: cx('
|
|
80
|
+
return (_jsxs("div", { ...props, ref: ref, "data-wrap": wrap || undefined, className: cx('surf-code-block', className), children: [_jsxs("div", { className: 'surf-code-toolbar', children: [_jsxs("span", { className: 'surf-code-label', children: [label, language && _jsx("span", { className: 'surf-code-language', children: language })] }), _jsxs(Button, { ref: button, type: 'button', variant: 'outline', size: 'small', className: 'surf-code-copy', onClick: copy,
|
|
78
81
|
// A pending copy blocks a second start but keeps focus on the button.
|
|
79
|
-
disabled: state === 'busy', focusableWhenDisabled: true, "aria-busy": state === 'busy' || undefined, "data-copy-state": icon === 'idle' ? undefined : icon, "data-copy-used": used || undefined, children: [_jsx(Icon, { name: copyIcons[icon], className: '
|
|
82
|
+
disabled: state === 'busy', focusableWhenDisabled: true, "aria-busy": state === 'busy' || undefined, "data-copy-state": icon === 'idle' ? undefined : icon, "data-copy-used": used || undefined, children: [_jsx(Icon, { name: copyIcons[icon], className: 'surf-code-copy-icon' }, icon), _jsx("span", { "aria-live": 'polite', children: _jsx("span", { className: 'surf-code-copy-label', children: state === 'copied'
|
|
80
83
|
? copiedLabel
|
|
81
84
|
: state === 'failed'
|
|
82
85
|
? copyErrorLabel
|
|
83
|
-
: copyLabel }, icon) })] })] }), _jsx(ScrollArea, { label: label, orientation: 'horizontal', children: _jsx("pre", { ref: source, className: '
|
|
84
|
-
}
|
|
86
|
+
: copyLabel }, icon) })] })] }), _jsx(ScrollArea, { label: label, orientation: 'horizontal', children: _jsx("pre", { ref: source, className: 'surf-code-text', children: _jsx(SyntaxHighlighter, { code: code, language: language, inline: true }) }) })] }));
|
|
87
|
+
};
|
package/dist/collapsible.d.ts
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
|
|
2
|
+
import { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';
|
|
3
|
+
declare const CollapsibleTrigger: ({ className, children, indicator, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCollapsible.Trigger> & {
|
|
3
4
|
indicator?: React.ReactNode;
|
|
4
|
-
} &
|
|
5
|
-
|
|
5
|
+
} & {
|
|
6
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCollapsible.Trigger>>;
|
|
7
|
+
}) => React.JSX.Element;
|
|
8
|
+
declare const CollapsiblePanel: ({ className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCollapsible.Panel> & {
|
|
9
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCollapsible.Panel>>;
|
|
10
|
+
}) => React.JSX.Element;
|
|
6
11
|
export declare const Collapsible: {
|
|
7
|
-
Root:
|
|
8
|
-
size?: import("./
|
|
9
|
-
} &
|
|
10
|
-
|
|
12
|
+
Root: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/collapsible").CollapsibleRootProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
13
|
+
size?: import("./size.js").ComponentSize;
|
|
14
|
+
} & {
|
|
15
|
+
ref?: React.Ref<HTMLDivElement> | undefined;
|
|
16
|
+
}) => React.JSX.Element;
|
|
17
|
+
Trigger: ({ className, children, indicator, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCollapsible.Trigger> & {
|
|
11
18
|
indicator?: React.ReactNode;
|
|
12
|
-
} &
|
|
13
|
-
|
|
19
|
+
} & {
|
|
20
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCollapsible.Trigger>>;
|
|
21
|
+
}) => React.JSX.Element;
|
|
22
|
+
Panel: ({ className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseCollapsible.Panel> & {
|
|
23
|
+
ref?: React.Ref<React.ComponentRef<typeof BaseCollapsible.Panel>>;
|
|
24
|
+
}) => React.JSX.Element;
|
|
14
25
|
};
|
|
15
26
|
export { CollapsiblePanel, CollapsibleTrigger };
|
|
16
|
-
export declare const CollapsibleRoot:
|
|
17
|
-
size?: import("./
|
|
18
|
-
} &
|
|
27
|
+
export declare const CollapsibleRoot: ({ ref, ...props }: Omit<Omit<Omit<import("@base-ui/react/collapsible").CollapsibleRootProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
28
|
+
size?: import("./size.js").ComponentSize;
|
|
29
|
+
} & {
|
|
30
|
+
ref?: React.Ref<HTMLDivElement> | undefined;
|
|
31
|
+
}) => React.JSX.Element;
|
package/dist/collapsible.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from 'react';
|
|
4
3
|
import { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';
|
|
5
4
|
import { Icon } from './icon.js';
|
|
6
5
|
import { skin, part } from './parts.js';
|
|
7
|
-
const CollapsibleTrigger =
|
|
8
|
-
return (_jsxs(BaseCollapsible.Trigger, { ...props, ref: ref, className: skin('
|
|
9
|
-
}
|
|
10
|
-
const CollapsiblePanel =
|
|
11
|
-
return (_jsx(BaseCollapsible.Panel, { ...props, ref: ref, className: skin('
|
|
12
|
-
}
|
|
6
|
+
const CollapsibleTrigger = function CollapsibleTrigger({ className, children, indicator, ref, ...props }) {
|
|
7
|
+
return (_jsxs(BaseCollapsible.Trigger, { ...props, ref: ref, className: skin('surf-disclosure-trigger', className), children: [_jsx("span", { className: 'surf-disclosure-label', children: children }), indicator === undefined ? (_jsx(Icon, { name: 'chevron-forward', className: 'surf-disclosure-chevron' })) : (indicator)] }));
|
|
8
|
+
};
|
|
9
|
+
const CollapsiblePanel = function CollapsiblePanel({ className, children, ref, ...props }) {
|
|
10
|
+
return (_jsx(BaseCollapsible.Panel, { ...props, ref: ref, className: skin('surf-collapsible-panel', className), children: _jsx("div", { className: 'surf-disclosure-body', children: children }) }));
|
|
11
|
+
};
|
|
13
12
|
export const Collapsible = {
|
|
14
13
|
...BaseCollapsible,
|
|
15
|
-
Root: /* @__PURE__ */ part(BaseCollapsible.Root, '
|
|
14
|
+
Root: /* @__PURE__ */ part(BaseCollapsible.Root, 'surf-collapsible'),
|
|
16
15
|
Trigger: CollapsibleTrigger,
|
|
17
16
|
Panel: CollapsiblePanel,
|
|
18
17
|
};
|