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

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 (157) hide show
  1. package/README.md +53 -9
  2. package/dist/Alert.d.ts +78 -0
  3. package/dist/Alert.d.ts.map +1 -0
  4. package/dist/Alert.js +37 -0
  5. package/dist/Button.d.ts +144 -0
  6. package/dist/Button.d.ts.map +1 -0
  7. package/dist/Button.js +38 -0
  8. package/dist/Carousel.d.ts +547 -0
  9. package/dist/Carousel.d.ts.map +1 -0
  10. package/dist/Carousel.js +387 -0
  11. package/dist/Checkbox.d.ts +203 -0
  12. package/dist/Checkbox.d.ts.map +1 -0
  13. package/dist/Checkbox.js +140 -0
  14. package/dist/Collection.d.ts +254 -0
  15. package/dist/Collection.d.ts.map +1 -0
  16. package/dist/Collection.js +218 -0
  17. package/dist/Combobox.d.ts +516 -0
  18. package/dist/Combobox.d.ts.map +1 -0
  19. package/dist/Combobox.js +371 -0
  20. package/dist/Component.d.ts +127 -0
  21. package/dist/Component.d.ts.map +1 -0
  22. package/dist/Component.js +60 -0
  23. package/dist/Composite.d.ts +823 -0
  24. package/dist/Composite.d.ts.map +1 -0
  25. package/dist/Composite.js +615 -0
  26. package/dist/Dialog.d.ts +544 -0
  27. package/dist/Dialog.d.ts.map +1 -0
  28. package/dist/Dialog.js +355 -0
  29. package/dist/Disclosure.d.ts +219 -0
  30. package/dist/Disclosure.d.ts.map +1 -0
  31. package/dist/Disclosure.js +128 -0
  32. package/dist/Dom/Events.d.ts +122 -0
  33. package/dist/Dom/Events.d.ts.map +1 -0
  34. package/dist/Dom/Events.js +192 -0
  35. package/dist/Dom/Props.d.ts +161 -0
  36. package/dist/Dom/Props.d.ts.map +1 -0
  37. package/dist/Dom/Props.js +110 -0
  38. package/dist/Dom/Refs.d.ts +58 -0
  39. package/dist/Dom/Refs.d.ts.map +1 -0
  40. package/dist/Dom/Refs.js +61 -0
  41. package/dist/Dom/Render.d.ts +59 -0
  42. package/dist/Dom/Render.d.ts.map +1 -0
  43. package/dist/Dom/Render.js +71 -0
  44. package/dist/Dom/Types.d.ts +570 -0
  45. package/dist/Dom/Types.d.ts.map +1 -0
  46. package/dist/Dom/Types.js +1 -0
  47. package/dist/Dom/index.d.ts +20 -0
  48. package/dist/Dom/index.d.ts.map +1 -0
  49. package/dist/Dom/index.js +8 -0
  50. package/dist/Dom.d.ts +14 -0
  51. package/dist/Dom.d.ts.map +1 -0
  52. package/dist/Dom.js +13 -0
  53. package/dist/Focusable.d.ts +85 -0
  54. package/dist/Focusable.d.ts.map +1 -0
  55. package/dist/Focusable.js +35 -0
  56. package/dist/Form.d.ts +1695 -0
  57. package/dist/Form.d.ts.map +1 -0
  58. package/dist/Form.js +987 -0
  59. package/dist/Grid.d.ts +569 -0
  60. package/dist/Grid.d.ts.map +1 -0
  61. package/dist/Grid.js +379 -0
  62. package/dist/Group.d.ts +147 -0
  63. package/dist/Group.d.ts.map +1 -0
  64. package/dist/Group.js +63 -0
  65. package/dist/Heading.d.ts +86 -0
  66. package/dist/Heading.d.ts.map +1 -0
  67. package/dist/Heading.js +48 -0
  68. package/dist/Hovercard.d.ts +297 -0
  69. package/dist/Hovercard.d.ts.map +1 -0
  70. package/dist/Hovercard.js +188 -0
  71. package/dist/HttpRouter.d.ts +129 -6
  72. package/dist/HttpRouter.d.ts.map +1 -1
  73. package/dist/HttpRouter.js +196 -53
  74. package/dist/Link.d.ts +67 -28
  75. package/dist/Link.d.ts.map +1 -1
  76. package/dist/Link.js +91 -37
  77. package/dist/Listbox.d.ts +437 -0
  78. package/dist/Listbox.d.ts.map +1 -0
  79. package/dist/Listbox.js +316 -0
  80. package/dist/Menu.d.ts +972 -0
  81. package/dist/Menu.d.ts.map +1 -0
  82. package/dist/Menu.js +731 -0
  83. package/dist/Menubar.d.ts +367 -0
  84. package/dist/Menubar.d.ts.map +1 -0
  85. package/dist/Menubar.js +265 -0
  86. package/dist/Meter.d.ts +217 -0
  87. package/dist/Meter.d.ts.map +1 -0
  88. package/dist/Meter.js +94 -0
  89. package/dist/NativeDetails.d.ts +41 -0
  90. package/dist/NativeDetails.d.ts.map +1 -0
  91. package/dist/NativeDetails.js +40 -0
  92. package/dist/NativeDialog.d.ts +64 -0
  93. package/dist/NativeDialog.d.ts.map +1 -0
  94. package/dist/NativeDialog.js +50 -0
  95. package/dist/NativePopover.d.ts +41 -0
  96. package/dist/NativePopover.d.ts.map +1 -0
  97. package/dist/NativePopover.js +46 -0
  98. package/dist/Popover.d.ts +241 -0
  99. package/dist/Popover.d.ts.map +1 -0
  100. package/dist/Popover.js +141 -0
  101. package/dist/RadioGroup.d.ts +432 -0
  102. package/dist/RadioGroup.d.ts.map +1 -0
  103. package/dist/RadioGroup.js +291 -0
  104. package/dist/Role.d.ts +64 -0
  105. package/dist/Role.d.ts.map +1 -0
  106. package/dist/Role.js +27 -0
  107. package/dist/Select.d.ts +529 -0
  108. package/dist/Select.d.ts.map +1 -0
  109. package/dist/Select.js +407 -0
  110. package/dist/Separator.d.ts +54 -0
  111. package/dist/Separator.d.ts.map +1 -0
  112. package/dist/Separator.js +26 -0
  113. package/dist/Slider.d.ts +188 -0
  114. package/dist/Slider.d.ts.map +1 -0
  115. package/dist/Slider.js +96 -0
  116. package/dist/SpinButton.d.ts +188 -0
  117. package/dist/SpinButton.d.ts.map +1 -0
  118. package/dist/SpinButton.js +96 -0
  119. package/dist/Storybook.d.ts +76 -0
  120. package/dist/Storybook.d.ts.map +1 -0
  121. package/dist/Storybook.js +102 -0
  122. package/dist/Switch.d.ts +187 -0
  123. package/dist/Switch.d.ts.map +1 -0
  124. package/dist/Switch.js +116 -0
  125. package/dist/Tab.d.ts +26 -0
  126. package/dist/Tab.d.ts.map +1 -0
  127. package/dist/Tab.js +25 -0
  128. package/dist/Tabs.d.ts +591 -0
  129. package/dist/Tabs.d.ts.map +1 -0
  130. package/dist/Tabs.js +346 -0
  131. package/dist/Toolbar.d.ts +366 -0
  132. package/dist/Toolbar.d.ts.map +1 -0
  133. package/dist/Toolbar.js +245 -0
  134. package/dist/Tooltip.d.ts +296 -0
  135. package/dist/Tooltip.d.ts.map +1 -0
  136. package/dist/Tooltip.js +172 -0
  137. package/dist/Tree.d.ts +591 -0
  138. package/dist/Tree.d.ts.map +1 -0
  139. package/dist/Tree.js +434 -0
  140. package/dist/TreeGrid.d.ts +645 -0
  141. package/dist/TreeGrid.d.ts.map +1 -0
  142. package/dist/TreeGrid.js +420 -0
  143. package/dist/VisuallyHidden.d.ts +54 -0
  144. package/dist/VisuallyHidden.d.ts.map +1 -0
  145. package/dist/VisuallyHidden.js +27 -0
  146. package/dist/WindowSplitter.d.ts +376 -0
  147. package/dist/WindowSplitter.d.ts.map +1 -0
  148. package/dist/WindowSplitter.js +222 -0
  149. package/dist/index.d.ts +49 -0
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +49 -0
  152. package/package.json +45 -18
  153. package/src/HttpRouter.test.ts +0 -256
  154. package/src/HttpRouter.ts +0 -165
  155. package/src/Link.test.ts +0 -84
  156. package/src/Link.ts +0 -107
  157. package/src/index.ts +0 -2
