@hortonstudio/main 1.9.20 → 1.9.22
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/dist/assets/animations-igIF6V0K.js +3 -0
- package/dist/assets/animations-igIF6V0K.js. +3 -0
- package/dist/assets/animations-igIF6V0K.js.gz +0 -0
- package/dist/assets/animations-igIF6V0K.js.map +1 -0
- package/dist/assets/counter-B9xmgh8V.js +2 -0
- package/dist/assets/counter-B9xmgh8V.js. +2 -0
- package/dist/assets/counter-B9xmgh8V.js.gz +0 -0
- package/dist/assets/counter-B9xmgh8V.js.map +1 -0
- package/dist/assets/cssVariables-n9wQSSYb.js +2 -0
- package/dist/assets/cssVariables-n9wQSSYb.js.map +1 -0
- package/dist/assets/default-CZ6vle49.js +2 -0
- package/dist/assets/default-CZ6vle49.js. +2 -0
- package/dist/assets/default-CZ6vle49.js.gz +0 -0
- package/dist/assets/default-CZ6vle49.js.map +1 -0
- package/dist/assets/modalManager-LtDi9OJz.js +2 -0
- package/dist/assets/modalManager-LtDi9OJz.js. +2 -0
- package/dist/assets/modalManager-LtDi9OJz.js.gz +0 -0
- package/dist/assets/modalManager-LtDi9OJz.js.map +1 -0
- package/dist/assets/normalize-DWI4olFS.js +2 -0
- package/dist/assets/normalize-DWI4olFS.js. +2 -0
- package/dist/assets/normalize-DWI4olFS.js.gz +0 -0
- package/dist/assets/normalize-DWI4olFS.js.map +1 -0
- package/dist/assets/structure--7b3v7AH.js +2 -0
- package/dist/assets/structure--7b3v7AH.js. +2 -0
- package/dist/assets/structure--7b3v7AH.js.gz +0 -0
- package/dist/assets/structure--7b3v7AH.js.map +1 -0
- package/dist/assets/utils-DA-PANmk.js +2 -0
- package/dist/assets/utils-DA-PANmk.js.map +1 -0
- package/dist/bootstrap.js +2 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/main.js +3 -0
- package/dist/main.js. +3 -0
- package/dist/main.js.gz +0 -0
- package/dist/main.js.map +1 -0
- package/package.json +5 -2
- package/.prettierrc +0 -8
- package/eslint.config.js +0 -32
- package/index.ts +0 -275
- package/public/bootstrap.js +0 -16
- package/src/animations/animations.ts +0 -93
- package/src/animations/functions/counter/counter.ts +0 -137
- package/src/config.json +0 -570
- package/src/config.ts +0 -105
- package/src/modules/default/README.md +0 -167
- package/src/modules/default/default.ts +0 -71
- package/src/modules/default/functions/accessibility/README.md +0 -134
- package/src/modules/default/functions/accessibility/accessibility.ts +0 -54
- package/src/modules/default/functions/accordion/README.md +0 -451
- package/src/modules/default/functions/accordion/accordion.ts +0 -189
- package/src/modules/default/functions/comparison/comparison.ts +0 -424
- package/src/modules/default/functions/marquee/marquee.ts +0 -206
- package/src/modules/default/functions/navbar/README.md +0 -393
- package/src/modules/default/functions/navbar/functions/arrow-navigation/arrow-navigation.ts +0 -183
- package/src/modules/default/functions/navbar/functions/dropdown/dropdown.ts +0 -313
- package/src/modules/default/functions/navbar/functions/menu/menu.ts +0 -315
- package/src/modules/default/functions/navbar/navbar.ts +0 -51
- package/src/modules/default/functions/smooth-scroll/README.md +0 -417
- package/src/modules/default/functions/smooth-scroll/smooth-scroll.ts +0 -115
- package/src/modules/default/functions/transition/README.md +0 -328
- package/src/modules/default/functions/transition/transition.ts +0 -290
- package/src/modules/normalize/README.md +0 -172
- package/src/modules/normalize/functions/clickable/README.md +0 -84
- package/src/modules/normalize/functions/clickable/clickable.ts +0 -43
- package/src/modules/normalize/functions/clickable/functions/normalize/README.md +0 -213
- package/src/modules/normalize/functions/clickable/functions/normalize/normalize.ts +0 -68
- package/src/modules/normalize/functions/dupe/README.md +0 -405
- package/src/modules/normalize/functions/dupe/dupe.ts +0 -197
- package/src/modules/normalize/functions/sync/sync.ts +0 -378
- package/src/modules/normalize/normalize.ts +0 -58
- package/src/modules/structure/README.md +0 -190
- package/src/modules/structure/functions/form/README.md +0 -94
- package/src/modules/structure/functions/form/form.ts +0 -54
- package/src/modules/structure/functions/form/functions/honeypot/README.md +0 -77
- package/src/modules/structure/functions/form/functions/honeypot/honeypot.ts +0 -37
- package/src/modules/structure/functions/form/functions/range/README.md +0 -410
- package/src/modules/structure/functions/form/functions/range/range.ts +0 -92
- package/src/modules/structure/functions/form/functions/select/README.md +0 -393
- package/src/modules/structure/functions/form/functions/select/functions/custom-select/custom-select.ts +0 -637
- package/src/modules/structure/functions/form/functions/select/functions/states/states.ts +0 -118
- package/src/modules/structure/functions/form/functions/select/select.ts +0 -48
- package/src/modules/structure/functions/form/functions/test/test.ts +0 -132
- package/src/modules/structure/functions/pagination/README.md +0 -527
- package/src/modules/structure/functions/pagination/pagination.ts +0 -493
- package/src/modules/structure/functions/site-settings/README.md +0 -395
- package/src/modules/structure/functions/site-settings/site-settings.ts +0 -158
- package/src/modules/structure/functions/toc/README.md +0 -82
- package/src/modules/structure/functions/toc/functions/heading-links/heading-links.ts +0 -171
- package/src/modules/structure/functions/toc/functions/progress-bar/progress-bar.ts +0 -101
- package/src/modules/structure/functions/toc/toc.ts +0 -35
- package/src/modules/structure/functions/year-replacement/README.md +0 -55
- package/src/modules/structure/functions/year-replacement/year-replacement.ts +0 -59
- package/src/modules/structure/structure.ts +0 -59
- package/src/utils/attributeSelector.ts +0 -78
- package/src/utils/cssVariables.ts +0 -24
- package/src/utils/gsap.ts +0 -198
- package/src/utils/heightAnimator.ts +0 -130
- package/src/utils/modalManager.ts +0 -150
- package/src/utils.ts +0 -54
- package/tsconfig.json +0 -24
- package/vite.config.js +0 -45
package/src/utils/gsap.ts
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GSAP Global Handler
|
|
3
|
-
*
|
|
4
|
-
* Centralized GSAP detection and error handling.
|
|
5
|
-
* Provides type-safe access to GSAP and ScrollTrigger.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* import { getGsap, hasGsap } from '@utils';
|
|
9
|
-
*
|
|
10
|
-
* if (hasGsap()) {
|
|
11
|
-
* const { gsap, ScrollTrigger } = getGsap();
|
|
12
|
-
* gsap.to(element, { opacity: 1 });
|
|
13
|
-
* }
|
|
14
|
-
*
|
|
15
|
-
* @version 2.0.0
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
// Type definitions for externally loaded GSAP
|
|
19
|
-
interface GsapPlugin {
|
|
20
|
-
create: (config: unknown) => void;
|
|
21
|
-
getAll: () => unknown[];
|
|
22
|
-
refresh: () => void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface GsapDraggable {
|
|
26
|
-
create: (target: unknown, vars?: Record<string, unknown>) => unknown[];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface GsapInstance {
|
|
30
|
-
to: (target: unknown, vars: Record<string, unknown>) => unknown;
|
|
31
|
-
from: (target: unknown, vars: Record<string, unknown>) => unknown;
|
|
32
|
-
set: (target: unknown, vars: Record<string, unknown>) => unknown;
|
|
33
|
-
timeline: (vars?: Record<string, unknown>) => unknown;
|
|
34
|
-
registerPlugin: (...plugins: unknown[]) => void;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Declare global types for GSAP (loaded externally)
|
|
38
|
-
declare global {
|
|
39
|
-
interface Window {
|
|
40
|
-
gsap?: GsapInstance;
|
|
41
|
-
ScrollTrigger?: GsapPlugin;
|
|
42
|
-
Draggable?: GsapDraggable;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let hasWarned = false;
|
|
47
|
-
let globalScrollVelocity = 0;
|
|
48
|
-
let globalScrollDirection = 0; // 1 = down, -1 = up, 0 = not scrolling
|
|
49
|
-
let scrollVelocityInitialized = false;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Initialize global scroll velocity tracking
|
|
53
|
-
* Call this once to start tracking scroll velocity across the entire page
|
|
54
|
-
*/
|
|
55
|
-
export function initScrollVelocityTracking() {
|
|
56
|
-
if (scrollVelocityInitialized || !hasScrollTrigger()) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const gsap = window.gsap!;
|
|
61
|
-
|
|
62
|
-
// Track scroll position and smooth velocity
|
|
63
|
-
let lastScrollY = window.scrollY;
|
|
64
|
-
let lastTime = performance.now();
|
|
65
|
-
let targetVelocity = 0;
|
|
66
|
-
let currentVelocity = 0;
|
|
67
|
-
|
|
68
|
-
// Update target velocity and direction on scroll
|
|
69
|
-
window.ScrollTrigger!.create({
|
|
70
|
-
onUpdate: () => {
|
|
71
|
-
const currentScrollY = window.scrollY;
|
|
72
|
-
const currentTime = performance.now();
|
|
73
|
-
const deltaY = currentScrollY - lastScrollY;
|
|
74
|
-
const deltaTime = currentTime - lastTime;
|
|
75
|
-
|
|
76
|
-
// Update scroll direction
|
|
77
|
-
if (deltaY > 0) {
|
|
78
|
-
globalScrollDirection = 1; // Scrolling down
|
|
79
|
-
} else if (deltaY < 0) {
|
|
80
|
-
globalScrollDirection = -1; // Scrolling up
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Calculate velocity in pixels per second (framerate-independent)
|
|
84
|
-
// Avoid division by zero
|
|
85
|
-
if (deltaTime > 0) {
|
|
86
|
-
targetVelocity = (Math.abs(deltaY) / deltaTime) * 1000; // Convert to pixels/second
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
lastScrollY = currentScrollY;
|
|
90
|
-
lastTime = currentTime;
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Smoothly lerp current velocity to target velocity every frame
|
|
95
|
-
gsap.ticker.add(() => {
|
|
96
|
-
// Lerp factor: lower = smoother (0.08 for buttery smooth)
|
|
97
|
-
const lerpFactor = 0.08;
|
|
98
|
-
|
|
99
|
-
// Interpolate current velocity towards target
|
|
100
|
-
currentVelocity += (targetVelocity - currentVelocity) * lerpFactor;
|
|
101
|
-
|
|
102
|
-
// Decay target velocity (simulates friction) - slower decay for smoothness
|
|
103
|
-
targetVelocity *= 0.95;
|
|
104
|
-
|
|
105
|
-
// Snap to zero when very small
|
|
106
|
-
if (Math.abs(currentVelocity) < 0.1) {
|
|
107
|
-
currentVelocity = 0;
|
|
108
|
-
}
|
|
109
|
-
if (Math.abs(targetVelocity) < 0.1) {
|
|
110
|
-
targetVelocity = 0;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Update global velocity
|
|
114
|
-
globalScrollVelocity = currentVelocity;
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
scrollVelocityInitialized = true;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Get current scroll velocity
|
|
122
|
-
* @returns Current scroll velocity (pixels per second)
|
|
123
|
-
*/
|
|
124
|
-
export function getScrollVelocity(): number {
|
|
125
|
-
return globalScrollVelocity;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get current scroll direction
|
|
130
|
-
* @returns 1 for down, -1 for up, 0 for not scrolling
|
|
131
|
-
*/
|
|
132
|
-
export function getScrollDirection(): number {
|
|
133
|
-
return globalScrollDirection;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Check if GSAP is available
|
|
138
|
-
*/
|
|
139
|
-
export function hasGsap(): boolean {
|
|
140
|
-
return typeof window.gsap !== 'undefined';
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Check if ScrollTrigger is available
|
|
145
|
-
*/
|
|
146
|
-
export function hasScrollTrigger(): boolean {
|
|
147
|
-
return typeof window.ScrollTrigger !== 'undefined';
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Check if Draggable is available
|
|
152
|
-
*/
|
|
153
|
-
export function hasDraggable(): boolean {
|
|
154
|
-
return typeof window.Draggable !== 'undefined';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Get GSAP instance with type safety
|
|
159
|
-
* @param moduleName - Name of the module requesting GSAP (for logging)
|
|
160
|
-
* @param required - Whether GSAP is required (default: true)
|
|
161
|
-
* @returns GSAP instance or null if not available
|
|
162
|
-
*/
|
|
163
|
-
export function getGsap(moduleName?: string, required: boolean = true) {
|
|
164
|
-
if (!hasGsap()) {
|
|
165
|
-
if (required && !hasWarned) {
|
|
166
|
-
console.warn(
|
|
167
|
-
'[gsap] GSAP library not detected. Some animations will be skipped. ' +
|
|
168
|
-
'Add GSAP to your project: https://greensock.com/docs/v3/Installation'
|
|
169
|
-
);
|
|
170
|
-
hasWarned = true;
|
|
171
|
-
} else if (moduleName && !hasWarned) {
|
|
172
|
-
console.warn(`[${moduleName}] GSAP not available, module will use fallback behavior`);
|
|
173
|
-
hasWarned = true;
|
|
174
|
-
}
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
gsap: window.gsap!,
|
|
180
|
-
ScrollTrigger: window.ScrollTrigger,
|
|
181
|
-
Draggable: window.Draggable,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Reset warning state (useful for testing)
|
|
187
|
-
*/
|
|
188
|
-
export function resetGsapWarning() {
|
|
189
|
-
hasWarned = false;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Check if user prefers reduced motion
|
|
194
|
-
* @returns true if user prefers reduced motion
|
|
195
|
-
*/
|
|
196
|
-
export function prefersReducedMotion(): boolean {
|
|
197
|
-
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
198
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global height animation utility with singleton pattern
|
|
3
|
-
* Handles GSAP height animations with customizable duration and easing
|
|
4
|
-
*
|
|
5
|
-
* Uses config from @config for all attribute names
|
|
6
|
-
* Supports per-element customization via attributes
|
|
7
|
-
*
|
|
8
|
-
* @version 2.0.0
|
|
9
|
-
*/
|
|
10
|
-
import config from '@config';
|
|
11
|
-
import { getGsap, prefersReducedMotion } from './gsap.ts';
|
|
12
|
-
|
|
13
|
-
class HeightAnimator {
|
|
14
|
-
#activeAnimations = new Map();
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Animate element height to open or closed state
|
|
18
|
-
* @param {HTMLElement} element - Container element (may contain height target)
|
|
19
|
-
* @param {boolean} isOpen - True to open (height: auto), false to close (height: 0)
|
|
20
|
-
* @param {Object} options - Animation options
|
|
21
|
-
* @param {number} options.duration - Duration in milliseconds (default: 300)
|
|
22
|
-
* @param {string} options.ease - GSAP easing function (default: 'power2.inOut')
|
|
23
|
-
*/
|
|
24
|
-
async animate(element, isOpen, options = {}) {
|
|
25
|
-
const gsapLib = getGsap('heightAnimator');
|
|
26
|
-
if (!gsapLib) return;
|
|
27
|
-
|
|
28
|
-
const { gsap } = gsapLib;
|
|
29
|
-
|
|
30
|
-
const heightAttr = config._global.attributes.height;
|
|
31
|
-
const heightValue = config._global.attributes.heightValue;
|
|
32
|
-
const durationAttr = config._global.attributes.heightDuration;
|
|
33
|
-
const easeAttr = config._global.attributes.heightEase;
|
|
34
|
-
|
|
35
|
-
// Check for custom height target element
|
|
36
|
-
const heightTarget =
|
|
37
|
-
element.hasAttribute?.(heightAttr) && element.getAttribute(heightAttr) === heightValue
|
|
38
|
-
? element
|
|
39
|
-
: element.querySelector?.(`[${heightAttr}="${heightValue}"]`) || element;
|
|
40
|
-
|
|
41
|
-
// Cancel existing animation on this element
|
|
42
|
-
const existingAnim = this.#activeAnimations.get(heightTarget);
|
|
43
|
-
if (existingAnim) {
|
|
44
|
-
existingAnim.kill();
|
|
45
|
-
this.#activeAnimations.delete(heightTarget);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Get attributes - check both the target AND its parent wrapper
|
|
49
|
-
let durationValue = heightTarget.getAttribute(durationAttr);
|
|
50
|
-
let easeValue = heightTarget.getAttribute(easeAttr);
|
|
51
|
-
|
|
52
|
-
// If not found on target, check parent wrapper
|
|
53
|
-
if (!durationValue && heightTarget.parentElement) {
|
|
54
|
-
durationValue = heightTarget.parentElement.getAttribute(durationAttr);
|
|
55
|
-
}
|
|
56
|
-
if (!easeValue && heightTarget.parentElement) {
|
|
57
|
-
easeValue = heightTarget.parentElement.getAttribute(easeAttr);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Fallback chain: attribute > options > default
|
|
61
|
-
let duration = durationValue
|
|
62
|
-
? parseInt(durationValue, 10) / 1000
|
|
63
|
-
: (options.duration || 300) / 1000;
|
|
64
|
-
|
|
65
|
-
// Force instant updates if user prefers reduced motion
|
|
66
|
-
if (prefersReducedMotion()) {
|
|
67
|
-
duration = 0;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const ease = easeValue || options.ease || 'power2.inOut';
|
|
71
|
-
|
|
72
|
-
// Create animation
|
|
73
|
-
const animation = gsap.to(heightTarget, {
|
|
74
|
-
height: isOpen ? 'auto' : 0,
|
|
75
|
-
duration: duration,
|
|
76
|
-
ease: ease,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Track active animation
|
|
80
|
-
this.#activeAnimations.set(heightTarget, animation);
|
|
81
|
-
|
|
82
|
-
// Wait for animation to complete
|
|
83
|
-
try {
|
|
84
|
-
await animation.then();
|
|
85
|
-
} finally {
|
|
86
|
-
this.#activeAnimations.delete(heightTarget);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Set element height immediately without animation (for initial state)
|
|
92
|
-
* @param {HTMLElement} element - Container element (may contain height target)
|
|
93
|
-
* @param {boolean} isOpen - True for auto height, false for 0
|
|
94
|
-
*/
|
|
95
|
-
setHeight(element, isOpen) {
|
|
96
|
-
const gsapLib = getGsap('heightAnimator');
|
|
97
|
-
if (!gsapLib) return;
|
|
98
|
-
|
|
99
|
-
const { gsap } = gsapLib;
|
|
100
|
-
|
|
101
|
-
const heightAttr = config._global.attributes.height;
|
|
102
|
-
const heightValue = config._global.attributes.heightValue;
|
|
103
|
-
|
|
104
|
-
// Check for custom height target element
|
|
105
|
-
const heightTarget =
|
|
106
|
-
element.hasAttribute?.(heightAttr) && element.getAttribute(heightAttr) === heightValue
|
|
107
|
-
? element
|
|
108
|
-
: element.querySelector?.(`[${heightAttr}="${heightValue}"]`) || element;
|
|
109
|
-
|
|
110
|
-
// Set immediately without animation
|
|
111
|
-
gsap.set(heightTarget, {
|
|
112
|
-
height: isOpen ? 'auto' : 0,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Cancel all active animations (for cleanup)
|
|
118
|
-
*/
|
|
119
|
-
cancelAll() {
|
|
120
|
-
this.#activeAnimations.forEach((anim) => anim.kill());
|
|
121
|
-
this.#activeAnimations.clear();
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Export singleton instance
|
|
126
|
-
export const heightAnimator = new HeightAnimator();
|
|
127
|
-
|
|
128
|
-
// Export bound methods for convenience
|
|
129
|
-
export const animateHeight = heightAnimator.animate.bind(heightAnimator);
|
|
130
|
-
export const setHeight = heightAnimator.setHeight.bind(heightAnimator);
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global modal manager with extensible hooks
|
|
3
|
-
* Handles body classes and allows custom callbacks for modal open/close
|
|
4
|
-
* Uses reference counting to support multiple modals open simultaneously
|
|
5
|
-
*
|
|
6
|
-
* Class names configured via @config for easy customization
|
|
7
|
-
*
|
|
8
|
-
* Usage (internal):
|
|
9
|
-
* import { openModal, closeModal } from '@utils/modalManager.js';
|
|
10
|
-
* openModal(); // Register modal as open
|
|
11
|
-
* closeModal(); // Register modal as closed
|
|
12
|
-
*
|
|
13
|
-
* Usage (external):
|
|
14
|
-
* window.HS.modal.open();
|
|
15
|
-
* window.HS.modal.close();
|
|
16
|
-
* window.HS.modal.onOpen(() => window.lenis?.stop());
|
|
17
|
-
* window.HS.modal.onClose(() => window.lenis?.start());
|
|
18
|
-
*
|
|
19
|
-
* @version 2.0.0
|
|
20
|
-
*/
|
|
21
|
-
import config from '@config';
|
|
22
|
-
|
|
23
|
-
let activeModalCount = 0;
|
|
24
|
-
const openCallbacks = [];
|
|
25
|
-
const closeCallbacks = [];
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Register a callback to run when first modal opens
|
|
29
|
-
* @param {Function} callback - Function to run on modal open
|
|
30
|
-
* @returns {Function} Unregister function
|
|
31
|
-
*/
|
|
32
|
-
export function onModalOpen(callback) {
|
|
33
|
-
if (typeof callback !== 'function') {
|
|
34
|
-
console.warn('[modalManager] onModalOpen requires a function');
|
|
35
|
-
return () => {};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
openCallbacks.push(callback);
|
|
39
|
-
|
|
40
|
-
// Return unregister function
|
|
41
|
-
return () => {
|
|
42
|
-
const index = openCallbacks.indexOf(callback);
|
|
43
|
-
if (index > -1) openCallbacks.splice(index, 1);
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Register a callback to run when last modal closes
|
|
49
|
-
* @param {Function} callback - Function to run on modal close
|
|
50
|
-
* @returns {Function} Unregister function
|
|
51
|
-
*/
|
|
52
|
-
export function onModalClose(callback) {
|
|
53
|
-
if (typeof callback !== 'function') {
|
|
54
|
-
console.warn('[modalManager] onModalClose requires a function');
|
|
55
|
-
return () => {};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
closeCallbacks.push(callback);
|
|
59
|
-
|
|
60
|
-
// Return unregister function
|
|
61
|
-
return () => {
|
|
62
|
-
const index = closeCallbacks.indexOf(callback);
|
|
63
|
-
if (index > -1) closeCallbacks.splice(index, 1);
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Register a modal as open
|
|
69
|
-
* Increments modal count and applies body classes when first modal opens
|
|
70
|
-
*/
|
|
71
|
-
export function openModal() {
|
|
72
|
-
activeModalCount++;
|
|
73
|
-
|
|
74
|
-
// Only apply effects when first modal opens
|
|
75
|
-
if (activeModalCount === 1) {
|
|
76
|
-
const modalOpenClass = config._global.classes.modalOpen;
|
|
77
|
-
const overflowHiddenClass = config._global.classes.overflowHidden;
|
|
78
|
-
|
|
79
|
-
document.body.classList.add(overflowHiddenClass, modalOpenClass);
|
|
80
|
-
|
|
81
|
-
// Run all registered open callbacks
|
|
82
|
-
openCallbacks.forEach((callback) => {
|
|
83
|
-
try {
|
|
84
|
-
callback();
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.error('[modalManager] Error in open callback:', error);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Register a modal as closed
|
|
94
|
-
* Decrements modal count and removes body classes when last modal closes
|
|
95
|
-
*/
|
|
96
|
-
export function closeModal() {
|
|
97
|
-
activeModalCount--;
|
|
98
|
-
|
|
99
|
-
// Only remove effects when last modal closes
|
|
100
|
-
if (activeModalCount === 0) {
|
|
101
|
-
const modalOpenClass = config._global.classes.modalOpen;
|
|
102
|
-
const overflowHiddenClass = config._global.classes.overflowHidden;
|
|
103
|
-
|
|
104
|
-
document.body.classList.remove(overflowHiddenClass, modalOpenClass);
|
|
105
|
-
|
|
106
|
-
// Run all registered close callbacks
|
|
107
|
-
closeCallbacks.forEach((callback) => {
|
|
108
|
-
try {
|
|
109
|
-
callback();
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error('[modalManager] Error in close callback:', error);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Safety: prevent negative count
|
|
117
|
-
if (activeModalCount < 0) {
|
|
118
|
-
console.warn('[modalManager] Modal count went negative, resetting to 0');
|
|
119
|
-
activeModalCount = 0;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Get current modal count (for debugging)
|
|
125
|
-
* @returns {number} Number of active modals
|
|
126
|
-
*/
|
|
127
|
-
export function getActiveModalCount() {
|
|
128
|
-
return activeModalCount;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Check if any modals are currently open
|
|
133
|
-
* @returns {boolean} True if at least one modal is open
|
|
134
|
-
*/
|
|
135
|
-
export function isModalOpen() {
|
|
136
|
-
return activeModalCount > 0;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Expose globally for external scripts
|
|
140
|
-
if (typeof window !== 'undefined') {
|
|
141
|
-
window.HS = window.HS || {};
|
|
142
|
-
window.HS.modal = {
|
|
143
|
-
open: openModal,
|
|
144
|
-
close: closeModal,
|
|
145
|
-
getCount: getActiveModalCount,
|
|
146
|
-
isOpen: isModalOpen,
|
|
147
|
-
onOpen: onModalOpen,
|
|
148
|
-
onClose: onModalClose,
|
|
149
|
-
};
|
|
150
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Centralized utils export
|
|
3
|
-
*
|
|
4
|
-
* Barrel export for all utility functions to enable cleaner imports.
|
|
5
|
-
* Instead of multiple relative imports, modules can import from a single source.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* import { getSelector, animateHeight, openModal } from '../../src/utils.js';
|
|
9
|
-
*
|
|
10
|
-
* @version 2.0.0
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// Attribute selector utilities
|
|
14
|
-
export {
|
|
15
|
-
getSelector,
|
|
16
|
-
querySelectorAll,
|
|
17
|
-
querySelector,
|
|
18
|
-
checkDeprecated,
|
|
19
|
-
} from './utils/attributeSelector.ts';
|
|
20
|
-
|
|
21
|
-
// Height animation utilities
|
|
22
|
-
export { animateHeight, setHeight } from './utils/heightAnimator.ts';
|
|
23
|
-
|
|
24
|
-
// Modal manager utilities
|
|
25
|
-
export {
|
|
26
|
-
openModal,
|
|
27
|
-
closeModal,
|
|
28
|
-
onModalOpen,
|
|
29
|
-
onModalClose,
|
|
30
|
-
getActiveModalCount,
|
|
31
|
-
isModalOpen,
|
|
32
|
-
} from './utils/modalManager.ts';
|
|
33
|
-
|
|
34
|
-
// Import config to extract globalConfig
|
|
35
|
-
import config from '@config';
|
|
36
|
-
|
|
37
|
-
// Export globalConfig from master config
|
|
38
|
-
export const globalConfig = config._global;
|
|
39
|
-
|
|
40
|
-
// CSS variables utility (default export becomes named export)
|
|
41
|
-
export { default as cssVariables } from './utils/cssVariables.ts';
|
|
42
|
-
|
|
43
|
-
// GSAP utilities
|
|
44
|
-
export {
|
|
45
|
-
getGsap,
|
|
46
|
-
hasGsap,
|
|
47
|
-
hasScrollTrigger,
|
|
48
|
-
hasDraggable,
|
|
49
|
-
resetGsapWarning,
|
|
50
|
-
prefersReducedMotion,
|
|
51
|
-
initScrollVelocityTracking,
|
|
52
|
-
getScrollVelocity,
|
|
53
|
-
getScrollDirection,
|
|
54
|
-
} from './utils/gsap.ts';
|
package/tsconfig.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"moduleResolution": "bundler",
|
|
7
|
-
"resolveJsonModule": true,
|
|
8
|
-
"allowImportingTsExtensions": true,
|
|
9
|
-
"noEmit": true,
|
|
10
|
-
"strict": false,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"esModuleInterop": true,
|
|
13
|
-
"allowSyntheticDefaultImports": true,
|
|
14
|
-
"forceConsistentCasingInFileNames": true,
|
|
15
|
-
"paths": {
|
|
16
|
-
"@utils": ["./src/utils.ts"],
|
|
17
|
-
"@utils/*": ["./src/utils/*"],
|
|
18
|
-
"@config": ["./src/config.ts"],
|
|
19
|
-
"@modules/*": ["./src/modules/*"]
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"include": ["src/**/*", "index.ts", "*.d.ts"],
|
|
23
|
-
"exclude": ["node_modules", "dist"]
|
|
24
|
-
}
|
package/vite.config.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { resolve, dirname } from 'path';
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import compression from 'vite-plugin-compression';
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = dirname(__filename);
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
server: {
|
|
10
|
-
cors: true,
|
|
11
|
-
},
|
|
12
|
-
resolve: {
|
|
13
|
-
alias: {
|
|
14
|
-
'@utils/': resolve(__dirname, './src/utils/'),
|
|
15
|
-
'@utils': resolve(__dirname, './src/utils.ts'),
|
|
16
|
-
'@config': resolve(__dirname, './src/config.ts'),
|
|
17
|
-
'@modules/': resolve(__dirname, './src/modules/'),
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
plugins: [compression({ algorithm: 'brotli' }), compression({ algorithm: 'gzip' })],
|
|
21
|
-
build: {
|
|
22
|
-
outDir: 'dist',
|
|
23
|
-
sourcemap: true,
|
|
24
|
-
rollupOptions: {
|
|
25
|
-
input: {
|
|
26
|
-
main: resolve(__dirname, './index.ts'),
|
|
27
|
-
bootstrap: resolve(__dirname, './public/bootstrap.js'),
|
|
28
|
-
},
|
|
29
|
-
output: {
|
|
30
|
-
entryFileNames: '[name].js',
|
|
31
|
-
format: 'es',
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
minify: 'terser',
|
|
35
|
-
terserOptions: {
|
|
36
|
-
compress: {
|
|
37
|
-
drop_console: false,
|
|
38
|
-
drop_debugger: true,
|
|
39
|
-
},
|
|
40
|
-
format: {
|
|
41
|
-
comments: false,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
};
|