List Box
Lista de opções sempre visível, com seleção simples ou múltipla e navegação por teclado.
'use client';
import { ListBox, ListBoxItem } from '@/components/ui/list-box';
export default function ListBoxDemo() {
return (
<ListBox aria-label="Segmento" selectionMode="single" defaultSelectedKeys={['padaria']} className="w-64">
<ListBoxItem id="padaria">Padaria</ListBoxItem>
<ListBoxItem id="restaurante">Restaurante</ListBoxItem>
<ListBoxItem id="oficina">Oficina mecânica</ListBoxItem>
<ListBoxItem id="clinica">Clínica</ListBoxItem>
<ListBoxItem id="salao" isDisabled>
Salão de beleza (em breve)
</ListBoxItem>
</ListBox>
);
}Instalação
npx shadcn@latest add @lenstech/list-boxUso
import { ListBox, ListBoxItem } from "@/components/ui/list-box"<ListBox aria-label="Segmento" selectionMode="single">
<ListBoxItem id="padaria">Padaria</ListBoxItem>
<ListBoxItem id="clinica">Clínica</ListBoxItem>
</ListBox>O List Box é a base do Select e do Combobox: dentro deles, a moldura some porque o popover já a fornece.
Seleção é um Set de chaves
Cada item é identificado pelo id. selectedKeys / defaultSelectedKeys recebem uma lista (ou Set) de ids e
onSelectionChange entrega um Selection — um Set de chaves ou a string "all". Se o conteúdo do item não
for texto puro, informe textValue (usado na busca por digitação e por leitores de tela).
Exemplos
Seleção múltipla
'use client';
import { ListBox, ListBoxItem } from '@/components/ui/list-box';
export default function ListBoxMultiple() {
return (
<ListBox
aria-label="Formas de pagamento"
selectionMode="multiple"
defaultSelectedKeys={['pix', 'cartao']}
className="w-64"
>
<ListBoxItem id="pix">Pix</ListBoxItem>
<ListBoxItem id="cartao">Cartão</ListBoxItem>
<ListBoxItem id="boleto">Boleto</ListBoxItem>
<ListBoxItem id="dinheiro">Dinheiro</ListBoxItem>
</ListBox>
);
}Seções, ícones e separador
'use client';
import { Store, Truck, Wallet } from 'lucide-react';
import { ListBox, ListBoxItem, ListBoxSection, ListBoxSeparator } from '@/components/ui/list-box';
export default function ListBoxSections() {
return (
<ListBox aria-label="Configurações" selectionMode="single" defaultSelectedKeys={['loja']} className="w-64">
<ListBoxSection title="Vendas">
<ListBoxItem id="loja" textValue="Loja">
<Store /> Loja
</ListBoxItem>
<ListBoxItem id="pagamentos" textValue="Pagamentos">
<Wallet /> Pagamentos
</ListBoxItem>
</ListBoxSection>
<ListBoxSeparator />
<ListBoxSection title="Logística">
<ListBoxItem id="entregas" textValue="Entregas">
<Truck /> Entregas
</ListBoxItem>
</ListBoxSection>
</ListBox>
);
}Itens dinâmicos e controlado
Passe items e uma função como filho para renderizar dados de uma lista. Com disallowEmptySelection, sempre
há um item selecionado.
Agendando com: Dra. Ana Souza
'use client';
import { useState } from 'react';
import type { Selection } from 'react-aria-components';
import { ListBox, ListBoxItem } from '@/components/ui/list-box';
const profissionais = [
{ id: 'ana', nome: 'Dra. Ana Souza', especialidade: 'Ortodontia' },
{ id: 'bruno', nome: 'Dr. Bruno Lima', especialidade: 'Implantes' },
{ id: 'carla', nome: 'Dra. Carla Mendes', especialidade: 'Clínico geral' },
];
export default function ListBoxDynamic() {
const [selecionado, setSelecionado] = useState<Selection>(new Set(['ana']));
const id = [...(selecionado === 'all' ? [] : selecionado)][0];
const atual = profissionais.find((p) => p.id === id);
return (
<div className="flex flex-col gap-3">
<ListBox
aria-label="Profissional"
items={profissionais}
selectionMode="single"
disallowEmptySelection
selectedKeys={selecionado}
onSelectionChange={setSelecionado}
className="w-64"
>
{(p) => (
<ListBoxItem textValue={p.nome}>
<div className="flex flex-col gap-0.5">
<span>{p.nome}</span>
<span className="text-xs text-muted-foreground">{p.especialidade}</span>
</div>
</ListBoxItem>
)}
</ListBox>
<p className="text-sm text-muted-foreground">Agendando com: {atual?.nome}</p>
</div>
);
}Estado vazio
'use client';
import { ListBox, ListBoxItem } from '@/components/ui/list-box';
const clientes: { id: string; nome: string }[] = [];
export default function ListBoxEmpty() {
return (
<ListBox
aria-label="Clientes"
items={clientes}
renderEmptyState={() => 'Nenhum cliente cadastrado.'}
className="w-64"
>
{(cliente) => <ListBoxItem>{cliente.nome}</ListBoxItem>}
</ListBox>
);
}Quando usar
- Use para listas visíveis em painéis e filtros, com seleção simples ou múltipla.
- Não use em formulários com pouco espaço — use
Select. - Não use para listas longas com busca — use
Combobox. - Não use para ações (editar, excluir) — use
Menu.
API
ListBox
Aceita todas as props do ListBox do React Aria. As mais usadas:
Prop
Type
ListBoxItem
Aceita todas as props do ListBoxItem do React Aria (id, textValue, isDisabled, href…). Mostra ✓ à
direita quando selecionado.
ListBoxSection
Prop
Type
ListBoxHeader e ListBoxSeparator
Título de seção manual e divisor entre opções.