mtrl 0.0.2 → 0.1.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 (52) hide show
  1. package/package.json +2 -2
  2. package/src/components/button/styles.scss +198 -161
  3. package/src/components/checkbox/checkbox.js +4 -3
  4. package/src/components/checkbox/styles.scss +105 -55
  5. package/src/components/container/styles.scss +65 -58
  6. package/src/components/list/styles.scss +240 -11
  7. package/src/components/menu/features/items-manager.js +5 -1
  8. package/src/components/menu/styles.scss +37 -30
  9. package/src/components/navigation/constants.js +19 -54
  10. package/src/components/navigation/styles.scss +406 -6
  11. package/src/components/snackbar/styles.scss +46 -17
  12. package/src/components/switch/styles.scss +104 -40
  13. package/src/components/switch/switch.js +1 -1
  14. package/src/components/textfield/styles.scss +351 -5
  15. package/src/core/build/_ripple.scss +79 -0
  16. package/src/core/compose/features/disabled.js +27 -7
  17. package/src/core/compose/features/input.js +9 -1
  18. package/src/core/compose/features/textinput.js +16 -20
  19. package/src/core/dom/create.js +0 -1
  20. package/src/styles/abstract/_mixins.scss +9 -7
  21. package/src/styles/abstract/_theme.scss +157 -0
  22. package/src/styles/abstract/_variables.scss +72 -6
  23. package/src/styles/base/_reset.scss +86 -0
  24. package/src/styles/base/_typography.scss +155 -0
  25. package/src/styles/main.scss +104 -57
  26. package/src/styles/themes/_base-theme.scss +2 -27
  27. package/src/styles/themes/_baseline.scss +64 -39
  28. package/src/styles/utilities/_color.scss +154 -0
  29. package/src/styles/utilities/_flexbox.scss +194 -0
  30. package/src/styles/utilities/_spacing.scss +139 -0
  31. package/src/styles/utilities/_typography.scss +178 -0
  32. package/src/styles/utilities/_visibility.scss +142 -0
  33. package/test/components/button.test.js +46 -34
  34. package/test/components/checkbox.test.js +238 -0
  35. package/test/components/list.test.js +105 -0
  36. package/test/components/menu.test.js +385 -0
  37. package/test/components/navigation.test.js +227 -0
  38. package/test/components/snackbar.test.js +234 -0
  39. package/test/components/switch.test.js +186 -0
  40. package/test/components/textfield.test.js +314 -0
  41. package/test/core/ripple.test.js +21 -120
  42. package/test/setup.js +152 -239
  43. package/src/components/list/styles/_list-item.scss +0 -142
  44. package/src/components/list/styles/_list.scss +0 -89
  45. package/src/components/list/styles/_variables.scss +0 -13
  46. package/src/components/navigation/styles/_bar.scss +0 -51
  47. package/src/components/navigation/styles/_base.scss +0 -129
  48. package/src/components/navigation/styles/_drawer.scss +0 -169
  49. package/src/components/navigation/styles/_rail.scss +0 -65
  50. package/src/components/textfield/styles/base.scss +0 -107
  51. package/src/components/textfield/styles/filled.scss +0 -58
  52. package/src/components/textfield/styles/outlined.scss +0 -66
@@ -1,9 +1,13 @@
1
- // src/components/snackbar/styles.scss
2
- @use 'sass:map';
3
- @use '../../styles/abstract/mixins' as m;
1
+ // src/components/snackbar/_snackbar.scss
2
+ @use '../../styles/abstract/base' as base;
4
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;
5
7
 
6
- .#{v.$prefix}-snackbar {
8
+ $component: '#{base.$prefix}-snackbar';
9
+
10
+ .#{$component} {
7
11
  // Base styles following modern minimal design
8
12
  @include m.typography('body-medium');
9
13
  position: fixed;
@@ -12,26 +16,29 @@
12
16
  justify-content: space-between;
13
17
  min-width: 280px;
14
18
  max-width: 480px;
15
- padding: 12px 16px;
19
+ padding: 14px 16px;
16
20
  gap: 12px;
17
21
 
18
22
  // Updated colors and appearance
19
23
  background-color: rgba(32, 33, 36, 0.9);
20
24
  color: rgb(255, 255, 255);
21
- border-radius: 4px;
25
+ border-radius: f.get-shape('extra-small');
22
26
  backdrop-filter: blur(8px);
