mtrl 0.3.6 → 0.3.8

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 (45) hide show
  1. package/package.json +2 -2
  2. package/src/components/button/api.ts +16 -0
  3. package/src/components/button/types.ts +9 -0
  4. package/src/components/menu/api.ts +61 -22
  5. package/src/components/menu/config.ts +10 -8
  6. package/src/components/menu/features/anchor.ts +254 -19
  7. package/src/components/menu/features/controller.ts +724 -271
  8. package/src/components/menu/features/index.ts +11 -2
  9. package/src/components/menu/features/position.ts +353 -0
  10. package/src/components/menu/index.ts +5 -5
  11. package/src/components/menu/menu.ts +21 -61
  12. package/src/components/menu/types.ts +30 -16
  13. package/src/components/select/api.ts +78 -0
  14. package/src/components/select/config.ts +76 -0
  15. package/src/components/select/features.ts +331 -0
  16. package/src/components/select/index.ts +38 -0
  17. package/src/components/select/select.ts +73 -0
  18. package/src/components/select/types.ts +355 -0
  19. package/src/components/textfield/api.ts +78 -6
  20. package/src/components/textfield/features/index.ts +17 -0
  21. package/src/components/textfield/features/leading-icon.ts +127 -0
  22. package/src/components/textfield/features/placement.ts +149 -0
  23. package/src/components/textfield/features/prefix-text.ts +107 -0
  24. package/src/components/textfield/features/suffix-text.ts +100 -0
  25. package/src/components/textfield/features/supporting-text.ts +113 -0
  26. package/src/components/textfield/features/trailing-icon.ts +108 -0
  27. package/src/components/textfield/textfield.ts +51 -15
  28. package/src/components/textfield/types.ts +70 -0
  29. package/src/core/collection/adapters/base.ts +62 -0
  30. package/src/core/collection/collection.ts +300 -0
  31. package/src/core/collection/index.ts +57 -0
  32. package/src/core/collection/list-manager.ts +333 -0
  33. package/src/index.ts +4 -45
  34. package/src/styles/abstract/_variables.scss +18 -0
  35. package/src/styles/components/_button.scss +21 -5
  36. package/src/styles/components/{_chip.scss → _chips.scss} +118 -4
  37. package/src/styles/components/_menu.scss +97 -24
  38. package/src/styles/components/_select.scss +272 -0
  39. package/src/styles/components/_textfield.scss +233 -42
  40. package/src/styles/main.scss +2 -1
  41. package/src/components/textfield/features.ts +0 -322
  42. package/src/core/collection/adapters/base.js +0 -26
  43. package/src/core/collection/collection.js +0 -259
  44. package/src/core/collection/list-manager.js +0 -157
  45. /package/src/core/collection/adapters/{route.js → route.ts} +0 -0
@@ -1,4 +1,4 @@
1
- // src/components/textfield/_styles.scss
1
+ // src/styles/components/_textfield.scss
2
2
  @use '../../styles/abstract/base' as base;
3
3
  @use '../../styles/abstract/variables' as v;
4
4
  @use '../../styles/abstract/functions' as f;
@@ -70,6 +70,40 @@ $component: '#{base.$prefix}-textfield';
70
70
  }
71
71
  }
72
72
 
73
+ // Prefix text
74
+ &-prefix {
75
+ @include m.typography('body-large');
76
+ position: absolute;
77
+ left: 12px;
78
+ top: 50%;
79
+ transform: translateY(-50%);
80
+ color: t.color('on-surface');
81
+ pointer-events: none;
82
+ z-index: 2; // Increased to ensure it stays above input
83
+ white-space: nowrap; // Prevent text wrapping
84
+ max-width: 40%; // Prevent extreme overflow
85
+ overflow: hidden;
86
+ text-overflow: ellipsis;
87
+ transition: top v.motion('duration-short4') v.motion('easing-emphasized'); // Add transition for top position
88
+ }
89
+
90
+ // Suffix text
91
+ &-suffix {
92
+ @include m.typography('body-large');
93
+ position: absolute;
94
+ right: 16px;
95
+ top: 50%;
96
+ transform: translateY(-50%);
97
+ color: t.color('on-surface');
98
+ pointer-events: none;
99
+ z-index: 2; // Increased to ensure it stays above input
100
+ white-space: nowrap; // Prevent text wrapping
101
+ max-width: 40%; // Prevent extreme overflow
102
+ overflow: hidden;
103
+ text-overflow: ellipsis;
104
+ transition: top v.motion('duration-short4') v.motion('easing-emphasized'); // Add transition for top position
105
+ }
106
+
73
107
  // Leading icon
