# Button
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(buttons)/button.mdx
> Interactive component that triggers an action when pressed.
## Import
```tsx
import { Button } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Button**: Main container that handles press interactions, animations, and variants. Renders string children as label or accepts compound components for custom layouts.
* **Button.Label**: Text content of the button. Inherits size and variant styling from parent Button context.
## Usage
### Basic Usage
The Button component accepts string children that automatically render as label.
```tsx
```
### With Compound Parts
Use Button.Label for explicit control over the label component.
```tsx
```
### With Icons
Combine icons with labels for enhanced visual communication.
```tsx
```
### Icon Only
Create square icon-only buttons using the isIconOnly prop.
```tsx
```
### Sizes
Control button dimensions with three size options.
```tsx
```
### Variants
Choose from seven visual variants for different emphasis levels.
```tsx
```
### Feedback Variants
The `feedbackVariant` prop controls which press feedback effects are rendered:
* `'scale-highlight'` (default): Built-in scale + highlight overlay
* `'scale-ripple'`: Built-in scale + ripple overlay
* `'scale'`: Built-in scale only (no overlay)
* `'none'`: No feedback animations at all
```tsx
{/* Scale + Highlight (default) */}
{/* Scale + Ripple */}
{/* Scale only */}
{/* No feedback */}
```
### Custom Animation
The `animation` prop controls individual sub-animations. Its shape depends on the `feedbackVariant`.
```tsx
{/* Customize scale and highlight (default feedbackVariant) */}
{/* Customize scale and ripple */}
```
### Disable Individual Animations
Disable specific sub-animations by setting them to `false`:
```tsx
{/* Disable scale, keep highlight */}
{/* Disable highlight, keep scale */}
{/* Disable both */}
```
### Disable All Animations
Use `animation={false}` to disable all feedback, or `animation="disable-all"` for cascading disable:
```tsx
```
### Loading State with Spinner
Transform button to loading state with spinner animation.
```tsx
const themeColorAccentForeground = useThemeColor('accent-foreground');
;
```
### Custom Background with LinearGradient
Add gradient backgrounds using absolute positioned elements. Use `feedbackVariant="none"` to disable the default highlight overlay, or use `feedbackVariant="scale-ripple"` for a custom ripple effect.
```tsx
import { Button, PressableFeedback } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet } from 'react-native';
{/* Gradient with no feedback overlay */}
{/* Gradient with custom ripple effect */}
```
## Example
```tsx
import { Button, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
export default function ButtonExample() {
const [
themeColorAccentForeground,
themeColorAccentSoftForeground,
themeColorDangerForeground,
themeColorDefaultForeground,
] = useThemeColor([
'accent-foreground',
'accent-soft-foreground',
'danger-foreground',
'default-foreground',
]);
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/button.tsx).
## API Reference
### Button
Button extends all props from [PressableFeedback](./pressable-feedback) (except `animation`, which is redefined) with additional button-specific props.
| prop | type | default | description |
| ----------------- | --------------------------------------------------------------------------------------------- | ------------------- | -------------------------------------------------------------- |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'outline' \| 'ghost' \| 'danger' \| 'danger-soft'` | `'primary'` | Visual variant of the button |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the button |
| `isIconOnly` | `boolean` | `false` | Whether the button displays an icon only (square aspect ratio) |
| `feedbackVariant` | `'scale-highlight' \| 'scale-ripple' \| 'scale' \| 'none'` | `'scale-highlight'` | Determines which feedback effects are rendered |
| `animation` | `ButtonAnimation` | - | Animation configuration (shape depends on `feedbackVariant`) |
For inherited props including `isDisabled`, `className`, `children`, and all Pressable props, see [PressableFeedback API Reference](./pressable-feedback#api-reference).
#### ButtonAnimation
The `animation` prop is a discriminated union based on `feedbackVariant`. It follows the `AnimationRoot` control flow:
* `true` or `undefined`: Use default animations
* `false` or `"disabled"`: Disable all feedback animations
* `"disable-all"`: Cascade-disable all animations including child compound parts
* `object`: Custom configuration with sub-animation keys (see below)
**When `feedbackVariant="scale-highlight"` (default):**
| prop | type | default | description |
| ----------- | ---------------------------------------- | ------- | ------------------------------------------------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | Scale animation config (`false` to disable) |
| `highlight` | `PressableFeedbackHighlightAnimation` | - | Highlight overlay config (`false` to disable) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Control animation state while keeping config (runtime toggle) |
**When `feedbackVariant="scale-ripple"`:**
| prop | type | default | description |
| -------- | ---------------------------------------- | ------- | ------------------------------------------------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | Scale animation config (`false` to disable) |
| `ripple` | `PressableFeedbackRippleAnimation` | - | Ripple overlay config (`false` to disable) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Control animation state while keeping config (runtime toggle) |
**When `feedbackVariant="scale"`:**
| prop | type | default | description |
| ------- | ---------------------------------------- | ------- | ------------------------------------------------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | Scale animation config (`false` to disable) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Control animation state while keeping config (runtime toggle) |
**When `feedbackVariant="none"`:**
Only `'disable-all'` is accepted as a string value. All feedback effects are disabled.
For detailed animation sub-types (`PressableFeedbackScaleAnimation`, `PressableFeedbackHighlightAnimation`, `PressableFeedbackRippleAnimation`), see [PressableFeedback API Reference](./pressable-feedback#api-reference).
### Button.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be rendered as label |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard Text props are supported |
## Hooks
### useButton
Hook to access the Button context values. Returns the button's size, variant, and disabled state.
```tsx
import { useButton } from 'heroui-native';
const { size, variant, isDisabled } = useButton();
```
#### Return Value
| property | type | description |
| ------------ | --------------------------------------------------------------------------------------------- | ------------------------------ |
| `size` | `'sm' \| 'md' \| 'lg'` | Size of the button |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'outline' \| 'ghost' \| 'danger' \| 'danger-soft'` | Visual variant of the button |
| `isDisabled` | `boolean` | Whether the button is disabled |
**Note:** This hook must be used within a `Button` component. It will throw an error if called outside of the button context.
# CloseButton
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/close-button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(buttons)/close-button.mdx
> Button component for closing dialogs, modals, or dismissing content.
## Import
```tsx
import { CloseButton } from 'heroui-native';
```
## Usage
### Basic Usage
The CloseButton component renders a close icon button with default styling.
```tsx
```
### Custom Icon Color
Customize the icon color using the `iconProps` prop.
```tsx
```
### Custom Icon Size
Adjust the icon size using the `iconProps` prop.
```tsx
```
### Custom Children
Replace the default close icon with custom content.
```tsx
```
### Disabled State
Disable the button to prevent interactions.
```tsx
```
## Example
```tsx
import { CloseButton, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export default function CloseButtonExample() {
const themeColorForeground = useThemeColor('foreground');
const themeColorDanger = useThemeColor('danger');
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/close-button.tsx).
## API Reference
### CloseButton
CloseButton extends all props from [Button](./button) component. It defaults to `variant='tertiary'`, `size='sm'`, and `isIconOnly=true`.
| prop | type | default | description |
| ----------- | ---------------------- | ------- | ------------------------------------------------ |
| `iconProps` | `CloseButtonIconProps` | - | Props for customizing the close icon |
| `children` | `React.ReactNode` | - | Custom content to replace the default close icon |
For inherited props including `isDisabled`, `className`, `animation`, `feedbackVariant` and all Pressable props, see [Button API Reference](./button#api-reference).
#### CloseButtonIconProps
| prop | type | default | description |
| ------- | -------- | ---------------------- | ----------------- |
| `size` | `number` | `20` | Size of the icon |
| `color` | `string` | Uses theme muted color | Color of the icon |
# LinkButton
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/link-button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(buttons)/link-button.mdx
> A ghost-variant button with no highlight feedback, designed for inline link-style interactions.
## Import
```tsx
import { LinkButton } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **LinkButton**: Root pressable container. Renders a `Button` with the `ghost` variant and disabled highlight feedback enforced internally. These cannot be overridden by consumers.
* **LinkButton.Label**: Text content of the link button. Inherits size and variant styling from the parent context.
## Usage
### Basic Usage
The LinkButton component renders inline link-style text that responds to press events.
```tsx
Learn more
```
### Sizes
Control the text size with the `size` prop.
```tsx
Small
Medium
Large
```
### Disabled State
Disable the link button to prevent interaction.
```tsx
Disabled link
```
### Custom Styling
Apply custom styles using the `className` prop on both root and label.
```tsx
Styled link
```
### Inline with Text
Place link buttons inline alongside regular text for terms, policies, or contextual navigation.
```tsx
I agree to the
Terms of Service
and
Privacy Policy
```
## Example
```tsx
import { Button, Checkbox, ControlField, LinkButton } from 'heroui-native';
import React from 'react';
import { Alert, View } from 'react-native';
export default function LinkButtonExample() {
const [isAgreed, setIsAgreed] = React.useState(false);
const handleTermsPress = () => Alert.alert('Terms', 'Navigate to Terms');
const handlePrivacyPress = () =>
Alert.alert('Privacy', 'Navigate to Privacy Policy');
return (
I agree to the
Terms of Service
and
Privacy Policy
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/link-button.tsx).
## API Reference
### LinkButton
Extends all [Button](./button#button) props except `variant` (enforced as `ghost` internally).
**Behavioral overrides applied internally:**
| override | value | description |
| ----------- | ------------ | --------------------------------------------------- |
| `variant` | `ghost` | Always renders as a ghost button, cannot be changed |
| `highlight` | `false` | Highlight feedback is disabled, cannot be changed |
| `className` | `h-auto p-0` | Removes default button height and padding |
### LinkButton.Label
Equivalent to [Button.Label](./button#buttonlabel). Accepts the same props.
# Menu
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/menu
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(collections)/menu.mdx
> A floating context menu with positioning, selection groups, and multiple presentation modes.
## Import
```tsx
import { Menu, SubMenu } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Menu**: Main container that manages open/close state, positioning, and provides context to child components.
* **Menu.Trigger**: Clickable element that toggles the menu visibility.
* **Menu.Portal**: Renders menu content in a portal layer above other content.
* **Menu.Overlay**: Optional background overlay to capture outside clicks and close the menu.
* **Menu.Content**: Container for menu content with two presentation modes: floating popover with positioning and collision detection, or bottom sheet modal.
* **Menu.Close**: Close button that dismisses the menu when pressed.
* **Menu.Label**: Non-interactive section heading text within the menu.
* **Menu.Group**: Groups menu items with optional selection state (none, single, multiple).
* **Menu.Item**: Pressable menu item with animated press feedback. Standalone or within a Group for selection.
* **Menu.ItemTitle**: Primary label text for a menu item.
* **Menu.ItemDescription**: Secondary description text for a menu item.
* **Menu.ItemIndicator**: Visual selection indicator (checkmark or dot) for a menu item.
* **SubMenu**: Root container that manages the expand/collapse state and provides animation context to children.
* **SubMenu.Trigger**: Pressable row that toggles the submenu open/closed. Styled like a regular menu item.
* **SubMenu.TriggerIndicator**: Animated chevron icon (default: chevron-right) that rotates when the submenu opens/closes. Place inside `SubMenu.Trigger`.
* **SubMenu.Content**: Absolutely positioned container that animates its height when the submenu opens/closes. Place `Menu.Item` elements inside.
## Usage
### Basic Usage
The Menu component uses compound parts to create a floating context menu.
```tsx
```
### With Item Descriptions
Add secondary description text to menu items alongside titles.
```tsx
```
### Single Selection
Use `Menu.Group` with `selectionMode="single"` to allow one selected item at a time.
```tsx
const [theme, setTheme] = useState>(() => new Set(['system']));
;
```
### Multiple Selection
Use `selectionMode="multiple"` to allow selecting multiple items simultaneously.
```tsx
const [textStyles, setTextStyles] = useState>(
() => new Set(['bold', 'italic'])
);
;
```
### With SubMenu
Nest a `SubMenu` inside `Menu.Content` to reveal additional items on press.
```tsx
```
### Danger Variant
Use `variant="danger"` on a menu item for destructive actions.
```tsx
```
### Placements
Control where the menu appears relative to the trigger.
```tsx
```
### Bottom Sheet Presentation
Use `presentation="bottom-sheet"` to display menu content as a bottom sheet modal.
```tsx
```
### Dot Indicator
Use `variant="dot"` on `Menu.ItemIndicator` to show a filled circle instead of a checkmark.
```tsx
```
## Example
```tsx
import type { MenuKey } from 'heroui-native';
import { Button, Menu, Separator } from 'heroui-native';
import { useState } from 'react';
import { Text, View } from 'react-native';
export default function MenuExample() {
const [textStyles, setTextStyles] = useState>(
() => new Set(['bold', 'italic'])
);
const [alignment, setAlignment] = useState>(
() => new Set(['left'])
);
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/menu.tsx).
## API Reference
### Menu
| prop | type | default | description |
| --------------- | ----------------------------- | ----------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The content of the menu |
| `presentation` | `'popover' \| 'bottom-sheet'` | `'popover'` | Presentation mode for the menu content |
| `isOpen` | `boolean` | - | Controlled open state of the menu |
| `isDefaultOpen` | `boolean` | - | Open state when initially rendered (uncontrolled) |
| `isDisabled` | `boolean` | - | Whether the menu is disabled |
| `animation` | `MenuRootAnimation` | - | Animation configuration for menu root |
| `onOpenChange` | `(open: boolean) => void` | - | Callback fired when the menu open state changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### MenuRootAnimation
Animation configuration for menu root component. Can be:
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
### Menu.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The trigger element content |
| `className` | `string` | - | Additional CSS class for the trigger |
| `isDisabled` | `boolean` | `false` | Whether the trigger is disabled |
| `asChild` | `boolean` | - | Render as child element using Slot pattern |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Menu.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The portal content |
| `className` | `string` | - | Additional CSS class for the portal container |
| `disableFullWindowOverlay` | `boolean` | `false` | Use a regular View instead of FullWindowOverlay on iOS |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `hostName` | `string` | - | Optional name of the host element for the portal |
| `forceMount` | `boolean` | - | Force mount the portal regardless of open state |
### Menu.Overlay
| prop | type | default | description |
| ----------------------- | ---------------------- | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS class for the overlay |
| `closeOnPress` | `boolean` | `true` | Whether to close the menu when the overlay is pressed |
| `animation` | `MenuOverlayAnimation` | - | Animation configuration for overlay |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `forceMount` | `boolean` | - | Force mount the overlay regardless of open state |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### MenuOverlayAnimation
Animation configuration for menu overlay component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------ | ----------------------- | ----------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.entering.value` | `EntryOrExitLayoutType` | `FadeIn.duration(200)` | Custom entering animation for overlay |
| `opacity.exiting.value` | `EntryOrExitLayoutType` | `FadeOut.duration(150)` | Custom exiting animation for overlay |
### Menu.Content (Popover)
Props when `presentation="popover"`.
| prop | type | default | description |
| ----------------- | ------------------------------------------------ | --------------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The menu content |
| `presentation` | `'popover'` | - | Presentation mode (must match Menu root) |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Where the menu appears relative to the trigger |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alignment of the menu relative to the trigger |
| `avoidCollisions` | `boolean` | `true` | Whether to reposition to avoid screen edges |
| `offset` | `number` | `9` | Distance from the trigger element in pixels |
| `alignOffset` | `number` | `0` | Offset along the alignment axis in pixels |
| `width` | `'content-fit' \| 'trigger' \| 'full' \| number` | `'content-fit'` | Content width sizing strategy |
| `className` | `string` | - | Additional CSS class for the content container |
| `animation` | `MenuContentAnimation` | - | Animation configuration for content |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### MenuContentAnimation
Animation configuration for menu popover content component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ----------------------- | ------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | Scale + fade entering animation | Custom entering animation for content |
| `exiting.value` | `EntryOrExitLayoutType` | Scale + fade exiting animation | Custom exiting animation for content |
### Menu.Content (Bottom Sheet)
Props when `presentation="bottom-sheet"`. Extends `@gorhom/bottom-sheet` BottomSheet props.
| prop | type | default | description |
| --------------------------- | ---------------------------------------- | ------- | ---------------------------------------------------- |
| `children` | `React.ReactNode` | - | The bottom sheet content |
| `presentation` | `'bottom-sheet'` | - | Presentation mode (must match Menu root) |
| `className` | `string` | - | Additional CSS class for the bottom sheet |
| `backgroundClassName` | `string` | - | Additional CSS class for the background |
| `handleIndicatorClassName` | `string` | - | Additional CSS class for the handle indicator |
| `contentContainerClassName` | `string` | - | Additional CSS class for the content container |
| `contentContainerProps` | `Omit` | - | Props for the content container |
| `animation` | `AnimationDisabled` | - | Set to `false` or `"disabled"` to disable animations |
| `...BottomSheetProps` | `Partial` | - | All `@gorhom/bottom-sheet` props are supported |
### Menu.Close
Extends `CloseButtonProps`. Automatically closes the menu when pressed.
| prop | type | default | description |
| ---------------- | ---------------------- | ------- | ------------------------------------ |
| `iconProps` | `CloseButtonIconProps` | - | Props for customizing the close icon |
| `...ButtonProps` | `ButtonRootProps` | - | All Button root props are supported |
### Menu.Group
| prop | type | default | description |
| --------------------- | ---------------------------------- | -------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The group content (Menu.Item elements) |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | The type of selection allowed in the group |
| `selectedKeys` | `Iterable` | - | Currently selected keys (controlled) |
| `defaultSelectedKeys` | `Iterable` | - | Initially selected keys (uncontrolled) |
| `isDisabled` | `boolean` | `false` | Whether the entire group is disabled |
| `disabledKeys` | `Iterable` | - | Keys of items that should be disabled |
| `shouldCloseOnSelect` | `boolean` | - | Whether selecting an item should close the menu |
| `className` | `string` | - | Additional CSS class for the group container |
| `onSelectionChange` | `(keys: Set) => void` | - | Callback fired when the selection changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Menu.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The label text content |
| `className` | `string` | - | Additional CSS class for the label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Menu.Item
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode \| ((props: MenuItemRenderProps) => ReactNode)` | - | Child elements or a render function |
| `id` | `MenuKey` | - | Unique identifier, required when inside a Menu.Group |
| `variant` | `'default' \| 'danger'` | `'default'` | Visual variant of the menu item |
| `isDisabled` | `boolean` | `false` | Whether the item is disabled |
| `isSelected` | `boolean` | - | Controlled selected state for standalone items |
| `shouldCloseOnSelect` | `boolean` | `true` | Whether pressing this item should close the menu |
| `className` | `string` | - | Additional CSS class for the item |
| `animation` | `MenuItemAnimation` | - | Animation configuration for press feedback |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `onSelectedChange` | `(selected: boolean) => void` | - | Callback when standalone item's selected state changes |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### MenuItemRenderProps
Props passed to the render function when `children` is a function.
| prop | type | description |
| ------------ | ----------------------- | --------------------------------------- |
| `isSelected` | `boolean` | Whether this item is currently selected |
| `isDisabled` | `boolean` | Whether the item is disabled |
| `isPressed` | `SharedValue` | Whether the item is currently pressed |
| `variant` | `'default' \| 'danger'` | Visual variant of the item |
#### MenuItemAnimation
Animation configuration for menu item press feedback. Can be:
* `false` or `"disabled"`: Disable all item animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------------ | ------------------ | -------------------------- | ---------------------------------------- |
| `scale.value` | `number` | `0.98` | Scale value when pressed |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | Spring animation configuration for scale |
| `backgroundColor.value` | `string` | `useThemeColor('default')` | Background color shown while pressed |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | Animation timing for background color |
### Menu.ItemTitle
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The title text content |
| `className` | `string` | - | Additional CSS class for the item title |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Menu.ItemDescription
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | The description text content |
| `className` | `string` | - | Additional CSS class for the item description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Menu.ItemIndicator
| prop | type | default | description |
| -------------- | ---------------------------- | ------------- | ------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom indicator content, defaults to checkmark or dot |
| `variant` | `'checkmark' \| 'dot'` | `'checkmark'` | Visual variant of the indicator |
| `iconProps` | `MenuItemIndicatorIconProps` | - | Icon configuration (checkmark variant) |
| `forceMount` | `boolean` | `true` | Force mount the indicator regardless of selected state |
| `className` | `string` | - | Additional CSS class for the item indicator |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### MenuItemIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ---------------------------------------------- |
| `size` | `number` | `16` | Size of the indicator icon (8 for dot variant) |
| `color` | `string` | `muted` | Color of the indicator icon |
### SubMenu
| prop | type | default | description |
| --------------- | ------------------------- | ------- | -------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The sub-menu content (trigger, content, and other items) |
| `isOpen` | `boolean` | - | Controlled open state of the sub-menu |
| `isDefaultOpen` | `boolean` | - | Open state when initially rendered (uncontrolled) |
| `isDisabled` | `boolean` | `false` | Whether the sub-menu is disabled |
| `className` | `string` | - | Additional CSS class for the root container |
| `animation` | `SubMenuRootAnimation` | - | Animation configuration for the sub-menu |
| `onOpenChange` | `(open: boolean) => void` | - | Callback fired when the sub-menu open state changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
##### SubMenuRootAnimation
Animation configuration for the SubMenu root component. Can be:
* `"disable-all"`: Disable all animations including children
* `false` or `"disabled"`: Disable only root animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------------- | ----------------------- | ------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rootContent.marginHorizontal` | `number` | `-16` | Margin horizontal when sub-menu is open |
| `rootContent.marginVertical` | `number` | `-16` | Margin vertical when sub-menu is open |
| `rootContent.paddingHorizontal` | `number` | `6` | Padding horizontal when sub-menu is open |
| `rootContent.paddingTop` | `number` | `12` | Padding top when sub-menu is open |
| `rootContent.springConfig` | `WithSpringConfig` | `{ damping: 100, stiffness: 950, mass: 3 }` | Spring configuration for expand/collapse |
#### SubMenu.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The trigger content (title, icons, indicator, etc.) |
| `textValue` | `string` | - | Accessible text value announced by screen readers |
| `className` | `string` | - | Additional CSS class for the trigger |
| `isDisabled` | `boolean` | `false` | Whether the trigger is disabled |
| `asChild` | `boolean` | - | Render as child element using Slot pattern |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### SubMenu.TriggerIndicator
Animated indicator icon that rotates when the submenu opens/closes. Defaults to a chevron-right icon.
| prop | type | default | description |
| ----------------------- | ---------------------------------- | ------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom indicator content (replaces default chevron) |
| `className` | `string` | - | Additional CSS class for the indicator |
| `iconProps` | `SubMenuTriggerIndicatorIconProps` | - | Icon configuration for the default chevron |
| `animation` | `SubMenuTriggerIndicatorAnimation` | - | Animation configuration for indicator rotation |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
##### SubMenuTriggerIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | --------------------------- |
| `size` | `number` | `14` | Size of the indicator icon |
| `color` | `string` | `muted` | Color of the indicator icon |
##### SubMenuTriggerIndicatorAnimation
Animation configuration for the trigger indicator rotation. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rotation.value` | `[number, number]` | `[0, 90]` | Rotation values \[collapsed, expanded] in degrees |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | Spring configuration for rotation |
#### SubMenu.Content
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The submenu items (Menu.Item, Menu.Group, etc.) |
| `className` | `string` | - | Additional CSS class for the content container |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
## Hooks
### useMenu
Hook to access the menu root context. Must be used within a `Menu` component.
```tsx
import { useMenu } from 'heroui-native';
const { isOpen, onOpenChange, presentation, isDisabled } = useMenu();
```
#### Returns
| property | type | description |
| -------------- | ----------------------------- | --------------------------------------- |
| `isOpen` | `boolean` | Whether the menu is currently open |
| `onOpenChange` | `(open: boolean) => void` | Callback to change the open state |
| `presentation` | `'popover' \| 'bottom-sheet'` | Current presentation mode |
| `isDisabled` | `boolean \| undefined` | Whether the menu is disabled |
| `nativeID` | `string` | Unique identifier for the menu instance |
### useMenuItem
Hook to access the menu item context. Must be used within a `Menu.Item` component.
```tsx
import { useMenuItem } from 'heroui-native';
const { id, isSelected, isDisabled, variant } = useMenuItem();
```
#### Returns
| property | type | description |
| ------------ | ----------------------- | -------------------------------------- |
| `id` | `MenuKey \| undefined` | Item identifier |
| `isSelected` | `boolean` | Whether the item is currently selected |
| `isDisabled` | `boolean` | Whether the item is disabled |
| `variant` | `'default' \| 'danger'` | Visual variant of the item |
### useMenuAnimation
Hook to access the menu animation context. Must be used within a `Menu` component.
```tsx
import { useMenuAnimation } from 'heroui-native';
const { progress, isDragging } = useMenuAnimation();
```
#### Returns
| property | type | description |
| ------------ | ---------------------- | --------------------------------------------------------- |
| `progress` | `SharedValue` | Animation progress shared value (0=idle, 1=open, 2=close) |
| `isDragging` | `SharedValue` | Whether the bottom sheet is currently being dragged |
### useSubMenu
Hook to access the sub-menu context. Must be used within a `SubMenu` component.
```tsx
import { useSubMenu } from 'heroui-native';
const { isOpen, onOpenChange, isDisabled } = useSubMenu();
```
#### Returns
| property | type | description |
| -------------- | ------------------------- | ------------------------------------------- |
| `isOpen` | `boolean` | Whether the sub-menu is currently open |
| `onOpenChange` | `(open: boolean) => void` | Callback to change the open state |
| `isDisabled` | `boolean` | Whether the sub-menu is disabled |
| `nativeID` | `string` | Unique identifier for the sub-menu instance |
## Special Notes
### Element Inspector (iOS)
Menu uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `Menu.Portal`. Tradeoff: the menu will not appear above native modals when disabled.
### Native Modal (iOS)
When a `Menu` is opened inside a screen presented as a native modal (`presentation: 'modal' | 'formSheet' | 'pageSheet'`), the menu content may render shifted upward. In the new architecture (Fabric), `react-native-screens` marks `RNSModalScreen` as a Fabric root, so the trigger's position is reported relative to the modal's origin while `FullWindowOverlay` (where the menu is mounted) is anchored to the iOS application window. Compensate by adding `safeAreaInsets.top` to `offset`:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# TagGroup
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/tag-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(collections)/tag-group.mdx
> A compound component for displaying and managing selectable tags with optional removal.
## Import
```tsx
import { TagGroup } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **TagGroup**: Main container that manages tag selection state, disabled keys, and remove functionality. Provides size and variant context to all child components.
* **TagGroup.List**: Container for rendering the list of tags with optional empty state rendering.
* **TagGroup.Item**: Individual tag within the group. Supports string children (auto-wrapped in TagGroup.ItemLabel), render function children, or custom layouts.
* **TagGroup.ItemLabel**: Text label for the tag. Automatically rendered when string children are provided, or can be used explicitly.
* **TagGroup.ItemRemoveButton**: Remove button for the tag. Must be placed explicitly when removal is needed. Only functional when `onRemove` is provided to TagGroup.
## Usage
### Basic Usage
Display a simple tag group with selectable items.
```tsx
News
Travel
Gaming
```
### Single Selection Mode
Allow only one tag to be selected at a time.
```tsx
News
Travel
Gaming
```
### Multiple Selection Mode
Allow multiple tags to be selected simultaneously.
```tsx
News
Travel
Gaming
```
### Controlled Selection
Control selection state with `selectedKeys` and `onSelectionChange`.
```tsx
const [selected, setSelected] = useState(new Set(['news']));
News
Travel
Gaming
;
```
### Variants
Apply different visual variants to the tags.
```tsx
News
Travel
News
Travel
```
### Sizes
Control the size of all tags in the group.
```tsx
News
News
News
```
### With Remove Button
Add remove buttons to tags by providing `onRemove` and placing `TagGroup.ItemRemoveButton` in each item.
```tsx
const [tags, setTags] = useState([
{ id: 'news', name: 'News' },
{ id: 'travel', name: 'Travel' },
]);
const onRemove = (keys) => {
setTags((prev) => prev.filter((tag) => !keys.has(tag.id)));
};
{tags.map((tag) => (
{tag.name}
))}
;
```
### Render Function Children
Use a render function to access `isSelected` and `isDisabled` for custom layouts.
```tsx
{({ isSelected }) => (
<>
News
>
)}
```
### Empty State
Render custom content when the list has no tags.
```tsx
(
No categories found
)}
>
{tags.map((tag) => (
{tag.name}
))}
```
### Disabled Tags
Disable individual tags or the entire group.
```tsx
News
Travel
Gaming
```
## Example
```tsx
import { TagGroup, Label, Description, FieldError } from 'heroui-native';
import { useState, useMemo } from 'react';
import { View } from 'react-native';
export default function TagGroupExample() {
const [selected, setSelected] = useState(new Set());
const isInvalid = useMemo(
() => Array.from(selected).length === 0,
[selected]
);
return (
Laundry
Fitness center
Parking
Swimming pool
Breakfast
{`Selected: ${Array.from(selected).join(', ')}`}
Please select at least one category
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/tag-group.tsx).
## API Reference
### TagGroup
| prop | type | default | description |
| --------------------- | ---------------------------------- | ----------- | ---------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Child elements to render inside the tag group |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of all tags in the group |
| `variant` | `'default' \| 'surface'` | `'default'` | Visual variant of all tags in the group |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | The type of selection allowed in the tag group |
| `selectedKeys` | `Iterable` | - | The currently selected keys (controlled) |
| `defaultSelectedKeys` | `Iterable` | - | The initial selected keys (uncontrolled) |
| `disabledKeys` | `Iterable` | - | Keys of tags that should be disabled |
| `isDisabled` | `boolean` | `false` | Whether the entire tag group is disabled |
| `isInvalid` | `boolean` | `false` | Whether the tag group is in an invalid state |
| `isRequired` | `boolean` | `false` | Whether the tag group is required |
| `className` | `string` | - | Additional CSS classes for the tag group container |
| `style` | `StyleProp` | - | Additional styles for the tag group container |
| `animation` | `"disable-all" \| undefined` | - | Use `"disable-all"` to disable all animations including children |
| `onSelectionChange` | `(keys: Set) => void` | - | Handler called when the selection changes |
| `onRemove` | `(keys: Set) => void` | - | Handler called when tags are removed |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### TagKey
`string | number` — Key type for identifying tags within a TagGroup.
#### Animation
Use `animation="disable-all"` to disable all animations including children. Omit or use `undefined` for default animations.
### TagGroup.List
| prop | type | default | description |
| ------------------ | ----------------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Child elements to render inside the list |
| `className` | `string` | - | Additional CSS classes for the list container |
| `style` | `StyleProp` | - | Additional styles for the list container |
| `renderEmptyState` | `() => React.ReactNode` | - | Function to render when the list has no tags |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### TagGroup.Item
| prop | type | default | description |
| ------------------- | ----------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((renderProps: TagRenderProps) => React.ReactNode)` | - | Tag content: string, elements, or a render function receiving TagRenderProps |
| `id` | `TagKey` | - | Unique identifier for this tag |
| `isDisabled` | `boolean` | - | Whether this specific tag is disabled |
| `className` | `string` | - | Additional CSS classes for the tag |
| `style` | `StyleProp` | - | Additional styles for the tag |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### TagRenderProps
| prop | type | description |
| ------------ | --------- | --------------------------------------------------------------------------- |
| `isSelected` | `boolean` | Whether the tag is currently selected |
| `isDisabled` | `boolean` | Whether the tag is disabled (merged from root, disabledKeys, and item prop) |
### TagGroup.ItemLabel
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Text content to render |
| `className` | `string` | - | Additional CSS classes for the label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### TagGroup.ItemRemoveButton
| prop | type | default | description |
| ------------------- | -------------------------- | ------- | ---------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom icon or content for the remove button. Defaults to close icon when omitted |
| `className` | `string` | - | Additional CSS classes for the remove button |
| `iconProps` | `TagRemoveButtonIconProps` | - | Props for customizing the default close icon. Only applies when no children are provided |
| `hitSlop` | `number` | `8` | Extends the touchable area |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### TagRemoveButtonIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ----------------- |
| `size` | `number` | `12` | Size of the icon |
| `color` | `string` | - | Color of the icon |
## Hooks
### useTagGroup
Hook to access the tag group root context. Must be used within a `TagGroup` component.
```tsx
import { useTagGroup } from 'heroui-native';
const {
selectedKeys,
disabledKeys,
selectionMode,
onSelectionChange,
onRemove,
isDisabled,
isInvalid,
isRequired,
} = useTagGroup();
```
#### Returns
| property | type | description |
| ------------------- | -------------------------------------------- | ---------------------------------------------- |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | The type of selection allowed in the tag group |
| `selectedKeys` | `Set` | Currently selected tag keys |
| `disabledKeys` | `Set` | Keys of disabled tags |
| `onSelectionChange` | `(keys: Set) => void` | Callback when selection changes |
| `onRemove` | `((keys: Set) => void) \| undefined` | Callback when tags are removed |
| `isDisabled` | `boolean` | Whether the entire tag group is disabled |
| `isInvalid` | `boolean` | Whether the tag group is in an invalid state |
| `isRequired` | `boolean` | Whether the tag group is required |
### useTagGroupItem
Hook to access the tag item context. Must be used within a `TagGroup.Item` component.
```tsx
import { useTagGroupItem } from 'heroui-native';
const { id, isSelected, isDisabled, allowsRemoving } = useTagGroupItem();
```
#### Returns
| property | type | description |
| ---------------- | --------- | --------------------------------------------------------------------------- |
| `id` | `TagKey` | Unique identifier for this tag |
| `isSelected` | `boolean` | Whether the tag is currently selected |
| `isDisabled` | `boolean` | Whether the tag is disabled |
| `allowsRemoving` | `boolean` | Whether the tag can be removed (true when onRemove is provided to TagGroup) |
# Slider
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/slider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(controls)/slider.mdx
> A draggable input for selecting a value or range within a bounded interval.
## Import
```tsx
import { Slider } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Slider**: Main container that manages slider value state, orientation, and provides context to all sub-components. Supports single value and range modes.
* **Slider.Output**: Optional display of the current value(s). Supports render functions for custom formatting. Shows a formatted value label by default.
* **Slider.Track**: Sizing container for Fill and Thumb elements. Reports its layout size for position calculations. Supports tap-to-position and render-function children for dynamic content (e.g. multiple thumbs for range sliders).
* **Slider.Fill**: Responsive fill bar that stretches the full cross-axis of the Track. Only the main-axis position and size are computed.
* **Slider.Thumb**: Draggable thumb element using react-native-gesture-handler. Centered on the cross-axis by the Track layout. Animates scale on press via react-native-reanimated. Each thumb gets `role="slider"` with full `accessibilityValue`.
## Usage
### Basic Usage
The Slider component uses compound parts to create a draggable value input.
```tsx
```
### With Label and Output
Display a label alongside the current value output.
```tsx
```
### Vertical Orientation
Render the slider vertically by setting `orientation` to `"vertical"`.
```tsx
```
### Range Slider
Pass an array as the value and use a render function on `Slider.Track` to create multiple thumbs.
```tsx
{({ state }) => (
<>
{state.values.map((_, i) => (
))}
>
)}
```
### Controlled Value
Use `value` and `onChange` for controlled mode. The `onChangeEnd` callback fires when a drag or tap interaction completes.
```tsx
const [volume, setVolume] = useState(50);
save(v)}>
;
```
### Custom Styling
Apply custom styles using `className`, `classNames`, or `styles` on the thumb and other sub-components.
```tsx
```
### Disabled
Disable the entire slider to prevent interaction.
```tsx
```
## Example
```tsx
import { Label, Slider } from 'heroui-native';
import { useState } from 'react';
import { View, Text } from 'react-native';
export default function SliderExample() {
const [price, setPrice] = useState([200, 800]);
return (
{({ state }) => (
<>
{state.values.map((_, i) => (
))}
>
)}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/slider.tsx).
## API Reference
### Slider
| prop | type | default | description |
| --------------- | ------------------------------------- | -------------- | --------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the slider |
| `value` | `number \| number[]` | - | Current slider value (controlled mode) |
| `defaultValue` | `number \| number[]` | `0` | Default slider value (uncontrolled mode) |
| `minValue` | `number` | `0` | Minimum value of the slider |
| `maxValue` | `number` | `100` | Maximum value of the slider |
| `step` | `number` | `1` | Step increment for the slider |
| `formatOptions` | `Intl.NumberFormatOptions` | - | Number format options for value label formatting |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Orientation of the slider |
| `isDisabled` | `boolean` | `false` | Whether the slider is disabled |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration for the slider |
| `onChange` | `(value: number \| number[]) => void` | - | Callback fired when the slider value changes during interaction |
| `onChangeEnd` | `(value: number \| number[]) => void` | - | Callback fired when an interaction completes (drag end or tap) |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AnimationRootDisableAll
Animation configuration for the slider root component. Can be:
* `"disable-all"`: Disable all animations including children
* `undefined`: Use default animations
### Slider.Output
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: SliderRenderProps) => React.ReactNode)` | - | Custom content or render function receiving slider state. Defaults to formatted value label |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SliderRenderProps
| prop | type | description |
| ------------- | ------------------- | ------------------------------ |
| `state` | `SliderState` | Current slider state |
| `orientation` | `SliderOrientation` | Orientation of the slider |
| `isDisabled` | `boolean` | Whether the slider is disabled |
#### SliderState
| prop | type | description |
| -------------------- | --------------------------- | ---------------------------------------------- |
| `values` | `number[]` | Current slider value(s) by thumb index |
| `getThumbValueLabel` | `(index: number) => string` | Returns the formatted string label for a thumb |
### Slider.Track
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: SliderRenderProps) => React.ReactNode)` | - | Content or render function receiving slider state for dynamic thumb rendering |
| `className` | `string` | - | Additional CSS classes |
| `hitSlop` | `number` | `8` | Extra touch area around the track |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Slider.Fill
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Slider.Thumb
| prop | type | default | description |
| -------------- | ---------------------------------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom thumb content. Defaults to an animated knob |
| `index` | `number` | `0` | Index of this thumb within the slider |
| `isDisabled` | `boolean` | - | Whether this individual thumb is disabled |
| `className` | `string` | - | Additional CSS classes for the thumb container |
| `classNames` | `ElementSlots` | - | Additional CSS classes for thumb slots |
| `styles` | `Partial>` | - | Inline styles for thumb slots |
| `hitSlop` | `number` | `12` | Extra touch area around the thumb |
| `animation` | `SliderThumbAnimation` | - | Animation configuration for the thumb knob |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### ElementSlots\
| prop | type | description |
| ---------------- | -------- | ----------------------------------------------- |
| `thumbContainer` | `string` | Custom class name for the outer thumb container |
| `thumbKnob` | `string` | Custom class name for the inner thumb knob |
#### styles
| prop | type | description |
| ---------------- | ----------- | ------------------------------------ |
| `thumbContainer` | `ViewStyle` | Styles for the outer thumb container |
| `thumbKnob` | `ViewStyle` | Styles for the inner thumb knob |
#### SliderThumbAnimation
Animation configuration for the thumb knob scale effect. Can be:
* `false` or `"disabled"`: Disable thumb animation
* `undefined`: Use default animations
* `object`: Custom scale animation configuration
| prop | type | default | description |
| -------------------- | ------------------ | -------------------------------------------- | ----------------------------------------------- |
| `scale.value` | `[number, number]` | `[1, 0.9]` | Scale values \[idle, dragging] |
| `scale.springConfig` | `WithSpringConfig` | `{ damping: 15, stiffness: 200, mass: 0.5 }` | Spring animation configuration for scale effect |
## Hooks
### useSlider
Hook to access the slider context. Must be used within a `Slider` component.
```tsx
import { useSlider } from 'heroui-native';
const { values, orientation, isDisabled, getThumbValueLabel } = useSlider();
```
#### Returns
| property | type | description |
| -------------------- | -------------------------------------------- | -------------------------------------------------------------- |
| `values` | `number[]` | Current slider values (one per thumb) |
| `minValue` | `number` | Minimum value of the slider |
| `maxValue` | `number` | Maximum value of the slider |
| `step` | `number` | Step increment |
| `orientation` | `'horizontal' \| 'vertical'` | Current orientation |
| `isDisabled` | `boolean` | Whether the slider is disabled |
| `formatOptions` | `Intl.NumberFormatOptions \| undefined` | Number format options for labels |
| `getThumbPercent` | `(index: number) => number` | Returns the percentage position (0–1) for a given thumb index |
| `getThumbValueLabel` | `(index: number) => string` | Returns the formatted label for a given thumb index |
| `getThumbMinValue` | `(index: number) => number` | Returns the minimum allowed value for a thumb |
| `getThumbMaxValue` | `(index: number) => number` | Returns the maximum allowed value for a thumb |
| `updateValue` | `(index: number, newValue: number) => void` | Updates a thumb value by index |
| `isThumbDragging` | `(index: number) => boolean` | Returns whether a given thumb is currently being dragged |
| `setThumbDragging` | `(index: number, dragging: boolean) => void` | Sets the dragging state of a thumb |
| `trackSize` | `number` | Track layout width (horizontal) or height (vertical) in pixels |
| `thumbSize` | `number` | Measured thumb size (main-axis dimension) in pixels |
# Switch
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/switch
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(controls)/switch.mdx
> A toggle control that allows users to switch between on and off states.
## Import
```tsx
import { Switch } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **Switch**: Main container that handles toggle state and user interaction. Renders default thumb if no children provided. Animates scale (on press) and background color based on selection state. Acts as a pressable area for toggling.
* **Switch.Thumb**: Optional sliding thumb element that moves between positions. Uses spring animation for smooth transitions. Can contain custom content like icons or be customized with different styles and animations.
* **Switch.StartContent**: Optional content displayed on the left side of the switch. Typically used for icons or text that appear when switch is off. Positioned absolutely within the switch container.
* **Switch.EndContent**: Optional content displayed on the right side of the switch. Typically used for icons or text that appear when switch is on. Positioned absolutely within the switch container.
## Usage
### Basic Usage
The Switch component renders with default thumb if no children provided.
```tsx
```
### With Custom Thumb
Replace the default thumb with custom content using the Thumb component.
```tsx
...
```
### With Start and End Content
Add icons or text that appear on each side of the switch.
```tsx
...
...
```
### With Render Function
Use render functions for dynamic content based on switch state.
```tsx
{({ isSelected, isDisabled }) => (
<>
{({ isSelected }) => (isSelected ? : )}
>
)}
```
### With Custom Animations
Customize animations for the switch root and thumb components.
```tsx
```
### Disable Animations
Disable animations entirely or only for specific components.
```tsx
{
/* Disable all animations including children */
}
;
{
/* Disable only root animations, thumb can still animate */
}
;
```
## Example
```tsx
import { Switch } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { View } from 'react-native';
import Animated, { ZoomIn } from 'react-native-reanimated';
export default function SwitchExample() {
const [darkMode, setDarkMode] = React.useState(false);
return (
{darkMode && (
)}
{!darkMode && (
)}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/switch.tsx).
## API Reference
### Switch
| prop | type | default | description |
| --------------------------- | -------------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode \| ((props: SwitchRenderProps) => React.ReactNode)` | `undefined` | Content to render inside the switch, or a render function |
| `isSelected` | `boolean` | `undefined` | Whether the switch is currently selected |
| `isDisabled` | `boolean` | `false` | Whether the switch is disabled and cannot be interacted with |
| `className` | `string` | `undefined` | Custom class name for the switch |
| `animation` | `SwitchRootAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `onSelectedChange` | `(isSelected: boolean) => void` | - | Callback fired when the switch selection state changes |
| `...AnimatedPressableProps` | `AnimatedProps` | - | All React Native Reanimated Pressable props are supported |
#### SwitchRenderProps
| prop | type | description |
| ------------ | --------- | ------------------------------ |
| `isSelected` | `boolean` | Whether the switch is selected |
| `isDisabled` | `boolean` | Whether the switch is disabled |
#### SwitchRootAnimation
Animation configuration for Switch component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------------ | ---------------------------------------- | -------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `scale.value` | `[number, number]` | `[1, 0.96]` | Scale values \[unpressed, pressed] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | Animation timing configuration |
| `backgroundColor.value` | `[string, string]` | Uses theme colors | Background color values \[unselected, selected] |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) }` | Animation timing configuration |
### Switch.Thumb
| prop | type | default | description |
| ----------------------- | -------------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode \| ((props: SwitchRenderProps) => React.ReactNode)` | `undefined` | Content to render inside the thumb, or a render function |
| `className` | `string` | `undefined` | Custom class name for the thumb element |
| `animation` | `SwitchThumbAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SwitchThumbAnimation
Animation configuration for Switch.Thumb component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------------ | ----------------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `left.value` | `number` | `2` | Offset value from the edges (left when unselected, right when selected) |
| `left.springConfig` | `WithSpringConfig` | `{ damping: 120, stiffness: 1600, mass: 2 }` | Spring animation configuration for thumb position |
| `backgroundColor.value` | `[string, string]` | `['white', theme accent-foreground color]` | Background color values \[unselected, selected] |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) }` | Animation timing configuration |
### Switch.StartContent
| prop | type | default | description |
| -------------- | ----------------- | ----------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | Content to render inside the switch content |
| `className` | `string` | `undefined` | Custom class name for the content element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Switch.EndContent
| prop | type | default | description |
| -------------- | ----------------- | ----------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | Content to render inside the switch content |
| `className` | `string` | `undefined` | Custom class name for the content element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
## Hooks
### useSwitch
A hook that provides access to the Switch context. This is useful when building custom switch components or when you need to access switch state in child components.
**Returns:**
| Property | Type | Description |
| ------------ | --------- | ------------------------------ |
| `isSelected` | `boolean` | Whether the switch is selected |
| `isDisabled` | `boolean` | Whether the switch is disabled |
**Example:**
```tsx
import { useSwitch } from 'heroui-native';
function CustomSwitchContent() {
const { isSelected, isDisabled } = useSwitch();
return (
Status: {isSelected ? 'On' : 'Off'}
{isDisabled && Disabled}
);
}
// Usage
;
```
## Special Notes
### Border Styling
If you need to apply a border to the switch root, use the `outline` style properties instead of `border`. This ensures the border doesn't affect the internal layout calculations for the thumb position:
```tsx
```
Using `outline` keeps the border visual without impacting the switch's internal width calculations, ensuring the thumb animates correctly.
### Integration with ControlField
The Switch component integrates seamlessly with ControlField for press state sharing:
```tsx
import { Description, ControlField, Label } from 'heroui-native';
Receive push notifications
```
When wrapped in ControlField, the Switch will automatically respond to press events on the entire ControlField container, creating a larger touch target and better user experience.
# Chip
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/chip
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(data-display)/chip.mdx
> Displays a compact element in a capsule shape.
## Import
```tsx
import { Chip } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **Chip**: Main container that displays a compact element
* **Chip.Label**: Text content of the chip
## Usage
### Basic Usage
The Chip component displays text or custom content in a capsule shape.
```tsx
Basic Chip
```
### Sizes
Control the chip size with the `size` prop.
```tsx
Small
Medium
Large
```
### Variants
Choose between different visual styles with the `variant` prop.
```tsx
Primary
Secondary
Tertiary
Soft
```
### Colors
Apply different color themes with the `color` prop.
```tsx
Accent
Default
Success
Warning
Danger
```
### With Icons
Add icons or custom content alongside text using compound components.
```tsx
Featured
Close
```
### Custom Styling
Apply custom styles using className or style props.
```tsx
Custom
```
### Disable All Animations
Disable all animations including children by using the `"disable-all"` value for the `animation` prop.
```tsx
{
/* Disable all animations including children */
}
No Animations;
```
## Example
```tsx
import { Chip } from 'heroui-native';
import { View, Text } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
export default function ChipExample() {
return (
Small
Medium
Large
Primary
Success
Premium
Remove
Custom
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/chip.tsx).
## API Reference
### Chip
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to render inside the chip |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the chip |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'soft'` | `'primary'` | Visual variant of the chip |
| `color` | `'accent' \| 'default' \| 'success' \| 'warning' \| 'danger'` | `'accent'` | Color theme of the chip |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `...PressableProps` | `PressableProps` | - | All Pressable props are supported |
### Chip.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------- |
| `children` | `React.ReactNode` | - | Text or content to render as the label |
| `className` | `string` | - | Additional CSS classes to apply |
| `...TextProps` | `TextProps` | - | All standard Text props are supported |
## Hooks
### useChip
Hook to access the Chip context values. Returns the chip's size, variant, and color.
```tsx
import { useChip } from 'heroui-native';
const { size, variant, color } = useChip();
```
#### Return Value
| property | type | description |
| --------- | ------------------------------------------------------------- | -------------------------- |
| `size` | `'sm' \| 'md' \| 'lg'` | Size of the chip |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'soft'` | Visual variant of the chip |
| `color` | `'accent' \| 'default' \| 'success' \| 'warning' \| 'danger'` | Color theme of the chip |
**Note:** This hook must be used within a `Chip` component. It will throw an error if called outside of the chip context.
# Alert
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/alert
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(feedback)/alert.mdx
> Displays important messages and notifications to users with status indicators.
## Import
```tsx
import { Alert } from 'heroui-native';
```
## Anatomy
```tsx
...
...
```
* **Alert**: Main container with `role="alert"` and status-based styling. Provides status context to sub-components via a primitive context.
* **Alert.Indicator**: Renders a status-appropriate icon by default. Accepts custom children to override the default icon. Supports `iconProps` for customising size and color.
* **Alert.Content**: Wrapper for the title and description. Provides layout structure for text content.
* **Alert.Title**: Heading text with status-based color. Connected to root via `aria-labelledby`.
* **Alert.Description**: Body text rendered with muted color. Connected to root via `aria-describedby`.
## Usage
### Basic Usage
The Alert component uses compound parts to display a notification with an icon, title, and description.
```tsx
New features available
Check out our latest updates including dark mode support and improved
accessibility features.
```
### Status Variants
Set the `status` prop to control the icon and title color. Available statuses are `default`, `accent`, `success`, `warning`, and `danger`.
```tsx
Success
...
Scheduled maintenance
...
Unable to connect
...
```
### Title Only
Omit `Alert.Description` for a compact single-line alert.
```tsx
Profile updated successfully
```
### With Action Buttons
Place additional elements like buttons alongside the content.
```tsx
Update available
A new version of the application is available.
```
### Custom Indicator
Replace the default status icon by passing custom children to `Alert.Indicator`.
```tsx
Processing your request
Please wait while we sync your data.
```
### Custom Styling
Apply custom styles using the `className` prop on the root and compound parts.
```tsx
...
...
```
## Example
```tsx
import { Alert, Button, CloseButton } from 'heroui-native';
import { View } from 'react-native';
export default function AlertExample() {
return (
Update available
A new version of the application is available. Please refresh to get
the latest features and bug fixes.
Unable to connect to server
Unable to connect to the server. Check your internet connection and
try again.
Profile updated successfully
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/alert.tsx).
## API Reference
### Alert
| prop | type | default | description |
| -------------- | ------------------------------------------------------------- | ----------- | ----------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to render inside the alert |
| `status` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | Status controlling the icon and color treatment |
| `id` | `string \| number` | - | Unique identifier for the alert. Auto-generated when not provided |
| `className` | `string` | - | Additional CSS classes |
| `style` | `ViewStyle` | - | Additional styles applied to the root container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Alert.Indicator
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom children to render instead of the default status icon |
| `className` | `string` | - | Additional CSS classes |
| `iconProps` | `AlertIconProps` | - | Props passed to the default status icon (size and color overrides) |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AlertIconProps
| prop | type | default | description |
| ------- | -------- | ------------ | ---------------------- |
| `size` | `number` | `18` | Icon size in pixels |
| `color` | `string` | status color | Icon color as a string |
### Alert.Content
| prop | type | default | description |
| -------------- | ----------------- | ------- | --------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements (typically Alert.Title and Alert.Description) |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Alert.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Title text content |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Alert.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Description text content |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
## Hooks
### useAlert
Hook to access the alert root context. Must be used within an `Alert` component.
```tsx
import { useAlert } from 'heroui-native';
const { status, nativeID } = useAlert();
```
#### Returns
| property | type | description |
| ---------- | ------------------------------------------------------------- | ------------------------------------------------------------ |
| `status` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | Current alert status for sub-component styling |
| `nativeID` | `string` | Unique identifier used for accessibility and ARIA attributes |
# SkeletonGroup
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/skeleton-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(feedback)/skeleton-group.mdx
> Coordinates multiple skeleton loading placeholders with centralized animation control.
## Import
```tsx
import { SkeletonGroup } from 'heroui-native';
```
## Anatomy
```tsx
```
* **SkeletonGroup**: Root container that provides centralized control for all skeleton items
* **SkeletonGroup.Item**: Individual skeleton item that inherits props from the parent group
## Usage
### Basic Usage
The SkeletonGroup component manages multiple skeleton items with shared loading state and animation.
```tsx
```
### With Container Layout
Use className on the group to control layout of skeleton items.
```tsx
```
### With isSkeletonOnly for Pure Skeleton Layouts
Use `isSkeletonOnly` when the group contains only skeleton placeholders with layout wrappers (like View) that have no content to render in the loaded state. This prop hides the entire group when `isLoading` is false, preventing empty containers from affecting your layout.
```tsx
{/* This View is only for layout, no content */}
```
### With Animation Variants
Control animation style for all items in the group.
```tsx
```
### With Custom Animation Configuration
Configure shimmer or pulse animations for the entire group.
```tsx
```
### With Enter/Exit Animations
Apply Reanimated transitions when the group appears or disappears.
```tsx
```
## Example
```tsx
import { Card, SkeletonGroup, Avatar } from 'heroui-native';
import { useState } from 'react';
import { Text, View, Image } from 'react-native';
export default function SkeletonGroupExample() {
const [isLoading, setIsLoading] = useState(true);
return (
John Doe
@johndoe
This is the first line of the post content.
Second line with more interesting content to read.
Last line is shorter.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/skeleton-group.tsx).
## API Reference
### SkeletonGroup
| prop | type | default | description |
| ----------------------- | -------------------------------- | ----------- | ---------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | SkeletonGroup.Item components and layout elements |
| `isLoading` | `boolean` | `true` | Whether the skeleton items are currently loading |
| `isSkeletonOnly` | `boolean` | `false` | Hides entire group when isLoading is false (for skeleton-only layouts) |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | `'shimmer'` | Animation variant for all items in the group |
| `animation` | `SkeletonRootAnimation` | - | Animation configuration |
| `className` | `string` | - | Additional CSS classes for the group container |
| `style` | `StyleProp` | - | Custom styles for the group container |
| `...Animated.ViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
#### SkeletonRootAnimation
Animation configuration for SkeletonGroup component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------ | ---------------------------------------- | --------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn` | Custom entering animation |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut` | Custom exiting animation |
| `shimmer.duration` | `number` | `1500` | Animation duration in milliseconds |
| `shimmer.speed` | `number` | `1` | Speed multiplier for the animation |
| `shimmer.highlightColor` | `string` | - | Highlight color for the shimmer effect |
| `shimmer.easing` | `EasingFunction` | `Easing.linear` | Easing function for the animation |
| `pulse.duration` | `number` | `1000` | Animation duration in milliseconds |
| `pulse.minOpacity` | `number` | `0.5` | Minimum opacity value |
| `pulse.maxOpacity` | `number` | `1` | Maximum opacity value |
| `pulse.easing` | `EasingFunction` | `Easing.inOut(Easing.ease)` | Easing function for the animation |
### SkeletonGroup.Item
| prop | type | default | description |
| ----------------------- | -------------------------------- | --------- | ------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to show when not loading |
| `isLoading` | `boolean` | inherited | Whether the skeleton is currently loading (overrides group setting) |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | inherited | Animation variant (overrides group setting) |
| `animation` | `SkeletonRootAnimation` | inherited | Animation configuration (overrides group setting) |
| `className` | `string` | - | Additional CSS classes for styling the item |
| `...Animated.ViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
## Special Notes
### Props Inheritance
SkeletonGroup.Item components inherit all animation-related props from their parent SkeletonGroup:
* `isLoading`
* `variant`
* `animation`
Individual items can override any inherited prop by providing their own value.
# Skeleton
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/skeleton
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(feedback)/skeleton.mdx
> Displays a loading placeholder with shimmer or pulse animation effects.
## Import
```tsx
import { Skeleton } from 'heroui-native';
```
## Anatomy
The Skeleton component is a simple wrapper that renders a placeholder for content that is loading. It does not have any child components.
```tsx
```
## Usage
### Basic Usage
The Skeleton component creates an animated placeholder while content is loading.
```tsx
```
### With Content
Show skeleton while loading, then display content when ready.
```tsx
Loaded Content
```
### Animation Variants
Control the animation style with the `variant` prop.
```tsx
```
### Custom Shimmer Configuration
Customize the shimmer effect with duration, speed, and highlight color.
```tsx
...
```
### Custom Pulse Configuration
Configure pulse animation with duration and opacity range.
```tsx
...
```
### Shape Variations
Create different skeleton shapes using className for styling.
```tsx
```
### Custom Enter/Exit Animations
Apply custom Reanimated transitions when skeleton appears or disappears.
```tsx
...
```
## Example
```tsx
import { Avatar, Card, Skeleton } from 'heroui-native';
import { useState } from 'react';
import { Image, Text, View } from 'react-native';
export default function SkeletonExample() {
const [isLoading, setIsLoading] = useState(true);
return (
John Doe
@johndoe
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/skeleton.tsx).
## API Reference
### Skeleton
| prop | type | default | description |
| ----------------------- | -------------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Content to show when not loading |
| `isLoading` | `boolean` | `true` | Whether the skeleton is currently loading |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | `'shimmer'` | Animation variant |
| `animation` | `SkeletonRootAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `className` | `string` | - | Additional CSS classes for styling |
| `...Animated.ViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
#### SkeletonRootAnimation
Animation configuration for Skeleton component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------ | ---------------------------------------- | --------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn` | Custom entering animation |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut` | Custom exiting animation |
| `shimmer.duration` | `number` | `1500` | Animation duration in milliseconds |
| `shimmer.speed` | `number` | `1` | Speed multiplier for the animation |
| `shimmer.highlightColor` | `string` | - | Highlight color for the shimmer effect |
| `shimmer.easing` | `EasingFunction` | `Easing.linear` | Easing function for the animation |
| `pulse.duration` | `number` | `1000` | Animation duration in milliseconds |
| `pulse.minOpacity` | `number` | `0.5` | Minimum opacity value |
| `pulse.maxOpacity` | `number` | `1` | Maximum opacity value |
| `pulse.easing` | `EasingFunction` | `Easing.inOut(Easing.ease)` | Easing function for the animation |
# Spinner
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/spinner
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(feedback)/spinner.mdx
> Displays an animated loading indicator.
## Import
```tsx
import { Spinner } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **Spinner**: Main container that controls loading state, size, and color. Renders a default animated indicator if no children provided.
* **Spinner.Indicator**: Optional sub-component for customizing animation configuration and icon appearance. Accepts custom children to replace the default icon.
## Usage
### Basic Usage
The Spinner component displays a rotating loading indicator.
```tsx
```
### Sizes
Control the spinner size with the `size` prop.
```tsx
```
### Colors
Use predefined color variants or custom colors.
```tsx
```
### Loading State
Control the visibility of the spinner with the `isLoading` prop.
```tsx
```
### Animation Speed
Customize the rotation speed using the `animation` prop on the Indicator component.
```tsx
```
### Custom Icon
Replace the default spinner icon with custom content.
```tsx
const themeColorForeground = useThemeColor('foreground')
⏳
```
## Example
```tsx
import { Spinner } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
export default function SpinnerExample() {
const [isLoading, setIsLoading] = React.useState(true);
return (
Loading content...
Processing...
setIsLoading(!isLoading)}>
{isLoading ? 'Tap to stop' : 'Tap to start'}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/spinner.tsx).
## API Reference
### Spinner
| prop | type | default | description |
| -------------- | ----------------------------------------------------------- | ----------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | Content to render inside the spinner |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the spinner |
| `color` | `'default' \| 'success' \| 'warning' \| 'danger' \| string` | `'default'` | Color theme of the spinner |
| `isLoading` | `boolean` | `true` | Whether the spinner is loading |
| `className` | `string` | `undefined` | Custom class name for the spinner |
| `animation` | `SpinnerRootAnimation` | - | Animation configuration |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SpinnerRootAnimation
Animation configuration for Spinner component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.out(Easing.ease))` | Custom entering animation |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(100)` | Custom exiting animation |
### Spinner.Indicator
| prop | type | default | description |
| ----------------------- | --------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | `undefined` | Content to render inside the indicator |
| `iconProps` | `SpinnerIconProps` | `undefined` | Props for the default icon |
| `className` | `string` | `undefined` | Custom class name for the indicator element |
| `animation` | `SpinnerIndicatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### SpinnerIndicatorAnimation
Animation configuration for Spinner.Indicator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ----------------- | ---------------------------- | --------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rotation.speed` | `number` | `1.1` | Rotation speed multiplier |
| `rotation.easing` | `WithTimingConfig['easing']` | `Easing.linear` | Animation easing configuration |
### SpinnerIconProps
| prop | type | default | description |
| -------- | ------------------ | ---------------- | ------------------ |
| `width` | `number \| string` | `24` | Width of the icon |
| `height` | `number \| string` | `24` | Height of the icon |
| `color` | `string` | `'currentColor'` | Color of the icon |
# Checkbox
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/checkbox
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/checkbox.mdx
> A selectable control that allows users to toggle between checked and unchecked states.
## Import
```tsx
import { Checkbox } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **Checkbox**: Main container that handles selection state and user interaction. Renders default indicator with animated checkmark if no children provided. Automatically detects surface context for proper styling. Features press scale animation that can be customized or disabled. Supports render function children to access state (`isSelected`, `isInvalid`, `isDisabled`).
* **Checkbox.Indicator**: Optional checkmark container with default slide, scale, opacity, and border radius animations when selected. Renders animated check icon with SVG path drawing animation if no children provided. All animations can be individually customized or disabled. Supports render function children to access state.
## Usage
### Basic Usage
The Checkbox component renders with a default animated indicator if no children are provided. It automatically detects whether it's on a surface background for proper styling.
```tsx
```
### With Custom Indicator
Use a render function in the Indicator to show/hide custom icons based on state.
```tsx
{({ isSelected }) => (isSelected ? : null)}
```
### Invalid State
Show validation errors with the `isInvalid` prop, which applies danger color styling.
```tsx
```
### Custom Animations
Customize or disable animations for both the root checkbox and indicator.
```tsx
{
/* Disable all animations (root and indicator) */
}
;
{
/* Disable only root animation */
}
;
{
/* Disable only indicator animation */
}
;
{
/* Custom animation configuration */
}
;
```
## Example
```tsx
import {
Checkbox,
Description,
ControlField,
Label,
Separator,
Surface,
} from "heroui-native";
import React from 'react';
import { View, Text } from 'react-native';
interface CheckboxFieldProps {
isSelected: boolean;
onSelectedChange: (value: boolean) => void;
title: string;
description: string;
}
const CheckboxField: React.FC = ({
isSelected,
onSelectedChange,
title,
description,
}) => {
return (
{description}
);
};
export default function BasicUsage() {
const [fields, setFields] = React.useState({
newsletter: true,
marketing: false,
terms: false,
});
const fieldConfigs: Record<
keyof typeof fields,
{ title: string; description: string }
> = {
newsletter: {
title: 'Subscribe to newsletter',
description: 'Get weekly updates about new features and tips',
},
marketing: {
title: 'Marketing communications',
description: 'Receive promotional emails and special offers',
},
terms: {
title: 'Accept terms and conditions',
description: 'Agree to our Terms of Service and Privacy Policy',
},
};
const handleFieldChange = (key: keyof typeof fields) => (value: boolean) => {
setFields((prev) => ({ ...prev, [key]: value }));
};
const fieldKeys = Object.keys(fields) as Array;
return (
{fieldKeys.map((key, index) => (
{index > 0 && }
))}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/checkbox.tsx).
## API Reference
### Checkbox
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | Child elements or render function to customize the checkbox |
| `isSelected` | `boolean` | `undefined` | Whether the checkbox is currently selected |
| `onSelectedChange` | `(isSelected: boolean) => void` | `undefined` | Callback fired when the checkbox selection state changes |
| `isDisabled` | `boolean` | `false` | Whether the checkbox is disabled and cannot be interacted with |
| `isInvalid` | `boolean` | `false` | Whether the checkbox is invalid (shows danger color) |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | Variant style for the checkbox |
| `hitSlop` | `number` | `6` | Hit slop for the pressable area |
| `animation` | `CheckboxRootAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `className` | `string` | `undefined` | Additional CSS classes to apply |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported (except disabled) |
#### CheckboxRenderProps
| prop | type | description |
| ------------ | --------- | -------------------------------- |
| `isSelected` | `boolean` | Whether the checkbox is selected |
| `isInvalid` | `boolean` | Whether the checkbox is invalid |
| `isDisabled` | `boolean` | Whether the checkbox is disabled |
#### CheckboxRootAnimation
Animation configuration for checkbox root component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| -------------------- | ---------------------------------------- | ------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `scale.value` | `[number, number]` | `[1, 0.96]` | Scale values \[unpressed, pressed] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | Animation timing configuration |
### Checkbox.Indicator
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | Content or render function for the checkbox indicator |
| `className` | `string` | `undefined` | Additional CSS classes for the indicator |
| `iconProps` | `CheckboxIndicatorIconProps` | `undefined` | Custom props for the default animated check icon |
| `animation` | `CheckboxIndicatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...AnimatedViewProps` | `AnimatedProps` | - | All standard React Native Animated View props are supported |
#### CheckboxIndicatorIconProps
Props for customizing the default animated check icon.
| prop | type | description |
| --------------- | -------- | ------------------------------------------------ |
| `size` | `number` | Icon size |
| `strokeWidth` | `number` | Icon stroke width |
| `color` | `string` | Icon color (defaults to theme accent-foreground) |
| `enterDuration` | `number` | Duration of enter animation (check appearing) |
| `exitDuration` | `number` | Duration of exit animation (check disappearing) |
#### CheckboxIndicatorAnimation
Animation configuration for checkbox indicator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| --------------------------- | ----------------------- | ------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 1]` | Opacity values \[unselected, selected] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | Animation timing configuration |
| `borderRadius.value` | `[number, number]` | `[8, 0]` | Border radius values \[unselected, selected] |
| `borderRadius.timingConfig` | `WithTimingConfig` | `{ duration: 50 }` | Animation timing configuration |
| `translateX.value` | `[number, number]` | `[-4, 0]` | TranslateX values \[unselected, selected] |
| `translateX.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | Animation timing configuration |
| `scale.value` | `[number, number]` | `[0.8, 1]` | Scale values \[unselected, selected] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | Animation timing configuration |
## Hooks
### useCheckbox
Hook to access checkbox context values within custom components or compound components.
```tsx
import { useCheckbox } from 'heroui-native';
const CustomIndicator = () => {
const { isSelected, isInvalid, isDisabled } = useCheckbox();
// ... your implementation
};
```
**Returns:** `UseCheckboxReturn`
| property | type | description |
| ------------------ | ---------------------------------------------- | -------------------------------------------------------------- |
| `isSelected` | `boolean \| undefined` | Whether the checkbox is currently selected |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | Callback function to change the checkbox selection state |
| `isDisabled` | `boolean` | Whether the checkbox is disabled and cannot be interacted with |
| `isInvalid` | `boolean` | Whether the checkbox is invalid (shows danger color) |
| `nativeID` | `string \| undefined` | Native ID for the checkbox element |
**Note:** This hook must be used within a `Checkbox` component. It will throw an error if called outside of the checkbox context.
# ControlField
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/control-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/control-field.mdx
> A field component that combines a label, description (or other content), and a control component (Switch or Checkbox) into a single pressable area.
## Import
```tsx
import { ControlField } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **ControlField**: Root container that manages layout and state propagation
* **Label**: Primary text label for the control (from [Label](./label) component)
* **Description**: Secondary descriptive helper text (from [Description](./description) component)
* **ControlField.Indicator**: Container for the form control component ([Switch](./switch), [Checkbox](./checkbox), [Radio](./radio))
* **FieldError**: Validation error message display (from [FieldError](./field-error) component)
## Usage
### Basic Usage
ControlField wraps form controls to provide consistent layout and state management.
```tsx
```
### With Description
Add helper text below the label using the Description component.
```tsx
Receive push notifications about your account activity
```
### With Error Message
Display validation errors using the ErrorMessage component.
```tsx
By checking this box, you agree to our Terms of Service
This field is required
```
### Disabled State
Control interactivity with the disabled prop.
```tsx
This field is disabled
```
### Disabling All Animations
Disable all animations including children by using `"disable-all"`. This cascades down to all child components.
```tsx
Description text
```
## Example
```tsx
import {
Checkbox,
Description,
FieldError,
ControlField,
Label,
Switch,
} from 'heroui-native';
import React from 'react';
import { ScrollView, View } from 'react-native';
export default function ControlFieldExample() {
const [notifications, setNotifications] = React.useState(false);
const [terms, setTerms] = React.useState(false);
const [newsletter, setNewsletter] = React.useState(true);
return (
Receive push notifications about your account activity
By checking this box, you agree to our Terms of Service
This field is required
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/control-field.tsx).
## API Reference
### ControlField
| prop | type | default | description |
| ----------------- | -------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| children | `React.ReactNode \| ((props: ControlFieldRenderProps) => React.ReactNode)` | - | Content to render inside the form control, or a render function |
| isSelected | `boolean` | `undefined` | Whether the control is selected/checked |
| isDisabled | `boolean` | `false` | Whether the form control is disabled |
| isInvalid | `boolean` | `false` | Whether the form control is invalid |
| isRequired | `boolean` | `false` | Whether the form control is required |
| className | `string` | - | Custom class name for the root element |
| onSelectedChange | `(isSelected: boolean) => void` | - | Callback when selection state changes |
| animation | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| ...PressableProps | `PressableProps` | - | All React Native Pressable props are supported |
### Label
The `Label` component automatically consumes form state (`isDisabled`, `isInvalid`) from the ControlField context.
**Note**: For complete prop documentation, see the [Label component documentation](./label).
### Description
The `Description` component automatically consumes form state (`isDisabled`, `isInvalid`) from the ControlField context.
**Note**: For complete prop documentation, see the [Description component documentation](./description).
### ControlField.Indicator
| prop | type | default | description |
| ------------ | ----------------------------------- | ---------- | ---------------------------------------------------------- |
| children | `React.ReactNode` | - | Control component to render (Switch, Checkbox, Radio) |
| variant | `'checkbox' \| 'radio' \| 'switch'` | `'switch'` | Variant of the control to render when no children provided |
| className | `string` | - | Custom class name for the indicator element |
| ...ViewProps | `ViewProps` | - | All React Native View props are supported |
**Note**: When children are provided, the component automatically passes down `isSelected`, `onSelectedChange`, `isDisabled`, and `isInvalid` props from the ControlField context if they are not already present on the child component. When using the `radio` variant, the Radio component renders in standalone mode (outside of a RadioGroup).
### FieldError
The `FieldError` component automatically consumes form state (`isInvalid`) from the ControlField context.
**Note**: For complete prop documentation, see the [FieldError component documentation](./field-error). The error message visibility is controlled by the `isInvalid` state of the parent ControlField.
## Hooks
### useControlField
**Returns:**
| property | type | description |
| ------------------ | ---------------------------------------------- | ---------------------------------------------- |
| `isSelected` | `boolean \| undefined` | Whether the control is selected/checked |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | Callback when selection state changes |
| `isDisabled` | `boolean` | Whether the form control is disabled |
| `isInvalid` | `boolean` | Whether the form control is invalid |
| `isPressed` | `SharedValue` | Reanimated shared value indicating press state |
# Description
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/description
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/description.mdx
> Text component for providing accessible descriptions and helper text for form fields and other UI elements.
## Import
```tsx
import { Description } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **Description**: Text component that displays description or helper text with muted styling. Can be linked to form fields via `nativeID` for accessibility support.
## Usage
### Basic Usage
Display description text with default muted styling.
```tsx
This is a helpful description.
```
### With Form Fields
Provide accessible descriptions for form fields using the `nativeID` prop.
```tsx
We'll never share your email with anyone else.
```
### Accessibility Linking
Link descriptions to form fields for screen reader support by using `nativeID` and `aria-describedby`.
```tsx
Use at least 8 characters with a mix of letters, numbers, and symbols.
```
### Hiding on Invalid State
Control whether the description should be hidden when the form field is invalid using the `hideOnInvalid` prop.
```tsx
We'll never share your email with anyone else.
Please enter a valid email address
```
When `hideOnInvalid` is `true`, the description will be hidden when the field is invalid. When `false` (default), the description remains visible even when invalid.
## Example
```tsx
import { Description, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function DescriptionExample() {
return (
We'll never share your email with anyone else.
Use at least 8 characters with a mix of letters, numbers, and symbols.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/description.tsx).
## API Reference
### Description
| prop | type | default | description |
| --------------- | ----------------------------------- | ------- | ------------------------------------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Description text content |
| `className` | `string` | - | Additional CSS classes to apply |
| `nativeID` | `string` | - | Native ID for accessibility. Used to link description to form fields via aria-describedby. |
| `isInvalid` | `boolean` | - | Whether the description is in an invalid state (overrides context) |
| `isDisabled` | `boolean` | - | Whether the description is disabled (overrides context) |
| `hideOnInvalid` | `boolean` | `false` | Whether to hide the description when invalid |
| `animation` | `DescriptionAnimation \| undefined` | - | Animation configuration for description transitions |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
# FieldError
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/field-error
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/field-error.mdx
> Displays validation error message content with smooth animations.
## Import
```tsx
import { FieldError } from 'heroui-native';
```
## Anatomy
```tsx
Error message content
```
* **FieldError**: Main container that displays error messages with smooth animations. Accepts string children which are automatically wrapped with Text component, or custom React components for more complex layouts. Controls visibility through the `isInvalid` prop and supports custom entering/exiting animations.
## Usage
### Basic Usage
The FieldError component displays error messages when validation fails.
```tsx
This field is required
```
### Controlled Visibility
Control when the error appears using the `isInvalid` prop. When used inside a form field component (like TextField), FieldError automatically consumes the form-item-state context.
```tsx
const [isInvalid, setIsInvalid] = useState(false);
Please enter a valid email address;
```
### With Form Fields
FieldError automatically consumes form state from TextField via the form-item-state context.
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
Please enter a valid email address
```
### Custom Content
Pass custom React components as children instead of strings.
```tsx
Invalid input
```
### Custom Animations
Override default entering and exiting animations using the `animation` prop.
```tsx
import { SlideInDown, SlideOutUp } from 'react-native-reanimated';
Field validation failed
;
```
Disable animations entirely:
```tsx
Field validation failed
```
### Custom Styling
Apply custom styles to the container and text elements.
```tsx
Password must be at least 8 characters
```
### Custom Text Props
Pass additional props to the Text component when children is a string.
```tsx
This is a very long error message that might need to be truncated
```
## Example
```tsx
import { Description, FieldError, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
export default function FieldErrorExample() {
const [email, setEmail] = useState('');
const [isInvalid, setIsInvalid] = useState(false);
const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const handleBlur = () => {
setIsInvalid(email !== '' && !isValidEmail);
};
return (
We'll use this to contact you
Please enter a valid email address
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/field-error.tsx).
## API Reference
### FieldError
| prop | type | default | description |
| ---------------------- | --------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | The content of the error field. String children are wrapped with Text |
| `isInvalid` | `boolean` | `undefined` | Controls the visibility of the error field (overrides form-item-state context). When used inside TextField, automatically consumes form state |
| `animation` | `FieldErrorRootAnimation` | - | Animation configuration |
| `className` | `string` | `undefined` | Additional CSS classes for the container |
| `classNames` | `ElementSlots` | `undefined` | Additional CSS classes for different parts of the component |
| `styles` | `{ container?: ViewStyle; text?: TextStyle }` | `undefined` | Styles for different parts of the field error |
| `textProps` | `TextProps` | `undefined` | Additional props to pass to the Text component when children is a string |
| `...AnimatedViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
**classNames prop:** `ElementSlots` provides type-safe CSS classes for different parts of the field error component. Available slots: `container`, `text`.
#### `styles`
| prop | type | description |
| ----------- | ----------- | --------------------------- |
| `container` | `ViewStyle` | Styles for the container |
| `text` | `TextStyle` | Styles for the text content |
#### FieldErrorRootAnimation
Animation configuration for field error root component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ---------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(150)`
`.easing(Easing.out(Easing.ease))` | Custom entering animation for field error |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(100)`
`.easing(Easing.out(Easing.ease))` | Custom exiting animation for field error |
# InputGroup
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/input-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/input-group.mdx
> A compound layout component that groups an input with optional prefix and suffix decorators.
## Import
```tsx
import { InputGroup } from 'heroui-native';
```
## Anatomy
```tsx
...
...
```
* **InputGroup**: Layout container that wraps Prefix, Input, and Suffix. Provides animation settings and a measurement context so Prefix/Suffix widths are automatically applied as padding on the Input.
* **InputGroup.Prefix**: Absolutely positioned View anchored to the left side of the Input. Its measured width is applied as `paddingLeft` on InputGroup.Input automatically.
* **InputGroup.Suffix**: Absolutely positioned View anchored to the right side of the Input. Its measured width is applied as `paddingRight` on InputGroup.Input automatically.
* **InputGroup.Input**: Pass-through to the Input component. Accepts all Input props directly. Automatically receives paddingLeft/paddingRight from measured Prefix/Suffix.
## Usage
### Basic Usage
The InputGroup component uses compound parts to attach prefix and suffix content to an input.
```tsx
...
...
```
### With Prefix Only
Attach leading content such as icons to the input.
```tsx
```
### With Suffix Only
Attach trailing content such as icons to the input.
```tsx
```
### Decorative vs Interactive
Set `isDecorative` on Prefix or Suffix to make touches pass through to the Input and hide the content from screen readers. Omit it when the decorator contains interactive elements.
```tsx
```
### Disabled State
Disable the entire input group. The disabled state cascades to all child components.
```tsx
```
### With TextField Integration
Combine with TextField, Label, and Description for full form field support.
```tsx
We'll never share your email
```
## Example
```tsx
import { InputGroup } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
export default function InputGroupExample() {
const [value, setValue] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
setIsPasswordVisible(!isPasswordVisible)}
hitSlop={20}
>
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input-group.tsx).
## API Reference
### InputGroup
| prop | type | default | description |
| -------------- | ------------------------- | ------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the input group |
| `className` | `string` | - | Additional CSS classes |
| `isDisabled` | `boolean` | `false` | Whether the entire input group and its children are disabled |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration for input group |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AnimationRootDisableAll
Animation configuration for the InputGroup root component. Can be:
* `"disable-all"`: Disable all animations including children (cascades down)
* `undefined`: Use default animations
### InputGroup.Prefix
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to render inside the prefix |
| `className` | `string` | - | Additional CSS classes |
| `isDecorative` | `boolean` | `false` | When true, touches pass through to the Input and content is hidden from screen readers |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### InputGroup.Suffix
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to render inside the suffix |
| `className` | `string` | - | Additional CSS classes |
| `isDecorative` | `boolean` | `false` | When true, touches pass through to the Input and content is hidden from screen readers |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### InputGroup.Input
Pass-through to the [Input](./input) component. Accepts all Input props directly.
# InputOTP
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/input-otp
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/input-otp.mdx
> Input component for entering one-time passwords (OTP) with individual character slots, animations, and validation support.
## Import
```tsx
import { InputOTP } from 'heroui-native';
```
## Anatomy
```tsx
```
* **InputOTP**: Main container that manages OTP input state, handles text changes, and provides context to child components. Manages focus, validation, and character input.
* **InputOTP.Group**: Container for grouping multiple slots together. Use this to visually group related slots (e.g., groups of 3 digits).
* **InputOTP.Slot**: Individual slot that displays a single character or placeholder. Each slot must have a unique index matching its position in the OTP sequence. When no children are provided, automatically renders SlotPlaceholder, SlotValue, and SlotCaret.
* **InputOTP.SlotPlaceholder**: Text component that displays the placeholder character for a slot when it's empty. Used by default in Slot if no children provided.
* **InputOTP.SlotValue**: Text component that displays the actual character value for a slot with animations. Used by default in Slot if no children provided.
* **InputOTP.SlotCaret**: Animated caret indicator that shows the current input position. Place this inside a Slot to show where the user is currently typing.
* **InputOTP.Separator**: Visual separator between groups of slots. Use this to visually separate different groups of OTP digits.
## Usage
### Basic Usage
Create a 6-digit OTP input with grouped slots and separator.
```tsx
console.log(code)}>
```
### Four Digits
Create a simple 4-digit PIN input.
```tsx
console.log(code)}>
```
### With Placeholder
Provide custom placeholder characters for each slot position.
```tsx
console.log(code)}
>
{({ slots }) => (
<>
{slots.map((slot) => (
))}
>
)}
```
### Controlled Value
Control the OTP value programmatically.
```tsx
const [value, setValue] = useState('');
;
```
### With Validation
Display validation errors when the OTP is invalid.
```tsx
```
### With Pattern
Restrict input to specific character patterns using regex. Three predefined patterns are available: `REGEXP_ONLY_DIGITS` (matches digits 0-9), `REGEXP_ONLY_CHARS` (matches alphabetic characters a-z, A-Z), and `REGEXP_ONLY_DIGITS_AND_CHARS` (matches both digits and alphabetic characters).
```tsx
import { InputOTP, REGEXP_ONLY_CHARS } from 'heroui-native';
console.log(code)}
>
;
```
### Custom Layout
Use render props in Group to create custom slot layouts.
```tsx
{({ slots, isFocused, isInvalid }) => (
<>
{slots.map((slot) => (
))}
>
)}
```
### Inside a Bottom Sheet
When rendering an InputOTP inside a `BottomSheet`, use the `useBottomSheetAwareHandlers` hook to wire keyboard avoidance handlers. Pass the returned `onFocus` and `onBlur` to InputOTP.
> **Note**: `useBottomSheetAwareHandlers` must be used inside a `BottomSheet`. Call it from a child component rendered inside `BottomSheet.Content` — outside of a `BottomSheet` context the returned handlers are no-ops.
```tsx
import { InputOTP, useBottomSheetAwareHandlers } from 'heroui-native';
const BottomSheetOTPInput = () => {
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
return (
);
};
```
## Example
```tsx
import { InputOTP, Label, Description, type InputOTPRef } from 'heroui-native';
import { View } from 'react-native';
import { useRef } from 'react';
export default function InputOTPExample() {
const ref = useRef(null);
const onComplete = (code: string) => {
console.log('OTP completed:', code);
setTimeout(() => {
ref.current?.clear();
}, 1000);
};
return (
We've sent a code to a****@gmail.com
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input-otp.tsx).
## API Reference
### InputOTP
| prop | type | default | description |
| -------------------------- | ----------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| `maxLength` | `number` | - | Maximum length of the OTP (required) |
| `value` | `string` | - | Controlled value for the OTP input |
| `defaultValue` | `string` | - | Default value for uncontrolled usage |
| `onChange` | `(value: string) => void` | - | Callback when value changes |
| `onComplete` | `(value: string) => void` | - | Handler called when all slots are filled |
| `isDisabled` | `boolean` | `false` | Whether the input is disabled |
| `isInvalid` | `boolean` | `false` | Whether the input is in an invalid state |
| `pattern` | `string` | - | Regex pattern for allowed characters (e.g., REGEXP\_ONLY\_DIGITS, REGEXP\_ONLY\_CHARS) |
| `inputMode` | `TextInputProps['inputMode']` | `'numeric'` | Input mode for the input |
| `placeholder` | `string` | - | Placeholder text for the input. Each character corresponds to a slot position |
| `placeholderTextColor` | `string` | - | Placeholder text color for all slots |
| `placeholderTextClassName` | `string` | - | Placeholder text class name for all slots |
| `pasteTransformer` | `(text: string) => string` | - | Transform pasted text (e.g., remove hyphens). Defaults to removing non-matching characters |
| `onFocus` | `(e: FocusEvent) => void` | - | Handler for focus events |
| `onBlur` | `(e: BlurEvent) => void` | - | Handler for blur events |
| `textInputProps` | `Omit` | - | Additional props to pass to the underlying TextInput component |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the InputOTP |
| `className` | `string` | - | Additional CSS classes to apply |
| `style` | `PressableProps['style']` | - | Style to pass to the container Pressable component |
| `isBottomSheetAware` | `boolean` | `true` | Whether the InputOTP automatically handles keyboard state when rendered inside a BottomSheet. Set to `false` to disable |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
### InputOTP.Group
| prop | type | default | description |
| -------------- | --------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `children` | `React.ReactNode \| ((props: InputOTPGroupRenderProps) => React.ReactNode)` | - | Children elements to be rendered inside the group, or a render function that receives slot data and other context values |
| `className` | `string` | - | Additional CSS classes to apply |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### InputOTPGroupRenderProps
| prop | type | description |
| ------------ | ------------ | ---------------------------------------- |
| `slots` | `SlotData[]` | Array of slot data for each position |
| `maxLength` | `number` | Maximum length of the OTP |
| `value` | `string` | Current OTP value |
| `isFocused` | `boolean` | Whether the input is currently focused |
| `isDisabled` | `boolean` | Whether the input is disabled |
| `isInvalid` | `boolean` | Whether the input is in an invalid state |
### InputOTP.Slot
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------------------------------------------------------------------- |
| `index` | `number` | - | Zero-based index of the slot (required). Must be between 0 and maxLength - 1 |
| `children` | `React.ReactNode` | - | Custom slot content. If not provided, defaults to SlotPlaceholder, SlotValue, and SlotCaret |
| `className` | `string` | - | Additional CSS classes to apply |
| `style` | `ViewStyle` | - | Additional styles to apply |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### InputOTP.SlotPlaceholder
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------------------------- |
| `children` | `string` | - | Text content to display (optional, defaults to slot.placeholderChar) |
| `className` | `string` | - | Additional CSS classes to apply |
| `style` | `TextStyle` | - | Additional styles to apply |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### InputOTP.SlotValue
| prop | type | default | description |
| -------------- | ---------------------------- | ------- | --------------------------------------------------------- |
| `children` | `string` | - | Text content to display (optional, defaults to slot.char) |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `InputOTPSlotValueAnimation` | - | Animation configuration for SlotValue |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
#### InputOTPSlotValueAnimation
Animation configuration for InputOTP.SlotValue component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------ | ----------------------- | ---------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `wrapper.entering` | `EntryOrExitLayoutType` | `FadeIn.duration(250)` | Entering animation for wrapper |
| `wrapper.exiting` | `EntryOrExitLayoutType` | `FadeOut.duration(100)` | Exiting animation for wrapper |
| `text.entering` | `EntryOrExitLayoutType` | `FlipInXDown.duration(250).easing(...)` | Entering animation for text |
| `text.exiting` | `EntryOrExitLayoutType` | `FlipOutXDown.duration(250).easing(...)` | Exiting animation for text |
### InputOTP.SlotCaret
| prop | type | default | description |
| ----------------------- | ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes to apply |
| `style` | `ViewStyle` | - | Additional styles to apply |
| `animation` | `InputOTPSlotCaretAnimation` | - | Animation configuration for SlotCaret |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active. When `false`, the animated style is removed and you can implement custom logic |
| `pointerEvents` | `'none' \| 'auto' \| ...` | `'none'` | Pointer events configuration |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### InputOTPSlotCaretAnimation
Animation configuration for InputOTP.SlotCaret component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------ | ----------------------- | ---------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 1]` | Opacity values \[min, max] |
| `opacity.duration` | `number` | `500` | Animation duration in milliseconds |
| `height.value` | `[number, number]` | `[16, 18]` | Height values \[min, max] in pixels |
| `height.duration` | `number` | `500` | Animation duration in milliseconds |
### InputOTP.Separator
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes to apply |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
## Hooks
### useInputOTP
Hook to access the InputOTP root context. Must be used within an `InputOTP` component.
```tsx
const { value, maxLength, isFocused, isDisabled, isInvalid, slots } =
useInputOTP();
```
### useInputOTPSlot
Hook to access the InputOTP.Slot context. Must be used within an `InputOTP.Slot` component.
```tsx
const { slot, isActive, isCaretVisible } = useInputOTPSlot();
```
# Input
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/input
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/input.mdx
> A text input component with styled border and background for collecting user input.
## Import
```tsx
import { Input } from 'heroui-native';
```
## Usage
### Basic Usage
Input can be used standalone or within a TextField component.
```tsx
import { Input } from 'heroui-native';
;
```
### Within TextField
Input works seamlessly with TextField for complete form structure.
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### With Validation
Display error state when the input is invalid.
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
Please enter a valid email
;
```
### With Local Invalid State Override
Override the context's invalid state for the input.
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
Email format is incorrect
;
```
### Disabled State
Disable the input to prevent interaction.
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### With Variant
Use different variants to style the input based on context.
```tsx
import { Input, Label, TextField } from 'heroui-native';
```
### Custom Styling
Customize the input appearance using className.
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### Inside a Bottom Sheet
When rendering an Input inside a `BottomSheet`, use the `useBottomSheetAwareHandlers` hook to wire keyboard avoidance handlers. Pass the returned `onFocus` and `onBlur` to the Input.
> **Note**: `useBottomSheetAwareHandlers` must be used inside a `BottomSheet`. Call it from a child component rendered inside `BottomSheet.Content` — outside of a `BottomSheet` context the returned handlers are no-ops.
```tsx
import { Input, TextField, useBottomSheetAwareHandlers } from 'heroui-native';
const BottomSheetTextInput = () => {
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
return (
);
};
```
## Example
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Description, Input, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export const TextInputContent = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
We'll never share your email with anyone else.
setIsPasswordVisible(!isPasswordVisible)}
>
Password must be at least 6 characters
);
};
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input.tsx).
## API Reference
### Input
| prop | type | default | description |
| ------------------------- | -------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------- |
| isInvalid | `boolean` | `undefined` | Whether the input is in an invalid state (overrides context) |
| variant | `'primary' \| 'secondary'` | `'primary'` | Variant style for the input |
| className | `string` | - | Custom class name for the input |
| selectionColorClassName | `string` | `"accent-accent"` | Custom className for the selection color |
| placeholderColorClassName | `string` | `"field-placeholder"` | Custom className for the placeholder text color |
| isBottomSheetAware | `boolean` | `true` | Whether the input automatically handles keyboard state when rendered inside a BottomSheet. Set to `false` to disable |
| animation | `AnimationRoot` | `undefined` | Animation configuration for the input |
| ...TextInputProps | `TextInputProps` | - | All standard React Native TextInput props are supported |
> **Note**: When used within a TextField component, Input automatically consumes form state (isDisabled, isInvalid) from TextField via the form-item-state context.
# Label
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/label
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/label.mdx
> Text component for labeling form fields and other UI elements with support for required indicators and validation states.
## Import
```tsx
import { Label } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Label**: Root container that manages label state and provides context to child components. When string children are provided, automatically renders as Label.Text. Supports disabled, required, and invalid states.
* **Label.Text**: Text content of the label. Displays the label text and automatically shows an asterisk when the label is required. Changes color when invalid or disabled.
## Usage
### Basic Usage
Display a label with text content. String children are automatically rendered as Label.Text.
```tsx
```
### With Form Fields
Use Label with form fields to provide accessible labels.
```tsx
```
### Required Fields
Show an asterisk indicator for required fields using the `isRequired` prop.
```tsx
```
### Invalid State
Display labels in an invalid state to indicate validation errors.
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
Passwords do not match
```
### Disabled State
Disable labels to indicate non-interactive fields.
```tsx
```
### Custom Layout
Use compound components for custom label layouts.
```tsx
```
### Custom Styling
Apply custom styles using className, classNames, or styles props.
```tsx
```
## Example
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function LabelExample() {
return (
Passwords do not match
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/label.tsx).
## API Reference
### Label
| prop | type | default | description |
| ------------------- | ---------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Label content. When string is provided, automatically renders as Label.Text. Otherwise renders children as-is |
| `isRequired` | `boolean` | `false` | Whether the label is required. Shows asterisk indicator when true |
| `isInvalid` | `boolean` | `false` | Whether the label is in an invalid state. Changes text color to danger |
| `isDisabled` | `boolean` | `false` | Whether the label is disabled. Applies disabled styling and prevents interaction |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Label.Text
| prop | type | default | description |
| -------------- | ---------------------------------------- | ------- | ---------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Label text content |
| `className` | `string` | - | Additional CSS classes to apply to the text element |
| `classNames` | `ElementSlots` | - | Additional CSS classes for different parts of the label |
| `styles` | `Partial>` | - | Styles for different parts of the label |
| `nativeID` | `string` | - | Native ID for accessibility. Used to link label to form fields via aria-labelledby |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
#### `ElementSlots`
| prop | type | description |
| ---------- | -------- | ------------------------------ |
| `text` | `string` | CSS classes for the label text |
| `asterisk` | `string` | CSS classes for the asterisk |
#### `styles`
| prop | type | description |
| ---------- | ----------- | ------------------------- |
| `text` | `TextStyle` | Styles for the label text |
| `asterisk` | `TextStyle` | Styles for the asterisk |
# RadioGroup
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/radio-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/radio-group.mdx
> A set of radio buttons where only one option can be selected at a time.
## Import
```tsx
import { RadioGroup } from 'heroui-native';
```
## Anatomy
```tsx
...
...
```
* **RadioGroup**: Container that manages the selection state of radio items. Supports both horizontal and vertical orientations.
* **RadioGroup.Item**: Individual radio option within a RadioGroup. Must be used inside RadioGroup. Handles selection state and renders a default `` indicator when text children are provided. Supports render function children to access state (`isSelected`, `isInvalid`, `isDisabled`).
* **Label**: Optional clickable text label for the radio option. Linked to the radio for accessibility. Use the [Label](./label) component directly.
* **Description**: Optional secondary text below the label. Provides additional context about the radio option. Use the [Description](./description) component directly.
* **Radio**: The [Radio](./radio) component used inside `RadioGroup.Item` to render the radio indicator. Automatically detects the `RadioGroupItem` context and derives `isSelected`, `isDisabled`, `isInvalid`, and `variant` from it.
* **Radio.Indicator**: Optional container for the radio circle. Renders default thumb if no children provided. Manages the visual selection state. See [Radio](./radio) for full API.
* **Radio.IndicatorThumb**: Optional inner circle that appears when selected. Animates scale based on selection. Can be replaced with custom content. See [Radio](./radio) for full API.
* **FieldError**: Error message displayed when radio group is invalid. Shown with animation below the radio group content. Use the [FieldError](./field-error) component directly.
## Usage
### Basic Usage
RadioGroup with simple string children automatically renders title and indicator.
```tsx
Option 1
Option 2
Option 3
```
### With Descriptions
Add descriptive text below each radio option for additional context.
```tsx
import { RadioGroup, Radio, Label, Description } from 'heroui-native';
import { View } from 'react-native';
Delivered in 5-7 business days
Delivered in 2-3 business days
;
```
### Custom Indicator
Replace the default indicator thumb with custom content using `Radio` sub-components.
```tsx
import { RadioGroup, Radio, Label } from 'heroui-native';
{({ isSelected }) => (
<>
{isSelected && (
)}
>
)}
;
```
### With Render Function
Use a render function on RadioGroup.Item to access state and customize the entire content.
```tsx
import { RadioGroup, Radio, Label } from 'heroui-native';
{({ isSelected, isInvalid, isDisabled }) => (
<>
{isSelected && }
>
)}
;
```
### With Error Message
Display validation errors below the radio group.
```tsx
import { RadioGroup, FieldError } from 'heroui-native';
function RadioGroupWithError() {
const [value, setValue] = React.useState(undefined);
return (
I agree to the terms
I do not agree
Please select an option to continue
);
}
```
## Example
```tsx
import {
Description,
Label,
Radio,
RadioGroup,
Separator,
Surface,
} from 'heroui-native';
import React from 'react';
import { View } from 'react-native';
export default function RadioGroupExample() {
const [selection, setSelection] = React.useState('desc1');
return (
Delivered in 5-7 business days
Delivered in 2-3 business days
Delivered next business day
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/radio-group.tsx).
## API Reference
### RadioGroup
| prop | type | default | description |
| --------------- | ---------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | Radio group content |
| `value` | `string \| undefined` | `undefined` | The currently selected value of the radio group |
| `onValueChange` | `(val: string) => void` | `undefined` | Callback fired when the selected value changes |
| `isDisabled` | `boolean` | `false` | Whether the entire radio group is disabled |
| `isInvalid` | `boolean` | `false` | Whether the radio group is invalid |
| `variant` | `'primary' \| 'secondary'` | `undefined` | Variant style for the radio group (inherited by items if not set on item) |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `className` | `string` | `undefined` | Custom class name |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### RadioGroup.Item
| prop | type | default | description |
| ------------------- | ---------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: RadioGroupItemRenderProps) => React.ReactNode)` | `undefined` | Radio item content or render function to customize the radio item |
| `value` | `string` | `undefined` | The value associated with this radio item |
| `isDisabled` | `boolean` | `false` | Whether this specific radio item is disabled |
| `isInvalid` | `boolean` | `false` | Whether the radio item is invalid |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | Variant style for the radio item |
| `hitSlop` | `number` | `6` | Hit slop for the pressable area |
| `className` | `string` | `undefined` | Custom class name |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported (except disabled) |
#### RadioGroupItemRenderProps
| prop | type | description |
| ------------ | --------- | ---------------------------------- |
| `isSelected` | `boolean` | Whether the radio item is selected |
| `isInvalid` | `boolean` | Whether the radio item is invalid |
| `isDisabled` | `boolean` | Whether the radio item is disabled |
### Radio (inside RadioGroup.Item)
The `Radio` component is used inside `RadioGroup.Item` to render the radio indicator. When placed inside a `RadioGroup.Item`, the Radio component automatically detects the `RadioGroupItem` context and derives `isSelected`, `isDisabled`, `isInvalid`, and `variant` from it — no manual prop passing is needed.
Use `` for the default indicator, or compose with `Radio.Indicator` and `Radio.IndicatorThumb` for custom styling.
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: RadioRenderProps) => React.ReactNode)` | `undefined` | Child elements or render function to customize the radio |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | Variant style for the radio |
| `isSelected` | `boolean` | `undefined` | Whether the radio is currently selected |
| `isDisabled` | `boolean` | `undefined` | Whether the radio is disabled and cannot be interacted with |
| `isInvalid` | `boolean` | `false` | Whether the radio is invalid (shows danger color) |
| `className` | `string` | `undefined` | Additional CSS classes to apply |
| `animation` | `RadioRootAnimation` | - | Animation configuration for radio |
| `onSelectedChange` | `(isSelected: boolean) => void` | `undefined` | Callback fired when the radio selection state changes |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported (except disabled) |
#### RadioRenderProps
| prop | type | description |
| ------------ | --------- | ----------------------------- |
| `isSelected` | `boolean` | Whether the radio is selected |
| `isDisabled` | `boolean` | Whether the radio is disabled |
| `isInvalid` | `boolean` | Whether the radio is invalid |
#### RadioRootAnimation
Animation configuration for radio root component. Can be:
* `"disable-all"`: Disable all animations including children (Indicator, IndicatorThumb)
* `undefined`: Use default animations
### Radio.Indicator
| prop | type | default | description |
| ---------------------- | -------------------------- | ----------- | ------------------------------------------------ |
| `children` | `React.ReactNode` | `undefined` | Content for the radio indicator |
| `className` | `string` | `undefined` | Additional CSS classes for the indicator |
| `...AnimatedViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
### Radio.IndicatorThumb
| prop | type | default | description |
| ----------------------- | ------------------------------ | ----------- | ------------------------------------------------------------ |
| `className` | `string` | `undefined` | Additional CSS classes for the thumb |
| `animation` | `RadioIndicatorThumbAnimation` | - | Animation configuration for the thumb |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...AnimatedViewProps` | `AnimatedProps` | - | All Reanimated Animated.View props are supported |
#### RadioIndicatorThumbAnimation
Animation configuration for radio indicator thumb component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| -------------------- | ----------------------- | ---------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `scale.value` | `[number, number]` | `[1.5, 1]` | Scale values \[unselected, selected] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 300, easing: Easing.out(Easing.ease) }` | Animation timing configuration |
**Note:** For labels, descriptions, and error messages, use the base components directly:
* Use [Label](../label/label.md) component for labels
* Use [Description](../description/description.md) component for descriptions
* Use [FieldError](../field-error/field-error.md) component for error messages
## Hooks
### useRadioGroup
**Returns:**
| Property | Type | Description |
| --------------- | -------------------------- | ---------------------------------------------- |
| `value` | `string \| undefined` | Currently selected value |
| `isDisabled` | `boolean` | Whether the radio group is disabled |
| `isInvalid` | `boolean` | Whether the radio group is in an invalid state |
| `variant` | `'primary' \| 'secondary'` | Variant style for the radio group |
| `onValueChange` | `(value: string) => void` | Function to change the selected value |
### useRadioGroupItem
**Returns:**
| Property | Type | Description |
| ------------------ | ---------------------------------------------- | ----------------------------------------------------------------------- |
| `isSelected` | `boolean` | Whether the radio item is selected |
| `isDisabled` | `boolean \| undefined` | Whether the radio item is disabled |
| `isInvalid` | `boolean \| undefined` | Whether the radio item is invalid |
| `variant` | `'primary' \| 'secondary' \| undefined` | Variant style for the radio item |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | Callback to change the selection state (selects this item in the group) |
# SearchField
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/search-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/search-field.mdx
> A compound search input for filtering and querying content.
## Import
```tsx
import { SearchField } from 'heroui-native';
```
## Anatomy
```tsx
```
* **SearchField**: Root container that accepts `value` and `onChange`, providing them to children via context. Also provides form field state (isDisabled, isInvalid, isRequired) and animation settings.
* **SearchField.Group**: Flex-row container that positions the search icon, input, and clear button horizontally.
* **SearchField.SearchIcon**: Magnifying glass icon positioned absolutely on the left side of the input. Supports custom children to replace the default icon.
* **SearchField.Input**: Wraps the Input component with search-specific defaults. Reads `value` and `onChangeText` from the SearchField context automatically.
* **SearchField.ClearButton**: Small icon-only button to clear the search input. Automatically hidden when value is empty. Calls `onChange("")` from context on press.
## Usage
### Basic Usage
The SearchField component uses compound parts to create a search input. Pass `value` and `onChange` to the root; the Input and ClearButton consume them via context.
```tsx
```
### With Label and Description
Add a Label and Description outside the Group to provide context for the search field.
```tsx
Search by name, category, or SKU
```
### With Validation
Use `isInvalid` and `isRequired` on the root to control validation state. Pair with FieldError to display error messages.
```tsx
Enter at least 3 characters to search
No results found. Please try a different search term.
```
### Custom Search Icon
Replace the default magnifying glass icon by passing children to `SearchField.SearchIcon`.
```tsx
🔍
```
### Disabled
Set `isDisabled` on the root to disable all child components via context.
```tsx
Search is temporarily unavailable
```
## Example
```tsx
import { Description, Label, SearchField } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
export default function SearchFieldExample() {
const [searchValue, setSearchValue] = useState('');
return (
Search by name, category, or SKU
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/search-field.tsx).
## API Reference
### SearchField
| prop | type | default | description |
| -------------- | ------------------------- | ------- | -------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the search field |
| `value` | `string` | - | Controlled search text value |
| `onChange` | `(value: string) => void` | - | Callback fired when the search text changes |
| `isDisabled` | `boolean` | `false` | Whether the search field is disabled |
| `isInvalid` | `boolean` | `false` | Whether the search field is in an invalid state |
| `isRequired` | `boolean` | `false` | Whether the search field is required |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration for the search field |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AnimationRootDisableAll
Animation configuration for the SearchField root component. Can be:
* `"disable-all"`: Disable all animations including children (cascades down)
* `undefined`: Use default animations
### SearchField.Group
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the group |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### SearchField.SearchIcon
| prop | type | default | description |
| -------------- | -------------------------------- | ------- | ---------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom content to replace the default search icon |
| `className` | `string` | - | Additional CSS classes |
| `iconProps` | `SearchFieldSearchIconIconProps` | - | Props for customizing the default search icon (ignored when children are provided) |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SearchFieldSearchIconIconProps
| prop | type | default | description |
| ------- | -------- | ------------------- | ----------------- |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | Theme `muted` color | Color of the icon |
### SearchField.Input
Extends [Input](./input) props with search-specific defaults (`placeholder="Search..."`, `returnKeyType="search"`, `accessibilityRole="search"`). Omits `value` and `onChangeText` because they are provided by the SearchField context.
### SearchField.ClearButton
Automatically hidden when the controlled `value` is an empty string. Calls `onChange("")` from context on press. Additional `onPress` handlers passed via props are called after clearing.
| prop | type | default | description |
| ---------------- | --------------------------------- | ------- | ------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom content to replace the default close icon |
| `iconProps` | `SearchFieldClearButtonIconProps` | - | Props for customizing the clear button icon |
| `className` | `string` | - | Additional CSS classes |
| `...ButtonProps` | `ButtonRootProps` | - | All Button root props are supported |
#### SearchFieldClearButtonIconProps
| prop | type | default | description |
| ------- | -------- | ------------------- | ----------------- |
| `size` | `number` | `14` | Size of the icon |
| `color` | `string` | Theme `muted` color | Color of the icon |
## Hooks
### useSearchField
Hook to access the search field state from context. Must be used within a `SearchField` component.
```tsx
import { useSearchField } from 'heroui-native';
const { value, onChange, isDisabled, isInvalid, isRequired } = useSearchField();
```
#### Returns
| property | type | description |
| ------------ | ---------------------------------------- | ----------------------------------------------- |
| `value` | `string \| undefined` | Current controlled search text value |
| `onChange` | `((value: string) => void) \| undefined` | Callback to update the search text |
| `isDisabled` | `boolean` | Whether the search field is disabled |
| `isInvalid` | `boolean` | Whether the search field is in an invalid state |
| `isRequired` | `boolean` | Whether the search field is required |
# Select
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/select
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/select.mdx
> Displays a list of options for the user to pick from — triggered by a button.
## Import
```tsx
import { Select } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Select**: Main container that manages open/close state, value selection and provides context to child components.
* **Select.Trigger**: Clickable element that toggles the select visibility. Wraps any child element with press handlers. Supports `variant` prop (`'default'` or `'unstyled'`).
* **Select.Value**: Displays the selected value or placeholder text. Automatically updates when selection changes. Styling changes based on selection state.
* **Select.TriggerIndicator**: Optional visual indicator showing open/close state. Renders an animated chevron icon by default that rotates when the select opens/closes.
* **Select.Portal**: Renders select content in a portal layer above other content. Ensures proper stacking and positioning.
* **Select.Overlay**: Optional background overlay. Can be transparent or semi-transparent to capture outside clicks.
* **Select.Content**: Container for select content with three presentation modes: popover (floating with positioning), bottom sheet modal, or dialog modal.
* **Select.Close**: Close button for the select. Can accept custom children or uses default close icon.
* **Select.ListLabel**: Label for the list of items with pre-styled typography.
* **Select.Item**: Selectable option item. Handles selection state and press events.
* **Select.ItemLabel**: Displays the label text for an item.
* **Select.ItemDescription**: Optional description text for items with muted styling.
* **Select.ItemIndicator**: Optional indicator shown for selected items. Renders a check icon by default.
## Usage
### Basic Usage
The Select component uses compound parts to create dropdown selection interfaces.
```tsx
```
### With Value Display
Display the selected value in the trigger using the Value component.
```tsx
```
### Popover Presentation
Use popover presentation for floating content with automatic positioning.
```tsx
```
### Width Control
Control the width of the select content using the `width` prop. This only works with popover presentation.
```tsx
{
/* Fixed width in pixels */
}
;
{
/* Match trigger width */
}
;
{
/* Full width (100%) */
}
;
{
/* Auto-size to content (default) */
}
;
```
### Bottom Sheet Presentation
Use bottom sheet for mobile-optimized selection experience.
```tsx
```
### Dialog Presentation
Use dialog presentation for centered modal-style selection.
```tsx
```
### Custom Item Content
Customize item appearance with custom content and indicators.
```tsx
```
### With Render Function
Use a render function on `Select.Item` to access state and customize content based on selection.
```tsx
```
### With Item Description
Add descriptions to items for additional context.
```tsx
```
### With Trigger Indicator
Add a visual indicator to show the open/close state of the select. The indicator rotates when the select opens/closes.
```tsx
```
### Custom Trigger with Unstyled Variant
Use the `unstyled` variant when composing a custom trigger with other components like Button.
```tsx
```
### Controlled Mode
Control the select state programmatically.
```tsx
const [value, setValue] = useState();
const [isOpen, setIsOpen] = useState(false);
;
```
## Example
```tsx
import { Select, Separator } from 'heroui-native';
import React, { useState } from 'react';
type SelectOption = {
value: string;
label: string;
};
const US_STATES: SelectOption[] = [
{ value: 'CA', label: 'California' },
{ value: 'NY', label: 'New York' },
{ value: 'TX', label: 'Texas' },
{ value: 'FL', label: 'Florida' },
];
export default function SelectExample() {
const [value, setValue] = useState();
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/select.tsx).
## API Reference
### Select
| prop | type | default | description |
| --------------- | ------------------------------------------------- | ----------- | ---------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The content of the select |
| `value` | `SelectOption \| SelectOption[]` | - | The selected value(s) (controlled mode) |
| `onValueChange` | `(value: SelectOption \| SelectOption[]) => void` | - | Callback when the value changes |
| `defaultValue` | `SelectOption \| SelectOption[]` | - | The default selected value(s) (uncontrolled mode) |
| `isOpen` | `boolean` | - | Whether the select is open (controlled mode) |
| `isDefaultOpen` | `boolean` | - | Whether the select is open when initially rendered (uncontrolled mode) |
| `onOpenChange` | `(isOpen: boolean) => void` | - | Callback when the select open state changes |
| `isDisabled` | `boolean` | `false` | Whether the select is disabled |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | `'popover'` | Presentation mode for the select content |
| `animation` | `SelectRootAnimation` | - | Animation configuration |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SelectRootAnimation
Animation configuration for Select component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ------------------------------------------------ | ------- | ----------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | Animation configuration for when select opens |
| `exiting.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | Animation configuration for when select closes |
#### SpringAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ----------------------------------------- |
| `type` | `'spring'` | - | Animation type (must be `'spring'`) |
| `config` | `WithSpringConfig` | - | Reanimated spring animation configuration |
#### TimingAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ----------------------------------------- |
| `type` | `'timing'` | - | Animation type (must be `'timing'`) |
| `config` | `WithTimingConfig` | - | Reanimated timing animation configuration |
### Select.Trigger
| prop | type | default | description |
| ------------------- | ------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------- |
| `variant` | `'default' \| 'unstyled'` | `'default'` | The variant of the trigger. `'default'` applies pre-styled container styles, `'unstyled'` removes default styling |
| `children` | `ReactNode` | - | The trigger element content |
| `className` | `string` | - | Additional CSS classes for the trigger |
| `asChild` | `boolean` | `true` | Whether to render as a child element |
| `isDisabled` | `boolean` | - | Whether the trigger is disabled |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Select.Value
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `placeholder` | `string` | - | Placeholder text when no value is selected |
| `className` | `string` | - | Additional CSS classes for the value |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
**Note:** The value component automatically applies different text colors based on selection state:
* When a value is selected: `text-foreground`
* When no value is selected (placeholder): `text-field-placeholder`
### Select.TriggerIndicator
| prop | type | default | description |
| ----------------------- | --------------------------------- | ------- | ------------------------------------------------------------ |
| `children` | `ReactNode` | - | Custom indicator content. Defaults to animated chevron icon |
| `className` | `string` | - | Additional CSS classes for the trigger indicator |
| `style` | `ViewStyle` | - | Custom styles for the trigger indicator |
| `iconProps` | `SelectTriggerIndicatorIconProps` | - | Chevron icon configuration |
| `animation` | `SelectTriggerIndicatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
**Note:** The following style properties are occupied by animations and cannot be set via className:
* `transform` (specifically `rotate`) - Animated for open/close rotation transitions
To customize this property, use the `animation` prop. To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.
#### SelectTriggerIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ------------------------------------------------------ |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | - | Color of the icon (defaults to foreground theme color) |
#### SelectTriggerIndicatorAnimation
Animation configuration for Select.TriggerIndicator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations (rotation from 0° to -180°)
* `object`: Custom animation configuration
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rotation.value` | `[number, number]` | `[0, -180]` | Rotation values \[closed, open] in degrees |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | Spring animation configuration for rotation |
### Select.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The portal content (required) |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; overlay won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `className` | `string` | - | Additional CSS classes for the portal container |
| `hostName` | `string` | - | Optional name of the host element for the portal |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Select.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes for the overlay |
| `animation` | `SelectOverlayAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `closeOnPress` | `boolean` | `true` | Whether to close the select when overlay is pressed |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### SelectOverlayAnimation
Animation configuration for Select.Overlay component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations (progress-based opacity for bottom-sheet/dialog, Keyframe animations for popover)
* `object`: Custom animation configuration
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | ---------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | Opacity values \[idle, open, close] (for bottom-sheet/dialog presentation) |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (for popover presentation) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (for popover presentation) |
### Select.Content (Popover Presentation)
| prop | type | default | description |
| ----------------------- | ------------------------------------------------ | --------------- | ------------------------------------------------------ |
| `children` | `ReactNode` | - | The select content |
| `width` | `number \| 'trigger' \| 'content-fit' \| 'full'` | `'content-fit'` | Width sizing strategy for the content |
| `presentation` | `'popover'` | `'popover'` | Presentation mode for the select |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Placement of the content relative to trigger |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alignment along the placement axis |
| `avoidCollisions` | `boolean` | `true` | Whether to flip placement when close to viewport edges |
| `offset` | `number` | `8` | Distance from trigger element in pixels |
| `alignOffset` | `number` | `0` | Offset along the alignment axis in pixels |
| `className` | `string` | - | Additional CSS classes for the content container |
| `animation` | `SelectContentPopoverAnimation` | - | Animation configuration |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `insets` | `Insets` | - | Screen edge insets to respect when positioning |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### SelectContentPopoverAnimation
Animation configuration for Select.Content component (popover presentation). Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default Keyframe animations (translateY/translateX, scale, opacity based on placement)
* `object`: Custom animation configuration with `entering` and/or `exiting` Keyframe animations
| prop | type | default | description |
| ---------- | ----------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (default: Keyframe with translateY/translateX, scale, opacity based on placement, 200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (default: Keyframe mirroring entering animation, 150ms) |
### Select.Content (Bottom Sheet Presentation)
| prop | type | default | description |
| --------------------------- | ------------------ | ------- | ------------------------------------------------ |
| `children` | `ReactNode` | - | The bottom sheet content |
| `presentation` | `'bottom-sheet'` | - | Presentation mode for the select |
| `contentContainerClassName` | `string` | - | Additional CSS classes for the content container |
| `...BottomSheetProps` | `BottomSheetProps` | - | All @gorhom/bottom-sheet props are supported |
### Select.Content (Dialog Presentation)
| prop | type | default | description |
| -------------- | -------------------------------------------------------- | ------- | --------------------------------------------------- |
| `children` | `ReactNode` | - | The dialog content |
| `presentation` | `'dialog'` | - | Presentation mode for the select |
| `classNames` | `{ wrapper?: string; content?: string }` | - | Additional CSS classes for wrapper and content |
| `styles` | `Partial>` | - | Styles for different parts of the dialog content |
| `animation` | `SelectContentAnimation` | - | Animation configuration |
| `isSwipeable` | `boolean` | `true` | Whether the dialog content can be swiped to dismiss |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### `styles`
| prop | type | description |
| --------- | ----------- | -------------------------------- |
| `wrapper` | `ViewStyle` | Styles for the wrapper container |
| `content` | `ViewStyle` | Styles for the dialog content |
#### SelectContentAnimation
Animation configuration for Select.Content component (dialog presentation). Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default Keyframe animations (scale and opacity transitions)
* `object`: Custom animation configuration with `entering` and/or `exiting` Keyframe animations
| prop | type | default | description |
| ---------- | ----------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for entering transition (default: Keyframe with scale and opacity, 200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | Custom Keyframe animation for exiting transition (default: Keyframe mirroring entering animation, 150ms) |
### Select.Close
Select.Close extends [CloseButton](./close-button) and automatically handles select dismissal when pressed.
### Select.ListLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The label text content |
| `className` | `string` | - | Additional CSS classes for the list label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.Item
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------ | ------- | -------------------------------------------------------------------------- |
| `children` | `ReactNode \| ((props: SelectItemRenderProps) => ReactNode)` | - | Custom item content. Defaults to label and indicator, or a render function |
| `value` | `any` | - | The value associated with this item (required) |
| `label` | `string` | - | The label text for this item (required) |
| `isDisabled` | `boolean` | `false` | Whether this item is disabled |
| `className` | `string` | - | Additional CSS classes for the item |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### SelectItemRenderProps
When using a render function for `children`, the following props are provided:
| property | type | description |
| ------------ | --------- | --------------------------------------- |
| `isSelected` | `boolean` | Whether this item is currently selected |
| `value` | `string` | The value of the item |
| `isDisabled` | `boolean` | Whether the item is disabled |
### Select.ItemLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes for the item label |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.ItemDescription
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The description text content |
| `className` | `string` | - | Additional CSS classes for the item description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Select.ItemIndicator
| prop | type | default | description |
| -------------- | ------------------------------ | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | Custom indicator content. Defaults to check icon |
| `className` | `string` | - | Additional CSS classes for the item indicator |
| `iconProps` | `SelectItemIndicatorIconProps` | - | Check icon configuration |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### SelectItemIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ---------------- | ----------------- |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | `--colors-muted` | Color of the icon |
## Hooks
### useSelect
Hook to access the Select root context. Returns the select state and control functions.
```tsx
import { useSelect } from 'heroui-native';
const {
isOpen,
onOpenChange,
isDefaultOpen,
isDisabled,
presentation,
triggerPosition,
setTriggerPosition,
contentLayout,
setContentLayout,
nativeID,
value,
onValueChange,
} = useSelect();
```
#### Return Value
| property | type | description |
| -------------------- | -------------------------------------------------- | --------------------------------------------------------- |
| `isOpen` | `boolean` | Whether the select is currently open |
| `onOpenChange` | `(open: boolean) => void` | Callback to change the open state |
| `isDefaultOpen` | `boolean \| undefined` | Whether the select is open by default (uncontrolled mode) |
| `isDisabled` | `boolean \| undefined` | Whether the select is disabled |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | Presentation mode for the select content |
| `triggerPosition` | `LayoutPosition \| null` | Position of the trigger element relative to viewport |
| `setTriggerPosition` | `(position: LayoutPosition \| null) => void` | Updates the trigger element's position |
| `contentLayout` | `LayoutRectangle \| null` | Layout measurements of the select content |
| `setContentLayout` | `(layout: LayoutRectangle \| null) => void` | Updates the content layout measurements |
| `nativeID` | `string` | Unique identifier for the select instance |
| `value` | `SelectOption \| SelectOption[]` | Currently selected option |
| `onValueChange` | `(option: SelectOption \| SelectOption[]) => void` | Callback fired when the selected value changes |
**Note:** This hook must be used within a `Select` component. It will throw an error if called outside of the select context.
### useSelectAnimation
Hook to access the Select animation state values within custom components or compound components.
```tsx
import { useSelectAnimation } from 'heroui-native';
const { selectState, progress, isDragging, isGestureReleaseAnimationRunning } =
useSelectAnimation();
```
#### Return Value
| property | type | description |
| ---------------------------------- | ---------------------- | ---------------------------------------------------------- |
| `progress` | `SharedValue` | Progress value for animations (0=idle, 1=open, 2=close) |
| `isDragging` | `SharedValue` | Whether the select content is currently being dragged |
| `isGestureReleaseAnimationRunning` | `SharedValue` | Whether the gesture release animation is currently running |
**Note:** This hook must be used within a `Select` component. It will throw an error if called outside of the select animation context.
#### SelectOption
| property | type | description |
| -------- | -------- | ---------------------------- |
| `value` | `string` | The value of the option |
| `label` | `string` | The label text of the option |
### useSelectItem
Hook to access the Select Item context. Returns the item's value and label.
```tsx
import { useSelectItem } from 'heroui-native';
const { itemValue, label } = useSelectItem();
```
#### Return Value
| property | type | description |
| ----------- | -------- | ---------------------------------- |
| `itemValue` | `string` | The value of the current item |
| `label` | `string` | The label text of the current item |
## Special Notes
### Element Inspector (iOS)
Select uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `Select.Portal`. Tradeoff: the select dropdown will not appear above native modals when disabled.
### Native Modal (iOS)
When a `Select` is opened inside a screen presented as a native modal (`presentation: 'modal' | 'formSheet' | 'pageSheet'`), the dropdown may render shifted upward. In the new architecture (Fabric), `react-native-screens` marks `RNSModalScreen` as a Fabric root, so the trigger's position is reported relative to the modal's origin while `FullWindowOverlay` (where the dropdown is mounted) is anchored to the iOS application window. Compensate by adding `safeAreaInsets.top` to `offset`:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# TextArea
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/text-area
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/text-area.mdx
> A multiline text input component with styled border and background for collecting longer user input.
## Import
```tsx
import { TextArea } from 'heroui-native';
```
## Usage
### Basic Usage
TextArea can be used standalone or within a TextField component.
```tsx
import { TextArea } from 'heroui-native';
```
### Within TextField
TextArea works seamlessly with TextField for complete form structure.
```tsx
import { Description, Label, TextArea, TextField } from 'heroui-native';
Please provide as much detail as possible.
```
### With Validation
Display error state when the text area is invalid.
```tsx
import { FieldError, Label, TextArea, TextField } from 'heroui-native';
Please enter a valid message
```
### Disabled State
Disable the text area to prevent interaction.
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
### With Variant
Use different variants to style the text area based on context.
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
### Custom Styling
Customize the text area appearance using className.
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
## Example
```tsx
import { Description, FieldError, Label, TextArea, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function TextAreaExample() {
return (
Default variant with primary styling
Secondary variant for surfaces
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text-area.tsx).
## API Reference
TextArea extends [Input](./input) component and inherits all its props. The only differences are default values: `multiline` defaults to `true` and `textAlignVertical` defaults to `'top'`.
# TextField
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/text-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(forms)/text-field.mdx
> A text input component with label, description, and error handling for collecting user input.
## Import
```tsx
import { TextField } from 'heroui-native';
```
## Anatomy
```tsx
...
...
```
* **TextField**: Root container that provides spacing and state management
* **Label**: Label with optional asterisk for required fields (from [Label](./label) component)
* **Input**: Input container with animated border and background (from [Input](./input) component)
* **Description**: Secondary descriptive helper text (from [Description](./description) component)
* **FieldError**: Validation error message display (from [FieldError](./field-error) component)
## Usage
### Basic Usage
TextField provides a complete form input structure with label and description.
```tsx
We'll never share your email
```
### With Required Field
Mark fields as required to show an asterisk in the label.
```tsx
```
### With Validation
Display error messages when the field is invalid.
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
Please enter a valid email
;
```
### With Local Invalid State Override
Override the context's invalid state for individual components.
```tsx
import {
Description,
FieldError,
Input,
Label,
TextField,
} from 'heroui-native';
This shows despite input being invalid
Email format is incorrect
;
```
### Multiline Input
Create text areas for longer content.
```tsx
Maximum 500 characters
```
### Disabled State
Disable the entire field to prevent interaction.
```tsx
```
### With Variant
Use different variants to style the input based on context.
```tsx
```
### Custom Styling
Customize the input appearance using className.
```tsx
```
## Example
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Description, Input, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export const TextInputContent = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
We'll never share your email with anyone else.
setIsPasswordVisible(!isPasswordVisible)}
>
Password must be at least 6 characters
);
};
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text-field.tsx).
## API Reference
### TextField
| prop | type | default | description |
| ------------ | ---------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| children | `React.ReactNode` | - | Content to render inside the text field |
| isDisabled | `boolean` | `false` | Whether the entire text field is disabled |
| isInvalid | `boolean` | `false` | Whether the text field is in an invalid state |
| isRequired | `boolean` | `false` | Whether the text field is required (shows asterisk) |
| className | `string` | - | Custom class name for the root element |
| animation | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| ...ViewProps | `ViewProps` | - | All standard React Native View props are supported |
> **Note**: For Label, Input, Description, and FieldError components, see their respective documentation:
>
> * [Label documentation](./label)
> * [Input documentation](./input)
> * [Description documentation](./description)
> * [FieldError documentation](./field-error)
>
> These components automatically consume form state from TextField via the form-item-state context.
## Hooks
### useTextField
Hook to access the TextField context values. Must be used within a `TextField` component.
```tsx
import { TextField, useTextField } from 'heroui-native';
function CustomComponent() {
const { isDisabled, isInvalid, isRequired } = useTextField();
// Use the context values...
}
```
#### Returns
| property | type | description |
| ---------- | --------- | --------------------------------------------- |
| isDisabled | `boolean` | Whether the entire text field is disabled |
| isInvalid | `boolean` | Whether the text field is in an invalid state |
| isRequired | `boolean` | Whether the text field is required |
# Card
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/card
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(layout)/card.mdx
> Displays a card container with flexible layout sections for structured content.
## Import
```tsx
import { Card } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
...
```
* **Card**: Main container that extends Surface component. Provides base card structure with configurable surface variants and handles overall layout.
* **Card.Header**: Header section for top-aligned content like icons or badges.
* **Card.Body**: Main content area with flex-1 that expands to fill all available space between Card.Header and Card.Footer.
* **Card.Title**: Title text with foreground color and medium font weight.
* **Card.Description**: Description text with muted color and smaller font size.
* **Card.Footer**: Footer section for bottom-aligned actions like buttons.
## Usage
### Basic Usage
The Card component creates a container with built-in sections for organized content.
```tsx
...
```
### With Title and Description
Combine title and description components for structured text content.
```tsx
...
...
```
### With Header and Footer
Add header and footer sections for icons, badges, or actions.
```tsx
...
...
...
```
### Variants
Control the card's background appearance using different variants.
```tsx
...
...
...
...
```
### Horizontal Layout
Create horizontal cards by using flex-row styling.
```tsx
```
### Background Image
Use an image as an absolute positioned background.
```tsx
...
```
## Example
```tsx
import { Button, Card } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
export default function CardExample() {
return (
$450
Living room Sofa • Collection 2025
This sofa is perfect for modern tropical spaces, baroque inspired
spaces.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/card.tsx).
## API Reference
### Card
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be rendered inside the card |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | Visual variant of the card surface |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Card.Header
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the header |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Card.Body
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the body |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Card.Footer
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the footer |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Card.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered as the title text |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Card.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered as the description text |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
# Separator
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/separator
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(layout)/separator.mdx
> A simple line to separate content visually.
## Import
```tsx
import { Separator } from "heroui-native";
```
## Anatomy
```tsx
```
* **Separator**: A simple line component that separates content visually. Can be oriented horizontally or vertically, with customizable thickness and variant styles.
## Usage
### Basic Usage
The Separator component creates a visual separation between content sections.
```tsx
```
### Orientation
Control the direction of the separator with the `orientation` prop.
```tsx
Horizontal separator
Content below
Left
Right
```
### Variants
Choose between thin and thick variants for different visual emphasis.
```tsx
```
### Custom Thickness
Set a specific thickness value for precise control.
```tsx
```
## Example
```tsx
import { Separator, Surface } from 'heroui-native';
import { Text, View } from 'react-native';
export default function SeparatorExample() {
return (
HeroUI Native
A modern React Native component library.
Components
Themes
Examples
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/separator.tsx).
## API Reference
### Separator
| prop | type | default | description |
| -------------- | ---------------------------- | -------------- | -------------------------------------------------------------------------------------------- |
| `variant` | `'thin' \| 'thick'` | `'thin'` | Variant style of the separator |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Orientation of the separator |
| `thickness` | `number` | `undefined` | Custom thickness in pixels. Controls height for horizontal or width for vertical orientation |
| `className` | `string` | `undefined` | Additional CSS classes to apply |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
# Surface
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/surface
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(layout)/surface.mdx
> Container component that provides elevation and background styling.
## Import
```tsx
import { Surface } from 'heroui-native';
```
## Anatomy
The Surface component is a container that provides elevation and background styling. It accepts children and can be customized with variants and styling props.
```tsx
...
```
* **Surface**: Main container component that provides consistent padding, background styling, and elevation through variants.
## Usage
### Basic Usage
The Surface component creates a container with consistent padding and styling.
```tsx
...
```
### Variants
Control the visual appearance with different surface levels.
```tsx
...
...
...
```
### Nested Surfaces
Create visual hierarchy by nesting surfaces with different variants.
```tsx
...
...
...
```
### Custom Styling
Apply custom styles using className or style props.
```tsx
...
...
```
### Disable All Animations
Disable all animations including children by using the `"disable-all"` value for the `animation` prop.
```tsx
{
/* Disable all animations including children */
}
No Animations;
```
## Example
```tsx
import { Surface } from 'heroui-native';
import { Text, View } from 'react-native';
export default function SurfaceExample() {
return (
Surface Content
This is a default surface variant. It uses bg-surface styling.
Surface Content
This is a secondary surface variant. It uses bg-surface-secondary
styling.
Surface Content
This is a tertiary surface variant. It uses bg-surface-tertiary
styling.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/surface.tsx).
## API Reference
### Surface
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | Visual variant controlling background color and border |
| `children` | `React.ReactNode` | - | Content to be rendered inside the surface |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
# Avatar
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/avatar
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(media)/avatar.mdx
> Displays a user avatar with support for images, text initials, or fallback icons.
## Import
```tsx
import { Avatar } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Avatar**: Main container that manages avatar display state. Provides size and color context to child components. Supports animation configuration to control all child animations.
* **Avatar.Image**: Optional image component that displays the avatar image. Handles loading states and errors automatically with opacity-based fade-in animation.
* **Avatar.Fallback**: Optional fallback component shown when image fails to load or is unavailable. Displays a default person icon when no children are provided. Supports configurable entering animations with delay support.
## Usage
### Basic Usage
The Avatar component displays a default person icon when no image or text is provided.
```tsx
```
### With Image
Display an avatar image with automatic fallback handling.
```tsx
JD
```
### With Text Initials
Show text initials as the avatar content.
```tsx
AB
```
### With Custom Icon
Provide a custom icon as fallback content.
```tsx
```
### Sizes
Control the avatar size with the size prop.
```tsx
```
### Variants
Choose between different visual styles with the `variant` prop.
```tsx
DF
SF
```
### Colors
Apply different color variants to the avatar.
```tsx
DF
AC
SC
WR
DG
```
### Delayed Fallback
Show fallback after a delay to prevent flashing during image load.
```tsx
NA
```
### Custom Image Component
Use a custom image component with the asChild prop.
```tsx
import { Image } from 'expo-image';
EI
;
```
### Animation Control
Control animations at different levels of the Avatar component.
#### Disable All Animations
Disable all animations including children from the root component:
```tsx
JD
```
#### Custom Image Animation
Customize the image opacity animation:
```tsx
JD
```
#### Custom Fallback Animation
Customize the fallback entering animation:
```tsx
import { FadeInDown } from 'react-native-reanimated';
JD
;
```
#### Disable Individual Animations
Disable animations for specific components:
```tsx
JD
```
## Example
```tsx
import { Avatar } from 'heroui-native';
import { View } from 'react-native';
export default function AvatarExample() {
const users = [
{ id: 1, image: 'https://example.com/user1.jpg', name: 'John Doe' },
{ id: 2, image: 'https://example.com/user2.jpg', name: 'Jane Smith' },
{ id: 3, image: 'https://example.com/user3.jpg', name: 'Bob Johnson' },
];
return (
{users.map((user) => (
{user.name
.split(' ')
.map((n) => n[0])
.join('')}
))}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/avatar.tsx).
## API Reference
### Avatar
| prop | type | default | description |
| -------------- | ------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Avatar content (Image and/or Fallback components) |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the avatar |
| `variant` | `'default' \| 'soft'` | `'default'` | Visual variant of the avatar |
| `color` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'accent'` | Color variant of the avatar |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `"disable-all"` \| `undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `alt` | `string` | `'Avatar'` | Alternative text description for accessibility |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Avatar.Image
Props extend different base types depending on the `asChild` prop value:
* When `asChild={false}` (default): extends `AnimatedProps` from React Native Reanimated
* When `asChild={true}`: extends primitive image props for custom image components
**Note:** When using `asChild={true}` with custom image components, the `className` prop may not be applied in some cases depending on the custom component's implementation. Ensure your custom component properly handles style props.
| prop | type | default | description |
| ----------------------- | ---------------------------------------------- | ------- | ------------------------------------------------------------ |
| `source` | `ImageSourcePropType` | - | Image source (required when `asChild={false}`) |
| `asChild` | `boolean` | `false` | Whether to use a custom image component as child |
| `className` | `string` | - | Additional CSS classes to apply |
| `animation` | `AvatarImageAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...AnimatedProps` | `AnimatedProps` or primitive props | - | Additional props based on `asChild` value |
#### AvatarImageAnimation
Animation configuration for avatar image component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------------- | ----------------------- | --------------------------------------------------- | ----------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 1]` | Opacity values \[initial, loaded] for image animation |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200, easing: Easing.in(Easing.ease) }` | Animation timing configuration |
**Note:** Animation is automatically disabled when `asChild={true}`
### Avatar.Fallback
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------------- | --------------------- | --------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Fallback content (text, icon, or custom element) |
| `delayMs` | `number` | `0` | Delay in milliseconds before showing the fallback (applied to entering animation) |
| `color` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | inherited from parent | Color variant of the fallback |
| `className` | `string` | - | Additional CSS classes for the container |
| `classNames` | `ElementSlots` | - | Additional CSS classes for different parts |
| `styles` | `{ container?: ViewStyle; text?: TextStyle }` | - | Styles for different parts of the avatar fallback |
| `textProps` | `TextProps` | - | Props to pass to Text component when children is a string |
| `iconProps` | `PersonIconProps` | - | Props to customize the default person icon |
| `animation` | `AvatarFallbackAnimation` | - | Animation configuration |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
**classNames prop:** `ElementSlots` provides type-safe CSS classes for different parts of the fallback component. Available slots: `container`, `text`.
#### `styles`
| prop | type | description |
| ----------- | ----------- | --------------------------- |
| `container` | `ViewStyle` | Styles for the container |
| `text` | `TextStyle` | Styles for the text content |
#### AvatarFallbackAnimation
Animation configuration for avatar fallback component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ----------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.in(Easing.ease))`
`.delay(0)` | Custom entering animation for fallback |
#### PersonIconProps
| prop | type | description |
| ------- | -------- | ------------------------------------- |
| `size` | `number` | Size of the icon in pixels (optional) |
| `color` | `string` | Color of the icon (optional) |
## Hooks
### useAvatar Hook
Hook to access Avatar primitive root context. Provides access to avatar status.
**Note:** The `status` property is particularly useful for adding a skeleton loader while the image is loading.
```tsx
import { Avatar, useAvatar, Skeleton } from 'heroui-native';
function AvatarWithSkeleton() {
return (
JD
);
}
function AvatarContent() {
const { status } = useAvatar();
if (status === 'loading') {
return ;
}
return null;
}
```
| property | type | description |
| ----------- | ---------------------------------------------------- | ----------------------------------------------------------- |
| `status` | `'loading' \| 'loaded' \| 'error'` | Current loading state of the avatar image. |
| `setStatus` | `(status: 'loading' \| 'loaded' \| 'error') => void` | Function to manually set the avatar status (advanced usage) |
**Status Values:**
* `'loading'`: Image is currently being loaded. Use this state to show a skeleton loader.
* `'loaded'`: Image has successfully loaded.
* `'error'`: Image failed to load or source is invalid. The fallback component is automatically shown in this state.
# Accordion
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/accordion
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(navigation)/accordion.mdx
> A collapsible content panel for organizing information in a compact space
## Import
```tsx
import { Accordion } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **Accordion**: Main container that manages the accordion state and behavior. Controls expansion/collapse of items, supports single or multiple selection modes, and provides variant styling (default or surface).
* **Accordion.Item**: Container for individual accordion items. Wraps the trigger and content, managing the expanded state for each item.
* **Accordion.Trigger**: Interactive element that toggles item expansion. Built on Header and Trigger primitives.
* **Accordion.Indicator**: Optional visual indicator showing expansion state. Defaults to an animated chevron icon that rotates based on item state.
* **Accordion.Content**: Container for expandable content. Animated with layout transitions for smooth expand/collapse effects.
## Usage
### Basic Usage
The Accordion component uses compound parts to create expandable content sections.
```tsx
...
...
```
### Single Selection Mode
Allow only one item to be expanded at a time.
```tsx
...
...
...
...
```
### Multiple Selection Mode
Allow multiple items to be expanded simultaneously.
```tsx
...
...
...
...
...
...
```
### Surface Variant
Apply a surface container style to the accordion.
```tsx
...
...
```
### Custom Indicator
Replace the default chevron indicator with custom content.
```tsx
...
...
```
### Without Separators
Hide the separators between accordion items.
```tsx
...
...
...
...
```
### Custom Styling
Apply custom styles using className, classNames, or styles props.
```tsx
...
...
```
### With PressableFeedback
Use `Accordion.Trigger` with `asChild` prop and wrap content with `PressableFeedback` to add custom press feedback animations.
```tsx
import { Accordion, PressableFeedback } from 'heroui-native';
import { View } from 'react-native';
Item Title
...
;
```
## Example
```tsx
import { Accordion, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View, Text } from 'react-native';
export default function AccordionExample() {
const themeColorMuted = useThemeColor('muted');
const accordionData = [
{
id: '1',
title: 'How do I place an order?',
icon: ,
content:
'Lorem ipsum dolor sit amet consectetur. Netus nunc mauris risus consequat. Libero placerat dignissim consectetur nisl.',
},
{
id: '2',
title: 'What payment methods do you accept?',
icon: ,
content:
'Lorem ipsum dolor sit amet consectetur. Netus nunc mauris risus consequat. Libero placerat dignissim consectetur nisl.',
},
{
id: '3',
title: 'How much does shipping cost?',
icon: ,
content:
'Lorem ipsum dolor sit amet consectetur. Netus nunc mauris risus consequat. Libero placerat dignissim consectetur nisl.',
},
];
return (
{accordionData.map((item) => (
{item.icon}
{item.title}
{item.content}
))}
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/accordion.tsx).
## API Reference
### Accordion
| prop | type | default | description |
| ----------------------- | -------------------------------------------------- | ----------- | -------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the accordion |
| `selectionMode` | `'single' \| 'multiple'` | - | Whether the accordion allows single or multiple expanded items |
| `variant` | `'default' \| 'surface'` | `'default'` | Visual variant of the accordion |
| `hideSeparator` | `boolean` | `false` | Whether to hide the separator between accordion items |
| `defaultValue` | `string \| string[] \| undefined` | - | Default expanded item(s) in uncontrolled mode |
| `value` | `string \| string[] \| undefined` | - | Controlled expanded item(s) |
| `isDisabled` | `boolean` | - | Whether all accordion items are disabled |
| `isCollapsible` | `boolean` | `true` | Whether expanded items can be collapsed |
| `animation` | `AccordionRootAnimation` | - | Animation configuration for accordion |
| `className` | `string` | - | Additional CSS classes for the container |
| `classNames` | `ElementSlots` | - | Additional CSS classes for the slots |
| `styles` | `Partial>` | - | Styles for different parts of the accordion root |
| `onValueChange` | `(value: string \| string[] \| undefined) => void` | - | Callback when expanded items change |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### `ElementSlots`
| prop | type | description |
| ----------- | -------- | ------------------------------------------------- |
| `container` | `string` | Custom class name for the accordion container |
| `separator` | `string` | Custom class name for the separator between items |
#### `styles`
| prop | type | description |
| ----------- | ----------- | -------------------------------------- |
| `container` | `ViewStyle` | Styles for the accordion container |
| `separator` | `ViewStyle` | Styles for the separator between items |
#### AccordionRootAnimation
Animation configuration for accordion root component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| -------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `layout.value` | `LayoutTransition` | `LinearTransition`
`.springify()`
`.damping(140)`
`.stiffness(1600)`
`.mass(4)` | Custom layout animation for accordion transitions |
### Accordion.Item
| prop | type | default | description |
| ----------------------- | --------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: AccordionItemRenderProps) => React.ReactNode)` | - | Children elements to be rendered inside the accordion item, or a render function |
| `value` | `string` | - | Unique value to identify this item |
| `isDisabled` | `boolean` | - | Whether this specific item is disabled |
| `className` | `string` | - | Additional CSS classes |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### AccordionItemRenderProps
| prop | type | description |
| ------------ | --------- | ------------------------------------------------ |
| `isExpanded` | `boolean` | Whether the accordion item is currently expanded |
| `value` | `string` | Unique value identifier for this accordion item |
### Accordion.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the trigger |
| `className` | `string` | - | Additional CSS classes |
| `isDisabled` | `boolean` | - | Whether the trigger is disabled |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Accordion.Indicator
| prop | type | default | description |
| ----------------------- | ----------------------------- | ------- | ---------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom indicator content, if not provided defaults to animated chevron |
| `className` | `string` | - | Additional CSS classes |
| `iconProps` | `AccordionIndicatorIconProps` | - | Icon configuration |
| `animation` | `AccordionIndicatorAnimation` | - | Animation configuration for indicator |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### AccordionIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------------ | ----------------- |
| `size` | `number` | `16` | Size of the icon |
| `color` | `string` | `foreground` | Color of the icon |
#### AccordionIndicatorAnimation
Animation configuration for accordion indicator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `rotation.value` | `[number, number]` | `[0, -180]` | Rotation values \[collapsed, expanded] in degrees |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | Spring animation configuration for rotation |
### Accordion.Content
| prop | type | default | description |
| -------------- | --------------------------- | ------- | --------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the content |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `AccordionContentAnimation` | - | Animation configuration for content |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AccordionContentAnimation
Animation configuration for accordion content component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------- | ----------------------- | ---------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.out(Easing.ease))` | Custom entering animation for content |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(200)`
`.easing(Easing.in(Easing.ease))` | Custom exiting animation for content |
## Hooks
### useAccordion
Hook to access the accordion root context. Must be used within an `Accordion` component.
```tsx
import { useAccordion } from 'heroui-native';
const { value, onValueChange, selectionMode, isCollapsible, isDisabled } =
useAccordion();
```
#### Returns
| property | type | description |
| --------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `selectionMode` | `'single' \| 'multiple' \| undefined` | Whether the accordion allows single or multiple expanded items |
| `value` | `(string \| undefined) \| string[]` | Currently expanded item(s) - string for single mode, array for multiple mode |
| `onValueChange` | `(value: string \| undefined) => void \| ((value: string[]) => void)` | Callback function to update expanded items |
| `isCollapsible` | `boolean` | Whether expanded items can be collapsed |
| `isDisabled` | `boolean \| undefined` | Whether all accordion items are disabled |
### useAccordionItem
Hook to access the accordion item context. Must be used within an `Accordion.Item` component.
```tsx
import { useAccordionItem } from 'heroui-native';
const { value, isExpanded, isDisabled, nativeID } = useAccordionItem();
```
#### Returns
| property | type | description |
| ------------ | ---------------------- | ---------------------------------------------------- |
| `value` | `string` | Unique value identifier for this accordion item |
| `isExpanded` | `boolean` | Whether the accordion item is currently expanded |
| `isDisabled` | `boolean \| undefined` | Whether this specific item is disabled |
| `nativeID` | `string` | Native ID used for accessibility and ARIA attributes |
## Special Notes
When using the Accordion component alongside other components in the same view, you should import and apply `AccordionLayoutTransition` to those components to ensure smooth and consistent layout animations across the entire screen.
```jsx
import { Accordion, AccordionLayoutTransition } from 'heroui-native';
import Animated from 'react-native-reanimated';
{/* Other content */}
{/* Accordion items */}
;
```
This ensures that when the accordion expands or collapses, all components on the screen animate with the same timing and easing, creating a cohesive user experience.
# ListGroup
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/list-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(navigation)/list-group.mdx
> A Surface-based container that groups related list items with consistent layout and spacing.
## Import
```tsx
import { ListGroup } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **ListGroup**: Surface-based root container that groups related list items. Supports all Surface variants (default, secondary, tertiary, transparent).
* **ListGroup.Item**: Pressable horizontal flex-row container for a single item, providing consistent spacing and alignment.
* **ListGroup.ItemPrefix**: Optional leading content slot for icons, avatars, or other visual elements.
* **ListGroup.ItemContent**: Flex-1 wrapper for title and description, occupying the remaining horizontal space.
* **ListGroup.ItemTitle**: Primary text label styled with foreground color and medium font weight.
* **ListGroup.ItemDescription**: Secondary text styled with muted color and smaller font size.
* **ListGroup.ItemSuffix**: Optional trailing content slot. Renders a chevron-right icon by default; accepts children to override the default icon.
## Usage
### Basic Usage
The ListGroup component uses compound parts to create grouped list items with title and description.
```tsx
Personal Info
Name, email, phone number
Payment Methods
Visa ending in 4829
```
### With Icons
Add leading icons using the `ListGroup.ItemPrefix` slot.
```tsx
Profile
Name, photo, bio
Security
Password, 2FA
```
### Title Only
Omit `ListGroup.ItemDescription` to display title-only items.
```tsx
Wi-Fi
Bluetooth
```
### Surface Variant
Apply a different visual variant to the root container.
```tsx
Wi-Fi
```
### Custom Suffix
Override the default chevron icon by passing children to `ListGroup.ItemSuffix`.
```tsx
Language
English
Notifications
7
```
### Custom Suffix Icon Props
Customise the default chevron icon size and color using `iconProps`.
```tsx
Storage
12.4 GB of 50 GB used
```
### With PressableFeedback
Wrap items with `PressableFeedback` to add scale and ripple press feedback animations. When using this pattern, pass `onPress` on `PressableFeedback` instead of `ListGroup.Item` and disable the item with `disabled` prop.
```tsx
import { ListGroup, PressableFeedback, Separator } from 'heroui-native';
{}}>
Appearance
Theme, font size, display
{}}>
Notifications
Alerts, sounds, badges
```
## Example
```tsx
import { Ionicons } from '@expo/vector-icons';
import { ListGroup, Separator, useThemeColor } from 'heroui-native';
import { View, Text } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export default function ListGroupExample() {
const mutedColor = useThemeColor('muted');
return (
Account
Personal Info
Name, email, phone number
Payment Methods
Visa ending in 4829
Preferences
Appearance
Theme, font size, display
Notifications
Alerts, sounds, badges
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/list-group.tsx).
## API Reference
### ListGroup
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the group |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | Visual variant of the underlying Surface container |
| `className` | `string` | - | Additional CSS classes for the root container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### ListGroup.Item
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the item |
| `className` | `string` | - | Additional CSS classes for the item |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### ListGroup.ItemPrefix
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Leading content such as icons or avatars |
| `className` | `string` | - | Additional CSS classes for the prefix |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### ListGroup.ItemContent
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content area, typically title and description |
| `className` | `string` | - | Additional CSS classes for the content area |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### ListGroup.ItemTitle
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Title text or custom content |
| `className` | `string` | - | Additional CSS classes for the title |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### ListGroup.ItemDescription
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Description text or custom content |
| `className` | `string` | - | Additional CSS classes for the description |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### ListGroup.ItemSuffix
| prop | type | default | description |
| -------------- | -------------------- | ------- | -------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom trailing content; overrides the default chevron-right icon when provided |
| `className` | `string` | - | Additional CSS classes for the suffix |
| `iconProps` | `ListGroupIconProps` | - | Props to customise the default chevron-right icon. Only applies when no children |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### ListGroupIconProps
| prop | type | default | description |
| ------- | -------- | ------------------- | ---------------------------------- |
| `size` | `number` | `16` | Size of the chevron icon in pixels |
| `color` | `string` | theme `muted` color | Color of the chevron icon |
# Tabs
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/tabs
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(navigation)/tabs.mdx
> Organize content into tabbed views with animated transitions and indicators.
## Import
```tsx
import { Tabs } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **Tabs**: Main container that manages tab state and selection. Controls active tab, handles value changes, and provides context to child components.
* **Tabs.List**: Container for tab triggers. Groups triggers together with optional styling variants (primary or secondary).
* **Tabs.ScrollView**: Optional scrollable wrapper for tab triggers. Enables horizontal scrolling when tabs overflow with automatic centering of active tab.
* **Tabs.Trigger**: Interactive button for each tab. Handles press events to change active tab and measures its position for indicator animation.
* **Tabs.Label**: Text content for tab triggers. Displays the tab title with appropriate styling.
* **Tabs.Indicator**: Animated visual indicator for active tab. Smoothly transitions between tabs using spring or timing animations.
* **Tabs.Separator**: Visual separator between tabs. Shows when the current tab value is not in the `betweenValues` array, with animated opacity transitions.
* **Tabs.Content**: Container for tab panel content. Shows content when its value matches the active tab.
## Usage
### Basic Usage
The Tabs component uses compound parts to create navigable content sections.
```tsx
Tab 1
Tab 2
...
...
```
### Primary Variant
Default rounded primary style for tab triggers.
```tsx
Settings
Profile
...
...
```
### Secondary Variant
Underline style indicator for a more minimal appearance.
```tsx
Overview
Analytics
...
...
```
### Scrollable Tabs
Handle many tabs with horizontal scrolling.
```tsx
First Tab
Second Tab
Third Tab
Fourth Tab
Fifth Tab
...
...
...
...
...
```
### Disabled Tabs
Disable specific tabs to prevent interaction.
```tsx
Active
Disabled
Another
...
...
```
### With Icons
Combine icons with labels for enhanced visual context.
```tsx
Home
Search
...
...
```
### With Render Function
Use a render function on `Tabs.Trigger` to access state and customize content based on selection.
```tsx
{({ isSelected, value, isDisabled }) => (
Settings
)}
{({ isSelected }) => (
<>
Profile
>
)}
...
...
```
### With Separators
Add visual separators between tabs that show when the active tab is not between specified values.
```tsx
General
Notifications
Profile
...
...
...
```
## Example
```tsx
import {
Button,
Checkbox,
Description,
ControlField,
Label,
Tabs,
TextField,
} from 'heroui-native';
import { useState } from 'react';
import { View, Text } from 'react-native';
import Animated, {
FadeIn,
FadeOut,
LinearTransition,
} from 'react-native-reanimated';
const AnimatedContentContainer = ({
children,
}: {
children: React.ReactNode;
}) => (
{children}
);
export default function TabsExample() {
const [activeTab, setActiveTab] = useState('general');
const [showSidebar, setShowSidebar] = useState(true);
const [accountActivity, setAccountActivity] = useState(true);
const [name, setName] = useState('');
return (
General
Notifications
Profile
Display the sidebar navigation panel
Notifications about your account activity
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/tabs.tsx).
## API Reference
### Tabs
| prop | type | default | description |
| --------------- | ---------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside tabs |
| `value` | `string` | - | Currently active tab value |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | Visual variant of the tabs |
| `className` | `string` | - | Additional CSS classes for the container |
| `animation` | `"disable-all" \| undefined` | `undefined` | Animation configuration. Use `"disable-all"` to disable all animations including children |
| `onValueChange` | `(value: string) => void` | - | Callback when the active tab changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Tabs.List
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the list |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Tabs.ScrollView
| prop | type | default | description |
| --------------------------- | ---------------------------------------- | ---------- | -------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the scroll view |
| `scrollAlign` | `'start' \| 'center' \| 'end' \| 'none'` | `'center'` | Scroll alignment variant for the selected item |
| `className` | `string` | - | Additional CSS classes for the scroll view |
| `contentContainerClassName` | `string` | - | Additional CSS classes for the content container |
| `...ScrollViewProps` | `ScrollViewProps` | - | All standard React Native ScrollView props are supported |
### Tabs.Trigger
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------- |
| `children` | `React.ReactNode \| ((props: TabsTriggerRenderProps) => React.ReactNode)` | - | Children elements to be rendered inside the trigger, or a render function |
| `value` | `string` | - | The unique value identifying this tab |
| `isDisabled` | `boolean` | `false` | Whether the trigger is disabled |
| `className` | `string` | - | Additional CSS classes |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### TabsTriggerRenderProps
When using a render function for `children`, the following props are provided:
| property | type | description |
| ------------ | --------- | ------------------------------------------ |
| `isSelected` | `boolean` | Whether this trigger is currently selected |
| `value` | `string` | The value of the trigger |
| `isDisabled` | `boolean` | Whether the trigger is disabled |
### Tabs.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Text content to be rendered as label |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Tabs.Indicator
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom indicator content |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `TabsIndicatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### TabsIndicatorAnimation
Animation configuration for Tabs.Indicator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------- | -------------------------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `width.type` | `'spring' \| 'timing'` | `'spring'` | Type of animation to use |
| `width.config` | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration |
| `height.type` | `'spring' \| 'timing'` | `'spring'` | Type of animation to use |
| `height.config` | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration |
| `translateX.type` | `'spring' \| 'timing'` | `'spring'` | Type of animation to use |
| `translateX.config` | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }` (spring) or `{ duration: 200 }` (timing) | Reanimated animation configuration |
### Tabs.Separator
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `betweenValues` | `string[]` | - | Array of tab values between which the separator should be visible. The separator shows when the current tab value is NOT in this array |
| `isAlwaysVisible` | `boolean` | `false` | If true, opacity is always 1 regardless of the current tab value |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `TabsSeparatorAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `children` | `React.ReactNode` | - | Custom separator content |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
**Note:** The following style properties are occupied by animations and cannot be set via className:
* `opacity` - Animated for separator visibility transitions (0 when current tab is in `betweenValues`, 1 when not)
To customize these properties, use the `animation` prop. To completely disable animated styles and use your own via className or style prop, set `isAnimatedStyleActive={false}`.
#### TabsSeparatorAnimation
Animation configuration for Tabs.Separator component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------------------- | ----------------------- | ------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 1]` | Opacity values \[hidden, visible] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | Animation timing configuration |
### Tabs.Content
| prop | type | default | description |
| -------------- | ----------------- | ------- | --------------------------------------------------- |
| `children` | `React.ReactNode` | - | Children elements to be rendered inside the content |
| `value` | `string` | - | The value of the tab this content belongs to |
| `className` | `string` | - | Additional CSS classes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
## Hooks
### useTabs
Hook to access tabs root context values within custom components or compound components.
```tsx
import { useTabs } from 'heroui-native';
const CustomComponent = () => {
const { value, onValueChange, nativeID } = useTabs();
// ... your implementation
};
```
**Returns:** `UseTabsReturn`
| property | type | description |
| --------------- | ------------------------- | ------------------------------------------ |
| `value` | `string` | Currently active tab value |
| `onValueChange` | `(value: string) => void` | Callback function to change the active tab |
| `nativeID` | `string` | Unique identifier for the tabs instance |
**Note:** This hook must be used within a `Tabs` component. It will throw an error if called outside of the tabs context.
### useTabsMeasurements
Hook to access tab measurements context values for managing tab trigger positions and dimensions.
```tsx
import { useTabsMeasurements } from 'heroui-native';
const CustomIndicator = () => {
const { measurements, variant } = useTabsMeasurements();
// ... your implementation
};
```
**Returns:** `UseTabsMeasurementsReturn`
| property | type | description |
| ----------------- | ------------------------------------------------------- | ------------------------------------------------- |
| `measurements` | `Record` | Record of measurements for each tab trigger |
| `setMeasurements` | `(key: string, measurements: ItemMeasurements) => void` | Function to update measurements for a tab trigger |
| `variant` | `'primary' \| 'secondary'` | Visual variant of the tabs |
#### ItemMeasurements
| property | type | description |
| -------- | -------- | ----------------------------------- |
| `width` | `number` | Width of the tab trigger in pixels |
| `height` | `number` | Height of the tab trigger in pixels |
| `x` | `number` | X position of the tab trigger |
**Note:** This hook must be used within a `Tabs` component. It will throw an error if called outside of the tabs context.
### useTabsTrigger
Hook to access tab trigger context values within custom components or compound components.
```tsx
import { useTabsTrigger } from 'heroui-native';
const CustomLabel = () => {
const { value, isSelected, nativeID } = useTabsTrigger();
// ... your implementation
};
```
**Returns:** `UseTabsTriggerReturn`
| property | type | description |
| ------------ | --------- | ------------------------------------------ |
| `value` | `string` | The value of this trigger |
| `nativeID` | `string` | Unique identifier for this trigger |
| `isSelected` | `boolean` | Whether this trigger is currently selected |
**Note:** This hook must be used within a `Tabs.Trigger` component. It will throw an error if called outside of the trigger context.
# BottomSheet
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/bottom-sheet
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(overlays)/bottom-sheet.mdx
> Displays a bottom sheet that slides up from the bottom with animated transitions and swipe-to-dismiss gestures.
## Import
```tsx
import { BottomSheet } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
...
```
* **BottomSheet**: Root component that manages open state and provides context to child components.
* **BottomSheet.Trigger**: Pressable element that opens the bottom sheet when pressed.
* **BottomSheet.Portal**: Renders bottom sheet content in a portal with full window overlay.
* **BottomSheet.Overlay**: Background overlay that covers the screen, typically closes bottom sheet when pressed.
* **BottomSheet.Content**: Main bottom sheet container using @gorhom/bottom-sheet for rendering with gesture support.
* **BottomSheet.Close**: Close button for the bottom sheet. Can accept custom children or uses default close icon.
* **BottomSheet.Title**: Bottom sheet title text with semantic heading role and accessibility linking.
* **BottomSheet.Description**: Bottom sheet description text that provides additional context with accessibility linking.
## Usage
### Basic Bottom Sheet
Simple bottom sheet with title, description, and close button.
```tsx
...
...
```
### Detached Bottom Sheet
Bottom sheet that appears detached from the bottom edge with custom spacing.
```tsx
...
...
```
### Scrollable with Snap Points
Bottom sheet with multiple snap points and scrollable content.
To make scrollable content work correctly inside `BottomSheet.Content`, follow these base principles:
* Use a scrollable from [`@gorhom/bottom-sheet`](https://gorhom.dev/react-native-bottom-sheet/components/bottomsheetscrollview) (e.g. `BottomSheetScrollView`, `BottomSheetFlatList`, `BottomSheetSectionList`, `BottomSheetVirtualizedList`). A plain `ScrollView`/`FlatList` from `react-native` will let the sheet intercept the scroll gesture.
* On `BottomSheet.Content`, disable over-drag and dynamic sizing so the sheet does not grow with its content or absorb the scroll: `enableOverDrag={false}` and `enableDynamicSizing={false}`.
* Give `BottomSheet.Content` a fixed height via `contentContainerClassName="h-full"` (or any other fixed height). The constraint must be on `BottomSheet.Content`, not on the scrollable child — the scrollable needs a bounded parent to scroll inside.
```tsx
import { BottomSheetScrollView } from '@gorhom/bottom-sheet';
...
...
;
```
See the full example with a sticky footer (`BottomSheetFooter`) in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/components/bottom-sheet/scrollable-with-snap-points.tsx).
### Custom Overlay
Replace the default overlay with custom content like blur effects.
```tsx
import { useBottomSheet, useBottomSheetAnimation } from 'heroui-native';
import { StyleSheet, Pressable } from 'react-native';
import { interpolate, useDerivedValue } from 'react-native-reanimated';
import { AnimatedBlurView } from './animated-blur-view';
import { useUniwind } from 'uniwind';
export const BottomSheetBlurOverlay = () => {
const { theme } = useUniwind();
const { onOpenChange } = useBottomSheet();
const { progress } = useBottomSheetAnimation();
const blurIntensity = useDerivedValue(() => {
return interpolate(progress.get(), [0, 1, 2], [0, 40, 0]);
});
return (
onOpenChange(false)}
>
);
};
```
```tsx
...
...
```
### With Keyboard-Aware Input
When rendering an `Input` or `InputOTP` inside `BottomSheet.Content`, use the `useBottomSheetAwareHandlers` hook to wire keyboard avoidance handlers. Pass the returned `onFocus` / `onBlur` to your input.
> **Note**: `useBottomSheetAwareHandlers` must be used inside a `BottomSheet`. Call it from a child component rendered inside `BottomSheet.Content` — outside of a `BottomSheet` context the returned handlers are no-ops.
For scrollable content, also configure `BottomSheet.Content` with `keyboardBehavior="extend"` (or `"interactive"`) and `keyboardShouldPersistTaps="handled"` on the scrollable so taps don't dismiss the keyboard before reaching their target.
```tsx
import { BottomSheet, Input, useBottomSheetAwareHandlers } from 'heroui-native';
const BottomSheetTextInput = () => {
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
return ;
};
...
;
```
See full examples for [`Input`](https://github.com/heroui-inc/heroui-native/blob/main/example/src/components/bottom-sheet/with-text-input.tsx) and [`InputOTP`](https://github.com/heroui-inc/heroui-native/blob/main/example/src/components/bottom-sheet/with-otp-input.tsx) inside a bottom sheet.
## Example
```tsx
import { BottomSheet, Button } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
import { withUniwind } from 'uniwind';
import Ionicons from '@expo/vector-icons/Ionicons';
const StyledIonicons = withUniwind(Ionicons);
export default function BottomSheetExample() {
const [isOpen, setIsOpen] = useState(false);
return (
Keep yourself safe
Update your software to the latest version for better security and
performance.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/bottom-sheet.tsx).
## API Reference
### BottomSheet
| prop | type | default | description |
| --------------- | -------------------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Bottom sheet content and trigger elements |
| `isOpen` | `boolean` | - | Controlled open state of the bottom sheet |
| `isDefaultOpen` | `boolean` | `false` | Initial open state when uncontrolled |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration |
| `onOpenChange` | `(value: boolean) => void` | - | Callback when open state changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### Animation Configuration
Animation configuration for bottom sheet root component. Can be:
* `"disable-all"`: Disable all animations including children
* `undefined`: Use default animations
### BottomSheet.Trigger
| prop | type | default | description |
| -------------------------- | ----------------------- | ------- | -------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Trigger element content |
| `asChild` | `boolean` | - | Render as child element without wrapper |
| `...TouchableOpacityProps` | `TouchableOpacityProps` | - | All standard React Native TouchableOpacity props are supported |
### BottomSheet.Portal
| prop | type | default | description |
| -------------------------------------------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Portal content (overlay and bottom sheet) |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; overlay won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `className` | `string` | - | Additional CSS classes for portal container |
| `style` | `StyleProp` | - | Additional styles for portal container |
| `hostName` | `string` | - | Optional portal host name for specific container |
| `forceMount` | `boolean` | - | Force mount when closed for animation purposes |
### BottomSheet.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------ | ------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom overlay content |
| `className` | `string` | - | Additional CSS classes for overlay |
| `style` | `ViewStyle` | - | Additional styles for overlay container |
| `animation` | `Omit` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `isCloseOnPress` | `boolean` | `true` | Whether pressing overlay closes bottom sheet |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### Animation Configuration
Animation configuration for bottom sheet overlay component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration (excluding `entering` and `exiting` properties)
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | Opacity values \[idle, open, close] |
### BottomSheet.Content
| prop | type | default | description |
| --------------------------- | ---------------------------------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Bottom sheet content |
| `className` | `string` | - | Additional CSS classes for bottom sheet container |
| `containerClassName` | `string` | - | Additional CSS classes for container |
| `contentContainerClassName` | `string` | - | Additional CSS classes for content container |
| `backgroundClassName` | `string` | - | Additional CSS classes for background |
| `handleClassName` | `string` | - | Additional CSS classes for handle |
| `handleIndicatorClassName` | `string` | - | Additional CSS classes for handle indicator |
| `contentContainerProps` | `Omit` | - | Props for the content container |
| `animation` | `AnimationDisabled` | - | Animation configuration |
| `...GorhomBottomSheetProps` | `Partial` | - | All [@gorhom/bottom-sheet props](https://gorhom.dev/react-native-bottom-sheet/props) are supported |
**Note**: You can use all components from [@gorhom/bottom-sheet](https://gorhom.dev/react-native-bottom-sheet/components/bottomsheetview) inside the content, such as `BottomSheetView`, `BottomSheetScrollView`, `BottomSheetFlatList`, etc.
### BottomSheet.Close
BottomSheet.Close extends [CloseButton](./close-button) and automatically handles bottom sheet dismissal when pressed.
### BottomSheet.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Title content |
| `className` | `string` | - | Additional CSS classes for title |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### BottomSheet.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Description content |
| `className` | `string` | - | Additional CSS classes for description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
## Hooks
### useBottomSheet
Hook to access bottom sheet primitive context.
```tsx
const { isOpen, onOpenChange } = useBottomSheet();
```
| property | type | description |
| -------------- | -------------------------- | ----------------------------- |
| `isOpen` | `boolean` | Current open state |
| `onOpenChange` | `(value: boolean) => void` | Function to change open state |
### useBottomSheetAnimation
Hook to access bottom sheet animation context for advanced customization.
```tsx
const { progress } = useBottomSheetAnimation();
```
| property | type | description |
| ---------- | --------------------- | -------------------------------------------- |
| `progress` | `SharedValue` | Animation progress (0=idle, 1=open, 2=close) |
### useBottomSheetAwareHandlers
Hook that returns `onFocus` and `onBlur` handlers for keyboard avoidance when an `Input` or `InputOTP` is rendered inside `BottomSheet.Content`. Must be used inside a `BottomSheet` — outside of a `BottomSheet` context, the returned handlers are no-ops.
```tsx
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
```
| property | type | description |
| --------- | ------------------------- | ------------------------------------------------------------------------------------ |
| `onFocus` | `(e: FocusEvent) => void` | Focus handler that notifies the bottom sheet about the keyboard target |
| `onBlur` | `(e: BlurEvent) => void` | Blur handler that conditionally clears the keyboard target in the bottom sheet state |
## Special Notes
### Element Inspector (iOS)
BottomSheet uses FullWindowOverlay on iOS, which renders in a separate native window. This breaks the React Native element inspector. To enable the inspector during development, set `disableFullWindowOverlay={true}` on `BottomSheet.Portal`. Tradeoff: the bottom sheet will not appear above native modals when disabled.
### Handling Close Callbacks
It's recommended to use `BottomSheet`'s `onOpenChange` prop for handling close callbacks, as it reliably fires for all close scenarios (swiping down, pressing overlay, pressing close button, programmatic close, etc.).
```tsx
{
setIsOpen(value);
if (!value) {
// This callback runs whenever the bottom sheet closes
// regardless of how it was closed
yourCallbackOnClose();
}
}}
>
...
```
**Note**: `BottomSheet.Content`'s `onClose` prop (from @gorhom/bottom-sheet) has limitations and will only fire when the bottom sheet is closed by swiping down. It won't fire when closing via overlay press, close button, or programmatic close. For reliable close callbacks, always use `BottomSheet`'s `onOpenChange` prop instead.
# Dialog
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/dialog
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(overlays)/dialog.mdx
> Displays a modal overlay with animated transitions and gesture-based dismissal.
## Import
```tsx
import { Dialog } from 'heroui-native';
```
## Anatomy
```tsx
```
* **Dialog**: Root component that manages open state and provides context to child components.
* **Dialog.Trigger**: Pressable element that opens the dialog when pressed.
* **Dialog.Portal**: Renders dialog content in a portal with centered layout and animation control.
* **Dialog.Overlay**: Background overlay that appears behind the dialog content, typically closes dialog when pressed.
* **Dialog.Content**: Main dialog container with gesture support for drag-to-dismiss.
* **Dialog.Close**: Close button for the dialog. Can accept custom children or uses default close icon.
* **Dialog.Title**: Dialog title text with semantic heading role.
* **Dialog.Description**: Dialog description text that provides additional context.
## Usage
### Basic Dialog
Simple dialog with title, description, and close button.
```tsx
```
### Scrollable Content
Handle long content with scroll views.
```tsx
```
### Form Dialog
Dialog with text inputs and keyboard handling.
```tsx
```
## Example
```tsx
import { Button, Dialog } from 'heroui-native';
import { View } from 'react-native';
import { useState } from 'react';
export default function DialogExample() {
const [isOpen, setIsOpen] = useState(false);
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/dialog.tsx).
## API Reference
### Dialog
| prop | type | default | description |
| --------------- | -------------------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Dialog content and trigger elements |
| `isOpen` | `boolean` | - | Controlled open state of the dialog |
| `isDefaultOpen` | `boolean` | `false` | Initial open state when uncontrolled |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration |
| `onOpenChange` | `(value: boolean) => void` | - | Callback when open state changes |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AnimationRootDisableAll
Animation configuration for dialog root component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
### Dialog.Trigger
| prop | type | default | description |
| -------------------------- | ----------------------- | ------- | -------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Trigger element content |
| `asChild` | `boolean` | - | Render as child element without wrapper |
| `...TouchableOpacityProps` | `TouchableOpacityProps` | - | All standard React Native TouchableOpacity props are supported |
### Dialog.Portal
| prop | type | default | description |
| -------------------------------------------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Portal content (overlay and dialog) |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; overlay won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `className` | `string` | - | Additional CSS classes for portal container |
| `style` | `StyleProp` | - | Additional styles for portal container |
| `hostName` | `string` | - | Optional portal host name for specific container |
| `forceMount` | `boolean` | - | Force mount when closed for animation purposes |
### Dialog.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ------------------------------------------------------------ |
| `children` | `React.ReactNode` | - | Custom overlay content |
| `className` | `string` | - | Additional CSS classes for overlay |
| `style` | `ViewStyle` | - | Additional styles for overlay container |
| `animation` | `DialogOverlayAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `isCloseOnPress` | `boolean` | `true` | Whether pressing overlay closes dialog |
| `forceMount` | `boolean` | - | Force mount when closed for animation purposes |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
#### DialogOverlayAnimation
Animation configuration for dialog overlay component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| --------------- | -------------------------- | ----------------------- | ----------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | Opacity values \[idle, open, close] (progress-based, for dialog presentation) |
| `entering` | `EntryOrExitLayoutType` | `FadeIn.duration(200)` | Custom entering animation (for popover presentation) |
| `exiting` | `EntryOrExitLayoutType` | `FadeOut.duration(150)` | Custom exiting animation (for popover presentation) |
### Dialog.Content
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | --------------------------------------------------- |
| `children` | `React.ReactNode` | - | Dialog content |
| `className` | `string` | - | Additional CSS classes for content container |
| `style` | `StyleProp` | - | Additional styles for content container |
| `animation` | `DialogContentAnimation` | - | Animation configuration |
| `isSwipeable` | `boolean` | `true` | Whether the dialog content can be swiped to dismiss |
| `forceMount` | `boolean` | - | Force mount when closed for animation purposes |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### DialogContentAnimation
Animation configuration for dialog content component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------- | ----------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | Keyframe with `scale: 0.96→1` and `opacity: 0→1` (200ms, easing: `Easing.out(Easing.ease)`) | Custom entering animation |
| `exiting` | `EntryOrExitLayoutType` | Keyframe with `scale: 1→0.96` and `opacity: 1→0` (150ms, easing: `Easing.in(Easing.ease)`) | Custom exiting animation |
### Dialog.Close
Dialog.Close extends [CloseButton](./close-button) and automatically handles dialog dismissal when pressed.
### Dialog.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Title content |
| `className` | `string` | - | Additional CSS classes for title |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Dialog.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Description content |
| `className` | `string` | - | Additional CSS classes for description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
## Hooks
### useDialog
Hook to access dialog primitive context.
```tsx
const { isOpen, onOpenChange } = useDialog();
```
| property | type | description |
| -------------- | -------------------------- | ----------------------------- |
| `isOpen` | `boolean` | Current open state |
| `onOpenChange` | `(value: boolean) => void` | Function to change open state |
### useDialogAnimation
Hook to access dialog animation context for advanced customization.
```tsx
const { progress, isDragging, isGestureReleaseAnimationRunning } =
useDialogAnimation();
```
| property | type | description |
| ---------------------------------- | ---------------------- | -------------------------------------------- |
| `progress` | `SharedValue` | Animation progress (0=idle, 1=open, 2=close) |
| `isDragging` | `SharedValue` | Whether dialog is being dragged |
| `isGestureReleaseAnimationRunning` | `SharedValue` | Whether gesture release animation is running |
## Special Notes
### Element Inspector (iOS)
Dialog uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `Dialog.Portal`. Tradeoff: the dialog will not appear above native modals when disabled.
# Popover
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/popover
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(overlays)/popover.mdx
> Displays a floating content panel anchored to a trigger element with placement and alignment options.
## Import
```tsx
import { Popover } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **Popover**: Main container that manages open/close state, positioning, and provides context to child components.
* **Popover.Trigger**: Clickable element that toggles popover visibility. Wraps any child element with press handlers.
* **Popover.Portal**: Renders popover content in a portal layer above other content. Ensures proper stacking and positioning.
* **Popover.Overlay**: Optional background overlay. Can be transparent or semi-transparent to capture outside clicks.
* **Popover.Content**: Container for popover content with positioning, styling, and collision detection. Supports both popover and bottom-sheet presentations.
* **Popover.Arrow**: Optional arrow element pointing to the trigger. Automatically positioned based on placement.
* **Popover.Close**: Close button for the popover. Can accept custom children or uses default close icon.
* **Popover.Title**: Optional title text with pre-styled typography.
* **Popover.Description**: Optional description text with muted styling.
## Usage
### Basic Usage
The Popover component uses compound parts to create floating content panels.
```tsx
...
...
```
### With Title and Description
Structure popover content with title and description for better information hierarchy.
```tsx
...
...
...
```
### With Arrow
Add an arrow pointing to the trigger element for better visual connection.
```tsx
...
...
```
> **Note:** When using ``, you need to apply a border to `Popover.Content`, for instance using the `border border-border` class. This ensures the arrow visually connects properly with the content border.
### Width Control
Control the width of the popover content using the `width` prop.
```tsx
{
/* Fixed width in pixels */
}
...
...
;
{
/* Match trigger width */
}
...
...
;
{
/* Full width (100%) */
}
...
...
;
{
/* Auto-size to content (default) */
}
...
...
;
```
### Bottom Sheet Presentation
Use bottom sheet presentation for mobile-optimized interaction patterns.
> **Important:** The `presentation` prop on `Popover.Content` must match the `presentation` prop on `Popover.Root`. In development mode, a mismatch will throw an error.
```tsx
...
...
...
```
### Placement Options
Control where the popover appears relative to the trigger element.
```tsx
...
...
```
### Alignment Options
Fine-tune content alignment along the placement axis.
```tsx
...
...
```
### Custom Animation
Configure custom animations for open and close transitions using the `animation` prop on `Popover.Root`.
```tsx
...
...
```
### Programmatic control
```tsx
// Open or close popover programmatically using ref
const popoverRef = useRef(null);
// Open programmatically
popoverRef.current?.open();
// Close programmatically
popoverRef.current?.close();
// Full example
Content
;
```
## Example
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Button, Popover, useThemeColor } from 'heroui-native';
import { Text, View } from 'react-native';
export default function PopoverExample() {
const themeColorMuted = useThemeColor('muted');
return (
Information
This popover includes a title and description to provide more
structured information to users.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/popover.tsx).
## API Reference
### Popover
| prop | type | default | description |
| --------------- | ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | Children elements to be rendered inside the popover |
| `isOpen` | `boolean` | - | Whether the popover is open (controlled mode) |
| `isDefaultOpen` | `boolean` | - | The open state of the popover when initially rendered (uncontrolled mode) |
| `onOpenChange` | `(isOpen: boolean) => void` | - | Callback when the popover open state changes |
| `animation` | `AnimationRootDisableAll` | - | Animation configuration. Can be `false`, `"disabled"`, `"disable-all"`, `true`, or `undefined` |
| `presentation` | `'popover' \| 'bottom-sheet'` | `'popover'` | Presentation mode for the popover content |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### AnimationRootDisableAll
Animation configuration for popover root component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
### Popover.Trigger
| prop | type | default | description |
| ------------------- | ---------------- | ------- | ------------------------------------------------------- |
| `children` | `ReactNode` | - | The trigger element content |
| `className` | `string` | - | Additional CSS classes for the trigger |
| `asChild` | `boolean` | `true` | Whether to render as a child element |
| `...PressableProps` | `PressableProps` | - | All standard React Native Pressable props are supported |
### Popover.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The portal content (required) |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; overlay won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `hostName` | `string` | - | Optional name of the host element for the portal |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `className` | `string` | - | Additional CSS classes for the portal container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Popover.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------- | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes for the overlay |
| `closeOnPress` | `boolean` | `true` | Whether to close the popover when overlay is pressed |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `animation` | `PopoverOverlayAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
#### PopoverOverlayAnimation
Animation configuration for popover overlay component. Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| --------------- | -------------------------- | --------------------------- | ----------------------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | Opacity values \[idle, open, close] - Takes effect for bottom-sheet/dialog presentation |
| `entering` | `EntryOrExitLayoutType` | FadeIn with duration 200ms | Custom Keyframe animation for entering transition - Takes effect for popover presentation |
| `exiting` | `EntryOrExitLayoutType` | FadeOut with duration 150ms | Custom Keyframe animation for exiting transition - Takes effect for popover presentation |
### Popover.Content (Popover Presentation)
| prop | type | default | description |
| ------------------------- | ------------------------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The popover content |
| `presentation` | `'popover'` | `'popover'` | Presentation mode - must match Popover.Root presentation prop. When not provided, defaults to 'popover' |
| `width` | `number \| 'trigger' \| 'content-fit' \| 'full'` | `'content-fit'` | Width sizing strategy for the content |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | Placement of the popover relative to trigger |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alignment along the placement axis |
| `avoidCollisions` | `boolean` | `true` | Whether to flip placement when close to viewport edges |
| `offset` | `number` | `9` | Distance from trigger element in pixels |
| `alignOffset` | `number` | `0` | Offset along the alignment axis in pixels |
| `disablePositioningStyle` | `boolean` | `false` | Whether to disable automatic positioning styles |
| `forceMount` | `boolean` | - | Whether to force mount the component in the DOM |
| `insets` | `Insets` | - | Screen edge insets to respect when positioning |
| `className` | `string` | - | Additional CSS classes for the content container |
| `animation` | `PopupPopoverContentAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | All Reanimated Animated.View props are supported |
### Popover.Content (Bottom Sheet Presentation)
| prop | type | default | description |
| --------------------------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | The bottom sheet content |
| `presentation` | `'bottom-sheet'` | - | Presentation mode - must be 'bottom-sheet' and match Popover.Root presentation prop (required) |
| `contentContainerClassName` | `string` | - | Additional CSS classes for the content container |
| `contentContainerProps` | `BottomSheetViewProps` | - | Props for the content container |
| `enablePanDownToClose` | `boolean` | `true` | Whether pan down gesture closes the sheet |
| `backgroundStyle` | `ViewStyle` | - | Style for the bottom sheet background |
| `handleIndicatorStyle` | `ViewStyle` | - | Style for the bottom sheet handle indicator |
| `...BottomSheetProps` | `BottomSheetProps` | - | All @gorhom/bottom-sheet props are supported |
#### PopupPopoverContentAnimation
Animation configuration for popover content component (popover presentation). Can be:
* `false` or `"disabled"`: Disable all animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ---------- | ----------------------- | --------------------------------------------------------------- | ------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `entering` | `EntryOrExitLayoutType` | Keyframe with translateY/translateX, scale, and opacity (200ms) | Custom Keyframe animation for entering transition |
| `exiting` | `EntryOrExitLayoutType` | Keyframe mirroring entering animation (150ms) | Custom Keyframe animation for exiting transition |
### Popover.Arrow
| prop | type | default | description |
| --------------------- | ---------------------------------------- | ------- | --------------------------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes for the arrow |
| `height` | `number` | `12` | Height of the arrow in pixels |
| `width` | `number` | `20` | Width of the arrow in pixels |
| `fill` | `string` | - | Fill color of the arrow (defaults to content background) |
| `stroke` | `string` | - | Stroke (border) color of the arrow (defaults to content border color) |
| `strokeWidth` | `number` | `1` | Stroke width of the arrow border in pixels |
| `strokeBaselineInset` | `number` | `1` | Baseline inset in pixels for stroke alignment |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | - | Placement of the popover (inherited from content) |
| `children` | `ReactNode` | - | Custom arrow content (replaces default SVG arrow) |
| `style` | `StyleProp` | - | Additional styles for the arrow container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
### Popover.Close
Popover.Close extends [CloseButton](./close-button) and automatically handles popover dismissal when pressed.
### Popover.Title
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The title text content |
| `className` | `string` | - | Additional CSS classes for the title |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Popover.Description
| prop | type | default | description |
| -------------- | ----------- | ------- | -------------------------------------------------- |
| `children` | `ReactNode` | - | The description text content |
| `className` | `string` | - | Additional CSS classes for the description |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
## Hooks
### usePopover
Hook to access popover context values within custom components or compound components.
```tsx
import { usePopover } from 'heroui-native';
const CustomContent = () => {
const { isOpen, onOpenChange, triggerPosition } = usePopover();
// ... your implementation
};
```
**Returns:** `UsePopoverReturn`
| property | type | description |
| -------------------- | --------------------------------------------------- | ----------------------------------------------------------------- |
| `isOpen` | `boolean` | Whether the popover is currently open |
| `onOpenChange` | `(open: boolean) => void` | Callback function to change the popover open state |
| `isDefaultOpen` | `boolean \| undefined` | Whether the popover should be open by default (uncontrolled mode) |
| `isDisabled` | `boolean \| undefined` | Whether the popover is disabled |
| `triggerPosition` | `LayoutPosition \| null` | The position of the trigger element relative to the viewport |
| `setTriggerPosition` | `(triggerPosition: LayoutPosition \| null) => void` | Function to update the trigger element's position |
| `contentLayout` | `LayoutRectangle \| null` | The layout measurements of the popover content |
| `setContentLayout` | `(contentLayout: LayoutRectangle \| null) => void` | Function to update the content layout measurements |
| `nativeID` | `string` | Unique identifier for the popover instance |
**Note:** This hook must be used within a `Popover` component. It will throw an error if called outside of the popover context.
### usePopoverAnimation
Hook to access popover animation state values within custom components or compound components.
```tsx
import { usePopoverAnimation } from 'heroui-native';
const CustomContent = () => {
const { progress, isDragging } = usePopoverAnimation();
// ... your implementation
};
```
**Returns:** `UsePopoverAnimationReturn`
| property | type | description |
| ------------ | ---------------------- | ------------------------------------------------------------------ |
| `progress` | `SharedValue` | Progress value for the popover animation (0=idle, 1=open, 2=close) |
| `isDragging` | `SharedValue` | Dragging state shared value |
**Note:** This hook must be used within a `Popover` component. It will throw an error if called outside of the popover animation context.
## Special Notes
### Element Inspector (iOS)
Popover uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `Popover.Portal`. Tradeoff: the popover will not appear above native modals when disabled.
### Native Modal (iOS)
When a `Popover` is opened inside a screen presented as a native modal (`presentation: 'modal' | 'formSheet' | 'pageSheet'`), the popover content may render shifted upward. In the new architecture (Fabric), `react-native-screens` marks `RNSModalScreen` as a Fabric root, so the trigger's position is reported relative to the modal's origin while `FullWindowOverlay` (where the popover is mounted) is anchored to the iOS application window. Compensate by adding `safeAreaInsets.top` to `offset`:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# Toast
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/toast
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(overlays)/toast.mdx
> Displays temporary notification messages that appear at the top or bottom of the screen.
## Import
```tsx
import { Toast, useToast } from 'heroui-native';
```
## Anatomy
```tsx
...
...
...
```
* **Toast**: Main container that displays notification messages. Handles positioning, animations, and swipe gestures.
* **Toast.Title**: Title text of the toast notification. Inherits variant styling from parent Toast context.
* **Toast.Description**: Descriptive text content displayed below the title.
* **Toast.Action**: Action button within the toast. Button variant is automatically determined based on toast variant but can be overridden.
* **Toast.Close**: Close button for dismissing the toast. Renders as an icon-only button that calls hide when pressed.
## Usage
### Usage Pattern 1: Simple String
Show a toast with a simple string message.
```tsx
const { toast } = useToast();
toast.show('This is a toast message');
```
### Usage Pattern 2: Config Object
Show a toast with label, description, variant, and action button using a config object.
```tsx
const { toast } = useToast();
toast.show({
variant: 'success',
label: 'You have upgraded your plan',
description: 'You can continue using HeroUI Chat',
icon: ,
actionLabel: 'Close',
onActionPress: ({ hide }) => hide(),
});
```
### Usage Pattern 3: Custom Component
Show a toast with a fully custom component for complete control over styling and layout.
```tsx
const { toast } = useToast();
toast.show({
component: (props) => (
Custom Toast
This is a custom toast component
),
});
```
**Note**: Toast items are memoized for performance. If you need to pass external state (like loading state) to a custom toast component, it will not update automatically. Use shared state techniques instead, such as React Context, state management libraries, or refs to ensure state updates propagate to the toast component.
### Disabling All Animations
Disable all animations including children by using `"disable-all"`. This cascades down to all child components (like Button in Toast.Action).
```tsx
const { toast } = useToast();
toast.show({
variant: 'success',
label: 'Operation completed',
description: 'All animations are disabled',
animation: 'disable-all',
});
```
Or with a custom component:
```tsx
const { toast } = useToast();
toast.show({
component: (props) => (
No animations
This toast has all animations disabled
Action
),
});
```
## Example
```tsx
import { Button, Toast, useToast, useThemeColor } from 'heroui-native';
import { View } from 'react-native';
export default function ToastExample() {
const { toast } = useToast();
const themeColorForeground = useThemeColor('foreground');
return (
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/toast.tsx).
## Global Configuration
Configure toast behavior globally using `HeroUINativeProvider` config prop. Global configs serve as defaults for all toasts unless overridden locally.
> **Note**: For complete provider configuration options, see the [Provider documentation](/docs/native/getting-started/handbook/provider#toast-configuration).
### Insets
Insets control the distance of toast sides from screen edges. Insets are added to safe area insets. To set all toasts to have a side distance of 20px from screen edges, configure insets:
```tsx
{children}
```
### Content Wrapper with KeyboardAvoidingView
Wrap toast content with KeyboardAvoidingView to ensure toasts adjust when the keyboard appears:
```tsx
import {
KeyboardAvoidingView,
KeyboardProvider,
} from 'react-native-keyboard-controller';
import { HeroUINativeProvider } from 'heroui-native';
import { useCallback } from 'react';
function AppContent() {
const contentWrapper = useCallback(
(children: React.ReactNode) => (
{children}
),
[]
);
return (
{children}
);
}
```
### Default Props
Set global defaults for variant, placement, animation, and swipe behavior:
```tsx
{children}
```
## API Reference
### Toast
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------- |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | Visual variant of the toast |
| `placement` | `'top' \| 'bottom'` | `'top'` | Placement of the toast on screen |
| `isSwipeable` | `boolean` | `true` | Whether the toast can be swiped to dismiss and dragged with rubber effect |
| `animation` | `ToastRootAnimation` | - | Animation configuration |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `className` | `string` | - | Additional CSS class for the toast container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### ToastRootAnimation
Animation configuration for Toast component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[1, 0]` | Opacity interpolation values for fade effect as toasts move beyond visible stack |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | Animation timing configuration for opacity transitions |
| `translateY.value` | `[number, number]` | `[0, 10]` | Translate Y interpolation values for peek effect of stacked toasts |
| `translateY.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | Animation timing configuration for translateY transitions |
| `scale.value` | `[number, number]` | `[1, 0.97]` | Scale interpolation values for depth effect of stacked toasts |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | Animation timing configuration for scale transitions |
| `entering.top` | `EntryOrExitLayoutType` | `FadeInUp`
`.springify()`
`.withInitialValues({ opacity: 1, transform: [{ translateY: -100 }] })`
`.mass(3)` | Custom entering animation for top placement |
| `entering.bottom` | `EntryOrExitLayoutType` | `FadeInDown`
`.springify()`
`.withInitialValues({ opacity: 1, transform: [{ translateY: 100 }] })`
`.mass(3)` | Custom entering animation for bottom placement |
| `exiting.top` | `EntryOrExitLayoutType` | Keyframe animation with
`translateY: -100, scale: 0.97, opacity: 0.5` | Custom exiting animation for top placement |
| `exiting.bottom` | `EntryOrExitLayoutType` | Keyframe animation with
`translateY: 100, scale: 0.97, opacity: 0.5` | Custom exiting animation for bottom placement |
### Toast.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be rendered as title |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Toast.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be rendered as description |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native Text props are supported |
### Toast.Action
Toast.Action extends all props from [Button](button) component. Button variant is automatically determined based on toast variant but can be overridden.
| prop | type | default | description |
| ----------- | ---------------------- | ------- | ---------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be rendered as action button label |
| `variant` | `ButtonVariant` | - | Button variant. If not provided, automatically determined from toast variant |
| `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Size of the action button |
| `className` | `string` | - | Additional CSS classes |
For inherited props including `onPress`, `isDisabled`, and all Button props, see [Button API Reference](button#api-reference).
### Toast.Close
Toast.Close extends all props from [Button](button) component.
| prop | type | default | description |
| ----------- | ----------------------------------- | ------- | ---------------------------------------------- |
| `children` | `React.ReactNode` | - | Custom close icon. Defaults to CloseIcon |
| `iconProps` | `{ size?: number; color?: string }` | - | Props for the default close icon |
| `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Size of the close button |
| `className` | `string` | - | Additional CSS classes |
| `onPress` | `(event: any) => void` | - | Custom press handler. Defaults to hiding toast |
For inherited props including `isDisabled` and all Button props, see [Button API Reference](button#api-reference).
### ToastProviderProps
Props for configuring toast behavior globally via `HeroUINativeProvider` config prop.
| prop | type | default | description |
| -------------------------------------------- | --------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `defaultProps` | `ToastGlobalConfig` | - | Global toast configuration used as defaults for all toasts |
| `disableFullWindowOverlay` | `boolean` | `false` | When true on iOS, uses View instead of FullWindowOverlay. Enables element inspector; toasts won't appear above native modals |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | Controls whether VoiceOver treats the overlay window as a modal container. When `true`, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates |
| `insets` | `ToastInsets` | - | Insets for spacing from screen edges (added to safe area insets) |
| `maxVisibleToasts` | `number` | `3` | Maximum number of visible toasts before opacity starts fading |
| `contentWrapper` | `(children: React.ReactNode) => React.ReactElement` | - | Custom wrapper function to wrap toast content |
| `children` | `React.ReactNode` | - | Children to render |
#### ToastGlobalConfig
Global toast configuration used as defaults for all toasts unless overridden locally.
| prop | type | description |
| ------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | Visual variant of the toast |
| `placement` | `'top' \| 'bottom'` | Placement of the toast on screen |
| `isSwipeable` | `boolean` | Whether the toast can be swiped to dismiss and dragged with rubber effect |
| `animation` | `ToastRootAnimation` | Animation configuration for toast |
#### ToastInsets
Insets for spacing from screen edges. Values are added to safe area insets.
| prop | type | default | description |
| -------- | -------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `top` | `number` | - | Inset from the top edge in pixels (added to safe area inset). Platform-specific: iOS = 0, Android = 12 |
| `bottom` | `number` | - | Inset from the bottom edge in pixels (added to safe area inset). Platform-specific: iOS = 6, Android = 12 |
| `left` | `number` | - | Inset from the left edge in pixels (added to safe area inset). Default: 12 |
| `right` | `number` | - | Inset from the right edge in pixels (added to safe area inset). Default: 12 |
## Hooks
### useToast
Hook to access toast functionality. Must be used within a `ToastProvider` (provided by `HeroUINativeProvider`).
| return value | type | description |
| ---------------- | -------------- | ---------------------------------------- |
| `toast` | `ToastManager` | Toast manager with show and hide methods |
| `isToastVisible` | `boolean` | Whether any toast is currently visible |
#### ToastManager
| method | type | description |
| ------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `show` | `(options: string \| ToastShowOptions) => string` | Show a toast. Returns the ID of the shown toast. Supports three usage patterns: simple string, config object, or custom component |
| `hide` | `(ids?: string \| string[] \| 'all') => void` | Hide one or more toasts. No argument hides the last toast, 'all' hides all toasts, single ID or array of IDs hides specific toast(s) |
#### ToastShowOptions
Options for showing a toast. Can be either a config object with default styling or a custom component.
**When using config object (without component):**
| prop | type | default | description |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------- |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | - | Visual variant of the toast |
| `placement` | `'top' \| 'bottom'` | - | Placement of the toast on screen |
| `isSwipeable` | `boolean` | - | Whether the toast can be swiped to dismiss |
| `animation` | `ToastRootAnimation \| false \| "disabled" \| "disable-all"` | - | Animation configuration for toast |
| `duration` | `number \| 'persistent'` | `4000` | Duration in milliseconds before auto-hide. Set to 'persistent' to prevent auto-hide |
| `id` | `string` | - | Optional ID for the toast. If not provided, one will be generated |
| `label` | `string` | - | Label text for the toast |
| `description` | `string` | - | Description text for the toast |
| `actionLabel` | `string` | - | Action button label text |
| `onActionPress` | `(helpers: { show: (options: string \| ToastShowOptions) => string; hide: (ids?: string \| string[] \| 'all') => void }) => void` | - | Callback function called when the action button is pressed |
| `icon` | `React.ReactNode` | - | Icon element to display in the toast |
| `onShow` | `() => void` | - | Callback function called when the toast is shown |
| `onHide` | `() => void` | - | Callback function called when the toast is hidden |
**When using custom component:**
| prop | type | default | description |
| ----------- | ---------------------------------------------------- | ------- | ----------------------------------------------------------------------------------- |
| `id` | `string` | - | Optional ID for the toast. If not provided, one will be generated |
| `component` | `(props: ToastComponentProps) => React.ReactElement` | - | A function that receives toast props and returns a React element |
| `duration` | `number \| 'persistent'` | `4000` | Duration in milliseconds before auto-hide. Set to 'persistent' to prevent auto-hide |
| `onShow` | `() => void` | - | Callback function called when the toast is shown |
| `onHide` | `() => void` | - | Callback function called when the toast is hidden |
## Special Notes
### Element Inspector (iOS)
Toast uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set `disableFullWindowOverlay={true}` on `ToastProvider` (via `config.toast` when using HeroUINativeProvider). Tradeoff: toasts will not appear above native modals when disabled.
# Typography
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/text
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(typography)/text.mdx
> Primitive typography component for rendering styled text with semantic type variants.
## Import
```tsx
import { Typography } from 'heroui-native';
```
## Anatomy
```tsx
...
{/* Sub-components */}
...
...
...
```
* **Typography**: Root text element. Selects a typography preset via `type` and exposes orthogonal `align`, `color`, `weight`, and `truncate` props.
* **Typography.Heading**: Convenience wrapper restricted to heading types (`h1`–`h6`). Adds `accessibilityRole="header"` automatically.
* **Typography.Paragraph**: Convenience wrapper restricted to body types (`body`, `body-sm`, `body-xs`).
* **Typography.Code**: Chip-styled inline monospaced text. Uses a platform-appropriate monospace font family.
## Usage
### Basic Usage
The Typography component renders body text by default.
```tsx
Hello, world!
```
### Type Variants
Use the `type` prop to select a semantic typography preset.
```tsx
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Body text
Small body text
Extra-small body text
Code snippet
```
### Headings
Use `Typography.Heading` for heading text with automatic header accessibility role.
```tsx
Page Title
Section Title
Subsection Title
```
### Paragraphs
Use `Typography.Paragraph` for body text.
```tsx
This is a paragraph of body text with the default size.
This is smaller body text.
```
### Code
Use `Typography.Code` (or equivalently ``) for inline code snippets. Both render a chip-styled, monospaced inline element with a subtle background, rounded corners, and a `self-start` layout so it does not stretch in flex containers. The platform monospace `fontFamily` is applied at the `Typography` root, so the two forms are interchangeable.
```tsx
console.log('hello')
console.log('hello')
```
### Alignment
Use the `align` prop to control horizontal alignment. `start` and `end` are RTL-aware (they flip under right-to-left layouts).
```tsx
Start-aligned
Center-aligned
End-aligned
Justified text spreads across the line.
```
> **Note:** `text-justify` is iOS-only on React Native; Android falls back to left alignment.
### Color
Use the `color` prop to apply a semantic foreground color preset.
```tsx
Default foreground
Muted secondary text
```
For other theme colors, pass the corresponding utility through `className` (e.g. `className="text-accent"`, `className="text-danger"`).
### Weight
Use the `weight` prop to override the font weight implied by `type`. The override merges via `tailwind-merge`, so it always wins over the type variant's default weight.
```tsx
Bold H1
Medium body
Semibold body
```
### Truncation
Use the `truncate` boolean prop to limit the text to a single line with an ellipsis. It is mapped to React Native's `numberOfLines={1}`. An explicit `numberOfLines` prop, if provided, takes precedence.
```tsx
A long line of text that will be cut off with an ellipsis when it overflows
the container.
;
{
/* Multi-line truncation via the underlying RN prop */
}
Two-line truncation works through React Native's standard `numberOfLines`
prop.
;
```
## Example
```tsx
import { Typography } from 'heroui-native';
import { View } from 'react-native';
export default function TypographyExample() {
return (
Welcome
Getting Started
This is a body paragraph rendered with the Typography component.
Smaller supporting text for captions or footnotes.
npm install heroui-native
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text.tsx).
## API Reference
### Typography
`Typography` extends all standard React Native `TextProps` with additional typography props.
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `type` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6' \| 'body' \| 'body-sm' \| 'body-xs' \| 'code'` | `'body'` | Semantic typography variant (size, default weight, line-height) |
| `align` | `'start' \| 'center' \| 'end' \| 'justify'` | `'start'` | Horizontal alignment. `start` and `end` are RTL-aware. `justify` is iOS-only. |
| `color` | `'default' \| 'muted'` | `'default'` | Semantic foreground color preset |
| `weight` | `'normal' \| 'medium' \| 'semibold' \| 'bold'` | - | Font weight override. When set, overrides the weight implied by `type`. |
| `truncate` | `boolean` | `false` | Truncates the text to a single line with an ellipsis (sets `numberOfLines={1}`). An explicit `numberOfLines` takes precedence. |
| `children` | `React.ReactNode` | - | Content to render |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native `Text` props are supported |
### Typography.Heading
Inherits all `Typography` root props (`align`, `color`, `weight`, `truncate`, `className`, and React Native `TextProps`). Sets `accessibilityRole="header"` automatically and narrows `type` to heading variants.
| prop | type | default | description |
| -------------- | ---------------------------------------------- | ------- | ---------------------------------------------------- |
| `type` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h1'` | Heading level |
| `children` | `React.ReactNode` | - | Content to render |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native `Text` props are supported |
### Typography.Paragraph
Inherits all `Typography` root props (`align`, `color`, `weight`, `truncate`, `className`, and React Native `TextProps`). Narrows `type` to body variants.
| prop | type | default | description |
| -------------- | ---------------------------------- | -------- | ---------------------------------------------------- |
| `type` | `'body' \| 'body-sm' \| 'body-xs'` | `'body'` | Paragraph text size |
| `children` | `React.ReactNode` | - | Content to render |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native `Text` props are supported |
### Typography.Code
Inherits all `Typography` root props (`align`, `color`, `weight`, `truncate`, `className`, `style`, and React Native `TextProps`). Thin wrapper that forces `type="code"`; the platform monospace `fontFamily` is merged in at the `Typography` root, so `` and `` render identically.
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to render |
| `className` | `string` | - | Additional CSS classes |
| `...TextProps` | `TextProps` | - | All standard React Native `Text` props are supported |
# PressableFeedback
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/pressable-feedback
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(utilities)/pressable-feedback.mdx
> Container component that provides visual feedback for press interactions with automatic scale animation.
## Import
```tsx
import { PressableFeedback } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **PressableFeedback**: Pressable container with built-in scale animation. Manages press state and container dimensions, providing them to child compound parts via context. Use `animation={false}` to disable the built-in scale when using `PressableFeedback.Scale` instead.
* **PressableFeedback.Scale**: Scale animation wrapper for applying scale to a specific child element. Use this instead of the root's built-in scale when you need control over which element scales or need to apply `className` / `style` to the scale wrapper.
* **PressableFeedback.Highlight**: Highlight overlay for iOS-style press feedback. Renders an absolute-positioned layer that fades in on press.
* **PressableFeedback.Ripple**: Ripple overlay for Android-style press feedback. Renders a radial gradient circle that expands from the touch point.
## Usage
### Basic
PressableFeedback provides press-down scale feedback out of the box. This is the recommended way to use it in most cases.
```tsx
...
```
### With Highlight
Add a highlight overlay for iOS-style feedback effect alongside the built-in scale.
```tsx
...
```
### With Ripple
Add a ripple overlay for Android-style feedback effect alongside the built-in scale.
```tsx
...
```
### Custom Scale Animation
Customize the built-in scale animation via the `animation.scale` prop. Accepts `value`, `timingConfig`, and `ignoreScaleCoefficient`.
```tsx
...
```
### Custom Highlight Animation
Configure highlight overlay opacity and background color.
```tsx
...
```
### Custom Ripple Animation
Configure ripple effect color, opacity, and duration.
```tsx
...
```
### Scale on a Specific Child (PressableFeedback.Scale)
When you need to apply the scale animation to a specific element inside the container rather than the root itself, disable the root's built-in scale with `animation={false}` and use the `PressableFeedback.Scale` compound part. This gives you full control over which element scales and lets you apply `className` / `style` directly to the scale wrapper.
```tsx
...
```
You can combine it with Highlight or Ripple inside the Scale wrapper:
```tsx
...
```
### Disable All Animations
Set `animation="disable-all"` on the root to cascade-disable all animations including the built-in scale and any child compound parts (Scale, Highlight, Ripple).
```tsx
...
```
You can also disable all animations while keeping a scale config (e.g. for toggling at runtime):
```tsx
...
```
## Example
```tsx
import { PressableFeedback, Card, Button } from 'heroui-native';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet, View, Text } from 'react-native';
export default function PressableFeedbackExample() {
return (
Neo
Home robot
Available soon
Get notified
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/pressable-feedback.tsx).
## API Reference
### PressableFeedback
| prop | type | default | description |
| ----------------------- | -------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to be wrapped with press feedback |
| `isDisabled` | `boolean` | `false` | Whether the pressable component is disabled |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `PressableFeedbackRootAnimation` | - | Customize scale via `{ scale: ... }`, `false` to disable root scale, `'disable-all'` to cascade-disable all |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether the root's built-in animated styles are active |
| `asChild` | `boolean` | `false` | Whether to render as a child element |
| `...rest` | `AnimatedProps` | - | All Reanimated Animated Pressable props are supported |
#### PressableFeedbackRootAnimation
The root animation prop supports the standard `AnimationRoot` control flow:
* `true` or `undefined`: Use the default built-in scale animation
* `false` or `"disabled"`: Disable the root's built-in scale (use this when applying scale via `PressableFeedback.Scale` instead)
* `"disable-all"`: Cascade-disable all animations including the built-in scale and children (Scale, Highlight, Ripple)
* `object`: Custom configuration for the built-in scale
| prop | type | default | description |
| ------- | ---------------------------------------- | ------- | ------------------------------------------------------------------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | Customize the built-in scale animation (value, timingConfig, etc.) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Control animation state while keeping configuration (e.g. for runtime toggling) |
### PressableFeedback.Scale
Use this compound part when you need to apply scale to a specific child element inside the container, instead of scaling the root itself. Set `animation={false}` on the root to disable its built-in scale when using this component.
| prop | type | default | description |
| ----------------------- | --------------------------------- | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `PressableFeedbackScaleAnimation` | - | Animation configuration for scale effect |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `style` | `ViewStyle` | - | Additional styles |
| `...AnimatedProps` | `AnimatedProps` | - | All Reanimated Animated View props are supported |
#### PressableFeedbackScaleAnimation
Animation configuration for scale effect. Can be:
* `false` or `"disabled"`: Disable scale animation
* `true` or `undefined`: Use default scale animation
* `object`: Custom scale configuration
| prop | type | default | description |
| ------------------------ | ----------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `value` | `number` | `0.985` | Scale value when pressed (automatically adjusted based on container width) |
| `timingConfig` | `WithTimingConfig` | `{ duration: 300, easing: Easing.out(Easing.ease) }` | Animation timing configuration |
| `ignoreScaleCoefficient` | `boolean` | `false` | Ignore automatic scale coefficient and use the scale value directly |
### PressableFeedback.Highlight
| prop | type | default | description |
| ----------------------- | ------------------------------------- | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes |
| `animation` | `PressableFeedbackHighlightAnimation` | - | Animation configuration for highlight overlay |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `style` | `ViewStyle` | - | Additional styles |
| `...AnimatedProps` | `AnimatedProps` | - | All Reanimated Animated View props are supported |
#### PressableFeedbackHighlightAnimation
Animation configuration for highlight overlay. Can be:
* `false` or `"disabled"`: Disable highlight animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ----------------------- | ----------------------- | ------------------- | ----------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 0.1]` | Opacity values \[unpressed, pressed] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | Animation timing configuration |
| `backgroundColor.value` | `string` | Theme-aware gray | Background color of highlight overlay |
### PressableFeedback.Ripple
| prop | type | default | description |
| ----------------------- | ----------------------------------------- | ------- | ------------------------------------------------------------ |
| `className` | `string` | - | Additional CSS classes for container slot |
| `classNames` | `ElementSlots` | - | Additional CSS classes for slots (container, ripple) |
| `styles` | `Partial>` | - | Styles for different parts of the ripple overlay |
| `animation` | `PressableFeedbackRippleAnimation` | - | Animation configuration for ripple overlay |
| `isAnimatedStyleActive` | `boolean` | `true` | Whether animated styles (react-native-reanimated) are active |
| `...ViewProps` | `Omit` | - | All View props except style are supported |
#### `styles`
| prop | type | description |
| ----------- | ----------- | ----------------------------- |
| `container` | `ViewStyle` | Styles for the container slot |
| `ripple` | `ViewStyle` | Styles for the ripple slot |
#### PressableFeedbackRippleAnimation
Animation configuration for ripple overlay. Can be:
* `false` or `"disabled"`: Disable ripple animations
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| ------------------------------------ | -------------------------- | ----------------------- | ---------------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | Disable animations while customizing properties |
| `backgroundColor.value` | `string` | Computed based on theme | Background color of ripple effect |
| `progress.baseDuration` | `number` | `1000` | Base duration for ripple progress (automatically adjusted based on diagonal) |
| `progress.minBaseDuration` | `number` | `750` | Minimum base duration for the ripple progress animation |
| `progress.ignoreDurationCoefficient` | `boolean` | `false` | Ignore automatic duration coefficient and use base duration directly |
| `opacity.value` | `[number, number, number]` | `[0, 0.1, 0]` | Opacity values \[start, peak, end] for ripple animation |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | Animation timing configuration |
| `scale.value` | `[number, number, number]` | `[0, 1, 1]` | Scale values \[start, peak, end] for ripple animation |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | Animation timing configuration |
#### `ElementSlots`
Additional CSS classes for ripple slots:
| slot | description |
| ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `container` | Outer container slot (`absolute inset-0`) - styles can be fully customized |
| `ripple` | Inner ripple slot (`absolute top-0 left-0 rounded-full`) - has animated properties that cannot be set via className |
# ScrollShadow
**Category**: native
**URL**: https://www.heroui.com/en/docs/native/components/scroll-shadow
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/en/native/components/(utilities)/scroll-shadow.mdx
> Adds dynamic gradient shadows to scrollable content based on scroll position and overflow.
## Import
```tsx
import { ScrollShadow } from 'heroui-native';
```
## Anatomy
```tsx
...
```
* **ScrollShadow**: Main container that wraps scrollable components and adds dynamic gradient shadows at the edges based on scroll position and content overflow. Automatically detects scroll orientation (horizontal/vertical) and manages shadow visibility.
* **LinearGradientComponent**: Required prop that accepts a LinearGradient component from compatible libraries (expo-linear-gradient, react-native-linear-gradient, etc.) to render the gradient shadows.
## Usage
### Basic Usage
Wrap any scrollable component to automatically add edge shadows.
```tsx
...
```
### Horizontal Scrolling
The component auto-detects horizontal scrolling from the child's `horizontal` prop.
```tsx
```
### Custom Shadow Size
Control the gradient shadow height/width with the `size` prop.
```tsx
...
```
### Visibility Control
Specify which shadows to display using the `visibility` prop.
```tsx
...
...
...
```
### Custom Shadow Color
Override the default shadow color which uses the theme's background.
```tsx
...
```
### With Custom Scroll Handler
**Important:** ScrollShadow internally converts the child to a Reanimated animated component. If you need to use the `onScroll` prop, you must use `useAnimatedScrollHandler` from react-native-reanimated.
```tsx
import { LinearGradient } from 'expo-linear-gradient';
import Animated, { useAnimatedScrollHandler } from 'react-native-reanimated';
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
console.log(event.contentOffset.y);
},
});
...
;
```
## Example
```tsx
import { ScrollShadow, Surface } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { FlatList, ScrollView, Text, View } from 'react-native';
export default function ScrollShadowExample() {
const horizontalData = Array.from({ length: 10 }, (_, i) => ({
id: i,
title: `Card ${i + 1}`,
}));
return (
Horizontal List
(
{item.title}
)}
showsHorizontalScrollIndicator={false}
contentContainerClassName="p-5 gap-4"
/>
Vertical Content
Long Content
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris.
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
quae ab illo inventore veritatis et quasi architecto beatae vitae.
);
}
```
You can find more examples in the [GitHub repository](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/scroll-shadow.tsx).
## API Reference
### ScrollShadow
| prop | type | default | description |
| ------------------------- | ---------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------- |
| `children` | `React.ReactElement` | - | The scrollable component to enhance with shadows. Must be a single React element (ScrollView, FlatList, etc.) |
| `LinearGradientComponent` | `ComponentType<`
`LinearGradientProps>` | **required** | LinearGradient component from any compatible library (expo-linear-gradient, react-native-linear-gradient, etc.) |
| `size` | `number` | `50` | Size (height/width) of the gradient shadow in pixels |
| `orientation` | `'horizontal' \| 'vertical'` | auto-detect | Orientation of the scroll shadow. If not provided, will auto-detect from child's `horizontal` prop |
| `visibility` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right' \| 'both' \| 'none'` | `'auto'` | Visibility mode for the shadows. 'auto' shows shadows based on scroll position and content overflow |
| `color` | `string` | theme color | Custom color for the gradient shadow. If not provided, uses the theme's background color |
| `isEnabled` | `boolean` | `true` | Whether the shadow effect is enabled |
| `animation` | `ScrollShadowRootAnimation` | - | Animation configuration |
| `className` | `string` | - | Additional CSS classes to apply to the container |
| `...ViewProps` | `ViewProps` | - | All standard React Native View props are supported |
#### ScrollShadowRootAnimation
Animation configuration for ScrollShadow component. Can be:
* `false` or `"disabled"`: Disable only root animations
* `"disable-all"`: Disable all animations including children
* `true` or `undefined`: Use default animations
* `object`: Custom animation configuration
| prop | type | default | description |
| --------------- | ---------------------------------------- | -------- | ------------------------------------------------------------------------------------ |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | Disable animations while customizing properties |
| `opacity.value` | `[number, number]` | `[0, 1]` | `Opacity values [initial, active].`
`For bottom/right shadow, this is reversed` |
### LinearGradientProps
The `LinearGradientComponent` prop expects a component that accepts these props:
| prop | type | description |
| ----------- | --------------------------------- | ------------------------------------------------------------------ |
| `colors` | `any` | Array of colors for the gradient |
| `locations` | `any` (optional) | Array of numbers defining the location of each gradient color stop |
| `start` | `any` (optional) | Start point of the gradient (e.g., `{ x: 0, y: 0 }`) |
| `end` | `any` (optional) | End point of the gradient (e.g., `{ x: 1, y: 0 }`) |
| `style` | `StyleProp` (optional) | Style to apply to the gradient view |
## Special Notes
**Important:** ScrollShadow internally converts the child to a Reanimated animated component. If you need to use the `onScroll` prop on your scrollable component, you must use `useAnimatedScrollHandler` from react-native-reanimated instead of the standard `onScroll` prop.
# Button 按钮
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(buttons)/button.mdx
> 按下时触发操作的交互组件。
## 导入
```tsx
import { Button } from 'heroui-native';
```
## 结构
```tsx
```
* **Button**:主容器,负责按压交互、动画与变体。字符串子节点会渲染为标签,也可使用复合子组件自定义布局。
* **Button.Label**:按钮文字,继承父级 Button 上下文中的尺寸与变体样式。
## 用法
### 基础用法
`Button` 可直接传入字符串子节点,会自动渲染为标签。
```tsx
```
### 使用复合子组件
使用 `Button.Label` 显式控制标签部分。
```tsx
```
### 与图标组合
将图标与文字组合,增强可读性。
```tsx
```
### 仅图标
使用 `isIconOnly` 创建方形纯图标按钮。
```tsx
```
### 尺寸
通过三种尺寸控制按钮大小。
```tsx
```
### 变体
提供七种视觉变体,用于不同强调层级。
```tsx
```
### 反馈变体
`feedbackVariant` 控制渲染哪些按压反馈效果:
* `'scale-highlight'`(默认):内置缩放 + 高亮遮罩
* `'scale-ripple'`:内置缩放 + 水波纹遮罩
* `'scale'`:仅内置缩放(无遮罩)
* `'none'`:无任何反馈动画
```tsx
{/* 缩放 + 高亮(默认) */}
{/* 缩放 + 水波纹 */}
{/* 仅缩放 */}
{/* 无反馈 */}
```
### 自定义动画
`animation` 控制各子动画,其结构取决于 `feedbackVariant`。
```tsx
{/* 自定义缩放与高亮(默认 feedbackVariant) */}
{/* 自定义缩放与水波纹 */}
```
### 关闭部分子动画
将某个子动画设为 `false` 即可单独关闭:
```tsx
{/* 关闭缩放,保留高亮 */}
{/* 关闭高亮,保留缩放 */}
{/* 两者都关 */}
```
### 关闭全部动画
使用 `animation={false}` 关闭所有反馈,或使用 `animation="disable-all"` 级联关闭:
```tsx
```
### 加载态与 Spinner
配合 Spinner 展示加载状态。
```tsx
const themeColorAccentForeground = useThemeColor('accent-foreground');
;
```
### 使用 LinearGradient 自定义背景
通过绝对定位元素添加渐变背景。使用 `feedbackVariant="none"` 关闭默认高亮遮罩,或使用 `feedbackVariant="scale-ripple"` 自定义水波纹。
```tsx
import { Button, PressableFeedback } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet } from 'react-native';
{/* 无反馈遮罩的渐变 */}
{/* 带自定义水波纹的渐变 */}
```
## 示例
```tsx
import { Button, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
export default function ButtonExample() {
const [
themeColorAccentForeground,
themeColorAccentSoftForeground,
themeColorDangerForeground,
themeColorDefaultForeground,
] = useThemeColor([
'accent-foreground',
'accent-soft-foreground',
'danger-foreground',
'default-foreground',
]);
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/button.tsx)。
## API 参考
### Button
`Button` 继承 [PressableFeedback](./pressable-feedback) 的全部属性(`animation` 除外,已重新定义),并增加按钮专用属性。
| prop | type | default | description |
| ----------------- | --------------------------------------------------------------------------------------------- | ------------------- | ----------------------------- |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'outline' \| 'ghost' \| 'danger' \| 'danger-soft'` | `'primary'` | 按钮视觉变体 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 按钮尺寸 |
| `isIconOnly` | `boolean` | `false` | 是否为仅图标按钮(方形比例) |
| `feedbackVariant` | `'scale-highlight' \| 'scale-ripple' \| 'scale' \| 'none'` | `'scale-highlight'` | 决定渲染哪些反馈效果 |
| `animation` | `ButtonAnimation` | - | 动画配置(结构取决于 `feedbackVariant`) |
继承属性(含 `isDisabled`、`className`、`children` 及所有 Pressable 属性)见 [PressableFeedback API 参考](./pressable-feedback#api-reference)。
#### ButtonAnimation
`animation` 是按 `feedbackVariant` 区分的联合类型,遵循 `AnimationRoot` 控制流:
* `true` 或 `undefined`:使用默认动画
* `false` 或 `"disabled"`:关闭所有反馈动画
* `"disable-all"`:级联关闭所有动画(含子复合部件)
* `object`:自定义子动画配置(见下)
**当 `feedbackVariant="scale-highlight"`(默认)时:**
| prop | type | default | description |
| ----------- | ---------------------------------------- | ------- | --------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | 缩放动画配置(`false` 为关闭) |
| `highlight` | `PressableFeedbackHighlightAnimation` | - | 高亮遮罩配置(`false` 为关闭) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在保留配置的同时控制动画状态(运行时切换) |
**当 `feedbackVariant="scale-ripple"` 时:**
| prop | type | default | description |
| -------- | ---------------------------------------- | ------- | --------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | 缩放动画配置(`false` 为关闭) |
| `ripple` | `PressableFeedbackRippleAnimation` | - | 水波纹遮罩配置(`false` 为关闭) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在保留配置的同时控制动画状态(运行时切换) |
**当 `feedbackVariant="scale"` 时:**
| prop | type | default | description |
| ------- | ---------------------------------------- | ------- | --------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | 缩放动画配置(`false` 为关闭) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在保留配置的同时控制动画状态(运行时切换) |
**当 `feedbackVariant="none"` 时:**
仅接受字符串 `'disable-all'`。所有反馈效果均被禁用。
动画子类型(`PressableFeedbackScaleAnimation`、`PressableFeedbackHighlightAnimation`、`PressableFeedbackRippleAnimation`)详见 [PressableFeedback API 参考](./pressable-feedback#api-reference)。
### Button.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------- |
| `children` | `React.ReactNode` | - | 作为标签渲染的内容 |
| `className` | `string` | - | 额外 CSS 类 |
| `...TextProps` | `TextProps` | - | 支持全部标准 Text 属性 |
## Hooks
### useButton
用于读取 Button 上下文,返回尺寸、变体与禁用状态。
```tsx
import { useButton } from 'heroui-native';
const { size, variant, isDisabled } = useButton();
```
#### 返回值
| property | type | description |
| ------------ | --------------------------------------------------------------------------------------------- | ----------- |
| `size` | `'sm' \| 'md' \| 'lg'` | 按钮尺寸 |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'outline' \| 'ghost' \| 'danger' \| 'danger-soft'` | 按钮视觉变体 |
| `isDisabled` | `boolean` | 是否禁用 |
**说明:** 必须在 `Button` 内使用;在按钮上下文外调用会抛错。
# CloseButton 关闭按钮
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/close-button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(buttons)/close-button.mdx
> 用于关闭对话框、模态框或收起内容的按钮组件。
## 导入
```tsx
import { CloseButton } from 'heroui-native';
```
## 用法
### 基础用法
CloseButton 渲染带默认样式的关闭图标按钮。
```tsx
```
### 自定义图标颜色
通过 `iconProps` 自定义图标颜色。
```tsx
```
### 自定义图标尺寸
通过 `iconProps` 调整图标大小。
```tsx
```
### 自定义子节点
用自定义内容替换默认关闭图标。
```tsx
```
### 禁用态
禁用按钮以禁止交互。
```tsx
```
## 示例
```tsx
import { CloseButton, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export default function CloseButtonExample() {
const themeColorForeground = useThemeColor('foreground');
const themeColorDanger = useThemeColor('danger');
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/close-button.tsx)。
## API 参考
### CloseButton
CloseButton 继承 [Button](./button) 的全部属性。默认 `variant='tertiary'`、`size='sm'`、`isIconOnly=true`。
| prop | type | default | description |
| ----------- | ---------------------- | ------- | -------------- |
| `iconProps` | `CloseButtonIconProps` | - | 自定义关闭图标属性 |
| `children` | `React.ReactNode` | - | 自定义内容,替换默认关闭图标 |
`isDisabled`、`className`、`animation`、`feedbackVariant` 以及所有 Pressable 相关继承属性见 [Button API 参考](./button#api-reference)。
#### CloseButtonIconProps
| prop | type | default | description |
| ------- | -------- | ---------------------- | ----------- |
| `size` | `number` | `20` | 图标尺寸 |
| `color` | `string` | Uses theme muted color | 图标颜色 |
# LinkButton 链接按钮
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/link-button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(buttons)/link-button.mdx
> 幽灵样式按钮,无高亮按压反馈,适合行内链接式交互。
## 导入
```tsx
import { LinkButton } from 'heroui-native';
```
## 结构
```tsx
...
```
* **LinkButton**:根级可按压容器。内部渲染 `variant="ghost"` 的 `Button`,并强制关闭高亮反馈;使用者无法覆盖上述行为。
* **LinkButton.Label**:链接按钮文字,继承父级上下文中的尺寸与变体样式。
## 用法
### 基础用法
行内链接风格文字,响应按压。
```tsx
了解更多
```
### 尺寸
使用 `size` 控制文字尺寸。
```tsx
小
中
大
```
### 禁用状态
禁用后不可交互。
```tsx
已禁用的链接
```
### 自定义样式
在根与 `Label` 上使用 `className`。
```tsx
样式化链接
```
### 与正文混排
与普通文字混排,用于条款、政策或上下文导航。
```tsx
我同意
服务条款
与
隐私政策
```
## 示例
```tsx
import { Button, Checkbox, ControlField, LinkButton } from 'heroui-native';
import React from 'react';
import { Alert, View, Text } from 'react-native';
export default function LinkButtonExample() {
const [isAgreed, setIsAgreed] = React.useState(false);
const handleTermsPress = () => Alert.alert('条款', '跳转至服务条款');
const handlePrivacyPress = () =>
Alert.alert('隐私', '跳转至隐私政策');
return (
我同意
服务条款
与
隐私政策
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/link-button.tsx)。
## API 参考
### LinkButton
继承 [Button](./button#button) 的全部属性,**除 `variant` 外**(内部固定为 `ghost`)。
**内部强制行为:**
| override | value | description |
| ----------- | ------------ | -------------- |
| `variant` | `ghost` | 始终为 ghost,不可修改 |
| `highlight` | `false` | 高亮反馈关闭,不可修改 |
| `className` | `h-auto p-0` | 移除默认按钮高度与内边距 |
### LinkButton.Label
与 [Button.Label](./button#buttonlabel) 等价,属性相同。
# Menu 菜单
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/menu
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(collections)/menu.mdx
> 浮动上下文菜单,支持定位、选择分组与多种呈现方式。
## 导入
```tsx
import { Menu, SubMenu } from 'heroui-native';
```
## 结构
```tsx
```
* **Menu**:主容器,管理开闭状态与定位,并向子组件提供上下文。
* **Menu.Trigger**:可点击元素,用于切换菜单显隐。
* **Menu.Portal**:在 Portal 层渲染菜单内容,叠于其他内容之上。
* **Menu.Overlay**:可选背景遮罩,用于捕获外部点击并关闭菜单。
* **Menu.Content**:菜单内容容器;两种呈现:带定位与碰撞检测的浮动 Popover,或底部抽屉式 Bottom Sheet。
* **Menu.Close**:关闭按钮,按下后关闭菜单。
* **Menu.Label**:菜单内的非交互分区标题。
* **Menu.Group**:对菜单项分组,可选选择模式(无 / 单选 / 多选)。
* **Menu.Item**:可按压菜单项,带按压动画反馈;可独立使用或置于 Group 内参与选择。
* **Menu.ItemTitle**:菜单项主标题文本。
* **Menu.ItemDescription**:菜单项次要说明文本。
* **Menu.ItemIndicator**:菜单项选中指示(对勾或圆点)。
* **SubMenu**:子菜单根容器,管理展开/收起状态并为子级提供动画上下文。
* **SubMenu.Trigger**:可按压行,切换子菜单开闭;样式与普通菜单项一致。
* **SubMenu.TriggerIndicator**:动画 V 形图标(默认 chevron-right),随子菜单开闭旋转;放在 `SubMenu.Trigger` 内。
* **SubMenu.Content**:绝对定位容器,子菜单开闭时带动画高度变化;其内放置 `Menu.Item` 等。
## 用法
### 基础用法
Menu 通过复合部件组成浮动上下文菜单。
```tsx
```
### 带副标题
在标题旁为菜单项添加次要说明文字。
```tsx
```
### 单选
使用 `Menu.Group` 并设置 `selectionMode="single"`,同一时间仅允许选中一项。
```tsx
const [theme, setTheme] = useState>(() => new Set(['system']));
;
```
### 多选
使用 `selectionMode="multiple"` 可同时选中多项。
```tsx
const [textStyles, setTextStyles] = useState>(
() => new Set(['bold', 'italic'])
);
;
```
### 子菜单
在 `Menu.Content` 内嵌套 `SubMenu`,按压后展开更多项。
```tsx
```
### 危险变体
对破坏性操作在菜单项上使用 `variant="danger"`。
```tsx
```
### 方位
控制菜单相对触发器出现的位置。
```tsx
```
### Bottom Sheet 呈现
使用 `presentation="bottom-sheet"` 以底部抽屉形式展示菜单内容。
```tsx
```
### 圆点指示器
在 `Menu.ItemIndicator` 上使用 `variant="dot"` 显示实心圆点,而非对勾。
```tsx
```
## 示例
```tsx
import type { MenuKey } from 'heroui-native';
import { Button, Menu, Separator } from 'heroui-native';
import { useState } from 'react';
import { Text, View } from 'react-native';
export default function MenuExample() {
const [textStyles, setTextStyles] = useState>(
() => new Set(['bold', 'italic'])
);
const [alignment, setAlignment] = useState>(
() => new Set(['left'])
);
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/menu.tsx)。
## API 参考
### Menu
| prop | type | default | description |
| --------------- | ----------------------------- | ----------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 菜单内容 |
| `presentation` | `'popover' \| 'bottom-sheet'` | `'popover'` | 菜单内容的呈现方式 |
| `isOpen` | `boolean` | - | 受控开闭状态 |
| `isDefaultOpen` | `boolean` | - | 非受控:首次渲染时是否打开 |
| `isDisabled` | `boolean` | - | 是否禁用菜单 |
| `animation` | `MenuRootAnimation` | - | 菜单根级动画配置 |
| `onOpenChange` | `(open: boolean) => void` | - | 开闭状态变化时触发 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### MenuRootAnimation
菜单根组件的动画配置,可为:
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
### Menu.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 触发器内容 |
| `className` | `string` | - | 触发器额外 class |
| `isDisabled` | `boolean` | `false` | 是否禁用触发器 |
| `asChild` | `boolean` | - | 使用 Slot 模式将行为合并到单个子元素 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
### Menu.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------------- | ------- | --------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Portal 内容 |
| `className` | `string` | - | Portal 容器额外 class |
| `disableFullWindowOverlay` | `boolean` | `false` | 在 iOS 上使用普通 `View` 替代 `FullWindowOverlay` |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 控制 VoiceOver 是否将遮罩窗口视为模态容器。为 `true` 时焦点限制在遮罩内。仅 iOS。不稳定:可能随 `react-native-screens` 更新变化 |
| `hostName` | `string` | - | Portal 宿主元素的可选名称 |
| `forceMount` | `boolean` | - | 无论开闭状态是否强制挂载 Portal |
### Menu.Overlay
| prop | type | default | description |
| ----------------------- | ---------------------- | ------- | ----------------------------------- |
| `className` | `string` | - | 遮罩额外 class |
| `closeOnPress` | `boolean` | `true` | 点击遮罩时是否关闭菜单 |
| `animation` | `MenuOverlayAnimation` | - | 遮罩动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `forceMount` | `boolean` | - | 无论开闭是否强制挂载遮罩 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
#### MenuOverlayAnimation
菜单遮罩的动画配置,可为:
* `false` 或 `"disabled"`:关闭所有动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------ | ----------------------- | ----------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `opacity.entering.value` | `EntryOrExitLayoutType` | `FadeIn.duration(200)` | 遮罩进入动画 |
| `opacity.exiting.value` | `EntryOrExitLayoutType` | `FadeOut.duration(150)` | 遮罩退出动画 |
### Menu.Content(Popover)
当 `presentation="popover"` 时的属性。
| prop | type | default | description |
| ----------------- | ------------------------------------------------ | --------------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 菜单内容 |
| `presentation` | `'popover'` | - | 呈现方式(须与 Menu 根一致) |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | 相对触发器的弹出方位 |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | 沿对齐轴相对触发器的对齐方式 |
| `avoidCollisions` | `boolean` | `true` | 是否自动避让屏幕边缘 |
| `offset` | `number` | `9` | 与触发器的间距(像素) |
| `alignOffset` | `number` | `0` | 沿对齐轴的偏移(像素) |
| `width` | `'content-fit' \| 'trigger' \| 'full' \| number` | `'content-fit'` | 内容宽度策略 |
| `className` | `string` | - | 内容容器额外 class |
| `animation` | `MenuContentAnimation` | - | 内容动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### MenuContentAnimation
Popover 内容动画配置,可为:
* `false` 或 `"disabled"`:关闭所有动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ----------------------- | ------------------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `entering.value` | `EntryOrExitLayoutType` | Scale + fade entering animation | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | Scale + fade exiting animation | 自定义退出动画 |
### Menu.Content(Bottom Sheet)
当 `presentation="bottom-sheet"` 时的属性。继承 `@gorhom/bottom-sheet` 的 BottomSheet 属性。
| prop | type | default | description |
| --------------------------- | ---------------------------------------- | ------- | ------------------------------- |
| `children` | `React.ReactNode` | - | 底部抽屉内容 |
| `presentation` | `'bottom-sheet'` | - | 呈现方式(须与 Menu 根一致) |
| `className` | `string` | - | 底部抽屉额外 class |
| `backgroundClassName` | `string` | - | 背景额外 class |
| `handleIndicatorClassName` | `string` | - | 把手指示条额外 class |
| `contentContainerClassName` | `string` | - | 内容容器额外 class |
| `contentContainerProps` | `Omit` | - | 内容容器属性 |
| `animation` | `AnimationDisabled` | - | 设为 `false` 或 `"disabled"` 可关闭动画 |
| `...BottomSheetProps` | `Partial` | - | 支持 `@gorhom/bottom-sheet` 的全部属性 |
### Menu.Close
继承 `CloseButtonProps`。按下后自动关闭菜单。
| prop | type | default | description |
| ---------------- | ---------------------- | ------- | ---------------- |
| `iconProps` | `CloseButtonIconProps` | - | 自定义关闭图标属性 |
| `...ButtonProps` | `ButtonRootProps` | - | 支持 Button 根级全部属性 |
### Menu.Group
| prop | type | default | description |
| --------------------- | ---------------------------------- | -------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 分组内容(`Menu.Item` 等) |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | 分组内允许的选择类型 |
| `selectedKeys` | `Iterable` | - | 当前选中键(受控) |
| `defaultSelectedKeys` | `Iterable` | - | 初始选中键(非受控) |
| `isDisabled` | `boolean` | `false` | 是否禁用整个分组 |
| `disabledKeys` | `Iterable` | - | 应禁用的项键集合 |
| `shouldCloseOnSelect` | `boolean` | - | 选中项时是否关闭菜单 |
| `className` | `string` | - | 分组容器额外 class |
| `onSelectionChange` | `(keys: Set) => void` | - | 选中变化时回调 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Menu.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 标签文本内容 |
| `className` | `string` | - | 标签额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Menu.Item
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------- | ----------- | ----------------------------------- |
| `children` | `React.ReactNode \| ((props: MenuItemRenderProps) => ReactNode)` | - | 子元素或渲染函数 |
| `id` | `MenuKey` | - | 唯一标识;在 `Menu.Group` 内时必填 |
| `variant` | `'default' \| 'danger'` | `'default'` | 菜单项视觉变体 |
| `isDisabled` | `boolean` | `false` | 是否禁用该项 |
| `isSelected` | `boolean` | - | 独立项时的受控选中状态 |
| `shouldCloseOnSelect` | `boolean` | `true` | 按压该项是否关闭菜单 |
| `className` | `string` | - | 菜单项额外 class |
| `animation` | `MenuItemAnimation` | - | 按压反馈动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `onSelectedChange` | `(selected: boolean) => void` | - | 独立项选中状态变化时回调 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
#### MenuItemRenderProps
当 `children` 为函数时传入渲染函数的参数。
| prop | type | description |
| ------------ | ----------------------- | ----------- |
| `isSelected` | `boolean` | 当前项是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isPressed` | `SharedValue` | 是否处于按压中 |
| `variant` | `'default' \| 'danger'` | 项的视觉变体 |
#### MenuItemAnimation
菜单项按压反馈动画配置,可为:
* `false` 或 `"disabled"`:关闭项动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------------ | ------------------ | -------------------------- | ----------- |
| `scale.value` | `number` | `0.98` | 按压时的缩放值 |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | 缩放的动画配置 |
| `backgroundColor.value` | `string` | `useThemeColor('default')` | 按压时背景色 |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | 背景色过渡时间配置 |
### Menu.ItemTitle
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 标题文本内容 |
| `className` | `string` | - | 标题额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Menu.ItemDescription
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 说明文本内容 |
| `className` | `string` | - | 说明额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Menu.ItemIndicator
| prop | type | default | description |
| -------------- | ---------------------------- | ------------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 自定义指示内容;默认为对勾或圆点 |
| `variant` | `'checkmark' \| 'dot'` | `'checkmark'` | 指示器视觉变体 |
| `iconProps` | `MenuItemIndicatorIconProps` | - | 图标配置(对勾变体) |
| `forceMount` | `boolean` | `true` | 无论是否选中都强制挂载指示器 |
| `className` | `string` | - | 指示器额外 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### MenuItemIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | --------------- |
| `size` | `number` | `16` | 指示图标尺寸(圆点变体为 8) |
| `color` | `string` | `muted` | 指示图标颜色 |
### SubMenu
| prop | type | default | description |
| --------------- | ------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 子菜单内容(触发器、内容区等) |
| `isOpen` | `boolean` | - | 受控开闭状态 |
| `isDefaultOpen` | `boolean` | - | 非受控:首次渲染时是否打开 |
| `isDisabled` | `boolean` | `false` | 是否禁用子菜单 |
| `className` | `string` | - | 根容器额外 class |
| `animation` | `SubMenuRootAnimation` | - | 子菜单动画配置 |
| `onOpenChange` | `(open: boolean) => void` | - | 开闭状态变化时回调 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
##### SubMenuRootAnimation
SubMenu 根组件动画配置,可为:
* `"disable-all"`:关闭所有动画(含子级)
* `false` 或 `"disabled"`:仅关闭根级动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------------- | ----------------------- | ------------------------------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `rootContent.marginHorizontal` | `number` | `-16` | 子菜单打开时水平外边距 |
| `rootContent.marginVertical` | `number` | `-16` | 子菜单打开时垂直外边距 |
| `rootContent.paddingHorizontal` | `number` | `6` | 子菜单打开时水平内边距 |
| `rootContent.paddingTop` | `number` | `12` | 子菜单打开时顶部内边距 |
| `rootContent.springConfig` | `WithSpringConfig` | `{ damping: 100, stiffness: 950, mass: 3 }` | 展开/收起的弹簧配置 |
#### SubMenu.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 触发器内容(标题、图标、指示器等) |
| `textValue` | `string` | - | 读屏播报的无障碍文本 |
| `className` | `string` | - | 触发器额外 class |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `asChild` | `boolean` | - | 使用 Slot 模式合并到单个子元素 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
#### SubMenu.TriggerIndicator
子菜单开闭时旋转的指示图标,默认为向右 V 形(chevron-right)。
| prop | type | default | description |
| ----------------------- | ---------------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 自定义指示内容(替换默认 V 形) |
| `className` | `string` | - | 指示器额外 class |
| `iconProps` | `SubMenuTriggerIndicatorIconProps` | - | 默认 V 形的图标配置 |
| `animation` | `SubMenuTriggerIndicatorAnimation` | - | 指示器旋转动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
##### SubMenuTriggerIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ----------- |
| `size` | `number` | `14` | 指示图标尺寸 |
| `color` | `string` | `muted` | 指示图标颜色 |
##### SubMenuTriggerIndicatorAnimation
触发器指示旋转的动画配置,可为:
* `false` 或 `"disabled"`:关闭所有动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ------------------ |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `rotation.value` | `[number, number]` | `[0, 90]` | 旋转角度 \[收起, 展开],单位度 |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | 旋转弹簧配置 |
#### SubMenu.Content
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 子菜单项(`Menu.Item`、`Menu.Group` 等) |
| `className` | `string` | - | 内容容器额外 class |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
## Hooks
### useMenu
访问菜单根上下文,须在 `Menu` 内使用。
```tsx
import { useMenu } from 'heroui-native';
const { isOpen, onOpenChange, presentation, isDisabled } = useMenu();
```
#### 返回值
| property | type | description |
| -------------- | ----------------------------- | ----------- |
| `isOpen` | `boolean` | 菜单是否打开 |
| `onOpenChange` | `(open: boolean) => void` | 修改开闭状态的回调 |
| `presentation` | `'popover' \| 'bottom-sheet'` | 当前呈现模式 |
| `isDisabled` | `boolean \| undefined` | 是否禁用 |
| `nativeID` | `string` | 菜单实例唯一标识 |
### useMenuItem
访问菜单项上下文,须在 `Menu.Item` 内使用。
```tsx
import { useMenuItem } from 'heroui-native';
const { id, isSelected, isDisabled, variant } = useMenuItem();
```
#### 返回值
| property | type | description |
| ------------ | ----------------------- | ----------- |
| `id` | `MenuKey \| undefined` | 项标识 |
| `isSelected` | `boolean` | 是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
| `variant` | `'default' \| 'danger'` | 项的视觉变体 |
### useMenuAnimation
访问菜单动画上下文,须在 `Menu` 内使用。
```tsx
import { useMenuAnimation } from 'heroui-native';
const { progress, isDragging } = useMenuAnimation();
```
#### 返回值
| property | type | description |
| ------------ | ---------------------- | -------------------- |
| `progress` | `SharedValue` | 动画进度(0=空闲,1=打开,2=关闭) |
| `isDragging` | `SharedValue` | Bottom Sheet 是否正在被拖拽 |
### useSubMenu
访问子菜单上下文,须在 `SubMenu` 内使用。
```tsx
import { useSubMenu } from 'heroui-native';
const { isOpen, onOpenChange, isDisabled } = useSubMenu();
```
#### 返回值
| property | type | description |
| -------------- | ------------------------- | ----------- |
| `isOpen` | `boolean` | 子菜单是否打开 |
| `onOpenChange` | `(open: boolean) => void` | 修改开闭状态的回调 |
| `isDisabled` | `boolean` | 是否禁用 |
| `nativeID` | `string` | 子菜单实例唯一标识 |
## 特别说明
### 元素检查器(iOS)
Menu 在 iOS 上使用 `FullWindowOverlay`。开发时若需启用 React Native 元素检查器,请在 `Menu.Portal` 上设置 `disableFullWindowOverlay={true}`。代价是菜单将无法叠在原生模态之上。
### 原生模态(iOS)
当 `Menu` 位于以原生模态形式呈现的页面内时(`presentation: 'modal' | 'formSheet' | 'pageSheet'`),菜单内容可能会向上偏移渲染。在新架构(Fabric)中,`react-native-screens` 将 `RNSModalScreen` 标记为 Fabric 根节点,因此触发器的坐标是相对于模态原点上报的,而 `FullWindowOverlay`(菜单挂载点)锚定在 iOS 应用窗口上。可通过将 `safeAreaInsets.top` 加到 `offset` 来补偿:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# TagGroup 标签组
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/tag-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(collections)/tag-group.mdx
> 用于展示与管理可选标签的复合组件,支持可选移除。
## 导入
```tsx
import { TagGroup } from 'heroui-native';
```
## 结构
```tsx
...
```
* **TagGroup**:主容器,管理标签选中状态、禁用键与移除能力,并向子组件提供尺寸与变体上下文。
* **TagGroup.List**:渲染标签列表的容器,可渲染空状态。
* **TagGroup.Item**:组内单个标签。支持字符串子节点(自动包在 `TagGroup.ItemLabel`)、渲染函数子节点或自定义布局。
* **TagGroup.ItemLabel**:标签文字。提供字符串子节点时会自动渲染,也可显式使用。
* **TagGroup.ItemRemoveButton**:移除按钮;需要移除能力时需显式放置。仅当 `TagGroup` 传入 `onRemove` 时生效。
## 用法
### 基础用法
展示一个简单的可选标签组。
```tsx
新闻
旅行
游戏
```
### 单选模式
同一时间只能选中一个标签。
```tsx
新闻
旅行
游戏
```
### 多选模式
允许多个标签同时选中。
```tsx
新闻
旅行
游戏
```
### 受控选中
通过 `selectedKeys` 与 `onSelectionChange` 控制选中状态。
```tsx
const [selected, setSelected] = useState(new Set(['news']));
新闻
旅行
游戏
;
```
### 变体
为标签应用不同视觉变体。
```tsx
新闻
旅行
新闻
旅行
```
### 尺寸
控制组内所有标签的尺寸。
```tsx
新闻
新闻
新闻
```
### 带移除按钮
提供 `onRemove`,并在每个条目中放置 `TagGroup.ItemRemoveButton` 以显示移除按钮。
```tsx
const [tags, setTags] = useState([
{ id: 'news', name: '新闻' },
{ id: 'travel', name: '旅行' },
]);
const onRemove = (keys) => {
setTags((prev) => prev.filter((tag) => !keys.has(tag.id)));
};
{tags.map((tag) => (
{tag.name}
))}
;
```
### 渲染函数子节点
使用渲染函数访问 `isSelected`、`isDisabled` 以自定义布局。
```tsx
{({ isSelected }) => (
<>
新闻
>
)}
```
### 空状态
列表无标签时渲染自定义内容。
```tsx
(
暂无分类
)}
>
{tags.map((tag) => (
{tag.name}
))}
```
### 禁用标签
禁用单个标签或整个组。
```tsx
新闻
旅行
游戏
```
## 示例
```tsx
import { TagGroup, Label, Description, FieldError } from 'heroui-native';
import { useState, useMemo } from 'react';
import { View } from 'react-native';
export default function TagGroupExample() {
const [selected, setSelected] = useState(new Set());
const isInvalid = useMemo(
() => Array.from(selected).length === 0,
[selected]
);
return (
洗衣
健身房
停车
泳池
早餐
{`已选:${Array.from(selected).join('、')}`}
请至少选择一个分类
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/tag-group.tsx)。
## API 参考
### TagGroup
| prop | type | default | description |
| --------------------- | ---------------------------------- | ----------- | ------------------------------- |
| `children` | `React.ReactNode` | - | 渲染在标签组内的子节点 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 组内所有标签的尺寸 |
| `variant` | `'default' \| 'surface'` | `'default'` | 组内所有标签的视觉变体 |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | 允许的选中类型 |
| `selectedKeys` | `Iterable` | - | 当前选中键(受控) |
| `defaultSelectedKeys` | `Iterable` | - | 初始选中键(非受控) |
| `disabledKeys` | `Iterable` | - | 应被禁用的标签键 |
| `isDisabled` | `boolean` | `false` | 是否禁用整个标签组 |
| `isInvalid` | `boolean` | `false` | 是否处于非法状态 |
| `isRequired` | `boolean` | `false` | 是否必填 |
| `className` | `string` | - | 标签组容器的额外 class |
| `style` | `StyleProp` | - | 标签组容器的额外样式 |
| `animation` | `"disable-all" \| undefined` | - | 设为 `"disable-all"` 可禁用全部动画(含子级) |
| `onSelectionChange` | `(keys: Set) => void` | - | 选中变化时调用 |
| `onRemove` | `(keys: Set) => void` | - | 移除标签时调用 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### TagKey
`string | number` — 在 `TagGroup` 内标识标签的键类型。
#### Animation
使用 `animation="disable-all"` 可禁用全部动画(含子级)。省略或使用 `undefined` 为默认动画。
### TagGroup.List
| prop | type | default | description |
| ------------------ | ----------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 列表内的子节点 |
| `className` | `string` | - | 列表容器的额外 class |
| `style` | `StyleProp` | - | 列表容器的额外样式 |
| `renderEmptyState` | `() => React.ReactNode` | - | 无标签时调用的渲染函数 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### TagGroup.Item
| prop | type | default | description |
| ------------------- | ----------------------------------------------------------------------- | ------- | -------------------------------------- |
| `children` | `React.ReactNode \| ((renderProps: TagRenderProps) => React.ReactNode)` | - | 标签内容:字符串、元素,或接收 `TagRenderProps` 的渲染函数 |
| `id` | `TagKey` | - | 该标签的唯一标识 |
| `isDisabled` | `boolean` | - | 是否禁用该标签 |
| `className` | `string` | - | 标签的额外 class |
| `style` | `StyleProp` | - | 标签的额外样式 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部属性 |
#### TagRenderProps
| prop | type | description |
| ------------ | --------- | ----------------------------------- |
| `isSelected` | `boolean` | 当前是否选中 |
| `isDisabled` | `boolean` | 是否禁用(根级、`disabledKeys` 与条目属性合并后的结果) |
### TagGroup.ItemLabel
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 要渲染的文字内容 |
| `className` | `string` | - | 标签文字的额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### TagGroup.ItemRemoveButton
| prop | type | default | description |
| ------------------- | -------------------------- | ------- | --------------------------------- |
| `children` | `React.ReactNode` | - | 自定义图标或内容;省略时默认为关闭图标 |
| `className` | `string` | - | 移除按钮的额外 class |
| `iconProps` | `TagRemoveButtonIconProps` | - | 自定义默认关闭图标的属性;仅在没有 `children` 时生效 |
| `hitSlop` | `number` | `8` | 扩大可点击区域 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部属性 |
#### TagRemoveButtonIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ----------- |
| `size` | `number` | `12` | 图标尺寸 |
| `color` | `string` | - | 图标颜色 |
## Hooks
### useTagGroup
访问标签组根上下文,必须在 `TagGroup` 内使用。
```tsx
import { useTagGroup } from 'heroui-native';
const {
selectedKeys,
disabledKeys,
selectionMode,
onSelectionChange,
onRemove,
isDisabled,
isInvalid,
isRequired,
} = useTagGroup();
```
#### 返回值
| property | type | description |
| ------------------- | -------------------------------------------- | ----------- |
| `selectionMode` | `'none' \| 'single' \| 'multiple'` | 允许的选中类型 |
| `selectedKeys` | `Set` | 当前选中的标签键 |
| `disabledKeys` | `Set` | 被禁用的标签键 |
| `onSelectionChange` | `(keys: Set) => void` | 选中变化回调 |
| `onRemove` | `((keys: Set) => void) \| undefined` | 移除标签回调 |
| `isDisabled` | `boolean` | 是否禁用整个标签组 |
| `isInvalid` | `boolean` | 是否处于非法状态 |
| `isRequired` | `boolean` | 是否必填 |
### useTagGroupItem
访问单个标签上下文,必须在 `TagGroup.Item` 内使用。
```tsx
import { useTagGroupItem } from 'heroui-native';
const { id, isSelected, isDisabled, allowsRemoving } = useTagGroupItem();
```
#### 返回值
| property | type | description |
| ---------------- | --------- | ------------------------------------------ |
| `id` | `TagKey` | 该标签的唯一标识 |
| `isSelected` | `boolean` | 当前是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
| `allowsRemoving` | `boolean` | 是否允许移除(当 `TagGroup` 提供 `onRemove` 时为 true) |
# Slider 滑块
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/slider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(controls)/slider.mdx
> 在有限区间内通过拖拽选择单个值或区间的输入控件。
## 导入
```tsx
import { Slider } from 'heroui-native';
```
## 结构
```tsx
```
* **Slider**:主容器,管理滑块数值、方向,并为所有子组件提供上下文。支持单值与区间模式。
* **Slider.Output**:可选,显示当前值;支持渲染函数以自定义格式;默认显示格式化后的数值标签。
* **Slider.Track**:为 Fill 与 Thumb 提供尺寸的容器;上报布局尺寸用于位置计算;支持点击定位与渲染函数子节点(例如区间滑块的多拇指)。
* **Slider.Fill**:沿轨道交叉轴铺满的填充条;仅计算主轴位置与尺寸。
* **Slider.Thumb**:基于 react-native-gesture-handler 的可拖拽拇指;由 Track 布局在交叉轴居中;通过 react-native-reanimated 在按压时缩放。每个拇指具备 `role="slider"` 与完整 `accessibilityValue`。
## 用法
### 基础用法
Slider 通过复合部件组成可拖拽的数值输入。
```tsx
```
### 标签与输出
在数值输出旁显示标签。
```tsx
```
### 纵向
将 `orientation` 设为 `"vertical"` 以纵向渲染。
```tsx
```
### 区间滑块
将 `value`/`defaultValue` 设为数组,并在 `Slider.Track` 上使用渲染函数以渲染多个拇指。
```tsx
{({ state }) => (
<>
{state.values.map((_, i) => (
))}
>
)}
```
### 受控值
使用 `value` 与 `onChange` 进入受控模式。`onChangeEnd` 在拖拽结束或点击定位完成后触发。
```tsx
const [volume, setVolume] = useState(50);
save(v)}>
;
```
### 自定义样式
在拇指等子组件上使用 `className`、`classNames` 或 `styles` 自定义样式。
```tsx
```
### 禁用
禁用整个滑块以禁止交互。
```tsx
```
## 示例
```tsx
import { Label, Slider } from 'heroui-native';
import { useState } from 'react';
import { View, Text } from 'react-native';
export default function SliderExample() {
const [price, setPrice] = useState([200, 800]);
return (
{({ state }) => (
<>
{state.values.map((_, i) => (
))}
>
)}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/slider.tsx)。
## API 参考
### Slider
| prop | type | default | description |
| --------------- | ------------------------------------- | -------------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 滑块内部子元素 |
| `value` | `number \| number[]` | - | 当前值(受控) |
| `defaultValue` | `number \| number[]` | `0` | 默认值(非受控) |
| `minValue` | `number` | `0` | 最小值 |
| `maxValue` | `number` | `100` | 最大值 |
| `step` | `number` | `1` | 步进 |
| `formatOptions` | `Intl.NumberFormatOptions` | - | 数值标签的 `Intl` 格式化选项 |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | 方向 |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `className` | `string` | - | 额外 class |
| `animation` | `AnimationRootDisableAll` | - | 根级动画配置 |
| `onChange` | `(value: number \| number[]) => void` | - | 交互过程中数值变化时触发 |
| `onChangeEnd` | `(value: number \| number[]) => void` | - | 交互结束(拖放结束或点击定位)时触发 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### AnimationRootDisableAll
滑块根组件动画配置,可为:
* `"disable-all"`:关闭所有动画(含子级)
* `undefined`:使用默认动画
### Slider.Output
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode \| ((props: SliderRenderProps) => React.ReactNode)` | - | 自定义内容或接收滑块状态的渲染函数;默认显示格式化数值标签 |
| `className` | `string` | - | 额外 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### SliderRenderProps
| prop | type | description |
| ------------- | ------------------- | ----------- |
| `state` | `SliderState` | 当前滑块状态 |
| `orientation` | `SliderOrientation` | 滑块方向 |
| `isDisabled` | `boolean` | 是否禁用 |
#### SliderState
| prop | type | description |
| -------------------- | --------------------------- | --------------- |
| `values` | `number[]` | 按拇指索引的当前数值数组 |
| `getThumbValueLabel` | `(index: number) => string` | 返回指定拇指的格式化字符串标签 |
### Slider.Track
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode \| ((props: SliderRenderProps) => React.ReactNode)` | - | 子内容或接收滑块状态的渲染函数,用于动态渲染多拇指等 |
| `className` | `string` | - | 额外 class |
| `hitSlop` | `number` | `8` | 轨道周围扩展点击区域(像素) |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Slider.Fill
| prop | type | default | description |
| -------------- | ----------- | ------- | ------------------------------ |
| `className` | `string` | - | 额外 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Slider.Thumb
| prop | type | default | description |
| -------------- | ---------------------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 自定义拇指内容;默认可动画圆钮 |
| `index` | `number` | `0` | 该拇指在滑块中的索引 |
| `isDisabled` | `boolean` | - | 是否仅禁用该拇指 |
| `className` | `string` | - | 拇指容器额外 class |
| `classNames` | `ElementSlots` | - | 各拇指插槽的额外 class |
| `styles` | `Partial>` | - | 各拇指插槽的行内样式 |
| `hitSlop` | `number` | `12` | 拇指周围扩展点击区域(像素) |
| `animation` | `SliderThumbAnimation` | - | 拇指圆钮动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### ElementSlots\
| prop | type | description |
| ---------------- | -------- | --------------- |
| `thumbContainer` | `string` | 外层拇指容器自定义 class |
| `thumbKnob` | `string` | 内层圆钮自定义 class |
#### styles
| prop | type | description |
| ---------------- | ----------- | ----------- |
| `thumbContainer` | `ViewStyle` | 外层拇指容器样式 |
| `thumbKnob` | `ViewStyle` | 内层圆钮样式 |
#### SliderThumbAnimation
拇指缩放动画配置,可为:
* `false` 或 `"disabled"`:关闭拇指动画
* `undefined`:使用默认动画
* `object`:自定义缩放动画
| prop | type | default | description |
| -------------------- | ------------------ | -------------------------------------------- | -------------- |
| `scale.value` | `[number, number]` | `[1, 0.9]` | 缩放值 \[空闲, 拖拽中] |
| `scale.springConfig` | `WithSpringConfig` | `{ damping: 15, stiffness: 200, mass: 0.5 }` | 缩放弹簧配置 |
## Hooks
### useSlider
访问滑块上下文,须在 `Slider` 内使用。
```tsx
import { useSlider } from 'heroui-native';
const { values, orientation, isDisabled, getThumbValueLabel } = useSlider();
```
#### 返回值
| property | type | description |
| -------------------- | -------------------------------------------- | ---------------------- |
| `values` | `number[]` | 当前各拇指的数值 |
| `minValue` | `number` | 最小值 |
| `maxValue` | `number` | 最大值 |
| `step` | `number` | 步进 |
| `orientation` | `'horizontal' \| 'vertical'` | 当前方向 |
| `isDisabled` | `boolean` | 是否禁用 |
| `formatOptions` | `Intl.NumberFormatOptions \| undefined` | 标签数字格式化选项 |
| `getThumbPercent` | `(index: number) => number` | 返回指定拇指位置百分比(0–1) |
| `getThumbValueLabel` | `(index: number) => string` | 返回指定拇指的格式化标签 |
| `getThumbMinValue` | `(index: number) => number` | 返回指定拇指允许的最小值 |
| `getThumbMaxValue` | `(index: number) => number` | 返回指定拇指允许的最大值 |
| `updateValue` | `(index: number, newValue: number) => void` | 按索引更新拇指数值 |
| `isThumbDragging` | `(index: number) => boolean` | 指定拇指是否正在拖拽 |
| `setThumbDragging` | `(index: number, dragging: boolean) => void` | 设置拇指拖拽状态 |
| `trackSize` | `number` | 轨道布局宽度(横向)或高度(纵向),单位像素 |
| `thumbSize` | `number` | 已测量的拇指尺寸(主轴方向),单位像素 |
# Switch 开关
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/switch
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(controls)/switch.mdx
> 在开与关两种状态之间切换的拨动控件。
## 导入
```tsx
import { Switch } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **Switch**:主容器,处理开关状态与用户交互。未提供子节点时渲染默认拇指;根据选中状态对缩放(按压)与背景色做动画;整块可点以切换。
* **Switch.Thumb**:可选滑动拇指,在位置间移动,弹簧过渡。可放自定义内容(图标等)或通过样式与动画定制。
* **Switch.StartContent**:可选,显示在开关左侧;常用于关态时的图标或文字;在容器内绝对定位。
* **Switch.EndContent**:可选,显示在开关右侧;常用于开态时的图标或文字;在容器内绝对定位。
## 用法
### 基础用法
未提供子节点时,Switch 使用默认拇指渲染。
```tsx
```
### 自定义拇指
通过 Thumb 子组件替换默认拇指。
```tsx
...
```
### 首尾内容
在开关两侧添加图标或文字。
```tsx
...
...
```
### 渲染函数
根据开关状态用渲染函数动态渲染内容。
```tsx
{({ isSelected, isDisabled }) => (
<>
{({ isSelected }) => (isSelected ? : )}
>
)}
```
### 自定义动画
为开关根与拇指自定义动画。
```tsx
```
### 关闭动画
可整体关闭动画,或仅关闭部分组件的动画。
```tsx
{
/* 关闭所有动画(含子级) */
}
;
{
/* 仅关闭根动画,拇指仍可动画 */
}
;
```
## 示例
```tsx
import { Switch } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { View } from 'react-native';
import Animated, { ZoomIn } from 'react-native-reanimated';
export default function SwitchExample() {
const [darkMode, setDarkMode] = React.useState(false);
return (
{darkMode && (
)}
{!darkMode && (
)}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/switch.tsx)。
## API 参考
### Switch
| prop | type | default | description |
| --------------------------- | -------------------------------------------------------------------- | ----------- | ----------------------------- |
| `children` | `React.ReactNode \| ((props: SwitchRenderProps) => React.ReactNode)` | `undefined` | 开关内部内容或渲染函数 |
| `isSelected` | `boolean` | `undefined` | 是否选中 |
| `isDisabled` | `boolean` | `false` | 是否禁用、不可交互 |
| `className` | `string` | `undefined` | 根节点自定义 class |
| `animation` | `SwitchRootAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `onSelectedChange` | `(isSelected: boolean) => void` | - | 选中状态变化时回调 |
| `...AnimatedPressableProps` | `AnimatedProps` | - | 支持 Reanimated Pressable 的全部属性 |
#### SwitchRenderProps
| prop | type | description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
#### SwitchRootAnimation
Switch 根组件动画配置,可为:
* `false` 或 `"disabled"`:仅关闭根动画
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------------ | ---------------------------------------- | -------------------------------------------------------------- | --------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `scale.value` | `[number, number]` | `[1, 0.96]` | 缩放值 \[未按压, 按压] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | 动画时间配置 |
| `backgroundColor.value` | `[string, string]` | 使用主题色 | 背景色 \[未选中, 选中] |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) }` | 背景色过渡时间配置 |
### Switch.Thumb
| prop | type | default | description |
| ----------------------- | -------------------------------------------------------------------- | ----------- | ------------------------------ |
| `children` | `React.ReactNode \| ((props: SwitchRenderProps) => React.ReactNode)` | `undefined` | 拇指内内容或渲染函数 |
| `className` | `string` | `undefined` | 拇指元素自定义 class |
| `animation` | `SwitchThumbAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### SwitchThumbAnimation
`Switch.Thumb` 动画配置,可为:
* `false` 或 `"disabled"`:关闭全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------------ | ----------------------- | -------------------------------------------------------------- | ----------------- |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `left.value` | `number` | `2` | 距边缘偏移(未选中偏左,选中偏右) |
| `left.springConfig` | `WithSpringConfig` | `{ damping: 120, stiffness: 1600, mass: 2 }` | 拇指位置弹簧配置 |
| `backgroundColor.value` | `[string, string]` | `['white', theme accent-foreground color]` | 背景色 \[未选中, 选中] |
| `backgroundColor.timingConfig` | `WithTimingConfig` | `{ duration: 175, easing: Easing.bezier(0.25, 0.1, 0.25, 1) }` | 背景色过渡时间配置 |
### Switch.StartContent
| prop | type | default | description |
| -------------- | ----------------- | ----------- | ------------------------------ |
| `children` | `React.ReactNode` | `undefined` | 左侧区域内容 |
| `className` | `string` | `undefined` | 内容区域自定义 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Switch.EndContent
| prop | type | default | description |
| -------------- | ----------------- | ----------- | ------------------------------ |
| `children` | `React.ReactNode` | `undefined` | 右侧区域内容 |
| `className` | `string` | `undefined` | 内容区域自定义 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
## Hooks
### useSwitch
用于访问 Switch 上下文,便于在子组件中读取开关状态或封装自定义结构。
**返回值:**
| Property | Type | Description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
**示例:**
```tsx
import { useSwitch } from 'heroui-native';
function CustomSwitchContent() {
const { isSelected, isDisabled } = useSwitch();
return (
Status: {isSelected ? 'On' : 'Off'}
{isDisabled && Disabled}
);
}
// 用法
;
```
## 特别说明
### 边框样式
若需为开关根节点加边框,请使用 `outline` 相关样式而非 `border`,避免影响拇指位置的内部宽度计算:
```tsx
```
使用 `outline` 可在不改变内部宽度计算的前提下显示边框,确保拇指动画正确。
### 与 ControlField 组合
Switch 可与 ControlField 组合以共享按压态、扩大点击区域:
```tsx
import { Description, ControlField, Label } from 'heroui-native';
Receive push notifications
```
包在 ControlField 内时,整个容器上的按压都会驱动开关,触控目标更大、体验更好。
# Chip 标签
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/chip
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(data-display)/chip.mdx
> 以胶囊形态展示的小型元素。
## 导入
```tsx
import { Chip } from 'heroui-native';
```
## 结构
```tsx
...
```
* **Chip**:主容器,展示紧凑元素
* **Chip.Label**:芯片上的文字内容
## 用法
### 基础用法
Chip 以胶囊形态展示文字或自定义内容。
```tsx
基础芯片
```
### 尺寸
使用 `size` 控制尺寸。
```tsx
小
中
大
```
### 变体
使用 `variant` 切换视觉风格。
```tsx
主要
次要
第三级
柔和
```
### 颜色
使用 `color` 应用不同主题色。
```tsx
强调
默认
成功
警告
危险
```
### 搭配图标
通过复合组件在文字旁添加图标或自定义内容。
```tsx
精选
关闭
```
### 自定义样式
通过 `className` 或 `style` 传入样式。
```tsx
自定义
```
### 禁用全部动画
将 `animation` 设为 `"disable-all"` 可禁用自身及子级的全部动画。
```tsx
{
/* 禁用自身及子级的全部动画 */
}
无动画;
```
## 示例
```tsx
import { Chip } from 'heroui-native';
import { View, Text } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
export default function ChipExample() {
return (
小
中
大
主要
成功
高级
移除
自定义
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/chip.tsx)。
## API 参考
### Chip
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------- | ----------- | ---------------------------------- |
| `children` | `React.ReactNode` | - | 芯片内要渲染的内容 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 芯片尺寸 |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'soft'` | `'primary'` | 视觉变体 |
| `color` | `'accent' \| 'default' \| 'success' \| 'warning' \| 'danger'` | `'accent'` | 颜色主题 |
| `className` | `string` | - | 额外的 class |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| `...PressableProps` | `PressableProps` | - | 支持 `Pressable` 的全部属性 |
### Chip.Label
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 作为标签渲染的文字或内容 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
## Hooks
### useChip
访问 Chip 上下文,返回尺寸、变体与颜色。
```tsx
import { useChip } from 'heroui-native';
const { size, variant, color } = useChip();
```
#### 返回值
| property | type | description |
| --------- | ------------------------------------------------------------- | ----------- |
| `size` | `'sm' \| 'md' \| 'lg'` | 芯片尺寸 |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'soft'` | 视觉变体 |
| `color` | `'accent' \| 'default' \| 'success' \| 'warning' \| 'danger'` | 颜色主题 |
**说明:** 必须在 `Chip` 内使用;在上下文外调用将抛出错误。
# Alert 警告
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/alert
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(feedback)/alert.mdx
> 向用户展示重要消息与通知,并带有状态指示。
## 导入
```tsx
import { Alert } from 'heroui-native';
```
## 结构
```tsx
...
...
```
* **Alert**:根容器,`role="alert"`,按状态应用样式;通过原语上下文向子组件提供状态。
* **Alert.Indicator**:默认渲染与状态匹配的图标;可传入自定义子节点覆盖;支持 `iconProps` 调整尺寸与颜色。
* **Alert.Content**:包裹标题与描述,提供文字布局结构。
* **Alert.Title**:标题文字,颜色随状态变化;通过 `aria-labelledby` 与根关联。
* **Alert.Description**:正文,弱化色;通过 `aria-describedby` 与根关联。
## 用法
### 基础用法
使用复合子部件展示带图标、标题与描述的通知。
```tsx
新功能已上线
查看最新更新,包括深色模式支持与无障碍改进等。
```
### 状态变体
使用 `status` 控制图标与标题颜色。可选:`default`、`accent`、`success`、`warning`、`danger`。
```tsx
成功
...
计划维护
...
无法连接
...
```
### 仅标题
省略 `Alert.Description` 以得到紧凑单行提示。
```tsx
资料已成功更新
```
### 操作按钮
在内容旁放置按钮等额外元素。
```tsx
有可用更新
应用有新版本可用。
```
### 自定义指示器
向 `Alert.Indicator` 传入自定义子节点以替换默认状态图标。
```tsx
正在处理请求
请稍候,正在同步您的数据。
```
### 自定义样式
在根与各复合部件上使用 `className`。
```tsx
...
...
```
## 示例
```tsx
import { Alert, Button, CloseButton } from 'heroui-native';
import { View } from 'react-native';
export default function AlertExample() {
return (
有可用更新
应用有新版本。请刷新以获取最新功能与问题修复。
无法连接服务器
无法连接到服务器。请检查网络后重试。
资料已成功更新
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/alert.tsx)。
## API 参考
### Alert
| prop | type | default | description |
| -------------- | ------------------------------------------------------------- | ----------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 渲染在 Alert 内的子节点 |
| `status` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | 状态,控制图标与着色 |
| `id` | `string \| number` | - | 唯一标识;未提供时自动生成 |
| `className` | `string` | - | 额外的 class |
| `style` | `ViewStyle` | - | 根容器额外样式 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Alert.Indicator
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 自定义子节点,替代默认状态图标 |
| `className` | `string` | - | 额外的 class |
| `iconProps` | `AlertIconProps` | - | 传给默认状态图标的属性(尺寸、颜色等) |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### AlertIconProps
| prop | type | default | description |
| ------- | -------- | ------- | ----------- |
| `size` | `number` | `18` | 图标尺寸(像素) |
| `color` | `string` | 随状态着色 | 图标颜色字符串 |
### Alert.Content
| prop | type | default | description |
| -------------- | ----------------- | ------- | -------------------------------------------- |
| `children` | `React.ReactNode` | - | 子节点(通常为 `Alert.Title` 与 `Alert.Description`) |
| `className` | `string` | - | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Alert.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 标题文字 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### Alert.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 描述文字 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
## Hooks
### useAlert
访问 Alert 根上下文,必须在 `Alert` 内使用。
```tsx
import { useAlert } from 'heroui-native';
const { status, nativeID } = useAlert();
```
#### 返回值
| property | type | description |
| ---------- | ------------------------------------------------------------- | ----------------- |
| `status` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | 当前状态,供子组件样式使用 |
| `nativeID` | `string` | 无障碍与 ARIA 使用的唯一标识 |
# SkeletonGroup 骨架屏组
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/skeleton-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(feedback)/skeleton-group.mdx
> 协调多个骨架屏占位,并提供统一的动画与加载态控制。
## 导入
```tsx
import { SkeletonGroup } from 'heroui-native';
```
## 结构
```tsx
```
* **SkeletonGroup**:根容器,为所有骨架项提供统一控制
* **SkeletonGroup.Item**:单个骨架项,继承父级组的属性
## 用法
### 基础用法
SkeletonGroup 用共享的加载态与动画管理多个骨架项。
```tsx
```
### 容器布局
在组上使用 `className` 控制骨架项布局。
```tsx
```
### isSkeletonOnly(纯骨架布局)
当组内仅有骨架与布局用 `View`(加载完成后无真实内容)时,使用 `isSkeletonOnly`。`isLoading` 为 `false` 时整个组会隐藏,避免空容器影响布局。
```tsx
{/* 该 View 仅用于布局,无加载后内容 */}
```
### 动画变体
为组内所有项统一设置动画变体。
```tsx
```
### 自定义动画配置
为整组配置 shimmer 或 pulse。
```tsx
```
### 进出场动画
组出现或消失时应用 Reanimated 过渡。
```tsx
```
## 示例
```tsx
import { Card, SkeletonGroup, Avatar } from 'heroui-native';
import { useState } from 'react';
import { Text, View, Image } from 'react-native';
export default function SkeletonGroupExample() {
const [isLoading, setIsLoading] = useState(true);
return (
John Doe
@johndoe
This is the first line of the post content.
Second line with more interesting content to read.
Last line is shorter.
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/skeleton-group.tsx)。
## API 参考
### SkeletonGroup
| prop | type | default | description |
| ----------------------- | -------------------------------- | ----------- | -------------------------------------------- |
| `children` | `React.ReactNode` | - | `SkeletonGroup.Item` 与布局元素 |
| `isLoading` | `boolean` | `true` | 骨架项是否处于加载中 |
| `isSkeletonOnly` | `boolean` | `false` | 为 `true` 时,`isLoading` 为 `false` 隐藏整组(纯骨架布局) |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | `'shimmer'` | 组内所有项的动画变体 |
| `animation` | `SkeletonRootAnimation` | - | 动画配置 |
| `className` | `string` | - | 组容器额外 class |
| `style` | `StyleProp` | - | 组容器自定义样式 |
| `...Animated.ViewProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 全部属性 |
#### SkeletonRootAnimation
SkeletonGroup 动画配置,可为:
* `false` 或 `"disabled"`:仅关闭根动画
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------ | ---------------------------------------- | --------------------------- | --------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn` | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut` | 自定义退出动画 |
| `shimmer.duration` | `number` | `1500` | 动画时长(毫秒) |
| `shimmer.speed` | `number` | `1` | 速度倍率 |
| `shimmer.highlightColor` | `string` | - | 微光高光色 |
| `shimmer.easing` | `EasingFunction` | `Easing.linear` | 缓动函数 |
| `pulse.duration` | `number` | `1000` | 动画时长(毫秒) |
| `pulse.minOpacity` | `number` | `0.5` | 最小不透明度 |
| `pulse.maxOpacity` | `number` | `1` | 最大不透明度 |
| `pulse.easing` | `EasingFunction` | `Easing.inOut(Easing.ease)` | 缓动函数 |
### SkeletonGroup.Item
| prop | type | default | description |
| ----------------------- | -------------------------------- | ------- | ---------------------------------- |
| `children` | `React.ReactNode` | - | 非加载态显示的内容 |
| `isLoading` | `boolean` | 继承组 | 是否加载中(覆盖组设置) |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | 继承组 | 动画变体(覆盖组设置) |
| `animation` | `SkeletonRootAnimation` | 继承组 | 动画配置(覆盖组设置) |
| `className` | `string` | - | 单项额外 class |
| `...Animated.ViewProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 全部属性 |
## 特别说明
### 属性继承
`SkeletonGroup.Item` 从父级 `SkeletonGroup` 继承所有与动画相关的属性:
* `isLoading`
* `variant`
* `animation`
单项可通过自身属性覆盖继承值。
# Skeleton 骨架屏
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/skeleton
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(feedback)/skeleton.mdx
> 展示加载占位,支持微光(shimmer)或脉冲(pulse)等动画效果。
## 导入
```tsx
import { Skeleton } from 'heroui-native';
```
## 结构
Skeleton 为简单包装器,在内容加载时渲染占位,无子部件 API。
```tsx
```
## 用法
### 基础用法
在内容加载期间显示带动画的占位。
```tsx
```
### 与内容切换
加载中显示 Skeleton,就绪后显示真实内容。
```tsx
Loaded Content
```
### 动画变体
用 `variant` 控制动画样式。
```tsx
```
### 自定义微光
自定义时长、速度与高光色。
```tsx
...
```
### 自定义脉冲
配置脉冲时长与不透明度范围。
```tsx
...
```
### 形状变化
通过 `className` 控制占位形状。
```tsx
```
### 自定义进出场
Skeleton 出现或消失时使用自定义 Reanimated 过渡。
```tsx
...
```
## 示例
```tsx
import { Avatar, Card, Skeleton } from 'heroui-native';
import { useState } from 'react';
import { Image, Text, View } from 'react-native';
export default function SkeletonExample() {
const [isLoading, setIsLoading] = useState(true);
return (
John Doe
@johndoe
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/skeleton.tsx)。
## API 参考
### Skeleton
| prop | type | default | description |
| ----------------------- | -------------------------------- | ----------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 非加载态时显示的内容 |
| `isLoading` | `boolean` | `true` | 是否处于加载中 |
| `variant` | `'shimmer' \| 'pulse' \| 'none'` | `'shimmer'` | 动画变体 |
| `animation` | `SkeletonRootAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `className` | `string` | - | 额外样式 class |
| `...Animated.ViewProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### SkeletonRootAnimation
Skeleton 根动画配置,可为:
* `false` 或 `"disabled"`:仅关闭根动画
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------ | ---------------------------------------- | --------------------------- | --------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn` | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut` | 自定义退出动画 |
| `shimmer.duration` | `number` | `1500` | 动画时长(毫秒) |
| `shimmer.speed` | `number` | `1` | 速度倍率 |
| `shimmer.highlightColor` | `string` | - | 微光高光色 |
| `shimmer.easing` | `EasingFunction` | `Easing.linear` | 缓动函数 |
| `pulse.duration` | `number` | `1000` | 动画时长(毫秒) |
| `pulse.minOpacity` | `number` | `0.5` | 最小不透明度 |
| `pulse.maxOpacity` | `number` | `1` | 最大不透明度 |
| `pulse.easing` | `EasingFunction` | `Easing.inOut(Easing.ease)` | 缓动函数 |
# Spinner 加载指示器
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/spinner
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(feedback)/spinner.mdx
> 展示旋转加载动画。
## 导入
```tsx
import { Spinner } from 'heroui-native';
```
## 结构
```tsx
...
```
* **Spinner**:主容器,控制加载状态、尺寸与颜色。未提供子节点时渲染默认动画指示器。
* **Spinner.Indicator**:可选子组件,用于自定义动画配置与图标外观;可传入自定义子节点替换默认图标。
## 用法
### 基础用法
展示旋转加载指示器。
```tsx
```
### 尺寸
使用 `size` 控制大小。
```tsx
```
### 颜色
使用预设色或自定义颜色字符串。
```tsx
```
### 加载状态
使用 `isLoading` 控制是否显示。
```tsx
```
### 动画速度
在 `Indicator` 上使用 `animation` 自定义旋转速度。
```tsx
```
### 自定义图标
用自定义内容替换默认图标。
```tsx
const themeColorForeground = useThemeColor('foreground')
⏳
```
## 示例
```tsx
import { Spinner } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
export default function SpinnerExample() {
const [isLoading, setIsLoading] = React.useState(true);
return (
正在加载内容…
处理中…
setIsLoading(!isLoading)}>
{isLoading ? '点击停止' : '点击开始'}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/spinner.tsx)。
## API 参考
### Spinner
| prop | type | default | description |
| -------------- | ----------------------------------------------------------- | ----------- | ---------------------------- |
| `children` | `React.ReactNode` | `undefined` | 旋转器内部内容 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 尺寸 |
| `color` | `'default' \| 'success' \| 'warning' \| 'danger' \| string` | `'default'` | 颜色主题或自定义色值 |
| `isLoading` | `boolean` | `true` | 是否处于加载中(显示动画) |
| `className` | `string` | `undefined` | 自定义 class |
| `animation` | `SpinnerRootAnimation` | - | 根级动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### SpinnerRootAnimation
Spinner 根组件的动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根级动画
* `"disable-all"`:禁用全部动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------- | ----------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在自定义属性时禁用动画 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.out(Easing.ease))` | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(100)` | 自定义退出动画 |
### Spinner.Indicator
| prop | type | default | description |
| ----------------------- | --------------------------- | ----------- | ----------------------------------- |
| `children` | `React.ReactNode` | `undefined` | 指示器内部内容 |
| `iconProps` | `SpinnerIconProps` | `undefined` | 默认图标的属性 |
| `className` | `string` | `undefined` | 指示器元素的 class |
| `animation` | `SpinnerIndicatorAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### SpinnerIndicatorAnimation
`Spinner.Indicator` 的动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ----------------- | ---------------------------- | --------------- | ----------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `rotation.speed` | `number` | `1.1` | 旋转速度倍率 |
| `rotation.easing` | `WithTimingConfig['easing']` | `Easing.linear` | 动画缓动配置 |
### SpinnerIconProps
| prop | type | default | description |
| -------- | ------------------ | ---------------- | ----------- |
| `width` | `number \| string` | `24` | 图标宽度 |
| `height` | `number \| string` | `24` | 图标高度 |
| `color` | `string` | `'currentColor'` | 图标颜色 |
# Checkbox 复选框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/checkbox
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/checkbox.mdx
> 可在选中与未选中之间切换的可选控件。
## 导入
```tsx
import { Checkbox } from 'heroui-native';
```
## 结构
```tsx
...
```
* **Checkbox**:主容器,处理选中状态与用户交互。未提供子节点时渲染带动画对勾的默认指示器;自动识别是否在 Surface 上以便样式正确;支持可定制或关闭的按压缩放动画;子节点可为渲染函数以访问 `isSelected`、`isInvalid`、`isDisabled`。
* **Checkbox.Indicator**:可选对勾容器,选中时默认带滑动、缩放、透明度与圆角动画;无子节点时渲染带动画路径的 SVG 对勾;各动画可单独配置或关闭;子节点可为渲染函数以访问状态。
## 用法
### 基础用法
未提供子节点时,Checkbox 使用默认动画指示器,并自动检测是否在 Surface 背景上。
```tsx
```
### 自定义指示器
在 Indicator 中使用渲染函数,按状态显示/隐藏自定义图标。
```tsx
{({ isSelected }) => (isSelected ? : null)}
```
### 非法状态
使用 `isInvalid` 表示校验错误并应用危险色样式。
```tsx
```
### 自定义动画
为根与指示器分别自定义或关闭动画。
```tsx
{
/* 关闭所有动画(根与指示器) */
}
;
{
/* 仅关闭根动画 */
}
;
{
/* 仅关闭指示器动画 */
}
;
{
/* 自定义动画配置 */
}
;
```
## 示例
```tsx
import {
Checkbox,
Description,
ControlField,
Label,
Separator,
Surface,
} from "heroui-native";
import React from 'react';
import { View, Text } from 'react-native';
interface CheckboxFieldProps {
isSelected: boolean;
onSelectedChange: (value: boolean) => void;
title: string;
description: string;
}
const CheckboxField: React.FC = ({
isSelected,
onSelectedChange,
title,
description,
}) => {
return (
{description}
);
};
export default function BasicUsage() {
const [fields, setFields] = React.useState({
newsletter: true,
marketing: false,
terms: false,
});
const fieldConfigs: Record<
keyof typeof fields,
{ title: string; description: string }
> = {
newsletter: {
title: 'Subscribe to newsletter',
description: 'Get weekly updates about new features and tips',
},
marketing: {
title: 'Marketing communications',
description: 'Receive promotional emails and special offers',
},
terms: {
title: 'Accept terms and conditions',
description: 'Agree to our Terms of Service and Privacy Policy',
},
};
const handleFieldChange = (key: keyof typeof fields) => (value: boolean) => {
setFields((prev) => ({ ...prev, [key]: value }));
};
const fieldKeys = Object.keys(fields) as Array;
return (
{fieldKeys.map((key, index) => (
{index > 0 && }
))}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/checkbox.tsx)。
## API 参考
### Checkbox
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ----------------------------------------------- |
| `children` | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | 子元素或用于自定义的渲染函数 |
| `isSelected` | `boolean` | `undefined` | 是否选中 |
| `onSelectedChange` | `(isSelected: boolean) => void` | `undefined` | 选中状态变化时回调 |
| `isDisabled` | `boolean` | `false` | 是否禁用、不可交互 |
| `isInvalid` | `boolean` | `false` | 是否非法(危险色样式) |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | 视觉变体 |
| `hitSlop` | `number` | `6` | 可点区域扩展(hit slop) |
| `animation` | `CheckboxRootAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `className` | `string` | `undefined` | 额外 class |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 标准属性(`disabled` 除外) |
#### CheckboxRenderProps
| prop | type | description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 是否选中 |
| `isInvalid` | `boolean` | 是否非法 |
| `isDisabled` | `boolean` | 是否禁用 |
#### CheckboxRootAnimation
复选框根组件动画配置,可为:
* `false` 或 `"disabled"`:仅关闭根动画
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| -------------------- | ---------------------------------------- | ------------------- | --------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `scale.value` | `[number, number]` | `[1, 0.96]` | 缩放值 \[未按压, 按压] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 150 }` | 动画时间配置 |
### Checkbox.Indicator
| prop | type | default | description |
| ----------------------- | ---------------------------------------------------------------------- | ----------- | ---------------------------------- |
| `children` | `React.ReactNode \| ((props: CheckboxRenderProps) => React.ReactNode)` | `undefined` | 指示器内容或渲染函数 |
| `className` | `string` | `undefined` | 指示器额外 class |
| `iconProps` | `CheckboxIndicatorIconProps` | `undefined` | 默认动画对勾图标的自定义属性 |
| `animation` | `CheckboxIndicatorAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...AnimatedViewProps` | `AnimatedProps` | - | 支持 React Native Animated View 标准属性 |
#### CheckboxIndicatorIconProps
用于自定义默认动画对勾图标。
| prop | type | description |
| --------------- | -------- | ----------------------------- |
| `size` | `number` | 图标尺寸 |
| `strokeWidth` | `number` | 描边宽度 |
| `color` | `string` | 图标颜色(默认为主题 accent-foreground) |
| `enterDuration` | `number` | 出现动画时长(对勾显示) |
| `exitDuration` | `number` | 消失动画时长(对勾隐藏) |
#### CheckboxIndicatorAnimation
指示器动画配置,可为:
* `false` 或 `"disabled"`:关闭全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| --------------------------- | ----------------------- | ------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `opacity.value` | `[number, number]` | `[0, 1]` | 透明度 \[未选中, 选中] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | 透明度动画时间配置 |
| `borderRadius.value` | `[number, number]` | `[8, 0]` | 圆角 \[未选中, 选中] |
| `borderRadius.timingConfig` | `WithTimingConfig` | `{ duration: 50 }` | 圆角动画时间配置 |
| `translateX.value` | `[number, number]` | `[-4, 0]` | X 位移 \[未选中, 选中] |
| `translateX.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | 位移动画时间配置 |
| `scale.value` | `[number, number]` | `[0.8, 1]` | 缩放 \[未选中, 选中] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 100 }` | 缩放动画时间配置 |
## Hooks
### useCheckbox
在自定义或复合结构内访问复选框上下文。
```tsx
import { useCheckbox } from 'heroui-native';
const CustomIndicator = () => {
const { isSelected, isInvalid, isDisabled } = useCheckbox();
// ... your implementation
};
```
**返回值:** `UseCheckboxReturn`
| property | type | description |
| ------------------ | ---------------------------------------------- | --------------- |
| `isSelected` | `boolean \| undefined` | 是否选中 |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | 修改选中状态的回调函数 |
| `isDisabled` | `boolean` | 是否禁用、不可交互 |
| `isInvalid` | `boolean` | 是否非法(危险色) |
| `nativeID` | `string \| undefined` | 复选框元素 native ID |
**注意:** 必须在 `Checkbox` 内使用;在上下文外调用会抛错。
# ControlField 控件字段
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/control-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/control-field.mdx
> 将标签、说明(或其他内容)与控件(Switch 或 Checkbox)组合为单一可按压区域的字段组件。
## 导入
```tsx
import { ControlField } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **ControlField**:根容器,管理布局与状态向下传递
* **Label**:主标签(来自 [Label](./label))
* **Description**:辅助说明(来自 [Description](./description))
* **ControlField.Indicator**:表单控件容器([Switch](./switch)、[Checkbox](./checkbox)、[Radio](./radio))
* **FieldError**:校验错误展示(来自 [FieldError](./field-error))
## 用法
### 基础用法
ControlField 包裹控件,提供一致布局与状态管理。
```tsx
```
### 带说明
在标签下使用 Description 添加辅助说明。
```tsx
Receive push notifications about your account activity
```
### 带错误信息
使用 FieldError 展示校验错误。
```tsx
By checking this box, you agree to our Terms of Service
This field is required
```
### 禁用态
使用 `isDisabled` 控制是否可交互。
```tsx
This field is disabled
```
### 关闭所有动画
使用 `"disable-all"` 关闭根及子级全部动画。
```tsx
Description text
```
## 示例
```tsx
import {
Checkbox,
Description,
FieldError,
ControlField,
Label,
Switch,
} from 'heroui-native';
import React from 'react';
import { ScrollView, View } from 'react-native';
export default function ControlFieldExample() {
const [notifications, setNotifications] = React.useState(false);
const [terms, setTerms] = React.useState(false);
const [newsletter, setNewsletter] = React.useState(true);
return (
Receive push notifications about your account activity
By checking this box, you agree to our Terms of Service
This field is required
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/control-field.tsx)。
## API 参考
### ControlField
| prop | type | default | description |
| ----------------- | -------------------------------------------------------------------------- | ----------- | -------------------------------- |
| children | `React.ReactNode \| ((props: ControlFieldRenderProps) => React.ReactNode)` | - | 字段内部内容或渲染函数 |
| isSelected | `boolean` | `undefined` | 是否选中/勾选 |
| isDisabled | `boolean` | `false` | 是否禁用 |
| isInvalid | `boolean` | `false` | 是否非法 |
| isRequired | `boolean` | `false` | 是否必填 |
| className | `string` | - | 根元素自定义 class |
| onSelectedChange | `(isSelected: boolean) => void` | - | 选中状态变化时回调 |
| animation | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 时关闭根及子级全部动画 |
| ...PressableProps | `PressableProps` | - | 支持 React Native Pressable 全部属性 |
### Label
`Label` 会自动消费 ControlField 上下文中的表单状态(`isDisabled`、`isInvalid`)。
**说明**:完整属性见 [Label 组件文档](./label)。
### Description
`Description` 会自动消费 ControlField 上下文中的表单状态(`isDisabled`、`isInvalid`)。
**说明**:完整属性见 [Description 组件文档](./description)。
### ControlField.Indicator
| prop | type | default | description |
| ------------ | ----------------------------------- | ---------- | ----------------------------- |
| children | `React.ReactNode` | - | 要渲染的控件(Switch、Checkbox、Radio) |
| variant | `'checkbox' \| 'radio' \| 'switch'` | `'switch'` | 未提供 children 时渲染的内置变体 |
| className | `string` | - | 指示器容器自定义 class |
| ...ViewProps | `ViewProps` | - | 支持 React Native View 全部属性 |
**说明:** 提供 `children` 时,若子组件上尚未设置,会自动从 ControlField 上下文传入 `isSelected`、`onSelectedChange`、`isDisabled`、`isInvalid`。使用 `radio` 变体时,Radio 以独立模式渲染(不在 RadioGroup 内)。
### FieldError
`FieldError` 会自动消费 ControlField 上下文中的 `isInvalid`。
**说明**:完整属性见 [FieldError 组件文档](./field-error)。显隐由父级 ControlField 的 `isInvalid` 控制。
## Hooks
### useControlField
在 `ControlField` 内访问字段上下文(用于自定义子结构)。
**返回值:**
| property | type | description |
| ------------------ | ---------------------------------------------- | --------------------- |
| `isSelected` | `boolean \| undefined` | 是否选中/勾选 |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | 选中状态变化回调 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isInvalid` | `boolean` | 是否非法 |
| `isPressed` | `SharedValue` | Reanimated 共享值,表示按压状态 |
# Description 描述
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/description
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/description.mdx
> 用于为表单字段等提供无障碍说明与辅助文案的文本组件。
## 导入
```tsx
import { Description } from 'heroui-native';
```
## 结构
```tsx
...
```
* **Description**:以弱化样式展示说明或辅助文案;可通过 `nativeID` 与表单字段关联以支持无障碍。
## 用法
### 基础用法
使用默认弱化样式展示说明文字。
```tsx
This is a helpful description.
```
### 与表单字段组合
使用 `nativeID` 为表单字段提供可关联的说明。
```tsx
We'll never share your email with anyone else.
```
### 无障碍关联
通过 `nativeID` 与 `aria-describedby` 将说明与字段关联,便于读屏。
```tsx
Use at least 8 characters with a mix of letters, numbers, and symbols.
```
### 非法态时隐藏
使用 `hideOnInvalid` 控制字段非法时是否隐藏说明。
```tsx
We'll never share your email with anyone else.
Please enter a valid email address
```
当 `hideOnInvalid` 为 `true` 时,字段非法会隐藏说明;为 `false`(默认)时非法仍显示说明。
## 示例
```tsx
import { Description, Input, Label, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function DescriptionExample() {
return (
We'll never share your email with anyone else.
Use at least 8 characters with a mix of letters, numbers, and symbols.
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/description.tsx)。
## API 参考
### Description
| prop | type | default | description |
| --------------- | ----------------------------------- | ------- | ------------------------------------------- |
| `children` | `React.ReactNode` | - | 说明文本内容 |
| `className` | `string` | - | 额外 class |
| `nativeID` | `string` | - | 无障碍用 native ID,与 `aria-describedby` 等配合关联字段 |
| `isInvalid` | `boolean` | - | 是否处于非法态(可覆盖上下文) |
| `isDisabled` | `boolean` | - | 是否禁用态(可覆盖上下文) |
| `hideOnInvalid` | `boolean` | `false` | 非法时是否隐藏说明 |
| `animation` | `DescriptionAnimation \| undefined` | - | 说明显隐等过渡的动画配置 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
# FieldError 字段错误
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/field-error
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/field-error.mdx
> 展示校验错误信息,并带有平滑动画。
## 导入
```tsx
import { FieldError } from 'heroui-native';
```
## 结构
```tsx
错误信息内容
```
* **FieldError**:展示错误信息的主容器,带动画。字符串子节点会自动用 `Text` 包裹,也可传入自定义 React 节点。通过 `isInvalid` 控制显隐,并支持自定义进入/退出动画。
## 用法
### 基础用法
校验失败时展示错误信息。
```tsx
此字段为必填
```
### 受控显隐
使用 `isInvalid` 控制何时显示。放在 `TextField` 等表单项内时,会自动消费 form-item-state 上下文。
```tsx
const [isInvalid, setIsInvalid] = useState(false);
请输入有效的邮箱地址;
```
### 与表单字段配合
`FieldError` 会通过 form-item-state 上下文自动读取 `TextField` 的表单状态。
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
请输入有效的邮箱地址
```
### 自定义内容
子节点可传入自定义 React 组件而非纯字符串。
```tsx
输入无效
```
### 自定义动画
使用 `animation` 覆盖默认进入/退出动画。
```tsx
import { SlideInDown, SlideOutUp } from 'react-native-reanimated';
字段校验未通过
;
```
完全禁用动画:
```tsx
字段校验未通过
```
### 自定义样式
为容器与文字应用自定义样式。
```tsx
密码至少 8 位
```
### 自定义 Text 属性
当子节点为字符串时,可通过 `textProps` 传给内部 `Text`。
```tsx
这是一段可能很长需要截断的错误提示文案示例
```
## 示例
```tsx
import { Description, FieldError, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
export default function FieldErrorExample() {
const [email, setEmail] = useState('');
const [isInvalid, setIsInvalid] = useState(false);
const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
const handleBlur = () => {
setIsInvalid(email !== '' && !isValidEmail);
};
return (
我们将通过此邮箱与您联系
请输入有效的邮箱地址
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/field-error.tsx)。
## API 参考
### FieldError
| prop | type | default | description |
| ---------------------- | --------------------------------------------- | ----------- | ------------------------------------------------------ |
| `children` | `React.ReactNode` | `undefined` | 错误内容;字符串子节点会用 `Text` 包裹 |
| `isInvalid` | `boolean` | `undefined` | 控制是否显示(可覆盖 form-item-state)。置于 `TextField` 内时会自动消费表单状态 |
| `animation` | `FieldErrorRootAnimation` | - | 动画配置 |
| `className` | `string` | `undefined` | 容器的额外 class |
| `classNames` | `ElementSlots` | `undefined` | 各部分的额外 class |
| `styles` | `{ container?: ViewStyle; text?: TextStyle }` | `undefined` | 容器与文字的样式 |
| `textProps` | `TextProps` | `undefined` | 子节点为字符串时传给 `Text` 的额外属性 |
| `...AnimatedViewProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
**classNames:** `ElementSlots` 为各部分提供类型安全的 class。可用插槽:`container`、`text`。
#### `styles`
| prop | type | description |
| ----------- | ----------- | ----------- |
| `container` | `ViewStyle` | 容器样式 |
| `text` | `TextStyle` | 文字样式 |
#### FieldErrorRootAnimation
根组件动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根级动画
* `"disable-all"`:禁用全部动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ---------------------------------------- | ----------------------------------------------------------------------- | ----------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在自定义属性时禁用动画 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(150)`
`.easing(Easing.out(Easing.ease))` | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(100)`
`.easing(Easing.out(Easing.ease))` | 自定义退出动画 |
# InputGroup 输入框组
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/input-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/input-group.mdx
> 复合布局组件,将输入框与可选的前后缀装饰组合在一起。
## 导入
```tsx
import { InputGroup } from 'heroui-native';
```
## 结构
```tsx
...
...
```
* **InputGroup**:布局容器,包裹前缀、输入与后缀;提供动画设置与测量上下文,自动将前后缀宽度应用为 `Input` 的内边距。
* **InputGroup.Prefix**:绝对定位在输入左侧;测量宽度自动作为 `InputGroup.Input` 的 `paddingLeft`。
* **InputGroup.Suffix**:绝对定位在输入右侧;测量宽度自动作为 `InputGroup.Input` 的 `paddingRight`。
* **InputGroup.Input**:透传至 `Input`,支持全部 `Input` 属性,并自动获得前后缀对应的左右内边距。
## 用法
### 基础用法
通过复合子部件为输入框附加前后缀内容。
```tsx
...
...
```
### 仅前缀
在输入前附加图标等内容。
```tsx
```
### 仅后缀
在输入后附加图标等内容。
```tsx
```
### 装饰性与可交互
在 `Prefix`/`Suffix` 上设置 `isDecorative` 时,触摸事件会穿透到 `Input`,且对读屏隐藏装饰内容;包含可交互元素时不要设置。
```tsx
```
### 禁用状态
禁用整个输入组,状态会级联到子组件。
```tsx
```
### 与 TextField 组合
与 `TextField`、`Label`、`Description` 等组合成完整表单项。
```tsx
我们不会公开您的邮箱
```
## 示例
```tsx
import { InputGroup } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
export default function InputGroupExample() {
const [value, setValue] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
setIsPasswordVisible(!isPasswordVisible)}
hitSlop={20}
>
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input-group.tsx)。
## API 参考
### InputGroup
| prop | type | default | description |
| -------------- | ------------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 组内子节点 |
| `className` | `string` | - | 额外的 class |
| `isDisabled` | `boolean` | `false` | 是否禁用整个输入组及子级 |
| `animation` | `AnimationRootDisableAll` | - | 输入组动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### AnimationRootDisableAll
根组件动画配置,可为:
* `"disable-all"`:禁用全部动画(含子级,级联)
* `undefined`:使用默认动画
### InputGroup.Prefix
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 前缀区域内容 |
| `className` | `string` | - | 额外的 class |
| `isDecorative` | `boolean` | `false` | 为 true 时触摸穿透到 `Input`,且对读屏隐藏 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### InputGroup.Suffix
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 后缀区域内容 |
| `className` | `string` | - | 额外的 class |
| `isDecorative` | `boolean` | `false` | 为 true 时触摸穿透到 `Input`,且对读屏隐藏 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### InputGroup.Input
透传至 [Input](./input) 组件,支持其全部属性。
# InputOTP 一次性密码输入框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/input-otp
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/input-otp.mdx
> 用于输入一次性验证码(OTP)的输入组件,支持分格、动画与校验。
## 导入
```tsx
import { InputOTP } from 'heroui-native';
```
## 结构
```tsx
```
* **InputOTP**:根容器,管理 OTP 状态与文本变更,并为子组件提供上下文;处理焦点、校验与字符输入。
* **InputOTP.Group**:将多个格子编组;用于视觉分组(例如每 3 位一组)。
* **InputOTP.Slot**:单个字符格;`index` 须在 OTP 序列中唯一且与位置对应。未提供子节点时,默认渲染 `SlotPlaceholder`、`SlotValue` 与 `SlotCaret`。
* **InputOTP.SlotPlaceholder**:空位时显示的占位字符;`Slot` 无子节点时默认使用。
* **InputOTP.SlotValue**:显示已输入字符并带动画;`Slot` 无子节点时默认使用。
* **InputOTP.SlotCaret**:动画光标,指示当前输入位置;置于 `Slot` 内以显示正在输入的位置。
* **InputOTP.Separator**:分组之间的视觉分隔符。
## 用法
### 基础用法
创建 6 位 OTP,分两组并带分隔符。
```tsx
console.log(code)}>
```
### 四位 PIN
简单的 4 位数字 PIN。
```tsx
console.log(code)}>
```
### 自定义占位
为每个格子位置提供自定义占位字符。
```tsx
console.log(code)}
>
{({ slots }) => (
<>
{slots.map((slot) => (
))}
>
)}
```
### 受控值
以编程方式控制 OTP 值。
```tsx
const [value, setValue] = useState('');
;
```
### 校验态
非法时展示校验错误样式。
```tsx
```
### 输入模式(正则)
使用正则限制可输入字符。内置:`REGEXP_ONLY_DIGITS`(0–9)、`REGEXP_ONLY_CHARS`(a–z、A–Z)、`REGEXP_ONLY_DIGITS_AND_CHARS`(数字与字母)。
```tsx
import { InputOTP, REGEXP_ONLY_CHARS } from 'heroui-native';
console.log(code)}
>
;
```
### 自定义布局
在 `Group` 上使用渲染属性以自定义格子布局。
```tsx
{({ slots, isFocused, isInvalid }) => (
<>
{slots.map((slot) => (
))}
>
)}
```
### 在底部抽屉内
在 `BottomSheet` 中渲染 `InputOTP` 时,使用 `useBottomSheetAwareHandlers` 返回的 `onFocus` / `onBlur` 传给 `InputOTP`,以正确处理键盘避让。
```tsx
import { InputOTP, useBottomSheetAwareHandlers } from 'heroui-native';
const BottomSheetOTPInput = () => {
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
return (
);
};
```
## 示例
```tsx
import { InputOTP, Label, Description, type InputOTPRef } from 'heroui-native';
import { View } from 'react-native';
import { useRef } from 'react';
export default function InputOTPExample() {
const ref = useRef(null);
const onComplete = (code: string) => {
console.log('OTP completed:', code);
setTimeout(() => {
ref.current?.clear();
}, 1000);
};
return (
我们已向 a****@gmail.com 发送验证码
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input-otp.tsx)。
## API 参考
### InputOTP
| prop | type | default | description |
| -------------------------- | ----------------------------- | ----------- | --------------------------------------------------- |
| `maxLength` | `number` | - | OTP 最大长度(必填) |
| `value` | `string` | - | 受控值 |
| `defaultValue` | `string` | - | 非受控默认值 |
| `onChange` | `(value: string) => void` | - | 值变化回调 |
| `onComplete` | `(value: string) => void` | - | 所有格子填满时触发 |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `isInvalid` | `boolean` | `false` | 是否处于非法状态 |
| `pattern` | `string` | - | 允许字符的正则(如 `REGEXP_ONLY_DIGITS`、`REGEXP_ONLY_CHARS`) |
| `inputMode` | `TextInputProps['inputMode']` | `'numeric'` | 输入模式 |
| `placeholder` | `string` | - | 占位字符串;每个字符对应一个格子位置 |
| `placeholderTextColor` | `string` | - | 全部格子的占位文字颜色 |
| `placeholderTextClassName` | `string` | - | 全部格子的占位文字 class |
| `pasteTransformer` | `(text: string) => string` | - | 粘贴内容转换(如去掉连字符);默认会移除非匹配字符 |
| `onFocus` | `(e: FocusEvent) => void` | - | 聚焦回调 |
| `onBlur` | `(e: BlurEvent) => void` | - | 失焦回调 |
| `textInputProps` | `Omit` | - | 透传给底层 `TextInput` 的额外属性 |
| `children` | `React.ReactNode` | - | 子节点 |
| `className` | `string` | - | 根容器额外 class |
| `style` | `PressableProps['style']` | - | 传给容器 `Pressable` 的样式 |
| `isBottomSheetAware` | `boolean` | `true` | 在 `BottomSheet` 内是否自动处理键盘相关状态;设为 `false` 可关闭 |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级全部动画 |
### InputOTP.Group
| prop | type | default | description |
| -------------- | --------------------------------------------------------------------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode \| ((props: InputOTPGroupRenderProps) => React.ReactNode)` | - | 子节点,或接收格子数据与上下文的渲染函数 |
| `className` | `string` | - | 额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### InputOTPGroupRenderProps
| prop | type | description |
| ------------ | ------------ | ----------- |
| `slots` | `SlotData[]` | 每个位置的格子数据数组 |
| `maxLength` | `number` | OTP 最大长度 |
| `value` | `string` | 当前 OTP 值 |
| `isFocused` | `boolean` | 是否聚焦 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isInvalid` | `boolean` | 是否非法 |
### InputOTP.Slot
| prop | type | default | description |
| -------------- | ----------------- | ------- | --------------------------------------------------------- |
| `index` | `number` | - | 格子下标(必填),须为 `0` 到 `maxLength - 1` |
| `children` | `React.ReactNode` | - | 自定义格子内容;未提供时默认为 `SlotPlaceholder`、`SlotValue`、`SlotCaret` |
| `className` | `string` | - | 额外 class |
| `style` | `ViewStyle` | - | 额外样式 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### InputOTP.SlotPlaceholder
| prop | type | default | description |
| -------------- | ----------- | ------- | ------------------------------------ |
| `children` | `string` | - | 显示文本(可选,默认使用 `slot.placeholderChar`) |
| `className` | `string` | - | 额外 class |
| `style` | `TextStyle` | - | 额外样式 |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
### InputOTP.SlotValue
| prop | type | default | description |
| -------------- | ---------------------------- | ------- | ----------------------------- |
| `children` | `string` | - | 显示文本(可选,默认使用 `slot.char`) |
| `className` | `string` | - | 额外 class |
| `animation` | `InputOTPSlotValueAnimation` | - | `SlotValue` 动画配置 |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
#### InputOTPSlotValueAnimation
`InputOTP.SlotValue` 动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------ | ----------------------- | ---------------------------------------- | ------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `wrapper.entering` | `EntryOrExitLayoutType` | `FadeIn.duration(250)` | 包裹层进入动画 |
| `wrapper.exiting` | `EntryOrExitLayoutType` | `FadeOut.duration(100)` | 包裹层退出动画 |
| `text.entering` | `EntryOrExitLayoutType` | `FlipInXDown.duration(250).easing(...)` | 文本进入动画 |
| `text.exiting` | `EntryOrExitLayoutType` | `FlipOutXDown.duration(250).easing(...)` | 文本退出动画 |
### InputOTP.SlotCaret
| prop | type | default | description |
| ----------------------- | ---------------------------- | -------- | ---------------------------------------------- |
| `className` | `string` | - | 额外 class |
| `style` | `ViewStyle` | - | 额外样式 |
| `animation` | `InputOTPSlotCaretAnimation` | - | `SlotCaret` 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式;为 `false` 时移除内置动画样式,可自行实现 |
| `pointerEvents` | `'none' \| 'auto' \| ...` | `'none'` | 指针事件配置 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### InputOTPSlotCaretAnimation
`InputOTP.SlotCaret` 动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------ | ----------------------- | ---------- | ---------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `opacity.value` | `[number, number]` | `[0, 1]` | 透明度 \[最小, 最大] |
| `opacity.duration` | `number` | `500` | 动画时长(毫秒) |
| `height.value` | `[number, number]` | `[16, 18]` | 高度 \[最小, 最大](像素) |
| `height.duration` | `number` | `500` | 动画时长(毫秒) |
### InputOTP.Separator
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `className` | `string` | - | 额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
## Hooks
### useInputOTP
读取 `InputOTP` 根上下文,须在 `InputOTP` 内使用。
```tsx
const { value, maxLength, isFocused, isDisabled, isInvalid, slots } =
useInputOTP();
```
### useInputOTPSlot
读取 `InputOTP.Slot` 上下文,须在 `InputOTP.Slot` 内使用。
```tsx
const { slot, isActive, isCaretVisible } = useInputOTPSlot();
```
# Input 输入框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/input
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/input.mdx
> 单行文本输入,带样式边框与背景,用于收集用户输入。
## 导入
```tsx
import { Input } from 'heroui-native';
```
## 用法
### 基础用法
`Input` 可单独使用,也可放在 `TextField` 内。
```tsx
import { Input } from 'heroui-native';
;
```
### 与 TextField 组合
与 `TextField` 搭配形成完整表单结构。
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### 校验状态
非法时展示错误样式。
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
请输入有效邮箱
;
```
### 局部覆盖非法状态
在输入上覆盖上下文中的非法状态。
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
邮箱格式不正确
;
```
### 禁用状态
禁用输入,阻止交互。
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### 变体
按场景使用不同视觉变体。
```tsx
import { Input, Label, TextField } from 'heroui-native';
```
### 自定义样式
通过 `className` 自定义外观。
```tsx
import { Input, Label, TextField } from 'heroui-native';
;
```
### 在 Bottom Sheet 内
在 `BottomSheet` 中渲染 `Input` 时,使用 `useBottomSheetAwareHandlers` 连接键盘避让:将返回的 `onFocus`、`onBlur` 传给 `Input`。
```tsx
import { Input, TextField, useBottomSheetAwareHandlers } from 'heroui-native';
const BottomSheetTextInput = () => {
const { onFocus, onBlur } = useBottomSheetAwareHandlers();
return (
);
};
```
## 示例
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Description, Input, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export const TextInputContent = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
我们不会向他人公开您的邮箱。
setIsPasswordVisible(!isPasswordVisible)}
>
密码至少 6 位
);
};
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/input.tsx)。
## API 参考
### Input
| prop | type | default | description |
| ------------------------- | -------------------------- | --------------------- | ------------------------------------------ |
| isInvalid | `boolean` | `undefined` | 是否非法(可覆盖上下文) |
| variant | `'primary' \| 'secondary'` | `'primary'` | 输入框视觉变体 |
| className | `string` | - | 自定义 class |
| selectionColorClassName | `string` | `"accent-accent"` | 选中文本颜色的 class |
| placeholderColorClassName | `string` | `"field-placeholder"` | 占位符文字颜色的 class |
| isBottomSheetAware | `boolean` | `true` | 在 BottomSheet 内是否自动处理键盘相关逻辑;设为 `false` 可关闭 |
| animation | `AnimationRoot` | `undefined` | 输入框动画配置 |
| ...TextInputProps | `TextInputProps` | - | 支持 React Native `TextInput` 的全部属性 |
> **说明**:置于 `TextField` 内时,`Input` 会通过 form-item-state 上下文自动消费 `isDisabled`、`isInvalid` 等表单状态。
# Label 标签
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/label
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/label.mdx
> 用于标注表单字段等 UI 的文本组件,支持必填标记与校验状态。
## 导入
```tsx
import { Label } from 'heroui-native';
```
## 结构
```tsx
```
* **Label**:根容器,管理标签状态并为子组件提供上下文。传入字符串子节点时会自动渲染为 `Label.Text`。支持禁用、必填与非法状态。
* **Label.Text**:标签文字;在必填时自动显示星号,非法或禁用时改变颜色。
## 用法
### 基础用法
展示标签文字。字符串子节点会自动渲染为 `Label.Text`。
```tsx
```
### 与表单字段配合
将 `Label` 与表单字段组合以提供无障碍标签。
```tsx
```
### 必填字段
使用 `isRequired` 显示必填星号。
```tsx
```
### 非法状态
在校验失败时使用非法样式突出标签。
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
两次密码不一致
```
### 禁用状态
禁用标签以表示字段不可交互。
```tsx
```
### 自定义布局
使用复合子组件自定义标签结构。
```tsx
```
### 自定义样式
通过 `className`、`classNames` 或 `styles` 传入样式。
```tsx
```
## 示例
```tsx
import { FieldError, Label, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function LabelExample() {
return (
两次密码不一致
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/label.tsx)。
## API 参考
### Label
| prop | type | default | description |
| ------------------- | ---------------------------- | ----------- | --------------------------------------- |
| `children` | `React.ReactNode` | - | 标签内容。为字符串时自动渲染为 `Label.Text`;否则按原样渲染子节点 |
| `isRequired` | `boolean` | `false` | 是否必填;为 true 时显示星号 |
| `isInvalid` | `boolean` | `false` | 是否非法;为 true 时文字使用危险色 |
| `isDisabled` | `boolean` | `false` | 是否禁用;应用禁用样式并阻止交互 |
| `className` | `string` | - | 额外的 class |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部属性 |
### Label.Text
| prop | type | default | description |
| -------------- | ---------------------------------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 标签文字内容 |
| `className` | `string` | - | 文本元素的额外 class |
| `classNames` | `ElementSlots` | - | 标签各部分的额外 class |
| `styles` | `Partial>` | - | 标签各部分的样式 |
| `nativeID` | `string` | - | 无障碍用原生 ID,通过 aria-labelledby 关联表单控件 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
#### `ElementSlots`
| prop | type | description |
| ---------- | -------- | ----------- |
| `text` | `string` | 标签文字的 class |
| `asterisk` | `string` | 星号的 class |
#### `styles`
| prop | type | description |
| ---------- | ----------- | ----------- |
| `text` | `TextStyle` | 标签文字样式 |
| `asterisk` | `TextStyle` | 星号样式 |
# RadioGroup 单选框组
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/radio-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/radio-group.mdx
> 单选按钮组,同一时间只能选中一个选项。
## 导入
```tsx
import { RadioGroup } from 'heroui-native';
```
## 结构
```tsx
...
...
```
* **RadioGroup**:管理单选项选中状态的容器,支持横向与纵向布局。
* **RadioGroup.Item**:组内单个选项,必须放在 `RadioGroup` 内。处理选中状态;在仅提供文本子节点时会渲染默认 `` 指示器。支持渲染函数子节点以访问状态(`isSelected`、`isInvalid`、`isDisabled`)。
* **Label**:可选的可点击文字标签,与单选项关联以提升无障碍。请直接使用 [Label](./label) 组件。
* **Description**:标签下方的可选说明文字。请直接使用 [Description](./description) 组件。
* **Radio**:置于 `RadioGroup.Item` 内的 [Radio](./radio) 组件,用于渲染单选指示器。会自动识别 `RadioGroupItem` 上下文并从中获取 `isSelected`、`isDisabled`、`isInvalid` 与 `variant`。
* **Radio.Indicator**:单选圆环的可选容器;无子节点时渲染默认拇指样式,管理选中视觉。完整 API 见 [Radio](./radio)。
* **Radio.IndicatorThumb**:选中时显示的可选内圆,随选中状态缩放动画;可替换为自定义内容。见 [Radio](./radio)。
* **FieldError**:在组无效时显示的错误信息,带动画显示在组内容下方。请直接使用 [FieldError](./field-error) 组件。
## 用法
### 基础用法
使用简单字符串子节点时,会自动渲染标题与指示器。
```tsx
选项 1
选项 2
选项 3
```
### 带说明文字
在每个选项下方添加描述以补充上下文。
```tsx
import { RadioGroup, Radio, Label, Description } from 'heroui-native';
import { View } from 'react-native';
5–7 个工作日送达
2–3 个工作日送达
;
```
### 自定义指示器
使用 `Radio` 子组件将默认拇指替换为自定义内容。
```tsx
import { RadioGroup, Radio, Label } from 'heroui-native';
{({ isSelected }) => (
<>
{isSelected && (
)}
>
)}
;
```
### 使用渲染函数
在 `RadioGroup.Item` 上使用渲染函数以访问状态并自定义整块内容。
```tsx
import { RadioGroup, Radio, Label } from 'heroui-native';
{({ isSelected, isInvalid, isDisabled }) => (
<>
{isSelected && }
>
)}
;
```
### 显示错误信息
在单选组下方展示校验错误。
```tsx
import { RadioGroup, FieldError } from 'heroui-native';
function RadioGroupWithError() {
const [value, setValue] = React.useState(undefined);
return (
我同意条款
我不同意
请选择一项以继续
);
}
```
## 示例
```tsx
import {
Description,
Label,
Radio,
RadioGroup,
Separator,
Surface,
} from 'heroui-native';
import React from 'react';
import { View } from 'react-native';
export default function RadioGroupExample() {
const [selection, setSelection] = React.useState('desc1');
return (
5–7 个工作日送达
2–3 个工作日送达
下一个工作日送达
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/radio-group.tsx)。
## API 参考
### RadioGroup
| prop | type | default | description |
| --------------- | ---------------------------- | ----------- | --------------------------------------- |
| `children` | `React.ReactNode` | `undefined` | 单选组内容 |
| `value` | `string \| undefined` | `undefined` | 当前选中值 |
| `onValueChange` | `(val: string) => void` | `undefined` | 选中值变化时的回调 |
| `isDisabled` | `boolean` | `false` | 是否禁用整个单选组 |
| `isInvalid` | `boolean` | `false` | 组是否处于无效状态 |
| `variant` | `'primary' \| 'secondary'` | `undefined` | 单选组样式变体(子项未单独设置时继承) |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置。使用 `"disable-all"` 可关闭包含子节点在内的全部动画 |
| `className` | `string` | `undefined` | 自定义 className |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native View 属性 |
### RadioGroup.Item
| prop | type | default | description |
| ------------------- | ---------------------------------------------------------------------------- | ----------- | -------------------------------- |
| `children` | `React.ReactNode \| ((props: RadioGroupItemRenderProps) => React.ReactNode)` | `undefined` | 选项内容,或用于自定义项的渲染函数 |
| `value` | `string` | `undefined` | 该选项关联的值 |
| `isDisabled` | `boolean` | `false` | 是否禁用该选项 |
| `isInvalid` | `boolean` | `false` | 该选项是否无效 |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | 该选项的样式变体 |
| `hitSlop` | `number` | `6` | 可点击区域的热区扩展 |
| `className` | `string` | `undefined` | 自定义 className |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 Pressable 属性(不含 disabled) |
#### RadioGroupItemRenderProps
| prop | type | description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 该选项是否选中 |
| `isInvalid` | `boolean` | 该选项是否无效 |
| `isDisabled` | `boolean` | 该选项是否禁用 |
### Radio(位于 RadioGroup.Item 内)
`Radio` 放在 `RadioGroup.Item` 内用于渲染单选指示器。此时会自动识别 `RadioGroupItem` 上下文并从中获取 `isSelected`、`isDisabled`、`isInvalid` 与 `variant`,无需手动传参。
使用 `` 获得默认指示器,或组合 `Radio.Indicator` 与 `Radio.IndicatorThumb` 自定义样式。
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------------- | ----------- | -------------------------------- |
| `children` | `React.ReactNode \| ((props: RadioRenderProps) => React.ReactNode)` | `undefined` | 子元素或渲染函数以自定义单选 |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | 单选视觉变体 |
| `isSelected` | `boolean` | `undefined` | 是否选中 |
| `isDisabled` | `boolean` | `undefined` | 是否禁用且不可交互 |
| `isInvalid` | `boolean` | `false` | 是否无效(危险色) |
| `className` | `string` | `undefined` | 额外 CSS 类 |
| `animation` | `RadioRootAnimation` | - | 单选根动画配置 |
| `onSelectedChange` | `(isSelected: boolean) => void` | `undefined` | 选中状态变化时的回调 |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 Pressable 属性(不含 disabled) |
#### RadioRenderProps
| prop | type | description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 是否选中 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isInvalid` | `boolean` | 是否无效 |
#### RadioRootAnimation
单选根组件的动画配置,可为:
* `"disable-all"`:关闭包含子节点(Indicator、IndicatorThumb)在内的全部动画
* `undefined`:使用默认动画
### Radio.Indicator
| prop | type | default | description |
| ---------------------- | -------------------------- | ----------- | -------------------------------- |
| `children` | `React.ReactNode` | `undefined` | 指示器内容 |
| `className` | `string` | `undefined` | 指示器额外 CSS 类 |
| `...AnimatedViewProps` | `AnimatedProps` | - | 支持全部 Reanimated Animated.View 属性 |
### Radio.IndicatorThumb
| prop | type | default | description |
| ----------------------- | ------------------------------ | ----------- | -------------------------------- |
| `className` | `string` | `undefined` | 拇指区域额外 CSS 类 |
| `animation` | `RadioIndicatorThumbAnimation` | - | 拇指动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...AnimatedViewProps` | `AnimatedProps` | - | 支持全部 Reanimated Animated.View 属性 |
#### RadioIndicatorThumbAnimation
单选指示器拇指的动画配置,可为:
* `false` 或 `"disabled"`:关闭全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| -------------------- | ----------------------- | ---------------------------------------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `scale.value` | `[number, number]` | `[1.5, 1]` | 缩放值 \[未选中, 已选中] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 300, easing: Easing.out(Easing.ease) }` | 动画时间配置 |
**说明:** 标签、说明与错误信息请直接使用基础组件:
* 标签使用 [Label](../label/label.md)
* 说明使用 [Description](../description/description.md)
* 错误使用 [FieldError](../field-error/field-error.md)
## Hooks
### useRadioGroup
#### 返回值
| 属性 | 类型 | 描述 |
| --------------- | -------------------------- | -------- |
| `value` | `string \| undefined` | 当前选中值 |
| `isDisabled` | `boolean` | 单选组是否禁用 |
| `isInvalid` | `boolean` | 单选组是否无效 |
| `variant` | `'primary' \| 'secondary'` | 单选组样式变体 |
| `onValueChange` | `(value: string) => void` | 修改选中值的函数 |
### useRadioGroupItem
#### 返回值
| 属性 | 类型 | 描述 |
| ------------------ | ---------------------------------------------- | ------------------ |
| `isSelected` | `boolean` | 该选项是否选中 |
| `isDisabled` | `boolean \| undefined` | 该选项是否禁用 |
| `isInvalid` | `boolean \| undefined` | 该选项是否无效 |
| `variant` | `'primary' \| 'secondary' \| undefined` | 该选项的样式变体 |
| `onSelectedChange` | `((isSelected: boolean) => void) \| undefined` | 修改选中状态的回调(在组内选中该项) |
# SearchField 搜索框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/search-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/search-field.mdx
> 用于筛选与查询的复合搜索输入框。
## 导入
```tsx
import { SearchField } from 'heroui-native';
```
## 结构
```tsx
```
* **SearchField**:根容器,接收 `value` 与 `onChange` 并通过上下文下发;同时提供 `isDisabled`、`isInvalid`、`isRequired` 与动画设置。
* **SearchField.Group**:横向 `flex-row` 容器,排列搜索图标、输入与清除按钮。
* **SearchField.SearchIcon**:默认放大镜图标,绝对定位在输入左侧;可传入子节点替换默认图标。
* **SearchField.Input**:包装 `Input` 并应用搜索相关默认行为;自动从上下文读取 `value` 与 `onChangeText`。
* **SearchField.ClearButton**:清除输入的小图标按钮;值为空时自动隐藏;按下时调用上下文的 `onChange("")`。
## 用法
### 基础用法
在根上传入 `value` 与 `onChange`;`Input` 与 `ClearButton` 通过上下文消费。
```tsx
```
### 标签与说明
在 `Group` 外放置 `Label`、`Description` 以补充语义。
```tsx
按名称、分类或 SKU 搜索
```
### 校验
在根上使用 `isInvalid`、`isRequired`,并配合 `FieldError` 展示错误。
```tsx
至少输入 3 个字符再搜索
未找到结果,请尝试其他关键词。
```
### 自定义搜索图标
向 `SearchField.SearchIcon` 传入子节点替换默认图标。
```tsx
🔍
```
### 禁用
根上设置 `isDisabled`,通过上下文禁用子级。
```tsx
搜索暂时不可用
```
## 示例
```tsx
import { Description, Label, SearchField } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
export default function SearchFieldExample() {
const [searchValue, setSearchValue] = useState('');
return (
按名称、分类或 SKU 搜索
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/search-field.tsx)。
## API 参考
### SearchField
| prop | type | default | description |
| -------------- | ------------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 搜索字段内的子节点 |
| `value` | `string` | - | 受控搜索文本 |
| `onChange` | `(value: string) => void` | - | 文本变化回调 |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `isInvalid` | `boolean` | `false` | 是否非法 |
| `isRequired` | `boolean` | `false` | 是否必填 |
| `className` | `string` | - | 额外的 class |
| `animation` | `AnimationRootDisableAll` | - | 搜索字段动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### AnimationRootDisableAll
根动画配置,可为:
* `"disable-all"`:禁用全部动画(含子级,级联)
* `undefined`:使用默认动画
### SearchField.Group
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 组内子节点 |
| `className` | `string` | - | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### SearchField.SearchIcon
| prop | type | default | description |
| -------------- | -------------------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 自定义内容,替换默认搜索图标 |
| `className` | `string` | - | 额外的 class |
| `iconProps` | `SearchFieldSearchIconIconProps` | - | 自定义默认搜索图标(提供 `children` 时忽略) |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### SearchFieldSearchIconIconProps
| prop | type | default | description |
| ------- | -------- | ------------- | ----------- |
| `size` | `number` | `16` | 图标尺寸 |
| `color` | `string` | 主题的 `muted` 色 | 图标颜色 |
### SearchField.Input
在 [Input](./input) 属性之上带有搜索默认值(`placeholder="Search..."`、`returnKeyType="search"`、`accessibilityRole="search"`)。不提供 `value` 与 `onChangeText`,由 `SearchField` 上下文提供。
### SearchField.ClearButton
受控 `value` 为空字符串时自动隐藏;按下时调用上下文的 `onChange("")`。若额外传入 `onPress`,会在清空后调用。
| prop | type | default | description |
| ---------------- | --------------------------------- | ------- | ---------------- |
| `children` | `React.ReactNode` | - | 自定义内容,替换默认关闭图标 |
| `iconProps` | `SearchFieldClearButtonIconProps` | - | 清除按钮图标属性 |
| `className` | `string` | - | 额外的 class |
| `...ButtonProps` | `ButtonRootProps` | - | 支持 Button 根级全部属性 |
#### SearchFieldClearButtonIconProps
| prop | type | default | description |
| ------- | -------- | ------------- | ----------- |
| `size` | `number` | `14` | 图标尺寸 |
| `color` | `string` | 主题的 `muted` 色 | 图标颜色 |
## Hooks
### useSearchField
访问搜索字段上下文,必须在 `SearchField` 内使用。
```tsx
import { useSearchField } from 'heroui-native';
const { value, onChange, isDisabled, isInvalid, isRequired } = useSearchField();
```
#### 返回值
| property | type | description |
| ------------ | ---------------------------------------- | ----------- |
| `value` | `string \| undefined` | 当前受控搜索文本 |
| `onChange` | `((value: string) => void) \| undefined` | 更新搜索文本的回调 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isInvalid` | `boolean` | 是否非法 |
| `isRequired` | `boolean` | 是否必填 |
# Select 选择器
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/select
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/select.mdx
> 通过按钮触发,展示可选列表供用户选择。
## 导入
```tsx
import { Select } from 'heroui-native';
```
## 结构
```tsx
```
* **Select**:根容器,管理打开/关闭、选中值,并向子组件提供上下文。
* **Select.Trigger**:可点击的触发器,用于切换选择器显示。为任意子元素包裹按压处理,支持 `variant`(`'default'` 或 `'unstyled'`)。
* **Select.Value**:显示当前选中值或占位符;选中变化时自动更新,样式随是否有选中值变化。
* **Select.TriggerIndicator**:可选的视觉指示器,表示开/关状态;默认渲染带动画的双角标,随打开/关闭旋转。
* **Select.Portal**:在Portal层渲染内容,保证正确的层级与定位。
* **Select.Overlay**:可选的背景遮罩,可透明或半透明,用于捕获外部点击。
* **Select.Content**:内容容器,支持三种呈现:气泡(浮动定位)、底部抽屉或对话框。
* **Select.Close**:关闭按钮;可传入自定义子节点,否则使用默认关闭图标。
* **Select.ListLabel**:列表标题,使用预设排版样式。
* **Select.Item**:可选中的选项,处理选中态与按压。
* **Select.ItemLabel**:选项主文案。
* **Select.ItemDescription**:可选的说明文字,弱化样式。
* **Select.ItemIndicator**:选中项的可选指示器,默认渲染对勾图标。
## 用法
### 基础用法
Select 通过复合子组件构建下拉选择界面。
```tsx
```
### 在触发器显示选中值
使用 Value 在触发器区域展示当前选中项。
```tsx
```
### 气泡(Popover)呈现
使用 `presentation="popover"` 获得带自动定位的浮动内容。
```tsx
```
### 宽度控制
通过 `width` 控制内容宽度;仅对气泡呈现生效。
```tsx
{
/* 固定像素宽度 */
}
;
{
/* 与触发器同宽 */
}
;
{
/* 全宽(100%) */
}
;
{
/* 随内容自适应(默认) */
}
;
```
### 底部抽屉呈现
使用底部抽屉以获得更贴近移动端的体验。
```tsx
```
### 对话框呈现
使用对话框呈现居中模态式选择。
```tsx
```
### 自定义选项内容
通过自定义子节点与指示器定制选项外观。
```tsx
```
### 使用渲染函数
在 `Select.Item` 上使用渲染函数,根据选中态等自定义内容。
```tsx
```
### 带选项说明
为选项添加说明以提供更多上下文。
```tsx
```
### 带触发器指示器
添加视觉指示器表示开/关状态;打开/关闭时会旋转。
```tsx
```
### 无样式触发器与自定义组合
使用 `unstyled` 变体,将触发器与 Button 等组件组合。
```tsx
```
### 受控模式
以编程方式控制打开状态与选中值。
```tsx
const [value, setValue] = useState();
const [isOpen, setIsOpen] = useState(false);
;
```
## 示例
```tsx
import { Select, Separator } from 'heroui-native';
import React, { useState } from 'react';
type SelectOption = {
value: string;
label: string;
};
const US_STATES: SelectOption[] = [
{ value: 'CA', label: '加利福尼亚' },
{ value: 'NY', label: '纽约' },
{ value: 'TX', label: '得克萨斯' },
{ value: 'FL', label: '佛罗里达' },
];
export default function SelectExample() {
const [value, setValue] = useState();
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/select.tsx)。
## API 参考
### Select
| prop | type | default | description |
| --------------- | ------------------------------------------------- | ----------- | ----------------------------- |
| `children` | `ReactNode` | - | 选择器子内容 |
| `value` | `SelectOption \| SelectOption[]` | - | 当前选中值(受控) |
| `onValueChange` | `(value: SelectOption \| SelectOption[]) => void` | - | 选中值变化时的回调 |
| `defaultValue` | `SelectOption \| SelectOption[]` | - | 默认选中值(非受控) |
| `isOpen` | `boolean` | - | 是否打开(受控) |
| `isDefaultOpen` | `boolean` | - | 初始是否打开(非受控) |
| `onOpenChange` | `(isOpen: boolean) => void` | - | 打开状态变化时的回调 |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | `'popover'` | 内容呈现方式 |
| `animation` | `SelectRootAnimation` | - | 动画配置 |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### SelectRootAnimation
Select 根级动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根动画
* `"disable-all"`:禁用根与子级全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ------------------------------------------------ | ------- | ------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `entering.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | 打开时的动画配置 |
| `exiting.value` | `SpringAnimationConfig \| TimingAnimationConfig` | - | 关闭时的动画配置 |
#### SpringAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ------------------- |
| `type` | `'spring'` | - | 动画类型(须为 `'spring'`) |
| `config` | `WithSpringConfig` | - | Reanimated 弹簧动画配置 |
#### TimingAnimationConfig
| prop | type | default | description |
| -------- | ------------------ | ------- | ------------------- |
| `type` | `'timing'` | - | 动画类型(须为 `'timing'`) |
| `config` | `WithTimingConfig` | - | Reanimated 时长动画配置 |
### Select.Trigger
| prop | type | default | description |
| ------------------- | ------------------------- | ----------- | ---------------------------------------------- |
| `variant` | `'default' \| 'unstyled'` | `'default'` | 触发器变体:`'default'` 应用预设容器样式,`'unstyled'` 移除默认样式 |
| `children` | `ReactNode` | - | 触发器内容 |
| `className` | `string` | - | 触发器额外 class |
| `asChild` | `boolean` | `true` | 是否将子元素作为实际渲染节点 |
| `isDisabled` | `boolean` | - | 是否禁用触发器 |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 React Native `Pressable` 属性 |
### Select.Value
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `placeholder` | `string` | - | 未选中时的占位文案 |
| `className` | `string` | - | 值区域额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
**说明:** 值组件会根据是否有选中项自动应用不同文字颜色:
* 已选中:`text-foreground`
* 未选中(占位):`text-field-placeholder`
### Select.TriggerIndicator
| prop | type | default | description |
| ----------------------- | --------------------------------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 自定义指示器内容;默认带动画的双角标 |
| `className` | `string` | - | 指示器额外 class |
| `style` | `ViewStyle` | - | 指示器自定义样式 |
| `iconProps` | `SelectTriggerIndicatorIconProps` | - | 双角标图标配置 |
| `animation` | `SelectTriggerIndicatorAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
**说明:** 以下样式属性由动画占用,不能通过 `className` 设置:
* `transform`(尤其是 `rotate`)— 用于开/关旋转过渡
若要自定义,请使用 `animation`。若需完全关闭动画样式并自行用 `className` 或 `style` 控制,请设置 `isAnimatedStyleActive={false}`。
#### SelectTriggerIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------- | -------------- |
| `size` | `number` | `16` | 图标尺寸 |
| `color` | `string` | - | 图标颜色(默认同前景主题色) |
#### SelectTriggerIndicatorAnimation
`Select.TriggerIndicator` 的动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画(0° 到 -180° 旋转)
* `object`:自定义动画配置
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ------------------ |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `rotation.value` | `[number, number]` | `[0, -180]` | 旋转角度 \[关闭, 打开],单位度 |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | 旋转弹簧动画配置 |
### Select.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------- | ------- | -------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | Portal内容(必填) |
| `disableFullWindowOverlay` | `boolean` | `false` | 在 iOS 为 `true` 时使用 `View` 代替 `FullWindowOverlay`,便于元素检查器;遮罩将无法叠在原生模态之上 |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 控制 VoiceOver 是否将遮罩窗口视为模态容器。为 `true` 时,VoiceOver 仅聚焦遮罩内元素。仅 iOS;API 不稳定,可能随 react-native-screens 变更 |
| `className` | `string` | - | Portal容器额外 class |
| `hostName` | `string` | - | Portal宿主元素的可选名称 |
| `forceMount` | `boolean` | - | 是否强制挂载到 DOM |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### Select.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ----------------------------------- |
| `className` | `string` | - | 遮罩额外 class |
| `animation` | `SelectOverlayAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `closeOnPress` | `boolean` | `true` | 点击遮罩是否关闭选择器 |
| `forceMount` | `boolean` | - | 是否强制挂载到 DOM |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### SelectOverlayAnimation
`Select.Overlay` 的动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画(底部抽屉/对话框为基于进度的透明度;气泡为关键帧动画)
* `object`:自定义动画配置
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | ------------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | 透明度 \[空闲, 打开, 关闭](用于底部抽屉/对话框呈现) |
| `entering` | `EntryOrExitLayoutType` | - | 进入过渡自定义关键帧(用于气泡呈现) |
| `exiting` | `EntryOrExitLayoutType` | - | 退出过渡自定义关键帧(用于气泡呈现) |
### Select.Content(气泡呈现)
| prop | type | default | description |
| ----------------------- | ------------------------------------------------ | --------------- | ----------------------------------- |
| `children` | `ReactNode` | - | 选择器内容 |
| `width` | `number \| 'trigger' \| 'content-fit' \| 'full'` | `'content-fit'` | 内容宽度策略 |
| `presentation` | `'popover'` | `'popover'` | 呈现模式 |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | 相对触发器的方位 |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | 沿放置轴的对齐方式 |
| `avoidCollisions` | `boolean` | `true` | 靠近视口边缘时是否翻转 placement |
| `offset` | `number` | `8` | 与触发器的间距(像素) |
| `alignOffset` | `number` | `0` | 沿对齐轴的偏移(像素) |
| `className` | `string` | - | 内容容器额外 class |
| `animation` | `SelectContentPopoverAnimation` | - | 动画配置 |
| `forceMount` | `boolean` | - | 是否强制挂载到 DOM |
| `insets` | `Insets` | - | 定位时需遵守的屏幕边距 |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### SelectContentPopoverAnimation
`Select.Content`(气泡呈现)的动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认关键帧(按 placement 的 translateY/translateX、scale、opacity)
* `object`:自定义 `entering` 和/或 `exiting` 关键帧
| prop | type | default | description |
| ---------- | ----------------------- | ------- | ------------------------------------------------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `entering` | `EntryOrExitLayoutType` | - | 进入过渡关键帧(默认:按 placement 的 translateY/translateX、scale、opacity,200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | 退出过渡关键帧(默认:与进入镜像,150ms) |
### Select.Content(底部抽屉呈现)
| prop | type | default | description |
| --------------------------- | ------------------ | ------- | ------------------------------- |
| `children` | `ReactNode` | - | 底部抽屉内容 |
| `presentation` | `'bottom-sheet'` | - | 呈现模式 |
| `contentContainerClassName` | `string` | - | 内容容器额外 class |
| `...BottomSheetProps` | `BottomSheetProps` | - | 支持 `@gorhom/bottom-sheet` 的全部属性 |
### Select.Content(对话框呈现)
| prop | type | default | description |
| -------------- | -------------------------------------------------------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 对话框内容 |
| `presentation` | `'dialog'` | - | 呈现模式 |
| `classNames` | `{ wrapper?: string; content?: string }` | - | 包裹层与内容区额外 class |
| `styles` | `Partial>` | - | 对话框各部分的样式 |
| `animation` | `SelectContentAnimation` | - | 动画配置 |
| `isSwipeable` | `boolean` | `true` | 是否允许滑动关闭 |
| `forceMount` | `boolean` | - | 是否强制挂载到 DOM |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### `styles`
| prop | type | description |
| --------- | ----------- | ----------- |
| `wrapper` | `ViewStyle` | 外层包裹容器样式 |
| `content` | `ViewStyle` | 对话框内容区样式 |
#### SelectContentAnimation
`Select.Content`(对话框呈现)的动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认关键帧(scale 与 opacity)
* `object`:自定义 `entering` 和/或 `exiting` 关键帧
| prop | type | default | description |
| ---------- | ----------------------- | ------- | --------------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `entering` | `EntryOrExitLayoutType` | - | 进入过渡关键帧(默认:scale 与 opacity,200ms) |
| `exiting` | `EntryOrExitLayoutType` | - | 退出过渡关键帧(默认:与进入镜像,150ms) |
### Select.Close
`Select.Close` 继承 [CloseButton](./close-button),按下时自动关闭选择器。
### Select.ListLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 列表标题文案 |
| `className` | `string` | - | 列表标题额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
### Select.Item
| prop | type | default | description |
| ------------------- | ------------------------------------------------------------ | ------- | ---------------------------------- |
| `children` | `ReactNode \| ((props: SelectItemRenderProps) => ReactNode)` | - | 自定义选项内容;默认可为标签+指示器,或渲染函数 |
| `value` | `any` | - | 选项关联的值(必填) |
| `label` | `string` | - | 选项标签文案(必填) |
| `isDisabled` | `boolean` | `false` | 是否禁用该选项 |
| `className` | `string` | - | 选项额外 class |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 React Native `Pressable` 属性 |
#### SelectItemRenderProps
使用渲染函数作为 `children` 时,会传入以下属性:
| property | type | description |
| ------------ | --------- | ----------- |
| `isSelected` | `boolean` | 当前项是否选中 |
| `value` | `string` | 当前项的值 |
| `isDisabled` | `boolean` | 当前项是否禁用 |
### Select.ItemLabel
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `className` | `string` | - | 选项标签额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
### Select.ItemDescription
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 说明文案 |
| `className` | `string` | - | 说明额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
### Select.ItemIndicator
| prop | type | default | description |
| -------------- | ------------------------------ | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 自定义指示器;默认对勾图标 |
| `className` | `string` | - | 指示器额外 class |
| `iconProps` | `SelectItemIndicatorIconProps` | - | 对勾图标配置 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### SelectItemIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ---------------- | ----------- |
| `size` | `number` | `16` | 图标尺寸 |
| `color` | `string` | `--colors-muted` | 图标颜色 |
## Hooks
### useSelect
用于读取 Select 根上下文,返回状态与控制方法。
```tsx
import { useSelect } from 'heroui-native';
const {
isOpen,
onOpenChange,
isDefaultOpen,
isDisabled,
presentation,
triggerPosition,
setTriggerPosition,
contentLayout,
setContentLayout,
nativeID,
value,
onValueChange,
} = useSelect();
```
#### 返回值
| property | type | description |
| -------------------- | -------------------------------------------------- | ----------- |
| `isOpen` | `boolean` | 当前是否打开 |
| `onOpenChange` | `(open: boolean) => void` | 修改打开状态的回调 |
| `isDefaultOpen` | `boolean \| undefined` | 默认是否打开(非受控) |
| `isDisabled` | `boolean \| undefined` | 是否禁用 |
| `presentation` | `'popover' \| 'bottom-sheet' \| 'dialog'` | 内容呈现方式 |
| `triggerPosition` | `LayoutPosition \| null` | 触发器相对视口的位置 |
| `setTriggerPosition` | `(position: LayoutPosition \| null) => void` | 更新触发器位置 |
| `contentLayout` | `LayoutRectangle \| null` | 选择器内容的布局测量 |
| `setContentLayout` | `(layout: LayoutRectangle \| null) => void` | 更新内容布局测量 |
| `nativeID` | `string` | 当前实例的唯一标识 |
| `value` | `SelectOption \| SelectOption[]` | 当前选中项 |
| `onValueChange` | `(option: SelectOption \| SelectOption[]) => void` | 选中值变化时的回调 |
**说明:** 必须在 `Select` 内使用;在上下文外调用将抛错。
### useSelectAnimation
用于在自定义或复合子组件中读取 Select 动画相关共享值。
```tsx
import { useSelectAnimation } from 'heroui-native';
const { selectState, progress, isDragging, isGestureReleaseAnimationRunning } =
useSelectAnimation();
```
#### 返回值
| property | type | description |
| ---------------------------------- | ---------------------- | -------------------- |
| `progress` | `SharedValue` | 动画进度(0=空闲,1=打开,2=关闭) |
| `isDragging` | `SharedValue` | 内容是否正在被拖拽 |
| `isGestureReleaseAnimationRunning` | `SharedValue` | 手势释放后的动画是否正在运行 |
**说明:** 必须在 `Select` 内使用;在动画上下文外调用将抛错。
#### SelectOption
| property | type | description |
| -------- | -------- | ----------- |
| `value` | `string` | 选项值 |
| `label` | `string` | 选项显示标签 |
### useSelectItem
用于读取 Select Item 上下文,返回当前项的值与标签。
```tsx
import { useSelectItem } from 'heroui-native';
const { itemValue, label } = useSelectItem();
```
#### 返回值
| property | type | description |
| ----------- | -------- | ----------- |
| `itemValue` | `string` | 当前项的值 |
| `label` | `string` | 当前项的标签文案 |
## 特别说明
### 元素检查器(iOS)
Select 在 iOS 上使用 `FullWindowOverlay`。开发时若需启用 React Native 元素检查器,请在 `Select.Portal` 上设置 `disableFullWindowOverlay={true}`。代价是下拉层将无法叠在原生模态之上。
### 原生模态(iOS)
当 `Select` 位于以原生模态形式呈现的页面内时(`presentation: 'modal' | 'formSheet' | 'pageSheet'`),下拉层可能会向上偏移渲染。在新架构(Fabric)中,`react-native-screens` 将 `RNSModalScreen` 标记为 Fabric 根节点,因此触发器的坐标是相对于模态原点上报的,而 `FullWindowOverlay`(下拉层挂载点)锚定在 iOS 应用窗口上。可通过将 `safeAreaInsets.top` 加到 `offset` 来补偿:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# TextArea 多行文本框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/text-area
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/text-area.mdx
> 多行文本输入,带样式边框与背景,用于收集较长内容。
## 导入
```tsx
import { TextArea } from 'heroui-native';
```
## 用法
### 基础用法
`TextArea` 可单独使用,也可放在 `TextField` 内。
```tsx
import { TextArea } from 'heroui-native';
```
### 与 TextField 组合
与 `TextField` 搭配形成完整表单结构。
```tsx
import { Description, Label, TextArea, TextField } from 'heroui-native';
请尽量提供详细信息。
```
### 校验状态
非法时展示错误样式。
```tsx
import { FieldError, Label, TextArea, TextField } from 'heroui-native';
请输入有效留言
```
### 禁用状态
禁用后不可编辑。
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
### 变体
按场景使用不同视觉变体。
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
### 自定义样式
通过 `className` 自定义外观。
```tsx
import { Label, TextArea, TextField } from 'heroui-native';
```
## 示例
```tsx
import { Description, FieldError, Label, TextArea, TextField } from 'heroui-native';
import { View } from 'react-native';
export default function TextAreaExample() {
return (
默认变体,主要样式
用于表面上的次要变体
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text-area.tsx)。
## API 参考
`TextArea` 继承 [Input](./input) 的全部属性。区别仅为默认值:`multiline` 默认为 `true`,`textAlignVertical` 默认为 `'top'`。
# TextField 文本输入框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/text-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(forms)/text-field.mdx
> 带标签、说明与错误处理的文本输入,用于收集用户输入。
## 导入
```tsx
import { TextField } from 'heroui-native';
```
## 结构
```tsx
...
...
```
* **TextField**:根容器,负责间距与状态管理
* **Label**:标签,必填时可显示星号(见 [Label](./label))
* **Input**:带动画边框与背景的输入(见 [Input](./input))
* **Description**:辅助说明文字(见 [Description](./description))
* **FieldError**:校验错误展示(见 [FieldError](./field-error))
## 用法
### 基础用法
提供带标签与说明的完整输入结构。
```tsx
我们不会公开您的邮箱
```
### 必填
在必填字段的标签上显示星号。
```tsx
```
### 校验
非法时展示错误信息。
```tsx
import { FieldError, Input, Label, TextField } from 'heroui-native';
请输入有效邮箱
;
```
### 局部覆盖非法状态
为单个部件覆盖上下文的非法状态。
```tsx
import {
Description,
FieldError,
Input,
Label,
TextField,
} from 'heroui-native';
尽管输入非法,此说明仍可显示
邮箱格式不正确
;
```
### 多行输入
用于较长内容。
```tsx
最多 500 字
```
### 禁用状态
禁用整个字段。
```tsx
```
### 变体
按场景切换输入样式。
```tsx
```
### 自定义样式
通过 `className` 自定义输入外观。
```tsx
```
## 示例
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Description, Input, Label, TextField } from 'heroui-native';
import { useState } from 'react';
import { Pressable, View } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export const TextInputContent = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
return (
我们不会向他人公开您的邮箱。
setIsPasswordVisible(!isPasswordVisible)}
>
密码至少 6 位
);
};
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text-field.tsx)。
## API 参考
### TextField
| prop | type | default | description |
| ------------ | ---------------------------- | ----------- | ---------------------------------- |
| children | `React.ReactNode` | - | 文本字段内的子节点 |
| isDisabled | `boolean` | `false` | 是否禁用整个字段 |
| isInvalid | `boolean` | `false` | 是否处于非法状态 |
| isRequired | `boolean` | `false` | 是否必填(显示星号) |
| className | `string` | - | 根元素自定义 class |
| animation | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| ...ViewProps | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
> **说明**:`Label`、`Input`、`Description`、`FieldError` 的详细 API 见各自文档:
>
> * [Label](./label)
> * [Input](./input)
> * [Description](./description)
> * [FieldError](./field-error)
>
> 这些组件会通过 form-item-state 上下文自动消费 `TextField` 的表单状态。
## Hooks
### useTextField
访问 `TextField` 上下文,必须在 `TextField` 内使用。
```tsx
import { TextField, useTextField } from 'heroui-native';
function CustomComponent() {
const { isDisabled, isInvalid, isRequired } = useTextField();
// 使用上下文值…
}
```
#### 返回值
| property | type | description |
| ---------- | --------- | ----------- |
| isDisabled | `boolean` | 是否禁用整个字段 |
| isInvalid | `boolean` | 是否处于非法状态 |
| isRequired | `boolean` | 是否必填 |
# Card 卡片
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/card
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(layout)/card.mdx
> 卡片容器,提供灵活分区以结构化展示内容。
## 导入
```tsx
import { Card } from 'heroui-native';
```
## 结构
```tsx
...
...
...
...
```
* **Card**:主容器,继承 `Surface`;提供可配置的表面变体与整体布局。
* **Card.Header**:顶部区域,可放图标、徽章等。
* **Card.Body**:主内容区,`flex-1` 填充 `Header` 与 `Footer` 之间的空间。
* **Card.Title**:标题,前景色与中等字重。
* **Card.Description**:描述,弱化色与较小字号。
* **Card.Footer**:底部区域,可放按钮等操作。
## 用法
### 基础用法
使用内置分区组织内容。
```tsx
...
```
### 标题与描述
组合标题与描述以结构化展示文字。
```tsx
...
...
```
### 页头与页脚
增加顶部与底部区域放置图标、徽章或操作。
```tsx
...
...
...
```
### 变体
通过变体控制卡片背景外观。
```tsx
...
...
...
...
```
### 横向布局
使用 `flex-row` 等样式创建横向卡片。
```tsx
```
### 背景图
使用绝对定位图片作为背景。
```tsx
...
```
## 示例
```tsx
import { Button, Card } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';
export default function CardExample() {
return (
¥450
客厅沙发 • 2025 系列
这款沙发适合现代热带风、巴洛克灵感等空间。
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/card.tsx)。
## API 参考
### Card
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | ---------------------------------- |
| `children` | `React.ReactNode` | - | 卡片内内容 |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | 卡片表面视觉变体 |
| `className` | `string` | - | 额外的 class |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Card.Header
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 页头内子节点 |
| `className` | `string` | - | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Card.Body
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 主内容区子节点 |
| `className` | `string` | - | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Card.Footer
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 页脚内子节点 |
| `className` | `string` | - | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Card.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 标题文字 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### Card.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 描述文字 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
# Separator 分隔符
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/separator
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(layout)/separator.mdx
> 用于在视觉上分隔内容的简单线条。
## 导入
```tsx
import { Separator } from "heroui-native";
```
## 结构
```tsx
```
* **Separator**:简单的分隔线组件,可水平或垂直排列,并支持自定义粗细与变体样式。
## 用法
### 基础用法
在内容区块之间创建视觉分隔。
```tsx
```
### 方向
使用 `orientation` 控制分隔线方向。
```tsx
水平分隔线
下方内容
左侧
右侧
```
### 变体
在细线与粗线之间选择,以强调程度区分。
```tsx
```
### 自定义粗细
使用数值精确控制线条粗细(像素)。
```tsx
```
## 示例
```tsx
import { Separator, Surface } from 'heroui-native';
import { Text, View } from 'react-native';
export default function SeparatorExample() {
return (
HeroUI Native
现代化的 React Native 组件库。
组件
主题
示例
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/separator.tsx)。
## API 参考
### Separator
| prop | type | default | description |
| -------------- | ---------------------------- | -------------- | ---------------------------- |
| `variant` | `'thin' \| 'thick'` | `'thin'` | 分隔线样式变体 |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | 分隔线方向 |
| `thickness` | `number` | `undefined` | 自定义粗细(像素);水平时控制高度,垂直时控制宽度 |
| `className` | `string` | `undefined` | 额外的 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
# Surface 表面
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/surface
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(layout)/surface.mdx
> 提供层级与背景样式的容器组件。
## 导入
```tsx
import { Surface } from 'heroui-native';
```
## 结构
Surface 是提供层级与背景样式的容器,可包裹子内容,并通过变体与样式属性定制外观。
```tsx
...
```
* **Surface**:主容器,通过变体提供一致的内边距、背景与层级感。
## 用法
### 基础用法
Surface 用于创建具有一致内边距与样式的容器。
```tsx
...
```
### 变体
通过不同层级控制视觉外观。
```tsx
...
...
...
```
### 嵌套 Surface
使用不同变体嵌套,形成视觉层级。
```tsx
...
...
...
```
### 自定义样式
通过 `className` 或 `style` 传入自定义样式。
```tsx
...
...
```
### 禁用全部动画
将 `animation` 设为 `"disable-all"` 可禁用自身及子级的全部动画。
```tsx
{
/* 禁用自身及子级的全部动画 */
}
无动画;
```
## 示例
```tsx
import { Surface } from 'heroui-native';
import { Text, View } from 'react-native';
export default function SurfaceExample() {
return (
表面内容
默认表面变体,使用 bg-surface 样式。
表面内容
次要表面变体,使用 bg-surface-secondary 样式。
表面内容
第三级表面变体,使用 bg-surface-tertiary 样式。
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/surface.tsx)。
## API 参考
### Surface
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | ---------------------------------- |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | 视觉变体,控制背景色与边框 |
| `children` | `React.ReactNode` | - | 渲染在表面内的内容 |
| `className` | `string` | - | 额外的 class |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| `asChild` | `boolean` | `false` | 是否以子元素方式渲染 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
# Avatar 头像
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/avatar
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(media)/avatar.mdx
> 展示用户头像,支持图片、文字首字母或回退图标。
## 导入
```tsx
import { Avatar } from 'heroui-native';
```
## 结构
```tsx
```
* **Avatar**:主容器,管理头像展示状态,向子组件提供尺寸与颜色上下文;可通过动画配置统一控制子级动画。
* **Avatar.Image**:可选图片组件,展示头像;自动处理加载与错误,并以不透明度淡入。
* **Avatar.Fallback**:图片加载失败或不可用时显示;无子节点时显示默认人像图标;支持可配置的进入动画与延迟。
## 用法
### 基础用法
未提供图片或文字时,显示默认人像图标。
```tsx
```
### 使用图片
展示头像图片并自动处理回退。
```tsx
JD
```
### 文字首字母
使用首字母作为头像内容。
```tsx
AB
```
### 自定义图标
以自定义图标作为回退内容。
```tsx
```
### 尺寸
使用 `size` 控制头像大小。
```tsx
```
### 变体
使用 `variant` 切换视觉风格。
```tsx
DF
SF
```
### 颜色
应用不同颜色变体。
```tsx
DF
AC
SC
WR
DG
```
### 延迟显示回退
延迟显示回退,避免图片加载时的闪烁。
```tsx
NA
```
### 自定义图片组件
配合 `asChild` 使用自定义图片组件。
```tsx
import { Image } from 'expo-image';
EI
;
```
### 动画控制
在 Avatar 不同层级控制动画。
#### 禁用全部动画
在根组件禁用自身及子级的全部动画:
```tsx
JD
```
#### 自定义图片动画
自定义图片不透明度动画:
```tsx
JD
```
#### 自定义回退动画
自定义回退进入动画:
```tsx
import { FadeInDown } from 'react-native-reanimated';
JD
;
```
#### 单独禁用动画
对指定子组件禁用动画:
```tsx
JD
```
## 示例
```tsx
import { Avatar } from 'heroui-native';
import { View } from 'react-native';
export default function AvatarExample() {
const users = [
{ id: 1, image: 'https://example.com/user1.jpg', name: '张 三' },
{ id: 2, image: 'https://example.com/user2.jpg', name: '李 四' },
{ id: 3, image: 'https://example.com/user3.jpg', name: '王 五' },
];
return (
{users.map((user) => (
{user.name
.split(' ')
.map((n) => n[0])
.join('')}
))}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/avatar.tsx)。
## API 参考
### Avatar
| prop | type | default | description |
| -------------- | ------------------------------------------------------------- | ----------- | ---------------------------------- |
| `children` | `React.ReactNode` | - | 头像内容(`Image` 与/或 `Fallback`) |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 尺寸 |
| `variant` | `'default' \| 'soft'` | `'default'` | 视觉变体 |
| `color` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'accent'` | 颜色变体 |
| `className` | `string` | - | 额外的 class |
| `animation` | `"disable-all"` \| `undefined` | `undefined` | 动画配置;`"disable-all"` 可禁用自身及子级的全部动画 |
| `alt` | `string` | - | 无障碍替代文本描述 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
### Avatar.Image
根据 `asChild` 扩展不同的基础类型:
* `asChild={false}`(默认):扩展自 React Native Reanimated 的 `AnimatedProps`
* `asChild={true}`:扩展自定义图片组件的原语图片属性
**说明:** `asChild={true}` 时,取决于自定义组件实现,`className` 可能不会生效;请确保自定义组件正确处理样式 props。
| prop | type | default | description |
| ----------------------- | ---------------------------------------------- | ------- | -------------------------- |
| `source` | `ImageSourcePropType` | - | 图片源(`asChild={false}` 时必填) |
| `asChild` | `boolean` | `false` | 是否使用自定义图片子组件 |
| `className` | `string` | - | 额外的 class |
| `animation` | `AvatarImageAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...AnimatedProps` | `AnimatedProps` or primitive props | - | 随 `asChild` 变化的额外属性 |
#### AvatarImageAnimation
图片动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------------- | ----------------------- | --------------------------------------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `opacity.value` | `[number, number]` | `[0, 1]` | 不透明度 \[初始, 已加载] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200, easing: Easing.in(Easing.ease) }` | 时间曲线配置 |
**说明:** `asChild={true}` 时动画会自动禁用。
### Avatar.Fallback
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------------- | --------------------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 回退内容(文字、图标或自定义节点) |
| `delayMs` | `number` | `0` | 显示回退前的延迟(毫秒),作用于进入动画 |
| `color` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | inherited from parent | 回退颜色变体 |
| `className` | `string` | - | 容器额外 class |
| `classNames` | `ElementSlots` | - | 各部分额外 class |
| `styles` | `{ container?: ViewStyle; text?: TextStyle }` | - | 回退各部分的样式 |
| `textProps` | `TextProps` | - | 子节点为字符串时传给 `Text` 的属性 |
| `iconProps` | `PersonIconProps` | - | 自定义默认人像图标的属性 |
| `animation` | `AvatarFallbackAnimation` | - | 动画配置 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
**classNames:** `ElementSlots` 提供类型安全的 class。可用插槽:`container`、`text`。
#### `styles`
| prop | type | description |
| ----------- | ----------- | ----------- |
| `container` | `ViewStyle` | 容器样式 |
| `text` | `TextStyle` | 文字样式 |
#### AvatarFallbackAnimation
回退动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ----------------------- | -------------------------------------------------------------------------------------- | ----------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.in(Easing.ease))`
`.delay(0)` | 自定义进入动画 |
#### PersonIconProps
| prop | type | description |
| ------- | -------- | ----------- |
| `size` | `number` | 图标尺寸(可选) |
| `color` | `string` | 图标颜色(可选) |
## Hooks
### useAvatar
访问 Avatar 根上下文,获取头像状态。
**说明:** `status` 常用于在图片加载时显示骨架屏。
```tsx
import { Avatar, useAvatar, Skeleton } from 'heroui-native';
function AvatarWithSkeleton() {
return (
JD
);
}
function AvatarContent() {
const { status } = useAvatar();
if (status === 'loading') {
return ;
}
return null;
}
```
| property | type | description |
| ----------- | ---------------------------------------------------- | ------------ |
| `status` | `'loading' \| 'loaded' \| 'error'` | 当前图片加载状态 |
| `setStatus` | `(status: 'loading' \| 'loaded' \| 'error') => void` | 手动设置状态(高级用法) |
**状态含义:**
* `'loading'`:图片加载中,可显示骨架屏
* `'loaded'`:图片加载成功
* `'error'`:加载失败或资源无效,会自动显示回退
# Accordion 手风琴
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/accordion
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(navigation)/accordion.mdx
> 可折叠内容面板,在紧凑空间内组织信息
## 导入
```tsx
import { Accordion } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **Accordion**:主容器,管理手风琴状态与行为;控制各条目的展开/收起,支持单选或多选展开模式,并提供 `default` 或 `surface` 等视觉变体。
* **Accordion.Item**:单个条目的容器,包裹触发器与内容,并管理该条目的展开状态。
* **Accordion.Trigger**:用于切换条目展开的可交互区域,基于 Header 与 Trigger 原语构建。
* **Accordion.Indicator**:可选的视觉指示器,展示展开状态;默认使用随状态旋转的动画 chevron 图标。
* **Accordion.Content**:可展开内容的容器,配合布局过渡动画实现平滑展开/收起。
## 用法
### 基础用法
Accordion 通过复合子组件创建可展开的内容区块。
```tsx
...
...
```
### 单选模式
同一时间只允许展开一个条目。
```tsx
...
...
...
...
```
### 多选模式
允许多个条目同时展开。
```tsx
...
...
...
...
...
...
```
### Surface 变体
为手风琴应用表面容器样式。
```tsx
...
...
```
### 自定义指示器
用自定义内容替换默认 chevron 指示器。
```tsx
...
...
```
### 无分隔线
隐藏条目之间的分隔线。
```tsx
...
...
...
...
```
### 自定义样式
通过 `className`、`classNames` 或 `styles` 传入自定义样式。
```tsx
...
...
```
### 配合 PressableFeedback
对 `Accordion.Trigger` 使用 `asChild`,并用 `PressableFeedback` 包裹内容以添加按压反馈动画。
```tsx
import { Accordion, PressableFeedback } from 'heroui-native';
import { View } from 'react-native';
条目标题
...
;
```
## 示例
```tsx
import { Accordion, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View, Text } from 'react-native';
export default function AccordionExample() {
const themeColorMuted = useThemeColor('muted');
const accordionData = [
{
id: '1',
title: '如何下单?',
icon: ,
content:
'这是一段示例说明文字,用于演示折叠面板中的正文内容展示效果。',
},
{
id: '2',
title: '支持哪些支付方式?',
icon: ,
content:
'这是一段示例说明文字,用于演示折叠面板中的正文内容展示效果。',
},
{
id: '3',
title: '运费如何计算?',
icon: ,
content:
'这是一段示例说明文字,用于演示折叠面板中的正文内容展示效果。',
},
];
return (
{accordionData.map((item) => (
{item.icon}
{item.title}
{item.content}
))}
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/accordion.tsx)。
## API 参考
### Accordion
| prop | type | default | description |
| ----------------------- | -------------------------------------------------- | ----------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 渲染在手风琴内的子节点 |
| `selectionMode` | `'single' \| 'multiple'` | - | 允许单条或多条同时展开 |
| `variant` | `'default' \| 'surface'` | `'default'` | 手风琴视觉变体 |
| `hideSeparator` | `boolean` | `false` | 是否隐藏条目之间的分隔线 |
| `defaultValue` | `string \| string[] \| undefined` | - | 非受控模式下的默认展开项 |
| `value` | `string \| string[] \| undefined` | - | 受控模式下的当前展开项 |
| `isDisabled` | `boolean` | - | 是否禁用全部条目 |
| `isCollapsible` | `boolean` | `true` | 已展开条目是否可再次收起 |
| `animation` | `AccordionRootAnimation` | - | 根级动画配置 |
| `className` | `string` | - | 容器的额外 class |
| `classNames` | `ElementSlots` | - | 各插槽的额外 class |
| `styles` | `Partial>` | - | 根组件各部分的样式 |
| `onValueChange` | `(value: string \| string[] \| undefined) => void` | - | 展开项变化时的回调 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### `ElementSlots`
| prop | type | description |
| ----------- | -------- | ----------------- |
| `container` | `string` | 手风琴容器的自定义 class |
| `separator` | `string` | 条目之间分隔线的自定义 class |
#### `styles`
| prop | type | description |
| ----------- | ----------- | ----------- |
| `container` | `ViewStyle` | 手风琴容器样式 |
| `separator` | `ViewStyle` | 条目之间分隔线样式 |
#### AccordionRootAnimation
手风琴根组件的动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根级动画
* `"disable-all"`:禁用全部动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| -------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------- | ------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在自定义属性时禁用动画 |
| `layout.value` | `LayoutTransition` | `LinearTransition`
`.springify()`
`.damping(140)`
`.stiffness(1600)`
`.mass(4)` | 手风琴过渡的自定义布局动画 |
### Accordion.Item
| prop | type | default | description |
| ----------------------- | --------------------------------------------------------------------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode \| ((props: AccordionItemRenderProps) => React.ReactNode)` | - | 条目内的子节点,或渲染函数 |
| `value` | `string` | - | 唯一标识该条目的值 |
| `isDisabled` | `boolean` | - | 是否禁用该条目 |
| `className` | `string` | - | 额外的 class |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### AccordionItemRenderProps
| prop | type | description |
| ------------ | --------- | ----------- |
| `isExpanded` | `boolean` | 当前条目是否展开 |
| `value` | `string` | 该条目的唯一值 |
### Accordion.Trigger
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ------------------------------- |
| `children` | `React.ReactNode` | - | 触发器内的子节点 |
| `className` | `string` | - | 额外的 class |
| `isDisabled` | `boolean` | - | 是否禁用触发器 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的属性 |
### Accordion.Indicator
| prop | type | default | description |
| ----------------------- | ----------------------------- | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 自定义指示器内容;未提供时默认为带动画的 chevron |
| `className` | `string` | - | 额外的 class |
| `iconProps` | `AccordionIndicatorIconProps` | - | 图标配置 |
| `animation` | `AccordionIndicatorAnimation` | - | 指示器动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### AccordionIndicatorIconProps
| prop | type | default | description |
| ------- | -------- | ------------ | ----------- |
| `size` | `number` | `16` | 图标尺寸 |
| `color` | `string` | `foreground` | 图标颜色 |
#### AccordionIndicatorAnimation
指示器动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ----------------------- | ----------------------- | -------------------------------------------- | ------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `rotation.value` | `[number, number]` | `[0, -180]` | 旋转角度 \[收起, 展开],单位为度 |
| `rotation.springConfig` | `WithSpringConfig` | `{ damping: 140, stiffness: 1000, mass: 4 }` | 旋转弹簧动画配置 |
### Accordion.Content
| prop | type | default | description |
| -------------- | --------------------------- | ------- | -------------------------- |
| `children` | `React.ReactNode` | - | 内容区域内的子节点 |
| `className` | `string` | - | 额外的 class |
| `animation` | `AccordionContentAnimation` | - | 内容动画配置 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的属性 |
#### AccordionContentAnimation
内容区动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------------- | ----------------------- | ---------------------------------------------------------------------- | ----------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `entering.value` | `EntryOrExitLayoutType` | `FadeIn`
`.duration(200)`
`.easing(Easing.out(Easing.ease))` | 自定义进入动画 |
| `exiting.value` | `EntryOrExitLayoutType` | `FadeOut`
`.duration(200)`
`.easing(Easing.in(Easing.ease))` | 自定义退出动画 |
## Hooks
### useAccordion
访问手风琴根上下文,必须在 `Accordion` 内使用。
```tsx
import { useAccordion } from 'heroui-native';
const { value, onValueChange, selectionMode, isCollapsible, isDisabled } =
useAccordion();
```
#### 返回值
| property | type | description |
| --------------- | --------------------------------------------------------------------- | ------------------ |
| `selectionMode` | `'single' \| 'multiple' \| undefined` | 单选或多选展开模式 |
| `value` | `(string \| undefined) \| string[]` | 当前展开项:单选为字符串,多选为数组 |
| `onValueChange` | `(value: string \| undefined) => void \| ((value: string[]) => void)` | 更新展开项的回调 |
| `isCollapsible` | `boolean` | 已展开项是否可收起 |
| `isDisabled` | `boolean \| undefined` | 是否禁用全部条目 |
### useAccordionItem
访问单条条目上下文,必须在 `Accordion.Item` 内使用。
```tsx
import { useAccordionItem } from 'heroui-native';
const { value, isExpanded, isDisabled, nativeID } = useAccordionItem();
```
#### 返回值
| property | type | description |
| ------------ | ---------------------- | ------------------ |
| `value` | `string` | 该条目的唯一值 |
| `isExpanded` | `boolean` | 当前是否展开 |
| `isDisabled` | `boolean \| undefined` | 该条目是否禁用 |
| `nativeID` | `string` | 无障碍与 ARIA 使用的原生 ID |
## 特别说明
当 Accordion 与同屏其他组件一起使用时,请为这些组件导入并应用 `AccordionLayoutTransition`,以保证整屏布局动画一致、顺滑。
```jsx
import { Accordion, AccordionLayoutTransition } from 'heroui-native';
import Animated from 'react-native-reanimated';
{/* 其他内容 */}
{/* 手风琴条目 */}
;
```
这样在展开或收起时,屏幕上各组件会使用相同的时长与缓动,体验更统一。
# ListGroup 列表组
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/list-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(navigation)/list-group.mdx
> 基于 Surface 的容器,用于分组展示列表项并保持一致的布局与间距。
## 导入
```tsx
import { ListGroup } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **ListGroup**:基于 Surface 的根容器,用于分组列表项;支持全部 Surface 变体(`default`、`secondary`、`tertiary`、`transparent`)。
* **ListGroup.Item**:可按压的水平 `flex-row` 行容器,提供统一的间距与对齐。
* **ListGroup.ItemPrefix**:可选前导槽,用于图标、头像等。
* **ListGroup.ItemContent**:`flex-1` 包裹标题与说明,占据剩余横向空间。
* **ListGroup.ItemTitle**:主标题,前景色与中等字重。
* **ListGroup.ItemDescription**:次要说明,弱化颜色与较小字号。
* **ListGroup.ItemSuffix**:可选尾部槽;默认渲染右箭头;传入子节点可覆盖默认图标。
## 用法
### 基础用法
通过组合子部件创建带标题与说明的分组列表。
```tsx
个人信息
姓名、邮箱、手机号
支付方式
Visa 尾号 4829
```
### 带图标
使用 `ListGroup.ItemPrefix` 放置前置图标。
```tsx
个人资料
姓名、照片、简介
安全
密码、双重验证
```
### 仅标题
省略 `ListGroup.ItemDescription` 以展示仅标题行。
```tsx
Wi-Fi
蓝牙
```
### Surface 变体
为根容器应用不同的视觉变体。
```tsx
Wi-Fi
```
### 自定义尾部
向 `ListGroup.ItemSuffix` 传入子节点以覆盖默认箭头。
```tsx
语言
简体中文
通知
7
```
### 自定义尾部图标属性
通过 `iconProps` 调整默认箭头尺寸与颜色。
```tsx
存储空间
已用 12.4 GB / 共 50 GB
```
### 配合 PressableFeedback
用 `PressableFeedback` 包裹列表项以添加缩放与水波纹反馈。此模式下将 `onPress` 放在 `PressableFeedback` 上,并对 `ListGroup.Item` 使用 `disabled`。
```tsx
import { ListGroup, PressableFeedback, Separator } from 'heroui-native';
{}}>
外观
主题、字号、显示
{}}>
通知
提醒、声音、角标
```
## 示例
```tsx
import { Ionicons } from '@expo/vector-icons';
import { ListGroup, Separator, useThemeColor } from 'heroui-native';
import { View, Text } from 'react-native';
import { withUniwind } from 'uniwind';
const StyledIonicons = withUniwind(Ionicons);
export default function ListGroupExample() {
const mutedColor = useThemeColor('muted');
return (
账户
个人信息
姓名、邮箱、手机号
支付方式
Visa 尾号 4829
偏好设置
外观
主题、字号、显示
通知
提醒、声音、角标
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/list-group.tsx)。
## API 参考
### ListGroup
| prop | type | default | description |
| -------------- | --------------------------------------------------------- | ----------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 分组内的子节点 |
| `variant` | `'default' \| 'secondary' \| 'tertiary' \| 'transparent'` | `'default'` | 底层 Surface 容器的视觉变体 |
| `className` | `string` | - | 根容器额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### ListGroup.Item
| prop | type | default | description |
| ------------------- | ----------------- | ------- | ---------------------------------- |
| `children` | `React.ReactNode` | - | 列表行内的子节点 |
| `className` | `string` | - | 列表行额外 class |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 React Native `Pressable` 属性 |
### ListGroup.ItemPrefix
| prop | type | default | description |
| -------------- | ----------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 前导内容,如图标或头像 |
| `className` | `string` | - | 前导区域额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### ListGroup.ItemContent
| prop | type | default | description |
| -------------- | ----------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 内容区,通常为标题与说明 |
| `className` | `string` | - | 内容区额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### ListGroup.ItemTitle
| prop | type | default | description |
| -------------- | ----------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 标题文本或自定义内容 |
| `className` | `string` | - | 标题额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### ListGroup.ItemDescription
| prop | type | default | description |
| -------------- | ----------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 说明文本或自定义内容 |
| `className` | `string` | - | 说明额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### ListGroup.ItemSuffix
| prop | type | default | description |
| -------------- | -------------------- | ------- | ----------------------------- |
| `children` | `React.ReactNode` | - | 自定义尾部内容;提供时将覆盖默认右箭头图标 |
| `className` | `string` | - | 尾部额外 class |
| `iconProps` | `ListGroupIconProps` | - | 自定义默认右箭头图标;仅在无 `children` 时生效 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### ListGroupIconProps
| prop | type | default | description |
| ------- | -------- | -------------- | ----------- |
| `size` | `number` | `16` | 箭头图标尺寸(像素) |
| `color` | `string` | 主题的 `muted` 颜色 | 箭头图标颜色 |
# Tabs 标签页
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/tabs
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(navigation)/tabs.mdx
> 使用选项卡视图组织内容,支持动画过渡与指示器。
## 导入
```tsx
import { Tabs } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **Tabs**:管理选项卡状态与选中的根容器。控制当前激活项、处理值变化,并向子组件提供上下文。
* **Tabs.List**:放置选项卡触发器的容器。将多个触发器组合在一起,并支持 `primary` 或 `secondary` 等样式变体。
* **Tabs.ScrollView**:可选的横向滚动容器。当标签溢出时可横向滚动,并可在选中时自动居中。
* **Tabs.Trigger**:每个选项卡的交互触发器。处理按压以切换激活项,并测量位置以驱动指示器动画。
* **Tabs.Label**:触发器上的文字标签,用于展示选项卡标题及对应样式。
* **Tabs.Indicator**:当前激活项的可视指示器,可在选项卡之间以弹簧或时长动画平滑过渡。
* **Tabs.Separator**:选项卡之间的分隔线。当当前值不在 `betweenValues` 数组中时显示,并带有透明度过渡动画。
* **Tabs.Content**:面板内容容器。当其 `value` 与当前激活项一致时显示对应内容。
## 用法
### 基础用法
Tabs 使用复合子组件,将内容划分为可切换的区域。
```tsx
标签一
标签二
...
...
```
### 主样式(primary)
默认圆角主样式,选中项背后为填充指示器。
```tsx
设置
个人资料
...
...
```
### 次样式(secondary)
下划线指示器,视觉更轻量。
```tsx
概览
分析
...
...
```
### 可滚动标签
标签较多时通过横向滚动容纳。
```tsx
第一个
第二个
第三个
第四个
第五个
...
...
...
...
...
```
### 禁用标签
使用 `isDisabled` 禁止与特定标签交互。
```tsx
可用
已禁用
其他
...
...
```
### 与图标组合
图标与文字并用,信息更直观。
```tsx
首页
搜索
...
...
```
### 使用渲染函数
在 `Tabs.Trigger` 上使用渲染函数,可读取选中状态并按需自定义内容。
```tsx
{({ isSelected, value, isDisabled }) => (
设置
)}
{({ isSelected }) => (
<>
个人资料
>
)}
...
...
```
### 与分隔线配合
在标签之间添加分隔线;可见性由 `betweenValues` 与当前激活项共同决定(详见下方 API)。
```tsx
通用
通知
个人资料
...
...
...
```
## 示例
```tsx
import {
Button,
Checkbox,
Description,
ControlField,
Label,
Tabs,
TextField,
} from 'heroui-native';
import { useState } from 'react';
import { View, Text } from 'react-native';
import Animated, {
FadeIn,
FadeOut,
LinearTransition,
} from 'react-native-reanimated';
const AnimatedContentContainer = ({
children,
}: {
children: React.ReactNode;
}) => (
{children}
);
export default function TabsExample() {
const [activeTab, setActiveTab] = useState('general');
const [showSidebar, setShowSidebar] = useState(true);
const [accountActivity, setAccountActivity] = useState(true);
const [name, setName] = useState('');
return (
通用
通知
个人资料
显示侧边导航面板
接收与账户活动相关的通知
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/tabs.tsx)。
## API 参考
### Tabs
| prop | type | 默认值 | 描述 |
| --------------- | ---------------------------- | ----------- | ------------------------------------ |
| `children` | `React.ReactNode` | - | 渲染在 Tabs 内的子元素 |
| `value` | `string` | - | 当前激活的标签值 |
| `variant` | `'primary' \| 'secondary'` | `'primary'` | 视觉变体 |
| `className` | `string` | - | 根容器额外 className |
| `animation` | `"disable-all" \| undefined` | `undefined` | 动画配置。设为 `"disable-all"` 可关闭全部动画(含子树) |
| `onValueChange` | `(value: string) => void` | - | 激活标签变化时的回调 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Tabs.List
| prop | type | 默认值 | 描述 |
| -------------- | ----------------- | --- | ------------------------------ |
| `children` | `React.ReactNode` | - | 渲染在列表内的子元素 |
| `className` | `string` | - | 额外 className |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
### Tabs.ScrollView
| prop | type | 默认值 | 描述 |
| --------------------------- | ---------------------------------------- | ---------- | ------------------------------------ |
| `children` | `React.ReactNode` | - | 渲染在滚动视图内的子元素 |
| `scrollAlign` | `'start' \| 'center' \| 'end' \| 'none'` | `'center'` | 选中项的滚动对齐方式 |
| `className` | `string` | - | 滚动容器额外 className |
| `contentContainerClassName` | `string` | - | 内容容器额外 className |
| `...ScrollViewProps` | `ScrollViewProps` | - | 支持 React Native `ScrollView` 的全部标准属性 |
### Tabs.Trigger
| prop | type | 默认值 | 描述 |
| ------------------- | ------------------------------------------------------------------------- | ------- | -------------------------------------- |
| `children` | `React.ReactNode \| ((props: TabsTriggerRenderProps) => React.ReactNode)` | - | 子节点,或接收 `TabsTriggerRenderProps` 的渲染函数 |
| `value` | `string` | - | 唯一标识该标签的值 |
| `isDisabled` | `boolean` | `false` | 是否禁用该触发器 |
| `className` | `string` | - | 额外 className |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部标准属性 |
#### TabsTriggerRenderProps
使用渲染函数作为 `children` 时,会传入以下属性:
| property | type | 描述 |
| ------------ | --------- | ---------- |
| `isSelected` | `boolean` | 当前触发器是否被选中 |
| `value` | `string` | 该触发器的值 |
| `isDisabled` | `boolean` | 该触发器是否禁用 |
### Tabs.Label
| prop | type | 默认值 | 描述 |
| -------------- | ----------------- | --- | ------------------------------ |
| `children` | `React.ReactNode` | - | 作为标签渲染的文本内容 |
| `className` | `string` | - | 额外 className |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Tabs.Indicator
| prop | type | 默认值 | 描述 |
| ----------------------- | ------------------------ | ------ | ----------------------------------- |
| `children` | `React.ReactNode` | - | 自定义指示器内容 |
| `className` | `string` | - | 额外 className |
| `animation` | `TabsIndicatorAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### TabsIndicatorAnimation
`Tabs.Indicator` 的动画配置,可为:
* `false` 或 `"disabled"`:关闭所有动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | 默认值 | 描述 |
| ------------------- | -------------------------------------- | ------------------------------------------------------------------------ | --------------- |
| `state` | `'disabled' \| boolean` | - | 自定义属性时用于禁用动画 |
| `width.type` | `'spring' \| 'timing'` | `'spring'` | 宽度动画类型 |
| `width.config` | `WithSpringConfig \| WithTimingConfig` | `{ stiffness: 1200, damping: 120 }`(spring)或 `{ duration: 200 }`(timing) | Reanimated 动画配置 |
| `height.type` | `'spring' \| 'timing'` | `'spring'` | 高度动画类型 |
| `height.config` | `WithSpringConfig \| WithTimingConfig` | 同上 | Reanimated 动画配置 |
| `translateX.type` | `'spring' \| 'timing'` | `'spring'` | 水平位移动画类型 |
| `translateX.config` | `WithSpringConfig \| WithTimingConfig` | 同上 | Reanimated 动画配置 |
### Tabs.Separator
| prop | type | 默认值 | 描述 |
| ----------------------- | ------------------------ | ------- | --------------------------------------------------- |
| `betweenValues` | `string[]` | - | 分隔线两侧对应的标签值数组。当**当前**标签值**不在**该数组中时,分隔线可见(与可见性动画联动) |
| `isAlwaysVisible` | `boolean` | `false` | 为 `true` 时透明度恒为 1,不受当前标签影响 |
| `className` | `string` | - | 额外 className |
| `animation` | `TabsSeparatorAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `children` | `React.ReactNode` | - | 自定义分隔线内容 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
**说明:** 以下样式属性由动画占用,不能仅通过 `className` 覆盖:
* `opacity`:用于分隔线显隐过渡(当前标签在 `betweenValues` 内时为 0,否则为 1)
若要调整这些属性,请使用 `animation`。若需完全关闭动画样式、改用自己的 `className` 或 `style`,请设置 `isAnimatedStyleActive={false}`。
#### TabsSeparatorAnimation
`Tabs.Separator` 的动画配置,可为:
* `false` 或 `"disabled"`:关闭所有动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | 默认值 | 描述 |
| ---------------------- | ----------------------- | ------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 自定义属性时用于禁用动画 |
| `opacity.value` | `[number, number]` | `[0, 1]` | 透明度区间 \[隐藏, 显示] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | 时长类动画配置 |
### Tabs.Content
| prop | type | 默认值 | 描述 |
| -------------- | ----------------- | --- | ------------------------------ |
| `children` | `React.ReactNode` | - | 渲染在面板内的子元素 |
| `value` | `string` | - | 该内容与哪个标签值对应 |
| `className` | `string` | - | 额外 className |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
## Hooks
### useTabs
在自定义组件或复合子组件中读取 Tabs 根上下文。
```tsx
import { useTabs } from 'heroui-native';
const CustomComponent = () => {
const { value, onValueChange, nativeID } = useTabs();
// ...你的实现
};
```
#### 返回值
类型:`UseTabsReturn`
| property | type | 描述 |
| --------------- | ------------------------- | -------------- |
| `value` | `string` | 当前激活的标签值 |
| `onValueChange` | `(value: string) => void` | 用于切换激活标签的回调 |
| `nativeID` | `string` | 该 Tabs 实例的唯一标识 |
**说明:** 必须在 `Tabs` 内使用;在上下文外调用会抛错。
### useTabsMeasurements
读取标签测量上下文,用于管理各触发器的位置与尺寸。
```tsx
import { useTabsMeasurements } from 'heroui-native';
const CustomIndicator = () => {
const { measurements, variant } = useTabsMeasurements();
// ...你的实现
};
```
#### 返回值
类型:`UseTabsMeasurementsReturn`
| property | type | 描述 |
| ----------------- | ------------------------------------------------------- | ------------- |
| `measurements` | `Record` | 各标签触发器的测量数据 |
| `setMeasurements` | `(key: string, measurements: ItemMeasurements) => void` | 更新指定触发器的测量数据 |
| `variant` | `'primary' \| 'secondary'` | 当前 Tabs 的视觉变体 |
#### ItemMeasurements
| property | type | 描述 |
| -------- | -------- | --------- |
| `width` | `number` | 触发器宽度(像素) |
| `height` | `number` | 触发器高度(像素) |
| `x` | `number` | 触发器的 x 坐标 |
**说明:** 必须在 `Tabs` 内使用;在上下文外调用会抛错。
### useTabsTrigger
在自定义组件或复合子组件中读取单个 `Tabs.Trigger` 的上下文。
```tsx
import { useTabsTrigger } from 'heroui-native';
const CustomLabel = () => {
const { value, isSelected, nativeID } = useTabsTrigger();
// ...你的实现
};
```
#### 返回值
类型:`UseTabsTriggerReturn`
| property | type | 描述 |
| ------------ | --------- | ---------- |
| `value` | `string` | 该触发器的值 |
| `nativeID` | `string` | 该触发器的唯一标识 |
| `isSelected` | `boolean` | 当前触发器是否被选中 |
**说明:** 必须在 `Tabs.Trigger` 内使用;在上下文外调用会抛错。
# BottomSheet 底部弹层
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/bottom-sheet
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(overlays)/bottom-sheet.mdx
> 自底部滑入的底部表单,带动画与下滑关闭手势。
## 导入
```tsx
import { BottomSheet } from 'heroui-native';
```
## 结构
```tsx
...
...
...
...
```
* **BottomSheet**:根组件,管理开关状态并向子级提供上下文。
* **BottomSheet.Trigger**:按下后打开底部表单的可按压区域。
* **BottomSheet.Portal**:在 Portal 中渲染,使用全屏覆盖层。
* **BottomSheet.Overlay**:覆盖全屏的背景层,按下通常可关闭。
* **BottomSheet.Content**:主容器,基于 @gorhom/bottom-sheet 渲染并支持手势。
* **BottomSheet.Close**:关闭按钮;可自定义子节点或使用默认关闭图标。
* **BottomSheet.Title**:标题,语义标题角色并关联无障碍。
* **BottomSheet.Description**:说明文字,并关联无障碍。
## 用法
### 基础底部表单
包含标题、描述与关闭按钮的简单示例。
```tsx
...
...
```
### 悬浮(Detached)
与底边留出间距的悬浮样式。
```tsx
...
...
```
### 多停靠点与滚动
多档高度与可滚动内容。
```tsx
...
...
```
### 自定义遮罩
用模糊等自定义内容替换默认遮罩。
```tsx
import { useBottomSheet, useBottomSheetAnimation } from 'heroui-native';
import { StyleSheet, Pressable } from 'react-native';
import { interpolate, useDerivedValue } from 'react-native-reanimated';
import { AnimatedBlurView } from './animated-blur-view';
import { useUniwind } from 'uniwind';
export const BottomSheetBlurOverlay = () => {
const { theme } = useUniwind();
const { onOpenChange } = useBottomSheet();
const { progress } = useBottomSheetAnimation();
const blurIntensity = useDerivedValue(() => {
return interpolate(progress.get(), [0, 1, 2], [0, 40, 0]);
});
return (
onOpenChange(false)}
>
);
};
```
```tsx
...
...
```
## 示例
```tsx
import { BottomSheet, Button } from 'heroui-native';
import { useState } from 'react';
import { View } from 'react-native';
import { withUniwind } from 'uniwind';
import Ionicons from '@expo/vector-icons/Ionicons';
const StyledIonicons = withUniwind(Ionicons);
export default function BottomSheetExample() {
const [isOpen, setIsOpen] = useState(false);
return (
保持安全
将软件更新到最新版本,以获得更好的安全性与性能。
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/bottom-sheet.tsx)。
## API 参考
### BottomSheet
| prop | type | default | description |
| --------------- | -------------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 触发器与底部表单内容 |
| `isOpen` | `boolean` | - | 受控开关状态 |
| `isDefaultOpen` | `boolean` | `false` | 非受控初始是否打开 |
| `animation` | `AnimationRootDisableAll` | - | 动画配置 |
| `onOpenChange` | `(value: boolean) => void` | - | 开关状态变化回调 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### 动画配置
根动画配置,可为:
* `"disable-all"`:禁用全部动画(含子级)
* `undefined`:使用默认动画
### BottomSheet.Trigger
| prop | type | default | description |
| -------------------------- | ----------------------- | ------- | ---------------------------------------- |
| `children` | `React.ReactNode` | - | 触发器内容 |
| `asChild` | `boolean` | - | 是否无包裹渲染为子元素 |
| `...TouchableOpacityProps` | `TouchableOpacityProps` | - | 支持 React Native `TouchableOpacity` 的全部属性 |
### BottomSheet.Portal
| prop | type | default | description |
| -------------------------------------------- | ---------------------- | ------- | ----------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Portal 内容(遮罩与底部表单) |
| `disableFullWindowOverlay` | `boolean` | `false` | iOS 为 true 时使用普通 `View` 替代 `FullWindowOverlay`,便于检查器;遮罩不再叠在原生模态之上 |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 是否将覆盖窗口视为模态容器(VoiceOver)。仅 iOS;可能随 react-native-screens 变化 |
| `className` | `string` | - | Portal 容器额外 class |
| `style` | `StyleProp` | - | Portal 容器额外样式 |
| `hostName` | `string` | - | 可选 Portal 宿主名 |
| `forceMount` | `boolean` | - | 关闭时仍挂载以配合动画 |
### BottomSheet.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------ | ------- | --------------------------------- |
| `children` | `React.ReactNode` | - | 自定义遮罩内容 |
| `className` | `string` | - | 遮罩额外 class |
| `style` | `ViewStyle` | - | 遮罩容器样式 |
| `animation` | `Omit` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `isCloseOnPress` | `boolean` | `true` | 按下遮罩是否关闭 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部属性 |
#### 动画配置
遮罩动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置(不含 `entering` / `exiting`)
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | ------------------ |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | 不透明度 \[空闲, 打开, 关闭] |
### BottomSheet.Content
| prop | type | default | description |
| --------------------------- | ---------------------------------------- | ------- | -------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | 底部表单内容 |
| `className` | `string` | - | 容器额外 class |
| `containerClassName` | `string` | - | 外层容器 class |
| `contentContainerClassName` | `string` | - | 内容区 class |
| `backgroundClassName` | `string` | - | 背景 class |
| `handleClassName` | `string` | - | 拖动手柄区域 class |
| `handleIndicatorClassName` | `string` | - | 手柄指示条 class |
| `contentContainerProps` | `Omit` | - | 内容容器 props |
| `animation` | `AnimationDisabled` | - | 动画配置 |
| `...GorhomBottomSheetProps` | `Partial` | - | 支持 [@gorhom/bottom-sheet 全部 props](https://gorhom.dev/react-native-bottom-sheet/props) |
**说明:** 内容区内可使用 [@gorhom/bottom-sheet 组件](https://gorhom.dev/react-native-bottom-sheet/components/bottomsheetview),如 `BottomSheetView`、`BottomSheetScrollView`、`BottomSheetFlatList` 等。
### BottomSheet.Close
`BottomSheet.Close` 继承 [CloseButton](./close-button),按下时自动关闭底部表单。
### BottomSheet.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 标题内容 |
| `className` | `string` | - | 标题额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### BottomSheet.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 描述内容 |
| `className` | `string` | - | 描述额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
## Hooks
### useBottomSheet
访问底部表单原语上下文。
```tsx
const { isOpen, onOpenChange } = useBottomSheet();
```
| property | type | description |
| -------------- | -------------------------- | ----------- |
| `isOpen` | `boolean` | 当前是否打开 |
| `onOpenChange` | `(value: boolean) => void` | 修改开关状态 |
### useBottomSheetAnimation
访问底部表单动画上下文。
```tsx
const { progress } = useBottomSheetAnimation();
```
| property | type | description |
| ---------- | --------------------- | -------------------- |
| `progress` | `SharedValue` | 动画进度(0=空闲,1=打开,2=关闭) |
## 特别说明
### 元素检查器(iOS)
`BottomSheet` 在 iOS 使用 `FullWindowOverlay`,位于独立原生窗口,会破坏 React Native 元素检查器。开发时可在 `BottomSheet.Portal` 设置 `disableFullWindowOverlay={true}`。代价:底部表单将无法叠在原生系统模态之上。
### 关闭回调
建议使用 `BottomSheet` 的 `onOpenChange` 处理关闭逻辑,可在所有关闭场景可靠触发(下滑、点遮罩、点关闭、程序化关闭等)。
```tsx
{
setIsOpen(value);
if (!value) {
// 任意方式关闭时都会执行
yourCallbackOnClose();
}
}}
>
...
```
**说明:** `@gorhom/bottom-sheet` 在 `BottomSheet.Content` 上的 `onClose` 仅在下滑关闭时触发,点遮罩、关闭按钮或程序化关闭不会触发。需要可靠关闭回调时请使用根组件的 `onOpenChange`。
# Dialog 对话框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/dialog
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(overlays)/dialog.mdx
> 模态浮层,带动画过渡并支持手势关闭。
## 导入
```tsx
import { Dialog } from 'heroui-native';
```
## 结构
```tsx
```
* **Dialog**:根组件,管理开关状态并向子级提供上下文。
* **Dialog.Trigger**:按下后打开对话框的可按压区域。
* **Dialog.Portal**:在 Portal 中渲染内容,居中布局并控制动画。
* **Dialog.Overlay**:内容背后的遮罩,按下通常可关闭对话框。
* **Dialog.Content**:主容器,支持拖拽关闭等手势。
* **Dialog.Close**:关闭按钮;可自定义子节点或使用默认关闭图标。
* **Dialog.Title**:标题,语义为标题角色。
* **Dialog.Description**:补充说明文字。
## 用法
### 基础对话框
包含标题、描述与关闭按钮的简单对话框。
```tsx
```
### 可滚动内容
长内容使用滚动容器承载。
```tsx
```
### 表单对话框
包含输入与键盘避让的对话框。
```tsx
```
## 示例
```tsx
import { Button, Dialog } from 'heroui-native';
import { View } from 'react-native';
import { useState } from 'react';
export default function DialogExample() {
const [isOpen, setIsOpen] = useState(false);
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/dialog.tsx)。
## API 参考
### Dialog
| prop | type | default | description |
| --------------- | -------------------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 触发器与对话框内容 |
| `isOpen` | `boolean` | - | 受控开关状态 |
| `isDefaultOpen` | `boolean` | `false` | 非受控初始是否打开 |
| `animation` | `AnimationRootDisableAll` | - | 动画配置 |
| `onOpenChange` | `(value: boolean) => void` | - | 开关状态变化回调 |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### AnimationRootDisableAll
根动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根级动画
* `"disable-all"`:禁用全部动画(含子级)
* `true` 或 `undefined`:使用默认动画
### Dialog.Trigger
| prop | type | default | description |
| -------------------------- | ----------------------- | ------- | ---------------------------------------- |
| `children` | `React.ReactNode` | - | 触发器内容 |
| `asChild` | `boolean` | - | 是否无包裹渲染为子元素 |
| `...TouchableOpacityProps` | `TouchableOpacityProps` | - | 支持 React Native `TouchableOpacity` 的全部属性 |
### Dialog.Portal
| prop | type | default | description |
| -------------------------------------------- | ---------------------- | ------- | ----------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Portal 内容(遮罩与对话框) |
| `disableFullWindowOverlay` | `boolean` | `false` | iOS 为 true 时使用普通 `View` 替代 `FullWindowOverlay`,便于检查器;遮罩不再叠在原生模态之上 |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 是否将覆盖窗口视为模态容器(VoiceOver)。仅 iOS;可能随 react-native-screens 变化 |
| `className` | `string` | - | Portal 容器额外 class |
| `style` | `StyleProp` | - | Portal 容器额外样式 |
| `hostName` | `string` | - | 可选 Portal 宿主名 |
| `forceMount` | `boolean` | - | 关闭时仍挂载以配合动画 |
### Dialog.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | --------------------------------- |
| `children` | `React.ReactNode` | - | 自定义遮罩内容 |
| `className` | `string` | - | 遮罩额外 class |
| `style` | `ViewStyle` | - | 遮罩容器样式 |
| `animation` | `DialogOverlayAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `isCloseOnPress` | `boolean` | `true` | 按下遮罩是否关闭 |
| `forceMount` | `boolean` | - | 关闭时仍挂载以配合动画 |
| `...PressableProps` | `PressableProps` | - | 支持 React Native `Pressable` 的全部属性 |
#### DialogOverlayAnimation
遮罩动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| --------------- | -------------------------- | ----------------------- | ----------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | 不透明度 \[空闲, 打开, 关闭](基于进度,用于呈现) |
| `entering` | `EntryOrExitLayoutType` | `FadeIn.duration(200)` | 自定义进入动画(Popover 呈现用) |
| `exiting` | `EntryOrExitLayoutType` | `FadeOut.duration(150)` | 自定义退出动画(Popover 呈现用) |
### Dialog.Content
| prop | type | default | description |
| ----------------------- | ------------------------ | ------- | ----------------------------------- |
| `children` | `React.ReactNode` | - | 对话框内容 |
| `className` | `string` | - | 内容容器额外 class |
| `style` | `StyleProp` | - | 内容容器额外样式 |
| `animation` | `DialogContentAnimation` | - | 动画配置 |
| `isSwipeable` | `boolean` | `true` | 是否可滑动关闭 |
| `forceMount` | `boolean` | - | 关闭时仍挂载以配合动画 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### DialogContentAnimation
内容动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------- | ----------------------- | ------------------------------------------------------------------------ | ----------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `entering` | `EntryOrExitLayoutType` | 关键帧 `scale: 0.96→1` 与 `opacity: 0→1`(200ms,缓动 `Easing.out(Easing.ease)`) | 自定义进入动画 |
| `exiting` | `EntryOrExitLayoutType` | 关键帧 `scale: 1→0.96` 与 `opacity: 1→0`(150ms,缓动 `Easing.in(Easing.ease)`) | 自定义退出动画 |
### Dialog.Close
`Dialog.Close` 继承 [CloseButton](./close-button),按下时自动关闭对话框。
### Dialog.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 标题内容 |
| `className` | `string` | - | 标题额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### Dialog.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 描述内容 |
| `className` | `string` | - | 描述额外 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
## Hooks
### useDialog
访问对话框原语上下文。
```tsx
const { isOpen, onOpenChange } = useDialog();
```
| property | type | description |
| -------------- | -------------------------- | ----------- |
| `isOpen` | `boolean` | 当前是否打开 |
| `onOpenChange` | `(value: boolean) => void` | 修改开关状态 |
### useDialogAnimation
访问对话框动画上下文,用于高级定制。
```tsx
const { progress, isDragging, isGestureReleaseAnimationRunning } =
useDialogAnimation();
```
| property | type | description |
| ---------------------------------- | ---------------------- | -------------------- |
| `progress` | `SharedValue` | 动画进度(0=空闲,1=打开,2=关闭) |
| `isDragging` | `SharedValue` | 是否正在拖拽 |
| `isGestureReleaseAnimationRunning` | `SharedValue` | 手势释放动画是否进行中 |
## 特别说明
### 元素检查器(iOS)
`Dialog` 在 iOS 使用 `FullWindowOverlay`。开发时若需启用 React Native 元素检查器,可在 `Dialog.Portal` 设置 `disableFullWindowOverlay={true}`。代价:对话框将无法叠在原生系统模态之上。
# Popover 弹出框
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/popover
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(overlays)/popover.mdx
> 锚定在触发器上的浮动内容面板,支持方位与对齐选项。
## 导入
```tsx
import { Popover } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **Popover**:根容器,管理展开/收起、定位,并为子组件提供上下文。
* **Popover.Trigger**:可点击的触发器,切换浮层可见性;为子元素包裹按压处理。
* **Popover.Portal**:在Portal层渲染内容,保证层级与定位正确。
* **Popover.Overlay**:可选背景遮罩;可透明或半透明,用于捕获外部点击。
* **Popover.Content**:内容容器,含定位、样式与碰撞检测;支持 `popover` 与底部抽屉呈现。
* **Popover.Arrow**:可选箭头,指向触发器;随 `placement` 自动定位。
* **Popover.Close**:关闭按钮;可自定义子节点,默认关闭图标。
* **Popover.Title**:可选标题,使用预设排版。
* **Popover.Description**:可选说明文字,弱化样式。
## 用法
### 基础用法
通过组合子部件创建浮动内容面板。
```tsx
...
...
```
### 标题与说明
使用标题与说明组织内容层级。
```tsx
...
...
...
```
### 带箭头
添加指向触发器的箭头以增强视觉关联。
```tsx
...
...
```
> **说明:** 使用 `` 时,需要为 `Popover.Content` 添加边框,例如 `border border-border`,以便箭头与内容边框视觉衔接。
### 宽度控制
通过 `width` 控制浮层内容宽度。
```tsx
{
/* 固定像素宽度 */
}
...
...
;
{
/* 与触发器同宽 */
}
...
...
;
{
/* 全宽(100%) */
}
...
...
;
{
/* 随内容自适应(默认) */
}
...
...
;
```
### 底部抽屉呈现
在移动端使用底部抽屉交互。
> **重要:** `Popover.Content` 的 `presentation` 必须与 `Popover` 根上的 `presentation` 一致。开发模式下不一致会抛错。
```tsx
...
...
...
```
### 方位选项
控制浮层相对触发器出现的位置。
```tsx
...
...
```
### 对齐选项
沿放置轴微调内容对齐。
```tsx
...
...
```
### 自定义动画
在 `Popover` 根上使用 `animation` 配置展开/收起过渡。
```tsx
...
...
```
### 编程式控制
```tsx
// 通过 ref 编程式打开/关闭
const popoverRef = useRef(null);
// 打开
popoverRef.current?.open();
// 关闭
popoverRef.current?.close();
// 完整示例
内容
;
```
## 示例
```tsx
import { Ionicons } from '@expo/vector-icons';
import { Button, Popover, useThemeColor } from 'heroui-native';
import { Text, View } from 'react-native';
export default function PopoverExample() {
const themeColorMuted = useThemeColor('muted');
return (
说明
此浮层包含标题与描述,用于向用户提供更有层次的信息。
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/popover.tsx)。
## API 参考
### Popover
| prop | type | default | description |
| --------------- | ----------------------------- | ----------- | ----------------------------------------------------------------- |
| `children` | `ReactNode` | - | 浮层内的子节点 |
| `isOpen` | `boolean` | - | 是否展开(受控) |
| `isDefaultOpen` | `boolean` | - | 初始是否展开(非受控) |
| `onOpenChange` | `(isOpen: boolean) => void` | - | 展开状态变化时的回调 |
| `animation` | `AnimationRootDisableAll` | - | 动画配置,可为 `false`、`"disabled"`、`"disable-all"`、`true` 或 `undefined` |
| `presentation` | `'popover' \| 'bottom-sheet'` | `'popover'` | 内容呈现方式 |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
#### AnimationRootDisableAll
根级动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根动画
* `"disable-all"`:禁用根与子级全部动画
* `true` 或 `undefined`:使用默认动画
### Popover.Trigger
| prop | type | default | description |
| ------------------- | ---------------- | ------- | ---------------------------------- |
| `children` | `ReactNode` | - | 触发器内容 |
| `className` | `string` | - | 触发器额外 class |
| `asChild` | `boolean` | `true` | 是否将子元素作为实际渲染节点 |
| `...PressableProps` | `PressableProps` | - | 支持全部标准 React Native `Pressable` 属性 |
### Popover.Portal
| prop | type | default | description |
| -------------------------------------------- | ----------- | ------- | -------------------------------------------------------------------------------------------------- |
| `children` | `ReactNode` | - | Portal内容(必填) |
| `disableFullWindowOverlay` | `boolean` | `false` | 在 iOS 为 `true` 时使用 `View` 代替 `FullWindowOverlay`,便于元素检查器;遮罩将无法叠在原生模态之上 |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 控制 VoiceOver 是否将遮罩窗口视为模态容器。为 `true` 时,VoiceOver 仅聚焦遮罩内元素。仅 iOS;API 不稳定,可能随 react-native-screens 变更 |
| `hostName` | `string` | - | Portal宿主元素的可选名称 |
| `forceMount` | `boolean` | - | 是否强制挂载 |
| `className` | `string` | - | Portal容器额外 class |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### Popover.Overlay
| prop | type | default | description |
| ----------------------- | ------------------------- | ------- | ----------------------------------- |
| `className` | `string` | - | 遮罩额外 class |
| `closeOnPress` | `boolean` | `true` | 点击遮罩是否关闭 |
| `forceMount` | `boolean` | - | 是否强制挂载 |
| `animation` | `PopoverOverlayAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
#### PopoverOverlayAnimation
遮罩动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| --------------- | -------------------------- | ----------- | --------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `opacity.value` | `[number, number, number]` | `[0, 1, 0]` | 透明度 \[空闲, 打开, 关闭],用于底部抽屉等呈现 |
| `entering` | `EntryOrExitLayoutType` | 默认淡入 200ms | 自定义进入关键帧,用于 `popover` 呈现 |
| `exiting` | `EntryOrExitLayoutType` | 默认淡出 150ms | 自定义退出关键帧,用于 `popover` 呈现 |
### Popover.Content(Popover 呈现)
| prop | type | default | description |
| ------------------------- | ------------------------------------------------ | --------------- | -------------------------------------- |
| `children` | `ReactNode` | - | 浮层内容 |
| `presentation` | `'popover'` | `'popover'` | 呈现模式,须与 `Popover` 根一致;未传时默认为 `popover` |
| `width` | `number \| 'trigger' \| 'content-fit' \| 'full'` | `'content-fit'` | 内容宽度策略 |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'bottom'` | 相对触发器的方位 |
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | 沿放置轴的对齐 |
| `avoidCollisions` | `boolean` | `true` | 靠近视口边缘时是否翻转 placement |
| `offset` | `number` | `9` | 与触发器的间距(像素) |
| `alignOffset` | `number` | `0` | 沿对齐轴的偏移(像素) |
| `disablePositioningStyle` | `boolean` | `false` | 是否禁用自动定位样式 |
| `forceMount` | `boolean` | - | 是否强制挂载 |
| `insets` | `Insets` | - | 定位时需遵守的屏幕边距 |
| `className` | `string` | - | 内容容器额外 class |
| `animation` | `PopupPopoverContentAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `asChild` | `boolean` | `false` | 是否将子元素作为实际渲染节点 |
| `...Animated.ViewProps` | `Animated.ViewProps` | - | 支持 Reanimated `Animated.View` 的全部属性 |
### Popover.Content(底部抽屉呈现)
| prop | type | default | description |
| --------------------------- | ---------------------- | ------- | -------------------------------- |
| `children` | `ReactNode` | - | 底部抽屉内容 |
| `presentation` | `'bottom-sheet'` | - | 呈现模式,须为 `bottom-sheet` 并与根一致(必填) |
| `contentContainerClassName` | `string` | - | 内容容器额外 class |
| `contentContainerProps` | `BottomSheetViewProps` | - | 内容容器属性 |
| `enablePanDownToClose` | `boolean` | `true` | 是否允许下滑关闭 |
| `backgroundStyle` | `ViewStyle` | - | 底部抽屉背景样式 |
| `handleIndicatorStyle` | `ViewStyle` | - | 把手指示器样式 |
| `...BottomSheetProps` | `BottomSheetProps` | - | 支持 `@gorhom/bottom-sheet` 的全部属性 |
#### PopupPopoverContentAnimation
内容(`popover` 呈现)动画配置,可为:
* `false` 或 `"disabled"`:禁用全部动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ---------- | ----------------------- | ------------------------------------------------ | ------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时用于禁用动画 |
| `entering` | `EntryOrExitLayoutType` | 默认关键帧:translateY/translateX、scale、opacity(200ms) | 自定义进入关键帧 |
| `exiting` | `EntryOrExitLayoutType` | 默认与进入镜像(150ms) | 自定义退出关键帧 |
### Popover.Arrow
| prop | type | default | description |
| --------------------- | ---------------------------------------- | ------- | ----------------------------- |
| `className` | `string` | - | 箭头额外 class |
| `height` | `number` | `12` | 箭头高度(像素) |
| `width` | `number` | `20` | 箭头宽度(像素) |
| `fill` | `string` | - | 填充色(默认与内容背景一致) |
| `stroke` | `string` | - | 描边色(默认与内容边框色一致) |
| `strokeWidth` | `number` | `1` | 描边宽度(像素) |
| `strokeBaselineInset` | `number` | `1` | 描边基线内缩(像素) |
| `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | - | 浮层方位(自内容继承) |
| `children` | `ReactNode` | - | 自定义箭头内容(替换默认 SVG) |
| `style` | `StyleProp` | - | 箭头容器额外样式 |
| `...ViewProps` | `ViewProps` | - | 支持全部标准 React Native `View` 属性 |
### Popover.Close
`Popover.Close` 继承 [CloseButton](./close-button),按下时自动关闭浮层。
### Popover.Title
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 标题文案 |
| `className` | `string` | - | 标题额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
### Popover.Description
| prop | type | default | description |
| -------------- | ----------- | ------- | ----------------------------- |
| `children` | `ReactNode` | - | 说明文案 |
| `className` | `string` | - | 说明额外 class |
| `...TextProps` | `TextProps` | - | 支持全部标准 React Native `Text` 属性 |
## Hooks
### usePopover
在自定义或复合子组件中读取浮层上下文。
```tsx
import { usePopover } from 'heroui-native';
const CustomContent = () => {
const { isOpen, onOpenChange, triggerPosition } = usePopover();
// …实现
};
```
#### 返回值
| property | type | description |
| -------------------- | --------------------------------------------------- | ----------- |
| `isOpen` | `boolean` | 当前是否打开 |
| `onOpenChange` | `(open: boolean) => void` | 修改展开状态的回调 |
| `isDefaultOpen` | `boolean \| undefined` | 默认是否打开(非受控) |
| `isDisabled` | `boolean \| undefined` | 是否禁用 |
| `triggerPosition` | `LayoutPosition \| null` | 触发器相对视口的位置 |
| `setTriggerPosition` | `(triggerPosition: LayoutPosition \| null) => void` | 更新触发器位置 |
| `contentLayout` | `LayoutRectangle \| null` | 浮层内容的布局测量 |
| `setContentLayout` | `(contentLayout: LayoutRectangle \| null) => void` | 更新内容布局测量 |
| `nativeID` | `string` | 当前实例唯一标识 |
**说明:** 必须在 `Popover` 内使用;在上下文外调用将抛错。
### usePopoverAnimation
在自定义或复合子组件中读取浮层动画共享值。
```tsx
import { usePopoverAnimation } from 'heroui-native';
const CustomContent = () => {
const { progress, isDragging } = usePopoverAnimation();
// …实现
};
```
#### 返回值
| property | type | description |
| ------------ | ---------------------- | -------------------- |
| `progress` | `SharedValue` | 动画进度(0=空闲,1=打开,2=关闭) |
| `isDragging` | `SharedValue` | 是否正在拖拽 |
**说明:** 必须在 `Popover` 内使用;在动画上下文外调用将抛错。
## 特别说明
### 元素检查器(iOS)
`Popover` 在 iOS 使用 `FullWindowOverlay`。开发时若需启用 React Native 元素检查器,可在 `Popover.Portal` 设置 `disableFullWindowOverlay={true}`。代价:浮层将无法叠在原生系统模态之上。
### 原生模态(iOS)
当 `Popover` 位于以原生模态形式呈现的页面内时(`presentation: 'modal' | 'formSheet' | 'pageSheet'`),浮层内容可能会向上偏移渲染。在新架构(Fabric)中,`react-native-screens` 将 `RNSModalScreen` 标记为 Fabric 根节点,因此触发器的坐标是相对于模态原点上报的,而 `FullWindowOverlay`(浮层挂载点)锚定在 iOS 应用窗口上。可通过将 `safeAreaInsets.top` 加到 `offset` 来补偿:
```tsx
import { useSafeAreaInsets } from 'react-native-safe-area-context';
const insets = useSafeAreaInsets();
...
;
```
# Toast 轻提示
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/toast
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(overlays)/toast.mdx
> 在屏幕顶部或底部展示的临时通知消息。
## 导入
```tsx
import { Toast, useToast } from 'heroui-native';
```
## 结构
```tsx
...
...
...
```
* **Toast**:主容器,负责定位、动画与滑动手势。
* **Toast.Title**:标题文字,继承父级 Toast 的变体样式。
* **Toast.Description**:标题下方的描述文字。
* **Toast.Action**:操作按钮;按钮变体默认随 Toast 变体推断,也可覆盖。
* **Toast.Close**:关闭按钮,图标按钮样式,按下时调用隐藏。
## 用法
### 用法一:简单字符串
使用纯字符串快速展示 Toast。
```tsx
const { toast } = useToast();
toast.show('这是一条 Toast 消息');
```
### 用法二:配置对象
通过配置对象传入标题、描述、变体与操作按钮等。
```tsx
const { toast } = useToast();
toast.show({
variant: 'success',
label: '套餐已升级',
description: '可继续使用 HeroUI Chat',
icon: ,
actionLabel: '关闭',
onActionPress: ({ hide }) => hide(),
});
```
### 用法三:自定义组件
使用完全自定义的组件以自由控制样式与布局。
```tsx
const { toast } = useToast();
toast.show({
component: (props) => (
自定义 Toast
这是一个自定义 Toast 组件
),
});
```
**说明**:Toast 条目会做性能相关的 memo。若需把外部状态(如加载中)传入自定义 Toast,不会自动随状态重渲染。请使用 React Context、全局状态或 ref 等方式让状态能传递到 Toast 内。
### 禁用全部动画
使用 `"disable-all"` 可禁用自身及子级(如 `Toast.Action` 内的 `Button`)的全部动画。
```tsx
const { toast } = useToast();
toast.show({
variant: 'success',
label: '操作完成',
description: '已禁用全部动画',
animation: 'disable-all',
});
```
自定义组件示例:
```tsx
const { toast } = useToast();
toast.show({
component: (props) => (
无动画
此 Toast 已禁用全部动画
操作
),
});
```
## 示例
```tsx
import { Button, Toast, useToast, useThemeColor } from 'heroui-native';
import { View } from 'react-native';
export default function ToastExample() {
const { toast } = useToast();
const themeColorForeground = useThemeColor('foreground');
return (
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/toast.tsx)。
## 全局配置
通过 `HeroUINativeProvider` 的 `config` 全局配置 Toast;本地调用可覆盖默认值。
> **说明**:Provider 的完整配置见 [Provider 文档](/docs/native/getting-started/handbook/provider#toast-configuration)。
### 边距(Insets)
控制 Toast 与屏幕边缘的距离,会在安全区内边距基础上叠加。例如四边距屏幕 20px:
```tsx
{children}
```
### 使用 KeyboardAvoidingView 包裹内容
用 `KeyboardAvoidingView` 包裹 Toast 内容,键盘弹出时自动避让:
```tsx
import {
KeyboardAvoidingView,
KeyboardProvider,
} from 'react-native-keyboard-controller';
import { HeroUINativeProvider } from 'heroui-native';
import { useCallback } from 'react';
function AppContent() {
const contentWrapper = useCallback(
(children: React.ReactNode) => (
{children}
),
[]
);
return (
{children}
);
}
```
### 默认属性
全局设置变体、位置、动画与滑动等默认值:
```tsx
{children}
```
## API 参考
### Toast
| prop | type | default | description |
| ----------------------- | ------------------------------------------------------------- | ----------- | ---------------------------- |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | 视觉变体 |
| `placement` | `'top' \| 'bottom'` | `'top'` | 在屏幕上的位置 |
| `isSwipeable` | `boolean` | `true` | 是否可滑动关闭并带橡皮筋拖拽效果 |
| `animation` | `ToastRootAnimation` | - | 动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `className` | `string` | - | Toast 容器额外 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部属性 |
#### ToastRootAnimation
Toast 根动画配置,可为:
* `false` 或 `"disabled"`:仅禁用根级动画
* `"disable-all"`:禁用全部动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在自定义属性时禁用动画 |
| `opacity.value` | `[number, number]` | `[1, 0]` | Toast 移出可视堆叠时的透明度插值 |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | 透明度过渡的时间配置 |
| `translateY.value` | `[number, number]` | `[0, 10]` | 堆叠 Toast 微位移效果的 Y 插值 |
| `translateY.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | translateY 过渡的时间配置 |
| `scale.value` | `[number, number]` | `[1, 0.97]` | 堆叠 Toast 景深缩放的插值 |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 300 }` | 缩放过渡的时间配置 |
| `entering.top` | `EntryOrExitLayoutType` | `FadeInUp`
`.springify()`
`.withInitialValues({ opacity: 1, transform: [{ translateY: -100 }] })`
`.mass(3)` | 顶部放置时的进入动画 |
| `entering.bottom` | `EntryOrExitLayoutType` | `FadeInDown`
`.springify()`
`.withInitialValues({ opacity: 1, transform: [{ translateY: 100 }] })`
`.mass(3)` | 底部放置时的进入动画 |
| `exiting.top` | `EntryOrExitLayoutType` | 关键帧动画
`translateY: -100, scale: 0.97, opacity: 0.5` | 顶部放置时的退出动画 |
| `exiting.bottom` | `EntryOrExitLayoutType` | 关键帧动画
`translateY: 100, scale: 0.97, opacity: 0.5` | 底部放置时的退出动画 |
### Toast.Title
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 标题内容 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### Toast.Description
| prop | type | default | description |
| -------------- | ----------------- | ------- | ---------------------------- |
| `children` | `React.ReactNode` | - | 描述内容 |
| `className` | `string` | - | 额外的 class |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部属性 |
### Toast.Action
`Toast.Action` 继承 [Button](button) 的全部属性。按钮变体默认由 Toast 变体推断,也可覆盖。
| prop | type | default | description |
| ----------- | ---------------------- | ------- | ----------------------- |
| `children` | `React.ReactNode` | - | 操作按钮文字 |
| `variant` | `ButtonVariant` | - | 按钮变体;未提供时由 Toast 变体自动决定 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | 操作按钮尺寸 |
| `className` | `string` | - | 额外的 class |
`onPress`、`isDisabled` 等其余属性见 [Button API 参考](button#api-reference)。
### Toast.Close
`Toast.Close` 继承 [Button](button) 的全部属性。
| prop | type | default | description |
| ----------- | ----------------------------------- | ------- | ---------------------- |
| `children` | `React.ReactNode` | - | 自定义关闭图标;默认使用 CloseIcon |
| `iconProps` | `{ size?: number; color?: string }` | - | 默认关闭图标的属性 |
| `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | 关闭按钮尺寸 |
| `className` | `string` | - | 额外的 class |
| `onPress` | `(event: any) => void` | - | 自定义按下处理;默认隐藏 Toast |
其余继承属性见 [Button API 参考](button#api-reference)。
### ToastProviderProps
通过 `HeroUINativeProvider` 的 `config.toast` 进行全局配置时可用的属性。
| prop | type | default | description |
| -------------------------------------------- | --------------------------------------------------- | ------- | ---------------------------------------------------------------------------- |
| `defaultProps` | `ToastGlobalConfig` | - | 全局默认配置,可被单次调用覆盖 |
| `disableFullWindowOverlay` | `boolean` | `false` | iOS 上为 true 时使用普通 `View` 替代 `FullWindowOverlay`,便于元素检查器;Toast 将不再叠在原生模态之上 |
| `unstable_accessibilityContainerViewIsModal` | `boolean` | `false` | 是否将覆盖窗口视为模态容器(VoiceOver)。为 true 时焦点限制在覆盖层内。仅 iOS;可能随 react-native-screens 变化 |
| `insets` | `ToastInsets` | - | 相对屏幕边缘的内边距(与安全区内边距相加) |
| `maxVisibleToasts` | `number` | `3` | 最大可见条数,超过后开始降低透明度 |
| `contentWrapper` | `(children: React.ReactNode) => React.ReactElement` | - | 自定义包裹 Toast 内容的函数 |
| `children` | `React.ReactNode` | - | 子节点 |
#### ToastGlobalConfig
全局默认,可被单次调用覆盖。
| prop | type | description |
| ------------- | ------------------------------------------------------------- | -------------- |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | 视觉变体 |
| `placement` | `'top' \| 'bottom'` | 位置 |
| `isSwipeable` | `boolean` | 是否可滑动关闭并带橡皮筋效果 |
| `animation` | `ToastRootAnimation` | Toast 动画配置 |
#### ToastInsets
相对屏幕边缘的间距,会与安全区内边距相加。
| prop | type | default | description |
| -------- | -------- | ------- | ---------------------------------- |
| `top` | `number` | - | 距顶部像素(叠加安全区)。平台默认:iOS 0,Android 12 |
| `bottom` | `number` | - | 距底部像素(叠加安全区)。平台默认:iOS 6,Android 12 |
| `left` | `number` | - | 距左侧像素(叠加安全区)。默认 12 |
| `right` | `number` | - | 距右侧像素(叠加安全区)。默认 12 |
## Hooks
### useToast
访问 Toast 能力,必须在 `ToastProvider` 内使用(由 `HeroUINativeProvider` 提供)。
| 返回值 | type | description |
| ---------------- | -------------- | ------------------------------ |
| `toast` | `ToastManager` | 含 `show`、`hide` 等方法的 Toast 管理器 |
| `isToastVisible` | `boolean` | 当前是否有 Toast 可见 |
#### ToastManager
| method | type | description |
| ------ | ------------------------------------------------- | ------------------------------------------------ |
| `show` | `(options: string \| ToastShowOptions) => string` | 显示 Toast,返回 ID。支持字符串、配置对象或自定义组件三种形式 |
| `hide` | `(ids?: string \| string[] \| 'all') => void` | 隐藏一条或多条。无参隐藏最后一条;`'all'` 隐藏全部;传入 ID 或 ID 数组隐藏指定项 |
#### ToastShowOptions
展示选项:默认样式的配置对象,或自定义组件。
**使用配置对象(无 `component`)时:**
| prop | type | default | description |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------ |
| `variant` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | - | 视觉变体 |
| `placement` | `'top' \| 'bottom'` | - | 位置 |
| `isSwipeable` | `boolean` | - | 是否可滑动关闭 |
| `animation` | `ToastRootAnimation \| false \| "disabled" \| "disable-all"` | - | 动画配置 |
| `duration` | `number \| 'persistent'` | `4000` | 自动隐藏毫秒数;`'persistent'` 表示不自动隐藏 |
| `id` | `string` | - | 可选 ID;未提供则自动生成 |
| `label` | `string` | - | 标题文字 |
| `description` | `string` | - | 描述文字 |
| `actionLabel` | `string` | - | 操作按钮文案 |
| `onActionPress` | `(helpers: { show: (options: string \| ToastShowOptions) => string; hide: (ids?: string \| string[] \| 'all') => void }) => void` | - | 操作按钮按下回调 |
| `icon` | `React.ReactNode` | - | 左侧图标 |
| `onShow` | `() => void` | - | 显示时回调 |
| `onHide` | `() => void` | - | 隐藏时回调 |
**使用自定义组件时:**
| prop | type | default | description |
| ----------- | ---------------------------------------------------- | ------- | ------------------------------ |
| `id` | `string` | - | 可选 ID;未提供则自动生成 |
| `component` | `(props: ToastComponentProps) => React.ReactElement` | - | 接收 Toast props 并返回 React 元素的函数 |
| `duration` | `number \| 'persistent'` | `4000` | 自动隐藏毫秒数;`'persistent'` 表示不自动隐藏 |
| `onShow` | `() => void` | - | 显示时回调 |
| `onHide` | `() => void` | - | 隐藏时回调 |
## 特别说明
### 元素检查器(iOS)
Toast 在 iOS 上使用 `FullWindowOverlay`。开发时若需使用 React Native 元素检查器,可在 `HeroUINativeProvider` 的 `config.toast` 中设置 `disableFullWindowOverlay={true}`。代价:Toast 将无法叠在原生系统模态之上。
# Typography 文本
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/text
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(typography)/text.mdx
> 用于渲染带语义类型变体的样式化文本的排版基元组件。
## 导入
```tsx
import { Typography } from 'heroui-native';
```
## 结构
```tsx
...
{/* 子组件 */}
...
...
...
```
* **Typography**:文本根元素。通过 `type` 选择排版预设,并提供互不耦合的 `align`、`color`、`weight`、`truncate` 属性。
* **Typography.Heading**:限定为标题类型(`h1`–`h6`)的便捷包装组件,会自动添加 `accessibilityRole="header"`。
* **Typography.Paragraph**:限定为正文类型(`body`、`body-sm`、`body-xs`)的便捷包装组件。
* **Typography.Code**:以 chip 样式呈现的等宽内联文本,采用平台合适的等宽字体。
## 用法
### 基础用法
`Typography` 默认渲染正文文本。
```tsx
Hello, world!
```
### 类型变体
使用 `type` 属性选择语义化排版预设。
```tsx
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Body text
Small body text
Extra-small body text
Code snippet
```
### 标题
使用 `Typography.Heading` 渲染标题文本,自动具备 header 无障碍角色。
```tsx
Page Title
Section Title
Subsection Title
```
### 段落
使用 `Typography.Paragraph` 渲染正文文本。
```tsx
这是一个使用默认尺寸渲染的正文段落。
这是较小的正文文本。
```
### 代码
使用 `Typography.Code`(或等价的 ``)渲染内联代码片段。两者都会呈现为 chip 样式的等宽内联元素,带有低饱和背景、圆角,并采用 `self-start` 布局以避免在 flex 容器中被拉伸。平台相关的等宽 `fontFamily` 在 `Typography` 根元素上应用,因此两种写法可互换。
```tsx
console.log('hello')
console.log('hello')
```
### 对齐
使用 `align` 属性控制水平对齐。`start` 与 `end` 是 RTL 感知的(在从右到左布局下会翻转)。
```tsx
Start-aligned
Center-aligned
End-aligned
Justified text spreads across the line.
```
> **说明:** `text-justify` 在 React Native 中仅 iOS 生效;Android 会回退为左对齐。
### 颜色
使用 `color` 属性应用语义化前景色预设。
```tsx
Default foreground
Muted secondary text
```
如需其他主题色,可通过 `className` 传入对应工具类(如 `className="text-accent"`、`className="text-danger"`)。
### 字重
使用 `weight` 属性覆盖由 `type` 推导出的字重。该覆盖通过 `tailwind-merge` 合并,因此始终优先于 type 变体的默认字重。
```tsx
Bold H1
Medium body
Semibold body
```
### 截断
使用布尔属性 `truncate` 将文本限制为单行并以省略号结尾。它映射到 React Native 的 `numberOfLines={1}`。如显式提供 `numberOfLines`,则以后者为准。
```tsx
当内容溢出容器时,这一长行文本会被截断并显示省略号。
;
{
/* 通过底层 RN 属性实现多行截断 */
}
通过 React Native 标准的 `numberOfLines` 属性可实现多行截断。
;
```
## 示例
```tsx
import { Typography } from 'heroui-native';
import { View } from 'react-native';
export default function TypographyExample() {
return (
欢迎
快速开始
这是使用 Typography 组件渲染的正文段落。
用于注释或脚注的较小辅助文本。
npm install heroui-native
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/text.tsx)。
## API 参考
### Typography
`Typography` 继承 React Native 的全部 `TextProps`,并新增排版相关属性。
| prop | type | default | description |
| -------------- | -------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------- |
| `type` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6' \| 'body' \| 'body-sm' \| 'body-xs' \| 'code'` | `'body'` | 语义化排版变体(字号、默认字重、行高) |
| `align` | `'start' \| 'center' \| 'end' \| 'justify'` | `'start'` | 水平对齐方式。`start` 与 `end` 为 RTL 感知;`justify` 仅 iOS 生效 |
| `color` | `'default' \| 'muted'` | `'default'` | 语义化前景色预设 |
| `weight` | `'normal' \| 'medium' \| 'semibold' \| 'bold'` | - | 字重覆盖。设置后会覆盖 `type` 暗含的字重 |
| `truncate` | `boolean` | `false` | 将文本截断为单行并显示省略号(即设 `numberOfLines={1}`)。显式 `numberOfLines` 优先级更高 |
| `children` | `React.ReactNode` | - | 渲染内容 |
| `className` | `string` | - | 额外 CSS 类 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Typography.Heading
继承 `Typography` 根元素的全部属性(`align`、`color`、`weight`、`truncate`、`className` 及 React Native `TextProps`)。自动设置 `accessibilityRole="header"`,并将 `type` 收窄为标题变体。
| prop | type | default | description |
| -------------- | ---------------------------------------------- | ------- | ------------------------------ |
| `type` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h1'` | 标题级别 |
| `children` | `React.ReactNode` | - | 渲染内容 |
| `className` | `string` | - | 额外 CSS 类 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Typography.Paragraph
继承 `Typography` 根元素的全部属性(`align`、`color`、`weight`、`truncate`、`className` 及 React Native `TextProps`)。将 `type` 收窄为正文变体。
| prop | type | default | description |
| -------------- | ---------------------------------- | -------- | ------------------------------ |
| `type` | `'body' \| 'body-sm' \| 'body-xs'` | `'body'` | 段落文本字号 |
| `children` | `React.ReactNode` | - | 渲染内容 |
| `className` | `string` | - | 额外 CSS 类 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
### Typography.Code
继承 `Typography` 根元素的全部属性(`align`、`color`、`weight`、`truncate`、`className`、`style` 及 React Native `TextProps`)。它是一个强制 `type="code"` 的轻量包装;平台相关的等宽 `fontFamily` 在 `Typography` 根元素上合并,因此 `` 与 `` 渲染效果完全一致。
| prop | type | default | description |
| -------------- | ----------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode` | - | 渲染内容 |
| `className` | `string` | - | 额外 CSS 类 |
| `...TextProps` | `TextProps` | - | 支持 React Native `Text` 的全部标准属性 |
# PressableFeedback 按压反馈
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/pressable-feedback
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(utilities)/pressable-feedback.mdx
> 为按压交互提供视觉反馈的容器组件,内置缩放动画。
## 导入
```tsx
import { PressableFeedback } from 'heroui-native';
```
## 结构
```tsx
...
```
* **PressableFeedback**:内置缩放动画的可按压容器;管理按压状态与容器尺寸,并通过上下文提供给子复合部件。使用 `PressableFeedback.Scale` 时可将 `animation={false}` 关闭根级内置缩放。
* **PressableFeedback.Scale**:对特定子元素应用缩放的包装层;需要精确控制哪个元素缩放,或要在缩放层上直接应用 `className` / `style` 时使用。
* **PressableFeedback.Highlight**:iOS 风格的高亮遮罩,绝对定位,在按压时淡入。
* **PressableFeedback.Ripple**:Android 风格的涟漪,从触点扩展的径向渐变圆。
## 用法
### 基础
默认提供按下缩放反馈,多数场景推荐直接使用。
```tsx
...
```
### 配合 Highlight
在默认缩放之外叠加 iOS 风格高亮。
```tsx
...
```
### 配合 Ripple
在默认缩放之外叠加 Android 风格涟漪。
```tsx
...
```
### 自定义缩放动画
通过根组件 `animation.scale` 配置,支持 `value`、`timingConfig`、`ignoreScaleCoefficient`。
```tsx
...
```
### 自定义 Highlight 动画
配置高亮层的不透明度与背景色。
```tsx
...
```
### 自定义 Ripple 动画
配置涟漪颜色、不透明度与时长。
```tsx
...
```
### 对指定子元素缩放(PressableFeedback.Scale)
需要对容器内某一子元素而非根节点缩放时,将根组件设为 `animation={false}` 关闭内置缩放,再使用 `PressableFeedback.Scale`,以便在缩放层上直接应用 `className` / `style`。
```tsx
...
```
可与 `Highlight` 或 `Ripple` 组合在 `Scale` 内:
```tsx
...
```
### 禁用全部动画
根上设置 `animation="disable-all"` 可级联禁用内置缩放及子复合部件(Scale、Highlight、Ripple)的动画。
```tsx
...
```
也可在保留缩放配置的同时禁用动画(例如运行时切换):
```tsx
...
```
## 示例
```tsx
import { PressableFeedback, Card, Button } from 'heroui-native';
import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet, View, Text } from 'react-native';
export default function PressableFeedbackExample() {
return (
Neo
家用机器人
即将开售
订阅通知
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/pressable-feedback.tsx)。
## API 参考
### PressableFeedback
| prop | type | default | description |
| ----------------------- | -------------------------------- | ------- | --------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | 需要包裹按压反馈的内容 |
| `isDisabled` | `boolean` | `false` | 是否禁用 |
| `className` | `string` | - | 额外的 class |
| `animation` | `PressableFeedbackRootAnimation` | - | 通过 `{ scale: ... }` 自定义缩放;`false` 关闭根级缩放;`'disable-all'` 级联禁用全部 |
| `isAnimatedStyleActive` | `boolean` | `true` | 根内置动画样式是否启用 |
| `asChild` | `boolean` | `false` | 是否以子元素方式渲染 |
| `...rest` | `AnimatedProps` | - | 支持 Reanimated `Animated` `Pressable` 的属性 |
#### PressableFeedbackRootAnimation
根 `animation` 遵循标准 `AnimationRoot` 控制流:
* `true` 或 `undefined`:使用默认内置缩放
* `false` 或 `"disabled"`:关闭根内置缩放(改用 `PressableFeedback.Scale` 时)
* `"disable-all"`:级联禁用全部动画(含内置缩放与子级 Scale、Highlight、Ripple)
* `object`:自定义内置缩放
| prop | type | default | description |
| ------- | ---------------------------------------- | ------- | ----------------------------- |
| `scale` | `PressableFeedbackScaleAnimation` | - | 自定义内置缩放(value、timingConfig 等) |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 在保留配置的同时控制动画状态(例如运行时开关) |
### PressableFeedback.Scale
对容器内指定子元素应用缩放时使用;根上设 `animation={false}` 以关闭其内置缩放。
| prop | type | default | description |
| ----------------------- | --------------------------------- | ------- | --------------------------------- |
| `className` | `string` | - | 额外的 class |
| `animation` | `PressableFeedbackScaleAnimation` | - | 缩放动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `style` | `ViewStyle` | - | 额外样式 |
| `...AnimatedProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 的属性 |
#### PressableFeedbackScaleAnimation
缩放动画配置,可为:
* `false` 或 `"disabled"`:禁用缩放动画
* `true` 或 `undefined`:使用默认缩放动画
* `object`:自定义缩放配置
| prop | type | default | description |
| ------------------------ | ----------------------- | ---------------------------------------------------- | ----------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `value` | `number` | `0.985` | 按下时的缩放值(会随容器宽度自动调整) |
| `timingConfig` | `WithTimingConfig` | `{ duration: 300, easing: Easing.out(Easing.ease) }` | 时间曲线配置 |
| `ignoreScaleCoefficient` | `boolean` | `false` | 为 true 时忽略自动缩放系数,直接使用 `value` |
### PressableFeedback.Highlight
| prop | type | default | description |
| ----------------------- | ------------------------------------- | ------- | --------------------------------- |
| `className` | `string` | - | 额外的 class |
| `animation` | `PressableFeedbackHighlightAnimation` | - | 高亮层动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `style` | `ViewStyle` | - | 额外样式 |
| `...AnimatedProps` | `AnimatedProps` | - | 支持 Reanimated `Animated.View` 的属性 |
#### PressableFeedbackHighlightAnimation
高亮层动画配置,可为:
* `false` 或 `"disabled"`:禁用高亮动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ----------------------- | ----------------------- | ------------------- | --------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `opacity.value` | `[number, number]` | `[0, 0.1]` | 不透明度 \[未按下, 按下] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | 时间曲线配置 |
| `backgroundColor.value` | `string` | 随主题灰色 | 高亮层背景色 |
### PressableFeedback.Ripple
| prop | type | default | description |
| ----------------------- | ----------------------------------------- | ------- | --------------------------- |
| `className` | `string` | - | 容器插槽的 class |
| `classNames` | `ElementSlots` | - | 各插槽 class(container、ripple) |
| `styles` | `Partial>` | - | 涟漪遮罩各部分的样式 |
| `animation` | `PressableFeedbackRippleAnimation` | - | 涟漪动画配置 |
| `isAnimatedStyleActive` | `boolean` | `true` | 是否启用 Reanimated 动画样式 |
| `...ViewProps` | `Omit` | - | 支持 `View` 属性(不含 `style`) |
#### `styles`
| prop | type | description |
| ----------- | ----------- | ----------- |
| `container` | `ViewStyle` | 容器插槽样式 |
| `ripple` | `ViewStyle` | 涟漪插槽样式 |
#### PressableFeedbackRippleAnimation
涟漪动画配置,可为:
* `false` 或 `"disabled"`:禁用涟漪动画
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| ------------------------------------ | -------------------------- | ------------------- | ------------------------- |
| `state` | `'disabled' \| boolean` | - | 在自定义属性时禁用动画 |
| `backgroundColor.value` | `string` | 随主题计算 | 涟漪背景色 |
| `progress.baseDuration` | `number` | `1000` | 涟漪进度基准时长(会按对角线自动调整) |
| `progress.minBaseDuration` | `number` | `750` | 进度动画最小时长 |
| `progress.ignoreDurationCoefficient` | `boolean` | `false` | 为 true 时忽略自动时长系数,直接使用基准时长 |
| `opacity.value` | `[number, number, number]` | `[0, 0.1, 0]` | 不透明度 \[起始, 峰值, 结束] |
| `opacity.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | 时间曲线配置 |
| `scale.value` | `[number, number, number]` | `[0, 1, 1]` | 缩放 \[起始, 峰值, 结束] |
| `scale.timingConfig` | `WithTimingConfig` | `{ duration: 200 }` | 时间曲线配置 |
#### `ElementSlots`
涟漪各插槽的额外 class:
| slot | description |
| ----------- | ----------------------------------------------------------------------- |
| `container` | 外层容器(`absolute inset-0`),可通过 class 完全定制样式 |
| `ripple` | 内层涟漪(`absolute top-0 left-0 rounded-full`),带动画属性,不宜用 className 覆盖动画相关表现 |
# ScrollShadow 滚动阴影
**Category**: native
**URL**: https://www.heroui.com/cn/docs/native/components/scroll-shadow
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/cn/native/components/(utilities)/scroll-shadow.mdx
> 根据滚动位置与溢出情况,为可滚动内容添加动态渐变边缘阴影。
## 导入
```tsx
import { ScrollShadow } from 'heroui-native';
```
## 结构
```tsx
...
```
* **ScrollShadow**:包裹可滚动组件,按滚动位置与内容溢出在边缘显示动态渐变阴影;自动识别横向/纵向滚动并管理阴影显隐。
* **LinearGradientComponent**:必填,传入兼容库的 `LinearGradient`(如 expo-linear-gradient、react-native-linear-gradient)以绘制渐变阴影。
## 用法
### 基础用法
包裹任意可滚动组件,自动在边缘添加阴影。
```tsx
...
```
### 横向滚动
根据子组件的 `horizontal` 属性自动识别横向滚动。
```tsx
```
### 自定义阴影尺寸
用 `size` 控制渐变阴影的高度或宽度(像素)。
```tsx
...
```
### 显隐控制
用 `visibility` 指定显示哪些边的阴影。
```tsx
...
...
...
```
### 自定义阴影颜色
覆盖默认使用主题背景的阴影颜色。
```tsx
...
```
### 自定义滚动处理
**重要:** ScrollShadow 内部会将子节点转为 Reanimated 动画组件。若需使用 `onScroll`,必须使用 `react-native-reanimated` 的 `useAnimatedScrollHandler`,而不能使用普通的 `onScroll`。
```tsx
import { LinearGradient } from 'expo-linear-gradient';
import Animated, { useAnimatedScrollHandler } from 'react-native-reanimated';
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
console.log(event.contentOffset.y);
},
});
...
;
```
## 示例
```tsx
import { ScrollShadow, Surface } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { FlatList, ScrollView, Text, View } from 'react-native';
export default function ScrollShadowExample() {
const horizontalData = Array.from({ length: 10 }, (_, i) => ({
id: i,
title: `Card ${i + 1}`,
}));
return (
Horizontal List
(
{item.title}
)}
showsHorizontalScrollIndicator={false}
contentContainerClassName="p-5 gap-4"
/>
Vertical Content
Long Content
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
ad minim veniam, quis nostrud exercitation ullamco laboris.
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
quae ab illo inventore veritatis et quasi architecto beatae vitae.
);
}
```
更多示例见 [GitHub 仓库](https://github.com/heroui-inc/heroui-native/blob/main/example/src/app/\(home\)/components/scroll-shadow.tsx)。
## API 参考
### ScrollShadow
| prop | type | default | description |
| ------------------------- | ---------------------------------------------------------------------- | -------- | ------------------------------------------------- |
| `children` | `React.ReactElement` | - | 需要增强阴影的可滚动组件,须为单一 React 元素(ScrollView、FlatList 等) |
| `LinearGradientComponent` | `ComponentType<`
`LinearGradientProps>` | **必填** | 来自任意兼容库的 LinearGradient 组件 |
| `size` | `number` | `50` | 渐变阴影高度或宽度(像素) |
| `orientation` | `'horizontal' \| 'vertical'` | 自动检测 | 阴影方向;未提供时根据子组件 `horizontal` 自动检测 |
| `visibility` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right' \| 'both' \| 'none'` | `'auto'` | 阴影显隐模式;`auto` 根据滚动位置与溢出自动显示 |
| `color` | `string` | 主题色 | 渐变阴影自定义颜色;未提供时使用主题背景色 |
| `isEnabled` | `boolean` | `true` | 是否启用阴影效果 |
| `animation` | `ScrollShadowRootAnimation` | - | 动画配置 |
| `className` | `string` | - | 容器额外 class |
| `...ViewProps` | `ViewProps` | - | 支持 React Native `View` 的全部标准属性 |
#### ScrollShadowRootAnimation
ScrollShadow 动画配置,可为:
* `false` 或 `"disabled"`:仅关闭根动画
* `"disable-all"`:关闭所有动画(含子级)
* `true` 或 `undefined`:使用默认动画
* `object`:自定义动画配置
| prop | type | default | description |
| --------------- | ---------------------------------------- | -------- | --------------------------- |
| `state` | `'disabled' \| 'disable-all' \| boolean` | - | 关闭动画的同时仍允许自定义属性 |
| `opacity.value` | `[number, number]` | `[0, 1]` | 不透明度 \[初始, 激活];底部/右侧阴影时顺序相反 |
### LinearGradientProps
`LinearGradientComponent` 应接受以下属性:
| prop | type | description |
| ----------- | -------------------------- | ----------------------- |
| `colors` | `any` | 渐变颜色数组 |
| `locations` | `any`(可选) | 各颜色停靠位置 |
| `start` | `any`(可选) | 渐变起点,如 `{ x: 0, y: 0 }` |
| `end` | `any`(可选) | 渐变终点,如 `{ x: 1, y: 0 }` |
| `style` | `StyleProp`(可选) | 应用于渐变视图的样式 |
## 特别说明
**重要:** ScrollShadow 内部会将子节点转为 Reanimated 动画组件。若需在可滚动组件上使用滚动回调,必须使用 `react-native-reanimated` 的 `useAnimatedScrollHandler`,不能使用标准 `onScroll`。