Pular para o conteúdo

5. Componentes

Este documento apresenta a biblioteca de componentes reutilizáveis para soluções web desenvolvidas com Astro 5, detalhando suas propriedades, uso e exemplos.

Visão Geral

Nossa biblioteca de componentes segue princípios de design atômico, organizando os componentes em uma hierarquia que facilita a composição e reutilização:

  1. Átomos: Componentes básicos e indivisíveis (botões, inputs, ícones)
  2. Moléculas: Combinações de átomos que formam unidades funcionais (formulários, cards)
  3. Organismos: Grupos complexos de moléculas que formam seções distintas (headers, footers)
  4. Templates: Arranjos de organismos que formam páginas
  5. Páginas: Instâncias específicas de templates com conteúdo real

Componentes UI (Átomos)

Button

O componente Button é usado para ações interativas.

---
// Uso:
import { Button } from '../components/ui/Button.astro';
---
<Button>Botão Padrão</Button>
<Button variant="secondary">Botão Secundário</Button>
<Button size="lg" disabled>Botão Grande Desabilitado</Button>

Props

PropTipoPadrãoDescrição
variantstring'primary'Variante visual ('primary', 'secondary', 'outline', 'ghost', 'danger')
sizestring'md'Tamanho do botão ('sm', 'md', 'lg', 'xl')
disabledbooleanfalseDefine se o botão está desabilitado
typestring'button'Tipo do botão ('button', 'submit', 'reset')
classstring''Classes CSS adicionais

Icon

O componente Icon renderiza ícones SVG.

---
// Uso:
import { Icon } from '../components/ui/Icon.astro';
---
<Icon name="check" class="w-5 h-5 text-green-500" />
<Icon name="arrow-right" class="w-4 h-4 ml-2" />

Props

PropTipoPadrãoDescrição
namestring-Nome do ícone (obrigatório)
classstring''Classes CSS adicionais

Badge

O componente Badge exibe informações de status ou categoria.

---
// Uso:
import { Badge } from '../components/ui/Badge.astro';
---
<Badge>Novo</Badge>
<Badge variant="success">Ativo</Badge>
<Badge variant="warning">Pendente</Badge>
<Badge variant="danger">Erro</Badge>
<Badge variant="info">Informação</Badge>

Props

PropTipoPadrãoDescrição
variantstring'default'Variante visual ('default', 'success', 'warning', 'danger', 'info')
classstring''Classes CSS adicionais

Avatar

O componente Avatar exibe uma imagem de perfil ou iniciais.

---
// Uso:
import { Avatar } from '../components/ui/Avatar.astro';
---
<Avatar src="/images/user.jpg" alt="Nome do Usuário" />
<Avatar initials="JD" />
<Avatar src="/images/user.jpg" alt="Nome do Usuário" size="lg" />

Props

PropTipoPadrãoDescrição
srcstring''URL da imagem
altstring''Texto alternativo para a imagem
initialsstring''Iniciais a serem exibidas quando não há imagem
sizestring'md'Tamanho do avatar ('sm', 'md', 'lg', 'xl')
classstring''Classes CSS adicionais

Componentes de Formulário

Input

O componente Input para entrada de texto.

---
// Uso:
import { Input } from '../components/ui/Input.astro';
---
<Input
id="email"
label="Email"
type="email"
placeholder="seu@email.com"
required
/>
<Input
id="username"
label="Nome de usuário"
error="Nome de usuário já está em uso"
/>
<Input
id="bio"
label="Biografia"
helpText="Uma breve descrição sobre você"
/>

Props

PropTipoPadrãoDescrição
idstring-ID único do input (obrigatório)
labelstring''Texto do label
typestring'text'Tipo do input ('text', 'email', 'password', etc.)
placeholderstring''Texto de placeholder
requiredbooleanfalseDefine se o campo é obrigatório
disabledbooleanfalseDefine se o campo está desabilitado
errorstring''Mensagem de erro
helpTextstring''Texto de ajuda
classstring''Classes CSS adicionais

