@phreshos/react-ui 0.1.2 → 0.1.4

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
@@ -120,36 +120,14 @@ const colors = useColor(theme.accent)
120
120
  <strong style={{ color: colors.strong }} />
121
121
  ```
122
122
 
123
- `GlassSurface` is the shared translucent material. The Theme supplies its
124
- background, foreground, and concrete default values for distortion, blur,
125
- saturation, brightness, and material opacity. The component derives its tint
126
- from the background and applies the foreground to its content, while accent
127
- remains independent for emphasis and interaction. The surface may also derive
128
- a small or large treatment from each numeric default without turning those
129
- levels into system state.
130
-
131
- Derived opacity is capped at thirty percent and never fades the surface's
132
- content. Layout, spacing, radius, and external elevation remain ordinary
133
- container concerns:
134
-
135
- ```tsx
136
- <GlassSurface className="rounded-xl p-3">
137
- ...
138
- </GlassSurface>
139
-
140
- <GlassSurface color="soft" distortion="large" blur="small" opacity="medium">
141
- ...
142
- </GlassSurface>
143
- ```
144
-
145
123
  Shape-owning components accept the shared `Radius` value directly. Semantic
146
124
  levels are derived from the Theme's concrete radius through the same
147
125
  `scale()` rule used for spacing, while numbers and CSS values remain explicit
148
126
  overrides:
149
127
 
150
128
  ```tsx
151
- <GlassSurface radius="large">...</GlassSurface>
152
- <GlassSurface radius="2rem">...</GlassSurface>
129
+ <Button radius="large">...</Button>
130
+ <Button radius="2rem">...</Button>
153
131
  ```
154
132
 
155
133
  Structures whose native element owns the shape derive from the explicit
package/dist/main.d.ts CHANGED
@@ -8,7 +8,6 @@ export { ThemeProvider, useTheme, type ThemeProviderProps } from "./theme-provid
8
8
  export { Flex, type FlexProps } from "./flex.js";
9
9
  export { Grid, type GridProps } from "./grid.js";
10
10
  export { Surface, type SurfaceColor, type SurfaceProps } from "./surface.js";
11
- export { GlassSurface, type GlassSurfaceProps } from "./glass-surface.js";
12
11
  export { Button, type ButtonProps } from "./button.js";
13
12
  export type { LayoutAlignment, LayoutGap, LayoutJustification } from "./layout.js";
14
13
  export { resolveRadius, type Radius, type RadiusProps } from "./radius.js";
package/dist/main.js CHANGED
@@ -8,7 +8,6 @@ export { ThemeProvider, useTheme } from "./theme-provider.js";
8
8
  export { Flex } from "./flex.js";
9
9
  export { Grid } from "./grid.js";
10
10
  export { Surface } from "./surface.js";
11
- export { GlassSurface } from "./glass-surface.js";
12
11
  export { Button } from "./button.js";
13
12
  export { resolveRadius } from "./radius.js";
14
13
  export { resolveSpacing } from "./spacing.js";
@@ -26,12 +26,14 @@ export function SurfaceMaterial({ animation, color, grain, opacity }) {
26
26
  height: "100%",
27
27
  overflow: "hidden",
28
28
  borderRadius: "inherit",
29
+ border: "1px solid rgba(15, 17, 21, 0.08)",
30
+ boxSizing: "border-box",
29
31
  opacity,
30
32
  pointerEvents: "none"
31
33
  }, children: [_jsx("defs", { children: _jsx("pattern", { id: identity, width: patternSize, height: patternSize, patternUnits: "userSpaceOnUse", children: initial.map((path, tone) => {
32
34
  const channel = Math.round(tone / (toneCount - 1) * 255);
33
35
  return _jsx("path", { ref: node => { paths.current[tone] = node; }, "data-surface-grain-tone": tone, d: path, fill: `rgb(${channel}, ${channel}, ${channel})`, shapeRendering: "crispEdges" }, tone);
34
- }) }) }), _jsx("rect", { "data-surface-base": "", width: "100%", height: "100%", fill: color }), _jsx("rect", { "data-surface-grain": "", width: "100%", height: "100%", fill: `url(#${identity})`, opacity: grain, shapeRendering: "crispEdges" }), _jsx("rect", { "data-surface-edge": "", width: "100%", height: "100%", fill: "none", stroke: "rgb(15, 17, 21)", strokeOpacity: "0.08", strokeWidth: "2", vectorEffect: "non-scaling-stroke" })] });
36
+ }) }) }), _jsx("rect", { "data-surface-base": "", width: "100%", height: "100%", fill: color }), _jsx("rect", { "data-surface-grain": "", width: "100%", height: "100%", fill: `url(#${identity})`, opacity: grain, shapeRendering: "crispEdges" })] });
35
37
  }
