@phreshos/react-ui 0.1.30 → 0.1.31
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 +162 -18
- package/dist/accordion.d.ts +45 -0
- package/dist/accordion.js +62 -0
- package/dist/alert-dialog.d.ts +0 -1
- package/dist/alert-dialog.js +0 -1
- package/dist/aria-direction.d.ts +9 -0
- package/dist/aria-direction.js +49 -0
- package/dist/calendar-layout.d.ts +8 -0
- package/dist/calendar-layout.js +103 -0
- package/dist/calendar-trigger.d.ts +5 -0
- package/dist/calendar-trigger.js +30 -0
- package/dist/calendar.d.ts +18 -0
- package/dist/calendar.js +13 -0
- package/dist/color.d.ts +16 -1
- package/dist/color.js +60 -11
- package/dist/combo-box.d.ts +20 -0
- package/dist/combo-box.js +68 -0
- package/dist/context-menu.d.ts +2 -4
- package/dist/context-menu.js +0 -1
- package/dist/control-surface.d.ts +2 -1
- package/dist/control-surface.js +2 -2
- package/dist/control.d.ts +1 -1
- package/dist/control.js +7 -8
- package/dist/date-control.d.ts +24 -0
- package/dist/date-control.js +69 -0
- package/dist/date-field.d.ts +19 -0
- package/dist/date-field.js +13 -0
- package/dist/date-picker.d.ts +19 -0
- package/dist/date-picker.js +16 -0
- package/dist/date-range-picker.d.ts +20 -0
- package/dist/date-range-picker.js +25 -0
- package/dist/date-range.d.ts +6 -0
- package/dist/date-range.js +0 -0
- package/dist/dialog.d.ts +4 -2
- package/dist/dialog.js +24 -7
- package/dist/disclosure.d.ts +42 -0
- package/dist/disclosure.js +97 -0
- package/dist/dropdown-menu.d.ts +0 -2
- package/dist/dropdown-menu.js +0 -1
- package/dist/list-box.d.ts +49 -0
- package/dist/list-box.js +129 -0
- package/dist/main.d.ts +25 -9
- package/dist/main.js +25 -9
- package/dist/material-paint.js +19 -1
- package/dist/menu.d.ts +22 -4
- package/dist/menu.js +25 -6
- package/dist/panel.d.ts +0 -1
- package/dist/panel.js +0 -1
- package/dist/popover.d.ts +0 -1
- package/dist/popover.js +13 -3
- package/dist/progress-bar.d.ts +22 -0
- package/dist/progress-bar.js +46 -0
- package/dist/radio.d.ts +5 -5
- package/dist/radio.js +8 -4
- package/dist/radius.js +1 -1
- package/dist/range-calendar.d.ts +19 -0
- package/dist/range-calendar.js +15 -0
- package/dist/scroll-area.d.ts +4 -1
- package/dist/scroll-area.js +3 -3
- package/dist/select.js +4 -14
- package/dist/selection.d.ts +18 -0
- package/dist/selection.js +28 -0
- package/dist/slider.js +1 -1
- package/dist/spacing.js +1 -1
- package/dist/table.d.ts +78 -0
- package/dist/table.js +148 -0
- package/dist/tabs.d.ts +45 -0
- package/dist/tabs.js +103 -0
- package/dist/time-field.d.ts +22 -0
- package/dist/time-field.js +13 -0
- package/dist/toggle-indicator.js +1 -1
- package/dist/toolbar.d.ts +46 -0
- package/dist/toolbar.js +121 -0
- package/dist/tooltip.d.ts +0 -1
- package/dist/tooltip.js +0 -1
- package/dist/tree.d.ts +56 -0
- package/dist/tree.js +134 -0
- package/dist/window.d.ts +6 -3
- package/dist/window.js +10 -7
- package/package.json +3 -1
package/dist/table.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
|
+
import { Cell as AriaCell, Column as AriaColumn, Row as AriaRow, Table as AriaTable, TableBody as AriaTableBody, TableHeader as AriaTableHeader } from "react-aria-components";
|
|
4
|
+
import { colorOpacity } from "./color.js";
|
|
5
|
+
import { controlFontWeight, controlOpacity, useControlTheme } from "./control.js";
|
|
6
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
7
|
+
import { multipleSelection, singleSelection, stringKey, toAriaSelection } from "./selection.js";
|
|
8
|
+
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
9
|
+
const TableThemeContext = createContext(null);
|
|
10
|
+
export const TableRoot = forwardRef(function TableRoot(properties, ref) {
|
|
11
|
+
const { className, color, defaultValue, disabledValues, onChange, onRowAction, onSortChange, radius = "medium", selectionMode = "none", size = "medium", sort, style, value, ...native } = properties;
|
|
12
|
+
const theme = useControlTheme({ color, radius, size });
|
|
13
|
+
const context = useMemo(() => ({ color, interactive: selectionMode !== "none" || onRowAction != null, radius, size, theme }), [color, onRowAction, radius, selectionMode, size, theme]);
|
|
14
|
+
const direction = resolveDirection(native.dir, useDirection());
|
|
15
|
+
return _jsx(TableThemeContext.Provider, { value: context, children: _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaTable, { ...native, ...selectionProperties(properties), ...(sort === undefined ? {} : { sortDescriptor: sort }), ref: ref, dir: direction, className: className, disabledKeys: disabledValues, selectionMode: selectionMode, onRowAction: onRowAction == null ? undefined : key => onRowAction(stringKey(key)), onSortChange: onSortChange == null ? undefined : descriptor => onSortChange(tableSort(descriptor)), style: {
|
|
16
|
+
width: "100%",
|
|
17
|
+
minWidth: "max-content",
|
|
18
|
+
borderCollapse: "separate",
|
|
19
|
+
borderSpacing: 0,
|
|
20
|
+
boxSizing: "border-box",
|
|
21
|
+
borderRadius: theme.radius,
|
|
22
|
+
// Header and row paints belong to the table, so the table must clip
|
|
23
|
+
// them rather than relying on a surrounding surface for its radius.
|
|
24
|
+
overflow: "hidden",
|
|
25
|
+
fontFamily: "inherit",
|
|
26
|
+
fontSize: theme.fontSize,
|
|
27
|
+
...style
|
|
28
|
+
} }) }) });
|
|
29
|
+
});
|
|
30
|
+
function selectionProperties(properties) {
|
|
31
|
+
const selectedKeys = toAriaSelection(properties.value);
|
|
32
|
+
const defaultSelectedKeys = toAriaSelection(properties.defaultValue);
|
|
33
|
+
const onSelectionChange = properties.onChange == null
|
|
34
|
+
? undefined
|
|
35
|
+
: (selection) => {
|
|
36
|
+
if (properties.selectionMode === "multiple") {
|
|
37
|
+
properties.onChange?.(multipleSelection(selection));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (properties.selectionMode === "single")
|
|
41
|
+
properties.onChange?.(singleSelection(selection));
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
...(selectedKeys !== undefined ? { selectedKeys } : {}),
|
|
45
|
+
...(defaultSelectedKeys !== undefined ? { defaultSelectedKeys } : {}),
|
|
46
|
+
...(onSelectionChange !== undefined ? { onSelectionChange } : {})
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function tableSort(descriptor) {
|
|
50
|
+
return { column: stringKey(descriptor.column), direction: descriptor.direction };
|
|
51
|
+
}
|
|
52
|
+
const TableHeaderImplementation = forwardRef(function TableHeader({ className, color, style, ...properties }, ref) {
|
|
53
|
+
const inherited = useTableContext();
|
|
54
|
+
const resolvedColor = color ?? inherited.color;
|
|
55
|
+
const theme = useControlTheme({ color: resolvedColor, radius: inherited.radius, size: inherited.size });
|
|
56
|
+
const context = useMemo(() => ({ ...inherited, color: resolvedColor, theme }), [inherited, resolvedColor, theme]);
|
|
57
|
+
return _jsx(TableThemeContext.Provider, { value: context, children: _jsx(AriaTableHeader, { ...properties, ref: ref, className: className, style: { ...style } }) });
|
|
58
|
+
});
|
|
59
|
+
export const TableHeader = TableHeaderImplementation;
|
|
60
|
+
export const TableColumn = forwardRef(function TableColumn({ allowsSorting = false, children, className, style, textValue, ...properties }, ref) {
|
|
61
|
+
const theme = useTableTheme();
|
|
62
|
+
return _jsx(AriaColumn, { ...properties, ref: ref, allowsSorting: allowsSorting, className: className, textValue: textValue ?? (typeof children === "string" ? children : undefined), style: state => ({
|
|
63
|
+
...theme.transition,
|
|
64
|
+
minWidth: 0,
|
|
65
|
+
height: theme.height,
|
|
66
|
+
paddingBlock: theme.gap,
|
|
67
|
+
paddingInline: Math.max(8, theme.spacing),
|
|
68
|
+
boxSizing: "border-box",
|
|
69
|
+
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
70
|
+
outlineOffset: -1,
|
|
71
|
+
...(state.isHovered && allowsSorting ? theme.paints.palette.hover : theme.paints.palette.rest),
|
|
72
|
+
cursor: allowsSorting ? "pointer" : "default",
|
|
73
|
+
fontWeight: controlFontWeight,
|
|
74
|
+
textAlign: "start",
|
|
75
|
+
userSelect: "none",
|
|
76
|
+
...style
|
|
77
|
+
}), children: state => _jsxs("span", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: theme.gap, minWidth: 0 }, children: [_jsx("span", { style: { minWidth: 0 }, children: typeof children === "function" ? children(state) : children }), allowsSorting && state.sortDirection != null && _jsx(SortIndicator, { direction: state.sortDirection, theme: theme })] }) });
|
|
78
|
+
});
|
|
79
|
+
function SortIndicator({ direction, theme }) {
|
|
80
|
+
return _jsx("svg", { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: {
|
|
81
|
+
...theme.transition,
|
|
82
|
+
flexShrink: 0,
|
|
83
|
+
transitionProperty: "transform",
|
|
84
|
+
transform: `rotate(${direction === "descending" ? 180 : 0}deg)`
|
|
85
|
+
}, children: _jsx("path", { d: "m2 8 4-4 4 4" }) });
|
|
86
|
+
}
|
|
87
|
+
const TableBodyImplementation = forwardRef(function TableBody({ className, style, ...properties }, ref) {
|
|
88
|
+
return _jsx(AriaTableBody, { ...properties, ref: ref, className: className, style: { ...style } });
|
|
89
|
+
});
|
|
90
|
+
export const TableBody = TableBodyImplementation;
|
|
91
|
+
const TableRowImplementation = forwardRef(function TableRow({ className, disabled = false, onAction, style, ...properties }, ref) {
|
|
92
|
+
const { interactive, theme } = useTableContext();
|
|
93
|
+
return _jsx(AriaRow, { ...properties, ref: ref, className: className, isDisabled: disabled, onAction: onAction, style: state => ({
|
|
94
|
+
...theme.transition,
|
|
95
|
+
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
96
|
+
outlineOffset: -1,
|
|
97
|
+
cursor: disabled ? "not-allowed" : interactive || onAction != null ? "pointer" : "default",
|
|
98
|
+
opacity: disabled ? controlOpacity.disabled : 1,
|
|
99
|
+
...(state.isSelected
|
|
100
|
+
? state.isPressed
|
|
101
|
+
? theme.paints.palette.pressed
|
|
102
|
+
: state.isHovered
|
|
103
|
+
? theme.paints.palette.hover
|
|
104
|
+
: theme.paints.palette.rest
|
|
105
|
+
: state.isHovered && (interactive || onAction != null)
|
|
106
|
+
? theme.paints.subtle.hover
|
|
107
|
+
: { background: "transparent", color: "inherit" }),
|
|
108
|
+
...style
|
|
109
|
+
}) });
|
|
110
|
+
});
|
|
111
|
+
export const TableRow = TableRowImplementation;
|
|
112
|
+
export const TableCell = forwardRef(function TableCell({ className, style, ...properties }, ref) {
|
|
113
|
+
const theme = useTableTheme();
|
|
114
|
+
const separator = colorOpacity(theme.tint, controlOpacity.separator);
|
|
115
|
+
return _jsx(AriaCell, { ...properties, ref: ref, className: className, style: state => ({
|
|
116
|
+
minWidth: 0,
|
|
117
|
+
height: theme.height,
|
|
118
|
+
paddingBlock: theme.gap,
|
|
119
|
+
paddingInline: Math.max(8, theme.spacing),
|
|
120
|
+
boxSizing: "border-box",
|
|
121
|
+
// Separators belong to the row that follows them. This preserves every
|
|
122
|
+
// internal boundary while leaving the final row without a bottom edge.
|
|
123
|
+
borderBlockStart: `1px solid ${separator}`,
|
|
124
|
+
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
125
|
+
outlineOffset: -1,
|
|
126
|
+
background: "transparent",
|
|
127
|
+
color: "inherit",
|
|
128
|
+
textAlign: "start",
|
|
129
|
+
...style
|
|
130
|
+
}) });
|
|
131
|
+
});
|
|
132
|
+
function useTableContext() {
|
|
133
|
+
const value = useContext(TableThemeContext);
|
|
134
|
+
if (value == null)
|
|
135
|
+
throw new Error("Table parts must be used inside Table");
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
function useTableTheme() {
|
|
139
|
+
return useTableContext().theme;
|
|
140
|
+
}
|
|
141
|
+
/** Structured rows and columns with optional selection and consumer-owned sorting. */
|
|
142
|
+
export const Table = Object.assign(TableRoot, {
|
|
143
|
+
Header: TableHeader,
|
|
144
|
+
Column: TableColumn,
|
|
145
|
+
Body: TableBody,
|
|
146
|
+
Row: TableRow,
|
|
147
|
+
Cell: TableCell
|
|
148
|
+
});
|
package/dist/tabs.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, RefAttributes } from "react";
|
|
2
|
+
import type { TabListProps as AriaTabListProps, TabPanelProps as AriaTabPanelProps, TabPanelsProps as AriaTabPanelsProps, TabProps as AriaTabProps, TabsProps as AriaTabsProps } from "react-aria-components";
|
|
3
|
+
import type { ControlColor } from "./control.js";
|
|
4
|
+
import type { RadiusProps } from "./radius.js";
|
|
5
|
+
import type { ScaleLevel } from "./scale.js";
|
|
6
|
+
export interface TabsRootProps extends Omit<AriaTabsProps, "className" | "defaultSelectedKey" | "isDisabled" | "onSelectionChange" | "selectedKey" | "style">, RadiusProps {
|
|
7
|
+
readonly className?: string;
|
|
8
|
+
readonly color?: ControlColor;
|
|
9
|
+
readonly defaultValue?: string;
|
|
10
|
+
readonly disabled?: boolean;
|
|
11
|
+
readonly onChange?: (value: string) => void;
|
|
12
|
+
readonly size?: ScaleLevel;
|
|
13
|
+
readonly style?: CSSProperties;
|
|
14
|
+
readonly value?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const TabsRoot: import("react").ForwardRefExoticComponent<TabsRootProps & RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export interface TabsListProps<T extends object = object> extends Omit<AriaTabListProps<T>, "className" | "style"> {
|
|
18
|
+
readonly className?: string;
|
|
19
|
+
readonly style?: CSSProperties;
|
|
20
|
+
}
|
|
21
|
+
export type TabsListComponent = <T extends object = object>(properties: TabsListProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
22
|
+
export declare const TabsList: TabsListComponent;
|
|
23
|
+
export interface TabsTabProps extends Omit<AriaTabProps, "className" | "id" | "isDisabled" | "style"> {
|
|
24
|
+
readonly className?: string;
|
|
25
|
+
readonly disabled?: boolean;
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly style?: CSSProperties;
|
|
28
|
+
}
|
|
29
|
+
export declare const TabsTab: import("react").ForwardRefExoticComponent<TabsTabProps & RefAttributes<HTMLDivElement>>;
|
|
30
|
+
export type TabsPanelsProps<T extends object = object> = AriaTabPanelsProps<T>;
|
|
31
|
+
export declare const TabsPanels: <T>(props: AriaTabPanelsProps<T> & React.RefAttributes<HTMLDivElement>) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
|
|
32
|
+
export interface TabsPanelProps extends Omit<AriaTabPanelProps, "className" | "id" | "style"> {
|
|
33
|
+
readonly className?: string;
|
|
34
|
+
readonly id: string;
|
|
35
|
+
readonly style?: CSSProperties;
|
|
36
|
+
}
|
|
37
|
+
export declare const TabsPanel: import("react").ForwardRefExoticComponent<TabsPanelProps & RefAttributes<HTMLDivElement>>;
|
|
38
|
+
/** Peer views with one selected tab and one corresponding panel. */
|
|
39
|
+
export declare const Tabs: import("react").ForwardRefExoticComponent<TabsRootProps & RefAttributes<HTMLDivElement>> & {
|
|
40
|
+
List: TabsListComponent;
|
|
41
|
+
Tab: import("react").ForwardRefExoticComponent<TabsTabProps & RefAttributes<HTMLDivElement>>;
|
|
42
|
+
Panels: <T>(props: AriaTabPanelsProps<T> & React.RefAttributes<HTMLDivElement>) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
|
|
43
|
+
Panel: import("react").ForwardRefExoticComponent<TabsPanelProps & RefAttributes<HTMLDivElement>>;
|
|
44
|
+
};
|
|
45
|
+
export type TabsProps = TabsRootProps;
|
package/dist/tabs.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useId, useMemo } from "react";
|
|
3
|
+
import { Tab as AriaTab, TabList as AriaTabList, TabPanel as AriaTabPanel, TabPanels as AriaTabPanels, Tabs as AriaTabs } from "react-aria-components";
|
|
4
|
+
import { LayoutGroup, motion } from "motion/react";
|
|
5
|
+
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
6
|
+
import { controlOpacity, useControlTheme } from "./control.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
8
|
+
import { stringKey } from "./selection.js";
|
|
9
|
+
import { Surface } from "./surface.js";
|
|
10
|
+
const TabsThemeContext = createContext(null);
|
|
11
|
+
export const TabsRoot = forwardRef(function TabsRoot({ className, color, defaultValue, disabled = false, onChange, orientation = "horizontal", radius = "medium", size = "medium", style, value, ...properties }, ref) {
|
|
12
|
+
const theme = useControlTheme({ color, radius, size });
|
|
13
|
+
const context = useMemo(() => ({ orientation, theme }), [orientation, theme]);
|
|
14
|
+
const layoutGroup = useId();
|
|
15
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
16
|
+
return _jsx(TabsThemeContext.Provider, { value: context, children: _jsx(LayoutGroup, { id: layoutGroup, children: _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaTabs, { ...properties, ...(value !== undefined ? { selectedKey: value } : {}), ...(defaultValue !== undefined ? { defaultSelectedKey: defaultValue } : {}), ref: ref, dir: direction, className: className, isDisabled: disabled, orientation: orientation, onSelectionChange: key => onChange?.(stringKey(key)), style: {
|
|
17
|
+
display: "flex",
|
|
18
|
+
flexDirection: orientation === "horizontal" ? "column" : "row",
|
|
19
|
+
alignItems: "stretch",
|
|
20
|
+
gap: theme.gap,
|
|
21
|
+
minWidth: 0,
|
|
22
|
+
fontFamily: "inherit",
|
|
23
|
+
fontSize: theme.fontSize,
|
|
24
|
+
...style
|
|
25
|
+
} }) }) }) });
|
|
26
|
+
});
|
|
27
|
+
const TabsListImplementation = forwardRef(function TabsList({ className, style, ...properties }, ref) {
|
|
28
|
+
const { orientation, theme } = useTabsTheme();
|
|
29
|
+
return _jsx(AriaTabList, { ...properties, ref: ref, className: className, style: {
|
|
30
|
+
display: "grid",
|
|
31
|
+
gridAutoFlow: orientation === "horizontal" ? "column" : "row",
|
|
32
|
+
gridAutoColumns: orientation === "horizontal" ? "minmax(0, 1fr)" : undefined,
|
|
33
|
+
alignContent: "start",
|
|
34
|
+
alignItems: "stretch",
|
|
35
|
+
gap: Math.max(2, theme.gap / 2),
|
|
36
|
+
minWidth: 0,
|
|
37
|
+
width: orientation === "horizontal" ? "100%" : undefined,
|
|
38
|
+
boxSizing: "border-box",
|
|
39
|
+
padding: Math.max(2, theme.gap / 2),
|
|
40
|
+
borderRadius: theme.radius,
|
|
41
|
+
background: theme.paints.palette.rest.background,
|
|
42
|
+
...style
|
|
43
|
+
} });
|
|
44
|
+
});
|
|
45
|
+
export const TabsList = TabsListImplementation;
|
|
46
|
+
export const TabsTab = forwardRef(function TabsTab({ children, className, disabled = false, style, ...properties }, ref) {
|
|
47
|
+
const { orientation, theme } = useTabsTheme();
|
|
48
|
+
return _jsx(AriaTab, { ...properties, ref: ref, className: className, isDisabled: disabled, style: state => ({
|
|
49
|
+
...theme.transition,
|
|
50
|
+
position: "relative",
|
|
51
|
+
zIndex: 0,
|
|
52
|
+
display: "flex",
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
justifyContent: "center",
|
|
55
|
+
width: "100%",
|
|
56
|
+
minWidth: 0,
|
|
57
|
+
minHeight: theme.height,
|
|
58
|
+
paddingBlock: 0,
|
|
59
|
+
paddingInline: Math.max(8, theme.spacing),
|
|
60
|
+
boxSizing: "border-box",
|
|
61
|
+
borderRadius: theme.radius,
|
|
62
|
+
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
63
|
+
outlineOffset: 1,
|
|
64
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
65
|
+
opacity: disabled ? controlOpacity.disabled : 1,
|
|
66
|
+
userSelect: "none",
|
|
67
|
+
background: "transparent",
|
|
68
|
+
color: theme.paints.palette.rest.color,
|
|
69
|
+
...(orientation === "vertical" ? { justifyContent: "start" } : {}),
|
|
70
|
+
...style
|
|
71
|
+
}), children: state => _jsxs(_Fragment, { children: [state.isSelected && _jsx(Surface, { as: motion.span, "data-tabs-indicator": "", "aria-hidden": "true", initial: false, layoutId: "selection", color: theme.paints.palette.hover.background, transition: theme.motionTransition, style: {
|
|
72
|
+
position: "absolute",
|
|
73
|
+
zIndex: -1,
|
|
74
|
+
inset: 0,
|
|
75
|
+
boxSizing: "border-box",
|
|
76
|
+
borderRadius: theme.radius,
|
|
77
|
+
pointerEvents: "none"
|
|
78
|
+
} }), _jsx("span", { style: { minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: typeof children === "function" ? children(state) : children })] }) });
|
|
79
|
+
});
|
|
80
|
+
export const TabsPanels = AriaTabPanels;
|
|
81
|
+
export const TabsPanel = forwardRef(function TabsPanel({ className, style, ...properties }, ref) {
|
|
82
|
+
const { orientation, theme } = useTabsTheme();
|
|
83
|
+
return _jsx(AriaTabPanel, { ...properties, ref: ref, className: className, style: state => ({
|
|
84
|
+
flex: orientation === "vertical" ? "1 1 auto" : undefined,
|
|
85
|
+
minWidth: 0,
|
|
86
|
+
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
87
|
+
outlineOffset: 1,
|
|
88
|
+
...style
|
|
89
|
+
}) });
|
|
90
|
+
});
|
|
91
|
+
function useTabsTheme() {
|
|
92
|
+
const value = useContext(TabsThemeContext);
|
|
93
|
+
if (value == null)
|
|
94
|
+
throw new Error("Tabs parts must be used inside Tabs");
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
/** Peer views with one selected tab and one corresponding panel. */
|
|
98
|
+
export const Tabs = Object.assign(TabsRoot, {
|
|
99
|
+
List: TabsList,
|
|
100
|
+
Tab: TabsTab,
|
|
101
|
+
Panels: TabsPanels,
|
|
102
|
+
Panel: TabsPanel
|
|
103
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Time } from "@internationalized/date";
|
|
2
|
+
import type { TimeFieldProps as AriaTimeFieldProps } from "react-aria-components";
|
|
3
|
+
import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
|
|
4
|
+
import type { MaterialOverrides } from "./material-options.js";
|
|
5
|
+
import type { RadiusProps } from "./radius.js";
|
|
6
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
7
|
+
type TimeFieldOverrides = ControlOverrides | "isReadOnly" | "value" | "defaultValue" | "onChange" | "minValue" | "maxValue" | "placeholderValue" | "granularity" | "hourCycle" | "hideTimeZone" | "shouldForceLeadingZeros";
|
|
8
|
+
export interface TimeFieldProps extends Omit<AriaTimeFieldProps<Time>, TimeFieldOverrides>, ControlProps, FieldProps, RadiusProps, MaterialOverrides, ShadowOverrides {
|
|
9
|
+
readonly value?: Time | null;
|
|
10
|
+
readonly defaultValue?: Time | null;
|
|
11
|
+
readonly onChange?: (value: Time | null) => void;
|
|
12
|
+
readonly minValue?: Time | null;
|
|
13
|
+
readonly maxValue?: Time | null;
|
|
14
|
+
readonly placeholderValue?: Time;
|
|
15
|
+
readonly granularity?: "hour" | "minute" | "second";
|
|
16
|
+
readonly hourCycle?: 12 | 24;
|
|
17
|
+
readonly shouldForceLeadingZeros?: boolean;
|
|
18
|
+
readonly readOnly?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** A locale-aware time-only field whose visible clock units are independent editable segments. */
|
|
21
|
+
export declare const TimeField: import("react").ForwardRefExoticComponent<TimeFieldProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { TimeField as AriaTimeField } from "react-aria-components";
|
|
4
|
+
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
5
|
+
import { FieldFeedback, FieldLabel, fieldStyle, useControlTheme } from "./control.js";
|
|
6
|
+
import { DateControl } from "./date-control.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
8
|
+
/** A locale-aware time-only field whose visible clock units are independent editable segments. */
|
|
9
|
+
export const TimeField = forwardRef(function TimeField({ label, description, errorMessage, disabled, readOnly, required, invalid, size, color, radius, material, shadow, style, className, ...properties }, ref) {
|
|
10
|
+
const theme = useControlTheme({ size, color, radius });
|
|
11
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
12
|
+
return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaTimeField, { ...properties, ref: ref, dir: direction, className: className, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(theme, disabled, style), children: state => _jsxs(_Fragment, { children: [_jsx(FieldLabel, { label: label }), _jsx(DateControl, { disabled: state.isDisabled, invalid: state.isInvalid, material: material, shadow: shadow, theme: theme }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] }) }) });
|
|
13
|
+
});
|
package/dist/toggle-indicator.js
CHANGED
|
@@ -6,7 +6,7 @@ export function ToggleIndicator({ kind, direction = "ltr", selected, indetermina
|
|
|
6
6
|
const { animations, motionTransition: transition } = theme;
|
|
7
7
|
const diameter = theme.indicatorSize;
|
|
8
8
|
const active = selected || indeterminate;
|
|
9
|
-
const paints = invalid ? theme.paints.danger : active ? theme.paints.palette : theme.paints.
|
|
9
|
+
const paints = invalid ? theme.paints.danger : active ? theme.paints.palette : theme.paints.subtle;
|
|
10
10
|
const paint = pressed ? paints.pressed : hovered ? paints.hover : paints.rest;
|
|
11
11
|
const radius = kind === "checkbox" ? Math.min(diameter / 4, typeof theme.radius === "number" ? theme.radius : diameter / 4) : diameter;
|
|
12
12
|
const switching = kind === "switch";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, CSSProperties, ReactElement } from "react";
|
|
2
|
+
import type { GroupProps as AriaGroupProps, SeparatorProps as AriaSeparatorProps } from "react-aria-components";
|
|
3
|
+
import { type ControlColor } from "./control.js";
|
|
4
|
+
import { type LayoutGap } from "./layout.js";
|
|
5
|
+
type ToolbarOrientation = "horizontal" | "vertical";
|
|
6
|
+
export interface ToolbarRootProps extends Omit<ComponentPropsWithoutRef<"div">, "className" | "color" | "role" | "style"> {
|
|
7
|
+
/** Base color inherited by toolbar-owned text and separators. */
|
|
8
|
+
readonly color?: ControlColor;
|
|
9
|
+
/** Space between the Toolbar's direct children. */
|
|
10
|
+
readonly gap?: LayoutGap;
|
|
11
|
+
/** Axis used both for layout and arrow-key navigation. */
|
|
12
|
+
readonly orientation?: ToolbarOrientation;
|
|
13
|
+
/** Native class name applied without replacing the Toolbar contract. */
|
|
14
|
+
readonly className?: string;
|
|
15
|
+
/** Native styles applied after Toolbar defaults. */
|
|
16
|
+
readonly style?: CSSProperties;
|
|
17
|
+
}
|
|
18
|
+
/** A labelled group of controls with orientation-aware arrow-key navigation. */
|
|
19
|
+
export declare const ToolbarRoot: import("react").ForwardRefExoticComponent<ToolbarRootProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export interface ToolbarGroupProps extends Omit<AriaGroupProps, "className" | "style"> {
|
|
21
|
+
/** Space between the controls in this group. */
|
|
22
|
+
readonly gap?: LayoutGap;
|
|
23
|
+
/** Native class name applied without replacing the group contract. */
|
|
24
|
+
readonly className?: string;
|
|
25
|
+
/** Native styles applied after group defaults. */
|
|
26
|
+
readonly style?: CSSProperties;
|
|
27
|
+
}
|
|
28
|
+
/** A semantic group of related controls within a Toolbar. */
|
|
29
|
+
export declare const ToolbarGroup: import("react").ForwardRefExoticComponent<ToolbarGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
30
|
+
export interface ToolbarSeparatorProps extends Omit<AriaSeparatorProps, "className" | "orientation" | "style"> {
|
|
31
|
+
/** Native class name applied without replacing the separator contract. */
|
|
32
|
+
readonly className?: string;
|
|
33
|
+
/** Native styles applied after separator defaults. */
|
|
34
|
+
readonly style?: CSSProperties;
|
|
35
|
+
}
|
|
36
|
+
/** A visual boundary whose axis is perpendicular to its Toolbar. */
|
|
37
|
+
export declare const ToolbarSeparator: import("react").ForwardRefExoticComponent<ToolbarSeparatorProps & import("react").RefAttributes<HTMLElement>>;
|
|
38
|
+
interface ToolbarComponent {
|
|
39
|
+
(properties: ToolbarRootProps): ReactElement | null;
|
|
40
|
+
readonly Group: typeof ToolbarGroup;
|
|
41
|
+
readonly Separator: typeof ToolbarSeparator;
|
|
42
|
+
}
|
|
43
|
+
/** A keyboard-navigable layout for related interactive controls. */
|
|
44
|
+
export declare const Toolbar: ToolbarComponent;
|
|
45
|
+
export type ToolbarProps = ToolbarRootProps;
|
|
46
|
+
export {};
|
package/dist/toolbar.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo, useRef } from "react";
|
|
3
|
+
import { FocusScope, mergeProps, mergeRefs, useFocusManager, useToolbar } from "react-aria";
|
|
4
|
+
import { Group as AriaGroup, Separator as AriaSeparator } from "react-aria-components";
|
|
5
|
+
import { useResolvedAppearance } from "./appearance-context.js";
|
|
6
|
+
import { colorOpacity, resolveColor } from "./color.js";
|
|
7
|
+
import { controlOpacity } from "./control.js";
|
|
8
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
9
|
+
import { resolveGap } from "./layout.js";
|
|
10
|
+
const ToolbarThemeContext = createContext(null);
|
|
11
|
+
/** A labelled group of controls with orientation-aware arrow-key navigation. */
|
|
12
|
+
export const ToolbarRoot = forwardRef(function ToolbarRoot(properties, ref) {
|
|
13
|
+
return _jsx(FocusScope, { children: _jsx(ToolbarLayout, { ...properties, ref: ref }) });
|
|
14
|
+
});
|
|
15
|
+
const ToolbarLayout = forwardRef(function ToolbarLayout({ className, color, gap = "medium", orientation = "horizontal", style, ...properties }, ref) {
|
|
16
|
+
const { appearance, colors } = useResolvedAppearance();
|
|
17
|
+
const fallbackDirection = useDirection();
|
|
18
|
+
const direction = resolveDirection(properties.dir, fallbackDirection);
|
|
19
|
+
const localRef = useRef(null);
|
|
20
|
+
const focusManager = useFocusManager();
|
|
21
|
+
const { toolbarProps } = useToolbar({
|
|
22
|
+
"aria-label": properties["aria-label"],
|
|
23
|
+
"aria-labelledby": properties["aria-labelledby"],
|
|
24
|
+
orientation
|
|
25
|
+
}, localRef);
|
|
26
|
+
const { onKeyDownCapture: _localeKeyDown, ...behaviorProperties } = toolbarProps;
|
|
27
|
+
const foreground = resolveColor(color ?? "foreground:base", colors);
|
|
28
|
+
const theme = useMemo(() => ({
|
|
29
|
+
gap: resolveGap(gap, appearance),
|
|
30
|
+
groupGap: resolveGap("small", appearance),
|
|
31
|
+
orientation,
|
|
32
|
+
separator: colorOpacity(foreground, controlOpacity.separator)
|
|
33
|
+
}), [appearance, foreground, gap, orientation]);
|
|
34
|
+
return _jsx(ToolbarThemeContext.Provider, { value: theme, children: _jsx("div", { ...mergeProps(properties, behaviorProperties, {
|
|
35
|
+
onKeyDownCapture: toolbarKeyDown(focusManager, orientation, direction)
|
|
36
|
+
}), ref: mergeRefs(localRef, ref), className: className, style: {
|
|
37
|
+
display: "flex",
|
|
38
|
+
flexDirection: orientation === "horizontal" ? "row" : "column",
|
|
39
|
+
alignItems: orientation === "horizontal" ? "center" : "flex-start",
|
|
40
|
+
gap: theme.gap,
|
|
41
|
+
width: "fit-content",
|
|
42
|
+
maxWidth: "100%",
|
|
43
|
+
minWidth: 0,
|
|
44
|
+
color: foreground,
|
|
45
|
+
fontFamily: "inherit",
|
|
46
|
+
...style
|
|
47
|
+
} }) });
|
|
48
|
+
});
|
|
49
|
+
function toolbarKeyDown(focusManager, orientation, direction) {
|
|
50
|
+
return event => {
|
|
51
|
+
if (focusManager == null || !event.currentTarget.contains(event.target))
|
|
52
|
+
return;
|
|
53
|
+
const forward = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
|
|
54
|
+
const backward = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
|
|
55
|
+
if (event.key === forward) {
|
|
56
|
+
if (orientation === "horizontal" && direction === "rtl")
|
|
57
|
+
focusManager.focusPrevious();
|
|
58
|
+
else
|
|
59
|
+
focusManager.focusNext();
|
|
60
|
+
}
|
|
61
|
+
else if (event.key === backward) {
|
|
62
|
+
if (orientation === "horizontal" && direction === "rtl")
|
|
63
|
+
focusManager.focusNext();
|
|
64
|
+
else
|
|
65
|
+
focusManager.focusPrevious();
|
|
66
|
+
}
|
|
67
|
+
else if (event.key === "Tab") {
|
|
68
|
+
if (event.shiftKey)
|
|
69
|
+
focusManager.focusFirst();
|
|
70
|
+
else
|
|
71
|
+
focusManager.focusLast();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
event.stopPropagation();
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** A semantic group of related controls within a Toolbar. */
|
|
82
|
+
export const ToolbarGroup = forwardRef(function ToolbarGroup({ className, gap, style, ...properties }, ref) {
|
|
83
|
+
const inherited = useToolbarTheme();
|
|
84
|
+
const { appearance } = useResolvedAppearance();
|
|
85
|
+
return _jsx(AriaGroup, { ...properties, ref: ref, className: className, style: {
|
|
86
|
+
display: "flex",
|
|
87
|
+
flexDirection: inherited.orientation === "horizontal" ? "row" : "column",
|
|
88
|
+
alignItems: inherited.orientation === "horizontal" ? "center" : "flex-start",
|
|
89
|
+
gap: gap === undefined ? inherited.groupGap : resolveGap(gap, appearance),
|
|
90
|
+
minWidth: 0,
|
|
91
|
+
...style
|
|
92
|
+
} });
|
|
93
|
+
});
|
|
94
|
+
/** A visual boundary whose axis is perpendicular to its Toolbar. */
|
|
95
|
+
export const ToolbarSeparator = forwardRef(function ToolbarSeparator({ className, style, ...properties }, ref) {
|
|
96
|
+
const { orientation, separator } = useToolbarTheme();
|
|
97
|
+
const separatorOrientation = orientation === "horizontal" ? "vertical" : "horizontal";
|
|
98
|
+
return _jsx(AriaSeparator, { ...properties, ref: ref, className: className, orientation: separatorOrientation, style: {
|
|
99
|
+
flexShrink: 0,
|
|
100
|
+
alignSelf: "center",
|
|
101
|
+
width: separatorOrientation === "vertical" ? 1 : "50%",
|
|
102
|
+
minWidth: separatorOrientation === "vertical" ? 1 : undefined,
|
|
103
|
+
height: separatorOrientation === "vertical" ? "1.5em" : 1,
|
|
104
|
+
minHeight: separatorOrientation === "vertical" ? 8 : 1,
|
|
105
|
+
margin: 0,
|
|
106
|
+
border: 0,
|
|
107
|
+
background: separator,
|
|
108
|
+
...style
|
|
109
|
+
} });
|
|
110
|
+
});
|
|
111
|
+
function useToolbarTheme() {
|
|
112
|
+
const context = useContext(ToolbarThemeContext);
|
|
113
|
+
if (context == null)
|
|
114
|
+
throw new Error("Toolbar parts must be used inside Toolbar");
|
|
115
|
+
return context;
|
|
116
|
+
}
|
|
117
|
+
/** A keyboard-navigable layout for related interactive controls. */
|
|
118
|
+
export const Toolbar = Object.assign(ToolbarRoot, {
|
|
119
|
+
Group: ToolbarGroup,
|
|
120
|
+
Separator: ToolbarSeparator
|
|
121
|
+
});
|
package/dist/tooltip.d.ts
CHANGED
|
@@ -14,7 +14,6 @@ export interface TooltipContentProps extends Omit<AriaTooltipProps, "children" |
|
|
|
14
14
|
export declare const TooltipContent: import("react").ForwardRefExoticComponent<TooltipContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
15
15
|
/** A description shown from the focus and hover state of its trigger. */
|
|
16
16
|
export declare const Tooltip: typeof TooltipRoot & {
|
|
17
|
-
Root: typeof TooltipRoot;
|
|
18
17
|
Trigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
19
18
|
Content: import("react").ForwardRefExoticComponent<TooltipContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
20
19
|
};
|
package/dist/tooltip.js
CHANGED
|
@@ -33,7 +33,6 @@ export const TooltipContent = forwardRef(function TooltipContent({ children, cla
|
|
|
33
33
|
});
|
|
34
34
|
/** A description shown from the focus and hover state of its trigger. */
|
|
35
35
|
export const Tooltip = Object.assign(TooltipRoot, {
|
|
36
|
-
Root: TooltipRoot,
|
|
37
36
|
Trigger: TooltipTrigger,
|
|
38
37
|
Content: TooltipContent
|
|
39
38
|
});
|
package/dist/tree.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, RefAttributes } from "react";
|
|
2
|
+
import { Collection as AriaCollection } from "react-aria-components";
|
|
3
|
+
import type { CollectionProps as AriaCollectionProps, TreeItemContentProps as AriaTreeItemContentProps, TreeItemProps as AriaTreeItemProps, TreeProps as AriaTreeProps } from "react-aria-components";
|
|
4
|
+
import type { ControlColor } from "./control.js";
|
|
5
|
+
import type { RadiusProps } from "./radius.js";
|
|
6
|
+
import type { ScaleLevel } from "./scale.js";
|
|
7
|
+
import { type MultipleStringSelection, type MultipleStringSelectionProps, type SingleStringSelectionProps } from "./selection.js";
|
|
8
|
+
type TreeRootBaseProps<T extends object> = Omit<AriaTreeProps<T>, "className" | "defaultExpandedKeys" | "defaultSelectedKeys" | "disabledKeys" | "expandedKeys" | "onAction" | "onExpandedChange" | "onSelectionChange" | "selectedKeys" | "selectionMode" | "style"> & RadiusProps & Readonly<{
|
|
9
|
+
className?: string;
|
|
10
|
+
color?: ControlColor;
|
|
11
|
+
defaultExpanded?: readonly string[];
|
|
12
|
+
disabledValues?: readonly string[];
|
|
13
|
+
expanded?: readonly string[];
|
|
14
|
+
onExpandedChange?: (values: readonly string[]) => void;
|
|
15
|
+
onItemAction?: (value: string) => void;
|
|
16
|
+
size?: ScaleLevel;
|
|
17
|
+
style?: CSSProperties;
|
|
18
|
+
}>;
|
|
19
|
+
export type TreeNoSelectionProps = Readonly<{
|
|
20
|
+
selectionMode?: "none";
|
|
21
|
+
value?: never;
|
|
22
|
+
defaultValue?: never;
|
|
23
|
+
onChange?: never;
|
|
24
|
+
}>;
|
|
25
|
+
export type TreeSingleSelectionProps = SingleStringSelectionProps & Readonly<{
|
|
26
|
+
selectionMode: "single";
|
|
27
|
+
}>;
|
|
28
|
+
export type TreeMultipleValue = MultipleStringSelection;
|
|
29
|
+
export type TreeMultipleSelectionProps = MultipleStringSelectionProps & Readonly<{
|
|
30
|
+
selectionMode: "multiple";
|
|
31
|
+
}>;
|
|
32
|
+
export type TreeRootProps<T extends object = object> = TreeRootBaseProps<T> & (TreeNoSelectionProps | TreeSingleSelectionProps | TreeMultipleSelectionProps);
|
|
33
|
+
export type TreeRootComponent = <T extends object = object>(properties: TreeRootProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
34
|
+
export declare const TreeRoot: TreeRootComponent;
|
|
35
|
+
export interface TreeItemProps<T = object> extends Omit<AriaTreeItemProps<T>, "className" | "id" | "isDisabled" | "style"> {
|
|
36
|
+
readonly className?: string;
|
|
37
|
+
readonly disabled?: boolean;
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly style?: CSSProperties;
|
|
40
|
+
}
|
|
41
|
+
export type TreeItemComponent = <T = object>(properties: TreeItemProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
42
|
+
export declare const TreeItem: TreeItemComponent;
|
|
43
|
+
export interface TreeContentProps extends AriaTreeItemContentProps {
|
|
44
|
+
readonly children: AriaTreeItemContentProps["children"];
|
|
45
|
+
}
|
|
46
|
+
export declare const TreeContent: import("react").ForwardRefExoticComponent<TreeContentProps & RefAttributes<Element>>;
|
|
47
|
+
export type TreeCollectionProps<T extends object = object> = AriaCollectionProps<T>;
|
|
48
|
+
export declare const TreeCollection: typeof AriaCollection;
|
|
49
|
+
/** Hierarchical navigation with independently controlled expansion, selection, and item actions. */
|
|
50
|
+
export declare const Tree: TreeRootComponent & {
|
|
51
|
+
Item: TreeItemComponent;
|
|
52
|
+
Content: import("react").ForwardRefExoticComponent<TreeContentProps & RefAttributes<Element>>;
|
|
53
|
+
Collection: typeof AriaCollection;
|
|
54
|
+
};
|
|
55
|
+
export type TreeProps<T extends object = object> = TreeRootProps<T>;
|
|
56
|
+
export {};
|