# rharuow-ds

[![NPM Version](https://img.shields.io/npm/v/rharuow-ds)](https://www.npmjs.com/package/rharuow-ds)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Build Status](https://github.com/Rharuow/rharuow-ds-docs/workflows/CI/badge.svg)](https://github.com/Rharuow/rharuow-ds-docs/actions)

Um Design System moderno em React com integração completa ao React Hook Form, estilizado com Tailwind CSS e baseado em shadcn/ui.

## 🌟 Características

- ⚛️ **React 18+** com TypeScript
- 🧩 **24 componentes** prontos para uso (Input, ColorInput, Textarea, Select, AsyncSelect, MultiSelect, MultiAsyncSelect, RadioGroup, Button, Switch, Chip, Pagination, Card, Table, Tooltip, Accordion, AsideSheet, Sidebar, BottomSheet, BottomTabNavigator, Modal, Toaster, ImageInput)
- 💡 **Filtro digitável** em componentes Select - Digite para encontrar opções rapidamente
- 🔗 **Integração nativa** com React Hook Form
- 🎨 **Sistema de cores automático** - Defina apenas 2 cores e todas as variações são calculadas automaticamente
- 🎯 **Contraste automático** para textos (WCAG AA compliance)
- 🌓 **Dark mode** com ajustes automáticos de cores
- 🎯 **Componentes acessíveis** (ARIA)
- 📱 **Responsivo** por padrão
- 🎭 **Animações suaves** e modernas
- 📚 **Documentação interativa** com Storybook

## 📚 Documentação

Acesse a documentação interativa dos componentes em:
**[https://rharuow.github.io/rharuow-ds-docs/](https://rharuow.github.io/rharuow-ds-docs/)**

---

## 🚀 Instalação

Adicione o pacote ao seu projeto:

```bash
npm install rharuow-ds
```

### Dependências necessárias

Se você for usar componentes com formulários, instale também:

```bash
npm install react-hook-form
```

> **💡 Atenção:**  
> Não é necessário instalar ou configurar Tailwind CSS no seu projeto consumidor para usar os estilos do rharuow-ds. O CSS já vem pronto no pacote!

### Compatibilidade

- ⚛️ React 16.8+ (hooks)
- 📋 React Hook Form 7.0+
- 🌐 Navegadores modernos (ES2018+)

---

## 📖 Como usar

1. **Importe o CSS do design system**  
   No seu arquivo de entrada (ex: `src/main.tsx`, `src/index.tsx` ou `_app.tsx` no Next.js):

   ```js
   import "rharuow-ds/dist/styles.css";
   ```

2. **Use os componentes normalmente**

   ```tsx
   import {
     Card,
     Table,
     Button,
     Chip,
     Pagination,
     Input,
     Textarea,
     Select,
     AsyncSelect,
     MultiSelect,
     RadioGroup,
     Tooltip,
     Accordion,
     AsideSheet,
     Sidebar,
    BottomSheet,
    BottomTabNavigator,
    Switch,
     Modal,
     Toaster,
     ImageInput,
     ColorInput,
   } from "rharuow-ds";

   function App() {
     return (
       <div>
         {/* Exemplo básico do Card */}
         <Card variant="default">
           <Card.Header>
             <h3>Título do Card</h3>
             <p>Subtítulo ou descrição</p>
           </Card.Header>
           <Card.Body>
             <p>Conteúdo principal do card</p>
           </Card.Body>
           <Card.Footer>
             <Button>Ação Principal</Button>
           </Card.Footer>
         </Card>

         {/* Exemplo da Table */}
         <Table variant="striped" size="md">
           <Table.Header>
             <Table.Row>
               <Table.Cell as="th">Nome</Table.Cell>
               <Table.Cell as="th">Email</Table.Cell>
               <Table.Cell as="th">Ações</Table.Cell>
             </Table.Row>
           </Table.Header>
           <Table.Body>
             <Table.Row>
               <Table.Cell>João Silva</Table.Cell>
               <Table.Cell>joao@email.com</Table.Cell>
               <Table.Cell>
                 <Button variant="outline">Editar</Button>
               </Table.Cell>
             </Table.Row>
           </Table.Body>
         </Table>

         {/* Outros componentes */}
         <Input label="E-mail" name="email" type="email" />
         <Input label="Senha" name="password" type="password" />
         <Textarea label="Comentários" name="comments" rows={4} />
         <Select
           label="País"
           name="country"
           options={[
             { label: "Brasil", value: "br" },
             { label: "Estados Unidos", value: "us" },
           ]}
         />
         <RadioGroup
           label="Tamanho"
           name="size"
           options={[
             { label: "Pequeno", value: "sm" },
             { label: "Médio", value: "md" },
             { label: "Grande", value: "lg" },
           ]}
         />
         
         <Tooltip content="Clique para enviar o formulário" position="top">
           <Button variant="default">Enviar</Button>
         </Tooltip>
       </div>
     );
   }
   ```

3. **Para componentes com React Hook Form**

   ```tsx
   import { useForm, FormProvider } from "react-hook-form";
   import {
     Card,
     Table,
     Input,
     Textarea,
     Select,
     AsyncSelect,
     MultiAsyncSelect,
     RadioGroup,
     Button,
     Tooltip,
     Accordion,
     AsideSheet,
     Sidebar,
    BottomSheet,
    BottomTabNavigator,
    Switch,
     Modal,
     Toaster,
     ImageInput,
     ColorInput,
   } from "rharuow-ds";

   function FormExample() {
     const methods = useForm();

     const loadCountries = async (search?: string) => {
       // Simular chamada à API
       const countries = [
         { label: "Brasil", value: "br" },
         { label: "Argentina", value: "ar" },
         { label: "Estados Unidos", value: "us" },
         { label: "Chile", value: "cl" },
         { label: "Peru", value: "pe" },
       ];

       if (!search) return countries;
       return countries.filter((c) =>
         c.label.toLowerCase().includes(search.toLowerCase())
       );
     };

     return (
       <Card variant="default" size="lg">
         <Card.Header>
           <h2>Formulário de Cadastro</h2>
           <p>Preencha os dados abaixo</p>
         </Card.Header>
         
         <Card.Body>
           <FormProvider {...methods}>
             <form onSubmit={methods.handleSubmit(console.log)}>
               <Input label="Nome" name="name" />
               <Input label="E-mail" name="email" type="email" />
               <Input label="Senha" name="password" type="password" />
               <Textarea label="Observações" name="notes" rows={3} />

               <AsyncSelect
                 label="País"
                 name="country"
                 loadOptions={loadCountries}
                 searchable
                 isClearable
               />

               <MultiAsyncSelect
                 label="Países favoritos"
                 name="favoriteCountries"
                 loadOptions={loadCountries}
                 searchable
                 isClearable
                 maxVisibleItems={2}
               />

               <RadioGroup
                 label="Tamanho"
                 name="size"
                 options={[
                   { label: "Pequeno", value: "sm" },
                   { label: "Médio", value: "md" },
                   { label: "Grande", value: "lg" },
                 ]}
               />
             </form>
           </FormProvider>
         </Card.Body>
         
         <Card.Footer>
           <div className="flex space-x-2">
             <Button variant="outline">Cancelar</Button>
             <Button type="submit">Enviar</Button>
           </div>
         </Card.Footer>
       </Card>
     );
   }
   ```

---

## Componentes Disponíveis

### � **Card**

Componente flexível para exibir conteúdo organizado em seções:

- ✅ **Estrutura modular**: Header, Body e Footer independentes
- ✅ **Múltiplas variantes**: default, outlined, elevated, flat
- ✅ **Largura flexível**: Por padrão, cresce para ocupar largura disponível
- ✅ **Controle de largura**: Use `constrainWidth=true` para aplicar limitações por tamanho
- ✅ **Tamanhos configuráveis**: sm, md, lg (aplicados apenas com `constrainWidth`)
- ✅ **Suporte ao tema dark**: Variáveis CSS para light/dark mode
- ✅ **Elementos semânticos**: Props `as` para acessibilidade (header, main, footer)
- ✅ **Flexibilidade total**: Use apenas as seções necessárias
- ✅ **Customização completa**: Padding, bordas arredondadas e estilos

### 📊 **Table**

Componente completo para exibição de dados tabulares:

- ✅ **Estrutura modular**: Table, Header, Body, Footer, Row, Cell
- ✅ **Múltiplas variantes**: default, striped, bordered
- ✅ **Tamanhos configuráveis**: sm, md, lg  
- ✅ **Responsividade**: Scroll horizontal automático
- ✅ **Header fixo**: Para tabelas com muitos dados
- ✅ **Suporte ao tema dark**: Variáveis CSS para light/dark mode
- ✅ **Alinhamento de células**: left, center, right
- ✅ **Colspan e rowspan**: Células que ocupam múltiplas colunas/linhas
- ✅ **Elementos semânticos**: Props `as` para acessibilidade (th/td, thead/tbody/tfoot)
- ✅ **Linhas interativas**: Hover e estados de seleção

### �

### 🎯 **Button**

Botão customizável com diferentes variantes, incluindo uma variante exclusiva para ícones.

- ✅ Variante `default` — fundo primário com texto contrastante
- ✅ Variante `outline` — borda primária com fundo transparente
- ✅ Variante `secondary` — fundo secundário com texto contrastante
- ✅ Variante `icon` — botão quadrado que centraliza um ícone filho

```tsx
import { Button } from "rharuow-ds";

// Botão padrão
<Button variant="default">Enviar</Button>

// Botão outline
<Button variant="outline">Cancelar</Button>

// Botão secundário
<Button variant="secondary">Mais opções</Button>

// Botão apenas com ícone (ícone é passado como filho)
<Button variant="icon" aria-label="Adicionar">
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <line x1="12" y1="5" x2="12" y2="19" />
    <line x1="5" y1="12" x2="19" y2="12" />
  </svg>
</Button>
```

> **Dica:** Na variante `icon`, o ícone é passado como `children` do botão e fica automaticamente centralizado. Use sempre `aria-label` para descrever a ação do botão para acessibilidade.

### 🏷️ **Chip**

Elemento pill interativo para filtros, tags e seleções toggleáveis:

- ✅ Estado ativo/inativo com visual distinto
- ✅ Ícone opcional à esquerda
- ✅ `onChange(active: boolean)` — callback de toggle
- ✅ Estado `disabled` com visual reduzido
- ✅ Acessível (`role="switch"`, `aria-checked`)
- ✅ Totalmente estilizável via `className`

```tsx
import { Chip } from "rharuow-ds";

// Toggle simples
const [active, setActive] = useState(false);
<Chip label="Filtro" active={active} onChange={setActive} />

// Grupo de filtros
const filters = ["React", "TypeScript", "Tailwind"];
const [selected, setSelected] = useState<string[]>([]);

const toggle = (filter: string) =>
  setSelected(prev =>
    prev.includes(filter) ? prev.filter(f => f !== filter) : [...prev, filter]
  );

{filters.map(filter => (
  <Chip
    key={filter}
    label={filter}
    active={selected.includes(filter)}
    onChange={() => toggle(filter)}
  />
))}

// Com ícone
<Chip
  label="Favorito"
  active={isFavorite}
  onChange={setIsFavorite}
  icon={<StarIcon />}
/>
```

### � **Pagination**

Componente de paginação com janela deslizante e ellipsis:

- ✅ Exibe janela de **3 páginas** centrada na página atual
- ✅ Ellipsis (`…`) + última página quando o total ultrapassa a janela visível
- ✅ Seta esquerda (← anterior) oculta na primeira página
- ✅ Seta direita (→ próxima) oculta na última página
- ✅ Estado `disabled` para toda a navegação
- ✅ Acessível (`role="navigation"`, `aria-label`, `aria-current`)

```tsx
import { Pagination } from "rharuow-ds";

const [page, setPage] = useState(1);

<Pagination
  totalPages={20}
  currentPage={page}
  onPageChange={setPage}
/>
```

### �📝 **Input**

Campo de texto versátil com label flutuante e integração com React Hook Form:

- ✅ Label flutuante animada
- ✅ Suporte a múltiplos tipos (text, email, password, number, tel, url)
- ✅ Variante de CEP com máscara automática (`00000-000`) e validação de formato
- ✅ Funcionalidade de password com botão mostrar/ocultar
- ✅ Variante de moeda com máscara e formatação automática (BRL por padrão)
- ✅ Saída configurável no React Hook Form como string formatada ou number
- ✅ `onChange` exposto para integrações como busca de endereço por CEP
- ✅ Ícones customizados opcionais
- ✅ Estados de erro integrados
- ✅ Totalmente acessível (ARIA)

Exemplo com CEP e `onChange` para busca de endereço:

```tsx
import React from "react";
import { Input } from "rharuow-ds";

function AddressForm() {
  const [cep, setCep] = React.useState("");

  const handleCepChange: React.ChangeEventHandler<HTMLInputElement> = async (event) => {
    const maskedCep = event.target.value;
    setCep(maskedCep);

    const normalizedCep = maskedCep.replace(/\D/g, "");
    if (normalizedCep.length === 8) {
      // Exemplo: chamar servico externo quando CEP estiver completo
      // const endereco = await buscarEnderecoPorCep(normalizedCep);
      // preencher campos do formulario...
    }
  };

  return (
    <Input
      name="cep"
      label="CEP"
      cep
      value={cep}
      onChange={handleCepChange}
    />
  );
}
```

Veja a story de CEP no Storybook para exemplos completos:

[Storybook - Input CEP](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-input-cep--default)

### � **Textarea**

Campo de texto multilinha com as mesmas funcionalidades do Input:

- ✅ Label flutuante animada
- ✅ Altura ajustável (propriedade `rows`)
- ✅ Redimensionamento vertical permitido
- ✅ Ícones customizados opcionais
- ✅ Estados de erro integrados
- ✅ Integração completa com React Hook Form
- ✅ Mesma consistência visual do Input

### �📋 **Select**

Seletor customizado com opções estáticas e suporte a busca.

### 🔄 **AsyncSelect**

Seletor com carregamento assíncrono de opções:

- ✅ Carregamento de dados via API
- ✅ Busca em tempo real (searchable)
- ✅ Debounce configurável
- ✅ Estados de loading e "sem opções"
- ✅ Integração completa com React Hook Form

### 🎛️ **MultiSelect**

Seletor múltiplo para escolha de várias opções:

- ✅ Seleção múltipla com checkboxes
- ✅ **Filtro digitável** (`searchable`) - Digite para encontrar opções
- ✅ Tags visuais para itens selecionados
- ✅ Remoção individual de itens
- ✅ Filtro case-sensitive configurável
- ✅ Função de filtro customizável
- ✅ Botão de limpeza geral (`isClearable`)
- ✅ Integração completa com React Hook Form

```tsx
// MultiSelect básico
<MultiSelect
  name="fruits"
  label="Escolha suas frutas favoritas"
  options={fruitOptions}
/>

// MultiSelect com filtro
<MultiSelect
  name="fruits"
  label="Escolha suas frutas favoritas"
  searchable
  filterPlaceholder="Digite para filtrar frutas..."
  caseSensitive={false}
  isClearable
  options={fruitOptions}
/>
```

### 🔄🎛️ **MultiAsyncSelect**

Seletor múltiplo com carregamento assíncrono:

- ✅ Todas as funcionalidades do AsyncSelect
- ✅ Seleção múltipla com tags visuais
- ✅ Remoção individual de itens selecionados
- ✅ Limite configurável de itens exibidos
- ✅ Contador de itens extras (+X mais)

### 🎯 **RadioGroup**

Radio buttons modernos e criativos:

- ✅ Design de botões estilizados (não radio tradicional)
- ✅ Ícones customizados opcionais
- ✅ Layout horizontal ou vertical
- ✅ Diferentes tamanhos (sm, md, lg)
- ✅ Animações ao selecionar

### 💡 **Tooltip**

Componente de tooltip inteligente e acessível:

- ✅ **Posicionamento automático**: top, bottom, left, right
- ✅ **Detecção de bordas**: Ajusta posição automaticamente se não couber na tela
- ✅ **Acessibilidade completa**: Suporte a navegação por teclado e screen readers
- ✅ **Animações suaves**: Transições de entrada e saída elegantes
- ✅ **Seta indicativa**: Aponta para o elemento que ativou o tooltip
- ✅ **Suporte a temas**: Variáveis CSS para light/dark mode
- ✅ **Flexível**: Funciona com qualquer elemento como trigger
- ✅ **Controle de estado**: Pode ser desabilitado conforme necessário
- ✅ **Largura configurável** (`maxWidth`): Limita a largura e permite quebra de linha no conteúdo

```tsx
// Tooltip básico
<Tooltip content="Informação útil" position="top">
  <Button>Passe o mouse aqui</Button>
</Tooltip>

// Tooltip com texto
<Tooltip content="Clique para mais detalhes" position="right">
  <span className="underline cursor-help">
    Texto com tooltip
  </span>
</Tooltip>

// Tooltip personalizado
<Tooltip 
  content="Tooltip customizado" 
  position="bottom"
  className="bg-red-500 text-white"
>
  <Button variant="outline">Hover aqui</Button>
</Tooltip>

// Tooltip desabilitado
<Tooltip content="Este não aparece" disabled>
  <Button>Tooltip desabilitado</Button>
</Tooltip>

// Tooltip com largura máxima (texto longo quebra em múltiplas linhas)
// Aceita número (convertido para px) ou qualquer string CSS válida
<Tooltip
  content="Este é um texto longo que vai quebrar em múltiplas linhas quando a largura for limitada."
  position="top"
  maxWidth={200}
>
  <Button>maxWidth numérico (200px)</Button>
</Tooltip>

<Tooltip
  content="Também é possível usar valores CSS como rem, em ou percentagem."
  position="bottom"
  maxWidth="12rem"
>
  <Button>maxWidth string (12rem)</Button>
</Tooltip>
```

#### Props do Tooltip

| Prop | Tipo | Padrão | Descrição |
|------|------|--------|-----------|
| `content` | `string` | — | Texto exibido no tooltip |
| `position` | `"top" \| "bottom" \| "left" \| "right"` | `"top"` | Posição preferencial do tooltip |
| `disabled` | `boolean` | `false` | Desabilita o tooltip |
| `maxWidth` | `string \| number` | `undefined` | Largura máxima. Número é convertido para `px`. Quando definido, o texto quebra em múltiplas linhas |
| `className` | `string` | `""` | Classes CSS adicionais para o balão do tooltip |

### 🪗 **Accordion**

Componente de accordion (acordeão) flexível e acessível para expandir e colapsar seções de conteúdo:

- ✅ **Modo single**: Apenas um item aberto por vez
- ✅ **Modo multiple**: Vários itens podem estar abertos simultaneamente
- ✅ **Animações suaves**: Transições de altura com ease-in-out
- ✅ **Variantes visuais**: default, bordered, separated
- ✅ **Acessibilidade completa**: ARIA labels e navegação por teclado
- ✅ **Itens desabilitados**: Suporte para itens que não podem ser expandidos
- ✅ **Ícones customizados**: Adicione ícones aos títulos
- ✅ **Collapsible configurável**: Controle se todos os itens podem ser fechados
- ✅ **DefaultOpen**: Items podem iniciar abertos
- ✅ **Customização total**: Classes CSS para header e content

```tsx
// Accordion básico
<Accordion>
  <Accordion.Item title="O que é React?">
    <p>React é uma biblioteca JavaScript para construir interfaces de usuário.</p>
  </Accordion.Item>
  <Accordion.Item title="O que é TypeScript?">
    <p>TypeScript é um superset de JavaScript que adiciona tipagem estática.</p>
  </Accordion.Item>
</Accordion>

// Accordion com múltiplos itens abertos
<Accordion type="multiple">
  <Accordion.Item title="Seção 1" defaultOpen>
    <p>Esta seção inicia aberta.</p>
  </Accordion.Item>
  <Accordion.Item title="Seção 2" defaultOpen>
    <p>Esta seção também inicia aberta.</p>
  </Accordion.Item>
</Accordion>

// Accordion com variant bordered
<Accordion variant="bordered">
  <Accordion.Item title="Recursos do Produto">
    <ul>
      <li>Interface intuitiva</li>
      <li>Integração com múltiplas plataformas</li>
      <li>Suporte 24/7</li>
    </ul>
  </Accordion.Item>
</Accordion>

// Accordion com ícones customizados
<Accordion variant="separated" type="multiple">
  <Accordion.Item
    title="Documentação"
    icon={<DocumentIcon />}
  >
    <p>Acesse a documentação completa.</p>
  </Accordion.Item>
  <Accordion.Item
    title="Suporte"
    icon={<SupportIcon />}
  >
    <p>Entre em contato com nossa equipe.</p>
  </Accordion.Item>
</Accordion>

// Accordion não collapsible (sempre mantém um aberto)
<Accordion collapsible={false}>
  <Accordion.Item title="Passo 1" defaultOpen>
    <p>Configure seu ambiente.</p>
  </Accordion.Item>
  <Accordion.Item title="Passo 2">
    <p>Desenvolva sua aplicação.</p>
  </Accordion.Item>
</Accordion>
```

### 🪟 **AsideSheet**

Componente tipo painel deslizante (sheet) que abre a partir das bordas da tela.

- ✅ Suporta controle programático (controlled) e estado interno (uncontrolled)
- ✅ Abre da direita para a esquerda ou da esquerda para a direita (`side: 'left' | 'right'`)
- ✅ Largura configurável via `size` ou `className`
- ✅ Acessível: foco gerenciado e comportamento esperado ao fechar (Esc)

Props principais:

- `isOpen?: boolean` — controla visibilidade (quando usado como controlled)
- `defaultOpen?: boolean` — estado inicial (uncontrolled)
- `onClose?: () => void` — callback chamado ao fechar
- `side?: 'left' | 'right'` — lado de abertura (padrão: 'right')
- `size?: 'sm' | 'md' | 'lg' | 'full'` — tamanho pré-definido do sheet
- `className?: string` — classes adicionais para o container
- `title?: string | React.ReactNode` — título opcional do painel

Exemplo de uso (controlado):

```tsx
import React from 'react';
import { AsideSheet, Button } from 'rharuow-ds';

function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <div>
      <Button onClick={() => setOpen(true)}>Abrir Aside</Button>

      <AsideSheet
        isOpen={open}
        onClose={() => setOpen(false)}
        side="right"
        size="md"
      >
        <AsideSheet.Header>
          <h3>Detalhes</h3>
        </AsideSheet.Header>

        <AsideSheet.Body>
          <p>Conteúdo do painel.</p>
        </AsideSheet.Body>

        <AsideSheet.Footer>
          <Button variant="outline" onClick={() => setOpen(false)}>
            Fechar
          </Button>
        </AsideSheet.Footer>
      </AsideSheet>
    </div>
  );
}
```

Veja a story do componente no Storybook para demonstrações e variações (left/right, controlled/uncontrolled):

[Storybook — AsideSheet](https://rharuow.github.io/rharuow-ds-docs/?path=/story/asidesheet--default)

### 🗂️ **Sidebar**

Painel lateral persistente para telas `md+` (≥ 768px). Diferente do `AsideSheet`, a Sidebar não usa overlay nem portal — é parte do layout fixo da página.

- ✅ **Exclusivo para telas médias e grandes** — oculto automaticamente em mobile (`hidden md:flex`)
- ✅ Lado configurável: `left` ou `right`
- ✅ Larguras predefinidas: `sm` (256px), `md` (288px), `lg` (384px)
- ✅ Largura customizada com qualquer valor CSS (ex: `"320px"`, `"20rem"`)
- ✅ Animação suave de slide in/out
- ✅ Sem overlay — não bloqueia o conteúdo principal
- ✅ Variável CSS `--sidebar-bg` (fallback para `--aside-bg` e depois `#ffffff`)
- ✅ Acessível: `role="navigation"`, `aria-expanded`

Props principais:

- `open: boolean` — controla visibilidade (slide in/out)
- `side?: 'left' | 'right'` — lado de abertura (padrão: `'left'`)
- `size?: 'sm' | 'md' | 'lg' | string` — tamanho pré-definido ou valor CSS customizado (padrão: `'md'`)
- `className?: string` — classes adicionais para o container

Exemplo de uso:

```tsx
import React from 'react';
import { Sidebar, Button } from 'rharuow-ds';

function Layout() {
  const [sidebarOpen, setSidebarOpen] = React.useState(true);

  return (
    <div className="flex min-h-screen">
      <Sidebar open={sidebarOpen} side="left" size="md">
        <div className="p-6 flex flex-col gap-4">
          <h3 className="text-lg font-semibold">Menu</h3>
          <nav className="flex flex-col gap-2 text-sm">
            <a href="/dashboard">Dashboard</a>
            <a href="/users">Usuários</a>
            <a href="/settings">Configurações</a>
          </nav>
        </div>
      </Sidebar>

      {/* Conteúdo principal com margem para não ficar atrás da sidebar */}
      <main className="flex-1 md:ml-72 p-6">
        <Button onClick={() => setSidebarOpen((v) => !v)}>
          {sidebarOpen ? 'Fechar Sidebar' : 'Abrir Sidebar'}
        </Button>
        <p>Conteúdo da página.</p>
      </main>
    </div>
  );
}
```

Exemplo com largura customizada:

```tsx
<Sidebar open={open} side="left" size="320px">
  {/* conteúdo */}
</Sidebar>
```

Variável CSS para customizar a cor de fundo:

```css
:root {
  --sidebar-bg: #1e293b; /* escuro */
}
```

Veja as stories do componente no Storybook:

[Storybook — Sidebar](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-sidebar--left)

### 🔀 **Switch**

Componente de alternancia (on/off) com foco em acessibilidade e controle simples de estado.

- ✅ Funciona em modo controlado com `checked` + `onChange`
- ✅ Label opcional com posicao configuravel (`left` ou `right`)
- ✅ Tamanhos predefinidos: `sm`, `md`, `lg`
- ✅ Estado `disabled` com estilo e comportamento apropriados
- ✅ Acessivel com `role="switch"` e `aria-checked`

Props principais:

- `checked?: boolean` - Estado atual do switch
- `onChange?: (checked: boolean) => void` - Callback ao alternar
- `label?: string` - Texto exibido ao lado do controle
- `labelPosition?: 'left' | 'right'` - Posicao do label (padrao: `'right'`)
- `size?: 'sm' | 'md' | 'lg'` - Tamanho visual (padrao: `'md'`)
- `disabled?: boolean` - Desabilita interacao

Exemplo de uso:

```tsx
import React from 'react';
import { Switch } from 'rharuow-ds';

function Settings() {
  const [notifications, setNotifications] = React.useState(false);

  return (
    <Switch
      checked={notifications}
      onChange={setNotifications}
      label={notifications ? 'Notificacoes ativas' : 'Notificacoes inativas'}
      labelPosition="right"
      size="md"
    />
  );
}
```

Storybook:

[Storybook — Switch](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-switch--default)

### 📱 **BottomTabNavigator**

Navegacao inferior fixa para mobile, ideal para areas principais do app.

- ✅ Exibido somente em telas pequenas (`md:hidden`)
- ✅ Suporte a modo controlado (`value`) e nao controlado (`defaultValue`)
- ✅ Cada item pode ter icone, badge e estado desabilitado
- ✅ Layout responsivo com colunas dinamicas conforme quantidade de tabs
- ✅ Acessivel com `role="tablist"` e `role="tab"`

Props principais:

- `items: BottomTabItem[]` - Lista de abas
- `value?: string` - Valor selecionado (modo controlado)
- `defaultValue?: string` - Valor inicial (modo nao controlado)
- `onValueChange?: (value: string) => void` - Callback de troca de aba

Exemplo de uso:

```tsx
import React from 'react';
import { BottomTabNavigator } from 'rharuow-ds';

function MobileLayout() {
  const [active, setActive] = React.useState('home');

  return (
    <BottomTabNavigator
      value={active}
      onValueChange={setActive}
      items={[
        { id: 'home', label: 'Inicio', icon: '🏠' },
        { id: 'search', label: 'Buscar', icon: '🔎' },
        { id: 'wallet', label: 'Carteira', icon: '💳', badge: '●' },
        { id: 'profile', label: 'Perfil', icon: '👤' },
      ]}
    />
  );
}
```

Storybook:

[Storybook — BottomTabNavigator](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-bottomtabnavigator--default)

### 🧲 **BottomSheet**

Painel deslizante que abre de baixo para cima em mobile, util para filtros, acoes e formularios curtos.

- ✅ Exibido apenas em mobile (`md:hidden`)
- ✅ Portal no `document.body` com overlay
- ✅ Fechamento por overlay e tecla ESC (configuravel)
- ✅ Bloqueio de scroll do body enquanto aberto (configuravel)
- ✅ Suporte a arrastar para baixo para fechar (`closeOnDragDown`)
- ✅ Tamanhos predefinidos (`sm`, `md`, `lg`, `full`) ou valor customizado

Props principais:

- `open: boolean` - Controla visibilidade do painel
- `onClose: () => void` - Callback ao fechar
- `size?: 'sm' | 'md' | 'lg' | 'full' | string` - Altura maxima do painel
- `closeOnOverlayClick?: boolean` - Fecha ao clicar fora (padrao: `true`)
- `closeOnEscape?: boolean` - Fecha ao pressionar ESC (padrao: `true`)
- `lockBodyScroll?: boolean` - Bloqueia scroll da pagina (padrao: `true`)
- `closeOnDragDown?: boolean` - Habilita gesto de arrastar para fechar (padrao: `true`)
- `dragCloseThreshold?: number` - Distancia minima de arraste para fechar (padrao: `100`)

Exemplo de uso:

```tsx
import React from 'react';
import { BottomSheet, Button } from 'rharuow-ds';

function Filters() {
  const [open, setOpen] = React.useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Abrir filtros</Button>

      <BottomSheet open={open} onClose={() => setOpen(false)} size="md">
        <div className="px-4 pb-6 pt-4">
          <h3 className="text-lg font-semibold">Filtros rapidos</h3>
          <p className="mt-2 text-sm">Escolha os filtros e aplique.</p>
        </div>
      </BottomSheet>
    </>
  );
}
```

Storybook:

[Storybook — BottomSheet](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-bottomsheet--default)

### 🎭 **Modal**

Componente de diálogo modal para exibir conteúdo sobreposto à página principal.

- ✅ Overlay com transparência configurável
- ✅ Múltiplos tamanhos: sm, md, lg, xl, full
- ✅ Variantes de cor: default, primary, secondary (usando CSS Variables)
- ✅ Controle de fechamento via overlay, ESC ou botão X
- ✅ Prevenção de scroll do body quando aberto
- ✅ Animações suaves de entrada/saída
- ✅ Sub-componentes para estruturação: Header, Body, Footer
- ✅ Renderização via Portal (React Portal)
- ✅ Acessível: role="dialog", aria-modal

Props principais:

- `open: boolean` — controla visibilidade do modal
- `onClose: () => void` — callback chamado ao fechar
- `size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'` — tamanho do modal (padrão: 'md')
- `variant?: 'default' | 'primary' | 'secondary'` — variante de cor (padrão: 'default')
- `closeOnOverlayClick?: boolean` — fecha ao clicar fora (padrão: true)
- `closeOnEscape?: boolean` — fecha ao pressionar ESC (padrão: true)
- `showCloseButton?: boolean` — exibe botão X de fechar (padrão: true)
- `className?: string` — classes adicionais para o container do modal

Exemplo de uso básico:

```tsx
import React from 'react';
import { Modal, Button } from 'rharuow-ds';

function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <div>
      <Button onClick={() => setOpen(true)}>Abrir Modal</Button>

      <Modal open={open} onClose={() => setOpen(false)}>
        <h2>Título do Modal</h2>
        <p>Conteúdo do modal aqui.</p>
      </Modal>
    </div>
  );
}
```

Exemplo com estrutura completa:

```tsx
import React from 'react';
import { Modal, Button } from 'rharuow-ds';

function Example() {
  const [open, setOpen] = React.useState(false);

  return (
    <div>
      <Button onClick={() => setOpen(true)}>Confirmar Ação</Button>

      <Modal 
        open={open} 
        onClose={() => setOpen(false)}
        size="md"
      >
        <Modal.Header>
          <h2 className="text-2xl font-bold">Confirmar Exclusão</h2>
          <p className="text-sm text-gray-500">Esta ação não pode ser desfeita</p>
        </Modal.Header>

        <Modal.Body>
          <p className="text-gray-700">
            Você tem certeza que deseja excluir este item? 
            Todos os dados associados serão removidos permanentemente.
          </p>
        </Modal.Body>

        <Modal.Footer>
          <Button variant="outline" onClick={() => setOpen(false)}>
            Cancelar
          </Button>
          <Button onClick={() => {
            // Executar ação
            setOpen(false);
          }}>
            Confirmar
          </Button>
        </Modal.Footer>
      </Modal>
    </div>
  );
}
```

Exemplo com formulário integrado:

```tsx
import React from 'react';
import { Modal, Button, Input } from 'rharuow-ds';
import { FormProvider, useForm } from 'react-hook-form';

function FormModal() {
  const [open, setOpen] = React.useState(false);
  const methods = useForm();

  const onSubmit = (data: any) => {
    console.log('Form data:', data);
    setOpen(false);
    methods.reset();
  };

  return (
    <div>
      <Button onClick={() => setOpen(true)}>Novo Cadastro</Button>

      <Modal 
        open={open} 
        onClose={() => setOpen(false)}
        size="lg"
        closeOnOverlayClick={false}
      >
        <FormProvider {...methods}>
          <form onSubmit={methods.handleSubmit(onSubmit)}>
            <Modal.Header>
              <h2 className="text-2xl font-bold">Cadastrar Usuário</h2>
            </Modal.Header>

            <Modal.Body>
              <div className="space-y-4">
                <Input label="Nome completo" name="name" required />
                <Input label="E-mail" name="email" type="email" required />
                <Input label="Telefone" name="phone" />
              </div>
            </Modal.Body>

            <Modal.Footer>
              <Button 
                type="button" 
                variant="outline" 
                onClick={() => setOpen(false)}
              >
                Cancelar
              </Button>
              <Button type="submit">Salvar</Button>
            </Modal.Footer>
          </form>
        </FormProvider>
      </Modal>
    </div>
  );
}
```

Exemplo com variantes de cor:

```tsx
import React from 'react';
import { Modal, Button } from 'rharuow-ds';

function ColorVariants() {
  const [openPrimary, setOpenPrimary] = React.useState(false);
  const [openSecondary, setOpenSecondary] = React.useState(false);

  return (
    <div>
      {/* Modal com cor primária */}
      <Button onClick={() => setOpenPrimary(true)}>
        Modal Primary
      </Button>
      
      <Modal 
        open={openPrimary} 
        onClose={() => setOpenPrimary(false)}
        variant="primary"
      >
        <Modal.Header>
          <h2 className="text-2xl font-bold">Ação Importante</h2>
        </Modal.Header>
        <Modal.Body>
          <p className="opacity-95">
            Este modal usa as cores primárias da aplicação, 
            ideal para destacar ações principais.
          </p>
        </Modal.Body>
        <Modal.Footer>
          <Button variant="outline" onClick={() => setOpenPrimary(false)}>
            Fechar
          </Button>
        </Modal.Footer>
      </Modal>

      {/* Modal com cor secundária */}
      <Button onClick={() => setOpenSecondary(true)} variant="secondary">
        Modal Secondary
      </Button>
      
      <Modal 
        open={openSecondary} 
        onClose={() => setOpenSecondary(false)}
        variant="secondary"
      >
        <Modal.Header>
          <h2 className="text-2xl font-bold">Aviso</h2>
        </Modal.Header>
        <Modal.Body>
          <p className="opacity-95">
            Este modal usa as cores secundárias da aplicação,
            ideal para avisos e ações alternativas.
          </p>
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={() => setOpenSecondary(false)}>
            Fechar
          </Button>
        </Modal.Footer>
      </Modal>
    </div>
  );
}
```

#### Customizando o background do Modal (`--bg-modal`)

O background do Modal na variante `default` pode ser customizado via a variável CSS `--bg-modal`.

| Tema | Valor padrão |
|------|-------------|
| Light | `#ffffff` (branco) |
| Dark  | `#000000` (preto) |

Para customizar no seu app consumidor, defina a variável no seu CSS global ou diretamente no elemento:

```css
/* CSS global da aplicação */
:root {
  --bg-modal: #1e3a5f; /* Azul escuro customizado */
}

/* Ou por tema */
:root {
  --bg-modal: #f0f4f8; /* Light */
}
[data-theme="dark"], .dark {
  --bg-modal: #1a1a2e; /* Dark */
}
```

```tsx
// Ou inline via style (para casos específicos)
<div style={{ "--bg-modal": "#1e3a5f" } as React.CSSProperties}>
  <Modal open={open} onClose={onClose}>...</Modal>
</div>
```

> **Nota:** A variável `--bg-modal` afeta apenas a variante `default`. As variantes `primary` e `secondary` usam `--primary` e `--secondary` respectivamente.

Veja a story do componente no Storybook para mais exemplos e variações:

[Storybook — Modal](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-modal--basic)

### � **Toaster**

Sistema completo de notificações toast para feedback ao usuário com múltiplas variantes e posicionamento flexível.

- ✅ 5 variantes de toast: success, error, warning, info, default
- ✅ 6 posições configuráveis na tela
- ✅ Auto-dismiss com duração customizável
- ✅ Toast permanente (duration: 0)
- ✅ Ícones automáticos por variante
- ✅ Animações suaves de entrada e saída
- ✅ Limite de toasts simultâneos (padrão: 5)
- ✅ Callbacks ao fechar
- ✅ Hook `useToast` para uso simplificado
- ✅ Gerenciamento via Context API

**Configuração inicial:**

O Toaster precisa ser configurado uma única vez no nível superior da aplicação:

```tsx
import React from 'react';
import { ToasterProvider } from 'rharuow-ds';

function App() {
  return (
    <ToasterProvider position="top-right" maxToasts={5}>
      {/* Sua aplicação aqui */}
      <YourApp />
    </ToasterProvider>
  );
}
```

Props do `ToasterProvider`:

- `position?: ToastPosition` - Posição dos toasts na tela (padrão: 'top-right')
  - Opções: 'top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'
- `maxToasts?: number` - Número máximo de toasts simultâneos (padrão: 5)

**Uso básico com hook `useToast`:**

```tsx
import React from 'react';
import { useToast, Button } from 'rharuow-ds';

function MyComponent() {
  const toast = useToast();

  return (
    <div>
      <Button onClick={() => toast.success('Operação realizada com sucesso!')}>
        Success
      </Button>

      <Button onClick={() => toast.error('Erro ao processar requisição')}>
        Error
      </Button>

      <Button onClick={() => toast.warning('Atenção: verifique os dados')}>
        Warning
      </Button>

      <Button onClick={() => toast.info('Você tem 3 novas mensagens')}>
        Info
      </Button>
    </div>
  );
}
```

**Toasts com duração customizada:**

```tsx
import React from 'react';
import { useToast, Button } from 'rharuow-ds';

function CustomDuration() {
  const toast = useToast();

  return (
    <div>
      {/* Toast rápido - 2 segundos */}
      <Button onClick={() => toast.success('Toast rápido', 2000)}>
        2 Segundos
      </Button>

      {/* Toast longo - 10 segundos */}
      <Button onClick={() => toast.info('Toast longo', 10000)}>
        10 Segundos
      </Button>

      {/* Toast permanente - não fecha automaticamente */}
      <Button 
        onClick={() => toast.toast('Toast permanente', { duration: 0 })}
      >
        Permanente
      </Button>
    </div>
  );
}
```

**Toast com callback ao fechar:**

```tsx
import React from 'react';
import { useToaster, Button } from 'rharuow-ds';

function WithCallback() {
  const { addToast } = useToaster();

  const handleAction = () => {
    addToast({
      message: 'Processando dados...',
      variant: 'info',
      duration: 3000,
      onClose: () => {
        console.log('Toast fechado!');
        // Executar ação após fechamento
        performNextAction();
      },
    });
  };

  return <Button onClick={handleAction}>Iniciar Processo</Button>;
}
```

**Exemplo completo em um formulário:**

```tsx
import React from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import { Input, Button, useToast } from 'rharuow-ds';

function FormWithToast() {
  const methods = useForm();
  const toast = useToast();

  const onSubmit = async (data: any) => {
    try {
      // Simular chamada à API
      await saveData(data);
      
      toast.success('Dados salvos com sucesso!');
      methods.reset();
    } catch (error) {
      toast.error('Erro ao salvar dados. Tente novamente.');
      console.error(error);
    }
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <Input label="Nome" name="name" required />
        <Input label="E-mail" name="email" type="email" required />
        
        <Button type="submit">Salvar</Button>
      </form>
    </FormProvider>
  );
}
```

**API do hook `useToast`:**

```typescript
const toast = useToast();

// Métodos disponíveis:
toast.success(message: string, duration?: number)
toast.error(message: string, duration?: number)
toast.warning(message: string, duration?: number)
toast.info(message: string, duration?: number)
toast.toast(message: string, options?: ToastOptions)
```

**API avançada com `useToaster`:**

```typescript
const { addToast, removeToast, clearAll, toasts } = useToaster();

// Adicionar toast com controle total
const id = addToast({
  message: 'Mensagem personalizada',
  variant: 'success',
  duration: 5000,
  onClose: () => console.log('Fechado'),
});

// Remover toast específico
removeToast(id);

// Limpar todos os toasts
clearAll();
```

**Dicas de uso:**

- Use `success` para operações bem-sucedidas (save, delete, update)
- Use `error` para falhas e erros
- Use `warning` para avisos que requerem atenção
- Use `info` para informações gerais
- Configure `duration: 0` para toasts que precisam de ação manual do usuário
- Posicione toasts conforme o contexto: top para notificações gerais, bottom para ações específicas

Veja a story do componente no Storybook para demonstrações interativas:

[Storybook — Toaster](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-toaster--top-right)

### �📷 **ImageInput**

Componente para seleção e upload de imagens com preview e ações de confirmação/remoção:

- ✅ **Seleção via explorador** - Clique para abrir o explorador de arquivos (apenas imagens)
- ✅ **Preview da imagem** - Visualização imediata após seleção
- ✅ **Modo avatar** (`avatar={true}`) - Formato circular para fotos de perfil
- ✅ **Ações de confirmação** - Botões para confirmar upload ou cancelar
- ✅ **Remoção de imagem** - Botão para excluir imagem já salva
- ✅ **Suporte a URLs externas** - Exibe imagens já salvas via `value` prop
- ✅ **Validação de arquivos** - Controle de tipo e tamanho máximo
- ✅ **Estados de loading** - Indicação visual durante upload/remoção
- ✅ **Flexível** - Funciona com qualquer serviço (Cloudinary, Firebase, S3, etc.)
- ✅ **Integração com React Hook Form** - Nome do campo e validação

Props principais:

- `avatar?: boolean` — formato circular (ideal para avatars)
- `value?: string` — URL da imagem atual (já salva)
- `onUpload?: (file: File) => Promise<string>` — callback para upload (retorna URL)
- `onRemove?: (imageUrl?: string) => Promise<void>` — callback para remoção
- `accept?: string` — tipos aceitos (padrão: "image/*")
- `maxSize?: number` — tamanho máximo em bytes
- `size?: 'sm' | 'md' | 'lg'` — tamanho do componente
- `loading?: boolean` — estado de carregamento
- `disabled?: boolean` — desabilitar interações

Exemplo básico:

```tsx
import React from 'react';
import { ImageInput } from 'rharuow-ds';

function ProfileForm() {
  const [avatarUrl, setAvatarUrl] = React.useState('');

  const handleUpload = async (file: File): Promise<string> => {
    // Upload para seu serviço preferido (Cloudinary, Firebase, etc.)
    const formData = new FormData();
    formData.append('file', file);
    
    const response = await fetch('/api/upload', {
      method: 'POST',
      body: formData
    });
    
    const data = await response.json();
    setAvatarUrl(data.url);
    return data.url;
  };

  const handleRemove = async (url?: string) => {
    // Remover do serviço se necessário
    await fetch(`/api/delete?url=${encodeURIComponent(url || '')}`, {
      method: 'DELETE'
    });
    setAvatarUrl('');
  };

  return (
    <ImageInput
      avatar
      label="Foto do Perfil"
      value={avatarUrl}
      onUpload={handleUpload}
      onRemove={handleRemove}
      size="lg"
      maxSize={2 * 1024 * 1024} // 2MB
    />
  );
}
```

Exemplo com Cloudinary:

```tsx
const uploadToCloudinary = async (file: File): Promise<string> => {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('upload_preset', 'seu_preset');

  const response = await fetch(
    `https://api.cloudinary.com/v1_1/seu_cloud_name/image/upload`,
    {
      method: 'POST',
      body: formData
    }
  );

  const data = await response.json();
  return data.secure_url;
};

<ImageInput 
  onUpload={uploadToCloudinary}
  placeholder="Upload para Cloudinary"
/>
```

Veja a story do componente no Storybook para demonstrações completas:

[Storybook — ImageInput](https://rharuow.github.io/rharuow-ds-docs/?path=/story/imageinput--default)

---

### 🎨 **ColorInput**

Componente de seleção de cor (color picker) com label flutuante e integração nativa com React Hook Form:

- ✅ **Seletor nativo** - Usa `<input type="color">` do navegador para máxima compatibilidade
- ✅ **Valor hexadecimal visível** - Exibe o código hex selecionado ao lado do swatch
- ✅ **Label flutuante** - Mesmo comportamento do componente `Input`
- ✅ **Integração com React Hook Form** - Registra automaticamente via `useFormContext`
- ✅ **Controlado ou não-controlado** - Funciona com ou sem `FormProvider`
- ✅ **Acessível** - Label associado ao input via `htmlFor`

Props principais:

- `name: string` — nome do campo (obrigatório, usado no React Hook Form)
- `label?: string` — label flutuante
- `containerClassName?: string` — classe extra no wrapper
- `disabled?: boolean` — desabilita o campo

Exemplo básico:

```tsx
import { ColorInput } from 'rharuow-ds';
import { FormProvider, useForm } from 'react-hook-form';

function ThemeForm() {
  const methods = useForm({ defaultValues: { primaryColor: '#8b5cf6' } });

  const onSubmit = (data: { primaryColor: string }) => {
    console.log('Cor escolhida:', data.primaryColor);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <ColorInput name="primaryColor" label="Cor primária" />
        <button type="submit">Salvar</button>
      </form>
    </FormProvider>
  );
}
```

Exemplo controlado (sem React Hook Form):

```tsx
import React from 'react';
import { ColorInput } from 'rharuow-ds';

function ColorPicker() {
  const [color, setColor] = React.useState('#ec4899');

  return (
    <ColorInput
      name="cor"
      label="Escolha uma cor"
      value={color}
      onChange={(e) => setColor(e.target.value)}
    />
  );
}
```

Veja a story do componente no Storybook para demonstrações completas:

[Storybook — ColorInput](https://rharuow.github.io/rharuow-ds-docs/?path=/story/components-colorinput--default)

---
```

---

## 🎨 Customização de Tema

O rharuow-ds utiliza um **sistema de cores inteligente** que permite personalizar todo o design system definindo apenas **duas cores**: primária e secundária. Todas as variações (hover, light, dark) e cores de texto com contraste adequado são **calculadas automaticamente**.

> ⚡ **NOVO**: Sistema de Cálculo Automático de Cores! Veja a [documentação completa](AUTO_COLOR_SYSTEM.md) para detalhes.

### ✨ Modo Simplificado (Recomendado)

**Defina apenas 2 variáveis** e o sistema calcula automaticamente todas as variações:

```css
/* Importar o DS primeiro */
@import 'rharuow-ds/dist/styles.css';

/* Defina APENAS as cores base - o resto é automático! */
:root {
  --primary: #8b5cf6;    /* Roxo */
  --secondary: #ec4899;  /* Rosa */
}

/* Para dark mode */
[data-theme="dark"] {
  --primary: #a78bfa;    /* Versão mais clara para melhor contraste */
  --secondary: #f472b6;
}
```

O sistema automaticamente gera:
- ✅ `--primary-hover`, `--primary-light`, `--primary-dark`, `--primary-text`
- ✅ `--secondary-hover`, `--secondary-light`, `--secondary-dark`, `--secondary-text`
- ✅ Contraste adequado para textos (WCAG AA compliance)
- ✅ Ajustes automáticos para dark mode

### 💻 Uso com JavaScript/TypeScript

Para aplicações que precisam mudar cores dinamicamente:

```typescript
import { applyThemeColors } from 'rharuow-ds/lib/color.utils';
import 'rharuow-ds/dist/styles.css';

function App() {
  useEffect(() => {
    // Aplica cores e calcula automaticamente todas as variações
    applyThemeColors('#8b5cf6', '#ec4899');
  }, []);
  
  return <div>...</div>;
}
```

### 🎨 Funções Utilitárias

O DS exporta várias funções para cálculos de cor:

```typescript
import {
  generateColorPalette,    // Gera paleta completa de uma cor
  getContrastingTextColor, // Retorna branco ou preto com melhor contraste
  isLightColor,            // Verifica se uma cor é clara ou escura
  lightenColor,            // Clareia uma cor em X%
  darkenColor,             // Escurece uma cor em X%
  hexToRgb,                // Converte HEX para RGB
  getLuminance,            // Calcula luminância relativa
  getContrastRatio         // Calcula razão de contraste (WCAG)
} from 'rharuow-ds/lib/color.utils';

// Exemplo: Gerar paleta completa
const palette = generateColorPalette('#8b5cf6');
/*
{
  base: '#8b5cf6',
  hover: '#7c3aed',
  light: '#ede9fe',
  dark: '#6d28d9',
  text: '#ffffff',
  textOnLight: '#1f2937'
}
*/
```

### 🌈 Sistema de Cores

#### Como os Componentes Usam as Cores

Os componentes **derivam automaticamente** suas cores das variáveis primárias:

- **Card Header**: Mescla 5% da cor primária com fundo neutro
- **Table Header**: Mescla 8% da cor primária com fundo neutro
- **Table Hover**: Mescla 10% da cor primária com fundo neutro
- **Select Selected**: Usa diretamente `--primary-light`
- **Button/Modal**: Usam cores primária/secundária com texto de alto contraste
- **Elementos Selecionados**: Consistentemente usam a cor primária clara

### 💡 Modo Avançado (Controle Total)

Se você precisa de controle total sobre cada variação:

```css
:root {
  /* Defina todas as variações manualmente */
  --primary: #8b5cf6;
  --primary-hover: #7c3aed;
  --primary-light: #ede9fe;
  --primary-dark: #6d28d9;
  --primary-text: #ffffff;
  
  --secondary: #ec4899;
  --secondary-hover: #db2777;
  --secondary-light: #fce7f3;
  --secondary-dark: #be185d;
  --secondary-text: #ffffff;
}
```

### 📖 Documentação Completa

- **[AUTO_COLOR_SYSTEM.md](AUTO_COLOR_SYSTEM.md)** - Guia completo do sistema de cores automático
- **[THEME_CUSTOMIZATION.md](THEME_CUSTOMIZATION.md)** - Customização detalhada de tema

#### Método 2: JavaScript/React

```typescript
// App.tsx ou main.tsx
useEffect(() => {
  const root = document.documentElement;
  
  root.style.setProperty('--primary', '#f59e0b');
  root.style.setProperty('--primary-hover', '#d97706');
  root.style.setProperty('--primary-light', '#fef3c7');
}, []);
```

### 🎯 Exemplos de Paletas

```css
/* Paleta Corporativa (Azul) */
:root {
  --primary: #0ea5e9;
  --primary-hover: #0284c7;
  --primary-light: #e0f2fe;
}

/* Paleta Moderna (Roxo/Rosa) */
:root {
  --primary: #8b5cf6;
  --primary-hover: #7c3aed;
  --primary-light: #ede9fe;
  --secondary: #ec4899;
}

/* Paleta Natureza (Verde) */
:root {
  --primary: #10b981;
  --primary-hover: #059669;
  --primary-light: #d1fae5;
}

/* Paleta Minimalista (Cinza) */
:root {
  --primary: #6b7280;
  --primary-hover: #4b5563;
  --primary-light: #f3f4f6;
}
```

### 🔧 Customização Avançada

Para controle total, você pode sobrescrever variáveis específicas:

```css
:root {
  /* Cores base da marca */
  --primary: #8b5cf6;
  
  /* Customização específica de Card */
  --card-header-bg: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  --card-header-border: #8b5cf6;
  
  /* Customização específica de Table */
  --table-header-bg: #f3e8ff;
  --table-row-selected: #ede9fe;
}
```

### 📚 Variáveis Disponíveis por Componente

#### Card
- `--card-bg`, `--card-border`, `--card-text`
- `--card-header-bg`, `--card-header-border`
- `--card-footer-bg`, `--card-footer-border`

#### Table
- `--table-bg`, `--table-border`, `--table-text`
- `--table-header-bg`, `--table-row-hover`, `--table-row-selected`

#### Select/AsyncSelect/MultiSelect
- `--select-dropdown-bg`, `--select-dropdown-border`
- `--select-dropdown-hover`, `--select-dropdown-selected`

#### Tooltip
- `--tooltip-bg`, `--tooltip-text`

### 🌓 Dark Mode

O sistema ajusta automaticamente as cores no dark mode:

```css
/* Ative o dark mode adicionando o atributo */
<html data-theme="dark">
  <!-- ou -->
<html class="dark">
```

### No Storybook

Na [documentação do Storybook](https://rharuow.github.io/rharuow-ds-docs/), você pode testar diferentes temas na story **"Theme Customization"**.

Para mais detalhes, consulte [THEME_CUSTOMIZATION.md](./THEME_CUSTOMIZATION.md).

---

## 🛠️ Desenvolvimento

- ✅ Ícones customizados opcionais
- ✅ Três tamanhos: sm, md, lg
- ✅ Layout horizontal ou vertical
- ✅ Animações e estados visuais
- ✅ Label flutuante integrada

---

## Documentação

Acesse a documentação interativa dos componentes em [GitHub Pages](#) _(link será atualizado após o deploy)_.

---

## Desenvolvimento

Para contribuir ou rodar localmente:

```bash
git clone https://github.com/Rharuow/rharuow-ds-docs.git
cd rharuow-ds-docs
npm install
```

### Comandos disponíveis:

```bash
# Iniciar Storybook para desenvolvimento
npm run storybook

# Build dos componentes
npm run build

# Gerar CSS do Tailwind
npm run build:css

# Executar testes
npm test

# Build do Storybook para produção
npm run build-storybook
```

### Estrutura do projeto:

```
src/
├── components/          # Componentes React
│   ├── Button.tsx
│   ├── Input.tsx
│   ├── Select.tsx
│   ├── AsyncSelect.tsx
│   ├── MultiSelect.tsx
│   ├── types.ts        # Tipos compartilhados
│   └── index.ts        # Exportações
├── lib/
│   └── utils.ts        # Utilitários (cn, etc.)
├── stories/            # Stories do Storybook
└── styles/
    └── ds.css          # Estilos Tailwind
```

---

## Tecnologias

- ⚛️ **React 18** - Biblioteca base
- 📋 **React Hook Form** - Gerenciamento de formulários
- 🎨 **Tailwind CSS** - Estilização
- 📚 **Storybook** - Documentação interativa
- 📦 **Vite** - Build tool
- 🔷 **TypeScript** - Tipagem estática

---

Desenvolvido por Harysson.
