MishkaGervaz.Table.Behaviours.Template behaviour (MishkaGervaz v0.0.1-alpha.2)

Copy Markdown View Source

Behaviour for layout templates.

Templates define HOW data is structured and arranged:

  • Table: Traditional rows and columns
  • MediaGallery: Image/file gallery with thumbnails
  • Kanban: Column-based board layout
  • List: Simple list layout

Templates work together with UIAdapters:

  • Template = WHERE things go (structure/layout)
  • UIAdapter = HOW things look (styling/CSS)

Creating a Custom Template

defmodule MyApp.Templates.CustomTable do
  @behaviour MishkaGervaz.Table.Behaviours.Template
  use Phoenix.Component

  @impl true
  def name, do: :custom_table

  @impl true
  def label, do: "Custom Table"

  @impl true
  def icon, do: "hero-table-cells"

  @impl true
  def features, do: [:sort, :filter, :select, :paginate]

  @impl true
  def render(assigns) do
    ~H"""
    <div class="my-custom-wrapper">
      {render_slot(@inner_block)}
    </div>
    """
  end

  # ... implement other callbacks
end

Using in DSL

mishka_gervaz do
  table do
    presentation do
      template MyApp.Templates.CustomTable
      switchable_templates [
        MishkaGervaz.Table.Templates.Table,
        MyApp.Templates.CustomTable
      ]
    end
  end
end

See MishkaGervaz.Table.Templates.Table (default), MishkaGervaz.Table.Templates.MediaGallery, MishkaGervaz.Table.Templates.Shared (rendering helpers), MishkaGervaz.Behaviours.UIAdapter, and the form-side counterpart MishkaGervaz.Form.Behaviours.Template.

Summary

Callbacks

Default options for this template.

Description of what this template is best used for.

Features supported by this template.

Icon identifier for template switcher UI.

Human-readable label for UI display.

Unique template identifier atom.

Render the complete template wrapper.

Render bulk actions bar. Optional - has default implementation.

Render the empty state when no records exist.

Render the error state.

Render filters section. Optional - has default implementation.

Render the header section (for tables: thead, for grids: toolbar, etc.)

Render a single item (row for table, card for grid, etc.)

Render the loading state.

Render pagination controls.

Render the template switcher UI. Optional - has default implementation.

Functions

Use this module to get default implementations for optional callbacks.

Returns the list of all valid features.

Checks if a specific feature is enabled.

Extract cell value from a record based on column source.

Normalizes features to a list.

Types

assigns()

@type assigns() :: map()

feature()

@type feature() ::
  :sort
  | :filter
  | :select
  | :bulk_actions
  | :paginate
  | :export
  | :expand
  | :reorder
  | :inline_edit

features()

@type features() :: :all | [feature()]

rendered()

@type rendered() :: Phoenix.LiveView.Rendered.t()

Callbacks

default_options()

@callback default_options() :: keyword()

Default options for this template.

Can include things like:

  • :columns - Number of grid columns
  • :card_size - Card size for grid
  • :show_header - Whether to show header

description()

@callback description() :: String.t()

Description of what this template is best used for.

features()

@callback features() :: features()

Features supported by this template.

Can return :all for all features or a list of specific features.

Possible features:

  • :sort - Column sorting
  • :filter - Filtering
  • :select - Row/item selection
  • :bulk_actions - Bulk actions on selected items
  • :paginate - Pagination
  • :export - Export to CSV/Excel
  • :expand - Expandable rows/cards
  • :reorder - Drag and drop reordering
  • :inline_edit - Inline editing

Examples

# All features
def features, do: :all

# Specific features
def features, do: [:sort, :filter, :paginate]

icon()

@callback icon() :: String.t()

Icon identifier for template switcher UI.

Examples: "hero-table-cells", "hero-squares-2x2", "hero-photo"

label()

@callback label() :: String.t()

Human-readable label for UI display.

Examples: "Table", "Grid View", "Media Gallery"

name()

@callback name() :: atom()

Unique template identifier atom.

Examples: :table, :grid, :media_gallery, :kanban

render(assigns)

@callback render(assigns()) :: rendered()

Render the complete template wrapper.

This is the main entry point. It should render:

  • Filters (if enabled)
  • The main content area (table/grid/etc.)
  • Pagination (if enabled)

Assigns include:

  • @state - The table state
  • @ui_adapter - The UI adapter module
  • @stream - The data stream
  • @columns - Column configurations
  • @filters - Filter configurations
  • And more...

render_bulk_actions(assigns)

(optional)
@callback render_bulk_actions(assigns()) :: rendered()

Render bulk actions bar. Optional - has default implementation.

render_empty(assigns)

@callback render_empty(assigns()) :: rendered()

Render the empty state when no records exist.

render_error(assigns)

@callback render_error(assigns()) :: rendered()

Render the error state.

render_filters(assigns)

(optional)
@callback render_filters(assigns()) :: rendered()

Render filters section. Optional - has default implementation.

render_header(assigns)

@callback render_header(assigns()) :: rendered()

Render the header section (for tables: thead, for grids: toolbar, etc.)

render_item(assigns)

@callback render_item(assigns()) :: rendered()

Render a single item (row for table, card for grid, etc.)

Assigns include:

  • @record - The data record
  • @id - The stream item ID
  • @columns - Column configurations
  • @actions - Available actions

render_loading(assigns)

(optional)
@callback render_loading(assigns()) :: rendered()

Render the loading state.

render_pagination(assigns)

@callback render_pagination(assigns()) :: rendered()

Render pagination controls.

render_template_switcher(assigns)

(optional)
@callback render_template_switcher(assigns()) :: rendered()

Render the template switcher UI. Optional - has default implementation.

Functions

__using__(opts)

(macro)

Use this module to get default implementations for optional callbacks.

defmodule MyTemplate do
  use MishkaGervaz.Table.Behaviours.Template

  # Now you only need to implement required callbacks
end

all_features()

@spec all_features() :: [feature()]

Returns the list of all valid features.

feature_enabled?(features, feature)

@spec feature_enabled?(features(), feature()) :: boolean()

Checks if a specific feature is enabled.

Examples

iex> feature_enabled?(:all, :sort)
true

iex> feature_enabled?([:filter, :paginate], :sort)
false

get_cell_value(record, source)

@spec get_cell_value(map(), map() | atom()) :: any()

Extract cell value from a record based on column source.

Handles various source formats:

  • Atom: Direct field access
  • List: Multiple fields joined
  • Tuple: Relationship field access

normalize_features(features)

@spec normalize_features(features()) :: [feature()]

Normalizes features to a list.

Converts :all to the full list of features, validates feature atoms.

Examples

iex> normalize_features(:all)
[:sort, :filter, :select, :bulk_actions, :paginate, :export, :expand, :reorder, :inline_edit]

iex> normalize_features([:sort, :filter])
[:sort, :filter]