# Woovi UI - Component Library

> Biblioteca de componentes React da Woovi para construir interfaces de pagamento e dashboards financeiros.

Documentação: https://storybook.woovi.design
Repositório: https://github.com/woovi/woovi-ui
Pacote NPM: @woovi/ui

---

## Instalação

```bash
npm install @woovi/ui
# ou
yarn add @woovi/ui
# ou
pnpm add @woovi/ui
```

## Dependências

- React 18+
- Material-UI (MUI) v7+
- TypeScript

---

## Avatar

Componentes para exibir fotos de perfil e grupos de usuários.

```tsx
import { Avatar } from '@woovi/ui';

// Avatar simples
<Avatar src="https://example.com/photo.jpg" alt="User" />

```

- Avatar: https://storybook.woovi.design/?path=/docs/components-avatar-avatar--docs

## Banner

Componentes para exibir mensagens de alerta, erro e informações.

```tsx
import { Banner, BannerError, BannerInfos } from '@woovi/ui';

// Banner genérico (conteúdo via children)
<Banner variant="solid" color="info">Informação importante</Banner>

// Banner de erro (recebe array de mensagens)
<BannerError
  errors={["Ocorreu um erro ao processar"]}
  callbackOnClose={() => {}}
/>

// Banner informativo com detalhes (tabela de erros/informações)
<BannerInfos
  errors={data}
  columns={[{ field: 'name', headerName: 'Nome' }]}
  titleHeader="Atenção"
  onClose={() => {}}
  refColumn={{ field: 'id', headerName: 'ID' }}
  isOpen={true}
/>
```

- Banner: https://storybook.woovi.design/?path=/docs/components-banner-banner--docs
- BannerError: https://storybook.woovi.design/?path=/docs/components-banner-bannererror--docs
- BannerInfos: https://storybook.woovi.design/?path=/docs/components-banner-bannerinfos--docs

## Buttons

Botões para ações, copiar, pagamentos e menus.

```tsx
import {
  ActionButton,
  ButtonMenu,
  ButtonMenuItem,
  CopyButton,
  DangerButton,
  PayWithPixButton,
  ResponsiveSplitButton,
  SplitButton
} from '@woovi/ui';

// Botão de ação primário
<ActionButton label="Salvar" onClick={handleSave} />
<ActionButton label="Salvar" loading={isLoading} />
<ActionButton label="Criar" icon="add" />

// Botão de copiar (children é o label do botão)
<CopyButton value="texto-para-copiar">Copiar Chave</CopyButton>

// Botão de perigo/exclusão
<DangerButton label="Excluir" onClick={handleDelete} />

// Menu de botões
<ButtonMenu label="Opções">
  <ButtonMenuItem onClick={handleEdit}>Editar</ButtonMenuItem>
  <ButtonMenuItem onClick={handleDelete}>Excluir</ButtonMenuItem>
</ButtonMenu>

// Botão de pagamento Pix
<PayWithPixButton onClick={handlePixPayment} />

// Split button com opções
<SplitButton
  options={[
    { label: 'Ação 1', onClick: () => {} },
    { label: 'Ação 2', onClick: () => {} },
  ]}
/>
```

- ActionButton: https://storybook.woovi.design/?path=/docs/components-buttons-actionbutton--docs
- ButtonMenu: https://storybook.woovi.design/?path=/docs/components-buttons-buttonmenu--docs
- CopyButton: https://storybook.woovi.design/?path=/docs/components-buttons-copybutton--docs
- DangerButton: https://storybook.woovi.design/?path=/docs/components-buttons-dangerbutton--docs
- PayWithPixButton: https://storybook.woovi.design/?path=/docs/components-buttons-paywithpixbutton--docs
- ResponsiveSplitButton: https://storybook.woovi.design/?path=/docs/components-buttons-responsivesplitbutton--docs
- SplitButton: https://storybook.woovi.design/?path=/docs/components-buttons-splitbutton--docs

### ClickPix Buttons

Botões específicos para pagamentos via Pix com um clique.

```tsx
import {
  ClickPixButton,
  DonateClickPixButton,
  DonateWithClickButton
} from '@woovi/ui';

// Botão ClickPix padrão
<ClickPixButton onClick={handleClickPix} />

// Botão de doação ClickPix
<DonateClickPixButton amount={1000} correlationID="donation-123" />

// Botão de doação com click
<DonateWithClickButton />
```

- ClickPixButton: https://storybook.woovi.design/?path=/docs/components-buttons-clickpix-clickpixbutton--docs
- DonateClickPixButton: https://storybook.woovi.design/?path=/docs/components-buttons-clickpix-donateclickpixbutton--docs
- DonateWithClickButton: https://storybook.woovi.design/?path=/docs/components-buttons-clickpix-donatewithclickbutton--docs

## Card

Containers para exibir conteúdo em formato de cartão.

```tsx
import {
  Card,
  CardActions,
  CardContent,
  CardCopy,
  CardForm,
  CardSelectable,
  CardStep,
  CardWithActions,
  CardWithIcon,
  CardWithLink,
  CardWithLinkSkeleton
} from '@woovi/ui';

// Card básico
<Card>
  <CardContent>
    <h2>Título do Card</h2>
    <p>Conteúdo do card</p>
  </CardContent>
  <CardActions>
    <ActionButton label="Ação" />
  </CardActions>
</Card>

// Card com ícone
<CardWithIcon
  icon="payment"
  title="Pagamentos"
  description="Gerencie seus pagamentos"
/>

// Card com link
<CardWithLink
  title="Ver detalhes"
  href="/details"
/>

// Card selecionável
<CardSelectable
  isSelected={isSelected}
  onClick={() => setSelected(!isSelected)}
>
  Conteúdo selecionável
</CardSelectable>

// Card de cópia (para chaves Pix, etc)
<CardCopy content="chave-pix@email.com" />
```

