Skip to content

forms

wybthon.forms

Form state, validation helpers, and a11y attribute utilities.

FieldState dataclass

Signals representing a field's value, error message, and touched state.

a11y_control_attrs(field, *, described_by_id=None)

Return ARIA attributes for an input/select control bound to the field.

  • aria-invalid is set to "true" when there's an error, else "false".
  • aria-describedby includes the provided error element id when an error exists.

bind_checkbox(field)

Bind a checkbox input to a boolean field.

bind_select(field)

Bind a select element to a field, updating value on change.

bind_text(field, *, validators=None)

Bind a text input to a field with validation on input events.

email(message='Invalid email address')

Validate a basic email address format (lightweight regex).

error_message_attrs(*, id)

Return attributes for an error message container.

Use with a live region to announce validation errors to assistive tech.

form_state(initial)

Create a form state map from initial values using Signals.

max_length(n, message=None)

Validate that stringified value length is at most n.

min_length(n, message=None)

Validate that stringified value length is at least n.

on_submit(handler, form)

Create a submit handler that prevents default and calls the handler.

on_submit_validated(rules, handler, form)

Submit handler that validates the whole form before invoking handler.

Prevents the default submit, validates via validate_form, and calls handler(form) only when the form is valid.

required(message='This field is required')

Validate that a value is present and non-empty.

rules_from_schema(schema)

Build a validators map from a simple, lightweight schema.

Supported keys per field: - required: bool or str (if str, used as custom message) - min_length: int (optional custom message via min_length_message) - max_length: int (optional custom message via max_length_message) - email: bool or str (if str, used as custom message)

Example

{ "name": {"required": True, "min_length": 2}, "email": {"email": True}, }

validate(value, validators)

Return first validation error or None when all validators pass.

validate_field(field, validators=None)

Validate a single field and update its error/touched signals.

Returns the error message if any, else None.

validate_form(form, rules)

Validate all fields in a form against a rules map.

Mutates each field's touched and error signals. Returns (is_valid, errors_map).

Additional helpers introduced:

  • validate_field
  • validate_form
  • on_submit_validated
  • rules_from_schema
  • a11y_control_attrs
  • error_message_attrs

Schema-based rules

rules_from_schema(schema: Dict[str, Dict[str, Any]]) -> Dict[str, List[Validator]]

Build a validators map from a lightweight schema. Supported per-field keys:

  • required: bool or str (custom message)
  • min_length: int (optional min_length_message)
  • max_length: int (optional max_length_message)
  • email: bool or str (custom message)

Example:

schema = {
    "name": {"required": True, "min_length": 2},
    "email": {"email": True},
}
rules = rules_from_schema(schema)