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 Package - Complete Reference

Version: 1.6.0
Latest Update: July 2025
Status: ✅ Production Ready


📚 Documentation Files

Quick Start (Start Here!)

Advanced Topics


🚀 Quick Start

Basic Table (3 seconds)

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Item',
    'columns' => [
        ['key' => 'name', 'label' => 'Item Name'],
        ['key' => 'price', 'label' => 'Price'],
        ['key' => 'created_at', 'label' => 'Created'],
    ],
])

With Sorting

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Item',
    'columns' => [
        ['key' => 'name', 'label' => 'Item Name'],
        ['key' => 'price', 'label' => 'Price'],
        ['key' => 'created_at', 'label' => 'Created'],
    ],
    'sortBy' => 'created_at',
    'sort'   => 'desc',
])

⚡ Static / Foreach Mode (v1.6.0)

Pass any PHP array or Laravel Collection directly — no Eloquent model required. Best for: API responses, computed/aggregated data, small datasets.

[@php](https://github.com/php)
$employees = [
    ['name' => 'Alice', 'salary' => 5000, 'dept' => 'Engineering'],
    ['name' => 'Bob',   'salary' => 4500, 'dept' => 'Design'],
];
[@endphp](https://github.com/endphp)

[@livewire](https://github.com/livewire)('aftable', [
    'data'    => $employees,
    'vars'    => ['currency' => 'USD'],
    'columns' => [
        ['key' => 'name',   'label' => 'Name'],
        ['key' => 'dept',   'label' => 'Department'],
        ['key' => 'salary', 'label' => 'Salary',
         'raw' => '{{ $currency }} {{ number_format($row->salary, 2) }}'],
    ],
])

Static mode features: in-memory search, sort, and pagination — fully reactive.


🎨 Custom Table Template (v1.6.0)

Render the table using your app's own table markup instead of the default Bootstrap one.

Using [@aftable](https://github.com/aftable) / [@endaftable](https://github.com/endaftable) directives

[@aftable](https://github.com/aftable)(['model' => App\Models\User::class, 'columns' => [...]])
    <table class="table table-hover table-striped my-theme-class">
        <thead class="bg-dark text-white"><tr></tr></thead>
        <tbody></tbody>
    </table>
[@endaftable](https://github.com/endaftable)

The component extracts your <table> tag's attributes and applies them while still rendering all the standard headers, rows, search, filters, and pagination.

Using customTemplate parameter directly

[@livewire](https://github.com/livewire)('aftable', [
    'model'          => App\Models\User::class,
    'columns'        => [...],
    'customTemplate' => '<table class="table table-hover my-theme" id="myTable">',
])

🧩 Raw Column Templates

Blade String (full Blade syntax)

['key' => 'status', 'label' => 'Status',
 'raw' => '<span class="badge bg-{{ $row->active ? \'success\' : \'danger\' }}">
               {{ $row->active ? \'Active\' : \'Inactive\' }}
           </span>'],

Closure / Callable (faster — zero Blade overhead)

['key' => 'status', 'label' => 'Status',
 'raw' => fn($row) => $row->active
     ? '<span class="badge bg-success">Active</span>'
     : '<span class="badge bg-danger">Inactive</span>'],

// With extra vars ($vars is your 'vars' array)
['key' => 'price', 'label' => 'Price',
 'raw' => fn($row, $vars) => e($vars['currency']).' '.number_format($row->price, 2)],

PHP Calculations in Blade

['key' => 'total', 'label' => 'Total', 'sortable' => false,
 'raw' => '{{ number_format($row->price * $row->qty, 2) }}'],

🎨 Dynamic CSS Classes (v1.6.0 — no eval())

The classCondition map now uses closures or safe shorthand (no more eval()):

'classCondition' => [
    // Closure (most flexible)
    'text-success fw-bold' => fn($row) => $row->active,
    
    // Boolean literal
    'opacity-50' => false,
    
    // Truthy shorthand — truthy check: !!$row->featured
    'border-primary' => 'featured',
    
    // Negation shorthand — !$row->active
    'text-muted' => '!active',
    
    // Equality shorthand — $row->status === 'inactive'
    'text-danger' => 'status:inactive',
],

📋 All Mount Parameters

Parameter Type Default Description
model class-string null Eloquent model class (Eloquent mode)
data array|Collection null Static rows (static mode)
vars array [] Extra variables available in all raw templates
columns array [] Column definitions
filters array [] Filter configuration
actions array [] Row action buttons
sortBy string null Default sort column
sort string 'desc' Default sort direction
customTemplate string null Custom <table> HTML for theming
query array|Closure null Extra query constraints
searchable bool true Enable global search
exportable bool false Show export dropdown
printable bool false Show print button
index bool false Show row index column
checkbox bool false Row selection checkboxes
colvisBtn bool true Column visibility toggle
refreshBtn bool false Manual refresh button
records int 10 Rows per page
dateColumn string null Column for date range filter

With Related Data (7 seconds)

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Item',
    'columns' => [
        ['key' => 'name', 'label' => 'Item Name'],
        ['key' => 'category_name', 'label' => 'Category', 'relation' => 'category:name'],
        ['key' => 'reviews_count', 'label' => 'Reviews'],
    ],
    'sortBy' => 'category_name',
    'sortDirection' => 'asc',
])

✨ Key Features

⚡ Performance

  • Single Query: 50 items = 1 database query (not 51)
  • Eager Loading: Auto-loads relationships (no N+1)
  • Count Aggregation: Efficient relationship counting
  • Query Caching: 5-minute TTL for repeated queries
  • Chunked Export: Handle 100K+ records without memory issues

🔍 Search

  • Multi-Column: Search across all text columns
  • Relations: Search in related model data
  • JSON: Search inside JSON columns
  • Smart: Case-insensitive, partial matching
  • Debounced: Optimized queries

🔀 Sorting

  • Database: Sort by any column
  • Relations: Sort by related data
  • Counts: Sort by aggregated counts
  • JSON: Sort by JSON values
  • JOINs: Automatic efficient joins

🎨 Display

  • Column Toggle: Users show/hide columns
  • Session Persist: Remembers preferences
  • Dark Mode: Bootstrap 5 compatible
  • Responsive: Mobile-friendly tables
  • Customizable: CSS classes supported

💾 Export

  • CSV: Plain text format
  • Excel: Formatted spreadsheet
  • PDF: Printable document
  • Smart: Only visible columns
  • Chunked: Large files handled

🔒 Security

  • XSS Protection: HTML sanitized
  • SQL Safe: Parameterized queries
  • Auth Check: Per-user filtering
  • Session Isolation: User data protected

📋 Real-World Examples

Financial Transactions (Sorted by Date)

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\AccountFlow\Transaction',
    'columns' => [
        ['key' => 'date', 'label' => 'Date'],
        ['key' => 'amount', 'label' => 'Amount'],
        ['key' => 'type', 'label' => 'Type'],
        ['key' => 'category_id', 'relation' => 'category:name', 'label' => 'Category'],
        ['key' => 'account_id', 'relation' => 'account:name', 'label' => 'Account'],
        ['key' => 'description', 'label' => 'Description'],
    ],
    'sortBy' => 'date',
    'sortDirection' => 'desc',      // Newest transactions first
    'records' => 25,
])

E-Commerce Products

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Product',
    'columns' => [
        ['key' => 'sku', 'label' => 'SKU'],
        ['key' => 'name', 'label' => 'Product'],
        ['key' => 'category_name', 'label' => 'Category', 'relation' => 'category:name'],
        ['key' => 'price', 'label' => 'Price'],
        ['key' => 'stock', 'label' => 'Stock'],
        ['key' => 'reviews_count', 'label' => 'Reviews'],
    ],
    'sortBy' => 'price',
    'sortDirection' => 'desc',      // Most expensive first
    'searchable' => true,
    'showExport' => true,
])

