···11# Animations & Transitions
22+33+VoltX provides a powerful, declarative animation system through two complementary plugins:
44+55+1. **surge** for enter/leave transitions and
66+2. **shift** for CSS keyframe animations.
77+88+Both integrate with the reactivity system and respect user accessibility preferences.
99+1010+## Quick Start
1111+1212+Add transitions to any element with `data-volt-if` or `data-volt-show` by adding `data-volt-surge` with a preset name:
1313+1414+```html
1515+<div data-volt-if="isVisible" data-volt-surge="fade">
1616+ Content fades in and out smoothly
1717+</div>
1818+```
1919+2020+That's it! The surge plugin automatically hooks into the element's lifecycle, applying transitions when it appears or disappears.
2121+2222+## Built-in Presets
2323+2424+VoltX includes ready-to-use transition presets:
2525+2626+| Preset | Description |
2727+| --------------- | --------------------------------- |
2828+| **fade** | Simple opacity transition |
2929+| **slide-up** | Sliding motion with opacity |
3030+| **slide-down** | |
3131+| **slide-left** | |
3232+| **slide-right** | |
3333+| **scale** | Subtle scale effect with opacity |
3434+| **blur** | Blur effect combined with opacity |
3535+3636+All presets are designed with smooth, professional timing curves and 300ms duration by default.
3737+3838+## Surge Plugin: Enter/Leave Transitions
3939+4040+The surge plugin provides two modes of operation: automatic (with if/show bindings) and explicit (signal-based).
4141+4242+### Automatic Mode
4343+4444+When used with `data-volt-if` or `data-volt-show`, surge automatically manages the element's visibility transitions. The element smoothly animates in when the condition becomes true and animates out before removal.
4545+4646+### Explicit Mode
4747+4848+Watch any signal by providing a signal path. The element will transition in/out based on the signal's truthiness:
4949+5050+```html
5151+<div data-volt-surge="showPanel:slide-down">
5252+ Panel slides down when showPanel is true
5353+</div>
5454+```
5555+5656+### Duration and Delay Modifiers
5757+5858+Override preset timing using dot notation:
5959+6060+```html
6161+<!-- 500ms duration -->
6262+<div data-volt-surge="fade.500">...</div>
6363+6464+<!-- 600ms duration, 100ms delay -->
6565+<div data-volt-surge="slide-down.600.100">...</div>
6666+```
6767+6868+### Granular Control
6969+7070+Specify different transitions for enter and leave phases:
7171+7272+```html
7373+<div
7474+ data-volt-if="show"
7575+ data-volt-surge:enter="slide-down.400"
7676+ data-volt-surge:leave="fade.200">
7777+ Slides in, fades out
7878+</div>
7979+```
8080+8181+## Shift Plugin: Keyframe Animations
8282+8383+The shift plugin applies CSS keyframe animations, perfect for attention-grabbing effects and continuous animations.
8484+8585+### Built-in Animations
8686+8787+| Animation | Description |
8888+| ---------- | --------------------------------- |
8989+| **bounce** | Quick bounce effect |
9090+| **shake** | Horizontal shake motion |
9191+| **pulse** | Subtle pulsing scale (continuous) |
9292+| **spin** | Full rotation (continuous) |
9393+| **flash** | Opacity flash effect |
9494+9595+### One-Time Animations
9696+9797+Apply animation when element mounts:
9898+9999+```html
100100+<button data-volt-shift="bounce">Bounces on mount</button>
101101+```
102102+103103+### Signal-Triggered Animations
104104+105105+Trigger animations based on signal changes:
106106+107107+```html
108108+<div data-volt-shift="error:shake.600.2">
109109+ Shakes twice when error becomes truthy
110110+</div>
111111+```
112112+113113+The syntax supports duration and iteration overrides: `animationName.duration.iterations`
114114+115115+## View Transitions API
116116+117117+VoltX automatically uses the View Transitions API when available, providing native browser-level transitions for ultra-smooth visual updates.
118118+The system gracefully falls back to CSS transitions on unsupported browsers.
119119+120120+For advanced use cases, manually trigger view transitions using `startViewTransition` or `namedViewTransition` from the programmatic API.
121121+122122+## Custom Presets (Programmatic Mode)
123123+124124+Register custom transitions for reuse across your application:
125125+126126+```javascript
127127+import { registerTransition } from "voltx.js";
128128+129129+registerTransition("custom-slide", {
130130+ enter: {
131131+ from: { opacity: 0, transform: "translateX(-100px)" },
132132+ to: { opacity: 1, transform: "translateX(0)" },
133133+ duration: 400,
134134+ easing: "cubic-bezier(0.4, 0, 0.2, 1)",
135135+ },
136136+ leave: {
137137+ from: { opacity: 1, transform: "translateX(0)" },
138138+ to: { opacity: 0, transform: "translateX(100px)" },
139139+ duration: 300,
140140+ easing: "ease-out",
141141+ },
142142+});
143143+```
144144+145145+Similarly, register custom shift animations with `registerAnimation`.
146146+147147+## Easing Functions
148148+149149+Surge supports standard CSS easing values plus extended named easings:
150150+151151+- Standard: `linear`, `ease`, `ease-in`, `ease-out`, `ease-in-out`
152152+- Extended: `ease-in-sine`, `ease-out-quad`, `ease-in-out-cubic`, `ease-in-back`
153153+154154+Custom cubic-bezier values are also supported.
155155+156156+## Integration with Bindings
157157+158158+- With `data-volt-if`, surge defers element insertion/removal until transitions complete, preventing visual glitches.
159159+- With `data-volt-show`, surge manages display property changes around the transition lifecycle.
160160+- Simply add `data-volt-surge` to elements already using these bindings.
161161+162162+## Accessibility
163163+164164+The animation system automatically respects the `prefers-reduced-motion` media query. When enabled, animations are skipped or significantly reduced, instantly applying final states instead.
165165+166166+Both surge and shift plugins honor this setting by default, ensuring your application remains accessible without additional configuration.
+2-4
docs/overview.md
···22outline: deep
33---
4455-# Framework Overview
55+# Overview
6677VoltX is a lightweight, hypermedia based reactive framework for building declarative UIs.
88···43434444## Browser Support
45454646-Modern browsers with support for:
4646+Modern browsers (Chrome 90+, Firefox 88+, Safari 14+) with support for:
47474848- ES modules
4949- Proxy objects
5050- CSS custom properties
5151-5252-Chrome 90+, Firefox 88+, Safari 14+
···11+# Routing
22+33+Client-side routing lets VoltX applications feel like multi-page sites without full page reloads.
44+The `url` plugin keeps a signal in sync with the browser URL so your application can react declaratively to route changes.
55+This guide walks through building a hash-based router that swaps entire page sections while preserving the advantages
66+of VoltX's signal system.
77+88+## Why?
99+1010+- **Zero reloads:** Route changes update `window.location.hash` via `history.pushState`, so the browser history stack is maintained while the document stays mounted and stateful widgets keep their values.
1111+- **Shareable URLs:** Users can refresh or share a link such as `/#/pricing` and land directly on the same view.
1212+- **Declarative rendering:** Routing is just another signal; templates choose what to display with conditional bindings like `data-volt-if` or `data-volt-show`.
1313+- **Simple integration:** No extra router dependency is required—register the plugin once and opt-in per signal.
1414+1515+> The plugin also supports synchronising signals with query parameters (`read:` and `sync:` modes).
1616+> For multi-page navigation the `hash:` mode is the simplest option because it avoids server configuration and works on static hosting.
1717+1818+## How?
1919+2020+1. Install Volt normally (see [Installation](../installation.md)).
2121+2. Register the plugin before calling `charge()` or `mount()`:
2222+2323+ ```html
2424+ <script type="module">
2525+ import {
2626+ charge,
2727+ registerPlugin,
2828+ urlPlugin,
2929+ } from 'https://unpkg.com/voltx.js@latest/dist/volt.js';
3030+3131+ registerPlugin('url', urlPlugin);
3232+ charge();
3333+ </script>
3434+ ```
3535+3636+3. In your markup, opt a signal into hash synchronisation with `data-volt-url="hash:signalName"`.
3737+3838+## Building a multi-page shell
3939+4040+The example below delivers a three-page marketing site entirely on the client. Each "page" is a section that only renders
4141+when the current route matches its slug.
4242+4343+```html
4444+<main
4545+ data-volt
4646+ data-volt-state='{"route": "home"}'
4747+ data-volt-url="hash:route">
4848+ <nav>
4949+ <button data-volt-class:active="route === 'home'" data-volt-on-click="route.set('home')">
5050+ Home
5151+ </button>
5252+ <button data-volt-class:active="route === 'pricing'" data-volt-on-click="route.set('pricing')">
5353+ Pricing
5454+ </button>
5555+ <button data-volt-class:active="route === 'about'" data-volt-on-click="route.set('about')">
5656+ About
5757+ </button>
5858+ </nav>
5959+6060+ <section data-volt-if="route === 'home'">
6161+ <h1>Volt</h1>
6262+ <p>A lightning-fast reactive runtime for the DOM.</p>
6363+ </section>
6464+6565+ <section data-volt-if="route === 'pricing'">
6666+ <h1>Pricing</h1>
6767+ <ul>
6868+ <li>Starter — $0</li>
6969+ <li>Team — $29</li>
7070+ <li>Enterprise — Contact us</li>
7171+ </ul>
7272+ </section>
7373+7474+ <section data-volt-if="route === 'about'">
7575+ <h1>About</h1>
7676+ <p>Learn more about the Volt runtime and ecosystem.</p>
7777+ </section>
7878+7979+ <section data-volt-if="route !== 'home' && route !== 'pricing' && route !== 'about'">
8080+ <h1>Not found</h1>
8181+ <p data-volt-text="'No page named \"' + route + '\"'"></p>
8282+ <button data-volt-on-click="route.set('home')">Return home</button>
8383+ </section>
8484+</main>
8585+```
8686+8787+### How it works
8888+8989+- On first mount, the plugin reads `window.location.hash` and updates the `route` signal (defaulting to `"home"` if empty).
9090+- Clicking navigation buttons calls `route.set(...)`, which updates the signal and immediately pushes the new hash to history.
9191+ The hash-change event also keeps the signal in sync when the user clicks the browser back button.
9292+- Each section uses `data-volt-if` to opt-in to rendering when the `route` value matches.
9393+ Volt removes sections that no longer match, so each "page" has a distinct DOM subtree.
9494+9595+You can style the `"active"` class however you like; it toggles purely through declarative class bindings.
9696+9797+## Linking with anchors
9898+9999+Prefer plain `<a>` elements when appropriate so the browser shows the target hash in tooltips and lets users open the route in new tabs:
100100+101101+```html
102102+<a href="#pricing" data-volt-on-click="route.set('pricing')">Pricing</a>
103103+```
104104+105105+Setting `href="#pricing"` ensures non-JavaScript fallbacks still land on the right section, while the click handler keeps
106106+the signal aligned with the hash plugin.
107107+108108+## Nested & Computed Routes
109109+110110+Because the route is just a string signal, you can derive extra information using computed signals or watchers:
111111+112112+```html
113113+<div
114114+ data-volt
115115+ data-volt-state='{"route": "home"}'
116116+ data-volt-url="hash:route"
117117+ data-volt-computed:segments="route.split('/')">
118118+ <p data-volt-text="'Section: ' + segments[0]"></p>
119119+ <p data-volt-if="segments.length > 1" data-volt-text="'Item: ' + segments[1]"></p>
120120+</div>
121121+```
122122+123123+Use this pattern to build nested routes like `#/blog/introducing-volt`. Parse the segments in a computed signal and update child components accordingly.
124124+125125+For richer logic (e.g., mapping slugs to component functions), register a handler in `data-volt-methods` or mount with the programmatic API.
126126+This would allow something like a switch statement or usage of a look up of route definitions in a collection.
127127+128128+## Preserving State
129129+130130+Client-side routing works best when page-level state lives alongside the route signal.
131131+Volt keeps signals alive as long as their elements remain mounted, so consider nesting pages inside `data-volt-if` blocks that wrap the entire section.
132132+When you need to reset state upon navigation, call `.set()` explicitly inside your route change handlers or watch the `route` signal and perform cleanup in `ctx.addCleanup`.
133133+134134+## Query Params
135135+136136+Hash routing is ideal for static sites, but you can combine it with query parameter syncing.
137137+138138+For example:
139139+140140+```html
141141+<div
142142+ data-volt
143143+ data-volt-state='{"route": "home", "preview": false}'
144144+ data-volt-url="hash:route">
145145+ <span hidden data-volt-url="sync:preview"></span>
146146+ <!-- ... -->
147147+</div>
148148+```
149149+150150+Now `#/pricing?preview=true` keeps both the route and a feature flag in sync with the URL.
151151+Add the extra `data-volt-url="sync:preview"` binding on a child element when you need more than one signal to participate in URL synchronisation.
152152+153153+## Progressive Enhancement
154154+155155+- Always provide semantic HTML in each section so the site remains usable without JavaScript or when crawled.
156156+- Consider prefetching data when a link becomes visible: attach a watcher to `route` and trigger fetch logic from the programmatic API.
157157+- Use `scrollPlugin` for auto-scrolling on navigation if you have tall pages (`data-volt-scroll="route"`).