@phreshos/react-ui 0.1.10 → 0.1.11

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 CHANGED
@@ -27,14 +27,22 @@ collapses Appearance into a second retained object.
27
27
  An application using the Client SDK composes the packages explicitly:
28
28
 
29
29
  ```tsx
30
+ import { useDocumentColorScheme } from "@phreshos/react-ui"
31
+
30
32
  const appearance = useSystemAppearance()
31
- const theme = useSystemTheme()
33
+ const { theme } = useDesktopPreferences()
34
+ useDocumentColorScheme(theme)
32
35
 
33
36
  return <AppearanceProvider appearance={appearance} theme={theme}>
34
37
  {children}
35
38
  </AppearanceProvider>
36
39
  ```
37
40
 
41
+ `useDocumentColorScheme(theme)` explicitly synchronizes the document root's
42
+ native `color-scheme` and restores its previous value on unmount. Call it once
43
+ at the application root; reading Theme or Desktop preferences has no document
44
+ side effect.
45
+
38
46
  ## Levels
39
47
 
40
48
  `useScale(value)` and `useColor(value)` derive semantic UI levels from one
@@ -65,5 +73,6 @@ Appearance; elevation stays with the surrounding layout.
65
73
  - `Flex` and `Grid`: small layout primitives that preserve native props.
66
74
  - `AppearanceProvider`, `useAppearance`, `useTheme`, `useResolveTheme`:
67
75
  environment-neutral appearance composition.
76
+ - `useDocumentColorScheme`: explicit browser document integration.
68
77
  - `useScale`, `useColor`, `resolveSpacing`, `resolveRadius`: explicit visual
69
78
  derivation helpers.
@@ -0,0 +1,3 @@
1
+ import type { Theme } from "@phreshos/core";
2
+ /** Keeps the document root's native color scheme aligned with one effective Theme. */
3
+ export default function useDocumentColorScheme(theme: Theme): void;
@@ -0,0 +1,10 @@
1
+ import { useLayoutEffect } from "react";
2
+ /** Keeps the document root's native color scheme aligned with one effective Theme. */
3
+ export default function useDocumentColorScheme(theme) {
4
+ useLayoutEffect(() => {
5
+ const root = document.documentElement;
6
+ const previous = root.style.colorScheme;
7
+ root.style.colorScheme = theme;
8
+ return () => { root.style.colorScheme = previous; };
9
+ }, [theme]);
10
+ }
package/dist/main.d.ts CHANGED
@@ -5,9 +5,10 @@
5
5
  * behavior contract has been established by the package's tests.
6
6
  */
7
7
  export { AppearanceProvider, useAppearance, useResolveTheme, useTheme, type AppearanceProviderProps } from "./appearance-provider.js";
8
+ export { default as useDocumentColorScheme } from "./document-color-scheme.js";
8
9
  export { Flex, type FlexProps } from "./flex.js";
9
10
  export { Grid, type GridProps } from "./grid.js";
10
- export { Surface, type SurfaceColor, type SurfaceProps } from "./surface.js";
11
+ export { Surface, type SurfaceProps } from "./surface.js";
11
12
  export { Button, type ButtonProps } from "./button.js";
12
13
  export type { LayoutAlignment, LayoutGap, LayoutJustification } from "./layout.js";
13
14
  export { resolveRadius, type Radius, type RadiusProps } from "./radius.js";
package/dist/main.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * behavior contract has been established by the package's tests.
6
6
  */
7
7
  export { AppearanceProvider, useAppearance, useResolveTheme, useTheme } from "./appearance-provider.js";
8
+ export { default as useDocumentColorScheme } from "./document-color-scheme.js";
8
9
  export { Flex } from "./flex.js";
9
10
  export { Grid } from "./grid.js";
10
11
  export { Surface } from "./surface.js";
package/dist/surface.d.ts CHANGED
@@ -1,12 +1,7 @@
1
1
  import type { ComponentPropsWithoutRef } from "react";
2
- import { type ColorLevel } from "./color.js";
3
2
  import { type ScaleLevel } from "./scale.js";
4
- /** An Appearance-derived treatment or direct CSS color. */
5
- export type SurfaceColor = ColorLevel | (string & {});
6
3
  /** Native div properties plus controls for the locally owned material. */
