mtrl 0.2.4 → 0.2.5

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,14 +1,17 @@
1
1
  {
2
2
  "name": "mtrl",
3
- "version": "0.2.4",
4
- "description": "A functional JavaScript component library with composable architecture based on Material Design 3",
3
+ "version": "0.2.5",
4
+ "description": "A functional TypeScript/JavaScript component library with composable architecture based on Material Design 3",
5
5
  "keywords": [
6
6
  "component",
7
7
  "library",
8
8
  "ui",
9
9
  "user interface",
10
+ "typescript",
10
11
  "functional",
11
- "composable"
12
+ "composable",
13
+ "material design 3",
14
+ "md3"
12
15
  ],
13
16
  "main": "index.js",
14
17
  "scripts": {
@@ -43,7 +43,7 @@ $component: '#{base.$prefix}-slider';
43
43
  background-color: t.color('primary');
44
44
  transform-origin: left center;
45
45
  // transition: transform 0.1s ease, width 0.1s ease, height 0.1s ease;
46
- border-radius: 5px;
46
+ border-radius: 2px;
47
47
  opacity: 0.24;
48
48
  z-index: 1;
49
49
 
@@ -72,7 +72,7 @@ $component: '#{base.$prefix}-slider';
72
72
  background-color: t.color('primary');
73
73
  transform-origin: left center;
74
74
  // transition: transform 0.1s ease, width 0.1s ease, height 0.1s ease, left 0.1s ease, bottom 0.1s ease;
75
- border-radius: 5px;
75
+ border-radius: 2px;
76
76
  z-index: 1;
77
77
 
78
78
  .#{$component}--secondary & {
@@ -97,7 +97,7 @@ $component: '#{base.$prefix}-slider';
97
97
  background-color: t.color('primary');
98
98
  transform-origin: left center;
99
99
  // transition: transform 0.1s ease, width 0.1s ease, height 0.1s ease, left 0.1s ease, bottom 0.1s ease;
100
- border-radius: 5px;
100
+ border-radius: 2px;
101
101
  width: 100%;
102
102
  z-index: 0;
103
103
 
@@ -125,38 +125,44 @@ $component: '#{base.$prefix}-slider';
125
125
  width: 4px;
126
126
  height: 4px;
127
127
  border-radius: 50%;
128
- background-color: t.color('primary');
129
128
  top: 50%;
130
129
  transform: translateY(-50%);
131
130
  z-index: 1;
132
131
 
133
132
  // Start dot
134
133
  &--start {
135
- left: 4px;
134
+ left: 6px;
135
+ // Color variants
136
+ background-color: t.color('on-primary');
137
+
138
+ .#{$component}--secondary & {
139
+ background-color: t.color('on-secondary');
140
+ }
141
+
142
+ .#{$component}--tertiary & {
143
+ background-color: t.color('on-tertiary');
144
+ }
136
145
  }
137
146
 
138
147
  // End dot
139
148
  &--end {
140
- right: 4px;
141
- }
142
-
143
- // Color variants
144
- .#{$component}--secondary & {
145
- background-color: t.color('secondary');
146
- }
147
-
148
- .#{$component}--tertiary & {
149
- background-color: t.color('tertiary');
150
- }
151
-
152
- .#{$component}--error & {
153
- background-color: t.color('error');
149
+ right: 6px;
150
+ // Color variants
151
+ background-color: t.color('primary');
152
+
153
+ .#{$component}--secondary & {
154
+ background-color: t.color('secondary');
155
+ }
156
+
157
+ .#{$component}--tertiary & {
158
+ background-color: t.color('tertiary');
159
+ }
154
160
  }
155
161
 
156
- // Disabled state
157
162
  .#{$component}--disabled & {
158
163
  opacity: 0.38;
159
164
  }
165
+
160
166
  }
161
167
 
162
168
  // Thumb - updated to MD3 style with T-shape
@@ -165,7 +171,7 @@ $component: '#{base.$prefix}-slider';
165
171
  top: 50%;
166
172
  transform: translate(-50%, -50%);
167
173
  cursor: pointer;
