Modals are just async functions you forgot to await.
The zero-dependency, framework-agnostic core of Layers — the layer/stack engine every adapter wraps. State coordination, not UI ownership: it owns ordering, keys, transitions, blockers, and the await client.open(...) contract; you own rendering, focus, portals, and a11y.
Experimental — the API may change between minor releases. Pin your version.
bun add @stainless-code/layers
Peer: none. App developers install a framework adapter instead.
import {
LayerClient,
layerOptions,
createLayer,
createCallContext,
} from "@stainless-code/layers";
const client = new LayerClient();
const confirm = layerOptions<{ title: string }, boolean>({
stack: "confirm",
key: ["confirm", "remove"],
});
const c = createLayer(confirm, client);
const stack = client.getStack("confirm");
stack.subscribe(() => {
for (const state of stack.getSnapshot()) {
const call = createCallContext(stack, stack.getLayer(state.id)!, state);
// render the layer; call.end(response) resolves `await c.open(...)`.
}
});
const ok = await c.open({ title: "Remove?" });