npm package: @g4-educacao/g4-apollo-design-system
Description: Design System da organização **G4 Educação**, construído com React, Vite, Tailwind CSS, ShadCN, Radix UI e tokens CSS personalizados.
Latest version: 1.19.0

# G4 Apollo Design System

Design System da organização **G4 Educação**, construído com React, Vite, Tailwind CSS, ShadCN, Radix UI e tokens CSS personalizados.

> ✨ Totalmente modular com suporte a Atomic Design e distribuição via NPM.

---

## 📦 Instalação

### 1. Via NPM (produção ou consumo externo)

```bash
pnpm add @g4-educacao/g4-apollo-design-system@develop
# ou
npm install @g4-educacao/g4-apollo-design-system@develop
```

> 💡 **Importando componentes e CSS**

Após instalar o pacote, importe os componentes que desejar e o CSS global do Design System no seu projeto consumidor:

```tsx
import {
    Badge,
    BreadcrumbBuilder,
    Button,
    Checkbox,
    DropdownMenu,
    DropdownMenuContent,
    Icon,
    SearchBar,
    Switch,
    TextArea,
} from '@g4-educacao/g4-apollo-design-system';
import '@g4-educacao/g4-apollo-design-system/css';
```

### 2. Desenvolvimento local via `npm link`

Caso deseje contribuir com o design system e testá-lo em um projeto local:

```bash
# Dentro da pasta do design system
pnpm install
pnpm build
pnpm link

# Em outro projeto que irá consumir o design system
pnpm link @g4-educacao/g4-apollo-design-system
```

> ⚠️ Após alterações no design system, sempre rode `pnpm build` novamente para refletir as mudanças no projeto consumidor.

---

## 💡 Criação de Componentes

### 🤖 Criação Automática (recomendado)

Para criar novos componentes de forma automatizada, use os scripts baseados no ShadCN:

```bash
pnpm add:atom nome-do-componente
pnpm add:molecule nome-do-componente
pnpm add:organism nome-do-componente
pnpm add:template nome-do-componente
```

**O que o script faz automaticamente:**

1. Cria a pasta `src/components/{tipo}/{nome}/`
2. Gera o arquivo `{nome}.tsx` com template baseado no ShadCN
3. Adiciona a exportação no `index.ts` correspondente

**Exemplo:**

```bash
pnpm add:molecule button
```

Irá criar:

- Pasta: `src/components/molecules/button/`
- Arquivo: `button.tsx`
- Export em: `src/components/molecules/index.ts` → `export * from './button/button';`

### 🔧 Criação Manual

Para componentes que não fazem parte do acervo do ShadCN ou customizações específicas:

1. **Criar a estrutura de pastas**

    ```
    src/components/{atoms|molecules|organisms|templates}/{nome-componente}/
    ```

2. **Criar o arquivo do componente**

    ```
    src/components/{tipo}/{nome-componente}/{nome-componente}.tsx
    ```

3. **Exportação automática**
   ⚠️ **Não se preocupe com exports manuais!** O script `generate-exports` é executado automaticamente no build e recria todos os `index.ts`, garantindo que seu componente seja exportável.

### 📁 Estruturas de Exportação Suportadas

O sistema de exportação automática suporta dois padrões:

**Padrão 1: Componente único**

```
src/components/atoms/button/
├── button.tsx          # Componente principal
└── button.css          # CSS opcional
```

→ Gera: `export * from './button/button';`

**Padrão 2: Múltiplos componentes (com index.ts)**

```
src/components/organisms/sidenav/
├── index.ts            # Exporta múltiplos componentes
├── sidenavHeader.tsx
├── sidenavContent.tsx
└── sidenavFooter.tsx
```

→ Gera: `export * from './sidenav/index';`

### 🎨 Arquivos CSS

Para componentes que precisam de estilos CSS separados:

1. **Criar o arquivo CSS**

    ```
    src/components/{tipo}/{nome-componente}/{nome-componente}.css
    ```

2. **Importar no CSS global**
   Adicione a importação em `src/index.css`:
    ```css
    @import './components/molecules/button/button.css';
    ```

> ⚠️ **Importante**: A importação do CSS deve ser feita manualmente no `src/index.css` para que os estilos sejam incluídos no build final.

---

## 💡 Scripts úteis

### 🎨 Criar novo ícone SVG automaticamente

```bash
pnpm create:icon nome-do-icone
```

Gera o componente no padrão e registra no `iconsMap.ts`.
Exemplo:
ao rodar o comando `pnpm create:icon novo-icone`, irá gerar o arquivo `NovoIcone.tsx` em `src/componentes/atoms/icon/icons`,
com a seguinte estrutura:

```
import { SvgWrapper } from '@/components/atoms/icon/svgWrapper';
import { IconProps } from '@/components/atoms/icon/iconsMap';

export const NovoIcone = ({ size, className, color = 'var(--color-icon-g400)' }: IconProps) => (
  <SvgWrapper size={size} className={className}>
    {/* Cole aqui o <path> do SVG */}
  </SvgWrapper>
);
```

Basta atualizar o arquivo com o `<path>` do svg e atualizar os imports do arquivo `iconsMap.tsx` para enxergar o novo componente.
Além disso, é interessante alterar o valor da propriedade `fill` do `<path>` para `color`, para que o ícone assuma a cor informada na propriedade.
Pronto, o Design System está pronto para enxergar o novo ícone.

---

## 🤖 Scripts de Automação

### Scripts de Tokens CSS

O projeto possui um sistema automatizado de geração de tokens CSS que é executado antes de cada build:

#### `pnpm generate-colors-map`

- **Quando é executado**: Automaticamente no `prebuild`
- **O que faz**: Lê todos os arquivos CSS da pasta `src/tokens/colors/` e extrai as variáveis CSS definidas com `--color-*`
- **Resultado**: Gera o arquivo `src/tokens/colors/colorsMap.ts` com um mapeamento das cores disponíveis
- **Exemplo**: `--color-blue-500` vira `{ blue: ['500'] }`

#### `pnpm generate-colors-type`

- **Quando é executado**: Automaticamente no `prebuild` (após `generate-colors-map`)
- **O que faz**: Usa o `colorsMap.ts` para gerar tipos TypeScript das cores
- **Resultado**: Gera o arquivo `src/tokens/colors/colorsType.ts` com union types das cores disponíveis
- **Exemplo**: `type ColorsType = 'blue-500' | 'red-200' | 'green-800'`

#### `pnpm generate-colors-array`

- **Quando é executado**: Automaticamente no `prebuild` (após `generate-colors-type`)
- **O que faz**: Converte o tipo `ColorsType` em um array utilizável em runtime
- **Resultado**: Gera o arquivo `src/tokens/colors/colorsArray.ts`
- **Uso**: Útil para componentes que precisam listar as cores disponíveis (ex: Storybook controls)

#### `pnpm generate-classes`

- **Quando é executado**: Automaticamente no `prebuild` (após todos os scripts de cores)
- **O que faz**: Gera classes CSS dinâmicas do Tailwind baseadas nas cores do `colorsMap`
- **Resultado**: Cria o arquivo `src/generatedClasses.css` com classes como `bg-blue-500`, `text-red-300`, etc.
- **Por que é necessário**: Garante que as classes dinâmicas sejam incluídas no build final do CSS, permitindo que projetos consumidores usem as cores do design system

### Scripts de Desenvolvimento

#### `pnpm add:atom|molecule|organism|template <nome>`

- **Quando usar**: Durante desenvolvimento de novos componentes
- **O que faz**: Cria automaticamente a estrutura de pastas e arquivos para um novo componente baseado em ShadCN
- **Resultado**:
    - Cria pasta `src/components/{tipo}/{nome}/`
    - Gera arquivo `{nome}.tsx` com template base
    - Adiciona export no `index.ts` correspondente

#### `pnpm generate-exports`

- **Quando é executado**: Automaticamente no `prebuild` (após geração de classes)
- **O que faz**: Recria todos os arquivos `index.ts` das pastas de componentes (atoms, molecules, organisms, templates)
- **Como funciona**:
    - **Prioridade 1**: Se existe `index.ts/tsx` na pasta do componente → `export * from './componente/index';`
    - **Prioridade 2**: Se não, procura arquivo principal → `export * from './componente/componente';`
- **Por que é importante**: Garante que todos os componentes sejam exportáveis, mesmo quando esquecemos de adicionar manualmente

#### `pnpm create:icon <nome-do-icone>`

- **Quando usar**: Para adicionar novos ícones SVG ao design system
- **O que faz**: Cria automaticamente o componente de ícone e registra no mapa de ícones
- **Resultado**:
    - Gera arquivo `src/components/atoms/icon/icons/{Nome}.tsx`
    - Atualiza `iconsMap.tsx` com o novo ícone

### Scripts de Build e Publicação

#### `prebuild`

- **Quando é executado**: Automaticamente antes de qualquer build
- **O que faz**: Executa sequencialmente todos os scripts de geração de tokens
- **Sequência**: `generate-colors-map` → `generate-colors-type` → `generate-colors-array` → `generate-classes`

#### `build:css`

- **Quando é executado**: Automaticamente no `postbuild`
- **O que faz**: Compila o CSS final usando PostCSS e Tailwind
- **Resultado**: Gera `dist/index.css` com todos os estilos do design system

