@waveso/ui 0.19.0 → 0.20.0
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 +3 -4
- package/dist/film-grain-shader.d.ts +2 -2
- package/dist/film-grain-shader.js +46 -32
- package/dist/film-grain-webgl.js +1 -1
- package/dist/input.js +1 -1
- package/dist/select.js +1 -1
- package/dist/textarea.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<br />
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
<img src="assets/showcase-placeholder.svg" alt="Wave UI across its three themes — Graphite, Ink, and Paper" width="760" />
|
|
13
|
+
<img src="assets/showcase.svg" alt="Wave UI across its three themes — Graphite, Ink, and Paper" width="760" />
|
|
15
14
|
|
|
16
15
|
<br /><br />
|
|
17
16
|
|
|
@@ -85,8 +84,8 @@ Wave pays close attention to token taxonomy. Surfaces encode elevation; borders
|
|
|
85
84
|
### Text — contrast
|
|
86
85
|
|
|
87
86
|
- `--contrast` — titles, primary text
|
|
88
|
-
- `--muted` — body text, icons, any mark
|
|
89
|
-
- `--subtle` —
|
|
87
|
+
- `--muted` — body text, placeholders, icons, any mark
|
|
88
|
+
- `--subtle` — hints
|
|
90
89
|
|
|
91
90
|
### Brand — colour
|
|
92
91
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/film-grain-shader.d.ts
|
|
2
|
-
export declare const vertexShader = "\
|
|
3
|
-
export declare const fragmentShader = "\nprecision highp float;\n\nuniform float uTime;\nuniform vec2 uResolution;\nuniform float uDensity;\nuniform float uOpacity;\nuniform float uFps;\nuniform vec3 uColor;\n\
|
|
2
|
+
export declare const vertexShader = "#version 300 es\nin vec2 position;\nout vec2 vUv;\n\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}\n";
|
|
3
|
+
export declare const fragmentShader = "#version 300 es\nprecision highp float;\n\nuniform float uTime;\nuniform vec2 uResolution;\nuniform float uDensity;\nuniform float uOpacity;\nuniform float uFps;\nuniform vec3 uColor;\n\nin vec2 vUv;\nout vec4 fragColor;\n\n// Integer hash (two rounds of a permuted congruential mix): three\n// independent values from three inputs, identical on every GPU. No sine:\n// a sine hash loses precision on some mobile GPUs and draws faint stripes.\nuvec3 hash3(uvec3 v) {\n v = v * 1664525u + 1013904223u;\n v.x += v.y * v.z;\n v.y += v.z * v.x;\n v.z += v.x * v.y;\n v ^= v >> 16u;\n v.x += v.y * v.z;\n v.y += v.z * v.x;\n v.z += v.x * v.y;\n return v;\n}\n\nconst float UNIT = 1.0 / 4294967295.0;\n\n// A pixel's fine speck: the average of two values, so it gathers round the\n// middle as film grain does, with fewer pure darks and lights.\nfloat fine(uvec2 pixel, uint frame) {\n uvec3 h = hash3(uvec3(pixel, frame));\n return (float(h.x) + float(h.y)) * (0.5 * UNIT);\n}\n\n// Film response curve (soft toe + shoulder rolloff)\nfloat filmCurve(float x) {\n return smoothstep(0.0, 0.2, x) * (1.0 - smoothstep(0.8, 1.0, x));\n}\n\nvoid main() {\n uvec2 p = uvec2(gl_FragCoord.xy);\n // The grain changes once per frame of its fps; the component only draws\n // when this changes.\n uint frame = uint(floor(uTime * uFps));\n\n // Multi-scale grain. One hash per 4x4 block gives its coarse speck, its\n // clumping and, a byte for each 2x2 quarter, its medium specks.\n uvec3 block = hash3(uvec3(p >> 2u, frame ^ 0x9e3779b9u));\n uint quarter = ((p.y >> 1u) & 1u) * 2u + ((p.x >> 1u) & 1u);\n float medium = float((block.z >> (quarter * 8u)) & 255u) / 255.0;\n float coarse = float(block.x) * UNIT;\n float grain = fine(p, frame) * 0.65 + medium * 0.25 + coarse * 0.10;\n\n // Emulsion clumping (organic structure)\n grain *= mix(0.75, 1.35, float(block.y) * UNIT);\n\n // Density threshold\n grain = smoothstep(1.0 - uDensity, 1.0, grain);\n\n // Film response curve (replaces raw pow gamma)\n grain = filmCurve(grain);\n\n // Micro-blur: sample neighbors for optical diffusion\n float n1 = fine(p + uvec2(1u, 0u), frame);\n float n2 = fine(p - uvec2(1u, 0u), frame);\n float n3 = fine(p + uvec2(0u, 1u), frame);\n float n4 = fine(p - uvec2(0u, 1u), frame);\n float neighbors = (n1 + n2 + n3 + n4) * 0.25;\n grain = mix(grain, neighbors, 0.15);\n\n // Chromatic aberration (reuse neighbor hashes)\n float rShift = n1 * 0.015;\n float bShift = n2 * 0.015;\n\n vec3 color = uColor * vec3(\n grain + rShift,\n grain,\n grain + bShift\n );\n\n color = clamp(color, 0.0, 1.0);\n\n fragColor = vec4(color, grain * uOpacity);\n}\n";
|
|
4
4
|
//#endregion
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
//#region src/film-grain-shader.ts
|
|
2
|
-
const vertexShader =
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const vertexShader = `#version 300 es
|
|
3
|
+
in vec2 position;
|
|
4
|
+
out vec2 vUv;
|
|
5
5
|
|
|
6
6
|
void main() {
|
|
7
7
|
vUv = position * 0.5 + 0.5;
|
|
8
8
|
gl_Position = vec4(position, 0.0, 1.0);
|
|
9
9
|
}
|
|
10
10
|
`;
|
|
11
|
-
const fragmentShader =
|
|
11
|
+
const fragmentShader = `#version 300 es
|
|
12
12
|
precision highp float;
|
|
13
13
|
|
|
14
14
|
uniform float uTime;
|
|
@@ -18,11 +18,31 @@ uniform float uOpacity;
|
|
|
18
18
|
uniform float uFps;
|
|
19
19
|
uniform vec3 uColor;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
in vec2 vUv;
|
|
22
|
+
out vec4 fragColor;
|
|
23
|
+
|
|
24
|
+
// Integer hash (two rounds of a permuted congruential mix): three
|
|
25
|
+
// independent values from three inputs, identical on every GPU. No sine:
|
|
26
|
+
// a sine hash loses precision on some mobile GPUs and draws faint stripes.
|
|
27
|
+
uvec3 hash3(uvec3 v) {
|
|
28
|
+
v = v * 1664525u + 1013904223u;
|
|
29
|
+
v.x += v.y * v.z;
|
|
30
|
+
v.y += v.z * v.x;
|
|
31
|
+
v.z += v.x * v.y;
|
|
32
|
+
v ^= v >> 16u;
|
|
33
|
+
v.x += v.y * v.z;
|
|
34
|
+
v.y += v.z * v.x;
|
|
35
|
+
v.z += v.x * v.y;
|
|
36
|
+
return v;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const float UNIT = 1.0 / 4294967295.0;
|
|
22
40
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
// A pixel's fine speck: the average of two values, so it gathers round the
|
|
42
|
+
// middle as film grain does, with fewer pure darks and lights.
|
|
43
|
+
float fine(uvec2 pixel, uint frame) {
|
|
44
|
+
uvec3 h = hash3(uvec3(pixel, frame));
|
|
45
|
+
return (float(h.x) + float(h.y)) * (0.5 * UNIT);
|
|
26
46
|
}
|
|
27
47
|
|
|
28
48
|
// Film response curve (soft toe + shoulder rolloff)
|
|
@@ -31,27 +51,21 @@ float filmCurve(float x) {
|
|
|
31
51
|
}
|
|
32
52
|
|
|
33
53
|
void main() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
float
|
|
44
|
-
float
|
|
45
|
-
float
|
|
46
|
-
|
|
47
|
-
float medium = hash(floor(uv * 0.5), seed + 3.1);
|
|
48
|
-
float coarse = hash(floor(uv * 0.25), seed + 7.93);
|
|
49
|
-
|
|
50
|
-
float grain = fine * 0.65 + medium * 0.25 + coarse * 0.10;
|
|
54
|
+
uvec2 p = uvec2(gl_FragCoord.xy);
|
|
55
|
+
// The grain changes once per frame of its fps; the component only draws
|
|
56
|
+
// when this changes.
|
|
57
|
+
uint frame = uint(floor(uTime * uFps));
|
|
58
|
+
|
|
59
|
+
// Multi-scale grain. One hash per 4x4 block gives its coarse speck, its
|
|
60
|
+
// clumping and, a byte for each 2x2 quarter, its medium specks.
|
|
61
|
+
uvec3 block = hash3(uvec3(p >> 2u, frame ^ 0x9e3779b9u));
|
|
62
|
+
uint quarter = ((p.y >> 1u) & 1u) * 2u + ((p.x >> 1u) & 1u);
|
|
63
|
+
float medium = float((block.z >> (quarter * 8u)) & 255u) / 255.0;
|
|
64
|
+
float coarse = float(block.x) * UNIT;
|
|
65
|
+
float grain = fine(p, frame) * 0.65 + medium * 0.25 + coarse * 0.10;
|
|
51
66
|
|
|
52
67
|
// Emulsion clumping (organic structure)
|
|
53
|
-
|
|
54
|
-
grain *= mix(0.75, 1.35, cluster);
|
|
68
|
+
grain *= mix(0.75, 1.35, float(block.y) * UNIT);
|
|
55
69
|
|
|
56
70
|
// Density threshold
|
|
57
71
|
grain = smoothstep(1.0 - uDensity, 1.0, grain);
|
|
@@ -60,10 +74,10 @@ void main() {
|
|
|
60
74
|
grain = filmCurve(grain);
|
|
61
75
|
|
|
62
76
|
// Micro-blur: sample neighbors for optical diffusion
|
|
63
|
-
float n1 =
|
|
64
|
-
float n2 =
|
|
65
|
-
float n3 =
|
|
66
|
-
float n4 =
|
|
77
|
+
float n1 = fine(p + uvec2(1u, 0u), frame);
|
|
78
|
+
float n2 = fine(p - uvec2(1u, 0u), frame);
|
|
79
|
+
float n3 = fine(p + uvec2(0u, 1u), frame);
|
|
80
|
+
float n4 = fine(p - uvec2(0u, 1u), frame);
|
|
67
81
|
float neighbors = (n1 + n2 + n3 + n4) * 0.25;
|
|
68
82
|
grain = mix(grain, neighbors, 0.15);
|
|
69
83
|
|
|
@@ -79,7 +93,7 @@ void main() {
|
|
|
79
93
|
|
|
80
94
|
color = clamp(color, 0.0, 1.0);
|
|
81
95
|
|
|
82
|
-
|
|
96
|
+
fragColor = vec4(color, grain * uOpacity);
|
|
83
97
|
}
|
|
84
98
|
`;
|
|
85
99
|
//#endregion
|
package/dist/film-grain-webgl.js
CHANGED
|
@@ -125,7 +125,7 @@ function useFilmGrain({ density, fps = 18, color = "#ffffff" }) {
|
|
|
125
125
|
dpr
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
|
-
const canGetWebGL = (c) =>
|
|
128
|
+
const canGetWebGL = (c) => c.getContext("webgl2");
|
|
129
129
|
const probeGl = canGetWebGL(document.createElement("canvas"));
|
|
130
130
|
const webglSupported = probeGl ? initWebGL(probeGl) !== null : false;
|
|
131
131
|
probeGl?.getExtension("WEBGL_lose_context")?.loseContext();
|
package/dist/input.js
CHANGED
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { Input as Input$1 } from "@base-ui/react/input";
|
|
5
5
|
//#region src/input.tsx
|
|
6
|
-
const inputVariants = cva("bg-neutral hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger placeholder:text-
|
|
6
|
+
const inputVariants = cva("bg-neutral hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger placeholder:text-muted flex w-full min-w-0 items-center overflow-hidden rounded-md border border-transparent motion-color focus-visible:outline-hidden file:inline-flex file:my-[3px] file:items-center file:me-3 file:cursor-clickable file:rounded-md file:border-0 file:bg-primary file:px-2.5 file:leading-none file:font-medium file:text-white file:motion-color file:hover:bg-primary/80 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3", {
|
|
7
7
|
variants: { size: {
|
|
8
8
|
xs: "h-6 rounded-sm px-2 text-xs file:-ms-[5px] file:h-4",
|
|
9
9
|
sm: "h-8 px-3 text-sm file:-ms-[9px] file:h-6",
|
package/dist/select.js
CHANGED
|
@@ -5,7 +5,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import { Select as Select$1 } from "@base-ui/react/select";
|
|
7
7
|
//#region src/select.tsx
|
|
8
|
-
const selectTriggerVariants = cva("data-placeholder:text-
|
|
8
|
+
const selectTriggerVariants = cva("data-placeholder:text-muted bg-neutral hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger flex w-fit items-center justify-between gap-1.5 rounded-md border border-transparent whitespace-nowrap motion-color focus-visible:outline-hidden select-none focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
9
9
|
variants: { size: {
|
|
10
10
|
xs: "h-6 rounded-sm px-2 text-xs",
|
|
11
11
|
sm: "h-8 px-3 text-sm",
|
package/dist/textarea.js
CHANGED
|
@@ -3,7 +3,7 @@ import { cn } from "./lib/utils.js";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
//#region src/textarea.tsx
|
|
6
|
-
const textareaVariants = cva("bg-neutral hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger resize-y resize-handle disabled:pointer-events-none placeholder:text-
|
|
6
|
+
const textareaVariants = cva("bg-neutral hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger resize-y resize-handle disabled:pointer-events-none placeholder:text-muted flex field-sizing-content w-full rounded-md border border-transparent motion-color focus-visible:outline-hidden focus-visible:ring-3 disabled:opacity-30 aria-invalid:ring-3", {
|
|
7
7
|
variants: { size: {
|
|
8
8
|
xs: "min-h-12 rounded-sm px-2 py-1 text-xs",
|
|
9
9
|
sm: "min-h-14 px-3 py-1.5 text-sm",
|