36
38
  class AnimationClock {
37
39
  #entries = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/react-ui",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
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.7",
55
+ "@phreshos/core": "^0.1.8",
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.7",
64
+ "@phreshos/core": "^0.1.8",
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",
@@ -1,34 +0,0 @@
1
- import type { ComponentPropsWithoutRef } from "react";
2
- import { type Colorable, type ColorLevel, type ScaleLevel } from "@phreshos/core";
3
- import { type RadiusProps } from "./radius.js";
4
- /** Native properties accepted by the shared glass container. */
5
- export type GlassSurfaceProps = ComponentPropsWithoutRef<"div"> & Colorable<ColorLevel> & RadiusProps & Readonly<{
6
- /** Distortion derived from the Theme's concrete default. */
7
- distortion?: ScaleLevel;
8
- /** Blur derived from the Theme's concrete default. */
9
- blur?: ScaleLevel;
10
- /** Saturation derived from the Theme's concrete default. */
11
- saturation?: ScaleLevel;
12
- /** Brightness derived from the Theme's concrete default. */
13
- brightness?: ScaleLevel;
14
- /** Material opacity derived from the Theme's concrete default. */
15
- opacity?: ScaleLevel;
16
- }>;
17
- /**
18
- * Contains content within the shared refracted glass material.
19
- *
20
- * Layout, spacing, radius, and external elevation remain the responsibility of
21
- * the containing interface. Only the material itself is owned here.
22
- */
23
- export declare const GlassSurface: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & Colorable<ColorLevel> & RadiusProps & Readonly<{
24
- /** Distortion derived from the Theme's concrete default. */
25
- distortion?: ScaleLevel;
26
- /** Blur derived from the Theme's concrete default. */
27
- blur?: ScaleLevel;
28
- /** Saturation derived from the Theme's concrete default. */
29
- saturation?: ScaleLevel;
30
- /** Brightness derived from the Theme's concrete default. */
31
- brightness?: ScaleLevel;
32
- /** Material opacity derived from the Theme's concrete default. */
33
- opacity?: ScaleLevel;
34
- }> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,40 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useId } from "react";
3
- import { color as deriveColor, scale, scaleMultiplier, themeLimits } from "@phreshos/core";
4
- import { colorOpacity } from "./color.js";
5
- import { resolveRadius } from "./radius.js";
6
- import { useTheme } from "./theme-provider.js";
7
- const shell = "inset 1px 1px 0 rgba(255, 255, 255, 0.7), inset -1px -1px 0 rgba(255, 255, 255, 0.28)";
8
- /**
9
- * Contains content within the shared refracted glass material.
10
- *
11
- * Layout, spacing, radius, and external elevation remain the responsibility of
12
- * the containing interface. Only the material itself is owned here.
13
- */
14
- export const GlassSurface = forwardRef(function GlassSurface({ blur = "medium", brightness = "medium", children, color = "base", distortion = "medium", opacity = "medium", radius, saturation = "medium", style, ...properties }, ref) {
15
- const theme = useTheme();
16
- const filter = `phresh-glass-${useId().replaceAll(":", "")}`;
17
- const backdrop = glassBackdrop(theme.glass, { blur, brightness, saturation });
18
- const alpha = boundedOpacity(scale(theme.glass.opacity, opacity));
19
- const tint = deriveColor(theme.background)[color];
20
- const borderRadius = resolveRadius(radius, theme);
21
- return _jsxs("div", { ...properties, ref: ref, style: {
22
- ...style,
23
- ...(borderRadius === undefined ? {} : { borderRadius }),
24
- color: theme.foreground,
25
- backgroundColor: colorOpacity(tint, alpha),
26
- backgroundImage: `linear-gradient(to bottom, ${colorOpacity(tint, boundedOpacity(alpha * 5 / 3))}, ${colorOpacity(tint, boundedOpacity(alpha / 2))})`,
27
- boxShadow: shell,
28
- backdropFilter: `url(#${filter}) ${backdrop}`,
29
- WebkitBackdropFilter: backdrop,
30
- isolation: "isolate",
31
- overflow: "hidden"
32
- }, children: [_jsx("svg", { "aria-hidden": "true", width: "0", height: "0", style: { position: "absolute" }, children: _jsxs("filter", { id: filter, x: "0%", y: "0%", width: "100%", height: "100%", children: [_jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.008 0.008", numOctaves: "2", seed: "92", result: "noise" }), _jsx("feGaussianBlur", { in: "noise", stdDeviation: "2", result: "blurred" }), _jsx("feDisplacementMap", { in: "SourceGraphic", in2: "blurred", scale: scale(theme.glass.distortion, distortion), xChannelSelector: "R", yChannelSelector: "G" })] }) }), children] });
33
- });
34
- function glassBackdrop(glass, levels) {
35
- return `blur(${scale(glass.blur, levels.blur)}px) saturate(${scaleMultiplier(glass.saturation, levels.saturation)}) brightness(${scaleMultiplier(glass.brightness, levels.brightness)})`;
36
- }
37
- /** Keeps every derived tint within the system's maximum glass opacity. */
38
- function boundedOpacity(value) {
39
- return Math.round(Math.min(themeLimits.glass.opacity.maximum, Math.max(0, value)) * 10_000) / 10_000;
40
- }