Behaviours

v0.0.1

A Gervaz extension point is a behaviour. This page lists the callbacks of the UI adapter, the table template, the form template and the four type behaviours, with their arities. A module that uses one of these behaviours plugs into the DSL by name, and you reach the default of any callback you override with super. For when to use which, see How Gervaz works.

UI adapter

MishkaGervaz.Behaviours.UIAdapter declares 69 one-argument component functions, each taking an assigns map. use MishkaGervaz.Behaviours.UIAdapter writes a defdelegate to a fallback module for every function and marks them all overridable, so an adapter defines only what differs. One adapter serves both the table and the form. MishkaGervaz.Behaviours.UIAdapter.component_functions/0 returns the live list.

Options of use

OptionTypeDefaultDescription
:fallbackmoduleMishkaGervaz.UIAdapters.TailwindWhere an undefined component goes. A fallback may itself fall back to another adapter.
:componentsmodulenoneA components module. Each function is wired to it when the module is loaded and exports a matching one-argument function.
:nested_componentsbooleanfalseLooks for Components.Button.button/1 instead of Components.button/1.
:module_prefixstringnonePrepended to the submodule name, so "Mishka" gives Components.MishkaButton.button/1. It applies only with nested_components: true.
:component_prefixstringnonePrepended to the function name, so "mc_" gives mc_button/1.

Built-in adapters

ModulePurpose
MishkaGervaz.UIAdapters.TailwindPlain Tailwind CSS. The default adapter.
MishkaGervaz.UIAdapters.MediaGalleryOverrides button/1 for the cards of the media gallery template and inherits the rest. The gallery template uses it in place of the Tailwind adapter.
MishkaGervaz.UIAdapters.DynamicRenders components resolved at run time and falls back per component. Options: :site (default "Global"), :component_renderer, :module_resolver and :fallback.

Component functions

Inputs

FunctionRenders
text_input/1Render a text input.
select/1Render a select dropdown.
multi_select/1Render a multi-select with search support.
search_select/1Render a single-select with search support.
load_more_select/1Render a single-select with paginated load-more (no search input).
checkbox/1Render a checkbox.
date_input/1Render a date input.
datetime_input/1Render a datetime input.
number_input/1Render a number input.
textarea/1Render a multi-line text input.
json_editor/1Render a JSON editor (textarea with formatting).
toggle_input/1Render a boolean toggle switch.
range_input/1Render a range slider input.
string_list_input/1Render a dynamic string list input with add/remove buttons.
password_input/1Render a password input (masked text entry).
combobox/1Render a combobox (text input with dropdown suggestions).

Actions and display

FunctionRenders
button/1Render a button.
icon/1Render an icon.
badge/1Render a badge/tag (variant :tag or :pill, optional leading dot).
copy_button/1Render a copy-to-clipboard button for a value.
spinner/1Render a loading spinner.
nav_link/1Render a navigation link.
dropdown/1Render a dropdown menu.

State and status

FunctionRenders
empty_state/1Render empty state.
error_state/1Render error state.
loading_state/1Render loading state.
alert/1Render a static alert/notice (info/warning/error/success/neutral).

Table

FunctionRenders
table/1Render table wrapper.
table_header/1Render table header row.
th/1Render a table header cell.
tr/1Render a table row.
td/1Render a table cell.
date_range_container/1Render a date range container.
cell_empty/1Render empty cell value (nil/missing data).
cell_text/1Render text cell value.
cell_number/1Render number cell value.
cell_date/1Render date cell value.
cell_datetime/1Render datetime cell value.
cell_code/1Render code/monospace cell value.
cell_array/1Render array/list container.
cell_tags/1Render a list of tags/chips with a +N inline expand/collapse toggle.
cell_avatars/1Render an overlapping avatar stack with a +N inline expand/collapse toggle.
cell_stacked/1Render a two-line cell: a primary line over a quieter secondary one.
cell_stats/1Render a wrapping row of icon+count markers and chips.
cell_bars/1Render a bar-gauge cell (a numeric value as filled bars + the number).
filter_reset_button/1Render filter reset/clear button.
archive_toggle/1Render archive status toggle.
bulk_action_bar/1Render bulk actions bar container.
bulk_action_button/1Render individual bulk action button.
pagination_container/1Render pagination container with page info.
pagination_nav_button/1Render pagination nav button (prev/next/first/last).
pagination_page_button/1Render pagination page number button.
template_switcher/1Render template switcher container with buttons.
template_switcher_button/1Render template switcher button.

Form

FunctionRenders
form_container/1Render the main form wrapper (phx-change, phx-submit).
form_header/1Render a form header (title + description).
form_footer/1Render a form footer (static content below the submit row).
field_wrapper/1Render a field wrapper with label, input, and error display.
field_group/1Render a collapsible group of fields.
field_error/1Render a field error message display.
step_indicator/1Render wizard/tabs step progress indicator.
step_navigation/1Render wizard prev/next/submit navigation controls.
upload_dropzone/1Render a drag-drop file upload zone.
upload_preview/1Render a file preview thumbnail.
upload_progress/1Render an upload progress bar.
upload_file_input/1Render a styled file input (non-dropzone) upload control.
upload_existing_file/1Render an existing file card with remove button (for edit mode).
nested_fields/1Render a container for nested form fields.
array_fields/1Render a container for array-of-maps fields.