23
27
 
24
28
  // Animation setup - separated properties for better transitions
25
29
  opacity: 0;
26
30
  transform: translateY(20px);
27
31
  transition:
28
- opacity 200ms cubic-bezier(0.4, 0, 0.2, 1),
29
- transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
32
+ opacity v.motion('duration-short2') v.motion('easing-standard'),
33
+ transform v.motion('duration-short2') v.motion('easing-standard');
30
34
 
31
- z-index: var(--mtrl-sys-z-index-snackbar);
35
+ // Using a fixed z-index since 'snackbar' isn't defined in z-index tokens
36
+ z-index: f.get-z-index('popover');
32
37
  pointer-events: none;
33
38
  will-change: transform, opacity;
34
39
 
40
+ @include m.elevation(2);
41
+
35
42
  // Message text styles
36
43
  &-text {
37
44
  @include m.truncate(1);
@@ -44,17 +51,18 @@
44
51
  &-action {
45
52
  @include m.typography('label-large');
46
53
  padding: 8px 12px;
47
- margin: -8px -12px;
54
+ margin: -8px -10px -8px -4px;
55
+ // margin-left: 4px;
48
56
  color: rgb(138, 180, 248);
49
57
  background: none;
50
58
  border: none;
51
- border-radius: 4px;
59
+ border-radius: f.get-shape('extra-small');
52
60
  cursor: pointer;
53
61
  font-weight: 500;
54
62
  font-size: 14px;
55
63
  text-transform: capitalize;
56
64
  white-space: nowrap;
57
- transition: background-color 150ms ease;
65
+ @include m.motion-transition(background-color);
58
66
 
59
67
  &:hover {
60
68
  background-color: rgba(138, 180, 248, 0.08);
@@ -129,12 +137,12 @@
129
137
  opacity: 1;
130
138
  pointer-events: auto;
131
139
 
132
- &.#{v.$prefix}-snackbar--start,
133
- &.#{v.$prefix}-snackbar--end {
140
+ &.#{$component}--start,
141
+ &.#{$component}--end {
134
142
  transform: translateY(0);
135
143
  }
136
144
 
137
- &.#{v.$prefix}-snackbar--center {
145
+ &.#{$component}--center {
138
146
  transform: translate(-50%, 0);
139
147
  }
140
148
  }
@@ -144,11 +152,32 @@
144
152
  padding-top: 14px;
145
153
  padding-bottom: 14px;
146
154
 
147
- .#{v.$prefix}-snackbar-text {
155
+ .#{$component}-text {
148
156
  @include m.truncate(2);
149
157
  }
150
158
  }
151
159
 
160
+ // Color variants
161
+ &--primary {
162
+ background-color: t.alpha('primary', 0.9);
163
+
164
+ .#{$component}-action {
165
+ color: t.color('on-primary');
166
+
167
+ &:hover {
168
+ background-color: t.alpha('on-primary', 0.08);
169
+ }
170
+
171
+ &:active {
172
+ background-color: t.alpha('on-primary', 0.12);
173
+ }
174
+
175
+ &:focus-visible {
176
+ outline-color: t.color('on-primary');
177
+ }
178
+ }
179
+ }
180
+
152
181
  // Accessibility
153
182
  @include m.reduced-motion {
154
183
  transition: none;
@@ -157,7 +186,7 @@
157
186
  &--visible {
158
187
  transform: none;
159
188
 
160
- &.#{v.$prefix}-snackbar--center {
189
+ &.#{$component}--center {
161
190
  transform: translateX(-50%);
162
191
  }
163
192
  }
@@ -1,8 +1,14 @@
1
- // src/components/switch/styles.scss
2
- @use 'sass:map';
3
- @use '../../styles/abstract/config' as c;
1
+ // src/components/switch/_switch.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;
4
7
 
5
- .#{c.$prefix}-switch {
8
+ $component: '#{base.$prefix}-switch';
9
+
10
+ .#{$component} {
11
+ // Base styles
6
12
  display: inline-flex;
7
13
  align-items: center;
8
14
  position: relative;
@@ -10,6 +16,7 @@
10
16
  padding: 4px 0;
11
17
  user-select: none;
12
18
 
19
+ // Input (visually hidden but accessible)
13
20
  &-input {
14
21
  position: absolute;
15
22
  opacity: 0;
@@ -23,25 +30,25 @@
23
30
  cursor: not-allowed;
24
31
  }
