@phreshos/react-ui 0.1.30 → 0.1.32
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/appearance.d.ts +6 -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 +27 -11
- 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/preferences.d.ts +8 -0
- 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/ui-provider.d.ts +4 -4
- package/dist/ui-provider.js +47 -8
- package/dist/window.d.ts +6 -3
- package/dist/window.js +10 -7
- package/package.json +4 -2
package/dist/menu.js
CHANGED
|
@@ -3,23 +3,43 @@ import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
|
3
3
|
import { Header as AriaHeader, Menu as AriaMenu, MenuItem as AriaMenuItem, MenuSection as AriaMenuSection, Separator as AriaSeparator } from "react-aria-components";
|
|
4
4
|
import { colorOpacity } from "./color.js";
|
|
5
5
|
import { controlFontWeight, controlOpacity, useControlTheme } from "./control.js";
|
|
6
|
+
import { multipleSelection, singleSelection, stringKey, toAriaSelection } from "./selection.js";
|
|
6
7
|
const MenuThemeContext = createContext(null);
|
|
7
|
-
const MenuRootImplementation = forwardRef(function MenuRoot(
|
|
8
|
+
const MenuRootImplementation = forwardRef(function MenuRoot(properties, ref) {
|
|
9
|
+
const { className, color, defaultValue, disabledValues, onChange, onItemAction, selectionMode = "none", size = "medium", style, value, ...native } = properties;
|
|
8
10
|
const theme = useControlTheme({ color, size });
|
|
9
11
|
const context = useMemo(() => ({ color, size, theme }), [color, size, theme]);
|
|
10
|
-
return _jsx(MenuThemeContext.Provider, { value: context, children: _jsx(AriaMenu, { ...properties, ref: ref, className: className, style: {
|
|
12
|
+
return _jsx(MenuThemeContext.Provider, { value: context, children: _jsx(AriaMenu, { ...native, ...selectionProperties(properties), ref: ref, className: className, disabledKeys: disabledValues, selectionMode: selectionMode === "none" ? undefined : selectionMode, onAction: onItemAction == null ? undefined : key => onItemAction(stringKey(key)), style: {
|
|
11
13
|
display: "grid",
|
|
12
14
|
gap: theme.gap,
|
|
13
15
|
minWidth: theme.height * 4,
|
|
14
16
|
padding: theme.gap,
|
|
15
17
|
boxSizing: "border-box",
|
|
16
18
|
outline: "none",
|
|
17
|
-
color: theme.foreground,
|
|
18
19
|
fontFamily: "inherit",
|
|
19
20
|
fontSize: theme.fontSize,
|
|
20
21
|
...style
|
|
21
22
|
} }) });
|
|
22
23
|
});
|
|
24
|
+
function selectionProperties(properties) {
|
|
25
|
+
const selectedKeys = toAriaSelection(properties.value);
|
|
26
|
+
const defaultSelectedKeys = toAriaSelection(properties.defaultValue);
|
|
27
|
+
const onSelectionChange = properties.onChange == null
|
|
28
|
+
? undefined
|
|
29
|
+
: (selection) => {
|
|
30
|
+
if (properties.selectionMode === "multiple") {
|
|
31
|
+
properties.onChange?.(multipleSelection(selection));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (properties.selectionMode === "single")
|
|
35
|
+
properties.onChange?.(singleSelection(selection));
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
...(selectedKeys !== undefined ? { selectedKeys } : {}),
|
|
39
|
+
...(defaultSelectedKeys !== undefined ? { defaultSelectedKeys } : {}),
|
|
40
|
+
...(onSelectionChange !== undefined ? { onSelectionChange } : {})
|
|
41
|
+
};
|
|
42
|
+
}
|
|
23
43
|
export const MenuRoot = MenuRootImplementation;
|
|
24
44
|
const MenuItemImplementation = forwardRef(function MenuItem({ className, color, disabled = false, style, ...properties }, ref) {
|
|
25
45
|
const inherited = useContext(MenuThemeContext);
|
|
@@ -37,7 +57,7 @@ function MenuItemView({ className, disabled, properties, ref, style, theme }) {
|
|
|
37
57
|
? theme.paints.palette.pressed
|
|
38
58
|
: state.isHovered || state.isSelected
|
|
39
59
|
? theme.paints.palette.hover
|
|
40
|
-
: { background: "transparent", color:
|
|
60
|
+
: { background: "transparent", color: "inherit" };
|
|
41
61
|
return {
|
|
42
62
|
...theme.transition,
|
|
43
63
|
display: "flex",
|
|
@@ -77,7 +97,7 @@ export const MenuSeparator = forwardRef(function MenuSeparator({ style, ...prope
|
|
|
77
97
|
height: 1,
|
|
78
98
|
marginBlock: theme.gap,
|
|
79
99
|
border: 0,
|
|
80
|
-
background: colorOpacity(theme.
|
|
100
|
+
background: colorOpacity(theme.tint, controlOpacity.separator),
|
|
81
101
|
...style
|
|
82
102
|
} });
|
|
83
103
|
});
|
|
@@ -89,7 +109,6 @@ function useMenuTheme() {
|
|
|
89
109
|
}
|
|
90
110
|
/** A keyboard-navigable collection of commands or selectable options. */
|
|
91
111
|
export const Menu = Object.assign(MenuRoot, {
|
|
92
|
-
Root: MenuRoot,
|
|
93
112
|
Item: MenuItem,
|
|
94
113
|
Section: MenuSection,
|
|
95
114
|
Header: MenuHeader,
|
package/dist/panel.d.ts
CHANGED
|
@@ -11,7 +11,6 @@ export type PanelContentProps = SurfaceProps;
|
|
|
11
11
|
export declare const PanelContent: import("react").ForwardRefExoticComponent<Omit<PanelContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
12
12
|
/** A material shell whose named parts remain independently composable. */
|
|
13
13
|
export declare const Panel: import("react").ForwardRefExoticComponent<Omit<PanelRootProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
14
|
-
Root: import("react").ForwardRefExoticComponent<Omit<PanelRootProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
15
14
|
Header: import("react").ForwardRefExoticComponent<PanelHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
16
15
|
Content: import("react").ForwardRefExoticComponent<Omit<PanelContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
17
16
|
};
|
package/dist/panel.js
CHANGED
|
@@ -36,7 +36,6 @@ export const PanelContent = forwardRef(function PanelContent({ style, ...propert
|
|
|
36
36
|
});
|
|
37
37
|
/** A material shell whose named parts remain independently composable. */
|
|
38
38
|
export const Panel = Object.assign(PanelRoot, {
|
|
39
|
-
Root: PanelRoot,
|
|
40
39
|
Header: PanelHeader,
|
|
41
40
|
Content: PanelContent
|
|
42
41
|
});
|
package/dist/popover.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export type PopoverCloseProps = ButtonProps;
|
|
|
20
20
|
export declare const PopoverClose: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
21
21
|
/** An anchored non-modal overlay with explicit trigger, surface, and dialog roles. */
|
|
22
22
|
export declare const Popover: typeof PopoverRoot & {
|
|
23
|
-
Root: typeof PopoverRoot;
|
|
24
23
|
Trigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
25
24
|
Content: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
|
|
26
25
|
Dialog: import("react").ForwardRefExoticComponent<AriaDialogProps & import("react").RefAttributes<HTMLElement>>;
|
package/dist/popover.js
CHANGED
|
@@ -3,6 +3,7 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { Dialog as AriaDialog, DialogTrigger as AriaDialogTrigger, Heading as AriaHeading, Popover as AriaPopover } from "react-aria-components";
|
|
4
4
|
import { useResolvedAppearance } from "./appearance-context.js";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
|
+
import { controlFontSizes, controlFontWeight } from "./control.js";
|
|
6
7
|
import MotionStyle, { overlayMotionClass, overlayTransition } from "./motion-style.js";
|
|
7
8
|
import { scale } from "./scale.js";
|
|
8
9
|
import { Surface } from "./surface.js";
|
|
@@ -30,15 +31,24 @@ export const PopoverContent = forwardRef(function PopoverContent({ children, cla
|
|
|
30
31
|
export const PopoverDialog = forwardRef(function PopoverDialog({ style, ...properties }, ref) {
|
|
31
32
|
return _jsx(AriaDialog, { ...properties, ref: ref, style: { minWidth: 0, outline: "none", ...style } });
|
|
32
33
|
});
|
|
33
|
-
export const PopoverTitle = forwardRef(function PopoverTitle(properties, ref) {
|
|
34
|
-
return _jsx(AriaHeading, { ...properties, ref: ref, slot: "title"
|
|
34
|
+
export const PopoverTitle = forwardRef(function PopoverTitle({ style, ...properties }, ref) {
|
|
35
|
+
return _jsx(AriaHeading, { ...properties, ref: ref, slot: "title",
|
|
36
|
+
// Portalled headings cannot rely on the trigger subtree to neutralize
|
|
37
|
+
// browser heading defaults; this part owns its complete text treatment.
|
|
38
|
+
style: {
|
|
39
|
+
margin: 0,
|
|
40
|
+
fontFamily: "inherit",
|
|
41
|
+
fontSize: controlFontSizes.medium,
|
|
42
|
+
fontWeight: controlFontWeight,
|
|
43
|
+
lineHeight: 1.5,
|
|
44
|
+
...style
|
|
45
|
+
} });
|
|
35
46
|
});
|
|
36
47
|
export const PopoverClose = forwardRef(function PopoverClose(properties, ref) {
|
|
37
48
|
return _jsx(Button, { ...properties, ref: ref, slot: "close" });
|
|
38
49
|
});
|
|
39
50
|
/** An anchored non-modal overlay with explicit trigger, surface, and dialog roles. */
|
|
40
51
|
export const Popover = Object.assign(PopoverRoot, {
|
|
41
|
-
Root: PopoverRoot,
|
|
42
52
|
Trigger: PopoverTrigger,
|
|
43
53
|
Content: PopoverContent,
|
|
44
54
|
Dialog: PopoverDialog,
|
package/dist/preferences.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { DesktopPreferences } from "@phreshos/core";
|
|
2
2
|
/** Complete environment preferences consumed by React UI. */
|
|
3
3
|
export type Preferences = Pick<DesktopPreferences, "theme" | "animations">;
|
|
4
|
+
/** At least one preference merged with the nearest UIProvider. */
|
|
5
|
+
export type PreferencesUpdate = Readonly<{
|
|
6
|
+
theme: Preferences["theme"];
|
|
7
|
+
animations?: Preferences["animations"];
|
|
8
|
+
}> | Readonly<{
|
|
9
|
+
theme?: Preferences["theme"];
|
|
10
|
+
animations: Preferences["animations"];
|
|
11
|
+
}>;
|
|
4
12
|
export type Theme = Preferences["theme"];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { ProgressBarProps as AriaProgressBarProps } from "react-aria-components";
|
|
3
|
+
import type { ControlColor } from "./control.js";
|
|
4
|
+
import type { ScaleLevel } from "./scale.js";
|
|
5
|
+
type NativeProgressBarProps = Omit<AriaProgressBarProps, "children" | "className" | "isIndeterminate" | "style">;
|
|
6
|
+
export interface ProgressBarProps extends NativeProgressBarProps {
|
|
7
|
+
/** Native class name applied without replacing the component contract. */
|
|
8
|
+
readonly className?: string;
|
|
9
|
+
/** Color used for the completed or moving portion. */
|
|
10
|
+
readonly color?: ControlColor;
|
|
11
|
+
/** Displays progress without asserting a current value. */
|
|
12
|
+
readonly indeterminate?: boolean;
|
|
13
|
+
/** Visible label associated with the progress value. */
|
|
14
|
+
readonly label?: ReactNode;
|
|
15
|
+
/** Derives typography and track thickness from Appearance. */
|
|
16
|
+
readonly size?: ScaleLevel;
|
|
17
|
+
/** Native styles applied after ProgressBar defaults. */
|
|
18
|
+
readonly style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/** Determinate or indeterminate progress for an operation over time. */
|
|
21
|
+
export declare const ProgressBar: import("react").ForwardRefExoticComponent<ProgressBarProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Label, ProgressBar as AriaProgressBar } from "react-aria-components";
|
|
4
|
+
import { motion } from "motion/react";
|
|
5
|
+
import { controlFontWeight, controlOpacity, fieldStyle, useControlTheme } from "./control.js";
|
|
6
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
7
|
+
/** Determinate or indeterminate progress for an operation over time. */
|
|
8
|
+
export const ProgressBar = forwardRef(function ProgressBar({ className, color = "default:base", indeterminate = false, label, size = "medium", style, value, minValue = 0, maxValue = 100, ...properties }, ref) {
|
|
9
|
+
const theme = useControlTheme({ color, size });
|
|
10
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
11
|
+
const thickness = Math.max(2, Math.round(theme.spacing / 2));
|
|
12
|
+
const sweep = direction === "rtl" ? ["100%", "-350%"] : ["-100%", "350%"];
|
|
13
|
+
const duration = typeof theme.motionTransition.duration === "number"
|
|
14
|
+
? theme.motionTransition.duration * 10
|
|
15
|
+
: 1.2;
|
|
16
|
+
return _jsx(AriaProgressBar, { ...properties, ref: ref, className: className, value: value, minValue: minValue, maxValue: maxValue, isIndeterminate: indeterminate, style: {
|
|
17
|
+
...fieldStyle(theme, false),
|
|
18
|
+
width: "100%",
|
|
19
|
+
...style
|
|
20
|
+
}, children: state => {
|
|
21
|
+
const output = properties.valueLabel ?? state.valueText;
|
|
22
|
+
const showHeading = label != null || (!state.isIndeterminate && output != null);
|
|
23
|
+
const moving = state.isIndeterminate && theme.animations;
|
|
24
|
+
return _jsxs(_Fragment, { children: [showHeading && _jsxs("span", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: theme.gap }, children: [label != null && _jsx(Label, { style: { fontWeight: controlFontWeight }, children: label }), !state.isIndeterminate && output != null && _jsx("span", { style: { fontVariantNumeric: "tabular-nums", opacity: controlOpacity.secondary }, children: output })] }), _jsx("span", { "data-progress-track": "", "aria-hidden": "true", style: {
|
|
25
|
+
position: "relative",
|
|
26
|
+
display: "block",
|
|
27
|
+
width: "100%",
|
|
28
|
+
height: thickness,
|
|
29
|
+
overflow: "hidden",
|
|
30
|
+
borderRadius: thickness,
|
|
31
|
+
background: theme.paints.subtle.rest.background
|
|
32
|
+
}, children: _jsx(motion.span, { "data-progress-fill": "", initial: false, animate: { x: moving ? sweep : "0%" }, transition: moving
|
|
33
|
+
? { ...theme.motionTransition, duration, repeat: Infinity }
|
|
34
|
+
: theme.motionTransition, style: {
|
|
35
|
+
...theme.transition,
|
|
36
|
+
position: "absolute",
|
|
37
|
+
insetBlock: 0,
|
|
38
|
+
insetInlineStart: state.isIndeterminate && !moving ? "30%" : 0,
|
|
39
|
+
display: "block",
|
|
40
|
+
width: state.isIndeterminate ? "40%" : `${state.percentage ?? 0}%`,
|
|
41
|
+
borderRadius: "inherit",
|
|
42
|
+
background: theme.paints.palette.rest.background,
|
|
43
|
+
transitionProperty: "width"
|
|
44
|
+
} }) })] });
|
|
45
|
+
} });
|
|
46
|
+
});
|
package/dist/radio.d.ts
CHANGED
|
@@ -12,10 +12,10 @@ export interface RadioGroupProps extends Omit<BaseRadioGroupProps<string | null>
|
|
|
12
12
|
readonly readOnly?: boolean;
|
|
13
13
|
readonly orientation?: "horizontal" | "vertical";
|
|
14
14
|
}
|
|
15
|
-
export interface
|
|
15
|
+
export interface RadioGroupItemProps extends Omit<BaseRadioProps<string>, "children" | "className" | "disabled" | "readOnly" | "required" | "style" | "value">, ControlProps, Pick<FieldProps, "label" | "description">, MaterialOverrides, ShadowOverrides {
|
|
16
16
|
readonly value: string;
|
|
17
17
|
}
|
|
18
|
-
/** One
|
|
19
|
-
export declare const RadioGroup: import("react").ForwardRefExoticComponent<Omit<RadioGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
/** One exclusive-choice field whose context-dependent options are grouped as Items. */
|
|
19
|
+
export declare const RadioGroup: import("react").ForwardRefExoticComponent<Omit<RadioGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>> & {
|
|
20
|
+
Item: import("react").ForwardRefExoticComponent<Omit<RadioGroupItemProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
21
|
+
};
|
package/dist/radio.js
CHANGED
|
@@ -8,8 +8,8 @@ import { controlFontWeight, controlOpacity, fieldStyle, useControlTheme } from "
|
|
|
8
8
|
import { ToggleIndicator, toggleStyle } from "./toggle-indicator.js";
|
|
9
9
|
import { resolveDirection, useDirection } from "./direction.js";
|
|
10
10
|
const RadioStyleContext = createContext(null);
|
|
11
|
-
/** One string value selected from its
|
|
12
|
-
|
|
11
|
+
/** One string value selected from its Items, with direction-aware arrow navigation. */
|
|
12
|
+
const RadioGroupRoot = forwardRef(function RadioGroupRoot({ label, description, errorMessage, children, disabled = false, readOnly = false, required = false, invalid = false, value, defaultValue, onChange, orientation = "vertical", size, color, style, className, material, shadow, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...properties }, ref) {
|
|
13
13
|
const theme = useControlTheme({ size, color });
|
|
14
14
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
15
15
|
const labelId = useId();
|
|
@@ -23,10 +23,10 @@ export const RadioGroup = forwardRef(function RadioGroup({ label, description, e
|
|
|
23
23
|
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
24
24
|
});
|
|
25
25
|
/** An option in a RadioGroup. Selection and validation belong to the group. */
|
|
26
|
-
|
|
26
|
+
const RadioGroupItem = forwardRef(function RadioGroupItem({ label, description, value, disabled = false, size, color, style, className, material, shadow, onFocus, onBlur, "aria-describedby": ariaDescribedBy, ...properties }, ref) {
|
|
27
27
|
const inherited = useContext(RadioStyleContext);
|
|
28
28
|
if (inherited == null)
|
|
29
|
-
throw new Error("
|
|
29
|
+
throw new Error("RadioGroup.Item must be used inside RadioGroup");
|
|
30
30
|
const theme = useControlTheme({ size: size ?? inherited.size, color: color ?? inherited.color });
|
|
31
31
|
const descriptionId = useId();
|
|
32
32
|
const [hovered, setHovered] = useState(false);
|
|
@@ -41,3 +41,7 @@ export const Radio = forwardRef(function Radio({ label, description, value, disa
|
|
|
41
41
|
onBlur?.(event);
|
|
42
42
|
}, style: state => toggleStyle(theme, state.disabled, state.readOnly), render: (native, state) => _jsxs("span", { ...native, children: [_jsx(ToggleIndicator, { kind: "radio", material: material ?? inherited.material, shadow: shadow ?? inherited.shadow, theme: theme, selected: state.checked, focused: focusVisible, invalid: inherited.invalid, hovered: !state.disabled && !state.readOnly && hovered, pressed: !state.disabled && !state.readOnly && pressed }), label] }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description })] });
|
|
43
43
|
});
|
|
44
|
+
/** One exclusive-choice field whose context-dependent options are grouped as Items. */
|
|
45
|
+
export const RadioGroup = Object.assign(RadioGroupRoot, {
|
|
46
|
+
Item: RadioGroupItem
|
|
47
|
+
});
|
package/dist/radius.js
CHANGED
|
@@ -6,6 +6,6 @@ export function resolveRadius(value, appearance) {
|
|
|
6
6
|
if (!isScaleLevel(value))
|
|
7
7
|
return value;
|
|
8
8
|
if (!appearance)
|
|
9
|
-
throw new Error("A semantic radius requires
|
|
9
|
+
throw new Error("A semantic radius requires an Appearance value");
|
|
10
10
|
return scale(appearance.radius, value);
|
|
11
11
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CalendarDate } from "@internationalized/date";
|
|
2
|
+
import type { RangeCalendarProps as AriaRangeCalendarProps } from "react-aria-components";
|
|
3
|
+
import { type ControlOverrides, type ControlProps } from "./control.js";
|
|
4
|
+
import type { DateRange } from "./date-range.js";
|
|
5
|
+
import type { RadiusProps } from "./radius.js";
|
|
6
|
+
type RangeCalendarOverrides = ControlOverrides | "children" | "isReadOnly" | "isInvalid" | "value" | "defaultValue" | "onChange" | "minValue" | "maxValue" | "isDateUnavailable" | "visibleDuration" | "createCalendar" | "errorMessage" | "validationState";
|
|
7
|
+
export interface RangeCalendarProps extends Omit<AriaRangeCalendarProps<CalendarDate>, RangeCalendarOverrides>, ControlProps, RadiusProps {
|
|
8
|
+
readonly value?: DateRange | null;
|
|
9
|
+
readonly defaultValue?: DateRange | null;
|
|
10
|
+
readonly onChange?: (value: DateRange) => void;
|
|
11
|
+
readonly minValue?: CalendarDate | null;
|
|
12
|
+
readonly maxValue?: CalendarDate | null;
|
|
13
|
+
readonly isDateUnavailable?: (date: CalendarDate, anchorDate: CalendarDate | null) => boolean;
|
|
14
|
+
readonly readOnly?: boolean;
|
|
15
|
+
readonly invalid?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** A locale-aware month view for selecting an inclusive date range. */
|
|
18
|
+
export declare const RangeCalendar: import("react").ForwardRefExoticComponent<RangeCalendarProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { RangeCalendar as AriaRangeCalendar } from "react-aria-components";
|
|
4
|
+
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
5
|
+
import { CalendarLayout, calendarRootStyle } from "./calendar-layout.js";
|
|
6
|
+
import { useControlTheme } from "./control.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
8
|
+
/** A locale-aware month view for selecting an inclusive date range. */
|
|
9
|
+
export const RangeCalendar = forwardRef(function RangeCalendar({ disabled, readOnly, invalid, size, color, radius, style, className, isDateUnavailable, ...properties }, ref) {
|
|
10
|
+
const theme = useControlTheme({ size, color, radius });
|
|
11
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
12
|
+
return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaRangeCalendar, { ...properties, ref: ref, dir: direction, className: className, isDisabled: disabled, isReadOnly: readOnly, isInvalid: invalid, isDateUnavailable: isDateUnavailable == null
|
|
13
|
+
? undefined
|
|
14
|
+
: (date, anchorDate) => isDateUnavailable(date, anchorDate), style: calendarRootStyle(theme, disabled, style), children: _jsx(CalendarLayout, { color: color, range: true, size: size, theme: theme }) }) });
|
|
15
|
+
});
|
package/dist/scroll-area.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { ComponentPropsWithoutRef, Ref, ReactNode, UIEventHandler } from "react";
|
|
2
|
+
import type { ControlColor } from "./control.js";
|
|
2
3
|
export type ScrollAreaAxis = "vertical" | "horizontal" | "both";
|
|
3
|
-
export interface ScrollAreaProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "onScroll"> {
|
|
4
|
+
export interface ScrollAreaProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "color" | "onScroll"> {
|
|
4
5
|
readonly axis?: ScrollAreaAxis;
|
|
5
6
|
readonly children?: ReactNode;
|
|
7
|
+
/** Base color from which scrollbar states are derived. */
|
|
8
|
+
readonly color?: ControlColor;
|
|
6
9
|
readonly onScroll?: UIEventHandler<HTMLDivElement>;
|
|
7
10
|
readonly viewportRef?: Ref<HTMLDivElement>;
|
|
8
11
|
}
|
package/dist/scroll-area.js
CHANGED
|
@@ -3,15 +3,15 @@ import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
|
3
3
|
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
4
4
|
import { forwardRef, useState } from "react";
|
|
5
5
|
import { useResolvedAppearance } from "./appearance-context.js";
|
|
6
|
-
import { colorOpacity } from "./color.js";
|
|
6
|
+
import { colorOpacity, resolveColor } from "./color.js";
|
|
7
7
|
import { transitionTiming } from "./motion-style.js";
|
|
8
8
|
import { resolveDirection, useDirection } from "./direction.js";
|
|
9
9
|
/** A native scrolling viewport with locally owned React UI scrollbars. */
|
|
10
|
-
export const ScrollArea = forwardRef(function ScrollArea({ axis = "vertical", children, onScroll, style, viewportRef, ...properties }, ref) {
|
|
10
|
+
export const ScrollArea = forwardRef(function ScrollArea({ axis = "vertical", children, color, onScroll, style, viewportRef, ...properties }, ref) {
|
|
11
11
|
const resolved = useResolvedAppearance();
|
|
12
12
|
const { appearance } = resolved;
|
|
13
13
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
14
|
-
const foreground = resolved.colors
|
|
14
|
+
const foreground = resolveColor(color ?? "foreground:base", resolved.colors);
|
|
15
15
|
const radius = Math.min(appearance.radius, 8);
|
|
16
16
|
const thickness = Math.max(8, appearance.spacing);
|
|
17
17
|
const inset = Math.max(2, thickness / 3);
|
package/dist/select.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useMemo } from "react";
|
|
3
|
-
import { Select as AriaSelect, Button, SelectValue
|
|
3
|
+
import { Select as AriaSelect, Button, SelectValue } from "react-aria-components";
|
|
4
4
|
import { controlOpacity, controlPaint, controlStyle, FieldFeedback, FieldLabel, fieldStyle, useControlTheme } from "./control.js";
|
|
5
5
|
import { SurfaceButton } from "./control-surface.js";
|
|
6
6
|
import { ScrollArea } from "./scroll-area.js";
|
|
7
7
|
import { PopoverContent } from "./popover.js";
|
|
8
8
|
import { resolveDirection, useDirection } from "./direction.js";
|
|
9
|
+
import { ListBox } from "./list-box.js";
|
|
9
10
|
/** Single selection from string-valued options; keyboard navigation and typeahead stay native to React Aria. */
|
|
10
11
|
export const Select = forwardRef(function Select({ label, description, errorMessage, disabled, required, invalid, options, value, defaultValue, onChange, size, color, radius, style, material, shadow, ...properties }, ref) {
|
|
11
12
|
const theme = useControlTheme({ size, color, radius });
|
|
@@ -18,19 +19,8 @@ export const Select = forwardRef(function Select({ label, description, errorMess
|
|
|
18
19
|
}), children: [_jsx(SelectValue, { style: ({ isPlaceholder }) => ({ opacity: isPlaceholder ? controlOpacity.placeholder : 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }) }), _jsx("svg", { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { ...theme.transition, transitionProperty: "transform", flexShrink: 0, transform: `rotate(${state.isOpen ? 180 : 0}deg)` }, children: _jsx("path", { d: "m2 4 4 4 4-4" }) })] }), _jsx(PopoverContent, { dir: direction, placement: "bottom start", offset: theme.gap, style: {
|
|
19
20
|
width: "var(--trigger-width)",
|
|
20
21
|
maxHeight: `min(calc(100vh - ${theme.spacing * 2}px), ${theme.height * 8}px)`,
|
|
21
|
-
padding:
|
|
22
|
+
padding: 0,
|
|
22
23
|
display: "flex",
|
|
23
24
|
flexDirection: "column"
|
|
24
|
-
}, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, {
|
|
25
|
-
...theme.transition,
|
|
26
|
-
display: "flex", alignItems: "center", justifyContent: "space-between", gap: theme.gap,
|
|
27
|
-
minHeight: theme.height, paddingInline: Math.max(8, theme.spacing), boxSizing: "border-box",
|
|
28
|
-
borderRadius: theme.radius,
|
|
29
|
-
outline: item.isFocusVisible && !item.isSelected ? `1px solid ${theme.focusColor}` : "none", outlineOffset: 1,
|
|
30
|
-
cursor: item.isDisabled ? "not-allowed" : "pointer",
|
|
31
|
-
opacity: item.isDisabled ? controlOpacity.disabled : 1,
|
|
32
|
-
...(item.isSelected
|
|
33
|
-
? item.isPressed ? theme.paints.palette.pressed : item.isHovered ? theme.paints.palette.hover : theme.paints.palette.rest
|
|
34
|
-
: item.isHovered ? theme.paints.neutral.hover : { background: "transparent", color: theme.foreground })
|
|
35
|
-
}), children: item => _jsxs(_Fragment, { children: [option.label, _jsx("span", { "aria-hidden": "true", children: item.isSelected ? "✓" : null })] }) }, option.value)) }) }) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] }) });
|
|
25
|
+
}, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { color: color, radius: radius, size: size, children: options.map(option => _jsx(ListBox.Item, { id: option.value, textValue: option.label, disabled: option.disabled, children: option.label }, option.value)) }) }) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] }) });
|
|
36
26
|
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Key, Selection } from "react-aria-components";
|
|
2
|
+
export type MultipleStringSelection = readonly string[] | "all";
|
|
3
|
+
export type SingleStringSelectionProps = Readonly<{
|
|
4
|
+
value?: string | null;
|
|
5
|
+
defaultValue?: string | null;
|
|
6
|
+
onChange?: (value: string | null) => void;
|
|
7
|
+
}>;
|
|
8
|
+
export type MultipleStringSelectionProps = Readonly<{
|
|
9
|
+
value?: MultipleStringSelection;
|
|
10
|
+
defaultValue?: MultipleStringSelection;
|
|
11
|
+
onChange?: (value: MultipleStringSelection) => void;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function toAriaSelection(value: string | null | MultipleStringSelection | undefined): "all" | Set<string> | undefined;
|
|
14
|
+
export declare function stringKey(value: Key): string;
|
|
15
|
+
export declare function optionalStringKey(value: Key | null): string | null;
|
|
16
|
+
export declare function singleSelection(selection: Selection): string | null;
|
|
17
|
+
export declare function multipleSelection(selection: Selection): MultipleStringSelection;
|
|
18
|
+
export declare function stringKeys(values: Iterable<Key>): readonly string[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function toAriaSelection(value) {
|
|
2
|
+
if (value === undefined)
|
|
3
|
+
return undefined;
|
|
4
|
+
if (value === "all")
|
|
5
|
+
return "all";
|
|
6
|
+
if (value === null)
|
|
7
|
+
return new Set();
|
|
8
|
+
if (typeof value === "string")
|
|
9
|
+
return new Set([value]);
|
|
10
|
+
return new Set(value);
|
|
11
|
+
}
|
|
12
|
+
export function stringKey(value) {
|
|
13
|
+
if (typeof value !== "string")
|
|
14
|
+
throw new Error("Collection identities must be strings");
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
export function optionalStringKey(value) {
|
|
18
|
+
return value === null ? null : stringKey(value);
|
|
19
|
+
}
|
|
20
|
+
export function singleSelection(selection) {
|
|
21
|
+
return selection === "all" ? null : optionalStringKey(selection.values().next().value ?? null);
|
|
22
|
+
}
|
|
23
|
+
export function multipleSelection(selection) {
|
|
24
|
+
return selection === "all" ? "all" : [...selection].map(stringKey);
|
|
25
|
+
}
|
|
26
|
+
export function stringKeys(values) {
|
|
27
|
+
return [...values].map(stringKey);
|
|
28
|
+
}
|
package/dist/slider.js
CHANGED
|
@@ -46,7 +46,7 @@ export const Slider = forwardRef(function Slider({ label, description, name, for
|
|
|
46
46
|
width: vertical ? rail : "100%",
|
|
47
47
|
height: vertical ? "100%" : rail,
|
|
48
48
|
borderRadius: rail,
|
|
49
|
-
background: theme.paints.
|
|
49
|
+
background: theme.paints.subtle.rest.background
|
|
50
50
|
}, children: [_jsx(BaseSlider.Indicator, { style: {
|
|
51
51
|
...theme.transition,
|
|
52
52
|
borderRadius: rail,
|
package/dist/spacing.js
CHANGED
|
@@ -3,6 +3,6 @@ export function resolveSpacing(value, appearance) {
|
|
|
3
3
|
if (!isScaleLevel(value))
|
|
4
4
|
return value;
|
|
5
5
|
if (!appearance)
|
|
6
|
-
throw new Error("Semantic spacing requires
|
|
6
|
+
throw new Error("Semantic spacing requires an Appearance value");
|
|
7
7
|
return scale(appearance.spacing, value);
|
|
8
8
|
}
|
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, RefAttributes } from "react";
|
|
2
|
+
import type { CellProps as AriaCellProps, ColumnProps as AriaColumnProps, RowProps as AriaRowProps, TableBodyProps as AriaTableBodyProps, TableHeaderProps as AriaTableHeaderProps, TableProps as AriaTableProps } 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
|
+
import { type MultipleStringSelection, type MultipleStringSelectionProps, type SingleStringSelectionProps } from "./selection.js";
|
|
7
|
+
export type TableSortDirection = "ascending" | "descending";
|
|
8
|
+
export interface TableSort {
|
|
9
|
+
readonly column: string;
|
|
10
|
+
readonly direction: TableSortDirection;
|
|
11
|
+
}
|
|
12
|
+
type TableRootBaseProps = Omit<AriaTableProps, "className" | "defaultSelectedKeys" | "disabledKeys" | "onRowAction" | "onSelectionChange" | "onSortChange" | "selectedKeys" | "selectionMode" | "sortDescriptor" | "style"> & RadiusProps & Readonly<{
|
|
13
|
+
className?: string;
|
|
14
|
+
color?: ControlColor;
|
|
15
|
+
disabledValues?: readonly string[];
|
|
16
|
+
onRowAction?: (value: string) => void;
|
|
17
|
+
onSortChange?: (sort: TableSort) => void;
|
|
18
|
+
size?: ScaleLevel;
|
|
19
|
+
sort?: TableSort;
|
|
20
|
+
style?: CSSProperties;
|
|
21
|
+
}>;
|
|
22
|
+
export type TableNoSelectionProps = Readonly<{
|
|
23
|
+
selectionMode?: "none";
|
|
24
|
+
value?: never;
|
|
25
|
+
defaultValue?: never;
|
|
26
|
+
onChange?: never;
|
|
27
|
+
}>;
|
|
28
|
+
export type TableSingleSelectionProps = SingleStringSelectionProps & Readonly<{
|
|
29
|
+
selectionMode: "single";
|
|
30
|
+
}>;
|
|
31
|
+
export type TableMultipleValue = MultipleStringSelection;
|
|
32
|
+
export type TableMultipleSelectionProps = MultipleStringSelectionProps & Readonly<{
|
|
33
|
+
selectionMode: "multiple";
|
|
34
|
+
}>;
|
|
35
|
+
export type TableRootProps = TableRootBaseProps & (TableNoSelectionProps | TableSingleSelectionProps | TableMultipleSelectionProps);
|
|
36
|
+
export declare const TableRoot: import("react").ForwardRefExoticComponent<TableRootProps & RefAttributes<HTMLDivElement | HTMLTableElement>>;
|
|
37
|
+
export interface TableHeaderProps<T extends object = object> extends Omit<AriaTableHeaderProps<T>, "className" | "style"> {
|
|
38
|
+
readonly className?: string;
|
|
39
|
+
readonly color?: ControlColor;
|
|
40
|
+
readonly style?: CSSProperties;
|
|
41
|
+
}
|
|
42
|
+
export type TableHeaderComponent = <T extends object = object>(properties: TableHeaderProps<T> & RefAttributes<HTMLTableSectionElement | HTMLDivElement>) => ReactElement | null;
|
|
43
|
+
export declare const TableHeader: TableHeaderComponent;
|
|
44
|
+
export interface TableColumnProps extends Omit<AriaColumnProps, "className" | "id" | "style"> {
|
|
45
|
+
readonly className?: string;
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly style?: CSSProperties;
|
|
48
|
+
}
|
|
49
|
+
export declare const TableColumn: import("react").ForwardRefExoticComponent<TableColumnProps & RefAttributes<HTMLDivElement | HTMLTableCellElement>>;
|
|
50
|
+
export interface TableBodyProps<T extends object = object> extends Omit<AriaTableBodyProps<T>, "className" | "style"> {
|
|
51
|
+
readonly className?: string;
|
|
52
|
+
readonly style?: CSSProperties;
|
|
53
|
+
}
|
|
54
|
+
export type TableBodyComponent = <T extends object = object>(properties: TableBodyProps<T> & RefAttributes<HTMLTableSectionElement | HTMLDivElement>) => ReactElement | null;
|
|
55
|
+
export declare const TableBody: TableBodyComponent;
|
|
56
|
+
export interface TableRowProps<T extends object = object> extends Omit<AriaRowProps<T>, "className" | "id" | "isDisabled" | "style"> {
|
|
57
|
+
readonly className?: string;
|
|
58
|
+
readonly disabled?: boolean;
|
|
59
|
+
readonly id: string;
|
|
60
|
+
readonly style?: CSSProperties;
|
|
61
|
+
}
|
|
62
|
+
export type TableRowComponent = <T extends object = object>(properties: TableRowProps<T> & RefAttributes<HTMLTableRowElement | HTMLDivElement>) => ReactElement | null;
|
|
63
|
+
export declare const TableRow: TableRowComponent;
|
|
64
|
+
export interface TableCellProps extends Omit<AriaCellProps, "className" | "style"> {
|
|
65
|
+
readonly className?: string;
|
|
66
|
+
readonly style?: CSSProperties;
|
|
67
|
+
}
|
|
68
|
+
export declare const TableCell: import("react").ForwardRefExoticComponent<TableCellProps & RefAttributes<HTMLDivElement | HTMLTableCellElement>>;
|
|
69
|
+
/** Structured rows and columns with optional selection and consumer-owned sorting. */
|
|
70
|
+
export declare const Table: import("react").ForwardRefExoticComponent<TableRootProps & RefAttributes<HTMLDivElement | HTMLTableElement>> & {
|
|
71
|
+
Header: TableHeaderComponent;
|
|
72
|
+
Column: import("react").ForwardRefExoticComponent<TableColumnProps & RefAttributes<HTMLDivElement | HTMLTableCellElement>>;
|
|
73
|
+
Body: TableBodyComponent;
|
|
74
|
+
Row: TableRowComponent;
|
|
75
|
+
Cell: import("react").ForwardRefExoticComponent<TableCellProps & RefAttributes<HTMLDivElement | HTMLTableCellElement>>;
|
|
76
|
+
};
|
|
77
|
+
export type TableProps = TableRootProps;
|
|
78
|
+
export {};
|