# `MishkaGervaz.Table.Behaviours.FilterType`
[🔗](https://github.com/mishka-group/mishka_gervaz/blob/v0.0.1-alpha.3/lib/mishka_gervaz/table/behaviours/filter_type.ex#L1)

Behaviour for filter type implementations.

Implement this behaviour to create custom filter inputs and query logic.

## Example

    defmodule MyApp.FilterTypes.DateRange do
      @behaviour MishkaGervaz.Table.Behaviours.FilterType
      use Phoenix.Component
      import Ash.Expr

      @impl true
      def render_input(filter, value, ui) do
        assigns = %{filter: filter, value: value || %{}, ui: ui}
        ~H"""
        <div class="flex gap-2">
          {@ui.date_input(%{name: "#{@filter.name}_from", value: @value[:from]})}
          <span class="self-center">to</span>
          {@ui.date_input(%{name: "#{@filter.name}_to", value: @value[:to]})}
        </div>
        """
      end

      @impl true
      def parse_value(%{"from" => from, "to" => to}, _filter) do
        %{from: Date.from_iso8601!(from), to: Date.from_iso8601!(to)}
      end
      def parse_value(_, _), do: nil

      @impl true
      def build_query(query, field, %{from: from, to: to}) do
        query
        |> Ash.Query.filter(^ref(field) >= ^from)
        |> Ash.Query.filter(^ref(field) <= ^to)
      end
    end

Then use in DSL:

    filter :created_at, type: MyApp.FilterTypes.DateRange

See `MishkaGervaz.Table.Types.Filter` (registry),
`MishkaGervaz.Table.Entities.Filter`,
`MishkaGervaz.Table.Behaviours.TypeRegistry`, and the form-side
counterpart `MishkaGervaz.Form.Behaviours.FieldType`.

# `build_query`

```elixir
@callback build_query(
  query :: Ash.Query.t(),
  field :: atom(),
  value :: any()
) :: Ash.Query.t()
```

Apply the filter to an Ash query.

## Parameters

- `query` - The Ash.Query to filter
- `field` - The field name (atom)
- `value` - The parsed filter value

# `build_query`
*optional* 

```elixir
@callback build_query(
  query :: Ash.Query.t(),
  field :: atom(),
  value :: any(),
  filter :: map()
) :: Ash.Query.t()
```

Apply the filter to an Ash query with full filter context.

Use this when you need access to the full filter config (e.g., for multi-field search).

## Parameters

- `query` - The Ash.Query to filter
- `field` - The field name (atom)
- `value` - The parsed filter value
- `filter` - Full filter configuration map

# `label`
*optional* 

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

Optional: Return label for the filter.

# `parse_value`

```elixir
@callback parse_value(raw :: any(), filter :: map()) :: any()
```

Parse raw form params into the filter value.

Receives the raw string value(s) from the form and returns
the parsed value that will be passed to build_query.

# `render_input`

```elixir
@callback render_input(
  filter :: map(),
  value :: any(),
  ui :: module()
) :: Phoenix.LiveView.Rendered.t()
```

Render the filter input element.

## Parameters

- `filter` - Filter configuration map from DSL
- `value` - Current filter value (parsed)
- `ui` - UI adapter module for consistent styling

---

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