Skip to main content

ListExpandable

O componente ListExpandable é um item de lista interativo que permite expandir e colapsar conteúdo adicional. Ideal para listas de transações, detalhes de pedidos, informações adicionais ou qualquer conteúdo que precise ser ocultado inicialmente.

Importação

import { ListExpandable } from '@useblu/ocean-react';

Importação específica (recomendado para tree-shaking)

import { ListExpandable } from '@useblu/ocean-react/ListExpandable';

Importação de tipos TypeScript

import type { ListExpandableProps } from '@useblu/ocean-react';

// Uso em componente customizado
const MyComponent: React.FC<ListExpandableProps> = (props) => {
return <ListExpandable {...props} />;
};

Playground Interativo

Explore o componente ListExpandable no playground interativo do Storybook:

Documentação Completa

Para documentação técnica detalhada, exemplos de uso e API completa, consulte o Storybook do ListExpandable.

No Storybook você encontrará:

  • Controles interativos para testar todas as props
  • API gerada automaticamente com tipagem completa
  • Exemplos visuais de todas as variantes e estados
  • Playground para experimentação rápida

Uso básico

<ListExpandable
title="Detalhes da Transação"
description="PIX enviado - 25/11/2025"
icon={<PlaceholderOutline size={24} />}
>
<div style={{ padding: '16px', background: '#f3f5fe' }}>
<p>Destinatário: João Silva</p>
<p>Valor: R$ 150,00</p>
<p>ID: ABC123456</p>
</div>
</ListExpandable>

Tipos de Estilo (type)

O ListExpandable suporta dois tipos visuais principais:

Card (padrão)

Estilo com fundo e bordas de card, ideal para uso dentro de listas.

<ListExpandable
title="Tipo Card"
description="Estilo padrão com visual de card"
type="card"
>
<div>Conteúdo expandido</div>
</ListExpandable>

Text

Estilo apenas texto, sem background de card, ideal para uso fora de listas ou em contextos mais simples.

<ListExpandable
title="Tipo Text"
description="Estilo apenas texto, sem card"
type="text"
showDivider
>
<div>Conteúdo expandido</div>
</ListExpandable>

Status de Conteúdo

O ListExpandable suporta diferentes status para comunicar diferentes estados ou significados visuais:

Guia de uso dos status

  • default: Status padrão para conteúdo geral
  • inactive: Para itens inativos ou desabilitados visualmente
  • positive: Para valores positivos (créditos, ganhos)
  • warning: Para itens que precisam de atenção
  • highlight: Para informações importantes
  • highlight-lead: Para destaques principais com mais ênfase
  • strikethrough: Para valores com desconto (mostra valor riscado)
<ListExpandable
title="Status Positive"
description="+ R$ 500,00"
status="positive"
>
<div>Conteúdo expandido</div>
</ListExpandable>

Estados de Expansão

O ListExpandable pode ser usado em modo controlado ou não controlado:

Uncontrolled (padrão)

// O componente gerencia seu próprio estado
<ListExpandable
title="Card Uncontrolled"
description="Gerencia o estado internamente"
defaultExpanded={false}
onToggle={(expanded) => console.log('Estado:', expanded)}
>
<div>Conteúdo expandido</div>
</ListExpandable>

Controlled

// Você controla o estado externamente
const [expanded, setExpanded] = useState(false);

<ListExpandable
title="Card Controlled"
description="Controlado por estado externo"
expanded={expanded}
onToggle={(newExpanded) => setExpanded(newExpanded)}
>
<div>Conteúdo expandido</div>
</ListExpandable>;

Indicadores

Adicione badges ou tags como indicadores visuais antes da ação de expansão:

// Com Badge
<ListExpandable
title="Notificações"
description="Você tem novas mensagens"
icon={<Bell size={24} />}
indicator={<Badge count={5} color="brand" />}
>
<div>Lista de notificações...</div>
</ListExpandable>

// Com Tag
<ListExpandable
title="Pedido #12345"
description="Compra realizada hoje"
icon={<ShoppingBag size={24} />}
indicator={<Tag type="positive" size="small">Aprovado</Tag>}
>
<div>Detalhes do pedido...</div>
</ListExpandable>

Estado de Loading

Durante carregamento de dados, use o estado loading para mostrar skeleton:

<ListExpandable title="Carregando..." description="Aguarde" loading={true}>
<div>Este conteúdo não será exibido durante o loading</div>
</ListExpandable>

Estado Disabled

Desabilite a interação com o componente usando a prop disabled:

<ListExpandable
title="Item Desabilitado"
description="Este item não pode ser expandido"
disabled
>
<div>Conteúdo não acessível</div>
</ListExpandable>

Com Divisor (showDivider)

Adicione um divisor visual entre o header e o conteúdo expandido:

<ListExpandable
title="Com Divisor"
description="Divisor entre header e conteúdo"
showDivider
defaultExpanded
>
<div>Conteúdo com divisor acima</div>
</ListExpandable>

Conteúdo Complexo

O conteúdo expandido pode ser tão complexo quanto necessário:

Variações de Layout

Sem Ícone

Com Caption

Invertido

Use inverted para destacar valores numéricos ou dados principais:

// Útil para destacar valores monetários
<ListExpandable
title="R$ 1.234,56"
description="Transferência PIX"
icon={<PixIcon size={24} />}
inverted
>
<div>Detalhes da transferência...</div>
</ListExpandable>