- Card: https://storybook.woovi.design/?path=/docs/components-card-card--docs
- CardActions: https://storybook.woovi.design/?path=/docs/components-card-cardactions--docs
- CardContent: https://storybook.woovi.design/?path=/docs/components-card-cardcontent--docs
- CardCopy: https://storybook.woovi.design/?path=/docs/components-card-cardcopy--docs
- CardForm: https://storybook.woovi.design/?path=/docs/components-card-cardform--docs
- CardSelectable: https://storybook.woovi.design/?path=/docs/components-card-cardselectable--docs
- CardStep: https://storybook.woovi.design/?path=/docs/components-card-cardstep--docs
- CardWithActions: https://storybook.woovi.design/?path=/docs/components-card-cardwithactions--docs
- CardWithIcon: https://storybook.woovi.design/?path=/docs/components-card-cardwithicon--docs
- CardWithLink: https://storybook.woovi.design/?path=/docs/components-card-cardwithlink--docs
- CardWithLinkSkeleton: https://storybook.woovi.design/?path=/docs/components-card-cardwithlinkskeleton--docs

## CardAnalytics

Componentes para exibir métricas e dados analíticos.

```tsx
import { CardAnalytics, CardAnalyticsSmall } from '@woovi/ui';

// Card de métricas
<CardAnalytics
  title="Total de Vendas"
  value="R$ 15.000,00"
  total="150 transações"
  color="success"
  loading={false}
  onClick={() => navigate('/sales')}
/>

// Versão compacta
<CardAnalyticsSmall
  label="Conversão"
  value="3.2%"
/>
```

- CardAnalytics: https://storybook.woovi.design/?path=/docs/components-cardanalytics-cardanalytics--docs
- CardAnalyticsSkeleton: https://storybook.woovi.design/?path=/docs/components-cardanalytics-cardanalyticsskeleton--docs
- CardAnalyticsSmall: https://storybook.woovi.design/?path=/docs/components-cardanalytics-cardanalyticssmall--docs

## CardGrid

Sistema de grid para organizar cards em layout responsivo.

```tsx
import { CardGrid, CardField, Grid } from '@woovi/ui';

// Grid de cards
<CardGrid>
  <CardField label="Nome" value="João Silva" />
  <CardField label="Email" value="joao@email.com" />
</CardGrid>

// Grid genérico
<Grid columns={3} gap={2}>
  <Card>Item 1</Card>
  <Card>Item 2</Card>
  <Card>Item 3</Card>
</Grid>
```

- CardField: https://storybook.woovi.design/?path=/docs/components-cardgrid-cardfield--docs
- CardGrid: https://storybook.woovi.design/?path=/docs/components-cardgrid-cardgrid--docs
- Grid: https://storybook.woovi.design/?path=/docs/components-cardgrid-grid--docs

## CardWithImage

Card com suporte a imagens.

```tsx
import { CardWithImage } from '@woovi/ui';

<CardWithImage
  image="/product.jpg"
  title="Produto"
  description="Descrição do produto"
/>
```

- CardWithImage: https://storybook.woovi.design/?path=/docs/components-cardwithimage-cardwithimage--docs

## ClickPix

Componentes da marca ClickPix para pagamentos instantâneos.

```tsx
import { ClickPixButton, ClickPixLogo } from '@woovi/ui';

// Logo ClickPix
<ClickPixLogo width={120} />

// Botão ClickPix
<ClickPixButton variant="primary" onClick={handlePay} />
```

- ClickPixButton: https://storybook.woovi.design/?path=/docs/components-clickpix-clickpixbutton--docs
- ClickPixLogo: https://storybook.woovi.design/?path=/docs/components-clickpix-clickpixlogo--docs

## Code

Componente para exibir blocos de código.

```tsx
import { Code } from '@woovi/ui';

<Code language="javascript">
  {`const pix = await woovi.createCharge({ value: 1000 });`}
</Code>
```

- Code: https://storybook.woovi.design/?path=/docs/components-code-code--docs

## Collapsible

Componentes expansíveis para organizar conteúdo em seções.

```tsx
import {
  Collapse,
  Collapsible,
  CollapsibleStep,
  CollapsibleTree,
  LeafCollapsible
} from '@woovi/ui';

// Collapsible simples
<Collapsible title="Ver mais detalhes">
  <p>Conteúdo expandido</p>
</Collapsible>

// Collapsible em etapas
<CollapsibleStep step={1} title="Primeira etapa">
  <p>Conteúdo da etapa</p>
</CollapsibleStep>

// Árvore collapsible
<CollapsibleTree>
  <LeafCollapsible title="Item pai">
    <LeafCollapsible title="Item filho" />
  </LeafCollapsible>
</CollapsibleTree>
```

