@phreshos/react-ui 0.1.28 → 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.
@@ -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.28",
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.53",
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"