mtrl 0.2.0 → 0.2.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mtrl",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "A functional JavaScript component library with composable architecture based on Material Design 3",
5
5
  "keywords": [
6
6
  "component",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "author": "floor",
25
25
  "license": "MIT License",
26
- "dependencies": {
26
+ "devDependencies": {
27
27
  "typedoc": "^0.27.9"
28
28
  }
29
29
  }
@@ -21,6 +21,20 @@ export const CARD_ELEVATIONS = {
21
21
  DRAGGED: CardElevation.DRAGGED
22
22
  };
23
23
 
24
+ // Default width values following MD3 principles
25
+ export const CARD_WIDTHS = {
26
+ // Mobile-optimized default (MD3 recommends 344dp for small screens)
27
+ DEFAULT: '344px',
28
+ // Percentage-based responsive options
29
+ FULL: '100%',
30
+ HALF: '50%',
31
+ // Fixed widths for different breakpoints
32
+ SMALL: '344px',
33
+ MEDIUM: '480px',
34
+ LARGE: '624px'
35
+ }
36
+
37
+
24
38
  /**
25
39
  * Validation schema for card configuration
26
40
  */
@@ -1,4 +1,4 @@
1
- // src/components/checkbox/constants.js
1
+ // src/components/checkbox/constants.ts
2
2
 
3
3
  /**
4
4
  * Visual variants for checkbox
@@ -6,7 +6,7 @@
6
6
  export const CHECKBOX_VARIANTS = {
7
7
  FILLED: 'filled',
8
8
  OUTLINED: 'outlined'
9
- }
9
+ } as const;
10
10
 
11
11
  /**
12
12
  * Label position options
@@ -14,58 +14,7 @@ export const CHECKBOX_VARIANTS = {
14
14
  export const CHECKBOX_LABEL_POSITION = {
15
15
  START: 'start',
16
16
  END: 'end'
17
- }
18
-
19
- /**
20
- * Validation schema for checkbox configuration
21
- */
22
- export const CHECKBOX_SCHEMA = {
23
- type: 'object',
24
- properties: {
25
- name: {
26
- type: 'string',
27
- optional: true
28
- },
29
- checked: {
30
- type: 'boolean',
31
- optional: true
32
- },
33
- indeterminate: {
34
- type: 'boolean',
35
- optional: true
36
- },
37
- required: {
38
- type: 'boolean',
39
- optional: true
40
- },
41
- disabled: {
42
- type: 'boolean',
43
- optional: true
44
- },
45
- value: {
46
- type: 'string',
47
- optional: true
48
- },
49
- label: {
50
- type: 'string',
51
- optional: true
52
- },
53
- labelPosition: {
54
- type: 'string',
55
- enum: Object.values(CHECKBOX_LABEL_POSITION),
56
- optional: true
57
- },
58
- variant: {
59
- type: 'string',
60
- enum: Object.values(CHECKBOX_VARIANTS),
61
- optional: true
62
- },
63
- class: {
64
- type: 'string',
65
- optional: true
66
- }
67
- }
68
- }
17
+ } as const;
69
18
 
