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
@@ -0,0 +1,156 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { Component } from '../../src/component';
3
+ const _defaults = {
4
+ accordion: true,
5
+ onOpenStart: null,
6
+ onOpenEnd: null,
7
+ onCloseStart: null,
8
+ onCloseEnd: null,
9
+ inDuration: 300,
10
+ outDuration: 300
11
+ };
12
+ export class Collapsible extends Component {
13
+ _headers;
14
+ constructor(el, options) {
15
+ super(el, options, Collapsible);
16
+ this.el['M_Collapsible'] = this;
17
+ this.options = {
18
+ ...Collapsible.defaults,
19
+ ...options
20
+ };
21
+ // Setup tab indices
22
+ this._headers = Array.from(this.el.querySelectorAll('li > .collapsible-header'));
23
+ this._headers.forEach((el) => (el.tabIndex = 0));
24
+ this._setupEventHandlers();
25
+ // Open active
26
+ const activeBodies = Array.from(this.el.querySelectorAll('li.active > .collapsible-body'));
27
+ if (this.options.accordion) {
28
+ if (activeBodies.length > 0) {
29
+ // Accordion => open first active only
30
+ this._setExpanded(activeBodies[0]);
31
+ }
32
+ }
33
+ else {
34
+ // Expandables => all active
35
+ activeBodies.forEach((el) => this._setExpanded(el));
36
+ }
37
+ }
38
+ static get defaults() {
39
+ return _defaults;
40
+ }
41
+ /**
42
+ * Initializes instances of Collapsible.
43
+ * @param els HTML elements.
44
+ * @param options Component options.
45
+ */
46
+ static init(els, options = {}) {
47
+ return super.init(els, options, Collapsible);
48
+ }
49
+ static getInstance(el) {
50
+ return el['M_Collapsible'];
51
+ }
52
+ destroy() {
53
+ this._removeEventHandlers();
54
+ this.el['M_Collapsible'] = undefined;
55
+ }
56
+ _setupEventHandlers() {
57
+ this.el.addEventListener('click', this._handleCollapsibleClick);
58
+ this._headers.forEach((header) => header.addEventListener('keydown', this._handleCollapsibleKeydown));
59
+ }
60
+ _removeEventHandlers() {
61
+ this.el.removeEventListener('click', this._handleCollapsibleClick);
62
+ this._headers.forEach((header) => header.removeEventListener('keydown', this._handleCollapsibleKeydown));
63
+ }
64
+ _handleCollapsibleClick = (e) => {
65
+ const header = e.target.closest('.collapsible-header');
66
+ if (e.target && header) {
67
+ const collapsible = header.closest('.collapsible');
68
+ if (collapsible !== this.el)
69
+ return;
70
+ const li = header.closest('li');
71
+ const isActive = li.classList.contains('active');
72
+ const index = [...li.parentNode.children].indexOf(li);
73
+ if (isActive)
74
+ this.close(index);
75
+ else
76
+ this.open(index);
77
+ }
78
+ };
79
+ _handleCollapsibleKeydown = (e) => {
80
+ if (Utils.keys.ENTER.includes(e.key)) {
81
+ this._handleCollapsibleClick(e);
82
+ }
83
+ };
84
+ _setExpanded(li) {
85
+ li.style.maxHeight = li.scrollHeight + 'px';
86
+ }
87
+ _animateIn(index) {
88
+ const li = this.el.children[index];
89
+ if (!li)
90
+ return;
91
+ const body = li.querySelector('.collapsible-body');
92
+ const duration = this.options.inDuration; // easeInOutCubic
93
+ body.style.transition = `max-height ${duration}ms ease-out`;
94
+ this._setExpanded(body);
95
+ setTimeout(() => {
96
+ if (typeof this.options.onOpenEnd === 'function') {
97
+ this.options.onOpenEnd.call(this, li);
98
+ }
99
+ }, duration);
100
+ }
101
+ _animateOut(index) {
102
+ const li = this.el.children[index];
103
+ if (!li)
104
+ return;
105
+ const body = li.querySelector('.collapsible-body');
106
+ const duration = this.options.outDuration; // easeInOutCubic
107
+ body.style.transition = `max-height ${duration}ms ease-out`;
108
+ body.style.maxHeight = '0';
109
+ setTimeout(() => {
110
+ if (typeof this.options.onCloseEnd === 'function') {
111
+ this.options.onCloseEnd.call(this, li);
112
+ }
113
+ }, duration);
114
+ }
115
+ /**
116
+ * Open collapsible section.
117
+ * @param n Nth section to open.
118
+ */
119
+ open = (index) => {
120
+ const listItems = Array.from(this.el.children).filter((c) => c.tagName === 'LI');
121
+ const li = listItems[index];
122
+ if (li && !li.classList.contains('active')) {
123
+ // onOpenStart callback
124
+ if (typeof this.options.onOpenStart === 'function') {
125
+ this.options.onOpenStart.call(this, li);
126
+ }
127
+ // Handle accordion behavior
128
+ if (this.options.accordion) {
129
+ const activeLis = listItems.filter((li) => li.classList.contains('active'));
130
+ activeLis.forEach((activeLi) => {
131
+ const index = listItems.indexOf(activeLi);
132
+ this.close(index);
133
+ });
134
+ }
135
+ // Animate in
136
+ li.classList.add('active');
137
+ this._animateIn(index);
138
+ }
139
+ };
140
+ /**
141
+ * Close collapsible section.
142
+ * @param n Nth section to close.
143
+ */
144
+ close = (index) => {
145
+ const li = Array.from(this.el.children).filter((c) => c.tagName === 'LI')[index];
146
+ if (li && li.classList.contains('active')) {
147
+ // onCloseStart callback
148
+ if (typeof this.options.onCloseStart === 'function') {
149
+ this.options.onCloseStart.call(this, li);
150
+ }
151
+ // Animate out
152
+ li.classList.remove('active');
153
+ this._animateOut(index);
154
+ }
155
+ };
156
+ }
@@ -0,0 +1,166 @@
1
+ import { Component } from '../../src/component';
2
+ import { loadPeer } from '../../src/peer-loader';
3
+ // @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Color.ts
4
+ // Built-in French translation for Pickr's UI strings, activated by
5
+ // `data-color-locale="fr-fr"` alone - no separate options object required
6
+ // from the consumer, unlike a fully custom `options.locale` override.
7
+ const FR_FR = {
8
+ 'ui:dialog': 'boîte de dialogue du sélecteur de couleur',
9
+ 'btn:toggle': 'basculer la boîte de dialogue du sélecteur de couleur',
10
+ 'btn:swatch': 'échantillon de couleur',
11
+ 'btn:last-color': 'utiliser la couleur précédente',
12
+ 'btn:save': 'Enregistrer',
13
+ 'btn:cancel': 'Annuler',
14
+ 'btn:clear': 'Effacer',
15
+ 'aria:btn:save': 'enregistrer et fermer',
16
+ 'aria:btn:cancel': 'annuler et fermer',
17
+ 'aria:btn:clear': 'effacer et fermer',
18
+ 'aria:input': 'champ de saisie de couleur',
19
+ 'aria:palette': 'zone de sélection des couleurs',
20
+ 'aria:hue': 'curseur de sélection de teinte',
21
+ 'aria:opacity': "curseur de sélection d'opacité"
22
+ };
23
+ const _defaults = {
24
+ theme: 'classic',
25
+ opacity: true,
26
+ swatches: [
27
+ 'rgba(244, 67, 54, 1)',
28
+ 'rgba(233, 30, 99, 0.95)',
29
+ 'rgba(156, 39, 176, 0.9)',
30
+ 'rgba(103, 58, 183, 0.85)',
31
+ 'rgba(63, 81, 181, 0.8)',
32
+ 'rgba(33, 150, 243, 0.75)',
33
+ 'rgba(3, 169, 244, 0.7)',
34
+ 'rgba(0, 188, 212, 0.7)',
35
+ 'rgba(0, 150, 136, 0.75)',
36
+ 'rgba(76, 175, 80, 0.8)',
37
+ 'rgba(139, 195, 74, 0.85)',
38
+ 'rgba(205, 220, 57, 0.9)',
39
+ 'rgba(255, 235, 59, 0.95)',
40
+ 'rgba(255, 193, 7, 1)'
41
+ ]
42
+ };
43
+ // @implement /Users/kzarshenas/Sites/CrazyProject/CrazyPHP/src/Front/Library/Utility/Form/Color.ts
44
+ // Enhances a native `<input type="color" data-color-picker="pickr">` with a
45
+ // full Pickr popup (palette, hue/opacity sliders, swatches, hex/rgba/hsla).
46
+ // If `data-color-picker` is absent the input is left completely untouched -
47
+ // still a plain native color swatch, matching CrazyPHP's own fallback.
48
+ //
49
+ // Pickr remains an optional peerDependency and is loaded on demand via peer-loader.
50
+ export class ColorInput extends Component {
51
+ pickr;
52
+ ready;
53
+ _swatchEl;
54
+ _labels;
55
+ constructor(el, options) {
56
+ super(el, options, ColorInput);
57
+ this.el.M_ColorInput = this;
58
+ this.options = {
59
+ ...ColorInput.defaults,
60
+ ...options
61
+ };
62
+ this._swatchEl = document.createElement('div');
63
+ this.el.after(this._swatchEl);
64
+ this.el.classList.add('hide');
65
+ this.el.addEventListener('change', this._handleInputChange);
66
+ this._labels = Array.from(document.querySelectorAll('label')).filter(label => label.htmlFor === this.el.id);
67
+ this._labels.forEach(label => label.addEventListener('click', this._handleLabelClick));
68
+ this.ready = this._setup();
69
+ }
70
+ static get defaults() {
71
+ return _defaults;
72
+ }
73
+ static init(els, options = {}) {
74
+ return super.init(els, options, ColorInput);
75
+ }
76
+ static getInstance(el) {
77
+ return el.M_ColorInput;
78
+ }
79
+ destroy() {
80
+ this.el.removeEventListener('change', this._handleInputChange);
81
+ this._labels.forEach(label => label.removeEventListener('click', this._handleLabelClick));
82
+ this.pickr?.destroyAndRemove();
83
+ this._swatchEl.remove();
84
+ this.el.classList.remove('hide');
85
+ this.el.M_ColorInput = undefined;
86
+ }
87
+ _handleInputChange = () => {
88
+ this.pickr?.setColor(this.el.value);
89
+ };
90
+ _handleLabelClick = (event) => {
91
+ // A label associated with a hidden input[type=color] otherwise opens
92
+ // the browser's native picker (notably in Firefox). Route the same
93
+ // accessible label activation to Pickr instead.
94
+ event.preventDefault();
95
+ void this.ready.then(() => this.pickr?.show());
96
+ };
97
+ async _setup() {
98
+ const Pickr = await loadPeer({
99
+ specifier: '@simonwep/pickr',
100
+ globalName: 'Pickr',
101
+ feature: 'Color input (Pickr) enhancement',
102
+ cdnHint: '<link rel="stylesheet" href="path/to/pickr-classic.min.css">\n' +
103
+ ' <script src="path/to/pickr.min.js"></script>\n' +
104
+ ' (self-hosted - copy from node_modules/@simonwep/pickr/dist/, or a CDN of your choice)'
105
+ }, () => import('@simonwep/pickr'));
106
+ const dataset = this.el.dataset;
107
+ const theme = (['classic', 'monolith', 'nano'].includes(dataset.colorTheme ?? '')
108
+ ? dataset.colorTheme
109
+ : this.options.theme);
110
+ const lockOpacity = dataset.colorOpacity !== undefined
111
+ ? ['false', '0', '', 'null'].includes(dataset.colorOpacity)
112
+ : !this.options.opacity;
113
+ const pickrOptions = {
114
+ el: this._swatchEl,
115
+ theme,
116
+ lockOpacity,
117
+ swatches: this.options.swatches,
118
+ components: {
119
+ preview: true,
120
+ opacity: true,
121
+ hue: true,
122
+ interaction: {
123
+ hex: true,
124
+ rgba: true,
125
+ hsla: true,
126
+ hsva: true,
127
+ cmyk: true,
128
+ input: true,
129
+ clear: true,
130
+ save: true
131
+ }
132
+ }
133
+ };
134
+ if (this.options.locale) {
135
+ pickrOptions.i18n = this.options.locale;
136
+ }
137
+ else if (dataset.colorLocale === 'fr-fr') {
138
+ pickrOptions.i18n = FR_FR;
139
+ }
140
+ const currentValue = this.el.getAttribute('value');
141
+ if (currentValue && currentValue !== 'randomHex()') {
142
+ pickrOptions.default = currentValue;
143
+ }
144
+ else if (this.el.hasAttribute('default')) {
145
+ const currentDefault = this.el.getAttribute('default');
146
+ if (currentDefault === 'randomHex()') {
147
+ const randomColor = Math.floor(Math.random() * 16777216);
148
+ pickrOptions.default = `#${randomColor.toString(16).padStart(6, '0')}`;
149
+ }
150
+ else if (currentDefault) {
151
+ pickrOptions.default = currentDefault;
152
+ }
153
+ }
154
+ this.pickr = Pickr.create(pickrOptions);
155
+ if (this.el.disabled)
156
+ this.pickr.disable();
157
+ this.pickr.on('save', (color, instance) => {
158
+ const hexa = color?.toHEXA().toString();
159
+ if (hexa) {
160
+ this.el.value = hexa;
161
+ this.el.dispatchEvent(new Event('change', { bubbles: true }));
162
+ }
163
+ instance.hide();
164
+ });
165
+ }
166
+ }