Knowledge Base · Referência visual
Design System do FIRO.
Fonte única de tokens e componentes reutilizáveis para tudo o que construímos - do backoffice ao frontoffice. Blade + Tailwind + Alpine, sem framework externo.
design.json
11 secções · componentes vivos
Zero dependências externas
Tokens
Extraídos automaticamente de design.json. Editar aí propaga para todas as utilities Tailwind.
Blue (primary)
50
100
200
300
400
500
600
700
800
900
950
Accent
50
100
200
300
400
500
600
700
800
900
950
Tipografia - Poppins
The quick brown fox jumps over the lazy dog
text-xs · 0.75remThe quick brown fox jumps over the lazy dog
text-sm · 0.875remThe quick brown fox jumps over the lazy dog
text-base · 1remThe quick brown fox jumps over the lazy dog
text-lg · 1.125remThe quick brown fox jumps over the lazy dog
text-xl · 1.25remThe quick brown fox jumps over the lazy dog
text-2xl · 1.5remBotões
<x-btn> - 7 variantes, 4 tamanhos, suporta href, loading e disabled.
<x-btn variant="primary" size="md">Marcar</x-btn>
<x-btn href="/foo" variant="outline">Ir para foo</x-btn>
<x-btn variant="danger" loading>A eliminar</x-btn>
Badges
<x-badge> - 8 variantes, com ou sem dot.
<x-badge variant="success" dot>Ativo</x-badge>
Alerts
<x-alert> - 4 variantes, opcionalmente com title e dismissible.
Nova versão disponível
Atenção
Erro no pagamento
<x-alert variant="warning" title="Atenção" dismissible>
A tua subscrição expira em 3 dias.
</x-alert>
Cards & Stat cards
<x-card> para contentores; <x-stat-card> para dashboards.
Card padrão
Conteúdo neutro.
Interactive
Hover shadow + cursor pointer.
Selected
Border azul + ring.
Marcações
248
Receita
€ 4.320
Clientes ativos
87
Cancelamentos
6
<x-stat-card label="Marcações" value="248" trend="+12%" trendDirection="up" />
Formulários
<x-form.field> agrega label + hint + erro. Primitivos com border-radius suave, focus ring de 4px, e ícones opcionais.
Inputs
Nome completo do cliente
Formato internacional
Este email já existe na base de dados.
Não podes alterar isto
Textarea & select nativo
Só visível para a equipa. Máx 500 caracteres.
Select com pesquisa Select2
Pesquisa em milhares de contactos
Podes escolher várias
<x-form.select2 name="customer_id" placeholder="Procurar cliente..." :options="$customers" />
<x-form.select2 name="tags[]" multiple :options="$tags" :value="$selected" />
Controlos booleanos & segmentados
Toggles
Checkboxes
Segmented control
<x-form.toggle name="notify" label="Enviar SMS" checked />
<x-form.segmented name="view" :options="['day' => 'Dia', 'week' => 'Semana']" value="week" />
Exemplo completo
Tabelas
<x-table> com subcomponentes head, body, row, cell.
| Cliente | Serviço | Total | Estado |
|---|---|---|---|
| Ana Silva | Corte | € 18,00 | Confirmada |
| João Costa | Massagem | € 45,00 | Pendente |
| Maria Rocha | Manicure | € 22,50 | Cancelada |
Dropdown
<x-dropdown> com slot trigger e <x-dropdown.item> no interior.
Tabs
<x-tabs> + <x-tab-panel>. Estado gerido por Alpine.
Painel de visão geral: KPIs e gráficos aparecem aqui.
Painel de definições: formulário de configuração.
Painel de logs: histórico de eventos.
Modal
Abre-se via evento global Alpine: $dispatch('open-modal', 'nome').
<x-btn x-data @click="$dispatch('open-modal', 'confirm')">Abrir</x-btn>
<x-modal name="confirm" title="Confirmar" maxWidth="lg">
Tens a certeza?
<x-slot:footer>
<x-btn variant="ghost" x-on:click="$dispatch('close-modal', 'confirm')">Cancelar</x-btn>
<x-btn variant="danger">Eliminar</x-btn>
</x-slot:footer>
</x-modal>
Como usar
Regras para manter o sistema consistente.
Do
- Reusar
<x-btn>para tudo que pareça botão ou link com aparência de botão. - Usar
<x-form.field>sempre que haja label + input. - Passar
variantsemântico em vez de hard-code de cores. - Editar
design.jsonpara introduzir novos tokens.
Don't
- Copiar classes Tailwind para reproduzir um botão à mão.
- Introduzir cores hex em blade views - se falta shade, adiciona ao JSON.
- Criar variantes num consumidor. Se precisas de nova variante, adiciona ao componente.
- Usar
!importantpara forçar estilos sobre um componente.
Adicionar um componente novo
resources/views/components/, declara props com @props, aceita {{ $attributes }}, documenta neste ficheiro e adiciona uma secção nesta página.