a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1---
2outline: deep
3---
4
5# Shift Plugin
6
7The shift plugin applies reusable CSS keyframe animations to any element. Use it for attention-grabbing nudges, loading
8states, or signal-driven feedback without writing imperative animation code.
9
10## Quick Start
11
12```html
13<!-- Run bounce once on mount -->
14<button data-volt-shift="bounce">Click me</button>
15
16<!-- Infinite pulse animation -->
17<span data-volt-shift="pulse">Loading…</span>
18```
19
20When an element mounts the plugin pulls a preset from the animation registry and calls the Web Animations API with the
21configured keyframes, duration, iterations, and easing. Users with `prefers-reduced-motion` skip the animation entirely.
22
23## Built-in Presets
24
25Volt ships with several presets you can reference immediately:
26
27- `bounce`-snappy vertical movement for call-to-action buttons.
28- `shake`-horizontal wiggle, ideal for error indicators.
29- `pulse`-scale and opacity pulse that repeats forever.
30- `spin`-continuous 360° rotation.
31- `flash`-blinking opacity effect.
32
33## Custom Duration and Iterations
34
35Add dot-separated numbers after the preset to override timing settings.
36
37```html
38<!-- 1 second bounce repeated three times -->
39<div data-volt-shift="bounce.1000.3">Triple bounce</div>
40```
41
42The first number is duration in milliseconds; the optional second number controls iteration count. Omitted values fall
43back to the preset configuration.
44
45## Reacting to Signals
46
47Prefix the binding with a signal path to trigger the animation whenever the signal changes from its previous value to a
48truthy value.
49
50```html
51<div data-volt-shift="form.error:shake">Please fix the highlighted fields</div>
52```
53
54For the snippet above:
55
56- `form.error` is resolved via `ctx.findSignal`.
57- The element animates the first time the signal evaluates truthy.
58- Subsequent updates run the animation whenever the value toggles and remains truthy.
59
60## Registering Custom Animations
61
62Use the programmatic API to add, inspect, or remove presets.
63
64```ts
65import { getRegisteredAnimations, registerAnimation } from "volt/plugins/shift";
66
67registerAnimation("wiggle", {
68 keyframes: [
69 { offset: 0, transform: "rotate(0deg)" },
70 { offset: 0.25, transform: "rotate(-5deg)" },
71 { offset: 0.75, transform: "rotate(5deg)" },
72 { offset: 1, transform: "rotate(0deg)" },
73 ],
74 duration: 300,
75 iterations: 2,
76 timing: "ease-in-out",
77});
78
79console.log(getRegisteredAnimations()); // ["bounce", "shake", ..., "wiggle"]
80```
81
82Other helpers:
83
84- `getAnimation(name)` - fetch the preset definition.
85- `hasAnimation(name)` - check existence.
86- `unregisterAnimation(name)` - remove custom presets (built-ins cannot be deleted).
87
88## Cleanup
89
90Shift automatically cancels the underlying `element.animate` call on completion and removes subscriptions registered via signals.
91No additional teardown is required beyond VoltX’s normal plugin lifecycle.