Select

O componente Select para seleção de opções.

---
// Uso:
import { Select } from '../components/ui/Select.astro';
const options = [
{ value: 'option1', label: 'Opção 1' },
{ value: 'option2', label: 'Opção 2' },
{ value: 'option3', label: 'Opção 3' },
];
---
<Select
id="select-example"
label="Selecione uma opção"
options={options}
required
/>

Props

PropTipoPadrãoDescrição
idstring-ID único do select (obrigatório)
labelstring''Texto do label
optionsarray[]Array de objetos com value e label
requiredbooleanfalseDefine se o campo é obrigatório
disabledbooleanfalseDefine se o campo está desabilitado
errorstring''Mensagem de erro
helpTextstring''Texto de ajuda
classstring''Classes CSS adicionais

Checkbox

O componente Checkbox para seleção booleana.

---
// Uso:
import { Checkbox } from '../components/ui/Checkbox.astro';
---
<Checkbox
id="terms"
label="Eu aceito os termos e condições"
required
/>
<Checkbox
id="newsletter"
label="Inscrever-se na newsletter"
helpText="Você pode cancelar a qualquer momento"
/>

Props

PropTipoPadrãoDescrição
idstring-ID único do checkbox (obrigatório)
labelstring''Texto do label
checkedbooleanfalseEstado inicial do checkbox
requiredbooleanfalseDefine se o campo é obrigatório
disabledbooleanfalseDefine se o campo está desabilitado
errorstring''Mensagem de erro
helpTextstring''Texto de ajuda
classstring''Classes CSS adicionais

Componentes de Layout (Moléculas)

Card

O componente Card para agrupar conteúdo relacionado.

---
// Uso:
import { Card } from '../components/ui/Card.astro';
---
<Card>
<h3 class="text-xl font-semibold mb-2">Título do Card</h3>
<p>Conteúdo do card com texto informativo.</p>
</Card>
<Card padding="large" shadow="lg" border={true} hover={true}>
<h3 class="text-xl font-semibold mb-2">Card com Opções</h3>
<p>Card com padding grande, sombra grande, borda e efeito hover.</p>
</Card>

Props

PropTipoPadrãoDescrição
paddingstring'normal'Espaçamento interno ('none', 'small', 'normal', 'large')
shadowstring'md'Tamanho da sombra ('none', 'sm', 'md', 'lg')
borderbooleanfalseDefine se o card tem borda
hoverbooleanfalseDefine se o card tem efeito hover
classstring''Classes CSS adicionais

Alert

O componente Alert para mensagens de feedback.

---
// Uso:
import { Alert } from '../components/ui/Alert.astro';
---
<Alert>Informação importante</Alert>
<Alert variant="success">Operação realizada com sucesso!</Alert>
<Alert variant="warning">Atenção: esta ação não pode ser desfeita.</Alert>
<Alert variant="danger">Erro: não foi possível completar a operação.</Alert>
<Alert variant="info" dismissible>Esta é uma mensagem informativa que pode ser fechada.</Alert>

Props

PropTipoPadrãoDescrição
variantstring'default'Variante visual ('default', 'success', 'warning', 'danger', 'info')
dismissiblebooleanfalseDefine se o alerta pode ser fechado
classstring''Classes CSS adicionais

Tabs

O componente Tabs para organizar conteúdo em abas.

---
// Uso:
import { Tabs, TabItem } from '../components/ui/Tabs.astro';
---
<Tabs>
<TabItem label="Aba 1" active>
<p>Conteúdo da primeira aba.</p>
</TabItem>
<TabItem label="Aba 2">
<p>Conteúdo da segunda aba.</p>
</TabItem>
<TabItem label="Aba 3">
<p>Conteúdo da terceira aba.</p>
</TabItem>
</Tabs>

Props (Tabs)