25
32
 
26
- // New focus style that's more visible
27
- &:focus-visible ~ .#{c.$prefix}-switch-track {
28
- outline: 2px solid var(--mtrl-sys-color-primary);
33
+ // Focus indicator
34
+ &:focus-visible ~ .#{$component}-track {
35
+ outline: 2px solid t.color('primary');
29
36
  outline-offset: 2px;
30
37
  }
31
38
  }
32
39
 
40
+ // Switch track (background bar)
33
41
  &-track {
34
42
  position: relative;
35
43
  min-width: 52px;
36
44
  height: 32px;
37
45
  border-radius: 16px;
38
- background-color: var(--mtrl-sys-color-surface-container-highest);
39
- border: 2px solid var(--mtrl-sys-color-outline);
40
- transition: background-color map.get(c.$motion, 'duration-short4') map.get(c.$motion, 'easing-standard'),
41
- border-color map.get(c.$motion, 'duration-short4') map.get(c.$motion, 'easing-standard'),
42
- outline map.get(c.$motion, 'duration-short4') map.get(c.$motion, 'easing-standard');
46
+ background-color: t.color('surface-container-highest');
47
+ border: 2px solid t.color('outline');
48
+ @include m.motion-transition(background-color, border-color, outline);
43
49
  }
44
50
 
51
+ // Switch thumb (slider)
45
52
  &-thumb {
46
53
  position: absolute;
47
54
  top: 6px;
@@ -49,21 +56,22 @@
49
56
  width: 16px;
50
57
  height: 16px;
51
58
  border-radius: 50%;
52
- background-color: var(--mtrl-sys-color-outline);
59
+ background-color: t.color('outline');
53
60
  transform: translateX(0);
54
- transition: all map.get(c.$motion, 'duration-short4') map.get(c.$motion, 'easing-emphasized');
61
+ transition: all v.motion('duration-short4') v.motion('easing-emphasized');
55
62
  display: flex;
56
63
  align-items: center;
57
64
  justify-content: center;
58
65
 
66
+ // Icon inside thumb
59
67
  &-icon {
60
68
  display: flex;
61
69
  align-items: center;
62
70
  justify-content: center;
63
71
  opacity: 0;
64
72
  transform: scale(0);
65
- transition: all map.get(c.$motion, 'duration-short4') map.get(c.$motion, 'easing-emphasized');
66
- color: var(--mtrl-sys-color-primary);
73
+ transition: all v.motion('duration-short4') v.motion('easing-emphasized');
74
+ color: t.color('primary');
67
75
 
68
76
  svg {
69
77
  width: 14px;
@@ -72,17 +80,18 @@
72
80
  }
73
81
  }
74
82
 
83
+ // Label
75
84
  &-label {
76
- @include c.typography('body-large');
85
+ @include m.typography('body-large');
77
86
  margin-left: 12px;
78
- color: var(--mtrl-sys-color-on-surface);
87
+ color: t.color('on-surface');
79
88
  }
80
89
 
81
90
  // Label position variants
82
91
  &--label-start {
83
92
  flex-direction: row-reverse;
84
93
 
85
- .#{c.$prefix}-switch-label {
94
+ .#{$component}-label {
86
95
  margin-left: 0;
87
96
  margin-right: 12px;
88
97
  }
@@ -91,37 +100,43 @@
91
100
  &--label-end {
92
101
  flex-direction: row;
93
102
 
94
- .#{c.$prefix}-switch-label {
103
+ .#{$component}-label {
95
104
  margin-left: 12px;
96
105
  margin-right: 0;
97
106
  }
98
107
  }
99
108
 
100
- @include c.rtl {
109
+ // RTL support
110
+ @include m.rtl {
101
111
  &--label-start {
102
- .#{c.$prefix}-switch-label {
112
+ .#{$component}-label {
103
113
  margin-left: 12px;
104
114
  margin-right: 0;
105
115
  }
106
116
  }
107
117
 
108
118
  &--label-end {
109
- .#{c.$prefix}-switch-label {
119
+ .#{$component}-label {
110
120
  margin-left: 0;
111
121
  margin-right: 12px;
112
122
  }
113
123
  }
124
+
125
+ // Adjust thumb movement for RTL layout
126
+ &--checked .#{$component}-thumb {
127
+ transform: translateX(-20px);
128
+ }
114
129
  }
115
130
 
