# All Components
**Category**: native
**URL**: https://v3.heroui.com/docs/native/components
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/components/index.mdx
> Explore the full list of components available in HeroUI Native. More are on the way.
## Buttons
## Collections
## Controls
## Forms
## Navigation
## Overlays
## Feedback
## Layout
## Media
## Data Display
## Utilities
# Introduction
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/index.mdx
> An open-source UI component library for building beautiful and accessible user interfaces.
HeroUI Native is a component library built on [Tailwind v4](https://tailwindcss.com/blog/tailwindcss-v4) via [Uniwind](https://uniwind.dev/) and modern mobile development technologies. Every component comes with smooth animations, polished details, and built-in accessibility—ready to use, fully customizable.
## Why HeroUI Native?
**Beautiful by default** — Professional look out of the box, no extra styling needed.
**Accessible** — Accessibility is managed following mobile development best practices, with proper focus management, touch accessibility, and screen reader support built into every component.
**Flexible** — Each component is made of customizable parts. Change what you need, leave the rest.
**Developer-friendly** — Fully typed APIs, predictable patterns, and excellent autocompletion.
**Maintained** — We handle updates, bug fixes, and new features. Just update the package.
**Lightweight** — Tree-shaken. Only what you use goes into your app.
**Future-proof** — Compatible with the latest [Expo](https://expo.dev/) and on [Tailwind v4](https://tailwindcss.com/blog/tailwindcss-v4) via [Uniwind](https://uniwind.dev/), designed for AI-assisted development.
## A Living Library, Not Copy-Paste
Copy-paste code works until it breaks. You're left maintaining outdated dependencies that stop evolving.
HeroUI Native is different. It's a living library that grows with you:
* Automatic updates and fixes
* New features without extra work
* Components stay current with React Native, Tailwind, and mobile platforms
* Deep customization, not shallow theme tweaks
* AI-friendly APIs for code generation
HeroUI Native is not a snapshot—it's a garden that keeps growing. 🌱
## HeroUI Ecosystem
* **🌐 HeroUI v3** (web) — React components with Tailwind CSS v4
* **📱 HeroUI Native (mobile)** — Beautiful components for React Native
* **🤖 [HeroUI Chat](https://heroui.chat?ref=heroui-v3)** (text-to-app) — Create apps with natural language
* **🧠 UI for LLMs** — New platform & MCPs coming soon
## FAQ
**Is HeroUI Native free?**
Yes, completely free and open source under the MIT license.
**Is it production-ready?**
Currently in **beta**. We're actively working towards a stable release with community feedback.
**Can I customize the components?**
Yes! Update default styles, animations or compose component parts differently. Every slot is customizable.
**Does it work with TypeScript?**
Fully typed with excellent IDE support and autocompletion.
**What about accessibility?**
Accessibility follows mobile development best practices with proper focus management, touch accessibility, and screen reader support built into every component.
**Is there a Figma file?**
Yes! Access our design system at [HeroUI Figma Kit V3](https://www.figma.com/community/file/1546526812159103429).
## Get Involved
Join the community, share feedback, or contribute:
* [GitHub Discussions](https://github.com/heroui-inc/heroui-native/discussions)
* [Discord](https://discord.gg/9b6yyZKmH4)
* [X/Twitter](https://x.com/hero_ui)
* [Contributing Guidelines](https://github.com/heroui-inc/heroui-native/blob/main/CONTRIBUTING.md)
HeroUI Native is released under the [MIT License](https://github.com/heroui-inc/heroui-native/blob/main/LICENSE).
# Beta 10
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/beta-10
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/beta-10.mdx
> Bottom Sheet component, PressableFeedback refactor, Animation API State Prop extension, use-theme-color multiple colors selection, and bug fixes.
December 30, 2025
This release introduces the new [Bottom Sheet](/docs/native/components/bottom-sheet) component, refactors [PressableFeedback](/docs/native/components/pressable-feedback) with improved API, extends the Animation API with State Prop support, enhances the `use-theme-color` hook to handle multiple colors selection, and includes various bug fixes and documentation improvements.
## Installation
Update to the latest version:
```bash
npm i heroui-native@beta
```
```bash
pnpm add heroui-native@beta
```
```bash
yarn add heroui-native@beta
```
```bash
bun add heroui-native@beta
```
**Using 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](/docs/native/getting-started/mcp-server).
## What's New
### New Components
#### Bottom Sheet
This release introduces the **Bottom Sheet** component, a versatile overlay component that slides up from the bottom of the screen with animated transitions and swipe-to-dismiss gestures.
**Features:**
* Smooth animated transitions with gesture support
* Multiple snap points for flexible sizing
* Detached mode for custom positioning
* Customizable overlay with blur effects
* Full accessibility support
* Built on [@gorhom/bottom-sheet](https://gorhom.dev/react-native-bottom-sheet)
**Usage:**
```tsx
import { BottomSheet, Button } from 'heroui-native';
TitleDescription
```
For complete documentation and examples, see the [Bottom Sheet component page](/docs/native/components/bottom-sheet).
**Related PR:** [#174](https://github.com/heroui-inc/heroui-native/pull/174)
## Component Improvements
### PressableFeedback Refactor
The [PressableFeedback](/docs/native/components/pressable-feedback) component has been refactored with an improved API and better animation control.
**Improvements:**
* Enhanced animation configuration API
* Better support for custom animation states
* Improved performance and smoother animations
* More flexible feedback positioning options
The component maintains backward compatibility while providing more control over press feedback animations.
**Related PR:** [#182](https://github.com/heroui-inc/heroui-native/pull/182)
## API Enhancements
### Animation API State Prop Extension
The Animation API has been extended with a new `state` prop that allows you to disable animations while customizing properties. This provides more granular control over animation behavior.
**New Capability:**
```tsx
```
The `state` prop can be:
* `'disabled'`: Disable animations while still allowing property customization
* `'disable-all'`: Disable all animations including children
* `boolean`: Simple enable/disable control
This enhancement makes it easier to customize animation properties without enabling animations, useful for fine-tuning component behavior.
**Related PR:** [#176](https://github.com/heroui-inc/heroui-native/pull/176)
### use-theme-color Multiple Colors Selection
The `use-theme-color` hook has been refactored to handle multiple colors selection, making it more flexible and powerful for theme customization.
**Enhancement:**
* Support for selecting multiple colors at once
* Improved color selection logic
* Better performance when working with multiple color values
This improvement makes it easier to work with complex theming scenarios where multiple colors need to be selected and applied together.
**Related PR:** [#170](https://github.com/heroui-inc/heroui-native/pull/170)
## Documentation
### Animated Styles Guide Comments
Added comprehensive comments and documentation to the Animated Styles Guide, making it easier for developers to understand and use animation features effectively.
**Improvements:**
* Enhanced code examples with detailed comments
* Better explanation of animation patterns
* Clearer guidance on when to use different animation approaches
**Related PR:** [#179](https://github.com/heroui-inc/heroui-native/pull/179)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #173](https://github.com/heroui-inc/heroui-native/issues/173)**: Fixed issue where `classNames={{container:"bg-x"}}` was not working for styling the backgroundColor of TextField.Input container
* **[Issue #177](https://github.com/heroui-inc/heroui-native/issues/177)**: Fixed button scale animation issue where the scale would sometimes stay at 0.9x and not bounce back after being pressed
* **[Issue #178](https://github.com/heroui-inc/heroui-native/issues/178)**: Fixed bug affecting component functionality
## Updated Documentation
The following documentation pages have been updated to reflect the changes in this release:
* [Animation Guide](/docs/native/getting-started/animation) - Updated with Animation API State Prop documentation
* [Colors Guide](/docs/native/getting-started/colors) - Updated with use-theme-color multiple colors selection information
* [PressableFeedback Component](/docs/native/components/pressable-feedback) - Updated with refactored API documentation
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# Beta 11
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/beta-11
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/beta-11.mdx
> Enhanced Bottom Sheet close coordination, Dialog swipe-to-dismiss fixes, TextField improvements, and PortalHost export for advanced use cases
January 6, 2026
Beta 11 focuses on improving component reliability and developer experience across several key areas. This release enhances Bottom Sheet close coordination to ensure consistent behavior across all close mechanisms, fixes Dialog swipe-to-dismiss gesture handling issues, resolves TextField styling and functionality problems, and introduces a new PortalHost export for advanced portal mounting scenarios. These improvements make interactions smoother and provide developers with more control over component behavior.
## Installation
Update to the latest version:
```bash
npm i heroui-native@beta
```
```bash
pnpm add heroui-native@beta
```
```bash
yarn add heroui-native@beta
```
```bash
bun add heroui-native@beta
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the Beta 11 improvements in action with our preview app! You can explore the enhanced Bottom Sheet, Dialog, TextField, and PortalHost components directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
This will automatically open the app in Expo Go if it's installed on your device.
## Component Improvements
### Bottom Sheet Close Coordination Enhancement
The [Bottom Sheet](/docs/native/components/bottom-sheet) component has been enhanced with improved close coordination across all close mechanisms.
**Improvements:**
* Enhanced synchronization between swipe-to-dismiss, overlay press, close button, and programmatic close actions
* Improved state management to prevent race conditions during close operations
* More reliable `onOpenChange` callback firing across all close scenarios
* Better coordination between animation progress and close state transitions
The Bottom Sheet component supports multiple ways to close: swiping down, pressing the overlay, clicking the close button, or programmatically calling close. Previously, these mechanisms could sometimes conflict or produce inconsistent behavior. This update ensures all close mechanisms work harmoniously together, providing a smoother and more predictable user experience.
**Related PR:** [#201](https://github.com/heroui-inc/heroui-native/pull/201)
### Dialog Swipe-to-Dismiss Gesture Handling Fix
The [Dialog](/docs/native/components/dialog) component has been fixed to properly handle swipe-to-dismiss gestures.
**Improvements:**
* Fixed gesture detection and handling for swipe-to-dismiss functionality
* Improved gesture state management during swipe interactions
* Enhanced animation coordination during gesture release
* More reliable dismissal when swiping beyond the threshold
The Dialog component supports swipe-to-dismiss functionality, allowing users to dismiss dialogs by swiping down. This fix resolves issues where gesture handling could become unresponsive or produce unexpected behavior during swipe interactions.
**Related PR:** [#193](https://github.com/heroui-inc/heroui-native/pull/193)
### TextField Styling and Functionality Fixes
The [TextField](/docs/native/components/text-field) component has been fixed to resolve styling and functionality issues.
**Improvements:**
* Fixed input styling inconsistencies
* Resolved animation state management issues
* Improved focus and blur state handling
* Enhanced error state visual feedback
* Fixed placeholder and selection color application
These fixes ensure the TextField component displays correctly across all states (focused, blurred, invalid) and provides consistent visual feedback to users.
**Related PR:** [#202](https://github.com/heroui-inc/heroui-native/pull/202)
## API Enhancements
### PortalHost Export for Advanced Use Cases
The `PortalHost` component is now exported from the main provider module, enabling advanced portal host mounting scenarios.
**New Capability:**
```tsx
import { HeroUINativeProvider, PortalHost } from "@heroui/native";
export function CustomLayout() {
return (
<>
{/* Your app content */}
{/* Manually mount PortalHost in a custom location */}
>
);
}
```
This enhancement allows developers to manually mount portal hosts in custom layouts, which is particularly useful for scenarios where you need portals to render in specific locations (e.g., within BottomSheet, Modal, or other overlay components). By default, `HeroUINativeProvider` includes a `PortalHost` for standard use cases, but now you can create additional hosts with custom names for advanced scenarios.
**Use Cases:**
* Mounting portals within BottomSheet components
* Creating portal hosts in Modal components
* Custom overlay rendering scenarios
* Multi-host portal architectures
**Related PR:** [#185](https://github.com/heroui-inc/heroui-native/pull/185)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #187](https://github.com/heroui-inc/heroui-native/issues/187)**: Fixed an issue where multiple presses were required to re-open a bottom sheet or dialog after it was dismissed via swipe gesture. The internal state now properly synchronizes with the close animation, allowing immediate reopening regardless of how the component was closed.
* **[Issue #189](https://github.com/heroui-inc/heroui-native/issues/189)**: Fixed app freezing when swiping to dismiss dialogs containing text inputs.
* **[Issue #196](https://github.com/heroui-inc/heroui-native/issues/196)**: Fixed TextField multiline input behavior to match React Native's TextInput multiline functionality.
* **[Issue #199](https://github.com/heroui-inc/heroui-native/issues/199)**: Fixed placeholder text positioning within TextField Input component.
**Related PRs:**
* [#201](https://github.com/heroui-inc/heroui-native/pull/201)
* [#202](https://github.com/heroui-inc/heroui-native/pull/202)
* [#193](https://github.com/heroui-inc/heroui-native/pull/193)
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# Beta 12
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/beta-12
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/beta-12.mdx
> InputOTP, Label, and Description components, Popover close fixes, controlled state improvements, border radius fixes, and variant style prop support
January 13, 2026
Beta 12 introduces three essential form components—InputOTP, Label, and Description—that enhance form building capabilities in React Native applications. This release also includes critical fixes for Popover close behavior, popup controlled state management, border radius configuration, and adds variant style prop support across multiple form components. These improvements provide developers with more robust form components and better control over component styling and behavior.
## Installation
Update to the latest version:
```bash
npm i heroui-native@beta
```
```bash
pnpm add heroui-native@beta
```
```bash
yarn add heroui-native@beta
```
```bash
bun add heroui-native@beta
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the Beta 12 improvements in action with our preview app! You can explore the new InputOTP, Label, and Description components, along with the Popover fixes, controlled state improvements, border radius fixes, and variant style prop support directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
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 form components:
* **[InputOTP](/docs/native/components/input-otp)**: Input component for entering one-time passwords (OTP) with individual character slots, animations, and validation support.
* **[Label](/docs/native/components/label)**: Text component for labeling form fields and other UI elements with support for required indicators and validation states.
* **[Description](/docs/native/components/description)**: Text component for providing accessible descriptions and helper text for form fields and other UI elements.
#### InputOTP
The InputOTP component provides a complete solution for one-time password input scenarios, such as two-factor authentication, verification codes, and PIN entry. It features individual character slots with smooth animations, customizable grouping, separators, and comprehensive validation support.
**Features:**
* Individual character slots with smooth animations and caret indicators
* Flexible grouping with separators for visual organization
* Pattern-based input restriction (digits, characters, or custom regex)
* Controlled and uncontrolled value management
* Validation state support with visual feedback
* Customizable placeholder characters per slot position
* Paste support with transformer function
* Complete accessibility support
**Usage:**
```tsx
import { InputOTP, Label, Description } from "heroui-native";
export function Example() {
return (
<>
console.log(code)}>
We've sent a code to your email
>
);
}
```
For complete documentation and examples, see the [InputOTP component page](/docs/native/components/input-otp).
**Related PR:** [#214](https://github.com/heroui-inc/heroui-native/pull/214)
#### Label
The Label component provides accessible labeling for form fields with built-in support for required indicators, validation states, and disabled states. It automatically displays an asterisk for required fields and adapts its styling based on the field's validation state.
**Features:**
* Automatic required field indicator (asterisk)
* Invalid state styling for validation errors
* Disabled state support
* Compound component architecture for custom layouts
* Full accessibility support with nativeID linking
* Customizable styling via className, classNames, and styles props
**Usage:**
```tsx
import { Label, TextField } from "heroui-native";
export function Example() {
return (
);
}
```
For complete documentation and examples, see the [Label component page](/docs/native/components/label).
**Related PR:** [#214](https://github.com/heroui-inc/heroui-native/pull/214)
#### Description
The Description component provides accessible helper text and descriptions for form fields. It features muted styling by default and supports linking to form fields via nativeID for screen reader support.
**Features:**
* Muted text styling optimized for helper text
* Accessibility linking via nativeID and aria-describedby
* Seamless integration with form components
* Customizable styling support
**Usage:**
```tsx
import { Description, TextField } from "heroui-native";
export function Example() {
return (
Email address
We'll never share your email with anyone else.
);
}
```
For complete documentation and examples, see the [Description component page](/docs/native/components/description).
**Related PR:** [#214](https://github.com/heroui-inc/heroui-native/pull/214)
## Component Improvements
### Popover Close via Ref Fix
The [Popover](/docs/native/components/popover) component has been fixed to properly handle programmatic close operations via ref.
**Improvements:**
* Fixed ref-based close method to properly trigger close animations
* Improved state synchronization between ref calls and component state
* Enhanced reliability of programmatic close operations
This fix ensures that when developers call `popoverRef.current?.close()`, the popover closes reliably with proper animation and state management.
**Related PR:** [#207](https://github.com/heroui-inc/heroui-native/pull/207)
### Popup Controlled State Fix
Popup components (including Dialog, Bottom Sheet, and Popover) have been fixed to properly handle controlled state via the `isOpen` prop.
**Improvements:**
* Fixed controlled state synchronization for popup components
* Improved handling of external state changes
* Enhanced reliability when using controlled mode
This fix ensures that popup components correctly respond to external state changes when using controlled mode, providing developers with more predictable behavior when managing popup state externally.
**Related PR:** [#215](https://github.com/heroui-inc/heroui-native/pull/215)
### Button, Chip, and Tabs Border Radius Fix
The [Button](/docs/native/components/button), [Chip](/docs/native/components/chip), and [Tabs](/docs/native/components/tabs) components have been fixed to properly respect global border radius configuration.
**Improvements:**
* Fixed border radius configuration application for Button component
* Fixed border radius configuration application for Chip component
* Fixed border radius configuration application for Tabs component
* Improved consistency across components using global theme configuration
These fixes ensure that global border radius settings defined in the theme configuration are properly applied to Button, Chip, and Tabs components, providing consistent styling across the application.
**Related PR:** [#218](https://github.com/heroui-inc/heroui-native/pull/218)
### TextField.Input Props Cleanup
The [TextField](/docs/native/components/text-field) component's Input subcomponent has been cleaned up by removing the `animation` and `isAnimatedStyleActive` props.
**Changes:**
* Removed `animation` prop from TextField.Input
* Removed `isAnimatedStyleActive` prop from TextField.Input
* Simplified component API for better maintainability
These props were removed to streamline the TextField.Input API and reduce complexity. Animation behavior is now handled internally by the component, providing a more consistent and predictable experience without requiring manual animation configuration.
**Related PR:** [#220](https://github.com/heroui-inc/heroui-native/pull/220)
## API Enhancements
### HeroUINativeProvider devInfo Configuration
The `HeroUINativeProvider` component now supports `devInfo` configuration options for enhanced development experience.
**New Capability:**
```tsx
import { HeroUINativeProvider } from "heroui-native";
export function App() {
return (
{/* Your app content */}
);
}
```
This enhancement provides developers with additional configuration options for development and debugging scenarios, making it easier to troubleshoot and optimize applications during development.
**Related PR:** [#217](https://github.com/heroui-inc/heroui-native/pull/217)
### Variant Style Prop Support
The [Checkbox](/docs/native/components/checkbox), [Radio](/docs/native/components/radio), [TextField](/docs/native/components/text-field), and [InputOTP](/docs/native/components/input-otp) components now support the `variant` style prop for easier variant customization.
**New Capability:**
```tsx
import { Checkbox, Radio, TextField, InputOTP } from "heroui-native";
// Apply variant styles directly via style prop
Option 1
Option 2
```
This enhancement provides developers with more flexibility when customizing component variants, allowing variant changes to be applied via the style prop in addition to the component's variant prop.
**Related PR:** [#220](https://github.com/heroui-inc/heroui-native/pull/220)
## Style Fixes
### Border Radius Configuration
Fixed global border radius configuration not applying correctly to certain components.
**Fixes:**
* Fixed Button component not respecting global border radius configuration
* Fixed Chip component border radius application
* Fixed Tabs component border radius application
### Style Optimizations
* **Border Radius Consistency**: Improved consistency of border radius application across Button, Chip, and Tabs components
* **Theme Configuration**: Enhanced theme configuration propagation to ensure all components respect global settings
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #93](https://github.com/heroui-inc/heroui-native/issues/93)**: Fixed global border radius configuration not applying to Button component in hero-ui-native using Unwind. The Button component now properly respects border radius settings defined in the global theme configuration, ensuring consistent styling across the application.
* **[Issue #213](https://github.com/heroui-inc/heroui-native/issues/213)**: Fixed Select controlled mode (`isOpen`) not working. The Select component now properly handles controlled state when the `isOpen` prop is provided, allowing developers to manage Select open/close state externally with predictable behavior.
**Related PRs:**
* [#218](https://github.com/heroui-inc/heroui-native/pull/218)
* [#215](https://github.com/heroui-inc/heroui-native/pull/215)
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# Beta 13
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/beta-13
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/beta-13.mdx
> TextArea component, Button outline variant, Tabs improvements, form component decomposition, popup animation refactor, style class exports, and critical bug fixes
February 3, 2026
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:
```bash
npm i heroui-native@beta
```
```bash
pnpm add heroui-native@beta
```
```bash
yarn add heroui-native@beta
```
```bash
bun add heroui-native@beta
```
**Using 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](/docs/native/getting-started/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](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
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](/docs/native/components/text-area)**: Multiline text input component with styled border and background for collecting longer user input.
* **[Input](/docs/native/components/input)**: Single-line text input component with styled border and background, now available as a standalone component separate from TextField.
* **[CloseButton](/docs/native/components/close-button)**: 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:**
```tsx
import { Description, Label, TextArea, TextField } from "heroui-native";
export function Example() {
return (
Please provide as much detail as possible.
);
}
```
For complete documentation and examples, see the [TextArea component page](/docs/native/components/text-area).
**Related PR:** [#254](https://github.com/heroui-inc/heroui-native/pull/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:**
```tsx
import { Description, Input, Label, TextField } from "heroui-native";
export function Example() {
return (
We'll never share your email.
);
}
```
For complete documentation and examples, see the [Input component page](/docs/native/components/input).
**Related PR:** [#247](https://github.com/heroui-inc/heroui-native/pull/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:**
```tsx
import { CloseButton } from "heroui-native";
// Standalone usage
// As part of Dialog, Popover, Select, Bottom Sheet
```
For complete documentation and examples, see the [CloseButton component page](/docs/native/components/close-button).
**Related PR:** [#237](https://github.com/heroui-inc/heroui-native/pull/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 `betweenValues` prop
* Customizable animation timing and opacity
* Always visible option for static separators
**Usage:**
```tsx
import { Tabs } from "heroui-native";
GeneralNotifications
```
**Related PR:** [#228](https://github.com/heroui-inc/heroui-native/pull/228)
## Component Improvements
### Button Outline Variant
The [Button](/docs/native/components/button) component now includes an `outline` variant that provides a bordered style with transparent background, offering more visual variety for button designs.
**Improvements:**
* New `outline` variant 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:**
```tsx
import { Button } from "heroui-native";
```
**Related PR:** [#235](https://github.com/heroui-inc/heroui-native/pull/235)
### Tabs Indicator Animation Refactor
The [Tabs](/docs/native/components/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 `translateX` transforms
* Improved animation performance and smoothness
* Better visual consistency during tab transitions
* Reduced layout recalculations during animations
**Related PR:** [#227](https://github.com/heroui-inc/heroui-native/pull/227)
### Popover Arrow Sizing and Visual Connection
The [Popover](/docs/native/components/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](https://github.com/heroui-inc/heroui-native/pull/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](https://github.com/heroui-inc/heroui-native/pull/247)
### Input Android Shadow Fix
The [Input](/docs/native/components/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](https://github.com/heroui-inc/heroui-native/pull/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](https://github.com/heroui-inc/heroui-native/pull/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:**
```tsx
// 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 component
* `heroui-native/[component-name]` - Individual components
* `heroui-native/portal` - Portal utilities
* `heroui-native/utils` - Utility functions
* `heroui-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](https://github.com/heroui-inc/heroui-native/pull/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:**
```tsx
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](https://github.com/heroui-inc/heroui-native/pull/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](https://github.com/heroui-inc/heroui-native/pull/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:
```tsx
// Before
{/* content */}
{/* content */}
// After
{/* content */}
{/* content */}
```
**Available options:**
* `"primary"` - Primary variant (previously `"pill"`)
* `"secondary"` - Secondary variant (previously `"line"`)
**Related PR:** [#236](https://github.com/heroui-inc/heroui-native/pull/236)
### Tabs Indicator Animation Refactor
The [Tabs](/docs/native/components/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:
```tsx
// Before
{/* content */}
// After
{/* content */}
```
**What Changed:**
* Animation API changed from `left` to `translateX` in `TabsIndicatorAnimation` configuration
* Indicator positioning now uses `translateX` transform for GPU-accelerated animations
* Added `left-0` base class to indicator styles to maintain initial positioning
* Visual behavior remains identical, only the underlying implementation has changed
**Related PR:** [#227](https://github.com/heroui-inc/heroui-native/pull/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:
```tsx
// Before
import { Divider } from "heroui-native";
// After
import { Separator } from "heroui-native";
```
**Related PR:** [#238](https://github.com/heroui-inc/heroui-native/pull/238)
### Quaternary Variant Removal
The `quaternary` variant has been removed from [Surface](/docs/native/components/surface) and [Card](/docs/native/components/card) components to simplify the design system and improve consistency.
**Migration:**
Update any components using the `quaternary` variant:
```tsx
// Before
{/* content */}
{/* content */}
// After
// Use default, secondary, or tertiary variants, or apply custom styling
{/* content */}
{/* content */}
// Or use custom styling for specific needs
{/* content */}
```
**Available variants:**
* `"default"` - Default surface styling
* `"secondary"` - Secondary surface styling
* `"tertiary"` - Tertiary surface styling
**Related PR:** [#246](https://github.com/heroui-inc/heroui-native/pull/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:**
* `FormField` has been renamed to `ControlField`
* `ErrorView` has been renamed to `FieldError`
**Migration:**
Update all imports and usages:
```tsx
// Before
import { FormField, ErrorView, TextField } from "heroui-native";
Error message
// After
import { ControlField, FieldError, Input, TextField } from "heroui-native";
Error message
```
**TextField.Input Removal:**
The `TextField.Input` subcomponent has been removed. Use the standalone `Input` component instead:
```tsx
// Before
import { TextField } from "heroui-native";
// After
import { Input, TextField } from "heroui-native";
```
**Component Composition Changes:**
`RadioGroup`, `TextField`, and `ControlField` now use `Label`, `Description`, and `FieldError` components directly, providing more flexible composition:
```tsx
import { ControlField, Description, FieldError, Input, Label, RadioGroup, TextField } from "heroui-native";
// TextField with Label, Description, and FieldError
We'll never share your email.Invalid email address
// RadioGroup with Label, Description, and FieldError
Option 1Choose one optionPlease select an option
// ControlField with Label, Description, and FieldError
Additional informationValidation error
```
**Related PR:** [#247](https://github.com/heroui-inc/heroui-native/pull/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:
```tsx
// Before
import { Button, Dialog } from "heroui-native";
// After
import { Button, Dialog } from "heroui-native";
const [isOpen, setIsOpen] = useState(false);
```
**What Changed:**
* New `CloseButton` component added with default `variant="tertiary"`, `size="sm"`, and `isIconOnly={true}`
* `Dialog.Close`, `Popover.Close`, `Select.Close`, and `BottomSheet.Close` now extend `CloseButton` internally
* The `asChild` prop has been removed from all Close components
* Close components still support all Button props including `variant`, `size`, `iconProps`, and custom `children`
* You must now handle close logic manually when using custom buttons instead of Close components
**Related PR:** [#237](https://github.com/heroui-inc/heroui-native/pull/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 `closeDelay` and `isDismissKeyboardOnClose` props from `Dialog.Root`
* Remove custom `entering`/`exiting` animation configs from `Dialog.Root` animation prop (now only supports disable flags). Custom animations should be configured using Keyframe animations directly on `Dialog.Content` component
* Remove `isAnimatedStyleActive` and `onLayout` props from `Dialog.Content`
* Remove `isDismissKeyboardOnClose` prop from `BottomSheet.Root`
* Update `BottomSheet.Overlay` animation prop to remove `entering`/`exiting` properties (no longer supported)
* Make `presentation` prop explicit on all `Popover.Content` and `Select.Content` components (changed from optional to required)
* Update animation hooks usage: `useBottomSheetAnimation()` no longer returns `bottomSheetState`, `useDialogAnimation()` no longer returns `dialogState`
**What Changed:**
* `Dialog.Root`: Removed `closeDelay` and `isDismissKeyboardOnClose` props
* `Dialog.Root`: Animation prop type changed from `DialogRootAnimation` (supported custom entering/exiting) to `AnimationRootDisableAll` (disable flags only)
* `Dialog.Content`: Removed `isAnimatedStyleActive` and `onLayout` props
* `BottomSheet.Root`: Removed `isDismissKeyboardOnClose` prop
* `BottomSheet.Overlay`: Animation prop no longer supports `entering`/`exiting` properties
* `Popover.Content`: `presentation` prop is now required (was optional, defaulted to `"popover"`)
* `Select.Content`: `presentation` prop is now required (was optional, defaulted to `"popover"`)
* Animation hooks: `useBottomSheetAnimation()` no longer returns `bottomSheetState`, `useDialogAnimation()` no longer returns `dialogState`
**Related PR:** [#263](https://github.com/heroui-inc/heroui-native/pull/263)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #181](https://github.com/heroui-inc/heroui-native/issues/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](https://github.com/heroui-inc/heroui-native/issues/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](https://github.com/heroui-inc/heroui-native/issues/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](https://github.com/heroui-inc/heroui-native/issues/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](https://github.com/heroui-inc/heroui-native/issues/261)**: Fixed `@gorhom/bottom-sheet` not 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 `childrenToString` function to prevent React elements from being stringified incorrectly
**Related PRs:**
* [#226](https://github.com/heroui-inc/heroui-native/pull/226)
* [#239](https://github.com/heroui-inc/heroui-native/pull/239)
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# All Releases
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/index.mdx
> All updates and changes to HeroUI Native, including new features, fixes, and breaking changes.
**Using 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](/docs/native/getting-started/mcp-server).
## Latest Release
### RC 4
**March 2026**
This release introduces the SubMenu compound component for nested expandable menus with animated expand/collapse, refactors Slider Output composition with slot-based styling and `textProps` forwarding, and fixes PressableFeedback ripple animation blink on rapid presses.
[Read full release notes →](/docs/native/releases/rc-4)
### RC 3
**February 2026**
This release introduces three new components—TagGroup, Menu, and InputGroup—adds Android hardware back button support for all bottom-sheet-based overlays, and achieves Expo 55 compatibility with a critical `combineStyles` fix that preserves Reanimated animated style bindings.
[Read full release notes →](/docs/native/releases/rc-3)
### RC 2
**February 2026**
This release introduces three new components—SearchField, ListGroup, and Slider—adds multi-selection mode to Select with type-safe generics, and refactors the Button feedback API into a unified `feedbackVariant` + `animation` prop pattern. Peer dependency constraints are relaxed for broader Expo SDK 55 compatibility, and several Select and Avatar bugs are fixed.
[Read full release notes →](/docs/native/releases/rc-2)
### RC 1
**February 2026**
This release introduces the Alert compound component with five status variants and accessibility primitives, extracts Radio into a standalone component with dual-mode operation, and adds the animated Select.TriggerIndicator subcomponent. It also delivers HeroUINativeProviderRaw for bundle optimization, a `disableFullWindowOverlay` prop for iOS debugging, unified `styles` prop support across six components, and theme surface variable refactoring with explicit per-theme definitions.
[Read full release notes →](/docs/native/releases/rc-1)
### Beta 13
**February 2026**
This release introduces the TextArea component for multiline text input, adds Button outline variant, exports style class names for all components, and includes a reusable CloseButton component. The release also refactors Tabs with improved animations and variant naming, decomposes form components into standalone primitives, and adds granular exports for bundle optimization. Critical bug fixes for theme colors and component stringification are also included.
[Read full release notes →](/docs/native/releases/beta-13)
### Beta 12
**January 2026**
This release introduces three essential form components—InputOTP, Label, and Description—that enhance form building capabilities in React Native applications. The release also includes critical fixes for Popover close behavior, popup controlled state management, border radius configuration, and adds variant style prop support across multiple form components.
[Read full release notes →](/docs/native/releases/beta-12)
### Beta 11
**January 2026**
This release enhances component reliability and developer experience with improved close coordination for Bottom Sheet, fixes for Dialog swipe-to-dismiss gestures, TextField styling improvements, and a new PortalHost export for advanced portal mounting scenarios. These updates ensure smoother interactions and provide more flexibility for custom layouts.
[Read full release notes →](/docs/native/releases/beta-11)
### Beta 10
**December 2025**
This release introduces the new [Bottom Sheet](/docs/native/components/bottom-sheet) component, refactors [PressableFeedback](/docs/native/components/pressable-feedback) with improved API, extends the Animation API with State Prop support, enhances the `use-theme-color` hook to handle multiple colors selection, and includes various bug fixes and documentation improvements.
[Read full release notes →](/docs/native/releases/beta-10)
## Release Schedule
HeroUI Native follows a regular release cycle:
* **Release candidates**: Final stabilization before stable release - In progress
* **Stable releases**: Quarterly major versions (Q1 2026 target)
## Contributing
Found an issue or want to contribute? Check out our [GitHub repository](https://github.com/heroui-inc/heroui-native).
# RC 1
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/rc-1
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/rc-1.mdx
> Alert component, standalone Radio component, Select TriggerIndicator, HeroUINativeProviderRaw, disableFullWindowOverlay prop, styles prop expansion, theme surface refactor
February 12, 2026
RC 1 marks the first Release Candidate for HeroUI Native, signaling that the library is approaching production readiness. This release introduces the Alert compound component with accessibility-first design and status variants, extracts Radio into a standalone component with dual-mode operation, and adds the animated Select.TriggerIndicator subcomponent. It also delivers a lightweight HeroUINativeProviderRaw for bundle optimization, a new `disableFullWindowOverlay` prop for iOS debugging, unified `styles` prop support across six components, and a theme refactor that replaces calculated surface colors with explicit theme-defined variables. Several critical bug fixes—including InputOTP in BottomSheet, toast text clipping, and element inspector compatibility—round out the release.
## Installation
Update to the latest version:
```bash
npm i heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the RC 1 improvements in action with our preview app! You can explore the new Alert and Radio components, Select TriggerIndicator and all the bug fixes directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
This will automatically open the app in Expo Go if it's installed on your device.
## What's New
### New Components
This release introduces **1 new** component:
* **[Alert](/docs/native/components/alert)**: Accessible alert component with five status variants and compound sub-components for flexible content composition.
#### Alert
The Alert component provides accessible alert messaging with built-in support for five status variants: default, accent, success, warning, and danger. It follows the compound component pattern with `Alert.Indicator`, `Alert.Content`, `Alert.Title`, and `Alert.Description` sub-components, giving developers full control over layout and customization. The primitive layer provides `role="alert"`, `aria-labelledby`, and `aria-describedby` accessibility associations automatically.
**Features:**
* Five status variants: default, accent, success, warning, and danger
* Default SVG status icons with theme-aware colors via `useStatusColor` hook
* Compound component architecture with Indicator, Content, Title, and Description sub-components
* Custom indicator support (e.g., replace default icon with a Spinner)
* Accessibility primitives with `role="alert"`, `aria-labelledby`, and `aria-describedby`
* `asChild` slot support on all sub-components
* Ref forwarding and `className` prop support on all parts
**Usage:**
```tsx
import { Alert } from "heroui-native";
export function Example() {
return (
Payment successful
Your payment has been processed successfully.
);
}
```
For complete documentation and examples, see the [Alert component page](/docs/native/components/alert).
**Related PR:** [#284](https://github.com/heroui-inc/heroui-native/pull/284)
### New Subcomponents
#### Select.TriggerIndicator
The [Select](/docs/native/components/select) component now includes a `TriggerIndicator` subcomponent that displays an animated chevron icon to visually indicate the open/close state. The indicator rotates smoothly when the select opens or closes, using React Native Reanimated spring physics.
**Features:**
* Animated chevron icon that rotates on open/close transitions
* Customizable animation configuration via `animation` prop with rotation values and spring config
* Icon customization through `iconProps` (size, color)
* Support for custom children to replace the default chevron
* Automatic state synchronization with Select open/close state
**Usage:**
```tsx
import { Select } from "heroui-native";
```
**Related PR:** [#274](https://github.com/heroui-inc/heroui-native/pull/274)
## Component Improvements
### Toast Styling and Stacking Refactor
The [Toast](/docs/native/components/toast) component styling has been refactored to replace the border-based padding approach with proper padding and vertical placeholder views, improving content visibility when toasts stack.
**Improvements:**
* Replaced `border-[16px]` padding workaround with proper `p-4` padding
* Added `useVerticalPlaceholderStyles` hook for placeholder view styling
* Added absolute positioned placeholder Views at top and bottom to prevent content visibility when toasts stack
* Updated shadow system to use `shadow-overlay` token
* Standardized overlay shadow values across all themes (alpha, mint, sky) with lighter opacity
This refactor ensures content remains properly hidden when toasts of different heights stack together, while providing a more maintainable and predictable styling approach.
**Related PR:** [#229](https://github.com/heroui-inc/heroui-native/pull/229)
### Dialog Overlay Animation Fix
The [Dialog](/docs/native/components/dialog) component's popup animation timing has been fixed when closing via gesture. The progress value is now properly sequenced with delays to ensure the closing animation completes before resetting.
**Improvements:**
* Progress value now transitions to 2 after a 300ms delay when closing via gesture
* Progress resets to 0 after 350ms to ensure animation completion
* Removed immediate `progress.set(2)` call when `isOpen` becomes false
* Smooth closing animations now play correctly when dismissing popups via swipe gestures
**Related PR:** [#277](https://github.com/heroui-inc/heroui-native/pull/277)
### Theme Surface Variables Refactor
The theme system has been refactored to replace calculated surface colors with explicit theme-defined variables, providing more control and consistency across themes.
**Improvements:**
* `surface-secondary` and `surface-tertiary` (with foregrounds) are now defined explicitly in each theme (alpha, lavender, mint, sky, variables.css)
* Base theme uses `var(--surface-secondary)` and `var(--surface-tertiary)` instead of `color-mix` calculations
* Removed `on-surface`, `on-surface-secondary`, and `on-surface-tertiary` palettes from theme.css
* Updated theming documentation with the new variable structure and examples
This change gives theme authors direct control over surface color values rather than relying on `color-mix` calculations, resulting in more predictable and consistent surface styling across all themes.
**Related PR:** [#281](https://github.com/heroui-inc/heroui-native/pull/281)
## API Enhancements
### Unified `styles` Prop for Multiple Components
Six components now support the unified `styles` prop for slot-based styling, providing a consistent pattern for applying styles to component internals.
**Supported components:**
* **Accordion**: `container` and `separator` slots
* **AvatarFallback**: `container` and `text` slots
* **FieldError**: `container` and `text` slots
* **Label**: `text` and `asterisk` slots (also fixed `style` prop handling)
* **PressableFeedback Ripple**: `container` and `ripple` slots (replaces `containerStyle` and `rippleStyle`)
* **SelectContentDialog**: `wrapper` and `content` slots
**New Capability:**
```tsx
import { Accordion, Label } from "heroui-native";
// Apply styles to specific slots
{/* Accordion items */}
```
All changes maintain backward compatibility with existing `style` props and properly merge styles when both are provided.
**Related PR:** [#271](https://github.com/heroui-inc/heroui-native/pull/271)
### `disableFullWindowOverlay` Prop
Portal-based components now support a `disableFullWindowOverlay` prop that enables React Native element inspector support on iOS during development.
**Supported components:**
* `BottomSheet.Portal`
* `Dialog.Portal`
* `Popover.Portal`
* `Select.Portal`
* `ToastProvider`
**New Capability:**
```tsx
import { Dialog } from "heroui-native";
// Enable element inspector support on iOS
```
On iOS, `FullWindowOverlay` uses a separate native window that blocks the React Native element inspector. Setting `disableFullWindowOverlay` to `true` renders content in the main window instead, enabling the inspector during development. The tradeoff is that overlays will no longer appear above native modals or the keyboard. This prop has no effect on Android.
For Toast, the prop is passed via `config.toast` when using `HeroUINativeProvider`.
**Related PR:** [#283](https://github.com/heroui-inc/heroui-native/pull/283)
### HeroUINativeProviderRaw
A new lightweight provider variant, `HeroUINativeProviderRaw`, excludes `ToastProvider` and `PortalHost` to give consumers full control over which dependencies are bundled.
**New Capability:**
```tsx
import { HeroUINativeProviderRaw } from "heroui-native/provider-raw";
// Lightweight provider without Toast and Portal dependencies
export function App() {
return (
{/* Your app content */}
);
}
```
This makes `react-native-screens`, `@gorhom/bottom-sheet`, and `react-native-svg` fully optional dependencies. The raw provider includes only `SafeAreaListener`, `GlobalAnimationSettingsProvider`, and `TextComponentProvider`. Consumers who need toast or portal features can compose them manually.
**Related PR:** [#285](https://github.com/heroui-inc/heroui-native/pull/285)
### Select.Trigger `variant` Prop
The `Select.Trigger` component now supports a `variant` prop with `"default"` and `"unstyled"` options, enabling better composition with custom trigger components like Button.
**New Capability:**
```tsx
import { Button, Select } from "heroui-native";
// Default variant (pre-styled trigger)
// Unstyled variant for custom compositions
```
**Related PR:** [#274](https://github.com/heroui-inc/heroui-native/pull/274)
### ControlField Radio Variant
The [ControlField](/docs/native/components/control-field) component now supports a `"radio"` variant in `ControlField.Indicator`, rendering a standalone Radio component alongside the existing `"switch"` and `"checkbox"` variants.
**New Capability:**
```tsx
import { ControlField } from "heroui-native";
Radio option
```
**Related PR:** [#286](https://github.com/heroui-inc/heroui-native/pull/286)
## ⚠️ Breaking Changes
### PressableFeedback Ripple: Unified `styles` Prop
The PressableFeedback Ripple component's individual style props (`containerStyle` and `rippleStyle`) have been replaced with a unified `styles` prop.
**Migration:**
Update all instances of individual style props to the unified `styles` prop:
```tsx
// Before
// After
```
**Related PR:** [#271](https://github.com/heroui-inc/heroui-native/pull/271)
### Select.Trigger Default Styles
`Select.Trigger` now defaults to `variant="default"`, which applies default container styles (`flex-row items-center justify-between h-12 px-4 rounded-2xl bg-surface shadow-surface`). Users with custom styled triggers need to add `variant="unstyled"` to prevent default styles from being applied.
**Migration:**
```tsx
// Before (custom styled trigger)
{/* content */}
// After (add variant="unstyled" to preserve custom styling)
{/* content */}
```
**Related PR:** [#274](https://github.com/heroui-inc/heroui-native/pull/274)
### Surface Theme Variables Restructured
The `on-surface`, `on-surface-secondary`, and `on-surface-tertiary` CSS variables and their hover/focus variants have been removed from the base theme. Surface secondary and tertiary colors are now defined explicitly in each theme file.
**Migration:**
If you reference `on-surface`, `on-surface-secondary`, or `on-surface-tertiary` variables in custom styles, replace them with the appropriate surface foreground variables defined in your theme.
```css
/* Before */
color: var(--on-surface);
color: var(--on-surface-secondary);
/* After */
color: var(--surface-foreground);
color: var(--surface-secondary-foreground);
```
**Related PR:** [#281](https://github.com/heroui-inc/heroui-native/pull/281)
### RadioGroup Indicator Removed
`RadioGroup.Indicator` and `RadioGroup.IndicatorThumb` have been removed in favor of the new standalone `Radio` component. The related types `RadioGroupIndicatorProps`, `RadioGroupIndicatorThumbProps`, and `RadioGroupIndicatorThumbAnimation` are also removed from exports.
**Migration:**
Replace all `RadioGroup.Indicator` and `RadioGroup.IndicatorThumb` usages with the `Radio` component:
```tsx
// Before
import { RadioGroup } from "heroui-native";
Option 1
// After
import { Radio, RadioGroup } from "heroui-native";
Option 1
```
**Related PR:** [#286](https://github.com/heroui-inc/heroui-native/pull/286)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #229](https://github.com/heroui-inc/heroui-native/issues/229)**: Fixed InputOTP not working inside BottomSheet. The InputOTP component now functions correctly when rendered within a BottomSheet overlay, resolving input focus and interaction issues that previously prevented OTP entry in bottom sheet contexts.
* **[Issue #265](https://github.com/heroui-inc/heroui-native/issues/265)**: Fixed the first letter of Toast description text being clipped. The toast styling refactor replaces the border-based padding approach with proper padding and placeholder views, ensuring all text content is fully visible regardless of toast stacking configuration.
* **[Issue #272](https://github.com/heroui-inc/heroui-native/issues/272)**: Fixed FullWindowOverlay blocking the React Native element inspector on iOS. The new `disableFullWindowOverlay` prop on portal components allows developers to render overlay content in the main window during development, restoring element inspector functionality.
**Related PRs:**
* [#229](https://github.com/heroui-inc/heroui-native/pull/229)
* [#283](https://github.com/heroui-inc/heroui-native/pull/283)
## Updated Documentation
The following documentation pages have been updated to reflect the changes in this release:
* [Alert](/docs/native/components/alert) - New component documentation with usage examples and API reference
* [Radio](/docs/native/components/radio) - New standalone Radio component documentation
* [Radio Group](/docs/native/components/radio-group) - Updated to reflect RadioGroup.Indicator removal and Radio integration
* [Control Field](/docs/native/components/control-field) - Updated with new radio variant documentation
* [Select](/docs/native/components/select) - TriggerIndicator subcomponent and Trigger variant documentation
* [Toast](/docs/native/components/toast) - Updated styling approach documentation
* [Bottom Sheet](/docs/native/components/bottom-sheet) - Added disableFullWindowOverlay documentation
* [Dialog](/docs/native/components/dialog) - Added disableFullWindowOverlay documentation
* [Popover](/docs/native/components/popover) - Added disableFullWindowOverlay documentation
* [Provider](/docs/native/getting-started/provider) - HeroUINativeProviderRaw documentation and provider hierarchy
* [Theming](/docs/native/getting-started/theming) - Updated surface variable structure and examples
* [Accordion](/docs/native/components/accordion) - Added styles prop documentation
* [Avatar](/docs/native/components/avatar) - Added styles prop documentation
* [Label](/docs/native/components/label) - Added styles prop documentation
* [Field Error](/docs/native/components/field-error) - Added styles prop documentation
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# RC 2
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/rc-2
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/rc-2.mdx
> SearchField, ListGroup, and Slider components, Select multi-selection mode, Button feedback API refactor, peer dependency relaxation
February 20, 2026
RC 2 continues the march toward production readiness with three new components—SearchField, ListGroup, and Slider—and a powerful multi-selection mode for Select backed by type-safe generics. The Button feedback API has been refactored into a cleaner unified `feedbackVariant` + `animation` prop pattern, and peer dependency constraints are relaxed for broader compatibility with Expo SDK 55. Several Select and Avatar bug fixes round out the release.
## Installation
Update to the latest version:
```bash
npm i heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the RC 2 improvements in action with our preview app! You can explore the new SearchField, ListGroup, and Slider components, Select multi-selection mode, the updated Button feedback API, and all the bug fixes directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
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** components:
* **[Slider](/docs/native/components/slider)**: Slider component with single-value and range modes, horizontal/vertical orientation, custom number formatting, and spring-animated thumb feedback.
* **[ListGroup](/docs/native/components/list-group)**: Surface-based grouped list component with pressable items, prefix/suffix slots, and default chevron navigation indicator.
* **[SearchField](/docs/native/components/search-field)**: Compound component for filtering and querying content with built-in search icon, clearable input, and auto-hide clear button.
#### Slider
The Slider component supports single-value and range (multi-thumb) modes, horizontal and vertical orientation, custom number formatting via `Intl.NumberFormat`, and spring-animated thumb feedback. The primitive layer handles all gesture and value logic independently, making it reusable for alternative styled implementations.
**Features:**
* Compound sub-components: `Slider.Output`, `Slider.Track`, `Slider.Fill`, `Slider.Thumb`
* Range slider: pass an array as `defaultValue`/`value` and use a render-function on `Slider.Track` to render multiple thumbs
* Vertical orientation via `orientation="vertical"`
* Custom formatting with `formatOptions` accepting `Intl.NumberFormatOptions` (currency, percent, unit, etc.)
* Gesture-handler-based drag and tap-to-position on track
* Value clamping, stepping, and multi-thumb support
* Spring-animated thumb scale via configurable `animation` prop
* Accessibility: each thumb receives `role="slider"` with full `accessibilityValue` (min, max, now, text)
* `useSlider` hook exposes slider context for advanced use cases
**Usage:**
```tsx
import { Slider } from "heroui-native";
export function BasicSlider() {
return (
);
}
export function RangeSlider() {
return (
{({ thumbs }) => (
<>
{thumbs.map((_, i) => (
))}
>
)}
);
}
```
For complete documentation and examples, see the [Slider component page](/docs/native/components/slider).
**Related PR:** [#305](https://github.com/heroui-inc/heroui-native/pull/305)
#### ListGroup
The ListGroup component renders grouped list items inside a Surface container, providing a polished navigation-list pattern commonly used in settings screens, menus, and content browsers. Each item supports prefix, content (title + description), and suffix slots with a default chevron-right navigation indicator.
**Features:**
* Surface-based container with rounded corners and consistent spacing
* Compound sub-components: `ListGroup.Item`, `ListGroup.ItemPrefix`, `ListGroup.ItemContent`, `ListGroup.ItemTitle`, `ListGroup.ItemDescription`, `ListGroup.ItemSuffix`
* Default chevron-right icon in `ItemSuffix` via internal `ChevronRightIcon`
* Pressable items with PressableFeedback integration
* Fully customizable slots for icons, badges, and other content
**Usage:**
```tsx
import { ListGroup } from "heroui-native";
export function Example() {
return (
console.log("Profile")}>
ProfileManage your account console.log("Settings")}>
SettingsApp preferences
);
}
```
For complete documentation and examples, see the [ListGroup component page](/docs/native/components/list-group).
**Related PR:** [#302](https://github.com/heroui-inc/heroui-native/pull/302)
#### SearchField
The SearchField component provides a dedicated input for search and filtering scenarios, built with the same compound-component pattern used by TextField. It includes a search icon, clearable input, and an auto-hiding clear button that disappears when the input is empty.
**Features:**
* Compound sub-components: `SearchField.Group`, `SearchField.SearchIcon`, `SearchField.Input`, `SearchField.ClearButton`
* `ClearButton` auto-hides when value is empty and clears search text on press
* `SearchIcon` supports custom children to replace the default magnifying glass SVG
* Validation state support with visual feedback
* Disabled state support
* Seamless integration with Label, Description, and FieldError
**Usage:**
```tsx
import { Label, SearchField } from "heroui-native";
export function Example() {
return (
);
}
```
For complete documentation and examples, see the [SearchField component page](/docs/native/components/search-field).
**Related PR:** [#299](https://github.com/heroui-inc/heroui-native/pull/299)
### Select Multi-Selection Mode
The [Select](/docs/native/components/select) component now supports multi-item selection via a new `selectionMode` prop. The `RootProps` type is now generic on `SelectionMode`, so TypeScript correctly resolves `value` and `onValueChange` types per mode—`SelectOption` for single, `SelectOption[]` for multiple.
**Features:**
* `selectionMode="multiple"` enables toggling multiple items; `closeOnPress` defaults to `false` in multiple mode
* Type-safe generics: `RootProps` resolves `value` and `onValueChange` types via `SelectValueType`
* `Select.Value` formats multiple labels as "Apple, Banana and Cherry" using `formatSelectedLabels`
* Single mode remains fully backward-compatible (default)
**Usage:**
```tsx
import { Select } from "heroui-native";
export function MultiSelect() {
return (
);
}
```
**Related PR:** [#298](https://github.com/heroui-inc/heroui-native/pull/298)
### New Subcomponents
#### PressableFeedback.Scale
A new compound sub-component for opt-in scale animation composability. `PressableFeedback.Scale` lets you add scale press animations to any pressable element—such as `ListGroup.Item`—without needing the root `PressableFeedback` to manage scale.
**Usage:**
```tsx
import { PressableFeedback } from "heroui-native";
{/* item content */}
```
**Related PR:** [#302](https://github.com/heroui-inc/heroui-native/pull/302)
## Component Improvements
### Select Trigger and State Fixes
The [Select](/docs/native/components/select) component has been improved with several targeted fixes to the trigger and controllable state system.
**Improvements:**
* Custom `className` is now correctly forwarded to the trigger's style computation, resolving cases where user-provided classes were silently dropped
* `useControllableState` now resets internal state when transitioning from controlled to uncontrolled, preventing stale selections from persisting
* Trigger measures position via `onLayout` to properly support `isDefaultOpen`
* Updated trigger styles to use `gap-3`, `py-3.5` padding, and `flex-1` on the value text for improved layout
**Related PR:** [#298](https://github.com/heroui-inc/heroui-native/pull/298)
### Avatar asChild Image Fix
The [Avatar](/docs/native/components/avatar) component's `AvatarImage` now correctly separates `source`, `style`, and `asChild` from rest props when forwarding to the underlying primitive, fixing an issue where all props were incorrectly spread to the image component when using `asChild`.
**Related PR:** [#298](https://github.com/heroui-inc/heroui-native/pull/298)
## API Enhancements
### Button Feedback API Refactor
The [Button](/docs/native/components/button) component's pressable feedback API has been refactored into a unified, type-safe `feedbackVariant` + `animation` prop pattern, replacing the previous multi-prop approach.
**New Capability:**
```tsx
import { Button } from "heroui-native";
// Scale + highlight (default)
// Scale + ripple
// Scale only
// Custom animation configuration
```
The `animation` prop is a discriminated union typed per variant, providing full type-safety for each feedback configuration.
New utility helpers `resolveAnimationObject` and `isAnimationDisabled` in `button.utils.ts` centralise animation prop resolution.
**Related PR:** [#302](https://github.com/heroui-inc/heroui-native/pull/302)
## Dependencies
### Relaxed Peer Dependency Constraints
Peer dependency version constraints have been relaxed to use caret (`^`) and range (`>=`) specifiers instead of restrictive tilde (`~`) or pinned versions. This improves compatibility for consumers on newer dependency versions, particularly those using Expo SDK 55.
**Changes:**
* `react-native-reanimated`: `~4.1.1` → `^4.1.1` (allows minor updates)
* `react-native-safe-area-context`: `~5.6.0` → `^5.6.0` (allows minor updates)
* `react-native-svg`: `15.12.1` → `^15.12.1` (allows patch/minor updates)
* `react-native-worklets`: `0.5.1` → `>=0.5.1` (allows any version 0.5.1+)
No runtime code changes are included—existing projects with previously valid versions continue to work without modification.
**Related PR:** [#306](https://github.com/heroui-inc/heroui-native/pull/306)
## ⚠️ Breaking Changes
### Button Feedback API
The `pressableFeedbackVariant`, `pressableFeedbackHighlightProps`, and `pressableFeedbackRippleProps` props on Button have been removed. Consumers must migrate to `feedbackVariant` and the unified `animation` prop.
**Migration:**
Update all Button feedback prop usages:
```tsx
// Before
// After
```
**Variant mapping:**
* `"highlight"` → `"scale-highlight"` (default)
* `"ripple"` → `"scale-ripple"`
* `"none"` → `"scale"` or `"none"`
**Available options:**
* `"scale-highlight"` - Scale down with highlight overlay (default)
* `"scale-ripple"` - Scale down with ripple effect
* `"scale"` - Scale down only
* `"none"` - No feedback animation
**Related PR:** [#302](https://github.com/heroui-inc/heroui-native/pull/302)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #291](https://github.com/heroui-inc/heroui-native/issues/291)**: Fixed `Select.Trigger` variant prop being overwritten by `className`. Custom class names passed to the trigger are now correctly forwarded to the style computation instead of being silently dropped.
* **[Issue #294](https://github.com/heroui-inc/heroui-native/issues/294)**: Resolved compatibility with `react-native-worklets` 0.7.x and `react-native-reanimated` 4.2.x (Expo SDK 55). Peer dependency constraints have been relaxed to accept these newer versions without producing resolution warnings.
**Related PRs:**
* [#298](https://github.com/heroui-inc/heroui-native/pull/298)
* [#306](https://github.com/heroui-inc/heroui-native/pull/306)
## Updated Documentation
The following documentation pages have been updated to reflect the changes in this release:
* [SearchField](/docs/native/components/search-field) - New component documentation with usage examples and API reference
* [ListGroup](/docs/native/components/list-group) - New component documentation with usage examples and API reference
* [Slider](/docs/native/components/slider) - New component documentation with usage examples and API reference
* [Select](/docs/native/components/select) - Multi-selection mode, trigger className fix, and controllable state improvements
* [Button](/docs/native/components/button) - Updated feedback API documentation with new `feedbackVariant` and `animation` props
* [Avatar](/docs/native/components/avatar) - Fixed `asChild` image prop spreading documentation
* [PressableFeedback](/docs/native/components/pressable-feedback) - New `PressableFeedback.Scale` subcomponent documentation
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# RC 3
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/rc-3
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/rc-3.mdx
> TagGroup, Menu, and InputGroup components, Bottom Sheet Android back press fix, Expo 55 compatibility
February 26, 2026
RC 3 delivers three new components—TagGroup for selectable tag management, Menu for popover/bottom-sheet-based dropdown menus, and InputGroup for decorated text inputs with auto-measuring prefix/suffix slots. This release also brings Android hardware back button support for all bottom-sheet-based overlays, Expo 55 compatibility with a critical `combineStyles` fix that preserves Reanimated animated style bindings, and several dependency upgrades.
## Installation
Update to the latest version:
```bash
npm i heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the RC 3 improvements in action with our preview app! You can explore the new TagGroup, Menu, and InputGroup components, Android back press support for bottom sheets, and all the bug fixes directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
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** components:
* **[TagGroup](/docs/native/components/tag-group)**: Compound component for displaying and managing selectable tags with optional removal, single/multiple selection, and form field integration.
* **[Menu](/docs/native/components/menu)**: Dropdown menu system with popover and bottom-sheet presentation modes, single/multiple selection, item variants, and animated press feedback.
* **[InputGroup](/docs/native/components/input-group)**: Decorated text input with absolutely-positioned prefix/suffix slots that auto-measure widths and apply matching padding to the input.
#### TagGroup
The TagGroup component provides a compound component pattern for rendering selectable tag groups with optional removal support. It supports single and multiple selection modes, controlled and uncontrolled APIs, two visual variants (default and surface), three sizes, disabled states, and full form field integration with Label, Description, and FieldError.
**Features:**
* Compound sub-components: `TagGroup.List`, `TagGroup.Item`, `TagGroup.ItemLabel`, `TagGroup.ItemRemoveButton`
* Single and multiple selection modes with controlled/uncontrolled APIs
* Two visual variants: `default` and `surface`
* Three sizes: `sm`, `md`, `lg`
* Per-item disabled state and `disabledKeys` support
* Remove functionality via `onRemove` callback and `TagGroup.ItemRemoveButton`
* Empty state rendering via `renderEmptyState` on `TagGroup.List`
* Form field integration with Label, Description, FieldError, `isInvalid`, and `isRequired`
* `useTagGroup` and `useTagGroupItem` hooks for advanced use cases
**Usage:**
```tsx
import { TagGroup } from "heroui-native";
export function BasicTagGroup() {
return (
ReactVueSvelte
);
}
export function RemovableTagGroup() {
const [items, setItems] = useState(["React", "Vue", "Svelte"]);
return (
setItems((prev) => prev.filter((i) => !keys.has(i)))}>
{items.map((item) => (
{item}
))}
);
}
```
For complete documentation and examples, see the [TagGroup component page](/docs/native/components/tag-group).
**Related PR:** [#309](https://github.com/heroui-inc/heroui-native/pull/309)
#### Menu
The Menu component provides a dropdown menu system built on a compound component pattern, supporting both popover and bottom-sheet presentation modes. It includes full Reanimated-based press animations, single and multiple selection modes, item variants (default and danger), indicator styles, and configurable placement.
**Features:**
* Compound sub-components: `Menu.Trigger`, `Menu.Portal`, `Menu.Overlay`, `Menu.Content`, `Menu.Label`, `Menu.Group`, `Menu.Item`, `Menu.ItemTitle`, `Menu.ItemDescription`, `Menu.ItemIndicator`
* Two presentation modes: `popover` and `bottom-sheet` with configurable placement (`top`, `bottom`, `left`, `right`)
* Single and multiple selection via `Menu.Group` with `selectedKeys`/`onSelectionChange`
* Item press animations (scale + background color) via Reanimated with full customization through the `animation` prop
* Item variants: `default` and `danger`
* Indicator variants: `checkmark`, `dot`, and custom content
* `Menu.Label` for section headings
* `shouldCloseOnSelect` control per group
**Usage:**
```tsx
import { Menu } from "heroui-native";
export function BasicMenu() {
return (
);
}
export function MenuWithSections() {
return (
);
}
```
For complete documentation and examples, see the [Menu component page](/docs/native/components/menu).
**Related PR:** [#312](https://github.com/heroui-inc/heroui-native/pull/312)
#### InputGroup
The InputGroup component provides a decorated text input with absolutely-positioned `Prefix` and `Suffix` sub-components that automatically measure their widths via `onLayout` and apply matching padding to the Input. It features a convenient `isDecorative` prop that handles accessibility and pointer-event boilerplate for decorative addons in a single boolean, and a root `isDisabled` prop that cascades disabled state to all children via context.
**Features:**
* Compound sub-components: `InputGroup.Prefix`, `InputGroup.Suffix`, `InputGroup.Input`
* Auto-padding: Prefix/Suffix widths are measured via `onLayout` and automatically applied as `paddingLeft`/`paddingRight` on the Input
* `isDecorative` prop on Prefix/Suffix handles `pointerEvents="none"`, `accessibilityElementsHidden`, and `importantForAccessibility` in a single boolean
* Root `isDisabled` cascades to all children via context (Prefix/Suffix opacity + pointer-events, Input editability)
* `InputGroup.Input` is a direct pass-through — consumers manage `value`/`onChangeText` directly on the Input
**Usage:**
```tsx
import { InputGroup } from "heroui-native";
export function SearchInput() {
return (
);
}
export function DisabledInput() {
return (
);
}
```
For complete documentation and examples, see the [InputGroup component page](/docs/native/components/input-group).
**Related PR:** [#313](https://github.com/heroui-inc/heroui-native/pull/313)
## Component Improvements
### Bottom Sheet Android Back Press Support
The [Bottom Sheet](/docs/native/components/bottom-sheet) shared container now handles the Android hardware back button, dismissing any open bottom sheet when pressed. The `BackHandler` listener is only active while the sheet is open, preventing closed instances from consuming the event. This fix applies globally to all bottom-sheet-based components.
**Supported components:**
* [Bottom Sheet](/docs/native/components/bottom-sheet)
* [Popover](/docs/native/components/popover)
* [Select](/docs/native/components/select)
The fix uses React Native's `BackHandler` API which is a no-op on iOS, so no platform-specific handling is needed.
**Related PR:** [#308](https://github.com/heroui-inc/heroui-native/pull/308)
### Slot `combineStyles` Fix
The Slot primitive's `combineStyles` function now returns style arrays instead of using `StyleSheet.flatten`, which was destroying Reanimated `SharedValue` and `useAnimatedStyle` bindings by deep-copying style objects into plain objects.
**Improvements:**
* `combineStyles` preserves Reanimated animated style bindings by returning arrays
* React Native handles nested style arrays natively, so consumer behavior is unchanged
* Fixes animation breakages across components that compose via the Slot primitive
**Related PR:** [#314](https://github.com/heroui-inc/heroui-native/pull/314)
## Dependencies
### Expo 55 Compatibility
Dependency versions have been updated for Expo SDK 55 compatibility:
* `uniwind`: 1.2.7 → 1.3.2
* `@gorhom/bottom-sheet`: ^5 → ^5.2.8
The `combineStyles` fix described above is the primary code change enabling Expo 55 support, as the previous `StyleSheet.flatten` approach broke Reanimated style bindings in the new SDK.
**Related PR:** [#314](https://github.com/heroui-inc/heroui-native/pull/314)
## Bug Fixes
This release includes fixes for the following issues:
* **[Issue #272](https://github.com/heroui-inc/heroui-native/issues/272)**: Resolved `FullWindowOverlay` interfering with the React Native element inspector.
* **[Issue #280](https://github.com/heroui-inc/heroui-native/issues/280)**: Fixed Avatar component and other Reanimated-dependent components breaking under Expo 55. The `combineStyles` function was destroying Reanimated animated style bindings via `StyleSheet.flatten`; it now returns style arrays to preserve `SharedValue` and `useAnimatedStyle` bindings.
**Related PRs:**
* [#308](https://github.com/heroui-inc/heroui-native/pull/308)
* [#314](https://github.com/heroui-inc/heroui-native/pull/314)
## Updated Documentation
The following documentation pages have been updated to reflect the changes in this release:
* [TagGroup](/docs/native/components/tag-group) - New component documentation with usage examples and API reference
* [Menu](/docs/native/components/menu) - New component documentation with usage examples and API reference
* [InputGroup](/docs/native/components/input-group) - New component documentation with usage examples and API reference
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# RC 4
**Category**: native
**URL**: https://v3.heroui.com/docs/native/releases/rc-4
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/releases/rc-4.mdx
> SubMenu component, Slider Output composition, PressableFeedback ripple fix, Bottom Sheet back handler fix
March 6, 2026
RC 4 introduces the SubMenu compound component for nested expandable menus with spring-animated expand/collapse, refactors Slider Output with slot-based styling and `textProps` forwarding, and adds `disallowEmptySelection` to Menu.Group for radio-group behavior. This release also resolves the PressableFeedback ripple blink on rapid presses with a dual-layer buffer system, fixes the Bottom Sheet Android back handler to respect `enablePanDownToClose`.
## Installation
Update to the latest version:
```bash
npm i heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
**Using 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](/docs/native/getting-started/mcp-server).
## Try It Out
Experience all the RC 4 improvements in action with our preview app! You can explore the new SubMenu component, improved Slider Output, and all the bug fixes directly on your device.
### Prerequisites
Make sure you have the latest version of [Expo Go](https://expo.dev/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**
**[📱 Open Demo App in Expo Go](https://link.heroui.com/native-demo)**
This will automatically open the app in Expo Go if it's installed on your device.
## What's New
### SubMenu Component
The [Menu](/docs/native/components/menu) component now supports nested expandable sub-menus via the new `SubMenu` compound component. SubMenu nests inside `Menu.Content` and reveals additional items on press with spring-based expand/collapse animations and indicator rotation.
**Features:**
* Compound sub-components: `SubMenu`, `SubMenu.Trigger`, `SubMenu.TriggerIndicator`, `SubMenu.Content`
* Spring-based expand/collapse animation with indicator rotation
* Headless primitive layer with context, controlled/uncontrolled open state, and accessibility attributes (`role`, `aria-expanded`, `aria-disabled`)
* Parent menu coordination: popover scales to 0.98, shadow is removed, and non-SubMenu items fade to 40% opacity with `pointer-events-none` when a SubMenu is open
* Menu content switches to `FadeOut` exit animation when a SubMenu is open to avoid conflicting scale animations
* `useSubMenu` hook for advanced use cases
**Usage:**
```tsx
import { Menu, SubMenu } from "heroui-native";
export function MenuWithSubMenu() {
return (
);
}
```
For complete documentation and examples, see the [Menu component page](/docs/native/components/menu).
**Related PR:** [#331](https://github.com/heroui-inc/heroui-native/pull/331)
## Component Improvements
### Slider Output Composition Refactor
The [Slider](/docs/native/components/slider) Output component has been refactored to use a proper slot-based architecture with `container` and `text` slots, and introduces `textProps` for forwarding props to the inner text element.
**Improvements:**
* Slot-based styling: `output` class split into `container` and `text` slots with a new `classNames` prop (`classNames={{ container, text }}`) for granular style targeting
* Composition fix: `HeroText` now only renders for default content; custom children render directly without an extra text wrapper
* New `textProps` prop on `Slider.Output` for forwarding arbitrary props (e.g., `maxFontSizeMultiplier`) to the inner text element
* `OutputSlots` type exported from the styles module for external consumption
**Related PR:** [#328](https://github.com/heroui-inc/heroui-native/pull/328)
### Menu.Group `disallowEmptySelection`
The [Menu](/docs/native/components/menu) `Menu.Group` component now supports a `disallowEmptySelection` prop that prevents deselecting the last item in `single` selection mode, enabling radio-group behavior.
**Usage:**
```tsx
List ViewGrid View
```
**Related PR:** [#331](https://github.com/heroui-inc/heroui-native/pull/331)
### Bottom Sheet `enablePanDownToClose` Consistency
The [Bottom Sheet](/docs/native/components/bottom-sheet) component now correctly respects the `enablePanDownToClose` prop for Android hardware back button behavior. Previously, the back button would close the sheet even when `enablePanDownToClose` was set to `false`.
**Improvements:**
* The `enablePanDownToClose` prop is threaded through to `BottomSheetContentContainer` (defaults to `true`)
* The `BackHandler` event listener is only registered when both `isOpen` and `enablePanDownToClose` are `true`
* Bottom sheets with `enablePanDownToClose={false}` are no longer dismissible via the Android back button
**Related PR:** [#327](https://github.com/heroui-inc/heroui-native/pull/327)
## ⚠️ Breaking Changes
### Chip Component Sizing
The [Chip](/docs/native/components/chip) component's size variants have been migrated from fixed heights to padding-based sizing to accommodate dynamic text scaling at larger accessibility font sizes.
**Migration:**
Custom styles relying on the previous `h-5`/`h-6`/`h-7` chip heights should be updated to use the new padding-based approach:
```tsx
// Before — Fixed height sizing
// Chip used h-5 (sm), h-6 (md), h-7 (lg)
// After — Padding-based sizing
// Chip uses py-0.5 (sm), py-[3px] (md), py-1 (lg)
// Border radius updated: rounded-xl → rounded-2xl/rounded-3xl
```
## Updated Documentation
The following documentation pages have been updated to reflect the changes in this release:
* [Menu](/docs/native/components/menu) - SubMenu component documentation with anatomy, usage examples, full API reference, and `useSubMenu` hook docs
* [Slider](/docs/native/components/slider) - Updated Output component documentation with slot-based styling and `textProps`
## Links
* [Component Documentation](../components)
* [GitHub Repository](https://github.com/heroui-inc/heroui-native)
## Contributors
Thanks to everyone who contributed to this release!
# All Components
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/index.mdx
> Explore the full list of components available in the library. More are on the way.
## Buttons
## Collections
## Colors
## Controls
## Data Display
## Date and Time
## Feedback
## Forms
## Layout
## Media
## Navigation
## Overlays
## Pickers
## Typography
## Utilities
# Introduction
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/index.mdx
> An open-source UI component library for building beautiful and accessible user interfaces.
HeroUI is a React component library built on [Tailwind CSS v4](https://tailwindcss.com/) and [React Aria Components](https://react-spectrum.adobe.com/react-aria/index.html). Every component comes with smooth animations, polished details, and built-in accessibility—ready to use, fully customizable.
## Why HeroUI?
**Beautiful by default** — Professional look out of the box, no extra styling needed.
**Accessible** — Built on [React Aria Components](https://react-spectrum.adobe.com/react-aria/components.html) with focus management, keyboard navigation, and screen reader support.
**Flexible** — Each component is made of customizable parts. Change what you need, leave the rest.
**Developer-friendly** — Fully typed APIs, predictable patterns, and excellent autocompletion.
**Maintained** — We handle updates, bug fixes, and new features. Just update the package.
**Lightweight** — Tree-shaken. Only what you use goes into your app.
**Future-proof** — Built for [React 19](https://react.dev/blog/2024/12/05/react-19) and [Tailwind v4](https://tailwindcss.com/blog/tailwindcss-v4), designed for AI-assisted development.
## A Living Library, Not Copy-Paste
Copy-paste code works until it breaks. You're left maintaining outdated dependencies that stop evolving.
HeroUI is different. It's a living library that grows with you:
* Automatic updates and fixes
* New features without extra work
* Components stay current with React, Tailwind, and browsers
* Deep customization, not shallow theme tweaks
* AI-friendly APIs for code generation
HeroUI v3 is not a snapshot—it's a garden that keeps growing. 🌱
## HeroUI Ecosystem
* **🌐 HeroUI v3** (web) — You're here! React components with Tailwind CSS v4
* **📱 [HeroUI Native](https://link.heroui.com/native)** (mobile) — Beautiful components for React Native
* **🤖 [HeroUI Chat](https://heroui.chat?ref=heroui-v3)** (text-to-app) — Create apps with natural language
* **🧠 UI for LLMs** — New platform & MCPs coming soon
**Why React Aria?** We chose React Aria for accessibility at scale. We've used it since HeroUI v2, and v3 keeps familiar API conventions like `isDisabled` and `onPress`. Thanks to [Devon Govett](https://x.com/devongovett) and the Adobe team.
## FAQ
**Is HeroUI free?**
Yes, completely free and open source under the MIT license.
**Is it production-ready?**
Currently in **beta**. We're actively working towards a stable release with community feedback.
**Can I customize the components?**
Yes! Use Tailwind utilities, CSS variables, [BEM](https://getbem.com/) modifiers, or compose component parts differently. Every slot is customizable.
**Does it work with TypeScript?**
Fully typed with excellent IDE support and autocompletion.
**What about accessibility?**
Built on React Aria Components for WCAG compliance. Keyboard navigation, focus management, and screen reader support included.
**Can I use the styles without React?**
Yes, the CSS can be applied to plain HTML. See our [Tailwind Play example](https://play.tailwindcss.com/Ioomj2xdce).
**Is there a Figma file?**
Yes! Access our design system at [HeroUI Figma Kit V3](https://www.figma.com/community/file/1546526812159103429).
## Get Involved
Join the community, share feedback, or contribute:
* [GitHub Discussions](https://github.com/heroui-inc/heroui/discussions)
* [Discord](https://discord.gg/9b6yyZKmH4)
* [X/Twitter](https://x.com/hero_ui)
* [Contributing Guidelines](https://github.com/heroui-inc/heroui/blob/main/CONTRIBUTING.md)
HeroUI is released under the [MIT License](https://github.com/heroui-inc/heroui/blob/main/LICENSE).
# All Releases
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/index.mdx
> All updates and changes to HeroUI v3, including new features, fixes, and breaking changes.
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## Latest Release
### v3.0.0-beta.8
**March 2, 2026**
This release adds three new components ([Badge](/docs/components/badge), [Pagination](/docs/components/pagination), [Table](/docs/components/table)) and new `InputContainer` composition APIs for [DateField](/docs/components/date-field) + [TimeField](/docs/components/time-field). ⚠️ **Breaking changes**: TextField CSS classes were renamed from `.text-field` to `.textfield`.
[Read full release notes →](/docs/releases/v3-0-0-beta-8)
### v3.0.0-beta.7
**February 18, 2026**
This release introduces a comprehensive **Date & Time** system with four new components ([Calendar](/docs/components/calendar), [RangeCalendar](/docs/components/range-calendar), [DatePicker](/docs/components/date-picker), [DateRangePicker](/docs/components/date-range-picker)), new [Switch.Content](/docs/components/switch) sub-component, explicit [Tabs.Separator](/docs/components/tabs) for opt-in separator lines, and ⚠️ **breaking changes** removing `hideSeparator` from Tabs and consolidating `DateInputGroup`/`ColorInputGroup` under their respective field components.
[Read full release notes →](/docs/releases/v3-0-0-beta-7)
### v3.0.0-beta.6
**February 6, 2026**
This release introduces a comprehensive **Color System** with six new components ([ColorPicker](/docs/components/color-picker), [ColorArea](/docs/components/color-area), [ColorSlider](/docs/components/color-slider), [ColorField](/docs/components/color-field), [ColorSwatch](/docs/components/color-swatch), [ColorSwatchPicker](/docs/components/color-swatch-picker)), major [Toast](/docs/components/toast) improvements with loading states and promise support, [Separator](/docs/components/separator) variants, and ⚠️ **breaking changes** renaming `Toast.Container` to `Toast.Provider` and updating CSS class names to hyphenated format.
[Read full release notes →](/docs/releases/v3-0-0-beta-6)
### v3.0.0-beta.5
* Fixed build issue
### v3.0.0-beta.4
**January 20, 2026**
**Critical Build Issue Fixed**: This version (beta.4) had a critical build issue that has been fixed in **beta.5**. Please upgrade to `@heroui/styles@3.0.0-beta.5` and `@heroui/react@3.0.0-beta.5` to ensure proper TypeScript declaration generation and export resolution.
This release introduces the new [Theme Builder](/themes) for visual theme customization, three new components ([Autocomplete](/docs/components/autocomplete), [Breadcrumbs](/docs/components/breadcrumbs), [Toast](/docs/components/toast)), secondary variant for [Tabs](/docs/components/tabs), primary/secondary variants for [Input](/docs/components/input) and [InputGroup](/docs/components/input-group), and ⚠️ **breaking changes** removing Link's underline variants and `isInSurface` prop from form components.
[Read full release notes →](/docs/releases/v3-0-0-beta-4)
### v3.0.0-beta.3
**December 19, 2025**
This release introduces seven new components ([ButtonGroup](/docs/components/button-group), [DateField](/docs/components/date-field), [ErrorMessage](/docs/components/error-message), [ScrollShadow](/docs/components/scroll-shadow), [SearchField](/docs/components/search-field), [TagGroup](/docs/components/tag-group), [TimeField](/docs/components/time-field)), adds `fullWidth` support for form and input components, introduces `hideSeparator` to [Tabs](/docs/components/tabs), [ButtonGroup](/docs/components/button-group), and [Accordion](/docs/components/accordion) for cleaner layouts, includes styling fixes, and ⚠️ **breaking changes** removing the `asChild` prop and updating [AlertDialog](/docs/components/alert-dialog) & [Modal](/docs/components/modal) backdrop variant.
[Read full release notes →](/docs/releases/v3-0-0-beta-3)
### v3.0.0-beta.2
**November 20, 2025**
This release introduces six essential new components ([AlertDialog](/docs/components/alert-dialog), [ComboBox](/docs/components/combo-box), [Dropdown](/docs/components/dropdown), [InputGroup](/docs/components/input-group), [Modal](/docs/components/modal), [NumberField](/docs/components/number-field)), enhances theme compatibility and motion preferences, improves the [Select](/docs/components/select) component API with a ⚠️ **breaking change**, plus various refinements and bug fixes.
[Read full release notes →](/docs/releases/v3-0-0-beta-2)
### v3.0.0-beta.1
**November 6, 2025**
This release introduces a comprehensive redesign of HeroUI v3, merging v2's beauty and animations with v3's simplicity. All components have been redesigned, 8 new components added ([Alert](/docs/compoenents/alert), [Checkbox](/docs/components/checkbox), [InputOTP](/docs/components/input-otp), [ListBox](/docs/components/listbox), [Select](/docs/components/select), [Slider](/docs/components/slider), [Surface](/docs/components/surface)), and the design system has been completely overhauled with better color tokens, shadows, and architecture. Includes breaking changes to design system variables, component APIs, and flexible component patterns.
[Read full release notes →](/docs/releases/v3-0-0-beta-1)
## Previous Releases
### v3.0.0-alpha.35
**October 21, 2025**
#### React Server Components Support
* Fixed critical issue where compound components didn't work in React Server Components (RSC)
* Moved compound pattern logic from components to index files, resolving `"use client"` conflicts
* **(⚠️ Breaking change)**: Main component now requires `.Root` suffix (e.g., `` → ``)
* Named exports remain unchanged and fully supported
#### React 19 Improvements
* Removed `forwardRef` (now native in [React 19](https://react.dev/blog/2024/12/05/react-19#ref-as-a-prop))
* Simplified Context usage (`Context.Provider` → [React 19](https://react.dev/blog/2024/12/05/react-19#context-as-a-provider))
#### Switch Component Refactoring
* **(⚠️ Breaking change)**: Split Switch and SwitchGroup into separate components
* Cleaner API: `` replaces `` and ``
* Matches Radio/RadioGroup pattern for consistency
* Separate styles, types, and implementations
#### Affected Components
All compound components now require `.Root` suffix: `Accordion`, `Avatar`, `Card`, `Disclosure`, `Fieldset`, `Kbd`, `Link`, `Popover`, `Radio`, `Switch`, `Tabs`, `Tooltip`
[Read full release notes →](/docs/releases/v3-0-0-alpha-35)
### v3.0.0-alpha.34
**October 15, 2025**
* Added Form-based components: [Description](/docs/components/description), [FieldError](/docs/components/field-error), [Fieldset](/docs/components/fieldset), [Form](/docs/components/form), [Input](/docs/components/input), [Label](/docs/components/label), [RadioGroup](/docs/components/radio-group), [TextField](/docs/components/text-field), and [TextArea](/docs/components/textarea).
* Introduced form field tokens `--field-*`
* Reorganized Storybook by category
* **(Breaking change)**: Renamed `--skeleton-default-animation-type` to `--skeleton-animation` in [Skeleton](/docs/components/skeleton)
* Aligned data-slot markers across components
* Improved documentation
[Read full release notes →](/docs/releases/v3-0-0-alpha-34)
### v3.0.0-alpha.33
**October 5, 2025**
* Upgraded RAC with [October 2, 2025 Release](https://react-spectrum.adobe.com/releases/2025-10-02.html)
* Reordered [Tabs](/docs/components/tabs) Indicator (**Breaking change**)
* Updated [Tabs](/docs/components/tabs) component to use React Aria's `SelectionIndicator`, now supports SSR
* Updated [Disclosure](/docs/components/disclosure) and [Disclosure Group](/docs/components/disclosure-group) components to use RAC CSS variables for the expand and collapse animations
* Updated [Switch](/docs/components/switch) component styles and animations
* Added `size` variants and added demo in [Switch](/docs/components/switch#sizes)
* Added related showcases in [Button](/docs/components/button), [Tabs](/docs/components/tabs), [Disclosure](/docs/components/disclosure), [Disclosure Group](/docs/components/disclosure-group)
* Improved documentation
[Read full release notes →](/docs/releases/v3-0-0-alpha-33)
### v3.0.0-alpha.32
**October 1, 2025**
Card component redesigned with [new variants](/docs/components/card), added [CloseButton](/docs/components/close-button) component, [MCP Server](/docs/ui-for-agents/mcp-server) for AI coding assistants, and improved documentation.
[Read full release notes →](/docs/releases/v3-0-0-alpha-32)
### v3.0.0-alpha.31
**September 22, 2025**
* 🎨 **Showcases page** - Gallery of sites built with HeroUI
* 🌀 **DisclosureGroup component** - Groups multiple disclosures together
* 📇 **Card component** (preview) - First version of card component
* 🔀 **Switch component** (preview) - Toggle switch for settings
## Release Schedule
HeroUI v3 follows a regular release cycle:
* **Alpha releases**: Weekly to bi-weekly during active development
* **Beta releases**: Monthly stabilization releases - In progress
* **Stable releases**: Quarterly major versions (Q4 2025 target)
## Contributing
Found an issue or want to contribute? Check out our [GitHub repository](https://github.com/heroui-inc/heroui).
# v3.0.0-alpha.32
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-alpha-32
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-alpha-32.mdx
> Card component redesign, CloseButton, MCP Server for AI assistants
October 1, 2025
This release adds AI development tools, updates the [Card component](/docs/components/card) API, and improves the developer experience.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@alpha @heroui/react@alpha
```
```bash
pnpm add @heroui/styles@alpha @heroui/react@alpha
```
```bash
yarn add @heroui/styles@alpha @heroui/react@alpha
```
```bash
bun add @heroui/styles@alpha @heroui/react@alpha
```
## What's New
### MCP Server
HeroUI now includes an [MCP server](/docs/ui-for-agents/mcp-server) that lets AI assistants like Cursor, Claude Code, and VS Code Copilot access HeroUI v3 documentation and component information directly.
**Quick Setup:**
### Cursor
Or manually add to **Cursor Settings** → **Tools** → **MCP Servers**:
```json
{
"mcpServers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"]
}
}
}
```
### Claude Code
Run this command in your terminal:
```bash
claude mcp add heroui-react -- npx -y @heroui/react-mcp@latest
```
[Learn more](/docs/ui-for-agents/mcp-server)
### Card Component API Redesign
The [Card component](/docs/components/card) has been updated with a new variant system that makes it more flexible.
**Breaking Changes:**
* Replaced `surface` prop with new `variant` system
* Removed `Card.Image`, `Card.Details`, and `Card.CloseButton` (use composition instead)
* New variants: `flat`, `outlined`, `elevated`, `filled`
**Before:**
```tsx
Old Card
```
**After:**
```tsx
New Card
```
**New Features:**
* Horizontal layout support
* Avatar integration
* Background image support
* Improved accessibility with semantic HTML
[View Card documentation](/docs/components/card)
### CloseButton Component
Added a [CloseButton component](/docs/components/close-button) for closing dialogs, modals, and other dismissible elements.
```tsx
import {CloseButton} from "@heroui/react";
// Basic usage
console.log("Closed")} />
// With custom icon
```
## Documentation Improvements
### UI for Agents
* **[MCP Server documentation](/docs/ui-for-agents/mcp-server)** for development with AI assistants
* **[llms.txt](/docs/ui-for-agents/llms-txt)** file for LLM-friendly documentation
* Setup guides for popular AI coding tools
### Component Documentation
* **[Card](/docs/components/card)**: Rewrote documentation with anatomy, variants, and more examples
* **[Switch](/docs/components/switch)**: Added anatomy diagrams and better examples
* **[CloseButton](/docs/components/close-button)**: New documentation with usage examples
## Migration Guide
### Card Component Migration
1. **Update variant prop:**
* `surface="1"` → `variant="flat"`
* `surface="2"` → `variant="outlined"`
* `surface="3"` → `variant="elevated"`
* `surface="4"` → `variant="filled"`
* Custom surfaces → Use new variant system
2. **Update component structure:**
* Replace `Card.Image` with `` in `Card.Header`
* Replace `Card.Details` with `Card.Body`
* Move `Card.CloseButton` to use new `CloseButton` component
3. **Update imports:**
```tsx
// Add CloseButton if needed
import {Card, CloseButton} from "@heroui/react";
```
## Links
* [GitHub PR #5747](https://github.com/heroui-inc/heroui/pull/5747)
* [MCP Server Documentation](/docs/ui-for-agents/mcp-server)
* [Card Component Guide](/docs/components/card)
* [CloseButton Component](/docs/components/close-button)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-alpha.33
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-alpha-33
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-alpha-33.mdx
> RAC upgrade, Tabs indicator redesign, Switch size variant, Related showcase
October 5, 2025
This release upgrades React Aria Components, redesigns the Tabs indicator, adds Switch sizes, and includes component showcases.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@alpha @heroui/react@alpha
```
```bash
pnpm add @heroui/styles@alpha @heroui/react@alpha
```
```bash
yarn add @heroui/styles@alpha @heroui/react@alpha
```
```bash
bun add @heroui/styles@alpha @heroui/react@alpha
```
## What's New
### RAC Upgrade
Upgraded React Aria Components to the [October 2, 2025 Release](https://react-spectrum.adobe.com/releases/2025-10-02.html).
This release includes:
* CSS variables for animations
* Better SSR support
* Performance improvements for selection indicators
### Disclosure and Disclosure Group Updates
[Disclosure](/docs/components/disclosure) and [Disclosure Group](/docs/components/disclosure-group) now use React Aria's CSS variables for animations. The components use `--disclosure-panel-width` and `--disclosure-panel-height` variables that track the panel's actual size during expand/collapse.
### Tabs Indicator Redesign
[Tabs](/docs/components/tabs) now uses React Aria's `SelectionIndicator` and supports SSR. This fixes layout shifts on initial render.
**🚧 Breaking Changes:**
* Moved `Tabs.Indicator` inside each `Tabs.Tab`
**Before:**
```diff tsx
+
-
```
### Switch Updates
[Switch](/docs/components/switch) has updated styles and animations. Added `size` prop with options: `sm`, `md`, `lg`.
```tsx
import {Label, Switch} from "@heroui/react";
export function Sizes() {
return (
);
}
```
### Related showcases
Related showcases have been added in [Button](/docs/components/button), [Disclosure](/docs/components/disclosure), [Disclosure Group](/docs/components/disclosure-group) and [Tabs](/docs/components/tabs).
## Documentation Improvements
### Component Documentation
* **[Tabs](/docs/components/tabs)**: Updated anatomy, revised examples with new indicator design and added related showcase
* **[Switch](/docs/components/switch)**: Added size example and revised with-icon example
* **[Button](/docs/components/button)**, **[Disclosure](/docs/components/disclosure)**, **[Disclosure Group](/docs/components/disclosure-group)**: Added related showcase
## Migration Guide
### Tabs Component Migration
1. **Update component structure:**
* move `` inside each ``
## Links
* [GitHub PR #5777](https://github.com/heroui-inc/heroui/pull/5777)
* [Tabs Component](/docs/components/tabs)
* [Switch Component](/docs/components/switch)
* [Button Component](/docs/components/button)
* [Disclosure Component](/docs/components/disclosure)
* [Disclosure Group Component](/docs/components/disclosure-group)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-alpha.34
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-alpha-34
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-alpha-34.mdx
> Essentials for building forms with a clean API Form, TextField, RadioGroup, Label, Input, Fieldset and more.
October 15, 2025
This release introduces Form-based components, form field tokens, reorganizes Storybook, and aligns data-slot markers across components.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@alpha @heroui/react@alpha
```
```bash
pnpm add @heroui/styles@alpha @heroui/react@alpha
```
```bash
yarn add @heroui/styles@alpha @heroui/react@alpha
```
```bash
bun add @heroui/styles@alpha @heroui/react@alpha
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### Form-based Components
We've introduced a comprehensive set of form-based components built on React Aria Components, providing accessible and composable building blocks for creating forms. These components include [Description](/docs/components/description), [FieldError](/docs/components/field-error), [Fieldset](/docs/components/fieldset), [Form](/docs/components/form), [Input](/docs/components/input), [Label](/docs/components/label), [RadioGroup](/docs/components/radio-group), [TextField](/docs/components/text-field), and [TextArea](/docs/components/textarea).
#### Description
```tsx
import {Description, Input, Label} from "@heroui/react";
export function Basic() {
return (
We'll never share your email with anyone else.
);
}
```
#### FieldError
```tsx
"use client";
import {FieldError, Input, Label, TextField} from "@heroui/react";
import {useState} from "react";
export function Basic() {
const [value, setValue] = useState("jr");
const isInvalid = value.length > 0 && value.length < 3;
return (
setValue(e.target.value)}
/>
Username must be at least 3 characters
);
}
```
#### Fieldset
```tsx
"use client";
import {FloppyDisk} from "@gravity-ui/icons";
import {
Button,
Description,
FieldError,
FieldGroup,
Fieldset,
Form,
Input,
Label,
TextArea,
TextField,
} from "@heroui/react";
export function Basic() {
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const data: Record = {};
// Convert FormData to plain object
formData.forEach((value, key) => {
data[key] = value.toString();
});
alert("Form submitted successfully!");
};
return (
);
}
```
#### Form
```tsx
"use client";
import {Check} from "@gravity-ui/icons";
import {Button, Description, FieldError, Form, Input, Label, TextField} from "@heroui/react";
export function Basic() {
const onSubmit = (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const data: Record = {};
// Convert FormData to plain object
formData.forEach((value, key) => {
data[key] = value.toString();
});
alert(`Form submitted with: ${JSON.stringify(data, null, 2)}`);
};
return (
);
}
```
#### Input
```tsx
import {Input} from "@heroui/react";
export function Basic() {
return ;
}
```
#### Label
```tsx
import {Input, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
#### RadioGroup
```tsx
import {Description, Label, Radio, RadioGroup} from "@heroui/react";
export function Basic() {
return (
Choose the plan that suits you bestIncludes 100 messages per monthIncludes 200 messages per monthUnlimited messages
);
}
```
#### TextField
#### TextArea
```tsx
import {TextArea} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Form Field Tokens
Introduced form field tokens `--field-*` for consistent styling across form components. See [Theming](/docs/handbook/theming#calculated-variables-tailwind) for the `--field-*` variables.
### Storybook Organization
Reorganized Storybook by category for better navigation and component discovery.
### Skeleton Animation Token
**🚧 Breaking Changes:** Renamed `--skeleton-default-animation-type` to `--skeleton-animation` in [Skeleton](/docs/components/skeleton) for consistency with other component tokens.
### Data-Slot Alignment
Aligned data-slot markers across components for consistent styling and customization. This standardization makes it easier to target specific component parts with CSS selectors and improves the overall developer experience when customizing component styles.
Components now use consistent `data-slot` attributes like:
* `data-slot="base"` for the root element
* `data-slot="label"` for label text
* `data-slot="description"` for description text
* `data-slot="error"` for error messages
This allows for predictable CSS targeting across all form components:
```css
.radio {
[data-slot="label"] {
/* Styles apply to radio labels */
}
}
```
## Documentation Improvements
### Component Documentation
* **[Link](/docs/components/link)**: Added Anatomy, and examples with Icon. Updated Link and Link.Icon props section.
* **[Description](/docs/components/description)**, **[FieldError](/docs/components/field-error)**, **[Fieldset](/docs/components/fieldset)**, **[Form](/docs/components/form)**, **[Input](/docs/components/input)**, **[Label](/docs/components/label)**, **[RadioGroup](/docs/components/radio-group)**, **[TextField](/docs/components/text-field)**, and **[TextArea](/docs/components/textarea)**: New documentation with usage examples
## Migration Guide
### Skeleton Component Migration
1. **Update animation token:**
* Replace `--skeleton-default-animation-type` with `--skeleton-animation`
## Links
* [GitHub PR #5780](https://github.com/heroui-inc/heroui/pull/5780)
* [Description Component](/docs/components/description)
* [FieldError Component](/docs/components/field-error)
* [Fieldset Component](/docs/components/fieldset)
* [Form Component](/docs/components/form)
* [Input Component](/docs/components/input)
* [Label Component](/docs/components/label)
* [RadioGroup Component](/docs/components/radio-group)
* [TextField Component](/docs/components/text-field)
* [TextArea Component](/docs/components/textarea)
* [Skeleton Component](/docs/components/skeleton)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-alpha.35
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-alpha-35
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-alpha-35.mdx
> React Server Components support for compound components, React 19 improvements, and critical bug fixes.
October 21, 2025
This release fixes a critical issue where **compound components didn't work correctly in React Server Components (RSC)**. Additionally, this release adopts React 19 best practices by removing `forwardRef` and simplifying context usage. The Switch component has been refactored to match the Radio/RadioGroup pattern, providing a cleaner and more consistent API.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@alpha @heroui/react@alpha
```
```bash
pnpm add @heroui/styles@alpha @heroui/react@alpha
```
```bash
yarn add @heroui/styles@alpha @heroui/react@alpha
```
```bash
bun add @heroui/styles@alpha @heroui/react@alpha
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### React Server Components Support
Compound components now work correctly in React Server Components. The previous implementation had the compound pattern logic inside components, which conflicted with the `"use client"` directive. This has been fixed by moving the pattern logic to component index files.
### React 19 Improvements
This release adopts React 19 best practices:
1. **Removed `forwardRef`**: No longer needed in React 19, where `ref` is now a prop ([React 19 docs](https://react.dev/blog/2024/12/05/react-19#ref-as-a-prop))
2. **Simplified Context**: `Context.Provider` replaced with just `Context` ([React 19 docs](https://react.dev/blog/2024/12/05/react-19#context-as-a-provider))
### Switch Component Architecture Improvement
The Switch component has been refactored to follow the same clean separation pattern as Radio/RadioGroup:
* **Separate Components**: Switch and SwitchGroup are now independent components (previously combined)
* **Cleaner API**: `` replaces the nested `` and `` pattern
* **Better Organization**: Separate styles, types, and implementations for each component
* **Consistent Pattern**: Matches the Radio/RadioGroup architecture for a more predictable API
**Before:**
```tsx
...
```
**After:**
```tsx
......
```
## ⚠️ Breaking Changes
### Main Component Requires `.Root` Suffix
To support React Server Components, the compound component pattern has been restructured. The main component now requires the `.Root` suffix when using the compound pattern.
**Before:**
```tsx
import { Avatar } from "@heroui/react"
JR
```
**After:**
```tsx
import { Avatar } from "@heroui/react"
JR
```
**Note:** Named exports (e.g., ``, ``, ``) remain unchanged and fully supported.
### Switch Component API Changes
The Switch component grouping API has been restructured to match the Radio/RadioGroup pattern:
**Before:**
```tsx
import { Switch } from "@heroui/react"
```
**After:**
```tsx
import { Switch, SwitchGroup } from "@heroui/react"
```
This change helps to:
* **Separate Components**: Switch and SwitchGroup are now independent components (previously combined)
* **Cleaner API**: `` replaces the nested `` and `` pattern
* **Better Organization**: Separate styles, types, and implementations for each component
* **Consistent Pattern**: Matches the Radio/RadioGroup architecture for a more predictable API
**Migration Steps:**
1. Import `SwitchGroup` separately: `import { Switch, SwitchGroup } from "@heroui/react"`
2. Replace `` with ``
3. Remove the nested `` wrapper
4. Individual `Switch.Root` components remain unchanged
#### Affected Components
All compound components are affected:
* `Accordion` → `Accordion.Root`
* `Avatar` → `Avatar.Root`
* `Card` → `Card.Root`
* `Disclosure` → `Disclosure.Root`
* `Fieldset` → `Fieldset.Root`
* `Kbd` → `Kbd.Root`
* `Link` → `Link.Root`
* `Popover` → `Popover.Root`
* `RadioGroup` → `RadioGroup.Root`
* `Switch` → `Switch.Root`
* `Tabs` → `Tabs.Root`
* `Tooltip` → `Tooltip.Root`
## Migration Guide
You have two options for using HeroUI compound components:
### Option 1: Update to Use `.Root` (Compound Pattern)
If you're using the compound pattern (dot notation), update your code to use `.Root` for the main component:
**Card Example:**
```tsx
import { Card } from "@heroui/react"
Card TitleCard description
Card content
Card footer
```
**Tabs Example:**
```tsx
import { Tabs } from "@heroui/react"
Tab 1Tab 2Panel 1Panel 2
```
[See more examples in the documentation](/docs/components/card)
**Avatar Example:**
```tsx
import { Avatar } from "@heroui/react"
JD
```
[See more examples in the documentation](/docs/components/avatar)
### Option 2: Use Named Exports
We added support for named exports for all compound components. You can use them like this:
**Card Example:**
```tsx
import {
CardRoot,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@heroui/react"
Card TitleCard description
Card content
Card footer
```
**Tabs Example:**
```tsx
import { TabsRoot, TabListContainer, TabList, Tab, TabIndicator, TabPanel } from "@heroui/react"
Tab 1Tab 2Panel 1Panel 2
```
**Avatar Example:**
```tsx
import { Avatar, AvatarImage, AvatarFallback } from "@heroui/react"
JD
```
### Migration Steps
If you're using the compound pattern, you only need to update the main component to use `.Root`:
1. **Find all instances of compound components** (e.g., `` with `` inside)
2. **Add `.Root` to the main component**:
```tsx
// Before
// After
```
3. **That's it!** All child components (e.g., `Avatar.Image`, `Avatar.Fallback`) remain unchanged.
### Complete Migration Reference
| Component | Named Export Pattern | Compound Pattern (with `.Root`) | Additional Changes |
| -------------- | ------------------------------- | ------------------------------------- | ------------------------------------------------------- |
| **Accordion** | `` | `` | - |
| **Avatar** | `` | `` | - |
| **Card** | `` | `` | - |
| **Disclosure** | `` | `` | - |
| **Fieldset** | `
# v3.0.0-beta.1
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-1
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-1.mdx
> Major redesign with new design system, 8 new components, and improved developer experience.
November 6, 2025
This release introduces a comprehensive redesign of HeroUI v3, merging v2's beauty and animations with v3's simplicity. All components redesigned, 8 new components, and improved design system with better color tokens, shadows, and architecture.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### New Design System
We've spent weeks crafting a new design system that merges the soul of HeroUI v2 with the simplicity of v3. Every component has been redesigned with attention to detail, smooth animations, and improved developer experience. The new design system is available in our [Figma Kit V3](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3).
The redesign brings:
* New color system that brings v3's vision to life and stands out for its uniqueness
* Refined shadow system for better depth perception
* New variables and tokens for better customization
* Automatic `isOnSurface` support for form-based components
* Enhanced border and spacing tokens
* Better contrast and accessibility
* Consistent component patterns across web and native
### New Components
This release introduces **8 new** essential components:
* **[Alert](#alert)**: Display important messages and notifications with status indicators.
* **[Checkbox & CheckboxGroup](#checkbox-checkboxgroup)**: Select multiple items from a list.
* **[InputOTP](#inputotp)**: One-time password input for authentication flows.
* **[Listbox](#listbox)**: Display a list of options and allow single or multiple selection.
* **[Select](#select)**: Dropdown selection component built on top of Listbox.
* **[Slider](#slider)**: Select a value from a range with custom marks and labels.
* **[Surface](#surface)**: Base surface component for creating elevated containers.
### Alert
```tsx
import {Alert, Button, CloseButton, Spinner} from "@heroui/react";
import React from "react";
export function Basic() {
return (
{/* Default - General information */}
New features available
Check out our latest updates including dark mode support and improved accessibility
features.
{/* Accent - Important information with action */}
Update available
A new version of the application is available. Please refresh to get the latest features
and bug fixes.
{/* Danger - Error with detailed steps */}
Unable to connect to server
We're experiencing connection issues. Please try the following:
Check your internet connection
Refresh the page
Clear your browser cache
{/* Without description */}
Profile updated successfully
{/* Custom indicator - Loading state */}
Processing your request
Please wait while we sync your data. This may take a few moments.
{/* Without close button */}
Scheduled maintenance
Our services will be unavailable on Sunday, March 15th from 2:00 AM to 6:00 AM UTC for
scheduled maintenance.
);
}
```
### Checkbox & CheckboxGroup
```tsx
import {Checkbox, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
```tsx
import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react";
export function Basic() {
return (
Choose all that applyLove building softwareEnjoy creating beautiful interfacesPassionate about content creation
);
}
```
### InputOTP
```tsx
import {InputOTP, Label, Link} from "@heroui/react";
export function Basic() {
return (
We've sent a code to a****@gmail.com
Didn't receive a code?
Resend
);
}
```
### Listbox
```tsx
import {Avatar, Description, Label, ListBox} from "@heroui/react";
export function Default() {
return (
B
bob@heroui.com
F
fred@heroui.com
M
martha@heroui.com
);
}
```
### Select
```tsx
import {Label, ListBox, Select} from "@heroui/react";
export function Default() {
return (
);
}
```
### Slider
```tsx
import {Label, Slider} from "@heroui/react";
export function Default() {
return (
);
}
```
### Surface
```tsx
import {Surface} from "@heroui/react";
export function Variants() {
return (
Default
Surface Content
This is a default surface variant. It uses bg-surface styling.
Secondary
Surface Content
This is a secondary surface variant. It uses bg-surface-secondary styling.
Tertiary
Surface Content
This is a tertiary surface variant. It uses bg-surface-tertiary styling.
Transparent
Surface Content
This is a transparent surface variant. It has no background, suitable for overlays and
cards with custom backgrounds.
);
}
```
### Improved Component APIs
Several components have been refined with better APIs:
* **Link**: Added `underline` and `underlineOffset` props for better customization
```tsx
import {Link} from "@heroui/react";
export function LinkBasic() {
return (
Call to action
);
}
```
* **Card**: Improved variants and styling system
```tsx
import {CircleDollar} from "@gravity-ui/icons";
import {Avatar, Button, Card, CloseButton, Link} from "@heroui/react";
export function WithImages() {
return (
{/* Row 1: Large Product Card - Available Soon */}
Become an ACME Creator!
Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet
faucibus etiam.
Only 10 spotsSubmission ends Oct 10.
{/* Row 2 */}
{/* Left Column */}
{/* Top Card */}
PAYMENT
You can now withdraw on crypto
Add your wallet in settings to withdraw
Go to settings
{/* Bottom cards */}
{/* Left Card */}
JK
Indie Hackers
148 members
JK
By John
{/* Right Card */}
AB
AI Builders
362 members
M
By Martha
{/* Right Column */}
{/* Background image */}
{/* Header */}
NEO
Home Robot
{/* Footer */}
Available soon
Get notified
{/* Row 3 */}
{/* Left Column: Card */}
NEO
$499/m
{/* Right Column: Cards Stack */}
{/* 1 */}
Bridging the FutureToday, 6:30 PM
{/* 2 */}
Avocado HackathonWed, 4:30 PM
{/* 3 */}
Sound Electro | Beyond artFri, 8:00 PM
);
}
```
* **Chip**: Enhanced with size variants and improved color system
```tsx
import {Chip} from "@heroui/react";
export function ChipBasic() {
return (
DefaultAccentSuccessWarningDanger
);
}
```
* **Switch**: Redesigned from the ground up with improved visual design and animations
```tsx
import {Label, Switch} from "@heroui/react";
export function Basic() {
return (
);
}
```
* **RadioGroup**: Redesigned from the ground up with better API and styling
```tsx
import {Description, Label, Radio, RadioGroup} from "@heroui/react";
export function Basic() {
return (
Choose the plan that suits you bestIncludes 100 messages per monthIncludes 200 messages per monthUnlimited messages
);
}
```
### Flexible Component Patterns
HeroUI now supports flexible component syntax. Use compound patterns with or without `.Root`, or named exports - all three patterns work identically.
**Available patterns:**
```tsx
import { Avatar } from "@heroui/react"
// 1. Compound pattern (no .Root needed) - recommended
JD
// 2. Compound pattern with .Root - still supported
JD
// 3. Named exports
import { AvatarRoot, AvatarImage, AvatarFallback } from "@heroui/react"
JD
```
**Simple components** like Button work the same way:
```tsx
import { Button } from "@heroui/react"
// No .Root needed
// Or with .Root
Label
// Or named export
import { ButtonRoot } from "@heroui/react"
Label
```
**You can mix compound and named exports** in the same component:
```tsx
import { Avatar, AvatarFallback } from "@heroui/react"
JD
```
This provides:
* **Simpler API**: Main components no longer require `.Root` suffix
* **Flexibility**: Choose between compound pattern, compound with `.Root`, or named exports
* **Backward Compatibility**: The `.Root` pattern still works
* **Naming Consistency**: Standardized naming (e.g., "Container" instead of "Wrapper")
### Global Animation Control
HeroUI now supports easy global animation control through the `data-reduce-motion` attribute. Simply add `data-reduce-motion="true"` to your `` or `` tag to disable all animations across your application.
```html
```
HeroUI automatically respects user motion preferences using the `prefers-reduced-motion` media query and extends Tailwind's `motion-reduce:` variant to support both system preferences and manual control via the data attribute. This provides flexible control over animations while maintaining accessibility best practices.
Learn more about animations and motion preferences in the [Animation documentation](/docs/handbook/animation).
## ⚠️ Breaking Changes
### Design System Variables
#### Panel → Surface & Overlay
The `--panel` variable has been replaced with `--surface` and `--overlay` to better distinguish between non-overlay components (cards, accordions) and floating components (tooltips, popovers, modals).
**Before:**
```css
--panel: var(--white);
--panel-foreground: var(--foreground);
--shadow-panel: 0 0 1px 0 rgba(0, 0, 0, 0.3) inset, 0 2px 8px 0 rgba(0, 0, 0, 0.08);
```
**After:**
```css
--surface: var(--white);
--surface-foreground: var(--foreground);
--overlay: var(--white);
--overlay-foreground: var(--foreground);
--shadow-surface: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06);
--shadow-overlay: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09);
```
**Migration:**
* Replace `bg-panel` with `bg-surface` for non-overlay components
* Replace `bg-panel` with `bg-overlay` for floating components
* Replace `shadow-panel` with `shadow-surface` or `shadow-overlay`
* Replace `--color-panel` with `--color-surface` or `--color-overlay`
#### Surface Levels Simplified
The `--surface-1`, `--surface-2`, and `--surface-3` variables have been removed. Surface levels are now automatically calculated from `--surface` using `color-mix`, so you only need to declare the base surface color.
**Before (manual declaration):**
```css
--surface-1: var(--background);
--surface-2: var(--color-neutral-100);
--surface-3: var(--color-neutral-200);
```
**After (auto-calculated):**
```css
/* You only declare the base surface */
--surface: var(--white);
--surface-foreground: var(--foreground);
/* HeroUI automatically calculates these using color-mix */
--color-surface-secondary: color-mix(in oklab, var(--surface) 94%, var(--surface-foreground) 6%);
--color-surface-tertiary: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%);
--color-surface-quaternary: color-mix(in oklab, var(--surface) 86%, var(--surface-foreground) 14%);
```
**Customization:**
You can override the default calculations using Tailwind's `@theme` directive:
```css
@theme inline {
--color-surface-secondary: color-mix(in oklab, var(--surface) 96%, var(--surface-foreground) 4%);
--color-surface-tertiary: color-mix(in oklab, var(--surface) 94%, var(--surface-foreground) 6%);
--color-surface-quaternary: color-mix(in oklab, var(--surface) 90%, var(--surface-foreground) 10%);
}
```
**Migration:**
* Replace `bg-surface-1` with `bg-surface` (base surface)
* Replace `bg-surface-2` with `bg-surface-secondary` (auto-calculated)
* Replace `bg-surface-3` with `bg-surface-tertiary` (auto-calculated)
The same auto-calculation pattern applies to:
* **Background shades**: Calculated from `--background` → `background-secondary`, `background-tertiary`, `background-quaternary`
* **Soft colors**: Calculated from status colors → `accent-soft`, `danger-soft`, `warning-soft`, `success-soft`
#### Border Width Default Changed
The default border width has changed from `1px` to `0px`. Borders are now opt-in rather than default.
**Before:**
```css
--border-width: 1px;
```
**After:**
```css
--border-width: 0px; /* no border by default */
```
**Migration:**
* If you rely on default borders, explicitly set `border-width` in your custom styles
* Form fields now use `transparent` borders by default
#### Border Color Default Changed
The default border color opacity has changed from `15%` to `0%` (transparent).
**Before:**
```css
--border: oklch(0 0 0 / 15%);
```
**After:**
```css
--border: oklch(0 0 0 / 0%);
```
**Field Border Default:**
```css
--field-border: transparent; /* no border by default on form fields */
```
#### Shadow System Updates
The shadow system has been completely redesigned with separate shadows for surfaces and overlays.
**Before:**
```css
--panel-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.3) inset, 0 2px 8px 0 rgba(0, 0, 0, 0.08);
--field-shadow: 0 0 0 0 rgba(255, 255, 255, 0.1) inset, 0 1px 2px 0 rgba(0, 0, 0, 0.05);
```
**After (Light):**
```css
--surface-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06);
--overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09);
--field-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06), 0 0 1px 0 rgba(0, 0, 0, 0.06);
```
**After (Dark):**
```css
--surface-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--overlay-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--field-shadow: 0 0 0 0 transparent inset; /* Transparent shadow to allow ring utilities to work */
```
#### Accent Color Updates
The accent color has been updated for better contrast and visual appeal.
**Before:**
```css
--accent: var(--color-neutral-950);
--accent-foreground: var(--snow);
```
**After:**
```css
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
```
#### Status Color Refinements
Success, warning, and danger colors have been refined for better consistency and contrast.
**Success:**
* **Before:** `oklch(0.5503 0.1244 153.56)`
* **After:** `oklch(0.7329 0.1935 150.81)`
* Foreground changed from `var(--snow)` to `var(--eclipse)` in light mode
**Warning:**
* **Before:** `oklch(0.7186 0.1521 64.85)`
* **After:** `oklch(0.7819 0.1585 72.33)` (light), `oklch(0.8203 0.1388 76.34)` (dark)
**Danger:**
* **Before:** `oklch(0.6259 0.1908 29.19)`
* **After:** `oklch(0.6532 0.2328 25.74)` (light), `oklch(0.594 0.1967 24.63)` (dark)
### Component API Changes
#### Chip Component
The Chip component's `type` prop has been renamed to `color`, and a new `size` prop has been added. A new `soft` variant has been introduced.
**Before:**
```tsx
import { Chip } from "@heroui/react";
Label
```
**After:**
```tsx
import { Chip } from "@heroui/react";
Label
```
**Migration:**
* Replace `type` prop with `color` prop
* Use `size` prop (`sm`, `md`, `lg`) to control chip size
* The `soft` variant provides a subtle appearance for less prominent chips
#### Link Component
The Link component now supports `underline` and `underlineOffset` props, and includes `asChild` support.
**Before:**
```tsx
import { Link } from "@heroui/react";
Link text
```
**After:**
```tsx
import { Link } from "@heroui/react";
Link text
```
**New Props:**
* `underline`: `"none" | "hover" | "always"` - Controls underline visibility
* `underlineOffset`: `number` - Controls underline offset from text
#### Type Reference Syntax
Due to the dual pattern implementation, type references through the namespace syntax are no longer supported. Use object-style syntax or named type imports instead.
**Before (no longer works):**
```tsx
type AvatarProps = Avatar.RootProps
```
**After (Option 1 - Object-style syntax):**
```tsx
type AvatarProps = Avatar["RootProps"]
```
**After (Option 2 - Named type imports, recommended):**
```tsx
import type { AvatarRootProps } from "@heroui/react"
type AvatarProps = AvatarRootProps
```
This change affects all compound components when accessing prop types.
#### Tabs Component Renaming
The Tabs component's wrapper element has been renamed for consistency:
* **Compound property**: `Tabs.ListWrapper` → `Tabs.ListContainer`
* **Named export**: `TabListWrapper` → `TabListContainer`
* **CSS class**: `.tabs__list-wrapper` → `.tabs__list-container`
* **Data attribute**: `data-slot="tabs-list-wrapper"` → `data-slot="tabs-list-container"`
**Migration:**
Find and replace all instances of `TabListWrapper` with `TabListContainer`:
```bash
# Component usage
TabListWrapper → TabListContainer
Tabs.ListWrapper → Tabs.ListContainer
# CSS selectors (if using custom styles)
.tabs__list-wrapper → .tabs__list-container
[data-slot="tabs-list-wrapper"] → [data-slot="tabs-list-container"]
```
#### Removed Variables
The following variables have been removed:
* `--panel` → Use `--surface` or `--overlay`
* `--panel-foreground` → Use `--surface-foreground` or `--overlay-foreground`
* `--surface-1`, `--surface-2`, `--surface-3` → Use background shades or surface levels
* `--accent-soft` → Use `--color-accent-soft` (now calculated)
* `--radius-panel` and `--radius-panel-inner` → Use standard radius values
## Design System Updates
### New Color System
#### Surface vs Overlay Concept
The design system now distinguishes between two types of elevated components:
* **Surface**: Used for non-overlay components like cards, accordions, and disclosure groups that sit on the page
* **Overlay**: Used for floating components like tooltips, popovers, modals, and menus that appear above the page
This distinction provides:
* Better visual hierarchy
* Appropriate shadow depths
* Improved dark mode contrast
* Clearer component semantics
#### Auto-Calculated Color System
HeroUI now automatically calculates shade levels and soft color variants using CSS `color-mix`. You only need to declare the base colors, and HeroUI handles the rest.
**Background Shade Levels**
Background shades are automatically calculated from `--background`:
```css
/* You only declare the base */
--background: oklch(0.9702 0 0);
--foreground: var(--eclipse);
/* HeroUI automatically calculates these */
--color-background-secondary: color-mix(in oklab, var(--color-background) 96%, var(--color-foreground) 4%);
--color-background-tertiary: color-mix(in oklab, var(--color-background) 92%, var(--color-foreground) 8%);
--color-background-quaternary: color-mix(in oklab, var(--color-background) 86%, var(--color-foreground) 14%);
```
**Surface Levels**
Surface levels are automatically calculated from `--surface`:
```css
/* You only declare the base */
--surface: var(--white);
--surface-foreground: var(--foreground);
/* HeroUI automatically calculates these */
--color-surface-secondary: color-mix(in oklab, var(--surface) 94%, var(--surface-foreground) 6%);
--color-surface-tertiary: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%);
--color-surface-quaternary: color-mix(in oklab, var(--surface) 86%, var(--surface-foreground) 14%);
```
**Soft Color Variants**
Soft color variants are automatically calculated from status colors:
```css
/* You declare the base status colors */
--accent: oklch(0.6204 0.195 253.83);
--danger: oklch(0.6532 0.2328 25.74);
--warning: oklch(0.7819 0.1585 72.33);
--success: oklch(0.7329 0.1935 150.81);
/* HeroUI automatically calculates these at 15% opacity */
--color-accent-soft: color-mix(in oklab, var(--color-accent) 15%, transparent);
--color-danger-soft: color-mix(in oklab, var(--color-danger) 15%, transparent);
--color-warning-soft: color-mix(in oklab, var(--color-warning) 15%, transparent);
--color-success-soft: color-mix(in oklab, var(--color-success) 15%, transparent);
```
Each soft variant includes hover states (20% opacity) and foreground colors for proper contrast.
**Customization:**
You can override any auto-calculated values using Tailwind's `@theme` directive:
```css
@theme inline {
/* Adjust surface levels */
--color-surface-secondary: color-mix(in oklab, var(--surface) 96%, var(--surface-foreground) 4%);
/* Adjust soft colors */
--color-accent-soft: color-mix(in oklab, var(--color-accent) 20%, transparent);
}
```
This auto-calculation system reduces the number of variables you need to manage while providing full customization when needed.
### Shadow System
The shadow system has been redesigned to provide:
* Separate shadows for surfaces and overlays
* Better depth perception
* Dark mode support (transparent shadows)
* Consistent field shadows
Shadows automatically adapt to light and dark modes, providing appropriate depth cues for each theme.
### Focus System
The focus color now uses the accent color for consistency:
```css
--focus: var(--accent);
```
This ensures focus indicators align with your brand colors while maintaining accessibility.
### Typography Tokens
Several typography-related variables have been removed in favor of using Tailwind's typography utilities directly. The design system now focuses on color and spacing tokens, letting Tailwind handle typography.
## Migration Guide
### Step 1: Update Design System Variables
Replace old panel variables with surface/overlay:
```css
/* Before */
.my-card {
background: var(--panel);
box-shadow: var(--shadow-panel);
}
/* After */
.my-card {
background: var(--surface);
box-shadow: var(--shadow-surface);
}
.my-tooltip {
background: var(--overlay);
box-shadow: var(--shadow-overlay);
}
```
### Step 2: Update Surface Levels
Surface levels are now automatically calculated from `--surface`, so you don't need to manually declare them. Simply use the new utility classes:
```css
/* Before */
.bg-surface-1 → .bg-surface (base surface)
.bg-surface-2 → .bg-surface-secondary (auto-calculated)
.bg-surface-3 → .bg-surface-tertiary (auto-calculated)
/* You can also use background shades */
.bg-surface-2 → .bg-background-secondary (auto-calculated from --background)
.bg-surface-3 → .bg-background-tertiary (auto-calculated from --background)
```
**Note:** Surface levels (`surface-secondary`, `surface-tertiary`, etc.) are automatically calculated based on your `--surface` color. No manual CSS variables needed unless you want to customize the calculations.
### Step 3: Update Component Props
Update Chip and Link components:
```tsx
// Chip: type → color, add size if needed
→
// Link: Add underline props if customizing underlines
Text // Still works, underline props are optional
```
### Step 4: Simplify Component Patterns (Optional)
If you adopted the `.Root` suffix from v3.0.0-alpha.35, you can now simplify your code by removing it:
**Before (v3.0.0-alpha.35):**
```tsx
JD
```
**After (simpler):**
```tsx
JD
```
**Note:** The `.Root` syntax still works if you prefer it.
### Step 5: Update Type References
If you're using namespace syntax for types, switch to object-style syntax or named imports:
**Before:**
```tsx
type ButtonProps = Button.RootProps
```
**After (Option 1 - Object-style):**
```tsx
type ButtonProps = Button["RootProps"]
```
**After (Option 2 - Named imports, recommended):**
```tsx
import type { ButtonRootProps } from "@heroui/react"
type ButtonProps = ButtonRootProps
```
### Step 6: Update Tabs Component
Replace `TabListWrapper` with `TabListContainer`:
**Before:**
```tsx
import { Tabs } from "@heroui/react"
HomeContent
```
**After:**
```tsx
import { Tabs } from "@heroui/react"
HomeContent
```
### Step 7: Handle Border Changes
If your custom styles rely on default borders:
```css
/* Add explicit borders where needed */
.my-component {
border-width: 1px;
border-color: var(--color-border);
}
```
### Step 8: Update Status Colors
If you've customized status colors, review the new values and adjust your custom theme if needed:
```css
/* Check if your custom status colors need updates */
--success: oklch(0.7329 0.1935 150.81); /* New value */
--warning: oklch(0.7819 0.1585 72.33); /* New value */
--danger: oklch(0.6532 0.2328 25.74); /* New value */
```
### Automated Migration
For large codebases, you can use find-and-replace:
```bash
# Panel → Surface
--panel → --surface
bg-panel → bg-surface
shadow-panel → shadow-surface
# Panel → Overlay (for floating components)
--panel → --overlay (where appropriate)
bg-panel → bg-overlay (for tooltips, popovers, etc.)
shadow-panel → shadow-overlay (for floating components)
# Chip type prop
type=" → color="
# Surface levels
bg-surface-1 → bg-surface
bg-surface-2 → bg-surface-secondary
bg-surface-3 → bg-surface-tertiary
# Tabs component
TabListWrapper → TabListContainer
Tabs.ListWrapper → Tabs.ListContainer
# Type references
Component.RootProps → Component["RootProps"] or use named imports
```
## Component Updates
### Card Component
Card component has been refined with improved variants and better semantic structure. The component now uses the new surface system for consistent styling.
### Accordion Component
Accordion now uses the surface system for better visual consistency with other components.
### Form Components
Form components (Input, TextField, TextArea) have been updated to use the new field border system (transparent by default) for a cleaner look while maintaining accessibility.
### Component Pattern Updates
All components now support flexible patterns. Components that support the dual pattern include:
* **Simple components**: Button, Link, Spinner, Chip, Kbd
* **Compound components**: Accordion, Avatar, Card, Disclosure, Fieldset, Popover, RadioGroup, Switch, Tabs, Tooltip
You can use any of the three patterns (compound without `.Root`, compound with `.Root`, or named exports) with all these components.
## HeroUI Pro
HeroUI Pro is being reshaped from the ground up on top of the new design system. The new Pro version will feature:
* New components built on top of HeroUI v3
* Tailwind CSS v4 native support
* CSS native animations
* Enhanced customization options
We'll share more updates soon.
## Roadmap
We're working towards a stable release in **Q4** this year (2025). This beta release brings us significantly closer to that goal with:
* Comprehensive component set
* Refined design system
* Improved developer experience
* Better performance
## Community
The reception on the native side has been phenomenal. Thank you for supporting us as we build HeroUI v3! Your feedback helps us improve every day.
See what the community is saying: [HeroUI Native Reception](https://x.com/hero_ui/status/1985721976220966926)
## Links
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [HeroUI Native](https://link.heroui.com/native)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #5872](https://github.com/heroui-inc/heroui/pull/5872)
## Contributors
Thanks to everyone who contributed to this release, helping us create a design system that's both beautiful and practical!
# v3.0.0-beta.2
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-2
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-2.mdx
> Six new components (AlertDialog, ComboBox, Dropdown, InputGroup, Modal, NumberField), Select API improvements, and component refinements.
November 20, 2025
This release introduces six essential new components, improves the Select component API, and includes various refinements and bug fixes.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### New Components
This release introduces **6 new** essential components:
* **[AlertDialog](#alert-dialog)**: Modal dialog for important decisions that require user confirmation. ([Documentation](/docs/components/alert-dialog))
* **[ComboBox](#combo-box)**: Combines a text input with a listbox, allowing users to filter a list of options. ([Documentation](/docs/components/combo-box))
* **[Dropdown](#dropdown)**: Displays a list of actions or options that a user can choose. ([Documentation](/docs/components/dropdown))
* **[InputGroup](#inputgroup)**: Group related input controls with prefix and suffix elements for enhanced form fields. ([Documentation](/docs/components/input-group))
* **[Modal](#modal)**: Dialog overlay for focused user interactions and important content. ([Documentation](/docs/components/modal))
* **[NumberField](#numberfield)**: Number input with increment/decrement buttons, validation, and internationalized formatting. ([Documentation](/docs/components/number-field))
### AlertDialog
```tsx
"use client";
import {AlertDialog, Button} from "@heroui/react";
export function Default() {
return (
Delete project permanently?
This will permanently delete My Awesome Project and all of its
data. This action cannot be undone.
);
}
```
### ComboBox
```tsx
"use client";
import {ComboBox, Input, Label, ListBox} from "@heroui/react";
export function Default() {
return (
Aardvark
Cat
Dog
Kangaroo
Panda
Snake
);
}
```
### Dropdown
```tsx
"use client";
import {Button, Dropdown, Label} from "@heroui/react";
export function Default() {
return (
console.log(`Selected: ${key}`)}>
);
}
```
### Modal
```tsx
"use client";
import {Rocket} from "@gravity-ui/icons";
import {Button, Modal} from "@heroui/react";
export function Default() {
return (
Welcome to HeroUI
A beautiful, fast, and modern React UI library for building accessible and
customizable web applications with ease.
);
}
```
### InputGroup
```tsx
"use client";
import {Globe} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";
export function WithIconPrefixAndTextSuffix() {
return (
.com
);
}
```
### NumberField
```tsx
import {Label, NumberField} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Style Improvements
#### Custom Variants and Theme Compatibility
Enhanced CSS variants and theme system for better customization:
**Motion Preferences**:
* New `motion-safe` variant with `data-reduce-motion="true"` attribute matching
* Enhanced `motion-reduce` now supports ancestor elements and pseudo-elements
**Dark Mode**:
* Class and `data-theme="dark"` attribute selectors now take precedence over `prefers-color-scheme`
* Full support for pseudo-elements in dark mode
**Theme Variables**:
* Expanded light theme scope to support nested themes (`:root`, `.light`, `.default`, `[data-theme="light"]`, `[data-theme="default"]`)
### Component Improvements
#### Select Component API Update
The Select component's API has been improved for better consistency with other components. The `Content` subcomponent has been renamed to `Popover`.
**Before:**
```tsx
```
**After:**
```tsx
```
#### Chip Component Refinements
Chip component sizes have been updated for better consistency:
* **Small (`sm`)**: `px-1 py-0 text-xs`
* **Medium (`md`)**: `text-xs` (now explicitly set)
* **Large (`lg`)**: `px-3 py-1 text-sm font-medium`
#### Separator Component Enhancement
The Separator component now automatically detects when it's placed inside a surface component (one that uses `bg-surface`) and applies the appropriate divider color for better visibility. A new `isOnSurface` prop is also available for manual control.
**New Calculated Variable:**
* `--color-separator-on-surface`: A calculated variable (automatically generated using `color-mix`) that ensures the separator is visible when placed on a surface background. Like other calculated variables, it can be overridden in your theme.
**Usage:**
```tsx
```
The `isOnSurface` prop is automatically applied when the Separator detects a `SurfaceContext` provider (used by components like Card, Alert, Popover, Modal, etc.).
You can also use the calculated variable directly with Tailwind classes:
```tsx
```
#### Animation Improvements
* Loading state spinner color updated for better visibility
* Select and Slider component styles adjusted for improved animations
* Checkbox animation improved (faster transition)
* Better support for `prefers-reduced-motion` with pseudo elements
## ⚠️ Breaking Changes
### Select Component
The `Select.Content` subcomponent has been renamed to `Select.Popover` for consistency with other components like ComboBox and Dropdown.
**Migration:**
Replace all instances of `Select.Content` with `Select.Popover`:
```tsx
// Before
...
// After
...
```
**Type imports:**
```tsx
// Before
import type { SelectContentProps } from "@heroui/react"
// After
import type { SelectPopoverProps } from "@heroui/react"
```
**Named exports:**
```tsx
// Before
import { SelectContent } from "@heroui/react"
// After
import { SelectPopover } from "@heroui/react"
```
### CSS Variables and Utilities: Divider → Separator
All CSS variables and utility classes related to `divider` have been renamed to `separator` for consistency with the Separator component name.
**CSS Variables:**
```css
/* Before */
border-bottom: 1px solid var(--divider);
/* After */
border-bottom: 1px solid var(--separator);
```
**Tailwind Utility Classes:**
```tsx
// Before
// After
```
**Theme Overrides:**
If you have custom themes that override the divider variable, update them:
```css
/* Before */
:root {
--divider: oklch(92% 0.004 286.32);
}
.dark {
--divider: oklch(22% 0.006 286.033);
}
/* After */
:root {
--separator: oklch(92% 0.004 286.32);
}
.dark {
--separator: oklch(22% 0.006 286.033);
}
```
## Bug Fixes
* Fixed loading state spinner color for better visibility
* Fixed bordered focus styles taking precedence over hover states
* Fixed animation stuttering in documentation
* Improved modal form styling
* Enhanced motion reduce support for pseudo elements
* Fixed mobile hover states sticking after touch interactions by wrapping hover styles in `@media (hover: hover)` media queries. Also simplified data attribute selectors by removing unnecessary `="true"` value checks.
## Links
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3 (updated)](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #5885](https://github.com/heroui-inc/heroui/pull/5885)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-beta.3
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-3
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-3.mdx
> Seven new components, fullWidth and hideSeparator support, style fixes, and breaking changes for AlertDialog/Modal backdrop variants and asChild prop removal.
December 19, 2025
This release introduces seven new components ([ButtonGroup](/docs/components/button-group), [DateField](/docs/components/date-field), [ErrorMessage](/docs/components/error-message), [ScrollShadow](/docs/components/scroll-shadow), [SearchField](/docs/components/search-field), [TagGroup](/docs/components/tag-group), [TimeField](/docs/components/time-field)), adds `fullWidth` support for form components and `hideSeparator` to [Tabs](/docs/components/tabs), [ButtonGroup](/docs/components/button-group), and [Accordion](/docs/components/accordion), includes style fixes, and ⚠️ **breaking changes** removing the `asChild` prop and updating [AlertDialog](/docs/components/alert-dialog) & [Modal](/docs/components/modal) backdrop variants.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### New Components
This release introduces **7 new** essential components:
* **[ButtonGroup](#button-group)**: Groups related buttons with consistent styling and spacing. ([Documentation](/docs/components/button-group))
* **[DateField](#date-field)**: Date input field with labels, descriptions, and validation built on React Aria DateField. ([Documentation](/docs/components/date-field))
* **[ErrorMessage](#error-message)**: Low-level error message component for displaying errors in non-form components. ([Documentation](/docs/components/error-message))
* **[ScrollShadow](#scroll-shadow)**: Apply visual shadows to indicate scrollable content overflow with automatic detection of scroll position. ([Documentation](/docs/components/scroll-shadow))
* **[SearchField](#search-field)**: Search input field with built-in search icon and clear button. ([Documentation](/docs/components/search-field))
* **[TagGroup](#tag-group)**: Focusable list of tags with support for keyboard navigation, selection, and removal. ([Documentation](/docs/components/tag-group))
* **[TimeField](#time-field)**: Time input field with labels, descriptions, and validation built on React Aria TimeField. ([Documentation](/docs/components/time-field))
### ButtonGroup
```tsx
import {
ChevronDown,
ChevronLeft,
ChevronRight,
CodeFork,
Ellipsis,
Picture,
Pin,
QrCode,
Star,
TextAlignCenter,
TextAlignJustify,
TextAlignLeft,
TextAlignRight,
ThumbsDown,
ThumbsUp,
Video,
} from "@gravity-ui/icons";
import {Button, ButtonGroup, Chip, Description, Dropdown, Label} from "@heroui/react";
export function Basic() {
return (
{/* Single button with dropdown */}
All commits from this branch will be added to the base branch
The 14 commits from this branch will be combined into one commit in the base
branch
The 14 commits from this branch will be rebased and added to the base branch
{/* Individual buttons */}
{/* Previous/Next Button Group */}
{/* Content Selection Button Group */}
{/* Text Alignment Button Group */}
{/* Icon-Only Alignment Button Group */}
);
}
```
### DateField
```tsx
"use client";
import {DateField, Label} from "@heroui/react";
export function Basic() {
return (
{(segment) => }
);
}
```
### ErrorMessage
```tsx
"use client";
import type {Key} from "@heroui/react";
import {Description, ErrorMessage, Label, Tag, TagGroup} from "@heroui/react";
import {useMemo, useState} from "react";
export function ErrorMessageBasic() {
const [selected, setSelected] = useState>(new Set());
const isInvalid = useMemo(() => Array.from(selected).length === 0, [selected]);
return (
setSelected(keys)}
>
NewsTravelGamingShoppingSelect at least one category{!!isInvalid && <>Please select at least one category>}
);
}
```
### SearchField
```tsx
import {Label, SearchField} from "@heroui/react";
export function Basic() {
return (
);
}
```
### ScrollShadow
```tsx
import {Card, ScrollShadow} from "@heroui/react";
const images = [
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/robot1.jpeg",
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/avocado.jpeg",
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/oranges.jpeg",
];
export default function Orientation() {
const getRandomImage = (idx: number) => {
return images[idx % images.length];
};
return (
Vertical
{Array.from({length: 10}).map((_, idx) => (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non
risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor
quam. Morbi accumsan cursus enim, sed ultricies sapien.
))}
Horizontal
{Array.from({length: 10}).map((_, idx) => (
Bridging the FutureToday, 6:30 PM
))}
);
}
```
### TagGroup
```tsx
"use client";
import {PlanetEarth, Rocket, ShoppingBag, SquareArticle} from "@gravity-ui/icons";
import {Tag, TagGroup} from "@heroui/react";
export function TagGroupBasic() {
return (
News
Travel
Gaming
Shopping
);
}
```
### TimeField
```tsx
"use client";
import {Label, TimeField} from "@heroui/react";
export function Basic() {
return (
{(segment) => }
);
}
```
### Full-Width Support
Added `fullWidth` support to form and input components, allowing them to span the full width of their container. This is particularly useful for creating consistent form layouts and responsive designs.
**Supported components:**
* [ButtonGroup](/docs/components/button-group)
* [Button](/docs/components/button)
* [ComboBox](/docs/components/combo-box)
* [DateField](/docs/components/date-field)
* [DateInputGroup](/docs/components/date-input-group)
* [InputGroup](/docs/components/input-group)
* [Input](/docs/components/input)
* [NumberField](/docs/components/number-field)
* [SearchField](/docs/components/search-field)
* [Select](/docs/components/select)
* [TextField](/docs/components/text-field)
* [TextArea](/docs/components/textarea)
* [TimeField](/docs/components/time-field)
## Component Improvements
### Separator Control Enhancement
Added `hideSeparator` prop to [Tabs](/docs/components/tabs), [ButtonGroup](/docs/components/button-group), and [Accordion](/docs/components/accordion) components, allowing you to hide separator lines between items for a cleaner, more minimal appearance.
**Tabs:**
```tsx
OverviewAnalytics
```
**ButtonGroup:**
```tsx
```
**Accordion:**
```tsx
Item 1Content
```
### Documentation Icons Integration
Integrated [@gravity-ui/icons](https://github.com/gravity-ui/icons) into documentation components for consistent icon rendering with improved SSR support and better performance.
## Dependencies
### React Aria Components v1.14.0
Upgraded [react-aria-components](https://react-aria.adobe.com/releases/v1-14-0) to v1.14.0. This release includes:
**Enhancements:**
* SearchField: Added `isReadOnly` and `isRequired` to render props
* Tooltip: Added `shouldCloseOnPress` prop
* Tabs: Support for animated transitions between tab panels
* Miscellaneous: Support for `setState` callback in `useControlledState`
**Fixes:**
* ComboBox: Fixed VoiceOver announcement not respecting `aria-label` of ListBoxItem
* Date and Time: Enhanced error handling for absolute date and date time strings
* NumberField: Prevented incrementing/decrementing when scrolling on mobile
* Overlays: Fixed overlay positioning and flipping when boundary container is set
* Table: Fixed crash in drag and drop when keyboard navigating
* Various other bug fixes and improvements
For the complete list of changes, see the [React Aria Components v1.14.0 release notes](https://react-aria.adobe.com/releases/v1-14-0).
### Other Dependency Upgrades
* `@internationalized/date`: 3.10.0 → 3.10.1
* `@radix-ui/react-avatar`: 1.1.10 → 1.1.11
* `tailwind-merge`: 3.3.1 → 3.4.0
* `tailwind-variants`: 3.1.1 → 3.2.2
## Style Fixes
### Form Component Disabled State
Fixed disabled state styling for [Input](/docs/components/input) and [TextArea](/docs/components/textarea) components.
### Style Optimizations
* **Improved selector precision**: Enhanced CSS selector specificity for better style isolation and performance
* **Enhanced animations**: Improved animation performance and smoothness across components
* **Added no-highlight utility**: Added `no-highlight` utility class to prevent text selection on interactive elements for improved user experience
* **Optimized will-change properties**: Updated `will-change` CSS properties across components for better animation performance
* **Removed global scrollbar styling**: Removed global scrollbar styles to prevent conflicts with custom scrollbar implementations and fix modal/overlay interaction issues
## ⚠️ Breaking Changes
### AlertDialog & Modal Backdrop Variant
Renamed `backdropVariant`/`variant` prop value from `"solid"` to `"opaque"` for better semantic clarity. The term "opaque" more accurately describes the backdrop's visual appearance.
**Migration:**
Update all instances of `backdropVariant="solid"` to `backdropVariant="opaque"` for AlertDialog, and `variant="solid"` to `variant="opaque"` for Modal:
```tsx
// Before
{/* content */}
{/* content */}
// After
{/* content */}
{/* content */}
```
**Available backdrop variants:**
* `"opaque"` - Dark backdrop that completely obscures the background (formerly `"solid"`)
* `"blur"` - Blurred backdrop that softly obscures the background
* `"transparent"` - Transparent backdrop that keeps the background visible
### Removed `asChild` Prop
Removed the `asChild` prop pattern from components for cleaner APIs, improved type safety, and simplified usage.
For more details about component composition patterns, see the [Composition guide](/docs/handbook/composition).
## Bug Fixes
* Fixed `isInvalid` styles when components are used on surface backgrounds
* Fixed AlertDialog and Modal re-rendering issues after close
* Fixed overlay close issue that prevented proper cleanup when closing overlays
* Fixed Storybook links and navigation issues
## Links
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3 (updated)](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #5923](https://github.com/heroui-inc/heroui/pull/5923)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-beta.4
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-4
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-4.mdx
> New Theme Builder, three new components (Autocomplete, Breadcrumbs, Toast), Tabs secondary variant, Input/InputGroup variants, and various improvements.
January 20, 2026
**Critical Build Issue Fixed**: This version (beta.4) had a critical build issue that has been fixed in **beta.5**. Please upgrade to `@heroui/styles@3.0.0-beta.5` and `@heroui/react@3.0.0-beta.5` to ensure proper TypeScript declaration generation and export resolution.
This release introduces the new [Theme Builder](/themes) for visual theme customization, three new components ([Autocomplete](/docs/components/autocomplete), [Breadcrumbs](/docs/components/breadcrumbs), [Toast](/docs/components/toast)), adds secondary variant to [Tabs](/docs/components/tabs), primary/secondary variants to [Input](/docs/components/input) and [InputGroup](/docs/components/input-group), TextArea support for InputGroup, and ⚠️ **breaking changes** removing Link's underline variants and the `isInSurface` prop from form components.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### Theme Builder
We're excited to introduce the **[Theme Builder](/themes)** - a powerful visual tool for creating and customizing HeroUI themes. Build your perfect theme with real-time preview and export ready-to-use CSS.
**Key features:**
* **Visual Color Editing**: Adjust colors using OKLCH color pickers with intuitive sliders for lightness, chroma, and hue
* **Real-time Preview**: See your changes instantly on live component previews
* **Custom Accent Colors**: Define your brand colors and watch them propagate across all components
* **Preset Themes**: Start from curated presets like Default, Airbnb, Coinbase, Discord, and more
* **Export Ready**: Generate CSS variables ready to copy into your project
* **Light & Dark Mode**: Customize both themes simultaneously with linked or independent values
* **Keyboard Shortcuts**: Undo/redo support and quick actions for efficient workflow
Try it now at [v3.heroui.com/themes](/themes).
### New Components
This release introduces **3 new** essential components:
* **[Autocomplete](#autocomplete)**: Combines a select with filtering, allowing users to search and select from a list of options. ([Documentation](/docs/components/autocomplete))
* **[Breadcrumbs](#breadcrumbs)**: Navigation breadcrumbs showing the current page's location within a hierarchy. ([Documentation](/docs/components/breadcrumbs))
* **[Toast](#toast)**: Display temporary notifications and messages with automatic dismissal and customizable placement. ([Documentation](/docs/components/toast))
### Autocomplete
```tsx
"use client";
import type {Key} from "@heroui/react";
import {
Autocomplete,
EmptyState,
Label,
ListBox,
SearchField,
Tag,
TagGroup,
useFilter,
} from "@heroui/react";
import {useState} from "react";
export default function Default() {
const {contains} = useFilter({sensitivity: "base"});
const [selectedKeys, setSelectedKeys] = useState([]);
const items = [
{id: "florida", name: "Florida"},
{id: "delaware", name: "Delaware"},
{id: "california", name: "California"},
{id: "texas", name: "Texas"},
{id: "new-york", name: "New York"},
{id: "washington", name: "Washington"},
];
const onRemoveTags = (keys: Set) => {
setSelectedKeys((prev) => prev.filter((key) => !keys.has(key)));
};
return (
setSelectedKeys(keys as Key[])}
>
{({defaultChildren, isPlaceholder, state}: any) => {
if (isPlaceholder || state.selectedItems.length === 0) {
return defaultChildren;
}
const selectedItemsKeys = state.selectedItems.map((item: any) => item.key);
return (
{selectedItemsKeys.map((selectedItemKey: Key) => {
const item = items.find((s) => s.id === selectedItemKey);
if (!item) return null;
return (
{item.name}
);
})}
);
}}
No results found}>
{items.map((item) => (
{item.name}
))}
);
}
```
### Breadcrumbs
```tsx
"use client";
import {Breadcrumbs} from "@heroui/react";
export default function BreadcrumbsBasic() {
return (
HomeProductsElectronicsLaptop
);
}
```
### Toast
This component is currently in preview and some features might not work as expected.
```tsx
"use client";
import {HardDrive, Persons} from "@gravity-ui/icons";
import {Button, toast} from "@heroui/react";
const noop = () => {};
export function Variants() {
return (
);
}
```
## Component Improvements
### Tabs Secondary Variant
Added a new `secondary` variant to [Tabs](/docs/components/tabs) with an underline indicator style. The secondary variant supports both horizontal and vertical orientations.
```tsx
import {Tabs} from "@heroui/react";
export function Secondary() {
return (
Overview
Analytics
Reports
View your project overview and recent activity.
Track your metrics and analyze performance data.
Generate and download detailed reports.
);
}
```
**Usage:**
```tsx
Overview
Analytics
ContentContent
```
### Input Variants
Added `primary` and `secondary` variants to the [Input](/docs/components/input) component:
* **`primary`** (default): Standard styling with shadow, suitable for most use cases
* **`secondary`**: Lower emphasis variant without shadow, suitable for use in Surface components
```tsx
import {Input} from "@heroui/react";
export function Variants() {
return (
);
}
```
### InputGroup Enhancements
The [InputGroup](/docs/components/input-group) component received several improvements:
**TextArea Support**: Use `InputGroup.TextArea` for multiline text inputs with prefix and suffix elements.
```tsx
"use client";
import {ArrowUp, At, Microphone, PlugConnection, Plus} from "@gravity-ui/icons";
import {Button, InputGroup, Kbd, Spinner, TextField, Tooltip} from "@heroui/react";
import {useState} from "react";
export function WithTextArea() {
const [value, setValue] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = () => {
if (!value.trim()) return;
setIsSubmitting(true);
setTimeout(() => {
setIsSubmitting(false);
setValue("");
}, 1000);
};
return (
setValue(event.target.value)}
/>
Add a files and more
Connect apps
Voice input
Send
);
}
```
**Variants**: Added `primary` and `secondary` variants matching the Input component.
```tsx
import {Envelope} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";
export function Variants() {
return (
);
}
```
### Button & ButtonGroup Outline Variants
Added a new `outline` variant to both [Button](/docs/components/button) and [ButtonGroup](/docs/components/button-group) components for outlined styling.
```tsx
import {Button, ButtonGroup} from "@heroui/react";
export function OutlineVariant() {
return (
Button
ButtonGroup
);
}
```
### AlertDialog Size Support
Added size support to [AlertDialog](/docs/components/alert-dialog) component, allowing you to control the dialog size.
```tsx
"use client";
import {Rocket} from "@gravity-ui/icons";
import {AlertDialog, Button} from "@heroui/react";
export function Sizes() {
const sizes = ["xs", "sm", "md", "lg", "cover"] as const;
return (
{size === "cover" ? (
<>
This alert dialog uses the cover size variant. It spans the
full screen with margins: 16px on mobile and 40px on desktop. Maintains
rounded corners and standard padding. Perfect for critical confirmations
that need maximum width while preserving alert dialog aesthetics.
>
) : (
<>
This alert dialog uses the {size} size variant. On mobile
devices, all sizes adapt to near full-width for optimal viewing. On desktop,
each size provides a different maximum width to suit various content needs.
>
)}
))}
);
}
```
### Checkbox Animation Improvements
Faster animation and increased stroke width for better feedback on [Checkbox](/docs/components/checkbox).
```tsx
import {Checkbox, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Link Text Decoration
The [Link](/docs/components/link) component now uses Tailwind CSS classes for text decoration instead of built-in variants. This provides more flexibility and follows Tailwind conventions.
**Available Tailwind utilities:**
* `underline` - Always visible underline
* `no-underline` - Remove underline
* `hover:underline` - Underline appears on hover
* `decoration-primary`, `decoration-secondary`, etc. - Set underline color
* `decoration-1`, `decoration-2`, `decoration-4` - Control thickness
* `underline-offset-1`, `underline-offset-2`, etc. - Adjust spacing
```tsx
import {Link} from "@heroui/react";
export function LinkUnderlineAndOffset() {
return (
);
}
```
## ⚠️ Breaking Changes
### Link Component - Removed Underline Variants
The Link component's built-in `underline` and `underlineOffset` props have been removed. Use Tailwind CSS classes instead for text decoration.
**Before:**
```tsx
Link text
```
**After:**
```tsx
Link text
```
**Available Tailwind classes:**
* `underline`, `no-underline`, `hover:underline` - Decoration line
* `decoration-primary`, `decoration-muted`, etc. - Decoration color
* `decoration-solid`, `decoration-dashed`, `decoration-dotted` - Decoration style
* `decoration-1`, `decoration-2`, `decoration-4` - Decoration thickness
* `underline-offset-1`, `underline-offset-2`, `underline-offset-4` - Underline offset
For more details, see the [Link documentation](/docs/components/link).
### Form Components - Removed `isInSurface` Prop
The `isInSurface` prop and automatic surface detection have been removed from form-based components. Instead, use the `variant="secondary"` prop when placing form components inside Surface, Card, or other surface-based containers.
**Before:**
```tsx
{/* Input automatically detected surface context */}
```
**After:**
```tsx
{/* Use variant="secondary" for surface backgrounds */}
```
**Affected components:**
* Input
* InputGroup
* TextField
* TextArea
* SearchField
* NumberField
* DateField
* TimeField
* Select
* ComboBox
* Autocomplete
The `secondary` variant provides lower emphasis styling without shadow, which is appropriate for use on surface backgrounds.
## Style Fixes
* **Button**: Updated secondary button colors for improved visual consistency
* **Checkbox**: Optimized animation speed and increased stroke width for better feedback (see [Checkbox Animation Improvements](#checkbox-animation-improvements))
* **Link**: Updated decoration styles and transition timings
* **Focus Visible**: Added `:not(:focus)` to focus-visible selectors to prevent conflicts with hover states
* **Separator**: Fixed styles to only apply to horizontal separator
## Bug Fixes
* Fixed Link with Button variants styling
* Fixed Fieldset flexbox quirk in Safari with BEM styles
* Fixed SearchField empty state to properly disable clear button
* Fixed ButtonGroup context to only apply to direct children
* Fixed ButtonGroup `BUTTON_GROUP_CHILD` re-export for type declarations
## Dependencies
### Direct Exports from React Aria Components
HeroUI now provides direct exports from react-aria-components for easier access to primitives and utilities. These exports are particularly useful for [React Aria Framework setup](https://react-aria.adobe.com/frameworks).
**Providers:**
* `RouterProvider` - Configure React Aria links to use your client-side router
* `I18nProvider` - Set the locale used by React Aria components
**Hooks and Utilities:**
* `isRTL` - Check if a locale is right-to-left
* `useLocale` - Access the current locale and direction
* `useFilter` - Filter and sort collections
**Components:**
* `Collection` - Collection component for managing lists
* `ListBoxLoadMoreItem` - ListBox item for loading more items
**i18n Utilities:**
* `getLocalizationScript` - Get localization script for server-side rendering (from `react-aria-components/i18n`)
All of these can be imported directly from `@heroui/react`:
```tsx
import {
RouterProvider,
I18nProvider,
isRTL,
useLocale,
useFilter,
getLocalizationScript
} from "@heroui/react";
```
## Links
* [Theme Builder](/themes)
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3 (updated)](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #6121](https://github.com/heroui-inc/heroui/pull/6121)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-beta.6
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-6
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-6.mdx
> 6 new color components (ColorPicker, ColorArea, ColorSlider, ColorField, ColorSwatch, ColorSwatchPicker), toast improvements, and various style fixes.
February 6, 2026
This release introduces a comprehensive **Color System** with six new components for color selection and manipulation: [ColorPicker](/docs/components/color-picker), [ColorArea](/docs/components/color-area), [ColorSlider](/docs/components/color-slider), [ColorField](/docs/components/color-field), [ColorSwatch](/docs/components/color-swatch), and [ColorSwatchPicker](/docs/components/color-swatch-picker). Also includes [Separator](/docs/components/separator) variants and various style improvements.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### Color System
We're excited to introduce a comprehensive **Color System** - a complete suite of components for color selection, manipulation, and display. These components are built on React Aria's color primitives and work together seamlessly.
**Key features:**
* **Full Color Space Support**: Work with HSL, HSB, and RGB color spaces
* **Channel-based Editing**: Manipulate individual color channels (hue, saturation, lightness, brightness, red, green, blue, alpha)
* **Accessible by Default**: Full keyboard navigation and screen reader support
* **Composable Design**: Mix and match components to build custom color pickers
### New Components
This release introduces **6 new** color components:
* **[ColorPicker](#colorpicker)**: Complete color picker with trigger, popover, and composable internals. ([Documentation](/docs/components/color-picker))
* **[ColorArea](#colorarea)**: 2D gradient area for selecting two color channels simultaneously. ([Documentation](/docs/components/color-area))
* **[ColorSlider](#colorslider)**: Single-channel slider for precise color adjustments. ([Documentation](/docs/components/color-slider))
* **[ColorField](#colorfield)**: Text input for entering and editing color values. ([Documentation](/docs/components/color-field))
* **[ColorSwatch](#colorswatch)**: Visual color preview with support for transparency. ([Documentation](/docs/components/color-swatch))
* **[ColorSwatchPicker](#colorswatchpicker)**: Grid of selectable color swatches for quick color selection. ([Documentation](/docs/components/color-swatch-picker))
### ColorPicker
The ColorPicker is a compound component that combines all color components into a complete color selection experience.
```tsx
import {ColorArea, ColorPicker, ColorSlider, ColorSwatch, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
### ColorArea
A 2D gradient area for selecting two color channels at once, typically saturation and brightness.
```tsx
import {ColorArea} from "@heroui/react";
export function ColorAreaBasic() {
return (
);
}
```
### ColorSlider
A slider for adjusting individual color channels like hue, saturation, lightness, or alpha.
```tsx
import {ColorSlider, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
**With different channels:**
```tsx
"use client";
import {ColorSlider, ColorSwatch, Label} from "@heroui/react";
import {useState} from "react";
import {parseColor} from "react-aria-components";
export function Channels() {
const [color, setColor] = useState(parseColor("hsl(0, 100%, 50%)"));
return (
Current color: {color.toString("hsl")}
);
}
```
### ColorField
A text input field for entering color values directly. Supports various color formats.
```tsx
"use client";
import type {Color} from "@heroui/react";
import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react";
import {useState} from "react";
export function Basic() {
const [color, setColor] = useState(parseColor("#0485F7"));
return (
);
}
```
### ColorSwatch
A visual display of a color value with support for transparency patterns.
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchBasic() {
return (
);
}
```
### ColorSwatchPicker
A grid of color swatches for quick color selection from a predefined palette.
```tsx
import {ColorSwatchPicker} from "@heroui/react";
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
export function Basic() {
return (
{colors.map((color) => (
))}
);
}
```
## Component Improvements
### Toast Enhancements
The [Toast](/docs/components/toast) component has been significantly improved with new features and better stability (#6151):
**New Features:**
* **Loading State**: Added `isLoading` prop to show a spinner instead of the default indicator
* **Default Timeout**: Toasts now auto-dismiss after 4 seconds by default (configurable via `timeout` prop)
* **Width Control**: Added `width` prop to `Toast.Provider` for customizable toast width
* **Adaptive Height**: Toasts now adapt their height based on content
* **Better Stacking**: Fixed layout shifts when toasts stack using absolute positioning and height synchronization
* **Improved Close Handling**: Deferred `onClose` callback to prevent toast transition deadlock
* **Front-most Close Button**: Close button only appears on the front-most toast for cleaner UI
* **Enhanced Promise Support**: Improved `toast.promise()` with better loading states and error handling
**New Demos:**
* Promise & Loading states
* Callbacks and timeout handling
```tsx
"use client";
import {HardDrive, Persons} from "@gravity-ui/icons";
import {Button, toast} from "@heroui/react";
const noop = () => {};
export function Variants() {
return (
);
}
```
### Separator Variants
Added variants to the [Separator](/docs/components/separator) component for different visual styles.
### Chip Component - Label Slot
The [Chip](/docs/components/chip) component now supports a `Chip.Label` subcomponent for better visual alignment. When removing start or end content (like icons), the label text was too close to the chip edges. Plain text children are automatically wrapped in `` for backward compatibility.
**Usage:**
```tsx
import { Chip } from '@heroui/react';
// Automatic wrapping (backward compatible)
Label text
// Explicit label with custom styling
Custom Label
// Mixing icons and labels
With Icon
```
## Style Fixes
* **Overlay Content**: Fixed blur effect on overlay content (#6136)
* **Invalid Field**: Converted ring to outline for invalid field states (#6184)
* **Link with Button**: Fixed styling for Link components using button variants (#6138)
* **Toast Content**: Fixed vertical alignment of toast content (#6147)
* **Safari SVG**: Fixed SVG shifting issue in Safari (#6149)
* **Placeholder Color**: Aligned placeholder color with input text (#6139)
* **Tooltip**: Removed cursor style from tooltip trigger component
* **CSS Variables**: Made calculated variables depend only on root variables (#6154)
## Bug Fixes
* Fixed page interactivity during view transitions (#6128)
* Fixed markdown URL formatting (#6162)
* Fixed incorrect link to combo box page (#6164)
* Fixed autocomplete styles import order in index.css
* Fixed hyphenated format for CSS classes (#6191)
## ⚠️ Breaking Changes
### Toast Component - Container Renamed to Provider
The `Toast.Container` component has been renamed to `Toast.Provider` for better semantic clarity (#6151).
**Before:**
```tsx
```
**After:**
```tsx
```
**Additional Changes:**
* Default `gap` prop changed from `14` to `12` pixels
* Default `timeout` is now `4000` (4 seconds) instead of requiring explicit timeout
* `Toast.Action` has been renamed to `Toast.ActionButton` for consistency
### CSS Class Naming Convention
CSS classes have been renamed to use hyphenated format for consistency (#6141). This follows BEM conventions more closely and improves compatibility with Tailwind CSS.
**Important Note**: The `textarea` class was initially renamed to `text-area` but was rolled back to `textarea` in PR #6191 due to conflicts with Tailwind's native `textarea` class. No changes are needed for TextArea component classes.
#### Component Class Name Changes
The following CSS class names have been updated. If you have custom CSS targeting these classes directly, update your selectors:
| Component | Old Class Name | New Class Name | Notes |
| ------------------ | -------------------------- | --------------------------- | ------------------------------------------------------ |
| **ComboBox** | `.combobox` | `.combo-box` | All related classes updated |
| | `.combobox__input-group` | `.combo-box__input-group` | |
| | `.combobox__trigger` | `.combo-box__trigger` | |
| | `.combobox__popover` | `.combo-box__popover` | |
| | `.combobox--full-width` | `.combo-box--full-width` | |
| **ListBox** | `.listbox` | `.list-box` | All related classes updated |
| **ListBoxItem** | `.listbox-item` | `.list-box-item` | All related classes updated |
| | `.listbox-item__indicator` | `.list-box-item__indicator` | |
| | `.listbox-item--default` | `.list-box-item--default` | |
| | `.listbox-item--danger` | `.list-box-item--danger` | |
| **ListBoxSection** | `.listbox-section` | `.list-box-section` | All related classes updated |
| **TextArea** | `.textarea` | `.textarea` | **No change** - Rolled back to avoid Tailwind conflict |
#### Migration Guide
**Before:**
```css
/* Custom styles targeting old class names */
.combobox {
/* styles */
}
.listbox-item {
/* styles */
}
```
**After:**
```css
/* Update to new hyphenated class names */
.combo-box {
/* styles */
}
.list-box-item {
/* styles */
}
```
**JavaScript/TypeScript Updates:**
If you're using these class names in JavaScript or TypeScript code:
```tsx
// Before
// After
```
**Note**: Component props and TypeScript types remain unchanged. Only CSS class names have been updated.
### Removed CSS Variables
Several CSS variables have been removed as part of the surface color refactoring (#6204). These variables were either replaced with direct variable references or removed entirely.
#### Surface Color Variables
The following calculated surface color variables have been removed and replaced with direct variable references:
**Removed:**
* `--color-surface-secondary` (was calculated via `color-mix`)
* `--color-surface-tertiary` (was calculated via `color-mix`)
**Replacement:**
These variables now directly reference the base variables defined in `variables.css`:
* `--color-surface-secondary` → Uses `var(--surface-secondary)` directly
* `--color-surface-tertiary` → Uses `var(--surface-tertiary)` directly
The base variables `--surface-secondary` and `--surface-tertiary` are now defined directly in `variables.css` instead of being calculated in `theme.css`.
#### On Surface Color Variables
All `--color-on-surface-*` variables have been removed entirely:
**Removed:**
* `--color-on-surface`
* `--color-on-surface-foreground`
* `--color-on-surface-hover`
* `--color-on-surface-focus`
* `--color-on-surface-secondary`
* `--color-on-surface-secondary-foreground`
* `--color-on-surface-secondary-hover`
* `--color-on-surface-secondary-focus`
* `--color-on-surface-tertiary`
* `--color-on-surface-tertiary-foreground`
* `--color-on-surface-tertiary-hover`
* `--color-on-surface-tertiary-focus`
**Migration:**
If you were using these variables, update your code to use the appropriate surface variables directly:
```css
/* Before */
.element {
background: var(--color-on-surface);
color: var(--color-on-surface-foreground);
}
.element:hover {
background: var(--color-on-surface-hover);
}
/* After */
.element {
background: var(--surface-secondary);
color: var(--surface-secondary-foreground);
}
.element:hover {
background: color-mix(in oklab, var(--surface-secondary) 92%, var(--surface-secondary-foreground) 8%);
}
```
Or use the Tailwind utilities:
```tsx
// Before
// After
```
**Related PR:** [#6204](https://github.com/heroui-inc/heroui/pull/6204)
## Links
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #6201](https://github.com/heroui-inc/heroui/pull/6201)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-beta.7
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-7
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-7.mdx
> 4 new components (Calendar, RangeCalendar, DatePicker, DateRangePicker) and APIs improvements.
February 19, 2026
This release adds 4 new components: [Calendar](/docs/components/calendar), [RangeCalendar](/docs/components/range-calendar), [DatePicker](/docs/components/date-picker), and [DateRangePicker](/docs/components/date-range-picker). Also new: [Switch.Content](#switchcontent) for grouping label and description, and [Tabs.Separator](#tabsseparator) for opt-in separator lines between tabs.
⚠️ **Breaking changes**: `hideSeparator` removed from Tabs; `DateInputGroup` and `ColorInputGroup` moved under `DateField.Group`, `TimeField.Group`, and `ColorField.Group`.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### Date & Time System
**Date & Time** — Calendar, DatePicker, RangeCalendar, and DateRangePicker built on React Aria date primitives. Supports i18n, time zones, and full keyboard/ARIA accessibility.
**Key features:**
* **Calendar systems**: Gregorian, Buddhist, Persian, and others
* **Year picker**: Overlay for quick year navigation
* **Cell indicators**: Events, availability, or status dots on cells
* **Range selection**: Date ranges with visual highlighting
* **Accessible**: Keyboard nav, screen readers, ARIA
All date values use [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types (`CalendarDate`, `CalendarDateTime`, `ZonedDateTime`). Wrap with [`I18nProvider`](https://react-aria.adobe.com/I18nProvider) to override locale; read it with [`useLocale`](https://react-aria.adobe.com/useLocale).
### New Components
* **[Calendar](#calendar)**: Single date selection, year picker, indicators, multi-month. ([Docs](/docs/components/calendar))
* **[RangeCalendar](#rangecalendar)**: Date ranges with range highlighting and multi-month. ([Docs](/docs/components/range-calendar))
* **[DatePicker](#datepicker)**: Date field + popover calendar. ([Docs](/docs/components/date-picker))
* **[DateRangePicker](#daterangepicker)**: Two date fields + popover range calendar. ([Docs](/docs/components/date-range-picker))
### Calendar
Single-date calendar with year picker, cell indicators, multi-month view, and i18n calendars.
```tsx
"use client";
import {Calendar} from "@heroui/react";
export function Basic() {
return (
{(day) => {day}}
{(date) => }
);
}
```
**Year Picker:**
```tsx
"use client";
import {Calendar} from "@heroui/react";
export function YearPicker() {
return (
{(day) => {day}}
{(date) => }
{({year}) => }
);
}
```
**International Calendars:**
```tsx
"use client";
import {Calendar} from "@heroui/react";
import {getLocalTimeZone, today} from "@internationalized/date";
import {I18nProvider} from "react-aria-components";
export function InternationalCalendar() {
return (
{(day) => {day}}
{(date) => }
{({year}) => }
);
}
```
### RangeCalendar
Date range selection with range highlighting and multi-month views.
```tsx
"use client";
import {RangeCalendar} from "@heroui/react";
export function Basic() {
return (
{(day) => {day}}
{(date) => }
);
}
```
**Multiple Months:**
```tsx
"use client";
import {RangeCalendar} from "@heroui/react";
import {getLocalTimeZone} from "@internationalized/date";
import React from "react";
import {RangeCalendarStateContext, useLocale} from "react-aria-components";
function RangeCalendarMonthHeading({offset = 0}: {offset?: number}) {
const state = React.useContext(RangeCalendarStateContext)!;
const {locale} = useLocale();
const startDate = state.visibleRange.start;
const monthDate = startDate.add({months: offset});
const dateObj = monthDate.toDate(getLocalTimeZone());
const monthYear = new Intl.DateTimeFormat(locale, {month: "long", year: "numeric"}).format(
dateObj,
);
return {monthYear};
}
export function MultipleMonths() {
return (
state.setTimeValue(v as TimeValue)}
>
{(segment) => }
)}
>
)}
);
}
```
### DateRangePicker
Two date fields + popover range calendar.
```tsx
"use client";
import {DateField, DateRangePicker, Label, RangeCalendar} from "@heroui/react";
export function Basic() {
return (
{(segment) => }
{(segment) => }
{(day) => {day}}
{(date) => }
{({year}) => }
);
}
```
## API Improvements
### Switch.Content
`Switch.Content` groups label and description next to the switch control ([#6240](https://github.com/heroui-inc/heroui/pull/6240)).
**Before:**
```tsx
import { Switch, Label, Description } from '@heroui/react';
Get notified when someone mentions you
```
### Tabs.Separator
The [Tabs](/docs/components/tabs) component now includes an explicit `Tabs.Separator` sub-component for adding visual separator lines between tabs. This replaces the previous automatic CSS pseudo-element separator and the `hideSeparator` prop ([#6243](https://github.com/heroui-inc/heroui/pull/6243)).
Separators are now **opt-in** — add `` inside each `` where you want a separator line.
### Field Sub-Component Consolidation
`DateField`, `TimeField`, and `ColorField` now expose their input group sub-components directly, removing the need to import `DateInputGroup` or `ColorInputGroup` separately. See [Breaking Changes](#-breaking-changes) for migration details.
### Breadcrumbs Fix
Props passed to `Breadcrumbs.Item` are now forwarded to the underlying `Link` ([#6233](https://github.com/heroui-inc/heroui/pull/6233)).
## Style Fixes
* **ListBox Item**: Adjusted hover background color from `bg-default-hover` to `bg-default` for consistency
* **Date Input Group**: Changed segment text from `tabular-nums` to `text-nowrap` for better layout
* **Date Input Group**: Improved focus-within styles to exclude date picker trigger from field focus highlighting
## Dependencies
* **React Aria Components**: Updated from `1.14.0` to `1.15.0` — adds a new [`render` prop](https://react-aria.adobe.com/customization#dom-elements) for customizing the DOM element rendered by any React Aria component (useful for router links, animation libraries like Motion, etc.)
* **@react-aria/utils**: Updated from `3.32.0` to `3.33.0`
* **@react-types/shared**: Updated from `3.32.1` to `3.33.0`
* **@internationalized/date**: Updated from `3.10.1` to `3.11.0` — date fields now constrain on blur instead of as you type
* Added `@react-aria/i18n` and `@react-stately/utils` for calendar i18n
## ⚠️ Breaking Changes
### Tabs — `hideSeparator` Prop Removed
The `hideSeparator` prop has been removed from the Tabs component. Separators are now **opt-in** using the new `` sub-component instead of being automatically generated via CSS pseudo-elements ([#6243](https://github.com/heroui-inc/heroui/pull/6243)).
**Before:**
```tsx
{/* Separators shown by default, hidden via prop */}
Tab 1Tab 2
```
**After:**
```tsx
{/* No separators by default — explicitly add them where needed */}
Tab 1Tab 2
```
**CSS Changes:**
* Tab separator styles moved from pseudo-element (`.tabs__tab:not(:first-child):before`) to a dedicated `.tabs__separator` class
* The `[data-hide-separator]` data attribute has been removed
### Field Sub-Component API Changes
`DateInputGroup` and `ColorInputGroup` are no longer exported directly from `@heroui/react`. Their sub-components have been consolidated under their respective field components (`DateField`, `TimeField`, `ColorField`).
#### DateField Changes
**Before:**
```tsx
import {DateField, Label, DateInputGroup, Description} from '@heroui/react';
...
{(segment) => }
...Pick a date
```
**After:**
```tsx
import {DateField, Label, Description} from '@heroui/react';
...
{(segment) => }
...Pick a date
```
#### TimeField Changes
Same pattern as DateField:
| Before | After |
| ------------------------ | ------------------- |
| `DateInputGroup` | `TimeField.Group` |
| `DateInputGroup.Input` | `TimeField.Input` |
| `DateInputGroup.Segment` | `TimeField.Segment` |
| `DateInputGroup.Prefix` | `TimeField.Prefix` |
| `DateInputGroup.Suffix` | `TimeField.Suffix` |
#### ColorField Changes
| Before | After |
| ------------------------ | ------------------- |
| `ColorInputGroup` | `ColorField.Group` |
| `ColorInputGroup.Input` | `ColorField.Input` |
| `ColorInputGroup.Prefix` | `ColorField.Prefix` |
| `ColorInputGroup.Suffix` | `ColorField.Suffix` |
**Usage:**
```tsx
import {ColorField, Label, ColorInputGroup, ColorSwatch} from '@heroui/react';
```
**After:**
```tsx
import {ColorField, Label, ColorSwatch} from '@heroui/react';
```
> **Note:** The underlying CSS classes (`.date-input-group`, `.color-input-group`, etc.) remain unchanged. Only the JavaScript import paths and component names have changed.
## Links
* [Component Documentation](/docs/react/components)
* [Design System - Figma Kit V3](https://www.figma.com/community/file/1546526812159103429/heroui-figma-kit-v3)
* [GitHub Repository](https://github.com/heroui-inc/heroui)
* [GitHub PR #6237](https://github.com/heroui-inc/heroui/pull/6237)
## Contributors
Thanks to everyone who contributed to this release!
# v3.0.0-beta.8
**Category**: react
**URL**: https://v3.heroui.com/docs/react/releases/v3-0-0-beta-8
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/releases/v3-0-0-beta-8.mdx
> 3 new components (Badge, Pagination, Table), DateField improvements, and key API/style fixes.
March 2, 2026
This release adds three new components: [Badge](/docs/components/badge), [Pagination](/docs/components/pagination), and [Table](/docs/components/table), plus new `InputContainer` composition APIs for [DateField](/docs/components/date-field) and [TimeField](/docs/components/time-field).
⚠️ **Breaking changes**: TextField CSS classes were renamed from `.text-field` to `.textfield`.
## Installation
Update to the latest version:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
**Using AI assistants?** Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the [HeroUI MCP Server](/docs/ui-for-agents/mcp-server).
## What's New
### New Components
* **[Badge](#badge)**: Compact status + count indicator with color, variant, placement, and size options. ([Docs](/docs/components/badge))
* **[Pagination](#pagination)**: Compound pagination primitives with summary, ellipsis, and previous/next controls. ([Docs](/docs/components/pagination))
* **[Table](#table)**: Data table primitives with sorting, selection, resizing, async loading, and footer composition. ([Docs](/docs/components/table))
### Badge
New badge primitives for counters, labels, and anchored overlays with `Badge.Anchor` and `Badge.Label`.
```tsx
import {Avatar, Badge} from "@heroui/react";
const GREEN_AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
const ORANGE_AVATAR_URL =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg";
const BLUE_AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg";
export function BadgeBasic() {
return (
JD
5
AB
New
CD
);
}
```
### Pagination
New navigation component built with composable parts (`Root`, `Content`, `Item`, `Link`, `Previous`, `Next`, `Summary`, `Ellipsis`).
```tsx
"use client";
import {Pagination} from "@heroui/react";
import {useState} from "react";
export function PaginationWithEllipsis() {
const [page, setPage] = useState(1);
const totalPages = 12;
const getPageNumbers = () => {
const pages: (number | "ellipsis")[] = [];
pages.push(1);
if (page > 3) {
pages.push("ellipsis");
}
const start = Math.max(2, page - 1);
const end = Math.min(totalPages - 1, page + 1);
for (let i = start; i <= end; i++) {
pages.push(i);
}
if (page < totalPages - 2) {
pages.push("ellipsis");
}
pages.push(totalPages);
return pages;
};
return (
setPage((p) => p - 1)}>
Previous
{getPageNumbers().map((p, i) =>
p === "ellipsis" ? (
) : (
setPage(p)}>
{p}
),
)}
setPage((p) => p + 1)}>
Next
);
}
```
### Table
Compound data table on React Aria with sortable columns, row selection, custom cells, load-more sentinel rows, and resizable columns.
```tsx
import {Table} from "@heroui/react";
export function Basic() {
return (
### Background & Surface
### Primary Colors
**Accent** — Your main brand color (used for primary actions)
**Accent Soft** — A lighter version for secondary actions
### Status Colors
For alerts, validation, and status messages:
### Form Field Colors
For consistent form field styling across input components:
### Other Colors
## How to Use Colors
**In your components:**
```tsx
import { View, Text } from 'react-native';
import { Button } from 'heroui-native';
Content;
```
**In CSS files:**
```css title="global.css"
/* Direct CSS variables */
.container {
flex: 1;
background-color: var(--accent);
width: 50px;
height: 50px;
border-radius: var(--radius);
}
```
## Default Theme
The complete theme definition can be found in ([variables.css](https://github.com/heroui-inc/heroui-native/blob/rc/src/styles/variables.css)). This theme automatically switches between light and dark modes through [Uniwind's theming system](https://docs.uniwind.dev/theming/basics), which supports system preferences and programmatic theme switching.
```css
@theme {
/* Primitive Colors (Do not change between light and dark) */
--white: oklch(100% 0 0);
--black: oklch(0% 0 0);
--snow: oklch(0.9911 0 0);
--eclipse: oklch(0.2103 0.0059 285.89);
/* Border */
--border-width: 1px;
--field-border-width: 0px;
/* Base radius */
--radius: 0.5rem;
--field-radius: calc(var(--radius) * 1.5);
/* Opacity */
--opacity-disabled: 0.5;
}
@layer theme {
:root {
@variant light {
/* Base Colors */
--background: oklch(0.9702 0 0);
--foreground: var(--eclipse);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: var(--white);
--surface-foreground: var(--foreground);
--surface-secondary: oklch(0.9524 0.0013 286.37);
--surface-secondary-foreground: var(--foreground);
--surface-tertiary: oklch(0.9373 0.0013 286.37);
--surface-tertiary-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: var(--white);
--overlay-foreground: var(--foreground);
--muted: oklch(0.5517 0.0138 285.94);
--default: oklch(94% 0.001 286.375);
--default-foreground: var(--eclipse);
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
/* Form Fields */
--field-background: var(--white);
--field-foreground: oklch(0.2103 0.0059 285.89);
--field-placeholder: var(--muted);
--field-border: transparent; /* no border by default on form fields */
/* Status Colors */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.7819 0.1585 72.33);
--warning-foreground: var(--eclipse);
--danger: oklch(0.6532 0.2328 25.74);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: var(--white);
--segment-foreground: var(--eclipse);
/* Misc Colors */
--border: oklch(90% 0.004 286.32);
--separator: oklch(74% 0.004 286.32);
--focus: var(--accent);
--link: var(--foreground);
/* Shadows */
--surface-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
--overlay-shadow:
0 2px 8px 0 rgba(0, 0, 0, 0.02), 0 -6px 12px 0 rgba(0, 0, 0, 0.01),
0 14px 28px 0 rgba(0, 0, 0, 0.03);
--field-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
}
@variant dark {
/* Base Colors */
--background: oklch(12% 0.005 285.823);
--foreground: var(--snow);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.2103 0.0059 285.89);
--surface-foreground: var(--foreground);
--surface-secondary: oklch(0.257 0.0037 286.14);
--surface-secondary-foreground: var(--foreground);
--surface-tertiary: oklch(0.2721 0.0024 247.91);
--surface-tertiary-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) - lighter for contrast */
--overlay: oklch(0.2103 0.0059 285.89);
--overlay-foreground: var(--foreground);
--muted: oklch(70.5% 0.015 286.067);
--default: oklch(27.4% 0.006 286.033);
--default-foreground: var(--snow);
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
/* Form Field Defaults - Colors (only the ones that are different from light theme) */
--field-background: oklch(0.2103 0.0059 285.89);
--field-foreground: var(--foreground);
--field-placeholder: var(--muted);
--field-border: transparent; /* no border by default on form fields */
/* Status Colors */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.8203 0.1388 76.34);
--warning-foreground: var(--eclipse);
--danger: oklch(0.594 0.1967 24.63);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: oklch(0.3964 0.01 285.93);
--segment-foreground: var(--foreground);
/* Misc Colors */
--border: oklch(28% 0.006 286.033);
--separator: oklch(40% 0.006 286.033);
--focus: var(--accent);
--link: var(--foreground);
/* Shadows */
--surface-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--overlay-shadow: 0 0 1px 0 rgba(255, 255, 255, 0.2) inset;
--field-shadow: 0 0 0 0 transparent inset; /* Transparent shadow to allow ring utilities to work */
}
}
}
```
## Customizing Colors
**Override existing colors:**
```css
@layer theme {
@variant light {
/* Override default colors */
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--success: oklch(0.65 0.15 155);
}
@variant dark {
/* Override dark theme colors */
--accent: oklch(0.65 0.25 270);
--success: oklch(0.75 0.12 155);
}
}
```
**Tip:** Convert colors at [oklch.com](https://oklch.com)
**Add your own colors:**
```css
@layer theme {
@variant light {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
@variant dark {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
}
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now you can use it:
```tsx
import { View, Text } from 'react-native';
Info message;
```
> **Note**: To learn more about theme variables and how they work in Tailwind CSS v4, see the [Tailwind CSS Theme documentation](https://tailwindcss.com/docs/theme).
## useThemeColor Hook
The `useThemeColor` hook has been enhanced to support multiple colors selection, making it more flexible for complex theming scenarios.
**Multiple Colors Selection:**
You can now select multiple colors at once, which is useful when you need to work with related color values together:
```tsx
import { useThemeColor } from 'heroui-native';
// Select multiple colors at once
const [accent, accentForeground, success, danger] = useThemeColor([
'accent',
'accentForeground',
'success',
'danger',
]);
// Use the selected colors
Accent Text;
```
This enhancement improves performance when working with multiple color values and makes it easier to manage complex theming scenarios where multiple colors need to be selected and applied together.
## Quick Tips
* Always use color variables, not hard-coded values
* Use foreground/background pairs for good contrast
* Test in both light and dark modes
* The system respects user's theme preference automatically
## Related
* [Theming](/docs/native/getting-started/theming) - Learn about the theming system
* [Styling](/docs/native/getting-started/styling) - Styling components with CSS
* [Design Principles](/docs/native/getting-started/design-principles) - Understanding HeroUI's design philosophy
# Composition
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/composition
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/composition.mdx
> Build flexible UI with component composition patterns
HeroUI Native uses composition patterns to create flexible, customizable components. Change the rendered element, compose components together, and maintain full control over markup.
## Compound Components
HeroUI Native components use a compound component pattern with dot notation—components export sub-components as properties (e.g., `Button.Label`, `Dialog.Trigger`, `Accordion.Item`) that work together to form complete UI elements.
```tsx
import { Button, Dialog } from 'heroui-native';
function DialogExample() {
return (
);
}
```
## The asChild Prop
The `asChild` prop lets you change what element a component renders. When `asChild` is true, HeroUI Native clones the child element and merges props instead of rendering its default element.
```tsx
import { Button, Dialog } from 'heroui-native';
function DialogExample() {
return (
);
}
```
## Custom Components
Create your own components by composing HeroUI Native primitives:
```tsx
import { Button, Card, Popover } from 'heroui-native';
import { View } from 'react-native';
// Product card component
function ProductCard({ title, description, price, onBuy, ...props }) {
return (
{price}{title}{description}
);
}
// Popover button component
function PopoverButton({ children, popoverContent, ...props }) {
return (
{popoverContent}
);
}
// Usage
console.log('Buy')}
/>
InformationAdditional details here
}>
Show Info
```
## Custom Variants
Create custom variants using `tailwind-variants` to extend component styling. Note that text color classes must be applied to `Button.Label`, not the parent `Button`:
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
base: 'font-semibold rounded-lg',
variants: {
intent: {
primary: 'bg-blue-500',
secondary: 'bg-gray-200',
danger: 'bg-red-500',
},
},
defaultVariants: {
intent: 'primary',
},
});
const customLabelVariants = tv({
base: '',
variants: {
intent: {
primary: 'text-white',
secondary: 'text-gray-800',
danger: 'text-white',
},
},
defaultVariants: {
intent: 'primary',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
labelClassName?: string;
}
export function CustomButton({
intent,
className,
labelClassName,
children,
...props
}: CustomButtonProps) {
return (
);
}
```
## Next Steps
* Learn about [Styling](/docs/native/getting-started/styling) system
* Explore [Theming](/docs/native/getting-started/theming) documentation
* Explore [Animation](/docs/native/getting-started/animation) options
# Portal
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/portal
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/portal.mdx
Portals let you render its children into a different part of your app. This is particularly useful for components that need to render above other content, such as modals, overlays, and popups.
## Default Setup
By default, the `PortalHost` is included in the `HeroUINativeProvider`, so there is no need to add it manually. The provider automatically sets up the portal system for all components that use portals.
## Advanced Use Cases
For advanced use cases, you can import `Portal` and `PortalHost` directly from `heroui-native` to create custom portal implementations:
```tsx
import { Portal, PortalHost } from "heroui-native";
import { View, Text } from "react-native";
function AppLayout() {
return (
Header ContentMain Content Area
{/* Portal host positioned at the top of the screen */}
);
}
function CustomNotification() {
return (
This notification appears at the top via Portal
);
}
```
In this example, the `CustomNotification` component uses a `Portal` to render its content at the location of the `PortalHost`, which is positioned at the top of the screen. This allows the notification to appear above all other content regardless of where it's defined in the component tree.
## State Management Considerations
State changes in parent components can cause unexpected issues with components rendered inside portals. For example, when a text input is placed directly inside a portal and the parent component re-renders, it can reset the input's auto-suggestions or cause other UI disruptions.
To avoid this, keep the state of interactive components (like text inputs) inside the portal by creating a separate component for the portal content. This isolates the state from parent re-renders.
### Example Pattern
```tsx
// ❌ Problematic: State in parent causes re-renders that affect portal content
function ParentComponent() {
const [dialogOpen, setDialogOpen] = useState(false);
const [inputValue, setInputValue] = useState(""); // State in parent
return (
);
}
// ✅ Correct: State managed inside separate component within portal
function ParentComponent() {
const [dialogOpen, setDialogOpen] = useState(false);
return (
);
}
function DialogFormContent({ onClose }: { onClose: () => void }) {
const [inputValue, setInputValue] = useState(""); // State inside portal
const [error, setError] = useState("");
return (
{error}
);
}
```
In the correct pattern, the `DialogFormContent` component manages its own state independently of the parent component. This ensures that parent re-renders (such as when `dialogOpen` changes) don't affect the input's internal state, preserving auto-suggestions and other input behaviors.
## API Reference
### PortalHost
By default, children of all Portal components will be rendered as its own children.
| Prop | Type | Note |
| ---- | -------- | --------------------------------------------------- |
| name | `string` | Provide when it is used as a custom host (optional) |
### Portal
| Prop | Type | Note |
| -------- | ----------------- | ------------------------------------------------------------------------------------- |
| name\* | `string` | Unique value otherwise the portal with the same name will replace the original portal |
| hostName | `string` | Provide when its children are to be rendered in a custom host (optional) |
| children | `React.ReactNode` | The content to render in the portal |
\* Required prop
## Related
* [Quick Start](/docs/native/getting-started/quick-start) - Basic setup guide
* View [Provider](/docs/native/getting-started/provider) documentation
# Provider
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/provider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/provider.mdx
> Configure HeroUI Native provider with text, animation, and toast settings
The `HeroUINativeProvider` is the root provider component that configures and initializes HeroUI Native in your React Native application. It provides global configuration and portal management for your application.
## Overview
The provider serves as the main entry point for HeroUI Native, wrapping your application with essential contexts and configurations:
* **Safe Area Insets**: Automatically handles safe area insets updates via `SafeAreaListener` and syncs them with Uniwind for use in Tailwind classes (e.g., `pb-safe-offset-3`)
* **Text Configuration**: Global text component settings for consistency across all HeroUI components
* **Animation Configuration**: Global animation control to disable all animations across the application
* **Toast Configuration**: Global toast system configuration including insets, default props, and wrapper components
* **Portal Management**: Handles overlays, modals, and other components that render on top of the app hierarchy
## Basic Setup
Wrap your application root with the provider:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
{/* Your app content */}
);
}
```
## Configuration Options
The provider accepts a `config` prop with the following options:
### Text Component Configuration
Global settings for all Text components within HeroUI Native. These props are carefully selected to include only those that make sense to configure globally across all Text components in the application:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
textProps: {
// Disable font scaling for accessibility
allowFontScaling: false,
// Auto-adjust font size to fit container
adjustsFontSizeToFit: false,
// Maximum font size multiplier when scaling
maxFontSizeMultiplier: 1.5,
// Minimum font scale (iOS only, 0.01-1.0)
minimumFontScale: 0.5,
},
};
export default function App() {
return (
{/* Your app content */}
);
}
```
### Animation Configuration
Global animation configuration for the entire application:
```tsx
const config: HeroUINativeConfig = {
// Disable all animations across the application (cascades to all children)
animation: 'disable-all',
};
```
**Note**: When set to `'disable-all'`, all animations across the application will be disabled. This is useful for accessibility or performance optimization.
### Developer Information Configuration
Control developer-facing informational messages displayed in the console:
```tsx
const config: HeroUINativeConfig = {
devInfo: {
// Disable styling principles information message
stylingPrinciples: false,
},
};
```
**Note**: By default, informational messages are enabled. Set `stylingPrinciples: false` to disable the styling principles message that appears in the console during development.
### Toast Configuration
Configure the global toast system including insets, default props, and wrapper components. You can also disable the toast provider entirely:
**Option 1: Disable Toast Provider**
```tsx
const config: HeroUINativeConfig = {
// Disable toast provider entirely
toast: false,
// or
toast: 'disabled',
};
```
**Note**: When toast is disabled (`false` or `'disabled'`), the `ToastProvider` will not be rendered, and toast functionality will not be available in your application.
**Option 2: Configure Toast Provider**
```tsx
import { KeyboardAvoidingView } from 'react-native';
const config: HeroUINativeConfig = {
toast: {
// Global toast configuration (used as defaults for all toasts)
defaultProps: {
variant: 'default',
placement: 'top',
isSwipeable: true,
animation: true,
},
// Insets for spacing from screen edges (added to safe area insets)
insets: {
top: 0, // Default: iOS = 0, Android = 12
bottom: 6, // Default: iOS = 6, Android = 12
left: 12, // Default: 12
right: 12, // Default: 12
},
// Maximum number of visible toasts before opacity starts fading
maxVisibleToasts: 3,
// Custom wrapper function to wrap the toast content
contentWrapper: (children) => (
{children}
),
},
};
```
## Complete Example
Here's a comprehensive example showing all configuration options:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const config: HeroUINativeConfig = {
// Global text configuration
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
allowFontScaling: true,
adjustsFontSizeToFit: false,
},
// Global animation configuration
animation: 'disable-all', // Optional: disable all animations
// Developer information messages configuration
devInfo: {
stylingPrinciples: true, // Optional: disable styling principles message
},
// Global toast configuration
// Option 1: Configure toast with custom settings
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
maxVisibleToasts: 3,
},
// Option 2: Disable toast entirely
// toast: false,
// or
// toast: 'disabled',
};
export default function App() {
return (
);
}
```
## Integration with Expo Router
When using Expo Router, wrap your root layout:
```tsx
// app/_layout.tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { Stack } from 'expo-router';
const config: HeroUINativeConfig = {
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
},
};
export default function RootLayout() {
return (
);
}
```
## Architecture
### Provider Hierarchy
The `HeroUINativeProvider` internally composes multiple providers:
```
HeroUINativeProvider
├── SafeAreaListener (handles safe area insets updates)
│ └── GlobalAnimationSettingsProvider (animation configuration)
│ └── TextComponentProvider (text configuration)
│ └── ToastProvider (toast configuration, conditionally rendered)
│ └── Your App
│ └── PortalHost (for overlays)
```
**Note**: The `ToastProvider` is conditionally rendered based on the `toast` configuration. If `toast` is set to `false` or `'disabled'`, the `ToastProvider` will not be rendered, and the app content and `PortalHost` will be rendered directly under `TextComponentProvider`.
### Safe Area Insets Handling
The provider automatically wraps your application with [`SafeAreaListener`](https://appandflow.github.io/react-native-safe-area-context/api/safe-area-listener) from `react-native-safe-area-context`. This component listens to safe area insets and frame changes without triggering re-renders, and automatically updates Uniwind with the latest insets via the `onChange` callback.
## Raw Provider
`HeroUINativeProviderRaw` is a lightweight variant of `HeroUINativeProvider` designed for bundle optimization. It excludes `ToastProvider` and `PortalHost`, giving you a bare minimum starting point where you only install and add what you actually need.
### When to Use
Use `HeroUINativeProviderRaw` when you want full control over which dependencies are included in your bundle. With the raw provider imported from `heroui-native/provider-raw`, the following dependencies are optional and only required if you use the corresponding components:
* **react-native-screens** -- required for overlay components (Popover, Dialog)
* **@gorhom/bottom-sheet** -- required for BottomSheet component
* **react-native-svg** -- required for components that use icons (Accordion, Alert, Checkbox, etc.)
### Setup
```tsx
import {
HeroUINativeProviderRaw,
type HeroUINativeConfigRaw,
} from 'heroui-native/provider-raw';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const config: HeroUINativeConfigRaw = {
textProps: {
maxFontSizeMultiplier: 1.5,
},
};
export default function App() {
return (
{/* Your app content */}
);
}
```
### Adding Toast and Portal Manually
If you need toast or portal functionality with the raw provider, add them yourself:
```tsx
import { HeroUINativeProviderRaw } from 'heroui-native/provider-raw';
import { PortalHost } from 'heroui-native/portal';
import { ToastProvider } from 'heroui-native/toast';
export default function App() {
return (
{/* Your app content */}
);
}
```
### Provider Hierarchy
```
HeroUINativeProviderRaw
├── SafeAreaListener (handles safe area insets updates)
│ └── GlobalAnimationSettingsProvider (animation configuration)
│ └── TextComponentProvider (text configuration)
│ └── Your App
```
## Best Practices
### 1. Single Provider Instance
Always use a single `HeroUINativeProvider` at the root of your app. Don't nest multiple providers:
```tsx
// ❌ Bad
{/* Don't do this */}
// ✅ Good
```
### 2. Configuration Object
Define your configuration outside the component to prevent recreating on each render:
```tsx
// ❌ Bad
function App() {
return (
{/* ... */}
);
}
// ✅ Good
const config: HeroUINativeConfig = {
textProps: {
maxFontSizeMultiplier: 1.5,
},
};
function App() {
return (
{/* ... */}
);
}
```
### 3. Text Configuration
Consider accessibility when configuring text props:
```tsx
const config: HeroUINativeConfig = {
textProps: {
// Allow font scaling for accessibility
allowFontScaling: true,
// But limit maximum scale
maxFontSizeMultiplier: 1.5,
},
};
```
## TypeScript Support
The provider is fully typed. Import types for better IDE support:
```tsx
import { HeroUINativeProvider, type HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
// Full type safety and autocomplete
textProps: {
allowFontScaling: true,
maxFontSizeMultiplier: 1.5,
},
animation: 'disable-all', // Optional: disable all animations
devInfo: {
stylingPrinciples: true, // Optional: disable styling principles message
},
// Toast configuration options:
// - false or 'disabled': Disable toast provider
// - ToastProviderProps object: Configure toast settings
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
},
};
```
## Related
* [Quick Start](/docs/native/getting-started/quick-start) - Basic setup guide
* [Theming](/docs/native/getting-started/theming) - Customize colors and themes
* [Styling](/docs/native/getting-started/styling) - Style components with Tailwind
# Styling
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/styling
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/styling.mdx
> Style HeroUI Native components with Tailwind or StyleSheet API
HeroUI Native components provide flexible styling options: Tailwind CSS utilities, StyleSheet API, and render props for dynamic styling.
## Styling Principles
HeroUI Native is built with `className` as the go-to styling solution. You can use Tailwind CSS classes via the `className` prop on all components.
**StyleSheet precedence:** The `style` prop (StyleSheet API) can be used and has precedence over `className` when both are provided. This allows you to override Tailwind classes when needed.
**Animated styles:** Some style properties are animated using `react-native-reanimated` and, like StyleSheet styles, they have precedence over `className`. To identify which styles are animated and cannot be used via `className`:
* **Hover over `className` in your IDE** - The TypeScript definitions will show which properties are available
* **Check component documentation** - Each component page includes a link to the component's style source at the top, which contains notes about animated properties
**Customizing animated styles:** If styles are occupied by animation, you can modify them via the `animation` prop on components that support it.
## Basic Styling
**Using className:** All HeroUI Native components accept `className` props:
```tsx
import { Button } from 'heroui-native';
;
```
**Using style:** Components also accept inline styles via the `style` prop:
```tsx
import { Button } from 'heroui-native';
;
```
## Render Props
Use a render function to access component state and customize content dynamically:
```tsx
import { RadioGroup, Label, cn } from 'heroui-native';
{({ isSelected, isInvalid, isDisabled }) => (
<>
{isSelected && }
>
)}
;
```
## Creating Wrapper Components
Create reusable custom components using [tailwind-variants](https://tailwind-variants.org/)—a Tailwind CSS first-class variant API:
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
base: 'font-semibold rounded-lg',
variants: {
intent: {
primary: 'bg-blue-500',
secondary: 'bg-gray-200',
danger: 'bg-red-500',
},
},
defaultVariants: {
intent: 'primary',
},
});
const customLabelVariants = tv({
base: '',
variants: {
intent: {
primary: 'text-white',
secondary: 'text-gray-800',
danger: 'text-white',
},
},
defaultVariants: {
intent: 'primary',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
labelClassName?: string;
}
export function CustomButton({
intent,
className,
labelClassName,
children,
...props
}: CustomButtonProps) {
return (
);
}
```
## Using Component classNames
Each HeroUI Native component exports a `classNames` object that contains the same styling functions used internally by the component. This is particularly useful when you want to style your own custom components to match the appearance of HeroUI Native components.
For example, you can style a custom `Link` component to look like a `Button`:
```tsx
import { buttonClassNames, cn } from 'heroui-native';
import { Pressable, Text } from 'react-native';
interface LinkProps {
href: string;
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
className?: string;
}
export function Link({
href,
variant = 'primary',
size = 'md',
children,
className,
}: LinkProps) {
return (
{
// Handle navigation
}}
>
{children}
);
}
```
**Available classNames exports:**
Each component exports its `classNames` object. For example:
* `buttonClassNames` - Contains `root` and `label` functions
* `cardClassNames` - Contains `root`, `header`, `body`, `footer`, `label`, and `description` functions
* `chipClassNames` - Contains `root` and `label` functions
* And many more...
**Usage pattern:**
```tsx
import { buttonClassNames } from 'heroui-native';
// Use with variant and size options
const rootClasses = buttonClassNames.root({
variant: 'primary',
size: 'md',
className: 'custom-class', // Optional: merge with your own classes
});
const labelClasses = buttonClassNames.label({
variant: 'primary',
size: 'md',
});
```
The `classNames` functions accept the same variant props as the components themselves, allowing you to maintain visual consistency across your custom components and HeroUI Native components.
## Responsive Design
HeroUI Native supports Tailwind's responsive breakpoint system via [Uniwind](https://docs.uniwind.dev/breakpoints). Use breakpoint prefixes like `sm:`, `md:`, `lg:`, and `xl:` to apply styles conditionally based on screen width.
**Mobile-first approach:** Start with mobile styles (no prefix), then use breakpoints to enhance for larger screens.
### Responsive Typography and Spacing
```tsx
import { Button } from 'heroui-native';
import { View, Text } from 'react-native';
Responsive Heading
;
```
### Responsive Layouts
```tsx
import { View, Text } from 'react-native';
{/* Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns */}
Item 1;
```
**Default breakpoints:**
* `sm`: 640px
* `md`: 768px
* `lg`: 1024px
* `xl`: 1280px
* `2xl`: 1536px
For custom breakpoints and more details, see the [Uniwind breakpoints documentation](https://docs.uniwind.dev/breakpoints).
## Utilities
HeroUI Native provides utility functions to assist with styling components.
### cn Utility
The `cn` utility function merges Tailwind CSS classes with proper conflict resolution. It's particularly useful when combining conditional classes or merging classes from props:
````tsx
import { cn } from 'heroui-native';
import { View } from 'react-native';
function MyComponent({ className, isActive }) {
return (
);
}
```;
The `cn` utility is powered by `tailwind-variants` and includes:
- Automatic Tailwind class merging (`twMerge: true`)
- Custom opacity class group support
- Proper conflict resolution (later classes override earlier ones)
**Example with conflicts:**
```tsx
// 'bg-accent' overrides 'bg-background'
cn('bg-background p-4', 'bg-accent');
// Result: 'p-4 bg-accent'
````
### useThemeColor Hook
Retrieves theme color values from CSS variables. Supports both single color and multiple colors for efficient batch retrieval.
**Single color usage:**
````tsx
import { useThemeColor } from 'heroui-native';
function MyComponent() {
const accentColor = useThemeColor('accent');
const dangerColor = useThemeColor('danger');
return (
Error message
);
}
```;
**Multiple colors usage (more efficient):**
```tsx
import { useThemeColor } from 'heroui-native';
function MyComponent() {
const [accentColor, backgroundColor, dangerColor] = useThemeColor([
'accent',
'background',
'danger',
]);
return (
Error message
);
}
```;
**Type signatures:**
```tsx
// Single color
useThemeColor(themeColor: ThemeColor): string
// Multiple colors (with type inference for tuples)
useThemeColor(
themeColor: T
): CreateStringTuple
// Multiple colors (array)
useThemeColor(themeColor: ThemeColor[]): string[]
````
Available theme colors include: `background`, `foreground`, `surface`, `accent`, `default`, `success`, `warning`, `danger`, and all their variants (hover, soft, foreground, etc.), plus semantic colors like `muted`, `border`, `separator`, `field`, `overlay`, and more.
## Next Steps
* Learn about [Animation](/docs/native/getting-started/animation) techniques
* Explore [Theming](/docs/native/getting-started/theming) system
* Explore [Colors](/docs/native/getting-started/colors) documentation
# Theming
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/theming
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/theming.mdx
> Customize HeroUI Native's design system with CSS variables and global styles
HeroUI Native uses CSS variables for theming. Customize everything from colors to component styles using standard CSS.
## How It Works
HeroUI Native's theming system is built on top of [Tailwind CSS v4](https://tailwindcss.com/docs/theme)'s theme via [Uniwind](https://uniwind.dev/). When you import `heroui-native/styles`, it uses Tailwind's built-in color palettes, maps them to semantic variables, automatically switches between light and dark themes, and uses CSS layers and the `@theme` directive for organization.
**Naming pattern:**
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
## Quick Start
**Apply colors in your components:**
```tsx
import { View, Text } from 'react-native';
Your app content;
```
**Switch themes:**
HeroUI Native automatically supports dark mode through [Uniwind](https://docs.uniwind.dev/theming/basics). The theme switches between light and dark variants based on system preferences or manual selection:
```tsx
import { Uniwind, useUniwind } from 'uniwind';
import { Button } from 'heroui-native';
function ThemeToggle() {
const { theme } = useUniwind();
return (
);
}
```
**Override colors:**
```css
/* global.css */
@layer theme {
@variant light {
/* Override any color variable */
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--success: oklch(0.65 0.15 155);
}
@variant dark {
--accent: oklch(0.65 0.25 270);
--success: oklch(0.75 0.12 155);
}
}
```
> **Note**: See [Colors](/docs/native/getting-started/colors) for the complete color palette and visual reference.
**Create your own theme:**
Create multiple themes using Uniwind's variant system. For complete custom theme documentation, see the [Uniwind Custom Themes Guide](https://docs.uniwind.dev/theming/custom-themes).
**Important:** All themes must define the same variables. See the [Default Theme](/docs/native/getting-started/colors#default-theme) section for a complete list of all required variables.
```css
/* global.css */
@layer theme {
:root {
@variant ocean-light {
/* Base Colors */
--background: oklch(0.95 0.02 230);
--foreground: oklch(0.25 0.04 230);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.98 0.01 230);
--surface-foreground: oklch(0.3 0.045 230);
--surface-secondary: oklch(0.96 0.012 230);
--surface-secondary-foreground: oklch(0.3 0.045 230);
--surface-tertiary: oklch(0.94 0.015 230);
--surface-tertiary-foreground: oklch(0.3 0.045 230);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: oklch(0.998 0.003 230);
--overlay-foreground: oklch(0.3 0.045 230);
--muted: oklch(0.55 0.035 230);
--default: oklch(0.94 0.018 230);
--default-foreground: oklch(0.4 0.05 230);
/* Accent */
--accent: oklch(0.6 0.2 230);
--accent-foreground: oklch(0.98 0.005 230);
/* Form Field Defaults - Colors */
--field-background: oklch(0.98 0.01 230);
--field-foreground: oklch(0.25 0.04 230);
--field-placeholder: var(--muted);
--field-border: transparent;
/* Status Colors */
--success: oklch(0.72 0.14 165);
--success-foreground: oklch(0.25 0.08 165);
--warning: oklch(0.78 0.12 85);
--warning-foreground: oklch(0.3 0.08 85);
--danger: oklch(0.68 0.18 15);
--danger-foreground: oklch(0.98 0.005 15);
/* Component Colors */
--segment: oklch(0.98 0.01 230);
--segment-foreground: oklch(0.25 0.04 230);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--separator: oklch(0.91 0.015 230);
--focus: var(--accent);
--link: oklch(0.62 0.17 230);
/* Shadows */
--surface-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
--overlay-shadow:
0 2px 8px 0 rgba(0, 0, 0, 0.02), 0 -6px 12px 0 rgba(0, 0, 0, 0.01),
0 14px 28px 0 rgba(0, 0, 0, 0.03);
--field-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
}
@variant ocean-dark {
/* Base Colors */
--background: oklch(0.15 0.04 230);
--foreground: oklch(0.94 0.01 230);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.2 0.048 230);
--surface-foreground: oklch(0.9 0.015 230);
--surface-secondary: oklch(0.24 0.046 230);
--surface-secondary-foreground: oklch(0.9 0.015 230);
--surface-tertiary: oklch(0.27 0.044 230);
--surface-tertiary-foreground: oklch(0.9 0.015 230);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: oklch(0.23 0.045 230);
--overlay-foreground: oklch(0.9 0.015 230);
--muted: oklch(0.5 0.04 230);
--default: oklch(0.25 0.05 230);
--default-foreground: oklch(0.88 0.018 230);
/* Accent */
--accent: oklch(0.72 0.21 230);
--accent-foreground: oklch(0.15 0.04 230);
/* Form Field Defaults - Colors */
--field-background: var(--default);
--field-foreground: var(--foreground);
--field-placeholder: var(--muted);
--field-border: transparent;
/* Status Colors */
--success: oklch(0.68 0.16 165);
--success-foreground: oklch(0.95 0.008 165);
--warning: oklch(0.75 0.14 90);
--warning-foreground: oklch(0.2 0.04 90);
--danger: oklch(0.65 0.2 20);
--danger-foreground: oklch(0.95 0.008 20);
/* Component Colors */
--segment: oklch(0.22 0.046 230);
--segment-foreground: oklch(0.9 0.015 230);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--separator: oklch(0.28 0.045 230);
--focus: var(--accent);
--link: oklch(0.75 0.18 230);
/* Shadows */
--surface-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--overlay-shadow: 0 0 1px 0 rgba(255, 255, 255, 0.3) inset;
--field-shadow: 0 0 0 0 transparent inset; /* Transparent shadow to allow ring utilities to work */
}
}
}
```
**Important:** When adding custom themes, you must register them in your Metro config:
```js
// metro.config.js
const { withUniwindConfig } = require('uniwind/metro');
const {
wrapWithReanimatedMetroConfig,
} = require('react-native-reanimated/metro-config');
const config = {
// ... your existing config
};
module.exports = withUniwindConfig(wrapWithReanimatedMetroConfig(config), {
cssEntryFile: './global.css',
dtsFile: './src/uniwind.d.ts',
extraThemes: ['ocean-light', 'ocean-dark'],
});
```
Apply themes in your app:
```tsx
import { Uniwind } from 'uniwind';
import { Button } from 'heroui-native';
function App() {
return (
);
}
```
## Adding Custom Colors
Add your own semantic colors to the theme:
```css
@layer theme {
@variant light {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
@variant dark {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
}
/* Make the color available to Tailwind */
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now use it in your components:
```tsx
import { View, Text } from 'react-native';
Info message;
```
## Custom Fonts
To use a custom font family in your app, you need to load the fonts and then override the font CSS variables.
### 1. Load Fonts in Your App
First, load your custom fonts (using Expo's `useFonts` hook for example):
```tsx
import { useFonts } from 'expo-font';
import { HeroUINativeProvider } from 'heroui-native';
import {
YourFont_400Regular,
YourFont_500Medium,
YourFont_600SemiBold,
} from '@expo-google-fonts/your-font';
export default function App() {
const [fontsLoaded] = useFonts({
YourFont_400Regular,
YourFont_500Medium,
YourFont_600SemiBold,
});
if (!fontsLoaded) {
return null; // Or return a loading screen
}
return {/* Your app content */};
}
```
### 2. Configure Font CSS Variables
After loading the fonts, override the font CSS variables in your `global.css` file:
```css
@theme {
--font-normal: 'YourFont-400Regular';
--font-medium: 'YourFont-500Medium';
--font-semibold: 'YourFont-600SemiBold';
}
```
**Note:** The font names in CSS variables should match the PostScript names of your loaded fonts. Check your font package documentation or use the font names exactly as they appear in your `useFonts` hook.
All HeroUI Native components automatically use these font variables, ensuring consistent typography throughout your app.
## Variables Reference
HeroUI defines three types of variables:
1. **Base Variables** — Non-changing values like `--white`, `--black`
2. **Theme Variables** — Colors that change between light/dark themes
3. **Calculated Variables** — Automatically generated hover (pressed) states and size variants
For a complete reference, see: [Colors Documentation](/docs/native/getting-started/colors), [Default Theme Variables](https://github.com/heroui-inc/heroui-native/blob/rc/src/styles/variables.css), [Shared Theme Utilities](https://github.com/heroui-inc/heroui-native/blob/rc/src/styles/theme.css)
**Calculated variables (Tailwind):**
We use Tailwind's `@theme` directive to automatically create calculated variables for hover (pressed) states and radius variants. These are defined in [theme.css](https://github.com/heroui-inc/heroui-native/blob/rc/src/styles/theme.css):
```css
@theme inline static {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);
--color-surface-foreground: var(--surface-foreground);
--color-surface-hover: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%);
--color-surface-secondary: var(--surface-secondary);
--color-surface-secondary-foreground: var(--surface-secondary-foreground);
--color-surface-tertiary: var(--surface-tertiary);
--color-surface-tertiary-foreground: var(--surface-tertiary-foreground);
--color-overlay: var(--overlay);
--color-overlay-foreground: var(--overlay-foreground);
--color-muted: var(--muted);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-segment: var(--segment);
--color-segment-foreground: var(--segment-foreground);
--color-border: var(--border);
--color-separator: var(--separator);
--color-focus: var(--focus);
--color-link: var(--link);
--color-default: var(--default);
--color-default-foreground: var(--default-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-danger: var(--danger);
--color-danger-foreground: var(--danger-foreground);
/* Form Field Tokens */
--color-field: var(--field-background, var(--default));
--color-field-foreground: var(--field-foreground, var(--foreground));
--color-field-placeholder: var(--field-placeholder, var(--muted));
--color-field-border: var(--field-border, var(--border));
--radius-field: var(--field-radius, var(--radius-xl));
--border-width-field: var(--field-border-width, var(--border-width));
--shadow-surface: var(--surface-shadow);
--shadow-overlay: var(--overlay-shadow);
--shadow-field: var(--field-shadow);
/* Calculated Variables */
/* Colors */
/* --- background shades --- */
--color-background-secondary: color-mix(in oklab, var(--background) 96%, var(--foreground) 4%);
--color-background-tertiary: color-mix(in oklab, var(--background) 92%, var(--foreground) 8%);
--color-background-inverse: var(--foreground);
/* ------------------------- */
--color-default-hover: color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%);
--color-accent-hover: color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%);
--color-success-hover: color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%);
--color-warning-hover: color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%);
--color-danger-hover: color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%);
/* Form Field Colors */
--color-field-hover: color-mix(in oklab, var(--field-background, var(--default)) 90%, var(--field-foreground, var(--foreground)) 2%);
--color-field-focus: var(--field-background, var(--default));
--color-field-border-hover: color-mix(in oklab, var(--field-border, var(--border)) 88%, var(--field-foreground, var(--foreground)) 10%);
--color-field-border-focus: color-mix(in oklab, var(--field-border, var(--border)) 74%, var(--field-foreground, var(--foreground)) 22%);
/* Soft Colors */
--color-accent-soft: color-mix(in oklab, var(--accent) 15%, transparent);
--color-accent-soft-foreground: var(--accent);
--color-accent-soft-hover: color-mix(in oklab, var(--accent) 20%, transparent);
--color-danger-soft: color-mix(in oklab, var(--danger) 15%, transparent);
--color-danger-soft-foreground: var(--danger);
--color-danger-soft-hover: color-mix(in oklab, var(--danger) 20%, transparent);
--color-warning-soft: color-mix(in oklab, var(--warning) 15%, transparent);
--color-warning-soft-foreground: var(--warning);
--color-warning-soft-hover: color-mix(in oklab, var(--warning) 20%, transparent);
--color-success-soft: color-mix(in oklab, var(--success) 15%, transparent);
--color-success-soft-foreground: var(--success);
--color-success-soft-hover: color-mix(in oklab, var(--success) 20%, transparent);
/* Separator Colors - Levels */
--color-separator-secondary: color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%);
--color-separator-tertiary: color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%);
/* Border Colors - Levels (progressive contrast: default → secondary → tertiary) */
/* Light mode: lighter → darker | Dark mode: darker → lighter */
--color-border-secondary: color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%);
--color-border-tertiary: color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%);
/* Radius and default sizes - defaults can change by just changing the --radius */
--radius-xs: calc(var(--radius) * 0.25); /* 0.125rem (2px) */
--radius-sm: calc(var(--radius) * 0.5); /* 0.25rem (4px) */
--radius-md: calc(var(--radius) * 0.75); /* 0.375rem (6px) */
--radius-lg: calc(var(--radius) * 1); /* 0.5rem (8px) */
--radius-xl: calc(var(--radius) * 1.5); /* 0.75rem (12px) */
--radius-2xl: calc(var(--radius) * 2); /* 1rem (16px) */
--radius-3xl: calc(var(--radius) * 3); /* 1.5rem (24px) */
--radius-4xl: calc(var(--radius) * 4); /* 2rem (32px) */
}
```
Form controls now rely on the `--field-*` variables and their calculated hover/focus variants. Update them in your theme to restyle inputs, checkboxes, radios, and OTP slots without impacting surfaces like buttons or cards.
## Resources
* [Colors Documentation](/docs/native/getting-started/colors)
* [Styling Guide](/docs/native/getting-started/styling)
* [Tailwind CSS v4 Theming](https://tailwindcss.com/docs/theme)
* [OKLCH Color Tool](https://oklch.com)
# Design Principles
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/design-principles
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(overview)/design-principles.mdx
> Core principles that guide HeroUI v3's design and development
HeroUI Native follows 9 core principles that prioritize clarity, accessibility, customization, and developer experience.
## Core Principles
### 1. Semantic Intent Over Visual Style
Use semantic naming (primary, secondary, tertiary) instead of visual descriptions (solid, flat, bordered). Inspired by [Uber's Base design system](https://base.uber.com/6d2425e9f/p/756216-button), variants follow a clear hierarchy:
```tsx
// ✅ Semantic variants communicate hierarchy
```
| Variant | Purpose | Usage |
| ------------- | --------------------------------- | ---------------- |
| **Primary** | Main action to move forward | 1 per context |
| **Secondary** | Alternative actions | Multiple allowed |
| **Tertiary** | Dismissive actions (cancel, skip) | Sparingly |
| **Danger** | Destructive actions | When needed |
### 2. Accessibility as Foundation
Accessibility follows mobile development best practices with proper touch accessibility, focus management, and screen reader support built into every component. All components include proper accessibility labels and semantic structure for VoiceOver (iOS) and TalkBack (Android).
```tsx
import { Tabs } from 'heroui-native';
ProfileSecurityContentContent
```
### 3. Composition Over Configuration
Compound components let you rearrange, customize, or omit parts as needed. Use dot notation to compose components exactly as you need them.
```tsx
// Compose parts to build exactly what you need
import { Accordion } from 'heroui-native';
Question Text
Answer content
```
### 4. Progressive Disclosure
Start simple, add complexity only when needed. Components work with minimal props and scale up as requirements grow.
```tsx
import { Button, Spinner } from 'heroui-native';
import { Feather } from '@expo/vector-icons';
// Level 1: Minimal
// Level 2: Enhanced
// Level 3: Advanced
```
### 5. Predictable Behavior
Consistent patterns across all components: sizes (`sm`, `md`, `lg`), variants, and className support. Same API, same behavior.
```tsx
import { Button, Chip, Avatar } from 'heroui-native';
// All components follow the same patterns
SuccessJD
```
### 6. Type Safety First
Full TypeScript support with IntelliSense, auto-completion, and compile-time error detection. Extend types for custom components.
```tsx
import type { ButtonRootProps } from 'heroui-native';
// Type-safe props and event handlers
// Extend types for custom components
interface CustomButtonProps extends Omit {
intent: 'save' | 'cancel' | 'delete';
}
```
### 7. Developer Experience Excellence
Clear APIs, descriptive errors, IntelliSense and AI-friendly markdown docs.
### 8. Complete Customization
Beautiful defaults out-of-the-box. Transform the entire look with CSS variables through [Uniwind's theming system](https://docs.uniwind.dev/theming/basics). Every slot is customizable.
```css
/* Custom colors using Uniwind's theme layer */
@layer theme {
@variant light {
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--background: oklch(0.98 0 0); /* Custom background */
}
@variant dark {
--accent: oklch(0.65 0.25 270);
--background: oklch(0.15 0 0);
}
}
/* Radius customization */
@theme {
--radius: 0.75rem; /* Increase for rounder components */
}
```
### 9. Open and Extensible
Wrap, extend, and customize components to match your needs. Create custom wrappers or apply custom styles using className.
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
// Custom wrapper component
interface CTAButtonProps extends Omit {
intent?: 'primary-cta' | 'secondary-cta' | 'minimal';
}
const CTAButton = ({
intent = 'primary-cta',
children,
...props
}: CTAButtonProps) => {
const variantMap = {
'primary-cta': 'primary',
'secondary-cta': 'secondary',
'minimal': 'ghost'
} as const;
return (
);
};
// Usage
Get StartedLearn More
```
**Extend with Tailwind Variants:**
```tsx
import { Button } from 'heroui-native';
import { tv } from 'tailwind-variants';
// Extend button styles with custom variants
const myButtonVariants = tv({
base: 'px-4 py-2 rounded-lg',
variants: {
variant: {
'primary-cta': 'bg-accent px-8 py-4 shadow-lg',
'secondary-cta': 'border-2 border-accent px-6 py-3',
}
},
defaultVariants: {
variant: 'primary-cta',
}
});
// Label variants for text colors (must be applied to Button.Label)
const myLabelVariants = tv({
base: '',
variants: {
variant: {
'primary-cta': 'text-accent-foreground',
'secondary-cta': 'text-accent',
}
},
defaultVariants: {
variant: 'primary-cta',
}
});
// Use the custom variants
function CustomButton({ variant, className, labelClassName, children, ...props }) {
return (
);
}
// Usage
Get StartedLearn More
```
# Quick Start
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/quick-start
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(overview)/quick-start.mdx
> Get started with HeroUI Native in minutes
## Getting Started
### 1. Install HeroUI Native
```bash
npm install heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
### 2. Install Mandatory Peer Dependencies
```bash
npm install react-native-screens@^4.16.0 react-native-reanimated@^4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@^0.5.1 react-native-safe-area-context@^5.6.0 react-native-svg@^15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5.2.8
```
```bash
pnpm add react-native-screens@^4.16.0 react-native-reanimated@^4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@^0.5.1 react-native-safe-area-context@^5.6.0 react-native-svg@^15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5.2.8
```
```bash
yarn add react-native-screens@^4.16.0 react-native-reanimated@^4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@^0.5.1 react-native-safe-area-context@^5.6.0 react-native-svg@^15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5.2.8
```
```bash
bun add react-native-screens@^4.16.0 react-native-reanimated@^4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@^0.5.1 react-native-safe-area-context@^5.6.0 react-native-svg@^15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5.2.8
```
It's recommended to use the exact versions specified above to avoid compatibility issues. Version mismatches may cause unexpected bugs.
### 3. Set Up Uniwind
Follow the [Uniwind installation guide](https://docs.uniwind.dev/quickstart) to set up Tailwind CSS for React Native.
If you're migrating from NativeWind, see the [migration guide](https://docs.uniwind.dev/migration-from-nativewind).
### 4. Configure global.css
Inside your `global.css` file add the following imports:
```css
@import 'tailwindcss';
@import 'uniwind';
@import 'heroui-native/styles';
/* Path to the heroui-native lib inside node_modules relative to global.css */
/* Examples:
* - If global.css is at project root: ./node_modules/heroui-native/lib
* - If global.css is in app/: ../node_modules/heroui-native/lib
* - If global.css is in src/styles/: ../../node_modules/heroui-native/lib
*/
@source './node_modules/heroui-native/lib';
```
### 5. Wrap Your App with Provider
Wrap your application with `HeroUINativeProvider`. You must wrap it with `GestureHandlerRootView`:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
{/* Your app content */}
);
}
```
> **Note**: For advanced configuration options including text props, animation settings, and toast configuration, see the [Provider documentation](/docs/native/getting-started/provider).
### 6. Use Your First Component
```tsx
import { Button } from 'heroui-native';
import { View } from 'react-native';
export default function MyComponent() {
return (
);
}
```
### 7. Reduce Bundle Size with Granular Exports
If you want to reduce bundle size and import only the components you need, our library provides granular exports for each component:
```tsx
// 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 component
* `heroui-native/provider-raw` - Lightweight provider (keeps bare minimum to start)
* `heroui-native/[component-name]` - Individual components
* `heroui-native/portal` - Portal utilities
* `heroui-native/toast` - Toast provider and utilities
* `heroui-native/utils` - Utility functions
* `heroui-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.
> **Tip**: For even more control over your bundle, consider using [`HeroUINativeProviderRaw`](/docs/native/getting-started/provider#raw-provider) — a lightweight provider that excludes `ToastProvider` and `PortalHost`, making dependencies like `react-native-screens`, `@gorhom/bottom-sheet`, and `react-native-svg` fully optional.
## What's Next?
* [HeroUI Native Provider](/docs/native/getting-started/provider)
* [Styling Guide](/docs/native/getting-started/styling)
* [Theming Documentation](/docs/native/getting-started/theming)
## Running on Web (Expo)
HeroUI Native is currently not recommended for web use. We are focusing on mobile platforms (iOS and Android) at this time. For web development, please use [HeroUI React](/docs/react/getting-started/quick-start) instead.
# Agent Skills
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/agent-skills
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/agent-skills.mdx
> Enable AI assistants to build mobile UIs with HeroUI Native components
HeroUI Native Skills give your AI assistant comprehensive knowledge of HeroUI Native components, patterns, and best practices for React Native development.
### Installation
```bash
curl -fsSL https://v3.heroui.com/install | bash -s heroui-native
```
Or using the skills package:
```bash
npx skills add heroui-inc/heroui
```
Support Claude Code, Cursor, OpenCode and more.
### Usage
Skills are **automatically discovered** by your AI assistant, or call it directly using `/heroui-native` command.
Simply ask your AI assistant to:
* Build mobile components using HeroUI Native
* Create screens with HeroUI Native components
* Customize themes and styles
* Access component documentation
For more complex use cases, use the [MCP Server](/docs/native/getting-started/mcp-server) which provides real-time access to component documentation and source code.
### What's Included
* HeroUI Native installation guide
* All HeroUI Native components with props, examples, and usage patterns
* Theming and styling guidelines with Uniwind
* Design principles and composition patterns
### Structure
```
skills/heroui-native/
├── SKILL.md # Main skill documentation
├── LICENSE.txt # MIT license
└── scripts/ # Utility scripts
├── list_components.mjs
├── get_component_docs.mjs
├── get_theme.mjs
└── get_docs.mjs
```
### Related Documentation
* [Agent Skills Specification](https://agentskills.io/home) - Learn about the Agent Skills format
* [Claude Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) - Claude's Skills documentation
* [Cursor Skills](https://cursor.com/docs/context/skills) - Using Skills in Cursor
* [OpenCode Skills](https://opencode.ai/docs/skills) - Using Skills in OpenCode
# AGENTS.md
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/agents-md
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/agents-md.mdx
> Download HeroUI Native documentation for AI coding agents
Download HeroUI Native documentation directly into your project for AI assistants to reference.
**Note:** The `agents-md` command is specifically for HeroUI React v3 and HeroUI Native. Other CLI commands (like `add`, `init`, `upgrade`, etc.) are for HeroUI v2 (for now).
### Usage
```bash
npx heroui-cli@latest agents-md --native
```
Or specify output file:
```bash
npx heroui-cli@latest agents-md --native --output AGENTS.md
```
### What It Does
* Downloads latest HeroUI Native docs to `.heroui-docs/native/`
* Generates an index in `AGENTS.md` or `CLAUDE.md`
* Adds `.heroui-docs/` to `.gitignore` automatically
### Options
* `--native` - Download Native docs only
* `--output ` - Target file(s) (e.g., `AGENTS.md` or `AGENTS.md CLAUDE.md`)
* `--ssh` - Use SSH for git clone
### Requirements
* Tailwind CSS >= v4 (via Uniwind)
### Related Documentation
* [AGENTS.md](https://agents.md/) - Learn about the AGENTS.md format for coding agents
* [CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md) - Claude equivalent of AGENTS.md
* [AGENTS.md vs Skills](https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals) - AGENTS.md performance
# LLMs.txt
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/llms-txt
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/llms-txt.mdx
> Enable AI assistants like Claude, Cursor, and Windsurf to understand HeroUI Native
We provide [LLMs.txt](https://llmstxt.org/) files to make HeroUI Native documentation accessible to AI coding assistants.
## Available Files
**Core documentation:**
* [/native/llms.txt](/native/llms.txt) — Quick reference index for Native documentation
* [/native/llms-full.txt](/native/llms-full.txt) — Complete HeroUI Native documentation
**For limited context windows:**
* [/native/llms-components.txt](/native/llms-components.txt) — Component documentation only
* [/native/llms-patterns.txt](/native/llms-patterns.txt) — Common patterns and recipes
**All platforms:**
* [/llms.txt](/llms.txt) — Quick reference index (React + Native)
* [/llms-full.txt](/llms-full.txt) — Complete documentation (React + Native)
* [/llms-components.txt](/llms-components.txt) — All component documentation
* [/llms-patterns.txt](/llms-patterns.txt) — All patterns and recipes
## Integration
**Claude Code:** Tell Claude to reference the documentation:
```
Use HeroUI Native documentation from https://v3.heroui.com/native/llms.txt
```
Or add to your project's `.claude` file for automatic loading.
**Cursor:** Use the `@Docs` feature:
```
@Docs https://v3.heroui.com/native/llms-full.txt
```
[Learn more](https://docs.cursor.com/context/@-symbols/@-docs)
**Windsurf:** Add to your `.windsurfrules` file:
```
#docs https://v3.heroui.com/native/llms-full.txt
```
[Learn more](https://docs.codeium.com/windsurf/memories#memories-and-rules)
**Other AI tools:** Most AI assistants can reference documentation by URL. Simply provide:
```
https://v3.heroui.com/native/llms.txt
```
**For component-specific documentation:**
```
https://v3.heroui.com/native/llms-components.txt
```
**For patterns and best practices:**
```
https://v3.heroui.com/native/llms-patterns.txt
```
## Contributing
Found an issue with AI-generated code? Help us improve our LLMs.txt files on [GitHub](https://github.com/heroui-inc/heroui).
# MCP Server
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/mcp-server
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/mcp-server.mdx
> Access HeroUI Native documentation directly in your AI assistant
The HeroUI MCP Server gives AI assistants direct access to HeroUI Native component documentation, making it easier to build with HeroUI in AI-powered development environments.
The MCP server currently supports **heroui-native** and [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio). Published at `@heroui/native-mcp` on npm. View the source code on [GitHub](https://github.com/heroui-inc/heroui-mcp).
As we add more components to HeroUI Native, they'll be available in the MCP server too.
## Quick Setup
**Cursor:**
Or manually add to **Cursor Settings** → **Tools** → **MCP Servers**:
```json title=".cursor/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
Alternatively, add the following to your `~/.cursor/mcp.json` file. To learn more, see the [Cursor documentation](https://cursor.com/docs/context/mcp).
**Claude Code:** Run this command in your terminal:
```bash
claude mcp add heroui-native -- npx -y @heroui/native-mcp@latest
```
Or manually add to your project's `.mcp.json` file:
```json title=".mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, restart Claude Code and run `/mcp` to see the HeroUI MCP server in the list. If you see **Connected**, you're ready to use it.
See the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp) for more details.
**Windsurf:** Add the HeroUI server to your project's `.windsurf/mcp.json` configuration file:
```json title=".windsurf/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, restart Windsurf to activate the MCP server.
See the [Windsurf MCP documentation](https://docs.windsurf.com/windsurf/cascade/mcp) for more details.
**Zed:** Add the HeroUI server to your `settings.json` configuration file. Open settings via Command Palette (`zed: open settings`) or use `Cmd-,` (Mac) / `Ctrl-,` (Linux):
```json title="settings.json"
{
"context_servers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"],
"env": {}
}
}
}
```
After adding the configuration, restart Zed and open the Agent Panel settings view. Check that the indicator dot next to the heroui-native server is green with "Server is active" tooltip.
See the [Zed MCP documentation](https://zed.dev/docs/ai/mcp) for more details.
**VS Code:** To configure MCP in VS Code with GitHub Copilot, add the HeroUI server to your project's `.vscode/mcp.json` configuration file:
```json title=".vscode/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the heroui-native server.
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) for more details.
## Usage
Once configured, ask your AI assistant questions like:
* "Help me install HeroUI Native in my Expo app"
* "Show me all HeroUI Native components"
* "What props does the Button component have?"
* "Give me an example of using the Card component"
* "What are the theme variables for dark mode?"
### Automatic Updates
The MCP server can help you upgrade to the latest HeroUI Native version:
```bash
"Hey Cursor, update HeroUI Native to the latest version"
```
Your AI assistant will automatically:
* Compare your current version with the latest release
* Review the changelog for breaking changes
* Apply the necessary code updates to your project
This works for any version upgrade, whether you're updating to the latest alpha, beta, or stable release.
## Available Tools
The MCP server provides these tools to AI assistants:
| Tool | Description |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_components` | List all available HeroUI Native components |
| `get_component_docs` | Get complete component documentation including anatomy, props, examples, and usage patterns for one or more components |
| `get_theme_variables` | Access theme variables for colors, typography, spacing with light/dark mode support |
| `get_docs` | Browse the full HeroUI Native documentation including guides and principles (use path `/docs/native/getting-started/quick-start` for installation instructions) |
## Troubleshooting
**Requirements:** Node.js 22 or higher. The package will be automatically downloaded when using `npx`.
**Need help?** [GitHub Issues](https://github.com/heroui-inc/heroui-mcp/issues) | [Discord Community](https://discord.gg/heroui)
## Links
* [npm Package](https://www.npmjs.com/package/@heroui/native-mcp)
* [GitHub Repository](https://github.com/heroui-inc/heroui-mcp)
* [Contributing Guide](https://github.com/heroui-inc/heroui-mcp/blob/main/CONTRIBUTING.md)
# ButtonGroup
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/button-group
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(buttons)/button-group.mdx
> Group related buttons together with consistent styling and spacing
## Import
```tsx
import { ButtonGroup } from '@heroui/react';
```
### Usage
```tsx
import {
ChevronDown,
ChevronLeft,
ChevronRight,
CodeFork,
Ellipsis,
Picture,
Pin,
QrCode,
Star,
TextAlignCenter,
TextAlignJustify,
TextAlignLeft,
TextAlignRight,
ThumbsDown,
ThumbsUp,
Video,
} from "@gravity-ui/icons";
import {Button, ButtonGroup, Chip, Description, Dropdown, Label} from "@heroui/react";
export function Basic() {
return (
{/* Single button with dropdown */}
All commits from this branch will be added to the base branch
The 14 commits from this branch will be combined into one commit in the base
branch
The 14 commits from this branch will be rebased and added to the base branch
{/* Individual buttons */}
{/* Previous/Next Button Group */}
{/* Content Selection Button Group */}
{/* Text Alignment Button Group */}
{/* Icon-Only Alignment Button Group */}
);
}
```
### Anatomy
```tsx
import { ButtonGroup, Button } from '@heroui/react';
export default () => (
)
```
> **ButtonGroup** wraps multiple Button components together, applying consistent styling, spacing, and automatic border radius handling. It uses React Context to pass `size`, `variant`, and `isDisabled` props to all child buttons.
### Variants
```tsx
import {Button, ButtonGroup} from "@heroui/react";
export function Variants() {
return (
Primary
Secondary
Tertiary
Outline
Ghost
Danger
);
}
```
### Sizes
```tsx
import {Button, ButtonGroup} from "@heroui/react";
export function Sizes() {
return (
Small
Medium (default)
Large
);
}
```
### With Icons
```tsx
import {Globe, Plus, TrashBin} from "@gravity-ui/icons";
import {Button, ButtonGroup} from "@heroui/react";
export function WithIcons() {
return (
With icons
Icon only buttons
);
}
```
### Full Width
```tsx
import {TextAlignCenter, TextAlignLeft, TextAlignRight} from "@gravity-ui/icons";
import {Button, ButtonGroup} from "@heroui/react";
export function FullWidth() {
return (
);
}
```
### Disabled State
```tsx
import {Button, ButtonGroup} from "@heroui/react";
export function Disabled() {
return (
All buttons disabled
Group disabled, but one button overrides
);
}
```
### Without Separator
```tsx
import {Button, ButtonGroup} from "@heroui/react";
export function WithoutSeparator() {
return (
);
}
```
## Related Components
* **Button**: Allows a user to perform an action
* **Dropdown**: Context menu with actions and options
* **Chip**: Compact elements for tags and filters
## Styling
### Passing Tailwind CSS classes
```tsx
import { ButtonGroup } from '@heroui/react';
function CustomButtonGroup() {
return (
);
}
```
### Customizing the component classes
To customize the ButtonGroup component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.button-group {
@apply gap-2 rounded-lg;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ButtonGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/button-group.css)):
#### Base Classes
* `.button-group` - Base button group container
The ButtonGroup component automatically applies border radius to buttons:
* First button gets rounded left/start edge
* Last button gets rounded right/end edge
* Middle buttons have no border radius
* Single button gets full border radius on all edges
Separators are automatically added between buttons using a pseudo-element (`:before`) on buttons that are not the first child.
## API Reference
### ButtonGroup Props
| Prop | Type | Default | Description |
| --------------- | --------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------- |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'ghost' \| 'danger'` | - | Visual style variant applied to all buttons in the group |
| `size` | `'sm' \| 'md' \| 'lg'` | - | Size applied to all buttons in the group |
| `fullWidth` | `boolean` | `false` | Whether the button group should take full width of its container |
| `isDisabled` | `boolean` | `false` | Whether all buttons in the group are disabled (can be overridden on individual buttons) |
| `hideSeparator` | `boolean` | `false` | Hide separator lines between buttons |
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Button components to group together |
### Notes
* ButtonGroup uses React Context to pass `size`, `variant`, and `isDisabled` props to all child Button components
* **Only direct child buttons receive the ButtonGroup props** - Buttons nested inside other components (like Modal, Dropdown, etc.) will not inherit the group's props even if they are descendants of the ButtonGroup
* Individual Button components can override the group's `isDisabled` prop by setting `isDisabled={false}`
* The component automatically handles border radius and separators between buttons
* Buttons in a group have their active/pressed scale transform removed for a more cohesive appearance
# Button
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(buttons)/button.mdx
> A clickable button component with multiple variants and states
## Import
```tsx
import { Button } from '@heroui/react';
```
### Usage
```tsx
"use client";
import {Button} from "@heroui/react";
export function Basic() {
return ;
}
```
### Variants
```tsx
import {Button} from "@heroui/react";
export function Variants() {
return (
);
}
```
### With Icons
```tsx
import {Envelope, Globe, Plus, TrashBin} from "@gravity-ui/icons";
import {Button} from "@heroui/react";
export function WithIcons() {
return (
);
}
```
### Icon Only
```tsx
import {Ellipsis, Gear, TrashBin} from "@gravity-ui/icons";
import {Button} from "@heroui/react";
export function IconOnly() {
return (
);
}
```
### Loading
```tsx
"use client";
import {Button, Spinner} from "@heroui/react";
import React from "react";
export function Loading() {
return (
);
}
```
### Loading State
```tsx
"use client";
import {Paperclip} from "@gravity-ui/icons";
import {Button, Spinner} from "@heroui/react";
import React, {useState} from "react";
export function LoadingState() {
const [isLoading, setLoading] = useState(false);
const handlePress = () => {
setLoading(true);
setTimeout(() => setLoading(false), 2000);
};
return (
);
}
```
### Sizes
```tsx
import {Button} from "@heroui/react";
export function Sizes() {
return (
);
}
```
### Full Width
```tsx
import {Plus} from "@gravity-ui/icons";
import {Button} from "@heroui/react";
export function FullWidth() {
return (
);
}
```
### Disabled State
```tsx
import {Button} from "@heroui/react";
export function Disabled() {
return (
);
}
```
### Social Buttons
```tsx
import {Button} from "@heroui/react";
import {Icon} from "@iconify/react";
export function Social() {
return (
);
}
```
### Custom Render Function
```tsx
"use client";
import {Button} from "@heroui/react";
export function CustomRenderFunction() {
return (
);
}
```
## Related Components
* **Popover**: Displays content in context with a trigger
* **Tooltip**: Contextual information on hover or focus
* **Form**: Form validation and submission handling
## Styling
### Passing Tailwind CSS classes
```tsx
import { Button } from '@heroui/react';
function CustomButton() {
return (
Purple Button
);
}
```
### Customizing the component classes
To customize the Button component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.button {
@apply bg-purple-500 text-white hover:bg-purple-600;
}
.button--icon-only {
@apply rounded-lg bg-blue-500;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### Adding custom variants
You can extend HeroUI components by wrapping them and adding your own custom variants.
```tsx
import type {ButtonProps} from "@heroui/react";
import type {VariantProps} from "tailwind-variants";
import {Button, buttonVariants} from "@heroui/react";
import {tv} from "tailwind-variants";
const myButtonVariants = tv({
base: "text-md font-semibold shadow-md text-shadow-lg data-[pending=true]:opacity-40",
defaultVariants: {
radius: "full",
variant: "primary",
},
extend: buttonVariants,
variants: {
radius: {
full: "rounded-full",
lg: "rounded-lg",
md: "rounded-md",
sm: "rounded-sm",
},
size: {
lg: "h-12 px-8",
md: "h-11 px-6",
sm: "h-10 px-4",
xl: "h-13 px-10",
},
variant: {
primary: "text-white dark:bg-white/10 dark:text-white dark:hover:bg-white/15",
},
},
});
type MyButtonVariants = VariantProps;
export type MyButtonProps = Omit &
MyButtonVariants & {className?: string};
function CustomButton({className, radius, variant, ...props}: MyButtonProps) {
return ;
}
export function CustomVariants() {
return Custom Button;
}
```
### Adding Ripple Effect
The Button component supports ripple effects through composition, allowing you to nest ripple components as children. This example uses [m3-ripple](https://github.com/saltyaom/m3-ripple).
```tsx
"use client";
import {Button} from "@heroui/react";
import {Ripple} from "m3-ripple";
import "m3-ripple/ripple.css";
export function RippleEffect() {
return (
Click me
);
}
```
### CSS Classes
The Button component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/button.css)):
#### Base & Size Classes
* `.button` - Base button styles
* `.button--sm` - Small size variant
* `.button--md` - Medium size variant
* `.button--lg` - Large size variant
#### Variant Classes
* `.button--primary`
* `.button--secondary`
* `.button--tertiary`
* `.button--outline`
* `.button--ghost`
* `.button--danger`
#### Modifier Classes
* `.button--icon-only`
* `.button--icon-only.button--sm`
* `.button--icon-only.button--lg`
### Interactive States
The button supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]`
* **Active/Pressed**: `:active` or `[data-pressed="true"]` (includes scale transform)
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]` (shows focus ring)
* **Disabled**: `:disabled` or `[aria-disabled="true"]` (reduced opacity, no pointer events)
* **Pending**: `[data-pending]` (no pointer events during loading)
## API Reference
### Button Props
| Prop | Type | Default | Description |
| ------------ | ---------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
| `variant` | `'primary' \| 'secondary' \| 'tertiary' \| 'outline' \| 'ghost' \| 'danger'` | `'primary'` | Visual style variant |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size of the button |
| `fullWidth` | `boolean` | `false` | Whether the button should take full width of its container |
| `isDisabled` | `boolean` | `false` | Whether the button is disabled |
| `isPending` | `boolean` | `false` | Whether the button is in a loading state |
| `isIconOnly` | `boolean` | `false` | Whether the button contains only an icon |
| `onPress` | `(e: PressEvent) => void` | - | Handler called when the button is pressed |
| `children` | `React.ReactNode \| (values: ButtonRenderProps) => React.ReactNode` | - | Button content or render prop |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ButtonRenderProps
When using the render prop pattern, these values are provided:
| Prop | Type | Description |
| ---------------- | --------- | ---------------------------------------------- |
| `isPending` | `boolean` | Whether the button is in a loading state |
| `isPressed` | `boolean` | Whether the button is currently pressed |
| `isHovered` | `boolean` | Whether the button is hovered |
| `isFocused` | `boolean` | Whether the button is focused |
| `isFocusVisible` | `boolean` | Whether the button should show focus indicator |
| `isDisabled` | `boolean` | Whether the button is disabled |
# CloseButton
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/close-button
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(buttons)/close-button.mdx
> Button component for closing dialogs, modals, or dismissing content
## Import
```tsx
import { CloseButton } from "@heroui/react";
```
### Usage
```tsx
import {CloseButton} from "@heroui/react";
export function Default() {
return ;
}
```
### With Custom Icon
```tsx
import {CircleXmark, Xmark} from "@gravity-ui/icons";
import {CloseButton} from "@heroui/react";
export function WithCustomIcon() {
return (
Custom Icon
Alternative Icon
);
}
```
### Interactive
```tsx
"use client";
import {CloseButton} from "@heroui/react";
import {useState} from "react";
export function Interactive() {
const [count, setCount] = useState(0);
return (
setCount(count + 1)}
/>
Clicked: {count} times
);
}
```
## Related Components
* **Alert**: Display important messages and notifications
* **AlertDialog**: Critical confirmations requiring user attention
* **Chip**: Compact elements for tags and filters
## Styling
### Passing Tailwind CSS classes
```tsx
import {CloseButton} from "@heroui/react";
function CustomCloseButton() {
return Close;
}
```
### Customizing the component classes
To customize the CloseButton component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.close-button {
@apply bg-red-100 text-red-800 hover:bg-red-200;
}
.close-button--custom {
@apply rounded-full border-2 border-red-300;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The CloseButton component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/close-button.css)):
#### Base Classes
* `.close-button` - Base component styles
#### Variant Classes
* `.close-button--default` - Default variant
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]`
* **Active/Pressed**: `:active` or `[data-pressed="true"]`
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]`
* **Disabled**: `:disabled` or `[aria-disabled="true"]`
## API Reference
### CloseButton Props
| Prop | Type | Default | Description |
| ------------ | ----------------------- | --------------- | ------------------------------------------- |
| `variant` | `"default"` | `"default"` | Visual variant of the button |
| `children` | `ReactNode \| function` | `` | Content to display (defaults to close icon) |
| `onPress` | `() => void` | - | Handler called when the button is pressed |
| `isDisabled` | `boolean` | `false` | Whether the button is disabled |
### React Aria Button Props
CloseButton extends all React Aria Button props. Common props include:
| Prop | Type | Description |
| ------------------ | -------- | --------------------------------------- |
| `aria-label` | `string` | Accessible label for screen readers |
| `aria-labelledby` | `string` | ID of element that labels the button |
| `aria-describedby` | `string` | ID of element that describes the button |
### RenderProps
When using the render prop pattern, these values are provided:
| Prop | Type | Description |
| ------------ | --------- | ------------------------------ |
| `isHovered` | `boolean` | Whether the button is hovered |
| `isPressed` | `boolean` | Whether the button is pressed |
| `isFocused` | `boolean` | Whether the button is focused |
| `isDisabled` | `boolean` | Whether the button is disabled |
# Dropdown
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/dropdown
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(collections)/dropdown.mdx
> A dropdown displays a list of actions or options that a user can choose
## Import
```tsx
import { Dropdown } from '@heroui/react';
```
### Usage
```tsx
"use client";
import {Button, Dropdown, Label} from "@heroui/react";
export function Default() {
return (
Actions
console.log(`Selected: ${key}`)}>
);
}
```
### Anatomy
Import the Dropdown component and access all parts using dot notation.
```tsx
import { Dropdown, Button, Label, Description, Header, Kbd, Separator } from '@heroui/react';
export default () => (
)
```
### With Single Selection
```tsx
"use client";
import type {Selection} from "@heroui/react";
import {Button, Dropdown, Header, Label} from "@heroui/react";
import {useState} from "react";
export function WithSingleSelection() {
const [selected, setSelected] = useState(new Set(["apple"]));
return (
Fruit
Select a fruit
);
}
```
### Single With Custom Indicator
```tsx
"use client";
import type {Selection} from "@heroui/react";
import {Button, Dropdown, Header, Label} from "@heroui/react";
import {useState} from "react";
export function SingleWithCustomIndicator() {
const [selected, setSelected] = useState(new Set(["apple"]));
const CustomCheckmarkIcon = (
);
return (
Fruits
Select a fruit
{({isSelected}) => (isSelected ? CustomCheckmarkIcon : null)}
{({isSelected}) => (isSelected ? CustomCheckmarkIcon : null)}
{({isSelected}) => (isSelected ? CustomCheckmarkIcon : null)}
{({isSelected}) => (isSelected ? CustomCheckmarkIcon : null)}
{({isSelected}) => (isSelected ? CustomCheckmarkIcon : null)}
);
}
```
### With Multiple Selection
```tsx
"use client";
import type {Selection} from "@heroui/react";
import {Button, Dropdown, Header, Label} from "@heroui/react";
import {useState} from "react";
export function WithMultipleSelection() {
const [selected, setSelected] = useState(new Set(["apple"]));
return (
Preferred Fruits
Select a fruit
);
}
```
### With Section Level Selection
```tsx
"use client";
import type {Selection} from "@heroui/react";
import {Button, Dropdown, Header, Kbd, Label, Separator} from "@heroui/react";
import {useState} from "react";
export function WithSectionLevelSelection() {
const [textStyles, setTextStyles] = useState(new Set(["bold", "italic"]));
const [textAlignment, setTextAlignment] = useState(new Set(["left"]));
return (
Styles
ActionsXCUText StyleBIUText AlignmentAHD
);
}
```
### With Keyboard Shortcuts
```tsx
"use client";
import {Button, Dropdown, Kbd, Label} from "@heroui/react";
export function WithKeyboardShortcuts() {
return (
Actions
console.log(`Selected: ${key}`)}>
NOSD
);
}
```
### With Icons
```tsx
"use client";
import {FloppyDisk, FolderOpen, SquarePlus, TrashBin} from "@gravity-ui/icons";
import {Button, Dropdown, Kbd, Label} from "@heroui/react";
export function WithIcons() {
return (
Actions
console.log(`Selected: ${key}`)}>
NOSD
);
}
```
### Long Press Trigger
```tsx
import {Button, Dropdown, Label} from "@heroui/react";
export function LongPressTrigger() {
return (
Long Press
);
}
```
### With Descriptions
```tsx
"use client";
import {FloppyDisk, FolderOpen, SquarePlus, TrashBin} from "@gravity-ui/icons";
import {Button, Description, Dropdown, Kbd, Label} from "@heroui/react";
export function WithDescriptions() {
return (
Actions
console.log(`Selected: ${key}`)}>
);
}
```
### Anatomy
Import the ListBox component and access all parts using dot notation.
```tsx
import { ListBox, Label, Description, Header } from '@heroui/react';
export default () => (
)
```
### With Sections
```tsx
"use client";
import {Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons";
import {Description, Header, Kbd, Label, ListBox, Separator, Surface} from "@heroui/react";
export function WithSections() {
return (
alert(`Selected item: ${key}`)}
>
Actions
Create a new file
N
Make changes
EDanger zone
Move to trash
D
);
}
```
### Multi Select
```tsx
import {Avatar, Description, Label, ListBox, Surface} from "@heroui/react";
export function MultiSelect() {
return (
B
bob@heroui.com
F
fred@heroui.com
M
martha@heroui.com
);
}
```
### With Disabled Items
```tsx
"use client";
import {Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons";
import {Description, Header, Kbd, Label, ListBox, Separator, Surface} from "@heroui/react";
export function WithDisabledItems() {
return (
alert(`Selected item: ${key}`)}
>
Actions
Create a new file
N
Make changes
EDanger zone
Move to trash
D
);
}
```
### Custom Check Icon
```tsx
"use client";
import {Check} from "@gravity-ui/icons";
import {Avatar, Description, Label, ListBox, Surface} from "@heroui/react";
export function CustomCheckIcon() {
return (
B
bob@heroui.com
{({isSelected}) => (isSelected ? : null)}
F
fred@heroui.com
{({isSelected}) => (isSelected ? : null)}
M
martha@heroui.com
{({isSelected}) => (isSelected ? : null)}
);
}
```
### Controlled
```tsx
"use client";
import type {Selection} from "@heroui/react";
import {Check} from "@gravity-ui/icons";
import {Avatar, Description, Label, ListBox, Surface} from "@heroui/react";
import {useState} from "react";
export function Controlled() {
const [selected, setSelected] = useState(new Set(["1"]));
const selectedItems = Array.from(selected);
return (
list.setSelectedKeys(keys)}
>
No team members}
>
{(user) => (
{user.fallback}
{user.name}
)}
Select team members for your project
{list.selectedKeys !== "all" && Array.from(list.selectedKeys).length > 0 && (
Selected:
{Array.from(list.selectedKeys).map((key) => {
const user = list.getItem(key);
if (!user) return null;
return (
{user.fallback}{user.name}
);
})}
)}
);
}
```
### Custom Render Function
```tsx
"use client";
import {PlanetEarth, Rocket, ShoppingBag, SquareArticle} from "@gravity-ui/icons";
import {Tag, TagGroup} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
selectionMode="single"
>
News
Travel
Gaming
Shopping
);
}
```
## Related Components
* **Label**: Accessible label for form controls
* **Description**: Helper text for form fields
* **ErrorMessage**: Displays validation error messages for components with validation support
## Styling
### Passing Tailwind CSS classes
```tsx
import { TagGroup, Tag, Label } from '@heroui/react';
function CustomTagGroup() {
return (
Custom Styled
);
}
```
### Customizing the component classes
To customize the TagGroup component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.tag-group {
@apply flex flex-col gap-2;
}
.tag-group__list {
@apply flex flex-wrap gap-2;
}
.tag {
@apply rounded-full px-3 py-1;
}
.tag__remove-button {
@apply ml-1;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The TagGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/tag-group.css) and [tag.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/tag.css)):
#### Base Classes
* `.tag-group` - Base tag group container
* `.tag-group__list` - Container for the list of tags
* `.tag` - Base tag styles
* `.tag__remove-button` - Remove button trigger
#### Slot Classes
* `.tag-group [slot="description"]` - Description slot styles
* `.tag-group [slot="errorMessage"]` - ErrorMessage slot styles
#### Size Classes
* `.tag--sm` - Small size tag
* `.tag--md` - Medium size tag (default)
* `.tag--lg` - Large size tag
#### Variant Classes
* `.tag--default` - Default variant
* `.tag--surface` - Surface variant with surface background
#### State Classes
* `.tag[data-selected="true"]` - Selected tag state
* `.tag[data-disabled="true"]` - Disabled tag state
* `.tag[data-hovered="true"]` - Hovered tag state
* `.tag[data-pressed="true"]` - Pressed tag state
* `.tag[data-focus-visible="true"]` - Focused tag state (keyboard focus)
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]` on tag
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on tag
* **Pressed**: `:active` or `[data-pressed="true"]` on tag
* **Selected**: `[data-selected="true"]` or `[aria-selected="true"]` on tag
* **Disabled**: `:disabled` or `[data-disabled="true"]` on tag
## API Reference
### TagGroup Props
| Prop | Type | Default | Description |
| --------------------- | ----------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
| `selectionMode` | `"none" \| "single" \| "multiple"` | `"none"` | The type of selection that is allowed |
| `selectedKeys` | `Selection` | - | The currently selected keys (controlled) |
| `defaultSelectedKeys` | `Selection` | - | The initial selected keys (uncontrolled) |
| `onSelectionChange` | `(keys: Selection) => void` | - | Handler called when the selection changes |
| `disabledKeys` | `Iterable` | - | Keys of disabled tags |
| `isDisabled` | `boolean` | - | Whether the tag group is disabled |
| `onRemove` | `(keys: Set) => void` | - | Handler called when tags are removed |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Size of the tags in the group |
| `variant` | `"default" \| "surface"` | `"default"` | Visual variant of the tags |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | TagGroup content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### TagGroup.List Props
| Prop | Type | Default | Description |
| ------------------ | -------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------- |
| `items` | `Iterable` | - | The items to display in the tag list |
| `renderEmptyState` | `() => ReactNode` | - | Function to render when the list is empty |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | TagList content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### Tag Props
| Prop | Type | Default | Description |
| ------------ | ---------------------------------------------------------------------- | ------- | -------------------------------------------------------------------- |
| `id` | `Key` | - | The unique identifier for the tag |
| `textValue` | `string` | - | A string representation of the tag's content, used for accessibility |
| `isDisabled` | `boolean` | - | Whether the tag is disabled |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Tag content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
**Note**: `size`, `variant` are inherited from the parent `TagGroup` component and cannot be set directly on individual `Tag` components.
### Tag.RemoveButton Props
| Prop | Type | Default | Description |
| ----------- | ----------- | ------- | ----------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode` | - | Custom remove button content (defaults to close icon) |
**Note**: The `Tag.RemoveButton` component supports customization similar to `SearchField.ClearButton`. When `onRemove` is provided to `TagGroup`:
* **Auto-rendering**: If no custom `Tag.RemoveButton` is included in the `Tag` children, a default remove button is automatically rendered.
* **Custom button**: If a custom `Tag.RemoveButton` is provided as a child of `Tag`, it will be used instead of the auto-rendered button.
* **Custom icon**: You can pass custom content (like icons) to `Tag.RemoveButton` children to customize the appearance.
**Example - Auto-rendered (default)**:
```tsx
News
{/* Remove button is automatically rendered */}
```
**Example - Custom RemoveButton with icon**:
```tsx
News
```
**Example - Custom RemoveButton in render props**:
```tsx
{(renderProps) => (
<>
News
{!!renderProps.allowsRemoving && (
)}
>
)}
```
### RenderProps
When using render functions with TagGroup.List, these values are provided:
| Prop | Type | Description |
| ---------------- | --------- | ---------------------------------- |
| `isSelected` | `boolean` | Whether the tag is selected |
| `isDisabled` | `boolean` | Whether the tag is disabled |
| `isHovered` | `boolean` | Whether the tag is hovered |
| `isPressed` | `boolean` | Whether the tag is pressed |
| `isFocused` | `boolean` | Whether the tag is focused |
| `isFocusVisible` | `boolean` | Whether the tag has keyboard focus |
# ColorArea
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-area
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-area.mdx
> A 2D color picker that allows users to select colors from a gradient area
## Import
```tsx
import { ColorArea } from '@heroui/react';
```
### Usage
```tsx
import {ColorArea} from "@heroui/react";
export function ColorAreaBasic() {
return (
);
}
```
### Anatomy
```tsx
import { ColorArea } from '@heroui/react';
export default () => (
);
```
### With Dots
```tsx
import {ColorArea} from "@heroui/react";
export function ColorAreaWithDots() {
return (
);
}
```
### Controlled
```tsx
"use client";
import type {Color} from "@heroui/react";
import {ColorArea, ColorSwatch, parseColor} from "@heroui/react";
import {useState} from "react";
export function ColorAreaControlled() {
const [color, setColor] = useState(parseColor("#9B80FF"));
return (
Current color:{" "}
{color ? color.toString("hex") : "(empty)"}
);
}
```
### Color Space & Channels
Use `colorSpace` to set the color space (RGB, HSL, HSB) and `xChannel`/`yChannel` props to customize which color channels are displayed on each axis.
```tsx
"use client";
import type {ColorSpace, Key} from "@heroui/react";
import {ColorArea, Label, ListBox, Select, parseColor} from "@heroui/react";
import {useState} from "react";
type ColorChannel = "hue" | "saturation" | "brightness" | "lightness" | "red" | "green" | "blue";
interface ChannelOption {
id: ColorChannel;
name: string;
}
const colorSpaces: Array<{id: ColorSpace; name: string}> = [
{id: "rgb", name: "RGB"},
{id: "hsl", name: "HSL"},
{id: "hsb", name: "HSB"},
];
const channelsBySpace: Record = {
hsb: [
{id: "hue", name: "Hue"},
{id: "saturation", name: "Saturation"},
{id: "brightness", name: "Brightness"},
],
hsl: [
{id: "hue", name: "Hue"},
{id: "saturation", name: "Saturation"},
{id: "lightness", name: "Lightness"},
],
rgb: [
{id: "red", name: "Red"},
{id: "green", name: "Green"},
{id: "blue", name: "Blue"},
],
};
export function ColorAreaSpaceAndChannels() {
const [colorSpace, setColorSpace] = useState("hsb");
const [color, setColor] = useState(() => parseColor("hsb(219, 58%, 93%)"));
const channels = channelsBySpace[colorSpace];
const defaultX = colorSpace === "rgb" ? "blue" : "saturation";
const defaultY =
colorSpace === "rgb" ? "green" : colorSpace === "hsl" ? "lightness" : "brightness";
const [xChannel, setXChannel] = useState(defaultX);
const [yChannel, setYChannel] = useState(defaultY);
const handleColorSpaceChange = (newSpace: Key | null) => {
if (!newSpace) return;
const space = newSpace as ColorSpace;
setColorSpace(space);
// Reset channels to appropriate defaults for the new color space
if (space === "rgb") {
setXChannel("blue");
setYChannel("green");
} else if (space === "hsl") {
setXChannel("saturation");
setYChannel("lightness");
} else {
setXChannel("saturation");
setYChannel("brightness");
}
};
// Filter out the other channel from options (can't have same channel on both axes)
const xChannelOptions = channels.filter((c) => c.id !== yChannel);
const yChannelOptions = channels.filter((c) => c.id !== xChannel);
return (
{/* Controls */}
{/* Color Space Select */}
{/* X Channel Select */}
{/* Y Channel Select */}
{/* Color Area */}
{/* Color Value Display */}
{color.toString(colorSpace)}
);
}
```
### Disabled
```tsx
import {ColorArea} from "@heroui/react";
export function ColorAreaDisabled() {
return (
);
}
```
### Custom Render Function
```tsx
"use client";
import {ColorArea} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
>
} />
);
}
```
## Related Components
* **ColorSwatch**: Visual preview of a color value
* **ColorSwatchPicker**: Color swatch selection from a list of colors
* **ColorField**: Input for entering color values with hex format
## Styling
### Passing Tailwind CSS classes
```tsx
import { ColorArea } from '@heroui/react';
function CustomColorArea() {
return (
);
}
```
### Customizing the component classes
To customize the ColorArea component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.color-area {
@apply rounded-3xl;
}
.color-area__thumb {
@apply size-5 border-4;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ColorArea component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/color-area.css)):
#### Base Classes
* `.color-area` - Base styles with gradient background and inner shadow
* `.color-area--show-dots` - Adds dot grid overlay for precision picking
#### Element Classes
* `.color-area__thumb` - Draggable thumb indicator
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Disabled**: `[data-disabled="true"]`
* **Focus**: `[data-focus-visible="true"]`
* **Dragging**: `[data-dragging="true"]` (thumb only)
## API Reference
### ColorArea Props
Inherits from [React Aria ColorArea](https://react-spectrum.adobe.com/react-aria/ColorArea.html).
| Prop | Type | Default | Description |
| -------------- | ---------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------- |
| `value` | `string \| Color` | - | The current color value (controlled) |
| `defaultValue` | `string \| Color` | - | The default color value (uncontrolled) |
| `onChange` | `(color: Color) => void` | - | Handler called when the color changes while dragging |
| `onChangeEnd` | `(color: Color) => void` | - | Handler called when the user stops dragging |
| `xChannel` | `ColorChannel` | `"saturation"` | Color channel for the horizontal axis |
| `yChannel` | `ColorChannel` | `"brightness"` | Color channel for the vertical axis |
| `colorSpace` | `ColorSpace` | - | The color space for the channels |
| `isDisabled` | `boolean` | `false` | Whether the color area is disabled |
| `showDots` | `boolean` | `false` | Whether to show the dot grid overlay |
| `className` | `string` | - | Additional CSS classes |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ColorArea.Thumb Props
| Prop | Type | Default | Description |
| ----------- | ----------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `style` | `CSSProperties \| ((renderProps) => CSSProperties)` | - | Inline styles or render props function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
# ColorField
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-field.mdx
> Color input field with labels, descriptions, and validation built on React Aria ColorField
## Import
```tsx
import { ColorField, parseColor } from '@heroui/react';
```
### Usage
```tsx
"use client";
import type {Color} from "@heroui/react";
import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react";
import {useState} from "react";
export function Basic() {
const [color, setColor] = useState(parseColor("#0485F7"));
return (
);
}
```
### Anatomy
```tsx
import {ColorField, Label, ColorSwatch, Description, FieldError, parseColor} from '@heroui/react';
export default () => (
)
```
> **ColorField** combines label, color input, description, and error into a single accessible component.
### With Description
```tsx
import {ColorField, Description, Label} from "@heroui/react";
export function WithDescription() {
return (
Enter your brand's primary colorUsed for highlights and CTAs
);
}
```
### Required Field
```tsx
import {ColorField, Description, Label} from "@heroui/react";
export function Required() {
return (
Required field
);
}
```
### Validation
Use `isInvalid` together with `FieldError` to surface validation messages.
```tsx
import {ColorField, FieldError, Label} from "@heroui/react";
export function Invalid() {
return (
Please enter a valid hex colorInvalid color format. Use hex (e.g., #FF5733)
);
}
```
### Channel Editing
ColorField supports editing individual color channels (hue, saturation, lightness, red, green, blue, alpha) by setting the `colorSpace` and `channel` props.
```tsx
"use client";
import type {Color} from "@heroui/react";
import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react";
import {useState} from "react";
export function ChannelEditing() {
const [color, setColor] = useState(parseColor("#7F007F"));
return (
);
}
```
### Controlled
Control the value to synchronize with other components or state management.
```tsx
"use client";
import type {Color} from "@heroui/react";
import {Button, ColorField, ColorSwatch, Description, Label, parseColor} from "@heroui/react";
import {useState} from "react";
export function Controlled() {
const [value, setValue] = useState(parseColor("#0485F7"));
return (
Current value: {value ? value.toString("hex") : "(empty)"}
setValue(parseColor("#EF4444"))}>
Set Red
setValue(parseColor("#10B981"))}>
Set Green
setValue(null)}>
Clear
);
}
```
### Disabled State
```tsx
"use client";
import {ColorField, Description, Label} from "@heroui/react";
export function Disabled() {
return (
This color field is disabledThis color field is disabled
);
}
```
### Full Width
```tsx
import {ColorField, Label} from "@heroui/react";
export function FullWidth() {
return (
);
}
```
### Variants
The ColorField.Group component supports two visual variants:
* **`primary`** (default) - Standard styling with shadow, suitable for most use cases
* **`secondary`** - Lower emphasis variant without shadow, suitable for use in Surface components
```tsx
import {ColorField, Label} from "@heroui/react";
export function Variants() {
return (
);
}
```
### On Surface
When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` on ColorField.Group to apply the lower emphasis variant suitable for surface backgrounds.
```tsx
import {ColorField, Description, Label, Surface} from "@heroui/react";
export function OnSurface() {
return (
Select your theme color
);
}
```
### Form Example
Complete form example with validation and submission handling.
```tsx
"use client";
import type {Color} from "@heroui/react";
import {Button, ColorField, ColorSwatch, Description, Form, Label} from "@heroui/react";
import {useState} from "react";
export function FormExample() {
const [value, setValue] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!value) {
return;
}
setIsSubmitting(true);
// Simulate API call
setTimeout(() => {
console.log("Color submitted:", {color: value.toString("hex")});
setValue(null);
setIsSubmitting(false);
}, 1500);
};
return (
);
}
```
### Custom Render Function
```tsx
"use client";
import type {Color} from "@heroui/react";
import {ColorField, ColorSwatch, Label, parseColor} from "@heroui/react";
import {useState} from "react";
export function CustomRenderFunction() {
const [color, setColor] = useState(parseColor("#0485F7"));
return (
}
value={color}
onChange={setColor}
>
}>
);
}
```
## Related Components
* **ColorSwatch**: Visual preview of a color value
* **ColorSwatchPicker**: Color swatch selection from a list of colors
* **ColorPicker**: Composable color picker with popover
## Styling
### Passing Tailwind CSS classes
```tsx
import {ColorField, Label, ColorSwatch, Description} from '@heroui/react';
function CustomColorField() {
return (
Select your brand's primary color.
);
}
```
### Customizing the component classes
ColorField has minimal default styling. Override the `.color-field` class to customize the container styling.
```css
@layer components {
.color-field {
@apply flex flex-col gap-1;
&[data-invalid="true"],
&[aria-invalid="true"] {
[data-slot="description"] {
@apply hidden;
}
}
[data-slot="label"] {
@apply w-fit;
}
[data-slot="description"] {
@apply px-1;
}
}
}
```
### CSS Classes
* `.color-field` – Root container with minimal styling (`flex flex-col gap-1`)
> **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options. ColorField.Group styling is documented below in the API Reference section.
### Interactive States
ColorField automatically manages these data attributes based on its state:
* **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid
* **Required**: `[data-required="true"]` - Applied when `isRequired` is true
* **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true
* **Focus Within**: `[data-focus-within="true"]` - Applied when any child input is focused
## API Reference
### ColorField Props
ColorField inherits all props from React Aria's [ColorField](https://react-aria.adobe.com/ColorField.md) component.
#### Base Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------- |
| `children` | `React.ReactNode \| (values: ColorFieldRenderProps) => React.ReactNode` | - | Child components (Label, ColorField.Group, etc.) or render function. |
| `className` | `string \| (values: ColorFieldRenderProps) => string` | - | CSS classes for styling, supports render props. |
| `style` | `React.CSSProperties \| (values: ColorFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. |
| `fullWidth` | `boolean` | `false` | Whether the color field should take full width of its container |
| `id` | `string` | - | The element's unique identifier. |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
#### Value Props
| Prop | Type | Default | Description |
| -------------- | -------------------------------- | ------- | -------------------------------------- |
| `value` | `Color \| null` | - | Current value (controlled). |
| `defaultValue` | `Color \| null` | - | Default value (uncontrolled). |
| `onChange` | `(color: Color \| null) => void` | - | Handler called when the value changes. |
#### Channel Props
| Prop | Type | Default | Description |
| ------------ | -------------- | ------- | ---------------------------------------------------------------------------- |
| `colorSpace` | `ColorSpace` | - | The color space that the color field operates in when `channel` is provided. |
| `channel` | `ColorChannel` | - | The color channel to edit. If not provided, edits hex value. |
#### Validation Props
| Prop | Type | Default | Description |
| -------------------- | ---------------------------------------------------------------- | ---------- | -------------------------------------------------------------- |
| `isRequired` | `boolean` | `false` | Whether user input is required before form submission. |
| `isInvalid` | `boolean` | - | Whether the value is invalid. |
| `validate` | `(value: Color) => ValidationError \| true \| null \| undefined` | - | Custom validation function. |
| `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. |
#### State Props
| Prop | Type | Default | Description |
| ----------------- | --------- | ------- | -------------------------------------------------- |
| `isDisabled` | `boolean` | - | Whether the input is disabled. |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. |
| `isWheelDisabled` | `boolean` | - | Whether to disable changing the value with scroll. |
#### Form Props
| Prop | Type | Default | Description |
| ----------- | --------- | ------- | ---------------------------------------------------- |
| `name` | `string` | - | Name of the input element, for HTML form submission. |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render. |
#### Accessibility Props
| Prop | Type | Default | Description |
| ------------------ | -------- | ------- | ----------------------------------------------------- |
| `aria-label` | `string` | - | Accessibility label when no visible label is present. |
| `aria-labelledby` | `string` | - | ID of elements that label this field. |
| `aria-describedby` | `string` | - | ID of elements that describe this field. |
| `aria-details` | `string` | - | ID of elements with additional details. |
### Composition Components
ColorField works with these separate components that should be imported and used directly:
* **Label** - Field label component from `@heroui/react`
* **ColorField.Group** - Color input group component (documented below)
* **ColorField.Input** - Input element within ColorField.Group
* **ColorField.Prefix** / **ColorField.Suffix** - Prefix and suffix slots for the input group
* **ColorSwatch** - Color preview component from `@heroui/react`
* **Description** - Helper text component from `@heroui/react`
* **FieldError** - Validation error message from `@heroui/react`
Each of these components has its own props API. Use them directly within ColorField for composition:
```tsx
import {ColorField, Label, ColorSwatch, Description, FieldError, parseColor} from '@heroui/react';
Select your brand's primary color.Please enter a valid color.
```
### Color Types
ColorField uses `Color` objects from React Aria Components:
```tsx
import {parseColor} from '@heroui/react';
// Parse from hex string
const color = parseColor('#3B82F6');
// Get hex string from color
const hex = color.toString('hex'); // "#3b82f6"
// Get RGB values
const rgb = color.toString('rgb'); // "rgb(59, 130, 246)"
// Use in ColorField
{/* ... */}
```
### ColorFieldRenderProps
When using render props with `className`, `style`, or `children`, these values are available:
| Prop | Type | Description |
| ---------------- | --------- | ----------------------------------------------- |
| `isDisabled` | `boolean` | Whether the field is disabled. |
| `isInvalid` | `boolean` | Whether the field is currently invalid. |
| `isReadOnly` | `boolean` | Whether the field is read-only. |
| `isRequired` | `boolean` | Whether the field is required. |
| `isFocused` | `boolean` | Whether the field is currently focused. |
| `isFocusWithin` | `boolean` | Whether any child element is focused. |
| `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). |
### ColorField.Group Props
ColorField.Group accepts all props from React Aria's `Group` component plus the following:
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `className` | `string` | - | Tailwind classes merged with the component styles. |
| `fullWidth` | `boolean` | `false` | Whether the color input group should take full width of its container |
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the component. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ColorField.Input Props
ColorField.Input accepts all props from React Aria's `Input` component plus the following:
| Prop | Type | Default | Description |
| ------------- | -------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Tailwind classes merged with the component styles. |
| `placeholder` | `string` | - | Placeholder text shown when empty. |
### ColorField.Prefix Props
ColorField.Prefix accepts standard HTML `div` attributes:
| Prop | Type | Default | Description |
| ----------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Tailwind classes merged with the component styles. |
| `children` | `ReactNode` | - | Content to display in the prefix slot. |
### ColorField.Suffix Props
ColorField.Suffix accepts standard HTML `div` attributes:
| Prop | Type | Default | Description |
| ----------- | ----------- | ------- | -------------------------------------------------- |
| `className` | `string` | - | Tailwind classes merged with the component styles. |
| `children` | `ReactNode` | - | Content to display in the suffix slot. |
## ColorField.Group Styling
### Customizing the component classes
The base classes power every instance. Override them once with `@layer components`.
```css
@layer components {
.color-input-group {
@apply inline-flex h-9 items-center overflow-hidden rounded-field border bg-field text-sm text-field-foreground shadow-field outline-none;
&:hover,
&[data-hovered="true"] {
@apply bg-field-hover;
}
&[data-focus-within="true"],
&:focus-within {
@apply status-focused-field;
}
&[data-invalid="true"] {
@apply status-invalid-field;
}
&[data-disabled="true"],
&[aria-disabled="true"] {
@apply status-disabled;
}
}
.color-input-group__input {
@apply flex flex-1 items-center rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none;
}
.color-input-group__prefix,
.color-input-group__suffix {
@apply shrink-0 text-field-placeholder flex items-center;
}
}
```
### ColorField.Group CSS Classes
* `.color-input-group` – Root container styling
* `.color-input-group__input` – Input wrapper styling
* `.color-input-group__prefix` – Prefix element styling
* `.color-input-group__suffix` – Suffix element styling
### ColorField.Group Interactive States
* **Hover**: `:hover` or `[data-hovered="true"]`
* **Focus Within**: `[data-focus-within="true"]` or `:focus-within`
* **Invalid**: `[data-invalid="true"]` (also syncs with `aria-invalid`)
* **Disabled**: `[data-disabled="true"]` or `[aria-disabled="true"]`
# ColorPicker
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-picker
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-picker.mdx
> A composable color picker that synchronizes color value between multiple color components
## Import
```tsx
import {
ColorPicker,
ColorArea,
ColorSlider,
ColorSwatch,
ColorField,
ColorSwatchPicker,
} from '@heroui/react';
```
### Usage
```tsx
import {ColorArea, ColorPicker, ColorSlider, ColorSwatch, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
The ColorPicker is a composable component that combines multiple color components:
```tsx
import { ColorPicker, ColorArea, ColorSlider, ColorSwatch, Label } from '@heroui/react';
export default () => (
);
```
### Controlled
```tsx
"use client";
import {
Button,
ColorArea,
ColorField,
ColorPicker,
ColorSlider,
ColorSwatch,
ColorSwatchPicker,
Label,
parseColor,
} from "@heroui/react";
import {Icon} from "@iconify/react";
import {useState} from "react";
export function Controlled() {
const [color, setColor] = useState(parseColor("#325578"));
const colorPresets = [
"#ef4444",
"#f97316",
"#eab308",
"#22c55e",
"#06b6d4",
"#3b82f6",
"#8b5cf6",
"#ec4899",
"#f43f5e",
];
const shuffleColor = () => {
const randomHue = Math.floor(Math.random() * 360);
const randomSaturation = 50 + Math.floor(Math.random() * 50); // 50-100%
const randomLightness = 40 + Math.floor(Math.random() * 30); // 40-70%
setColor(parseColor(`hsl(${randomHue}, ${randomSaturation}%, ${randomLightness}%)`));
};
return (
{colorPresets.map((preset) => (
))}
Selected: {color.toString("hex")}
);
}
```
### With Swatches
```tsx
import {
ColorArea,
ColorPicker,
ColorSlider,
ColorSwatch,
ColorSwatchPicker,
Label,
} from "@heroui/react";
export function WithSwatches() {
const presets = [
"#ef4444",
"#f97316",
"#eab308",
"#22c55e",
"#06b6d4",
"#3b82f6",
"#8b5cf6",
"#ec4899",
"#f43f5e",
];
return (
{presets.map((preset) => (
))}
);
}
```
### With Fields
Use `ColorField` to allow users to edit individual color channel values with a `Select` to switch between color spaces.
```tsx
"use client";
import type {ColorChannel, ColorSpace} from "@heroui/react";
import {
ColorArea,
ColorField,
ColorPicker,
ColorSlider,
ColorSwatch,
Label,
ListBox,
Select,
} from "@heroui/react";
import {useState} from "react";
export function WithFields() {
const [colorSpace, setColorSpace] = useState("hsl");
const colorChannelsByColorSpace: Record = {
hsb: ["hue", "saturation", "brightness"],
hsl: ["hue", "saturation", "lightness"],
rgb: ["red", "green", "blue"],
};
return (
);
}
```
### With Sliders
Use multiple `ColorSlider` components to adjust each channel of a color value.
```tsx
"use client";
import type {ColorChannel, ColorSpace} from "@heroui/react";
import {ColorPicker, ColorSlider, ColorSwatch, Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";
export function WithSliders() {
const [colorSpace, setColorSpace] = useState("hsl");
const colorChannelsByColorSpace: Record = {
hsb: ["hue", "saturation", "brightness", "alpha"],
hsl: ["hue", "saturation", "lightness", "alpha"],
rgb: ["red", "green", "blue", "alpha"],
};
return (
{colorChannelsByColorSpace[colorSpace].map((channel: ColorChannel) => (
// @ts-expect-error - TypeScript can't correlate dynamic colorSpace with channel type
))}
);
}
```
## Related Components
* **ColorArea**: 2D color picker for selecting colors from a gradient area
* **ColorSlider**: Slider for adjusting individual color channel values
* **ColorSwatch**: Visual preview of a color value
## Styling
### Passing Tailwind CSS classes
```tsx
import { ColorPicker, ColorArea, ColorSlider, ColorSwatch, Label } from '@heroui/react';
function CustomColorPicker() {
return (
);
}
```
### Customizing the component classes
To customize the ColorPicker component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.color-picker {
@apply inline-flex;
}
.color-picker__trigger {
@apply inline-flex items-center gap-4 rounded-lg;
}
.color-picker__popover {
@apply p-4 rounded-xl;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ColorPicker component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/color-picker.css)):
#### Base Classes
* `.color-picker` - Base container
* `.color-picker__trigger` - Trigger button
* `.color-picker__popover` - Popover container
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]`
* **Disabled**: `:disabled` or `[data-disabled="true"]`
## API Reference
### ColorPicker Props
Inherits from [React Aria ColorPicker](https://react-spectrum.adobe.com/react-aria/ColorPicker.html).
| Prop | Type | Default | Description |
| -------------- | ------------------------ | ------- | ---------------------------------------------------- |
| `value` | `string \| Color` | - | The current color value (controlled) |
| `defaultValue` | `string \| Color` | - | The default color value (uncontrolled) |
| `onChange` | `(color: Color) => void` | - | Handler called when the color changes |
| `children` | `React.ReactNode` | - | Content of the color picker (Trigger, Popover, etc.) |
| `className` | `string` | - | Additional CSS classes |
### ColorPicker.Trigger Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------- | ------- | ------------------------------ |
| `children` | `React.ReactNode \| ((renderProps) => React.ReactNode)` | - | Trigger content or render prop |
| `className` | `string` | - | Additional CSS classes |
### ColorPicker.Popover Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | --------------- | ------------------------ |
| `placement` | `Placement` | `"bottom left"` | Placement of the popover |
| `children` | `React.ReactNode` | - | Popover content |
| `className` | `string` | - | Additional CSS classes |
### Related Types
#### Color
Represents a color value. See [React Aria Color](https://react-spectrum.adobe.com/react-aria/ColorPicker.html#color) for full API.
| Method | Description |
| ---------------------------------- | ---------------------------------------------------------------------------- |
| `toString(format)` | Converts the color to a string in the given format (hex, rgb, hsl, hsb, css) |
| `toFormat(format)` | Converts the color to the given format and returns a new Color object |
| `getChannelValue(channel)` | Returns the numeric value for a given channel |
| `withChannelValue(channel, value)` | Sets the numeric value for a channel and returns a new Color |
#### parseColor
```tsx
import { parseColor } from 'react-aria-components';
// Parse from string
const color = parseColor('#ff0000');
const hslColor = parseColor('hsl(0, 100%, 50%)');
```
# ColorSlider
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-slider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-slider.mdx
> A color slider allows users to adjust an individual channel of a color value
## Import
```tsx
import { ColorSlider, Label } from '@heroui/react';
```
### Usage
```tsx
import {ColorSlider, Label} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
Import the ColorSlider component and access all parts using dot notation.
```tsx
import { ColorSlider, Label } from '@heroui/react';
export default () => (
)
```
### Vertical
```tsx
import {ColorSlider} from "@heroui/react";
export function Vertical() {
return (
);
}
```
### Disabled
```tsx
import {ColorSlider, Label} from "@heroui/react";
export function Disabled() {
return (
);
}
```
### Controlled
```tsx
"use client";
import {ColorSlider, ColorSwatch, Label} from "@heroui/react";
import {useState} from "react";
import {parseColor} from "react-aria-components";
export function Controlled() {
const [color, setColor] = useState(parseColor("hsl(200, 100%, 50%)"));
return (
Current color: {color.toString("hsl")}
);
}
```
### HSL Channels
Use multiple ColorSliders to control different channels of a color value. The sliders can share the same color value to create a complete color picker.
```tsx
"use client";
import {ColorSlider, ColorSwatch, Label} from "@heroui/react";
import {useState} from "react";
import {parseColor} from "react-aria-components";
export function Channels() {
const [color, setColor] = useState(parseColor("hsl(0, 100%, 50%)"));
return (
Current color: {color.toString("hsl")}
);
}
```
### Alpha Channel
The alpha channel slider shows a transparency checkerboard pattern to help visualize the transparency level.
```tsx
import {ColorSlider, Label} from "@heroui/react";
export function AlphaChannel() {
return (
);
}
```
### RGB Channels
You can also use RGB color space with red, green, and blue channels.
```tsx
"use client";
import {ColorSlider, ColorSwatch, Label} from "@heroui/react";
import {useState} from "react";
import {parseColor} from "react-aria-components";
export function RGBChannels() {
const [color, setColor] = useState(parseColor("rgb(255, 100, 50)"));
return (
Current color: {color.toString("rgb")}
);
}
```
### Custom Render Function
```tsx
"use client";
import {ColorSlider, Label} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
>
);
}
```
## Related Components
* **ColorSwatch**: Visual preview of a color value
* **ColorSwatchPicker**: Color swatch selection from a list of colors
* **ColorPicker**: Composable color picker with popover
## Styling
### Passing Tailwind CSS classes
```tsx
import { ColorSlider, Label } from '@heroui/react';
function CustomColorSlider() {
return (
);
}
```
### Customizing the component classes
To customize the ColorSlider component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.color-slider {
@apply flex flex-col gap-2;
}
.color-slider__output {
@apply text-muted text-sm;
}
.color-slider__track {
@apply relative h-5 w-full rounded-full;
}
.color-slider__thumb {
@apply size-4 rounded-full border-3 border-white shadow-overlay;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ColorSlider component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/color-slider.css)):
#### Base Classes
* `.color-slider` - Base slider container
* `.color-slider__output` - Output element displaying current value
* `.color-slider__track` - Track element with color gradient
* `.color-slider__thumb` - Thumb element showing current color
#### State Classes
* `.color-slider[data-disabled="true"]` - Disabled slider state
* `.color-slider[data-orientation="vertical"]` - Vertical orientation
* `.color-slider__thumb[data-dragging="true"]` - Thumb being dragged
* `.color-slider__thumb[data-focus-visible="true"]` - Thumb keyboard focused
* `.color-slider__thumb[data-disabled="true"]` - Disabled thumb state
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]` on thumb
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on thumb
* **Dragging**: `[data-dragging="true"]` on thumb
* **Disabled**: `:disabled` or `[data-disabled="true"]` on slider or thumb
## API Reference
### ColorSlider Props
Inherits from [React Aria ColorSlider](https://react-spectrum.adobe.com/react-aria/ColorSlider.html).
| Prop | Type | Default | Description |
| -------------- | ------------------------------------------------------------------------------ | -------------- | --------------------------------------------------------------------------------------------------------------- |
| `channel` | `ColorChannel` | - | The color channel that the slider manipulates (hue, saturation, lightness, brightness, alpha, red, green, blue) |
| `colorSpace` | `ColorSpace` | - | The color space (hsl, hsb, rgb). Defaults to the color space of the value |
| `value` | `string \| Color` | - | The current color value (controlled) |
| `defaultValue` | `string \| Color` | - | The default color value (uncontrolled) |
| `onChange` | `(value: Color) => void` | - | Handler called when the value changes during dragging |
| `onChangeEnd` | `(value: Color) => void` | - | Handler called when dragging ends |
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | The orientation of the slider |
| `isDisabled` | `boolean` | - | Whether the slider is disabled |
| `name` | `string` | - | The name of the input element for form submission |
| `aria-label` | `string` | - | Accessibility label for the slider |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Slider content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ColorSlider.Output Props
| Prop | Type | Default | Description |
| ----------- | ----------------------------- | ------- | --------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Output content or render function |
### ColorSlider.Track Props
| Prop | Type | Default | Description |
| ----------- | --------------------------------- | ------- | -------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `style` | `CSSProperties \| RenderFunction` | - | Inline styles or render function |
| `children` | `ReactNode \| RenderFunction` | - | Track content or render function |
### ColorSlider.Thumb Props
| Prop | Type | Default | Description |
| ----------- | --------------------------------- | ------- | -------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `style` | `CSSProperties \| RenderFunction` | - | Inline styles or render function |
| `children` | `ReactNode \| RenderFunction` | - | Thumb content or render function |
### RenderProps
When using render functions, these values are provided:
| Prop | Type | Description |
| ------------- | ---------------------------- | ------------------------------ |
| `state` | `ColorSliderState` | The state of the color slider |
| `color` | `Color` | The current color value |
| `orientation` | `"horizontal" \| "vertical"` | The orientation of the slider |
| `isDisabled` | `boolean` | Whether the slider is disabled |
## Accessibility
The ColorSlider component implements the ARIA slider pattern and provides:
* Full keyboard navigation support (Arrow keys, Home, End, Page Up/Down)
* Screen reader announcements for value changes
* Proper focus management
* Support for disabled states
* HTML form integration via hidden input elements
* Internationalization support with locale-aware value formatting
For more information, see the [React Aria ColorSlider documentation](https://react-spectrum.adobe.com/react-aria/ColorSlider.html).
# ColorSwatchPicker
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-swatch-picker
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-swatch-picker.mdx
> A list of color swatches that allows users to select a color from a predefined palette.
## Import
```tsx
import { ColorSwatchPicker, parseColor } from '@heroui/react';
```
### Usage
```tsx
import {ColorSwatchPicker} from "@heroui/react";
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
export function Basic() {
return (
{colors.map((color) => (
))}
);
}
```
### Anatomy
Import the ColorSwatchPicker component and access all parts using dot notation.
```tsx
import { ColorSwatchPicker } from '@heroui/react';
export default () => (
);
```
### Variants
```tsx
import {ColorSwatchPicker} from "@heroui/react";
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
export function Variants() {
return (
);
}
```
### Disabled
```tsx
import {ColorSwatchPicker} from "@heroui/react";
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
export function Disabled() {
return (
{colors.map((color) => (
))}
);
}
```
### Custom Indicator
```tsx
import {HeartFill} from "@gravity-ui/icons";
import {ColorSwatchPicker} from "@heroui/react";
export function CustomIndicator() {
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
return (
{colors.map((color) => (
))}
);
}
```
### Custom Render Function
```tsx
"use client";
import {ColorSwatchPicker} from "@heroui/react";
const colors = ["#F43F5E", "#D946EF", "#8B5CF6", "#3B82F6", "#06B6D4", "#10B981", "#84CC16"];
export function CustomRenderFunction() {
return (
}>
{colors.map((color) => (
))}
);
}
```
## Related Components
* **ColorSwatch**: Visual preview of a color value
* **ColorField**: Input for entering color values with hex format
* **ColorArea**: 2D color picker for selecting colors from a gradient area
## Styling
### Passing Tailwind CSS classes
You can customize the ColorSwatchPicker using className props:
```tsx
import { ColorSwatchPicker } from '@heroui/react';
function CustomColorSwatchPicker() {
return (
);
}
```
### Customizing the component classes
To customize the ColorSwatchPicker component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.color-swatch-picker {
@apply gap-4;
}
.color-swatch-picker__item {
@apply shadow-md;
}
.color-swatch-picker__swatch {
@apply border-2 border-white;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ColorSwatchPicker component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/color-swatch-picker.css)):
#### Base & Structure
* `.color-swatch-picker` - Base container (flex layout)
* `.color-swatch-picker__item` - Individual swatch item wrapper
* `.color-swatch-picker__swatch` - The color swatch visual element
#### Size Classes
* `.color-swatch-picker--xs` - Extra small (16px)
* `.color-swatch-picker--sm` - Small (24px)
* `.color-swatch-picker--md` - Medium (32px, default)
* `.color-swatch-picker--lg` - Large (36px)
* `.color-swatch-picker--xl` - Extra large (40px)
#### Shape Variants
* `.color-swatch-picker--circle` - Circle shape (default)
* `.color-swatch-picker--square` - Square shape with rounded corners
#### Layout Classes
* `.color-swatch-picker--grid` - Horizontal wrapping layout (default)
* `.color-swatch-picker--stack` - Vertical stacked layout
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]` - Scale up to 1.1 (only when not selected)
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]` - Focus ring
* **Selected**: `[data-selected="true"]` - Inner border with same color as swatch
* **Disabled**: `[data-disabled="true"]` - Reduced opacity
## API Reference
### ColorSwatchPicker Props
Inherits from [React Aria ColorSwatchPicker](https://react-spectrum.adobe.com/react-aria/ColorSwatchPicker.html).
| Prop | Type | Default | Description |
| -------------- | ------------------------------------------------------------------------------------ | ---------- | ---------------------------------------------------------------- |
| `value` | `string \| Color` | - | The current selected color (controlled) |
| `defaultValue` | `string \| Color` | - | The default selected color (uncontrolled) |
| `onChange` | `(value: Color) => void` | - | Handler called when selection changes |
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of the swatches |
| `variant` | `"circle" \| "square"` | `"circle"` | Shape of the swatches |
| `layout` | `"grid" \| "stack"` | `"grid"` | Layout direction |
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | ColorSwatchPicker.Item elements |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ColorSwatchPicker.Item Props
| Prop | Type | Default | Description |
| ------------ | ---------------------------------------------------------------------------------------- | ------------ | ---------------------------------------------------------------- |
| `color` | `string \| Color` | **Required** | The color of the swatch |
| `isDisabled` | `boolean` | `false` | Whether the item is disabled |
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | ColorSwatchPicker.Swatch element |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### ColorSwatchPicker.Swatch Props
| Prop | Type | Default | Description |
| ----------- | -------- | ------- | ---------------------- |
| `className` | `string` | - | Additional CSS classes |
### parseColor
The `parseColor` function is re-exported from React Aria Components for convenience:
```tsx
import { parseColor } from '@heroui/react';
// Parse hex color
const red = parseColor('#ff0000');
// Parse RGB
const green = parseColor('rgb(0, 255, 0)');
// Parse HSL
const blue = parseColor('hsl(240, 100%, 50%)');
```
# ColorSwatch
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/color-swatch
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(colors)/color-swatch.mdx
> A visual preview of a color value with accessibility support
## Import
```tsx
import { ColorSwatch } from '@heroui/react';
```
### Usage
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchBasic() {
return (
);
}
```
### Sizes
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchSizes() {
return (
);
}
```
### Shapes
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchShapes() {
return (
);
}
```
### Transparency
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchTransparency() {
return (
);
}
```
### Custom Styles with Render Props
You can use the `style` render props to access the color value and create custom visual effects.
```tsx
"use client";
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchCustomStyles() {
const colors = ["#0485F7", "#EF4444", "#F59E0B", "#10B981", "#D946EF"];
return (
);
}
```
### Accessibility
Use `colorName` to provide a custom accessible name for the color, and `aria-label` to add context about how the color is used.
```tsx
import {ColorSwatch} from "@heroui/react";
export function ColorSwatchAccessibility() {
return (
);
}
```
### Custom Render Function
```tsx
"use client";
import {ColorSwatch} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
/>
}
/>
}
/>
}
/>
}
/>
);
}
```
## Related Components
* **ColorSwatchPicker**: Color swatch selection from a list of colors
* **ColorField**: Input for entering color values with hex format
* **ColorArea**: 2D color picker for selecting colors from a gradient area
## Styling
### Passing Tailwind CSS classes
```tsx
import {ColorSwatch} from '@heroui/react';
function CustomColorSwatch() {
return (
);
}
```
### Customizing the component classes
To customize the ColorSwatch component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.color-swatch {
@apply border-2 border-white;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The ColorSwatch component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/color-swatch.css)):
#### Base Classes
* `.color-swatch` - Base swatch styles with checkered background for transparency
#### Shape Classes
* `.color-swatch--circle` - Circular shape (default)
* `.color-swatch--square` - Square shape with rounded corners
#### Size Classes
* `.color-swatch--xs` - Extra small (16px)
* `.color-swatch--sm` - Small (24px)
* `.color-swatch--md` - Medium (32px, default)
* `.color-swatch--lg` - Large (36px)
* `.color-swatch--xl` - Extra large (40px)
## API Reference
### ColorSwatch Props
| Prop | Type | Default | Description |
| ------------ | ------------------------------------------------------------------------------ | ---------- | -------------------------------------------------------------------- |
| `color` | `string \| Color` | - | The color value to display (hex, rgb, hsl, etc.) |
| `colorName` | `string` | - | Accessible name for the color (overrides auto-generated description) |
| `className` | `string` | - | Additional CSS classes |
| `shape` | `"circle" \| "square"` | `"circle"` | Shape of the swatch |
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of the swatch |
| `style` | `CSSProperties \| ((renderProps) => CSSProperties)` | - | Inline styles or render props function with access to color |
| `aria-label` | `string` | - | Accessible label for the swatch |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### Style Render Props
When using the `style` prop as a function, you receive render props with access to the color:
```tsx
({
boxShadow: `0 4px 14px ${color.toString("css")}80`,
})}
/>
```
The `color` object provides methods like:
* `color.toString("css")` - Returns CSS color string
* `color.toString("hex")` - Returns hex color string
* `color.getChannelValue("alpha")` - Returns alpha channel value
# Slider
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/slider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(controls)/slider.mdx
> A slider allows a user to select one or more values within a range
## Import
```tsx
import { Slider } from '@heroui/react';
```
### Usage
```tsx
import {Label, Slider} from "@heroui/react";
export function Default() {
return (
);
}
```
### Anatomy
Import the Slider component and access all parts using dot notation.
```tsx
import { Slider, Label } from '@heroui/react';
export default () => (
)
```
### Range Slider Anatomy
```tsx
import { Slider, Label } from '@heroui/react';
export default () => (
{({state}) => (
<>
{state.values.map((_, i) => (
))}
>
)}
)
```
### Vertical
```tsx
import {Label, Slider} from "@heroui/react";
export function Vertical() {
return (
);
}
```
### Range
```tsx
"use client";
import {Label, Slider} from "@heroui/react";
export function Range() {
return (
{({state}) => (
<>
{state.values.map((_, i) => (
))}
>
)}
);
}
```
### Disabled
```tsx
import {Label, Slider} from "@heroui/react";
export function Disabled() {
return (
);
}
```
### Custom Render Function
```tsx
"use client";
import {Label, Slider} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
>
);
}
```
## Related Components
* **Label**: Accessible label for form controls
* **Form**: Form validation and submission handling
* **Description**: Helper text for form fields
## Styling
### Passing Tailwind CSS classes
```tsx
import { Slider, Label } from '@heroui/react';
function CustomSlider() {
return (
);
}
```
### Customizing the component classes
To customize the Slider component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.slider {
@apply flex flex-col gap-2;
}
.slider__output {
@apply text-muted-fg text-sm;
}
.slider-track {
@apply relative h-2 w-full rounded-full bg-surface-secondary;
}
.slider-fill {
@apply absolute h-full rounded-full bg-accent;
}
.slider-thumb {
@apply size-4 rounded-full bg-accent border-2 border-background;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The Slider component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/slider.css)):
#### Base Classes
* `.slider` - Base slider container
* `.slider__output` - Output element displaying current value(s)
* `.slider-track` - Track element containing fill and thumbs
* `.slider-fill` - Fill element showing selected range
* `.slider-thumb` - Individual thumb element
#### State Classes
* `.slider[data-disabled="true"]` - Disabled slider state
* `.slider[data-orientation="vertical"]` - Vertical orientation
* `.slider-thumb[data-dragging="true"]` - Thumb being dragged
* `.slider-thumb[data-focus-visible="true"]` - Thumb keyboard focused
* `.slider-thumb[data-disabled="true"]` - Disabled thumb state
* `.slider-track[data-fill-start="true"]` - Fill starts at beginning
* `.slider-track[data-fill-end="true"]` - Fill ends at end
### Interactive States
The component supports both CSS pseudo-classes and data attributes for flexibility:
* **Hover**: `:hover` or `[data-hovered="true"]` on thumb
* **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on thumb
* **Dragging**: `[data-dragging="true"]` on thumb
* **Disabled**: `:disabled` or `[data-disabled="true"]` on slider or thumb
## API Reference
### Slider Props
| Prop | Type | Default | Description |
| ----------------- | ------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------- |
| `value` | `number \| number[]` | - | The current value (controlled) |
| `defaultValue` | `number \| number[]` | - | The default value (uncontrolled) |
| `onChange` | `(value: number \| number[]) => void` | - | Handler called when the value changes |
| `onChangeEnd` | `(value: number \| number[]) => void` | - | Handler called when dragging ends |
| `minValue` | `number` | `0` | The slider's minimum value |
| `maxValue` | `number` | `100` | The slider's maximum value |
| `step` | `number` | `1` | The slider's step value |
| `formatOptions` | `Intl.NumberFormatOptions` | - | The display format of the value label |
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | The orientation of the slider |
| `isDisabled` | `boolean` | - | Whether the slider is disabled |
| `aria-label` | `string` | - | Accessibility label for the slider |
| `aria-labelledby` | `string` | - | ID of element that labels the slider |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Slider content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### Slider.Output Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Output content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### Slider.Track Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------------------------------ | ------- | ---------------------------------------------------------------- |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Track content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### Slider.Fill Props
| Prop | Type | Default | Description |
| ----------- | --------------- | ------- | ---------------------- |
| `className` | `string` | - | Additional CSS classes |
| `style` | `CSSProperties` | - | Inline styles |
### Slider.Thumb Props
| Prop | Type | Default | Description |
| ------------ | ------------------------------------------------------------------------------ | ------- | ---------------------------------------------------------------- |
| `index` | `number` | `0` | Index of the thumb within the slider |
| `isDisabled` | `boolean` | - | Whether this thumb is disabled |
| `name` | `string` | - | The name of the input element, used when submitting an HTML form |
| `className` | `string` | - | Additional CSS classes |
| `children` | `ReactNode \| RenderFunction` | - | Thumb content or render function |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function. |
### RenderProps
When using render functions with Slider.Output or Slider.Track, these values are provided:
| Prop | Type | Description |
| -------------------- | ---------------------------- | -------------------------------------------------------- |
| `state` | `SliderState` | The state of the slider |
| `values` | `number[]` | Values managed by the slider by thumb index |
| `getThumbValueLabel` | `(index: number) => string` | Returns the string label for the specified thumb's value |
| `orientation` | `"horizontal" \| "vertical"` | The orientation of the slider |
| `isDisabled` | `boolean` | Whether the slider is disabled |
## Examples
### Basic Usage
```tsx
import { Slider, Label } from '@heroui/react';
```
### Range Slider
```tsx
import { Slider, Label } from '@heroui/react';
{({state}) => (
<>
{state.values.map((_, i) => (
))}
>
)}
```
### Controlled Value
```tsx
import { Slider, Label } from '@heroui/react';
import { useState } from 'react';
function ControlledSlider() {
const [value, setValue] = useState(25);
return (
<>
Current value: {value}
>
);
}
```
### Custom Value Formatting
```tsx
import { Slider, Label } from '@heroui/react';
```
### Vertical Orientation
```tsx
import { Slider, Label } from '@heroui/react';
```
### Custom Output Display
```tsx
import { Slider, Label } from '@heroui/react';
{({state}) =>
state.values.map((_, i) => state.getThumbValueLabel(i)).join(' – ')
}
{({state}) => (
<>
{state.values.map((_, i) => (
))}
>
)}
```
## Accessibility
The Slider component implements the ARIA slider pattern and provides:
* Full keyboard navigation support (Arrow keys, Home, End, Page Up/Down)
* Screen reader announcements for value changes
* Proper focus management
* Support for disabled states
* HTML form integration via hidden input elements
* Internationalization support with locale-aware value formatting
* Right-to-left (RTL) language support
For more information, see the [React Aria Slider documentation](https://react-spectrum.adobe.com/react-aria/Slider.html).
# Switch
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/switch
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(controls)/switch.mdx
> A toggle switch component for boolean states
## Import
```tsx
import { Switch, SwitchGroup, Label } from '@heroui/react';
```
### Usage
```tsx
import {Label, Switch} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
Import the Switch component and access all parts using dot notation.
```tsx
import { Switch, Label, Description } from '@heroui/react';
export default () => (
{/* Optional */}
{/* Optional */}
);
```
For grouping multiple switches, use the `SwitchGroup` component:
```tsx
import { Switch, SwitchGroup, Label } from '@heroui/react';
export default () => (
);
```
### Disabled
```tsx
import {Label, Switch} from "@heroui/react";
export function Disabled() {
return (
);
}
```
### Default Selected
```tsx
import {Label, Switch} from "@heroui/react";
export function DefaultSelected() {
return (
);
}
```
### Controlled
```tsx
"use client";
import {Label, Switch} from "@heroui/react";
import React from "react";
export function Controlled() {
const [isSelected, setIsSelected] = React.useState(false);
return (
Switch is {isSelected ? "on" : "off"}
);
}
```
### Without Label
```tsx
import {Switch} from "@heroui/react";
export function WithoutLabel() {
return (
);
}
```
### Sizes
```tsx
import {Label, Switch} from "@heroui/react";
export function Sizes() {
return (
);
}
```
### Label Position
```tsx
import {Label, Switch} from "@heroui/react";
export function LabelPosition() {
return (
);
}
```
### With Icons
```tsx
"use client";
import {
BellFill,
BellSlash,
Check,
Microphone,
MicrophoneSlash,
Moon,
Power,
Sun,
VolumeFill,
VolumeSlashFill,
} from "@gravity-ui/icons";
import {Switch} from "@heroui/react";
export function WithIcons() {
const icons = {
check: {
off: Power,
on: Check,
selectedControlClass: "bg-green-500/80",
},
darkMode: {
off: Moon,
on: Sun,
selectedControlClass: "",
},
microphone: {
off: Microphone,
on: MicrophoneSlash,
selectedControlClass: "bg-red-500/80",
},
notification: {
off: BellSlash,
on: BellFill,
selectedControlClass: "bg-purple-500/80",
},
volume: {
off: VolumeFill,
on: VolumeSlashFill,
selectedControlClass: "bg-blue-500/80",
},
};
return (
);
}
```
### Sizes
```tsx
import {Avatar, Badge} from "@heroui/react";
const AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
export function BadgeSizes() {
const sizes = ["sm", "md", "lg"] as const;
return (
{sizes.map((size) => (
JD
5
))}
);
}
```
### Variants
```tsx
import {Avatar, Badge, Separator} from "@heroui/react";
import React from "react";
const AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
export function BadgeVariants() {
const variants = ["primary", "secondary", "soft"] as const;
const colors = ["accent", "default", "success", "warning", "danger"] as const;
return (
{variants.map((variant, index) => (
{variant}
{colors.map((color) => (
JD
5
))}
{index < variants.length - 1 && }
))}
);
}
```
### Placements
```tsx
import {Avatar, Badge} from "@heroui/react";
const AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
export function BadgePlacements() {
const placements = ["top-right", "top-left", "bottom-right", "bottom-left"] as const;
return (
{placements.map((placement) => (
JD{placement}
))}
);
}
```
### With Content
Badge supports text, numbers, and icons as content. When no children are provided, it renders as a dot indicator.
```tsx
import {Bell} from "@gravity-ui/icons";
import {Avatar, Badge} from "@heroui/react";
const AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
export function BadgeWithContent() {
return (
JD
5
JD
New
JD
99+
JD
);
}
```
### Dot Badge
Empty badges act as status indicators — useful for online/offline states or activity signals.
```tsx
import {Avatar, Badge} from "@heroui/react";
const AVATAR_URL = "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
export function BadgeDot() {
const colors = ["accent", "success", "warning", "danger"] as const;
return (
{colors.map((color) => (
JD
))}
);
}
```
## Related Components
* **Avatar**: Display user profile images
* **Chip**: Compact elements for tags and filters
## Styling
### Passing Tailwind CSS classes
You can style the root container and individual slots:
```tsx
import {Badge, Avatar} from '@heroui/react';
function CustomBadge() {
return (
99+
);
}
```
### Customizing the component classes
To customize the Badge component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.badge {
@apply rounded-full text-xs;
}
.badge__label {
@apply font-semibold;
}
.badge--accent {
@apply shadow-sm;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The Badge component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/badge.css)):
#### Base Classes
* `.badge` - Base badge container styles
* `.badge__label` - Label text slot styles
* `.badge-anchor` - Positioning wrapper for the anchored element
#### Color Classes
* `.badge--accent` - Accent color variant
* `.badge--danger` - Danger color variant
* `.badge--default` - Default color variant
* `.badge--success` - Success color variant
* `.badge--warning` - Warning color variant
#### Variant Classes
* `.badge--primary` - Primary variant with filled background
* `.badge--secondary` - Secondary variant with default background
* `.badge--soft` - Soft variant with lighter background
#### Size Classes
* `.badge--sm` - Small size
* `.badge--md` - Medium size (default)
* `.badge--lg` - Large size
#### Placement Classes
* `.badge--top-right` - Position at top-right corner (default)
* `.badge--top-left` - Position at top-left corner
* `.badge--bottom-right` - Position at bottom-right corner
* `.badge--bottom-left` - Position at bottom-left corner
#### Compound Variant Classes
Badges support combining variant and color classes (e.g., `.badge--primary.badge--accent`). The following combinations have default styles defined:
**Primary Variants:**
* `.badge--primary.badge--accent` - Primary accent with filled background
* `.badge--primary.badge--default` - Primary default with filled background
* `.badge--primary.badge--success` - Primary success with filled background
* `.badge--primary.badge--warning` - Primary warning with filled background
* `.badge--primary.badge--danger` - Primary danger with filled background
**Soft Variants:**
* `.badge--soft.badge--accent` - Soft accent with lighter background
* `.badge--soft.badge--default` - Soft default with lighter background
* `.badge--soft.badge--success` - Soft success with lighter background
* `.badge--soft.badge--warning` - Soft warning with lighter background
* `.badge--soft.badge--danger` - Soft danger with lighter background
## API Reference
### Badge Props
| Prop | Type | Default | Description |
| ----------- | -------------------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to display inside the badge (text, number, or icon). When omitted, renders as a dot. |
| `className` | `string` | - | Additional CSS classes for the root element |
| `color` | `"default" \| "accent" \| "success" \| "warning" \| "danger"` | `"default"` | Color variant of the badge |
| `variant` | `"primary" \| "secondary" \| "soft"` | `"primary"` | Visual style variant |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Size of the badge |
| `placement` | `"top-right" \| "top-left" \| "bottom-right" \| "bottom-left"` | `"top-right"` | Position of the badge relative to its anchor |
### Badge.Anchor Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | --------------------------------------------------------- |
| `children` | `React.ReactNode` | - | The element to anchor the badge to, plus the Badge itself |
| `className` | `string` | - | Additional CSS classes for the anchor wrapper |
### Badge.Label Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | ----------------------------------------- |
| `children` | `React.ReactNode` | - | Label text content |
| `className` | `string` | - | Additional CSS classes for the label slot |
# Chip
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/chip
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(data-display)/chip.mdx
> Small informational badges for displaying labels, statuses, and categories
## Import
```tsx
import { Chip } from '@heroui/react';
```
## Anatomy
Import the Chip component and access all parts using dot notation.
> Plain-text children are automatically wrapped in ``.
```tsx
Label text
```
### Usage
```tsx
import {Chip} from "@heroui/react";
export function ChipBasic() {
return (
DefaultAccentSuccessWarningDanger
);
}
```
### Variants
```tsx
import {CircleDashed} from "@gravity-ui/icons";
import {Chip, Separator} from "@heroui/react";
import React from "react";
export function ChipVariants() {
const sizes = ["lg", "md", "sm"] as const;
const variants = ["primary", "secondary", "tertiary", "soft"] as const;
const colors = ["accent", "default", "success", "warning", "danger"] as const;
return (
{sizes.map((size, index) => (
{size}
{/* Color labels header */}
{colors.map((color) => (
{color}
))}
{variants.map((variant) => (
{variant}
{colors.map((color) => (
Label
))}
))}
{index < sizes.length - 1 && }
))}
);
}
```
### With Icons
```tsx
import {ChevronDown, CircleCheckFill, CircleFill, Clock, Xmark} from "@gravity-ui/icons";
import {Chip} from "@heroui/react";
export function ChipWithIcon() {
return (
InformationCompletedPendingFailedLabel
);
}
```
### Statuses
```tsx
import {Ban, Check, CircleFill, CircleInfo, TriangleExclamation} from "@gravity-ui/icons";
import {Chip} from "@heroui/react";
export function ChipStatuses() {
return (
DefaultActivePendingInactive
New FeatureAvailableBetaDeprecated
);
}
```
## Related Components
* **Avatar**: Display user profile images
* **CloseButton**: Button for dismissing overlays
* **Separator**: Visual divider between content
## Styling
### Passing Tailwind CSS classes
You can style the root container and individual slots:
```tsx
import {Chip} from '@heroui/react';
function CustomChip() {
return (
Custom Styled
);
}
```
### Customizing the component classes
To customize the Chip component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).
```css
@layer components {
.chip {
@apply rounded-full text-xs;
}
.chip__label {
@apply font-medium;
}
.chip--accent {
@apply border-accent/20;
}
.chip--accent .chip__label {
@apply text-accent;
}
}
```
HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.
### CSS Classes
The Chip component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/chip.css)):
#### Base Classes
* `.chip` - Base chip container styles
* `.chip__label` - Label text slot styles
#### Color Classes
* `.chip--accent` - Accent color variant
* `.chip--danger` - Danger color variant
* `.chip--default` - Default color variant
* `.chip--success` - Success color variant
* `.chip--warning` - Warning color variant
#### Variant Classes
* `.chip--primary` - Primary variant with filled background
* `.chip--secondary` - Secondary variant with border
* `.chip--tertiary` - Tertiary variant with transparent background
* `.chip--soft` - Soft variant with lighter background
#### Size Classes
* `.chip--sm` - Small size
* `.chip--md` - Medium size (default)
* `.chip--lg` - Large size
#### Compound Variant Classes
Chips support combining variant and color classes (e.g., `.chip--secondary.chip--accent`). The following combinations have default styles defined:
**Primary Variants:**
* `.chip--primary.chip--accent` - Primary accent combination with filled background
* `.chip--primary.chip--success` - Primary success combination with filled background
* `.chip--primary.chip--warning` - Primary warning combination with filled background
* `.chip--primary.chip--danger` - Primary danger combination with filled background
**Soft Variants:**
* `.chip--accent.chip--soft` - Soft accent combination with lighter background
* `.chip--success.chip--soft` - Soft success combination with lighter background
* `.chip--warning.chip--soft` - Soft warning combination with lighter background
* `.chip--danger.chip--soft` - Soft danger combination with lighter background
**Note:** You can apply custom styles to any variant-color combination (e.g., `.chip--secondary.chip--accent`, `.chip--tertiary.chip--success`) using the `@layer components` directive in your CSS.
## API Reference
### Chip Props
| Prop | Type | Default | Description |
| ----------- | ------------------------------------------------------------- | ------------- | ------------------------------------------- |
| `children` | `React.ReactNode` | - | Content to display inside the chip |
| `className` | `string` | - | Additional CSS classes for the root element |
| `color` | `"default" \| "accent" \| "success" \| "warning" \| "danger"` | `"default"` | Color variant of the chip |
| `variant` | `"primary" \| "secondary" \| "tertiary" \| "soft"` | `"secondary"` | Visual style variant |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Size of the chip |
### Chip.Label Props
| Prop | Type | Default | Description |
| ----------- | ----------------- | ------- | ----------------------------------------- |
| `children` | `React.ReactNode` | - | Label text content |
| `className` | `string` | - | Additional CSS classes for the label slot |
# Table
**Category**: react
**URL**: https://v3.heroui.com/docs/react/components/table
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(data-display)/table.mdx
> Tables display structured data in rows and columns with support for sorting, selection, column resizing, and infinite scrolling.
## Import
```tsx
import { Table } from '@heroui/react';
```
### Usage
```tsx
import {Table} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
Import the Table component and access all parts using dot notation.
```tsx
import { Table } from '@heroui/react';
export default () => (