74
108
  &-leading-icon {
75
109
  position: absolute;
@@ -84,6 +118,7 @@ $component: '#{base.$prefix}-textfield';
84
118
  pointer-events: none;
85
119
  color: t.color('on-surface-variant');
86
120
  z-index: 1;
121
+ transition: top v.motion('duration-short4') v.motion('easing-emphasized'); // Add transition for top position
87
122
 
88
123
  svg {
89
124
  width: 20px;
@@ -105,6 +140,7 @@ $component: '#{base.$prefix}-textfield';
105
140
  color: t.color('on-surface-variant');
106
141
  z-index: 1;
107
142
  cursor: pointer;
143
+ transition: top v.motion('duration-short4') v.motion('easing-emphasized'); // Add transition for top position
108
144
 
109
145
  svg {
110
146
  width: 20px;
@@ -112,6 +148,27 @@ $component: '#{base.$prefix}-textfield';
112
148
  }
113
149
  }
114
150
 
151
+ // Adjustments when prefix/suffix are present - base case styling
152
+ // JavaScript will handle dynamic sizing, these are fallbacks
153
+ &--with-prefix {
154
+ .#{$component}-label {
155
+ // Default value - will be overridden by JS for precise positioning
156
+ left: 48px;
157
+ }
158
+
159
+ .#{$component}-input {
160
+ // Default value - will be overridden by JS for precise padding
161
+ padding-left: 48px;
162
+ }
163
+ }
164
+
165
+ &--with-suffix {
166
+ .#{$component}-input {
167
+ // Default value - will be overridden by JS for precise padding
168
+ padding-right: 48px;
169
+ }
170
+ }
171
+
115
172
  // Adjustments when icons are present
116
173
  &--with-leading-icon {
117
174
  .#{$component}-label {
@@ -121,12 +178,41 @@ $component: '#{base.$prefix}-textfield';
121
178
  .#{$component}-input {
122
179
  padding-left: 44px;
123
180
  }
181
+
182
+ // If there's also a prefix, adjust positions
183
+ &.#{$component}--with-prefix {
184
+ .#{$component}-prefix {
185
+ left: 44px;
186
+ }
187
+
188
+ .#{$component}-label {
189
+ // Default value - will be overridden by JS for precise positioning
190
+ left: 76px;
191
+ }
192
+
193
+ .#{$component}-input {
194
+ // Default value - will be overridden by JS for precise padding
195
+ padding-left: 76px;
196
+ }
197
+ }
124
198
  }
125
199
 
126
200
  &--with-trailing-icon {
127
201
  .#{$component}-input {
128
202
  padding-right: 44px;
129
203
  }
204
+
205
+ // If there's also a suffix, adjust positions
206
+ &.#{$component}--with-suffix {
207
+ .#{$component}-suffix {
208
+ right: 44px;
209
+ }
210
+
211
+ .#{$component}-input {
212
+ // Default value - will be overridden by JS for precise padding
213
+ padding-right: 76px;
214
+ }
215
+ }
130
216
  }
131
217
 
132
218
  // Error state
@@ -138,7 +224,9 @@ $component: '#{base.$prefix}-textfield';
138
224
  }
139
225
 
140
226
  .#{$component}-leading-icon,
141
- .#{$component}-trailing-icon {
227
+ .#{$component}-trailing-icon,
228
+ .#{$component}-prefix,
229
+ .#{$component}-suffix {
142
230
  color: t.color('error');