116
- // States
131
+ // Checked state
117
132
  &--checked {
118
- .#{c.$prefix}-switch-track {
119
- background-color: var(--mtrl-sys-color-primary);
120
- border-color: var(--mtrl-sys-color-primary);
133
+ .#{$component}-track {
134
+ background-color: t.color('primary');
135
+ border-color: t.color('primary');
121
136
  }
122
137
 
123
- .#{c.$prefix}-switch-thumb {
124
- background-color: var(--mtrl-sys-color-on-primary);
138
+ .#{$component}-thumb {
139
+ background-color: t.color('on-primary');
125
140
  transform: translateX(20px);
126
141
  width: 24px;
127
142
  height: 24px;
@@ -135,13 +150,46 @@
135
150
  }
136
151
  }
137
152
 
153
+ // Disabled state
138
154
  &--disabled {
139
- opacity: .5;
155
+ opacity: 0.38;
156
+
157
+ // Specific styles for disabled + checked
158
+ &.#{$component}--checked {
159
+ .#{$component}-track {
160
+ background-color: t.color('outline');
161
+ border-color: t.color('outline');
162
+ opacity: 0.38;
163
+ }
164
+
165
+ .#{$component}-thumb {
166
+ background-color: t.color('on-primary');
167
+ opacity: 1;
168
+ &-icon {
169
+ color: t.color('outline')
170
+ }
171
+ }
172
+ }
140
173
  }
141
174
 
142
- // Hover effects
175
+ // Hover effects (state layer)
143
176
  &:not(&--disabled) {
144
- .#{c.$prefix}-switch-input:hover + .#{c.$prefix}-switch-track {
177
+ .#{$component}-input:hover + .#{$component}-track {
178
+ &::before {
179
+ content: '';
180
+ position: absolute;
181
+ top: -8px;
182
+ left: -8px;
183
+ right: -8px;
184
+ bottom: -8px;
185
+ background-color: t.color('on-surface');
186
+ opacity: v.state('hover-state-layer-opacity');
187
+ border-radius: 20px;
188
+ }
189
+ }
190
+
191
+ // Active/pressed state
192
+ .#{$component}-input:active + .#{$component}-track {
145
193
  &::before {
146
194
  content: '';
147
195
  position: absolute;
@@ -149,24 +197,40 @@
149
197
  left: -8px;
150
198
  right: -8px;
151
199
  bottom: -8px;
152
- background-color: var(--mtrl-sys-color-on-surface);
153
- opacity: 0.08;
200
+ background-color: t.color('on-surface');
201
+ opacity: v.state('pressed-state-layer-opacity');
154
202
  border-radius: 20px;
155
203
  }
156
204
  }
205
+
206
+ // Hover/active states when checked
207
+ &.#{$component}--checked {
208
+ .#{$component}-input:hover + .#{$component}-track::before,
209
+ .#{$component}-input:active + .#{$component}-track::before {
210
+ background-color: t.color('primary');
211
+ }
212
+ }
157
213
  }
158
214
 
159
- @include c.reduced-motion {
160
- .#{c.$prefix}-switch-track,
161
- .#{c.$prefix}-switch-thumb,
162
- .#{c.$prefix}-switch-thumb-icon {
215
+ // Accessibility
216
+ @include m.reduced-motion {
217
+ .#{$component}-track,
218
+ .#{$component}-thumb,
219
+ .#{$component}-thumb-icon {
163
220
  transition: none;
164
221
  }
165
222
  }
166
223
 
167
- @include c.high-contrast {
168
- .#{c.$prefix}-switch-track {
224
+ @include m.high-contrast {
225
+ .#{$component}-track {
169
226
  border-width: 2px;
170
227
  }
228
+
229
+ &--checked .#{$component}-track {
230
+ border-color: currentColor;
231
+ }
171
232
  }
233
+
234
+ // Touch target for better mobile experience
235
+ // @include m.touch-target;
172
236
  }
@@ -58,7 +58,7 @@ const createSwitch = (config = {}) => {
58
58
  withTextLabel(baseConfig),
59
59
  withLabelPosition(baseConfig),
60
60
  withCheckable(baseConfig),
61
- withDisabled(),
61
+ withDisabled(baseConfig), // Pass the config to ensure disabled state is properly initialized
62
62
  withLifecycle(),
63
63
  comp => withAPI({
64
64
  disabled: comp.disabled,