Skip to content

Latest commit

 

History

History

README.md

@stainless-code/alpine-layers

Layers

Modals are just async functions you forgot to await.

Alpine.js adapter — open any layer from anywhere and await a typed result. State coordination, not UI ownership: you own markup, focus (@alpinejs/focus), portals (x-teleport), and a11y.

bundle size

Experimental — the API may change between minor releases. Pin your version.

Install

bun add @stainless-code/alpine-layers

Peer: alpinejs (>=3.13). Optional: @alpinejs/focus for modal trap recipes.

CDN

Load before Alpine core; the CDN entry listens for alpine:init and registers the plugin.

<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/@stainless-code/alpine-layers/cdn"
></script>
<script
  defer
  src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"
></script>

Taste (Vite / bundled)

import Alpine from "alpinejs";
import layers, {
  LayerClient,
  createLayer,
  layerOptions,
  setLayerClient,
} from "@stainless-code/alpine-layers";

const client = new LayerClient();
setLayerClient(client);
Alpine.plugin(layers);
Alpine.start();
<div x-data>
  <template x-layer-outlet="'modal'">
    <div x-data role="dialog">
      <h2 x-text="$layer.payload.title"></h2>
      <button type="button" @click="$layer.call.end(true)">Yes</button>
    </div>
  </template>
</div>
const confirm = layerOptions({
  stack: "modal",
  key: ["confirm"],
  exitingDelay: 0,
});
const c = createLayer(confirm, client);
void c.open({ title: "Remove?" });

Learn more