```
### Card Grid
Display cards in responsive grid:
```blade
Total Posts
1,234
Published
856
Drafts
378
```
## Stat Widgets
### Simple Stat
```blade
```
### Stat with Trend
```blade
```
**Trend Indicators:**
- Positive number: green up arrow
- Negative number: red down arrow
- Zero: neutral indicator
### Stat with Chart
```blade
```
**Sparkline Data:**
```php
public function getSparklineData()
{
return [
120, 145, 132, 158, 170, 165, 180, 195, 185, 200
];
}
```
### Stat Grid
```blade
```
## Tables
### Basic Table
```blade
TitleAuthorStatusActions
@foreach($posts as $post)
{{ $post->title }}{{ $post->author->name }}
{{ $post->status }}
Edit
@endforeach
```
### Sortable Table
```blade
Title
Created
{{-- Table rows --}}
```
**Livewire Component:**
```php
class PostsTable extends Component
{
public $sortField = 'created_at';
public $sortDirection = 'desc';
public function sortBy($field)
{
if ($this->sortField === $field) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
} else {
$this->sortField = $field;
$this->sortDirection = 'asc';
}
}
public function render()
{
$posts = Post::orderBy($this->sortField, $this->sortDirection)
->paginate(20);
return view('livewire.posts-table', compact('posts'));
}
}
```
### Table with Bulk Actions
```blade
TitleActions
@foreach($posts as $post)
{{ $post->title }}...
@endforeach
@if(count($selected) > 0)
{{ count($selected) }} selected
PublishDelete
@endif
```
## Badges
### Status Badges
```blade
PublishedDraftArchivedScheduledPending
```
### Badge with Dot
```blade
Active
```
### Badge with Icon
```blade
Verified
```
### Removable Badge
```blade
{{ $tag->name }}
```
## Alerts
### Basic Alert
```blade
Post published successfully!
Failed to save post. Please try again.
This post has not been reviewed yet.
You have 3 draft posts.
```
### Dismissible Alert
```blade
Post published successfully!
```
### Alert with Title
```blade
Pending Review
This post requires approval before it can be published.
```
## Empty States
### Basic Empty State
```blade
No posts yet
Get started by creating your first blog post.
Create Post
```
### Search Empty State
```blade
@if($posts->isEmpty() && $search)
No results found
No posts match your search for "{{ $search }}".
Clear Search
@endif
```
## Loading States
### Skeleton Loaders
```blade
```
### Loading Spinner
```blade
{{-- Content --}}
```
### Loading Overlay
```blade
{{-- Content becomes translucent while loading --}}
```
## Pagination
```blade
{{-- Table content --}}
{{ $posts->links('admin::pagination') }}
```
**Custom Pagination:**
```blade
```
## Modals (See Modals Documentation)
See [Livewire Modals →](/packages/admin/modals) for full modal documentation.
## Dropdowns
### Basic Dropdown
```blade
Actions
Edit
Duplicate
Delete
```
### Dropdown with Icons
```blade
Edit Post
View
```
## Tabs
```blade
{{-- General settings --}}
{{-- SEO settings --}}
{{-- Advanced settings --}}
```
## Best Practices
### 1. Use Semantic Components
```blade
{{-- ✅ Good - semantic component --}}
{{-- ❌ Bad - manual markup --}}
Revenue
{{ $revenue }}
```
### 2. Consistent Colors
```blade
{{-- ✅ Good - use color props --}}
ActiveInactive
{{-- ❌ Bad - custom classes --}}
Active
```
### 3. Loading States
```blade
{{-- ✅ Good - show loading state --}}
{{-- ❌ Bad - no feedback --}}
```
### 4. Empty States
```blade
{{-- ✅ Good - helpful empty state --}}
@if($posts->isEmpty())
Create First Post
@endif
{{-- ❌ Bad - no guidance --}}
@if($posts->isEmpty())
No posts
@endif
```
## Testing Components
```php
use Tests\TestCase;
class ComponentsTest extends TestCase
{
public function test_stat_widget_renders(): void
{
$view = $this->blade('');
$view->assertSee('Users');
$view->assertSee('100');
}
public function test_badge_renders_with_color(): void
{
$view = $this->blade('Active');
$view->assertSee('Active');
$view->assertSeeInOrder(['class', 'green']);
}
}
```
## Learn More
- [Form Components →](/packages/admin/forms)
- [Livewire Modals →](/packages/admin/modals)
- [Authorization →](/packages/admin/authorization)