- Collapse: https://storybook.woovi.design/?path=/docs/components-collapsible-collapse--docs
- Collapsible: https://storybook.woovi.design/?path=/docs/components-collapsible-collapsible--docs
- CollapsibleStep: https://storybook.woovi.design/?path=/docs/components-collapsible-collapsiblestep--docs
- CollapsibleStepHeader: https://storybook.woovi.design/?path=/docs/components-collapsible-collapsiblestepheader--docs
- CollapsibleTree: https://storybook.woovi.design/?path=/docs/components-collapsible-collapsibletree--docs
- LeafCollapsible: https://storybook.woovi.design/?path=/docs/components-collapsible-leafcollapsible--docs

## Content

Componentes para estruturar conteúdo e texto.

```tsx
import { Content, ActionMargin } from '@woovi/ui';

// Container de conteúdo
<Content>
  <p>Seu conteúdo aqui</p>
</Content>

// Margem para ações
<ActionMargin>
  <ActionButton label="Salvar" />
</ActionMargin>
```

- ActionMargin: https://storybook.woovi.design/?path=/docs/components-content-actionmargin--docs
- Content: https://storybook.woovi.design/?path=/docs/components-content-content--docs

## Countdown

Componentes de contagem regressiva para expirações de pagamento.

```tsx
import { Countdown } from '@woovi/ui';

// Contagem regressiva para expiração de cobrança Pix
<Countdown
  expiresAt={new Date('2024-12-31T23:59:59')}
  onExpire={() => console.log('Expirado!')}
/>
```

- Countdown: https://storybook.woovi.design/?path=/docs/components-countdown-countdown--docs
- ShowCounter: https://storybook.woovi.design/?path=/docs/components-countdown-showcounter--docs

## DataGrid

Tabelas de dados avançadas com suporte a paginação, ordenação e filtros.

```tsx
import { DataGrid, DataGridLoading, DataGridDetailContainer } from '@woovi/ui';

// DataGrid básico
<DataGrid
  columns={[
    { field: 'id', headerName: 'ID', width: 90 },
    { field: 'name', headerName: 'Nome', width: 150 },
    { field: 'status', headerName: 'Status', width: 110 },
  ]}
  rows={data}
  loading={isLoading}
  onRowClick={(row) => console.log(row)}
/>

// DataGrid com exportação CSV habilitada
<DataGrid
  columns={columns}
  rows={data}
  exportTable
/>

// DataGrid com zebra rows
<DataGrid
  columns={columns}
  rows={data}
  zebraRow
/>

// DataGrid com rowHref (função que recebe row e retorna href)
<DataGrid
  columns={columns}
  rows={data}
  rowAnchor
  rowHref={(row) => `/details/${row.id}`}
/>

// Estado de loading
<DataGridLoading columns={3} rows={5} />
```

- DataGrid: https://storybook.woovi.design/?path=/docs/components-datagrid-datagrid--docs
- DataGridDetailContainer: https://storybook.woovi.design/?path=/docs/components-datagrid-datagriddetailcontainer--docs
- DataGridLoading: https://storybook.woovi.design/?path=/docs/components-datagrid-datagridloading--docs

## Dialog

Sistema de modais e diálogos.

```tsx
import { DialogProvider, useDialog } from '@woovi/ui';

// Provider no root da aplicação
<DialogProvider>
  <App />
</DialogProvider>

// Hook para abrir diálogos
const { openDialog, closeDialog } = useDialog();

openDialog({
  title: 'Confirmar ação',
  content: 'Deseja continuar?',
  actions: [
    { label: 'Cancelar', onClick: closeDialog },
    { label: 'Confirmar', onClick: handleConfirm },
  ],
});
```

- DialogProvider: https://storybook.woovi.design/?path=/docs/components-dialog-dialogprovider--docs

## Drawer

Painéis laterais deslizantes.

```tsx
import { DrawerCard, DrawerResponsiveWrapper } from '@woovi/ui';

// Drawer com card
<DrawerCard open={isOpen} onClose={handleClose}>
  <CardContent>Conteúdo do drawer</CardContent>
</DrawerCard>

// Drawer responsivo (lateral em desktop, bottom sheet em mobile)
<DrawerResponsiveWrapper open={isOpen} onClose={handleClose}>
  <p>Conteúdo adaptativo</p>
</DrawerResponsiveWrapper>
```

- DrawerCard: https://storybook.woovi.design/?path=/docs/components-drawer-drawercard--docs
- DrawerResponsiveWrapper: https://storybook.woovi.design/?path=/docs/components-drawer-drawerresponsivewrapper--docs

## EmptyState

Componente para exibir estados vazios — listas sem resultados, telas sem dados ou seções aguardando uma ação do usuário. Suporta até dois botões de ação: `primaryButton` (contained) e `secondaryButton` (outlined), exibidos lado a lado.

