Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

BottomSheet

  • Stable
  • WCAG 2.2 evidence
  • RTL
  • Web · iOS · Android

A mobile sheet that slides up from the bottom edge for a short task or a set of options. Built on React Aria ModalOverlay + Modal + Dialog: a role="dialog" named by its title; focus moves inside on open, Tab stays inside while the page is inert and does not scroll, Escape, the close button or a tap on the scrim closes it, and focus returns to the trigger (WCAG 2.1.1, 2.1.2, 2.4.3, 4.1.2). The grabber resizes the sheet between half and full: drag it up or down (down from half height closes), or use it as a button: press it (Enter, Space, click) to toggle, or press the up and down arrow keys. So dragging is never the only way (2.5.7). Motion only runs when allowed (2.3.3). Consumer duties: title and action wording; pass the same platform to the actions you put in footer. On wide screens use Drawer or Popover instead.

import { BottomSheet } from "@nexera-ui/react";
Loading example…
6
examples
20
props
7
live controls
3
platforms
9
WCAG criteria
3
blocks use it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
title
children
detent
defaultDetent
platform
isDismissable
defaultOpen
Generated code
import { BottomSheet } from "@nexera-ui/react";

<BottomSheet />

Examples 5

The same examples as Storybook, rendered live. Open Code to copy one.

Full

Figma Detent=Full.

Loading example…

Android

Figma Platform=Android: a larger grabber area, an H3 title and the 52 dp ghost close button.

Loading example…

Web

Web: the iOS geometry with a shorter footer. Prefer Drawer or Popover on wide screens.

Loading example…

Long content

A long body scrolls (and joins the tab order) between the header and the footer.

Loading example…

Right to left

Right-to-left: the title starts on the right and the close button sits on the left.

Loading example…

Props 20

Press "Try it" on a card to load that prop into the playground.

20 props shown

title*Nexera
ReactNode

Title: a level 2 heading that names the dialog. It wraps instead of truncating.

Default –
childrenNexera
ReactNode

The body. It scrolls.

Default –
footerNexera
ReactNode

Actions stacked at full width at the bottom, for example <Button size="lg" platform="ios" slot="close">Apply</Button>. Shown when provided.

Default –
detentNexera
"half" | "full"

Height, controlled. Use with onDetentChange.

Default –
defaultDetentNexera
"half" | "full"

Height on first render (uncontrolled).

Default half
onDetentChangeNexera
(detent: BottomSheetDetent) => void

Called when the grabber (press, arrow keys or a drag) changes the height.

Default –
platformNexera
"web" | "ios" | "android"

Platform look. Defaults to the NexeraProvider platform.

Default "web"
expandLabelNexera
string

Accessible name of the grabber while the sheet is at half height. Translate it for your locale.

Default Expand
collapseLabelNexera
string

Accessible name of the grabber while the sheet is at full height. Translate it for your locale.

Default Collapse
closeLabelNexera
string

Accessible name of the close button. Translate it for your locale.

Default Close
isDismissableNexera
boolean

Whether a tap on the scrim closes the sheet. Escape and the close button always close it unless isKeyboardDismissDisabled.

Default true
idNexera
string

Id of the sheet element.

Default –
classNameNexera
string

Extra classes for the sheet, merged last so they win over the defaults.

Default –
styleNexera
CSSProperties

Inline style for the sheet.

Default –
triggerNexera
ReactElement<unknown, string | JSXElementConstructor<any>>

The element that opens the overlay, usually a Nexera Button. It toggles the overlay when pressed and gets focus back when the overlay closes. Leave it out to open the overlay from your own state (isOpen + onOpenChange).

Default –
isOpenNexera
boolean

Whether the overlay is open (controlled). Use with onOpenChange.

Default –
defaultOpenNexera
boolean

Whether the overlay is open on first render (uncontrolled).

Default false
onOpenChangeNexera
(isOpen: boolean) => void

Called when the overlay opens or closes (Escape, the close button, a slot="close" action, a click outside).

Default –
shouldCloseOnInteractOutsideReact Aria
(element: Element) => boolean

When user interacts with the argument element outside of the overlay ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the overlay. By default, onClose will always be called on interaction outside the overlay ref.

Default –
isKeyboardDismissDisabledReact Aria
boolean

Whether pressing the escape key to close the modal should be disabled.

Default false

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

6 direct · 3 supporting
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.4.10ReflowLevel AA · supporting test
  • 2.1.1KeyboardLevel A · tested directly
  • 2.1.2No Keyboard TrapLevel A · tested directly
  • 2.3.3Animation from InteractionsLevel AAA · supporting test
  • 2.4.3Focus OrderLevel A · tested directly
  • 2.5.7Dragging MovementsLevel AA · tested directly
  • 2.5.8Target Size (Minimum)Level AA · supporting test
  • 4.1.2Name, Role, ValueLevel A · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

  • data-dragging
  • data-entering
  • data-exiting
  • data-hovered
  • data-pressed
Usage
<BottomSheet className="data-dragging:opacity-90 shadow-sm" />

Used in blocks

Related components