Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Table Laravel Package

artflow-studio/table

View on GitHub
Deep Wiki
Context7

πŸ”§ ArtFlow Table - AI Technical Reference

For AI Agents & Developers: Complete technical architecture and implementation guide


πŸ“‹ Package Overview

Property Value
Package artflow-studio/table
Type Livewire Component (Trait-Based)
Version 1.5.2
Developer Site https://artflow.pk
Location vendor/artflow-studio/table/src/
Main Component DatatableTrait (Livewire Component)
Blade Directive [@livewire](https://github.com/livewire)('aftable', [...])
Registration TableServiceProvider::class
Auto-Discovery βœ… Yes (Laravel 5.5+)

πŸ—οΈ Architecture Overview

Component Stack

[@livewire](https://github.com/livewire)('aftable', [...])
    ↓
DatatableTrait.php (Main Livewire Component)
    β”œβ”€β”€ Uses 18 Core Traits
    β”œβ”€β”€ Mounted Properties
    β”œβ”€β”€ Reactive Methods
    └── Blade Rendering
        ↓
    aftable.blade.php (Template)
    β”œβ”€β”€ Search Box
    β”œβ”€β”€ Column Headers
    β”œβ”€β”€ Table Rows
    β”œβ”€β”€ Pagination
    └── Export/Filters

Trait Organization

app/Http/Livewire/
└── DatatableTrait.php (Main Component)

vendor/artflow-studio/table/src/Traits/
β”œβ”€β”€ Core/
β”‚   β”œβ”€β”€ HasDataProcessing.php        # Data transformation
β”‚   β”œβ”€β”€ HasQueryBuilding.php         # Query construction
β”‚   β”œβ”€β”€ HasPagination.php            # Pagination logic
β”‚   β”œβ”€β”€ HasSearch.php                # Search functionality
β”‚   β”œβ”€β”€ HasSorting.php               # Sort handling
β”‚   β”œβ”€β”€ HasAutoOptimization.php      # Auto-detection
β”‚   β”œβ”€β”€ HasCountAggregations.php     # N+1 prevention
β”‚   β”œβ”€β”€ HasRelationships.php         # Relation handling
β”‚   β”œβ”€β”€ HasColumnValidation.php      # Column checking
β”‚   β”œβ”€β”€ HasColumnInitialization.php  # Column setup
β”‚   └── HasUtilities.php             # Helper methods
β”‚
β”œβ”€β”€ UI/
β”‚   β”œβ”€β”€ HasSortingUI.php             # Sort UI elements
β”‚   β”œβ”€β”€ HasColumnVisibility.php      # Show/hide columns
β”‚   β”œβ”€β”€ HasActions.php               # Action buttons
β”‚   └── HasExport.php                # Export features
β”‚
└── Advanced/
    β”œβ”€β”€ HasAdvancedFiltering.php     # Complex filters
    β”œβ”€β”€ HasPerformanceOptimization.php # Cache handling
    └── HasSessionManagement.php     # Session isolation

πŸ“ Usage Pattern

Blade Integration

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Item',
    'columns' => [
        ['key' => 'title', 'label' => 'Title'],
        ['key' => 'category_name', 'label' => 'Category', 'relation' => 'category:name'],
        ['key' => 'subitems_count', 'label' => 'Sub-items'],
    ],
    'records' => 50,
])

What Happens Behind the Scenes

  1. Component Mount

    mount() called
    β†’ initializeComponent()
    β†’ initializeColumns()
    β†’ setDefaultSort()
    
  2. Data Initialization

    autoOptimizeColumns()
    β†’ Detects relations
    β†’ Detects count columns
    β†’ Enables sorting/searching
    
    autoDetectCountAggregations()
    β†’ Finds _count columns
    β†’ Extracts relation names
    β†’ Queues for withCount()
    
  3. Query Building

    buildUnifiedQuery()
    β†’ applyEagerLoading()
    β†’ applyCountAggregations()
    β†’ applySearch()
    β†’ applySorting()
    β†’ paginate()
    
  4. Rendering

    render()
    β†’ Load aftable.blade.php
    β†’ Pass $records, $columns, etc.
    β†’ Display to user
    