User Management

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\User',
    'columns' => [
        ['key' => 'name', 'label' => 'Full Name'],
        ['key' => 'email', 'label' => 'Email'],
        ['key' => 'role', 'label' => 'Role'],
        ['key' => 'organization_name', 'label' => 'Organization', 'relation' => 'organization:name'],
        ['key' => 'created_at', 'label' => 'Member Since'],
    ],
    'sortBy' => 'name',
    'sortDirection' => 'asc',       // A to Z
    'records' => 50,
])

🎯 Sorting Deep Dive

Basic Sorting

'sortBy' => 'column_key',           // Initial sort column
'sortDirection' => 'asc|desc',      // Initial direction

Relationship Sorting

'columns' => [
    ['key' => 'customer_name', 'label' => 'Customer', 'relation' => 'customer:name'],
],
'sortBy' => 'customer_name',        // Sorts by customer.name via JOIN

Count Sorting

'columns' => [
    ['key' => 'items_count', 'label' => 'Items'],  // Auto-detected
],
'sortBy' => 'items_count',          // Sorts by COUNT(items)

Sortable vs Non-Sortable

Type Sortable Example
Database Column ['key' => 'name']
Simple Relation ['relation' => 'user:name']
Count Column ['key' => 'items_count']
JSON Column ['json' => 'field']
Function Column ['function' => 'getStatus']
Raw HTML ['raw' => '<button>']
Nested Relation ['relation' => 'user.profile:name']

