# 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 (
); } ``` ## 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 ( ); } ``` ### 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 ); } ``` ### 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 | ### 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 ( 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 () => (
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 (
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 (
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 (
Actions
X C U
Text Style
B I U
Text Alignment
A H D
); } ``` ### With Keyboard Shortcuts ```tsx "use client"; import {Button, Dropdown, Kbd, Label} from "@heroui/react"; export function WithKeyboardShortcuts() { return ( console.log(`Selected: ${key}`)}> N O S D ); } ``` ### 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 ( console.log(`Selected: ${key}`)}> N O S D ); } ``` ### Long Press Trigger ```tsx import {Button, Dropdown, Label} from "@heroui/react"; export function LongPressTrigger() { return ( ); } ``` ### 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 ( console.log(`Selected: ${key}`)}>
Create a new file
N
Open an existing file
O
Save the current file
S
Move to trash
D
); } ``` ### With Sections ```tsx "use client"; import {EllipsisVertical, Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons"; import {Description, Dropdown, Header, Kbd, Label, Separator} from "@heroui/react"; export function WithSections() { return ( console.log(`Selected: ${key}`)}>
Actions
Create a new file
N
Make changes
E
Danger zone
Move to trash
D
); } ``` ### With Disabled Items ```tsx "use client"; import {Bars, Pencil, SquarePlus, TrashBin} from "@gravity-ui/icons"; import {Button, Description, Dropdown, Header, Kbd, Label, Separator} from "@heroui/react"; export function WithDisabledItems() { return ( console.log(`Selected: ${key}`)} >
Actions
Create a new file
N
Make changes
E
Danger zone
Move to trash
D
); } ``` ### With Submenus ```tsx "use client"; import {Button, Dropdown, Label} from "@heroui/react"; export function WithSubmenus() { return ( console.log(`Selected: ${key}`)}> ); } ``` ### With Custom Submenu Indicator ```tsx "use client"; import {ArrowRight} from "@gravity-ui/icons"; import {Button, Dropdown, Label} from "@heroui/react"; export function WithCustomSubmenuIndicator() { return ( console.log(`Selected: ${key}`)}> ); } ``` ### Controlled ```tsx "use client"; import type {Selection} from "@heroui/react"; import {Button, Dropdown, Label} from "@heroui/react"; import {useState} from "react"; export function Controlled() { const [selected, setSelected] = useState(new Set(["bold"])); const selectedItems = Array.from(selected); return (

Selected: {selectedItems.length > 0 ? selectedItems.join(", ") : "None"}

); } ``` ### Controlled Open State ```tsx "use client"; import {Button, Dropdown, Label} from "@heroui/react"; import {useState} from "react"; export function ControlledOpenState() { const [open, setOpen] = useState(false); return (

Dropdown is: {open ? "open" : "closed"}

); } ``` ### Custom Trigger ```tsx import {ArrowRightFromSquare, Gear, Persons} from "@gravity-ui/icons"; import {Avatar, Dropdown, Label} from "@heroui/react"; export function CustomTrigger() { return ( JD
JD

Jane Doe

jane@example.com

); } ``` ## Related Components * **Button**: Allows a user to perform an action * **Popover**: Displays content in context with a trigger * **Separator**: Visual divider between content ## Styling ### Passing Tailwind CSS classes ```tsx import { Dropdown, Button } from '@heroui/react'; function CustomDropdown() { return ( Item 1 ); } ``` ### Customizing the component classes To customize the Dropdown component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .dropdown { @apply flex flex-col gap-1; } .dropdown__trigger { @apply outline-none; } .dropdown__popover { @apply rounded-lg border border-border bg-overlay p-2; } .dropdown__menu { @apply flex flex-col gap-1; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The Dropdown component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/dropdown.css)): #### Base Classes * `.dropdown` - Base dropdown container * `.dropdown__trigger` - The button or element that triggers the dropdown * `.dropdown__popover` - The popover container * `.dropdown__menu` - The menu container inside the popover #### State Classes * `.dropdown__trigger[data-focus-visible="true"]` - Focused trigger state * `.dropdown__trigger[data-disabled="true"]` - Disabled trigger state * `.dropdown__trigger[data-pressed="true"]` - Pressed trigger state * `.dropdown__popover[data-entering]` - Entering animation state * `.dropdown__popover[data-exiting]` - Exiting animation state * `.dropdown__menu[data-selection-mode="single"]` - Single selection mode * `.dropdown__menu[data-selection-mode="multiple"]` - Multiple selection mode ### Menu Component Classes The Dropdown component uses Menu, MenuItem, and MenuSection as base components. These classes are also available for customization: #### Menu Classes * `.menu` - Base menu container ([menu.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/menu.css)) * `[data-slot="separator"]` - Separator elements within the menu #### MenuItem Classes * `.menu-item` - Base menu item container ([menu-item.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/menu-item.css)) * `.menu-item__indicator` - Selection indicator (checkmark or dot) * `[data-slot="menu-item-indicator--checkmark"]` - Checkmark indicator SVG * `[data-slot="menu-item-indicator--dot"]` - Dot indicator SVG * `.menu-item__indicator--submenu` - Submenu indicator (chevron) * `.menu-item--default` - Default variant styling * `.menu-item--danger` - Danger variant styling #### MenuItem State Classes * `.menu-item[data-focus-visible="true"]` - Focused item state (keyboard focus) * `.menu-item[data-focus="true"]` - Focused item state * `.menu-item[data-pressed]` - Pressed item state * `.menu-item[data-hovered]` - Hovered item state * `.menu-item[data-selected="true"]` - Selected item state * `.menu-item[data-disabled]` - Disabled item state * `.menu-item[data-has-submenu="true"]` - Item with submenu * `.menu-item[data-selection-mode="single"]` - Single selection mode * `.menu-item[data-selection-mode="multiple"]` - Multiple selection mode * `.menu-item[aria-checked="true"]` - Checked item (ARIA) * `.menu-item[aria-selected="true"]` - Selected item (ARIA) #### MenuSection Classes * `.menu-section` - Base menu section container ([menu-section.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/menu-section.css)) ### Interactive States The component supports both CSS pseudo-classes and data attributes for flexibility: * **Hover**: `:hover` or `[data-hovered="true"]` on trigger and items * **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on trigger and items * **Disabled**: `:disabled` or `[data-disabled="true"]` on trigger and items * **Pressed**: `:active` or `[data-pressed="true"]` on trigger and items * **Selected**: `[data-selected="true"]` or `[aria-selected="true"]` on items ## API Reference ### Dropdown Props | Prop | Type | Default | Description | | -------------- | --------------------------- | --------- | ------------------------------------------------------ | | `isOpen` | `boolean` | - | Sets the open state of the menu (controlled) | | `defaultOpen` | `boolean` | - | Sets the default open state of the menu (uncontrolled) | | `onOpenChange` | `(isOpen: boolean) => void` | - | Handler called when the open state changes | | `trigger` | `"press" \| "longPress"` | `"press"` | The type of interaction that triggers the menu | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Dropdown content | ### Dropdown.Trigger Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ------- | ---------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Trigger content or render function | All [Button](https://react-spectrum.adobe.com/react-aria/Button.html) props are also supported when using a Button as the trigger. ### Dropdown.Popover Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | ------------------------------------------------ | | `placement` | `"bottom" \| "bottom left" \| "bottom right" \| "bottom start" \| "bottom end" \| "top" \| "top left" \| "top right" \| "top start" \| "top end" \| "left" \| "left top" \| "left bottom" \| "start" \| "start top" \| "start bottom" \| "right" \| "right top" \| "right bottom" \| "end" \| "end top" \| "end bottom"` | `"bottom"` | Placement of the popover relative to the trigger | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Content children | All [Popover](https://react-spectrum.adobe.com/react-aria/Popover.html) props are also supported. ### Dropdown.Menu Props | Prop | Type | Default | Description | | --------------------- | ---------------------------------- | -------- | ----------------------------------------------- | | `selectionMode` | `"single" \| "multiple" \| "none"` | `"none"` | Whether single or multiple selection is enabled | | `selectedKeys` | `Iterable` | - | The currently selected keys (controlled) | | `defaultSelectedKeys` | `Iterable` | - | The initial selected keys (uncontrolled) | | `onSelectionChange` | `(keys: Selection) => void` | - | Handler called when the selection changes | | `disabledKeys` | `Iterable` | - | Keys of disabled items | | `onAction` | `(key: Key) => void` | - | Handler called when an item is activated | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Menu content | All [Menu](https://react-spectrum.adobe.com/react-aria/Menu.html#menu) props are also supported. ### Dropdown.Section Props | Prop | Type | Default | Description | | --------------------- | --------------------------- | ------- | -------------------------------------------- | | `selectionMode` | `"single" \| "multiple"` | - | Selection mode for items within this section | | `selectedKeys` | `Iterable` | - | The currently selected keys (controlled) | | `defaultSelectedKeys` | `Iterable` | - | The initial selected keys (uncontrolled) | | `onSelectionChange` | `(keys: Selection) => void` | - | Handler called when the selection changes | | `disabledKeys` | `Iterable` | - | Keys of disabled items | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Section content | All [MenuSection](https://react-spectrum.adobe.com/react-aria/Menu.html#menusection) props are also supported. ### Dropdown.Item Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ----------- | -------------------------------------- | | `id` | `Key` | - | Unique identifier for the item | | `textValue` | `string` | - | Text content of the item for typeahead | | `variant` | `"default" \| "danger"` | `"default"` | Visual variant of the item | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Item content or render function | All [MenuItem](https://react-spectrum.adobe.com/react-aria/Menu.html#menuitem) props are also supported. ### Dropdown.ItemIndicator Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ------------- | ------------------------------------------- | | `type` | `"checkmark" \| "dot"` | `"checkmark"` | Type of indicator to display | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Custom indicator content or render function | When using a render function, these values are provided: | Prop | Type | Description | | ----------------- | --------- | --------------------------------------------- | | `isSelected` | `boolean` | Whether the item is selected | | `isIndeterminate` | `boolean` | Whether the item is in an indeterminate state | ### Dropdown.SubmenuIndicator Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ------------------------ | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Custom indicator content | ### Dropdown.SubmenuTrigger Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ----------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Submenu trigger content | All [SubmenuTrigger](https://react-spectrum.adobe.com/react-aria/Menu.html#submenutrigger) props are also supported. ### RenderProps When using render functions with Dropdown.Item, these values are provided: | Prop | Type | Description | | ------------ | --------- | --------------------------------- | | `isSelected` | `boolean` | Whether the item is selected | | `isFocused` | `boolean` | Whether the item is focused | | `isDisabled` | `boolean` | Whether the item is disabled | | `isPressed` | `boolean` | Whether the item is being pressed | ## Examples ### Basic Usage ```tsx import { Dropdown, Button, Label } from '@heroui/react'; alert(`Selected: ${key}`)}> ``` ### With Sections ```tsx import { Dropdown, Button, Label, Header, Separator } from '@heroui/react'; alert(`Selected: ${key}`)}>
Actions
Danger zone
``` ### Controlled Selection ```tsx import type { Selection } from '@heroui/react'; import { Dropdown, Button, Label } from '@heroui/react'; import { useState } from 'react'; function ControlledDropdown() { const [selected, setSelected] = useState(new Set(['bold'])); return ( ); } ``` ### With Submenus ```tsx import { Dropdown, Button, Label } from '@heroui/react'; alert(`Selected: ${key}`)}> ``` ## Accessibility The Dropdown component implements the ARIA menu pattern and provides: * Full keyboard navigation support (arrow keys, home/end, typeahead) * Screen reader announcements for actions and selection changes * Proper focus management * Support for disabled states * Long press interaction support * Submenu navigation For more information, see the [React Aria Menu documentation](https://react-spectrum.adobe.com/react-aria/Menu.html#menu).
# ListBox **Category**: react **URL**: https://v3.heroui.com/docs/react/components/list-box **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(collections)/list-box.mdx > A listbox displays a list of options and allows a user to select one or more of them ## Import ```tsx import { ListBox } from '@heroui/react'; ``` ### Usage ```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
); } ``` ### 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
E
Danger 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
E
Danger 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 (
B
bob@heroui.com
{({isSelected}) => (isSelected ? : null)}
F
fred@heroui.com
{({isSelected}) => (isSelected ? : null)}
M
martha@heroui.com
{({isSelected}) => (isSelected ? : null)}

Selected: {selectedItems.length > 0 ? selectedItems.join(", ") : "None"}

); } ``` ## Related Components * **Select**: Dropdown select control * **ComboBox**: Text input with searchable dropdown list * **Avatar**: Display user profile images ## Styling ### Passing Tailwind CSS classes ```tsx import { ListBox } from '@heroui/react'; function CustomListBox() { return ( Item 1 ); } ``` ### Customizing the component classes To customize the ListBox component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .listbox { @apply rounded-lg border border-border bg-surface p-2; } .listbox-item { @apply rounded px-2 py-1 cursor-pointer; } .listbox-item--danger { @apply text-danger; } .listbox-item__indicator { @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 ListBox component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/listbox.css)): #### Base Classes * `.listbox` - Base listbox container * `.listbox-item` - Individual listbox item * `.listbox-item__indicator` - Selection indicator icon * `.listbox-section` - Section container for grouping items #### Variant Classes * `.listbox--default` - Default variant styling * `.listbox--danger` - Danger variant styling * `.listbox-item--default` - Default item variant * `.listbox-item--danger` - Danger item variant #### State Classes * `.listbox-item[data-selected="true"]` - Selected item state * `.listbox-item[data-focus-visible="true"]` - Focused item state * `.listbox-item[data-disabled="true"]` - Disabled item state * `.listbox-item__indicator[data-visible="true"]` - Visible indicator state ### Interactive States The component supports both CSS pseudo-classes and data attributes for flexibility: * **Hover**: `:hover` or `[data-hovered="true"]` on item * **Focus**: `:focus-visible` or `[data-focus-visible="true"]` on item * **Selected**: `[data-selected="true"]` on item * **Disabled**: `:disabled` or `[data-disabled="true"]` on item ## API Reference ### ListBox Props | Prop | Type | Default | Description | | --------------------- | ---------------------------------- | ----------- | ---------------------------------------- | | `aria-label` | `string` | - | Accessibility label for the listbox | | `aria-labelledby` | `string` | - | ID of element that labels the listbox | | `selectionMode` | `"none" \| "single" \| "multiple"` | `"single"` | Selection behavior | | `selectedKeys` | `Selection` | - | Controlled selected keys | | `defaultSelectedKeys` | `Selection` | - | Initial selected keys | | `onSelectionChange` | `(keys: Selection) => void` | - | Handler called when selection changes | | `disabledKeys` | `Iterable` | - | Keys of disabled items | | `onAction` | `(key: Key) => void` | - | Handler called when an item is activated | | `variant` | `"default" \| "danger"` | `"default"` | Visual variant | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | ListBox items and sections | ### ListBox.Item Props | Prop | Type | Default | Description | | ------------ | ----------------------------- | ----------- | ------------------------------------------ | | `id` | `Key` | - | Unique identifier for the item | | `textValue` | `string` | - | Text value for accessibility and typeahead | | `isDisabled` | `boolean` | `false` | Whether this item is disabled | | `variant` | `"default" \| "danger"` | `"default"` | Visual variant | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Item content or render function | ### ListBox.ItemIndicator Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ------- | ------------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Custom indicator content or render function | ### ListBox.Section Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ------------------------------------------ | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Section content including Header and Items | ### RenderProps When using render functions with ListBox.Item or ListBox.ItemIndicator, these values are provided: | Prop | Type | Description | | ------------ | --------- | --------------------------------- | | `isSelected` | `boolean` | Whether the item is selected | | `isFocused` | `boolean` | Whether the item is focused | | `isDisabled` | `boolean` | Whether the item is disabled | | `isPressed` | `boolean` | Whether the item is being pressed | ## Examples ### Basic Usage ```tsx import { ListBox, Label, Description } from '@heroui/react'; bob@heroui.com alice@heroui.com ``` ### With Sections ```tsx import { ListBox, Header, Separator } from '@heroui/react'; console.log(key)}>
Actions
New file Edit file
Danger zone
Delete
``` ### Controlled Selection ```tsx import { ListBox, Selection } from '@heroui/react'; import { useState } from 'react'; function ControlledListBox() { const [selected, setSelected] = useState(new Set(["1"])); return ( Option 1 Option 2 Option 3 ); } ``` ### Custom Indicator ```tsx import { ListBox, ListBoxItemIndicator } from '@heroui/react'; import { Icon } from '@iconify/react'; Option 1 {({isSelected}) => isSelected ? : null } ``` ## Accessibility The ListBox component implements the ARIA listbox pattern and provides: * Full keyboard navigation support * Screen reader announcements for selection changes * Proper focus management * Support for disabled states * Typeahead search functionality For more information, see the [React Aria ListBox documentation](https://react-spectrum.adobe.com/react-aria/ListBox.html). # TagGroup **Category**: react **URL**: https://v3.heroui.com/docs/react/components/tag-group **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(collections)/tag-group.mdx > A focusable list of tags with support for keyboard navigation, selection, and removal ## Import ```tsx import { TagGroup } from '@heroui/react'; ``` ### Usage ```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 ); } ``` ### Anatomy ```tsx import { TagGroup, Tag, Label, Description, ErrorMessage } from '@heroui/react'; export default () => ( ) ``` ### Sizes ```tsx "use client"; import {Label, Tag, TagGroup} from "@heroui/react"; export function TagGroupSizes() { return (
News Travel Gaming News Travel Gaming News Travel Gaming
); } ``` ### Variants ```tsx "use client"; import {Label, Tag, TagGroup} from "@heroui/react"; export function TagGroupVariants() { return (
News Travel Gaming News Travel Gaming
); } ``` ### Disabled ```tsx "use client"; import {Description, Label, Tag, TagGroup} from "@heroui/react"; export function TagGroupDisabled() { return (
News Travel Gaming Some tags are disabled News Travel Gaming Tags disabled via disabledKeys prop
); } ``` ### Selection Modes ```tsx "use client"; import type {Key} from "@heroui/react"; import {Description, Label, Tag, TagGroup} from "@heroui/react"; import {useState} from "react"; export function TagGroupSelectionModes() { const [singleSelected, setSingleSelected] = useState>(new Set(["news"])); const [multipleSelected, setMultipleSelected] = useState>( new Set(["news", "travel"]), ); return (
setSingleSelected(keys)} > News Travel Gaming Shopping Choose one category setMultipleSelected(keys)} > News Travel Gaming Shopping Choose multiple categories
); } ``` ### Controlled ```tsx "use client"; import type {Key} from "@heroui/react"; import {Description, Label, Tag, TagGroup} from "@heroui/react"; import {useState} from "react"; export function TagGroupControlled() { const [selected, setSelected] = useState>(new Set(["news", "travel"])); return (
setSelected(keys)} > News Travel Gaming Shopping Selected: {Array.from(selected).length > 0 ? Array.from(selected).join(", ") : "None"}
); } ``` ### With Error Message ```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 TagGroupWithErrorMessage() { const [selected, setSelected] = useState>(new Set()); const isInvalid = useMemo(() => Array.from(selected).length === 0, [selected]); return ( setSelected(keys)} > Laundry Fitness center Parking Swimming pool Breakfast {isInvalid ? "Select at least one category" : "Selected: " + Array.from(selected).join(", ")} {!!isInvalid && <>Please select at least one category} ); } ``` ### With Prefix ```tsx "use client"; import {PlanetEarth, Rocket, ShoppingBag, SquareArticle} from "@gravity-ui/icons"; import {Avatar, Description, Label, Tag, TagGroup} from "@heroui/react"; export function TagGroupWithPrefix() { return (
News Travel Gaming Shopping Tags with icons F Fred M Michael J Jane Tags with avatars
); } ``` ### With Remove Button ```tsx "use client"; import type {Key} from "@heroui/react"; import {CircleXmarkFill} from "@gravity-ui/icons"; import {Description, EmptyState, Label, Tag, TagGroup} from "@heroui/react"; import {useState} from "react"; export function TagGroupWithRemoveButton() { type TagItem = {id: string; name: string}; const [tags, setTags] = useState([ {id: "news", name: "News"}, {id: "travel", name: "Travel"}, {id: "gaming", name: "Gaming"}, {id: "shopping", name: "Shopping"}, ]); const [frameworks, setFrameworks] = useState([ {id: "react", name: "React"}, {id: "vue", name: "Vue"}, {id: "angular", name: "Angular"}, {id: "svelte", name: "Svelte"}, ]); const onRemoveTags = (keys: Set) => { setTags(tags.filter((tag) => !keys.has(tag.id))); }; const onRemoveFrameworks = (keys: Set) => { setFrameworks(frameworks.filter((framework) => !keys.has(framework.id))); }; return (
No categories found} > {(tag) => ( {tag.name} )} Click the X to remove tags
No frameworks found} > {(tag) => ( {(renderProps) => ( <> {tag.name} {!!renderProps.allowsRemoving && ( )} )} )} Custom remove button with icon
); } ``` ### With List Data ```tsx "use client"; import type {Key} from "@heroui/react"; import {Avatar, Description, EmptyState, Label, Tag, TagGroup, useListData} from "@heroui/react"; export function TagGroupWithListData() { type User = { id: string; name: string; avatar: string; fallback: string; }; const list = useListData({ getKey: (item) => item.id, initialItems: [ { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg", fallback: "F", id: "fred", name: "Fred", }, { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg", fallback: "M", id: "michael", name: "Michael", }, { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg", fallback: "J", id: "jane", name: "Jane", }, { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg", fallback: "A", id: "alice", name: "Alice", }, { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg", fallback: "B", id: "bob", name: "Bob", }, { avatar: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/black.jpg", fallback: "C", id: "charlie", name: "Charlie", }, ], initialSelectedKeys: new Set(["fred", "michael"]), }); const onRemove = (keys: Set) => { list.remove(...keys); }; 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}
); })}
)}
); } ``` ## 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 | ### 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 | ### 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 | **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 |
# 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 () => ( ) ``` ### 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 ( ); } ``` ## 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 | ### Slider.Output Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ------- | --------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Output content or render function | ### Slider.Track Props | Prop | Type | Default | Description | | ----------- | ----------------------------- | ------- | -------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| RenderFunction` | - | Track content or 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 | ### 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 } from '@heroui/react'; export default () => ( {/* 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 (
{Object.entries(icons).map(([key, value]) => ( {({isSelected}) => ( <> {isSelected ? ( ) : ( )} )} ))}
); } ``` ### With Description ```tsx import {Description, Label, Switch} from "@heroui/react"; export function WithDescription() { return (
Allow others to see your profile information
); } ``` ### Group ```tsx import {Label, Switch, SwitchGroup} from "@heroui/react"; export function Group() { return ( ); } ``` ### Group Horizontal ```tsx import {Label, Switch, SwitchGroup} from "@heroui/react"; export function GroupHorizontal() { return ( ); } ``` ### Render Props ```tsx "use client"; import {Label, Switch} from "@heroui/react"; export function RenderProps() { return ( {({isSelected}) => ( <> )} ); } ``` ### Form Integration ```tsx "use client"; import {Button, Label, Switch, SwitchGroup} from "@heroui/react"; import React from "react"; export function Form() { const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.target as HTMLFormElement); alert( `Form submitted with:\n${Array.from(formData.entries()) .map(([key, value]) => `${key}: ${value}`) .join("\n")}`, ); }; return (
); } ``` ### Custom Styles ```tsx "use client"; import {Check, Power} from "@gravity-ui/icons"; import {Switch} from "@heroui/react"; export function CustomStyles() { return ( {({isSelected}) => ( <> {isSelected ? ( ) : ( )} )} ); } ``` ## Related Components * **Label**: Accessible label for form controls * **Description**: Helper text for form fields * **Button**: Allows a user to perform an action ## Styling ### Passing Tailwind CSS classes You can customize individual Switch components: ```tsx import { Switch, Label } from '@heroui/react'; function CustomSwitch() { return ( {({isSelected}) => ( <> )} ); } ``` Or customize the SwitchGroup layout: ```tsx import { Switch, SwitchGroup, Label } from '@heroui/react'; function CustomSwitchGroup() { return ( ); } ``` ### Customizing the component classes To customize the Switch component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .switch { @apply inline-flex gap-3 items-center; } .switch__control { @apply h-5 w-8 bg-gray-400 data-[selected=true]:bg-blue-500; } .switch__thumb { @apply bg-white shadow-sm; } .switch__icon { @apply h-3 w-3 text-current; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes #### Switch Classes The Switch component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/switch.css)): * `.switch` - Base switch container * `.switch__control` - Switch control track * `.switch__thumb` - Switch thumb that moves * `.switch__icon` - Optional icon inside the thumb * `.switch--sm` - Small size variant * `.switch--md` - Medium size variant (default) * `.switch--lg` - Large size variant #### SwitchGroup Classes The SwitchGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/switch-group.css)): * `.switch-group` - Switch group container * `.switch-group__items` - Container for switch items * `.switch-group--horizontal` - Horizontal layout * `.switch-group--vertical` - Vertical layout (default) ### Interactive States The switch supports both CSS pseudo-classes and data attributes for flexibility: * **Selected**: `[data-selected="true"]` (thumb position and background color change) * **Hover**: `:hover` or `[data-hovered="true"]` * **Focus**: `:focus-visible` or `[data-focus-visible="true"]` (shows focus ring) * **Disabled**: `:disabled` or `[aria-disabled="true"]` (reduced opacity, no pointer events) * **Pressed**: `:active` or `[data-pressed="true"]` ## API Reference ### Switch Props Inherits from [React Aria Switch](https://react-spectrum.adobe.com/react-aria/Switch.html). | Prop | Type | Default | Description | | ----------------- | ------------------------------------------------------------------- | ------- | ----------------------------------------------------------------- | | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | The size of the switch | | `isSelected` | `boolean` | `false` | Whether the switch is on | | `defaultSelected` | `boolean` | `false` | Whether the switch is on by default (uncontrolled) | | `isDisabled` | `boolean` | `false` | Whether the switch is disabled | | `name` | `string` | - | The name of the input element, used when submitting an HTML form | | `value` | `string` | - | The value of the input element, used when submitting an HTML form | | `onChange` | `(isSelected: boolean) => void` | - | Handler called when the switch value changes | | `onPress` | `(e: PressEvent) => void` | - | Handler called when the switch is pressed | | `children` | `React.ReactNode \| (values: SwitchRenderProps) => React.ReactNode` | - | Switch content or render prop | ### SwitchRenderProps When using the render prop pattern, these values are provided: | Prop | Type | Description | | ---------------- | --------- | --------------------------------------- | | `isSelected` | `boolean` | Whether the switch is currently on | | `isHovered` | `boolean` | Whether the switch is hovered | | `isPressed` | `boolean` | Whether the switch is currently pressed | | `isFocused` | `boolean` | Whether the switch is focused | | `isFocusVisible` | `boolean` | Whether the switch is keyboard focused | | `isDisabled` | `boolean` | Whether the switch is disabled | | `isReadOnly` | `boolean` | Whether the switch is read only | | `state` | `-` | State of the switch. | ### SwitchGroup Props | Prop | Type | Default | Description | | ------------- | ---------------------------- | ------------ | ----------------------------------- | | `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | The orientation of the switch group | | `children` | `React.ReactNode` | - | The switch items to render | | `className` | `string` | - | Additional CSS class names |
# 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'; ``` ### Usage ```tsx import {Chip} from "@heroui/react"; export function ChipBasic() { return (
Default Accent Success Warning Danger
); } ``` ### 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 (
Information Completed Pending Failed Label
); } ``` ### Statuses ```tsx import {Ban, Check, CircleFill, CircleInfo, TriangleExclamation} from "@gravity-ui/icons"; import {Chip} from "@heroui/react"; export function ChipStatuses() { return (
Default Active Pending Inactive
New Feature Available Beta Deprecated
); } ``` ## Related Components * **Avatar**: Display user profile images * **CloseButton**: Button for dismissing overlays * **Separator**: Visual divider between content ## Styling ### Passing Tailwind CSS classes ```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--accent { @apply border-accent/20; } } ``` 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 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 | | `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 | # Alert **Category**: react **URL**: https://v3.heroui.com/docs/react/components/alert **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(feedback)/alert.mdx > Display important messages and notifications to users with status indicators ## Import ```tsx import { Alert } from '@heroui/react'; ``` ### Usage ```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.
); } ``` ### Anatomy Import the Alert component and access all parts using dot notation. ```tsx import { Alert } from '@heroui/react'; export default () => ( ) ``` ## Related Components * **CloseButton**: Button for dismissing overlays * **Button**: Allows a user to perform an action * **Spinner**: Loading indicator ## Styling ### Passing Tailwind CSS classes ```tsx import { Alert } from "@heroui/react"; function CustomAlert() { return ( Custom Alert This alert has custom styling applied ); } ``` ### Customizing the component classes To customize the Alert component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .alert { @apply rounded-2xl shadow-lg; } .alert__title { @apply font-bold text-lg; } .alert--danger { @apply border-l-4 border-red-600; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The Alert component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/alert.css)): #### Base Classes * `.alert` - Base alert container * `.alert__indicator` - Icon/indicator container * `.alert__content` - Content wrapper for title and description * `.alert__title` - Alert title text * `.alert__description` - Alert description text #### Status Variant Classes * `.alert--default` - Default gray status * `.alert--accent` - Accent blue status * `.alert--success` - Success green status * `.alert--warning` - Warning yellow/orange status * `.alert--danger` - Danger red status ### Interactive States The Alert component is primarily informational and doesn't have interactive states on the base component. However, it can contain interactive elements like buttons or close buttons. ## API Reference ### Alert Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------- | ----------- | ------------------------------ | | `status` | `"default" \| "accent" \| "success" \| "warning" \| "danger"` | `"default"` | The visual status of the alert | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | The alert content | ### Alert.Indicator Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ----------------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Custom indicator icon (defaults to status icon) | ### Alert.Content Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ----------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | Content (typically Title and Description) | ### Alert.Title Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | The alert title text | ### Alert.Description Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | -------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | The alert description text |
# Skeleton **Category**: react **URL**: https://v3.heroui.com/docs/react/components/skeleton **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(feedback)/skeleton.mdx > Skeleton is a placeholder to show a loading state and the expected shape of a component. ## Import ```tsx import { Skeleton } from '@heroui/react'; ``` ### Usage ```tsx import {Skeleton} from "@heroui/react"; export function Basic() { return (
); } ``` ### Text Content ```tsx import {Skeleton} from "@heroui/react"; export function TextContent() { return (
); } ``` ### User Profile ```tsx import {Skeleton} from "@heroui/react"; export function UserProfile() { return (
); } ``` ### List Items ```tsx import {Skeleton} from "@heroui/react"; export function List() { return (
{Array.from({length: 3}).map((_, index) => (
))}
); } ``` ### Animation Types ```tsx import {Skeleton} from "@heroui/react"; export function AnimationTypes() { return (

Shimmer

Pulse

None

); } ``` ### Grid ```tsx import {Skeleton} from "@heroui/react"; export function Grid() { return (
); } ``` ### Single Shimmer A synchronized shimmer effect that passes over all skeleton elements at once. Apply the `skeleton--shimmer` class to a parent container and set `animationType="none"` on child skeletons. ```tsx import {Skeleton} from "@heroui/react"; export function SingleShimmer() { return (
); } ``` ## Related Components * **Card**: Content container with header, body, and footer * **Avatar**: Display user profile images ## Styling ### Global Animation Configuration You can set a default animation type for all Skeleton components in your application by defining the `--skeleton-animation` CSS variable: ```css /* In your global CSS file */ :root { /* Possible values: shimmer, pulse, none */ --skeleton-animation: pulse; } /* You can also set different values for light/dark themes */ .light, [data-theme="light"] { --skeleton-animation: shimmer; } .dark, [data-theme="dark"] { --skeleton-animation: pulse; } ``` This global setting will be overridden by the `animationType` prop when specified on individual components. ### Passing Tailwind CSS classes ```tsx import { Skeleton } from '@heroui/react'; function CustomSkeleton() { return ( ); } ``` ### Customizing the component classes To customize the Skeleton component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { /* Base skeleton styles */ .skeleton { @apply bg-surface-secondary/50; /* Change base background */ } /* Shimmer animation gradient */ .skeleton--shimmer:before { @apply viasurface; /* Change shimmer gradient color */ } /* Pulse animation */ .skeleton--pulse { @apply animate-pulse opacity-75; /* Customize pulse animation */ } /* No animation variant */ .skeleton--none { @apply opacity-50; /* Style for static skeleton */ } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The Skeleton component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/skeleton.css)): #### Base Class `.skeleton` - Base skeleton styles with background and rounded corners #### Animation Variant Classes * `.skeleton--shimmer` - Adds shimmer animation with gradient effect (default) * `.skeleton--pulse` - Adds pulse animation using Tailwind's animate-pulse * `.skeleton--none` - No animation, static skeleton ### Animation The Skeleton component supports three animation types, each with different visual effects: #### Shimmer Animation The shimmer effect creates a gradient that moves across the skeleton element: ```css .skeleton--shimmer:before { @apply animate-skeleton via-surface-3 absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent to-transparent content-['']; } ``` The shimmer animation is defined in the theme using: ```css @theme inline { --animate-skeleton: skeleton 2s linear infinite; @keyframes skeleton { 100% { transform: translateX(200%); } } } ``` #### Pulse Animation The pulse animation uses Tailwind's built-in `animate-pulse` utility: ```css .skeleton--pulse { @apply animate-pulse; } ``` #### No Animation For static skeletons without any animation: ```css .skeleton--none { /* No animation styles applied */ } ``` ## API Reference ### Skeleton Props | Prop | Type | Default | Description | | --------------- | -------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------- | | `animationType` | `"shimmer" \| "pulse" \| "none"` | `"shimmer"` or CSS variable | The animation type for the skeleton. Can be globally configured via `--skeleton-animation` CSS variable | | `className` | `string` | - | Additional CSS classes |
# Spinner **Category**: react **URL**: https://v3.heroui.com/docs/react/components/spinner **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(feedback)/spinner.mdx > A loading indicator component to show pending states ## Import ```tsx import { Spinner } from '@heroui/react'; ``` ### Usage ```tsx import {Spinner} from "@heroui/react"; export function SpinnerBasic() { return (
); } ``` ### Colors ```tsx import {Spinner} from "@heroui/react"; export function SpinnerColors() { return (
Current
Accent
Success
Warning
Danger
); } ``` ### Sizes ```tsx import {Spinner} from "@heroui/react"; export function SpinnerSizes() { return (
Small
Medium
Large
Extra Large
); } ``` ## Styling ### Passing Tailwind CSS classes ```tsx import {Spinner} from '@heroui/react'; function CustomSpinner() { return ( ); } ``` ### Customizing the component classes To customize the Spinner component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .spinner { @apply animate-spin; } .spinner--accent { color: var(--accent); } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The Spinner component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/spinner.css)): #### Base & Size Classes * `.spinner` - Base spinner styles with default size * `.spinner--sm` - Small size variant * `.spinner--md` - Medium size variant (default) * `.spinner--lg` - Large size variant * `.spinner--xl` - Extra large size variant #### Color Classes * `.spinner--current` - Inherits current text color * `.spinner--accent` - Accent color variant * `.spinner--danger` - Danger color variant * `.spinner--success` - Success color variant * `.spinner--warning` - Warning color variant ## API Reference ### Spinner Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------- | ----------- | ---------------------------- | | `size` | `"sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of the spinner | | `color` | `"current" \| "accent" \| "success" \| "warning" \| "danger"` | `"current"` | Color variant of the spinner | | `className` | `string` | - | Additional CSS classes |
# Card **Category**: react **URL**: https://v3.heroui.com/docs/react/components/card **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(layout)/card.mdx > Flexible container component for grouping related content and actions ## Import ```tsx import { Card } from "@heroui/react"; ``` ### Usage ```tsx import {CircleDollar} from "@gravity-ui/icons"; import {Card, Link} from "@heroui/react"; export function Default() { return ( Become an Acme Creator! Visit the Acme Creator Hub to sign up today and start earning credits from your fans and followers. Creator Hub ); } ``` ### Anatomy Import the Card component and access all parts using dot notation. ```tsx import { Card } from "@heroui/react"; export default () => ( ); ``` ### Variants Cards come in semantic variants that describe their prominence level rather than specific visual styles. This allows themes to interpret them differently: ```tsx import {Card} from "@heroui/react"; export function Variants() { return (
Transparent Minimal prominence with transparent background

