Contributor-facing. See README.md for usage, DESIGN.md for architecture.
- No stdlib imports in library code. Never
errors,strconv,strings,reflect. - Use
webtyp.com/fmt:fmt.Err("Noun", "Adjective")for errors,fmt.Convert(s).Int()instead ofstrconv.Atoi,fmt.Contains(s, sub)instead ofstrings.Contains. - No maps in inputs: use slices — maps increase WASM binary size.
- No
any/mapin public APIs. Noreflectat runtime. - The
inputpackage must stay free ofdomimports (edge-safe): HTML rendering lives in theformpackage.
| File | Responsibility |
|---|---|
form.go |
Form struct, New(), Input(), SetOptions(), SetValues(), Reset(), Namer |
sync.go |
SyncValues(), pointer-based field sync |
forms.go |
SetGlobalClass(), global forms state |
render.go |
Render(), String(), SetSSR(), submit event wiring |
render_input.go |
Field rendering (input + error span; owns dom imports); RenderInput() helper |
css.go |
RenderCSS() — base tw-* styles (!wasm, additive css.Stylesheet) |
validate.go |
Validate() |
validate_struct.go |
ValidateData() (crudp.DataValidator) |
input/interface.go |
Input interface (embeds model.Kind + metadata getters; no dom.Component) |
input/base.go |
Base struct embedded by all inputs |
input/*.go |
18 concrete input implementations |
tests/ |
Black-box tests (package form_test, public API only) |
White-box tests (unexported internals) stay next to the code they test
(render_input_test.go, submit.*_test.go); everything testable through the
public API belongs in tests/.
- Create
input/mytype.go— embedBase, configuremodel.Permittedrules. - Constructor
MyType() Inputreturns a stateless prototype (no arguments). - Add
Clone(parentID, name string) Inputon the concrete type (copy +InitBase). Name(),Storage(),Validate()are inherited fromBase; overrideValidateonly for specialized rules (delegate the baseline tom.Permitted.Validate(m.FieldName(), value)).- Add validation cases in
input/validation_test.goand the compile-time assertion ininput/assertions_test.go.
tests/— black-box (package form_test): binding, rendering contract, submit-adjacent behavior via public API.- Module root /
input/— white-box tests only, for unexported internals. - Shared native/wasm cases use the three-file pattern:
x.shared_test.go(helpers),x.back_test.go(//go:build !wasm),x.front_test.go(//go:build wasm). Run withgotest ./...(native + wasm).