Cinder.Collection (Cinder v0.18.1)

Copy Markdown View Source

The collection component, used as <Cinder.collection>. Its attributes and slots are listed below.

layout chooses how records are shown, and every layout shares filtering, sorting, search and pagination:

  • :table (the default): each <:col> is a column, and clicking a heading sorts by it.
  • :list and :grid: an <:item> slot shows each record, and the <:col> slots only say which fields can be filtered, sorted and searched. Sorting is a row of buttons above the items.
<Cinder.collection resource={MyApp.User} actor={@current_user}>
  <:col :let={user} field="name" filter sort>{user.name}</:col>
  <:col :let={user} field="email" filter>{user.email}</:col>
</Cinder.collection>

<Cinder.collection resource={MyApp.Product} actor={@current_user} layout={:grid} grid_columns={4}>
  <:col field="name" filter sort search />
  <:col field="category" filter />

  <:item :let={product}>
    <h3 class="font-bold">{product.name}</h3>
    <p>{product.category}</p>
  </:item>
</Cinder.collection>

The :controls slot lays out the filters and search box yourself, with the helpers in Cinder.Controls:

<Cinder.collection resource={MyApp.User} actor={@current_user}>
  <:col :let={user} field="name" filter sort search>{user.name}</:col>
  <:col :let={user} field="status" filter={:select}>{user.status}</:col>

  <:controls :let={controls}>
    <Cinder.Controls.render_header {controls} />
    <Cinder.Controls.render_search search={controls.search} theme={controls.theme} target={controls.target} />
    <div class="grid grid-cols-2 gap-4">
      <Cinder.Controls.render_filter
        :for={{_field, filter} <- controls.filters}
        filter={filter}
        theme={controls.theme}
        target={controls.target}
        raw_filter_params={controls.raw_filter_params}
      />
    </div>
  </:controls>
</Cinder.collection>

See the Getting Started, Filters, Sorting and Advanced Features guides for each feature.

Summary

Functions

Builds the list of columns used for query operations (filtering AND searching).

Process column definitions into the format expected by the underlying component.

Process filter-only slot definitions into the format expected by the filter system.

Process unified search configuration into individual components. Returns {label, placeholder, enabled, search_fn}.

Functions

build_query_columns(processed_columns, processed_filter_slots)

Builds the list of columns used for query operations (filtering AND searching).

This function combines:

  • Filterable columns: needed for filter application
  • Searchable columns: needed for search even if not filterable
  • Filter-only slots: dedicated filter controls not tied to display columns

NOTE: Sortable-only columns are NOT included here - sorting uses display_columns because sort controls are tied to column headers.

Raises ArgumentError if the same field is defined in both a filterable column and a filter-only slot.

collection(assigns)

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.
  • action (:atom) - The read action to use. Defaults to the primary read action. Defaults to nil.
  • actor (:any) - Actor for authorization. Defaults to nil.
  • tenant (:any) - Tenant for multi-tenant resources. Defaults to nil.
  • scope (:any) - An Ash scope, for the actor, tenant and context. Defaults to nil.
  • layout (:any) - Layout type: :table, :list, or :grid (also accepts strings). Defaults to :table.
  • id (:string) - The collection's id. Each collection on a page needs its own. Defaults to "cinder-collection".
  • page_size (:any) - Records per page: a number, or [default: 25, options: [10, 25, 50]] to let users choose. Defaults to config :cinder, default_page_size, or 25. Defaults to nil.
  • theme (:any) - A built-in theme's name, or a module using Cinder.Theme. Defaults to config :cinder, default_theme. Defaults to "default".
  • url_state (:any) - @url_state, assigned by use Cinder.UrlSync, to keep the collection's state in the URL. Defaults to false.
  • query_opts (:list) - Additional Ash query options: :load, :select, :tenant, :timeout, :authorize?, :max_concurrency and :tracer. Any other key logs a warning and is ignored. Columns' fields are loaded already; :load is for anything else slots show. Defaults to [].
  • initial_load (:any) - :async (default) loads data after the page renders; :sync loads it before, putting the first page of data in the server-rendered HTML at the cost of blocking the mount. Can also be set globally via config :cinder, default_initial_load: :sync. Defaults to nil.
  • on_state_change (:any) - The message sent to the parent when filters, sorting or the page change, as {name, id, encoded_state}. Cinder.UrlSync relies on its own, so leave this unset on a URL-synced collection. Defaults to nil.
  • on_query_change (:any) - Event name sent to parent when the query changes. Parent receives {event_name, %{query: Ash.Query.t(), count: integer() | nil, id: string()}}. Defaults to nil.

  • show_pagination (:boolean) - Whether to show pagination controls. Defaults to true.
  • pagination (:any) - Pagination mode: :offset (default) or :keyset. Keyset pagination is faster for large datasets but only supports prev/next navigation. Also accepts a keyword list: [mode: :keyset, count: :async], where count is true (default, counted with each page), :async (counted in the background) or false (never counted). Defaults to :offset.
  • show_filters (:any) - Controls filter visibility. true = always visible, false = hidden, nil = auto-detect, :toggle/"toggle" = collapsible starting collapsed, :toggle_open/"toggle_open" = collapsible starting expanded. Can also be set globally via config :cinder, show_filters: :toggle. Defaults to nil.
  • show_sort (:boolean) - Whether to show sort controls (auto-detected if nil, list/grid only). Defaults to nil.
  • sort_mode (:any) - How sorting by another column combines with the current sort: :additive adds to it, :exclusive replaces it (also accepts strings). Defaults to :additive. Must be one of :additive, :exclusive, "additive", or "exclusive".
  • loading_message (:string) - Message to show while loading. Defaults to nil.
  • filters_label (:string) - Label for the filters component (defaults to translated "Filters"). Defaults to nil.
  • sort_label (:string) - Label for sort button group (defaults to translated "Sort by:"). Defaults to nil.
  • search (:any) - The search box: shown when a column has search. false hides it, and [label: ..., placeholder: ..., fn: ...] changes its label and placeholder, or searches with your own fn(query, searchable_columns, text). Defaults to nil.
  • empty_message (:string) - Message to show when no results. Defaults to nil.
  • error_message (:string) - Message to show on error. Defaults to nil.
  • class (:string) - Additional CSS classes for the outer container. Defaults to "".
  • container_class (:string) - Override the item container CSS class (list/grid only). Defaults to nil.
  • grid_columns (:any) - Number of grid columns. Integer (e.g., 4) or keyword list (e.g., [xs: 1, md: 2, lg: 3]). Defaults to [xs: 1, md: 2, lg: 3].
  • click (:any) - Function to call when a row/item is clicked. Receives the item as argument. Defaults to nil.
  • item_class (:any) - CSS class(es) for each row/item. A string, or a fn item -> class end function evaluated per item, appended to the theme's row/item class. Defaults to nil.
  • id_field (:atom) - The field identifying each record, for selection and the Cinder.Update functions. Defaults to :id.
  • selectable (:any) - Enable row/item selection via checkboxes. Accepts true/false to enable for all rows, or a predicate fn item -> boolean end to make only matching rows selectable. Defaults to false.
  • on_selection_change (:any) - Event name (atom or string) sent to parent when selection changes. Parent receives {event_name, %{selected_ids: MapSet.t(), selected_count: integer(), component_id: string(), action: atom()}}. Defaults to nil.

