@vanduo-oss/framework 1.3.3 → 1.3.4
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 +14 -4
- package/css/components/cards.css +8 -0
- package/css/components/dropdown.css +8 -0
- package/css/components/fab.css +14 -0
- package/css/components/modals.css +13 -0
- package/css/components/navbar.css +30 -0
- package/css/components/toast.css +8 -0
- package/css/components/tooltips.css +29 -0
- package/css/core/tokens.css +37 -0
- package/css/core/vd-aliases.css +13 -0
- package/css/effects/glass.css +154 -0
- package/css/vanduo.css +1 -0
- package/dist/build-info.json +3 -3
- package/dist/vanduo.cjs.js +96 -3
- package/dist/vanduo.cjs.js.map +3 -3
- package/dist/vanduo.cjs.min.js +4 -4
- package/dist/vanduo.cjs.min.js.map +4 -4
- package/dist/vanduo.css +261 -1
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.esm.js +96 -3
- package/dist/vanduo.esm.js.map +3 -3
- package/dist/vanduo.esm.min.js +4 -4
- package/dist/vanduo.esm.min.js.map +4 -4
- package/dist/vanduo.js +96 -3
- 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 +4 -4
- package/dist/vanduo.min.js.map +4 -4
- package/js/components/glass.js +87 -0
- package/js/components/navbar.js +44 -3
- package/js/index.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanduo Framework - Glass Scroll Activation
|
|
3
|
+
* Generic scroll-aware glass activation via IntersectionObserver.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* Add `data-glass-scroll` to any element carrying a `.vd-glass*` class.
|
|
7
|
+
* By default the previous sibling is used as the sentinel.
|
|
8
|
+
* Point to a custom sentinel via `data-glass-sentinel="<CSS selector>"`.
|
|
9
|
+
*
|
|
10
|
+
* Behaviour:
|
|
11
|
+
* - Adds `.is-glass-active` when the sentinel leaves the viewport (scrolled past).
|
|
12
|
+
* - Removes `.is-glass-active` when the sentinel re-enters the viewport.
|
|
13
|
+
*/
|
|
14
|
+
(function () {
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const GlassScroll = {
|
|
18
|
+
/** @type {Map<Element, IntersectionObserver>} */
|
|
19
|
+
observers: new Map(),
|
|
20
|
+
|
|
21
|
+
init: function () {
|
|
22
|
+
document.querySelectorAll('[data-glass-scroll]').forEach(el => {
|
|
23
|
+
if (this.observers.has(el)) return;
|
|
24
|
+
this.initElement(el);
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Wire up a single scroll-activated glass element.
|
|
30
|
+
* @param {HTMLElement} el
|
|
31
|
+
*/
|
|
32
|
+
initElement: function (el) {
|
|
33
|
+
const sentinelSelector = el.dataset.glassSentinel;
|
|
34
|
+
let sentinel;
|
|
35
|
+
|
|
36
|
+
if (sentinelSelector) {
|
|
37
|
+
sentinel = document.querySelector(sentinelSelector);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!sentinel) {
|
|
41
|
+
// Fall back to the previous sibling element
|
|
42
|
+
sentinel = el.previousElementSibling;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!sentinel) {
|
|
46
|
+
// No sentinel available — activate immediately so glass is always shown
|
|
47
|
+
el.classList.add('is-glass-active');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const observer = new IntersectionObserver(
|
|
52
|
+
(entries) => {
|
|
53
|
+
entries.forEach(entry => {
|
|
54
|
+
// Active when sentinel is NOT intersecting (scrolled past it)
|
|
55
|
+
el.classList.toggle('is-glass-active', !entry.isIntersecting);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
{ threshold: 0, rootMargin: '0px' }
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
observer.observe(sentinel);
|
|
62
|
+
this.observers.set(el, observer);
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Disconnect and remove a single element's observer.
|
|
67
|
+
* @param {HTMLElement} el
|
|
68
|
+
*/
|
|
69
|
+
destroy: function (el) {
|
|
70
|
+
const observer = this.observers.get(el);
|
|
71
|
+
if (observer) {
|
|
72
|
+
observer.disconnect();
|
|
73
|
+
this.observers.delete(el);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
destroyAll: function () {
|
|
78
|
+
this.observers.forEach((observer, el) => this.destroy(el));
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (typeof window.Vanduo !== 'undefined') {
|
|
83
|
+
window.Vanduo.register('glassScroll', GlassScroll);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
window.VanduoGlassScroll = GlassScroll;
|
|
87
|
+
})();
|
package/js/components/navbar.js
CHANGED
|
@@ -41,6 +41,37 @@
|
|
|
41
41
|
});
|
|
42
42
|
},
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Initialize scroll-aware glass/transparent behaviour for a navbar.
|
|
46
|
+
* Adds/removes `.vd-navbar-scrolled` when the page scrolls past a threshold.
|
|
47
|
+
* Threshold: `data-scroll-threshold` attribute (px) or the navbar's own height.
|
|
48
|
+
* @param {HTMLElement} navbar - Navbar element
|
|
49
|
+
* @returns {Function|null} Cleanup function, or null if not applicable
|
|
50
|
+
*/
|
|
51
|
+
initScrollWatcher: function (navbar) {
|
|
52
|
+
const isGlass = navbar.classList.contains('vd-navbar-glass');
|
|
53
|
+
const isTransparent = navbar.classList.contains('vd-navbar-transparent');
|
|
54
|
+
|
|
55
|
+
if (!isGlass && !isTransparent) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const getThreshold = () => {
|
|
60
|
+
const attr = parseInt(navbar.dataset.scrollThreshold, 10);
|
|
61
|
+
return isNaN(attr) ? (navbar.offsetHeight || 60) : attr;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const onScroll = () => {
|
|
65
|
+
const scrolled = window.scrollY > getThreshold();
|
|
66
|
+
navbar.classList.toggle('vd-navbar-scrolled', scrolled);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
onScroll(); // set initial state without waiting for first scroll
|
|
70
|
+
window.addEventListener('scroll', onScroll, { passive: true });
|
|
71
|
+
|
|
72
|
+
return () => window.removeEventListener('scroll', onScroll);
|
|
73
|
+
},
|
|
74
|
+
|
|
44
75
|
/**
|
|
45
76
|
* Initialize a single navbar
|
|
46
77
|
* @param {HTMLElement} navbar - Navbar element
|
|
@@ -50,13 +81,23 @@
|
|
|
50
81
|
const menu = navbar.querySelector('.vd-navbar-menu');
|
|
51
82
|
const overlay = navbar.querySelector('.vd-navbar-overlay') || this.createOverlay(navbar);
|
|
52
83
|
|
|
84
|
+
// Store cleanup functions for this navbar instance
|
|
85
|
+
const cleanupFunctions = [];
|
|
86
|
+
|
|
87
|
+
// Wire up scroll-aware glass/transparent behaviour regardless of mobile menu
|
|
88
|
+
const scrollWatcherCleanup = this.initScrollWatcher(navbar);
|
|
89
|
+
if (scrollWatcherCleanup) {
|
|
90
|
+
cleanupFunctions.push(scrollWatcherCleanup);
|
|
91
|
+
}
|
|
92
|
+
|
|
53
93
|
if (!toggle || !menu) {
|
|
94
|
+
// Still store the instance so scroll-watcher cleanup is tracked
|
|
95
|
+
if (cleanupFunctions.length) {
|
|
96
|
+
this.instances.set(navbar, { toggle: null, menu: null, overlay: null, cleanup: cleanupFunctions });
|
|
97
|
+
}
|
|
54
98
|
return;
|
|
55
99
|
}
|
|
56
100
|
|
|
57
|
-
// Store cleanup functions for this navbar instance
|
|
58
|
-
const cleanupFunctions = [];
|
|
59
|
-
|
|
60
101
|
// Toggle menu on button click
|
|
61
102
|
const toggleClickHandler = (e) => {
|
|
62
103
|
e.preventDefault();
|
package/js/index.js
CHANGED
|
@@ -47,6 +47,9 @@ import './components/doc-search.js';
|
|
|
47
47
|
import './components/draggable.js';
|
|
48
48
|
import './components/lazy-load.js';
|
|
49
49
|
|
|
50
|
+
// Effects (glass scroll activation)
|
|
51
|
+
import './components/glass.js';
|
|
52
|
+
|
|
50
53
|
// Phase 10 (v1.2.7) components
|
|
51
54
|
import './components/flow.js';
|
|
52
55
|
import './components/bubble.js';
|