```tsx
import { EmptyState } from '@woovi/ui';

// Estado vazio com defaults (ícone, título e descrição padrão)
<EmptyState />

// Com botão primário (contained)
<EmptyState
  title="Nenhum resultado encontrado."
  description="Convide um usuário ou limpe o filtro de pesquisa."
  primaryButton={{
    label: "Convidar usuário",
    onClick: () => handleInvite(),
  }}
/>

// Com botão secundário (outlined)
<EmptyState
  title="Nenhum resultado encontrado."
  description="Volte para a tela anterior ou ajuste os filtros."
  secondaryButton={{
    label: "Voltar",
    onClick: () => handleBack(),
  }}
/>

// Com ambos os botões (secundário à esquerda, primário à direita)
<EmptyState
  title="Nenhuma cobrança ainda"
  description="Crie sua primeira cobrança Pix ou importe um arquivo CSV."
  secondaryButton={{
    label: "Importar CSV",
    onClick: () => handleImport(),
  }}
  primaryButton={{
    label: "Criar cobrança",
    onClick: () => handleCreate(),
  }}
/>

// Sem botões (cada botão só é renderizado se label E onClick forem fornecidos)
<EmptyState
  title="Lista vazia"
  description="Você ainda não possui itens cadastrados."
/>

// Com ícone customizado
<EmptyState
  icon={<MyCustomIcon />}
  title="Busca personalizada"
  description="Você pode passar qualquer ReactNode como ícone."
  primaryButton={{ label: "Tentar novamente", onClick: () => retry() }}
/>
```

- EmptyState: https://storybook.woovi.design/?path=/docs/components-emptystate-emptystate--docs

## Error

Componentes para tratamento e exibição de erros.

```tsx
import { ErrorView } from '@woovi/ui';

// Visualização de erro
<ErrorView
  title="Algo deu errado"
  message="Não foi possível carregar os dados"
  onRetry={handleRetry}
/>
```

- ErrorView: https://storybook.woovi.design/?path=/docs/components-error-errorview--docs

## Filter

Sistema de filtros para busca e filtragem de dados.

```tsx
import { Filter, FilterRelayFormik } from '@woovi/ui';

// Filtro básico
<Filter
  filters={[
    { field: 'status', label: 'Status', options: ['Ativo', 'Inativo'] },
    { field: 'date', label: 'Data', type: 'date' },
  ]}
  onFilter={(values) => handleFilter(values)}
/>
```

- Filter: https://storybook.woovi.design/?path=/docs/components-filter-filter--docs

## Form

Componentes de formulário.

```tsx
import { FieldRow } from '@woovi/ui';

// Linha de campo de formulário
<FieldRow label="Email" required>
  <input type="email" />
</FieldRow>
```

- FieldRow: https://storybook.woovi.design/?path=/docs/components-form-fieldrow--docs

## Heading

Cabeçalhos e títulos de seção.

```tsx
import { SectionHeading } from '@woovi/ui';

<SectionHeading
  title="Transações"
  subtitle="Últimas 30 dias"
  action={<ActionButton label="Ver todas" />}
/>
```

- SectionHeading: https://storybook.woovi.design/?path=/docs/components-heading-sectionheading--docs

## Helpers

Utilitários de layout e espaçamento.

```tsx
import { Divider, HorizontalStack } from '@woovi/ui';

// Divisor
<Divider />

// Stack horizontal
<HorizontalStack spacing={2}>
  <ActionButton label="Botão 1" />
  <ActionButton label="Botão 2" />
</HorizontalStack>
```

- Divider: https://storybook.woovi.design/?path=/docs/components-helpers-divider--docs
- HorizontalStack: https://storybook.woovi.design/?path=/docs/components-helpers-horizontalstack--docs

## Import

Componentes para importação de arquivos (CSV, XLSX).

```tsx
import { DropzoneFile } from '@woovi/ui';

// Dropzone para upload
<DropzoneFile
  onDrop={(files) => handleImport(files)}
  accept={{ 'text/csv': ['.csv'], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'] }}
>
  Arraste arquivos CSV ou XLSX aqui
</Dropzone>
```

- DropzoneFile: https://storybook.woovi.design/?path=/docs/components-import-dropzonefile--docs

## Layout

Componentes para estrutura de página.

```tsx
import { LayoutRoot, LayoutWrapper } from '@woovi/ui';

<LayoutRoot>
  <LayoutWrapper>
    <Content />
  </LayoutWrapper>
</LayoutRoot>
```

- LayoutRoot: https://storybook.woovi.design/?path=/docs/components-layoutroot--docs
- LayoutWrapper: https://storybook.woovi.design/?path=/docs/components-layoutwrapper-layoutwrapper--docs

## Link

Componentes de navegação e links.

```tsx
import { Link, WooviLink } from '@woovi/ui';

// Link interno
<Link href="/dashboard">Ir para Dashboard</Link>

// Link externo
<Link href="https://woovi.com" external>Woovi</Link>

// Link estilizado Woovi
<WooviLink href="/pricing">Ver preços</WooviLink>
```

- Link: https://storybook.woovi.design/?path=/docs/components-link--docs
- WooviLink: https://storybook.woovi.design/?path=/docs/components-link-woovilink--docs

## Logo

Logotipos da Woovi e OpenPix.

```tsx
import { Logo, WooviLogo } from '@woovi/ui';

// Logo genérico
<Logo src="/logo.png" alt="Empresa" />

// Logo Woovi
<WooviLogo width={150} />
```

- Logo: https://storybook.woovi.design/?path=/docs/components-logo--docs
- WooviLogo: https://storybook.woovi.design/?path=/docs/components-logo-woovilogo--docs

## MUI

Componentes baseados no Material-UI customizados.

```tsx
import { BoxFlex, Typography } from '@woovi/ui';

// Box flexbox
<BoxFlex gap={2} alignItems="center">
  <Typography variant="h6">Título</Typography>
  <Typography variant="body1">Texto</Typography>
</BoxFlex>
```

- BoxFlex: https://storybook.woovi.design/?path=/docs/components-mui-boxflex--docs
- Typography: https://storybook.woovi.design/?path=/docs/components-mui-typography--docs

