Add timing-indifference contract and fix form input components

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-01-07 07:12:46 +00:00
parent ff04f85403
commit fb9c96ae61

View File

@@ -9,6 +9,21 @@ description: Creating custom form input components that extend Form_Input_Abstra
Form input components extend `Form_Input_Abstract` which implements a template method pattern. The base class handles value buffering, events, and the val() interface. Concrete classes only implement how to get and set values.
## Core Contract: Timing Indifference
**Callers must never care about component lifecycle timing.**
`.val(value)` must produce identical results whether called:
- Before the component initializes (buffered, applied at `_mark_ready()`)
- After the component initializes (applied immediately via `_set_value()`)
- At any point during the component's lifecycle
This is non-negotiable. If a caller needs to use `await component.ready()` or timing tricks to make `val()` work, **the component is broken**.
**Implementation requirement**: Your `_set_value()` must work identically whether called during initial value application (via `_mark_ready()`) or later (via direct `val()` calls). If your implementation relies on initialization state or timing, you've violated this contract.
---
## Template Method Pattern
**Base class handles:**
@@ -76,6 +91,18 @@ _set_value(value) {
}
```
### String/Number Value Coercion
Input components must accept both string and numeric values. A select with options `"3"`, `"5"`, `"9"` must work with `.val(3)` or `.val("3")`.
```javascript
_set_value(value) {
// Convert to string for comparison with option values
const str_value = value == null ? '' : str(value);
this.tom_select.setValue(str_value, true);
}
```
### _mark_ready()
Call in `on_ready()` to apply buffered values and mark component ready: