mtrl 0.5.2 → 0.5.4

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 (80) hide show
  1. package/dist/components/checkbox/api.d.ts +1 -1
  2. package/dist/components/checkbox/types.d.ts +17 -6
  3. package/dist/components/chips/api.d.ts +5 -2
  4. package/dist/components/chips/chip/api.d.ts +1 -1
  5. package/dist/components/chips/config.d.ts +5 -1
  6. package/dist/components/chips/types.d.ts +14 -3
  7. package/dist/components/index.d.ts +1 -0
  8. package/dist/components/select/types.d.ts +21 -3
  9. package/dist/components/switch/types.d.ts +8 -4
  10. package/dist/index.cjs +14 -14
  11. package/dist/index.cjs.map +13 -13
  12. package/dist/index.js +14 -14
  13. package/dist/index.js.map +13 -13
  14. package/dist/package.json +1 -1
  15. package/dist/styles.css +2 -2
  16. package/package.json +4 -2
  17. package/src/styles/abstract/_base.scss +2 -0
  18. package/src/styles/abstract/_config.scss +28 -0
  19. package/src/styles/abstract/_functions.scss +124 -0
  20. package/src/styles/abstract/_mixins.scss +401 -0
  21. package/src/styles/abstract/_theme.scss +269 -0
  22. package/src/styles/abstract/_variables.scss +338 -0
  23. package/src/styles/base/_reset.scss +86 -0
  24. package/src/styles/base/_typography.scss +155 -0
  25. package/src/styles/components/_badge.scss +183 -0
  26. package/src/styles/components/_bottom-app-bar.scss +103 -0
  27. package/src/styles/components/_button.scss +756 -0
  28. package/src/styles/components/_card.scss +401 -0
  29. package/src/styles/components/_carousel.scss +645 -0
  30. package/src/styles/components/_checkbox.scss +231 -0
  31. package/src/styles/components/_chips.scss +643 -0
  32. package/src/styles/components/_datepicker.scss +358 -0
  33. package/src/styles/components/_dialog.scss +259 -0
  34. package/src/styles/components/_divider.scss +57 -0
  35. package/src/styles/components/_extended-fab.scss +309 -0
  36. package/src/styles/components/_fab.scss +244 -0
  37. package/src/styles/components/_list.scss +774 -0
  38. package/src/styles/components/_menu.scss +245 -0
  39. package/src/styles/components/_navigation-mobile.scss +244 -0
  40. package/src/styles/components/_navigation-system.scss +151 -0
  41. package/src/styles/components/_navigation.scss +407 -0
  42. package/src/styles/components/_progress.scss +101 -0
  43. package/src/styles/components/_radios.scss +187 -0
  44. package/src/styles/components/_search.scss +306 -0
  45. package/src/styles/components/_segmented-button.scss +227 -0
  46. package/src/styles/components/_select.scss +274 -0
  47. package/src/styles/components/_sheet.scss +236 -0
  48. package/src/styles/components/_slider.scss +264 -0
  49. package/src/styles/components/_snackbar.scss +211 -0
  50. package/src/styles/components/_switch.scss +305 -0
  51. package/src/styles/components/_tabs.scss +421 -0
  52. package/src/styles/components/_textfield.scss +1035 -0
  53. package/src/styles/components/_timepicker.scss +451 -0
  54. package/src/styles/components/_tooltip.scss +241 -0
  55. package/src/styles/components/_top-app-bar.scss +225 -0
  56. package/src/styles/main.scss +129 -0
  57. package/src/styles/themes/_autumn.scss +105 -0
  58. package/src/styles/themes/_base-theme.scss +85 -0
  59. package/src/styles/themes/_baseline.scss +173 -0
  60. package/src/styles/themes/_bluekhaki.scss +125 -0
  61. package/src/styles/themes/_brownbeige.scss +125 -0
  62. package/src/styles/themes/_browngreen.scss +125 -0
  63. package/src/styles/themes/_forest.scss +77 -0
  64. package/src/styles/themes/_greenbeige.scss +125 -0
  65. package/src/styles/themes/_index.scss +19 -0
  66. package/src/styles/themes/_material.scss +125 -0
  67. package/src/styles/themes/_ocean.scss +77 -0
  68. package/src/styles/themes/_sageivory.scss +125 -0
  69. package/src/styles/themes/_spring.scss +77 -0
  70. package/src/styles/themes/_summer.scss +87 -0
  71. package/src/styles/themes/_sunset.scss +60 -0
  72. package/src/styles/themes/_tealcaramel.scss +125 -0
  73. package/src/styles/themes/_winter.scss +77 -0
  74. package/src/styles/utilities/_colors.scss +154 -0
  75. package/src/styles/utilities/_flexbox.scss +194 -0
  76. package/src/styles/utilities/_layout.scss +665 -0
  77. package/src/styles/utilities/_ripple.scss +79 -0
  78. package/src/styles/utilities/_spacing.scss +139 -0
  79. package/src/styles/utilities/_typography.scss +178 -0
  80. package/src/styles/utilities/_visibility.scss +142 -0
