Criando um componente com diferentes temas com Blade e Tailwind CSS
Há pouco tempo, descobri que a combinação dos Componentes do Blade mais o Tailwind CSS, formam um excelente par para o desenvolvimento de interfaces web poderosas e reutilizáveis no Laravel. Neste tutorial, vou ensinar como definir seus próprios temas para Blade Components, através destas duas poderosas ferramentas.
Mas primeiro, se você caiu aqui de paraquedas, vamos entender o que são os componentes do Blade e o Tailwindcss:
O que é Blade?
O Blade é um Template Engine, ou seja, um sistema de templates, exclusivo do Laravel, que facilita bastante a construção de visualizações HTML para sua aplicação. Com ele, é possível estender ou reutilizar layouts e componentes, que facilitam bastante no desenvolvimento e construção de uma interface web.
O que é um Blade Component?
É um mecanismo dentro do Blade que permite reutilizar trechos de códigos. É possível utilizar uma sintaxe similar ao JSX, ou o próprio HTML, para fazer a chamada desses componentes, através de um alias de tag, prefixadas por x-
. Esses componentes, por padrão, são definidos na pasta resources/views/components
de uma aplicação Laravel.
Exemplo:
<!-- resource/views/components/button.blade.php -->
<button {{ $attributes->class('my-button-class') }}>{{ $slot }}</button>
Chamada do component em uma view do Laravel:
<x-button class="red">Meu Botão Personalizado</x-button>
O resultado acima, seria similar a seguinte:
<button class="my-button-class red">Meu Botão Personalizado</button>
O que é Tailwind CSS?
O TailwindCSS é um framework CSS que um extenso número de classes utilitárias para você construir a sua folha de estilo. Com ele, é possível que você construa interfaces web estilizadas bastante complexas, porém sem ter mexer em uma linha de código CSS. Isto é porque o Tailwindcss utiliza o conceito de Utility-First.
Construindo um componente com Blade e Tailwind CSS
Neste exemplo, vamos construir um componente de botão, através do Tailwindcss. Além disso, vamos fazer um componente que permita definir diferentes cores, através do Tailwindcss.
Primeiro, voltando ao exemplo anterior, crie um componente chamado resources/views/button.blade.php
@php
$classes = ['px-6 py-4', 'appearance-none', 'shadow'];
@endphp
<button {{ $attributes->class($classes) }}>{{ $slot }}</button>
Observe que, no componente acima, criamos as classes do botão em um array
. Isso porque agora vamos utilizar uma propriedade que vai adicionar classes que adicionarão cores ao fundo e texto do botão.
Veja:
@props(['color' => 'default'])
@php
$classes = ['px-6 py-4', 'appearance-none', 'shadow', 'rounded'];
$themes = [
'default' => 'bg-indigo-600 text-white hover:bg-indigo-600/80',
'danger' => 'bg-red-600 text-white hover:bg-danger-600/80',
'success' => 'bg-green-600 text-white hover:bg-green-600/80',
];
$classes[] = $themes[$color];
@endphp
<button {{ $attributes->class($classes) }}>{{ $slot }}</button>
Observe que definimos a variável $themes
. Esta variável é um array
com índices nomeados, para que possamos obter as classes do tema a partir da variável $color
.
Veja na prática como isso funciona:
<x-button color="danger">Alerta!</x-button>
<x-button color="success">Sucesso!</x-button>
<x-button color="default">Padrão!</x-button>
<x-button>Padrão!</x-button>
O resultado será parecido com este:
Observe que definimos o valor color
em @props
. Quando fazemos isso, dentro do componente, a variável $color
ficará disponível quando passarmos o atributo para o componente. Quando não passamos a propriedade para o componente, o valor 'default'
definido em 'color'
passa a ser o valor padrão. Em seguida, passamos $color
como chave de $themes
para obter um conjunto de classes específico para o tema desejado para nosso componente.
Observação: Essa dica de criar um
array
com chaves e definições de temas é muito útil, pois o Tailwindcss não consegue interpretar as classes do Tailwindcss caso a mesma esteja concatenada, conforme descrito na documentação do Tailwindcss em Content Configuration. Ao invés de concatenar ocolor
com as classes desejadas, você pode utilizar o exemplo da variável$themes
sugerida nesta publicação, para contornar este problema.