Vue
Vue adapter — provideLayerClient, composition API hooks, StackOutlet.
@stainless-code/vue-layers bridges stacks into Vue 3 composition API refs. The core is re-exported.
Install
npm install @stainless-code/vue-layerspnpm add @stainless-code/vue-layersyarn add @stainless-code/vue-layersbun add @stainless-code/vue-layersPeer: vue >=3.3.0
Client
Call provideLayerClient() in a parent setup() (creates a LayerClient when omitted). Descendants read it with useLayerClient():
<script setup lang="ts">
import { provideLayerClient, StackOutlet } from "@stainless-code/vue-layers";
provideLayerClient();
</script>
<template>
<StackOutlet stack="confirm" />
</template>
Render a stack
StackOutlet renders registered component entries. For scoped-slot-style subscriptions, use StackSubscribe or useStack({ stack, select }) directly in setup().
Confirm dialog
<script setup lang="ts">
import {
layerOptions,
provideLayerClient,
StackOutlet,
useLayer,
type LayerComponentProps,
} from "@stainless-code/vue-layers";
type ConfirmPayload = { title: string };
type ConfirmResponse = boolean;
const ConfirmDialog = defineComponent({
props: {
call: { type: Object, required: true },
payload: { type: Object, required: true },
},
setup(props: LayerComponentProps<ConfirmPayload, ConfirmResponse>) {
return () => (
<div role="dialog">
<h2>{props.payload.title}</h2>
<button onClick={() => void props.call.end(true)}>Yes</button>
<button onClick={() => void props.call.end(false)}>No</button>
</div>
);
},
});
const confirm = layerOptions<ConfirmPayload, ConfirmResponse>({
stack: "confirm",
key: ["confirm", "remove"],
component: ConfirmDialog,
});
provideLayerClient();
const c = useLayer(confirm);
async function remove() {
await c.open({ title: "Remove item?" });
}
</script>
<template>
<StackOutlet stack="confirm" />
<button @click="remove">Remove</button>
</template>
Primitives
Options bag plus optional trailing LayerClient. Drive with useLayer(options); observe with useLayerState({ key, … }).
| Export | Role |
|---|---|
useStack({ stack?, select?, compare? }, client?) |
Readonly<Ref<T>> of the selected stack slice |
useQueuedStack({ stack?, select?, compare? }, client?) |
Queued snapshot as Readonly<Ref<T>> |
useLayer(options, client?) |
Drive — wired handle refs + open() / dismiss() + reactive state / queued / top |
useLayerState({ key, stack?, select?, compare? }, client?) |
Observe — Readonly<Ref<LayerState[]>> for mounted same-key layers |
useLayerQueuedState({ key, stack?, select?, compare? }, client?) |
Observe — queued same-key layers |
Ergonomic APIs
| Export | Role |
|---|---|
useStackHandles(stack?, rootProps?) |
{ states: Ref, getCall } for headless rendering |
StackSubscribe |
Scoped-slot subscription (#default="{ value }") |
useMutationFlow(call) |
pending is a Ref<boolean>; run(fn).orEnd(response) |
useLayerGroup(call, options?) |
Child stack with Outlet component |
createStackHook(config?) |
StackProvider, useAppStack, AppHost, AppLayer components |