#### `pnpm release` / `pnpm release:dev`

- **Quando usar**: Para publicar novas versões do design system
- **O que faz**: Processo interativo de versionamento semântico e publicação no NPM
- **Opções**: Permite escolher tipo de versão (patch/minor/major) e tag (develop/master)

> 💡 **Importante**: Todos os scripts de geração de tokens são executados automaticamente no `prebuild`, garantindo que os tokens estejam sempre atualizados antes de qualquer build ou publicação.

---

## 🎨 Adicionando Novos Tokens de Cor

### Como adicionar uma nova cor ao Design System

Para adicionar novas cores ao design system, siga estes passos:

#### 1. Adicionar as variáveis CSS no arquivo de tokens

Edite o arquivo `src/tokens/colors/index.css` e adicione suas novas cores seguindo o padrão estabelecido:

```css
@layer base {
    :root {
        /* SUA NOVA COR */
        --color-minhacore-50: #f0f0f0;
        --color-minhacore-100: #e0e0e0;
        --color-minhacore-200: #d0d0d0;
        --color-minhacore-300: #c0c0c0;
        --color-minhacore-400: #b0b0b0;
        --color-minhacore-500: #a0a0a0;
        --color-minhacore-600: #909090;
        --color-minhacore-700: #808080;
    }
}
```

#### 2. Padrão de nomenclatura obrigatório

**Importante**: As variáveis CSS devem seguir exatamente o padrão `--color-NOME-VALOR` para serem reconhecidas pelos scripts de automação:

- ✅ `--color-blue-500` → gera classes `bg-blue-500`, `text-blue-500`, etc.
- ✅ `--color-primary-dark` → gera classes `bg-primary-dark`, `text-primary-dark`, etc.
- ✅ `--color-neutral` → gera classes `bg-neutral`, `text-neutral`, etc. (sem valor numérico)
- ❌ `--blue-500` → **não será reconhecido** (falta o prefixo `color`)
- ❌ `--color_blue_500` → **não será reconhecido** (usa underscore em vez de hífen)

#### 3. Processo automático no build

Quando você executar `pnpm build`, o sistema automaticamente:

1. **Extrai as cores**: O script `generate-colors-map` lê o arquivo `src/tokens/colors/index.css` e extrai todas as variáveis que seguem o padrão `--color-*`

2. **Gera tipos TypeScript**: Cria automaticamente os tipos `ColorsType` e arrays de cores para uso em componentes

3. **Gera classes Tailwind**: Cria o arquivo `src/generatedClasses.css` com todas as classes dinâmicas:

    ```css
    /* Gerado automaticamente */
    .bg-minhacore-500 {
        background-color: var(--color-minhacore-500);
    }
    .text-minhacore-500 {
        color: var(--color-minhacore-500);
    }
    .border-minhacore-500 {
        border-color: var(--color-minhacore-500);
    }
    /* ... e muitas outras variações */
    ```

4. **Inclui no CSS final**: As classes ficam disponíveis no `dist/index.css` para projetos consumidores

#### 4. Usando as novas cores

Após o build, suas cores estarão disponíveis tanto como:

**Variáveis CSS nativas**:

```css
.meu-componente {
    background-color: var(--color-minhacore-500);
}
```

**Classes Tailwind dinâmicas**:

```tsx
<div className="bg-minhacore-500 text-minhacore-100">Meu conteúdo</div>
```

**Em componentes do design system**:

```tsx
<Icon name="heart" color="minhacore-500" />
<Button variant="filled" className="bg-minhacore-500" />
```

> 💡 **Dica**: Depois de adicionar novas cores, rode `pnpm build` para regenerar todos os arquivos automaticamente e testar suas cores no Storybook com `pnpm storybook`.

---

## 🔧 Guia Completo: Criação de Componentes

### Estrutura de Componentes no Design System

O design system segue o padrão **Atomic Design** com a seguinte hierarquia:

```
src/components/
├── atoms/          # Componentes básicos (Button, Icon, Badge)
├── molecules/      # Combinação de atoms (SearchBar, ProductCard)
├── organisms/      # Seções complexas (Header, SideNav)
└── templates/      # Layouts de páginas
```

### Tipos de Estrutura de Componentes

#### 1. **Componente Simples** (mais comum)

```
src/components/atoms/button/
├── button.tsx           # Componente principal
├── button.css           # Estilos (opcional)
├── button.stories.tsx   # Documentação Storybook
└── test/
    └── button.test.tsx  # Testes unitários
```

**Export gerado**: `export * from './button/button';`

#### 2. **Componente Complexo** (como sidenav)