πŸ”‘ Key Traits Explained

1. HasAutoOptimization (Core Innovation)

Purpose: Automatically detect and configure columns

// What it does:
protected function autoOptimizeColumns(): void
{
    foreach ($this->columns as &$column) {
        // Detect if it's a relation column
        if (isset($column['relation'])) {
            $relation = extractRelationName($column['relation']);
            $this->relationsToLoad[] = $relation;
            $column['searchable'] = true;  // Relations are searchable
            $column['sortable'] = true;
        }
        
        // Detect if it's a count column
        if (str_ends_with($column['key'], '_count')) {
            $relation = str_replace('_count', '', $column['key']);
            $this->countAggregations[$relation] = $relation;
            $column['sortable'] = true;  // Counts are sortable
        }
        
        // Default text columns are searchable
        if (isTextColumn($column)) {
            $column['searchable'] = true;
        }
    }
}

Result: All optimization decisions made automatically - users don't need to configure anything!

2. HasCountAggregations (N+1 Prevention)

Purpose: Prevent N+1 queries when showing relationship counts

// What it does:
protected function autoDetectCountAggregations(): void
{
    foreach ($this->columns as $column) {
        if (str_ends_with($column['key'], '_count')) {
            $relation = str_replace('_count', '', $column['key']);
            
            // Verify relation exists on model
            if (hasRelation($this->model, $relation)) {
                $this->countAggregations[$relation] = true;
            }
        }
    }
}

protected function applyCountAggregations(Builder $query): Builder
{
    if (!empty($this->countAggregations)) {
        return $query->withCount(array_keys($this->countAggregations));
    }
    return $query;
}

Result: Single query loads all counts! No N+1!

3. HasSortingUI (User Experience)

Purpose: Display sort indicators and manage sort state

// What it does:
public function getSortIcon(string $columnKey): string
{
    if ($this->sortBy === $columnKey) {
        return $this->sortDirection === 'asc' ? '↑' : '↓';
    }
    return ''; // No icon if not sorted
}

public function updateSort(string $columnKey): void
{
    if ($this->sortBy === $columnKey) {
        // Toggle direction
        $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
    } else {
        // New sort column
        $this->sortBy = $columnKey;
        $this->sortDirection = 'asc';
    }
    $this->resetPage();
}

Result: Beautiful sort UI with up/down arrows that users understand!

4. HasQueryBuilding (Optimization)

Purpose: Build optimized Eloquent query

// What it does:
protected function buildUnifiedQuery(): Builder
{
    $query = $this->model::query();
    
    // Step 1: Eager load relations (prevent N+1)
    foreach ($this->relationsToLoad as $relation) {
        $query->with($relation);
    }
    
    // Step 2: Add count aggregations (show counts efficiently)
    $query = $this->applyCountAggregations($query);
    
    // Step 3: Apply search filters
    $query = $this->applySearch($query);
    
    // Step 4: Apply sorting
    $query = $this->applySorting($query);
    
    // Step 5: Paginate results
    return $query;
}

Result: Single optimized query that handles everything!

5. HasSearch (Searching)

Purpose: Search across multiple columns efficiently

// What it does:
protected function applySearch(Builder $query): Builder
{
    if (empty($this->search)) {
        return $query;
    }
    
    return $query->where(function ($q) {
        foreach ($this->searchableColumns as $column) {
            if ($column['type'] === 'relation') {
                // Search in related table
                $relation = extractRelationName($column['relation']);
                $field = extractColumnName($column['relation']);
                $q->orWhereHas($relation, fn($sub) => 
                    $sub->where($field, 'like', "%{$this->search}%")
                );
            } else {
                // Search in main table
                $q->orWhere($column['key'], 'like', "%{$this->search}%");
            }
        }
    });
}

Result: Smart search that works on all column types!


πŸ”„ Data Flow Diagram

