@nadicodeai/ui 0.5.3 → 0.6.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.
Files changed (59) hide show
  1. package/AGENTS.md +2 -2
  2. package/dist/components/accordion.js +1 -1
  3. package/dist/components/alert-dialog.js +5 -5
  4. package/dist/components/alert.js +1 -1
  5. package/dist/components/badge.js +4 -4
  6. package/dist/components/button-group.js +4 -4
  7. package/dist/components/button.d.ts.map +1 -1
  8. package/dist/components/button.js +12 -12
  9. package/dist/components/calendar.js +2 -2
  10. package/dist/components/card.js +3 -3
  11. package/dist/components/chart.js +1 -1
  12. package/dist/components/checkbox.js +1 -1
  13. package/dist/components/combobox.js +5 -5
  14. package/dist/components/command.js +4 -4
  15. package/dist/components/context-menu.js +6 -6
  16. package/dist/components/dialog.d.ts +8 -4
  17. package/dist/components/dialog.d.ts.map +1 -1
  18. package/dist/components/dialog.js +6 -6
  19. package/dist/components/drawer.d.ts.map +1 -1
  20. package/dist/components/drawer.js +4 -4
  21. package/dist/components/dropdown-menu.js +7 -7
  22. package/dist/components/empty.js +2 -2
  23. package/dist/components/field.js +3 -3
  24. package/dist/components/hover-card.js +1 -1
  25. package/dist/components/input-group.js +5 -5
  26. package/dist/components/input-otp.d.ts.map +1 -1
  27. package/dist/components/input-otp.js +8 -3
  28. package/dist/components/input.js +1 -1
  29. package/dist/components/item.d.ts.map +1 -1
  30. package/dist/components/item.js +5 -5
  31. package/dist/components/menubar.js +8 -8
  32. package/dist/components/native-select.js +1 -1
  33. package/dist/components/navigation-menu.js +5 -5
  34. package/dist/components/popover.js +1 -1
  35. package/dist/components/radio-group.js +1 -1
  36. package/dist/components/resizable.js +1 -1
  37. package/dist/components/scroll-area.js +1 -1
  38. package/dist/components/select.js +4 -4
  39. package/dist/components/sheet.d.ts +4 -2
  40. package/dist/components/sheet.d.ts.map +1 -1
  41. package/dist/components/sheet.js +5 -5
  42. package/dist/components/sidebar.d.ts +7 -3
  43. package/dist/components/sidebar.d.ts.map +1 -1
  44. package/dist/components/sidebar.js +16 -16
  45. package/dist/components/slider.js +1 -1
  46. package/dist/components/spinner.js +1 -1
  47. package/dist/components/switch.js +1 -1
  48. package/dist/components/tabs.js +2 -2
  49. package/dist/components/textarea.js +1 -1
  50. package/dist/components/theme-mode-switcher.js +1 -1
  51. package/dist/components/toggle-group.js +2 -2
  52. package/dist/components/toggle.js +5 -5
  53. package/dist/components/tooltip.js +1 -1
  54. package/dist/styles/globals.css +25 -3
  55. package/dist/styles/shadcn.tailwind.css +629 -0
  56. package/docs/component-classification.md +3 -3
  57. package/docs/product-compositions.md +2 -2
  58. package/docs/product-sections.md +2 -2
  59. package/package.json +5 -3
