Sheet
A native sheet with a native header: titles, back, close and actions, detents and a large title.
Import
import {Sheet} from '@hzblj/kara-ui'Examples
Detents and a large title
<Sheet detents={[0.6, 1]} onDismiss={close} scrollable visible={open}>
<Sheet.Header title="Nearby stores" titleStyle="large" trailingItems={closeItem} />
<Sheet.ScrollView content={{px: 's20'}}>{stores}</Sheet.ScrollView>
</Sheet>Props
A native sheet — UISheetPresentationController on iOS, Material's bottom sheet on Android — with an optional native header (<Sheet.Header> as a direct child). The React Native tier: it needs no host, and must not sit inside one; native atoms in its content go in an Island.
| Prop | Type | Default | Description |
|---|---|---|---|
| children* | ReactNode | — | The content. A |
| onDismiss* | () => void | — | The user dismissed it — |
| visible* | boolean | — | Presents the sheet while true; going false dismisses it. |
| bg | ColorToken | 'surface.primary' | The sheet's colour. |
| detents | SheetDetent[] | FIT_CONTENT | Where the sheet can rest, smallest first. |
| dimmed | boolean | true | Dims what is behind. On by default. |
| dismissible | boolean | true | A swipe down or a tap outside closes it. On by default. |
| draggable | boolean | true | It follows the finger between detents. On by default. |
| footer | ReactElement | — | Pinned to the bottom, above the content and the keyboard. |
| grabber | boolean | true | The drag handle. On by default. |
| onDetentChange | (detentIndex: number) => void | — | The sheet moved to another detent — its index in |
| onPresent | () => void | — | The sheet finished presenting. |
| ref | Ref<SheetRef> | — |
|
| scrollable | boolean | false | The content is a scroll view ( |
| testID | string | — | Test identifier, forwarded to the native sheet. |
The content. A <Sheet.Header> among the direct children becomes the native header instead.
The user dismissed it — visible going false does not call this.
Presents the sheet while true; going false dismisses it.
Where the sheet can rest, smallest first. ['auto'] — fit the content — by default.
Dims what is behind. On by default.
A swipe down or a tap outside closes it. On by default.
It follows the finger between detents. On by default.
Pinned to the bottom, above the content and the keyboard.
The drag handle. On by default.
The sheet moved to another detent — its index in detents.
The sheet finished presenting.
present, dismiss and resize, for driving the sheet imperatively.
The content is a scroll view (<Sheet.ScrollView>) the sheet drives: dragging past its top resizes the sheet, and a header scrolls with the iOS 26 edge effect. Off by default — set it with a scrolling body.
Test identifier, forwarded to the native sheet.
Sheet.Header
The sheet's header: a NavigationBar with the title and items, and anything else that should stay put above the content (children — a segmented control, a search hint). On iOS 26 a scrollable sheet's content scrolls under it with the system's scroll edge effect; elsewhere it sits above the content.
| Prop | Type | Description |
|---|---|---|
| children | ReactNode | Pinned under the bar. |
| inverted | boolean | Light items and title, for a sheet with a dark or image background. |
| leadingItems | NavigationBarItem[] | In screen order, from the leading edge. |
| search | NavigationBarSearch | A search field in place of the title (iOS). |
| title | string | The title — in the bar, or above the content with a |
| titleStyle | 'center' | 'large' | 'leading' |
|
| trailingItems | NavigationBarItem[] | In screen order, toward the trailing edge — the close item, by convention. |
Pinned under the bar.
Light items and title, for a sheet with a dark or image background.
A search field in place of the title (iOS).
The title — in the bar, or above the content with a large titleStyle.
center by default.
In screen order, toward the trailing edge — the close item, by convention.
Sheet.ScrollView
The body of a scrollable sheet: its content starts below an overlaid header, it carries a large title, and it reports its scroll to the sheet.
Also takes 'keyboardShouldPersistTaps' from ScrollViewProps.
| Prop | Type | Description |
|---|---|---|
| children* | ReactNode | The scrolling content, after the large title if there is one. |
| content | ResponsiveViewSx | Styles the scrolling content — padding and gap belong here, as with |
| onScroll | SheetScrollHandler | Called on every scroll event, after the sheet's own listener. |
| testID | string | Test identifier, forwarded to the scroll view. |
The scrolling content, after the large title if there is one.
Styles the scrolling content — padding and gap belong here, as with RnScrollView.
Called on every scroll event, after the sheet's own listener.
Test identifier, forwarded to the scroll view.
Platform notes
- React Native tier, on TrueSheet: no host, and never inside one — native atoms in its content go in an
Island. Sheet.Headeris a slot, not a view: a direct child, built fromNavigationBarinto a real native header.- On iOS 26 a scrollable sheet lays its header over the content, so
Sheet.ScrollViewpads by the header’s height. onDismissis the user’s dismissal only — settingvisibleto false dismisses without calling it.