ContextMenu
A long-press menu on any React Native content, with a custom preview on iOS.
Import
import {ContextMenu} from '@hzblj/kara-ui'Examples
A button inside the trigger
<ContextMenu actions={actions}>
<ProductCard />
<ContextMenu.Exclusion>
<Button label="Add to bag" onPress={add} />
</ContextMenu.Exclusion>
</ContextMenu>Props
A context menu on a React Native subtree — a card in a list, say — opened by a long press. iOS: a UIContextMenuInteraction, with an optional React Native preview lifted while the menu is open and a callback for a tap on it. Android, where Material has no lifted preview: a ripple and the long-press haptic, then a Material dropdown where the finger is, with the trigger highlighted while it is open. The trigger is ordinary React Native layout, so it needs no Screen or Island.
Also takes the React Native `sx` props.
| Prop | Type | Description |
|---|---|---|
| actions* | MenuAction[] | The menu's actions, top to bottom. |
| children* | ReactNode | The trigger, laid out as usual. |
| onPreviewPress | () => void | iOS: the user tapped the lifted preview, committing to it — open the detail the card stands for. |
| preview | ReactNode | iOS: lifted in place of the trigger while the menu is open — a larger version of the card, say. A snapshot of the trigger when unset. Mounted only once a finger has rested on the trigger, so a list of cards does not pay for every preview up front. |
| previewTransition | 'dismiss' | 'pop' | 'zoom' | iOS: how the preview leaves once tapped, before |
| testID | string | Test identifier — on the native view around the trigger on iOS, on the trigger's |
The trigger, laid out as usual.
iOS: the user tapped the lifted preview, committing to it — open the detail the card stands for.
iOS: lifted in place of the trigger while the menu is open — a larger version of the card, say. A snapshot of the trigger when unset. Mounted only once a finger has rested on the trigger, so a list of cards does not pay for every preview up front.
iOS: how the preview leaves once tapped, before onPreviewPress. zoom: its photo grows straight into the pushed screen, the way the App Store expands a preview — needs a ZoomTransition.Source (@hzblj/kara-ui/router) in the trigger, a preview and iOS 18, and shrinks back like dismiss otherwise. pop: UIKit's default, the preview flies out. dismiss: it shrinks back onto the trigger first. Default: zoom when the trigger holds a ZoomTransition.Source, pop otherwise.
Test identifier — on the native view around the trigger on iOS, on the trigger's Pressable on Android.
Platform notes
- The trigger is ordinary React Native layout, so it needs no
ScreenorIsland, and takes the viewsxprops. - iOS lifts
preview(or a snapshot of the trigger) above the menu. Material has no lifted preview: Android ripples, plays the long-press haptic and opens a dropdown where the finger is. - With a
ZoomTransition.Sourcein the trigger, a tap on the iOS preview zooms its photo straight into the pushed screen.