Componentes reutilizaveis com dark mode. Cada secao mostra o componente ao vivo + codigo Blade para copiar.
Este site que voce esta vendo e a documentacao ao vivo: todos os exemplos abaixo podem ser consultados aqui mesmo. Para usar no Laravel, baixe o repositorio e coloque os arquivos no lugar certo.
git clone https://github.com/pvitorv/kit-components.git
components (que esta dentro do
repo) para resources/views/components/ do seu
projeto. Se o repo tiver tambem a pasta layouts, coloque em resources/views/components/layouts/.
Requisitos: Laravel com Tailwind e Alpine (ou Livewire, que ja inclui Alpine). O HTML desta pagina usa as mesmas classes dos componentes Blade.
Container com titulo, variantes visuais e padding configuravel.
Variante padrao.
Efeito glass.
Sem borda.
So borda.
<x-app-card title="Titulo">Conteudo</x-app-card>
<x-app-card variant="glass" padding="lg">Glass com padding grande</x-app-card>
Card semitransparente dedicado. Controle de intensidade do blur.
Leve.
Pesado.
<x-app-glass-card title="Titulo" blur="lg">Conteudo</x-app-glass-card>
Card para metricas com label, valor e indicador de tendencia.
<x-app-stat-card label="Usuarios" value="1.234" trend="+12%" :trendUp="true" />
<x-app-stat-card label="Erros" value="23" trend="-5%" :trendUp="false" variant="glass" />
Botao com 8 variantes de cor e 5 tamanhos. Compativel com wire:click e x-on:click.
<x-button>Primary</x-button>
<x-button variant="danger" size="sm">Excluir</x-button>
<x-button variant="ghost" wire:click="cancelar">Cancelar</x-button>
<x-button variant="glass">Glass</x-button>
Input, Textarea, Select, Search, Checkbox, Radio e Toggle. Todos compativeis com wire:model.
Minimo 5 caracteres.
<x-app-input label="Email" type="email" placeholder="email@ex.com" hint="Dica" />
<x-app-textarea label="Bio" wire:model="bio" rows="6" />
<x-app-select label="Pais" :options="['br' => 'Brasil']" wire:model="pais" />
<x-app-search wire:model.live.debounce.300ms="busca" />
<x-app-checkbox label="Aceito os termos" wire:model="termos" />
<x-app-radio name="plano" label="Pro" value="pro" wire:model="plano" />
<x-app-toggle label="Ativar" :checked="true" />
Alerta com icone, titulo e botao de fechar opcional.
<x-app-alert variant="success" title="Sucesso">Salvo!</x-app-alert>
<x-app-alert variant="danger" :dismissible="true">Erro.</x-app-alert>
Etiqueta para status ou categorias.
<x-app-badge variant="success" :rounded="true">Ativo</x-app-badge>
<x-app-badge variant="danger" size="lg">Urgente</x-app-badge>
Foto, iniciais ou icone generico.
<x-app-avatar src="/foto.jpg" alt="Joao" size="lg" />
<x-app-avatar initials="PV" size="md" />
<x-app-avatar size="sm" /> <!-- icone generico -->
Indicador de carregamento. Ideal com wire:loading.
<x-app-spinner size="md" />
<div wire:loading><x-app-spinner size="sm" /></div>
Barra de progresso com label e cores.
<x-app-progress :value="65" :showLabel="true" color="green">Download</x-app-progress>
<x-app-progress :value="30" size="sm" color="red" />
Placeholder para listas/tabelas vazias.
Nenhum registro encontrado.
<x-app-empty-state title="Sem resultados" description="Tente outra busca.">
<x-button size="sm">Limpar</x-button>
</x-app-empty-state>
Separador com texto central opcional.
<x-app-divider />
<x-app-divider text="ou" />
5 tamanhos + versao glass. Abre via $dispatch, fecha com ESC ou clique no overlay.
<div x-data>
<x-button x-on:click="$dispatch('open-meu-modal')">Abrir</x-button>
</div>
<x-app-modal name="meu-modal" size="lg" variant="glass">
<h3>Titulo</h3>
<p>Conteudo.</p>
</x-app-modal>
Menu suspenso. Fecha ao clicar fora.
<x-app-dropdown align="right" width="w-56">
<x-slot:trigger><x-button>Menu</x-button></x-slot:trigger>
<a href="#" class="block px-4 py-2 text-sm hover:bg-gray-100">Item</a>
</x-app-dropdown>
Abas com Alpine. Use x-show="tab === 'chave'" no conteudo.
Aba Geral.
<x-app-tabs :tabs="['a' => 'Aba 1', 'b' => 'Aba 2']" active="a">
<div x-show="tab === 'a'">Conteudo 1</div>
<div x-show="tab === 'b'" style="display:none;">Conteudo 2</div>
</x-app-tabs>
Painel expansivel independente.
<x-app-accordion title="Pergunta" :open="true">Resposta.</x-app-accordion>
Dica ao passar o mouse. 4 posicoes.
<x-app-tooltip text="Salvar" position="top">
<x-button>Salvar</x-button>
</x-app-tooltip>
Notificacao temporaria (4s). Acionada via $dispatch.
<x-app-toast variant="success" position="top-center">Salvo!</x-app-toast>
<div x-data><x-button x-on:click="$dispatch('toast-success')">Salvar</x-button></div>
Tabela responsiva com zebra opcional.
| Nome | Status | |
|---|---|---|
|
AB Ana
|
ana@email.com | Ativo |
|
CD Carlos
|
carlos@email.com | Inativo |
<x-app-table :striped="true">
<x-slot:head>
<tr><th class="px-6 py-3">Nome</th><th class="px-6 py-3">Email</th></tr>
</x-slot:head>
<tr><td class="px-6 py-4">Ana</td><td class="px-6 py-4">ana@email.com</td></tr>
</x-app-table>
Na versao Laravel e um componente Livewire. Aqui: Alpine.js (mesmo comportamento).
<!-- Laravel: <livewire:todo-list /> -->
<!-- Estatico: use Alpine (x-data, x-for, x-model) como acima -->
Rodape com 3 variantes. Veja o exemplo ao vivo no final desta pagina.
<x-app-footer variant="glass">
<span>© 2026 Meu App</span>
<span>Feito com Laravel</span>
</x-app-footer>
Padroes usados em portfolio com mini CMS: layout admin, card de projeto, secao de contato e formulario de perfil.
Navbar para area administrativa: links Projetos, Perfil, Ver site e botao Sair (logout). Use em todas as paginas do admin.
<x-layouts.admin title="Projetos – Admin">
<main class="max-w-5xl mx-auto px-4 py-8">
<!-- conteudo da pagina admin -->
</main>
</x-layouts.admin>
resources/views/components/layouts/admin.blade.php.
Card com miniatura (imagem do projeto), titulo, descricao, botao "Ver projeto" (abre em nova aba) e botao opcional "GitHub".
<x-app-card variant="glass" padding="none" class="overflow-hidden flex flex-col h-full">
<a href="{{ $project->url }}" target="_blank" rel="noopener noreferrer" class="block aspect-video">
<img src="{{ $project->thumbnail_display_url }}" alt="{{ $project->display_name }}" class="w-full h-full object-cover" />
</a>
<div class="p-5">
<h3>{{ $project->display_name }}</h3>
<p>{{ $project->description }}</p>
<a href="{{ $project->url }}" target="_blank" rel="noopener noreferrer">Ver projeto</a>
@if($project->github_url)<a href="{{ $project->github_url }}" target="_blank">GitHub</a>@endif
</div>
</x-app-card>
Bloco de contato: titulo, dados (e-mail, telefone, localizacao, LinkedIn, GitHub) e formulario (nome, e-mail, mensagem). Ideal no rodape com id="contato".
<footer id="contato">
<section class="... backdrop-blur-md ...">
<h2>Contato</h2>
<div class="grid md:grid-cols-2 gap-10">
<div><!-- dados do perfil: email, phone, location, linkedin, github --></div>
<form action="{{ route('contact.store') }}" method="POST">
@csrf
<x-app-input name="name" label="Seu nome" />
<x-app-input name="email" type="email" label="Seu e-mail" />
<x-app-textarea name="message" label="Mensagem" />
<x-button type="submit">Enviar</x-button>
</form>
</div>
</section>
</footer>
Formulario para editar perfil do usuario: foto (upload), nome, e-mail, titulo, bio (curriculo), telefone, localizacao, LinkedIn, GitHub e alterar senha (opcional). Usado em /admin/profile.
<form action="{{ route('admin.profile.update') }}" method="POST" enctype="multipart/form-data">
@csrf
@method('PUT')
<x-app-input name="name" label="Nome" :value="$user->name" />
<x-app-input name="email" type="email" :value="$user->email" />
<input type="file" name="photo" accept="image/*" />
<x-app-input name="title" label="Titulo / Cargo" :value="$user->title" />
<x-app-textarea name="bio" label="Sobre voce">{{ $user->bio }}</x-app-textarea>
<x-app-input name="phone" label="Telefone" :value="$user->phone" />
<x-app-input name="linkedin_url" label="LinkedIn" type="url" :value="$user->linkedin_url" />
<x-app-input name="github_url" label="GitHub" type="url" :value="$user->github_url" />
<x-button type="submit">Salvar perfil</x-button>
</form>