Exemplo Controlado

Veja como controlar o estado de expansão externamente:

API

Props

PropTipoPadrãoDescrição
titlestring-Título principal do item (obrigatório)
descriptionstring-Descrição ou texto secundário
strikethroughDescriptionstring-Texto riscado (usado com status="strikethrough")
captionstring-Legenda ou texto terciário
invertedbooleanfalseInverte posição título/descrição
type'card' | 'text''card'Tipo de estilo visual do container
status'default' | 'inactive' | 'positive' | 'warning' | 'highlight' | 'highlight-lead' | 'strikethrough''default'Status de estilo do conteúdo
loadingbooleanfalseMostra skeleton de carregamento
disabledbooleanfalseDesabilita a interação com o componente
showDividerbooleanfalseMostra divisor entre header e conteúdo
highlight{ caption: string | ReactNode; backgroundColor?: string; captionColor?: string }-Exibe área de destaque com texto ou conteúdo na base do card
iconReactNode-Ícone à esquerda do conteúdo
indicatorReactNode-Badge/Tag antes da ação de expansão
expandedboolean-Controla estado expandido (controlled)
defaultExpandedbooleanfalseEstado inicial (uncontrolled)
onToggle(expanded: boolean) => void-Callback ao expandir/colapsar
childrenReactNode-Conteúdo exibido quando expandido
classNamestring-Classes CSS adicionais

Eventos

  • onToggle: Disparado quando o item é expandido ou colapsado, recebe o novo estado como parâmetro

Acessibilidade

  • ✅ Elemento <button> semântico para ação de expansão
  • ✅ Suporte completo a navegação por teclado
  • ✅ Estados de foco visíveis
  • ✅ Atributo aria-expanded para indicar estado
  • ✅ Atributo aria-label descritivo para leitores de tela
  • ✅ Indicadores visuais claros (ícones de chevron)
  • ✅ Transições suaves entre estados
  • ✅ Skeleton acessível durante loading
  • ✅ Estado disabled corretamente aplicado ao botão
TeclaFunção
TabMove foco para o item
Space / EnterExpande ou colapsa o conteúdo
Shift + TabMove foco para elemento anterior

CSS Classes

ClasseDescrição
.ods-list-expandableClasse base do componente
.ods-list-expandable--cardAplicada quando type="card"
.ods-list-expandable--textAplicada quando type="text"
.ods-list-expandable--expandedAplicada quando expandido
.ods-list-expandable--disabledAplicada quando desabilitado
.ods-list-expandable--loadingAplicada durante loading
.ods-list-expandable__mainContainer principal (botão)
.ods-list-expandable__iconContainer do ícone
.ods-list-expandable__icon--inactiveÍcone com status inactive
.ods-list-expandable__skeletonContainer do skeleton
.ods-list-expandable__trailingContainer do indicator e action
.ods-list-expandable__indicatorContainer do indicator
.ods-list-expandable__actionContainer da ação (chevron)
.ods-list-expandable__dividerDivisor entre header e conteúdo
.ods-list-expandable__contentContainer do conteúdo expandido

Melhores práticas

✅ Faça

  • Use títulos descritivos que indiquem o conteúdo
  • Adicione indicadores (badges/tags) para informações importantes
  • Use status apropriado para comunicar significado (positive, warning, etc.)
  • Use type="card" dentro de List e type="text" para uso isolado
  • Combine com List para múltiplos items
  • Use estado loading durante carregamento de dados
  • Implemente onToggle para tracking de interações
  • Use modo inverted para destacar valores monetários
  • Forneça ícones significativos que identifiquem o tipo de conteúdo
  • Use showDivider quando precisar separar visualmente header do conteúdo

❌ Não faça

  • Não oculte informações críticas no conteúdo expandido
  • Não use conteúdo expandido excessivamente longo (considere split)
  • Não omita o título (é obrigatório)
  • Não ignore o estado loading durante carregamentos
  • Não abuse de items expandidos na mesma tela (pode confundir)
  • Não use múltiplos níveis de expansão (evite nesting)
  • Não use disabled e loading simultaneamente

Casos de uso comuns

1. Lista de Transações

<List>
<ListExpandable
title="Transferência PIX"
description="R$ 150,00"
icon={<PixIcon size={24} />}
indicator={
<Tag type="positive" size="small">
Concluído
</Tag>
}
>
<TransactionDetails id="123" />
</ListExpandable>
</List>

2. Detalhes de Pedido

<ListExpandable
title="Pedido #12345"
description="25/11/2025 - R$ 459,90"
icon={<ShoppingBag size={24} />}
indicator={<Badge count={3} color="brand" />}
status="positive"
>
<OrderDetails items={items} />
</ListExpandable>

3. Notificações

<ListExpandable
title="Você tem novas notificações"
description="5 não lidas"
icon={<Bell size={24} />}
indicator={<Badge count={5} color="highlight" />}
>
<NotificationList />
</ListExpandable>

4. FAQ / Accordion

<List>
<ListExpandable
title="Como faço para alterar minha senha?"
description="Clique para ver as instruções"
>
<Typography variant="paragraph">1. Acesse configurações...</Typography>
</ListExpandable>
</List>

5. Item com Tipo Text e Divisor

<ListExpandable
title="Informações Adicionais"
description="Clique para expandir"
type="text"
showDivider
defaultExpanded
>
<div>Conteúdo separado por divisor</div>
</ListExpandable>