Skills
Frontend

React

Convenções de componente React 18 — estrutura de pasta, export, props tipadas — independente da biblioteca de estilo (SCSS Modules ou Tailwind). Invoque ao criar ou revisar qualquer componente React.

React

Convenções de componente que valem qualquer que seja a lib de estilo. Estilização em si mora em frontend/scss-bem ou frontend/tailwind, conforme o archetype do projeto.

Referência

Arquivo Conteúdo
reference/components.md Estrutura de componente, export, props tipadas
reference/folder-structure.md Estrutura de src/, regra de colocação e promoção

Regras inegociáveis

  • Export nomeado, não default, para componentes não-page. Páginas roteadas (src/pages/) podem seguir export default, que é o que roteadores com lazy-loading esperam.
  • Props tipadas com interface, nunca type inline anônimo.
  • Sem inline styles (style={{}}) — a classe/token vem da lib de estilo do projeto. Exceção: valor verdadeiramente dinâmico que não dá pra expressar em classe (ex. progresso calculado).
  • Componente sobe para src/components/ só quando há 2+ usos reais.
  • Componente .tsx é só estrutura — tipo de dado externo (form, resposta de API, params de URL) vem de um schema zod (frontend/react-hook-form-zod), nunca interface/type solto no .tsx.

Skills relacionadas

  • Tipagem: frontend/typescript
  • Build tool, aliases, env vars: frontend/vite
  • Estilo: frontend/scss-bem ou frontend/tailwind
  • Componentes gerados via CLI (shadcn/ui): frontend/shadcn-ui
  • Forms: frontend/react-hook-form-zod
  • Testes: frontend/vitest-testing-library, frontend/playwright-e2e

Documentos de referência

Componentes

fonte ↗

Componentes

Referência de frontend/react. Volte ao índice para o quando-invocar.

  • Uma pasta por componente (.tsx + arquivo de estilo do projeto + .test.tsx) quando o componente tem estilo próprio em arquivo separado (frontend/scss-bem); um arquivo solto quando o estilo é só classe utilitária (frontend/tailwind — ver aquela skill).
  • Export nomeado, não default, para componentes não-page.
  • Props tipadas com interface, nunca com type inline anônimo.
  • Nunca use inline styles (style={{}}).
// Button/Button.tsx
interface ButtonProps {
  label: string;
  variant?: 'primary' | 'secondary';
  onClick: () => void;
}

export function Button({ label, variant = 'primary', onClick }: ButtonProps) {
  return (
    <button className={/* classe vem da lib de estilo do projeto — ver frontend/scss-bem ou frontend/tailwind */ ''} onClick={onClick}>
      {label}
    </button>
  );
}

O arquivo de estilo em si (.module.scss + BEM, ou classes utilitárias Tailwind) segue a convenção do skill de estilo do archetype — frontend/scss-bem ou frontend/tailwind.

Export: se o código existente do projeto for inconsistente (mistura export const Foo = ... e export default Foo), prefira export nomeado para componentes novos que não são página/rota — é mais fácil de refatorar e evita o erro comum de importar { Foo } de um arquivo que só tem export default.

Estrutura de pastas

fonte ↗

Estrutura de pastas

Referência de frontend/react. Volte ao índice para o quando-invocar.

src/
├── assets/                   # imagens e fontes estáticas
├── components/               # componentes usados em 2+ lugares
│   └── Button/
├── pages/                    # uma pasta por rota / view
│   └── Dashboard/
├── forms/ (ou junto da page)  # um form = .tsx (estrutura) + .schema.ts (tipo + validação)
│   └── LoginForm/
├── hooks/                    # hooks reutilizados em 2+ lugares
├── lib/                      # funções utilitárias e acesso a API
│   └── __tests__/
├── schemas/                  # schemas zod usados em 2+ lugares
└── types/
    └── index.ts

O arquivo/pasta de estilo global (styles/ ou index.css) segue a convenção do skill de estilo do projeto (frontend/scss-bem ou frontend/tailwind) — não é parte deste layout genérico.

Regra de colocação

Asset 1 lugar 2+ lugares
Componente dentro da própria pasta de página src/components/
Schema zod (+ tipo de dado externo) <Form>.schema.ts junto do form (nunca inline no .tsx, mesmo com um único form — ver frontend/react-hook-form-zod) src/schemas/
Mock de teste mesma pasta do teste src/mocks/
Tipo (não derivado de schema) mesmo arquivo ou types.ts local src/types/index.ts
Função utilitária inline ou utils.ts local src/lib/

Não crie pasta compartilhada preventivamente — promova quando o reuso acontecer de verdade.

Regra de promoção de schema zod

Assim que um schema zod passa a ser usado em 2+ lugares, ele vira global — nunca duplicado/copiado-colado entre arquivos (isso é o mesmo valor de validação virando hardcoded em dois lugares que podem divergir):

  • Schema de formulário (RHF) reutilizado por 2+ forms → src/schemas/ (ver frontend/react-hook-form-zod).
  • Schema de validação de resposta de API (não ligado a um form — ex.: UserSchema.parse(raw) de frontend/typescript) reutilizado por 2+ chamadas → src/lib/, junto do client/função que faz a chamada.

Em ambos os casos, o arquivo original passa a importar do destino global — nunca mantenha as duas cópias.