USER INTERACTION
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ User Action (sort/search/page)   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ - Click column header β†’ sortBy()  β”‚
β”‚ - Type search β†’ search()          β”‚
β”‚ - Click page β†’ gotoPage()         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Livewire Reactivity              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ wire:click, wire:model, etc.     β”‚
β”‚ Triggers component method         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Component Method Executes         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ sortBy = 'name'                  β”‚
β”‚ sortDirection = 'asc'            β”‚
β”‚ resetPage() β†’ page = 1           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Livewire Renders                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ render() method called            β”‚
β”‚ Blade template updated            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Build Query (OPTIMIZE STEP)      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. with(relations)        [eager]β”‚
β”‚ 2. withCount(counts)      [N+1]  β”‚
β”‚ 3. where(search)          [find] β”‚
β”‚ 4. orderBy(sort)          [order]β”‚
β”‚ 5. paginate()             [page] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Execute Single Query             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ SELECT ... FROM products         β”‚
β”‚   with category, brand           β”‚
β”‚   withCount variants, reviews    β”‚
β”‚   WHERE name LIKE '%search%'     β”‚
β”‚   ORDER BY created_at ASC        β”‚
β”‚   LIMIT 50                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Render Table                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Display sorted/filtered results   β”‚
β”‚ Show page numbers                β”‚
β”‚ Highlight current sort column    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Column Configuration Format

Minimal (Most Common)

['key' => 'title', 'label' => 'Item Name']
  • Auto-sorted: βœ…
  • Auto-searched: βœ…
  • Displayed: βœ…

With Relationship

['key' => 'category_name', 'label' => 'Category', 'relation' => 'category:name']
  • Auto-eager loads category relation
  • Searches in category.name
  • Sorts by category.name
  • No N+1 query!

With Count

['key' => 'subitems_count', 'label' => 'Sub-items']
  • Auto-detected count column
  • Uses withCount('subitems')
  • Shows count without loading items
  • Single query!

With Actions

[
    'key' => 'actions',
    'label' => 'Actions',
    'actions' => [
        ['type' => 'button', 'label' => 'Edit', 'href' => '/items/{id}/edit'],
        ['type' => 'button', 'label' => 'Delete', 'href' => '/items/{id}', 'method' => 'DELETE'],
    ]
]

Advanced Options

[
    'key' => 'amount',
    'label' => 'Amount',
    'sortable' => true,        # Allow sorting (auto-enabled)
    'searchable' => true,      # Allow searching (auto-enabled)
    'hidden' => false,         # Show/hide column
    'value_type' => 'price',   # Format: price, date, boolean, etc.
    'class' => 'text-right',   # Cell CSS classes
    'width' => '120px',        # Column width
    'raw' => false,            # Escape HTML (false = escape)
]

⚑ Performance Optimizations

1. Eager Loading (Prevents N+1 Query on Relations)

Before (N+1 Problem):

Initial Query: SELECT * FROM items β†’ 50 rows
For Each Row: SELECT * FROM categories WHERE id = ? β†’ 50 queries!
TOTAL: 51 queries! ❌

After (Eager Loading):

Query: SELECT * FROM items WITH categories β†’ 1 query βœ…
Result: Items have categories pre-loaded
TOTAL: 1 query! βœ…

Code:

// Automatically done:
$query->with(['category', 'department', 'supplier']);

2. Count Aggregations (Prevents N+1 Query on Counts)

Before (N+1 Problem):

Initial Query: SELECT * FROM items β†’ 50 rows
For Each Row: SELECT COUNT(*) FROM subitems WHERE item_id = ? β†’ 50 queries!
TOTAL: 51 queries! ❌

After (withCount):

Query: SELECT * FROM items, COUNT(*) as subitems_count β†’ 1 query βœ…
Result: Each item has subitems_count pre-

calculated
TOTAL: 1 query! βœ…

Code:

// Automatically done:
$query->withCount(['subitems', 'related', 'attachments']);

3. Chunked Export (Prevents Memory Issues)

Code:

// Export processes in chunks:
$query->chunk(500, function($records) {
    foreach ($records as $record) {
        // Process each record
        $this->exportRow($record);
    }
});
// Handles 1M+ records without memory crash βœ…

4. Session Isolation (Prevents Cross-User Data Leaks)

Code:

// Each session stores its own state:
$sessionKey = 'aftable_' . md5($this->componentId);
session([$sessionKey => $this->state]);

// Other users can't see another user's table state

πŸ§ͺ Testing Guide

Test Auto-Optimization