@@ -0,0 +1,629 @@
1
+ @theme inline {
2
+ @keyframes accordion-down {
3
+ from {
4
+ height: 0;
5
+ }
6
+ to {
7
+ height: var(
8
+ --radix-accordion-content-height,
9
+ var(--accordion-panel-height, auto)
10
+ );
11
+ }
12
+ }
13
+
14
+ @keyframes accordion-up {
15
+ from {
16
+ height: var(
17
+ --radix-accordion-content-height,
18
+ var(--accordion-panel-height, auto)
19
+ );
20
+ }
21
+ to {
22
+ height: 0;
23
+ }
24
+ }
25
+ }
26
+
27
+ /* Custom variants */
28
+ @custom-variant data-open {
29
+ &:where([data-state="open"]),
30
+ &:where([data-open]:not([data-open="false"])) {
31
+ @slot;
32
+ }
33
+ }
34
+
35
+ @custom-variant data-closed {
36
+ &:where([data-state="closed"]),
37
+ &:where([data-closed]:not([data-closed="false"])) {
38
+ @slot;
39
+ }
40
+ }
41
+
42
+ @custom-variant data-checked {
43
+ &:where([data-state="checked"]),
44
+ &:where([data-checked]:not([data-checked="false"])) {
45
+ @slot;
46
+ }
47
+ }
48
+
49
+ @custom-variant data-unchecked {
50
+ &:where([data-state="unchecked"]),
51
+ &:where([data-unchecked]:not([data-unchecked="false"])) {
52
+ @slot;
53
+ }
54
+ }
55
+
56
+ @custom-variant data-selected {
57
+ &:where([data-selected="true"]) {
58
+ @slot;
59
+ }
60
+ }
61
+
62
+ @custom-variant data-disabled {
63
+ &:where([data-disabled="true"]),
64
+ &:where([data-disabled]:not([data-disabled="false"])) {
65
+ @slot;
66
+ }
67
+ }
68
+
69
+ @custom-variant data-active {
70
+ &:where([data-state="active"]),
71
+ &:where([data-active]:not([data-active="false"])) {
72
+ @slot;
73
+ }
74
+ }
75
+
76
+ @custom-variant data-horizontal {
77
+ &:where([data-orientation="horizontal"]) {
78
+ @slot;
79
+ }
80
+ }
81
+
82
+ @custom-variant data-vertical {
83
+ &:where([data-orientation="vertical"]) {
84
+ @slot;
85
+ }
86
+ }
87
+
88
+ @utility no-scrollbar {
89
+ -ms-overflow-style: none;
90
+ scrollbar-width: none;
91
+
92
+ &::-webkit-scrollbar {
93
+ display: none;
94
+ }
95
+ }
96
+
97
+ /* scroll-fade */
98
+ @property --scroll-fade-t {
99
+ syntax: "<length-percentage>";
100
+ inherits: false;
101
+ initial-value: 0px;
102
+ }
103
+ @property --scroll-fade-b {
104
+ syntax: "<length-percentage>";
105
+ inherits: false;
106
+ initial-value: 0px;
107
+ }
108
+ @property --scroll-fade-s {
109
+ syntax: "<length-percentage>";
110
+ inherits: false;
111
+ initial-value: 0px;
112
+ }
113
+ @property --scroll-fade-e {
114
+ syntax: "<length-percentage>";
115
+ inherits: false;
116
+ initial-value: 0px;
117
+ }
118
+ @property --scroll-fade-mask {
119
+ syntax: "*";
120
+ inherits: false;
121
+ }
122
+
123
+ @theme inline {
124
+ @keyframes scroll-fade-reveal-t {
125
+ from {
126
+ --scroll-fade-t: 0px;
127
+ }
128
+ to {
129
+ --scroll-fade-t: var(--_scroll-fade-size-t, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
130
+ }
131
+ }
132
+ @keyframes scroll-fade-reveal-b {
133
+ from {
134
+ --scroll-fade-b: var(--_scroll-fade-size-b, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
135
+ }
136
+ to {
137
+ --scroll-fade-b: 0px;
138
+ }
139
+ }
140
+ @keyframes scroll-fade-reveal-s {
141
+ from {
142
+ --scroll-fade-s: 0px;
143
+ }
144
+ to {
145
+ --scroll-fade-s: var(--_scroll-fade-size-s, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
146
+ }
147
+ }
148
+ @keyframes scroll-fade-reveal-e {
149
+ from {
150
+ --scroll-fade-e: var(--_scroll-fade-size-e, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
151
+ }
152
+ to {
153
+ --scroll-fade-e: 0px;
154
+ }
155
+ }
156
+ }
157
+
158
+ @utility scroll-fade {
159
+ --_scroll-fade-size-t: var(
160
+ --scroll-fade-t-size,
161
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
162
+ );
163
+ --_scroll-fade-size-b: var(
164
+ --scroll-fade-b-size,
165
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
166
+ );
167
+ --scroll-fade-block: linear-gradient(
168
+ to bottom,
169
+ transparent 0,
170
+ #000 var(--scroll-fade-t, 0px),
171
+ #000 calc(100% - var(--scroll-fade-b, 0px)),
172
+ transparent 100%
173
+ );
174
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
175
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
176
+ -webkit-mask-composite: source-in;
177
+ mask-composite: intersect;
178
+ -webkit-mask-repeat: no-repeat;
179
+ mask-repeat: no-repeat;
180
+
181
+ @supports (animation-timeline: scroll()) {
182
+ animation:
183
+ scroll-fade-reveal-t 1ms ease-in-out,
184
+ scroll-fade-reveal-b 1ms ease-in-out;
185
+ animation-timeline: scroll(self y), scroll(self y);
186
+ animation-range:
187
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
188
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
189
+ animation-fill-mode: both;
190
+ }
191
+
192
+ @supports not (animation-timeline: scroll()) {
193
+ --scroll-fade-t: var(--_scroll-fade-size-t);
194
+ --scroll-fade-b: var(--_scroll-fade-size-b);
195
+ }
196
+ }
197
+
198
+ @utility scroll-fade-y {
199
+ --_scroll-fade-size-t: var(
200
+ --scroll-fade-t-size,
201
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
202
+ );
203
+ --_scroll-fade-size-b: var(
204
+ --scroll-fade-b-size,
205
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
206
+ );
207
+ --scroll-fade-block: linear-gradient(
208
+ to bottom,
209
+ transparent 0,
210
+ #000 var(--scroll-fade-t, 0px),
211
+ #000 calc(100% - var(--scroll-fade-b, 0px)),
212
+ transparent 100%
213
+ );
214
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
215
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
216
+ -webkit-mask-composite: source-in;
217
+ mask-composite: intersect;
218
+ -webkit-mask-repeat: no-repeat;
219
+ mask-repeat: no-repeat;
220
+
221
+ @supports (animation-timeline: scroll()) {
222
+ animation:
223
+ scroll-fade-reveal-t 1ms ease-in-out,
224
+ scroll-fade-reveal-b 1ms ease-in-out;
225
+ animation-timeline: scroll(self y), scroll(self y);
226
+ animation-range:
227
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
228
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
229
+ animation-fill-mode: both;
230
+ }
231
+
232
+ @supports not (animation-timeline: scroll()) {
233
+ --scroll-fade-t: var(--_scroll-fade-size-t);
234
+ --scroll-fade-b: var(--_scroll-fade-size-b);
235
+ }
236
+ }
237
+
238
+ @utility scroll-fade-x {
239
+ --_scroll-fade-size-s: var(
240
+ --scroll-fade-s-size,
241
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
242
+ );
243
+ --_scroll-fade-size-e: var(
244
+ --scroll-fade-e-size,
245
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
246
+ );
247
+ --scroll-fade-inline: linear-gradient(
248
+ to right,
249
+ transparent 0,
250
+ #000 var(--scroll-fade-s, 0px),
251
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
252
+ transparent 100%
253
+ );
254
+ &:where([dir="rtl"], [dir="rtl"] *) {
255
+ --scroll-fade-inline: linear-gradient(
256
+ to left,
257
+ transparent 0,
258
+ #000 var(--scroll-fade-s, 0px),
259
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
260
+ transparent 100%
261
+ );
262
+ }
263
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
264
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
265
+ -webkit-mask-composite: source-in;
266
+ mask-composite: intersect;
267
+ -webkit-mask-repeat: no-repeat;
268
+ mask-repeat: no-repeat;
269
+
270
+ @supports (animation-timeline: scroll()) {
271
+ animation:
272
+ scroll-fade-reveal-s 1ms ease-in-out,
273
+ scroll-fade-reveal-e 1ms ease-in-out;
274
+ animation-timeline: scroll(self inline), scroll(self inline);
275
+ animation-range:
276
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
277
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
278
+ animation-fill-mode: both;
279
+ }
280
+
281
+ @supports not (animation-timeline: scroll()) {
282
+ --scroll-fade-s: var(--_scroll-fade-size-s);
283
+ --scroll-fade-e: var(--_scroll-fade-size-e);
284
+ }
285
+ }
286
+
287
+ @utility scroll-fade-t {
288
+ --_scroll-fade-size-t: var(
289
+ --scroll-fade-t-size,
290
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
291
+ );
292
+ --scroll-fade-mask: linear-gradient(
293
+ to bottom,
294
+ transparent 0,
295
+ #000 var(--scroll-fade-t, 0px),
296
+ #000 100%
297
+ );
298
+ -webkit-mask-image: var(--scroll-fade-mask);
299
+ mask-image: var(--scroll-fade-mask);
300
+ -webkit-mask-composite: source-in;
301
+ mask-composite: intersect;
302
+ -webkit-mask-repeat: no-repeat;
303
+ mask-repeat: no-repeat;
304
+
305
+ @supports (animation-timeline: scroll()) {
306
+ animation: scroll-fade-reveal-t 1ms ease-in-out;
307
+ animation-timeline: scroll(self y);
308
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
309
+ animation-fill-mode: both;
310
+ }
311
+
312
+ @supports not (animation-timeline: scroll()) {
313
+ --scroll-fade-t: var(--_scroll-fade-size-t);
314
+ }
315
+ }
316
+
317
+ @utility scroll-fade-b {
318
+ --_scroll-fade-size-b: var(
319
+ --scroll-fade-b-size,
320
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
321
+ );
322
+ --scroll-fade-mask: linear-gradient(
323
+ to bottom,
324
+ #000 0,
325
+ #000 calc(100% - var(--scroll-fade-b, 0px)),
326
+ transparent 100%
327
+ );
328
+ -webkit-mask-image: var(--scroll-fade-mask);
329
+ mask-image: var(--scroll-fade-mask);
330
+ -webkit-mask-composite: source-in;
331
+ mask-composite: intersect;
332
+ -webkit-mask-repeat: no-repeat;
333
+ mask-repeat: no-repeat;
334
+
335
+ @supports (animation-timeline: scroll()) {
336
+ animation: scroll-fade-reveal-b 1ms ease-in-out;
337
+ animation-timeline: scroll(self y);
338
+ animation-range: calc(
339
+ 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
340
+ )
341
+ 100%;
342
+ animation-fill-mode: both;
343
+ }
344
+
345
+ @supports not (animation-timeline: scroll()) {
346
+ --scroll-fade-b: var(--_scroll-fade-size-b);
347
+ }
348
+ }
349
+
350
+ @utility scroll-fade-l {
351
+ --_scroll-fade-size-s: var(
352
+ --scroll-fade-s-size,
353
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
354
+ );
355
+ --scroll-fade-mask: linear-gradient(
356
+ to right,
357
+ transparent 0,
358
+ #000 var(--scroll-fade-s, 0px),
359
+ #000 100%
360
+ );
361
+ -webkit-mask-image: var(--scroll-fade-mask);
362
+ mask-image: var(--scroll-fade-mask);
363
+ -webkit-mask-composite: source-in;
364
+ mask-composite: intersect;
365
+ -webkit-mask-repeat: no-repeat;
366
+ mask-repeat: no-repeat;
367
+
368
+ @supports (animation-timeline: scroll()) {
369
+ animation: scroll-fade-reveal-s 1ms ease-in-out;
370
+ animation-timeline: scroll(self x);
371
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
372
+ animation-fill-mode: both;
373
+ }
374
+
375
+ @supports not (animation-timeline: scroll()) {
376
+ --scroll-fade-s: var(--_scroll-fade-size-s);
377
+ }
378
+ }
379
+
380
+ @utility scroll-fade-r {
381
+ --_scroll-fade-size-e: var(
382
+ --scroll-fade-e-size,
383
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
384
+ );
385
+ --scroll-fade-mask: linear-gradient(
386
+ to right,
387
+ #000 0,
388
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
389
+ transparent 100%
390
+ );
391
+ -webkit-mask-image: var(--scroll-fade-mask);
392
+ mask-image: var(--scroll-fade-mask);
393
+ -webkit-mask-composite: source-in;
394
+ mask-composite: intersect;
395
+ -webkit-mask-repeat: no-repeat;
396
+ mask-repeat: no-repeat;
397
+
398
+ @supports (animation-timeline: scroll()) {
399
+ animation: scroll-fade-reveal-e 1ms ease-in-out;
400
+ animation-timeline: scroll(self x);
401
+ animation-range: calc(
402
+ 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
403
+ )
404
+ 100%;
405
+ animation-fill-mode: both;
406
+ }
407
+
408
+ @supports not (animation-timeline: scroll()) {
409
+ --scroll-fade-e: var(--_scroll-fade-size-e);
410
+ }
411
+ }
412
+
413
+ @utility scroll-fade-s {
414
+ --_scroll-fade-size-s: var(
415
+ --scroll-fade-s-size,
416
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
417
+ );
418
+ --scroll-fade-mask: linear-gradient(
419
+ to right,
420
+ transparent 0,
421
+ #000 var(--scroll-fade-s, 0px),
422
+ #000 100%
423
+ );
424
+ &:where([dir="rtl"], [dir="rtl"] *) {
425
+ --scroll-fade-mask: linear-gradient(
426
+ to left,
427
+ transparent 0,
428
+ #000 var(--scroll-fade-s, 0px),
429
+ #000 100%
430
+ );
431
+ }
432
+ -webkit-mask-image: var(--scroll-fade-mask);
433
+ mask-image: var(--scroll-fade-mask);
434
+ -webkit-mask-composite: source-in;
435
+ mask-composite: intersect;
436
+ -webkit-mask-repeat: no-repeat;
437
+ mask-repeat: no-repeat;
438
+
439
+ @supports (animation-timeline: scroll()) {
440
+ animation: scroll-fade-reveal-s 1ms ease-in-out;
441
+ animation-timeline: scroll(self inline);
442
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
443
+ animation-fill-mode: both;
444
+ }
445
+
446
+ @supports not (animation-timeline: scroll()) {
447
+ --scroll-fade-s: var(--_scroll-fade-size-s);
448
+ }
449
+ }
450
+
451
+ @utility scroll-fade-e {
452
+ --_scroll-fade-size-e: var(
453
+ --scroll-fade-e-size,
454
+ var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10)))
455
+ );
456
+ --scroll-fade-mask: linear-gradient(
457
+ to right,
458
+ #000 0,
459
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
460
+ transparent 100%
461
+ );
462
+ &:where([dir="rtl"], [dir="rtl"] *) {
463
+ --scroll-fade-mask: linear-gradient(
464
+ to left,
465
+ #000 0,
466
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
467
+ transparent 100%
468
+ );
469
+ }
470
+ -webkit-mask-image: var(--scroll-fade-mask);
471
+ mask-image: var(--scroll-fade-mask);
472
+ -webkit-mask-composite: source-in;
473
+ mask-composite: intersect;
474
+ -webkit-mask-repeat: no-repeat;
475
+ mask-repeat: no-repeat;
476
+
477
+ @supports (animation-timeline: scroll()) {
478
+ animation: scroll-fade-reveal-e 1ms ease-in-out;
479
+ animation-timeline: scroll(self inline);
480
+ animation-range: calc(
481
+ 100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))
482
+ )
483
+ 100%;
484
+ animation-fill-mode: both;
485
+ }
486
+
487
+ @supports not (animation-timeline: scroll()) {
488
+ --scroll-fade-e: var(--_scroll-fade-size-e);
489
+ }
490
+ }
491
+
492
+ @utility scroll-fade-* {
493
+ --scroll-fade-size: calc(var(--spacing) * --value(integer));
494
+ --scroll-fade-size: --value([length], [percentage]);
495
+ }
496
+
497
+ @utility scroll-fade-t-* {
498
+ --scroll-fade-t-size: calc(var(--spacing) * --value(integer));
499
+ --scroll-fade-t-size: --value([length], [percentage]);
500
+ }
501
+
502
+ @utility scroll-fade-b-* {
503
+ --scroll-fade-b-size: calc(var(--spacing) * --value(integer));
504
+ --scroll-fade-b-size: --value([length], [percentage]);
505
+ }
506
+
507
+ @utility scroll-fade-s-* {
508
+ --scroll-fade-s-size: calc(var(--spacing) * --value(integer));
509
+ --scroll-fade-s-size: --value([length], [percentage]);
510
+ }
511
+
512
+ @utility scroll-fade-e-* {
513
+ --scroll-fade-e-size: calc(var(--spacing) * --value(integer));
514
+ --scroll-fade-e-size: --value([length], [percentage]);
515
+ }
516
+
517
+ @utility scroll-fade-none {
518
+ --scroll-fade-mask: none;
519
+ }
520
+
521
+ /* shimmer */
522
+ @property --shimmer-angle {
523
+ syntax: "<angle>";
524
+ inherits: true;
525
+ initial-value: 20deg;
526
+ }
527
+ @property --shimmer-image {
528
+ syntax: "*";
529
+ inherits: false;
530
+ }
531
+ @property --shimmer-text-fill {
532
+ syntax: "*";
533
+ inherits: false;
534
+ }
535
+
536
+ @theme inline {
537
+ @keyframes tw-shimmer {
538
+ from {
539
+ background-position: 100% 0;
540
+ }
541
+ to {
542
+ background-position: 0 0;
543
+ }
544
+ }
545
+ }
546
+
547
+ @utility shimmer {
548
+ --_spread: var(--shimmer-spread, calc(3ch + 40px));
549
+ --_base: currentColor;
550
+ --_highlight: var(
551
+ --shimmer-color,
552
+ oklch(from currentColor l c h / calc(alpha* 0.2))
553
+ );
554
+
555
+ background-image: var(
556
+ --shimmer-image,
557
+ linear-gradient(
558
+ calc(90deg + var(--shimmer-angle)),
559
+ var(--_base) calc(50% - var(--_spread)),
560
+ color-mix(in oklch, var(--_highlight), var(--_base) 50%)
561
+ calc(50% - var(--_spread) * 0.5),
562
+ var(--_highlight) 50%,
563
+ color-mix(in oklch, var(--_highlight), var(--_base) 50%)
564
+ calc(50% + var(--_spread) * 0.5),
565
+ var(--_base) calc(50% + var(--_spread))
566
+ )
567
+ );
568
+ background-repeat: no-repeat;
569
+ background-size: calc(200% + var(--_spread) * 2) 100%;
570
+ background-position: 0 0;
571
+ background-clip: text;
572
+ -webkit-background-clip: text;
573
+ -webkit-text-fill-color: var(--shimmer-text-fill, transparent);
574
+ animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
575
+
576
+ @variant dark {
577
+ --_highlight: var(
578
+ --shimmer-color,
579
+ oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4))
580
+ );
581
+ }
582
+
583
+ &:where([dir="rtl"], [dir="rtl"] *) {
584
+ animation-direction: reverse;
585
+ }
586
+ }
587
+
588
+ @utility shimmer-once {
589
+ animation-iteration-count: 1;
590
+ }
591
+
592
+ @utility shimmer-reverse {
593
+ animation-direction: reverse;
594
+ }
595
+
596
+ @utility shimmer-none {
597
+ --shimmer-image: none;
598
+ --shimmer-text-fill: currentColor;
599
+ }
600
+
601
+ @utility shimmer-color-* {
602
+ --shimmer-color: --value(--color, [color]);
603
+ --shimmer-color: color-mix(
604
+ in oklch,
605
+ --value(--color, [color]) calc(--modifier(integer) * 1%),
606
+ transparent
607
+ );
608
+ }
609
+
610
+ @utility shimmer-duration-* {
611
+ --shimmer-duration: calc(--value(integer) * 1ms);
612
+ }
613
+
614
+ @utility shimmer-spread-* {
615
+ --shimmer-spread: calc(var(--spacing) * --value(integer));
616
+ --shimmer-spread: --value([length], [percentage]);
617
+ }
618
+
619
+ @utility shimmer-angle-* {
620
+ --shimmer-angle: calc(--value(integer) * 1deg);
621
+ }
622
+
623
+ @media (prefers-reduced-motion: reduce) {
624
+ .shimmer {
625
+ animation: none;
626
+ background-image: none;
627
+ -webkit-text-fill-color: currentColor;
628
+ }
629
+ }
@@ -19,9 +19,9 @@ copy, and behavior.
19
19
 
