Cinder.Table (Cinder v0.3.0)

View Source

Simplified 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

table(assigns)

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 synchronization
  • query_opts - Additional query options for Ash (default: [])
  • on_state_change - Callback for state changes
  • show_filters - Show filter controls (default: auto-detect from columns)
  • show_pagination - Show pagination controls (default: true)
  • loading_message - Custom loading message
  • empty_message - Custom empty state message
  • class - 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 column
  • label - 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 to nil.
  • query (:any) - The Ash query to execute (use either resource or query, not both). Defaults to nil.
  • actor (:any) - Actor for authorization. Defaults to nil.
  • tenant (:any) - Tenant for multi-tenant resources. Defaults to nil.
  • scope (:any) - Ash scope containing actor and tenant. Defaults to nil.
  • id (:string) - Unique identifier for the table. Defaults to "cinder-table".
  • page_size (:integer) - Number of items per page. Defaults to 25.
  • 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 to false.
  • query_opts (:list) - Additional query options (load, select, etc.). Defaults to [].
  • on_state_change (:any) - Custom state change handler. Defaults to nil.
  • show_pagination (:boolean) - Whether to show pagination controls. Defaults to true.
  • show_filters (:boolean) - Whether to show filter controls (auto-detected if nil). Defaults to nil.
  • 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 to nil.

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.