mtrl 0.2.7 → 0.2.9

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 (190) hide show
  1. package/index.ts +2 -0
  2. package/package.json +14 -3
  3. package/src/components/badge/api.ts +23 -14
  4. package/src/components/badge/badge.ts +2 -2
  5. package/src/components/badge/config.ts +10 -11
  6. package/src/components/badge/features.ts +15 -10
  7. package/src/components/badge/index.ts +27 -2
  8. package/src/components/badge/types.ts +28 -8
  9. package/src/components/bottom-app-bar/bottom-app-bar.ts +2 -44
  10. package/src/components/bottom-app-bar/config.ts +1 -45
  11. package/src/components/bottom-app-bar/index.ts +7 -1
  12. package/src/components/bottom-app-bar/types.ts +7 -1
  13. package/src/components/button/button.ts +0 -1
  14. package/src/components/button/config.ts +1 -2
  15. package/src/components/button/index.ts +10 -2
  16. package/src/components/button/types.ts +14 -2
  17. package/src/components/card/config.ts +17 -9
  18. package/src/components/card/content.ts +8 -10
  19. package/src/components/card/features.ts +4 -6
  20. package/src/components/card/index.ts +29 -2
  21. package/src/components/card/types.ts +6 -23
  22. package/src/components/checkbox/config.ts +3 -4
  23. package/src/components/checkbox/index.ts +1 -2
  24. package/src/components/checkbox/types.ts +12 -3
  25. package/src/components/chip/api.ts +170 -221
  26. package/src/components/chip/chip.ts +34 -302
  27. package/src/components/chip/config.ts +1 -2
  28. package/src/components/chip/index.ts +10 -2
  29. package/src/components/chip/types.ts +224 -35
  30. package/src/components/datepicker/api.ts +18 -25
  31. package/src/components/datepicker/config.ts +9 -12
  32. package/src/components/datepicker/datepicker.ts +7 -12
  33. package/src/components/datepicker/index.ts +10 -7
  34. package/src/components/datepicker/render.ts +16 -18
  35. package/src/components/datepicker/types.ts +164 -35
  36. package/src/components/datepicker/utils.ts +1 -2
  37. package/src/components/dialog/api.ts +7 -8
  38. package/src/components/dialog/config.ts +3 -4
  39. package/src/components/dialog/features.ts +56 -22
  40. package/src/components/dialog/index.ts +38 -8
  41. package/src/components/dialog/types.ts +33 -10
  42. package/src/components/divider/index.ts +5 -1
  43. package/src/components/extended-fab/config.ts +6 -2
  44. package/src/components/extended-fab/index.ts +7 -2
  45. package/src/components/extended-fab/types.ts +21 -4
  46. package/src/components/fab/config.ts +3 -4
  47. package/src/components/fab/fab.ts +1 -1
  48. package/src/components/fab/index.ts +7 -2
  49. package/src/components/fab/types.ts +21 -4
  50. package/src/components/list/config.ts +4 -5
  51. package/src/components/list/features.ts +6 -7
  52. package/src/components/list/index.ts +7 -9
  53. package/src/components/list/list-item.ts +12 -13
  54. package/src/components/list/types.ts +50 -5
  55. package/src/components/list/utils.ts +30 -3
  56. package/src/components/menu/features/items-manager.ts +9 -9
  57. package/src/components/menu/features/positioning.ts +7 -7
  58. package/src/components/menu/features/visibility.ts +7 -7
  59. package/src/components/menu/index.ts +7 -9
  60. package/src/components/menu/menu-item.ts +6 -6
  61. package/src/components/menu/menu.ts +22 -0
  62. package/src/components/menu/types.ts +29 -10
  63. package/src/components/menu/utils.ts +67 -0
  64. package/src/components/navigation/api.ts +131 -96
  65. package/src/components/navigation/config.ts +22 -10
  66. package/src/components/navigation/features/controller.ts +273 -0
  67. package/src/components/navigation/features/items.ts +160 -87
  68. package/src/components/navigation/index.ts +0 -6
  69. package/src/components/navigation/nav-item.ts +12 -24
  70. package/src/components/navigation/navigation.ts +21 -8
  71. package/src/components/navigation/system-types.ts +124 -0
  72. package/src/components/navigation/system.ts +776 -0
  73. package/src/components/navigation/types.ts +228 -203
  74. package/src/components/progress/api.ts +2 -3
  75. package/src/components/progress/config.ts +2 -3
  76. package/src/components/progress/index.ts +0 -1
  77. package/src/components/progress/progress.ts +1 -2
  78. package/src/components/progress/types.ts +186 -33
  79. package/src/components/radios/config.ts +1 -1
  80. package/src/components/radios/index.ts +0 -1
  81. package/src/components/radios/types.ts +0 -7
  82. package/src/components/search/config.ts +1 -2
  83. package/src/components/search/features/search.ts +14 -15
  84. package/src/components/search/features/states.ts +5 -1
  85. package/src/components/search/features/structure.ts +3 -4
  86. package/src/components/search/index.ts +0 -3
  87. package/src/components/search/types.ts +18 -6
  88. package/src/components/segmented-button/config.ts +20 -7
  89. package/src/components/segmented-button/segment.ts +6 -7
  90. package/src/components/segmented-button/segmented-button.ts +4 -5
  91. package/src/components/segmented-button/types.ts +37 -2
  92. package/src/components/slider/config.ts +20 -2
  93. package/src/components/slider/features/controller.ts +761 -0
  94. package/src/components/slider/features/handlers.ts +18 -15
  95. package/src/components/slider/features/index.ts +3 -2
  96. package/src/components/slider/features/range.ts +104 -0
  97. package/src/components/slider/slider.ts +34 -14
  98. package/src/components/slider/structure.ts +152 -0
  99. package/src/components/slider/types.ts +34 -8
  100. package/src/components/snackbar/config.ts +2 -3
  101. package/src/components/snackbar/constants.ts +0 -32
  102. package/src/components/snackbar/index.ts +0 -1
  103. package/src/components/snackbar/position.ts +9 -1
  104. package/src/components/snackbar/types.ts +122 -46
  105. package/src/components/switch/config.ts +2 -3
  106. package/src/components/switch/index.ts +0 -1
  107. package/src/components/switch/types.ts +3 -2
  108. package/src/components/tabs/config.ts +3 -4
  109. package/src/components/tabs/index.ts +0 -15
  110. package/src/components/tabs/tab-api.ts +12 -4
  111. package/src/components/tabs/tab.ts +18 -6
  112. package/src/components/tabs/types.ts +13 -3
  113. package/src/components/textfield/api.ts +53 -0
  114. package/src/components/textfield/config.ts +2 -3
  115. package/src/components/textfield/features.ts +322 -0
  116. package/src/components/textfield/index.ts +0 -1
  117. package/src/components/textfield/textfield.ts +8 -0
  118. package/src/components/textfield/types.ts +29 -6
  119. package/src/components/timepicker/api.ts +1 -1
  120. package/src/components/timepicker/clockdial.ts +2 -5
  121. package/src/components/timepicker/config.ts +102 -4
  122. package/src/components/timepicker/index.ts +1 -6
  123. package/src/components/timepicker/render.ts +1 -1
  124. package/src/components/timepicker/timepicker.ts +1 -1
  125. package/src/components/tooltip/api.ts +1 -1
  126. package/src/components/tooltip/config.ts +27 -6
  127. package/src/components/tooltip/index.ts +0 -1
  128. package/src/components/tooltip/types.ts +13 -3
  129. package/src/core/compose/features/textinput.ts +15 -2
  130. package/src/core/compose/features/textlabel.ts +0 -3
  131. package/src/core/composition/features/dom.ts +33 -0
  132. package/src/core/composition/features/icon.ts +131 -0
  133. package/src/core/composition/features/index.ts +11 -0
  134. package/src/core/composition/features/label.ts +156 -0
  135. package/src/core/composition/features/structure.ts +22 -0
  136. package/src/core/composition/index.ts +26 -0
  137. package/src/core/index.ts +1 -1
  138. package/src/core/structure.ts +288 -0
  139. package/src/index.ts +1 -0
  140. package/src/styles/components/_navigation-mobile.scss +244 -0
  141. package/src/styles/components/_navigation-system.scss +151 -0
  142. package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +1 -1
  143. package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +314 -72
  144. package/src/styles/main.scss +98 -49
  145. package/src/components/badge/constants.ts +0 -40
  146. package/src/components/button/constants.ts +0 -11
  147. package/src/components/card/constants.ts +0 -84
  148. package/src/components/datepicker/constants.ts +0 -98
  149. package/src/components/dialog/constants.ts +0 -32
  150. package/src/components/extended-fab/constants.ts +0 -36
  151. package/src/components/fab/constants.ts +0 -41
  152. package/src/components/menu/constants.ts +0 -154
  153. package/src/components/navigation/constants.ts +0 -200
  154. package/src/components/progress/constants.ts +0 -29
  155. package/src/components/search/constants.ts +0 -21
  156. package/src/components/segmented-button/constants.ts +0 -42
  157. package/src/components/slider/features/slider.ts +0 -318
  158. package/src/components/slider/features/structure.ts +0 -181
  159. package/src/components/slider/features/ui.ts +0 -388
  160. package/src/components/switch/constants.ts +0 -80
  161. package/src/components/tabs/constants.ts +0 -89
  162. package/src/components/textfield/constants.ts +0 -100
  163. package/src/components/timepicker/constants.ts +0 -138
  164. /package/src/{components/badge/_styles.scss → styles/components/_badge.scss} +0 -0
  165. /package/src/{components/bottom-app-bar/_styles.scss → styles/components/_bottom-app-bar.scss} +0 -0
  166. /package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -0
  167. /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
  168. /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
  169. /package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -0
  170. /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
  171. /package/src/{components/datepicker/_styles.scss → styles/components/_datepicker.scss} +0 -0
  172. /package/src/{components/dialog/_styles.scss → styles/components/_dialog.scss} +0 -0
  173. /package/src/{components/divider/_styles.scss → styles/components/_divider.scss} +0 -0
  174. /package/src/{components/extended-fab/_styles.scss → styles/components/_extended-fab.scss} +0 -0
  175. /package/src/{components/fab/_styles.scss → styles/components/_fab.scss} +0 -0
  176. /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
  177. /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
  178. /package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +0 -0
  179. /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
  180. /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
  181. /package/src/{components/search/_styles.scss → styles/components/_search.scss} +0 -0
  182. /package/src/{components/segmented-button/_styles.scss → styles/components/_segmented-button.scss} +0 -0
  183. /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
  184. /package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +0 -0
  185. /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
  186. /package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -0
  187. /package/src/{components/timepicker/_styles.scss → styles/components/_timepicker.scss} +0 -0
  188. /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
  189. /package/src/{components/top-app-bar/_styles.scss → styles/components/_top-app-bar.scss} +0 -0
  190. /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