## MultiFactor

Componentes de autenticação multi-fator para verificação segura de usuários.

```tsx
import {
  MultiFactorConfirmModal,
  MultiFactorPixPaymentMatch,
  MultiFactorPixPaymentMismatch,
  MultiFactorPixPaymentView
} from '@woovi/ui';

// Modal de confirmação MFA (suporta TOTP, WhatsApp/SMS e email)
<MultiFactorConfirmModal
  title="Confirm your identity"
  isOpen={isOpen}
  onConfirm={handleConfirm}
  handleOpenChange={handleClose}
  email="user@example.com"
/>

// Verificação PIX com sucesso (CPF corresponde)
<MultiFactorPixPaymentMatch amount={0.01} />

// Verificação PIX com falha (CPF não corresponde)
<MultiFactorPixPaymentMismatch amount={0.01} />

// View do QR Code PIX para verificação
<MultiFactorPixPaymentView
  pixAuthentication={{ brCode: '...', taxID: '...' }}
  onGetResult={handleGetResult}
/>
```

- MultiFactorConfirmModal: https://storybook.woovi.design/?path=/docs/components-multifactor-multifactorconfirmmodal--docs
- MultiFactorPixPaymentMatch: https://storybook.woovi.design/?path=/docs/components-multifactor-multifactorpixpaymentmatch--docs
- MultiFactorPixPaymentMismatch: https://storybook.woovi.design/?path=/docs/components-multifactor-multifactorpixpaymentmismatch--docs
- MultiFactorPixPaymentView: https://storybook.woovi.design/?path=/docs/components-multifactor-multifactorpixpaymentview--docs

## OpenPix

Componentes específicos do ecossistema OpenPix.

```tsx
import { ChargeTagStatus, PixTransactionTypeTag, QRCodeWrapper } from '@woovi/ui';

// Tag de status de cobrança
<ChargeTagStatus status="COMPLETED" />
<ChargeTagStatus status="PENDING" />
<ChargeTagStatus status="EXPIRED" />

// Tag de tipo de transação Pix
<PixTransactionTypeTag type="PAYMENT" />
<PixTransactionTypeTag type="WITHDRAWAL" />

// Wrapper para QR Code Pix
<QRCodeWrapper
  value="00020126580014br.gov.bcb.pix..."
  size={256}
/>
```

- ChargeTagStatus: https://storybook.woovi.design/?path=/docs/components-openpix-chargetagstatus--docs
- PixTransactionTypeTag: https://storybook.woovi.design/?path=/docs/components-openpix-pixtransactiontypetag--docs
- QrCodeWrapper: https://storybook.woovi.design/?path=/docs/components-openpix-qrcodewrapper--docs

## PaymentLinkRow

Componente para exibir links de pagamento em listas.

```tsx
import { PaymentLinkRow } from '@woovi/ui';

<PaymentLinkRow
  title="Pagamento #123"
  value={5000}
  status="pending"
  href="/payments/123"
/>
```

- PaymentLinkRow: https://storybook.woovi.design/?path=/docs/components-paymentlinkrow-paymentlinkrow--docs

## PinInput

Campos de entrada para PIN e códigos de verificação.

```tsx
import { PinInput, PinInputFormik } from '@woovi/ui';

// Pin input standalone
<PinInput
  length={6}
  onChange={(value) => setPin(value)}
/>

// Pin input com Formik
<PinInputFormik name="verificationCode" length={4} />
```

- PinInput: https://storybook.woovi.design/?path=/docs/components-pininput-pininput--docs
- PinInputFormik: https://storybook.woovi.design/?path=/docs/components-pininput-pininputformik--docs

## RadioCard

Card selecionável estilo radio button.

```tsx
import { RadioCard } from '@woovi/ui';

<RadioCard
  selected={selectedOption === 'pix'}
  onClick={() => setSelectedOption('pix')}
  title="Pix"
  description="Pagamento instantâneo"
  icon="pix"
/>
```

- RadioCard: https://storybook.woovi.design/?path=/docs/components-radiocard-radiocard--docs

## RewardTicket

Componente para exibir tickets de recompensa/cashback.

```tsx
import { RewardTicket } from '@woovi/ui';

<RewardTicket
  value={500}
  description="Cashback de 5%"
/>
```

- RewardTicket: https://storybook.woovi.design/?path=/docs/components-rewardticket-rewardticket--docs

## Ribbon

Faixa decorativa para destacar elementos.

```tsx
import { Ribbon } from '@woovi/ui';

<Card>
  <Ribbon label="Novo" color="primary" />
  <CardContent>Conteúdo</CardContent>
</Card>
```

- Ribbon: https://storybook.woovi.design/?path=/docs/components-ribbon-ribbon--docs

## Root

Componentes de estrutura raiz da aplicação.

```tsx
import { ContentBoundary } from '@woovi/ui';

<ContentBoundary>
  <YourAppContent />
</ContentBoundary>
```

- ContentBoundary: https://storybook.woovi.design/?path=/docs/components-root-contentboundary--docs

## Routed

Componentes com integração de rotas.

```tsx
import { RoutedTabs } from '@woovi/ui';

// Tabs com rotas
<RoutedTabs
  tabs={[
    { label: 'Visão Geral', path: '/overview' },
    { label: 'Transações', path: '/transactions' },
    { label: 'Configurações', path: '/settings' },
  ]}
/>
```