Use for less important content or nested cards

Default Standard card appearance (bg-surface)

The default card variant for most use cases

Secondary Medium prominence (bg-surface-secondary)

Use to draw moderate attention

Tertiary Higher prominence (bg-surface-tertiary)

Use for primary or featured content

); } ``` * **`transparent`** - Minimal prominence, transparent background (great for nested cards) * **`default`** - Standard card for most use cases (surface-secondary) * **`secondary`** - Medium prominence to draw moderate attention (surface-tertiary) * **`tertiary`** - Higher prominence for important content (surface-tertiary) ### Horizontal Layout ```tsx import {Button, Card, CloseButton} from "@heroui/react"; export function Horizontal() { return (
Cherries
Become an ACME Creator! Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet faucibus etiam.
Only 10 spots Submission ends Oct 10.
); } ``` ### With Avatar ```tsx import {Avatar, Card} from "@heroui/react"; export function WithAvatar() { return (
Indie Hackers community Indie Hackers 148 members IH By Martha AI Builders community AI Builders 362 members B By John
); } ``` ### With Images ```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 */}
Cherries
Become an ACME Creator! Lorem ipsum dolor sit amet consectetur. Sed arcu donec id aliquam dolor sed amet faucibus etiam.
Only 10 spots Submission 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 */} Futuristic Robot
Bridging the Future Today, 6:30 PM
{/* 2 */} Avocado
Avocado Hackathon Wed, 4:30 PM
{/* 3 */} Sound Electro event
Sound Electro | Beyond art Fri, 8:00 PM
); } ``` ### With Form ```tsx "use client"; import {Button, Card, Form, Input, Label, Link, TextField} from "@heroui/react"; export function WithForm() { 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 ( Login Enter your credentials to access your account
Forgot password?
); } ``` ## Accessibility ```tsx import { Card } from '@heroui/react'; import { cardVariants } from '@heroui/styles'; // Semantic markup Article Title // Interactive cards Product Name ``` ## Related Components * **Surface**: Base container surface * **Avatar**: Display user profile images * **Form**: Form validation and submission handling ## Styling ### Component Customization ```tsx Custom Styled Card Custom colors applied

