Sheet
A workspace-level bottom sheet built on Base UI Drawer, with App’s floating sheet geometry, software-keyboard handling, and a claim on the one shared dim.
Installation
import { Sheet } from "@o/pipeline/experimental/components/sheet";
Usage
Sheet is for a surface that takes the whole screen in its own right, the command palette being the first. It is not App.Drawer, which is the sidebar stack and is deliberately scoped to it. A sheet portals to the document, sits on the --z-sheet layer between the drawer stack and dialogs, and dims whatever it covers.
<Sheet.Root open={open} onOpenChange={setOpen}>
<Sheet.Portal>
<Sheet.Backdrop />
<Sheet.Viewport>
<Sheet.Popup aria-label="Command palette">
<Sheet.Content>{children}</Sheet.Content>
<Sheet.Close>Close</Sheet.Close>
</Sheet.Popup>
</Sheet.Viewport>
</Sheet.Portal>
</Sheet.Root>
Rootis modal and swipes down by default, and mounts Base UI’sVirtualKeyboardProviderfor you, because the popup’s geometry is only correct while something is publishing--drawer-keyboard-inset.Portalrenders intodocument.bodyunless you name acontainer, the same defaultDialog.Portaltakes. Without it floating-ui nests the sheet into whichever App panel it was mounted under, and the sheet cannot escape that panel’s stacking context.Backdropforce-renders Base UI’s part (which skips itself whenever a drawer looks nested, and every drawer insideApp.Rootdoes) and claims the shared dim at thesheetlayer. The part itself is transparent, and is the press and swipe target.Popupis content-sized up to100dvhless App’s mobile insets, and accounts for the software keyboard once, by raising its own bottom edge and subtracting the same term from the cap. Do not add keyboard padding inside it.Closeis Base UI’s close part. Where the control goes is the consumer’s call:CommandMenu.Dialogplaces one at the top end of the sheet for touch, since there is no Escape key there.
There are no snap points yet.