@vanduo-oss/framework 1.4.5 → 1.5.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/CHANGELOG.md +82 -0
- package/README.md +23 -9
- package/css/primitives/primitives.css +257 -0
- package/css/utilities/print.css +19 -17
- package/css/vanduo.css +9 -3
- package/dist/build-info.json +3 -3
- package/dist/vanduo-core.css +19701 -0
- package/dist/vanduo-core.css.map +1 -0
- package/dist/vanduo-core.min.css +2 -0
- package/dist/vanduo-core.min.css.map +1 -0
- package/dist/vanduo.cjs.js +39 -19
- package/dist/vanduo.cjs.js.map +2 -2
- package/dist/vanduo.cjs.min.js +5 -5
- package/dist/vanduo.cjs.min.js.map +3 -3
- package/dist/vanduo.css +628 -33585
- package/dist/vanduo.css.map +1 -1
- package/dist/vanduo.d.ts +77 -0
- package/dist/vanduo.esm.js +39 -19
- package/dist/vanduo.esm.js.map +2 -2
- package/dist/vanduo.esm.min.js +5 -5
- package/dist/vanduo.esm.min.js.map +3 -3
- package/dist/vanduo.js +39 -19
- package/dist/vanduo.js.map +2 -2
- package/dist/vanduo.min.css +2 -2
- package/dist/vanduo.min.css.map +1 -1
- package/dist/vanduo.min.js +5 -5
- package/dist/vanduo.min.js.map +3 -3
- package/js/components/parallax.js +13 -7
- package/js/components/spotlight.js +46 -16
- package/package.json +7 -3
- package/css/components/doc-tabs.css +0 -38
- package/dist/icons/phosphor/bold/Phosphor-Bold.svg +0 -3057
- package/dist/icons/phosphor/bold/Phosphor-Bold.ttf +0 -0
- package/dist/icons/phosphor/bold/Phosphor-Bold.woff +0 -0
- package/dist/icons/phosphor/bold/Phosphor-Bold.woff2 +0 -0
- package/dist/icons/phosphor/bold/style.css +0 -4627
- package/dist/icons/phosphor/duotone/Phosphor-Duotone.svg +0 -3054
- package/dist/icons/phosphor/duotone/Phosphor-Duotone.ttf +0 -0
- package/dist/icons/phosphor/duotone/Phosphor-Duotone.woff +0 -0
- package/dist/icons/phosphor/duotone/Phosphor-Duotone.woff2 +0 -0
- package/dist/icons/phosphor/duotone/style.css +0 -12115
- package/dist/icons/phosphor/light/Phosphor-Light.svg +0 -3057
- package/dist/icons/phosphor/light/Phosphor-Light.ttf +0 -0
- package/dist/icons/phosphor/light/Phosphor-Light.woff +0 -0
- package/dist/icons/phosphor/light/Phosphor-Light.woff2 +0 -0
- package/dist/icons/phosphor/light/style.css +0 -4627
- package/dist/icons/phosphor/thin/Phosphor-Thin.svg +0 -3057
- package/dist/icons/phosphor/thin/Phosphor-Thin.ttf +0 -0
- package/dist/icons/phosphor/thin/Phosphor-Thin.woff +0 -0
- package/dist/icons/phosphor/thin/Phosphor-Thin.woff2 +0 -0
- package/dist/icons/phosphor/thin/style.css +0 -4627
- package/js/components/vd-hex.js +0 -838
- package/js/utils/hex-math.js +0 -233
|
@@ -64,15 +64,17 @@
|
|
|
64
64
|
initParallax: function (element) {
|
|
65
65
|
element.dataset.parallaxInitialized = 'true';
|
|
66
66
|
|
|
67
|
-
// Check if disabled on mobile
|
|
68
|
-
const disableMobile = element.classList.contains('parallax-disable-mobile')
|
|
67
|
+
// Check if disabled on mobile (vd- prefixed; unprefixed kept for back-compat)
|
|
68
|
+
const disableMobile = element.classList.contains('vd-parallax-disable-mobile')
|
|
69
|
+
|| element.classList.contains('parallax-disable-mobile');
|
|
69
70
|
if (disableMobile && this.isMobile) {
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
const layers = element.querySelectorAll('.vd-parallax-layer, .vd-parallax-bg');
|
|
74
75
|
const speed = this.getSpeed(element);
|
|
75
|
-
const direction = element.classList.contains('parallax-horizontal')
|
|
76
|
+
const direction = (element.classList.contains('vd-parallax-horizontal')
|
|
77
|
+
|| element.classList.contains('parallax-horizontal')) ? 'horizontal' : 'vertical';
|
|
76
78
|
|
|
77
79
|
this.parallaxElements.set(element, {
|
|
78
80
|
layers: Array.from(layers),
|
|
@@ -91,9 +93,11 @@
|
|
|
91
93
|
* @returns {number} Speed multiplier
|
|
92
94
|
*/
|
|
93
95
|
getSpeed: function (element) {
|
|
94
|
-
if (element.classList.contains('parallax-slow')
|
|
96
|
+
if (element.classList.contains('vd-parallax-slow')
|
|
97
|
+
|| element.classList.contains('parallax-slow')) {
|
|
95
98
|
return 0.5;
|
|
96
|
-
} else if (element.classList.contains('parallax-fast')
|
|
99
|
+
} else if (element.classList.contains('vd-parallax-fast')
|
|
100
|
+
|| element.classList.contains('parallax-fast')) {
|
|
97
101
|
return 1.5;
|
|
98
102
|
}
|
|
99
103
|
return 1; // Default medium speed
|
|
@@ -150,8 +154,10 @@
|
|
|
150
154
|
const offset = (scrollProgress - 0.5) * config.speed * 100;
|
|
151
155
|
|
|
152
156
|
config.layers.forEach((layer, _index) => {
|
|
153
|
-
// Different layers can have different speeds
|
|
154
|
-
|
|
157
|
+
// Different layers can have different speeds. Accept data-parallax-speed
|
|
158
|
+
// (canonical) or data-speed (back-compat).
|
|
159
|
+
const layerSpeedAttr = layer.dataset.parallaxSpeed || layer.dataset.speed;
|
|
160
|
+
const layerSpeed = layerSpeedAttr ? parseFloat(layerSpeedAttr) : 1;
|
|
155
161
|
const layerOffset = offset * layerSpeed;
|
|
156
162
|
|
|
157
163
|
if (config.direction === 'horizontal') {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
_cleanup: [],
|
|
15
15
|
_boundTriggers: new WeakMap(),
|
|
16
16
|
_triggerElement: null,
|
|
17
|
+
_currentTarget: null,
|
|
17
18
|
|
|
18
19
|
init: function (root) {
|
|
19
20
|
const triggers = window.Vanduo.queryAll(root, '[data-vd-spotlight]');
|
|
@@ -113,9 +114,39 @@
|
|
|
113
114
|
// Overlay click to close
|
|
114
115
|
overlay.addEventListener('click', () => this.stop());
|
|
115
116
|
|
|
117
|
+
// Keep the tooltip glued to its target while active — through the smooth
|
|
118
|
+
// scrollIntoView and any late layout (e.g. content-visibility sections that
|
|
119
|
+
// only render their real geometry once scrolled into view).
|
|
120
|
+
const reposition = () => {
|
|
121
|
+
if (this._active && this._currentTarget) this._positionTooltip(this._currentTarget);
|
|
122
|
+
};
|
|
123
|
+
window.addEventListener('scroll', reposition, { passive: true });
|
|
124
|
+
window.addEventListener('resize', reposition);
|
|
125
|
+
this._cleanup.push(() => window.removeEventListener('scroll', reposition));
|
|
126
|
+
this._cleanup.push(() => window.removeEventListener('resize', reposition));
|
|
127
|
+
|
|
116
128
|
this._showStep(this._currentStep);
|
|
117
129
|
},
|
|
118
130
|
|
|
131
|
+
_positionTooltip: function (target) {
|
|
132
|
+
const tooltip = this._elements.tooltip;
|
|
133
|
+
if (!tooltip || !target || !target.isConnected) return;
|
|
134
|
+
|
|
135
|
+
const rect = target.getBoundingClientRect();
|
|
136
|
+
const tRect = tooltip.getBoundingClientRect();
|
|
137
|
+
let top = rect.bottom + 12 + window.scrollY;
|
|
138
|
+
let left = rect.left + (rect.width - tRect.width) / 2 + window.scrollX;
|
|
139
|
+
|
|
140
|
+
// Keep in viewport
|
|
141
|
+
left = Math.max(8, Math.min(left, window.innerWidth - tRect.width - 8));
|
|
142
|
+
if (top + tRect.height > window.innerHeight + window.scrollY) {
|
|
143
|
+
top = rect.top - tRect.height - 12 + window.scrollY;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
tooltip.style.top = top + 'px';
|
|
147
|
+
tooltip.style.left = left + 'px';
|
|
148
|
+
},
|
|
149
|
+
|
|
119
150
|
_showStep: function (index) {
|
|
120
151
|
const step = this._steps[index];
|
|
121
152
|
if (!step) return;
|
|
@@ -206,23 +237,21 @@
|
|
|
206
237
|
footer.appendChild(actions);
|
|
207
238
|
tooltip.appendChild(footer);
|
|
208
239
|
|
|
209
|
-
// Position tooltip near target
|
|
240
|
+
// Position the tooltip near the target. A single measurement right after a
|
|
241
|
+
// smooth scrollIntoView is unreliable: the scroll is still animating and the
|
|
242
|
+
// target's final geometry may not exist yet (content-visibility sections only
|
|
243
|
+
// render once scrolled into view). Re-position across the settle window so the
|
|
244
|
+
// tooltip converges on the correct spot; the scroll/resize listeners keep it
|
|
245
|
+
// there afterward.
|
|
246
|
+
this._currentTarget = target || null;
|
|
210
247
|
if (target) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
left = Math.max(8, Math.min(left, window.innerWidth - tRect.width - 8));
|
|
219
|
-
if (top + tRect.height > window.innerHeight + window.scrollY) {
|
|
220
|
-
top = rect.top - tRect.height - 12 + window.scrollY;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
tooltip.style.top = top + 'px';
|
|
224
|
-
tooltip.style.left = left + 'px';
|
|
225
|
-
});
|
|
248
|
+
let frames = 0;
|
|
249
|
+
const settle = () => {
|
|
250
|
+
if (!this._active || this._currentTarget !== target) return;
|
|
251
|
+
this._positionTooltip(target);
|
|
252
|
+
if (frames++ < 30) requestAnimationFrame(settle);
|
|
253
|
+
};
|
|
254
|
+
requestAnimationFrame(settle);
|
|
226
255
|
}
|
|
227
256
|
|
|
228
257
|
document.dispatchEvent(new CustomEvent('spotlight:step', {
|
|
@@ -272,6 +301,7 @@
|
|
|
272
301
|
this._elements = {};
|
|
273
302
|
this._steps = [];
|
|
274
303
|
this._currentStep = 0;
|
|
304
|
+
this._currentTarget = null;
|
|
275
305
|
|
|
276
306
|
if (this._triggerElement && this._triggerElement.isConnected && typeof this._triggerElement.focus === 'function') {
|
|
277
307
|
this._triggerElement.focus();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vanduo-oss/framework",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Zero-dependency CSS/JS framework built on Fibonacci/Golden Ratio design system with Open Color integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -21,13 +21,16 @@
|
|
|
21
21
|
"type": "module",
|
|
22
22
|
"main": "dist/vanduo.cjs.js",
|
|
23
23
|
"module": "dist/vanduo.esm.js",
|
|
24
|
+
"types": "./dist/vanduo.d.ts",
|
|
24
25
|
"exports": {
|
|
25
26
|
".": {
|
|
27
|
+
"types": "./dist/vanduo.d.ts",
|
|
26
28
|
"import": "./dist/vanduo.esm.js",
|
|
27
29
|
"require": "./dist/vanduo.cjs.js",
|
|
28
30
|
"default": "./dist/vanduo.esm.js"
|
|
29
31
|
},
|
|
30
32
|
"./css": "./dist/vanduo.min.css",
|
|
33
|
+
"./css/core": "./dist/vanduo-core.min.css",
|
|
31
34
|
"./iife": "./dist/vanduo.min.js",
|
|
32
35
|
"./package.json": "./package.json"
|
|
33
36
|
},
|
|
@@ -36,12 +39,13 @@
|
|
|
36
39
|
"css/",
|
|
37
40
|
"js/",
|
|
38
41
|
"fonts/",
|
|
39
|
-
"icons/"
|
|
42
|
+
"icons/",
|
|
43
|
+
"CHANGELOG.md"
|
|
40
44
|
],
|
|
41
45
|
"devDependencies": {
|
|
42
46
|
"@eslint/js": "^10.0.1",
|
|
43
47
|
"@playwright/test": "^1.60.0",
|
|
44
|
-
"esbuild": "^0.28.
|
|
48
|
+
"esbuild": "^0.28.1",
|
|
45
49
|
"eslint": "^10.4.1",
|
|
46
50
|
"husky": "^9.1.7",
|
|
47
51
|
"lightningcss": "^1.32.0",
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vanduo Documentation Tabs Component
|
|
3
|
-
* Provides styled tab navigation for documentation sections
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
.doc-tabs {
|
|
7
|
-
display: flex;
|
|
8
|
-
gap: 0.5rem;
|
|
9
|
-
margin: 1rem 0 1.5rem;
|
|
10
|
-
flex-wrap: wrap;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.doc-tab {
|
|
14
|
-
display: inline-flex;
|
|
15
|
-
align-items: center;
|
|
16
|
-
gap: 0.4rem;
|
|
17
|
-
padding: 0.6rem 1rem;
|
|
18
|
-
border: 1px solid var(--vd-border-color);
|
|
19
|
-
border-radius: var(--vd-btn-border-radius);
|
|
20
|
-
background: var(--vd-bg-secondary);
|
|
21
|
-
color: var(--vd-text-primary);
|
|
22
|
-
text-decoration: none;
|
|
23
|
-
font-weight: 500;
|
|
24
|
-
transition: all 0.2s ease;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.doc-tab:hover {
|
|
28
|
-
border-color: var(--vd-color-primary);
|
|
29
|
-
color: var(--vd-color-primary);
|
|
30
|
-
background: var(--vd-color-primary-alpha-08);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.doc-tab.active {
|
|
34
|
-
border-color: var(--vd-color-primary);
|
|
35
|
-
color: var(--vd-text-on-primary);
|
|
36
|
-
background: var(--vd-color-primary);
|
|
37
|
-
box-shadow: 0 0 0 1px var(--vd-color-primary-alpha-20);
|
|
38
|
-
}
|