@@ -0,0 +1,774 @@
1
+ // src/components/list/_list.scss
2
+ @use "../../styles/abstract/base" as base;
3
+ @use "../../styles/abstract/variables" as v;
4
+ @use "../../styles/abstract/functions" as f;
5
+ @use "../../styles/abstract/mixins" as m;
6
+ @use "../../styles/abstract/theme" as t;
7
+
8
+ // Component variables
9
+ $component: "#{base.$prefix}-list";
10
+ $list-item-height: 48px !default;
11
+ $list-item-dense-height: 40px !default;
12
+ $list-padding: 8px !default;
13
+ $list-item-padding: 16px !default;
14
+ $list-section-padding: 16px !default;
15
+ $list-container-min-height: 200px !default;
16
+
17
+ // Transition variables
18
+ $state-transition-duration: v.motion("duration-medium1") !default;
19
+ $state-transition-easing: v.motion("easing-standard") !default;
20
+ $quick-transition: v.motion("duration-short4")
21
+ v.motion("easing-standard-accelerate");
22
+
23
+ // Reusable transitions
24
+ $color-transition: color $state-transition-duration $state-transition-easing;
25
+ $bg-transition: background-color $state-transition-duration
26
+ $state-transition-easing;
27
+ $opacity-transition: opacity $state-transition-duration $state-transition-easing;
28
+
29
+ // Placeholder styling variables
30
+ $placeholder-opacity: 0.6 !default;
31
+ $placeholder-opacity-skeleton: 0.8 !default;
32
+ $placeholder-opacity-masked: 0.7 !default;
33
+ $placeholder-opacity-subtle: 0.4 !default;
34
+ $placeholder-background-alpha: 0.4 !default;
35
+ $placeholder-shimmer-alpha: 0.2 !default;
36
+ $placeholder-animation-speed: 1.5s !default;
37
+
38
+ // Component-specific mixins
39
+ @mixin list-item-state-layer($state: "hover", $color: "on-surface") {
40
+ &::before {
41
+ content: "";
42
+ position: absolute;
43
+ inset: 0;
44
+ background-color: t.color($color);
45
+ opacity: f.get-state-opacity($state);
46
+ pointer-events: none;
47
+ border-radius: inherit;
48
+ transition: $opacity-transition;
49
+ }
50
+ }
51
+
52
+ @mixin list-section-title {
53
+ @include m.typography("label-large");
54
+ color: t.color("primary");
55
+ padding: $list-section-padding $list-item-padding 8px;
56
+ }
57
+
58
+ // LIST CONTAINER
59
+ .#{$component}-container {
60
+ position: relative;
61
+ overflow-y: auto;
62
+ overflow-x: hidden;
63
+ height: 100%;
64
+ min-height: $list-container-min-height;
65
+ background-color: t.color("surface");
66
+ -webkit-overflow-scrolling: touch;
67
+ scrollbar-width: thin;
68
+ transition: $bg-transition;
69
+
70
+ // Performance optimizations
71
+ contain: layout style paint;
72
+ content-visibility: auto;
73
+ transform: translateZ(0);
74
+ backface-visibility: hidden;
75
+ will-change: scroll-position;
76
+
77
+ // Scrollbar styling
78
+ &::-webkit-scrollbar {
79
+ width: 8px;
80
+
81
+ &-track {
82
+ background: transparent;
83
+ }
84
+
85
+ &-thumb {
86
+ background-color: t.color("outline-variant");
87
+ border-radius: 4px;
88
+ transition: $bg-transition;
89
+
90
+ &:hover {
91
+ background-color: t.alpha("outline", 0.38);
92
+ }
93
+ }
94
+ }
95
+
96
+ // Loading state
97
+ &--loading::after {
98
+ content: "";
99
+ position: absolute;
100
+ top: 0;
101
+ left: 0;
102
+ right: 0;
103
+ height: 3px;
104
+ background: linear-gradient(
105
+ to right,
106
+ transparent,
107
+ t.color("primary"),
108
+ transparent
109
+ );
110
+ animation: loading-shimmer 1.5s infinite v.motion("easing-standard");
111
+ }
112
+ }
113
+
114
+ // LIST COMPONENT
115
+ .#{$component} {
116
+ display: flex;
117
+ flex-direction: column;
118
+ padding: $list-padding 0;
119
+ width: 100%;
120
+ position: relative;
121
+ transition: padding $state-transition-duration $state-transition-easing,
122
+ $opacity-transition;
123
+
124
+ // Inner containers
125
+ &-content {
126
+ position: relative;
127
+ width: 100%;
128
+ }
129
+
130
+ // Sections
131
+ &-section {
132
+ display: flex;
133
+ flex-direction: column;
134
+ width: 100%;
135
+ transition: margin-bottom $state-transition-duration
136
+ $state-transition-easing;
137
+
138
+ &:not(:last-child) {
139
+ margin-bottom: $list-padding;
140
+ }
141
+ }
142
+
143
+ &-section-title {
144
+ @include list-section-title;
145
+ transition: $color-transition;
146
+ }
147
+
148
+ // Dividers
149
+ &-divider {
150
+ height: 1px;
151
+ margin: $list-padding 0;
152
+ background-color: t.color("outline-variant");
153
+ transition: $bg-transition;
154
+ }
155
+
156
+ // Virtual list helper elements
157
+ &-spacer {
158
+ position: absolute;
159
+ top: 0;
160
+ left: 0;
161
+ width: 1px;
162
+ visibility: hidden;
163
+ pointer-events: none;
164
+
165
+ // Performance optimizations for spacer
166
+ contain: strict;
167
+ will-change: height;
168
+ transform: translateZ(0);
169
+ overflow: hidden;
170
+ }
171
+
172
+ // Sentinel elements for intersection observer
173
+ &-sentinel {
174
+ position: absolute;
175
+ width: 1px;
176
+ height: 1px;
177
+ opacity: 0;
178
+ pointer-events: none;
179
+ contain: layout;
180
+
181
+ &--top {
182
+ top: 0;
183
+ }
184
+
185
+ &--bottom {
186
+ bottom: 0;
187
+ }
188
+ }
189
+
190
+ // Empty state
191
+ &-empty {
192
+ display: flex;
193
+ flex-direction: column;
194
+ align-items: center;
195
+ justify-content: center;
196
+ padding: 32px 16px;
197
+ text-align: center;
198
+ color: t.color("on-surface-variant");
199
+ transition: $color-transition, $opacity-transition;
200
+
201
+ &-icon {
202
+ font-size: 48px;
203
+ margin-bottom: 16px;
204
+ opacity: 0.6;
205
+ transition: $opacity-transition;
206
+ }
207
+
208
+ &-text {
209
+ @include m.typography("body-large");
210
+ transition: $color-transition;
211
+ }
212
+
213
+ &-action {
214
+ margin-top: 16px;
215
+ transition: $opacity-transition;
216
+ }
217
+ }
218
+
219
+ // Loading indicator
220
+ &-loading-indicator {
221
+ display: flex;
222
+ align-items: center;
223
+ justify-content: center;
224
+ height: 48px;
225
+ width: 100%;
226
+ color: t.color("on-surface-variant");
227
+ transition: $color-transition;
228
+
229
+ &::after {
230
+ content: "";
231
+ width: 24px;
232
+ height: 24px;
233
+ border: 2px solid currentColor;
234
+ border-bottom-color: transparent;
235
+ border-radius: 50%;
236
+ animation: rotation 0.8s infinite linear;
237
+ }
238
+ }
239
+
240
+ // Dense variant
241
+ &--dense .#{$component}-item {
242
+ min-height: $list-item-dense-height;
243
+ }
244
+
245
+ // Disabled state
246
+ &--disabled {
247
+ pointer-events: none;
248
+ opacity: 0.38;
249
+ transition: $opacity-transition;
250
+ }
251
+
252
+ // High contrast mode
253
+ @include m.high-contrast {
254
+ border: 1px solid currentColor;
255
+
256
+ &-divider {
257
+ border-top: 1px solid currentColor;
258
+ background: none;
259
+ }
260
+ }
261
+
262
+ // LIST ITEMS
263
+ &-item {
264
+ display: flex;
265
+ align-items: center;
266
+ min-height: $list-item-height;
267
+ padding: $list-padding $list-item-padding;
268
+
269
+ // Performance-optimized positioning
270
+ left: 0;
271
+ right: 0;
272
+ width: 100%;
273
+
274
+ // APZ-friendly positioning using CSS custom properties
275
+ // This prevents Firefox scroll-linked effects warnings
276
+ --item-offset: 0px;
277
+ transform: translateY(var(--item-offset)) translateZ(0);
278
+ will-change: transform;
279
+ contain: layout style;
280
+
281
+ gap: 16px;
282
+ color: t.color("on-surface");
283
+ cursor: pointer;
284
+ box-sizing: border-box;
285
+ overflow: hidden;
286
+ transition: $bg-transition, $color-transition, opacity 0.2s ease-in-out;
287
+
288
+ // State layer base
289
+ &::before {
290
+ content: "";
291
+ position: absolute;
292
+ inset: 0;
293
+ background-color: t.color("on-surface");
294
+ opacity: 0;
295
+ pointer-events: none;
296
+ border-radius: inherit;
297
+ transition: $opacity-transition;
298
+ }
299
+
300
+ // State interactions
301
+ &:hover::before {
302
+ opacity: f.get-state-opacity("hover");
303
+ }
304
+
305
+ &:focus-visible {
306
+ outline: none;
307
+
308
+ &::before {
309
+ opacity: f.get-state-opacity("focus");
310
+ }
311
+
312
+ &::after {
313
+ content: "";
314
+ position: absolute;
315
+ inset: 0;
316
+ border-radius: inherit;
317
+ box-shadow: inset 0 0 0 2px t.color("primary");
318
+ pointer-events: none;
319
+ transition: box-shadow $state-transition-duration
320
+ $state-transition-easing;
321
+ }
322
+ }
323
+
324
+ &:active::before {
325
+ opacity: f.get-state-opacity("pressed");
326
+ transition: opacity $quick-transition;
327
+ }
328
+
329
+ // Content elements
330
+ &-content {
331
+ flex: 1;
332
+ min-width: 0;
333
+ display: flex;
334
+ flex-direction: column;
335
+ justify-content: center;
336
+ transition: $opacity-transition;
337
+ }
338
+
339
+ &-text {
340
+ display: flex;
341
+ flex-direction: column;
342
+ gap: 4px;
343
+ }
344
+
345
+ // Text elements with shared properties
346
+ &-overline,
347
+ &-supporting,
348
+ &-meta {
349
+ color: t.color("on-surface-variant");
350
+ transition: $color-transition;
351
+ }
352
+
353
+ &-overline {
354
+ @include m.typography("label-small");
355
+ }
356
+
357
+ &-headline {
358
+ @include m.typography("body-large");
359
+ color: t.color("on-surface");
360
+ white-space: nowrap;
361
+ overflow: hidden;
362
+ text-overflow: ellipsis;
363
+ transition: $color-transition;
364
+ }
365
+
366
+ &-supporting {
367
+ @include m.typography("body-medium");
368
+ white-space: nowrap;
369
+ overflow: hidden;
370
+ text-overflow: ellipsis;
371
+ }
372
+
373
+ &-meta {
374
+ @include m.typography("label-small");
375
+ margin-top: 4px;
376
+ }
377
+
378
+ // Leading/trailing elements
379
+ &-leading,
380
+ &-trailing {
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: center;
384
+ flex-shrink: 0;
385
+ color: t.color("on-surface-variant");
386
+ transition: $color-transition, $opacity-transition;
387
+ }
388
+
389
+ &-leading {
390
+ width: 24px;
391
+ height: 24px;
392
+
393
+ svg {
394
+ width: 100%;
395
+ height: 100%;
396
+ transition: fill $state-transition-duration $state-transition-easing,
397
+ stroke $state-transition-duration $state-transition-easing;
398
+ }
399
+ }
400
+
401
+ // Vertical layout variant
402
+ &.vertical {
403
+ min-height: 72px;
404
+ padding: 12px $list-item-padding;
405
+
406
+ .#{$component}-item {
407
+ &-content {
408
+ flex-direction: column;
409
+ gap: 4px;
410
+ }
411
+ &-meta {
412
+ margin-top: $list-padding;
413
+ }
414
+ }
415
+ }
416
+
417
+ // Selected state
418
+ &--selected {
419
+ background-color: t.color("secondary-container");
420
+ color: t.color("on-secondary-container");
421
+ transition: $bg-transition, $color-transition;
422
+
423
+ // Update state layer color for selected state
424
+ &::before {
425
+ background-color: t.color("on-secondary-container");
426
+ }
427
+
428
+ // Update text and icon colors for selected state
429
+ .#{$component}-item {
430
+ &-leading,
431
+ &-trailing,
432
+ &-supporting,
433
+ &-overline,
434
+ &-meta {
435
+ color: t.color("on-secondary-container");
436
+ transition: $color-transition;
437
+ }
438
+ }
439
+ }
440
+
441
+ // Disabled state
442
+ &--disabled {
443
+ opacity: 0.38;
444
+ pointer-events: none;
445
+ transition: $opacity-transition;
446
+ }
447
+
448
+ // Placeholder loading state
449
+ &.#{base.$prefix}-item-placeholder {
450
+ opacity: $placeholder-opacity;
451
+ pointer-events: none;
452
+ position: relative;
453
+ height: 84px;
454
+ transition: opacity 0.3s ease-in-out,
455
+ background-color $state-transition-duration $state-transition-easing;
456
+
457
+ // Performance optimizations for placeholders
458
+ contain: strict;
459
+ will-change: contents;
460
+
461
+ // Background tint for visibility
462
+ background-color: t.alpha(
463
+ "surface-variant",
464
+ $placeholder-background-alpha
465
+ );
466
+
467
+ // Enhanced shimmer effect for loading indication
468
+ // &::before {
469
+ // content: "";
470
+ // position: absolute;
471
+ // top: 0;
472
+ // left: -100%;
473
+ // width: 100%;
474
+ // height: 100%;
475
+ // background: linear-gradient(
476
+ // 90deg,
477
+ // transparent,
478
+ // rgba(255, 255, 255, 0.1),
479
+ // transparent
480
+ // );
481
+ // animation: shimmer 1.5s infinite;
482
+ // will-change: transform;
483
+
484
+ // @media (prefers-reduced-motion: reduce) {
485
+ // animation: none;
486
+ // }
487
+ // }
488
+
489
+ // Loading shimmer effect
490
+ // &::after {
491
+ // content: "";
492
+ // position: absolute;
493
+ // top: 0;
494
+ // left: 0;
495
+ // right: 0;
496
+ // height: 3px;
497
+ // background: linear-gradient(
498
+ // 90deg,
499
+ // transparent,
500
+ // t.alpha("primary", $placeholder-shimmer-alpha),
501
+ // transparent
502
+ // );
503
+ // animation: placeholder-shimmer $placeholder-animation-speed infinite
504
+ // v.motion("easing-standard");
505
+ // transform-origin: left center;
506
+ // }
507
+
508
+ // Accessibility indicator
509
+ &[aria-busy="true"] {
510
+ .#{$component}-item-content {
511
+ opacity: 0.9;
512
+ transition: opacity 0.3s ease-in-out;
513
+ }
514
+ }
515
+
516
+ // Text styling for placeholder visibility
517
+ .#{$component}-item-headline,
518
+ .#{$component}-item-supporting,
519
+ .#{$component}-item-meta {
520
+ transition: color 0.3s ease-in-out, opacity 0.3s ease-in-out;
521
+ opacity: 1;
522
+ }
523
+
524
+ // Placeholder mode variants
525
+ &--skeleton {
526
+ opacity: $placeholder-opacity-skeleton;
527
+
528
+ .#{$component}-item-headline,
529
+ .#{$component}-item-supporting {
530
+ background-color: t.color("surface-variant");
531
+ border-radius: 4px;
532
+ color: transparent;
533
+ animation: skeleton-pulse 1.5s infinite;
534
+ }
535
+ }
536
+
537
+ &--masked {
538
+ opacity: $placeholder-opacity-masked;
539
+ }
540
+
541
+ &--subtle {
542
+ opacity: $placeholder-opacity-subtle;
543
+
544
+ &::after {
545
+ display: none; // No shimmer for subtle mode
546
+ }
547
+ }
548
+
549
+ // // Reduce motion support
550
+ // @media (prefers-reduced-motion: reduce) {
551
+ // &::after {
552
+ // animation: none;
553
+ // background: t.alpha("primary", calc($placeholder-shimmer-alpha / 2));
554
+ // }
555
+
556
+ // &--skeleton {
557
+ // .#{$component}-item-headline,
558
+ // .#{$component}-item-supporting {
559
+ // animation: none;
560
+ // }
561
+ // }
562
+ // }
563
+
564
+ // High contrast mode
565
+ @include m.high-contrast {
566
+ outline: 2px dashed currentColor;
567
+ outline-offset: -2px;
568
+
569
+ &::after {
570
+ background: currentColor;
571
+ opacity: 0.5;
572
+ }
573
+ }
574
+ }
575
+
576
+ // Recycled element optimizations
577
+ &.#{base.$prefix}-item-recycled {
578
+ will-change: contents;
579
+ }
580
+ }
581
+ }
582
+
583
+ // Selection specific styling (single/multi/radio)
584
+ .#{$component}[data-type="single"],
585
+ .#{$component}[data-type="multi"],
586
+ .#{$component}[data-type="radio"] {
587
+ .#{$component}-item {
588
+ cursor: pointer;
589
+ }
590
+ }
591
+
592
+ @mixin rtl {
593
+ // Replace this problematic line:
594
+ // [dir='rtl'] & {
595
+ // @content;
596
+ // }
597
+
598
+ // With this correct approach:
599
+ [dir="rtl"] {
600
+ @content;
601
+ }
602
+ }
603
+
604
+ // High contrast mode for selected items
605
+ @include m.high-contrast {
606
+ .#{$component}-item--selected {
607
+ outline: 2px solid currentColor;
608
+ outline-offset: -2px;
609
+ }
610
+ }
611
+
612
+ // ANIMATIONS
613
+ @keyframes loading-shimmer {
614
+ 0% {
615
+ transform: translateX(-100%);
616
+ }
617
+ 50% {
618
+ transform: translateX(100%);
619
+ }
620
+ 100% {
621
+ transform: translateX(100%);
622
+ }
623
+ }
624
+
625
+ @keyframes rotation {
626
+ from {
627
+ transform: rotate(0deg);
628
+ }
629
+ to {
630
+ transform: rotate(360deg);
631
+ }
632
+ }
633
+
634
+ @keyframes placeholder-shimmer {
635
+ 0% {
636
+ transform: translateX(-100%);
637
+ opacity: 0;
638
+ }
639
+ 50% {
640
+ transform: translateX(0%);
641
+ opacity: 1;
642
+ }
643
+ 100% {
644
+ transform: translateX(100%);
645
+ opacity: 0;
646
+ }
647
+ }
648
+
649
+ @keyframes skeleton-pulse {
650
+ 0% {
651
+ opacity: 1;
652
+ }
653
+ 50% {
654
+ opacity: 0.4;
655
+ }
656
+ 100% {
657
+ opacity: 1;
658
+ }
659
+ }
660
+
661
+ @keyframes shimmer {
662
+ 0% {
663
+ transform: translateX(-100%);
664
+ }
665
+ 100% {
666
+ transform: translateX(200%);
667
+ }
668
+ }
669
+
670
+ // PERFORMANCE UTILITIES
671
+ .#{$component}-container {
672
+ // Performance mode for slower devices
673
+ &--performance-mode {
674
+ .#{$component}-item {
675
+ will-change: auto;
676
+ transform: none;
677
+ contain: none; // Reduce containment on slower devices
678
+
679
+ &.#{base.$prefix}-item-placeholder::before {
680
+ animation: none;
681
+ }
682
+ }
683
+ }
684
+
685
+ // Debug mode for development
686
+ &--debug {
687
+ .#{$component}-item {
688
+ outline: 1px solid rgba(255, 0, 0, 0.3);
689
+
690
+ &.#{base.$prefix}-item-placeholder {
691
+ outline-color: rgba(0, 255, 0, 0.3);
692
+ }
693
+
694
+ &.#{base.$prefix}-item-recycled {
695
+ outline-color: rgba(0, 0, 255, 0.3);
696
+ }
697
+ }
698
+ }
699
+
700
+ // High-performance scroll optimization
701
+ &.#{$component}-performance-scroll {
702
+ scroll-behavior: auto;
703
+ will-change: scroll-position;
704
+
705
+ &::-webkit-scrollbar {
706
+ width: 8px;
707
+ }
708
+
709
+ &::-webkit-scrollbar-track {
710
+ background: transparent;
711
+ }
712
+
713
+ &::-webkit-scrollbar-thumb {
714
+ background-color: t.alpha("outline", 0.2);
715
+ border-radius: 4px;
716
+
717
+ &:hover {
718
+ background-color: t.alpha("outline", 0.3);
719
+ }
720
+ }
721
+ }
722
+ }
723
+
724
+ // Dark mode optimizations
725
+ @media (prefers-color-scheme: dark) {
726
+ .#{$component}-item.#{base.$prefix}-item-placeholder::before {
727
+ background: linear-gradient(
728
+ 90deg,
729
+ transparent,
730
+ rgba(255, 255, 255, 0.05),
731
+ transparent
732
+ );
733
+ }
734
+ }
735
+
736
+ // Responsive performance optimizations
737
+ @media (max-width: 768px) {
738
+ .#{$component}-container {
739
+ .#{$component}-item {
740
+ // Optimize for touch on mobile
741
+ touch-action: pan-y;
742
+ will-change: transform;
743
+ }
744
+ }
745
+ }
746
+
747
+ @media (max-width: 480px) {
748
+ .#{$component}-container {
749
+ .#{$component}-item.#{base.$prefix}-item-placeholder::before {
750
+ animation-duration: 2s; // Slower animation on small screens
751
+ }
752
+ }
753
+ }
754
+
755
+ // High-density display optimizations
756
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
757
+ .#{$component}-item {
758
+ text-rendering: optimizeLegibility;
759
+ -webkit-font-smoothing: antialiased;
760
+ -moz-osx-font-smoothing: grayscale;
761
+ }
762
+ }
763
+
764
+ // Print optimizations
765
+ @media print {
766
+ .#{$component}-container {
767
+ .#{$component}-item {
768
+ will-change: auto !important;
769
+ transform: none !important;
770
+ animation: none !important;
771
+ transition: none !important;
772
+ }
773
+ }
774
+ }