@typed/ui 1.0.0-beta.6 → 1.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/Alert.d.ts +35 -41
  2. package/dist/Alert.d.ts.map +1 -1
  3. package/dist/Alert.js +23 -20
  4. package/dist/Button.d.ts +34 -78
  5. package/dist/Button.d.ts.map +1 -1
  6. package/dist/Button.js +16 -12
  7. package/dist/Carousel.d.ts +35 -236
  8. package/dist/Carousel.d.ts.map +1 -1
  9. package/dist/Carousel.js +13 -136
  10. package/dist/Checkbox.d.ts +55 -90
  11. package/dist/Checkbox.d.ts.map +1 -1
  12. package/dist/Checkbox.js +44 -38
  13. package/dist/Collection.d.ts +15 -15
  14. package/dist/Collection.js +7 -7
  15. package/dist/Combobox.d.ts +38 -187
  16. package/dist/Combobox.d.ts.map +1 -1
  17. package/dist/Combobox.js +9 -80
  18. package/dist/Component.d.ts +30 -24
  19. package/dist/Component.d.ts.map +1 -1
  20. package/dist/Component.js +23 -12
  21. package/dist/Composite.d.ts +50 -50
  22. package/dist/Composite.js +20 -20
  23. package/dist/Dialog.d.ts +34 -34
  24. package/dist/Dialog.d.ts.map +1 -1
  25. package/dist/Dialog.js +16 -14
  26. package/dist/Disclosure.d.ts +15 -15
  27. package/dist/Disclosure.js +6 -6
  28. package/dist/Dom/Events.d.ts +4 -4
  29. package/dist/Dom/Events.js +4 -4
  30. package/dist/Dom/Props.d.ts +9 -9
  31. package/dist/Dom/Props.js +4 -4
  32. package/dist/Dom/Refs.d.ts +2 -2
  33. package/dist/Dom/Refs.js +1 -1
  34. package/dist/Dom/Render.d.ts +2 -2
  35. package/dist/Dom/Render.js +2 -2
  36. package/dist/Dom/Types.d.ts +33 -33
  37. package/dist/Dom/index.d.ts +5 -5
  38. package/dist/Dom/index.d.ts.map +1 -1
  39. package/dist/Dom/index.js +4 -4
  40. package/dist/Dom.d.ts +1 -1
  41. package/dist/Dom.js +1 -1
  42. package/dist/Focusable.d.ts +5 -5
  43. package/dist/Focusable.js +1 -1
  44. package/dist/Form.d.ts +565 -533
  45. package/dist/Form.d.ts.map +1 -1
  46. package/dist/Form.js +350 -195
  47. package/dist/Grid.d.ts +39 -220
  48. package/dist/Grid.d.ts.map +1 -1
  49. package/dist/Grid.js +12 -107
  50. package/dist/Group.d.ts +50 -69
  51. package/dist/Group.d.ts.map +1 -1
  52. package/dist/Group.js +33 -25
  53. package/dist/Heading.d.ts +41 -40
  54. package/dist/Heading.d.ts.map +1 -1
  55. package/dist/Heading.js +26 -16
  56. package/dist/Hovercard.d.ts +18 -18
  57. package/dist/Hovercard.js +6 -6
  58. package/dist/HttpRouter.d.ts +3 -3
  59. package/dist/HttpRouter.js +5 -5
  60. package/dist/Link.d.ts +17 -21
  61. package/dist/Link.d.ts.map +1 -1
  62. package/dist/Link.js +11 -0
  63. package/dist/Listbox.d.ts +31 -163
  64. package/dist/Listbox.d.ts.map +1 -1
  65. package/dist/Listbox.js +9 -80
  66. package/dist/Menu.d.ts +67 -376
  67. package/dist/Menu.d.ts.map +1 -1
  68. package/dist/Menu.js +17 -179
  69. package/dist/Menubar.d.ts +24 -142
  70. package/dist/Menubar.d.ts.map +1 -1
  71. package/dist/Menubar.js +8 -66
  72. package/dist/Meter.d.ts +72 -132
  73. package/dist/Meter.d.ts.map +1 -1
  74. package/dist/Meter.js +35 -42
  75. package/dist/NativeDetails.d.ts +1 -1
  76. package/dist/NativeDetails.js +1 -1
  77. package/dist/NativeDialog.d.ts +7 -5
  78. package/dist/NativeDialog.d.ts.map +1 -1
  79. package/dist/NativeDialog.js +42 -4
  80. package/dist/NativePopover.d.ts +6 -4
  81. package/dist/NativePopover.d.ts.map +1 -1
  82. package/dist/NativePopover.js +43 -5
  83. package/dist/Popover.d.ts +18 -19
  84. package/dist/Popover.d.ts.map +1 -1
  85. package/dist/Popover.js +7 -8
  86. package/dist/RadioGroup.d.ts +86 -188
  87. package/dist/RadioGroup.d.ts.map +1 -1
  88. package/dist/RadioGroup.js +55 -105
  89. package/dist/Role.d.ts +4 -4
  90. package/dist/Role.js +1 -1
  91. package/dist/Select.d.ts +109 -220
  92. package/dist/Select.d.ts.map +1 -1
  93. package/dist/Select.js +67 -117
  94. package/dist/Separator.d.ts +30 -26
  95. package/dist/Separator.d.ts.map +1 -1
  96. package/dist/Separator.js +16 -10
  97. package/dist/Slider.d.ts +64 -111
  98. package/dist/Slider.d.ts.map +1 -1
  99. package/dist/Slider.js +47 -42
  100. package/dist/SpinButton.d.ts +64 -111
  101. package/dist/SpinButton.d.ts.map +1 -1
  102. package/dist/SpinButton.js +47 -42
  103. package/dist/Storybook.d.ts +2 -2
  104. package/dist/Storybook.js +1 -1
  105. package/dist/Switch.d.ts +52 -91
  106. package/dist/Switch.d.ts.map +1 -1
  107. package/dist/Switch.js +30 -36
  108. package/dist/Tabs.d.ts +44 -224
  109. package/dist/Tabs.d.ts.map +1 -1
  110. package/dist/Tabs.js +10 -94
  111. package/dist/Toolbar.d.ts +24 -142
  112. package/dist/Toolbar.d.ts.map +1 -1
  113. package/dist/Toolbar.js +8 -66
  114. package/dist/Tooltip.d.ts +20 -20
  115. package/dist/Tooltip.js +6 -6
  116. package/dist/Tree.d.ts +43 -229
  117. package/dist/Tree.d.ts.map +1 -1
  118. package/dist/Tree.js +12 -113
  119. package/dist/TreeGrid.d.ts +45 -264
  120. package/dist/TreeGrid.d.ts.map +1 -1
  121. package/dist/TreeGrid.js +13 -125
  122. package/dist/VisuallyHidden.d.ts +41 -27
  123. package/dist/VisuallyHidden.d.ts.map +1 -1
  124. package/dist/VisuallyHidden.js +27 -10
  125. package/dist/WindowSplitter.d.ts +68 -108
  126. package/dist/WindowSplitter.d.ts.map +1 -1
  127. package/dist/WindowSplitter.js +106 -23
  128. package/package.json +9 -8
package/dist/Form.d.ts CHANGED
@@ -1,148 +1,174 @@
1
+ /**
2
+ * Schema-bound native controls, decoded values, field errors, and submit lifetime.
3
+ * Start with make for application forms; explicit-state controls support library boundaries.
4
+ * Browser FormData conversion and structured input codecs are separate APIs.
5
+ *
6
+ * Read the [Form guide](/explore/ui-form) for a complete example.
7
+ *
8
+ * [Platform reference](https://html.spec.whatwg.org/multipage/forms.html#the-form-element).
9
+ * @since 1.0.0
10
+ * @category Overview
11
+ * @packageDocumentation
12
+ */
1
13
  import * as Effect from "effect/Effect";
2
14
  import * as Context from "effect/Context";
3
15
  import * as Schema from "effect/Schema";
4
16
  import { RefSubject } from "@typed/fx";
5
- import type * as Scope from "effect/Scope";
17
+ import * as Scope from "effect/Scope";
6
18
  import type { Fx } from "@typed/fx/Fx";
