@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/scroll-area.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
3
|
+
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
3
4
|
import { forwardRef, useState } from "react";
|
|
4
|
-
import { useAppearance, useThemedValue } from "./
|
|
5
|
+
import { useAppearance, useThemedValue } from "./ui-provider.js";
|
|
5
6
|
import { colorOpacity } from "./color.js";
|
|
6
7
|
import { useTransitionTiming } from "./motion-style.js";
|
|
8
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
7
9
|
/** A native scrolling viewport with locally owned React UI scrollbars. */
|
|
8
10
|
export const ScrollArea = forwardRef(function ScrollArea({ axis = "vertical", children, onScroll, style, viewportRef, ...properties }, ref) {
|
|
9
11
|
const appearance = useAppearance();
|
|
12
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
10
13
|
const foreground = useThemedValue(appearance.colors).foreground;
|
|
11
14
|
const radius = Math.min(appearance.radius, 8);
|
|
12
15
|
const vertical = axis === "vertical" || axis === "both";
|
|
13
16
|
const horizontal = axis === "horizontal" || axis === "both";
|
|
14
|
-
|
|
17
|
+
const root = _jsxs(BaseScrollArea.Root, { ...properties, "data-phreshos-scroll-area": "", ref: ref, style: {
|
|
15
18
|
...style,
|
|
16
19
|
position: style?.position ?? "relative",
|
|
17
20
|
minWidth: style?.minWidth ?? 0,
|
|
@@ -23,6 +26,7 @@ export const ScrollArea = forwardRef(function ScrollArea({ axis = "vertical", ch
|
|
|
23
26
|
overflowX: horizontal ? "scroll" : "hidden",
|
|
24
27
|
overflowY: vertical ? "scroll" : "hidden"
|
|
25
28
|
}, children: _jsx(BaseScrollArea.Content, { "data-phreshos-scroll-area-content": "", style: vertical && !horizontal ? { minWidth: "100%", width: "100%" } : undefined, children: children }) }), vertical && _jsx(Scrollbar, { orientation: "vertical", foreground: foreground, radius: radius }), horizontal && _jsx(Scrollbar, { orientation: "horizontal", foreground: foreground, radius: radius }), vertical && horizontal && _jsx(BaseScrollArea.Corner, { style: { background: "transparent" } })] });
|
|
29
|
+
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
26
30
|
});
|
|
27
31
|
function Scrollbar({ orientation, foreground, radius }) {
|
|
28
32
|
const [hovered, setHovered] = useState(false);
|
package/dist/select.d.ts
CHANGED
|
@@ -2,12 +2,13 @@ import type { SelectProps as AriaSelectProps } from "react-aria-components";
|
|
|
2
2
|
import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
|
|
3
3
|
import type { RadiusProps } from "./radius.js";
|
|
4
4
|
import type { MaterialOverrides } from "./material-options.js";
|
|
5
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
5
6
|
export interface SelectOption {
|
|
6
7
|
readonly value: string;
|
|
7
8
|
readonly label: string;
|
|
8
9
|
readonly disabled?: boolean;
|
|
9
10
|
}
|
|
10
|
-
export interface SelectProps extends Omit<AriaSelectProps<SelectOption>, ControlOverrides | "value" | "defaultValue" | "onChange" | "selectedKey" | "defaultSelectedKey" | "onSelectionChange" | "disabledKeys" | "selectionMode">, ControlProps, FieldProps, RadiusProps, MaterialOverrides {
|
|
11
|
+
export interface SelectProps extends Omit<AriaSelectProps<SelectOption>, ControlOverrides | "value" | "defaultValue" | "onChange" | "selectedKey" | "defaultSelectedKey" | "onSelectionChange" | "disabledKeys" | "selectionMode">, ControlProps, FieldProps, RadiusProps, MaterialOverrides, ShadowOverrides {
|
|
11
12
|
readonly options: readonly SelectOption[];
|
|
12
13
|
readonly value?: string | null;
|
|
13
14
|
readonly defaultValue?: string | null;
|
package/dist/select.js
CHANGED
|
@@ -7,16 +7,34 @@ import { SurfaceButton } from "./control-surface.js";
|
|
|
7
7
|
import { Surface } from "./surface.js";
|
|
8
8
|
import { ScrollArea } from "./scroll-area.js";
|
|
9
9
|
import { overlayMotionClass, useControlTransition, useOverlayTransition } from "./motion-style.js";
|
|
10
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
11
|
+
import { resolveDirectionalPlacement } from "./overlay-placement.js";
|
|
10
12
|
/** Single selection from string-valued options; keyboard navigation and typeahead stay native to React Aria. */
|
|
11
|
-
export const Select = forwardRef(function Select({ label, description, errorMessage, disabled, required, invalid, options, value, defaultValue, onChange, size, color, radius, style, material, ...properties }, ref) {
|
|
13
|
+
export const Select = forwardRef(function Select({ label, description, errorMessage, disabled, required, invalid, options, value, defaultValue, onChange, size, color, radius, style, material, shadow, ...properties }, ref) {
|
|
12
14
|
const theme = useControlTheme({ size, color, radius });
|
|
13
15
|
const transition = useControlTransition();
|
|
14
16
|
const overlayTransition = useOverlayTransition();
|
|
15
|
-
|
|
17
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
18
|
+
const optionDependencies = [
|
|
19
|
+
theme.transition.transitionDuration,
|
|
20
|
+
theme.transition.transitionTimingFunction,
|
|
21
|
+
theme.transition.transitionProperty,
|
|
22
|
+
theme.gap,
|
|
23
|
+
theme.height,
|
|
24
|
+
theme.spacing,
|
|
25
|
+
theme.radius,
|
|
26
|
+
theme.focusColor,
|
|
27
|
+
theme.foreground,
|
|
28
|
+
theme.paints.palette.rest.background,
|
|
29
|
+
theme.paints.palette.rest.color,
|
|
30
|
+
theme.paints.palette.hover.background,
|
|
31
|
+
theme.paints.palette.hover.color
|
|
32
|
+
];
|
|
33
|
+
return _jsx(AriaSelect, { ...properties, ref: ref, value: value, defaultValue: defaultValue, onChange: key => onChange?.(key == null ? null : String(key)), disabledKeys: options.filter(option => option.disabled).map(option => option.value), isDisabled: disabled, isRequired: required, isInvalid: invalid, style: fieldStyle(theme, disabled, style), children: state => _jsxs(_Fragment, { children: [_jsx(FieldLabel, { label: label }), _jsxs(Button, { render: (native, button) => _jsx(SurfaceButton, { native: native, material: material, shadow: shadow, paint: controlPaint(theme, state.isOpen || button.isFocused, state.isInvalid, button.isHovered) }), style: button => ({
|
|
16
34
|
...controlStyle(theme, state.isOpen || button.isFocused, state.isInvalid, button.isHovered, button.isFocusVisible),
|
|
17
35
|
display: "flex", alignItems: "center", justifyContent: "space-between", gap: theme.gap,
|
|
18
36
|
cursor: disabled ? "not-allowed" : "pointer", textAlign: "start"
|
|
19
|
-
}), children: [_jsx(SelectValue, { style: ({ isPlaceholder }) => ({ opacity: isPlaceholder ? 0.6 : 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }) }), _jsx(motion.svg, { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", initial: false, animate: { rotate: state.isOpen ? 180 : 0 }, transition: transition, style: { flexShrink: 0 }, children: _jsx("path", { d: "m2 4 4 4 4-4" }) })] }), _jsx(Popover, { className: overlayMotionClass, placement: "bottom start", offset: theme.gap, maxHeight: 280 + theme.gap * 2, style: { ...overlayTransition, width: "var(--trigger-width)", maxWidth: "calc(100vw - 16px)" }, children: _jsx(Surface, { style: { padding: theme.gap, display: "flex", flexDirection: "column", maxHeight: "inherit", boxSizing: "border-box" }, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { items: options, style: { display: "grid", gap: theme.gap, outline: "none", fontSize: theme.fontSize, color: theme.foreground }, children: option => _jsx(ListBoxItem, { id: option.value, textValue: option.label, style: item => ({
|
|
37
|
+
}), children: [_jsx(SelectValue, { style: ({ isPlaceholder }) => ({ opacity: isPlaceholder ? 0.6 : 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }) }), _jsx(motion.svg, { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", initial: false, animate: { rotate: state.isOpen ? 180 : 0 }, transition: transition, style: { flexShrink: 0 }, children: _jsx("path", { d: "m2 4 4 4 4-4" }) })] }), _jsx(Popover, { dir: direction, className: overlayMotionClass, placement: resolveDirectionalPlacement("bottom start", direction), offset: theme.gap, maxHeight: 280 + theme.gap * 2, style: { ...overlayTransition, width: "var(--trigger-width)", maxWidth: "calc(100vw - 16px)" }, children: _jsx(Surface, { dir: direction, style: { padding: theme.gap, display: "flex", flexDirection: "column", maxHeight: "inherit", boxSizing: "border-box" }, children: _jsx(ScrollArea, { style: { flex: "1 1 auto", minHeight: 0 }, children: _jsx(ListBox, { items: options, dependencies: optionDependencies, shouldFocusOnHover: false, style: { display: "grid", gap: theme.gap, outline: "none", fontSize: theme.fontSize, color: theme.foreground }, children: option => _jsx(ListBoxItem, { id: option.value, textValue: option.label, style: item => ({
|
|
20
38
|
...theme.transition,
|
|
21
39
|
display: "flex", alignItems: "center", justifyContent: "space-between", gap: theme.gap,
|
|
22
40
|
minHeight: theme.height, paddingInline: Math.max(8, theme.spacing), boxSizing: "border-box",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ScaleLevel } from "./scale.js";
|
|
2
|
+
/** Optional outer-shadow values expressed directly or relative to Appearance. */
|
|
3
|
+
export interface ShadowOptions {
|
|
4
|
+
readonly x?: ScaleLevel | number;
|
|
5
|
+
readonly y?: ScaleLevel | number;
|
|
6
|
+
readonly blur?: ScaleLevel | number;
|
|
7
|
+
readonly spread?: ScaleLevel | number;
|
|
8
|
+
readonly opacity?: ScaleLevel | number;
|
|
9
|
+
}
|
|
10
|
+
/** Grouped shadow customization exposed by components built on Surface. */
|
|
11
|
+
export interface ShadowOverrides {
|
|
12
|
+
/** Omission or true uses Appearance defaults; false removes the shadow. */
|
|
13
|
+
readonly shadow?: boolean | ShadowOptions;
|
|
14
|
+
}
|
|
15
|
+
/** Resolves shadow values from the active Appearance branch. */
|
|
16
|
+
export declare function useShadowOptions(values?: ShadowOptions): {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
blur: number;
|
|
20
|
+
spread: number;
|
|
21
|
+
opacity: number;
|
|
22
|
+
};
|
|
23
|
+
export type ResolvedShadow = ReturnType<typeof useShadowOptions>;
|
|
24
|
+
/** Serializes one resolved neutral-black outer shadow. */
|
|
25
|
+
export declare function shadowStyle({ x, y, blur, spread, opacity }: ResolvedShadow): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { appearanceLimits } from "@phreshos/core";
|
|
2
|
+
import { useAppearance, useThemedValue } from "./ui-provider.js";
|
|
3
|
+
import { isScaleLevel, scale } from "./scale.js";
|
|
4
|
+
/** Resolves shadow values from the active Appearance branch. */
|
|
5
|
+
export function useShadowOptions(values = {}) {
|
|
6
|
+
const appearance = useAppearance();
|
|
7
|
+
const defaults = useThemedValue(appearance.shadow);
|
|
8
|
+
const limits = appearanceLimits.shadow;
|
|
9
|
+
return {
|
|
10
|
+
x: resolve(values.x, defaults.x, limits.x),
|
|
11
|
+
y: resolve(values.y, defaults.y, limits.y),
|
|
12
|
+
blur: resolve(values.blur, defaults.blur, limits.blur),
|
|
13
|
+
spread: resolve(values.spread, defaults.spread, limits.spread),
|
|
14
|
+
opacity: resolve(values.opacity, defaults.opacity, limits.opacity)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Serializes one resolved neutral-black outer shadow. */
|
|
18
|
+
export function shadowStyle({ x, y, blur, spread, opacity }) {
|
|
19
|
+
return opacity === 0 ? "none" : `${x}px ${y}px ${blur}px ${spread}px rgba(0, 0, 0, ${opacity})`;
|
|
20
|
+
}
|
|
21
|
+
function resolve(value, base, range) {
|
|
22
|
+
const resolved = isScaleLevel(value) ? scale(base, value) : value ?? base;
|
|
23
|
+
const finite = Number.isFinite(resolved) ? resolved : base;
|
|
24
|
+
return Math.min(range.maximum, Math.max(range.minimum, finite));
|
|
25
|
+
}
|
package/dist/slider.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
export interface SliderProps extends Omit<
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import type { ControlProps, FieldProps } from "./control.js";
|
|
3
|
+
export interface SliderProps extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "className" | "color" | "defaultValue" | "onChange" | "style">, ControlProps, Pick<FieldProps, "label" | "description"> {
|
|
4
|
+
readonly value?: number;
|
|
5
|
+
readonly defaultValue?: number;
|
|
6
|
+
readonly minValue?: number;
|
|
7
|
+
readonly maxValue?: number;
|
|
8
|
+
readonly step?: number;
|
|
9
|
+
readonly orientation?: "horizontal" | "vertical";
|
|
4
10
|
readonly name?: string;
|
|
11
|
+
readonly form?: string;
|
|
12
|
+
readonly formatOptions?: Intl.NumberFormatOptions;
|
|
13
|
+
readonly onChange?: (value: number) => void;
|
|
14
|
+
readonly onChangeEnd?: (value: number) => void;
|
|
5
15
|
}
|
|
6
16
|
/** One numeric value with pointer, touch, keyboard, and form support. */
|
|
7
17
|
export declare const Slider: import("react").ForwardRefExoticComponent<SliderProps & import("react").RefAttributes<HTMLDivElement>>;
|
package/dist/slider.js
CHANGED
|
@@ -1,38 +1,70 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { usePreferences } from "./appearance-provider.js";
|
|
2
|
+
import { Slider as BaseSlider } from "@base-ui/react/slider";
|
|
3
|
+
import { DirectionProvider as BaseDirectionProvider } from "@base-ui/react/direction-provider";
|
|
4
|
+
import { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
5
|
+
import { fieldStyle, useControlTheme } from "./control.js";
|
|
6
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
8
7
|
/** One numeric value with pointer, touch, keyboard, and form support. */
|
|
9
|
-
export const Slider = forwardRef(function Slider({ label, description, name, disabled, size, color, style, orientation = "horizontal", ...properties }, ref) {
|
|
8
|
+
export const Slider = forwardRef(function Slider({ label, description, name, form, disabled, size, color, style, orientation = "horizontal", value, defaultValue, minValue = 0, maxValue = 100, step = 1, formatOptions, onChange, onChangeEnd, ...properties }, ref) {
|
|
10
9
|
const theme = useControlTheme({ size, color });
|
|
10
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
11
11
|
const descriptionId = useId();
|
|
12
|
+
const input = useRef(null);
|
|
13
|
+
const initialValue = useRef(defaultValue ?? minValue);
|
|
14
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(initialValue.current);
|
|
15
|
+
const [hovered, setHovered] = useState(false);
|
|
12
16
|
const vertical = orientation === "vertical";
|
|
13
17
|
const diameter = theme.fontSize + 6;
|
|
14
|
-
const { animations } = usePreferences();
|
|
15
|
-
const transition = useControlTransition();
|
|
16
18
|
const rail = Math.max(4, Math.round(diameter / 3));
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
const describedBy = [properties["aria-describedby"], description != null ? descriptionId : null].filter(Boolean).join(" ") || undefined;
|
|
20
|
+
const controlled = value !== undefined;
|
|
21
|
+
const resolvedValue = controlled ? value : uncontrolledValue;
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const formElement = input.current?.form;
|
|
24
|
+
if (controlled || formElement == null)
|
|
25
|
+
return;
|
|
26
|
+
const reset = () => setUncontrolledValue(initialValue.current);
|
|
27
|
+
formElement.addEventListener("reset", reset);
|
|
28
|
+
return () => formElement.removeEventListener("reset", reset);
|
|
29
|
+
}, [controlled]);
|
|
30
|
+
const root = _jsxs(BaseSlider.Root, { ...properties, ref: ref, value: resolvedValue, min: minValue, max: maxValue, step: step, name: name, form: form, disabled: disabled, orientation: orientation, format: formatOptions, onValueChange: next => {
|
|
31
|
+
if (!controlled)
|
|
32
|
+
setUncontrolledValue(next);
|
|
33
|
+
onChange?.(next);
|
|
34
|
+
}, onValueCommitted: next => onChangeEnd?.(next), style: fieldStyle(theme, disabled, style), children: [_jsxs("div", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: theme.gap }, children: [label != null && _jsx(BaseSlider.Label, { style: { fontWeight: 550 }, children: label }), _jsx(BaseSlider.Value, { style: { fontVariantNumeric: "tabular-nums", opacity: 0.7 } })] }), _jsx(BaseSlider.Control, { style: {
|
|
35
|
+
position: "relative",
|
|
36
|
+
display: "flex",
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
justifyContent: "center",
|
|
39
|
+
touchAction: "none",
|
|
40
|
+
userSelect: "none",
|
|
41
|
+
width: vertical ? theme.height : "100%",
|
|
42
|
+
height: vertical ? 160 : theme.height
|
|
43
|
+
}, children: _jsxs(BaseSlider.Track, { style: {
|
|
44
|
+
position: "relative",
|
|
45
|
+
width: vertical ? rail : "100%",
|
|
46
|
+
height: vertical ? "100%" : rail,
|
|
47
|
+
borderRadius: rail,
|
|
48
|
+
background: theme.paints.neutral.rest.background
|
|
49
|
+
}, children: [_jsx(BaseSlider.Indicator, { style: {
|
|
50
|
+
...theme.transition,
|
|
51
|
+
borderRadius: rail,
|
|
52
|
+
background: theme.paints.palette.rest.background
|
|
53
|
+
} }), _jsx(BaseSlider.Thumb, { inputRef: input, "aria-label": properties["aria-label"], "aria-labelledby": properties["aria-labelledby"], "aria-describedby": describedBy, onPointerEnter: () => setHovered(true), onPointerLeave: () => setHovered(false), style: state => {
|
|
54
|
+
const paint = state.dragging ? theme.paints.palette.pressed : hovered ? theme.paints.palette.hover : theme.paints.palette.rest;
|
|
55
|
+
return {
|
|
56
|
+
...theme.transition,
|
|
57
|
+
width: diameter,
|
|
58
|
+
height: diameter,
|
|
59
|
+
borderRadius: "50%",
|
|
60
|
+
boxSizing: "border-box",
|
|
61
|
+
background: paint.color,
|
|
62
|
+
border: `3px solid ${paint.background}`,
|
|
63
|
+
outline: state.focused ? `1px solid ${theme.focusColor}` : "none",
|
|
64
|
+
outlineOffset: 1,
|
|
65
|
+
cursor: state.disabled ? "not-allowed" : state.dragging ? "grabbing" : "grab",
|
|
66
|
+
transform: `scale(${state.dragging ? 0.92 : hovered ? 1.08 : 1})`
|
|
67
|
+
};
|
|
68
|
+
} })] }) }), description != null && _jsx("span", { id: descriptionId, style: { fontSize: "0.92em", opacity: 0.7 }, children: description })] });
|
|
69
|
+
return _jsx(BaseDirectionProvider, { direction: direction, children: root });
|
|
38
70
|
});
|
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 a UIProvider");
|
|
7
7
|
return scale(appearance.spacing, value);
|
|
8
8
|
}
|
package/dist/surface-edge.d.ts
CHANGED
package/dist/surface-edge.js
CHANGED
|
@@ -1,60 +1,57 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment
|
|
3
|
-
import {
|
|
4
|
-
import { usePaintTransition } from "./motion-style.js";
|
|
2
|
+
import { Fragment } from "react";
|
|
3
|
+
import { useTransitionTiming } from "./motion-style.js";
|
|
5
4
|
import { scale } from "./scale.js";
|
|
5
|
+
const edgeLayer = {
|
|
6
|
+
position: "absolute",
|
|
7
|
+
zIndex: 1,
|
|
8
|
+
inset: 0,
|
|
9
|
+
boxSizing: "border-box",
|
|
10
|
+
borderRadius: "inherit",
|
|
11
|
+
pointerEvents: "none"
|
|
12
|
+
};
|
|
13
|
+
const edgeScale = 0.8;
|
|
14
|
+
const outerEdgeThickness = edgeScale;
|
|
15
|
+
const illuminatedEdgeThickness = 0.3;
|
|
16
|
+
const illuminatedEdgeBoundary = Math.round((outerEdgeThickness + illuminatedEdgeThickness) * 100) / 100;
|
|
17
|
+
const horizontalIllumination = "linear-gradient(90deg, var(--phreshos-surface-edge-light-minimum) 0%, var(--phreshos-surface-edge-light-minimum) 12%, var(--phreshos-surface-edge-light-soft) 34%, var(--phreshos-surface-edge-light-peak) 50%, var(--phreshos-surface-edge-light-soft) 66%, var(--phreshos-surface-edge-light-minimum) 88%, var(--phreshos-surface-edge-light-minimum) 100%)";
|
|
18
|
+
const edgeMask = "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)";
|
|
6
19
|
/** Paints the boundary owned by one Surface from the material it contains. */
|
|
7
20
|
export function SurfaceEdge({ material }) {
|
|
8
|
-
const
|
|
21
|
+
const timing = useTransitionTiming();
|
|
9
22
|
const visible = material.opacity > 0;
|
|
10
|
-
const palette = useRef(null);
|
|
11
|
-
const [colors, setColors] = useState(null);
|
|
12
|
-
const updatePalette = useCallback(() => {
|
|
13
|
-
const base = palette.current;
|
|
14
|
-
const view = base?.ownerDocument.defaultView;
|
|
15
|
-
if (!base || !view)
|
|
16
|
-
return;
|
|
17
|
-
const computed = view.getComputedStyle(base);
|
|
18
|
-
const background = computed.fill;
|
|
19
|
-
const foreground = computed.color;
|
|
20
|
-
setColors(previous => previous?.background === background && previous.foreground === foreground ? previous : {
|
|
21
|
-
...orderColors(background, foreground),
|
|
22
|
-
background,
|
|
23
|
-
foreground,
|
|
24
|
-
lightness: Math.max(0, Math.min(1, colorLightness(background)))
|
|
25
|
-
});
|
|
26
|
-
}, []);
|
|
27
|
-
useLayoutEffect(updatePalette);
|
|
28
|
-
useLayoutEffect(() => {
|
|
29
|
-
const base = palette.current;
|
|
30
|
-
if (!base)
|
|
31
|
-
return;
|
|
32
|
-
const complete = (event) => {
|
|
33
|
-
if (event.target === base && (event.propertyName === "fill" || event.propertyName === "color"))
|
|
34
|
-
updatePalette();
|
|
35
|
-
};
|
|
36
|
-
base.addEventListener("transitionend", complete);
|
|
37
|
-
return () => base.removeEventListener("transitionend", complete);
|
|
38
|
-
}, [updatePalette, visible]);
|
|
39
23
|
if (!visible)
|
|
40
24
|
return null;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
opacity
|
|
50
|
-
|
|
51
|
-
WebkitMask: "linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)",
|
|
25
|
+
const opacity = Math.min(1, scale(material.opacity, "xlarge"));
|
|
26
|
+
const peak = illumination(material.color, 92);
|
|
27
|
+
return _jsxs(Fragment, { children: [_jsx("span", { "data-surface-edge-light": "", "aria-hidden": "true", style: {
|
|
28
|
+
...timing,
|
|
29
|
+
...edgeLayer,
|
|
30
|
+
transitionProperty: "opacity",
|
|
31
|
+
padding: illuminatedEdgeBoundary,
|
|
32
|
+
background: horizontalIllumination,
|
|
33
|
+
opacity,
|
|
34
|
+
WebkitMask: edgeMask,
|
|
52
35
|
WebkitMaskComposite: "xor",
|
|
53
|
-
mask:
|
|
54
|
-
maskComposite: "exclude"
|
|
36
|
+
mask: edgeMask,
|
|
37
|
+
maskComposite: "exclude",
|
|
38
|
+
"--phreshos-surface-edge-light-peak": peak,
|
|
39
|
+
"--phreshos-surface-edge-light-soft": illumination(material.color, 56),
|
|
40
|
+
"--phreshos-surface-edge-light-minimum": illumination(material.color, 24)
|
|
41
|
+
} }), _jsx("span", { "data-surface-edge": "", "aria-hidden": "true", style: {
|
|
42
|
+
...timing,
|
|
43
|
+
...edgeLayer,
|
|
44
|
+
transitionProperty: "border-color, opacity",
|
|
45
|
+
borderStyle: "solid",
|
|
46
|
+
borderWidth: outerEdgeThickness,
|
|
47
|
+
borderColor: "var(--phreshos-surface-edge-dark)",
|
|
48
|
+
opacity,
|
|
49
|
+
"--phreshos-surface-edge-dark": darkEdge(material.color)
|
|
55
50
|
} })] });
|
|
56
51
|
}
|
|
57
|
-
function
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
function darkEdge(color) {
|
|
53
|
+
return `color-mix(in srgb, color-mix(in oklch, ${color} 72%, black) 38%, transparent)`;
|
|
54
|
+
}
|
|
55
|
+
function illumination(color, opacity) {
|
|
56
|
+
return `color-mix(in srgb, color-mix(in oklch, ${color} 64%, white) ${opacity}%, transparent)`;
|
|
60
57
|
}
|
package/dist/surface.d.ts
CHANGED
|
@@ -2,8 +2,11 @@ import type { ComponentPropsWithRef, CSSProperties, ElementType, ReactElement, R
|
|
|
2
2
|
import { type Color } from "./color.js";
|
|
3
3
|
import { type MaterialOverrides } from "./material-options.js";
|
|
4
4
|
import { type RadiusProps } from "./radius.js";
|
|
5
|
+
import { type ShadowOverrides } from "./shadow-options.js";
|
|
6
|
+
import type { Direction } from "./direction.js";
|
|
5
7
|
export type { MaterialOptions } from "./material-options.js";
|
|
6
|
-
export
|
|
8
|
+
export type { ShadowOptions } from "./shadow-options.js";
|
|
9
|
+
export interface SurfaceOwnProps extends MaterialOverrides, ShadowOverrides, RadiusProps {
|
|
7
10
|
readonly color?: Color;
|
|
8
11
|
}
|
|
9
12
|
/**
|
|
@@ -13,6 +16,7 @@ export interface SurfaceOwnProps extends MaterialOverrides, RadiusProps {
|
|
|
13
16
|
*/
|
|
14
17
|
export interface SurfaceHostProps {
|
|
15
18
|
readonly children?: ReactNode;
|
|
19
|
+
readonly dir?: Direction;
|
|
16
20
|
readonly style?: CSSProperties;
|
|
17
21
|
}
|
|
18
22
|
export type SurfaceHost = ElementType<SurfaceHostProps>;
|
package/dist/surface.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createElement, forwardRef, useId } from "react";
|
|
3
|
-
import { useAppearance, useThemedValue } from "./
|
|
3
|
+
import { useAppearance, useThemedValue } from "./ui-provider.js";
|
|
4
4
|
import { useResolveColor } from "./color.js";
|
|
5
5
|
import { useMaterialOptions } from "./material-options.js";
|
|
6
6
|
import { MaterialPaint } from "./material-paint.js";
|
|
7
7
|
import MotionStyle, { useVisualTransition } from "./motion-style.js";
|
|
8
8
|
import { resolveRadius } from "./radius.js";
|
|
9
|
+
import { shadowStyle, useShadowOptions } from "./shadow-options.js";
|
|
9
10
|
import { SurfaceEdge } from "./surface-edge.js";
|
|
10
|
-
/** One material-owning element. The host is a div unless `as` selects another element. */
|
|
11
|
-
const SurfaceRoot = forwardRef(function Surface({ as: Element = "div", color, material: options, radius, children, style, ...properties }, ref) {
|
|
11
|
+
/** One material- and shadow-owning element. The host is a div unless `as` selects another element. */
|
|
12
|
+
const SurfaceRoot = forwardRef(function Surface({ as: Element = "div", color, material: options, shadow: shadowOptions, radius, children, style, ...properties }, ref) {
|
|
12
13
|
const appearance = useAppearance();
|
|
13
14
|
const transition = useVisualTransition();
|
|
14
15
|
const material = useResolvedSurface(color, options);
|
|
16
|
+
const resolvedShadow = useShadowOptions(typeof shadowOptions === "object" ? shadowOptions : undefined);
|
|
17
|
+
const shadow = shadowOptions === false ? "none" : shadowStyle(resolvedShadow);
|
|
15
18
|
const resolvedRadius = resolveRadius(radius ?? "medium", appearance);
|
|
16
19
|
return createElement(Element, {
|
|
17
20
|
...properties,
|
|
@@ -19,20 +22,22 @@ const SurfaceRoot = forwardRef(function Surface({ as: Element = "div", color, ma
|
|
|
19
22
|
style: {
|
|
20
23
|
...transition,
|
|
21
24
|
...style,
|
|
22
|
-
background: "transparent",
|
|
25
|
+
background: material.enabled ? "transparent" : material.color,
|
|
26
|
+
boxShadow: shadow,
|
|
23
27
|
color: style?.color ?? material.foreground,
|
|
24
28
|
borderRadius: radius === undefined ? style?.borderRadius ?? resolvedRadius : resolvedRadius,
|
|
25
29
|
position: style?.position ?? "relative",
|
|
26
30
|
isolation: "isolate"
|
|
27
31
|
}
|
|
28
|
-
}, _jsx(SurfaceLayers, { material: material }), _jsx(SurfaceEdge, { material: material }), children);
|
|
32
|
+
}, material.enabled && _jsx(SurfaceLayers, { material: material }), material.enabled && _jsx(SurfaceEdge, { material: material }), children);
|
|
29
33
|
});
|
|
30
34
|
export const Surface = SurfaceRoot;
|
|
31
35
|
function useResolvedSurface(color, options) {
|
|
32
36
|
const appearance = useAppearance();
|
|
33
|
-
const material = useMaterialOptions(options);
|
|
37
|
+
const material = useMaterialOptions(typeof options === "object" ? options : undefined);
|
|
34
38
|
return {
|
|
35
39
|
...material,
|
|
40
|
+
enabled: options !== false,
|
|
36
41
|
color: useResolveColor(color),
|
|
37
42
|
foreground: useThemedValue(appearance.colors).foreground
|
|
38
43
|
};
|
package/dist/switch.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { SwitchFieldProps } from "react-aria-components";
|
|
2
2
|
import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
|
|
3
3
|
import type { MaterialOverrides } from "./material-options.js";
|
|
4
|
-
|
|
4
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
5
|
+
export interface SwitchProps extends Omit<SwitchFieldProps, ControlOverrides | "isReadOnly" | "isSelected" | "defaultSelected">, ControlProps, FieldProps, MaterialOverrides, ShadowOverrides {
|
|
5
6
|
readonly checked?: boolean;
|
|
6
7
|
readonly defaultChecked?: boolean;
|
|
7
8
|
readonly readOnly?: boolean;
|
package/dist/switch.js
CHANGED
|
@@ -3,8 +3,10 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { SwitchField, SwitchButton } from "react-aria-components";
|
|
4
4
|
import { FieldFeedback, fieldStyle, useControlTheme } from "./control.js";
|
|
5
5
|
import { ToggleIndicator, toggleStyle } from "./toggle-indicator.js";
|
|
6
|
+
import { resolveDirection, useDirection } from "./direction.js";
|
|
6
7
|
/** An on/off setting. onChange receives the next boolean value. */
|
|
7
|
-
export const Switch = forwardRef(function Switch({ label, description, errorMessage, disabled, required, invalid, readOnly, checked, defaultChecked, size, color, style, material, ...properties }, ref) {
|
|
8
|
+
export const Switch = forwardRef(function Switch({ label, description, errorMessage, disabled, required, invalid, readOnly, checked, defaultChecked, size, color, style, material, shadow, ...properties }, ref) {
|
|
8
9
|
const theme = useControlTheme({ size, color });
|
|
9
|
-
|
|
10
|
+
const direction = resolveDirection(properties.dir, useDirection());
|
|
11
|
+
return _jsxs(SwitchField, { ...properties, ref: ref, isDisabled: disabled, isRequired: required, isInvalid: invalid, isReadOnly: readOnly, isSelected: checked, defaultSelected: defaultChecked, style: state => fieldStyle(theme, state.isDisabled, style), children: [_jsx(SwitchButton, { style: state => toggleStyle(theme, state.isDisabled, state.isReadOnly), children: state => _jsxs(_Fragment, { children: [_jsx(ToggleIndicator, { kind: "switch", direction: direction, material: material, shadow: shadow, theme: theme, selected: state.isSelected, focused: state.isFocusVisible, invalid: state.isInvalid, hovered: !state.isDisabled && !state.isReadOnly && state.isHovered, pressed: !state.isDisabled && !state.isReadOnly && state.isPressed }), label] }) }), _jsx(FieldFeedback, { theme: theme, description: description, errorMessage: errorMessage })] });
|
|
10
12
|
});
|
package/dist/text-control.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ import type { TextFieldProps } from "react-aria-components";
|
|
|
2
2
|
import type { ControlOverrides, ControlProps, FieldProps } from "./control.js";
|
|
3
3
|
import type { RadiusProps } from "./radius.js";
|
|
4
4
|
import type { MaterialOverrides } from "./material-options.js";
|
|
5
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
5
6
|
/** Shared contract for native text-entry controls. */
|
|
6
|
-
export interface TextControlProps extends Omit<TextFieldProps, ControlOverrides | "isReadOnly">, ControlProps, FieldProps, RadiusProps, MaterialOverrides {
|
|
7
|
+
export interface TextControlProps extends Omit<TextFieldProps, ControlOverrides | "isReadOnly">, ControlProps, FieldProps, RadiusProps, MaterialOverrides, ShadowOverrides {
|
|
7
8
|
readonly placeholder?: string;
|
|
8
9
|
readonly readOnly?: boolean;
|
|
9
10
|
}
|
package/dist/textarea.js
CHANGED
|
@@ -5,9 +5,9 @@ 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 multiline text control, vertically resizable without escaping its width. */
|
|
8
|
-
export const Textarea = forwardRef(function Textarea({ label, description, errorMessage, disabled, readOnly, required, invalid, size, color, radius, style, className, placeholder, rows = 4, material, ...properties }, ref) {
|
|
8
|
+
export const Textarea = forwardRef(function Textarea({ label, description, errorMessage, disabled, readOnly, required, invalid, size, color, radius, style, className, placeholder, rows = 4, 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(AriaTextarea, { ref: ref, placeholder: placeholder, rows: rows, className: textControlClass, render: (native, state) => _jsx(SurfaceField, { material: material, radius: theme.radius, paint: controlPaint(theme, state.isFocused, state.isInvalid, state.isHovered), children: _jsx("textarea", { ...native, style: { ...native.style, borderRadius: "inherit", background: "transparent" } }) }), style: state => ({
|
|
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(AriaTextarea, { ref: ref, placeholder: placeholder, rows: rows, 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("textarea", { ...native, style: { ...native.style, borderRadius: "inherit", background: "transparent" } }) }), style: state => ({
|
|
11
11
|
...controlStyle(theme, state.isFocused, state.isInvalid, state.isHovered, state.isFocusVisible),
|
|
12
12
|
height: "auto",
|
|
13
13
|
minHeight: theme.height,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { CSSProperties } from "react";
|
|
2
2
|
import type { ControlTheme } from "./control.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { MaterialOverrides } from "./material-options.js";
|
|
4
|
+
import type { ShadowOverrides } from "./shadow-options.js";
|
|
5
|
+
import type { Direction } from "./direction.js";
|
|
4
6
|
/** Shared paint only. Selection, focus, validation, and native input behavior belong to React Aria. */
|
|
5
|
-
export declare function ToggleIndicator({ kind, selected, indeterminate, focused, invalid, hovered, pressed, theme, material: options }: Readonly<{
|
|
7
|
+
export declare function ToggleIndicator({ kind, direction, selected, indeterminate, focused, invalid, hovered, pressed, theme, material: options, shadow }: Readonly<{
|
|
6
8
|
kind: "checkbox" | "radio" | "switch";
|
|
9
|
+
direction?: Direction;
|
|
7
10
|
selected: boolean;
|
|
8
11
|
indeterminate?: boolean;
|
|
9
12
|
focused: boolean;
|
|
@@ -11,6 +14,5 @@ export declare function ToggleIndicator({ kind, selected, indeterminate, focused
|
|
|
11
14
|
hovered?: boolean;
|
|
12
15
|
pressed?: boolean;
|
|
13
16
|
theme: ControlTheme;
|
|
14
|
-
|
|
15
|
-
}>): import("react").JSX.Element;
|
|
17
|
+
} & MaterialOverrides & ShadowOverrides>): import("react").JSX.Element;
|
|
16
18
|
export declare function toggleStyle(theme: ControlTheme, disabled: boolean, readOnly: boolean): CSSProperties;
|
package/dist/toggle-indicator.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { motion } from "motion/react";
|
|
3
|
-
import { useLocale } from "react-aria-components";
|
|
4
3
|
import { useControlTransition } from "./motion-style.js";
|
|
5
|
-
import { usePreferences } from "./
|
|
4
|
+
import { usePreferences } from "./ui-provider.js";
|
|
6
5
|
import { Surface } from "./surface.js";
|
|
7
6
|
/** Shared paint only. Selection, focus, validation, and native input behavior belong to React Aria. */
|
|
8
|
-
export function ToggleIndicator({ kind, selected, indeterminate = false, focused, invalid = false, hovered = false, pressed = false, theme, material: options }) {
|
|
7
|
+
export function ToggleIndicator({ kind, direction = "ltr", selected, indeterminate = false, focused, invalid = false, hovered = false, pressed = false, theme, material: options, shadow }) {
|
|
9
8
|
const { animations } = usePreferences();
|
|
10
9
|
const transition = useControlTransition();
|
|
11
|
-
const { direction } = useLocale();
|
|
12
10
|
const diameter = theme.fontSize + 6;
|
|
13
11
|
const active = selected || indeterminate;
|
|
14
12
|
const paints = invalid ? theme.paints.danger : active ? theme.paints.palette : theme.paints.neutral;
|
|
@@ -17,7 +15,7 @@ export function ToggleIndicator({ kind, selected, indeterminate = false, focused
|
|
|
17
15
|
const switching = kind === "switch";
|
|
18
16
|
const thumbWidth = diameter - 6 + (pressed && animations ? 3 : 0);
|
|
19
17
|
const travel = (diameter * 2 - thumbWidth) / 2 - 3;
|
|
20
|
-
return _jsx(Surface, { as: motion.span, material: options, color: paint.background, "aria-hidden": "true", initial: false, animate: { scale: !animations || switching ? 1 : pressed ? 0.94 : hovered ? 1.03 : 1 }, transition: transition, style: {
|
|
18
|
+
return _jsx(Surface, { as: motion.span, material: options, shadow: shadow, color: paint.background, "aria-hidden": "true", initial: false, animate: { scale: !animations || switching ? 1 : pressed ? 0.94 : hovered ? 1.03 : 1 }, transition: transition, style: {
|
|
21
19
|
color: paint.color,
|
|
22
20
|
...theme.transition,
|
|
23
21
|
display: "inline-grid",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ComponentProps, CSSProperties, ReactNode } from "react";
|
|
2
|
+
import type { TooltipProps as AriaTooltipProps, TooltipTriggerComponentProps as AriaTooltipTriggerProps } from "react-aria-components";
|
|
3
|
+
import { type ButtonProps } from "./button.js";
|
|
4
|
+
import { type SurfaceOwnProps } from "./surface.js";
|
|
5
|
+
export type TooltipRootProps = AriaTooltipTriggerProps;
|
|
6
|
+
export declare function TooltipRoot(properties: TooltipRootProps): import("react").JSX.Element;
|
|
7
|
+
export type TooltipTriggerProps = ButtonProps;
|
|
8
|
+
export declare const TooltipTrigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
9
|
+
export interface TooltipContentProps extends Omit<AriaTooltipProps, "children" | "className" | "color" | "style">, SurfaceOwnProps {
|
|
10
|
+
readonly children?: ReactNode;
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
readonly style?: CSSProperties;
|
|
13
|
+
}
|
|
14
|
+
export declare const TooltipContent: import("react").ForwardRefExoticComponent<TooltipContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
15
|
+
/** A description shown from the focus and hover state of its trigger. */
|
|
16
|
+
export declare const Tooltip: typeof TooltipRoot & {
|
|
17
|
+
Root: typeof TooltipRoot;
|
|
18
|
+
Trigger: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
19
|
+
Content: import("react").ForwardRefExoticComponent<TooltipContentProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
20
|
+
};
|
|
21
|
+
export type TooltipProps = ComponentProps<typeof TooltipRoot>;
|