mtrl 0.2.6 → 0.2.7

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 (147) hide show
  1. package/index.ts +18 -0
  2. package/package.json +1 -1
  3. package/src/components/badge/_styles.scss +117 -109
  4. package/src/components/badge/api.ts +57 -59
  5. package/src/components/badge/badge.ts +16 -2
  6. package/src/components/badge/config.ts +65 -11
  7. package/src/components/badge/constants.ts +22 -12
  8. package/src/components/badge/features.ts +44 -40
  9. package/src/components/badge/types.ts +42 -30
  10. package/src/components/bottom-app-bar/_styles.scss +103 -0
  11. package/src/components/bottom-app-bar/bottom-app-bar.ts +196 -0
  12. package/src/components/bottom-app-bar/config.ts +73 -0
  13. package/src/components/bottom-app-bar/index.ts +11 -0
  14. package/src/components/bottom-app-bar/types.ts +108 -0
  15. package/src/components/button/_styles.scss +0 -10
  16. package/src/components/button/api.ts +5 -0
  17. package/src/components/button/config.ts +5 -0
  18. package/src/components/button/types.ts +6 -0
  19. package/src/components/card/card.ts +13 -25
  20. package/src/components/card/config.ts +67 -22
  21. package/src/components/card/features.ts +3 -0
  22. package/src/components/card/types.ts +28 -0
  23. package/src/components/checkbox/_styles.scss +0 -2
  24. package/src/components/datepicker/_styles.scss +358 -0
  25. package/src/components/datepicker/api.ts +272 -0
  26. package/src/components/datepicker/config.ts +144 -0
  27. package/src/components/datepicker/constants.ts +98 -0
  28. package/src/components/datepicker/datepicker.ts +346 -0
  29. package/src/components/datepicker/index.ts +9 -0
  30. package/src/components/datepicker/render.ts +452 -0
  31. package/src/components/datepicker/types.ts +268 -0
  32. package/src/components/datepicker/utils.ts +290 -0
  33. package/src/components/dialog/_styles.scss +174 -128
  34. package/src/components/dialog/api.ts +48 -13
  35. package/src/components/dialog/config.ts +9 -5
  36. package/src/components/dialog/dialog.ts +6 -3
  37. package/src/components/dialog/features.ts +290 -130
  38. package/src/components/dialog/types.ts +7 -4
  39. package/src/components/divider/_styles.scss +57 -0
  40. package/src/components/divider/config.ts +81 -0
  41. package/src/components/divider/divider.ts +37 -0
  42. package/src/components/divider/features.ts +207 -0
  43. package/src/components/divider/index.ts +5 -0
  44. package/src/components/divider/types.ts +55 -0
  45. package/src/components/extended-fab/_styles.scss +267 -0
  46. package/src/components/extended-fab/api.ts +141 -0
  47. package/src/components/extended-fab/config.ts +108 -0
  48. package/src/components/extended-fab/constants.ts +36 -0
  49. package/src/components/extended-fab/extended-fab.ts +125 -0
  50. package/src/components/extended-fab/index.ts +4 -0
  51. package/src/components/extended-fab/types.ts +287 -0
  52. package/src/components/fab/_styles.scss +225 -0
  53. package/src/components/fab/api.ts +97 -0
  54. package/src/components/fab/config.ts +94 -0
  55. package/src/components/fab/constants.ts +41 -0
  56. package/src/components/fab/fab.ts +67 -0
  57. package/src/components/fab/index.ts +4 -0
  58. package/src/components/fab/types.ts +234 -0
  59. package/src/components/navigation/_styles.scss +1 -0
  60. package/src/components/navigation/api.ts +78 -50
  61. package/src/components/navigation/features/items.ts +280 -0
  62. package/src/components/navigation/nav-item.ts +72 -23
  63. package/src/components/navigation/navigation.ts +54 -2
  64. package/src/components/navigation/types.ts +210 -188
  65. package/src/components/search/_styles.scss +306 -0
  66. package/src/components/search/api.ts +203 -0
  67. package/src/components/search/config.ts +87 -0
  68. package/src/components/search/constants.ts +21 -0
  69. package/src/components/search/features/index.ts +4 -0
  70. package/src/components/search/features/search.ts +718 -0
  71. package/src/components/search/features/states.ts +165 -0
  72. package/src/components/search/features/structure.ts +198 -0
  73. package/src/components/search/index.ts +10 -0
  74. package/src/components/search/search.ts +52 -0
  75. package/src/components/search/types.ts +163 -0
  76. package/src/components/segmented-button/_styles.scss +117 -0
  77. package/src/components/segmented-button/config.ts +67 -0
  78. package/src/components/segmented-button/constants.ts +42 -0
  79. package/src/components/segmented-button/index.ts +4 -0
  80. package/src/components/segmented-button/segment.ts +155 -0
  81. package/src/components/segmented-button/segmented-button.ts +250 -0
  82. package/src/components/segmented-button/types.ts +219 -0
  83. package/src/components/slider/_styles.scss +83 -24
  84. package/src/components/slider/accessibility.md +5 -5
  85. package/src/components/slider/api.ts +41 -120
  86. package/src/components/slider/config.ts +51 -47
  87. package/src/components/slider/features/handlers.ts +495 -0
  88. package/src/components/slider/features/index.ts +1 -2
  89. package/src/components/slider/features/slider.ts +66 -84
  90. package/src/components/slider/features/states.ts +195 -0
  91. package/src/components/slider/features/structure.ts +136 -206
  92. package/src/components/slider/features/ui.ts +145 -206
  93. package/src/components/slider/index.ts +2 -11
  94. package/src/components/slider/slider.ts +9 -12
  95. package/src/components/slider/types.ts +39 -24
  96. package/src/components/switch/_styles.scss +0 -2
  97. package/src/components/tabs/_styles.scss +94 -32
  98. package/src/components/tabs/features.ts +4 -2
  99. package/src/components/tabs/indicator.ts +73 -13
  100. package/src/components/tabs/types.ts +10 -2
  101. package/src/components/timepicker/README.md +277 -0
  102. package/src/components/timepicker/_styles.scss +451 -0
  103. package/src/components/timepicker/api.ts +632 -0
  104. package/src/components/timepicker/clockdial.ts +482 -0
  105. package/src/components/timepicker/config.ts +130 -0
  106. package/src/components/timepicker/constants.ts +138 -0
  107. package/src/components/timepicker/index.ts +8 -0
  108. package/src/components/timepicker/render.ts +613 -0
  109. package/src/components/timepicker/timepicker.ts +117 -0
  110. package/src/components/timepicker/types.ts +336 -0
  111. package/src/components/timepicker/utils.ts +241 -0
  112. package/src/components/top-app-bar/_styles.scss +225 -0
  113. package/src/components/top-app-bar/config.ts +83 -0
  114. package/src/components/top-app-bar/index.ts +11 -0
  115. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  116. package/src/components/top-app-bar/types.ts +140 -0
  117. package/src/core/build/_ripple.scss +6 -6
  118. package/src/core/build/ripple.ts +72 -95
  119. package/src/core/compose/features/icon.ts +3 -1
  120. package/src/core/compose/features/ripple.ts +4 -1
  121. package/src/core/compose/features/textlabel.ts +26 -2
  122. package/src/core/dom/create.ts +5 -0
  123. package/src/index.ts +9 -0
  124. package/src/styles/abstract/_theme.scss +9 -1
  125. package/src/styles/themes/_autumn.scss +21 -0
  126. package/src/styles/themes/_base-theme.scss +61 -0
  127. package/src/styles/themes/_baseline.scss +58 -0
  128. package/src/styles/themes/_bluekhaki.scss +125 -0
  129. package/src/styles/themes/_brownbeige.scss +125 -0
  130. package/src/styles/themes/_browngreen.scss +125 -0
  131. package/src/styles/themes/_forest.scss +6 -0
  132. package/src/styles/themes/_greenbeige.scss +125 -0
  133. package/src/styles/themes/_material.scss +125 -0
  134. package/src/styles/themes/_ocean.scss +6 -0
  135. package/src/styles/themes/_sageivory.scss +125 -0
  136. package/src/styles/themes/_spring.scss +6 -0
  137. package/src/styles/themes/_summer.scss +5 -0
  138. package/src/styles/themes/_sunset.scss +5 -0
  139. package/src/styles/themes/_tealcaramel.scss +125 -0
  140. package/src/styles/themes/_winter.scss +6 -0
  141. package/src/components/navigation/features/items.js +0 -192
  142. package/src/components/slider/features/appearance.ts +0 -94
  143. package/src/components/slider/features/disabled.ts +0 -68
  144. package/src/components/slider/features/events.ts +0 -164
  145. package/src/components/slider/features/interactions.ts +0 -396
  146. package/src/components/slider/features/keyboard.ts +0 -233
  147. package/src/core/collection/adapters/mongodb.js +0 -232