- RoutedTabs: https://storybook.woovi.design/?path=/docs/components-routed-routedtabs--docs

## ScreenHeader

Cabeçalhos de tela para dashboards.

```tsx
import { ScreenHeaderUI, ScreenHeaderCard } from '@woovi/ui';

// Header de tela
<ScreenHeaderUI
  title="Dashboard"
  subtitle="Visão geral das suas transações"
  actions={<ActionButton label="Exportar" />}
/>

// Header em card
<ScreenHeaderCard title="Configurações" />
```

- ScreenHeaderUI: https://storybook.woovi.design/?path=/docs/components-screenheader-screenheaderui--docs
- ScreenHeaderCard: https://storybook.woovi.design/?path=/docs/components-screenheadercard-screenheadercard--docs

## Search

Campos de busca.

```tsx
import { GlobalSearchField, SearchField } from '@woovi/ui';

// Campo de busca global (controlled component)
<GlobalSearchField
  value={search}
  onChange={(e) => setSearch(e.target.value)}
  variant="primary"
  onDebounceApplied={(value, event) => handleSearch(value)}
  fullWidth={false}
/>

// Campo de busca simples
<SearchField
  value={search}
  onChange={(e) => setSearch(e.target.value)}
/>
```

- GlobalSearchField: https://storybook.woovi.design/?path=/docs/components-search-globalsearchfield--docs
- SearchField: https://storybook.woovi.design/?path=/docs/components-searchfield--docs

## Select

Componentes de seleção.

```tsx
import { Select } from '@woovi/ui';

// Select básico
<Select
  label="Status"
  value={status}
  onChange={setStatus}
  options={[
    { value: 'active', label: 'Ativo' },
    { value: 'inactive', label: 'Inativo' },
  ]}
/>
```

- Select: https://storybook.woovi.design/?path=/docs/components-select-select--docs

## Sidebar

Sistema de navegação lateral.

```tsx
import { Sidebar, SidebarGroup, SidebarItem, SidebarMenuList } from '@woovi/ui';

<Sidebar>
  <SidebarGroup title="Principal">
    <SidebarItem icon="dashboard" label="Dashboard" href="/" />
    <SidebarItem icon="payment" label="Pagamentos" href="/payments" />
  </SidebarGroup>
  <SidebarGroup title="Configurações">
    <SidebarItem icon="settings" label="Conta" href="/settings" />
  </SidebarGroup>
</Sidebar>
```

- Sidebar: https://storybook.woovi.design/?path=/docs/components-sidebar-sidebar--docs
- Group: https://storybook.woovi.design/?path=/docs/components-sidebar-group--docs
- Item: https://storybook.woovi.design/?path=/docs/components-sidebar-item--docs
- MenuList: https://storybook.woovi.design/?path=/docs/components-sidebar-menulist--docs

## Snackbar

Notificações toast.

```tsx
import { useSnackbar } from '@woovi/ui';

const { showSnackbar } = useSnackbar();

// Mostrar notificação
showSnackbar('Operação realizada com sucesso!', { variant: 'success' });
showSnackbar('Erro ao processar', { variant: 'error' });
showSnackbar('Atenção!', { variant: 'warning' });
```

- Snackbar: https://storybook.woovi.design/?path=/docs/components-snackbar-snackbar--docs
- CloseSnack: https://storybook.woovi.design/?path=/docs/components-snackbar-closesnack--docs

## Statement

Componentes para extrato e histórico de transações.

```tsx
import { LedgerStatementText, TransactionTypeText } from '@woovi/ui';

// Texto de extrato
<LedgerStatementText type="credit" value={1000} />
<LedgerStatementText type="debit" value={-500} />

// Texto de tipo de transação
<TransactionTypeText type="PIX_RECEIVED" />
<TransactionTypeText type="PIX_SENT" />
```

- LedgerStatementText: https://storybook.woovi.design/?path=/docs/components-statement-ledgerstatementtext--docs
- TransactionTypeText: https://storybook.woovi.design/?path=/docs/components-statement-transactiontypetext--docs

## SwipeableDialog

Dialog com suporte a gestos de swipe para mobile.

```tsx
import {
  SwipeableDialog,
  SwipeableDialogContent,
  SwipeableDialogTitle,
  SwipeableDialogActions,
  SwipeableModal
} from '@woovi/ui';

<SwipeableDialog open={isOpen} onClose={handleClose}>
  <SwipeableDialogTitle>Confirmar</SwipeableDialogTitle>
  <SwipeableDialogContent>
    Deseja continuar com esta ação?
  </SwipeableDialogContent>
  <SwipeableDialogActions>
    <ActionButton label="Cancelar" onClick={handleClose} />
    <ActionButton label="Confirmar" onClick={handleConfirm} />
  </SwipeableDialogActions>
</SwipeableDialog>
```

- SwipeableDialog: https://storybook.woovi.design/?path=/docs/components-swipeabledialog-swipeabledialog--docs
- SwipeableModal: https://storybook.woovi.design/?path=/docs/components-swipeablemodal-swipeablemodal--docs

## Table

Componentes de tabela, listas virtualizadas, alternância de visualização e parser EMV.

