` | undefined |
| disabled | undefined | `boolean` | undefined |
# Presence
```tsx
"use client"
import {
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceFade = () => {
const { open, onToggle } = useDisclosure()
return (
Fade
)
}
```
## Usage
```jsx
import { Presence } from "@chakra-ui/react"
```
```jsx
Presence content
```
Think of `Presence` like the `AnimatePresence` component from Framer Motion,
except that it's built for CSS animations instead.
The key things to note:
- the `present` prop is a boolean that controls the presence state of the
component.
- the `_open` condition is used to style the open state.
- the `_closed` condition is used to style the closed state.
## Examples
### Fade
Setting the animation name to `fade-in` and `fade-out`, the component will
animate the entry and exit of the element.
```tsx
"use client"
import {
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceFade = () => {
const { open, onToggle } = useDisclosure()
return (
Fade
)
}
```
### Scale Fade
Using the animation styles `scale-fade-in` and `scale-fade-out`, the component
will animate the entry and exit of the element.
```tsx
"use client"
import {
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceScaleFade = () => {
const { open, onToggle } = useDisclosure()
return (
Scale Fade
)
}
```
### Slide Fade
Here's an example that uses the animation names `slide-from-bottom` and
`slide-to-bottom` to animate the entry and exit of the element.
```tsx
"use client"
import {
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceSlideFade = () => {
const { open, onToggle } = useDisclosure()
return (
Slide Fade
)
}
```
### Slide
Here's an example that uses the animation names `slide-from-bottom-full` and
`slide-to-bottom-full` to animate the entry and exit of the element.
```tsx
"use client"
import {
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceSlide = () => {
const { open, onToggle } = useDisclosure()
return (
Slide
)
}
```
### Lazy Mount
Use the `lazyMount` prop to delay the mount of the component until it's present.
```tsx
"use client"
import {
Alert,
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceLazyMount = () => {
const { open, onToggle } = useDisclosure()
return (
Check the DOM to see that the element not mounted initially
Fade
)
}
```
### Unmount On Exit
Use the `unmountOnExit` prop to unmount the component when it's not present.
```tsx
"use client"
import {
Alert,
Button,
Center,
Presence,
Stack,
useDisclosure,
} from "@chakra-ui/react"
export const PresenceUnmountOnExit = () => {
const { open, onToggle } = useDisclosure()
return (
Check the DOM to see that the element is removed when not present.
Fade
)
}
```
# Progress Circle
```tsx
import { ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleBasic = () => {
return (
)
}
```
## Usage
```tsx
import { ProgressCircle } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Rounded
Use the `strokeLinecap` prop on `ProgressCircle.Range` to make the ends of the
progress circle rounded.
```tsx
import { ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleWithRoundCap = () => {
return (
)
}
```
### Sizes
Use the `size` prop to change the size of the progress circle component.
```tsx
import { For, HStack, ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Colors
Use the `colorPalette` prop to change the color scheme of the component.
```tsx
import { HStack, ProgressCircle, Stack, Text } from "@chakra-ui/react"
export const ProgressCircleWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Value Text
Render the `ProgressCircle.ValueText` component to display the progress value.
```tsx
import { AbsoluteCenter, For, HStack, ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleWithValueText = () => {
return (
{(size) => (
)}
)
}
```
### Custom Thickness
Pass the `--thickness` css variable to the `ProgressCircleRing` component to
change the thickness of the ring.
```tsx
import { ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleWithThickness = () => {
return (
)
}
```
### Indeterminate
Set the `value` prop to `null` to render the indeterminate state.
```tsx
import { ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleIndeterminate = () => {
return (
)
}
```
### Color
Pass the `stroke` prop to the `ProgressCircle.Range` component to change the
color of the range.
```tsx
import { ProgressCircle } from "@chakra-ui/react"
export const ProgressCircleWithRangeColor = () => {
return (
)
}
```
### Closed Component
Here's how to create a closed component using the `ProgressCircle` component.
## 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 | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | 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. |
# Progress
```tsx
import { Progress } from "@chakra-ui/react"
export const ProgressBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Progress } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the progress bar.
```tsx
import { For, Progress, Stack } from "@chakra-ui/react"
export const ProgressWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Variants
Use the `variant` prop to change the visual style of the progress bar.
```tsx
import { Progress, Stack } from "@chakra-ui/react"
export const ProgressWithVariants = () => {
return (
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the progress bar.
```tsx
import { Progress, Stack, Text } from "@chakra-ui/react"
export const ProgressWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Inline Label
Compose the `Progress.Label` and `Progress.ValueText` components to create an
inline label for the progress bar.
```tsx
import { HStack, Progress } from "@chakra-ui/react"
export const ProgressWithInlineLabel = () => {
return (
Usage
40%
)
}
```
### Info tip
Use the `info` prop to add a tooltip to the progress bar.
```tsx
import { Progress } from "@chakra-ui/react"
import { InfoTip } from "@/components/ui/toggle-tip"
export const ProgressWithLabelInfo = () => {
return (
Uploading
Uploading document to the server
)
}
```
### Indeterminate
Set the value to `null` to show an indeterminate progress bar.
```tsx
import { Progress } from "@chakra-ui/react"
export const ProgressIndeterminate = () => {
return (
)
}
```
### Stripes
Set the `striped` prop to `true` to add stripes to the progress bar.
```tsx
import { Progress } from "@chakra-ui/react"
export const ProgressWithStripes = () => {
return (
)
}
```
### Animated Stripes
Set the `animated` prop to `true` to animate the stripes.
```tsx
import { Progress } from "@chakra-ui/react"
export const ProgressWithAnimatedStripes = () => {
return (
)
}
```
### Closed Component
Here's how to create a closed component using the `Progress` component.
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| defaultValue | 50 | `number` | The initial value of the progress bar when rendered.
Use when you don't need to control the value of the progress bar. |
| formatOptions | { style: "percent" } | `NumberFormatOptions` | The options to use for formatting the value. |
| locale | "en-US" | `string` | The locale to use for formatting the value. |
| max | 100 | `number` | The maximum allowed value of the progress bar. |
| min | 0 | `number` | The minimum allowed value of the progress bar. |
| orientation | "horizontal" | `'horizontal' \| 'vertical'` | The orientation of the element. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | outline | `'outline' \| 'subtle'` | The variant of the component |
| shape | rounded | `'square' \| 'rounded' \| 'full'` | The shape of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | 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. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; track: string; label: string; circle: string }>` | The ids of the elements in the progress bar. Useful for composition. |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Callback fired when the value changes. |
| translations | undefined | `IntlTranslations` | The localized messages to use. |
| value | undefined | `number` | The controlled value of the progress bar. |
| striped | undefined | `'true' \| 'false'` | The striped of the component |
| animated | undefined | `'true' \| 'false'` | The animated of the component |
## Explorer
Explore the `Progress` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Prose
```tsx
import { Prose } from "@/components/ui/prose"
// Used for syntax highlighting
const html = String.raw
const content = html`
Title Heading 1
Title Heading 2
Title Heading 3
Title Heading 4
Title Heading 4 testing
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at dolor nec
ex rutrum semper. Praesent ultricies purus eget lectus tristique egestas ac
in lacus. Nulla eleifend lorem risus, sit amet dictum nisi gravida eget.
Suspendisse odio sem, scelerisque congue luctus nec, scelerisque ultrices
orci. Praesent tincidunt, risus ut commodo cursus, ligula orci tristique
justo, vitae sollicitudin lacus risus dictum orci. Press Ctrl +
C to copy
Vivamus vel enim at lorem ultricies faucibus. Cras vitae ipsum ut quam
varius dignissim a ac tellus. Aliquam maximus mauris eget tincidunt
interdum. Fusce vitae massa non risus congue tincidunt. Pellentesque maximus
elit quis eros lobortis dictum.
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at
consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
Pellentesque dapibus justo dui, quis egestas sapien porttitor in.
`
export const ProseBasic = () => {
return
}
```
## Setup
If you don't already have the snippet, run the following command to add the
`prose` snippet
```sh
npx @chakra-ui/cli snippet add prose
```
## Usage
```jsx
import { Prose } from "@/components/ui/prose"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the `Prose` component
```tsx
import { For, Stack, Text } from "@chakra-ui/react"
import { Prose } from "@/components/ui/prose"
export const ProseWithSizes = () => {
return (
{(size) => (
size: {size}
Title Heading 1
Title Heading 2
Title Heading 3
Title Heading 4
Title Heading 4 testing
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
at dolor nec ex rutrum semper. Praesent ultricies purus eget
lectus tristique egestas ac in lacus. Nulla eleifend lorem
risus, sit amet dictum nisi gravida eget. Suspendisse odio sem,
scelerisque congue luctus nec, scelerisque ultrices orci.
Praesent tincidunt, risus ut commodo cursus, ligula orci
tristique justo, vitae sollicitudin lacus risus dictum orci.
Press Ctrl +C to copy
)}
)
}
```
### Blockquote
Blockquote elements are styled to match the design language of the `Blockquote`
component.
```tsx
import { Prose } from "@/components/ui/prose"
// Used for syntax highlighting
const html = String.raw
const content = html`
Blockquotes
This is a good looking blockquote!
And it can span into multiple lines:
Fusce placerat ipsum vel sollicitudin imperdiet. Morbi vulputate non diam at
consequat. Donec vitae sem eu arcu auctor scelerisque vel in turpis.
Pellentesque dapibus justo dui, quis egestas sapien porttitor in.
There's also strong, b, em support as
well! But, let's display some code!
`
export const ProseWithBlockquote = () => {
return
}
```
### List
List elements are styled to match the design language of the `List` component.
```tsx
import { Prose } from "@/components/ui/prose"
// Used for syntax highlighting
const html = String.raw
const content = html`
Lists
Let's look at some unordered lists. Things to buy:
- Milk
- Eggs
- Bread
- Chakra UI Pro license
And some ordered lists. Things to do:
- Pay the bills
- Walk the dog
- Take out trash
`
export const ProseWithList = () => {
return
}
```
### React Markdown
Here's an example of using the `react-markdown` library to render markdown
content.
```tsx
import { Prose } from "@/components/ui/prose"
import Markdown from "react-markdown"
export const ProseWithReactMarkdown = () => {
return (
{`
## Heading
Based on your Chakra package. So [click here](http://chakra-ui.com) to confirm your plan.
- first item
- second item
- second item
- second item
[title](http://chakra-ui.com)
`}
)
}
```
### Table
The table elements are styled to match the design language of the `Table`
component.
```tsx
import { Prose } from "@/components/ui/prose"
// Used for syntax highlighting
const html = String.raw
const content = html`
Tables
| Name |
Role |
GitHub Profile |
| Segun |
Creator |
segunadebayo |
| Chris |
Ark Wizard |
grizzlycodes |
| Abraham |
Trouble maker |
anubra266 |
| Esther |
Developer Advocate |
estheragbaje |
`
export const ProseWithTable = () => {
return
}
```
# QR Code
```tsx
import { QrCode } from "@chakra-ui/react"
export const QrCodeBasic = () => {
return (
)
}
```
## Usage
```tsx
import { QrCode } 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 QR code.
```tsx
import { For, QrCode, Stack } from "@chakra-ui/react"
export const QrCodeWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Logo Overlay
Pass the children prop to the `QrCode.Overlay` component to add a logo or
overlay to the QR code.
```tsx
import { QrCode } from "@chakra-ui/react"
export const QrCodeWithOverlay = () => {
return (
)
}
const Logo = () => {
return (
)
}
```
### Fill
Use the `fill` prop to set the fill color of the QR code.
```tsx
import { Flex, For, QrCode } from "@chakra-ui/react"
export const QrCodeWithFill = () => {
return (
{(fill) => (
)}
)
}
```
### Download
Use the `QrCode.DownloadTrigger` to download the QR code.
> The `fileName` and the `mimeType` props are required.
```tsx
import { Button, QrCode } from "@chakra-ui/react"
export const QrCodeWithExport = () => {
return (
)
}
```
### Error Correction
In cases where the link is too long or the logo overlay covers a significant
area, the error correction level can be increased.
Use the `encoding.ecc` or `encoding.boostEcc` property to set the error
correction level:
- `L`: Allows recovery of up to 7% data loss (default)
- `M`: Allows recovery of up to 15% data loss
- `Q`: Allows recovery of up to 25% data loss
- `H`: Allows recovery of up to 30% data loss
```tsx
"use client"
import { QrCode, SegmentGroup, Stack } from "@chakra-ui/react"
import { useState } from "react"
type ErrorLevel = "L" | "M" | "Q" | "H"
export const QrCodeWithErrorLevel = () => {
const [errorLevel, setErrorLevel] = useState("L")
return (
setErrorLevel(e.value as ErrorLevel)}
>
)
}
```
### Store
The `RootProvider` component provides a context for the QR code.
It accepts the value of the `useQrCode` hook. You can leverage it to access the
component state and methods from outside the QR code.
```tsx
"use client"
import { Button, QrCode, Stack, useQrCode } from "@chakra-ui/react"
export const QrCodeWithStore = () => {
const qrCode = useQrCode({ defaultValue: "https://www.google.com" })
return (
)
}
```
### Input
Here's an example of how to use the `QrCode` component with an `Input`
component.
```tsx
"use client"
import { Input, QrCode, Stack } from "@chakra-ui/react"
import { useState } from "react"
export const QrCodeWithInput = () => {
const [value, setValue] = useState("https://www.google.com")
return (
setValue(e.target.value)} />
)
}
```
### Spinner
Here's an example of how to use the `QrCode` component with a `Spinner`
component.
```tsx
import { AbsoluteCenter, Box, QrCode, Spinner } from "@chakra-ui/react"
export const QrCodeWithSpinner = () => {
return (
)
}
```
### Closed Component
Here's how to setup the QR code 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 qr-code
```
## 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 | `'2xs' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| 'full'` | 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 to encode when rendered.
Use when you don't need to control the value of the qr code. |
| encoding | undefined | `QrCodeGenerateOptions` | The qr code encoding options. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; frame: string }>` | The element ids. |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Callback fired when the value changes. |
| pixelSize | undefined | `number` | The pixel size of the qr code. |
| value | undefined | `string` | The controlled value to encode. |
### DownloadTrigger
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| fileName | undefined | `string` | The name of the file. |
| mimeType | undefined | `DataUrlType` | The mime type of the image. |
| asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. |
| quality | undefined | `number` | The quality of the image. |
## Explorer
Explore the `QR Code` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Radio Card
```tsx
import { HStack, RadioCard } from "@chakra-ui/react"
export const RadioCardBasic = () => {
return (
Select framework
{items.map((item) => (
{item.title}
))}
)
}
const items = [
{ value: "next", title: "Next.js" },
{ value: "vite", title: "Vite" },
{ value: "astro", title: "Astro" },
]
```
## Usage
```tsx
import { RadioCard } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Description
Here's an example of how to add some further description to the radio card.
```tsx
import { HStack, RadioCard } from "@chakra-ui/react"
export const RadioCardWithDescription = () => {
return (
Select framework
{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 `RadioCard.Root` component to change the size of the
radio card.
```tsx
import { For, HStack, RadioCard, Stack } from "@chakra-ui/react"
export const RadioCardWithSizes = () => {
return (
{(size) => (
size = ({size})
{items.map((item) => (
{item.title}
))}
)}
)
}
const items = [
{ value: "next", title: "Next.js" },
{ value: "vite", title: "Vite" },
]
```
### Colors
Pass the `colorPalette` prop to the `RadioCard.Root` component to change the
color of the radio card.
```tsx
import { For, HStack, RadioCard, Stack } from "@chakra-ui/react"
export const RadioCardWithColors = () => {
return (
{(colorPalette) => (
Select Framework
{items.map((item) => (
{item.title}
))}
)}
)
}
const items = [
{ value: "next", title: "Next.js" },
{ value: "vite", title: "Vite" },
]
```
### Variants
Pass the `variant` prop to the `RadioCard.Root` component to change the visual
style of the radio card.
```tsx
import { For, HStack, RadioCard, Stack } from "@chakra-ui/react"
export const RadioCardWithVariants = () => {
return (
{(variant) => (
variant = ({variant})
{items.map((item) => (
{item.title}
))}
)}
)
}
const items = [
{ value: "next", title: "Next.js" },
{ value: "vite", title: "Vite" },
]
```
### Icon
Render a custom icon inside the radio card by placing it within
`RadioCard.ItemContent`.
```tsx
import { HStack, Icon, RadioCard } from "@chakra-ui/react"
import { LuArrowRight, LuCircleOff, LuLock } from "react-icons/lu"
export const RadioCardWithIcon = () => {
return (
Select permission
{items.map((item) => (
{item.icon}
{item.title}
{item.description}
))}
)
}
const items = [
{
icon: ,
value: "allow",
title: "Allow",
description: "This user can access the system",
},
{
icon: ,
value: "deny",
title: "Deny",
description: "This user will be denied access to the system",
},
{
icon: ,
value: "lock",
title: "Lock",
description: "This user will be locked out of the system",
},
]
```
### Controlled
Pass the `value` and `onValueChange` props to the RadioCard.Root component to
control the selected radio card.
```tsx
"use client"
import { HStack, RadioCard } from "@chakra-ui/react"
import { useState } from "react"
export const RadioCardControlled = () => {
const [value, setValue] = useState("next")
return (
setValue(e.value)}>
Select framework
{items.map((item) => (
{item.title}
))}
)
}
const items = [
{ value: "next", title: "Next.js" },
{ value: "vite", title: "Vite" },
{ value: "astro", title: "Astro" },
]
```
### No Indicator
Here's an example of how to use the radio card without an indicator.
```tsx
import { HStack, Icon, RadioCard } from "@chakra-ui/react"
import { RiAppleFill, RiBankCardFill, RiPaypalFill } from "react-icons/ri"
export const RadioCardWithoutIndicator = () => {
return (
Payment method
{items.map((item) => (
{item.icon}
{item.title}
))}
)
}
const items = [
{ value: "paypal", title: "Paypal", icon: },
{ value: "apple-pay", title: "Apple Pay", icon: },
{ value: "card", title: "Card", icon: },
]
```
### No Indicator (Vertical)
Here's an example of a radio card with no indicator and content aligned
vertically.
```tsx
import { HStack, Icon, RadioCard } from "@chakra-ui/react"
import { RiAppleFill, RiBankCardFill, RiPaypalFill } from "react-icons/ri"
export const RadioCardWithoutIndicatorVertical = () => {
return (
Payment method
{items.map((item) => (
{item.icon}
{item.title}
))}
)
}
const items = [
{ value: "paypal", title: "Paypal", icon: },
{ value: "apple-pay", title: "Apple Pay", icon: },
{ value: "card", title: "Card", icon: },
]
```
### Centered
Here's an example of a radio card with centered text.
```tsx
import { HStack, Icon, RadioCard } from "@chakra-ui/react"
import { LuClock, LuDollarSign, LuTrendingUp } from "react-icons/lu"
export const RadioCardCentered = () => {
return (
Select contract type
{items.map((item) => (
{item.icon}
{item.title}
))}
)
}
const items = [
{ icon: , value: "fixed", title: "Fixed Rate" },
{ icon: , value: "milestone", title: "Milestone" },
{ icon: , value: "hourly", title: "Hourly" },
]
```
### Composition
Here's an example of composing the RadioCard with the `Group` component.
```tsx
import { Group, RadioCard } from "@chakra-ui/react"
export const RadioCardComposition = () => {
return (
How well do you know React?
{items.map((item) => (
{item.title}
{item.description}
))}
)
}
const items = [
{
value: "advanced",
title: "Advanced",
description: "I love complex things",
},
{
value: "professional",
title: "Professional",
description: "I can hack simple things",
},
{
value: "beginner",
title: "Beginner",
description: "I don't write code",
},
]
```
### Addon
Use the `RadioCard.ItemAddon` component to add metadata to the radio card.
```tsx
import { HStack, RadioCard } from "@chakra-ui/react"
export const RadioCardWithAddon = () => {
return (
Select framework
{items.map((item) => (
{item.title}
{item.description}
Some addon text
))}
)
}
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" },
]
```
### Closed Component
Here's how to setup the Radio 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 radio-card
```
Here's how to use the it
```tsx
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| orientation | horizontal | `'vertical' \| 'horizontal'` | The orientation of the component |
| 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 |
| 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 checked radio when rendered.
Use when you don't need to control the value of the radio group. |
| disabled | undefined | `boolean` | If `true`, the radio group will be disabled |
| 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 label: string\n indicator: string\n item: (value: string) => string\n itemLabel: (value: string) => string\n itemControl: (value: string) => string\n itemHiddenInput: (value: string) => string\n}>` | The ids of the elements in the radio. Useful for composition. |
| name | undefined | `string` | The name of the input fields in the radio
(Useful for form submission). |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function called once a radio is checked |
| readOnly | undefined | `boolean` | Whether the checkbox is read-only |
| value | undefined | `string` | The controlled value of the radio group |
| justify | undefined | `'start' \| 'end' \| 'center'` | The justify of the component |
## Explorer
Explore the `Radio Card` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Radio
```tsx
import { HStack, RadioGroup } from "@chakra-ui/react"
export const RadioBasic = () => {
return (
{items.map((item) => (
{item.label}
))}
)
}
const items = [
{ label: "Option 1", value: "1" },
{ label: "Option 2", value: "2" },
{ label: "Option 3", value: "3" },
]
```
## Usage
```tsx
import { RadioGroup } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Controlled
Pass the `value` and `onValueChange` props to the `RadioGroup.Root` component to
control the selected radio button.
```tsx
"use client"
import { HStack, RadioGroup } from "@chakra-ui/react"
import { useState } from "react"
export const RadioControlled = () => {
const [value, setValue] = useState(null)
return (
setValue(e.value)}>
{items.map((item) => (
{item.label}
))}
)
}
const items = [
{ label: "Option 1", value: "1" },
{ label: "Option 2", value: "2" },
{ label: "Option 3", value: "3" },
]
```
### Colors
Pass the `colorPalette` prop to the `RadioGroup.Root` component to change the
color scheme of the component.
```tsx
import { HStack, RadioGroup, Stack, Text } from "@chakra-ui/react"
export const RadioWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
{items.map((item) => (
{item.label}
))}
))}
)
}
const items = [
{ label: "React", value: "react" },
{ label: "Vue", value: "vue" },
{ label: "Solid", value: "solid" },
]
```
### Sizes
Pass the `size` prop to the `RadioGroup.Root` component to change the size of
the radio component.
```tsx
import { For, HStack, RadioGroup } from "@chakra-ui/react"
export const RadioWithSizes = () => {
return (
{(size) => (
Radio ({size})
)}
)
}
```
### Variants
Pass the `variant` prop to the `RadioGroup.Root` component to change the
appearance of the radio component.
```tsx
import { For, HStack, RadioGroup, Stack } from "@chakra-ui/react"
export const RadioWithVariants = () => {
return (
{(variant) => (
React ({variant})
Vue ({variant})
)}
)
}
```
### Disabled
Pass the `disabled` prop to the `RadioGroup.Item` component to make the radio
disabled.
```tsx
import { HStack, RadioGroup } from "@chakra-ui/react"
export const RadioDisabled = () => {
return (
{items.map((item) => (
{item.label}
))}
)
}
const items = [
{ label: "Option 1", value: "1" },
{ label: "Option 2", value: "2", disabled: true },
{ label: "Option 3", value: "3" },
]
```
### Hook Form
Use the `Controller` component from `react-hook-form` to control the radio group
within a form
```tsx
"use client"
import { Button, Fieldset, HStack, RadioGroup } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
import { Controller, useForm } from "react-hook-form"
import { z } from "zod"
const items = [
{ value: "1", label: "Option 1" },
{ value: "2", label: "Option 2" },
{ value: "3", label: "Option 3" },
]
const formSchema = z.object({
value: z.string({ message: "Value is required" }),
})
type FormValues = z.infer
export const RadioWithHookForm = () => {
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 Radio 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 radio
```
Here's how to use it:
```tsx
```
## 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 | solid | `'outline' \| 'subtle' \| 'solid'` | 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. |
| defaultValue | undefined | `string` | The initial value of the checked radio when rendered.
Use when you don't need to control the value of the radio group. |
| disabled | undefined | `boolean` | If `true`, the radio group will be disabled |
| 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 label: string\n indicator: string\n item: (value: string) => string\n itemLabel: (value: string) => string\n itemControl: (value: string) => string\n itemHiddenInput: (value: string) => string\n}>` | The ids of the elements in the radio. Useful for composition. |
| name | undefined | `string` | The name of the input fields in the radio
(Useful for form submission). |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function called once a radio is checked |
| orientation | undefined | `'horizontal' \| 'vertical'` | Orientation of the radio group |
| readOnly | undefined | `boolean` | Whether the checkbox is read-only |
| value | undefined | `string` | The controlled value of the radio group |
# Radiomark
```tsx
import { Radiomark, Stack } from "@chakra-ui/react"
export const RadiomarkBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Radiomark } from "@chakra-ui/react"
```
```tsx
```
## Examples
### States
The Radiomark component supports checked and unchecked states, with optional
disabled state.
```tsx
import { HStack, Radiomark } from "@chakra-ui/react"
export const RadiomarkStates = () => {
return (
)
}
```
### Variants
Use the `variant` prop to change the visual style of the radiomark.
```tsx
import { For, Radiomark, Stack } from "@chakra-ui/react"
export const RadiomarkVariants = () => {
return (
{(variant) => }
)
}
```
### Sizes
Use the `size` prop to change the size of the radiomark.
```tsx
import { For, HStack, Radiomark } from "@chakra-ui/react"
export const RadiomarkWithSizes = () => {
return (
{(size) => }
)
}
```
### Colors
Use the `colorPalette` prop to change the color scheme of the radiomark.
```tsx
import { For, HStack, Radiomark } from "@chakra-ui/react"
export const RadiomarkWithColors = () => {
return (
{(colorPalette) => (
)}
)
}
```
### Filled
Use the `filled` prop with the `outline` variant to add a background color to
the radiomark.
```tsx
import { HStack, Radiomark } from "@chakra-ui/react"
export const RadiomarkWithFilled = () => {
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 | solid | `'solid' \| 'subtle' \| 'outline' \| 'inverted'` | The variant of the component |
| size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component |
| checked | undefined | `boolean \| undefined` | Whether the checkmark is checked |
| 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. |
# Rating
```tsx
import { RatingGroup } from "@chakra-ui/react"
export const RatingBasic = () => {
return (
)
}
```
## Usage
```tsx
import { RatingGroup } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Shortcuts
The `Rating` component also provides a set of shortcuts for common use cases.
### RatingControl
This component renders the number of rating items specified in the `count` prop.
This works:
```tsx
{Array.from({ length: 5 }).map((_, index) => (
))}
```
This might be more concise, if you don't need to customize the rating icons:
```tsx
```
## Examples
### Basic
```tsx
import { RatingGroup } from "@chakra-ui/react"
export const RatingBasic = () => {
return (
)
}
```
### Sizes
Use the `size` prop to change the size of the rating component.
```tsx
import { For, RatingGroup, Stack } from "@chakra-ui/react"
export const RatingWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Controlled
Use the `value` and `onValueChange` prop to control the rating value.
```tsx
"use client"
import { RatingGroup } from "@chakra-ui/react"
import { useState } from "react"
export const RatingControlled = () => {
const [value, setValue] = useState(3)
return (
setValue(e.value)}
>
)
}
```
### Store
An alternative way to control the rating is to use the `RootProvider` component
and the `useRatingGroup` store hook.
This way you can access the rating state and methods from outside the component.
```tsx
"use client"
import { RatingGroup, useRatingGroup } from "@chakra-ui/react"
export const RatingWithStore = () => {
const store = useRatingGroup({ count: 5, defaultValue: 3 })
return (
)
}
```
### ReadOnly
Use the `readOnly` prop to make the rating component read-only.
```tsx
import { RatingGroup } from "@chakra-ui/react"
export const RatingWithReadonly = () => {
return (
)
}
```
### Hook Form
Here's an example of how to use rating with `react-hook-form`.
```tsx
"use client"
import { Button, Field, RatingGroup, 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({
rating: z.number({ message: "Rating is required" }).min(1).max(5),
})
type FormValues = z.infer
export const RatingWithHookForm = () => {
const {
handleSubmit,
formState: { errors },
control,
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Custom Icon
Use the `icon` prop to pass a custom icon to the rating component. This will
override the default star icon.
```tsx
import { RatingGroup } from "@chakra-ui/react"
import { IoHeart } from "react-icons/io5"
export const RatingWithCustomIcon = () => {
return (
{Array.from({ length: 5 }).map((_, index) => (
} />
))}
)
}
```
### Label
Render the `RatingGroup.Label` component to provide a human-readable label for
the rating component.
```tsx
import { RatingGroup } from "@chakra-ui/react"
export const RatingWithLabel = () => {
return (
Rating
)
}
```
### Half Star
Use the `allowHalf` prop to allow half-star ratings.
```tsx
import { RatingGroup } from "@chakra-ui/react"
export const RatingWithHalf = () => {
return (
)
}
```
### Emoji
Compose the rating component with emojis.
```tsx
import { RatingGroup } from "@chakra-ui/react"
const emojiMap: Record = {
1: "😡",
2: "😠",
3: "😐",
4: "😊",
5: "😍",
}
export const RatingEmoji = () => {
return (
{Array.from({ length: 5 }).map((_, index) => (
{emojiMap[index + 1]}
))}
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the rating
```tsx
import { RatingGroup, Stack, Text } from "@chakra-ui/react"
export const RatingWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Testimonial
Use the rating component to show testimonials.
```tsx
import { Avatar, HStack, RatingGroup, Stack, Text } from "@chakra-ui/react"
export const RatingInTestimonial = () => {
return (
Sage is a great software engineer. He is very professional and
knowledgeable.
Matthew Jones
CTO, Company
)
}
```
### Closed Component
Here's how to setup the Rating for a closed component composition.
Here's how to use the it
```tsx
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| count | 5 | `number` | The total number of ratings. |
| 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. |
| allowHalf | undefined | `boolean` | Whether to allow half stars. |
| autoFocus | undefined | `boolean` | Whether to autofocus the rating. |
| defaultValue | undefined | `number` | The initial value of the rating when rendered.
Use when you don't need to control the value of the rating. |
| disabled | undefined | `boolean` | Whether the rating is 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 label: string\n hiddenInput: string\n control: string\n item: (id: string) => string\n}>` | The ids of the elements in the rating. Useful for composition. |
| name | undefined | `string` | The name attribute of the rating element (used in forms). |
| onHoverChange | undefined | `(details: HoverChangeDetails) => void` | Function to be called when the rating value is hovered. |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function to be called when the rating value changes. |
| readOnly | undefined | `boolean` | Whether the rating is readonly. |
| required | undefined | `boolean` | Whether the rating is required. |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| value | undefined | `number` | The controlled value of the rating |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| index | undefined | `number` | 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. |
# Scroll Area
```tsx
import { ScrollArea } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaBasic = () => (
)
```
## Usage
```tsx
import { ScrollArea } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Variants
Use the `variant` prop to change the scrollbar visibility behavior. Values can
be either `hover` (default) or `always`.
```tsx
import { For, ScrollArea, Stack, Text } from "@chakra-ui/react"
import Lorem from "react-lorem-ipsum"
export const ScrollAreaWithVariants = () => (
{(variant) => (
variant="{variant}"
)}
)
```
### Sizes
Use the `size` prop to change the size of the scroll area. This affects the
scrollbar thickness and content padding.
```tsx
import { For, ScrollArea, Stack, Text } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaWithSizes = () => (
{(size) => (
size="{size}"
)}
)
```
### Horizontal Scrolling
The scroll area automatically supports horizontal scrolling when content
overflows horizontally.
```tsx
import { Flex, ScrollArea } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const ScrollAreaHorizontal = () => (
{Array.from({ length: 12 }, (_, i) => (
Item {i + 1}
))}
)
```
### Both Directions
When content overflows in both directions, both scrollbars will appear.
```tsx
import { ScrollArea } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaBothDirections = () => (
)
```
:::info
You can render the `ScrollArea.Corner` component to show a corner indicator to
fill the intersection of the two scrollbars for a seamless, styled appearance.
:::
### Scroll Shadow
Add visual feedback when content is scrollable by implementing scroll shadows
that appear at the edges using `mask-image`.
```tsx
import { ScrollArea } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const ScrollAreaWithScrollShadow = () => {
return (
{Array.from({ length: 10 }, (_, i) => (
Item {i + 1}
))}
)
}
```
### Thumb Styling
Customize the appearance of the scrollbar thumb with different styles and
colors.
```tsx
import { ScrollArea } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaWithThumbStyling = () => (
)
```
### Stick to Bottom
Implement chat-like behavior where new content automatically scrolls to the
bottom, but allows manual scrolling.
> This example uses `use-stick-to-bottom` to scroll pinning.
```tsx
"use client"
import {
Box,
Button,
ButtonGroup,
IconButton,
ScrollArea,
VStack,
} from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
import { useState } from "react"
import { LuArrowDown } from "react-icons/lu"
import { useStickToBottom } from "use-stick-to-bottom"
export const ScrollAreaStickToBottom = () => {
const sticky = useStickToBottom()
const [messages, setMessages] = useState([
"Message 1 - 10:00:00",
"Message 2 - 10:00:01",
"Message 3 - 10:00:02",
"Message 4 - 10:00:03",
"Message 5 - 10:00:04",
"Message 6 - 10:00:05",
"Message 7 - 10:00:06",
"Message 8 - 10:00:07",
"Message 9 - 10:00:08",
"Message 10 - 10:00:09",
])
const addMessage = () => {
const newMessage = `Message ${messages.length + 1} - ${new Date().toLocaleTimeString()}`
setMessages((prev) => [...prev, newMessage])
}
const addMultipleMessages = () => {
const newMessages = Array.from(
{ length: 5 },
(_, i) =>
`Batch message ${messages.length + i + 1} - ${new Date().toLocaleTimeString()}`,
)
setMessages((prev) => [...prev, ...newMessages])
}
const removeMessage = () => {
setMessages((prev) => prev.slice(0, -1))
}
return (
{messages.map((message, index) => (
{message}
))}
{!sticky.isAtBottom && (
{
sticky.scrollToBottom()
}}
colorScheme="blue"
variant="solid"
>
)}
)
}
```
### Virtualization
Handle large datasets efficiently by rendering only visible items using
`@tanstack/react-virtual`.
```tsx
"use client"
import { ScrollArea } from "@chakra-ui/react"
import { type VirtualItem, useVirtualizer } from "@tanstack/react-virtual"
import { Box } from "@chakra-ui/react"
import React, { useCallback, useMemo, useRef } from "react"
export const ScrollAreaVirtualization = () => {
const scrollRef = useRef(null)
const items = useMemo(
() =>
Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `Item ${i + 1}`,
})),
[],
)
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => 80,
overscan: 5,
})
const contentProps = useMemo(
(): React.ComponentProps<"div"> => ({
style: {
height: `${virtualizer.getTotalSize()}px`,
width: "full",
position: "relative",
},
}),
[virtualizer],
)
const getItemProps = useCallback(
(item: VirtualItem): React.ComponentProps<"div"> => ({
style: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
paddingBottom: 4,
height: `${item.size}px`,
transform: `translateY(${item.start}px)`,
},
}),
[],
)
return (
{virtualizer.getVirtualItems().map((virtualItem) => {
const item = items[virtualItem.index]
return (
{item.name}
)
})}
)
}
```
### Store
Use the scroll area with external state management and programmatic control.
```tsx
"use client"
import { ScrollArea, useScrollArea } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaWithStore = () => {
const scrollArea = useScrollArea()
return (
)
}
```
### Scroll to Side
Programmatically navigate through content by scrolling to different sides and
directions.
```tsx
"use client"
import {
Button,
ButtonGroup,
ScrollArea,
Stack,
useScrollArea,
} from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaScrollToSide = () => {
const scrollArea = useScrollArea()
return (
)
}
```
### Scroll to Position
Jump to specific positions or items within the scrollable area with smooth
animations.
```tsx
"use client"
import { Button, ScrollArea, Stack, useScrollArea } from "@chakra-ui/react"
import LoremIpsum from "react-lorem-ipsum"
export const ScrollAreaScrollToPosition = () => {
const scrollArea = useScrollArea()
return (
)
}
```
### RTL Support
The scroll area component fully supports Right-to-Left (RTL) languages like
Arabic and Hebrew.
```tsx
import { LocaleProvider, ScrollArea } from "@chakra-ui/react"
const arabicText = [
"مرحباً بكم في نظام التمرير المخصص",
"هذا مثال على النص العربي في منطقة التمرير",
"يدعم النظام اللغات التي تُكتب من اليمين إلى اليسار",
"التمرير الأفقي يعمل بشكل صحيح مع النصوص العربية",
"يمكنك رؤية كيف تتكيف أشرطة التمرير مع اتجاه النص",
"النظام يدعم التمرير العمودي والأفقي في نفس الوقت",
"يمكن تخصيص مظهر أشرطة التمرير حسب التصميم المطلوب",
"التفاعل مع أشرطة التمرير سهل ومريح للمستخدم",
"يعمل النظام بسلاسة على جميع المتصفحات الحديثة",
"يمكن دمج هذا المكون مع مكونات أخرى بسهولة",
"الأداء محسّن للتعامل مع كميات كبيرة من المحتوى",
]
export const ScrollAreaWithRtl = () => {
return (
{arabicText.map((text, i) => (
{text}
))}
)
}
```
### With Menu
Combine scroll area with other components like menus to handle overflowing
content. This example shows how to create a scrollable menu with many items.
```tsx
import { Button, Menu, Portal, ScrollArea } from "@chakra-ui/react"
import { useId } from "react"
export const ScrollAreaWithMenu = () => {
const contentId = useId()
return (
{menuItems.map((item) => (
{item.label}
))}
)
}
function MenuContent(props: Menu.ContentProps) {
const { id, children, ...rest } = props
return (
{children}
)
}
const menuItems = [
{ value: "profile", label: "Profile" },
{ value: "settings", label: "Settings" },
{ value: "notifications", label: "Notifications" },
{ value: "messages", label: "Messages" },
{ value: "documents", label: "Documents" },
{ value: "files", label: "Files" },
{ value: "images", label: "Images" },
{ value: "videos", label: "Videos" },
{ value: "music", label: "Music" },
{ value: "downloads", label: "Downloads" },
{ value: "share", label: "Share" },
{ value: "copy", label: "Copy" },
{ value: "edit", label: "Edit" },
{ value: "favorites", label: "Favorites" },
{ value: "liked", label: "Liked Items" },
{ value: "bookmarks", label: "Bookmarks" },
{ value: "flagged", label: "Flagged Items" },
{ value: "help", label: "Help & Support" },
{ value: "trash", label: "Trash" },
{ value: "logout", label: "Logout" },
]
```
## 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 | hover | `'hover' \| 'always'` | 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. |
| ids | undefined | `Partial<{ root: string; viewport: string; content: string; scrollbar: string; thumb: string }>` | The ids of the scroll area elements |
### Viewport
| 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. |
### Scrollbar
| 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. |
| orientation | undefined | `Orientation` | undefined |
### Thumb
| 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. |
### Corner
| 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 `Scroll Area` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Segmented Control
```tsx
import { SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlBasic = () => {
return (
)
}
```
## Usage
```tsx
import { SegmentGroup } from "@chakra-ui/react"
```
```tsx
```
## Shortcuts
The `SegmentGroup` component also provides a set of shortcuts for common use
cases.
### SegmentGroupItems
The `SegmentGroupItems` shortcut renders a list of items based on the `items`
prop.
This works:
```tsx
<>
{items.map((item) => (
{item.label}
))}
>
```
This might be more concise, if you don't need to customize the items:
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the segmented control.
```tsx
import { For, SegmentGroup, Stack, Text, VStack } from "@chakra-ui/react"
export const SegmentedControlWithSizes = () => {
return (
{(size) => (
size = {size}
)}
)
}
```
### Controlled
Use the `value` and `onValueChange` props to control the selected item.
```tsx
"use client"
import { SegmentGroup } from "@chakra-ui/react"
import { useState } from "react"
export const SegmentedControlControlled = () => {
const [value, setValue] = useState("React")
return (
setValue(e.value)}>
)
}
```
### Hook Form
Here's an example of how to use the `SegmentedControl` with `react-hook-form`.
```tsx
"use client"
import { Button, Field, SegmentGroup, 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({
fontSize: z.string({ message: "Font size is required" }),
})
type FormValues = z.infer
export const SegmentedControlWithHookForm = () => {
const {
handleSubmit,
formState: { errors },
control,
} = useForm({
defaultValues: { fontSize: "md" },
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Vertical
By default, the segmented control is horizontal. Set the `orientation` prop to
`vertical` to change the orientation of the segmented control.
```tsx
import { SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlVertical = () => {
return (
)
}
```
### Disabled
Use the `disabled` prop to disable the segmented control.
```tsx
import { SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlWithDisabled = () => {
return (
)
}
```
### Disabled Item
Use the `disabled` prop on the item to disable it.
```tsx
import { SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlWithDisabledItem = () => {
return (
)
}
```
### Custom Indicator
Customize the indicator appearance using CSS variables like
`--segment-indicator-bg` and `--segment-indicator-shadow`.
```tsx
import { SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlWithCustomIndicator = () => {
return (
)
}
```
### Color Palette
By default, the segment control doesn't support changing the design via the
`colorPalette` prop. This example shows how to customize the segmented control
to make the `colorPalette` prop work.
```tsx
import { Center, For, SegmentGroup } from "@chakra-ui/react"
export const SegmentedControlWithColorPalette = () => {
return (
{(item) => (
{item}
)}
)
}
```
### Icon
Render the `label` as a `ReactNode` to render an icon.
```tsx
import { HStack, SegmentGroup } from "@chakra-ui/react"
import { LuGrid2X2, LuList, LuTable } from "react-icons/lu"
export const SegmentedControlWithIcon = () => {
return (
Table
),
},
{
value: "board",
label: (
Board
),
},
{
value: "list",
label: (
List
),
},
]}
/>
)
}
```
### Card
Here's an example of how to use the `SegmentedControl` within a `Card`.
```tsx
import { Button, Card, Field, Heading, SegmentGroup } from "@chakra-ui/react"
import { LuSearch } from "react-icons/lu"
export const SegmentedControlInCard = () => {
return (
Find your dream home
Bedrooms
Beds
Bathrooms
)
}
```
## 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 | `'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. |
| defaultValue | undefined | `string` | The initial value of the checked radio when rendered.
Use when you don't need to control the value of the radio group. |
| disabled | undefined | `boolean` | If `true`, the radio group will be disabled |
| 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 label: string\n indicator: string\n item: (value: string) => string\n itemLabel: (value: string) => string\n itemControl: (value: string) => string\n itemHiddenInput: (value: string) => string\n}>` | The ids of the elements in the radio. Useful for composition. |
| name | undefined | `string` | The name of the input fields in the radio
(Useful for form submission). |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function called once a radio is checked |
| orientation | undefined | `'horizontal' \| 'vertical'` | Orientation of the radio group |
| readOnly | undefined | `boolean` | Whether the checkbox is read-only |
| value | undefined | `string` | The controlled value of the radio group |
# Select
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectBasic = () => {
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 { Select } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the select component.
```tsx
"use client"
import {
For,
Portal,
Select,
Stack,
createListCollection,
} from "@chakra-ui/react"
export const SelectWithSizes = () => {
return (
{(size) => (
size = {size}
{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" },
],
})
```
### Variants
Use the `variant` prop to change the appearance of the select component.
```tsx
"use client"
import {
For,
Portal,
Select,
Stack,
createListCollection,
} from "@chakra-ui/react"
export const SelectWithVariants = () => {
return (
{(variant) => (
Select framework - {variant}
{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" },
],
})
```
### Option Group
Use the `Select.ItemGroup` component to group select options.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
import { groupBy } from "es-toolkit"
export const SelectWithOptionGroup = () => {
return (
Select framework
{categories.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" },
],
})
const categories = Object.entries(
groupBy(collection.items, (item) => item.category),
)
```
### Controlled
Use the `value` and `onValueChange` props to control the select component.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
import { useState } from "react"
export const SelectControlled = () => {
const [value, setValue] = useState([])
return (
setValue(e.value)}
>
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" },
],
})
```
### Async Loading
Here's an example of how to populate the select `collection` from a remote
source.
```tsx
"use client"
import { Portal, Select, Spinner, createListCollection } from "@chakra-ui/react"
import { useMemo } from "react"
import { useAsync } from "react-use"
interface Pokemon {
name: string
url: string
}
export const SelectAsyncLoading = () => {
const state = useAsync(async (): Promise => {
const response = await fetch("https://pokeapi.co/api/v2/pokemon")
const data = await response.json()
return data.results
}, [])
const collection = useMemo(() => {
return createListCollection({
items: state.value ?? [],
itemToString: (pokemon) => pokemon.name,
itemToValue: (pokemon) => pokemon.name,
})
}, [state.value])
return (
Select pokemon
{state.loading && (
)}
{collection.items.map((pokemon) => (
{pokemon.name}
))}
)
}
```
### Hook Form
Here's an example of how to use the `Select` component with `react-hook-form`.
```tsx
"use client"
import {
Button,
Field,
Portal,
Select,
Stack,
createListCollection,
} 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" }).array(),
})
type FormValues = z.infer
export const SelectWithHookForm = () => {
const {
handleSubmit,
formState: { errors },
control,
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### Disabled
Use the `disabled` prop to disable the select component.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithDisabled = () => {
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" },
],
})
```
### Invalid
Here's an example of how to compose the `Select` component with the `Field`
component to display an error state.
```tsx
"use client"
import { Field, Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithInvalid = () => {
return (
Select framework
{frameworks.items.map((framework) => (
{framework.label}
))}
This is an error
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### Multiple
Use the `multiple` prop to allow multiple selections.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithMultiple = () => {
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" },
],
})
```
### Positioning
Use the `positioning` prop to control the underlying `floating-ui` options of
the select component.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithPositioning = () => {
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" },
],
})
```
### Clear Trigger
Render the `Select.ClearTrigger` component to show a clear button. Clicking the
clear button will clear the selected value.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithClear = () => {
return (
Select fav. anime
{animeMovies.items.map((anime) => (
{anime.label}
))}
)
}
const animeMovies = createListCollection({
items: [
{ label: "Spirited Away", value: "spirited_away" },
{ label: "My Neighbor Totoro", value: "my_neighbor_totoro" },
{ label: "Akira", value: "akira" },
{ label: "Princess Mononoke", value: "princess_mononoke" },
{ label: "Grave of the Fireflies", value: "grave_of_the_fireflies" },
{ label: "Howl's Moving Castle", value: "howls_moving_castle" },
{ label: "Ghost in the Shell", value: "ghost_in_the_shell" },
{ label: "Naruto", value: "naruto" },
{ label: "Hunter x Hunter", value: "hunter_x_hunter" },
{ label: "The Wind Rises", value: "the_wind_rises" },
{ label: "Kiki's Delivery Service", value: "kikis_delivery_service" },
{ label: "Perfect Blue", value: "perfect_blue" },
{
label: "The Girl Who Leapt Through Time",
value: "the_girl_who_leapt_through_time",
},
{ label: "Weathering with You", value: "weathering_with_you" },
{ label: "Ponyo", value: "ponyo" },
{ label: "5 Centimeters per Second", value: "5_centimeters_per_second" },
{ label: "A Silent Voice", value: "a_silent_voice" },
{ label: "Paprika", value: "paprika" },
{ label: "Wolf Children", value: "wolf_children" },
{ label: "Redline", value: "redline" },
{
label: "The Tale of the Princess Kaguya",
value: "the_tale_of_the_princess_kaguya",
},
],
})
```
### Overflow
When the options are too many, the options will overflow the container due to
the `maxHeight` set.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
export const SelectWithOverflow = () => {
return (
Select anime
{animeMovies.items.map((movie) => (
{movie.label}
))}
)
}
const animeMovies = createListCollection({
items: [
{ label: "Spirited Away", value: "spirited_away" },
{ label: "My Neighbor Totoro", value: "my_neighbor_totoro" },
{ label: "Akira", value: "akira" },
{ label: "Princess Mononoke", value: "princess_mononoke" },
{ label: "Grave of the Fireflies", value: "grave_of_the_fireflies" },
{ label: "Howl's Moving Castle", value: "howls_moving_castle" },
{ label: "Ghost in the Shell", value: "ghost_in_the_shell" },
{ label: "Naruto", value: "naruto" },
{ label: "Hunter x Hunter", value: "hunter_x_hunter" },
{ label: "The Wind Rises", value: "the_wind_rises" },
{ label: "Kiki's Delivery Service", value: "kikis_delivery_service" },
{ label: "Perfect Blue", value: "perfect_blue" },
{
label: "The Girl Who Leapt Through Time",
value: "the_girl_who_leapt_through_time",
},
{ label: "Weathering with You", value: "weathering_with_you" },
{ label: "Ponyo", value: "ponyo" },
{ label: "5 Centimeters per Second", value: "5_centimeters_per_second" },
{ label: "A Silent Voice", value: "a_silent_voice" },
{ label: "Paprika", value: "paprika" },
{ label: "Wolf Children", value: "wolf_children" },
{ label: "Redline", value: "redline" },
{
label: "The Tale of the Princess Kaguya",
value: "the_tale_of_the_princess_kaguya",
},
],
})
```
### Item Description
Here's an example of how to render a description for each item.
```tsx
"use client"
import {
Portal,
Select,
Span,
Stack,
createListCollection,
} from "@chakra-ui/react"
export const SelectWithItemDescription = () => {
return (
Select plan
{frameworks.items.map((framework) => (
{framework.label}
{framework.description}
))}
)
}
const frameworks = createListCollection({
items: [
{
label: "Basic Plan",
value: "basic",
description: "$9/month - Perfect for small projects",
},
{
label: "Pro Plan",
value: "pro",
description: "$29/month - Advanced features",
},
{
label: "Business Plan",
value: "business",
description: "$99/month - Enterprise-grade solutions",
},
{
label: "Enterprise Plan",
value: "enterprise",
description: "Custom pricing - Tailored solutions",
},
],
})
```
### Within Popover
Here's an example of how to use the `Select` within a `Popover` component.
```tsx
"use client"
import {
Button,
Popover,
Portal,
Select,
createListCollection,
} from "@chakra-ui/react"
export const SelectInPopover = () => {
return (
Select in Popover
{frameworks.items.map((item) => (
{item.label}
))}
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
```
### Within Dialog
To use the `Select` within a `Dialog`, you need to avoid portalling the
`Select.Positioner` to the document's body.
```diff
-
{/* ... */}
-
```
If you have set `scrollBehavior="inside"` on the `Dialog`, you need to:
- Set the select positioning to `fixed` to avoid the select from being clipped
by the dialog.
- Set `hideWhenDetached` to `true` to hide the select when the trigger is
scrolled out of view.
```tsx
{/* ... */}
```
```tsx
"use client"
import {
Button,
CloseButton,
Dialog,
Portal,
Select,
createListCollection,
} from "@chakra-ui/react"
export const SelectInDialog = () => {
return (
Select in Dialog
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
function DialogSelect() {
return (
Select framework
{frameworks.items.map((item) => (
{item.label}
))}
)
}
```
### Avatar Select
Here's an example of how to compose the `Select` and the `Avatar`.
```tsx
"use client"
import {
Avatar,
HStack,
Select,
createListCollection,
useSelectContext,
} from "@chakra-ui/react"
const SelectValue = () => {
const select = useSelectContext()
const items = select.selectedItems as Array<{ name: string; avatar: string }>
const { name, avatar } = items[0]
return (
{name}
)
}
export const SelectWithAvatar = () => {
return (
Select member
{members.items.map((item) => (
{item.name}
))}
)
}
const members = createListCollection({
items: [
{
name: "Jessica Jones",
id: "jessica_jones",
avatar:
"https://images.unsplash.com/photo-1531746020798-e6953c6e8e04?w=100",
},
{
name: "Kenneth Johnson",
id: "kenneth_johnson",
avatar:
"https://images.unsplash.com/photo-1523477800337-966dbabe060b?w=100",
},
{
name: "Kate Wilson",
id: "kate_wilson",
avatar:
"https://images.unsplash.com/photo-1609712409631-dbbb050746d1?w=100",
},
],
itemToString: (item) => item.name,
itemToValue: (item) => item.id,
})
```
### Country Select
Here's an example of how to use the `Select` component to select a country.
```tsx
"use client"
import { Portal, Select, createListCollection } from "@chakra-ui/react"
import { groupBy } from "es-toolkit"
export const SelectWithCountry = () => {
return (
Select country
{continents.map(([continent, items]) => (
{continent}
{items.map((item) => (
{countries.stringifyItem(item)}
))}
))}
)
}
const countries = createListCollection({
items: [
{ value: "US", label: "United States", flag: "🇺🇸", continent: "America" },
{ value: "CA", label: "Canada", flag: "🇨🇦", continent: "America" },
{ value: "MX", label: "Mexico", flag: "🇲🇽", continent: "America" },
{ value: "BR", label: "Brazil", flag: "🇧🇷", continent: "America" },
{ value: "ZA", label: "South Africa", flag: "🇿🇦", continent: "Africa" },
{ value: "NG", label: "Nigeria", flag: "🇳🇬", continent: "Africa" },
{ value: "MA", label: "Morocco", flag: "🇲🇦", continent: "Africa" },
{ value: "EG", label: "Egypt", flag: "🇪🇬", continent: "Africa" },
{ value: "CN", label: "China", flag: "🇨🇳", continent: "Asia" },
{ value: "JP", label: "Japan", flag: "🇯🇵", continent: "Asia" },
{ value: "IN", label: "India", flag: "🇮🇳", continent: "Asia" },
{ value: "KR", label: "South Korea", flag: "🇰🇷", continent: "Asia" },
{ value: "GB", label: "United Kingdom", flag: "🇬🇧", continent: "Europe" },
{ value: "FR", label: "France", flag: "🇫🇷", continent: "Europe" },
{ value: "DE", label: "Germany", flag: "🇩🇪", continent: "Europe" },
{ value: "IT", label: "Italy", flag: "🇮🇹", continent: "Europe" },
{ value: "ES", label: "Spain", flag: "🇪🇸", continent: "Europe" },
{ value: "AU", label: "Australia", flag: "🇦🇺", continent: "Oceania" },
{ value: "NZ", label: "New Zealand", flag: "🇳🇿", continent: "Oceania" },
{ value: "FJ", label: "Fiji", flag: "🇫🇯", continent: "Oceania" },
],
itemToString: (item) => `${item.flag} ${item.label}`,
itemToValue: (item) => item.value,
})
const continents = Object.entries(
groupBy(countries.items, (item) => item.continent),
)
```
### Icon Button
Here's an example of how to trigger the select component with an `IconButton`.
```tsx
"use client"
import {
HStack,
IconButton,
Portal,
Select,
createListCollection,
useSelectContext,
} from "@chakra-ui/react"
import {
RiAngularjsLine,
RiForbidLine,
RiReactjsLine,
RiSvelteLine,
RiVuejsLine,
} from "react-icons/ri"
const SelectTrigger = () => {
const select = useSelectContext()
const items = select.selectedItems as Framework[]
return (
{select.hasSelectedItems ? items[0].icon : }
)
}
export const SelectWithIconButton = () => {
return (
{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: },
],
})
interface Framework {
label: string
value: string
icon: React.ReactNode
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| collection | undefined | `ListCollection` | The collection of items |
| closeOnSelect | true | `boolean` | Whether the select should close after an item is selected |
| composite | true | `boolean` | Whether the select is a composed with other composite widgets like tabs or combobox |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| loopFocus | false | `boolean` | Whether to loop the keyboard navigation through the options |
| 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'` | 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. |
| 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 select. |
| defaultOpen | undefined | `boolean` | Whether the select's open state is controlled by the user |
| defaultValue | undefined | `string[]` | The initial default value of the select when rendered.
Use when you don't need to control the value of the select. |
| deselectable | undefined | `boolean` | Whether the value can be cleared by clicking the selected item.
**Note:** this is only applicable for single selection |
| disabled | undefined | `boolean` | Whether the select is disabled |
| form | undefined | `string` | The associate form of the underlying select. |
| 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 control: string\n trigger: string\n clearTrigger: string\n label: string\n hiddenSelect: string\n positioner: 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 select. Useful for composition. |
| immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame |
| invalid | undefined | `boolean` | Whether the select is invalid |
| multiple | undefined | `boolean` | Whether to allow multiple selection |
| name | undefined | `string` | The `name` attribute of the underlying select. |
| 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` | The callback fired when the highlighted 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 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` | The callback fired when the selected item changes. |
| open | undefined | `boolean` | Whether the select menu is open |
| positioning | undefined | `PositioningOptions` | The positioning options of the menu. |
| present | undefined | `boolean` | Whether the node is present (controlled by the user) |
| readOnly | undefined | `boolean` | Whether the select is read-only |
| required | undefined | `boolean` | Whether the select is required |
| scrollToIndexFn | undefined | `(details: ScrollToIndexDetails) => void` | Function to scroll to a specific index |
| value | undefined | `string[]` | The controlled keys of the selected items |
## Explorer
Explore the `Select` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Separator
```tsx
import { Separator, Stack, Text } from "@chakra-ui/react"
export const SeparatorBasic = () => {
return (
First
Second
Third
)
}
```
## Usage
```jsx
import { Separator } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Variants
Use the `variant` prop to change the appearance of the separator.
```tsx
import { Separator, Stack } from "@chakra-ui/react"
export const SeparatorWithVariants = () => {
return (
)
}
```
### Sizes
Use the `size` prop to change the size of the separator.
```tsx
import { Separator, Stack } from "@chakra-ui/react"
export const SeparatorWithSizes = () => {
return (
)
}
```
### Label
Use the `label` prop to add a label to the separator.
```tsx
import { HStack, Separator, Stack, Text } from "@chakra-ui/react"
export const SeparatorWithLabel = () => {
return (
Label (start)
Label (end)
Label (center)
)
}
```
### Vertical
Use the `orientation` prop to change the orientation of the separator.
```tsx
import { HStack, Separator, Text } from "@chakra-ui/react"
export const SeparatorVertical = () => {
return (
First
Second
)
}
```
### Responsive Orientation
Here's an example of how to change the `orientation` property based on the
screen size.
```tsx
import { Separator, Stack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SeparatorWithResponsiveOrientation = () => {
return (
First
Second
)
}
```
:::note
When the `orientation` prop is a responsive value, the separator will be
rendered without `aria-orientation` and the role is set to `presentation`.
:::
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | solid | `'solid' \| 'dashed' \| 'dotted'` | The variant of the component |
| orientation | horizontal | `'vertical' \| 'horizontal'` | The orientation 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. |
# Show
```tsx
"use client"
import { Button, Show, Stack } from "@chakra-ui/react"
import { useState } from "react"
export const ShowBasic = () => {
const [count, setCount] = useState(0)
return (
3}>
My Content
)
}
```
## Usage
The `Show` component renders its children when the `when` value is truthy,
otherwise it renders the `fallback` prop.
```jsx
import { Show } from "@chakra-ui/react"
```
```jsx
Content
```
## Examples
### Fallback
Use the `fallback` prop to render a fallback component when the array is empty
or undefined.
```tsx
"use client"
import { Button, Show, Stack, Text } from "@chakra-ui/react"
import { useState } from "react"
export const ShowWithFallback = () => {
const [count, setCount] = useState(0)
return (
3}
fallback={Not there yet. Keep clicking...}
>
Congrats! I am here
)
}
```
### Render Prop
Use the `children` render prop to narrow the type of the `when` value and remove
`undefined` | `null`
```tsx
import { Show } from "@chakra-ui/react"
export const ShowWithRenderProp = () => {
const value: number | undefined = 10
return {(value) => Value: {value}
}
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| when | undefined | `T \| null \| undefined` | If `true`, it'll render the `children` prop |
| fallback | undefined | `React.ReactNode \| undefined` | The fallback content to render if `when` is `false` |
| 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. |
# SimpleGrid
```tsx
import { SimpleGrid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SimpleGridBasic = () => {
return (
)
}
```
## Usage
The `SimpleGrid` component allows you to create responsive grid layouts with
ease.
```jsx
import { SimpleGrid } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Columns
Specify the number of columns for the grid layout using the `columns` prop.
```tsx
import { SimpleGrid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SimpleGridWithColumns = () => (
)
```
### Auto-responsive
Make the grid responsive and adjust automatically without passing columns, by
using the `minChildWidth` prop. This uses css grid auto-fit and minmax()
internally.
```tsx
import { SimpleGrid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SimpleGridWithAutofit = () => (
)
```
### Column Span
Specify the size of the column by using the `colSpan` prop.
```tsx
import { GridItem, SimpleGrid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SimpleGridWithColSpan = () => (
Column 1
Column 2
)
```
### Row and Column Gap
Pass the `rowGap` and `columnGap` props to change the row and column spacing
between the grid items.
```tsx
import { SimpleGrid } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const SimpleGridWithRowAndColGap = () => {
return (
)
}
```
# Skeleton
```tsx
import { HStack, Skeleton, SkeletonCircle, Stack } from "@chakra-ui/react"
export const SkeletonBasic = () => {
return (
)
}
```
## Usage
```jsx
import { Skeleton, SkeletonCircle, SkeletonText } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Feed
Use the `Skeleton` component to create a feed skeleton.
```tsx
import {
HStack,
Skeleton,
SkeletonCircle,
SkeletonText,
Stack,
} from "@chakra-ui/react"
export const SkeletonForFeed = () => {
return (
)
}
```
### Text
Use the `SkeletonText` component to create a skeleton for text.
```tsx
import { SkeletonText } from "@chakra-ui/react"
export const SkeletonForText = () => {
return
}
```
### With Children
Use the `loading` prop to show the skeleton while the content is loading.
```tsx
import { Badge, HStack, Skeleton } from "@chakra-ui/react"
export const SkeletonWithChildren = () => {
return (
Select
Select
)
}
```
### Variants
Use the `variant` prop to change the visual style of the Skeleton.
```tsx
import { HStack, Skeleton, Stack, Text } from "@chakra-ui/react"
export const SkeletonWithVariants = () => {
return (
pulse
shine
)
}
```
### Content Loading
When `loading` is changed to `false`, the Skeleton component will fade in.
```tsx
"use client"
import { Button, Skeleton, Stack, Text } from "@chakra-ui/react"
import { useState } from "react"
export const SkeletonWithLoaded = () => {
const [loading, setLoading] = useState(true)
return (
Chakra UI is cool
)
}
```
### Start and End Color
Use the `--start-color` and `--end-color` CSS variables to change the start and
end color of the skeleton.
```tsx
import { Skeleton } from "@chakra-ui/react"
export const SkeletonWithStartEndColor = () => {
return (
)
}
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| loading | true | `'true' \| 'false'` | The loading of the component |
| variant | pulse | `'pulse' \| 'shine' \| 'none'` | 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. |
# Skip Nav
```tsx
import { Box, SkipNavContent, SkipNavLink, Text } from "@chakra-ui/react"
export const SkipNavBasic = () => {
return (
Skip to Content
{/* Simulated navigation */}
Navigation
This represents a navigation area that users might want to skip over.
{/* Main content area */}
Main Content
This is the main content area. When users press Tab and then Enter
on the "Skip to Content" link, focus will jump directly here,
bypassing the navigation.
)
}
```
## Usage
Skip Navigation link and destination container for screen readers and keyboard
users.
Per
[WebAIM.org on WCAG 2.4.1 (Bypass Blocks - Level A)](https://webaim.org/standards/wcag/checklist#sc2.4.1),
because the main content is not always the first section that the user
encounters on a page, it is strongly recommended to include a skip link for
users to be able to bypass content that is present on multiple pages. Navigation
links are the most common skipped.
> A user with a screen reader or specialized software could skip content via the
> headings or `main` region, but this is not sufficient for sighted users who
> primarily use a keyboard.
```jsx
import { SkipNavContent, SkipNavLink } from "@chakra-ui/react"
```
```jsx
Skip to content
```
## Examples
### Basic Usage
The `SkipNavLink` component ideally needs to be one of the first items a user
encounters when they begin navigating a page after load. Therefore, it is
recommended to place it as high as possible in the app.
It renders an `a` tag and automatically creates a link with an `href` attribute
that will point to `SkipNavContent`.
The `SkipNavContent` component is used as a target for the link to place
keyboard focus on the first piece of main content. It renders a `div` and can
either be a self-closing component, or wrap the main content.
```tsx
import { Box, SkipNavContent, SkipNavLink, Text } from "@chakra-ui/react"
export const SkipNavBasic = () => {
return (
Skip to Content
{/* Simulated navigation */}
Navigation
This represents a navigation area that users might want to skip over.
{/* Main content area */}
Main Content
This is the main content area. When users press Tab and then Enter
on the "Skip to Content" link, focus will jump directly here,
bypassing the navigation.
)
}
```
### Custom ID
You can supply a custom id value using the `id` prop but you will have to use
this prop and value in both components, or they will not match.
```tsx
import { Box, SkipNavContent, SkipNavLink, Text } from "@chakra-ui/react"
export const SkipNavCustomId = () => {
return (
Skip to Main Content
{/* Simulated header and navigation */}
Header & Navigation
This example uses a custom ID "main-content" for both components to
ensure they match.
{/* Main content area with custom ID */}
Main Content (Custom ID)
Both the SkipNavLink and SkipNavContent use the same custom ID
"main-content" to ensure proper linking and focus management.
)
}
```
### With Main Content
The `SkipNavContent` component can wrap your main content area to ensure proper
focus management.
```tsx
import {
Box,
Heading,
SkipNavContent,
SkipNavLink,
Text,
VStack,
} from "@chakra-ui/react"
export const SkipNavWithContent = () => {
return (
Skip to Content
{/* Simulated header with multiple navigation items */}
Site Header
• Home
• About
• Services
• Contact
{/* SkipNavContent wrapping main content */}
Welcome to Our Site
This is the main content area. The SkipNavContent component wraps
this entire section, making it the target for the skip navigation
link.
When keyboard users press Tab to focus the "Skip to Content" link
and then press Enter, focus will jump directly to this content
area, bypassing all the navigation items above.
This is especially helpful for users with screen readers or those
who navigate primarily with keyboards.
)
}
```
## In Action
You can see these components in action on this page!
1. Place your cursor in the browser's address bar.
2. Remove any id queries from the url. (i.e. `/skip-nav#usage`)
3. Hit `Enter` to reload the page, then hit `Tab`. The Skip Nav link will appear
in the upper left.
4. Hitting `Enter` on the link will take you to the top of the docs content.
# Slider
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Slider } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Shortcuts
### `Slider.Thumbs`
This component renders the `Slider.Thumb` and `Slider.HiddenInput` components
for each value.
The code below works:
```tsx
```
but this might be better if you don't need to customize the thumb:
```tsx
```
### `Slider.Marks`
This component renders the `Slider.MarkerGroup` and `Slider.Marker` components
for each value.
The code below works:
```tsx
```
but this might be better if you don't need to customize the marker:
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the slider.
```tsx
import { For, Slider, Stack } from "@chakra-ui/react"
export const SliderWithSizes = () => {
return (
{(size) => (
Slider - {size}
)}
)
}
```
### Variants
Use the `variant` prop to change the visual style of the slider.
```tsx
import { For, Slider, Stack } from "@chakra-ui/react"
export const SliderWithVariants = () => {
return (
{(variant) => (
Slider - {variant}
)}
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the slider.
```tsx
import { For, Slider, Stack } from "@chakra-ui/react"
const colors = ["gray", "blue", "red", "green", "pink"]
export const SliderWithColors = () => {
return (
{(color) => (
)}
)
}
```
### Label
Use the `label` prop to add a label to the slider.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderWithLabel = () => {
return (
Quantity
)
}
```
### Range Slider
Set the `value` or `defaultValue` prop to an array to create a range slider.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderWithMultipleThumbs = () => {
return (
)
}
```
### Prevent Overlap
Use the `minStepsBetweenThumbs` prop to avoid thumbs with the same value.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderPreventOverlap = () => {
return (
)
}
```
### Customization
Here's an example of customizing the thumb with custom icon and background.
```tsx
"use client"
import { Box, Slider } from "@chakra-ui/react"
import { MdGraphicEq } from "react-icons/md"
export const SliderCustomization = () => {
return (
)
}
```
### Value Text
Use the `Slider.ValueText` component to show the current value of the slider.
```tsx
import { HStack, Slider } from "@chakra-ui/react"
export const SliderWithValueText = () => {
return (
Volume
)
}
```
### Controlled
Use the `value` and `onValueChange` props to control the value of the slider.
```tsx
"use client"
import { Slider } from "@chakra-ui/react"
import { useState } from "react"
export const SliderControlled = () => {
const [value, setValue] = useState([40])
return (
setValue(e.value)}
>
)
}
```
### Store
An alternative way to control the slider is to use the `RootProvider` component
and the `useSlider` store hook.
This way you can access the slider state and methods from outside the slider.
```tsx
"use client"
import { Code, Slider, Stack, useSlider } from "@chakra-ui/react"
export const SliderWithStore = () => {
const slider = useSlider({
defaultValue: [40],
thumbAlignment: "center",
})
return (
current: {slider.value}
Slider
)
}
```
### Hook Form
Here's an example of how to integrate a slider with `react-hook-form`.
```tsx
"use client"
import { Button, Field, Slider, 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({
value: z.array(
z
.number({ message: "Value is required" })
.min(60, { message: "Value must be greater than 60" }),
),
})
type FormValues = z.infer
export const SliderWithHookForm = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm({
resolver: standardSchemaResolver(formSchema),
defaultValues: { value: [40] },
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Disabled
Use the `disabled` prop to disable the slider.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderDisabled = () => {
return (
)
}
```
### Change End
Use the `onValueChangeEnd` prop to listen to the end of the slider change.
```tsx
"use client"
import { Box, Code, Slider, Stack } from "@chakra-ui/react"
import { useState } from "react"
const initialValue = [50]
export const SliderChangeEnd = () => {
const [value, setValue] = useState(initialValue)
const [endValue, setEndValue] = useState(initialValue)
return (
setValue(e.value)}
onValueChangeEnd={(e) => setEndValue(e.value)}
>
onChange: {value}
onChangeEnd: {endValue}
)
}
```
### Steps
Use the `step` prop to set the step value of the slider.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderWithStep = () => {
return (
)
}
```
### Thumb Alignment
Use the `thumbAlignment` and `thumbSize` prop to align the thumb within the
track. By default, the thumb is aligned to the start of the track.
```tsx
import { Slider, Stack } from "@chakra-ui/react"
export const SliderWithThumbAlignment = () => {
return (
Slider (contain)
Slider (center)
)
}
```
### Marks
Use the `marks` prop to display marks on the slider.
```tsx
import { For, Slider, Stack, Text, VStack } from "@chakra-ui/react"
export const SliderWithMarks = () => {
return (
{(size) => (
size = {size}
)}
)
}
```
You can also add labels to the marks using the `marks` prop.
```tsx
import { Slider } from "@chakra-ui/react"
const marks = [
{ value: 0, label: "0%" },
{ value: 50, label: "50%" },
{ value: 100, label: "100%" },
]
export const SliderWithMarksAndLabel = () => {
return (
)
}
```
### Vertical
Use the `orientation` prop to change the orientation of the slider.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderVertical = () => {
return (
)
}
```
### Vertical with Marks
Here's an example of a vertical slider with marks.
```tsx
import { Slider } from "@chakra-ui/react"
const marks = [
{ value: 0, label: "0%" },
{ value: 50, label: "50%" },
{ value: 100, label: "100%" },
]
export const SliderWithMarksVertical = () => {
return (
)
}
```
### Dragging Indicator
Render the `Slider.DraggingIndicator` component to show an indicator or tooltip
when dragging the thumb.
> Pro Tip: You can render the `Slider.ValueText` component inside the
> `Slider.DraggingIndicator` to show the current value.
```tsx
import { Slider } from "@chakra-ui/react"
export const SliderWithDraggingIndicator = () => {
return (
)
}
```
### Closed Component
If you prefer a closed component composition, check out the snippet below.
If you want to automatically add the closed component to your project, run the
command:
```bash
npx @chakra-ui/cli snippet add slider
```
## Props
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| max | 100 | `number` | The maximum value of the slider |
| min | 0 | `number` | The minimum value of the slider |
| minStepsBetweenThumbs | 0 | `number` | The minimum permitted steps between multiple thumbs.
`minStepsBetweenThumbs` * `step` should reflect the gap between the thumbs.
- `step: 1` and `minStepsBetweenThumbs: 10` => gap is `10`
- `step: 10` and `minStepsBetweenThumbs: 2` => gap is `20` |
| orientation | horizontal | `'vertical' \| 'horizontal'` | The orientation of the component |
| origin | "start" | `'center' \| 'end' \| 'start'` | The origin of the slider range. The track is filled from the origin
to the thumb for single values.
- "start": Useful when the value represents an absolute value
- "center": Useful when the value represents an offset (relative)
- "end": Useful when the value represents an offset from the end |
| step | 1 | `number` | The step value of the slider |
| thumbAlignment | "contain" | `'center' \| 'contain'` | The alignment of the slider thumb relative to the track
- `center`: the thumb will extend beyond the bounds of the slider track.
- `contain`: the thumb will be contained within the bounds of the track. |
| 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 | `'outline' \| 'solid'` | 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. |
| aria-label | undefined | `string[]` | The aria-label of each slider thumb. Useful for providing an accessible name to the slider |
| aria-labelledby | undefined | `string[]` | The `id` of the elements that labels each slider thumb. Useful for providing an accessible name to the slider |
| defaultValue | undefined | `number[]` | The initial value of the slider when rendered.
Use when you don't need to control the value of the slider. |
| disabled | undefined | `boolean` | Whether the slider is disabled |
| form | undefined | `string` | The associate form of the underlying input element. |
| getAriaValueText | undefined | `(details: ValueTextDetails) => string` | Function that returns a human readable value for the slider thumb |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{\n root: string\n thumb: (index: number) => string\n hiddenInput: (index: number) => string\n control: string\n track: string\n range: string\n label: string\n valueText: string\n marker: (index: number) => string\n}>` | The ids of the elements in the slider. Useful for composition. |
| invalid | undefined | `boolean` | Whether the slider is invalid |
| name | undefined | `string` | The name associated with each slider thumb (when used in a form) |
| onFocusChange | undefined | `(details: FocusChangeDetails) => void` | Function invoked when the slider's focused index changes |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Function invoked when the value of the slider changes |
| onValueChangeEnd | undefined | `(details: ValueChangeDetails) => void` | Function invoked when the slider value change is done |
| readOnly | undefined | `boolean` | Whether the slider is read-only |
| thumbSize | undefined | `{ width: number; height: number }` | The slider thumbs dimensions |
| value | undefined | `number[]` | The controlled value of the slider |
## Explorer
Explore the `Slider` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Spinner
```tsx
import { Spinner } from "@chakra-ui/react"
export const SpinnerBasic = () => {
return
}
```
## Usage
```jsx
import { Spinner } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the spinner.
```tsx
import { HStack, Spinner } from "@chakra-ui/react"
export const SpinnerWithSizes = () => {
return (
)
}
```
### Colors
Use the `colorPalette` prop to change the color scheme of the spinner.
```tsx
import { Spinner, Stack } from "@chakra-ui/react"
export const SpinnerWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
))}
)
}
```
### Custom Color
Use the `color` prop to pass a custom color to the spinner.
```tsx
import { Spinner } from "@chakra-ui/react"
export const SpinnerCustomColor = () => {
return
}
```
### Track Color
Use the `--spinner-track-color` variable to change the color of the spinner's
track.
```tsx
import { Spinner } from "@chakra-ui/react"
export const SpinnerWithTrackColor = () => (
)
```
### Custom Speed
Use the `animationDuration` prop to change the speed of the spinner.
```tsx
import { Spinner } from "@chakra-ui/react"
export const SpinnerWithCustomSpeed = () => (
)
```
### Thickness
Use the `borderWidth` prop to change the thickness of the spinner.
```tsx
import { Spinner } from "@chakra-ui/react"
export const SpinnerWithCustomThickness = () => (
)
```
### Label
Compose the spinner with a label to provide additional context.
```tsx
import { Spinner, Text, VStack } from "@chakra-ui/react"
export const SpinnerWithLabel = () => {
return (
Loading...
)
}
```
### Overlay
Compose spinner with the `AbsoluteCenter` component to overlay the spinner on
top of another component.
```tsx
import { Box, Center, Heading, Spinner, Text } from "@chakra-ui/react"
export const SpinnerWithOverlay = () => {
return (
Some heading text
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac
consectetur libero, id ultricies urna. Sed ac consectetur libero, id
fames ac ante ipsum primis in faucibus.
)
}
```
## 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 | `'inherit' \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | 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. |
# Stack
```tsx
import { Stack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackBasic = () => {
return (
)
}
```
## Usage
By default, Stack applies `flex-direction: column` and `gap: 8px` to its
children.
```jsx
import { HStack, Stack, VStack } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Horizontal
Use the `direction` prop to change the direction of the stack.
```tsx
import { Stack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackHorizontal = () => {
return (
)
}
```
### HStack
Alternatively, you can use the `HStack` to create a horizontal stack and align
its children horizontally.
```tsx
import { HStack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackWithHstack = () => {
return (
)
}
```
### VStack
Use the `VStack` to create a vertical stack and align its children vertically.
```tsx
import { VStack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackWithVstack = () => {
return (
)
}
```
### Separator
Use the `separator` prop to add a separator between the stack items.
```tsx
import { Stack, StackSeparator } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackWithSeparator = () => {
return (
}>
)
}
```
### Responsive Direction
Use the `direction` prop to change the direction of the stack responsively.
```tsx
import { Stack } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const StackWithResponsiveDirection = () => {
return (
)
}
```
# Stat
```tsx
import { Stat } from "@chakra-ui/react"
export const StatBasic = () => {
return (
Unique visitors
192.1k
)
}
```
## Usage
```tsx
import { Stat } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Format Options
Use the `FormatNumber` component within `Stat.ValueText` to format the value.
```tsx
import { FormatNumber, Stat } from "@chakra-ui/react"
export const StatWithFormatOptions = () => {
return (
Revenue
)
}
```
### Indicator
Here's an example of how to display a statistic with an indicator.
```tsx
import { Badge, Stat } from "@chakra-ui/react"
export const StatWithIndicator = () => {
return (
Unique visitors
192.1k
1.9%
)
}
```
### Info Tip
Compose the `InfoTip` and `Stat.Label` components to display an info tip.
```tsx
import { Stat } from "@chakra-ui/react"
import { InfoTip } from "@/components/ui/toggle-tip"
export const StatWithInfoTip = () => {
return (
Unique
Some info
192.1k
)
}
```
### Value Unit
Here's an example of how to display a value with a unit.
```tsx
import { Stat } from "@chakra-ui/react"
export const StatWithValueUnit = () => {
return (
Time to complete
3 hr
20 min
)
}
```
### Progress Bar
Here's an example of how to display a statistic with a progress bar.
```tsx
import { FormatNumber, Progress, Stat } from "@chakra-ui/react"
export const StatWithProgressBar = () => {
return (
This week
+12% from last week
)
}
```
### Icon
Here's an example of how to display a statistic with an icon.
```tsx
import { HStack, Icon, Stat } from "@chakra-ui/react"
import { LuDollarSign } from "react-icons/lu"
export const StatWithIcon = () => {
return (
Sales
$4.24k
)
}
```
### Trend
Here's an example of how to display a statistic with a trend indicator.
```tsx
import { Badge, FormatNumber, HStack, Stat } from "@chakra-ui/react"
export const StatWithTrend = () => {
return (
Unique
12%
since last month
)
}
```
### Closed Component
Here's how to setup the Stat for a closed component composition.
## 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 `Stat` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Status
```tsx
import { HStack, Status } from "@chakra-ui/react"
export const StatusBasic = () => {
return (
)
}
```
## Usage
```tsx
import { Status } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Label
Render the label within the `Status.Root` component.
```tsx
import { HStack, Status } from "@chakra-ui/react"
export const StatusWithLabel = () => {
return (
Error
Info
Warning
Success
)
}
```
### Sizes
Use the `size` prop to change the size of the status component.
```tsx
import { For, HStack, Stack, Status } from "@chakra-ui/react"
export const StatusWithSizes = () => {
return (
{(size) => (
In Review
Error
Approved
)}
)
}
```
### Closed Component
Here's how to setup the Status 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 status
```
## 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. |
## Explorer
Explore the `Status` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Steps
```tsx
import { Button, ButtonGroup, Steps } from "@chakra-ui/react"
export const StepsBasic = () => {
return (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
## Usage
```tsx
import { Steps } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the steps component.
```tsx
import { Button, ButtonGroup, For, Stack, Steps } from "@chakra-ui/react"
export const StepsWithSizes = () => {
return (
{(size) => (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)}
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Variants
Use the `variant` prop to change the appearance of the steps component.
```tsx
import { Button, ButtonGroup, For, Stack, Steps } from "@chakra-ui/react"
export const StepsWithVariants = () => {
return (
{(variant) => (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)}
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Colors
Use the `colorPalette` prop to change the color scheme of the component.
```tsx
import { Button, ButtonGroup, For, Stack, Steps } from "@chakra-ui/react"
export const StepsWithColors = () => {
return (
{(colorPalette) => (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)}
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Trigger
Use the `Steps.Trigger` component to make the step clickable.
```tsx
import { Button, ButtonGroup, Steps } from "@chakra-ui/react"
export const StepsWithTrigger = () => {
return (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Vertical
Use the `orientation` prop to change the orientation of the steps component.
```tsx
import { Button, ButtonGroup, Stack, Steps } from "@chakra-ui/react"
export const StepsVertical = () => {
return (
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Controlled
Use the `step` and `onStepChange` props to control the current step of the steps
component.
```tsx
"use client"
import { Button, ButtonGroup, Steps } from "@chakra-ui/react"
import { useState } from "react"
export const StepsControlled = () => {
const [step, setStep] = useState(1)
return (
setStep(e.step)}
count={steps.length}
>
{steps.map((step, index) => (
{step.title}
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const steps = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Store
An alternative way to control the steps is to use the `RootProvider` component
and the `useSteps` store hook.
This way you can access the steps state and methods from outside the steps.
```tsx
"use client"
import {
Button,
ButtonGroup,
Code,
Stack,
Steps,
useSteps,
} from "@chakra-ui/react"
export const StepsWithStore = () => {
const steps = useSteps({
defaultStep: 1,
count: items.length,
})
return (
current step: {steps.value}
{items.map((step, index) => (
{step.title}
))}
{items.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const items = [
{
title: "Step 1",
description: "Step 1 description",
},
{
title: "Step 2",
description: "Step 2 description",
},
{
title: "Step 3",
description: "Step 3 description",
},
]
```
### Icon
Pass the `icon` prop to the `StepsItem` component to display an icon.
```tsx
import { Button, ButtonGroup, Steps } from "@chakra-ui/react"
import { LuCalendar, LuCheck, LuUser, LuWallet } from "react-icons/lu"
export const StepsWithIcon = () => {
return (
{steps.map((step, index) => (
} />
))}
{steps.map((step, index) => (
{step.description}
))}
All steps are complete!
)
}
const steps = [
{
icon: ,
description: "Contact Details",
},
{
icon: ,
description: "Payment",
},
{
icon: ,
description: "Book an Appointment",
},
]
```
### Description
Pass the `description` prop to the `StepsItem` component to display a
description.
```tsx
import { Box, Button, ButtonGroup, Steps } from "@chakra-ui/react"
export const StepsWithDescription = () => {
return (
{steps.map((step, index) => (
{step.title}
{step.description}
))}
{steps.map((step, index) => (
{step.content}
))}
All steps are complete!
)
}
const steps = [
{
title: "Step 1",
content: "Step 1 content",
description: "This step",
},
{
title: "Step 2",
content: "Step 2 content",
description: "That step",
},
{
title: "Step 3",
content: "Step 3 content",
description: "Final step",
},
]
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| orientation | horizontal | `'vertical' \| 'horizontal'` | The orientation of the component |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | solid | `'solid' \| 'subtle'` | 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. |
| count | undefined | `number` | The total number of steps |
| defaultStep | undefined | `number` | The initial value of the stepper when rendered.
Use when you don't need to control the value of the stepper. |
| ids | undefined | `ElementIds` | The custom ids for the stepper elements |
| linear | undefined | `boolean` | If `true`, the stepper requires the user to complete the steps in order |
| onStepChange | undefined | `(details: StepChangeDetails) => void` | Callback to be called when the value changes |
| onStepComplete | undefined | `VoidFunction` | Callback to be called when a step is completed |
| step | undefined | `number` | The controlled value of the stepper |
## Explorer
Explore the `Steps` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Switch
```tsx
import { Switch } from "@chakra-ui/react"
export const SwitchBasic = () => {
return (
Activate Chakra
)
}
```
## Usage
```tsx
import { Switch } from "@chakra-ui/react"
```
```tsx
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Shortcuts
The `Switch` component also provides a set of shortcuts for common use cases.
### SwitchControl
The `Switch.Control` renders the `Switch.Thumb` within it by default.
This works:
```tsx
```
This might be more concise, if you don't need to customize the thumb:
```tsx
```
## Examples
### Sizes
Pass the `size` prop to the `Switch.Root` component to change the size of the
switch component.
```tsx
import { For, HStack, Switch } from "@chakra-ui/react"
export const SwitchWithSizes = () => {
return (
{(size) => (
)}
)
}
```
### Variants
Pass the `variant` prop to the `Switch.Root` component to change the visual
style of the switch.
```tsx
import { For, HStack, Switch } from "@chakra-ui/react"
export const SwitchWithVariants = () => {
return (
{(variant) => (
)}
)
}
```
### Colors
Pass the `colorPalette` prop to the `Switch.Root` component to change the color
scheme of the component.
```tsx
import { Stack, Switch, Text } from "@chakra-ui/react"
export const SwitchWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
))}
)
}
```
### Controlled
Use the `checked` and `onCheckedChange` prop to control the state of the switch.
```tsx
"use client"
import { Switch } from "@chakra-ui/react"
import { useState } from "react"
export const SwitchControlled = () => {
const [checked, setChecked] = useState(false)
return (
setChecked(e.checked)}
>
)
}
```
### Hook Form
Here's an example of integrating the switch with `react-hook-form`.
```tsx
"use client"
import { Button, Field, Stack, Switch } 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({
active: z.boolean({ message: "Active is required" }),
})
type FormData = z.infer
export const SwitchWithHookForm = () => {
const {
handleSubmit,
control,
formState: { errors },
} = useForm({
resolver: standardSchemaResolver(formSchema),
})
return (
)
}
```
### Disabled
Pass the `disabled` prop to the `Switch.Root` component to disable the switch.
```tsx
import { Switch } from "@chakra-ui/react"
export const SwitchWithDisabled = () => {
return (
Activate Chakra
)
}
```
### Invalid
Pass the `invalid` prop to the `Switch.Root` component to indicate an error
state for the switch.
```tsx
import { Switch } from "@chakra-ui/react"
export const SwitchWithInvalid = () => {
return (
Activate Chakra
)
}
```
### Tooltip
Here's an example of how to compose a switch with a tooltip.
```tsx
import { Switch } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useId } from "react"
export const SwitchWithTooltip = () => {
const id = useId()
return (
Switch with tooltip
)
}
```
### Track Indicator
Use the `Switch.Indicator` component to display different indicators based on
the checked state.
```tsx
"use client"
import { Icon, Switch } from "@chakra-ui/react"
import { FaMoon, FaSun } from "react-icons/fa"
export const SwitchWithTrackIndicator = () => {
return (
}>
Switch me
)
}
```
### Thumb Indicator
Use the `Switch.ThumbIndicator` component to add an icon to the switch thumb.
```tsx
import { Switch } from "@chakra-ui/react"
import { HiCheck, HiX } from "react-icons/hi"
export const SwitchWithThumbIndicator = () => {
return (
}>
Switch me
)
}
```
### Closed Component
Here's how to setup the Switch 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 switch
```
Here's how to use the it
```tsx
Activate Chakra
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| value | "on" | `string \| number` | The value of switch input. Useful for form submission. |
| colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component |
| variant | solid | `'solid' \| 'raised'` | 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. |
| checked | undefined | `boolean` | The controlled checked state of the switch |
| disabled | undefined | `boolean` | Whether the switch is disabled. |
| ids | undefined | `Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string }>` | The ids of the elements in the switch. Useful for composition. |
| invalid | undefined | `boolean` | If `true`, the switch is marked as invalid. |
| label | undefined | `string` | Specifies the localized strings that identifies the accessibility elements and their states |
| name | undefined | `string` | The name of the input field in a switch
(Useful for form submission). |
| onCheckedChange | undefined | `(details: CheckedChangeDetails) => void` | Function to call when the switch is clicked. |
| readOnly | undefined | `boolean` | Whether the switch is read-only |
| required | undefined | `boolean` | If `true`, the switch input is marked as required, |
## Explorer
Explore the `Switch` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Table
```tsx
import { Table } from "@chakra-ui/react"
export const TableBasic = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
## Usage
```jsx
import { Table } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the table.
```tsx
import { For, Stack, Table } from "@chakra-ui/react"
export const TableWithSizes = () => {
return (
{(size) => (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Variants
Use the `variant` prop to change the appearance of the table.
```tsx
import { For, Stack, Table } from "@chakra-ui/react"
export const TableWithVariants = () => {
return (
{(variant) => (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Striped
Use the `striped` prop to add zebra-stripes to the table.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithStriped = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Caption
Use the `Table.Caption` component to add a caption to the table.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithCaption = () => {
return (
Product inventory and pricing information
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Caption Top
Use the `side` prop on `Table.Caption` to position the caption at the top of the
table.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithCaptionTop = () => {
return (
Product inventory and pricing information
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Column Border
Use the `showColumnBorder` prop to add borders between columns.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithColumnBorder = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Overflow
Render the `Table.ScrollArea` component to enable horizontal scrolling.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithOverflow = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Sticky Header
Use the `stickyHeader` prop to make the table header sticky.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithStickyHeader = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Sticky Column
Here's an example what uses `data-sticky` attributes to make table columns
sticky during horizontal scrolling.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithStickyColumn = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Highlight on Hover
Use the `interactive` prop to highlight rows on hover.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithInteractive = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Pagination
Here's an example of how to compose a table with pagination.
```tsx
"use client"
import {
ButtonGroup,
Heading,
IconButton,
Pagination,
Stack,
Table,
} from "@chakra-ui/react"
import { LuChevronLeft, LuChevronRight } from "react-icons/lu"
export const TableWithPagination = () => {
return (
Products
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
(
{page.value}
)}
/>
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Selection
Here's an example of how to add row selection with checkboxes to your table.
```tsx
"use client"
import { Checkbox, Table } from "@chakra-ui/react"
import { useState } from "react"
export const TableWithSelection = () => {
const [selection, setSelection] = useState([])
const indeterminate = selection.length > 0 && selection.length < items.length
const rows = items.map((item) => (
{
setSelection((prev) =>
changes.checked
? [...prev, item.name]
: selection.filter((name) => name !== item.name),
)
}}
>
{item.name}
{item.category}
${item.price}
))
return (
0}
onCheckedChange={(changes) => {
setSelection(
changes.checked ? items.map((item) => item.name) : [],
)
}}
>
Product
Category
Price
{rows}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Action Bar
Here's an example of how to compose a table with an action bar and checkboxes.
This is useful for showing actions for selected table rows.
```tsx
"use client"
import {
ActionBar,
Button,
Checkbox,
Kbd,
Portal,
Table,
} from "@chakra-ui/react"
import { useState } from "react"
export const TableWithSelectionActionBar = () => {
const [selection, setSelection] = useState([])
const hasSelection = selection.length > 0
const indeterminate = hasSelection && selection.length < items.length
const rows = items.map((item) => (
{
setSelection((prev) =>
changes.checked
? [...prev, item.name]
: selection.filter((name) => name !== item.name),
)
}}
>
{item.name}
{item.category}
${item.price}
))
return (
<>
0}
onCheckedChange={(changes) => {
setSelection(
changes.checked ? items.map((item) => item.name) : [],
)
}}
>
Product
Category
Price
{rows}
{selection.length} selected
>
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Column Group
Use the `Table.ColumnGroup` component to distribute the column widths using the
html `colgroup` element.
:::warning
The only prop that works for this component is `htmlWidth`
:::
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithColumnGroup = () => {
return (
Product
Category
Price
{items.map((item) => (
{item.name}
{item.category}
{item.price}
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99 },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: 49.99 },
{ id: 3, name: "Desk Chair", category: "Furniture", price: 150.0 },
{ id: 4, name: "Smartphone", category: "Electronics", price: 799.99 },
{ id: 5, name: "Headphones", category: "Accessories", price: 199.99 },
]
```
### Native Mode
Use the `native` prop to render table descendants using native HTML elements
(``, ``, ``, `| `, ` | `) instead of Chakra's styled
components.
> This is a great way to improve performance for large tables by eliminating the
> runtime styling and React Context overhead.
```tsx
import { Table } from "@chakra-ui/react"
export const TableWithNative = () => {
return (
| Product |
Category |
Price |
{items.map((item) => (
| {item.name} |
{item.category} |
{item.price} |
))}
)
}
const items = [
{ id: 1, name: "Laptop", category: "Electronics", price: "$999.00" },
{ id: 2, name: "Coffee Maker", category: "Home Appliances", price: "$49.99" },
{ id: 3, name: "Desk Chair", category: "Furniture", price: "$150.00" },
{ id: 4, name: "Smartphone", category: "Electronics", price: "$799.99" },
{ id: 5, name: "Headphones", category: "Accessories", price: "$199.99" },
]
```
### TanStack Table
Chakra UI works seamlessly with
[TanStack Table](https://tanstack.com/table/latest) for advanced table features.
```tsx
"use client"
import { Table } from "@chakra-ui/react"
import {
createColumnHelper,
flexRender,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
type Product = {
id: number
name: string
category: string
price: number
stock: number
}
const columnHelper = createColumnHelper()
const columns = [
columnHelper.accessor("name", {
header: "Product",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("category", {
header: "Category",
cell: (info) => info.getValue(),
}),
columnHelper.accessor("price", {
header: "Price",
cell: (info) => `${info.getValue().toFixed(2)}`,
}),
columnHelper.accessor("stock", {
header: "Stock",
cell: (info) => info.getValue(),
}),
]
export const TableWithTanstack = () => {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
})
return (
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
|
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
|
))}
))}
{table.getRowModel().rows.map((row) => (
{row.getVisibleCells().map((cell) => (
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
))}
))}
)
}
const data: Product[] = [
{ id: 1, name: "Laptop", category: "Electronics", price: 999.99, stock: 50 },
{
id: 2,
name: "Coffee Maker",
category: "Home Appliances",
price: 49.99,
stock: 120,
},
{
id: 3,
name: "Desk Chair",
category: "Furniture",
price: 150.0,
stock: 30,
},
{
id: 4,
name: "Smartphone",
category: "Electronics",
price: 799.99,
stock: 75,
},
{
id: 5,
name: "Headphones",
category: "Accessories",
price: 199.99,
stock: 200,
},
]
```
## 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 | line | `'line' \| 'outline'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg'` | The size of the component |
| native | undefined | `boolean \| undefined` | If `true`, the table will style its descendants with nested selectors |
| 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. |
| interactive | undefined | `'true' \| 'false'` | The interactive of the component |
| stickyHeader | undefined | `'true' \| 'false'` | The stickyHeader of the component |
| striped | undefined | `'true' \| 'false'` | The striped of the component |
| showColumnBorder | undefined | `'true' \| 'false'` | The showColumnBorder of the component |
## Explorer
Explore the `Table` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Tabs
```tsx
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsBasic = () => {
return (
Members
Projects
Settings
Manage your team members
Manage your projects
Manage your tasks for freelancers
)
}
```
## Usage
```jsx
import { Tabs } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Variants
Use the `variant` prop to change the visual style of the tabs.
```tsx
import { For, SimpleGrid, Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsWithVariants = () => {
return (
{(variant) => (
Members
Projects
Settings
Manage your team members
Manage your projects
Manage your tasks for freelancers
)}
)
}
```
### Lazy Mounted
Use the `lazyMount` and/or `unmountOnExit` prop to only render the tab content
when it is active. This can be useful for performance optimization.
```tsx
"use client"
import { Tabs } from "@chakra-ui/react"
import { useEffect, useState } from "react"
export const TabsLazyMounted = () => {
return (
Tab 1
Tab 2
Tab 3
Tab 1: Content
Tab 2: Content
Tab 3: Content
)
}
const TickValue = () => {
const [value, setValue] = useState(0)
useEffect(() => {
const intervalId = window.setInterval(() => {
setValue((v) => v + 1)
}, 1000)
return () => {
window.clearInterval(intervalId)
}
}, [])
return (
{value}
)
}
```
### Indicator
Render the `Tabs.Indicator` component to display a visual indicator of the
active tab.
```tsx
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsWithIndicator = () => {
return (
Members
Projects
Settings
Manage your team members
Manage your projects
Manage your tasks for freelancers
)
}
```
### Custom Indicator
Customize the indicator appearance using CSS variables like
`--tabs-indicator-bg` and `--tabs-indicator-shadow`.
```tsx
import { Tabs } from "@chakra-ui/react"
export const TabsWithCustomIndicator = () => {
return (
Members
Projects
Settings
Manage your team members
Manage your projects
Manage your settings
)
}
```
### Links
Pass the `asChild` to the `Tabs.Trigger` component to render a link as a tab.
When a tab is clicked, the link will be navigated to.
```tsx
import { Link, Tabs } from "@chakra-ui/react"
export const TabsWithLinks = () => {
return (
Members
Projects
Manage your team members
Manage your projects
)
}
```
When using custom router links, you need to set the `navigate` prop on the
`Tabs.Root` component.
```tsx
"use client"
import { Tabs } from "@chakra-ui/react"
import { useNavigate } from "react-router-dom"
const Demo = () => {
const navigate = useNavigate()
return (
navigate(`/${value}`)}>
{/* ... */}
)
}
```
### Fitted
Use the `fitted` prop to make the tabs fit the width of the container.
```tsx
import { Tabs } from "@chakra-ui/react"
export const TabsWithFitted = () => {
return (
Tab 1
Tab 2
Tab 3
)
}
```
### Controlled
Use the `value` and `onValueChange` prop to control the active tab.
```tsx
"use client"
import { Tabs } from "@chakra-ui/react"
import { useState } from "react"
export const TabsControlled = () => {
const [value, setValue] = useState("first")
return (
setValue(e.value)}>
First tab
Second tab
First panel
Second panel
)
}
```
### Store
An alternative way to control the tabs is to use the `RootProvider` component
and the `useTabs` store hook.
This way you can access the tabs state and methods from outside the tabs.
```tsx
"use client"
import { Code, Stack, Tabs, useTabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsWithStore = () => {
const tabs = useTabs({
defaultValue: "members",
})
return (
selected: {tabs.value}
Members
Projects
Tasks
Manage your team members
Manage your projects
Manage your tasks for freelancers
)
}
```
### Disabled Tab
Set the `disabled` prop on the `Tabs.Trigger` component to disable a tab.
```tsx
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsWithDisabledTab = () => {
return (
Members
Projects
Settings
{/* content */}
)
}
```
### Manual activation
By default, the tabs are selected when the arrow keys are pressed. Disable this
behavior by setting the `activationBehavior` prop to `manual`.
In this mode, the tabs will only be selected when clicked or the enter key is
pressed.
```tsx
import { Tabs } from "@chakra-ui/react"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TabsWithManualActivation = () => {
return (
Members
Projects
Settings
{/* content */}
)
}
```
### Dynamic
Here's an example of how to dynamically add and remove tabs.
```tsx
"use client"
import { Button, CloseButton, Heading, Tabs, Text } from "@chakra-ui/react"
import { useState } from "react"
import { LuPlus } from "react-icons/lu"
interface Item {
id: string
title: string
content: React.ReactNode
}
const items: Item[] = [
{ id: "1", title: "Tab", content: "Tab Content" },
{ id: "2", title: "Tab", content: "Tab Content" },
{ id: "3", title: "Tab", content: "Tab Content" },
{ id: "4", title: "Tab", content: "Tab Content" },
]
const uuid = () => {
return Math.random().toString(36).substring(2, 15)
}
export const TabsWithDynamicAdd = () => {
const [tabs, setTabs] = useState- (items)
const [selectedTab, setSelectedTab] = useState(items[0].id)
const addTab = () => {
const newTabs = [...tabs]
const uid = uuid()
newTabs.push({
id: uid,
title: `Tab`,
content: `Tab Body`,
})
setTabs(newTabs)
setSelectedTab(newTabs[newTabs.length - 1].id)
}
const removeTab = (id: string) => {
if (tabs.length > 1) {
const newTabs = [...tabs].filter((tab) => tab.id !== id)
setTabs(newTabs)
}
}
return (
setSelectedTab(e.value)}
>
{tabs.map((item) => (
{item.title}{" "}
{
e.stopPropagation()
removeTab(item.id)
}}
/>
))}
{tabs.map((item) => (
{item.content} {item.id}
Dolore ex esse laboris elit magna esse sunt. Pariatur in veniam
Lorem est occaecat do magna nisi mollit ipsum sit adipisicing
fugiat ex. Pariatur ullamco exercitation ea qui adipisicing. Id
cupidatat aute id ut excepteur exercitation magna pariatur. Mollit
irure irure reprehenderit pariatur eiusmod proident Lorem deserunt
duis cillum mollit.
))}
)
}
```
### Responsive Orientation
Responsive values are not supported for the `orientation` prop because it
affects keyboard navigation and `aria-orientation` behavior, not just styling.
The orientation changes how arrow keys work (horizontal uses left/right,
vertical uses up/down).
To achieve responsive orientation, use the `useBreakpointValue` hook to change
the orientation based on the screen size.
```tsx
"use client"
import { Tabs, useBreakpointValue } from "@chakra-ui/react"
export const TabsWithResponsiveOrientation = () => {
const orientation = useBreakpointValue<"horizontal" | "vertical">({
base: "horizontal",
md: "vertical",
})
return (
Members
Projects
Settings
Manage your team members and their roles here.
Manage your projects and their status here.
Manage your tasks and their progress here.
)
}
```
### Animation
Use the `_open` and `_close` conditional props to animate the tabs.
```tsx
import { Box, Flex, Tabs } from "@chakra-ui/react"
const items = [
{
title: "1",
content: "Dolore ex esse laboris elit magna esse sunt",
},
{
title: "2",
content:
"Pariatur in veniam Lorem est occaecat do magna nisi mollit ipsum sit adipisicing fugiat ex.",
},
]
export const TabsWithAnimation = () => {
return (
{items.map((item, index) => (
Tab {item.title}
))}
{items.map((item, index) => (
{item.content}
))}
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| activationMode | "automatic" | `'manual' \| 'automatic'` | The activation mode of the tabs. Can be `manual` or `automatic`
- `manual`: Tabs are activated when clicked or press `enter` key.
- `automatic`: Tabs are activated when receiving focus |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| loopFocus | true | `boolean` | Whether the keyboard navigation will loop from last tab to first, and vice versa. |
| orientation | "horizontal" | `'horizontal' \| 'vertical'` | The orientation of the tabs. Can be `horizontal` or `vertical`
- `horizontal`: only left and right arrow key navigation will work.
- `vertical`: only up and down arrow key navigation will work. |
| 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 | `'sm' \| 'md' \| 'lg'` | The size of the component |
| variant | line | `'line' \| 'subtle' \| 'enclosed' \| 'outline' \| '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. |
| composite | undefined | `boolean` | Whether the tab is composite |
| defaultValue | undefined | `string` | The initial selected tab value when rendered.
Use when you don't need to control the selected tab value. |
| deselectable | undefined | `boolean` | Whether the active tab can be deselected when clicking on it. |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ root: string; trigger: string; list: string; content: string; indicator: string }>` | The ids of the elements in the tabs. Useful for composition. |
| navigate | undefined | `(details: NavigateDetails) => void` | Function to navigate to the selected tab when clicking on it.
Useful if tab triggers are anchor elements. |
| onFocusChange | undefined | `(details: FocusChangeDetails) => void` | Callback to be called when the focused tab changes |
| onValueChange | undefined | `(details: ValueChangeDetails) => void` | Callback to be called when the selected/active tab changes |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| value | undefined | `string` | The controlled selected tab value |
| fitted | undefined | `'true' \| 'false'` | The fitted of the component |
| justify | undefined | `'start' \| 'center' \| 'end'` | The justify of the component |
### Trigger
| 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. |
## Explorer
Explore the `Tabs` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Tag
```tsx
import { HStack, Tag } from "@chakra-ui/react"
export const TagBasic = () => {
return (
Plain Tag
Closable Tag
)
}
```
## Usage
```tsx
import { Tag } from "@chakra-ui/react"
```
```tsx
Tag here
```
:::info
If you prefer a closed component composition, check out the
[snippet below](#closed-component).
:::
## Examples
### Icon
Use the `Tag.StartElement` and `Tag.EndElement` components to add an icon to the
start or end of the tag
```tsx
import { HStack, Tag } from "@chakra-ui/react"
import { LuCircleUser, LuFileBadge } from "react-icons/lu"
export const TagWithIcon = () => {
return (
Tag 1
Top Rated
Tag 2
)
}
```
### Variants
Use the `variant` prop to change the appearance of the tag.
```tsx
import { For, HStack, Stack, Tag } from "@chakra-ui/react"
import { HiCheck } from "react-icons/hi"
export const TagWithVariants = () => {
return (
{(variant) => (
Gray
Gray
Gray
)}
)
}
```
### Sizes
Use the `size` prop to change the size of the tag.
```tsx
import { For, HStack, Stack, Tag } from "@chakra-ui/react"
import { HiCheck } from "react-icons/hi"
export const TagWithSizes = () => {
return (
{(size) => (
Gray
Gray
Gray
)}
)
}
```
### Colors
Use the `colorPalette` prop to change the color of the tag.
```tsx
import { Stack, Tag, Text } from "@chakra-ui/react"
import { HiPlus } from "react-icons/hi"
export const TagWithColors = () => {
return (
{["gray","red","green","blue","teal","pink","purple","cyan","orange","yellow"].map((colorPalette) => (
{colorPalette}
Content
Content
Content
))}
)
}
```
### Closable
Use the `Tag.CloseTrigger` within the `Tag.EndElement` to make the tag closable.
```tsx
import { HStack, Tag } from "@chakra-ui/react"
import { LuActivity } from "react-icons/lu"
export const TagWithClose = () => {
return (
Tag 1
Tag 2
)
}
```
### Overflow
Use the `maxWidth` prop to control the maximum width of the tag. When the
content exceeds this width, it will be truncated with an ellipsis.
> This is particularly useful when dealing with dynamic or user-generated
> content where the length might vary.
```tsx
import { Tag } from "@chakra-ui/react"
export const TagWithOverflow = () => {
return (
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam
molestias, laboriosam, quod, quia quidem quae voluptatem natus
exercitationem autem quibusdam
)
}
```
### Avatar
The tag component has been designed to work well with the `Avatar` component.
> Note: Set the avatar size to `full` to ensure it's sized correctly.
```tsx
import { Avatar, For, HStack, Tag } from "@chakra-ui/react"
export const TagWithAvatar = () => {
return (
{(size) => (
Emily {size}
)}
)
}
```
### Render as button
Use the `asChild` prop to render the tag as a button.
```tsx
import { Tag } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const TagAsButton = () => {
return (
)
}
```
### Closed Component
Here's how to setup the Tag 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 tag
```
## 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' \| 'xl'` | The size of the component |
| variant | surface | `'subtle' \| 'solid' \| 'outline' \| 'surface'` | 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 `Tag` component parts interactively. Click on parts in the sidebar
to highlight them in the preview.
# Tags Input
```tsx
"use client"
import { Span, TagsInput } from "@chakra-ui/react"
export const TagsInputBasic = () => {
return (
Tags
Press Enter or Return to add tag
)
}
```
## Usage
```jsx
import { TagsInput } from "@chakra-ui/react"
```
```jsx
```
## Shortcuts
The `TagsInput` component also provides a set of shortcuts for common use cases.
### TagsInputItems
The `TagsInputItems` shortcut renders all tag items automatically based on the
current value.
This works:
```jsx
{({ value }) =>
value.map((tag, index) => (
{tag}
))
}
```
This might be more concise, if you don't need to customize the items:
```jsx
```
## Examples
### Sizes
Use the `size` prop to adjust the size of the tags input.
```tsx
"use client"
import { For, Span, Stack, TagsInput } from "@chakra-ui/react"
export const TagsInputWithSizes = () => {
return (
{(size) => (
Tags (size={size})
Press Enter or Return to add tag
)}
)
}
```
### Variants
Use the `variant` prop to change the visual style of the tags input.
```tsx
"use client"
import { For, Span, Stack, TagsInput } from "@chakra-ui/react"
export const TagsInputWithVariants = () => {
return (
{(variant) => (
Tags (variant={variant})
Press Enter or Return to add tag
)}
)
}
```
### Controlled
Use the `value` and `onValueChange` props to programmatically control the tags.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
import { useState } from "react"
export const TagsInputControlled = () => {
const [tags, setTags] = useState(["React", "Chakra"])
return (
setTags(details.value)}
>
Tags
)
}
```
### Store
An alternative way to control the tags input is to use the `RootProvider`
component and the `useTagsInput` store hook.
This way you can access the tags input state and methods from outside the
component.
> Use `RootProvider + useTagsInput` or `Root`, not both.
```tsx
"use client"
import { Button, Stack, TagsInput } from "@chakra-ui/react"
import { useTagsInput } from "@chakra-ui/react"
export const TagsInputWithStore = () => {
const tags = useTagsInput()
return (
Tags: {JSON.stringify(tags.value)}
)
}
```
### Max Tags
Pass the `max` prop to the `TagsInput.Root` component to limit the number of
tags that can be added.
```tsx
"use client"
import { Badge, Button, HStack, Span, TagsInput } from "@chakra-ui/react"
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
const isValidEmail = (value: string) => EMAIL_REGEX.test(value)
export const TagsInputWithMax = () => {
return (
isValidEmail(e.inputValue)}
defaultValue={["sage@company.com"]}
>
Invite guests (max 3)
{({ value }) => (
You've invited {value.length} / 3 guests to your
event
)}
)
}
```
### Editable Tags
Use the `editable` prop to enable inline editing of existing tags by clicking on
them, allowing users to quickly update tag values.
```tsx
"use client"
import { Span, TagsInput } from "@chakra-ui/react"
export const TagsInputEditable = () => (
Edit Tags Inline
Use the arrow keys to navigate and press Enter to edit
)
```
### Validate Tag
Use the `validate` prop to implement custom validation rules. Tags will be added
when the validation passes.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
export const TagsInputValidation = () => (
e.inputValue.length >= 3}
>
Tags (min 3 chars)
)
```
### Disabled
Use the `disabled` prop to disable the tags input to prevent user interaction.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
export const TagsInputDisabled = () => (
Disabled Tags
)
```
### Readonly
Use the `readOnly` prop to make the tags input read-only. Tags input can be
focused but can't be modified.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
export const TagsInputReadOnly = () => (
Read Only Tags
)
```
### Invalid
Pass the `invalid` prop to the `TagsInput.Root` component to display the tags
input in an invalid state with error messages.
```tsx
"use client"
import { Field, TagsInput } from "@chakra-ui/react"
export const TagsInputInvalid = () => (
Invalid Tags
This is an error
)
```
### Field
Here's an example that composes the `TagsInput.Root` with the `Field` component
to add labels, helper text, and error messages.
```tsx
"use client"
import { Field, TagsInput } from "@chakra-ui/react"
export const TagsInputWithField = () => {
return (
Enter tags
Add emails separated by commas
)
}
```
### Form
Here's an example that composes the `TagsInput.Root` with a `form` to collect
structured data and handle submissions.
```tsx
"use client"
import { Button, Field, Input, Stack, TagsInput } from "@chakra-ui/react"
export const TagsInputWithForm = () => {
return (
)
}
```
### Paste
Pass the `addOnPaste` prop to the `TagsInput.Root` component to allow users to
paste multiple values at once, automatically splitting them into individual tags
based on a delimiter.
```tsx
"use client"
import { Box, Clipboard, IconButton, Stack, TagsInput } from "@chakra-ui/react"
export const TagsInputWithPaste = () => (
Paste Tags
)
const SampleClipboard = (props: { value: string }) => (
Copy Tags
)
```
### Blur Behavior
Use the `blurBehavior` prop to configure how the input behaves when it loses
focus, such as automatically creating a tag from the current input value.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
export const TagsInputWithBlurBehavior = () => (
Create Tag on Blur
)
```
### Custom Delimiter
Use the `delimiter` prop to use custom delimiters like commas, semicolons, or
spaces to create new tags as users type.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
const SPLIT_REGEX = /[;,]/
export const TagsInputWithDelimiter = () => (
Custom Delimiters (; ,)
)
```
### Colors
Here's an example that assigns rather color scheme to the tags based on the tag
value.
```tsx
"use client"
import { TagsInput } from "@chakra-ui/react"
export const TagsInputWithColors = () => (
Colored Tags
{({ value }) =>
value.map((tag, index) => (
{tag}
))
}
)
const randomColor = (str: string) => {
// Simple hash from string
let hash = 0
for (let i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash)
}
// Generate light HSL color (H: 0-359, S: 60-80%, L: 85-94%)
const h = Math.abs(hash) % 360
const s = 60 + (Math.abs(hash) % 20) // 60% - 79%
const l = 85 + (Math.abs(hash) % 10) // 85% - 94%
return `hsl(${h},${s}%,${l}%)`
}
```
### Combobox
Here's an example that composes the `TagsInput` component with the `Combobox`
component to create a tags input that allows users to select from a list of
predefined tags.
```tsx
"use client"
import {
Combobox,
TagsInput,
useCombobox,
useFilter,
useListCollection,
useTagsInput,
} from "@chakra-ui/react"
import { useId, useRef } from "react"
export const TagsInputWithCombobox = () => {
const { contains } = useFilter({ sensitivity: "base" })
const { collection, filter } = useListCollection({
initialItems: [
"React",
"Chakra",
"TypeScript",
"Next.js",
"Ark UI",
"Zag.js",
],
filter: contains,
})
const inputId = useId()
const controlRef = useRef(null)
const tags = useTagsInput({
ids: { input: inputId },
})
const comobobox = useCombobox({
ids: { input: inputId },
collection,
onInputValueChange(e) {
filter(e.inputValue)
},
positioning: {
getAnchorRect() {
return controlRef.current!.getBoundingClientRect()
},
},
value: [],
allowCustomValue: true,
onValueChange: (e) => tags.addValue(e.value[0]),
selectionBehavior: "clear",
})
return (
Tags
{tags.value.map((tag, index) => (
{tag}
))}
No tags found
{collection.items.map((item) => (
{item}
))}
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| addOnPaste | false | `boolean` | Whether to add a tag when you paste values into the tag input |
| delimiter | "," | `string \| RegExp` | The character that serves has:
- event key to trigger the addition of a new tag
- character used to split tags when pasting into the input |
| editable | true | `boolean` | Whether a tag can be edited after creation, by pressing `Enter` or double clicking. |
| max | Infinity | `number` | The max number of tags |
| 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. |
| allowOverflow | undefined | `boolean` | Whether to allow tags to exceed max. In this case,
we'll attach `data-invalid` to the root |
| autoFocus | undefined | `boolean` | Whether the input should be auto-focused |
| blurBehavior | undefined | `'clear' \| 'add'` | The behavior of the tags input when the input is blurred
- `"add"`: add the input value as a new tag
- `"clear"`: clear the input value |
| defaultInputValue | undefined | `string` | The initial tag input value when rendered.
Use when you don't need to control the tag input value. |
| defaultValue | undefined | `string[]` | The initial tag value when rendered.
Use when you don't need to control the tag value. |
| disabled | undefined | `boolean` | Whether the tags input should be 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 input: string\n hiddenInput: string\n clearBtn: string\n label: string\n control: string\n item: (opts: ItemProps) => string\n itemDeleteTrigger: (opts: ItemProps) => string\n itemInput: (opts: ItemProps) => string\n}>` | The ids of the elements in the tags input. Useful for composition. |
| inputValue | undefined | `string` | The controlled tag input's value |
| invalid | undefined | `boolean` | Whether the tags input is invalid |
| maxLength | undefined | `number` | The max length of the input. |
| name | undefined | `string` | The name attribute for the input. Useful for form submissions |
| onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component |
| onHighlightChange | undefined | `(details: HighlightChangeDetails) => void` | Callback fired when a tag is highlighted by pointer or keyboard navigation |
| onInputValueChange | undefined | `(details: InputValueChangeDetails) => void` | Callback fired when the input value is updated |
| 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` | Callback fired when the tag values is updated |
| onValueInvalid | undefined | `(details: ValidityChangeDetails) => void` | Callback fired when the max tag count is reached or the `validateTag` function returns `false` |
| readOnly | undefined | `boolean` | Whether the tags input should be read-only |
| required | undefined | `boolean` | Whether the tags input is required |
| translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states |
| validate | undefined | `(details: ValidateArgs) => boolean` | Returns a boolean that determines whether a tag can be added.
Useful for preventing duplicates or invalid tag values. |
| value | undefined | `string[]` | The controlled tag value |
### Item
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| index | undefined | `string \| number` | undefined |
| value | undefined | `string` | 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. |
| disabled | undefined | `boolean` | undefined |
## Explorer
Explore the `TagsInput` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Text
```tsx
import { Text } from "@chakra-ui/react"
export const TextBasic = () => {
return Sphinx of black quartz, judge my vow.
}
```
## Usage
```jsx
import { Text } from "@chakra-ui/react"
```
```jsx
This is the text component
```
## Examples
### Sizes
Use the `fontSize` or `textStyle` prop to change the size of the text.
```tsx
import { Stack, Text } from "@chakra-ui/react"
export const TextWithSizes = () => {
return (
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
Chakra
)
}
```
### Weights
Use the `fontWeight` prop to change the weight of the text.
```tsx
import { Stack, Text } from "@chakra-ui/react"
export const TextWithWeights = () => {
return (
Sphinx of black quartz, judge my vow.
Sphinx of black quartz, judge my vow.
Sphinx of black quartz, judge my vow.
Sphinx of black quartz, judge my vow.
Sphinx of black quartz, judge my vow.
)
}
```
### Truncation
Use the `truncate` prop to truncate the text after a single line.
```tsx
import { Flex, Text } from "@chakra-ui/react"
export const TextWithTruncate = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
)
}
```
### Line Clamp
Use the `lineClamp` prop to truncate the text after a certain number of lines.
```tsx
import { Flex, Text } from "@chakra-ui/react"
export const TextWithLineClamp = () => {
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.
)
}
```
### Ref
Here's how to access the underlying element reference
```tsx
const Demo = () => {
const ref = useRef(null)
return This is the text component
}
```
# Textarea
```tsx
import { Textarea } from "@chakra-ui/react"
export const TextareaBasic = () => {
return
}
```
## Usage
```jsx
import { Textarea } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Variants
Use the `variant` prop to change the appearance of the textarea.
```tsx
import { Stack, Textarea } from "@chakra-ui/react"
export const TextareaWithVariants = () => {
return (
)
}
```
### Sizes
Use the `size` prop to change the size of the textarea.
```tsx
import { Stack, Textarea } from "@chakra-ui/react"
export const TextareaWithSizes = () => {
return (
)
}
```
### Helper Text
Pair the textarea with the `Field` component to add helper text.
```tsx
import { Field, HStack, Textarea } from "@chakra-ui/react"
export const TextareaWithHelperText = () => {
return (
Comment
Max 500 characters.
Comment
Max 500 characters.
)
}
```
### Error Text
Pair the textarea with the `Field` component to add error text.
```tsx
import { Field, HStack, Textarea } from "@chakra-ui/react"
export const TextareaWithErrorText = () => {
return (
Comment
Field is required
Comment
Field is required
)
}
```
### Field
Compose the textarea 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 textarea with `react-hook-form`.
```tsx
"use client"
import { Button, Field, Input, Stack, Textarea } from "@chakra-ui/react"
import { useForm } from "react-hook-form"
interface FormValues {
username: string
bio: string
}
export const TextareaWithHookForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm()
const onSubmit = handleSubmit((data) => console.log(data))
return (
)
}
```
### Resize
Use the `resize` prop to control the resize behavior of the textarea.
```tsx
import { Stack, Textarea } from "@chakra-ui/react"
export const TextareaWithResize = () => {
return (
)
}
```
To limit the maximum height (or rows) of the textarea, we recommend using the
`maxHeight` prop and setting the value to a `lh` unit.
```tsx
```
### Autoresize
Use the `autoresize` prop to make the textarea autoresize vertically as you
type.
```tsx
import { Textarea } from "@chakra-ui/react"
export const TextareaWithAutoresize = () => {
return
}
```
### Ref
Here's how to access the underlying element reference
```tsx
const Demo = () => {
const ref = useRef(null)
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' \| 'xl'` | 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. |
# Theme
```tsx
import { Button, Stack, Theme } from "@chakra-ui/react"
export const ThemeBasic = () => {
return (
)
}
```
## Usage
```jsx
import { Theme } from "@chakra-ui/react"
```
```jsx
```
## Examples
### Nested
The theme can be nested to apply different appearances to different parts of the
tree. This is useful for applying a global appearance and then overriding some
parts of it.
> Good to know: We use native CSS selectors to achieve this.
```tsx
import { Box, Button, Theme } from "@chakra-ui/react"
export const ThemeNested = () => {
return (
Hello Normal
Hello Dark
Hello Light
)
}
```
### Portalled
Use the `asChild` prop to force the appearance of portalled elements like the
popover and modal content.
```tsx
import { Button, Input, Popover, Portal, Text, Theme } from "@chakra-ui/react"
export const ThemeWithPortalled = () => {
return (
Naruto Form
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
)
}
```
### Page Specific Color Mode
To lock a page to a specific color mode (light or dark), wrap the entire page
with the `Theme` component.
You can also combine it with the `ColorModeProvider` if you use the
`useColorMode` hook.
```tsx
import { ColorModeProvider } from "@/components/ui/color-mode"
import { Theme } from "@chakra-ui/react"
export const ForcedColorMode = ({ children }) => {
return (
{/* Rest of the page */}
)
}
```
# Timeline
```tsx
import { Text, Timeline } from "@chakra-ui/react"
import { LuCheck, LuPackage, LuShip } from "react-icons/lu"
export const TimelineBasic = () => {
return (
Product Shipped
13th May 2021
We shipped your product via FedEx and it should
arrive within 3-5 business days.
Order Confirmed
18th May 2021
Order Delivered
20th May 2021, 10:30am
)
}
```
## Usage
```tsx
import { Timeline } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Sizes
Use the `size` prop to change the size of the timeline.
```tsx
import { Avatar, Badge, For, Span, Stack, Timeline } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const TimelineWithSizes = () => {
return (
{(size) => (
sage
created a new project
sage
changed status from
In progress
to{" "}
Completed
)}
)
}
```
### Variants
Use the `variant` prop to change the variant of the timeline.
```tsx
import { Avatar, Badge, For, Span, Stack, Timeline } from "@chakra-ui/react"
import { LuCheck } from "react-icons/lu"
export const TimelineWithVariants = () => {
return (
{(variant) => (
sage
created a new project
sage
changed status from In progress to{" "}
Completed
)}
)
}
```
### Content Before
Here's an example of a timeline with content before the timeline indicator.
```tsx
import { For, Stack, Timeline } from "@chakra-ui/react"
export const TimelineWithContentBefore = () => {
return (
{(size) => (
Nov 1994
1
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nov 2010
2
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
)}
)
}
```
### Alternating Content
Here's an example of a timeline with alternating content.
```tsx
import { Timeline } from "@chakra-ui/react"
export const TimelineAlternating = () => {
return (
Placed Order
Prepared Order
Order Delivered
)
}
```
### Composition
Here's an example of how to compose the timeline with other components to create
a consistent-looking timeline.
```tsx
import {
Avatar,
Button,
Card,
Icon,
Input,
Span,
Timeline,
} from "@chakra-ui/react"
import { LuPen, LuX } from "react-icons/lu"
import LoremIpsum from "react-lorem-ipsum"
export const TimelineComposition = () => {
return (
Lucas Moras has changed
3 labels on
Jan 1, 2024
Jenna Smith removed
Enas
on Jan 12, 2024
Erica commented
on Jan 12, 2024
)
}
```
## 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 | solid | `'subtle' \| 'solid' \| 'outline' \| 'plain'` | The variant of the component |
| size | md | `'sm' \| 'md' \| 'lg' \| 'xl'` | 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 `Timeline` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Toast
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterBasic = () => {
return (
)
}
```
## Setup
If you don't already have the snippet, run the following command to add the
`toaster` snippet
```sh
npx @chakra-ui/cli snippet add toaster
```
The snippet includes a closed component composition for the `Toast` component.
## Usage
```jsx
import { Toaster, toaster } from "@/components/ui/toaster"
```
First, render the `Toaster` component in your app.
```jsx
```
Then, create a toast by calling the `toaster` function.
```jsx
toaster.create({
title: "Toast Title",
description: "Toast Description",
})
```
## Examples
### Closable Toast
Set the `closable` prop to `true` to create a closable toast.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterClosable = () => {
return (
)
}
```
### External Close
Use the `toaster.dismiss` method to close a toast.
- `toaster.dismiss(id)`: Dismiss a toast by its id.
- `toaster.dismiss()`: Dismiss all toasts.
```tsx
"use client"
import { Button, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithExternalClose = () => {
return (
)
}
```
### Types
Here's an example of each type of toast.
```tsx
"use client"
import { Button, For, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithStatus = () => {
return (
{(type) => (
)}
)
}
```
### With Action
Use the `action` and `actionLabel` prop to add an action to the toast.
> When the action trigger is clicked, the toast will be closed.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithAction = () => {
return (
)
}
```
### Persistent Toast
Set the `type` prop to `"loading"` to create a persistent toast.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterPersistent = () => {
return (
)
}
```
### Promise
Use the `toaster.promise` to create a toast that resolves when the promise is
resolved.
Next, you can define the toast options (title, description, etc.) for each state
of the promise.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithPromise = () => {
return (
)
}
```
### Update
Use `toaster.update(...)` to modify a visible toast.
```tsx
"use client"
import { Button, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithUpdate = () => {
const id = "login-error-toast"
const show = () => {
if (toaster.isVisible(id)) return
toaster.loading({
id,
title: "Error Connecting...",
description: "You do not have permissions to perform this action.",
})
}
const update = () => {
toaster.update(id, {
title: "Hooray 🥳🥳🥳!!!",
description: "You now have permissions to perform this action.",
type: "success",
duration: 3000,
})
}
return (
)
}
```
### Custom Duration
Use the `duration` prop to set the duration of the toast.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
export const ToasterWithDuration = () => {
return (
)
}
```
### Pause and Play
Use the `pause` and `resume` methods on the `toaster` object to pause and play
the toast.
Pausing a toast prevents it from timing out, while resuming it will reenable the
timeout using the remaining duration.
```tsx
"use client"
import { Button, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
import { useId, useState } from "react"
import { HiPause, HiPlay } from "react-icons/hi"
export const ToasterPauseAndPlay = () => {
const id = useId()
const [paused, setPaused] = useState(false)
const [shown, setShown] = useState(false)
const show = () => {
toaster.success({
id,
title: "This is a success toast",
onStatusChange: (details) => {
if (details.status === "visible") {
setShown(true)
} else if (details.status === "dismissing") {
setShown(false)
}
},
})
}
const pause = () => {
toaster.pause(id)
setPaused(true)
}
const play = () => {
toaster.resume(id)
setPaused(false)
}
return (
)
}
```
### Lifecycle
Use the `onStatusChange` prop on the `toaster` function to listen for changes to
the toast's status.
```tsx
"use client"
import { Button, HStack, Stack, Text } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
import { useState } from "react"
export const ToasterLifecycle = () => {
const [statusLog, setStatusLog] = useState<[number, string][]>([])
const [dismissed, setDismissed] = useState(true)
return (
{statusLog.map(([time, toastStatus], i) => {
const date = new Date(time)
return (
{date.toLocaleTimeString()}{" "}
{toastStatus}
)
})}
)
}
```
### Maximum Visible Toasts
Set the `max` prop on the `createToaster` function to define the maximum number
of toasts that can be rendered at any one time. Any extra toasts will be queued
and rendered when a toast has been dismissed.
```jsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
max: 3,
})
```
### Placement
Toasts can be displayed on all four corners of a page. We recommend picking one
desired position and configure it in the `createToaster` function.
```jsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
placement: "top-end",
})
```
### Overlapping Toasts
By default, toasts are stacked on top of each other. To make the toasts overlap
each other, set the `overlap` prop to `true` in the `createToaster` function.
```jsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
placement: "top-end",
overlap: true,
})
```
### Page Idle Behavior
Pause toast timers when the page is idle/hidden.
```tsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
pauseOnPageIdle: true,
})
```
### Offset
Set the `offsets` prop in the `createToaster` function to offset the toasts from
the edges of the screen.
```jsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
offsets: "20px",
})
```
Alternatively, you can use the `offsets` prop to set the offset for each edge of
the screen.
```jsx title="@/components/ui/toaster.tsx"
const toaster = createToaster({
offsets: { left: "20px", top: "20px", right: "20px", bottom: "20px" },
})
```
## Props
### Toaster
### Root
| 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. |
| unstyled | undefined | `boolean` | Whether to remove the component's style. |
### Title
| 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. |
### Description
| 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. |
### ActionTrigger
| 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. |
### CloseTrigger
| 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. |
# Toggle Tip
```tsx
import { Button } from "@chakra-ui/react"
import { ToggleTip } from "@/components/ui/toggle-tip"
import { LuInfo } from "react-icons/lu"
export const ToggleTipBasic = () => {
return (
)
}
```
## Setup
For ease of use, create a closed component composition for the `ToggleTip`
component.
Alternatively, you can add it to your project using the following command.
```sh
npx @chakra-ui/cli snippet add toggle-tip
```
The snippet includes a closed component composition for the `Popover` component.
## Usage
```jsx
import { InfoTip, ToggleTip } from "@/components/ui/toggle-tip"
```
```jsx
```
## Examples
### Info Tip
Use the `InfoTip` component to display an info tip. This component renders an
icon button with an info icon by default.
> Useful for landing pages to display additional information about a feature.
```tsx
import { FormatByte, HStack, Text } from "@chakra-ui/react"
import { InfoTip } from "@/components/ui/toggle-tip"
export const ToggleTipInfoTip = () => {
return (
File size:
)
}
```
## 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) |
# Tooltip
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipBasic = () => {
return (
)
}
```
## Setup
For ease of use, create a closed component composition for the `Tooltip`
component.
Alternatively, you can add it to your project using the following command.
```sh
npx @chakra-ui/cli snippet add tooltip
```
## Usage
```jsx
import { Tooltip } from "@/components/ui/tooltip"
```
```jsx
```
## Examples
### Arrow
Use the `showArrow` prop to show an arrow on the tooltip.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithArrow = () => {
return (
)
}
```
### Placement
Use the `positioning.placement` prop to change the position of the tooltip.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithPlacement = () => {
return (
)
}
```
### Offset
Use the `positioning.offset` prop to change the offset of the tooltip.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithOffset = () => {
return (
)
}
```
### Delay
Use the `openDelay` and `closeDelay` prop to change the delay of the tooltip.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithDelay = () => {
return (
)
}
```
### Custom Background
Use the `--tooltip-bg` CSS variable to change the background color of the
tooltip.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { FaBell } from "react-icons/fa"
export const TooltipWithCustomBg = () => (
)
```
### Controlled
Use the `open` and `onOpenChange` prop to control the visibility of the tooltip.
```tsx
"use client"
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useState } from "react"
export const TooltipControlled = () => {
const [open, setOpen] = useState(false)
return (
setOpen(e.open)}
>
)
}
```
### Store
An alternative way to control the tooltip is to use the `RootProvider` component
and the `useTooltip` store hook.
This way you can access the tooltip state and methods from outside the tooltip.
```tsx
"use client"
import { Button, HStack, Tooltip, useTooltip } from "@chakra-ui/react"
export const TooltipWithStore = () => {
const tooltip = useTooltip()
const toggleOpen = () => tooltip.setOpen(!tooltip.open)
return (
This is the tooltip content
)
}
```
### Interactive
Use the `interactive` prop to keep the tooltip open when interacting with its
content.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithInteractive = () => {
return (
)
}
```
### Disabled
Use the `disabled` prop to disable the tooltip. When disabled, the tooltip will
not be shown.
```tsx
import { Button } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithDisabled = () => {
return (
)
}
```
### With Avatar
Here's an example of how to use the `Tooltip` component with an `Avatar`
component.
```tsx
import { Avatar } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useId } from "react"
export const TooltipWithAvatar = () => {
const id = useId()
return (
)
}
```
### With Checkbox
Here's an example of how to use the `Tooltip` component with a `Checkbox`
component.
```tsx
import { Checkbox } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useId } from "react"
export const TooltipWithCheckbox = () => {
const id = useId()
return (
Welcome
)
}
```
### With MenuItem
Here's an example of how to use the `Tooltip` with a `MenuItem` component.
```tsx
import { Button, Menu, Portal, Show } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
export const TooltipWithMenuItem = () => {
return (
)
}
const MenuItem = (props: Menu.ItemProps) => {
const { value, title, ...rest } = props
return (
}>
)
}
```
### With MenuTrigger
Here's an example of how to use the `Tooltip` with a `MenuTrigger` component.
```tsx
"use client"
import { Button, Menu, Portal } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useId } from "react"
export const TooltipWithMenuTrigger = () => {
const triggerId = useId()
return (
Open tooltip
New File...
New Window
Export
)
}
```
### With Switch
Here's an example of how to wrap `Tooltip` around a `Switch` component.
```tsx
import { Switch } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { useId } from "react"
export const TooltipWithSwitch = () => {
const id = useId()
return (
Toggle
)
}
```
### With Tabs
Here's an example of how to wrap `Tooltip` around a `Tabs` component.
```tsx
import { Tabs } from "@chakra-ui/react"
import { Tooltip } from "@/components/ui/tooltip"
import { LuFolder, LuSquareCheck, LuUser } from "react-icons/lu"
export const TooltipWithTab = () => {
return (
{/* TODO: Remove this once Zag.js is fixed */}
Members
Projects
Settings
Manage your team members
Manage your projects
Manage your tasks for freelancers
)
}
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| closeDelay | 500 | `number` | The close delay of the tooltip. |
| closeOnClick | true | `boolean` | Whether the tooltip should close on click |
| closeOnEscape | true | `boolean` | Whether to close the tooltip when the Escape key is pressed. |
| closeOnPointerDown | true | `boolean` | Whether to close the tooltip on pointerdown. |
| closeOnScroll | true | `boolean` | Whether the tooltip should close on scroll |
| interactive | false | `boolean` | Whether the tooltip's content is interactive.
In this mode, the tooltip will remain open when user hovers over the content. |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| openDelay | 1000 | `number` | The open delay of the tooltip. |
| skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. |
| 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. |
| aria-label | undefined | `string` | Custom label for the tooltip. |
| defaultOpen | undefined | `boolean` | The initial open state of the tooltip when rendered.
Use when you don't need to control the open state of the tooltip. |
| disabled | undefined | `boolean` | Whether the tooltip is disabled |
| id | undefined | `string` | The unique identifier of the machine. |
| ids | undefined | `Partial<{ trigger: string; content: string; arrow: string; positioner: string }>` | The ids of the elements in the tooltip. 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 |
| onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function called when the tooltip is opened. |
| open | undefined | `boolean` | The controlled open state of the tooltip |
| 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 `Tooltip` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# TreeView
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewBasic = () => {
return (
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
## Usage
```tsx
import { TreeView } from "@chakra-ui/react"
```
```tsx
```
## Shortcuts
### `TreeView.Node`
This component is a helper to manage the recursive rendering of the branch and
leaf nodes.
```tsx
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
```
is equivalent to:
```tsx
const TreeNode = (props: TreeView.NodeProviderProps) => {
const { node, indexPath } = props
return (
{node.children ? (
{node.name}
{node.children.map((child, index) => (
))}
) : (
{node.name}
)}
)
}
```
## Examples
### Sizes
Use the `size` prop to change the size of the tree view.
```tsx
"use client"
import { For, Stack, TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewWithSizes = () => {
return (
{(size) => (
Tree (size={size})
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)}
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Variants
Use the `variant` prop to change the variant of the tree view.
```tsx
"use client"
import { For, Stack, TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewWithVariants = () => {
return (
{(variant) => (
Tree (variant={variant})
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)}
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Colors
Use the `colorPalette` prop to change the color palette of the tree view.
```tsx
"use client"
import { For, TreeView, Wrap, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewWithColors = () => {
return (
{(colorPalette) => (
Tree (colorPalette={colorPalette})
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)}
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Disabled Node
Adding the `disabled` prop to a node's property will disable the node and
prevent interaction.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewDisabledNode = () => {
return (
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
disabled?: boolean
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json", disabled: true },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Controlled Expansion
Use the `expandedValue` and `onExpandedChange` props to programmatically control
node expansion behavior.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { useState } from "react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewControlledExpansion = () => {
const [expandedValue, setExpandedValue] = useState(["node_modules"])
return (
setExpandedValue(e.expandedValue)}
>
Tree
indentGuide={}
render={({ node }) =>
node.children ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Explicit Expand
Render the `TreeView.BranchTrigger` to manually control node expansion behavior.
> You might need to set `role="none"` on the `TreeView.BranchControl` to avoid
> accessibility issues.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuChevronRight, LuFile, LuFolder } from "react-icons/lu"
export const TreeViewExplicitExpand = () => {
return (
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Expand Icon
Use the `nodeState.expanded` prop to swap the rendered icon on the branch when
it's expanded or collapsed.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuSquareMinus, LuSquarePlus } from "react-icons/lu"
export const TreeViewExpandIcon = () => {
return (
Tree
nodeState.isBranch ? (
{nodeState.expanded ? : }
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Remove Indentation
Set the css variable `--tree-indentation` to `0px` to remove the indentation of
the tree view.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewRemoveIndentation = () => {
return (
Tree
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Async Loading
Lazy loading is a feature that allows the tree view to load children of a node
on demand (or async). This helps to improve the initial load time and memory
usage.
To use this, you need to provide the following:
- `loadChildren` — A function that is used to load the children of a node.
- `onLoadChildrenComplete` — A callback that is called when the children of a
node are loaded. Used to update the tree collection.
- `childrenCount` — A number that indicates the number of children of a branch
node.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { useState } from "react"
import { LuFile, LuFolder, LuLoaderCircle } from "react-icons/lu"
// mock api result
const response: Record = {
node_modules: [
{ id: "zag-js", name: "zag-js" },
{ id: "pandacss", name: "panda" },
{ id: "@types", name: "@types", childrenCount: 2 },
],
"node_modules/@types": [
{ id: "react", name: "react" },
{ id: "react-dom", name: "react-dom" },
],
src: [
{ id: "app.tsx", name: "app.tsx" },
{ id: "index.ts", name: "index.ts" },
],
}
// function to load children of a node
function loadChildren(
details: TreeView.LoadChildrenDetails,
): Promise {
const value = details.valuePath.join("/")
return new Promise((resolve) => {
setTimeout(() => {
resolve(response[value] ?? [])
}, 1200)
})
}
export const TreeViewAsync = () => {
const [collection, setCollection] = useState(initialCollection)
return (
setCollection(e.collection)}
>
Tree
indentGuide={}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{nodeState.loading ? (
) : (
)}
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
childrenCount?: number
}
const initialCollection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{ id: "node_modules", name: "node_modules", childrenCount: 3 },
{ id: "src", name: "src", childrenCount: 2 },
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Filtering
Filtering is useful when you have a large tree and you want to filter the nodes
to only show the ones that match the search query.
Here's an example that composes the `filter` method from the `TreeCollection`
and `useFilter` hook to filter the nodes.
```tsx
"use client"
import {
Highlight,
Input,
Stack,
TreeView,
createTreeCollection,
useFilter,
} from "@chakra-ui/react"
import { useState } from "react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewWithFilter = () => {
const [collection, setCollection] = useState(initialCollection)
const [expanded, setExpanded] = useState([])
const [query, setQuery] = useState("")
const { contains } = useFilter({ sensitivity: "base" })
const search = (search: string) => {
setQuery(search)
const nextCollection = initialCollection.filter((node) =>
contains(node.name, search),
)
// update collection
setCollection(nextCollection)
// expand all branches
setExpanded(nextCollection.getBranchValues())
}
return (
search(e.target.value)}
/>
setExpanded(details.expandedValue)}
>
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const initialCollection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Collapse Animation
Use the `animateContent` prop to animate the tree view content expand/collapse
state.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewCollapseAnimation = () => {
return (
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Expand/Collapse All
Provide controls to expand or collapse all nodes at once.
```tsx
"use client"
import {
Button,
ButtonGroup,
HStack,
TreeView,
createTreeCollection,
useTreeViewContext,
} from "@chakra-ui/react"
import { isEqual } from "es-toolkit"
import { useMemo } from "react"
import { LuFile, LuFolder } from "react-icons/lu"
const ExpandCollapseAll = () => {
const tree = useTreeViewContext()
const isAllExpanded = useMemo(
() => isEqual(tree.expandedValue, tree.collection.getBranchValues()),
[tree.expandedValue, tree.collection],
)
return (
)
}
export const TreeViewExpandCollapseAll = () => {
return (
Tree
}
render={({ node, nodeState }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Store
Use the `useTreeView` hook to create the tree view store and pass it to the
`TreeView.RootProvider` component. This allows you to have maximum control over
the tree view programmatically.
```tsx
"use client"
import { TreeView, createTreeCollection, useTreeView } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewWithStore = () => {
const store = useTreeView({
collection,
defaultExpandedValue: [],
})
return (
Tree
{JSON.stringify(store.expandedValue)}
indentGuide={}
render={({ node }) =>
node.children ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Links
Render the tree items as links by leveraging the `asChild` prop on the
`TreeView.Item` component.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuChevronRight, LuExternalLink, LuFile } from "react-icons/lu"
export const TreeViewWithLinks = () => {
return (
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
{node.href?.startsWith("http") && (
)}
)
}
/>
)
}
interface Node {
id: string
name: string
href?: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "docs",
name: "Documentation",
children: [
{
id: "docs/getting-started",
name: "Getting Started",
href: "/docs/getting-started",
},
{
id: "docs/installation",
name: "Installation",
href: "/docs/installation",
},
{
id: "docs/components",
name: "Components",
children: [
{
id: "docs/components/accordion",
name: "Accordion",
href: "/docs/components/accordion",
},
{
id: "docs/components/dialog",
name: "Dialog",
href: "/docs/components/dialog",
},
{
id: "docs/components/menu",
name: "Menu",
href: "/docs/components/menu",
},
],
},
],
},
{
id: "examples",
name: "Examples",
children: [
{
id: "examples/react",
name: "React Examples",
href: "/examples/react",
},
{ id: "examples/vue", name: "Vue Examples", href: "/examples/vue" },
{
id: "examples/solid",
name: "Solid Examples",
href: "/examples/solid",
},
],
},
{
id: "external",
name: "External Links",
children: [
{
id: "external/github",
name: "GitHub Repository",
href: "https://github.com/chakra-ui/zag",
},
{
id: "external/npm",
name: "NPM Package",
href: "https://www.npmjs.com/package/@zag-js/core",
},
{
id: "external/docs",
name: "Official Docs",
href: "https://zagjs.com",
},
],
},
{ id: "readme.md", name: "README.md", href: "/readme" },
{ id: "license", name: "LICENSE", href: "/license" },
],
},
})
```
### Multi Select
Add the `selectionMode="multiple"` prop to the `TreeView.Root` component to
enable multi-select functionality.
:::info
This mode requires a modifier key to be pressed to select multiple items.
- Hold `Ctrl` or `⌘` on macOS and click the items.
- Click an item, then hold `Shift` while clicking on another item.
:::
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
export const TreeViewMultiSelect = () => {
return (
Tree
indentGuide={}
render={({ node }) =>
node.children ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Checkbox Tree
Add checkboxes to tree nodes for selection functionality.
```tsx
"use client"
import {
Checkmark,
TreeView,
createTreeCollection,
useTreeViewNodeContext,
} from "@chakra-ui/react"
import { LuFile, LuFolder } from "react-icons/lu"
const TreeNodeCheckbox = (props: TreeView.NodeCheckboxProps) => {
const nodeState = useTreeViewNodeContext()
return (
)
}
export const TreeViewCheckbox = () => {
return (
Tree
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface Node {
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Mutation
Here's an example of how to design add/remove nodes in the tree view.
```tsx
"use client"
import {
HStack,
IconButton,
TreeView,
createTreeCollection,
useTreeViewContext,
} from "@chakra-ui/react"
import { useState } from "react"
import { LuFile, LuFolder, LuPlus, LuTrash } from "react-icons/lu"
export const TreeViewMutation = () => {
const [collection, setCollection] = useState(initialCollection)
const removeNode = (props: TreeNodeProps) => {
setCollection(collection.remove([props.indexPath]))
}
const addNode = (props: TreeNodeProps) => {
const { node, indexPath } = props
if (!collection.isBranchNode(node)) return
const children = [
{
id: `untitled-${Date.now()}`,
name: `untitled-${node.children?.length}.tsx`,
},
...(node.children || []),
]
setCollection(collection.replace(indexPath, { ...node, children }))
}
return (
Tree
}
render={({ node, nodeState, indexPath }) =>
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
interface TreeNodeProps extends TreeView.NodeProviderProps {
onRemove?: (props: TreeView.NodeProviderProps) => void
onAdd?: (props: TreeView.NodeProviderProps) => void
}
const TreeNodeActions = (props: TreeNodeProps) => {
const { onRemove, onAdd, node } = props
const tree = useTreeViewContext()
const isBranch = tree.collection.isBranchNode(node)
return (
{
e.stopPropagation()
onRemove?.(props)
}}
>
{isBranch && (
{
e.stopPropagation()
onAdd?.(props)
tree.expand([node.id])
}}
>
)}
)
}
interface Node {
id: string
name: string
children?: Node[]
childrenCount?: number
}
const initialCollection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
children: [
{
id: "node_modules",
name: "node_modules",
children: [
{ id: "node_modules/zag-js", name: "zag-js" },
{ id: "node_modules/pandacss", name: "panda" },
{
id: "node_modules/@types",
name: "@types",
children: [
{ id: "node_modules/@types/react", name: "react" },
{ id: "node_modules/@types/react-dom", name: "react-dom" },
],
},
],
},
{
id: "src",
name: "src",
children: [
{ id: "src/app.tsx", name: "app.tsx" },
{ id: "src/index.ts", name: "index.ts" },
],
},
{ id: "panda.config", name: "panda.config.ts" },
{ id: "package.json", name: "package.json" },
{ id: "renovate.json", name: "renovate.json" },
{ id: "readme.md", name: "README.md" },
],
},
})
```
### Custom Icon
Here's an example of how to render a custom icon for the tree view based on its
data.
```tsx
"use client"
import { TreeView, createTreeCollection } from "@chakra-ui/react"
import { RxFrame, RxImage, RxSquare, RxText } from "react-icons/rx"
export const TreeViewCustomIcon = () => {
return (
Tree
nodeState.isBranch ? (
{node.name}
) : (
{node.name}
)
}
/>
)
}
const TreeViewNodeIcon = (props: { type: Node["type"] }) => {
switch (props.type) {
case "text":
return
case "image":
return
case "frame":
return
case "rectangle":
return
default:
return null
}
}
interface Node {
type: "text" | "image" | "frame" | "rectangle"
id: string
name: string
children?: Node[]
}
const collection = createTreeCollection({
nodeToValue: (node) => node.id,
nodeToString: (node) => node.name,
rootNode: {
id: "ROOT",
name: "",
type: "frame",
children: [
{
id: "page",
name: "Page",
type: "frame",
children: [
{
id: "header",
name: "Header",
type: "frame",
children: [
{ id: "logo", name: "Logo", type: "image" },
{ id: "nav", name: "Navigation", type: "text" },
],
},
],
},
{ id: "footer", name: "Footer", type: "text" },
{
id: "main",
name: "Main",
type: "frame",
children: [
{ id: "hero", name: "Hero Section", type: "text" },
{ id: "features", name: "Features", type: "text" },
],
},
],
},
})
```
## Props
### Root
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| collection | undefined | `TreeCollection` | The collection of tree nodes |
| expandOnClick | true | `boolean` | Whether clicking on a branch should open it or not |
| lazyMount | false | `boolean` | Whether to enable lazy mounting |
| selectionMode | "single" | `'multiple' \| 'single'` | Whether the tree supports multiple selection
- "single": only one node can be selected
- "multiple": multiple nodes can be selected |
| typeahead | true | `boolean` | Whether the tree supports typeahead search |
| 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 | `'md' \| 'sm' \| 'xs'` | The size of the component |
| variant | subtle | `'subtle' \| 'solid'` | 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. |
| checkedValue | undefined | `string[]` | The controlled checked node value |
| defaultCheckedValue | undefined | `string[]` | The initial checked node value when rendered.
Use when you don't need to control the checked node value. |
| defaultExpandedValue | undefined | `string[]` | The initial expanded node ids when rendered.
Use when you don't need to control the expanded node value. |
| defaultFocusedValue | undefined | `string` | The initial focused node value when rendered.
Use when you don't need to control the focused node value. |
| defaultSelectedValue | undefined | `string[]` | The initial selected node value when rendered.
Use when you don't need to control the selected node value. |
| expandedValue | undefined | `string[]` | The controlled expanded node ids |
| focusedValue | undefined | `string` | The value of the focused node |
| ids | undefined | `Partial<{ root: string; tree: string; label: string; node: (value: string) => string }>` | The ids of the tree elements. Useful for composition. |
| loadChildren | undefined | `(details: LoadChildrenDetails) => Promise` | Function to load children for a node asynchronously.
When provided, branches will wait for this promise to resolve before expanding. |
| onCheckedChange | undefined | `(details: CheckedChangeDetails) => void` | Called when the checked value changes |
| onExpandedChange | undefined | `(details: ExpandedChangeDetails) => void` | Called when the tree is opened or closed |
| onFocusChange | undefined | `(details: FocusChangeDetails) => void` | Called when the focused node changes |
| onLoadChildrenComplete | undefined | `(details: LoadChildrenCompleteDetails) => void` | Called when a node finishes loading children |
| onLoadChildrenError | undefined | `(details: LoadChildrenErrorDetails) => void` | Called when loading children fails for one or more nodes |
| onSelectionChange | undefined | `(details: SelectionChangeDetails) => void` | Called when the selection changes |
| selectedValue | undefined | `string[]` | The controlled selected node value |
| animateContent | undefined | `'true' \| 'false'` | The animateContent of the component |
### Node
| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| render | undefined | `(props` | undefined |
| indentGuide | undefined | `React.ReactElement` | undefined |
| renderBranch | undefined | `(props` | undefined |
| branchProps | undefined | `TreeViewBranchProps` | undefined |
| branchContentProps | undefined | `TreeViewBranchContentProps` | 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. |
## Explorer
Explore the `TreeView` component parts interactively. Click on parts in the
sidebar to highlight them in the preview.
# Visually Hidden
```tsx
import { Button, VisuallyHidden } from "@chakra-ui/react"
import { LuBell } from "react-icons/lu"
export const VisuallyHiddenBasic = () => {
return (
)
}
```
## Usage
```jsx
import { VisuallyHidden } from "@chakra-ui/react"
```
```jsx
Hidden content
```
## Examples
### Input
Using the `asChild` prop, you can pass a child element to the `VisuallyHidden`
component.
```tsx
import { HStack, VisuallyHidden } from "@chakra-ui/react"
export const VisuallyHiddenWithInput = () => {
return (
The input is hidden
)
}
```
# Wrap
```tsx
import { Badge, Wrap } from "@chakra-ui/react"
export const WrapBasic = () => (
Badge 1
Badge 2
Badge 3
)
```
## Usage
By default, `Wrap` applies `display: flex`, `flex-wrap: wrap`, and `gap: 8px` to
its children.
```tsx
import { Wrap, WrapItem } from "@chakra-ui/react"
```
```tsx
```
## Examples
### Gap or Spacing
Pass the `gap` prop to apply a consistent spacing between each child, even if it
wraps.
```tsx
import { Wrap } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const WrapWithGap = () => (
{Array.from({ length: 10 }).map((_, index) => (
))}
)
```
### Alignment
Pass the `align` prop to change the alignment of the child along the cross axis.
```tsx
import { Center, Wrap, WrapItem } from "@chakra-ui/react"
export const WrapWithAlign = () => (
{Array.from({ length: 5 }).map((_, index) => (
Box {index + 1}
))}
)
```
### Justify
Pass the `justify` prop to change the alignment of the child along the main
axis.
```tsx
import { Center, Wrap, WrapItem } from "@chakra-ui/react"
export const WrapWithJustify = () => (
{Array.from({ length: 5 }).map((_, index) => (
Box {index + 1}
))}
)
```
### Row and Column Gap
Pass the `rowGap` and `columnGap` props to apply a consistent spacing between
the rows and columns.
```tsx
import { Wrap } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const WrapWithRowColumnGap = () => (
{Array.from({ length: 10 }).map((_, index) => (
))}
)
```
### Responsive
Use responsive values for the `gap`, `rowGap`, and `columnGap` props to apply
responsive spacing between each child.
```tsx
import { Wrap } from "@chakra-ui/react"
import { Box } from "@chakra-ui/react"
export const WrapResponsive = () => (
)
```
# Animation Styles
## Overview
Animation styles allow you to define reusable animation properties. The goal is
to reduce the amount of code needed to animate components.
The supported animation styles are:
- **Animation**: animation composition, delay, direction, duration, fill mode,
iteration count, name, play state, timing function
- **Animation range**: animation range, start, end, timeline
- **Transform origin**: transform origin
## Defining animation styles
Animation styles are defined using the `defineAnimationStyles` function.
Here's an example of an animation style:
```js
import { defineAnimationStyles } from "@chakra-ui/react"
const animationStyles = defineAnimationStyles({
bounceFadeIn: {
value: {
animationName: "bounce, fade-in",
animationDuration: "1s",
animationTimingFunction: "ease-in-out",
animationIterationCount: "infinite",
},
},
})
```
## Built-in animation styles
Chakra UI provides a set of built-in animation styles that you can use.
## Update the theme
To use the animation styles, update the `theme` object with the
`animationStyles` property.
```js filename="theme.ts"
import { createSystem, defineConfig } from "@chakra-ui/react"
import { animationStyles } from "./animation-styles"
const config = defineConfig({
theme: {
animationStyles,
},
})
export default createSystem(defaultConfig, config)
```
After updating the theme, run this command to generate the animations.
```bash
npx @chakra-ui/cli typegen ./theme.ts
```
These animation styles can be composed with other styles like `_open` and
`_closed` which map to the `data-state=open|closed` attribute.
```jsx
This content will fade in
```
# Cascade Layers
Chakra UI relies on CSS cascade layers to provide a predictable, performant way
to override components. The layers are defined to match that of
[Panda CSS](https://panda-css.com).
> **Good to know**: This plays a major role in the faster reconciliation times
> in v3.x
## Layer Types
Chakra supports these cascade layer types:
- `@layer reset`: Where the preflight or css resets styles are defined.
- `@layer base`: Where global styles are placed when defined in `globalCss`
config property.
- `@layer recipes`: Where styles for recipes are placed when defined in
`theme.recipes` or `theme.slotRecipes`
- `@layer tokens`: Where styles for design tokens are placed when defined in
`theme.tokens` or `theme.semanticTokens`
## Layer Order
Chakra appends the following layers to the top of the generated emotion
stylesheet:
```css
@layer reset, base, tokens, recipes;
```
This structure allows for smoother experience when combining Chakra and Panda
CSS in the same project.
## Disabling Layers
Cascade layers are enabled by default. If you want to disable them, you can do
so by setting the `disableLayers` option to `true`
```js title="theme.ts"
export const system = createSystem(defaultConfig, {
disableLayers: true,
})
```
Next, edit the `components/ui/provider` file to use the new system
```tsx title="provider.tsx" {3} /value={system}/
import { ColorModeProvider } from "@/components/ui/color-mode"
import { ChakraProvider } from "@chakra-ui/react"
import { system } from "./theme"
export function Provider(props: React.PropsWithChildren) {
return (
{props.children}
)
}
```
# Chakra Factory
## Overview
Chakra factory serves as a way to create supercharged JSX component from any
HTML element to enable them receive JSX style props.
```js
import { chakra } from "@chakra-ui/react"
```
The chakra factory can be used in two ways: as a JSX element or as a factory
function.
## JSX Element
Style props are CSS properties that you can pass as props to your components.
With the JSX factory, you can use `chakra.` syntax to create JSX
elements that support style props.
```jsx
import { chakra } from "@chakra-ui/react"
const Button = ({ children }) => (
{children}
)
```
## Factory function
Use the `chakra` function to convert native elements or custom components. The
key requirement is that the component **must** accept `className` as props.
```jsx
const Link = chakra("a")
function Example() {
return
}
```
Another example with a custom component.
```jsx
import * as RadixScrollArea from "@radix-ui/react-scroll-area"
const ScrollArea = chakra(RadixScrollArea.Root)
function Example() {
return (
Hello
)
}
```
### Attaching styles
Use the `chakra` function to attach styles or recipes to components.
```jsx
const Link = chakra("a", {
base: {
bg: "papayawhip",
color: "red.500",
},
})
// usage:
```
### Attaching recipes
Here's an example of attaching a recipe to the component.
```jsx
const Card = chakra("div", {
base: {
shadow: "lg",
rounded: "lg",
bg: "white",
},
variants: {
variant: {
outline: {
border: "1px solid",
borderColor: "red.500",
},
solid: {
bg: "red.500",
color: "white",
},
},
},
})
// usage:
```
### Forwarding props
By default, the `chakra` factory only filters chakra related style props from
getting to the DOM. For more fine-grained control of how props are forwarded,
pass the `shouldForwardProp` option.
Here's an example that forwards all props that doesn't start with `$`
```tsx
function shouldForwardProp(prop: string) {
return !prop.startsWith("$")
}
const Component = chakra("div", {}, { shouldForwardProp })
```
To create custom forward props logic, combine the
[@emotion/is-prop-valid](https://github.com/emotion-js/emotion/tree/master/packages/is-prop-valid)
package and the `isValidProperty` from Chakra UI.
```tsx
import { chakra, defaultSystem } from "@chakra-ui/react"
import shouldForwardProp from "@emotion/is-prop-valid"
const { isValidProperty } = defaultSystem
function shouldForwardProp(prop: string, variantKeys: string[]) {
const chakraSfp = !variantKeys?.includes(prop) && !isValidProperty(prop)
return shouldForwardProp(prop) || chakraSfp
}
const Component = chakra("div", {}, { shouldForwardProp })
```
## Default Props
Use the `defaultProps` option to pass default props to the component.
```jsx {9}
const Button = chakra(
"button",
{
base: {
bg: "blue.500",
color: "white",
},
},
{ defaultProps: { type: "button" } },
)
```
## Polymorphism
Every component created with the chakra factory can accept the `as` and
`asChild` props to change the underlying DOM element.
```tsx
```
or
```tsx
```
> Learn more about composition in Chakra UI
> [here](/docs/components/concepts/composition)
# Color opacity modifier
Every color related style property can use the
[`color-mix`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix)
shortcut to apply opacity to a color.
## Syntax
The general syntax is `{color}/{opacity}`. For example: `bg="red.300/40"`.
## Usage
```tsx
Hello World
```
This will generate something like this:
```css {2,3}
.css-sxdf {
--mix-background: color-mix(in srgb, var(--colors-red-300) 40%, transparent);
background: var(--mix-background, var(--colors-red-300));
color: var(--colors-white);
}
```
### CSS Variables
This feature can be used in css variables as well. This is useful for creating
one-off color token in a component.
The token reference syntax `{}` is required for this to work.
```tsx
Hello World
```
# Conditional Styles
## Overview
Chakra allows you to write styles for pseudo states, media queries, and custom
data attributes with the conditional style props.
:::note
See the list of [built-in conditions](#reference) below.
:::
## Usage
For example, here's how to change the background color of a button when it's
hovered:
```jsx
Hover me
```
### Nested condition
Conditional values can be nested to create complex selector rules.
Here's how to change the background color of an element when in focus on hover:
```jsx
Hover & Focus me
```
### At Rules
This also works with the supported at-rules (`@media`, `@layer`, `@container`,
`@supports`, and `@page`):
```tsx
Hello
```
## Pseudo Classes
### Hover, Active, Focus, and Disabled
Here's an example of how to style the hover, active, focus, and disabled states
of an element
```jsx
Hover me > Hover me
```
### First, Last, Odd, Even
Here's an example of how to style the first, last, odd, and even elements in a
list
```jsx
{items.map((item) => (
{item}
))}
```
You can also style even and odd elements using the `_even` and `_odd` modifier
```jsx
{items.map((item) => (
| {item} |
))}
```
## Pseudo Elements
### Before and After
To style the `::before` and `::after` pseudo elements of an element, use the
`_before` and `_after` modifiers
```jsx /_before/
Hello
```
### Placeholder
To style the placeholder text of any input or textarea, use the `_placeholder`
modifier:
```jsx {3}
```
### File Inputs
To style the file input button, use the `_file` modifier:
```jsx {3}
```
## Media Queries
### Reduced Motion
Use the `_motionReduce` and `_motionSafe` modifiers to style an element based on
the user's motion preference:
```jsx
Hello
```
### Color Scheme
The `prefers-color-scheme` media feature is used to detect if the user has
requested the system to use a light or dark color theme.
Use the `_osLight` and `_osDark` modifiers to style an element based on the
user's color scheme preference:
```jsx
Hello
```
### Color Contrast
The `prefers-contrast` media feature is used to detect if the user has requested
the system use a high or low contrast theme.
Use the `_highContrast` and `_lessContrast` modifiers to style an element based
on the user's color contrast preference:
```jsx
Hello
```
### Orientation
The `orientation` media feature is used to detect if the user has a device in
portrait or landscape mode.
Use the `_portrait` and `_landscape` modifiers to style an element based on the
user's device orientation:
```jsx
Hello
```
## Selectors
### Arbitrary selectors
For arbitrary, use the `css` prop to write styles for one-off selectors:
```tsx
```
Here's another example that targets the child elements of a parent element:
```tsx
*": { margin: "2" },
}}
/>
```
### Group Selectors
To style an element based on its parent element's state or attribute, add the
`group` class to the parent element, and use any of the `_group*` modifiers on
the child element.
```jsx
Hover me
```
This modifier works for every pseudo class modifiers like `_groupHover`,
`_groupActive`, `_groupFocus`, and `_groupDisabled`, etc.
### Sibling Selectors
To style an element based on its sibling element's state or attribute, add the
`peer` class to the sibling element, and use any of the `_peer*` modifiers on
the target element.
```jsx /_peerHover={{ bg: "red.500" }}/
Hover me
I'll change by bg
```
> **Note:** This only works for when the element marked with `peer` is a
> previous siblings, that is, it comes before the element you want to start.
## Data Attribute
### LTR and RTL
To style an element based on the direction of the text, use the `_ltr` and
`_rtl` modifiers
```jsx {2}
Hello
```
### State
To style an element based on its `data-{state}` attribute, use the corresponding
`_{state}` modifier
```jsx /_loading/
Hello
```
This works for common states like `data-active`, `data-disabled`, `data-focus`,
`data-hover`, `data-invalid`, `data-required`, and `data-valid`.
```jsx /_active/
Hello
```
### Orientation
To style an element based on its `data-orientation` attribute, use the
`_horizontal` and `_vertical` modifiers
```jsx
Hello
```
## ARIA Attribute
To style an element based on its `aria-{state}=true` attribute, use the
corresponding `_{state}` prop
```jsx
Hello
```
## Reference
Here's a list of all the condition props you can use in Chakra:
## Customization
Chakra lets you create your own conditions, so you're not limited to the ones in
the default preset. Learn more about customizing conditions
[here](/docs/theming/customization/conditions).
# CSS Variables
## Overview
CSS variables have become the defacto way to create shared values on the web.
It's very useful to avoid prop interpolations, classname regeneration, and
reduce runtime evaluation of token values.
## Examples
### Basic
Use the `css` prop to create css variables
```jsx
Hello
Hello
```
### Access tokens
Use the full token path to access tokens
```jsx
Hello
```
Here's an example of how to access size tokens
```jsx
Hello
```
### Responsive Styles
Use the responsive syntax to make css variables responsive
```jsx
Hello
Hello
```
### Color Opacity Modifier
When accessing color tokens, you can use the opacity modifier to access the
color with an opacity. The requirement is to use the `{}` syntax.
```jsx
Hello
```
### Virtual Color
Variables can point to a virtual color via the `colors.colorPalette.*` value.
This is useful for creating theme components.
```jsx
Hello
```
# Dark Mode
Chakra relies on the `next-themes` library to provide dark mode support. During
the installation process, the snippets required to get started are added to your
project via the CLI.
To implement color mode in your components, you can use:
- **Semantic tokens** (recommended): Use Chakra's built-in semantic tokens like
`bg.subtle` that automatically adapt to light/dark mode.
- **`_dark` overrides**: Manually specify dark mode styles for each color
property.
## Setup
If you haven't already, you can add the `next-themes` library to your project
via the CLI.
```bash
npx @chakra-ui/cli snippet add color-mode
```
The generated snippets consists of the following:
- `ColorModeProvider`: composes the `next-themes` provider component
- `useColorMode`: provides the current color mode and a function to toggle the
color mode
- `useColorModeValue`: returns the correct value based on the current color mode
- `ColorModeButton`: can be used to toggle the color mode
## Usage
Wrap your app with the `ColorModeProvider` and use the `useColorMode` hook to
access and toggle the color mode.
```tsx
import { ColorModeProvider } from "@/components/ui/color-mode"
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
```
### Adding the dark mode toggle
Use the `ColorModeButton` component to toggle the color mode.
```tsx
import { ColorModeButton } from "@/components/ui/color-mode"
export default function Page({ children }: { children: React.ReactNode }) {
return (
<>
{children}
>
)
}
```
### Styling dark mode
Use the `_dark` condition to style components for dark mode.
```tsx
Hello
```
or
```tsx
Hello
```
## Using semantic tokens
To reduce the amount of code you need to write, use semantic tokens to style
components for dark mode. This ensures the light and dark mode styles are
applied automatically and consistently.
Chakra provides a set of semantic tokens that you can use to style components
for dark mode. Learn more about
[semantic tokens](/docs/theming/semantic-tokens).
```tsx
Hello
```
## Forcing dark mode
### Element specific dark mode
To force dark mode, set the `dark` className on any parent element, or the root
element of your application.
```tsx /className="dark"/
Hello
```
The same applied to forcing light mode, use the `light` className.
```tsx /className="light"/
Hello
```
### Page specific dark mode
Use the `ColorModeProvider` component to set the dark mode for a page.
```tsx
Hello
```
> Follow this `next-themes` guide to learn more about
> [forcing color mode](https://github.com/pacocoursey/next-themes#force-page-to-a-theme).
# Focus Ring
The focus ring is used to identify the currently focused element on your page.
While this is important for accessibility, styling every component to have a
focus ring can be tedious.
Chakra UI provides the `focusRing` and `focusVisibleRing` style props to style
focus ring with ease. The value of the `focusRing` prop can be "outside",
"inside", or "mixed".
## Focus Ring
This focus ring maps to the `&:is(:focus, [data-focus])` CSS selector.
Here's how to style a button from scratch with a focus ring:
```tsx
Click me
```
## Focus Visible Ring
This focus ring maps to the `&:is(:focus-visible, [data-focus-visible])` CSS
selector.
```tsx
Click me
```
### Difference between Focus Ring and Focus Visible Ring
The Focus Visible Ring functions similarly to the Focus Ring, but with a key
difference: it only applies focus indicator styles when an element receives
keyboard focus.
This ensures that the focus ring is visible only when navigating via keyboard,
improving accessibility without affecting mouse interactions.
## Built-in Focus Ring
Here's a preview of the supported focus ring.
```tsx
import { Center, For, Stack } from "@chakra-ui/react"
export const TokensFocusRing = () => {
return (
{(focusRing) => (
{focusRing}
)}
)
}
```
## Customization
### Ring Color
To change the focus ring color for a specific component, you can use the
`focusRingColor` prop.
```tsx
```
To change the color of the focus ring globally, you can configure the
`focusRing` semantic token.
```tsx title="theme.ts"
const config = defineConfig({
globalCss: {
"*": {
focusRingColor: "red.500 !important",
},
},
})
export const system = createSystem(defaultConfig, config)
```
### Ring Width
To change the focus ring width for a specific component, you can use the
`focusRingWidth` prop.
```tsx
```
### Ring Style
To change the focus ring style for a specific component, you can use the
`focusRingStyle` prop.
```tsx
```
# Layer Styles
## Overview
Layer styles allow you to define visual properties. The common properties are:
- Color or text color
- Background color
- Border width and border color
- Box shadow
- Opacity
## Defining layer styles
Layer styles are defined using the `defineLayerStyles` function.
```js title="layer-styles.ts"
import { defineLayerStyles } from "@chakra-ui/react"
const layerStyles = defineLayerStyles({
container: {
description: "container styles",
value: {
background: "gray.50",
border: "2px solid",
borderColor: "gray.500",
},
},
})
```
## Built-in layer styles
Chakra UI provides a set of built-in layer styles.
## Updating the theme
To use the layer styles, update the `theme` object with the `layerStyles`
property.
```js title="theme.ts"
import { createSystem, defineConfig } from "@chakra-ui/react"
import { layerStyles } from "./layer-styles"
const config = defineConfig({
theme: {
layerStyles,
},
})
export default createSystem(defaultConfig, config)
```
After updating the theme, run this command to generate the type definitions.
```bash
npx @chakra-ui/cli typegen
```
## Using layer styles
Now you can use `layerStyle` property in your components.
```jsx
This is inside a container style
```
# Styling
## Concepts
After installing Chakra UI, follow these guidelines to learn the key concepts:
- [Chakra Factory](/docs/styling/chakra-factory)
- [Responsive Design](/docs/styling/responsive-design)
- [CSS Variables](/docs/styling/css-variables)
- [Dark Mode](/docs/styling/dark-mode)
- [Color Opacity Modifier](/docs/styling/color-opacity-modifier)
- [Conditional Styles](/docs/styling/conditional-styles)
- [Virtual Color](/docs/styling/virtual-color)
## Compositions
After understanding the concepts, learn how to use these compositions to avoid
repeating styles:
- [Text Styles](/docs/styling/text-styles)
- [Layer Styles](/docs/styling/layer-styles)
- [Animation Styles](/docs/styling/animation-styles)
- [Focus Ring](/docs/styling/focus-ring)
## Style Props
Style props are the most fundamental way to style your components in Chakra UI.
They are basically css styles as props.
[Learn more about style props](/docs/styling/style-props/background)
# Responsive Design
## Overview
Chakra UI uses a mobile-first breakpoint system with min-width media queries:
```ts
const breakpoints = {
base: "0rem", // 0px
sm: "30rem", // ~480px
md: "48rem", // ~768px
lg: "62rem", // ~992px
xl: "80rem", // ~1280px
"2xl": "96rem", // ~1536px
}
```
## Object syntax
Here's an example of how to change the font weight of a text on large screens
```jsx
Text
```
or use the prop based modifier
```jsx
Text
```
## Array syntax
Chakra also accepts arrays as values for responsive styles. Pass the
corresponding value for each breakpoint in the array. Using our previous code as
an example:
```jsx
Text
```
Notice the use of `undefined` for the breakpoints to skip the `md` and `lg`
breakpoints.
## Breakpoint targeting
### Breakpoint range
Chakra provides a way to target a range of breakpoints using the `To` notation.
To apply styles between the `md` and `xl` breakpoints, use the `mdToXl`
property:
```jsx
Text
```
> This text will only be bold from `md` to `xl` breakpoints.
### Only breakpoint
To target a single breakpoint, use the `Only` notation. Here's an example of how
to apply styles only in the `lg` breakpoint, using the `lgOnly` property:
```jsx
Text
```
### Down breakpoint
To target a breakpoint and below, use the `Down` notation. This creates clear
boundaries for responsive variants. Here's an example of how to apply styles
from the `sm` breakpoint and below:
```jsx
Text
```
> This text will be bold from `base` up to and including the `sm` breakpoint.
## Hiding elements at breakpoint
Chakra provides the `hideFrom` and `hideBelow` utilities to hide elements at
specific breakpoints.
To hide an element from the `md` breakpoint, use the `hideFrom` utility:
```jsx
This text will be hidden from the `md` breakpoint
```
To hide an element below the `md` breakpoint, use the `hideBelow` utility:
```jsx
This text will be hidden below the `md` breakpoint
```
## Customizing Breakpoints
To learn how to customize breakpoints, please refer to the
[customizing breakpoints](/docs/theming/customization/breakpoints) section.
## Responsive Variants
When applying breakpoints to component variants, we recommend using explicit
breakpoints instead of using the `base` breakpoint.
This way, you can avoid style leaking from one variant to another.
```jsx
// okay, but can lead to style leaking ⚠️
// good ✅
```
This creates clear boundaries without style accumulation. :::
## FAQs
### Why are breakpoints converted to `rem`?
The conversion to `rem` is intentional and beneficial for accessibility reasons:
- User changed their browser's font setting
- User zoomed in
- Font size changed in HTML
# Text Styles
## Overview
Text styles allows you to define textual css properties. The common properties
are:
- **Font**: font family, weight, size
- **Line height**
- **Letter spacing**
- **Text decoration**
- **Text transform**
## Defining text styles
Text styles are defined using the `defineTextStyles` function.
```js filename="text-styles.ts"
import { defineTextStyles } from "@chakra-ui/react"
export const textStyles = defineTextStyles({
body: {
description: "The body text style - used in paragraphs",
value: {
fontFamily: "Inter",
fontWeight: "500",
fontSize: "16px",
lineHeight: "24",
letterSpacing: "0",
textDecoration: "None",
textTransform: "None",
},
},
})
```
## Built-in text styles
Chakra UI provides a set of built-in text styles.
## Update the theme
To use the text styles, update the `theme` object with the `textStyles`
property.
```js filename="theme.ts"
import { createSystem, defineConfig } from "@chakra-ui/react"
import { textStyles } from "./text-styles"
const config = defineConfig({
theme: {
textStyles,
},
})
export default createSystem(defaultConfig, config)
```
After updating the theme, run this command to generate the typings.
```bash
npx @chakra-ui/cli typegen
```
## Using text styles
Now you can use `textStyle` property in your components.
```jsx
This is the body text style
```
# Virtual Color
## Overview
Chakra allows you to create a virtual color or color placeholder in your
project. The `colorPalette` property is how you create virtual color.
```js
Hello World
```
This will translate to the `blue.100` background color and `blue.200` background
color on hover.
## Usage
The fundamental requirement for virtual colors is that your colors must have a
consistent naming convention. By default, Chakra use `50-950` color values for
each color we provide.
This makes it easier for you to create and use virtual colors. Let's say we need
to create a themable outline button from scratch.
```jsx
Click me
```
### Recipes
Virtual colors are most useful when used with recipes.
```js
const buttonRecipe = defineRecipe({
base: {
display: "flex",
alignItems: "center",
justifyContent: "center",
// set the color palette
colorPalette: "blue",
},
variants: {
variant: {
primary: {
bg: "colorPalette.500",
color: "white",
},
outline: {
borderWidth: "1px",
borderColor: "colorPalette.500",
_hover: {
borderColor: "colorPalette.600",
},
},
},
},
})
```
### Components
Most built-in components in Chakra support virtual colors.
```jsx
```
### Dark mode
Another amazing thing you can do with virtual colors is to use them with dark
mode.
```jsx
Hello World
```
> This element will have a `blue.600` background color in light mode and a
> `blue.400` background color in dark mode.
# Animations
## Keyframes
Chakra UI supports the following keyframes out of the box.
| Animation Key | Example |
| ------------------------ | --------------------------------------------- |
| `spin` | |
| `pulse` | |
| `ping` | |
| `bounce` | |
| `bg-position` | |
| `position` | |
| `circular-progress` | |
| `expand-height` | |
| `collapse-height` | |
| `expand-width` | |
| `collapse-width` | |
| `fade-in` | |
| `fade-out` | |
| `slide-from-left-full` | |
| `slide-from-right-full` | |
| `slide-from-top-full` | |
| `slide-from-bottom-full` | |
| `slide-to-left-full` | |
| `slide-to-right-full` | |
| `slide-to-top-full` | |
| `slide-to-bottom-full` | |
| `slide-from-top` | |
| `slide-from-bottom` | |
| `slide-from-left` | |
| `slide-from-right` | |
| `slide-to-top` | |
| `slide-to-bottom` | |
| `slide-to-left` | |
| `slide-to-right` | |
| `scale-in` | |
| `scale-out` | |
## Durations
Chakra UI supports the following durations out of the box.
| Duration Token | Value | Example |
| -------------- | ------- | --------------------------------------------------------- |
| `slowest` | `500ms` | |
| `slower` | `400ms` | |
| `slow` | `300ms` | |
| `moderate` | `200ms` | |
| `fast` | `150ms` | |
| `faster` | `100ms` | |
| `fastest` | `50ms` | |
# Aspect Ratios
## Tokens
Chakra UI supports the following aspect ratios out of the box.
| Aspect Ratio Token | Value | Example |
| ------------------ | ----------- | ------------------------------- |
| `square` | `1 / 1` | |
| `landscape` | `4 / 3` | |
| `portrait` | `3 / 4` | |
| `wide` | `16 / 9` | |
| `ultrawide` | `18 / 5` | |
| `golden` | `1.618 / 1` | |
# Breakpoints
Chakra UI supports the following breakpoints out of the box.
| Breakpoint Token | Example |
| ---------------- | --------------------------------- |
| `sm` | |
| `md` | |
| `lg` | |
| `xl` | |
| `2xl` | |
# Colors
## Semantic Tokens
Chakra UI supports these semantic tokens out of the box.
:::info
We recommend using semantic tokens as they automatically adapt to color modes
and provide consistent styling across your application.
:::
### Background
| Background Token | Example |
| ---------------- | -------------------------- |
| `bg` | |
| `bg.subtle` | |
| `bg.muted` | |
| `bg.emphasized` | |
| `bg.inverted` | |
| `bg.panel` | |
| `bg.error` | |
| `bg.warning` | |
| `bg.success` | |
| `bg.info` | |
### Text
| Text Token | Example |
| ------------- | --------------------------- |
| `fg` | |
| `fg.muted` | |
| `fg.subtle` | |
| `fg.inverted` | |
| `fg.error` | |
| `fg.warning` | |
| `fg.success` | |
| `fg.info` | |
### Border
| Border Token | Example |
| ------------------- | --------------------------------------- |
| `border` | |
| `border.muted` | |
| `border.subtle` | |
| `border.emphasized` | |
| `border.inverted` | |
| `border.error` | |
| `border.warning` | |
| `border.success` | |
| `border.info` | |
## Tokens
Chakra UI supports the following color tokens out of the box.
| Color Token | Value | Example |
| ------------ | --------- | ------------------------------------------ |
| `gray.50` | `#fafafa` | |
| `gray.100` | `#f4f4f5` | |
| `gray.200` | `#e4e4e7` | |
| `gray.300` | `#d4d4d8` | |
| `gray.400` | `#a1a1aa` | |
| `gray.500` | `#71717a` | |
| `gray.600` | `#52525b` | |
| `gray.700` | `#3f3f46` | |
| `gray.800` | `#27272a` | |
| `gray.900` | `#18181b` | |
| `gray.950` | `#111111` | |
| `red.50` | `#fef2f2` | |
| `red.100` | `#fee2e2` | |
| `red.200` | `#fecaca` | |
| `red.300` | `#fca5a5` | |
| `red.400` | `#f87171` | |
| `red.500` | `#ef4444` | |
| `red.600` | `#dc2626` | |
| `red.700` | `#991919` | |
| `red.800` | `#511111` | |
| `red.900` | `#300c0c` | |
| `red.950` | `#1f0808` | |
| `orange.50` | `#fff7ed` | |
| `orange.100` | `#ffedd5` | |
| `orange.200` | `#fed7aa` | |
| `orange.300` | `#fdba74` | |
| `orange.400` | `#fb923c` | |
| `orange.500` | `#f97316` | |
| `orange.600` | `#ea580c` | |
| `orange.700` | `#92310a` | |
| `orange.800` | `#6c2710` | |
| `orange.900` | `#3b1106` | |
| `orange.950` | `#220a04` | |
| `yellow.50` | `#fefce8` | |
| `yellow.100` | `#fef9c3` | |
| `yellow.200` | `#fef08a` | |
| `yellow.300` | `#fde047` | |
| `yellow.400` | `#facc15` | |
| `yellow.500` | `#eab308` | |
| `yellow.600` | `#ca8a04` | |
| `yellow.700` | `#845209` | |
| `yellow.800` | `#713f12` | |
| `yellow.900` | `#422006` | |
| `yellow.950` | `#281304` | |
| `green.50` | `#f0fdf4` | |
| `green.100` | `#dcfce7` | |
| `green.200` | `#bbf7d0` | |
| `green.300` | `#86efac` | |
| `green.400` | `#4ade80` | |
| `green.500` | `#22c55e` | |
| `green.600` | `#16a34a` | |
| `green.700` | `#116932` | |
| `green.800` | `#124a28` | |
| `green.900` | `#042713` | |
| `green.950` | `#03190c` | |
| `teal.50` | `#f0fdfa` | |
| `teal.100` | `#ccfbf1` | |
| `teal.200` | `#99f6e4` | |
| `teal.300` | `#5eead4` | |
| `teal.400` | `#2dd4bf` | |
| `teal.500` | `#14b8a6` | |
| `teal.600` | `#0d9488` | |
| `teal.700` | `#0c5d56` | |
| `teal.800` | `#114240` | |
| `teal.900` | `#032726` | |
| `teal.950` | `#021716` | |
| `blue.50` | `#eff6ff` | |
| `blue.100` | `#dbeafe` | |
| `blue.200` | `#bfdbfe` | |
| `blue.300` | `#a3cfff` | |
| `blue.400` | `#60a5fa` | |
| `blue.500` | `#3b82f6` | |
| `blue.600` | `#2563eb` | |
| `blue.700` | `#173da6` | |
| `blue.800` | `#1a3478` | |
| `blue.900` | `#14204a` | |
| `blue.950` | `#0c142e` | |
| `cyan.50` | `#ecfeff` | |
| `cyan.100` | `#cffafe` | |
| `cyan.200` | `#a5f3fc` | |
| `cyan.300` | `#67e8f9` | |
| `cyan.400` | `#22d3ee` | |
| `cyan.500` | `#06b6d4` | |
| `cyan.600` | `#0891b2` | |
| `cyan.700` | `#0c5c72` | |
| `cyan.800` | `#134152` | |
| `cyan.900` | `#072a38` | |
| `cyan.950` | `#051b24` | |
| `purple.50` | `#faf5ff` | |
| `purple.100` | `#f3e8ff` | |
| `purple.200` | `#e9d5ff` | |
| `purple.300` | `#d8b4fe` | |
| `purple.400` | `#c084fc` | |
| `purple.500` | `#a855f7` | |
| `purple.600` | `#9333ea` | |
| `purple.700` | `#641ba3` | |
| `purple.800` | `#4a1772` | |
| `purple.900` | `#2f0553` | |
| `purple.950` | `#1a032e` | |
| `pink.50` | `#fdf2f8` | |
| `pink.100` | `#fce7f3` | |
| `pink.200` | `#fbcfe8` | |
| `pink.300` | `#f9a8d4` | |
| `pink.400` | `#f472b6` | |
| `pink.500` | `#ec4899` | |
| `pink.600` | `#db2777` | |
| `pink.700` | `#a41752` | |
| `pink.800` | `#6d0e34` | |
| `pink.900` | `#45061f` | |
| `pink.950` | `#2c0514` | |
# Cursors
## Overview
Chakra UI uses the `cursor` token to define the cursor for interactive elements.
| Cursor Token | Value | Example |
| ------------ | ------------- | ------------------------- |
| `button` | `pointer` | |
| `checkbox` | `default` | |
| `disabled` | `not-allowed` | |
| `menuitem` | `default` | |
| `option` | `default` | |
| `radio` | `default` | |
| `slider` | `default` | |
| `switch` | `pointer` | |
## Cursor Tokens
To customize the cursor for interactive elements in Chakra, set the desired
`cursor` token values.
Here's a list of the available cursor tokens:
- **button**: Cursors for buttons
- **checkbox**: Cursors for checkbox and checkbox card
- **disabled**: Cursors for disabled elements
- **menuitem**: Cursors for menu item and menu option items.
- **option**: Cursors for select, combobox and listbox options
- **radio**: Cursors for radio and radio cards
- **slider**: Cursors for slider track and thumb interaction
- **switch**: Cursors for switch
## Customizing Cursors
Here's an example of how to change the cursor for a button, you can set the
`button` token to `default`.
```tsx
import { createSystem, defaultConfig } from "@chakra-ui/react"
export const system = createSystem(defaultConfig, {
theme: {
tokens: {
cursor: {
button: { value: "pointer" },
},
},
},
})
```
# Layer Styles
Chakra UI provides these text styles out of the box.
# Overview
## Architecture
The Chakra UI theming system is built around the API of
[Panda CSS](https://panda-css.com/).
Here's a quick overview of how the system is structured to provide a performant
and extensible styling system:
- Define the styling system configuration using the `defineConfig` function
- Create the styling engine using the `createSystem` function
- Pass the styling engine to the `ChakraProvider` component
```tsx
import {
ChakraProvider,
createSystem,
defaultConfig,
defineConfig,
} from "@chakra-ui/react"
const config = defineConfig({
theme: {
tokens: {
colors: {},
},
},
})
const system = createSystem(defaultConfig, config)
export default function App() {
return (
Hello World
)
}
```
## Config
The Chakra UI system is configured using the `defineConfig` function. This
function accepts a configuration object that allows you to customize the styling
system's behavior.
After a config is defined, it is passed to the `createSystem` function to create
the styling engine.
### cssVarsRoot
`cssVarsRoot` is the root element where the token CSS variables will be applied.
```tsx title="theme.ts"
const config = defineConfig({
cssVarsRoot: ":where(:root, :host)",
})
export default createSystem(defaultConfig, config)
```
### cssVarsPrefix
`cssVarsPrefix` is the prefix used for the token CSS variables.
```tsx title="theme.ts"
const config = defineConfig({
cssVarsPrefix: "ck",
})
export default createSystem(defaultConfig, config)
```
### globalCss
`globalCss` is used to apply global styles to the system.
```tsx title="theme.ts"
const config = defineConfig({
globalCss: {
"html, body": {
margin: 0,
padding: 0,
},
},
})
export default createSystem(defaultConfig, config)
```
### preflight
`preflight` is used to apply css reset styles to the system.
```tsx title="theme.ts"
const config = defineConfig({
preflight: false,
})
export default createSystem(defaultConfig, config)
```
Alternatively, you can use the `preflight` config property to apply css reset
styles to the system. This is useful if you want to apply css reset styles to a
specific element.
```tsx title="theme.ts"
const config = defineConfig({
preflight: {
scope: ".chakra-reset",
},
})
export default createSystem(defaultConfig, config)
```
### theme
Use the `theme` config property to define the system theme. This property
accepts the following properties:
- `breakpoints`: for defining breakpoints
- `keyframes`: for defining css keyframes animations
- `tokens`: for defining tokens
- `semanticTokens`: for defining semantic tokens
- `textStyles`: for defining typography styles
- `layerStyles`: for defining layer styles
- `animationStyles`: for defining animation styles
- `recipes`: for defining component recipes
- `slotRecipes`: for defining component slot recipes
```tsx title="theme.ts"
const config = defineConfig({
theme: {
breakpoints: {
sm: "320px",
md: "768px",
lg: "960px",
xl: "1200px",
},
tokens: {
colors: {
red: "#EE0F0F",
},
},
semanticTokens: {
colors: {
danger: { value: "{colors.red}" },
},
},
keyframes: {
spin: {
from: { transform: "rotate(0deg)" },
to: { transform: "rotate(360deg)" },
},
},
},
})
export default createSystem(defaultConfig, config)
```
### conditions
Use the `conditions` config property to define custom selectors and media query
conditions for use in the system.
```tsx title="theme.ts"
const config = defineConfig({
conditions: {
cqSm: "@container(min-width: 320px)",
child: "& > *",
},
})
export default createSystem(defaultConfig, config)
```
Sample usage:
```tsx
Hello World
```
### strictTokens
Use the `strictTokens` config property to enforce the usage of only design
tokens. This will throw a TS error if you try to use a token that is not defined
in the theme.
```tsx title="theme.ts"
const config = defineConfig({
strictTokens: true,
})
export default createSystem(defaultConfig, config)
```
```tsx
// ❌ This will throw a TS error
Hello World
// ✅ This will work
Hello World
```
## TypeScript
When you configure the system properties (like `colors`, `space`, `fonts`,
etc.), the CLI can be used to generate type definitions for them.
```bash
npx @chakra-ui/cli typegen ./theme.ts
```
This will update the internal types in the `@chakra-ui/react` package, and make
sure they are in sync with the theme. Providing a type-safe API and delightful
experience for developers.
## System
After a config is defined, it is passed to the `createSystem` function to create
the styling engine. The returned `system` is framework-agnostic JavaScript
styling engine that can be used to style components.
```tsx
const system = createSystem(defaultConfig, config)
```
The system includes the following properties:
### token
The token function is used to get a raw token value, or css variable.
```tsx
const system = createSystem(defaultConfig, config)
// raw token
system.token("colors.red.200")
// => "#EE0F0F"
// token with fallback
system.token("colors.pink.240", "#000")
// => "#000"
```
Use the `token.var` function to get the css variable:
```tsx
// css variable
system.token.var("colors.red.200")
// => "var(--chakra-colors-red-200)"
// token with fallback
system.token.var("colors.pink.240", "colors.red.200")
// => "var(--chakra-colors-red-200)"
```
It's important to note that `semanticTokens` always return a css variable,
regardless of whether you use `token` or `token.var`. This is because semantic
tokens change based on the theme.
```tsx
// semantic token
system.token("colors.danger")
// => "var(--chakra-colors-danger)"
system.token.var("colors.danger")
// => "var(--chakra-colors-danger)"
```
### tokens
```tsx
const system = createSystem(defaultConfig, config)
system.tokens.getVar("colors.red.200")
// => "var(--chakra-colors-red-200)"
system.tokens.expandReferenceInValue("3px solid {colors.red.200}")
// => "3px solid var(--chakra-colors-red-200)"
system.tokens.cssVarMap
// => Map { "colors": Map { "red.200": "var(--chakra-colors-red-200)" } }
system.tokens.flatMap
// => Map { "colors.red.200": "var(--chakra-colors-red-200)" }
```
### css
The `css` function is used to convert chakra style objects to CSS style object
that can be passed to `emotion` or `styled-components` or any other styling
library.
```tsx
const system = createSystem(defaultConfig, config)
system.css({
color: "red.200",
bg: "blue.200",
})
// => { color: "var(--chakra-colors-red-200)", background: "var(--chakra-colors-blue-200)" }
```
### cva
The `cva` function is used to create component recipes. It returns a function
that, when called with a set of props, returns a style object.
```tsx
const system = createSystem(defaultConfig, config)
const button = system.cva({
base: {
color: "white",
bg: "blue.500",
},
variants: {
outline: {
color: "blue.500",
bg: "transparent",
border: "1px solid",
},
},
})
button({ variant: "outline" })
// => { color: "blue.500", bg: "transparent", border: "1px solid" }
```
### sva
The `sva` function is used to create component slot recipes. It returns a
function that, when called with a set of props, returns a style object for each
slot.
```tsx
const system = createSystem(defaultConfig, config)
const alert = system.sva({
slots: ["title", "description", "icon"],
base: {
title: { color: "white" },
description: { color: "white" },
icon: { color: "white" },
},
variants: {
status: {
info: {
title: { color: "blue.500" },
description: { color: "blue.500" },
icon: { color: "blue.500" },
},
},
},
})
alert({ status: "info" })
// => { title: { color: "blue.500" }, description: { color: "blue.500" }, icon: { color: "blue.500" } }
```
### isValidProperty
The `isValidProperty` function is used to check if a property is valid.
```tsx
const system = createSystem(defaultConfig, config)
system.isValidProperty("color")
// => true
system.isValidProperty("background")
// => true
system.isValidProperty("invalid")
// => false
```
### splitCssProps
The `splitCssProps` function is used to split the props into css props and
non-css props.
```tsx
const system = createSystem(defaultConfig, config)
system.splitCssProps({
color: "red.200",
bg: "blue.200",
"aria-label": "Hello World",
})
// => [{ color: "red.200", bg: "blue.200" }, { "aria-label": "Hello World" }]
```
### breakpoints
The `breakpoints` property is used to query breakpoints.
```tsx
const system = createSystem(defaultConfig, config)
system.breakpoints.up("sm")
// => "@media (min-width: 320px)"
system.breakpoints.down("sm")
// => "@media (max-width: 319px)"
system.breakpoints.only("md")
// => "@media (min-width: 320px) and (max-width: 768px)"
system.breakpoints.keys()
// => ["sm", "md", "lg", "xl"]
```
## Tokens
To learn more about tokens, please refer to the [tokens](/docs/theming/tokens)
section.
## Recipes
To learn more about recipes, please refer to the
[recipes](/docs/theming/recipes) section.
# Radii
## Tokens
Chakra UI supports the following border radius tokens out of the box.
| Border Radius Token | Value | Example |
| ------------------- | ------------ | --------------------------- |
| `none` | `0` | |
| `2xs` | `0.0625rem` | |
| `xs` | `0.125rem` | |
| `sm` | `0.25rem` | |
| `md` | `0.375rem` | |
| `lg` | `0.5rem` | |
| `xl` | `0.75rem` | |
| `2xl` | `1rem` | |
| `3xl` | `1.5rem` | |
| `4xl` | `2rem` | |
| `full` | `9999px` | |
| `l1` | `{radii.xs}` | |
| `l2` | `{radii.sm}` | |
| `l3` | `{radii.md}` | |
Here’s the conversion of the given rem values to px, assuming the root font size is 16px (which is the default in most browsers)
| Size | rem Value | px Equivalent |
|-------|-----------|---------------|
| none | 0 | 0px |
| 2xs | 0.0625rem | 1px |
| xs | 0.125rem | 2px |
| sm | 0.25rem | 4px |
| md | 0.375rem | 6px |
| lg | 0.5rem | 8px |
| xl | 0.75rem | 12px |
| 2xl | 1rem | 16px |
| 3xl | 1.5rem | 24px |
| 4xl | 2rem | 32px |
| full | 9999px | 9999px |
# Recipes
## Overview
Chakra provides a way to write CSS-in-JS with better performance, developer
experience, and composability. One of its key features is the ability to create
multi-variant styles with a type-safe runtime API.
A recipe consists of these properties:
- `className`: The className to attach to the component
- `base`: The base styles for the component
- `variants`: The different style variations for the component
- `compoundVariants`: The different combinations of variants for the component
- `defaultVariants`: The default variant values for the component
## Defining the recipe
Use the `defineRecipe` identity function to create a recipe.
```tsx title="button.recipe.ts"
import { defineRecipe } from "@chakra-ui/react"
export const buttonRecipe = defineRecipe({
base: {
display: "flex",
},
variants: {
variant: {
solid: { bg: "red.200", color: "white" },
outline: { borderWidth: "1px", borderColor: "red.200" },
},
size: {
sm: { padding: "4", fontSize: "12px" },
lg: { padding: "8", fontSize: "24px" },
},
},
})
```
## Using the recipe
There are two ways to use the recipe in a component:
- Directly in the component with `useRecipe`
- Creating a component (recommended) with the `chakra` factory
:::info
**RSC Tip:** Adding the `"use client"` directive is required since it relies on
react hooks like `useContext` and `useInsertionEffect` under the hood.
:::
### Directly in component
Use the `useRecipe` hook to get the recipe for a component. Then, call the
recipe with its variant props to get the styles.
```tsx title="button.tsx" {9}
"use client"
import { chakra, useRecipe } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
export const Button = (props) => {
const { variant, size, ...restProps } = props
const recipe = useRecipe({ recipe: buttonRecipe })
const styles = recipe({ variant, size })
return
}
```
#### splitVariantProps
Notice how the `variant` and `size` props were destructured from the props to be
passed to the recipe. A smarter approach would be to automatically split the
recipe props from the component props.
To do that, use the `recipe.splitVariantProps` function to split the recipe
props from the component props.
```tsx title="button.tsx" {8}
"use client"
import { chakra, useRecipe } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
export const Button = (props) => {
const recipe = useRecipe({ recipe: buttonRecipe })
const [recipeProps, restProps] = recipe.splitVariantProps(props)
const styles = recipe(recipeProps)
// ...
}
```
#### TypeScript
To infer the recipe variant prop types, use the `RecipeVariantProps` type
helper.
```tsx title="button.tsx"
import type { RecipeVariantProps } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
type ButtonVariantProps = RecipeVariantProps
export interface ButtonProps
extends React.PropsWithChildren {}
```
### Creating a component
Use the `chakra` function to create a component from a recipe.
> **Note:** The recipe can also be inlined into the `chakra` function.
```tsx title="button.tsx"
"use client"
import { chakra } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
export const Button = chakra("button", buttonRecipe)
```
Next, use the component and pass recipe properties to it.
```tsx title="app.tsx"
import { Button } from "./button"
const App = () => {
return (
)
}
```
## Default Variants
The `defaultVariants` property is used to set the default variant values for the
recipe. This is useful when you want to apply a variant by default.
```tsx title="button.tsx" {19-22}
"use client"
import { chakra } from "@chakra-ui/react"
const Button = chakra("button", {
base: {
display: "flex",
},
variants: {
variant: {
solid: { bg: "red.200", color: "white" },
outline: { borderWidth: "1px", borderColor: "red.200" },
},
size: {
sm: { padding: "4", fontSize: "12px" },
lg: { padding: "8", fontSize: "24px" },
},
},
defaultVariants: {
variant: "solid",
size: "lg",
},
})
```
## Compound Variants
Use the `compoundVariants` property to define a set of variants that are applied
based on a combination of other variants.
```tsx title="button.tsx" /compoundVariants/
"use client"
import { chakra } from "@chakra-ui/react"
const button = cva({
base: {
display: "flex",
},
variants: {
variant: {
solid: { bg: "red.200", color: "white" },
outline: { borderWidth: "1px", borderColor: "red.200" },
},
size: {
sm: { padding: "4", fontSize: "12px" },
lg: { padding: "8", fontSize: "24px" },
},
},
compoundVariants: [
{
size: "small",
variant: "outline",
css: {
borderWidth: "2px",
},
},
],
})
```
When you use the `size="small"` and `variant="outline"` variants together, the
`compoundVariants` will apply the `css` property to the component.
```tsx title="app.tsx"
```
### Caveat
Due to the design constraints, using `compoundVariants` with responsive values
doesn't work.
This means a code like this will not work:
```tsx
```
For this cases, we recommend rendering multiple versions of the component with
different breakpoints, then hide/show as needed.
## Theme Usage
To use the recipe in a reusable manner, move it to the system theme and add it
to `theme.recipes` property.
```tsx title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
const config = defineConfig({
theme: {
recipes: {
button: buttonRecipe,
},
},
})
export default createSystem(defaultConfig, config)
```
### TypeScript
Use the CLI to generate the types for the recipe.
```bash
npx @chakra-ui/cli typegen ./theme.ts
```
Then, import the generated types in your component.
```tsx title="button.tsx"
import type { RecipeVariantProps } from "@chakra-ui/react"
import { buttonRecipe } from "./button.recipe"
type ButtonVariantProps = RecipeVariantProps
export interface ButtonProps
extends React.PropsWithChildren {}
```
### Update code
If you use the recipe directly in your component, update the `useRecipe` to use
the `key` property to get the recipe from the theme.
```diff title="button.tsx"
const Button = () => {
- const recipe = useRecipe({ recipe: buttonRecipe })
+ const recipe = useRecipe({ key: "button" })
// ...
}
```
# Semantic Tokens
## Overview
Semantic tokens are tokens that are designed to be used in a specific context. A
semantic token consists of the following properties:
- `value`: The value of the token or a reference to an existing token.
- `description`: An optional description of what the token can be used for.
## Defining Semantic Tokens
In most cases, the value of a semantic token references to an existing token.
> To reference a value in a semantic token, use the token reference `{}` syntax.
```js title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const config = defineConfig({
theme: {
tokens: {
colors: {
red: { value: "#EE0F0F" },
},
},
semanticTokens: {
colors: {
danger: { value: "{colors.red}" },
},
},
},
})
export default createSystem(defaultConfig, config)
```
## Using Semantic Tokens
After defining semantic tokens, we recommend using the Chakra CLI to generate
theme typings for your tokens.
```bash
npx @chakra-ui/cli typegen ./src/theme.ts
```
This will provide autocompletion for your tokens in your editor.
```tsx
Hello World
```
## Conditional Token
Semantic tokens can also be changed based on the conditions like light and dark
modes.
For example, if you want a color to change automatically based on light or dark
mode.
```js title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const config = defineConfig({
theme: {
semanticTokens: {
colors: {
danger: {
value: { base: "{colors.red}", _dark: "{colors.darkred}" },
},
success: {
value: { base: "{colors.green}", _dark: "{colors.darkgreen}" },
},
},
},
},
})
export default createSystem(defaultConfig, config)
```
:::info
The conditions used in semantic tokens must be an at-rule or parent selector
[condition](/docs/styling/conditional-styles#reference).
:::
## Semantic Token Nesting
Semantic tokens can be nested to create a hierarchy of tokens. This is useful
when you want to group tokens together.
:::info
Use the `DEFAULT` key to define the default value of a nested token.
:::
```js title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const config = defineConfig({
theme: {
semanticTokens: {
colors: {
bg: {
DEFAULT: { value: "{colors.gray.100}" },
primary: { value: "{colors.teal.100}" },
secondary: { value: "{colors.gray.100}" },
},
},
},
},
})
export default createSystem(defaultConfig, config)
```
This allows the use of the `bg` token in the following ways:
```tsx
Hello World
Hello World
```
# Shadows
## Semantic Tokens
Chakra UI supports these semantic tokens out of the box.
| Shadow Token | Example |
| ------------ | ---------------------- |
| `xs` | |
| `sm` | |
| `md` | |
| `lg` | |
| `xl` | |
| `2xl` | |
| `inner` | |
| `inset` | |
Here’s an example of how to add new shadows.
```javascript
export const system = createSystem(defaultConfig, {
theme: {
semanticTokens: {
shadows: {
custom: {
value: {
_light: "0 32px 56px 0 rgba(0, 0, 0, 0.25)",
_dark: "0 32px 56px 0 rgba(0, 0, 0, 0.25)",
},
},
},
},
},
});
```
# Sizes
## Tokens
Chakra UI supports the following size tokens out of the box.
# Slot Recipes
## Overview
Slot Recipes come in handy when you need to apply style variations to multiple
parts of a component.
A slot recipe consists of these properties:
- `className`: The className prefix to attach to the component slot
- `slots`: An array of component parts to style
- `base`: The base styles per slot
- `variants`: The different visual styles for each slot
- `defaultVariants`: The default variant for the component
- `compoundVariants`: The compound variant combination and style overrides for
each slot.
## Defining the recipe
Use the `defineSlotRecipe` identity function to create a slot recipe.
```tsx title="checkbox.recipe.ts"
import { defineSlotRecipe } from "@chakra-ui/react"
export const checkboxSlotRecipe = defineSlotRecipe({
slots: ["root", "control", "label"],
base: {
root: { display: "flex", alignItems: "center", gap: "2" },
control: { borderWidth: "1px", borderRadius: "sm" },
label: { marginStart: "2" },
},
variants: {
size: {
sm: {
control: { width: "8", height: "8" },
label: { fontSize: "sm" },
},
md: {
control: { width: "10", height: "10" },
label: { fontSize: "md" },
},
},
},
})
```
## Using the recipe
There are two ways to use the recipe in a component:
- Directly in the component with `useSlotRecipe`
- As a compound component (recommended) with `createSlotRecipeContext`
:::info
Adding the `"use client"` directive is required to use the `useSlotRecipe` hook
or `createSlotRecipeContext` function. This is because they rely on react hooks
like `useContext` and `useInsertionEffect` under the hood.
:::
### Directly in component
Use the `useSlotRecipe` hook to get the recipe for a component. Then, call the
recipe with its variant props to get the styles.
```tsx title="checkbox.tsx"
"use client"
import { chakra, useSlotRecipe } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
export const Checkbox = (props) => {
const { size, ...restProps } = props
const recipe = useSlotRecipe({ recipe: checkboxSlotRecipe })
const styles = recipe({ size })
return (
Checkbox Label
)
}
```
#### splitVariantProps
Notice how the `size` prop was destructured from the props to be passed to the
recipe. A smarter approach would be to automatically split the recipe props from
the component props.
To do that, use the `recipe.splitVariantProps` function to split the recipe
props from the component props.
```tsx title="checkbox.tsx" {8}
"use client"
import { chakra, useSlotRecipe } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
export const Checkbox = (props) => {
const recipe = useSlotRecipe({ recipe: checkboxSlotRecipe })
const [recipeProps, restProps] = recipe.splitVariantProps(props)
const styles = recipe(recipeProps)
//...
}
```
#### TypeScript
To infer the recipe variant prop types, use the `RecipeVariantProps` type
helper.
```tsx title="checkbox.tsx"
import type { RecipeVariantProps } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
type CheckboxVariantProps = RecipeVariantProps
export interface CheckboxProps
extends React.PropsWithChildren {}
```
### Create compound components
Pass the recipe to the `createSlotRecipeContext` function to create a slot
recipe context.
Then, use the `withProvider` and `withContext` functions to create the compound
components that share the same context.
:::info
You will need to manually type the generics for `withProvider` and
`withContext`. This approach is designed to optimize TypeScript performance.
Auto-inference, while convenient, would slow down TypeScript compilation due to
the complexity of the types involved.
:::
```tsx title="checkbox.tsx"
"use client"
import { createSlotRecipeContext } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
const { withProvider, withContext } = createSlotRecipeContext({
recipe: checkboxSlotRecipe,
})
interface CheckboxRootProps
extends HTMLChakraProps<
"label",
RecipeVariantProps
> {}
export const CheckboxRoot = withProvider(
"label",
"root",
)
interface CheckboxControlProps extends HTMLChakraProps<"input"> {}
export const CheckboxControl = withContext<
HTMLInputElement,
CheckboxControlProps
>("input", "control")
interface CheckboxLabelProps extends HTMLChakraProps<"span"> {}
export const CheckboxLabel = withContext(
"span",
"label",
)
```
Pass the variant props to the "root" component that to apply the styles.
> **Note:** The root component is the one that used the `withProvider` function.
```tsx title="app.tsx"
const App = () => {
return (
)
}
```
#### unstyled prop
This approach supports the use of the `unstyled` prop to remove the styles
applied by the recipe.
```tsx title="checkbox.tsx" /unstyled/
```
#### TypeScript
To infer the recipe variant prop types, use the `RecipeVariantProps` type
helper.
```ts
import type { RecipeVariantProps, UnstyledProp } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
type CheckboxVariantProps = RecipeVariantProps
export interface CheckboxProps
extends React.PropsWithChildren,
UnstyledProp {}
```
## Compound Variants
Use the `compoundVariants` property to define a set of variants that are applied
based on a combination of other variants.
```tsx title="checkbox.recipe.ts" /compoundVariants/
import { defineSlotRecipe } from "@chakra-ui/react"
export const checkboxRecipe = defineSlotRecipe({
slots: ["root", "control", "label"],
base: {},
variants: {
size: {
sm: {},
md: {},
},
visual: {
contained: {},
outline: {},
},
},
compoundVariants: [
{
size: "sm",
visual: "outline",
css: {
control: { borderWidth: "1px" },
label: { color: "green.500" },
},
},
],
})
```
## Targeting a slot
In some cases, targeting a slot by className might be needed.
- Set the `className` property in the config
- The naming convention is `${className}__${slot}`
```tsx title="checkbox.recipe.ts" /& .checkbox__label/
import { defineSlotRecipe } from "@chakra-ui/react"
export const checkboxRecipe = defineSlotRecipe({
className: "checkbox",
slots: ["root", "control", "label"],
base: {
root: {
bg: "blue.500",
_hover: {
"& .checkbox__label": { color: "white" },
},
},
},
})
```
## Theme Usage
To use the recipe in a reusable manner, move it to the system theme and add it
to `theme.slotRecipes` property.
> No need to add the `"use client"` directive when using the recipe in the
> theme.
```tsx title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
import { checkboxSlotRecipe } from "./checkbox.recipe"
const config = defineConfig({
theme: {
slotRecipes: {
checkbox: checkboxSlotRecipe,
},
},
})
export default createSystem(defaultConfig, config)
```
### TypeScript
Use the CLI to generate the types for the recipe.
```bash
npx @chakra-ui/cli typegen ./theme.ts
```
Then, import the generated types in your component.
```tsx title="checkbox.tsx"
import type { SlotRecipeProps, UnstyledProp } from "@chakra-ui/react"
export interface CheckboxProps
extends SlotRecipeProps<"checkbox">,
UnstyledProp {}
```
### Update code
If you use the recipe directly in your component, update the `useRecipe` to use
the `key` property to get the recipe from the theme.
```diff title="checkbox.tsx"
const Checkbox = () => {
- const recipe = useRecipe({ recipe: checkboxRecipe })
+ const recipe = useRecipe({ key: "checkbox" })
// ...
}
```
If you create a compound component, update the `createSlotRecipeContext` to use
the `key` property.
```diff title="checkbox.tsx"
const { withProvider, withContext } = createSlotRecipeContext({
- recipe: checkboxRecipe,
+ key: "checkbox",
})
```
# Spacing
## Tokens
Chakra UI supports the following spacing tokens out of the box.
| Spacing Token | Value | Example |
| ------------- | ---------- | --------------------- |
| `0.5` | `0.125rem` | |
| `1` | `0.25rem` | |
| `1.5` | `0.375rem` | |
| `2` | `0.5rem` | |
| `2.5` | `0.625rem` | |
| `3` | `0.75rem` | |
| `3.5` | `0.875rem` | |
| `4` | `1rem` | |
| `4.5` | `1.125rem` | |
| `5` | `1.25rem` | |
| `6` | `1.5rem` | |
| `7` | `1.75rem` | |
| `8` | `2rem` | |
| `9` | `2.25rem` | |
| `10` | `2.5rem` | |
| `11` | `2.75rem` | |
| `12` | `3rem` | |
| `14` | `3.5rem` | |
| `16` | `4rem` | |
| `20` | `5rem` | |
| `24` | `6rem` | |
| `28` | `7rem` | |
| `32` | `8rem` | |
| `36` | `9rem` | |
| `40` | `10rem` | |
| `44` | `11rem` | |
| `48` | `12rem` | |
| `52` | `13rem` | |
| `56` | `14rem` | |
| `60` | `15rem` | |
| `64` | `16rem` | |
| `72` | `18rem` | |
| `80` | `20rem` | |
| `96` | `24rem` | |
# Text Styles
Chakra UI provides these text styles out of the box.
# Tokens
## Overview
Design tokens are the platform-agnostic way to manage design decisions in your
application or website. It is a collection of attributes that describe any
fundamental/atomic visual style. Each attribute is a key-value pair.
> Design tokens in Chakra are largely influenced by the
> [W3C Token Format](https://tr.designtokens.org/format/).
A design token consists of the following properties:
- `value`: The value of the token. This can be any valid CSS value.
- `description`: An optional description of what the token can be used for.
## Defining Tokens
Tokens are defined in the under the `theme` key in your system config.
```ts title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const config = defineConfig({
theme: {
tokens: {
colors: {
primary: { value: "#0FEE0F" },
secondary: { value: "#EE0F0F" },
},
fonts: {
body: { value: "system-ui, sans-serif" },
},
},
},
})
export const system = createSystem(defaultConfig, config)
```
:::warning
> Token values need to be nested in an object with a `value` key. This is to
> allow for additional properties like `description` and more in the future.
:::
## Using Tokens
After defining tokens, we recommend using the Chakra CLI to generate theme
typings for your tokens.
```bash
npx @chakra-ui/cli typegen ./src/theme.ts
```
This will provide autocompletion for your tokens in your editor.
```tsx
Hello World
```
### Token reference syntax
Chakra UI enables you to reference design tokens within composite values for CSS
properties like `border`, `padding`, and `box-shadow`.
This is achieved through the token reference syntax: `{path.to.token}`.
:::note
It is important to use the complete token path; for example, instead of using
`red.300`, you must reference it as `colors.red.300`.
:::
Here’s an example where token reference syntax is applied to both the border and
p (padding) props:
```tsx
```
## Token Nesting
Tokens can be nested to create a hierarchy of tokens. This is useful when you
want to group related tokens together.
:::info
Use the `DEFAULT` key to define the default value of a nested token.
:::
```ts title="theme.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const config = defineConfig({
theme: {
tokens: {
colors: {
red: {
DEFAULT: { value: "#EE0F0F" },
100: { value: "#EE0F0F" },
},
},
},
},
})
export default createSystem(defaultConfig, config)
```
```tsx
Hello World
```
## Token Types
### Colors
Colors have meaning and support the purpose of the content, communicating things
like hierarchy of information, and states. It is mostly defined as a string
value or reference to other tokens.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
colors: {
red: {
100: { value: "#fff1f0" },
},
},
})
export default createSystem({
theme: { tokens },
})
```
### Gradients
Gradient tokens represent a smooth transition between two or more colors. Its
value can be defined as a string or a composite value.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
gradients: {
// string value
simple: { value: "linear-gradient(to right, red, blue)" },
// composite value
primary: {
value: { type: "linear", placement: "to right", stops: ["red", "blue"] },
},
},
})
export default createSystem({
theme: { tokens },
})
```
### Sizes
Size tokens represent the width and height of an element. Its value is defined
as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
sizes: {
sm: { value: "12px" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Size tokens are typically used in `width`, `height`, `minWidth`, `maxWidth`,
> `minHeight`, `maxHeight` properties.
### Spacing
Spacing tokens represent the margin and padding of an element. Its value is
defined as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
spacing: {
gutter: { value: "12px" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Spacing tokens are typically used in `margin`, `padding`, `gap`, and
> `{top,right,bottom,left}` properties.
### Fonts
Font tokens represent the font family of a text element. Its value is defined as
a string or an array of strings.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
fonts: {
body: { value: "Inter, sans-serif" },
heading: { value: ["Roboto Mono", "sans-serif"] },
},
})
export default createSystem({
theme: { tokens },
})
```
> Font tokens are typically used in `font-family` property.
### Font Sizes
Font size tokens represent the size of a text element. Its value is defined as a
string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
fontSizes: {
sm: { value: "12px" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Font size tokens are typically used in `font-size` property.
### Font Weights
Font weight tokens represent the weight of a text element. Its value is defined
as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
fontWeights: {
bold: { value: "700" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Font weight tokens are typically used in `font-weight` property.
### Letter Spacings
Letter spacing tokens represent the spacing between letters in a text element.
Its value is defined as a string.
```tsx
const tokens = defineTokens({
letterSpacings: {
wide: { value: "0.1em" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Letter spacing tokens are typically used in `letter-spacing` property.
### Line Heights
Line height tokens represent the height of a line of text. Its value is defined
as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
lineHeights: {
normal: { value: "1.5" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Line height tokens are typically used in `line-height` property.
### Radii
Radii tokens represent the radius of a border. Its value is defined as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
radii: {
sm: { value: "4px" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Radii tokens are typically used in `border-radius` property.
### Borders
A border is a line surrounding a UI element. You can define them as string
values or as a composite value
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
borders: {
// string value
subtle: { value: "1px solid red" },
// string value with reference to color token
danger: { value: "1px solid {colors.red.400}" },
// composite value
accent: { value: { width: "1px", color: "red", style: "solid" } },
},
})
export default createSystem({
theme: { tokens },
})
```
> Border tokens are typically used in `border`, `border-top`, `border-right`,
> `border-bottom`, `border-left`, `outline` properties.
### Border Widths
Border width tokens represent the width of a border. Its value is defined as a
string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
borderWidths: {
thin: { value: "1px" },
thick: { value: "2px" },
medium: { value: "1.5px" },
},
})
export default createSystem({
theme: { tokens },
})
```
### Shadows
Shadow tokens represent the shadow of an element. Its value is defined as single
or multiple values containing a string or a composite value.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
shadows: {
// string value
subtle: { value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
// composite value
accent: {
value: {
offsetX: 0,
offsetY: 4,
blur: 4,
spread: 0,
color: "rgba(0, 0, 0, 0.1)",
},
},
// multiple string values
realistic: {
value: [
"0 1px 2px 0 rgba(0, 0, 0, 0.05)",
"0 1px 4px 0 rgba(0, 0, 0, 0.1)",
],
},
},
})
export default createSystem({
theme: { tokens },
})
```
> Shadow tokens are typically used in `box-shadow` property.
### Easings
Easing tokens represent the easing function of an animation or transition. Its
value is defined as a string or an array of values representing the cubic
bezier.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
easings: {
// string value
easeIn: { value: "cubic-bezier(0.4, 0, 0.2, 1)" },
// array value
easeOut: { value: [0.4, 0, 0.2, 1] },
},
})
export default createSystem({
theme: { tokens },
})
```
> Ease tokens are typically used in `transition-timing-function` property.
### Opacity
Opacity tokens help you set the opacity of an element.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
opacity: {
50: { value: 0.5 },
},
})
export default createSystem({
theme: { tokens },
})
```
> Opacity tokens are typically used in `opacity` property.
### Z-Index
This token type represents the depth of an element's position on the z-axis.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
zIndex: {
modal: { value: 1000 },
},
})
export default createSystem({
theme: { tokens },
})
```
> Z-index tokens are typically used in `z-index` property.
### Assets
Asset tokens represent a url or svg string. Its value is defined as a string or
a composite value.
```ts
type CompositeAsset = { type: "url" | "svg"; value: string }
type Asset = string | CompositeAsset
```
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
tokens: {
assets: {
logo: {
value: { type: "url", value: "/static/logo.png" },
},
checkmark: {
value: { type: "svg", value: "" },
},
},
},
})
export default createSystem({
theme: { tokens },
})
```
> Asset tokens are typically used in `background-image` property.
### Durations
Duration tokens represent the length of time in milliseconds an animation or
animation cycle takes to complete. Its value is defined as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
durations: {
fast: { value: "100ms" },
},
})
export default createSystem({
theme: { tokens },
})
```
> Duration tokens are typically used in `transition-duration` and
> `animation-duration` properties.
### Animations
Animation tokens represent a keyframe animation. Its value is defined as a
string value.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
animations: {
spin: {
value: "spin 1s linear infinite",
},
},
})
export default createSystem({
theme: { tokens },
})
```
> Animation tokens are typically used in `animation` property.
### Aspect Ratios
Aspect ratio tokens represent the aspect ratio of an element. Its value is
defined as a string.
```tsx title="theme.ts"
import { defineTokens } from "@chakra-ui/react"
const tokens = defineTokens({
aspectRatios: {
"1:1": { value: "1 / 1" },
"16:9": { value: "16 / 9" },
},
})
export default createSystem({
theme: { tokens },
})
```
# Typography
## Fonts
Here's the list of available fonts.
| Font Token | Example |
| ---------- | ----------------------------- |
| `heading` | |
| `body` | |
| `mono` | |
## Font Sizes
Here's the list of available font sizes.
| Font Size Token | Value | Example |
| --------------- | ---------- | ----------------------- |
| `2xs` | `0.625rem` | |
| `xs` | `0.75rem` | |
| `sm` | `0.875rem` | |
| `md` | `1rem` | |
| `lg` | `1.125rem` | |
| `xl` | `1.25rem` | |
| `2xl` | `1.5rem` | |
| `3xl` | `1.875rem` | |
| `4xl` | `2.25rem` | |
| `5xl` | `3rem` | |
| `6xl` | `3.75rem` | |
| `7xl` | `4.5rem` | |
| `8xl` | `6rem` | |
| `9xl` | `8rem` | |
## Font Weights
Here's the list of available font weights.
| Font Weight Token | Value | Example |
| ----------------- | ----- | -------------------------------- |
| `thin` | `100` | |
| `extralight` | `200` | |
| `light` | `300` | |
| `normal` | `400` | |
| `medium` | `500` | |
| `semibold` | `600` | |
| `bold` | `700` | |
| `extrabold` | `800` | |
| `black` | `900` | |
## Line Heights
Here's the list of available line heights.
| Line Height Token | Value | Example |
| ----------------- | ------- | ------------------------------ |
| `shorter` | `1.25` | |
| `short` | `1.375` | |
| `moderate` | `1.5` | |
| `tall` | `1.625` | |
| `taller` | `2` | |
## Letter Spacings
Here's the list of available letter spacing.
| Letter Spacing Token | Value | Example |
| -------------------- | ---------- | -------------------------------- |
| `tighter` | `-0.05em` | |
| `tight` | `-0.025em` | |
| `wide` | `0.025em` | |
| `wider` | `0.05em` | |
| `widest` | `0.1em` | |
# Z-Index
## Tokens
Chakra UI supports the following z-index tokens out of the box.
| Z Index Token | Value | Example |
| ------------- | ------------ | ------------------------- |
| `hide` | `-1` | |
| `base` | `0` | |
| `docked` | `10` | |
| `dropdown` | `1000` | |
| `sticky` | `1100` | |
| `banner` | `1200` | |
| `overlay` | `1300` | |
| `modal` | `1400` | |
| `popover` | `1500` | |
| `skipNav` | `1600` | |
| `toast` | `1700` | |
| `tooltip` | `1800` | |
| `max` | `2147483647` | |
# LLMs.txt Documentation
We support [LLMs.txt](https://llmstxt.org/) files for making the Chakra UI v3
documentation available to large language models.
## Directory Overview
The following files are available.
- [/llms.txt](https://chakra-ui.com/llms.txt): The main LLMs.txt file
- [/llms-full.txt](https://chakra-ui.com/llms-full.txt): The complete
documentation for Chakra UI v3
---
Separate docs are available if you have a limited context window.
- [/llms-components.txt](https://chakra-ui.com/llms-components.txt): Only
component documentation
- [/llms-styling.txt](https://chakra-ui.com/llms-styling.txt): Only styling
documentation
- [/llms-theming.txt](https://chakra-ui.com/llms-theming.txt): Only theming
documentation
---
We also have a special `llms-v3-migration.txt` file that contains documentation
for migrating to Chakra UI v3.
- [/llms-v3-migration.txt](https://chakra-ui.com/llms-v3-migration.txt):
Documentation for migrating to Chakra UI v3
## Usage
### Cursor
Use `@Docs` feature in Cursor to include the LLMs.txt files in your project.
[Read more](https://docs.cursor.com/context/@-symbols/@-docs)
### Windstatic
Reference the LLMs.txt files using `@` or in your `.windsurfrules` files.
[Read more](https://docs.codeium.com/windsurf/memories#memories-and-rules)
# MCP Server
The Chakra UI MCP Server is a specialized
[Model Context Protocol](https://modelcontextprotocol.io/introduction) server
that provides AI assistants (like Claude Code, Cursor, and Copilot) with access
to the Chakra UI component library, design tokens, and migration guidance.
## Tools
The Chakra UI MCP exposes the following tools to AI agents:
### Component Tools
- **`list_components`**: Get a complete list of all available components
- **`get_component_props`**: Detailed props, types, and configuration options
for any component
- **`get_component_example`**: Retrieve code examples and usage patterns
### Chakra UI Pro Tools
These tools provide AI agents with access to well-designed, fully responsive,
and accessible component templates from Chakra UI Pro.
- **`list_component_templates`**: List available component templates from Chakra
UI Pro
- **`get_component_templates`**: Retrieve well-designed, fully responsive, and
accessible component templates from Chakra UI Pro
:::note
These tools require an active [Chakra UI Pro](https://pro.chakra-ui.com/pricing)
license and setting the `CHAKRA_PRO_API_KEY` environment variable with your API
key generated from Chakra UI Pro. See the
[Chakra UI Pro Integration](#chakra-ui-pro-integration) section for setup
instructions.
:::
### Design System Tools
- **`get_theme`**: Get a detailed list of all the design tokens
- **`theme_customization`**: Custom theme token creation and modification
### Migration Tools
- **`v2_to_v3_code_review`**: Migration guidance from version 2 to version 3
## Setup
The MCP server currently supports only
[stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio)
and is published at `@chakra-ui/react-mcp`.
### Visual Studio Code
> Make sure you have the
> [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot)
> and
> [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat)
> extensions installed.
In the `.vscode/mcp.json` file at the root of your project, add the MCP server
block:
```json title=".vscode/mcp.json"
{
"servers": {
"chakra-ui": {
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
```
The MCP server is now ready to use. Click on Start on the MCP server.
### Cursor
In the `.cursor/mcp.json` file at the root of your project, add the following
configuration:
```json
{
"mcpServers": {
"chakra-ui": {
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
```
> If Cursor doesn't automatically detect the changes, restart the editor or
> manually enable the Chakra UI server via "MCP Tools."
### Claude Code
> Make sure you have Claude Code installed. Visit
> [Anthropic docs](https://docs.anthropic.com/en/docs/claude-code/mcp) for
> installation instructions.
Run the following command in your terminal to add the Chakra UI MCP server:
```bash
claude mcp add chakra-ui -- npx -y @chakra-ui/react-mcp
```
The MCP server is now ready to use. Start a Claude Code session by running
`claude`.
### Windsurf
1. Navigate to "Settings" > "Windsurf Settings" > "Cascade"
2. Click the "Manage MCPs" button, then click the "View raw config" button.
3. Add the following to the MCP configuration file:
```json title=".codeium/windsurf/mcp_config.json"
{
"mcpServers": {
"chakra-ui": {
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
```
> You might need to click the "Refresh" button to see the MCP server in the
> list.
### Zed
1. Go to Settings > Open Settings
2. In the `settings.json` file, add MCP server as a new **context server**
```json title=".config/zed/settings.json"
{
"context_servers": {
"chakra-ui": {
"source": "custom",
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
```
### Custom MCP Client
To run the MCP server in a local or development environment using a custom MCP
client, you need to add the MCP server to the client's configuration file.
```json
{
"mcpServers": {
"chakra-ui": {
"command": "npx",
"args": ["-y", "@chakra-ui/react-mcp"]
}
}
}
```
## Chakra UI Pro Integration
To enable access to premium component templates from Chakra UI Pro, you'll need
to configure your API key. This requires an active
[Chakra UI Pro](https://pro.chakra-ui.com/pricing) license.
### Setting Up Your API Key
1. Get your API key from the [Chakra UI Pro](https://pro.chakra-ui.com) user
menu.
2. Add the `CHAKRA_PRO_API_KEY` environment variable to your MCP configuration:
**For editors with `env` support (VS Code, Cursor, Windsurf, Zed, Custom MCP):**
```json
{
"env": {
"CHAKRA_PRO_API_KEY": "your_api_key_here"
}
}
```
**For Claude Code:**
```bash
claude mcp add chakra-ui --env CHAKRA_PRO_API_KEY=your_api_key_here -- npx -y @chakra-ui/react-mcp
```
Once configured, the `list_component_templates` and `get_component_templates`
tools will be available for accessing PRO component templates.
# AI Rules
Configure your AI coding assistants (like Cursor, GitHub Copilot, or Claude) by
adding these rules to your project's `.cursorrules`,
`.github/copilot-instructions.md`, or AI configuration file.
## Configuration File
Create a file with the following rules in your project root:
```yaml
---
description: Chakra UI v3 Development Rules
globs: "*.tsx"
alwaysApply: false
---
```
## Rules
### Core Migration
```md
## Core Migration Rules
### Package Changes
# Removed Packages
- Remove @emotion/styled and framer-motion dependencies
- Icons: Use lucide-react or react-icons instead of @chakra-ui/icons
- Hooks: Use react-use or usehooks-ts instead of @chakra-ui/hooks
- Next.js: Use asChild prop instead of @chakra-ui/next-js package
### Import Sources
Always use correct import sources:
# From @chakra-ui/react:
Alert, Avatar, Button, Card, Field, Table, Input, NativeSelect, Tabs, Textarea,
Separator, useDisclosure, Box, Flex, Stack, HStack, VStack, Text, Heading, Icon
# From components/ui (relative imports):
Provider, Toaster, ColorModeProvider, Tooltip, PasswordInput
```
### Component
````mdx
### Toast System
```tsx
// ✅ New v3 way
import { toaster } from "./components/ui/toaster"
// ❌ Old v2 way
const toast = useToast()
toast({
title: "Title",
status: "error",
isClosable: true,
position: "top-right",
})
toaster.create({
title: "Title",
type: "error", // status → type
meta: {
closable: true, // isClosable → meta.closable
},
placement: "top-end", // top-right → top-end
})
```
### Dialog (formerly Modal)
```tsx
// ❌ Old v2
Title
Content
// ✅ New v3
Title
Content
```
### Button Icons
```tsx
// ❌ Old v2
} rightIcon={}>
Email
// ✅ New v3
```
### Alert Structure
```tsx
// ❌ Old v2
Title
Description
// ✅ New v3
Title
Description
```
### Tooltip
```tsx
// ❌ Old v2
// ✅ New v3
import { Tooltip } from "./components/ui/tooltip"
```
### Input with Validation
```tsx
// ❌ Old v2
// ✅ New v3
Email
This field is required
```
### Table Structure
```tsx
// ❌ Old v2
// ✅ New v3
Header
Cell
```
### Tabs
```tsx
// ❌ Old v2
One
Content
// ✅ New v3
One
Content
```
### Menu
```tsx
// ❌ Old v2
// ✅ New v3
Download
```
### Popover
```tsx
// ❌ Old v2
Content
// ✅ New v3
Content
```
### Select/NativeSelect
```tsx
// ❌ Old v2
// ✅ New v3
```
````
### Prop Name
```md
## Prop Name Rules
### Boolean Props
- `isOpen` → `open`
- `isDisabled` → `disabled`
- `isInvalid` → `invalid`
- `isRequired` → `required`
- `isActive` → `data-active`
- `isLoading` → `loading`
- `isChecked` → `checked`
- `isIndeterminate` → `indeterminate`
### Style Props
- `colorScheme` → `colorPalette`
- `spacing` → `gap`
- `noOfLines` → `lineClamp`
- `truncated` → `truncate`
- `thickness` → `borderWidth`
- `speed` → `animationDuration`
### Component-Specific
- Divider → Separator
- Modal → Dialog
- Collapse → Collapsible
- Tags → Badge
- useToast → toaster.create()
```
### Style System
````md
## Style System Rules
### Nested Styles
```tsx
// ❌ Old v2
// ✅ New v3 (the & is required)
```
### Gradients
```tsx
// ❌ Old v2
// ✅ New v3
```
### Theme Access
```tsx
// ❌ Old v2
const theme = useTheme()
const gray400 = theme.colors.gray["400"]
// ✅ New v3
const system = useChakra()
const gray400 = system.token("colors.gray.400")
```
````
## Example .cursorrules File
Create a `.cursorrules` file in your project root. Then feel free to copy and
paste the rules above.
Here's an example:
```mdx
---
description: Chakra UI v3 Development
globs: "*.tsx"
---
# Chakra UI v3 Rules
This project uses Chakra UI v3. Follow these rules:
1. Import from @chakra-ui/react: Alert, Avatar, Button, Card, Field, Table, etc.
2. Import from components/ui: Checkbox, Drawer, Radio, Menu, Dialog, Tooltip,
etc.
3. Use toaster.create() instead of useToast()
4. Modal is now Dialog with different props
5. Boolean props changed: isOpen → open, isDisabled → disabled
6. colorScheme → colorPalette
7. Button icons are children, not props
8. Always use VStack/HStack, not Stack
9. Use compound components for complex components
10. Check migration guide for component-specific changes
```
## Resources
- [Full Migration Guide](/docs/get-started/migration)
- [Component Documentation](/docs/components)
- [Theming Guide](/docs/theming)
# Using Chakra UI in Iframe
Iframes are useful for isolating styles and logic in a separate context. For
example, you might want to showcase a Chakra component in dedicated sandbox.
## Template
Use the following template to get started quickly
:::card-group
:::
## Installation
> The minimum node version required is Node.20.x
:::steps
### Install dependencies
```bash
npm i @chakra-ui/react @emotion/react @emotion/cache react-frame-component
```
The additional packages used are:
- `react-frame-component` used to create an iframe easily
- `@emotion/cache` used to create a custom insertion point for styles
### Add snippets
Snippets are pre-built components that you can use to build your UI faster.
Using the `@chakra-ui/cli` you can add snippets to your project.
```bash
npx @chakra-ui/cli snippet add
```
### Update tsconfig
If you're using TypeScript, you need to update the `compilerOptions` in the
tsconfig file to include the following options:
```json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
```
### Setup Iframe
Create a `components/ui/iframe-provider.tsx` file to setup the iframe using the
`react-frame-component` package.
```tsx title="components/ui/iframe-provider.tsx"
import {
ChakraProvider,
EnvironmentProvider,
defaultSystem,
} from "@chakra-ui/react"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import Iframe, { FrameContextConsumer } from "react-frame-component"
function memoize(func: (arg: T) => R): (arg: T) => R {
const cache = new WeakMap()
return (arg: T) => {
if (cache.has(arg)) return cache.get(arg)!
const ret = func(arg)
cache.set(arg, ret)
return ret
}
}
const createCacheFn = memoize((container: HTMLElement) =>
createCache({ container, key: "frame" }),
)
export const IframeProvider = (props: React.PropsWithChildren) => {
const { children } = props
return (
)
}
```
### Setup provider
Wrap your application with the `Provider` component generated in the
`components/ui/provider` component at the root of your application.
This provider composes the following:
- `ChakraProvider` from `@chakra-ui/react` for the styling system
- `ThemeProvider` from `next-themes` for color mode
```jsx
import { Provider } from "@/components/ui/provider"
import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App"
ReactDOM.createRoot(document.getElementById("root")!).render(
,
)
```
### Use the IframeProvider
At any component in your application, wrap it with the `IframeProvider`
component to render it inside the iframe.
```tsx title="src/App.tsx"
import { Button, Container, Heading, Stack } from "@chakra-ui/react"
import { IframeProvider } from "./components/ui/iframe-provider"
function App() {
return (
Outside Iframe
Inside Iframe
)
}
export default App
```
:::
## Customization
If you created a custom theme using the `createSystem` function, ensure it's
passed to the `IframeProvider` and `Provider` components to ensure it's used
inside the iframe.
For example, let's say you created a custom theme:
```ts
export const system = createSystem(defaultConfig, {
theme: { colors: {} },
})
```
Then, pass it to the `IframeProvider` and `Provider` components:
```tsx
{/* ... */}
```
# Using Chakra UI in Shadow DOM
When developing extensions for browsers or using Chakra as part of a large
project, leveraging the Shadow DOM is useful for style and logic encapsulation.
## Template
Use the following template to get started quickly
:::card-group
:::
## Installation
> The minimum node version required is Node.20.x
:::steps
### Install dependencies
```bash
npm i @chakra-ui/react @emotion/react @emotion/cache react-shadow
```
The additional packages used are:
- `react-shadow` used to create a Shadow DOM easily
- `@emotion/cache` used to create a custom insertion point for styles
### Add snippets
Snippets are pre-built components that you can use to build your UI faster.
Using the `@chakra-ui/cli` you can add snippets to your project.
```bash
npx @chakra-ui/cli snippet add
```
### Update tsconfig
If you're using TypeScript, you need to update the `compilerOptions` in the
tsconfig file to include the following options:
```json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
```
### Configure style engine
Create a `system.ts` file in the root of your project and configure the style
engine.
```tsx title="components/ui/system.ts"
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const varRoot = ":host"
const config = defineConfig({
cssVarsRoot: varRoot,
conditions: {
light: `${varRoot} &, .light &`,
},
preflight: { scope: varRoot },
globalCss: {
[varRoot]: defaultConfig.globalCss?.html ?? {},
},
})
export const system = createSystem(defaultConfig, config)
```
> **Good to know**: The main purpose of the `system.ts` file is to configure the
> style engine to target the Shadow DOM.
### Setup provider
Update the generated `components/ui/provider` component with the `Provider`
component.
This provider composes the following:
- `ChakraProvider` from `@chakra-ui/react` for the styling system
- `EnvironmentProvider` from `react-shadow` to ensure Chakra components query
the DOM correctly
- `CacheProvider` from `@emotion/react` to provide the custom insertion point
- `ThemeProvider` from `next-themes` for color mode
```tsx title="components/ui/provider.tsx"
"use client"
import { ChakraProvider, EnvironmentProvider } from "@chakra-ui/react"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import { ThemeProvider, type ThemeProviderProps } from "next-themes"
import { useEffect, useState } from "react"
import root from "react-shadow/emotion"
import { system } from "./system"
export function Provider(props: ThemeProviderProps) {
const [shadow, setShadow] = useState(null)
const [cache, setCache] = useState | null>(
null,
)
useEffect(() => {
if (!shadow?.shadowRoot || cache) return
const emotionCache = createCache({
key: "root",
container: shadow.shadowRoot,
})
setCache(emotionCache)
}, [shadow, cache])
return (
{shadow && cache && (
shadow.shadowRoot ?? document}>
)}
)
}
```
### Use the provider
Wrap your application with the `Provider` component generated in the
`components/ui/provider` component at the root of your application.
```tsx title="src/main.tsx" {1,8,10}
import { Provider } from "@/components/ui/provider"
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import App from "./App.tsx"
createRoot(document.getElementById("root")!).render(
,
)
```
### Enjoy!
With the power of the snippets and the primitive components from Chakra UI, you
can build your UI faster.
```tsx
import { Button, HStack } from "@chakra-ui/react"
export default function App() {
return (
)
}
```
:::
# Using Chakra UI in Next.js (App)
## Templates
Use one of the following templates to get started quickly. The templates are
configured correctly to use Chakra UI.
:::card-group
:::
## Installation
> The minimum node version required is Node.20.x
:::steps
### Install dependencies
```bash
npm i @chakra-ui/react @emotion/react
```
### Add snippets
Snippets are pre-built components that you can use to build your UI faster.
Using the `@chakra-ui/cli` you can add snippets to your project.
```bash
npx @chakra-ui/cli snippet add
```
### Update tsconfig
If you're using TypeScript, you need to update the `compilerOptions` in the
tsconfig file to include the following options:
```json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
```
> If you're using JavaScript, create a `jsconfig.json` file and add the above
> code to the file.
### Setup provider
Wrap your application with the `Provider` component generated in the
`components/ui/provider` component at the root of your application.
This provider composes the following:
- `ChakraProvider` from `@chakra-ui/react` for the styling system
- `ThemeProvider` from `next-themes` for color mode
```tsx title="app/layout.tsx" {1,6,8}
import { Provider } from "@/components/ui/provider"
export default function RootLayout(props: { children: React.ReactNode }) {
const { children } = props
return (
{children}
)
}
```
> Adding the `suppressHydrationWarning` prop to the `html` element is required
> to prevent the warning about the `next-themes` library.
### Optimize Bundle
We recommend using the `experimental.optimizePackageImports` feature in Next.js
to optimize your bundle size by loading only the modules that you are actually
using.
```tsx title="next.config.mjs" {3}
export default {
experimental: {
optimizePackageImports: ["@chakra-ui/react"],
},
}
```
This also helps to resolve warnings like:
```sh
[webpack.cache.PackFileCacheStrategy] Serializing big strings (xxxkiB)
```
### Hydration errors
If you see an error like this: **Hydration failed because the initial server
rendered HTML did not match the client**, and the error looks similar to:
```diff
+
- |