@phreshos/react-ui 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -167
- package/dist/accordion.d.ts +7 -6
- package/dist/accordion.js +5 -5
- package/dist/alert-dialog.d.ts +2 -2
- package/dist/alert-dialog.js +3 -1
- package/dist/alert.d.ts +17 -0
- package/dist/alert.js +30 -0
- package/dist/app-layout.d.ts +13 -0
- package/dist/app-layout.js +84 -0
- package/dist/button.d.ts +31 -27
- package/dist/button.js +48 -40
- package/dist/calendar-layout.d.ts +9 -5
- package/dist/calendar-layout.js +67 -78
- package/dist/calendar-trigger.d.ts +4 -4
- package/dist/calendar-trigger.js +7 -29
- package/dist/calendar.d.ts +2 -2
- package/dist/calendar.js +6 -5
- package/dist/checkbox.d.ts +4 -4
- package/dist/checkbox.js +16 -6
- package/dist/color-area.d.ts +20 -0
- package/dist/color-area.js +30 -0
- package/dist/color-field.d.ts +17 -0
- package/dist/color-field.js +17 -0
- package/dist/color-picker.d.ts +24 -0
- package/dist/color-picker.js +30 -0
- package/dist/color-slider.d.ts +19 -0
- package/dist/color-slider.js +29 -0
- package/dist/color-swatch-picker.d.ts +23 -0
- package/dist/color-swatch-picker.js +36 -0
- package/dist/color-swatch.d.ts +18 -0
- package/dist/color-swatch.js +20 -0
- package/dist/combo-box.d.ts +18 -10
- package/dist/combo-box.js +43 -58
- package/dist/context-menu.d.ts +14 -10
- package/dist/context-menu.js +7 -6
- package/dist/control/color-thumb.d.ts +13 -0
- package/dist/control/color-thumb.js +33 -0
- package/dist/control/color-value.d.ts +6 -0
- package/dist/control/color-value.js +7 -0
- package/dist/control/control.d.ts +60 -0
- package/dist/control/control.js +71 -0
- package/dist/control/field-button.d.ts +13 -0
- package/dist/control/field-button.js +28 -0
- package/dist/control/field.d.ts +20 -0
- package/dist/control/field.js +34 -0
- package/dist/control/icon.d.ts +11 -0
- package/dist/control/icon.js +8 -0
- package/dist/control/item.d.ts +37 -0
- package/dist/control/item.js +57 -0
- package/dist/control/open-state.d.ts +25 -0
- package/dist/control/open-state.js +8 -0
- package/dist/control/selection-track.d.ts +39 -0
- package/dist/control/selection-track.js +122 -0
- package/dist/control/selection.d.ts +44 -0
- package/dist/{selection.js → control/selection.js} +16 -0
- package/dist/control/surface-render.d.ts +10 -0
- package/dist/control/surface-render.js +12 -0
- package/dist/control/text-control.d.ts +32 -0
- package/dist/control/text-control.js +31 -0
- package/dist/control/toggle.d.ts +32 -0
- package/dist/control/toggle.js +80 -0
- package/dist/date-control.d.ts +9 -9
- package/dist/date-control.js +31 -34
- package/dist/date-field.d.ts +7 -6
- package/dist/date-field.js +8 -6
- package/dist/date-picker.d.ts +13 -6
- package/dist/date-picker.js +9 -6
- package/dist/date-range-picker.d.ts +15 -6
- package/dist/date-range-picker.js +12 -9
- package/dist/dialog.d.ts +29 -15
- package/dist/dialog.js +37 -28
- package/dist/disclosure.d.ts +8 -7
- package/dist/disclosure.js +31 -52
- package/dist/drop-zone.d.ts +18 -0
- package/dist/drop-zone.js +32 -0
- package/dist/dropdown-menu.d.ts +11 -8
- package/dist/dropdown-menu.js +5 -4
- package/dist/fieldset.d.ts +13 -0
- package/dist/fieldset.js +26 -0
- package/dist/file-trigger.d.ts +13 -0
- package/dist/file-trigger.js +6 -0
- package/dist/flex.d.ts +1 -1
- package/dist/flex.js +5 -4
- package/dist/foundation/appearance.d.ts +83 -0
- package/dist/foundation/appearance.js +38 -0
- package/dist/{aria-direction.js → foundation/aria-direction.js} +3 -1
- package/dist/foundation/color.d.ts +61 -0
- package/dist/foundation/color.js +247 -0
- package/dist/{layout.d.ts → foundation/layout.d.ts} +6 -4
- package/dist/{layout.js → foundation/layout.js} +7 -5
- package/dist/foundation/motion-style.d.ts +9 -0
- package/dist/foundation/motion-style.js +50 -0
- package/dist/foundation/preferences.d.ts +15 -0
- package/dist/{ui-provider.d.ts → foundation/provider.d.ts} +9 -5
- package/dist/{ui-provider.js → foundation/provider.js} +18 -27
- package/dist/{radius.d.ts → foundation/radius.d.ts} +6 -3
- package/dist/foundation/radius.js +11 -0
- package/dist/foundation/spacing.d.ts +11 -0
- package/dist/foundation/spacing.js +4 -0
- package/dist/foundation/visual.d.ts +42 -0
- package/dist/{appearance-context.js → foundation/visual.js} +41 -27
- package/dist/grid.d.ts +1 -1
- package/dist/grid.js +5 -4
- package/dist/icons/main.d.ts +5 -3
- package/dist/icons/main.js +5 -3
- package/dist/input.d.ts +2 -2
- package/dist/input.js +9 -7
- package/dist/list-box.d.ts +24 -19
- package/dist/list-box.js +52 -109
- package/dist/main.d.ts +28 -17
- package/dist/main.js +22 -9
- package/dist/menu.d.ts +28 -32
- package/dist/menu.js +47 -93
- package/dist/number-field.d.ts +17 -0
- package/dist/number-field.js +28 -0
- package/dist/panel.d.ts +10 -5
- package/dist/panel.js +33 -12
- package/dist/popover.d.ts +26 -12
- package/dist/popover.js +22 -15
- package/dist/progress-bar.d.ts +8 -10
- package/dist/progress-bar.js +18 -34
- package/dist/radio.d.ts +15 -12
- package/dist/radio.js +27 -37
- package/dist/range-calendar.d.ts +5 -3
- package/dist/range-calendar.js +8 -7
- package/dist/scroll-area.d.ts +2 -2
- package/dist/scroll-area.js +10 -9
- package/dist/segmented-control.d.ts +23 -0
- package/dist/segmented-control.js +38 -0
- package/dist/select.d.ts +40 -13
- package/dist/select.js +63 -18
- package/dist/slider.d.ts +7 -3
- package/dist/slider.js +51 -50
- package/dist/spinner.d.ts +5 -8
- package/dist/spinner.js +12 -27
- package/dist/surface/grain.d.ts +12 -0
- package/dist/surface/grain.js +65 -0
- package/dist/{material-options.d.ts → surface/material-options.d.ts} +1 -2
- package/dist/{material-options.js → surface/material-options.js} +2 -2
- package/dist/surface/paint-class.d.ts +13 -0
- package/dist/surface/paint-class.js +47 -0
- package/dist/{shadow-options.d.ts → surface/shadow-options.d.ts} +13 -1
- package/dist/{shadow-options.js → surface/shadow-options.js} +17 -2
- package/dist/surface/surface.d.ts +80 -0
- package/dist/surface/surface.js +239 -0
- package/dist/switch.d.ts +4 -5
- package/dist/switch.js +17 -8
- package/dist/table.d.ts +29 -32
- package/dist/table.js +68 -106
- package/dist/tabs.d.ts +16 -15
- package/dist/tabs.js +44 -86
- package/dist/textarea.d.ts +2 -2
- package/dist/textarea.js +10 -14
- package/dist/time-field.d.ts +6 -6
- package/dist/time-field.js +8 -6
- package/dist/toolbar.d.ts +6 -4
- package/dist/toolbar.js +16 -15
- package/dist/tooltip.d.ts +17 -8
- package/dist/tooltip.js +17 -15
- package/dist/tree.d.ts +22 -27
- package/dist/tree.js +54 -99
- package/dist/window.d.ts +4 -4
- package/dist/window.js +18 -20
- package/package.json +3 -3
- package/dist/appearance-context.d.ts +0 -54
- package/dist/appearance.d.ts +0 -11
- package/dist/appearance.js +0 -11
- package/dist/color.d.ts +0 -69
- package/dist/color.js +0 -192
- package/dist/control-surface.d.ts +0 -20
- package/dist/control-surface.js +0 -11
- package/dist/control.d.ts +0 -70
- package/dist/control.js +0 -105
- package/dist/field-style.d.ts +0 -3
- package/dist/field-style.js +0 -12
- package/dist/material-paint.d.ts +0 -13
- package/dist/material-paint.js +0 -119
- package/dist/motion-style.d.ts +0 -13
- package/dist/motion-style.js +0 -75
- package/dist/preferences.d.ts +0 -12
- package/dist/radius.js +0 -11
- package/dist/readiness.d.ts +0 -37
- package/dist/readiness.js +0 -134
- package/dist/selection.d.ts +0 -18
- package/dist/spacing.d.ts +0 -8
- package/dist/spacing.js +0 -8
- package/dist/surface-edge.d.ts +0 -11
- package/dist/surface-edge.js +0 -55
- package/dist/surface.d.ts +0 -27
- package/dist/surface.js +0 -92
- package/dist/text-control.d.ts +0 -10
- package/dist/text-control.js +0 -0
- package/dist/toggle-indicator.d.ts +0 -18
- package/dist/toggle-indicator.js +0 -49
- /package/dist/{aria-direction.d.ts → foundation/aria-direction.d.ts} +0 -0
- /package/dist/{direction.d.ts → foundation/direction.d.ts} +0 -0
- /package/dist/{direction.js → foundation/direction.js} +0 -0
- /package/dist/{overlay-placement.d.ts → foundation/overlay-placement.d.ts} +0 -0
- /package/dist/{overlay-placement.js → foundation/overlay-placement.js} +0 -0
- /package/dist/{preferences.js → foundation/preferences.js} +0 -0
- /package/dist/{scale.d.ts → foundation/scale.d.ts} +0 -0
- /package/dist/{scale.js → foundation/scale.js} +0 -0
package/dist/tree.js
CHANGED
|
@@ -1,134 +1,89 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext, useMemo } from "react";
|
|
3
3
|
import { Button as AriaButton, Collection as AriaCollection, Tree as AriaTree, TreeItem as AriaTreeItem, TreeItemContent as AriaTreeItemContent } from "react-aria-components";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { AriaDirectionBoundary } from "./aria-direction.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
import { proportionalRadius, transition, useControlMetrics } from "./control/control.js";
|
|
5
|
+
import { itemPaint, itemStyle } from "./control/item.js";
|
|
6
|
+
import { ariaSelection, stringKey, stringKeys } from "./control/selection.js";
|
|
7
|
+
import { AriaDirectionBoundary } from "./foundation/aria-direction.js";
|
|
8
|
+
import { colorOpacity } from "./foundation/color.js";
|
|
9
|
+
import { resolveDirection, useDirection } from "./foundation/direction.js";
|
|
10
|
+
import { dimmedClass } from "./surface/surface.js";
|
|
11
|
+
import { ChevronRight } from "lucide-react";
|
|
12
|
+
import { iconProps } from "./control/icon.js";
|
|
13
|
+
const TreeStyleContext = createContext(null);
|
|
14
|
+
const TreeRootImplementation = forwardRef(function Tree(properties, ref) {
|
|
15
|
+
const { className, color = "primary", defaultExpanded, defaultValue: _defaultValue, expanded, onAction, onChange: _onChange, onExpandedChange, radius, selectOnPressUp, selectionMode = "none", size, style, value: _value, ...native } = properties;
|
|
16
|
+
const metrics = useControlMetrics(size, radius);
|
|
17
|
+
// Items are controls: they take the control radius at their size.
|
|
18
|
+
const itemRadius = metrics.radius;
|
|
12
19
|
const direction = resolveDirection(native.dir, useDirection());
|
|
13
|
-
const context = useMemo(() => ({ direction, interactive: selectionMode !== "none" ||
|
|
14
|
-
return _jsx(
|
|
20
|
+
const context = useMemo(() => ({ color, direction, interactive: selectionMode !== "none" || onAction != null, metrics, itemRadius }), [color, direction, metrics, itemRadius, onAction, selectionMode]);
|
|
21
|
+
return _jsx(TreeStyleContext.Provider, { value: context, children: _jsx(AriaDirectionBoundary, { direction: direction, children: _jsx(AriaTree, { ...native, shouldSelectOnPressUp: selectOnPressUp, ...ariaSelection(properties, "none"), ...(expanded !== undefined ? { expandedKeys: new Set(expanded) } : {}), ...(defaultExpanded !== undefined ? { defaultExpandedKeys: new Set(defaultExpanded) } : {}), ...(onExpandedChange !== undefined ? { onExpandedChange: (keys) => onExpandedChange(stringKeys(keys)) } : {}), ref: ref, dir: direction, className: className, onAction: onAction == null ? undefined : key => onAction(stringKey(key)), style: {
|
|
15
22
|
display: "grid",
|
|
16
23
|
alignContent: "start",
|
|
17
|
-
gap:
|
|
24
|
+
gap: 2,
|
|
18
25
|
minWidth: 0,
|
|
19
|
-
padding:
|
|
26
|
+
padding: metrics.listInset,
|
|
20
27
|
boxSizing: "border-box",
|
|
21
28
|
outline: "none",
|
|
22
29
|
fontFamily: "inherit",
|
|
23
|
-
fontSize:
|
|
30
|
+
fontSize: metrics.fontSize,
|
|
24
31
|
...style
|
|
25
32
|
} }) }) });
|
|
26
33
|
});
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const onSelectionChange = properties.onChange == null
|
|
32
|
-
? undefined
|
|
33
|
-
: (selection) => {
|
|
34
|
-
if (properties.selectionMode === "multiple") {
|
|
35
|
-
properties.onChange?.(multipleSelection(selection));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (properties.selectionMode === "single")
|
|
39
|
-
properties.onChange?.(singleSelection(selection));
|
|
40
|
-
};
|
|
41
|
-
return {
|
|
42
|
-
...(selectedKeys !== undefined ? { selectedKeys } : {}),
|
|
43
|
-
...(defaultSelectedKeys !== undefined ? { defaultSelectedKeys } : {}),
|
|
44
|
-
...(onSelectionChange !== undefined ? { onSelectionChange } : {})
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
function expansionProperties({ defaultExpanded, expanded, onExpandedChange }) {
|
|
48
|
-
return {
|
|
49
|
-
...(expanded !== undefined ? { expandedKeys: new Set(expanded) } : {}),
|
|
50
|
-
...(defaultExpanded !== undefined ? { defaultExpandedKeys: new Set(defaultExpanded) } : {}),
|
|
51
|
-
...(onExpandedChange !== undefined
|
|
52
|
-
? { onExpandedChange: (keys) => onExpandedChange(stringKeys(keys)) }
|
|
53
|
-
: {})
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
const TreeItemImplementation = forwardRef(function TreeItem({ className, disabled = false, onAction, style, ...properties }, ref) {
|
|
57
|
-
const { interactive, theme } = useTreeTheme();
|
|
58
|
-
return _jsx(AriaTreeItem, { ...properties, ref: ref, className: className, isDisabled: disabled, onAction: onAction, style: state => {
|
|
34
|
+
/** Tree entries use the collection Item treatment as their own paint. */
|
|
35
|
+
const TreeItemImplementation = forwardRef(function TreeItem({ arrowNavigation, className, disabled = false, expandable, onAction, style, ...properties }, ref) {
|
|
36
|
+
const { color, interactive, itemRadius, metrics } = useTreeStyle();
|
|
37
|
+
return _jsx(AriaTreeItem, { ...properties, allowsArrowNavigation: arrowNavigation, hasChildItems: expandable, ref: ref, className: state => dimmedClass(state.isDisabled, className ?? state.defaultClassName) ?? "", isDisabled: disabled, onAction: onAction, style: state => {
|
|
59
38
|
const responds = interactive || onAction != null || state.hasChildItems;
|
|
60
39
|
return {
|
|
61
|
-
...
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
paddingInlineStart:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
outline: state.isFocusVisible ? `1px solid ${theme.focusColor}` : "none",
|
|
40
|
+
...itemStyle(metrics, state.isDisabled),
|
|
41
|
+
...itemPaint(metrics.visual, color, {
|
|
42
|
+
selected: state.isSelected,
|
|
43
|
+
hovered: responds && state.isHovered,
|
|
44
|
+
pressed: responds && state.isPressed,
|
|
45
|
+
focusVisible: false,
|
|
46
|
+
disabled: state.isDisabled
|
|
47
|
+
}),
|
|
48
|
+
paddingInlineStart: metrics.inset / 2 + Math.max(0, state.level - 1) * metrics.spacing,
|
|
49
|
+
borderRadius: itemRadius,
|
|
50
|
+
outline: `3px solid ${state.isFocusVisible ? colorOpacity(metrics.visual.colors.primary, 0.34) : "transparent"}`,
|
|
73
51
|
outlineOffset: 1,
|
|
74
|
-
cursor:
|
|
75
|
-
opacity: disabled ? controlOpacity.disabled : 1,
|
|
76
|
-
userSelect: "none",
|
|
77
|
-
...(state.isSelected
|
|
78
|
-
? state.isPressed
|
|
79
|
-
? theme.paints.palette.pressed
|
|
80
|
-
: state.isHovered
|
|
81
|
-
? theme.paints.palette.hover
|
|
82
|
-
: theme.paints.palette.rest
|
|
83
|
-
: state.isHovered && responds
|
|
84
|
-
? theme.paints.subtle.hover
|
|
85
|
-
: { background: "transparent", color: "inherit" }),
|
|
52
|
+
cursor: state.isDisabled ? "not-allowed" : responds ? "pointer" : "default",
|
|
86
53
|
...style
|
|
87
54
|
};
|
|
88
55
|
} });
|
|
89
56
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
57
|
+
const TreeContent = forwardRef(function TreeContent({ children }, ref) {
|
|
58
|
+
const { direction, metrics } = useTreeStyle();
|
|
59
|
+
const box = Math.round(metrics.indicator);
|
|
93
60
|
return _jsx(AriaTreeItemContent, { ref: ref, children: state => _jsxs(_Fragment, { children: [state.hasChildItems
|
|
94
61
|
? _jsx(AriaButton, { slot: "chevron", style: ({ isFocusVisible }) => ({
|
|
95
|
-
...theme.transition,
|
|
96
|
-
appearance: "none",
|
|
97
62
|
display: "inline-grid",
|
|
98
63
|
flex: "0 0 auto",
|
|
99
64
|
placeItems: "center",
|
|
100
|
-
width:
|
|
101
|
-
height:
|
|
65
|
+
width: box,
|
|
66
|
+
height: box,
|
|
102
67
|
padding: 0,
|
|
103
68
|
border: 0,
|
|
104
|
-
borderRadius:
|
|
105
|
-
outline:
|
|
106
|
-
outlineOffset: 1,
|
|
69
|
+
borderRadius: proportionalRadius(metrics.visual, box),
|
|
70
|
+
outline: `3px solid ${isFocusVisible ? colorOpacity(metrics.visual.colors.primary, 0.34) : "transparent"}`,
|
|
107
71
|
background: "transparent",
|
|
108
72
|
color: "inherit",
|
|
109
73
|
cursor: state.isDisabled ? "not-allowed" : "pointer",
|
|
110
74
|
font: "inherit"
|
|
111
|
-
}), children: _jsx(
|
|
112
|
-
: _jsx("span", { "aria-hidden": "true", style: { flex: `0 0 ${
|
|
75
|
+
}), children: _jsx(ChevronRight, { ...iconProps(14), style: { ...transition(metrics.visual, "rotate"), rotate: state.isExpanded ? "90deg" : direction === "rtl" ? "180deg" : "0deg" } }) })
|
|
76
|
+
: _jsx("span", { "aria-hidden": "true", style: { flex: `0 0 ${box}px` } }), _jsx("span", { style: { flex: "1 1 auto", minWidth: 0, display: "flex", alignItems: "center", gap: metrics.gap }, children: typeof children === "function" ? children(state) : children })] }) });
|
|
113
77
|
});
|
|
114
|
-
function
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
transform: `rotate(${expanded ? 90 : collapsedRotation}deg)`
|
|
120
|
-
}, children: _jsx("path", { d: "m4 2 4 4-4 4" }) });
|
|
78
|
+
function useTreeStyle() {
|
|
79
|
+
const context = useContext(TreeStyleContext);
|
|
80
|
+
if (context == null)
|
|
81
|
+
throw new Error("Tree parts must be used inside Tree");
|
|
82
|
+
return context;
|
|
121
83
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
Item: TreeItem,
|
|
84
|
+
/** Hierarchical navigation with independently controlled expansion, selection, and actions. */
|
|
85
|
+
export const Tree = Object.assign(TreeRootImplementation, {
|
|
86
|
+
Item: TreeItemImplementation,
|
|
126
87
|
Content: TreeContent,
|
|
127
|
-
Collection:
|
|
88
|
+
Collection: AriaCollection
|
|
128
89
|
});
|
|
129
|
-
function useTreeTheme() {
|
|
130
|
-
const value = useContext(TreeThemeContext);
|
|
131
|
-
if (value == null)
|
|
132
|
-
throw new Error("Tree parts must be used inside Tree");
|
|
133
|
-
return value;
|
|
134
|
-
}
|
package/dist/window.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
2
|
import type { BeginWindowMoveGesture } from "@phreshos/core";
|
|
3
|
-
import { type
|
|
4
|
-
import { type Color } from "./color.js";
|
|
5
|
-
import { type SurfaceProps } from "./surface.js";
|
|
3
|
+
import { type ButtonActionProps } from "./button.js";
|
|
4
|
+
import { type Color } from "./foundation/color.js";
|
|
5
|
+
import { type SurfaceProps } from "./surface/surface.js";
|
|
6
6
|
/** The material shell that establishes the complete header-and-content layout. */
|
|
7
7
|
export type WindowProps = SurfaceProps;
|
|
8
8
|
/** The remaining window area. Its consumer owns content behavior, including overflow. */
|
|
@@ -27,7 +27,7 @@ export interface WindowIdentityProps extends Omit<HTMLAttributes<HTMLDivElement>
|
|
|
27
27
|
}
|
|
28
28
|
export type WindowCenterProps = HTMLAttributes<HTMLDivElement>;
|
|
29
29
|
export type WindowActionsProps = HTMLAttributes<HTMLDivElement>;
|
|
30
|
-
export type WindowActionProps = Omit<
|
|
30
|
+
export type WindowActionProps = Omit<ButtonActionProps, "size">;
|
|
31
31
|
export type WindowControlProps = Omit<WindowActionProps, "children">;
|
|
32
32
|
export interface WindowMaximizeProps extends WindowControlProps {
|
|
33
33
|
readonly maximized?: boolean;
|
package/dist/window.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, forwardRef, useContext } from "react";
|
|
3
|
-
import { useResolvedAppearance } from "./appearance-context.js";
|
|
4
3
|
import { Button } from "./button.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import { transition } from "./control/control.js";
|
|
5
|
+
import { resolveColor } from "./foundation/color.js";
|
|
6
|
+
import { headerHeight } from "./foundation/layout.js";
|
|
7
|
+
import { scale } from "./foundation/scale.js";
|
|
8
|
+
import { useVisual } from "./foundation/visual.js";
|
|
9
|
+
import { Surface } from "./surface/surface.js";
|
|
9
10
|
import useWindowMoveHandle from "./use-window-move-handle.js";
|
|
11
|
+
import { ArrowDownLeft, Maximize2, Minimize2, X } from "lucide-react";
|
|
12
|
+
import { iconProps } from "./control/icon.js";
|
|
10
13
|
const HeaderContext = createContext(null);
|
|
11
14
|
function useHeader() {
|
|
12
15
|
const value = useContext(HeaderContext);
|
|
@@ -34,17 +37,17 @@ const WindowContent = forwardRef(function WindowContent({ style, ...properties }
|
|
|
34
37
|
});
|
|
35
38
|
/** The composable top region of a window; its enclosing Surface owns the material. */
|
|
36
39
|
const HeaderRoot = forwardRef(function HeaderRoot({ active = true, beginMoveGesture, children, color, maximized = false, onDoubleClick, onLostPointerCapture, onMaximize, onMoveError, onPointerCancel, onPointerDown, onPointerMove, onPointerUp, style, ...properties }, ref) {
|
|
37
|
-
const
|
|
38
|
-
const spacing =
|
|
39
|
-
const foreground = style?.color ?? resolveColor(color ?? "foreground
|
|
40
|
+
const visual = useVisual();
|
|
41
|
+
const spacing = visual.spacing;
|
|
42
|
+
const foreground = style?.color ?? resolveColor(color ?? "foreground", visual.colors);
|
|
40
43
|
const state = {
|
|
41
44
|
active,
|
|
42
45
|
foreground,
|
|
43
|
-
iconRadius: scale(
|
|
46
|
+
iconRadius: scale(visual.radius, "xsmall"),
|
|
44
47
|
maximized,
|
|
45
48
|
onMaximize,
|
|
46
49
|
spacing,
|
|
47
|
-
transition:
|
|
50
|
+
transition: transition(visual, "opacity")
|
|
48
51
|
};
|
|
49
52
|
const move = useWindowMoveHandle(beginMoveGesture, onMoveError);
|
|
50
53
|
return _jsx(HeaderContext.Provider, { value: state, children: _jsx("div", { ...properties, ref: ref, onPointerDown: event => {
|
|
@@ -61,7 +64,7 @@ const HeaderRoot = forwardRef(function HeaderRoot({ active = true, beginMoveGest
|
|
|
61
64
|
alignItems: "center",
|
|
62
65
|
gap: spacing,
|
|
63
66
|
minWidth: 0,
|
|
64
|
-
height:
|
|
67
|
+
height: headerHeight(spacing),
|
|
65
68
|
paddingInline: spacing,
|
|
66
69
|
flexShrink: 0,
|
|
67
70
|
userSelect: "none",
|
|
@@ -122,21 +125,16 @@ const WindowAction = forwardRef(function WindowAction({ ...properties }, ref) {
|
|
|
122
125
|
return _jsx(Button, { ...properties, ref: ref, size: "xsmall" });
|
|
123
126
|
});
|
|
124
127
|
const WindowMinimize = forwardRef(function WindowMinimize({ "aria-label": label = "Minimize", preventFocusOnPress = true, ...properties }, ref) {
|
|
125
|
-
return _jsx(WindowAction, { ...properties, ref: ref, "aria-label": label, preventFocusOnPress: preventFocusOnPress, children: _jsx(
|
|
128
|
+
return _jsx(WindowAction, { ...properties, ref: ref, "aria-label": label, preventFocusOnPress: preventFocusOnPress, children: _jsx(ArrowDownLeft, { ...iconProps(14) }) });
|
|
126
129
|
});
|
|
127
130
|
const WindowMaximize = forwardRef(function WindowMaximize({ "aria-label": label, maximized, onPress, ...properties }, ref) {
|
|
128
131
|
const header = useHeader();
|
|
129
132
|
const selected = maximized ?? header.maximized;
|
|
130
|
-
return _jsx(WindowAction, { ...properties, ref: ref, onPress: onPress ?? header.onMaximize, "aria-label": label ?? (selected ? "Restore" : "Maximize"), children: _jsx(
|
|
131
|
-
? _jsx("path", { d: "M1 4h5v5H1zM4 1h5v5H6.5", strokeWidth: "1.3", strokeLinejoin: "round" })
|
|
132
|
-
: _jsx("path", { d: "M1.5 1.5h7v7h-7z", strokeWidth: "1.3", strokeLinejoin: "round" }) }) });
|
|
133
|
+
return _jsx(WindowAction, { ...properties, ref: ref, onPress: onPress ?? header.onMaximize, "aria-label": label ?? (selected ? "Restore" : "Maximize"), children: selected ? _jsx(Minimize2, { ...iconProps(14) }) : _jsx(Maximize2, { ...iconProps(14) }) });
|
|
133
134
|
});
|
|
134
|
-
const WindowClose = forwardRef(function WindowClose({ "aria-label": label = "Close", color = "danger
|
|
135
|
-
return _jsx(WindowAction, { ...properties, ref: ref, "aria-label": label, color: color, preventFocusOnPress: preventFocusOnPress, children: _jsx(
|
|
135
|
+
const WindowClose = forwardRef(function WindowClose({ "aria-label": label = "Close", color = "danger", preventFocusOnPress = true, ...properties }, ref) {
|
|
136
|
+
return _jsx(WindowAction, { ...properties, ref: ref, "aria-label": label, color: color, preventFocusOnPress: preventFocusOnPress, children: _jsx(X, { ...iconProps(14) }) });
|
|
136
137
|
});
|
|
137
|
-
function ControlIcon({ children }) {
|
|
138
|
-
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 });
|
|
139
|
-
}
|
|
140
138
|
const Header = Object.assign(HeaderRoot, {
|
|
141
139
|
Identity: WindowIdentity,
|
|
142
140
|
Center: WindowCenter,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/react-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
4
4
|
"description": "React components for coherent PhreshOS Program interfaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -57,9 +57,9 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@base-ui/react": "^1.7.0",
|
|
59
59
|
"@internationalized/date": "^3.12.3",
|
|
60
|
-
"@phreshos/core": "^0.1.
|
|
60
|
+
"@phreshos/core": "^0.1.62",
|
|
61
61
|
"colorjs.io": "^0.7.1",
|
|
62
|
-
"
|
|
62
|
+
"lucide-react": "^1.48.0",
|
|
63
63
|
"react-aria": "^3.51.0",
|
|
64
64
|
"react-aria-components": "^1.20.0"
|
|
65
65
|
},
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { type Appearance, type ThemedValue } from "./appearance.js";
|
|
2
|
-
import type { Preferences } from "./preferences.js";
|
|
3
|
-
export declare const AppearanceContext: import("react").Context<Appearance>;
|
|
4
|
-
export interface PreferencesSource {
|
|
5
|
-
readonly getSnapshot: () => Preferences;
|
|
6
|
-
readonly getServerSnapshot: () => Preferences;
|
|
7
|
-
readonly subscribe: (change: () => void) => () => void;
|
|
8
|
-
}
|
|
9
|
-
/** Returns the nearest unresolved appearance, or React UI's default. */
|
|
10
|
-
export declare function useAppearance(): Appearance;
|
|
11
|
-
/** Returns the nearest complete Preferences, or reactively follows the browser. */
|
|
12
|
-
export declare function usePreferences(): Preferences;
|
|
13
|
-
/** Reactively reads the browser's complete visual preferences. */
|
|
14
|
-
export declare function useBrowserPreferences(): Preferences;
|
|
15
|
-
/** Selects the active branch of one complete ThemedValue. */
|
|
16
|
-
export declare function useThemedValue<Value>(value: ThemedValue<Value>): Value;
|
|
17
|
-
/** Resolves one coherent Appearance snapshot for internal component derivation. */
|
|
18
|
-
export declare function useResolvedAppearance(): {
|
|
19
|
-
appearance: Appearance;
|
|
20
|
-
preferences: Preferences;
|
|
21
|
-
colors: Readonly<{
|
|
22
|
-
background: string;
|
|
23
|
-
foreground: string;
|
|
24
|
-
default: string;
|
|
25
|
-
primary: string;
|
|
26
|
-
secondary: string;
|
|
27
|
-
success: string;
|
|
28
|
-
warning: string;
|
|
29
|
-
danger: string;
|
|
30
|
-
info: string;
|
|
31
|
-
}>;
|
|
32
|
-
material: Readonly<{
|
|
33
|
-
grain: number;
|
|
34
|
-
grainAmount: number;
|
|
35
|
-
backdrop: number;
|
|
36
|
-
opacity: number;
|
|
37
|
-
distortion: number;
|
|
38
|
-
saturation: number;
|
|
39
|
-
}>;
|
|
40
|
-
shadow: Readonly<{
|
|
41
|
-
x: number;
|
|
42
|
-
y: number;
|
|
43
|
-
blur: number;
|
|
44
|
-
spread: number;
|
|
45
|
-
opacity: number;
|
|
46
|
-
}>;
|
|
47
|
-
transaction: Readonly<{
|
|
48
|
-
duration: number;
|
|
49
|
-
easing: import("@phreshos/core").Easing;
|
|
50
|
-
}>;
|
|
51
|
-
};
|
|
52
|
-
/** Creates a stable source for a complete explicitly supplied Preferences value. */
|
|
53
|
-
export declare function fixedPreferencesSource(preferences: Preferences): PreferencesSource;
|
|
54
|
-
export declare const PreferencesContext: import("react").Context<PreferencesSource>;
|
package/dist/appearance.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { appearanceLimits, type Appearance as SystemAppearance, type AppearanceUpdate as SystemAppearanceUpdate, type AppearanceColor, type AppearanceColors, type AppearanceMaterial, type AppearanceRange, type AppearanceShadow, type AppearanceTransaction, type Easing, type ThemedValue } from "@phreshos/core";
|
|
2
|
-
/** Complete visual input consumed by React UI. */
|
|
3
|
-
export type Appearance = Pick<SystemAppearance, "colors" | "spacing" | "radius" | "shadow" | "material" | "transaction">;
|
|
4
|
-
type AppearanceUpdateFields = Pick<SystemAppearanceUpdate, "colors" | "spacing" | "radius" | "shadow" | "material" | "transaction">;
|
|
5
|
-
/** At least one partial visual field recursively merged with the nearest UIProvider. */
|
|
6
|
-
export type AppearanceUpdate = {
|
|
7
|
-
[Field in keyof AppearanceUpdateFields]-?: Readonly<Required<Pick<AppearanceUpdateFields, Field>> & Omit<AppearanceUpdateFields, Field>>;
|
|
8
|
-
}[keyof AppearanceUpdateFields];
|
|
9
|
-
export { appearanceLimits, type AppearanceColor, type AppearanceColors, type AppearanceMaterial, type AppearanceRange, type AppearanceShadow, type AppearanceTransaction, type Easing, type ThemedValue };
|
|
10
|
-
/** React UI's default visual input, derived from the System default. */
|
|
11
|
-
export declare const defaultAppearance: Appearance;
|
package/dist/appearance.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { appearanceLimits, defaultAppearance as systemDefaultAppearance } from "@phreshos/core";
|
|
2
|
-
export { appearanceLimits };
|
|
3
|
-
/** React UI's default visual input, derived from the System default. */
|
|
4
|
-
export const defaultAppearance = Object.freeze({
|
|
5
|
-
colors: systemDefaultAppearance.colors,
|
|
6
|
-
spacing: systemDefaultAppearance.spacing,
|
|
7
|
-
radius: systemDefaultAppearance.radius,
|
|
8
|
-
shadow: systemDefaultAppearance.shadow,
|
|
9
|
-
material: systemDefaultAppearance.material,
|
|
10
|
-
transaction: systemDefaultAppearance.transaction
|
|
11
|
-
});
|
package/dist/color.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { AppearanceColor, AppearanceColors } from "./appearance.js";
|
|
2
|
-
/** A visual treatment derived from one concrete CSS color. */
|
|
3
|
-
export type ColorLevel = "subtle" | "soft" | "base" | "strong" | "intense";
|
|
4
|
-
/** Every visual treatment derived from one concrete CSS color. */
|
|
5
|
-
export type ColorScale = Readonly<Record<ColorLevel, string>>;
|
|
6
|
-
/** One Appearance color and resting level, or a direct CSS color. */
|
|
7
|
-
export type Color = `${AppearanceColor}:${ColorLevel}` | (string & {});
|
|
8
|
-
export declare const defaultColor = "background:base";
|
|
9
|
-
/** Distinguishes derived color levels from direct CSS colors. */
|
|
10
|
-
export declare function isColorLevel(value: string | undefined): value is ColorLevel;
|
|
11
|
-
/** Derives visual treatments while preserving the concrete value at `base`. */
|
|
12
|
-
export declare function color(value: string): ColorScale;
|
|
13
|
-
/** Resolves the same named treatment for solid paint and contrast calculations. */
|
|
14
|
-
export declare function resolveColorLevel(value: string, level: ColorLevel): string;
|
|
15
|
-
/** Returns the complete visual treatments derived from one concrete color. */
|
|
16
|
-
export declare function useColor(value: string): ColorScale;
|
|
17
|
-
/** Returns the readable Appearance content color for one semantic or CSS fill. */
|
|
18
|
-
export declare function useContrastingColor(value: Color): string;
|
|
19
|
-
/** Resolves a semantic color from an already selected Appearance branch. */
|
|
20
|
-
export declare function resolveColor(value: Color | undefined, colors: AppearanceColors): string;
|
|
21
|
-
/** Resolves opaque control paint from an already selected Appearance branch. */
|
|
22
|
-
export declare function resolveSolidColor(value: Color, colors: AppearanceColors): string;
|
|
23
|
-
/** Applies material opacity without restricting the source CSS color syntax. */
|
|
24
|
-
export declare function colorOpacity(value: string, opacity: number): string;
|
|
25
|
-
/** Reads perceptual lightness from a resolved CSS color. */
|
|
26
|
-
export declare function colorLightness(value: string): number;
|
|
27
|
-
/** Orders resolved CSS colors by perceptual lightness, never by their role. */
|
|
28
|
-
export declare function orderColors(first: string, second: string): {
|
|
29
|
-
lighter: string;
|
|
30
|
-
darker: string;
|
|
31
|
-
};
|
|
32
|
-
/** Solid controls use opaque, gamut-mapped colors for both paint and contrast. */
|
|
33
|
-
export declare function opaqueColor(value: string): string;
|
|
34
|
-
/** Changes only perceptual lightness; theme names never determine direction. */
|
|
35
|
-
export declare function colorShade(value: string, amount: number): string;
|
|
36
|
-
/** Chooses the perceptually opposite Appearance color for the actual painted fill. */
|
|
37
|
-
export declare function onColor(fill: string, background: string, foreground: string): string;
|
|
38
|
-
/** Chooses readable content when the fill can be evaluated, otherwise preserves Appearance foreground. */
|
|
39
|
-
export declare function contrastingColor(value: Color, colors: AppearanceColors): string;
|
|
40
|
-
/** Solid controls start at base; interaction shades preserve its text choice. */
|
|
41
|
-
export declare function solidColors(base: string, background: string, foreground: string): {
|
|
42
|
-
rest: {
|
|
43
|
-
background: string;
|
|
44
|
-
color: string;
|
|
45
|
-
};
|
|
46
|
-
hover: {
|
|
47
|
-
background: string;
|
|
48
|
-
color: string;
|
|
49
|
-
};
|
|
50
|
-
pressed: {
|
|
51
|
-
background: string;
|
|
52
|
-
color: string;
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
/** Low-emphasis interaction paints derived from the same component-owned base. */
|
|
56
|
-
export declare function subtleColors(base: string, background: string, foreground: string): {
|
|
57
|
-
rest: {
|
|
58
|
-
background: string;
|
|
59
|
-
color: string;
|
|
60
|
-
};
|
|
61
|
-
hover: {
|
|
62
|
-
background: string;
|
|
63
|
-
color: string;
|
|
64
|
-
};
|
|
65
|
-
pressed: {
|
|
66
|
-
background: string;
|
|
67
|
-
color: string;
|
|
68
|
-
};
|
|
69
|
-
};
|