143
231
  }
144
232
  }
@@ -152,7 +240,9 @@ $component: '#{base.$prefix}-textfield';
152
240
 
153
241
  & ~ .#{$component}-label,
154
242
  & ~ .#{$component}-leading-icon,
155
- & ~ .#{$component}-trailing-icon {
243
+ & ~ .#{$component}-trailing-icon,
244
+ & ~ .#{$component}-prefix,
245
+ & ~ .#{$component}-suffix {
156
246
  color: t.color('on-surface');
157
247
  opacity: 0.38;
158
248
  }
@@ -183,6 +273,13 @@ $component: '#{base.$prefix}-textfield';
183
273
  &-label {
184
274
  transition: none;
185
275
  }
276
+
277
+ &-prefix,
278
+ &-suffix,
279
+ &-leading-icon,
280
+ &-trailing-icon {
281
+ transition: none;
282
+ }
186
283
  }
187
284
 
188
285
  // RTL support
@@ -198,6 +295,16 @@ $component: '#{base.$prefix}-textfield';
198
295
  margin-right: 4px;
199
296
  }
200
297
 
298
+ &-prefix {
299
+ left: auto;
300
+ right: 16px;
301
+ }
302
+
303
+ &-suffix {
304
+ right: auto;
305
+ left: 16px;
306
+ }
307
+
201
308
  &-leading-icon {
202
309
  left: auto;
203
310
  right: 12px;
@@ -208,6 +315,28 @@ $component: '#{base.$prefix}-textfield';
208
315
  left: 12px;
209
316
  }
210
317
 
318
+ &--with-prefix {
319
+ .#{$component}-label {
320
+ left: auto;
321
+ // Default value - will be overridden by JS for precise positioning
322
+ right: 48px;
323
+ }
324
+
325
+ .#{$component}-input {
326
+ padding-left: 16px;
327
+ // Default value - will be overridden by JS for precise padding
328
+ padding-right: 48px;
329
+ }
330
+ }
331
+
332
+ &--with-suffix {
333
+ .#{$component}-input {
334
+ padding-right: 16px;
335
+ // Default value - will be overridden by JS for precise padding
336
+ padding-left: 48px;
337
+ }
338
+ }
339
+
211
340
  &--with-leading-icon {
212
341
  .#{$component}-label {
213
342
  left: auto;
@@ -218,6 +347,25 @@ $component: '#{base.$prefix}-textfield';
218
347
  padding-left: 16px;
219
348
  padding-right: 44px;
220
349
  }
350
+
351
+ &.#{$component}--with-prefix {
352
+ .#{$component}-prefix {
353
+ left: auto;
354
+ right: 44px;
355
+ }
356
+
357
+ .#{$component}-label {
358
+ left: auto;
359
+ // Default value - will be overridden by JS for precise positioning
360
+ right: 76px;
361
+ }
362
+
363
+ .#{$component}-input {
364
+ padding-left: 16px;
365
+ // Default value - will be overridden by JS for precise padding
366
+ padding-right: 76px;
367
+ }
368
+ }
221
369
  }
222
370
 
223
371
  &--with-trailing-icon {
@@ -225,6 +373,19 @@ $component: '#{base.$prefix}-textfield';
225
373
  padding-right: 16px;
226
374
  padding-left: 44px;
227
375
  }
376
+
377
+ &.#{$component}--with-suffix {
378
+ .#{$component}-suffix {
379
+ right: auto;
380
+ left: 44px;
381
+ }
382
+
383
+ .#{$component}-input {
384
+ padding-right: 16px;
385
+ // Default value - will be overridden by JS for precise padding
386
+ padding-left: 76px;
387
+ }
388
+ }
228
389
  }
229
390
  }
230
391
 
