# `MishkaGervaz.Form.Behaviours.Template`
[🔗](https://github.com/mishka-group/mishka_gervaz/blob/v0.0.1-alpha.3/lib/mishka_gervaz/form/behaviours/template.ex#L1)

Behaviour for form layout templates.

Templates define **how the form is structured**:

  - Standard — single-page form with groups
  - Wizard   — multi-step form with progress indicator
  - Tabs     — tabbed form layout

Templates pair with UI adapters along orthogonal axes:

  - **Template**   — *where* things go (structure / layout)
  - **UIAdapter**  — *how* things look (styling / CSS)

## Two ways to implement

Bare behaviour — implement every required callback yourself. The default
template `MishkaGervaz.Form.Templates.Standard` follows this path:

    defmodule MyApp.Form.Templates.Custom do
      @behaviour MishkaGervaz.Form.Behaviours.Template
      use Phoenix.Component

      @impl true
      def name, do: :custom

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

      @impl true
      def icon, do: "hero-document-text"

      @impl true
      def render(assigns) do
        ~H"""
        <div class="my-custom-form">...</div>
        """
      end

      # render_loading/1, render_field/1, render_group/1,
      # render_step_indicator/1 must be implemented or `use`-d below.
    end

Or `use` this module to inherit `Standard`'s implementations of the
optional callbacks (overridable). Most custom templates only need to
override `render/1`:

    defmodule MyApp.Form.Templates.Sidebar do
      use MishkaGervaz.Form.Behaviours.Template

      @impl true
      def name,  do: :sidebar
      @impl true
      def label, do: "Sidebar"
      @impl true
      def icon,  do: "hero-bars-3"

      @impl true
      def render(assigns), do: ~H"<aside>...</aside>"

      # render_loading, render_field, render_group, render_step_indicator
      # delegate to Standard. Override any of them as needed.
    end

See `MishkaGervaz.Form.Templates.Standard`,
`MishkaGervaz.Form.Behaviours.FieldType`, and
`MishkaGervaz.Behaviours.UIAdapter`.

# `assigns`

```elixir
@type assigns() :: map()
```

Phoenix LiveView assigns map.

# `rendered`

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

Result of a Phoenix render.

# `icon`

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

Icon identifier.

# `label`

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

Human-readable label for UI display.

# `name`

```elixir
@callback name() :: atom()
```

Unique template identifier atom.

# `render`

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

Render the complete form.

Assigns include:

  - `@static`  — static form configuration (fields, groups, steps,
    ui_adapter, …)
  - `@state`   — dynamic form state (form, errors, current_step, …)
  - `@myself`  — `LiveComponent` reference for targeting events

# `render_field`
*optional* 

```elixir
@callback render_field(assigns()) :: rendered()
```

Render a single field by dispatching to its type.

# `render_group`
*optional* 

```elixir
@callback render_group(assigns()) :: rendered()
```

Render a group of fields.

# `render_loading`
*optional* 

```elixir
@callback render_loading(assigns()) :: rendered()
```

Render the loading state while the form is being initialized.

# `render_step_indicator`
*optional* 

```elixir
@callback render_step_indicator(assigns()) :: rendered()
```

Render the step indicator for wizard / tabs mode.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
