Cinder.Table (Cinder v0.3.0)
View SourceSimplified Cinder table component with intelligent defaults.
This is the new, simplified API for Cinder tables that leverages automatic type inference and smart defaults while providing a clean, Phoenix LiveView-like interface.
Basic Usage
With Resource Parameter (Simple)
<Cinder.Table.table resource={MyApp.User} actor={@current_user}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
<:col field="created_at" sort>Created</:col>
</Cinder.Table.table>
With Query Parameter (Advanced)
<!-- Using resource as query -->
<Cinder.Table.table query={MyApp.User} actor={@current_user}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
<:col field="created_at" sort>Created</:col>
</Cinder.Table.table>
<!-- Pre-configured query with custom read action -->
<Cinder.Table.table query={Ash.Query.for_read(MyApp.User, :active_users)} actor={@current_user}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
<:col field="created_at" sort>Created</:col>
</Cinder.Table.table>
<!-- Query with base filters -->
<Cinder.Table.table query={MyApp.User |> Ash.Query.filter(department: "Engineering")} actor={@current_user}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
<:col field="department.name" filter>Department</:col>
</Cinder.Table.table>
Advanced Configuration
<Cinder.Table.table
resource={MyApp.Album}
actor={@current_user}
url_state={@url_state}
page_size={50}
theme="modern"
>
<:col field="title" filter sort class="w-1/2">
Title
</:col>
<:col field="artist.name" filter sort>
Artist
</:col>
<:col field="genre" filter={:select}>
Genre
</:col>
</Cinder.Table.table>
Complex Query Examples
<!-- Admin interface with authorization and tenant -->
<Cinder.Table.table
query={MyApp.User
|> Ash.Query.for_read(:admin_read, %{}, actor: @actor, authorize?: @authorizing)
|> Ash.Query.set_tenant(@tenant)
|> Ash.Query.filter(active: true)}
actor={@actor}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
<:col field="last_login" sort>Last Login</:col>
<:col field="role" filter={:select}>Role</:col>
</Cinder.Table.table>
Multi-Tenant Examples
<!-- Simple tenant support -->
<Cinder.Table.table
resource={MyApp.User}
actor={@current_user}
tenant={@tenant}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
</Cinder.Table.table>
<!-- Using Ash scope (only actor and tenant are extracted) -->
<Cinder.Table.table
resource={MyApp.User}
scope={%{actor: @current_user, tenant: @tenant}}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
</Cinder.Table.table>
<!-- Custom scope struct -->
<Cinder.Table.table
resource={MyApp.User}
scope={@my_scope}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
</Cinder.Table.table>
<!-- Mixed usage (explicit overrides scope) -->
<Cinder.Table.table
resource={MyApp.User}
scope={@scope}
actor={@different_actor}>
<:col field="name" filter sort>Name</:col>
<:col field="email" filter>Email</:col>
</Cinder.Table.table>
Features
- Automatic type inference from Ash resources
- Intelligent filtering with automatic filter type detection
- URL state management with browser back/forward support
- Relationship support using dot notation (e.g.,
artist.name
) - Flexible theming with built-in presets
Summary
Functions
Renders a data table with intelligent defaults.
Functions
Renders a data table with intelligent defaults.
Attributes
Resource/Query (Choose One)
resource
- Ash resource module to query (use either resource or query, not both)query
- Ash query to execute (use either resource or query, not both)
Required
actor
- Actor for authorization (can be nil)
Authorization & Tenancy
tenant
- Tenant for multi-tenant resources (default: nil)scope
- Ash scope containing actor and tenant (default: nil)
Optional Configuration
id
- Component ID (defaults to "cinder-table")page_size
- Number of items per page (default: 25)theme
- Theme preset or custom theme map (default: "default")url_state
- URL state object from UrlSync.handle_params, or false to disable URL synchronizationquery_opts
- Additional query options for Ash (default: [])on_state_change
- Callback for state changesshow_filters
- Show filter controls (default: auto-detect from columns)show_pagination
- Show pagination controls (default: true)loading_message
- Custom loading messageempty_message
- Custom empty state messageclass
- Additional CSS classes
When to Use Resource vs Query
Use resource
for:
- Simple tables with default read actions
- Getting started quickly
- Standard use cases without custom requirements
Use query
for:
- Custom read actions (e.g.,
:active_users
,:admin_only
) - Pre-filtering data with base filters
- Custom authorization settings
- Tenant-specific queries
- Admin interfaces with complex requirements
- Integration with existing Ash query pipelines
Column Slot
The :col
slot supports these attributes:
field
(required) - Field name or relationship path (e.g., "user.name")filter
- Enable filtering (boolean or filter type atom)sort
- Enable sorting (boolean)class
- CSS classes for this columnlabel
- Column header label (auto-generated from field name if not provided)
Filter types: :text
, :select
, :multi_select
, :multi_checkboxes
, :boolean
, :date_range
, :number_range
Filter Type Selection:
:multi_select
- Modern tag-based interface with dropdown (default for array types):multi_checkboxes
- Traditional checkbox interface for multiple selection
Column Labels
Column labels are automatically generated from field names using intelligent humanization:
name
→ "Name"email_address
→ "Email Address"user.name
→ "User Name"created_at
→ "Created At"
You can override the auto-generated label by providing a label
attribute.
Row Click Functionality
Tables can be made interactive by providing a row_click
function that will be
executed when a row is clicked:
<Cinder.Table.table
resource={MyApp.Item}
actor={@current_user}
row_click={fn item -> JS.navigate(~p"/items/#{item.id}") end}
>
<:col field="name" filter sort>Name</:col>
<:col field="description">Description</:col>
</Cinder.Table.table>
The row_click
function receives the row item as its argument and should return
a Phoenix.LiveView.JS command or similar action. When provided, rows will be
styled to indicate they are clickable with hover effects and cursor changes.
Attributes
resource
(:atom
) - The Ash resource to query (use either resource or query, not both). Defaults tonil
.query
(:any
) - The Ash query to execute (use either resource or query, not both). Defaults tonil
.actor
(:any
) - Actor for authorization. Defaults tonil
.tenant
(:any
) - Tenant for multi-tenant resources. Defaults tonil
.scope
(:any
) - Ash scope containing actor and tenant. Defaults tonil
.id
(:string
) - Unique identifier for the table. Defaults to"cinder-table"
.page_size
(:integer
) - Number of items per page. Defaults to25
.theme
(:any
) - Theme name or theme map. Defaults to"default"
.url_state
(:any
) - URL state object from UrlSync.handle_params, or false to disable. Defaults tofalse
.query_opts
(:list
) - Additional query options (load, select, etc.). Defaults to[]
.on_state_change
(:any
) - Custom state change handler. Defaults tonil
.show_pagination
(:boolean
) - Whether to show pagination controls. Defaults totrue
.show_filters
(:boolean
) - Whether to show filter controls (auto-detected if nil). Defaults tonil
.loading_message
(:string
) - Message to show while loading. Defaults to"Loading..."
.empty_message
(:string
) - Message to show when no results. Defaults to"No results found"
.class
(:string
) - Additional CSS classes. Defaults to""
.row_click
(:any
) - Function to call when a row is clicked. Receives the row item as argument. Defaults tonil
.
Slots
col
(required) - Accepts attributes:field
(:string
) (required) - Field name (supports dot notation for relationships).filter
(:any
) - Enable filtering (true, false, or filter type atom).filter_options
(:list
) - Custom filter options (e.g., [options: [{"Label", "value"}]]).sort
(:boolean
) - Enable sorting.label
(:string
) - Custom column label (auto-generated if not provided).class
(:string
) - CSS classes for this column.