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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user