@@ -7,20 +7,23 @@ import { SliderConfig, SliderEvent } from '../types';
7
7
  *
8
8
  * @param config Slider configuration
9
9
  * @param state Slider state object
10
- * @param uiHelpers UI helper methods
10
+ * @param uiRenderer UI renderer interface from controller
11
11
  * @param eventHelpers Event helper methods
12
12
  * @returns Event handlers for all slider interactions
13
13
  */
14
- export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelpers) => {
14
+ export const createHandlers = (config: SliderConfig, state, uiRenderer, eventHelpers) => {
15
15
  // Get required elements from structure (with fallbacks)
16
+ const components = state.component?.components || {};
17
+
18
+ // Extract needed components
16
19
  const {
17
20
  container = null,
18
- track = null,
19
- handle = null,
21
+ handle = null,
22
+ track = null,
20
23
  valueBubble = null,
21
24
  secondHandle = null,
22
25
  secondValueBubble = null
23
- } = state.component?.structure || {};
26
+ } = components;
24
27
 
25
28
  // Get required helper methods (with fallbacks)
26
29
  const {
@@ -28,8 +31,8 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
28
31
  roundToStep = value => value,
29
32
  clamp = (value, min, max) => value,
30
33
  showValueBubble = () => {},
31
- updateUi = () => {}
32
- } = uiHelpers;
34
+ render = () => {}
35
+ } = uiRenderer;
33
36
 
