Build faster with Premium Chakra UI Components 💎
Learn moreWe've just shipped Chakra UI v3.26! This release introduces the highly anticipated Listbox component, bringing powerful selection capabilities to Chakra UI.
This release also made important improvements to the CodeBlock component and fixed several bugs across more components.
The Listbox component is a versatile selection component that provides single and multi-select functionality with support for filtering, grid layout, and virtualization.
Use it to build command palettes, searchable dropdowns, transfer lists, image galleries with selection, and much more.
"use client"
import { Listbox, createListCollection } from "@chakra-ui/react"
const Demo = () => {
return (
<Listbox.Root collection={frameworks} width="320px">
<Listbox.Label>Select framework</Listbox.Label>
<Listbox.Content>
{frameworks.items.map((framework) => (
<Listbox.Item item={framework} key={framework.value}>
<Listbox.ItemText>{framework.label}</Listbox.ItemText>
<Listbox.ItemIndicator />
</Listbox.Item>
))}
</Listbox.Content>
</Listbox.Root>
)
}
const frameworks = createListCollection({
items: [
{ label: "React.js", value: "react" },
{ label: "Vue.js", value: "vue" },
{ label: "Angular", value: "angular" },
{ label: "Svelte", value: "svelte" },
],
})
Here's a fun example of an emoji picker that composes the listbox with grid collection.
"use client"
import {
Input,
Listbox,
Square,
createGridCollection,
useFilter,
useListboxContext,
} from "@chakra-ui/react"
import emojibase from "emojibase-data/en/compact.json"
import { useCallback, useMemo, useState } from "react"
import { LuSmile } from "react-icons/lu"
type Emoji = (typeof emojibase)[number]
const emojis = emojibase
.filter((e) => !e.label.startsWith("regional indicator"))
.slice(0, 200) as Emoji[]
const Demo = () => {
const { contains } = useFilter({ sensitivity: "base" })
const [items, setItems] = useState(emojis)
const collection = useMemo(
() =>
createGridCollection({
columnCount: 8,
items: items,
itemToString(item) {
return `${item.label} (${item.shortcodes})`
},
itemToValue(item) {
return item.hexcode
},
}),
[items],
)
const filter = useCallback(
(value: string) => {
setItems(emojis.filter((e) => contains(e.label, value)))
},
[contains],
)
return (
<Listbox.Root collection={collection} maxW="min-content">
<SelectedEmoji />
<Listbox.Input
as={Input}
placeholder="Type to filter frameworks..."
onChange={(e) => filter(e.target.value)}
/>
<Listbox.Content
w="374px"
display="grid"
gridTemplateColumns="repeat(8, 1fr)"
gap="1"
>
{collection.items.map((item, index) => (
<Listbox.Item
item={item}
key={index}
css={{
width: "40px",
height: "40px",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: "md",
fontSize: "22px",
}}
>
{item.unicode}
</Listbox.Item>
))}
</Listbox.Content>
</Listbox.Root>
)
}
const SelectedEmoji = () => {
const listbox = useListboxContext()
const [item] = listbox.selectedItems as Emoji[]
return (
<Square size="40px" bg="bg.muted" rounded="sm" textStyle="lg">
{item ? item.unicode : <LuSmile />}
</Square>
)
}
HoverCard: Added support for disabled
prop to conditionally disable
hover interactions.
CodeBlock [Breaking Change]: Theme configuration is now required when creating a Shiki adapter:
// Before
const adapter = createShikiAdapter({
async load() { /* ... */ },
})
// After
const adapter = createShikiAdapter({
async load() { /* ... */ },
theme: {
light: "github-light",
dark: "github-dark",
},
// or theme: 'github-dark'
})
data-scrubbing
attributeTo upgrade to the latest version, run:
npm install @chakra-ui/react@latest
Make sure to update your CodeBlock configuration if you're using the Shiki adapter, as the theme property is now required.
We're excited to see what you build with the new Listbox component! Share your creations with us on Twitter or in our Discord community.