20
20
  | Component | Classification | Built on | Required states | Package-owned accessibility | Fixture |
21
21
  | --- | --- | --- | --- | --- | --- |
22
- | `SettingsSection` | Net-new NadicodeAI product composition. | shadcn `FieldGroup` plus standard section markup. | header with optional actions; field group content. | section structure; no form behavior. | `../tests/product-compositions.test.ts` |
23
- | `SettingsField` | Net-new NadicodeAI product composition. | shadcn `Field`, `FieldLabel`, `FieldDescription`, and `FieldError`. | valid and invalid field rows; disabled rows. | `data-invalid`, `aria-invalid`, `aria-describedby`, label `htmlFor`. | `../tests/product-compositions.test.ts` |
24
- | `FeedbackState` | Net-new central product state composition adapted from shadcn empty-state patterns. | shadcn `Empty` and lucide status icons. | `empty`, `loading`, `saving`, `error`, `permission`, `offline`, `no-results`, `fatal`. | `role="status"` for loading/saving; `role="alert"` for error, permission, offline, and fatal. | `../tests/product-compositions.test.ts` |
22
+ | `SettingsSection` | Net-new NadicodeAI product composition. | shadcn `FieldGroup` plus standard section markup. | header with optional actions; field group content. | section structure; no form behavior. | `../tests/guards/product-compositions.test.ts` |
23
+ | `SettingsField` | Net-new NadicodeAI product composition. | shadcn `Field`, `FieldLabel`, `FieldDescription`, and `FieldError`. | valid and invalid field rows; disabled rows. | `data-invalid`, `aria-invalid`, `aria-describedby`, label `htmlFor`. | `../tests/guards/product-compositions.test.ts` |
24
+ | `FeedbackState` | Net-new central product state composition adapted from shadcn empty-state patterns. | shadcn `Empty` and lucide status icons. | `empty`, `loading`, `saving`, `error`, `permission`, `offline`, `no-results`, `fatal`. | `role="status"` for loading/saving; `role="alert"` for error, permission, offline, and fatal. | `../tests/guards/product-compositions.test.ts` |
25
25
 
