@hortonstudio/main
v1.9.39
Published
Animation and utility library for client websites
Maintainers
Readme
@hortonstudio/main
Version: 2.0.0
Auto-initializing JavaScript library for Webflow sites with animations, accessibility, and utility functions.
Installation
Standard Installation
<script type="module" src="https://cdn.jsdelivr.net/npm/@hortonstudio/main@2/dist/main.js"></script>
<script>document.documentElement.classList.add('hs-main');!function t(){hsmain?.afterReady?hsmain.afterReady(()=>{hsmainReady=!0,dispatchEvent(new Event('hsmain:ready'))}):setTimeout(t,50)}()</script>Local Development:
<!-- Local testing (run: npm run dev) -->
<script type="module" src="http://localhost:5173/index.ts"></script>
<script>(function(){function w(){if(window.hsmain?.afterReady){window.hsmain.afterReady(function(){window.hsmainReady=true;window.dispatchEvent(new Event('hsmain:ready'))});}else{setTimeout(w,50);}}w();})();</script>SPA Mode (Barba.js, Swup, etc.): Add data-hs-spa="true" to the module loader
<script type="module" src="https://cdn.jsdelivr.net/npm/@hortonstudio/main@2/dist/main.js" data-hs-spa="true"></script>
<script>(function(){function w(){if(window.hsmain?.afterReady){window.hsmain.afterReady(function(){window.hsmainReady=true;window.dispatchEvent(new Event('hsmain:ready'))});}else{setTimeout(w,50);}}w();})();</script>Configuration
// Example: Barba.js integration
barba.hooks.before(() => {
window.dispatchEvent(new CustomEvent('hsmain:transition-exit'));
});
barba.hooks.after(() => {
window.dispatchEvent(new CustomEvent('hsmain:transition-enter'));
});API Usage
External Script Integration
When using external scripts & libraries (Barba.js, GSAP ScrollTrigger, etc.) that need to wait for hsmain to be ready, the inline helper script (included with standard installation) ensures window.hsmain is available.
External scripts should use the callback pattern:
<script>
window.hsmain?.afterReady(() => {
// Your code here
});
</script>Why this works:
The inline helper script (included in standard installation) polls for window.hsmain to exist and calls afterReady() once initialization completes. This guarantees that by the time your external script runs, window.hsmain exists and afterReady() will fire either immediately (if already ready) or when initialization completes.
Cleanup
// Destroy all modules (useful for SPA navigation)
window.hsmain.destroy();
// Reinitialize everything
await window.hsmain.reinitialize();Manual Module Loading
// Load a single module
window.hsmain.load('counter');
// With callback
window.hsmain.push([
'counter',
() => {
console.log('Counter module ready');
},
]);Lifecycle Hooks
// Execute code after all modules load
window.hsmain.afterReady(() => {
console.log('Library fully initialized');
});
// Check module status
const status = window.hsmain.status('counter');
console.log(status); // { loaded: true, loading: false }Modal Manager & Lenis Integration
Modal manager automatically detects and handles Lenis smooth scroll (stops on modal open, starts on close).
// Auto-detection works with zero config
// Just use modals normally - Lenis is handled automatically
// Disable auto Lenis handling if needed
window.HS.modal.setLenisEnabled(false);
// Manual modal control
window.HS.modal.open();
window.HS.modal.close();
// Custom callbacks (run in addition to auto Lenis handling)
window.HS.modal.onOpen(() => {
console.log('Modal opened');
});
window.HS.modal.onClose(() => {
console.log('Modal closed');
});Architecture
- TypeScript: Full type safety with TypeScript source
- Vite Bundled: Optimized build with code splitting (~24kb gzipped total)
- Config-driven: Centralized configuration in
config.json - SPA Compatible: Works with Barba.js, Swup, and other routers
- Memory Safe: Proper cleanup tracking for observers and event handlers
- Phase-based Loading: Optimized initialization sequence
