Tessera UI

Action Sheet

A mobile-first bottom sheet presenting a set of contextual actions. Built on Base UI Dialog. Compound component pattern with Header, Group, Item, Separator, and Cancel. Three sizes. Five corner-rounding options. Destructive intent, loading state, icon slots. LTR and RTL support.

Installation

pnpm add @tessinaui/ui

Usage

import {
  ActionSheet,
  ActionSheetTrigger,
  ActionSheetContent,
  ActionSheetHeader,
  ActionSheetTitle,
  ActionSheetDescription,
  ActionSheetGroup,
  ActionSheetSeparator,
  ActionSheetItem,
  ActionSheetCancel,
} from "@tessinaui/ui";
<ActionSheet>
  <ActionSheetTrigger className="...">Open</ActionSheetTrigger>

  <ActionSheetContent>
    <ActionSheetHeader>
      <ActionSheetTitle>Actions</ActionSheetTitle>
      <ActionSheetDescription>Choose an action below.</ActionSheetDescription>
    </ActionSheetHeader>

    <ActionSheetGroup>
      <ActionSheetItem icon={<Share2 />}>Share</ActionSheetItem>
      <ActionSheetItem icon={<Copy />}>Copy link</ActionSheetItem>
      <ActionSheetSeparator />
      <ActionSheetItem intent="destructive" icon={<Trash2 />}>Delete</ActionSheetItem>
    </ActionSheetGroup>

    <ActionSheetCancel />
  </ActionSheetContent>
</ActionSheet>

Playground

Preview

Showcase

Preview

API Reference

ActionSheet

Root component. Provides context and wraps Base UI Dialog.Root.

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Max-height of the sheet panel (50dvh / 70dvh / 90dvh)
dir"ltr" | "rtl""ltr"Text direction applied to the panel and all children
openbooleanControlled open state
defaultOpenbooleanUncontrolled initial open state
onOpenChange(open: boolean, event: Event) => voidCalled when the open state changes
dismissiblebooleantrueWhether tapping the scrim or pressing Escape closes the sheet
modalbooleantrueWhether the dialog uses modal behavior (focus trap, scroll lock)

ActionSheetContent

Renders the panel anchored to the bottom of the viewport inside a portal. Includes the backdrop scrim.

PropTypeDefaultDescription
rounded"none" | "sm" | "md" | "lg" | "full""md"Top corner rounding of the panel
showHandlebooleantrueWhether to show the drag handle pill
size"sm" | "md" | "lg"Overrides the size from context

ActionSheetItem

Individual action button row.

PropTypeDefaultDescription
intent"default" | "destructive""default"Visual intent — destructive renders in error color
size"sm" | "md" | "lg"Overrides the size from context
iconReact.ReactNodeOptional leading icon
loadingbooleanfalseShows a loading spinner and disables the button
closeOnSelectbooleantrueClose the sheet when the action is triggered
disabledbooleanDisables the item

ActionSheetCancel

Sticky cancel action at the bottom of the sheet, separated by a top border.

PropTypeDefaultDescription
size"sm" | "md" | "lg"Overrides the size from context
childrenReact.ReactNode"Cancel"Button label

ActionSheetHeader

Optional header section with ActionSheetTitle and ActionSheetDescription. Centered text, separated from the group by a bottom border.

ActionSheetGroup

Scrollable container for ActionSheetItem and ActionSheetSeparator rows. Grows to fill available height.

ActionSheetSeparator

Horizontal rule styled with border-border.

ActionSheetTrigger

Re-export of Dialog.Trigger. Renders a <button> that opens the sheet.

ActionSheetClose

Re-export of Dialog.Close. Renders a <button> that closes the sheet.


Behaviour

  • Slides up from the bottom of the viewport with a spring animation
  • Blocks background interaction via modal focus trap and scroll lock
  • Closes on: scrim tap, Escape key, ActionSheetCancel, any ActionSheetItem with closeOnSelect (default)
  • Sheet height is constrained by the size prop and scrolls internally when content overflows
  • ActionSheetCancel is always sticky at the bottom outside the scroll area

On this page