@vanduo-oss/framework 1.3.9 → 1.4.1
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 +89 -42
- package/css/components/affix.css +12 -12
- package/css/components/alerts.css +70 -70
- package/css/components/avatar.css +78 -78
- package/css/components/badges.css +67 -67
- package/css/components/breadcrumbs.css +32 -32
- package/css/components/bubble.css +40 -40
- package/css/components/button-group.css +2 -2
- package/css/components/buttons.css +157 -157
- package/css/components/cards.css +79 -79
- package/css/components/chips.css +50 -50
- package/css/components/code-snippet.css +132 -132
- package/css/components/collapsible.css +67 -67
- package/css/components/collections.css +68 -68
- package/css/components/datepicker.css +54 -54
- package/css/components/doc-search.css +96 -103
- package/css/components/doc-tabs.css +11 -11
- package/css/components/draggable.css +77 -77
- package/css/components/dropdown.css +50 -50
- package/css/components/expanding-cards.css +1 -1
- package/css/components/fab.css +61 -61
- package/css/components/flow.css +55 -55
- package/css/components/footer.css +62 -62
- package/css/components/forms.css +437 -425
- package/css/components/image-box.css +50 -54
- package/css/components/modals.css +51 -51
- package/css/components/music-player.css +150 -150
- package/css/components/navbar.css +80 -80
- package/css/components/pagination.css +51 -51
- package/css/components/preloader.css +19 -19
- package/css/components/progress.css +20 -20
- package/css/components/rating.css +19 -19
- package/css/components/ripple.css +10 -10
- package/css/components/sidenav.css +72 -72
- package/css/components/skeleton.css +17 -16
- package/css/components/spinner.css +33 -33
- package/css/components/spotlight.css +33 -33
- package/css/components/stepper.css +39 -39
- package/css/components/suggest.css +37 -37
- package/css/components/tabs.css +60 -60
- package/css/components/theme-customizer.css +154 -154
- package/css/components/timeline.css +50 -50
- package/css/components/timepicker.css +29 -29
- package/css/components/toast.css +53 -53
- package/css/components/tooltips.css +78 -78
- package/css/components/transfer.css +37 -37
- package/css/components/tree.css +28 -28
- package/css/components/waypoint.css +12 -12
- package/css/core/colors.css +640 -640
- package/css/core/grid.css +127 -132
- package/css/core/helpers.css +349 -349
- package/css/core/tokens.css +133 -67
- package/css/core/typography.css +105 -103
- package/css/effects/morph.css +21 -21
- package/css/effects/parallax.css +6 -6
- package/css/utilities/color-utilities.css +273 -273
- package/css/utilities/media.css +4 -4
- package/css/utilities/shadow.css +75 -75
- package/css/utilities/table.css +64 -64
- package/css/utilities/transitions.css +53 -41
- package/css/vanduo.css +14 -35
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +947 -307
- 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 +9650 -9656
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +947 -307
- 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 +947 -307
- 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 +4 -4
- 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 +23 -13
- package/js/components/glass.js +2 -2
- package/js/components/grid.js +19 -8
- package/js/components/image-box.js +51 -12
- package/js/components/lazy-load.js +81 -9
- package/js/components/modals.js +28 -12
- package/js/components/morph.js +3 -3
- package/js/components/music-player.js +13 -13
- package/js/components/navbar.js +3 -3
- package/js/components/pagination.js +2 -3
- package/js/components/parallax.js +9 -10
- package/js/components/preloader.js +15 -6
- 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 +155 -25
- 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 +10 -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 +2 -1
- package/css/core/vd-aliases.css +0 -60
package/js/components/sidenav.js
CHANGED
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
sidenavs: new Map(),
|
|
14
14
|
breakpoint: 992, // Desktop breakpoint
|
|
15
15
|
restoreDelayMs: 450,
|
|
16
|
+
__vanduoScopedDestroyAll: true,
|
|
16
17
|
|
|
17
18
|
// Global cleanup functions (toggles, resize)
|
|
18
19
|
_globalCleanups: [],
|
|
20
|
+
_resizeCleanup: null,
|
|
19
21
|
|
|
20
22
|
isFixedVariant: function(sidenav) {
|
|
21
23
|
return sidenav.classList.contains('vd-sidenav-fixed') || sidenav.classList.contains('sidenav-fixed');
|
|
@@ -140,8 +142,8 @@
|
|
|
140
142
|
/**
|
|
141
143
|
* Initialize sidenav components
|
|
142
144
|
*/
|
|
143
|
-
init: function() {
|
|
144
|
-
const sidenavs =
|
|
145
|
+
init: function(root) {
|
|
146
|
+
const sidenavs = window.Vanduo.queryAll(root, '.vd-sidenav, .vd-offcanvas');
|
|
145
147
|
|
|
146
148
|
sidenavs.forEach(sidenav => {
|
|
147
149
|
if (this.sidenavs.has(sidenav)) {
|
|
@@ -151,7 +153,9 @@
|
|
|
151
153
|
});
|
|
152
154
|
|
|
153
155
|
// Handle toggle buttons
|
|
154
|
-
const toggles =
|
|
156
|
+
const toggles = window.Vanduo && typeof window.Vanduo.queryAll === 'function'
|
|
157
|
+
? window.Vanduo.queryAll(root, '[data-sidenav-toggle]')
|
|
158
|
+
: document.querySelectorAll('[data-sidenav-toggle]');
|
|
155
159
|
toggles.forEach(toggle => {
|
|
156
160
|
if (toggle.dataset.sidenavToggleInitialized) return;
|
|
157
161
|
toggle.dataset.sidenavToggleInitialized = 'true';
|
|
@@ -165,16 +169,18 @@
|
|
|
165
169
|
}
|
|
166
170
|
};
|
|
167
171
|
toggle.addEventListener('click', toggleClickHandler);
|
|
168
|
-
|
|
172
|
+
toggle._sidenavToggleCleanup = () => toggle.removeEventListener('click', toggleClickHandler);
|
|
169
173
|
});
|
|
170
174
|
|
|
171
175
|
// Handle responsive behavior
|
|
172
176
|
this.handleResize();
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
177
|
+
if (!this._resizeCleanup) {
|
|
178
|
+
const resizeHandler = () => {
|
|
179
|
+
this.handleResize();
|
|
180
|
+
};
|
|
181
|
+
window.addEventListener('resize', resizeHandler);
|
|
182
|
+
this._resizeCleanup = () => window.removeEventListener('resize', resizeHandler);
|
|
183
|
+
}
|
|
178
184
|
},
|
|
179
185
|
|
|
180
186
|
/**
|
|
@@ -406,12 +412,36 @@
|
|
|
406
412
|
/**
|
|
407
413
|
* Destroy all sidenav instances
|
|
408
414
|
*/
|
|
409
|
-
destroyAll: function() {
|
|
415
|
+
destroyAll: function(root) {
|
|
416
|
+
const scope = window.Vanduo && typeof window.Vanduo._normalizeRoot === 'function'
|
|
417
|
+
? window.Vanduo._normalizeRoot(root)
|
|
418
|
+
: (root || document);
|
|
419
|
+
|
|
410
420
|
this.sidenavs.forEach((data, sidenav) => {
|
|
411
|
-
|
|
421
|
+
if (scope === document || scope === sidenav || (typeof scope.contains === 'function' && scope.contains(sidenav))) {
|
|
422
|
+
this.destroy(sidenav);
|
|
423
|
+
}
|
|
412
424
|
});
|
|
413
|
-
|
|
414
|
-
|
|
425
|
+
|
|
426
|
+
const toggles = window.Vanduo && typeof window.Vanduo.queryAll === 'function'
|
|
427
|
+
? window.Vanduo.queryAll(scope, '[data-sidenav-toggle][data-sidenav-toggle-initialized]')
|
|
428
|
+
: document.querySelectorAll('[data-sidenav-toggle][data-sidenav-toggle-initialized]');
|
|
429
|
+
toggles.forEach(toggle => {
|
|
430
|
+
if (toggle._sidenavToggleCleanup) {
|
|
431
|
+
toggle._sidenavToggleCleanup();
|
|
432
|
+
delete toggle._sidenavToggleCleanup;
|
|
433
|
+
}
|
|
434
|
+
delete toggle.dataset.sidenavToggleInitialized;
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
if (scope === document) {
|
|
438
|
+
if (this._resizeCleanup) {
|
|
439
|
+
this._resizeCleanup();
|
|
440
|
+
this._resizeCleanup = null;
|
|
441
|
+
}
|
|
442
|
+
this._globalCleanups.forEach(fn => fn());
|
|
443
|
+
this._globalCleanups = [];
|
|
444
|
+
}
|
|
415
445
|
}
|
|
416
446
|
};
|
|
417
447
|
|
|
@@ -424,4 +454,3 @@
|
|
|
424
454
|
window.VanduoSidenav = Sidenav;
|
|
425
455
|
|
|
426
456
|
})();
|
|
427
|
-
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
_boundTriggers: new WeakMap(),
|
|
16
16
|
_triggerElement: null,
|
|
17
17
|
|
|
18
|
-
init: function () {
|
|
19
|
-
const triggers =
|
|
18
|
+
init: function (root) {
|
|
19
|
+
const triggers = window.Vanduo.queryAll(root, '[data-vd-spotlight]');
|
|
20
20
|
|
|
21
21
|
triggers.forEach(trigger => {
|
|
22
22
|
if (this._boundTriggers.has(trigger)) return;
|
package/js/components/stepper.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Stepper = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const steppers =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const steppers = window.Vanduo.queryAll(root, '.vd-stepper');
|
|
14
14
|
steppers.forEach(el => {
|
|
15
15
|
if (this.instances.has(el)) return;
|
|
16
16
|
this.initInstance(el);
|
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)) {
|
|
@@ -86,23 +86,77 @@
|
|
|
86
86
|
|
|
87
87
|
isInitialized: false,
|
|
88
88
|
_cleanup: [],
|
|
89
|
+
_ownsDynamicPanel: false,
|
|
89
90
|
|
|
90
91
|
// DOM references
|
|
91
92
|
elements: {
|
|
92
93
|
customizer: null,
|
|
93
94
|
trigger: null,
|
|
95
|
+
activeTrigger: null,
|
|
94
96
|
triggers: [],
|
|
95
97
|
panel: null,
|
|
96
98
|
overlay: null
|
|
97
99
|
},
|
|
98
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
|
+
|
|
99
151
|
/**
|
|
100
152
|
* Initialize the Theme Customizer
|
|
101
153
|
*/
|
|
102
|
-
init: function () {
|
|
154
|
+
init: function (root) {
|
|
155
|
+
const scope = this.normalizeRoot(root);
|
|
156
|
+
|
|
103
157
|
if (this.isInitialized) {
|
|
104
|
-
this.bindExistingElements();
|
|
105
|
-
this.bindTriggerEvents();
|
|
158
|
+
this.bindExistingElements(scope);
|
|
159
|
+
this.bindTriggerEvents(scope);
|
|
106
160
|
this.bindPanelEvents();
|
|
107
161
|
this.updateUI();
|
|
108
162
|
return;
|
|
@@ -113,10 +167,8 @@
|
|
|
113
167
|
|
|
114
168
|
this.loadPreferences();
|
|
115
169
|
this.applyAllPreferences();
|
|
116
|
-
this.bindExistingElements();
|
|
117
|
-
this.bindEvents();
|
|
118
|
-
|
|
119
|
-
console.log('Vanduo Theme Customizer initialized');
|
|
170
|
+
this.bindExistingElements(scope);
|
|
171
|
+
this.bindEvents(scope);
|
|
120
172
|
},
|
|
121
173
|
|
|
122
174
|
addListener: function (target, event, handler, options) {
|
|
@@ -208,7 +260,7 @@
|
|
|
208
260
|
|
|
209
261
|
this.state.radius = radius;
|
|
210
262
|
document.documentElement.setAttribute('data-radius', radius);
|
|
211
|
-
document.documentElement.style.setProperty('--radius-scale', radius);
|
|
263
|
+
document.documentElement.style.setProperty('--vd-radius-scale', radius);
|
|
212
264
|
this.savePreference(this.STORAGE_KEYS.RADIUS, radius);
|
|
213
265
|
|
|
214
266
|
this.dispatchEvent('radius-change', { radius: radius });
|
|
@@ -315,21 +367,33 @@
|
|
|
315
367
|
/**
|
|
316
368
|
* Bind to existing DOM elements or create them dynamically
|
|
317
369
|
*/
|
|
318
|
-
bindExistingElements: function () {
|
|
319
|
-
|
|
320
|
-
this.
|
|
321
|
-
|
|
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
|
+
|
|
322
381
|
if (!this.elements.trigger && this.elements.triggers.length) {
|
|
323
382
|
this.elements.trigger = this.elements.triggers[0];
|
|
324
383
|
}
|
|
325
384
|
|
|
326
|
-
|
|
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;
|
|
327
391
|
this.elements.trigger = this.elements.customizer.querySelector('.vd-theme-customizer-trigger') || this.elements.trigger;
|
|
328
392
|
this.elements.panel = this.elements.customizer.querySelector('.vd-theme-customizer-panel');
|
|
329
393
|
this.elements.overlay = this.elements.customizer.querySelector('.vd-theme-customizer-overlay');
|
|
330
394
|
} else {
|
|
331
395
|
// Look for standalone trigger buttons with data attribute
|
|
332
|
-
if (this.elements.
|
|
396
|
+
if (scopedTriggers.length && !this.elements.panel) {
|
|
333
397
|
this.createDynamicPanel();
|
|
334
398
|
}
|
|
335
399
|
}
|
|
@@ -342,7 +406,7 @@
|
|
|
342
406
|
* Create the panel dynamically when only a trigger button exists
|
|
343
407
|
*/
|
|
344
408
|
createDynamicPanel: function () {
|
|
345
|
-
if (!this.elements.triggers.length) {
|
|
409
|
+
if (!this.elements.triggers.length || (this.elements.panel && this.elements.panel.isConnected)) {
|
|
346
410
|
return;
|
|
347
411
|
}
|
|
348
412
|
this.elements.trigger = this.elements.triggers[0];
|
|
@@ -363,6 +427,7 @@
|
|
|
363
427
|
// Store references
|
|
364
428
|
this.elements.panel = panel;
|
|
365
429
|
this.elements.overlay = overlay;
|
|
430
|
+
this._ownsDynamicPanel = true;
|
|
366
431
|
this.elements.customizer = {
|
|
367
432
|
contains: (el) => panel.contains(el) || this.elements.triggers.some((trigger) => trigger.contains(el))
|
|
368
433
|
};
|
|
@@ -396,7 +461,7 @@
|
|
|
396
461
|
} else {
|
|
397
462
|
// Desktop: position directly below the trigger button, aligned to its right edge
|
|
398
463
|
const triggerRect = anchorTrigger.getBoundingClientRect();
|
|
399
|
-
const panelWidth = 320; // --customizer-width
|
|
464
|
+
const panelWidth = 320; // --vd-customizer-width
|
|
400
465
|
const panelTop = triggerRect.bottom + 8;
|
|
401
466
|
|
|
402
467
|
// Calculate right position: align panel's right edge with trigger's right edge
|
|
@@ -507,13 +572,13 @@
|
|
|
507
572
|
// Generate primary color swatches
|
|
508
573
|
let primarySwatches = '';
|
|
509
574
|
for (const [key, value] of Object.entries(this.PRIMARY_COLORS)) {
|
|
510
|
-
primarySwatches += `<button class="tc-color-swatch${key === this.state.primary ? ' is-active' : ''}" data-color="${esc(key)}" style="--swatch-color: ${safeColor(value.color)}" title="${esc(value.name)}"></button>`;
|
|
575
|
+
primarySwatches += `<button class="tc-color-swatch${key === this.state.primary ? ' is-active' : ''}" data-color="${esc(key)}" style="--vd-swatch-color: ${safeColor(value.color)}" title="${esc(value.name)}"></button>`;
|
|
511
576
|
}
|
|
512
577
|
|
|
513
578
|
// Generate neutral color swatches
|
|
514
579
|
let neutralSwatches = '';
|
|
515
580
|
for (const [key, value] of Object.entries(this.NEUTRAL_COLORS)) {
|
|
516
|
-
neutralSwatches += `<button class="tc-neutral-swatch${key === this.state.neutral ? ' is-active' : ''}" data-neutral="${esc(key)}" style="--swatch-color: ${safeColor(value.color)}" title="${esc(value.name)}"><span>${esc(value.name)}</span></button>`;
|
|
581
|
+
neutralSwatches += `<button class="tc-neutral-swatch${key === this.state.neutral ? ' is-active' : ''}" data-neutral="${esc(key)}" style="--vd-swatch-color: ${safeColor(value.color)}" title="${esc(value.name)}"><span>${esc(value.name)}</span></button>`;
|
|
517
582
|
}
|
|
518
583
|
|
|
519
584
|
// Generate radius buttons
|
|
@@ -595,8 +660,8 @@
|
|
|
595
660
|
}
|
|
596
661
|
},
|
|
597
662
|
|
|
598
|
-
bindEvents: function () {
|
|
599
|
-
this.bindTriggerEvents();
|
|
663
|
+
bindEvents: function (root) {
|
|
664
|
+
this.bindTriggerEvents(root);
|
|
600
665
|
|
|
601
666
|
this.bindPanelEvents();
|
|
602
667
|
|
|
@@ -631,22 +696,53 @@
|
|
|
631
696
|
});
|
|
632
697
|
},
|
|
633
698
|
|
|
634
|
-
bindTriggerEvents: function () {
|
|
635
|
-
this.
|
|
699
|
+
bindTriggerEvents: function (root) {
|
|
700
|
+
const triggers = root ? this.getTriggers(root) : this.elements.triggers;
|
|
701
|
+
triggers.forEach((trigger) => {
|
|
636
702
|
if (trigger.getAttribute('data-customizer-trigger-initialized') === 'true') {
|
|
637
703
|
return;
|
|
638
704
|
}
|
|
639
|
-
|
|
705
|
+
|
|
706
|
+
const onClick = (e) => {
|
|
640
707
|
e.preventDefault();
|
|
641
708
|
e.stopPropagation();
|
|
642
709
|
this.elements.activeTrigger = trigger;
|
|
643
710
|
this.elements.trigger = trigger;
|
|
644
711
|
this.toggle();
|
|
645
|
-
}
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
trigger.addEventListener('click', onClick);
|
|
715
|
+
trigger._themeCustomizerTriggerHandler = onClick;
|
|
646
716
|
trigger.setAttribute('data-customizer-trigger-initialized', 'true');
|
|
647
717
|
});
|
|
648
718
|
},
|
|
649
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
|
+
|
|
650
746
|
/**
|
|
651
747
|
* Toggle panel open/close
|
|
652
748
|
*/
|
|
@@ -782,7 +878,21 @@
|
|
|
782
878
|
}
|
|
783
879
|
},
|
|
784
880
|
|
|
785
|
-
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
|
+
|
|
786
896
|
this._cleanup.forEach(fn => fn());
|
|
787
897
|
this._cleanup = [];
|
|
788
898
|
|
|
@@ -790,7 +900,27 @@
|
|
|
790
900
|
this.elements.panel.removeAttribute('data-customizer-initialized');
|
|
791
901
|
}
|
|
792
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
|
+
|
|
793
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;
|
|
794
924
|
this.isInitialized = false;
|
|
795
925
|
}
|
|
796
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);
|