General
Blog code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/blog/article-meta.blade.php
@props([
'post' => null,
'date' => null,
'dateTime' => null,
'category' => null,
'categoryHref' => null,
'draft' => false,
'statusLabel' => null,
'statusVariant' => 'amber',
])
@php
/*
| Article metadata row: publish date or draft badge, optional category link.
|
| Pass a Post model for the standard blog, or scalar props (date, category,
| categoryHref) to render without a model.
|
| Usage:
| <x-ui.blog.article-meta :post="$post" />
| <x-ui.blog.article-meta date="June 12, 2026" category="Product" :category-href="$url" />
*/
if ($post) {
$draft = ! $post->isPublished();
$date = $post->published_at?->format('F j, Y');
$dateTime = $post->published_at?->toIso8601String();
$category = $post->category?->name;
$categoryHref = $post->category ? route('categories.show', $post->category) : null;
$statusLabel = $post->statusLabel();
$statusVariant = $post->statusBadgeVariant();
}
@endphp
<div {{ $attributes->merge(['class' => 'flex items-center gap-2 text-sm font-medium text-gray-500 dark:text-gray-400']) }}>
@if ($draft)
<x-ui.badge :variant="$statusVariant" size="sm">{{ $statusLabel }}</x-ui.badge>
@elseif ($date)
<time @if ($dateTime) datetime="{{ $dateTime }}" @endif>{{ $date }}</time>
@endif
@if ($category)
<span aria-hidden="true">·</span>
@if ($categoryHref)
<a href="{{ $categoryHref }}" class="transition hover:text-brand-600 dark:hover:text-brand-400">
<x-ui.badge variant="brand" size="sm" icon="tag">{{ $category }}</x-ui.badge>
</a>
@else
<x-ui.badge variant="brand" size="sm" icon="tag">{{ $category }}</x-ui.badge>
@endif
@endif
</div>
resources/views/components/ui/blog/author-byline.blade.php
@props([
'user' => null,
'name' => null,
'label' => 'Author',
'size' => 'base',
])
@php
/*
| Author byline with avatar, name and role label.
|
| Pass a User model for the standard blog (uses the user's custom avatar),
| or a `name` string to render without a model.
|
| Usage:
| <x-ui.blog.author-byline :user="$post->user" />
| <x-ui.blog.author-byline name="Ada Lovelace" label="Founding Designer" />
*/
$name ??= $user?->fullName();
@endphp
<div {{ $attributes->merge(['class' => 'flex items-center gap-3']) }}>
@if ($user)
<x-ui.avatar
:name="$user->fullName()"
:initials="$user->avatarInitials()"
:background="$user->avatarBackground()"
:color="$user->avatar_character_color"
:size="$size"
/>
@else
<x-ui.avatar :name="$name" :size="$size" />
@endif
<div>
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $name }}</p>
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $label }}</p>
</div>
</div>
resources/views/components/ui/blog/masthead.blade.php
@props([
'title',
'description' => null,
])
@php
/*
| Blog page masthead with optional eyebrow badge and trailing actions.
|
| Usage:
| <x-ui.blog.masthead title="The Blog" description="Thoughts and updates.">
| <x-slot:actions><x-ui.button href="...">Write</x-ui.button></x-slot:actions>
| </x-ui.blog.masthead>
|
| <x-ui.blog.masthead title="{{ $category->name }}" :description="$category->description">
| <x-slot:eyebrow><x-ui.badge variant="brand" icon="tag">Category</x-ui.badge></x-slot:eyebrow>
| </x-ui.blog.masthead>
*/
@endphp
<header {{ $attributes->merge(['class' => 'flex flex-col gap-4 border-b border-gray-200 pb-8 sm:flex-row sm:items-end sm:justify-between sm:gap-6 dark:border-gray-800']) }}>
<div class="min-w-0">
@isset($eyebrow)
<div class="flex items-center gap-2">{{ $eyebrow }}</div>
@endisset
<h1 @class([
'text-4xl font-bold tracking-tight text-gray-900 dark:text-white',
'mt-3' => isset($eyebrow),
])>{{ $title }}</h1>
@if ($description)
<p class="mt-2 text-base text-gray-500 dark:text-gray-400">{{ $description }}</p>
@endif
</div>
@isset($actions)
<div class="flex w-full shrink-0 flex-wrap items-center gap-2 sm:w-auto">{{ $actions }}</div>
@endisset
</header>
resources/views/components/ui/blog/post-list-item.blade.php
@props([
'post' => null,
'showCategory' => true,
'title' => null,
'author' => null,
'date' => null,
'dateTime' => null,
'category' => null,
'comments' => 0,
'href' => '#',
'excerpt' => null,
])
@php
/*
| Blog reading-list row: meta, title, excerpt and comment count.
|
| Pass a Post model for the standard blog, or the scalar props
| (title, author, date, category, comments, href, excerpt) to render a row
| without a model (e.g. in showcases).
|
| Usage:
| <x-ui.blog.post-list-item :post="$post" />
| <x-ui.blog.post-list-item title="..." author="Ada" date="Jun 9, 2026" :href="$url" />
*/
if ($post) {
$title = $post->title;
$author = $post->user->fullName();
$date = $post->published_at->format('M j, Y');
$dateTime = $post->published_at->toIso8601String();
$category = $showCategory ? $post->category?->name : null;
$comments = $post->comments_count;
$href = route('posts.show', $post);
$excerpt = $post->excerpt ?: Str::limit(strip_tags($post->body), 180);
}
@endphp
<article {{ $attributes->merge(['class' => 'group py-10']) }}>
<a href="{{ $href }}" class="block">
<div class="flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
<span>{{ $author }}</span>
<span aria-hidden="true">·</span>
<time @if ($dateTime) datetime="{{ $dateTime }}" @endif>{{ $date }}</time>
@if ($showCategory && $category)
<span aria-hidden="true">·</span>
<span class="text-brand-600 dark:text-brand-400">{{ $category }}</span>
@endif
</div>
<h2 class="mt-3 text-2xl font-bold tracking-tight text-gray-900 transition-colors group-hover:text-brand-600 dark:text-white dark:group-hover:text-brand-400">
{{ $title }}
</h2>
@if ($excerpt)
<p class="mt-3 text-base leading-relaxed text-gray-600 dark:text-gray-300">
{{ $excerpt }}
</p>
@endif
<div class="mt-4 flex items-center gap-4 text-sm text-gray-500 dark:text-gray-400">
<span class="inline-flex items-center gap-1.5">
<x-ui.icon name="chat-circle" size="sm" />
{{ $comments }} {{ Str::plural('comment', $comments) }}
</span>
<span class="inline-flex items-center gap-1 font-medium text-brand-600 opacity-0 transition-opacity group-hover:opacity-100 dark:text-brand-400">
Read
<x-ui.icon name="arrow-right" weight="bold" size="sm" class="transition-transform group-hover:translate-x-0.5" />
</span>
</div>
</a>
</article>