168
- z-index: 2;
174
+ z-index: 4;
169
175
  // transition: left 0.1s ease, bottom 0.1s ease;
170
176
  width: 16px;
171
177
  height: 100%;
@@ -182,7 +188,7 @@ $component: '#{base.$prefix}-slider';
182
188
  left: 50%;
183
189
  top: 50%;
184
190
  transform: translate(-50%, -50%);
185
- transition: background-color 0.15s ease;
191
+ transition: background-color 0.15s ease, width 0.15s ease;
186
192
 
187
193
  .#{$component}--secondary & {
188
194
  background-color: t.color('secondary');
@@ -207,6 +213,13 @@ $component: '#{base.$prefix}-slider';
207
213
  pointer-events: auto;
208
214
  }
209
215
 
216
+ // Make thumb line slimmer during dragging
217
+ .#{$component}--dragging & {
218
+ &::before {
219
+ width: 3px;
220
+ }
221
+ }
222
+
210
223
  // Hover state
211
224
  &:hover::before, &:hover::after {
212
225
  background-color: t.color('primary');
@@ -278,6 +291,17 @@ $component: '#{base.$prefix}-slider';
278
291
  }
279
292
  }
280
293
 
294
+ // Container for ticks in MD3 style
295
+ &-ticks-container {
296
+ position: absolute;
297
+ width: 100%;
298
+ height: 100%;
299
+ left: 0;
300
+ top: 0;
301
+ pointer-events: none;
302
+ z-index: 3;
303
+ }
304
+
281
305
  // Tick marks
282
306
  &-tick {
283
307
  position: absolute;
@@ -288,7 +312,7 @@ $component: '#{base.$prefix}-slider';
288
312
  top: 50%;
289
313
  transform: translate(-50%, -50%);
290
314
  pointer-events: none;
291
- opacity: 0.6;
315
+ opacity: 1;
292
316
 
293
317
  &:last-child, &:first-child {
294
318
  display: none
@@ -296,32 +320,35 @@ $component: '#{base.$prefix}-slider';
296
320
 
297
321
  // Active tick (filled)
298
322
  &--active {
299
- background-color: t.alpha('on-primary', 0.38);
323
+ // background-color: white;
324
+ background-color: t.color('on-primary');
300
325
 
301
326
  .#{$component}--secondary & {
302
- background-color: t.alpha('on-secondary', 0.38);
327
+ background-color: t.color('on-secondary');
303
328
  }
304
329
 
305
330
  .#{$component}--tertiary & {
306
- background-color: t.alpha('on-tertiary', 0.38);
331
+ background-color: t.color('on-tertiary');
332
+ }
333
+ }
334
+
335
+ // Inactive tick (unfilled)
336
+ &--inactive {
337
+ background-color: t.color('primary');
338
+
339
+ .#{$component}--secondary & {
340
+ background-color: t.color('secondary');
307
341
  }
308
342
 
309
- .#{$component}--error & {
310
- background-color: t.alpha('on-error', 0.38);
343
+ .#{$component}--tertiary & {
344
+ background-color: t.color('tertiary');
311
345
  }
312
346
  }
313
- }
314
-
315
- // Labels for tick marks
316
- &-label {
317
- position: absolute;
318
- font-size: 12px;
319
- color: t.color('on-surface-variant');
320
- top: 45px;
321
- transform: translateX(-50%);
322
- white-space: nowrap;
323
- pointer-events: none;
324
- font-weight: 500;
347
+
348
+ // Hidden tick
349
+ &--hidden {
350
+ opacity: 0
351
+ }
325
352
  }
326
353
 
327
354
  // Range slider styles (for two thumbs)
@@ -363,88 +390,6 @@ $component: '#{base.$prefix}-slider';
363
390
  }
364
391
  }
365
392
 