package/dist/Form.d.ts ADDED
@@ -0,0 +1,1695 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Context from "effect/Context";
3
+ import * as Schema from "effect/Schema";
4
+ import { RefSubject } from "@typed/fx";
5
+ import type * as Scope from "effect/Scope";
6
+ import type { Fx } from "@typed/fx/Fx";
7
+ import { EventHandler, type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
8
+ import * as Dom from "./Dom.js";
9
+ import type { HostResult } from "./Dom/Types.js";
10
+ /**
11
+ * Interaction metadata tracked for one form field.
12
+ *
13
+ * @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
+ *
22
+ * @since 1.0.0
23
+ * @category models
24
+ */
25
+ export interface FieldMeta {
26
+ /** Stored mutation flag for the field; update operations decide when it becomes true. */
27
+ readonly dirty: boolean;
28
+ /** Whether user or programmatic field mutation has occurred. */
29
+ readonly touched: boolean;
30
+ }
31
+ /**
32
+ * Serializable renderer-independent state of a form.
33
+ *
34
+ * @remarks
35
+ * ## Why
36
+ * Values, defaults, validation messages, interaction metadata, and submission
37
+ * state can be inspected and tested without rendering a component.
38
+ *
39
+ * ## Ownership and lifetime
40
+ * A `FormState` RefSubject owns this value. Renderers subscribe to it; they do
41
+ * not contain or become the source of truth.
42
+ *
43
+ * @since 1.0.0
44
+ * @category models
45
+ */
46
+ export interface State<Values extends object = object> {
47
+ /** Current decoded field values. */
48
+ readonly values: Values;
49
+ /** Exact baseline reference used by reset and retained independently from current values. */
50
+ readonly defaultValues: Values;
51
+ /** Current validation messages keyed by field name. */
52
+ readonly errors: Partial<Record<keyof Values & string, string>>;
53
+ /** Dirty/touched metadata keyed by field name. */
54
+ readonly meta: Partial<Record<keyof Values & string, FieldMeta>>;
55
+ /** Whether a valid-submit Effect is currently running. */
56
+ readonly submitting: boolean;
57
+ }
58
+ /**
59
+ * Input used to construct a hydrated form state.
60
+ *
61
+ * @remarks
62
+ * ## Why
63
+ * Defaults make the common case concise while allowing SSR callers to provide
64
+ * deterministic identity and server-known validation state.
65
+ *
66
+ * ## Ownership and lifetime
67
+ * `values` and an explicit `defaultValues` are retained by reference, including
68
+ * their nested objects. When `defaultValues` is omitted, both state fields
69
+ * initially reference the exact `values` object. Subsequent helpers replace the
70
+ * top-level `values` record but do not deep-clone nested values.
71
+ *
72
+ * @since 1.0.0
73
+ * @category models
74
+ */
75
+ export interface InitialState<Values extends object> {
76
+ /** Stable relationship/hydration id; provide it for deterministic SSR. */
77
+ readonly id?: string;
78
+ /** Initial decoded values. */
79
+ readonly values: Values;
80
+ /** Exact reset-baseline reference; defaults to the same object as `values`. */
81
+ readonly defaultValues?: Values;
82
+ /** Optional initial validation messages. */
83
+ readonly errors?: Partial<Record<keyof Values & string, string>>;
84
+ /** Optional initial field metadata. */
85
+ readonly meta?: Partial<Record<keyof Values & string, FieldMeta>>;
86
+ /** Optional initial submission state. */
87
+ readonly submitting?: boolean;
88
+ }
89
+ /**
90
+ * Hydrated RefSubject carrying form state plus runtime schema metadata.
91
+ *
92
+ * @remarks
93
+ * ## Why
94
+ * State is serializable across SSR while codecs and field validators stay as
95
+ * runtime capabilities. This keeps validation type-safe without trying to
96
+ * serialize executable schemas.
97
+ *
98
+ * ## Ownership and lifetime
99
+ * The surrounding Effect Scope owns the hydrated RefSubject and its subscribers.
100
+ * On the server, serializable state is emitted for hydration; on the client it
101
+ * must be restored before mounted controls begin producing updates.
102
+ *
103
+ * @since 1.0.0
104
+ * @category models
105
+ */
106
+ 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. */
108
+ readonly id: string;
109
+ /** Runtime-only validation codec; it is deliberately absent from hydration state. */
110
+ readonly codec: Schema.Codec<Values, unknown>;
111
+ /** Runtime field codecs used for field-level validation. */
112
+ readonly fields: Readonly<Record<keyof Values & string, Schema.Codec<any, any>>>;
113
+ };
114
+ /**
115
+ * Context service exposed to schema-bound descendant controls.
116
+ *
117
+ * @remarks
118
+ * ## Why
119
+ * A bound form can share its state through Effect context without a component tree.
120
+ *
121
+ * ## Ownership and lifetime
122
+ * The root form provides the service only for its rendered Fx lifetime; it does
123
+ * not own the underlying state beyond that state's Scope.
124
+ *
125
+ * @since 1.0.0
126
+ * @category services
127
+ */
128
+ export interface FormService<Values extends object> {
129
+ /** Form state visible to bound descendants. */
130
+ readonly state: FormState<Values>;
131
+ }
132
+ /**
133
+ * Effect context service used by schema-bound form controls.
134
+ *
135
+ * @remarks
136
+ * ## Why
137
+ * Bound controls avoid threading `state` through every call while their
138
+ * service requirement remains visible in the Fx type.
139
+ *
140
+ * ## Ownership and lifetime
141
+ * `Form` provides the service for its child render lifetime; use outside that
142
+ * boundary fails with the ordinary Effect missing-service defect.
143
+ *
144
+ * @since 1.0.0
145
+ * @category services
146
+ */
147
+ export declare const CurrentForm: Context.Service<FormService<any>, FormService<any>>;
148
+ declare const FieldMetaSchema: Schema.Struct<{
149
+ readonly dirty: Schema.Boolean;
150
+ readonly touched: Schema.Boolean;
151
+ }>;
152
+ /**
153
+ * Schema field map accepted by the schema-bound form factory.
154
+ *
155
+ * @remarks
156
+ * ## Why
157
+ * A Struct's individual codecs drive field-name inference and field-level decoding.
158
+ *
159
+ * ## Ownership and lifetime
160
+ * Codecs are runtime values retained by the created form API; they are not hydrated.
161
+ *
162
+ * @since 1.0.0
163
+ * @category models
164
+ */
165
+ export type FormFields = Readonly<Record<string, Schema.Codec<any, any>>>;
166
+ type OptionalFields<Fields extends FormFields, Value extends Schema.Constraint> = {
167
+ readonly [Key in keyof Fields]: Schema.optionalKey<Value>;
168
+ };
169
+ type InitialStateFor<Fields extends FormFields> = {
170
+ readonly id?: string;
171
+ readonly values: Schema.Struct.Type<Fields>;
172
+ readonly defaultValues?: Schema.Struct.Type<Fields>;
173
+ readonly errors?: Schema.Struct.Type<OptionalFields<Fields, typeof Schema.String>>;
174
+ readonly meta?: Schema.Struct.Type<OptionalFields<Fields, typeof FieldMetaSchema>>;
175
+ readonly submitting?: boolean;
176
+ };
177
+ /**
178
+ * Builds the serializable schema for a form's hydrated state.
179
+ *
180
+ * @remarks
181
+ * ## Why
182
+ * The hydration payload needs validation independent from runtime-only field codecs.
183
+ *
184
+ * ## Ownership and lifetime
185
+ * Pure schema construction; the returned Schema acquires no Scope or subscription.
186
+ *
187
+ * @example
188
+ * ```ts
189
+ * import { StateSchema } from "@typed/ui/Form"
190
+ * import { Schema } from "effect"
191
+ *
192
+ * const codec = Schema.Struct({ email: Schema.String })
193
+ * const stateCodec = StateSchema(codec)
194
+ * ```
195
+ *
196
+ * @since 1.0.0
197
+ * @category schemas
198
+ */
199
+ export declare function StateSchema<const Fields extends FormFields>(codec: Schema.Struct<Fields>): Schema.Struct<{
200
+ readonly values: Schema.Struct<Fields>;
201
+ readonly defaultValues: Schema.Struct<Fields>;
202
+ readonly errors: Schema.Struct<OptionalFields<Fields, Schema.String>>;
203
+ readonly meta: Schema.Struct<OptionalFields<Fields, Schema.Struct<{
204
+ readonly dirty: Schema.Boolean;
205
+ readonly touched: Schema.Boolean;
206
+ }>>>;
207
+ readonly submitting: Schema.Boolean;
208
+ }>;
209
+ /**
210
+ * Creates a Scope-owned hydrated form RefSubject from a Struct codec.
211
+ *
212
+ * @remarks
213
+ * ## Why
214
+ * One constructor establishes values, defaults, validation state, field codecs,
215
+ * and hydration identity consistently.
216
+ *
217
+ * ## Ownership and lifetime
218
+ * Requires `Scope.Scope`. Provide an explicit `id` during SSR; the counter-based
219
+ * fallback is process/order dependent. Only state data hydrates—`codec` and
220
+ * `fields` are reattached from the live Struct on each runtime.
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import { makeState } from "@typed/ui/Form"
225
+ * import { Effect, Schema } from "effect"
226
+ *
227
+ * const codec = Schema.Struct({ email: Schema.String })
228
+ * const program = Effect.gen(function* () {
229
+ * const state = yield* makeState(codec, { id: "signup", values: { email: "" } })
230
+ * return state
231
+ * })
232
+ * ```
233
+ *
234
+ * @since 1.0.0
235
+ * @category constructors
236
+ */
237
+ export declare function makeState<const Fields extends FormFields>(codec: Schema.Struct<Fields>, initial: InitialStateFor<Fields>): Effect.Effect<RefSubject.HydratedRefSubject<{
238
+ readonly values: Schema.Struct.View<Fields, "Type", Schema.Struct.TypeOptionalKeys<Fields>, Schema.Struct.TypeMutableKeys<Fields>>;
239
+ readonly defaultValues: Schema.Struct.View<Fields, "Type", Schema.Struct.TypeOptionalKeys<Fields>, Schema.Struct.TypeMutableKeys<Fields>>;
240
+ readonly errors: Schema.Struct.View<OptionalFields<Fields, Schema.String>, "Type", Schema.Struct.TypeOptionalKeys<OptionalFields<Fields, Schema.String>>, Schema.Struct.TypeMutableKeys<OptionalFields<Fields, Schema.String>>>;
241
+ readonly meta: Schema.Struct.View<OptionalFields<Fields, Schema.Struct<{
242
+ readonly dirty: Schema.Boolean;
243
+ readonly touched: Schema.Boolean;
244
+ }>>, "Type", Schema.Struct.TypeOptionalKeys<OptionalFields<Fields, Schema.Struct<{
245
+ readonly dirty: Schema.Boolean;
246
+ readonly touched: Schema.Boolean;
247
+ }>>>, Schema.Struct.TypeMutableKeys<OptionalFields<Fields, Schema.Struct<{
248
+ readonly dirty: Schema.Boolean;
249
+ readonly touched: Schema.Boolean;
250
+ }>>>>;
251
+ readonly submitting: boolean;
252
+ }, Schema.SchemaError, never, Schema.Struct.DecodingServices<{
253
+ readonly values: Schema.Struct<Fields>;
254
+ readonly defaultValues: Schema.Struct<Fields>;
255
+ readonly errors: Schema.Struct<OptionalFields<Fields, Schema.String>>;
256
+ readonly meta: Schema.Struct<OptionalFields<Fields, Schema.Struct<{
257
+ readonly dirty: Schema.Boolean;
258
+ readonly touched: Schema.Boolean;
259
+ }>>>;
260
+ readonly submitting: Schema.Boolean;
261
+ }> | Schema.Struct.EncodingServices<{
262
+ readonly values: Schema.Struct<Fields>;
263
+ readonly defaultValues: Schema.Struct<Fields>;
264
+ readonly errors: Schema.Struct<OptionalFields<Fields, Schema.String>>;
265
+ readonly meta: Schema.Struct<OptionalFields<Fields, Schema.Struct<{
266
+ readonly dirty: Schema.Boolean;
267
+ readonly touched: Schema.Boolean;
268
+ }>>>;
269
+ readonly submitting: Schema.Boolean;
270
+ }>> & {
271
+ codec: Schema.Struct<Fields>;
272
+ fields: Fields;
273
+ id: string;
274
+ }, never, Scope.Scope>;
275
+ /**
276
+ * Field names whose decoded value is assignable to `Value`.
277
+ *
278
+ * @remarks
279
+ * ## Why
280
+ * Control options reject incompatible fields at compile time.
281
+ *
282
+ * ## Ownership and lifetime
283
+ * Type-only and resource-free.
284
+ *
285
+ * @since 1.0.0
286
+ * @category type-level
287
+ */
288
+ export type FieldNameFor<Values extends object, Value> = {
289
+ [Key in keyof Values & string]: Values[Key] extends Value ? Key : never;
290
+ }[keyof Values & string];
291
+ /**
292
+ * Struct field names matching both decoded and encoded control value types.
293
+ *
294
+ * @remarks
295
+ * ## Why
296
+ * 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
+ * @since 1.0.0
302
+ * @category type-level
303
+ */
304
+ export type SchemaFieldNameFor<Fields extends FormFields, Value, Encoded> = {
305
+ [Key in keyof Fields & string]: Fields[Key]["Type"] extends Value ? Fields[Key]["Encoded"] extends Encoded ? Key : never : never;
306
+ }[keyof Fields & string];
307
+ /**
308
+ * Options shared by state-explicit native input components.
309
+ *
310
+ * @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
+ *
319
+ * @since 1.0.0
320
+ * @category component-options
321
+ */
322
+ export interface InputOptions<Values extends object, Value> extends Dom.HostOptions<HTMLInputElement> {
323
+ /** Renderer-independent form state to read and update. */
324
+ readonly state: FormState<Values>;
325
+ /** Type-compatible field name. */
326
+ readonly name: FieldNameFor<Values, Value>;
327
+ /** Optional string codec overriding the input type's default codec. */
328
+ readonly codec?: Schema.Codec<Value, string>;
329
+ }
330
+ /**
331
+ * String-valued native input options.
332
+ * @remarks
333
+ * ## Why
334
+ * Names are restricted to fields a text-like control can represent without an incompatible cast.
335
+ * ## Ownership and lifetime
336
+ * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
337
+ * @since 1.0.0
338
+ * @category component-options
339
+ */
340
+ export type TextInputOptions<Values extends object> = InputOptions<Values, string>;
341
+ /**
342
+ * Finite-number native input options.
343
+ * @remarks
344
+ * ## Why
345
+ * Names are restricted to numeric fields compatible with number/range decoding.
346
+ * ## Ownership and lifetime
347
+ * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
348
+ * @since 1.0.0
349
+ * @category component-options
350
+ */
351
+ export type NumberInputOptions<Values extends object> = InputOptions<Values, number>;
352
+ /**
353
+ * Date-valued native input options.
354
+ * @remarks
355
+ * ## Why
356
+ * Names are restricted to Date fields compatible with native date-string decoding.
357
+ * ## Ownership and lifetime
358
+ * The control Scope owns DOM work; the referenced state and optional codec are borrowed.
359
+ * @since 1.0.0
360
+ * @category component-options
361
+ */
362
+ 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>): () => {
364
+ readonly type: string;
365
+ readonly name: FieldNameFor<Values, Value>;
366
+ readonly "aria-describedby": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
367
+ readonly "aria-invalid": RefSubject.Computed<true | undefined, Schema.SchemaError, never>;
368
+ readonly ".value": RefSubject.Computed<string, Schema.SchemaError, never>;
369
+ readonly oninput: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
370
+ };
371
+ type InputProps<Values extends object, Value> = ReturnType<ReturnType<typeof inputProps<Values, Value>>>;
372
+ type RenderableComponentOptions<Options> = Pick<Options, Extract<keyof Options, "props" | "ref" | "content" | Dom.EventHandlerProperty>>;
373
+ /**
374
+ * Options for a schema-bound native input.
375
+ *
376
+ * @remarks
377
+ * ## Why
378
+ * The factory's Struct infers compatible field names, so callers need not pass state or a codec.
379
+ *
380
+ * ## Ownership and lifetime
381
+ * State is borrowed from `CurrentForm`; the control's Scope owns its DOM subscription.
382
+ *
383
+ * @since 1.0.0
384
+ * @category component-options
385
+ */
386
+ 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. */
388
+ readonly name: SchemaFieldNameFor<Fields, Value, string>;
389
+ }
390
+ /**
391
+ * Options for a schema-bound masked text input.
392
+ *
393
+ * @remarks
394
+ * ## Why
395
+ * Any field with a string encoding can use the Struct field codec as its mask codec.
396
+ *
397
+ * ## Ownership and lifetime
398
+ * State is borrowed from `CurrentForm`; the control Scope owns DOM work.
399
+ *
400
+ * @since 1.0.0
401
+ * @category component-options
402
+ */
403
+ export interface SchemaBoundMaskedInputOptions<Fields extends FormFields> extends Dom.HostOptions<HTMLInputElement> {
404
+ /** Struct field whose codec accepts the input's string representation. */
405
+ readonly name: SchemaFieldNameFor<Fields, unknown, string>;
406
+ }
407
+ /**
408
+ * Options for a schema-bound boolean checkbox.
409
+ *
410
+ * @remarks
411
+ * ## Why
412
+ * Field-name inference limits the native checked binding to boolean fields.
413
+ *
414
+ * ## Ownership and lifetime
415
+ * State is borrowed from `CurrentForm`; the control Scope owns DOM work.
416
+ *
417
+ * @since 1.0.0
418
+ * @category component-options
419
+ */
420
+ export interface SchemaBoundCheckboxOptions<Values extends object> extends Dom.HostOptions<HTMLInputElement> {
421
+ /** Boolean field controlled by the checkbox. */
422
+ readonly name: BooleanFieldName<Values>;
423
+ }
424
+ /**
425
+ * Options for a schema-bound native select.
426
+ *
427
+ * @remarks
428
+ * ## Why
429
+ * Native option markup remains caller-authored while selection binds to a string field.
430
+ *
431
+ * ## Ownership and lifetime
432
+ * State is borrowed from `CurrentForm`; rendered content is owned by the control Scope.
433
+ *
434
+ * @since 1.0.0
435
+ * @category component-options
436
+ */
437
+ export interface SchemaBoundSelectOptions<Values extends object> extends Dom.HostOptions<HTMLSelectElement> {
438
+ /** String field controlled by the select. */
439
+ readonly name: FieldNameFor<Values, string>;
440
+ /** Native option/optgroup renderable content. */
441
+ readonly content: Renderable.Any;
442
+ }
443
+ /**
444
+ * Options for a schema-bound field-error region.
445
+ *
446
+ * @remarks
447
+ * ## Why
448
+ * Error text and ARIA relationships derive from the same form identity and field name.
449
+ *
450
+ * ## Ownership and lifetime
451
+ * State is borrowed from `CurrentForm`; the error host Scope owns its subscription.
452
+ *
453
+ * @since 1.0.0
454
+ * @category component-options
455
+ */
456
+ export interface SchemaBoundErrorOptions<Values extends object> extends Dom.HostOptions<HTMLDivElement> {
457
+ /** Field whose current validation message is rendered. */
458
+ readonly name: keyof Values & string;
459
+ }
460
+ /**
461
+ * Options for a schema-bound reset button.
462
+ *
463
+ * @remarks
464
+ * ## Why
465
+ * The button can use native semantics without receiving state explicitly.
466
+ *
467
+ * ## Ownership and lifetime
468
+ * State is borrowed from `CurrentForm`; button content is Scope-owned renderable work.
469
+ *
470
+ * @since 1.0.0
471
+ * @category component-options
472
+ */
473
+ export interface SchemaBoundResetOptions extends Dom.HostOptions<HTMLButtonElement> {
474
+ /** Reset button label/content. */
475
+ readonly content: Renderable.Any;
476
+ }
477
+ /**
478
+ * Options for a schema-bound array append button.
479
+ *
480
+ * @remarks
481
+ * ## Why
482
+ * Array field and element types are inferred from the form schema.
483
+ *
484
+ * ## Ownership and lifetime
485
+ * State is borrowed from `CurrentForm`; the click Effect and content share the host Scope.
486
+ *
487
+ * @since 1.0.0
488
+ * @category component-options
489
+ */
490
+ export interface SchemaBoundPushOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
491
+ /** Array-valued field to append to. */
492
+ readonly name: Name;
493
+ /** Type-compatible item appended on activation. */
494
+ readonly value: ArrayFieldValue<Values, Name>;
495
+ /** Button label/content. */
496
+ readonly content: Renderable.Any;
497
+ }
498
+ /**
499
+ * Options for a schema-bound array removal button.
500
+ *
501
+ * @remarks
502
+ * ## Why
503
+ * The field is constrained to arrays and the index remains an explicit local operation.
504
+ *
505
+ * ## Ownership and lifetime
506
+ * State is borrowed from `CurrentForm`; the click Effect and content share the host Scope.
507
+ *
508
+ * @since 1.0.0
509
+ * @category component-options
510
+ */
511
+ export interface SchemaBoundRemoveOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
512
+ /** Array-valued field to remove from. */
513
+ readonly name: Name;
514
+ /** Zero-based item index removed on activation. */
515
+ readonly index: number;
516
+ /** Button label/content. */
517
+ readonly content: Renderable.Any;
518
+ }
519
+ /**
520
+ * Public component contract shared by state-explicit native input factories.
521
+ *
522
+ * @remarks
523
+ * ## Why
524
+ *
525
+ * Text-like, numeric, range, and date controls differ in their default codec while preserving one
526
+ * field-inference, host-override, error, and service contract. Naming that contract keeps emitted
527
+ * declarations readable without hiding any generic channel behind a private compiler alias.
528
+ *
529
+ * ## Ownership and lifetime
530
+ *
531
+ * Calling an input component starts no work. The returned Fx requires the Scope and RenderTemplate
532
+ * that own DOM rendering; the supplied FormState remains independently owned and may outlive it.
533
+ *
534
+ * @example
535
+ * ```ts
536
+ * import { InputComponent, makeState, TextInput } from "@typed/ui/Form"
537
+ * import { html } from "@typed/template"
538
+ * import { Effect, Schema } from "effect"
539
+ *
540
+ * const Text: InputComponent<string> = TextInput
541
+ * const rendered = Effect.gen(function* () {
542
+ * const state = yield* makeState(Schema.Struct({ name: Schema.String }), {
543
+ * values: { name: "" }
544
+ * })
545
+ * return Text({ state, name: "name" }, (props) => html`<input ...${props} />`)
546
+ * })
547
+ * ```
548
+ *
549
+ * @since 1.0.0
550
+ * @category models
551
+ */
552
+ 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
+ /**
554
+ * Binds a native `input[type=text]` to a string field.
555
+ *
556
+ * @remarks
557
+ * ## Why
558
+ * The control uses the browser's real input event and a Schema codec while
559
+ * keeping state independently testable.
560
+ *
561
+ * ## Ownership and lifetime
562
+ * The control Scope owns DOM listeners/subscriptions; the supplied `FormState`
563
+ * may outlive the rendered input. A custom host must apply all merged props.
564
+ *
565
+ * @example
566
+ * ```ts
567
+ * import { TextInput, makeState } from "@typed/ui/Form"
568
+ * import { Effect, Schema } from "effect"
569
+ *
570
+ * const codec = Schema.Struct({ name: Schema.String })
571
+ * const input = Effect.gen(function* () {
572
+ * const state = yield* makeState(codec, { values: { name: "" } })
573
+ * return TextInput({ state, name: "name" })
574
+ * })
575
+ * ```
576
+ *
577
+ * @since 1.0.0
578
+ * @category components
579
+ */
580
+ export declare const TextInput: InputComponent<string>;
581
+ /**
582
+ * Binds a native search input to a string field.
583
+ * @remarks
584
+ * ## Why
585
+ * 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
+ * @since 1.0.0
589
+ * @category components
590
+ */
591
+ export declare const SearchInput: InputComponent<string>;
592
+ /**
593
+ * Binds a native email input to a string field.
594
+ * @remarks
595
+ * ## Why
596
+ * 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
+ * @since 1.0.0
600
+ * @category components
601
+ */
602
+ export declare const EmailInput: InputComponent<string>;
603
+ /**
604
+ * Binds a native URL input to a string field.
605
+ * @remarks
606
+ * ## Why
607
+ * 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
+ * @since 1.0.0
611
+ * @category components
612
+ */
613
+ export declare const UrlInput: InputComponent<string>;
614
+ /**
615
+ * Binds a native telephone input to a string field.
616
+ * @remarks
617
+ * ## Why
618
+ * Preserves platform telephone keyboards and autocomplete behavior.
619
+ * ## Ownership and lifetime
620
+ * DOM work is control-Scope-owned; form state remains independently owned.
621
+ * @since 1.0.0
622
+ * @category components
623
+ */
624
+ export declare const TelInput: InputComponent<string>;
625
+ /**
626
+ * Binds a native password input to a string field.
627
+ * @remarks
628
+ * ## Why
629
+ * 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
+ * @since 1.0.0
633
+ * @category components
634
+ */
635
+ export declare const PasswordInput: InputComponent<string>;
636
+ /**
637
+ * Binds a native hidden input to a string field.
638
+ * @remarks
639
+ * ## Why
640
+ * 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
+ * @since 1.0.0
644
+ * @category components
645
+ */
646
+ export declare const HiddenInput: InputComponent<string>;
647
+ /**
648
+ * Binds a native color input to a string field.
649
+ * @remarks
650
+ * ## Why
651
+ * 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
+ * @since 1.0.0
655
+ * @category components
656
+ */
657
+ export declare const ColorInput: InputComponent<string>;
658
+ /**
659
+ * Binds a native time input to a string field.
660
+ * @remarks
661
+ * ## Why
662
+ * 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
+ * @since 1.0.0
666
+ * @category components
667
+ */
668
+ export declare const TimeInput: InputComponent<string>;
669
+ /**
670
+ * Binds a native local date-time input to a string field.
671
+ * @remarks
672
+ * ## Why
673
+ * 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
+ * @since 1.0.0
677
+ * @category components
678
+ */
679
+ export declare const DateTimeLocalInput: InputComponent<string>;
680
+ /**
681
+ * Binds a native month input to a string field.
682
+ * @remarks
683
+ * ## Why
684
+ * 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
+ * @since 1.0.0
688
+ * @category components
689
+ */
690
+ export declare const MonthInput: InputComponent<string>;
691
+ /**
692
+ * Binds a native week input to a string field.
693
+ * @remarks
694
+ * ## Why
695
+ * 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
+ * @since 1.0.0
699
+ * @category components
700
+ */
701
+ export declare const WeekInput: InputComponent<string>;
702
+ /**
703
+ * Binds a native number input to a finite number field.
704
+ * @remarks
705
+ * ## Why
706
+ * `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
+ * @since 1.0.0
710
+ * @category components
711
+ */
712
+ export declare const NumberInput: InputComponent<number>;
713
+ /**
714
+ * Binds a native range input to a finite number field.
715
+ * @remarks
716
+ * ## Why
717
+ * 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
+ * @since 1.0.0
721
+ * @category components
722
+ */
723
+ export declare const RangeInput: InputComponent<number>;
724
+ /**
725
+ * Binds a native date input to a `Date` field.
726
+ * @remarks
727
+ * ## Why
728
+ * `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
+ * @since 1.0.0
732
+ * @category components
733
+ */
734
+ export declare const DateInput: InputComponent<Date>;
735
+ /**
736
+ * Native value emitted by `FormData`.
737
+ * @remarks
738
+ * ## Why
739
+ * Browser serialization produces strings and Files; the union states that boundary exactly.
740
+ * ## Ownership and lifetime
741
+ * Files remain browser-owned objects referenced by the converted record.
742
+ * @since 1.0.0
743
+ * @category models
744
+ */
745
+ export type FormDataValue = string | File;
746
+ /**
747
+ * Object representation of native FormData, preserving repeated names as arrays.
748
+ * @remarks
749
+ * ## Why
750
+ * A plain record is directly consumable by Effect Schema without losing repeats.
751
+ * ## Ownership and lifetime
752
+ * Conversion allocates arrays/record entries but retains original File objects.
753
+ * @since 1.0.0
754
+ * @category models
755
+ */
756
+ export type FormDataRecord = Readonly<Record<string, FormDataValue | ReadonlyArray<FormDataValue>>>;
757
+ /**
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.
765
+ * @example
766
+ * ```ts
767
+ * import { formDataToRecord } from "@typed/ui/Form"
768
+ *
769
+ * const data = new FormData()
770
+ * data.append("tag", "one")
771
+ * data.append("tag", "two")
772
+ * const record = formDataToRecord(data)
773
+ * ```
774
+ * @since 1.0.0
775
+ * @category conversions
776
+ */
777
+ export declare function formDataToRecord(data: FormData): FormDataRecord;
778
+ /**
779
+ * Decodes native FormData through an Effect Schema codec.
780
+ * @remarks
781
+ * ## Why
782
+ * Browser serialization, repeated values, Files, and typed validation meet at
783
+ * one explicit fallible boundary.
784
+ * ## Ownership and lifetime
785
+ * The returned Effect is lazy and owns no browser resource; it references File
786
+ * objects present in the supplied FormData.
787
+ * @example
788
+ * ```ts
789
+ * import { decodeFormData } from "@typed/ui/Form"
790
+ * import { Schema } from "effect"
791
+ *
792
+ * const decode = decodeFormData(Schema.Struct({ name: Schema.String }), new FormData())
793
+ * ```
794
+ * @since 1.0.0
795
+ * @category conversions
796
+ */
797
+ 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
+ /**
799
+ * Validates current form values and synchronizes decoded values or field errors.
800
+ * @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`.
806
+ * @since 1.0.0
807
+ * @category validation
808
+ */
809
+ export declare function validate<Values extends object>(state: FormState<Values>): Effect.Effect<Values, Schema.SchemaError, never>;
810
+ /**
811
+ * Named decoded segment in a bidirectional text mask.
812
+ * @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.
817
+ * @since 1.0.0
818
+ * @category models
819
+ */
820
+ export interface MaskSlot<Name extends string = string, Value = unknown> {
821
+ /** Discriminant used to distinguish slots from literal mask parts. */
822
+ readonly _tag: "MaskSlot";
823
+ /** Property name written into the decoded mask object. */
824
+ readonly name: Name;
825
+ /** Bidirectional conversion between this slot's string segment and decoded value. */
826
+ readonly codec: Schema.Codec<Value, string>;
827
+ /** Exact encoded character count, when fixed-width. */
828
+ readonly length?: number;
829
+ /** Per-character acceptance test applied before Schema decoding. */
830
+ readonly charset?: RegExp | ((character: string) => boolean);
831
+ }
832
+ /**
833
+ * Literal or decoded segment of a mask.
834
+ * @remarks
835
+ * ## Why
836
+ * The tuple order completely specifies parsing and formatting.
837
+ * ## Ownership and lifetime
838
+ * Immutable description data with no runtime ownership.
839
+ * @since 1.0.0
840
+ * @category models
841
+ */
842
+ export type MaskPart = string | MaskSlot;
843
+ /**
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
+ */
853
+ export type MaskValue<Parts extends ReadonlyArray<MaskPart>> = {
854
+ readonly [Part in Parts[number] as Part extends MaskSlot<infer Name> ? Name : never]: Part extends MaskSlot<string, infer Value> ? Value : never;
855
+ };
856
+ /**
857
+ * Creates a named, Schema-decoded mask slot.
858
+ * @remarks
859
+ * ## Why
860
+ * Length and character constraints are expressed beside the codec that owns conversion.
861
+ * ## Ownership and lifetime
862
+ * Pure constructor; the returned descriptor retains the codec but acquires no Scope.
863
+ * @example
864
+ * ```ts
865
+ * import { slot } from "@typed/ui/Form"
866
+ * import { Schema } from "effect"
867
+ *
868
+ * const areaCode = slot("area", Schema.String, { length: 3, charset: /[0-9]/ })
869
+ * ```
870
+ * @since 1.0.0
871
+ * @category constructors
872
+ */
873
+ 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
+ /**
875
+ * Builds a bidirectional Schema codec from literal text and named slots.
876
+ * @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.
882
+ * @example
883
+ * ```ts
884
+ * import { mask, slot } from "@typed/ui/Form"
885
+ * import { Schema } from "effect"
886
+ *
887
+ * const phone = mask("(", slot("area", Schema.String, { length: 3 }), ") ",
888
+ * slot("number", Schema.String, { length: 7 }))
889
+ * ```
890
+ * @since 1.0.0
891
+ * @category schemas
892
+ */
893
+ export declare function mask<const Parts extends ReadonlyArray<MaskPart>>(...parts: Parts): Schema.Codec<MaskValue<Parts>, string>;
894
+ /**
895
+ * Options for an input decoded through a structured mask codec.
896
+ * @remarks
897
+ * ## Why
898
+ * A normal text input can expose a structured typed value without hiding native events or props.
899
+ * ## Ownership and lifetime
900
+ * The control Scope owns DOM work; form state and the mask codec remain independently owned.
901
+ * @since 1.0.0
902
+ * @category component-options
903
+ */
904
+ 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. */
906
+ readonly mask: Schema.Codec<MaskValue<Parts>, string>;
907
+ }
908
+ /**
909
+ * Binds a native text input to a structured mask value.
910
+ * @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.
917
+ * @since 1.0.0
918
+ * @category components
919
+ */
920
+ 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
+ /**
922
+ * Options for a state-explicit native checkbox.
923
+ * @remarks
924
+ * ## Why
925
+ * Boolean field inference and live `checked` binding preserve native checkbox behavior.
926
+ * ## Ownership and lifetime
927
+ * The control Scope owns the listener/binding; form state may outlive the element.
928
+ * @since 1.0.0
929
+ * @category component-options
930
+ */
931
+ export interface CheckboxOptions<Values extends object> extends Dom.HostOptions<HTMLInputElement> {
932
+ /** Renderer-independent state read and updated by the checkbox. */
933
+ readonly state: FormState<Values>;
934
+ /** Boolean field controlled by the checkbox. */
935
+ readonly name: BooleanFieldName<Values>;
936
+ }
937
+ declare function checkboxProps<Values extends object>(options: CheckboxOptions<Values>): () => {
938
+ readonly type: "checkbox";
939
+ readonly name: BooleanFieldName<Values>;
940
+ readonly "aria-describedby": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
941
+ readonly "aria-invalid": RefSubject.Computed<true | undefined, Schema.SchemaError, never>;
942
+ readonly "?checked": RefSubject.Computed<boolean, Schema.SchemaError, never>;
943
+ readonly ".checked": RefSubject.Computed<boolean, Schema.SchemaError, never>;
944
+ readonly onchange: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
945
+ };
946
+ type CheckboxProps<Values extends object> = ReturnType<ReturnType<typeof checkboxProps<Values>>>;
947
+ /**
948
+ * Binds a native checkbox to a boolean form field.
949
+ * @remarks
950
+ * ## Why
951
+ * Both the checked attribute and live property follow state, while the browser's
952
+ * real change event is decoded through the field codec.
953
+ * ## Ownership and lifetime
954
+ * The rendered Scope owns the input, listener, and subscriptions. A custom host
955
+ * must apply merged name, ARIA, checked, and change props.
956
+ * @since 1.0.0
957
+ * @category components
958
+ */
959
+ 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
+ /**
961
+ * Options for a state-explicit native select.
962
+ * @remarks
963
+ * ## Why
964
+ * Callers author ordinary option markup while the selected value binds to typed state.
965
+ * ## Ownership and lifetime
966
+ * The control Scope owns content, listener, and binding; form state may outlive it.
967
+ * @since 1.0.0
968
+ * @category component-options
969
+ */
970
+ export interface SelectOptions<Values extends object> extends Dom.HostOptions<HTMLSelectElement> {
971
+ /** Renderer-independent state read and updated by the select. */
972
+ readonly state: FormState<Values>;
973
+ /** String field controlled by the select. */
974
+ readonly name: FieldNameFor<Values, string>;
975
+ /** Native option/optgroup renderable content. */
976
+ readonly content: Renderable.Any;
977
+ }
978
+ declare function selectProps<Values extends object>(options: SelectOptions<Values>): () => {
979
+ readonly name: FieldNameFor<Values, string>;
980
+ readonly "aria-describedby": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
981
+ readonly "aria-invalid": RefSubject.Computed<true | undefined, Schema.SchemaError, never>;
982
+ readonly ".value": RefSubject.Computed<string, Schema.SchemaError, never>;
983
+ readonly onchange: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
984
+ };
985
+ type SelectProps<Values extends object> = ReturnType<ReturnType<typeof selectProps<Values>>>;
986
+ /**
987
+ * Binds a native select element to a string form field.
988
+ * @remarks
989
+ * ## Why
990
+ * Native keyboard, accessibility, option, and form semantics remain browser-owned.
991
+ * ## Ownership and lifetime
992
+ * The rendered Scope owns the select/content subscriptions. A custom host must
993
+ * preserve supplied name, ARIA, value, and change props.
994
+ * @since 1.0.0
995
+ * @category components
996
+ */
997
+ 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
+ /**
999
+ * Options for a native form label.
1000
+ * @remarks
1001
+ * ## Why
1002
+ * Explicit `for` linkage keeps accessible naming in browser-standard markup.
1003
+ * ## Ownership and lifetime
1004
+ * The label Scope owns rendered content only; it does not own the referenced control.
1005
+ * @since 1.0.0
1006
+ * @category component-options
1007
+ */
1008
+ export interface LabelOptions extends Dom.HostOptions<HTMLLabelElement> {
1009
+ /** ID of the native control labeled by this element. */
1010
+ readonly for: string;
1011
+ /** Human-readable label content. */
1012
+ readonly content: Renderable.Any;
1013
+ }
1014
+ declare function labelProps<const Options extends LabelOptions>(options: Options): () => {
1015
+ readonly for: string;
1016
+ };
1017
+ type LabelProps<Options extends LabelOptions> = ReturnType<ReturnType<typeof labelProps<Options>>>;
1018
+ /**
1019
+ * Renders a native label with an explicit control relationship.
1020
+ * @remarks
1021
+ * ## Why
1022
+ * The browser supplies click-to-focus and accessible-name behavior with no synthetic layer.
1023
+ * ## Ownership and lifetime
1024
+ * The Scope owns label output/content; the referenced element remains separately owned.
1025
+ * @since 1.0.0
1026
+ * @category components
1027
+ */
1028
+ 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
+ /**
1030
+ * Options for descriptive form content.
1031
+ * @remarks
1032
+ * ## Why
1033
+ * Provides a host-overrideable descriptive region without inventing text semantics.
1034
+ * ## Ownership and lifetime
1035
+ * The host Scope owns the rendered content.
1036
+ * @since 1.0.0
1037
+ * @category component-options
1038
+ */
1039
+ export interface DescriptionOptions extends Dom.HostOptions<HTMLDivElement> {
1040
+ /** Descriptive renderable content. */
1041
+ readonly content: Renderable.Any;
1042
+ }
1043
+ declare function descriptionProps(): () => {};
1044
+ type DescriptionProps = ReturnType<ReturnType<typeof descriptionProps>>;
1045
+ /**
1046
+ * Renders form description content in a neutral native div by default.
1047
+ * @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.
1052
+ * @since 1.0.0
1053
+ * @category components
1054
+ */
1055
+ 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
+ /**
1057
+ * Options for a field validation alert.
1058
+ * @remarks
1059
+ * ## Why
1060
+ * Error identity derives from form and field IDs so controls can reference it reliably.
1061
+ * ## Ownership and lifetime
1062
+ * The error host subscribes within its Scope; form state remains independently owned.
1063
+ * @since 1.0.0
1064
+ * @category component-options
1065
+ */
1066
+ export interface ErrorOptions<Values extends object> extends Dom.HostOptions<HTMLDivElement> {
1067
+ /** Renderer-independent state supplying validation errors. */
1068
+ readonly state: FormState<Values>;
1069
+ /** Field whose current message is rendered. */
1070
+ readonly name: keyof Values & string;
1071
+ }
1072
+ declare function errorProps<Values extends object>(options: ErrorOptions<Values>): () => {
1073
+ readonly id: string;
1074
+ readonly role: "alert";
1075
+ };
1076
+ type ErrorProps<Values extends object> = ReturnType<ReturnType<typeof errorProps<Values>>>;
1077
+ /**
1078
+ * Renders the current field error as a native ARIA alert region.
1079
+ * @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.
1085
+ * @since 1.0.0
1086
+ * @category components
1087
+ */
1088
+ 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
+ /**
1090
+ * Options for a native submit button.
1091
+ * @remarks
1092
+ * ## Why
1093
+ * Uses ordinary form submission semantics while exposing all button props/events.
1094
+ * ## Ownership and lifetime
1095
+ * The button Scope owns rendered content and listeners.
1096
+ * @since 1.0.0
1097
+ * @category component-options
1098
+ */
1099
+ export interface SubmitOptions extends Dom.HostOptions<HTMLButtonElement> {
1100
+ /** Submit button label/content. */
1101
+ readonly content: Renderable.Any;
1102
+ }
1103
+ declare function submitProps(): () => {
1104
+ readonly type: "submit";
1105
+ };
1106
+ type SubmitProps = ReturnType<ReturnType<typeof submitProps>>;
1107
+ /**
1108
+ * Renders a native `type=submit` button.
1109
+ * @remarks
1110
+ * ## Why
1111
+ * Keyboard activation, form association, and accessibility stay browser-standard.
1112
+ * ## Ownership and lifetime
1113
+ * The Scope owns the button/content; the surrounding Form owns submission sequencing.
1114
+ * @since 1.0.0
1115
+ * @category components
1116
+ */
1117
+ 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
+ /**
1119
+ * Options for a state-explicit reset button.
1120
+ * @remarks
1121
+ * ## Why
1122
+ * Native reset activation can restore renderer-independent Typed state deterministically.
1123
+ * ## Ownership and lifetime
1124
+ * The click Effect runs in the button Scope; state may outlive the button.
1125
+ * @since 1.0.0
1126
+ * @category component-options
1127
+ */
1128
+ export interface ResetOptions<Values extends object> extends Dom.HostOptions<HTMLButtonElement> {
1129
+ /** Renderer-independent state restored on activation. */
1130
+ readonly state: FormState<Values>;
1131
+ /** Reset button label/content. */
1132
+ readonly content: Renderable.Any;
1133
+ }
1134
+ declare function resetProps<Values extends object>(options: ResetOptions<Values>): () => {
1135
+ readonly type: "reset";
1136
+ readonly onclick: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
1137
+ };
1138
+ type ResetProps<Values extends object> = ReturnType<ReturnType<typeof resetProps<Values>>>;
1139
+ /**
1140
+ * Renders a native reset button that restores Typed form defaults.
1141
+ * @remarks
1142
+ * ## Why
1143
+ * It prevents the browser's independent control mutation and resets the single
1144
+ * RefSubject source of truth, clearing errors, metadata, and submitting state.
1145
+ * ## Ownership and lifetime
1146
+ * The Scope owns the click handler/content. The supplied form state remains independently owned.
1147
+ * @since 1.0.0
1148
+ * @category components
1149
+ */
1150
+ 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
+ /**
1152
+ * Options for an accessible group of form controls.
1153
+ * @remarks
1154
+ * ## Why
1155
+ * Provides a native host with `role=group` and optional accessible label.
1156
+ * ## Ownership and lifetime
1157
+ * The group Scope owns child renderables but not their independent form state.
1158
+ * @since 1.0.0
1159
+ * @category component-options
1160
+ */
1161
+ export interface GroupOptions extends Dom.HostOptions<HTMLDivElement> {
1162
+ /** Controls or other renderable members of the group. */
1163
+ readonly content: Renderable.Any;
1164
+ /** Optional accessible name applied through `aria-label`. */
1165
+ readonly label?: string;
1166
+ }
1167
+ declare function groupProps<const Options extends GroupOptions>(options: Options): () => {
1168
+ readonly role: "group";
1169
+ readonly "aria-label": string | undefined;
1170
+ };
1171
+ type GroupProps<Options extends GroupOptions> = ReturnType<ReturnType<typeof groupProps<Options>>>;
1172
+ /**
1173
+ * Renders an ARIA group with an optional accessible name.
1174
+ * @remarks
1175
+ * ## Why
1176
+ * Related controls can expose their relationship without a framework-specific wrapper.
1177
+ * ## Ownership and lifetime
1178
+ * The Scope owns host/content; child controls retain their own DOM/state contracts.
1179
+ * @since 1.0.0
1180
+ * @category components
1181
+ */
1182
+ 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
+ /**
1184
+ * Options for an array-field append button.
1185
+ * @remarks
1186
+ * ## Why
1187
+ * The field name and appended item are derived from the form value type.
1188
+ * ## Ownership and lifetime
1189
+ * The click Effect runs in the button Scope; form state remains independently owned.
1190
+ * @since 1.0.0
1191
+ * @category component-options
1192
+ */
1193
+ export interface PushOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
1194
+ /** Renderer-independent state updated on activation. */
1195
+ readonly state: FormState<Values>;
1196
+ /** Array-valued field to append to. */
1197
+ readonly name: Name;
1198
+ /** Type-compatible item appended to the field. */
1199
+ readonly value: ArrayFieldValue<Values, Name>;
1200
+ /** Button label/content. */
1201
+ readonly content: Renderable.Any;
1202
+ }
1203
+ declare function pushProps<Values extends object, Name extends ArrayFieldName<Values>>(options: PushOptions<Values, Name>): () => {
1204
+ readonly type: "button";
1205
+ readonly onclick: Effect.Effect<State<Values>, Schema.SchemaError, never>;
1206
+ };
1207
+ type PushProps<Values extends object, Name extends ArrayFieldName<Values>> = ReturnType<ReturnType<typeof pushProps<Values, Name>>>;
1208
+ /**
1209
+ * Renders a button that appends one item to an array field.
1210
+ * @remarks
1211
+ * ## Why
1212
+ * Array mutation is immutable, typed, and marks the field dirty/touched.
1213
+ * ## Ownership and lifetime
1214
+ * The Scope owns the button handler/content; state may outlive the button.
1215
+ * @since 1.0.0
1216
+ * @category components
1217
+ */
1218
+ 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
+ /**
1220
+ * Options for an array-field removal button.
1221
+ * @remarks
1222
+ * ## Why
1223
+ * The array field is type-checked and the local index is explicit.
1224
+ * ## Ownership and lifetime
1225
+ * The click Effect runs in the button Scope; form state remains independently owned.
1226
+ * @since 1.0.0
1227
+ * @category component-options
1228
+ */
1229
+ export interface RemoveOptions<Values extends object, Name extends ArrayFieldName<Values>> extends Dom.HostOptions<HTMLButtonElement> {
1230
+ /** Renderer-independent state updated on activation. */
1231
+ readonly state: FormState<Values>;
1232
+ /** Array-valued field to remove from. */
1233
+ readonly name: Name;
1234
+ /** Zero-based item index removed from the field. */
1235
+ readonly index: number;
1236
+ /** Button label/content. */
1237
+ readonly content: Renderable.Any;
1238
+ }
1239
+ declare function removeProps<Values extends object, Name extends ArrayFieldName<Values>>(options: RemoveOptions<Values, Name>): () => {
1240
+ readonly type: "button";
1241
+ readonly onclick: Effect.Effect<State<Values>, Schema.SchemaError, never>;
1242
+ };
1243
+ type RemoveProps<Values extends object, Name extends ArrayFieldName<Values>> = ReturnType<ReturnType<typeof removeProps<Values, Name>>>;
1244
+ /**
1245
+ * Renders a button that removes one array item by index.
1246
+ * @remarks
1247
+ * ## Why
1248
+ * Array mutation is immutable, typed, and marks the field dirty/touched.
1249
+ * ## Ownership and lifetime
1250
+ * The Scope owns the button handler/content; state may outlive the button.
1251
+ * @since 1.0.0
1252
+ * @category components
1253
+ */
1254
+ 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
+ /**
1256
+ * Sets one decoded field value and updates dirty/touched metadata.
1257
+ * @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.
1262
+ * @since 1.0.0
1263
+ * @category state
1264
+ */
1265
+ 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
+ /**
1267
+ * Restores default values and clears errors, interaction metadata, and submission state.
1268
+ * @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`.
1274
+ * @since 1.0.0
1275
+ * @category state
1276
+ */
1277
+ export declare function reset<Values extends object, E, R>(state: RefSubject.RefSubject<State<Values>, E, R>): Effect.Effect<State<Values>, E, R>;
1278
+ /**
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
+ */
1288
+ export type BooleanFieldName<Values extends object> = FieldNameFor<Values, boolean>;
1289
+ /**
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
+ */
1299
+ export type ArrayFieldName<Values extends object> = {
1300
+ [Key in keyof Values & string]: Values[Key] extends ReadonlyArray<unknown> ? Key : never;
1301
+ }[keyof Values & string];
1302
+ /**
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
+ */
1312
+ export type ArrayFieldValue<Values extends object, Name extends ArrayFieldName<Values>> = Values[Name] extends ReadonlyArray<infer Value> ? Value : never;
1313
+ /**
1314
+ * Appends one item to an array field and marks it dirty and touched.
1315
+ * @remarks
1316
+ * ## Why
1317
+ * The immutable state transition is usable in tests, commands, or any renderer.
1318
+ * ## Ownership and lifetime
1319
+ * The returned Effect performs one RefSubject update when run.
1320
+ * @since 1.0.0
1321
+ * @category state
1322
+ */
1323
+ 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
+ /**
1325
+ * Removes one item by index from an array field and marks it dirty and touched.
1326
+ * @remarks
1327
+ * ## Why
1328
+ * The transition is explicit and renderer-independent; an out-of-range index leaves values unchanged.
1329
+ * ## Ownership and lifetime
1330
+ * The returned Effect performs one RefSubject update when run.
1331
+ * @since 1.0.0
1332
+ * @category state
1333
+ */
1334
+ 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
+ /**
1336
+ * Handler invoked only after whole-form Schema validation succeeds.
1337
+ * @remarks
1338
+ * ## Why
1339
+ * Callers receive decoded values and the real native SubmitEvent, and may return an Effect.
1340
+ * ## Ownership and lifetime
1341
+ * A returned Effect runs inside the form submit handler and completes before `submitting` resets.
1342
+ * @since 1.0.0
1343
+ * @category events
1344
+ */
1345
+ export type ValidSubmitHandler<Values extends object, E = never, R = never> = (values: Values, event: SubmitEvent) => void | Effect.Effect<unknown, E, R>;
1346
+ /**
1347
+ * Options for the state-explicit form root.
1348
+ * @remarks
1349
+ * ## Why
1350
+ * The form supplies native submit/reset behavior and Effect context while its
1351
+ * data remains in a standalone hydrated RefSubject.
1352
+ * ## Ownership and lifetime
1353
+ * The root Scope owns DOM handlers/content and provides `CurrentForm` to descendants.
1354
+ * It borrows `state`; submission Effects are finalized before `submitting` is cleared.
1355
+ * @since 1.0.0
1356
+ * @category component-options
1357
+ */
1358
+ export interface FormOptions<Values extends object, E = never, R = never> extends Dom.HostOptions<HTMLFormElement> {
1359
+ /** Hydrated renderer-independent state owned outside the form renderer. */
1360
+ readonly state: FormState<Values>;
1361
+ /** Controls and other renderable form content. */
1362
+ readonly content: Renderable.Any;
1363
+ /** Callback invoked with decoded values only after successful validation. */
1364
+ readonly onValidSubmit?: ValidSubmitHandler<Values, E, R>;
1365
+ }
1366
+ declare function formProps<const Values extends object, E, R, const Options extends FormOptions<Values, E, R>>(options: Options): () => {
1367
+ readonly ref: FormState<Values>;
1368
+ readonly onsubmit: EventHandler.EventHandler<SubmitEvent, E | Schema.SchemaError, R>;
1369
+ readonly onreset: EventHandler.EventHandler<Event, Schema.SchemaError, never>;
1370
+ };
1371
+ type FormProps<Values extends object, E, R, Options extends FormOptions<Values, E, R>> = ReturnType<ReturnType<typeof formProps<Values, E, R, Options>>>;
1372
+ /**
1373
+ * Renders a native form and provides its state to schema-bound descendants.
1374
+ * @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.
1383
+ * @example
1384
+ * ```ts
1385
+ * import { Form, Submit, TextInput, makeState } from "@typed/ui/Form"
1386
+ * import { Effect, Schema } from "effect"
1387
+ * import { html } from "@typed/template"
1388
+ *
1389
+ * const codec = Schema.Struct({ email: Schema.String })
1390
+ * const view = Effect.gen(function* () {
1391
+ * const state = yield* makeState(codec, { id: "signup", values: { email: "" } })
1392
+ * return Form({
1393
+ * state,
1394
+ * content: html`${TextInput({ state, name: "email" })}${Submit({ content: "Join" })}`,
1395
+ * onValidSubmit: (values) => Effect.log(`Submitting ${values.email}`)
1396
+ * })
1397
+ * })
1398
+ * ```
1399
+ * @since 1.0.0
1400
+ * @category components
1401
+ */
1402
+ 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
+ /**
1404
+ * Options accepted by a schema-bound form root.
1405
+ * @remarks
1406
+ * ## Why
1407
+ * The factory names the state `form` and supplies its schema/context automatically.
1408
+ * ## Ownership and lifetime
1409
+ * The root Scope borrows `form` and owns content, listeners, and submit Effects.
1410
+ * @since 1.0.0
1411
+ * @category component-options
1412
+ */
1413
+ 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. */
1415
+ readonly form: FormState<Values>;
1416
+ /** Schema-bound controls and other renderable form content. */
1417
+ readonly content: Renderable.Any;
1418
+ /** Callback invoked with decoded values only after successful validation. */
1419
+ readonly onValidSubmit?: ValidSubmitHandler<Values, E, R>;
1420
+ }
1421
+ type CurrentFormIdentifier = Context.Service.Identifier<typeof CurrentForm>;
1422
+ /**
1423
+ * Fx result of a schema-bound descendant control.
1424
+ * @remarks
1425
+ * ## Why
1426
+ * Its type makes `CurrentForm`, render services, Schema errors, Scope, and custom-host requirements explicit.
1427
+ * ## Ownership and lifetime
1428
+ * The parent form supplies `CurrentForm`; the running Scope owns DOM work.
1429
+ * @since 1.0.0
1430
+ * @category models
1431
+ */
1432
+ export type SchemaBoundComponentResult<Options, Host> = Fx<RenderEvent, Schema.SchemaError | Renderable.Error<RenderableComponentOptions<Options> | Host>, Renderable.Services<RenderableComponentOptions<Options> | Host> | CurrentFormIdentifier | Scope.Scope | RenderTemplate>;
1433
+ /**
1434
+ * Fx result of a schema-bound root after it provides `CurrentForm` internally.
1435
+ * @remarks
1436
+ * ## Why
1437
+ * Consumers see only external render/host requirements, not the service supplied by the root itself.
1438
+ * ## Ownership and lifetime
1439
+ * The running Scope owns the service provision, listeners, and rendered range.
1440
+ * @since 1.0.0
1441
+ * @category models
1442
+ */
1443
+ 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
+ /**
1445
+ * Callable schema-bound input constructor for fields with one decoded value type.
1446
+ * @remarks
1447
+ * ## Why
1448
+ * Struct field names, errors, and services remain inferred without passing state repeatedly.
1449
+ * ## Ownership and lifetime
1450
+ * Each call borrows `CurrentForm` and returns Scope-owned render work.
1451
+ * @since 1.0.0
1452
+ * @category models
1453
+ */
1454
+ 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 */
1456
+ <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
+ }
1458
+ /**
1459
+ * Callable schema-bound input using its selected field's string codec as a mask.
1460
+ * @remarks
1461
+ * ## Why
1462
+ * Structured string encodings stay declared once in the Struct schema.
1463
+ * ## Ownership and lifetime
1464
+ * Each call borrows `CurrentForm` and returns Scope-owned render work.
1465
+ * @since 1.0.0
1466
+ * @category models
1467
+ */
1468
+ 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 */
1470
+ <const Options extends object, const Host extends HostResult = never>(options: SchemaBoundMaskedInputOptions<Fields> & Options, host?: Dom.HostOverride<Dom.HostProps<HTMLInputElement>, "", Host>): SchemaBoundComponentResult<Options, Host>;
1471
+ }
1472
+ /**
1473
+ * Callable schema-bound checkbox constructor.
1474
+ * @remarks
1475
+ * ## Why
1476
+ * Only boolean field names are accepted and state comes from `CurrentForm`.
1477
+ * ## Ownership and lifetime
1478
+ * Each call returns Scope-owned DOM work and borrows the current form state.
1479
+ * @since 1.0.0
1480
+ * @category models
1481
+ */
1482
+ export interface SchemaBoundCheckbox<Values extends object> {
1483
+ /** Creates a bound native checkbox for a boolean field. @since 1.0.0 @category constructors */
1484
+ <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
+ }
1486
+ /**
1487
+ * Callable schema-bound native select constructor.
1488
+ * @remarks
1489
+ * ## Why
1490
+ * String field names are inferred while option content remains caller-authored.
1491
+ * ## Ownership and lifetime
1492
+ * Each call returns Scope-owned DOM/content work and borrows current form state.
1493
+ * @since 1.0.0
1494
+ * @category models
1495
+ */
1496
+ export interface SchemaBoundSelect<Values extends object> {
1497
+ /** Creates a bound native select and preserves caller-authored option content. @since 1.0.0 @category constructors */
1498
+ <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
+ }
1500
+ /**
1501
+ * Callable schema-bound field-error constructor.
1502
+ * @remarks
1503
+ * ## Why
1504
+ * Field error text and relationship IDs derive from the current form automatically.
1505
+ * ## Ownership and lifetime
1506
+ * Each call returns a Scope-owned subscription and borrows current form state.
1507
+ * @since 1.0.0
1508
+ * @category models
1509
+ */
1510
+ export interface SchemaBoundError<Values extends object> {
1511
+ /** Creates a bound alert region for one field's current error. @since 1.0.0 @category constructors */
1512
+ <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
+ }
1514
+ /**
1515
+ * Callable schema-bound reset-button constructor.
1516
+ * @remarks
1517
+ * ## Why
1518
+ * Reset behavior can access the current form without a state argument.
1519
+ * ## Ownership and lifetime
1520
+ * Each call returns Scope-owned DOM work and borrows current form state.
1521
+ * @since 1.0.0
1522
+ * @category models
1523
+ */
1524
+ export interface SchemaBoundReset {
1525
+ /** Creates a reset button targeting the form provided by `CurrentForm`. @since 1.0.0 @category constructors */
1526
+ <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
+ }
1528
+ /**
1529
+ * Callable schema-bound array append-button constructor.
1530
+ * @remarks
1531
+ * ## Why
1532
+ * Field and item types are derived from the form value.
1533
+ * ## Ownership and lifetime
1534
+ * Each call returns Scope-owned DOM work and borrows current form state.
1535
+ * @since 1.0.0
1536
+ * @category models
1537
+ */
1538
+ 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 */
1540
+ <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
+ }
1542
+ /**
1543
+ * Callable schema-bound array removal-button constructor.
1544
+ * @remarks
1545
+ * ## Why
1546
+ * Array fields remain type-checked without passing state explicitly.
1547
+ * ## Ownership and lifetime
1548
+ * Each call returns Scope-owned DOM work and borrows current form state.
1549
+ * @since 1.0.0
1550
+ * @category models
1551
+ */
1552
+ 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 */
1554
+ <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
+ }
1556
+ /**
1557
+ * Callable root constructor supplied by a schema-bound form API.
1558
+ * @remarks
1559
+ * ## Why
1560
+ * It connects one factory-created state to native form behavior and descendant context.
1561
+ * ## Ownership and lifetime
1562
+ * The returned Fx provides `CurrentForm` for its own Scope and borrows the state.
1563
+ * @since 1.0.0
1564
+ * @category models
1565
+ */
1566
+ 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 */
1568
+ <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
+ }
1570
+ /**
1571
+ * Optional state metadata for `SchemaBoundForm.state`.
1572
+ * @remarks
1573
+ * ## Why
1574
+ * Callers may seed SSR identity, defaults, errors, and interaction/submission state.
1575
+ * ## Ownership and lifetime
1576
+ * Values/defaults and nested references are retained exactly; provide `id` for
1577
+ * deterministic SSR identity.
1578
+ * @since 1.0.0
1579
+ * @category models
1580
+ */
1581
+ export interface SchemaBoundStateOptions<Values extends object> {
1582
+ /** Stable hydration and accessibility relationship ID; required for deterministic SSR ordering. */
1583
+ readonly id?: string;
1584
+ /** Exact reset-baseline reference, defaulting to the same object passed as initial values. */
1585
+ readonly defaultValues?: Values;
1586
+ /** Initial field validation messages. */
1587
+ readonly errors?: Partial<Record<keyof Values & string, string>>;
1588
+ /** Initial dirty/touched metadata. */
1589
+ readonly meta?: Partial<Record<keyof Values & string, FieldMeta>>;
1590
+ /** Initial in-flight submission flag. */
1591
+ readonly submitting?: boolean;
1592
+ }
1593
+ /**
1594
+ * Schema-specialized form API returned by `make`.
1595
+ * @remarks
1596
+ * ## Why
1597
+ * The Struct codec is declared once, then every state, field name, component,
1598
+ * error, and custom-host signature stays aligned with it.
1599
+ * ## Ownership and lifetime
1600
+ * The API retains the codec but acquires no Scope. Each `state` call creates a
1601
+ * Scope-owned hydrated RefSubject; each component call creates lazy Fx output.
1602
+ * @since 1.0.0
1603
+ * @category models
1604
+ */
1605
+ export interface SchemaBoundForm<Fields extends FormFields> {
1606
+ /** Struct codec shared by state construction and every bound field. */
1607
+ readonly codec: Schema.Struct<Fields>;
1608
+ /** Creates a Scope-owned hydrated state from decoded initial values. */
1609
+ 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. */
1611
+ readonly Root: SchemaBoundRoot<Schema.Struct.Type<Fields>>;
1612
+ /** Bound native text input for string-encoded string fields. */
1613
+ readonly TextInput: SchemaBoundInput<Fields, string>;
1614
+ /** Bound native search input for string-encoded string fields. */
1615
+ readonly SearchInput: SchemaBoundInput<Fields, string>;
1616
+ /** Bound native email input for string-encoded string fields. */
1617
+ readonly EmailInput: SchemaBoundInput<Fields, string>;
1618
+ /** Bound native URL input for string-encoded string fields. */
1619
+ readonly UrlInput: SchemaBoundInput<Fields, string>;
1620
+ /** Bound native telephone input for string-encoded string fields. */
1621
+ readonly TelInput: SchemaBoundInput<Fields, string>;
1622
+ /** Bound native password input for string-encoded string fields. */
1623
+ readonly PasswordInput: SchemaBoundInput<Fields, string>;
1624
+ /** Bound native hidden input for string-encoded string fields. */
1625
+ readonly HiddenInput: SchemaBoundInput<Fields, string>;
1626
+ /** Bound native color input for string-encoded string fields. */
1627
+ readonly ColorInput: SchemaBoundInput<Fields, string>;
1628
+ /** Bound native time input for string-encoded string fields. */
1629
+ readonly TimeInput: SchemaBoundInput<Fields, string>;
1630
+ /** Bound native local date-time input for string-encoded string fields. */
1631
+ readonly DateTimeLocalInput: SchemaBoundInput<Fields, string>;
1632
+ /** Bound native month input for string-encoded string fields. */
1633
+ readonly MonthInput: SchemaBoundInput<Fields, string>;
1634
+ /** Bound native week input for string-encoded string fields. */
1635
+ readonly WeekInput: SchemaBoundInput<Fields, string>;
1636
+ /** Bound native number input for finite-number fields encoded as strings. */
1637
+ readonly NumberInput: SchemaBoundInput<Fields, number>;
1638
+ /** Bound native range input for finite-number fields encoded as strings. */
1639
+ readonly RangeInput: SchemaBoundInput<Fields, number>;
1640
+ /** Bound native date input for Date fields encoded as strings. */
1641
+ readonly DateInput: SchemaBoundInput<Fields, Date>;
1642
+ /** Bound text input using the selected field's own string codec. */
1643
+ readonly MaskedInput: SchemaBoundMaskedInput<Fields>;
1644
+ /** Bound native checkbox limited to boolean fields. */
1645
+ readonly Checkbox: SchemaBoundCheckbox<Schema.Struct.Type<Fields>>;
1646
+ /** Bound native select limited to string fields. */
1647
+ readonly Select: SchemaBoundSelect<Schema.Struct.Type<Fields>>;
1648
+ /** Bound ARIA alert for a field's current validation message. */
1649
+ readonly Error: SchemaBoundError<Schema.Struct.Type<Fields>>;
1650
+ /** Bound reset button that restores the current form's defaults. */
1651
+ readonly Reset: SchemaBoundReset;
1652
+ /** Bound button that appends to an array field. */
1653
+ readonly Push: SchemaBoundPush<Schema.Struct.Type<Fields>>;
1654
+ /** Bound button that removes an item from an array field. */
1655
+ readonly Remove: SchemaBoundRemove<Schema.Struct.Type<Fields>>;
1656
+ /** Native label component; callers provide the target control ID. */
1657
+ readonly Label: typeof Label;
1658
+ /** Neutral description host for caller-linked explanatory content. */
1659
+ readonly Description: typeof Description;
1660
+ /** Native submit button. */
1661
+ readonly Submit: typeof Submit;
1662
+ /** Accessible group host for related controls. */
1663
+ readonly Group: typeof Group;
1664
+ }
1665
+ /**
1666
+ * Creates a schema-bound form component family from one Struct codec.
1667
+ * @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.
1675
+ * @example
1676
+ * ```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({
1685
+ * form,
1686
+ * content: html`${Signup.EmailInput({ name: "email" })}${Signup.Checkbox({ name: "accepted" })}`
1687
+ * })
1688
+ * })
1689
+ * ```
1690
+ * @since 1.0.0
1691
+ * @category constructors
1692
+ */
1693
+ export declare function make<const Fields extends FormFields>(codec: Schema.Struct<Fields>): SchemaBoundForm<Fields>;
1694
+ export {};
1695
+ //# sourceMappingURL=Form.d.ts.map