7
- export type SurfaceProps = Omit<ComponentPropsWithoutRef<"div">, "color" | "opacity"> & Readonly<{
8
- /** Appearance-derived treatment or direct CSS material color. */
9
- color?: SurfaceColor;
4
+ export type SurfaceProps = Omit<ComponentPropsWithoutRef<"div">, "opacity"> & Readonly<{
10
5
  /** Appearance-derived level or direct grain intensity from zero to one. */
11
6
  grain?: ScaleLevel | number;
12
7
  /** Appearance-derived level or direct retained grain amount from zero to one. */
@@ -27,9 +22,7 @@ export type SurfaceProps = Omit<ComponentPropsWithoutRef<"div">, "color" | "opac
27
22
  brightness?: ScaleLevel | number;
28
23
  }>;
29
24
  /** Contains content above locally owned Surface material layers. */
30
- export declare const Surface: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "opacity" | "color"> & Readonly<{
31
- /** Appearance-derived treatment or direct CSS material color. */
32
- color?: SurfaceColor;
25
+ export declare const Surface: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "opacity"> & Readonly<{
33
26
  /** Appearance-derived level or direct grain intensity from zero to one. */
34
27
  grain?: ScaleLevel | number;
35
28
  /** Appearance-derived level or direct retained grain amount from zero to one. */
package/dist/surface.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef, useCallback, useId, useLayoutEffect, useRef } from "react";
3
3
  import { appearanceLimits } from "@phreshos/core";
4
- import { color as deriveColor } from "./color.js";
5
4
  import { isScaleLevel, scale, scaleMultiplier } from "./scale.js";
6
5
  import { SurfaceMaterial } from "./surface-material.js";
7
6
  import { useAppearance, useResolveTheme } from "./appearance-provider.js";
@@ -12,7 +11,7 @@ const layerStyle = {
12
11
  pointerEvents: "none"
13
12
  };
14
13
  /** Contains content above locally owned Surface material layers. */
15
- export const Surface = forwardRef(function Surface({ backdrop, brightness, children, color, distortion, grain, grainAmount, opacity, ripples, saturation, style, waves, ...properties }, forwardedRef) {
14
+ export const Surface = forwardRef(function Surface({ backdrop, brightness, children, distortion, grain, grainAmount, opacity, ripples, saturation, style, waves, ...properties }, forwardedRef) {
16
15
  const appearance = useAppearance();
17
16
  const background = useResolveTheme(appearance.background);
18
17
  const foreground = useResolveTheme(appearance.foreground);
@@ -27,7 +26,7 @@ export const Surface = forwardRef(function Surface({ backdrop, brightness, child
27
26
  else if (forwardedRef)
28
27
  forwardedRef.current = node;
29
28
  }, [forwardedRef]);
30
- const resolved = resolveSurface({ backdrop, brightness, color, distortion, grain, grainAmount, opacity, ripples, saturation, waves }, background, surface);
29
+ const resolved = resolveSurface({ backdrop, brightness, distortion, grain, grainAmount, opacity, ripples, saturation, waves }, background, surface);
31
30
  useLayoutEffect(() => {
32
31
  const surface = element.current;
33
32
  if (surface)
@@ -61,7 +60,7 @@ function BackdropLayer({ filter, name, zIndex }) {
61
60
  }
62
61
  function resolveSurface(values, background, surface) {
63
62
  const material = {
64
- color: resolveColor(values.color, background),
63
+ color: background,
65
64
  distortion: resolveScale(values.distortion, surface.distortion, appearanceLimits.surface.distortion),
66
65
  grain: resolveScale(values.grain, surface.grain, appearanceLimits.surface.grain),
67
66
  grainAmount: resolveScale(values.grainAmount, surface.grainAmount, appearanceLimits.surface.grainAmount),
@@ -83,14 +82,6 @@ function resolveSurface(values, background, surface) {
83
82
  refracts: material.distortion > 0 || material.waves > 0 || material.ripples > 0
84
83
  };
85
84
  }
86
- function resolveColor(value, base) {
87
- if (value === undefined)
88
- return base;
89
- return isColorLevel(value) ? deriveColor(base)[value] : value;
90
- }
91
- function isColorLevel(value) {
92
- return value === "subtle" || value === "soft" || value === "base" || value === "strong" || value === "intense";
93
- }
94
85
  function resolveScale(value, base, range) {
95
86
  const resolved = isScaleLevel(value) ? scale(base, value) : value ?? base;
96
87
  const finite = Number.isFinite(resolved) ? resolved : base;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/react-ui",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "React components for coherent PhreshOS Program interfaces.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -52,7 +52,7 @@
52
52
  "prepack": "node --run test && node --run build"
53
53
  },
54
54
  "peerDependencies": {
55
- "@phreshos/core": "^0.1.19",
55
+ "@phreshos/core": "^0.1.22",
56
56
  "react": "^19.2.0",
57
57
  "react-dom": "^19.2.0"
58
58
  },
@@ -61,7 +61,7 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@base-ui/react": "^1.7.0",
64
- "@phreshos/core": "^0.1.19",
64
+ "@phreshos/core": "^0.1.22",
65
65
  "@testing-library/dom": "^10.4.1",
66
66
  "@testing-library/react": "^16.3.0",
67
67
  "@testing-library/user-event": "^14.6.1",