26
26
  ## App-Owned Boundaries
27
27
 
@@ -17,8 +17,8 @@ import { SettingsSection } from "@nadicodeai/ui/components/settings-section"
17
17
 
18
18
  Fixtures live in:
19
19
 
20
- - [`../tests/product-compositions.test.ts`](../tests/product-compositions.test.ts)
21
- - [`../tests/product-compositions-ssr.test.ts`](../tests/product-compositions-ssr.test.ts)
20
+ - [`../tests/guards/product-compositions.test.ts`](../tests/guards/product-compositions.test.ts)
21
+ - [`../tests/guards/product-compositions-ssr.test.ts`](../tests/guards/product-compositions-ssr.test.ts)
22
22
 
23
23
  ## Boundaries
24
24
 
@@ -11,8 +11,8 @@ import { PluginSlotBoundary } from "@nadicodeai/ui/components/plugin-slot-bounda
11
11
 
12
12
  Fixtures live in:
13
13
 
14
- - [`../tests/product-sections.test.ts`](../tests/product-sections.test.ts)
15
- - [`../tests/product-sections-ssr.test.ts`](../tests/product-sections-ssr.test.ts)
14
+ - [`../tests/guards/product-sections.test.ts`](../tests/guards/product-sections.test.ts)
15
+ - [`../tests/guards/product-sections-ssr.test.ts`](../tests/guards/product-sections-ssr.test.ts)
16
16
 
