mithril-materialized 2.0.0-beta.11 → 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 +58 -2
- package/dist/components.css +595 -0
- package/dist/forms.css +325 -0
- package/dist/icon.d.ts +2 -2
- package/dist/index.css +607 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.esm.js +1271 -157
- package/dist/index.js +1274 -156
- package/dist/index.min.css +1 -1
- package/dist/index.umd.js +1274 -156
- package/dist/input-options.d.ts +18 -4
- package/dist/material-icon.d.ts +3 -0
- package/dist/range-slider.d.ts +4 -0
- package/dist/treeview.d.ts +39 -0
- package/package.json +1 -1
- package/sass/components/_treeview.scss +353 -0
- package/sass/components/forms/_forms.scss +1 -1
- package/sass/components/forms/_range-enhanced.scss +393 -0
- package/sass/materialize.scss +2 -0
package/dist/index.umd.js
CHANGED
|
@@ -840,6 +840,18 @@
|
|
|
840
840
|
'M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 0 0 5.7 7.11L10.59 12l-4.89 4.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z',
|
|
841
841
|
'M0 0h24v24H0z',
|
|
842
842
|
],
|
|
843
|
+
chevron: [
|
|
844
|
+
'M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z', // chevron down
|
|
845
|
+
'M0 0h24v24H0z', // background
|
|
846
|
+
],
|
|
847
|
+
expand: [
|
|
848
|
+
'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z', // plus
|
|
849
|
+
'M0 0h24v24H0z', // background
|
|
850
|
+
],
|
|
851
|
+
collapse: [
|
|
852
|
+
'M19 13H5v-2h14v2z', // minus
|
|
853
|
+
'M0 0h24v24H0z', // background
|
|
854
|
+
],
|
|
843
855
|
};
|
|
844
856
|
const MaterialIcon = () => {
|
|
845
857
|
return {
|
|
@@ -849,8 +861,8 @@
|
|
|
849
861
|
const rotationMap = {
|
|
850
862
|
down: 0,
|
|
851
863
|
up: 180,
|
|
852
|
-
left:
|
|
853
|
-
right: 90,
|
|
864
|
+
left: 90,
|
|
865
|
+
right: -90,
|
|
854
866
|
};
|
|
855
867
|
const rotation = (_a = rotationMap[direction]) !== null && _a !== void 0 ? _a : 0;
|
|
856
868
|
const transform = rotation ? `rotate(${rotation}deg)` : undefined;
|
|
@@ -1159,7 +1171,7 @@
|
|
|
1159
1171
|
const lang = language || 'lang-TypeScript';
|
|
1160
1172
|
const label = lang.replace('lang-', '');
|
|
1161
1173
|
const cb = code instanceof Array ? code.join('\n') : code;
|
|
1162
|
-
const cn = [newRow ? 'clear' : '', lang, className].filter(Boolean).join(' ').trim();
|
|
1174
|
+
const cn = [newRow ? 'clear' : '', lang, className].filter(Boolean).join(' ').trim() || undefined;
|
|
1163
1175
|
return m(`pre.codeblock${newRow ? '.clear' : ''}`, attrs, [
|
|
1164
1176
|
m('div', m('label', label)),
|
|
1165
1177
|
m('code', Object.assign(Object.assign({}, params), { className: cn }), cb),
|
|
@@ -2182,6 +2194,12 @@
|
|
|
2182
2194
|
isValid: true,
|
|
2183
2195
|
active: false,
|
|
2184
2196
|
inputElement: null,
|
|
2197
|
+
// Range-specific state
|
|
2198
|
+
rangeMinValue: undefined,
|
|
2199
|
+
rangeMaxValue: undefined,
|
|
2200
|
+
singleValue: undefined,
|
|
2201
|
+
isDragging: false,
|
|
2202
|
+
activeThumb: null,
|
|
2185
2203
|
};
|
|
2186
2204
|
// let labelManager: { updateLabelState: () => void; cleanup: () => void } | null = null;
|
|
2187
2205
|
// let lengthUpdateHandler: (() => void) | null = null;
|
|
@@ -2207,19 +2225,425 @@
|
|
|
2207
2225
|
state.hasInteracted = length > 0;
|
|
2208
2226
|
}
|
|
2209
2227
|
};
|
|
2228
|
+
// Range slider helper functions
|
|
2229
|
+
const getPercentage = (value, min, max) => {
|
|
2230
|
+
return ((value - min) / (max - min)) * 100;
|
|
2231
|
+
};
|
|
2232
|
+
const updateRangeValues = (minValue, maxValue, attrs, immediate = false) => {
|
|
2233
|
+
// Ensure min doesn't exceed max and vice versa
|
|
2234
|
+
if (minValue > maxValue)
|
|
2235
|
+
minValue = maxValue;
|
|
2236
|
+
if (maxValue < minValue)
|
|
2237
|
+
maxValue = minValue;
|
|
2238
|
+
state.rangeMinValue = minValue;
|
|
2239
|
+
state.rangeMaxValue = maxValue;
|
|
2240
|
+
// Call oninput for immediate feedback or onchange for final changes
|
|
2241
|
+
if (immediate && attrs.oninput) {
|
|
2242
|
+
attrs.oninput(minValue, maxValue);
|
|
2243
|
+
}
|
|
2244
|
+
else if (!immediate && attrs.onchange) {
|
|
2245
|
+
attrs.onchange(minValue, maxValue);
|
|
2246
|
+
}
|
|
2247
|
+
};
|
|
2248
|
+
// Render function for single range slider with tooltip
|
|
2249
|
+
const renderSingleRangeWithTooltip = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
2250
|
+
const { min = 0, max = 100, step = 1, initialValue, vertical = false, showValue = false, height = '200px', disabled = false, oninput, onchange, } = attrs;
|
|
2251
|
+
// Initialize single range value
|
|
2252
|
+
const currentValue = initialValue !== undefined ? initialValue : state.singleValue || min;
|
|
2253
|
+
if (state.singleValue === undefined) {
|
|
2254
|
+
state.singleValue = currentValue;
|
|
2255
|
+
}
|
|
2256
|
+
const percentage = getPercentage(state.singleValue, min, max);
|
|
2257
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
2258
|
+
const containerStyle = vertical ? { height } : {};
|
|
2259
|
+
const progressStyle = vertical
|
|
2260
|
+
? {
|
|
2261
|
+
height: `${percentage}%`,
|
|
2262
|
+
}
|
|
2263
|
+
: {
|
|
2264
|
+
width: `${percentage}%`,
|
|
2265
|
+
};
|
|
2266
|
+
const thumbStyle = vertical
|
|
2267
|
+
? {
|
|
2268
|
+
bottom: `${percentage}%`,
|
|
2269
|
+
}
|
|
2270
|
+
: {
|
|
2271
|
+
left: `${percentage}%`,
|
|
2272
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
2273
|
+
};
|
|
2274
|
+
const updateSingleValue = (newValue, immediate = false) => {
|
|
2275
|
+
state.singleValue = newValue;
|
|
2276
|
+
if (immediate && oninput) {
|
|
2277
|
+
oninput(newValue);
|
|
2278
|
+
}
|
|
2279
|
+
else if (!immediate && onchange) {
|
|
2280
|
+
onchange(newValue);
|
|
2281
|
+
}
|
|
2282
|
+
};
|
|
2283
|
+
const handleMouseDown = (e) => {
|
|
2284
|
+
if (disabled)
|
|
2285
|
+
return;
|
|
2286
|
+
e.preventDefault();
|
|
2287
|
+
state.isDragging = true;
|
|
2288
|
+
// Get container reference from the current target's parent
|
|
2289
|
+
const thumbElement = e.currentTarget;
|
|
2290
|
+
const container = thumbElement.parentElement;
|
|
2291
|
+
if (!container)
|
|
2292
|
+
return;
|
|
2293
|
+
const handleMouseMove = (e) => {
|
|
2294
|
+
if (!state.isDragging || !container)
|
|
2295
|
+
return;
|
|
2296
|
+
const rect = container.getBoundingClientRect();
|
|
2297
|
+
let percentage;
|
|
2298
|
+
if (vertical) {
|
|
2299
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
2300
|
+
}
|
|
2301
|
+
else {
|
|
2302
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
2303
|
+
}
|
|
2304
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
2305
|
+
const value = min + (percentage / 100) * (max - min);
|
|
2306
|
+
const steppedValue = Math.round(value / step) * step;
|
|
2307
|
+
updateSingleValue(steppedValue, true);
|
|
2308
|
+
// Redraw to update the UI
|
|
2309
|
+
m.redraw();
|
|
2310
|
+
};
|
|
2311
|
+
const handleMouseUp = () => {
|
|
2312
|
+
state.isDragging = false;
|
|
2313
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
2314
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
2315
|
+
// Fire onchange when dragging ends
|
|
2316
|
+
updateSingleValue(state.singleValue, false);
|
|
2317
|
+
};
|
|
2318
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
2319
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
2320
|
+
};
|
|
2321
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
2322
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
2323
|
+
return m('.input-field', { className: cn, style }, [
|
|
2324
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2325
|
+
// Hidden input for label association and accessibility
|
|
2326
|
+
m('input[type=range]', {
|
|
2327
|
+
id,
|
|
2328
|
+
value: state.singleValue,
|
|
2329
|
+
min,
|
|
2330
|
+
max,
|
|
2331
|
+
step,
|
|
2332
|
+
style: { display: 'none' },
|
|
2333
|
+
disabled,
|
|
2334
|
+
tabindex: -1,
|
|
2335
|
+
}),
|
|
2336
|
+
m('div', { class: fieldClass, style: containerStyle }, [
|
|
2337
|
+
m(`.single-range-slider.${orientation}`, {
|
|
2338
|
+
tabindex: disabled ? -1 : 0,
|
|
2339
|
+
role: 'slider',
|
|
2340
|
+
'aria-valuemin': min,
|
|
2341
|
+
'aria-valuemax': max,
|
|
2342
|
+
'aria-valuenow': state.singleValue,
|
|
2343
|
+
'aria-label': label || 'Range slider',
|
|
2344
|
+
onclick: (e) => {
|
|
2345
|
+
// Focus the slider when clicked
|
|
2346
|
+
e.currentTarget.focus();
|
|
2347
|
+
},
|
|
2348
|
+
onkeydown: (e) => {
|
|
2349
|
+
if (disabled)
|
|
2350
|
+
return;
|
|
2351
|
+
let newValue = state.singleValue;
|
|
2352
|
+
switch (e.key) {
|
|
2353
|
+
case 'ArrowLeft':
|
|
2354
|
+
case 'ArrowDown':
|
|
2355
|
+
e.preventDefault();
|
|
2356
|
+
newValue = Math.max(min, newValue - step);
|
|
2357
|
+
updateSingleValue(newValue, false);
|
|
2358
|
+
m.redraw();
|
|
2359
|
+
break;
|
|
2360
|
+
case 'ArrowRight':
|
|
2361
|
+
case 'ArrowUp':
|
|
2362
|
+
e.preventDefault();
|
|
2363
|
+
newValue = Math.min(max, newValue + step);
|
|
2364
|
+
updateSingleValue(newValue, false);
|
|
2365
|
+
m.redraw();
|
|
2366
|
+
break;
|
|
2367
|
+
case 'Home':
|
|
2368
|
+
e.preventDefault();
|
|
2369
|
+
updateSingleValue(min, false);
|
|
2370
|
+
m.redraw();
|
|
2371
|
+
break;
|
|
2372
|
+
case 'End':
|
|
2373
|
+
e.preventDefault();
|
|
2374
|
+
updateSingleValue(max, false);
|
|
2375
|
+
m.redraw();
|
|
2376
|
+
break;
|
|
2377
|
+
}
|
|
2378
|
+
},
|
|
2379
|
+
}, [
|
|
2380
|
+
// Track
|
|
2381
|
+
m(`.track.${orientation}`),
|
|
2382
|
+
// Progress
|
|
2383
|
+
m(`.range-progress.${orientation}`, { style: progressStyle }),
|
|
2384
|
+
// Thumb
|
|
2385
|
+
m(`.thumb.${orientation}`, {
|
|
2386
|
+
style: thumbStyle,
|
|
2387
|
+
onmousedown: handleMouseDown,
|
|
2388
|
+
}, showValue
|
|
2389
|
+
? m(`.value-tooltip.${vertical ? 'right' : 'top'}`, state.singleValue.toFixed(0))
|
|
2390
|
+
: null),
|
|
2391
|
+
]),
|
|
2392
|
+
]),
|
|
2393
|
+
label
|
|
2394
|
+
? m(Label, {
|
|
2395
|
+
label,
|
|
2396
|
+
id,
|
|
2397
|
+
isMandatory,
|
|
2398
|
+
isActive: true, // Range sliders always have active labels
|
|
2399
|
+
})
|
|
2400
|
+
: null,
|
|
2401
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
2402
|
+
]);
|
|
2403
|
+
};
|
|
2404
|
+
// Render function for minmax range slider
|
|
2405
|
+
const renderMinMaxRange = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
2406
|
+
const { min = 0, max = 100, step = 1, minValue, maxValue, vertical = false, showValue = false, height = '200px', disabled = false, } = attrs;
|
|
2407
|
+
// Initialize range values
|
|
2408
|
+
const currentMinValue = minValue !== undefined ? minValue : attrs.minValue || min;
|
|
2409
|
+
const currentMaxValue = maxValue !== undefined ? maxValue : attrs.maxValue || max;
|
|
2410
|
+
if (state.rangeMinValue === undefined || state.rangeMaxValue === undefined) {
|
|
2411
|
+
state.rangeMinValue = currentMinValue;
|
|
2412
|
+
state.rangeMaxValue = currentMaxValue;
|
|
2413
|
+
}
|
|
2414
|
+
// Initialize active thumb if not set
|
|
2415
|
+
if (state.activeThumb === null) {
|
|
2416
|
+
state.activeThumb = 'min';
|
|
2417
|
+
}
|
|
2418
|
+
const minPercentage = getPercentage(state.rangeMinValue, min, max);
|
|
2419
|
+
const maxPercentage = getPercentage(state.rangeMaxValue, min, max);
|
|
2420
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
2421
|
+
const containerStyle = vertical ? { height } : {};
|
|
2422
|
+
const rangeStyle = vertical
|
|
2423
|
+
? {
|
|
2424
|
+
bottom: `${minPercentage}%`,
|
|
2425
|
+
height: `${maxPercentage - minPercentage}%`,
|
|
2426
|
+
}
|
|
2427
|
+
: {
|
|
2428
|
+
left: `${minPercentage}%`,
|
|
2429
|
+
width: `${maxPercentage - minPercentage}%`,
|
|
2430
|
+
};
|
|
2431
|
+
// Only keep dynamic positioning and z-index as inline styles
|
|
2432
|
+
const createThumbStyle = (percentage, isActive) => vertical
|
|
2433
|
+
? {
|
|
2434
|
+
bottom: `${percentage}%`,
|
|
2435
|
+
zIndex: isActive ? 10 : 5,
|
|
2436
|
+
}
|
|
2437
|
+
: {
|
|
2438
|
+
left: `${percentage}%`,
|
|
2439
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
2440
|
+
zIndex: isActive ? 10 : 5,
|
|
2441
|
+
};
|
|
2442
|
+
const handleMouseDown = (thumb) => (e) => {
|
|
2443
|
+
if (disabled)
|
|
2444
|
+
return;
|
|
2445
|
+
e.preventDefault();
|
|
2446
|
+
state.isDragging = true;
|
|
2447
|
+
state.activeThumb = thumb;
|
|
2448
|
+
// Get container reference from the current target's parent
|
|
2449
|
+
const thumbElement = e.currentTarget;
|
|
2450
|
+
const container = thumbElement.parentElement;
|
|
2451
|
+
if (!container)
|
|
2452
|
+
return;
|
|
2453
|
+
const handleMouseMove = (e) => {
|
|
2454
|
+
if (!state.isDragging || !container)
|
|
2455
|
+
return;
|
|
2456
|
+
const rect = container.getBoundingClientRect();
|
|
2457
|
+
let percentage;
|
|
2458
|
+
if (vertical) {
|
|
2459
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
2460
|
+
}
|
|
2461
|
+
else {
|
|
2462
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
2463
|
+
}
|
|
2464
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
2465
|
+
const value = min + (percentage / 100) * (max - min);
|
|
2466
|
+
const steppedValue = Math.round(value / step) * step;
|
|
2467
|
+
if (thumb === 'min') {
|
|
2468
|
+
updateRangeValues(Math.min(steppedValue, state.rangeMaxValue), state.rangeMaxValue, attrs, true);
|
|
2469
|
+
}
|
|
2470
|
+
else {
|
|
2471
|
+
updateRangeValues(state.rangeMinValue, Math.max(steppedValue, state.rangeMinValue), attrs, true);
|
|
2472
|
+
}
|
|
2473
|
+
// Redraw to update the UI
|
|
2474
|
+
m.redraw();
|
|
2475
|
+
};
|
|
2476
|
+
const handleMouseUp = () => {
|
|
2477
|
+
state.isDragging = false;
|
|
2478
|
+
state.activeThumb = null;
|
|
2479
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
2480
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
2481
|
+
// Fire onchange when dragging ends
|
|
2482
|
+
updateRangeValues(state.rangeMinValue, state.rangeMaxValue, attrs, false);
|
|
2483
|
+
};
|
|
2484
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
2485
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
2486
|
+
};
|
|
2487
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
2488
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
2489
|
+
return m('.input-field', { className: cn, style }, [
|
|
2490
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2491
|
+
// Hidden inputs for label association and accessibility
|
|
2492
|
+
m('input[type=range]', {
|
|
2493
|
+
id,
|
|
2494
|
+
value: state.rangeMinValue,
|
|
2495
|
+
min,
|
|
2496
|
+
max,
|
|
2497
|
+
step,
|
|
2498
|
+
style: { display: 'none' },
|
|
2499
|
+
disabled,
|
|
2500
|
+
tabindex: -1,
|
|
2501
|
+
}),
|
|
2502
|
+
m('input[type=range]', {
|
|
2503
|
+
id: `${id}_max`,
|
|
2504
|
+
value: state.rangeMaxValue,
|
|
2505
|
+
min,
|
|
2506
|
+
max,
|
|
2507
|
+
step,
|
|
2508
|
+
style: { display: 'none' },
|
|
2509
|
+
disabled,
|
|
2510
|
+
tabindex: -1,
|
|
2511
|
+
}),
|
|
2512
|
+
m(`.${fieldClass}`, [
|
|
2513
|
+
m(`.double-range-slider.${orientation}`, {
|
|
2514
|
+
style: containerStyle,
|
|
2515
|
+
tabindex: disabled ? -1 : 0,
|
|
2516
|
+
role: 'slider',
|
|
2517
|
+
'aria-valuemin': min,
|
|
2518
|
+
'aria-valuemax': max,
|
|
2519
|
+
'aria-valuenow': state.rangeMinValue,
|
|
2520
|
+
'aria-valuetext': `${state.rangeMinValue} to ${state.rangeMaxValue}`,
|
|
2521
|
+
'aria-label': label || 'Range slider',
|
|
2522
|
+
onclick: (e) => {
|
|
2523
|
+
// Focus the slider when clicked
|
|
2524
|
+
e.currentTarget.focus();
|
|
2525
|
+
},
|
|
2526
|
+
onkeydown: (e) => {
|
|
2527
|
+
if (disabled)
|
|
2528
|
+
return;
|
|
2529
|
+
let newMinValue = state.rangeMinValue;
|
|
2530
|
+
let newMaxValue = state.rangeMaxValue;
|
|
2531
|
+
const activeThumb = state.activeThumb || 'min';
|
|
2532
|
+
switch (e.key) {
|
|
2533
|
+
case 'ArrowLeft':
|
|
2534
|
+
case 'ArrowDown':
|
|
2535
|
+
e.preventDefault();
|
|
2536
|
+
if (activeThumb === 'min') {
|
|
2537
|
+
newMinValue = Math.max(min, newMinValue - step);
|
|
2538
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2539
|
+
}
|
|
2540
|
+
else {
|
|
2541
|
+
newMaxValue = Math.max(newMinValue, newMaxValue - step);
|
|
2542
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2543
|
+
}
|
|
2544
|
+
m.redraw();
|
|
2545
|
+
break;
|
|
2546
|
+
case 'ArrowRight':
|
|
2547
|
+
case 'ArrowUp':
|
|
2548
|
+
e.preventDefault();
|
|
2549
|
+
if (activeThumb === 'min') {
|
|
2550
|
+
newMinValue = Math.min(newMaxValue, newMinValue + step);
|
|
2551
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2552
|
+
}
|
|
2553
|
+
else {
|
|
2554
|
+
newMaxValue = Math.min(max, newMaxValue + step);
|
|
2555
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, false);
|
|
2556
|
+
}
|
|
2557
|
+
m.redraw();
|
|
2558
|
+
break;
|
|
2559
|
+
// Remove Tab case - let normal tab navigation work
|
|
2560
|
+
// Users can click on specific thumbs to activate them
|
|
2561
|
+
case 'Home':
|
|
2562
|
+
e.preventDefault();
|
|
2563
|
+
if (activeThumb === 'min') {
|
|
2564
|
+
updateRangeValues(min, newMaxValue, attrs, false);
|
|
2565
|
+
}
|
|
2566
|
+
else {
|
|
2567
|
+
updateRangeValues(newMinValue, newMinValue, attrs, false);
|
|
2568
|
+
}
|
|
2569
|
+
m.redraw();
|
|
2570
|
+
break;
|
|
2571
|
+
case 'End':
|
|
2572
|
+
e.preventDefault();
|
|
2573
|
+
if (activeThumb === 'min') {
|
|
2574
|
+
updateRangeValues(newMaxValue, newMaxValue, attrs, false);
|
|
2575
|
+
}
|
|
2576
|
+
else {
|
|
2577
|
+
updateRangeValues(newMinValue, max, attrs, false);
|
|
2578
|
+
}
|
|
2579
|
+
m.redraw();
|
|
2580
|
+
break;
|
|
2581
|
+
}
|
|
2582
|
+
},
|
|
2583
|
+
}, [
|
|
2584
|
+
// Track
|
|
2585
|
+
m(`.track.${orientation}`),
|
|
2586
|
+
// Range
|
|
2587
|
+
m(`.range.${orientation}`, { style: rangeStyle }),
|
|
2588
|
+
// Min thumb
|
|
2589
|
+
m(`.thumb.${orientation}.min-thumb${state.activeThumb === 'min' ? '.active' : ''}`, {
|
|
2590
|
+
style: createThumbStyle(minPercentage, state.activeThumb === 'min'),
|
|
2591
|
+
onmousedown: handleMouseDown('min'),
|
|
2592
|
+
onclick: () => {
|
|
2593
|
+
state.activeThumb = 'min';
|
|
2594
|
+
m.redraw();
|
|
2595
|
+
},
|
|
2596
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMinValue.toFixed(0)) : null),
|
|
2597
|
+
// Max thumb
|
|
2598
|
+
m(`.thumb.${orientation}.max-thumb${state.activeThumb === 'max' ? '.active' : ''}`, {
|
|
2599
|
+
style: createThumbStyle(maxPercentage, state.activeThumb === 'max'),
|
|
2600
|
+
onmousedown: handleMouseDown('max'),
|
|
2601
|
+
onclick: () => {
|
|
2602
|
+
state.activeThumb = 'max';
|
|
2603
|
+
m.redraw();
|
|
2604
|
+
},
|
|
2605
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMaxValue.toFixed(0)) : null),
|
|
2606
|
+
]),
|
|
2607
|
+
]),
|
|
2608
|
+
label
|
|
2609
|
+
? m(Label, {
|
|
2610
|
+
label,
|
|
2611
|
+
id,
|
|
2612
|
+
isMandatory,
|
|
2613
|
+
isActive: true, // Range sliders always have active labels
|
|
2614
|
+
})
|
|
2615
|
+
: null,
|
|
2616
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
2617
|
+
]);
|
|
2618
|
+
};
|
|
2210
2619
|
return {
|
|
2211
2620
|
view: ({ attrs }) => {
|
|
2212
2621
|
var _a;
|
|
2213
2622
|
const { className = 'col s12', dataError, dataSuccess, helperText, iconName, id = state.id, initialValue, placeholder, isMandatory, label, maxLength, newRow, oninput, onchange, onkeydown, onkeypress, onkeyup, style, validate } = attrs, params = __rest(attrs, ["className", "dataError", "dataSuccess", "helperText", "iconName", "id", "initialValue", "placeholder", "isMandatory", "label", "maxLength", "newRow", "oninput", "onchange", "onkeydown", "onkeypress", "onkeyup", "style", "validate"]);
|
|
2214
2623
|
// const attributes = toAttrs(params);
|
|
2215
|
-
const cn = [newRow ? 'clear' : '', defaultClass, className].filter(Boolean).join(' ').trim();
|
|
2624
|
+
const cn = [newRow ? 'clear' : '', defaultClass, className].filter(Boolean).join(' ').trim() || undefined;
|
|
2216
2625
|
const isActive = state.active || ((_a = state.inputElement) === null || _a === void 0 ? void 0 : _a.value) || placeholder || type === 'color' || type === 'range'
|
|
2217
2626
|
? true
|
|
2218
2627
|
: false;
|
|
2628
|
+
// Special rendering for minmax range sliders
|
|
2629
|
+
if (type === 'range' && attrs.minmax) {
|
|
2630
|
+
return renderMinMaxRange(attrs, state, cn, style, iconName, id, label, isMandatory, helperText);
|
|
2631
|
+
}
|
|
2632
|
+
// Special rendering for single range sliders with tooltips
|
|
2633
|
+
if (type === 'range' && attrs.showValue) {
|
|
2634
|
+
return renderSingleRangeWithTooltip(attrs, state, cn, style, iconName, id, label, isMandatory, helperText);
|
|
2635
|
+
}
|
|
2219
2636
|
return m('.input-field', { className: cn, style }, [
|
|
2220
2637
|
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
2221
2638
|
m('input.validate', Object.assign(Object.assign({}, params), { type, tabindex: 0, id,
|
|
2222
|
-
placeholder,
|
|
2639
|
+
placeholder, class: type === 'range' && attrs.vertical ? 'range-slider vertical' : undefined, style: type === 'range' && attrs.vertical
|
|
2640
|
+
? {
|
|
2641
|
+
height: attrs.height || '200px',
|
|
2642
|
+
width: '6px',
|
|
2643
|
+
writingMode: 'vertical-lr',
|
|
2644
|
+
direction: 'rtl',
|
|
2645
|
+
}
|
|
2646
|
+
: undefined,
|
|
2223
2647
|
// attributes,
|
|
2224
2648
|
oncreate: ({ dom }) => {
|
|
2225
2649
|
const input = (state.inputElement = dom);
|
|
@@ -2235,7 +2659,7 @@
|
|
|
2235
2659
|
state.currentLength = input.value.length; // Initial count
|
|
2236
2660
|
}
|
|
2237
2661
|
// Range input functionality
|
|
2238
|
-
if (type === 'range') {
|
|
2662
|
+
if (type === 'range' && !attrs.minmax) {
|
|
2239
2663
|
const updateThumb = () => {
|
|
2240
2664
|
const value = input.value;
|
|
2241
2665
|
const min = input.min || '0';
|
|
@@ -2488,7 +2912,7 @@
|
|
|
2488
2912
|
callback(checkedIds);
|
|
2489
2913
|
}
|
|
2490
2914
|
: undefined;
|
|
2491
|
-
const cn = [newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim();
|
|
2915
|
+
const cn = [newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim() || undefined;
|
|
2492
2916
|
const optionsContent = layout === 'horizontal'
|
|
2493
2917
|
? m('div.grid-container', options.map((option) => m(InputCheckbox, {
|
|
2494
2918
|
disabled: disabled || option.disabled,
|
|
@@ -3359,6 +3783,423 @@
|
|
|
3359
3783
|
};
|
|
3360
3784
|
};
|
|
3361
3785
|
|
|
3786
|
+
// Utility functions
|
|
3787
|
+
const getPercentage = (value, min, max) => {
|
|
3788
|
+
return ((value - min) / (max - min)) * 100;
|
|
3789
|
+
};
|
|
3790
|
+
const updateRangeValues = (minValue, maxValue, attrs, state, immediate) => {
|
|
3791
|
+
// Ensure min doesn't exceed max and vice versa
|
|
3792
|
+
if (minValue > maxValue)
|
|
3793
|
+
minValue = maxValue;
|
|
3794
|
+
if (maxValue < minValue)
|
|
3795
|
+
maxValue = minValue;
|
|
3796
|
+
state.rangeMinValue = minValue;
|
|
3797
|
+
state.rangeMaxValue = maxValue;
|
|
3798
|
+
// Call oninput for immediate feedback or onchange for final changes
|
|
3799
|
+
if (immediate && attrs.oninput) {
|
|
3800
|
+
attrs.oninput(minValue, maxValue);
|
|
3801
|
+
}
|
|
3802
|
+
else if (!immediate && attrs.onchange) {
|
|
3803
|
+
attrs.onchange(minValue, maxValue);
|
|
3804
|
+
}
|
|
3805
|
+
};
|
|
3806
|
+
// Single Range Slider with Tooltip
|
|
3807
|
+
const renderSingleRangeWithTooltip = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
3808
|
+
const { min = 0, max = 100, step = 1, initialValue, vertical = false, showValue = false, height = '200px', disabled = false, tooltipPos = 'top', oninput, onchange, } = attrs;
|
|
3809
|
+
// Initialize single range value
|
|
3810
|
+
const currentValue = initialValue !== undefined ? initialValue : state.singleValue || min;
|
|
3811
|
+
if (state.singleValue === undefined) {
|
|
3812
|
+
state.singleValue = currentValue;
|
|
3813
|
+
}
|
|
3814
|
+
const percentage = getPercentage(state.singleValue, min, max);
|
|
3815
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
3816
|
+
const containerStyle = vertical ? { height } : {};
|
|
3817
|
+
const progressStyle = vertical
|
|
3818
|
+
? {
|
|
3819
|
+
height: `${percentage}%`,
|
|
3820
|
+
}
|
|
3821
|
+
: {
|
|
3822
|
+
width: `${percentage}%`,
|
|
3823
|
+
};
|
|
3824
|
+
const thumbStyle = vertical
|
|
3825
|
+
? {
|
|
3826
|
+
bottom: `${percentage}%`,
|
|
3827
|
+
}
|
|
3828
|
+
: {
|
|
3829
|
+
left: `${percentage}%`,
|
|
3830
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
3831
|
+
};
|
|
3832
|
+
const updateSingleValue = (newValue, immediate = false) => {
|
|
3833
|
+
state.singleValue = newValue;
|
|
3834
|
+
if (immediate && oninput) {
|
|
3835
|
+
oninput(newValue);
|
|
3836
|
+
}
|
|
3837
|
+
else if (!immediate && onchange) {
|
|
3838
|
+
onchange(newValue);
|
|
3839
|
+
}
|
|
3840
|
+
};
|
|
3841
|
+
const handleMouseDown = (e) => {
|
|
3842
|
+
if (disabled)
|
|
3843
|
+
return;
|
|
3844
|
+
e.preventDefault();
|
|
3845
|
+
state.isDragging = true;
|
|
3846
|
+
// Get container reference from the current target's parent
|
|
3847
|
+
const thumbElement = e.currentTarget;
|
|
3848
|
+
const container = thumbElement.parentElement;
|
|
3849
|
+
if (!container)
|
|
3850
|
+
return;
|
|
3851
|
+
const handleMouseMove = (e) => {
|
|
3852
|
+
if (!state.isDragging || !container)
|
|
3853
|
+
return;
|
|
3854
|
+
const rect = container.getBoundingClientRect();
|
|
3855
|
+
let percentage;
|
|
3856
|
+
if (vertical) {
|
|
3857
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
3858
|
+
}
|
|
3859
|
+
else {
|
|
3860
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
3861
|
+
}
|
|
3862
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
3863
|
+
const value = min + (percentage / 100) * (max - min);
|
|
3864
|
+
const steppedValue = Math.round(value / step) * step;
|
|
3865
|
+
updateSingleValue(steppedValue, true);
|
|
3866
|
+
// Redraw to update the UI during drag
|
|
3867
|
+
m.redraw();
|
|
3868
|
+
};
|
|
3869
|
+
const handleMouseUp = () => {
|
|
3870
|
+
state.isDragging = false;
|
|
3871
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
3872
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
3873
|
+
// Fire onchange when dragging ends
|
|
3874
|
+
updateSingleValue(state.singleValue, false);
|
|
3875
|
+
};
|
|
3876
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
3877
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
3878
|
+
};
|
|
3879
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
3880
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
3881
|
+
// Determine tooltip position for vertical sliders
|
|
3882
|
+
const tooltipPosition = vertical ? (tooltipPos === 'top' || tooltipPos === 'bottom' ? 'right' : tooltipPos) : tooltipPos;
|
|
3883
|
+
return m('.input-field', { className: cn, style }, [
|
|
3884
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
3885
|
+
// Hidden input for label association and accessibility
|
|
3886
|
+
m('input[type=range]', {
|
|
3887
|
+
id,
|
|
3888
|
+
value: state.singleValue,
|
|
3889
|
+
min,
|
|
3890
|
+
max,
|
|
3891
|
+
step,
|
|
3892
|
+
style: { display: 'none' },
|
|
3893
|
+
disabled,
|
|
3894
|
+
tabindex: -1,
|
|
3895
|
+
}),
|
|
3896
|
+
m('div', { class: fieldClass, style: containerStyle }, [
|
|
3897
|
+
m(`.single-range-slider.${orientation}`, {
|
|
3898
|
+
tabindex: disabled ? -1 : 0,
|
|
3899
|
+
role: 'slider',
|
|
3900
|
+
'aria-valuemin': min,
|
|
3901
|
+
'aria-valuemax': max,
|
|
3902
|
+
'aria-valuenow': state.singleValue,
|
|
3903
|
+
'aria-label': label || 'Range slider',
|
|
3904
|
+
onclick: (e) => {
|
|
3905
|
+
// Focus the slider when clicked
|
|
3906
|
+
e.currentTarget.focus();
|
|
3907
|
+
},
|
|
3908
|
+
onkeydown: (e) => {
|
|
3909
|
+
if (disabled)
|
|
3910
|
+
return;
|
|
3911
|
+
let newValue = state.singleValue;
|
|
3912
|
+
switch (e.key) {
|
|
3913
|
+
case 'ArrowLeft':
|
|
3914
|
+
case 'ArrowDown':
|
|
3915
|
+
e.preventDefault();
|
|
3916
|
+
newValue = Math.max(min, newValue - step);
|
|
3917
|
+
updateSingleValue(newValue, false);
|
|
3918
|
+
// m.redraw();
|
|
3919
|
+
break;
|
|
3920
|
+
case 'ArrowRight':
|
|
3921
|
+
case 'ArrowUp':
|
|
3922
|
+
e.preventDefault();
|
|
3923
|
+
newValue = Math.min(max, newValue + step);
|
|
3924
|
+
updateSingleValue(newValue, false);
|
|
3925
|
+
// m.redraw();
|
|
3926
|
+
break;
|
|
3927
|
+
case 'Home':
|
|
3928
|
+
e.preventDefault();
|
|
3929
|
+
updateSingleValue(min, false);
|
|
3930
|
+
// m.redraw();
|
|
3931
|
+
break;
|
|
3932
|
+
case 'End':
|
|
3933
|
+
e.preventDefault();
|
|
3934
|
+
updateSingleValue(max, false);
|
|
3935
|
+
// m.redraw();
|
|
3936
|
+
break;
|
|
3937
|
+
}
|
|
3938
|
+
},
|
|
3939
|
+
}, [
|
|
3940
|
+
// Track
|
|
3941
|
+
m(`.track.${orientation}`),
|
|
3942
|
+
// Progress
|
|
3943
|
+
m(`.range-progress.${orientation}`, { style: progressStyle }),
|
|
3944
|
+
// Thumb
|
|
3945
|
+
m(`.thumb.${orientation}`, {
|
|
3946
|
+
style: thumbStyle,
|
|
3947
|
+
onmousedown: handleMouseDown,
|
|
3948
|
+
}, showValue
|
|
3949
|
+
? m(`.value-tooltip.${tooltipPosition}`, state.singleValue.toFixed(0))
|
|
3950
|
+
: null),
|
|
3951
|
+
]),
|
|
3952
|
+
]),
|
|
3953
|
+
label
|
|
3954
|
+
? m(Label, {
|
|
3955
|
+
label,
|
|
3956
|
+
id,
|
|
3957
|
+
isMandatory,
|
|
3958
|
+
isActive: true, // Range sliders always have active labels
|
|
3959
|
+
})
|
|
3960
|
+
: null,
|
|
3961
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
3962
|
+
]);
|
|
3963
|
+
};
|
|
3964
|
+
// Double Range Slider (Min/Max)
|
|
3965
|
+
const renderMinMaxRange = (attrs, state, cn, style, iconName, id, label, isMandatory, helperText) => {
|
|
3966
|
+
const { min = 0, max = 100, step = 1, minValue, maxValue, vertical = false, showValue = false, height = '200px', disabled = false, } = attrs;
|
|
3967
|
+
// Initialize range values
|
|
3968
|
+
const currentMinValue = minValue !== undefined ? minValue : attrs.minValue || min;
|
|
3969
|
+
const currentMaxValue = maxValue !== undefined ? maxValue : attrs.maxValue || max;
|
|
3970
|
+
if (state.rangeMinValue === undefined || state.rangeMaxValue === undefined) {
|
|
3971
|
+
state.rangeMinValue = currentMinValue;
|
|
3972
|
+
state.rangeMaxValue = currentMaxValue;
|
|
3973
|
+
}
|
|
3974
|
+
// Initialize active thumb if not set
|
|
3975
|
+
if (state.activeThumb === null) {
|
|
3976
|
+
state.activeThumb = 'min';
|
|
3977
|
+
}
|
|
3978
|
+
const minPercentage = getPercentage(state.rangeMinValue, min, max);
|
|
3979
|
+
const maxPercentage = getPercentage(state.rangeMaxValue, min, max);
|
|
3980
|
+
// Only keep dynamic styles as inline, use CSS classes for static styles
|
|
3981
|
+
const containerStyle = vertical ? { height } : {};
|
|
3982
|
+
const rangeStyle = vertical
|
|
3983
|
+
? {
|
|
3984
|
+
bottom: `${minPercentage}%`,
|
|
3985
|
+
height: `${maxPercentage - minPercentage}%`,
|
|
3986
|
+
}
|
|
3987
|
+
: {
|
|
3988
|
+
left: `${minPercentage}%`,
|
|
3989
|
+
width: `${maxPercentage - minPercentage}%`,
|
|
3990
|
+
};
|
|
3991
|
+
// Only keep dynamic positioning and z-index as inline styles
|
|
3992
|
+
const createThumbStyle = (percentage, isActive) => vertical
|
|
3993
|
+
? {
|
|
3994
|
+
bottom: `${percentage}%`,
|
|
3995
|
+
zIndex: isActive ? 10 : 5,
|
|
3996
|
+
}
|
|
3997
|
+
: {
|
|
3998
|
+
left: `${percentage}%`,
|
|
3999
|
+
marginLeft: '-10px', // Half of thumb size (20px)
|
|
4000
|
+
zIndex: isActive ? 10 : 5,
|
|
4001
|
+
};
|
|
4002
|
+
const handleMouseDown = (thumb) => (e) => {
|
|
4003
|
+
if (disabled)
|
|
4004
|
+
return;
|
|
4005
|
+
e.preventDefault();
|
|
4006
|
+
state.isDragging = true;
|
|
4007
|
+
state.activeThumb = thumb;
|
|
4008
|
+
// Get container reference from the current target's parent
|
|
4009
|
+
const thumbElement = e.currentTarget;
|
|
4010
|
+
const container = thumbElement.parentElement;
|
|
4011
|
+
if (!container)
|
|
4012
|
+
return;
|
|
4013
|
+
const handleMouseMove = (e) => {
|
|
4014
|
+
if (!state.isDragging || !container)
|
|
4015
|
+
return;
|
|
4016
|
+
const rect = container.getBoundingClientRect();
|
|
4017
|
+
let percentage;
|
|
4018
|
+
if (vertical) {
|
|
4019
|
+
percentage = ((rect.bottom - e.clientY) / rect.height) * 100;
|
|
4020
|
+
}
|
|
4021
|
+
else {
|
|
4022
|
+
percentage = ((e.clientX - rect.left) / rect.width) * 100;
|
|
4023
|
+
}
|
|
4024
|
+
percentage = Math.max(0, Math.min(100, percentage));
|
|
4025
|
+
const value = min + (percentage / 100) * (max - min);
|
|
4026
|
+
const steppedValue = Math.round(value / step) * step;
|
|
4027
|
+
if (thumb === 'min') {
|
|
4028
|
+
updateRangeValues(Math.min(steppedValue, state.rangeMaxValue), state.rangeMaxValue, attrs, state, true);
|
|
4029
|
+
}
|
|
4030
|
+
else {
|
|
4031
|
+
updateRangeValues(state.rangeMinValue, Math.max(steppedValue, state.rangeMinValue), attrs, state, true);
|
|
4032
|
+
}
|
|
4033
|
+
// Redraw to update the UI during drag
|
|
4034
|
+
m.redraw();
|
|
4035
|
+
};
|
|
4036
|
+
const handleMouseUp = () => {
|
|
4037
|
+
state.isDragging = false;
|
|
4038
|
+
state.activeThumb = null;
|
|
4039
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
4040
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
4041
|
+
// Fire onchange when dragging ends
|
|
4042
|
+
updateRangeValues(state.rangeMinValue, state.rangeMaxValue, attrs, state, false);
|
|
4043
|
+
};
|
|
4044
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
4045
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
4046
|
+
};
|
|
4047
|
+
const fieldClass = vertical ? 'range-field vertical' : 'range-field';
|
|
4048
|
+
const orientation = vertical ? 'vertical' : 'horizontal';
|
|
4049
|
+
return m('.input-field', { className: cn, style }, [
|
|
4050
|
+
iconName ? m('i.material-icons.prefix', iconName) : undefined,
|
|
4051
|
+
// Hidden inputs for label association and accessibility
|
|
4052
|
+
m('input[type=range]', {
|
|
4053
|
+
id,
|
|
4054
|
+
value: state.rangeMinValue,
|
|
4055
|
+
min,
|
|
4056
|
+
max,
|
|
4057
|
+
step,
|
|
4058
|
+
style: { display: 'none' },
|
|
4059
|
+
disabled,
|
|
4060
|
+
tabindex: -1,
|
|
4061
|
+
}),
|
|
4062
|
+
m('input[type=range]', {
|
|
4063
|
+
id: `${id}_max`,
|
|
4064
|
+
value: state.rangeMaxValue,
|
|
4065
|
+
min,
|
|
4066
|
+
max,
|
|
4067
|
+
step,
|
|
4068
|
+
style: { display: 'none' },
|
|
4069
|
+
disabled,
|
|
4070
|
+
tabindex: -1,
|
|
4071
|
+
}),
|
|
4072
|
+
m(`div`, { className: fieldClass }, [
|
|
4073
|
+
m(`.double-range-slider.${orientation}`, {
|
|
4074
|
+
style: containerStyle,
|
|
4075
|
+
tabindex: disabled ? -1 : 0,
|
|
4076
|
+
role: 'slider',
|
|
4077
|
+
'aria-valuemin': min,
|
|
4078
|
+
'aria-valuemax': max,
|
|
4079
|
+
'aria-valuenow': state.rangeMinValue,
|
|
4080
|
+
'aria-valuetext': `${state.rangeMinValue} to ${state.rangeMaxValue}`,
|
|
4081
|
+
'aria-label': label || 'Range slider',
|
|
4082
|
+
onclick: (e) => {
|
|
4083
|
+
// Focus the slider when clicked
|
|
4084
|
+
e.currentTarget.focus();
|
|
4085
|
+
},
|
|
4086
|
+
onkeydown: (e) => {
|
|
4087
|
+
if (disabled)
|
|
4088
|
+
return;
|
|
4089
|
+
let newMinValue = state.rangeMinValue;
|
|
4090
|
+
let newMaxValue = state.rangeMaxValue;
|
|
4091
|
+
const activeThumb = state.activeThumb || 'min';
|
|
4092
|
+
switch (e.key) {
|
|
4093
|
+
case 'ArrowLeft':
|
|
4094
|
+
case 'ArrowDown':
|
|
4095
|
+
e.preventDefault();
|
|
4096
|
+
if (activeThumb === 'min') {
|
|
4097
|
+
newMinValue = Math.max(min, newMinValue - step);
|
|
4098
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4099
|
+
}
|
|
4100
|
+
else {
|
|
4101
|
+
newMaxValue = Math.max(newMinValue, newMaxValue - step);
|
|
4102
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4103
|
+
}
|
|
4104
|
+
// m.redraw();
|
|
4105
|
+
break;
|
|
4106
|
+
case 'ArrowRight':
|
|
4107
|
+
case 'ArrowUp':
|
|
4108
|
+
e.preventDefault();
|
|
4109
|
+
if (activeThumb === 'min') {
|
|
4110
|
+
newMinValue = Math.min(newMaxValue, newMinValue + step);
|
|
4111
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4112
|
+
}
|
|
4113
|
+
else {
|
|
4114
|
+
newMaxValue = Math.min(max, newMaxValue + step);
|
|
4115
|
+
updateRangeValues(newMinValue, newMaxValue, attrs, state, false);
|
|
4116
|
+
}
|
|
4117
|
+
// m.redraw();
|
|
4118
|
+
break;
|
|
4119
|
+
case 'Tab':
|
|
4120
|
+
// Handle Tab navigation properly
|
|
4121
|
+
if (activeThumb === 'min') {
|
|
4122
|
+
if (e.shiftKey) {
|
|
4123
|
+
// Shift+Tab from min thumb: go to previous element (let browser handle)
|
|
4124
|
+
return; // Don't prevent default
|
|
4125
|
+
}
|
|
4126
|
+
else {
|
|
4127
|
+
// Tab from min thumb: go to max thumb
|
|
4128
|
+
e.preventDefault();
|
|
4129
|
+
state.activeThumb = 'max';
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
else { // activeThumb === 'max'
|
|
4133
|
+
if (e.shiftKey) {
|
|
4134
|
+
// Shift+Tab from max thumb: go to min thumb
|
|
4135
|
+
e.preventDefault();
|
|
4136
|
+
state.activeThumb = 'min';
|
|
4137
|
+
}
|
|
4138
|
+
else {
|
|
4139
|
+
// Tab from max thumb: go to next element (let browser handle)
|
|
4140
|
+
return; // Don't prevent default
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
break;
|
|
4144
|
+
case 'Home':
|
|
4145
|
+
e.preventDefault();
|
|
4146
|
+
if (activeThumb === 'min') {
|
|
4147
|
+
updateRangeValues(min, newMaxValue, attrs, state, false);
|
|
4148
|
+
}
|
|
4149
|
+
else {
|
|
4150
|
+
updateRangeValues(newMinValue, newMinValue, attrs, state, false);
|
|
4151
|
+
}
|
|
4152
|
+
// m.redraw();
|
|
4153
|
+
break;
|
|
4154
|
+
case 'End':
|
|
4155
|
+
e.preventDefault();
|
|
4156
|
+
if (activeThumb === 'min') {
|
|
4157
|
+
updateRangeValues(newMaxValue, newMaxValue, attrs, state, false);
|
|
4158
|
+
}
|
|
4159
|
+
else {
|
|
4160
|
+
updateRangeValues(newMinValue, max, attrs, state, false);
|
|
4161
|
+
}
|
|
4162
|
+
// m.redraw();
|
|
4163
|
+
break;
|
|
4164
|
+
}
|
|
4165
|
+
},
|
|
4166
|
+
}, [
|
|
4167
|
+
// Track
|
|
4168
|
+
m(`.track.${orientation}`),
|
|
4169
|
+
// Range
|
|
4170
|
+
m(`.range.${orientation}`, { style: rangeStyle }),
|
|
4171
|
+
// Min thumb
|
|
4172
|
+
m(`.thumb.${orientation}.min-thumb${state.activeThumb === 'min' ? '.active' : ''}`, {
|
|
4173
|
+
style: createThumbStyle(minPercentage, state.activeThumb === 'min'),
|
|
4174
|
+
onmousedown: handleMouseDown('min'),
|
|
4175
|
+
onclick: () => {
|
|
4176
|
+
state.activeThumb = 'min';
|
|
4177
|
+
// m.redraw();
|
|
4178
|
+
},
|
|
4179
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMinValue.toFixed(0)) : null),
|
|
4180
|
+
// Max thumb
|
|
4181
|
+
m(`.thumb.${orientation}.max-thumb${state.activeThumb === 'max' ? '.active' : ''}`, {
|
|
4182
|
+
style: createThumbStyle(maxPercentage, state.activeThumb === 'max'),
|
|
4183
|
+
onmousedown: handleMouseDown('max'),
|
|
4184
|
+
onclick: () => {
|
|
4185
|
+
state.activeThumb = 'max';
|
|
4186
|
+
// m.redraw();
|
|
4187
|
+
},
|
|
4188
|
+
}, showValue ? m(`.value.${orientation}`, state.rangeMaxValue.toFixed(0)) : null),
|
|
4189
|
+
]),
|
|
4190
|
+
]),
|
|
4191
|
+
label
|
|
4192
|
+
? m(Label, {
|
|
4193
|
+
label,
|
|
4194
|
+
id,
|
|
4195
|
+
isMandatory,
|
|
4196
|
+
isActive: true, // Range sliders always have active labels
|
|
4197
|
+
})
|
|
4198
|
+
: null,
|
|
4199
|
+
helperText ? m(HelperText, { helperText }) : null,
|
|
4200
|
+
]);
|
|
4201
|
+
};
|
|
4202
|
+
|
|
3362
4203
|
/**
|
|
3363
4204
|
* Pure TypeScript MaterialBox - creates an image lightbox that fills the screen when clicked
|
|
3364
4205
|
* No MaterializeCSS dependencies
|
|
@@ -3533,7 +4374,7 @@
|
|
|
3533
4374
|
view: ({ attrs }) => {
|
|
3534
4375
|
const { src, alt, width, height, caption, className, style } = attrs, otherAttrs = __rest(attrs, ["src", "alt", "width", "height", "caption", "className", "style"]);
|
|
3535
4376
|
return m('img.materialboxed', Object.assign(Object.assign({}, otherAttrs), { src, alt: alt || '', width,
|
|
3536
|
-
height, className: ['materialboxed', className].filter(Boolean).join(' '), style: Object.assign({ cursor: 'zoom-in', transition: 'opacity 200ms ease' }, style), onclick: (e) => {
|
|
4377
|
+
height, className: ['materialboxed', className].filter(Boolean).join(' ') || undefined, style: Object.assign({ cursor: 'zoom-in', transition: 'opacity 200ms ease' }, style), onclick: (e) => {
|
|
3537
4378
|
e.preventDefault();
|
|
3538
4379
|
openBox(e.target, attrs);
|
|
3539
4380
|
} }));
|
|
@@ -3615,7 +4456,7 @@
|
|
|
3615
4456
|
.filter(Boolean)
|
|
3616
4457
|
.join(' ')
|
|
3617
4458
|
.trim();
|
|
3618
|
-
const overlayClasses = ['modal-overlay', state.isOpen ? 'active' : ''].filter(Boolean).join(' ').trim();
|
|
4459
|
+
const overlayClasses = ['modal-overlay', state.isOpen ? 'active' : ''].filter(Boolean).join(' ').trim() || undefined;
|
|
3619
4460
|
return m('div', { className: 'modal-container' }, [
|
|
3620
4461
|
// Modal overlay
|
|
3621
4462
|
m('div', {
|
|
@@ -3640,23 +4481,25 @@
|
|
|
3640
4481
|
role: 'dialog',
|
|
3641
4482
|
'aria-labelledby': `${id}-title`,
|
|
3642
4483
|
'aria-describedby': description ? `${id}-desc` : undefined,
|
|
3643
|
-
style: Object.assign(Object.assign({ display: state.isOpen ? 'flex' : 'none', position: 'fixed' }, (bottomSheet
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
4484
|
+
style: Object.assign(Object.assign({ display: state.isOpen ? 'flex' : 'none', position: 'fixed' }, (bottomSheet
|
|
4485
|
+
? {
|
|
4486
|
+
// Bottom sheet positioning
|
|
4487
|
+
top: 'auto',
|
|
4488
|
+
bottom: '0',
|
|
4489
|
+
left: '0',
|
|
4490
|
+
right: '0',
|
|
4491
|
+
transform: 'none',
|
|
4492
|
+
maxWidth: '100%',
|
|
4493
|
+
borderRadius: '8px 8px 0 0',
|
|
4494
|
+
}
|
|
4495
|
+
: {
|
|
4496
|
+
// Regular modal positioning
|
|
4497
|
+
top: '50%',
|
|
4498
|
+
left: '50%',
|
|
4499
|
+
transform: 'translate(-50%, -50%)',
|
|
4500
|
+
maxWidth: '75%',
|
|
4501
|
+
borderRadius: '4px',
|
|
4502
|
+
})), { backgroundColor: 'var(--mm-modal-background, #fff)', maxHeight: '85%', overflow: 'auto', zIndex: '1003', padding: '0', flexDirection: 'column', boxShadow: '0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12), 0 11px 15px -7px rgba(0,0,0,0.20)' }),
|
|
3660
4503
|
onclick: (e) => e.stopPropagation(), // Prevent backdrop click when clicking inside modal
|
|
3661
4504
|
}, [
|
|
3662
4505
|
// Close button
|
|
@@ -4694,7 +5537,7 @@
|
|
|
4694
5537
|
callback(propId);
|
|
4695
5538
|
}
|
|
4696
5539
|
};
|
|
4697
|
-
const cn = [newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim();
|
|
5540
|
+
const cn = [newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim() || undefined;
|
|
4698
5541
|
const optionsContent = layout === 'horizontal'
|
|
4699
5542
|
? m('div.grid-container', options.map((r) => m(RadioButton, Object.assign(Object.assign({}, r), { onchange,
|
|
4700
5543
|
groupId, disabled: disabled || r.disabled, className: checkboxClass, checked: r.id === checkedId, inputId: `${componentId}-${r.id}` }))))
|
|
@@ -4967,7 +5810,7 @@
|
|
|
4967
5810
|
view: ({ attrs }) => {
|
|
4968
5811
|
const id = attrs.id || state.id;
|
|
4969
5812
|
const { label, left, right, disabled, newRow, onchange, isMandatory, className = 'col s12' } = attrs, params = __rest(attrs, ["label", "left", "right", "disabled", "newRow", "onchange", "isMandatory", "className"]);
|
|
4970
|
-
const cn = ['input-field', newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim();
|
|
5813
|
+
const cn = ['input-field', newRow ? 'clear' : '', className].filter(Boolean).join(' ').trim() || undefined;
|
|
4971
5814
|
return m('div', {
|
|
4972
5815
|
className: cn,
|
|
4973
5816
|
onclick: (e) => {
|
|
@@ -5118,7 +5961,7 @@
|
|
|
5118
5961
|
},
|
|
5119
5962
|
view: ({ attrs }) => {
|
|
5120
5963
|
const { tabWidth, tabs, className, style, swipeable = false } = attrs;
|
|
5121
|
-
const cn = [tabWidth === 'fill' ? 'tabs-fixed-width' : '', className].filter(Boolean).join(' ').trim();
|
|
5964
|
+
const cn = [tabWidth === 'fill' ? 'tabs-fixed-width' : '', className].filter(Boolean).join(' ').trim() || undefined;
|
|
5122
5965
|
const anchoredTabs = tabs.map(toAnchored());
|
|
5123
5966
|
const activeTab = setActiveTabId(anchoredTabs, attrs.selectedTabId);
|
|
5124
5967
|
updateIndicator();
|
|
@@ -6104,8 +6947,8 @@
|
|
|
6104
6947
|
}
|
|
6105
6948
|
// Check file type
|
|
6106
6949
|
if (attrs.accept) {
|
|
6107
|
-
const acceptedTypes = attrs.accept.split(',').map(type => type.trim());
|
|
6108
|
-
const isAccepted = acceptedTypes.some(acceptedType => {
|
|
6950
|
+
const acceptedTypes = attrs.accept.split(',').map((type) => type.trim());
|
|
6951
|
+
const isAccepted = acceptedTypes.some((acceptedType) => {
|
|
6109
6952
|
if (acceptedType.startsWith('.')) {
|
|
6110
6953
|
// Extension check
|
|
6111
6954
|
return file.name.toLowerCase().endsWith(acceptedType.toLowerCase());
|
|
@@ -6165,11 +7008,11 @@
|
|
|
6165
7008
|
}
|
|
6166
7009
|
// Notify parent component
|
|
6167
7010
|
if (attrs.onFilesSelected) {
|
|
6168
|
-
attrs.onFilesSelected(state.files.filter(f => !f.uploadError));
|
|
7011
|
+
attrs.onFilesSelected(state.files.filter((f) => !f.uploadError));
|
|
6169
7012
|
}
|
|
6170
7013
|
};
|
|
6171
7014
|
const removeFile = (fileToRemove, attrs) => {
|
|
6172
|
-
state.files = state.files.filter(file => file !== fileToRemove);
|
|
7015
|
+
state.files = state.files.filter((file) => file !== fileToRemove);
|
|
6173
7016
|
if (attrs.onFileRemoved) {
|
|
6174
7017
|
attrs.onFileRemoved(fileToRemove);
|
|
6175
7018
|
}
|
|
@@ -6188,11 +7031,11 @@
|
|
|
6188
7031
|
id: uniqueId(),
|
|
6189
7032
|
files: [],
|
|
6190
7033
|
isDragOver: false,
|
|
6191
|
-
isUploading: false
|
|
7034
|
+
isUploading: false,
|
|
6192
7035
|
};
|
|
6193
7036
|
},
|
|
6194
7037
|
view: ({ attrs }) => {
|
|
6195
|
-
const { accept, multiple = false, disabled = false, label = 'Choose files or drag them here', helperText, showPreview = true, className = '', error } = attrs;
|
|
7038
|
+
const { accept, multiple = false, disabled = false, label = 'Choose files or drag them here', helperText, showPreview = true, className = '', error, } = attrs;
|
|
6196
7039
|
return m('.file-upload-container', { class: className }, [
|
|
6197
7040
|
// Upload area
|
|
6198
7041
|
m('.file-upload-area', {
|
|
@@ -6200,8 +7043,10 @@
|
|
|
6200
7043
|
state.isDragOver ? 'drag-over' : '',
|
|
6201
7044
|
disabled ? 'disabled' : '',
|
|
6202
7045
|
error ? 'error' : '',
|
|
6203
|
-
state.files.length > 0 ? 'has-files' : ''
|
|
6204
|
-
]
|
|
7046
|
+
state.files.length > 0 ? 'has-files' : '',
|
|
7047
|
+
]
|
|
7048
|
+
.filter(Boolean)
|
|
7049
|
+
.join(' ') || undefined,
|
|
6205
7050
|
ondragover: (e) => {
|
|
6206
7051
|
if (disabled)
|
|
6207
7052
|
return;
|
|
@@ -6232,7 +7077,7 @@
|
|
|
6232
7077
|
return;
|
|
6233
7078
|
const input = document.getElementById(state.id);
|
|
6234
7079
|
input === null || input === void 0 ? void 0 : input.click();
|
|
6235
|
-
}
|
|
7080
|
+
},
|
|
6236
7081
|
}, [
|
|
6237
7082
|
m('input[type="file"]', {
|
|
6238
7083
|
id: state.id,
|
|
@@ -6245,57 +7090,55 @@
|
|
|
6245
7090
|
if (target.files) {
|
|
6246
7091
|
handleFiles(target.files, attrs);
|
|
6247
7092
|
}
|
|
6248
|
-
}
|
|
7093
|
+
},
|
|
6249
7094
|
}),
|
|
6250
7095
|
m('.file-upload-content', [
|
|
6251
7096
|
m('i.material-icons.file-upload-icon', 'cloud_upload'),
|
|
6252
7097
|
m('p.file-upload-label', label),
|
|
6253
7098
|
helperText && m('p.file-upload-helper', helperText),
|
|
6254
|
-
accept && m('p.file-upload-types', `Accepted: ${accept}`)
|
|
6255
|
-
])
|
|
7099
|
+
accept && m('p.file-upload-types', `Accepted: ${accept}`),
|
|
7100
|
+
]),
|
|
6256
7101
|
]),
|
|
6257
7102
|
// Error message
|
|
6258
7103
|
error && m('.file-upload-error', error),
|
|
6259
7104
|
// File list
|
|
6260
|
-
state.files.length > 0 &&
|
|
6261
|
-
m('
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
m('img', { src: file.preview, alt: file.name })
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
7105
|
+
state.files.length > 0 &&
|
|
7106
|
+
m('.file-upload-list', [
|
|
7107
|
+
m('h6', 'Selected Files:'),
|
|
7108
|
+
state.files.map((file) => m('.file-upload-item', { key: file.name + file.size }, [
|
|
7109
|
+
// Preview thumbnail
|
|
7110
|
+
showPreview && file.preview && m('.file-preview', [m('img', { src: file.preview, alt: file.name })]),
|
|
7111
|
+
// File info
|
|
7112
|
+
m('.file-info', [
|
|
7113
|
+
m('.file-name', file.name),
|
|
7114
|
+
m('.file-details', [
|
|
7115
|
+
m('span.file-size', formatFileSize(file.size)),
|
|
7116
|
+
file.type && m('span.file-type', file.type),
|
|
7117
|
+
]),
|
|
7118
|
+
// Progress bar (if uploading)
|
|
7119
|
+
file.uploadProgress !== undefined &&
|
|
7120
|
+
m('.file-progress', [
|
|
7121
|
+
m('.progress', [
|
|
7122
|
+
m('.determinate', {
|
|
7123
|
+
style: { width: `${file.uploadProgress}%` },
|
|
7124
|
+
}),
|
|
7125
|
+
]),
|
|
7126
|
+
]),
|
|
7127
|
+
// Error message
|
|
7128
|
+
file.uploadError && m('.file-error', file.uploadError),
|
|
6281
7129
|
]),
|
|
6282
|
-
//
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
}, [
|
|
6293
|
-
m('i.material-icons', 'close')
|
|
6294
|
-
])
|
|
6295
|
-
]))
|
|
6296
|
-
])
|
|
7130
|
+
// Remove button
|
|
7131
|
+
m('button.btn-flat.file-remove', {
|
|
7132
|
+
onclick: (e) => {
|
|
7133
|
+
e.stopPropagation();
|
|
7134
|
+
removeFile(file, attrs);
|
|
7135
|
+
},
|
|
7136
|
+
title: 'Remove file',
|
|
7137
|
+
}, [m('i.material-icons', 'close')]),
|
|
7138
|
+
])),
|
|
7139
|
+
]),
|
|
6297
7140
|
]);
|
|
6298
|
-
}
|
|
7141
|
+
},
|
|
6299
7142
|
};
|
|
6300
7143
|
};
|
|
6301
7144
|
|
|
@@ -6325,7 +7168,7 @@
|
|
|
6325
7168
|
state = {
|
|
6326
7169
|
id: attrs.id || uniqueId(),
|
|
6327
7170
|
isOpen: attrs.isOpen || false,
|
|
6328
|
-
isAnimating: false
|
|
7171
|
+
isAnimating: false,
|
|
6329
7172
|
};
|
|
6330
7173
|
// Set up keyboard listener
|
|
6331
7174
|
if (typeof document !== 'undefined' && attrs.closeOnEscape !== false) {
|
|
@@ -6354,34 +7197,33 @@
|
|
|
6354
7197
|
}
|
|
6355
7198
|
},
|
|
6356
7199
|
view: ({ attrs, children }) => {
|
|
6357
|
-
const { position = 'left', mode = 'overlay', width = 300, className = '', showBackdrop = true, animationDuration = 300, fixed = false } = attrs;
|
|
7200
|
+
const { position = 'left', mode = 'overlay', width = 300, className = '', showBackdrop = true, animationDuration = 300, fixed = false, } = attrs;
|
|
6358
7201
|
const isOpen = state.isOpen;
|
|
6359
7202
|
return [
|
|
6360
7203
|
// Backdrop (using existing materialize class)
|
|
6361
|
-
showBackdrop &&
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
7204
|
+
showBackdrop &&
|
|
7205
|
+
mode === 'overlay' &&
|
|
7206
|
+
m('.sidenav-overlay', {
|
|
7207
|
+
style: {
|
|
7208
|
+
display: isOpen ? 'block' : 'none',
|
|
7209
|
+
opacity: isOpen ? '1' : '0',
|
|
7210
|
+
},
|
|
7211
|
+
onclick: () => handleBackdropClick(attrs),
|
|
7212
|
+
}),
|
|
6368
7213
|
// Sidenav (using existing materialize structure)
|
|
6369
7214
|
m('ul.sidenav', {
|
|
6370
7215
|
id: state.id,
|
|
6371
|
-
class: [
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
className
|
|
6375
|
-
].filter(Boolean).join(' '),
|
|
7216
|
+
class: [position === 'right' ? 'right-aligned' : '', fixed ? 'sidenav-fixed' : '', className]
|
|
7217
|
+
.filter(Boolean)
|
|
7218
|
+
.join(' ') || undefined,
|
|
6376
7219
|
style: {
|
|
6377
7220
|
width: `${width}px`,
|
|
6378
|
-
transform: isOpen ? 'translateX(0)' :
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
}, children)
|
|
7221
|
+
transform: isOpen ? 'translateX(0)' : position === 'left' ? 'translateX(-105%)' : 'translateX(105%)',
|
|
7222
|
+
'transition-duration': `${animationDuration}ms`,
|
|
7223
|
+
},
|
|
7224
|
+
}, children),
|
|
6383
7225
|
];
|
|
6384
|
-
}
|
|
7226
|
+
},
|
|
6385
7227
|
};
|
|
6386
7228
|
};
|
|
6387
7229
|
/**
|
|
@@ -6391,37 +7233,30 @@
|
|
|
6391
7233
|
const SidenavItem = () => {
|
|
6392
7234
|
return {
|
|
6393
7235
|
view: ({ attrs, children }) => {
|
|
6394
|
-
const { text, icon, active = false, disabled = false, onclick, href, className = '', divider = false, subheader = false } = attrs;
|
|
7236
|
+
const { text, icon, active = false, disabled = false, onclick, href, className = '', divider = false, subheader = false, } = attrs;
|
|
6395
7237
|
if (divider) {
|
|
6396
7238
|
return m('li.divider');
|
|
6397
7239
|
}
|
|
6398
7240
|
if (subheader) {
|
|
6399
7241
|
return m('li.subheader', text || children);
|
|
6400
7242
|
}
|
|
6401
|
-
const itemClasses = [
|
|
6402
|
-
|
|
6403
|
-
disabled ? 'disabled' : '',
|
|
6404
|
-
className
|
|
6405
|
-
].filter(Boolean).join(' ');
|
|
6406
|
-
const content = [
|
|
6407
|
-
icon && m('i.material-icons', icon),
|
|
6408
|
-
text || children
|
|
6409
|
-
];
|
|
7243
|
+
const itemClasses = [active ? 'active' : '', disabled ? 'disabled' : '', className].filter(Boolean).join(' ') || undefined;
|
|
7244
|
+
const content = [icon && m('i.material-icons', icon), text || children];
|
|
6410
7245
|
if (href && !disabled) {
|
|
6411
7246
|
return m('li', { class: itemClasses }, [
|
|
6412
7247
|
m('a', {
|
|
6413
7248
|
href,
|
|
6414
|
-
onclick: disabled ? undefined : onclick
|
|
6415
|
-
}, content)
|
|
7249
|
+
onclick: disabled ? undefined : onclick,
|
|
7250
|
+
}, content),
|
|
6416
7251
|
]);
|
|
6417
7252
|
}
|
|
6418
7253
|
return m('li', { class: itemClasses }, [
|
|
6419
7254
|
m('a', {
|
|
6420
7255
|
onclick: disabled ? undefined : onclick,
|
|
6421
|
-
href: '#!'
|
|
6422
|
-
}, content)
|
|
7256
|
+
href: '#!',
|
|
7257
|
+
}, content),
|
|
6423
7258
|
]);
|
|
6424
|
-
}
|
|
7259
|
+
},
|
|
6425
7260
|
};
|
|
6426
7261
|
};
|
|
6427
7262
|
/**
|
|
@@ -6472,7 +7307,7 @@
|
|
|
6472
7307
|
const Breadcrumb = () => {
|
|
6473
7308
|
return {
|
|
6474
7309
|
view: ({ attrs }) => {
|
|
6475
|
-
const { items = [], separator = 'chevron_right', className = '', showIcons = false, maxItems, showHome = false } = attrs;
|
|
7310
|
+
const { items = [], separator = 'chevron_right', className = '', showIcons = false, maxItems, showHome = false, } = attrs;
|
|
6476
7311
|
if (items.length === 0) {
|
|
6477
7312
|
return null;
|
|
6478
7313
|
}
|
|
@@ -6481,52 +7316,46 @@
|
|
|
6481
7316
|
if (maxItems && items.length > maxItems) {
|
|
6482
7317
|
const firstItem = items[0];
|
|
6483
7318
|
const lastItems = items.slice(-(maxItems - 2));
|
|
6484
|
-
displayItems = [
|
|
6485
|
-
firstItem,
|
|
6486
|
-
{ text: '...', disabled: true, className: 'breadcrumb-ellipsis' },
|
|
6487
|
-
...lastItems
|
|
6488
|
-
];
|
|
7319
|
+
displayItems = [firstItem, { text: '...', disabled: true, className: 'breadcrumb-ellipsis' }, ...lastItems];
|
|
6489
7320
|
}
|
|
6490
7321
|
return m('nav.breadcrumb', { class: className }, [
|
|
6491
|
-
m('ol.breadcrumb-list', displayItems
|
|
7322
|
+
m('ol.breadcrumb-list', displayItems
|
|
7323
|
+
.map((item, index) => {
|
|
6492
7324
|
const isLast = index === displayItems.length - 1;
|
|
6493
7325
|
const isFirst = index === 0;
|
|
6494
7326
|
return [
|
|
6495
7327
|
// Breadcrumb item
|
|
6496
7328
|
m('li.breadcrumb-item', {
|
|
6497
|
-
class: [
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
item.className || ''
|
|
6501
|
-
].filter(Boolean).join(' ')
|
|
7329
|
+
class: [item.active || isLast ? 'active' : '', item.disabled ? 'disabled' : '', item.className || '']
|
|
7330
|
+
.filter(Boolean)
|
|
7331
|
+
.join(' ') || undefined,
|
|
6502
7332
|
}, [
|
|
6503
|
-
item.href && !item.disabled && !isLast
|
|
6504
|
-
// Link item
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
// Text item (active or disabled)
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
7333
|
+
item.href && !item.disabled && !isLast
|
|
7334
|
+
? // Link item
|
|
7335
|
+
m('a.breadcrumb-link', {
|
|
7336
|
+
href: item.href,
|
|
7337
|
+
onclick: item.onclick,
|
|
7338
|
+
}, [
|
|
7339
|
+
showIcons && item.icon && m('i.material-icons.breadcrumb-icon', item.icon),
|
|
7340
|
+
showHome && isFirst && !item.icon && m('i.material-icons.breadcrumb-icon', 'home'),
|
|
7341
|
+
m('span.breadcrumb-text', item.text),
|
|
7342
|
+
])
|
|
7343
|
+
: // Text item (active or disabled)
|
|
7344
|
+
m('span.breadcrumb-text', {
|
|
7345
|
+
onclick: item.disabled ? undefined : item.onclick,
|
|
7346
|
+
}, [
|
|
7347
|
+
showIcons && item.icon && m('i.material-icons.breadcrumb-icon', item.icon),
|
|
7348
|
+
showHome && isFirst && !item.icon && m('i.material-icons.breadcrumb-icon', 'home'),
|
|
7349
|
+
item.text,
|
|
7350
|
+
]),
|
|
6521
7351
|
]),
|
|
6522
7352
|
// Separator (except for last item)
|
|
6523
|
-
!isLast && m('li.breadcrumb-separator', [
|
|
6524
|
-
m('i.material-icons', separator)
|
|
6525
|
-
])
|
|
7353
|
+
!isLast && m('li.breadcrumb-separator', [m('i.material-icons', separator)]),
|
|
6526
7354
|
];
|
|
6527
|
-
})
|
|
7355
|
+
})
|
|
7356
|
+
.reduce((acc, val) => acc.concat(val), [])),
|
|
6528
7357
|
]);
|
|
6529
|
-
}
|
|
7358
|
+
},
|
|
6530
7359
|
};
|
|
6531
7360
|
};
|
|
6532
7361
|
/**
|
|
@@ -6539,7 +7368,7 @@
|
|
|
6539
7368
|
items.push({
|
|
6540
7369
|
text: 'Home',
|
|
6541
7370
|
href: basePath,
|
|
6542
|
-
icon: 'home'
|
|
7371
|
+
icon: 'home',
|
|
6543
7372
|
});
|
|
6544
7373
|
// Add path segments
|
|
6545
7374
|
let currentPath = basePath;
|
|
@@ -6549,7 +7378,7 @@
|
|
|
6549
7378
|
items.push({
|
|
6550
7379
|
text: segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' '),
|
|
6551
7380
|
href: isLast ? undefined : currentPath,
|
|
6552
|
-
active: isLast
|
|
7381
|
+
active: isLast,
|
|
6553
7382
|
});
|
|
6554
7383
|
});
|
|
6555
7384
|
return items;
|
|
@@ -6568,19 +7397,18 @@
|
|
|
6568
7397
|
items.push({
|
|
6569
7398
|
text: 'Home',
|
|
6570
7399
|
href: '/',
|
|
6571
|
-
icon: 'home'
|
|
7400
|
+
icon: 'home',
|
|
6572
7401
|
});
|
|
6573
7402
|
let currentPath = '';
|
|
6574
7403
|
segments.forEach((segment, index) => {
|
|
6575
7404
|
currentPath += '/' + segment;
|
|
6576
7405
|
const isLast = index === segments.length - 1;
|
|
6577
7406
|
// Use custom text from config or format segment
|
|
6578
|
-
const text = routeConfig[currentPath] ||
|
|
6579
|
-
segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ');
|
|
7407
|
+
const text = routeConfig[currentPath] || segment.charAt(0).toUpperCase() + segment.slice(1).replace(/-/g, ' ');
|
|
6580
7408
|
items.push({
|
|
6581
7409
|
text,
|
|
6582
7410
|
href: isLast ? undefined : currentPath,
|
|
6583
|
-
active: isLast
|
|
7411
|
+
active: isLast,
|
|
6584
7412
|
});
|
|
6585
7413
|
});
|
|
6586
7414
|
return items;
|
|
@@ -6592,7 +7420,7 @@
|
|
|
6592
7420
|
return hierarchy.map((item, index) => ({
|
|
6593
7421
|
text: item[textKey],
|
|
6594
7422
|
href: index === hierarchy.length - 1 ? undefined : item[pathKey],
|
|
6595
|
-
active: index === hierarchy.length - 1
|
|
7423
|
+
active: index === hierarchy.length - 1,
|
|
6596
7424
|
}));
|
|
6597
7425
|
}
|
|
6598
7426
|
}
|
|
@@ -6726,7 +7554,7 @@
|
|
|
6726
7554
|
hasError ? 'error' : '',
|
|
6727
7555
|
step.disabled ? 'disabled' : '',
|
|
6728
7556
|
step.optional ? 'optional' : ''
|
|
6729
|
-
].filter(Boolean).join(' '),
|
|
7557
|
+
].filter(Boolean).join(' ') || undefined,
|
|
6730
7558
|
onclick: allowHeaderNavigation && !step.disabled ?
|
|
6731
7559
|
() => goToStep(index, attrs) : undefined
|
|
6732
7560
|
}, [
|
|
@@ -6800,6 +7628,292 @@
|
|
|
6800
7628
|
};
|
|
6801
7629
|
};
|
|
6802
7630
|
|
|
7631
|
+
// Utility function to check if a node is the last in its branch
|
|
7632
|
+
const isNodeLastInBranch = (nodePath, rootNodes) => {
|
|
7633
|
+
// Navigate to the node's position and check if it's the last child at every level
|
|
7634
|
+
let currentNodes = rootNodes;
|
|
7635
|
+
for (let i = 0; i < nodePath.length; i++) {
|
|
7636
|
+
const index = nodePath[i];
|
|
7637
|
+
const isLastAtThisLevel = index === currentNodes.length - 1;
|
|
7638
|
+
// If this is not the last child at this level, then this node is not last in branch
|
|
7639
|
+
if (!isLastAtThisLevel) {
|
|
7640
|
+
return false;
|
|
7641
|
+
}
|
|
7642
|
+
// Move to the next level if it exists
|
|
7643
|
+
if (i < nodePath.length - 1) {
|
|
7644
|
+
const currentNode = currentNodes[index];
|
|
7645
|
+
if (currentNode.children) {
|
|
7646
|
+
currentNodes = currentNode.children;
|
|
7647
|
+
}
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
return true;
|
|
7651
|
+
};
|
|
7652
|
+
const TreeNodeComponent = () => {
|
|
7653
|
+
return {
|
|
7654
|
+
view: ({ attrs }) => {
|
|
7655
|
+
const { node, level, isSelected, isExpanded, isFocused, showConnectors, iconType, selectionMode, onToggleExpand, onToggleSelect, onFocus, } = attrs;
|
|
7656
|
+
const hasChildren = node.children && node.children.length > 0;
|
|
7657
|
+
const indentLevel = level * 24; // 24px per level
|
|
7658
|
+
return m('li.tree-node', {
|
|
7659
|
+
class: [
|
|
7660
|
+
isSelected && 'selected',
|
|
7661
|
+
isFocused && 'focused',
|
|
7662
|
+
node.disabled && 'disabled',
|
|
7663
|
+
hasChildren && 'has-children',
|
|
7664
|
+
attrs.isLastInBranch && 'tree-last-in-branch',
|
|
7665
|
+
]
|
|
7666
|
+
.filter(Boolean)
|
|
7667
|
+
.join(' ') || undefined,
|
|
7668
|
+
'data-node-id': node.id,
|
|
7669
|
+
'data-level': level,
|
|
7670
|
+
}, [
|
|
7671
|
+
// Node content
|
|
7672
|
+
m('.tree-node-content', {
|
|
7673
|
+
style: {
|
|
7674
|
+
paddingLeft: `${indentLevel}px`,
|
|
7675
|
+
},
|
|
7676
|
+
onclick: node.disabled
|
|
7677
|
+
? undefined
|
|
7678
|
+
: () => {
|
|
7679
|
+
if (selectionMode !== 'none') {
|
|
7680
|
+
onToggleSelect(node.id);
|
|
7681
|
+
}
|
|
7682
|
+
onFocus(node.id);
|
|
7683
|
+
},
|
|
7684
|
+
onkeydown: (e) => {
|
|
7685
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
7686
|
+
e.preventDefault();
|
|
7687
|
+
if (!node.disabled && selectionMode !== 'none') {
|
|
7688
|
+
onToggleSelect(node.id);
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7691
|
+
},
|
|
7692
|
+
tabindex: node.disabled ? -1 : 0,
|
|
7693
|
+
role: selectionMode === 'multiple' ? 'option' : 'treeitem',
|
|
7694
|
+
'aria-selected': selectionMode !== 'none' ? isSelected.toString() : undefined,
|
|
7695
|
+
'aria-expanded': hasChildren ? isExpanded.toString() : undefined,
|
|
7696
|
+
'aria-disabled': node.disabled ? 'true' : undefined,
|
|
7697
|
+
}, [
|
|
7698
|
+
// Connector lines
|
|
7699
|
+
showConnectors &&
|
|
7700
|
+
level > 0 &&
|
|
7701
|
+
m('.tree-connectors', Array.from({ length: level }, (_, i) => m('.tree-connector', {
|
|
7702
|
+
key: i,
|
|
7703
|
+
style: { left: `${i * 24 + 12}px` },
|
|
7704
|
+
}))),
|
|
7705
|
+
// Expand/collapse icon or spacer
|
|
7706
|
+
hasChildren
|
|
7707
|
+
? m('.tree-expand-icon', {
|
|
7708
|
+
onclick: (e) => {
|
|
7709
|
+
e.stopPropagation();
|
|
7710
|
+
if (!node.disabled) {
|
|
7711
|
+
onToggleExpand(node.id);
|
|
7712
|
+
}
|
|
7713
|
+
},
|
|
7714
|
+
class: iconType,
|
|
7715
|
+
}, [
|
|
7716
|
+
iconType === 'plus-minus'
|
|
7717
|
+
? m('span.tree-plus-minus', isExpanded ? '−' : '+')
|
|
7718
|
+
: iconType === 'triangle'
|
|
7719
|
+
? m('span.tree-triangle', { class: isExpanded ? 'expanded' : undefined }, '▶')
|
|
7720
|
+
: iconType === 'chevron'
|
|
7721
|
+
? m(MaterialIcon, {
|
|
7722
|
+
name: 'chevron',
|
|
7723
|
+
direction: isExpanded ? 'down' : 'right',
|
|
7724
|
+
class: 'tree-chevron-icon',
|
|
7725
|
+
})
|
|
7726
|
+
: m(MaterialIcon, {
|
|
7727
|
+
name: 'caret',
|
|
7728
|
+
direction: isExpanded ? 'down' : 'right',
|
|
7729
|
+
class: 'tree-caret-icon',
|
|
7730
|
+
}),
|
|
7731
|
+
])
|
|
7732
|
+
: m('.tree-expand-spacer'), // Spacer for alignment
|
|
7733
|
+
// Selection indicator for multiple selection
|
|
7734
|
+
selectionMode === 'multiple' &&
|
|
7735
|
+
m('.tree-selection-indicator', [
|
|
7736
|
+
m('input[type=checkbox]', {
|
|
7737
|
+
checked: isSelected,
|
|
7738
|
+
disabled: node.disabled,
|
|
7739
|
+
onchange: () => {
|
|
7740
|
+
if (!node.disabled) {
|
|
7741
|
+
onToggleSelect(node.id);
|
|
7742
|
+
}
|
|
7743
|
+
},
|
|
7744
|
+
onclick: (e) => e.stopPropagation(),
|
|
7745
|
+
}),
|
|
7746
|
+
]),
|
|
7747
|
+
// Node icon (optional)
|
|
7748
|
+
node.icon && m('i.tree-node-icon.material-icons', node.icon),
|
|
7749
|
+
// Node label
|
|
7750
|
+
m('span.tree-node-label', node.label),
|
|
7751
|
+
]),
|
|
7752
|
+
// Children (recursive)
|
|
7753
|
+
hasChildren &&
|
|
7754
|
+
isExpanded &&
|
|
7755
|
+
m('ul.tree-children', {
|
|
7756
|
+
role: 'group',
|
|
7757
|
+
'aria-expanded': 'true',
|
|
7758
|
+
}, node.children.map((child, childIndex) => {
|
|
7759
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7760
|
+
// Calculate state for each child using treeState
|
|
7761
|
+
const childIsSelected = (_b = (_a = attrs.treeState) === null || _a === void 0 ? void 0 : _a.selectedIds.has(child.id)) !== null && _b !== void 0 ? _b : false;
|
|
7762
|
+
const childIsExpanded = (_d = (_c = attrs.treeState) === null || _c === void 0 ? void 0 : _c.expandedIds.has(child.id)) !== null && _d !== void 0 ? _d : false;
|
|
7763
|
+
const childIsFocused = ((_e = attrs.treeState) === null || _e === void 0 ? void 0 : _e.focusedNodeId) === child.id;
|
|
7764
|
+
// Calculate if this child is last in branch
|
|
7765
|
+
const childPath = [...(attrs.currentPath || []), childIndex];
|
|
7766
|
+
const childIsLastInBranch = ((_f = attrs.treeAttrs) === null || _f === void 0 ? void 0 : _f.data) ?
|
|
7767
|
+
isNodeLastInBranch(childPath, attrs.treeAttrs.data) : false;
|
|
7768
|
+
return m(TreeNodeComponent, {
|
|
7769
|
+
key: child.id,
|
|
7770
|
+
node: child,
|
|
7771
|
+
level: level + 1,
|
|
7772
|
+
isSelected: childIsSelected,
|
|
7773
|
+
isExpanded: childIsExpanded,
|
|
7774
|
+
isFocused: childIsFocused,
|
|
7775
|
+
showConnectors,
|
|
7776
|
+
iconType,
|
|
7777
|
+
selectionMode,
|
|
7778
|
+
onToggleExpand,
|
|
7779
|
+
onToggleSelect,
|
|
7780
|
+
onFocus,
|
|
7781
|
+
isLastInBranch: childIsLastInBranch,
|
|
7782
|
+
currentPath: childPath,
|
|
7783
|
+
treeState: attrs.treeState,
|
|
7784
|
+
treeAttrs: attrs.treeAttrs,
|
|
7785
|
+
});
|
|
7786
|
+
})),
|
|
7787
|
+
]);
|
|
7788
|
+
},
|
|
7789
|
+
};
|
|
7790
|
+
};
|
|
7791
|
+
const TreeView = () => {
|
|
7792
|
+
const state = {
|
|
7793
|
+
selectedIds: new Set(),
|
|
7794
|
+
expandedIds: new Set(),
|
|
7795
|
+
focusedNodeId: null,
|
|
7796
|
+
treeMap: new Map(),
|
|
7797
|
+
};
|
|
7798
|
+
const buildTreeMap = (nodes, map) => {
|
|
7799
|
+
nodes.forEach((node) => {
|
|
7800
|
+
map.set(node.id, node);
|
|
7801
|
+
if (node.children) {
|
|
7802
|
+
buildTreeMap(node.children, map);
|
|
7803
|
+
}
|
|
7804
|
+
});
|
|
7805
|
+
};
|
|
7806
|
+
const initializeExpandedNodes = (nodes) => {
|
|
7807
|
+
nodes.forEach((node) => {
|
|
7808
|
+
if (node.expanded) {
|
|
7809
|
+
state.expandedIds.add(node.id);
|
|
7810
|
+
}
|
|
7811
|
+
if (node.children) {
|
|
7812
|
+
initializeExpandedNodes(node.children);
|
|
7813
|
+
}
|
|
7814
|
+
});
|
|
7815
|
+
};
|
|
7816
|
+
const handleToggleExpand = (nodeId, attrs) => {
|
|
7817
|
+
var _a;
|
|
7818
|
+
const isExpanded = state.expandedIds.has(nodeId);
|
|
7819
|
+
if (isExpanded) {
|
|
7820
|
+
state.expandedIds.delete(nodeId);
|
|
7821
|
+
}
|
|
7822
|
+
else {
|
|
7823
|
+
state.expandedIds.add(nodeId);
|
|
7824
|
+
}
|
|
7825
|
+
(_a = attrs.onexpand) === null || _a === void 0 ? void 0 : _a.call(attrs, { nodeId, expanded: !isExpanded });
|
|
7826
|
+
};
|
|
7827
|
+
const handleToggleSelect = (nodeId, attrs) => {
|
|
7828
|
+
var _a;
|
|
7829
|
+
const { selectionMode = 'single' } = attrs;
|
|
7830
|
+
if (selectionMode === 'single') {
|
|
7831
|
+
state.selectedIds.clear();
|
|
7832
|
+
state.selectedIds.add(nodeId);
|
|
7833
|
+
}
|
|
7834
|
+
else if (selectionMode === 'multiple') {
|
|
7835
|
+
if (state.selectedIds.has(nodeId)) {
|
|
7836
|
+
state.selectedIds.delete(nodeId);
|
|
7837
|
+
}
|
|
7838
|
+
else {
|
|
7839
|
+
state.selectedIds.add(nodeId);
|
|
7840
|
+
}
|
|
7841
|
+
}
|
|
7842
|
+
(_a = attrs.onselection) === null || _a === void 0 ? void 0 : _a.call(attrs, Array.from(state.selectedIds));
|
|
7843
|
+
};
|
|
7844
|
+
const handleFocus = (nodeId) => {
|
|
7845
|
+
state.focusedNodeId = nodeId;
|
|
7846
|
+
};
|
|
7847
|
+
const renderNodes = (nodes, attrs, level = 0, parentPath = []) => {
|
|
7848
|
+
return nodes.map((node, index) => {
|
|
7849
|
+
var _a, _b, _c;
|
|
7850
|
+
const isSelected = state.selectedIds.has(node.id);
|
|
7851
|
+
const isExpanded = state.expandedIds.has(node.id);
|
|
7852
|
+
const isFocused = state.focusedNodeId === node.id;
|
|
7853
|
+
const currentPath = [...parentPath, index];
|
|
7854
|
+
const isLastInBranch = isNodeLastInBranch(currentPath, attrs.data);
|
|
7855
|
+
return m(TreeNodeComponent, {
|
|
7856
|
+
key: node.id,
|
|
7857
|
+
node,
|
|
7858
|
+
level,
|
|
7859
|
+
isSelected,
|
|
7860
|
+
isExpanded,
|
|
7861
|
+
isFocused,
|
|
7862
|
+
showConnectors: (_a = attrs.showConnectors) !== null && _a !== void 0 ? _a : true,
|
|
7863
|
+
iconType: (_b = attrs.iconType) !== null && _b !== void 0 ? _b : 'caret',
|
|
7864
|
+
selectionMode: (_c = attrs.selectionMode) !== null && _c !== void 0 ? _c : 'single',
|
|
7865
|
+
onToggleExpand: (nodeId) => handleToggleExpand(nodeId, attrs),
|
|
7866
|
+
onToggleSelect: (nodeId) => handleToggleSelect(nodeId, attrs),
|
|
7867
|
+
onFocus: handleFocus,
|
|
7868
|
+
isLastInBranch,
|
|
7869
|
+
currentPath,
|
|
7870
|
+
// Pass state and attrs for recursive rendering
|
|
7871
|
+
treeState: state,
|
|
7872
|
+
treeAttrs: attrs,
|
|
7873
|
+
});
|
|
7874
|
+
});
|
|
7875
|
+
};
|
|
7876
|
+
return {
|
|
7877
|
+
oninit: ({ attrs }) => {
|
|
7878
|
+
// Build internal tree map for efficient lookups
|
|
7879
|
+
buildTreeMap(attrs.data, state.treeMap);
|
|
7880
|
+
// Initialize expanded nodes from data
|
|
7881
|
+
initializeExpandedNodes(attrs.data);
|
|
7882
|
+
// Initialize selected nodes from props
|
|
7883
|
+
if (attrs.selectedIds) {
|
|
7884
|
+
state.selectedIds = new Set(attrs.selectedIds);
|
|
7885
|
+
}
|
|
7886
|
+
},
|
|
7887
|
+
onupdate: ({ attrs }) => {
|
|
7888
|
+
// Sync selectedIds prop with internal state
|
|
7889
|
+
if (attrs.selectedIds) {
|
|
7890
|
+
const newSelection = new Set(attrs.selectedIds);
|
|
7891
|
+
if (newSelection.size !== state.selectedIds.size ||
|
|
7892
|
+
!Array.from(newSelection).every((id) => state.selectedIds.has(id))) {
|
|
7893
|
+
state.selectedIds = newSelection;
|
|
7894
|
+
}
|
|
7895
|
+
}
|
|
7896
|
+
},
|
|
7897
|
+
view: ({ attrs }) => {
|
|
7898
|
+
const { data, className, style, id, selectionMode = 'single', showConnectors = true } = attrs;
|
|
7899
|
+
return m('div.tree-view', {
|
|
7900
|
+
class: [
|
|
7901
|
+
className,
|
|
7902
|
+
showConnectors && 'show-connectors'
|
|
7903
|
+
].filter(Boolean).join(' ') || undefined,
|
|
7904
|
+
style,
|
|
7905
|
+
id,
|
|
7906
|
+
role: selectionMode === 'multiple' ? 'listbox' : 'tree',
|
|
7907
|
+
'aria-multiselectable': selectionMode === 'multiple' ? 'true' : 'false',
|
|
7908
|
+
}, [
|
|
7909
|
+
m('ul.tree-root', {
|
|
7910
|
+
role: 'group',
|
|
7911
|
+
}, renderNodes(data, attrs)),
|
|
7912
|
+
]);
|
|
7913
|
+
},
|
|
7914
|
+
};
|
|
7915
|
+
};
|
|
7916
|
+
|
|
6803
7917
|
/**
|
|
6804
7918
|
* @fileoverview Core TypeScript utility types for mithril-materialized library
|
|
6805
7919
|
* These types improve type safety and developer experience across all components
|
|
@@ -6851,6 +7965,7 @@
|
|
|
6851
7965
|
exports.ListItem = ListItem;
|
|
6852
7966
|
exports.Mandatory = Mandatory;
|
|
6853
7967
|
exports.MaterialBox = MaterialBox;
|
|
7968
|
+
exports.MaterialIcon = MaterialIcon;
|
|
6854
7969
|
exports.ModalPanel = ModalPanel;
|
|
6855
7970
|
exports.NumberInput = NumberInput;
|
|
6856
7971
|
exports.Options = Options;
|
|
@@ -6885,6 +8000,7 @@
|
|
|
6885
8000
|
exports.ToastComponent = ToastComponent;
|
|
6886
8001
|
exports.Tooltip = Tooltip;
|
|
6887
8002
|
exports.TooltipComponent = TooltipComponent;
|
|
8003
|
+
exports.TreeView = TreeView;
|
|
6888
8004
|
exports.UrlInput = UrlInput;
|
|
6889
8005
|
exports.Wizard = Wizard;
|
|
6890
8006
|
exports.createBreadcrumb = createBreadcrumb;
|
|
@@ -6896,6 +8012,8 @@
|
|
|
6896
8012
|
exports.isValidationSuccess = isValidationSuccess;
|
|
6897
8013
|
exports.padLeft = padLeft;
|
|
6898
8014
|
exports.range = range;
|
|
8015
|
+
exports.renderMinMaxRange = renderMinMaxRange;
|
|
8016
|
+
exports.renderSingleRangeWithTooltip = renderSingleRangeWithTooltip;
|
|
6899
8017
|
exports.toast = toast;
|
|
6900
8018
|
exports.uniqueId = uniqueId;
|
|
6901
8019
|
exports.uuid4 = uuid4;
|