You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Abies currently has no built-in forms or validation support. Developers must manually wire up every form input with oninput → Message → Update → model field, and implement all validation logic from scratch. This is the most verbose gap compared to Blazor, which provides EditForm, DataAnnotationsValidator, ValidationSummary, InputText, InputNumber, and other typed input components with automatic validation.
Current State (Conduit example)
In Abies.Conduit, every form requires extensive boilerplate:
// Login form - every field needs manual wiringinput([class_("form-control form-control-lg"),type("email"),placeholder("Email"),value(model.Email),oninput(v =>newMessage.EmailChanged(v??""))],[])// Validation is entirely manual
if (model.Errorsis not null){foreach(varerrorinmodel.Errors){li([],[text(error)])}}
This pattern is repeated across Login, Register, Settings, and Editor pages — each with its own model fields, change messages, and error display logic.
Proposed Solution
Add a forms module to Abies that stays true to the MVU architecture while reducing boilerplate. The key insight is that forms are a pattern, not a component — we can provide helper functions that generate the right virtual DOM nodes and messages.
Three layers:
Abies.Forms module — Higher-level input helpers that bundle value + oninput + validation display
Abies.Validation module — Pure validation functions that work with any model
Integration with the existing MVU loop — No magic, no hidden state, forms are still just Node trees and messages
API Design
Layer 1: Form Helpers
usingstaticAbies.Forms;// Instead of manually wiring value + oninput + validation:InputText(model.Email,
v =>newEmailChanged(v),validation:Validate.Required("Email is required").And(Validate.Email("Must be a valid email")),placeholder:"Email",class_:"form-control form-control-lg")// Typed inputs
InputNumber(model.Age, v =>newAgeChanged(v),min:0,max:150)
InputPassword(model.Password, v =>newPasswordChanged(v))
TextArea(model.Bio, v =>newBioChanged(v),rows:8)// Select dropdown
Select(model.SelectedTag, v =>newTagSelected(v),options:tags)
Layer 2: Validation
usingstaticAbies.Validation;// Pure validation functions — return ValidationResultpublicstaticValidationResultValidateLogin(LoginModelmodel)=>Validate.All(Validate.Required(model.Email,"Email is required"),Validate.Email(model.Email,"Must be a valid email"),Validate.MinLength(model.Password,8,"Password must be at least 8 characters"));// ValidationResult is a simple sum typepublicinterfaceValidationResult{recordValid:ValidationResult;recordInvalid(IReadOnlyList<string>Errors):ValidationResult;}
Layer 3: Form wrapper
// Form helper that prevents submit when invalidForm(onValidSubmit:newSubmitLogin(),validation:ValidateLogin(model),children:[InputText(model.Email, v =>newEmailChanged(v), ...),InputPassword(model.Password, v =>newPasswordChanged(v), ...),SubmitButton("Sign in",model.IsSubmitting)])
Alternatives Considered
Blazor-style EditContext with DataAnnotations — Rejected because it relies on mutable state and reflection, which conflicts with the MVU pattern
Two-way binding macro — Rejected because Abies is explicitly one-directional (message-based)
Do nothing, keep manual wiring — Viable but leads to significant boilerplate in real apps (Conduit has ~200 lines of manual form wiring)
Acceptance Criteria
Abies.Forms module with InputText, InputPassword, InputNumber, TextArea, Select helpers
Problem Statement
Abies currently has no built-in forms or validation support. Developers must manually wire up every form input with
oninput→ Message → Update → model field, and implement all validation logic from scratch. This is the most verbose gap compared to Blazor, which providesEditForm,DataAnnotationsValidator,ValidationSummary,InputText,InputNumber, and other typed input components with automatic validation.Current State (Conduit example)
In
Abies.Conduit, every form requires extensive boilerplate:This pattern is repeated across Login, Register, Settings, and Editor pages — each with its own model fields, change messages, and error display logic.
Proposed Solution
Add a forms module to Abies that stays true to the MVU architecture while reducing boilerplate. The key insight is that forms are a pattern, not a component — we can provide helper functions that generate the right virtual DOM nodes and messages.
Three layers:
Abies.Formsmodule — Higher-level input helpers that bundlevalue+oninput+ validation displayAbies.Validationmodule — Pure validation functions that work with any modelNodetrees and messagesAPI Design
Layer 1: Form Helpers
Layer 2: Validation
Layer 3: Form wrapper
Alternatives Considered
Acceptance Criteria
Abies.Formsmodule withInputText,InputPassword,InputNumber,TextArea,SelecthelpersAbies.Validationmodule withRequired,MinLength,MaxLength,Email,Pattern,Range,CustomvalidatorsValidationResultsum type (Valid/Invalid)Validate.All()combinator for composing validatorsForm()helper withonValidSubmitthat checks validation before dispatchingValidationSummary()andValidationMessage()display helpersNodetypes — no hidden statePriority
🔴 High — Core functionality gap
Additional Context