kmaterialize 2.3.3-1.0.21 → 2.3.3-1.0.23

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.
Files changed (47) hide show
  1. package/components/air-datepicker/air-datepicker.js +152 -0
  2. package/components/alert/alert.js +54 -0
  3. package/components/button/buttons.js +220 -0
  4. package/components/card/cards.js +149 -0
  5. package/components/carousel/carousel.js +574 -0
  6. package/components/carousel/slider.js +340 -0
  7. package/components/chip/chips.js +341 -0
  8. package/components/collapsible/collapsible.js +156 -0
  9. package/components/color-input/color-input.js +166 -0
  10. package/components/datepicker/datepicker.js +1035 -0
  11. package/components/dialog/materialbox.js +377 -0
  12. package/components/dialog/modal.js +72 -0
  13. package/components/dropdown/dropdown.js +505 -0
  14. package/components/file-input/file-input.js +169 -0
  15. package/components/kanban/_kanban.scss +69 -0
  16. package/components/kanban/kanban.js +168 -0
  17. package/components/kanban/kanban.ts +57 -8
  18. package/components/loading/_loading.scss +68 -0
  19. package/components/loading/loading.ts +104 -0
  20. package/components/loading/loadingSpec.js +102 -0
  21. package/components/navigation-drawer/sidenav.js +454 -0
  22. package/components/number-input/number-input.js +68 -0
  23. package/components/password-input/password-input.js +49 -0
  24. package/components/popup/_popup.scss +106 -0
  25. package/components/popup/popup.ts +113 -0
  26. package/components/popup/popupSpec.js +140 -0
  27. package/components/search/autocomplete.js +470 -0
  28. package/components/slider/range.js +169 -0
  29. package/components/snackbar/toasts.js +244 -0
  30. package/components/tabs/tabs.js +289 -0
  31. package/components/textfield/forms.js +172 -0
  32. package/components/textfield/select.js +385 -0
  33. package/components/timepicker/timepicker.js +698 -0
  34. package/components/tom-select/tom-select-field.js +130 -0
  35. package/components/toolbar/toolbar.js +134 -0
  36. package/components/tooltip/tooltip.js +270 -0
  37. package/dist/css/materialize.colors.min.css +1 -1
  38. package/dist/css/materialize.css +322 -1
  39. package/dist/css/materialize.min.css +2 -2
  40. package/dist/css/materialize.min.css.map +1 -1
  41. package/dist/js/materialize.cjs.js +258 -42
  42. package/dist/js/materialize.d.ts +50 -3
  43. package/dist/js/materialize.js +258 -42
  44. package/dist/js/materialize.min.js +2 -2
  45. package/dist/js/materialize.mjs +257 -43
  46. package/package.json +6 -1
  47. package/sass/materialize.scss +2 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Materialize v2.3.3-1.0.21 (https://materializeweb.com)
2
+ * Materialize v2.3.3-1.0.23 (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$x = {
403
+ const _defaults$y = {
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$x;
456
+ return _defaults$y;
457
457
  }
458
458
  /**
459
459
  * Initializes instances of Dropdown.
@@ -904,7 +904,7 @@ var M = (function (exports) {
904
904
  };
905
905
  }
906
906
 
907
- const _defaults$w = {
907
+ const _defaults$x = {
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$w;
967
+ return _defaults$x;
968
968
  }
969
969
  /**
970
970
  * Initializes instances of Autocomplete.
@@ -1372,6 +1372,194 @@ var M = (function (exports) {
1372
1372
  }
1373
1373
  }
1374
1374
 
1375
+ const _cache = new Map();
1376
+ async function loadPeer(spec, importer) {
1377
+ if (_cache.has(spec.specifier))
1378
+ return _cache.get(spec.specifier);
1379
+ try {
1380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1381
+ const mod = await importer();
1382
+ const resolved = mod?.default ?? mod;
1383
+ _cache.set(spec.specifier, resolved);
1384
+ return resolved;
1385
+ }
1386
+ catch {
1387
+ // fall through to the global-scope lookup below
1388
+ }
1389
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1390
+ const globalScope = typeof window !== 'undefined' ? window : undefined;
1391
+ if (globalScope && globalScope[spec.globalName]) {
1392
+ const resolved = globalScope[spec.globalName];
1393
+ _cache.set(spec.specifier, resolved);
1394
+ return resolved;
1395
+ }
1396
+ throw new Error(`kmaterialize's ${spec.feature} requires "${spec.specifier}", which isn't installed/loaded.\n` +
1397
+ `- If you're using a bundler: npm/pnpm/yarn install "${spec.specifier}".\n` +
1398
+ `- If you're using the plain <script> (no-bundler) build: add\n` +
1399
+ ` ${spec.cdnHint}\n` +
1400
+ ` before initializing this component, so window.${spec.globalName} is defined.`);
1401
+ }
1402
+
1403
+ function withClass(required, custom) {
1404
+ return [
1405
+ required,
1406
+ ...(typeof custom === 'string'
1407
+ ? custom.split(/\s+/)
1408
+ : custom ?? [])
1409
+ ]
1410
+ .filter((value, index, values) => value && values.indexOf(value) === index)
1411
+ .join(' ');
1412
+ }
1413
+ /** Materialize-themed SweetAlert2 dialogs. No element initialization is needed. */
1414
+ class Popup {
1415
+ /** Fresh defaults so per-dialog customization cannot affect later popups. */
1416
+ static get defaults() {
1417
+ return {
1418
+ buttonsStyling: false,
1419
+ heightAuto: false,
1420
+ customClass: {
1421
+ container: 'popup-container',
1422
+ popup: 'popup',
1423
+ confirmButton: 'btn filled',
1424
+ cancelButton: 'btn outlined',
1425
+ denyButton: 'btn tonal'
1426
+ }
1427
+ };
1428
+ }
1429
+ static _load() {
1430
+ // Use the JS-only build: the consumer controls stylesheet order.
1431
+ return loadPeer({
1432
+ specifier: 'sweetalert2',
1433
+ globalName: 'Swal',
1434
+ feature: 'Popup',
1435
+ cdnHint: '<link rel="stylesheet" href="path/to/sweetalert2.min.css">\n' +
1436
+ ' <script src="path/to/sweetalert2.min.js"></script>\n' +
1437
+ ' (copy from node_modules/sweetalert2/dist/; load the CSS before materialize.css)'
1438
+ }, () => import('sweetalert2/dist/sweetalert2.js'));
1439
+ }
1440
+ /** Open a dialog and resolve with SweetAlert2's confirmation/dismissal result. */
1441
+ static async fire(options = {}) {
1442
+ const swal = await Popup._load();
1443
+ const defaults = Popup.defaults;
1444
+ const customClass = {
1445
+ ...defaults.customClass,
1446
+ ...options.customClass,
1447
+ // Keep the scoped theme even when consumers add their own classes.
1448
+ container: withClass('popup-container', options.customClass?.container),
1449
+ popup: withClass('popup', options.customClass?.popup)
1450
+ };
1451
+ /*
1452
+ * SweetAlertOptions is a discriminated union because `input: "file"`
1453
+ * uses a different inputValidator signature. Object spreading causes
1454
+ * TypeScript to lose that correlation, even though the resulting
1455
+ * object is valid.
1456
+ */
1457
+ const mergedOptions = {
1458
+ ...defaults,
1459
+ ...options,
1460
+ customClass
1461
+ };
1462
+ const result = await swal.fire(mergedOptions);
1463
+ /*
1464
+ * SweetAlert2 declares its own internal Awaited<T>, while modern
1465
+ * TypeScript provides the global Awaited<T>. They are semantically
1466
+ * equivalent here but TypeScript can report them as unrelated.
1467
+ */
1468
+ return result;
1469
+ }
1470
+ /** Close the current SweetAlert2 dialog, resolving its pending result. */
1471
+ static async close() {
1472
+ const swal = await Popup._load();
1473
+ swal.close();
1474
+ }
1475
+ }
1476
+
1477
+ const _defaults$w = {
1478
+ active: true,
1479
+ label: 'Loading…',
1480
+ completeLabel: 'Ready'
1481
+ };
1482
+ /** A circular loading indicator with an optional centered logo or icon. */
1483
+ class Loading extends Component {
1484
+ _originalAttributes = {};
1485
+ _originalActive;
1486
+ _originalLoading;
1487
+ _generatedSpinner = null;
1488
+ constructor(el, options = {}) {
1489
+ super(el, options, Loading);
1490
+ this.options = { ...Loading.defaults, ...options };
1491
+ this.el['M_Loading'] = this;
1492
+ this._originalActive = this.el.classList.contains('active');
1493
+ this._originalLoading = this.el.classList.contains('loading');
1494
+ for (const name of ['role', 'aria-live', 'aria-busy', 'aria-label']) {
1495
+ this._originalAttributes[name] = this.el.getAttribute(name);
1496
+ }
1497
+ // Preserve an accessible name supplied in the markup unless overridden.
1498
+ if (options.label === undefined && this.el.hasAttribute('aria-label')) {
1499
+ this.options.label = this.el.getAttribute('aria-label');
1500
+ }
1501
+ this.el.classList.add('loading');
1502
+ // Reuse authored Preloader markup; generate it for the compact JS API.
1503
+ if (!this.el.querySelector(':scope > .preloader-wrapper')) {
1504
+ this._generatedSpinner = document.createElement('div');
1505
+ this._generatedSpinner.className = 'preloader-wrapper active';
1506
+ this._generatedSpinner.setAttribute('aria-hidden', 'true');
1507
+ this._generatedSpinner.innerHTML = `<div class="spinner-layer">
1508
+ <div class="circle-clipper left"><div class="circle"></div></div>
1509
+ <div class="gap-patch"><div class="circle"></div></div>
1510
+ <div class="circle-clipper right"><div class="circle"></div></div>
1511
+ </div>`;
1512
+ this.el.appendChild(this._generatedSpinner);
1513
+ }
1514
+ if (!this.el.hasAttribute('role'))
1515
+ this.el.setAttribute('role', 'status');
1516
+ if (!this.el.hasAttribute('aria-live'))
1517
+ this.el.setAttribute('aria-live', 'polite');
1518
+ if (this.options.active)
1519
+ this.start();
1520
+ else
1521
+ this.stop();
1522
+ }
1523
+ static get defaults() {
1524
+ return _defaults$w;
1525
+ }
1526
+ static init(els, options = {}) {
1527
+ return super.init(els, options, Loading);
1528
+ }
1529
+ static getInstance(el) {
1530
+ return el['M_Loading'];
1531
+ }
1532
+ get isActive() {
1533
+ return this.el.classList.contains('active');
1534
+ }
1535
+ /** Show the animated ring and announce the loading status. */
1536
+ start(label = this.options.label) {
1537
+ this.el.setAttribute('aria-label', label);
1538
+ this.el.setAttribute('aria-busy', 'true');
1539
+ this.el.classList.add('active');
1540
+ }
1541
+ /** Hide the ring, keeping the centered content visible. */
1542
+ stop(label = this.options.completeLabel) {
1543
+ this.el.setAttribute('aria-label', label);
1544
+ this.el.setAttribute('aria-busy', 'false');
1545
+ this.el.classList.remove('active');
1546
+ }
1547
+ /** Restore the original markup state and remove the instance. */
1548
+ destroy() {
1549
+ this._generatedSpinner?.remove();
1550
+ this._generatedSpinner = null;
1551
+ for (const [name, value] of Object.entries(this._originalAttributes)) {
1552
+ if (value === null)
1553
+ this.el.removeAttribute(name);
1554
+ else
1555
+ this.el.setAttribute(name, value);
1556
+ }
1557
+ this.el.classList.toggle('active', this._originalActive);
1558
+ this.el.classList.toggle('loading', this._originalLoading);
1559
+ delete this.el['M_Loading'];
1560
+ }
1561
+ }
1562
+
1375
1563
  const _defaults$v = {
1376
1564
  dismissible: true
1377
1565
  };
@@ -1433,13 +1621,24 @@ var M = (function (exports) {
1433
1621
  class Kanban extends Component {
1434
1622
  _draggedCard = null;
1435
1623
  _dragSourceColumn = null;
1624
+ _dropPreview = null;
1625
+ _dragImage = null;
1626
+ _previewHeight = 64;
1436
1627
  _onDragStart = (event) => {
1437
1628
  const card = event.target?.closest('.kanban-card');
1438
- if (!card || !this.options.draggable)
1629
+ if (!card || !this.options.draggable || card.classList.contains('is-disabled') || card.getAttribute('aria-disabled') === 'true')
1439
1630
  return;
1440
1631
  this._draggedCard = card;
1441
1632
  this._dragSourceColumn = card.closest('.kanban-column');
1633
+ this._previewHeight = Math.max(64, Math.round(card.getBoundingClientRect().height));
1442
1634
  card.classList.add('is-dragging');
1635
+ this._dragImage = card.cloneNode(true);
1636
+ this._dragImage.classList.remove('is-dragging');
1637
+ this._dragImage.classList.add('kanban-drag-image');
1638
+ this._dragImage.setAttribute('aria-hidden', 'true');
1639
+ this._dragImage.style.width = `${card.getBoundingClientRect().width}px`;
1640
+ document.body.appendChild(this._dragImage);
1641
+ event.dataTransfer?.setDragImage(this._dragImage, card.offsetWidth / 2, card.offsetHeight / 2);
1443
1642
  event.dataTransfer?.setData('text/plain', card.dataset.kanbanCard || '');
1444
1643
  if (event.dataTransfer)
1445
1644
  event.dataTransfer.effectAllowed = 'move';
@@ -1455,6 +1654,7 @@ var M = (function (exports) {
1455
1654
  event.dataTransfer.dropEffect = 'move';
1456
1655
  this.el.querySelectorAll('.kanban-column.is-drag-over').forEach((item) => item.classList.remove('is-drag-over'));
1457
1656
  column.classList.add('is-drag-over');
1657
+ this._updateDropPreview(column, event);
1458
1658
  };
1459
1659
  _onDrop = (event) => {
1460
1660
  if (!this._draggedCard)
@@ -1466,17 +1666,21 @@ var M = (function (exports) {
1466
1666
  const body = column.querySelector('.kanban-column-body') || column;
1467
1667
  const targetCard = event.target?.closest('.kanban-card');
1468
1668
  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);
1669
+ const movedCard = this._draggedCard;
1670
+ if (this._dropPreview?.parentElement === body) {
1671
+ body.insertBefore(movedCard, this._dropPreview);
1672
+ this._dropPreview.remove();
1673
+ }
1674
+ else if (targetCard && targetCard !== movedCard && targetCard.parentElement === body) {
1675
+ body.insertBefore(movedCard, targetCard);
1472
1676
  }
1473
1677
  else {
1474
- body.appendChild(this._draggedCard);
1678
+ body.appendChild(movedCard);
1475
1679
  }
1476
1680
  this._clearDragState();
1477
1681
  this._updateCounts();
1478
1682
  if (source && source !== column)
1479
- this.options.onMove?.({ card: this._draggedCard, from: source, to: column });
1683
+ this.options.onMove?.({ card: movedCard, from: source, to: column });
1480
1684
  };
1481
1685
  _onDragEnd = () => this._clearDragState();
1482
1686
  constructor(el, options) {
@@ -1505,9 +1709,15 @@ var M = (function (exports) {
1505
1709
  body.setAttribute('role', 'list');
1506
1710
  column.querySelectorAll('.kanban-card').forEach((card) => {
1507
1711
  card.setAttribute('role', 'listitem');
1508
- card.setAttribute('tabindex', '0');
1509
- if (this.options.draggable)
1712
+ const disabled = card.classList.contains('is-disabled') || card.getAttribute('aria-disabled') === 'true';
1713
+ card.setAttribute('tabindex', disabled ? '-1' : '0');
1714
+ if (disabled) {
1715
+ card.setAttribute('aria-disabled', 'true');
1716
+ card.draggable = false;
1717
+ }
1718
+ else if (this.options.draggable) {
1510
1719
  card.draggable = true;
1720
+ }
1511
1721
  });
1512
1722
  });
1513
1723
  this._updateCounts();
@@ -1519,10 +1729,15 @@ var M = (function (exports) {
1519
1729
  this.el.addEventListener('dragend', this._onDragEnd);
1520
1730
  }
1521
1731
  _clearDragState() {
1732
+ this._dragImage?.remove();
1733
+ this._dragImage = null;
1734
+ this._dropPreview?.remove();
1735
+ this._dropPreview = null;
1522
1736
  this._draggedCard?.classList.remove('is-dragging');
1523
1737
  this.el.querySelectorAll('.kanban-column.is-drag-over').forEach((item) => item.classList.remove('is-drag-over'));
1524
1738
  this._draggedCard = null;
1525
1739
  this._dragSourceColumn = null;
1740
+ this._previewHeight = 64;
1526
1741
  }
1527
1742
  _updateCounts() {
1528
1743
  this.el.querySelectorAll('.kanban-column').forEach((column) => {
@@ -1530,8 +1745,33 @@ var M = (function (exports) {
1530
1745
  const body = column.querySelector('.kanban-column-body');
1531
1746
  if (count && body)
1532
1747
  count.textContent = String(body.querySelectorAll(':scope > .kanban-card').length);
1748
+ const empty = body?.querySelector('.kanban-empty');
1749
+ if (empty && body)
1750
+ empty.hidden = body.querySelectorAll(':scope > .kanban-card').length > 0;
1533
1751
  });
1534
1752
  }
1753
+ _updateDropPreview(column, event) {
1754
+ const body = column.querySelector('.kanban-column-body') || column;
1755
+ const targetCard = event.target?.closest('.kanban-card');
1756
+ if (targetCard === this._draggedCard)
1757
+ return;
1758
+ if (!this._dropPreview) {
1759
+ this._dropPreview = document.createElement('div');
1760
+ this._dropPreview.className = 'kanban-drop-preview';
1761
+ this._dropPreview.setAttribute('aria-hidden', 'true');
1762
+ }
1763
+ // Keep the preview tied to the dragged card's original height. Using the
1764
+ // hovered card's height makes the placeholder jump as the pointer crosses
1765
+ // cards with different content lengths.
1766
+ this._dropPreview.style.height = `${this._previewHeight}px`;
1767
+ if (targetCard && targetCard.parentElement === body) {
1768
+ const box = targetCard.getBoundingClientRect();
1769
+ body.insertBefore(this._dropPreview, event.clientY < box.top + box.height / 2 ? targetCard : targetCard.nextSibling);
1770
+ }
1771
+ else if (this._dropPreview.parentElement !== body) {
1772
+ body.appendChild(this._dropPreview);
1773
+ }
1774
+ }
1535
1775
  destroy() {
1536
1776
  this._clearDragState();
1537
1777
  this.el.removeEventListener('dragstart', this._onDragStart);
@@ -7794,34 +8034,6 @@ var M = (function (exports) {
7794
8034
  };
7795
8035
  }
7796
8036
 
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
8037
  const _defaults$9 = {
7826
8038
  thousandsSeparator: ' ',
7827
8039
  radix: '.',
@@ -9381,7 +9593,7 @@ var M = (function (exports) {
9381
9593
  }
9382
9594
 
9383
9595
  /* eslint-disable @typescript-eslint/no-unused-vars */
9384
- const version = '2.3.3-1.0.21';
9596
+ const version = '2.3.3-1.0.23';
9385
9597
  /**
9386
9598
  * Convenience helper matching v1's `M.toast({...})` call, since Toast is a
9387
9599
  * class in v2 with no bare functional equivalent of its own.
@@ -9396,6 +9608,7 @@ var M = (function (exports) {
9396
9608
  */
9397
9609
  function AutoInit(context = document.body, options) {
9398
9610
  const registry = {
9611
+ Loading: context.querySelectorAll('.loading:not(.no-autoinit)'),
9399
9612
  Alert: context.querySelectorAll('.alert:not(.no-autoinit)'),
9400
9613
  Kanban: context.querySelectorAll('.kanban-board:not(.no-autoinit)'),
9401
9614
  Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'),
@@ -9430,6 +9643,7 @@ var M = (function (exports) {
9430
9643
  TomSelectField: context.querySelectorAll('select.tomselected:not(.no-autoinit)')
9431
9644
  };
9432
9645
  Autocomplete.init(registry.Autocomplete, options?.Autocomplete ?? {});
9646
+ Loading.init(registry.Loading, options?.Loading ?? {});
9433
9647
  Alert.init(registry.Alert, options?.Alert ?? {});
9434
9648
  Kanban.init(registry.Kanban, options?.Kanban ?? {});
9435
9649
  Cards.init(registry.Cards, options?.Cards ?? {});
@@ -9488,11 +9702,13 @@ var M = (function (exports) {
9488
9702
  exports.FormSelect = FormSelect;
9489
9703
  exports.Forms = Forms;
9490
9704
  exports.Kanban = Kanban;
9705
+ exports.Loading = Loading;
9491
9706
  exports.Materialbox = Materialbox;
9492
9707
  exports.Modal = Modal;
9493
9708
  exports.NumberInput = NumberInput;
9494
9709
  exports.Parallax = Parallax;
9495
9710
  exports.PasswordInput = PasswordInput;
9711
+ exports.Popup = Popup;
9496
9712
  exports.Pushpin = Pushpin;
9497
9713
  exports.Range = Range;
9498
9714
  exports.ScrollSpy = ScrollSpy;