Beta 13
TextArea component, Button outline variant, Tabs improvements, form component decomposition, popup animation refactor, style class exports, and critical bug fixes
Beta 13 introduces the TextArea component for multiline text input, adds Button outline variant, and exports style class names for all components. This release also includes significant improvements to Tabs with better animations and clearer variant naming, decomposes form components into standalone primitives for better flexibility, refactors popup animation system for improved consistency and Android compatibility, and fixes critical issues including Chinese character input handling, theme color calculations, Uniwind Pro compatibility, BottomSheet opening issues, and tree-shaking support. These updates enhance developer experience and component reliability across the library.
Installation
Update to the latest version:
npm i heroui-native@betapnpm add heroui-native@betayarn add heroui-native@betabun add heroui-native@betaUsing AI assistants? Simply prompt "Hey Cursor, update HeroUI Native to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the HeroUI Native MCP Server.
Try It Out
Experience all the Beta 13 improvements in action with our preview app! You can explore the new TextArea and CloseButton components, along with Button outline variant, Tabs improvements, granular exports, and all the bug fixes directly on your device.
Prerequisites
Make sure you have the latest version of Expo Go installed on your mobile device.
How to Access
Option 1: Scan the QR Code
Use your device's camera or Expo Go app to scan:

Note for Android users: If scanning the QR code with your device's camera or other scanner apps redirects to a browser and shows a 404 error, open Expo Go first and use its built-in QR scanner instead.
Option 2: Click the Link
This will automatically open the app in Expo Go if it's installed on your device.
What's New
New Components
This release introduces 3 new essential components:
- TextArea: Multiline text input component with styled border and background for collecting longer user input.
- Input: Single-line text input component with styled border and background, now available as a standalone component separate from TextField.
- CloseButton: Reusable button component for closing dialogs, modals, or dismissing content with consistent styling across overlay components.
TextArea
The TextArea component provides a complete solution for multiline text input scenarios, such as comments, messages, descriptions, and longer form fields. It features seamless integration with TextField for complete form structure, validation state support, and customizable variants for different visual contexts.
Features:
- Multiline text input with customizable rows
- Seamless integration with TextField component
- Validation state support with visual feedback
- Primary and secondary variants for different contexts
- Disabled and read-only states
- Customizable styling via className and styles props
- Complete accessibility support
Usage:
import { Description, Label, TextArea, TextField } from "heroui-native";
export function Example() {
return (
<TextField>
<Label>Message</Label>
<TextArea placeholder="Enter your message here..." />
<Description>Please provide as much detail as possible.</Description>
</TextField>
);
}For complete documentation and examples, see the TextArea component page.
Related PR: #254
Input
The Input component is now available as a standalone component, providing single-line text input functionality with styled border and background. Previously available only as TextField.Input, Input can now be used independently or integrated with form components like TextField and ControlField.
Features:
- Single-line text input with styled border and background
- Standalone usage or integration with form components
- Validation state support with visual feedback
- Primary and secondary variants for different contexts
- Disabled and read-only states
- Customizable styling via className and styles props
- Complete accessibility support
Usage:
import { Description, Input, Label, TextField } from "heroui-native";
export function Example() {
return (
<TextField>
<Label>Email</Label>
<Input placeholder="Enter your email..." />
<Description>We'll never share your email.</Description>
</TextField>
);
}For complete documentation and examples, see the Input component page.
Related PR: #247
CloseButton
The CloseButton component provides a reusable solution for closing dialogs, modals, popovers, and other overlay components. It features consistent styling across all overlay components, customizable icon properties, and seamless integration with Dialog, Popover, Select, and Bottom Sheet components.
Features:
- Consistent close button styling across overlay components
- Customizable icon size and color
- Support for custom children to replace default icon
- Disabled state support
- Seamless integration with Dialog, Popover, Select, and Bottom Sheet
- Default styling optimized for overlay contexts
Usage:
import { CloseButton } from "heroui-native";
// Standalone usage
<CloseButton onPress={handleClose} />
// As part of Dialog, Popover, Select, Bottom Sheet
<Dialog>
<Dialog.Close />
</Dialog>For complete documentation and examples, see the CloseButton component page.
Related PR: #237
New Subcomponents
Tabs.Separator
The Tabs component now includes a new Separator subcomponent that provides animated visibility control between tab triggers. This allows developers to create visual separators that automatically show or hide based on the active tab state.
Features:
- Animated visibility transitions based on active tab
- Configurable visibility via
betweenValuesprop - Customizable animation timing and opacity
- Always visible option for static separators
Usage:
import { Tabs } from "heroui-native";
<Tabs value={activeTab} onValueChange={setActiveTab}>
<Tabs.List>
<Tabs.ScrollView>
<Tabs.Indicator />
<Tabs.Trigger value="general">
<Tabs.Label>General</Tabs.Label>
</Tabs.Trigger>
<Tabs.Separator betweenValues={["general", "notifications"]} />
<Tabs.Trigger value="notifications">
<Tabs.Label>Notifications</Tabs.Label>
</Tabs.Trigger>
</Tabs.ScrollView>
</Tabs.List>
</Tabs>Related PR: #228
Component Improvements
Button Outline Variant
The Button component now includes an outline variant that provides a bordered style with transparent background, offering more visual variety for button designs.
Improvements:
- New
outlinevariant for bordered button style - Consistent styling with other Button variants
- Proper hover and focus states for outline variant
- Seamless integration with existing Button API
Usage:
import { Button } from "heroui-native";
<Button variant="outline">Outline Button</Button>Related PR: #235
Tabs Indicator Animation Refactor
The Tabs component's indicator animation has been refactored to use translateX transforms instead of width/height animations, resulting in smoother and more performant tab indicator transitions.
Improvements:
- Migrated indicator animation to
translateXtransforms - Improved animation performance and smoothness
- Better visual consistency during tab transitions
- Reduced layout recalculations during animations
Related PR: #227
Popover Arrow Sizing and Visual Connection
The Popover component has been improved with better arrow sizing and visual connection to the popover content, creating a more cohesive visual appearance.
Improvements:
- Improved arrow sizing relative to popover content
- Enhanced visual connection between arrow and popover
- Better alignment and spacing
- More polished overall appearance
Related PR: #243
Form Components Decomposition
Form components have been decomposed into standalone primitives, providing developers with more flexibility and better control over component composition.
Improvements:
- Decomposed form components into standalone primitives
- Improved component reusability and composition
- Better separation of concerns
- Enhanced flexibility for custom form layouts
Related PR: #247
Input Android Shadow Fix
The Input component now includes platform-specific shadow styling for Android, ensuring consistent visual appearance across platforms.
Improvements:
- Added platform-specific shadow for Android
- Improved visual consistency across iOS and Android
- Better elevation appearance on Android devices
- Enhanced component appearance on Android platform
Related PR: #248
Popup Animation System Refactor
The animation system for popup components (Popover, Select, Dialog, BottomSheet) has been refactored to improve entering/exiting animation logic, overlay composition, and content animation handling. This change standardizes animation behavior across all popup components and fixes Android pointer events issues.
Improvements:
- Standardized entering/exiting animations using FadeInDown/FadeOutDown for dialog presentations
- Refactored overlay animation hooks to support both progress-based and entering/exiting animations
- Improved overlay composition using Dialog.Overlay and Popover.Overlay components instead of Pressable wrappers
- Fixed Android pointer events issue affecting popup interactions
- Made presentation prop explicit in examples (popover, dialog, bottom-sheet)
- Simplified animation API for better maintainability and consistency
Related PR: #263
API Enhancements
Granular Exports for Bundle Optimization
The library now provides granular exports for each component, allowing developers to reduce bundle size by importing only the components they need.
New Capability:
// Granular imports - use when you need only a few components
import { HeroUINativeProvider } from "heroui-native/provider";
import { Button } from "heroui-native/button";
import { Card } from "heroui-native/card";
// General import - imports the whole library, use when you're using many components
import { Button, Card } from "heroui-native";Granular imports are ideal when you only need a few components, as they help keep your bundle size smaller. General imports from heroui-native will include the entire library, which is convenient when you're using many components throughout your app.
Available granular exports:
heroui-native/provider- Provider componentheroui-native/[component-name]- Individual componentsheroui-native/portal- Portal utilitiesheroui-native/utils- Utility functionsheroui-native/hooks- Custom hooks
Important: To keep the bundle size under control, you must follow the pattern with granular imports consistently. Even one general import from heroui-native will break this optimization strategy.
Related PR: #233
Style Class Names Export
All components now export their style class names, enabling developers to reference component styles programmatically and create custom styling solutions.
New Capability:
import { buttonClassNames } from "heroui-native";
// Access component class names programmatically
const customStyles = {
base: buttonClassNames.base,
variant: buttonClassNames.variant,
};This enhancement provides developers with programmatic access to component class names, enabling advanced styling scenarios and custom theme implementations.
Related PR: #252
Style Fixes
Style Optimizations
- Quaternary Variant Removal: Removed quaternary variant and polished component styles for better consistency
- Component Style Polish: Enhanced styling across multiple components for improved visual consistency
- Shadow and Border Radius Updates: Improved shadow and border radius consistency across components
- Theme Variable Cleanup: Simplified theme variables and removed redundant color-mix calculations
Related PR: #246
⚠️ Breaking Changes
Tabs Variant Prop Rename
The Tabs component's variant prop has been renamed from pill/line to primary/secondary for better clarity and consistency with other components.
Migration:
Update all instances of Tabs variant prop:
// Before
<Tabs variant="pill">
{/* content */}
</Tabs>
<Tabs variant="line">
{/* content */}
</Tabs>
// After
<Tabs variant="primary">
{/* content */}
</Tabs>
<Tabs variant="secondary">
{/* content */}
</Tabs>Available options:
"primary"- Primary variant (previously"pill")"secondary"- Secondary variant (previously"line")
Related PR: #236
Tabs Indicator Animation Refactor
The Tabs component's indicator animation has been refactored to use translateX transforms instead of left positioning for GPU-accelerated performance. This change improves animation performance but requires updates to custom animation configurations.
Migration:
If you have customized the Tabs indicator animation, update your animation configuration:
// Before
<Tabs
indicatorAnimation={{
left: {
type: "spring",
config: { damping: 20, stiffness: 300 }
}
}}
>
{/* content */}
</Tabs>
// After
<Tabs
indicatorAnimation={{
translateX: {
type: "spring",
config: { damping: 20, stiffness: 300 }
}
}}
>
{/* content */}
</Tabs>What Changed:
- Animation API changed from
lefttotranslateXinTabsIndicatorAnimationconfiguration - Indicator positioning now uses
translateXtransform for GPU-accelerated animations - Added
left-0base class to indicator styles to maintain initial positioning - Visual behavior remains identical, only the underlying implementation has changed
Related PR: #227
Divider Component Rename
The Divider component has been renamed to Separator for better consistency with naming conventions and to avoid confusion with other divider implementations.
Migration:
Update all imports and usages:
// Before
import { Divider } from "heroui-native";
<Divider />
// After
import { Separator } from "heroui-native";
<Separator />Related PR: #238
Quaternary Variant Removal
The quaternary variant has been removed from Surface and Card components to simplify the design system and improve consistency.
Migration:
Update any components using the quaternary variant:
// Before
<Surface variant="quaternary">
{/* content */}
</Surface>
<Card variant="quaternary">
{/* content */}
</Card>
// After
// Use default, secondary, or tertiary variants, or apply custom styling
<Surface variant="secondary">
{/* content */}
</Surface>
<Card variant="secondary">
{/* content */}
</Card>
// Or use custom styling for specific needs
<Surface className="bg-custom-quaternary">
{/* content */}
</Surface>Available variants:
"default"- Default surface styling"secondary"- Secondary surface styling"tertiary"- Tertiary surface styling
Related PR: #246
Form Component Decomposition
As part of the form component decomposition, several components have been renamed and restructured to provide better flexibility and composition patterns.
Component Renames:
FormFieldhas been renamed toControlFieldErrorViewhas been renamed toFieldError
Migration:
Update all imports and usages:
// Before
import { FormField, ErrorView, TextField } from "heroui-native";
<FormField>
<TextField.Input />
<ErrorView>Error message</ErrorView>
</FormField>
// After
import { ControlField, FieldError, Input, TextField } from "heroui-native";
<ControlField>
<Input />
<FieldError>Error message</FieldError>
</ControlField>TextField.Input Removal:
The TextField.Input subcomponent has been removed. Use the standalone Input component instead:
// Before
import { TextField } from "heroui-native";
<TextField>
<TextField.Input placeholder="Enter text..." />
</TextField>
// After
import { Input, TextField } from "heroui-native";
<TextField>
<Input placeholder="Enter text..." />
</TextField>Component Composition Changes:
RadioGroup, TextField, and ControlField now use Label, Description, and FieldError components directly, providing more flexible composition:
import { ControlField, Description, FieldError, Input, Label, RadioGroup, TextField } from "heroui-native";
// TextField with Label, Description, and FieldError
<TextField>
<Label>Email</Label>
<Input placeholder="Enter email..." />
<Description>We'll never share your email.</Description>
<FieldError>Invalid email address</FieldError>
</TextField>
// RadioGroup with Label, Description, and FieldError
<RadioGroup>
<Label>Select option</Label>
<RadioGroup.Item value="option1">
<RadioGroup.Label>Option 1</RadioGroup.Label>
</RadioGroup.Item>
<Description>Choose one option</Description>
<FieldError>Please select an option</FieldError>
</RadioGroup>
// ControlField with Label, Description, and FieldError
<ControlField>
<Label>Custom Field</Label>
<Input placeholder="Enter value..." />
<Description>Additional information</Description>
<FieldError>Validation error</FieldError>
</ControlField>Related PR: #247
CloseButton Component and asChild Removal
A new reusable CloseButton component has been introduced, and all close button implementations across Dialog, Popover, Select, and BottomSheet components have been refactored to use this shared component. The asChild prop has been removed from all Close components.
Migration:
Update any usage of asChild prop on Close components:
// Before
import { Button, Dialog } from "heroui-native";
<Dialog>
<Dialog.Close asChild>
<Button>Cancel</Button>
</Dialog.Close>
</Dialog>
// After
import { Button, Dialog } from "heroui-native";
const [isOpen, setIsOpen] = useState(false);
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<Button onPress={() => setIsOpen(false)}>Cancel</Button>
</Dialog>What Changed:
- New
CloseButtoncomponent added with defaultvariant="tertiary",size="sm", andisIconOnly={true} Dialog.Close,Popover.Close,Select.Close, andBottomSheet.Closenow extendCloseButtoninternally- The
asChildprop has been removed from all Close components - Close components still support all Button props including
variant,size,iconProps, and customchildren - You must now handle close logic manually when using custom buttons instead of Close components
Related PR: #237
Popup Animation System Refactor
The animation system for popup components has been refactored, resulting in several API changes that require code updates.
Migration:
- Remove
closeDelayandisDismissKeyboardOnCloseprops fromDialog.Root - Remove custom
entering/exitinganimation configs fromDialog.Rootanimation prop (now only supports disable flags). Custom animations should be configured using Keyframe animations directly onDialog.Contentcomponent - Remove
isAnimatedStyleActiveandonLayoutprops fromDialog.Content - Remove
isDismissKeyboardOnCloseprop fromBottomSheet.Root - Update
BottomSheet.Overlayanimation prop to removeentering/exitingproperties (no longer supported) - Make
presentationprop explicit on allPopover.ContentandSelect.Contentcomponents (changed from optional to required) - Update animation hooks usage:
useBottomSheetAnimation()no longer returnsbottomSheetState,useDialogAnimation()no longer returnsdialogState
What Changed:
Dialog.Root: RemovedcloseDelayandisDismissKeyboardOnClosepropsDialog.Root: Animation prop type changed fromDialogRootAnimation(supported custom entering/exiting) toAnimationRootDisableAll(disable flags only)Dialog.Content: RemovedisAnimatedStyleActiveandonLayoutpropsBottomSheet.Root: RemovedisDismissKeyboardOnClosepropBottomSheet.Overlay: Animation prop no longer supportsentering/exitingpropertiesPopover.Content:presentationprop is now required (was optional, defaulted to"popover")Select.Content:presentationprop is now required (was optional, defaulted to"popover")- Animation hooks:
useBottomSheetAnimation()no longer returnsbottomSheetState,useDialogAnimation()no longer returnsdialogState
Related PR: #263
Bug Fixes
This release includes fixes for the following issues:
-
Issue #181: Fixed TextField error when inputting Chinese characters. The TextField component now properly handles multibyte characters and international input, ensuring smooth text entry for all languages including Chinese, Japanese, and Korean.
-
Issue #219: Fixed Button
childrenToString()returning"[object Object]"for multiple children. The function now properly handles React elements and complex children structures, preventing stringification issues when rendering button content. -
Issue #232: Fixed HeroUINativeProvider breaking with the recently released Uniwind Pro. The provider now properly handles Uniwind Pro compatibility, ensuring smooth integration with the latest Uniwind version.
-
Issue #259: Fixed BottomSheet issue where opening quickly and starting a meeting would prevent it from opening again. The refactored animation system resolves this issue by improving the entering/exiting animation logic.
-
Issue #261: Fixed
@gorhom/bottom-sheetnot being tree-shaken. The library now properly supports tree-shaking for unused dependencies.
Additional Fixes:
- Fixed theme calculated colors issue that was causing incorrect color values in certain scenarios
- Fixed
childrenToStringfunction to prevent React elements from being stringified incorrectly
Related PRs:
Links
Contributors
Thanks to everyone who contributed to this release!