Installation
Étape 1 : Copier les fichiers
Copiez le dossier UI/ dans app/ :
Important : Modifiez le namespace de TailwindUI dans chaque fichier PHP.
Étape 2 : Mettre à jour les namespaces
Dans chaque fichier du dossier UI, changez le namespace :
<?php
// Avant
namespace TailwindUI;
// Aucun changement nécessaire si vous utilisez TailwindUI dans Laravel !
// Le namespace App\ est déjà configuré par défaut.
?>
Étape 3 : Configurer Tailwind CSS
Si vous n'avez pas encore Tailwind CSS dans votre projet Laravel :
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Ou utilisez le CDN dans votre layout Blade :
<!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Mon Application')</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
@stack('styles')
</head>
<body class="bg-gray-50">
@yield('content')
@stack('scripts')
</body>
</html>
Utilisation dans Blade
Méthode 1 : Utilisation directe
{{-- resources/views/dashboard.blade.php --}}
@extends('layouts.app')
@section('title', 'Dashboard')
@section('content')
<div class="max-w-7xl mx-auto py-8 px-4">
<h1 class="text-3xl font-bold mb-8">Tableau de bord</h1>
{{-- Alertes --}}
@if(session('success'))
{!! \TailwindUI\Alert::success(session('success')) !!}
@endif
@if(session('error'))
{!! \TailwindUI\Alert::error(session('error')) !!}
@endif
{{-- Statistiques --}}
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
{!! \TailwindUI\Card::stat('Projets', $projectCount, 'fas fa-folder', 'blue') !!}
{!! \TailwindUI\Card::stat('Tâches', $taskCount, 'fas fa-tasks', 'green') !!}
{!! \TailwindUI\Card::stat('Terminées', $completedCount, 'fas fa-check-circle', 'purple') !!}
{!! \TailwindUI\Card::stat('En retard', $overdueCount, 'fas fa-exclamation-triangle', 'red') !!}
</div>
{{-- Tableau --}}
@php
$headers = ['Titre', 'Statut', 'Priorité', 'Actions'];
$rows = [];
foreach($tasks as $task) {
$rows[] = [
e($task->title),
\TailwindUI\Table::statusCell($task->status),
\TailwindUI\Table::priorityCell($task->priority),
\TailwindUI\Table::actionsCell([
\TailwindUI\Table::actionButton(route('tasks.edit', $task), 'fas fa-edit', 'Modifier', 'blue'),
\TailwindUI\Table::actionButton(route('tasks.destroy', $task), 'fas fa-trash', 'Supprimer', 'red')
])
];
}
@endphp
{!! \TailwindUI\Table::full($headers, $rows) !!}
</div>
@endsection
Méthode 2 : Avec imports use
{{-- resources/views/projects/create.blade.php --}}
@php
use TailwindUI\Form;
use TailwindUI\Button;
use TailwindUI\Card;
@endphp
@extends('layouts.app')
@section('content')
<div class="max-w-2xl mx-auto py-8">
{!! Card::withHeader(
'Nouveau Projet',
'
<form method="POST" action="' . route('projects.store') . '">
' . csrf_field() . '
' . Form::input('title', 'Titre du projet', [
'required' => true,
'value' => old('title')
], $errors->first('title')) . '
' . Form::textarea('description', 'Description', [
'rows' => 4,
'value' => old('description')
], $errors->first('description')) . '
' . Form::grid([
Form::select('priority', 'Priorité', [
'low' => 'Basse',
'medium' => 'Moyenne',
'high' => 'Haute'
], old('priority', 'medium')),
Form::datetime('deadline', 'Date limite', 'date', [
'value' => old('deadline')
])
], 2) . '
<div class="flex justify-end space-x-4 pt-6 border-t">
' . Button::secondary('Annuler', ['onclick' => 'history.back()']) . '
' . Button::withIcon('Créer', 'fas fa-save', 'primary', ['type' => 'submit']) . '
</div>
</form>
'
) !!}
</div>
@endsection
Créer une Facade (Optionnel)
Helper Class UI
Créez une classe helper pour un accès plus simple :
<?php
// app/Helpers/UI.php
namespace App\Helpers;
use TailwindUI\Button;
use TailwindUI\Card;
use TailwindUI\Form;
use TailwindUI\Alert;
use TailwindUI\Badge;
use TailwindUI\Table;
use TailwindUI\Navigation;
class UI
{
// Button shortcuts
public static function button(...$args) { return Button::primary(...$args); }
public static function buttonPrimary(...$args) { return Button::primary(...$args); }
public static function buttonSecondary(...$args) { return Button::secondary(...$args); }
public static function buttonSuccess(...$args) { return Button::success(...$args); }
public static function buttonDanger(...$args) { return Button::danger(...$args); }
public static function buttonWithIcon(...$args) { return Button::withIcon(...$args); }
// Card shortcuts
public static function card(...$args) { return Card::basic(...$args); }
public static function cardWithHeader(...$args) { return Card::withHeader(...$args); }
public static function stat(...$args) { return Card::stat(...$args); }
public static function emptyState(...$args) { return Card::empty(...$args); }
// Form shortcuts
public static function input(...$args) { return Form::input(...$args); }
public static function textarea(...$args) { return Form::textarea(...$args); }
public static function select(...$args) { return Form::select(...$args); }
public static function checkbox(...$args) { return Form::checkbox(...$args); }
// Alert shortcuts
public static function alertSuccess(...$args) { return Alert::success(...$args); }
public static function alertError(...$args) { return Alert::error(...$args); }
public static function alertWarning(...$args) { return Alert::warning(...$args); }
public static function alertInfo(...$args) { return Alert::info(...$args); }
// Badge shortcuts
public static function badge(...$args) { return Badge::primary(...$args); }
public static function status(...$args) { return Badge::status(...$args); }
public static function priority(...$args) { return Badge::priority(...$args); }
// Table shortcuts
public static function table(...$args) { return Table::full(...$args); }
public static function pagination(...$args) { return Table::pagination(...$args); }
// Navigation shortcuts
public static function breadcrumb(...$args) { return Navigation::breadcrumb(...$args); }
public static function tabs(...$args) { return Navigation::tabs(...$args); }
}
?>
Enregistrez-le dans composer.json :
{
"autoload": {
"files": [
"app/Helpers/UI.php"
]
}
}
Utilisation simplifiée
{{-- Dans vos vues Blade --}}
@php use App\Helpers\UI; @endphp
{!! UI::stat('Projets', '12', 'fas fa-folder', 'blue') !!}
{!! UI::input('email', 'Email', ['required' => true]) !!}
{!! UI::buttonWithIcon('Enregistrer', 'fas fa-save', 'primary') !!}
{!! UI::status('active') !!}
{!! UI::alertSuccess('Opération réussie !') !!}
Composants Blade (Avancé)
Créer des composants Blade
Pour une syntaxe encore plus propre, créez des composants Blade :
<?php
// app/View/Components/UIButton.php
namespace App\View\Components;
use Illuminate\View\Component;
use TailwindUI\Button;
class UIButton extends Component
{
public string $text;
public string $variant;
public string $size;
public array $attributes;
public function __construct(
string $text,
string $variant = 'primary',
string $size = 'md',
array $attributes = []
) {
$this->text = $text;
$this->variant = $variant;
$this->size = $size;
$this->attributes = $attributes;
}
public function render()
{
$method = $this->variant;
return Button::$method($this->text, $this->attributes, $this->size);
}
}
?>
Utilisation dans Blade :
<!-- Utilisation avec composant Blade -->
<x-u-i-button text="Enregistrer" variant="primary" />
<x-u-i-button text="Annuler" variant="secondary" />
<x-u-i-button text="Supprimer" variant="danger" />
Exemple de Controller
ProjectController.php
<?php
namespace App\Http\Controllers;
use App\Models\Project;
use Illuminate\Http\Request;
class ProjectController extends Controller
{
public function index()
{
$projects = Project::with('tasks')
->where('user_id', auth()->id())
->latest()
->paginate(10);
// Stats pour les cartes
$stats = [
'total' => Project::where('user_id', auth()->id())->count(),
'active' => Project::where('user_id', auth()->id())
->where('status', 'active')->count(),
'completed' => Project::where('user_id', auth()->id())
->where('status', 'completed')->count(),
];
return view('projects.index', compact('projects', 'stats'));
}
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'priority' => 'required|in:low,medium,high',
'deadline' => 'nullable|date',
]);
$project = auth()->user()->projects()->create($validated);
return redirect()
->route('projects.show', $project)
->with('success', 'Projet créé avec succès !');
}
public function destroy(Project $project)
{
$this->authorize('delete', $project);
$project->delete();
return redirect()
->route('projects.index')
->with('success', 'Projet supprimé avec succès.');
}
}
?>
Conseils et Astuces
Validation des erreurs
Utilisez $errors->first('field') pour afficher les erreurs Laravel dans les champs Form :
Form::input('email', 'Email', [], $errors->first('email'))
Old input
Conservez les anciennes valeurs avec old() :
Form::input('title', 'Titre', ['value' => old('title')])
Flash messages
Créez un partial pour les messages flash dans votre layout :
@if(session('success'))
{!! \TailwindUI\Alert::success(session('success')) !!}
@endif
Routes nommées
Utilisez route() pour les URLs dans les boutons :
Button::primary('Voir', ['onclick' => 'window.location="' . route('projects.show', $project) . '"'])