```tsx
import {
  CardListVirtualized,
  CardListLoading,
  CardColumn,
  TableToggleViewModel,
  TablePixEMV
} from '@woovi/ui';

// Lista virtualizada para grandes conjuntos de dados
<CardListVirtualized
  columns={columns}
  data={rows}
  onScrollToBottom={handleLoadMore}
  cardListDefaultHeight="300px"
/>

// Estado de loading
<CardListLoading columns={columns} size={5} />

// Card individual com colunas (usado internamente pela lista virtualizada)
<CardColumn
  columns={columns}
  row={{ id: 1, name: 'John', email: 'john@example.com' }}
  onCardClick={(card, event) => handleClick(card)}
/>

// Toggle entre visualização tabela e card
<TableToggleViewModel />

// Tabela de dados EMV de QR Code Pix (com linhas expansíveis para tags aninhadas)
<TablePixEMV emv="00020126580014br.gov.bcb.pix0136..." />
```

- CardColumn: https://storybook.woovi.design/?path=/docs/components-table-cardcolumn--docs
- CardListLoading: https://storybook.woovi.design/?path=/docs/components-table-cardlistloading--docs
- CardListVirtualized: https://storybook.woovi.design/?path=/docs/components-table-cardlistvirtualized--docs
- TableToggleViewModel: https://storybook.woovi.design/?path=/docs/components-table-tabletoggleviewmodel--docs
- TablePixEMV: https://storybook.woovi.design/?path=/docs/components-table-tablepixemv--docs

## MuiTable

Tabela MUI com paginação, seleção de linhas e múltiplos tipos de célula. Substitui o pacote `@woovi/table` (descontinuado). Use com `useRelayPagination` de `@woovi/hooks` para consumers Relay.

```tsx
import { Table, TableRelayPagination, CELL_TYPES, useTableProps } from '@woovi/ui';
import type { TableColumn } from '@woovi/ui';
import { useRelayPagination } from '@woovi/hooks';

// Definição de colunas
const columns: TableColumn<User>[] = [
  { property: 'name',      type: CELL_TYPES.STRING,   header: { label: 'Nome' } },
  { property: 'email',     type: CELL_TYPES.STRING,   header: { label: 'E-mail' } },
  { property: 'amount',    type: CELL_TYPES.CURRENCY, header: { label: 'Saldo' } },
  { property: 'createdAt', type: CELL_TYPES.DATETIME, header: { label: 'Data' } },
  // Renderização customizada
  {
    property: 'status',
    header: { label: 'Status' },
    renderRow: (value) => <StatusChip status={value} />,
  },
  // Link para rota interna
  {
    property: 'id',
    type: CELL_TYPES.LINK,
    header: { label: 'ID' },
    getClickPath: (value) => `/transactions/${value}`,
  },
  // Menu de ações
  {
    property: 'id',
    type: CELL_TYPES.ACTIONS,
    header: { label: '' },
    actions: [
      { label: 'Editar',  action: (row) => handleEdit(row) },
      { label: 'Excluir', action: (row) => handleDelete(row) },
    ],
  },
];

// Table simples (dados em memória)
const { isLoading, quantityPerPage, setQuantityPerPage } = useTableProps();
<Table
  columns={columns}
  rows={users}
  isLoading={isLoading}
  emptyMessage="Nenhum resultado encontrado"
  rowsPerPage={quantityPerPage}
  totalItems={users.length}
  firstItemIndex={0}
  lastItemIndex={users.length}
  handleRowsPerPageChange={setQuantityPerPage}
  handlePageChange={() => {}}
  isSelectable={false}
  isRowClickEnabled={() => false}
  fixedHeader={false}
  height="auto"
  onSelectedRowsChange={() => {}}
  onRowCheck={() => {}}
  onSelectAllCheck={() => {}}
  selectedRows={[]}
/>

// TableRelayPagination — consumer Relay com useRelayPagination
const { edges, paginationProps } = useRelayPagination({ connection, relay });
<TableRelayPagination
  columns={columns}
  edges={edges}
  isLoading={isLoading}
  emptyMessage="Nenhum resultado"
  {...paginationProps}
/>
```

Tipos de célula disponíveis em CELL_TYPES: STRING, CURRENCY, DATE, TIME, DATETIME, LINK, ICON, ACTIONS, CHECKBOX, EDITABLE, TAG. Use `renderRow` para renderização JSX customizada em qualquer coluna.

- Table: https://storybook.woovi.design/?path=/docs/components-muitable-table--docs
- TableRelayPagination: https://storybook.woovi.design/?path=/docs/components-muitable-table--relay-pagination

## Tag

Componentes de tag e status.

```tsx
import {
  Tag,
  TagsContainer,
  CashbackTagStatus,
  TransactionTagStatus,
} from '@woovi/ui';

// Tag simples
<Tag label="Pix" color="primary" />
<Tag label="Novo" color="success" />

// Container de tags
<TagsContainer>
  <Tag label="Tag 1" />
  <Tag label="Tag 2" />
</TagsContainer>

// Tags de status específicos
<CashbackTagStatus status="pending" />
<TransactionTagStatus status="completed" />
```

- Tag: https://storybook.woovi.design/?path=/docs/components-tag-tag--docs
- TagsContainer: https://storybook.woovi.design/?path=/docs/components-tag-tagscontainer--docs
- CashbackTagStatus: https://storybook.woovi.design/?path=/docs/components-cashbacktagstatus--docs
- TransactionTagStatus: https://storybook.woovi.design/?path=/docs/components-transactiontagstatus--docs

## Term

Componentes de termos e condições.

