Skip to Content
Разработка шаблоновBlade компоненты

Blade компоненты

Компоненты — переиспользуемые UI элементы. Все компоненты из views/components/ автоматически доступны через синтаксис <x-имя>.

Кнопка (button)

Типы кнопок

{{-- Основные типы --}} <x-button type="accent">Accent (основная)</x-button> <x-button type="primary">Primary</x-button> <x-button type="success">Success</x-button> <x-button type="error">Error / Danger</x-button> <x-button type="warning">Warning</x-button> {{-- Outline варианты --}} <x-button type="outline-accent">Outline Accent</x-button> <x-button type="outline-primary">Outline Primary</x-button> <x-button type="outline-error">Outline Error</x-button>

Размеры

<x-button size="tiny">Tiny</x-button> <x-button size="small">Small</x-button> <x-button size="medium">Medium (default)</x-button> <x-button size="large">Large</x-button>

Кнопка-ссылка

<x-button href="/profile">Перейти в профиль</x-button> <x-button href="/external" target="_blank">Внешняя ссылка</x-button>

Состояния

{{-- Disabled --}} <x-button :disabled="true">Недоступна</x-button> {{-- Submit формы --}} <x-button :submit="true" type="accent">Отправить</x-button> {{-- С индикатором загрузки --}} <x-button :withLoading="true">Загрузка...</x-button>

С иконкой

<x-button type="accent"> <x-icon path="ph.regular.check" /> Сохранить </x-button> <x-button type="error"> <x-icon path="ph.regular.trash" /> Удалить </x-button> {{-- Только иконка --}} <x-button type="outline-primary" size="small"> <x-icon path="ph.regular.gear" /> </x-button>

HTMX интеграция

{{-- Кнопка с HTMX навигацией --}} <x-button href="/page" :swap="true" swapTarget="#main"> Загрузить </x-button>

Дополнительные атрибуты

<x-button type="accent" class="my-custom-class" id="submit-btn" data-action="submit" onclick="handleClick()"> Кнопка </x-button>

Карточка (card)

Простая карточка

<x-card> <p>Содержимое карточки</p> </x-card>

С заголовком

<x-card title="Заголовок"> <p>Содержимое</p> </x-card> <x-card title="Заголовок" subtitle="Подзаголовок"> <p>Содержимое</p> </x-card>

С кастомным header (через slot)

<x-card> <x-slot:header> <div class="flex-between"> <h5>Пользователи</h5> <x-button size="small" type="accent">Добавить</x-button> </div> </x-slot:header> <p>Список пользователей...</p> </x-card>
<x-card title="Форма"> <form> <input type="text" class="input" placeholder="Имя"> </form> <x-slot:footer> <div class="flex-between"> <x-button type="outline-primary">Отмена</x-button> <x-button type="accent" :submit="true">Сохранить</x-button> </div> </x-slot:footer> </x-card>

Модификаторы

{{-- Без padding --}} <x-card :withoutPadding="true"> <img src="/image.jpg" style="width: 100%"> </x-card> {{-- Кастомные классы --}} <x-card headerClass="bg-accent-100" bodyClass="p-4" class="shadow-lg"> ... </x-card>

Алерт (alert)

Типы

<x-alert type="success">Операция выполнена успешно!</x-alert> <x-alert type="error">Произошла ошибка</x-alert> <x-alert type="warning">Внимание! Проверьте данные</x-alert> <x-alert type="info">Информационное сообщение</x-alert>

Опции

{{-- Без кнопки закрытия --}} <x-alert type="info" :withClose="false"> Это сообщение нельзя закрыть </x-alert> {{-- Только бордер (без заливки) --}} <x-alert type="success" :onlyBorders="true"> Алерт с бордером </x-alert> {{-- Кастомная иконка --}} <x-alert type="info" icon="ph.regular.bell"> Уведомление </x-alert>

Сложный контент

<x-alert type="warning"> <strong>Важно!</strong> <p>Ваша сессия скоро истечет.</p> <x-button size="small" type="warning">Продлить</x-button> </x-alert>

Модальное окно (modal)

Базовое использование

{{-- Кнопка открытия --}} <x-button data-modal-open="my-modal">Открыть модалку</x-button> {{-- Модальное окно --}} <x-modal id="my-modal" title="Заголовок"> <p>Содержимое модального окна</p> </x-modal>
<x-modal id="confirm-modal" title="Подтверждение"> <p>Вы уверены, что хотите удалить?</p> <x-slot:footer> <x-button type="outline-primary" data-modal-close="confirm-modal"> Отмена </x-button> <x-button type="error"> Удалить </x-button> </x-slot:footer> </x-modal>

Размеры

<x-modal id="small" title="Маленькая" size="sm">...</x-modal> <x-modal id="default" title="Обычная">...</x-modal> <x-modal id="large" title="Большая" size="lg">...</x-modal> <x-modal id="xlarge" title="Очень большая" size="xl">...</x-modal>

Ленивая загрузка контента

<x-modal id="lazy-modal" title="Данные" loadUrl="/api/modal-content" loadTarget="#modal-body"> <div id="modal-body"> <div class="skeleton" style="height: 200px;"></div> </div> </x-modal>

Закрытие из JavaScript