// Test that relations are auto-detected
public function testAutoDetectsRelations()
{
    $component = Livewire::test(DatatableTrait::class, [
        'model' => 'App\Models\Product',
        'columns' => [
            ['key' => 'category_name', 'relation' => 'category:name'],
        ],
    ]);
    
    $this->assertContains('category', $component->instance()->relationsToLoad);
}

Test Count Aggregations

// Test that _count columns work
public function testCountAggregations()
{
    $component = Livewire::test(DatatableTrait::class, [
        'model' => 'App\Models\Product',
        'columns' => [
            ['key' => 'variants_count', 'label' => 'Variants'],
        ],
    ]);
    
    // Query should include withCount
    $this->assertStringContainsString('count', $component->instance()->buildUnifiedQuery()->toSql());
}

Test Search

// Test search filtering
public function testSearch()
{
    $component = Livewire::test(DatatableTrait::class, [
        'model' => 'App\Models\Product',
        'columns' => [
            ['key' => 'name', 'label' => 'Name'],
        ],
    ]);
    
    $component->set('search', 'Test Product');
    $results = $component->instance()->records;
    
    $this->assertTrue($results->every(fn($r) => str_contains($r->name, 'Test Product')));
}

Test Sorting

// Test sort functionality
public function testSorting()
{
    $component = Livewire::test(DatatableTrait::class, [
        'model' => 'App\Models\Product',
        'columns' => [
            ['key' => 'name', 'label' => 'Name'],
        ],
    ]);
    
    $component->call('updateSort', 'name');
    
    $this->assertEquals('name', $component->instance()->sortBy);
    $this->assertEquals('asc', $component->instance()->sortDirection);
}

πŸ› Debugging Tips

1. Check Database Queries

// Enable query logging in tinker:
DB::enableQueryLog();

// Then render component...

// Check queries:
echo DB::getQueryLog();

Expected Output:

Query 1: SELECT * FROM products WITH category, brand, supplier withCount(variants)...
Total: 1 query βœ…

2. Check Auto-Optimization

// In tinker:
$component = app(DatatableTrait::class);
$component->model = 'App\Models\Product';
$component->columns = [
    ['key' => 'category_name', 'relation' => 'category:name'],
    ['key' => 'variants_count', 'label' => 'Variants'],
];

$component->autoOptimizeColumns();

dd([
    'relationsToLoad' => $component->relationsToLoad,
    'countAggregations' => $component->countAggregations,
    'columns' => $component->columns,
]);

3. Check Blade Variables

<!-- In aftable.blade.php template -->
<pre>{{ print_r($columns, true) }}</pre>
<pre>{{ print_r($records, true) }}</pre>
<pre>{{ "Queries: " . DB::getQueryLog() }}</pre>

πŸ”Œ Extending the Component

Add Custom Column Type

// In your component or trait:
protected function formatColumnValue($value, $column)
{
    return match($column['value_type'] ?? null) {
        'price' => '$' . number_format($value, 2),
        'date' => \Carbon\Carbon::parse($value)->format('M d, Y'),
        'boolean' => $value ? 'βœ“' : 'βœ—',
        'custom' => $this->customFormat($value, $column),
        default => $value,
    };
}

Add Custom Filter

// In your component:
public function addCustomFilter(string $key, \Closure $callback)
{
    $this->customFilters[$key] = $callback;
}

// Then in query building:
protected function applyCustomFilters(Builder $query): Builder
{
    foreach ($this->customFilters as $callback) {
        $query = $callback($query);
    }
    return $query;
}

Add Custom Action

// In column config:
['key' => 'custom_action', 'raw' => 'handleCustomAction()']

// Add method:
public function handleCustomAction()
{
    // Your logic here
}

πŸ“Š Trait Dependencies