🔍 Advanced Filtering

Multiple Columns

'filters' => [
    'status' => ['type' => 'select'],
    'price' => ['type' => 'number'],
    'date' => ['type' => 'date'],
],

Filter Types

  • text - Text input (3+ characters)
  • number - Number with operators (<, >, =, etc.)
  • date - Date picker
  • select - Dropdown
  • distinct - Auto-populated from data

📊 Column Configuration

Simple Column

['key' => 'name', 'label' => 'Product Name']

Related Data

['key' => 'category_name', 'label' => 'Category', 'relation' => 'category:name']

Count

['key' => 'items_count', 'label' => 'Items']

JSON Extract

['key' => 'data', 'label' => 'Color', 'json' => 'color']

Custom HTML

['key' => 'price', 'label' => 'Price', 'raw' => '₹{{ $row->price }}']

Function

['key' => 'status', 'label' => 'Status', 'function' => 'getStatus']

🎛️ All Parameters

[@livewire](https://github.com/livewire)('aftable', [
    // Required
    'model' => 'App\Models\Item',
    'columns' => [...],
    
    // Sorting
    'sortBy' => 'column_key',
    'sortDirection' => 'asc|desc',
    
    // Pagination
    'records' => 50,
    
    // Search
    'searchable' => true,
    
    // Filters
    'filters' => [...],
    
    // Export
    'showExport' => true,
    'exportFormats' => ['csv', 'excel', 'pdf'],
    
    // UI
    'colvisBtn' => true,            // Column visibility toggle
    'refreshBtn' => false,          // Refresh button
    'printable' => false,           // Print button
    'index' => true,                // Row numbers
    
    // Advanced
    'customQuery' => Builder,       // Custom Eloquent query
    'data' => Collection,           // Pre-loaded data
])

📈 Performance Tips

✅ DO

  1. Use relation for related data

    ['key' => 'category_name', 'relation' => 'category:name']
    
  2. Use count columns for aggregates

    ['key' => 'items_count']  // Auto-detected
    
  3. Leverage sorting for fast data access

    'sortBy' => 'created_at', 'sortDirection' => 'desc'
    
  4. Set reasonable page size

    'records' => 50  // Not 1000+
    
  5. Enable search instead of scrolling

    'searchable' => true
    

❌ DON'T

  1. Load relationships manually in columns
  2. Count relationships in PHP code
  3. Use nested relations for sorting
  4. Display 50+ columns in table
  5. Set records to 1000+ by default

🐛 Troubleshooting

Sorting Doesn't Work

Problem: Clicking headers doesn't sort

