Component

Vue Action Sheet Component

<DomActionSheet>

A bottom action sheet for mobile and desktop, with bounded scrolling, keyboard dismissal, focus return, and drag dismissal. Works standalone as a viewport overlay. In DomAppShell, place it in the overlay slot and it stays inside that app.

Mobile actions

Action sheet playground

Action sheet playground

Preview

Mobile content area

Playground.vuevue
Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { reactive } from 'vue';
import { DomActionSheet } from '@getdom/studio';

const data = reactive({
		"modelValue": true,
		"title": "Project actions",
		"description": "Use for app commands that should stay near the thumb.",
		"actions": [
			{
				"label": "Share project",
				"description": "Open the native share sheet",
				"value": "share",
				"variant": "",
				"disabled": false
			},
			{
				"label": "Duplicate screen",
				"description": "",
				"value": "duplicate",
				"variant": "",
				"disabled": false
			},
			{
				"label": "Delete draft",
				"description": "",
				"value": "delete",
				"variant": "danger",
				"disabled": false
			}
		],
		"cancelLabel": "Cancel"
	});
</script>

<template>
	<DomActionSheet
		v-bind="data"
		@update:modelValue="data.modelValue = $event"
	/>
</template>

A desktop action sheet

No app wrapper is required. The standalone sheet overlays the viewport and limits its width on desktop. In a DomAppShell, use its overlay slot to contain the sheet. Long lists scroll inside the sheet while Cancel stays visible. Escape, the backdrop, Cancel, and the handle dismiss it; focus returns to the opener.

Document actions

1200px

Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { computed, ref } from 'vue';
import { DomActionSheet, DomButton } from '@getdom/studio';

const open = ref(false);
const longList = ref(false);
const result = ref('No action selected.');
const actions = computed(() => longList.value
	? Array.from({ length: 18 }, (_, index) => ({ label: `Move to project ${index + 1}`, value: `project-${index + 1}` }))
	: [
		{ label: 'Copy document link', value: 'copy', description: 'Copy a link to the quarterly report' },
		{ label: 'Duplicate document', value: 'duplicate' },
		{ label: 'Download PDF', value: 'download', disabled: true, description: 'Available when the report is published' },
		{ label: 'Archive document', value: 'archive', variant: 'danger' },
	]);

/** Opens either the standard actions or the deliberately long scrolling list. */
function showActions(long = false) {
	longList.value = long;
	open.value = true;
}

/** Reports the demo selection; persistence and device APIs belong to the app. */
function selectAction(action) {
	result.value = `Selected: ${action.label}. This preview does not change a document.`;
}
</script>

<template>
	<section class="mx-auto w-full max-w-4xl space-y-6 p-5 sm:p-8">
		<header class="flex flex-wrap items-center justify-between gap-4 border-b border-border pb-5">
			<div>
				<p class="text-xs font-medium text-muted-fg">Workspace / Reports</p>
				<h2 class="mt-1 text-xl font-semibold tracking-tight">Quarterly product review</h2>
			</div>
			<DomButton variant="secondary" @click="showActions()">Document actions</DomButton>
		</header>
		<div class="space-y-4 rounded-xl border border-border bg-secondary/20 p-5">
			<p class="text-sm font-semibold">Ready for the team review</p>
			<p class="max-w-xl text-sm leading-6 text-muted-fg">Keep document commands together in a sheet that works with a mouse, keyboard, or touch. The same component fits a desktop workspace and a mobile screen.</p>
			<DomButton variant="secondary" @click="showActions(true)">Try a long action list</DomButton>
		</div>
		<p role="status" class="text-sm text-muted-fg">{{ result }}</p>
		<DomActionSheet v-model="open" :title="longList ? 'Move document' : 'Document actions'" description="Quarterly product review" :actions="actions" @select="selectAction" />
	</section>
</template>

Reference

Props

Control props

NameTypeTSDefaultDescription
containedbooleanboolean—Defaults to contained inside DomAppShell, viewport otherwise. Explicit true requires a positioned, sized parent; prefer the shell overlay slot.
modelValuebooleanbooleanfalseWhether the action sheet is open.
titlestringstring''Optional action sheet title.
descriptionstringstring''Optional supporting text below the title.
actions
ts
[
	{
		"disabled": false,
		"label": "Item 1",
		"description": "",
		"value": "item-1",
		"variant": ""
	}
]
arrayArray<ActionsItem
type ActionsItem = {
	disabled?: boolean; // Disabled
	label?: string; // Label
	description?: string; // Description
	value?: string; // Value
	variant?: "" | "danger"; // Variant
};
>
[]Action rows: { label, description, value, variant, disabled }.
cancelLabelstringstring'Cancel'Dismiss button label.

Auto-generated from Action sheet.props and inline _edit hints.

Events

NamePayloadDescription
@update:modelValuebooleanFired when the sheet opens or closes.
@selectobjectFired with the selected action.

Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.