UNPKG

@sc4rfurryx/proteusjs

Version:

The Modern Web Development Framework for Accessible, Responsive, and High-Performance Applications. Intelligent container queries, fluid typography, WCAG compliance, and performance optimization.

121 lines (119 loc) 3.61 kB
/*! * ProteusJS v2.0.0 * Shape-shifting responsive design that adapts like the sea god himself * (c) 2025 sc4rfurry * Released under the MIT License */ /** * @sc4rfurryx/proteusjs/transitions * View Transitions API wrapper with safe fallbacks * * @version 2.0.0 * @author sc4rfurry * @license MIT */ /** * One API for animating DOM state changes and cross-document navigations * using the View Transitions API with safe fallbacks. */ async function transition(run, opts = {}) { const { name, duration = 300, onBefore, onAfter, allowInterrupt = true } = opts; // Check for View Transitions API support const hasViewTransitions = 'startViewTransition' in document; if (onBefore) { onBefore(); } if (!hasViewTransitions) { // Fallback: run immediately without transitions try { await run(); } finally { if (onAfter) { onAfter(); } } return; } // Use native View Transitions API try { const viewTransition = document.startViewTransition(async () => { await run(); }); // Add CSS view-transition-name if name provided if (name) { const style = document.createElement('style'); style.textContent = ` ::view-transition-old(${name}), ::view-transition-new(${name}) { animation-duration: ${duration}ms; } `; document.head.appendChild(style); // Clean up style after transition viewTransition.finished.finally(() => { style.remove(); }); } await viewTransition.finished; } catch (error) { console.warn('View transition failed, falling back to immediate execution:', error); await run(); } finally { if (onAfter) { onAfter(); } } } /** * MPA-friendly navigation with view transitions when supported */ async function navigate(url, opts = {}) { const { name, prerender = false } = opts; // Optional prerender hint (basic implementation) if (prerender && 'speculation' in HTMLScriptElement.prototype) { const script = document.createElement('script'); script.type = 'speculationrules'; script.textContent = JSON.stringify({ prerender: [{ where: { href_matches: url } }] }); document.head.appendChild(script); } // Check for View Transitions API support const hasViewTransitions = 'startViewTransition' in document; if (!hasViewTransitions) { // Fallback: normal navigation window.location.href = url; return; } try { // Use view transitions for navigation const viewTransition = document.startViewTransition(() => { window.location.href = url; }); if (name) { const style = document.createElement('style'); style.textContent = ` ::view-transition-old(${name}), ::view-transition-new(${name}) { animation-duration: 300ms; } `; document.head.appendChild(style); } await viewTransition.finished; } catch (error) { console.warn('View transition navigation failed, falling back to normal navigation:', error); window.location.href = url; } } // Export default object for convenience var index = { transition, navigate }; export { index as default, navigate, transition }; //# sourceMappingURL=transitions.esm.js.map