Solution: Ensure column is in database

// ✅ Works
['key' => 'email', 'label' => 'Email']

// ❌ Doesn't work (if not in DB)
['key' => 'full_name', 'label' => 'Full Name']  // Computed property

Related Data Shows Null

Problem: Relationship column is empty

Solution: Check relation format

// ❌ Wrong
['key' => 'category_id', 'relation' => 'category']

// ✅ Correct
['key' => 'category_id', 'relation' => 'category:name']

Search Returns Nothing

Problem: Search doesn't find data

Solution: Only text columns are searchable

// ✅ Searchable
['key' => 'name', 'label' => 'Name']

// ❌ Not searchable
['key' => 'price', 'label' => 'Price']  // Number field

Slow Performance

Problem: Table takes >1 second to load

Solution: Check for N+1 queries

// ❌ Bad - 51 queries
'columns' => [['key' => 'user_name', 'label' => 'User']]  // Manual fetch

// ✅ Good - 1 query
'columns' => [['key' => 'user_name', 'label' => 'User', 'relation' => 'user:name']]

📚 Documentation Structure

docs/
├── SORTING_GUIDE.md              (NEW!) Complete sorting guide
├── ENHANCED_FEATURES.md          (NEW!) Advanced features
├── AI_USAGE_GUIDE.md             Quick practical guide
├── USAGE_STUB.md                 All parameters
├── AI_TECHNICAL_REFERENCE.md     Technical deep-dive
└── README.md                      This file

📊 Performance Benchmarks

Single Query Design

Dataset Items Sorting Search Time Queries
Small 50 45ms 1
Medium 500 85ms 1
Large 5,000 150ms 1
XL 50,000 250ms 1

Export Performance

Format Rows Time Memory
CSV 10K 450ms 8MB
Excel 10K 650ms 12MB
PDF 10K 1.2s 15MB

🎯 Version History

v1.5.2 (Latest - Dec 30, 2025)

  • ✨ New sortBy parameter support
  • ✨ New SORTING_GUIDE.md documentation
  • ✨ New ENHANCED_FEATURES.md guide
  • 🐛 Fixed Blade template rendering
  • 🚀 Improved UI/UX for search and filters
  • 📈 Better mobile responsiveness

v1.5.1

  • Added JSON column support
  • Enhanced count aggregations
  • Improved session persistence

v1.5.0

  • Initial public release
  • Trait-based architecture
  • Performance optimization

📞 Support & Resources

  • Package: artflow-studio/table
  • Developer: ArtFlow Studio
  • Site: https://artflow.pk
  • PHP: 8.0+
  • Laravel: 11+
  • Livewire: 3+

📝 Quick Reference Card

# Installation
composer require artflow-studio/table

# Update
composer update artflow-studio/table

# No additional setup needed!
# Component auto-registers with Laravel 5.5+

Blade Usage

[@livewire](https://github.com/livewire)('aftable', [
    'model' => 'App\Models\Item',
    'columns' => [...],
    'sortBy' => 'created_at',
    'sortDirection' => 'desc',
])

Sorting Parameters

'sortBy' => 'column_key'              // Column to sort by
'sortDirection' => 'asc'|'desc'       // Direction
'sort' => 'asc'|'desc'                // Legacy (backward compat)

Feature Toggles

'searchable' => true                  // Enable search
'showExport' => true                  // Export button
'colvisBtn' => true                   // Column visibility
'refreshBtn' => false                 // Refresh button
'printable' => false                  // Print button
'index' => true                       // Row numbers

✅ Checklist Before Production

  • Installed artflow-studio/table
  • Configured columns correctly
  • Set sortBy for initial sort
  • Tested on multiple browsers
  • Verified performance (< 1s load)
  • Checked with users (at least 100 rows)
  • Enabled export if needed
  • Set up search if applicable
  • Tested on mobile devices
  • Read SORTING_GUIDE.md for advanced sorting

Status: ✅ Production Ready
Last Updated: December 30, 2025
Version: 1.5.2+

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