@surflane/ui 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-shell.d.ts +10 -0
- package/dist/app-shell.js +7 -1
- package/dist/bar-list.d.ts +31 -0
- package/dist/bar-list.js +25 -0
- package/dist/bottom-navigation.d.ts +6 -2
- package/dist/bottom-navigation.js +2 -2
- package/dist/chart.d.ts +56 -3
- package/dist/chart.js +266 -48
- package/dist/css/bar-list.css +9 -0
- package/dist/css/chart.css +2 -0
- package/dist/css/dashboard.css +20 -0
- package/dist/css/rules/alert-dialog.css +4 -0
- package/dist/css/rules/app-shell.css +10 -0
- package/dist/css/rules/bar-list.css +101 -0
- package/dist/css/rules/bottom-navigation.css +16 -0
- package/dist/css/rules/card.css +5 -0
- package/dist/css/rules/chart.css +74 -3
- package/dist/css/rules/dashboard.css +66 -0
- package/dist/css/rules/date-picker.css +10 -3
- package/dist/css/rules/dialog.css +11 -0
- package/dist/css/rules/field-control.css +7 -0
- package/dist/css/rules/filter-bar.css +8 -1
- package/dist/css/rules/input-group.css +9 -0
- package/dist/css/rules/otp-field.css +7 -4
- package/dist/css/rules/panel.css +9 -1
- package/dist/css/rules/select.css +25 -1
- package/dist/css/rules/sizing.css +10 -0
- package/dist/css/rules/slider.css +4 -2
- package/dist/css/rules/stat.css +57 -0
- package/dist/css/rules/time-range-picker.css +14 -0
- package/dist/css/styles.css +3 -0
- package/dist/css/time-range-picker.css +14 -0
- package/dist/dashboard.d.ts +46 -0
- package/dist/dashboard.js +35 -0
- package/dist/icon.d.ts +10 -0
- package/dist/icon.js +11 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +5 -2
- package/dist/select.d.ts +33 -6
- package/dist/select.js +94 -21
- package/dist/stat.d.ts +20 -0
- package/dist/stat.js +15 -1
- package/dist/time-range-picker.d.ts +42 -0
- package/dist/time-range-picker.js +69 -0
- package/package.json +18 -3
package/dist/app-shell.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export type AppShellSidebarToggleProps = Omit<ButtonProps, 'children'> & {
|
|
|
25
25
|
labels?: Partial<AppShellSidebarToggleLabels>;
|
|
26
26
|
children?: React.ReactNode;
|
|
27
27
|
};
|
|
28
|
+
export type AppShellMenuTriggerProps = Omit<ButtonProps, 'children'> & {
|
|
29
|
+
/** The button's name. Say what it opens. */
|
|
30
|
+
label?: string;
|
|
31
|
+
children?: React.ReactNode;
|
|
32
|
+
};
|
|
28
33
|
export type AppShellBrandProps = Omit<useRender.ComponentProps<'div'>, 'ref' | 'children'> & {
|
|
29
34
|
/** The product mark, about 24px. It is decorative: the name names the brand. */
|
|
30
35
|
mark?: React.ReactNode;
|
|
@@ -55,6 +60,9 @@ export declare const AppShell: {
|
|
|
55
60
|
SidebarToggle: ({ labels, className, children, onClick, ref, ...props }: AppShellSidebarToggleProps & {
|
|
56
61
|
ref?: React.Ref<HTMLButtonElement>;
|
|
57
62
|
}) => React.JSX.Element;
|
|
63
|
+
MenuTrigger: ({ label, className, children, ref, ...props }: AppShellMenuTriggerProps & {
|
|
64
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
65
|
+
}) => React.JSX.Element;
|
|
58
66
|
Brand: ({ mark, name, description, render, className, ref, ...props }: AppShellBrandProps & {
|
|
59
67
|
ref?: React.Ref<HTMLDivElement>;
|
|
60
68
|
}) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
@@ -85,6 +93,8 @@ export declare const AppShellRoot: ({ collapsed, defaultCollapsed, onCollapsedCh
|
|
|
85
93
|
ref?: React.Ref<HTMLElement>;
|
|
86
94
|
}) => React.JSX.Element, AppShellSidebarToggle: ({ labels, className, children, onClick, ref, ...props }: AppShellSidebarToggleProps & {
|
|
87
95
|
ref?: React.Ref<HTMLButtonElement>;
|
|
96
|
+
}) => React.JSX.Element, AppShellMenuTrigger: ({ label, className, children, ref, ...props }: AppShellMenuTriggerProps & {
|
|
97
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
88
98
|
}) => React.JSX.Element, AppShellBrand: ({ mark, name, description, render, className, ref, ...props }: AppShellBrandProps & {
|
|
89
99
|
ref?: React.Ref<HTMLDivElement>;
|
|
90
100
|
}) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>>, AppShellNav: ({ label, className, children, ref, ...props }: AppShellNavProps & {
|
package/dist/app-shell.js
CHANGED
|
@@ -75,6 +75,11 @@ const SidebarToggle = function AppShellSidebarToggle({ labels, className, childr
|
|
|
75
75
|
shell.setCollapsed(!shell.collapsed);
|
|
76
76
|
}, children: children ?? _jsx(Icon, { name: 'sidebar' }) }) }));
|
|
77
77
|
};
|
|
78
|
+
/** Opens the caller's navigation, such as a Sheet, where the sidebar is hidden: at
|
|
79
|
+
* 760px and narrower it shows at the header's end, and above that it is hidden. */
|
|
80
|
+
const MenuTrigger = function AppShellMenuTrigger({ label = 'Open navigation', className, children, ref, ...props }) {
|
|
81
|
+
return (_jsx(Button, { variant: 'ghost', size: 'icon', ...props, ref: ref, "aria-label": label, className: skin('surf-app-shell-menu-trigger', className), children: children ?? _jsx(Icon, { name: 'menu', decorative: true }) }));
|
|
82
|
+
};
|
|
78
83
|
const Header = function AppShellHeader({ className, ref, ...props }) {
|
|
79
84
|
return (_jsx("div", { ...props, ref: ref, className: cx('surf-app-shell-header', className) }));
|
|
80
85
|
};
|
|
@@ -144,6 +149,7 @@ export const AppShell = {
|
|
|
144
149
|
Header,
|
|
145
150
|
Sidebar,
|
|
146
151
|
SidebarToggle,
|
|
152
|
+
MenuTrigger,
|
|
147
153
|
Brand,
|
|
148
154
|
Nav,
|
|
149
155
|
Content,
|
|
@@ -153,4 +159,4 @@ export const AppShell = {
|
|
|
153
159
|
Link,
|
|
154
160
|
};
|
|
155
161
|
// Flat names for React Server Components, which cannot dot into client exports.
|
|
156
|
-
export const { Root: AppShellRoot, Header: AppShellHeader, Sidebar: AppShellSidebar, SidebarToggle: AppShellSidebarToggle, Brand: AppShellBrand, Nav: AppShellNav, Content: AppShellContent, Page: AppShellPage, Footer: AppShellFooter, Label: AppShellLabel, Link: AppShellLink, } = AppShell;
|
|
162
|
+
export const { Root: AppShellRoot, Header: AppShellHeader, Sidebar: AppShellSidebar, SidebarToggle: AppShellSidebarToggle, MenuTrigger: AppShellMenuTrigger, Brand: AppShellBrand, Nav: AppShellNav, Content: AppShellContent, Page: AppShellPage, Footer: AppShellFooter, Label: AppShellLabel, Link: AppShellLink, } = AppShell;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type BarListItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
/** What the row measures, such as a directory or a project. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** A second, quieter name under the label, such as a path. */
|
|
7
|
+
detail?: string;
|
|
8
|
+
value: number;
|
|
9
|
+
/** The value as written, such as "412 GiB". Defaults to the formatted value. */
|
|
10
|
+
text?: string;
|
|
11
|
+
};
|
|
12
|
+
export type BarListProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> & {
|
|
13
|
+
/** Names the list, such as "Disk used by directory". */
|
|
14
|
+
label: string;
|
|
15
|
+
items: readonly BarListItem[];
|
|
16
|
+
/** The value a full bar stands for. Defaults to the largest value. */
|
|
17
|
+
max?: number;
|
|
18
|
+
/** Orders the rows from the largest value down. Turn it off to keep your order. */
|
|
19
|
+
sorted?: boolean;
|
|
20
|
+
/** The rows shown before the list scrolls inside itself. */
|
|
21
|
+
maxRows?: number;
|
|
22
|
+
/** Writes a value that has no text. */
|
|
23
|
+
formatValue?: (value: number) => string;
|
|
24
|
+
locale?: string;
|
|
25
|
+
};
|
|
26
|
+
/** A ranked list of named values, each with a bar in proportion to the largest, such
|
|
27
|
+
* as disk by directory or tokens by project. Names and values are text; the bars are
|
|
28
|
+
* decoration. */
|
|
29
|
+
export declare const BarList: ({ label, items, max, sorted, maxRows, formatValue, locale, className, style, ref, ...props }: BarListProps & {
|
|
30
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
31
|
+
}) => React.JSX.Element;
|
package/dist/bar-list.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from './class-names.js';
|
|
3
|
+
import { ScrollArea } from './scroll-area.js';
|
|
4
|
+
/** A ranked list of named values, each with a bar in proportion to the largest, such
|
|
5
|
+
* as disk by directory or tokens by project. Names and values are text; the bars are
|
|
6
|
+
* decoration. */
|
|
7
|
+
export const BarList = function BarList({ label, items, max, sorted = true, maxRows, formatValue, locale, className, style, ref, ...props }) {
|
|
8
|
+
const rows = sorted ? [...items].sort((a, b) => b.value - a.value) : items;
|
|
9
|
+
const top = max ?? rows.reduce((largest, item) => Math.max(largest, item.value), 0);
|
|
10
|
+
const number = new Intl.NumberFormat(locale);
|
|
11
|
+
const write = (value) => formatValue ? formatValue(value) : number.format(value);
|
|
12
|
+
const scrolls = maxRows !== undefined && rows.length > maxRows;
|
|
13
|
+
const list = (_jsx("ol", { className: 'surf-bar-list-items', "aria-label": label, children: rows.map((item) => {
|
|
14
|
+
const share = top > 0 && Number.isFinite(item.value)
|
|
15
|
+
? Math.min(100, Math.max(0, (item.value / top) * 100))
|
|
16
|
+
: 0;
|
|
17
|
+
return (_jsxs("li", { className: 'surf-bar-list-item', children: [_jsxs("span", { className: 'surf-bar-list-label', children: [_jsx("span", { className: 'surf-bar-list-name', title: item.label, children: item.label }), item.detail && (_jsx("span", { className: 'surf-bar-list-detail', title: item.detail, children: item.detail }))] }), _jsx("span", { className: 'surf-bar-list-bar', "aria-hidden": 'true', children: _jsx("span", { className: 'surf-bar-list-fill', style: { inlineSize: `${share}%` } }) }), _jsx("span", { className: 'surf-bar-list-value', children: item.text ?? write(item.value) })] }, item.id));
|
|
18
|
+
}) }));
|
|
19
|
+
return (_jsx("div", { ...props, ref: ref, className: cx('surf-bar-list', className), "data-detail": items.some((item) => item.detail) || undefined, style: scrolls
|
|
20
|
+
? {
|
|
21
|
+
...style,
|
|
22
|
+
'--surf-bar-list-rows': maxRows,
|
|
23
|
+
}
|
|
24
|
+
: style, children: scrolls ? (_jsx(ScrollArea, { orientation: 'vertical', label: label, children: list })) : (list) }));
|
|
25
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
import type { StatusTone } from './status.js';
|
|
3
4
|
export type BottomNavigationRootProps = React.ComponentPropsWithoutRef<'nav'> & {
|
|
4
5
|
/** Names the navigation, such as "Primary". */
|
|
5
6
|
'aria-label': string;
|
|
@@ -20,17 +21,20 @@ export type BottomNavigationItemProps = Omit<useRender.ComponentProps<'a'>, 'ref
|
|
|
20
21
|
/** What the badge means, read after the label, such as "3 unread". A count reads
|
|
21
22
|
* as its number without it; a dot needs it. */
|
|
22
23
|
badgeLabel?: string;
|
|
24
|
+
/** The badge's color, by what it means: danger for what needs action now,
|
|
25
|
+
* caution for what needs a look soon, neutral for news. */
|
|
26
|
+
badgeTone?: StatusTone;
|
|
23
27
|
};
|
|
24
28
|
export declare const BottomNavigation: {
|
|
25
29
|
Root: ({ visible, position, className, children, ref, ...props }: BottomNavigationRootProps & {
|
|
26
30
|
ref?: React.Ref<HTMLElement>;
|
|
27
31
|
}) => React.JSX.Element;
|
|
28
|
-
Item: ({ icon, label, current, badge, badgeLabel, render, className, ref, ...props }: BottomNavigationItemProps & {
|
|
32
|
+
Item: ({ icon, label, current, badge, badgeLabel, badgeTone, render, className, ref, ...props }: BottomNavigationItemProps & {
|
|
29
33
|
ref?: React.Ref<HTMLAnchorElement>;
|
|
30
34
|
}) => React.JSX.Element;
|
|
31
35
|
};
|
|
32
36
|
export declare const BottomNavigationRoot: ({ visible, position, className, children, ref, ...props }: BottomNavigationRootProps & {
|
|
33
37
|
ref?: React.Ref<HTMLElement>;
|
|
34
|
-
}) => React.JSX.Element, BottomNavigationItem: ({ icon, label, current, badge, badgeLabel, render, className, ref, ...props }: BottomNavigationItemProps & {
|
|
38
|
+
}) => React.JSX.Element, BottomNavigationItem: ({ icon, label, current, badge, badgeLabel, badgeTone, render, className, ref, ...props }: BottomNavigationItemProps & {
|
|
35
39
|
ref?: React.Ref<HTMLAnchorElement>;
|
|
36
40
|
}) => React.JSX.Element;
|
|
@@ -9,7 +9,7 @@ const Root = function BottomNavigationRoot({ visible = 'mobile', position = 'fix
|
|
|
9
9
|
};
|
|
10
10
|
/** One destination: an icon above its label. Pass a router's link element as
|
|
11
11
|
* `render` to keep client navigation. */
|
|
12
|
-
const Item = function BottomNavigationItem({ icon, label, current, badge, badgeLabel, render, className, ref, ...props }) {
|
|
12
|
+
const Item = function BottomNavigationItem({ icon, label, current, badge, badgeLabel, badgeTone = 'danger', render, className, ref, ...props }) {
|
|
13
13
|
const count = typeof badge === 'number' && badge > 0
|
|
14
14
|
? badge > 99
|
|
15
15
|
? '99+'
|
|
@@ -25,7 +25,7 @@ const Item = function BottomNavigationItem({ icon, label, current, badge, badgeL
|
|
|
25
25
|
...props,
|
|
26
26
|
'aria-current': current ? 'page' : props['aria-current'],
|
|
27
27
|
className: cx('surf-bottom-nav-item', className),
|
|
28
|
-
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'surf-bottom-nav-icon', "aria-hidden": 'true', children: [icon, shown && (_jsx("span", { className: 'surf-bottom-nav-badge', "data-dot": count ? undefined : '', children: count }))] }), _jsx("span", { className: 'surf-bottom-nav-label', children: label }), shown && spoken && (_jsxs("span", { className: 'surf-feedback-sr', children: [", ", spoken] }))] })),
|
|
28
|
+
children: (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'surf-bottom-nav-icon', "aria-hidden": 'true', children: [icon, shown && (_jsx("span", { className: 'surf-bottom-nav-badge', "data-tone": badgeTone, "data-dot": count ? undefined : '', children: count }))] }), _jsx("span", { className: 'surf-bottom-nav-label', children: label }), shown && spoken && (_jsxs("span", { className: 'surf-feedback-sr', children: [", ", spoken] }))] })),
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
return _jsx("li", { className: 'surf-bottom-nav-entry', children: link });
|
package/dist/chart.d.ts
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
export type ChartDatum = {
|
|
3
3
|
id: string;
|
|
4
|
+
/** What the readout and the table call the row, such as its full date and time. */
|
|
4
5
|
label: string;
|
|
6
|
+
/** When the row was measured, in ms since the epoch or as a Date. Required for
|
|
7
|
+
* xScale="time", where it places the row on the axis. */
|
|
8
|
+
time?: number | Date;
|
|
5
9
|
values: Readonly<Record<string, number | null | undefined>>;
|
|
6
10
|
};
|
|
7
11
|
export type ChartSeries = {
|
|
8
12
|
key: string;
|
|
9
13
|
label: string;
|
|
14
|
+
/** A color of your own, such as var(--surf-chart-category-3), in place of the
|
|
15
|
+
* palette's. Marks and dashes still tell the series apart. */
|
|
16
|
+
color?: string;
|
|
17
|
+
};
|
|
18
|
+
export type ChartTone = 'neutral' | 'caution' | 'danger';
|
|
19
|
+
/** A threshold line at y, or a band from one value to another, such as a target
|
|
20
|
+
* range. The legend names it with its value. */
|
|
21
|
+
export type ChartReference = {
|
|
22
|
+
y: number;
|
|
23
|
+
label: string;
|
|
24
|
+
tone?: ChartTone;
|
|
25
|
+
} | {
|
|
26
|
+
from: number;
|
|
27
|
+
to: number;
|
|
28
|
+
label: string;
|
|
29
|
+
tone?: ChartTone;
|
|
10
30
|
};
|
|
11
31
|
export type ChartProps = Omit<React.ComponentPropsWithoutRef<'figure'>, 'children' | 'title'> & {
|
|
12
32
|
title: string;
|
|
@@ -17,13 +37,33 @@ export type ChartProps = Omit<React.ComponentPropsWithoutRef<'figure'>, 'childre
|
|
|
17
37
|
xLabel: string;
|
|
18
38
|
yLabel: string;
|
|
19
39
|
type?: 'line' | 'bar' | 'area';
|
|
40
|
+
/** Plot height in px: 280 by default, 180 when compact. */
|
|
20
41
|
height?: number;
|
|
21
42
|
/** Keeps 0 on the value axis. Turn it off for values far from zero, such as
|
|
22
43
|
* prices, so the line uses the height; bars always start at zero. */
|
|
23
44
|
includeZero?: boolean;
|
|
24
|
-
/** neutral tells series apart by ink, dashes and markers. categorical adds
|
|
25
|
-
* for categories that color must separate, such as buckets or sectors. */
|
|
45
|
+
/** neutral tells series apart by ink, dashes and markers. categorical adds twelve
|
|
46
|
+
* hues, for categories that color must separate, such as buckets or sectors. */
|
|
26
47
|
palette?: 'neutral' | 'categorical';
|
|
48
|
+
/** category spaces the rows evenly and names them by label. time places them by
|
|
49
|
+
* data[].time, puts ticks on round times and breaks a line where sampling stops. */
|
|
50
|
+
xScale?: 'category' | 'time';
|
|
51
|
+
/** log suits values across orders of magnitude, such as prefill and decode
|
|
52
|
+
* throughput. Zero and negative values stay off the plot and in the table. */
|
|
53
|
+
yScale?: 'linear' | 'log';
|
|
54
|
+
/** step holds each value until the next, for values sampled when they change. */
|
|
55
|
+
curve?: 'linear' | 'step';
|
|
56
|
+
/** Stacks bar and area series, so the top of the stack is their total. */
|
|
57
|
+
stacked?: boolean;
|
|
58
|
+
/** Thresholds and target bands over the plot. The value axis reaches them. */
|
|
59
|
+
references?: readonly ChartReference[];
|
|
60
|
+
/** compact keeps the plot, legend and floating values for a dashboard card; the
|
|
61
|
+
* caption, keyboard help and readout stay for assistive technology. */
|
|
62
|
+
density?: 'default' | 'compact';
|
|
63
|
+
/** Above the plot, beside the value axis name, or below it. */
|
|
64
|
+
legendPosition?: 'top' | 'bottom';
|
|
65
|
+
/** Shows this many series in the legend; the rest fold behind a "+N" button. */
|
|
66
|
+
legendLimit?: number;
|
|
27
67
|
locale?: string;
|
|
28
68
|
/** Formats a value for the readout, the table and the value axis ticks. The unit
|
|
29
69
|
* follows it in the readout and the table, and names the axis. */
|
|
@@ -52,9 +92,22 @@ export type ChartLabels = {
|
|
|
52
92
|
legend: (title: string) => string;
|
|
53
93
|
/** A legend button that shows or hides a series. */
|
|
54
94
|
series: (label: string) => string;
|
|
95
|
+
/** The button that opens the series past legendLimit. */
|
|
96
|
+
moreSeries: (count: number) => string;
|
|
97
|
+
/** The sum of stacked series in the readout. */
|
|
98
|
+
total: string;
|
|
99
|
+
};
|
|
100
|
+
export type ChartSeriesMarkProps = {
|
|
101
|
+
type?: 'line' | 'bar' | 'area';
|
|
102
|
+
/** The series' place in the chart's series, which sets its dash, marker and color. */
|
|
103
|
+
index: number;
|
|
104
|
+
palette?: 'neutral' | 'categorical';
|
|
105
|
+
color?: string;
|
|
55
106
|
};
|
|
107
|
+
/** A series' swatch as Chart's legend draws it, for a legend or key of your own. */
|
|
108
|
+
export declare function ChartSeriesMark({ type, index, palette, color, }: ChartSeriesMarkProps): React.JSX.Element;
|
|
56
109
|
/** Cartesian trends with a persistent, keyboard-readable tooltip region and a
|
|
57
110
|
* full data-table alternative. Missing values are gaps, never fabricated zeros. */
|
|
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 & {
|
|
111
|
+
export declare const Chart: ({ title, description, data, series, unit, xLabel, yLabel, type, height, includeZero, palette, xScale, yScale, curve, stacked, references, density, legendPosition, legendLimit, locale, formatValue, labels, hiddenSeries, defaultHiddenSeries, onHiddenSeriesChange, className, ref, ...props }: ChartProps & {
|
|
59
112
|
ref?: React.Ref<HTMLElement>;
|
|
60
113
|
}) => React.JSX.Element;
|