7
19
  import { EventHandler, type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
8
20
  import * as Dom from "./Dom.js";
9
21
  import type { HostResult } from "./Dom/Types.js";
10
22
  /**
11
- * Interaction metadata tracked for one form field.
23
+ * Metadata updated after a successful field mutation.
12
24
  *
13
25
  * @remarks
14
- * ## Why
15
- * Dirty and touched state belong to renderer-independent form state so they can
16
- * be tested without mounting UI and consumed by any host.
17
- *
18
- * ## Ownership and lifetime
19
- * Stored inside `FormState`; updates are owned by that RefSubject's Scope and
20
- * survive replacement of individual rendered controls.
21
- *
26
+ * dirty compares the new field value with defaultValues using !==, so object and array
27
+ * comparisons are by identity. touched becomes true for both user and programmatic updates; it
28
+ * is not specifically a blur flag.
22
29
  * @since 1.0.0
23
- * @category models
30
+ * @category State models
24
31
  */
25
32
  export interface FieldMeta {
26
- /** Stored mutation flag for the field; update operations decide when it becomes true. */
33
+ /**
34
+ * Whether the updated value differs from its default under !== comparison.
35
+ */
27
36
  readonly dirty: boolean;
28
- /** Whether user or programmatic field mutation has occurred. */
37
+ /**
38
+ * Whether user or programmatic field mutation has occurred.
39
+ */
29
40
  readonly touched: boolean;
30
41
  }
31
42
  /**
32
43
  * Serializable renderer-independent state of a form.
33
44
  *
34
45
  * @remarks
35
- * ## Why
36
46
  * Values, defaults, validation messages, interaction metadata, and submission
37
47
  * state can be inspected and tested without rendering a component.
38
48
  *
39
- * ## Ownership and lifetime
40
49
  * A `FormState` RefSubject owns this value. Renderers subscribe to it; they do
41
50
  * not contain or become the source of truth.
42
- *
43
51
  * @since 1.0.0
44
- * @category models
52
+ * @category State models
45
53
  */
46
54
  export interface State<Values extends object = object> {
47
- /** Current decoded field values. */
55
+ /**
56
+ * Current decoded field values.
57
+ */
48
58
  readonly values: Values;
49
- /** Exact baseline reference used by reset and retained independently from current values. */
59
+ /**
60
+ * Exact baseline reference used by reset and retained independently from current values.
61
+ */
50
62
  readonly defaultValues: Values;
51
- /** Current validation messages keyed by field name. */
63
+ /**
64
+ * Current validation messages keyed by field name.
65
+ */
52
66
  readonly errors: Partial<Record<keyof Values & string, string>>;
53
- /** Dirty/touched metadata keyed by field name. */
67
+ /**
68
+ * Dirty/touched metadata keyed by field name.
69
+ */
54
70
  readonly meta: Partial<Record<keyof Values & string, FieldMeta>>;
55
- /** Whether a valid-submit Effect is currently running. */
71
+ /**
72
+ * Whether validation or the returned submit Effect is running.
73
+ */
56
74
  readonly submitting: boolean;
57
75
  }
58
76
  /**
59
77
  * Input used to construct a hydrated form state.
60
78
  *
61
79
  * @remarks
62
- * ## Why
63
80
  * Defaults make the common case concise while allowing SSR callers to provide
64
81
  * deterministic identity and server-known validation state.
65
82
  *
66
- * ## Ownership and lifetime
67
83
  * `values` and an explicit `defaultValues` are retained by reference, including
68
84
  * their nested objects. When `defaultValues` is omitted, both state fields
69
85
  * initially reference the exact `values` object. Subsequent helpers replace the
70
86
  * top-level `values` record but do not deep-clone nested values.
71
- *
72
87
  * @since 1.0.0
73
- * @category models
88
+ * @category State models
74
89
  */
75
90
  export interface InitialState<Values extends object> {
76
- /** Stable relationship/hydration id; provide it for deterministic SSR. */
91
+ /**
92
+ * Stable relationship/hydration id; provide it for deterministic SSR.
93
+ */
77
94
  readonly id?: string;
78
- /** Initial decoded values. */
95
+ /**
96
+ * Initial decoded values.
97
+ */
79
98
  readonly values: Values;
80
- /** Exact reset-baseline reference; defaults to the same object as `values`. */
99
+ /**
100
+ * Exact reset-baseline reference; defaults to the same object as `values`.
101
+ */
81
102
  readonly defaultValues?: Values;
82
- /** Optional initial validation messages. */
103
+ /**
104
+ * Optional initial validation messages.
105
+ */
83
106
  readonly errors?: Partial<Record<keyof Values & string, string>>;
84
- /** Optional initial field metadata. */
107
+ /**
108
+ * Optional initial field metadata.
109
+ */
85
110
  readonly meta?: Partial<Record<keyof Values & string, FieldMeta>>;
86
- /** Optional initial submission state. */
111
+ /**
112
+ * Whether validation or the returned submit Effect is running.
113
+ */
87
114
  readonly submitting?: boolean;
88
115
  }
89
116
  /**
90
117
  * Hydrated RefSubject carrying form state plus runtime schema metadata.
91
118
  *
92
119
  * @remarks
93
- * ## Why
94
120
  * State is serializable across SSR while codecs and field validators stay as
95
121
  * runtime capabilities. This keeps validation type-safe without trying to
96
122
  * serialize executable schemas.
97
123
  *
98
- * ## Ownership and lifetime
99
124
  * The surrounding Effect Scope owns the hydrated RefSubject and its subscribers.
100
125
  * On the server, serializable state is emitted for hydration; on the client it
101
126
  * must be restored before mounted controls begin producing updates.
102
- *
103
127
  * @since 1.0.0
104
- * @category models
128
+ * @category State models
105
129
  */
106
130
  export type FormState<Values extends object> = RefSubject.HydratedRefSubject<State<Values>, Schema.SchemaError> & {
107
- /** Runtime identity used to scope field/error relationships. Pass an id for deterministic SSR. */
131
+ /**
132
+ * Runtime identity used to scope field/error relationships. Pass an id for deterministic SSR.
133
+ */
108
134
  readonly id: string;
109
- /** Runtime-only validation codec; it is deliberately absent from hydration state. */
135
+ /**
136
+ * Runtime-only validation codec; it is deliberately absent from hydration state.
137
+ */
110
138
  readonly codec: Schema.Codec<Values, unknown>;
111
- /** Runtime field codecs used for field-level validation. */
139
+ /**
140
+ * Runtime field codecs used for field-level validation.
141
+ */
112
142
  readonly fields: Readonly<Record<keyof Values & string, Schema.Codec<any, any>>>;
113
143
  };
114
144
  /**
115
145
  * Context service exposed to schema-bound descendant controls.
116
146
  *
117
147
  * @remarks
118
- * ## Why
119
148
  * A bound form can share its state through Effect context without a component tree.
120
149
  *
121
- * ## Ownership and lifetime
122
150
  * The root form provides the service only for its rendered Fx lifetime; it does
123
151
  * not own the underlying state beyond that state's Scope.
124
- *
125
152
  * @since 1.0.0
126
- * @category services
153
+ * @category Form context
127
154
  */
128
155
  export interface FormService<Values extends object> {
129
- /** Form state visible to bound descendants. */
156
+ /**
157
+ * Form state visible to bound descendants.
158
+ */
130
159
  readonly state: FormState<Values>;
131
160
  }
132
161
  /**
133
162
  * Effect context service used by schema-bound form controls.
134
163
  *
135
164
  * @remarks
136
- * ## Why
137
165
  * Bound controls avoid threading `state` through every call while their
138
166
  * service requirement remains visible in the Fx type.
139
167
  *
140
- * ## Ownership and lifetime
141
168
  * `Form` provides the service for its child render lifetime; use outside that
142
169
  * boundary fails with the ordinary Effect missing-service defect.
143
- *
144
170
  * @since 1.0.0
145
- * @category services
171
+ * @category Form context
146
172
  */
147
173
  export declare const CurrentForm: Context.Service<FormService<any>, FormService<any>>;
148
174
  declare const FieldMetaSchema: Schema.Struct<{
@@ -153,14 +179,11 @@ declare const FieldMetaSchema: Schema.Struct<{
153
179
  * Schema field map accepted by the schema-bound form factory.
154
180
  *
155
181
  * @remarks
156
- * ## Why
157
182
  * A Struct's individual codecs drive field-name inference and field-level decoding.
158
183
  *
159
- * ## Ownership and lifetime
160
184
  * Codecs are runtime values retained by the created form API; they are not hydrated.
161
- *
162
185
  * @since 1.0.0
163
- * @category models
186
+ * @category State models
164
187
  */
165
188
  export type FormFields = Readonly<Record<string, Schema.Codec<any, any>>>;
166
189
  type OptionalFields<Fields extends FormFields, Value extends Schema.Constraint> = {
@@ -178,10 +201,8 @@ type InitialStateFor<Fields extends FormFields> = {
178
201
  * Builds the serializable schema for a form's hydrated state.
179
202
  *
180
203
  * @remarks
181
- * ## Why
182
204
  * The hydration payload needs validation independent from runtime-only field codecs.
183
205
  *
184
- * ## Ownership and lifetime
185
206
  * Pure schema construction; the returned Schema acquires no Scope or subscription.
186
207
  *
187
208
  * @example
@@ -192,9 +213,8 @@ type InitialStateFor<Fields extends FormFields> = {
192
213
  * const codec = Schema.Struct({ email: Schema.String })
193
214
  * const stateCodec = StateSchema(codec)
194
215
  * ```
195
- *
196
216
  * @since 1.0.0
197
- * @category schemas
217
+ * @category Hydration schemas
198
218
  */
199
219
  export declare function StateSchema<const Fields extends FormFields>(codec: Schema.Struct<Fields>): Schema.Struct<{
200
220
  readonly values: Schema.Struct<Fields>;
@@ -210,11 +230,9 @@ export declare function StateSchema<const Fields extends FormFields>(codec: Sche
210
230
  * Creates a Scope-owned hydrated form RefSubject from a Struct codec.
211
231
  *
212
232
  * @remarks
213
- * ## Why
214
233
  * One constructor establishes values, defaults, validation state, field codecs,
215
234
  * and hydration identity consistently.
216
235
  *
217
- * ## Ownership and lifetime
218
236
  * Requires `Scope.Scope`. Provide an explicit `id` during SSR; the counter-based
219
237
  * fallback is process/order dependent. Only state data hydrates—`codec` and
220
238
  * `fields` are reattached from the live Struct on each runtime.
@@ -230,9 +248,8 @@ export declare function StateSchema<const Fields extends FormFields>(codec: Sche
230
248
  * return state
231
249
  * })
232
250
  * ```
233
- *
234
251
  * @since 1.0.0
235
- * @category constructors
252
+ * @category State construction
236
253
  */
237
254
  export declare function makeState<const Fields extends FormFields>(codec: Schema.Struct<Fields>, initial: InitialStateFor<Fields>): Effect.Effect<RefSubject.HydratedRefSubject<{
238
255
  readonly values: Schema.Struct.View<Fields, "Type", Schema.Struct.TypeOptionalKeys<Fields>, Schema.Struct.TypeMutableKeys<Fields>>;
@@ -276,14 +293,9 @@ export declare function makeState<const Fields extends FormFields>(codec: Schema
276
293
  * Field names whose decoded value is assignable to `Value`.
277
294
  *
278
295
  * @remarks
279
- * ## Why
280
296
  * Control options reject incompatible fields at compile time.
281
- *
282
- * ## Ownership and lifetime
283
- * Type-only and resource-free.
284
- *
285
297
  * @since 1.0.0
286
- * @category type-level
298
+ * @category Field types
287
299
  */
288
300
  export type FieldNameFor<Values extends object, Value> = {
289
301
  [Key in keyof Values & string]: Values[Key] extends Value ? Key : never;
@@ -292,242 +304,242 @@ export type FieldNameFor<Values extends object, Value> = {
292
304
  * Struct field names matching both decoded and encoded control value types.
293
305
  *
294
306
  * @remarks
295
- * ## Why
296
307
  * Schema-bound controls require an encoded form compatible with the native element.
297
- *
298
- * ## Ownership and lifetime
299
- * Type-only and resource-free.
300
- *
301
308
  * @since 1.0.0
302
- * @category type-level
309
+ * @category Field types
303
310
  */
304
311
  export type SchemaFieldNameFor<Fields extends FormFields, Value, Encoded> = {
305
312
  [Key in keyof Fields & string]: Fields[Key]["Type"] extends Value ? Fields[Key]["Encoded"] extends Encoded ? Key : never : never;
306
313
  }[keyof Fields & string];
307
314
  /**
308
- * Options shared by state-explicit native input components.
315
+ * State-explicit native input binding with a compatible field name and optional string codec.
309
316
  *
310
317
  * @remarks
311
- * ## Why
312
- * Controls bind a typed field directly to renderer-independent state while
313
- * leaving every ordinary input prop and native event available.
314
- *
315
- * ## Ownership and lifetime
316
- * The rendered control subscribes within its Scope. `state` remains independently
317
- * owned and may outlive that control; custom codecs are retained for that host.
318
- *
318
+ * Successful native input decoding updates values and metadata; failure records an error while
319
+ * retaining the last decoded value. Rendering encodes the retained value into .value, so
320
+ * arbitrary invalid draft text is not guaranteed to remain visible. Native constraints and codec
321
+ * validation are separate boundaries.
319
322
  * @since 1.0.0
320
- * @category component-options
323
+ * @category Component options
321
324
  */
322
325
  export interface InputOptions<Values extends object, Value> extends Dom.HostOptions<HTMLInputElement> {
323
- /** Renderer-independent form state to read and update. */
326
+ /**
327
+ * Renderer-independent form state to read and update.
328
+ */
324
329
  readonly state: FormState<Values>;
325
- /** Type-compatible field name. */
330
+ /**
331
+ * Type-compatible field name.
332
+ */
326
333
  readonly name: FieldNameFor<Values, Value>;
327
- /** Optional string codec overriding the input type's default codec. */
334
+ /**
335
+ * Optional string codec overriding the input type's default codec.
336
+ */
328
337
  readonly codec?: Schema.Codec<Value, string>;
329
338
  }
330
339
  /**
331
340
  * String-valued native input options.
332
341
  * @remarks
333
- * ## Why
334
342
  * Names are restricted to fields a text-like control can represent without an incompatible cast.
335
- * ## Ownership and lifetime
336
343
  * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
337
344
  * @since 1.0.0
338
- * @category component-options
345
+ * @category Component options
339
346
  */
340
347
  export type TextInputOptions<Values extends object> = InputOptions<Values, string>;
341
348
  /**
342
349
  * Finite-number native input options.
343
350
  * @remarks
344
- * ## Why
345
351
  * Names are restricted to numeric fields compatible with number/range decoding.
346
- * ## Ownership and lifetime
347
352
  * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
348
353
  * @since 1.0.0
349
- * @category component-options
354
+ * @category Component options
350
355
  */
351
356
  export type NumberInputOptions<Values extends object> = InputOptions<Values, number>;
352
357
  /**
353
358
  * Date-valued native input options.
354
359
  * @remarks
355
- * ## Why
356
360
  * Names are restricted to Date fields compatible with native date-string decoding.
357
- * ## Ownership and lifetime
358
361
  * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
359
362
  * @since 1.0.0
360
- * @category component-options
363
+ * @category Component options
361
364
  */
362
365
  export type DateInputOptions<Values extends object> = InputOptions<Values, Date>;
363
- declare function inputProps<Values extends object, Value>(options: InputOptions<Values, Value>, type: string, codec: Schema.Codec<Value, string>): () => {
366
+ declare function inputProps<Values extends object, Value>(options: InputOptions<Values, Value>, type: string, codec: Schema.Codec<Value, string>): (() => {
364
367
  readonly type: string;
365
368
  readonly name: FieldNameFor<Values, Value>;
366
369
  readonly "aria-describedby": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
367
370
  readonly "aria-invalid": RefSubject.Computed<true | undefined, Schema.SchemaError, never>;
368
371
  readonly ".value": RefSubject.Computed<string, Schema.SchemaError, never>;
369
372
  readonly oninput: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
370
- };
373
+ }) | (() => {
374
+ readonly type: string;
375
+ readonly name: FieldNameFor<Values, Value>;
376
+ readonly "aria-describedby": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
377
+ readonly "aria-invalid": RefSubject.Computed<true | undefined, Schema.SchemaError, never>;
378
+ readonly ".value": Effect.Effect<string, Schema.SchemaError, never>;
379
+ readonly ref: (element: HTMLInputElement) => Effect.Effect<void, Schema.SchemaError, Scope.Scope>;
380
+ readonly onbeforeinput: EventHandler.EventHandler<InputEvent, Schema.SchemaError, never>;
381
+ readonly oninput: EventHandler.EventHandler<InputEvent, Schema.SchemaError, never>;
382
+ readonly oncompositionstart: EventHandler.EventHandler<Event, never, never>;
383
+ readonly oncompositionend: EventHandler.EventHandler<CompositionEvent, Schema.SchemaError, never>;
384
+ });
371
385
  type InputProps<Values extends object, Value> = ReturnType<ReturnType<typeof inputProps<Values, Value>>>;
372
386
  type RenderableComponentOptions<Options> = Pick<Options, Extract<keyof Options, "props" | "ref" | "content" | Dom.EventHandlerProperty>>;
373
387
  /**
374
388
  * Options for a schema-bound native input.
375
389
  *
376
390
  * @remarks
377
- * ## Why
378
391
  * The factory's Struct infers compatible field names, so callers need not pass state or a codec.
379
392
  *
380
- * ## Ownership and lifetime
381
393
  * State is borrowed from `CurrentForm`; the control's Scope owns its DOM subscription.
382
- *
383
394
  * @since 1.0.0
384
- * @category component-options
395
+ * @category Component options
385
396
  */
386
397
  export interface SchemaBoundInputOptions<Fields extends FormFields, Value> extends Dom.HostOptions<HTMLInputElement> {
387
- /** Struct field whose decoded type matches `Value` and whose encoded type is string. */
398
+ /**
399
+ * Struct field whose decoded type matches `Value` and whose encoded type is string.
400
+ */
388
401
  readonly name: SchemaFieldNameFor<Fields, Value, string>;
389
402
  }
390
403
  /**
391
404
  * Options for a schema-bound masked text input.
392
405
  *
393
406
  * @remarks
394
- * ## Why
395
407
  * Any field with a string encoding can use the Struct field codec as its mask codec.
396
408
  *
397
- * ## Ownership and lifetime
398
409
  * State is borrowed from `CurrentForm`; the control Scope owns DOM work.
399
- *
400
410
  * @since 1.0.0
401
- * @category component-options
411
+ * @category Component options
402
412
  */
403
413
  export interface SchemaBoundMaskedInputOptions<Fields extends FormFields> extends Dom.HostOptions<HTMLInputElement> {
404
- /** Struct field whose codec accepts the input's string representation. */
414
+ /**
415
+ * Struct field whose codec accepts the input's string representation.
416
+ */
405
417
  readonly name: SchemaFieldNameFor<Fields, unknown, string>;
406
418
  }
407
419
  /**
408
420
  * Options for a schema-bound boolean checkbox.
409
421
  *
410
422
  * @remarks
411
- * ## Why
412
423
  * Field-name inference limits the native checked binding to boolean fields.
413
424
  *
414
- * ## Ownership and lifetime
415
425
  * State is borrowed from `CurrentForm`; the control Scope owns DOM work.
416
- *
417
426
  * @since 1.0.0
418
- * @category component-options
427
+ * @category Component options
419
428
  */
420
429
  export interface SchemaBoundCheckboxOptions<Values extends object> extends Dom.HostOptions<HTMLInputElement> {
421
- /** Boolean field controlled by the checkbox. */
430
+ /**
431
+ * Boolean field controlled by the checkbox.
432
+ */
422
433
  readonly name: BooleanFieldName<Values>;
423
434
  }
424
435
  /**
425
436
  * Options for a schema-bound native select.
426
437
  *
427
438
  * @remarks
428
- * ## Why
429
439
  * Native option markup remains caller-authored while selection binds to a string field.
430
440
  *
431
- * ## Ownership and lifetime
432
441
  * State is borrowed from `CurrentForm`; rendered content is owned by the control Scope.
433
- *
434
442
  * @since 1.0.0
435
- * @category component-options
443
+ * @category Component options
436
444
  */
437
445
  export interface SchemaBoundSelectOptions<Values extends object> extends Dom.HostOptions<HTMLSelectElement> {
438
- /** String field controlled by the select. */
446
+ /**
447
+ * String field controlled by the select.
448
+ */
439
449
  readonly name: FieldNameFor<Values, string>;
440
- /** Native option/optgroup renderable content. */
450
+ /**
451
+ * Native option/optgroup renderable content.
452
+ */
441
453
  readonly content: Renderable.Any;
442
454
  }
443
455
  /**
444
456
  * Options for a schema-bound field-error region.
445
457
  *
446
458
  * @remarks
447
- * ## Why
448
459
  * Error text and ARIA relationships derive from the same form identity and field name.
449
460
  *
450
- * ## Ownership and lifetime
451
461
  * State is borrowed from `CurrentForm`; the error host Scope owns its subscription.
452
- *
453
462
  * @since 1.0.0
454
- * @category component-options
463
+ * @category Component options
455
464
  */
456
465
  export interface SchemaBoundErrorOptions<Values extends object> extends Dom.HostOptions<HTMLDivElement> {
457
- /** Field whose current validation message is rendered. */
466
+ /**
467
+ * Field whose current validation message is rendered.
468
+ */
458
469
  readonly name: keyof Values & string;
459
470
  }
460
471
  /**
461
472
  * Options for a schema-bound reset button.
462
473
  *
463
474
  * @remarks
464
- * ## Why
465
475
  * The button can use native semantics without receiving state explicitly.
466
476
  *
467
- * ## Ownership and lifetime
468
477
  * State is borrowed from `CurrentForm`; button content is Scope-owned renderable work.
469
- *
470
478
  * @since 1.0.0
471
- * @category component-options
479
+ * @category Component options
472
480
  */
473
481
  export interface SchemaBoundResetOptions extends Dom.HostOptions<HTMLButtonElement> {
474
- /** Reset button label/content. */
482
+ /**
483
+ * Reset button label/content.
484
+ */
475
485
  readonly content: Renderable.Any;
476
486
  }
477
487
  /**
478
488
  * Options for a schema-bound array append button.
479
489
  *
480
490
  * @remarks
481
- * ## Why
482
491
  * Array field and element types are inferred from the form schema.
483
492
  *
484
- * ## Ownership and lifetime
485
493
  * State is borrowed from `CurrentForm`; the click Effect and content share the host Scope.
486
- *
487
494
  * @since 1.0.0
488
- * @category component-options
495
+ * @category Component options
489
496
  */
490
497
  export interface SchemaBoundPushOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
491
- /** Array-valued field to append to. */
498
+ /**
499
+ * Array-valued field to append to.
500
+ */
492
501
  readonly name: Name;
493
- /** Type-compatible item appended on activation. */
502
+ /**
503
+ * Type-compatible item appended on activation.
504
+ */
494
505
  readonly value: ArrayFieldValue<Values, Name>;
495
- /** Button label/content. */
506
+ /**
507
+ * Button label/content.
508
+ */
496
509
  readonly content: Renderable.Any;
497
510
  }
498
511
  /**
499
512
  * Options for a schema-bound array removal button.
500
513
  *
501
514
  * @remarks
502
- * ## Why
503
515
  * The field is constrained to arrays and the index remains an explicit local operation.
504
516
  *
505
- * ## Ownership and lifetime
506
517
  * State is borrowed from `CurrentForm`; the click Effect and content share the host Scope.
507
- *
508
518
  * @since 1.0.0
509
- * @category component-options
519
+ * @category Component options
510
520
  */
511
521
  export interface SchemaBoundRemoveOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
512
- /** Array-valued field to remove from. */
522
+ /**
523
+ * Array-valued field to remove from.
524
+ */
513
525
  readonly name: Name;
514
- /** Zero-based item index removed on activation. */
526
+ /**
527
+ * Zero-based item index removed on activation.
528
+ */
515
529
  readonly index: number;
516
- /** Button label/content. */
530
+ /**
531
+ * Button label/content.
532
+ */
517
533
  readonly content: Renderable.Any;
518
534
  }
519
535
  /**
520
536
  * Public component contract shared by state-explicit native input factories.
521
537
  *
522
538
  * @remarks
523
- * ## Why
524
- *
525
539
  * Text-like, numeric, range, and date controls differ in their default codec while preserving one
526
540
  * field-inference, host-override, error, and service contract. Naming that contract keeps emitted
527
541
  * declarations readable without hiding any generic channel behind a private compiler alias.
528
542
  *
529
- * ## Ownership and lifetime
530
- *
531
543
  * Calling an input component starts no work. The returned Fx requires the Scope and RenderTemplate
532
544
  * that own DOM rendering; the supplied FormState remains independently owned and may outlive it.
533
545
  *
@@ -545,20 +557,17 @@ export interface SchemaBoundRemoveOptions<Values extends object, Name extends Ar
545
557
  * return Text({ state, name: "name" }, (props) => html`<input ...${props} />`)
546
558
  * })
547
559
  * ```
548
- *
549
560
  * @since 1.0.0
550
- * @category models
561
+ * @category Native controls
551
562
  */
552
563
  export type InputComponent<Value> = <const Values extends object, const Options extends InputOptions<Values, Value>, const Host extends HostResult = never>(options: Options & Pick<InputOptions<Values, Value>, "state" | "name">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, InputProps<Values, Value>>, "", Host>) => Fx<RenderEvent, Schema.SchemaError | Renderable.Error<RenderableComponentOptions<Options> | Host>, Renderable.Services<RenderableComponentOptions<Options> | Host> | Scope.Scope | RenderTemplate>;
553
564
  /**
554
565
  * Binds a native `input[type=text]` to a string field.
555
566
  *
556
567
  * @remarks
557
- * ## Why
558
568
  * The control uses the browser's real input event and a Schema codec while
559
569
  * keeping state independently testable.
560
570
  *
561
- * ## Ownership and lifetime
562
571
  * The control Scope owns DOM listeners/subscriptions; the supplied `FormState`
563
572
  * may outlive the rendered input. A custom host must apply all merged props.
564
573
  *
@@ -573,195 +582,142 @@ export type InputComponent<Value> = <const Values extends object, const Options
573
582
  * return TextInput({ state, name: "name" })
574
583
  * })
575
584
  * ```
576
- *
577
585
  * @since 1.0.0
578
- * @category components
586
+ * @category Native controls
579
587
  */
580
588
  export declare const TextInput: InputComponent<string>;
581
589
  /**
582
590
  * Binds a native search input to a string field.
583
591
  * @remarks
584
- * ## Why
585
592
  * Preserves the platform's search-input semantics while sharing Typed validation.
586
- * ## Ownership and lifetime
587
- * DOM work is control-Scope-owned; form state remains independently owned.
588
593
  * @since 1.0.0
589
- * @category components
594
+ * @category Native controls
590
595
  */
591
596
  export declare const SearchInput: InputComponent<string>;
592
597
  /**
593
598
  * Binds a native email input to a string field.
594
599
  * @remarks
595
- * ## Why
596
600
  * Keeps browser email affordances and constraints available alongside Schema validation.
597
- * ## Ownership and lifetime
598
- * DOM work is control-Scope-owned; form state remains independently owned.
599
601
  * @since 1.0.0
600
- * @category components
602
+ * @category Native controls
601
603
  */
602
604
  export declare const EmailInput: InputComponent<string>;
603
605
  /**
604
606
  * Binds a native URL input to a string field.
605
607
  * @remarks
606
- * ## Why
607
608
  * Keeps browser URL affordances while the schema remains the decoded state contract.
608
- * ## Ownership and lifetime
609
- * DOM work is control-Scope-owned; form state remains independently owned.
610
609
  * @since 1.0.0
611
- * @category components
610
+ * @category Native controls
612
611
  */
613
612
  export declare const UrlInput: InputComponent<string>;
614
613
  /**
615
614
  * Binds a native telephone input to a string field.
616
615
  * @remarks
617
- * ## Why
618
616
  * Preserves platform telephone keyboards and autocomplete behavior.
619
- * ## Ownership and lifetime
620
- * DOM work is control-Scope-owned; form state remains independently owned.
621
617
  * @since 1.0.0
622
- * @category components
618
+ * @category Native controls
623
619
  */
624
620
  export declare const TelInput: InputComponent<string>;
625
621
  /**
626
622
  * Binds a native password input to a string field.
627
623
  * @remarks
628
- * ## Why
629
624
  * Uses browser password handling instead of recreating sensitive-input behavior.
630
- * ## Ownership and lifetime
631
- * DOM work is control-Scope-owned; form state remains independently owned.
632
625
  * @since 1.0.0
633
- * @category components
626
+ * @category Native controls
634
627
  */
635
628
  export declare const PasswordInput: InputComponent<string>;
636
629
  /**
637
630
  * Binds a native hidden input to a string field.
638
631
  * @remarks
639
- * ## Why
640
632
  * Allows standards-based form serialization for non-visible values.
641
- * ## Ownership and lifetime
642
- * DOM work is control-Scope-owned; form state remains independently owned.
643
633
  * @since 1.0.0
644
- * @category components
634
+ * @category Native controls
645
635
  */
646
636
  export declare const HiddenInput: InputComponent<string>;
647
637
  /**
648
638
  * Binds a native color input to a string field.
649
639
  * @remarks
650
- * ## Why
651
640
  * Retains the browser's color picker while state receives its string value.
652
- * ## Ownership and lifetime
653
- * DOM work is control-Scope-owned; form state remains independently owned.
654
641
  * @since 1.0.0
655
- * @category components
642
+ * @category Native controls
656
643
  */
657
644
  export declare const ColorInput: InputComponent<string>;
658
645
  /**
659
646
  * Binds a native time input to a string field.
660
647
  * @remarks
661
- * ## Why
662
648
  * Preserves browser locale and time-entry behavior without inventing a picker.
663
- * ## Ownership and lifetime
664
- * DOM work is control-Scope-owned; form state remains independently owned.
665
649
  * @since 1.0.0
666
- * @category components
650
+ * @category Native controls
667
651
  */
668
652
  export declare const TimeInput: InputComponent<string>;
669
653
  /**
670
654
  * Binds a native local date-time input to a string field.
671
655
  * @remarks
672
- * ## Why
673
656
  * Keeps the platform's local date-time UI and its standard encoded value.
674
- * ## Ownership and lifetime
675
- * DOM work is control-Scope-owned; form state remains independently owned.
676
657
  * @since 1.0.0
677
- * @category components
658
+ * @category Native controls
678
659
  */
679
660
  export declare const DateTimeLocalInput: InputComponent<string>;
680
661
  /**
681
662
  * Binds a native month input to a string field.
682
663
  * @remarks
683
- * ## Why
684
664
  * Preserves the browser month picker and standardized string encoding.
685
- * ## Ownership and lifetime
686
- * DOM work is control-Scope-owned; form state remains independently owned.
687
665
  * @since 1.0.0
688
- * @category components
666
+ * @category Native controls
689
667
  */
690
668
  export declare const MonthInput: InputComponent<string>;
691
669
  /**
692
670
  * Binds a native week input to a string field.
693
671
  * @remarks
694
- * ## Why
695
672
  * Preserves platform week-entry behavior and standardized string encoding.
696
- * ## Ownership and lifetime
697
- * DOM work is control-Scope-owned; form state remains independently owned.
698
673
  * @since 1.0.0
699
- * @category components
674
+ * @category Native controls
700
675
  */
701
676
  export declare const WeekInput: InputComponent<string>;
702
677
  /**
703
678
  * Binds a native number input to a finite number field.
704
679
  * @remarks
705
- * ## Why
706
680
  * `FiniteFromString` makes the browser's string value an explicit typed decode.
707
- * ## Ownership and lifetime
708
- * DOM work is control-Scope-owned; form state remains independently owned.
709
681
  * @since 1.0.0
710
- * @category components
682
+ * @category Native controls
711
683
  */
712
684
  export declare const NumberInput: InputComponent<number>;
713
685
  /**
714
686
  * Binds a native range input to a finite number field.
715
687
  * @remarks
716
- * ## Why
717
688
  * Retains native slider interaction while exposing a decoded numeric value.
718
- * ## Ownership and lifetime
719
- * DOM work is control-Scope-owned; form state remains independently owned.
720
689
  * @since 1.0.0
721
- * @category components
690
+ * @category Native controls
722
691
  */
723
692
  export declare const RangeInput: InputComponent<number>;
724
693
  /**
725
694
  * Binds a native date input to a `Date` field.
726
695
  * @remarks
727
- * ## Why
728
696
  * `DateFromString` makes the native encoded value's conversion explicit and fallible.
729
- * ## Ownership and lifetime
730
- * DOM work is control-Scope-owned; form state remains independently owned.
731
697
  * @since 1.0.0
732
- * @category components
698
+ * @category Native controls
733
699
  */
734
700
  export declare const DateInput: InputComponent<Date>;
735
701
  /**
736
702
  * Native value emitted by `FormData`.
737
703
  * @remarks
738
- * ## Why
739
704
  * Browser serialization produces strings and Files; the union states that boundary exactly.
740
- * ## Ownership and lifetime
741
705
  * Files remain browser-owned objects referenced by the converted record.
742
706
  * @since 1.0.0
743
- * @category models
707
+ * @category Browser form data
744
708
  */
745
709
  export type FormDataValue = string | File;
746
710
  /**
747
711
  * Object representation of native FormData, preserving repeated names as arrays.
748
712
  * @remarks
749
- * ## Why
750
713
  * A plain record is directly consumable by Effect Schema without losing repeats.
751
- * ## Ownership and lifetime
752
714
  * Conversion allocates arrays/record entries but retains original File objects.
753
715
  * @since 1.0.0
754
- * @category models
716
+ * @category Browser form data
755
717
  */
756
718
  export type FormDataRecord = Readonly<Record<string, FormDataValue | ReadonlyArray<FormDataValue>>>;
757
719
  /**
758
- * Converts native FormData to a record and preserves repeated fields as arrays.
759
- * @remarks
760
- * ## Why
761
- * `Object.fromEntries` silently loses repeated names, which breaks checkbox,
762
- * multiselect, and multi-file submissions.
763
- * ## Ownership and lifetime
764
- * The function is synchronous and resource-free; File values are not cloned.
720
+ * Converts native form data to a record, preserving repeated names as arrays.
765
721
  * @example
766
722
  * ```ts
767
723
  * import { formDataToRecord } from "@typed/ui/Form"
@@ -772,16 +728,14 @@ export type FormDataRecord = Readonly<Record<string, FormDataValue | ReadonlyArr
772
728
  * const record = formDataToRecord(data)
773
729
  * ```
774
730
  * @since 1.0.0
775
- * @category conversions
731
+ * @category Browser form data
776
732
  */
777
733
  export declare function formDataToRecord(data: FormData): FormDataRecord;
778
734
  /**
779
735
  * Decodes native FormData through an Effect Schema codec.
780
736
  * @remarks
781
- * ## Why
782
737
  * Browser serialization, repeated values, Files, and typed validation meet at
783
738
  * one explicit fallible boundary.
784
- * ## Ownership and lifetime
785
739
  * The returned Effect is lazy and owns no browser resource; it references File
786
740
  * objects present in the supplied FormData.
787
741
  * @example
@@ -792,63 +746,62 @@ export declare function formDataToRecord(data: FormData): FormDataRecord;
792
746
  * const decode = decodeFormData(Schema.Struct({ name: Schema.String }), new FormData())
793
747
  * ```
794
748
  * @since 1.0.0
795
- * @category conversions
749
+ * @category Browser form data
796
750
  */
797
751
  export declare function decodeFormData<Values extends object, Codec extends Schema.Codec<Values, unknown>>(codec: Codec, data: FormData): Effect.Effect<Codec["Type"], Schema.SchemaError, Codec["DecodingServices"]>;
798
752
  /**
799
- * Validates current form values and synchronizes decoded values or field errors.
753
+ * Checks retained decoded values against the form codec Type.
754
+ *
800
755
  * @remarks
801
- * ## Why
802
- * Submission needs one whole-form schema check in addition to incremental field decoding.
803
- * ## Ownership and lifetime
804
- * The returned Effect updates the supplied state when run. On success it clears
805
- * errors; on failure it records messages and re-fails with `SchemaError`.
756
+ * Success replaces values and clears errors. Failure copies the aggregate schema message across
757
+ * fields and re-fails with SchemaError; this is not per-field issue-path mapping. A prior input
758
+ * decode error does not independently block success when the retained decoded value still
759
+ * validates.
806
760
  * @since 1.0.0
807
- * @category validation
761
+ * @category Validation
808
762
  */
809
763
  export declare function validate<Values extends object>(state: FormState<Values>): Effect.Effect<Values, Schema.SchemaError, never>;
810
764
  /**
811
765
  * Named decoded segment in a bidirectional text mask.
812
766
  * @remarks
813
- * ## Why
814
- * Slots make structured display strings type-safe and Schema-driven rather than cursor heuristics.
815
- * ## Ownership and lifetime
816
- * A slot retains its codec and optional validation constraints; it acquires no Scope.
767
+ * The codec preserves the slot's domain type. Supply a fixed length and charset
768
+ * when the input should insert unambiguous surrounding literals while editing.
769
+ * Use string codecs for identifiers such as phone segments that may start with zero.
817
770
  * @since 1.0.0
818
- * @category models
771
+ * @category Input codecs
819
772
  */
820
773
  export interface MaskSlot<Name extends string = string, Value = unknown> {
821
- /** Discriminant used to distinguish slots from literal mask parts. */
774
+ /**
775
+ * Discriminant used to distinguish slots from literal mask parts.
776
+ */
822
777
  readonly _tag: "MaskSlot";
823
- /** Property name written into the decoded mask object. */
778
+ /**
779
+ * Property name written into the decoded mask object.
780
+ */
824
781
  readonly name: Name;
825
- /** Bidirectional conversion between this slot's string segment and decoded value. */
782
+ /**
783
+ * Bidirectional conversion between this slot's string segment and decoded value.
784
+ */
826
785
  readonly codec: Schema.Codec<Value, string>;
827
- /** Exact encoded character count, when fixed-width. */
786
+ /**
787
+ * Exact encoded character count, when fixed-width.
788
+ */
828
789
  readonly length?: number;
829
- /** Per-character acceptance test applied before Schema decoding. */
790
+ /**
791
+ * Per-character acceptance test applied before Schema decoding.
792
+ */
830
793
  readonly charset?: RegExp | ((character: string) => boolean);
831
794
  }
832
795
  /**
833
796
  * Literal or decoded segment of a mask.
834
797
  * @remarks
835
- * ## Why
836
798
  * The tuple order completely specifies parsing and formatting.
837
- * ## Ownership and lifetime
838
799
  * Immutable description data with no runtime ownership.
839
800
  * @since 1.0.0
840
- * @category models
801
+ * @category Input codecs
841
802
  */
842
803
  export type MaskPart = string | MaskSlot;
843
804
  /**
844
- * Decoded object inferred from the named slots in a mask tuple.
845
- * @remarks
846
- * ## Why
847
- * Slot names and codecs become a precise form-field value type.
848
- * ## Ownership and lifetime
849
- * Type-only and resource-free.
850
- * @since 1.0.0
851
- * @category type-level
852
805
  */
853
806
  export type MaskValue<Parts extends ReadonlyArray<MaskPart>> = {
854
807
  readonly [Part in Parts[number] as Part extends MaskSlot<infer Name> ? Name : never]: Part extends MaskSlot<string, infer Value> ? Value : never;
@@ -856,9 +809,7 @@ export type MaskValue<Parts extends ReadonlyArray<MaskPart>> = {
856
809
  /**
857
810
  * Creates a named, Schema-decoded mask slot.
858
811
  * @remarks
859
- * ## Why
860
812
  * Length and character constraints are expressed beside the codec that owns conversion.
861
- * ## Ownership and lifetime
862
813
  * Pure constructor; the returned descriptor retains the codec but acquires no Scope.
863
814
  * @example
864
815
  * ```ts
@@ -868,17 +819,17 @@ export type MaskValue<Parts extends ReadonlyArray<MaskPart>> = {
868
819
  * const areaCode = slot("area", Schema.String, { length: 3, charset: /[0-9]/ })
869
820
  * ```
870
821
  * @since 1.0.0
871
- * @category constructors
822
+ * @category Input codecs
872
823
  */
873
824
  export declare function slot<Name extends string, Value>(name: Name, codec: Schema.Codec<Value, string>, options?: Omit<MaskSlot<Name, Value>, "_tag" | "name" | "codec">): MaskSlot<Name, Value>;
874
825
  /**
875
826
  * Builds a bidirectional Schema codec from literal text and named slots.
876
827
  * @remarks
877
- * ## Why
878
- * Display formatting and decoding share one ordered specification and produce
879
- * ordinary Schema issues on invalid length, characters, literals, or slot values.
880
- * ## Ownership and lifetime
881
- * Pure codec construction. Decode/encode Effects are lazy and Scope-free.
828
+ * Strict encoding and decoding share the same parts and reject invalid length,
829
+ * characters, literals, or slot values. MaskedInput also uses these parts to
830
+ * retain drafts and format fixed-width slots with explicit charsets. Literal
831
+ * characters must be distinguishable from editable characters for auto-formatting;
832
+ * ambiguous or variable-width masks retain ordinary strict text entry.
882
833
  * @example
883
834
  * ```ts
884
835
  * import { mask, slot } from "@typed/ui/Form"
@@ -888,50 +839,53 @@ export declare function slot<Name extends string, Value>(name: Name, codec: Sche
888
839
  * slot("number", Schema.String, { length: 7 }))
889
840
  * ```
890
841
  * @since 1.0.0
891
- * @category schemas
842
+ * @category Input codecs
892
843
  */
893
844
  export declare function mask<const Parts extends ReadonlyArray<MaskPart>>(...parts: Parts): Schema.Codec<MaskValue<Parts>, string>;
894
845
  /**
895
846
  * Options for an input decoded through a structured mask codec.
896
847
  * @remarks
897
- * ## Why
898
848
  * A normal text input can expose a structured typed value without hiding native events or props.
899
- * ## Ownership and lifetime
900
849
  * The control Scope owns DOM work; form state and the mask codec remain independently owned.
901
850
  * @since 1.0.0
902
- * @category component-options
851
+ * @category Input codecs
903
852
  */
904
853
  export interface MaskedInputOptions<Values extends object, Parts extends ReadonlyArray<MaskPart>> extends InputOptions<Values, MaskValue<Parts>> {
905
- /** Bidirectional mask codec used for display and input decoding. */
854
+ /**
855
+ * Bidirectional mask codec used for display and input decoding.
856
+ */
906
857
  readonly mask: Schema.Codec<MaskValue<Parts>, string>;
907
858
  }
908
859
  /**
909
860
  * Binds a native text input to a structured mask value.
910
861
  * @remarks
911
- * ## Why
912
- * The supplied Schema codec controls both display encoding and input decoding;
913
- * failed edits update field errors rather than corrupting decoded state.
914
- * ## Ownership and lifetime
915
- * DOM listeners and reactive value binding live in the control Scope. The
916
- * supplied state can be tested and retained without mounting this control.
862
+ * A codec created by mask supplies the editable format. Fixed-width slots with
863
+ * explicit charsets receive literal insertion and caret-aware deletion; other
864
+ * codecs retain strict text entry. Incomplete drafts remain visible while decoded
865
+ * state keeps its previous value. Native custom validity and field error text
866
+ * prevent native submission of an incomplete mask. Composition is committed only
867
+ * after compositionend. New edits and resets supersede pending slot decoders.
868
+ * Each mounted input owns its draft observer and reset registration in Scope.
917
869
  * @since 1.0.0
918
- * @category components
870
+ * @category Input codecs
919
871
  */
920
872
  export declare function MaskedInput<const Values extends object, const Parts extends ReadonlyArray<MaskPart>, const Options extends MaskedInputOptions<Values, Parts>, const Host extends HostResult = never>(options: Options & Pick<MaskedInputOptions<Values, Parts>, "state" | "name" | "mask">, host?: Dom.HostOverride<Dom.RenderHostProps<Omit<Options, "mask">, InputProps<Values, MaskValue<Parts>>>, "", Host>): Fx<RenderEvent, Schema.SchemaError | Renderable.Error<RenderableComponentOptions<Omit<Options, "mask">> | Host>, Renderable.Services<RenderableComponentOptions<Omit<Options, "mask">> | Host> | Scope.Scope | RenderTemplate>;
921
873
  /**
922
874
  * Options for a state-explicit native checkbox.
923
875
  * @remarks
924
- * ## Why
925
876
  * Boolean field inference and live `checked` binding preserve native checkbox behavior.
926
- * ## Ownership and lifetime
927
877
  * The control Scope owns the listener/binding; form state may outlive the element.
928
878
  * @since 1.0.0
929
- * @category component-options
879
+ * @category Component options
930
880
  */
931
881
  export interface CheckboxOptions<Values extends object> extends Dom.HostOptions<HTMLInputElement> {
932
- /** Renderer-independent state read and updated by the checkbox. */
882
+ /**
883
+ * Renderer-independent state read and updated by the checkbox.
884
+ */
933
885
  readonly state: FormState<Values>;
934
- /** Boolean field controlled by the checkbox. */
886
+ /**
887
+ * Boolean field controlled by the checkbox.
888
+ */
935
889
  readonly name: BooleanFieldName<Values>;
936
890
  }
937
891
  declare function checkboxProps<Values extends object>(options: CheckboxOptions<Values>): () => {
@@ -947,32 +901,34 @@ type CheckboxProps<Values extends object> = ReturnType<ReturnType<typeof checkbo
947
901
  /**
948
902
  * Binds a native checkbox to a boolean form field.
949
903
  * @remarks
950
- * ## Why
951
904
  * Both the checked attribute and live property follow state, while the browser's
952
905
  * real change event is decoded through the field codec.
953
- * ## Ownership and lifetime
954
906
  * The rendered Scope owns the input, listener, and subscriptions. A custom host
955
907
  * must apply merged name, ARIA, checked, and change props.
956
908
  * @since 1.0.0
957
- * @category components
909
+ * @category Native controls
958
910
  */
959
911
  export declare function Checkbox<const Values extends object, const Options extends CheckboxOptions<Values>, const Host extends HostResult = never>(options: Options & Pick<CheckboxOptions<Values>, "state" | "name">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, CheckboxProps<Values>>, "", Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
960
912
  /**
961
913
  * Options for a state-explicit native select.
962
914
  * @remarks
963
- * ## Why
964
915
  * Callers author ordinary option markup while the selected value binds to typed state.
965
- * ## Ownership and lifetime
966
916
  * The control Scope owns content, listener, and binding; form state may outlive it.
967
917
  * @since 1.0.0
968
- * @category component-options
918
+ * @category Component options
969
919
  */
970
920
  export interface SelectOptions<Values extends object> extends Dom.HostOptions<HTMLSelectElement> {
971
- /** Renderer-independent state read and updated by the select. */
921
+ /**
922
+ * Renderer-independent state read and updated by the select.
923
+ */
972
924
  readonly state: FormState<Values>;
973
- /** String field controlled by the select. */
925
+ /**
926
+ * String field controlled by the select.
927
+ */
974
928
  readonly name: FieldNameFor<Values, string>;
975
- /** Native option/optgroup renderable content. */
929
+ /**
930
+ * Native option/optgroup renderable content.
931
+ */
976
932
  readonly content: Renderable.Any;
977
933
  }
978
934
  declare function selectProps<Values extends object>(options: SelectOptions<Values>): () => {
@@ -986,29 +942,29 @@ type SelectProps<Values extends object> = ReturnType<ReturnType<typeof selectPro
986
942
  /**
987
943
  * Binds a native select element to a string form field.
988
944
  * @remarks
989
- * ## Why
990
945
  * Native keyboard, accessibility, option, and form semantics remain browser-owned.
991
- * ## Ownership and lifetime
992
946
  * The rendered Scope owns the select/content subscriptions. A custom host must
993
947
  * preserve supplied name, ARIA, value, and change props.
994
948
  * @since 1.0.0
995
- * @category components
949
+ * @category Native controls
996
950
  */
997
951
  export declare function Select<const Values extends object, const Options extends SelectOptions<Values>, const Host extends HostResult = never>(options: Options & Pick<SelectOptions<Values>, "state" | "name" | "content">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, SelectProps<Values>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
998
952
  /**
999
953
  * Options for a native form label.
1000
954
  * @remarks
1001
- * ## Why
1002
955
  * Explicit `for` linkage keeps accessible naming in browser-standard markup.
1003
- * ## Ownership and lifetime
1004
956
  * The label Scope owns rendered content only; it does not own the referenced control.
1005
957
  * @since 1.0.0
1006
- * @category component-options
958
+ * @category Field relationships
1007
959
  */
1008
960
  export interface LabelOptions extends Dom.HostOptions<HTMLLabelElement> {
1009
- /** ID of the native control labeled by this element. */
961
+ /**
962
+ * ID of the native control labeled by this element.
963
+ */
1010
964
  readonly for: string;
1011
- /** Human-readable label content. */
965
+ /**
966
+ * Human-readable label content.
967
+ */
1012
968
  readonly content: Renderable.Any;
1013
969
  }
1014
970
  declare function labelProps<const Options extends LabelOptions>(options: Options): () => {
@@ -1018,55 +974,54 @@ type LabelProps<Options extends LabelOptions> = ReturnType<ReturnType<typeof lab
1018
974
  /**
1019
975
  * Renders a native label with an explicit control relationship.
1020
976
  * @remarks
1021
- * ## Why
1022
977
  * The browser supplies click-to-focus and accessible-name behavior with no synthetic layer.
1023
- * ## Ownership and lifetime
1024
978
  * The Scope owns label output/content; the referenced element remains separately owned.
1025
979
  * @since 1.0.0
1026
- * @category components
980
+ * @category Field relationships
1027
981
  */
1028
982
  export declare function Label<const Options extends LabelOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, LabelProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
1029
983
  /**
1030
984
  * Options for descriptive form content.
1031
985
  * @remarks
1032
- * ## Why
1033
986
  * Provides a host-overrideable descriptive region without inventing text semantics.
1034
- * ## Ownership and lifetime
1035
987
  * The host Scope owns the rendered content.
1036
988
  * @since 1.0.0
1037
- * @category component-options
989
+ * @category Field relationships
1038
990
  */
1039
991
  export interface DescriptionOptions extends Dom.HostOptions<HTMLDivElement> {
1040
- /** Descriptive renderable content. */
992
+ /**
993
+ * Descriptive renderable content.
994
+ */
1041
995
  readonly content: Renderable.Any;
1042
996
  }
1043
997
  declare function descriptionProps(): () => {};
1044
998
  type DescriptionProps = ReturnType<ReturnType<typeof descriptionProps>>;
1045
999
  /**
1046
- * Renders form description content in a neutral native div by default.
1000
+ * Renders visible explanatory content in a neutral div.
1001
+ *
1047
1002
  * @remarks
1048
- * ## Why
1049
- * Consumers can connect the resulting element with ordinary ARIA props where needed.
1050
- * ## Ownership and lifetime
1051
- * The Scope owns the description host/content and no external control.
1003
+ * No control relationship is created automatically. The current input binding owns its generated
1004
+ * error aria-describedby; do not assume consumer description IDs are merged into it.
1052
1005
  * @since 1.0.0
1053
- * @category components
1006
+ * @category Field relationships
1054
1007
  */
1055
1008
  export declare function Description<const Options extends DescriptionOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, DescriptionProps>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1056
1009
  /**
1057
1010
  * Options for a field validation alert.
1058
1011
  * @remarks
1059
- * ## Why
1060
1012
  * Error identity derives from form and field IDs so controls can reference it reliably.
1061
- * ## Ownership and lifetime
1062
1013
  * The error host subscribes within its Scope; form state remains independently owned.
1063
1014
  * @since 1.0.0
1064
- * @category component-options
1015
+ * @category Field relationships
1065
1016
  */
1066
1017
  export interface ErrorOptions<Values extends object> extends Dom.HostOptions<HTMLDivElement> {
1067
- /** Renderer-independent state supplying validation errors. */
1018
+ /**
1019
+ * Renderer-independent state supplying validation errors.
1020
+ */
1068
1021
  readonly state: FormState<Values>;
1069
- /** Field whose current message is rendered. */
1022
+ /**
1023
+ * Field whose current message is rendered.
1024
+ */
1070
1025
  readonly name: keyof Values & string;
1071
1026
  }
1072
1027
  declare function errorProps<Values extends object>(options: ErrorOptions<Values>): () => {
@@ -1075,29 +1030,28 @@ declare function errorProps<Values extends object>(options: ErrorOptions<Values>
1075
1030
  };
1076
1031
  type ErrorProps<Values extends object> = ReturnType<ReturnType<typeof errorProps<Values>>>;
1077
1032
  /**
1078
- * Renders the current field error as a native ARIA alert region.
1033
+ * Renders the named field message with a generated ID and alert role.
1034
+ *
1079
1035
  * @remarks
1080
- * ## Why
1081
- * The same derived ID is placed on the error and in the control's
1082
- * `aria-describedby`, keeping validation messaging coherent.
1083
- * ## Ownership and lifetime
1084
- * The Scope owns the alert and state subscription; removing it does not remove form state.
1036
+ * Bound inputs refer to this ID through aria-describedby and expose aria-invalid when an error
1037
+ * exists. Keep the form ID stable and render one matching error host per field. Alert timing
1038
+ * still depends on the browser and assistive technology; this is not an announcement queue.
1085
1039
  * @since 1.0.0
1086
- * @category components
1040
+ * @category Field relationships
1087
1041
  */
1088
1042
  export declare function Error<const Values extends object, const Options extends ErrorOptions<Values>, const Host extends HostResult = never>(options: Options & Pick<ErrorOptions<Values>, "state" | "name">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ErrorProps<Values>>, Renderable.Any, Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1089
1043
  /**
1090
1044
  * Options for a native submit button.
1091
1045
  * @remarks
1092
- * ## Why
1093
1046
  * Uses ordinary form submission semantics while exposing all button props/events.
1094
- * ## Ownership and lifetime
1095
1047
  * The button Scope owns rendered content and listeners.
1096
1048
  * @since 1.0.0
1097
- * @category component-options
1049
+ * @category Component options
1098
1050
  */
1099
1051
  export interface SubmitOptions extends Dom.HostOptions<HTMLButtonElement> {
1100
- /** Submit button label/content. */
1052
+ /**
1053
+ * Submit button label/content.
1054
+ */
1101
1055
  readonly content: Renderable.Any;
1102
1056
  }
1103
1057
  declare function submitProps(): () => {
@@ -1107,28 +1061,28 @@ type SubmitProps = ReturnType<ReturnType<typeof submitProps>>;
1107
1061
  /**
1108
1062
  * Renders a native `type=submit` button.
1109
1063
  * @remarks
1110
- * ## Why
1111
1064
  * Keyboard activation, form association, and accessibility stay browser-standard.
1112
- * ## Ownership and lifetime
1113
1065
  * The Scope owns the button/content; the surrounding Form owns submission sequencing.
1114
1066
  * @since 1.0.0
1115
- * @category components
1067
+ * @category Form actions
1116
1068
  */
1117
1069
  export declare function Submit<const Options extends SubmitOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, SubmitProps>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1118
1070
  /**
1119
1071
  * Options for a state-explicit reset button.
1120
1072
  * @remarks
1121
- * ## Why
1122
1073
  * Native reset activation can restore renderer-independent Typed state deterministically.
1123
- * ## Ownership and lifetime
1124
1074
  * The click Effect runs in the button Scope; state may outlive the button.
1125
1075
  * @since 1.0.0
1126
- * @category component-options
1076
+ * @category Component options
1127
1077
  */
1128
1078
  export interface ResetOptions<Values extends object> extends Dom.HostOptions<HTMLButtonElement> {
1129
- /** Renderer-independent state restored on activation. */
1079
+ /**
1080
+ * Renderer-independent state restored on activation.
1081
+ */
1130
1082
  readonly state: FormState<Values>;
1131
- /** Reset button label/content. */
1083
+ /**
1084
+ * Reset button label/content.
1085
+ */
1132
1086
  readonly content: Renderable.Any;
1133
1087
  }
1134
1088
  declare function resetProps<Values extends object>(options: ResetOptions<Values>): () => {
@@ -1139,29 +1093,29 @@ type ResetProps<Values extends object> = ReturnType<ReturnType<typeof resetProps
1139
1093
  /**
1140
1094
  * Renders a native reset button that restores Typed form defaults.
1141
1095
  * @remarks
1142
- * ## Why
1143
1096
  * It prevents the browser's independent control mutation and resets the single
1144
1097
  * RefSubject source of truth, clearing errors, metadata, and submitting state.
1145
- * ## Ownership and lifetime
1146
1098
  * The Scope owns the click handler/content. The supplied form state remains independently owned.
1147
1099
  * @since 1.0.0
1148
- * @category components
1100
+ * @category Form actions
1149
1101
  */
1150
1102
  export declare function Reset<const Values extends object, const Options extends ResetOptions<Values>, const Host extends HostResult = never>(options: Options & Pick<ResetOptions<Values>, "state" | "content">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ResetProps<Values>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1151
1103
  /**
1152
1104
  * Options for an accessible group of form controls.
1153
1105
  * @remarks
1154
- * ## Why
1155
1106
  * Provides a native host with `role=group` and optional accessible label.
1156
- * ## Ownership and lifetime
1157
1107
  * The group Scope owns child renderables but not their independent form state.
1158
1108
  * @since 1.0.0
1159
- * @category component-options
1109
+ * @category Field relationships
1160
1110
  */
1161
1111
  export interface GroupOptions extends Dom.HostOptions<HTMLDivElement> {
1162
- /** Controls or other renderable members of the group. */
1112
+ /**
1113
+ * Controls or other renderable members of the group.
1114
+ */
1163
1115
  readonly content: Renderable.Any;
1164
- /** Optional accessible name applied through `aria-label`. */
1116
+ /**
1117
+ * Optional accessible name applied through `aria-label`.
1118
+ */
1165
1119
  readonly label?: string;
1166
1120
  }
1167
1121
  declare function groupProps<const Options extends GroupOptions>(options: Options): () => {
@@ -1172,32 +1126,36 @@ type GroupProps<Options extends GroupOptions> = ReturnType<ReturnType<typeof gro
1172
1126
  /**
1173
1127
  * Renders an ARIA group with an optional accessible name.
1174
1128
  * @remarks
1175
- * ## Why
1176
1129
  * Related controls can expose their relationship without a framework-specific wrapper.
1177
- * ## Ownership and lifetime
1178
1130
  * The Scope owns host/content; child controls retain their own DOM/state contracts.
1179
1131
  * @since 1.0.0
1180
- * @category components
1132
+ * @category Field relationships
1181
1133
  */
1182
1134
  export declare function Group<const Options extends GroupOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, GroupProps<Options>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1183
1135
  /**
1184
1136
  * Options for an array-field append button.
1185
1137
  * @remarks
1186
- * ## Why
1187
1138
  * The field name and appended item are derived from the form value type.
1188
- * ## Ownership and lifetime
1189
1139
  * The click Effect runs in the button Scope; form state remains independently owned.
1190
1140
  * @since 1.0.0
1191
- * @category component-options
1141
+ * @category Component options
1192
1142
  */
1193
1143
  export interface PushOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
1194
- /** Renderer-independent state updated on activation. */
1144
+ /**
1145
+ * Renderer-independent state updated on activation.
1146
+ */
1195
1147
  readonly state: FormState<Values>;
1196
- /** Array-valued field to append to. */
1148
+ /**
1149
+ * Array-valued field to append to.
1150
+ */
1197
1151
  readonly name: Name;
1198
- /** Type-compatible item appended to the field. */
1152
+ /**
1153
+ * Type-compatible item appended to the field.
1154
+ */
1199
1155
  readonly value: ArrayFieldValue<Values, Name>;
1200
- /** Button label/content. */
1156
+ /**
1157
+ * Button label/content.
1158
+ */
1201
1159
  readonly content: Renderable.Any;
1202
1160
  }
1203
1161
  declare function pushProps<Values extends object, Name extends ArrayFieldName<Values>>(options: PushOptions<Values, Name>): () => {
@@ -1208,32 +1166,36 @@ type PushProps<Values extends object, Name extends ArrayFieldName<Values>> = Ret
1208
1166
  /**
1209
1167
  * Renders a button that appends one item to an array field.
1210
1168
  * @remarks
1211
- * ## Why
1212
1169
  * Array mutation is immutable, typed, and marks the field dirty/touched.
1213
- * ## Ownership and lifetime
1214
1170
  * The Scope owns the button handler/content; state may outlive the button.
1215
1171
  * @since 1.0.0
1216
- * @category components
1172
+ * @category Form actions
1217
1173
  */
1218
1174
  export declare function Push<const Values extends object, const Name extends ArrayFieldName<Values>, const Options extends PushOptions<Values, Name>, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, PushProps<Values, Name>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1219
1175
  /**
1220
1176
  * Options for an array-field removal button.
1221
1177
  * @remarks
1222
- * ## Why
1223
1178
  * The array field is type-checked and the local index is explicit.
1224
- * ## Ownership and lifetime
1225
1179
  * The click Effect runs in the button Scope; form state remains independently owned.
1226
1180
  * @since 1.0.0
1227
- * @category component-options
1181
+ * @category Component options
1228
1182
  */
1229
1183
  export interface RemoveOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
1230
- /** Renderer-independent state updated on activation. */
1184
+ /**
1185
+ * Renderer-independent state updated on activation.
1186
+ */
1231
1187
  readonly state: FormState<Values>;
1232
- /** Array-valued field to remove from. */
1188
+ /**
1189
+ * Array-valued field to remove from.
1190
+ */
1233
1191
  readonly name: Name;
1234
- /** Zero-based item index removed from the field. */
1192
+ /**
1193
+ * Zero-based item index removed from the field.
1194
+ */
1235
1195
  readonly index: number;
1236
- /** Button label/content. */
1196
+ /**
1197
+ * Button label/content.
1198
+ */
1237
1199
  readonly content: Renderable.Any;
1238
1200
  }
1239
1201
  declare function removeProps<Values extends object, Name extends ArrayFieldName<Values>>(options: RemoveOptions<Values, Name>): () => {
@@ -1244,123 +1206,93 @@ type RemoveProps<Values extends object, Name extends ArrayFieldName<Values>> = R
1244
1206
  /**
1245
1207
  * Renders a button that removes one array item by index.
1246
1208
  * @remarks
1247
- * ## Why
1248
1209
  * Array mutation is immutable, typed, and marks the field dirty/touched.
1249
- * ## Ownership and lifetime
1250
1210
  * The Scope owns the button handler/content; state may outlive the button.
1251
1211
  * @since 1.0.0
1252
- * @category components
1212
+ * @category Form actions
1253
1213
  */
1254
1214
  export declare function Remove<const Values extends object, const Name extends ArrayFieldName<Values>, const Options extends RemoveOptions<Values, Name>, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, RemoveProps<Values, Name>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
1255
1215
  /**
1256
- * Sets one decoded field value and updates dirty/touched metadata.
1216
+ * Assigns one decoded field value and updates dirty/touched metadata.
1217
+ *
1257
1218
  * @remarks
1258
- * ## Why
1259
- * Programmatic updates use the same renderer-independent state transition as controls.
1260
- * ## Ownership and lifetime
1261
- * The returned Effect mutates only the supplied RefSubject when run.
1219
+ * The helper does not decode or validate the supplied value and does not clear an existing field
1220
+ * error. Use validate for an explicit whole-form check. Dirty tracking compares against the
1221
+ * default field with !==; updates replace the top-level values record.
1262
1222
  * @since 1.0.0
1263
- * @category state
1223
+ * @category State transitions
1264
1224
  */
1265
1225
  export declare function setValue<Values extends object, Key extends keyof Values & string, E, R>(state: RefSubject.RefSubject<State<Values>, E, R>, key: Key, value: Values[Key]): Effect.Effect<State<Values>, E, R>;
1266
1226
  /**
1267
- * Restores default values and clears errors, interaction metadata, and submission state.
1227
+ * Restores default values and clears errors, metadata, and submitting.
1228
+ *
1268
1229
  * @remarks
1269
- * ## Why
1270
- * Resetting the RefSubject, rather than only DOM controls, keeps every renderer
1271
- * and test observer consistent with the source of truth.
1272
- * ## Ownership and lifetime
1273
- * The returned Effect performs one update when run and requires the same services as `state`.
1230
+ * The defaultValues object is reused rather than deep-cloned. This state operation does not
1231
+ * cancel a running submission Effect or reset independently owned result state.
1274
1232
  * @since 1.0.0
1275
- * @category state
1233
+ * @category State transitions
1276
1234
  */
1277
1235
  export declare function reset<Values extends object, E, R>(state: RefSubject.RefSubject<State<Values>, E, R>): Effect.Effect<State<Values>, E, R>;
1278
1236
  /**
1279
- * Names of boolean-valued fields.
1280
- * @remarks
1281
- * ## Why
1282
- * Constrains checkbox bindings to values the control can represent exactly.
1283
- * ## Ownership and lifetime
1284
- * Type-only and resource-free.
1285
- * @since 1.0.0
1286
- * @category type-level
1287
1237
  */
1288
1238
  export type BooleanFieldName<Values extends object> = FieldNameFor<Values, boolean>;
1289
1239
  /**
1290
- * Names of readonly-array-valued fields.
1291
- * @remarks
1292
- * ## Why
1293
- * Constrains append/removal helpers to collection fields.
1294
- * ## Ownership and lifetime
1295
- * Type-only and resource-free.
1296
- * @since 1.0.0
1297
- * @category type-level
1298
1240
  */
1299
1241
  export type ArrayFieldName<Values extends object> = {
1300
1242
  [Key in keyof Values & string]: Values[Key] extends ReadonlyArray<unknown> ? Key : never;
1301
1243
  }[keyof Values & string];
1302
1244
  /**
1303
- * Element type of a selected array field.
1304
- * @remarks
1305
- * ## Why
1306
- * Append values are checked against the exact chosen field.
1307
- * ## Ownership and lifetime
1308
- * Type-only and resource-free.
1309
- * @since 1.0.0
1310
- * @category type-level
1311
1245
  */
1312
1246
  export type ArrayFieldValue<Values extends object, Name extends ArrayFieldName<Values>> = Values[Name] extends ReadonlyArray<infer Value> ? Value : never;
1313
1247
  /**
1314
1248
  * Appends one item to an array field and marks it dirty and touched.
1315
1249
  * @remarks
1316
- * ## Why
1317
1250
  * The immutable state transition is usable in tests, commands, or any renderer.
1318
- * ## Ownership and lifetime
1319
1251
  * The returned Effect performs one RefSubject update when run.
1320
1252
  * @since 1.0.0
1321
- * @category state
1253
+ * @category State transitions
1322
1254
  */
1323
1255
  export declare function pushValue<Values extends object, Name extends ArrayFieldName<Values>, E, R>(state: RefSubject.RefSubject<State<Values>, E, R>, name: Name, value: ArrayFieldValue<Values, Name>): Effect.Effect<State<Values>, E, R>;
1324
1256
  /**
1325
1257
  * Removes one item by index from an array field and marks it dirty and touched.
1326
1258
  * @remarks
1327
- * ## Why
1328
1259
  * The transition is explicit and renderer-independent; an out-of-range index leaves values unchanged.
1329
- * ## Ownership and lifetime
1330
1260
  * The returned Effect performs one RefSubject update when run.
1331
1261
  * @since 1.0.0
1332
- * @category state
1262
+ * @category State transitions
1333
1263
  */
1334
1264
  export declare function removeValue<Values extends object, Name extends ArrayFieldName<Values>, E, R>(state: RefSubject.RefSubject<State<Values>, E, R>, name: Name, index: number): Effect.Effect<State<Values>, E, R>;
1335
1265
  /**
1336
1266
  * Handler invoked only after whole-form Schema validation succeeds.
1337
1267
  * @remarks
1338
- * ## Why
1339
1268
  * Callers receive decoded values and the real native SubmitEvent, and may return an Effect.
1340
- * ## Ownership and lifetime
1341
1269
  * A returned Effect runs inside the form submit handler and completes before `submitting` resets.
1342
1270
  * @since 1.0.0
1343
- * @category events
1271
+ * @category Form roots
1344
1272
  */
1345
1273
  export type ValidSubmitHandler<Values extends object, E = never, R = never> = (values: Values, event: SubmitEvent) => void | Effect.Effect<unknown, E, R>;
1346
1274
  /**
1347
1275
  * Options for the state-explicit form root.
1348
1276
  * @remarks
1349
- * ## Why
1350
1277
  * The form supplies native submit/reset behavior and Effect context while its
1351
1278
  * data remains in a standalone hydrated RefSubject.
1352
- * ## Ownership and lifetime
1353
1279
  * The root Scope owns DOM handlers/content and provides `CurrentForm` to descendants.
1354
1280
  * It borrows `state`; submission Effects are finalized before `submitting` is cleared.
1355
1281
  * @since 1.0.0
1356
- * @category component-options
1282
+ * @category Form roots
1357
1283
  */
1358
1284
  export interface FormOptions<Values extends object, E = never, R = never> extends Dom.HostOptions<HTMLFormElement> {
1359
- /** Hydrated renderer-independent state owned outside the form renderer. */
1285
+ /**
1286
+ * Hydrated renderer-independent state owned outside the form renderer.
1287
+ */
1360
1288
  readonly state: FormState<Values>;
1361
- /** Controls and other renderable form content. */
1289
+ /**
1290
+ * Controls and other renderable form content.
1291
+ */
1362
1292
  readonly content: Renderable.Any;
1363
- /** Callback invoked with decoded values only after successful validation. */
1293
+ /**
1294
+ * Callback invoked with decoded values only after successful validation.
1295
+ */
1364
1296
  readonly onValidSubmit?: ValidSubmitHandler<Values, E, R>;
1365
1297
  }
1366
1298
  declare function formProps<const Values extends object, E, R, const Options extends FormOptions<Values, E, R>>(options: Options): () => {
@@ -1370,16 +1302,14 @@ declare function formProps<const Values extends object, E, R, const Options exte
1370
1302
  };
1371
1303
  type FormProps<Values extends object, E, R, Options extends FormOptions<Values, E, R>> = ReturnType<ReturnType<typeof formProps<Values, E, R, Options>>>;
1372
1304
  /**
1373
- * Renders a native form and provides its state to schema-bound descendants.
1305
+ * Renders a native form and provides its state to bound descendants.
1306
+ *
1374
1307
  * @remarks
1375
- * ## Why
1376
- * Native submission is intercepted once, whole-form Schema validation runs,
1377
- * then `onValidSubmit` receives decoded values. Reset updates the RefSubject so
1378
- * all renderers stay coherent.
1379
- * ## Ownership and lifetime
1380
- * The root Scope owns its listeners/content and `CurrentForm` service. A valid
1381
- * submit Effect runs in that lifetime; `submitting` is cleared in finalization
1382
- * even on failure or interruption. Hydration does not itself attach client UI.
1308
+ * The submit listener synchronously prevents browser navigation, marks submitting, validates
1309
+ * decoded state, and runs onValidSubmit on success. Finalization clears submitting. Native
1310
+ * constraint validation can prevent submit dispatch before this handler runs. The root does not
1311
+ * read FormData, serialize a request, cancel duplicate submissions, or infer server errors.
1312
+ *
1383
1313
  * @example
1384
1314
  * ```ts
1385
1315
  * import { Form, Submit, TextInput, makeState } from "@typed/ui/Form"
@@ -1397,298 +1327,400 @@ type FormProps<Values extends object, E, R, Options extends FormOptions<Values,
1397
1327
  * })
1398
1328
  * ```
1399
1329
  * @since 1.0.0
1400
- * @category components
1330
+ * @category Form roots
1401
1331
  */
1402
1332
  export declare function Form<const Values extends object, E, R, const Options extends FormOptions<Values, E, R>, const Host extends HostResult = never>(options: Options & Pick<FormOptions<Values, E, R>, "state" | "content">, host?: Dom.HostOverride<Dom.RenderHostProps<Options, FormProps<Values, E, R, Options>>, Options["content"], Host>): SchemaBoundRootResult<Options, Host>;
1403
1333
  /**
1404
1334
  * Options accepted by a schema-bound form root.
1405
1335
  * @remarks
1406
- * ## Why
1407
1336
  * The factory names the state `form` and supplies its schema/context automatically.
1408
- * ## Ownership and lifetime
1409
1337
  * The root Scope borrows `form` and owns content, listeners, and submit Effects.
1410
1338
  * @since 1.0.0
1411
- * @category component-options
1339
+ * @category Form roots
1412
1340
  */
1413
1341
  export interface BoundFormOptions<Values extends object, E = never, R = never> extends Dom.HostOptions<HTMLFormElement> {
1414
- /** State previously created by the bound API's `state` constructor. */
1342
+ /**
1343
+ * State previously created by the bound API's `state` constructor.
1344
+ */
1415
1345
  readonly form: FormState<Values>;
1416
- /** Schema-bound controls and other renderable form content. */
1346
+ /**
1347
+ * Schema-bound controls and other renderable form content.
1348
+ */
1417
1349
  readonly content: Renderable.Any;
1418
- /** Callback invoked with decoded values only after successful validation. */
1350
+ /**
1351
+ * Callback invoked with decoded values only after successful validation.
1352
+ */
1419
1353
  readonly onValidSubmit?: ValidSubmitHandler<Values, E, R>;
1420
1354
  }
1421
1355
  type CurrentFormIdentifier = Context.Service.Identifier<typeof CurrentForm>;
1422
1356
  /**
1423
1357
  * Fx result of a schema-bound descendant control.
1424
1358
  * @remarks
1425
- * ## Why
1426
- * Its type makes `CurrentForm`, render services, Schema errors, Scope, and custom-host requirements explicit.
1427
- * ## Ownership and lifetime
1359
+ * Its type makes `CurrentForm`, render services, Schema errors, Scope, and custom-host
1360
+ * requirements explicit.
1428
1361
  * The parent form supplies `CurrentForm`; the running Scope owns DOM work.
1429
1362
  * @since 1.0.0
1430
- * @category models
1363
+ * @category Schema-bound components
1431
1364
  */
1432
1365
  export type SchemaBoundComponentResult<Options, Host> = Fx<RenderEvent, Schema.SchemaError | Renderable.Error<RenderableComponentOptions<Options> | Host>, Renderable.Services<RenderableComponentOptions<Options> | Host> | CurrentFormIdentifier | Scope.Scope | RenderTemplate>;
1433
1366
  /**
1434
1367
  * Fx result of a schema-bound root after it provides `CurrentForm` internally.
1435
1368
  * @remarks
1436
- * ## Why
1437
1369
  * Consumers see only external render/host requirements, not the service supplied by the root itself.
1438
- * ## Ownership and lifetime
1439
1370
  * The running Scope owns the service provision, listeners, and rendered range.
1440
1371
  * @since 1.0.0
1441
- * @category models
1372
+ * @category Schema-bound components
1442
1373
  */
1443
1374
  export type SchemaBoundRootResult<Options, Host> = Fx<RenderEvent, Schema.SchemaError | Renderable.Error<RenderableComponentOptions<Options> | Host>, Exclude<Renderable.Services<RenderableComponentOptions<Options> | Host>, CurrentFormIdentifier> | Scope.Scope | RenderTemplate>;
1444
1375
  /**
1445
1376
  * Callable schema-bound input constructor for fields with one decoded value type.
1446
1377
  * @remarks
1447
- * ## Why
1448
1378
  * Struct field names, errors, and services remain inferred without passing state repeatedly.
1449
- * ## Ownership and lifetime
1450
1379
  * Each call borrows `CurrentForm` and returns Scope-owned render work.
1451
1380
  * @since 1.0.0
1452
- * @category models
1381
+ * @category Schema-bound components
1453
1382
  */
1454
1383
  export interface SchemaBoundInput<Fields extends FormFields, Value> {
1455
- /** Creates a bound native input and optionally delegates its merged props to a custom host. @since 1.0.0 @category constructors */
1384
+ /**
1385
+ * Creates a bound native input and optionally delegates its merged props to a custom host.
1386
+ * @since 1.0.0
1387
+ * @category Schema-bound components
1388
+ */
1456
1389
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundInputOptions<Fields, Value> & Options, host?: Dom.HostOverride<Dom.HostProps<HTMLInputElement>, "", Host>): SchemaBoundComponentResult<Omit<Options, "name">, Host>;
1457
1390
  }
1458
1391
  /**
1459
1392
  * Callable schema-bound input using its selected field's string codec as a mask.
1460
1393
  * @remarks
1461
- * ## Why
1462
1394
  * Structured string encodings stay declared once in the Struct schema.
1463
- * ## Ownership and lifetime
1464
1395
  * Each call borrows `CurrentForm` and returns Scope-owned render work.
1465
1396
  * @since 1.0.0
1466
- * @category models
1397
+ * @category Schema-bound components
1467
1398
  */
1468
1399
  export interface SchemaBoundMaskedInput<Fields extends FormFields> {
1469
- /** Creates a bound text input using the selected field's bidirectional string codec. @since 1.0.0 @category constructors */
1400
+ /**
1401
+ * Creates a bound text input using the selected field's bidirectional string codec.
1402
+ * @since 1.0.0
1403
+ * @category Schema-bound components
1404
+ */
1470
1405
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundMaskedInputOptions<Fields> & Options, host?: Dom.HostOverride<Dom.HostProps<HTMLInputElement>, "", Host>): SchemaBoundComponentResult<Options, Host>;
1471
1406
  }
1472
1407
  /**
1473
1408
  * Callable schema-bound checkbox constructor.
1474
1409
  * @remarks
1475
- * ## Why
1476
1410
  * Only boolean field names are accepted and state comes from `CurrentForm`.
1477
- * ## Ownership and lifetime
1478
1411
  * Each call returns Scope-owned DOM work and borrows the current form state.
1479
1412
  * @since 1.0.0
1480
- * @category models
1413
+ * @category Schema-bound components
1481
1414
  */
1482
1415
  export interface SchemaBoundCheckbox<Values extends object> {
1483
- /** Creates a bound native checkbox for a boolean field. @since 1.0.0 @category constructors */
1416
+ /**
1417
+ * Creates a bound native checkbox for a boolean field.
1418
+ * @since 1.0.0
1419
+ * @category Schema-bound components
1420
+ */
1484
1421
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundCheckboxOptions<Values> & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, CheckboxProps<Values>>, "", Host>): SchemaBoundComponentResult<Options, Host>;
1485
1422
  }
1486
1423
  /**
1487
1424
  * Callable schema-bound native select constructor.
1488
1425
  * @remarks
1489
- * ## Why
1490
1426
  * String field names are inferred while option content remains caller-authored.
1491
- * ## Ownership and lifetime
1492
1427
  * Each call returns Scope-owned DOM/content work and borrows current form state.
1493
1428
  * @since 1.0.0
1494
- * @category models
1429
+ * @category Schema-bound components
1495
1430
  */
1496
1431
  export interface SchemaBoundSelect<Values extends object> {
1497
- /** Creates a bound native select and preserves caller-authored option content. @since 1.0.0 @category constructors */
1432
+ /**
1433
+ * Creates a bound native select and preserves caller-authored option content.
1434
+ * @since 1.0.0
1435
+ * @category Schema-bound components
1436
+ */
1498
1437
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundSelectOptions<Values> & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, SelectProps<Values>>, (SchemaBoundSelectOptions<Values> & Options)["content"], Host>): SchemaBoundComponentResult<Options, Host>;
1499
1438
  }
1500
1439
  /**
1501
1440
  * Callable schema-bound field-error constructor.
1502
1441
  * @remarks
1503
- * ## Why
1504
1442
  * Field error text and relationship IDs derive from the current form automatically.
1505
- * ## Ownership and lifetime
1506
1443
  * Each call returns a Scope-owned subscription and borrows current form state.
1507
1444
  * @since 1.0.0
1508
- * @category models
1445
+ * @category Schema-bound components
1509
1446
  */
1510
1447
  export interface SchemaBoundError<Values extends object> {
1511
- /** Creates a bound alert region for one field's current error. @since 1.0.0 @category constructors */
1448
+ /**
1449
+ * Creates a bound alert region for one field's current error.
1450
+ * @since 1.0.0
1451
+ * @category Schema-bound components
1452
+ */
1512
1453
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundErrorOptions<Values> & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ErrorProps<Values>>, Renderable.Any, Host>): SchemaBoundComponentResult<Options, Host>;
1513
1454
  }
1514
1455
  /**
1515
1456
  * Callable schema-bound reset-button constructor.
1516
1457
  * @remarks
1517
- * ## Why
1518
1458
  * Reset behavior can access the current form without a state argument.
1519
- * ## Ownership and lifetime
1520
1459
  * Each call returns Scope-owned DOM work and borrows current form state.
1521
1460
  * @since 1.0.0
1522
- * @category models
1461
+ * @category Schema-bound components
1523
1462
  */
1524
1463
  export interface SchemaBoundReset {
1525
- /** Creates a reset button targeting the form provided by `CurrentForm`. @since 1.0.0 @category constructors */
1464
+ /**
1465
+ * Creates a reset button targeting the form provided by `CurrentForm`.
1466
+ * @since 1.0.0
1467
+ * @category Schema-bound components
1468
+ */
1526
1469
  <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundResetOptions & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ResetProps<object>>, (SchemaBoundResetOptions & Options)["content"], Host>): SchemaBoundComponentResult<Options, Host>;
1527
1470
  }
1528
1471
  /**
1529
1472
  * Callable schema-bound array append-button constructor.
1530
1473
  * @remarks
1531
- * ## Why
1532
1474
  * Field and item types are derived from the form value.
1533
- * ## Ownership and lifetime
1534
1475
  * Each call returns Scope-owned DOM work and borrows current form state.
1535
1476
  * @since 1.0.0
1536
- * @category models
1477
+ * @category Schema-bound components
1537
1478
  */
1538
1479
  export interface SchemaBoundPush<Values extends object> {
1539
- /** Creates an append button for a type-compatible array field and item. @since 1.0.0 @category constructors */
1480
+ /**
1481
+ * Creates an append button for a type-compatible array field and item.
1482
+ * @since 1.0.0
1483
+ * @category Schema-bound components
1484
+ */
1540
1485
  <const Name extends ArrayFieldName<Values>, const Options extends object, const Host extends HostResult = never>(options: SchemaBoundPushOptions<Values, Name> & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, PushProps<Values, Name>>, (SchemaBoundPushOptions<Values, Name> & Options)["content"], Host>): SchemaBoundComponentResult<Options, Host>;
1541
1486
  }
1542
1487
  /**
1543
1488
  * Callable schema-bound array removal-button constructor.
1544
1489
  * @remarks
1545
- * ## Why
1546
1490
  * Array fields remain type-checked without passing state explicitly.
1547
- * ## Ownership and lifetime
1548
1491
  * Each call returns Scope-owned DOM work and borrows current form state.
1549
1492
  * @since 1.0.0
1550
- * @category models
1493
+ * @category Schema-bound components
1551
1494
  */
1552
1495
  export interface SchemaBoundRemove<Values extends object> {
1553
- /** Creates a remove button for an array field and explicit item index. @since 1.0.0 @category constructors */
1496
+ /**
1497
+ * Creates a remove button for an array field and explicit item index.
1498
+ * @since 1.0.0
1499
+ * @category Schema-bound components
1500
+ */
1554
1501
  <const Name extends ArrayFieldName<Values>, const Options extends object, const Host extends HostResult = never>(options: SchemaBoundRemoveOptions<Values, Name> & Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, RemoveProps<Values, Name>>, (SchemaBoundRemoveOptions<Values, Name> & Options)["content"], Host>): SchemaBoundComponentResult<Options, Host>;
1555
1502
  }
1556
1503
  /**
1557
1504
  * Callable root constructor supplied by a schema-bound form API.
1558
1505
  * @remarks
1559
- * ## Why
1560
1506
  * It connects one factory-created state to native form behavior and descendant context.
1561
- * ## Ownership and lifetime
1562
1507
  * The returned Fx provides `CurrentForm` for its own Scope and borrows the state.
1563
1508
  * @since 1.0.0
1564
- * @category models
1509
+ * @category Schema-bound components
1565
1510
  */
1566
1511
  export interface SchemaBoundRoot<Values extends object> {
1567
- /** Creates the native form root that provides its `form` state to bound descendants. @since 1.0.0 @category constructors */
1512
+ /**
1513
+ * Creates the native form root that provides its `form` state to bound descendants.
1514
+ * @since 1.0.0
1515
+ * @category Schema-bound components
1516
+ */
1568
1517
  <E, R, const Options extends BoundFormOptions<Values, E, R>, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.HostProps<HTMLFormElement>, Options["content"], Host>): SchemaBoundRootResult<Options, Host>;
1569
1518
  }
1570
1519
  /**
1571
1520
  * Optional state metadata for `SchemaBoundForm.state`.
1572
1521
  * @remarks
1573
- * ## Why
1574
1522
  * Callers may seed SSR identity, defaults, errors, and interaction/submission state.
1575
- * ## Ownership and lifetime
1576
1523
  * Values/defaults and nested references are retained exactly; provide `id` for
1577
1524
  * deterministic SSR identity.
1578
1525
  * @since 1.0.0
1579
- * @category models
1526
+ * @category Component options
1580
1527
  */
1581
1528
  export interface SchemaBoundStateOptions<Values extends object> {
1582
- /** Stable hydration and accessibility relationship ID; required for deterministic SSR ordering. */
1529
+ /**
1530
+ * Stable hydration and accessibility relationship ID; required for deterministic SSR ordering.
1531
+ */
1583
1532
  readonly id?: string;
1584
- /** Exact reset-baseline reference, defaulting to the same object passed as initial values. */
1533
+ /**
1534
+ * Exact reset-baseline reference, defaulting to the same object passed as initial values.
1535
+ */
1585
1536
  readonly defaultValues?: Values;
1586
- /** Initial field validation messages. */
1537
+ /**
1538
+ * Initial field validation messages.
1539
+ */
1587
1540
  readonly errors?: Partial<Record<keyof Values & string, string>>;
1588
- /** Initial dirty/touched metadata. */
1541
+ /**
1542
+ * Initial dirty/touched metadata.
1543
+ */
1589
1544
  readonly meta?: Partial<Record<keyof Values & string, FieldMeta>>;
1590
- /** Initial in-flight submission flag. */
1545
+ /**
1546
+ * Whether validation or the returned submit Effect is running.
1547
+ */
1591
1548
  readonly submitting?: boolean;
1592
1549
  }
1593
1550
  /**
1594
1551
  * Schema-specialized form API returned by `make`.
1595
1552
  * @remarks
1596
- * ## Why
1597
1553
  * The Struct codec is declared once, then every state, field name, component,
1598
1554
  * error, and custom-host signature stays aligned with it.
1599
- * ## Ownership and lifetime
1600
1555
  * The API retains the codec but acquires no Scope. Each `state` call creates a
1601
1556
  * Scope-owned hydrated RefSubject; each component call creates lazy Fx output.
1602
1557
  * @since 1.0.0
1603
- * @category models
1558
+ * @category Schema-bound components
1604
1559
  */
1605
1560
  export interface SchemaBoundForm<Fields extends FormFields> {
1606
- /** Struct codec shared by state construction and every bound field. */
1561
+ /**
1562
+ * Struct codec shared by state construction and every bound field.
1563
+ */
1607
1564
  readonly codec: Schema.Struct<Fields>;
1608
- /** Creates a Scope-owned hydrated state from decoded initial values. */
1565
+ /**
1566
+ * Creates a Scope-owned hydrated state from decoded initial values.
1567
+ */
1609
1568
  readonly state: (values: Schema.Struct.Type<Fields>, options?: SchemaBoundStateOptions<Schema.Struct.Type<Fields>>) => Effect.Effect<FormState<Schema.Struct.Type<Fields>>, Schema.SchemaError, Scope.Scope>;
1610
- /** Native form root that provides the current state to bound descendants. */
1569
+ /**
1570
+ * Native form root that provides the current state to bound descendants.
1571
+ */
1611
1572
  readonly Root: SchemaBoundRoot<Schema.Struct.Type<Fields>>;
1612
- /** Bound native text input for string-encoded string fields. */
1573
+ /**
1574
+ * Bound native text input for string-encoded string fields.
1575
+ */
1613
1576
  readonly TextInput: SchemaBoundInput<Fields, string>;
1614
- /** Bound native search input for string-encoded string fields. */
1577
+ /**
1578
+ * Bound native search input for string-encoded string fields.
1579
+ */
1615
1580
  readonly SearchInput: SchemaBoundInput<Fields, string>;
1616
- /** Bound native email input for string-encoded string fields. */
1581
+ /**
1582
+ * Bound native email input for string-encoded string fields.
1583
+ */
1617
1584
  readonly EmailInput: SchemaBoundInput<Fields, string>;
1618
- /** Bound native URL input for string-encoded string fields. */
1585
+ /**
1586
+ * Bound native URL input for string-encoded string fields.
1587
+ */
1619
1588
  readonly UrlInput: SchemaBoundInput<Fields, string>;
1620
- /** Bound native telephone input for string-encoded string fields. */
1589
+ /**
1590
+ * Bound native telephone input for string-encoded string fields.
1591
+ */
1621
1592
  readonly TelInput: SchemaBoundInput<Fields, string>;
1622
- /** Bound native password input for string-encoded string fields. */
1593
+ /**
1594
+ * Bound native password input for string-encoded string fields.
1595
+ */
1623
1596
  readonly PasswordInput: SchemaBoundInput<Fields, string>;
1624
- /** Bound native hidden input for string-encoded string fields. */
1597
+ /**
1598
+ * Bound native hidden input for string-encoded string fields.
1599
+ */
1625
1600
  readonly HiddenInput: SchemaBoundInput<Fields, string>;
1626
- /** Bound native color input for string-encoded string fields. */
1601
+ /**
1602
+ * Bound native color input for string-encoded string fields.
1603
+ */
1627
1604
  readonly ColorInput: SchemaBoundInput<Fields, string>;
1628
- /** Bound native time input for string-encoded string fields. */
1605
+ /**
1606
+ * Bound native time input for string-encoded string fields.
1607
+ */
1629
1608
  readonly TimeInput: SchemaBoundInput<Fields, string>;
1630
- /** Bound native local date-time input for string-encoded string fields. */
1609
+ /**
1610
+ * Bound native local date-time input for string-encoded string fields.
1611
+ */
1631
1612
  readonly DateTimeLocalInput: SchemaBoundInput<Fields, string>;
1632
- /** Bound native month input for string-encoded string fields. */
1613
+ /**
1614
+ * Bound native month input for string-encoded string fields.
1615
+ */
1633
1616
  readonly MonthInput: SchemaBoundInput<Fields, string>;
1634
- /** Bound native week input for string-encoded string fields. */
1617
+ /**
1618
+ * Bound native week input for string-encoded string fields.
1619
+ */
1635
1620
  readonly WeekInput: SchemaBoundInput<Fields, string>;
1636
- /** Bound native number input for finite-number fields encoded as strings. */
1621
+ /**
1622
+ * Bound native number input for finite-number fields encoded as strings.
1623
+ */
1637
1624
  readonly NumberInput: SchemaBoundInput<Fields, number>;
1638
- /** Bound native range input for finite-number fields encoded as strings. */
1625
+ /**
1626
+ * Bound native range input for finite-number fields encoded as strings.
1627
+ */
1639
1628
  readonly RangeInput: SchemaBoundInput<Fields, number>;
1640
- /** Bound native date input for Date fields encoded as strings. */
1629
+ /**
1630
+ * Bound native date input for Date fields encoded as strings.
1631
+ */
1641
1632
  readonly DateInput: SchemaBoundInput<Fields, Date>;
1642
- /** Bound text input using the selected field's own string codec. */
1633
+ /**
1634
+ * Bound text input using the selected field's own string codec.
1635
+ */
1643
1636
  readonly MaskedInput: SchemaBoundMaskedInput<Fields>;
1644
- /** Bound native checkbox limited to boolean fields. */
1637
+ /**
1638
+ * Bound native checkbox limited to boolean fields.
1639
+ */
1645
1640
  readonly Checkbox: SchemaBoundCheckbox<Schema.Struct.Type<Fields>>;
1646
- /** Bound native select limited to string fields. */
1641
+ /**
1642
+ * Bound native select limited to string fields.
1643
+ */
1647
1644
  readonly Select: SchemaBoundSelect<Schema.Struct.Type<Fields>>;
1648
- /** Bound ARIA alert for a field's current validation message. */
1645
+ /**
1646
+ * Bound ARIA alert for a field's current validation message.
1647
+ */
1649
1648
  readonly Error: SchemaBoundError<Schema.Struct.Type<Fields>>;
1650
- /** Bound reset button that restores the current form's defaults. */
1649
+ /**
1650
+ * Bound reset button that restores the current form's defaults.
1651
+ */
1651
1652
  readonly Reset: SchemaBoundReset;
1652
- /** Bound button that appends to an array field. */
1653
+ /**
1654
+ * Bound button that appends to an array field.
1655
+ */
1653
1656
  readonly Push: SchemaBoundPush<Schema.Struct.Type<Fields>>;
1654
- /** Bound button that removes an item from an array field. */
1657
+ /**
1658
+ * Bound button that removes an item from an array field.
1659
+ */
1655
1660
  readonly Remove: SchemaBoundRemove<Schema.Struct.Type<Fields>>;
1656
- /** Native label component; callers provide the target control ID. */
1661
+ /**
1662
+ * Native label component; callers provide the target control ID.
1663
+ */
1657
1664
  readonly Label: typeof Label;
1658
- /** Neutral description host for caller-linked explanatory content. */
1665
+ /**
1666
+ * Neutral description host for caller-linked explanatory content.
1667
+ */
1659
1668
  readonly Description: typeof Description;
1660
- /** Native submit button. */
1669
+ /**
1670
+ * Native submit button.
1671
+ */
1661
1672
  readonly Submit: typeof Submit;
1662
- /** Accessible group host for related controls. */
1673
+ /**
1674
+ * Accessible group host for related controls.
1675
+ */
1663
1676
  readonly Group: typeof Group;
1664
1677
  }
1665
1678
  /**
1666
- * Creates a schema-bound form component family from one Struct codec.
1679
+ * Binds a native form component family to one Struct codec.
1680
+ *
1667
1681
  * @remarks
1668
- * ## Why
1669
- * Defining the schema once removes repeated state/codec arguments and makes
1670
- * incompatible field/component combinations compile-time errors.
1671
- * ## Ownership and lifetime
1672
- * Factory creation is pure and retains the codec. `state` requires Scope and
1673
- * returns a hydrated RefSubject. `Root` provides that state through Effect
1674
- * context only for its render lifetime; controls borrow it.
1682
+ * state accepts decoded defaults and allocates a Scope-owned hydrated subject. Root provides
1683
+ * that form through CurrentForm. Bound controls select compatible field names from both decoded
1684
+ * and encoded schema types; their context requirement remains in the Fx until Root provides it.
1685
+ * Use explicit stable IDs when server rendering and hydrating.
1686
+ *
1675
1687
  * @example
1676
1688
  * ```ts
1677
- * import { make } from "@typed/ui/Form"
1678
- * import { Effect, Schema } from "effect"
1679
- * import { html } from "@typed/template"
1680
- *
1681
- * const Signup = make(Schema.Struct({ email: Schema.String, accepted: Schema.Boolean }))
1682
- * const view = Effect.gen(function* () {
1683
- * const form = yield* Signup.state({ email: "", accepted: false }, { id: "signup" })
1684
- * return Signup.Root({
1689
+ * import { Schema } from "effect";
1690
+ * import { html } from "@typed/template";
1691
+ * import { RefSubject } from "@typed/fx";
1692
+ * import { component } from "@typed/ui/Component";
1693
+ * import * as Form from "@typed/ui/Form";
1694
+ *
1695
+ * const Order = Form.make(Schema.Struct({
1696
+ * copies: Schema.FiniteFromString.pipe(Schema.check(Schema.isGreaterThan(0))),
1697
+ * includeNotes: Schema.Boolean,
1698
+ * }));
1699
+ *
1700
+ * export const PrintOrder = component(function* () {
1701
+ * const form = yield* Order.state({ copies: 1, includeNotes: false }, { id: "print-order" });
1702
+ * const submitting = RefSubject.map(form, (state) => state.submitting);
1703
+ * const preview = yield* RefSubject.make("No print request preview yet.");
1704
+ * return html`<section>${Order.Root({
1685
1705
  * form,
1686
- * content: html`${Signup.EmailInput({ name: "email" })}${Signup.Checkbox({ name: "accepted" })}`
1687
- * })
1688
- * })
1706
+ * content: [
1707
+ * Order.Label({ for: "order-copies", content: "Copies" }),
1708
+ * Order.NumberInput({ name: "copies", props: { id: "order-copies", min: 1, required: true } }),
1709
+ * Order.Error({ name: "copies" }),
1710
+ * Order.Checkbox({ name: "includeNotes", props: { id: "order-notes" } }),
1711
+ * Order.Label({ for: "order-notes", content: "Include speaker notes" }),
1712
+ * Order.Submit({ content: "Preview print request", props: { "?disabled": submitting } }),
1713
+ * Order.Reset({ content: "Restore defaults" }),
1714
+ * ],
1715
+ * onValidSubmit: (values) => RefSubject.set(
1716
+ * preview,
1717
+ * `${values.copies} copies; notes ${values.includeNotes ? "included" : "excluded"}.`,
1718
+ * ),
1719
+ * })}<p role="status">${preview}</p></section>`;
1720
+ * });
1689
1721
  * ```
1690
1722
  * @since 1.0.0
1691
- * @category constructors
1723
+ * @category Schema-bound components
1692
1724
  */
1693
1725
  export declare function make<const Fields extends FormFields>(codec: Schema.Struct<Fields>): SchemaBoundForm<Fields>;
1694
1726
  export {};