@wallarm-org/design-system 2.3.0 → 2.3.2-rc-fix-filter-popover-handoff.1

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.
@@ -13,9 +13,8 @@ export interface AppShellProps extends HTMLAttributes<HTMLDivElement>, TestableP
13
13
  onRevealed?: () => void;
14
14
  appeared?: boolean;
15
15
  /**
16
- * The Frame's ambient layer — drifting blooms, grain and a dot cluster behind the header and
17
- * rail. On by default; `false` leaves the flat Frame token fill. Still under
18
- * `prefers-reduced-motion: reduce`.
16
+ * The Frame's ambient layer — soft blooms, grain and a dot cluster behind the header and
17
+ * rail. On by default; `false` leaves the flat Frame token fill.
19
18
  */
20
19
  ambient?: boolean;
21
20
  }
@@ -2,7 +2,7 @@ import type { FC } from 'react';
2
2
  /**
3
3
  * The Frame's ambient layer. The Frame is the shell's gray zone — the header
4
4
  * bar plus the rail, everything around the canvas — and Ambient is the life in
5
- * it: slow-drifting blooms, grain and a dot cluster pooled bottom-left of the
5
+ * it: soft blooms, grain and a dot cluster pooled bottom-left of the
6
6
  * rail. Purely decorative, painted under every region (see
7
7
  * `theme/components/app-shell.css`). Internal to `AppShell`; toggled with its
8
8
  * `ambient` prop.
@@ -12,6 +12,7 @@ const AppShellAmbient = ()=>{
12
12
  let t5;
13
13
  let t6;
14
14
  let t7;
15
+ let t8;
15
16
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
16
17
  t0 = /*#__PURE__*/ jsx("div", {
17
18
  className: "app-shell-ambient-bloom app-shell-ambient-bloom-1"
@@ -37,6 +38,9 @@ const AppShellAmbient = ()=>{
37
38
  t7 = /*#__PURE__*/ jsx("div", {
38
39
  className: "app-shell-ambient-grain"
39
40
  });
41
+ t8 = /*#__PURE__*/ jsx("div", {
42
+ className: "app-shell-ambient-dots"
43
+ });
40
44
  $[0] = t0;
41
45
  $[1] = t1;
42
46
  $[2] = t2;
@@ -45,6 +49,7 @@ const AppShellAmbient = ()=>{
45
49
  $[5] = t5;
46
50
  $[6] = t6;
47
51
  $[7] = t7;
52
+ $[8] = t8;
48
53
  } else {
49
54
  t0 = $[0];
50
55
  t1 = $[1];
@@ -54,23 +59,8 @@ const AppShellAmbient = ()=>{
54
59
  t5 = $[5];
55
60
  t6 = $[6];
56
61
  t7 = $[7];
62
+ t8 = $[8];
57
63
  }
58
- let t8;
59
- if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
60
- t8 = /*#__PURE__*/ jsx("div", {
61
- className: "app-shell-ambient-dots",
62
- children: /*#__PURE__*/ jsx("div", {
63
- className: "app-shell-ambient-dots-noise-a",
64
- children: /*#__PURE__*/ jsx("div", {
65
- className: "app-shell-ambient-dots-noise-b",
66
- children: /*#__PURE__*/ jsx("div", {
67
- className: "app-shell-ambient-dots-grid"
68
- })
69
- })
70
- })
71
- });
72
- $[8] = t8;
73
- } else t8 = $[8];
74
64
  let t9;
75
65
  if ($[9] !== testId) {
76
66
  t9 = /*#__PURE__*/ jsxs("div", {
@@ -94,6 +94,7 @@ const FieldMenuPopover = (t0)=>{
94
94
  minWidth: "240px",
95
95
  maxWidth: "340px",
96
96
  className: "gap-6 pointer-events-none",
97
+ "data-filter-input-menu": "true",
97
98
  "data-testid": "field-menu-popover",
98
99
  children: [
99
100
  t4,
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "2.2.0",
3
- "generatedAt": "2026-10-08T10:17:05.571Z",
2
+ "version": "2.3.1",
3
+ "generatedAt": "2026-10-09T13:43:37.468Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
@@ -4236,7 +4236,7 @@
4236
4236
  "name": "ambient",
4237
4237
  "type": "boolean | undefined",
4238
4238
  "required": false,
4239
- "description": "The Frame's ambient layer — drifting blooms, grain and a dot cluster behind the header and\nrail. On by default; `false` leaves the flat Frame token fill. Still under\n`prefers-reduced-motion: reduce`.",
4239
+ "description": "The Frame's ambient layer — soft blooms, grain and a dot cluster behind the header and\nrail. On by default; `false` leaves the flat Frame token fill.",
4240
4240
  "defaultValue": "true"
4241
4241
  },
4242
4242
  {
@@ -8,28 +8,19 @@
8
8
  * Three stacked layers, all decorative, all under the regions:
9
9
  * 1. blooms — seven large soft gray spots: four in the rail (two lifts, two
10
10
  * shades) and three flat ellipses crossing
11
- * the top edge so the header carries the same light. They wander
12
- * on 60–90 s loops, stretching as they move. This is the "mesh
13
- * gradient" of the 21st.dev builder, in the shell's own tones.
11
+ * the top edge so the header carries the same light. This is a
12
+ * still frame of the "mesh gradient" of the 21st.dev builder, in
13
+ * the shell's own tones.
14
14
  * 2. grain — desaturated fractal noise tiled as a background image, so it
15
15
  * rasterises once.
16
16
  * 3. dots — a 12px halftone raster (the auth-page scanner's grid) pooled
17
17
  * in the bottom-left of the rail, fading upward to nothing;
18
- * patches of it surface and dissolve under two drifting noise
19
- * masks, so the grid is never fully there.
18
+ * two noise masks break it into patches, so the grid is never
19
+ * fully there.
20
20
  *
21
- * Performance (ENG-911). Everything that moves animates `transform` /
22
- * `opacity` only, so the compositor shifts already-rasterised layers and
23
- * nothing is repainted. The dots used to animate `mask-position`, which Chrome
24
- * repaints on the main thread every frame (about a third of the old idle CPU);
25
- * the masks now ride on their own layers instead. Softness is baked into the
26
- * gradient stops rather than `filter: blur()`: a blur on a moving layer is
27
- * re-run by the GPU every frame, a gradient is rasterised once.
28
- *
29
- * Motion is opt-in: it runs only under `prefers-reduced-motion:
30
- * no-preference`, set on each `bloom-N` itself (a shared rule would lose to
31
- * the equally specific, later `bloom-N`). Otherwise the ambient is the
32
- * still first frame.
21
+ * Nothing here animates (ENG-911): endless 60–150 s drift loops kept a CPU
22
+ * core busy on every idle tab just to repaint a background nobody watches.
23
+ * Softness is baked into the gradient stops rather than `filter: blur()`.
33
24
  *
34
25
  * The canvas (`AppShellRemote`) sits on top, so none of this shows under page
35
26
  * content. Colours are theme tokens in semantic.css (light and dark), derived
@@ -70,7 +61,7 @@
70
61
  }
71
62
 
72
63
  /* One soft spot. Each `app-shell-ambient-bloom-N` only sets its colour (`--c`), shape,
73
- size, position and drift path; the falloff below approximates a Gaussian so no
64
+ size and position; the falloff below approximates a Gaussian so no
74
65
  `filter: blur()` is needed. */
75
66
  @utility app-shell-ambient-bloom {
76
67
  --c: transparent;
@@ -93,10 +84,6 @@
93
84
  height: 760px;
94
85
  left: -280px;
95
86
  bottom: -240px;
96
-
97
- @media (prefers-reduced-motion: no-preference) {
98
- animation: app-shell-ambient-drift-1 60s ease-in-out infinite;
99
- }
100
87
  }
101
88
 
102
89
  @utility app-shell-ambient-bloom-2 {
@@ -105,10 +92,6 @@
105
92
  height: 680px;
106
93
  left: -140px;
107
94
  top: 8%;
108
-
109
- @media (prefers-reduced-motion: no-preference) {
110
- animation: app-shell-ambient-drift-2 74s ease-in-out infinite;
111
- }
112
95
  }
113
96
 
114
97
  @utility app-shell-ambient-bloom-3 {
@@ -117,10 +100,6 @@
117
100
  height: 540px;
118
101
  left: -170px;
119
102
  top: 46%;
120
-
121
- @media (prefers-reduced-motion: no-preference) {
122
- animation: app-shell-ambient-drift-3 66s ease-in-out infinite;
123
- }
124
103
  }
125
104
 
126
105
  @utility app-shell-ambient-bloom-4 {
@@ -129,10 +108,6 @@
129
108
  height: 620px;
130
109
  left: 30px;
131
110
  bottom: -190px;
132
-
133
- @media (prefers-reduced-motion: no-preference) {
134
- animation: app-shell-ambient-drift-4 82s ease-in-out infinite;
135
- }
136
111
  }
137
112
 
138
113
  /* Header strip: three wide, flat ellipses crossing the top edge so the bar
@@ -146,10 +121,6 @@
146
121
  height: 540px;
147
122
  left: 22%;
148
123
  top: -360px;
149
-
150
- @media (prefers-reduced-motion: no-preference) {
151
- animation: app-shell-ambient-drift-5 90s ease-in-out infinite;
152
- }
153
124
  }
154
125
 
155
126
  @utility app-shell-ambient-bloom-6 {
@@ -159,10 +130,6 @@
159
130
  height: 580px;
160
131
  right: -300px;
161
132
  top: -390px;
162
-
163
- @media (prefers-reduced-motion: no-preference) {
164
- animation: app-shell-ambient-drift-6 78s ease-in-out infinite;
165
- }
166
133
  }
167
134
 
168
135
  @utility app-shell-ambient-bloom-7 {
@@ -172,141 +139,6 @@
172
139
  height: 500px;
173
140
  left: 20px;
174
141
  top: -350px;
175
-
176
- @media (prefers-reduced-motion: no-preference) {
177
- animation: app-shell-ambient-drift-7 70s ease-in-out infinite;
178
- }
179
- }
180
-
181
- /* Drift paths. Each spot wanders through four waypoints instead of a straight
182
- back-and-forth, stretching along the direction it moves (a liquid smearing
183
- on a surface) and breathing a little in opacity. Transform + opacity only,
184
- so the rasterised gradient is never repainted, just composited. */
185
- @keyframes app-shell-ambient-drift-1 {
186
- 0% {
187
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
188
- opacity: 1;
189
- }
190
- 33% {
191
- transform: translate(70px, -90px) rotate(6deg) scale(1.16, 0.92);
192
- opacity: 0.9;
193
- }
194
- 66% {
195
- transform: translate(30px, -160px) rotate(-4deg) scale(0.94, 1.14);
196
- opacity: 1;
197
- }
198
- 100% {
199
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
200
- opacity: 1;
201
- }
202
- }
203
- @keyframes app-shell-ambient-drift-2 {
204
- 0% {
205
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
206
- opacity: 0.95;
207
- }
208
- 33% {
209
- transform: translate(-50px, 110px) rotate(-8deg) scale(0.9, 1.18);
210
- opacity: 1;
211
- }
212
- 66% {
213
- transform: translate(40px, 170px) rotate(5deg) scale(1.2, 0.9);
214
- opacity: 0.88;
215
- }
216
- 100% {
217
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
218
- opacity: 0.95;
219
- }
220
- }
221
- @keyframes app-shell-ambient-drift-3 {
222
- 0% {
223
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
224
- opacity: 1;
225
- }
226
- 33% {
227
- transform: translate(60px, -120px) rotate(10deg) scale(1.22, 0.88);
228
- opacity: 0.85;
229
- }
230
- 66% {
231
- transform: translate(-30px, -200px) rotate(-6deg) scale(0.92, 1.16);
232
- opacity: 1;
233
- }
234
- 100% {
235
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
236
- opacity: 1;
237
- }
238
- }
239
- @keyframes app-shell-ambient-drift-4 {
240
- 0% {
241
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
242
- opacity: 0.9;
243
- }
244
- 33% {
245
- transform: translate(-80px, -60px) rotate(-7deg) scale(1.18, 0.9);
246
- opacity: 1;
247
- }
248
- 66% {
249
- transform: translate(-40px, -140px) rotate(4deg) scale(0.9, 1.2);
250
- opacity: 0.86;
251
- }
252
- 100% {
253
- transform: translate(0, 0) rotate(0deg) scale(1, 1);
254
- opacity: 0.9;
255
- }
256
- }
257
- @keyframes app-shell-ambient-drift-5 {
258
- 0% {
259
- transform: translate(0, 0) scale(1, 1);
260
- opacity: 1;
261
- }
262
- 33% {
263
- transform: translate(160px, 40px) scale(1.14, 0.94);
264
- opacity: 0.85;
265
- }
266
- 66% {
267
- transform: translate(260px, 10px) scale(0.96, 1.1);
268
- opacity: 1;
269
- }
270
- 100% {
271
- transform: translate(0, 0) scale(1, 1);
272
- opacity: 1;
273
- }
274
- }
275
- @keyframes app-shell-ambient-drift-6 {
276
- 0% {
277
- transform: translate(0, 0) scale(1, 1);
278
- opacity: 0.95;
279
- }
280
- 33% {
281
- transform: translate(-200px, 30px) scale(1.12, 0.92);
282
- opacity: 1;
283
- }
284
- 66% {
285
- transform: translate(-320px, 60px) scale(0.94, 1.12);
286
- opacity: 0.85;
287
- }
288
- 100% {
289
- transform: translate(0, 0) scale(1, 1);
290
- opacity: 0.95;
291
- }
292
- }
293
- @keyframes app-shell-ambient-drift-7 {
294
- 0% {
295
- transform: translate(0, 0) scale(1, 1);
296
- opacity: 1;
297
- }
298
- 33% {
299
- transform: translate(120px, 50px) scale(1.16, 0.9);
300
- opacity: 0.88;
301
- }
302
- 66% {
303
- transform: translate(200px, 20px) scale(0.92, 1.12);
304
- opacity: 1;
305
- }
306
- 100% {
307
- transform: translate(0, 0) scale(1, 1);
308
- opacity: 1;
309
- }
310
142
  }
311
143
 
312
144
  @utility app-shell-ambient-grain {
@@ -319,82 +151,33 @@
319
151
  }
320
152
 
321
153
  /* Dot cluster. Confined to the bottom-left of the Frame (the only place it is
322
- ever visible). Three masks intersect: the vertical fade here, and two tiles
323
- of low-frequency noise on the nested `dots-noise-*` layers. Dots show only
324
- where both noise tiles are open, so patches surface and dissolve in place
325
- over a couple of minutes instead of sliding across.
326
-
327
- The noise tiles move by `transform`, not `mask-position`, so the compositor
328
- slides them and nothing repaints. Each layer carries its mask with it, and
329
- the grid counter-moves by the sum of the two, so the dots themselves stay
330
- put. The noise layers overhang the box by 1200px (a multiple of both the
331
- 400px tile and the 12px grid) so their edges never show mid-loop. */
154
+ ever visible). Three masks intersect: the vertical fade, and two tiles of
155
+ low-frequency noise. Dots show only where both noise tiles are open, so the
156
+ grid reads as scattered patches. */
332
157
  @utility app-shell-ambient-dots {
333
158
  position: absolute;
334
159
  left: 0;
335
160
  bottom: 0;
336
161
  width: min(100%, 480px);
337
162
  height: min(560px, 64vh);
338
- overflow: hidden;
339
- mask-image: linear-gradient(
340
- to top,
341
- #000 0,
342
- rgb(0 0 0 / 0.75) 22%,
343
- rgb(0 0 0 / 0.4) 48%,
344
- rgb(0 0 0 / 0.12) 74%,
345
- transparent 94%
346
- );
347
- }
348
-
349
- @utility app-shell-ambient-dots-noise-a {
350
- position: absolute;
351
- inset: -1200px;
352
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 0 -6.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
353
- mask-size: 400px 400px;
354
-
355
- @media (prefers-reduced-motion: no-preference) {
356
- animation: app-shell-ambient-dots-noise-a 150s linear infinite;
357
- }
358
- }
359
-
360
- @utility app-shell-ambient-dots-noise-b {
361
- position: absolute;
362
- inset: 0;
363
- mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 0 -6.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
364
- mask-size: 400px 400px;
365
-
366
- @media (prefers-reduced-motion: no-preference) {
367
- animation: app-shell-ambient-dots-noise-b 150s linear infinite;
368
- }
369
- }
370
-
371
- @utility app-shell-ambient-dots-grid {
372
- position: absolute;
373
- inset: 0;
374
163
  background-image: radial-gradient(circle at center, var(--color-component-app-shell-ambient-dot) 0.9px, transparent 1.1px);
375
164
  background-size: 12px 12px;
376
165
  background-position: 6px 6px;
377
-
378
- @media (prefers-reduced-motion: no-preference) {
379
- animation: app-shell-ambient-dots-grid 150s linear infinite;
380
- }
381
- }
382
-
383
- /* Whole-tile offsets (multiples of 400px) so the loop is seamless. Noise A
384
- travels (400, -400), noise B (-800, 400) in total — so (-1200, 800) relative
385
- to A, which it sits inside — and the grid undoes B's total. */
386
- @keyframes app-shell-ambient-dots-noise-a {
387
- to {
388
- transform: translate(400px, -400px);
389
- }
390
- }
391
- @keyframes app-shell-ambient-dots-noise-b {
392
- to {
393
- transform: translate(-1200px, 800px);
394
- }
395
- }
396
- @keyframes app-shell-ambient-dots-grid {
397
- to {
398
- transform: translate(800px, -400px);
399
- }
166
+ mask-image:
167
+ linear-gradient(
168
+ to top,
169
+ #000 0,
170
+ rgb(0 0 0 / 0.75) 22%,
171
+ rgb(0 0 0 / 0.4) 48%,
172
+ rgb(0 0 0 / 0.12) 74%,
173
+ transparent 94%
174
+ ),
175
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 0 -6.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
176
+ url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='400'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.014' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 0 -6.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
177
+ mask-size:
178
+ 100% 100%,
179
+ 400px 400px,
180
+ 400px 400px;
181
+ mask-repeat: no-repeat, repeat, repeat;
182
+ mask-composite: intersect;
400
183
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "2.3.0",
3
+ "version": "2.3.2-rc-fix-filter-popover-handoff.1",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",