@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/affix.js
CHANGED
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
const Affix = {
|
|
33
33
|
instances: new Map(),
|
|
34
34
|
|
|
35
|
-
init: function () {
|
|
36
|
-
const elements =
|
|
35
|
+
init: function (root) {
|
|
36
|
+
const elements = window.Vanduo.queryAll(root, '.vd-affix, .vd-sticky, [data-vd-affix]');
|
|
37
37
|
elements.forEach(el => {
|
|
38
38
|
if (this.instances.has(el)) return;
|
|
39
39
|
this.initInstance(el);
|
package/js/components/bubble.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
_globalCleanups: [],
|
|
12
12
|
|
|
13
|
-
init: function () {
|
|
14
|
-
const triggers =
|
|
13
|
+
init: function (root) {
|
|
14
|
+
const triggers = window.Vanduo.queryAll(root, '[data-vd-bubble], [data-vd-popover]');
|
|
15
15
|
triggers.forEach(el => {
|
|
16
16
|
if (this.instances.has(el)) return;
|
|
17
17
|
this.initInstance(el);
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
body.className = 'vd-bubble-body';
|
|
83
83
|
if (htmlContent) {
|
|
84
84
|
if (typeof sanitizeHtml === 'function') {
|
|
85
|
-
body.innerHTML = sanitizeHtml(htmlContent, { allowSvg });
|
|
85
|
+
body.innerHTML = sanitizeHtml(htmlContent, { allowSvg, allowStyle: false });
|
|
86
86
|
} else {
|
|
87
87
|
body.textContent = htmlContent;
|
|
88
88
|
}
|
|
@@ -12,6 +12,31 @@
|
|
|
12
12
|
const CodeSnippet = {
|
|
13
13
|
_snippetIdCounter: 0,
|
|
14
14
|
|
|
15
|
+
resolveRoot: function (root) {
|
|
16
|
+
if (root && (root.nodeType === 1 || root.nodeType === 9 || root.nodeType === 11)) {
|
|
17
|
+
return root;
|
|
18
|
+
}
|
|
19
|
+
return document;
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
queryWithin: function (root, selector) {
|
|
23
|
+
const scope = this.resolveRoot(root);
|
|
24
|
+
const matches = [];
|
|
25
|
+
|
|
26
|
+
if (scope instanceof Element && typeof scope.matches === 'function' && scope.matches(selector)) {
|
|
27
|
+
matches.push(scope);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (typeof scope.querySelectorAll === 'function') {
|
|
31
|
+
const descendants = scope.querySelectorAll(selector);
|
|
32
|
+
for (let i = 0; i < descendants.length; i++) {
|
|
33
|
+
matches.push(descendants[i]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return matches;
|
|
38
|
+
},
|
|
39
|
+
|
|
15
40
|
getSnippetInstanceId: function (snippet) {
|
|
16
41
|
if (snippet.dataset.codeSnippetId) {
|
|
17
42
|
return snippet.dataset.codeSnippetId;
|
|
@@ -40,8 +65,8 @@
|
|
|
40
65
|
/**
|
|
41
66
|
* Initialize all code snippet components
|
|
42
67
|
*/
|
|
43
|
-
init: function () {
|
|
44
|
-
const snippets =
|
|
68
|
+
init: function (root) {
|
|
69
|
+
const snippets = this.queryWithin(root, '.vd-code-snippet');
|
|
45
70
|
|
|
46
71
|
snippets.forEach(snippet => {
|
|
47
72
|
if (!snippet.dataset.initialized) {
|
|
@@ -86,6 +111,11 @@
|
|
|
86
111
|
this.extractHtml(pane);
|
|
87
112
|
});
|
|
88
113
|
|
|
114
|
+
const panesToHighlight = snippet.querySelectorAll('.vd-code-snippet-pane:not([data-extract])');
|
|
115
|
+
panesToHighlight.forEach(pane => {
|
|
116
|
+
this.applyPaneHighlighting(pane);
|
|
117
|
+
});
|
|
118
|
+
|
|
89
119
|
// Handle line numbers
|
|
90
120
|
const lineNumberPanes = snippet.querySelectorAll('.has-line-numbers');
|
|
91
121
|
lineNumberPanes.forEach(pane => {
|
|
@@ -383,6 +413,7 @@
|
|
|
383
413
|
codeEl.innerHTML = html;
|
|
384
414
|
pane.replaceChildren(codeEl);
|
|
385
415
|
pane.dataset.extracted = 'true';
|
|
416
|
+
pane.dataset.highlighted = 'true';
|
|
386
417
|
},
|
|
387
418
|
|
|
388
419
|
/**
|
|
@@ -441,6 +472,94 @@
|
|
|
441
472
|
return div.innerHTML;
|
|
442
473
|
},
|
|
443
474
|
|
|
475
|
+
needsHighlighting: function (pane, codeEl) {
|
|
476
|
+
if (!codeEl) return false;
|
|
477
|
+
if (pane.dataset.highlighted === 'true') return false;
|
|
478
|
+
if (codeEl.querySelector('[class^="code-"], [class*=" code-"]')) return false;
|
|
479
|
+
return true;
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
getHighlightMode: function (lang) {
|
|
483
|
+
const normalized = String(lang || '').trim().toLowerCase();
|
|
484
|
+
|
|
485
|
+
if ([
|
|
486
|
+
'html',
|
|
487
|
+
'xml',
|
|
488
|
+
'svg',
|
|
489
|
+
'vue',
|
|
490
|
+
'svelte',
|
|
491
|
+
'astro'
|
|
492
|
+
].includes(normalized)) {
|
|
493
|
+
return 'html';
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if ([
|
|
497
|
+
'css',
|
|
498
|
+
'scss',
|
|
499
|
+
'sass',
|
|
500
|
+
'less'
|
|
501
|
+
].includes(normalized)) {
|
|
502
|
+
return 'css';
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if ([
|
|
506
|
+
'js',
|
|
507
|
+
'mjs',
|
|
508
|
+
'cjs',
|
|
509
|
+
'ts',
|
|
510
|
+
'jsx',
|
|
511
|
+
'tsx',
|
|
512
|
+
'json',
|
|
513
|
+
'bash',
|
|
514
|
+
'sh'
|
|
515
|
+
].includes(normalized)) {
|
|
516
|
+
return 'js';
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return 'plain';
|
|
520
|
+
},
|
|
521
|
+
|
|
522
|
+
highlightCodeByLang: function (rawCode, lang) {
|
|
523
|
+
const escaped = this.escapeHtml(rawCode);
|
|
524
|
+
const mode = this.getHighlightMode(lang);
|
|
525
|
+
|
|
526
|
+
if (mode === 'html') {
|
|
527
|
+
return this.highlightHtml(escaped);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (mode === 'css') {
|
|
531
|
+
return this.highlightCss(escaped);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (mode === 'js') {
|
|
535
|
+
return this.highlightJs(escaped);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return escaped;
|
|
539
|
+
},
|
|
540
|
+
|
|
541
|
+
applyPaneHighlighting: function (pane) {
|
|
542
|
+
if (!pane) return;
|
|
543
|
+
|
|
544
|
+
const codeEl = pane.querySelector('code') || pane;
|
|
545
|
+
if (!this.needsHighlighting(pane, codeEl)) {
|
|
546
|
+
pane.dataset.highlighted = 'true';
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const rawCode = codeEl.textContent || '';
|
|
551
|
+
const highlighted = this.highlightCodeByLang(rawCode, pane.dataset.lang);
|
|
552
|
+
const nextCodeEl = codeEl.tagName === 'CODE' ? codeEl : document.createElement('code');
|
|
553
|
+
|
|
554
|
+
nextCodeEl.innerHTML = highlighted;
|
|
555
|
+
|
|
556
|
+
if (nextCodeEl !== codeEl) {
|
|
557
|
+
pane.replaceChildren(nextCodeEl);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
pane.dataset.highlighted = 'true';
|
|
561
|
+
},
|
|
562
|
+
|
|
444
563
|
/**
|
|
445
564
|
* Apply syntax highlighting to HTML
|
|
446
565
|
* @param {string} html - Escaped HTML string
|
|
@@ -451,9 +570,11 @@
|
|
|
451
570
|
html = html.replace(/(<\/?)([\w-]+)/g, '$1<span class="code-tag">$2</span>');
|
|
452
571
|
|
|
453
572
|
// Highlight attributes
|
|
573
|
+
html = html.replace(/([\w-]+)(=)(["'])/g, '<span class="code-attr">$1</span>$2$3');
|
|
454
574
|
html = html.replace(/([\w-]+)(=)("|')/g, '<span class="code-attr">$1</span>$2$3');
|
|
455
575
|
|
|
456
576
|
// Highlight attribute values (strings)
|
|
577
|
+
html = html.replace(/(["'])([^"']*)(["'])/g, '$1<span class="code-string">$2</span>$3');
|
|
457
578
|
html = html.replace(/("|')([^&]*)("|')/g, '$1<span class="code-string">$2</span>$3');
|
|
458
579
|
|
|
459
580
|
// Highlight comments
|
|
@@ -625,9 +746,12 @@
|
|
|
625
746
|
/**
|
|
626
747
|
* Destroy all code snippet instances
|
|
627
748
|
*/
|
|
628
|
-
destroyAll: function () {
|
|
629
|
-
const
|
|
630
|
-
snippets
|
|
749
|
+
destroyAll: function (root) {
|
|
750
|
+
const scope = this.resolveRoot(root);
|
|
751
|
+
const snippets = this.queryWithin(scope, '.vd-code-snippet[data-initialized="true"]');
|
|
752
|
+
snippets.forEach(snippet => {
|
|
753
|
+
this.destroy(snippet);
|
|
754
|
+
});
|
|
631
755
|
}
|
|
632
756
|
};
|
|
633
757
|
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
/**
|
|
17
17
|
* Initialize collapsible components
|
|
18
18
|
*/
|
|
19
|
-
init: function() {
|
|
20
|
-
const collapsibles =
|
|
19
|
+
init: function(root) {
|
|
20
|
+
const collapsibles = window.Vanduo.queryAll(root, '.vd-collapsible, .accordion');
|
|
21
21
|
|
|
22
22
|
collapsibles.forEach(container => {
|
|
23
23
|
if (this.instances.has(container)) {
|
|
@@ -223,4 +223,3 @@
|
|
|
223
223
|
window.VanduoCollapsible = Collapsible;
|
|
224
224
|
|
|
225
225
|
})();
|
|
226
|
-
|
|
@@ -131,8 +131,8 @@
|
|
|
131
131
|
const Datepicker = {
|
|
132
132
|
instances: new Map(),
|
|
133
133
|
|
|
134
|
-
init: function () {
|
|
135
|
-
const inputs =
|
|
134
|
+
init: function (root) {
|
|
135
|
+
const inputs = window.Vanduo.queryAll(root, '[data-vd-datepicker]');
|
|
136
136
|
inputs.forEach(el => {
|
|
137
137
|
if (this.instances.has(el)) return;
|
|
138
138
|
this.initInstance(el);
|
|
@@ -84,6 +84,26 @@
|
|
|
84
84
|
placeholder: 'Search...'
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
+
const ALLOWED_HIGHLIGHT_TAGS = {
|
|
88
|
+
mark: true,
|
|
89
|
+
span: true,
|
|
90
|
+
strong: true,
|
|
91
|
+
em: true
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function isRoot(value) {
|
|
95
|
+
return typeof window.VanduoLifecycle !== 'undefined' && window.VanduoLifecycle.isRoot(value);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function normalizeRoot(root) {
|
|
99
|
+
return isRoot(root) ? root : document;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function normalizeHighlightTag(tagName) {
|
|
103
|
+
const normalized = typeof tagName === 'string' ? tagName.toLowerCase() : 'mark';
|
|
104
|
+
return ALLOWED_HIGHLIGHT_TAGS[normalized] ? normalized : 'mark';
|
|
105
|
+
}
|
|
106
|
+
|
|
87
107
|
/**
|
|
88
108
|
* Search Component Factory
|
|
89
109
|
* Creates a new search instance with the given configuration
|
|
@@ -93,6 +113,8 @@
|
|
|
93
113
|
*/
|
|
94
114
|
function createSearch(options) {
|
|
95
115
|
const config = Object.assign({}, DEFAULTS, options || {});
|
|
116
|
+
config.root = normalizeRoot(config.root);
|
|
117
|
+
config.highlightTag = normalizeHighlightTag(config.highlightTag);
|
|
96
118
|
|
|
97
119
|
// Instance state
|
|
98
120
|
const state = {
|
|
@@ -109,6 +131,28 @@
|
|
|
109
131
|
boundHandlers: {}
|
|
110
132
|
};
|
|
111
133
|
|
|
134
|
+
function queryAll(selector) {
|
|
135
|
+
if (window.Vanduo && typeof window.Vanduo.queryAll === 'function') {
|
|
136
|
+
return window.Vanduo.queryAll(config.root, selector);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const scope = normalizeRoot(config.root);
|
|
140
|
+
if (scope === document) {
|
|
141
|
+
return Array.from(document.querySelectorAll(selector));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const matches = [];
|
|
145
|
+
if (scope instanceof Element && scope.matches(selector)) {
|
|
146
|
+
matches.push(scope);
|
|
147
|
+
}
|
|
148
|
+
return matches.concat(Array.from(scope.querySelectorAll(selector)));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function queryOne(selector) {
|
|
152
|
+
const matches = queryAll(selector);
|
|
153
|
+
return matches.length ? matches[0] : null;
|
|
154
|
+
}
|
|
155
|
+
|
|
112
156
|
function safeInvokeCallback(name, fn, ...args) {
|
|
113
157
|
try {
|
|
114
158
|
fn(...args);
|
|
@@ -136,7 +180,7 @@
|
|
|
136
180
|
return instance;
|
|
137
181
|
}
|
|
138
182
|
|
|
139
|
-
state.container =
|
|
183
|
+
state.container = queryOne(config.containerSelector);
|
|
140
184
|
if (!state.container) {
|
|
141
185
|
state.initialized = false;
|
|
142
186
|
return null;
|
|
@@ -192,7 +236,7 @@
|
|
|
192
236
|
}
|
|
193
237
|
|
|
194
238
|
// Build from DOM
|
|
195
|
-
const sections =
|
|
239
|
+
const sections = queryAll(config.contentSelector);
|
|
196
240
|
const categoryMap = buildCategoryMap();
|
|
197
241
|
|
|
198
242
|
sections.forEach(function(section) {
|
|
@@ -234,7 +278,7 @@
|
|
|
234
278
|
function buildCategoryMap() {
|
|
235
279
|
const map = {};
|
|
236
280
|
let currentCategory = 'Documentation';
|
|
237
|
-
const navItems =
|
|
281
|
+
const navItems = queryAll(config.navSelector + ', ' + config.sectionSelector);
|
|
238
282
|
|
|
239
283
|
navItems.forEach(function(item) {
|
|
240
284
|
if (item.classList.contains('doc-nav-section')) {
|
|
@@ -736,7 +780,7 @@
|
|
|
736
780
|
}
|
|
737
781
|
|
|
738
782
|
// Default behavior: navigate to section
|
|
739
|
-
const section = document.querySelector(result.url);
|
|
783
|
+
const section = queryOne(result.url) || document.querySelector(result.url);
|
|
740
784
|
if (section) {
|
|
741
785
|
section.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
742
786
|
window.history.pushState(null, '', result.url);
|
|
@@ -748,7 +792,7 @@
|
|
|
748
792
|
* Update sidebar navigation active state
|
|
749
793
|
*/
|
|
750
794
|
function updateSidebarActive(sectionId) {
|
|
751
|
-
const navLinks =
|
|
795
|
+
const navLinks = queryAll(config.navSelector);
|
|
752
796
|
navLinks.forEach(function(link) {
|
|
753
797
|
link.classList.remove('active');
|
|
754
798
|
if (link.getAttribute('href') === '#' + sectionId) {
|
|
@@ -822,6 +866,8 @@
|
|
|
822
866
|
*/
|
|
823
867
|
function setConfig(newConfig) {
|
|
824
868
|
Object.assign(config, newConfig);
|
|
869
|
+
config.root = normalizeRoot(config.root);
|
|
870
|
+
config.highlightTag = normalizeHighlightTag(config.highlightTag);
|
|
825
871
|
}
|
|
826
872
|
|
|
827
873
|
/**
|
|
@@ -848,7 +894,10 @@
|
|
|
848
894
|
close: close,
|
|
849
895
|
setConfig: setConfig,
|
|
850
896
|
getConfig: getConfig,
|
|
851
|
-
getIndex: getIndex
|
|
897
|
+
getIndex: getIndex,
|
|
898
|
+
getContainer: function () {
|
|
899
|
+
return state.container;
|
|
900
|
+
}
|
|
852
901
|
};
|
|
853
902
|
|
|
854
903
|
return instance;
|
|
@@ -878,7 +927,10 @@
|
|
|
878
927
|
/**
|
|
879
928
|
* Initialize the default search instance
|
|
880
929
|
*/
|
|
881
|
-
init: function(
|
|
930
|
+
init: function(rootOrOptions, maybeOptions) {
|
|
931
|
+
const root = isRoot(rootOrOptions) ? rootOrOptions : null;
|
|
932
|
+
const options = root ? maybeOptions : rootOrOptions;
|
|
933
|
+
|
|
882
934
|
if (this._instance) {
|
|
883
935
|
this._instance.destroy();
|
|
884
936
|
}
|
|
@@ -887,22 +939,28 @@
|
|
|
887
939
|
Object.assign(this.config, options);
|
|
888
940
|
}
|
|
889
941
|
|
|
890
|
-
this._instance = createSearch(this.config);
|
|
942
|
+
this._instance = createSearch(Object.assign({}, this.config, root ? { root: root } : {}));
|
|
891
943
|
return this._instance ? this._instance.init() : null;
|
|
892
944
|
},
|
|
893
945
|
|
|
894
946
|
/**
|
|
895
947
|
* Destroy the default instance
|
|
896
948
|
*/
|
|
897
|
-
destroy: function() {
|
|
949
|
+
destroy: function(root) {
|
|
950
|
+
if (root && this._instance && this._instance.getContainer() && typeof window.VanduoLifecycle !== 'undefined') {
|
|
951
|
+
if (!window.VanduoLifecycle.isInRoot(root, this._instance.getContainer())) {
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
898
956
|
if (this._instance) {
|
|
899
957
|
this._instance.destroy();
|
|
900
958
|
this._instance = null;
|
|
901
959
|
}
|
|
902
960
|
},
|
|
903
961
|
|
|
904
|
-
destroyAll: function() {
|
|
905
|
-
this.destroy();
|
|
962
|
+
destroyAll: function(root) {
|
|
963
|
+
this.destroy(root);
|
|
906
964
|
},
|
|
907
965
|
|
|
908
966
|
/**
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
/**
|
|
25
25
|
* Initialize draggable components
|
|
26
26
|
*/
|
|
27
|
-
init: function () {
|
|
28
|
-
const draggables =
|
|
27
|
+
init: function (root) {
|
|
28
|
+
const draggables = window.Vanduo.queryAll(root, '.vd-draggable, [data-draggable]');
|
|
29
29
|
|
|
30
30
|
draggables.forEach(element => {
|
|
31
31
|
if (this.instances.has(element)) {
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
this.initDraggable(element);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
const containers =
|
|
37
|
+
const containers = window.Vanduo.queryAll(root, this.containerSelector);
|
|
38
38
|
containers.forEach(container => {
|
|
39
39
|
if (!this.instances.has(container)) {
|
|
40
40
|
this.initContainer(container);
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
const dropZones =
|
|
44
|
+
const dropZones = window.Vanduo.queryAll(root, '.vd-drop-zone');
|
|
45
45
|
dropZones.forEach(zone => {
|
|
46
46
|
if (!this.instances.has(zone)) {
|
|
47
47
|
this.initDropZone(zone);
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
/**
|
|
17
17
|
* Initialize dropdown components
|
|
18
18
|
*/
|
|
19
|
-
init: function() {
|
|
20
|
-
const dropdowns =
|
|
19
|
+
init: function(root) {
|
|
20
|
+
const dropdowns = window.Vanduo.queryAll(root, '.vd-dropdown');
|
|
21
21
|
|
|
22
22
|
dropdowns.forEach(dropdown => {
|
|
23
23
|
if (this.instances.has(dropdown)) {
|
|
@@ -367,4 +367,3 @@
|
|
|
367
367
|
window.VanduoDropdown = Dropdown;
|
|
368
368
|
|
|
369
369
|
})();
|
|
370
|
-
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
const ExpandingCards = {
|
|
14
14
|
instances: new Map(),
|
|
15
15
|
|
|
16
|
-
init: function () {
|
|
17
|
-
|
|
16
|
+
init: function (root) {
|
|
17
|
+
window.Vanduo.queryAll(root, '.vd-expanding-cards').forEach(function (el) {
|
|
18
18
|
if (el.getAttribute('data-vd-expanding-cards') === 'manual') return;
|
|
19
19
|
if (ExpandingCards.instances.has(el)) return;
|
|
20
20
|
ExpandingCards.initContainer(el);
|
package/js/components/flow.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
const Flow = {
|
|
10
10
|
instances: new Map(),
|
|
11
11
|
|
|
12
|
-
init: function () {
|
|
13
|
-
const carousels =
|
|
12
|
+
init: function (root) {
|
|
13
|
+
const carousels = window.Vanduo.queryAll(root, '.vd-flow, .vd-carousel');
|
|
14
14
|
carousels.forEach(el => {
|
|
15
15
|
if (this.instances.has(el)) return;
|
|
16
16
|
this.initInstance(el);
|
|
@@ -40,36 +40,42 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
getToggles: function(root) {
|
|
44
|
+
if (window.Vanduo && typeof window.Vanduo.queryAll === 'function') {
|
|
45
|
+
return window.Vanduo.queryAll(root, '[data-toggle="font"]');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return Array.from(document.querySelectorAll('[data-toggle="font"]'));
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
init: function(root) {
|
|
44
52
|
this.state = {
|
|
45
53
|
preference: this.getPreference()
|
|
46
54
|
};
|
|
47
55
|
if (!this.fonts[this.state.preference]) {
|
|
48
|
-
this.state.preference = '
|
|
56
|
+
this.state.preference = 'ubuntu';
|
|
49
57
|
this.setStorageValue(this.STORAGE_KEY, this.state.preference);
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
if (this.isInitialized) {
|
|
53
61
|
this.applyFont();
|
|
54
|
-
this.renderUI();
|
|
55
|
-
this.updateUI();
|
|
62
|
+
this.renderUI(root);
|
|
63
|
+
this.updateUI(root);
|
|
56
64
|
return;
|
|
57
65
|
}
|
|
58
66
|
|
|
59
67
|
this.isInitialized = true;
|
|
60
68
|
|
|
61
69
|
this.applyFont();
|
|
62
|
-
this.renderUI();
|
|
63
|
-
|
|
64
|
-
console.log('Vanduo Font Switcher initialized');
|
|
70
|
+
this.renderUI(root);
|
|
65
71
|
},
|
|
66
72
|
|
|
67
73
|
/**
|
|
68
74
|
* Get saved font preference from localStorage
|
|
69
|
-
* @returns {string} Font key or '
|
|
75
|
+
* @returns {string} Font key or 'ubuntu' (default)
|
|
70
76
|
*/
|
|
71
77
|
getPreference: function() {
|
|
72
|
-
return this.getStorageValue(this.STORAGE_KEY, '
|
|
78
|
+
return this.getStorageValue(this.STORAGE_KEY, 'ubuntu');
|
|
73
79
|
},
|
|
74
80
|
|
|
75
81
|
/**
|
|
@@ -113,8 +119,8 @@
|
|
|
113
119
|
/**
|
|
114
120
|
* Initialize UI elements with data-toggle="font"
|
|
115
121
|
*/
|
|
116
|
-
renderUI: function() {
|
|
117
|
-
const toggles =
|
|
122
|
+
renderUI: function(root) {
|
|
123
|
+
const toggles = this.getToggles(root);
|
|
118
124
|
|
|
119
125
|
toggles.forEach(toggle => {
|
|
120
126
|
if (toggle.getAttribute('data-font-initialized') === 'true') {
|
|
@@ -153,8 +159,8 @@
|
|
|
153
159
|
/**
|
|
154
160
|
* Update all UI elements to reflect current state
|
|
155
161
|
*/
|
|
156
|
-
updateUI: function() {
|
|
157
|
-
const toggles =
|
|
162
|
+
updateUI: function(root) {
|
|
163
|
+
const toggles = this.getToggles(root);
|
|
158
164
|
|
|
159
165
|
toggles.forEach(toggle => {
|
|
160
166
|
if (toggle.tagName === 'SELECT') {
|
|
@@ -186,8 +192,10 @@
|
|
|
186
192
|
return this.fonts[fontKey] || null;
|
|
187
193
|
},
|
|
188
194
|
|
|
189
|
-
destroyAll: function() {
|
|
190
|
-
const toggles = document.
|
|
195
|
+
destroyAll: function(root) {
|
|
196
|
+
const toggles = this.getToggles(root || document).filter(function(toggle) {
|
|
197
|
+
return toggle.getAttribute('data-font-initialized') === 'true';
|
|
198
|
+
});
|
|
191
199
|
toggles.forEach(toggle => {
|
|
192
200
|
if (toggle._fontToggleHandler) {
|
|
193
201
|
const eventName = toggle.tagName === 'SELECT' ? 'change' : 'click';
|
|
@@ -197,7 +205,9 @@
|
|
|
197
205
|
toggle.removeAttribute('data-font-initialized');
|
|
198
206
|
});
|
|
199
207
|
|
|
200
|
-
|
|
208
|
+
if (!root || root === document) {
|
|
209
|
+
this.isInitialized = false;
|
|
210
|
+
}
|
|
201
211
|
},
|
|
202
212
|
|
|
203
213
|
getStorageValue: function(key, fallback) {
|
package/js/components/glass.js
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
/** @type {Map<Element, IntersectionObserver>} */
|
|
19
19
|
observers: new Map(),
|
|
20
20
|
|
|
21
|
-
init: function () {
|
|
22
|
-
|
|
21
|
+
init: function (root) {
|
|
22
|
+
window.Vanduo.queryAll(root, '[data-glass-scroll]').forEach(el => {
|
|
23
23
|
if (this.observers.has(el)) return;
|
|
24
24
|
this.initElement(el);
|
|
25
25
|
});
|
package/js/components/grid.js
CHANGED
|
@@ -20,12 +20,13 @@
|
|
|
20
20
|
*/
|
|
21
21
|
const GridLayout = {
|
|
22
22
|
instances: new Map(),
|
|
23
|
+
__vanduoScopedDestroyAll: true,
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Initialize all grid layout containers
|
|
26
27
|
*/
|
|
27
|
-
init: function () {
|
|
28
|
-
const containers =
|
|
28
|
+
init: function (root) {
|
|
29
|
+
const containers = window.Vanduo.queryAll(root, '[data-layout-mode]');
|
|
29
30
|
|
|
30
31
|
containers.forEach(function (container) {
|
|
31
32
|
if (this.instances.has(container)) {
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
this.initContainer(container);
|
|
35
36
|
}.bind(this));
|
|
36
37
|
|
|
37
|
-
this.initToggleButtons();
|
|
38
|
+
this.initToggleButtons(root);
|
|
38
39
|
},
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -59,8 +60,10 @@
|
|
|
59
60
|
/**
|
|
60
61
|
* Initialize toggle buttons that target grid containers
|
|
61
62
|
*/
|
|
62
|
-
initToggleButtons: function () {
|
|
63
|
-
const toggleButtons =
|
|
63
|
+
initToggleButtons: function (root) {
|
|
64
|
+
const toggleButtons = window.Vanduo && typeof window.Vanduo.queryAll === 'function'
|
|
65
|
+
? window.Vanduo.queryAll(root, '[data-grid-toggle]')
|
|
66
|
+
: document.querySelectorAll('[data-grid-toggle]');
|
|
64
67
|
|
|
65
68
|
toggleButtons.forEach(function (button) {
|
|
66
69
|
if (button.getAttribute('data-grid-initialized') === 'true') {
|
|
@@ -253,12 +256,20 @@
|
|
|
253
256
|
/**
|
|
254
257
|
* Destroy all grid layout instances and clean up toggle buttons
|
|
255
258
|
*/
|
|
256
|
-
destroyAll: function () {
|
|
259
|
+
destroyAll: function (root) {
|
|
260
|
+
const scope = window.Vanduo && typeof window.Vanduo._normalizeRoot === 'function'
|
|
261
|
+
? window.Vanduo._normalizeRoot(root)
|
|
262
|
+
: (root || document);
|
|
263
|
+
|
|
257
264
|
this.instances.forEach(function (instance, container) {
|
|
258
|
-
|
|
265
|
+
if (scope === document || scope === container || (typeof scope.contains === 'function' && scope.contains(container))) {
|
|
266
|
+
this.destroy(container);
|
|
267
|
+
}
|
|
259
268
|
}.bind(this));
|
|
260
269
|
|
|
261
|
-
const toggleButtons =
|
|
270
|
+
const toggleButtons = window.Vanduo && typeof window.Vanduo.queryAll === 'function'
|
|
271
|
+
? window.Vanduo.queryAll(scope, '[data-grid-toggle][data-grid-initialized="true"]')
|
|
272
|
+
: document.querySelectorAll('[data-grid-initialized="true"]');
|
|
262
273
|
toggleButtons.forEach(function (button) {
|
|
263
274
|
if (button._gridCleanup) {
|
|
264
275
|
button._gridCleanup();
|