@typed/ui 1.0.0-beta.0 → 1.0.0-beta.10

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