Koala logo Design
No matches for “
↑↓ navigate open Esc close
Components Step modals

Step modals

A standalone one-question-per-screen modal — no title bar, no step counter, a fixed narrow centred width, and a built-in animated stage that blurs/fades/height-morphs between screens. Independent of <koala-modal> by design; reach for it when a flow is a sequence of single decisions rather than one form.

<koala-step-modal>
<div x-data="stepModalDemo()">
    <button koala-btn="Primary" x-on:click="open = true">Confirm my details</button>
    <koala-step-modal flag="open" aria-label="Confirm your details">
        <koala-step-modal-content>
            <div x-show="currentScreen === 'name'">…</div>
            <div x-show="currentScreen === 'contact'">…</div>
        </koala-step-modal-content>
        <koala-step-modal-footer>
            <button x-show="!isFirstScreen" x-on:click="goBack()">Back</button>
            <button koala-btn="Primary" x-on:click="goNext()">Continue</button>
        </koala-step-modal-footer>
    </koala-step-modal>
</div>

Click through both screens to see the transition: the outgoing screen blurs and fades, the stage height morphs to fit the incoming screen, then it fades/unblurs in. The engine (transitionTo, wait) is plain Alpine state the caller owns — see _QuoteOnboardingModal.cshtml for the full reference implementation with branching screens.

2 helpers
Tag Attributes Notes
&lt;koala-step-modal-content&gt; The animated stage. Renders the .koala-step-stage / .koala-step-panel wrapper the caller's transition engine reads via x-ref="stepStage" / x-ref="stepPanel". Everything inside blurs/fades/height-morphs on screen change.
&lt;koala-step-modal-footer&gt; Static nav row (Back / Continue / Send). Sits outside the animated stage so button state never blurs mid-transition.
4 attributes
Attribute Values Notes
flag string Alpine variable controlling open/closed. Defaults to modalOpen. The parent x-data must declare it.
aria-label string Accessible label — there is no visible title bar to derive one from.
dismissable bool Defaults to true. Set false for a blocking overlay (drops ESC + backdrop-click).
teleport bool Teleport to <body> so an ancestor's overflow/transform can't clip the dialog.

"Is this address right?" — Yes / No

Do One decision per screen — a Yes/No, a single field, a short pill choice. Keeps the height-morph small and the flow feeling fast.

A screen with name, phone, email, and a dropdown all at once.

Don't Don't cram several fields onto one screen — that's what koala-modal + koala-modal-content already do well. Step modal earns its keep by staying atomic.

Reduced motion

prefers-reduced-motion: reduce strips the blur (a filter change) and the height morph entirely — both exceed DESIGN.md's opacity/<4px exemption — while keeping the opacity cross-fade, which is exempt. The caller's wait() helper should also skip its delays under reduced motion so screens swap immediately rather than pausing for a transition that no longer plays.