@phreshos/react-ui 0.1.35 → 0.1.37
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 +147 -167
- package/dist/accordion.d.ts +7 -6
- package/dist/accordion.js +5 -5
- package/dist/alert-dialog.js +3 -1
- package/dist/alert.d.ts +17 -0
- package/dist/alert.js +30 -0
- package/dist/app-layout.d.ts +13 -0
- package/dist/app-layout.js +84 -0
- package/dist/button.d.ts +12 -24
- package/dist/button.js +34 -39
- package/dist/calendar-layout.d.ts +9 -5
- package/dist/calendar-layout.js +67 -78
- package/dist/calendar-trigger.d.ts +4 -4
- package/dist/calendar-trigger.js +7 -29
- package/dist/calendar.d.ts +2 -2
- package/dist/calendar.js +6 -5
- package/dist/checkbox.d.ts +4 -4
- package/dist/checkbox.js +16 -6
- package/dist/color-area.d.ts +20 -0
- package/dist/color-area.js +30 -0
- package/dist/color-field.d.ts +17 -0
- package/dist/color-field.js +17 -0
- package/dist/color-picker.d.ts +24 -0
- package/dist/color-picker.js +30 -0
- package/dist/color-slider.d.ts +19 -0
- package/dist/color-slider.js +29 -0
- package/dist/color-swatch-picker.d.ts +23 -0
- package/dist/color-swatch-picker.js +36 -0
- package/dist/color-swatch.d.ts +18 -0
- package/dist/color-swatch.js +20 -0
- package/dist/combo-box.d.ts +18 -10
- package/dist/combo-box.js +43 -58
- package/dist/context-menu.d.ts +14 -10
- package/dist/context-menu.js +7 -6
- package/dist/control/color-thumb.d.ts +13 -0
- package/dist/control/color-thumb.js +33 -0
- package/dist/control/color-value.d.ts +6 -0
- package/dist/control/color-value.js +7 -0
- package/dist/control/control.d.ts +60 -0
- package/dist/control/control.js +71 -0
- package/dist/control/field-button.d.ts +13 -0
- package/dist/control/field-button.js +28 -0
- package/dist/control/field.d.ts +20 -0
- package/dist/control/field.js +34 -0
- package/dist/control/icon.d.ts +11 -0
- package/dist/control/icon.js +8 -0
- package/dist/control/item.d.ts +34 -0
- package/dist/control/item.js +53 -0
- package/dist/control/open-state.d.ts +25 -0
- package/dist/control/open-state.js +8 -0
- package/dist/control/selection-track.d.ts +39 -0
- package/dist/control/selection-track.js +122 -0
- package/dist/control/selection.d.ts +44 -0
- package/dist/{selection.js → control/selection.js} +16 -0
- package/dist/control/surface-render.d.ts +10 -0
- package/dist/control/surface-render.js +12 -0
- package/dist/control/text-control.d.ts +32 -0
- package/dist/control/text-control.js +31 -0
- package/dist/control/toggle.d.ts +32 -0
- package/dist/control/toggle.js +80 -0
- package/dist/date-control.d.ts +9 -9
- package/dist/date-control.js +31 -34
- package/dist/date-field.d.ts +7 -6
- package/dist/date-field.js +8 -6
- package/dist/date-picker.d.ts +13 -6
- package/dist/date-picker.js +9 -6
- package/dist/date-range-picker.d.ts +15 -6
- package/dist/date-range-picker.js +12 -9
- package/dist/dialog.d.ts +22 -8
- package/dist/dialog.js +37 -28
- package/dist/disclosure.d.ts +8 -7
- package/dist/disclosure.js +31 -52
- package/dist/drop-zone.d.ts +18 -0
- package/dist/drop-zone.js +32 -0
- package/dist/dropdown-menu.d.ts +7 -4
- package/dist/dropdown-menu.js +5 -4
- package/dist/fieldset.d.ts +13 -0
- package/dist/fieldset.js +26 -0
- package/dist/file-trigger.d.ts +13 -0
- package/dist/file-trigger.js +6 -0
- package/dist/flex.d.ts +1 -1
- package/dist/flex.js +5 -4
- package/dist/foundation/appearance.d.ts +83 -0
- package/dist/foundation/appearance.js +38 -0
- package/dist/{aria-direction.js → foundation/aria-direction.js} +3 -1
- package/dist/foundation/color.d.ts +61 -0
- package/dist/foundation/color.js +247 -0
- package/dist/{layout.d.ts → foundation/layout.d.ts} +6 -4
- package/dist/{layout.js → foundation/layout.js} +7 -5
- package/dist/foundation/motion-style.d.ts +9 -0
- package/dist/foundation/motion-style.js +50 -0
- package/dist/foundation/preferences.d.ts +15 -0
- package/dist/{ui-provider.d.ts → foundation/provider.d.ts} +3 -5
- package/dist/{ui-provider.js → foundation/provider.js} +14 -26
- package/dist/{radius.d.ts → foundation/radius.d.ts} +6 -3
- package/dist/foundation/radius.js +11 -0
- package/dist/foundation/spacing.d.ts +11 -0
- package/dist/foundation/spacing.js +4 -0
- package/dist/foundation/visual.d.ts +42 -0
- package/dist/{appearance-context.js → foundation/visual.js} +41 -27
- package/dist/grid.d.ts +1 -1
- package/dist/grid.js +5 -4
- package/dist/icons/main.d.ts +5 -3
- package/dist/icons/main.js +5 -3
- package/dist/input.d.ts +2 -2
- package/dist/input.js +9 -7
- package/dist/list-box.d.ts +24 -19
- package/dist/list-box.js +52 -109
- package/dist/main.d.ts +27 -16
- package/dist/main.js +22 -9
- package/dist/menu.d.ts +28 -32
- package/dist/menu.js +47 -93
- package/dist/number-field.d.ts +17 -0
- package/dist/number-field.js +28 -0
- package/dist/panel.d.ts +10 -5
- package/dist/panel.js +33 -12
- package/dist/popover.d.ts +19 -5
- package/dist/popover.js +22 -15
- package/dist/progress-bar.d.ts +8 -10
- package/dist/progress-bar.js +18 -34
- package/dist/radio.d.ts +15 -12
- package/dist/radio.js +27 -37
- package/dist/range-calendar.d.ts +5 -3
- package/dist/range-calendar.js +8 -7
- package/dist/scroll-area.d.ts +2 -2
- package/dist/scroll-area.js +10 -9
- package/dist/segmented-control.d.ts +23 -0
- package/dist/segmented-control.js +38 -0
- package/dist/select.d.ts +40 -13
- package/dist/select.js +63 -18
- package/dist/slider.d.ts +7 -3
- package/dist/slider.js +51 -50
- package/dist/spinner.d.ts +5 -8
- package/dist/spinner.js +12 -25
- package/dist/surface/grain.d.ts +12 -0
- package/dist/surface/grain.js +65 -0
- package/dist/{material-options.d.ts → surface/material-options.d.ts} +1 -2
- package/dist/{material-options.js → surface/material-options.js} +2 -2
- package/dist/surface/paint-class.d.ts +6 -0
- package/dist/surface/paint-class.js +36 -0
- package/dist/{shadow-options.d.ts → surface/shadow-options.d.ts} +13 -1
- package/dist/{shadow-options.js → surface/shadow-options.js} +17 -2
- package/dist/surface/surface.d.ts +73 -0
- package/dist/surface/surface.js +230 -0
- package/dist/switch.d.ts +4 -5
- package/dist/switch.js +17 -8
- package/dist/table.d.ts +29 -32
- package/dist/table.js +68 -106
- package/dist/tabs.d.ts +16 -15
- package/dist/tabs.js +44 -86
- package/dist/textarea.d.ts +2 -2
- package/dist/textarea.js +10 -14
- package/dist/time-field.d.ts +6 -6
- package/dist/time-field.js +8 -6
- package/dist/toolbar.d.ts +6 -4
- package/dist/toolbar.js +16 -15
- package/dist/tooltip.d.ts +13 -4
- package/dist/tooltip.js +17 -15
- package/dist/tree.d.ts +22 -27
- package/dist/tree.js +54 -99
- package/dist/window.d.ts +2 -2
- package/dist/window.js +18 -20
- package/package.json +3 -3
- package/dist/appearance-context.d.ts +0 -54
- package/dist/appearance.d.ts +0 -11
- package/dist/appearance.js +0 -11
- package/dist/color.d.ts +0 -69
- package/dist/color.js +0 -192
- package/dist/control-surface.d.ts +0 -20
- package/dist/control-surface.js +0 -11
- package/dist/control.d.ts +0 -70
- package/dist/control.js +0 -105
- package/dist/field-style.d.ts +0 -3
- package/dist/field-style.js +0 -12
- package/dist/material-paint.d.ts +0 -13
- package/dist/material-paint.js +0 -119
- package/dist/motion-style.d.ts +0 -13
- package/dist/motion-style.js +0 -75
- package/dist/preferences.d.ts +0 -12
- package/dist/radius.js +0 -11
- package/dist/readiness.d.ts +0 -37
- package/dist/readiness.js +0 -134
- package/dist/selection.d.ts +0 -18
- package/dist/spacing.d.ts +0 -8
- package/dist/spacing.js +0 -8
- package/dist/surface-edge.d.ts +0 -11
- package/dist/surface-edge.js +0 -55
- package/dist/surface.d.ts +0 -27
- package/dist/surface.js +0 -92
- package/dist/text-control.d.ts +0 -10
- package/dist/text-control.js +0 -0
- package/dist/toggle-indicator.d.ts +0 -18
- package/dist/toggle-indicator.js +0 -49
- /package/dist/{aria-direction.d.ts → foundation/aria-direction.d.ts} +0 -0
- /package/dist/{direction.d.ts → foundation/direction.d.ts} +0 -0
- /package/dist/{direction.js → foundation/direction.js} +0 -0
- /package/dist/{overlay-placement.d.ts → foundation/overlay-placement.d.ts} +0 -0
- /package/dist/{overlay-placement.js → foundation/overlay-placement.js} +0 -0
- /package/dist/{preferences.js → foundation/preferences.js} +0 -0
- /package/dist/{scale.d.ts → foundation/scale.d.ts} +0 -0
- /package/dist/{scale.js → foundation/scale.js} +0 -0
package/dist/radio.js
CHANGED
|
@@ -1,47 +1,37 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
|
+
import { Label, RadioButton, RadioField, RadioGroup as AriaRadioGroup, Text } from "react-aria-components";
|
|
4
|
+
import { controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { FieldFeedback, fieldStyle } from "./control/field.js";
|
|
6
|
+
import { ToggleIndicator, toggleRowStyle } from "./control/toggle.js";
|
|
7
|
+
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
8
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
9
|
+
import { dimmedClass } from "./surface/surface.js";
|
|
10
10
|
const RadioStyleContext = createContext(null);
|
|
11
|
-
/** One string value
|
|
12
|
-
const RadioGroupRoot = forwardRef(function
|
|
13
|
-
const
|
|
11
|
+
/** One string value chosen from its Items. */
|
|
12
|
+
const RadioGroupRoot = forwardRef(function RadioGroup({ label, description, errorMessage, children, disabled, readOnly, required, invalid, value, defaultValue, onChange, orientation = "vertical", size, color = "primary", style, className, material, ...properties }, ref) {
|
|
13
|
+
const metrics = useControlMetrics(size);
|
|
14
14
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const errorId = useId();
|
|
18
|
-
const describedBy = [ariaDescribedBy, description != null ? descriptionId : null, invalid && errorMessage != null ? errorId : null].filter(Boolean).join(" ") || undefined;
|
|
19
|
-
const root = _jsxs(BaseRadioGroup, { ...properties, ref: ref, className: className, value: value, defaultValue: defaultValue, onValueChange: next => {
|
|
20
|
-
if (next != null)
|
|
21
|
-
onChange?.(next);
|
|
22
|
-
}, disabled: disabled, readOnly: readOnly, required: required, "aria-invalid": invalid || undefined, "aria-labelledby": ariaLabelledBy ?? (label != null ? labelId : undefined), "aria-describedby": describedBy, style: fieldStyle(theme, disabled, style), children: [label != null && _jsx("div", { id: labelId, style: { fontWeight: controlFontWeight }, children: label }), _jsx(RadioStyleContext.Provider, { value: { size, color, disabled, invalid, readOnly, material, shadow }, children: _jsx("div", { style: { display: "flex", flexDirection: orientation === "vertical" ? "column" : "row", gap: theme.gap, flexWrap: "wrap" }, children: children }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description }), invalid && errorMessage != null && _jsx("span", { id: errorId, style: { fontSize: "0.92em", color: theme.danger }, children: errorMessage })] });
|
|
23
|
-
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
15
|
+
const context = useMemo(() => ({ color, direction, material, metrics }), [color, direction, material, metrics]);
|
|
16
|
+
return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsxs(AriaRadioGroup, { ...properties, ref: ref, dir: direction, className: dimmedClass(disabled ?? false, className), orientation: orientation, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), onChange: next => onChange?.(next), isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(metrics, style), children: [label != null && _jsx(Label, { style: { fontWeight: controlFontWeight }, children: label }), _jsx(RadioStyleContext.Provider, { value: context, children: _jsx("div", { style: { display: "flex", flexDirection: orientation === "vertical" ? "column" : "row", flexWrap: "wrap", gap: metrics.gap }, children: children }) }), _jsx(FieldFeedback, { metrics: metrics, description: description, errorMessage: errorMessage })] }) });
|
|
24
17
|
});
|
|
25
|
-
/**
|
|
26
|
-
const RadioGroupItem = forwardRef(function RadioGroupItem({ label, description,
|
|
18
|
+
/** One option in a RadioGroup. Selection, validation, and paint belong to the group. */
|
|
19
|
+
const RadioGroupItem = forwardRef(function RadioGroupItem({ label, description, disabled, className, style, ...properties }, ref) {
|
|
27
20
|
const inherited = useContext(RadioStyleContext);
|
|
28
21
|
if (inherited == null)
|
|
29
22
|
throw new Error("RadioGroup.Item must be used inside RadioGroup");
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
setFocusVisible(false);
|
|
41
|
-
onBlur?.(event);
|
|
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 })] });
|
|
23
|
+
const { color, direction, material, metrics } = inherited;
|
|
24
|
+
// Items inherit the group's text scale; only the group root applies it.
|
|
25
|
+
return _jsxs(RadioField, { ...properties, ref: ref, className: state => dimmedClass(state.isDisabled, className ?? state.defaultClassName) ?? "", isDisabled: disabled, style: { display: "grid", gap: 2, minWidth: 0, ...style }, children: [_jsx(RadioButton, { style: state => toggleRowStyle(metrics, state.isDisabled, state.isReadOnly), children: state => _jsxs(_Fragment, { children: [_jsx(ToggleIndicator, { kind: "radio", direction: direction, color: color, material: material, metrics: metrics, state: {
|
|
26
|
+
selected: state.isSelected,
|
|
27
|
+
hovered: !state.isReadOnly && state.isHovered,
|
|
28
|
+
pressed: !state.isReadOnly && state.isPressed,
|
|
29
|
+
focusVisible: state.isFocusVisible,
|
|
30
|
+
invalid: state.isInvalid,
|
|
31
|
+
disabled: state.isDisabled
|
|
32
|
+
} }), label] }) }), description != null && _jsx(Text, { slot: "description", style: { fontSize: "0.92em", opacity: controlOpacity.secondary, paddingInlineStart: metrics.indicator + metrics.gap }, children: description })] });
|
|
43
33
|
});
|
|
44
|
-
/** One exclusive-choice field whose
|
|
34
|
+
/** One exclusive-choice field whose options are its Items. */
|
|
45
35
|
export const RadioGroup = Object.assign(RadioGroupRoot, {
|
|
46
36
|
Item: RadioGroupItem
|
|
47
37
|
});
|
package/dist/range-calendar.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { CalendarDate } from "@internationalized/date";
|
|
2
2
|
import type { RangeCalendarProps as AriaRangeCalendarProps } from "react-aria-components";
|
|
3
|
-
import { type ControlOverrides, type ControlProps } from "./control.js";
|
|
3
|
+
import { type ControlOverrides, type ControlProps } from "./control/control.js";
|
|
4
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";
|
|
5
|
+
import type { RadiusProps } from "./foundation/radius.js";
|
|
6
|
+
type RangeCalendarOverrides = ControlOverrides | "children" | "isReadOnly" | "isInvalid" | "value" | "defaultValue" | "onChange" | "minValue" | "maxValue" | "isDateUnavailable" | "visibleDuration" | "createCalendar" | "errorMessage" | "validationState" | "allowsNonContiguousRanges";
|
|
7
7
|
export interface RangeCalendarProps extends Omit<AriaRangeCalendarProps<CalendarDate>, RangeCalendarOverrides>, ControlProps, RadiusProps {
|
|
8
8
|
readonly value?: DateRange | null;
|
|
9
9
|
readonly defaultValue?: DateRange | null;
|
|
@@ -11,6 +11,8 @@ export interface RangeCalendarProps extends Omit<AriaRangeCalendarProps<Calendar
|
|
|
11
11
|
readonly minValue?: CalendarDate | null;
|
|
12
12
|
readonly maxValue?: CalendarDate | null;
|
|
13
13
|
readonly isDateUnavailable?: (date: CalendarDate, anchorDate: CalendarDate | null) => boolean;
|
|
14
|
+
/** Whether a range may include unavailable dates. */
|
|
15
|
+
readonly nonContiguous?: boolean;
|
|
14
16
|
readonly readOnly?: boolean;
|
|
15
17
|
readonly invalid?: boolean;
|
|
16
18
|
}
|
package/dist/range-calendar.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { RangeCalendar as AriaRangeCalendar } from "react-aria-components";
|
|
4
|
-
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
4
|
+
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
5
5
|
import { CalendarLayout, calendarRootStyle } from "./calendar-layout.js";
|
|
6
|
-
import {
|
|
7
|
-
import { resolveDirection, useDirection } from "./direction.js";
|
|
6
|
+
import { useControlMetrics } from "./control/control.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
8
|
+
import { dimmedClass } from "./surface/surface.js";
|
|
8
9
|
/** 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
|
|
10
|
+
export const RangeCalendar = forwardRef(function RangeCalendar({ disabled, readOnly, invalid, size, color, radius, style, className, isDateUnavailable, nonContiguous, ...properties }, ref) {
|
|
11
|
+
const metrics = useControlMetrics(size, radius);
|
|
11
12
|
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
|
+
return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaRangeCalendar, { ...properties, ref: ref, dir: direction, className: dimmedClass(disabled ?? false, className), isDisabled: disabled, isReadOnly: readOnly, allowsNonContiguousRanges: nonContiguous, isInvalid: invalid, isDateUnavailable: isDateUnavailable == null
|
|
13
14
|
? undefined
|
|
14
|
-
: (date, anchorDate) => isDateUnavailable(date, anchorDate), style: calendarRootStyle(
|
|
15
|
+
: (date, anchorDate) => isDateUnavailable(date, anchorDate), style: calendarRootStyle(metrics, style), children: _jsx(CalendarLayout, { color: color ?? "primary", range: true, size: size, metrics: metrics }) }) });
|
|
15
16
|
});
|
package/dist/scroll-area.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ComponentPropsWithoutRef, Ref, ReactNode, UIEventHandler } from "react";
|
|
2
|
-
import type
|
|
2
|
+
import { type Color } from "./foundation/color.js";
|
|
3
3
|
export type ScrollAreaAxis = "vertical" | "horizontal" | "both";
|
|
4
4
|
export interface ScrollAreaProps extends Omit<ComponentPropsWithoutRef<"div">, "children" | "color" | "onScroll"> {
|
|
5
5
|
readonly axis?: ScrollAreaAxis;
|
|
6
6
|
readonly children?: ReactNode;
|
|
7
7
|
/** Base color from which scrollbar states are derived. */
|
|
8
|
-
readonly color?:
|
|
8
|
+
readonly color?: Color;
|
|
9
9
|
readonly onScroll?: UIEventHandler<HTMLDivElement>;
|
|
10
10
|
readonly viewportRef?: Ref<HTMLDivElement>;
|
|
11
11
|
}
|
package/dist/scroll-area.js
CHANGED
|
@@ -2,22 +2,23 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
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
|
-
import {
|
|
6
|
-
import { colorOpacity, resolveColor } from "./color.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import { transition as timing } from "./control/control.js";
|
|
6
|
+
import { colorOpacity, resolveColor } from "./foundation/color.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
8
|
+
import { useVisual } from "./foundation/visual.js";
|
|
9
9
|
/** A native scrolling viewport with locally owned React UI scrollbars. */
|
|
10
10
|
export const ScrollArea = forwardRef(function ScrollArea({ axis = "vertical", children, color, onScroll, style, viewportRef, ...properties }, ref) {
|
|
11
|
-
const
|
|
12
|
-
const { appearance } =
|
|
11
|
+
const visual = useVisual();
|
|
12
|
+
const { appearance } = visual;
|
|
13
13
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
14
|
-
const foreground = resolveColor(color ?? "foreground
|
|
15
|
-
|
|
14
|
+
const foreground = resolveColor(color ?? "foreground", visual.colors);
|
|
15
|
+
// A scrollbar thumb is a pill at any thickness.
|
|
16
|
+
const radius = 9999;
|
|
16
17
|
const thickness = Math.max(8, appearance.spacing);
|
|
17
18
|
const inset = Math.max(2, thickness / 3);
|
|
18
19
|
const vertical = axis === "vertical" || axis === "both";
|
|
19
20
|
const horizontal = axis === "horizontal" || axis === "both";
|
|
20
|
-
const transition =
|
|
21
|
+
const transition = timing(visual, "opacity");
|
|
21
22
|
const root = _jsxs(BaseScrollArea.Root, { ...properties, "data-phreshos-scroll-area": "", ref: ref, style: {
|
|
22
23
|
...style,
|
|
23
24
|
display: "flex",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { ToggleButtonGroupProps as AriaToggleButtonGroupProps, ToggleButtonProps as AriaToggleButtonProps } from "react-aria-components";
|
|
3
|
+
import { type ControlProps, type FieldProps } from "./control/control.js";
|
|
4
|
+
import type { RadiusProps } from "./foundation/radius.js";
|
|
5
|
+
import type { MaterialOverrides } from "./surface/material-options.js";
|
|
6
|
+
export interface SegmentedControlProps extends Omit<AriaToggleButtonGroupProps, "selectionMode" | "selectedKeys" | "defaultSelectedKeys" | "onSelectionChange" | "disallowEmptySelection" | "isDisabled" | "children" | "className" | "style">, ControlProps, Pick<FieldProps, "label" | "description">, RadiusProps, MaterialOverrides {
|
|
7
|
+
readonly children: ReactNode;
|
|
8
|
+
/** The selected Item's id. */
|
|
9
|
+
readonly value?: string;
|
|
10
|
+
readonly defaultValue?: string;
|
|
11
|
+
readonly onChange?: (value: string) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface SegmentedControlItemProps extends Omit<AriaToggleButtonProps, "id" | "isDisabled" | "className" | "style" | "children"> {
|
|
14
|
+
/** Identity of this Item; it is the value it selects. */
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly children: ReactNode;
|
|
17
|
+
readonly disabled?: boolean;
|
|
18
|
+
readonly className?: string;
|
|
19
|
+
readonly style?: CSSProperties;
|
|
20
|
+
}
|
|
21
|
+
export declare const SegmentedControl: import("react").ForwardRefExoticComponent<SegmentedControlProps & import("react").RefAttributes<HTMLDivElement>> & {
|
|
22
|
+
Item: import("react").ForwardRefExoticComponent<SegmentedControlItemProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext, useId, useMemo } from "react";
|
|
3
|
+
import { ToggleButton as AriaToggleButton, ToggleButtonGroup as AriaToggleButtonGroup } from "react-aria-components";
|
|
4
|
+
import { controlFontWeight, controlOpacity, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { fieldStyle } from "./control/field.js";
|
|
6
|
+
import { SelectionItemLabel, selectionItemStyle, selectionListStyle, SelectionTrack } from "./control/selection-track.js";
|
|
7
|
+
import { stringKey } from "./control/selection.js";
|
|
8
|
+
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
9
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
10
|
+
import { dimmedClass } from "./surface/surface.js";
|
|
11
|
+
const SegmentedStyleContext = createContext(null);
|
|
12
|
+
/**
|
|
13
|
+
* One value chosen from a few options that stay visible. It shares the Tabs
|
|
14
|
+
* track: the selection slides to the chosen Item. Use it where Tabs would
|
|
15
|
+
* switch views, but the choice is a value instead.
|
|
16
|
+
*/
|
|
17
|
+
const SegmentedControlRoot = forwardRef(function SegmentedControl({ label, description, children, value, defaultValue, onChange, disabled, size, color = "default", radius, material, orientation = "horizontal", className, style, ...properties }, ref) {
|
|
18
|
+
const metrics = useControlMetrics(size, radius);
|
|
19
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
20
|
+
const context = useMemo(() => ({ color, metrics, orientation }), [color, metrics, orientation]);
|
|
21
|
+
const labelId = useId();
|
|
22
|
+
const descriptionId = useId();
|
|
23
|
+
const selected = value ?? defaultValue;
|
|
24
|
+
return _jsx(AriaDirectionBoundary, { direction: direction, children: _jsxs("div", { className: dimmedClass(disabled ?? false, className), style: fieldStyle(metrics, style), children: [label != null && _jsx("span", { id: labelId, style: { fontWeight: controlFontWeight }, children: label }), _jsx(SegmentedStyleContext.Provider, { value: context, children: _jsx(SelectionTrack, { metrics: metrics, color: color, material: material, orientation: orientation, selectedKey: selected, children: _jsx(AriaToggleButtonGroup, { ...properties, ref: ref, dir: direction, "data-selection-list": "", "aria-labelledby": properties["aria-labelledby"] ?? (label != null ? labelId : undefined), "aria-describedby": properties["aria-describedby"] ?? (description != null ? descriptionId : undefined), orientation: orientation, selectionMode: "single", disallowEmptySelection: true, ...(value !== undefined ? { selectedKeys: [value] } : {}), ...(defaultValue !== undefined ? { defaultSelectedKeys: [defaultValue] } : {}), onSelectionChange: keys => {
|
|
25
|
+
const [key] = keys;
|
|
26
|
+
if (key !== undefined)
|
|
27
|
+
onChange?.(stringKey(key));
|
|
28
|
+
}, isDisabled: disabled, style: selectionListStyle(orientation), children: children }) }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description })] }) });
|
|
29
|
+
});
|
|
30
|
+
/** One option; its label may lead with an icon. */
|
|
31
|
+
const SegmentedControlItem = forwardRef(function SegmentedControlItem({ children, disabled, className, style, ...properties }, ref) {
|
|
32
|
+
const inherited = useContext(SegmentedStyleContext);
|
|
33
|
+
if (inherited == null)
|
|
34
|
+
throw new Error("SegmentedControl.Item must be used inside SegmentedControl");
|
|
35
|
+
const { color, metrics, orientation } = inherited;
|
|
36
|
+
return _jsx(AriaToggleButton, { ...properties, ref: ref, isDisabled: disabled, className: state => dimmedClass(state.isDisabled, className ?? state.defaultClassName) ?? "", style: state => ({ ...selectionItemStyle(metrics, color, orientation, state), ...style }), children: state => _jsx(SelectionItemLabel, { metrics: metrics, emphasized: state.isSelected || state.isHovered, children: children }) });
|
|
37
|
+
});
|
|
38
|
+
export const SegmentedControl = Object.assign(SegmentedControlRoot, { Item: SegmentedControlItem });
|
package/dist/select.d.ts
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
1
2
|
import type { SelectProps as AriaSelectProps } from "react-aria-components";
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
4
|
-
import type
|
|
5
|
-
import type {
|
|
6
|
-
export interface
|
|
7
|
-
|
|
8
|
-
readonly
|
|
9
|
-
readonly disabled?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface SelectProps extends Omit<AriaSelectProps<SelectOption>, ControlOverrides | "value" | "defaultValue" | "onChange" | "selectedKey" | "defaultSelectedKey" | "onSelectionChange" | "disabledKeys" | "selectionMode">, ControlProps, FieldProps, RadiusProps, MaterialOverrides, ShadowOverrides {
|
|
12
|
-
readonly options: readonly SelectOption[];
|
|
3
|
+
import { type ControlMetrics, type ControlOverrides, type ControlProps, type FieldProps } from "./control/control.js";
|
|
4
|
+
import { type RadiusProps } from "./foundation/radius.js";
|
|
5
|
+
import { type OpenStateProps } from "./control/open-state.js";
|
|
6
|
+
import type { MaterialOverrides } from "./surface/material-options.js";
|
|
7
|
+
export interface SelectProps extends Omit<AriaSelectProps<object>, ControlOverrides | "value" | "defaultValue" | "onChange" | "selectedKey" | "defaultSelectedKey" | "onSelectionChange" | "disabledKeys" | "selectionMode" | "isOpen" | "defaultOpen" | "onOpenChange" | "shouldCloseOnSelect" | "allowsEmptyCollection">, ControlProps, FieldProps, RadiusProps, MaterialOverrides, OpenStateProps {
|
|
8
|
+
/** `Select.Item` and `Select.Section` entries. */
|
|
9
|
+
readonly children: ReactNode;
|
|
13
10
|
readonly value?: string | null;
|
|
14
11
|
readonly defaultValue?: string | null;
|
|
15
12
|
readonly onChange?: (value: string | null) => void;
|
|
13
|
+
/** Whether the list can open while it has no Items. */
|
|
14
|
+
readonly openWhenEmpty?: boolean;
|
|
16
15
|
}
|
|
17
|
-
/**
|
|
18
|
-
export declare
|
|
16
|
+
/** Layout of a pressable field trigger shared by Select and ComboBox. */
|
|
17
|
+
export declare function fieldTriggerStyle(metrics: ControlMetrics, disabled?: boolean): {
|
|
18
|
+
readonly appearance: "none";
|
|
19
|
+
readonly boxSizing: "border-box";
|
|
20
|
+
readonly display: "flex";
|
|
21
|
+
readonly alignItems: "center";
|
|
22
|
+
readonly justifyContent: "space-between";
|
|
23
|
+
readonly gap: number;
|
|
24
|
+
readonly width: "100%";
|
|
25
|
+
readonly minWidth: 0;
|
|
26
|
+
readonly height: number;
|
|
27
|
+
readonly paddingInline: number;
|
|
28
|
+
readonly border: 0;
|
|
29
|
+
readonly background: "none";
|
|
30
|
+
readonly font: "inherit";
|
|
31
|
+
readonly lineHeight: 1.45;
|
|
32
|
+
readonly textAlign: "start";
|
|
33
|
+
readonly cursor: "not-allowed" | "pointer";
|
|
34
|
+
};
|
|
35
|
+
/** The disclosure chevron shared by every field that opens a list. */
|
|
36
|
+
export declare function Chevron({ metrics, open }: Readonly<{
|
|
37
|
+
metrics: ControlMetrics;
|
|
38
|
+
open: boolean;
|
|
39
|
+
}>): import("react").JSX.Element;
|
|
40
|
+
/** A single-choice field whose options are its Items. */
|
|
41
|
+
export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLDivElement>> & {
|
|
42
|
+
Item: import("./list-box.js").ListBoxItemComponent;
|
|
43
|
+
Section: import("./list-box.js").ListBoxSectionComponent;
|
|
44
|
+
Header: import("react").ForwardRefExoticComponent<import("react-aria-components").HeaderProps & import("react").RefAttributes<HTMLElement>>;
|
|
45
|
+
};
|
package/dist/select.js
CHANGED
|
@@ -1,26 +1,71 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef
|
|
3
|
-
import { Select as AriaSelect,
|
|
4
|
-
import { controlOpacity,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Button as AriaButton, Select as AriaSelect, SelectValue } from "react-aria-components";
|
|
4
|
+
import { controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { FieldFeedback, FieldLabel, fieldStyle } from "./control/field.js";
|
|
6
|
+
import { surfaceRender } from "./control/surface-render.js";
|
|
7
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
8
|
+
import { resolveRadius } from "./foundation/radius.js";
|
|
9
9
|
import { ListBox } from "./list-box.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { ariaOpenState } from "./control/open-state.js";
|
|
11
|
+
import { PopoverContent } from "./popover.js";
|
|
12
|
+
import { ScrollArea } from "./scroll-area.js";
|
|
13
|
+
import { dimmedClass } from "./surface/surface.js";
|
|
14
|
+
import { ChevronDown } from "lucide-react";
|
|
15
|
+
import { iconProps } from "./control/icon.js";
|
|
16
|
+
/** One value chosen from its Items; the field recesses like every value holder. */
|
|
17
|
+
const SelectRoot = forwardRef(function Select({ label, description, errorMessage, disabled, required, className, invalid, children, value, defaultValue, onChange, size, color = "background", radius, style, material, open, defaultOpen, onOpenChange, openWhenEmpty, ...properties }, ref) {
|
|
18
|
+
const metrics = useControlMetrics(size, radius);
|
|
19
|
+
// The list shell keeps the Appearance radius at the chosen level.
|
|
20
|
+
const shell = resolveRadius(radius ?? "medium", metrics.visual.radius);
|
|
13
21
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
return _jsx(AriaSelect, { ...properties, ref: ref, ...ariaOpenState({ open, defaultOpen, onOpenChange }), allowsEmptyCollection: openWhenEmpty, ...(value !== undefined ? { value } : {}), ...(defaultValue !== undefined ? { defaultValue } : {}), onChange: key => onChange?.(key == null ? null : String(key)), className: dimmedClass(disabled ?? false, className), isDisabled: disabled, isRequired: required, isInvalid: invalid, style: fieldStyle(metrics, style), children: state => _jsxs(_Fragment, { children: [_jsx(FieldLabel, { label: label }), _jsxs(AriaButton, { render: surfaceRender("button", button => ({
|
|
23
|
+
color,
|
|
24
|
+
depth: "recessed",
|
|
25
|
+
material,
|
|
26
|
+
radius: metrics.radius,
|
|
27
|
+
interaction: {
|
|
28
|
+
hovered: button.isHovered,
|
|
29
|
+
focusVisible: state.isOpen || button.isFocusVisible,
|
|
30
|
+
invalid: state.isInvalid,
|
|
31
|
+
disabled: button.isDisabled
|
|
32
|
+
}
|
|
33
|
+
})), style: fieldTriggerStyle(metrics, disabled), children: [_jsx(SelectValue, { style: ({ isPlaceholder }) => ({ minWidth: 0, opacity: isPlaceholder ? controlOpacity.placeholder : 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }), children: ({ isPlaceholder, selectedText, defaultChildren }) => isPlaceholder ? defaultChildren : selectedText }), _jsx(Chevron, { metrics: metrics, open: state.isOpen })] }), _jsx(PopoverContent, { dir: direction, placement: "bottom start", offset: metrics.gap, radius: shell, style: {
|
|
20
34
|
width: "var(--trigger-width)",
|
|
21
|
-
maxHeight: `min(calc(100vh - ${
|
|
35
|
+
maxHeight: `min(calc(100vh - ${metrics.spacing * 2}px), ${metrics.height * 8}px)`,
|
|
22
36
|
padding: 0,
|
|
23
37
|
display: "flex",
|
|
24
38
|
flexDirection: "column"
|
|
25
|
-
}, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, {
|
|
39
|
+
}, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { size: size, children: children }) }) }), _jsx(FieldFeedback, { metrics: metrics, description: description, errorMessage: errorMessage })] }) });
|
|
40
|
+
});
|
|
41
|
+
/** Layout of a pressable field trigger shared by Select and ComboBox. */
|
|
42
|
+
export function fieldTriggerStyle(metrics, disabled) {
|
|
43
|
+
return {
|
|
44
|
+
appearance: "none",
|
|
45
|
+
boxSizing: "border-box",
|
|
46
|
+
display: "flex",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
justifyContent: "space-between",
|
|
49
|
+
gap: metrics.gap,
|
|
50
|
+
width: "100%",
|
|
51
|
+
minWidth: 0,
|
|
52
|
+
height: metrics.height,
|
|
53
|
+
paddingInline: metrics.inset,
|
|
54
|
+
border: 0,
|
|
55
|
+
background: "none",
|
|
56
|
+
font: "inherit",
|
|
57
|
+
lineHeight: 1.45,
|
|
58
|
+
textAlign: "start",
|
|
59
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** The disclosure chevron shared by every field that opens a list. */
|
|
63
|
+
export function Chevron({ metrics, open }) {
|
|
64
|
+
return _jsx(ChevronDown, { ...iconProps(14), style: { ...transition(metrics.visual, "rotate"), flexShrink: 0, opacity: controlOpacity.secondary, rotate: open ? "180deg" : "0deg" } });
|
|
65
|
+
}
|
|
66
|
+
/** A single-choice field whose options are its Items. */
|
|
67
|
+
export const Select = Object.assign(SelectRoot, {
|
|
68
|
+
Item: ListBox.Item,
|
|
69
|
+
Section: ListBox.Section,
|
|
70
|
+
Header: ListBox.Header
|
|
26
71
|
});
|
package/dist/slider.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HTMLAttributes } from "react";
|
|
2
|
-
import type
|
|
3
|
-
|
|
2
|
+
import { type ControlProps, type FieldProps } from "./control/control.js";
|
|
3
|
+
import type { MaterialOverrides } from "./surface/material-options.js";
|
|
4
|
+
export interface SliderProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "className" | "color" | "defaultValue" | "onChange" | "style">, ControlProps, MaterialOverrides, Pick<FieldProps, "label" | "description"> {
|
|
4
5
|
readonly value?: number;
|
|
5
6
|
readonly defaultValue?: number;
|
|
6
7
|
readonly minValue?: number;
|
|
@@ -13,5 +14,8 @@ export interface SliderProps extends Omit<HTMLAttributes<HTMLDivElement>, "child
|
|
|
13
14
|
readonly onChange?: (value: number) => void;
|
|
14
15
|
readonly onChangeEnd?: (value: number) => void;
|
|
15
16
|
}
|
|
16
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* One numeric value, drawn as a long Switch: a recessed bed, a raised fill in
|
|
19
|
+
* the owner's color up to the thumb, and the Switch thumb dragged along it.
|
|
20
|
+
*/
|
|
17
21
|
export declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLDivElement>>;
|
package/dist/slider.js
CHANGED
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// Base UI accepts direction
|
|
2
|
+
// Base UI accepts an explicit direction; React Aria derives slider geometry
|
|
3
|
+
// from the locale, which cannot follow a React UI direction boundary.
|
|
3
4
|
import { Slider as BaseSlider } from "@base-ui/react/slider";
|
|
4
5
|
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
5
6
|
import { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
6
|
-
import { controlFontWeight, controlOpacity,
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
import { controlFontWeight, controlOpacity, transition, useControlMetrics } from "./control/control.js";
|
|
8
|
+
import { fieldStyle } from "./control/field.js";
|
|
9
|
+
import { lightColor } from "./foundation/color.js";
|
|
10
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
11
|
+
import { SurfaceView, dimmedClass } from "./surface/surface.js";
|
|
12
|
+
/**
|
|
13
|
+
* One numeric value, drawn as a long Switch: a recessed bed, a raised fill in
|
|
14
|
+
* the owner's color up to the thumb, and the Switch thumb dragged along it.
|
|
15
|
+
*/
|
|
16
|
+
export const Slider = forwardRef(function Slider({ label, description, name, form, disabled, size, color = "primary", style, className, orientation = "horizontal", value, defaultValue, minValue = 0, maxValue = 100, step = 1, formatOptions, onChange, onChangeEnd, material, ...properties }, ref) {
|
|
17
|
+
const metrics = useControlMetrics(size);
|
|
18
|
+
const { colors } = metrics.visual;
|
|
11
19
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
12
20
|
const descriptionId = useId();
|
|
13
21
|
const input = useRef(null);
|
|
14
22
|
const initialValue = useRef(defaultValue ?? minValue);
|
|
15
23
|
const [uncontrolledValue, setUncontrolledValue] = useState(initialValue.current);
|
|
16
|
-
const [hovered, setHovered] = useState(false);
|
|
17
24
|
const vertical = orientation === "vertical";
|
|
18
|
-
|
|
19
|
-
const
|
|
25
|
+
// The Switch's proportions: its bed height, and a thumb inset by the same gap.
|
|
26
|
+
const bed = metrics.indicator;
|
|
27
|
+
const inset = 3;
|
|
28
|
+
const thumb = bed - inset * 2;
|
|
20
29
|
const describedBy = [properties["aria-describedby"], description != null ? descriptionId : null].filter(Boolean).join(" ") || undefined;
|
|
21
30
|
const controlled = value !== undefined;
|
|
22
|
-
const resolvedValue = controlled ? value : uncontrolledValue;
|
|
23
31
|
useEffect(() => {
|
|
24
32
|
const formElement = input.current?.form;
|
|
25
33
|
if (controlled || formElement == null)
|
|
@@ -28,44 +36,37 @@ export const Slider = forwardRef(function Slider({ label, description, name, for
|
|
|
28
36
|
formElement.addEventListener("reset", reset);
|
|
29
37
|
return () => formElement.removeEventListener("reset", reset);
|
|
30
38
|
}, [controlled]);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
outline: state.focused ? `1px solid ${theme.focusColor}` : "none",
|
|
65
|
-
outlineOffset: 1,
|
|
66
|
-
cursor: state.disabled ? "not-allowed" : state.dragging ? "grabbing" : "grab",
|
|
67
|
-
transform: `scale(${state.dragging ? 0.92 : hovered ? 1.08 : 1})`
|
|
68
|
-
};
|
|
69
|
-
} })] }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description })] });
|
|
70
|
-
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
39
|
+
return _jsx(BaseDirectionProvider, { direction: direction, children: _jsxs(BaseSlider.Root, { ...properties, ref: ref, className: dimmedClass(disabled ?? false, className), value: controlled ? value : uncontrolledValue, min: minValue, max: maxValue, step: step, name: name, form: form, disabled: disabled, orientation: orientation, format: formatOptions, onValueChange: next => {
|
|
40
|
+
if (!controlled)
|
|
41
|
+
setUncontrolledValue(next);
|
|
42
|
+
onChange?.(next);
|
|
43
|
+
}, onValueCommitted: next => onChangeEnd?.(next), style: fieldStyle(metrics, style), children: [_jsxs("div", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: metrics.gap }, children: [label != null && _jsx(BaseSlider.Label, { style: { fontWeight: controlFontWeight }, children: label }), _jsx(BaseSlider.Value, { style: { fontVariantNumeric: "tabular-nums", opacity: controlOpacity.secondary } })] }), _jsx(SurfaceView, { as: "div", color: "background", depth: "recessed", material: material, radius: "full", style: {
|
|
44
|
+
display: "flex",
|
|
45
|
+
boxSizing: "border-box",
|
|
46
|
+
// The thumb center travels between the bed ends minus half a thumb,
|
|
47
|
+
// so the thumb keeps the Switch inset at both ends.
|
|
48
|
+
paddingBlock: vertical ? inset + thumb / 2 : inset,
|
|
49
|
+
paddingInline: vertical ? inset : inset + thumb / 2,
|
|
50
|
+
width: vertical ? bed : "100%",
|
|
51
|
+
height: vertical ? metrics.height * 4 : bed
|
|
52
|
+
}, children: _jsx(BaseSlider.Control, { style: { position: "relative", flex: 1, touchAction: "none", userSelect: "none" }, children: _jsxs(BaseSlider.Track, { style: { position: "relative", width: "100%", height: "100%" }, children: [_jsx(BaseSlider.Indicator, { render: (fill, _state) => _jsx(SurfaceView, { ...fill, ref: fill.ref, as: "div", color: color, material: material, shadow: false, radius: "full", style: {
|
|
53
|
+
...fill.style,
|
|
54
|
+
position: "absolute",
|
|
55
|
+
boxSizing: "content-box",
|
|
56
|
+
// The fill starts at the bed's end and wraps the thumb with the
|
|
57
|
+
// bed's inset, like an enabled Switch.
|
|
58
|
+
...(vertical
|
|
59
|
+
? { insetInlineStart: -inset, width: bed, marginBottom: -(inset + thumb / 2), paddingTop: thumb + inset * 2 }
|
|
60
|
+
: { top: -inset, height: bed, marginInlineStart: -(inset + thumb / 2), paddingInlineEnd: thumb + inset * 2 })
|
|
61
|
+
} }) }), _jsx(BaseSlider.Thumb, { inputRef: input, "aria-label": properties["aria-label"], "aria-labelledby": properties["aria-labelledby"], "aria-describedby": describedBy, render: (native, state) => _jsx(SurfaceView, { ...native, ref: native.ref, as: "div",
|
|
62
|
+
// A thumb is lit from above in every Theme.
|
|
63
|
+
color: lightColor(colors), radius: "full", interaction: { hovered: false, pressed: state.dragging, focusVisible: state.focused, disabled: state.disabled }, style: {
|
|
64
|
+
...native.style,
|
|
65
|
+
...transition(metrics.visual, "scale, outline-color, box-shadow"),
|
|
66
|
+
zIndex: 2,
|
|
67
|
+
width: thumb,
|
|
68
|
+
height: thumb,
|
|
69
|
+
cursor: state.disabled ? "not-allowed" : state.dragging ? "grabbing" : "grab",
|
|
70
|
+
scale: state.dragging ? "0.92" : "1"
|
|
71
|
+
} }) })] }) }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: controlOpacity.secondary }, children: description })] }) });
|
|
71
72
|
});
|
package/dist/spinner.d.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import type { CSSProperties } from "react";
|
|
2
2
|
import type { ProgressBarProps as AriaProgressBarProps } from "react-aria-components";
|
|
3
|
-
import type
|
|
4
|
-
import { type ScaleLevel } from "./scale.js";
|
|
3
|
+
import { type Color } from "./foundation/color.js";
|
|
4
|
+
import { type ScaleLevel } from "./foundation/scale.js";
|
|
5
5
|
type NativeSpinnerProps = Omit<AriaProgressBarProps, "aria-hidden" | "aria-label" | "aria-labelledby" | "children" | "className" | "formatOptions" | "isIndeterminate" | "maxValue" | "minValue" | "slot" | "style" | "value" | "valueLabel">;
|
|
6
6
|
interface SpinnerVisualProps extends NativeSpinnerProps {
|
|
7
|
-
/** Native class name applied without replacing the component contract. */
|
|
8
7
|
readonly className?: string;
|
|
9
|
-
/** Color of the moving
|
|
10
|
-
readonly color?:
|
|
11
|
-
/** Derives the indicator diameter from Appearance. */
|
|
8
|
+
/** Color of the moving arc. `currentColor` follows the surrounding content. */
|
|
9
|
+
readonly color?: Color;
|
|
12
10
|
readonly size?: ScaleLevel;
|
|
13
|
-
/** Native styles applied after Spinner defaults. */
|
|
14
11
|
readonly style?: CSSProperties;
|
|
15
12
|
}
|
|
16
13
|
type NamedSpinnerProps = Readonly<{
|
|
17
|
-
/** Accessible
|
|
14
|
+
/** Accessible name announced with indeterminate progress semantics. */
|
|
18
15
|
label: string;
|
|
19
16
|
decorative?: false;
|
|
20
17
|
}>;
|