```tsx
import { Terms, TermsLink } from '@woovi/ui';

// Checkbox de termos
<Terms
  checked={accepted}
  onChange={setAccepted}
/>

// Link para termos
<TermsLink href="/terms">Termos de Uso</TermsLink>
```

- Terms: https://storybook.woovi.design/?path=/docs/components-term-terms--docs
- TermsLink: https://storybook.woovi.design/?path=/docs/components-term-termslink--docs

## Text

Componentes de texto.

```tsx
import { TextMultiline } from '@woovi/ui';

<TextMultiline text="Texto com\\nmúltiplas\\nlinhas" />
```

- TextMultiline: https://storybook.woovi.design/?path=/docs/components-text-textmultiline--docs

## Theme

Sistema de temas e dark mode.

```tsx
import { ThemeProvider, useThemeMode } from '@woovi/ui';

// Provider de tema
<ThemeProvider>
  <App />
</ThemeProvider>

// Hook para alternar tema
const { mode, toggleMode } = useThemeMode();

<button onClick={toggleMode}>
  Tema atual: {mode}
</button>
```

- ThemeProvider: https://storybook.woovi.design/?path=/docs/components-themeprovider--docs

## Timeline

Linha do tempo para histórico de eventos.

```tsx
import { Timeline, TimelineItem } from '@woovi/ui';

<Timeline>
  <TimelineItem
    title="Pagamento recebido"
    date="2024-01-15 10:30"
    status="success"
  />
  <TimelineItem
    title="Cobrança criada"
    date="2024-01-15 10:00"
    status="info"
  />
</Timeline>
```

- Timeline: https://storybook.woovi.design/?path=/docs/components-timeline-timeline--docs

## User

Componentes para exibir informações de usuários.

```tsx
import { UserChip } from '@woovi/ui';

// Chip de usuário com avatar e nome
<UserChip label="João Silva" name="João Silva" />

// Chip de usuário com CPF (formatado automaticamente)
<UserChip label="12345678909" name="Maria Souza" />

// Chip de usuário com email
<UserChip label="user@woovi.com" name="User Woovi" />
```

- UserChip: https://storybook.woovi.design/?path=/docs/components-user-userchip--docs

## Utility Components

Componentes utilitários diversos.

```tsx
import {
  BackButton,
  CopyInput,
  EncryptedText,
  FloatingMenu,
  Loading,
  Row,
} from '@woovi/ui';

// Botão voltar
<BackButton onClick={() => navigate(-1)} />

// Input com botão de copiar
<CopyInput value="texto-para-copiar" />

// Texto criptografado (ex: CPF mascarado)
<EncryptedText value="123.456.789-00" />

// Menu flutuante
<FloatingMenu
  items={[
    { label: 'Editar', onClick: handleEdit },
    { label: 'Excluir', onClick: handleDelete },
  ]}
/>

// Loading spinner
<Loading />
<Loading size="small" />

// Layout em linha
<Row gap={2}>
  <Item1 />
  <Item2 />
</Row>
```

- BackButton: https://storybook.woovi.design/?path=/docs/components-backbutton--docs
- CopyInput: https://storybook.woovi.design/?path=/docs/components-copyinput--docs
- EncryptedText: https://storybook.woovi.design/?path=/docs/components-encryptedtext--docs
- FloatingMenu: https://storybook.woovi.design/?path=/docs/components-floatingmenu--docs
- Loading: https://storybook.woovi.design/?path=/docs/components-loading--docs
- Row: https://storybook.woovi.design/?path=/docs/components-row--docs
- WindowPopper: https://storybook.woovi.design/?path=/docs/components-windowpopper-windowpopper--docs

---

## Exemplo Completo

```tsx
import {
  ThemeProvider,
  LayoutRoot,
  LayoutWrapper,
  Sidebar,
  SidebarGroup,
  SidebarItem,
  ScreenHeaderUI,
  Card,
  CardContent,
  CardAnalytics,
  DataGrid,
  ActionButton,
  ChargeTagStatus,
  useSnackbar,
} from '@woovi/ui';

function App() {
  const { showSnackbar } = useSnackbar();

  const columns = [
    { field: 'id', headerName: 'ID', width: 100 },
    { field: 'customer', headerName: 'Cliente', width: 200 },
    { field: 'amount', headerName: 'Valor', width: 150 },
    {
      field: 'status',
      headerName: 'Status',
      width: 120,
      renderCell: (params) => <ChargeTagStatus status={params.value} />
    },
  ];

  return (
    <ThemeProvider>
      <LayoutRoot>
        <Sidebar>
          <SidebarGroup title="Menu">
            <SidebarItem icon="dashboard" label="Dashboard" href="/" />
            <SidebarItem icon="payment" label="Cobranças" href="/charges" />
          </SidebarGroup>
        </Sidebar>

        <LayoutWrapper>
          <ScreenHeaderUI
            title="Dashboard"
            actions={
              <ActionButton
                label="Nova Cobrança"
                onClick={() => showSnackbar('Cobrança criada!')}
              />
            }
          />

          <CardAnalytics
            title="Total Recebido"
            value="R$ 15.000,00"
            total="150 transações"
            color="success"
          />

          <Card>
            <CardContent>
              <DataGrid columns={columns} rows={data} />
            </CardContent>
          </Card>
        </LayoutWrapper>
      </LayoutRoot>
    </ThemeProvider>
  );
}
```

---

Gerado automaticamente para integração com LLMs.
