@vanduo-oss/framework 1.3.8 → 1.4.0
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 +87 -41
- package/css/components/affix.css +1 -1
- package/css/components/alerts.css +40 -40
- package/css/components/avatar.css +33 -33
- package/css/components/badges.css +42 -42
- package/css/components/breadcrumbs.css +5 -5
- package/css/components/bubble.css +4 -4
- package/css/components/buttons.css +124 -124
- package/css/components/cards.css +10 -10
- package/css/components/chips.css +28 -28
- package/css/components/code-snippet.css +18 -18
- package/css/components/collapsible.css +28 -20
- package/css/components/collections.css +21 -21
- package/css/components/datepicker.css +13 -13
- package/css/components/doc-search.css +46 -53
- package/css/components/doc-tabs.css +10 -10
- package/css/components/draggable.css +34 -34
- package/css/components/dropdown.css +14 -14
- package/css/components/expanding-cards.css +1 -1
- package/css/components/fab.css +7 -7
- package/css/components/flow.css +3 -3
- package/css/components/footer.css +26 -26
- package/css/components/forms.css +95 -83
- package/css/components/image-box.css +13 -17
- package/css/components/modals.css +8 -8
- package/css/components/music-player.css +26 -26
- package/css/components/navbar.css +27 -27
- package/css/components/pagination.css +15 -15
- package/css/components/preloader.css +10 -10
- package/css/components/progress.css +8 -8
- package/css/components/rating.css +4 -4
- package/css/components/sidenav.css +14 -14
- package/css/components/skeleton.css +10 -9
- package/css/components/spinner.css +10 -10
- package/css/components/spotlight.css +7 -7
- package/css/components/stepper.css +13 -13
- package/css/components/suggest.css +10 -10
- package/css/components/tabs.css +22 -22
- package/css/components/theme-customizer.css +87 -87
- package/css/components/timeline.css +14 -14
- package/css/components/timepicker.css +7 -7
- package/css/components/toast.css +31 -31
- package/css/components/tooltips.css +11 -11
- package/css/components/transfer.css +12 -12
- package/css/components/tree.css +9 -9
- package/css/components/waypoint.css +3 -3
- package/css/core/colors.css +61 -35
- package/css/core/grid.css +1 -6
- package/css/core/helpers.css +11 -11
- package/css/core/tokens.css +114 -36
- package/css/core/typography.css +15 -13
- package/css/core/vd-aliases.css +100 -52
- package/css/effects/morph.css +5 -5
- package/css/utilities/media.css +2 -2
- package/css/utilities/table.css +34 -34
- package/css/utilities/transitions.css +22 -10
- package/css/vanduo.css +14 -34
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +935 -294
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +7 -7
- package/dist/vanduo.cjs.min.js.map +3 -3
- package/dist/vanduo.css +7942 -7824
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +935 -294
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +7 -7
- package/dist/vanduo.esm.min.js.map +3 -3
- package/dist/vanduo.js +935 -294
- package/dist/vanduo.js.map +3 -3
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +7 -7
- package/dist/vanduo.min.js.map +3 -3
- package/js/components/affix.js +2 -2
- package/js/components/bubble.js +3 -3
- package/js/components/code-snippet.js +129 -5
- package/js/components/collapsible.js +2 -3
- package/js/components/datepicker.js +2 -2
- package/js/components/doc-search.js +69 -11
- package/js/components/draggable.js +4 -4
- package/js/components/dropdown.js +2 -3
- package/js/components/expanding-cards.js +2 -2
- package/js/components/flow.js +2 -2
- package/js/components/font-switcher.js +26 -16
- package/js/components/glass.js +2 -2
- package/js/components/grid.js +19 -8
- package/js/components/image-box.js +49 -10
- package/js/components/lazy-load.js +81 -9
- package/js/components/modals.js +28 -12
- package/js/components/morph.js +2 -2
- package/js/components/music-player.js +2 -2
- package/js/components/navbar.js +2 -2
- package/js/components/pagination.js +2 -3
- package/js/components/parallax.js +9 -10
- package/js/components/preloader.js +14 -5
- package/js/components/rating.js +2 -2
- package/js/components/ripple.js +2 -2
- package/js/components/select.js +2 -3
- package/js/components/sidenav.js +43 -14
- package/js/components/spotlight.js +2 -2
- package/js/components/stepper.js +2 -2
- package/js/components/suggest.js +9 -3
- package/js/components/tabs.js +2 -2
- package/js/components/theme-customizer.js +154 -23
- package/js/components/theme-switcher.js +27 -16
- package/js/components/timeline.js +41 -12
- package/js/components/timepicker.js +2 -2
- package/js/components/toast.js +1 -1
- package/js/components/tooltips.js +4 -4
- package/js/components/transfer.js +2 -2
- package/js/components/tree.js +2 -2
- package/js/components/validate.js +2 -2
- package/js/components/vd-hex.js +12 -6
- package/js/components/waypoint.js +2 -2
- package/js/utils/helpers.js +7 -4
- package/js/utils/lifecycle.js +158 -83
- package/js/vanduo.js +203 -34
- package/package.json +3 -4
package/js/components/suggest.js
CHANGED
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
const Suggest = {
|
|
37
37
|
instances: new Map(),
|
|
38
38
|
|
|
39
|
-
init: function () {
|
|
40
|
-
const inputs =
|
|
39
|
+
init: function (root) {
|
|
40
|
+
const inputs = window.Vanduo.queryAll(root, '[data-vd-suggest], [data-vd-autocomplete]');
|
|
41
41
|
inputs.forEach(el => {
|
|
42
42
|
if (this.instances.has(el)) return;
|
|
43
43
|
this.initInstance(el);
|
|
@@ -220,16 +220,22 @@
|
|
|
220
220
|
const blurHandler = () => {
|
|
221
221
|
setTimeout(close, 200);
|
|
222
222
|
};
|
|
223
|
+
const focusHandler = () => {
|
|
224
|
+
if (input.value.length >= minChars) {
|
|
225
|
+
doSearch(input.value);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
223
228
|
|
|
224
229
|
input.addEventListener('input', inputHandler);
|
|
225
230
|
input.addEventListener('keydown', keyHandler);
|
|
226
231
|
input.addEventListener('blur', blurHandler);
|
|
227
|
-
input.addEventListener('focus',
|
|
232
|
+
input.addEventListener('focus', focusHandler);
|
|
228
233
|
|
|
229
234
|
cleanup.push(
|
|
230
235
|
() => input.removeEventListener('input', inputHandler),
|
|
231
236
|
() => input.removeEventListener('keydown', keyHandler),
|
|
232
237
|
() => input.removeEventListener('blur', blurHandler),
|
|
238
|
+
() => input.removeEventListener('focus', focusHandler),
|
|
233
239
|
() => clearTimeout(debounceTimer),
|
|
234
240
|
() => { if (list.parentNode) list.parentNode.removeChild(list); }
|
|
235
241
|
);
|
package/js/components/tabs.js
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
/**
|
|
17
17
|
* Initialize all tab components
|
|
18
18
|
*/
|
|
19
|
-
init: function() {
|
|
20
|
-
const tabContainers =
|
|
19
|
+
init: function(root) {
|
|
20
|
+
const tabContainers = window.Vanduo.queryAll(root, '.vd-tabs, [data-tabs]');
|
|
21
21
|
|
|
22
22
|
tabContainers.forEach(container => {
|
|
23
23
|
if (this.instances.has(container)) {
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
DEFAULTS: {
|
|
22
22
|
PRIMARY_LIGHT: 'black',
|
|
23
23
|
PRIMARY_DARK: 'amber',
|
|
24
|
-
NEUTRAL: '
|
|
24
|
+
NEUTRAL: 'charcoal',
|
|
25
25
|
RADIUS: '0.5',
|
|
26
|
-
FONT: '
|
|
26
|
+
FONT: 'ubuntu',
|
|
27
27
|
THEME: 'system'
|
|
28
28
|
},
|
|
29
29
|
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
// Neutral color definitions
|
|
53
53
|
NEUTRAL_COLORS: {
|
|
54
|
+
'charcoal': { name: 'Charcoal', color: '#0d1117' },
|
|
54
55
|
'slate': { name: 'Slate', color: '#64748b' },
|
|
55
56
|
'gray': { name: 'Gray', color: '#6b7280' },
|
|
56
57
|
'zinc': { name: 'Zinc', color: '#71717a' },
|
|
@@ -85,23 +86,77 @@
|
|
|
85
86
|
|
|
86
87
|
isInitialized: false,
|
|
87
88
|
_cleanup: [],
|
|
89
|
+
_ownsDynamicPanel: false,
|
|
88
90
|
|
|
89
91
|
// DOM references
|
|
90
92
|
elements: {
|
|
91
93
|
customizer: null,
|
|
92
94
|
trigger: null,
|
|
95
|
+
activeTrigger: null,
|
|
93
96
|
triggers: [],
|
|
94
97
|
panel: null,
|
|
95
98
|
overlay: null
|
|
96
99
|
},
|
|
97
100
|
|
|
101
|
+
isRoot: function (root) {
|
|
102
|
+
return !!root && (root === document || root.nodeType === 1 || root.nodeType === 9 || root.nodeType === 11);
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
normalizeRoot: function (root) {
|
|
106
|
+
return this.isRoot(root) ? root : document;
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
queryAll: function (root, selector) {
|
|
110
|
+
const scope = this.normalizeRoot(root);
|
|
111
|
+
if (typeof window.VanduoLifecycle !== 'undefined' && typeof window.VanduoLifecycle.queryAll === 'function') {
|
|
112
|
+
return window.VanduoLifecycle.queryAll(scope, selector);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const matches = [];
|
|
116
|
+
if (scope instanceof Element && typeof scope.matches === 'function' && scope.matches(selector)) {
|
|
117
|
+
matches.push(scope);
|
|
118
|
+
}
|
|
119
|
+
if (typeof scope.querySelectorAll === 'function') {
|
|
120
|
+
const descendants = scope.querySelectorAll(selector);
|
|
121
|
+
for (let i = 0; i < descendants.length; i++) {
|
|
122
|
+
matches.push(descendants[i]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return matches;
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
queryOne: function (root, selector) {
|
|
129
|
+
const matches = this.queryAll(root, selector);
|
|
130
|
+
return matches.length ? matches[0] : null;
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
getTriggers: function (root) {
|
|
134
|
+
return this.queryAll(root, '[data-theme-customizer-trigger]');
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
pruneTriggers: function () {
|
|
138
|
+
this.elements.triggers = this.elements.triggers.filter(function (trigger) {
|
|
139
|
+
return trigger && trigger.isConnected;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (this.elements.trigger && !this.elements.trigger.isConnected) {
|
|
143
|
+
this.elements.trigger = null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (this.elements.activeTrigger && !this.elements.activeTrigger.isConnected) {
|
|
147
|
+
this.elements.activeTrigger = null;
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
|
|
98
151
|
/**
|
|
99
152
|
* Initialize the Theme Customizer
|
|
100
153
|
*/
|
|
101
|
-
init: function () {
|
|
154
|
+
init: function (root) {
|
|
155
|
+
const scope = this.normalizeRoot(root);
|
|
156
|
+
|
|
102
157
|
if (this.isInitialized) {
|
|
103
|
-
this.bindExistingElements();
|
|
104
|
-
this.bindTriggerEvents();
|
|
158
|
+
this.bindExistingElements(scope);
|
|
159
|
+
this.bindTriggerEvents(scope);
|
|
105
160
|
this.bindPanelEvents();
|
|
106
161
|
this.updateUI();
|
|
107
162
|
return;
|
|
@@ -112,10 +167,8 @@
|
|
|
112
167
|
|
|
113
168
|
this.loadPreferences();
|
|
114
169
|
this.applyAllPreferences();
|
|
115
|
-
this.bindExistingElements();
|
|
116
|
-
this.bindEvents();
|
|
117
|
-
|
|
118
|
-
console.log('Vanduo Theme Customizer initialized');
|
|
170
|
+
this.bindExistingElements(scope);
|
|
171
|
+
this.bindEvents(scope);
|
|
119
172
|
},
|
|
120
173
|
|
|
121
174
|
addListener: function (target, event, handler, options) {
|
|
@@ -314,21 +367,33 @@
|
|
|
314
367
|
/**
|
|
315
368
|
* Bind to existing DOM elements or create them dynamically
|
|
316
369
|
*/
|
|
317
|
-
bindExistingElements: function () {
|
|
318
|
-
|
|
319
|
-
this.
|
|
320
|
-
|
|
370
|
+
bindExistingElements: function (root) {
|
|
371
|
+
const scope = this.normalizeRoot(root);
|
|
372
|
+
this.pruneTriggers();
|
|
373
|
+
|
|
374
|
+
const scopedTriggers = this.getTriggers(scope);
|
|
375
|
+
scopedTriggers.forEach((trigger) => {
|
|
376
|
+
if (!this.elements.triggers.includes(trigger)) {
|
|
377
|
+
this.elements.triggers.push(trigger);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
|
|
321
381
|
if (!this.elements.trigger && this.elements.triggers.length) {
|
|
322
382
|
this.elements.trigger = this.elements.triggers[0];
|
|
323
383
|
}
|
|
324
384
|
|
|
325
|
-
|
|
385
|
+
const existingCustomizer = this.queryOne(scope, '.vd-theme-customizer')
|
|
386
|
+
|| (this.elements.customizer && typeof this.elements.customizer.contains === 'function' ? this.elements.customizer : null)
|
|
387
|
+
|| document.querySelector('.vd-theme-customizer');
|
|
388
|
+
|
|
389
|
+
if (existingCustomizer instanceof Element) {
|
|
390
|
+
this.elements.customizer = existingCustomizer;
|
|
326
391
|
this.elements.trigger = this.elements.customizer.querySelector('.vd-theme-customizer-trigger') || this.elements.trigger;
|
|
327
392
|
this.elements.panel = this.elements.customizer.querySelector('.vd-theme-customizer-panel');
|
|
328
393
|
this.elements.overlay = this.elements.customizer.querySelector('.vd-theme-customizer-overlay');
|
|
329
394
|
} else {
|
|
330
395
|
// Look for standalone trigger buttons with data attribute
|
|
331
|
-
if (this.elements.
|
|
396
|
+
if (scopedTriggers.length && !this.elements.panel) {
|
|
332
397
|
this.createDynamicPanel();
|
|
333
398
|
}
|
|
334
399
|
}
|
|
@@ -341,7 +406,7 @@
|
|
|
341
406
|
* Create the panel dynamically when only a trigger button exists
|
|
342
407
|
*/
|
|
343
408
|
createDynamicPanel: function () {
|
|
344
|
-
if (!this.elements.triggers.length) {
|
|
409
|
+
if (!this.elements.triggers.length || (this.elements.panel && this.elements.panel.isConnected)) {
|
|
345
410
|
return;
|
|
346
411
|
}
|
|
347
412
|
this.elements.trigger = this.elements.triggers[0];
|
|
@@ -362,6 +427,7 @@
|
|
|
362
427
|
// Store references
|
|
363
428
|
this.elements.panel = panel;
|
|
364
429
|
this.elements.overlay = overlay;
|
|
430
|
+
this._ownsDynamicPanel = true;
|
|
365
431
|
this.elements.customizer = {
|
|
366
432
|
contains: (el) => panel.contains(el) || this.elements.triggers.some((trigger) => trigger.contains(el))
|
|
367
433
|
};
|
|
@@ -594,8 +660,8 @@
|
|
|
594
660
|
}
|
|
595
661
|
},
|
|
596
662
|
|
|
597
|
-
bindEvents: function () {
|
|
598
|
-
this.bindTriggerEvents();
|
|
663
|
+
bindEvents: function (root) {
|
|
664
|
+
this.bindTriggerEvents(root);
|
|
599
665
|
|
|
600
666
|
this.bindPanelEvents();
|
|
601
667
|
|
|
@@ -630,22 +696,53 @@
|
|
|
630
696
|
});
|
|
631
697
|
},
|
|
632
698
|
|
|
633
|
-
bindTriggerEvents: function () {
|
|
634
|
-
this.
|
|
699
|
+
bindTriggerEvents: function (root) {
|
|
700
|
+
const triggers = root ? this.getTriggers(root) : this.elements.triggers;
|
|
701
|
+
triggers.forEach((trigger) => {
|
|
635
702
|
if (trigger.getAttribute('data-customizer-trigger-initialized') === 'true') {
|
|
636
703
|
return;
|
|
637
704
|
}
|
|
638
|
-
|
|
705
|
+
|
|
706
|
+
const onClick = (e) => {
|
|
639
707
|
e.preventDefault();
|
|
640
708
|
e.stopPropagation();
|
|
641
709
|
this.elements.activeTrigger = trigger;
|
|
642
710
|
this.elements.trigger = trigger;
|
|
643
711
|
this.toggle();
|
|
644
|
-
}
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
trigger.addEventListener('click', onClick);
|
|
715
|
+
trigger._themeCustomizerTriggerHandler = onClick;
|
|
645
716
|
trigger.setAttribute('data-customizer-trigger-initialized', 'true');
|
|
646
717
|
});
|
|
647
718
|
},
|
|
648
719
|
|
|
720
|
+
cleanupTrigger: function (trigger) {
|
|
721
|
+
if (!trigger || trigger.getAttribute('data-customizer-trigger-initialized') !== 'true') {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (trigger._themeCustomizerTriggerHandler) {
|
|
726
|
+
trigger.removeEventListener('click', trigger._themeCustomizerTriggerHandler);
|
|
727
|
+
delete trigger._themeCustomizerTriggerHandler;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
731
|
+
trigger.removeAttribute('data-customizer-trigger-initialized');
|
|
732
|
+
|
|
733
|
+
if (this.elements.activeTrigger === trigger) {
|
|
734
|
+
this.elements.activeTrigger = null;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
this.elements.triggers = this.elements.triggers.filter(function (candidate) {
|
|
738
|
+
return candidate !== trigger;
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
if (this.elements.trigger === trigger) {
|
|
742
|
+
this.elements.trigger = this.elements.triggers[0] || null;
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
|
|
649
746
|
/**
|
|
650
747
|
* Toggle panel open/close
|
|
651
748
|
*/
|
|
@@ -781,7 +878,21 @@
|
|
|
781
878
|
}
|
|
782
879
|
},
|
|
783
880
|
|
|
784
|
-
destroyAll: function () {
|
|
881
|
+
destroyAll: function (root) {
|
|
882
|
+
const scope = this.normalizeRoot(root);
|
|
883
|
+
|
|
884
|
+
if (scope !== document) {
|
|
885
|
+
this.getTriggers(scope).forEach((trigger) => {
|
|
886
|
+
this.cleanupTrigger(trigger);
|
|
887
|
+
});
|
|
888
|
+
this.pruneTriggers();
|
|
889
|
+
|
|
890
|
+
if (!this.elements.triggers.length) {
|
|
891
|
+
this.destroyAll(document);
|
|
892
|
+
}
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
|
|
785
896
|
this._cleanup.forEach(fn => fn());
|
|
786
897
|
this._cleanup = [];
|
|
787
898
|
|
|
@@ -789,7 +900,27 @@
|
|
|
789
900
|
this.elements.panel.removeAttribute('data-customizer-initialized');
|
|
790
901
|
}
|
|
791
902
|
|
|
903
|
+
this.elements.triggers.slice().forEach((trigger) => {
|
|
904
|
+
this.cleanupTrigger(trigger);
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
if (this._ownsDynamicPanel) {
|
|
908
|
+
if (this.elements.panel && this.elements.panel.parentNode) {
|
|
909
|
+
this.elements.panel.parentNode.removeChild(this.elements.panel);
|
|
910
|
+
}
|
|
911
|
+
if (this.elements.overlay && this.elements.overlay.parentNode) {
|
|
912
|
+
this.elements.overlay.parentNode.removeChild(this.elements.overlay);
|
|
913
|
+
}
|
|
914
|
+
this._ownsDynamicPanel = false;
|
|
915
|
+
}
|
|
916
|
+
|
|
792
917
|
this.close();
|
|
918
|
+
this.elements.customizer = null;
|
|
919
|
+
this.elements.trigger = null;
|
|
920
|
+
this.elements.activeTrigger = null;
|
|
921
|
+
this.elements.triggers = [];
|
|
922
|
+
this.elements.panel = null;
|
|
923
|
+
this.elements.overlay = null;
|
|
793
924
|
this.isInitialized = false;
|
|
794
925
|
}
|
|
795
926
|
};
|
|
@@ -11,7 +11,15 @@
|
|
|
11
11
|
_mediaQuery: null,
|
|
12
12
|
_onMediaChange: null,
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
getToggles: function (root) {
|
|
15
|
+
if (window.Vanduo && typeof window.Vanduo.queryAll === 'function') {
|
|
16
|
+
return window.Vanduo.queryAll(root, '[data-toggle="theme"]');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return Array.from(document.querySelectorAll('[data-toggle="theme"]'));
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
init: function (root) {
|
|
15
23
|
this.STORAGE_KEY = 'vanduo-theme-preference';
|
|
16
24
|
this.state = {
|
|
17
25
|
preference: this.getPreference() // 'light', 'dark', or 'system'
|
|
@@ -19,8 +27,8 @@
|
|
|
19
27
|
|
|
20
28
|
if (this.isInitialized) {
|
|
21
29
|
this.applyTheme();
|
|
22
|
-
this.renderUI();
|
|
23
|
-
this.updateUI();
|
|
30
|
+
this.renderUI(root);
|
|
31
|
+
this.updateUI(root);
|
|
24
32
|
return;
|
|
25
33
|
}
|
|
26
34
|
|
|
@@ -28,9 +36,7 @@
|
|
|
28
36
|
|
|
29
37
|
this.applyTheme();
|
|
30
38
|
this.listenForSystemChanges();
|
|
31
|
-
this.renderUI();
|
|
32
|
-
|
|
33
|
-
console.log('Vanduo Theme Switcher initialized');
|
|
39
|
+
this.renderUI(root);
|
|
34
40
|
},
|
|
35
41
|
|
|
36
42
|
getPreference: function () {
|
|
@@ -113,9 +119,9 @@
|
|
|
113
119
|
},
|
|
114
120
|
|
|
115
121
|
// Helper to facilitate UI creation if needed, though often UI is in HTML
|
|
116
|
-
renderUI: function () {
|
|
122
|
+
renderUI: function (root) {
|
|
117
123
|
// Look for any uninitialized theme toggles
|
|
118
|
-
const toggles =
|
|
124
|
+
const toggles = this.getToggles(root);
|
|
119
125
|
toggles.forEach(toggle => {
|
|
120
126
|
if (toggle.getAttribute('data-theme-initialized') === 'true') {
|
|
121
127
|
if (toggle.tagName === 'SELECT') {
|
|
@@ -147,8 +153,8 @@
|
|
|
147
153
|
});
|
|
148
154
|
},
|
|
149
155
|
|
|
150
|
-
updateUI: function () {
|
|
151
|
-
const toggles =
|
|
156
|
+
updateUI: function (root) {
|
|
157
|
+
const toggles = this.getToggles(root);
|
|
152
158
|
toggles.forEach(toggle => {
|
|
153
159
|
if (toggle.tagName === 'SELECT') {
|
|
154
160
|
toggle.value = this.state.preference;
|
|
@@ -166,8 +172,11 @@
|
|
|
166
172
|
});
|
|
167
173
|
},
|
|
168
174
|
|
|
169
|
-
destroyAll: function () {
|
|
170
|
-
const
|
|
175
|
+
destroyAll: function (root) {
|
|
176
|
+
const scope = root || document;
|
|
177
|
+
const toggles = this.getToggles(scope).filter(function (toggle) {
|
|
178
|
+
return toggle.getAttribute('data-theme-initialized') === 'true';
|
|
179
|
+
});
|
|
171
180
|
toggles.forEach(toggle => {
|
|
172
181
|
if (toggle._themeToggleHandler) {
|
|
173
182
|
const eventName = toggle.tagName === 'SELECT' ? 'change' : 'click';
|
|
@@ -177,13 +186,15 @@
|
|
|
177
186
|
toggle.removeAttribute('data-theme-initialized');
|
|
178
187
|
});
|
|
179
188
|
|
|
180
|
-
if (this._mediaQuery && this._onMediaChange) {
|
|
189
|
+
if (scope === document && this._mediaQuery && this._onMediaChange) {
|
|
181
190
|
this._mediaQuery.removeEventListener('change', this._onMediaChange);
|
|
182
191
|
}
|
|
183
192
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
193
|
+
if (scope === document) {
|
|
194
|
+
this._mediaQuery = null;
|
|
195
|
+
this._onMediaChange = null;
|
|
196
|
+
this.isInitialized = false;
|
|
197
|
+
}
|
|
187
198
|
}
|
|
188
199
|
};
|
|
189
200
|
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
const pauseBtn = scope.querySelector('[data-vd-timeline-pause]');
|
|
38
38
|
|
|
39
39
|
let playTimer = null;
|
|
40
|
+
let isPlaying = false;
|
|
41
|
+
let playToken = 0;
|
|
40
42
|
|
|
41
43
|
function updateNavButtons() {
|
|
42
44
|
const k = countRevealedPrefix(items);
|
|
@@ -52,10 +54,10 @@
|
|
|
52
54
|
nextBtn.setAttribute('aria-disabled', atEnd ? 'true' : 'false');
|
|
53
55
|
}
|
|
54
56
|
if (playBtn) {
|
|
55
|
-
playBtn.setAttribute('aria-pressed',
|
|
57
|
+
playBtn.setAttribute('aria-pressed', isPlaying ? 'true' : 'false');
|
|
56
58
|
}
|
|
57
59
|
if (pauseBtn) {
|
|
58
|
-
pauseBtn.disabled = !
|
|
60
|
+
pauseBtn.disabled = !isPlaying;
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
@@ -75,21 +77,43 @@
|
|
|
75
77
|
updateNavButtons();
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
playTimer =
|
|
80
|
+
function scheduleNext() {
|
|
81
|
+
const token = ++playToken;
|
|
82
|
+
playTimer = setTimeout(function () {
|
|
83
|
+
playTimer = null;
|
|
84
|
+
|
|
85
|
+
if (!isPlaying || token !== playToken) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
81
89
|
if (countRevealedPrefix(items) >= items.length) {
|
|
82
90
|
pause();
|
|
83
91
|
return;
|
|
84
92
|
}
|
|
93
|
+
|
|
85
94
|
stepNext();
|
|
95
|
+
|
|
96
|
+
if (countRevealedPrefix(items) >= items.length) {
|
|
97
|
+
pause();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
scheduleNext();
|
|
86
102
|
}, PLAY_INTERVAL_MS);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function play() {
|
|
106
|
+
if (isPlaying) return;
|
|
107
|
+
isPlaying = true;
|
|
108
|
+
scheduleNext();
|
|
87
109
|
updateNavButtons();
|
|
88
110
|
}
|
|
89
111
|
|
|
90
112
|
function pause() {
|
|
113
|
+
isPlaying = false;
|
|
114
|
+
playToken++;
|
|
91
115
|
if (playTimer) {
|
|
92
|
-
|
|
116
|
+
clearTimeout(playTimer);
|
|
93
117
|
playTimer = null;
|
|
94
118
|
}
|
|
95
119
|
updateNavButtons();
|
|
@@ -129,16 +153,16 @@
|
|
|
129
153
|
const Timeline = {
|
|
130
154
|
instances: new Map(),
|
|
131
155
|
|
|
132
|
-
init: function () {
|
|
133
|
-
|
|
156
|
+
init: function (root) {
|
|
157
|
+
window.Vanduo.queryAll(root, '.vd-timeline.vd-timeline-animated').forEach(function (el) {
|
|
134
158
|
if (Timeline.instances.has(el)) return;
|
|
135
159
|
Timeline.initInstance(el);
|
|
136
160
|
});
|
|
137
161
|
},
|
|
138
162
|
|
|
139
|
-
reinit: function () {
|
|
140
|
-
Timeline.destroyAll();
|
|
141
|
-
Timeline.init();
|
|
163
|
+
reinit: function (root) {
|
|
164
|
+
Timeline.destroyAll(root);
|
|
165
|
+
Timeline.init(root);
|
|
142
166
|
},
|
|
143
167
|
|
|
144
168
|
initInstance: function (container) {
|
|
@@ -211,8 +235,13 @@
|
|
|
211
235
|
this.instances.delete(container);
|
|
212
236
|
},
|
|
213
237
|
|
|
214
|
-
destroyAll: function () {
|
|
238
|
+
destroyAll: function (root) {
|
|
239
|
+
const scope = window.Vanduo && typeof window.Vanduo._normalizeRoot === 'function'
|
|
240
|
+
? window.Vanduo._normalizeRoot(root)
|
|
241
|
+
: document;
|
|
242
|
+
|
|
215
243
|
this.instances.forEach(function (_, el) {
|
|
244
|
+
if (scope !== document && scope !== el && (!scope.contains || !scope.contains(el))) return;
|
|
216
245
|
Timeline.destroy(el);
|
|
217
246
|
});
|
|
218
247
|
}
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Timepicker = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const inputs =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const inputs = window.Vanduo.queryAll(root, '[data-vd-timepicker]');
|
|
14
14
|
inputs.forEach(el => {
|
|
15
15
|
if (this.instances.has(el)) return;
|
|
16
16
|
this.initInstance(el);
|
package/js/components/toast.js
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
if (config.icon) {
|
|
95
95
|
const allowSvg = config.iconAllowSvg === true;
|
|
96
96
|
const safeIcon = typeof sanitizeHtml === 'function'
|
|
97
|
-
? sanitizeHtml(config.icon, { allowSvg })
|
|
97
|
+
? sanitizeHtml(config.icon, { allowSvg, allowStyle: false })
|
|
98
98
|
: escapeHtml(config.icon);
|
|
99
99
|
html += `<span class="vd-toast-icon">${safeIcon}</span>`;
|
|
100
100
|
} else if (config.type) {
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
/**
|
|
32
32
|
* Initialize tooltips
|
|
33
33
|
*/
|
|
34
|
-
init: function () {
|
|
35
|
-
const elements =
|
|
34
|
+
init: function (root) {
|
|
35
|
+
const elements = window.Vanduo.queryAll(root, '[data-tooltip], [data-tooltip-html]');
|
|
36
36
|
|
|
37
37
|
elements.forEach(element => {
|
|
38
38
|
if (this.tooltips.has(element)) {
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
|
|
94
94
|
if (htmlContent) {
|
|
95
95
|
const allowSvg = element.hasAttribute('data-tooltip-allow-svg');
|
|
96
|
-
tooltip.innerHTML = this.sanitizeHtml(htmlContent, { allowSvg });
|
|
96
|
+
tooltip.innerHTML = this.sanitizeHtml(htmlContent, { allowSvg, allowStyle: false });
|
|
97
97
|
tooltip.classList.add('vd-tooltip-html');
|
|
98
98
|
} else if (textContent) {
|
|
99
99
|
tooltip.textContent = textContent;
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
const { tooltip } = this.tooltips.get(el);
|
|
254
254
|
if (isHtml) {
|
|
255
255
|
const allowSvg = el.hasAttribute('data-tooltip-allow-svg');
|
|
256
|
-
tooltip.innerHTML = this.sanitizeHtml(content, { allowSvg });
|
|
256
|
+
tooltip.innerHTML = this.sanitizeHtml(content, { allowSvg, allowStyle: false });
|
|
257
257
|
tooltip.classList.add('vd-tooltip-html');
|
|
258
258
|
} else {
|
|
259
259
|
tooltip.textContent = content;
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Transfer = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const transfers =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const transfers = window.Vanduo.queryAll(root, '[data-vd-transfer]');
|
|
14
14
|
transfers.forEach(el => {
|
|
15
15
|
if (this.instances.has(el)) return;
|
|
16
16
|
this.initInstance(el);
|
package/js/components/tree.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Tree = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const trees =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const trees = window.Vanduo.queryAll(root, '[data-vd-tree]');
|
|
14
14
|
trees.forEach(el => {
|
|
15
15
|
if (this.instances.has(el)) return;
|
|
16
16
|
this.initInstance(el);
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
match: 'Fields do not match'
|
|
50
50
|
},
|
|
51
51
|
|
|
52
|
-
init: function () {
|
|
53
|
-
const forms =
|
|
52
|
+
init: function (root) {
|
|
53
|
+
const forms = window.Vanduo.queryAll(root, '[data-vd-validate], .vd-validate');
|
|
54
54
|
forms.forEach(form => {
|
|
55
55
|
if (this.instances.has(form)) return;
|
|
56
56
|
this.initInstance(form);
|
package/js/components/vd-hex.js
CHANGED
|
@@ -90,13 +90,19 @@ export class VdHexGrid {
|
|
|
90
90
|
const root = document.documentElement;
|
|
91
91
|
const style = getComputedStyle(root);
|
|
92
92
|
|
|
93
|
+
const readToken = (canonical, fallback, defaultValue) => {
|
|
94
|
+
return style.getPropertyValue(canonical).trim()
|
|
95
|
+
|| style.getPropertyValue(fallback).trim()
|
|
96
|
+
|| defaultValue;
|
|
97
|
+
};
|
|
98
|
+
|
|
93
99
|
return {
|
|
94
|
-
bgPrimary:
|
|
95
|
-
bgSecondary:
|
|
96
|
-
borderColor:
|
|
97
|
-
colorPrimary:
|
|
98
|
-
textColor:
|
|
99
|
-
textMuted:
|
|
100
|
+
bgPrimary: readToken('--vd-bg-primary', '--bg-primary', '#ffffff'),
|
|
101
|
+
bgSecondary: readToken('--vd-bg-secondary', '--bg-secondary', '#f5f5f5'),
|
|
102
|
+
borderColor: readToken('--vd-border-color', '--border-color', '#e0e0e0'),
|
|
103
|
+
colorPrimary: readToken('--vd-color-primary', '--color-primary', '#3b82f6'),
|
|
104
|
+
textColor: readToken('--vd-text-primary', '--text-primary', '#1f2937'),
|
|
105
|
+
textMuted: readToken('--vd-text-muted', '--text-muted', '#6b7280')
|
|
100
106
|
};
|
|
101
107
|
}
|
|
102
108
|
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Waypoint = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const navs =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const navs = window.Vanduo.queryAll(root, '[data-vd-waypoint-nav], [data-vd-scrollspy-nav]');
|
|
14
14
|
navs.forEach(nav => {
|
|
15
15
|
if (this.instances.has(nav)) return;
|
|
16
16
|
this.initInstance(nav);
|