Ash Form Builder ๐
โ ๏ธ EXPERIMENTAL - USE AT YOUR OWN RISK โ ๏ธ
This package is under active development. API may change without notice. Breaking changes are likely in minor versions. Not recommended for critical production systems without thorough testing.
Status: Alpha/Experimental | Version: 0.1.0
A declarative form generation engine for Ash Framework and Phoenix LiveView.
Define your form structures directly inside your Ash.Resource domain layer, and let the engine automatically generate the Phoenix form modules, nested configurations, and LiveView components.
โจ Features
- ๐ค Auto-Inference Engine - Automatically infers form fields from your resource's
acceptlist, includingmany_to_manyrelationships - ๐ Domain Code Interface Integration - Works seamlessly with Ash's
form_to_<action>pattern for clean, policy-compliant LiveViews - ๐ Searchable Many-to-Many - Built-in
:multiselect_comboboxtype with searchable selection for many-to-many relationships - โจ NEW: Creatable Combobox - Create related records on-the-fly directly from the form UI
- ๐ Has Many Nested Forms - Dynamic add/remove for child records (subtasks, order items, etc.)
- ๐จ Customizable Themes - Default HTML theme + full MishkaChelekom component integration
- ๐ ๏ธ Declarative DSL - Define form fields, types, and labels directly in your resource
- ๐ Multiple Actions - Support for both
:createand:updateforms with separate configurations - โก Self-Contained LiveComponent - A ready-to-use
<.live_component>that handles validation, submission, and nested form state automatically - ๐ Policy Enforcement - All Ash policies and validations are automatically respected
๐ฆ Installation
Add ash_form_builder to your list of dependencies in mix.exs:
def deps do
[
{:ash, "~> 3.0"},
{:ash_phoenix, "~> 2.0"},
# โ ๏ธ EXPERIMENTAL - Use at your own risk
{:ash_form_builder, "~> 0.1.0"}
# Or from GitHub for latest:
# {:ash_form_builder, github: "nagieeb0/ash_form_builder"}
]
endThen run:
mix deps.get
Configure your theme in config/config.exs:
# Default HTML theme
config :ash_form_builder, :theme, AshFormBuilder.Themes.Default
# MishkaChelekom theme (requires mishka_chelekom dependency)
config :ash_form_builder, :theme, AshFormBuilder.Theme.MishkaTheme๐ Quick Start
1. Define Your Resource with Auto-Inference
The simplest approach: just declare the action, and the form fields are auto-inferred from your resource's accept list.
defmodule MyApp.Billing.Clinic do
use Ash.Resource,
domain: MyApp.Billing,
extensions: [AshFormBuilder] # โ Add this extension
attributes do
uuid_primary_key :id
attribute :name, :string, allow_nil?: false
attribute :address, :string
attribute :phone, :string
end
relationships do
many_to_many :doctors, MyApp.Billing.Doctor do
through MyApp.Billing.ClinicDoctor
source_attribute_on_join_resource :clinic_id
destination_attribute_on_join_resource :doctor_id
end
end
actions do
defaults [:create, :read, :update, :destroy]
end
form do
action :create
# Fields are auto-inferred from action.accept!
# many_to_many relationships automatically use :multiselect_combobox
end
end2. Configure Domain Code Interfaces
Define form_to_<action> interfaces in your Domain for clean LiveView integration:
defmodule MyApp.Billing do
use Ash.Domain
resources do
resource MyApp.Billing.Clinic do
define :form_to_create_clinic, action: :create
define :form_to_update_clinic, action: :update
end
end
end3. Use in LiveView
defmodule MyAppWeb.ClinicLive.Form do
use MyAppWeb, :live_view
alias MyApp.Billing
def mount(_params, _session, socket) do
# Zero manual AshPhoenix.Form calls!
form = Billing.Clinic.Form.for_create(actor: socket.assigns.current_user)
{:ok, assign(socket, form: form)}
end
def render(assigns) do
~H"""
<.live_component
module={AshFormBuilder.FormComponent}
id="clinic-form"
resource={MyApp.Billing.Clinic}
form={@form}
/>
"""
end
def handle_info({:form_submitted, MyApp.Billing.Clinic, clinic}, socket) do
{:noreply, push_navigate(socket, to: ~p"/clinics/#{clinic.id}")}
end
end๐ฏ Key Features
Auto-Inference Engine
Fields are automatically mapped from Ash types to UI components:
| Ash Type | UI Type |
|---|---|
:string | :text_input |
:integer | :number |
:boolean | :checkbox |
:date | :date |
:datetime | :datetime |
:atom + one_of | :select |
many_to_many | :multiselect_combobox |
Creatable Combobox โญ NEW
Allow users to create new related records on-the-fly:
form do
field :tags do
type :multiselect_combobox
label "Tags"
placeholder "Search or create tags..."
opts [
creatable: true, # โ Enable creating new items
create_action: :create,
create_label: "Create \"\"",
search_event: "search_tags",
debounce: 300,
label_key: :name,
value_key: :id
]
end
endNested Forms (has_many)
Dynamic add/remove for child records:
form do
nested :subtasks do
label "Subtasks"
cardinality :many
add_label "Add Subtask"
field :title do
label "Subtask"
required true
end
end
end๐ Documentation
Guides
Comprehensive guides are available in the guides/ directory:
- Todo App Integration - Complete step-by-step tutorial
- Relationships Guide - has_many vs many_to_many, filtering, limits
- Example Usage - Reference documentation with all features
Module Documentation
Generate local docs:
mix docsโ ๏ธ Experimental Status
This package is EXPERIMENTAL and under active development.
What This Means
- โ Core functionality is working and tested
- โ ๏ธ API may change without notice
- โ ๏ธ Breaking changes likely in minor versions (0.x.y)
- โ ๏ธ Not all edge cases are handled
- โ ๏ธ Documentation may be incomplete
For Production Use
If you choose to use this in production:
- Pin to exact version:
{:ash_form_builder, "== 0.1.0"} - Test thoroughly before deployment
- Monitor the repository for updates and breaking changes
- Be prepared to handle breaking changes on upgrade
- Consider contributing fixes and improvements
Roadmap to 1.0
Planned features for stable release:
- Better creatable value extraction
- Loading states for async operations
- Inline error handling
- i18n support via GetText
- Field-level permissions
- Conditional field rendering
- Multi-step form wizards
- Form draft auto-save
- More comprehensive test coverage
๐ง Configuration
Theme System
AshFormBuilder uses a theme system for UI customization:
# config/config.exs
# Default theme (semantic HTML)
config :ash_form_builder, :theme, AshFormBuilder.Themes.Default
# MishkaChelekom theme (requires mishka_chelekom dependency)
config :ash_form_builder, :theme, AshFormBuilder.Theme.MishkaTheme
# Custom theme (implement AshFormBuilder.Theme behaviour)
config :ash_form_builder, :theme, MyAppWeb.CustomThemeCreating Custom Themes
See example_usage.ex for a complete custom theme example.
๐งช Testing
Run the test suite:
mix test๐ค Contributing
Contributions are welcome! This is an experimental project, and community feedback will help shape its development.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
๐ License
MIT License - see LICENSE file for details.
๐ Acknowledgments
- Ash Framework - The excellent Elixir framework for building maintainable applications
- Phoenix LiveView - Real-time HTML without writing JavaScript
- MishkaChelekom - UI component library
Built with โค๏ธ using Ash Framework