@waveso/ui 0.18.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 +23 -24
- package/dist/checkbox.js +1 -1
- 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/item.js +1 -1
- package/dist/radio.js +1 -1
- package/dist/select.js +1 -1
- package/dist/sidebar.js +2 -2
- package/dist/styles.css +29 -29
- package/dist/switch.js +1 -1
- package/dist/table.js +2 -2
- package/dist/tabs.js +1 -1
- package/dist/textarea.js +1 -1
- package/dist/toggle.js +2 -2
- 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
|
|
|
@@ -47,11 +46,12 @@ Wave builds around an intuitive, intentional **3-tier hierarchy** — for almost
|
|
|
47
46
|
- 3 offset amounts for transforms
|
|
48
47
|
- …and more
|
|
49
48
|
|
|
50
|
-
It
|
|
49
|
+
It builds around semantic intents:
|
|
51
50
|
|
|
52
51
|
- **Background** colors focus on elevation — how deep a surface sits
|
|
53
52
|
- **Content** colors focus on emphasis — how strongly something reads
|
|
54
53
|
- **Border** colors focus on structure — how functional a boundary is
|
|
54
|
+
- **Control** colors focus on state — whether a control is at rest, pointed at or chosen
|
|
55
55
|
|
|
56
56
|
This is the right shape for a system centered on an emphasis ladder: clean and minimal, but flexible.
|
|
57
57
|
|
|
@@ -71,49 +71,48 @@ A pinned class always beats the OS — put `.paper`, `.graphite`, or `.ink` on y
|
|
|
71
71
|
|
|
72
72
|
## Taxonomy
|
|
73
73
|
|
|
74
|
-
Wave pays close attention to token taxonomy. Surfaces encode elevation; borders act as _light interference rather than geometry_.
|
|
74
|
+
Wave pays close attention to token taxonomy. Surfaces encode elevation; borders act as _light interference rather than geometry_. Each of the five families below has three members, each with one job.
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
**Surfaces are solid: they contain. Borders and control fills are see-through:** `line`, `edge`, `contour`, `neutral` and `highlighted` are the theme's text colour made translucent, so they blend into whatever is underneath, for depth and integration. An input inside a primary-coloured banner, or on an accent card, only works if its fill is see-through; a solid control colour can't follow every background. And because controls don't borrow `secondary`, it's free to be a real brand colour.
|
|
77
|
+
|
|
78
|
+
### Surfaces — solid, to contain
|
|
77
79
|
|
|
78
80
|
- `--foundation` — the deepest layer, the base where elevation starts
|
|
79
81
|
- `--surface` — the middle layer: cards, sidebars, content boxes
|
|
80
82
|
- `--elevated` — the highest layer: floating windows, modals, dropdowns, dialogs
|
|
81
83
|
|
|
82
|
-
###
|
|
84
|
+
### Text — contrast
|
|
83
85
|
|
|
84
86
|
- `--contrast` — titles, primary text
|
|
85
|
-
- `--muted` — body text, icons, any mark
|
|
86
|
-
- `--subtle` —
|
|
87
|
+
- `--muted` — body text, placeholders, icons, any mark
|
|
88
|
+
- `--subtle` — hints
|
|
89
|
+
|
|
90
|
+
### Brand — colour
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
- `--primary` — wired to the Wave ramp
|
|
93
|
+
- `--secondary` — the second brand colour, a quiet neutral by default
|
|
94
|
+
- `--accent` — alternative emphasis
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
### Borders — boundary
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
The theme's text colour at three strengths, one job each:
|
|
93
99
|
|
|
94
100
|
- `--line` (5%) — what divides: separators, dividers, hairlines
|
|
95
101
|
- `--edge` (10%) — what bounds a surface: cards, dialogs, popups, toasts
|
|
96
102
|
- `--contour` (15%) — what outlines a control or a region: outline buttons, badges, toggles, layout regions
|
|
97
103
|
|
|
98
|
-
|
|
104
|
+
### Controls — depth
|
|
105
|
+
|
|
106
|
+
A control's state, from resting to chosen:
|
|
99
107
|
|
|
100
|
-
- `--
|
|
101
|
-
- `--
|
|
108
|
+
- `--neutral` (10%) — the look before anything is chosen or pointed at: field and track fills, unchecked boxes, table footers, muted items. Not Tailwind's `neutral-*` grey palette, which Wave doesn't use
|
|
109
|
+
- `--highlighted` (15%) — where attention lands: hovered, keyboard-highlighted and open items, a step stronger than `neutral`
|
|
110
|
+
- `--selected` — chosen, current or on: the current tab, a pressed toggle, a checked box, a selected row. `--primary` by default; set it to restyle every chosen state at once. Chosen items keep white text, so pick a colour it reads on, such as a darker shade of your brand colour
|
|
102
111
|
|
|
103
112
|
### Ring
|
|
104
113
|
|
|
105
114
|
- `--focus` — active / focus states
|
|
106
115
|
|
|
107
|
-
### Selected
|
|
108
|
-
|
|
109
|
-
- `--selected` — chosen, current or on: the current tab, a pressed toggle, a checked box, a selected row. Primary by default; set it to restyle every chosen state at once
|
|
110
|
-
|
|
111
|
-
### Brand
|
|
112
|
-
|
|
113
|
-
- `--primary` — wired to the Wave ramp
|
|
114
|
-
- `--secondary` — neutral fill
|
|
115
|
-
- `--accent` — alternative emphasis
|
|
116
|
-
|
|
117
116
|
### Border strategy
|
|
118
117
|
|
|
119
118
|
This is the sophisticated move most libraries skip.
|
package/dist/checkbox.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Checkbox as Checkbox$1 } from "@base-ui/react/checkbox";
|
|
|
7
7
|
function Checkbox({ className, ...props }) {
|
|
8
8
|
return /* @__PURE__ */ jsx(Checkbox$1.Root, {
|
|
9
9
|
"data-slot": "checkbox",
|
|
10
|
-
className: cn("cursor-clickable bg-neutral border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-
|
|
10
|
+
className: cn("cursor-clickable bg-neutral border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-selected data-indeterminate:bg-selected data-checked:text-white data-indeterminate:text-white data-checked:border-selected data-indeterminate:border-selected aria-invalid:aria-checked:border-selected aria-invalid:border-danger focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 peer relative flex size-6 shrink-0 items-center justify-center rounded-sm border motion-color focus-visible:outline-hidden group-has-disabled/field:opacity-30 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3", className),
|
|
11
11
|
...props,
|
|
12
12
|
children: /* @__PURE__ */ jsxs(Checkbox$1.Indicator, {
|
|
13
13
|
"data-slot": "checkbox-indicator",
|
|
@@ -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/item.js
CHANGED
|
@@ -12,7 +12,7 @@ const itemVariants = cva("[a,button]:hover:bg-highlighted [a,button]:cursor-clic
|
|
|
12
12
|
variant: {
|
|
13
13
|
default: "border-transparent",
|
|
14
14
|
outline: "border-line",
|
|
15
|
-
muted: "bg-
|
|
15
|
+
muted: "bg-neutral border-transparent"
|
|
16
16
|
},
|
|
17
17
|
size: {
|
|
18
18
|
default: "gap-3.5 px-4 py-3.5",
|
package/dist/radio.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Radio as Radio$1 } from "@base-ui/react/radio";
|
|
|
6
6
|
function Radio({ className, ...props }) {
|
|
7
7
|
return /* @__PURE__ */ jsx(Radio$1.Root, {
|
|
8
8
|
"data-slot": "radio",
|
|
9
|
-
className: cn("cursor-clickable bg-neutral border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-
|
|
9
|
+
className: cn("cursor-clickable bg-neutral border-transparent not-data-disabled:data-unchecked:hover:border-focus not-data-disabled:data-unchecked:group-hover/field:border-focus data-checked:bg-selected data-checked:text-white data-checked:border-selected aria-invalid:aria-checked:border-selected aria-invalid:border-danger focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 group/radio peer relative flex aspect-square size-6 shrink-0 rounded-full border motion-color focus-visible:outline-hidden group-has-disabled/field:opacity-30 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 aria-invalid:ring-3", className),
|
|
10
10
|
...props,
|
|
11
11
|
children: /* @__PURE__ */ jsx(RadioIndicator, {})
|
|
12
12
|
});
|
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/sidebar.js
CHANGED
|
@@ -299,7 +299,7 @@ function SidebarMenuItem({ className, ...props }) {
|
|
|
299
299
|
...props
|
|
300
300
|
});
|
|
301
301
|
}
|
|
302
|
-
const sidebarMenuButtonVariants = cva("ring-focus/50 hover:bg-highlighted active:bg-highlighted data-active:bg-
|
|
302
|
+
const sidebarMenuButtonVariants = cva("ring-focus/50 hover:bg-highlighted active:bg-highlighted data-active:bg-selected data-active:text-white gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[slot=sidebar-menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:w-full group-data-[collapsible=icon]:aspect-square group-data-[collapsible=icon]:h-11 focus-visible:ring-3 data-active:font-medium peer/menu-button flex w-full items-center overflow-hidden focus-visible:outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-30 aria-disabled:pointer-events-none aria-disabled:opacity-30 [&>span:last-child]:truncate [&_svg]:shrink-0", {
|
|
303
303
|
variants: {
|
|
304
304
|
variant: {
|
|
305
305
|
default: "",
|
|
@@ -387,7 +387,7 @@ function SidebarMenuSubItem({ className, ...props }) {
|
|
|
387
387
|
function SidebarMenuSubButton({ render, size = "md", isActive = false, className, ...props }) {
|
|
388
388
|
return useRender({
|
|
389
389
|
defaultTagName: "a",
|
|
390
|
-
props: mergeProps({ className: cn("text-contrast ring-focus/50 hover:bg-highlighted active:bg-highlighted data-active:bg-
|
|
390
|
+
props: mergeProps({ className: cn("text-contrast ring-focus/50 hover:bg-highlighted active:bg-highlighted data-active:bg-selected data-active:text-white h-7 gap-2 rounded-md px-2 focus-visible:ring-3 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden focus-visible:outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-30 aria-disabled:pointer-events-none aria-disabled:opacity-30 [&>span:last-child]:truncate [&>svg]:shrink-0", className) }, props),
|
|
391
391
|
render,
|
|
392
392
|
state: {
|
|
393
393
|
slot: "sidebar-menu-sub-button",
|
package/dist/styles.css
CHANGED
|
@@ -279,22 +279,21 @@
|
|
|
279
279
|
--ink-900: oklch(0.201 0.038 257); /* #0B1627 */
|
|
280
280
|
--ink-950: oklch(0.132 0.027 252); /* #020812 */
|
|
281
281
|
|
|
282
|
-
/* Paper — warm stone on a white page.
|
|
283
|
-
* cards (50)
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
* sRGB colours, the same on Display-P3 screens. */
|
|
282
|
+
/* Paper — warm stone on a white page. Its ends are its own colours, the
|
|
283
|
+
* cards (50) and the text (950); the steps between follow Ink's spacing, so
|
|
284
|
+
* the ramp falls smoothly all the way into the text colour. The warmth
|
|
285
|
+
* peaks at the 300 and eases into the text greys. The page is white, so it
|
|
286
|
+
* isn't a step; these are sRGB colours, the same on Display-P3 screens. */
|
|
288
287
|
--paper-50: oklch(0.989 0.002 67.8); /* #FCFBFA */
|
|
289
|
-
--paper-100: oklch(0.
|
|
290
|
-
--paper-200: oklch(0.
|
|
291
|
-
--paper-300: oklch(0.
|
|
292
|
-
--paper-400: oklch(0.
|
|
293
|
-
--paper-500: oklch(0.
|
|
294
|
-
--paper-600: oklch(0.
|
|
295
|
-
--paper-700: oklch(0.
|
|
296
|
-
--paper-800: oklch(0.
|
|
297
|
-
--paper-900: oklch(0.
|
|
288
|
+
--paper-100: oklch(0.929 0.002 67.8); /* #E8E7E6 */
|
|
289
|
+
--paper-200: oklch(0.850 0.007 67.7); /* #D1CDC9 */
|
|
290
|
+
--paper-300: oklch(0.756 0.010 72.6); /* #B4AFA9 */
|
|
291
|
+
--paper-400: oklch(0.668 0.008 64.9); /* #989490 */
|
|
292
|
+
--paper-500: oklch(0.567 0.006 52.9); /* #797673 */
|
|
293
|
+
--paper-600: oklch(0.465 0.005 34.3); /* #5C5857 */
|
|
294
|
+
--paper-700: oklch(0.372 0.004 34.3); /* #423F3F */
|
|
295
|
+
--paper-800: oklch(0.296 0.003 34.3); /* #2E2C2C */
|
|
296
|
+
--paper-900: oklch(0.228 0.001 34.3); /* #1D1C1C */
|
|
298
297
|
--paper-950: oklch(0.159 0 0); /* #0D0D0D */
|
|
299
298
|
|
|
300
299
|
/* ========================================================================
|
|
@@ -566,8 +565,8 @@
|
|
|
566
565
|
--line: color-mix(in srgb, var(--paper-950) 5%, transparent);
|
|
567
566
|
--edge: color-mix(in srgb, var(--paper-950) 10%, transparent);
|
|
568
567
|
--contour: color-mix(in srgb, var(--paper-950) 15%, transparent);
|
|
569
|
-
--highlighted: color-mix(in srgb, var(--paper-950)
|
|
570
|
-
--neutral: color-mix(in srgb, var(--paper-950)
|
|
568
|
+
--highlighted: color-mix(in srgb, var(--paper-950) 15%, transparent);
|
|
569
|
+
--neutral: color-mix(in srgb, var(--paper-950) 10%, transparent);
|
|
571
570
|
--shadow-strength: 0.055;
|
|
572
571
|
--danger: var(--wave-red-500);
|
|
573
572
|
--danger-text: var(--wave-red-600);
|
|
@@ -601,8 +600,8 @@
|
|
|
601
600
|
--line: color-mix(in srgb, var(--graphite-50) 5%, transparent);
|
|
602
601
|
--edge: color-mix(in srgb, var(--graphite-50) 10%, transparent);
|
|
603
602
|
--contour: color-mix(in srgb, var(--graphite-50) 15%, transparent);
|
|
604
|
-
--highlighted: color-mix(in srgb, var(--graphite-50)
|
|
605
|
-
--neutral: color-mix(in srgb, var(--graphite-50)
|
|
603
|
+
--highlighted: color-mix(in srgb, var(--graphite-50) 15%, transparent);
|
|
604
|
+
--neutral: color-mix(in srgb, var(--graphite-50) 10%, transparent);
|
|
606
605
|
--shadow-strength: 0.045;
|
|
607
606
|
--danger: var(--wave-red-500);
|
|
608
607
|
--danger-text: oklch(0.749 0.152 16.8); /* #FF828B, see below */
|
|
@@ -626,8 +625,8 @@
|
|
|
626
625
|
--line: color-mix(in srgb, var(--graphite-50) 5%, transparent);
|
|
627
626
|
--edge: color-mix(in srgb, var(--graphite-50) 10%, transparent);
|
|
628
627
|
--contour: color-mix(in srgb, var(--graphite-50) 15%, transparent);
|
|
629
|
-
--highlighted: color-mix(in srgb, var(--graphite-50)
|
|
630
|
-
--neutral: color-mix(in srgb, var(--graphite-50)
|
|
628
|
+
--highlighted: color-mix(in srgb, var(--graphite-50) 15%, transparent);
|
|
629
|
+
--neutral: color-mix(in srgb, var(--graphite-50) 10%, transparent);
|
|
631
630
|
--shadow-strength: 0.045;
|
|
632
631
|
--danger: var(--wave-red-500);
|
|
633
632
|
--danger-text: oklch(0.749 0.152 16.8); /* #FF828B, see below */
|
|
@@ -680,8 +679,8 @@
|
|
|
680
679
|
--line: color-mix(in srgb, var(--ink-50) 5%, transparent);
|
|
681
680
|
--edge: color-mix(in srgb, var(--ink-50) 10%, transparent);
|
|
682
681
|
--contour: color-mix(in srgb, var(--ink-50) 15%, transparent);
|
|
683
|
-
--highlighted: color-mix(in srgb, var(--ink-50)
|
|
684
|
-
--neutral: color-mix(in srgb, var(--ink-50)
|
|
682
|
+
--highlighted: color-mix(in srgb, var(--ink-50) 15%, transparent);
|
|
683
|
+
--neutral: color-mix(in srgb, var(--ink-50) 10%, transparent);
|
|
685
684
|
--shadow-strength: 0.045;
|
|
686
685
|
--danger: var(--wave-red-500);
|
|
687
686
|
--danger-text: var(--wave-red-400);
|
|
@@ -729,12 +728,13 @@
|
|
|
729
728
|
* always as a border (rings are kept for focus and invalid halos).
|
|
730
729
|
* `contour` (15%) outlines a control or a region: outline buttons, badges,
|
|
731
730
|
* toggles, the slider thumb, menubars.
|
|
732
|
-
* Fills, one job each: `
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
731
|
+
* Fills, one job each: `neutral` (10%) is the look before anything is
|
|
732
|
+
* chosen or pointed at: a control's body (field and track fills, unchecked
|
|
733
|
+
* boxes) and a quiet region (a table footer, a muted item). `highlighted`
|
|
734
|
+
* (15%) marks where attention lands: hovered, keyboard-highlighted and
|
|
735
|
+
* open items, always a step stronger than resting. (Tailwind's own
|
|
736
|
+
* `neutral-50` … `neutral-950` greys are a separate palette Wave doesn't
|
|
737
|
+
* use.) `focus` is the brand-themed ring (= primary). */
|
|
738
738
|
--color-line: var(--line);
|
|
739
739
|
--color-edge: var(--edge);
|
|
740
740
|
--color-contour: var(--contour);
|
package/dist/switch.js
CHANGED
|
@@ -4,7 +4,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
import { Switch as Switch$1 } from "@base-ui/react/switch";
|
|
6
6
|
//#region src/switch.tsx
|
|
7
|
-
const switchVariants = cva("@container cursor-clickable data-checked:bg-
|
|
7
|
+
const switchVariants = cva("@container cursor-clickable data-checked:bg-selected data-unchecked:bg-neutral data-unchecked:hover:border-focus focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger peer relative inline-flex shrink-0 items-center rounded-full border border-transparent motion-color focus-visible:outline-hidden after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 aria-invalid:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30", {
|
|
8
8
|
variants: { size: {
|
|
9
9
|
default: "h-6 w-11 p-1",
|
|
10
10
|
sm: "h-4 w-7 p-0.5"
|
package/dist/table.js
CHANGED
|
@@ -61,14 +61,14 @@ function TableBody({ className, ...props }) {
|
|
|
61
61
|
function TableFooter({ className, ...props }) {
|
|
62
62
|
return /* @__PURE__ */ jsx("tfoot", {
|
|
63
63
|
"data-slot": "table-footer",
|
|
64
|
-
className: cn("bg-
|
|
64
|
+
className: cn("bg-neutral border-t border-line font-medium [&>tr]:last:border-b-0", className),
|
|
65
65
|
...props
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
function TableRow({ className, ...props }) {
|
|
69
69
|
return /* @__PURE__ */ jsx("tr", {
|
|
70
70
|
"data-slot": "table-row",
|
|
71
|
-
className: cn("hover:bg-highlighted data-selected:bg-
|
|
71
|
+
className: cn("hover:bg-highlighted data-selected:bg-selected data-selected:text-white data-selected:**:data-[slot=checkbox]:border-white border-b border-line motion-color", className),
|
|
72
72
|
...props
|
|
73
73
|
});
|
|
74
74
|
}
|
package/dist/tabs.js
CHANGED
|
@@ -30,7 +30,7 @@ function TabsList({ className, variant = "default", ...props }) {
|
|
|
30
30
|
function TabsTrigger({ className, ...props }) {
|
|
31
31
|
return /* @__PURE__ */ jsx(Tabs$1.Tab, {
|
|
32
32
|
"data-slot": "tabs-trigger",
|
|
33
|
-
className: cn("cursor-clickable text-muted hover:text-contrast relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-2 rounded-sm border border-transparent px-3 py-1 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 text-sm font-medium whitespace-nowrap motion-color focus-visible:outline-hidden focus-visible:border-focus focus-visible:ring-focus/50 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start group-data-[orientation=vertical]/tabs:py-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "data-active:bg-
|
|
33
|
+
className: cn("cursor-clickable text-muted hover:text-contrast relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-2 rounded-sm border border-transparent px-3 py-1 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2 text-sm font-medium whitespace-nowrap motion-color focus-visible:outline-hidden focus-visible:border-focus focus-visible:ring-focus/50 focus-visible:ring-3 data-disabled:pointer-events-none data-disabled:opacity-30 group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start group-data-[orientation=vertical]/tabs:py-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "data-active:bg-selected data-active:text-white", "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent group-data-[variant=line]/tabs-list:data-active:text-contrast", "after:bg-contrast after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-end-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", className),
|
|
34
34
|
...props
|
|
35
35
|
});
|
|
36
36
|
}
|
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",
|
package/dist/toggle.js
CHANGED
|
@@ -7,8 +7,8 @@ import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
|
|
|
7
7
|
const toggleVariants = cva("cursor-clickable focus-visible:border-focus focus-visible:ring-focus/50 aria-invalid:ring-danger/30 aria-invalid:border-danger rounded-md border border-transparent bg-clip-padding font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap motion-color data-disabled:pointer-events-none data-disabled:opacity-30 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 focus-visible:outline-hidden group/toggle select-none active:scale-[0.97]", {
|
|
8
8
|
variants: {
|
|
9
9
|
variant: {
|
|
10
|
-
default: "text-contrast hover:bg-highlighted data-pressed:bg-
|
|
11
|
-
outline: "border-contour bg-foundation hover:bg-highlighted hover:text-contrast data-pressed:border-
|
|
10
|
+
default: "text-contrast hover:bg-highlighted data-pressed:bg-selected data-pressed:text-white data-pressed:hover:bg-selected/80 not-supports-backdrop-filter:data-pressed:hover:bg-selected/90 data-pressed:hover:backdrop-blur-xl data-pressed:hover:backdrop-saturate-150",
|
|
11
|
+
outline: "border-contour bg-foundation hover:bg-highlighted hover:text-contrast data-pressed:border-selected data-pressed:bg-selected data-pressed:text-white data-pressed:hover:bg-selected/80 not-supports-backdrop-filter:data-pressed:hover:bg-selected/90 data-pressed:hover:backdrop-blur-xl data-pressed:hover:backdrop-saturate-150"
|
|
12
12
|
},
|
|
13
13
|
size: {
|
|
14
14
|
default: "h-9 min-w-9 gap-1.5 px-3 text-base has-data-[icon=inline-end]:pe-2.5 has-data-[icon=inline-start]:ps-2.5",
|