mirror of
https://github.com/hanzoai/gui.git
synced 2026-10-25 02:31:41 +00:00
203 lines
5.4 KiB
Plaintext
203 lines
5.4 KiB
Plaintext
---
|
|
title: Native UI
|
|
description: Optional native integrations for better performance and UX
|
|
name: native
|
|
---
|
|
|
|
# Native Integrations
|
|
|
|
Gui components work great out of the box, but several offer optional native
|
|
integrations for improved performance and platform-native UX. All native
|
|
integrations are opt-in - components work without them, just with slightly
|
|
different behavior.
|
|
|
|
## @hanzogui/native Package
|
|
|
|
The `@hanzogui/native` package provides setup utilities for native integrations.
|
|
Import the setup modules at your app's entry point, before any Gui imports.
|
|
|
|
```bash
|
|
npm install @hanzogui/native
|
|
```
|
|
|
|
<Notice>
|
|
`@hanzogui/native` is a light setup package. When you use one of its optional
|
|
integrations, make sure the matching native dependency is installed in your app as well,
|
|
such as `react-native-gesture-handler`, `react-native-teleport`, `zeego`, or `burnt`. In
|
|
a monorepo, install those native packages in the parent app or workspace root rather
|
|
than a leaf package.
|
|
</Notice>
|
|
|
|
## Portal
|
|
|
|
**Native portals preserve React context** - the default implementation on native
|
|
uses a JS-based approach that breaks React context, or requires you to hoist data
|
|
awkwardly. With native portals, your custom contexts (navigation, app state)
|
|
work inside Sheet, Dialog, Popover, and other portaled content.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
npm install react-native-teleport
|
|
```
|
|
|
|
```tsx
|
|
// App.tsx - before any Gui imports
|
|
import '@hanzogui/native/setup-teleport'
|
|
```
|
|
|
|
See [Portal docs](/docs/components/portal) for full details.
|
|
|
|
## Gesture Handler
|
|
|
|
**Native gesture handling** - powers two features:
|
|
|
|
1. **Press events** - `onPress` uses RNGH for more reliable press detection with
|
|
proper gesture coordination. Matches RN Pressable semantics where only the
|
|
innermost pressable fires (no double-firing with nested buttons).
|
|
|
|
2. **Sheet gestures** - makes sheets feel smoother and not get confused with
|
|
scrollable content during drags.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
npm install react-native-gesture-handler
|
|
```
|
|
|
|
```tsx
|
|
// App.tsx - before any Gui imports
|
|
import '@hanzogui/native/setup-gesture-handler'
|
|
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
|
|
export default function App() {
|
|
return (
|
|
<GestureHandlerRootView style={{ flex: 1 }}>{/* Your app */}</GestureHandlerRootView>
|
|
)
|
|
}
|
|
```
|
|
|
|
### Selective Features
|
|
|
|
If you only want RNGH for specific features, use the configurable setup:
|
|
|
|
```tsx
|
|
import { setupGestureHandler } from '@hanzogui/native/setup-gesture-handler'
|
|
|
|
// only use RNGH for sheets, not press events
|
|
setupGestureHandler({ pressEvents: false, sheet: true })
|
|
|
|
// only use RNGH for press events, not sheets
|
|
setupGestureHandler({ pressEvents: true, sheet: false })
|
|
```
|
|
|
|
### Press Event Behavior
|
|
|
|
With RNGH enabled, `onPress` follows RN Pressable semantics:
|
|
|
|
- **Nested pressables** - only the innermost fires (no event bubbling)
|
|
- **Web parity** - `onPress` calls `stopPropagation()` automatically
|
|
- **Use `onClick` on web** if you need standard DOM event bubbling
|
|
|
|
This aligns to the React Native default behavior of Pressable.
|
|
|
|
### PressBoundary
|
|
|
|
If you need a non-Gui native wrapper to block a parent Gui pressable,
|
|
use `PressBoundary` from `@hanzogui/native/gesture-handler`.
|
|
|
|
This is useful when mixing Gui pressables with React Native `Pressable`,
|
|
custom native wrappers, or other components that don't use Gui's native
|
|
press ownership automatically.
|
|
|
|
```tsx
|
|
import { PressBoundary } from '@hanzogui/native/gesture-handler'
|
|
import { Pressable } from 'react-native'
|
|
|
|
export function AvatarLink() {
|
|
return (
|
|
<PressBoundary debugName="AvatarLink">
|
|
<Pressable onPress={() => {}}>{/* your content */}</Pressable>
|
|
</PressBoundary>
|
|
)
|
|
}
|
|
```
|
|
|
|
`PressBoundary` only coordinates with Gui's native press ownership. It does
|
|
not monkey-patch React Native bubbling semantics in general.
|
|
|
|
Native `Menu.Trigger` and `ContextMenu.Trigger` already do this automatically,
|
|
so you should not need extra wrappers or empty `onPress` handlers around them.
|
|
|
|
See [Sheet docs](/docs/components/sheet) for full details.
|
|
|
|
## Menu & ContextMenu
|
|
|
|
**Native menus** - renders platform-native context menus instead of custom
|
|
overlays. Uses iOS's native menu API for haptics, blur effects, and system
|
|
integration.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
npm install zeego @react-native-menu/menu react-native-ios-context-menu react-native-ios-utilities sf-symbols-typescript
|
|
```
|
|
|
|
```tsx
|
|
// App.tsx - before any Gui imports
|
|
import '@hanzogui/native/setup-zeego'
|
|
```
|
|
|
|
Then use the `native` prop:
|
|
|
|
```tsx
|
|
<Menu native>{/* menu content */}</Menu>
|
|
```
|
|
|
|
See [Menu docs](/docs/components/menu) and
|
|
[ContextMenu docs](/docs/components/context-menu) for full details.
|
|
|
|
## Toast
|
|
|
|
**Native toasts** - uses platform-native toast implementations:
|
|
|
|
- iOS: SPIndicator (system-style indicators)
|
|
- Android: ToastAndroid
|
|
- Web: Notification API
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
npm install burnt
|
|
```
|
|
|
|
```tsx
|
|
// App.tsx - before any Gui imports
|
|
import '@hanzogui/native/setup-burnt'
|
|
```
|
|
|
|
Then use the `native` prop on ToastProvider:
|
|
|
|
```tsx
|
|
<Toast.Provider native>{/* your app */}</Toast.Provider>
|
|
```
|
|
|
|
See [Toast docs](/docs/components/toast) for full details.
|
|
|
|
## LinearGradient
|
|
|
|
**Native gradients** - uses `expo-linear-gradient` for high-performance native gradient rendering.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
npm install expo-linear-gradient
|
|
```
|
|
|
|
```tsx
|
|
// App.tsx - before any Gui imports
|
|
import '@hanzogui/native/setup-expo-linear-gradient'
|
|
```
|
|
|
|
See [LinearGradient docs](/docs/components/linear-gradient) for full details.
|