Content with custom styling

``` ### CSS Variable Overrides ```css /* Override specific variants */ .card--secondary { @apply bg-gradient-to-br from-blue-50 to-purple-50; } /* Custom element styles */ .card__title { @apply text-xl font-bold; } ``` ## CSS Classes Card uses [BEM](https://getbem.com/) naming for predictable styling, ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/card.css)): #### Base Classes * `.card` - Base container with padding and border * `.card__header` - Header section container * `.card__title` - Title with base font size and weight * `.card__description` - Muted description text * `.card__content` - Flexible content container * `.card__footer` - Footer with row layout #### Variant Classes * `.card--transparent` - Minimal prominence, transparent background (maps to `transparent` variant) * `.card--default` - Standard appearance with surface-secondary (default) * `.card--secondary` - Medium prominence with surface-tertiary (maps to `secondary` variant) * `.card--tertiary` - Higher prominence with surface-tertiary (maps to `tertiary` variant) ## API Reference ### Card | Prop | Type | Default | Description | | ----------- | --------------------------------------------------------- | ----------- | -------------------------------------------- | | `variant` | `"transparent" \| "default" \| "secondary" \| "tertiary"` | `"default"` | Semantic variant indicating prominence level | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Card content | ### Card.Header | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Header content | ### Card.Title | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Title content (renders as `h3`) | ### Card.Description | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ------------------------------------ | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Description content (renders as `p`) | ### Card.Content | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Main content | ### Card.Footer | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Footer content |
# Separator **Category**: react **URL**: https://v3.heroui.com/docs/react/components/separator **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(layout)/separator.mdx > Visually divide content sections ## Import ```tsx import { Separator } from '@heroui/react'; ``` ### Usage ```tsx import {Separator} from "@heroui/react"; export function Basic() { return (

HeroUI v3 Components

Beautiful, fast and modern React UI library.

Blog
Docs
Source
); } ``` ### Vertical ```tsx import {Separator} from "@heroui/react"; export function Vertical() { return (
Blog
Docs
Source
); } ``` ### With Content ```tsx import {Separator} from "@heroui/react"; const items = [ { iconUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/bell-small.png", subtitle: "Receive account activity updates", title: "Set Up Notifications", }, { iconUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/compass-small.png", subtitle: "Connect your browser to your account", title: "Set up Browser Extension", }, { iconUrl: "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/3dicons/mint-collective-small.png", subtitle: "Create your first collectible", title: "Mint Collectible", }, ]; export function WithContent() { return (
{items.map((item, index) => (
{item.title}

{item.title}

{item.subtitle}

{index < items.length - 1 && }
))}
); } ``` ### Surface Variants The Separator component adapts to different surface backgrounds for better visibility. ```tsx import {Separator, Surface} from "@heroui/react"; export function SurfaceVariants() { return (

Default Surface

Surface Content

Separator automatically detects default surface level.

Secondary Surface

Surface Content

Separator automatically detects secondary surface level.

Tertiary Surface

Surface Content

Separator automatically detects tertiary surface level.

Transparent Surface

Surface Content

Separator automatically detects transparent surface level.

); } ``` ## Related Components * **Card**: Content container with header, body, and footer * **Chip**: Compact elements for tags and filters * **Avatar**: Display user profile images ## Styling ### Passing Tailwind CSS classes ```tsx import {Separator} from '@heroui/react'; function CustomSeparator() { return ( ); } ``` ### Customizing the component classes To customize the Separator component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .separator { @apply bg-accent h-[2px]; } .separator--vertical { @apply bg-accent w-[2px]; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The Separator component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/separator.css)): #### Base & Orientation Classes * `.separator` - Base separator styles with default horizontal orientation * `.separator--horizontal` - Horizontal orientation (full width, 1px height) * `.separator--vertical` - Vertical orientation (full height, 1px width) ## API Reference ### Separator Props | Prop | Type | Default | Description | | ------------- | ---------------------------- | -------------- | -------------------------------- | | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | The orientation of the separator | | `className` | `string` | - | Additional CSS classes |
# Surface **Category**: react **URL**: https://v3.heroui.com/docs/react/components/surface **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(layout)/surface.mdx > Container component that provides surface-level styling and context for child components ## Import ```tsx import { Surface } from '@heroui/react'; ``` ### Usage ```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.

); } ``` ## Overview The Surface component is a semantic container that provides different levels of visual prominence through variants. ### Variants Surface comes in semantic variants that describe their prominence level: * **`default`** - Standard surface appearance (bg-surface) * **`secondary`** - Medium prominence (bg-surface-secondary) * **`tertiary`** - Higher prominence (bg-surface-tertiary) ## Usage with Form Components When using form components inside a Surface, use the `variant="secondary"` prop to apply the lower emphasis variant suitable for surface backgrounds. ```tsx import { Surface, Input, TextArea } from '@heroui/react'; function App() { return (