```
src/components/organisms/sidenav/
├── index.ts             # Exporta todos os sub-componentes
├── sidenav.tsx          # Componente principal
├── sidenavItem.tsx      # Sub-componente
├── sidenavGroup.tsx     # Sub-componente
├── sidenavSection.tsx   # Sub-componente
├── sidenav.css          # Estilos
├── sidenav.stories.tsx  # Documentação
└── test/                # Testes de todos os componentes
    ├── sidenav.test.tsx
    ├── sidenavItem.test.tsx
    └── ...
```

**Export gerado**: `export * from './sidenav/index';` (prioriza o index.ts)

### Fluxo de Criação de Componentes

#### Método 1: Automático (Recomendado)

```bash
# Para componentes baseados em ShadCN
pnpm add:atom nome-do-componente
pnpm add:molecule nome-do-componente
pnpm add:organism nome-do-componente
pnpm add:template nome-do-componente
```

**O que acontece automaticamente:**

1. ✅ Cria a pasta `src/components/{tipo}/{nome}/`
2. ✅ Gera o arquivo `{nome}.tsx` com template ShadCN
3. ✅ Adiciona o export no `index.ts` correspondente
4. ✅ Estrutura pronta para desenvolvimento

#### Método 2: Manual

1. **Criar estrutura de pastas**

    ```bash
    mkdir -p src/components/atoms/meucomponente
    ```

2. **Criar arquivo principal**

    ```tsx
    // src/components/atoms/meucomponente/meucomponente.tsx
    import { type ComponentProps } from 'react';
    import { cn } from '@/lib/utils';

    interface MeuComponenteProps extends ComponentProps<'div'> {
        // suas props aqui
    }

    export const MeuComponente = ({ className, ...props }: MeuComponenteProps) => {
        return (
            <div
                className={cn('base-classes', className)}
                data-testid="meu-componente"
                {...props}
            />
        );
    };
    ```

3. **Não se preocupe com exports!**
   O script `generate-exports` roda automaticamente no `prebuild` e detectará seu componente.

### Sistema de Exportação Automática

#### Como o `generate-exports` funciona:

```javascript
// Para cada pasta de componente, verifica na ordem:

1. 🔍 Existe index.ts/tsx?
   → export * from './componente/index';

2. 🔍 Existe componente.tsx/ts?
   → export * from './componente/componente';

3. ❌ Nada encontrado
   → Componente não será exportado
```

#### Exemplos práticos:

```typescript
// src/components/atoms/index.ts (gerado automaticamente)
export * from './badge/badge'; // Componente simples
export * from './icon/icon'; // Componente simples
export * from './productIcon/productIcon'; // Componente simples

// src/components/organisms/index.ts (gerado automaticamente)
export * from './header/header'; // Componente simples
export * from './sidenav/index'; // Componente complexo (tem index.ts próprio)
```

### Boas Práticas

#### ✅ Recomendações:

1. **Use o script automático** quando possível
2. **Sempre inclua `data-testid`** para facilitar testes
3. **Siga a convenção de nomenclatura**: pasta e arquivo principal com mesmo nome
4. **Para componentes complexos**: crie um `index.ts` próprio exportando sub-componentes
5. **CSS separado**: apenas para componentes complexos que precisam

#### ❌ Evite:

1. **Não se preocupe em adicionar exports manualmente** - o sistema faz isso automaticamente
2. **Não use nomes diferentes** entre pasta e arquivo principal
3. **Não esqueça do `data-testid`** - essencial para testes

### Quando o componente é exportável?

O sistema detecta automaticamente um componente como exportável quando:

- ✅ Existe `{nome}/{nome}.tsx` ou `{nome}/{nome}.ts`
- ✅ **OU** existe `{nome}/index.ts` ou `{nome}/index.tsx`

### Fluxo completo no build:

```mermaid
prebuild → generate-exports → build → todos os componentes exportados automaticamente
```

Quando você roda `pnpm build`, o sistema:

1. 🔄 Recria todos os `index.ts` das pastas de componentes
2. 🔄 Detecta novos componentes automaticamente
3. ✅ Garante que tudo seja exportável no pacote final

> 💡 **Dica**: Crie seus componentes e não se preocupe com exports - o sistema cuida disso automaticamente no build!

---

## 🧠 Tecnologias usadas

- React 19
- TypeScript
- Tailwind CSS 4
- ShadCN + Radix UI
- Class Variance Authority (`cva`)
- CSS tokens com `@theme` e `:root`
- Storybook
- Vitest

---

## 📮 Contato

Projeto mantido por G4 Educação.
Dúvidas ou sugestões? Entre em contato com o time de tecnologia interno.