@phreshos/react-ui 0.1.27 → 0.1.29
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 +40 -21
- package/dist/appearance-context.d.ts +47 -16
- package/dist/appearance-context.js +70 -20
- package/dist/appearance.d.ts +6 -0
- package/dist/appearance.js +11 -0
- package/dist/button.js +6 -10
- package/dist/color.d.ts +7 -5
- package/dist/color.js +37 -12
- package/dist/context-menu.d.ts +4 -1
- package/dist/context-menu.js +30 -3
- package/dist/control.d.ts +16 -2
- package/dist/control.js +34 -20
- package/dist/dialog.js +47 -40
- package/dist/direction.d.ts +9 -1
- package/dist/direction.js +34 -10
- package/dist/field-style.js +2 -1
- package/dist/layout.d.ts +1 -1
- package/dist/main.d.ts +4 -3
- package/dist/main.js +3 -2
- package/dist/material-options.d.ts +10 -3
- package/dist/material-options.js +3 -6
- package/dist/material-paint.d.ts +3 -1
- package/dist/material-paint.js +35 -11
- package/dist/menu.js +30 -18
- package/dist/motion-style.d.ts +6 -8
- package/dist/motion-style.js +15 -31
- package/dist/popover.js +13 -12
- package/dist/preferences.d.ts +4 -0
- package/dist/preferences.js +0 -0
- package/dist/radio.js +4 -3
- package/dist/radius.d.ts +1 -1
- package/dist/scroll-area.js +17 -10
- package/dist/select.js +24 -36
- package/dist/shadow-options.d.ts +9 -3
- package/dist/shadow-options.js +3 -6
- package/dist/slider.js +7 -6
- package/dist/spacing.d.ts +1 -1
- package/dist/surface-edge.d.ts +3 -1
- package/dist/surface-edge.js +3 -5
- package/dist/surface.js +24 -19
- package/dist/toggle-indicator.js +2 -5
- package/dist/tooltip.js +16 -15
- package/dist/ui-provider.d.ts +2 -1
- package/dist/ui-provider.js +9 -7
- package/dist/window-header.d.ts +42 -0
- package/dist/window-header.js +113 -0
- package/package.json +2 -2
package/dist/tooltip.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { Tooltip as AriaTooltip, TooltipTrigger as AriaTooltipTrigger } from "react-aria-components";
|
|
4
|
-
import {
|
|
4
|
+
import { useResolvedAppearance } from "./appearance-context.js";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
6
|
import { controlFontSizes } from "./control.js";
|
|
7
|
-
import { overlayMotionClass,
|
|
7
|
+
import MotionStyle, { overlayMotionClass, overlayTransition } from "./motion-style.js";
|
|
8
8
|
import { scale } from "./scale.js";
|
|
9
9
|
import { Surface } from "./surface.js";
|
|
10
10
|
import { resolveDirection, useDirection } from "./direction.js";
|
|
@@ -16,19 +16,20 @@ export const TooltipTrigger = forwardRef(function TooltipTrigger(properties, ref
|
|
|
16
16
|
return _jsx(Button, { ...properties, ref: ref });
|
|
17
17
|
});
|
|
18
18
|
export const TooltipContent = forwardRef(function TooltipContent({ children, className, color, material, radius, shadow, style, offset, placement = "top", ...properties }, ref) {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
19
|
+
const resolved = useResolvedAppearance();
|
|
20
|
+
const inset = scale(resolved.appearance.spacing, "small");
|
|
21
|
+
const transition = overlayTransition(resolved.transaction, resolved.preferences.animations);
|
|
21
22
|
const direction = resolveDirection(properties.dir, useDirection());
|
|
22
|
-
return _jsx(AriaTooltip, { ...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: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
return _jsxs(_Fragment, { children: [_jsx(MotionStyle, {}), _jsx(AriaTooltip, { ...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: {
|
|
24
|
+
boxSizing: "border-box",
|
|
25
|
+
maxWidth: "28em",
|
|
26
|
+
paddingBlock: inset,
|
|
27
|
+
paddingInline: inset * 1.5,
|
|
28
|
+
outline: "none",
|
|
29
|
+
fontSize: controlFontSizes.small,
|
|
30
|
+
lineHeight: 1.4,
|
|
31
|
+
...style
|
|
32
|
+
}, children: children }) })] });
|
|
32
33
|
});
|
|
33
34
|
/** A description shown from the focus and hover state of its trigger. */
|
|
34
35
|
export const Tooltip = Object.assign(TooltipRoot, {
|
package/dist/ui-provider.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import type { Appearance } from "./appearance.js";
|
|
3
3
|
import { type Direction } from "./direction.js";
|
|
4
|
+
import type { Preferences } from "./preferences.js";
|
|
4
5
|
export { useAppearance, useBrowserPreferences, usePreferences, useThemedValue } from "./appearance-context.js";
|
|
5
6
|
export { useDirection, useDocumentDirection } from "./direction.js";
|
|
6
7
|
/** Establishes only the explicitly supplied UI values for a React subtree. */
|
package/dist/ui-provider.js
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {} from "
|
|
3
|
-
import { AppearanceContext, PreferencesContext } from "./appearance-context.js";
|
|
4
|
-
import { DirectionContext } from "./direction.js";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { AppearanceContext, fixedPreferencesSource, PreferencesContext } from "./appearance-context.js";
|
|
4
|
+
import { DirectionContext, fixedDirectionSource } from "./direction.js";
|
|
5
5
|
export { useAppearance, useBrowserPreferences, usePreferences, useThemedValue } from "./appearance-context.js";
|
|
6
6
|
export { useDirection, useDocumentDirection } from "./direction.js";
|
|
7
7
|
const directionBoundaryStyle = { display: "contents" };
|
|
8
8
|
/** Establishes only the explicitly supplied UI values for a React subtree. */
|
|
9
9
|
export function UIProvider({ appearance, children, direction, preferences }) {
|
|
10
10
|
let subtree = children;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const preferencesSource = useMemo(() => preferences === undefined ? undefined : fixedPreferencesSource(preferences), [preferences]);
|
|
12
|
+
const directionSource = useMemo(() => direction === undefined ? undefined : fixedDirectionSource(direction), [direction]);
|
|
13
|
+
if (preferencesSource !== undefined) {
|
|
14
|
+
subtree = _jsx(PreferencesContext.Provider, { value: preferencesSource, children: subtree });
|
|
13
15
|
}
|
|
14
16
|
if (appearance !== undefined) {
|
|
15
17
|
subtree = _jsx(AppearanceContext.Provider, { value: appearance, children: subtree });
|
|
16
18
|
}
|
|
17
|
-
if (
|
|
18
|
-
subtree = _jsx(DirectionContext.Provider, { value:
|
|
19
|
+
if (directionSource !== undefined) {
|
|
20
|
+
subtree = _jsx(DirectionContext.Provider, { value: directionSource, children: _jsx("div", { dir: direction, style: directionBoundaryStyle, children: subtree }) });
|
|
19
21
|
}
|
|
20
22
|
return subtree;
|
|
21
23
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ComponentProps, HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import { type ButtonProps } from "./button.js";
|
|
3
|
+
export interface WindowHeaderRootProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** Attenuates the identity when this header is not active. */
|
|
5
|
+
readonly active?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** The composable top region of a window; its enclosing Surface owns the material. */
|
|
8
|
+
export declare const WindowHeaderRoot: import("react").ForwardRefExoticComponent<WindowHeaderRootProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
9
|
+
export interface WindowHeaderIdentityProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
10
|
+
readonly icon?: string;
|
|
11
|
+
readonly title?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/** The icon and truncating title share the window's active treatment. */
|
|
14
|
+
export declare const WindowHeaderIdentity: import("react").ForwardRefExoticComponent<WindowHeaderIdentityProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
15
|
+
export type WindowHeaderCenterProps = HTMLAttributes<HTMLDivElement>;
|
|
16
|
+
/** Optional flexible space for application-owned content. */
|
|
17
|
+
export declare const WindowHeaderCenter: import("react").ForwardRefExoticComponent<WindowHeaderCenterProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
18
|
+
export type WindowHeaderActionsProps = HTMLAttributes<HTMLDivElement>;
|
|
19
|
+
/** End-aligned controls that do not begin a header drag or double-click action. */
|
|
20
|
+
export declare const WindowHeaderActions: import("react").ForwardRefExoticComponent<WindowHeaderActionsProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
21
|
+
export type WindowHeaderActionProps = Omit<ButtonProps, "size">;
|
|
22
|
+
/** A compact header action; extra actions use the same treatment as the standard controls. */
|
|
23
|
+
export declare const WindowHeaderAction: import("react").ForwardRefExoticComponent<WindowHeaderActionProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
24
|
+
export type WindowHeaderControlProps = Omit<WindowHeaderActionProps, "children">;
|
|
25
|
+
export declare const WindowHeaderMinimize: import("react").ForwardRefExoticComponent<WindowHeaderControlProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
26
|
+
export interface WindowHeaderMaximizeProps extends WindowHeaderControlProps {
|
|
27
|
+
readonly maximized?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare const WindowHeaderMaximize: import("react").ForwardRefExoticComponent<WindowHeaderMaximizeProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
30
|
+
export type WindowHeaderCloseProps = Omit<WindowHeaderControlProps, "color">;
|
|
31
|
+
export declare const WindowHeaderClose: import("react").ForwardRefExoticComponent<WindowHeaderCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
32
|
+
export declare const WindowHeader: import("react").ForwardRefExoticComponent<WindowHeaderRootProps & import("react").RefAttributes<HTMLDivElement>> & {
|
|
33
|
+
Root: import("react").ForwardRefExoticComponent<WindowHeaderRootProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
34
|
+
Identity: import("react").ForwardRefExoticComponent<WindowHeaderIdentityProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
35
|
+
Center: import("react").ForwardRefExoticComponent<WindowHeaderCenterProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
36
|
+
Actions: import("react").ForwardRefExoticComponent<WindowHeaderActionsProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
37
|
+
Action: import("react").ForwardRefExoticComponent<WindowHeaderActionProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
38
|
+
Minimize: import("react").ForwardRefExoticComponent<WindowHeaderControlProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
39
|
+
Maximize: import("react").ForwardRefExoticComponent<WindowHeaderMaximizeProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
40
|
+
Close: import("react").ForwardRefExoticComponent<WindowHeaderCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
41
|
+
};
|
|
42
|
+
export type WindowHeaderProps = ComponentProps<typeof WindowHeaderRoot>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext } from "react";
|
|
3
|
+
import { useResolvedAppearance } from "./appearance-context.js";
|
|
4
|
+
import { Button } from "./button.js";
|
|
5
|
+
import { transitionTiming } from "./motion-style.js";
|
|
6
|
+
import { scale } from "./scale.js";
|
|
7
|
+
const WindowHeaderContext = createContext(null);
|
|
8
|
+
function useWindowHeader() {
|
|
9
|
+
const value = useContext(WindowHeaderContext);
|
|
10
|
+
if (value === null)
|
|
11
|
+
throw new Error("WindowHeader parts require WindowHeader.Root");
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
/** The composable top region of a window; its enclosing Surface owns the material. */
|
|
15
|
+
export const WindowHeaderRoot = forwardRef(function WindowHeaderRoot({ active = true, children, onPointerDown, style, ...properties }, ref) {
|
|
16
|
+
const resolved = useResolvedAppearance();
|
|
17
|
+
const spacing = resolved.appearance.spacing;
|
|
18
|
+
const state = {
|
|
19
|
+
active,
|
|
20
|
+
foreground: resolved.colors.foreground,
|
|
21
|
+
iconRadius: scale(resolved.appearance.radius, "xsmall"),
|
|
22
|
+
spacing,
|
|
23
|
+
transition: transitionTiming(resolved.transaction, resolved.preferences.animations)
|
|
24
|
+
};
|
|
25
|
+
return _jsx(WindowHeaderContext.Provider, { value: state, children: _jsx("div", { ...properties, ref: ref, onPointerDown: onPointerDown, style: {
|
|
26
|
+
boxSizing: "border-box",
|
|
27
|
+
display: "flex",
|
|
28
|
+
alignItems: "center",
|
|
29
|
+
gap: spacing,
|
|
30
|
+
minWidth: 0,
|
|
31
|
+
height: 16 + spacing * 2,
|
|
32
|
+
paddingInline: spacing,
|
|
33
|
+
flexShrink: 0,
|
|
34
|
+
userSelect: "none",
|
|
35
|
+
touchAction: onPointerDown ? "none" : undefined,
|
|
36
|
+
cursor: onPointerDown ? "grab" : undefined,
|
|
37
|
+
...style
|
|
38
|
+
}, children: children }) });
|
|
39
|
+
});
|
|
40
|
+
/** The icon and truncating title share the window's active treatment. */
|
|
41
|
+
export const WindowHeaderIdentity = forwardRef(function WindowHeaderIdentity({ icon, title, style, ...properties }, ref) {
|
|
42
|
+
const { active, iconRadius, spacing, transition } = useWindowHeader();
|
|
43
|
+
return _jsxs("div", { ...properties, ref: ref, style: {
|
|
44
|
+
...transition,
|
|
45
|
+
transitionProperty: "opacity",
|
|
46
|
+
display: "flex",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
gap: spacing,
|
|
49
|
+
flex: "0 1 auto",
|
|
50
|
+
minWidth: 0,
|
|
51
|
+
opacity: active ? 1 : 0.6,
|
|
52
|
+
...style
|
|
53
|
+
}, children: [icon && _jsx("img", { src: icon, alt: "", draggable: false, style: {
|
|
54
|
+
width: 16,
|
|
55
|
+
height: 16,
|
|
56
|
+
flexShrink: 0,
|
|
57
|
+
borderRadius: iconRadius,
|
|
58
|
+
objectFit: "contain"
|
|
59
|
+
} }), title != null && _jsx("span", { style: {
|
|
60
|
+
minWidth: 0,
|
|
61
|
+
overflow: "hidden",
|
|
62
|
+
textOverflow: "ellipsis",
|
|
63
|
+
whiteSpace: "nowrap",
|
|
64
|
+
fontSize: "0.8125em",
|
|
65
|
+
fontWeight: 500
|
|
66
|
+
}, children: title })] });
|
|
67
|
+
});
|
|
68
|
+
/** Optional flexible space for application-owned content. */
|
|
69
|
+
export const WindowHeaderCenter = forwardRef(function WindowHeaderCenter({ onDoubleClick, onPointerDown, style, ...properties }, ref) {
|
|
70
|
+
useWindowHeader();
|
|
71
|
+
return _jsx("div", { ...properties, ref: ref, onDoubleClick: event => { event.stopPropagation(); onDoubleClick?.(event); }, onPointerDown: event => { event.stopPropagation(); onPointerDown?.(event); }, style: { display: "flex", alignItems: "center", flex: "1 1 auto", minWidth: 0, ...style } });
|
|
72
|
+
});
|
|
73
|
+
/** End-aligned controls that do not begin a header drag or double-click action. */
|
|
74
|
+
export const WindowHeaderActions = forwardRef(function WindowHeaderActions({ onDoubleClick, onPointerDown, style, ...properties }, ref) {
|
|
75
|
+
const { spacing } = useWindowHeader();
|
|
76
|
+
return _jsx("div", { ...properties, ref: ref, onDoubleClick: event => { event.stopPropagation(); onDoubleClick?.(event); }, onPointerDown: event => { event.stopPropagation(); onPointerDown?.(event); }, style: {
|
|
77
|
+
display: "flex",
|
|
78
|
+
alignItems: "center",
|
|
79
|
+
gap: Math.max(4, scale(spacing, "xsmall")),
|
|
80
|
+
flexShrink: 0,
|
|
81
|
+
marginInlineStart: "auto",
|
|
82
|
+
...style
|
|
83
|
+
} });
|
|
84
|
+
});
|
|
85
|
+
/** A compact header action; extra actions use the same treatment as the standard controls. */
|
|
86
|
+
export const WindowHeaderAction = forwardRef(function WindowHeaderAction({ style, ...properties }, ref) {
|
|
87
|
+
const { foreground } = useWindowHeader();
|
|
88
|
+
return _jsx(Button, { ...properties, ref: ref, size: "xsmall", style: { color: foreground, ...style } });
|
|
89
|
+
});
|
|
90
|
+
export const WindowHeaderMinimize = forwardRef(function WindowHeaderMinimize({ "aria-label": label = "Minimize", preventFocusOnPress = true, ...properties }, ref) {
|
|
91
|
+
return _jsx(WindowHeaderAction, { ...properties, ref: ref, "aria-label": label, preventFocusOnPress: preventFocusOnPress, children: _jsx(ControlIcon, { children: _jsx("path", { d: "M1.5 7.5h7" }) }) });
|
|
92
|
+
});
|
|
93
|
+
export const WindowHeaderMaximize = forwardRef(function WindowHeaderMaximize({ "aria-label": label, maximized = false, ...properties }, ref) {
|
|
94
|
+
return _jsx(WindowHeaderAction, { ...properties, ref: ref, "aria-label": label ?? (maximized ? "Restore" : "Maximize"), children: _jsx(ControlIcon, { children: maximized
|
|
95
|
+
? _jsx("path", { d: "M1 4h5v5H1zM4 1h5v5H6.5", strokeWidth: "1.3", strokeLinejoin: "round" })
|
|
96
|
+
: _jsx("path", { d: "M1.5 1.5h7v7h-7z", strokeWidth: "1.3", strokeLinejoin: "round" }) }) });
|
|
97
|
+
});
|
|
98
|
+
export const WindowHeaderClose = forwardRef(function WindowHeaderClose({ "aria-label": label = "Close", preventFocusOnPress = true, ...properties }, ref) {
|
|
99
|
+
return _jsx(WindowHeaderAction, { ...properties, ref: ref, "aria-label": label, color: "danger:base", preventFocusOnPress: preventFocusOnPress, children: _jsx(ControlIcon, { children: _jsx("path", { d: "M1.5 1.5 8.5 8.5M8.5 1.5 1.5 8.5" }) }) });
|
|
100
|
+
});
|
|
101
|
+
function ControlIcon({ children }) {
|
|
102
|
+
return _jsx("svg", { "aria-hidden": "true", width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", children: children });
|
|
103
|
+
}
|
|
104
|
+
export const WindowHeader = Object.assign(WindowHeaderRoot, {
|
|
105
|
+
Root: WindowHeaderRoot,
|
|
106
|
+
Identity: WindowHeaderIdentity,
|
|
107
|
+
Center: WindowHeaderCenter,
|
|
108
|
+
Actions: WindowHeaderActions,
|
|
109
|
+
Action: WindowHeaderAction,
|
|
110
|
+
Minimize: WindowHeaderMinimize,
|
|
111
|
+
Maximize: WindowHeaderMaximize,
|
|
112
|
+
Close: WindowHeaderClose
|
|
113
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/react-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "React components for coherent PhreshOS Program interfaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@base-ui/react": "^1.7.0",
|
|
59
|
-
"@phreshos/core": "^0.1.
|
|
59
|
+
"@phreshos/core": "^0.1.54",
|
|
60
60
|
"colorjs.io": "^0.7.1",
|
|
61
61
|
"motion": "^13.2.0",
|
|
62
62
|
"react-aria-components": "^1.20.0"
|