# 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

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 * 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 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/listbox **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(collections)/listbox.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
); } ``` ### 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"}
); } ``` ### On Surface ```tsx "use client"; import {Description, Label, Surface, Tag, TagGroup} from "@heroui/react"; export function TagGroupOnSurface() { return (
News Travel Gaming Tags on surface component
); } ``` ### 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 with field-on-background styling * `.tag--surface` - Surface variant with surface background * `.tag--on-surface` - On-surface variant for use on surface components #### Modifier Classes * `.tag__remove-button--on-surface` - Remove button modifier for on-surface variant #### 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 | | `isOnSurface` | `boolean` | - | Whether tags are displayed on a surface component | | `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`, and `isOnSurface` 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) | ### 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 |
# CheckboxGroup **Category**: react **URL**: https://v3.heroui.com/docs/react/components/checkbox-group **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/checkbox-group.mdx > A checkbox group component for managing multiple checkbox selections ## Import ```tsx import { CheckboxGroup, Checkbox, Label, Description } from '@heroui/react'; ``` ### Usage ```tsx import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react"; export function Basic() { return ( Choose all that apply Love building software Enjoy creating beautiful interfaces Passionate about content creation ); } ``` ### Anatomy Import the CheckboxGroup component and access all parts using dot notation. ```tsx import {CheckboxGroup, Checkbox, Label, Description, FieldError} from '@heroui/react'; export default () => ( ); ``` ### On Surface When used inside a [Surface](/docs/components/surface) component, CheckboxGroup automatically applies on-surface styling. ```tsx import {Checkbox, CheckboxGroup, Description, Label, Surface} from "@heroui/react"; export function OnSurface() { return ( Choose all that apply Love building software Enjoy creating beautiful interfaces Passionate about content creation ); } ``` ### With Custom Indicator ```tsx "use client"; import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react"; export function WithCustomIndicator() { return ( Select the features you want {({isSelected}) => isSelected ? ( ) : null } Receive updates via email {({isSelected}) => isSelected ? ( ) : null } Get weekly newsletters ); } ``` ### Indeterminate ```tsx "use client"; import {Checkbox, CheckboxGroup, Label} from "@heroui/react"; import {useState} from "react"; export function Indeterminate() { const [selected, setSelected] = useState(["coding"]); const allOptions = ["coding", "design", "writing"]; return (
0 && selected.length < allOptions.length} isSelected={selected.length === allOptions.length} name="select-all" onChange={(isSelected: boolean) => { setSelected(isSelected ? allOptions : []); }} >
); } ``` ### Controlled ```tsx "use client"; import {Checkbox, CheckboxGroup, Label} from "@heroui/react"; import {useState} from "react"; export function Controlled() { const [selected, setSelected] = useState(["coding", "design"]); return ( ); } ``` ### Validation ```tsx "use client"; import {Button, Checkbox, CheckboxGroup, FieldError, Form, Label} from "@heroui/react"; export function Validation() { return (
{ e.preventDefault(); const formData = new FormData(e.currentTarget); const values = formData.getAll("preferences"); alert(`Selected preferences: ${values.join(", ")}`); }} > Please select at least one notification method.
); } ``` ### Disabled ```tsx import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react"; export function Disabled() { return ( Feature selection is temporarily disabled This feature is coming soon This feature is coming soon ); } ``` ### Features and Add-ons Example ```tsx import {Bell, Comment, Envelope} from "@gravity-ui/icons"; import {Checkbox, CheckboxGroup, Description, Label} from "@heroui/react"; import clsx from "clsx"; export function FeaturesAndAddOns() { const addOns = [ { description: "Receive updates via email", icon: Envelope, title: "Email Notifications", value: "email", }, { description: "Get instant SMS notifications", icon: Comment, title: "SMS Alerts", value: "sms", }, { description: "Browser and mobile push alerts", icon: Bell, title: "Push Notifications", value: "push", }, ]; return (
Choose how you want to receive updates
{addOns.map((addon) => (
{addon.description}
))}
); } ``` ## Related Components * **Checkbox**: Binary choice input control * **Label**: Accessible label for form controls * **Fieldset**: Group related form controls with legends ## Styling ### Passing Tailwind CSS classes You can customize the CheckboxGroup component: ```tsx import { CheckboxGroup, Checkbox, Label } from '@heroui/react'; function CustomCheckboxGroup() { return ( ); } ``` ### Customizing the component classes To customize the CheckboxGroup component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .checkbox-group { @apply flex flex-col gap-2; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The CheckboxGroup component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/checkbox-group.css)): * `.checkbox-group` - Base checkbox group container ## API Reference ### CheckboxGroup Props Inherits from [React Aria CheckboxGroup](https://react-spectrum.adobe.com/react-aria/CheckboxGroup.html). | Prop | Type | Default | Description | | -------------- | -------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------- | | `value` | `string[]` | - | The current selected values (controlled) | | `defaultValue` | `string[]` | - | The default selected values (uncontrolled) | | `onChange` | `(value: string[]) => void` | - | Handler called when the selected values change | | `isDisabled` | `boolean` | `false` | Whether the checkbox group is disabled | | `isRequired` | `boolean` | `false` | Whether the checkbox group is required | | `isReadOnly` | `boolean` | `false` | Whether the checkbox group is read only | | `isInvalid` | `boolean` | `false` | Whether the checkbox group is in an invalid state | | `name` | `string` | - | The name of the checkbox group, used when submitting an HTML form | | `children` | `React.ReactNode \| (values: CheckboxGroupRenderProps) => React.ReactNode` | - | Checkbox group content or render prop | ### CheckboxGroupRenderProps When using the render prop pattern, these values are provided: | Prop | Type | Description | | ------------ | ---------- | ------------------------------------------------- | | `value` | `string[]` | The currently selected values | | `isDisabled` | `boolean` | Whether the checkbox group is disabled | | `isReadOnly` | `boolean` | Whether the checkbox group is read only | | `isInvalid` | `boolean` | Whether the checkbox group is in an invalid state | | `isRequired` | `boolean` | Whether the checkbox group is required |
# Checkbox **Category**: react **URL**: https://v3.heroui.com/docs/react/components/checkbox **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/checkbox.mdx > Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected. ## Import ```tsx import { Checkbox, Label } from '@heroui/react'; ``` ### Usage ```tsx import {Checkbox, Label} from "@heroui/react"; export function Basic() { return (
); } ``` ### Anatomy Import the Checkbox component and access all parts using dot notation. ```tsx import { Checkbox, Label, Description } from '@heroui/react'; export default () => ( ); ``` ### Disabled ```tsx import {Checkbox, Description, Label} from "@heroui/react"; export function Disabled() { return (
This feature is coming soon
); } ``` ### Default Selected ```tsx import {Checkbox, Label} from "@heroui/react"; export function DefaultSelected() { return (
); } ``` ### Controlled ```tsx "use client"; import {Checkbox, Label} from "@heroui/react"; import {useState} from "react"; export function Controlled() { const [isSelected, setIsSelected] = useState(true); return (

Status: {isSelected ? "Enabled" : "Disabled"}

); } ``` ### Indeterminate ```tsx "use client"; import {Checkbox, Description, Label} from "@heroui/react"; import {useState} from "react"; export function Indeterminate() { const [isIndeterminate, setIsIndeterminate] = useState(true); const [isSelected, setIsSelected] = useState(false); return (
{ setIsSelected(selected); setIsIndeterminate(false); }} >
Shows indeterminate state (dash icon)
); } ``` ### With Label ```tsx import {Checkbox, Label} from "@heroui/react"; export function WithLabel() { return ( ); } ``` ### With Description ```tsx import {Checkbox, Description, Label} from "@heroui/react"; export function WithDescription() { return (
Get notified when someone mentions you in a comment
); } ``` ### Render Props ```tsx "use client"; import {Checkbox, Description, Label} from "@heroui/react"; export function RenderProps() { return ( {({isSelected}) => ( <> {isSelected ? "Thank you for accepting" : "Please read and accept the terms"} )} ); } ``` ### Form Integration ```tsx "use client"; import {Button, Checkbox, Label} 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 (
); } ``` ### Invalid ```tsx import {Checkbox, Description, Label} from "@heroui/react"; export function Invalid() { return ( You must accept the terms to continue ); } ``` ### Custom Indicator ```tsx "use client"; import {Checkbox, Label} from "@heroui/react"; export function CustomIndicator() { return (
{({isSelected}) => isSelected ? ( ) : null } {({isSelected}) => isSelected ? ( ) : null } {({isIndeterminate}) => isIndeterminate ? ( ) : null }
); } ``` ### Full Rounded ```tsx import {Checkbox, Label} from "@heroui/react"; export function FullRounded() { return (
); } ``` ## Related Components * **Label**: Accessible label for form controls * **CheckboxGroup**: Group of checkboxes with shared state * **Description**: Helper text for form fields ## Styling ### Passing Tailwind CSS classes You can customize individual Checkbox components: ```tsx import { Checkbox, Label } from '@heroui/react'; function CustomCheckbox() { return ( ); } ``` ### Customizing the component classes To customize the Checkbox component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .checkbox { @apply inline-flex gap-3 items-center; } .checkbox__control { @apply size-5 border-2 border-gray-400 rounded data-[selected=true]:bg-blue-500 data-[selected=true]:border-blue-500; /* Animated background indicator */ &::before { @apply bg-accent pointer-events-none absolute inset-0 z-0 origin-center scale-50 rounded-md opacity-0 content-['']; transition: scale 200ms linear, opacity 200ms linear, background-color 200ms ease-out; } /* Show indicator when selected */ &[data-selected="true"]::before { @apply scale-100 opacity-100; } } .checkbox__indicator { @apply text-white; } .checkbox__content { @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 Checkbox component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/checkbox.css)): * `.checkbox` - Base checkbox container * `.checkbox__control` - Checkbox control box * `.checkbox__indicator` - Checkbox checkmark indicator * `.checkbox__content` - Optional content container ### Interactive States The checkbox supports both CSS pseudo-classes and data attributes for flexibility: * **Selected**: `[data-selected="true"]` or `[aria-checked="true"]` (shows checkmark and background color change) * **Indeterminate**: `[data-indeterminate="true"]` (shows indeterminate state with dash) * **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` (shows error state with danger colors) * **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 ### Checkbox Props Inherits from [React Aria Checkbox](https://react-spectrum.adobe.com/react-aria/Checkbox.html). | Prop | Type | Default | Description | | ----------------- | --------------------------------------------------------------------- | ------- | ----------------------------------------------------------------- | | `isSelected` | `boolean` | `false` | Whether the checkbox is checked | | `defaultSelected` | `boolean` | `false` | Whether the checkbox is checked by default (uncontrolled) | | `isIndeterminate` | `boolean` | `false` | Whether the checkbox is in an indeterminate state | | `isDisabled` | `boolean` | `false` | Whether the checkbox is disabled | | `isInvalid` | `boolean` | `false` | Whether the checkbox is invalid | | `isReadOnly` | `boolean` | `false` | Whether the checkbox is read only | | `isOnSurface` | `boolean` | `false` | Whether the checkbox is displayed on a surface (affects styling) | | `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 checkbox value changes | | `children` | `React.ReactNode \| (values: CheckboxRenderProps) => React.ReactNode` | - | Checkbox content or render prop | ### CheckboxRenderProps When using the render prop pattern, these values are provided: | Prop | Type | Description | | ----------------- | --------- | ------------------------------------------------- | | `isSelected` | `boolean` | Whether the checkbox is currently checked | | `isIndeterminate` | `boolean` | Whether the checkbox is in an indeterminate state | | `isHovered` | `boolean` | Whether the checkbox is hovered | | `isPressed` | `boolean` | Whether the checkbox is currently pressed | | `isFocused` | `boolean` | Whether the checkbox is focused | | `isFocusVisible` | `boolean` | Whether the checkbox is keyboard focused | | `isDisabled` | `boolean` | Whether the checkbox is disabled | | `isReadOnly` | `boolean` | Whether the checkbox is read only |
# DateField **Category**: react **URL**: https://v3.heroui.com/docs/react/components/date-field **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/date-field.mdx > Date input field with labels, descriptions, and validation built on React Aria DateField ## Import ```tsx import { DateField } from '@heroui/react'; ``` ### Usage ```tsx "use client"; import {DateField, DateInputGroup, Label} from "@heroui/react"; export function Basic() { return ( {(segment) => } ); } ``` ### Anatomy ```tsx import {DateField, Label, DateInputGroup, Description, FieldError} from '@heroui/react'; export default () => ( ) ``` > **DateField** combines label, date input, description, and error into a single accessible component. ### With Description ```tsx "use client"; import {DateField, DateInputGroup, Description, Label} from "@heroui/react"; export function WithDescription() { return (
{(segment) => } Enter your date of birth {(segment) => } Enter a date for your appointment
); } ``` ### Required Field ```tsx "use client"; import {DateField, DateInputGroup, Description, Label} from "@heroui/react"; export function Required() { return (
{(segment) => } {(segment) => } Required field
); } ``` ### Validation Use `isInvalid` together with `FieldError` to surface validation messages. ```tsx "use client"; import {DateField, DateInputGroup, FieldError, Label} from "@heroui/react"; export function Invalid() { return (
{(segment) => } Please enter a valid date {(segment) => } Date must be in the future
); } ``` ### With Validation DateField supports validation with `minValue`, `maxValue`, and custom validation logic. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {DateField, DateInputGroup, Description, FieldError, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function WithValidation() { const [value, setValue] = useState(null); const todayDate = today(getLocalTimeZone()); const isInvalid = value !== null && value.compare(todayDate) < 0; return (
{(segment) => } {isInvalid ? ( Date must be today or in the future ) : ( Enter a date from today onwards )}
); } ``` ### Controlled Control the value to synchronize with other components or state management. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Button, DateField, DateInputGroup, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function Controlled() { const [value, setValue] = useState(null); return (
{(segment) => } Current value: {value ? value.toString() : "(empty)"}
); } ``` ### Disabled State ```tsx "use client"; import {DateField, DateInputGroup, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; export function Disabled() { return (
{(segment) => } This date field is disabled {(segment) => } This date field is disabled
); } ``` ### With Icons Add prefix or suffix icons to enhance the date field. ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, DateInputGroup, Label} from "@heroui/react"; export function WithPrefixIcon() { return ( {(segment) => } ); } ``` ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, DateInputGroup, Label} from "@heroui/react"; export function WithSuffixIcon() { return ( {(segment) => } ); } ``` ```tsx "use client"; import {Calendar, ChevronDown} from "@gravity-ui/icons"; import {DateField, DateInputGroup, Description, Label} from "@heroui/react"; export function WithPrefixAndSuffix() { return ( {(segment) => } Enter a date ); } ``` ### Full Width ```tsx "use client"; import {Calendar, ChevronDown} from "@gravity-ui/icons"; import {DateField, DateInputGroup, Label} from "@heroui/react"; export function FullWidth() { return (
{(segment) => } {(segment) => }
); } ``` ### On Surface When used inside a [Surface](/docs/components/surface) component, DateField and its child DateInputGroup automatically apply on-surface styling. ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, DateInputGroup, Description, Label, Surface} from "@heroui/react"; export function OnSurface() { return ( {(segment) => } Enter a date {(segment) => } Enter a date for your appointment ); } ``` ### Form Example Complete form example with validation and submission handling. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Calendar} from "@gravity-ui/icons"; import { Button, DateField, DateInputGroup, Description, FieldError, Form, Label, } from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function FormExample() { const [value, setValue] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const todayDate = today(getLocalTimeZone()); const isInvalid = value !== null && value.compare(todayDate) < 0; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!value || isInvalid) { return; } setIsSubmitting(true); // Simulate API call setTimeout(() => { console.log("Date submitted:", {date: value}); setValue(null); setIsSubmitting(false); }, 1500); }; return (
{(segment) => } {isInvalid ? ( Date must be today or in the future ) : ( Enter a date from today onwards )}
); } ``` ## Related Components * **Label**: Accessible label for form controls * **FieldError**: Inline validation messages for form fields * **Description**: Helper text for form fields ## Styling ### Passing Tailwind CSS classes ```tsx import {DateField, Label, DateInputGroup, Description} from '@heroui/react'; function CustomDateField() { return ( {(segment) => } Select a date for your appointment. ); } ``` ### Customizing the component classes DateField has minimal default styling. Override the `.date-field` class to customize the container styling. ```css @layer components { .date-field { @apply flex flex-col gap-1; &[data-invalid="true"], &[aria-invalid="true"] { [data-slot="description"] { @apply hidden; } } [data-slot="label"] { @apply w-fit; } [data-slot="description"] { @apply px-1; } } } ``` ### CSS Classes * `.date-field` – Root container with minimal styling (`flex flex-col gap-1`) > **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options. DateInputGroup styling is documented below in the API Reference section. ### Interactive States DateField automatically manages these data attributes based on its state: * **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid * **Required**: `[data-required="true"]` - Applied when `isRequired` is true * **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true * **Focus Within**: `[data-focus-within="true"]` - Applied when any child input is focused ## API Reference ### DateField Props DateField inherits all props from React Aria's [DateField](https://react-aria.adobe.com/DateField.md) component. #### Base Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------ | | `children` | `React.ReactNode \| (values: DateFieldRenderProps) => React.ReactNode` | - | Child components (Label, DateInputGroup, etc.) or render function. | | `className` | `string \| (values: DateFieldRenderProps) => string` | - | CSS classes for styling, supports render props. | | `style` | `React.CSSProperties \| (values: DateFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. | | `fullWidth` | `boolean` | `false` | Whether the date field should take full width of its container | | `id` | `string` | - | The element's unique identifier. | #### Value Props | Prop | Type | Default | Description | | ------------------ | ------------------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------- | | `value` | `DateValue \| null` | - | Current value (controlled). Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `defaultValue` | `DateValue \| null` | - | Default value (uncontrolled). Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `onChange` | `(value: DateValue \| null) => void` | - | Handler called when the value changes. | | `placeholderValue` | `DateValue \| null` | - | Placeholder date that influences the format of the placeholder. | #### Validation Props | Prop | Type | Default | Description | | -------------------- | -------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `isRequired` | `boolean` | `false` | Whether user input is required before form submission. | | `isInvalid` | `boolean` | - | Whether the value is invalid. | | `minValue` | `DateValue \| null` | - | The minimum allowed date that a user may select. Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `maxValue` | `DateValue \| null` | - | The maximum allowed date that a user may select. Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `isDateUnavailable` | `(date: DateValue) => boolean` | - | Callback that is called for each date. If it returns true, the date is unavailable. | | `validate` | `(value: DateValue) => ValidationError \| true \| null \| undefined` | - | Custom validation function. | | `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. | #### Format Props | Prop | Type | Default | Description | | ------------------------- | ------------- | ------- | -------------------------------------------------------------------------------------------- | | `granularity` | `Granularity` | - | Determines the smallest unit displayed. Defaults to `"day"` for dates, `"minute"` for times. | | `hourCycle` | `12 \| 24` | - | Whether to display time in 12 or 24 hour format. By default, determined by locale. | | `hideTimeZone` | `boolean` | `false` | Whether to hide the time zone abbreviation. | | `shouldForceLeadingZeros` | `boolean` | - | Whether to always show leading zeros in month, day, and hour fields. | #### State Props | Prop | Type | Default | Description | | ------------ | --------- | ------- | -------------------------------------------------- | | `isDisabled` | `boolean` | - | Whether the input is disabled. | | `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. | #### Form Props | Prop | Type | Default | Description | | -------------- | --------- | ------- | -------------------------------------------------------------------------------- | | `name` | `string` | - | Name of the input element, for HTML form submission. Submits as ISO 8601 string. | | `autoFocus` | `boolean` | - | Whether the element should receive focus on render. | | `autoComplete` | `string` | - | Type of autocomplete functionality the input should provide. | #### Accessibility Props | Prop | Type | Default | Description | | ------------------ | -------- | ------- | ----------------------------------------------------- | | `aria-label` | `string` | - | Accessibility label when no visible label is present. | | `aria-labelledby` | `string` | - | ID of elements that label this field. | | `aria-describedby` | `string` | - | ID of elements that describe this field. | | `aria-details` | `string` | - | ID of elements with additional details. | ### Composition Components DateField works with these separate components that should be imported and used directly: * **Label** - Field label component from `@heroui/react` * **DateInputGroup** - Date input component with segmented editing from `@heroui/react` (documented below) * **Description** - Helper text component from `@heroui/react` * **FieldError** - Validation error message from `@heroui/react` Each of these components has its own props API. Use them directly within DateField for composition: ```tsx import {parseDate} from '@internationalized/date'; import {DateField, Label, DateInputGroup, Description, FieldError} from '@heroui/react'; {(segment) => } Select a date from today onwards. Please select a valid date. ``` ### DateValue Types DateField uses types from [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/): * `CalendarDate` - Date without time or timezone * `CalendarDateTime` - Date with time but no timezone * `ZonedDateTime` - Date with time and timezone * `Time` - Time only Example: ```tsx import {parseDate, today, getLocalTimeZone} from '@internationalized/date'; // Parse from string const date = parseDate('2024-01-15'); // Today's date const todayDate = today(getLocalTimeZone()); // Use in DateField {/* ... */} ``` > **Note:** DateField uses the [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) package for date manipulation, parsing, and type definitions. See the [Internationalized Date documentation](https://react-aria.adobe.com/internationalized/date/) for more information about available types and functions. ### DateFieldRenderProps When using render props with `className`, `style`, or `children`, these values are available: | Prop | Type | Description | | ---------------- | --------- | ----------------------------------------------- | | `isDisabled` | `boolean` | Whether the field is disabled. | | `isInvalid` | `boolean` | Whether the field is currently invalid. | | `isReadOnly` | `boolean` | Whether the field is read-only. | | `isRequired` | `boolean` | Whether the field is required. | | `isFocused` | `boolean` | Whether the field is currently focused. | | `isFocusWithin` | `boolean` | Whether any child element is focused. | | `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). | ### DateInputGroup Props DateInputGroup accepts all props from React Aria's `Group` component plus the following: | Prop | Type | Default | Description | | ------------- | --------- | ------- | -------------------------------------------------------------------- | | `className` | `string` | - | Tailwind classes merged with the component styles. | | `fullWidth` | `boolean` | `false` | Whether the date input group should take full width of its container | | `isOnSurface` | `boolean` | `false` | Whether the input is displayed on a surface (affects styling) | ### DateInputGroup.Input Props DateInputGroup.Input accepts all props from React Aria's `DateInput` component plus the following: | Prop | Type | Default | Description | | ------------- | --------- | ------- | ------------------------------------------------------------- | | `className` | `string` | - | Tailwind classes merged with the component styles. | | `isOnSurface` | `boolean` | `false` | Whether the input is displayed on a surface (affects styling) | The `DateInput` component accepts a render prop function that receives date segments. Each segment represents a part of the date (year, month, day, etc.). ### DateInputGroup.Segment Props DateInputGroup.Segment accepts all props from React Aria's `DateSegment` component: | Prop | Type | Default | Description | | ----------- | ------------- | ------- | ------------------------------------------------------- | | `segment` | `DateSegment` | - | The date segment object from the DateInput render prop. | | `className` | `string` | - | Tailwind classes merged with the component styles. | ### DateInputGroup.Prefix Props DateInputGroup.Prefix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | | ----------- | ----------- | ------- | -------------------------------------------------- | | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the prefix slot. | ### DateInputGroup.Suffix Props DateInputGroup.Suffix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | | ----------- | ----------- | ------- | -------------------------------------------------- | | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the suffix slot. | ## DateInputGroup Styling ### Customizing the component classes The base classes power every instance. Override them once with `@layer components`. ```css @layer components { .date-input-group { @apply inline-flex h-9 items-center overflow-hidden rounded-field border bg-field text-sm text-field-foreground shadow-field outline-none; &:hover, &[data-hovered="true"] { @apply bg-field-hover; } &[data-focus-within="true"], &:focus-within { @apply status-focused-field; } &[data-invalid="true"] { @apply status-invalid-field; } &[data-disabled="true"], &[aria-disabled="true"] { @apply status-disabled; } } .date-input-group__input { @apply flex flex-1 items-center gap-px rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none; } .date-input-group__segment { @apply inline-block rounded-md px-0.5 text-end tabular-nums outline-none; &:focus, &[data-focused="true"] { @apply bg-accent-soft text-accent-soft-foreground; } } .date-input-group__prefix, .date-input-group__suffix { @apply pointer-events-none shrink-0 text-field-placeholder flex items-center; } } ``` ### DateInputGroup CSS Classes * `.date-input-group` – Root container styling * `.date-input-group__input` – Input wrapper styling * `.date-input-group__segment` – Individual date segment styling * `.date-input-group__prefix` – Prefix element styling * `.date-input-group__suffix` – Suffix element styling ### DateInputGroup Interactive States * **Hover**: `:hover` or `[data-hovered="true"]` * **Focus Within**: `[data-focus-within="true"]` or `:focus-within` * **Invalid**: `[data-invalid="true"]` (also syncs with `aria-invalid`) * **Disabled**: `[data-disabled="true"]` or `[aria-disabled="true"]` * **Segment Focus**: `:focus` or `[data-focused="true"]` on segment elements * **Segment Placeholder**: `[data-placeholder="true"]` on segment elements
# Description **Category**: react **URL**: https://v3.heroui.com/docs/react/components/description **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/description.mdx > Provides supplementary text for form fields and other components ## Import ```tsx import { Description } from '@heroui/react'; ``` ## Usage ```tsx import {Description, Input, Label} from "@heroui/react"; export function Basic() { return (
We'll never share your email with anyone else.
); } ``` ## Related Components * **TextField**: Composition-friendly fields with labels and validation * **Input**: Single-line text input built on React Aria * **TextArea**: Multiline text input with focus management ## API ### Description Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ------------------------------ | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | The content of the description | ## Accessibility The Description component enhances accessibility by: * Using semantic HTML that screen readers can identify * Providing the `slot="description"` attribute for React Aria integration * Supporting proper text contrast ratios ## Styling The Description component uses the following CSS classes: * `.description` - Base description styles with `muted` text color ## Examples ### With Form Fields ```tsx
Must be at least 8 characters with one uppercase letter
``` ### Integration with TextField ```tsx import {TextField, Label, Input, Description} from '@heroui/react'; We'll never share your email ``` When using the [TextField](./text-field) component, accessibility attributes are automatically applied to the label and description.
# ErrorMessage **Category**: react **URL**: https://v3.heroui.com/docs/react/components/error-message **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/error-message.mdx > A low-level error message component for displaying errors ## Import ```tsx import { ErrorMessage } from '@heroui/react'; ``` ## Usage `ErrorMessage` is a low-level component built on React Aria's `Text` component with an `errorMessage` slot. It's designed for displaying error messages in **non-form components** such as `TagGroup`, `Calendar`, and other collection-based components. ```tsx "use client"; import type {Key} from "@heroui/react"; import {Description, ErrorMessage, Label, Tag, TagGroup} from "@heroui/react"; import {useMemo, useState} from "react"; export function ErrorMessageBasic() { const [selected, setSelected] = useState>(new Set()); const isInvalid = useMemo(() => Array.from(selected).length === 0, [selected]); return ( setSelected(keys)} > News Travel Gaming Shopping Select at least one category {!!isInvalid && <>Please select at least one category} ); } ``` ### Anatomy ```tsx import { TagGroup, Tag, Label, Description, ErrorMessage } from '@heroui/react'; ``` ## Related Components * **TagGroup**: Focusable list of tags with selection and removal support ## When to Use `ErrorMessage` is **not tied to forms**. It's a generic error display component for non-form contexts. * **Recommended for** non-form components (e.g., `TagGroup`, `Calendar`, collection components) * **For form fields**, we recommend using [`FieldError`](/docs/components/field-error) instead, which provides form-specific validation features and automatic error handling, following standardized form validation patterns. ## ErrorMessage vs FieldError | Component | Use Case | Form Integration | Example Components | | -------------- | ------------------------- | ---------------- | ------------------------------------ | | `ErrorMessage` | Non-form components | No | `TagGroup`, `Calendar` | | `FieldError` | Form fields (recommended) | Yes | `TextField`, `NumberField`, `Select` | For form validation, we recommend using `FieldError` as it follows standardized form validation patterns and provides form-specific features. See the [FieldError documentation](/docs/components/field-error) and the [Form guide](/docs/components/form) for examples and best practices. ## API Reference ### ErrorMessage Props | Prop | Type | Default | Description | | ----------- | ----------- | ------- | ------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode` | - | The error message content | **Note**: `ErrorMessage` is built on React Aria's `Text` component with `slot="errorMessage"`. It can be targeted using the `[slot=errorMessage]` CSS selector. ## Accessibility The ErrorMessage component enhances accessibility by: * Using semantic HTML that screen readers can identify * Providing the `slot="errorMessage"` attribute for React Aria integration * Supporting proper text contrast ratios for error states * Following WAI-ARIA best practices for error messaging ## Styling ### Passing Tailwind CSS classes ```tsx import { ErrorMessage } from '@heroui/react'; function CustomErrorMessage() { return ( Custom styled error message ); } ``` ### Customizing the component classes To customize the ErrorMessage component classes, you can use the `@layer components` directive.
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes). ```css @layer components { .error-message { @apply text-red-600 text-sm font-medium; } } ``` HeroUI follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize. ### CSS Classes The ErrorMessage component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/error-message.css)): #### Base Classes * `.error-message` - Base error message styles with danger color and text truncation #### Slot Classes * `[slot="errorMessage"]` - ErrorMessage slot styles for React Aria integration
# FieldError **Category**: react **URL**: https://v3.heroui.com/docs/react/components/field-error **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/field-error.mdx > Displays validation error messages for form fields ## Import ```tsx import { FieldError } from '@heroui/react'; ``` ## Usage The FieldError component displays validation error messages for form fields. It automatically appears when the parent field is marked as invalid and provides smooth opacity transitions. ```tsx "use client"; import {FieldError, Input, Label, TextField} from "@heroui/react"; import {useState} from "react"; export function Basic() { const [value, setValue] = useState("jr"); const isInvalid = value.length > 0 && value.length < 3; return ( setValue(e.target.value)} /> Username must be at least 3 characters ); } ``` ## Related Components * **TextField**: Composition-friendly fields with labels and validation * **Input**: Single-line text input built on React Aria * **TextArea**: Multiline text input with focus management ## API ### FieldError Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------ | ------- | ---------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `ReactNode \| ((validation: ValidationResult) => ReactNode)` | - | Error message content or render function | ## Accessibility The FieldError component ensures accessibility by: * Using proper ARIA attributes for error announcement * Supporting screen readers with semantic HTML * Providing visual and programmatic error indication * Automatically managing visibility based on validation state ## Styling The FieldError component uses the following CSS classes: * `.field-error` - Base error styles with danger color * Only shows when the `data-visible` attribute is present * Text is truncated with ellipsis for long messages ## Examples ### Basic Validation ```tsx export function Basic() { const [value, setValue] = useState(""); const isInvalid = value.length > 0 && value.length < 3; return ( setValue(e.target.value)} /> Username must be at least 3 characters ); } ``` ### With Dynamic Messages ```tsx 0}> {(validation) => validation.validationErrors.join(', ')} ``` ### Custom Validation Logic ```tsx function EmailField() { const [email, setEmail] = useState(''); const isInvalid = email.length > 0 && !email.includes('@'); return ( setEmail(e.target.value)} /> Email must include @ symbol ); } ``` ### Multiple Error Messages ```tsx {errors.map((error, i) => (
{error}
))}
```
# Fieldset **Category**: react **URL**: https://v3.heroui.com/docs/react/components/fieldset **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/fieldset.mdx > Group related form controls with legends, descriptions, and actions ## Import ```tsx import { Fieldset } from '@heroui/react'; ``` ### Usage ```tsx "use client"; import {FloppyDisk} from "@gravity-ui/icons"; import { Button, Description, FieldError, FieldGroup, Fieldset, Form, Input, Label, TextArea, TextField, } from "@heroui/react"; export function Basic() { const onSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget); const data: Record = {}; // Convert FormData to plain object formData.forEach((value, key) => { data[key] = value.toString(); }); alert("Form submitted successfully!"); }; return (
Profile Settings Update your profile information. { if (value.length < 3) { return "Name must be at least 3 characters"; } return null; }} > { if (value.length < 10) { return "Bio must be at least 10 characters"; } return null; }} >