34
37
  const { triggerEvent = () => ({ defaultPrevented: false }) } = eventHelpers;
35
38
 
@@ -127,7 +130,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
127
130
  document.addEventListener('touchmove', handleMouseMove, { passive: false });
128
131
  document.addEventListener('touchend', handleMouseUp);
129
132
 
130
- updateUi();
133
+ render();
131
134
  triggerEvent(SLIDER_EVENTS.START, e);
132
135
  };
133
136
 
@@ -169,7 +172,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
169
172
  }
170
173
 
171
174
  // Update UI and trigger events
172
- updateUi();
175
+ render();
173
176
  triggerEvent(SLIDER_EVENTS.INPUT, e);
174
177
  triggerEvent(SLIDER_EVENTS.CHANGE, e);
175
178
  } catch (error) {
@@ -244,7 +247,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
244
247
  state.value = newValue;
245
248
  }
246
249
 
247
- updateUi();
250
+ render();
248
251
  triggerEvent(SLIDER_EVENTS.INPUT, e);
249
252
  } catch (error) {
250
253
  console.warn('Error during slider drag:', error);
@@ -274,7 +277,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
274
277
 
275
278
  // Reset active handle and update UI
276
279
  state.activeHandle = null;
277
- updateUi();
280
+ render();
278
281
 
279
282
  // Trigger events
280
283
  triggerEvent(SLIDER_EVENTS.CHANGE, e);
@@ -355,7 +358,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
355
358
  }