@@ -273,8 +434,20 @@ $component: '#{base.$prefix}-textfield';
273
434
  &:not(.#{$component}--empty) .#{$component}-label,
274
435
  &.#{$component}--focused .#{$component}-label {
275
436
  transform: translateY(-95%) scale(0.75);
437
+ // Don't specify left position here - let JS handle it
438
+ }
439
+
440
+ // Position adjustments for prefix/suffix when in filled focused/populated state
441
+ &.mtrl-textfield--with-prefix,
442
+ &.mtrl-textfield--with-suffix {
443
+ &:not(.#{$component}--empty),
444
+ &.#{$component}--focused {
445
+ .#{$component}-prefix,
446
+ .#{$component}-suffix {
447
+ top: 34px; // Align with input text when focused or populated
448
+ }
449
+ }
276
450
  }
277
-
278
451
  // Focus state
279
452
  &.#{$component}--focused {
280
453
  .#{$component}-label {
@@ -286,13 +459,6 @@ $component: '#{base.$prefix}-textfield';
286
459
  }
287
460
  }
288
461
 
289
- // // Hover state
290
- // &:hover {
291
- // .#{$component}-label {
292
- // color: t.color('primary');
293
- // }
294
- // }
295
-
296
462
  // Error state
297
463
  &.#{$component}--error {
298
464
  &::before {
@@ -315,6 +481,19 @@ $component: '#{base.$prefix}-textfield';
315
481
  }
316
482
  }
317
483
 
484
+ // Prefix/suffix adjustments for filled variant
485
+ &.#{$component}--with-prefix {
486
+ .#{$component}-prefix {
487
+ top: 28px; // Align with input text in filled variant - default state
488
+ }
489
+ }
490
+
491
+ &.#{$component}--with-suffix {
492
+ .#{$component}-suffix {
493
+ top: 28px; // Align with input text in filled variant - default state
494
+ }
495
+ }
496
+
318
497
  // Icon adjustments for filled variant
319
498
  &.#{$component}--with-leading-icon {
320
499
  .#{$component}-input {
@@ -325,18 +504,23 @@ $component: '#{base.$prefix}-textfield';
325
504
  left: 44px;
326
505
  }
327
506
 
328
- &:not(.#{$component}--empty) .#{$component}-label,
329
- &.#{$component}--focused .#{$component}-label {
330
- transform: translateY(-95%) scale(0.75);
331
- // Keep the label aligned with input text when focused/filled
332
- left: 44px;
333
- }
334
-
335
507
  .#{$component}-leading-icon {
336
508
  top: 28px;
337
509
  }
510
+
338
511
  }
339
512
 
513
+ // Populated field (not empty) or focused field label position
514
+ &:not(.#{$component}--empty) .#{$component}-label,
515
+ &.#{$component}--focused .#{$component}-label {
516
+ // Important change: For outlined variant, when focused/populated
517
+ // we want to reset the left position back to default (or to JS calculated equivalent)
518
+ // to handle the label moving up above the field
519
+ // The JS will handle special positioning depending on if it's prefixed
520
+ left: 16px;
521
+ }
522
+
523
+
340
524
  &.#{$component}--with-trailing-icon {
341
525
  .#{$component}-input {
342
526
  padding-right: 44px;
@@ -363,12 +547,6 @@ $component: '#{base.$prefix}-textfield';
363
547
  left: auto;
364
548
  right: 44px;
365
549
  }
366
-
367
- &:not(.#{$component}--empty) .#{$component}-label,
368
- &.#{$component}--focused .#{$component}-label {
369
- // Keep the label aligned with input text when focused/filled in RTL
370
- right: 44px;
371
- }
372
550
  }
373
551
 
374
552
  &.#{$component}--with-trailing-icon {
@@ -434,6 +612,11 @@ $component: '#{base.$prefix}-textfield';
434
612
  &.#{$component}--focused .#{$component}-label {
435
613
  padding: 0 4px;
436
614
  transform: translateY(-147%) scale(0.75);
615
+ // Important change: For outlined variant, when focused/populated
616
+ // we want to reset the left position back to default (or to JS calculated equivalent)
617
+ // to handle the label moving up above the field
618
+ // The JS will handle special positioning depending on if it's prefixed
619
+ left: 12px;
437
620
  }