17
17
  ## Boundaries
18
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  "scripts": {
44
44
  "dev": "node scripts/dev-build.mjs --watch",
45
- "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/fix-dist-imports.mjs && rm -rf dist/styles && cp -R src/styles dist/styles",
45
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/fix-dist-imports.mjs && node scripts/build-styles.mjs",
46
46
  "build:fast": "node scripts/dev-build.mjs",
47
47
  "prepack": "npm run build",
48
48
  "lint": "eslint --max-warnings=0",
@@ -51,7 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@base-ui/react": "^1.6.0",
54
- "@nadicodeai/design-system": "0.5.3",
54
+ "@nadicodeai/design-system": "0.6.0",
55
55
  "@rive-app/react-webgl2": "^4.29.1",
56
56
  "@streamdown/cjk": "^1.0.3",
57
57
  "@streamdown/code": "^1.1.1",
@@ -80,6 +80,7 @@
80
80
  "streamdown": "^2.5.0",
81
81
  "tailwind-merge": "^3.0.0",
82
82
  "tokenlens": "^1.3.1",
83
+ "tw-animate-css": "^1.4.0",
83
84
  "use-stick-to-bottom": "^1.1.6"
84
85
  },
85
86
  "peerDependencies": {
@@ -95,6 +96,7 @@
95
96
  "eslint": "^9.39.4",
96
97
  "react": "19.2.7",
97
98
  "react-dom": "19.2.7",
99
+ "shadcn": "4.13.0",
98
100
  "tailwindcss": "^4.3.1",
99
101
  "typescript": "^5",
100
102
  "typescript-eslint": "^8.46.0",