356
359
 
357
360
  // Update UI and trigger events
358
- updateUi();
361
+ render();
359
362
  triggerEvent(SLIDER_EVENTS.INPUT, e);
360
363
  triggerEvent(SLIDER_EVENTS.CHANGE, e);
361
364
  };
@@ -406,7 +409,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
406
409
  * Set up all event listeners
407
410
  */
408
411
  const setupEventListeners = () => {
409
- if (!state.component || !state.component.structure) {
412
+ if (!state.component || !state.component.components) {
410
413
  console.warn('Cannot set up event listeners: missing component structure');
411
414
  return;
412
415
  }
@@ -436,7 +439,7 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
436
439
  * Clean up all event listeners
437
440
  */
438
441
  const cleanupEventListeners = () => {
439
- if (!state.component || !state.component.structure) return;
442
+ if (!state.component || !state.component.components) return;
440
443
 
441
444
  // Clean up container listeners
442
445
  if (container) {
@@ -492,4 +495,4 @@ export const createHandlers = (config: SliderConfig, state, uiHelpers, eventHelp
492
495
  hideAllBubbles,
493
496
  clearKeyboardFocus
494
497
  };
495
- };
498
+ }
@@ -1,4 +1,5 @@
1
1
  // src/components/slider/features/index.ts
2
- export { withStructure } from './structure';
2
+ // Export slider-specific features
3
+ export { withRange } from './range';
3
4
  export { withStates } from './states';
4
- export { withSlider } from './slider';
5
+ export { withController } from './controller';
@@ -0,0 +1,104 @@
1
+ // src/components/slider/features/range.ts
2
+ import { SliderConfig } from '../types';
3
+ import { createElement } from '../../../core/dom/create';
4
+
5
+ /**
6
+ * Enhances structure definition with range slider elements
7
+ *
8
+ * @param config Slider configuration
9
+ * @returns Component enhancer that adds range slider to structure
10
+ */
11
+ export const withRange = (config: SliderConfig) => component => {
12
+ // If not a range slider or missing structure definition, return unmodified
13
+ if (!config.range || !config.secondValue || !component.structureDefinition) {
14
+ return component;
15
+ }
16
+
17
+ try {
18
+ // Calculate values for second handle
19
+ const min = config.min || 0;
20
+ const max = config.max || 100;
21
+ const secondValue = config.secondValue;
22
+ const secondValuePercent = ((secondValue - min) / (max - min)) * 100;
23
+ const formatter = config.valueFormatter || (val => val.toString());
24
+ const isDisabled = config.disabled === true;
25
+ const getClass = component.getClass;
26
+
27
+ // Clone the structure definition (deep copy)
28
+ const structureDefinition = JSON.parse(JSON.stringify(component.structureDefinition));
29
+
30
+ // Add range class to root element
31
+ const rootClasses = structureDefinition.element.options.className || [];
32
+ if (Array.isArray(rootClasses)) {
33
+ rootClasses.push(getClass('slider--range'));
34
+ } else {
35
+ structureDefinition.element.options.className = `${rootClasses} ${getClass('slider--range')}`.trim();
36
+ }
37
+
38
+ // Add start track segment to track children
39
+ const trackChildren = structureDefinition.element.children.container.children.track.children;
40
+ trackChildren.startTrack = {
41
+ name: 'startTrack',
42
+ creator: createElement,
43
+ options: {
44
+ tag: 'div',
45
+ className: getClass('slider-start-track'),
46
+ style: {
47
+ width: '0%'
48
+ }
49
+ }
50
+ };
51
+
52
+ // Add second handle to container children
53
+ const containerChildren = structureDefinition.element.children.container.children;
54
+ containerChildren.secondHandle = {
55
+ name: 'secondHandle',
56
+ creator: createElement,
57
+ options: {
58
+ tag: 'div',
59
+ className: getClass('slider-handle'),
60
+ attrs: {
61
+ role: 'slider',
62
+ 'aria-valuemin': String(min),
63
+ 'aria-valuemax': String(max),
64
+ 'aria-valuenow': String(secondValue),
65
+ 'aria-orientation': 'horizontal',
66
+ tabindex: isDisabled ? '-1' : '0',
67
+ 'aria-disabled': isDisabled ? 'true' : 'false',
68
+ 'data-value': String(secondValue),
69
+ 'data-handle-index': '1'
70
+ },
71
+ style: {
72
+ left: `${secondValuePercent}%`
73
+ }
74
+ }
75
+ };
76
+
77
+ // Add second value bubble to container children
78
+ containerChildren.secondValueBubble = {
79
+ name: 'secondValueBubble',
80
+ creator: createElement,
81
+ options: {
82
+ tag: 'div',
83
+ className: getClass('slider-value'),
84
+ attrs: {
85
+ 'aria-hidden': 'true',
86
+ 'data-handle-index': '1'
87
+ },
88
+ text: formatter(secondValue),
89
+ style: {
90
+ left: `${secondValuePercent}%`
91
+ }
92
+ }
93
+ };
94
+
95
+ // Return component with updated structure definition
96
+ return {
97
+ ...component,
98
+ structureDefinition
99
+ };
100
+ } catch (error) {
101
+ console.warn('Error enhancing structure with range functionality:', error);
102
+ return component;
103
+ }
104
+ };
@@ -1,42 +1,62 @@
1
1
  // src/components/slider/slider.ts
2
2
  import { pipe } from '../../core/compose/pipe';
3
- import { createBase, withElement } from '../../core/compose/component';
4
- import { withEvents, withLifecycle, withTextLabel, withIcon } from '../../core/compose/features';
5
- import { withStructure, withSlider } from './features';
6
- import { withStates } from './features/states';
3
+ import { createBase } from '../../core/compose/component';
4
+ import { withEvents, withLifecycle } from '../../core/compose/features';
5
+ import { withStructure, withIcon, withLabel, withDom } from '../../core/composition/features';
6
+ import {
7
+ withRange,
8
+ withStates,
9
+ withController
10
+ } from './features';
7
11
  import { withAPI } from './api';
8
12
  import { SliderConfig, SliderComponent } from './types';
9
- import { createBaseConfig, getElementConfig, getApiConfig } from './config';
10
-
13
+ import { createBaseConfig, getApiConfig } from './config';
11
14
  /**
12
15
  * Creates a new Slider component
16
+ *
17
+ * Slider follows a clear architectural pattern:
18
+ * 1. Structure definition - Describes the DOM structure declaratively
19
+ * 2. Feature enhancement - Adds specific capabilities (range, icons, labels)
20
+ * 3. DOM creation - Turns the structure into actual DOM elements
21
+ * 4. State management - Handles visual states and appearance
22
+ * 5. Controller - Manages behavior, events, and UI rendering
23
+ * 6. Lifecycle - Handles component lifecycle events
24
+ * 7. Public API - Exposes a clean, consistent API
25
+ *
13
26
  * @param {SliderConfig} config - Slider configuration object
14
27
  * @returns {SliderComponent} Slider component instance
15
28
  */
16
29
  const createSlider = (config: SliderConfig = {}): SliderComponent => {
30
+ // Process configuration with defaults
17
31
  const baseConfig = createBaseConfig(config);
18
32
 
19
33
  try {
20
- // Create the component with all required features
34
+ // Create the component by composing features in a specific order
21
35
  const component = pipe(
36
+ // Base component with event system
22
37
  createBase,
23
38
  withEvents(),
24
- withElement(getElementConfig(baseConfig)),
25
- withIcon(baseConfig),
26
- withTextLabel(baseConfig),
27
39
  withStructure(baseConfig),
40
+ withIcon(baseConfig),
41
+ withLabel(baseConfig),
42
+ withRange(baseConfig),
43
+
44
+ // Now create the actual DOM elements from the complete structure
45
+ withDom(),
46
+
47
+ // Add state management and behavior
28
48
  withStates(baseConfig),
29
- withSlider(baseConfig),
49
+ withController(baseConfig),
30
50
  withLifecycle()
31
51
  )(baseConfig);
32
52
 
33
- // Generate the API configuration
53
+ // Generate the API configuration based on the enhanced component
34
54
  const apiOptions = getApiConfig(component);
35
55
 
36
- // Apply the API layer
56
+ // Apply the public API layer
37
57
  const slider = withAPI(apiOptions)(component);
38
58
 
39
- // Register event handlers from config
59
+ // Register event handlers from config for convenience
40
60
  if (baseConfig.on && typeof slider.on === 'function') {
41
61
  Object.entries(baseConfig.on).forEach(([event, handler]) => {
42
62
  if (typeof handler === 'function') {
@@ -0,0 +1,152 @@
1
+ // src/components/slider/structure.ts
2
+ import { SliderConfig } from './types';
3
+
4
+ /**
5
+ * Creates the base slider structure definition
6
+ *
7
+ * @param component Component for class name generation
8
+ * @param config Slider configuration
9
+ * @returns Structure definition object
10
+ */
11
+ export function createSliderDefinition(component, config: SliderConfig) {
12
+ // Get prefixed class names
13
+ const getClass = (className) => component.getClass(className);
14
+
15
+ // Set default values
16
+ const min = config.min || 0;
17
+ const max = config.max || 100;
18
+ const value = config.value !== undefined ? config.value : min;
19
+ const isDisabled = config.disabled === true;
20
+ const formatter = config.valueFormatter || (val => val.toString());
21
+
22
+ // Calculate initial position
23
+ const valuePercent = ((value - min) / (max - min)) * 100;
24
+
25
+ // Return base structure definition formatted for createStructure
26
+ return {
27
+ element: {
28
+ options: {
29
+ tag: 'div',
30
+ className: [getClass('slider'), config.class].filter(Boolean),
31
+ attrs: {
32
+ tabindex: '-1',
33
+ role: 'none',
34
+ 'aria-disabled': isDisabled ? 'true' : 'false'
35
+ }
36
+ },
37
+ children: {
38
+ // Container with all slider elements
39
+ container: {
40
+ options: {
41
+ tag: 'div',
42
+ className: getClass('slider-container')
43
+ },
44
+ children: {
45
+ // Track with segments
46
+ track: {
47
+ options: {
48
+ tag: 'div',
49
+ className: getClass('slider-track')
50
+ },
51
+ children: {
52
+ activeTrack: {
53
+ options: {
54
+ tag: 'div',
55
+ className: getClass('slider-active-track'),
56
+ style: {
57
+ width: `${valuePercent}%`
58
+ }
59
+ }
60
+ },
61
+ startTrack: {
62
+ options: {
63
+ tag: 'div',
64
+ className: getClass('slider-start-track'),
65
+ style: {
66
+ display: 'none', // Initially hidden for single slider
67
+ width: '0%'
68
+ }
69
+ }
70
+ },
71
+ remainingTrack: {
72
+ options: {
73
+ tag: 'div',
74
+ className: getClass('slider-remaining-track'),
75
+ style: {
76
+ width: `${100 - valuePercent}%`
77
+ }
78
+ }
79
+ }
80
+ }
81
+ },
82
+
83
+ // Ticks container
84
+ ticksContainer: {
85
+ options: {
86
+ tag: 'div',
87
+ className: getClass('slider-ticks-container')
88
+ }
89
+ },
90
+
91
+ // Dots for ends
92
+ startDot: {
93
+ options: {
94
+ tag: 'div',
95
+ className: [
96
+ getClass('slider-dot'),
97
+ getClass('slider-dot--start')
98
+ ]
99
+ }
100
+ },
101
+ endDot: {
102
+ options: {
103
+ tag: 'div',
104
+ className: [
105
+ getClass('slider-dot'),
106
+ getClass('slider-dot--end')
107
+ ]
108
+ }
109
+ },
110
+
111
+ // Main handle
112
+ handle: {
113
+ options: {
114
+ tag: 'div',
115
+ className: getClass('slider-handle'),
116
+ attrs: {
117
+ role: 'slider',
118
+ 'aria-valuemin': String(min),
119
+ 'aria-valuemax': String(max),
120
+ 'aria-valuenow': String(value),
121
+ 'aria-orientation': 'horizontal',
122
+ tabindex: isDisabled ? '-1' : '0',
123
+ 'aria-disabled': isDisabled ? 'true' : 'false',
124
+ 'data-value': String(value),
125
+ 'data-handle-index': '0'
126
+ },
127
+ style: {
128
+ left: `${valuePercent}%`
129
+ }
130
+ }
131
+ },
132
+ // Main value bubble
133
+ valueBubble: {
134
+ options: {
135
+ tag: 'div',
136
+ className: getClass('slider-value'),
137
+ attrs: {
138
+ 'aria-hidden': 'true',
139
+ 'data-handle-index': '0'
140
+ },
141
+ text: formatter(value),
142
+ style: {
143
+ left: `${valuePercent}%`
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ };
152
+ }
@@ -1,6 +1,24 @@
1
1
  // src/components/slider/types.ts
2
- import { SLIDER_COLORS, SLIDER_SIZES, SLIDER_EVENTS } from './constants';
3
2
 
3
+ /**
4
+ * Available slider color variants
5
+ */
6
+ export type SliderColor = 'primary' | 'secondary' | 'tertiary' | 'error';
7
+
8
+ /**
9
+ * Available slider size variants
10
+ */
11
+ export type SliderSize = 'small' | 'medium' | 'large';
12
+
13
+ /**
14
+ * Available slider event types
15
+ */
16
+ export type SliderEventType = 'change' | 'input' | 'focus' | 'blur' | 'start' | 'end';
17
+
18
+ /**
19
+ * Configuration options for the slider component
20
+ * @interface SliderConfig
21
+ */
4
22
  export interface SliderConfig {
5
23
  /** Minimum value of the slider */
6
24
  min?: number;
@@ -21,10 +39,10 @@ export interface SliderConfig {
21
39
  disabled?: boolean;
22
40
 
23
41
  /** Color variant of the slider */
24
- color?: keyof typeof SLIDER_COLORS | typeof SLIDER_COLORS[keyof typeof SLIDER_COLORS];
42
+ color?: SliderColor;
25
43
 
26
44
  /** Size variant of the slider */
27
- size?: keyof typeof SLIDER_SIZES | typeof SLIDER_SIZES[keyof typeof SLIDER_SIZES];
45
+ size?: SliderSize;
28
46
 
29
47
  /** Whether to show tick marks */
30
48
  ticks?: boolean;
@@ -58,10 +76,14 @@ export interface SliderConfig {
58
76
 
59
77
  /** Event handlers for slider events */
60
78
  on?: {
61
- [key in keyof typeof SLIDER_EVENTS | typeof SLIDER_EVENTS[keyof typeof SLIDER_EVENTS]]?: (event: SliderEvent) => void;
79
+ [key in SliderEventType]?: (event: SliderEvent) => void;
62
80
  };
63
81
  }
64
82
 
83
+ /**
84
+ * Slider event data
85
+ * @interface SliderEvent
86
+ */
65
87
  export interface SliderEvent {
66
88
  /** The slider component that triggered the event */
67
89
  slider: any;
@@ -82,6 +104,10 @@ export interface SliderEvent {
82
104
  defaultPrevented: boolean;
83
105
  }
84
106
 
107
+ /**
108
+ * Slider component public API interface
109
+ * @interface SliderComponent
110
+ */
85
111
  export interface SliderComponent {
86
112
  /** The root element of the slider */
87
113
  element: HTMLElement;
@@ -126,13 +152,13 @@ export interface SliderComponent {
126
152
  isDisabled: () => boolean;
127
153
 
128
154
  /** Sets slider color */
129
- setColor: (color: keyof typeof SLIDER_COLORS | typeof SLIDER_COLORS[keyof typeof SLIDER_COLORS]) => SliderComponent;
155
+ setColor: (color: SliderColor) => SliderComponent;
130
156
 
131
157
  /** Gets slider color */
132
158
  getColor: () => string;
133
159
 
134
160
  /** Sets slider size */
135
- setSize: (size: keyof typeof SLIDER_SIZES | typeof SLIDER_SIZES[keyof typeof SLIDER_SIZES]) => SliderComponent;
161
+ setSize: (size: SliderSize) => SliderComponent;
136
162
 
137
163
  /** Gets slider size */
138
164
  getSize: () => string;
@@ -156,10 +182,10 @@ export interface SliderComponent {
156
182
  getIcon: () => string;
157
183
 
158
184
  /** Adds event listener */
159
- on: (event: keyof typeof SLIDER_EVENTS | typeof SLIDER_EVENTS[keyof typeof SLIDER_EVENTS], handler: (event: SliderEvent) => void) => SliderComponent;
185
+ on: (event: SliderEventType, handler: (event: SliderEvent) => void) => SliderComponent;
160
186
 
161
187
  /** Removes event listener */
162
- off: (event: keyof typeof SLIDER_EVENTS | typeof SLIDER_EVENTS[keyof typeof SLIDER_EVENTS], handler: (event: SliderEvent) => void) => SliderComponent;
188
+ off: (event: SliderEventType, handler: (event: SliderEvent) => void) => SliderComponent;
163
189
 
164
190
  /** Destroys the slider component and cleans up resources */
165
191
  destroy: () => void;
@@ -5,14 +5,13 @@ import {
5
5
  BaseComponentConfig
6
6
  } from '../../core/config/component-config';
7
7
  import { SnackbarConfig, BaseComponent, ApiOptions } from './types';
8
- import { SNACKBAR_VARIANTS, SNACKBAR_POSITIONS } from './constants';
9
8
 
10
9
  /**
11
10
  * Default configuration for the Snackbar component
12
11
  */
13
12
  export const defaultConfig: SnackbarConfig = {
14
- variant: SNACKBAR_VARIANTS.BASIC,
15
- position: SNACKBAR_POSITIONS.CENTER,
13
+ variant: 'basic',
14
+ position: 'center',
16
15
  duration: 4000
17
16
  };
18
17
 
@@ -17,38 +17,6 @@ export const SNACKBAR_POSITIONS = {
17
17
  END: 'end'
18
18
  } as const;
19
19
 
20
- /**
21
- * Validation schema for snackbar configuration
22
- */
23
- export const SNACKBAR_SCHEMA = {
24
- variant: {
25
- type: 'string',
26
- enum: Object.values(SNACKBAR_VARIANTS),
27
- required: false
28
- },
29
- position: {
30
- type: 'string',
31
- enum: Object.values(SNACKBAR_POSITIONS),
32
- required: false
33
- },
34
- message: {
35
- type: 'string',
36
- required: true
37
- },
38
- action: {
39
- type: 'string',
40
- required: false
41
- },
42
- duration: {
43
- type: 'number',
44
- required: false
45
- },
46
- class: {
47
- type: 'string',
48
- required: false
49
- }
50
- } as const;
51
-
52
20
  /**
53
21
  * Snackbar state classes
54
22
  */
@@ -1,4 +1,3 @@
1
1
  // src/components/snackbar/index.ts
2
2
  export { default } from './snackbar'
3
- export { SNACKBAR_VARIANTS, SNACKBAR_POSITIONS } from './constants'
4
3
  export { SnackbarConfig, SnackbarComponent } from './types'
@@ -1,7 +1,15 @@
1
1
  // src/components/snackbar/position.ts
2
- import { SNACKBAR_POSITIONS } from './constants';
3
2
  import { BaseComponent } from './types';
4
3
 
4
+ /**
5
+ * Snackbar display positions
6
+ */
7
+ const SNACKBAR_POSITIONS = {
8
+ CENTER: 'center',
9
+ START: 'start',
10
+ END: 'end'
11
+ }
12
+
5
13
  /**
6
14
  * Position configuration for the withPosition function
7
15
  */