@surflane/ui 0.11.0 → 0.13.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/alert-dialog.d.ts +25 -7
- package/dist/alert-dialog.js +9 -4
- package/dist/app-shell.d.ts +10 -0
- package/dist/app-shell.js +7 -1
- package/dist/autocomplete.d.ts +2 -6
- package/dist/avatar.d.ts +7 -7
- package/dist/avatar.js +2 -2
- package/dist/bar-list.d.ts +31 -0
- package/dist/bar-list.js +31 -0
- package/dist/bottom-navigation.d.ts +6 -2
- package/dist/bottom-navigation.js +2 -2
- package/dist/button.d.ts +6 -11
- package/dist/button.js +8 -8
- package/dist/card.d.ts +15 -10
- package/dist/card.js +7 -2
- package/dist/chart.d.ts +58 -3
- package/dist/chart.js +330 -48
- package/dist/choice.d.ts +2 -2
- package/dist/class-names.d.ts +0 -4
- package/dist/class-names.js +0 -14
- package/dist/code.d.ts +19 -7
- package/dist/code.js +32 -38
- package/dist/combobox.d.ts +2 -8
- package/dist/combobox.js +2 -2
- package/dist/context-menu.d.ts +2 -8
- package/dist/context-menu.js +2 -2
- 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 +8 -2
- package/dist/css/rules/app-shell.css +57 -10
- package/dist/css/rules/bar-list.css +101 -0
- package/dist/css/rules/bar.css +5 -12
- package/dist/css/rules/bottom-navigation.css +21 -2
- package/dist/css/rules/breadcrumbs.css +0 -6
- package/dist/css/rules/button.css +4 -12
- package/dist/css/rules/card.css +19 -0
- package/dist/css/rules/chart.css +87 -8
- package/dist/css/rules/choice.css +26 -2
- package/dist/css/rules/combobox.css +17 -16
- package/dist/css/rules/dashboard.css +118 -0
- package/dist/css/rules/date-picker.css +50 -27
- package/dist/css/rules/dialog.css +47 -7
- package/dist/css/rules/disclosure.css +17 -3
- package/dist/css/rules/field-control.css +9 -6
- package/dist/css/rules/file-upload.css +9 -5
- package/dist/css/rules/filter-bar.css +32 -2
- package/dist/css/rules/gauge.css +2 -2
- package/dist/css/rules/icon.css +0 -5
- package/dist/css/rules/input-group.css +23 -8
- package/dist/css/rules/link.css +0 -6
- package/dist/css/rules/menu.css +5 -2
- package/dist/css/rules/menubar.css +1 -1
- package/dist/css/rules/navigation-menu.css +31 -26
- package/dist/css/rules/number-field.css +8 -1
- package/dist/css/rules/otp-field.css +13 -3
- package/dist/css/rules/page-header.css +10 -0
- package/dist/css/rules/panel.css +59 -10
- package/dist/css/rules/popup.css +50 -0
- package/dist/css/rules/preview-card.css +0 -21
- package/dist/css/rules/scroll-area.css +20 -1
- package/dist/css/rules/select.css +29 -2
- package/dist/css/rules/sizing.css +25 -3
- package/dist/css/rules/skeleton.css +1 -1
- package/dist/css/rules/slider.css +16 -8
- package/dist/css/rules/spinner.css +1 -1
- package/dist/css/rules/stat.css +66 -0
- package/dist/css/rules/tabs.css +14 -6
- package/dist/css/rules/textarea.css +28 -0
- package/dist/css/rules/time-range-picker.css +14 -0
- package/dist/css/rules/toast.css +3 -1
- package/dist/css/rules/toggle.css +10 -3
- package/dist/css/rules/toolbar.css +10 -3
- package/dist/css/rules/tree.css +29 -4
- package/dist/css/styles.css +3 -0
- package/dist/css/time-range-picker.css +14 -0
- package/dist/dashboard.d.ts +58 -0
- package/dist/dashboard.js +60 -0
- package/dist/date-picker.d.ts +32 -3
- package/dist/date-picker.js +43 -4
- package/dist/dialog.d.ts +25 -7
- package/dist/dialog.js +9 -4
- package/dist/drawer.d.ts +10 -2
- package/dist/drawer.js +6 -3
- package/dist/icon.d.ts +15 -5
- package/dist/icon.js +16 -3
- package/dist/index.d.ts +9 -6
- package/dist/index.js +7 -4
- package/dist/inline-message.d.ts +2 -2
- package/dist/inline-message.js +7 -2
- package/dist/input.d.ts +2 -2
- package/dist/layout.d.ts +1 -3
- package/dist/layout.js +2 -2
- package/dist/native-select.d.ts +2 -2
- package/dist/navigation-menu.d.ts +16 -0
- package/dist/navigation-menu.js +6 -1
- package/dist/page-header.d.ts +10 -2
- package/dist/page-header.js +3 -3
- package/dist/panel.d.ts +6 -3
- package/dist/panel.js +2 -2
- package/dist/parts.d.ts +7 -3
- package/dist/parts.js +12 -4
- package/dist/popover.d.ts +6 -6
- package/dist/popover.js +3 -2
- package/dist/preview-card.d.ts +2 -8
- package/dist/preview-card.js +2 -2
- package/dist/select.d.ts +38 -8
- package/dist/select.js +110 -22
- package/dist/sheet.d.ts +10 -2
- package/dist/sheet.js +6 -3
- package/dist/size.d.ts +8 -6
- package/dist/size.js +2 -7
- package/dist/sizing.d.ts +13 -6
- package/dist/sizing.js +13 -4
- package/dist/sparkline.d.ts +2 -2
- package/dist/sparkline.js +2 -2
- package/dist/spinner.d.ts +2 -2
- package/dist/spinner.js +2 -2
- package/dist/stat.d.ts +24 -0
- package/dist/stat.js +15 -1
- package/dist/table.d.ts +12 -4
- package/dist/table.js +8 -3
- package/dist/textarea.d.ts +6 -3
- package/dist/textarea.js +2 -2
- package/dist/time-range-picker.d.ts +42 -0
- package/dist/time-range-picker.js +69 -0
- package/dist/toggle.d.ts +2 -2
- package/dist/toggle.js +2 -2
- package/dist/toolbar.d.ts +11 -10
- package/dist/toolbar.js +23 -1
- package/dist/tooltip.d.ts +1 -3
- package/dist/tooltip.js +4 -2
- package/dist/tree.d.ts +1 -3
- package/dist/tree.js +2 -2
- package/dist/typography.d.ts +10 -3
- package/dist/typography.js +4 -3
- package/package.json +18 -3
package/dist/select.js
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { Icon } from './icon.js';
|
|
5
5
|
import { useComponentSize } from './sizing.js';
|
|
6
6
|
import { Select as BaseSelect } from '@base-ui/react/select';
|
|
7
|
-
import {
|
|
7
|
+
import { cx, usePortalDirection } from './parts.js';
|
|
8
8
|
const isGroup = (item) => 'options' in item;
|
|
9
9
|
const flatten = (items) => items.flatMap((item) => (isGroup(item) ? item.options : [item]));
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/** What a form reset reports: it has already happened, so it can't be canceled. */
|
|
11
|
+
function resetDetails(event) {
|
|
12
|
+
return {
|
|
13
|
+
reason: 'none',
|
|
14
|
+
event,
|
|
15
|
+
trigger: undefined,
|
|
16
|
+
cancel() { },
|
|
17
|
+
allowPropagation() { },
|
|
18
|
+
isCanceled: false,
|
|
19
|
+
isPropagationAllowed: false,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const multipleLabels = {
|
|
23
|
+
all: 'All',
|
|
24
|
+
none: 'None',
|
|
25
|
+
count: (count) => `${count} selected`,
|
|
26
|
+
};
|
|
27
|
+
// The value the "all" option carries; it never reaches a form or a callback.
|
|
28
|
+
const ALL = '\u0000all';
|
|
29
|
+
/** A choice from a list, or several with multiple. The ref reaches the trigger
|
|
30
|
+
* button, as triggerRef does. */
|
|
31
|
+
export const Select = function Select(allProps) {
|
|
32
|
+
const { options: items, className, inputRef, triggerRef, size, width = 'fill', ref, multiple, value: _value, defaultValue: _defaultValue, onValueChange: _onValueChange, labels: _labels, ...props } = allProps;
|
|
12
33
|
const scheme = useComponentSize(size);
|
|
34
|
+
const dir = usePortalDirection();
|
|
13
35
|
const options = flatten(items);
|
|
14
36
|
// One stable callback, so the trigger ref is not detached on every render.
|
|
15
37
|
const setTrigger = React.useCallback((node) => {
|
|
@@ -19,11 +41,16 @@ export const Select = function Select({ options: items, value, defaultValue, onV
|
|
|
19
41
|
else if (target)
|
|
20
42
|
target.current = node;
|
|
21
43
|
}, [ref, triggerRef]);
|
|
22
|
-
const
|
|
44
|
+
const many = allProps.multiple === true ? allProps : undefined;
|
|
45
|
+
const one = allProps.multiple === true ? undefined : allProps;
|
|
46
|
+
const initialValue = many
|
|
47
|
+
? (many.defaultValue ?? [])
|
|
48
|
+
: (one.defaultValue ?? options[0]?.value ?? '');
|
|
49
|
+
const [localValue, setLocalValue] = React.useState(initialValue);
|
|
23
50
|
const nativeInput = React.useRef(null);
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
const resetCallback = React.useRef(undefined);
|
|
52
|
+
resetCallback.current = allProps.onValueChange;
|
|
53
|
+
const resetKey = many ? initialValue.toString() : initialValue;
|
|
27
54
|
React.useEffect(() => {
|
|
28
55
|
const owner = nativeInput.current?.form;
|
|
29
56
|
if (!owner)
|
|
@@ -35,7 +62,9 @@ export const Select = function Select({ options: items, value, defaultValue, onV
|
|
|
35
62
|
if (event.defaultPrevented)
|
|
36
63
|
return;
|
|
37
64
|
setLocalValue(initialValue);
|
|
38
|
-
resetCallback.current?.(initialValue)
|
|
65
|
+
resetCallback.current?.((Array.isArray(initialValue)
|
|
66
|
+
? [...initialValue]
|
|
67
|
+
: initialValue), resetDetails(event));
|
|
39
68
|
}, 0);
|
|
40
69
|
pending.add(timer);
|
|
41
70
|
};
|
|
@@ -44,20 +73,79 @@ export const Select = function Select({ options: items, value, defaultValue, onV
|
|
|
44
73
|
owner.removeEventListener('reset', reset);
|
|
45
74
|
pending.forEach(clearTimeout);
|
|
46
75
|
};
|
|
47
|
-
|
|
48
|
-
|
|
76
|
+
// initialValue is read through resetKey, so a new array of the same values
|
|
77
|
+
// does not re-register the listener.
|
|
78
|
+
}, [resetKey, props.form]);
|
|
49
79
|
const { name, form, required, disabled, id, ...aria } = props;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
80
|
+
const setInput = (node) => {
|
|
81
|
+
nativeInput.current = node;
|
|
82
|
+
if (typeof inputRef === 'function')
|
|
83
|
+
inputRef(node);
|
|
84
|
+
else if (inputRef)
|
|
85
|
+
inputRef.current = node;
|
|
86
|
+
};
|
|
87
|
+
// Several values: the "all" option leads the list, and the trigger sums them up.
|
|
88
|
+
const choosable = options.filter((option) => !option.disabled);
|
|
89
|
+
const text = { ...multipleLabels, ...(many?.labels ?? {}) };
|
|
90
|
+
const chosen = many
|
|
91
|
+
? (many.value ?? localValue)
|
|
92
|
+
: [];
|
|
93
|
+
const everything = choosable.length > 0 &&
|
|
94
|
+
choosable.every((option) => chosen.includes(option.value));
|
|
95
|
+
const summary = (values) => values.length === 0
|
|
96
|
+
? text.none
|
|
97
|
+
: choosable.every((option) => values.includes(option.value))
|
|
98
|
+
? text.all
|
|
99
|
+
: values.length === 1
|
|
100
|
+
? options.find((option) => option.value === values[0])?.label
|
|
101
|
+
: text.count(values.length);
|
|
102
|
+
const selected = many
|
|
103
|
+
? everything
|
|
104
|
+
? [ALL, ...chosen]
|
|
105
|
+
: chosen
|
|
106
|
+
: (one.value ?? localValue);
|
|
107
|
+
const value = many ? summary(chosen) : _jsx(BaseSelect.Value, {});
|
|
108
|
+
// Content width: every label the trigger can show, stacked in one cell.
|
|
109
|
+
const sizes = many
|
|
110
|
+
? [
|
|
111
|
+
text.all,
|
|
112
|
+
text.none,
|
|
113
|
+
text.count(options.length),
|
|
114
|
+
...options.map((option) => option.label),
|
|
115
|
+
]
|
|
116
|
+
: options.map((option) => option.label);
|
|
117
|
+
return (_jsx("span", { className: cx('surf-select', className), "data-size": size, "data-ui-size": scheme, "data-width": width, "data-disabled": disabled || undefined, children: _jsxs(BaseSelect.Root, { items: options, multiple: multiple, value: selected, onValueChange: (next, eventDetails) => {
|
|
118
|
+
if (many) {
|
|
119
|
+
const list = next ?? [];
|
|
120
|
+
const toggledAll = list.includes(ALL) !== everything;
|
|
121
|
+
const values = toggledAll
|
|
122
|
+
? everything
|
|
123
|
+
? []
|
|
124
|
+
: choosable.map((option) => option.value)
|
|
125
|
+
: // Unchecking one option of "all" leaves the others.
|
|
126
|
+
list.filter((item) => item !== ALL);
|
|
127
|
+
many.onValueChange?.(values, eventDetails);
|
|
128
|
+
if (!eventDetails.isCanceled)
|
|
129
|
+
setLocalValue(values);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
one.onValueChange?.(next ?? '', eventDetails);
|
|
133
|
+
if (!eventDetails.isCanceled)
|
|
134
|
+
setLocalValue(next ?? '');
|
|
135
|
+
}
|
|
136
|
+
}, inputRef: setInput,
|
|
137
|
+
// A multiple Select submits its own inputs, without the "all" value.
|
|
138
|
+
name: many ? undefined : name, form: form, required: required, disabled: disabled, id: id, children: [_jsxs(BaseSelect.Trigger, { ...aria, ref: setTrigger, className: 'surf-select-trigger', "data-value": many ? chosen.join(' ') : selected, children: [width === 'content' ? (
|
|
139
|
+
// Every label sits in one cell, hidden but the chosen one, so the
|
|
140
|
+
// trigger is as wide as the longest.
|
|
141
|
+
_jsxs("span", { className: 'surf-select-sizer', children: [_jsx("span", { className: 'surf-select-value', children: value }), sizes.map((label, index) => (_jsx("span", { "aria-hidden": 'true', children: label }, index)))] })) : many ? (_jsx("span", { className: 'surf-select-value', children: value })) : (value), _jsx(BaseSelect.Icon, { className: 'surf-select-icon', children: _jsx(Icon, { name: 'chevron-down' }) })] }), many &&
|
|
142
|
+
name &&
|
|
143
|
+
chosen.map((item) => (_jsx("input", { type: 'hidden', name: name, value: item, form: form }, item))), _jsx(BaseSelect.Portal, { children: _jsx(BaseSelect.Positioner, { dir: dir, className: 'surf-positioner', sideOffset: 6, alignItemWithTrigger: false, children: _jsx(BaseSelect.Popup, { className: 'surf-select-popup', "data-ui-size": scheme, children: _jsxs(BaseSelect.List, { children: [many && (_jsxs(_Fragment, { children: [renderOption({
|
|
144
|
+
value: ALL,
|
|
145
|
+
label: text.all,
|
|
146
|
+
disabled: choosable.length === 0,
|
|
147
|
+
}), _jsx(BaseSelect.Separator, { className: 'surf-select-separator' })] })), items.map((item, index) => isGroup(item) ? (_jsxs(BaseSelect.Group, { className: 'surf-select-group', children: [_jsx(BaseSelect.GroupLabel, { className: 'surf-select-group-label', children: item.label }), item.options.map(renderOption)] }, index)) : (renderOption(item)))] }) }) }) })] }) }));
|
|
60
148
|
};
|
|
61
149
|
function renderOption(option) {
|
|
62
|
-
return (_jsxs(BaseSelect.Item, { className: 'surf-select-item', value: option.value, "data-option-value": option.value, disabled: option.disabled, children: [_jsx(BaseSelect.ItemIndicator, { className: 'surf-select-check', children: _jsx(Icon, { name: 'check' }) }), _jsx(BaseSelect.ItemText, { children: option.label })] }, option.value));
|
|
150
|
+
return (_jsxs(BaseSelect.Item, { className: 'surf-select-item', value: option.value, "data-option-value": option.value === ALL ? undefined : option.value, disabled: option.disabled, children: [_jsx(BaseSelect.ItemIndicator, { className: 'surf-select-check', children: _jsx(Icon, { name: 'check' }) }), _jsx(BaseSelect.ItemText, { children: option.label })] }, option.value));
|
|
63
151
|
}
|
package/dist/sheet.d.ts
CHANGED
|
@@ -4,14 +4,22 @@ import { Footer, Header, type PanelOptions, type PanelSide } from './panel.js';
|
|
|
4
4
|
declare function SheetRoot({ side, modal, ...props }: React.ComponentProps<typeof BaseDialog.Root> & {
|
|
5
5
|
side?: PanelSide;
|
|
6
6
|
}): React.JSX.Element;
|
|
7
|
-
declare const SheetContent: ({ size, flush, closeLabel, className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseDialog.Popup> & PanelOptions & {
|
|
7
|
+
declare const SheetContent: ({ size, flush, closeLabel, focusBoundaryLabel, className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseDialog.Popup> & PanelOptions & {
|
|
8
|
+
/** Names the focus guards at the panel's edges, which VoiceOver reaches past
|
|
9
|
+
* the last control, as Dialog's do. */
|
|
10
|
+
focusBoundaryLabel?: string;
|
|
11
|
+
} & {
|
|
8
12
|
ref?: React.Ref<HTMLDivElement>;
|
|
9
13
|
}) => React.JSX.Element;
|
|
10
14
|
declare function SheetTitle({ className, ...props }: React.ComponentProps<typeof BaseDialog.Title>): React.JSX.Element;
|
|
11
15
|
declare function SheetDescription({ className, ...props }: React.ComponentProps<typeof BaseDialog.Description>): React.JSX.Element;
|
|
12
16
|
export declare const Sheet: {
|
|
13
17
|
Root: typeof SheetRoot;
|
|
14
|
-
Content: ({ size, flush, closeLabel, className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseDialog.Popup> & PanelOptions & {
|
|
18
|
+
Content: ({ size, flush, closeLabel, focusBoundaryLabel, className, children, ref, ...props }: React.ComponentPropsWithoutRef<typeof BaseDialog.Popup> & PanelOptions & {
|
|
19
|
+
/** Names the focus guards at the panel's edges, which VoiceOver reaches past
|
|
20
|
+
* the last control, as Dialog's do. */
|
|
21
|
+
focusBoundaryLabel?: string;
|
|
22
|
+
} & {
|
|
15
23
|
ref?: React.Ref<HTMLDivElement>;
|
|
16
24
|
}) => React.JSX.Element;
|
|
17
25
|
Header: typeof Header;
|
package/dist/sheet.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { Icon } from './icon.js';
|
|
5
|
-
import {
|
|
5
|
+
import { useDialogFocusBoundary } from './dialog-focus.js';
|
|
6
|
+
import { skin, usePortalDirection } from './parts.js';
|
|
6
7
|
import { useComponentSize, normalizeSize } from './sizing.js';
|
|
7
8
|
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
|
|
8
9
|
import { Body, Footer, Header, } from './panel.js';
|
|
@@ -13,10 +14,12 @@ const SheetSide = /* @__PURE__ */ React.createContext({
|
|
|
13
14
|
function SheetRoot({ side = 'right', modal = true, ...props }) {
|
|
14
15
|
return (_jsx(SheetSide.Provider, { value: { side, modal }, children: _jsx(BaseDialog.Root, { ...props, modal: modal }) }));
|
|
15
16
|
}
|
|
16
|
-
const SheetContent = function SheetContent({ size, flush, closeLabel = 'Close panel', className, children, ref, ...props }) {
|
|
17
|
+
const SheetContent = function SheetContent({ size, flush, closeLabel = 'Close panel', focusBoundaryLabel = 'Continue panel navigation', className, children, ref, ...props }) {
|
|
17
18
|
const scheme = useComponentSize(size);
|
|
19
|
+
const dir = usePortalDirection();
|
|
20
|
+
const portalRef = useDialogFocusBoundary(focusBoundaryLabel);
|
|
18
21
|
const { side, modal } = React.useContext(SheetSide);
|
|
19
|
-
return (_jsx(BaseDialog.Portal, { children: _jsxs("div", { className: 'surf-panel-layer', "data-ui-size": scheme, children: [modal === true && (_jsx(BaseDialog.Backdrop, { className: 'surf-panel-backdrop' })), _jsx("div", { className: 'surf-panel-viewport', "data-side": side, "data-flush": flush || undefined, children: _jsxs(BaseDialog.Popup, { ...props, ref: ref, className: skin('surf-panel', className), "data-side": side, "data-size": normalizeSize(size) ?? 'default', "data-flush": flush || undefined, children: [_jsx(BaseDialog.Close, { className: 'surf-panel-close surf-icon-button', "aria-label": closeLabel, children: _jsx(Icon, { name: 'close' }) }), children] }) })] }) }));
|
|
22
|
+
return (_jsx(BaseDialog.Portal, { ref: portalRef, children: _jsxs("div", { className: 'surf-panel-layer', "data-ui-size": scheme, children: [modal === true && (_jsx(BaseDialog.Backdrop, { className: 'surf-panel-backdrop' })), _jsx("div", { className: 'surf-panel-viewport', "data-side": side, "data-flush": flush || undefined, children: _jsxs(BaseDialog.Popup, { dir: dir, ...props, ref: ref, className: skin('surf-panel', className), "data-side": side, "data-size": normalizeSize(size) ?? 'default', "data-flush": flush || undefined, children: [_jsx(BaseDialog.Close, { className: 'surf-panel-close surf-icon-button', "aria-label": closeLabel, children: _jsx(Icon, { name: 'close' }) }), children] }) })] }) }));
|
|
20
23
|
};
|
|
21
24
|
function SheetTitle({ className, ...props }) {
|
|
22
25
|
return (_jsx(BaseDialog.Title, { ...props, className: skin('surf-panel-title', className) }));
|
package/dist/size.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export type ComponentSize = 'small' | 'default' | 'large';
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export
|
|
2
|
+
/** How tightly a screen packs its blocks: compact tightens gaps, insets and touch growth. */
|
|
3
|
+
export type ComponentDensity = 'default' | 'compact';
|
|
4
|
+
/** @deprecated The short spellings sm, md and lg were removed in 0.13, so this is
|
|
5
|
+
* ComponentSize under its former name. Write ComponentSize; this name is removed in a
|
|
6
|
+
* later minor. */
|
|
7
|
+
export type ComponentSizeAlias = ComponentSize;
|
|
8
|
+
/** A component's size: the one place components read it, kept for server components. */
|
|
9
|
+
export declare function normalizeSize(size?: ComponentSize): ComponentSize | undefined;
|
package/dist/size.js
CHANGED
package/dist/sizing.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { normalizeSize, type ComponentSize, type ComponentSizeAlias } from './size.js';
|
|
3
|
-
export { normalizeSize, type ComponentSize, type ComponentSizeAlias };
|
|
2
|
+
import { normalizeSize, type ComponentDensity, type ComponentSize, type ComponentSizeAlias } from './size.js';
|
|
3
|
+
export { normalizeSize, type ComponentDensity, type ComponentSize, type ComponentSizeAlias, };
|
|
4
4
|
export declare const ComponentSizeContext: React.Context<ComponentSize | undefined>;
|
|
5
5
|
/** Explicit sizes override the surrounding scheme; portals retain React context. */
|
|
6
|
-
export declare function useComponentSize(size?:
|
|
6
|
+
export declare function useComponentSize(size?: ComponentSize): ComponentSize | undefined;
|
|
7
|
+
export declare const ComponentDensityContext: React.Context<ComponentDensity | undefined>;
|
|
8
|
+
/** A component's own density, else the surrounding one, else default. */
|
|
9
|
+
export declare function useComponentDensity(density?: ComponentDensity): ComponentDensity;
|
|
7
10
|
/** No layout box: grid/flex items and semantic children retain their own layout.
|
|
8
|
-
* For table internals, place the provider outside the table, never inside tbody.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
* For table internals, place the provider outside the table, never inside tbody.
|
|
12
|
+
* Either prop may be left out to keep the surrounding size or density. */
|
|
13
|
+
export declare function SizeProvider({ size, density, children, }: {
|
|
14
|
+
size?: ComponentSize;
|
|
15
|
+
/** compact tightens the gaps and insets of the blocks inside, and keeps controls
|
|
16
|
+
* at their size on touch screens instead of growing them to 44px. */
|
|
17
|
+
density?: ComponentDensity;
|
|
11
18
|
children: React.ReactNode;
|
|
12
19
|
}): React.JSX.Element;
|
|
13
20
|
/** The size context for a part a server component renders with an explicit size, so
|
package/dist/sizing.js
CHANGED
|
@@ -2,17 +2,26 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { normalizeSize, } from './size.js';
|
|
5
|
-
export { normalizeSize };
|
|
5
|
+
export { normalizeSize, };
|
|
6
6
|
export const ComponentSizeContext = /* @__PURE__ */ React.createContext(undefined);
|
|
7
7
|
/** Explicit sizes override the surrounding scheme; portals retain React context. */
|
|
8
8
|
export function useComponentSize(size) {
|
|
9
9
|
const inherited = React.useContext(ComponentSizeContext);
|
|
10
10
|
return normalizeSize(size) ?? inherited;
|
|
11
11
|
}
|
|
12
|
+
export const ComponentDensityContext = /* @__PURE__ */ React.createContext(undefined);
|
|
13
|
+
/** A component's own density, else the surrounding one, else default. */
|
|
14
|
+
export function useComponentDensity(density) {
|
|
15
|
+
const inherited = React.useContext(ComponentDensityContext);
|
|
16
|
+
return density ?? inherited ?? 'default';
|
|
17
|
+
}
|
|
12
18
|
/** No layout box: grid/flex items and semantic children retain their own layout.
|
|
13
|
-
* For table internals, place the provider outside the table, never inside tbody.
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
* For table internals, place the provider outside the table, never inside tbody.
|
|
20
|
+
* Either prop may be left out to keep the surrounding size or density. */
|
|
21
|
+
export function SizeProvider({ size, density, children, }) {
|
|
22
|
+
const inheritedSize = React.useContext(ComponentSizeContext);
|
|
23
|
+
const inheritedDensity = React.useContext(ComponentDensityContext);
|
|
24
|
+
return (_jsx(ComponentSizeContext.Provider, { value: size ?? inheritedSize, children: _jsx(ComponentDensityContext.Provider, { value: density ?? inheritedDensity, children: _jsx("div", { className: 'surf-size-scope', "data-ui-size": size, "data-ui-density": density, children: children }) }) }));
|
|
16
25
|
}
|
|
17
26
|
/** The size context for a part a server component renders with an explicit size, so
|
|
18
27
|
* the popups it portals keep that size. */
|
package/dist/sparkline.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ComponentSize } from './size.js';
|
|
3
3
|
export type SparklineTrend = 'auto' | 'up' | 'down' | 'flat' | 'neutral';
|
|
4
4
|
export type SparklineProps = Omit<React.ComponentPropsWithoutRef<'svg'>, 'children' | 'role' | 'aria-label'> & {
|
|
5
5
|
/** Values in order. A missing value leaves a gap. */
|
|
@@ -8,7 +8,7 @@ export type SparklineProps = Omit<React.ComponentPropsWithoutRef<'svg'>, 'childr
|
|
|
8
8
|
* line is an image; this is its name. */
|
|
9
9
|
label: string;
|
|
10
10
|
/** 24, 32 or 48px tall. Set --surf-sparkline-height for another height. */
|
|
11
|
-
size?:
|
|
11
|
+
size?: ComponentSize;
|
|
12
12
|
/** A reference line: a value, the first value, or none. */
|
|
13
13
|
baseline?: number | 'first' | 'none';
|
|
14
14
|
/** Marks the last value with a dot. */
|
package/dist/sparkline.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cx
|
|
2
|
+
import { cx } from './class-names.js';
|
|
3
3
|
const finite = (value) => typeof value === 'number' && Number.isFinite(value);
|
|
4
4
|
/** A small trend line for cards and table cells: no axes, legend or tooltip. Use Chart
|
|
5
5
|
* when people need to read values. */
|
|
@@ -41,7 +41,7 @@ export const Sparkline = function Sparkline({ data, label, size, baseline = 'non
|
|
|
41
41
|
let end = data.length - 1;
|
|
42
42
|
while (end >= 0 && !finite(data[end]))
|
|
43
43
|
end--;
|
|
44
|
-
return (_jsxs("svg", { ...props, ref: ref, role: 'img', "aria-label": label, className: cx('surf-sparkline', className), "data-size":
|
|
44
|
+
return (_jsxs("svg", { ...props, ref: ref, role: 'img', "aria-label": label, className: cx('surf-sparkline', className), "data-size": size, "data-tone": tone, viewBox: '0 0 100 100', preserveAspectRatio: 'none', focusable: 'false', children: [finite(reference) && (_jsx("path", { className: 'surf-sparkline-baseline', d: `M0 ${y(reference)}H100`, vectorEffect: 'non-scaling-stroke' })), _jsx("path", { className: 'surf-sparkline-line', d: path, vectorEffect: 'non-scaling-stroke' }), marker && end >= 0 && (
|
|
45
45
|
// A zero-length segment with a round cap stays a circle however the
|
|
46
46
|
// line stretches.
|
|
47
47
|
_jsx("path", { className: 'surf-sparkline-marker', d: `M${x(end)} ${y(data[end])}h0`, vectorEffect: 'non-scaling-stroke' }))] }));
|
package/dist/spinner.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ComponentSize } from './size.js';
|
|
3
3
|
export type SpinnerProps = Omit<React.ComponentPropsWithoutRef<'span'>, 'children'> & {
|
|
4
4
|
label?: string;
|
|
5
5
|
decorative?: boolean;
|
|
6
|
-
size?:
|
|
6
|
+
size?: ComponentSize;
|
|
7
7
|
};
|
|
8
8
|
/** Use decorative within a loading region that already owns the announcement. */
|
|
9
9
|
export declare const Spinner: ({ label, decorative, size, className, ref, ...props }: SpinnerProps & {
|
package/dist/spinner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { normalizeSize } from './size.js';
|
|
3
|
-
import {
|
|
3
|
+
import { cx } from './class-names.js';
|
|
4
4
|
/** Use decorative within a loading region that already owns the announcement. */
|
|
5
5
|
export const Spinner = function Spinner({ label = 'Loading', decorative = false, size, className, ref, ...props }) {
|
|
6
6
|
// An omitted size follows the surrounding size scope through CSS.
|
|
7
7
|
const scheme = normalizeSize(size);
|
|
8
|
-
return (_jsxs("span", { ...props, ref: ref, className: cx('surf-spinner', className), "data-size":
|
|
8
|
+
return (_jsxs("span", { ...props, ref: ref, className: cx('surf-spinner', className), "data-size": size, "data-ui-size": scheme, role: decorative ? undefined : 'status', "aria-hidden": decorative || undefined, children: [_jsxs("svg", { viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', "aria-hidden": 'true', children: [_jsx("circle", { cx: '12', cy: '12', r: '9', opacity: '.2' }), _jsx("path", { d: 'M12 3a9 9 0 0 1 9 9', strokeLinecap: 'round' })] }), !decorative && _jsx("span", { className: 'surf-feedback-sr', children: label })] }));
|
|
9
9
|
};
|
package/dist/stat.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { type StatusTone } from './status.js';
|
|
2
3
|
export type StatDirection = 'up' | 'down' | 'flat';
|
|
3
4
|
export type StatChangeProps = Omit<React.ComponentPropsWithoutRef<'dd'>, 'children'> & {
|
|
4
5
|
/** The change, such as 0.023 for 2.3%. Its sign sets the direction. */
|
|
@@ -11,6 +12,19 @@ export type StatChangeProps = Omit<React.ComponentPropsWithoutRef<'dd'>, 'childr
|
|
|
11
12
|
* still points the way the value moved. */
|
|
12
13
|
lowerIsBetter?: boolean;
|
|
13
14
|
};
|
|
15
|
+
export type StatStatusProps = React.ComponentPropsWithoutRef<'dd'> & {
|
|
16
|
+
/** The value's state: caution for one to watch, danger for one past its limit. */
|
|
17
|
+
tone: StatusTone;
|
|
18
|
+
};
|
|
19
|
+
export type StatGroupProps = React.ComponentPropsWithoutRef<'div'> & {
|
|
20
|
+
/** What every value in the group measures, such as "GPU temperature". It shows
|
|
21
|
+
* above them and names the group. */
|
|
22
|
+
label: string;
|
|
23
|
+
/** Names the group without showing the label, where a heading above already says
|
|
24
|
+
* it, such as the title of the Dashboard.Panel that holds the group. Give it a
|
|
25
|
+
* name of its own, such as "Free disk by node", so the two groups read apart. */
|
|
26
|
+
labelHidden?: boolean;
|
|
27
|
+
};
|
|
14
28
|
/** A key figure: what it measures, its value, how it moved and what it covers. Renders
|
|
15
29
|
* a description list, so the label names the value for assistive technology. */
|
|
16
30
|
export declare const Stat: {
|
|
@@ -29,10 +43,16 @@ export declare const Stat: {
|
|
|
29
43
|
Change: ({ value, format, direction, lowerIsBetter, className, ref, ...props }: StatChangeProps & {
|
|
30
44
|
ref?: React.Ref<HTMLElement>;
|
|
31
45
|
}) => React.JSX.Element;
|
|
46
|
+
Status: ({ tone, className, children, ref, ...props }: StatStatusProps & {
|
|
47
|
+
ref?: React.Ref<HTMLElement>;
|
|
48
|
+
}) => React.JSX.Element;
|
|
32
49
|
Caption: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref">, "size"> & {
|
|
33
50
|
size?: import("./size.js").ComponentSize;
|
|
34
51
|
ref?: React.Ref<HTMLElement> | undefined;
|
|
35
52
|
}) => React.JSX.Element;
|
|
53
|
+
Group: ({ label, labelHidden, className, children, ref, ...props }: StatGroupProps & {
|
|
54
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
55
|
+
}) => React.JSX.Element;
|
|
36
56
|
};
|
|
37
57
|
export declare const StatRoot: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDListElement>, HTMLDListElement>, "ref">, "size"> & {
|
|
38
58
|
size?: import("./size.js").ComponentSize;
|
|
@@ -45,7 +65,11 @@ export declare const StatRoot: ({ className, size, ref, ...rest }: Omit<Omit<Rea
|
|
|
45
65
|
ref?: React.Ref<HTMLElement> | undefined;
|
|
46
66
|
}) => React.JSX.Element, StatChange: ({ value, format, direction, lowerIsBetter, className, ref, ...props }: StatChangeProps & {
|
|
47
67
|
ref?: React.Ref<HTMLElement>;
|
|
68
|
+
}) => React.JSX.Element, StatStatus: ({ tone, className, children, ref, ...props }: StatStatusProps & {
|
|
69
|
+
ref?: React.Ref<HTMLElement>;
|
|
48
70
|
}) => React.JSX.Element, StatCaption: ({ className, size, ref, ...rest }: Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref">, "size"> & {
|
|
49
71
|
size?: import("./size.js").ComponentSize;
|
|
50
72
|
ref?: React.Ref<HTMLElement> | undefined;
|
|
73
|
+
}) => React.JSX.Element, StatGroup: ({ label, labelHidden, className, children, ref, ...props }: StatGroupProps & {
|
|
74
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
51
75
|
}) => React.JSX.Element;
|
package/dist/stat.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Icon } from './icon.js';
|
|
|
3
3
|
import { cx } from './class-names.js';
|
|
4
4
|
import { elementPart } from './element-part.js';
|
|
5
5
|
import { formatPercent } from './format.js';
|
|
6
|
+
import { StatusIcon } from './status.js';
|
|
6
7
|
const signed = (value) => formatPercent(value, { signed: true });
|
|
7
8
|
const arrows = { up: 'arrow-up', down: 'arrow-down', flat: 'minus' };
|
|
8
9
|
/** A change against an earlier value: an arrow, a signed figure and its direction's
|
|
@@ -12,6 +13,17 @@ const ChangePart = function StatChange({ value, format = signed, direction, lowe
|
|
|
12
13
|
const tone = way === 'flat' || !lowerIsBetter ? way : way === 'up' ? 'down' : 'up';
|
|
13
14
|
return (_jsxs("dd", { ...props, ref: ref, "data-direction": way, "data-tone": tone, className: cx('surf-stat-change', className), children: [_jsx(Icon, { name: arrows[way] }), format(value)] }));
|
|
14
15
|
};
|
|
16
|
+
/** The value's state against a threshold, such as "Below 30 GiB": the tone's icon and
|
|
17
|
+
* text in its color. A caution or danger status colors the value too, and the text
|
|
18
|
+
* says why, so color is never alone. */
|
|
19
|
+
const StatusPart = function StatStatus({ tone, className, children, ref, ...props }) {
|
|
20
|
+
return (_jsxs("dd", { ...props, ref: ref, "data-tone": tone, className: cx('surf-stat-status', className), children: [_jsx(StatusIcon, { tone: tone }), children] }));
|
|
21
|
+
};
|
|
22
|
+
/** Several values of one measure side by side, such as one per node: a shared label
|
|
23
|
+
* over Stat.Roots whose own labels name each. */
|
|
24
|
+
const GroupPart = function StatGroup({ label, labelHidden = false, className, children, ref, ...props }) {
|
|
25
|
+
return (_jsxs("div", { role: 'group', "aria-label": label, ...props, ref: ref, className: cx('surf-stat-group', className), children: [!labelHidden && (_jsx("span", { className: 'surf-stat-group-label', "aria-hidden": 'true', children: label })), _jsx("div", { className: 'surf-stat-group-items', children: children })] }));
|
|
26
|
+
};
|
|
15
27
|
/** A key figure: what it measures, its value, how it moved and what it covers. Renders
|
|
16
28
|
* a description list, so the label names the value for assistive technology. */
|
|
17
29
|
export const Stat = {
|
|
@@ -19,7 +31,9 @@ export const Stat = {
|
|
|
19
31
|
Label: /* @__PURE__ */ elementPart('dt', 'surf-stat-label'),
|
|
20
32
|
Value: /* @__PURE__ */ elementPart('dd', 'surf-stat-value'),
|
|
21
33
|
Change: ChangePart,
|
|
34
|
+
Status: StatusPart,
|
|
22
35
|
Caption: /* @__PURE__ */ elementPart('dd', 'surf-stat-caption'),
|
|
36
|
+
Group: GroupPart,
|
|
23
37
|
};
|
|
24
38
|
// Flat names for React Server Components, which cannot dot into client exports.
|
|
25
|
-
export const { Root: StatRoot, Label: StatLabel, Value: StatValue, Change: StatChange, Caption: StatCaption, } = Stat;
|
|
39
|
+
export const { Root: StatRoot, Label: StatLabel, Value: StatValue, Change: StatChange, Status: StatStatus, Caption: StatCaption, Group: StatGroup, } = Stat;
|
package/dist/table.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ declare const RootPart: ({ className, size, ref, ...rest }: Omit<Omit<React.Deta
|
|
|
15
15
|
export type TableDensity = 'default' | 'compact';
|
|
16
16
|
export type TableVariant = 'plain' | 'lined' | 'grid' | 'striped';
|
|
17
17
|
declare const TableRoot: ({ density, variant, stickyHeader, ref, ...props }: React.ComponentPropsWithoutRef<typeof RootPart> & {
|
|
18
|
-
/** compact tightens rows for scanning many records with a pointer.
|
|
18
|
+
/** compact tightens rows for scanning many records with a pointer. Without it the
|
|
19
|
+
* table follows a SizeProvider density; default keeps it roomy inside a compact one. */
|
|
19
20
|
density?: TableDensity;
|
|
20
21
|
/**
|
|
21
22
|
* plain separates rows by space; lined draws lines between rows, grid between
|
|
@@ -56,7 +57,10 @@ declare const TableSortHeader: ({ sort, onSort, disabled, children, className, r
|
|
|
56
57
|
ref?: React.Ref<HTMLTableCellElement>;
|
|
57
58
|
}) => React.JSX.Element;
|
|
58
59
|
/** One-line text that ends in an ellipsis. String content also becomes the title. */
|
|
59
|
-
declare const TableTruncate: ({ className, title, children, ref, ...props }: React.ComponentPropsWithoutRef<"span"> & {
|
|
60
|
+
declare const TableTruncate: ({ measure, className, title, style, children, ref, ...props }: React.ComponentPropsWithoutRef<"span"> & {
|
|
61
|
+
/** The widest it gets before the ellipsis, such as '44ch' for long image
|
|
62
|
+
* references; 32ch without it. */
|
|
63
|
+
measure?: string;
|
|
60
64
|
ref?: React.Ref<HTMLSpanElement>;
|
|
61
65
|
}) => React.JSX.Element;
|
|
62
66
|
/** A full-width body row for loading, empty, error and permission messages. It has no hover. */
|
|
@@ -80,7 +84,8 @@ export declare const Table: {
|
|
|
80
84
|
ref?: React.Ref<HTMLDivElement>;
|
|
81
85
|
}) => React.JSX.Element;
|
|
82
86
|
Root: ({ density, variant, stickyHeader, ref, ...props }: React.ComponentPropsWithoutRef<typeof RootPart> & {
|
|
83
|
-
/** compact tightens rows for scanning many records with a pointer.
|
|
87
|
+
/** compact tightens rows for scanning many records with a pointer. Without it the
|
|
88
|
+
* table follows a SizeProvider density; default keeps it roomy inside a compact one. */
|
|
84
89
|
density?: TableDensity;
|
|
85
90
|
/**
|
|
86
91
|
* plain separates rows by space; lined draws lines between rows, grid between
|
|
@@ -126,7 +131,10 @@ export declare const Table: {
|
|
|
126
131
|
Cell: ({ align, numeric, ref, ...props }: Omit<React.ComponentPropsWithoutRef<typeof CellPart>, "align"> & CellLayout & {
|
|
127
132
|
ref?: React.Ref<HTMLTableCellElement>;
|
|
128
133
|
}) => React.JSX.Element;
|
|
129
|
-
Truncate: ({ className, title, children, ref, ...props }: React.ComponentPropsWithoutRef<"span"> & {
|
|
134
|
+
Truncate: ({ measure, className, title, style, children, ref, ...props }: React.ComponentPropsWithoutRef<"span"> & {
|
|
135
|
+
/** The widest it gets before the ellipsis, such as '44ch' for long image
|
|
136
|
+
* references; 32ch without it. */
|
|
137
|
+
measure?: string;
|
|
130
138
|
ref?: React.Ref<HTMLSpanElement>;
|
|
131
139
|
}) => React.JSX.Element;
|
|
132
140
|
Message: ({ className, ref, ...props }: React.ComponentPropsWithoutRef<"td"> & {
|
package/dist/table.js
CHANGED
|
@@ -9,7 +9,7 @@ const TableContainer = function TableContainer({ bleed, rootClassName, ref, ...p
|
|
|
9
9
|
};
|
|
10
10
|
const RootPart = /* @__PURE__ */ elementPart('table', 'surf-table');
|
|
11
11
|
const TableRoot = function TableRoot({ density, variant, stickyHeader, ref, ...props }) {
|
|
12
|
-
return (_jsx(RootPart, { ...props, ref: ref, "data-density": density
|
|
12
|
+
return (_jsx(RootPart, { ...props, ref: ref, "data-density": density, "data-variant": variant && variant !== 'plain' ? variant : undefined, "data-sticky-header": stickyHeader || undefined }));
|
|
13
13
|
};
|
|
14
14
|
const layout = ({ align, numeric }) => ({
|
|
15
15
|
'data-align': numeric ? 'end' : align,
|
|
@@ -36,8 +36,13 @@ const TableSortHeader = function TableSortHeader({ sort, onSort, disabled, child
|
|
|
36
36
|
return (_jsx(TableHeaderCell, { ...props, ref: ref, scope: 'col', "aria-sort": sort, className: cx('surf-table-sort-header', className), children: _jsxs(Button, { variant: 'ghost', className: 'surf-table-sort', "data-sort": sort, disabled: disabled, onClick: onSort, children: [_jsx("span", { children: children }), _jsx(SortIcon, { sort: sort })] }) }));
|
|
37
37
|
};
|
|
38
38
|
/** One-line text that ends in an ellipsis. String content also becomes the title. */
|
|
39
|
-
const TableTruncate = function TableTruncate({ className, title, children, ref, ...props }) {
|
|
40
|
-
return (_jsx("span", { ...props, ref: ref, title: title ?? (typeof children === 'string' ? children : undefined),
|
|
39
|
+
const TableTruncate = function TableTruncate({ measure, className, title, style, children, ref, ...props }) {
|
|
40
|
+
return (_jsx("span", { ...props, ref: ref, title: title ?? (typeof children === 'string' ? children : undefined), style: measure
|
|
41
|
+
? {
|
|
42
|
+
...style,
|
|
43
|
+
'--surf-table-truncate-measure': measure,
|
|
44
|
+
}
|
|
45
|
+
: style, className: cx('surf-table-truncate', className), children: children }));
|
|
41
46
|
};
|
|
42
47
|
/** A full-width body row for loading, empty, error and permission messages. It has no hover. */
|
|
43
48
|
const TableMessage = function TableMessage({ className, ref, ...props }) {
|
package/dist/textarea.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ComponentSize } from './sizing.js';
|
|
3
3
|
/** A multi-line text field. Inside Field.Root it takes the label, description and
|
|
4
4
|
* error from the field, as Input does. */
|
|
5
|
-
export declare const Textarea: ({ className, size, rows, cols, wrap, ref, ...props }: React.ComponentPropsWithoutRef<"textarea"> & {
|
|
6
|
-
size?:
|
|
5
|
+
export declare const Textarea: ({ className, size, variant, rows, cols, wrap, ref, ...props }: React.ComponentPropsWithoutRef<"textarea"> & {
|
|
6
|
+
size?: ComponentSize;
|
|
7
|
+
/** `embedded` fills the pane it sits in, such as an editor beside a preview: no
|
|
8
|
+
* edge or corners of its own, and focus as a ring inside it. */
|
|
9
|
+
variant?: "default" | "embedded";
|
|
7
10
|
} & {
|
|
8
11
|
ref?: React.Ref<HTMLTextAreaElement>;
|
|
9
12
|
}) => React.JSX.Element;
|
package/dist/textarea.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Field as BaseField } from '@base-ui/react/field';
|
|
|
5
5
|
import { cx } from './parts.js';
|
|
6
6
|
/** A multi-line text field. Inside Field.Root it takes the label, description and
|
|
7
7
|
* error from the field, as Input does. */
|
|
8
|
-
export const Textarea = function Textarea({ className, size, rows, cols, wrap, ref, ...props }) {
|
|
8
|
+
export const Textarea = function Textarea({ className, size, variant = 'default', rows, cols, wrap, ref, ...props }) {
|
|
9
9
|
const scheme = useComponentSize(size);
|
|
10
|
-
return (_jsx(BaseField.Control, { ...props, ref: ref, "data-ui-size": scheme, render: _jsx("textarea", { rows: rows, cols: cols, wrap: wrap }), className: cx('surf-input surf-textarea', className) }));
|
|
10
|
+
return (_jsx(BaseField.Control, { ...props, ref: ref, "data-ui-size": scheme, "data-variant": variant === 'embedded' ? variant : undefined, render: _jsx("textarea", { rows: rows, cols: cols, wrap: wrap }), className: cx('surf-input surf-textarea', className) }));
|
|
11
11
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComponentSize } from './size.js';
|
|
3
|
+
/** A span of time back from now, or a refresh interval, in milliseconds. */
|
|
4
|
+
export type TimeRangeOption = {
|
|
5
|
+
value: number;
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const timeRangeOptions: readonly TimeRangeOption[];
|
|
9
|
+
/** 0 is off. */
|
|
10
|
+
export declare const refreshIntervalOptions: readonly TimeRangeOption[];
|
|
11
|
+
export type TimeRangePickerLabels = {
|
|
12
|
+
/** The range select's name. */
|
|
13
|
+
range: string;
|
|
14
|
+
/** The refresh interval select's name. */
|
|
15
|
+
refresh: string;
|
|
16
|
+
/** The button that refreshes now. */
|
|
17
|
+
refreshNow: string;
|
|
18
|
+
};
|
|
19
|
+
export type TimeRangePickerProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> & {
|
|
20
|
+
/** Names the group, such as "Dashboard time". */
|
|
21
|
+
label: string;
|
|
22
|
+
/** The span back from now, in ms; one of ranges. */
|
|
23
|
+
range: number;
|
|
24
|
+
onRangeChange: (range: number) => void;
|
|
25
|
+
/** The span options, such as timeRangeOptions with translated labels. */
|
|
26
|
+
ranges?: readonly TimeRangeOption[];
|
|
27
|
+
/** How often onRefresh runs, in ms; 0 is off. Leave it out for no interval select. */
|
|
28
|
+
refreshInterval?: number;
|
|
29
|
+
onRefreshIntervalChange?: (interval: number) => void;
|
|
30
|
+
refreshIntervals?: readonly TimeRangeOption[];
|
|
31
|
+
/** Runs when the button is pressed and on every interval while the page is shown.
|
|
32
|
+
* Leave it out for no refresh button. */
|
|
33
|
+
onRefresh?: () => void;
|
|
34
|
+
labels?: Partial<TimeRangePickerLabels>;
|
|
35
|
+
size?: ComponentSize;
|
|
36
|
+
};
|
|
37
|
+
/** The span a monitoring screen shows, back from now, with how often it refreshes and
|
|
38
|
+
* a button to refresh now. For a fixed span between two dates, put a DateRangePicker
|
|
39
|
+
* beside it. */
|
|
40
|
+
export declare const TimeRangePicker: ({ label, range, onRangeChange, ranges, refreshInterval, onRefreshIntervalChange, refreshIntervals: intervals, onRefresh, labels, size, className, ref, ...props }: TimeRangePickerProps & {
|
|
41
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
42
|
+
}) => React.JSX.Element;
|