kmaterialize 2.3.3-1.0.2 → 2.3.3-1.0.21
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 +4 -4
- package/components/air-datepicker/_air-datepicker.scss +137 -0
- package/components/air-datepicker/air-datepicker.ts +192 -0
- package/components/alert/_alerts.scss +130 -0
- package/components/alert/alert.ts +73 -0
- package/components/appbar/appbar.css +301 -4
- package/components/button/_buttons.scss +39 -1
- package/components/card/_cards.scss +9 -1
- package/components/checkbox/_checkboxes.scss +120 -229
- package/components/collapsible/_collapsible.scss +50 -0
- package/components/color-input/_color-input.scss +124 -0
- package/components/color-input/color-input.ts +203 -0
- package/components/dropdown/dropdown.ts +1 -1
- package/components/file-input/_file-input-enhanced.scss +61 -0
- package/components/file-input/file-input.ts +203 -0
- package/components/kanban/_kanban.scss +148 -0
- package/components/kanban/kanban.ts +133 -0
- package/components/list/_collection.scss +10 -2
- package/components/number-input/number-input.ts +103 -0
- package/components/password-input/password-input.ts +72 -0
- package/components/slider/_range.scss +5 -1
- package/components/switch/_switches.scss +5 -0
- package/components/textfield/_input-fields.scss +4 -4
- package/components/textfield/_select.scss +54 -0
- package/components/tom-select/_tom-select-field.scss +256 -0
- package/components/tom-select/tom-select-field.ts +175 -0
- package/components/toolbar/_toolbar.scss +324 -0
- package/components/toolbar/toolbar.ts +152 -0
- package/dist/css/materialize.colors.min.css +2 -2
- package/dist/css/materialize.css +10575 -711
- package/dist/css/materialize.min.css +2 -2
- package/dist/css/materialize.min.css.map +1 -1
- package/dist/js/materialize.cjs.js +1136 -45
- package/dist/js/materialize.d.ts +227 -2
- package/dist/js/materialize.js +1136 -45
- package/dist/js/materialize.min.js +2 -2
- package/dist/js/materialize.mjs +1128 -46
- package/package.json +45 -1
- package/sass/_colors.scss +191 -5
- package/sass/_global.scss +240 -1
- package/sass/materialize.scss +14 -1
- package/sass/mixins.module.scss +6 -6
package/dist/js/materialize.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Materialize v2.3.3-1.0.
|
|
2
|
+
* Materialize v2.3.3-1.0.21 (https://materializeweb.com)
|
|
3
3
|
* Copyright 2014-2026 Materialize
|
|
4
4
|
* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE)
|
|
5
5
|
*/
|
|
@@ -400,7 +400,7 @@ var M = (function (exports) {
|
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
const _defaults$
|
|
403
|
+
const _defaults$x = {
|
|
404
404
|
alignment: 'left',
|
|
405
405
|
autoFocus: true,
|
|
406
406
|
constrainWidth: true,
|
|
@@ -453,7 +453,7 @@ var M = (function (exports) {
|
|
|
453
453
|
this._setupEventHandlers();
|
|
454
454
|
}
|
|
455
455
|
static get defaults() {
|
|
456
|
-
return _defaults$
|
|
456
|
+
return _defaults$x;
|
|
457
457
|
}
|
|
458
458
|
/**
|
|
459
459
|
* Initializes instances of Dropdown.
|
|
@@ -545,7 +545,7 @@ var M = (function (exports) {
|
|
|
545
545
|
// isTouchMoving to check if scrolling on mobile.
|
|
546
546
|
this.close();
|
|
547
547
|
}
|
|
548
|
-
else if (!target.closest('.dropdown-content')) {
|
|
548
|
+
else if (!target.closest('.dropdown-content') && !target.closest('.dropdown-trigger')) {
|
|
549
549
|
// Do this one frame later so that if the element clicked also triggers _handleClick
|
|
550
550
|
// For example, if a label for a select was clicked, that we don't close/open the dropdown
|
|
551
551
|
setTimeout(() => {
|
|
@@ -904,7 +904,7 @@ var M = (function (exports) {
|
|
|
904
904
|
};
|
|
905
905
|
}
|
|
906
906
|
|
|
907
|
-
const _defaults$
|
|
907
|
+
const _defaults$w = {
|
|
908
908
|
data: [], // Autocomplete data set
|
|
909
909
|
onAutocomplete: null, // Callback for when autocompleted
|
|
910
910
|
dropdownOptions: {
|
|
@@ -964,7 +964,7 @@ var M = (function (exports) {
|
|
|
964
964
|
this._setupEventHandlers();
|
|
965
965
|
}
|
|
966
966
|
static get defaults() {
|
|
967
|
-
return _defaults$
|
|
967
|
+
return _defaults$w;
|
|
968
968
|
}
|
|
969
969
|
/**
|
|
970
970
|
* Initializes instances of Autocomplete.
|
|
@@ -1372,7 +1372,177 @@ var M = (function (exports) {
|
|
|
1372
1372
|
}
|
|
1373
1373
|
}
|
|
1374
1374
|
|
|
1375
|
-
const _defaults$
|
|
1375
|
+
const _defaults$v = {
|
|
1376
|
+
dismissible: true
|
|
1377
|
+
};
|
|
1378
|
+
/** A persistent, contextual feedback banner. */
|
|
1379
|
+
class Alert extends Component {
|
|
1380
|
+
_closeButton = null;
|
|
1381
|
+
_onClose = () => this.dismiss();
|
|
1382
|
+
constructor(el, options) {
|
|
1383
|
+
super(el, options, Alert);
|
|
1384
|
+
this.options = { ...Alert.defaults, ...options };
|
|
1385
|
+
this.el['M_Alert'] = this;
|
|
1386
|
+
this._bindCloseButton();
|
|
1387
|
+
}
|
|
1388
|
+
static get defaults() {
|
|
1389
|
+
return _defaults$v;
|
|
1390
|
+
}
|
|
1391
|
+
static init(els, options = {}) {
|
|
1392
|
+
return super.init(els, options, Alert);
|
|
1393
|
+
}
|
|
1394
|
+
static getInstance(el) {
|
|
1395
|
+
return el['M_Alert'];
|
|
1396
|
+
}
|
|
1397
|
+
_bindCloseButton() {
|
|
1398
|
+
this._closeButton = this.el.querySelector('.alert-close');
|
|
1399
|
+
if (this.options.dismissible && this._closeButton) {
|
|
1400
|
+
this._closeButton.addEventListener('click', this._onClose);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
/** Hide and remove the alert from the document. */
|
|
1404
|
+
dismiss() {
|
|
1405
|
+
if (!this.el.isConnected)
|
|
1406
|
+
return;
|
|
1407
|
+
this.el.classList.add('alert-dismissing');
|
|
1408
|
+
const remove = () => {
|
|
1409
|
+
this.el.removeEventListener('transitionend', remove);
|
|
1410
|
+
this.el.hidden = true;
|
|
1411
|
+
this.options.onDismiss?.(this);
|
|
1412
|
+
};
|
|
1413
|
+
if (getComputedStyle(this.el).transitionDuration === '0s')
|
|
1414
|
+
remove();
|
|
1415
|
+
else
|
|
1416
|
+
this.el.addEventListener('transitionend', remove, { once: true });
|
|
1417
|
+
}
|
|
1418
|
+
/** Show an alert that was previously dismissed. */
|
|
1419
|
+
open() {
|
|
1420
|
+
this.el.hidden = false;
|
|
1421
|
+
this.el.classList.remove('alert-dismissing');
|
|
1422
|
+
}
|
|
1423
|
+
destroy() {
|
|
1424
|
+
this._closeButton?.removeEventListener('click', this._onClose);
|
|
1425
|
+
delete this.el['M_Alert'];
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
const _defaults$u = {
|
|
1430
|
+
draggable: true
|
|
1431
|
+
};
|
|
1432
|
+
/** A lightweight, dependency-free board for columns of draggable cards. */
|
|
1433
|
+
class Kanban extends Component {
|
|
1434
|
+
_draggedCard = null;
|
|
1435
|
+
_dragSourceColumn = null;
|
|
1436
|
+
_onDragStart = (event) => {
|
|
1437
|
+
const card = event.target?.closest('.kanban-card');
|
|
1438
|
+
if (!card || !this.options.draggable)
|
|
1439
|
+
return;
|
|
1440
|
+
this._draggedCard = card;
|
|
1441
|
+
this._dragSourceColumn = card.closest('.kanban-column');
|
|
1442
|
+
card.classList.add('is-dragging');
|
|
1443
|
+
event.dataTransfer?.setData('text/plain', card.dataset.kanbanCard || '');
|
|
1444
|
+
if (event.dataTransfer)
|
|
1445
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
1446
|
+
};
|
|
1447
|
+
_onDragOver = (event) => {
|
|
1448
|
+
if (!this._draggedCard)
|
|
1449
|
+
return;
|
|
1450
|
+
const column = event.target?.closest('.kanban-column');
|
|
1451
|
+
if (!column || !this.el.contains(column))
|
|
1452
|
+
return;
|
|
1453
|
+
event.preventDefault();
|
|
1454
|
+
if (event.dataTransfer)
|
|
1455
|
+
event.dataTransfer.dropEffect = 'move';
|
|
1456
|
+
this.el.querySelectorAll('.kanban-column.is-drag-over').forEach((item) => item.classList.remove('is-drag-over'));
|
|
1457
|
+
column.classList.add('is-drag-over');
|
|
1458
|
+
};
|
|
1459
|
+
_onDrop = (event) => {
|
|
1460
|
+
if (!this._draggedCard)
|
|
1461
|
+
return;
|
|
1462
|
+
const column = event.target?.closest('.kanban-column');
|
|
1463
|
+
if (!column || !this.el.contains(column))
|
|
1464
|
+
return;
|
|
1465
|
+
event.preventDefault();
|
|
1466
|
+
const body = column.querySelector('.kanban-column-body') || column;
|
|
1467
|
+
const targetCard = event.target?.closest('.kanban-card');
|
|
1468
|
+
const source = this._dragSourceColumn;
|
|
1469
|
+
if (targetCard && targetCard !== this._draggedCard && targetCard.parentElement === body) {
|
|
1470
|
+
const box = targetCard.getBoundingClientRect();
|
|
1471
|
+
body.insertBefore(this._draggedCard, event.clientY < box.top + box.height / 2 ? targetCard : targetCard.nextSibling);
|
|
1472
|
+
}
|
|
1473
|
+
else {
|
|
1474
|
+
body.appendChild(this._draggedCard);
|
|
1475
|
+
}
|
|
1476
|
+
this._clearDragState();
|
|
1477
|
+
this._updateCounts();
|
|
1478
|
+
if (source && source !== column)
|
|
1479
|
+
this.options.onMove?.({ card: this._draggedCard, from: source, to: column });
|
|
1480
|
+
};
|
|
1481
|
+
_onDragEnd = () => this._clearDragState();
|
|
1482
|
+
constructor(el, options) {
|
|
1483
|
+
super(el, options, Kanban);
|
|
1484
|
+
this.options = { ...Kanban.defaults, ...options };
|
|
1485
|
+
this.el['M_Kanban'] = this;
|
|
1486
|
+
this._prepareMarkup();
|
|
1487
|
+
if (this.options.draggable)
|
|
1488
|
+
this._bindEvents();
|
|
1489
|
+
}
|
|
1490
|
+
static get defaults() {
|
|
1491
|
+
return _defaults$u;
|
|
1492
|
+
}
|
|
1493
|
+
static init(els, options = {}) {
|
|
1494
|
+
return super.init(els, options, Kanban);
|
|
1495
|
+
}
|
|
1496
|
+
static getInstance(el) {
|
|
1497
|
+
return el['M_Kanban'];
|
|
1498
|
+
}
|
|
1499
|
+
_prepareMarkup() {
|
|
1500
|
+
this.el.setAttribute('role', 'region');
|
|
1501
|
+
this.el.querySelectorAll('.kanban-column').forEach((column) => {
|
|
1502
|
+
column.setAttribute('role', 'group');
|
|
1503
|
+
const body = column.querySelector('.kanban-column-body');
|
|
1504
|
+
if (body)
|
|
1505
|
+
body.setAttribute('role', 'list');
|
|
1506
|
+
column.querySelectorAll('.kanban-card').forEach((card) => {
|
|
1507
|
+
card.setAttribute('role', 'listitem');
|
|
1508
|
+
card.setAttribute('tabindex', '0');
|
|
1509
|
+
if (this.options.draggable)
|
|
1510
|
+
card.draggable = true;
|
|
1511
|
+
});
|
|
1512
|
+
});
|
|
1513
|
+
this._updateCounts();
|
|
1514
|
+
}
|
|
1515
|
+
_bindEvents() {
|
|
1516
|
+
this.el.addEventListener('dragstart', this._onDragStart);
|
|
1517
|
+
this.el.addEventListener('dragover', this._onDragOver);
|
|
1518
|
+
this.el.addEventListener('drop', this._onDrop);
|
|
1519
|
+
this.el.addEventListener('dragend', this._onDragEnd);
|
|
1520
|
+
}
|
|
1521
|
+
_clearDragState() {
|
|
1522
|
+
this._draggedCard?.classList.remove('is-dragging');
|
|
1523
|
+
this.el.querySelectorAll('.kanban-column.is-drag-over').forEach((item) => item.classList.remove('is-drag-over'));
|
|
1524
|
+
this._draggedCard = null;
|
|
1525
|
+
this._dragSourceColumn = null;
|
|
1526
|
+
}
|
|
1527
|
+
_updateCounts() {
|
|
1528
|
+
this.el.querySelectorAll('.kanban-column').forEach((column) => {
|
|
1529
|
+
const count = column.querySelector('.kanban-column-count');
|
|
1530
|
+
const body = column.querySelector('.kanban-column-body');
|
|
1531
|
+
if (count && body)
|
|
1532
|
+
count.textContent = String(body.querySelectorAll(':scope > .kanban-card').length);
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
destroy() {
|
|
1536
|
+
this._clearDragState();
|
|
1537
|
+
this.el.removeEventListener('dragstart', this._onDragStart);
|
|
1538
|
+
this.el.removeEventListener('dragover', this._onDragOver);
|
|
1539
|
+
this.el.removeEventListener('drop', this._onDrop);
|
|
1540
|
+
this.el.removeEventListener('dragend', this._onDragEnd);
|
|
1541
|
+
delete this.el['M_Kanban'];
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
const _defaults$t = {
|
|
1376
1546
|
direction: 'top',
|
|
1377
1547
|
hoverEnabled: true,
|
|
1378
1548
|
toolbarEnabled: false
|
|
@@ -1419,7 +1589,7 @@ var M = (function (exports) {
|
|
|
1419
1589
|
this.#setupEventHandlers();
|
|
1420
1590
|
}
|
|
1421
1591
|
static get defaults() {
|
|
1422
|
-
return _defaults$
|
|
1592
|
+
return _defaults$t;
|
|
1423
1593
|
}
|
|
1424
1594
|
/**
|
|
1425
1595
|
* Initializes instances of FloatingActionButton.
|
|
@@ -1590,7 +1760,7 @@ var M = (function (exports) {
|
|
|
1590
1760
|
}
|
|
1591
1761
|
}
|
|
1592
1762
|
|
|
1593
|
-
const _defaults$
|
|
1763
|
+
const _defaults$s = {
|
|
1594
1764
|
onOpen: null,
|
|
1595
1765
|
onClose: null,
|
|
1596
1766
|
inDuration: 225,
|
|
@@ -1626,7 +1796,7 @@ var M = (function (exports) {
|
|
|
1626
1796
|
}
|
|
1627
1797
|
}
|
|
1628
1798
|
static get defaults() {
|
|
1629
|
-
return _defaults$
|
|
1799
|
+
return _defaults$s;
|
|
1630
1800
|
}
|
|
1631
1801
|
/**
|
|
1632
1802
|
* Initializes instances of Cards.
|
|
@@ -1737,7 +1907,7 @@ var M = (function (exports) {
|
|
|
1737
1907
|
}
|
|
1738
1908
|
}
|
|
1739
1909
|
|
|
1740
|
-
const _defaults$
|
|
1910
|
+
const _defaults$r = {
|
|
1741
1911
|
duration: 200, // ms
|
|
1742
1912
|
dist: -100, // zoom scale TODO: make this more intuitive as an option
|
|
1743
1913
|
shift: 0, // spacing for center image
|
|
@@ -1839,7 +2009,7 @@ var M = (function (exports) {
|
|
|
1839
2009
|
this._scroll(this.offset);
|
|
1840
2010
|
}
|
|
1841
2011
|
static get defaults() {
|
|
1842
|
-
return _defaults$
|
|
2012
|
+
return _defaults$r;
|
|
1843
2013
|
}
|
|
1844
2014
|
/**
|
|
1845
2015
|
* Initializes instances of Carousel.
|
|
@@ -2311,7 +2481,7 @@ var M = (function (exports) {
|
|
|
2311
2481
|
}
|
|
2312
2482
|
|
|
2313
2483
|
var _a;
|
|
2314
|
-
const _defaults$
|
|
2484
|
+
const _defaults$q = {
|
|
2315
2485
|
data: [],
|
|
2316
2486
|
placeholder: '',
|
|
2317
2487
|
secondaryPlaceholder: '',
|
|
@@ -2365,7 +2535,7 @@ var M = (function (exports) {
|
|
|
2365
2535
|
}
|
|
2366
2536
|
}
|
|
2367
2537
|
static get defaults() {
|
|
2368
|
-
return _defaults$
|
|
2538
|
+
return _defaults$q;
|
|
2369
2539
|
}
|
|
2370
2540
|
/**
|
|
2371
2541
|
* Initializes instances of Chips.
|
|
@@ -2648,7 +2818,7 @@ var M = (function (exports) {
|
|
|
2648
2818
|
}
|
|
2649
2819
|
_a = Chips;
|
|
2650
2820
|
|
|
2651
|
-
const _defaults$
|
|
2821
|
+
const _defaults$p = {
|
|
2652
2822
|
accordion: true,
|
|
2653
2823
|
onOpenStart: null,
|
|
2654
2824
|
onOpenEnd: null,
|
|
@@ -2684,7 +2854,7 @@ var M = (function (exports) {
|
|
|
2684
2854
|
}
|
|
2685
2855
|
}
|
|
2686
2856
|
static get defaults() {
|
|
2687
|
-
return _defaults$
|
|
2857
|
+
return _defaults$p;
|
|
2688
2858
|
}
|
|
2689
2859
|
/**
|
|
2690
2860
|
* Initializes instances of Collapsible.
|
|
@@ -2803,7 +2973,7 @@ var M = (function (exports) {
|
|
|
2803
2973
|
};
|
|
2804
2974
|
}
|
|
2805
2975
|
|
|
2806
|
-
const _defaults$
|
|
2976
|
+
const _defaults$o = {
|
|
2807
2977
|
classes: '',
|
|
2808
2978
|
dropdownOptions: {}
|
|
2809
2979
|
};
|
|
@@ -2843,7 +3013,7 @@ var M = (function (exports) {
|
|
|
2843
3013
|
this._setupEventHandlers();
|
|
2844
3014
|
}
|
|
2845
3015
|
static get defaults() {
|
|
2846
|
-
return _defaults$
|
|
3016
|
+
return _defaults$o;
|
|
2847
3017
|
}
|
|
2848
3018
|
/**
|
|
2849
3019
|
* Initializes instances of FormSelect.
|
|
@@ -3186,7 +3356,7 @@ var M = (function (exports) {
|
|
|
3186
3356
|
}
|
|
3187
3357
|
}
|
|
3188
3358
|
|
|
3189
|
-
const _defaults$
|
|
3359
|
+
const _defaults$n = {
|
|
3190
3360
|
margin: 5,
|
|
3191
3361
|
transition: 10,
|
|
3192
3362
|
duration: 250,
|
|
@@ -3203,7 +3373,7 @@ var M = (function (exports) {
|
|
|
3203
3373
|
constructor(el, container, options) {
|
|
3204
3374
|
this.el = el;
|
|
3205
3375
|
this.options = {
|
|
3206
|
-
..._defaults$
|
|
3376
|
+
..._defaults$n,
|
|
3207
3377
|
...options
|
|
3208
3378
|
};
|
|
3209
3379
|
this.container = document.createElement('div');
|
|
@@ -3265,7 +3435,7 @@ var M = (function (exports) {
|
|
|
3265
3435
|
};
|
|
3266
3436
|
}
|
|
3267
3437
|
|
|
3268
|
-
const _defaults$
|
|
3438
|
+
const _defaults$m = {
|
|
3269
3439
|
classList: ['modal'],
|
|
3270
3440
|
title: null,
|
|
3271
3441
|
onOpen: null,
|
|
@@ -3280,7 +3450,7 @@ var M = (function (exports) {
|
|
|
3280
3450
|
constructor(el, container, options) {
|
|
3281
3451
|
this.el = el;
|
|
3282
3452
|
this.options = {
|
|
3283
|
-
..._defaults$
|
|
3453
|
+
..._defaults$m,
|
|
3284
3454
|
...options,
|
|
3285
3455
|
};
|
|
3286
3456
|
this.container = document.createElement('dialog');
|
|
@@ -3338,7 +3508,7 @@ var M = (function (exports) {
|
|
|
3338
3508
|
};
|
|
3339
3509
|
}
|
|
3340
3510
|
|
|
3341
|
-
const _defaults$
|
|
3511
|
+
const _defaults$l = {
|
|
3342
3512
|
// the default output format for the input field value
|
|
3343
3513
|
format: 'mmm dd, yyyy',
|
|
3344
3514
|
// Used to create date object from current input string
|
|
@@ -3488,7 +3658,7 @@ var M = (function (exports) {
|
|
|
3488
3658
|
this._pickerSetup();
|
|
3489
3659
|
}
|
|
3490
3660
|
static get defaults() {
|
|
3491
|
-
return _defaults$
|
|
3661
|
+
return _defaults$l;
|
|
3492
3662
|
}
|
|
3493
3663
|
/**
|
|
3494
3664
|
* Initializes instances of Datepicker.
|
|
@@ -4541,7 +4711,7 @@ var M = (function (exports) {
|
|
|
4541
4711
|
}
|
|
4542
4712
|
}
|
|
4543
4713
|
|
|
4544
|
-
const _defaults$
|
|
4714
|
+
const _defaults$k = {
|
|
4545
4715
|
inDuration: 275,
|
|
4546
4716
|
outDuration: 200,
|
|
4547
4717
|
onOpenStart: null,
|
|
@@ -4593,7 +4763,7 @@ var M = (function (exports) {
|
|
|
4593
4763
|
this._setupEventHandlers();
|
|
4594
4764
|
}
|
|
4595
4765
|
static get defaults() {
|
|
4596
|
-
return _defaults$
|
|
4766
|
+
return _defaults$k;
|
|
4597
4767
|
}
|
|
4598
4768
|
/**
|
|
4599
4769
|
* Initializes instances of MaterialBox.
|
|
@@ -4917,7 +5087,7 @@ var M = (function (exports) {
|
|
|
4917
5087
|
};
|
|
4918
5088
|
}
|
|
4919
5089
|
|
|
4920
|
-
const _defaults$
|
|
5090
|
+
const _defaults$j = {
|
|
4921
5091
|
opacity: 0.5,
|
|
4922
5092
|
inDuration: 250,
|
|
4923
5093
|
outDuration: 250,
|
|
@@ -4942,7 +5112,7 @@ var M = (function (exports) {
|
|
|
4942
5112
|
this._setupEventHandlers();
|
|
4943
5113
|
}
|
|
4944
5114
|
static get defaults() {
|
|
4945
|
-
return _defaults$
|
|
5115
|
+
return _defaults$j;
|
|
4946
5116
|
}
|
|
4947
5117
|
static init(els, options = {}) {
|
|
4948
5118
|
return super.init(els, options, Modal);
|
|
@@ -4985,7 +5155,7 @@ var M = (function (exports) {
|
|
|
4985
5155
|
static { }
|
|
4986
5156
|
}
|
|
4987
5157
|
|
|
4988
|
-
const _defaults$
|
|
5158
|
+
const _defaults$i = {
|
|
4989
5159
|
edge: 'left',
|
|
4990
5160
|
draggable: true,
|
|
4991
5161
|
dragTargetWidth: '10px',
|
|
@@ -5041,7 +5211,7 @@ var M = (function (exports) {
|
|
|
5041
5211
|
Sidenav._sidenavs.push(this);
|
|
5042
5212
|
}
|
|
5043
5213
|
static get defaults() {
|
|
5044
|
-
return _defaults$
|
|
5214
|
+
return _defaults$i;
|
|
5045
5215
|
}
|
|
5046
5216
|
/**
|
|
5047
5217
|
* Initializes instances of Sidenav.
|
|
@@ -5438,7 +5608,7 @@ var M = (function (exports) {
|
|
|
5438
5608
|
}
|
|
5439
5609
|
}
|
|
5440
5610
|
|
|
5441
|
-
const _defaults$
|
|
5611
|
+
const _defaults$h = {
|
|
5442
5612
|
indicators: true,
|
|
5443
5613
|
height: 400,
|
|
5444
5614
|
duration: 500,
|
|
@@ -5530,7 +5700,7 @@ var M = (function (exports) {
|
|
|
5530
5700
|
this.start();
|
|
5531
5701
|
}
|
|
5532
5702
|
static get defaults() {
|
|
5533
|
-
return _defaults$
|
|
5703
|
+
return _defaults$h;
|
|
5534
5704
|
}
|
|
5535
5705
|
/**
|
|
5536
5706
|
* Initializes instances of Slider.
|
|
@@ -5777,7 +5947,7 @@ var M = (function (exports) {
|
|
|
5777
5947
|
};
|
|
5778
5948
|
}
|
|
5779
5949
|
|
|
5780
|
-
const _defaults$
|
|
5950
|
+
const _defaults$g = {
|
|
5781
5951
|
duration: 300,
|
|
5782
5952
|
onShow: null,
|
|
5783
5953
|
swipeable: false,
|
|
@@ -5814,7 +5984,7 @@ var M = (function (exports) {
|
|
|
5814
5984
|
this._setupEventHandlers();
|
|
5815
5985
|
}
|
|
5816
5986
|
static get defaults() {
|
|
5817
|
-
return _defaults$
|
|
5987
|
+
return _defaults$g;
|
|
5818
5988
|
}
|
|
5819
5989
|
/**
|
|
5820
5990
|
* Initializes instances of Tabs.
|
|
@@ -6065,7 +6235,7 @@ var M = (function (exports) {
|
|
|
6065
6235
|
}
|
|
6066
6236
|
}
|
|
6067
6237
|
|
|
6068
|
-
const _defaults$
|
|
6238
|
+
const _defaults$f = {
|
|
6069
6239
|
dialRadius: 135,
|
|
6070
6240
|
outerRadius: 105,
|
|
6071
6241
|
innerRadius: 70,
|
|
@@ -6152,7 +6322,7 @@ var M = (function (exports) {
|
|
|
6152
6322
|
this._pickerSetup();
|
|
6153
6323
|
}
|
|
6154
6324
|
static get defaults() {
|
|
6155
|
-
return _defaults$
|
|
6325
|
+
return _defaults$f;
|
|
6156
6326
|
}
|
|
6157
6327
|
/**
|
|
6158
6328
|
* Initializes instances of Timepicker.
|
|
@@ -6758,7 +6928,7 @@ var M = (function (exports) {
|
|
|
6758
6928
|
}
|
|
6759
6929
|
}
|
|
6760
6930
|
|
|
6761
|
-
const _defaults$
|
|
6931
|
+
const _defaults$e = {
|
|
6762
6932
|
text: '',
|
|
6763
6933
|
displayLength: 4000,
|
|
6764
6934
|
inDuration: 300,
|
|
@@ -6811,7 +6981,7 @@ var M = (function (exports) {
|
|
|
6811
6981
|
this._setTimer();
|
|
6812
6982
|
}
|
|
6813
6983
|
static get defaults() {
|
|
6814
|
-
return _defaults$
|
|
6984
|
+
return _defaults$e;
|
|
6815
6985
|
}
|
|
6816
6986
|
static getInstance(el) {
|
|
6817
6987
|
return el['M_Toast'];
|
|
@@ -7003,7 +7173,7 @@ var M = (function (exports) {
|
|
|
7003
7173
|
}
|
|
7004
7174
|
}
|
|
7005
7175
|
|
|
7006
|
-
const _defaults$
|
|
7176
|
+
const _defaults$d = {
|
|
7007
7177
|
exitDelay: 200,
|
|
7008
7178
|
enterDelay: 0,
|
|
7009
7179
|
text: '',
|
|
@@ -7047,7 +7217,7 @@ var M = (function (exports) {
|
|
|
7047
7217
|
this._setupEventHandlers();
|
|
7048
7218
|
}
|
|
7049
7219
|
static get defaults() {
|
|
7050
|
-
return _defaults$
|
|
7220
|
+
return _defaults$d;
|
|
7051
7221
|
}
|
|
7052
7222
|
/**
|
|
7053
7223
|
* Initializes instances of Tooltip.
|
|
@@ -7272,7 +7442,7 @@ var M = (function (exports) {
|
|
|
7272
7442
|
}
|
|
7273
7443
|
}
|
|
7274
7444
|
|
|
7275
|
-
const _defaults$
|
|
7445
|
+
const _defaults$c = {};
|
|
7276
7446
|
// TODO: !!!!!
|
|
7277
7447
|
class Range extends Component {
|
|
7278
7448
|
_mousedown;
|
|
@@ -7290,7 +7460,7 @@ var M = (function (exports) {
|
|
|
7290
7460
|
this._setupEventHandlers();
|
|
7291
7461
|
}
|
|
7292
7462
|
static get defaults() {
|
|
7293
|
-
return _defaults$
|
|
7463
|
+
return _defaults$c;
|
|
7294
7464
|
}
|
|
7295
7465
|
/**
|
|
7296
7466
|
* Initializes instances of Range.
|
|
@@ -7441,6 +7611,896 @@ var M = (function (exports) {
|
|
|
7441
7611
|
}
|
|
7442
7612
|
}
|
|
7443
7613
|
|
|
7614
|
+
const _defaults$b = {};
|
|
7615
|
+
// @implement /Users/kzarshenas/Sites/RodeoFx/rodeo_toolkit_2/app/Environment/Partials/PlanningToolbar.ts
|
|
7616
|
+
// Generic version of that file's track-indicator sliding and expandable
|
|
7617
|
+
// search behavior, decoupled from the page-specific filter/state-binding
|
|
7618
|
+
// system (UtilityFilter) the source used - here it's just plain DOM state.
|
|
7619
|
+
class Toolbar extends Component {
|
|
7620
|
+
_tracks;
|
|
7621
|
+
constructor(el, options) {
|
|
7622
|
+
super(el, options, Toolbar);
|
|
7623
|
+
this.el.M_Toolbar = this;
|
|
7624
|
+
this.options = {
|
|
7625
|
+
...Toolbar.defaults,
|
|
7626
|
+
...options
|
|
7627
|
+
};
|
|
7628
|
+
this._tracks = Array.from(this.el.querySelectorAll('.toolbar-track'));
|
|
7629
|
+
this._setupEventHandlers();
|
|
7630
|
+
this._tracks.forEach((track) => this._moveIndicator(track, false));
|
|
7631
|
+
// A custom/web font can still be loading at construction time; its
|
|
7632
|
+
// metrics landing after this first measurement would leave the
|
|
7633
|
+
// indicator very slightly offset from the (now differently-sized)
|
|
7634
|
+
// text it's supposed to sit behind. Re-measure once fonts are ready.
|
|
7635
|
+
if (typeof document !== 'undefined' && document.fonts) {
|
|
7636
|
+
document.fonts.ready.then(() => {
|
|
7637
|
+
this._tracks.forEach((track) => this._moveIndicator(track, false));
|
|
7638
|
+
});
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
static get defaults() {
|
|
7642
|
+
return _defaults$b;
|
|
7643
|
+
}
|
|
7644
|
+
static init(els, options = {}) {
|
|
7645
|
+
return super.init(els, options, Toolbar);
|
|
7646
|
+
}
|
|
7647
|
+
static getInstance(el) {
|
|
7648
|
+
return el.M_Toolbar;
|
|
7649
|
+
}
|
|
7650
|
+
destroy() {
|
|
7651
|
+
this._removeEventHandlers();
|
|
7652
|
+
this.el.M_Toolbar = undefined;
|
|
7653
|
+
}
|
|
7654
|
+
/**
|
|
7655
|
+
* Re-measure and reposition every track's sliding indicator - call this
|
|
7656
|
+
* after changing which .toolbar-track-item is active from your own code,
|
|
7657
|
+
* or after anything that could have changed the toolbar's layout/width.
|
|
7658
|
+
*/
|
|
7659
|
+
updateIndicators() {
|
|
7660
|
+
this._tracks.forEach((track) => this._moveIndicator(track, true));
|
|
7661
|
+
}
|
|
7662
|
+
_setupEventHandlers() {
|
|
7663
|
+
this.el.addEventListener('click', this._handleTrackClick);
|
|
7664
|
+
this.el.addEventListener('focusin', this._handleSearchFocusIn);
|
|
7665
|
+
this.el.addEventListener('focusout', this._handleSearchFocusOut);
|
|
7666
|
+
this.el.addEventListener('input', this._handleSearchInput);
|
|
7667
|
+
this.el.addEventListener('keydown', this._handleSearchKeydown);
|
|
7668
|
+
window.addEventListener('resize', this._handleWindowResize);
|
|
7669
|
+
}
|
|
7670
|
+
_removeEventHandlers() {
|
|
7671
|
+
this.el.removeEventListener('click', this._handleTrackClick);
|
|
7672
|
+
this.el.removeEventListener('focusin', this._handleSearchFocusIn);
|
|
7673
|
+
this.el.removeEventListener('focusout', this._handleSearchFocusOut);
|
|
7674
|
+
this.el.removeEventListener('input', this._handleSearchInput);
|
|
7675
|
+
this.el.removeEventListener('keydown', this._handleSearchKeydown);
|
|
7676
|
+
window.removeEventListener('resize', this._handleWindowResize);
|
|
7677
|
+
}
|
|
7678
|
+
_handleTrackClick = (e) => {
|
|
7679
|
+
const item = e.target.closest('.toolbar-track-item');
|
|
7680
|
+
if (!item)
|
|
7681
|
+
return;
|
|
7682
|
+
const track = item.closest('.toolbar-track');
|
|
7683
|
+
if (!track || !this._tracks.includes(track))
|
|
7684
|
+
return;
|
|
7685
|
+
track.querySelectorAll('.toolbar-track-item.is-active').forEach((el) => el.classList.remove('is-active'));
|
|
7686
|
+
item.classList.add('is-active');
|
|
7687
|
+
this._moveIndicator(track, true);
|
|
7688
|
+
};
|
|
7689
|
+
_handleSearchFocusIn = (e) => {
|
|
7690
|
+
const search = e.target.closest('.toolbar-search');
|
|
7691
|
+
if (search)
|
|
7692
|
+
search.classList.add('is-expanded');
|
|
7693
|
+
};
|
|
7694
|
+
_handleSearchFocusOut = (e) => {
|
|
7695
|
+
const search = e.target.closest('.toolbar-search');
|
|
7696
|
+
if (!search)
|
|
7697
|
+
return;
|
|
7698
|
+
const input = search.querySelector('.toolbar-search-input');
|
|
7699
|
+
if (input && input.value === '')
|
|
7700
|
+
search.classList.remove('is-expanded');
|
|
7701
|
+
};
|
|
7702
|
+
_handleSearchInput = (e) => {
|
|
7703
|
+
const input = e.target;
|
|
7704
|
+
if (!input.classList.contains('toolbar-search-input'))
|
|
7705
|
+
return;
|
|
7706
|
+
const search = input.closest('.toolbar-search');
|
|
7707
|
+
if (search)
|
|
7708
|
+
search.classList.toggle('is-expanded', input.value !== '' || document.activeElement === input);
|
|
7709
|
+
};
|
|
7710
|
+
_handleSearchKeydown = (e) => {
|
|
7711
|
+
if (e.key !== 'Escape')
|
|
7712
|
+
return;
|
|
7713
|
+
const input = e.target.closest('.toolbar-search')?.querySelector('.toolbar-search-input');
|
|
7714
|
+
if (!input)
|
|
7715
|
+
return;
|
|
7716
|
+
input.value = '';
|
|
7717
|
+
input.blur();
|
|
7718
|
+
};
|
|
7719
|
+
_handleWindowResize = () => {
|
|
7720
|
+
this._tracks.forEach((track) => this._moveIndicator(track, false));
|
|
7721
|
+
};
|
|
7722
|
+
_moveIndicator(track, animate) {
|
|
7723
|
+
const indicator = track.querySelector('.toolbar-track-indicator');
|
|
7724
|
+
const active = track.querySelector('.toolbar-track-item.is-active');
|
|
7725
|
+
if (!indicator || !active)
|
|
7726
|
+
return;
|
|
7727
|
+
if (!animate)
|
|
7728
|
+
indicator.style.transition = 'none';
|
|
7729
|
+
// No "- track.clientLeft" here: offsetLeft is already relative to the
|
|
7730
|
+
// offsetParent's padding edge, same origin as the indicator's own
|
|
7731
|
+
// `left: 0` (an absolutely positioned element's containing block is
|
|
7732
|
+
// its ancestor's padding box) - subtracting the border width again
|
|
7733
|
+
// was double-counting it, nudging the indicator a px too far left.
|
|
7734
|
+
indicator.style.transform = `translateX(${active.offsetLeft}px)`;
|
|
7735
|
+
indicator.style.width = `${active.offsetWidth}px`;
|
|
7736
|
+
track.classList.add('is-armed');
|
|
7737
|
+
if (!animate) {
|
|
7738
|
+
// Force layout so the transition-less move above actually applies
|
|
7739
|
+
// before re-enabling transitions on the next frame.
|
|
7740
|
+
void indicator.offsetWidth;
|
|
7741
|
+
requestAnimationFrame(() => {
|
|
7742
|
+
indicator.style.transition = '';
|
|
7743
|
+
});
|
|
7744
|
+
}
|
|
7745
|
+
}
|
|
7746
|
+
}
|
|
7747
|
+
|
|
7748
|
+
const _defaults$a = {};
|
|
7749
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Password.ts
|
|
7750
|
+
// Show/hide toggle for a password input - no third-party dependency, just
|
|
7751
|
+
// Materialize's own .prefix/.suffix icon-slot convention (see
|
|
7752
|
+
// components/textfield/_input-fields.scss), so unlike the other new form
|
|
7753
|
+
// enhancements in this batch this one needs no peer-loader/dynamic import.
|
|
7754
|
+
class PasswordInput extends Component {
|
|
7755
|
+
_suffixEl;
|
|
7756
|
+
constructor(el, options) {
|
|
7757
|
+
super(el, options, PasswordInput);
|
|
7758
|
+
this.el.M_PasswordInput = this;
|
|
7759
|
+
this.options = {
|
|
7760
|
+
...PasswordInput.defaults,
|
|
7761
|
+
...options
|
|
7762
|
+
};
|
|
7763
|
+
this._suffixEl = this.el.parentElement?.querySelector('[data-password-toggle-icon]') ?? null;
|
|
7764
|
+
if (!this.el.dataset.passwordVisible)
|
|
7765
|
+
this.el.dataset.passwordVisible = '0';
|
|
7766
|
+
this._setupEventHandlers();
|
|
7767
|
+
}
|
|
7768
|
+
static get defaults() {
|
|
7769
|
+
return _defaults$a;
|
|
7770
|
+
}
|
|
7771
|
+
static init(els, options = {}) {
|
|
7772
|
+
return super.init(els, options, PasswordInput);
|
|
7773
|
+
}
|
|
7774
|
+
static getInstance(el) {
|
|
7775
|
+
return el.M_PasswordInput;
|
|
7776
|
+
}
|
|
7777
|
+
destroy() {
|
|
7778
|
+
this._removeEventHandlers();
|
|
7779
|
+
this.el.M_PasswordInput = undefined;
|
|
7780
|
+
}
|
|
7781
|
+
_setupEventHandlers() {
|
|
7782
|
+
this._suffixEl?.addEventListener('click', this._handleToggleClick);
|
|
7783
|
+
}
|
|
7784
|
+
_removeEventHandlers() {
|
|
7785
|
+
this._suffixEl?.removeEventListener('click', this._handleToggleClick);
|
|
7786
|
+
}
|
|
7787
|
+
_handleToggleClick = () => {
|
|
7788
|
+
const visible = this.el.dataset.passwordVisible === '1';
|
|
7789
|
+
this.el.type = visible ? 'password' : 'text';
|
|
7790
|
+
this.el.dataset.passwordVisible = visible ? '0' : '1';
|
|
7791
|
+
const iconEl = this._suffixEl?.querySelector('i');
|
|
7792
|
+
if (iconEl)
|
|
7793
|
+
iconEl.textContent = visible ? 'visibility' : 'visibility_off';
|
|
7794
|
+
};
|
|
7795
|
+
}
|
|
7796
|
+
|
|
7797
|
+
const _cache = new Map();
|
|
7798
|
+
async function loadPeer(spec, importer) {
|
|
7799
|
+
if (_cache.has(spec.specifier))
|
|
7800
|
+
return _cache.get(spec.specifier);
|
|
7801
|
+
try {
|
|
7802
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7803
|
+
const mod = await importer();
|
|
7804
|
+
const resolved = mod?.default ?? mod;
|
|
7805
|
+
_cache.set(spec.specifier, resolved);
|
|
7806
|
+
return resolved;
|
|
7807
|
+
}
|
|
7808
|
+
catch {
|
|
7809
|
+
// fall through to the global-scope lookup below
|
|
7810
|
+
}
|
|
7811
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7812
|
+
const globalScope = typeof window !== 'undefined' ? window : undefined;
|
|
7813
|
+
if (globalScope && globalScope[spec.globalName]) {
|
|
7814
|
+
const resolved = globalScope[spec.globalName];
|
|
7815
|
+
_cache.set(spec.specifier, resolved);
|
|
7816
|
+
return resolved;
|
|
7817
|
+
}
|
|
7818
|
+
throw new Error(`kmaterialize's ${spec.feature} requires "${spec.specifier}", which isn't installed/loaded.\n` +
|
|
7819
|
+
`- If you're using a bundler: npm/pnpm/yarn install "${spec.specifier}".\n` +
|
|
7820
|
+
`- If you're using the plain <script> (no-bundler) build: add\n` +
|
|
7821
|
+
` ${spec.cdnHint}\n` +
|
|
7822
|
+
` before initializing this component, so window.${spec.globalName} is defined.`);
|
|
7823
|
+
}
|
|
7824
|
+
|
|
7825
|
+
const _defaults$9 = {
|
|
7826
|
+
thousandsSeparator: ' ',
|
|
7827
|
+
radix: '.',
|
|
7828
|
+
mapToRadix: [',']
|
|
7829
|
+
};
|
|
7830
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Number.ts
|
|
7831
|
+
// Masked/formatted numeric input via IMask (thousands separator, decimal
|
|
7832
|
+
// scale, min/max) - deliberately opts in on `type="text" data-type="number"`
|
|
7833
|
+
// rather than `type="number"`, so IMask can format the display value
|
|
7834
|
+
// (thousands separators etc.) that a native number input wouldn't allow.
|
|
7835
|
+
//
|
|
7836
|
+
// IMask is an optional peerDependency, loaded on demand via peer-loader -
|
|
7837
|
+
// see that file for the bundler/no-bundler resolution strategy.
|
|
7838
|
+
class NumberInput extends Component {
|
|
7839
|
+
mask;
|
|
7840
|
+
ready;
|
|
7841
|
+
constructor(el, options) {
|
|
7842
|
+
super(el, options, NumberInput);
|
|
7843
|
+
this.el.M_NumberInput = this;
|
|
7844
|
+
this.options = {
|
|
7845
|
+
...NumberInput.defaults,
|
|
7846
|
+
...options
|
|
7847
|
+
};
|
|
7848
|
+
this.ready = this._setup();
|
|
7849
|
+
}
|
|
7850
|
+
static get defaults() {
|
|
7851
|
+
return _defaults$9;
|
|
7852
|
+
}
|
|
7853
|
+
static init(els, options = {}) {
|
|
7854
|
+
return super.init(els, options, NumberInput);
|
|
7855
|
+
}
|
|
7856
|
+
static getInstance(el) {
|
|
7857
|
+
return el.M_NumberInput;
|
|
7858
|
+
}
|
|
7859
|
+
destroy() {
|
|
7860
|
+
this.mask?.destroy();
|
|
7861
|
+
this.el.M_NumberInput = undefined;
|
|
7862
|
+
}
|
|
7863
|
+
async _setup() {
|
|
7864
|
+
const IMask = await loadPeer({
|
|
7865
|
+
specifier: 'imask',
|
|
7866
|
+
globalName: 'IMask',
|
|
7867
|
+
feature: 'Number input (IMask) enhancement',
|
|
7868
|
+
cdnHint: '<script src="path/to/imask.min.js"></script> (self-hosted - copy from node_modules/imask/dist/imask.min.js, or a CDN of your choice)'
|
|
7869
|
+
}, () => import('imask'));
|
|
7870
|
+
const maskOptions = {
|
|
7871
|
+
mask: Number,
|
|
7872
|
+
skipInvalid: true,
|
|
7873
|
+
thousandsSeparator: this.options.thousandsSeparator,
|
|
7874
|
+
radix: this.options.radix,
|
|
7875
|
+
mapToRadix: this.options.mapToRadix,
|
|
7876
|
+
autofix: true
|
|
7877
|
+
};
|
|
7878
|
+
const max = this.options.max ?? (this.el.hasAttribute('max') ? Number(this.el.getAttribute('max')) : undefined);
|
|
7879
|
+
if (max !== undefined && !Number.isNaN(max))
|
|
7880
|
+
maskOptions.max = max;
|
|
7881
|
+
const min = this.options.min ?? (this.el.hasAttribute('min') ? Number(this.el.getAttribute('min')) : undefined);
|
|
7882
|
+
if (min !== undefined && !Number.isNaN(min))
|
|
7883
|
+
maskOptions.min = min;
|
|
7884
|
+
const step = this.el.getAttribute('step');
|
|
7885
|
+
const scale = this.options.scale ?? (step?.includes('.') ? step.split('.').at(-1)?.length : undefined);
|
|
7886
|
+
if (scale !== undefined)
|
|
7887
|
+
maskOptions.scale = scale;
|
|
7888
|
+
this.mask = IMask(this.el, maskOptions);
|
|
7889
|
+
}
|
|
7890
|
+
}
|
|
7891
|
+
|
|
7892
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Color.ts
|
|
7893
|
+
// Built-in French translation for Pickr's UI strings, activated by
|
|
7894
|
+
// `data-color-locale="fr-fr"` alone - no separate options object required
|
|
7895
|
+
// from the consumer, unlike a fully custom `options.locale` override.
|
|
7896
|
+
const FR_FR = {
|
|
7897
|
+
'ui:dialog': 'boîte de dialogue du sélecteur de couleur',
|
|
7898
|
+
'btn:toggle': 'basculer la boîte de dialogue du sélecteur de couleur',
|
|
7899
|
+
'btn:swatch': 'échantillon de couleur',
|
|
7900
|
+
'btn:last-color': 'utiliser la couleur précédente',
|
|
7901
|
+
'btn:save': 'Enregistrer',
|
|
7902
|
+
'btn:cancel': 'Annuler',
|
|
7903
|
+
'btn:clear': 'Effacer',
|
|
7904
|
+
'aria:btn:save': 'enregistrer et fermer',
|
|
7905
|
+
'aria:btn:cancel': 'annuler et fermer',
|
|
7906
|
+
'aria:btn:clear': 'effacer et fermer',
|
|
7907
|
+
'aria:input': 'champ de saisie de couleur',
|
|
7908
|
+
'aria:palette': 'zone de sélection des couleurs',
|
|
7909
|
+
'aria:hue': 'curseur de sélection de teinte',
|
|
7910
|
+
'aria:opacity': "curseur de sélection d'opacité"
|
|
7911
|
+
};
|
|
7912
|
+
const _defaults$8 = {
|
|
7913
|
+
theme: 'classic',
|
|
7914
|
+
opacity: true,
|
|
7915
|
+
swatches: [
|
|
7916
|
+
'rgba(244, 67, 54, 1)',
|
|
7917
|
+
'rgba(233, 30, 99, 0.95)',
|
|
7918
|
+
'rgba(156, 39, 176, 0.9)',
|
|
7919
|
+
'rgba(103, 58, 183, 0.85)',
|
|
7920
|
+
'rgba(63, 81, 181, 0.8)',
|
|
7921
|
+
'rgba(33, 150, 243, 0.75)',
|
|
7922
|
+
'rgba(3, 169, 244, 0.7)',
|
|
7923
|
+
'rgba(0, 188, 212, 0.7)',
|
|
7924
|
+
'rgba(0, 150, 136, 0.75)',
|
|
7925
|
+
'rgba(76, 175, 80, 0.8)',
|
|
7926
|
+
'rgba(139, 195, 74, 0.85)',
|
|
7927
|
+
'rgba(205, 220, 57, 0.9)',
|
|
7928
|
+
'rgba(255, 235, 59, 0.95)',
|
|
7929
|
+
'rgba(255, 193, 7, 1)'
|
|
7930
|
+
]
|
|
7931
|
+
};
|
|
7932
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Color.ts
|
|
7933
|
+
// Enhances a native `<input type="color" data-color-picker="pickr">` with a
|
|
7934
|
+
// full Pickr popup (palette, hue/opacity sliders, swatches, hex/rgba/hsla).
|
|
7935
|
+
// If `data-color-picker` is absent the input is left completely untouched -
|
|
7936
|
+
// still a plain native color swatch, matching CrazyPHP's own fallback.
|
|
7937
|
+
//
|
|
7938
|
+
// Pickr remains an optional peerDependency and is loaded on demand via peer-loader.
|
|
7939
|
+
class ColorInput extends Component {
|
|
7940
|
+
pickr;
|
|
7941
|
+
ready;
|
|
7942
|
+
_swatchEl;
|
|
7943
|
+
_labels;
|
|
7944
|
+
constructor(el, options) {
|
|
7945
|
+
super(el, options, ColorInput);
|
|
7946
|
+
this.el.M_ColorInput = this;
|
|
7947
|
+
this.options = {
|
|
7948
|
+
...ColorInput.defaults,
|
|
7949
|
+
...options
|
|
7950
|
+
};
|
|
7951
|
+
this._swatchEl = document.createElement('div');
|
|
7952
|
+
this.el.after(this._swatchEl);
|
|
7953
|
+
this.el.classList.add('hide');
|
|
7954
|
+
this.el.addEventListener('change', this._handleInputChange);
|
|
7955
|
+
this._labels = Array.from(document.querySelectorAll('label')).filter(label => label.htmlFor === this.el.id);
|
|
7956
|
+
this._labels.forEach(label => label.addEventListener('click', this._handleLabelClick));
|
|
7957
|
+
this.ready = this._setup();
|
|
7958
|
+
}
|
|
7959
|
+
static get defaults() {
|
|
7960
|
+
return _defaults$8;
|
|
7961
|
+
}
|
|
7962
|
+
static init(els, options = {}) {
|
|
7963
|
+
return super.init(els, options, ColorInput);
|
|
7964
|
+
}
|
|
7965
|
+
static getInstance(el) {
|
|
7966
|
+
return el.M_ColorInput;
|
|
7967
|
+
}
|
|
7968
|
+
destroy() {
|
|
7969
|
+
this.el.removeEventListener('change', this._handleInputChange);
|
|
7970
|
+
this._labels.forEach(label => label.removeEventListener('click', this._handleLabelClick));
|
|
7971
|
+
this.pickr?.destroyAndRemove();
|
|
7972
|
+
this._swatchEl.remove();
|
|
7973
|
+
this.el.classList.remove('hide');
|
|
7974
|
+
this.el.M_ColorInput = undefined;
|
|
7975
|
+
}
|
|
7976
|
+
_handleInputChange = () => {
|
|
7977
|
+
this.pickr?.setColor(this.el.value);
|
|
7978
|
+
};
|
|
7979
|
+
_handleLabelClick = (event) => {
|
|
7980
|
+
// A label associated with a hidden input[type=color] otherwise opens
|
|
7981
|
+
// the browser's native picker (notably in Firefox). Route the same
|
|
7982
|
+
// accessible label activation to Pickr instead.
|
|
7983
|
+
event.preventDefault();
|
|
7984
|
+
void this.ready.then(() => this.pickr?.show());
|
|
7985
|
+
};
|
|
7986
|
+
async _setup() {
|
|
7987
|
+
const Pickr = await loadPeer({
|
|
7988
|
+
specifier: '@simonwep/pickr',
|
|
7989
|
+
globalName: 'Pickr',
|
|
7990
|
+
feature: 'Color input (Pickr) enhancement',
|
|
7991
|
+
cdnHint: '<link rel="stylesheet" href="path/to/pickr-classic.min.css">\n' +
|
|
7992
|
+
' <script src="path/to/pickr.min.js"></script>\n' +
|
|
7993
|
+
' (self-hosted - copy from node_modules/@simonwep/pickr/dist/, or a CDN of your choice)'
|
|
7994
|
+
}, () => import('@simonwep/pickr'));
|
|
7995
|
+
const dataset = this.el.dataset;
|
|
7996
|
+
const theme = (['classic', 'monolith', 'nano'].includes(dataset.colorTheme ?? '')
|
|
7997
|
+
? dataset.colorTheme
|
|
7998
|
+
: this.options.theme);
|
|
7999
|
+
const lockOpacity = dataset.colorOpacity !== undefined
|
|
8000
|
+
? ['false', '0', '', 'null'].includes(dataset.colorOpacity)
|
|
8001
|
+
: !this.options.opacity;
|
|
8002
|
+
const pickrOptions = {
|
|
8003
|
+
el: this._swatchEl,
|
|
8004
|
+
theme,
|
|
8005
|
+
lockOpacity,
|
|
8006
|
+
swatches: this.options.swatches,
|
|
8007
|
+
components: {
|
|
8008
|
+
preview: true,
|
|
8009
|
+
opacity: true,
|
|
8010
|
+
hue: true,
|
|
8011
|
+
interaction: {
|
|
8012
|
+
hex: true,
|
|
8013
|
+
rgba: true,
|
|
8014
|
+
hsla: true,
|
|
8015
|
+
hsva: true,
|
|
8016
|
+
cmyk: true,
|
|
8017
|
+
input: true,
|
|
8018
|
+
clear: true,
|
|
8019
|
+
save: true
|
|
8020
|
+
}
|
|
8021
|
+
}
|
|
8022
|
+
};
|
|
8023
|
+
if (this.options.locale) {
|
|
8024
|
+
pickrOptions.i18n = this.options.locale;
|
|
8025
|
+
}
|
|
8026
|
+
else if (dataset.colorLocale === 'fr-fr') {
|
|
8027
|
+
pickrOptions.i18n = FR_FR;
|
|
8028
|
+
}
|
|
8029
|
+
const currentValue = this.el.getAttribute('value');
|
|
8030
|
+
if (currentValue && currentValue !== 'randomHex()') {
|
|
8031
|
+
pickrOptions.default = currentValue;
|
|
8032
|
+
}
|
|
8033
|
+
else if (this.el.hasAttribute('default')) {
|
|
8034
|
+
const currentDefault = this.el.getAttribute('default');
|
|
8035
|
+
if (currentDefault === 'randomHex()') {
|
|
8036
|
+
const randomColor = Math.floor(Math.random() * 16777216);
|
|
8037
|
+
pickrOptions.default = `#${randomColor.toString(16).padStart(6, '0')}`;
|
|
8038
|
+
}
|
|
8039
|
+
else if (currentDefault) {
|
|
8040
|
+
pickrOptions.default = currentDefault;
|
|
8041
|
+
}
|
|
8042
|
+
}
|
|
8043
|
+
this.pickr = Pickr.create(pickrOptions);
|
|
8044
|
+
if (this.el.disabled)
|
|
8045
|
+
this.pickr.disable();
|
|
8046
|
+
this.pickr.on('save', (color, instance) => {
|
|
8047
|
+
const hexa = color?.toHEXA().toString();
|
|
8048
|
+
if (hexa) {
|
|
8049
|
+
this.el.value = hexa;
|
|
8050
|
+
this.el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
8051
|
+
}
|
|
8052
|
+
instance.hide();
|
|
8053
|
+
});
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
|
|
8057
|
+
const _defaults$7 = {};
|
|
8058
|
+
let activeAirDatepickerField;
|
|
8059
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Date.ts
|
|
8060
|
+
// Enhances `<input type="text" data-type="date" data-date-picker="air-datepicker">`
|
|
8061
|
+
// with the air-datepicker calendar/range picker - deliberately separate from
|
|
8062
|
+
// kmaterialize's own native `components/datepicker/` (a different, already
|
|
8063
|
+
// existing class-based component); this one is opted into per-input via the
|
|
8064
|
+
// `data-date-picker` attribute so it never collides with `.datepicker`
|
|
8065
|
+
// elements. The `multiple` attribute switches the picker into range mode,
|
|
8066
|
+
// `data-date-format`/`data-date-lang` (only "fr-FR" ported so far) mirror
|
|
8067
|
+
// CrazyPHP's own dataset convention.
|
|
8068
|
+
//
|
|
8069
|
+
// air-datepicker is an optional peerDependency, loaded on demand via
|
|
8070
|
+
// peer-loader. Its own base stylesheet (air-datepicker/air-datepicker.css)
|
|
8071
|
+
// must be imported separately by the consumer - see the docs page.
|
|
8072
|
+
class AirDatepickerField extends Component {
|
|
8073
|
+
picker;
|
|
8074
|
+
ready;
|
|
8075
|
+
_triggers;
|
|
8076
|
+
_handleOutsideClick = (e) => {
|
|
8077
|
+
const calendarEl = document.querySelector('.air-datepicker');
|
|
8078
|
+
const clickedTrigger = this._triggers.some(trigger => trigger.contains(e.target));
|
|
8079
|
+
if (calendarEl instanceof HTMLElement &&
|
|
8080
|
+
!calendarEl.contains(e.target) &&
|
|
8081
|
+
!this.el.contains(e.target) &&
|
|
8082
|
+
!clickedTrigger) {
|
|
8083
|
+
this.picker?.hide();
|
|
8084
|
+
}
|
|
8085
|
+
};
|
|
8086
|
+
constructor(el, options) {
|
|
8087
|
+
super(el, options, AirDatepickerField);
|
|
8088
|
+
this.el.M_AirDatepickerField = this;
|
|
8089
|
+
this.options = {
|
|
8090
|
+
...AirDatepickerField.defaults,
|
|
8091
|
+
...options
|
|
8092
|
+
};
|
|
8093
|
+
const labels = Array.from(document.querySelectorAll('label')).filter(label => label.htmlFor === this.el.id);
|
|
8094
|
+
const icons = Array.from(this.el.parentElement?.querySelectorAll('.prefix, .suffix') ?? []);
|
|
8095
|
+
this._triggers = [...labels, ...icons];
|
|
8096
|
+
this._triggers.forEach(trigger => trigger.addEventListener('click', this._handleTriggerClick));
|
|
8097
|
+
this.ready = this._setup();
|
|
8098
|
+
}
|
|
8099
|
+
static get defaults() {
|
|
8100
|
+
return _defaults$7;
|
|
8101
|
+
}
|
|
8102
|
+
static init(els, options = {}) {
|
|
8103
|
+
return super.init(els, options, AirDatepickerField);
|
|
8104
|
+
}
|
|
8105
|
+
static getInstance(el) {
|
|
8106
|
+
return el.M_AirDatepickerField;
|
|
8107
|
+
}
|
|
8108
|
+
destroy() {
|
|
8109
|
+
document.removeEventListener('click', this._handleOutsideClick);
|
|
8110
|
+
this._triggers.forEach(trigger => trigger.removeEventListener('click', this._handleTriggerClick));
|
|
8111
|
+
this.picker?.destroy();
|
|
8112
|
+
if (activeAirDatepickerField === this)
|
|
8113
|
+
activeAirDatepickerField = undefined;
|
|
8114
|
+
this.el.M_AirDatepickerField = undefined;
|
|
8115
|
+
}
|
|
8116
|
+
_handleTriggerClick = (event) => {
|
|
8117
|
+
event.preventDefault();
|
|
8118
|
+
event.stopPropagation();
|
|
8119
|
+
void this.ready.then(() => this.picker?.show());
|
|
8120
|
+
};
|
|
8121
|
+
async _setup() {
|
|
8122
|
+
const AirDatepicker = await loadPeer({
|
|
8123
|
+
specifier: 'air-datepicker',
|
|
8124
|
+
globalName: 'AirDatepicker',
|
|
8125
|
+
feature: 'Date input (air-datepicker) enhancement',
|
|
8126
|
+
cdnHint: '<link rel="stylesheet" href="path/to/air-datepicker.css">\n' +
|
|
8127
|
+
' <script src="path/to/air-datepicker.js"></script>\n' +
|
|
8128
|
+
' (self-hosted - copy from node_modules/air-datepicker/, or a CDN of your choice)'
|
|
8129
|
+
}, () => import('air-datepicker'));
|
|
8130
|
+
const dataset = this.el.dataset;
|
|
8131
|
+
const builtInLocale = dataset.dateLang === 'fr-FR'
|
|
8132
|
+
? (await import('air-datepicker/locale/fr')).default
|
|
8133
|
+
: (await import('air-datepicker/locale/en')).default;
|
|
8134
|
+
const pickerOptions = {
|
|
8135
|
+
dateFormat: dataset.dateFormat || 'yyyy-MM-dd',
|
|
8136
|
+
autoClose: dataset.dateAutoClose !== 'false',
|
|
8137
|
+
locale: (this.options.locale ?? builtInLocale),
|
|
8138
|
+
onShow: isAnimationComplete => {
|
|
8139
|
+
if (isAnimationComplete)
|
|
8140
|
+
return;
|
|
8141
|
+
if (activeAirDatepickerField && activeAirDatepickerField !== this) {
|
|
8142
|
+
activeAirDatepickerField.picker?.hide();
|
|
8143
|
+
}
|
|
8144
|
+
activeAirDatepickerField = this;
|
|
8145
|
+
},
|
|
8146
|
+
onHide: isAnimationComplete => {
|
|
8147
|
+
if (isAnimationComplete && activeAirDatepickerField === this) {
|
|
8148
|
+
activeAirDatepickerField = undefined;
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8151
|
+
};
|
|
8152
|
+
let multiple = false;
|
|
8153
|
+
if (this.el.multiple || dataset.dateRange === 'true') {
|
|
8154
|
+
pickerOptions.range = true;
|
|
8155
|
+
pickerOptions.multipleDatesSeparator = ' - ';
|
|
8156
|
+
multiple = true;
|
|
8157
|
+
}
|
|
8158
|
+
const initialValue = this.el.getAttribute('value')?.trim();
|
|
8159
|
+
if (initialValue) {
|
|
8160
|
+
pickerOptions.selectedDates = multiple
|
|
8161
|
+
? initialValue.split(' - ').map(value => value.trim())
|
|
8162
|
+
: [initialValue];
|
|
8163
|
+
}
|
|
8164
|
+
if (dataset.dateTimepicker === 'true') {
|
|
8165
|
+
pickerOptions.timepicker = true;
|
|
8166
|
+
if (dataset.dateTimeFormat)
|
|
8167
|
+
pickerOptions.timeFormat = dataset.dateTimeFormat;
|
|
8168
|
+
}
|
|
8169
|
+
const supportedViews = ['days', 'months', 'years'];
|
|
8170
|
+
if (supportedViews.includes(dataset.dateView ?? '')) {
|
|
8171
|
+
pickerOptions.view = dataset.dateView;
|
|
8172
|
+
}
|
|
8173
|
+
if (supportedViews.includes(dataset.dateMinView ?? '')) {
|
|
8174
|
+
pickerOptions.minView = dataset.dateMinView;
|
|
8175
|
+
}
|
|
8176
|
+
if (dataset.dateMobile === 'true')
|
|
8177
|
+
pickerOptions.isMobile = true;
|
|
8178
|
+
if (dataset.datePosition) {
|
|
8179
|
+
pickerOptions.position = dataset.datePosition;
|
|
8180
|
+
}
|
|
8181
|
+
if (dataset.dateButtons) {
|
|
8182
|
+
const supportedButtons = ['today', 'clear'];
|
|
8183
|
+
pickerOptions.buttons = dataset.dateButtons
|
|
8184
|
+
.split(',')
|
|
8185
|
+
.map(button => button.trim())
|
|
8186
|
+
.filter(button => supportedButtons.includes(button));
|
|
8187
|
+
}
|
|
8188
|
+
if (this.el.hasAttribute('min') && this.el.getAttribute('min')) {
|
|
8189
|
+
pickerOptions.minDate = new Date(this.el.getAttribute('min'));
|
|
8190
|
+
}
|
|
8191
|
+
if (this.el.hasAttribute('max') && this.el.getAttribute('max')) {
|
|
8192
|
+
pickerOptions.maxDate = new Date(this.el.getAttribute('max'));
|
|
8193
|
+
}
|
|
8194
|
+
if (!this.el.required && !pickerOptions.buttons) {
|
|
8195
|
+
pickerOptions.buttons = ['clear'];
|
|
8196
|
+
}
|
|
8197
|
+
pickerOptions.onSelect = ({ date }) => {
|
|
8198
|
+
if (multiple && Array.isArray(date) && date.length === 1)
|
|
8199
|
+
return;
|
|
8200
|
+
this.el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
8201
|
+
this.el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
8202
|
+
};
|
|
8203
|
+
this.picker = new AirDatepicker(this.el, pickerOptions);
|
|
8204
|
+
document.addEventListener('click', this._handleOutsideClick);
|
|
8205
|
+
}
|
|
8206
|
+
}
|
|
8207
|
+
|
|
8208
|
+
const _defaults$6 = {
|
|
8209
|
+
plugins: []
|
|
8210
|
+
};
|
|
8211
|
+
// Each plugin needs its own literal `import('literal-string')` call (see
|
|
8212
|
+
// peer-loader.ts) so Vite/webpack/Rollup can statically discover it - a
|
|
8213
|
+
// generic specifier-driven loop can't produce that, hence one entry per
|
|
8214
|
+
// plugin instead of building the import call from PLUGIN_SPECS's string.
|
|
8215
|
+
const PLUGIN_LOADERS = {
|
|
8216
|
+
'image-preview': {
|
|
8217
|
+
specifier: 'filepond-plugin-image-preview',
|
|
8218
|
+
globalName: 'FilePondPluginImagePreview',
|
|
8219
|
+
importer: () => import('filepond-plugin-image-preview')
|
|
8220
|
+
},
|
|
8221
|
+
'file-validate-type': {
|
|
8222
|
+
specifier: 'filepond-plugin-file-validate-type',
|
|
8223
|
+
globalName: 'FilePondPluginFileValidateType',
|
|
8224
|
+
importer: () => import('filepond-plugin-file-validate-type')
|
|
8225
|
+
},
|
|
8226
|
+
'image-exif-orientation': {
|
|
8227
|
+
specifier: 'filepond-plugin-image-exif-orientation',
|
|
8228
|
+
globalName: 'FilePondPluginImageExifOrientation',
|
|
8229
|
+
importer: () => import('filepond-plugin-image-exif-orientation')
|
|
8230
|
+
}
|
|
8231
|
+
};
|
|
8232
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/File.ts
|
|
8233
|
+
// Enhances the EXISTING `.file-field` structure in place - add
|
|
8234
|
+
// `data-file-picker="filepond"` (+ optional `data-file-plugins="a,b,c"`) to
|
|
8235
|
+
// an otherwise completely stock `.file-field`, nothing else about the
|
|
8236
|
+
// markup changes. FilePond.create() hides the native `<input type=file>`
|
|
8237
|
+
// and injects its own root as a *sibling*, it never removes anything from
|
|
8238
|
+
// the DOM, so the surrounding button/label/file-path-wrapper stay intact
|
|
8239
|
+
// at rest - only the interactive drop area swaps in visually.
|
|
8240
|
+
//
|
|
8241
|
+
// FilePond and its plugins are optional peerDependencies, loaded on demand
|
|
8242
|
+
// via peer-loader.
|
|
8243
|
+
class FileInput extends Component {
|
|
8244
|
+
pond;
|
|
8245
|
+
ready;
|
|
8246
|
+
_fileEl;
|
|
8247
|
+
_pathEl;
|
|
8248
|
+
constructor(el, options) {
|
|
8249
|
+
super(el, options, FileInput);
|
|
8250
|
+
this.el.M_FileInput = this;
|
|
8251
|
+
const pluginsAttr = this.el.dataset.filePlugins;
|
|
8252
|
+
this.options = {
|
|
8253
|
+
...FileInput.defaults,
|
|
8254
|
+
plugins: pluginsAttr
|
|
8255
|
+
? pluginsAttr.split(',').map((p) => p.trim())
|
|
8256
|
+
: FileInput.defaults.plugins,
|
|
8257
|
+
...options
|
|
8258
|
+
};
|
|
8259
|
+
this._fileEl = this.el.querySelector('input[type="file"]');
|
|
8260
|
+
this._pathEl = this.el.querySelector('.file-path');
|
|
8261
|
+
this.ready = this._setup();
|
|
8262
|
+
}
|
|
8263
|
+
static get defaults() {
|
|
8264
|
+
return _defaults$6;
|
|
8265
|
+
}
|
|
8266
|
+
static init(els, options = {}) {
|
|
8267
|
+
return super.init(els, options, FileInput);
|
|
8268
|
+
}
|
|
8269
|
+
static getInstance(el) {
|
|
8270
|
+
return el.M_FileInput;
|
|
8271
|
+
}
|
|
8272
|
+
destroy() {
|
|
8273
|
+
this.el.classList.remove('file-field-enhanced');
|
|
8274
|
+
this.el.querySelector('.btn')?.classList.remove('hide');
|
|
8275
|
+
this.el.querySelector('.file-path-wrapper')?.classList.remove('hide');
|
|
8276
|
+
this.pond?.destroy();
|
|
8277
|
+
this.el.M_FileInput = undefined;
|
|
8278
|
+
}
|
|
8279
|
+
/** Convenience wrapper over the underlying FilePond instance's own getFiles(). */
|
|
8280
|
+
getFiles() {
|
|
8281
|
+
return this.pond?.getFiles() ?? [];
|
|
8282
|
+
}
|
|
8283
|
+
async _setup() {
|
|
8284
|
+
if (!this._fileEl) {
|
|
8285
|
+
console.error(Error('.file-field enhanced with data-file-picker="filepond" needs an input[type=file]'));
|
|
8286
|
+
return;
|
|
8287
|
+
}
|
|
8288
|
+
const FilePond = await loadPeer({
|
|
8289
|
+
specifier: 'filepond',
|
|
8290
|
+
globalName: 'FilePond',
|
|
8291
|
+
feature: 'File input (FilePond) enhancement',
|
|
8292
|
+
cdnHint: '<link rel="stylesheet" href="path/to/filepond.min.css">\n' +
|
|
8293
|
+
' <script src="path/to/filepond.min.js"></script>\n' +
|
|
8294
|
+
' (self-hosted - copy from node_modules/filepond/dist/, or a CDN of your choice)'
|
|
8295
|
+
}, () => import('filepond'));
|
|
8296
|
+
const pluginNames = new Set(this.options.plugins);
|
|
8297
|
+
// file-validate-type is auto-registered whenever the input restricts
|
|
8298
|
+
// `accept`, matching CrazyPHP's own convention, even if the consumer
|
|
8299
|
+
// didn't list it explicitly in data-file-plugins.
|
|
8300
|
+
if (this._fileEl.accept)
|
|
8301
|
+
pluginNames.add('file-validate-type');
|
|
8302
|
+
for (const name of pluginNames) {
|
|
8303
|
+
const loader = PLUGIN_LOADERS[name];
|
|
8304
|
+
if (!loader)
|
|
8305
|
+
continue;
|
|
8306
|
+
const plugin = await loadPeer({
|
|
8307
|
+
specifier: loader.specifier,
|
|
8308
|
+
globalName: loader.globalName,
|
|
8309
|
+
feature: `File input FilePond plugin "${name}"`,
|
|
8310
|
+
cdnHint: `<script src="path/to/${loader.specifier}.min.js"></script> (self-hosted - copy from node_modules/${loader.specifier}/dist/, or a CDN of your choice)`
|
|
8311
|
+
}, loader.importer);
|
|
8312
|
+
FilePond.registerPlugin(plugin);
|
|
8313
|
+
}
|
|
8314
|
+
const pondOptions = {};
|
|
8315
|
+
const { dataset } = this._fileEl;
|
|
8316
|
+
const readBoolean = (value) => value !== 'false';
|
|
8317
|
+
pondOptions.allowMultiple = this._fileEl.multiple;
|
|
8318
|
+
pondOptions.disabled = this._fileEl.disabled;
|
|
8319
|
+
if (dataset.defaultFile)
|
|
8320
|
+
pondOptions.files = [dataset.defaultFile];
|
|
8321
|
+
if (dataset.maxFiles)
|
|
8322
|
+
pondOptions.maxFiles = Number(dataset.maxFiles);
|
|
8323
|
+
if (this._fileEl.multiple)
|
|
8324
|
+
pondOptions.allowReorder = readBoolean(dataset.allowReorder);
|
|
8325
|
+
if (dataset.labelIdle)
|
|
8326
|
+
pondOptions.labelIdle = dataset.labelIdle;
|
|
8327
|
+
if (dataset.instantUpload !== undefined)
|
|
8328
|
+
pondOptions.instantUpload = readBoolean(dataset.instantUpload);
|
|
8329
|
+
if (dataset.dropValidation !== undefined)
|
|
8330
|
+
pondOptions.dropValidation = readBoolean(dataset.dropValidation);
|
|
8331
|
+
if (dataset.imagePreviewHeight)
|
|
8332
|
+
pondOptions.imagePreviewHeight = Number(dataset.imagePreviewHeight);
|
|
8333
|
+
if (dataset.stylePanelLayout) {
|
|
8334
|
+
pondOptions.stylePanelLayout = dataset.stylePanelLayout;
|
|
8335
|
+
}
|
|
8336
|
+
if (dataset.stylePanelAspectRatio)
|
|
8337
|
+
pondOptions.stylePanelAspectRatio = dataset.stylePanelAspectRatio;
|
|
8338
|
+
this.pond = FilePond.create(this._fileEl, pondOptions);
|
|
8339
|
+
// FilePond inserts its own root as a *sibling* of the input it was
|
|
8340
|
+
// given - but that input lives inside .btn (stock .file-field markup
|
|
8341
|
+
// is `.btn > input[type=file]`), so the fresh FilePond root lands
|
|
8342
|
+
// inside .btn too. Move it back out to be a direct child of .file-field
|
|
8343
|
+
// itself before hiding .btn, or hiding .btn would take the whole
|
|
8344
|
+
// FilePond widget down with it.
|
|
8345
|
+
const pondRoot = this.pond.element;
|
|
8346
|
+
if (pondRoot) {
|
|
8347
|
+
this.el.appendChild(pondRoot);
|
|
8348
|
+
const fileHeight = Number(dataset.fileHeight);
|
|
8349
|
+
if (Number.isFinite(fileHeight) && fileHeight > 0) {
|
|
8350
|
+
pondRoot.style.height = `${fileHeight}px`;
|
|
8351
|
+
}
|
|
8352
|
+
// Matches CrazyPHP's own File.ts behavior - FilePond's free-tier
|
|
8353
|
+
// "Powered by FilePond" credit link doesn't fit a themed, branded UI.
|
|
8354
|
+
pondRoot.querySelectorAll('.filepond--credits').forEach((el) => el.remove());
|
|
8355
|
+
}
|
|
8356
|
+
// Everything from the stock .file-field is now redundant - FilePond's
|
|
8357
|
+
// own drop zone is the entire upload affordance. Hidden, not removed,
|
|
8358
|
+
// so the .file-field structure this component promises to preserve is
|
|
8359
|
+
// still there, just not shown alongside FilePond's widget.
|
|
8360
|
+
this.el.classList.add('file-field-enhanced');
|
|
8361
|
+
this.el.querySelector('.btn')?.classList.add('hide');
|
|
8362
|
+
this.el.querySelector('.file-path-wrapper')?.classList.add('hide');
|
|
8363
|
+
this._syncPathInput();
|
|
8364
|
+
this.pond.on('updatefiles', this._syncPathInput);
|
|
8365
|
+
}
|
|
8366
|
+
_syncPathInput = () => {
|
|
8367
|
+
if (!this._pathEl || !this.pond)
|
|
8368
|
+
return;
|
|
8369
|
+
this._pathEl.value = this.pond
|
|
8370
|
+
.getFiles()
|
|
8371
|
+
.map((f) => f.filename)
|
|
8372
|
+
.join(', ');
|
|
8373
|
+
};
|
|
8374
|
+
}
|
|
8375
|
+
|
|
8376
|
+
const _defaults$5 = {};
|
|
8377
|
+
function readRemoteSpec(el) {
|
|
8378
|
+
const raw = el.dataset.selectRemote;
|
|
8379
|
+
if (!raw)
|
|
8380
|
+
return undefined;
|
|
8381
|
+
try {
|
|
8382
|
+
return JSON.parse(raw);
|
|
8383
|
+
}
|
|
8384
|
+
catch {
|
|
8385
|
+
return undefined;
|
|
8386
|
+
}
|
|
8387
|
+
}
|
|
8388
|
+
// @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Select.ts
|
|
8389
|
+
// Enhances an EXISTING native `<select class="tomselected">` with Tom
|
|
8390
|
+
// Select - searchable, taggable, remote-loading, dependent-field wiring,
|
|
8391
|
+
// clear button, drag-drop reorder. Ported in a somewhat scoped form: the
|
|
8392
|
+
// CrazyPHP source's remote-loading path goes through its own app-specific
|
|
8393
|
+
// Crazyrequest/Crazyurl HTTP-client and query-param helpers, which have no
|
|
8394
|
+
// equivalent in a standalone UI library - this version uses a plain
|
|
8395
|
+
// `fetch()` instead, keeping the same `data-select-remote` JSON shape
|
|
8396
|
+
// (url/value/label/search/dataKey) and the same `{{field}}` render-template
|
|
8397
|
+
// convention.
|
|
8398
|
+
//
|
|
8399
|
+
// Coexistence with FormSelect: `.tomselected` is a recognized exclusion
|
|
8400
|
+
// marker in FormSelect's own AutoInit selector (see src/index.ts), so a
|
|
8401
|
+
// `.tomselected` select is never picked up by FormSelect regardless of
|
|
8402
|
+
// init ordering. This constructor still defensively tears down any
|
|
8403
|
+
// FormSelect instance found on the same element, belt-and-suspenders, in
|
|
8404
|
+
// case that selector rule is ever violated by hand.
|
|
8405
|
+
//
|
|
8406
|
+
// Tom Select is an optional peerDependency, loaded on demand via
|
|
8407
|
+
// peer-loader.
|
|
8408
|
+
class TomSelectField extends Component {
|
|
8409
|
+
tomSelect;
|
|
8410
|
+
ready;
|
|
8411
|
+
_dependsOnEl = null;
|
|
8412
|
+
constructor(el, options) {
|
|
8413
|
+
super(el, options, TomSelectField);
|
|
8414
|
+
this.el.M_TomSelectField = this;
|
|
8415
|
+
FormSelect.getInstance(this.el)?.destroy();
|
|
8416
|
+
this.options = {
|
|
8417
|
+
remote: readRemoteSpec(this.el),
|
|
8418
|
+
...TomSelectField.defaults,
|
|
8419
|
+
...options
|
|
8420
|
+
};
|
|
8421
|
+
this.ready = this._setup();
|
|
8422
|
+
}
|
|
8423
|
+
static get defaults() {
|
|
8424
|
+
return _defaults$5;
|
|
8425
|
+
}
|
|
8426
|
+
static init(els, options = {}) {
|
|
8427
|
+
return super.init(els, options, TomSelectField);
|
|
8428
|
+
}
|
|
8429
|
+
static getInstance(el) {
|
|
8430
|
+
return el.M_TomSelectField;
|
|
8431
|
+
}
|
|
8432
|
+
destroy() {
|
|
8433
|
+
if (this._dependsOnEl)
|
|
8434
|
+
this._dependsOnEl.removeEventListener('change', this._handleDependencyChange);
|
|
8435
|
+
this.tomSelect?.destroy();
|
|
8436
|
+
this.el.M_TomSelectField = undefined;
|
|
8437
|
+
}
|
|
8438
|
+
_handleDependencyChange = () => {
|
|
8439
|
+
this.tomSelect?.clear();
|
|
8440
|
+
this.tomSelect?.clearOptions();
|
|
8441
|
+
this.tomSelect?.load?.('');
|
|
8442
|
+
};
|
|
8443
|
+
async _setup() {
|
|
8444
|
+
const TomSelect = await loadPeer({
|
|
8445
|
+
specifier: 'tom-select',
|
|
8446
|
+
globalName: 'TomSelect',
|
|
8447
|
+
feature: 'Select (Tom Select) enhancement',
|
|
8448
|
+
cdnHint: '<script src="path/to/tom-select.complete.min.js"></script> (self-hosted - copy from node_modules/tom-select/dist/js/, or a CDN of your choice)'
|
|
8449
|
+
}, () => import('tom-select'));
|
|
8450
|
+
const dataset = this.el.dataset;
|
|
8451
|
+
const settings = {
|
|
8452
|
+
persist: false,
|
|
8453
|
+
createOnBlur: true,
|
|
8454
|
+
create: 'selectTag' in dataset,
|
|
8455
|
+
plugins: {},
|
|
8456
|
+
...this.options.settings
|
|
8457
|
+
};
|
|
8458
|
+
if ('selectClear' in dataset) {
|
|
8459
|
+
settings.plugins.clear_button = { title: dataset.selectClear || 'Clear' };
|
|
8460
|
+
}
|
|
8461
|
+
if ('selectTag' in dataset || this.el.multiple) {
|
|
8462
|
+
settings.plugins.caret_position = {};
|
|
8463
|
+
settings.plugins.drag_drop = {};
|
|
8464
|
+
}
|
|
8465
|
+
if (this.el.classList.contains('icons')) {
|
|
8466
|
+
const renderWithIcon = (data, escape) => {
|
|
8467
|
+
const icon = data.icon ? `<img src="${escape(String(data.icon))}" alt="" />` : '';
|
|
8468
|
+
return `<div class="ts-option-content">${icon}<span>${escape(String(data.text ?? ''))}</span></div>`;
|
|
8469
|
+
};
|
|
8470
|
+
settings.render = { ...settings.render, option: renderWithIcon, item: renderWithIcon };
|
|
8471
|
+
}
|
|
8472
|
+
const remote = this.options.remote;
|
|
8473
|
+
if (remote) {
|
|
8474
|
+
settings.valueField = remote.value;
|
|
8475
|
+
if (remote.search)
|
|
8476
|
+
settings.searchField = [remote.search];
|
|
8477
|
+
if (remote.label && remote.label.includes('{{') && remote.label.includes('}}')) {
|
|
8478
|
+
const renderTemplate = (data, escape) => `<div>${remote.label.replace(/\{\{(.*?)\}\}/g, (_m, key) => escape(String(data[key] ?? '')))}</div>`;
|
|
8479
|
+
settings.render = { option: renderTemplate, item: renderTemplate };
|
|
8480
|
+
}
|
|
8481
|
+
else {
|
|
8482
|
+
settings.labelField = remote.label;
|
|
8483
|
+
}
|
|
8484
|
+
settings.load = (query, callback) => {
|
|
8485
|
+
fetch(remote.url)
|
|
8486
|
+
.then((r) => r.json())
|
|
8487
|
+
.then((value) => {
|
|
8488
|
+
const results = remote.dataKey
|
|
8489
|
+
? remote.dataKey.split('.').reduce((acc, key) => acc && acc[key], value)
|
|
8490
|
+
: value?.results ?? value;
|
|
8491
|
+
callback(Array.isArray(results) ? results : []);
|
|
8492
|
+
})
|
|
8493
|
+
.catch(() => callback([]));
|
|
8494
|
+
};
|
|
8495
|
+
}
|
|
8496
|
+
this.tomSelect = new TomSelect(this.el, settings);
|
|
8497
|
+
if (dataset.depends) {
|
|
8498
|
+
this._dependsOnEl = document.querySelector(dataset.depends);
|
|
8499
|
+
this._dependsOnEl?.addEventListener('change', this._handleDependencyChange);
|
|
8500
|
+
}
|
|
8501
|
+
}
|
|
8502
|
+
}
|
|
8503
|
+
|
|
7444
8504
|
const _defaults$4 = {
|
|
7445
8505
|
onOpen: null,
|
|
7446
8506
|
onClose: null
|
|
@@ -8321,7 +9381,7 @@ var M = (function (exports) {
|
|
|
8321
9381
|
}
|
|
8322
9382
|
|
|
8323
9383
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
8324
|
-
const version = '2.3.3-1.0.
|
|
9384
|
+
const version = '2.3.3-1.0.21';
|
|
8325
9385
|
/**
|
|
8326
9386
|
* Convenience helper matching v1's `M.toast({...})` call, since Toast is a
|
|
8327
9387
|
* class in v2 with no bare functional equivalent of its own.
|
|
@@ -8336,6 +9396,8 @@ var M = (function (exports) {
|
|
|
8336
9396
|
*/
|
|
8337
9397
|
function AutoInit(context = document.body, options) {
|
|
8338
9398
|
const registry = {
|
|
9399
|
+
Alert: context.querySelectorAll('.alert:not(.no-autoinit)'),
|
|
9400
|
+
Kanban: context.querySelectorAll('.kanban-board:not(.no-autoinit)'),
|
|
8339
9401
|
Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'),
|
|
8340
9402
|
Cards: context.querySelectorAll('.cards:not(.no-autoinit)'),
|
|
8341
9403
|
Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'),
|
|
@@ -8348,15 +9410,28 @@ var M = (function (exports) {
|
|
|
8348
9410
|
Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'),
|
|
8349
9411
|
Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'),
|
|
8350
9412
|
ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'),
|
|
8351
|
-
|
|
9413
|
+
// Excludes .tomselected - a select opted into TomSelectField instead
|
|
9414
|
+
// (see below), never eligible for FormSelect regardless of ordering.
|
|
9415
|
+
FormSelect: context.querySelectorAll('select:not(.no-autoinit):not(.tomselected)'),
|
|
8352
9416
|
Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'),
|
|
8353
9417
|
Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'),
|
|
8354
9418
|
TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'),
|
|
8355
9419
|
Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'),
|
|
8356
9420
|
Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'),
|
|
8357
|
-
FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)')
|
|
9421
|
+
FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)'),
|
|
9422
|
+
// Excludes .fixed-action-btn.toolbar - that's an unrelated FAB display
|
|
9423
|
+
// mode reusing the same class name, not this component.
|
|
9424
|
+
Toolbar: context.querySelectorAll('.toolbar:not(.fixed-action-btn):not(.no-autoinit)'),
|
|
9425
|
+
PasswordInput: context.querySelectorAll('input[data-password-toggle]:not(.no-autoinit)'),
|
|
9426
|
+
NumberInput: context.querySelectorAll('input[data-type="number"]:not(.no-autoinit)'),
|
|
9427
|
+
ColorInput: context.querySelectorAll('input[type="color"][data-color-picker="pickr"]:not(.no-autoinit)'),
|
|
9428
|
+
AirDatepickerField: context.querySelectorAll('input[data-date-picker="air-datepicker"]:not(.no-autoinit)'),
|
|
9429
|
+
FileInput: context.querySelectorAll('.file-field[data-file-picker="filepond"]:not(.no-autoinit)'),
|
|
9430
|
+
TomSelectField: context.querySelectorAll('select.tomselected:not(.no-autoinit)')
|
|
8358
9431
|
};
|
|
8359
9432
|
Autocomplete.init(registry.Autocomplete, options?.Autocomplete ?? {});
|
|
9433
|
+
Alert.init(registry.Alert, options?.Alert ?? {});
|
|
9434
|
+
Kanban.init(registry.Kanban, options?.Kanban ?? {});
|
|
8360
9435
|
Cards.init(registry.Cards, options?.Cards ?? {});
|
|
8361
9436
|
Carousel.init(registry.Carousel, options?.Carousel ?? {});
|
|
8362
9437
|
Chips.init(registry.Chips, options?.Chips ?? {});
|
|
@@ -8375,6 +9450,13 @@ var M = (function (exports) {
|
|
|
8375
9450
|
Timepicker.init(registry.Timepicker, options?.Timepicker ?? {});
|
|
8376
9451
|
Tooltip.init(registry.Tooltip, options?.Tooltip ?? {});
|
|
8377
9452
|
FloatingActionButton.init(registry.FloatingActionButton, options?.FloatingActionButton ?? {});
|
|
9453
|
+
Toolbar.init(registry.Toolbar, options?.Toolbar ?? {});
|
|
9454
|
+
PasswordInput.init(registry.PasswordInput, options?.PasswordInput ?? {});
|
|
9455
|
+
NumberInput.init(registry.NumberInput, options?.NumberInput ?? {});
|
|
9456
|
+
ColorInput.init(registry.ColorInput, options?.ColorInput ?? {});
|
|
9457
|
+
AirDatepickerField.init(registry.AirDatepickerField, options?.AirDatepickerField ?? {});
|
|
9458
|
+
FileInput.init(registry.FileInput, options?.FileInput ?? {});
|
|
9459
|
+
TomSelectField.init(registry.TomSelectField, options?.TomSelectField ?? {});
|
|
8378
9460
|
}
|
|
8379
9461
|
// Init
|
|
8380
9462
|
if (typeof document !== 'undefined') {
|
|
@@ -8389,6 +9471,8 @@ var M = (function (exports) {
|
|
|
8389
9471
|
Range.Init();
|
|
8390
9472
|
Cards.Init();
|
|
8391
9473
|
|
|
9474
|
+
exports.AirDatepickerField = AirDatepickerField;
|
|
9475
|
+
exports.Alert = Alert;
|
|
8392
9476
|
exports.AutoInit = AutoInit;
|
|
8393
9477
|
exports.Autocomplete = Autocomplete;
|
|
8394
9478
|
exports.Cards = Cards;
|
|
@@ -8396,14 +9480,19 @@ var M = (function (exports) {
|
|
|
8396
9480
|
exports.CharacterCounter = CharacterCounter;
|
|
8397
9481
|
exports.Chips = Chips;
|
|
8398
9482
|
exports.Collapsible = Collapsible;
|
|
9483
|
+
exports.ColorInput = ColorInput;
|
|
8399
9484
|
exports.Datepicker = Datepicker;
|
|
8400
9485
|
exports.Dropdown = Dropdown;
|
|
9486
|
+
exports.FileInput = FileInput;
|
|
8401
9487
|
exports.FloatingActionButton = FloatingActionButton;
|
|
8402
9488
|
exports.FormSelect = FormSelect;
|
|
8403
9489
|
exports.Forms = Forms;
|
|
9490
|
+
exports.Kanban = Kanban;
|
|
8404
9491
|
exports.Materialbox = Materialbox;
|
|
8405
9492
|
exports.Modal = Modal;
|
|
9493
|
+
exports.NumberInput = NumberInput;
|
|
8406
9494
|
exports.Parallax = Parallax;
|
|
9495
|
+
exports.PasswordInput = PasswordInput;
|
|
8407
9496
|
exports.Pushpin = Pushpin;
|
|
8408
9497
|
exports.Range = Range;
|
|
8409
9498
|
exports.ScrollSpy = ScrollSpy;
|
|
@@ -8413,6 +9502,8 @@ var M = (function (exports) {
|
|
|
8413
9502
|
exports.TapTarget = TapTarget;
|
|
8414
9503
|
exports.Timepicker = Timepicker;
|
|
8415
9504
|
exports.Toast = Toast;
|
|
9505
|
+
exports.TomSelectField = TomSelectField;
|
|
9506
|
+
exports.Toolbar = Toolbar;
|
|
8416
9507
|
exports.Tooltip = Tooltip;
|
|
8417
9508
|
exports.Waves = Waves;
|
|
8418
9509
|
exports.toast = toast;
|