mithril-materialized 2.0.0-beta.12 → 2.0.0-beta.14
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/README.md +35 -1
- package/dist/forms.css +325 -0
- package/dist/index.css +326 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +832 -3
- package/dist/index.js +833 -2
- package/dist/index.min.css +1 -1
- package/dist/index.umd.js +833 -2
- package/dist/input-options.d.ts +18 -4
- package/dist/range-slider.d.ts +4 -0
- package/package.json +2 -2
- package/sass/components/forms/_forms.scss +1 -1
- package/sass/components/forms/_range-enhanced.scss +393 -0
- package/sass/materialize.scss +1 -0
package/dist/index.js
CHANGED
|
@@ -2192,6 +2192,12 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
2192
2192
|
isValid: true,
|
|
2193
2193
|
active: false,
|
|
2194
2194
|
inputElement: null,
|
|
2195
|
+
// Range-specific state
|
|
2196
|
+
rangeMinValue: undefined,
|
|
2197
|
+
rangeMaxValue: undefined,
|
|
2198
|
+
singleValue: undefined,
|
|
2199
|
+
isDragging: false,
|
|
2200
|
+
activeThumb: null,
|
|
2195
2201
|
};
|
|
2196
2202
|
// let labelManager: { updateLabelState: () => void; cleanup: () => void } | null = null;
|
|
2197
2203
|
// let lengthUpdateHandler: (() => void) | null = null;
|
|
@@ -2217,6 +2223,397 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
2217
2223
|
state.hasInteracted = length > 0;
|
|
2218
2224
|
}
|
|
2219
2225
|
};
|
|
2226
|
+
// Range slider helper functions
|
|
2227
|
+
const getPercentage = (value, min, max) => {
|
|
2228
|
+
return ((value - min) / (max - min)) * 100;
|
|
2229
|
+
};
|
|
2230
|
+
const updateRangeValues = (minValue, maxValue, attrs, immediate = false) => {
|
|
2231
|
+
// Ensure min doesn't exceed max and vice versa
|
|
2232
|
+
if (minValue > maxValue)
|
|
2233
|
+
minValue = maxValue;
|
|
2234
|
+
if (maxValue < minValue)
|
|
2235
|
+
maxValue = minValue;
|
|
2236
|
+
state.rangeMinValue = minValue;
|
|
2237
|
+
state.rangeMaxValue = maxValue;
|
|
2238
|
+
// Call oninput for immediate feedback or onchange for final changes
|
|
2239
|
+
if (immediate && attrs.oninput) {
|
|
2240
|
+
attrs.oninput(minValue, maxValue);
|
|
2241
|
+
}
|
|
2242
|
+
else if (!immediate && attrs.onchange) {
|
|
2243
|
+
attrs.onchange(minValue, maxValue);
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
// Render function for single range slider with tooltip
|
|
2247
|
+
const renderSingleRangeWithTooltip = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
2248
|
+
const { min = 0, max = 100, step = 1, initialValue, vertical = false, showValue = false, height = '200px', disabled = false, oninput, onchange, } = attrs;
|
|
2249
|
+
// Initialize single range value
|
|
2250
|
+
const currentValue = initialValue !== undefined ? initialValue : state.singleValue || min;
|
|
2251
|
+
if (state.singleValue === undefined) {
|
|
2252
|
+
state.singleValue = currentValue;
|
|
2253
|
+
}
|
|
2254
|
+
const percentage = getPercentage(state.singleValue, min, max);
|
|
2255
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
2256
|
+
const containerStyle = vertical ? { height } : {};
|
|
2257
|
+
const progressStyle = vertical
|
|
2258
|
+
? {
|
|
2259
|
+
height: `${percentage}%`,
|
|
2260
|
+
}
|
|
2261
|
+
: {
|
|
2262
|
+
width: `${percentage}%`,
|
|
2263
|
+
};
|
|
2264
|
+
const thumbStyle = vertical
|
|
2265
|
+
? {
|
|
2266
|
+
bottom: `${percentage}%`,
|
|
2267
|
+
}
|
|
2268
|
+
: {
|
|
2269
|
+
left: `${percentage}%`,
|
|
2270
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
2271
|
+
};
|
|
2272
|
+
const updateSingleValue = (newValue, immediate = false) => {
|
|
2273
|
+
state.singleValue = newValue;
|
|
2274
|
+
if (immediate && oninput) {
|
|
2275
|
+
oninput(newValue);
|
|
2276
|
+
}
|
|
2277
|
+
else if (!immediate && onchange) {
|
|
2278
|
+
onchange(newValue);
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
const handleMouseDown = (e) => {
|
|
2282
|
+
if (disabled)
|
|
2283
|
+
return;
|
|
2284
|
+
e.preventDefault();
|
|
2285
|
+
state.isDragging = true;
|
|
2286
|
+
// Get container reference from the current target's parent
|
|
2287
|
+
const thumbElement = e.currentTarget;
|
|
2288
|
+
const container = thumbElement.parentElement;
|
|
2289
|
+
if (!container)
|
|
2290
|
+
return;
|
|
2291
|
+
const handleMouseMove = (e) => {
|
|
2292
|
+
if (!state.isDragging || !container)
|
|
2293
|
+
return;
|
|
2294
|
+
const rect = container.getBoundingClientRect();
|
|
2295
|
+
let percentage;
|
|
2296
|
+
if (vertical) {
|
|
2297
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
2298
|
+
}
|
|
2299
|
+
else {
|
|
2300
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
2301
|
+
}
|
|
2302
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
2303
|
+
const value = min + (percentage / 100) * (max - min);
|
|
2304
|
+
const steppedValue = Math.round(value / step) * step;
|
|
2305
|
+
updateSingleValue(steppedValue, true);
|
|
2306
|
+
// Redraw to update the UI
|
|
2307
|
+
m.redraw();
|
|
2308
|
+
};
|
|
2309
|
+
const handleMouseUp = () => {
|
|
2310
|
+
state.isDragging = false;
|
|
2311
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
2312
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
2313
|
+
// Fire onchange when dragging ends
|
|
2314
|
+
updateSingleValue(state.singleValue, false);
|
|
2315
|
+
};
|
|
2316
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
2317
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
2318
|
+
};
|
|
2319
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
2320
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
2321
|
+
return m('.input-field', { className: cn, style }, [
|
|
2322
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2323
|
+
// Hidden input for label association and accessibility
|
|
2324
|
+
m('input[type=range]', {
|
|
2325
|
+
id,
|
|
2326
|
+
value: state.singleValue,
|
|
2327
|
+
min,
|
|
2328
|
+
max,
|
|
2329
|
+
step,
|
|
2330
|
+
style: { display: 'none' },
|
|
2331
|
+
disabled,
|
|
2332
|
+
tabindex: -1,
|
|
2333
|
+
}),
|
|
2334
|
+
m('div', { class: fieldClass, style: containerStyle }, [
|
|
2335
|
+
m(`.single-range-slider.${orientation}`, {
|
|
2336
|
+
tabindex: disabled ? -1 : 0,
|
|
2337
|
+
role: 'slider',
|
|
2338
|
+
'aria-valuemin': min,
|
|
2339
|
+
'aria-valuemax': max,
|
|
2340
|
+
'aria-valuenow': state.singleValue,
|
|
2341
|
+
'aria-label': label || 'Range slider',
|
|
2342
|
+
onclick: (e) => {
|
|
2343
|
+
// Focus the slider when clicked
|
|
2344
|
+
e.currentTarget.focus();
|
|
2345
|
+
},
|
|
2346
|
+
onkeydown: (e) => {
|
|
2347
|
+
if (disabled)
|
|
2348
|
+
return;
|
|
2349
|
+
let newValue = state.singleValue;
|
|
2350
|
+
switch (e.key) {
|
|
2351
|
+
case 'ArrowLeft':
|
|
2352
|
+
case 'ArrowDown':
|
|
2353
|
+
e.preventDefault();
|
|
2354
|
+
newValue = Math.max(min, newValue - step);
|
|
2355
|
+
updateSingleValue(newValue, false);
|
|
2356
|
+
m.redraw();
|
|
2357
|
+
break;
|
|
2358
|
+
case 'ArrowRight':
|
|
2359
|
+
case 'ArrowUp':
|
|
2360
|
+
e.preventDefault();
|
|
2361
|
+
newValue = Math.min(max, newValue + step);
|
|
2362
|
+
updateSingleValue(newValue, false);
|
|
2363
|
+
m.redraw();
|
|
2364
|
+
break;
|
|
2365
|
+
case 'Home':
|
|
2366
|
+
e.preventDefault();
|
|
2367
|
+
updateSingleValue(min, false);
|
|
2368
|
+
m.redraw();
|
|
2369
|
+
break;
|
|
2370
|
+
case 'End':
|
|
2371
|
+
e.preventDefault();
|
|
2372
|
+
updateSingleValue(max, false);
|
|
2373
|
+
m.redraw();
|
|
2374
|
+
break;
|
|
2375
|
+
}
|
|
2376
|
+
},
|
|
2377
|
+
}, [
|
|
2378
|
+
// Track
|
|
2379
|
+
m(`.track.${orientation}`),
|
|
2380
|
+
// Progress
|
|
2381
|
+
m(`.range-progress.${orientation}`, { style: progressStyle }),
|
|
2382
|
+
// Thumb
|
|
2383
|
+
m(`.thumb.${orientation}`, {
|
|
2384
|
+
style: thumbStyle,
|
|
2385
|
+
onmousedown: handleMouseDown,
|
|
2386
|
+
}, showValue
|
|
2387
|
+
? m(`.value-tooltip.${vertical ? 'right' : 'top'}`, state.singleValue.toFixed(0))
|
|
2388
|
+
: null),
|
|
2389
|
+
]),
|
|
2390
|
+
]),
|
|
2391
|
+
label
|
|
2392
|
+
? m(Label, {
|
|
2393
|
+
label,
|
|
2394
|
+
id,
|
|
2395
|
+
isMandatory,
|
|
2396
|
+
isActive: true, // Range sliders always have active labels
|
|
2397
|
+
})
|
|
2398
|
+
: null,
|
|
2399
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
2400
|
+
]);
|
|
2401
|
+
};
|
|
2402
|
+
// Render function for minmax range slider
|
|
2403
|
+
const renderMinMaxRange = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
2404
|
+
const { min = 0, max = 100, step = 1, minValue, maxValue, vertical = false, showValue = false, height = '200px', disabled = false, } = attrs;
|
|
2405
|
+
// Initialize range values
|
|
2406
|
+
const currentMinValue = minValue !== undefined ? minValue : attrs.minValue || min;
|
|
2407
|
+
const currentMaxValue = maxValue !== undefined ? maxValue : attrs.maxValue || max;
|
|
2408
|
+
if (state.rangeMinValue === undefined || state.rangeMaxValue === undefined) {
|
|
2409
|
+
state.rangeMinValue = currentMinValue;
|
|
2410
|
+
state.rangeMaxValue = currentMaxValue;
|
|
2411
|
+
}
|
|
2412
|
+
// Initialize active thumb if not set
|
|
2413
|
+
if (state.activeThumb === null) {
|
|
2414
|
+
state.activeThumb = 'min';
|
|
2415
|
+
}
|
|
2416
|
+
const minPercentage = getPercentage(state.rangeMinValue, min, max);
|
|
2417
|
+
const maxPercentage = getPercentage(state.rangeMaxValue, min, max);
|
|
2418
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
2419
|
+
const containerStyle = vertical ? { height } : {};
|
|
2420
|
+
const rangeStyle = vertical
|
|
2421
|
+
? {
|
|
2422
|
+
bottom: `${minPercentage}%`,
|
|
2423
|
+
height: `${maxPercentage - minPercentage}%`,
|
|
2424
|
+
}
|
|
2425
|
+
: {
|
|
2426
|
+
left: `${minPercentage}%`,
|
|
2427
|
+
width: `${maxPercentage - minPercentage}%`,
|
|
2428
|
+
};
|
|
2429
|
+
// Only keep dynamic positioning and z-index as inline styles
|
|
2430
|
+
const createThumbStyle = (percentage, isActive) => vertical
|
|
2431
|
+
? {
|
|
2432
|
+
bottom: `${percentage}%`,
|
|
2433
|
+
zIndex: isActive ? 10 : 5,
|
|
2434
|
+
}
|
|
2435
|
+
: {
|
|
2436
|
+
left: `${percentage}%`,
|
|
2437
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
2438
|
+
zIndex: isActive ? 10 : 5,
|
|
2439
|
+
};
|
|
2440
|
+
const handleMouseDown = (thumb) => (e) => {
|
|
2441
|
+
if (disabled)
|
|
2442
|
+
return;
|
|
2443
|
+
e.preventDefault();
|
|
2444
|
+
state.isDragging = true;
|
|
2445
|
+
state.activeThumb = thumb;
|
|
2446
|
+
// Get container reference from the current target's parent
|
|
2447
|
+
const thumbElement = e.currentTarget;
|
|
2448
|
+
const container = thumbElement.parentElement;
|
|
2449
|
+
if (!container)
|
|
2450
|
+
return;
|
|
2451
|
+
const handleMouseMove = (e) => {
|
|
2452
|
+
if (!state.isDragging || !container)
|
|
2453
|
+
return;
|
|
2454
|
+
const rect = container.getBoundingClientRect();
|
|
2455
|
+
let percentage;
|
|
2456
|
+
if (vertical) {
|
|
2457
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
2458
|
+
}
|
|
2459
|
+
else {
|
|
2460
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
2461
|
+
}
|
|
2462
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
2463
|
+
const value = min + (percentage / 100) * (max - min);
|
|
2464
|
+
const steppedValue = Math.round(value / step) * step;
|
|
2465
|
+
if (thumb === 'min') {
|
|
2466
|
+
updateRangeValues(Math.min(steppedValue, state.rangeMaxValue), state.rangeMaxValue, attrs, true);
|
|
2467
|
+
}
|
|
2468
|
+
else {
|
|
2469
|
+
updateRangeValues(state.rangeMinValue, Math.max(steppedValue, state.rangeMinValue), attrs, true);
|
|
2470
|
+
}
|
|
2471
|
+
// Redraw to update the UI
|
|
2472
|
+
m.redraw();
|
|
2473
|
+
};
|
|
2474
|
+
const handleMouseUp = () => {
|
|
2475
|
+
state.isDragging = false;
|
|
2476
|
+
state.activeThumb = null;
|
|
2477
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
2478
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
2479
|
+
// Fire onchange when dragging ends
|
|
2480
|
+
updateRangeValues(state.rangeMinValue, state.rangeMaxValue, attrs, false);
|
|
2481
|
+
};
|
|
2482
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
2483
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
2484
|
+
};
|
|
2485
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
2486
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
2487
|
+
return m('.input-field', { className: cn, style }, [
|
|
2488
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2489
|
+
// Hidden inputs for label association and accessibility
|
|
2490
|
+
m('input[type=range]', {
|
|
2491
|
+
id,
|
|
2492
|
+
value: state.rangeMinValue,
|
|
2493
|
+
min,
|
|
2494
|
+
max,
|
|
2495
|
+
step,
|
|
2496
|
+
style: { display: 'none' },
|
|
2497
|
+
disabled,
|
|
2498
|
+
tabindex: -1,
|
|
2499
|
+
}),
|
|
2500
|
+
m('input[type=range]', {
|
|
2501
|
+
id: `${id}_max`,
|
|
2502
|
+
value: state.rangeMaxValue,
|
|
2503
|
+
min,
|
|
2504
|
+
max,
|
|
2505
|
+
step,
|
|
2506
|
+
style: { display: 'none' },
|
|
2507
|
+
disabled,
|
|
2508
|
+
tabindex: -1,
|
|
2509
|
+
}),
|
|
2510
|
+
m(`.${fieldClass}`, [
|
|
2511
|
+
m(`.double-range-slider.${orientation}`, {
|
|
2512
|
+
style: containerStyle,
|
|
2513
|
+
tabindex: disabled ? -1 : 0,
|
|
2514
|
+
role: 'slider',
|
|
2515
|
+
'aria-valuemin': min,
|
|
2516
|
+
'aria-valuemax': max,
|
|
2517
|
+
'aria-valuenow': state.rangeMinValue,
|
|
2518
|
+
'aria-valuetext': `${state.rangeMinValue} to ${state.rangeMaxValue}`,
|
|
2519
|
+
'aria-label': label || 'Range slider',
|
|
2520
|
+
onclick: (e) => {
|
|
2521
|
+
// Focus the slider when clicked
|
|
2522
|
+
e.currentTarget.focus();
|
|
2523
|
+
},
|
|
2524
|
+
onkeydown: (e) => {
|
|
2525
|
+
if (disabled)
|
|
2526
|
+
return;
|
|
2527
|
+
let newMinValue = state.rangeMinValue;
|
|
2528
|
+
let newMaxValue = state.rangeMaxValue;
|
|
2529
|
+
const activeThumb = state.activeThumb || 'min';
|
|
2530
|
+
switch (e.key) {
|
|
2531
|
+
case 'ArrowLeft':
|
|
2532
|
+
case 'ArrowDown':
|
|
2533
|
+
e.preventDefault();
|
|
2534
|
+
if (activeThumb === 'min') {
|
|
2535
|
+
newMinValue = Math.max(min, newMinValue - step);
|
|
2536
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2537
|
+
}
|
|
2538
|
+
else {
|
|
2539
|
+
newMaxValue = Math.max(newMinValue, newMaxValue - step);
|
|
2540
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2541
|
+
}
|
|
2542
|
+
m.redraw();
|
|
2543
|
+
break;
|
|
2544
|
+
case 'ArrowRight':
|
|
2545
|
+
case 'ArrowUp':
|
|
2546
|
+
e.preventDefault();
|
|
2547
|
+
if (activeThumb === 'min') {
|
|
2548
|
+
newMinValue = Math.min(newMaxValue, newMinValue + step);
|
|
2549
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2550
|
+
}
|
|
2551
|
+
else {
|
|
2552
|
+
newMaxValue = Math.min(max, newMaxValue + step);
|
|
2553
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2554
|
+
}
|
|
2555
|
+
m.redraw();
|
|
2556
|
+
break;
|
|
2557
|
+
// Remove Tab case - let normal tab navigation work
|
|
2558
|
+
// Users can click on specific thumbs to activate them
|
|
2559
|
+
case 'Home':
|
|
2560
|
+
e.preventDefault();
|
|
2561
|
+
if (activeThumb === 'min') {
|
|
2562
|
+
updateRangeValues(min, newMaxValue, attrs, false);
|
|
2563
|
+
}
|
|
2564
|
+
else {
|
|
2565
|
+
updateRangeValues(newMinValue, newMinValue, attrs, false);
|
|
2566
|
+
}
|
|
2567
|
+
m.redraw();
|
|
2568
|
+
break;
|
|
2569
|
+
case 'End':
|
|
2570
|
+
e.preventDefault();
|
|
2571
|
+
if (activeThumb === 'min') {
|
|
2572
|
+
updateRangeValues(newMaxValue, newMaxValue, attrs, false);
|
|
2573
|
+
}
|
|
2574
|
+
else {
|
|
2575
|
+
updateRangeValues(newMinValue, max, attrs, false);
|
|
2576
|
+
}
|
|
2577
|
+
m.redraw();
|
|
2578
|
+
break;
|
|
2579
|
+
}
|
|
2580
|
+
},
|
|
2581
|
+
}, [
|
|
2582
|
+
// Track
|
|
2583
|
+
m(`.track.${orientation}`),
|
|
2584
|
+
// Range
|
|
2585
|
+
m(`.range.${orientation}`, { style: rangeStyle }),
|
|
2586
|
+
// Min thumb
|
|
2587
|
+
m(`.thumb.${orientation}.min-thumb${state.activeThumb === 'min' ? '.active' : ''}`, {
|
|
2588
|
+
style: createThumbStyle(minPercentage, state.activeThumb === 'min'),
|
|
2589
|
+
onmousedown: handleMouseDown('min'),
|
|
2590
|
+
onclick: () => {
|
|
2591
|
+
state.activeThumb = 'min';
|
|
2592
|
+
m.redraw();
|
|
2593
|
+
},
|
|
2594
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMinValue.toFixed(0)) : null),
|
|
2595
|
+
// Max thumb
|
|
2596
|
+
m(`.thumb.${orientation}.max-thumb${state.activeThumb === 'max' ? '.active' : ''}`, {
|
|
2597
|
+
style: createThumbStyle(maxPercentage, state.activeThumb === 'max'),
|
|
2598
|
+
onmousedown: handleMouseDown('max'),
|
|
2599
|
+
onclick: () => {
|
|
2600
|
+
state.activeThumb = 'max';
|
|
2601
|
+
m.redraw();
|
|
2602
|
+
},
|
|
2603
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMaxValue.toFixed(0)) : null),
|
|
2604
|
+
]),
|
|
2605
|
+
]),
|
|
2606
|
+
label
|
|
2607
|
+
? m(Label, {
|
|
2608
|
+
label,
|
|
2609
|
+
id,
|
|
2610
|
+
isMandatory,
|
|
2611
|
+
isActive: true, // Range sliders always have active labels
|
|
2612
|
+
})
|
|
2613
|
+
: null,
|
|
2614
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
2615
|
+
]);
|
|
2616
|
+
};
|
|
2220
2617
|
return {
|
|
2221
2618
|
view: ({ attrs }) => {
|
|
2222
2619
|
var _a;
|
|
@@ -2226,10 +2623,25 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
2226
2623
|
const isActive = state.active || ((_a = state.inputElement) === null || _a === void 0 ? void 0 : _a.value) || placeholder || type === 'color' || type === 'range'
|
|
2227
2624
|
? true
|
|
2228
2625
|
: false;
|
|
2626
|
+
// Special rendering for minmax range sliders
|
|
2627
|
+
if (type === 'range' && attrs.minmax) {
|
|
2628
|
+
return renderMinMaxRange(attrs, state, cn, style, iconName, id, label, isMandatory, helperText);
|
|
2629
|
+
}
|
|
2630
|
+
// Special rendering for single range sliders with tooltips
|
|
2631
|
+
if (type === 'range' && attrs.showValue) {
|
|
2632
|
+
return renderSingleRangeWithTooltip(attrs, state, cn, style, iconName, id, label, isMandatory, helperText);
|
|
2633
|
+
}
|
|
2229
2634
|
return m('.input-field', { className: cn, style }, [
|
|
2230
2635
|
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2231
2636
|
m('input.validate', Object.assign(Object.assign({}, params), { type, tabindex: 0, id,
|
|
2232
|
-
placeholder,
|
|
2637
|
+
placeholder, class: type === 'range' && attrs.vertical ? 'range-slider vertical' : undefined, style: type === 'range' && attrs.vertical
|
|
2638
|
+
? {
|
|
2639
|
+
height: attrs.height || '200px',
|
|
2640
|
+
width: '6px',
|
|
2641
|
+
writingMode: 'vertical-lr',
|
|
2642
|
+
direction: 'rtl',
|
|
2643
|
+
}
|
|
2644
|
+
: undefined,
|
|
2233
2645
|
// attributes,
|
|
2234
2646
|
oncreate: ({ dom }) => {
|
|
2235
2647
|
const input = (state.inputElement = dom);
|
|
@@ -2245,7 +2657,7 @@ const InputField = (type, defaultClass = '') => () => {
|
|
|
2245
2657
|
state.currentLength = input.value.length; // Initial count
|
|
2246
2658
|
}
|
|
2247
2659
|
// Range input functionality
|
|
2248
|
-
if (type === 'range') {
|
|
2660
|
+
if (type === 'range' && !attrs.minmax) {
|
|
2249
2661
|
const updateThumb = () => {
|
|
2250
2662
|
const value = input.value;
|
|
2251
2663
|
const min = input.min || '0';
|
|
@@ -3369,6 +3781,423 @@ const FloatingActionButton = () => {
|
|
|
3369
3781
|
};
|
|
3370
3782
|
};
|
|
3371
3783
|
|
|
3784
|
+
// Utility functions
|
|
3785
|
+
const getPercentage = (value, min, max) => {
|
|
3786
|
+
return ((value - min) / (max - min)) * 100;
|
|
3787
|
+
};
|
|
3788
|
+
const updateRangeValues = (minValue, maxValue, attrs, state, immediate) => {
|
|
3789
|
+
// Ensure min doesn't exceed max and vice versa
|
|
3790
|
+
if (minValue > maxValue)
|
|
3791
|
+
minValue = maxValue;
|
|
3792
|
+
if (maxValue < minValue)
|
|
3793
|
+
maxValue = minValue;
|
|
3794
|
+
state.rangeMinValue = minValue;
|
|
3795
|
+
state.rangeMaxValue = maxValue;
|
|
3796
|
+
// Call oninput for immediate feedback or onchange for final changes
|
|
3797
|
+
if (immediate && attrs.oninput) {
|
|
3798
|
+
attrs.oninput(minValue, maxValue);
|
|
3799
|
+
}
|
|
3800
|
+
else if (!immediate && attrs.onchange) {
|
|
3801
|
+
attrs.onchange(minValue, maxValue);
|
|
3802
|
+
}
|
|
3803
|
+
};
|
|
3804
|
+
// Single Range Slider with Tooltip
|
|
3805
|
+
const renderSingleRangeWithTooltip = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
3806
|
+
const { min = 0, max = 100, step = 1, initialValue, vertical = false, showValue = false, height = '200px', disabled = false, tooltipPos = 'top', oninput, onchange, } = attrs;
|
|
3807
|
+
// Initialize single range value
|
|
3808
|
+
const currentValue = initialValue !== undefined ? initialValue : state.singleValue || min;
|
|
3809
|
+
if (state.singleValue === undefined) {
|
|
3810
|
+
state.singleValue = currentValue;
|
|
3811
|
+
}
|
|
3812
|
+
const percentage = getPercentage(state.singleValue, min, max);
|
|
3813
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
3814
|
+
const containerStyle = vertical ? { height } : {};
|
|
3815
|
+
const progressStyle = vertical
|
|
3816
|
+
? {
|
|
3817
|
+
height: `${percentage}%`,
|
|
3818
|
+
}
|
|
3819
|
+
: {
|
|
3820
|
+
width: `${percentage}%`,
|
|
3821
|
+
};
|
|
3822
|
+
const thumbStyle = vertical
|
|
3823
|
+
? {
|
|
3824
|
+
bottom: `${percentage}%`,
|
|
3825
|
+
}
|
|
3826
|
+
: {
|
|
3827
|
+
left: `${percentage}%`,
|
|
3828
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
3829
|
+
};
|
|
3830
|
+
const updateSingleValue = (newValue, immediate = false) => {
|
|
3831
|
+
state.singleValue = newValue;
|
|
3832
|
+
if (immediate && oninput) {
|
|
3833
|
+
oninput(newValue);
|
|
3834
|
+
}
|
|
3835
|
+
else if (!immediate && onchange) {
|
|
3836
|
+
onchange(newValue);
|
|
3837
|
+
}
|
|
3838
|
+
};
|
|
3839
|
+
const handleMouseDown = (e) => {
|
|
3840
|
+
if (disabled)
|
|
3841
|
+
return;
|
|
3842
|
+
e.preventDefault();
|
|
3843
|
+
state.isDragging = true;
|
|
3844
|
+
// Get container reference from the current target's parent
|
|
3845
|
+
const thumbElement = e.currentTarget;
|
|
3846
|
+
const container = thumbElement.parentElement;
|
|
3847
|
+
if (!container)
|
|
3848
|
+
return;
|
|
3849
|
+
const handleMouseMove = (e) => {
|
|
3850
|
+
if (!state.isDragging || !container)
|
|
3851
|
+
return;
|
|
3852
|
+
const rect = container.getBoundingClientRect();
|
|
3853
|
+
let percentage;
|
|
3854
|
+
if (vertical) {
|
|
3855
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
3856
|
+
}
|
|
3857
|
+
else {
|
|
3858
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
3859
|
+
}
|
|
3860
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
3861
|
+
const value = min + (percentage / 100) * (max - min);
|
|
3862
|
+
const steppedValue = Math.round(value / step) * step;
|
|
3863
|
+
updateSingleValue(steppedValue, true);
|
|
3864
|
+
// Redraw to update the UI during drag
|
|
3865
|
+
m.redraw();
|
|
3866
|
+
};
|
|
3867
|
+
const handleMouseUp = () => {
|
|
3868
|
+
state.isDragging = false;
|
|
3869
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
3870
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
3871
|
+
// Fire onchange when dragging ends
|
|
3872
|
+
updateSingleValue(state.singleValue, false);
|
|
3873
|
+
};
|
|
3874
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
3875
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
3876
|
+
};
|
|
3877
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
3878
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
3879
|
+
// Determine tooltip position for vertical sliders
|
|
3880
|
+
const tooltipPosition = vertical ? (tooltipPos === 'top' || tooltipPos === 'bottom' ? 'right' : tooltipPos) : tooltipPos;
|
|
3881
|
+
return m('.input-field', { className: cn, style }, [
|
|
3882
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
3883
|
+
// Hidden input for label association and accessibility
|
|
3884
|
+
m('input[type=range]', {
|
|
3885
|
+
id,
|
|
3886
|
+
value: state.singleValue,
|
|
3887
|
+
min,
|
|
3888
|
+
max,
|
|
3889
|
+
step,
|
|
3890
|
+
style: { display: 'none' },
|
|
3891
|
+
disabled,
|
|
3892
|
+
tabindex: -1,
|
|
3893
|
+
}),
|
|
3894
|
+
m('div', { class: fieldClass, style: containerStyle }, [
|
|
3895
|
+
m(`.single-range-slider.${orientation}`, {
|
|
3896
|
+
tabindex: disabled ? -1 : 0,
|
|
3897
|
+
role: 'slider',
|
|
3898
|
+
'aria-valuemin': min,
|
|
3899
|
+
'aria-valuemax': max,
|
|
3900
|
+
'aria-valuenow': state.singleValue,
|
|
3901
|
+
'aria-label': label || 'Range slider',
|
|
3902
|
+
onclick: (e) => {
|
|
3903
|
+
// Focus the slider when clicked
|
|
3904
|
+
e.currentTarget.focus();
|
|
3905
|
+
},
|
|
3906
|
+
onkeydown: (e) => {
|
|
3907
|
+
if (disabled)
|
|
3908
|
+
return;
|
|
3909
|
+
let newValue = state.singleValue;
|
|
3910
|
+
switch (e.key) {
|
|
3911
|
+
case 'ArrowLeft':
|
|
3912
|
+
case 'ArrowDown':
|
|
3913
|
+
e.preventDefault();
|
|
3914
|
+
newValue = Math.max(min, newValue - step);
|
|
3915
|
+
updateSingleValue(newValue, false);
|
|
3916
|
+
// m.redraw();
|
|
3917
|
+
break;
|
|
3918
|
+
case 'ArrowRight':
|
|
3919
|
+
case 'ArrowUp':
|
|
3920
|
+
e.preventDefault();
|
|
3921
|
+
newValue = Math.min(max, newValue + step);
|
|
3922
|
+
updateSingleValue(newValue, false);
|
|
3923
|
+
// m.redraw();
|
|
3924
|
+
break;
|
|
3925
|
+
case 'Home':
|
|
3926
|
+
e.preventDefault();
|
|
3927
|
+
updateSingleValue(min, false);
|
|
3928
|
+
// m.redraw();
|
|
3929
|
+
break;
|
|
3930
|
+
case 'End':
|
|
3931
|
+
e.preventDefault();
|
|
3932
|
+
updateSingleValue(max, false);
|
|
3933
|
+
// m.redraw();
|
|
3934
|
+
break;
|
|
3935
|
+
}
|
|
3936
|
+
},
|
|
3937
|
+
}, [
|
|
3938
|
+
// Track
|
|
3939
|
+
m(`.track.${orientation}`),
|
|
3940
|
+
// Progress
|
|
3941
|
+
m(`.range-progress.${orientation}`, { style: progressStyle }),
|
|
3942
|
+
// Thumb
|
|
3943
|
+
m(`.thumb.${orientation}`, {
|
|
3944
|
+
style: thumbStyle,
|
|
3945
|
+
onmousedown: handleMouseDown,
|
|
3946
|
+
}, showValue
|
|
3947
|
+
? m(`.value-tooltip.${tooltipPosition}`, state.singleValue.toFixed(0))
|
|
3948
|
+
: null),
|
|
3949
|
+
]),
|
|
3950
|
+
]),
|
|
3951
|
+
label
|
|
3952
|
+
? m(Label, {
|
|
3953
|
+
label,
|
|
3954
|
+
id,
|
|
3955
|
+
isMandatory,
|
|
3956
|
+
isActive: true, // Range sliders always have active labels
|
|
3957
|
+
})
|
|
3958
|
+
: null,
|
|
3959
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
3960
|
+
]);
|
|
3961
|
+
};
|
|
3962
|
+
// Double Range Slider (Min/Max)
|
|
3963
|
+
const renderMinMaxRange = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
3964
|
+
const { min = 0, max = 100, step = 1, minValue, maxValue, vertical = false, showValue = false, height = '200px', disabled = false, } = attrs;
|
|
3965
|
+
// Initialize range values
|
|
3966
|
+
const currentMinValue = minValue !== undefined ? minValue : attrs.minValue || min;
|
|
3967
|
+
const currentMaxValue = maxValue !== undefined ? maxValue : attrs.maxValue || max;
|
|
3968
|
+
if (state.rangeMinValue === undefined || state.rangeMaxValue === undefined) {
|
|
3969
|
+
state.rangeMinValue = currentMinValue;
|
|
3970
|
+
state.rangeMaxValue = currentMaxValue;
|
|
3971
|
+
}
|
|
3972
|
+
// Initialize active thumb if not set
|
|
3973
|
+
if (state.activeThumb === null) {
|
|
3974
|
+
state.activeThumb = 'min';
|
|
3975
|
+
}
|
|
3976
|
+
const minPercentage = getPercentage(state.rangeMinValue, min, max);
|
|
3977
|
+
const maxPercentage = getPercentage(state.rangeMaxValue, min, max);
|
|
3978
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
3979
|
+
const containerStyle = vertical ? { height } : {};
|
|
3980
|
+
const rangeStyle = vertical
|
|
3981
|
+
? {
|
|
3982
|
+
bottom: `${minPercentage}%`,
|
|
3983
|
+
height: `${maxPercentage - minPercentage}%`,
|
|
3984
|
+
}
|
|
3985
|
+
: {
|
|
3986
|
+
left: `${minPercentage}%`,
|
|
3987
|
+
width: `${maxPercentage - minPercentage}%`,
|
|
3988
|
+
};
|
|
3989
|
+
// Only keep dynamic positioning and z-index as inline styles
|
|
3990
|
+
const createThumbStyle = (percentage, isActive) => vertical
|
|
3991
|
+
? {
|
|
3992
|
+
bottom: `${percentage}%`,
|
|
3993
|
+
zIndex: isActive ? 10 : 5,
|
|
3994
|
+
}
|
|
3995
|
+
: {
|
|
3996
|
+
left: `${percentage}%`,
|
|
3997
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
3998
|
+
zIndex: isActive ? 10 : 5,
|
|
3999
|
+
};
|
|
4000
|
+
const handleMouseDown = (thumb) => (e) => {
|
|
4001
|
+
if (disabled)
|
|
4002
|
+
return;
|
|
4003
|
+
e.preventDefault();
|
|
4004
|
+
state.isDragging = true;
|
|
4005
|
+
state.activeThumb = thumb;
|
|
4006
|
+
// Get container reference from the current target's parent
|
|
4007
|
+
const thumbElement = e.currentTarget;
|
|
4008
|
+
const container = thumbElement.parentElement;
|
|
4009
|
+
if (!container)
|
|
4010
|
+
return;
|
|
4011
|
+
const handleMouseMove = (e) => {
|
|
4012
|
+
if (!state.isDragging || !container)
|
|
4013
|
+
return;
|
|
4014
|
+
const rect = container.getBoundingClientRect();
|
|
4015
|
+
let percentage;
|
|
4016
|
+
if (vertical) {
|
|
4017
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
4018
|
+
}
|
|
4019
|
+
else {
|
|
4020
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
4021
|
+
}
|
|
4022
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
4023
|
+
const value = min + (percentage / 100) * (max - min);
|
|
4024
|
+
const steppedValue = Math.round(value / step) * step;
|
|
4025
|
+
if (thumb === 'min') {
|
|
4026
|
+
updateRangeValues(Math.min(steppedValue, state.rangeMaxValue), state.rangeMaxValue, attrs, state, true);
|
|
4027
|
+
}
|
|
4028
|
+
else {
|
|
4029
|
+
updateRangeValues(state.rangeMinValue, Math.max(steppedValue, state.rangeMinValue), attrs, state, true);
|
|
4030
|
+
}
|
|
4031
|
+
// Redraw to update the UI during drag
|
|
4032
|
+
m.redraw();
|
|
4033
|
+
};
|
|
4034
|
+
const handleMouseUp = () => {
|
|
4035
|
+
state.isDragging = false;
|
|
4036
|
+
state.activeThumb = null;
|
|
4037
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
4038
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
4039
|
+
// Fire onchange when dragging ends
|
|
4040
|
+
updateRangeValues(state.rangeMinValue, state.rangeMaxValue, attrs, state, false);
|
|
4041
|
+
};
|
|
4042
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
4043
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
4044
|
+
};
|
|
4045
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
4046
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
4047
|
+
return m('.input-field', { className: cn, style }, [
|
|
4048
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
4049
|
+
// Hidden inputs for label association and accessibility
|
|
4050
|
+
m('input[type=range]', {
|
|
4051
|
+
id,
|
|
4052
|
+
value: state.rangeMinValue,
|
|
4053
|
+
min,
|
|
4054
|
+
max,
|
|
4055
|
+
step,
|
|
4056
|
+
style: { display: 'none' },
|
|
4057
|
+
disabled,
|
|
4058
|
+
tabindex: -1,
|
|
4059
|
+
}),
|
|
4060
|
+
m('input[type=range]', {
|
|
4061
|
+
id: `${id}_max`,
|
|
4062
|
+
value: state.rangeMaxValue,
|
|
4063
|
+
min,
|
|
4064
|
+
max,
|
|
4065
|
+
step,
|
|
4066
|
+
style: { display: 'none' },
|
|
4067
|
+
disabled,
|
|
4068
|
+
tabindex: -1,
|
|
4069
|
+
}),
|
|
4070
|
+
m(`div`, { className: fieldClass }, [
|
|
4071
|
+
m(`.double-range-slider.${orientation}`, {
|
|
4072
|
+
style: containerStyle,
|
|
4073
|
+
tabindex: disabled ? -1 : 0,
|
|
4074
|
+
role: 'slider',
|
|
4075
|
+
'aria-valuemin': min,
|
|
4076
|
+
'aria-valuemax': max,
|
|
4077
|
+
'aria-valuenow': state.rangeMinValue,
|
|
4078
|
+
'aria-valuetext': `${state.rangeMinValue} to ${state.rangeMaxValue}`,
|
|
4079
|
+
'aria-label': label || 'Range slider',
|
|
4080
|
+
onclick: (e) => {
|
|
4081
|
+
// Focus the slider when clicked
|
|
4082
|
+
e.currentTarget.focus();
|
|
4083
|
+
},
|
|
4084
|
+
onkeydown: (e) => {
|
|
4085
|
+
if (disabled)
|
|
4086
|
+
return;
|
|
4087
|
+
let newMinValue = state.rangeMinValue;
|
|
4088
|
+
let newMaxValue = state.rangeMaxValue;
|
|
4089
|
+
const activeThumb = state.activeThumb || 'min';
|
|
4090
|
+
switch (e.key) {
|
|
4091
|
+
case 'ArrowLeft':
|
|
4092
|
+
case 'ArrowDown':
|
|
4093
|
+
e.preventDefault();
|
|
4094
|
+
if (activeThumb === 'min') {
|
|
4095
|
+
newMinValue = Math.max(min, newMinValue - step);
|
|
4096
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4097
|
+
}
|
|
4098
|
+
else {
|
|
4099
|
+
newMaxValue = Math.max(newMinValue, newMaxValue - step);
|
|
4100
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4101
|
+
}
|
|
4102
|
+
// m.redraw();
|
|
4103
|
+
break;
|
|
4104
|
+
case 'ArrowRight':
|
|
4105
|
+
case 'ArrowUp':
|
|
4106
|
+
e.preventDefault();
|
|
4107
|
+
if (activeThumb === 'min') {
|
|
4108
|
+
newMinValue = Math.min(newMaxValue, newMinValue + step);
|
|
4109
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4110
|
+
}
|
|
4111
|
+
else {
|
|
4112
|
+
newMaxValue = Math.min(max, newMaxValue + step);
|
|
4113
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4114
|
+
}
|
|
4115
|
+
// m.redraw();
|
|
4116
|
+
break;
|
|
4117
|
+
case 'Tab':
|
|
4118
|
+
// Handle Tab navigation properly
|
|
4119
|
+
if (activeThumb === 'min') {
|
|
4120
|
+
if (e.shiftKey) {
|
|
4121
|
+
// Shift+Tab from min thumb: go to previous element (let browser handle)
|
|
4122
|
+
return; // Don't prevent default
|
|
4123
|
+
}
|
|
4124
|
+
else {
|
|
4125
|
+
// Tab from min thumb: go to max thumb
|
|
4126
|
+
e.preventDefault();
|
|
4127
|
+
state.activeThumb = 'max';
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
else { // activeThumb === 'max'
|
|
4131
|
+
if (e.shiftKey) {
|
|
4132
|
+
// Shift+Tab from max thumb: go to min thumb
|
|
4133
|
+
e.preventDefault();
|
|
4134
|
+
state.activeThumb = 'min';
|
|
4135
|
+
}
|
|
4136
|
+
else {
|
|
4137
|
+
// Tab from max thumb: go to next element (let browser handle)
|
|
4138
|
+
return; // Don't prevent default
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
break;
|
|
4142
|
+
case 'Home':
|
|
4143
|
+
e.preventDefault();
|
|
4144
|
+
if (activeThumb === 'min') {
|
|
4145
|
+
updateRangeValues(min, newMaxValue, attrs, state, false);
|
|
4146
|
+
}
|
|
4147
|
+
else {
|
|
4148
|
+
updateRangeValues(newMinValue, newMinValue, attrs, state, false);
|
|
4149
|
+
}
|
|
4150
|
+
// m.redraw();
|
|
4151
|
+
break;
|
|
4152
|
+
case 'End':
|
|
4153
|
+
e.preventDefault();
|
|
4154
|
+
if (activeThumb === 'min') {
|
|
4155
|
+
updateRangeValues(newMaxValue, newMaxValue, attrs, state, false);
|
|
4156
|
+
}
|
|
4157
|
+
else {
|
|
4158
|
+
updateRangeValues(newMinValue, max, attrs, state, false);
|
|
4159
|
+
}
|
|
4160
|
+
// m.redraw();
|
|
4161
|
+
break;
|
|
4162
|
+
}
|
|
4163
|
+
},
|
|
4164
|
+
}, [
|
|
4165
|
+
// Track
|
|
4166
|
+
m(`.track.${orientation}`),
|
|
4167
|
+
// Range
|
|
4168
|
+
m(`.range.${orientation}`, { style: rangeStyle }),
|
|
4169
|
+
// Min thumb
|
|
4170
|
+
m(`.thumb.${orientation}.min-thumb${state.activeThumb === 'min' ? '.active' : ''}`, {
|
|
4171
|
+
style: createThumbStyle(minPercentage, state.activeThumb === 'min'),
|
|
4172
|
+
onmousedown: handleMouseDown('min'),
|
|
4173
|
+
onclick: () => {
|
|
4174
|
+
state.activeThumb = 'min';
|
|
4175
|
+
// m.redraw();
|
|
4176
|
+
},
|
|
4177
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMinValue.toFixed(0)) : null),
|
|
4178
|
+
// Max thumb
|
|
4179
|
+
m(`.thumb.${orientation}.max-thumb${state.activeThumb === 'max' ? '.active' : ''}`, {
|
|
4180
|
+
style: createThumbStyle(maxPercentage, state.activeThumb === 'max'),
|
|
4181
|
+
onmousedown: handleMouseDown('max'),
|
|
4182
|
+
onclick: () => {
|
|
4183
|
+
state.activeThumb = 'max';
|
|
4184
|
+
// m.redraw();
|
|
4185
|
+
},
|
|
4186
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMaxValue.toFixed(0)) : null),
|
|
4187
|
+
]),
|
|
4188
|
+
]),
|
|
4189
|
+
label
|
|
4190
|
+
? m(Label, {
|
|
4191
|
+
label,
|
|
4192
|
+
id,
|
|
4193
|
+
isMandatory,
|
|
4194
|
+
isActive: true, // Range sliders always have active labels
|
|
4195
|
+
})
|
|
4196
|
+
: null,
|
|
4197
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
4198
|
+
]);
|
|
4199
|
+
};
|
|
4200
|
+
|
|
3372
4201
|
/**
|
|
3373
4202
|
* Pure TypeScript MaterialBox - creates an image lightbox that fills the screen when clicked
|
|
3374
4203
|
* No MaterializeCSS dependencies
|
|
@@ -7181,6 +8010,8 @@ exports.isValidationError = isValidationError;
|
|
|
7181
8010
|
exports.isValidationSuccess = isValidationSuccess;
|
|
7182
8011
|
exports.padLeft = padLeft;
|
|
7183
8012
|
exports.range = range;
|
|
8013
|
+
exports.renderMinMaxRange = renderMinMaxRange;
|
|
8014
|
+
exports.renderSingleRangeWithTooltip = renderSingleRangeWithTooltip;
|
|
7184
8015
|
exports.toast = toast;
|
|
7185
8016
|
exports.uniqueId = uniqueId;
|
|
7186
8017
|
exports.uuid4 = uuid4;
|