@@ -1,9 +1,11 @@
1
1
  // src/components/slider/features/structure.ts
2
2
  import { SLIDER_COLORS, SLIDER_SIZES } from '../constants';
3
3
  import { SliderConfig } from '../types';
4
+ import createLayout from '../../../core/layout';
5
+ import { createElement } from '../../../core/dom/create';
4
6
 
5
7
  /**
6
- * Creates the slider DOM structure following MD3 principles with improved accessibility
8
+ * Creates the slider DOM structure using layout system
7
9
  * @param config Slider configuration
8
10
  * @returns Component enhancer with DOM structure
9
11
  */
@@ -11,241 +13,169 @@ export const withStructure = (config: SliderConfig) => component => {
11
13
  // Set default values
12
14
  const min = config.min || 0;
13
15
  const max = config.max || 100;
14
- const range = max - min;
15
16
  const value = config.value !== undefined ? config.value : min;
16
17
  const secondValue = config.secondValue !== undefined ? config.secondValue : null;
17
18
  const isRangeSlider = config.range && secondValue !== null;
18
19
  const isDisabled = config.disabled === true;
19
20
 
20
- // Helper function to calculate percentage
21
- const getPercentage = (val) => ((val - min) / range) * 100;
22
- const valuePercent = getPercentage(value);
23
-
24
- // Create track element and segments
25
- const track = createElement('slider-track');
26
- const remainingTrack = createElement('slider-remaining-track');
27
- const startTrack = createElement('slider-start-track');
28
- const activeTrack = createElement('slider-active-track');
29
-
30
- // Create ticks container
31
- const ticksContainer = createElement('slider-ticks-container');
32
-
33
- // Create dots for track ends
34
- const startDot = createElement('slider-dot');
35
- startDot.classList.add(component.getClass('slider-dot--start'));
36
-
37
- const endDot = createElement('slider-dot');
38
- endDot.classList.add(component.getClass('slider-dot--end'));
39
-
40
- // Create value bubble and format the value
21
+ // Format the values
41
22
  const formatter = config.valueFormatter || (val => val.toString());
42
- const valueBubble = createElement('slider-value');
43
- valueBubble.textContent = formatter(value);
44
-
45
- // Create thumb element with improved accessibility attributes
46
- const thumb = createElement('slider-thumb');
47
- thumb.setAttribute('role', 'slider');
48
- thumb.setAttribute('aria-valuemin', String(min));
49
- thumb.setAttribute('aria-valuemax', String(max));
50
- thumb.setAttribute('aria-valuenow', String(value));
51
- thumb.setAttribute('aria-orientation', 'horizontal');
52
-
53
- // Set tabindex based on disabled state
54
- thumb.setAttribute('tabindex', isDisabled ? '-1' : '0');
55
- if (isDisabled) {
56
- thumb.setAttribute('aria-disabled', 'true');
57
- }
58
-
59
- // Set initial thumb position
60
- thumb.style.left = `${valuePercent}%`;
61
-
62
- // Calculate padding adjustment (8px equivalent as percentage)
63
- const paddingAdjustment = 8; // 8px padding
64
- const estimatedTrackSize = 300; // A reasonable guess at track width
65
- const paddingPercent = (paddingAdjustment / estimatedTrackSize) * 100;
66
-
67
- // Create second thumb and value bubble for range slider
68
- let secondThumb = null;
69
- let secondValueBubble = null;
70
23
 
24
+ // Get prefixed class names
25
+ const getClass = (className) => component.getClass(className);
26
+
27
+ // Define slider structure
28
+ const structure = [
29
+ [createElement, 'container', {
30
+ className: getClass('slider-container')
31
+ }, [
32
+ // Track with segments
33
+ [createElement, 'track', {
34
+ className: getClass('slider-track')
35
+ }, [
36
+ [createElement, 'startTrack', {
37
+ className: getClass('slider-start-track')
38
+ }],
39
+ [createElement, 'activeTrack', {
40
+ className: getClass('slider-active-track')
41
+ }],
42
+ [createElement, 'remainingTrack', {
43
+ className: getClass('slider-remaining-track')
44
+ }]
45
+ ]],
46
+
47
+ // Ticks container
48
+ [createElement, 'ticksContainer', {
49
+ className: getClass('slider-ticks-container')
50
+ }],
51
+
52
+ // Dots for ends
53
+ [createElement, 'startDot', {
54
+ className: [
55
+ getClass('slider-dot'),
56
+ getClass('slider-dot--start')
57
+ ]
58
+ }],
59
+ [createElement, 'endDot', {
60
+ className: [
61
+ getClass('slider-dot'),
62
+ getClass('slider-dot--end')
63
+ ]
64
+ }],
65
+
66
+ // Main handle
67
+ [createElement, 'handle', {
68
+ className: getClass('slider-handle'),
69
+ attrs: {
70
+ 'role': 'slider',
71
+ 'aria-valuemin': String(min),
72
+ 'aria-valuemax': String(max),
73
+ 'aria-valuenow': String(value),
74
+ 'aria-orientation': 'horizontal',
75
+ 'tabindex': isDisabled ? '-1' : '0',
76
+ 'aria-disabled': isDisabled ? 'true' : 'false'
77
+ },
78
+ style: {
79
+ left: `${((value - min) / (max - min)) * 100}%`
80
+ }
81
+ }],
82
+
83
+ // Main value bubble
84
+ [createElement, 'valueBubble', {
85
+ className: getClass('slider-value'),
86
+ text: formatter(value)
87
+ }]
88
+ ]]
89
+ ];
90
+
91
+ // Add second handle and bubble for range slider
71
92
  if (isRangeSlider) {
72
- secondThumb = createElement('slider-thumb');
73
- secondThumb.setAttribute('role', 'slider');
74
- secondThumb.setAttribute('aria-valuemin', String(min));
75
- secondThumb.setAttribute('aria-valuemax', String(max));
76
- secondThumb.setAttribute('aria-valuenow', String(secondValue));
77
- secondThumb.setAttribute('aria-orientation', 'horizontal');
78
-
79
- // Set tabindex based on disabled state
80
- secondThumb.setAttribute('tabindex', isDisabled ? '-1' : '0');
81
- if (isDisabled) {
82
- secondThumb.setAttribute('aria-disabled', 'true');
83
- }
93
+ const secondHandlePos = ((secondValue - min) / (max - min)) * 100;
84
94
 
85
- const secondPercent = getPercentage(secondValue);
86
- secondThumb.style.left = `${secondPercent}%`;
95
+ // Add second handle to structure
96
+ structure[0][3].push(
97
+ [createElement, 'secondHandle', {
98
+ className: getClass('slider-handle'),
99
+ attrs: {
100
+ 'role': 'slider',
101
+ 'aria-valuemin': String(min),
102
+ 'aria-valuemax': String(max),
103
+ 'aria-valuenow': String(secondValue),
104
+ 'aria-orientation': 'horizontal',
105
+ 'tabindex': isDisabled ? '-1' : '0',
106
+ 'aria-disabled': isDisabled ? 'true' : 'false'
107
+ },
108
+ style: {
109
+ left: `${secondHandlePos}%`
110
+ }
111
+ }]
112
+ );
87
113
 
88
- secondValueBubble = createElement('slider-value');
89
- secondValueBubble.textContent = formatter(secondValue);
114
+ // Add second bubble to structure
115
+ structure[0][3].push(
116
+ [createElement, 'secondValueBubble', {
117
+ className: getClass('slider-value'),
118
+ text: formatter(secondValue)
119
+ }]
120
+ );
90
121
  }
91
122
 
92
- // Set initial track segment dimensions
93
- setupInitialTrackSegments();
94
-
95
- // Add tracks to container
96
- track.appendChild(remainingTrack);
97
- track.appendChild(startTrack);
98
- track.appendChild(activeTrack);
123
+ // Create layout and get structure elements
124
+ const components = createLayout(structure, component.element).component;
99
125
 
100
- // Add elements to the slider
126
+ // Add component base class and accessibility attributes
101
127
  component.element.classList.add(component.getClass('slider'));
102
-
103
- // Accessibility enhancement: Container is not focusable
104
128
  component.element.setAttribute('tabindex', '-1');
105
-
106
- // Set container aria attributes
107
129
  component.element.setAttribute('role', 'none');
108
130
  component.element.setAttribute('aria-disabled', isDisabled ? 'true' : 'false');
109
131
 
110
- component.element.appendChild(track);
111
- component.element.appendChild(ticksContainer); // Add ticks container
112
- component.element.appendChild(startDot);
113
- component.element.appendChild(endDot);
114
- component.element.appendChild(thumb);
115
- component.element.appendChild(valueBubble);
116
-
117
- if (isRangeSlider && secondThumb && secondValueBubble) {
118
- component.element.classList.add(`${component.getClass('slider')}--range`);
119
- component.element.appendChild(secondThumb);
120
- component.element.appendChild(secondValueBubble);
132
+ // Position any icon properly
133
+ const iconElement = component.element.querySelector(`.${component.getClass('icon')}`);
134
+ if (iconElement && config.label) {
135
+ iconElement.classList.add(component.getClass('slider-icon'));
136
+ component.element.classList.add(component.getClass('slider--icon'));
121
137
  }
122
138
 
123
- // Apply styling classes
124
- applyStyleClasses();
125
-
126
- // Schedule UI update after DOM is attached
127
- setTimeout(() => {
128
- component.slider?.updateUi?.();
129
- }, 0);
139
+ // Apply style classes
140
+ applyStyleClasses(component, config, isRangeSlider, isDisabled);
130
141
 
131
142
  // Return enhanced component with structure
132
143
  return {
133
144
  ...component,
134
- structure: {
135
- track,
136
- activeTrack,
137
- startTrack,
138
- remainingTrack,
139
- ticksContainer,
140
- thumb,
141
- valueBubble,
142
- secondThumb,
143
- secondValueBubble,
144
- startDot,
145
- endDot
146
- }
145
+ structure: components
147
146
  };
147
+ };
148
+
149
+ /**
150
+ * Applies style classes based on configuration
151
+ */
152
+ function applyStyleClasses(component, config, isRangeSlider, isDisabled) {
153
+ const baseClass = component.getClass('slider');
148
154
 
149
- /**
150
- * Creates DOM element with slider class
151
- * @param className Base class name
152
- * @returns DOM element
153
- */
154
- function createElement(className) {
155
- const element = document.createElement('div');
156
- element.classList.add(component.getClass(className));
157
- return element;
155
+ // Apply size class
156
+ const size = config.size || SLIDER_SIZES.MEDIUM;
157
+ if (size !== SLIDER_SIZES.MEDIUM) {
158
+ component.element.classList.add(`${baseClass}--${size}`);
158
159
  }
159
160
 
160
- /**
161
- * Sets up initial track segment positions and dimensions
162
- */
163
- function setupInitialTrackSegments() {
164
- if (isRangeSlider) {
165
- // Range slider with two thumbs
166
- const lowerValue = Math.min(value, secondValue);
167
- const higherValue = Math.max(value, secondValue);
168
- const lowerPercent = getPercentage(lowerValue);
169
- const higherPercent = getPercentage(higherValue);
170
-
171
- // Adjust positions to account for spacing
172
- let adjustedLowerPercent = lowerPercent + paddingPercent;
173
- let adjustedHigherPercent = higherPercent - paddingPercent;
174
-
175
- // Handle case when thumbs are very close
176
- if (adjustedHigherPercent <= adjustedLowerPercent) {
177
- adjustedLowerPercent = (lowerPercent + higherPercent) / 2 - 1;
178
- adjustedHigherPercent = (lowerPercent + higherPercent) / 2 + 1;
179
- }
180
-
181
- // Calculate segment sizes
182
- const startWidth = Math.max(0, lowerPercent - paddingPercent);
183
- const activeWidth = Math.max(0, adjustedHigherPercent - adjustedLowerPercent);
184
- const remainingWidth = Math.max(0, 100 - higherPercent - paddingPercent);
185
-
186
- // Set styles
187
- startTrack.style.display = 'block';
188
- activeTrack.style.display = 'block';
189
- remainingTrack.style.display = 'block';
190
-
191
- // Horizontal orientation
192
- setTrackStyles(startTrack, startWidth, 0);
193
- setTrackStyles(activeTrack, activeWidth, adjustedLowerPercent);
194
- setTrackStyles(remainingTrack, remainingWidth, higherPercent + paddingPercent);
195
- } else {
196
- // Single thumb slider
197
- const adjustedWidth = Math.max(0, valuePercent - paddingPercent);
198
- const remainingWidth = Math.max(0, 100 - valuePercent - paddingPercent);
199
-
200
- // Hide start track for single thumb
201
- startTrack.style.display = 'none';
202
- activeTrack.style.display = 'block';
203
- remainingTrack.style.display = 'block';
204
-
205
- // Horizontal orientation
206
- setTrackStyles(activeTrack, adjustedWidth, 0);
207
- setTrackStyles(remainingTrack, remainingWidth, valuePercent + paddingPercent);
208
- }
161
+ // Apply color class
162
+ const color = config.color || SLIDER_COLORS.PRIMARY;
163
+ if (color !== SLIDER_COLORS.PRIMARY) {
164
+ component.element.classList.add(`${baseClass}--${color}`);
209
165
  }
210
166
 
211
- /**
212
- * Sets styles for track segments
213
- * @param element Track segment element
214
- * @param width Width as percentage
215
- * @param left Left position as percentage
216
- */
217
- function setTrackStyles(element, width, left) {
218
- element.style.width = `${width}%`;
219
- element.style.left = `${left}%`;
220
- element.style.height = '100%';
167
+ // Apply discrete class if step is specified
168
+ if (config.step !== undefined && config.step > 0) {
169
+ component.element.classList.add(`${baseClass}--discrete`);
221
170
  }
222
171
 
223
- /**
224
- * Applies style classes based on configuration
225
- */
226
- function applyStyleClasses() {
227
- const baseClass = component.getClass('slider');
228
-
229
- // Apply size class
230
- const size = config.size || SLIDER_SIZES.MEDIUM;
231
- if (size !== SLIDER_SIZES.MEDIUM) {
232
- component.element.classList.add(`${baseClass}--${size}`);
233
- }
234
-
235
- // Apply color class
236
- const color = config.color || SLIDER_COLORS.PRIMARY;
237
- if (color !== SLIDER_COLORS.PRIMARY) {
238
- component.element.classList.add(`${baseClass}--${color}`);
239
- }
240
-
241
- // Apply discrete class if step is specified
242
- if (config.step !== undefined && config.step > 0) {
243
- component.element.classList.add(`${baseClass}--discrete`);
244
- }
245
-
246
- // Apply disabled class if needed
247
- if (isDisabled) {
248
- component.element.classList.add(`${baseClass}--disabled`);
249
- }
172
+ // Apply disabled class if needed
173
+ if (isDisabled) {
174
+ component.element.classList.add(`${baseClass}--disabled`);
175
+ }
176
+
177
+ // Apply range class if needed
178
+ if (isRangeSlider) {
179
+ component.element.classList.add(`${baseClass}--range`);
250
180
  }
251
- };
181
+ }