Android bottom sheet

A native modal bottom sheet with Material geometry, accessible naming and focus restoration.

Preferences

Choose when to receive updates.

  • Notifications

Contextual settings

Background sync is enabled.

Connection settings

Choose how this device keeps documents up to date.

  • Use the current connection

Use it for

  • Contextual Android controls that temporarily cover the lower screen.
  • A focused choice or short task with a clear way to dismiss it.

Not for

  • Permanent side navigation or long documents.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { AndroidSheet, AndroidSheetTitle, AndroidSheetBody } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/android-sheet.

2. Vendor the source

npx @noorddev/vlak-cli add android-sheet

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/android-sheet.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { AndroidSheet, AndroidSheetTitle, AndroidSheetBody } from "@noorddev/vlak-react";

<AndroidSheet open={open} onOpenChange={setOpen}>
  <AndroidSheetTitle>Connection settings</AndroidSheetTitle>
  <AndroidSheetBody>Choose how this device connects.</AndroidSheetBody>
</AndroidSheet>

AndroidSheet

PropTypeDefaultDescription
openboolean
defaultOpenbooleanfalse
onOpenChange(open: boolean) => void
onClose() => void
dismissablebooleantrue
lightDismissbooleantrue
closeLabelstring"Close"

Also accepts Omit< DialogHTMLAttributes<HTMLDialogElement>, "open" | "onClose" >.

AndroidSheetBody

Also accepts HTMLAttributes<HTMLParagraphElement>.

AndroidSheetTitle

Also accepts HTMLAttributes<HTMLHeadingElement>.

KeysDoes
Tab or Shift+TabMoves through the modal's controls using native dialog focus containment.
EscapeRequests dismissal when dismissable is enabled.
Enter or SpaceActivates the focused control.
<dialog class="rs-android-sheet" aria-labelledby="android-sheet-title"><span class="rs-android-sheet-handle" aria-hidden="true"></span><button class="rs-android-sheet-close" type="button" aria-label="Close">×</button><h2 class="rs-android-sheet-title" id="android-sheet-title">Connection settings</h2><p class="rs-android-sheet-body">Choose how this device connects.</p></dialog>
.rs-android-sheet.rs-android-sheet-open.rs-android-sheet-handle.rs-android-sheet-close.rs-android-sheet-title.rs-android-sheet-body