Documentation for all components in Chakra UI v3.
# AbsoluteCenter
```tsx
import { AbsoluteCenter, Box } from "@chakra-ui/react"
export const AbsoluteCenterBasic = () => {
return (
Centered Content
)
}
```
## Usage
The `AbsoluteCenter` component uses the `position: absolute` strategy to center
its child element relative to its parent.
> The parent element must have `position: relative` for proper positioning.
```jsx
import { AbsoluteCenter } from "@chakra-ui/react"
```
```jsx
Centered Content
```
## Examples
### Axis Control
Control which axis to center on using the `axis` prop. Options are `horizontal`,
`vertical`, or `both` (default).
```tsx
import { AbsoluteCenter, Box, For, Text, VStack } from "@chakra-ui/react"
export const AbsoluteCenterWithAxis = () => {
return (
{(axis) => (
{``}
{axis}
)}
)
}
```
### With Content
Use `AbsoluteCenter` with various content types like icons, badges, and status
indicators.
```tsx
import { AbsoluteCenter, Box } from "@chakra-ui/react"
import { LuHeart } from "react-icons/lu"
export const AbsoluteCenterWithContent = () => {
return (
)
}
```
### Overlay Usage
Perfect for creating loading overlays or modal-like content that needs to be
centered over existing content.
```tsx
import { AbsoluteCenter, Box, HStack, Spinner, Text } from "@chakra-ui/react"
const Overlay = () => (
Loading...
)
export const AbsoluteCenterWithOverlay = () => {
return (
Some content that is being loaded...
)
}
```
### RTL Support
`AbsoluteCenter` automatically handles right-to-left (RTL) layouts by adjusting
the horizontal positioning and transforms appropriately.
```tsx
import {
AbsoluteCenter,
Box,
For,
HStack,
Span,
Text,
VStack,
} from "@chakra-ui/react"
export const AbsoluteCenterWithRtl = () => {
return (
{(axis) => (
RTL ({axis})البداية
)}
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| axis | undefined | `'horizontal' \| 'vertical' \| 'both' \| undefined` | undefined |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Accordion
```tsx
import { Accordion, Span } from "@chakra-ui/react"
export const AccordionBasic = () => {
return (
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{ value: "a", title: "First Item", text: "Some value 1..." },
{ value: "b", title: "Second Item", text: "Some value 2..." },
{ value: "c", title: "Third Item", text: "Some value 3..." },
]
```
## Usage
```tsx
import { Accordion } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Controlled
Set the accordion that shows up by default.
```tsx
"use client"
import { Accordion, Span, Stack, Text } from "@chakra-ui/react"
import { useState } from "react"
export const AccordionControlled = () => {
const [value, setValue] = useState(["second-item"])
return (
Expanded: {value.join(", ")} setValue(e.value)}>
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{ value: "first-item", title: "First Item", text: "Some value 1..." },
{ value: "second-item", title: "Second Item", text: "Some value 2..." },
{ value: "third-item", title: "Third Item", text: "Some value 3..." },
]
```
### With Icon
Here's an example of rendering a custom icon in each accordion item.
```tsx
import { Accordion, Heading, Icon, Stack } from "@chakra-ui/react"
import { LuChartBarStacked, LuTags } from "react-icons/lu"
export const AccordionWithIcon = () => {
return (
Product details
{items.map((item) => (
{item.icon}
{item.title}
{item.content}
))}
)
}
const items = [
{
value: "info",
icon: ,
title: "Product Info",
content:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec odio vel dui euismod fermentum.",
},
{
value: "stats",
icon: ,
title: "Stats",
content:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec odio vel dui euismod fermentum.",
},
]
```
### Expand Multiple Items
Use the `multiple` prop to allow multiple items to be expanded at once.
```tsx
import { Accordion, Span } from "@chakra-ui/react"
export const AccordionWithMultiple = () => {
return (
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{ value: "a", title: "First Item", text: "Some value 1..." },
{ value: "b", title: "Second Item", text: "Some value 2..." },
{ value: "c", title: "Third Item", text: "Some value 3..." },
]
```
### Sizes
Use the `size` prop to change the size of the accordion.
```tsx
import { Accordion, For, Span, Stack, Text } from "@chakra-ui/react"
export const AccordionSizes = () => {
return (
{(size) => (
{size}
{items.map((item, index) => (
{item.title}{item.text}
))}
)}
)
}
const items = [
{ value: "a", title: "First Item", text: "Some value 1..." },
{ value: "b", title: "Second Item", text: "Some value 2..." },
{ value: "c", title: "Third Item", text: "Some value 3..." },
]
```
### Variants
Use the `variant` prop to change the visual style of the accordion. Values can
be either `outline`, `subtle`, `enclosed` or `plain`.
```tsx
import { Accordion, For, Span, Stack, Text } from "@chakra-ui/react"
export const AccordionVariants = () => {
return (
{(variant) => (
{variant}
{items.map((item, index) => (
{item.title}{item.text}
))}
)}
)
}
const items = [
{ value: "a", title: "First Item", text: "Some value 1..." },
{ value: "b", title: "Second Item", text: "Some value 2..." },
{ value: "c", title: "Third Item", text: "Some value 3..." },
]
```
### Disabled Item
Pass the `disabled` prop to any `Accordion.Item` to prevent it from being
expanded or collapsed.
```tsx
import { Accordion, Span } from "@chakra-ui/react"
export const AccordionWithDisabledItem = () => {
return (
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{ value: "a", title: "First Item", text: "Some value 1..." },
{ value: "b", title: "Second Item", text: "Some value 2..." },
{ value: "c", title: "Third Item", text: "Some value 3...", disabled: true },
]
```
### With Avatar
Here's an example of composing an accordion with an avatar.
```tsx
import { Accordion, Avatar, Badge, HStack } from "@chakra-ui/react"
import { LuTrophy } from "react-icons/lu"
import { LoremIpsum } from "react-lorem-ipsum"
export const AccordionWithAvatar = () => {
return (
{items.map((item, index) => (
{item.name}{" "}
{item.topRated && (
Top Rated
)}
{item.bio}
))}
)
}
const items = [
{
name: "Alex",
bio: ,
image: "https://i.pravatar.cc/150?u=a",
topRated: false,
},
{
name: "Benji",
bio: ,
image: "https://i.pravatar.cc/150?u=b",
topRated: true,
},
{
name: "Charlie",
bio: ,
image: "https://i.pravatar.cc/150?u=c",
topRated: false,
},
]
```
### With Subtext
Here's an example of adding a subtext to an accordion item.
```tsx
import { Accordion, Stack, Text } from "@chakra-ui/react"
import { LoremIpsum } from "react-lorem-ipsum"
const items = [
{ value: "a", title: "First Item", text: },
{ value: "b", title: "Second Item", text: },
{ value: "c", title: "Third Item", text: },
]
export const AccordionWithSubtext = () => {
return (
{items.map((item, index) => (
{item.title}
Click to expand
{item.text}
))}
)
}
```
### With Actions
Here's an example of adding actions to an accordion item trigger.
```tsx
import { AbsoluteCenter, Accordion, Box, Button, Span } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const AccordionWithActions = () => {
return (
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{ value: "a", title: "First Item", text: },
{ value: "b", title: "Second Item", text: },
{ value: "c", title: "Third Item", text: },
]
```
### Styling Expanded Style
Pass the `_open` pseudo selector to the `Accordion.ItemTrigger` or
`Accordion.Item` to attach styles to it when expanded.
```tsx
import { Accordion, Span } from "@chakra-ui/react"
export const AccordionWithExpandedStyle = () => {
return (
{items.map((item, index) => (
{item.title}{item.text}
))}
)
}
const items = [
{
value: "a",
title: "First Item",
text: "Click the accordion button to see a different style when expanded.",
},
{
value: "b",
title: "Second Item",
text: "The trigger background changes to teal with white text when expanded.",
},
{
value: "c",
title: "Third Item",
text: "You can use any style props with the _open pseudo selector.",
},
]
```
## Guides
### Accessing Root State
Use `useAccordionContext` to access the accordion state at the root level:
```tsx
import { useAccordionContext } from "@chakra-ui/react"
const AccordionValueText = () => {
const accordion = useAccordionContext()
return Opened: {accordion.value.join(", ")}
}
// Usage
const Demo = () => (
{/* ... accordion items */}
)
```
### Accessing Item State
Use `useAccordionItemContext` to access the state of a specific accordion item:
```tsx
import { useAccordionItemContext } from "@chakra-ui/react"
const AccordionItemStatus = () => {
const item = useAccordionItemContext()
return (
{item.open ? "Expanded" : "Collapsed"}
)
}
// Usage
const Demo = () => (
Content
)
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| collapsible | false | `boolean` | Whether an accordion item can be closed after it has been expanded. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| multiple | false | `boolean` | Whether multiple accordion items can be expanded at the same time. |
| orientation | "vertical" | `'horizontal' \| 'vertical'` | The orientation of the accordion items. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | outline | `'outline' \| 'subtle' \| 'enclosed' \| 'plain'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultValue | undefined | `string[]` | The initial value of the expanded accordion items.
Use when you don't need to control the value of the accordion. |
| disabled | undefined | `boolean` | Whether the accordion items are disabled |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n item: (value: string) => string\n itemContent: (value: string) => string\n itemTrigger: (value: string) => string\n}>` | The ids of the elements in the accordion. Useful for composition. |
| onFocusChange | undefined | `(details: FocusChangeDetails) => void` | The callback fired when the focused accordion item changes. |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | The callback fired when the state of expanded/collapsed accordion items changes. |
| value | undefined | `string[]` | The controlled value of the expanded accordion items. |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | undefined | `string` | The value of the accordion item. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| disabled | undefined | `boolean` | Whether the accordion item is disabled. |
## Explorer
Explore the `Accordion` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Action Bar
```tsx
"use client"
import { ActionBar, Button, Checkbox, Portal } from "@chakra-ui/react"
import { useState } from "react"
import { LuShare, LuTrash2 } from "react-icons/lu"
export const ActionBarBasic = () => {
const [checked, setChecked] = useState(false)
return (
<>
setChecked(!!e.checked)}>
Show Action bar
2 selected
>
)
}
```
## Usage
The action bar is designed to be controlled by table or checkbox selections. It
provides a set of actions that can be performed on the selected items.
```tsx
import { ActionBar } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Close Trigger
Render the `ActionBar.CloseTrigger` to close the action bar, and pass the
`onOpenChange` handler to control the visibility of the action bar.
> The `open` and `onOpenChange` props control the visibility of the action bar.
```tsx
"use client"
import {
ActionBar,
Button,
Checkbox,
CloseButton,
Portal,
} from "@chakra-ui/react"
import { useState } from "react"
import { LuShare, LuTrash2 } from "react-icons/lu"
export const ActionBarWithCloseTrigger = () => {
const [checked, setChecked] = useState(false)
return (
<>
setChecked(!!e.checked)}
>
Show Action bar setChecked(e.open)}
closeOnInteractOutside={false}
>
2 selected
>
)
}
```
### Within Dialog
Here's an example of composing the `ActionBar` and the `Dialog` to perform a
delete action on a set of selected items.
> Press the `Delete projects` button to open the dialog.
```tsx
"use client"
import { ActionBar, Button, Checkbox, Dialog, Portal } from "@chakra-ui/react"
import { useState } from "react"
import { LuSquarePlus, LuTrash2 } from "react-icons/lu"
export const ActionBarWithDialog = () => {
const [checked, setChecked] = useState(false)
return (
<>
setChecked(!!e.checked)}>
Check to select projects
4 selected
Delete projects
Are you sure you want to delete 4 projects?
>
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| autoFocus | true | `boolean` | Whether to automatically set focus on the first focusable
content within the popover when opened. |
| closeOnEscape | true | `boolean` | Whether to close the popover when the escape key is pressed. |
| closeOnInteractOutside | true | `boolean` | Whether to close the popover when the user clicks outside of the popover. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| modal | false | `boolean` | Whether the popover should be modal. When set to `true`:
- interaction with outside elements will be disabled
- only popover content will be visible to screen readers
- scrolling is blocked
- focus is trapped within the popover |
| portalled | true | `boolean` | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position
of the popover content. |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultOpen | undefined | `boolean` | The initial open state of the popover when rendered.
Use when you don't need to control the open state of the popover. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n anchor: string\n trigger: string\n content: string\n title: string\n description: string\n closeTrigger: string\n positioner: string\n arrow: string\n}>` | The ids of the elements in the popover. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| initialFocusEl | undefined | `() => HTMLElement \| null` | The element to focus on when the popover is opened. |
| onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function invoked when the popover opens or closes |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| open | undefined | `boolean` | The controlled open state of the popover |
| persistentElements | undefined | `(() => Element \| null)[]` | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| positioning | undefined | `PositioningOptions` | The user provided options used to position the popover content |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
# Alert
```tsx
import { Alert } from "@chakra-ui/react"
export const AlertBasic = () => {
return (
This is the alert title
)
}
```
## Usage
```jsx
import { Alert } from "@chakra-ui/react"
```
```jsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Description
Render the `Alert.Description` component to provide additional context to the
alert.
```tsx
import { Alert } from "@chakra-ui/react"
export const AlertWithDescription = () => {
return (
Invalid Fields
Your form has some errors. Please fix them and try again.
)
}
```
### Status
Change the status of the alerts by passing the `status` prop. This affects the
color scheme and icon used. Alert supports `error`, `success`, `warning`, and
`info` statuses.
```tsx
import { Alert, Stack } from "@chakra-ui/react"
export const AlertWithStatus = () => {
return (
There was an error processing your request
Chakra is going live on August 30th. Get ready!
Seems your account is about expire, upgrade now
Data uploaded to the server. Fire on!
)
}
```
### Variants
Use the `variant` prop to change the visual style of the alert. Values can be
either `subtle`, `solid`, `outline`
```tsx
import { Alert, Stack } from "@chakra-ui/react"
export const AlertWithVariants = () => {
return (
Data uploaded to the server. Fire on!Data uploaded to the server. Fire on!Data uploaded to the server. Fire on!
)
}
```
### With Close Button
Here's and example of how to compose the `Alert` with a close button.
```tsx
import { Alert, CloseButton } from "@chakra-ui/react"
export const AlertWithCloseButton = () => {
return (
Success!
Your application has been received. We will review your application
and respond within the next 48 hours.
)
}
```
### With Spinner
Here's and example of how to compose the `Alert` with a spinner.
```tsx
import { Alert, Spinner } from "@chakra-ui/react"
export const AlertWithSpinner = () => {
return (
We are loading something
)
}
```
### Custom Icon
Use the `icon` prop to pass a custom icon to the alert. This will override the
default icon for the alert status.
```tsx
import { Alert } from "@chakra-ui/react"
import { LuAlarmClockPlus } from "react-icons/lu"
export const AlertWithCustomIcon = () => {
return (
Submitting this form will delete your account
)
}
```
### Color Palette Override
The default colorPalette is inferred from the `status` prop. To override the
color palette, pass the `colorPalette` prop.
```tsx
import { Alert } from "@chakra-ui/react"
export const AlertWithColorPaletteOverride = () => {
return (
This is an info alert but shown as teal
)
}
```
### Customization
You can style the `Alert` component using style props.
```tsx
import { Alert, Link, Stack } from "@chakra-ui/react"
import { LuPercent } from "react-icons/lu"
export const AlertWithCustomization = () => {
return (
Black Friday Sale (20% off)
Upgrade your plan to get access to the sale.
Upgrade
Heads up: Black Friday Sale (20% off)
)
}
```
### Closed Component
Here's how to setup the `Alert` for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add alert
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| status | info | `'info' \| 'warning' \| 'success' \| 'error' \| 'neutral'` | The status of the component |
| variant | subtle | `'subtle' \| 'surface' \| 'outline' \| 'solid'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| inline | false | `'true' \| 'false'` | The inline of the component |
## Explorer
Explore the `Alert` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Aspect Ratio
```tsx
import { AspectRatio, Center } from "@chakra-ui/react"
export const AspectRatioBasic = () => {
return (
16 / 9
)
}
```
## Usage
The `ratio` prop overrides the original aspect ratios of `AspectRatio`'s child
content, accepting only numeric values, not strings.
```jsx
import { AspectRatio } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Image
Here's how to embed an image that has a 4 by 3 aspect ratio.
```tsx
import { AspectRatio, Image } from "@chakra-ui/react"
export const AspectRatioWithImage = () => {
return (
)
}
```
### Video
Embed a video using an iframe, and use the `ratio` prop to override the video's
original aspect ratio.
```tsx
import { AspectRatio } from "@chakra-ui/react"
export const AspectRatioWithVideo = () => {
return (
)
}
```
### Google Map
Here's how to embed a responsive Google map using `AspectRatio`.
```tsx
import { AspectRatio } from "@chakra-ui/react"
export const AspectRatioWithMap = () => {
return (
)
}
```
### Responsive
Here's an example of applying a responsive aspect ratio to a box.
```tsx
import { AspectRatio } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const AspectRatioResponsive = () => (
Box
)
```
## Guide
### Aspect Ratio Token
Chakra UI also provides
[predefined aspect ratio tokens](/docs/theming/aspect-ratios) out of the box,
including `square`, `landscape`, `portrait`, `wide`, `ultrawide`, and `golden`
that can only be used in the `aspectRatio` CSS prop.
:::note
They cannot be used with the `ratio` prop that `AspectRatio` accepts.
:::
```tsx
```
## Props
These props can be passed to the `AspectRatio` component.
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| ratio | undefined | `ConditionalValue \| undefined` | The aspect ratio of the Box. Common values are:
`21/9`, `16/9`, `9/16`, `4/3`, `1.85/1` |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Avatar
```tsx
import { Avatar } from "@chakra-ui/react"
export const AvatarBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Avatar, AvatarGroup } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Use the `size` prop to change the size of the avatar
```tsx
import { Avatar, For, HStack } from "@chakra-ui/react"
export const AvatarWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Variants
Use the `variant` prop to change the variant of the avatar
```tsx
import { Avatar, For, HStack } from "@chakra-ui/react"
export const AvatarWithVariants = () => {
return (
{(variant) => (
)}
)
}
```
### Shape
Use the `shape` prop to change the shape of the avatar, from `rounded` to
`square`
```tsx
import { Avatar, HStack } from "@chakra-ui/react"
export const AvatarWithShape = () => {
return (
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the avatar
```tsx
import { Avatar, Stack, Text } from "@chakra-ui/react"
export const AvatarWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Fallback
Render `Avatar.Icon` as the fallback when the name is not provided or when the
image fails to load.
```tsx
import { Avatar, HStack } from "@chakra-ui/react"
export const AvatarWithFallback = () => {
return (
)
}
```
### Random Color
Combine the `colorPalette` prop with some custom logic to dynamically change the
color of the avatar
```tsx
import { Avatar, HStack } from "@chakra-ui/react"
const colorPalette = ["red", "blue", "green", "yellow", "purple", "orange"]
const pickPalette = (name: string) => {
const index = name.charCodeAt(0) % colorPalette.length
return colorPalette[index]
}
export const AvatarWithRandomColor = () => {
return (
)
}
```
### Ring
Use the `outline*` props to add a ring around the avatar
```tsx
import { Avatar, HStack, defineStyle } from "@chakra-ui/react"
const ringCss = defineStyle({
outlineWidth: "2px",
outlineColor: "colorPalette.500",
outlineOffset: "2px",
outlineStyle: "solid",
})
export const AvatarWithRing = () => {
return (
)
}
```
### Group
Use the `Group` component to group multiple avatars together
```tsx
import { Avatar, AvatarGroup } from "@chakra-ui/react"
export const AvatarWithGroup = () => {
return (
+3
)
}
```
### Stacking
When using the `AvatarGroup` component, you can use the `stacking` prop to
change the stacking order of the avatars
```tsx
import { Avatar, AvatarGroup, Stack } from "@chakra-ui/react"
export const AvatarGroupWithStacking = () => {
return (
{items.map((item) => (
))}
+3
{items.map((item) => (
))}
+3
{items.map((item) => (
))}
+3
)
}
const items = [
{
src: "https://cdn.myanimelist.net/r/84x124/images/characters/9/131317.webp?s=d4b03c7291407bde303bc0758047f6bd",
name: "Uchiha Sasuke",
},
{
src: "https://cdn.myanimelist.net/r/84x124/images/characters/7/284129.webp?s=a8998bf668767de58b33740886ca571c",
name: "Baki Ani",
},
{
src: "https://cdn.myanimelist.net/r/84x124/images/characters/9/105421.webp?s=269ff1b2bb9abe3ac1bc443d3a76e863",
name: "Uchiha Chan",
},
]
```
### Persona
Here's an example of how to use the `Avatar` component to display a user
persona.
```tsx
import { Avatar, HStack, Stack, Text } from "@chakra-ui/react"
export const AvatarPersona = () => {
return (
{users.map((user) => (
{user.name}
{user.email}
))}
)
}
const users = [
{
id: "1",
name: "John Mason",
email: "john.mason@example.com",
avatar: "https://i.pravatar.cc/300?u=iu",
},
{
id: "2",
name: "Melissa Jones",
email: "melissa.jones@example.com",
avatar: "https://i.pravatar.cc/300?u=po",
},
]
```
### Badge
Show a badge on the right corner of the avatar by composing the `Float` and
`Circle` components
```tsx
import { Avatar, Circle, Float } from "@chakra-ui/react"
export const AvatarWithBadge = () => {
return (
)
}
```
### Overflow
Here's an example of how to handle an overflow of avatars by composing the
`Menu` and `Avatar` components.
```tsx
import { Avatar, Group, Menu, Portal } from "@chakra-ui/react"
const names = [
"Naruto Uzumaki",
"Sakura Haruno",
"Kakashi Hatake",
"Hinata Hyuga",
"Shikamaru Nara",
]
const maxAvatars = 3
export const AvatarWithOverflow = () => {
const { items, overflow } = partition(names, maxAvatars)
return (
{items.map((item) => (
))}
{overflow.length > 0 && (
+{overflow.length}
{overflow.map((item) => (
{item}
))}
)}
)
}
const colorPalette = ["red", "blue", "green", "yellow", "purple", "orange"]
const pickPalette = (name: string) => {
const index = name.charCodeAt(0) % colorPalette.length
return colorPalette[index]
}
const partition = (arr: string[], max: number) => {
const items = []
const overflow = []
for (const item of arr) {
if (items.length < max) items.push(item)
else overflow.push(item)
}
return { items, overflow }
}
```
### Next.js
Here's an example of how to compose the avatar with Next.js Image.
```tsx
import { getImageProps } from "next/image"
function Demo() {
const imageProps = getImageProps({
src: "/image.png",
})
return (
)
}
```
### Store
An alternative way to access the avatar state and methods is to use the
`RootProvider` component and the `useAvatar` store hook.
```tsx
"use client"
import { Avatar, Code, Stack, useAvatar } from "@chakra-ui/react"
export const AvatarWithStore = () => {
const avatar = useAvatar()
return (
{avatar.loaded ? "loaded" : "not loaded"}
)
}
```
### Closed Component
Here's how to setup the Avatar for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add avatar
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'full' \| '2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | subtle | `'solid' \| 'subtle' \| 'outline'` | The variant of the component |
| shape | full | `'square' \| 'rounded' \| 'full'` | The shape of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| ids | undefined | `Partial<{ root: string; image: string; fallback: string }>` | The ids of the elements in the avatar. Useful for composition. |
| onStatusChange | undefined | `(details: StatusChangeDetails) => void` | Functional called when the image loading status changes. |
| borderless | undefined | `'true' \| 'false'` | The borderless of the component |
### Fallback
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| name | undefined | `string \| undefined` | The name to derive the initials from.
If not provided, the fallback will display a generic icon. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Image
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
## Explorer
Explore the `Avatar` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Badge
```tsx
import { Badge, Stack } from "@chakra-ui/react"
export const BadgeBasic = () => {
return (
DefaultSuccessRemovedNew
)
}
```
## Usage
```jsx
import { Badge } from "@chakra-ui/react"
```
```jsx
Badge
```
## Examples
### Icon
Render an icon within the badge directly
```tsx
import { Badge, Stack } from "@chakra-ui/react"
import { HiAtSymbol, HiStar } from "react-icons/hi"
export const BadgeWithIcon = () => {
return (
New
New
)
}
```
### Variants
Badges come in different variants
```tsx
import { Badge, Stack } from "@chakra-ui/react"
export const BadgeWithVariants = () => {
return (
OutlineSolidSubtleSurface
)
}
```
### Sizes
Badges come in different sizes
```tsx
import { Badge, HStack } from "@chakra-ui/react"
export const BadgeWithSizes = () => {
return (
NewNewNewNew
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | subtle | `'solid' \| 'subtle' \| 'outline' \| 'surface' \| 'plain'` | The variant of the component |
| size | sm | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Bleed
```tsx
import { Bleed, Box, Heading, Stack, Text } from "@chakra-ui/react"
export const BleedBasic = () => {
return (
BleedSome HeadingLorem ipsum dolor sit amet, consectetur adipiscing elit.
)
}
```
## Usage
```jsx
import { Bleed } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Vertical
Use the `block` prop to make the element bleed vertically.
```tsx
import { Bleed, Box } from "@chakra-ui/react"
export const BleedVertical = () => {
return (
Bleed
)
}
```
### Specific Direction
Use the `inlineStart`, `inlineEnd`, `blockStart`, and `blockEnd` props to make
the element bleed in a specific direction.
```tsx
import { Bleed, Box, Stack } from "@chakra-ui/react"
export const BleedWithDirection = () => {
return (
inlineStartinlineEndblockStartblockEnd
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| inline | undefined | `SystemStyleObject['marginInline'] \| undefined` | The negative margin on the x-axis |
| block | undefined | `SystemStyleObject['marginBlock'] \| undefined` | The negative margin on the y-axis |
| inlineStart | undefined | `SystemStyleObject['marginInlineStart'] \| undefined` | The negative margin on the inline-start axis |
| inlineEnd | undefined | `SystemStyleObject['marginInlineEnd'] \| undefined` | The negative margin on the inline-end axis |
| blockStart | undefined | `SystemStyleObject['marginBlockStart'] \| undefined` | The negative margin on the block-start axis |
| blockEnd | undefined | `SystemStyleObject['marginBlockEnd'] \| undefined` | The negative margin on the block-end axis |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Blockquote
```tsx
import { Blockquote } from "@chakra-ui/react"
export const BlockquoteBasic = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride in
himself, without comparing himself to anyone else.
)
}
```
## Usage
```jsx
import { Blockquote } from "@chakra-ui/react"
```
```tsx
Uzumaki Naruto
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### With Cite
To provide reference about the blockquote:
- pass the `cite` prop to `Blockquote.Content` pointing to the quote url
- render the `Blockquote.Caption` component to display name of quote author
```tsx
import { Blockquote } from "@chakra-ui/react"
export const BlockquoteWithCite = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride in
himself, without comparing himself to anyone else.
— Uzumaki Naruto
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the blockquote.
```tsx
import { Blockquote, Stack, Text } from "@chakra-ui/react"
export const BlockquoteWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take
pride in himself, without comparing himself to anyone else.
— Uzumaki Naruto
))}
)
}
```
### Variants
Use the `variant` prop to change the visual style of the blockquote.
```tsx
import { Blockquote, Stack } from "@chakra-ui/react"
export const BlockquoteWithVariants = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride
in himself, without comparing himself to anyone else.
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride
in himself, without comparing himself to anyone else.
)
}
```
### Icon
Here's an example of how to compose the `Float` and `BlockquoteIcon` to show an
icon on the blockquote. The default icon is a double quote.
```tsx
import { Blockquote, Float } from "@chakra-ui/react"
export const BlockquoteWithIcon = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride in
himself, without comparing himself to anyone else.
— Uzumaki Naruto
)
}
```
Alternatively, you can render a custom icon.
```tsx
import { Blockquote, Circle, Float } from "@chakra-ui/react"
import { LuQuote } from "react-icons/lu"
export const BlockquoteWithCustomIcon = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride in
himself, without comparing himself to anyone else.
— Uzumaki Naruto
)
}
```
### Justify
Use the `justify` prop to change the alignment of the blockquote.
```tsx
import { Blockquote, For, HStack, Stack, Text } from "@chakra-ui/react"
export const BlockquoteWithJustify = () => {
return (
{(justify) => (
{justify}
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take
pride in himself, without comparing himself to anyone else.
— Uzumaki Naruto
)}
)
}
```
### With Avatar
Here's an example of how to compose the `Blockquote`, `Avatar` and `Float`
components to create a stunning testimonial component.
```tsx
import { Avatar, Blockquote, Float, HStack, Span } from "@chakra-ui/react"
export const BlockquoteWithAvatar = () => {
return (
If anyone thinks he is something when he is nothing, he deceives
himself. Each one should test his own actions. Then he can take pride in
himself, without comparing himself to anyone else.
Emily Jones
)
}
```
### Closed Component
Here's an example of how to create a closed component composition
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add blockquote
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| justify | start | `'start' \| 'center' \| 'end'` | The justify of the component |
| variant | subtle | `'subtle' \| 'solid' \| 'plain'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `Blockquote` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Box
```tsx
import { Box } from "@chakra-ui/react"
export const BoxBasic = () => {
return (
This is the Box
)
}
```
## Usage
The `Box` component provides an easy way to write styles with ease. It provides
access to design tokens and an unmatched DX when writing responsive styles.
```jsx
import { Box } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Shorthand
Use shorthand like `bg` instead of `backgroundColor`, `m` instead of `margin`,
etc.
```tsx
import { Box } from "@chakra-ui/react"
export const BoxWithShorthand = () => {
return (
This is the Box
)
}
```
### Pseudo Props
Use pseudo props like `_hover` to apply styles on hover, `_focus` to apply
styles on focus, etc.
```tsx
import { Box } from "@chakra-ui/react"
export const BoxWithPseudoProps = () => {
return (
This is the Box
)
}
```
### Border
Use the `borderWidth` and `borderColor` prop to apply border styles.
> **Good to know:** Chakra applies `borderStyle: solid` globally so you don't
> have to.
```tsx
import { Box } from "@chakra-ui/react"
export const BoxWithBorder = () => {
return (
Somewhat disabled box
)
}
```
### As Prop
Use the `as` prop to render a different component.
> Inspect the DOM to see the rendered component.
```tsx
import { Box } from "@chakra-ui/react"
export const BoxWithAsProp = () => {
return (
This is a Box rendered as a section
)
}
```
### Shadow
Use the `boxShadow` or `shadow` prop to apply shadow styles.
```tsx
import { Box } from "@chakra-ui/react"
export const BoxWithShadow = () => {
return (
Box with shadow
)
}
```
### Composition
Here's an example of a property card built with layout primitives in Chakra.
```tsx
import { Badge, Box, HStack, Icon, Image, Text } from "@chakra-ui/react"
import { HiStar } from "react-icons/hi"
export const BoxPropertyCard = () => {
return (
Superhost
{data.rating} ({data.reviewCount})
{data.title}
{data.formattedPrice} • {data.beds} beds
)
}
const data = {
imageUrl: "https://bit.ly/2Z4KKcF",
imageAlt: "Rear view of modern home with pool",
beds: 3,
title: "Modern home in city center in the heart of historic Los Angeles",
formattedPrice: "$435",
reviewCount: 34,
rating: 4.5,
}
```
## Props
The `Box` component supports all CSS properties as props, making it easy to
style elements.
# Breadcrumb
```tsx
import { Breadcrumb } from "@chakra-ui/react"
export const BreadcrumbBasic = () => {
return (
DocsComponentsProps
)
}
```
## Usage
```tsx
import { Breadcrumb } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Use the `size` prop to change the size of the breadcrumb component
```tsx
import { Breadcrumb, For, Stack } from "@chakra-ui/react"
export const BreadcrumbWithSizes = () => {
return (
{(size) => (
DocsComponentsProps
)}
)
}
```
### Variants
Use the `variant` prop to change the appearance of the breadcrumb component
```tsx
import { Breadcrumb, For, Stack } from "@chakra-ui/react"
export const BreadcrumbWithVariants = () => {
return (
{(variant) => (
DocsComponentsProps
)}
)
}
```
### With Separator
Use the `Breadcrumb.Separator` component to add a custom separator
```tsx
import { Breadcrumb } from "@chakra-ui/react"
import { LiaSlashSolid } from "react-icons/lia"
export const BreadcrumbWithSeparator = () => {
return (
DocsComponentsProps
)
}
```
### Icon
Add a custom icon to the breadcrumb by rendering it within `Breadcrumb.Link`
```tsx
import { Breadcrumb } from "@chakra-ui/react"
import { LuHouse, LuShirt } from "react-icons/lu"
export const BreadcrumbWithIcon = () => {
return (
Home
Men Wear
Trousers
)
}
```
### Menu
Wrap the `Breadcrumb.Link` inside the `MenuTrigger` to ensure it works correctly
within the menu component
```tsx
import { Breadcrumb, Menu, Portal } from "@chakra-ui/react"
import { LuChevronDown } from "react-icons/lu"
interface BreadcrumbMenuItemProps {
children: React.ReactNode
items: Array<{ label: string; value: string }>
}
const BreadcrumbMenuItem = (props: BreadcrumbMenuItemProps) => {
const { children, items } = props
return (
{children}
{items.map((item) => (
{item.label}
))}
)
}
export const BreadcrumbWithMenu = () => {
return (
Docs/
Components
/Props
)
}
```
### Ellipsis
Render the `Breadcrumb.Ellipsis` component to show an ellipsis after a
breadcrumb item
```tsx
import { Breadcrumb } from "@chakra-ui/react"
export const BreadcrumbWithEllipsis = () => {
return (
DocsComponentsProps
)
}
```
### Routing Library
Use the `asChild` prop to change the underlying breadcrumb link
```tsx
import { Breadcrumb } from "@chakra-ui/react"
import { Link } from "next/link"
export const Example = () => {
return (
Docs
)
}
```
### Closed Component
Here's how to setup the Breadcrumb for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add breadcrumb
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | plain | `'underline' \| 'plain'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| separator | undefined | `React.ReactNode` | undefined |
| separatorGap | undefined | `SystemStyleObject['gap']` | undefined |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `Breadcrumb` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Button
```tsx
import { Button } from "@chakra-ui/react"
export const ButtonBasic = () => {
return
}
```
## Usage
```jsx
import { Button, ButtonGroup } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the button.
```tsx
import { Button, HStack } from "@chakra-ui/react"
export const ButtonWithSizes = () => {
return (
)
}
```
### Variants
Use the `variant` prop to change the visual style of the Button.
```tsx
import { Button, HStack } from "@chakra-ui/react"
export const ButtonWithVariants = () => {
return (
)
}
```
### Icon
Use icons within a button
```tsx
import { Button, HStack } from "@chakra-ui/react"
import { RiArrowRightLine, RiMailLine } from "react-icons/ri"
export const ButtonWithIcons = () => {
return (
)
}
```
### Color
Use the `colorPalette` prop to change the color of the button
```tsx
import { Button, Stack, Text } from "@chakra-ui/react"
export const ButtonWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Disabled
Use the `disabled` prop to disable the button.
```tsx
import { Button } from "@chakra-ui/react"
export const ButtonWithDisabled = () => {
return
}
```
### Disabled Link
When using the `disabled` prop with a link, you need to prevent the default
behavior of the link and add the `data-disabled` attribute.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
export const ButtonWithDisabledLink = () => {
return (
)
}
```
### Loading
Pass the `loading` and `loadingText` props to the `Button` component to show a
loading spinner and add a loading text.
```tsx
import { Button, Stack } from "@chakra-ui/react"
export const ButtonWithLoading = () => {
return (
)
}
```
Here's an example of how to toggle the loading state of a button while keeping
the width of the button the same.
```tsx
"use client"
import { Button, Checkbox, VStack } from "@chakra-ui/react"
import { useState } from "react"
import { MdAdsClick } from "react-icons/md"
export const ButtonWithLoadingToggle = () => {
const [loading, setLoading] = useState(false)
return (
setLoading(!loading)}
>
Loading
)
}
```
### Spinner Placement
Use the `spinnerPlacement` prop to change the placement of the spinner.
```tsx
import { Button, ButtonGroup } from "@chakra-ui/react"
export const ButtonWithSpinnerPlacement = () => {
return (
)
}
```
### Custom Spinner
Use the `spinner` prop to change the spinner.
```tsx
import { Button } from "@chakra-ui/react"
import { BeatLoader } from "react-spinners"
export const ButtonWithCustomSpinner = () => {
return (
}
>
Click me
)
}
```
### Group
Use the `ButtonGroup` component to group buttons together. This component allows
you pass common recipe properties to inner buttons.
```tsx
import { Button, ButtonGroup } from "@chakra-ui/react"
export const ButtonWithGroup = () => {
return (
)
}
```
To flush the buttons, pass the `attached` prop.
```tsx
import { Button, ButtonGroup, IconButton } from "@chakra-ui/react"
import { LuChevronDown } from "react-icons/lu"
export const ButtonWithGroupFlushed = () => {
return (
)
}
```
### Radius
Use the `rounded` prop to change the radius of the button.
```tsx
import { Button, ButtonGroup, Stack, Text } from "@chakra-ui/react"
export const ButtonWithRadius = () => {
return (
Semantic RadiusCore Radius
)
}
```
### As Link
Use the `asChild` prop to render a button as a link.
```tsx
import { Button } from "@chakra-ui/react"
export const ButtonAsLink = () => {
return (
)
}
```
### Ref
Here's how to access the underlying element reference
```tsx
const Demo = () => {
const ref = useRef(null)
return
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| spinnerPlacement | start | `'start' \| 'end' \| undefined` | The placement of the spinner |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | solid | `'solid' \| 'subtle' \| 'surface' \| 'outline' \| 'ghost' \| 'plain'` | The variant of the component |
| loading | false | `boolean \| undefined` | If `true`, the button will show a loading spinner. |
| loadingText | undefined | `React.ReactNode \| undefined` | The text to show while loading. |
| spinner | undefined | `React.ReactNode \| undefined` | The spinner to show while loading. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Card
```tsx
import { Avatar, Button, Card } from "@chakra-ui/react"
export const CardBasic = () => {
return (
Nue Camp
This is the card body. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Curabitur nec odio vel dui euismod fermentum.
Curabitur nec odio vel dui euismod fermentum.
)
}
```
## Usage
```jsx
import { Card } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Variants
Use the `variant` prop to change the visual style of the Card.
```tsx
import { Avatar, Button, Card, For, Stack } from "@chakra-ui/react"
export const CardWithVariants = () => {
return (
{(variant) => (
Nue Camp
This is the card body. Lorem ipsum dolor sit amet, consectetur
adipiscing elit.
)}
)
}
```
### Within Form
Use the Card component within a form to group related fields together.
```tsx
import { Button, Card, Field, Input, Stack } from "@chakra-ui/react"
export const CardWithForm = () => (
Sign up
Fill in the form below to create an account
First NameLast Name
)
```
### Sizes
Use the `size` prop to change the size of the Card.
```tsx
import { Card, Heading, Stack } from "@chakra-ui/react"
export const CardWithSizes = () => {
return (
Card - sm
This is the card body. Lorem ipsum dolor sit amet, consectetur
adipiscing elit.
Card - md
This is the card body. Lorem ipsum dolor sit amet, consectetur
adipiscing elit.
Card - lg
This is the card body. Lorem ipsum dolor sit amet, consectetur
adipiscing elit.
)
}
```
### With Image
Use the Card component to display an image.
```tsx
import { Button, Card, Image, Text } from "@chakra-ui/react"
export const CardWithImage = () => {
return (
Living room Sofa
This sofa is perfect for modern tropical spaces, baroque inspired
spaces.
$450
)
}
```
### Horizontal
Use the Card component to display content horizontally.
```tsx
import { Badge, Box, Button, Card, HStack, Image } from "@chakra-ui/react"
export const CardHorizontal = () => (
The perfect latte
Caffè latte is a coffee beverage of Italian origin made with espresso
and steamed milk.
HotCaffeine
)
```
### With Avatar
Use the Card component to display an avatar.
```tsx
import {
Avatar,
Button,
Card,
HStack,
Stack,
Strong,
Text,
} from "@chakra-ui/react"
import { LuCheck, LuX } from "react-icons/lu"
export const CardWithAvatar = () => {
return (
Nate Foss
@natefoss
Nate Foss
has requested to join your team. You can approve or decline their
request.
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | outline | `'elevated' \| 'outline' \| 'subtle'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `Card` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Carousel
```tsx
import { Carousel, IconButton } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselBasic = () => {
return (
{items.map((_, index) => (
{index + 1}
))}
)
}
```
## Usage
```jsx
import { Carousel } from "@chakra-ui/react"
```
```jsx
```
## Shortcuts
The `Carousel` component also provides convenient shortcuts for common patterns.
### Carousel.Indicators
The `Carousel.Indicators` shortcut renders a full set of indicators
automatically based on the number of slides.
```jsx
{Array.from({ length: items.length }, (_, index) => (
))}
```
This might be more concise if you don't need to customize each indicator:
```jsx
```
## Examples
### Controlled
Use the `page` and `onPageChange` props to programatically control the active
carousel page.
```tsx
"use client"
import { Carousel, IconButton } from "@chakra-ui/react"
import { useState } from "react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselControlled = () => {
const [page, setPage] = useState(0)
return (
setPage(e.page)}
>
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Store
Alternatively, use the `useCarousel` hook to create a carousel store and pass it
to the `Carousel.RootProvider` component for full programmatic control.
```tsx
"use client"
import { Button, Carousel, IconButton, useCarousel } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselWithStore = () => {
const carousel = useCarousel({ slideCount: items.length })
return (
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Arrows
Use the `Carousel.PrevTrigger` and `Carousel.NextTrigger` components to create
arrows that navigate between slides.
```tsx
import { Carousel, IconButton } from "@chakra-ui/react"
import { LuArrowLeft, LuArrowRight } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselWithFloatingArrow = () => {
return (
{items.map((_src, index) => (
{index + 1}
))}
)
}
```
### Indicators
Use the `Carousel.Indicators` component to render visual indicators that help
users track the progress of the carousel and jump to specific slides.
```tsx
import { Carousel } from "@chakra-ui/react"
const items = Array.from({ length: 5 })
export const CarouselWithIndicators = () => {
return (
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Thumbnail Indicators
Here's an example that uses an image thumbnail as a custom indicator.
```tsx
import { Carousel, IconButton, Image } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const CarouselWithThumbnails = () => {
return (
{items.map((item, index) => (
))}
{items.map((item, index) => (
))}
)
}
const items = [
{
label: "Mountain Landscape",
url: "https://images.unsplash.com/photo-1501785888041-af3ef285b470?auto=format&fit=crop&w=1200&h=900&q=80",
},
{
label: "Forest Path",
url: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&h=900&q=80",
},
{
label: "Ocean Waves",
url: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=1200&h=900&q=80",
},
{
label: "Desert Dunes",
url: "https://images.unsplash.com/photo-1501785888041-af3ef285b470?auto=format&fit=crop&w=1200&h=900&q=80",
},
{
label: "Sunset Lake",
url: "https://images.unsplash.com/photo-1475924156734-496f6cac6ec1?auto=format&fit=crop&q=80&w=2070",
},
]
```
### Spacing
Use the `spacing` prop to control the spacing between slides.
```tsx
import { Carousel, HStack, IconButton } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselSpacing = () => {
return (
{"spacing='48px'"}
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Vertical
Use the `orientation` prop to `vertical` to transform your carousel into a
vertical slider.
```tsx
import { Carousel, IconButton } from "@chakra-ui/react"
import { LuChevronDown, LuChevronUp } from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselVertical = () => {
return (
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Mouse Drag
Use the `allowMouseDrag` prop to enable mouse dragging on the carousel.
```tsx
import { Carousel, HStack, IconButton } from "@chakra-ui/react"
import {
LuChevronLeft,
LuChevronRight,
LuMouse,
LuMoveHorizontal,
} from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselWithMouseDrag = () => {
return (
Click and drag to change slides
{items.map((_, index) => (
{index + 1}
))}
)
}
```
### Autoplay
Pass the `autoplay` prop to the `Carousel.Root` component to make the carousel
automatically move between slides.
```tsx
import { Carousel, HStack, IconButton } from "@chakra-ui/react"
import {
LuChevronLeft,
LuChevronRight,
LuClock,
LuPause,
LuPlay,
} from "react-icons/lu"
const items = Array.from({ length: 5 })
export const CarouselWithAutoplay = () => {
return (
{"autoplay={{ delay: 2000 }}"} or {"autoplay={true}"}
{items.map((_, index) => (
{index + 1}
))}
}
play={}
/>
)
}
```
### Lightbox
Compose the `Carousel` component with the `Dialog` component to create a
lightbox.
```tsx
"use client"
import {
AspectRatio,
Button,
Carousel,
CloseButton,
Dialog,
HStack,
IconButton,
Image,
Portal,
} from "@chakra-ui/react"
import { useCarouselContext } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const CarouselWithDialog = () => {
return (
{items.map((src, index) => (
))}
)
}
const items = [
"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=800&q=80",
"https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=800&q=80",
"https://images.unsplash.com/photo-1572635196237-14b3f281503f?w=800&q=80",
"https://images.unsplash.com/photo-1560343090-f0409e92791a?w=800&q=80",
"https://images.unsplash.com/photo-1491553895911-0055eca6402d?w=800&q=80",
"https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=800&q=80",
]
const CarouselThumbnails = ({ items }: { items: string[] }) => {
const carousel = useCarouselContext()
return (
{items.map((src, index) => (
carousel.scrollTo(index)}
>
))}
)
}
```
### Image Carousel
Here's an example that shows how to create an image carousel for a product
showcase.
```tsx
import type { IconButtonProps } from "@chakra-ui/react"
import { AspectRatio, Box, Carousel, IconButton, Image } from "@chakra-ui/react"
import { forwardRef } from "react"
import { LuArrowLeft, LuArrowRight } from "react-icons/lu"
export const CarouselWithImages = () => {
return (
{items.map((src, index) => (
))}
)
}
const ActionButton = forwardRef(
function ActionButton(props, ref) {
return (
)
},
)
const items = [
"https://images.unsplash.com/photo-1656433031375-5042f5afe894?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2371",
"https://images.unsplash.com/photo-1587466412525-87497b34fc88?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2673",
"https://images.unsplash.com/photo-1629581688635-5d88654e5bdd?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2831",
"https://images.unsplash.com/photo-1661030420948-862787de0056?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2370",
"https://images.unsplash.com/photo-1703505841379-2f863b201212?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2371",
"https://images.unsplash.com/photo-1607776905497-b4f788205f6a?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2370",
]
```
### Property Card
Here's an example that shows how to compose the `Carousel` component with other
components to create a property card carousel.
```tsx
import {
Badge,
Box,
Carousel,
HStack,
Icon,
IconButton,
Image,
Span,
Stack,
} from "@chakra-ui/react"
import { FaStar } from "react-icons/fa"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const CarouselComposition = () => {
return (
Popular homes in Cape Town
{properties.map((property, index) => (
))}
)
}
interface PropertyCardProps {
data: Property
}
const PropertyCard = ({ data }: PropertyCardProps) => (
{data.favorite && (
Guest favorite
)}
{data.title}
${data.price} for {data.nights} nights
{data.rating}
)
interface Property {
id: number
title: string
price: number
nights: number
rating: number
image: string
favorite?: boolean
}
const properties: Property[] = [
{
id: 1,
title: "Loft Apartment in City Bowl",
price: 152,
nights: 2,
rating: 4.92,
image:
"https://images.unsplash.com/photo-1522708323590-d24dbb6b0267?w=800&q=80",
favorite: true,
},
{
id: 2,
title: "Modern Studio, Camps Bay Beachfront",
price: 296,
nights: 2,
rating: 4.99,
image:
"https://images.unsplash.com/photo-1512917774080-9991f1c4c750?w=800&q=80",
favorite: true,
},
{
id: 3,
title: "Retreat in Hout Bay with Views",
price: 257,
nights: 2,
rating: 4.94,
image:
"https://images.unsplash.com/photo-1580587771525-78b9dba3b914?w=800&q=80",
},
{
id: 4,
title: "Sunny Flat in Sea Point",
price: 132,
nights: 2,
rating: 4.87,
image:
"https://images.unsplash.com/photo-1613490493576-7fde63acd811?w=800&q=80",
},
{
id: 5,
title: "V&A Waterfront City Studio",
price: 200,
nights: 2,
rating: 4.83,
image:
"https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80",
favorite: true,
},
{
id: 6,
title: "Luxury Pad, Bantry Bay",
price: 247,
nights: 2,
rating: 4.96,
image:
"https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?w=800&q=80",
},
{
id: 7,
title: "Cozy Nest in Green Point",
price: 135,
nights: 2,
rating: 4.81,
image:
"https://images.unsplash.com/photo-1554995207-c18c203602cb?w=800&q=80",
favorite: true,
},
{
id: 8,
title: "Elegant Villa in Constantia",
price: 450,
nights: 2,
rating: 4.98,
image:
"https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&q=80",
},
]
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| slideCount | undefined | `number` | The total number of slides.
Useful for SSR to render the initial ating the snap points. |
| allowMouseDrag | false | `boolean` | Whether to allow scrolling via dragging with mouse |
| autoplay | false | `boolean \| { delay: number }` | Whether to scroll automatically. The default delay is 4000ms. |
| defaultPage | 0 | `number` | The initial page to scroll to when rendered.
Use when you don't need to control the page of the carousel. |
| inViewThreshold | 0.6 | `number \| number[]` | The threshold for determining if an item is in view. |
| loop | false | `boolean` | Whether the carousel should loop around. |
| orientation | "horizontal" | `'horizontal' \| 'vertical'` | The orientation of the element. |
| slidesPerMove | "auto" | `number \| 'auto'` | The number of slides to scroll at a time.
When set to `auto`, the number of slides to scroll is determined by the
`slidesPerPage` property. |
| slidesPerPage | 1 | `number` | The number of slides to show at a time. |
| snapType | "mandatory" | `'proximity' \| 'mandatory'` | The snap type of the item. |
| spacing | "0px" | `string` | The amount of space between items. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| ids | undefined | `Partial<{\n root: string\n item: (index: number) => string\n itemGroup: string\n nextTrigger: string\n prevTrigger: string\n indicatorGroup: string\n indicator: (index: number) => string\n}>` | The ids of the elements in the carousel. Useful for composition. |
| onAutoplayStatusChange | undefined | `(details: AutoplayStatusDetails) => void` | Function called when the autoplay status changes. |
| onDragStatusChange | undefined | `(details: DragStatusDetails) => void` | Function called when the drag status changes. |
| onPageChange | undefined | `(details: PageChangeDetails) => void` | Function called when the page changes. |
| padding | undefined | `string` | Defines the extra space added around the scrollable area,
enabling nearby items to remain partially in view. |
| page | undefined | `number` | The controlled page of the carousel. |
| translations | undefined | `IntlTranslations` | The localized messages to use. |
### ItemGroup
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| index | undefined | `number` | The index of the item. |
| snapAlign | "start" | `'center' \| 'end' \| 'start'` | The snap alignment of the item. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Control
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
## Explorer
Explore the `Carousel` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Center
```tsx
import { Box, Center } from "@chakra-ui/react"
export const CenterBasic = () => {
return (
This will be centered
)
}
```
## Usage
```jsx
import { Center, Circle, Square } from "@chakra-ui/react"
```
```jsx
This is the Center
```
## Examples
### Icon
Center can be used to create frames around icons or numbers.
```tsx
import { Box, Center, HStack } from "@chakra-ui/react"
import { LuPhone } from "react-icons/lu"
export const CenterWithIcons = () => {
return (
1
)
}
```
### Center with Inline
Use the `inline` prop to make `Center` behave like an inline element
(`display: inline-flex`) instead of a block-level element (`display: flex`).
This makes `Center` only take up as much width as its content needs, allowing it
to fit inside links, buttons, or other inline contexts without breaking the
layout.
```tsx
import { Box, Center, Link } from "@chakra-ui/react"
import { LuArrowRight } from "react-icons/lu"
export const CenterWithInline = () => {
return (
Visit Chakra UI
)
}
```
### Square
`Square` centers its child within a fixed-size container of equal width and
height. It accepts a `size` prop that sets both width and height to the same
value.
```tsx
import { Square } from "@chakra-ui/react"
import { LuPhoneForwarded } from "react-icons/lu"
export const CenterWithSquare = () => {
return (
)
}
```
### Circle
`Circle` extends `Square` by adding `borderRadius="9999px"` to create a perfect
circle. Like `Square`, it accepts a `size` prop that sets both width and height
to the same value.
```tsx
import { Circle } from "@chakra-ui/react"
import { LuPhoneForwarded } from "react-icons/lu"
export const CenterWithCircle = () => {
return (
)
}
```
## Props
### Center
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Square
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Circle
`Circle` extends `Square` and accepts all the same props. The only difference is
that `Circle` applies `borderRadius="9999px"`.
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Checkbox Card
```tsx
import { CheckboxCard } from "@chakra-ui/react"
export const CheckboxCardBasic = () => {
return (
Next.js
)
}
```
## Usage
```tsx
import { CheckboxCard } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Description
Use the `CheckboxCard.Description` component to add a description to the
checkbox card.
```tsx
import { CheckboxCard } from "@chakra-ui/react"
export const CheckboxCardWithDescription = () => {
return (
Next.jsBest for apps
)
}
```
### Group
Use the `CheckboxGroup` component to group multiple checkbox cards.
```tsx
import { CheckboxCard, CheckboxGroup, Flex, Text } from "@chakra-ui/react"
export const CheckboxCardWithGroup = () => {
return (
Select framework(s)
{items.map((item) => (
{item.title}
{item.description}
))}
)
}
const items = [
{ value: "next", title: "Next.js", description: "Best for apps" },
{ value: "vite", title: "Vite", description: "Best for SPAs" },
{ value: "astro", title: "Astro", description: "Best for static sites" },
]
```
### Sizes
Pass the `size` prop to the `CheckboxCard.Root` component to change the size of
the checkbox card.
```tsx
import { CheckboxCard, For, Stack } from "@chakra-ui/react"
export const CheckboxCardWithSizes = () => {
return (
{(size) => (
Checkbox {size}
)}
)
}
```
### Variants
Use the `variant` prop to Pass the `variant` prop to the `CheckboxCard.Root`
component to change the variant of the checkbox card.
```tsx
import { CheckboxCard, For, Stack } from "@chakra-ui/react"
export const CheckboxCardWithVariants = () => {
return (
{(variant) => (
Checkbox {variant}
)}
)
}
```
### Disabled
Pass the `disabled` prop to the `CheckboxCard.Root` component to make the
checkbox card disabled.
```tsx
import { CheckboxCard } from "@chakra-ui/react"
export const CheckboxCardDisabled = () => {
return (
Disabled
This is a disabled checkbox
)
}
```
### Addon
Render additional content within the `CheckboxCard.Addon` component to add some
more context to the checkbox card.
```tsx
import { Badge, CheckboxCard, HStack } from "@chakra-ui/react"
export const CheckboxCardWithAddon = () => {
return (
With AddonSome description
Some supporting text
New
)
}
```
### No Indicator
Here's an example of how to use the checkbox card without an indicator.
```tsx
import { CheckboxCard, HStack } from "@chakra-ui/react"
export const CheckboxCardNoIndicator = () => {
return (
Chakra UINext.js
)
}
```
### Icon
Here's an example of how to render custom icons within the checkbox card.
```tsx
import {
CheckboxCard,
CheckboxGroup,
Float,
Icon,
SimpleGrid,
} from "@chakra-ui/react"
import { HiGlobeAlt, HiLockClosed, HiShieldCheck, HiUser } from "react-icons/hi"
export const CheckboxCardWithIcon = () => {
return (
{items.map((item) => (
{item.icon}
{item.label}
{item.description}
))}
)
}
const items = [
{ icon: , label: "Admin", description: "Give full access" },
{ icon: , label: "User", description: "Give limited access" },
{
icon: ,
label: "Guest",
description: "Give read-only access",
},
{ icon: , label: "Blocked", description: "No access" },
]
```
### Closed Component
Here's how to setup the Checkbox card for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add checkbox-card
```
Here's how to use the it
```tsx
```
## Guides
### CheckboxGroup + Field vs Fieldset
When working with multiple checkbox cards, it's important to understand the
semantic difference between `Field` and `Fieldset`:
- **Single CheckboxCard**: Can be wrapped with `Field.Root` for proper form
field structure with labels and helper text
- **CheckboxGroup**: Should be wrapped with `Fieldset.Root`, not `Field.Root`
A group of checkbox cards represents a collection of related options and should
be marked up as a fieldset with a legend, not as a single field. Wrapping
`CheckboxGroup` in `Field.Root` can cause interaction issues where only the
first checkbox card responds to clicks.
**✅ Correct Usage:**
```tsx
Select framework(s)
{/* ... checkbox cards ... */}
```
**❌ Incorrect Usage:**
```tsx
// Don't wrap CheckboxGroup with Field.Root
{/* ... checkbox cards ... */}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | "on" | `string` | The value of checkbox input. Useful for form submission. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | outline | `'surface' \| 'subtle' \| 'outline' \| 'solid'` | The variant of the component |
| align | start | `'start' \| 'end' \| 'center'` | The align of the component |
| orientation | horizontal | `'vertical' \| 'horizontal'` | The orientation of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| checked | undefined | `CheckedState` | The controlled checked state of the checkbox |
| defaultChecked | undefined | `CheckedState` | The initial checked state of the checkbox when rendered.
Use when you don't need to control the checked state of the checkbox. |
| disabled | undefined | `boolean` | Whether the checkbox is disabled |
| form | undefined | `string` | The id of the form that the checkbox belongs to. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | The ids of the elements in the checkbox. Useful for composition. |
| invalid | undefined | `boolean` | Whether the checkbox is invalid |
| name | undefined | `string` | The name of the input field in a checkbox.
Useful for form submission. |
| onCheckedChange | undefined | `(details: CheckedChangeDetails) => void` | The callback invoked when the checked state changes. |
| readOnly | undefined | `boolean` | Whether the checkbox is read-only |
| required | undefined | `boolean` | Whether the checkbox is required |
| justify | undefined | `'start' \| 'end' \| 'center'` | The justify of the component |
## Explorer
Explore the `Checkbox Card` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Checkbox
```tsx
import { Checkbox } from "@chakra-ui/react"
export const CheckboxBasic = () => {
return (
Accept terms and conditions
)
}
```
## Usage
```tsx
import { Checkbox } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Shortcuts
The `Checkbox` component also provides a set of shortcuts for common use cases.
### CheckboxControl
This component renders the `Checkbox.Indicator` within it by default.
This works:
```tsx
```
This might be more concise, if you don't need to customize the indicator:
```tsx
```
## Examples
### Variants
Pass the `variant` prop to the `Checkbox.Root` component to change the visual
style of the checkbox.
```tsx
import { Checkbox, For, HStack, Stack, Text } from "@chakra-ui/react"
export const CheckboxWithVariants = () => {
return (
{(variant) => (
{variant}Checkbox
)}
)
}
```
### Colors
Pass the `colorPalette` prop to the `Checkbox.Root` component to change the
color of the checkbox.
```tsx
import { Checkbox, For, Stack, Text } from "@chakra-ui/react"
export const CheckboxWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
{(variant) => (
CheckboxCheckbox
)}
))}
)
}
```
### Sizes
Pass the `size` prop to the `Checkbox.Root` component to change the size of the
checkbox.
```tsx
import { Checkbox, For, Stack } from "@chakra-ui/react"
export const CheckboxWithSizes = () => {
return (
{(size) => (
Checkbox
)}
)
}
```
### States
Pass the `disabled` or `invalid` prop to the `Checkbox.Root` component to change
the visual state of the checkbox.
```tsx
import { Checkbox, Stack } from "@chakra-ui/react"
export const CheckboxWithStates = () => {
return (
DisabledDisabledReadonlyInvalid
)
}
```
### Controlled
Use the `checked` and `onCheckedChange` props to control the state of the
checkbox.
```tsx
"use client"
import { Checkbox } from "@chakra-ui/react"
import { useState } from "react"
export const CheckboxControlled = () => {
const [checked, setChecked] = useState(false)
return (
setChecked(!!e.checked)}
>
Accept terms and conditions
)
}
```
### Label Position
Here's an example of how to change the label position to the right.
```tsx
import { Checkbox } from "@chakra-ui/react"
export const CheckboxWithLabelPosition = () => {
return (
Accept terms and conditions
)
}
```
### Store
An alternative way to control the checkbox is to use the `RootProvider`
component and the `useCheckbox` store hook.
This way you can access the checkbox state and methods from outside the
checkbox.
```tsx
"use client"
import { Checkbox, useCheckbox } from "@chakra-ui/react"
export const CheckboxWithStore = () => {
const checkbox = useCheckbox()
return (
Accept terms and conditions
)
}
```
### Composition
Here's an example of how to compose a checkbox with a field component.
```tsx
"use client"
import { Button, Checkbox, Field, Input, Stack } from "@chakra-ui/react"
export const CheckboxWithForm = () => {
return (
)
}
```
### Hook Form
Here's an example of how to use the `Checkbox` component with the
`react-hook-form` library.
```tsx
"use client"
import { Button, Checkbox, Code, Field, HStack, Stack } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useController, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
enabled: z.boolean(),
})
type FormData = z.infer
export const CheckboxWithHookForm = () => {
const form = useForm({
resolver: standardSchemaResolver(formSchema),
defaultValues: { enabled: false },
})
const enabled = useController({
control: form.control,
name: "enabled",
})
const invalid = !!form.formState.errors.enabled
return (
)
}
```
### Group
Use the `CheckboxGroup` component to group multiple checkboxes together.
```tsx
import { Checkbox, CheckboxGroup, Fieldset, For } from "@chakra-ui/react"
export const CheckboxWithGroup = () => {
return (
Select framework
{(value) => (
{value}
)}
)
}
```
### Group Hook Form
Here's an example of how to use the `CheckboxGroup` component with the
`react-hook-form` library.
```tsx
"use client"
import {
Button,
Checkbox,
CheckboxGroup,
Code,
Fieldset,
} from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { useController, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
framework: z.array(z.string()).min(1, {
message: "You must select at least one framework.",
}),
})
type FormData = z.infer
const items = [
{ label: "React", value: "react" },
{ label: "Svelte", value: "svelte" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
]
export const CheckboxWithGroupHookForm = () => {
const {
handleSubmit,
control,
formState: { errors },
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const framework = useController({
control,
name: "framework",
defaultValue: [],
})
const invalid = !!errors.framework
return (
)
}
```
### Custom Icon
Render a custom icon within `Checkbox.Control` to change the icon of the
checkbox.
```tsx
import { Checkbox } from "@chakra-ui/react"
import { HiOutlinePlus } from "react-icons/hi"
export const CheckboxWithCustomIcon = () => {
return (
With Custom Icon
)
}
```
### Indeterminate
Set the `checked` prop to `indeterminate` to show the checkbox in an
indeterminate state.
```tsx
"use client"
import { Checkbox, Stack } from "@chakra-ui/react"
import { useState } from "react"
const initialValues = [
{ label: "Monday", checked: false, value: "monday" },
{ label: "Tuesday", checked: false, value: "tuesday" },
{ label: "Wednesday", checked: false, value: "wednesday" },
{ label: "Thursday", checked: false, value: "thursday" },
]
export const CheckboxIndeterminate = () => {
const [values, setValues] = useState(initialValues)
const allChecked = values.every((value) => value.checked)
const indeterminate = values.some((value) => value.checked) && !allChecked
const items = values.map((item, index) => (
{
setValues((current) => {
const newValues = [...current]
newValues[index] = { ...newValues[index], checked: !!e.checked }
return newValues
})
}}
>
{item.label}
))
return (
{
setValues((current) =>
current.map((value) => ({ ...value, checked: !!e.checked })),
)
}}
>
Weekdays
{items}
)
}
```
### Description
Here's an example of how to add some further description to the checkbox.
```tsx
import { Box, Checkbox, Stack } from "@chakra-ui/react"
export const CheckboxWithDescription = () => {
return (
I agree to the terms and conditions
By clicking this, you agree to our Terms and Privacy Policy.
)
}
```
### Link
Render an anchor tag within the `Checkbox.Label` to add a link to the label.
```tsx
import { Checkbox, Link } from "@chakra-ui/react"
export const CheckboxWithLink = () => {
return (
I agree to the{" "}
terms and conditions
)
}
```
### Closed Component
Here's how to setup the Checkbox for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add checkbox
```
Here's how to use the it
```tsx
Accept terms and conditions
```
## Guides
### CheckboxGroup + Field vs Fieldset
When working with multiple checkboxes, it's important to understand the semantic
difference between `Field` and `Fieldset`:
- **Single Checkbox**: Wrap with `Field.Root` for proper form field structure
with labels and helper text
- **CheckboxGroup**: Wrap with `Fieldset.Root`, not `Field.Root`
A checkbox group represents a collection of related options and should be marked
up as a fieldset with a legend, not as a single field. Wrapping `CheckboxGroup`
in `Field.Root` can cause interaction issues where only the first checkbox
responds to clicks.
**✅ Correct Usage:**
```tsx
Select framework
{/* ... checkboxes ... */}
```
**❌ Incorrect Usage:**
```tsx
// Don't wrap CheckboxGroup with Field.Root
{/* ... checkboxes ... */}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | "on" | `string` | The value of checkbox input. Useful for form submission. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | solid | `'outline' \| 'solid' \| 'subtle'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| checked | undefined | `CheckedState` | The controlled checked state of the checkbox |
| defaultChecked | undefined | `CheckedState` | The initial checked state of the checkbox when rendered.
Use when you don't need to control the checked state of the checkbox. |
| disabled | undefined | `boolean` | Whether the checkbox is disabled |
| form | undefined | `string` | The id of the form that the checkbox belongs to. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; hiddenInput: string; control: string; label: string }>` | The ids of the elements in the checkbox. Useful for composition. |
| invalid | undefined | `boolean` | Whether the checkbox is invalid |
| name | undefined | `string` | The name of the input field in a checkbox.
Useful for form submission. |
| onCheckedChange | undefined | `(details: CheckedChangeDetails) => void` | The callback invoked when the checked state changes. |
| readOnly | undefined | `boolean` | Whether the checkbox is read-only |
| required | undefined | `boolean` | Whether the checkbox is required |
## Explorer
Explore the `Checkbox` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Checkmark
```tsx
import { Checkmark, Stack } from "@chakra-ui/react"
export const CheckmarkBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Checkmark } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Indeterminate
Use the `indeterminate` prop to show an indeterminate state.
```tsx
import { Checkmark, HStack } from "@chakra-ui/react"
export const CheckmarkIndeterminate = () => {
return (
)
}
```
### States
The Checkmark component supports three states: unchecked (default), checked, and
indeterminate.
```tsx
import { Checkmark, HStack } from "@chakra-ui/react"
export const CheckmarkStates = () => {
return (
)
}
```
### Variants
Use the `variant` prop to change the visual style of the checkmark.
```tsx
import { Checkmark, For, HStack } from "@chakra-ui/react"
export const CheckmarkWithVariants = () => {
return (
{(variant) => }
)
}
```
### Sizes
Use the `size` prop to change the size of the checkmark.
```tsx
import { Checkmark, For, HStack } from "@chakra-ui/react"
export const CheckmarkWithSizes = () => {
return (
{(size) => }
)
}
```
### Colors
Use the `colorPalette` prop to change the color scheme of the checkmark.
```tsx
import { Checkmark, For, HStack } from "@chakra-ui/react"
export const CheckmarkWithColors = () => {
return (
{(colorPalette) => (
)}
)
}
```
### Filled
Use the `filled` prop with the `outline` variant to add a background color to
the checkmark.
```tsx
import { Checkmark } from "@chakra-ui/react"
export const CheckmarkWithFilled = () => {
return
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | solid | `'solid' \| 'outline' \| 'subtle' \| 'plain' \| 'inverted'` | The variant of the component |
| checked | undefined | `boolean \| undefined` | Whether the checkmark is checked |
| indeterminate | undefined | `boolean \| undefined` | Whether the checkmark is indeterminate |
| disabled | undefined | `boolean \| undefined` | Whether the checkmark is disabled |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Client Only
## Usage
```jsx
import { ClientOnly, Skeleton } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Fallback
Use the `fallback` prop to render a loading state while the client-side content
is being prepared.
```jsx
}>
```
### Render Prop (Recommended)
When your component accesses browser-only APIs (like `window`, `document`, or
`localStorage`), use the render prop pattern to prevent server-side rendering
issues:
```jsx
}>
{() => (
Current URL: {window.location.href}
Screen width: {window.innerWidth}px
)}
```
This pattern ensures that components accessing browser APIs are only evaluated
on the client side, preventing hydration mismatches and server-side errors.
> It can also be used for rendering heavy components that are not needed on the
> server side.
### Direct Children (Use with Caution)
While you can pass components directly as children, be careful with components
that access browser APIs:
```tsx
/* ❌ This may cause server-side errors */
}>
/* ✅ This is safe */
}>
{() => }
```
## Props
These props can be passed to the `ClientOnly` component.
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| fallback | undefined | `string \| number \| bigint \| boolean \| ReactElement> \| Iterable \| ReactPortal \| Promise<...>` | The fallback content to render while the component is mounting on the client
side. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Clipboard
```tsx
import { Clipboard, IconButton } from "@chakra-ui/react"
export const ClipboardBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Clipboard } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Button
Use the `Clipboard.Trigger` component to create a copy button.
```tsx
import { Button, Clipboard } from "@chakra-ui/react"
export const ClipboardWithButton = () => {
return (
)
}
```
### Input
Use the `Clipboard.Input` component to create a copy input.
```tsx
import { Clipboard, IconButton, Input, InputGroup } from "@chakra-ui/react"
export const ClipboardWithInput = () => {
return (
Document Link}>
)
}
const ClipboardIconButton = () => {
return (
)
}
```
### Timeout
Use the `timeout` prop to change the duration of the copy message.
```tsx
import { Button, Clipboard } from "@chakra-ui/react"
export const ClipboardWithTimeout = () => {
return (
)
}
```
### Link Appearance
Here's an example that combines the `Clipboard.Trigger` and
`Clipboard.ValueText` components to create a link appearance.
```tsx
import { Clipboard, Link } from "@chakra-ui/react"
export const ClipboardWithLink = () => {
return (
)
}
```
### Store
Alternatively, you can use the `useClipboard` hook to create a custom component.
```tsx
"use client"
import { Button, useClipboard } from "@chakra-ui/react"
export const ClipboardWithStore = () => {
const clipboard = useClipboard({ value: "https://chakra-ui.com" })
return (
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| timeout | 3000 | `number` | The timeout for the copy operation |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| defaultValue | undefined | `string` | The initial value to be copied to the clipboard when rendered.
Use when you don't need to control the value of the clipboard. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; input: string; label: string }>` | The ids of the elements in the clipboard. Useful for composition. |
| onStatusChange | undefined | `(details: CopyStatusDetails) => void` | The function to be called when the value is copied to the clipboard |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | The function to be called when the value changes |
| value | undefined | `string` | The controlled value of the clipboard |
## Explorer
Explore the `Clipboard` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Close Button
```tsx
import { CloseButton } from "@chakra-ui/react"
export const CloseButtonBasic = () => {
return
}
```
## Usage
```jsx
import { CloseButton } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the close button.
```tsx
import { CloseButton, For, HStack } from "@chakra-ui/react"
export const CloseButtonWithSizes = () => {
return (
{(size) => }
)
}
```
### Variants
Use the `variant` prop to change the appearance of the close button.
```tsx
import { CloseButton, HStack } from "@chakra-ui/react"
export const CloseButtonWithVariants = () => {
return (
)
}
```
### Custom Icon
Pass the custom icon to the `children` of the `CloseButton` component.
```tsx
import { CloseButton } from "@chakra-ui/react"
import { HiX } from "react-icons/hi"
export const CloseButtonWithCustomIcon = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| spinnerPlacement | start | `'start' \| 'end' \| undefined` | The placement of the spinner |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | solid | `'solid' \| 'subtle' \| 'surface' \| 'outline' \| 'ghost' \| 'plain'` | The variant of the component |
| loading | false | `boolean \| undefined` | If `true`, the button will show a loading spinner. |
| loadingText | undefined | `React.ReactNode \| undefined` | The text to show while loading. |
| spinner | undefined | `React.ReactNode \| undefined` | The spinner to show while loading. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Code Block
```tsx
"use client"
import { CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockBasic = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
## Usage
```js
import { CodeBlock } from "@chakra-ui/react"
```
```jsx
```
## Adapters
The CodeBlock component works for [Shiki](https://shiki.style/) and
[Highlight.js](https://highlightjs.org/) highlighting engines.
> The docs assumes **Shiki** by default.
To setup the code block component, you need to:
- Configure your preferred adapter (**Shiki** or **Highlight.js**).
- Provide the adapter to the `CodeBlock.AdapterProvider` at the top level.
- Render the `CodeBlock.Root` component within the `CodeBlock.AdapterProvider`.
### Shiki
Install the `shiki` package.
```bash
npm install shiki
```
Then, create the shiki adapter that dynamically loads the shiki highlighter for
the selected languages.
```tsx
import type { HighlighterGeneric } from "shiki"
import { createShikiAdapter } from "@chakra-ui/react"
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "json"],
themes: ["github-dark", "github-light"],
})
},
})
{/* ... */}
```
### Highlight.js
Install the `highlight.js` package.
```bash
npm install highlight.js
```
Then, create the highlight.js adapter that dynamically loads the selected
languages.
```tsx
import { createHighlightJsAdapter } from "@chakra-ui/react"
import hljs from "highlight.js/lib/core"
const highlightJsAdapter = createHighlightJsAdapter({
async load() {
const languages = {
tsx: () => import("highlight.js/lib/languages/typescript"),
html: () => import("highlight.js/lib/languages/xml"),
}
await Promise.all(
Object.entries(languages).map(async ([language, file]) => {
const { default: langModule } = await file()
hljs.registerLanguage(language, langModule)
}),
)
return hljs
},
})
```
## Examples
### Sizes
Use the `size` prop to change the size of the code block component.
```tsx
"use client"
import { CodeBlock, For, Stack, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithSizes = () => {
return (
{(size) => (
(size={size})
)}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Title
Render the `CodeBlock.Title` component within the `CodeBlock.Header` component
to add a title to the code block component.
```tsx
"use client"
import { CodeBlock, Icon, createShikiAdapter } from "@chakra-ui/react"
import { FaHtml5 } from "react-icons/fa"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithTitle = () => {
return (
{file.title}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Copy button
Use the `copyButton` prop to add a copy button to the code block component.
```tsx
"use client"
import { CodeBlock, IconButton, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithCopyButton = () => {
return (
{file.title}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Line numbers
Line numbers make it easier to reference specific lines of code. Pass the
`meta.showLineNumbers` prop to show line numbers in the code block component.
```tsx
"use client"
import { CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithLineNumbers = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Line highlighting
Pass the `meta.highlightLines` prop to the `CodeBlock.Root` component to
highlight specific lines of code. The prop accepts an array of line numbers.
```tsx
"use client"
import { CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithLineHighlight = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Line focus
Pass the `meta.focusedLineNumbers` prop to the `CodeBlock.Root` component to
focus specific lines of code. The prop accepts an array of line numbers. The
line numbers.
```tsx
"use client"
import { CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
const greeting = "Hello, World!"
function sayHello() {
console.log(greeting);
}
sayHello()
`,
language: "tsx",
title: "index.tsx",
}
export const CodeBlockWithLineFocus = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Diff
Diffs are useful for highlighting source code changes. Use the
`meta.addedLineNumbers` and `meta.removedLineNumbers` props to add line numbers
to the code block component.
> The prop accepts an array of line numbers. The line numbers are 1-based.
```tsx
"use client"
import { CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
const greeting = "Hello, World!";
function sayHello() {
console.log("Hello, World!");
console.log(greeting);
}
sayHello();
`,
language: "tsx",
title: "index.tsx",
}
export const CodeBlockWithDiff = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Max lines
Use the `meta.maxLines` prop to limit the number of lines in the code block
component. By default, the code block component will expand to fit the content.
```tsx
"use client"
import { CodeBlock, IconButton, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
export const CodeBlockWithMaxLines = () => {
return (
{file.title}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
const file = {
code: `import * as React from 'react';
import { CodeBlock } from '@chakra-ui/react';
const Example = () => {
const code = \`
{
"name": "My App",
"version": "1.0.0",
"description": "A simple web application",
"main": "index.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"build": "webpack --mode production",
"test": "jest"
},
"dependencies": {
"express": "^4.18.2",
"react": "^18.2.0",
"axios": "^1.4.0"
},
"author": "Developer",
"license": "MIT"
}
\`
return (
{file.title}
);
};
export default Example;
`,
language: "tsx",
title: "index.tsx",
}
```
### Language switcher
Here's an example that re-creates an API endpoint request component by composing
the `CodeBlock` and `Select` components.
```tsx
"use client"
import {
Badge,
CodeBlock,
HStack,
Icon,
IconButton,
Select,
Span,
createListCollection,
createShikiAdapter,
useSelect,
} from "@chakra-ui/react"
import { IoLogoJavascript, IoLogoPython } from "react-icons/io5"
import type { HighlighterGeneric } from "shiki"
export const CodeBlockWithLanguageSwitcher = () => {
const select = useSelect({
positioning: { strategy: "fixed" },
defaultValue: [files[0].value],
collection,
})
const selectedFile = select.selectedItems[0]
return (
POST
/v1/search
)
}
function LanguageSwitcher(props: Select.RootProviderProps) {
const { value: select } = props
return (
{select.collection.items.map((item) => (
{item.icon}
{item.value}
))}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["python", "typescript"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
interface CodeFile {
value: string
code: string
language: string
title: string
icon: React.ReactElement
}
const files: CodeFile[] = [
{
value: "python",
code: `
from github import Github
# Create a Github instance using an access token
g = Github("YOUR_ACCESS_TOKEN")
# Get a repository
repo = g.get_repo("octocat/Hello-World")
# Get repository information
print(f"Repository: {repo.name}")
print(f"Description: {repo.description}")
print(f"Stars: {repo.stargazers_count}")
# List issues
issues = repo.get_issues(state='open')
for issue in issues:
print(f"Issue #{issue.number}: {issue.title}")
`,
language: "python",
title: "python.py",
icon: ,
},
{
value: "typescript",
code: `
import { Octokit } from "@octokit/rest";
// Create an Octokit instance
const octokit = new Octokit({
auth: "YOUR_ACCESS_TOKEN",
});
// Get repository information
const { data: repo } = await octokit.rest.repos.get({
owner: "octocat",
repo: "Hello-World",
});
console.log(\`Repository: \${repo.name}\`);
console.log(\`Description: \${repo.description}\`);
console.log(\`Stars: \${repo.stargazers_count}\`);
// List issues
const { data: issues } = await octokit.rest.issues.listForRepo({
owner: "octocat",
repo: "Hello-World",
state: "open",
});
issues.forEach((issue) => {
console.log(\`Issue #\${issue.number}: \${issue.title}\`);
});
`,
language: "typescript",
title: "typescript.ts",
icon: ,
},
]
const collection = createListCollection({
items: files,
itemToString: (item) => item.value,
itemToValue: (item) => item.value,
})
```
### Floating copy button
Here's an example that adds a floating copy button to the code block component.
```tsx
"use client"
import {
CodeBlock,
Float,
IconButton,
createShikiAdapter,
} from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithFloatingCopyButton = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Tabs
Here's an example that composes the `CodeBlock` component with the `Tabs`
component to create a code block with tabs.
```tsx
"use client"
import {
CodeBlock,
IconButton,
Tabs,
createShikiAdapter,
useTabs,
} from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
export const CodeBlockWithTabs = () => {
const tabs = useTabs({
defaultValue: "python",
})
const activeTab =
files.find((file) => file.language === tabs.value) || files[0]
const otherTabs = files.filter((file) => file.language !== tabs.value)
return (
{files.map((file) => (
{file.title}
))}
{otherTabs.map((file) => (
))}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["python", "typescript", "java"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
const files = [
{ title: "Python", language: "python", code: "print('Hello, World!')" },
{
title: "TypeScript",
language: "typescript",
code: "console.log('Hello, World!')",
},
{
title: "Java",
language: "java",
code: "System.out.println('Hello, World!');",
},
]
```
### Tabs sync
Here's an example that automatically syncs all code blocks that share the same
storage key. Useful for package manager or framework specific code blocks in a
documentation site.
```tsx
"use client"
import {
CodeBlock,
IconButton,
Stack,
Tabs,
createShikiAdapter,
useTabs,
} from "@chakra-ui/react"
import { useEffect } from "react"
import type { HighlighterGeneric } from "shiki"
const files = [
{ title: "npm", language: "bash", code: "npm install @chakra-ui/react" },
{
title: "yarn",
language: "bash",
code: "yarn add @chakra-ui/react",
},
{
title: "bun",
language: "bash",
code: "bun install @chakra-ui/react",
},
]
export const CodeBlockWithTabsSync = () => {
return (
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["bash"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
const CodeTabs = () => {
const tabs = useTabsSync({
defaultValue: files[0].title,
storageKey: "code-tabs-sync",
})
const activeTab = files.find((file) => file.title === tabs.value) || files[0]
const otherTabs = files.filter((file) => file.title !== tabs.value)
return (
{files.map((file) => (
{file.title}
))}
{otherTabs.map((file) => (
))}
)
}
function useTabsSync(props: { defaultValue: string; storageKey: string }) {
const { defaultValue, storageKey } = props
const tabs = useTabs({
defaultValue,
onValueChange(details) {
if (details.value) {
localStorage.setItem(storageKey, details.value)
dispatchEvent(
new StorageEvent("storage", {
key: storageKey,
newValue: details.value,
}),
)
}
},
})
useEffect(() => {
const handleStorageChange = (e: StorageEvent) => {
requestAnimationFrame(() => {
if (e.key === storageKey && e.newValue) {
tabs.setValue(e.newValue)
}
})
}
window.addEventListener("storage", handleStorageChange)
return () => window.removeEventListener("storage", handleStorageChange)
}, [storageKey, tabs])
return tabs
}
```
### Themes
Use the `meta.colorScheme` prop to add a theme to the code block component. In
this example, the colorScheme is set to color mode from the `useColorMode` hook.
```tsx
"use client"
import { ClientOnly, CodeBlock, createShikiAdapter } from "@chakra-ui/react"
import { useColorMode } from "@/components/ui/color-mode"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithThemes = () => {
const { colorMode } = useColorMode()
return (
Loading...}>
{() => (
)}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark", "github-light"],
})
},
theme: {
light: "github-light",
dark: "github-dark",
},
})
```
### Wrap overflow
Use the `meta.wordWrap` prop to wrap the code block component.
```tsx
"use client"
import { CodeBlock, IconButton, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
const file = {
code: `
const greeting = "Hello, World! I am a long line of text that will wrap to the next line."
function sayHello() {
console.log(greeting)
}
sayHello()
`,
language: "tsx",
title: "index.tsx",
}
export const CodeBlockWithWordWrap = () => {
return (
{file.title}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["tsx", "scss", "html", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
```
### Line numbers with word wrap
You can combine line numbers with word wrapping by setting both
`meta.showLineNumbers` and `meta.wordWrap` to `true`. The line numbers will
properly align with wrapped text.
```tsx
"use client"
import { CodeBlock, IconButton, createShikiAdapter } from "@chakra-ui/react"
import type { HighlighterGeneric } from "shiki"
export const CodeBlockWithLineNumbersWordWrap = () => {
return (
{file.title}
)
}
const shikiAdapter = createShikiAdapter>({
async load() {
const { createHighlighter } = await import("shiki")
return createHighlighter({
langs: ["javascript", "bash", "json"],
themes: ["github-dark"],
})
},
theme: "github-dark",
})
const file = {
code: `total 121M
drwxr-xr-x 3 root root 4.0K Sep 11 2022 ..
-rw-r--r-- 1 ali ali 220 Sep 11 2022 .bash_logout
drwxr-xr-x 2 ali ali 4.0K Sep 11 2022 Templates
drwxr-xr-x 2 ali ali 4.0K Sep 11 2022 Public
-rw-r--r-- 1 ali ali 0 Sep 11 2022 .sudo_as_admin_successful
drwx------ 3 ali ali 4.0K Sep 11 2022 .pki
drwx------ 3 ali ali 4.0K Sep 11 2022 .gnome
-rw-r--r-- 1 ali ali 10 Sep 13 2022 .shell.pre-oh-my-zsh
drwxrwxr-x 3 ali ali 4.0K Sep 26 2022 v2ray
-rw-r--r-- 1 root root 12K Sep 26 2022 .profile.swp
drwxrwxrwx 4 ali ali 4.0K Sep 28 2022 .sonarlint
drwxrwxr-x 3 ali ali 4.0K Sep 28 2022 .eclipse
drwxrwxr-x 8 ali ali 4.0K Oct 4 2022 zsh-syntax-highlighting
drwxrwxr-x 2 ali ali 4.0K Oct 5 2022 .dart
drwxrwxr-x 4 ali ali 4.0K Oct 5 2022 .dartServer
drwxrwxrwx 2 ali ali 4.0K Oct 7 2022 .quicktype-vscode
-rw-rw-r-- 1 ali ali 38K Oct 31 2022 .zcompdump-ali-laptop-5.8.1.ali-laptop.5060
drwxrwxr-x 3 ali ali 4.0K Nov 16 2022 .swt
drwx------ 3 ali ali 4.0K Nov 17 2022 .nv
drwxrwxr-x 15 ali ali 4.0K Nov 18 2022 .gvm
drwxrwxr-x 2 ali ali 4.0K Nov 27 2022 .docker-esopmoc
drwxrwxr-x 3 ali ali 4.0K Dec 5 2022 .ipython
drwx------ 7 ali ali 4.0K Dec 5 2022 .local
drwxrwxr-x 2 ali ali 4.0K Dec 5 2022 .jupyter
drwxr-xr-x 4 ali ali 4.0K Dec 11 2022 .anydesk
drwxrwxr-x 3 ali ali 4.0K Feb 18 2023 .dotnet
drwxrwxr-x 3 ali ali 4.0K Feb 19 2023 .degit
drwxrwxr-x 3 ali ali 4.0K Feb 26 2023 .cargo
-rw-rw-r-- 1 ali ali 21 Feb 26 2023 .zshenv
drwxrwxr-x 6 ali ali 4.0K Feb 26 2023 .rustup
drwxrwxr-x 2 ali ali 4.0K Apr 8 2023 .ipynb_checkpoints
drwxr-xr-x 8 ali ali 4.0K Apr 20 2023 my_folder
drwx------ 3 ali ali 4.0K May 5 2023 .vmware
drwxrwxr-x 15 ali ali 4.0K May 7 2023 .openshot_qt
drwxrwxr-x 3 ali ali 4.0K May 10 2023 .parallel
drwxrwxr-x 2 ali ali 4.0K May 16 2023 .simplelocalize
-rw-rw-r-- 1 ali ali 5.7K May 21 2023 .v8flags.9.4.146.26-node.26.86318e52f5ed4801abe1d13d509443de.json
drwxrwxrwx 105 ali ali 4.0K Sep 5 10:27 `,
language: "bash",
title: "terminal-output.txt",
}
```
### Highlight.js
Here's an example that uses highlight.js to highlight the code block.
```tsx
"use client"
import { CodeBlock, createHighlightJsAdapter } from "@chakra-ui/react"
import hljs from "highlight.js/lib/core"
const file = {
code: `
Hello, world!
`,
language: "html",
title: "index.html",
}
export const CodeBlockWithHighlightJs = () => {
return (
{file.title}
)
}
const highlightJsAdapter = createHighlightJsAdapter({
async load() {
const languages = {
tsx: () => import("highlight.js/lib/languages/typescript"),
html: () => import("highlight.js/lib/languages/xml"),
}
await Promise.all(
Object.entries(languages).map(async ([language, file]) => {
const { default: langModule } = await file()
hljs.registerLanguage(language, langModule)
}),
)
return hljs
},
})
```
### Plain text
The code block falls back to a plain text by default. To create a plain text
code block, remove the use of `CodeBlock.AdapterProvider`.
```tsx
"use client"
import { CodeBlock, Float, IconButton, Span } from "@chakra-ui/react"
const file = {
code: "npm install @chakra-ui/react",
language: "bash",
title: "npm install @chakra-ui/react",
}
export const CodeBlockPlainText = () => {
return (
$
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | subtle | `'solid' \| 'subtle' \| 'outline' \| 'surface' \| 'plain'` | The variant of the component |
| size | sm | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Code
```tsx
import { Code } from "@chakra-ui/react"
export const CodeBasic = () => {
return {`console.log("Hello, world!")`}
}
```
## Usage
```js
import { Code } from "@chakra-ui/react"
```
```jsx
Hello world
```
## Examples
### Sizes
Use the `size` prop to change the size of the code component.
```tsx
import { Code, Stack } from "@chakra-ui/react"
export const CodeWithSizes = () => {
return (
console.log()console.log()console.log()console.log()
)
}
```
### Variants
Use the `variant` prop to change the appearance of the code component.
```tsx
import { Code, Stack } from "@chakra-ui/react"
export const CodeWithVariants = () => {
return (
console.log()console.log()console.log()console.log()
)
}
```
### Colors
Use the `colorPalette` prop to change the color scheme of the component.
```tsx
import { Code, Stack, Text } from "@chakra-ui/react"
export const CodeWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
{`console.log()`}
{`console.log()`}
{`console.log()`}
{`console.log()`}
))}
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | subtle | `'solid' \| 'subtle' \| 'outline' \| 'surface' \| 'plain'` | The variant of the component |
| size | sm | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Collapsible
```tsx
import { Box, Collapsible } from "@chakra-ui/react"
export const CollapsibleBasic = () => (
Toggle CollapsibleChakra UI embraces this philosophy in the world of
design and development. Just like chakras align energy in the body,
Chakra UI aligns your design system — bringing flow, consistency, and
peace of mind to your codebase. It helps developers focus on creating
beautiful, accessible UIs without friction.
Think of each component as a wheel in your app’s UI — smooth, connected,
and full of potential. Build with harmony. Build with
Chakra UI.
)
```
## Usage
```jsx
import { Collapsible } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Initial Open
Use the `defaultOpen` prop to render the collapsible in an open state by
default.
```tsx
import { Collapsible, Stack } from "@chakra-ui/react"
import { LuChevronRight } from "react-icons/lu"
import LoremIpsum from "react-lorem-ipsum"
export const CollapsibleInitialOpen = () => (
Toggle
)
```
### Partial Height
Use the `collapsedHeight` prop to show a preview of the content when collapsed.
```tsx
"use client"
import { Button, Collapsible, Stack } from "@chakra-ui/react"
import { LuChevronDown } from "react-icons/lu"
import { LoremIpsum } from "react-lorem-ipsum"
export const CollapsiblePartialHeight = () => (
)
```
### Disabled
Use the `disabled` prop to prevent the collapsible from being toggled.
```tsx
import { Box, Collapsible } from "@chakra-ui/react"
export const CollapsibleWithDisabled = () => (
Toggle (Disabled)
This content cannot be toggled because the collapsible is disabled using
the disabled prop.
)
```
### Controlled
Use the `open` and `onOpenChange` props to control the collapsible state.
```tsx
"use client"
import { Box, Collapsible, Stack } from "@chakra-ui/react"
import { useState } from "react"
export const CollapsibleControlled = () => {
const [open, setOpen] = useState(false)
return (
Status: {open ? "Open" : "Closed"} setOpen(e.open)}>
Toggle Collapsible
This collapsible is controlled by external state. You can open and
close it using the buttons above or by clicking the trigger.
)
}
```
### Store
An alternative way to control the collapsible is to use the `RootProvider`
component and the `useCollapsible` store hook.
```tsx
"use client"
import {
Box,
Button,
Collapsible,
Icon,
Stack,
useCollapsible,
} from "@chakra-ui/react"
import { LuChevronDown, LuChevronRight } from "react-icons/lu"
export const CollapsibleWithStore = () => {
const collapsible = useCollapsible()
return (
State: {collapsible.visible ? "Expanded" : "Collapsed"}
Using the useCollapsible hook and{" "}
RootProvider allows you to access the collapsible store
and control the state from anywhere in your component.
)
}
```
### Lazy Mounted
Use the `unmountOnExit` prop to make the content unmount when collapsed.
```tsx
import { Box, Collapsible } from "@chakra-ui/react"
export const CollapsibleLazyMounted = () => (
Toggle Collapse (Unmount on exit)
If you inspect the DOM, you'll notice that the content is unmounted when
collapsed. This is useful for performance reasons when you have a lot of
collapsible content.
)
```
## Guides
### Content Padding
To prevent janky animations when the collapsible expands or collapses, apply
padding to the inner content element rather than directly on
`Collapsible.Content` to prevent visual stuttering as its animations.
**DO THIS:**
```tsx
Toggle
{/* Content here */}
```
**NOT THIS:**
```tsx
Toggle
{/* ❌ Avoid applying padding directly to Content */}
{/* Content here */}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultOpen | undefined | `boolean` | The initial open state of the collapsible when rendered.
Use when you don't need to control the open state of the collapsible. |
| disabled | undefined | `boolean` | Whether the collapsible is disabled. |
| ids | undefined | `Partial<{ root: string; content: string; trigger: string }>` | The ids of the elements in the collapsible. Useful for composition. |
| onExitComplete | undefined | `VoidFunction` | The callback invoked when the exit animation completes. |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | The callback invoked when the open state changes. |
| open | undefined | `boolean` | The controlled open state of the collapsible. |
## Explorer
Explore the `Collapsible` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Color Picker
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
export const ColorPickerBasic = () => {
return (
Color
)
}
```
## Usage
```jsx
import { ColorPicker } from "@chakra-ui/react"
```
```jsx
```
## Shortcuts
### ColorPicker.ChannelSlider
This component renders the slider track, thumb and transparency grid.
```tsx
```
is the same as:
```tsx
```
### ColorPicker.Sliders
This is a shortcut component for the hue and alpha sliders:
```tsx
```
### ColorPicker.Area
This component renders the color area thumb and background.
```tsx
```
is the same as:
```tsx
```
### ColorPicker.EyeDropper
This is a shortcut component for:
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the color picker.
```tsx
"use client"
import {
ColorPicker,
For,
HStack,
Portal,
Stack,
parseColor,
} from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const ColorPickerWithSizes = () => {
return (
{(size) => (
Color ({size})
{swatches.map((item) => (
))}
)}
)
}
const swatches = ["red", "blue", "green"]
```
### Variants
Use the `variant` prop to change the visual style of the color picker. Values
can be either `outline` or `subtle`.
```tsx
"use client"
import {
ColorPicker,
For,
HStack,
Portal,
Stack,
parseColor,
} from "@chakra-ui/react"
export const ColorPickerWithVariants = () => {
return (
{(variant) => (
Color ({variant})
)}
)
}
```
### Input Only
Combine the `ColorPicker.ValueSwatch` and the `ColorPicker.EyeDropper` on the
`InputGroup` to render a color picker that contains only an input.
```tsx
"use client"
import { ColorPicker, InputGroup, parseColor } from "@chakra-ui/react"
export const ColorPickerInputOnly = () => {
return (
Color}
endElementProps={{ px: "1" }}
endElement={}
>
)
}
```
### Swatch Only
Use the `ColorPicker.SwatchGroup` and `ColorPicker.SwatchTrigger` to render only
the color swatches.
```tsx
import { ColorPicker } from "@chakra-ui/react"
export const ColorPickerSwatchOnly = () => {
return (
Color:
{swatches.map((item) => (
))}
)
}
const swatches = ["red", "green", "blue", "purple", "orange", "pink"]
```
### Trigger Only
Compose the color picker to initially show only a trigger using the
`ColorPicker.ValueSwatch` and `ColorPicker.ValueText`.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
export const ColorPickerTriggerOnly = () => {
return (
Color
)
}
```
### Trigger Inside Input
Compose the color picker to trigger in input using the `InputGroup` and
`ColorPickerInput`.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
export const ColorPickerTriggerOnly = () => {
return (
Color
)
}
```
### Controlled
Use the `value` and `onValueChange` props to control the state of the color
picker.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
import { useState } from "react"
export const ColorPickerControlled = () => {
const [color, setColor] = useState(parseColor("#eb5e41"))
return (
setColor(e.value)}
maxW="200px"
>
Color
)
}
```
### Store
An alternative way to control the color picker is to use the `RootProvider`
component and the `useColorPicker` store hook.
This way you can access the color picker state and methods from outside the
color picker.
```tsx
"use client"
import {
ColorPicker,
HStack,
Portal,
parseColor,
useColorPicker,
} from "@chakra-ui/react"
export const ColorPickerWithStore = () => {
const colorPicker = useColorPicker({
defaultValue: parseColor("#eb5e41"),
})
return (
Color
)
}
```
### Change End
Use the `onValueChangeEnd` to listen to when the user finishes selecting a
color, rather than while they are scrubbing or dragging through the color area.
```tsx
"use client"
import {
Code,
ColorPicker,
HStack,
Portal,
Stack,
parseColor,
} from "@chakra-ui/react"
import { useState } from "react"
export const ColorPickerChangeEnd = () => {
const [value, setValue] = useState(parseColor("#eb5e41"))
return (
onChangeEnd: {value.toString("hex")} setValue(e.value)}
>
Color
)
}
```
### Channel Slider
Combine the `ColorPickerChannelSliders` and the `format` prop to add the
different color channels to the color picker.
```tsx
"use client"
import {
ColorPicker,
For,
Portal,
Stack,
getColorChannels,
parseColor,
} from "@chakra-ui/react"
const ChannelSliders = (props: { format: ColorPicker.ColorFormat }) => {
const channels = getColorChannels(props.format)
return (
{(channel) => (
{channel}
)}
)
}
export const ColorPickerChannelSliderOnly = () => {
return (
)
}
```
### Hook Form
Here's an example of how to integrate the color picker with `react-hook-form`.
```tsx
"use client"
import {
Button,
ColorPicker,
HStack,
Portal,
Stack,
parseColor,
} from "@chakra-ui/react"
import { Controller, useForm } from "react-hook-form"
interface FormValues {
color: string
}
export const ColorPickerWithHookForm = () => {
const { control, handleSubmit } = useForm({
defaultValues: { color: "#000000" },
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Inline
Here's an example of how to display an inline version of the color picker.
```tsx
"use client"
import { ColorPicker, HStack, parseColor } from "@chakra-ui/react"
export const ColorPickerInline = () => {
return (
)
}
```
### Disabled
Pass the `disabled` prop to disable the color picker.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
export const ColorPickerWithDisabled = () => {
return (
Color
)
}
```
### Channel Input
Use the `ChannelFormat.Select` and `ColorPicker.ChannelInput` to create a color
picker that allows users to select their preferred channel.
```tsx
"use client"
import {
ColorPicker,
For,
HStack,
Portal,
VStack,
getColorChannels,
parseColor,
} from "@chakra-ui/react"
const ChannelInputs = (props: { format: ColorPicker.ColorFormat }) => {
const channels = getColorChannels(props.format)
return (
{(channel) => (
{channel.charAt(0).toUpperCase()}
)}
)
}
export const ColorPickerWithChannelInput = () => {
return (
Color
)
}
```
### Fit Content
Pass the `data-fit-content` attribute to the `ColorPicker.Trigger` to make it
fit the content.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
export const ColorPickerWithFitContent = () => {
return (
Color
)
}
```
### ReadOnly
Use the `readOnly` prop to make the color picker component read-only.
### Save Swatch
Here's an example of how to save a selected color as a swatch.
```tsx
"use client"
import {
Button,
ColorPicker,
HStack,
IconButton,
Portal,
Show,
VStack,
parseColor,
} from "@chakra-ui/react"
import { useState } from "react"
import { LuCheck, LuPlus, LuType } from "react-icons/lu"
export const ColorPickerWithSaveSwatch = () => {
const [color, setColor] = useState(parseColor("#000"))
const [view, setView] = useState<"picker" | "swatch">("swatch")
const [swatches, setSwatches] = useState([
"#FF0000",
"#00FF00",
"#0000FF",
"#FFFF00",
])
return (
setColor(e.value)}
maxW="200px"
>
{swatches.map((swatch) => (
))}
setView("picker")}
>
)
}
```
### Swatches
Here's an example of how to combine the color picker with pre-defined swatches.
```tsx
"use client"
import { ColorPicker, HStack, Portal, parseColor } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const ColorPickerWithSwatches = () => {
return (
Color
{swatches.map((item) => (
))}
)
}
// prettier-ignore
const swatches = ["#000000", "#4A5568", "#F56565", "#ED64A6", "#9F7AEA", "#6B46C1", "#4299E1", "#0BC5EA", "#00B5D8", "#38B2AC", "#48BB78", "#68D391", "#ECC94B", "#DD6B20"]
```
### Swatch and Input
Here's how to compose a swatch with an input.
```tsx
"use client"
import { ColorPicker, Portal, parseColor } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const ColorPickerWithSwatchAndInput = () => {
return (
{swatches.map((item) => (
))}
)
}
const swatches = ["red", "blue", "green"]
```
### Swatch and Trigger
Here's how to compose a swatch with a trigger.
```tsx
"use client"
import { ColorPicker, Portal, parseColor } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const ColorPickerWithSwatchAndInput = () => {
return (
{swatches.map((item) => (
))}
)
}
const swatches = ["red", "blue", "green"]
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeOnSelect | false | `boolean` | Whether to close the color picker when a swatch is selected |
| defaultFormat | "rgba" | `ColorFormat` | The initial color format when rendered.
Use when you don't need to control the color format of the color picker. |
| defaultValue | #000000 | `Color` | The initial color value when rendered.
Use when you don't need to control the color value of the color picker. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| openAutoFocus | true | `boolean` | Whether to auto focus the color picker when it is opened |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | outline | `'outline' \| 'subtle'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultOpen | undefined | `boolean` | The initial open state of the color picker when rendered.
Use when you don't need to control the open state of the color picker. |
| disabled | undefined | `boolean` | Whether the color picker is disabled |
| format | undefined | `ColorFormat` | The controlled color format to use |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; control: string; trigger: string; label: string; input: string; hiddenInput: string; content: string; area: string; areaGradient: string; positioner: string; formatSelect: string; areaThumb: string; channelInput: (id: string) => string; channelSliderTrack: (id: ColorChannel) => string; channe...` | The ids of the elements in the color picker. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| initialFocusEl | undefined | `() => HTMLElement \| null` | The initial focus element when the color picker is opened. |
| inline | undefined | `boolean` | Whether to render the color picker inline |
| invalid | undefined | `boolean` | Whether the color picker is invalid |
| name | undefined | `string` | The name for the form input |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onFormatChange | undefined | `(details: FormatChangeDetails) => void` | Function called when the color format changes |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Handler that is called when the user opens or closes the color picker. |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Handler that is called when the value changes, as the user drags. |
| onValueChangeEnd | undefined | `(details: ValueChangeDetails) => void` | Handler that is called when the user stops dragging. |
| open | undefined | `boolean` | The controlled open state of the color picker |
| positioning | undefined | `PositioningOptions` | The positioning options for the color picker |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
| readOnly | undefined | `boolean` | Whether the color picker is read-only |
| required | undefined | `boolean` | Whether the color picker is required |
| value | undefined | `Color` | The controlled color value of the color picker |
## Explorer
Explore the `Color Picker` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Color Swatch
```tsx
import { ColorSwatch } from "@chakra-ui/react"
export const ColorSwatchBasic = () => {
return
}
```
## Usage
```tsx
import { ColorSwatch } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the color swatch.
```tsx
import { HStack } from "@chakra-ui/react"
import { ColorSwatch } from "@chakra-ui/react"
import { For } from "@chakra-ui/react"
export const ColorSwatchWithSizes = () => {
return (
{(size) => }
)
}
```
### Alpha
Here's an example of how to create a color swatch with an alpha channel.
```tsx
import { ColorSwatch, HStack } from "@chakra-ui/react"
export const ColorSwatchWithAlpha = () => {
return (
{colors.map((color) => (
))}
)
}
const colors = [
"rgba(255, 0, 0, 0.5)",
"rgba(0, 0, 255, 0.7)",
"rgba(0, 255, 0, 0.4)",
"rgba(255, 192, 203, 0.6)",
]
```
### With Badge
Here's an example of how to compose the `ColorSwatch` with a `Badge`.
```tsx
import { Badge, ColorSwatch } from "@chakra-ui/react"
export const ColorSwatchWithBadge = () => {
return (
#bada55
)
}
```
### Mixed Colors
Use the `ColorSwatchMix` to create a color swatch that contains multiple colors,
but retains the size of a single color swatch.
```tsx
import { ColorSwatchMix, HStack } from "@chakra-ui/react"
export const ColorSwatchMixed = () => {
return (
)
}
```
### Palette
Here's an example of composing multiple swatches to create a palette.
```tsx
import { ColorSwatch, Group } from "@chakra-ui/react"
export const ColorSwatchPalette = () => {
return (
{swatches.map((color) => (
))}
)
}
const swatches = ["#ff0000", "#00ff00", "#0000ff", "#ffff00", "#ff00ff"]
```
# Combobox
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxBasic = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
## Usage
```tsx
import { Combobox } from "@chakra-ui/react"
```
```tsx
```
To setup combobox, you might need to import the following hooks:
- `useListCollection`: Used to manage the list of items in the combobox,
providing helpful methods for filtering and mutating the list.
- `useFilter`: Used to provide the filtering logic for the combobox based on
[`Intl.Collator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator)
APIs.
## Examples
### Basic
The basic combobox provides a searchable dropdown with single selection.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxBasic = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Sizes
Pass the `size` prop to the `Combobox.Root` to change the size of the combobox.
```tsx
"use client"
import {
Combobox,
Portal,
Stack,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithSizes = () => {
return (
)
}
const ComboboxDemo = (props: Omit) => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
collection={collection}
>
Select framework ({props.size?.toString()})
No items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Variants
Pass the `variant` prop to the `Combobox.Root` to change the appearance of the
combobox.
```tsx
"use client"
import {
Combobox,
Portal,
Stack,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithVariants = () => {
return (
)
}
const ComboboxDemo = (props: Omit) => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
collection={collection}
>
Select framework ({props.variant?.toString()})
No items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Multiple
Pass the `multiple` prop to the `Combobox.Root` to enable multiple selection.
This allows users to select multiple items from the list.
> When this is set, the combobox will always clear the input value when an item
> is selected.
```tsx
"use client"
import {
Badge,
Combobox,
Portal,
Wrap,
createListCollection,
} from "@chakra-ui/react"
import { useMemo, useState } from "react"
const skills = [
"JavaScript",
"TypeScript",
"React",
"Node.js",
"GraphQL",
"PostgreSQL",
]
export const ComboboxWithMultiple = () => {
const [searchValue, setSearchValue] = useState("")
const [selectedSkills, setSelectedSkills] = useState([])
const filteredItems = useMemo(
() =>
skills.filter((item) =>
item.toLowerCase().includes(searchValue.toLowerCase()),
),
[searchValue],
)
const collection = useMemo(
() => createListCollection({ items: filteredItems }),
[filteredItems],
)
const handleValueChange = (details: Combobox.ValueChangeDetails) => {
setSelectedSkills(details.value)
}
return (
setSearchValue(details.inputValue)}
>
{selectedSkills.map((skill) => (
{skill}
))}
Select SkillsSkills
{filteredItems.map((item) => (
{item}
))}
No skills found
)
}
```
### Async Loading
Here's an example of loading the `collection` asynchronously as users type,
perfect for API-driven search interfaces.
```tsx
"use client"
import {
Combobox,
HStack,
Portal,
Span,
Spinner,
useListCollection,
} from "@chakra-ui/react"
import { useState } from "react"
import { useAsync } from "react-use"
export const ComboboxWithAsyncContent = () => {
const [inputValue, setInputValue] = useState("")
const { collection, set } = useListCollection({
initialItems: [],
itemToString: (item) => item.name,
itemToValue: (item) => item.name,
})
const state = useAsync(async () => {
const response = await fetch(
`https://swapi.py4e.com/api/people/?search=${inputValue}`,
)
const data = await response.json()
set(data.results)
}, [inputValue, set])
return (
setInputValue(e.inputValue)}
positioning={{ sameWidth: false, placement: "bottom-start" }}
>
Search Star Wars Characters
{state.loading ? (
Loading...
) : state.error ? (
Error fetching
) : (
collection.items?.map((character) => (
{character.name}
{character.height}cm / {character.mass}kg
))
)}
)
}
interface Character {
name: string
height: string
mass: string
created: string
edited: string
url: string
}
```
### Highlight Matching Text
Here's an example of composing the `Combobox.Item` and `Highlight` components to
highlight matching text in search results.
```tsx
"use client"
import {
Combobox,
Highlight,
Portal,
useComboboxContext,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithHighlight = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
>
Select frameworkNo items found
{collection.items.map((item) => (
))}
)
}
function ComboboxItem(props: { item: { label: string; value: string } }) {
const { item } = props
const combobox = useComboboxContext()
return (
{item.label}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Open on Click
Use the `openOnClick` prop to open the combobox when the user clicks on the
input.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxOpenOnClick = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
openOnClick
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Custom Objects
By default, the combobox collection expects an array of objects with `label` and
`value` properties. In some cases, you may need to deal with custom objects.
Use the `itemToString` and `itemToValue` props to map the custom object to the
required interface.
```tsx
const items = [
{ country: "United States", code: "US", flag: "🇺🇸" },
{ country: "Canada", code: "CA", flag: "🇨🇦" },
{ country: "Australia", code: "AU", flag: "🇦🇺" },
// ...
]
const { contains } = useFilter({ sensitivity: "base" })
const { collection } = useListCollection({
initialItems: items,
itemToString: (item) => item.country,
itemToValue: (item) => item.code,
filter: contains,
})
```
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithCustomObject = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: countries,
itemToString: (item) => item.country,
itemToValue: (item) => item.code,
filter: contains,
})
const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
filter(details.inputValue)
}
return (
Search CountriesNo items found
{collection.items.map((item) => (
{item.country}
))}
)
}
const countries = [
{ country: "United States", code: "US", flag: "🇺🇸" },
{ country: "Canada", code: "CA", flag: "🇨🇦" },
{ country: "Australia", code: "AU", flag: "🇦🇺" },
{ country: "United Kingdom", code: "UK", flag: "🇬🇧" },
{ country: "New Zealand", code: "NZ", flag: "🇳🇿" },
{ country: "South Africa", code: "ZA", flag: "🇿🇦" },
{ country: "India", code: "IN", flag: "🇮🇳" },
{ country: "China", code: "CN", flag: "🇨🇳" },
{ country: "Japan", code: "JP", flag: "🇯🇵" },
{ country: "Korea", code: "KR", flag: "🇰🇷" },
{ country: "Vietnam", code: "VN", flag: "🇻🇳" },
{ country: "Thailand", code: "TH", flag: "🇹🇭" },
{ country: "Malaysia", code: "MY", flag: "🇲🇾" },
{ country: "Indonesia", code: "ID", flag: "🇮🇩" },
{ country: "Philippines", code: "PH", flag: "🇵🇭" },
{ country: "Singapore", code: "SG", flag: "🇸🇬" },
{ country: "Hong Kong", code: "HK", flag: "🇭🇰" },
{ country: "Macau", code: "MO", flag: "🇲🇴" },
{ country: "Taiwan", code: "TW", flag: "🇹🇼" },
]
```
### Minimum Characters
Use the `openOnChange` prop to set a minimum number of characters before
filtering the list.
```tsx
e.inputValue.length > 2} />
```
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxMinCharacter = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
openOnChange={(e) => e.inputValue.length > 2}
width="320px"
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Field
Compose the `Combobox` component with the `Field` component to wrap the combobox
in a form field. Useful for form layouts.
```tsx
"use client"
import {
Combobox,
Field,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithField = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
Select framework filter(e.inputValue)}
>
The framework you love to useNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Form + Custom Object
When working with custom objects in forms, you often need to submit the
programmatic value rather than the display value. This example shows how to
combine custom object mapping with form submission using a hidden input.
The key is using `itemToValue` to define what gets submitted, while
`itemToString` controls what users see. A hidden input captures the programmatic
value for form submission.
> In this example, users see "🇺🇸 United States" but the form submits "US".
```tsx
"use client"
import {
Button,
Combobox,
Field,
Portal,
Stack,
useComboboxContext,
useFilter,
useListCollection,
} from "@chakra-ui/react"
// This is a hidden input that is used to store the value of the combobox
const ComboboxHiddenInput = (props: React.ComponentProps<"input">) => {
const combobox = useComboboxContext()
return
}
export const ComboboxWithFormSubmit = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: countries,
itemToString: (item) => item.country,
itemToValue: (item) => item.code,
filter: contains,
})
const handleSubmit = (event: React.FormEvent) => {
event.preventDefault()
const formData = new FormData(event.currentTarget)
const country = formData.get("country")
console.log("Form submitted with country code:", country)
alert(`Selected country code: ${country}`)
}
const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
filter(details.inputValue)
}
return (
)
}
const countries = [
{ country: "United States", code: "US", flag: "🇺🇸" },
{ country: "Canada", code: "CA", flag: "🇨🇦" },
{ country: "Australia", code: "AU", flag: "🇦🇺" },
{ country: "United Kingdom", code: "GB", flag: "🇬🇧" },
{ country: "New Zealand", code: "NZ", flag: "🇳🇿" },
{ country: "South Africa", code: "ZA", flag: "🇿🇦" },
{ country: "India", code: "IN", flag: "🇮🇳" },
{ country: "China", code: "CN", flag: "🇨🇳" },
{ country: "Japan", code: "JP", flag: "🇯🇵" },
{ country: "Korea", code: "KR", flag: "🇰🇷" },
{ country: "Vietnam", code: "VN", flag: "🇻🇳" },
{ country: "Thailand", code: "TH", flag: "🇹🇭" },
{ country: "Malaysia", code: "MY", flag: "🇲🇾" },
{ country: "Indonesia", code: "ID", flag: "🇮🇩" },
{ country: "Philippines", code: "PH", flag: "🇵🇭" },
{ country: "Singapore", code: "SG", flag: "🇸🇬" },
{ country: "Hong Kong", code: "HK", flag: "🇭🇰" },
{ country: "Macau", code: "MO", flag: "🇲🇴" },
{ country: "Taiwan", code: "TW", flag: "🇹🇼" },
]
```
### Hook Form
This example demonstrates how to integrate the Combobox with React Hook Form
using the `Controller` component. The form automatically receives the item's
`value` property without needing a hidden input.
Users see "React" but the form receives "react".
```tsx
"use client"
import {
Button,
Combobox,
Field,
Portal,
Stack,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
framework: z.string({ message: "Framework is required" }).min(1),
})
type FormValues = z.infer
export const ComboboxWithHookForm = () => {
const {
handleSubmit,
formState: { errors },
control,
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => {
console.log("Form submitted with:", data)
alert(`Selected framework: ${data.framework}`)
})
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
filter(details.inputValue)
}
return (
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Solid", value: "solid" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine", value: "alpine" },
]
```
### Disabled State
Pass the `disabled` prop to the `Combobox.Root` to disable the entire combobox.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithDisabled = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
disabled
width="320px"
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Disabled Item
Disable specific items in the dropdown, add the `disabled` prop to the
collection item.
```tsx {2}
const items = [
{ label: "Item 1", value: "item-1", disabled: true },
{ label: "Item 2", value: "item-2" },
]
const { collection } = useListCollection({
initialItems: items,
// ...
})
```
```tsx
"use client"
import {
Combobox,
HStack,
Icon,
Portal,
Span,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithDisabledItem = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: companies,
filter: contains,
itemToValue: (item) => item.id,
itemToString: (item) => item.name,
isItemDisabled: (item) => !!item.disabled,
})
const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
filter(details.inputValue)
}
return (
Select a CompanyCompanies
{collection.items.map((country) => {
return (
{country.logo}{country.name}
)
})}
)
}
interface Company {
id: string
name: string
logo: React.ReactElement
disabled?: boolean
}
const companies: Company[] = [
{
id: "airbnb",
name: "Airbnb",
logo: (
),
},
{
id: "tesla",
disabled: true,
logo: (
),
name: "Tesla",
},
{
logo: (
),
id: "nvida",
name: "NVIDA",
},
{
id: "amazon",
name: "Amazon",
logo: (
),
},
]
```
### Input Group
Combine with InputGroup to add icons or other elements.
```tsx
"use client"
import {
Combobox,
InputGroup,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { LuCode } from "react-icons/lu"
export const ComboboxWithInputGroup = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
>
Select framework}>
No items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Invalid
Pass the `invalid` prop to the `Combobox.Root` to show the error state.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithInvalid = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
invalid
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Controlled Value
Use the `value` and `onValueChange` props to control the combobox's value
programmatically.
```tsx
"use client"
import {
Badge,
Combobox,
For,
HStack,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { useState } from "react"
export const ComboboxControlled = () => {
const [value, setValue] = useState([])
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
value={value}
onValueChange={(e) => setValue(e.value)}
width="320px"
>
Selected:
{(v) => {v}}
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Store
An alternative way to control the combobox is to use the `Combobox.RootProvider`
component and the `useCombobox` store hook.
```tsx
import { Combobox, useCombobox } from "@chakra-ui/react"
function Demo() {
const combobox = useCombobox()
return (
{/* ... */}
)
}
```
This way you can access the combobox state and methods from outside the
combobox.
```tsx
"use client"
import {
Combobox,
Portal,
useCombobox,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithStore = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
const combobox = useCombobox({
collection,
onInputValueChange(e) {
filter(e.inputValue)
},
})
return (
Select framework
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Controlled Open
Use the `open` and `onOpenChange` props to control the combobox's open state
programmatically.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { useState } from "react"
export const ComboboxOpenControlled = () => {
const [open, setOpen] = useState(false)
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
open={open}
onOpenChange={(e) => setOpen(e.open)}
>
Combobox is {open ? "open" : "closed"}No items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Limit Large Datasets
The recommended way of managing large lists is to use the `limit` property on
the `useListCollection` hook. This will limit the number of rendered items in
the DOM to improve performance.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { useRef } from "react"
export const ComboboxWithLimit = () => {
const contentRef = useRef(null)
const { startsWith } = useFilter({ sensitivity: "base" })
const { collection, filter, reset } = useListCollection({
initialItems: items,
filter: startsWith,
limit: 10,
})
return (
filter(e.inputValue)}
openOnClick
width="320px"
>
Select framework
{collection.items.map((item) => (
{item.emoji}
{item.label}
))}
)
}
export const items = [
{ value: "AD", label: "Andorra", emoji: "🇦🇩" },
{ value: "AE", label: "United Arab Emirates", emoji: "🇦🇪" },
{ value: "AF", label: "Afghanistan", emoji: "🇦🇫" },
{ value: "AG", label: "Antigua and Barbuda", emoji: "🇦🇬" },
{ value: "AI", label: "Anguilla", emoji: "🇦🇮" },
{ value: "AL", label: "Albania", emoji: "🇦🇱" },
{ value: "AM", label: "Armenia", emoji: "🇦🇲" },
{ value: "AO", label: "Angola", emoji: "🇦🇴" },
{ value: "AQ", label: "Antarctica", emoji: "🇦🇶" },
{ value: "AR", label: "Argentina", emoji: "🇦🇷" },
{ value: "AS", label: "American Samoa", emoji: "🇦🇸" },
{ value: "AT", label: "Austria", emoji: "🇦🇹" },
{ value: "AU", label: "Australia", emoji: "🇦🇺" },
{ value: "AW", label: "Aruba", emoji: "🇦🇼" },
{ value: "AX", label: "Åland Islands", emoji: "🇦🇽" },
{ value: "AZ", label: "Azerbaijan", emoji: "🇦🇿" },
{ value: "BA", label: "Bosnia and Herzegovina", emoji: "🇧🇦" },
{ value: "BB", label: "Barbados", emoji: "🇧🇧" },
{ value: "BD", label: "Bangladesh", emoji: "🇧🇩" },
{ value: "BE", label: "Belgium", emoji: "🇧🇪" },
{ value: "BF", label: "Burkina Faso", emoji: "🇧🇫" },
{ value: "BG", label: "Bulgaria", emoji: "🇧🇬" },
{ value: "BH", label: "Bahrain", emoji: "🇧🇭" },
{ value: "BI", label: "Burundi", emoji: "🇧🇮" },
{ value: "BJ", label: "Benin", emoji: "🇧🇯" },
{ value: "BL", label: "Saint Barthélemy", emoji: "🇧🇱" },
{ value: "BM", label: "Bermuda", emoji: "🇧🇲" },
{ value: "BN", label: "Brunei Darussalam", emoji: "🇧🇳" },
{ value: "BO", label: "Bolivia, Plurinational State of", emoji: "🇧🇴" },
{ value: "BQ", label: "Bonaire, Sint Eustatius and Saba", emoji: "🇧🇶" },
{ value: "BR", label: "Brazil", emoji: "🇧🇷" },
{ value: "BS", label: "Bahamas", emoji: "🇧🇸" },
{ value: "BT", label: "Bhutan", emoji: "🇧🇹" },
{ value: "BV", label: "Bouvet Island", emoji: "🇧🇻" },
{ value: "BW", label: "Botswana", emoji: "🇧🇼" },
{ value: "BY", label: "Belarus", emoji: "🇧🇾" },
{ value: "BZ", label: "Belize", emoji: "🇧🇿" },
{ value: "CA", label: "Canada", emoji: "🇨🇦" },
{ value: "CC", label: "Cocos (Keeling) Islands", emoji: "🇨🇨" },
{ value: "CD", label: "Congo, Democratic Republic of the", emoji: "🇨🇩" },
{ value: "CF", label: "Central African Republic", emoji: "🇨🇫" },
{ value: "CG", label: "Congo", emoji: "🇨🇬" },
{ value: "CH", label: "Switzerland", emoji: "🇨🇭" },
{ value: "CI", label: "Côte d'Ivoire", emoji: "🇨🇮" },
{ value: "CK", label: "Cook Islands", emoji: "🇨🇰" },
{ value: "CL", label: "Chile", emoji: "🇨🇱" },
{ value: "CM", label: "Cameroon", emoji: "🇨🇲" },
{ value: "CN", label: "China", emoji: "🇨🇳" },
{ value: "CO", label: "Colombia", emoji: "🇨🇴" },
{ value: "CR", label: "Costa Rica", emoji: "🇨🇷" },
{ value: "CU", label: "Cuba", emoji: "🇨🇺" },
{ value: "CV", label: "Cabo Verde", emoji: "🇨🇻" },
{ value: "CW", label: "Curaçao", emoji: "🇨🇼" },
{ value: "CX", label: "Christmas Island", emoji: "🇨🇽" },
{ value: "CY", label: "Cyprus", emoji: "🇨🇾" },
{ value: "CZ", label: "Czechia", emoji: "🇨🇿" },
{ value: "DE", label: "Germany", emoji: "🇩🇪" },
{ value: "DJ", label: "Djibouti", emoji: "🇩🇯" },
{ value: "DK", label: "Denmark", emoji: "🇩🇰" },
{ value: "DM", label: "Dominica", emoji: "🇩🇲" },
{ value: "DO", label: "Dominican Republic", emoji: "🇩🇴" },
{ value: "DZ", label: "Algeria", emoji: "🇩🇿" },
{ value: "EC", label: "Ecuador", emoji: "🇪🇨" },
{ value: "EE", label: "Estonia", emoji: "🇪🇪" },
{ value: "EG", label: "Egypt", emoji: "🇪🇬" },
{ value: "EH", label: "Western Sahara", emoji: "🇪🇭" },
{ value: "ER", label: "Eritrea", emoji: "🇪🇷" },
{ value: "ES", label: "Spain", emoji: "🇪🇸" },
{ value: "ET", label: "Ethiopia", emoji: "🇪🇹" },
{ value: "FI", label: "Finland", emoji: "🇫🇮" },
{ value: "FJ", label: "Fiji", emoji: "🇫🇯" },
{ value: "FK", label: "Falkland Islands (Malvinas)", emoji: "🇫🇰" },
{ value: "FM", label: "Micronesia, Federated States of", emoji: "🇫🇲" },
{ value: "FO", label: "Faroe Islands", emoji: "🇫🇴" },
{ value: "FR", label: "France", emoji: "🇫🇷" },
{ value: "GA", label: "Gabon", emoji: "🇬🇦" },
{
value: "GB",
label: "United Kingdom of Great Britain and Northern Ireland",
emoji: "🇬🇧",
},
{ value: "GD", label: "Grenada", emoji: "🇬🇩" },
{ value: "GE", label: "Georgia", emoji: "🇬🇪" },
{ value: "GF", label: "French Guiana", emoji: "🇬🇫" },
{ value: "GG", label: "Guernsey", emoji: "🇬🇬" },
{ value: "GH", label: "Ghana", emoji: "🇬🇭" },
{ value: "GI", label: "Gibraltar", emoji: "🇬🇮" },
{ value: "GL", label: "Greenland", emoji: "🇬🇱" },
{ value: "GM", label: "Gambia", emoji: "🇬🇲" },
{ value: "GN", label: "Guinea", emoji: "🇬🇳" },
{ value: "GP", label: "Guadeloupe", emoji: "🇬🇵" },
{ value: "GQ", label: "Equatorial Guinea", emoji: "🇬🇶" },
{ value: "GR", label: "Greece", emoji: "🇬🇷" },
{
value: "GS",
label: "South Georgia and the South Sandwich Islands",
emoji: "🇬🇸",
},
{ value: "GT", label: "Guatemala", emoji: "🇬🇹" },
{ value: "GU", label: "Guam", emoji: "🇬🇺" },
{ value: "GW", label: "Guinea-Bissau", emoji: "🇬🇼" },
{ value: "GY", label: "Guyana", emoji: "🇬🇾" },
{ value: "HK", label: "Hong Kong", emoji: "🇭🇰" },
{ value: "HM", label: "Heard Island and McDonald Islands", emoji: "🇭🇲" },
{ value: "HN", label: "Honduras", emoji: "🇭🇳" },
{ value: "HR", label: "Croatia", emoji: "🇭🇷" },
{ value: "HT", label: "Haiti", emoji: "🇭🇹" },
{ value: "HU", label: "Hungary", emoji: "🇭🇺" },
{ value: "ID", label: "Indonesia", emoji: "🇮🇩" },
{ value: "IE", label: "Ireland", emoji: "🇮🇪" },
{ value: "IL", label: "Israel", emoji: "🇮🇱" },
{ value: "IM", label: "Isle of Man", emoji: "🇮🇲" },
{ value: "IN", label: "India", emoji: "🇮🇳" },
{ value: "IO", label: "British Indian Ocean Territory", emoji: "🇮🇴" },
{ value: "IQ", label: "Iraq", emoji: "🇮🇶" },
{ value: "IR", label: "Iran, Islamic Republic of", emoji: "🇮🇷" },
{ value: "IS", label: "Iceland", emoji: "🇮🇸" },
{ value: "IT", label: "Italy", emoji: "🇮🇹" },
{ value: "JE", label: "Jersey", emoji: "🇯🇪" },
{ value: "JM", label: "Jamaica", emoji: "🇯🇲" },
{ value: "JO", label: "Jordan", emoji: "🇯🇴" },
{ value: "JP", label: "Japan", emoji: "🇯🇵" },
{ value: "KE", label: "Kenya", emoji: "🇰🇪" },
{ value: "KG", label: "Kyrgyzstan", emoji: "🇰🇬" },
{ value: "KH", label: "Cambodia", emoji: "🇰🇭" },
{ value: "KI", label: "Kiribati", emoji: "🇰🇮" },
{ value: "KM", label: "Comoros", emoji: "🇰🇲" },
{ value: "KN", label: "Saint Kitts and Nevis", emoji: "🇰🇳" },
{ value: "KP", label: "Korea, Democratic People's Republic of", emoji: "🇰🇵" },
{ value: "KR", label: "Korea, Republic of", emoji: "🇰🇷" },
{ value: "KW", label: "Kuwait", emoji: "🇰🇼" },
{ value: "KY", label: "Cayman Islands", emoji: "🇰🇾" },
{ value: "KZ", label: "Kazakhstan", emoji: "🇰🇿" },
{ value: "LA", label: "Lao People's Democratic Republic", emoji: "🇱🇦" },
{ value: "LB", label: "Lebanon", emoji: "🇱🇧" },
{ value: "LC", label: "Saint Lucia", emoji: "🇱🇨" },
{ value: "LI", label: "Liechtenstein", emoji: "🇱🇮" },
{ value: "LK", label: "Sri Lanka", emoji: "🇱🇰" },
{ value: "LR", label: "Liberia", emoji: "🇱🇷" },
{ value: "LS", label: "Lesotho", emoji: "🇱🇸" },
{ value: "LT", label: "Lithuania", emoji: "🇱🇹" },
{ value: "LU", label: "Luxembourg", emoji: "🇱🇺" },
{ value: "LV", label: "Latvia", emoji: "🇱🇻" },
{ value: "LY", label: "Libya", emoji: "🇱🇾" },
{ value: "MA", label: "Morocco", emoji: "🇲🇦" },
{ value: "MC", label: "Monaco", emoji: "🇲🇨" },
{ value: "MD", label: "Moldova, Republic of", emoji: "🇲🇩" },
{ value: "ME", label: "Montenegro", emoji: "🇲🇪" },
{ value: "MF", label: "Saint Martin, (French part)", emoji: "🇲🇫" },
{ value: "MG", label: "Madagascar", emoji: "🇲🇬" },
{ value: "MH", label: "Marshall Islands", emoji: "🇲🇭" },
{ value: "MK", label: "North Macedonia", emoji: "🇲🇰" },
{ value: "ML", label: "Mali", emoji: "🇲🇱" },
{ value: "MM", label: "Myanmar", emoji: "🇲🇲" },
{ value: "MN", label: "Mongolia", emoji: "🇲🇳" },
{ value: "MO", label: "Macao", emoji: "🇲🇴" },
{ value: "MP", label: "Northern Mariana Islands", emoji: "🇲🇵" },
{ value: "MQ", label: "Martinique", emoji: "🇲🇶" },
{ value: "MR", label: "Mauritania", emoji: "🇲🇷" },
{ value: "MS", label: "Montserrat", emoji: "🇲🇸" },
{ value: "MT", label: "Malta", emoji: "🇲🇹" },
{ value: "MU", label: "Mauritius", emoji: "🇲🇺" },
{ value: "MV", label: "Maldives", emoji: "🇲🇻" },
{ value: "MW", label: "Malawi", emoji: "🇲🇼" },
{ value: "MX", label: "Mexico", emoji: "🇲🇽" },
{ value: "MY", label: "Malaysia", emoji: "🇲🇾" },
{ value: "MZ", label: "Mozambique", emoji: "🇲🇿" },
{ value: "NA", label: "Namibia", emoji: "🇳🇦" },
{ value: "NC", label: "New Caledonia", emoji: "🇳🇨" },
{ value: "NE", label: "Niger", emoji: "🇳🇪" },
{ value: "NF", label: "Norfolk Island", emoji: "🇳🇫" },
{ value: "NG", label: "Nigeria", emoji: "🇳🇬" },
{ value: "NI", label: "Nicaragua", emoji: "🇳🇮" },
{ value: "NL", label: "Netherlands", emoji: "🇳🇱" },
{ value: "NO", label: "Norway", emoji: "🇳🇴" },
{ value: "NP", label: "Nepal", emoji: "🇳🇵" },
{ value: "NR", label: "Nauru", emoji: "🇳🇷" },
{ value: "NU", label: "Niue", emoji: "🇳🇺" },
{ value: "NZ", label: "New Zealand", emoji: "🇳🇿" },
{ value: "OM", label: "Oman", emoji: "🇴🇲" },
{ value: "PA", label: "Panama", emoji: "🇵🇦" },
{ value: "PE", label: "Peru", emoji: "🇵🇪" },
{ value: "PF", label: "French Polynesia", emoji: "🇵🇫" },
{ value: "PG", label: "Papua New Guinea", emoji: "🇵🇬" },
{ value: "PH", label: "Philippines", emoji: "🇵🇭" },
{ value: "PK", label: "Pakistan", emoji: "🇵🇰" },
{ value: "PL", label: "Poland", emoji: "🇵🇱" },
{ value: "PM", label: "Saint Pierre and Miquelon", emoji: "🇵🇲" },
{ value: "PN", label: "Pitcairn", emoji: "🇵🇳" },
{ value: "PR", label: "Puerto Rico", emoji: "🇵🇷" },
{ value: "PS", label: "Palestine, State of", emoji: "🇵🇸" },
{ value: "PT", label: "Portugal", emoji: "🇵🇹" },
{ value: "PW", label: "Palau", emoji: "🇵🇼" },
{ value: "PY", label: "Paraguay", emoji: "🇵🇾" },
{ value: "QA", label: "Qatar", emoji: "🇶🇦" },
{ value: "RE", label: "Réunion", emoji: "🇷🇪" },
{ value: "RO", label: "Romania", emoji: "🇷🇴" },
{ value: "RS", label: "Serbia", emoji: "🇷🇸" },
{ value: "RU", label: "Russian Federation", emoji: "🇷🇺" },
{ value: "RW", label: "Rwanda", emoji: "🇷🇼" },
{ value: "SA", label: "Saudi Arabia", emoji: "🇸🇦" },
{ value: "SB", label: "Solomon Islands", emoji: "🇸🇧" },
{ value: "SC", label: "Seychelles", emoji: "🇸🇨" },
{ value: "SD", label: "Sudan", emoji: "🇸🇩" },
{ value: "SE", label: "Sweden", emoji: "🇸🇪" },
{ value: "SG", label: "Singapore", emoji: "🇸🇬" },
{
value: "SH",
label: "Saint Helena, Ascension and Tristan da Cunha",
emoji: "🇸🇭",
},
{ value: "SI", label: "Slovenia", emoji: "🇸🇮" },
{ value: "SJ", label: "Svalbard and Jan Mayen", emoji: "🇸🇯" },
{ value: "SK", label: "Slovakia", emoji: "🇸🇰" },
{ value: "SL", label: "Sierra Leone", emoji: "🇸🇱" },
{ value: "SM", label: "San Marino", emoji: "🇸🇲" },
{ value: "SN", label: "Senegal", emoji: "🇸🇳" },
{ value: "SO", label: "Somalia", emoji: "🇸🇴" },
{ value: "SR", label: "Suriname", emoji: "🇸🇷" },
{ value: "SS", label: "South Sudan", emoji: "🇸🇸" },
{ value: "ST", label: "Sao Tome and Principe", emoji: "🇸🇹" },
{ value: "SV", label: "El Salvador", emoji: "🇸🇻" },
{ value: "SX", label: "Sint Maarten, (Dutch part)", emoji: "🇸🇽" },
{ value: "SY", label: "Syrian Arab Republic", emoji: "🇸🇾" },
{ value: "SZ", label: "Eswatini", emoji: "🇸🇿" },
{ value: "TC", label: "Turks and Caicos Islands", emoji: "🇹🇨" },
{ value: "TD", label: "Chad", emoji: "🇹🇩" },
{ value: "TF", label: "French Southern Territories", emoji: "🇹🇫" },
{ value: "TG", label: "Togo", emoji: "🇹🇬" },
{ value: "TH", label: "Thailand", emoji: "🇹🇭" },
{ value: "TJ", label: "Tajikistan", emoji: "🇹🇯" },
{ value: "TK", label: "Tokelau", emoji: "🇹🇰" },
{ value: "TL", label: "Timor-Leste", emoji: "🇹🇱" },
{ value: "TM", label: "Turkmenistan", emoji: "🇹🇲" },
{ value: "TN", label: "Tunisia", emoji: "🇹🇳" },
{ value: "TO", label: "Tonga", emoji: "🇹🇴" },
{ value: "TR", label: "Türkiye", emoji: "🇹🇷" },
{ value: "TT", label: "Trinidad and Tobago", emoji: "🇹🇹" },
{ value: "TV", label: "Tuvalu", emoji: "🇹🇻" },
{ value: "TW", label: "Taiwan, Province of China", emoji: "🇹🇼" },
{ value: "TZ", label: "Tanzania, United Republic of", emoji: "🇹🇿" },
{ value: "UA", label: "Ukraine", emoji: "🇺🇦" },
{ value: "UG", label: "Uganda", emoji: "🇺🇬" },
{ value: "UM", label: "United States Minor Outlying Islands", emoji: "🇺🇲" },
{ value: "US", label: "United States of America", emoji: "🇺🇸" },
{ value: "UY", label: "Uruguay", emoji: "🇺🇾" },
{ value: "UZ", label: "Uzbekistan", emoji: "🇺🇿" },
{ value: "VA", label: "Holy See", emoji: "🇻🇦" },
{ value: "VC", label: "Saint Vincent and the Grenadines", emoji: "🇻🇨" },
{ value: "VE", label: "Venezuela, Bolivarian Republic of", emoji: "🇻🇪" },
{ value: "VG", label: "Virgin Islands, British", emoji: "🇻🇬" },
{ value: "VI", label: "Virgin Islands, U.S.", emoji: "🇻🇮" },
{ value: "VN", label: "Viet Nam", emoji: "🇻🇳" },
{ value: "VU", label: "Vanuatu", emoji: "🇻🇺" },
{ value: "WF", label: "Wallis and Futuna", emoji: "🇼🇫" },
{ value: "WS", label: "Samoa", emoji: "🇼🇸" },
{ value: "YE", label: "Yemen", emoji: "🇾🇪" },
{ value: "YT", label: "Mayotte", emoji: "🇾🇹" },
{ value: "ZA", label: "South Africa", emoji: "🇿🇦" },
{ value: "ZM", label: "Zambia", emoji: "🇿🇲" },
{ value: "ZW", label: "Zimbabwe", emoji: "🇿🇼" },
]
```
### Virtualization
Alternatively, you can leverage virtualization from the
`@tanstack/react-virtual` package to render large datasets efficiently.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { useVirtualizer } from "@tanstack/react-virtual"
import { useRef } from "react"
import { flushSync } from "react-dom"
export const ComboboxVirtualized = () => {
const contentRef = useRef(null)
const { startsWith } = useFilter({ sensitivity: "base" })
const { collection, filter, reset } = useListCollection({
initialItems: items,
filter: startsWith,
})
const virtualizer = useVirtualizer({
count: collection.size,
getScrollElement: () => contentRef.current,
estimateSize: () => 28,
overscan: 10,
scrollPaddingEnd: 32,
})
const handleScrollToIndexFn = (details: { index: number }) => {
flushSync(() => {
virtualizer.scrollToIndex(details.index, {
align: "center",
behavior: "auto",
})
})
}
return (
filter(e.inputValue)}
scrollToIndexFn={handleScrollToIndexFn}
width="320px"
>
Select framework
)
}
export const items = [
{ value: "AD", label: "Andorra", emoji: "🇦🇩" },
{ value: "AE", label: "United Arab Emirates", emoji: "🇦🇪" },
{ value: "AF", label: "Afghanistan", emoji: "🇦🇫" },
{ value: "AG", label: "Antigua and Barbuda", emoji: "🇦🇬" },
{ value: "AI", label: "Anguilla", emoji: "🇦🇮" },
{ value: "AL", label: "Albania", emoji: "🇦🇱" },
{ value: "AM", label: "Armenia", emoji: "🇦🇲" },
{ value: "AO", label: "Angola", emoji: "🇦🇴" },
{ value: "AQ", label: "Antarctica", emoji: "🇦🇶" },
{ value: "AR", label: "Argentina", emoji: "🇦🇷" },
{ value: "AS", label: "American Samoa", emoji: "🇦🇸" },
{ value: "AT", label: "Austria", emoji: "🇦🇹" },
{ value: "AU", label: "Australia", emoji: "🇦🇺" },
{ value: "AW", label: "Aruba", emoji: "🇦🇼" },
{ value: "AX", label: "Åland Islands", emoji: "🇦🇽" },
{ value: "AZ", label: "Azerbaijan", emoji: "🇦🇿" },
{ value: "BA", label: "Bosnia and Herzegovina", emoji: "🇧🇦" },
{ value: "BB", label: "Barbados", emoji: "🇧🇧" },
{ value: "BD", label: "Bangladesh", emoji: "🇧🇩" },
{ value: "BE", label: "Belgium", emoji: "🇧🇪" },
{ value: "BF", label: "Burkina Faso", emoji: "🇧🇫" },
{ value: "BG", label: "Bulgaria", emoji: "🇧🇬" },
{ value: "BH", label: "Bahrain", emoji: "🇧🇭" },
{ value: "BI", label: "Burundi", emoji: "🇧🇮" },
{ value: "BJ", label: "Benin", emoji: "🇧🇯" },
{ value: "BL", label: "Saint Barthélemy", emoji: "🇧🇱" },
{ value: "BM", label: "Bermuda", emoji: "🇧🇲" },
{ value: "BN", label: "Brunei Darussalam", emoji: "🇧🇳" },
{ value: "BO", label: "Bolivia, Plurinational State of", emoji: "🇧🇴" },
{ value: "BQ", label: "Bonaire, Sint Eustatius and Saba", emoji: "🇧🇶" },
{ value: "BR", label: "Brazil", emoji: "🇧🇷" },
{ value: "BS", label: "Bahamas", emoji: "🇧🇸" },
{ value: "BT", label: "Bhutan", emoji: "🇧🇹" },
{ value: "BV", label: "Bouvet Island", emoji: "🇧🇻" },
{ value: "BW", label: "Botswana", emoji: "🇧🇼" },
{ value: "BY", label: "Belarus", emoji: "🇧🇾" },
{ value: "BZ", label: "Belize", emoji: "🇧🇿" },
{ value: "CA", label: "Canada", emoji: "🇨🇦" },
{ value: "CC", label: "Cocos (Keeling) Islands", emoji: "🇨🇨" },
{ value: "CD", label: "Congo, Democratic Republic of the", emoji: "🇨🇩" },
{ value: "CF", label: "Central African Republic", emoji: "🇨🇫" },
{ value: "CG", label: "Congo", emoji: "🇨🇬" },
{ value: "CH", label: "Switzerland", emoji: "🇨🇭" },
{ value: "CI", label: "Côte d'Ivoire", emoji: "🇨🇮" },
{ value: "CK", label: "Cook Islands", emoji: "🇨🇰" },
{ value: "CL", label: "Chile", emoji: "🇨🇱" },
{ value: "CM", label: "Cameroon", emoji: "🇨🇲" },
{ value: "CN", label: "China", emoji: "🇨🇳" },
{ value: "CO", label: "Colombia", emoji: "🇨🇴" },
{ value: "CR", label: "Costa Rica", emoji: "🇨🇷" },
{ value: "CU", label: "Cuba", emoji: "🇨🇺" },
{ value: "CV", label: "Cabo Verde", emoji: "🇨🇻" },
{ value: "CW", label: "Curaçao", emoji: "🇨🇼" },
{ value: "CX", label: "Christmas Island", emoji: "🇨🇽" },
{ value: "CY", label: "Cyprus", emoji: "🇨🇾" },
{ value: "CZ", label: "Czechia", emoji: "🇨🇿" },
{ value: "DE", label: "Germany", emoji: "🇩🇪" },
{ value: "DJ", label: "Djibouti", emoji: "🇩🇯" },
{ value: "DK", label: "Denmark", emoji: "🇩🇰" },
{ value: "DM", label: "Dominica", emoji: "🇩🇲" },
{ value: "DO", label: "Dominican Republic", emoji: "🇩🇴" },
{ value: "DZ", label: "Algeria", emoji: "🇩🇿" },
{ value: "EC", label: "Ecuador", emoji: "🇪🇨" },
{ value: "EE", label: "Estonia", emoji: "🇪🇪" },
{ value: "EG", label: "Egypt", emoji: "🇪🇬" },
{ value: "EH", label: "Western Sahara", emoji: "🇪🇭" },
{ value: "ER", label: "Eritrea", emoji: "🇪🇷" },
{ value: "ES", label: "Spain", emoji: "🇪🇸" },
{ value: "ET", label: "Ethiopia", emoji: "🇪🇹" },
{ value: "FI", label: "Finland", emoji: "🇫🇮" },
{ value: "FJ", label: "Fiji", emoji: "🇫🇯" },
{ value: "FK", label: "Falkland Islands (Malvinas)", emoji: "🇫🇰" },
{ value: "FM", label: "Micronesia, Federated States of", emoji: "🇫🇲" },
{ value: "FO", label: "Faroe Islands", emoji: "🇫🇴" },
{ value: "FR", label: "France", emoji: "🇫🇷" },
{ value: "GA", label: "Gabon", emoji: "🇬🇦" },
{
value: "GB",
label: "United Kingdom of Great Britain and Northern Ireland",
emoji: "🇬🇧",
},
{ value: "GD", label: "Grenada", emoji: "🇬🇩" },
{ value: "GE", label: "Georgia", emoji: "🇬🇪" },
{ value: "GF", label: "French Guiana", emoji: "🇬🇫" },
{ value: "GG", label: "Guernsey", emoji: "🇬🇬" },
{ value: "GH", label: "Ghana", emoji: "🇬🇭" },
{ value: "GI", label: "Gibraltar", emoji: "🇬🇮" },
{ value: "GL", label: "Greenland", emoji: "🇬🇱" },
{ value: "GM", label: "Gambia", emoji: "🇬🇲" },
{ value: "GN", label: "Guinea", emoji: "🇬🇳" },
{ value: "GP", label: "Guadeloupe", emoji: "🇬🇵" },
{ value: "GQ", label: "Equatorial Guinea", emoji: "🇬🇶" },
{ value: "GR", label: "Greece", emoji: "🇬🇷" },
{
value: "GS",
label: "South Georgia and the South Sandwich Islands",
emoji: "🇬🇸",
},
{ value: "GT", label: "Guatemala", emoji: "🇬🇹" },
{ value: "GU", label: "Guam", emoji: "🇬🇺" },
{ value: "GW", label: "Guinea-Bissau", emoji: "🇬🇼" },
{ value: "GY", label: "Guyana", emoji: "🇬🇾" },
{ value: "HK", label: "Hong Kong", emoji: "🇭🇰" },
{ value: "HM", label: "Heard Island and McDonald Islands", emoji: "🇭🇲" },
{ value: "HN", label: "Honduras", emoji: "🇭🇳" },
{ value: "HR", label: "Croatia", emoji: "🇭🇷" },
{ value: "HT", label: "Haiti", emoji: "🇭🇹" },
{ value: "HU", label: "Hungary", emoji: "🇭🇺" },
{ value: "ID", label: "Indonesia", emoji: "🇮🇩" },
{ value: "IE", label: "Ireland", emoji: "🇮🇪" },
{ value: "IL", label: "Israel", emoji: "🇮🇱" },
{ value: "IM", label: "Isle of Man", emoji: "🇮🇲" },
{ value: "IN", label: "India", emoji: "🇮🇳" },
{ value: "IO", label: "British Indian Ocean Territory", emoji: "🇮🇴" },
{ value: "IQ", label: "Iraq", emoji: "🇮🇶" },
{ value: "IR", label: "Iran, Islamic Republic of", emoji: "🇮🇷" },
{ value: "IS", label: "Iceland", emoji: "🇮🇸" },
{ value: "IT", label: "Italy", emoji: "🇮🇹" },
{ value: "JE", label: "Jersey", emoji: "🇯🇪" },
{ value: "JM", label: "Jamaica", emoji: "🇯🇲" },
{ value: "JO", label: "Jordan", emoji: "🇯🇴" },
{ value: "JP", label: "Japan", emoji: "🇯🇵" },
{ value: "KE", label: "Kenya", emoji: "🇰🇪" },
{ value: "KG", label: "Kyrgyzstan", emoji: "🇰🇬" },
{ value: "KH", label: "Cambodia", emoji: "🇰🇭" },
{ value: "KI", label: "Kiribati", emoji: "🇰🇮" },
{ value: "KM", label: "Comoros", emoji: "🇰🇲" },
{ value: "KN", label: "Saint Kitts and Nevis", emoji: "🇰🇳" },
{ value: "KP", label: "Korea, Democratic People's Republic of", emoji: "🇰🇵" },
{ value: "KR", label: "Korea, Republic of", emoji: "🇰🇷" },
{ value: "KW", label: "Kuwait", emoji: "🇰🇼" },
{ value: "KY", label: "Cayman Islands", emoji: "🇰🇾" },
{ value: "KZ", label: "Kazakhstan", emoji: "🇰🇿" },
{ value: "LA", label: "Lao People's Democratic Republic", emoji: "🇱🇦" },
{ value: "LB", label: "Lebanon", emoji: "🇱🇧" },
{ value: "LC", label: "Saint Lucia", emoji: "🇱🇨" },
{ value: "LI", label: "Liechtenstein", emoji: "🇱🇮" },
{ value: "LK", label: "Sri Lanka", emoji: "🇱🇰" },
{ value: "LR", label: "Liberia", emoji: "🇱🇷" },
{ value: "LS", label: "Lesotho", emoji: "🇱🇸" },
{ value: "LT", label: "Lithuania", emoji: "🇱🇹" },
{ value: "LU", label: "Luxembourg", emoji: "🇱🇺" },
{ value: "LV", label: "Latvia", emoji: "🇱🇻" },
{ value: "LY", label: "Libya", emoji: "🇱🇾" },
{ value: "MA", label: "Morocco", emoji: "🇲🇦" },
{ value: "MC", label: "Monaco", emoji: "🇲🇨" },
{ value: "MD", label: "Moldova, Republic of", emoji: "🇲🇩" },
{ value: "ME", label: "Montenegro", emoji: "🇲🇪" },
{ value: "MF", label: "Saint Martin, (French part)", emoji: "🇲🇫" },
{ value: "MG", label: "Madagascar", emoji: "🇲🇬" },
{ value: "MH", label: "Marshall Islands", emoji: "🇲🇭" },
{ value: "MK", label: "North Macedonia", emoji: "🇲🇰" },
{ value: "ML", label: "Mali", emoji: "🇲🇱" },
{ value: "MM", label: "Myanmar", emoji: "🇲🇲" },
{ value: "MN", label: "Mongolia", emoji: "🇲🇳" },
{ value: "MO", label: "Macao", emoji: "🇲🇴" },
{ value: "MP", label: "Northern Mariana Islands", emoji: "🇲🇵" },
{ value: "MQ", label: "Martinique", emoji: "🇲🇶" },
{ value: "MR", label: "Mauritania", emoji: "🇲🇷" },
{ value: "MS", label: "Montserrat", emoji: "🇲🇸" },
{ value: "MT", label: "Malta", emoji: "🇲🇹" },
{ value: "MU", label: "Mauritius", emoji: "🇲🇺" },
{ value: "MV", label: "Maldives", emoji: "🇲🇻" },
{ value: "MW", label: "Malawi", emoji: "🇲🇼" },
{ value: "MX", label: "Mexico", emoji: "🇲🇽" },
{ value: "MY", label: "Malaysia", emoji: "🇲🇾" },
{ value: "MZ", label: "Mozambique", emoji: "🇲🇿" },
{ value: "NA", label: "Namibia", emoji: "🇳🇦" },
{ value: "NC", label: "New Caledonia", emoji: "🇳🇨" },
{ value: "NE", label: "Niger", emoji: "🇳🇪" },
{ value: "NF", label: "Norfolk Island", emoji: "🇳🇫" },
{ value: "NG", label: "Nigeria", emoji: "🇳🇬" },
{ value: "NI", label: "Nicaragua", emoji: "🇳🇮" },
{ value: "NL", label: "Netherlands", emoji: "🇳🇱" },
{ value: "NO", label: "Norway", emoji: "🇳🇴" },
{ value: "NP", label: "Nepal", emoji: "🇳🇵" },
{ value: "NR", label: "Nauru", emoji: "🇳🇷" },
{ value: "NU", label: "Niue", emoji: "🇳🇺" },
{ value: "NZ", label: "New Zealand", emoji: "🇳🇿" },
{ value: "OM", label: "Oman", emoji: "🇴🇲" },
{ value: "PA", label: "Panama", emoji: "🇵🇦" },
{ value: "PE", label: "Peru", emoji: "🇵🇪" },
{ value: "PF", label: "French Polynesia", emoji: "🇵🇫" },
{ value: "PG", label: "Papua New Guinea", emoji: "🇵🇬" },
{ value: "PH", label: "Philippines", emoji: "🇵🇭" },
{ value: "PK", label: "Pakistan", emoji: "🇵🇰" },
{ value: "PL", label: "Poland", emoji: "🇵🇱" },
{ value: "PM", label: "Saint Pierre and Miquelon", emoji: "🇵🇲" },
{ value: "PN", label: "Pitcairn", emoji: "🇵🇳" },
{ value: "PR", label: "Puerto Rico", emoji: "🇵🇷" },
{ value: "PS", label: "Palestine, State of", emoji: "🇵🇸" },
{ value: "PT", label: "Portugal", emoji: "🇵🇹" },
{ value: "PW", label: "Palau", emoji: "🇵🇼" },
{ value: "PY", label: "Paraguay", emoji: "🇵🇾" },
{ value: "QA", label: "Qatar", emoji: "🇶🇦" },
{ value: "RE", label: "Réunion", emoji: "🇷🇪" },
{ value: "RO", label: "Romania", emoji: "🇷🇴" },
{ value: "RS", label: "Serbia", emoji: "🇷🇸" },
{ value: "RU", label: "Russian Federation", emoji: "🇷🇺" },
{ value: "RW", label: "Rwanda", emoji: "🇷🇼" },
{ value: "SA", label: "Saudi Arabia", emoji: "🇸🇦" },
{ value: "SB", label: "Solomon Islands", emoji: "🇸🇧" },
{ value: "SC", label: "Seychelles", emoji: "🇸🇨" },
{ value: "SD", label: "Sudan", emoji: "🇸🇩" },
{ value: "SE", label: "Sweden", emoji: "🇸🇪" },
{ value: "SG", label: "Singapore", emoji: "🇸🇬" },
{
value: "SH",
label: "Saint Helena, Ascension and Tristan da Cunha",
emoji: "🇸🇭",
},
{ value: "SI", label: "Slovenia", emoji: "🇸🇮" },
{ value: "SJ", label: "Svalbard and Jan Mayen", emoji: "🇸🇯" },
{ value: "SK", label: "Slovakia", emoji: "🇸🇰" },
{ value: "SL", label: "Sierra Leone", emoji: "🇸🇱" },
{ value: "SM", label: "San Marino", emoji: "🇸🇲" },
{ value: "SN", label: "Senegal", emoji: "🇸🇳" },
{ value: "SO", label: "Somalia", emoji: "🇸🇴" },
{ value: "SR", label: "Suriname", emoji: "🇸🇷" },
{ value: "SS", label: "South Sudan", emoji: "🇸🇸" },
{ value: "ST", label: "Sao Tome and Principe", emoji: "🇸🇹" },
{ value: "SV", label: "El Salvador", emoji: "🇸🇻" },
{ value: "SX", label: "Sint Maarten, (Dutch part)", emoji: "🇸🇽" },
{ value: "SY", label: "Syrian Arab Republic", emoji: "🇸🇾" },
{ value: "SZ", label: "Eswatini", emoji: "🇸🇿" },
{ value: "TC", label: "Turks and Caicos Islands", emoji: "🇹🇨" },
{ value: "TD", label: "Chad", emoji: "🇹🇩" },
{ value: "TF", label: "French Southern Territories", emoji: "🇹🇫" },
{ value: "TG", label: "Togo", emoji: "🇹🇬" },
{ value: "TH", label: "Thailand", emoji: "🇹🇭" },
{ value: "TJ", label: "Tajikistan", emoji: "🇹🇯" },
{ value: "TK", label: "Tokelau", emoji: "🇹🇰" },
{ value: "TL", label: "Timor-Leste", emoji: "🇹🇱" },
{ value: "TM", label: "Turkmenistan", emoji: "🇹🇲" },
{ value: "TN", label: "Tunisia", emoji: "🇹🇳" },
{ value: "TO", label: "Tonga", emoji: "🇹🇴" },
{ value: "TR", label: "Türkiye", emoji: "🇹🇷" },
{ value: "TT", label: "Trinidad and Tobago", emoji: "🇹🇹" },
{ value: "TV", label: "Tuvalu", emoji: "🇹🇻" },
{ value: "TW", label: "Taiwan, Province of China", emoji: "🇹🇼" },
{ value: "TZ", label: "Tanzania, United Republic of", emoji: "🇹🇿" },
{ value: "UA", label: "Ukraine", emoji: "🇺🇦" },
{ value: "UG", label: "Uganda", emoji: "🇺🇬" },
{ value: "UM", label: "United States Minor Outlying Islands", emoji: "🇺🇲" },
{ value: "US", label: "United States of America", emoji: "🇺🇸" },
{ value: "UY", label: "Uruguay", emoji: "🇺🇾" },
{ value: "UZ", label: "Uzbekistan", emoji: "🇺🇿" },
{ value: "VA", label: "Holy See", emoji: "🇻🇦" },
{ value: "VC", label: "Saint Vincent and the Grenadines", emoji: "🇻🇨" },
{ value: "VE", label: "Venezuela, Bolivarian Republic of", emoji: "🇻🇪" },
{ value: "VG", label: "Virgin Islands, British", emoji: "🇻🇬" },
{ value: "VI", label: "Virgin Islands, U.S.", emoji: "🇻🇮" },
{ value: "VN", label: "Viet Nam", emoji: "🇻🇳" },
{ value: "VU", label: "Vanuatu", emoji: "🇻🇺" },
{ value: "WF", label: "Wallis and Futuna", emoji: "🇼🇫" },
{ value: "WS", label: "Samoa", emoji: "🇼🇸" },
{ value: "YE", label: "Yemen", emoji: "🇾🇪" },
{ value: "YT", label: "Mayotte", emoji: "🇾🇹" },
{ value: "ZA", label: "South Africa", emoji: "🇿🇦" },
{ value: "ZM", label: "Zambia", emoji: "🇿🇲" },
{ value: "ZW", label: "Zimbabwe", emoji: "🇿🇼" },
]
```
### Links
Use the `asChild` prop to render the combobox items as links.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { LuExternalLink } from "react-icons/lu"
export const ComboboxWithLinks = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
selectionBehavior="clear"
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react", docs: "https://react.dev" },
{ label: "Solid", value: "solid", docs: "https://solidjs.com" },
{ label: "Vue", value: "vue", docs: "https://vuejs.org" },
{ label: "Angular", value: "angular", docs: "https://angular.io" },
{ label: "Svelte", value: "svelte", docs: "https://svelte.dev" },
{ label: "Preact", value: "preact", docs: "https://preactjs.com" },
{ label: "Qwik", value: "qwik", docs: "https://qwik.builder.io" },
{ label: "Lit", value: "lit", docs: "https://lit.dev" },
{ label: "Alpine.js", value: "alpinejs", docs: "https://alpinejs.dev" },
{ label: "Ember", value: "ember", docs: "https://emberjs.com" },
{ label: "Next.js", value: "nextjs", docs: "https://nextjs.org" },
]
```
For custom router links, you can customize the `navigate` prop on the
`Combobox.Root` component.
Here's an example of using the Tanstack Router.
```tsx {8-10}
import { Combobox } from "@chakra-ui/react"
import { useNavigate } from "@tanstack/react-router"
function Demo() {
const navigate = useNavigate()
return (
{
navigate({ to: href })
}}
>
{/* ... */}
)
}
```
### Rehydrate Value
In some cases, where a combobox has a `defaultValue` but the collection is not
loaded yet, here's an example of how to rehydrate the value and populate the
input value.
```tsx
"use client"
import {
Combobox,
For,
HStack,
Portal,
Span,
Spinner,
useCombobox,
useListCollection,
} from "@chakra-ui/react"
import { useRef, useState } from "react"
import { useAsync } from "react-use"
export const ComboboxRehydrateValue = () => {
const [inputValue, setInputValue] = useState("")
const { collection, set } = useListCollection({
initialItems: [],
itemToString: (item) => item.name,
itemToValue: (item) => item.name,
})
const combobox = useCombobox({
collection,
defaultValue: ["C-3PO"],
placeholder: "Example: Dexter",
inputValue,
onInputValueChange: (e) => setInputValue(e.inputValue),
})
const state = useAsync(async () => {
const response = await fetch(
`https://swapi.py4e.com/api/people/?search=${inputValue}`,
)
const data = await response.json()
set(data.results)
}, [inputValue, set])
// Rehydrate the value
const hydrated = useRef(false)
if (combobox.value.length && collection.size && !hydrated.current) {
combobox.syncSelectedItems()
hydrated.current = true
}
return (
Search Star Wars Characters
{state.loading ? (
Loading...
) : state.error ? (
{state.error.message}
) : (
No items}
>
{(item) => (
{item.name}
{item.height}cm / {item.mass}kg
)}
)}
)
}
interface Character {
name: string
height: string
mass: string
created: string
edited: string
url: string
}
```
### Custom Item
Customize the appearance of items in the dropdown with your own components.
```tsx
"use client"
import {
Combobox,
HStack,
Image,
Portal,
Span,
Stack,
useComboboxContext,
useFilter,
useListCollection,
} from "@chakra-ui/react"
function ComboboxValue() {
const combobox = useComboboxContext()
const selectedItems = combobox.selectedItems as (typeof items)[number][]
return (
{selectedItems.map((item) => (
{item.label}
))}
)
}
export const ComboboxWithCustomItem = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: items,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
placeholder="Example: Audi"
multiple
closeOnSelect
>
Search and select car brandsNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
export const items = [
{
label: "Audi",
value: "audi",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/audi-logo.png",
},
{
label: "BMW",
value: "bmw",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/bmw-logo.png",
},
{
label: "Citroen",
value: "citroen",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/citroen-logo.png",
},
{
label: "Dacia",
value: "dacia",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/dacia-logo.png",
},
{
label: "Fiat",
value: "fiat",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/fiat-logo.png",
},
{
label: "Ford",
value: "ford",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/ford-logo.png",
},
{
label: "Ferrari",
value: "ferrari",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/ferrari-logo.png",
},
{
label: "Honda",
value: "honda",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/honda-logo.png",
},
{
label: "Hyundai",
value: "hyundai",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/hyundai-logo.png",
},
{
label: "Jaguar",
value: "jaguar",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/jaguar-logo.png",
},
{
label: "Jeep",
value: "jeep",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/jeep-logo.png",
},
{
label: "Kia",
value: "kia",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/kia-logo.png",
},
{
label: "Land Rover",
value: "land rover",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/land-rover-logo.png",
},
{
label: "Mazda",
value: "mazda",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/mazda-logo.png",
},
{
label: "Mercedes",
value: "mercedes",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/mercedes-logo.png",
},
{
label: "Mini",
value: "mini",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/mini-logo.png",
},
{
label: "Mitsubishi",
value: "mitsubishi",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/mitsubishi-logo.png",
},
{
label: "Nissan",
value: "nissan",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/nissan-logo.png",
},
{
label: "Opel",
value: "opel",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/opel-logo.png",
},
{
label: "Peugeot",
value: "peugeot",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/peugeot-logo.png",
},
{
label: "Porsche",
value: "porsche",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/porsche-logo.png",
},
{
label: "Renault",
value: "renault",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/renault-logo.png",
},
{
label: "Saab",
value: "saab",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/saab-logo.png",
},
{
label: "Skoda",
value: "skoda",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/skoda-logo.png",
},
{
label: "Subaru",
value: "subaru",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/subaru-logo.png",
},
{
label: "Suzuki",
value: "suzuki",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/suzuki-logo.png",
},
{
label: "Toyota",
value: "toyota",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/toyota-logo.png",
},
{
label: "Volkswagen",
value: "volkswagen",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/volkswagen-logo.png",
},
{
label: "Volvo",
value: "volvo",
logo: "https://s3.amazonaws.com/cdn.formk.it/example-assets/car-brands/volvo-logo.png",
},
]
```
### Custom Filter
Here's an example of a custom filter that matches multiple properties of an
item.
```tsx
"use client"
import {
Combobox,
Portal,
Span,
Stack,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithCustomFilter = () => {
const { collection, set } = useListCollection({
initialItems: people,
itemToString: (item) => item.name,
itemToValue: (item) => item.id.toString(),
})
const handleInputChange = (details: Combobox.InputValueChangeDetails) => {
const filteredItems = people.filter((item) => {
const searchLower = details.inputValue.toLowerCase()
const nameParts = item.name.toLowerCase().split(" ")
const emailParts = item.email.toLowerCase().split("@")[0].split(".")
return (
item.name.toLowerCase().includes(searchLower) ||
nameParts.some((part) => part.includes(searchLower)) ||
emailParts.some((part) => part.includes(searchLower)) ||
item.role.toLowerCase().includes(searchLower)
)
})
set(filteredItems)
}
return (
Select PersonNo matches found
{collection.items.map((person) => (
{person.name}
{person.email}
))}
)
}
const people = [
{
id: 1,
name: "John Smith",
email: "john@example.com",
role: "Sales Manager",
},
{
id: 2,
name: "Sarah Johnson",
email: "sarah@example.com",
role: "UI Designer",
},
{
id: 3,
name: "Michael Brown",
email: "michael@example.com",
role: "Software Engineer",
},
{
id: 4,
name: "Emily Davis",
email: "emily@example.com",
role: "AI Engineer",
},
{
id: 5,
name: "James Wilson",
email: "james@example.com",
role: "Chief Executive Officer",
},
]
```
### Custom Animation
To customize the animation of the combobox, pass the `_open` and `_closed` prop
to the `Combobox.Content` component.
```tsx
"use client"
import {
Combobox,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxWithCustomAnimation = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
width="320px"
positioning={{ flip: false, gutter: 2 }}
>
Select frameworkNo items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
### Within Dialog
To use the combobox within a dialog or popover component, avoid wrapping the
`Combobox.Positioner` within the `Portal`.
```diff
-
{/* ... */}
-
```
If you use a `Dialog` and have set `scrollBehavior="inside"`, you need to:
- Set the combobox positioning to `fixed` to avoid the combobox from being
clipped by the dialog.
- Set `hideWhenDetached` to `true` to hide the combobox when the trigger is
scrolled out of view.
```tsx
{/* ... */}
```
```tsx
"use client"
import {
Button,
Combobox,
Popover,
Portal,
useFilter,
useListCollection,
} from "@chakra-ui/react"
export const ComboboxInPopover = () => {
return (
Select framework
)
}
const ComboboxDemo = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: frameworks,
filter: contains,
})
return (
filter(e.inputValue)}
>
No items found
{collection.items.map((item) => (
{item.label}
))}
)
}
const frameworks = [
{ label: "React", value: "react" },
{ label: "Solid", value: "solid" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Preact", value: "preact" },
{ label: "Qwik", value: "qwik" },
{ label: "Lit", value: "lit" },
{ label: "Alpine.js", value: "alpinejs" },
{ label: "Ember", value: "ember" },
{ label: "Next.js", value: "nextjs" },
]
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| collection | undefined | `ListCollection` | The collection of items |
| composite | true | `boolean` | Whether the combobox is a composed with other composite widgets like tabs |
| defaultInputValue | "" | `string` | The initial value of the combobox's input when rendered.
Use when you don't need to control the value of the combobox's input. |
| defaultValue | [] | `string[]` | The initial value of the combobox's selected items when rendered.
Use when you don't need to control the value of the combobox's selected items. |
| inputBehavior | "none" | `'none' \| 'autohighlight' \| 'autocomplete'` | Defines the auto-completion behavior of the combobox.
- `autohighlight`: The first focused item is highlighted as the user types
- `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| loopFocus | true | `boolean` | Whether to loop the keyboard navigation through the items |
| openOnChange | true | `boolean \| ((details: InputValueChangeDetails) => boolean)` | Whether to show the combobox when the input value changes |
| openOnClick | false | `boolean` | Whether to open the combobox popup on initial click on the input |
| openOnKeyPress | true | `boolean` | Whether to open the combobox on arrow key press |
| positioning | { placement: "bottom-start" } | `PositioningOptions` | The positioning options to dynamically position the menu |
| selectionBehavior | "replace" | `'replace' \| 'clear' \| 'preserve'` | The behavior of the combobox input when an item is selected
- `replace`: The selected item string is set as the input value
- `clear`: The input value is cleared
- `preserve`: The input value is preserved |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | outline | `'outline' \| 'subtle' \| 'flushed'` | The variant of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| allowCustomValue | undefined | `boolean` | Whether to allow typing custom values in the input |
| autoFocus | undefined | `boolean` | Whether to autofocus the input on mount |
| closeOnSelect | undefined | `boolean` | Whether to close the combobox when an item is selected. |
| defaultHighlightedValue | undefined | `string` | The initial highlighted value of the combobox when rendered.
Use when you don't need to control the highlighted value of the combobox. |
| defaultOpen | undefined | `boolean` | The initial open state of the combobox when rendered.
Use when you don't need to control the open state of the combobox. |
| disabled | undefined | `boolean` | Whether the combobox is disabled |
| disableLayer | undefined | `boolean` | Whether to disable registering this a dismissable layer |
| form | undefined | `string` | The associate form of the combobox. |
| highlightedValue | undefined | `string` | The controlled highlighted value of the combobox |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n label: string\n control: string\n input: string\n content: string\n trigger: string\n clearTrigger: string\n item: (id: string, index?: number \| undefined) => string\n positioner: string\n itemGroup: (id: string \| number) => string\n itemGroupLabel: (id: string \| number) => string\n}>` | The ids of the elements in the combobox. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| inputValue | undefined | `string` | The controlled value of the combobox's input |
| invalid | undefined | `boolean` | Whether the combobox is invalid |
| multiple | undefined | `boolean` | Whether to allow multiple selection.
**Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
It is recommended to render the selected items in a separate container. |
| name | undefined | `string` | The `name` attribute of the combobox's input. Useful for form submission |
| navigate | undefined | `(details: NavigateDetails) => void` | Function to navigate to the selected item |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onHighlightChange | undefined | `(details: HighlightChangeDetails) => void` | Function called when an item is highlighted using the pointer
or keyboard navigation. |
| onInputValueChange | undefined | `(details: InputValueChangeDetails) => void` | Function called when the input's value changes |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function called when the popup is opened |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| onSelect | undefined | `(details: SelectionDetails) => void` | Function called when an item is selected |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function called when a new item is selected |
| open | undefined | `boolean` | The controlled open state of the combobox |
| placeholder | undefined | `string` | The placeholder text of the combobox's input |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
| readOnly | undefined | `boolean` | Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
but the user can still interact with it |
| required | undefined | `boolean` | Whether the combobox is required |
| scrollToIndexFn | undefined | `(details: ScrollToIndexDetails) => void` | Function to scroll to a specific index |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| value | undefined | `string[]` | The controlled value of the combobox's selected items |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| item | undefined | `any` | The item to render |
| persistFocus | undefined | `boolean` | Whether hovering outside should clear the highlighted state |
## Explorer
Explore the `Combobox` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Container
```tsx
import { Container } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const ContainerBasic = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
consectetur, tortor in lacinia eleifend, dui nisl tristique nunc.
)
}
```
## Usage
The default `maxWidth` is `8xl` which maps to `90rem (1440px)`.
```jsx
import { Container } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `maxWidth` prop to change the size of the container.
```tsx
import { Container, For, Stack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const ContainerWithSizes = () => {
return (
{(size) => (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
consectetur, tortor in lacinia eleifend, dui nisl tristique nunc.
)}
)
}
```
### Fluid
Use the `fluid` prop to make the container stretch to fill the width of its
parent.
```tsx
import { Container } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const ContainerWithFluid = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
consectetur, tortor in lacinia eleifend, dui nisl tristique nunc.
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| centerContent | undefined | `'true' \| 'false'` | The centerContent of the component |
| fluid | undefined | `'true' \| 'false'` | The fluid of the component |
# DataList
```tsx
import { DataList } from "@chakra-ui/react"
const stats = [
{ label: "New Users", value: "234", diff: -12, helpText: "Till date" },
{ label: "Sales", value: "£12,340", diff: 12, helpText: "Last 30 days" },
{ label: "Revenue", value: "3,450", diff: 4.5, helpText: "Last 30 days" },
]
export const DataListBasic = () => {
return (
{stats.map((item) => (
{item.label}{item.value}
))}
)
}
```
## Usage
```tsx
import { DataList } from "@chakra-ui/react"
```
```tsx
{data.map((item) => (
{item.label}{item.value}
))}
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Use the `size` prop to change the size of the datalist component.
```tsx
import { DataList, Stack } from "@chakra-ui/react"
export const DataListWithSizes = () => {
return (
NameJohn DoeNameJohn DoeNameJohn Doe
)
}
```
### Variants
Use the `variant` prop to change the variant of the datalist component.
> Added in `v3.1.x`
```tsx
import { DataList, For, Stack } from "@chakra-ui/react"
export const DataListWithVariants = () => {
return (
{(variant) => (
{stats.map((item) => (
{item.label}{item.value}
))}
)}
)
}
const stats = [
{ label: "New Users", value: "234", diff: -12, helpText: "Till date" },
{ label: "Sales", value: "£12,340", diff: 12, helpText: "Last 30 days" },
{ label: "Revenue", value: "3,450", diff: 4.5, helpText: "Last 30 days" },
]
```
### Orientation
Use the `orientation` prop to change the orientation of the datalist component.
```tsx
import { DataList } from "@chakra-ui/react"
const stats = [
{ label: "New Users", value: "234", diff: -12, helpText: "Till date" },
{ label: "Sales", value: "£12,340", diff: 12, helpText: "Last 30 days" },
{ label: "Revenue", value: "3,450", diff: 4.5, helpText: "Last 30 days" },
]
export const DataListVertical = () => {
return (
{stats.map((item) => (
{item.label}{item.value}
))}
)
}
```
### Info Tip
Render the `InfoTip` component within `DataList.Item` to provide additional
context to the datalist.
```tsx
import { DataList } from "@chakra-ui/react"
import { InfoTip } from "@/components/ui/toggle-tip"
const stats = [
{ label: "New Users", value: "234", diff: -12, helpText: "Till date" },
{ label: "Sales", value: "£12,340", diff: 12, helpText: "Last 30 days" },
{ label: "Revenue", value: "3,450", diff: 4.5, helpText: "Last 30 days" },
]
export const DataListWithInfo = () => {
return (
{stats.map((item) => (
{item.label}
This is some info{item.value}
))}
)
}
```
### Separator
Use the `divideY` prop on the `DataList.Root` to add a separator between items.
```tsx
import { DataList } from "@chakra-ui/react"
export const DataListWithSeparator = () => {
return (
{items.map((item) => (
{item.label}{item.value}
))}
)
}
const items = [
{ label: "First Name", value: "Jassie" },
{ label: "Last Name", value: "Bhatia" },
{ label: "Email", value: "jassie@jassie.dev" },
{ label: "Phone", value: "1234567890" },
{ label: "Address", value: "1234 Main St, Anytown, USA" },
]
```
### Closed Component
Here's how to setup the Data List for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add data-list
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| orientation | vertical | `'horizontal' \| 'vertical'` | The orientation of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | subtle | `'subtle' \| 'bold'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `DataList` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Dialog
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogBasic = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
## Usage
```tsx
import { Dialog } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the dialog component.
```tsx
import {
Button,
CloseButton,
Dialog,
For,
HStack,
Portal,
} from "@chakra-ui/react"
export const DialogWithSizes = () => {
return (
{(size) => (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
)}
)
}
```
### Cover
Use the `size="cover"` prop to make the dialog component cover the entire screen
while revealing a small portion of the page behind.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithCover = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Fullscreen
Use the `size="full"` prop to make the dialog component take up the entire
screen.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithFullscreen = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Responsive Size
Use responsive values for the `size` prop to make the dialog adapt to different
screen sizes.
We recommend using exact breakpoints values instead of using a `base` to ensure
styles are properly contained.
```tsx
// ❌ Might cause a style leak between the breakpoints
{/* ... */}
// Works ✅
{/* ... */}
```
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithResponsiveSize = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Placement
Use the `placement` prop to change the placement of the dialog component.
```tsx
import {
Button,
CloseButton,
Dialog,
For,
HStack,
Portal,
} from "@chakra-ui/react"
export const DialogWithPlacement = () => {
return (
{(placement) => (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
)}
)
}
```
### Controlled
Use the `open` and `onOpenChange` prop to control the visibility of the dialog
component.
```tsx
"use client"
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
import { useState } from "react"
import Lorem from "react-lorem-ipsum"
export const DialogControlled = () => {
const [open, setOpen] = useState(false)
return (
setOpen(e.open)}>
Dialog Title
)
}
```
### Store
An alternative way to control the dialog is to use the `RootProvider` component
and the `useDialog` store hook.
This way you can access the dialog state and methods from outside the dialog.
```tsx
"use client"
import {
Button,
CloseButton,
Dialog,
Portal,
useDialog,
} from "@chakra-ui/react"
export const DialogWithStore = () => {
const dialog = useDialog()
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Context
Use the `DialogContext` component to access the dialog state and methods from
outside the dialog.
```tsx
"use client"
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithContext = () => {
return (
{(store) => (
Dialog is open: {store.open ? "true" : "false"}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
)}
)
}
```
### Nested Dialogs
You can nest dialogs by using the `Dialog.Root` component inside another
`Dialog.Root` component.
```tsx
import { Button, Dialog, Portal } from "@chakra-ui/react"
import Lorem from "react-lorem-ipsum"
export const DialogNested = () => {
return (
Dialog TitleDialog Title
)
}
```
### Initial Focus
Use the `initialFocusEl` prop to set the initial focus of the dialog component.
```tsx
"use client"
import { Button, Dialog, Field, Input, Portal, Stack } from "@chakra-ui/react"
import { useRef } from "react"
export const DialogWithInitialFocus = () => {
const ref = useRef(null)
return (
ref.current}>
Dialog HeaderFirst NameLast Name
)
}
```
### Inside Scroll
Use the `scrollBehavior=inside` prop to change the scroll behavior of the dialog
when its content overflows.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
import Lorem from "react-lorem-ipsum"
export const DialogWithInsideScroll = () => {
return (
With Inside Scroll
)
}
```
### Outside Scroll
Use the `scrollBehavior=outside` prop to change the scroll behavior of the
dialog when its content overflows.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
import Lorem from "react-lorem-ipsum"
export const DialogWithOutsideScroll = () => {
return (
With Outside Scroll
)
}
```
### Motion Preset
Use the `motionPreset` prop to change the animation of the dialog component.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithMotionPreset = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Alert Dialog
Set the `role: "alertdialog"` prop to change the dialog component to an alert
dialog.
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogWithRole = () => {
return (
Are you sure?
This action cannot be undone. This will permanently delete your
account and remove your data from our systems.
)
}
```
### Close Button Outside
Here's an example of how to customize the `Dialog.CloseTrigger` component to
position the close button outside the dialog component.
```tsx
import {
AspectRatio,
Button,
CloseButton,
Dialog,
Portal,
} from "@chakra-ui/react"
export const DialogWithCloseOutside = () => {
return (
Dialog Title
This is a dialog with some content and a video.
)
}
```
### Non-Modal Dialog
We don't recommend using a non-modal dialog due to the accessibility concerns
they present. In event you need it, here's what you can do:
- set the `modal` prop to `false`
- set `pointerEvents` to `none` on the `Dialog.Positioner` component
- (optional)set the `closeOnInteractOutside` prop to `false`
```tsx
import { Button, CloseButton, Dialog, Portal } from "@chakra-ui/react"
export const DialogNonModal = () => {
return (
Dialog Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### DataList
Here's an example of how to compose the dialog component with the `DataList`
component.
```tsx
import {
Avatar,
Badge,
Button,
CloseButton,
DataList,
Dialog,
HStack,
Portal,
Textarea,
VStack,
} from "@chakra-ui/react"
export const DialogWithDatalist = () => {
return (
Prepare Chakra V3StatusCompletedAssigned to
Segun Adebayo
Due date12th August 2024
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeOnEscape | true | `boolean` | Whether to close the dialog when the escape key is pressed |
| closeOnInteractOutside | true | `boolean` | Whether to close the dialog when the outside is clicked |
| defaultOpen | false | `boolean` | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| modal | true | `boolean` | Whether to prevent pointer interaction outside the element and hide all content below it |
| preventScroll | true | `boolean` | Whether to prevent scrolling behind the dialog when it's opened |
| role | "dialog" | `'dialog' \| 'alertdialog'` | The dialog's role |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| trapFocus | true | `boolean` | Whether to trap focus inside the dialog when it's opened |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| placement | top | `'center' \| 'top' \| 'bottom'` | The placement of the component |
| scrollBehavior | outside | `'inside' \| 'outside'` | The scrollBehavior of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'cover' \| 'full'` | The size of the component |
| motionPreset | scale | `'scale' \| 'slide-in-bottom' \| 'slide-in-top' \| 'slide-in-left' \| 'slide-in-right' \| 'none'` | The motionPreset of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| aria-label | undefined | `string` | Human readable label for the dialog, in event the dialog title is not rendered |
| finalFocusEl | undefined | `() => MaybeElement` | Element to receive focus when the dialog is closed |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n trigger: string\n positioner: string\n backdrop: string\n content: string\n closeTrigger: string\n title: string\n description: string\n}>` | The ids of the elements in the dialog. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| initialFocusEl | undefined | `() => MaybeElement` | Element to receive focus when the dialog is opened |
| onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function to call when the dialog's open state changes |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| open | undefined | `boolean` | The controlled open state of the dialog |
| persistentElements | undefined | `(() => Element \| null)[]` | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
| restoreFocus | undefined | `boolean` | Whether to restore focus to the element that had focus before the dialog was opened |
# Download Trigger
```tsx
import { Button, DownloadTrigger } from "@chakra-ui/react"
const data = "The quick brown fox jumps over the lazy dog"
export const DownloadTriggerBasic = () => {
return (
)
}
```
## Usage
```jsx
import { DownloadTrigger } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Basic
Pass the data you want to download to the `data` prop, and specify the
`fileName` and `mimeType` of the file.
```tsx
import { Button, DownloadTrigger } from "@chakra-ui/react"
const data = "The quick brown fox jumps over the lazy dog"
export const DownloadTriggerBasic = () => {
return (
)
}
```
### Download SVG
Here's an example of how to download an SVG file.
```tsx
import { Button, DownloadTrigger } from "@chakra-ui/react"
const data = String.raw`
`
export const DownloadTriggerSvg = () => {
return (
)
}
```
### Promise
You can also trigger downloads from a promise that returns a `Blob`, `File`, or
`string`.
```tsx
"use client"
import { Button, DownloadTrigger } from "@chakra-ui/react"
import { LuImageDown } from "react-icons/lu"
const data = async () => {
const res = await fetch("https://picsum.photos/200/300")
return res.blob()
}
export const DownloadTriggerWithPromise = () => {
return (
)
}
```
### File Size
Compose the `DownloadTrigger` with the `FormatByte` component to display the
size of the file in a human-readable format.
```tsx
import { Button, DownloadTrigger, FormatByte } from "@chakra-ui/react"
import { LuDownload } from "react-icons/lu"
const data = "The quick brown fox jumps over the lazy dog"
export const DownloadTriggerWithFileSize = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| spinnerPlacement | start | `'start' \| 'end' \| undefined` | The placement of the spinner |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | solid | `'solid' \| 'subtle' \| 'surface' \| 'outline' \| 'ghost' \| 'plain'` | The variant of the component |
| loading | false | `boolean \| undefined` | If `true`, the button will show a loading spinner. |
| loadingText | undefined | `React.ReactNode \| undefined` | The text to show while loading. |
| spinner | undefined | `React.ReactNode \| undefined` | The spinner to show while loading. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Drawer
```tsx
import { Button, CloseButton, Drawer, Portal } from "@chakra-ui/react"
export const DrawerBasic = () => {
return (
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
## Usage
```tsx
import { Drawer } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Controlled
Use the `open` and `onOpenChange` props to control the drawer component.
```tsx
"use client"
import { Button, CloseButton, Drawer, Portal } from "@chakra-ui/react"
import { useState } from "react"
export const DrawerControlled = () => {
const [open, setOpen] = useState(false)
return (
setOpen(e.open)}>
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Sizes
Use the `size` prop to change the size of the drawer component.
```tsx
import {
Button,
CloseButton,
Drawer,
For,
HStack,
Kbd,
Portal,
} from "@chakra-ui/react"
export const DrawerWithSizes = () => {
return (
{(size) => (
Drawer Title
Press the esc key to close the drawer.
)}
)
}
```
### Context
Use the `DrawerContext` component to access the drawer state and methods from
outside the drawer.
```tsx
"use client"
import { Button, CloseButton, Drawer, Portal } from "@chakra-ui/react"
export const DrawerWithContext = () => {
return (
{(store) => (
Drawer is open: {store.open ? "true" : "false"}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
)}
)
}
```
### Offset
Use the `padding` CSS property on `Drawer.Positioner` to adjust the offset of
the drawer component.
```tsx
import { Button, CloseButton, Drawer, Portal } from "@chakra-ui/react"
export const DrawerWithOffset = () => {
return (
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Placement
Use the `placement` prop to change the placement of the drawer component.
```tsx
import {
Button,
CloseButton,
Drawer,
For,
HStack,
Portal,
} from "@chakra-ui/react"
export const DrawerWithPlacement = () => {
return (
{(placement) => (
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
)}
)
}
```
### Initial Focus
Use the `initialFocusEl` prop to set the initial focus of the drawer component.
```tsx
"use client"
import {
Button,
CloseButton,
Drawer,
Input,
Portal,
Stack,
} from "@chakra-ui/react"
import { useRef } from "react"
export const DrawerWithInitialFocus = () => {
const ref = useRef(null)
return (
ref.current}>
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Custom Container
Here's an example of how to render the drawer component in a custom container.
Consider setting `closeOnInteractOutside` to `false` to prevent the drawer from
closing when interacting outside the drawer.
```tsx
"use client"
import {
Button,
CloseButton,
Drawer,
Portal,
Stack,
type StackProps,
Text,
} from "@chakra-ui/react"
import { forwardRef, useRef } from "react"
const DrawerContainer = forwardRef(
function DrawerContainer(props, ref) {
return (
)
},
)
export const DrawerWithCustomContainer = () => {
const portalRef = useRef(null)
return (
Render drawer hereDrawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Header Actions
Here's an example of rendering actions in the header of the drawer component.
```tsx
import {
Button,
ButtonGroup,
CloseButton,
Drawer,
Portal,
} from "@chakra-ui/react"
export const DrawerWithHeaderActions = () => {
return (
Drawer Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
)
}
```
### Drawer with conditional variants
Here is an example of how to change variants based on the different breakpoints.
This example uses the `mdDown` breakpoint to change the drawer's placement on
smaller screens. This approach is recommended because both conditions are
translated into CSS media queries, which helps avoid base style merging issues.
If you really want to use the base condition instead, you’ll also need to define
corresponding sizes. For example:
``
```tsx
import {
Button,
CloseButton,
Drawer,
Kbd,
Portal,
Text,
} from "@chakra-ui/react"
export const DrawerWithConditionalVariants = () => {
return (
<>
Open drawer and resize screen to mobile sizeDrawer Title
Press the esc key to close the drawer.
>
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeOnEscape | true | `boolean` | Whether to close the dialog when the escape key is pressed |
| closeOnInteractOutside | true | `boolean` | Whether to close the dialog when the outside is clicked |
| defaultOpen | false | `boolean` | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| modal | true | `boolean` | Whether to prevent pointer interaction outside the element and hide all content below it |
| preventScroll | true | `boolean` | Whether to prevent scrolling behind the dialog when it's opened |
| role | "dialog" | `'dialog' \| 'alertdialog'` | The dialog's role |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| trapFocus | true | `boolean` | Whether to trap focus inside the dialog when it's opened |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | xs | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | The size of the component |
| placement | end | `'start' \| 'end' \| 'top' \| 'bottom'` | The placement of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| aria-label | undefined | `string` | Human readable label for the dialog, in event the dialog title is not rendered |
| finalFocusEl | undefined | `() => MaybeElement` | Element to receive focus when the dialog is closed |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n trigger: string\n positioner: string\n backdrop: string\n content: string\n closeTrigger: string\n title: string\n description: string\n}>` | The ids of the elements in the dialog. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| initialFocusEl | undefined | `() => MaybeElement` | Element to receive focus when the dialog is opened |
| onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function to call when the dialog's open state changes |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| open | undefined | `boolean` | The controlled open state of the dialog |
| persistentElements | undefined | `(() => Element \| null)[]` | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
| restoreFocus | undefined | `boolean` | Whether to restore focus to the element that had focus before the dialog was opened |
| contained | undefined | `'true' \| 'false'` | The contained of the component |
# Editable
```tsx
import { Editable } from "@chakra-ui/react"
export const EditableBasic = () => (
)
```
## Usage
```jsx
import { Editable } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Double Click
Use the `activationMode` prop to make the content editable when users double
click.
```tsx
import { Editable } from "@chakra-ui/react"
export const EditableWithDoubleClick = () => (
)
```
### Disabled
Use the `disabled` prop to disable the editable component.
```tsx
import { Editable } from "@chakra-ui/react"
export const EditableDisabled = () => {
return (
)
}
```
### Textarea
You can make a text area editable.
```tsx
import { Editable } from "@chakra-ui/react"
export const EditableWithTextarea = () => {
return (
)
}
```
### With Controls
Add controls such as "edit", "cancel" and "submit" to `Editable` for better user
experience.
```tsx
import { Editable, IconButton } from "@chakra-ui/react"
import { LuCheck, LuPencilLine, LuX } from "react-icons/lu"
export const EditableWithControls = () => {
return (
)
}
```
### Controlled
Use the `value` and `onValueChange` props to control the editable component.
```tsx
"use client"
import { Editable } from "@chakra-ui/react"
import { useState } from "react"
export const EditableControlled = () => {
const [name, setName] = useState("")
return (
setName(e.value)}
placeholder="Click to edit"
>
)
}
```
### Store
An alternative way to control the editable component is to use the
`RootProvider` component and the `useEditable` store hook.
This way you can access the editable state and methods from outside the
editable.
```tsx
"use client"
import { Code, Editable, Stack, useEditable } from "@chakra-ui/react"
export const EditableWithStore = () => {
const editable = useEditable({
defaultValue: "Click to edit",
})
return (
{editable.editing ? "editing" : "not editing"}
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| activationMode | "focus" | `ActivationMode` | The activation mode for the preview element.
- "focus" - Enter edit mode when the preview is focused
- "dblclick" - Enter edit mode when the preview is double-clicked
- "click" - Enter edit mode when the preview is clicked
- "none" - Edit can be triggered programmatically only |
| selectOnFocus | true | `boolean` | Whether to select the text in the input when it is focused. |
| submitMode | "both" | `SubmitMode` | The action that triggers submit in the edit mode:
- "enter" - Trigger submit when the enter key is pressed
- "blur" - Trigger submit when the editable is blurred
- "none" - No action will trigger submit. You need to use the submit button
- "both" - Pressing `Enter` and blurring the input will trigger submit |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| autoResize | undefined | `boolean` | Whether the editable should auto-resize to fit the content. |
| defaultEdit | undefined | `boolean` | Whether the editable is in edit mode by default. |
| defaultValue | undefined | `string` | The initial value of the editable when rendered.
Use when you don't need to control the value of the editable. |
| disabled | undefined | `boolean` | Whether the editable is disabled. |
| edit | undefined | `boolean` | Whether the editable is in edit mode. |
| finalFocusEl | undefined | `() => HTMLElement \| null` | The element to receive focus when the editable is closed. |
| form | undefined | `string` | The associate form of the underlying input. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n area: string\n label: string\n preview: string\n input: string\n control: string\n submitTrigger: string\n cancelTrigger: string\n editTrigger: string\n}>` | The ids of the elements in the editable. Useful for composition. |
| invalid | undefined | `boolean` | Whether the input's value is invalid. |
| maxLength | undefined | `number` | The maximum number of characters allowed in the editable |
| name | undefined | `string` | The name attribute of the editable component. Used for form submission. |
| onEditChange | undefined | `(details: EditChangeDetails) => void` | Function to call when the edit mode changes. |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function to call when the value changes. |
| onValueCommit | undefined | `(details: ValueChangeDetails) => void` | Function to call when the value is committed. |
| onValueRevert | undefined | `(details: ValueChangeDetails) => void` | Function to call when the value is reverted. |
| placeholder | undefined | `string \| { edit: string; preview: string }` | The placeholder text for the editable. |
| readOnly | undefined | `boolean` | Whether the editable is read-only. |
| required | undefined | `boolean` | Whether the editable is required. |
| translations | undefined | `IntlTranslations` | The translations for the editable. |
| value | undefined | `string` | The controlled value of the editable. |
## Explorer
Explore the `Editable` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Em
```tsx
import { Em, Text } from "@chakra-ui/react"
export const EmBasic = () => {
return (
The design system is a collection of UI elements
)
}
```
## Usage
```js
import { Em } from "@chakra-ui/react"
```
```jsx
The design system is a collection of UI elements
```
# Empty State
```tsx
import { EmptyState, VStack } from "@chakra-ui/react"
import { LuShoppingCart } from "react-icons/lu"
export const EmptyStateBasic = () => {
return (
Your cart is empty
Explore our products and add items to your cart
)
}
```
## Usage
```tsx
import { EmptyState } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Use the `size` prop to set the size of the Empty state.
```tsx
import { EmptyState, For, Stack, VStack } from "@chakra-ui/react"
import { LuShoppingCart } from "react-icons/lu"
export const EmptyStateSizes = () => {
return (
{(size) => (
Your cart is empty
Explore our products and add items to your cart
)}
)
}
```
### Action
Here's an example of an empty state with an action button.
```tsx
import { Button, ButtonGroup, EmptyState, VStack } from "@chakra-ui/react"
import { HiColorSwatch } from "react-icons/hi"
export const EmptyStateWithAction = () => {
return (
Start adding tokens
Add a new design token to get started
)
}
```
### List
Here's an example of an empty state with a list.
```tsx
import { EmptyState, List, VStack } from "@chakra-ui/react"
import { HiColorSwatch } from "react-icons/hi"
export const EmptyStateWithList = () => {
return (
No results found
Try adjusting your search
Try removing filtersTry different keywords
)
}
```
### Closed Component
Here's how to setup the Empty State for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add empty-state
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `Empty State` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Environment Provider
We use
[Zag.js](https://zagjs.com/overview/composition#custom-window-environment)
internally, which relies on DOM query methods like `document.querySelectorAll`
and `document.getElementById`. In custom environments like iframes, Shadow DOM,
or Electron, these methods might not work as expected.
To handle this, Ark UI includes the `EnvironmentProvider`, allowing you to set
the appropriate root node or document, ensuring correct DOM queries.
## Usage
```jsx
import { EnvironmentProvider } from "@chakra-ui/react"
```
```jsx
{/* Your App */}
```
## Examples
### iframe
Here's an example that uses `react-frame-component` to set the
`EnvironmentProvider`'s value with the iframe environment.
```jsx
import { EnvironmentProvider } from "@chakra-ui/react"
import Frame, { FrameContextConsumer } from "react-frame-component"
export const Demo = () => (
{({ document }) => (
document}>
{/* Your App */}
)}
)
```
### Shadow DOM
Here's an example that uses `react-shadow` to set the `EnvironmentProvider`'s
value with Shadow DOM environment.
```jsx
import { EnvironmentProvider } from "@chakra-ui/react"
import { useRef } from "react"
import root from "react-shadow"
export const Demo = () => {
const portalRef = useRef()
return (
portalRef?.current?.shadowRoot ?? document}
>
{/* Your App */}
)
}
```
### Accessing Context
Use the `useEnvironmentContext` hook to access the `RootNode`, `Document`, and
`Window` context.
```jsx
import { useEnvironmentContext } from "@chakra-ui/react"
export const Demo = () => {
const { getRootNode } = useEnvironmentContext()
return
{JSON.stringify(getRootNode(), null, 2)}
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | undefined | `RootNode \| (() => RootNode)` | undefined |
# Field
```tsx
import { Field, Input } from "@chakra-ui/react"
export const FieldBasic = () => {
return (
Email
)
}
```
## Usage
```tsx
import { Field } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Error Text
Pass the `invalid` prop to `Field.Root` and use the `Field.ErrorText` to
indicate that the field is invalid.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const FieldWithErrorText = () => {
return (
EmailThis is an error text
)
}
```
### Helper Text
Use the `Field.HelperText` to add helper text to the field.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const FieldWithHelperText = () => {
return (
EmailThis is a helper text
)
}
```
### Horizontal
Use the `orientation="horizontal"` prop to align the label and input
horizontally.
```tsx
import { Field, Input, Stack, Switch } from "@chakra-ui/react"
export const FieldHorizontal = () => {
return (
NameEmailHide email
)
}
```
### Disabled
Use the `disabled` prop to disable the field.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const FieldWithDisabled = () => {
return (
Email
)
}
```
### Textarea
Here's how to use the field component with a textarea.
```tsx
import { Field, Textarea } from "@chakra-ui/react"
export const FieldWithTextarea = () => {
return (
Email
)
}
```
### Native Select
Here's how to use the field component with a native select.
```tsx
import { Field, NativeSelect } from "@chakra-ui/react"
export const FieldWithNativeSelect = () => {
return (
Email
)
}
```
### Required
Pass the `required` prop to `Field.Root` and use the `Field.RequiredIndicator`
to indicate that the field is required.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const FieldWithRequired = () => {
return (
Email
)
}
```
### Optional
Pass the `fallback` prop to the `Field.RequiredIndicator` to add optional text.
```tsx
import { Badge, Field, Input } from "@chakra-ui/react"
export const FieldWithOptional = () => {
return (
Email
Optional
}
/>
)
}
```
### Closed Component
Here's how to setup the Field for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add field
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| orientation | vertical | `'vertical' \| 'horizontal'` | The orientation of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| disabled | undefined | `boolean` | Indicates whether the field is disabled. |
| ids | undefined | `ElementIds` | The ids of the field parts. |
| invalid | undefined | `boolean` | Indicates whether the field is invalid. |
| readOnly | undefined | `boolean` | Indicates whether the field is read-only. |
| required | undefined | `boolean` | Indicates whether the field is required. |
## Explorer
Explore the `Field` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Fieldset
```tsx
import {
Button,
Field,
Fieldset,
For,
Input,
NativeSelect,
Stack,
} from "@chakra-ui/react"
export const FieldsetBasic = () => {
return (
Contact details
Please provide your contact details below.
NameEmail addressCountry
{(item) => (
)}
)
}
```
## Usage
```jsx
import { Fieldset } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Disabled
Use the `disabled` prop to disable the fieldset to disable all input elements
within the fieldset.
```tsx
import {
Field,
Fieldset,
For,
Input,
NativeSelect,
Textarea,
} from "@chakra-ui/react"
export const FieldsetWithDisabled = () => {
return (
Shipping detailsStreet addressCountry
{(item) => (
)}
Delivery notes
)
}
```
### Invalid
Use the `invalid` prop to mark the fieldset as invalid. This will show the error
text.
> Note: You need to pass the `invalid` prop to the `Field` component within the
> fieldset to make each input element invalid.
```tsx
import {
Field,
Fieldset,
For,
Input,
NativeSelect,
Textarea,
} from "@chakra-ui/react"
export const FieldsetWithInvalid = () => {
return (
Shipping detailsStreet addressCountry
{(item) => (
)}
Notes
Some fields are invalid. Please check them.
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| invalid | undefined | `boolean` | Indicates whether the fieldset is invalid. |
## Explorer
Explore the `Fieldset` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# File Upload
```tsx
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
export const FileUploadBasic = () => {
return (
)
}
```
## Usage
```jsx
import { FileUpload } from "@chakra-ui/react"
```
```jsx
```
## Shortcuts
The `FileUpload` component also provides a set of shortcuts for common use
cases.
### FileUploadItems
By default, the `FileUploadItems` shortcut renders the list of uploaded files.
This works:
```tsx
{({ acceptedFiles }) =>
acceptedFiles.map((file) => (
))
}
```
This might be more concise, if you don't need to customize the file upload
items:
```tsx
```
### FileUploadList
The `FileUploadList` shortcut renders the list of uploaded files. It composes
the `FileUpload.ItemGroup` and `FileUpload.Items` components.
```tsx
```
is the same as:
```tsx
```
## Examples
### Accepted Files
Define the accepted files for upload using the `accept` prop.
```tsx
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
export const FileUploadAcceptedFiles = () => {
return (
)
}
```
### Multiple Files
Upload multiple files at once by using the `maxFiles` prop.
```tsx
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
export const FileUploadMultiple = () => {
return (
)
}
```
### Custom Preview
Here's an example of how to show a custom image preview for files.
```tsx
"use client"
import {
Button,
FileUpload,
Float,
useFileUploadContext,
} from "@chakra-ui/react"
import { LuFileImage, LuX } from "react-icons/lu"
const FileUploadList = () => {
const fileUpload = useFileUploadContext()
const files = fileUpload.acceptedFiles
if (files.length === 0) return null
return (
{files.map((file) => (
))}
)
}
export const FileUploadCustomPreview = () => {
return (
)
}
```
### Directory
Use the `directory` prop to allow selecting a directory instead of a file.
```tsx
import { Button, FileUpload } from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
export const FileUploadDirectory = () => {
return (
)
}
```
### Media Capture
Use the `capture` prop to select and upload files from different environments
and media types.
> **Note:** This is
> [not fully supported](https://caniuse.com/mdn-api_htmlinputelement_capture) in
> all browsers.
```tsx
import { Button, FileUpload } from "@chakra-ui/react"
import { HiCamera } from "react-icons/hi"
export const FileUploadMediaCapture = () => {
return (
)
}
```
### Dropzone
Drop multiple files inside the dropzone and use the `maxFiles` prop to set the
number of files that can be uploaded at once.
```tsx
import { Box, FileUpload, Icon } from "@chakra-ui/react"
import { LuUpload } from "react-icons/lu"
export const FileUploadWithDropzone = () => {
return (
Drag and drop files here.png, .jpg up to 5MB
)
}
```
### Conditional Dropzone
Hide the dropzone when the maximum number of files has been reached by using
`useFileUploadContext` to access the accepted files count.
```tsx
"use client"
import { Box, FileUpload, Icon, useFileUploadContext } from "@chakra-ui/react"
import { LuUpload } from "react-icons/lu"
const MAX_FILES = 3
const ConditionalDropzone = () => {
const fileUpload = useFileUploadContext()
const acceptedFiles = fileUpload.acceptedFiles
if (acceptedFiles.length >= MAX_FILES) {
return null
}
return (
Drag and drop files here
{MAX_FILES - acceptedFiles.length} more file
{MAX_FILES - acceptedFiles.length !== 1 ? "s" : ""} allowed
)
}
export const FileUploadWithConditionalDropzone = () => {
return (
)
}
```
### Input
Use the `FileInput` component to create a trigger that looks like a text input.
```tsx
import { FileUpload, Input } from "@chakra-ui/react"
export const FileUploadWithInput = () => {
return (
Upload file
)
}
```
### Clearable
Here's an example of a clearable file upload input.
```tsx
import { CloseButton, FileUpload, Input, InputGroup } from "@chakra-ui/react"
import { LuFileUp } from "react-icons/lu"
export const FileUploadWithInputClear = () => {
return (
Upload file}
endElement={
}
>
)
}
```
### Pasting Files
Here's an example of handling files pasted from the clipboard.
```tsx
"use client"
import {
FileUpload,
Float,
HStack,
Input,
type InputProps,
useFileUploadContext,
} from "@chakra-ui/react"
import { HiX } from "react-icons/hi"
const FilePasteInput = (props: InputProps) => {
const fileUpload = useFileUploadContext()
return (
{
fileUpload.setClipboardFiles(e.clipboardData)
}}
/>
)
}
const FileImageList = () => {
const fileUpload = useFileUploadContext()
return (
{fileUpload.acceptedFiles.map((file) => (
))}
)
}
export const FileUploadWithPasteEvent = () => {
return (
)
}
```
### Store
An alternative way to control the file upload is to use the `RootProvider`
component and the `useFileUpload` store hook.
This way you can access the file upload state and methods from outside the file
upload.
```tsx
"use client"
import {
Button,
Code,
FileUpload,
Stack,
useFileUpload,
} from "@chakra-ui/react"
import { HiUpload } from "react-icons/hi"
export const FileUploadWithStore = () => {
const fileUpload = useFileUpload({
maxFiles: 1,
maxFileSize: 3000,
})
const accepted = fileUpload.acceptedFiles.map((file) => file.name)
const rejected = fileUpload.rejectedFiles.map((e) => e.file.name)
return (
accepted: {accepted.join(", ")}rejected: {rejected.join(", ")}
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| allowDrop | true | `boolean` | Whether to allow drag and drop in the dropzone element |
| locale | "en-US" | `string` | The current locale. Based on the BCP 47 definition. |
| maxFiles | 1 | `number` | The maximum number of files |
| maxFileSize | Infinity | `number` | The maximum file size in bytes |
| minFileSize | 0 | `number` | The minimum file size in bytes |
| preventDocumentDrop | true | `boolean` | Whether to prevent the drop event on the document |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| accept | undefined | `Record \| FileMimeType \| FileMimeType[]` | The accept file types |
| acceptedFiles | undefined | `File[]` | The controlled accepted files |
| capture | undefined | `'user' \| 'environment'` | The default camera to use when capturing media |
| defaultAcceptedFiles | undefined | `File[]` | The default accepted files when rendered.
Use when you don't need to control the accepted files of the input. |
| directory | undefined | `boolean` | Whether to accept directories, only works in webkit browsers |
| disabled | undefined | `boolean` | Whether the file input is disabled |
| ids | undefined | `Partial<{\n root: string\n dropzone: string\n hiddenInput: string\n trigger: string\n label: string\n item: (id: string) => string\n itemName: (id: string) => string\n itemSizeText: (id: string) => string\n itemPreview: (id: string) => string\n}>` | The ids of the elements. Useful for composition. |
| invalid | undefined | `boolean` | Whether the file input is invalid |
| name | undefined | `string` | The name of the underlying file input |
| onFileAccept | undefined | `(details: FileAcceptDetails) => void` | Function called when the file is accepted |
| onFileChange | undefined | `(details: FileChangeDetails) => void` | Function called when the value changes, whether accepted or rejected |
| onFileReject | undefined | `(details: FileRejectDetails) => void` | Function called when the file is rejected |
| required | undefined | `boolean` | Whether the file input is required |
| transformFiles | undefined | `(files: File[]) => Promise` | Function to transform the accepted files to apply transformations |
| translations | undefined | `IntlTranslations` | The localized messages to use. |
| validate | undefined | `(file: File, details: FileValidateDetails) => FileError[] \| null` | Function to validate a file |
## Explorer
Explore the `File Upload` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Flex
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexBasic = () => {
return (
)
}
```
## Usage
```jsx
import { Flex, Spacer } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Direction
Use the `direction` or `flexDirection` prop to change the direction of the flex
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithDirection = () => {
return (
)
}
```
### Align
Use the `align` or `alignItems` prop to align the children along the cross axis.
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithAlign = () => {
return (
)
}
```
### Justify
Use the `justify` or `justifyContent` prop to align the children along the main
axis.
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithJustify = () => {
return (
flex-start
center
flex-end
space-between
)
}
```
### Order
Use the `order` prop to change the order of the children.
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithOrder = () => {
return (
1
2
3
)
}
```
### Auto Margin
Apply margin to a flex item to push it away from its siblings.
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithAutoMargin = () => {
return (
)
}
```
### Spacer
Use the `Spacer` component to create flexible space between flex items. It will
expand to fill all available space, pushing items to opposite ends.
```tsx
import { Box, Flex, Spacer } from "@chakra-ui/react"
export const FlexWithSpacer = () => {
return (
Box 1
Box 2
)
}
```
### Wrap
Use the `wrap` or `flexWrap` prop to wrap the children when they overflow the
parent.
```tsx
import { Flex } from "@chakra-ui/react"
export const FlexWithWrap = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| align | undefined | `SystemStyleObject['alignItems'] \| undefined` | undefined |
| justify | undefined | `SystemStyleObject['justifyContent'] \| undefined` | undefined |
| wrap | undefined | `SystemStyleObject['flexWrap'] \| undefined` | undefined |
| direction | undefined | `SystemStyleObject['flexDirection'] \| undefined` | undefined |
| basis | undefined | `SystemStyleObject['flexBasis'] \| undefined` | undefined |
| grow | undefined | `SystemStyleObject['flexGrow'] \| undefined` | undefined |
| shrink | undefined | `SystemStyleObject['flexShrink'] \| undefined` | undefined |
| inline | undefined | `boolean \| undefined` | undefined |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Float
```tsx
import { Box, Circle, Float } from "@chakra-ui/react"
export const FloatBasic = () => (
3
)
```
## Usage
Float requires a parent element with `position: relative` style applied.
```jsx
import { Box, Float } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Placement
Use the `placement` prop to position the element along the edges of the
container.
```tsx
import { Box, Circle, Float, HStack, Stack } from "@chakra-ui/react"
export const FloatWithPlacements = () => (
{placements.map((placement) => (
{placement}
3
))}
)
const placements = [
"bottom-end",
"bottom-start",
"top-end",
"top-start",
"bottom-center",
"top-center",
"middle-center",
"middle-end",
"middle-start",
] as const
```
### Offset X
Use the `offsetX` prop to offset the element along the x-axis.
```tsx
import { Box, Circle, Float } from "@chakra-ui/react"
export const FloatWithOffsetX = () => (
3
)
```
### Offset Y
Use the `offsetY` prop to offset the element along the y-axis.
```tsx
import { Box, Circle, Float } from "@chakra-ui/react"
export const FloatWithOffsetY = () => (
3
)
```
### Offset
Use the `offset` prop to offset the element along both axes.
```tsx
import { Box, Circle, Float } from "@chakra-ui/react"
export const FloatWithOffset = () => (
3
)
```
### Avatar
Here's an example of composing a `Float` component with an `Avatar` component.
```tsx
import { Avatar, Badge, Box, Float } from "@chakra-ui/react"
export const FloatWithAvatar = () => {
return (
New
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| placement | top-end | `\| ConditionalValue<\n \| 'bottom-end'\n \| 'bottom-start'\n \| 'top-end'\n \| 'top-start'\n \| 'bottom-center'\n \| 'top-center'\n \| 'middle-center'\n \| 'middle-end'\n \| 'middle-start'\n >\n \| undefined` | The placement of the indicator |
| offsetX | undefined | `SystemStyleObject['left'] \| undefined` | The x offset of the indicator |
| offsetY | undefined | `SystemStyleObject['top'] \| undefined` | The y offset of the indicator |
| offset | undefined | `SystemStyleObject['top'] \| undefined` | The x and y offset of the indicator |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# For
```tsx
import { For } from "@chakra-ui/react"
export const ForBasic = () => {
return (
{(item, index) =>
{item}
}
)
}
```
## Usage
The `For` component is used to render a list of items in a strongly typed
manner. It is similar to the `.map()`.
```jsx
import { For } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Object
Here's an example of using the `For` component to loop over an object.
```tsx
import { Box, For, Stack, Text } from "@chakra-ui/react"
export const ForWithObject = () => {
return (
{(item, index) => (
{item.name}Powers: {item.powers.join(", ")}
)}
)
}
```
### Fallback
Use the `fallback` prop to render a fallback component when the array is empty
or undefined.
```tsx
import { For, Stack, VStack } from "@chakra-ui/react"
import { LuBox } from "react-icons/lu"
export const ForWithFallback = () => {
return (
No items to show
}
>
{(item, index) => (
{item}
)}
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| each | undefined | `T[] \| readonly T[] \| undefined` | The array to iterate over |
| fallback | undefined | `React.ReactNode \| undefined` | The fallback content to render when the array is empty |
# Format Byte
```tsx
import { FormatByte, Text } from "@chakra-ui/react"
export const FormatByteBasic = () => {
return (
File size:
)
}
```
## Usage
```jsx
import { FormatByte } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
The format functions works for any size of bytes.
```tsx
import { FormatByte, Stack, Text } from "@chakra-ui/react"
export const FormatByteSizes = () => {
return (
)
}
```
### Format Bits
Use the `unit` prop to change the byte format to bits.
```tsx
import { FormatByte, Text } from "@chakra-ui/react"
export const FormatByteWithUnit = () => {
return (
File size:
)
}
```
### Locale
Wrap the `FormatByte` component within the `LocaleProvider` to change the
locale.
```tsx
import { FormatByte, HStack, LocaleProvider, Text } from "@chakra-ui/react"
export const FormatByteWithLocale = () => {
return (
de-DEzh-CN
)
}
```
### Unit Display
Use the `unitDisplay` prop to change the byte format to compact notation.
```tsx
import { FormatByte, Stack, Text } from "@chakra-ui/react"
export const FormatByteWithUnitDisplay = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | undefined | `number` | The byte size to format |
| unit | undefined | `'bit' \| 'byte'` | The unit granularity to display |
| unitDisplay | undefined | `'long' \| 'short' \| 'narrow'` | The unit display |
# Format Number
```tsx
import { FormatNumber, Text } from "@chakra-ui/react"
export const FormatNumberBasic = () => {
return (
)
}
```
## Usage
The number formatting logic is handled by the native `Intl.NumberFormat` API and
smartly cached to avoid performance issues when using the same locale and
options.
```jsx
import { FormatNumber } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Percentage
Use the `style=percentage` prop to change the number format to percentage.
```tsx
import { FormatNumber, Text } from "@chakra-ui/react"
export const FormatNumberWithPercentage = () => {
return (
)
}
```
### Currency
Use the `style=currency` prop to change the number format to currency.
```tsx
import { FormatNumber, Text } from "@chakra-ui/react"
export const FormatNumberWithCurrency = () => {
return (
)
}
```
### Locale
Wrap the `FormatNumber` component within the `LocaleProvider` to change the
locale.
```tsx
import { FormatNumber, HStack, LocaleProvider, Text } from "@chakra-ui/react"
export const FormatNumberWithLocale = () => {
return (
de-DEzh-CN
)
}
```
### Unit
Use the `style=unit` prop to change the number format to unit.
```tsx
import { FormatNumber, Text } from "@chakra-ui/react"
export const FormatNumberWithUnit = () => {
return (
)
}
```
### Compact Notation
Use the `notation=compact` prop to change the number format to compact notation.
```tsx
import { FormatNumber, Text } from "@chakra-ui/react"
export const FormatNumberWithCompact = () => {
return (
)
}
```
## Props
The `FormatNumber` component supports all `Intl.NumberFormat` options in
addition to the following props:
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | undefined | `number` | The number to format |
# Grid
```tsx
import { Grid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const GridBasic = () => {
return (
)
}
```
## Usage
```jsx
import { Grid, GridItem } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Col Span
Pass `colSpan` prop to `GridItem` to span across columns.
```tsx
import { Grid, GridItem } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const GridWithColSpan = () => {
return (
)
}
```
### Spanning Columns
In some layouts, you may need certain grid items to span specific amount of
columns or rows instead of an even distribution
```tsx
import { Grid, GridItem } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const GridSpanningColumns = () => {
return (
rowSpan=2colSpan=2colSpan=2colSpan=4
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| templateColumns | undefined | `SystemStyleObject['gridTemplateColumns'] \| undefined` | undefined |
| autoFlow | undefined | `SystemStyleObject['gridAutoFlow'] \| undefined` | undefined |
| autoRows | undefined | `SystemStyleObject['gridAutoRows'] \| undefined` | undefined |
| autoColumns | undefined | `SystemStyleObject['gridAutoColumns'] \| undefined` | undefined |
| templateRows | undefined | `SystemStyleObject['gridTemplateRows'] \| undefined` | undefined |
| templateAreas | undefined | `SystemStyleObject['gridTemplateAreas'] \| undefined` | undefined |
| column | undefined | `SystemStyleObject['gridColumn'] \| undefined` | undefined |
| row | undefined | `SystemStyleObject['gridRow'] \| undefined` | undefined |
| inline | undefined | `boolean \| undefined` | undefined |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Group
```tsx
import { Group } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const GroupBasic = () => {
return (
1
2
)
}
```
## Usage
```jsx
import { Group } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Button
Here's an example of using the `Group` component to group buttons together.
```tsx
import { Button, Group } from "@chakra-ui/react"
export const GroupWithButton = () => {
return (
)
}
```
### Attached
Use the `attached` prop to attach the children together.
```tsx
import { Badge, Button, Group, Stack } from "@chakra-ui/react"
export const GroupWithAttached = () => {
return (
Commit status
90+
)
}
```
**Note:** When composing custom components and attaching them to a `Group`,
ensure you forward props.
```tsx {10} /{...props}/
export const Demo = () => {
return (
Two
)
}
function FocusButton(props: ButtonProps) {
return (
)
}
```
### Grow
Use the `grow` prop to make the children grow to fill the available space.
```tsx
import { Button, Group } from "@chakra-ui/react"
export const GroupWithGrow = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Heading
```tsx
import { Heading } from "@chakra-ui/react"
export const HeadingBasic = () => {
return The quick brown fox jumps over the lazy dog
}
```
## Usage
```js
import { Heading } from "@chakra-ui/react"
```
```jsx
I'm a Heading
```
## Examples
### Sizes
Use the `size` prop to change the size of the heading component.
```tsx
import { Heading, Stack } from "@chakra-ui/react"
export const HeadingWithSizes = () => {
return (
Heading (sm)Heading (md)Heading (lg)Heading (xl)Heading (2xl)Heading (3xl)Heading (4xl)Heading (5xl)Heading (6xl)
)
}
```
### Highlight
Compose the `Heading` component with the `Highlight` component to highlight
text.
```tsx
import { Heading, Highlight, Stack, Text } from "@chakra-ui/react"
export const HeadingWithHighlight = () => {
return (
Create accessible React apps with speed
Chakra UI is a simple, modular and accessible component library that
gives you the building blocks you need.
)
}
```
### As another element
Use the `as` prop to render the heading as another HTML element.
```tsx
import { Heading, Stack } from "@chakra-ui/react"
export const HeadingWithAsProp = () => {
return (
Level 1Level 2Level 3
)
}
```
### Weights
Use the `fontWeight` prop to change the weight of the heading component.
```tsx
import { Heading, Stack } from "@chakra-ui/react"
export const HeadingWithWeights = () => {
return (
NormalMediumSemiboldBold
)
}
```
### Composition
Use the `Heading` component to compose other components.
```tsx
import { Button, Heading, Stack, Text } from "@chakra-ui/react"
import { LuArrowRight } from "react-icons/lu"
export const HeadingWithComposition = () => {
return (
Modern payments for Stores
PayMe helps startups get paid by anyone, anywhere in the world
)
}
```
## Customization
To override the `fontSize`, we recommend using the `textStyle` prop since it
considers the line height and letter spacing as well.
### Base style
Here's an example of customizing the `Heading` component.
```tsx title="provider.tsx"
import { createSystem, defineRecipe } from "@chakra-ui/react"
import { defaultConfig } from "@chakra-ui/react"
const headingRecipe = defineRecipe({
base: {
fontWeight: "normal",
textStyle: "4xl",
},
})
const system = createSystem(defaultConfig, {
theme: {
recipes: { heading: headingRecipe },
},
})
```
### Custom Size
Update the `variants.size` property to create a custom size.
```tsx title="provider.tsx"
import { createSystem, defineRecipe } from "@chakra-ui/react"
import { defaultConfig } from "@chakra-ui/react"
const headingRecipe = defineRecipe({
variants: {
size: {
custom: {
fontSize: "100px",
lineHeight: "100px",
letterSpacing: "-2px",
},
},
},
})
const system = createSystem(defaultConfig, {
theme: {
recipes: { heading: headingRecipe },
},
})
```
Then, use the `custom` variant to create a custom size.
```tsx
I'm a custom size
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | xl | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| '3xl' \| '4xl' \| '5xl' \| '6xl' \| '7xl'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Highlight
```tsx
import { Highlight } from "@chakra-ui/react"
export const HighlightBasic = () => {
return (
With the Highlight component, you can spotlight words.
)
}
```
## Usage
```jsx
import { Highlight } from "@chakra-ui/react"
```
```jsx
Hello World
```
## Examples
### Multiple
Pass an array of strings to the `query` prop to highlight multiple substrings.
```tsx
import { Heading, Highlight } from "@chakra-ui/react"
export const HighlightMultiple = () => {
return (
With the Highlight component, you can spotlight, emphasize and
accentuate words.
)
}
```
### Custom Style
Use the `styles` prop to customize the style of the highlighted text.
```tsx
import { Highlight } from "@chakra-ui/react"
export const HighlightWithCustomStyle = () => {
return (
With the Highlight component, you can spotlight words.
)
}
```
### Search Query
Use the highlight component to highlight search query results.
```tsx
import { Highlight, Stack, Text } from "@chakra-ui/react"
const query = "spot"
const results = ["Spotlight bulb", "Spot cleaner", "Spot ceiling"]
export const HighlightSearchQuery = () => {
return (
Search result for: spot
{results.map((item) => (
{item}
))}
)
}
```
### With Squiggle
Here's an example of how to render a custom squiggle image around the
highlighted text. Useful for a more fancy effect.
```tsx
"use client"
import { Heading, Mark, useHighlight } from "@chakra-ui/react"
import { Fragment } from "react"
export const HighlightWithSquiggle = () => {
const chunks = useHighlight({
text: "Endless scale, powered by real humans.",
query: ["endless", "real humans."],
})
return (
{chunks.map((chunk, index) => {
return chunk.match ? (
{chunk.text}
) : (
{chunk.text}
)
})}
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| query | undefined | `string \| string[]` | The query to highlight in the text |
| text | undefined | `string` | The text to highlight |
| styles | undefined | `SystemStyleObject \| undefined` | undefined |
| ignoreCase | undefined | `boolean` | Whether to ignore case while matching |
| matchAll | undefined | `boolean` | Whether to match multiple instances of the query |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Hover Card
```tsx
import {
Avatar,
HStack,
HoverCard,
Icon,
Link,
Portal,
Stack,
Text,
} from "@chakra-ui/react"
import { LuChartLine } from "react-icons/lu"
export const HoverCardBasic = () => {
return (
@chakra_ui
Chakra UI
The most powerful toolkit for building modern web
applications.
2.5M Downloads
)
}
```
## Usage
```jsx
import { HoverCard } from "@chakra-ui/react"
```
```jsx
```
## Shortcuts
The `HoverCard` provides a shortcuts for common use cases.
### Arrow
The `HoverCard.Arrow` renders the `HoverCard.ArrowTip` component within in by
default.
This works:
```jsx
```
This might be more concise, if you don't need to customize the arrow tip.
```jsx
```
## Examples
### Controlled
Use the `open` and `onOpenChange` to control the visibility of the hover card.
```tsx
"use client"
import { Box, HoverCard, Link, Portal, Strong } from "@chakra-ui/react"
import { useState } from "react"
export const HoverCardControlled = () => {
const [open, setOpen] = useState(false)
return (
setOpen(e.open)}>
@chakra_ui
Chakra is a Sanskrit word that means disk or
wheel, referring to energy centers in the body
)
}
```
### Delays
Control the open and close delays using the `openDelay` and `closeDelay` props.
```tsx
import { Box, HoverCard, Link, Portal, Strong } from "@chakra-ui/react"
export const HoverCardWithDelay = () => {
return (
@chakra_ui
Chakra is a Sanskrit word that means disk or
wheel, referring to energy centers in the body
)
}
```
### Placement
Use the `positioning.placement` prop to configure the underlying `floating-ui`
positioning logic.
```tsx
import { Box, HoverCard, Link, Portal, Strong } from "@chakra-ui/react"
export const HoverCardWithPlacement = () => {
return (
@chakra_ui
Chakra is a Sanskrit word that means disk or
wheel, referring to energy centers in the body
)
}
```
### Disabled
Use the `disabled` prop to prevent opening the hover card on interaction.
```tsx
"use client"
import { HoverCard, Link, Portal, Stack, Text } from "@chakra-ui/react"
export const HoverCardWithDisabled = () => {
return (
@chakra_ui
Chakra UI
The most powerful toolkit for building modern web applications.
)
}
```
### Within Dialog
To use the `HoverCard` within a `Dialog`, you need to avoid portalling the
`HoverCard.Positioner` to the document's body.
```diff
-
{/* ... */}
-
```
## Accessibility
HoverCard should be used solely for supplementary information that is not
essential for understanding the context.
It is inaccessible to screen readers and cannot be activated via keyboard, so
avoid placing crucial content within it.
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeDelay | 300 | `number` | The duration from when the mouse leaves the trigger or content until the hover card closes. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| openDelay | 700 | `number` | The duration from when the mouse enters the trigger until the hover card opens. |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultOpen | undefined | `boolean` | The initial open state of the hover card when rendered.
Use when you don't need to control the open state of the hover card. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ trigger: string; content: string; positioner: string; arrow: string }>` | The ids of the elements in the popover. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function called when the hover card opens or closes. |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| open | undefined | `boolean` | The controlled open state of the hover card |
| positioning | undefined | `PositioningOptions` | The user provided options used to position the popover content |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
## Explorer
Explore the `Hover Card` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Icon Button
```tsx
import { IconButton } from "@chakra-ui/react"
import { LuSearch } from "react-icons/lu"
export const IconButtonBasic = () => {
return (
)
}
```
## Usage
```jsx
import { IconButton } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the button.
```tsx
import { For, HStack, IconButton, Text, VStack } from "@chakra-ui/react"
import { LuPhone } from "react-icons/lu"
export const IconButtonWithSizes = () => {
return (
{(size) => (
{size}
)}
)
}
```
### Variants
Use the `variant` prop to change its visual style
```tsx
import { For, HStack, IconButton, Text, VStack } from "@chakra-ui/react"
import { LuVoicemail } from "react-icons/lu"
export const IconButtonWithVariants = () => {
return (
{(variant) => (
{variant}
)}
)
}
```
### Color
Use the `colorPalette` prop to change the color of the button
```tsx
import { For, HStack, IconButton } from "@chakra-ui/react"
import { LuSearch } from "react-icons/lu"
export const IconButtonWithColors = () => {
return (
{(c) => (
)}
)
}
```
### Rounded
Set `rounded="full"` to make the button fully rounded
```tsx
import { IconButton } from "@chakra-ui/react"
import { LuVoicemail } from "react-icons/lu"
export const IconButtonRounded = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| spinnerPlacement | start | `'start' \| 'end' \| undefined` | The placement of the spinner |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | solid | `'solid' \| 'subtle' \| 'surface' \| 'outline' \| 'ghost' \| 'plain'` | The variant of the component |
| spinner | undefined | `React.ReactNode \| undefined` | The spinner to show while loading. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Icon
```tsx
import { Icon } from "@chakra-ui/react"
import { HiHeart } from "react-icons/hi"
export const IconBasic = () => (
)
```
## Usage
```jsx
import { Icon } from "@chakra-ui/react"
```
```jsx
```
:::warning
Chakra doesn't provide any icons out of the box. Use popular icon libraries like
[react-icons](https://react-icons.github.io/react-icons/) or
[lucide-react](https://lucide.dev/react/)
:::
## Examples
### React Icons
Integrate with popular react icon libraries like `react-icons`
```tsx
import { Icon } from "@chakra-ui/react"
import { Md3dRotation } from "react-icons/md"
export const IconWithReactIcon = () => (
)
```
### Custom svg
Use the `asChild` prop to render custom svg icons within the `Icon` component
```tsx
import { Icon } from "@chakra-ui/react"
export const IconWithCustomSvg = () => {
return (
)
}
```
### Create Icon
Use the `createIcon` utility to create custom icons
```tsx
"use client"
import { createIcon } from "@chakra-ui/react"
const HeartIcon = createIcon({
displayName: "HeartIcon",
path: (
<>
>
),
})
export const IconWithCreateIcon = () => {
return
}
```
# Image
```tsx
import { Image } from "@chakra-ui/react"
export const ImageBasic = () => (
)
```
## Usage
```js
import { Image } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Height
Use the `height` prop to change the height of the image component.
```tsx
import { Image } from "@chakra-ui/react"
export const ImageWithHeight = () => {
return (
)
}
```
### Circular
Here's an example of how to render a circular image.
```tsx
import { Image } from "@chakra-ui/react"
export const ImageCircular = () => (
)
```
### Aspect Ratio
Use the `aspectRatio` prop to change the aspect ratio of the image component.
```tsx
import { Image } from "@chakra-ui/react"
export const ImageWithAspectRatio = () => {
return (
)
}
```
### Fit
By default, the image applies `object-fit: cover`. Use the `fit` prop to change
the fit of the image component.
```tsx
import { Image } from "@chakra-ui/react"
export const ImageWithFit = () => (
)
```
### HTML Width and Height
Use the `htmlWidth` and `htmlHeight` props to set the native width and height of
the image component.
```tsx
import { Image } from "@chakra-ui/react"
export const ImageWithHtmlHeight = () => {
return (
)
}
```
### Next.js Image
Use the `asChild` prop to render the image as a child of the `Image` component.
```jsx
import NextImage from "next/image"
;
```
## Props
The `Image` component supports all native props for the `img` element.
# Input
```tsx
import { Input } from "@chakra-ui/react"
export const InputBasic = () => {
return
}
```
## Usage
```tsx
import { Input } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Variants
Use the `variant` prop to change the visual style of the input.
```tsx
import { Input, Stack } from "@chakra-ui/react"
export const InputWithVariants = () => {
return (
)
}
```
### Sizes
Use the `size` prop to change the size of the input.
```tsx
import { Input, Stack } from "@chakra-ui/react"
export const InputWithSizes = () => {
return (
)
}
```
### Helper Text
Pair the input with the `Field` component to add helper text.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const InputWithHelperText = () => {
return (
Email We'll never share your email.
)
}
```
### Error Text
Pair the input with the `Field` component to add error text.
```tsx
import { Field, Input } from "@chakra-ui/react"
export const InputWithErrorText = () => {
return (
EmailThis field is required
)
}
```
### Field
Compose the input with the `Field` component to add a label, helper text, and
error text.
```tsx
import { Field, HStack, Input } from "@chakra-ui/react"
export const InputWithField = () => {
return (
Email
Email
)
}
```
### Hook Form
Here's an example of how to integrate the input with `react-hook-form`.
```tsx
"use client"
import { Button, Field, Input, Stack } from "@chakra-ui/react"
import { useForm } from "react-hook-form"
interface FormValues {
firstName: string
lastName: string
}
export const InputWithHookForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm()
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Element
Use the `startElement` and `endElement` on the `InputGroup` component to add an
element to the start and end of the input.
#### Start Icon
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
import { LuUser } from "react-icons/lu"
export const InputWithStartIcon = () => {
return (
}>
)
}
```
#### Start Text
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
export const InputWithStartText = () => {
return (
)
}
```
#### Start and End Text
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
export const InputWithStartAndEndText = () => {
return (
)
}
```
#### Kbd
```tsx
import { Input, InputGroup, Kbd } from "@chakra-ui/react"
import { LuSearch } from "react-icons/lu"
export const InputWithKbd = () => (
} endElement={⌘K}>
)
```
#### Select
```tsx
import { Input, InputGroup, NativeSelect } from "@chakra-ui/react"
const DomainSelect = () => (
)
export const InputWithSelect = () => {
return (
}>
)
}
```
### Addon
Use the `InputAddon` and `Group` components to add an addon to the input.
#### Start Addon
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
export const InputWithStartAddon = () => {
return (
)
}
```
#### End Addon
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
export const InputWithEndAddon = () => {
return (
)
}
```
#### Start and End Addon
```tsx
import { Input, InputGroup } from "@chakra-ui/react"
export const InputWithStartAndEndAddon = () => {
return (
)
}
```
### Disabled
Use the `disabled` prop to disable the input.
```tsx
import { Input } from "@chakra-ui/react"
export const InputWithDisabled = () => {
return
}
```
### Button
Use the `Group` component to attach a button to the input.
```tsx
import { Button, Group, Input } from "@chakra-ui/react"
export const InputWithEndButton = () => {
return (
)
}
```
### Focus and Error Color
Use the `--focus-color` and `--error-color` CSS custom properties to change the
color of the input when it is focused or in an error state.
```tsx
import { Field, Input, Stack } from "@chakra-ui/react"
export const InputWithFocusErrorColor = () => {
return (
focusColor=limeerrorColor=greenerrorColor=bluevariant=outline,focusColor=errorvariant=subtle,focusColor=errorvariant=flushed,focusColor=error
)
}
```
### Placeholder Style
Use the `_placeholder` prop to style the placeholder text.
```tsx
import { Input } from "@chakra-ui/react"
export const InputWithPlaceholderStyle = () => {
return (
)
}
```
### Floating Label
Here's an example of how to build a floating label to the input.
```tsx
"use client"
import type { InputProps } from "@chakra-ui/react"
import {
Box,
Field,
Input,
defineStyle,
useControllableState,
} from "@chakra-ui/react"
import { useState } from "react"
export const InputWithFloatingLabel = () => {
return (
This field is required
)
}
interface FloatingLabelInputProps extends InputProps {
label: React.ReactNode
value?: string | undefined
defaultValue?: string | undefined
onValueChange?: ((value: string) => void) | undefined
}
const FloatingLabelInput = (props: FloatingLabelInputProps) => {
const { label, onValueChange, value, defaultValue = "", ...rest } = props
const [inputState, setInputState] = useControllableState({
defaultValue,
onChange: onValueChange,
value,
})
const [focused, setFocused] = useState(false)
const shouldFloat = inputState.length > 0 || focused
return (
{
props.onFocus?.(e)
setFocused(true)
}}
onBlur={(e) => {
props.onBlur?.(e)
setFocused(false)
}}
onChange={(e) => {
props.onChange?.(e)
setInputState(e.target.value)
}}
value={inputState}
data-float={shouldFloat || undefined}
/>
{label}
)
}
const floatingStyles = defineStyle({
pos: "absolute",
bg: "bg",
px: "0.5",
top: "2.5",
insetStart: "3",
fontWeight: "normal",
pointerEvents: "none",
transition: "position",
color: "fg.muted",
"&[data-float]": {
top: "-3",
insetStart: "2",
color: "fg",
},
})
```
### Mask
Here's an example of using the `use-mask-input` library to mask the input shape.
```tsx
"use client"
import { Input } from "@chakra-ui/react"
import { withMask } from "use-mask-input"
export const InputWithMask = () => {
return (
)
}
```
### Character Counter
Here's an example of how to add a character counter to the input.
```tsx
"use client"
import { Input, InputGroup, Span } from "@chakra-ui/react"
import { useState } from "react"
const MAX_CHARACTERS = 20
export const InputWithCharacterCounter = () => {
const [value, setValue] = useState("")
return (
{value.length} / {MAX_CHARACTERS}
}
>
{
setValue(e.currentTarget.value.slice(0, MAX_CHARACTERS))
}}
/>
)
}
```
### Card Number
Here's an example of using `react-payment-inputs` to create a card number input.
```tsx
"use client"
import { Input, InputGroup } from "@chakra-ui/react"
import { LuCreditCard } from "react-icons/lu"
import { usePaymentInputs } from "react-payment-inputs"
export const InputWithCardNumber = () => {
const { wrapperProps, getCardNumberProps } = usePaymentInputs()
return (
}>
)
}
```
You can create a full card inputs for a card number, expiry date, and CVC.
```tsx
"use client"
import { Box, Group, Input, InputGroup, Show } from "@chakra-ui/react"
import { LuCreditCard } from "react-icons/lu"
import { usePaymentInputs } from "react-payment-inputs"
import cardImages, { type CardImages } from "react-payment-inputs/images"
const images = cardImages as unknown as CardImages
const CardImage = (props: ReturnType) => {
const { meta, getCardImageProps } = props
return (
}
>
)
}
export const InputWithCardDetails = () => {
const payment = usePaymentInputs()
return (
}
>
)
}
```
### Clear Button
Combine the `Input` and `CloseButton` components to create a clear button. This
is useful for building search inputs.
```tsx
"use client"
import { CloseButton, Input, InputGroup } from "@chakra-ui/react"
import { useRef, useState } from "react"
export const InputWithClearButton = () => {
const [value, setValue] = useState("Initial value")
const inputRef = useRef(null)
const endElement = value ? (
{
setValue("")
inputRef.current?.focus()
}}
me="-2"
/>
) : undefined
return (
{
setValue(e.currentTarget.value)
}}
/>
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | outline | `'outline' \| 'subtle' \| 'flushed'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Kbd
```tsx
import { Kbd } from "@chakra-ui/react"
export const KbdBasic = () => {
return Shift + Tab
}
```
## Usage
```jsx
import { Kbd } from "@chakra-ui/react"
```
```jsx
F12
```
## Examples
### Combinations
Render `Kbd` to showcase key combinations
```tsx
import { HStack, Kbd } from "@chakra-ui/react"
export const KbdWithCombinations = () => {
return (
ctrl+shift+del
)
}
```
### Function Keys
Here's an example of using `Kbd` to showcase function keys
```tsx
import { HStack, Kbd } from "@chakra-ui/react"
export const KbdFunctionKeys = () => {
return (
⌘⌥⇧⌃
)
}
```
### Variants
Use the `variant` prop to change the appearance of the `Kbd` component
```tsx
import { HStack, Kbd } from "@chakra-ui/react"
export const KbdWithVariants = () => {
return (
Shift + TabShift + TabShift + TabShift + Tab
)
}
```
### Sizes
Use the `size` prop to change the size of the `Kbd` component
```tsx
import { HStack, Kbd } from "@chakra-ui/react"
export const KbdWithSizes = () => {
return (
Shift + TabShift + TabShift + Tab
)
}
```
### Within Text
Use `Kbd` within text to highlight key combinations
```tsx
import { Kbd, Text } from "@chakra-ui/react"
export const KbdWithinText = () => {
return (
Press F12 to open DevTools
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | raised | `'raised' \| 'outline' \| 'subtle' \| 'plain'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# Link Overlay
```tsx
import { Heading, Link, LinkOverlay, Stack, Text } from "@chakra-ui/react"
export const LinkOverlayBasic = () => {
return (
Wanna try it out?
This entire area is a link. Click it to see the effect.
Click me
)
}
```
## Usage
The `LinkOverlay` component provides a semantic way to link an entire component
or card.
```jsx
import { LinkBox, LinkOverlay } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Article
Here's an example of using `LinkOverlay` to link an entire article.
```tsx
import {
Heading,
Link,
LinkBox,
LinkOverlay,
Span,
Text,
} from "@chakra-ui/react"
export const LinkOverlayArticle = () => {
return (
Chakra V3 Workshop
Catch up on whats been cooking at Chakra UI and explore some of the
popular community resources.
Inner Link
)
}
```
### Custom Link
Use the `asChild` prop to add support for custom Link component like `next/link`
or react router's `Link`
```jsx
import { LinkBox, LinkOverlay } from "@chakra-ui/react"
import NextLink from "next/link"
function Example() {
return (
Blog Post Title
Some blog post content
Some inner link
)
}
```
## Caveat
One of the side-effects of this technique is that the content can't be
"selectable" (i.e. with a pointing device), however, this seems to be pretty
uncommon in web design.
# Link
```tsx
import { Link } from "@chakra-ui/react"
export const LinkBasic = () => {
return Visit Chakra UI
}
```
## Usage
```jsx
import { Link } from "@chakra-ui/react"
```
```jsx
Click here
```
## Examples
### Variants
Use the `variant` prop to change the appearance of the `Link` component
```tsx
import { Link, Stack } from "@chakra-ui/react"
export const LinkWithVariants = () => {
return (
Link (Underline)
Link (Plain)
)
}
```
### Within Text
Use `Link` within a text to create a hyperlink
```tsx
import { Link, Text } from "@chakra-ui/react"
export const LinkWithinText = () => {
return (
Visit the{" "}
Chakra UI
{" "}
website
)
}
```
### External
Add an external link icon to the `Link` component
```tsx
import { Link } from "@chakra-ui/react"
import { LuExternalLink } from "react-icons/lu"
export const LinkWithExternal = () => {
return (
Visit Chakra UI
)
}
```
### Routing Library
Use the `asChild` prop to compose `Link` with framework links like (Next.js)
```jsx
import { Link as ChakraLink } from "@chakra-ui/react"
import NextLink from "next/link"
const Demo = () => {
return (
Click here
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | plain | `'underline' \| 'plain'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
# List
```tsx
import { List } from "@chakra-ui/react"
export const ListBasic = () => (
Lorem ipsum dolor sit amet, consectetur adipisicing elit
Assumenda, quia temporibus eveniet a libero incidunt suscipit
Quidem, ipsam illum quis sed voluptatum quae eum fugit earum
)
```
## Usage
```jsx
import { List } from "@chakra-ui/react"
```
```jsx
Item 1Item 2
```
## Examples
### Ordered
Pass the `as="ol"` prop to create an ordered list
```tsx
import { List } from "@chakra-ui/react"
export const ListOrdered = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipisicing elit
Assumenda, quia temporibus eveniet a libero incidunt suscipit
Quidem, ipsam illum quis sed voluptatum quae eum fugit earum
)
}
```
### Icon
Use the `List.Indicator` component to add an icon to the list
```tsx
import { List } from "@chakra-ui/react"
import { LuCircleCheck, LuCircleDashed } from "react-icons/lu"
export const ListWithIcon = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipisicing elit
Assumenda, quia temporibus eveniet a libero incidunt suscipit
Quidem, ipsam illum quis sed voluptatum quae eum fugit earum
)
}
```
### Nested
Here's an example of a nested list
```tsx
import { List } from "@chakra-ui/react"
export const ListNested = () => {
return (
First order itemFirst order item
First order item with list
Nested itemNested itemNested itemFirst order item
)
}
```
### Marker Style
Use the `_marker` prop to style the marker of the list
```tsx
import { List } from "@chakra-ui/react"
const items = [
"Your failure to comply with any provision of these Terms of Service;",
"Your use of the Services, including but not limited to economic, physical, emotional, psychological or privacy related considerations; and",
"Your actions to knowingly affect the Services via any bloatware, malware, computer virus, worm, Trojan horse, spyware, adware, crimeware, scareware, rootkit or any other program installed in a way that executable code of any program is scheduled to utilize or utilizes processor cycles during periods of time when such program is not directly or indirectly being used.",
]
export const ListWithMarkerStyle = () => {
return (
{items.map((item, index) => (
{item}
))}
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | marker | `'marker' \| 'plain'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| align | undefined | `'center' \| 'start' \| 'end'` | The align of the component |
## Explorer
Explore the `List` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Listbox
```tsx
"use client"
import { Listbox, createListCollection } from "@chakra-ui/react"
export const ListboxBasic = () => {
return (
Select framework
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
## Usage
```jsx
import { Listbox } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Controlled
Control the listbox value externally using the `value` and `onValueChange` props
for custom state management.
```tsx
"use client"
import { Code, Listbox, Stack, createListCollection } from "@chakra-ui/react"
import { useState } from "react"
export const ListboxControlled = () => {
const [value, setValue] = useState([])
return (
setValue(details.value)}
>
Select framework
{frameworks.items.map((framework) => (
{framework.label}
))}
Selected: {JSON.stringify(value, null, 2)}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### With Store
An alternative way to control the listbox is to use the `RootProvider` component
and the `useListbox` store hook.
This way you can access the listbox state and methods from outside the listbox.
> Use `RootProvider + useListbox` or `Root`, not both.
```tsx
"use client"
import {
Code,
Listbox,
Stack,
createListCollection,
useListbox,
} from "@chakra-ui/react"
export const ListboxWithStore = () => {
const listbox = useListbox({ collection: frameworks })
return (
Select framework
{frameworks.items.map((framework) => (
{framework.label}
))}
Selected: {JSON.stringify(listbox.value, null, 2)}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### Disabled Item
Disable specific items in the listbox to indicate unavailable options while
keeping them visible for context.
```tsx
"use client"
import { Listbox, createListCollection } from "@chakra-ui/react"
export const ListboxDisabledItem = () => {
return (
Select framework
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue", disabled: true },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte", disabled: true },
{ label: "Next.js", value: "nextjs" },
],
})
```
### Grouped
Use item groups to organize related options with clear section headers, making
it easier for users to find specific categories of items.
```tsx
"use client"
import { Listbox, createListCollection } from "@chakra-ui/react"
export const ListboxGrouped = () => {
return (
Select media
{collection.group().map(([category, items]) => (
{category}
{items.map((item) => (
{item.label}
))}
))}
)
}
const collection = createListCollection({
items: [
{ label: "Naruto", value: "naruto", category: "Anime" },
{ label: "One Piece", value: "one-piece", category: "Anime" },
{ label: "Dragon Ball", value: "dragon-ball", category: "Anime" },
{
label: "The Shawshank Redemption",
value: "the-shawshank-redemption",
category: "Movies",
},
{ label: "The Godfather", value: "the-godfather", category: "Movies" },
{ label: "The Dark Knight", value: "the-dark-knight", category: "Movies" },
],
groupBy: (item) => item.category,
})
```
### Horizontal
Display listbox items in a horizontal layout with card-based presentation,
perfect for media galleries or visual selection interfaces.
```tsx
"use client"
import {
Image,
Listbox,
Stack,
Text,
createListCollection,
} from "@chakra-ui/react"
export const ListboxHorizontal = () => {
return (
Select Album
{musicAlbums.items.map((album) => (
{album.title}
{album.artist}
))}
)
}
const musicAlbums = createListCollection({
items: [
{
value: "euphoric-echoes",
title: "Euphoric Echoes",
artist: "Luna Solstice",
image:
"https://images.unsplash.com/photo-1493225457124-a3eb161ffa5f?w=160&h=160&fit=crop",
},
{
value: "neon-dreamscape",
title: "Neon Dreamscape",
artist: "Electra Skyline",
image:
"https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=160&h=160&fit=crop",
},
{
value: "cosmic-serenade",
title: "Cosmic Serenade",
artist: "Orion's Symphony",
image:
"https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=160&h=160&fit=crop",
},
{
value: "melancholy-melodies",
title: "Melancholy Melodies",
artist: "Violet Mistral",
image:
"https://images.unsplash.com/photo-1571330735066-03aaa9429d89?w=160&h=160&fit=crop",
},
{
value: "rhythmic-illusions",
title: "Rhythmic Illusions",
artist: "Mirage Beats",
image:
"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=160&h=160&fit=crop",
},
],
})
```
### Multiple Selection
Enable users to select multiple items from the list, useful for scenarios like
choosing tags, categories, or preferences.
```tsx
"use client"
import { Listbox, createListCollection } from "@chakra-ui/react"
export const ListboxMultiselect = () => {
return (
Select frameworks (multiple)
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Next.js", value: "nextjs" },
{ label: "Nuxt.js", value: "nuxtjs" },
],
})
```
### Select All
Provide convenient "Select All" and "Select None" controls for multiple
selection scenarios, with visual indicators showing selection state.
```tsx
"use client"
import type { CheckmarkProps, FlexProps } from "@chakra-ui/react"
import {
Box,
Checkmark,
Flex,
Listbox,
createListCollection,
useListboxContext,
useListboxItemContext,
} from "@chakra-ui/react"
export const ListboxSelectAll = () => {
return (
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const ListboxHeader = (props: FlexProps) => {
const listbox = useListboxContext()
const isAllSelected = listbox.value.length === frameworks.items.length
const isSomeSelected =
listbox.value.length > 0 && listbox.value.length < frameworks.items.length
const handleSelectAll = () => {
if (isAllSelected) {
listbox.setValue([])
} else {
listbox.setValue(frameworks.items.map((item) => item.value))
}
}
return (
Select Frameworks
)
}
const ListboxItemCheckmark = (props: CheckmarkProps) => {
const itemState = useListboxItemContext()
return (
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Next.js", value: "nextjs" },
{ label: "Nuxt.js", value: "nuxtjs" },
{ label: "Remix", value: "remix" },
{ label: "Gatsby", value: "gatsby" },
{ label: "Ember.js", value: "ember" },
{ label: "Preact", value: "preact" },
],
})
```
### Extended Select
Use extended selection mode to allow users to select multiple items using
keyboard shortcuts like Cmd/Ctrl for advanced selection patterns.
```tsx
"use client"
import { Kbd, Listbox, createListCollection } from "@chakra-ui/react"
export const ListboxExtendedSelect = () => {
return (
Select frameworks (hold ⌘ or ^ to select multiple)
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### With Checkmark
Display custom checkmarks for multiple selection scenarios, providing clear
visual feedback for selected items.
```tsx
"use client"
import {
Checkmark,
Listbox,
createListCollection,
useListboxItemContext,
} from "@chakra-ui/react"
const ListboxItemCheckmark = () => {
const itemState = useListboxItemContext()
return (
)
}
export const ListboxWithCheckmark = () => {
return (
Select frameworks (with checkmarks)
{frameworks.items.map((framework) => (
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Next.js", value: "nextjs" },
{ label: "Nuxt.js", value: "nuxtjs" },
],
})
```
### With Icon
Add icons to listbox items to provide visual context and improve recognition of
different options.
```tsx
"use client"
import { Box, Listbox, createListCollection } from "@chakra-ui/react"
import { LuAtom, LuGlobe, LuPalette, LuZap } from "react-icons/lu"
export const ListboxWithIcon = () => {
return (
Select framework
{frameworks.items.map((framework) => (
{framework.icon}
{framework.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react", icon: },
{ label: "Vue.js", value: "vue", icon: },
{ label: "Angular", value: "angular", icon: },
{ label: "Svelte", value: "svelte", icon: },
],
})
```
### With Description
Include additional descriptive text for each item to provide more context and
help users make informed choices.
```tsx
"use client"
import { Box, Listbox, Text, createListCollection } from "@chakra-ui/react"
export const ListboxWithDescription = () => {
return (
Select framework
{frameworks.items.map((framework) => (
{framework.label}
{framework.description}
))}
)
}
const frameworks = createListCollection({
items: [
{
label: "React.js",
value: "react",
description: "A JavaScript library for building user interfaces",
},
{
label: "Vue.js",
value: "vue",
description: "The progressive JavaScript framework",
},
{
label: "Angular",
value: "angular",
description: "Platform for building mobile and desktop web applications",
},
{
label: "Svelte",
value: "svelte",
description: "Cybernetically enhanced web apps",
},
{
label: "Next.js",
value: "nextjs",
description: "The React framework for production",
},
],
})
```
### With Input
Combine a search input with the listbox to filter options dynamically, making it
easy to find specific items in long lists.
```tsx
"use client"
import { Input, Listbox, useFilter, useListCollection } from "@chakra-ui/react"
export const ListboxWithInput = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Next.js", value: "nextjs" },
{ label: "Nuxt.js", value: "nuxtjs" },
{ label: "Remix", value: "remix" },
{ label: "Gatsby", value: "gatsby" },
{ label: "Ember.js", value: "ember" },
{ label: "Preact", value: "preact" },
],
filter: contains,
})
return (
Select Framework filter(e.target.value)}
/>
{collection.items.map((framework) => (
{framework.label}
))}
No frameworks found
)
}
```
### With Popover
Use the listbox within a popover to create dropdown-like selection menus that
overlay other content without taking up permanent screen space.
```tsx
"use client"
import {
Button,
Listbox,
Popover,
Portal,
useFilter,
useListCollection,
useListbox,
} from "@chakra-ui/react"
import { useRef, useState } from "react"
import { LuChevronDown } from "react-icons/lu"
export const ListboxWithPopover = () => {
const [inputValue, setInputValue] = useState("")
const [open, setOpen] = useState(false)
const { contains } = useFilter({ sensitivity: "base" })
const triggerRef = useRef(null)
const { collection, filter } = useListCollection({
initialItems: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
{ label: "Next.js", value: "nextjs" },
{ label: "Nuxt.js", value: "nuxtjs" },
],
filter: contains,
})
const listbox = useListbox({
collection,
onValueChange() {
setOpen(false)
setInputValueFn("")
triggerRef.current?.focus()
},
})
const setInputValueFn = (value: string) => {
setInputValue(value)
filter(value)
}
const selectedItem = listbox.selectedItems[0]
return (
setOpen(e.open)}>
setInputValueFn(e.currentTarget.value)}
/>
{collection.items.map((framework) => (
{framework.label}
))}
)
}
```
### With Dialog
Present the listbox in a modal dialog for focused selection experiences,
particularly useful for important choices that need user attention.
```tsx
"use client"
import {
Button,
Dialog,
HStack,
Kbd,
Listbox,
Portal,
Span,
Text,
useFilter,
useListCollection,
} from "@chakra-ui/react"
import { useState } from "react"
export const ListboxWithDialog = () => {
const [selectedFrameworks, setSelectedFrameworks] = useState([])
const [isOpen, setIsOpen] = useState(false)
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: [
{ label: "Linear.app", value: "linear", type: "applications" },
{ label: "Notion", value: "notion", type: "applications" },
{ label: "Figma", value: "figma", type: "applications" },
{ label: "Slack", value: "slack", type: "applications" },
{ label: "Cursor", value: "cursor", type: "applications" },
{ label: "Open Terminal", value: "terminal", type: "commands" },
{ label: "Search Files", value: "search", type: "commands" },
{ label: "Git Status", value: "git-status", type: "commands" },
{ label: "Run Tests", value: "run-tests", type: "commands" },
{ label: "Deploy App", value: "deploy", type: "commands" },
],
filter: contains,
groupBy: (item) => item.type,
groupSort: ["applications", "commands"],
})
const handleSelectionChange = (details: any) => {
setSelectedFrameworks(details.value)
setIsOpen(false)
filter("")
}
return (
<>
setIsOpen(e.open)}>
filter(e.currentTarget.value)}
/>
{collection.group().map(([group, items]) => (
{group}
{items.map((item) => (
{item.label}
{item.type}
))}
))}
{selectedFrameworks.length > 0 && (
Selected: {JSON.stringify(selectedFrameworks, null, 2)}
)}
>
)
}
const CommandItem = (props: { label: string; keys: string[] }) => {
return (
{props.label} {props.keys.join(" ")}
)
}
```
### Virtualized
Handle large datasets efficiently with virtualization, rendering only visible
items to maintain smooth scrolling performance even with thousands of items.
```tsx
"use client"
import { Listbox, createListCollection, useLiveRef } from "@chakra-ui/react"
import { type VirtualItem, useVirtualizer } from "@tanstack/react-virtual"
import React, { useEffect, useMemo, useRef } from "react"
export const ListboxVirtualized = () => {
const virtual = useListboxVirtualizer({
count: countries.length,
})
const collection = useMemo(
() => createListCollection({ items: countries }),
[],
)
return (
Select Country ({countries.length} items)
)}
)
}
export const ListboxTransferList = () => {
const state = useTransferListState({ items: animeCharacters })
return (
item.value)}
onValueChange={(e) => state.setSelectedSource(e.items)}
/>
{
state.moveToTarget(state.selectedSource)
}}
>
{
state.moveToSource(state.selectedTarget)
}}
>
item.value)}
onValueChange={(e) => state.setSelectedTarget(e.items)}
/>
)
}
function useTransferListState(options: CollectionOptions) {
const sourceContentRef = useRef(null)
const targetContentRef = useRef(null)
const [source, setSource] = useState(createListCollection(options))
const [target, setTarget] = useState(
createListCollection({ ...options, items: [] }),
)
const [selectedSource, setSelectedSource] = useState([])
const [selectedTarget, setSelectedTarget] = useState([])
const scrollToItem = (container: HTMLDivElement | null, item: T) => {
if (!container) return
requestAnimationFrame(() => {
const itemValue = target.getItemValue(item)
const itemElement = container.querySelector(`[data-value="${itemValue}"]`)
itemElement?.scrollIntoView({ block: "nearest" })
})
}
const moveToTarget = (items: T[]) => {
setSource(source.remove(...items))
setTarget(target.append(...items))
setSelectedSource([])
scrollToItem(targetContentRef.current, items[items.length - 1])
}
const moveToSource = (items: T[]) => {
setSource(source.append(...items))
setTarget(target.remove(...items))
setSelectedTarget([])
scrollToItem(sourceContentRef.current, items[items.length - 1])
}
return {
source,
target,
selectedSource,
selectedTarget,
setSelectedSource,
setSelectedTarget,
moveToTarget,
moveToSource,
sourceContentRef,
targetContentRef,
}
}
interface Item {
label: string
value: string
}
const animeCharacters = [
{ label: "Naruto", value: "naruto" },
{ label: "Sasuke", value: "sasuke" },
{ label: "Sakura", value: "sakura" },
{ label: "Kakashi", value: "kakashi" },
{ label: "Shisui", value: "shisui" },
{ label: "Itachi", value: "itachi" },
{ label: "Gaara", value: "gaara" },
{ label: "Rock Lee", value: "rock-lee" },
{ label: "Neji", value: "neji" },
{ label: "Tenten", value: "tenten" },
{ label: "Hinata", value: "hinata" },
{ label: "Kiba", value: "kiba" },
{ label: "Shino", value: "shino" },
{ label: "Choji", value: "choji" },
{ label: "Ino", value: "ino" },
]
```
### Emoji Grid
Display emojis in a grid layout with filtering capability, perfect for emoji
pickers or icon selection interfaces.
```tsx
"use client"
import {
Input,
Listbox,
Square,
createGridCollection,
useFilter,
useListboxContext,
} from "@chakra-ui/react"
import emojibase from "emojibase-data/en/compact.json"
import { useCallback, useMemo, useState } from "react"
import { LuSmile } from "react-icons/lu"
type Emoji = (typeof emojibase)[number]
const emojis = emojibase
.filter((e) => !e.label.startsWith("regional indicator"))
.slice(0, 200) as Emoji[]
export const ListboxWithEmojiGrid = () => {
const { contains } = useFilter({ sensitivity: "base" })
const [items, setItems] = useState(emojis)
const collection = useMemo(
() =>
createGridCollection({
columnCount: 8,
items: items,
itemToString(item) {
return `${item.label} (${item.shortcodes})`
},
itemToValue(item) {
return item.hexcode
},
}),
[items],
)
const filter = useCallback(
(value: string) => {
setItems(emojis.filter((e) => contains(e.label, value)))
},
[contains],
)
return (
filter(e.target.value)}
/>
{collection.items.map((item, index) => (
{item.unicode}
))}
)
}
const SelectedEmoji = () => {
const listbox = useListboxContext()
const [item] = listbox.selectedItems as Emoji[]
return (
{item ? item.unicode : }
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| collection | undefined | `ListCollection` | The collection of items |
| defaultValue | [] | `string[]` | The initial default value of the listbox when rendered.
Use when you don't need to control the value of the listbox. |
| loopFocus | false | `boolean` | Whether to loop the keyboard navigation through the options |
| orientation | "vertical" | `'horizontal' \| 'vertical'` | The orientation of the listbox. |
| selectionMode | "single" | `SelectionMode` | How multiple selection should behave in the listbox.
- `single`: The user can select a single item.
- `multiple`: The user can select multiple items without using modifier keys.
- `extended`: The user can select multiple items by using modifier keys. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | subtle | `'subtle' \| 'solid' \| 'plain'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultHighlightedValue | undefined | `string` | The initial value of the highlighted item when opened.
Use when you don't need to control the highlighted value of the listbox. |
| deselectable | undefined | `boolean` | Whether to disallow empty selection |
| disabled | undefined | `boolean` | Whether the listbox is disabled |
| disallowSelectAll | undefined | `boolean` | Whether to disallow selecting all items when `meta+a` is pressed |
| highlightedValue | undefined | `string` | The controlled key of the highlighted item |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n content: string\n label: string\n item: (id: string \| number) => string\n itemGroup: (id: string \| number) => string\n itemGroupLabel: (id: string \| number) => string\n}>` | The ids of the elements in the listbox. Useful for composition. |
| onHighlightChange | undefined | `(details: HighlightChangeDetails) => void` | The callback fired when the highlighted item changes. |
| onSelect | undefined | `(details: SelectionDetails) => void` | Function called when an item is selected |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | The callback fired when the selected item changes. |
| scrollToIndexFn | undefined | `(details: ScrollToIndexDetails) => void` | Function to scroll to a specific index |
| selectOnHighlight | undefined | `boolean` | Whether to select the item when it is highlighted |
| typeahead | undefined | `boolean` | Whether to enable typeahead on the listbox |
| value | undefined | `string[]` | The controlled keys of the selected items |
### Label
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Content
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| highlightOnHover | undefined | `boolean` | Whether to highlight the item on hover |
| item | undefined | `any` | The item to render |
### ItemText
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### ItemIndicator
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### ItemGroup
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
### ItemGroupLabel
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
## Explorer
Explore the `Listbox` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Locale Provider
## Usage
The `LocaleProvider` component sets the locale for your app, formatting dates,
numbers, and other locale-specific data.
> Most Chakra UI components that read the locale set by the `LocaleProvider`.
```jsx
import { LocaleProvider, useLocaleContext } from "@chakra-ui/react"
```
```jsx
{/* Your App */}
```
## Examples
### Setting Locale
Set the `locale` prop to the locale you want to use.
```jsx
```
### Reading Locale
```jsx
export const Usage = () => {
const { locale, dir } = useLocaleContext()
return
{JSON.stringify({ locale, dir }, null, 2)}
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| locale | 'en-US' | `string` | The locale to use for the application. |
# Mark
```tsx
import { Mark, Text } from "@chakra-ui/react"
export const MarkBasic = () => {
return (
The design system is a collection of UI
elements
)
}
```
## Usage
```js
import { Mark } from "@chakra-ui/react"
```
```jsx
The design system is a collection of UI elements
```
## Examples
### Variants
Use the `variant` prop to change the color of the mark.
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| variant | undefined | `'subtle' \| 'solid' \| 'text' \| 'plain'` | The variant of the component |
# Menu
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuBasic = () => {
return (
New Text FileNew File...New WindowOpen File...Export
)
}
```
## Usage
```tsx
import { Menu } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Command
Use the `Menu.ItemCommand` component to display a command in the menu.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithCommand = () => {
return (
New Text File ⌘E
New File... ⌘N
New Window ⌘W
Open File... ⌘O
Export ⌘S
)
}
```
### Context menu
Use the `Menu.ContextTrigger` component to create a context menu.
```tsx
import { Center, Menu, Portal } from "@chakra-ui/react"
export const MenuWithContextTrigger = () => {
return (
Right click here
New Text FileNew File...New WindowOpen File...Export
)
}
```
### Group
Use the `Menu.ItemGroup` component to group related menu items.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithGroup = () => {
return (
StylesBoldUnderlineAlignLeftMiddleRight
)
}
```
### Danger Item
Here's an example of how to style a menu item that is used to delete an item.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithDangerItem = () => {
return (
RenameExport
Delete...
)
}
```
### Submenu
Here's an example of how to create a submenu.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
import { LuChevronRight } from "react-icons/lu"
export const MenuWithSubmenu = () => {
return (
New Text FileNew File...
Open Recent PandaArk UIChakra v3Open File...Export
)
}
```
### Links
Pass the `asChild` prop to the `Menu.Item` component to render a link.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithLinks = () => {
return (
{links.map((link) => (
{link.title}
))}
)
}
const links = [
{
title: "Naruto",
href: "https://www.crunchyroll.com/naruto",
},
{
title: "One Piece",
href: "https://www.crunchyroll.com/one-piece",
},
{
title: "Attack on Titan",
href: "https://www.crunchyroll.com/attack-on-titan",
},
]
```
When using custom router links, you need to set the `navigate` prop on the
`Menu.Root` component.
```tsx
"use client"
import { Menu } from "@chakra-ui/react"
import { useNavigate } from "react-router-dom"
const Demo = () => {
const navigate = useNavigate()
return (
navigate(`/${value}`)}>
{/* ... */}
)
}
```
### Radio Items
Here's an example of how to create a menu with radio items.
```tsx
"use client"
import { Button, Menu, Portal } from "@chakra-ui/react"
import { useState } from "react"
import { HiSortAscending } from "react-icons/hi"
export const MenuWithRadioItems = () => {
const [value, setValue] = useState("asc")
return (
setValue(e.value)}
>
{items.map((item) => (
{item.label}
))}
)
}
const items = [
{ label: "Ascending", value: "asc" },
{ label: "Descending", value: "desc" },
]
```
### Checkbox Items
Here's an example of how to create a menu with checkbox items.
```tsx
"use client"
import { Button, Menu, Portal, useCheckboxGroup } from "@chakra-ui/react"
import { HiCog } from "react-icons/hi"
export const MenuWithCheckboxItems = () => {
const group = useCheckboxGroup({ defaultValue: ["autosave"] })
return (
Features
{items.map(({ title, value }) => (
group.toggleValue(value)}
>
{title}
))}
)
}
const items = [
{ title: "Autosave", value: "autosave" },
{ title: "Detect Language", value: "detect-language" },
{ title: "Spellcheck", value: "spellcheck" },
]
```
### Icon and Command
Compose the menu to include icons and commands.
```tsx
import { Box, Button, Menu, Portal } from "@chakra-ui/react"
import { LuClipboardPaste, LuCopy, LuScissors } from "react-icons/lu"
export const MenuWithIconAndCommand = () => {
return (
Cut⌘XCopy⌘CPaste⌘V
)
}
```
### Placement
Use the `positioning.placement` prop to control the placement of the menu.
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithPlacement = () => {
return (
New Text FileNew File...New WindowOpen File...Export
)
}
```
### Avatar
Here's an example that composes the `Menu` with the `Avatar` component to
display a menu underneath an avatar.
```tsx
import { Avatar, Menu, Portal } from "@chakra-ui/react"
export const MenuWithAvatar = () => {
return (
AccountSettingsLogout
)
}
```
### Anchor Point
Use the `positioning.anchorPoint` prop to control the anchor point of the menu.
You can derive it from the `getBoundingClientRect` of a DOM element, or use
something like `DOMRect.fromRect({ x: 0, y: 0, width: 1, height: 1 })` to create
a new rect.
```tsx
"use client"
import { Box, Button, Menu, Portal } from "@chakra-ui/react"
import { useRef } from "react"
export const MenuWithAnchorRect = () => {
const ref = useRef(null)
const getAnchorRect = () => ref.current!.getBoundingClientRect()
return (
Anchor
New Text FileNew File...New WindowOpen File...Export
)
}
```
### Mixed Layout
Here's an example of how to create a mixed layout of menu items. In this layout,
the top horizontal menu includes common menu items.
```tsx
import { Box, Button, Group, Menu, Portal } from "@chakra-ui/react"
import {
LuClipboard,
LuCopy,
LuFileSearch,
LuMessageSquare,
LuScissors,
LuShare,
} from "react-icons/lu"
const horizontalMenuItems = [
{ label: "Cut", value: "cut", icon: },
{ label: "Copy", value: "copy", icon: },
{ label: "Paste", value: "paste", icon: },
]
const verticalMenuItems = [
{ label: "Look Up", value: "look-up", icon: },
{ label: "Translate", value: "translate", icon: },
{ label: "Share", value: "share", icon: },
]
export const MenuWithMixedLayout = () => {
return (
{horizontalMenuItems.map((item) => (
{item.icon}
{item.label}
))}
{verticalMenuItems.map((item) => (
{item.label}
{item.icon}
))}
)
}
```
### Overflow
When you have a long list of menu items, you can set a `maxH` prop on the
`Menu.Content` to create a scrollable menu.
:::note
The content has a default `maxHeight: "var(--available-height)"`, which is the
maximum available height for the content relative to the viewport.
:::
```tsx
import { Button, Menu, Portal } from "@chakra-ui/react"
export const MenuWithOverflow = () => {
return (
{menuItems.map((item) => (
{item.label}
))}
)
}
const menuItems = [
{ value: "new-file", label: "New File" },
{ value: "new-folder", label: "New Folder" },
{ value: "open", label: "Open..." },
{ value: "open-recent", label: "Open Recent" },
{ value: "save", label: "Save" },
{ value: "save-as", label: "Save As..." },
{ value: "save-all", label: "Save All" },
{ value: "export", label: "Export" },
{ value: "import", label: "Import" },
{ value: "print", label: "Print" },
{ value: "share", label: "Share" },
{ value: "duplicate", label: "Duplicate" },
{ value: "rename", label: "Rename" },
{ value: "move", label: "Move To..." },
{ value: "copy", label: "Copy To..." },
{ value: "delete", label: "Delete" },
{ value: "find", label: "Find" },
{ value: "replace", label: "Replace" },
{ value: "preferences", label: "Preferences" },
{ value: "settings", label: "Settings" },
{ value: "help", label: "Help" },
{ value: "about", label: "About" },
{ value: "quit", label: "Quit" },
]
```
### Hide When Detached
When the menu is rendered in an scrolling container, set the
`positioning.hideWhenDetached` to `true` to hide the menu when the trigger is
scrolled out of view.
```tsx
import { Box, Center, Flex, Menu, Portal, Text } from "@chakra-ui/react"
export const MenuWithHideWhenDetached = () => {
return (
{[...Array(6).keys()].map((x) => (
Item{x}
))}
Menu
New Text FileNew File...New WindowOpen File...Export
)
}
```
### Within Dialog
To use the `Menu` within a `Dialog`, you need to avoid portalling the
`Menu.Positioner` to the document's body.
```diff
-
{/* ... */}
-
```
If you have set `scrollBehavior="inside"` on the `Dialog`, you need to:
- Set the menu positioning to `fixed` to avoid the menu from being clipped by
the dialog.
- Set `hideWhenDetached` to `true` to hide the menu when the trigger is scrolled
out of view.
```tsx
{/* ... */}
```
```tsx
"use client"
import { Button, Dialog, Menu, Portal } from "@chakra-ui/react"
import Lorem from "react-lorem-ipsum"
export const MenuWithinDialog = () => {
return (
Welcome to the menu
)
}
const DialogMenu = () => {
return (
New Text FileNew File...New WindowOpen File...Export
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeOnSelect | true | `boolean` | Whether to close the menu when an option is selected |
| composite | true | `boolean` | Whether the menu is a composed with other composite widgets like a combobox or tabs |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| loopFocus | false | `boolean` | Whether to loop the keyboard navigation. |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| typeahead | true | `boolean` | Whether the pressing printable characters should trigger typeahead navigation |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | subtle | `'subtle' \| 'solid'` | The variant of the component |
| size | md | `'sm' \| 'md'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| anchorPoint | undefined | `Point` | The positioning point for the menu. Can be set by the context menu trigger or the button trigger. |
| aria-label | undefined | `string` | The accessibility label for the menu |
| defaultHighlightedValue | undefined | `string` | The initial highlighted value of the menu item when rendered.
Use when you don't need to control the highlighted value of the menu item. |
| defaultOpen | undefined | `boolean` | The initial open state of the menu when rendered.
Use when you don't need to control the open state of the menu. |
| highlightedValue | undefined | `string` | The controlled highlighted value of the menu item. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n trigger: string\n contextTrigger: string\n content: string\n groupLabel: (id: string) => string\n group: (id: string) => string\n positioner: string\n arrow: string\n}>` | The ids of the elements in the menu. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| navigate | undefined | `(details: NavigateDetails) => void` | Function to navigate to the selected item if it's an anchor element |
| onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onHighlightChange | undefined | `(details: HighlightChangeDetails) => void` | Function called when the highlighted menu item changes. |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function called when the menu opens or closes |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| onSelect | undefined | `(details: SelectionDetails) => void` | Function called when a menu item is selected. |
| open | undefined | `boolean` | The controlled open state of the menu |
| positioning | undefined | `PositioningOptions` | The options used to dynamically position the menu |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | undefined | `string` | The unique value of the menu item option. |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| closeOnSelect | undefined | `boolean` | Whether the menu should be closed when the option is selected. |
| disabled | undefined | `boolean` | Whether the menu item is disabled |
| onSelect | undefined | `VoidFunction` | The function to call when the item is selected |
| valueText | undefined | `string` | The textual value of the option. Used in typeahead navigation of the menu.
If not provided, the text content of the menu item will be used. |
## Explorer
Explore the `Menu` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Select (Native)
```tsx
import { NativeSelect } from "@chakra-ui/react"
export const NativeSelectBasic = () => {
return (
)
}
```
## Usage
```jsx
import { NativeSelect } from "@chakra-ui/react"
```
```jsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Use the `size` prop to change the size of the select component.
```tsx
import { For, NativeSelect, Stack } from "@chakra-ui/react"
export const NativeSelectWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Variants
Use the `variant` prop to change the appearance of the select component.
```tsx
import { For, NativeSelect, Stack } from "@chakra-ui/react"
export const NativeSelectWithVariants = () => {
return (
{(variant) => (
)}
)
}
```
### Controlled
Use the `value` and `onChange` props to control the select component.
```tsx
"use client"
import { NativeSelect } from "@chakra-ui/react"
import { useState } from "react"
export const NativeSelectControlled = () => {
const [value, setValue] = useState("")
return (
setValue(e.currentTarget.value)}
>
)
}
```
### Disabled
Pass the `disabled` prop to the `NativeSelect.Root` component to disable the
select component.
```tsx
import { NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithDisabled = () => (
)
```
### Invalid
Compose the native and `Field` component to set the invalid set and show the
error text.
```tsx
import { Field, NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithInvalid = () => (
This is an error
)
```
Alternatively, you can use the `invalid` prop on the `NativeSelect.Root`
component as well.
```tsx
import { NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithInvalidRoot = () => (
)
```
### Hook Form
Here is an example of how to use the `NativeSelect` component with
`react-hook-form`.
```tsx
"use client"
import { Button, Field, NativeSelect } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
framework: z.string().min(1, { message: "Framework is required" }),
})
type FormValues = z.infer
export const NativeSelectWithHookForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Ref
Here's how to access the underlying element reference
```tsx
import { NativeSelect } from "@chakra-ui/react"
const Demo = () => {
const ref = useRef(null)
return (
)
}
```
### Closed Component
Here's how to setup the Native Select for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add native-select
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | outline | `'outline' \| 'subtle' \| 'plain'` | The variant of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | The size of the component |
| disabled | undefined | `boolean \| undefined` | undefined |
| invalid | undefined | `boolean \| undefined` | undefined |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
## Explorer
Explore the `Select (Native)` component parts interactively. Click on parts in
the sidebar to highlight them in the preview.
# Number Input
```tsx
import { NumberInput } from "@chakra-ui/react"
export const NumberInputBasic = () => {
return (
)
}
```
## Usage
```tsx
import { NumberInput } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Shortcuts
The `NumberInput` component provides a set of shortcuts for common use cases
### NumberInputControl
This component renders the `NumberInput.IncrementTrigger` and
`NumberInput.DecrementTrigger` within it by default.
Writing this:
```tsx
```
is shorthand for writing this if you don't need to customize the triggers:
```tsx
```
## Examples
### Sizes
Pass the `size` prop to the `NumberInput.Root` component to change the size of
the number input.
```tsx
import { For, NumberInput, Stack } from "@chakra-ui/react"
export const NumberInputWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Formatting
Pass the `formatOptions` prop to the `NumberInput.Root` component to format the
number input value. The value of this maps to `Intl.NumberFormatOptions` and is
applied based on the current locale.
```tsx
import { NumberInput, Stack } from "@chakra-ui/react"
export const NumberInputWithFormatOptions = () => {
return (
)
}
```
### Min and Max
Pass the `min` and `max` props to the `NumberInput.Root` component to set the
minimum and maximum values of the number input.
If value entered is less than `min` or greater than `max`, the value will be
clamped to the nearest boundary on blur, or enter key press.
```tsx
import { NumberInput } from "@chakra-ui/react"
export const NumberInputWithMinMax = () => {
return (
)
}
```
### Step
Pass the `step` prop to the `NumberInput.Root` component to change the increment
or decrement interval of the number input.
```tsx
import { NumberInput } from "@chakra-ui/react"
export const NumberInputWithStep = () => {
return (
)
}
```
### Controlled
Pass the `value` and `onValueChange` props to the `NumberInput.Root` component
to control the value of the number input.
```tsx
"use client"
import { NumberInput } from "@chakra-ui/react"
import { useState } from "react"
export const NumberInputControlled = () => {
const [value, setValue] = useState("10")
return (
setValue(e.value)}
>
)
}
```
### Mobile Stepper
Here's an example of how to compose the number input as a mobile stepper.
```tsx
import { HStack, IconButton, NumberInput } from "@chakra-ui/react"
import { LuMinus, LuPlus } from "react-icons/lu"
export const NumberInputWithStepper = () => {
return (
)
}
```
### Mouse Wheel
Pass the `allowMouseWheel` prop to the `NumberInput.Root` component to enable or
disable the mouse wheel to change
```tsx
import { NumberInput } from "@chakra-ui/react"
export const NumberInputWithMouseWheel = () => {
return (
)
}
```
### Disabled
Pass the `disabled` prop to the `NumberInput.Root` component to disable the
number input.
```tsx
import { NumberInput } from "@chakra-ui/react"
export const NumberInputWithDisabled = () => {
return (
)
}
```
### Invalid
Use the `Field` component and the `invalid` prop to indicate that the number
input is invalid.
```tsx
import { Field, NumberInput } from "@chakra-ui/react"
export const NumberInputWithInvalid = () => {
return (
Enter NumberThe entry is invalid
)
}
```
### Helper Text
Compose the `Field` and `Field.HelperText` components to add helper text to the
number input.
```tsx
import { Field, NumberInput } from "@chakra-ui/react"
export const NumberInputWithField = () => {
return (
Enter NumberEnter a number between 1 and 10
)
}
```
### Element
Here's an example of how to compose the number input with the input group
component to add an element on either the left or right.
```tsx
import { InputGroup, NumberInput } from "@chakra-ui/react"
import { LuDollarSign } from "react-icons/lu"
export const NumberInputWithElement = () => {
return (
}>
)
}
```
### Scrubber
Use the `NumberInput.Scrubber` component to make the number input supports
scrubber interactions.
```tsx
import { InputGroup, NumberInput } from "@chakra-ui/react"
import { LuArrowRightLeft } from "react-icons/lu"
export const NumberInputWithScrubber = () => {
return (
}
>
)
}
```
### Hook Form
Here is an example of how to use the `NumberInput` component with
`react-hook-form`.
```tsx
"use client"
import { Button, Field, NumberInput } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
number: z.string({ message: "Number is required" }),
})
type FormValues = z.infer
export const NumberInputWithHookForm = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Closed Component
Here's how to setup the Number Input for a closed component composition.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add number-input
```
Here's how to use the it
```tsx
```
## Guides
### Why use string values?
When controlling the NumberInput component, use string values instead of
converting to numbers. This preserves locale-specific formatting, especially for
currencies with different decimal and thousands separators (e.g., `1.523,30` vs
`1,523.30`).
```tsx
const [value, setValue] = useState("0")
setValue(details.value)}
>
{/* ... */}
```
If you need a numeric value for form submission, use `NumberInput.Context` to
access `valueAsNumber`:
```tsx
setValue(details.value)}
>
{(context) => (
)}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| allowOverflow | true | `boolean` | Whether to allow the value overflow the min/max range |
| clampValueOnBlur | true | `boolean` | Whether to clamp the value when the input loses focus (blur) |
| focusInputOnChange | true | `boolean` | Whether to focus input when the value changes |
| inputMode | "decimal" | `InputMode` | Hints at the type of data that might be entered by the user. It also determines
the type of keyboard shown to the user on mobile devices |
| locale | "en-US" | `string` | The current locale. Based on the BCP 47 definition. |
| max | Number.MAX_SAFE_INTEGER | `number` | The maximum value of the number input |
| min | Number.MIN_SAFE_INTEGER | `number` | The minimum value of the number input |
| pattern | "-?[0-9]*(.[0-9]+)?" | `string` | The pattern used to check the element's value against |
| spinOnPress | true | `boolean` | Whether to spin the value when the increment/decrement button is pressed |
| step | 1 | `number` | The amount to increment or decrement the value by |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | outline | `'outline' \| 'subtle' \| 'flushed'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| allowMouseWheel | undefined | `boolean` | Whether to allow mouse wheel to change the value |
| defaultValue | undefined | `string` | The initial value of the input when rendered.
Use when you don't need to control the value of the input. |
| disabled | undefined | `boolean` | Whether the number input is disabled. |
| form | undefined | `string` | The associate form of the input element. |
| formatOptions | undefined | `NumberFormatOptions` | The options to pass to the `Intl.NumberFormat` constructor |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n label: string\n input: string\n incrementTrigger: string\n decrementTrigger: string\n scrubber: string\n}>` | The ids of the elements in the number input. Useful for composition. |
| invalid | undefined | `boolean` | Whether the number input value is invalid. |
| name | undefined | `string` | The name attribute of the number input. Useful for form submission. |
| onFocusChange | undefined | `(details: FocusChangeDetails) => void` | Function invoked when the number input is focused |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function invoked when the value changes |
| onValueInvalid | undefined | `(details: ValueInvalidDetails) => void` | Function invoked when the value overflows or underflows the min/max range |
| readOnly | undefined | `boolean` | Whether the number input is readonly |
| required | undefined | `boolean` | Whether the number input is required |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| value | undefined | `string` | The controlled value of the input |
## Explorer
Explore the `NumberInput` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Overlay Manager
## Usage
The `createOverlay` function creates a new overlay component that can be
programmatically controlled.
```tsx
import { createOverlay } from "@chakra-ui/react"
const dialog = createOverlay((props) => {
const { title, description, content, ...rest } = props
return (
{title && (
{title}
)}
{description && (
{description}
)}
{content}
)
})
```
Then render the `Viewport` component to see the overlay.
```tsx
```
## Examples
### Dialog
Here's an example of a dialog component that can be programmatically controlled.
```tsx
"use client"
import { Button, Dialog, Portal, createOverlay } from "@chakra-ui/react"
interface DialogProps {
title: string
description?: string
content?: React.ReactNode
}
const dialog = createOverlay((props) => {
const { title, description, content, ...rest } = props
return (
{title && (
{title}
)}
{description && (
{description}
)}
{content}
)
})
export const OverlayBasic = () => {
return (
<>
>
)
}
```
### Drawer
Here's an example of a drawer component that can be programmatically controlled.
```tsx
"use client"
import { Button, Drawer, Portal, createOverlay } from "@chakra-ui/react"
interface DialogProps {
title: string
description?: string
content?: React.ReactNode
placement?: Drawer.RootProps["placement"]
}
const drawer = createOverlay((props) => {
const { title, description, content, ...rest } = props
return (
{title && (
{title}
)}
{description && (
{description}
)}
{content}
)
})
export const OverlayWithDrawer = () => {
return (
<>
>
)
}
```
### Update
Use the `.update` method to update the props of an overlay.
```tsx
"use client"
import { Box, Button, Dialog, Portal } from "@chakra-ui/react"
import { createOverlay } from "@chakra-ui/react"
interface DialogProps {
title: string
description?: string
content?: React.ReactNode
}
const dialog = createOverlay((props) => {
const { title, description, content, ...rest } = props
return (
{title && (
{title}
)}
{description && (
{description}
)}
{content}
)
})
export const OverlayWithUpdate = () => {
return (
<>
>
)
}
```
### Return Value
Awaiting the result of the `.open()` method returns the value passed to the
`.close()` method.
:::info
**Bonus:** You can also use the `.waitForExit()` method to wait for the exit
animation to complete before opening a new overlay.
:::
```tsx
"use client"
import { Button, Dialog, Portal } from "@chakra-ui/react"
import { createOverlay } from "@chakra-ui/react"
interface DialogProps {
title: string
description: string
content?: React.ReactNode
}
const dialog = createOverlay((props) => {
const { title, description, content, ...rest } = props
return (
{title && (
{title}
)}
{description && (
{description}
)}
{content}
)
})
export const OverlayWithReturnValue = () => {
return (
<>
>
)
}
```
### Programmatic Closing
You can close an overlay from within the component itself by calling the
injected `onOpenChange` prop with `{ open: false }`.
This is useful for scenarios like form submissions or user interactions that
should close the overlay.
```tsx
const dialog = createOverlay((props) => {
const { onOpenChange, ...rest } = props
const handleSubmit = () => {
// Close the overlay after successful action
onOpenChange?.({ open: false })
}
return {/* ... */}
})
```
```tsx
"use client"
import {
Button,
Dialog,
Input,
Portal,
Stack,
createOverlay,
} from "@chakra-ui/react"
import { useState } from "react"
interface ContactFormProps {
title?: string
}
const contactDialog = createOverlay((props) => {
const { title, ...rest } = props
const [name, setName] = useState("")
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
alert(`Hello ${name}!`)
// Close dialog using injected `onOpenChange` prop
props.onOpenChange?.({ open: false })
setName("")
}
return (
{title && (
{title}
)}
)
})
export const OverlayWithForm = () => {
return (
<>
{
contactDialog.open("form", { title: "Simple Form" })
}}
>
Open Form
>
)
}
```
## API
### Props
Props that are injected into the overlay component by the `createOverlay`
function:
- `open`: Whether the overlay is currently open
- `onOpenChange`: Callback fired when the overlay's open state changes
- `onExitComplete`: Callback fired when the overlay's exit animation completes
### Methods
### `Viewport`
The root component that renders all active overlays.
### `open(id, props)`
Opens a new overlay with the given id and props. Returns a promise that resolves
with any value.
### `close(id, value)`
Closes the overlay with the given id and returns a promise that resolves when
closed.
### `update(id, props)`
Updates the props of the overlay with the given id.
### `remove(id)`
Removes the overlay with the given id.
### `removeAll()`
Removes all overlays.
### `get(id)`
Gets the props of the overlay with the given id.
### `getSnapshot()`
Gets the current snapshot of the overlays.
### `waitForExit(id)`
Waits for the exit animation to complete for the overlay with the given id.
# Pagination
```tsx
"use client"
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const PaginationBasic = () => {
return (
(
{page.value}
)}
/>
)
}
```
## Usage
```tsx
import { Pagination } from "@chakra-ui/react"
```
```tsx
```
## Shortcuts
The `Pagination` component also provides a set of shortcuts for common use
cases.
### PaginationItems
This component renders the number of pages based on the `count` and `pageSize`
props.
Rendering this:
```tsx
```
is shorthand for this:
```tsx
{({ pages }) =>
pages.map((page, index) =>
page.type === "page" ? (
) : (
),
)
}
```
## Examples
### Sizes
Use the `size` prop to change the size of the pagination.
:::info
The pagination sizes are mapped to the `Button` component sizes.
:::
```tsx
"use client"
import {
ButtonGroup,
For,
IconButton,
Pagination,
Stack,
} from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const PaginationWithSizes = () => {
return (
{(size) => (
(
{page.value}
)}
/>
)}
)
}
```
### Variants
Use the `variant` prop to control the variant of the pagination items and
ellipsis.
> The variant matches the `Button` component variant.
```tsx
"use client"
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const PaginationWithVariants = () => {
return (
(
{page.value}
)}
/>
)
}
```
### Controlled
Use the `page` and `onPageChange` props to control the current page.
```tsx
"use client"
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { useState } from "react"
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"
export const PaginationControlled = () => {
const [page, setPage] = useState(1)
return (
setPage(e.page)}
>
(
{page.value}
)}
/>
)
}
```
### Sibling Count
Use `siblingCount` to control the number of sibling pages to show before and
after the current page.
```tsx
"use client"
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const PaginationWithSiblingCount = () => {
return (
(
{page.value}
)}
/>
)
}
```
### Compact
Use the `Pagination.PageText` to create a compact pagination. This can be useful
for mobile views.
```tsx
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"
export const PaginationCompact = () => {
return (
)
}
```
### As Link
Here's an example of rendering the pagination as links.
```tsx
"use client"
import {
ButtonGroup,
IconButton,
type IconButtonProps,
Pagination,
usePaginationContext,
} from "@chakra-ui/react"
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"
const PaginationLink = (
props: IconButtonProps & { page?: "prev" | "next" | number },
) => {
const { page, ...rest } = props
const pagination = usePaginationContext()
const pageValue = () => {
if (page === "prev") return pagination.previousPage
if (page === "next") return pagination.nextPage
return page
}
return (
{props.children}
)
}
export const PaginationAsLink = () => {
return (
(
{page.value}
)}
/>
)
}
```
### Attached
Here's an example of composing the pagination with the `Group` component to
attach the pagination items and triggers.
```tsx
"use client"
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"
export const PaginationAttached = () => {
return (
(
{page.value}
)}
/>
)
}
```
### Count Text
Pass `format="long"` to the `Pagination.PageText` component to show the count
text.
```tsx
import { ButtonGroup, IconButton, Pagination } from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const PaginationWithCountText = () => {
return (
)
}
```
### Data Driven
Here's an example of controlling the pagination state and using the state to
chunk the data.
```tsx
"use client"
import {
ButtonGroup,
IconButton,
Pagination,
Stack,
Text,
} from "@chakra-ui/react"
import { useState } from "react"
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"
const pageSize = 5
const count = 50
const items = new Array(count)
.fill(0)
.map((_, index) => `Lorem ipsum dolor sit amet ${index + 1}`)
export const PaginationWithContent = () => {
const [page, setPage] = useState(1)
const startRange = (page - 1) * pageSize
const endRange = startRange + pageSize
const visibleItems = items.slice(startRange, endRange)
return (
{visibleItems.map((item) => (
{item}
))}
setPage(e.page)}
>
(
{page.value}
)}
/>
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| defaultPage | 1 | `number` | The initial active page when rendered.
Use when you don't need to control the active page of the pagination. |
| defaultPageSize | 10 | `number` | The initial number of data items per page when rendered.
Use when you don't need to control the page size of the pagination. |
| siblingCount | 1 | `number` | Number of pages to show beside active page |
| type | "button" | `'button' \| 'link'` | The type of the trigger element |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| count | undefined | `number` | Total number of data items |
| ids | undefined | `Partial<{\n root: string\n ellipsis: (index: number) => string\n prevTrigger: string\n nextTrigger: string\n item: (page: number) => string\n}>` | The ids of the elements in the accordion. Useful for composition. |
| onPageChange | undefined | `(details: PageChangeDetails) => void` | Called when the page number is changed |
| onPageSizeChange | undefined | `(details: PageSizeChangeDetails) => void` | Called when the page size is changed |
| page | undefined | `number` | The controlled active page |
| pageSize | undefined | `number` | The controlled number of data items per page |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
# Password Input
```tsx
import { PasswordInput } from "@/components/ui/password-input"
export const PasswordInputBasic = () => {
return
}
```
## Setup
If you don't already have the snippet, run the following command to add the
`password-input` snippet
```sh
npx @chakra-ui/cli snippet add password-input
```
The snippet includes a closed component composition for the `PasswordInput`
component.
## Usage
```jsx
import {
PasswordInput,
PasswordStrengthMeter,
} from "@/components/ui/password-input"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the password input.
:::info
The password input sizes are mapped to the `Input` component sizes.
:::
```tsx
import { Stack } from "@chakra-ui/react"
import { PasswordInput } from "@/components/ui/password-input"
export const PasswordInputWithSizes = () => {
return (
)
}
```
### Controlled
Use the `value` and `onChange` props to control the current page.
```tsx
"use client"
import { PasswordInput } from "@/components/ui/password-input"
import { useState } from "react"
export const PasswordInputControlled = () => {
const [value, setValue] = useState("")
return (
setValue(e.target.value)} />
)
}
```
### Hook Form
Here's an example of how to use the `PasswordInput` component with
`react-hook-form`.
```tsx
"use client"
import { Button, Field, Input, Stack } from "@chakra-ui/react"
import { PasswordInput } from "@/components/ui/password-input"
import { useForm } from "react-hook-form"
interface FormValues {
username: string
password: string
}
export const PasswordInputWithHookForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm()
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Controlled Visibility
Use the `visible` and `onVisibleChange` props to control the visibility of the
password input.
```tsx
"use client"
import { Stack, Text } from "@chakra-ui/react"
import { PasswordInput } from "@/components/ui/password-input"
import { useState } from "react"
export const PasswordInputControlledVisibility = () => {
const [visible, setVisible] = useState(false)
return (
Password is {visible ? "visible" : "hidden"}
)
}
```
### Strength Indicator
Render the `PasswordStrengthMeter` component to show the strength of the
password. Compute the `value` prop based on the password input `value`.
```tsx
"use client"
import { Stack } from "@chakra-ui/react"
import { type Options, passwordStrength } from "check-password-strength"
import {
PasswordInput,
PasswordStrengthMeter,
} from "@/components/ui/password-input"
import { useMemo, useState } from "react"
const strengthOptions: Options = [
{ id: 1, value: "weak", minDiversity: 0, minLength: 0 },
{ id: 2, value: "medium", minDiversity: 2, minLength: 6 },
{ id: 3, value: "strong", minDiversity: 3, minLength: 8 },
{ id: 4, value: "very-strong", minDiversity: 4, minLength: 10 },
]
export const PasswordInputWithStrengthIndicator = () => {
const [password, setPassword] = useState("")
const strength = useMemo(() => {
if (!password) return 0
const result = passwordStrength(password, strengthOptions)
return result.id
}, [password])
return (
setPassword(e.currentTarget.value)}
placeholder="Enter your password"
/>
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| defaultVisible | false | `boolean` | The default visibility state of the password input. |
| visible | undefined | `boolean` | The controlled visibility state of the password input. |
| onVisibleChange | undefined | `(visible: boolean) => void` | Callback invoked when the visibility state changes. |
| visibilityIcon | undefined | `{ on: React.ReactNode; off: React.ReactNode }` | Custom icons for the visibility toggle button. |
# Pin Input
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputBasic = () => {
return (
)
}
```
## Usage
```tsx
import { PinInput } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Sizes
Pass the `size` prop to the `PinInput.Root` component to change the size of the
pin input component
```tsx
import { For, PinInput, Stack } from "@chakra-ui/react"
export const PinInputWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### One time code
Pass the `otp` prop to the `PinInput.Root` component to make the pin input
component behave like a one-time code input. This helps improve the user
experience when entering OTP codes
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputWithOtp = () => {
return (
)
}
```
### Mask
Pass the `mask` prop to the `PinInput.Root` component to obscure the entered pin
code
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputWithMask = () => {
return (
)
}
```
### Placeholder
Pass the `placeholder` prop to the `PinInPut.Root` component to add a
placeholder to the pin input
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputWithPlaceholder = () => {
return (
)
}
```
### Field
Here's an example of how to compose the `Field` and the `PinInput` components
```tsx
import { Field, PinInput } from "@chakra-ui/react"
export const PinInputWithField = () => {
return (
Enter otp
)
}
```
### Hook Form
Here's an example of how to compose the `Field` and the `PinInput` components
with `react-hook-form`
```tsx
"use client"
import { Button, Field, PinInput, Stack } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
pin: z
.array(z.string().min(1))
.min(1, { message: "Pin is required" })
.length(4, { message: "Pin must be 4 digits long" }),
})
type FormValues = z.infer
export const PinInputWithHookForm = () => {
const { handleSubmit, control, formState } = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Controlled
Pass the `value` and `onValueChange` props to the `PinInPut.Root` component to
control the value of the pin input
```tsx
"use client"
import { PinInput } from "@chakra-ui/react"
import { useState } from "react"
export const PinInputControlled = () => {
const [value, setValue] = useState(["", "", "", ""])
return (
setValue(e.value)}>
)
}
```
### Store
An alternative way to control the pin input is to use the `RootProvider`
component and the `usePinInput` store hook.
This way you can access the pin input state and methods from outside the
component.
```tsx
"use client"
import {
Button,
ButtonGroup,
PinInput,
Stack,
usePinInput,
} from "@chakra-ui/react"
export const PinInputWithStore = () => {
const store = usePinInput()
return (
store.setValue(["1", "2", "3", "4"])}>
Set value
store.clearValue()}>Clear value
)
}
```
### Attached
Pass the `attached` prop to the `PinInput.Root` component to attach the pin
input to the input field
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputAttached = () => {
return (
)
}
```
### Alphanumeric
Pass the `type` prop to the `PinInput.Root` component to allow the user to enter
alphanumeric characters. Values can be either `alphanumeric`, `numeric`, or
`alphabetic`
```tsx
import { PinInput } from "@chakra-ui/react"
export const PinInputAlphanumeric = () => {
return (
)
}
```
### Closed Component
Here's how to setup the Pin input for a closed component composition.
#### Usage
```tsx
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| placeholder | "○" | `string` | The placeholder text for the input |
| type | "numeric" | `'numeric' \| 'alphabetic' \| 'alphanumeric'` | The type of value the pin-input should allow |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` | The size of the component |
| variant | outline | `'outline' \| 'subtle' \| 'flushed'` | The variant of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| autoFocus | undefined | `boolean` | Whether to auto-focus the first input. |
| blurOnComplete | undefined | `boolean` | Whether to blur the input when the value is complete |
| count | undefined | `number` | The number of inputs to render to improve SSR aria attributes.
This will be required in next major version. |
| defaultValue | undefined | `string[]` | The initial value of the the pin input when rendered.
Use when you don't need to control the value of the pin input. |
| disabled | undefined | `boolean` | Whether the inputs are disabled |
| form | undefined | `string` | The associate form of the underlying input element. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n hiddenInput: string\n label: string\n control: string\n input: (id: string) => string\n}>` | The ids of the elements in the pin input. Useful for composition. |
| invalid | undefined | `boolean` | Whether the pin input is in the invalid state |
| mask | undefined | `boolean` | If `true`, the input's value will be masked just like `type=password` |
| name | undefined | `string` | The name of the input element. Useful for form submission. |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function called on input change |
| onValueComplete | undefined | `(details: ValueChangeDetails) => void` | Function called when all inputs have valid values |
| onValueInvalid | undefined | `(details: ValueInvalidDetails) => void` | Function called when an invalid value is entered |
| otp | undefined | `boolean` | If `true`, the pin input component signals to its fields that they should
use `autocomplete="one-time-code"`. |
| pattern | undefined | `string` | The regular expression that the user-entered input value is checked against. |
| readOnly | undefined | `boolean` | Whether the pin input is in the valid state |
| required | undefined | `boolean` | Whether the pin input is required |
| selectOnFocus | undefined | `boolean` | Whether to select input value when input is focused |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| value | undefined | `string[]` | The controlled value of the the pin input. |
| attached | undefined | `'true' \| 'false'` | The attached of the component |
## Explorer
Explore the `Pin Input` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Popover
```tsx
import { Button, Input, Popover, Portal, Text } from "@chakra-ui/react"
export const PopoverBasic = () => {
return (
Click me
Naruto Form
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
)
}
```
## Usage
```tsx
import { Popover } from "@chakra-ui/react"
```
```tsx
```
## Shortcuts
The `Popover` provides a shortcuts for common use cases.
### Arrow
The `Popover.Arrow` renders the `Popover.ArrowTip` component within in by
default.
This works:
```jsx
```
This might be more concise, if you don't need to customize the arrow tip.
```jsx
```
## Examples
### Controlled
Use the `open` and `onOpenChange` to control the visibility of the popover.
```tsx
"use client"
import { Button, Popover, Portal } from "@chakra-ui/react"
import { useState } from "react"
export const PopoverControlled = () => {
const [open, setOpen] = useState(false)
return (
setOpen(e.open)}>
Click me
This is a popover with the same width as the trigger button
)
}
```
### Sizes
Use the `size` prop to change the size of the popover component.
```tsx
import {
Button,
For,
Input,
Popover,
Portal,
Stack,
Text,
} from "@chakra-ui/react"
export const PopoverWithSizes = () => {
return (
{(size) => (
Click me
Naruto Form
Naruto is a Japanese manga series written and illustrated
by Masashi Kishimoto.
)}
)
}
```
### Lazy Mount
Use the `lazyMounted` and/or `unmountOnExit` prop to defer the mounting of the
popover content until it's opened.
```tsx
import { Button, Popover, Portal, Text } from "@chakra-ui/react"
export const PopoverLazyMounted = () => {
return (
Click me
Naruto Form
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
)
}
```
### Placement
Use the `positioning.placement` prop to configure the underlying `floating-ui`
positioning logic.
```tsx
import { Button, Popover, Portal } from "@chakra-ui/react"
export const PopoverWithPlacement = () => {
return (
Click me
Some content
)
}
```
### Offset
Use the `positioning.offset` prop to adjust the position of the popover content.
```tsx
import { Button, Popover, Portal } from "@chakra-ui/react"
export const PopoverWithOffset = () => {
return (
Open
This popover has a custom offset from its trigger
)
}
```
### Same Width
Use the `positioning.sameWidth` prop to make the popover content the same width
as the trigger.
```tsx
import { Button, Popover, Portal } from "@chakra-ui/react"
export const PopoverWithSameWidth = () => {
return (
Click me
This is a popover with the same width as the trigger button
)
}
```
### Nested Popover
When nesting floating elements like popover, select, menu, inside of the
popover, avoid portalling them to the document's body.
```diff
-
{/* ... */}
-
```
```tsx
import { Button, Popover, Portal, Text } from "@chakra-ui/react"
export const PopoverNested = () => {
return (
Click me
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
Open Nested Popover
Some nested popover content
)
}
```
### Initial Focus
Use the `initialFocusEl` prop to set the initial focus of the popover content.
```tsx
"use client"
import { Box, Button, Group, Popover, Portal } from "@chakra-ui/react"
import { useRef } from "react"
export const PopoverWithInitialFocus = () => {
const ref = useRef(null)
return (
ref.current}>
Click me
Manage Your Channels
This is a popover with the same width as the trigger button
Step 2 of 4
Prev
Next
)
}
```
### Form
Here's an example of a popover with a form inside.
```tsx
import {
Button,
Field,
Input,
Popover,
Portal,
Stack,
Textarea,
} from "@chakra-ui/react"
export const PopoverWithForm = () => {
return (
Click me
WidthHeightComments
)
}
```
### Custom Background
Use the `--popover-bg` CSS variable to change the background color of the
popover content and its arrow.
```tsx
import { Button, Input, Popover, Portal, Text } from "@chakra-ui/react"
export const PopoverWithCustomBg = () => {
return (
Click me
Naruto Form
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
)
}
```
### Within Dialog
To use the `Popover` within a `Dialog`, you need to avoid portalling the
`Popover.Positioner` to the document's body.
```diff
-
{/* ... */}
-
```
If you have set `scrollBehavior="inside"` on the `Dialog`, you need to:
- Set the popover positioning to `fixed` to avoid the popover from being clipped
by the dialog.
- Set `hideWhenDetached` to `true` to hide the popover when the trigger is
scrolled out of view.
```tsx
{/* ... */}
```
```tsx
"use client"
import {
Button,
CloseButton,
Dialog,
Popover,
Portal,
Text,
} from "@chakra-ui/react"
export const PopoverInDialog = () => {
return (
Open DialogPopover in Dialog
)
}
function DialogPopover() {
return (
Click me
Naruto Form
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| autoFocus | true | `boolean` | Whether to automatically set focus on the first focusable
content within the popover when opened. |
| closeOnEscape | true | `boolean` | Whether to close the popover when the escape key is pressed. |
| closeOnInteractOutside | true | `boolean` | Whether to close the popover when the user clicks outside of the popover. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| modal | false | `boolean` | Whether the popover should be modal. When set to `true`:
- interaction with outside elements will be disabled
- only popover content will be visible to screen readers
- scrolling is blocked
- focus is trapped within the popover |
| portalled | true | `boolean` | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position
of the popover content. |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| unmountOnExit | false | `boolean` | Whether to unmount on exit. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| as | undefined | `React.ElementType` | The underlying element to render. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
| defaultOpen | undefined | `boolean` | The initial open state of the popover when rendered.
Use when you don't need to control the open state of the popover. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n anchor: string\n trigger: string\n content: string\n title: string\n description: string\n closeTrigger: string\n positioner: string\n arrow: string\n}>` | The ids of the elements in the popover. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| initialFocusEl | undefined | `() => HTMLElement \| null` | The element to focus on when the popover is opened. |
| onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed |
| onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function invoked when the popover opens or closes |
| onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component |
| open | undefined | `boolean` | The controlled open state of the popover |
| persistentElements | undefined | `(() => Element \| null)[]` | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| positioning | undefined | `PositioningOptions` | The user provided options used to position the popover content |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
## Explorer
Explore the `Popover` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Portal
## Usage
The `Portal` uses the `ReactDOM.createPortal` API to render an element at the
end of `document.body` or specific container.
```jsx
import { Portal } from "@chakra-ui/react"
```
```jsx