// Открыть openModal('my-modal'); // Закрыть closeModal('my-modal');

Иконки (icon)

Используются Phosphor Icons — https://phosphoricons.com/ 

Варианты

{{-- Regular (по умолчанию) --}} <x-icon path="ph.regular.user" /> <x-icon path="ph.regular.gear" /> <x-icon path="ph.regular.bell" /> <x-icon path="ph.regular.check" /> <x-icon path="ph.regular.x" /> {{-- Bold --}} <x-icon path="ph.bold.check-bold" /> <x-icon path="ph.bold.x-bold" /> {{-- Fill --}} <x-icon path="ph.fill.star-fill" /> <x-icon path="ph.fill.heart-fill" /> {{-- Light --}} <x-icon path="ph.light.user-light" /> {{-- Thin --}} <x-icon path="ph.thin.house-thin" /> {{-- Duotone --}} <x-icon path="ph.duotone.bell-duotone" />

С параметрами

<x-icon path="ph.regular.gear" width="24" height="24" class="text-muted" />

Font Awesome

<x-icon path="fa.solid.home" /> <x-icon path="fa.regular.envelope" /> <x-icon path="fa.brands.github" />

<x-link href="/page">Обычная ссылка</x-link> <x-link href="/page" type="accent">Accent</x-link> <x-link href="/page" type="primary">Primary</x-link> <x-link href="/page" type="error">Error</x-link> <x-link href="/page" type="success">Success</x-link>

Формы

Field (обертка поля)

<x-forms.field> <x-slot:label> <x-forms.label for="email" :required="true">Email</x-forms.label> </x-slot:label> <input type="email" name="email" id="email" class="input"> </x-forms.field>

Label

<x-forms.label for="name">Имя</x-forms.label> <x-forms.label for="email" :required="true">Email</x-forms.label>

Полная форма

<form method="POST" action="/submit"> @csrf <x-forms.field> <x-slot:label> <x-forms.label for="name" :required="true">Имя</x-forms.label> </x-slot:label> <input type="text" name="name" id="name" class="input" required> </x-forms.field> <x-forms.field> <x-slot:label> <x-forms.label for="email" :required="true">Email</x-forms.label> </x-slot:label> <input type="email" name="email" id="email" class="input" required> </x-forms.field> <x-forms.field> <x-slot:label> <x-forms.label for="message">Сообщение</x-forms.label> </x-slot:label> <textarea name="message" id="message" class="input" rows="4"></textarea> </x-forms.field> <x-button type="accent" :submit="true">Отправить</x-button> </form>

Создание своего компонента

1. Создайте файл

views/components/stat-card.blade.php:

@props([ 'title', 'value', 'icon' => null, 'change' => null, 'changeType' => 'neutral' ]) <div {{ $attributes->merge(['class' => 'stat-card']) }}> @if ($icon) <div class="stat-card__icon"> <x-icon :path="$icon" /> </div> @endif <div class="stat-card__content"> <span class="stat-card__title">{{ $title }}</span> <span class="stat-card__value">{{ $value }}</span> @if ($change) <span class="stat-card__change stat-card__change--{{ $changeType }}"> {{ $change }} </span> @endif </div> </div>

2. Добавьте стили

assets/sass/components/_stat-card.scss:

.stat-card { display: flex; gap: var(--space-md); padding: var(--space-lg); background: var(--secondary); border-radius: var(--border1); &__icon { display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; background: var(--accent-100); color: var(--accent); border-radius: var(--border05); } &__title { font-size: var(--small); color: var(--text-muted); } &__value { font-size: var(--h3); font-weight: 700; } &__change { font-size: var(--small); &--positive { color: var(--success); } &--negative { color: var(--error); } &--neutral { color: var(--text-muted); } } }

3. Используйте

<x-stat-card title="Пользователи" value="12,345" icon="ph.regular.users" change="+12%" changeType="positive" />

Переопределение стандартного компонента

Чтобы изменить стандартный компонент, создайте файл с тем же именем:

views/components/button.blade.php → заменит <x-button> views/components/card.blade.php → заменит <x-card> views/components/modal.blade.php → заменит <x-modal>

Работа с атрибутами

$attributes

{{-- Слияние классов --}} <div {{ $attributes->merge(['class' => 'my-class']) }}> {{-- Исключение атрибутов --}} <div {{ $attributes->except(['class']) }}> {{-- Только определенные --}} <div {{ $attributes->only(['id', 'class']) }}> {{-- Проверка наличия --}} @if ($attributes->has('disabled')) ... @endif {{-- Получение значения --}} {{ $attributes->get('data-id', 'default') }}

@class директива

<div @class([ 'card', 'card--featured' => $featured, 'card--disabled' => $disabled, ])>

Слоты

Именованные слоты

{{-- Компонент --}} @props(['title']) <div class="card"> @if (isset($header)) <div class="card-header">{{ $header }}</div> @endif <div class="card-body">{{ $slot }}</div> @if (isset($footer)) <div class="card-footer">{{ $footer }}</div> @endif </div>
{{-- Использование --}} <x-card> <x-slot:header> <h5>Заголовок</h5> </x-slot:header> <p>Основной контент</p> <x-slot:footer> <x-button>Действие</x-button> </x-slot:footer> </x-card>