mtrl 0.2.4 → 0.2.6
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 +6 -3
- package/src/components/badge/_styles.scss +9 -9
- package/src/components/button/_styles.scss +0 -56
- package/src/components/button/button.ts +0 -2
- package/src/components/button/constants.ts +0 -6
- package/src/components/button/index.ts +2 -2
- package/src/components/button/types.ts +1 -7
- package/src/components/card/_styles.scss +67 -25
- package/src/components/card/api.ts +54 -3
- package/src/components/card/card.ts +33 -2
- package/src/components/card/config.ts +143 -21
- package/src/components/card/constants.ts +20 -19
- package/src/components/card/content.ts +299 -2
- package/src/components/card/features.ts +155 -4
- package/src/components/card/index.ts +31 -9
- package/src/components/card/types.ts +138 -15
- package/src/components/chip/chip.ts +1 -9
- package/src/components/chip/constants.ts +0 -10
- package/src/components/chip/index.ts +1 -1
- package/src/components/chip/types.ts +1 -4
- package/src/components/progress/_styles.scss +0 -65
- package/src/components/progress/config.ts +1 -2
- package/src/components/progress/constants.ts +0 -14
- package/src/components/progress/index.ts +1 -1
- package/src/components/progress/progress.ts +1 -4
- package/src/components/progress/types.ts +1 -4
- package/src/components/radios/_styles.scss +0 -45
- package/src/components/radios/api.ts +85 -60
- package/src/components/radios/config.ts +1 -2
- package/src/components/radios/constants.ts +0 -9
- package/src/components/radios/index.ts +1 -1
- package/src/components/radios/radio.ts +34 -11
- package/src/components/radios/radios.ts +2 -1
- package/src/components/radios/types.ts +1 -7
- package/src/components/slider/_styles.scss +193 -281
- package/src/components/slider/accessibility.md +59 -0
- package/src/components/slider/api.ts +36 -101
- package/src/components/slider/config.ts +29 -78
- package/src/components/slider/constants.ts +12 -8
- package/src/components/slider/features/appearance.ts +1 -47
- package/src/components/slider/features/disabled.ts +41 -16
- package/src/components/slider/features/interactions.ts +166 -26
- package/src/components/slider/features/keyboard.ts +125 -6
- package/src/components/slider/features/structure.ts +182 -195
- package/src/components/slider/features/ui.ts +234 -303
- package/src/components/slider/index.ts +11 -1
- package/src/components/slider/slider.ts +1 -1
- package/src/components/slider/types.ts +10 -25
- package/src/components/tabs/_styles.scss +285 -155
- package/src/components/tabs/api.ts +178 -400
- package/src/components/tabs/config.ts +46 -52
- package/src/components/tabs/constants.ts +85 -8
- package/src/components/tabs/features.ts +401 -0
- package/src/components/tabs/index.ts +60 -3
- package/src/components/tabs/indicator.ts +225 -0
- package/src/components/tabs/responsive.ts +144 -0
- package/src/components/tabs/scroll-indicators.ts +149 -0
- package/src/components/tabs/state.ts +186 -0
- package/src/components/tabs/tab-api.ts +258 -0
- package/src/components/tabs/tab.ts +255 -0
- package/src/components/tabs/tabs.ts +50 -31
- package/src/components/tabs/types.ts +324 -128
- package/src/components/tabs/utils.ts +107 -0
- package/src/components/textfield/_styles.scss +0 -98
- package/src/components/textfield/config.ts +2 -3
- package/src/components/textfield/constants.ts +0 -14
- package/src/components/textfield/index.ts +2 -2
- package/src/components/textfield/textfield.ts +0 -2
- package/src/components/textfield/types.ts +1 -4
- package/src/core/compose/component.ts +1 -1
- package/src/core/compose/features/badge.ts +79 -0
- package/src/core/compose/features/index.ts +3 -1
- package/src/styles/abstract/_theme.scss +106 -2
- package/src/components/card/actions.ts +0 -48
- package/src/components/card/header.ts +0 -88
- package/src/components/card/media.ts +0 -52
|
@@ -1,251 +1,134 @@
|
|
|
1
|
-
// src/components/slider/features/structure.ts
|
|
2
|
-
import { SLIDER_COLORS, SLIDER_SIZES
|
|
1
|
+
// src/components/slider/features/structure.ts
|
|
2
|
+
import { SLIDER_COLORS, SLIDER_SIZES } from '../constants';
|
|
3
3
|
import { SliderConfig } from '../types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Creates the slider DOM structure following MD3 principles
|
|
6
|
+
* Creates the slider DOM structure following MD3 principles with improved accessibility
|
|
7
7
|
* @param config Slider configuration
|
|
8
8
|
* @returns Component enhancer with DOM structure
|
|
9
9
|
*/
|
|
10
10
|
export const withStructure = (config: SliderConfig) => component => {
|
|
11
|
-
//
|
|
12
|
-
const track = document.createElement('div');
|
|
13
|
-
track.classList.add(component.getClass('slider-track'));
|
|
14
|
-
|
|
15
|
-
// Calculate initial percentages based on values
|
|
11
|
+
// Set default values
|
|
16
12
|
const min = config.min || 0;
|
|
17
13
|
const max = config.max || 100;
|
|
18
14
|
const range = max - min;
|
|
19
|
-
|
|
20
|
-
// Set default values
|
|
21
15
|
const value = config.value !== undefined ? config.value : min;
|
|
22
16
|
const secondValue = config.secondValue !== undefined ? config.secondValue : null;
|
|
17
|
+
const isRangeSlider = config.range && secondValue !== null;
|
|
18
|
+
const isDisabled = config.disabled === true;
|
|
23
19
|
|
|
24
|
-
//
|
|
20
|
+
// Helper function to calculate percentage
|
|
25
21
|
const getPercentage = (val) => ((val - min) / range) * 100;
|
|
26
22
|
const valuePercent = getPercentage(value);
|
|
27
23
|
|
|
28
|
-
// Create
|
|
29
|
-
const
|
|
30
|
-
remainingTrack
|
|
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');
|
|
31
29
|
|
|
32
|
-
// Create
|
|
33
|
-
const
|
|
34
|
-
startTrack.classList.add(component.getClass('slider-start-track'));
|
|
30
|
+
// Create ticks container
|
|
31
|
+
const ticksContainer = createElement('slider-ticks-container');
|
|
35
32
|
|
|
36
|
-
// Create
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Calculate padding adjustment (8px equivalent as percentage)
|
|
41
|
-
// We'll do a rough estimate initially, then recalculate once rendered
|
|
42
|
-
const paddingAdjustment = 8; // 8px padding
|
|
43
|
-
const estimatedTrackSize = 300; // A reasonable guess at track width
|
|
44
|
-
const paddingPercent = (paddingAdjustment / estimatedTrackSize) * 100;
|
|
33
|
+
// Create dots for track ends
|
|
34
|
+
const startDot = createElement('slider-dot');
|
|
35
|
+
startDot.classList.add(component.getClass('slider-dot--start'));
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Range slider
|
|
49
|
-
const lowerValue = Math.min(value, secondValue);
|
|
50
|
-
const higherValue = Math.max(value, secondValue);
|
|
51
|
-
const lowerPercent = getPercentage(lowerValue);
|
|
52
|
-
const higherPercent = getPercentage(higherValue);
|
|
53
|
-
|
|
54
|
-
// Adjust positions and width to account for spacing
|
|
55
|
-
let adjustedLowerPercent = lowerPercent + paddingPercent;
|
|
56
|
-
let adjustedHigherPercent = higherPercent - paddingPercent;
|
|
57
|
-
|
|
58
|
-
if (adjustedHigherPercent <= adjustedLowerPercent) {
|
|
59
|
-
adjustedLowerPercent = (lowerPercent + higherPercent) / 2 - 1;
|
|
60
|
-
adjustedHigherPercent = (lowerPercent + higherPercent) / 2 + 1;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Calculate track segment sizes
|
|
64
|
-
const startWidth = Math.max(0, lowerPercent - paddingPercent);
|
|
65
|
-
const activeWidth = Math.max(0, adjustedHigherPercent - adjustedLowerPercent);
|
|
66
|
-
const remainingWidth = Math.max(0, 100 - higherPercent - paddingPercent);
|
|
67
|
-
|
|
68
|
-
if (config.orientation === SLIDER_ORIENTATIONS.VERTICAL) {
|
|
69
|
-
// Vertical orientation
|
|
70
|
-
startTrack.style.display = 'block';
|
|
71
|
-
startTrack.style.height = `${startWidth}%`;
|
|
72
|
-
startTrack.style.bottom = '0';
|
|
73
|
-
startTrack.style.width = '100%';
|
|
74
|
-
|
|
75
|
-
activeTrack.style.display = 'block';
|
|
76
|
-
activeTrack.style.height = `${activeWidth}%`;
|
|
77
|
-
activeTrack.style.bottom = `${adjustedLowerPercent}%`;
|
|
78
|
-
activeTrack.style.width = '100%';
|
|
79
|
-
|
|
80
|
-
remainingTrack.style.display = 'block';
|
|
81
|
-
remainingTrack.style.height = `${remainingWidth}%`;
|
|
82
|
-
remainingTrack.style.bottom = `${higherPercent + paddingPercent}%`;
|
|
83
|
-
remainingTrack.style.width = '100%';
|
|
84
|
-
} else {
|
|
85
|
-
// Horizontal orientation
|
|
86
|
-
startTrack.style.display = 'block';
|
|
87
|
-
startTrack.style.width = `${startWidth}%`;
|
|
88
|
-
startTrack.style.left = '0';
|
|
89
|
-
startTrack.style.height = '100%';
|
|
90
|
-
|
|
91
|
-
activeTrack.style.display = 'block';
|
|
92
|
-
activeTrack.style.width = `${activeWidth}%`;
|
|
93
|
-
activeTrack.style.left = `${adjustedLowerPercent}%`;
|
|
94
|
-
activeTrack.style.height = '100%';
|
|
95
|
-
|
|
96
|
-
remainingTrack.style.display = 'block';
|
|
97
|
-
remainingTrack.style.width = `${remainingWidth}%`;
|
|
98
|
-
remainingTrack.style.left = `${higherPercent + paddingPercent}%`;
|
|
99
|
-
remainingTrack.style.height = '100%';
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
// Single thumb slider
|
|
103
|
-
const adjustedWidth = Math.max(0, valuePercent - paddingPercent);
|
|
104
|
-
const remainingWidth = Math.max(0, 100 - valuePercent - paddingPercent);
|
|
105
|
-
|
|
106
|
-
if (config.orientation === SLIDER_ORIENTATIONS.VERTICAL) {
|
|
107
|
-
// Vertical orientation
|
|
108
|
-
startTrack.style.display = 'none';
|
|
109
|
-
|
|
110
|
-
activeTrack.style.display = 'block';
|
|
111
|
-
activeTrack.style.height = `${adjustedWidth}%`;
|
|
112
|
-
activeTrack.style.bottom = '0';
|
|
113
|
-
activeTrack.style.width = '100%';
|
|
114
|
-
|
|
115
|
-
remainingTrack.style.display = 'block';
|
|
116
|
-
remainingTrack.style.height = `${remainingWidth}%`;
|
|
117
|
-
remainingTrack.style.bottom = `${valuePercent + paddingPercent}%`;
|
|
118
|
-
remainingTrack.style.width = '100%';
|
|
119
|
-
} else {
|
|
120
|
-
// Horizontal orientation
|
|
121
|
-
startTrack.style.display = 'none';
|
|
122
|
-
|
|
123
|
-
activeTrack.style.display = 'block';
|
|
124
|
-
activeTrack.style.width = `${adjustedWidth}%`;
|
|
125
|
-
activeTrack.style.left = '0';
|
|
126
|
-
activeTrack.style.height = '100%';
|
|
127
|
-
|
|
128
|
-
remainingTrack.style.display = 'block';
|
|
129
|
-
remainingTrack.style.width = `${remainingWidth}%`;
|
|
130
|
-
remainingTrack.style.left = `${valuePercent + paddingPercent}%`;
|
|
131
|
-
remainingTrack.style.height = '100%';
|
|
132
|
-
}
|
|
133
|
-
}
|
|
37
|
+
const endDot = createElement('slider-dot');
|
|
38
|
+
endDot.classList.add(component.getClass('slider-dot--end'));
|
|
134
39
|
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
40
|
+
// Create value bubble and format the value
|
|
41
|
+
const formatter = config.valueFormatter || (val => val.toString());
|
|
42
|
+
const valueBubble = createElement('slider-value');
|
|
43
|
+
valueBubble.textContent = formatter(value);
|
|
139
44
|
|
|
140
|
-
// Create thumb element
|
|
141
|
-
const thumb =
|
|
142
|
-
thumb.classList.add(component.getClass('slider-thumb'));
|
|
143
|
-
thumb.setAttribute('tabindex', '0');
|
|
45
|
+
// Create thumb element with improved accessibility attributes
|
|
46
|
+
const thumb = createElement('slider-thumb');
|
|
144
47
|
thumb.setAttribute('role', 'slider');
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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');
|
|
153
57
|
}
|
|
154
58
|
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
startDot.classList.add(component.getClass('slider-dot'));
|
|
158
|
-
startDot.classList.add(component.getClass('slider-dot--start'));
|
|
159
|
-
|
|
160
|
-
const endDot = document.createElement('div');
|
|
161
|
-
endDot.classList.add(component.getClass('slider-dot'));
|
|
162
|
-
endDot.classList.add(component.getClass('slider-dot--end'));
|
|
163
|
-
|
|
164
|
-
// Create value bubble element
|
|
165
|
-
const valueBubble = document.createElement('div');
|
|
166
|
-
valueBubble.classList.add(component.getClass('slider-value'));
|
|
59
|
+
// Set initial thumb position
|
|
60
|
+
thumb.style.left = `${valuePercent}%`;
|
|
167
61
|
|
|
168
|
-
//
|
|
169
|
-
const
|
|
170
|
-
|
|
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;
|
|
171
66
|
|
|
172
|
-
//
|
|
67
|
+
// Create second thumb and value bubble for range slider
|
|
173
68
|
let secondThumb = null;
|
|
174
69
|
let secondValueBubble = null;
|
|
175
70
|
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
secondThumb = document.createElement('div');
|
|
179
|
-
secondThumb.classList.add(component.getClass('slider-thumb'));
|
|
180
|
-
secondThumb.setAttribute('tabindex', '0');
|
|
71
|
+
if (isRangeSlider) {
|
|
72
|
+
secondThumb = createElement('slider-thumb');
|
|
181
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');
|
|
182
78
|
|
|
183
|
-
// Set
|
|
184
|
-
|
|
185
|
-
if (
|
|
186
|
-
secondThumb.
|
|
187
|
-
secondThumb.style.left = '50%';
|
|
188
|
-
secondThumb.style.top = 'auto';
|
|
189
|
-
} else {
|
|
190
|
-
secondThumb.style.left = `${secondPercent}%`;
|
|
79
|
+
// Set tabindex based on disabled state
|
|
80
|
+
secondThumb.setAttribute('tabindex', isDisabled ? '-1' : '0');
|
|
81
|
+
if (isDisabled) {
|
|
82
|
+
secondThumb.setAttribute('aria-disabled', 'true');
|
|
191
83
|
}
|
|
192
84
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
85
|
+
const secondPercent = getPercentage(secondValue);
|
|
86
|
+
secondThumb.style.left = `${secondPercent}%`;
|
|
87
|
+
|
|
88
|
+
secondValueBubble = createElement('slider-value');
|
|
196
89
|
secondValueBubble.textContent = formatter(secondValue);
|
|
197
90
|
}
|
|
198
91
|
|
|
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);
|
|
99
|
+
|
|
199
100
|
// Add elements to the slider
|
|
200
101
|
component.element.classList.add(component.getClass('slider'));
|
|
102
|
+
|
|
103
|
+
// Accessibility enhancement: Container is not focusable
|
|
104
|
+
component.element.setAttribute('tabindex', '-1');
|
|
105
|
+
|
|
106
|
+
// Set container aria attributes
|
|
107
|
+
component.element.setAttribute('role', 'none');
|
|
108
|
+
component.element.setAttribute('aria-disabled', isDisabled ? 'true' : 'false');
|
|
109
|
+
|
|
201
110
|
component.element.appendChild(track);
|
|
111
|
+
component.element.appendChild(ticksContainer); // Add ticks container
|
|
202
112
|
component.element.appendChild(startDot);
|
|
203
113
|
component.element.appendChild(endDot);
|
|
204
114
|
component.element.appendChild(thumb);
|
|
205
115
|
component.element.appendChild(valueBubble);
|
|
206
116
|
|
|
207
|
-
if (
|
|
117
|
+
if (isRangeSlider && secondThumb && secondValueBubble) {
|
|
208
118
|
component.element.classList.add(`${component.getClass('slider')}--range`);
|
|
209
119
|
component.element.appendChild(secondThumb);
|
|
210
120
|
component.element.appendChild(secondValueBubble);
|
|
211
121
|
}
|
|
212
122
|
|
|
213
|
-
// Apply
|
|
214
|
-
|
|
215
|
-
if (size !== SLIDER_SIZES.MEDIUM) {
|
|
216
|
-
component.element.classList.add(`${component.getClass('slider')}--${size}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Apply color class
|
|
220
|
-
const color = config.color || SLIDER_COLORS.PRIMARY;
|
|
221
|
-
if (color !== SLIDER_COLORS.PRIMARY) {
|
|
222
|
-
component.element.classList.add(`${component.getClass('slider')}--${color}`);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Apply orientation class
|
|
226
|
-
const orientation = config.orientation || SLIDER_ORIENTATIONS.HORIZONTAL;
|
|
227
|
-
if (orientation === SLIDER_ORIENTATIONS.VERTICAL) {
|
|
228
|
-
component.element.classList.add(`${component.getClass('slider')}--vertical`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Apply discrete class if step is specified
|
|
232
|
-
if (config.step !== undefined && config.step > 0) {
|
|
233
|
-
component.element.classList.add(`${component.getClass('slider')}--discrete`);
|
|
234
|
-
}
|
|
123
|
+
// Apply styling classes
|
|
124
|
+
applyStyleClasses();
|
|
235
125
|
|
|
236
|
-
//
|
|
237
|
-
if (config.disabled) {
|
|
238
|
-
component.element.classList.add(`${component.getClass('slider')}--disabled`);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Ensure proper initialization after DOM is attached by scheduling a UI update
|
|
126
|
+
// Schedule UI update after DOM is attached
|
|
242
127
|
setTimeout(() => {
|
|
243
|
-
|
|
244
|
-
component.slider.updateUi();
|
|
245
|
-
}
|
|
128
|
+
component.slider?.updateUi?.();
|
|
246
129
|
}, 0);
|
|
247
130
|
|
|
248
|
-
//
|
|
131
|
+
// Return enhanced component with structure
|
|
249
132
|
return {
|
|
250
133
|
...component,
|
|
251
134
|
structure: {
|
|
@@ -253,6 +136,7 @@ export const withStructure = (config: SliderConfig) => component => {
|
|
|
253
136
|
activeTrack,
|
|
254
137
|
startTrack,
|
|
255
138
|
remainingTrack,
|
|
139
|
+
ticksContainer,
|
|
256
140
|
thumb,
|
|
257
141
|
valueBubble,
|
|
258
142
|
secondThumb,
|
|
@@ -261,4 +145,107 @@ export const withStructure = (config: SliderConfig) => component => {
|
|
|
261
145
|
endDot
|
|
262
146
|
}
|
|
263
147
|
};
|
|
148
|
+
|
|
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;
|
|
158
|
+
}
|
|
159
|
+
|
|
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
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
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%';
|
|
221
|
+
}
|
|
222
|
+
|
|
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
|
+
}
|
|
250
|
+
}
|
|
264
251
|
};
|