@aberhamm/liquid-glass-react 0.2.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/LICENSE +38 -0
- package/README.md +627 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +1191 -0
- package/dist/index.d.ts +1191 -0
- package/dist/index.mjs +1314 -0
- package/dist/liquid-glass-react.css +1 -0
- package/dist/native/index.native.d.ts +19 -0
- package/dist/native/index.native.js +19 -0
- package/dist/native/liquid-glass.native.d.ts +65 -0
- package/dist/native/liquid-glass.native.js +200 -0
- package/dist/native/tokens.d.ts +245 -0
- package/dist/native/tokens.js +254 -0
- package/dist/native/types.d.ts +464 -0
- package/dist/native/types.js +9 -0
- package/package.json +122 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-neutral design tokens (plan 022).
|
|
3
|
+
*
|
|
4
|
+
* The single source of truth for the library's plain-data design constants —
|
|
5
|
+
* tint/saturation defaults, the blur-per-unit mapping, the drop-shadow layers
|
|
6
|
+
* and scroll-aware depth factors, the specular/press-glow geometry, the
|
|
7
|
+
* material-variant parameters, and the accessibility (reduced-transparency /
|
|
8
|
+
* increased-contrast) fills. These were previously embedded as web-local
|
|
9
|
+
* `const`s inside `liquid-glass.tsx`; they live here so BOTH the web file
|
|
10
|
+
* (`liquid-glass.tsx`) and the future React Native file
|
|
11
|
+
* (`liquid-glass.native.tsx`, plan 025) can consume ONE source of truth.
|
|
12
|
+
*
|
|
13
|
+
* ## Hard constraints (what may live here)
|
|
14
|
+
*
|
|
15
|
+
* This module is a leaf with ZERO platform coupling:
|
|
16
|
+
*
|
|
17
|
+
* - It imports nothing from the React renderer packages.
|
|
18
|
+
* - It contains NO DOM style types and NO browser-global references.
|
|
19
|
+
* - It holds only the underlying NUMBERS / COLORS / structured data. Anything
|
|
20
|
+
* inherently CSS — `mixBlendMode`, `backdrop-filter` strings, the
|
|
21
|
+
* `box-shadow` serialization (`buildDropShadow`), the `radial-gradient`
|
|
22
|
+
* templates — STAYS in the web file. The native file will serialize these
|
|
23
|
+
* same values into RN style objects.
|
|
24
|
+
*
|
|
25
|
+
* The only import is the platform-neutral {@link DisplacementMode} string-union
|
|
26
|
+
* type (no runtime, no DOM), so {@link DEFAULTS.mode} keeps its exact type.
|
|
27
|
+
*
|
|
28
|
+
* @internal Not part of the public package API pre-1.0 (eng-review decision):
|
|
29
|
+
* not re-exported from `index.ts`. The native barrel (plan 025) may import from
|
|
30
|
+
* `./tokens` directly. Exposing publicly later is additive / non-breaking.
|
|
31
|
+
*/
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Defaults (parity spec — plan 004)
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/** Default prop values for `<LiquidGlass>` (the parity spec). */
|
|
36
|
+
export const DEFAULTS = {
|
|
37
|
+
displacementScale: 70,
|
|
38
|
+
blurAmount: 0.0625,
|
|
39
|
+
saturation: 140,
|
|
40
|
+
aberrationIntensity: 2,
|
|
41
|
+
cornerRadius: 999,
|
|
42
|
+
mode: 'standard',
|
|
43
|
+
padding: '24px 32px',
|
|
44
|
+
elasticity: 0.15,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Maps the small public `blurAmount` (default `0.0625`) onto a px backdrop blur.
|
|
48
|
+
* The upstream convention treats `blurAmount` as a rem-ish factor; we scale by
|
|
49
|
+
* 16 (1rem) so the default lands at ~1px and larger values scale linearly.
|
|
50
|
+
*/
|
|
51
|
+
export const BLUR_PX_PER_UNIT = 16;
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Accessibility fills (reduced transparency — plan 013)
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Scheme-aware translucent fill layered ON TOP of the blurred backdrop when
|
|
57
|
+
* `prefers-reduced-transparency: reduce` is active and the backdrop tiers (1/2)
|
|
58
|
+
* still carry a `backdrop-filter`. It frosts the surface toward opaque so the
|
|
59
|
+
* material reads as static frosted glass rather than live lensing. Higher alpha
|
|
60
|
+
* than the tier-3 solid fill because here it composites over a blurred backdrop,
|
|
61
|
+
* not bare content. (a11y plan 013.)
|
|
62
|
+
*/
|
|
63
|
+
export const REDUCED_TRANSPARENCY_FILL = {
|
|
64
|
+
light: 'rgba(255, 255, 255, 0.75)',
|
|
65
|
+
dark: 'rgba(30, 30, 35, 0.75)',
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Scheme-aware solid fill for the no-`backdrop-filter` tier (3) under reduced
|
|
69
|
+
* transparency: a higher alpha than the default `0.55` solid fallback so the
|
|
70
|
+
* surface is more opaque / less transparent as the setting requests.
|
|
71
|
+
*/
|
|
72
|
+
export const REDUCED_TRANSPARENCY_SOLID_FILL = {
|
|
73
|
+
light: 'rgba(255, 255, 255, 0.92)',
|
|
74
|
+
dark: 'rgba(30, 30, 35, 0.92)',
|
|
75
|
+
};
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Increased-contrast tokens (a11y plan 014)
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
/**
|
|
80
|
+
* Solid border color drawn as an INSET `box-shadow` ring on the surface so the
|
|
81
|
+
* box geometry is unchanged (no layout shift) — a real `border` would grow the
|
|
82
|
+
* box or eat into padding. Scheme-aware near-opaque ink/light for a clearly
|
|
83
|
+
* delineated edge that the soft bevel alone cannot provide.
|
|
84
|
+
*/
|
|
85
|
+
export const CONTRAST_BORDER_COLOR = {
|
|
86
|
+
light: 'rgba(0, 0, 0, 0.92)',
|
|
87
|
+
dark: 'rgba(255, 255, 255, 0.92)',
|
|
88
|
+
};
|
|
89
|
+
/** Inset solid-border ring width (px), prepended to the surface box-shadow. */
|
|
90
|
+
export const CONTRAST_BORDER_WIDTH = 2;
|
|
91
|
+
/**
|
|
92
|
+
* More-opaque scheme-aware surface fill under increased contrast: it reduces
|
|
93
|
+
* the backdrop tint/show-through so foreground content reads at a higher
|
|
94
|
+
* contrast ratio. Layered over any retained blur (tiers 1/2) or used as the
|
|
95
|
+
* solid fill (tier 3). At 0.92 alpha it is at least as opaque as the
|
|
96
|
+
* reduced-transparency fills, so when BOTH a11y axes are active the contrast
|
|
97
|
+
* fill never undercuts reduced-transparency's opacity intent — contrast wants
|
|
98
|
+
* MORE opacity, not less, on every tier.
|
|
99
|
+
*/
|
|
100
|
+
export const CONTRAST_FILL = {
|
|
101
|
+
light: 'rgba(255, 255, 255, 0.92)',
|
|
102
|
+
dark: 'rgba(22, 22, 26, 0.92)',
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Under increased contrast, saturation is pinned to 100% (no decorative
|
|
106
|
+
* vibrancy boost) so the backdrop doesn't push color that competes with
|
|
107
|
+
* foreground text. The default `saturation` (140) is decorative and harms
|
|
108
|
+
* contrast, so it is overridden — never raised.
|
|
109
|
+
*/
|
|
110
|
+
export const CONTRAST_SATURATION = 100;
|
|
111
|
+
/**
|
|
112
|
+
* Content-adaptive foreground ink (plan 018). When `adaptiveTint` is on, the
|
|
113
|
+
* content layer's `color` flips with the verdict so small content (button
|
|
114
|
+
* labels, captions) stays legible: DARK ink over a bright/light backdrop, LIGHT
|
|
115
|
+
* ink over a dark backdrop. `color` is inheritable, so children that don't set
|
|
116
|
+
* their own color pick it up; children with an explicit color keep it. Best-
|
|
117
|
+
* effort legibility — see the `adaptiveTint` TSDoc limitation note.
|
|
118
|
+
*/
|
|
119
|
+
export const CONTENT_INK = {
|
|
120
|
+
light: 'rgba(255, 255, 255, 0.96)',
|
|
121
|
+
dark: 'rgba(17, 17, 20, 0.96)',
|
|
122
|
+
};
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Pointer-tracked specular hotspot + glow-on-press (plan 016)
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Resting specular-hotspot center as a percentage of the surface box. With no
|
|
128
|
+
* pointer over the glass (or under reduced-motion) the highlight falls back to a
|
|
129
|
+
* neutral, top-biased position so the material reads like overhead light on
|
|
130
|
+
* glass rather than a flat sweep. Top-center, slightly above the box.
|
|
131
|
+
*/
|
|
132
|
+
export const SPECULAR_REST_X = '50%';
|
|
133
|
+
export const SPECULAR_REST_Y = '0%';
|
|
134
|
+
/**
|
|
135
|
+
* Peak opacity of the specular hotspot's bright core (the inner stop). Hover
|
|
136
|
+
* brightens it slightly (see `LiquidGlass`); these are the base values.
|
|
137
|
+
*/
|
|
138
|
+
export const SPECULAR_CORE_OPACITY = { rest: 0.55, hover: 0.85 };
|
|
139
|
+
/**
|
|
140
|
+
* Radius of the specular hotspot gradient as a percentage of the surface's
|
|
141
|
+
* larger dimension. Big enough to read as a soft glassy hotspot, small enough
|
|
142
|
+
* that it tracks visibly rather than washing the whole surface.
|
|
143
|
+
*/
|
|
144
|
+
export const SPECULAR_RADIUS = '70%';
|
|
145
|
+
/**
|
|
146
|
+
* Peak opacity of the press-glow bloom's core when active. The glow originates
|
|
147
|
+
* at the contact point and spreads, then fades via the layer's opacity
|
|
148
|
+
* transition (gated on reduced-motion).
|
|
149
|
+
*/
|
|
150
|
+
export const PRESS_GLOW_OPACITY = 0.5;
|
|
151
|
+
/** Radius of the press-glow bloom as a percentage of the surface box. */
|
|
152
|
+
export const PRESS_GLOW_RADIUS = '60%';
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Scroll-aware shadow modulation (plan 021)
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
/**
|
|
157
|
+
* The static drop-shadow (the `static` factor of 1 reproduces today's exact
|
|
158
|
+
* values) is scaled by a single multiplier per backdrop scheme. The shadow
|
|
159
|
+
* DEEPENS/DARKENS over a dark backdrop (factor > 1 → larger offset/blur + darker
|
|
160
|
+
* alpha, lifting the glass above dense scrolling content) and EASES/LIGHTENS over
|
|
161
|
+
* a light/solid one (factor < 1). Factors are deliberately subtle so the polish
|
|
162
|
+
* reads as a gentle depth shift, not a jump.
|
|
163
|
+
*
|
|
164
|
+
* Keys map directly to `BackdropScheme`; `static` is the SSR / first-paint /
|
|
165
|
+
* unsampled fallback and equals the committed baseline shadow exactly.
|
|
166
|
+
*/
|
|
167
|
+
export const SCROLL_SHADOW_DEPTH = {
|
|
168
|
+
/** Conservative fallback: byte-for-byte the existing static shadow. */
|
|
169
|
+
static: 1,
|
|
170
|
+
/** Dark/dense backdrop ⇒ deeper, darker shadow. */
|
|
171
|
+
dark: 1.35,
|
|
172
|
+
/** Light/solid backdrop ⇒ shallower, lighter shadow. */
|
|
173
|
+
light: 0.7,
|
|
174
|
+
};
|
|
175
|
+
/** Base outer drop-shadow layers (offsetY, blur, alpha) at rest and on hover. */
|
|
176
|
+
export const SHADOW_LAYERS = {
|
|
177
|
+
rest: [
|
|
178
|
+
{ y: 8, blur: 24, alpha: 0.22 },
|
|
179
|
+
{ y: 1, blur: 4, alpha: 0.14 },
|
|
180
|
+
],
|
|
181
|
+
hover: [
|
|
182
|
+
{ y: 12, blur: 32, alpha: 0.28 },
|
|
183
|
+
{ y: 2, blur: 8, alpha: 0.18 },
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// Material variant parameters (plan 019)
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
/**
|
|
190
|
+
* Per-variant surface parameters (plan 019). A small parameter LOOKUP — NOT a
|
|
191
|
+
* theming system — that feeds the existing surface/content styles.
|
|
192
|
+
*
|
|
193
|
+
* - `'regular'` is a pure pass-through: `saturationFactor = 1`, no scrim, and
|
|
194
|
+
* `forceNonAdaptive = false`, so the default render is byte-for-byte unchanged
|
|
195
|
+
* and `adaptiveTint` keeps working exactly as in plan 018.
|
|
196
|
+
* - `'clear'` is permanently MORE transparent: the decorative backdrop saturation
|
|
197
|
+
* is pulled back (`saturationFactor < 1` reduces the tint/vibrancy show-through)
|
|
198
|
+
* and `forceNonAdaptive` hard-disables the adaptive sampling path. A subtle
|
|
199
|
+
* dimming scrim is rendered as a CONTENT SIBLING (see the layer stack) so labels
|
|
200
|
+
* stay legible over busy media without re-introducing adaptivity.
|
|
201
|
+
*/
|
|
202
|
+
export const VARIANT_PARAMS = {
|
|
203
|
+
regular: {
|
|
204
|
+
/** Multiplier on the requested `saturation` (1 = unchanged). */
|
|
205
|
+
saturationFactor: 1,
|
|
206
|
+
/** Force the adaptive-tint path off regardless of `adaptiveTint`. */
|
|
207
|
+
forceNonAdaptive: false,
|
|
208
|
+
/** Scheme-aware dimming-scrim color behind the content, or `null` for none. */
|
|
209
|
+
scrim: null,
|
|
210
|
+
},
|
|
211
|
+
clear: {
|
|
212
|
+
// Reduce the tint/vibrancy so the material reads as clearer (more of the
|
|
213
|
+
// backdrop shows through), per the Clear aesthetic.
|
|
214
|
+
saturationFactor: 0.7,
|
|
215
|
+
// Clear has NO adaptive behavior by definition — it never samples.
|
|
216
|
+
forceNonAdaptive: true,
|
|
217
|
+
// A subtle scheme-aware scrim so foreground labels stay readable over busy
|
|
218
|
+
// media even though the surface itself is more transparent.
|
|
219
|
+
scrim: {
|
|
220
|
+
light: 'rgba(0, 0, 0, 0.18)',
|
|
221
|
+
dark: 'rgba(0, 0, 0, 0.28)',
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
// Frosted DEFAULT-look tokens (the contract for plan 023)
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
/**
|
|
229
|
+
* The frosted-glass DEFAULT fill: a faint white tint that gives the surface a
|
|
230
|
+
* subtle milky body even before any blur. ≈ `rgba(255, 255, 255, 0.10)`, the
|
|
231
|
+
* `oklch(1 0 0 / 0.1)` equivalent used by the Video.js liquid-glass reference.
|
|
232
|
+
*
|
|
233
|
+
* Defined HERE as the CONTRACT only — plan 022 does NOT apply it to any surface
|
|
234
|
+
* (that would change the committed pixel baseline). Plan 023 wires it onto the
|
|
235
|
+
* frosted DEFAULT look. Distinct in intent from the a11y
|
|
236
|
+
* {@link REDUCED_TRANSPARENCY_FILL} / {@link CONTRAST_FILL} fills, which exist
|
|
237
|
+
* to force opacity under specific OS settings.
|
|
238
|
+
*/
|
|
239
|
+
export const FROSTED_DEFAULT_FILL = 'rgba(255, 255, 255, 0.1)';
|
|
240
|
+
/**
|
|
241
|
+
* The frosted-glass DEFAULT hairline ring: a crisp ~1px inset edge that defines
|
|
242
|
+
* the frosted surface's perimeter. `color` is a translucent white drawn as an
|
|
243
|
+
* inset ring; `width` is in px.
|
|
244
|
+
*
|
|
245
|
+
* Defined HERE as the CONTRACT only — plan 022 does NOT apply it (no surface
|
|
246
|
+
* change). Plan 023 serializes it onto the frosted DEFAULT surface (e.g. as an
|
|
247
|
+
* inset `box-shadow` ring, geometry-neutral like the existing bevel).
|
|
248
|
+
*/
|
|
249
|
+
export const FROSTED_HAIRLINE_RING = {
|
|
250
|
+
/** Inset ring color (translucent white). */
|
|
251
|
+
color: 'rgba(255, 255, 255, 0.5)',
|
|
252
|
+
/** Ring width in px (hairline). */
|
|
253
|
+
width: 1,
|
|
254
|
+
};
|