Table Front

Renders a toolbar above a table with search, actions, filter presets and record counts.

Read more Read less

The first row contains the search form and any actions supplied through the default slot, aligned to the right. The second row places filter navigation on the left and record counts on the right, in a shared horizontal flex container. Filter tabs scroll horizontally when space is limited. This row is omitted when neither filters nor a count are provided.

Search and additional fields

Search is enabled by default. The input is named query, uses a 200 ms debounce, and the form sends the "search" event on both change and submit. Use search_input_value to reflect the current query and search_input_placeholder to customize its placeholder.

Add fields to the same form with <:form :let={f}>, which receives the form. Setting search={false} hides only the search input; additional form fields and actions remain available. When id is supplied, the form ID is "<id>_search_form".

Filter presets

Supply one <:filters> slot per preset, with the tab label as its content. Each preset accepts sorting, filters, color and an optional count. Omitted sorting and filters default to []; the default color is :default. The navigation has a rounded outer border. Inactive tabs use their configured text color; the active tab has a rounded background in its configured color. Counts appear beside the labels.

With presets, patch must be a two-argument function receiving the preset's sorting and filters and returning a URL. Links perform a LiveView patch; the parent handles the URL parameters and updates the table. The callback is also responsible for preserving any query parameters that should survive, such as search.

A preset is active when both its sorting and filters match current_sorting and current_filters. Atoms and strings are treated equivalently. Sorting order matters; filter column order and option order do not, and empty option lists are ignored. Clicking an active preset reapplies it. A preset with no sorting or filters calls patch.([], []) and can serve as a reset button.

Counts

count displays the total beside count_label, which defaults to "enregistrement". The label is used as supplied for one record, with "s" appended otherwise. When selected_count is provided, the display becomes selected_count / count. A count of zero is displayed; false or nil hides the counter. selected_count is only shown when count is visible. Use count_class to extend its styling.

Each preset's optional count appears in parentheses; zero is displayed and nil hides it. The caller computes all counts, including preset totals before pagination that respect the current search and the preset's filters.

<.table_front
  count={42}
  id="table-front-single-everything"
  patch={&Storybook.Components.TableFront.table_path/2}
  search_input_icon_wrapper_class="!col-span-* col-span-4"
  count_label="screen"
  search_input_placeholder="Search ..."
>
  <:form :let={f}>
    <.select_input_group
      form={f}
      id="it-is-required-for-select-hook"
      group_class="mb-0 md:col-span-2 !md:col-span-*"
      name="gender"
      options={["", "Female", "Male"]}
      placeholder="Select a gender"
    />
  </:form>
  <.button icon="far fa-file-excel" color={:default}/>
  <.button icon="fa fa-plus" text="Add" />
  <:filters count={167}>All</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["critical"]]} color={:danger} count={23}>Critical</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["warning"]]} color={:warning} count={113}>Needs attention</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["ok"]]} color={:success} count={31}>OK</:filters>
</.table_front>
<.table_front id="table-front-single-search-and-button" search_input_icon="fal fa-filter">
  <.button text="Add" icon="fa fa-plus"/>
</.table_front>
<.table_front id="table-front-single-only-buttons">
  <.button icon="far fa-file-excel" color={:default}/>
  <.button icon="fa fa-plus" text="Add"/>
</.table_front>
<.table_front
  id="table-front-single-filters-with-counts"
  patch={&Storybook.Components.TableFront.table_path/2}
  current_filters={[score: ["critical"]]}
  current_sorting={[score: :desc]}
>
  <:filters count={167}>All</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["critical"]]} color={:danger} count={23}>Critical</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["warning"]]} color={:warning} count={113}>Needs attention</:filters>
  <:filters sorting={[score: :desc]} filters={[score: ["ok"]]} color={:success} count={31}>OK</:filters>
</.table_front>
<.table_front
  id="table-front-single-filters-without-counts"
  patch={&Storybook.Components.TableFront.table_path/2}
>
  <:filters>All</:filters>
  <:filters filters={[score: ["critical"]]} color={:danger}>Critical</:filters>
  <:filters filters={[score: ["ok"]]} color={:success}>OK</:filters>
</.table_front>
37 / 42 enregistrements
<.table_front
  count={42}
  id="table-front-single-no-button"
  selected_count={37}
  search_input_placeholder="Search ..."
 />
<.table_front
  id="table-front-single-with-form-slot"
  search_input_icon_wrapper_class="!col-span-* col-span-4"
  search_input_placeholder="Search ..."
>
  <:form :let={f}>
    <.select_input_group
      form={f}
      id="it-is-required-for-select-hook"
      group_class="mb-0 md:col-span-2 !md:col-span-*"
      name="gender"
      options={["", "Female", "Male"]}
      placeholder="Select a gender"
    />
  </:form>
</.table_front>