366
- // Vertical orientation
367
- &--vertical {
368
- width: 40px;
369
- height: 200px;
370
- flex-direction: column;
371
-
372
- .#{$component}-track {
373
- width: 16px;
374
- height: 100%;
375
- padding: 0;
376
- }
377
-
378
- .#{$component}-active-track {
379
- width: 100%;
380
- height: auto;
381
- transform-origin: bottom center;
382
- }
383
-
384
- .#{$component}-start-track {
385
- width: 100%;
386
- height: auto;
387
- transform-origin: bottom center;
388
- }
389
-
390
- .#{$component}-remaining-track {
391
- width: 100%;
392
- bottom: auto;
393
- top: 0;
394
- transform-origin: bottom center;
395
- }
396
-
397
- // Reorient thumb for vertical slider
398
- .#{$component}-thumb {
399
- &::before {
400
- width: 40px;
401
- height: 4px;
402
- }
403
-
404
- &::after {
405
- width: 16px;
406
- height: 16px;
407
- top: 50%;
408
- left: 0;
409
- transform: translate(0, -50%);
410
- }
411
-
412
- transform: translate(-50%, 50%);
413
- }
414
-
415
- // Dots for vertical orientation
416
- .#{$component}-dot {
417
- left: 50%;
418
- top: auto;
419
- transform: translateX(-50%);
420
-
421
- &--start {
422
- bottom: 0;
423
- }
424
-
425
- &--end {
426
- top: 0;
427
- }
428
- }
429
-
430
- .#{$component}-tick {
431
- left: 50%;
432
- transform: translate(-50%, 50%);
433
- }
434
-
435
- .#{$component}-label {
436
- top: auto;
437
- left: 35px;
438
- transform: translateY(50%);
439
- }
440
-
441
- .#{$component}-value {
442
- top: auto;
443
- left: -55px;
444
- transform: translateY(50%);
445
- }
446
- }
447
-
448
393
  // Discrete slider with steps
449
394
  &--discrete {
450
395
  .#{$component}-tick {
@@ -467,22 +412,6 @@ $component: '#{base.$prefix}-slider';
467
412
  height: 14px;
468
413
  }
469
414
  }
470
-
471
- &.#{$component}--vertical {
472
- width: 32px;
473
-
474
- .#{$component}-thumb {
475
- &::before {
476
- width: 34px;
477
- height: 3px;
478
- }
479
-
480
- &::after {
481
- width: 14px;
482
- height: 14px;
483
- }
484
- }
485
- }
486
415
  }
487
416
 
488
417
  &--large {
@@ -498,21 +427,10 @@ $component: '#{base.$prefix}-slider';
498
427
  height: 18px;
499
428
  }
500
429
  }
501
-
502
- &.#{$component}--vertical {
503
- width: 48px;
504
-
505
- .#{$component}-thumb {
506
- &::before {
507
- width: 48px;
508
- height: 4px;
509
- }
510
-
511
- &::after {
512
- width: 18px;
513
- height: 18px;
514
- }
515
- }
516
- }
430
+ }
431
+
432
+ // For dragging state
433
+ &--dragging {
434
+ // Additional styles when dragging will be applied to thumb::before
517
435
  }
518
436
  }
@@ -1,7 +1,10 @@
1
1
  // src/components/slider/api.ts
2
2
  import { SliderComponent, SliderEvent } from './types';
3
- import { SLIDER_COLORS, SLIDER_SIZES, SLIDER_ORIENTATIONS, SLIDER_EVENTS } from './constants';
3
+ import { SLIDER_COLORS, SLIDER_SIZES, SLIDER_EVENTS } from './constants';
4
4
 
