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