438
621
 
439
622
  // Focus state
@@ -473,6 +656,19 @@ $component: '#{base.$prefix}-textfield';
473
656
  }
474
657
  }
475
658
 
659
+ // Prefix/suffix vertical alignment for outlined variant
660
+ &.#{$component}--with-prefix {
661
+ .#{$component}-prefix {
662
+ top: 50%; // Centered vertically in outlined variant
663
+ }
664
+ }
665
+
666
+ &.#{$component}--with-suffix {
667
+ .#{$component}-suffix {
668
+ top: 50%; // Centered vertically in outlined variant
669
+ }
670
+ }
671
+
476
672
  // Icon adjustments for outlined variant
477
673
  &.#{$component}--with-leading-icon {
478
674
  .#{$component}-input {
@@ -483,10 +679,11 @@ $component: '#{base.$prefix}-textfield';
483
679
  left: 44px;
484
680
  }
485
681
 
682
+ // Important change: For outlined variant, when focused/populated
683
+ // we still reset to 12px position (default)
486
684
  &:not(.#{$component}--empty) .#{$component}-label,
487
685
  &.#{$component}--focused .#{$component}-label {
488
- // For outlined variant, move label to default position
489
- left: 13px;
686
+ left: 12px;
490
687
  }
491
688
  }
492
689
 
@@ -501,7 +698,7 @@ $component: '#{base.$prefix}-textfield';
501
698
  &:not(.#{$component}--empty) .#{$component}-label,
502
699
  &.#{$component}--focused .#{$component}-label {
503
700
  left: auto;
504
- right: 13px;
701
+ right: 12px;
505
702
  }
506
703
 
507
704
  &.#{$component}--focused .#{$component}-label {
@@ -525,8 +722,8 @@ $component: '#{base.$prefix}-textfield';
525
722
 
526
723
  &:not(.#{$component}--empty) .#{$component}-label,
527
724
  &.#{$component}--focused .#{$component}-label {
528
- // For outlined variant in RTL, move label to default position
529
- right: 13px;
725
+ // Reset to default value for focused state
726
+ right: 12px;
530
727
  left: auto;
531
728
  }
532
729
  }
@@ -549,19 +746,11 @@ $component: '#{base.$prefix}-textfield';
549
746
  padding-top: 12px;
550
747
  }
551
748
 
552
- &--filled {
553
- .#{$component}-input {
554
-
555
- }
749
+ .#{$component}-prefix,
750
+ .#{$component}-suffix {
751
+ top: 28px;
556
752
  }
557
-
558
- &--outlined {
559
- .#{$component}-input {
560
-
561
- }
562
- }
563
-
564
-
753
+
565
754
  .#{$component}-label {
566
755
  top: 24px;
567
756
  }
@@ -574,7 +763,9 @@ $component: '#{base.$prefix}-textfield';
574
763
  resize: vertical;
575
764
 
576
765
  & ~ .#{$component}-leading-icon,
577
- & ~ .#{$component}-trailing-icon {
766
+ & ~ .#{$component}-trailing-icon,
767
+ & ~ .#{$component}-prefix,
768
+ & ~ .#{$component}-suffix {
578
769
  top: 20px;
579
770
  transform: none;
580
771
  }
@@ -34,6 +34,7 @@
34
34
  @use './components/menu' as menu;
35
35
  @use './components/slider' as slider;
36
36
  @use './components/switch' as switch;
37
+ @use './components/select' as select;
37
38
  @use './components/tabs' as tabs;
38
39
  @use './components/top-app-bar' as top-app-bar;
39
40
 
@@ -44,7 +45,7 @@
44
45
  @use './components/card' as card;
45
46
  @use './components/carousel' as carousel;
46
47
  @use './components/checkbox' as checkbox;
47
- @use './components/chip' as chip;
48
+ @use './components/chips' as chips;
48
49
  @use './components/datepicker' as datepicker;
49
50
  @use './components/dialog' as dialog;
50
51
  @use './components/divider' as divider;