70
19
  /**
71
20
  * Checkbox state classes
@@ -75,7 +24,7 @@ export const CHECKBOX_STATES = {
75
24
  INDETERMINATE: 'indeterminate',
76
25
  DISABLED: 'disabled',
77
26
  FOCUSED: 'focused'
78
- }
27
+ } as const;
79
28
 
80
29
  /**
81
30
  * Checkbox element classes
@@ -85,4 +34,4 @@ export const CHECKBOX_CLASSES = {
85
34
  INPUT: 'checkbox-input',
86
35
  ICON: 'checkbox-icon',
87
36
  LABEL: 'checkbox-label'
88
- }
37
+ } as const;
@@ -13,25 +13,21 @@ $component: '#{base.$prefix}-chip';
13
13
  display: inline-flex;
14
14
  align-items: center;
15
15
  justify-content: center;
16
- height: 32px;
17
- padding: 0 12px;
18
- border: none;
19
- border-radius: 8px;
16
+ height: v.chip('height');
17
+ padding: 0 v.chip('padding-horizontal');
18
+ border-radius: v.chip('border-radius');
20
19
  background-color: transparent;
21
- color: inherit;
22
- font: inherit;
23
- text-decoration: none;
24
- cursor: pointer;
25
- user-select: none;
26
- vertical-align: middle;
27
- appearance: none;
20
+ max-width: 100%;
28
21
  overflow: hidden;
29
- transition: background-color 0.15s ease, box-shadow 0.15s ease, color 0.15s ease,
30
- border-color 0.15s ease, opacity 0.15s ease;
22
+ user-select: none;
23
+ cursor: pointer;
31
24
 
32
25
  // Typography
33
26
  @include m.typography('label-large');
34
27
 
28
+ // Interaction styles
29
+ @include m.motion-transition(background-color, color, border-color, box-shadow);
30
+
35
31
  // Focus styles
36
32
  &:focus {
37
33
  outline: none;
@@ -43,50 +39,57 @@ $component: '#{base.$prefix}-chip';
43
39
  }
44
40
 
45
41
  // Disabled state
46
- &[aria-disabled="true"] {
47
- pointer-events: none;
42
+ &--disabled {
48
43
  opacity: 0.38;
44
+ pointer-events: none;
49
45
  }
50
46
 
51
- // Leading icon styles
52
- &-icon {
53
- display: inline-flex;
47
+ // Content container
48
+ &-content {
49
+ display: flex;
54
50
  align-items: center;
55
51
  justify-content: center;
56
- width: 18px;
57
- height: 18px;
58
- margin-right: 8px;
59
-
60
- svg {
61
- width: 18px;
62
- height: 18px;
63
- }
52
+ width: 100%;
53
+ height: 100%;
64
54
  }
65
55
 
66
- // Trailing icon styles
56
+ // Ensure proper layout with icons
57
+ &-leading-icon,
67
58
  &-trailing-icon {
68
59
  display: inline-flex;
69
60
  align-items: center;
70
61
  justify-content: center;
71
62
  width: 18px;
72
63
  height: 18px;
73
- margin-left: 8px;
74
64
 
75
65
  svg {
76
66
  width: 18px;
77
67
  height: 18px;
78
68
  }
69
+ }
70
+
71
+ &-leading-icon {
72
+ margin-right: 8px;
73
+ }
74
+
75
+ &-trailing-icon {
76
+ margin-left: 8px;
79
77
 
80
78
  &:hover {
81
- opacity: 0.8;
79
+ opacity: 0.7;
82
80
  }
83
81
  }
84
82
 
85
- // Text content
86
83
  &-text {
87
84
  // Text truncation for long chip labels
88
85
  @include m.truncate;
89
- max-width: 150px;
86
+ }
87
+
88
+ // Selected state
89
+ &--selected {
90
+ // Default selected state styling (can be overridden by variants)
91
+ background-color: t.alpha('on-surface', 0.12);
92
+ font-weight: 500;
90
93
  }
91
94
 
92
95
  // Ripple container
@@ -99,9 +102,7 @@ $component: '#{base.$prefix}-chip';
99
102
  opacity: 0.12;
100
103
  }
101
104
 
102
- // === VARIANTS ===
103
-
104
- // Filled chip (default)
105
+ // Variants
105
106
  &--filled {
106
107
  background-color: t.color('surface-container-highest');
107
108
  color: t.color('on-surface');
@@ -128,7 +129,6 @@ $component: '#{base.$prefix}-chip';
128
129
  }
129
130
  }
130
131
 
131
- // Outlined chip
132
132
  &--outlined {
133
133
  border: 1px solid t.color('outline');
134
134
  color: t.color('on-surface');
@@ -142,21 +142,16 @@ $component: '#{base.$prefix}-chip';
142
142
  }
143
143
 
144
144
  &.#{$component}--selected {
145
- border-color: t.color('secondary');
145
+ border-color: t.color('outline');
146
146
  background-color: t.color('secondary-container');
147
147
  color: t.color('on-secondary-container');
148
148
 
149
149
  &:hover {
150
150
  @include m.state-layer(t.color('on-secondary-container'), 'hover');
151
151
  }
152
-
153
- &:active {
154
- @include m.state-layer(t.color('on-secondary-container'), 'pressed');
155
- }
156
152
  }
157
153
  }
158
154
 
159
- // Elevated chip
160
155
  &--elevated {
161
156
  background-color: t.color('surface-container-low');
162
157
  color: t.color('on-surface');
@@ -179,109 +174,79 @@ $component: '#{base.$prefix}-chip';
179
174
  &:hover {
180
175
  @include m.state-layer(t.color('on-secondary-container'), 'hover');
181
176
  }
182
-
183
- &:active {
184
- @include m.state-layer(t.color('on-secondary-container'), 'pressed');
185
- }
186
- }
187
-
188
- &[aria-disabled="true"] {
189
- @include m.elevation(0);
190
- box-shadow: none;
191
177
  }
192
178
  }
193
179
 
194
- // Assist chip
195
- &--assist {
196
- background-color: t.color('surface-container');
180
+ // Filter chip specific styling
181
+ &--filter {
182
+ background-color: t.color('surface-container-highest');
197
183
  color: t.color('on-surface');
198
184
 
199
185
  &:hover {
200
186
  @include m.state-layer(t.color('on-surface'), 'hover');
201
187
  }
202
188
 
203
- &:active {
204
- @include m.state-layer(t.color('on-surface'), 'pressed');
205
- }
206
-
207
- .#{$component}-icon {
208
- color: t.color('primary');
189
+ &.#{$component}--selected {
190
+ background-color: t.color('secondary-container');
191
+ color: t.color('on-secondary-container');
192
+
193
+ .#{$component}-leading-icon {
194
+ color: t.color('on-secondary-container');
195
+ }
209
196
  }
210
197
  }
211
198
 
212
- // Filter chip
213
- &--filter {
214
- background-color: t.color('surface-container-highest');
199
+ // Assist chip specific styling
200
+ &--assist {
201
+ background-color: t.color('surface-container-low');
215
202
  color: t.color('on-surface');
216
203
 
217
- &:hover {
218
- @include m.state-layer(t.color('on-surface'), 'hover');
219
- }
220
-
221
- &:active {
222
- @include m.state-layer(t.color('on-surface'), 'pressed');
204
+ .#{$component}-leading-icon {
205
+ color: t.color('primary');
223
206
  }
224
207
 
225
208
  &.#{$component}--selected {
226
209
  background-color: t.color('secondary-container');
227
210
  color: t.color('on-secondary-container');
228
211
 
229
- &:hover {
230
- @include m.state-layer(t.color('on-secondary-container'), 'hover');
231
- }
232
-
233
- &:active {
234
- @include m.state-layer(t.color('on-secondary-container'), 'pressed');
235
- }
236
-
237
- // Checkmark icon for selected filter chips
238
- .#{$component}-icon {
212
+ .#{$component}-leading-icon {
239
213
  color: t.color('on-secondary-container');
240
214
  }
241
215
  }
242
216
  }
243
217
 
244
- // Input chip
218
+ // Input chip specific styling
245
219
  &--input {
246
220
  background-color: t.color('surface-container-highest');
247
221
  color: t.color('on-surface');
248
- padding-right: 8px; // Less padding on the right to accommodate the trailing icon
249
-
250
- &:hover {
251
- @include m.state-layer(t.color('on-surface'), 'hover');
252
- }
253
222
 
254
223
  .#{$component}-trailing-icon {
255
- color: t.color('on-surface-variant');
224
+ cursor: pointer;
256
225
 
257
226
  &:hover {
258
- color: t.color('on-surface');
227
+ color: t.color('error');
259
228
  }
260
229
  }
261
230
  }
262
231
 
263
- // Suggestion chip
232
+ // Suggestion chip styling
264
233
  &--suggestion {
265
234
  background-color: t.color('surface-container');
266
235
  color: t.color('on-surface');
267
236
 
268
- &:hover {
269
- @include m.state-layer(t.color('on-surface'), 'hover');
270
- }
271
-
272
- &:active {
273
- @include m.state-layer(t.color('on-surface'), 'pressed');
237
+ &.#{$component}--selected {
238
+ background-color: t.color('secondary-container');
239
+ color: t.color('on-secondary-container');
274
240
  }
275
241
  }
276
242
 
277
- // === SIZES ===
278
-
243
+ // Size variants
279
244
  &--small {
280
245
  height: 24px;
281
246
  padding: 0 8px;
282
247
  font-size: 12px;
283
248
 
284
- .#{$component}-icon,
249
+ .#{$component}-leading-icon,
285
250
  .#{$component}-trailing-icon {
286
251
  width: 16px;
287
252
  height: 16px;
@@ -291,23 +256,18 @@ $component: '#{base.$prefix}-chip';
291
256
  height: 16px;
292
257
  }
293
258
  }
294
-
295
- .#{$component}-icon {
296
- margin-right: 4px;
297
- }
298
-
299
- .#{$component}-trailing-icon {
300
- margin-left: 4px;
301
- }
259
+ }
260
+
261
+ &--medium {
262
+ // Default size, styles already defined
302
263
  }
303
264
 
304
265
  &--large {
305
266
  height: 40px;
306
267
  padding: 0 16px;
307
- font-size: 15px;
308
- border-radius: 12px;
268
+ font-size: 16px;
309
269
 
310
- .#{$component}-icon,
270
+ .#{$component}-leading-icon,
311
271
  .#{$component}-trailing-icon {
312
272
  width: 20px;
313
273
  height: 20px;
@@ -317,40 +277,11 @@ $component: '#{base.$prefix}-chip';
317
277
  height: 20px;
318
278
  }
319
279
  }
320
-
321
- .#{$component}-icon {
322
- margin-right: 10px;
323
- }
324
-
325
- .#{$component}-trailing-icon {
326
- margin-left: 10px;
327
- }
328
- }
329
-
330
- // === SPECIAL CASES ===
331
-
332
- // For chips with only icons (no text)
333
- &--icon-only {
334
- padding: 0;
335
- width: 32px;
336
-
337
- &.#{$component}--small {
338
- width: 24px;
339
- }
340
-
341
- &.#{$component}--large {
342
- width: 40px;
343
- }
344
-
345
- .#{$component}-icon {
346
- margin-right: 0;
347
- }
348
280
  }
349
281
  }
350
282
 
351
- // === CHIP SET STYLES ===
352
-
353
- .#{$component}-set {
283
+ // Chip set container
284
+ .#{base.$prefix}-chip-set {
354
285
  display: flex;
355
286
  flex-wrap: wrap;
356
287
  gap: 8px;
@@ -358,11 +289,23 @@ $component: '#{base.$prefix}-chip';
358
289
  &--scrollable {
359
290
  flex-wrap: nowrap;
360
291
  overflow-x: auto;
361
- scrollbar-width: none; // Firefox
292
+ padding-bottom: 8px;
293
+ margin-bottom: -8px; // Compensate for padding to maintain vertical alignment
294
+ -webkit-overflow-scrolling: touch; // Smooth scrolling on iOS
362
295
 
296
+ // Hide scrollbar in various browsers while maintaining functionality
363
297
  &::-webkit-scrollbar {
364
- display: none; // Chrome, Safari, Edge
298
+ height: 4px;
365
299
  }
300
+
301
+ &::-webkit-scrollbar-thumb {
302
+ background-color: t.alpha('on-surface', 0.2);
303
+ border-radius: 4px;
304
+ }
305
+
306
+ // Style for Firefox
307
+ scrollbar-width: thin;
308
+ scrollbar-color: t.alpha('on-surface', 0.2) transparent;
366
309
  }
367
310
 
368
311
  &--vertical {