# `MishkaGervaz.Form.Types.Field`
[🔗](https://github.com/mishka-group/mishka_gervaz/blob/v0.0.1-alpha.3/lib/mishka_gervaz/form/types/field.ex#L1)

Built-in form field type registry.

Resolves field type atoms (`:text`, `:select`, `:relation`, …) to the
implementation modules under `MishkaGervaz.Form.Types.Field.*`. Built on
the shared `MishkaGervaz.Table.Behaviours.TypeRegistry` macro, which
generates `get/1`, `builtin_types/0`, `builtin?/1`, `default/0`,
`get_or_passthrough/1`, and `infer_from_ash_type/1`.

## Registration shape

Each entry is `{Module, [AshTypes]}`. The Ash-type list seeds
`infer_from_ash_type/1`, which is consulted by
`MishkaGervaz.Form.Transformers.ResolveFields` whenever a field omits
an explicit type — e.g. `field :title` on a `:string` attribute resolves
to `Field.Text` because `Ash.Type.String` is mapped there. An empty list
(`{Field.Hidden, []}`) means "this type is selectable by atom but never
inferred from an Ash attribute".

## Custom field types

Any module implementing `MishkaGervaz.Form.Behaviours.FieldType` can be
referenced directly in the DSL — no registration needed:

    field :background_color, MyApp.FieldTypes.Color

`get_or_passthrough/1` returns built-in modules by atom and any other
atom value as-is, so custom modules pass straight through to the
renderer.

See `MishkaGervaz.Form.Behaviours.FieldType`,
`MishkaGervaz.Table.Behaviours.TypeRegistry`, and
`MishkaGervaz.Form.Transformers.ResolveFields`.

# `builtin?`

```elixir
@spec builtin?(atom()) :: boolean()
```

Check if type name is registered.

# `builtin_types`

```elixir
@spec builtin_types() :: [atom()]
```

List all built-in type names.

# `default`

```elixir
@spec default() :: module() | nil
```

Get the default type module.

# `get`

```elixir
@spec get(atom()) :: module() | nil
```

Get module by type name.

Returns the module for built-in types, or the type itself
if it's already a module (for custom types).

# `get_or_passthrough`

```elixir
@spec get_or_passthrough(atom()) :: module()
```

Get module, falling back to type itself for custom modules.

Unlike `get/1` which returns nil for unknown types,
this returns the type as-is (assuming it's a custom module).

# `infer_from_ash_type`

```elixir
@spec infer_from_ash_type(map() | nil) :: module()
```

Infer column type module from Ash attribute type.

Maps Ash types to appropriate column type modules for rendering.
Returns default type when attribute is nil or type is unknown.

Auto-generated from builtin type registry mappings.

---

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