Table layout and presentation DSL
v0.0.1
The layout, empty_state, error_state and presentation sections of a resource's table block set the header, footer and notices around the table, what an empty or failed table says, and which template, UI adapter and theme draw it.
layout
The layout section has no options of its own. It holds the header, footer and notice entities, which draw the chrome around the table.
header
A title and description drawn above the toolbar. It sits at mishka_gervaz.table.layout.header.
| Option | Type | Default | Description |
|---|---|---|---|
title | String.t | (-> any) | (any -> any) | none | Header title. String, fn -> _ end, or fn state -> _ end. |
description | String.t | (-> any) | (any -> any) | none | Header description. String, fn -> _ end, or fn state -> _ end. |
icon | String.t | none | Heroicon name (e.g., "hero-document-text"). |
class | String.t | none | CSS classes for the header wrapper. |
visible | boolean | (any -> any) | true | Static or dynamic visibility. fn state -> boolean() end. |
restricted | boolean | (any -> any) | false | Restrict to master users. true or fn state -> boolean() end. |
render | (any -> any) | (any, any -> any) | none | Custom HEEx render. fn assigns -> ~H"..." end or fn assigns, state -> ~H"..." end. |
extra | map | %{} | Additional template-specific options. The value is compiled into the config, but no built-in template or handler reads it. |
footer
Static content drawn below the pagination. It sits at mishka_gervaz.table.layout.footer.
| Option | Type | Default | Description |
|---|---|---|---|
content | String.t | (-> any) | (any -> any) | none | Footer content. String, fn -> _ end, or fn state -> _ end. |
class | String.t | none | CSS classes for the footer wrapper. |
visible | boolean | (any -> any) | true | Static or dynamic visibility. fn state -> boolean() end. |
restricted | boolean | (any -> any) | false | Restrict to master users. true or fn state -> boolean() end. |
render | (any -> any) | (any, any -> any) | none | Custom HEEx render. fn assigns -> ~H"..." end or fn assigns, state -> ~H"..." end. |
extra | map | %{} | Additional template-specific options. The value is compiled into the config, but no built-in template or handler reads it. |
notice
A static alert or banner with a position and an optional binding. It sits at mishka_gervaz.table.layout.notice.
Call: notice name
Arguments:
| Argument | Type | Default | Description |
|---|---|---|---|
name | atom | none | Required. Unique notice identifier (used for dismiss tracking). |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
position | any | :table_top | Where the notice is drawn. Valid atoms and tuples are listed below the table. The default is :table_top. |
type | :info | :warning | :error | :success | :neutral | :info | Visual style: :info, :warning, :error, :success, or :neutral. |
title | String.t | (-> any) | (any -> any) | none | Notice title. String, fn -> _ end, or fn state -> _ end. |
content | String.t | (-> any) | (any -> any) | none | Notice body. String, fn -> _ end, or fn state -> _ end. |
icon | String.t | none | Heroicon name. |
dismissible | boolean | false | Lets the reader close the notice. Gervaz tracks dismissal by notice name. |
bind_to | nil | :no_results | :has_filters | :has_selection | :loading | :error | :archived_view | none | Draws the notice only while a condition holds. See the list below the table. Combined with show_when using AND. |
show_when | (any -> any) | none | Custom predicate fn state -> boolean() end. Combined with bind_to (AND). |
visible | boolean | (any -> any) | true | Static or dynamic visibility. fn state -> boolean() end. |
restricted | boolean | (any -> any) | false | Restrict to master users. true or fn state -> boolean() end. |
render | (any -> any) | (any, any -> any) | none | Custom HEEx render. fn assigns -> ~H"..." end or fn assigns, state -> ~H"..." end. |
Valid position values:
| Position | Where the notice is drawn |
|---|---|
:table_top | Above everything in the table region. The default. |
:before_header, :after_header | Around the table header. |
:before_filters, :after_filters | Around the filter bar. |
:before_bulk_actions, :after_bulk_actions | Around the bulk action bar. |
:before_table, :after_table | Around the table itself. |
:before_pagination, :after_pagination | Around the pagination row. |
:table_bottom | The last slot in the table region. |
:empty_state | The empty-state area. The built-in template draws it whether or not the table has rows. |
{:before_column, name}, {:after_column, name} | Gervaz validates these, and no built-in template draws a notice there. |
Valid bind_to values:
| Value | The notice shows while |
|---|---|
:no_results | The stream is empty after a load. |
:has_filters | Any filter has a value. |
:has_selection | Any row is selected. |
:loading | The table is loading. |
:error | The load returned an error. |
:archived_view | The reader is viewing archived records. |
notice ui
Classes for the notice. It sits at mishka_gervaz.table.layout.notice.ui.
| Option | Type | Default | Description |
|---|---|---|---|
class | String.t | none | CSS classes for the notice wrapper. |
extra | map | %{} | Additional template-specific options. The value is compiled into the config, but no built-in template or handler reads it. |
empty_state
What the table shows when there are no records. Declare it inline or as a block. It sits at mishka_gervaz.table.empty_state.
| Option | Type | Default | Description |
|---|---|---|---|
message | String.t | "No records found" | Empty state message. |
icon | String.t | none | Icon identifier. |
action_label | String.t | none | Label of a call-to-action link drawn under the message. Give action_label and action_path. action_icon is optional. |
action_path | String.t | none | Call-to-action button path. |
action_icon | String.t | none | Call-to-action button icon. |
error_state
What the table shows when a load fails. Declare it inline or as a block. It sits at mishka_gervaz.table.error_state.
| Option | Type | Default | Description |
|---|---|---|---|
message | String.t | "Error loading data" | Error message. The value is compiled into the config, but no built-in template or handler reads it. The built-in templates do not draw the error state from it. |
icon | String.t | none | Icon identifier. The value is compiled into the config, but no built-in template or handler reads it. The built-in templates do not draw the error state from it. |
retry_label | String.t | "Retry" | Retry button label. The value is compiled into the config, but no built-in template or handler reads it. The built-in templates do not draw the error state from it. |
presentation
Picks the template, the UI adapter, the features and the filter mode. It sits at mishka_gervaz.table.presentation.
| Option | Type | Default | Description |
|---|---|---|---|
filter_mode | :inline | :sidebar | :modal | :drawer | :inline | Where the filter bar draws. :inline draws it above the table, and :sidebar draws a side column. :modal and :drawer draw a Filters button whose toggle_filters event has no handler, so they open nothing. Gervaz ignores this option when the table declares filter_groups. |
template | atom | module | MishkaGervaz.Table.Templates.Table | The template module that arranges the table. Built in: MishkaGervaz.Table.Templates.Table (the default) and MishkaGervaz.Table.Templates.MediaGallery. |
switchable_templates | list(atom | module) | [] | Templates the reader can switch between. With two or more, the template switcher shows. An empty list turns switching off. |
template_options | keyword | [] | Options passed to the template. The Table template reads :striped and :hoverable. MediaGallery reads :columns, :overlay_action, :primary_action and :class. A template ignores a key it does not read. |
keep_loaded_records | boolean | false | Keeps every loaded page in state.loaded_records for a template that groups rows under headings and so cannot draw from a stream. It holds the loaded rows in the LiveView's memory, so turn it on only for a grouped template. |
features | :all | list(:sort | :filter | :select | :bulk_actions | :paginate | :export | :expand | :reorder | :inline_edit) | :all | :all uses the union of what the template and every switchable template support, minus :paginate when the table has no pagination. A list narrows it, and [] turns everything off. Accepted: :sort, :filter, :select, :bulk_actions, :paginate, :export, :expand, :reorder and :inline_edit. The built-in templates act on :sort, :filter, :select, :bulk_actions, :paginate and :expand only. |
ui_adapter | atom | module | MishkaGervaz.UIAdapters.Tailwind | The UI adapter module that draws buttons, inputs, badges and cells. MishkaGervaz.UIAdapters.Tailwind is the default. Build your own with use MishkaGervaz.Behaviours.UIAdapter. |
ui_adapter_opts | keyword | [] | Options for the adapter. With ui_adapter MishkaGervaz.UIAdapters.Dynamic, Gervaz builds <Resource>.GervazUIAdapter from :site (default "Global"), :fallback, :component_renderer and :module_resolver. Gervaz checks Dynamic first, so :component_module is ignored with it. With :component_module and another adapter, Gervaz builds <Resource>.GervazUIAdapter that calls the matching functions of that module, using :fallback, :nested_components, :module_prefix and :component_prefix. |
theme
Theme classes. It sits at mishka_gervaz.table.presentation.theme.
| Option | Type | Default | Description |
|---|---|---|---|
header_class | String.t | none | Header row CSS classes. |
row_class | String.t | none | Data row CSS classes. |
border_class | String.t | none | Border CSS classes. The value is compiled into the config, but no built-in template or handler reads it. |
extra | map | %{} | Template-specific theming options. The value is compiled into the config, but no built-in template or handler reads it. |
responsive
Responsive settings. It sits at mishka_gervaz.table.presentation.responsive.
| Option | Type | Default | Description |
|---|---|---|---|
hide_on_mobile | list(atom) | [] | Columns to hide on mobile. The value is compiled into the config, but no built-in template or handler reads it. |
hide_on_tablet | list(atom) | [] | Columns to hide on tablet. The value is compiled into the config, but no built-in template or handler reads it. |
mobile_layout | :cards | :stacked | none | Layout mode on mobile. The value is compiled into the config, but no built-in template or handler reads it. |