Day 9 - Component Challenge

Challenge UI with Livewire & Alpine.js

Day 9

Day 9

Data Table & Tooltip

Interactive data management with contextual information display

Tooltip & Popover

Contextual information display on hover or click for enhanced user experience.

Features

  • Multiple positions (top, bottom, left, right)
  • Configurable delay for hover trigger
  • Click or hover trigger modes
  • Smooth enter/leave transitions
  • 100% Tailwind CSS

Tooltip Positions

Icon Tooltips

Popover (Click Trigger)

JK

Jean-Paul Kamga

Admin


Share via

Popover (Hover Trigger)

ME Marie Eyenga

Marie Eyenga

Editor at Livewire UI Lab

Yaoundé Joined 2024

Data Table

Interactive data table with search, sorting, filtering, and pagination.

Features

  • Global search across all columns
  • Column-based sorting (asc/desc)
  • Dropdown filters per column
  • Integrated pagination
  • Skeleton loader during loading
  • 100% Alpine.js state management

Users Directory

Search, filter, and sort through user data

Showing to of results
Page of

Loading State Demo

Table with skeleton loader

Usage Examples

Tooltip Usage

Tooltip Component

The <x-ui.tooltip> component displays contextual information on hover. 100% Tailwind CSS.

Basic Usage

<x-ui.tooltip content="This is a tooltip">
<button>Hover me</button>
</x-ui.tooltip>

Positions

{{-- Top (default) --}}
<x-ui.tooltip content="Top tooltip" position="top">
<button>Top</button>
</x-ui.tooltip>
 
{{-- Bottom --}}
<x-ui.tooltip content="Bottom tooltip" position="bottom">
<button>Bottom</button>
</x-ui.tooltip>
 
{{-- Left --}}
<x-ui.tooltip content="Left tooltip" position="left">
<button>Left</button>
</x-ui.tooltip>
 
{{-- Right --}}
<x-ui.tooltip content="Right tooltip" position="right">
<button>Right</button>
</x-ui.tooltip>

Custom Delay

{{-- Instant (0ms) --}}
<x-ui.tooltip content="No delay" :delay="0">
<button>Instant</button>
</x-ui.tooltip>
 
{{-- Slow (500ms) --}}
<x-ui.tooltip content="Slow tooltip" :delay="500">
<button>Slow</button>
</x-ui.tooltip>

Without Arrow

<x-ui.tooltip content="No arrow" :arrow="false">
<button>Hover me</button>
</x-ui.tooltip>

Icon Tooltips

<x-ui.tooltip content="Settings">
<button class="p-2 rounded-lg hover:bg-accent">
<x-lucide-settings class="size-5" />
</button>
</x-ui.tooltip>

Props Reference

Prop Type Default Description
content string '' Tooltip text content
position string top Position (top, bottom, left, right)
delay int 200 Delay before showing (ms)
arrow bool true Show arrow pointer

Popover Usage

Popover Component

The <x-ui.popover> component displays rich content in a floating panel. 100% Tailwind CSS.

Basic Usage

<x-ui.popover>
<button>Click me</button>
 
<x-slot:content>
<p>Popover content here</p>
</x-slot:content>
</x-ui.popover>

Positions

{{-- Bottom (default) --}}
<x-ui.popover position="bottom">
<button>Bottom</button>
<x-slot:content>Content</x-slot:content>
</x-ui.popover>
 
{{-- Top --}}
<x-ui.popover position="top">
<button>Top</button>
<x-slot:content>Content</x-slot:content>
</x-ui.popover>
 
{{-- Left --}}
<x-ui.popover position="left">
<button>Left</button>
<x-slot:content>Content</x-slot:content>
</x-ui.popover>
 
{{-- Right --}}
<x-ui.popover position="right">
<button>Right</button>
<x-slot:content>Content</x-slot:content>
</x-ui.popover>

Alignment

{{-- Start aligned --}}
<x-ui.popover position="bottom" align="start">
<button>Start</button>
<x-slot:content>Aligned to start</x-slot:content>
</x-ui.popover>
 
{{-- Center aligned (default) --}}
<x-ui.popover position="bottom" align="center">
<button>Center</button>
<x-slot:content>Centered</x-slot:content>
</x-ui.popover>
 
{{-- End aligned --}}
<x-ui.popover position="bottom" align="end">
<button>End</button>
<x-slot:content>Aligned to end</x-slot:content>
</x-ui.popover>

Trigger Modes

{{-- Click trigger (default) --}}
<x-ui.popover trigger="click">
<button>Click me</button>
<x-slot:content>Click-triggered</x-slot:content>
</x-ui.popover>
 
{{-- Hover trigger --}}
<x-ui.popover trigger="hover">
<button>Hover me</button>
<x-slot:content>Hover-triggered</x-slot:content>
</x-ui.popover>

Width Options

{{-- Auto width (default) --}}
<x-ui.popover width="auto">...</x-ui.popover>
 
{{-- Small (12rem) --}}
<x-ui.popover width="sm">...</x-ui.popover>
 
{{-- Medium (16rem) --}}
<x-ui.popover width="md">...</x-ui.popover>
 
{{-- Large (20rem) --}}
<x-ui.popover width="lg">...</x-ui.popover>
 
{{-- Full width --}}
<x-ui.popover width="full">...</x-ui.popover>

User Profile Example

<x-ui.popover position="bottom" align="start" width="md">
<button class="flex items-center gap-2">
<x-ui.avatar name="John Doe" size="sm" />
<span>John Doe</span>
</button>
 
