Skip to content

Latest commit

 

History

History

README.md

@stainless-code/vue-layers

Layers

Modals are just async functions you forgot to await.

The Vue adapter for Layers — open any layer from anywhere and await a typed result. State coordination, not UI ownership: Layers owns the stack/keys/transitions/await contract; you own rendering, focus, portals, and a11y.

bundle size

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

Install

bun add @stainless-code/vue-layers

Peer: vue (>=3.3.0)

Taste

<!-- ConfirmDialog.vue -->
<script setup lang="ts">
import type { LayerComponentProps } from "@stainless-code/vue-layers";
const { call, payload } =
  defineProps<LayerComponentProps<{ title: string }, boolean>>();
</script>
<template>
  <div role="dialog">
    <h2>{{ payload.title }}</h2>
    <button @click="() => void call.end(true)">Yes</button>
    <button @click="() => void call.end(false)">No</button>
  </div>
</template>
// confirm.ts
import { layerOptions } from "@stainless-code/vue-layers";
import ConfirmDialog from "./ConfirmDialog.vue";

export const confirm = layerOptions({
  stack: "confirm",
  key: ["confirm", "remove"],
  component: ConfirmDialog,
});
<!-- App.vue -->
<script setup lang="ts">
import { provideLayerClient, StackOutlet } from "@stainless-code/vue-layers";

provideLayerClient();
</script>
<template>
  <StackOutlet stack="confirm" />
</template>
<!-- RemoveButton.vue -->
<script setup lang="ts">
import { useLayer } from "@stainless-code/vue-layers";
import { confirm } from "./confirm";

const c = useLayer(confirm);

async function handleRemove() {
  const ok = await c.open({ title: "Remove?" });
  if (!ok) return;
  deleteItem();
}
</script>

<template>
  <button type="button" @click="handleRemove()">Remove</button>
</template>

Docs

Source on GitHub