@phreshos/react-ui 0.1.25 → 0.1.26
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 +74 -23
- package/dist/alert-dialog.d.ts +23 -0
- package/dist/alert-dialog.js +25 -0
- package/dist/button.d.ts +2 -1
- package/dist/button.js +2 -2
- package/dist/checkbox.d.ts +2 -1
- package/dist/checkbox.js +2 -2
- package/dist/color.js +1 -1
- package/dist/context-menu.d.ts +21 -0
- package/dist/context-menu.js +18 -0
- package/dist/control-surface.d.ts +6 -7
- package/dist/control-surface.js +4 -4
- package/dist/control.js +1 -1
- package/dist/dialog.d.ts +46 -0
- package/dist/dialog.js +91 -0
- package/dist/direction.d.ts +9 -0
- package/dist/direction.js +31 -0
- package/dist/dropdown-menu.d.ts +21 -0
- package/dist/dropdown-menu.js +19 -0
- package/dist/flex.js +1 -1
- package/dist/grid.js +1 -1
- package/dist/input.js +2 -2
- package/dist/main.d.ts +11 -3
- package/dist/main.js +9 -2
- package/dist/material-options.d.ts +2 -1
- package/dist/material-options.js +1 -1
- package/dist/menu.d.ts +35 -0
- package/dist/menu.js +85 -0
- package/dist/motion-style.d.ts +1 -0
- package/dist/motion-style.js +15 -7
- package/dist/overlay-placement.d.ts +4 -0
- package/dist/overlay-placement.js +6 -0
- package/dist/panel.d.ts +17 -8
- package/dist/panel.js +36 -21
- package/dist/popover.d.ts +30 -0
- package/dist/popover.js +46 -0
- package/dist/radio.d.ts +14 -7
- package/dist/radio.js +36 -11
- package/dist/radius.d.ts +2 -2
- package/dist/radius.js +3 -1
- package/dist/scroll-area.js +6 -2
- package/dist/select.d.ts +2 -1
- package/dist/select.js +21 -3
- package/dist/shadow-options.d.ts +25 -0
- package/dist/shadow-options.js +25 -0
- package/dist/slider.d.ts +13 -3
- package/dist/slider.js +62 -30
- package/dist/spacing.js +1 -1
- package/dist/surface-edge.d.ts +0 -1
- package/dist/surface-edge.js +46 -49
- package/dist/surface.d.ts +5 -1
- package/dist/surface.js +11 -6
- package/dist/switch.d.ts +2 -1
- package/dist/switch.js +4 -2
- package/dist/text-control.d.ts +2 -1
- package/dist/textarea.js +2 -2
- package/dist/toggle-indicator.d.ts +6 -4
- package/dist/toggle-indicator.js +3 -5
- package/dist/tooltip.d.ts +21 -0
- package/dist/tooltip.js +38 -0
- package/dist/ui-provider.d.ts +14 -0
- package/dist/ui-provider.js +18 -0
- package/package.json +1 -1
- package/dist/appearance-provider.d.ts +0 -10
- package/dist/appearance-provider.js +0 -13
package/dist/input.js
CHANGED
|
@@ -5,7 +5,7 @@ import { controlPaint, controlStyle, FieldFeedback, FieldLabel, fieldStyle, useC
|
|
|
5
5
|
import { SurfaceField } from "./control-surface.js";
|
|
6
6
|
import FieldStyle, { textControlClass } from "./field-style.js";
|
|
7
7
|
/** A labeled single-line text control. onChange receives the string value. */
|
|
8
|
-
export const Input = forwardRef(function Input({ label, description, errorMessage, disabled, readOnly, required, invalid, size, color, radius, style, className, placeholder, material, ...properties }, ref) {
|
|
8
|
+
export const Input = forwardRef(function Input({ label, description, errorMessage, disabled, readOnly, required, invalid, size, color, radius, style, className, placeholder, material, shadow, ...properties }, ref) {
|
|
9
9
|
const theme = useControlTheme({ size, color, radius });
|
|
10
|
-
return _jsxs(TextField, { ...properties, className: className, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(theme, disabled, style), children: [_jsx(FieldStyle, {}), _jsx(FieldLabel, { label: label }), _jsx(AriaInput, { ref: ref, placeholder: placeholder, className: textControlClass, render: (native, state) => _jsx(SurfaceField, { material: material, radius: theme.radius, paint: controlPaint(theme, state.isFocused, state.isInvalid, state.isHovered), children: _jsx("input", { ...native, style: { ...native.style, borderRadius: "inherit", background: "transparent" } }) }), style: state => controlStyle(theme, state.isFocused, state.isInvalid, state.isHovered, state.isFocusVisible) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] });
|
|
10
|
+
return _jsxs(TextField, { ...properties, className: className, isDisabled: disabled, isReadOnly: readOnly, isRequired: required, isInvalid: invalid, style: fieldStyle(theme, disabled, style), children: [_jsx(FieldStyle, {}), _jsx(FieldLabel, { label: label }), _jsx(AriaInput, { ref: ref, placeholder: placeholder, className: textControlClass, render: (native, state) => _jsx(SurfaceField, { material: material, shadow: shadow, radius: theme.radius, paint: controlPaint(theme, state.isFocused, state.isInvalid, state.isHovered), children: _jsx("input", { ...native, style: { ...native.style, borderRadius: "inherit", background: "transparent" } }) }), style: state => controlStyle(theme, state.isFocused, state.isInvalid, state.isHovered, state.isFocusVisible) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] });
|
|
11
11
|
});
|
package/dist/main.d.ts
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
* behavior contract has been established by the package's tests.
|
|
6
6
|
*/
|
|
7
7
|
export { defaultAppearance } from "@phreshos/core";
|
|
8
|
-
export {
|
|
8
|
+
export { UIProvider, useAppearance, useBrowserPreferences, useDirection, useDocumentDirection, usePreferences, useThemedValue, type UIProviderProps } from "./ui-provider.js";
|
|
9
9
|
export type { DesktopPreferences as Preferences } from "@phreshos/core";
|
|
10
|
+
export type { Direction } from "./direction.js";
|
|
10
11
|
export { Flex, type FlexProps } from "./flex.js";
|
|
11
12
|
export { Grid, type GridProps } from "./grid.js";
|
|
12
|
-
export { Surface, type MaterialOptions, type SurfaceComponent, type SurfaceHost, type SurfaceHostProps, type SurfaceOwnProps, type SurfaceProps } from "./surface.js";
|
|
13
|
+
export { Surface, type MaterialOptions, type ShadowOptions, type SurfaceComponent, type SurfaceHost, type SurfaceHostProps, type SurfaceOwnProps, type SurfaceProps } from "./surface.js";
|
|
13
14
|
export { defaultColor, type Color, type ColorLevel, type ColorScale } from "./color.js";
|
|
14
|
-
export { Panel, type PanelProps } from "./panel.js";
|
|
15
|
+
export { Panel, PanelRoot, PanelHeader, PanelContent, type PanelProps, type PanelRootProps, type PanelHeaderProps, type PanelContentProps } from "./panel.js";
|
|
15
16
|
export { Button, type ButtonColor, type ButtonProps } from "./button.js";
|
|
16
17
|
export { Input, type InputProps } from "./input.js";
|
|
17
18
|
export { Textarea, type TextareaProps } from "./textarea.js";
|
|
@@ -21,6 +22,13 @@ export { Switch, type SwitchProps } from "./switch.js";
|
|
|
21
22
|
export { Select, type SelectProps, type SelectOption } from "./select.js";
|
|
22
23
|
export { Slider, type SliderProps } from "./slider.js";
|
|
23
24
|
export { ScrollArea, type ScrollAreaAxis, type ScrollAreaProps } from "./scroll-area.js";
|
|
25
|
+
export { Popover, PopoverRoot, PopoverTrigger, PopoverContent, PopoverDialog, PopoverTitle, PopoverClose, type PopoverProps, type PopoverRootProps, type PopoverTriggerProps, type PopoverContentProps, type PopoverDialogProps, type PopoverTitleProps, type PopoverCloseProps } from "./popover.js";
|
|
26
|
+
export { Menu, MenuRoot, MenuItem, MenuSection, MenuHeader, MenuSeparator, type MenuProps, type MenuRootProps, type MenuItemProps, type MenuSectionProps, type MenuHeaderProps, type MenuSeparatorProps } from "./menu.js";
|
|
27
|
+
export { DropdownMenu, DropdownMenuRoot, DropdownMenuTrigger, type DropdownMenuProps, type DropdownMenuRootProps, type DropdownMenuTriggerProps } from "./dropdown-menu.js";
|
|
28
|
+
export { ContextMenu, ContextMenuRoot, ContextMenuTrigger, type ContextMenuProps, type ContextMenuRootProps, type ContextMenuTriggerProps } from "./context-menu.js";
|
|
29
|
+
export { Dialog, DialogRoot, DialogTrigger, DialogBackdrop, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogClose, type DialogProps, type DialogRootProps, type DialogTriggerProps, type DialogBackdropProps, type DialogContentProps, type DialogHeaderProps, type DialogTitleProps, type DialogDescriptionProps, type DialogBodyProps, type DialogFooterProps, type DialogCloseProps } from "./dialog.js";
|
|
30
|
+
export { AlertDialog, AlertDialogRoot, AlertDialogBackdrop, AlertDialogContent, type AlertDialogProps, type AlertDialogRootProps, type AlertDialogBackdropProps, type AlertDialogContentProps } from "./alert-dialog.js";
|
|
31
|
+
export { Tooltip, TooltipRoot, TooltipTrigger, TooltipContent, type TooltipProps, type TooltipRootProps, type TooltipTriggerProps, type TooltipContentProps } from "./tooltip.js";
|
|
24
32
|
export type { ControlColor } from "./control.js";
|
|
25
33
|
export type { LayoutAlignment, LayoutGap, LayoutJustification } from "./layout.js";
|
|
26
34
|
export { resolveRadius, type Radius, type RadiusProps } from "./radius.js";
|
package/dist/main.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* behavior contract has been established by the package's tests.
|
|
6
6
|
*/
|
|
7
7
|
export { defaultAppearance } from "@phreshos/core";
|
|
8
|
-
export {
|
|
8
|
+
export { UIProvider, useAppearance, useBrowserPreferences, useDirection, useDocumentDirection, usePreferences, useThemedValue } from "./ui-provider.js";
|
|
9
9
|
export { Flex } from "./flex.js";
|
|
10
10
|
export { Grid } from "./grid.js";
|
|
11
11
|
export { Surface } from "./surface.js";
|
|
12
12
|
export { defaultColor } from "./color.js";
|
|
13
|
-
export { Panel } from "./panel.js";
|
|
13
|
+
export { Panel, PanelRoot, PanelHeader, PanelContent } from "./panel.js";
|
|
14
14
|
export { Button } from "./button.js";
|
|
15
15
|
export { Input } from "./input.js";
|
|
16
16
|
export { Textarea } from "./textarea.js";
|
|
@@ -20,6 +20,13 @@ export { Switch } from "./switch.js";
|
|
|
20
20
|
export { Select } from "./select.js";
|
|
21
21
|
export { Slider } from "./slider.js";
|
|
22
22
|
export { ScrollArea } from "./scroll-area.js";
|
|
23
|
+
export { Popover, PopoverRoot, PopoverTrigger, PopoverContent, PopoverDialog, PopoverTitle, PopoverClose } from "./popover.js";
|
|
24
|
+
export { Menu, MenuRoot, MenuItem, MenuSection, MenuHeader, MenuSeparator } from "./menu.js";
|
|
25
|
+
export { DropdownMenu, DropdownMenuRoot, DropdownMenuTrigger } from "./dropdown-menu.js";
|
|
26
|
+
export { ContextMenu, ContextMenuRoot, ContextMenuTrigger } from "./context-menu.js";
|
|
27
|
+
export { Dialog, DialogRoot, DialogTrigger, DialogBackdrop, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogBody, DialogFooter, DialogClose } from "./dialog.js";
|
|
28
|
+
export { AlertDialog, AlertDialogRoot, AlertDialogBackdrop, AlertDialogContent } from "./alert-dialog.js";
|
|
29
|
+
export { Tooltip, TooltipRoot, TooltipTrigger, TooltipContent } from "./tooltip.js";
|
|
23
30
|
export { resolveRadius } from "./radius.js";
|
|
24
31
|
export { resolveSpacing } from "./spacing.js";
|
|
25
32
|
export { useColor } from "./color.js";
|
|
@@ -10,7 +10,8 @@ export interface MaterialOptions {
|
|
|
10
10
|
}
|
|
11
11
|
/** Grouped material customization exposed by components built on Surface. */
|
|
12
12
|
export interface MaterialOverrides {
|
|
13
|
-
|
|
13
|
+
/** Omission or true uses Appearance defaults; false uses the resolved color as a normal background. */
|
|
14
|
+
readonly material?: boolean | MaterialOptions;
|
|
14
15
|
}
|
|
15
16
|
/** Resolves material values from the current Appearance without knowing any host geometry. */
|
|
16
17
|
export declare function useMaterialOptions(values?: MaterialOptions): {
|
package/dist/material-options.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { appearanceLimits } from "@phreshos/core";
|
|
2
|
-
import { useAppearance, useThemedValue } from "./
|
|
2
|
+
import { useAppearance, useThemedValue } from "./ui-provider.js";
|
|
3
3
|
import { isScaleLevel, scale, scaleMultiplier } from "./scale.js";
|
|
4
4
|
/** Resolves material values from the current Appearance without knowing any host geometry. */
|
|
5
5
|
export function useMaterialOptions(values = {}) {
|
package/dist/menu.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement, RefAttributes } from "react";
|
|
2
|
+
import type { HeaderProps as AriaHeaderProps, MenuItemProps as AriaMenuItemProps, MenuProps as AriaMenuProps, MenuSectionProps as AriaMenuSectionProps, SeparatorProps as AriaSeparatorProps } from "react-aria-components";
|
|
3
|
+
import { type ControlColor } from "./control.js";
|
|
4
|
+
import type { ScaleLevel } from "./scale.js";
|
|
5
|
+
export interface MenuRootProps<T extends object = object> extends Omit<AriaMenuProps<T>, "className" | "style"> {
|
|
6
|
+
readonly className?: string;
|
|
7
|
+
readonly color?: ControlColor;
|
|
8
|
+
readonly size?: ScaleLevel;
|
|
9
|
+
readonly style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export type MenuRootComponent = <T extends object = object>(properties: MenuRootProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
12
|
+
export declare const MenuRoot: MenuRootComponent;
|
|
13
|
+
export interface MenuItemProps<T = object> extends Omit<AriaMenuItemProps<T>, "className" | "isDisabled" | "style"> {
|
|
14
|
+
readonly className?: string;
|
|
15
|
+
readonly color?: ControlColor;
|
|
16
|
+
readonly disabled?: boolean;
|
|
17
|
+
readonly style?: CSSProperties;
|
|
18
|
+
}
|
|
19
|
+
export type MenuItemComponent = <T = object>(properties: MenuItemProps<T> & RefAttributes<HTMLDivElement>) => ReactElement | null;
|
|
20
|
+
export declare const MenuItem: MenuItemComponent;
|
|
21
|
+
export type MenuSectionProps<T extends object = object> = AriaMenuSectionProps<T>;
|
|
22
|
+
export declare const MenuSection: <T>(props: AriaMenuSectionProps<T> & React.RefAttributes<HTMLElement>) => ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
|
|
23
|
+
export type MenuHeaderProps = AriaHeaderProps;
|
|
24
|
+
export declare const MenuHeader: import("react").ForwardRefExoticComponent<AriaHeaderProps & RefAttributes<HTMLElement>>;
|
|
25
|
+
export type MenuSeparatorProps = AriaSeparatorProps;
|
|
26
|
+
export declare const MenuSeparator: import("react").ForwardRefExoticComponent<AriaSeparatorProps & RefAttributes<HTMLElement>>;
|
|
27
|
+
/** A keyboard-navigable collection of commands or selectable options. */
|
|
28
|
+
export declare const Menu: MenuRootComponent & {
|
|
29
|
+
Root: MenuRootComponent;
|
|
30
|
+
Item: MenuItemComponent;
|
|
31
|
+
Section: <T>(props: AriaMenuSectionProps<T> & React.RefAttributes<HTMLElement>) => ReactElement<unknown, string | React.JSXElementConstructor<any>> | null;
|
|
32
|
+
Header: import("react").ForwardRefExoticComponent<AriaHeaderProps & RefAttributes<HTMLElement>>;
|
|
33
|
+
Separator: import("react").ForwardRefExoticComponent<AriaSeparatorProps & RefAttributes<HTMLElement>>;
|
|
34
|
+
};
|
|
35
|
+
export type MenuProps<T extends object = object> = MenuRootProps<T>;
|
package/dist/menu.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext } from "react";
|
|
3
|
+
import { Header as AriaHeader, Menu as AriaMenu, MenuItem as AriaMenuItem, MenuSection as AriaMenuSection, Separator as AriaSeparator } from "react-aria-components";
|
|
4
|
+
import { colorOpacity } from "./color.js";
|
|
5
|
+
import { useControlTheme } from "./control.js";
|
|
6
|
+
const MenuThemeContext = createContext(null);
|
|
7
|
+
const MenuRootImplementation = forwardRef(function MenuRoot({ className, color, size = "medium", style, ...properties }, ref) {
|
|
8
|
+
const theme = useControlTheme({ color, size });
|
|
9
|
+
return _jsx(MenuThemeContext.Provider, { value: { color, size, theme }, children: _jsx(AriaMenu, { ...properties, ref: ref, className: className, style: {
|
|
10
|
+
display: "grid",
|
|
11
|
+
gap: theme.gap,
|
|
12
|
+
minWidth: 160,
|
|
13
|
+
padding: theme.gap,
|
|
14
|
+
boxSizing: "border-box",
|
|
15
|
+
outline: "none",
|
|
16
|
+
color: theme.foreground,
|
|
17
|
+
fontFamily: "inherit",
|
|
18
|
+
fontSize: theme.fontSize,
|
|
19
|
+
...style
|
|
20
|
+
} }) });
|
|
21
|
+
});
|
|
22
|
+
export const MenuRoot = MenuRootImplementation;
|
|
23
|
+
const MenuItemImplementation = forwardRef(function MenuItem({ className, color, disabled = false, style, ...properties }, ref) {
|
|
24
|
+
const inherited = useContext(MenuThemeContext);
|
|
25
|
+
const theme = useControlTheme({ color: color ?? inherited?.color, size: inherited?.size ?? "medium" });
|
|
26
|
+
return _jsx(AriaMenuItem, { ...properties, ref: ref, className: className, isDisabled: disabled, style: state => {
|
|
27
|
+
const paint = state.isPressed
|
|
28
|
+
? theme.paints.palette.pressed
|
|
29
|
+
: state.isFocused || state.isHovered || state.isSelected
|
|
30
|
+
? theme.paints.palette.hover
|
|
31
|
+
: { background: "transparent", color: theme.foreground };
|
|
32
|
+
return {
|
|
33
|
+
...theme.transition,
|
|
34
|
+
display: "flex",
|
|
35
|
+
alignItems: "center",
|
|
36
|
+
justifyContent: "space-between",
|
|
37
|
+
gap: theme.gap,
|
|
38
|
+
minWidth: 0,
|
|
39
|
+
minHeight: theme.height,
|
|
40
|
+
paddingInline: Math.max(8, theme.spacing),
|
|
41
|
+
boxSizing: "border-box",
|
|
42
|
+
borderRadius: theme.radius,
|
|
43
|
+
outline: "none",
|
|
44
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
45
|
+
opacity: disabled ? 0.46 : 1,
|
|
46
|
+
userSelect: "none",
|
|
47
|
+
...paint,
|
|
48
|
+
...style
|
|
49
|
+
};
|
|
50
|
+
} });
|
|
51
|
+
});
|
|
52
|
+
export const MenuItem = MenuItemImplementation;
|
|
53
|
+
export const MenuSection = AriaMenuSection;
|
|
54
|
+
export const MenuHeader = forwardRef(function MenuHeader({ style, ...properties }, ref) {
|
|
55
|
+
const inherited = useContext(MenuThemeContext);
|
|
56
|
+
const fallback = useControlTheme({});
|
|
57
|
+
const theme = inherited?.theme ?? fallback;
|
|
58
|
+
return _jsx(AriaHeader, { ...properties, ref: ref, style: {
|
|
59
|
+
paddingInline: Math.max(8, theme.spacing),
|
|
60
|
+
paddingBlock: theme.gap,
|
|
61
|
+
fontWeight: 600,
|
|
62
|
+
opacity: 0.7,
|
|
63
|
+
...style
|
|
64
|
+
} });
|
|
65
|
+
});
|
|
66
|
+
export const MenuSeparator = forwardRef(function MenuSeparator({ style, ...properties }, ref) {
|
|
67
|
+
const inherited = useContext(MenuThemeContext);
|
|
68
|
+
const fallback = useControlTheme({});
|
|
69
|
+
const theme = inherited?.theme ?? fallback;
|
|
70
|
+
return _jsx(AriaSeparator, { ...properties, ref: ref, style: {
|
|
71
|
+
height: 1,
|
|
72
|
+
marginBlock: theme.gap,
|
|
73
|
+
border: 0,
|
|
74
|
+
background: colorOpacity(theme.foreground, 0.14),
|
|
75
|
+
...style
|
|
76
|
+
} });
|
|
77
|
+
});
|
|
78
|
+
/** A keyboard-navigable collection of commands or selectable options. */
|
|
79
|
+
export const Menu = Object.assign(MenuRoot, {
|
|
80
|
+
Root: MenuRoot,
|
|
81
|
+
Item: MenuItem,
|
|
82
|
+
Section: MenuSection,
|
|
83
|
+
Header: MenuHeader,
|
|
84
|
+
Separator: MenuSeparator
|
|
85
|
+
});
|
package/dist/motion-style.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare function useControlTransition(): Transition;
|
|
|
9
9
|
/** Per-overlay variables consumed by the shared entrance keyframes. */
|
|
10
10
|
export declare function useOverlayTransition(): CSSProperties;
|
|
11
11
|
export declare const overlayMotionClass = "phreshos-ui-overlay";
|
|
12
|
+
export declare const backdropMotionClass = "phreshos-ui-backdrop";
|
|
12
13
|
export declare function useTransitionTiming(): CSSProperties;
|
|
13
14
|
/** React hoists and deduplicates this stylesheet, including portals. */
|
|
14
15
|
export default function MotionStyle(): import("react").JSX.Element;
|
package/dist/motion-style.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { defaultAppearance } from "@phreshos/core";
|
|
3
3
|
import { useAppearance, usePreferences } from "./appearance-context.js";
|
|
4
|
-
const visualProperties = "background-color, color, border-color, border-radius";
|
|
4
|
+
const visualProperties = "background-color, color, border-color, border-radius, box-shadow";
|
|
5
5
|
const paintProperties = "fill, stroke, opacity";
|
|
6
6
|
/** CSS timing for values painted directly by React UI. */
|
|
7
7
|
export function useVisualTransition() {
|
|
@@ -31,6 +31,7 @@ export function useOverlayTransition() {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
export const overlayMotionClass = "phreshos-ui-overlay";
|
|
34
|
+
export const backdropMotionClass = "phreshos-ui-backdrop";
|
|
34
35
|
export function useTransitionTiming() {
|
|
35
36
|
const { duration, easing } = useAppearance().transaction;
|
|
36
37
|
const { animations } = usePreferences();
|
|
@@ -61,10 +62,6 @@ const stylesheet = `
|
|
|
61
62
|
--phreshos-ui-motion-easing: ${cssEasing(defaultAppearance.transaction.easing)};
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
.phreshos-ui-overlay { --phreshos-ui-overlay-x: 0px; --phreshos-ui-overlay-y: -4px; }
|
|
65
|
-
.phreshos-ui-overlay[data-placement="top"] { --phreshos-ui-overlay-y: 4px; }
|
|
66
|
-
.phreshos-ui-overlay[data-placement="left"] { --phreshos-ui-overlay-x: 4px; --phreshos-ui-overlay-y: 0px; }
|
|
67
|
-
.phreshos-ui-overlay[data-placement="right"] { --phreshos-ui-overlay-x: -4px; --phreshos-ui-overlay-y: 0px; }
|
|
68
65
|
.phreshos-ui-overlay[data-entering] {
|
|
69
66
|
animation: phreshos-ui-overlay-enter var(--phreshos-ui-motion-duration) var(--phreshos-ui-motion-easing) both;
|
|
70
67
|
}
|
|
@@ -72,9 +69,20 @@ const stylesheet = `
|
|
|
72
69
|
animation: phreshos-ui-overlay-enter var(--phreshos-ui-motion-duration) var(--phreshos-ui-motion-easing) reverse both;
|
|
73
70
|
pointer-events: none;
|
|
74
71
|
}
|
|
72
|
+
.phreshos-ui-backdrop[data-entering] {
|
|
73
|
+
animation: phreshos-ui-backdrop-enter var(--phreshos-ui-motion-duration) var(--phreshos-ui-motion-easing) both;
|
|
74
|
+
}
|
|
75
|
+
.phreshos-ui-backdrop[data-exiting] {
|
|
76
|
+
animation: phreshos-ui-backdrop-enter var(--phreshos-ui-motion-duration) var(--phreshos-ui-motion-easing) reverse both;
|
|
77
|
+
pointer-events: none;
|
|
78
|
+
}
|
|
75
79
|
@keyframes phreshos-ui-overlay-enter {
|
|
76
|
-
from { opacity: 0;
|
|
77
|
-
to { opacity: 1;
|
|
80
|
+
from { opacity: 0; scale: 1.05; }
|
|
81
|
+
to { opacity: 1; scale: 1; }
|
|
82
|
+
}
|
|
83
|
+
@keyframes phreshos-ui-backdrop-enter {
|
|
84
|
+
from { opacity: 0; }
|
|
85
|
+
to { opacity: 1; }
|
|
78
86
|
}
|
|
79
87
|
`;
|
|
80
88
|
/** React hoists and deduplicates this stylesheet, including portals. */
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Placement } from "react-aria-components";
|
|
2
|
+
import type { Direction } from "./direction.js";
|
|
3
|
+
/** Resolves logical placement before it reaches the overlay primitive. */
|
|
4
|
+
export declare function resolveDirectionalPlacement(placement: Placement, direction: Direction): Placement;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Resolves logical placement before it reaches the overlay primitive. */
|
|
2
|
+
export function resolveDirectionalPlacement(placement, direction) {
|
|
3
|
+
const start = direction === "rtl" ? "right" : "left";
|
|
4
|
+
const end = direction === "rtl" ? "left" : "right";
|
|
5
|
+
return placement.replace(/\bstart\b/g, start).replace(/\bend\b/g, end);
|
|
6
|
+
}
|
package/dist/panel.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ComponentProps, HTMLAttributes } from "react";
|
|
2
2
|
import { type SurfaceProps } from "./surface.js";
|
|
3
|
-
/**
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
/** Optional content placed before the inset Panel surface. */
|
|
4
|
+
export type PanelHeaderProps = HTMLAttributes<HTMLDivElement>;
|
|
5
|
+
export declare const PanelHeader: import("react").ForwardRefExoticComponent<PanelHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
6
|
+
/** The material shell that owns a Panel's vertical composition. */
|
|
7
|
+
export type PanelRootProps = SurfaceProps;
|
|
8
|
+
export declare const PanelRoot: import("react").ForwardRefExoticComponent<Omit<PanelRootProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
9
|
+
/** The independently configurable inset Surface that owns Panel content. */
|
|
10
|
+
export type PanelContentProps = SurfaceProps;
|
|
11
|
+
export declare const PanelContent: import("react").ForwardRefExoticComponent<Omit<PanelContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
12
|
+
/** A material shell whose named parts remain independently composable. */
|
|
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
|
+
Header: import("react").ForwardRefExoticComponent<PanelHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
16
|
+
Content: import("react").ForwardRefExoticComponent<Omit<PanelContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
17
|
+
};
|
|
18
|
+
export type PanelProps = ComponentProps<typeof PanelRoot>;
|
package/dist/panel.js
CHANGED
|
@@ -1,27 +1,42 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import { forwardRef } from "react";
|
|
3
|
-
import { useAppearance } from "./
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children, createContext, forwardRef, isValidElement, useContext } from "react";
|
|
3
|
+
import { useAppearance } from "./ui-provider.js";
|
|
4
4
|
import { scale } from "./scale.js";
|
|
5
5
|
import { Surface } from "./surface.js";
|
|
6
|
-
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const PanelContext = createContext({ hasHeader: false });
|
|
7
|
+
export const PanelHeader = forwardRef(function PanelHeader({ style, ...properties }, ref) {
|
|
8
|
+
return _jsx("div", { ...properties, ref: ref, style: {
|
|
9
|
+
minWidth: 0,
|
|
10
|
+
...style
|
|
11
|
+
} });
|
|
12
|
+
});
|
|
13
|
+
export const PanelRoot = forwardRef(function PanelRoot({ children, style, ...properties }, ref) {
|
|
14
|
+
const hasHeader = Children.toArray(children).some(child => isValidElement(child) && child.type === PanelHeader);
|
|
15
|
+
return _jsx(PanelContext.Provider, { value: { hasHeader }, children: _jsx(Surface, { ...properties, ref: ref, style: {
|
|
16
|
+
display: "grid",
|
|
17
|
+
gridTemplateRows: hasHeader ? "auto minmax(0, 1fr)" : "minmax(0, 1fr)",
|
|
18
|
+
minWidth: 0,
|
|
19
|
+
minHeight: 0,
|
|
20
|
+
maxHeight: "inherit",
|
|
21
|
+
...style
|
|
22
|
+
}, children: children }) });
|
|
23
|
+
});
|
|
24
|
+
export const PanelContent = forwardRef(function PanelContent({ style, ...properties }, ref) {
|
|
25
|
+
const inset = scale(useAppearance().spacing, "small");
|
|
26
|
+
const { hasHeader } = useContext(PanelContext);
|
|
27
|
+
return _jsx(Surface, { ...properties, ref: ref, style: {
|
|
28
|
+
position: "relative",
|
|
14
29
|
minWidth: 0,
|
|
15
30
|
minHeight: 0,
|
|
16
|
-
|
|
31
|
+
margin: inset,
|
|
32
|
+
marginTop: hasHeader ? 0 : inset,
|
|
33
|
+
overflow: "hidden",
|
|
17
34
|
...style
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
...contentProps?.style
|
|
26
|
-
}, children: children })] });
|
|
35
|
+
} });
|
|
36
|
+
});
|
|
37
|
+
/** A material shell whose named parts remain independently composable. */
|
|
38
|
+
export const Panel = Object.assign(PanelRoot, {
|
|
39
|
+
Root: PanelRoot,
|
|
40
|
+
Header: PanelHeader,
|
|
41
|
+
Content: PanelContent
|
|
27
42
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentProps, CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { DialogProps as AriaDialogProps, DialogTriggerProps as AriaDialogTriggerProps, HeadingProps as AriaHeadingProps, PopoverProps as AriaPopoverProps } from "react-aria-components";
|
|
3
|
+
import { type ButtonProps } from "./button.js";
|
|
4
|
+
import { type SurfaceOwnProps } from "./surface.js";
|
|
5
|
+
export type PopoverRootProps = AriaDialogTriggerProps;
|
|
6
|
+
export declare function PopoverRoot(properties: PopoverRootProps): import("react").JSX.Element;
|
|
7
|
+
export type PopoverTriggerProps = ButtonProps;
|
|
8
|
+
export declare const PopoverTrigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
9
|
+
export interface PopoverContentProps extends Omit<AriaPopoverProps, "children" | "className" | "color" | "style">, SurfaceOwnProps {
|
|
10
|
+
readonly children?: ReactNode;
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
readonly style?: CSSProperties;
|
|
13
|
+
}
|
|
14
|
+
export declare const PopoverContent: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
|
|
15
|
+
export type PopoverDialogProps = AriaDialogProps;
|
|
16
|
+
export declare const PopoverDialog: import("react").ForwardRefExoticComponent<AriaDialogProps & import("react").RefAttributes<HTMLElement>>;
|
|
17
|
+
export type PopoverTitleProps = AriaHeadingProps;
|
|
18
|
+
export declare const PopoverTitle: import("react").ForwardRefExoticComponent<AriaHeadingProps & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
19
|
+
export type PopoverCloseProps = ButtonProps;
|
|
20
|
+
export declare const PopoverClose: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
21
|
+
/** An anchored non-modal overlay with explicit trigger, surface, and dialog roles. */
|
|
22
|
+
export declare const Popover: typeof PopoverRoot & {
|
|
23
|
+
Root: typeof PopoverRoot;
|
|
24
|
+
Trigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
25
|
+
Content: import("react").ForwardRefExoticComponent<PopoverContentProps & import("react").RefAttributes<HTMLElement>>;
|
|
26
|
+
Dialog: import("react").ForwardRefExoticComponent<AriaDialogProps & import("react").RefAttributes<HTMLElement>>;
|
|
27
|
+
Title: import("react").ForwardRefExoticComponent<AriaHeadingProps & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
28
|
+
Close: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
29
|
+
};
|
|
30
|
+
export type PopoverProps = ComponentProps<typeof PopoverRoot>;
|
package/dist/popover.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Dialog as AriaDialog, DialogTrigger as AriaDialogTrigger, Heading as AriaHeading, Popover as AriaPopover } from "react-aria-components";
|
|
4
|
+
import { useAppearance } from "./ui-provider.js";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
import { overlayMotionClass, useOverlayTransition } from "./motion-style.js";
|
|
7
|
+
import { scale } from "./scale.js";
|
|
8
|
+
import { Surface } from "./surface.js";
|
|
9
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
10
|
+
import { resolveDirectionalPlacement } from "./overlay-placement.js";
|
|
11
|
+
export function PopoverRoot(properties) {
|
|
12
|
+
return _jsx(AriaDialogTrigger, { ...properties });
|
|
13
|
+
}
|
|
14
|
+
export const PopoverTrigger = forwardRef(function PopoverTrigger(properties, ref) {
|
|
15
|
+
return _jsx(Button, { ...properties, ref: ref });
|
|
16
|
+
});
|
|
17
|
+
export const PopoverContent = forwardRef(function PopoverContent({ children, className, color, material, radius, shadow, style, offset, placement = "bottom", ...properties }, ref) {
|
|
18
|
+
const inset = scale(useAppearance().spacing, "small");
|
|
19
|
+
const transition = useOverlayTransition();
|
|
20
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
21
|
+
return _jsx(AriaPopover, { ...properties, ref: ref, dir: direction, offset: offset ?? inset, placement: resolveDirectionalPlacement(placement, direction), className: overlayMotionClass, style: transition, children: _jsx(Surface, { dir: direction, className: className, color: color, material: material, radius: radius, shadow: shadow, style: {
|
|
22
|
+
boxSizing: "border-box",
|
|
23
|
+
maxWidth: `calc(100vw - ${inset * 2}px)`,
|
|
24
|
+
maxHeight: `calc(100vh - ${inset * 2}px)`,
|
|
25
|
+
outline: "none",
|
|
26
|
+
...style
|
|
27
|
+
}, children: children }) });
|
|
28
|
+
});
|
|
29
|
+
export const PopoverDialog = forwardRef(function PopoverDialog({ style, ...properties }, ref) {
|
|
30
|
+
return _jsx(AriaDialog, { ...properties, ref: ref, style: { minWidth: 0, outline: "none", ...style } });
|
|
31
|
+
});
|
|
32
|
+
export const PopoverTitle = forwardRef(function PopoverTitle(properties, ref) {
|
|
33
|
+
return _jsx(AriaHeading, { ...properties, ref: ref, slot: "title" });
|
|
34
|
+
});
|
|
35
|
+
export const PopoverClose = forwardRef(function PopoverClose(properties, ref) {
|
|
36
|
+
return _jsx(Button, { ...properties, ref: ref, slot: "close" });
|
|
37
|
+
});
|
|
38
|
+
/** An anchored non-modal overlay with explicit trigger, surface, and dialog roles. */
|
|
39
|
+
export const Popover = Object.assign(PopoverRoot, {
|
|
40
|
+
Root: PopoverRoot,
|
|
41
|
+
Trigger: PopoverTrigger,
|
|
42
|
+
Content: PopoverContent,
|
|
43
|
+
Dialog: PopoverDialog,
|
|
44
|
+
Title: PopoverTitle,
|
|
45
|
+
Close: PopoverClose
|
|
46
|
+
});
|
package/dist/radio.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
import type { RadioRootProps as BaseRadioProps } from "@base-ui/react/radio";
|
|
2
|
+
import type { RadioGroupProps as BaseRadioGroupProps } from "@base-ui/react/radio-group";
|
|
1
3
|
import type { ReactNode } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
|
|
4
|
+
import type { ControlProps, FieldProps } from "./control.js";
|
|
4
5
|
import type { MaterialOverrides } from "./material-options.js";
|
|
5
|
-
|
|
6
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
7
|
+
export interface RadioGroupProps extends Omit<BaseRadioGroupProps<string | null>, "children" | "className" | "defaultValue" | "disabled" | "onChange" | "onValueChange" | "readOnly" | "required" | "style" | "value">, ControlProps, FieldProps, MaterialOverrides, ShadowOverrides {
|
|
6
8
|
readonly children: ReactNode;
|
|
9
|
+
readonly value?: string | null;
|
|
10
|
+
readonly defaultValue?: string | null;
|
|
11
|
+
readonly onChange?: (value: string) => void;
|
|
7
12
|
readonly readOnly?: boolean;
|
|
13
|
+
readonly orientation?: "horizontal" | "vertical";
|
|
8
14
|
}
|
|
9
|
-
export interface RadioProps extends Omit<
|
|
15
|
+
export interface RadioProps extends Omit<BaseRadioProps<string>, "children" | "className" | "disabled" | "readOnly" | "required" | "style" | "value">, ControlProps, Pick<FieldProps, "label" | "description">, MaterialOverrides, ShadowOverrides {
|
|
16
|
+
readonly value: string;
|
|
10
17
|
}
|
|
11
|
-
/** One string value selected from its Radio children, with
|
|
12
|
-
export declare const RadioGroup: import("react").ForwardRefExoticComponent<RadioGroupProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
18
|
+
/** One string value selected from its Radio children, with direction-aware arrow navigation. */
|
|
19
|
+
export declare const RadioGroup: import("react").ForwardRefExoticComponent<Omit<RadioGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
13
20
|
/** An option in a RadioGroup. Selection and validation belong to the group. */
|
|
14
|
-
export declare const Radio: import("react").ForwardRefExoticComponent<RadioProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
21
|
+
export declare const Radio: import("react").ForwardRefExoticComponent<Omit<RadioProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
package/dist/radio.js
CHANGED
|
@@ -1,17 +1,42 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
-
import {
|
|
3
|
-
import { RadioGroup as
|
|
4
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Radio as BaseRadio } from "@base-ui/react/radio";
|
|
3
|
+
import { RadioGroup as BaseRadioGroup } from "@base-ui/react/radio-group";
|
|
4
|
+
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
5
|
+
import { createContext, forwardRef, useContext, useId, useState } from "react";
|
|
6
|
+
import { fieldStyle, useControlTheme } from "./control.js";
|
|
5
7
|
import { ToggleIndicator, toggleStyle } from "./toggle-indicator.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
9
|
+
const RadioStyleContext = createContext(null);
|
|
10
|
+
/** One string value selected from its Radio children, with direction-aware arrow navigation. */
|
|
11
|
+
export const RadioGroup = forwardRef(function RadioGroup({ 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) {
|
|
9
12
|
const theme = useControlTheme({ size, color });
|
|
10
|
-
|
|
13
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
14
|
+
const labelId = useId();
|
|
15
|
+
const descriptionId = useId();
|
|
16
|
+
const errorId = useId();
|
|
17
|
+
const describedBy = [ariaDescribedBy, description != null ? descriptionId : null, invalid && errorMessage != null ? errorId : null].filter(Boolean).join(" ") || undefined;
|
|
18
|
+
const root = _jsxs(BaseRadioGroup, { ...properties, ref: ref, className: className, value: value, defaultValue: defaultValue, onValueChange: next => {
|
|
19
|
+
if (next != null)
|
|
20
|
+
onChange?.(next);
|
|
21
|
+
}, 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: 550 }, 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: 0.7 }, children: description }), invalid && errorMessage != null && _jsx("span", { id: errorId, style: { fontSize: "0.92em", color: theme.danger }, children: errorMessage })] });
|
|
22
|
+
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
11
23
|
});
|
|
12
24
|
/** An option in a RadioGroup. Selection and validation belong to the group. */
|
|
13
|
-
export const Radio = forwardRef(function Radio({ label, description, disabled, size, color, style, material, ...properties }, ref) {
|
|
14
|
-
const inherited = useContext(
|
|
25
|
+
export const Radio = forwardRef(function Radio({ label, description, value, disabled = false, size, color, style, className, material, shadow, onFocus, onBlur, "aria-describedby": ariaDescribedBy, ...properties }, ref) {
|
|
26
|
+
const inherited = useContext(RadioStyleContext);
|
|
27
|
+
if (inherited == null)
|
|
28
|
+
throw new Error("Radio must be used inside RadioGroup");
|
|
15
29
|
const theme = useControlTheme({ size: size ?? inherited.size, color: color ?? inherited.color });
|
|
16
|
-
|
|
30
|
+
const descriptionId = useId();
|
|
31
|
+
const [hovered, setHovered] = useState(false);
|
|
32
|
+
const [pressed, setPressed] = useState(false);
|
|
33
|
+
const [focusVisible, setFocusVisible] = useState(false);
|
|
34
|
+
const describedBy = [ariaDescribedBy, description != null ? descriptionId : null].filter(Boolean).join(" ") || undefined;
|
|
35
|
+
return _jsxs("div", { ref: ref, className: className, style: fieldStyle(theme, disabled && !inherited.disabled, style), children: [_jsx(BaseRadio.Root, { ...properties, value: value, disabled: disabled, "aria-describedby": describedBy, onPointerEnter: () => setHovered(true), onPointerLeave: () => { setHovered(false); setPressed(false); }, onPointerDown: () => setPressed(true), onPointerUp: () => setPressed(false), onFocus: event => {
|
|
36
|
+
setFocusVisible(event.currentTarget.matches(":focus-visible"));
|
|
37
|
+
onFocus?.(event);
|
|
38
|
+
}, onBlur: event => {
|
|
39
|
+
setFocusVisible(false);
|
|
40
|
+
onBlur?.(event);
|
|
41
|
+
}, 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: 0.7 }, children: description })] });
|
|
17
42
|
});
|
package/dist/radius.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { CSSProperties } from "react";
|
|
2
2
|
import type { Appearance } from "@phreshos/core";
|
|
3
3
|
import { type ScaleLevel } from "./scale.js";
|
|
4
|
-
/** An Appearance-derived level, pixel value, or explicit CSS corner radius. */
|
|
5
|
-
export type Radius = ScaleLevel | number | (string & {});
|
|
4
|
+
/** An Appearance-derived level, fully rounded shape, pixel value, or explicit CSS corner radius. */
|
|
5
|
+
export type Radius = ScaleLevel | "full" | number | (string & {});
|
|
6
6
|
/** Shared semantic corner-radius capability for React UI components. */
|
|
7
7
|
export interface RadiusProps {
|
|
8
8
|
readonly radius?: Radius;
|
package/dist/radius.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { isScaleLevel, scale } from "./scale.js";
|
|
2
2
|
/** Resolves a Radius while preserving explicit CSS and pixel values. */
|
|
3
3
|
export function resolveRadius(value, appearance) {
|
|
4
|
+
if (value === "full")
|
|
5
|
+
return "9999px";
|
|
4
6
|
if (!isScaleLevel(value))
|
|
5
7
|
return value;
|
|
6
8
|
if (!appearance)
|
|
7
|
-
throw new Error("A semantic radius requires
|
|
9
|
+
throw new Error("A semantic radius requires a UIProvider");
|
|
8
10
|
return scale(appearance.radius, value);
|
|
9
11
|
}
|