PropTipoPadrãoDescrição
classstring''Classes CSS adicionais

Props (TabItem)

PropTipoPadrãoDescrição
labelstring-Texto do label da aba (obrigatório)
activebooleanfalseDefine se a aba está ativa inicialmente
classstring''Classes CSS adicionais

Componentes de Navegação

O componente Breadcrumbs para navegação hierárquica.

---
// Uso:
import { Breadcrumbs } from '../components/navigation/Breadcrumbs.astro';
const items = [
{ label: 'Home', href: '/' },
{ label: 'Produtos', href: '/produtos' },
{ label: 'Categoria', href: '/produtos/categoria' },
{ label: 'Produto Atual', href: null },
];
---
<Breadcrumbs items={items} />

Props

PropTipoPadrãoDescrição
itemsarray[]Array de objetos com label e href
classstring''Classes CSS adicionais

Pagination

O componente Pagination para navegação entre páginas.

---
// Uso:
import { Pagination } from '../components/navigation/Pagination.astro';
---
<Pagination
currentPage={3}
totalPages={10}
baseUrl="/blog/page/"
/>

Props

PropTipoPadrãoDescrição
currentPagenumber1Página atual
totalPagesnumber-Número total de páginas (obrigatório)
baseUrlstring''URL base para links de paginação
showFirstLastbooleantrueMostra botões para primeira/última página
classstring''Classes CSS adicionais

Componentes de Layout (Organismos)

O componente Header para o cabeçalho do site.

---
// Uso:
import { Header } from '../components/layout/Header.astro';
const navItems = [
{ label: 'Home', href: '/' },
{ label: 'Sobre', href: '/sobre' },
{ label: 'Serviços', href: '/servicos' },
{ label: 'Blog', href: '/blog' },
{ label: 'Contato', href: '/contato' },
];
---
<Header
logoSrc="/images/logo.svg"
logoAlt="Nome da Empresa"
navItems={navItems}
/>

Props

PropTipoPadrãoDescrição
logoSrcstring-URL da imagem do logo
logoAltstring''Texto alternativo para o logo
navItemsarray[]Array de objetos com label e href
stickybooleanfalseDefine se o header é fixo no topo
classstring''Classes CSS adicionais

O componente Footer para o rodapé do site.

---
// Uso:
import { Footer } from '../components/layout/Footer.astro';
const columns = [
{
title: 'Empresa',
links: [
{ label: 'Sobre', href: '/sobre' },
{ label: 'Equipe', href: '/equipe' },
{ label: 'Carreiras', href: '/carreiras' },
],
},
{
title: 'Recursos',
links: [
{ label: 'Blog', href: '/blog' },
{ label: 'Documentação', href: '/docs' },
{ label: 'Tutoriais', href: '/tutoriais' },
],
},
{
title: 'Legal',
links: [
{ label: 'Termos', href: '/termos' },
{ label: 'Privacidade', href: '/privacidade' },
],
},
];
const socialLinks = [
{ platform: 'twitter', href: 'https://twitter.com/empresa' },
{ platform: 'github', href: 'https://github.com/empresa' },
{ platform: 'linkedin', href: 'https://linkedin.com/empresa' },
];
---
<Footer
columns={columns}
socialLinks={socialLinks}
copyright="© 2025 Nome da Empresa. Todos os direitos reservados."
/>

Props

PropTipoPadrãoDescrição
columnsarray[]Array de objetos com title e links
socialLinksarray[]Array de objetos com platform e href
copyrightstring''Texto de copyright
classstring''Classes CSS adicionais

Padrões de Composição de Componentes

Composição Básica

Combine componentes para criar interfaces complexas:

