v0.1.0 · MIT · vanilla · no dependencies

apertura

Dialogs where the button you pressed becomes the dialog. The same physical springs as the toast package, plus the flight back in.

The morph

Hand the dialog the element that triggered it and it grows out of it. Close it and it grows back in. Without an origin, it fades in from the centre.

const ok = await modal.open({
    origin: event.currentTarget,
    title: 'Delete this movement?',
    variant: 'danger',
})

Confirm

The default card is a title, a description and two actions. Confirm resolves true, cancel false, Escape or overlay undefined.

Your own content

Pass a render function and the body is yours. Call close(value) with whatever the caller is waiting for.

modal.open({
    origin: event.currentTarget,
    render(body, { close }) {
        const input = document.createElement('input')
        const save = document.createElement('button')
        save.onclick = () => close(input.value)
        body.append(input, save)
    },
})

Nested

A dialog can open another. The one underneath scales back and goes inert until the top one leaves.

Helpers

confirm, alert and prompt are thin wrappers on open(). Per-call morph and size sit on top of the playground knobs.

Anchor and in place

Same morph, different slot. Anchor grows beside the button. In place expands a card over itself. A sheet lands at the bottom.

After it lands

Drag a dialog toward its button (or down, on a sheet) to dismiss. update() reflows the card with a height spring. Confirm can fly into a different origin.

Inbox

Playground

The morph is a simulation, not a baked curve. Lower damping bounces more; velocity is the kick that bends the path.