x-flow-replay-controls
Duck-typed playback toolbar that drives any AlpineFlow replay handle — $flow.replay() (animation) and $flow.replayExecution() (workflow) both work without ceremony. Auto-binds to $flow.lastReplayHandle when present, otherwise lazy-builds $flow.replayExecution($flow.executionLog) on the first Play click.
<x-flow :nodes="$nodes" :edges="$edges">
<x-flow-panel position="bottom-center">
<x-flow-replay-controls />
</x-flow-panel>
</x-flow>
Page-level placement via :target:
<x-flow id="mycanvas" :nodes="$nodes" :edges="$edges" />
<aside class="sidebar">
<x-flow-replay-controls target="#mycanvas" />
</aside>
Props
| Prop | Type | Required | Purpose |
|---|---|---|---|
handle |
string | no | Alpine expression naming a property on the canvas that holds an explicit handle (otherwise auto-binds). |
target |
string | no | CSS selector for the canvas when used outside it. |
speeds |
array | no | Speed multipliers in the dropdown. Defaults to [0.5, 1, 2, 4]. |
Capability detection
Once a handle is bound, the component inspects it once:
| Handle exposes | Component renders |
|---|---|
scrubTo() |
Interactive scrubber + time readout |
currentTime + duration (no scrub) |
Non-interactive progress bar + time readout |
| Neither | Progress bar derived from log timestamps + elapsed wall clock |
The Play / Restart / Speed controls render in all cases; the progress wrap is gated on hasPlayableSource (a handle exists OR the executionLog is non-empty).
Restart behaviour
Restart calls handle.stop(), drops the bound reference, and rebuilds via the auto-bind path before resuming play — so the same component works whether the underlying replay system supports rewind or not.
Speed changes
If the handle exposes a writable speed property, the dropdown updates it live. Workflow handles without a writable speed pick up the new value on the next Restart.