---
import BaseLayout from '../layouts/BaseLayout.astro';
import { Container } from '../components/layout/Container.astro';
import { Card } from '../components/ui/Card.astro';
import { Button } from '../components/ui/Button.astro';
import { Icon } from '../components/ui/Icon.astro';
---
<BaseLayout title="Página de Exemplo">
<Container>
<h1 class="text-3xl font-bold mb-6">Título da Página</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Card>
<div class="flex items-center mb-4">
<Icon name="star" class="w-6 h-6 text-yellow-500 mr-2" />
<h2 class="text-xl font-semibold">Recurso 1</h2>
</div>
<p class="mb-4">Descrição do recurso com detalhes importantes.</p>
<Button variant="primary">Saiba mais</Button>
</Card>
<!-- Mais cards... -->
</div>
</Container>
</BaseLayout>

Padrão de Slots

Use slots para injetar conteúdo em componentes:

components/ui/Panel.astro
---
const { title } = Astro.props;
---
<div class="border rounded-lg overflow-hidden">
<div class="bg-gray-100 px-4 py-3 border-b">
<h3 class="font-medium">{title}</h3>
<slot name="header-actions" />
</div>
<div class="p-4">
<slot />
</div>
<div class="bg-gray-50 px-4 py-3 border-t">
<slot name="footer" />
</div>
</div>
---
// Uso:
import { Panel } from '../components/ui/Panel.astro';
import { Button } from '../components/ui/Button.astro';
---
<Panel title="Configurações da Conta">
<div slot="header-actions">
<Button variant="ghost" size="sm">Editar</Button>
</div>
<p>Conteúdo principal do painel.</p>
<p>Mais conteúdo...</p>
<div slot="footer" class="flex justify-end">
<Button variant="secondary" class="mr-2">Cancelar</Button>
<Button variant="primary">Salvar</Button>
</div>
</Panel>

Padrão de Composição

Crie componentes que aceitam outros componentes como props:

components/layout/TwoColumnLayout.astro
---
const {
sidebarWidth = '1/3',
reversed = false,
class: className,
...props
} = Astro.props;
const sidebarClasses = {
'1/4': 'lg:w-1/4',
'1/3': 'lg:w-1/3',
'1/2': 'lg:w-1/2',
};
const containerClass = `flex flex-col ${reversed ? 'lg:flex-row-reverse' : 'lg:flex-row'} ${className || ''}`;
const sidebarClass = `w-full ${sidebarClasses[sidebarWidth]} mb-6 lg:mb-0`;
const mainClass = `w-full ${reversed ? 'lg:pr-6' : 'lg:pl-6'}`;
---
<div class={containerClass} {...props}>
<div class={sidebarClass}>
<slot name="sidebar" />
</div>
<div class={mainClass}>
<slot name="main" />
</div>
</div>
---
// Uso:
import { TwoColumnLayout } from '../components/layout/TwoColumnLayout.astro';
import { Card } from '../components/ui/Card.astro';
---
<TwoColumnLayout sidebarWidth="1/3">
<Card slot="sidebar">
<h2 class="text-xl font-semibold mb-4">Filtros</h2>
<!-- Conteúdo da sidebar -->
</Card>
<div slot="main">
<h1 class="text-3xl font-bold mb-6">Produtos</h1>
<!-- Conteúdo principal -->
</div>
</TwoColumnLayout>

Documentação de Componentes

Para cada componente em sua biblioteca, mantenha uma documentação detalhada:

  1. Descrição: Explique o propósito e casos de uso do componente
  2. Props: Liste todas as props com tipos, valores padrão e descrições
  3. Slots: Documente slots disponíveis e seu propósito
  4. Exemplos: Forneça exemplos de uso em diferentes contextos
  5. Acessibilidade: Descreva considerações de acessibilidade
  6. Variações: Mostre diferentes variações do componente

Conclusão

Esta biblioteca de componentes fornece os blocos de construção necessários para criar interfaces consistentes e de alta qualidade. À medida que o projeto evolui, novos componentes podem ser adicionados seguindo os mesmos padrões de design e documentação.

Os próximos documentos detalharão outros aspectos do desenvolvimento:


Última atualização: 21 de março de 2025