Slots

  • col - Accepts attributes:
    • field (:string) - Field name (supports dot notation for relationships or __ for embedded attributes).
    • filter (:any) - Enable filtering (true, false, filter type atom, or unified config).
    • sort (:any) - Enable sorting (true, false, or unified config [cycle: [nil, :asc, :desc], then: ["inserted_at"]]).
    • search (:boolean) - Enable global search on this column.
    • label (:string) - Custom column label (auto-generated if not provided).
    • class (:string) - CSS classes for table column (table layout only).
  • item - Template for rendering each item (required for list/grid layouts).
  • filter - Filter-only slots for filtering without display columns. Accepts attributes:
    • field (:string) (required) - Field name to filter on.
    • type (:any) - Filter type, as an atom or string (:text, :select, ...): from the field's type if not given.
    • label (:string) - Custom filter label.
    • options (:list) - {label, value} tuples, for filters that list options.
    • value (:any) - Default or fixed value for checkbox filters.
    • operator (:atom) - Text filter operator: :contains (default), :starts_with, :ends_with or :equals.
    • case_sensitive (:boolean) - Whether text filtering is case-sensitive.
    • placeholder (:string) - Placeholder text for filter input.
    • labels (:map) - Custom labels for boolean filter options.
    • prompt (:string) - Prompt text for select filters.
    • match_mode (:atom) - Match mode for multi-value filters (:any or :all).
    • include_time (:boolean) - Whether to include time in date filters.
    • step (:any) - Step value for number range filters.
    • min (:any) - Minimum value for range filters.
    • max (:any) - Maximum value for range filters.
    • max_results (:integer) - Maximum number of options an autocomplete filter shows.
    • fn (:fun) - Custom filter function (fn query, filter_config -> query).
  • bulk_action - Accepts attributes:
    • action (:any) (required) - Ash action atom or function/2 receiving (query, opts) like code interface functions.
    • label (:string) - Button label text. Supports {count} interpolation. If provided, renders a themed button.
    • variant (:atom) - Button style: :primary (solid), :secondary (outline), :danger (destructive). Default: :primary. Must be one of :primary, :secondary, or :danger.
    • action_opts (:list) - Additional options passed to the Ash action (e.g., [return_records?: true, notify?: true]).
    • confirm (:string) - Confirmation message. Supports {count} interpolation for selected count.
    • on_success (:atom) - Message name sent to parent via handle_info on success. Payload: %{component_id, action, count, result}.
    • on_error (:atom) - Message name sent to parent via handle_info on error. Payload: %{component_id, action, reason, partial}.
  • controls - Custom layout for the filter/search controls area. Receives a controls data map via :let with filters, search, and metadata. Use Cinder.Controls helpers to render individual filters, search, and headers.
  • loading - Custom loading state content.
  • empty - Custom empty state content.
  • error - Custom error state content.

process_columns(col_slots, resource)

Process column definitions into the format expected by the underlying component.

process_filter_slots(filter_slots, resource)

Process filter-only slot definitions into the format expected by the filter system.

process_search_config(search_config, columns)

Process unified search configuration into individual components. Returns {label, placeholder, enabled, search_fn}.