Table template

MishkaGervaz.Table.Behaviours.Template arranges a table. use MishkaGervaz.Table.Behaviours.Template supplies the optional callbacks from MishkaGervaz.Table.Templates.Shared and imports get_cell_value/2. The renderer passes @static, @state, @stream, @empty? and @myself.

CallbackRequiredReturns or renders
name/0YesAn atom. It is what state.template.name() returns.
label/0YesThe label in the template switcher.
icon/0YesThe icon in the template switcher.
description/0YesA short description. Gervaz does not call it.
features/0YesThe list of features the template draws, or :all.
default_options/0YesA keyword list of defaults for template_options. Only the built-in templates merge their own. Gervaz does not merge the list of a custom template, so call it from render/1 if you want it.
render/1YesThe whole table.
render_item/1YesOne record.
render_header/1NoThe header. Default from Shared.
render_empty/1NoThe empty state, read from the DSL empty_state.
render_error/1NoThe error state, read from the DSL error_state.
render_loading/1NoThe loading state.
render_pagination/1NoThe pagination row.
render_filters/1NoThe filter bar.
render_bulk_actions/1NoThe bulk action bar.
render_template_switcher/1NoThe template switcher.

The accepted values of features/0, besides :all, are :sort, :filter, :select, :bulk_actions, :paginate, :export, :expand, :reorder and :inline_edit.

Form template

MishkaGervaz.Form.Behaviours.Template arranges a form. use MishkaGervaz.Form.Behaviours.Template delegates the four optional callbacks to MishkaGervaz.Form.Templates.Standard. The renderer passes @static, @state, @myself and @uploads.

CallbackRequiredReturns or renders
name/0YesAn atom.
label/0YesA label.
icon/0YesAn icon.
render/1YesThe whole form.
render_loading/1NoThe loading state.
render_field/1NoOne field, dispatched by field type.
render_group/1NoOne group.
render_step_indicator/1NoThe step indicator of a wizard or tabs form.

Column type

MishkaGervaz.Table.Behaviours.ColumnType draws one cell.

CallbackRequiredReceives
render/4Yesvalue (after format), the column config map, the full record and the UI adapter module.
cell_class/1NoThe column config map. Returns a class string or nil. Gervaz does not call it.

Filter type

MishkaGervaz.Table.Behaviours.FilterType draws a filter input, parses its raw value and applies it to the query. Gervaz calls parse_value/2 and build_query/4 for any filter module. It does not call render_input/3 of a custom module, because the built-in table template draws a filter itself by its type name.

CallbackRequiredReceives
render_input/3YesThe filter config map, the current value and the UI adapter module. The built-in table template does not call it for a custom module.
parse_value/2YesThe raw form value and the filter config map. Returns the value build_query expects.
build_query/3YesThe query, the field name and the parsed value. Returns the query. Gervaz calls build_query/4 and not this one.
build_query/4NoThe same, plus the full filter config map, for multi-field search. This is the one Gervaz calls. Define it, or give the last argument of build_query/3 a default.
label/1NoThe filter config map. Returns a label. Gervaz does not call it.

Action type

MishkaGervaz.Table.Behaviours.ActionType draws one row action.

CallbackRequiredReceives
render/5YesThe assigns map (with :action, :record, :state, :static, :ui_adapter and :myself), the action config map, the record, the UI adapter module and the phx-target.

Field type

MishkaGervaz.Form.Behaviours.FieldType draws one form input and prepares its value. Gervaz calls sanitize/2, parse_params/2 and validate/2. The Standard form template does not call render/2 or default_ui/0, and draws a field with a module type as a text input.

CallbackRequiredReceives or returns
render/2YesThe assigns map and the field config. Returns the markup. The behaviour requires it, and the Standard form template does not call it.
sanitize/2NoThe value and the config. Runs before validation. Text types strip HTML here.
parse_params/2NoThe raw value and the config. Returns the typed value.
validate/2NoThe value and the config. Returns {:ok, value} or {:error, message}.
default_ui/0NoReturns the baseline UI map of the type. Gervaz does not call it.

Type registries

The column, filter, action and field registries (MishkaGervaz.Table.Types.Column, MishkaGervaz.Table.Types.Filter, MishkaGervaz.Table.Types.Action and MishkaGervaz.Form.Types.Field) share one macro. Each gives you get/1, builtin_types/0, builtin?/1, default/0 and get_or_passthrough/1. The column and field registries add infer_from_ash_type/1. The DSL does not use the field registry's version to infer a field type. The ResolveFields transformer does, with the rules on Form fields DSL.