<x-slot:content>
<div class="space-y-3">
<div class="flex items-center gap-3">
<x-ui.avatar name="John Doe" size="lg" />
<div>
<p class="font-semibold">John Doe</p>
<p class="text-sm text-muted-foreground">Admin</p>
</div>
</div>
<hr class="border-border" />
<button class="w-full text-left px-2 py-1.5 text-sm rounded hover:bg-accent">
View Profile
</button>
<button class="w-full text-left px-2 py-1.5 text-sm text-destructive rounded hover:bg-destructive/10">
Sign Out
</button>
</div>
</x-slot:content>
</x-ui.popover>

Props Reference

Prop Type Default Description
position string bottom Position (top, bottom, left, right)
trigger string click Trigger mode (click, hover)
align string center Alignment (start, center, end)
width string auto Width (auto, sm, md, lg, full)

Data Table Usage

Data Table Component

The <x-ui.data-table> component displays interactive data with search, sorting, filtering and pagination. 100% Tailwind CSS + Alpine.js.

Basic Usage

<x-ui.data-table
:columns="[
['key' => 'name', 'label' => 'Name'],
['key' => 'email', 'label' => 'Email'],
['key' => 'role', 'label' => 'Role'],
]"
:data="[
['name' => 'John Doe', 'email' => 'john@example.com', 'role' => 'Admin'],
['name' => 'Jane Smith', 'email' => 'jane@example.com', 'role' => 'Editor'],
]"
/>

Column Configuration

@php
$columns = [
// Basic column
['key' => 'id', 'label' => 'ID'],
 
// Sortable column
['key' => 'name', 'label' => 'Name', 'sortable' => true],
 
// Filterable column (shows dropdown filter)
['key' => 'status', 'label' => 'Status', 'filterable' => true],
 
// Both sortable and filterable
['key' => 'role', 'label' => 'Role', 'sortable' => true, 'filterable' => true],
 
// Disable sorting for specific column
['key' => 'actions', 'label' => 'Actions', 'sortable' => false],
];
@endphp
 
<x-ui.data-table :columns="$columns" :data="$data" />

Pagination

{{-- Default 10 items per page --}}
<x-ui.data-table :columns="$columns" :data="$data" />
 
{{-- Custom items per page --}}
<x-ui.data-table :columns="$columns" :data="$data" :per-page="5" />
 
{{-- Disable pagination --}}
<x-ui.data-table :columns="$columns" :data="$data" :paginated="false" />

Search

{{-- With search (default) --}}
<x-ui.data-table :columns="$columns" :data="$data" />
 
{{-- Custom placeholder --}}
<x-ui.data-table
:columns="$columns"
:data="$data"
search-placeholder="Find users..."
/>
 
{{-- Disable search --}}
<x-ui.data-table :columns="$columns" :data="$data" :searchable="false" />

Sorting

{{-- With sorting (default) --}}
<x-ui.data-table :columns="$columns" :data="$data" />
 
{{-- Disable global sorting --}}
<x-ui.data-table :columns="$columns" :data="$data" :sortable="false" />

Filtering

{{-- With filtering (default) --}}
<x-ui.data-table :columns="$columns" :data="$data" />
 
{{-- Disable filtering --}}
<x-ui.data-table :columns="$columns" :data="$data" :filterable="false" />

Loading State

{{-- Static loading --}}
<x-ui.data-table :columns="$columns" :data="[]" :loading="true" />
 
{{-- Dynamic loading with Alpine --}}
<div x-data="{ loading: true }">
<x-ui.data-table :columns="$columns" :data="$data" ::loading="loading" />
</div>

Empty State

{{-- Custom empty message --}}
<x-ui.data-table
:columns="$columns"
:data="[]"
empty-message="No results found"
/>

Full Example (Livewire Component)

<?php
use Livewire\Volt\Component;
 
new class extends Component {
public array $users = [];
 
public function mount(): void
{
$this->users = [
['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'role' => 'Admin', 'status' => 'Active'],
['id' => 2, 'name' => 'Jane', 'email' => 'jane@example.com', 'role' => 'Editor', 'status' => 'Active'],
['id' => 3, 'name' => 'Bob', 'email' => 'bob@example.com', 'role' => 'Viewer', 'status' => 'Inactive'],
];
}
 
public function getColumns(): array
{
return [
['key' => 'id', 'label' => 'ID', 'sortable' => true],
['key' => 'name', 'label' => 'Name', 'sortable' => true],
['key' => 'email', 'label' => 'Email', 'sortable' => true],
['key' => 'role', 'label' => 'Role', 'sortable' => true, 'filterable' => true],
['key' => 'status', 'label' => 'Status', 'sortable' => true, 'filterable' => true],
];
}
};
?>
 
<x-ui.data-table
:columns="$this->getColumns()"
:data="$users"
:per-page="10"
search-placeholder="Search users..."
/>

Props Reference

Prop Type Default Description
columns array [] Column definitions
data array [] Data rows
searchable bool true Enable search
filterable bool true Enable filters
sortable bool true Enable sorting
paginated bool true Enable pagination
perPage int 10 Items per page
loading bool false Show loading state
emptyMessage string No data available Empty state message
searchPlaceholder string Search... Search input placeholder

Column Options

Option Type Default Description
key string required Data key
label string required Column header
sortable bool true Enable sorting
filterable bool false Enable filter dropdown