5
+ /**
6
+ * API options interface - structured by feature area
7
+ */
5
8
  interface ApiOptions {
6
9
  slider: {
7
10
  setValue: (value: number, triggerEvent?: boolean) => any;
@@ -26,10 +29,7 @@ interface ApiOptions {
26
29
  getColor: () => string;
27
30
  setSize: (size: string) => void;
28
31
  getSize: () => string;
29
- setOrientation: (orientation: string) => void;
30
- getOrientation: () => string;
31
32
  showTicks: (show: boolean) => void;
32
- showTickLabels: (show: boolean | string[]) => void;
33
33
  showCurrentValue: (show: boolean) => void;
34
34
  };
35
35
  events: {
@@ -41,6 +41,9 @@ interface ApiOptions {
41
41
  };
42
42
  }
43
43
 
44
+ /**
45
+ * Component with elements
46
+ */
44
47
  interface ComponentWithElements {
45
48
  element: HTMLElement;
46
49
  }
@@ -53,46 +56,6 @@ interface ComponentWithElements {
53
56
  */
54
57
  export const withAPI = (options: ApiOptions) =>
55
58
  (component: ComponentWithElements): SliderComponent => {
56
- // Make sure options is defined with fallbacks
57
- const safeOptions: ApiOptions = options || {
58
- slider: {
59
- setValue: () => {},
60
- getValue: () => 0,
61
- setSecondValue: () => {},
62
- getSecondValue: () => null,
63
- setMin: () => {},
64
- getMin: () => 0,
65
- setMax: () => {},
66
- getMax: () => 100,
67
- setStep: () => {},
68
- getStep: () => 1,
69
- regenerateTicks: () => {}
70
- },
71
- disabled: {
72
- enable: () => {},
73
- disable: () => {},
74
- isDisabled: () => false
75
- },
76
- appearance: {
77
- setColor: () => {},
78
- getColor: () => 'primary',
79
- setSize: () => {},
80
- getSize: () => 'medium',
81
- setOrientation: () => {},
82
- getOrientation: () => 'horizontal',
83
- showTicks: () => {},
84
- showTickLabels: () => {},
85
- showCurrentValue: () => {}
86
- },
87
- events: {
88
- on: () => {},
89
- off: () => {}
90
- },
91
- lifecycle: {
92
- destroy: () => {}
93
- }
94
- };
95
-
96
59
  return {
97
60
  ...component as any,
98
61
 
@@ -103,7 +66,7 @@ export const withAPI = (options: ApiOptions) =>
103
66
  * @returns {SliderComponent} Slider component instance for chaining
104
67
  */
105
68
  setValue(value: number, triggerEvent: boolean = true) {
106
- safeOptions.slider.setValue(value, triggerEvent);
69
+ options.slider.setValue(value, triggerEvent);
107
70
  return this;
108
71
  },
109
72
 
@@ -112,7 +75,7 @@ export const withAPI = (options: ApiOptions) =>
112
75
  * @returns {number} Current slider value
113
76
  */
114
77
  getValue() {
115
- return safeOptions.slider.getValue();
78
+ return options.slider.getValue();
116
79
  },
117
80
 
118
81
  /**
@@ -122,7 +85,7 @@ export const withAPI = (options: ApiOptions) =>
122
85
  * @returns {SliderComponent} Slider component instance for chaining
123
86
  */
124
87
  setSecondValue(value: number, triggerEvent: boolean = true) {
125
- safeOptions.slider.setSecondValue(value, triggerEvent);
88
+ options.slider.setSecondValue(value, triggerEvent);
126
89
  return this;
127
90
  },
128
91
 
@@ -131,7 +94,7 @@ export const withAPI = (options: ApiOptions) =>
131
94
  * @returns {number|null} Current secondary value or null
132
95
  */
133
96
  getSecondValue() {
134
- return safeOptions.slider.getSecondValue();
97
+ return options.slider.getSecondValue();
135
98
  },
136
99
 
137
100
  /**
@@ -140,7 +103,7 @@ export const withAPI = (options: ApiOptions) =>
140
103
  * @returns {SliderComponent} Slider component instance for chaining
141
104
  */
142
105
  setMin(min: number) {
143
- safeOptions.slider.setMin(min);
106
+ options.slider.setMin(min);
144
107
  return this;
145
108
  },
146
109
 
@@ -149,7 +112,7 @@ export const withAPI = (options: ApiOptions) =>
149
112
  * @returns {number} Current minimum value
150
113
  */
151
114
  getMin() {
152
- return safeOptions.slider.getMin();
115
+ return options.slider.getMin();
153
116
  },
154
117
 
155
118
  /**
@@ -158,7 +121,7 @@ export const withAPI = (options: ApiOptions) =>
158
121
  * @returns {SliderComponent} Slider component instance for chaining
159
122
  */
160
123
  setMax(max: number) {
161
- safeOptions.slider.setMax(max);
124
+ options.slider.setMax(max);
162
125
  return this;
163
126
  },
164
127
 
@@ -167,7 +130,7 @@ export const withAPI = (options: ApiOptions) =>
167
130
  * @returns {number} Current maximum value
168
131
  */
169
132
  getMax() {
170
- return safeOptions.slider.getMax();
133
+ return options.slider.getMax();
171
134
  },
172
135
 
173
136
  /**
@@ -176,7 +139,7 @@ export const withAPI = (options: ApiOptions) =>
176
139
  * @returns {SliderComponent} Slider component instance for chaining
177
140
  */
178
141
  setStep(step: number) {
179
- safeOptions.slider.setStep(step);
142
+ options.slider.setStep(step);
180
143
  return this;
181
144
  },
182
145
 
@@ -185,7 +148,7 @@ export const withAPI = (options: ApiOptions) =>
185
148
  * @returns {number} Current step size
186
149
  */
187
150
  getStep() {
188
- return safeOptions.slider.getStep();
151
+ return options.slider.getStep();
189
152
  },
190
153
 
191
154
  /**
@@ -193,7 +156,7 @@ export const withAPI = (options: ApiOptions) =>
193
156
  * @returns {SliderComponent} Slider component instance for chaining
194
157
  */
195
158
  enable() {
196
- safeOptions.disabled.enable();
159
+ options.disabled.enable();
197
160
  return this;
198
161
  },
199
162
 
@@ -202,7 +165,7 @@ export const withAPI = (options: ApiOptions) =>
202
165
  * @returns {SliderComponent} Slider component instance for chaining
203
166
  */
204
167
  disable() {
205
- safeOptions.disabled.disable();
168
+ options.disabled.disable();
206
169
  return this;
207
170
  },
208
171
 
@@ -211,7 +174,7 @@ export const withAPI = (options: ApiOptions) =>
211
174
  * @returns {boolean} True if slider is disabled
212
175
  */
213
176
  isDisabled() {
214
- return safeOptions.disabled.isDisabled();
177
+ return options.disabled.isDisabled();
215
178
  },
216
179
 
217
180
  /**
@@ -219,8 +182,8 @@ export const withAPI = (options: ApiOptions) =>
219
182
  * @param {string} color - Color variant
220
183
  * @returns {SliderComponent} Slider component instance for chaining
221
184
  */
222
- setColor(color: keyof typeof SLIDER_COLORS | SLIDER_COLORS) {
223
- safeOptions.appearance.setColor(color);
185
+ setColor(color: keyof typeof SLIDER_COLORS | typeof SLIDER_COLORS[keyof typeof SLIDER_COLORS]) {
186
+ options.appearance.setColor(color);
224
187
  return this;
225
188
  },
226
189
 
@@ -229,7 +192,7 @@ export const withAPI = (options: ApiOptions) =>
229
192
  * @returns {string} Current color name
230
193
  */
231
194
  getColor() {
232
- return safeOptions.appearance.getColor();
195
+ return options.appearance.getColor();
233
196
  },
234
197
 
235
198
  /**
@@ -237,8 +200,8 @@ export const withAPI = (options: ApiOptions) =>
237
200
  * @param {string} size - Size variant
238
201
  * @returns {SliderComponent} Slider component instance for chaining
239
202
  */
240
- setSize(size: keyof typeof SLIDER_SIZES | SLIDER_SIZES) {
241
- safeOptions.appearance.setSize(size);
203
+ setSize(size: keyof typeof SLIDER_SIZES | typeof SLIDER_SIZES[keyof typeof SLIDER_SIZES]) {
204
+ options.appearance.setSize(size);
242
205
  return this;
243
206
  },
244
207
 
@@ -247,25 +210,7 @@ export const withAPI = (options: ApiOptions) =>
247
210
  * @returns {string} Current size name
248
211
  */
249
212
  getSize() {
250
- return safeOptions.appearance.getSize();
251
- },
252
-
253
- /**
254
- * Sets slider orientation
255
- * @param {string} orientation - Orientation variant
256
- * @returns {SliderComponent} Slider component instance for chaining
257
- */
258
- setOrientation(orientation: keyof typeof SLIDER_ORIENTATIONS | SLIDER_ORIENTATIONS) {
259
- safeOptions.appearance.setOrientation(orientation);
260
- return this;
261
- },
262
-
263
- /**
264
- * Gets slider orientation
265
- * @returns {string} Current orientation name
266
- */
267
- getOrientation() {
268
- return safeOptions.appearance.getOrientation();
213
+ return options.appearance.getSize();
269
214
  },
270
215
 
271
216
  /**
@@ -274,17 +219,7 @@ export const withAPI = (options: ApiOptions) =>
274
219
  * @returns {SliderComponent} Slider component instance for chaining
275
220
  */
276
221
  showTicks(show: boolean) {
277
- safeOptions.appearance.showTicks(show);
278
- return this;
279
- },
280
-
281
- /**
282
- * Shows or hides tick labels
283
- * @param {boolean|string[]} show - Whether to show labels or array of label texts
284
- * @returns {SliderComponent} Slider component instance for chaining
285
- */
286
- showTickLabels(show: boolean | string[]) {
287
- safeOptions.appearance.showTickLabels(show);
222
+ options.appearance.showTicks(show);
288
223
  return this;
289
224
  },
290
225
 
@@ -294,7 +229,7 @@ export const withAPI = (options: ApiOptions) =>
294
229
  * @returns {SliderComponent} Slider component instance for chaining
295
230
  */
296
231
  showCurrentValue(show: boolean) {
297
- safeOptions.appearance.showCurrentValue(show);
232
+ options.appearance.showCurrentValue(show);
298
233
  return this;
299
234
  },
300
235
 
@@ -304,9 +239,9 @@ export const withAPI = (options: ApiOptions) =>
304
239
  * @param {Function} handler - Event handler
305
240
  * @returns {SliderComponent} Slider component instance for chaining
306
241
  */
307
- on(event: keyof typeof SLIDER_EVENTS | SLIDER_EVENTS, handler: (event: SliderEvent) => void) {
308
- if (safeOptions.events && typeof safeOptions.events.on === 'function') {
309
- safeOptions.events.on(event, handler);
242
+ on(event: keyof typeof SLIDER_EVENTS | typeof SLIDER_EVENTS[keyof typeof SLIDER_EVENTS], handler: (event: SliderEvent) => void) {
243
+ if (options.events && typeof options.events.on === 'function') {
244
+ options.events.on(event, handler);
310
245
  }
311
246
  return this;
312
247
  },
@@ -317,9 +252,9 @@ export const withAPI = (options: ApiOptions) =>
317
252
  * @param {Function} handler - Event handler
318
253
  * @returns {SliderComponent} Slider component instance for chaining
319
254
  */
320
- off(event: keyof typeof SLIDER_EVENTS | SLIDER_EVENTS, handler: (event: SliderEvent) => void) {
321
- if (safeOptions.events && typeof safeOptions.events.off === 'function') {
322
- safeOptions.events.off(event, handler);
255
+ off(event: keyof typeof SLIDER_EVENTS | typeof SLIDER_EVENTS[keyof typeof SLIDER_EVENTS], handler: (event: SliderEvent) => void) {
256
+ if (options.events && typeof options.events.off === 'function') {
257
+ options.events.off(event, handler);
323
258
  }
324
259
  return this;
325
260
  },
@@ -328,8 +263,8 @@ export const withAPI = (options: ApiOptions) =>
328
263
  * Destroys the slider component and cleans up resources
329
264
  */
330
265
  destroy() {
331
- if (safeOptions.lifecycle && typeof safeOptions.lifecycle.destroy === 'function') {
332
- safeOptions.lifecycle.destroy();
266
+ if (options.lifecycle && typeof options.lifecycle.destroy === 'function') {
267
+ options.lifecycle.destroy();
333
268
  }
334
269
  }
335
270
  };