DatatableTrait.php
β”œβ”€β”€ HasDataProcessing
β”œβ”€β”€ HasQueryBuilding
β”‚   β”œβ”€β”€ HasSearch
β”‚   β”œβ”€β”€ HasSorting
β”‚   β”œβ”€β”€ HasPagination
β”‚   β”œβ”€β”€ HasAutoOptimization
β”‚   β”œβ”€β”€ HasCountAggregations
β”‚   └── HasRelationships
β”œβ”€β”€ HasColumnInitialization
β”œβ”€β”€ HasColumnValidation
β”œβ”€β”€ HasUtilities
β”œβ”€β”€ HasSortingUI
β”œβ”€β”€ HasColumnVisibility
β”œβ”€β”€ HasActions
β”œβ”€β”€ HasExport
β”œβ”€β”€ HasAdvancedFiltering
β”œβ”€β”€ HasPerformanceOptimization
└── HasSessionManagement

Order Matters: Traits are loaded in dependency order to avoid conflicts!


🚨 Critical Rules for AI

βœ… DO

  • Use in Blade views only: [@livewire](https://github.com/livewire)('aftable', [...])
  • Pass Eloquent model: 'model' => 'App\Models\Product'
  • Use 'relation' => 'relationName:columnName' format
  • Use columnName_count for count aggregations
  • Test with actual data before deploying
  • Check database query count (should be 1!)

❌ DON'T

  • Don't instantiate component directly in PHP
  • Don't put complex logic in column configuration
  • Don't mix automatic and manual sorting config
  • Don't use raw HTML without escaping
  • Don't load 50+ columns (performance)
  • Don't assume eager loading without using 'relation'
  • Don't ignore N+1 query warnings

πŸ“š File Structure Reference

vendor/artflow-studio/table/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ Http/
β”‚   β”‚   └── Livewire/
β”‚   β”‚       └── DatatableTrait.php         [Main Component]
β”‚   β”œβ”€β”€ Traits/
β”‚   β”‚   β”œβ”€β”€ Core/
β”‚   β”‚   β”‚   β”œβ”€β”€ HasDataProcessing.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasQueryBuilding.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasPagination.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasSearch.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasSorting.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasAutoOptimization.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasCountAggregations.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasRelationships.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasColumnValidation.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasColumnInitialization.php
β”‚   β”‚   β”‚   └── HasUtilities.php
β”‚   β”‚   β”œβ”€β”€ UI/
β”‚   β”‚   β”‚   β”œβ”€β”€ HasSortingUI.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasColumnVisibility.php
β”‚   β”‚   β”‚   β”œβ”€β”€ HasActions.php
β”‚   β”‚   β”‚   └── HasExport.php
β”‚   β”‚   └── Advanced/
β”‚   β”‚       β”œβ”€β”€ HasAdvancedFiltering.php
β”‚   β”‚       β”œβ”€β”€ HasPerformanceOptimization.php
β”‚   β”‚       └── HasSessionManagement.php
β”‚   β”œβ”€β”€ resources/
β”‚   β”‚   └── views/
β”‚   β”‚       └── aftable.blade.php          [Template]
β”‚   └── Providers/
β”‚       └── TableServiceProvider.php        [Registration]
β”œβ”€β”€ composer.json
β”œβ”€β”€ README.md
└── DOCUMENTATION_FILES (guides, references, etc.)

πŸŽ“ Learning Path for AI

  1. Start Here: Read AI_USAGE_GUIDE.md (non-technical)
  2. Understand Structure: Read this file's "Architecture" section
  3. Study Examples: Look at "Real-World Examples" in usage guide
  4. Understand Traits: Read each trait's documentation in source code
  5. Test Query: Use tinker to test query building
  6. Debug Issues: Use debugging tips in this guide
  7. Extend: Add custom filters/actions as needed

πŸ”— Integration Examples

With Laravel Policy (Authorization)

<!-- Only show if user can edit -->
[@if](https://github.com/if)(auth()->user()->can('edit', \App\Models\Product::class))
    [@livewire](https://github.com/livewire)('aftable', [...])
[@endif](https://github.com/endif)

With Soft Deletes

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Product',
    'customQuery' => Product::withTrashed(),  # Include deleted
])

With Scopes

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Product',
    'customQuery' => Product::active(),  # Custom scope
])

With Tenant/Multi-Tenant

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Product',
    'customQuery' => Product::whereTenantId(auth()->user()->tenant_id),
])

Version: v1.6 Optimized
Last Updated: November 23, 2025
For: AI Agents, Developers, Architects
Status: Production Ready βœ…

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle