Overlays@knitui/components
Drawer
Drawer slides a panel in from any viewport edge. position chooses the anchor edge, size sets the panel extent (width for left/right, height for top/bottom), and title + withCloseButton compose the optional header. The compound sub-parts (Drawer.Header, Drawer.Title, Drawer.Body, Drawer.Content) are also exported for fully custom layouts.
import { Drawer } from "@knitui/components";Playground
Loading playground…
<Drawer
opened={false}
position="left"
size="md"
withCloseButton
title="Drawer title"
>
Drawer body content goes here.
</Drawer>Examples
Trigger
A trigger button that opens and closes the drawer — demonstrates controlled open state.
Loading example…
Positions
All four anchor positions side by side — each button opens its drawer from a different edge.
Loading example…
Sizes
All seven size steps, opening the same left-anchored drawer at increasing widths.
Loading example…
No Title
Drawer without a title — the header is omitted entirely.
Loading example…
Without Close Button
Close button hidden via withCloseButton={false} — only click-outside or Escape closes it.
Loading example…
With Offset
Drawer with an offset that creates a gap between the panel and the viewport edge.
Loading example…
Shadows
All five shadow levels across the shared elevation ladder. Rendered on the static Drawer.Content part (each in its own contained, non-overlapping cell) so the drop shadows are directly comparable without the portaled overlay. The live drawer defaults to shadow="xl".
Loading example…
Compound API
Compound API — assembling the drawer manually with Drawer.Header, Drawer.Title, and Drawer.Body.
Loading example…
Styles
Per-slot styles targets individual parts — here the overlay, content, and title.
Loading example…
Drag To Dismiss
Drag-to-dismiss (dragToDismiss) — drag the panel toward its anchored edge to close it (the same reanimated + gesture mechanic as @knitui/sheet): a left drawer drags left, a bottom drawer drags down, etc. The CSS enter/exit slide is unchanged. Release past ~30% of the panel extent (or a fling toward the edge) dismisses; a short drag springs back.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
onClose required | () => void | — | Called when the overlay requests to close (Escape, overlay click, close button). |
opened required | boolean | false | Controlled opened state. |
animation | false | MotionPresetName | MotionPreset | undefined | a subtle edge slide-in keyed to `position`.
Reduced motion is always honoured. Exit animates (the panel slides and scrim
fades out before unmounting) unless `keepMounted` is set. | Enter/exit animation — a motion preset name, an inline {@link MotionPreset}, or `false` to disable. |
animationConfig | SpringConfig | undefined | — | Spring config for the drag settle (reanimated `withSpring`). |
aria-describedby | string | undefined | — | Additional content description id(s). |
aria-label | string | undefined | "Drawer" | Accessible label used when no visible title is provided. |
children | ReactNode | Drawer body content goes here. | Drawer body content. |
closeButtonProps | { "aria-label"?: string; } | undefined | — | Typed, cross-platform-safe subset of close-button props. |
closeOnClickOutside | boolean | undefined | true | Close when the user clicks the overlay scrim. |
closeOnEscape | boolean | undefined | true | Close when the user presses Escape (web). |
disabled system | boolean | undefined | — | |
dragThreshold | number | undefined | 0.3 | Distance dragged toward the edge, as a fraction of the panel extent, past which releasing dismisses (a fling toward the edge always dismisses). |
dragToDismiss | boolean | undefined | false | Allow dragging the panel toward its anchored edge to dismiss (reanimated + gesture, the same mechanic as `@knitui/sheet`). The CSS enter/exit slide is unchanged; this only adds the interactive drag-to-close. |
duration | number | undefined | — | Animation speed in ms — overrides the preset's duration while keeping its easing. Ignored when `animation` is `false` or reduced motion is on. |
keepMounted | boolean | undefined | false | Keep mounted while closed (toggles `display:"none"` instead of unmounting). |
lockScroll | boolean | undefined | true | Lock body scroll while opened (web). |
offset | number | SpaceTokens | Animated.AnimatedNode | "safe" | null | undefined | "$0" | Gap between the panel and the viewport edge. Prefer `$space` tokens. |
overlayAnimation | false | MotionPresetName | MotionPreset | undefined | "fade". Reduced motion is
always honoured. The content frame's own animation is supplied separately by the
consumer (`Modal`/`Drawer`) on its content frame; pass `false` here to keep the
scrim in lockstep when the consumer disables that. | Enter/exit animation for the overlay scrim — a motion preset name, an inline {@link MotionPreset}, or `false` to disable. |
overlayProps | OverlayProps | undefined | — | Props forwarded to the underlying `Overlay` scrim. |
position | DrawerPosition | undefinedleft · right · top · bottom | "left" | Viewport edge the drawer is anchored to. |
radius system | string | number | undefined | — | Panel corner radius. |
returnFocus | boolean | undefined | true | Return focus to the previously-focused element on close (web). |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefinedunset · xs · sm · md · lg · xl | — | Elevation — drop shadow from the shared ladder. |
size system | string | number | undefinedxxs · xs · sm · md · lg · xl · xxl | "md" | Panel extent — width for left/right, height for top/bottom. |
styles system | DrawerStyles | undefined | — | Uniform per-slot style passthrough. See {@link DrawerStyles}. |
theme system | ThemeName | null | undefined | — | Applies a theme to this element |
title | ReactNode | Drawer title | Drawer title rendered in the header. |
trapFocus | boolean | undefined | true | Trap keyboard focus within the content while opened (web; no-op on native). |
withCloseButton | boolean | undefined | true | Show or hide the close button in the header. |
withinPortal | boolean | undefined | true | Render inside a `Portal`. |
withOverlay | boolean | undefined | true | Render the overlay scrim. |
zIndex | number | undefined | 200 | Root `z-index`. |
Style slots
Every part of Drawer can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
body | styles={{ body: { … } }} |
closeButton | styles={{ closeButton: { … } }} |
content | styles={{ content: { … } }} |
header | styles={{ header: { … } }} |
overlay | styles={{ overlay: { … } }} |
title | styles={{ title: { … } }} |
Accessibility & DOM props (2)
| Prop | Type |
|---|---|
key | Key | null | undefined |
ref | Ref<TamaguiElement> | undefined |
Plus 494 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.