fluid-primitives 0.19.1 → 1.0.0-beta.1

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 (67) hide show
  1. package/README.md +9 -0
  2. package/dist/Client-HrMIqv7d.js +1934 -0
  3. package/dist/accordion.d.ts +2 -2
  4. package/dist/accordion.js +25 -29
  5. package/dist/button.d.ts +52 -0
  6. package/dist/button.js +135 -0
  7. package/dist/checkbox-group.d.ts +6 -5
  8. package/dist/checkbox-group.js +36 -20
  9. package/dist/{checkbox-group.registry-CGwuF7SF.js → checkbox-group.registry-D8P8A4LY.js} +13 -8
  10. package/dist/checkbox.d.ts +18 -4
  11. package/dist/checkbox.js +30 -27
  12. package/dist/client.d.ts +2 -2
  13. package/dist/client.js +2 -2
  14. package/dist/clipboard.d.ts +12 -5
  15. package/dist/clipboard.js +14 -16
  16. package/dist/collapsible.d.ts +3 -3
  17. package/dist/collapsible.js +13 -17
  18. package/dist/combobox.d.ts +37 -0
  19. package/dist/combobox.js +151 -0
  20. package/dist/date-picker.d.ts +67 -0
  21. package/dist/date-picker.js +289 -0
  22. package/dist/dialog.d.ts +3 -3
  23. package/dist/dialog.js +11 -12
  24. package/dist/field-array.d.ts +97 -0
  25. package/dist/field-array.js +223 -0
  26. package/dist/field.d.ts +30 -54
  27. package/dist/field.js +589 -175
  28. package/dist/fieldset.d.ts +15 -0
  29. package/dist/fieldset.js +27 -0
  30. package/dist/file-upload.d.ts +85 -0
  31. package/dist/file-upload.js +255 -0
  32. package/dist/form.d.ts +2 -83
  33. package/dist/form.fields-B58TZukv.js +329 -0
  34. package/dist/form.js +263 -276
  35. package/dist/index-B06gIN_k.d.ts +1358 -0
  36. package/dist/input.d.ts +96 -0
  37. package/dist/input.js +233 -0
  38. package/dist/menu.d.ts +55 -0
  39. package/dist/menu.js +144 -0
  40. package/dist/navigation-menu.d.ts +3 -3
  41. package/dist/navigation-menu.js +29 -43
  42. package/dist/number-input.d.ts +13 -4
  43. package/dist/number-input.js +30 -31
  44. package/dist/popover.d.ts +11 -3
  45. package/dist/popover.js +17 -18
  46. package/dist/radio-group.d.ts +4 -4
  47. package/dist/radio-group.js +35 -42
  48. package/dist/scroll-area.d.ts +3 -3
  49. package/dist/scroll-area.js +10 -9
  50. package/dist/select.d.ts +13 -51
  51. package/dist/select.js +62 -55
  52. package/dist/slider.d.ts +27 -0
  53. package/dist/slider.js +71 -0
  54. package/dist/switch.d.ts +4 -4
  55. package/dist/switch.js +24 -33
  56. package/dist/tabs.d.ts +3 -3
  57. package/dist/tabs.js +12 -15
  58. package/dist/textarea.d.ts +101 -0
  59. package/dist/textarea.js +231 -0
  60. package/dist/tooltip.d.ts +11 -3
  61. package/dist/tooltip.js +11 -10
  62. package/package.json +79 -24
  63. package/dist/Client-C51NSHxg.js +0 -248
  64. package/dist/field.dom-CJQXpQbZ.js +0 -11
  65. package/dist/form.registry-Cb8Pvoe8.d.ts +0 -7
  66. package/dist/form.registry-CmpTny_s.js +0 -51
  67. package/dist/index-B8JCdyld.d.ts +0 -118
@@ -0,0 +1,1358 @@
1
+ import * as asyncList from "@zag-js/async-list";
2
+ import { Attrs, VanillaMachine, mergeProps, normalizeProps as normalizeProps$1, spreadProps } from "@zag-js/vanilla";
3
+ import { CollectionItem, ListCollection } from "@zag-js/collection";
4
+ import { EventObject, InputProps, Machine, MachineSchema } from "@zag-js/core";
5
+ import { CommonProperties, DirectionProperty, JSX, PropTypes } from "@zag-js/types";
6
+
7
+ //#region Resources/Private/Client/src/lib/async-list.d.ts
8
+ /** The options of an {@link AsyncList}: the props of the `@zag-js/async-list` machine. */
9
+ type AsyncListOptions<T, Filter = string, Sorting = asyncList.SortDescriptor<T>, Cursor = string> = asyncList.Props<T, Filter, Sorting, Cursor>;
10
+ /**
11
+ * Wraps the machine of `@zag-js/async-list` for use without any DOM or hydration: construct it, call
12
+ * `init()`, `subscribe()` to state changes and `destroy()` when done. Rendering is yours, do it from
13
+ * inside `subscribe()`.
14
+ *
15
+ * Debouncing or throttling `setFilter()` is left to the caller, wrap the call site with the
16
+ * `debounce` or `throttle` of `@zag-js/utils`, which this library already depends on.
17
+ */
18
+ declare class AsyncList<T, Filter = string, Sorting = asyncList.SortDescriptor<T>, Cursor = string> {
19
+ private machine;
20
+ constructor(options: AsyncListOptions<T, Filter, Sorting, Cursor>);
21
+ /** The api of the current state of the list. It is read fresh on every access, don't hold on to it. */
22
+ get api(): asyncList.Api<T, Filter, Sorting, Cursor>;
23
+ /**
24
+ * Calls `fn` with the api on every future state change. It does not fire for the current state,
25
+ * read `api` first if you need it.
26
+ *
27
+ * @param fn - The listener.
28
+ * @returns A function that removes the listener.
29
+ */
30
+ subscribe(fn: (api: asyncList.Api<T, Filter, Sorting, Cursor>) => void): () => void;
31
+ /** Sets the filter and reloads the list with it. */
32
+ setFilter(filter: Filter): void;
33
+ /**
34
+ * Changes options at runtime, e.g. `dependencies` to trigger an `autoReload`. `load` is fixed
35
+ * when the list is constructed and can't be swapped here.
36
+ */
37
+ updateProps(newProps: Partial<Omit<asyncList.Props<T, Filter, Sorting, Cursor>, 'load'>>): void;
38
+ /** Starts the machine, which loads the list for the first time. Call it once, after constructing. */
39
+ init(): void;
40
+ /** Stops the machine and cancels a load that is in flight. */
41
+ destroy(): void;
42
+ }
43
+ //#endregion
44
+ //#region Resources/Private/Client/src/lib/client-prop-converters.d.ts
45
+ /**
46
+ * Converts a prop from the shape it has on the wire (JSON) to the one the component needs. It gets
47
+ * the wire value and all props of the component.
48
+ */
49
+ type ClientPropConverter<TWire = unknown, TMachine = unknown> = (wireValue: TWire, props: Record<string, unknown>) => TMachine;
50
+ /** The converters of one component, by prop name. */
51
+ type ClientPropConverterMap = Record<string, ClientPropConverter<any, any>>;
52
+ /**
53
+ * The shape each prop of a converters object has after conversion. Use it for the
54
+ * `HydrationPropsOverrides` of a component, derived from the converters with `typeof` instead of
55
+ * typed a second time.
56
+ */
57
+ type ConverterMachineProps<T extends ClientPropConverterMap> = { [K in keyof T]: T[K] extends ClientPropConverter<any, infer TMachine> ? TMachine : never };
58
+ /**
59
+ * Registers which props of a component need converting before a `mountAll()` or `mount()` callback
60
+ * receives them, e.g. the `collection` of a Select: JSON on the wire, a `ListCollection` once
61
+ * converted.
62
+ *
63
+ * @param componentName - The component, e.g. `select`.
64
+ * @param propConverters - The converters, by prop name.
65
+ */
66
+ declare function registerClientPropConverters<T extends ClientPropConverterMap>(componentName: string, propConverters: T): void;
67
+ /**
68
+ * @internal
69
+ *
70
+ * Runs every registered converter for `componentName` against `props`, called for every
71
+ * registered key regardless of whether it's actually present on `props` - a converter is
72
+ * registered per prop *name*, not per wire value, so it can supply a default for a prop the wire
73
+ * data omitted entirely (e.g. Combobox's `collection` when a purely async, searchUrl-only combobox
74
+ * sends none).
75
+ */
76
+ declare function applyClientPropConverters(componentName: string, props: Record<string, unknown>): Record<string, unknown>;
77
+ //#endregion
78
+ //#region Resources/Private/Client/src/types.d.ts
79
+ declare global {
80
+ interface Window {
81
+ FluidPrimitives: {
82
+ /**
83
+ * Nested by Fluid namespace identifier first (e.g. "ui"/"primitives" - the same prefix
84
+ * a `mountAll`/`mount` call must use, see `parseNamespacedComponentName`), then by the
85
+ * bare component name, then by rootId - never a flat `"ui:select"`-string-keyed map.
86
+ * Two collections can legitimately register a same-named component with a different
87
+ * shape (a styled wrapper around a primitive it doesn't expose every prop of), and
88
+ * nesting by namespace first keeps those genuinely separate.
89
+ */
90
+ hydrationData: {
91
+ [namespace: string]: {
92
+ [componentName: string]: {
93
+ [id: string]: ComponentHydrationData;
94
+ };
95
+ };
96
+ };
97
+ globals?: FluidPrimitivesGlobals;
98
+ /**
99
+ * Every component instance `mountAll`/`mount` has created, nested the same way as
100
+ * `hydrationData` above - populated by both, so `getComponentInstance` can find a
101
+ * component that was mounted by hand with `mount` too.
102
+ */
103
+ componentInstances: {
104
+ [namespace: string]: {
105
+ [componentName: string]: {
106
+ [id: string]: Component<unknown, unknown>;
107
+ };
108
+ };
109
+ };
110
+ /**
111
+ * Root components PHP found nested inside a tracked scope - a `ui:template` stencil, or
112
+ * a FieldArray row - keyed by that scope's own id (see
113
+ * `HydrationRegistry::recordNestedComponent()`'s own docblock for why this exists rather
114
+ * than inferring nesting from rendered DOM shape). Read via
115
+ * {@see getNestedComponents}, not indexed directly.
116
+ */
117
+ nestedComponents?: {
118
+ [scopeId: string]: NestedComponentEntry[];
119
+ };
120
+ };
121
+ }
122
+ }
123
+ /** @internal */
124
+ interface NestedComponentEntry {
125
+ /**
126
+ * The nested component's own hydration registry key, "namespace:clientBaseName" (e.g.
127
+ * "primitives:field") - a single opaque, round-tripped string, never parsed/indexed as an
128
+ * object path the way `hydrationData`/`componentInstances` are.
129
+ */
130
+ name: string;
131
+ /** Its bare rootId - the same form `ComponentHydrator`'s own `rootId` uses, no namespace prefix. */
132
+ id: string;
133
+ }
134
+ /** @internal */
135
+ interface ComponentInterface<Api> {
136
+ document: Document;
137
+ machine: VanillaMachine<any>;
138
+ api: Api;
139
+ hydrator: ComponentHydrator;
140
+ init(): void;
141
+ destroy(): void;
142
+ render(): void;
143
+ }
144
+ /** The hydration entry of one component instance, as PHP renders it for `mountAll()` and `mount()`. */
145
+ interface ComponentHydrationData {
146
+ /** Whether the instance mounts on its own: `false` when it was rendered with `autoMount="{false}"`. */
147
+ autoMount: boolean;
148
+ /** The props of the instance. Typed per component by `HydrationPropsRegistry`. */
149
+ props: {
150
+ id: string;
151
+ ids: {
152
+ [key: string]: string;
153
+ };
154
+ [key: string]: unknown;
155
+ };
156
+ }
157
+ /**
158
+ * Types the `props` of `mountAll()` and `mount()` per component. It is empty on purpose: a project
159
+ * fills it with its own generated types, keyed by the namespaced name used at the call site.
160
+ * A component that is not in it gets the untyped `props` of `ComponentHydrationData`.
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * declare module 'fluid-primitives' {
165
+ * interface HydrationPropsRegistry {
166
+ * 'ui:select': SelectHydrationProps;
167
+ * }
168
+ * }
169
+ * ```
170
+ */
171
+ interface HydrationPropsRegistry {}
172
+ /**
173
+ * Overrides the type of the props whose shape changes through a registered client prop converter,
174
+ * for example the `collection` of a Select: JSON on the wire, a `ListCollection` once converted.
175
+ * It is keyed by the bare component name. Derive each entry from the converters with
176
+ * `ConverterMachineProps` instead of typing it by hand.
177
+ */
178
+ interface HydrationPropsOverrides {}
179
+ /** @internal */
180
+ type KnownComponentName = Extract<keyof HydrationPropsRegistry, string>;
181
+ /**
182
+ * `K` with any `"namespace:"` prefix stripped (e.g. `"ui:select"` -> `"select"`) - converters (see
183
+ * `client-prop-converters.ts`) are registered once per TS class under its own bare name,
184
+ * independent of which namespace ends up mounting it, so {@see HydrationPropsOverrides} stays
185
+ * bare-keyed even though {@see HydrationPropsRegistry} itself is namespaced.
186
+ */
187
+ type BareComponentName<K extends string> = K extends `${string}:${infer BaseName}` ? BaseName : K;
188
+ type PickOverride<K extends string> = BareComponentName<K> extends keyof HydrationPropsOverrides ? HydrationPropsOverrides[BareComponentName<K>] : object;
189
+ /**
190
+ * The `props` type of the callback of `mountAll()` and `mount()` for the component name `K`: its
191
+ * entry in `HydrationPropsRegistry`, with the props that have a converter replaced by their
192
+ * `HydrationPropsOverrides`. A name that is not in the registry gets the untyped props.
193
+ */
194
+ type HydrationPropsFor<K extends string> = K extends keyof HydrationPropsRegistry ? Omit<HydrationPropsRegistry[K], keyof PickOverride<K>> & PickOverride<K> : ComponentHydrationData['props'];
195
+ /** @internal */
196
+ interface FluidPrimitivesGlobals {
197
+ locale?: string;
198
+ /**
199
+ * Enables dev-only checks. Set automatically to whether
200
+ * TYPO3's own Application Context is development (see `HydrationRegistry::resolveGlobals()`),
201
+ * nothing for a consumer to configure. These checks aren't gated by a bundler env variable, so
202
+ * nothing is stripped from the production bundle either way - they simply never run unless
203
+ * this is true.
204
+ */
205
+ debug?: boolean;
206
+ [key: string]: unknown;
207
+ }
208
+ //#endregion
209
+ //#region Resources/Private/Client/src/lib/component.d.ts
210
+ /**
211
+ * Base class of every primitive. A subclass builds its machine in `initMachine()`, connects it in
212
+ * `initApi()` and spreads the props of its parts onto the DOM in `render()`. Call `init()` once to
213
+ * start it.
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * class Counter extends Component<CounterProps, CounterApi> {
218
+ * static componentName = 'counter';
219
+ *
220
+ * initMachine(props: CounterProps) {
221
+ * return new Machine(counter.machine, props);
222
+ * }
223
+ *
224
+ * initApi() {
225
+ * return counter.connect(this.machine.service, normalizeProps);
226
+ * }
227
+ *
228
+ * render() {
229
+ * const rootEl = this.hydrator.query('root');
230
+ * if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
231
+ * }
232
+ * }
233
+ * ```
234
+ */
235
+ declare abstract class Component<Props, Api> implements ComponentInterface<Api> {
236
+ #private;
237
+ private readonly initialProps;
238
+ /** The document the component renders into. */
239
+ document: Document;
240
+ /**
241
+ * The Fluid namespace identifier (e.g. "ui") this instance was mounted under - assigned by
242
+ * `mountAll`/`mount` right after their callback returns, so not yet available while it runs
243
+ * (`init()` included).
244
+ */
245
+ namespace?: string;
246
+ /** The name of the component, in camelCase. Every subclass has to set it. */
247
+ static componentName: string;
248
+ /** Alias of `document`. */
249
+ get doc(): Document;
250
+ constructor(initialProps: Props, userDocument?: Document);
251
+ /** Created by {@see init} - reading it earlier throws. */
252
+ get machine(): Machine$1<any>;
253
+ /** Created by {@see init} - reading it earlier throws. */
254
+ get api(): Api;
255
+ protected set api(api: Api);
256
+ /**
257
+ * Finds the component's parts by name, see {@see ComponentHydrator.query}. Created by
258
+ * {@see init} - reading it earlier throws.
259
+ */
260
+ get hydrator(): ComponentHydrator;
261
+ /**
262
+ * The props the instance runs on - what {@see transformProps} made of the ones it was created
263
+ * with. Created by {@see init} - reading it earlier throws.
264
+ */
265
+ get userProps(): Props;
266
+ /** Creates the machine from the props. Called once by `init()`. */
267
+ abstract initMachine(props: Props): Machine$1<any>;
268
+ /** Connects the machine to its api. Called by `init()` and again after every state change. */
269
+ abstract initApi(): Api;
270
+ /** Creates the hydrator that finds the parts of the component. It needs the `id` prop. */
271
+ initHydrator(props: Props): ComponentHydrator;
272
+ /**
273
+ * Builds everything the instance runs on - `userProps`, hydrator, machine and api - then renders
274
+ * once and starts the machine. Call it once after constructing.
275
+ */
276
+ init(): void;
277
+ /**
278
+ * Renders again with no prop change behind it. Use it after changing the DOM directly, e.g.
279
+ * after inserting a new `Template` instance, for a primitive with no prop that causes a render on
280
+ * its own. Combobox and Select don't need it: `updateProps({ collection })` already renders.
281
+ */
282
+ refresh(): void;
283
+ /** The `componentName` of the class. */
284
+ getName(): string;
285
+ /**
286
+ * Kebab form of {@see getName} - what actually appears in DOM-facing identifiers (part attribute
287
+ * names, hydration keys). See {@see ComponentHydrator.clientComponentName}.
288
+ */
289
+ getClientName(): string;
290
+ /**
291
+ * Override to adjust the props before anything else sees them, e.g. to wrap a callback prop.
292
+ * Runs once, first in {@see init}: the result becomes `userProps`, which `initHydrator()` and
293
+ * `initMachine()` receive.
294
+ */
295
+ transformProps(props: Props): Props;
296
+ /**
297
+ * Another already-mounted instance of this same component, by root id - for a primitive that
298
+ * composes two independent instances of itself (Menu submenus). Only resolves once
299
+ * `mountAll`/`mount` assigned {@see namespace}.
300
+ */
301
+ protected getPeerInstance<T extends Component<any, any>>(rootId: string): T | undefined;
302
+ /** Changes props at runtime. Only the ones you pass change, the others stay. */
303
+ updateProps(newProps: Partial<Props>): void;
304
+ /** Stops the machine and releases the hydrator. */
305
+ destroy(): void;
306
+ /** Applies the attributes and event handlers of a part's props to its element. */
307
+ spreadProps(node: HTMLElement, attrs: Attrs): void;
308
+ /** {@see spreadTextControlProps}: for a text control that mirrors what the user typed. */
309
+ spreadTextControlProps(node: HTMLInputElement | HTMLTextAreaElement, attrs: Attrs): void;
310
+ /**
311
+ * For every element matching `part`, reads its own `data-value` and hands `{el, value}` to
312
+ * `getProps`; if it returns a props object, spreads it onto that element via `spreadProps`.
313
+ * Returning `null`/`undefined` skips the element (e.g. a value that no longer resolves
314
+ * against a collection). Deliberately does not read any other attribute
315
+ * (disabled/invalid/current/...) or resolve a collection itself - callers read whatever flags
316
+ * they need off `el` and do their own value resolution, since both vary per primitive.
317
+ */
318
+ protected spreadPropsByValue(part: string, getProps: (ctx: {
319
+ el: HTMLElement;
320
+ value: string;
321
+ }) => Attrs | null | undefined, options?: {
322
+ parent?: HTMLElement | Document;
323
+ }): void;
324
+ protected spreadPropsByOptionalValue(part: string, getProps: (ctx: {
325
+ el: HTMLElement;
326
+ value?: string;
327
+ }) => Attrs | null | undefined, options?: {
328
+ parent?: HTMLElement | Document;
329
+ }): void;
330
+ /** Spreads the props of every part onto its element. Called after every state change. */
331
+ abstract render(): void;
332
+ }
333
+ //#endregion
334
+ //#region Resources/Private/Client/src/lib/delayed-indicator.d.ts
335
+ /** The options of a {@link DelayedIndicator}. */
336
+ interface DelayedIndicatorOptions<T> {
337
+ /**
338
+ * How long a transient value must persist before it is shown at all. Must be finite and >= 0.
339
+ * @default 150
340
+ */
341
+ showDelayMs?: number;
342
+ /**
343
+ * Once shown, how long a transient value stays current before a settled value can replace it.
344
+ * Must be finite and >= 0.
345
+ * @default 300
346
+ */
347
+ minVisibleMs?: number;
348
+ /**
349
+ * Marks which values are transient, e.g. a loading state. Every other value is treated as settled
350
+ * and passes through immediately once no transient value is held.
351
+ */
352
+ isTransient: (value: T) => boolean;
353
+ /** Called with each value once it is ready to be shown. */
354
+ onChange: (value: T) => void;
355
+ }
356
+ /**
357
+ * Delays showing a transient value long enough to avoid flicker, and keeps it visible for a minimum
358
+ * duration once shown. Feed it every new value through `set()`, typically straight from a subscribe
359
+ * callback, and it forwards them to `onChange`. The values `isTransient` marks are held back for
360
+ * `showDelayMs`, so a fast operation never flashes them. Once shown they stay for at least
361
+ * `minVisibleMs`, so they can't vanish the instant they appeared.
362
+ *
363
+ * It works on any value, not only a boolean: one instance can drive a spinner and a status text
364
+ * from the same source, so they never disagree.
365
+ */
366
+ declare class DelayedIndicator<T> {
367
+ private readonly showDelayMs;
368
+ private readonly minVisibleMs;
369
+ private readonly isTransient;
370
+ private readonly onChange;
371
+ private phase;
372
+ private latestValue;
373
+ private timer;
374
+ private shownAt;
375
+ constructor(options: DelayedIndicatorOptions<T>);
376
+ /**
377
+ * Passes a new value on, delayed as described above. It does not deduplicate: the same value
378
+ * again can still call `onChange` again, as this filters state over time, it is not a
379
+ * `distinctUntilChanged()`.
380
+ *
381
+ * @param value - The new value.
382
+ */
383
+ set(value: T): void;
384
+ /**
385
+ * Cancels any timer that is running. Call it when the indicator is no longer needed, e.g. on
386
+ * teardown: otherwise a scheduled value can still reach `onChange` afterwards. It is safe to call
387
+ * when nothing is transient or shown.
388
+ */
389
+ destroy(): void;
390
+ }
391
+ //#endregion
392
+ //#region Resources/Private/Client/src/lib/extbase.d.ts
393
+ /**
394
+ * Reads the Extbase argument namespace (`tx_docs_docs`) of a frontend action URL, from its
395
+ * `[controller]` or `[action]` query key. `UriBuilder::uriFor()` nests those under it, also for a
396
+ * custom `pluginNamespace`.
397
+ *
398
+ * @param url - The URL of the action.
399
+ * @returns The namespace, or `null` for a URL without such a key.
400
+ */
401
+ declare function getArgumentPrefix(url: string): string | null;
402
+ /**
403
+ * Sends GET and POST requests to an Extbase controller action from your own code, e.g. from the
404
+ * `load` callback of an async search. The data is nested under the Extbase argument namespace of the
405
+ * URL, the way `f:uri.action` builds it.
406
+ */
407
+ declare const extbase: {
408
+ /**
409
+ * GETs `url` with `data` appended as query parameters under its Extbase argument namespace. The
410
+ * URL's own query, `cHash` included, is kept - so the new parameters have to be listed in
411
+ * `FE.cacheHash.excludedParameters`, or TYPO3 rejects the request.
412
+ *
413
+ * @param url - The URL of the action, absolute or relative.
414
+ * @param data - The arguments. Nested objects and arrays are flattened into bracket notation.
415
+ * @param init - More options for `fetch`, e.g. `{ signal }`.
416
+ * @returns The native `Response`. A non-2xx status resolves normally, check `response.ok`.
417
+ */
418
+ get(url: string, data?: Record<string, unknown>, init?: RequestInit): Promise<Response>;
419
+ /**
420
+ * POSTs `data` as `multipart/form-data`, nested under the URL's Extbase argument namespace. A
421
+ * URL without one gets `data` unprefixed.
422
+ *
423
+ * @param url - The URL of the action.
424
+ * @param data - The arguments. Nested objects and arrays are flattened into bracket notation, `null`
425
+ * and `undefined` are skipped, a `File` or `Blob` is sent as it is.
426
+ * @param init - More options for `fetch`, e.g. `{ signal }`.
427
+ * @returns The native `Response`. A non-2xx status resolves normally, check `response.ok`.
428
+ */
429
+ post(url: string, data?: Record<string, unknown>, init?: RequestInit): Promise<Response>;
430
+ getArgumentPrefix: typeof getArgumentPrefix;
431
+ };
432
+ //#endregion
433
+ //#region Resources/Private/Primitives/Field/src/field.types.d.ts
434
+ /**
435
+ * A plain-object snapshot of the control's native `ValidityState`.
436
+ * The live DOM object is never exposed — its getters change under the framework's feet.
437
+ */
438
+ interface ValiditySnapshot {
439
+ badInput: boolean;
440
+ customError: boolean;
441
+ patternMismatch: boolean;
442
+ rangeOverflow: boolean;
443
+ rangeUnderflow: boolean;
444
+ stepMismatch: boolean;
445
+ tooLong: boolean;
446
+ tooShort: boolean;
447
+ typeMismatch: boolean;
448
+ valueMissing: boolean;
449
+ valid: boolean;
450
+ }
451
+ type ValidityMatch = Exclude<keyof ValiditySnapshot, 'valid'>;
452
+ interface ValidateDetails {
453
+ /**
454
+ * The current value of the control.
455
+ */
456
+ value: string;
457
+ /**
458
+ * Snapshot of the control's native validity, taken before custom validation runs.
459
+ */
460
+ validity: ValiditySnapshot;
461
+ }
462
+ /**
463
+ * Return a string or list of strings to mark the field invalid; anything else means valid.
464
+ */
465
+ type ValidateResult = string | string[] | null | undefined | void;
466
+ interface ValidityChangeDetails {
467
+ valid: boolean;
468
+ errors: string[];
469
+ validity: ValiditySnapshot;
470
+ value: string;
471
+ }
472
+ /**
473
+ * When validation is committed (made visible):
474
+ * - `onSubmit`: on form submission — behaves like `onChange` after the first submit attempt
475
+ * - `onBlur`: when the control loses focus
476
+ * - `onChange`: on every change
477
+ */
478
+ type ValidationMode = 'onSubmit' | 'onBlur' | 'onChange';
479
+ type ElementIds = Partial<{
480
+ root: string;
481
+ control: string;
482
+ label: string;
483
+ errorText: string;
484
+ helperText: string;
485
+ }>;
486
+ interface FieldProps extends DirectionProperty, CommonProperties {
487
+ /**
488
+ * The name of the field. It keys the field in its form and is what the field's value is read by.
489
+ */
490
+ name: string;
491
+ /**
492
+ * The initial value, used while the DOM holds no control for this name yet.
493
+ */
494
+ defaultValue?: unknown;
495
+ /**
496
+ * Names of sibling fields in the same form whose value changes this field reacts to.
497
+ */
498
+ listenTo?: string[] | undefined;
499
+ /**
500
+ * The ids of the elements. Useful for composition.
501
+ */
502
+ ids?: ElementIds | undefined;
503
+ /**
504
+ * Whether the field is disabled. Also inherited from a surrounding native `<fieldset disabled>`.
505
+ * @default false
506
+ */
507
+ disabled?: boolean | undefined;
508
+ /**
509
+ * Whether the field is invalid, regardless of computed validity.
510
+ * Use for app-level errors (e.g. server errors) the machine cannot compute itself.
511
+ */
512
+ invalid?: boolean | undefined;
513
+ /**
514
+ * Whether the field's value has been changed from its initial value.
515
+ * Useful when the field state is controlled by an external library.
516
+ */
517
+ dirty?: boolean | undefined;
518
+ /**
519
+ * Whether the field has been touched.
520
+ * Useful when the field state is controlled by an external library.
521
+ */
522
+ touched?: boolean | undefined;
523
+ /**
524
+ * Whether the field is read-only.
525
+ * @default false
526
+ */
527
+ readOnly?: boolean | undefined;
528
+ /**
529
+ * Whether the field is required.
530
+ * @default false
531
+ */
532
+ required?: boolean | undefined;
533
+ /**
534
+ * Custom validation, run against the value and the native validity snapshot.
535
+ * May return a promise; a newer validation run supersedes an in-flight one.
536
+ */
537
+ validate?: ((details: ValidateDetails) => ValidateResult | Promise<ValidateResult>) | undefined;
538
+ /**
539
+ * When validation results become visible.
540
+ * @default "onBlur"
541
+ */
542
+ validationMode?: ValidationMode | undefined;
543
+ /**
544
+ * Called when the committed validity changes.
545
+ */
546
+ onValidityChange?: ((details: ValidityChangeDetails) => void) | undefined;
547
+ }
548
+ type PropsWithDefault = 'disabled' | 'readOnly' | 'required' | 'validationMode';
549
+ interface FieldSchema {
550
+ state: 'idle';
551
+ props: FieldProps;
552
+ defaultPropKey: PropsWithDefault;
553
+ context: {
554
+ touched: boolean;
555
+ dirty: boolean;
556
+ filled: boolean;
557
+ focused: boolean;
558
+ validating: boolean;
559
+ errors: string[];
560
+ validity: ValiditySnapshot | null;
561
+ errorTextIds: string[];
562
+ hasHelperText: boolean;
563
+ fieldsetDisabled: boolean;
564
+ submitAttempted: boolean;
565
+ };
566
+ computed: {
567
+ disabled: boolean;
568
+ /**
569
+ * `null` until validation has run — the field is neither valid nor invalid.
570
+ */
571
+ valid: boolean | null;
572
+ invalid: boolean;
573
+ };
574
+ refs: {
575
+ /**
576
+ * Latches to `true` the first time the field is dirtied. Gates `valueMissing`
577
+ * so a pristine empty required field is not flagged before interaction or submit.
578
+ */
579
+ markedDirty: boolean;
580
+ /**
581
+ * The control value at first tracking, the baseline for `dirty`.
582
+ */
583
+ initialValue: string | null;
584
+ /**
585
+ * Async validation sequence — stale resolutions are discarded.
586
+ */
587
+ seq: number;
588
+ /**
589
+ * The field root, resolved once when the machine starts.
590
+ */
591
+ rootEl: HTMLElement | null;
592
+ };
593
+ event: EventObject;
594
+ action: string;
595
+ effect: string;
596
+ guard: string;
597
+ }
598
+ interface ErrorTextProps {
599
+ /**
600
+ * Narrows when the error text shows:
601
+ * - a `ValidityState` key shows it only for that native failure
602
+ * - `true` forces it visible (e.g. driven by an external form library)
603
+ * - omitted shows it whenever the field is invalid
604
+ */
605
+ match?: ValidityMatch | boolean | undefined;
606
+ /**
607
+ * Overrides the generated id. Use when two error texts share the same `match`.
608
+ */
609
+ id?: string | undefined;
610
+ }
611
+ type IndicatorType = 'required' | 'invalid' | 'valid' | 'validating';
612
+ interface IndicatorProps {
613
+ /**
614
+ * The state the indicator reflects. Hidden (not unmounted) unless the state
615
+ * matches, so CSS transitions survive:
616
+ * - `required`: the field is required (e.g. an asterisk)
617
+ * - `invalid`: committed validity is invalid
618
+ * - `valid`: committed validity is valid — a pristine field shows neither
619
+ * - `validating`: an async validation is in flight (e.g. a spinner)
620
+ */
621
+ type: IndicatorType;
622
+ }
623
+ interface ResolvedElementIds {
624
+ root: string;
625
+ control: string;
626
+ label: string;
627
+ errorText: string;
628
+ helperText: string;
629
+ }
630
+ /**
631
+ * Shared interaction and validity state, mirrored onto every field part.
632
+ */
633
+ interface FieldState {
634
+ /**
635
+ * Whether the field is disabled (including inherited fieldset disabled state).
636
+ */
637
+ disabled: boolean;
638
+ /**
639
+ * Whether the field is invalid.
640
+ */
641
+ invalid: boolean;
642
+ /**
643
+ * Committed validity: `null` until validation has run.
644
+ */
645
+ valid: boolean | null;
646
+ /**
647
+ * Whether the field is required.
648
+ */
649
+ required: boolean;
650
+ /**
651
+ * Whether the field is read-only.
652
+ */
653
+ readOnly: boolean;
654
+ /**
655
+ * Whether the control has been blurred at least once.
656
+ */
657
+ touched: boolean;
658
+ /**
659
+ * Whether the value differs from the initial value.
660
+ */
661
+ dirty: boolean;
662
+ /**
663
+ * Whether the control has a non-empty value.
664
+ */
665
+ filled: boolean;
666
+ /**
667
+ * Whether the control is focused.
668
+ */
669
+ focused: boolean;
670
+ /**
671
+ * Whether an async validation is in flight.
672
+ */
673
+ validating: boolean;
674
+ }
675
+ interface RootState extends FieldState {}
676
+ interface LabelState extends FieldState {}
677
+ interface ControlState extends FieldState {}
678
+ interface HelperTextState extends FieldState {}
679
+ interface ErrorTextState extends FieldState {
680
+ /**
681
+ * Whether the error text is hidden.
682
+ */
683
+ hidden: boolean;
684
+ }
685
+ interface IndicatorState extends FieldState {
686
+ /**
687
+ * The state this indicator reflects.
688
+ */
689
+ type: IndicatorType;
690
+ /**
691
+ * Whether the indicator is hidden.
692
+ */
693
+ hidden: boolean;
694
+ }
695
+ interface FieldApi<T extends PropTypes = PropTypes> {
696
+ /**
697
+ * The resolved element ids, for composition with other components.
698
+ */
699
+ ids: ResolvedElementIds;
700
+ /**
701
+ * Whether the field is disabled (including inherited fieldset disabled state).
702
+ */
703
+ disabled: boolean;
704
+ /**
705
+ * Whether the field is invalid.
706
+ */
707
+ invalid: boolean;
708
+ /**
709
+ * Committed validity: `null` until validation has run.
710
+ */
711
+ valid: boolean | null;
712
+ /**
713
+ * Whether the field is required.
714
+ */
715
+ required: boolean;
716
+ /**
717
+ * Whether the field is read-only.
718
+ */
719
+ readOnly: boolean;
720
+ /**
721
+ * Whether the control is focused.
722
+ */
723
+ focused: boolean;
724
+ /**
725
+ * Whether the control has been blurred at least once.
726
+ */
727
+ touched: boolean;
728
+ /**
729
+ * Whether the value differs from the initial value.
730
+ */
731
+ dirty: boolean;
732
+ /**
733
+ * Whether the control has a non-empty value.
734
+ */
735
+ filled: boolean;
736
+ /**
737
+ * Whether an async validation is in flight.
738
+ */
739
+ validating: boolean;
740
+ /**
741
+ * The committed error messages.
742
+ */
743
+ errors: string[];
744
+ /**
745
+ * The committed validity snapshot, `null` until validation has run.
746
+ */
747
+ validity: ValiditySnapshot | null;
748
+ /**
749
+ * The composed `aria-describedby`, for wiring custom controls.
750
+ */
751
+ ariaDescribedby: string | undefined;
752
+ /**
753
+ * Runs validation now, surfacing `valueMissing` even on a pristine field.
754
+ */
755
+ validate: VoidFunction;
756
+ /**
757
+ * Clears committed errors and returns validity to the pristine (unvalidated) state.
758
+ */
759
+ clearErrors: VoidFunction;
760
+ /**
761
+ * Resets interaction state and validity to pristine.
762
+ */
763
+ reset: VoidFunction;
764
+ /**
765
+ * Returns the state of the root.
766
+ */
767
+ getRootState: () => RootState;
768
+ getRootProps: () => T['element'];
769
+ /**
770
+ * Returns the state of the label.
771
+ */
772
+ getLabelState: () => LabelState;
773
+ getLabelProps: () => T['label'];
774
+ /**
775
+ * Returns the state of the control (input, textarea, select, or a custom host).
776
+ */
777
+ getControlState: () => ControlState;
778
+ getControlProps: () => T['element'];
779
+ getInputProps: () => T['input'];
780
+ getTextareaProps: () => T['textarea'];
781
+ getSelectProps: () => T['select'];
782
+ /**
783
+ * Returns the state of the helper text.
784
+ */
785
+ getHelperTextState: () => HelperTextState;
786
+ getHelperTextProps: () => T['element'];
787
+ /**
788
+ * Returns the state of the error text.
789
+ */
790
+ getErrorTextState: (props?: ErrorTextProps) => ErrorTextState;
791
+ getErrorTextProps: (props?: ErrorTextProps) => T['element'];
792
+ /**
793
+ * Returns the state of the indicator.
794
+ */
795
+ getIndicatorState: (props: IndicatorProps) => IndicatorState;
796
+ getIndicatorProps: (props: IndicatorProps) => T['element'];
797
+ }
798
+ //#endregion
799
+ //#region Resources/Private/Primitives/Field/src/field.registry.d.ts
800
+ type FieldMachine = Machine$1<FieldSchema>;
801
+ //#endregion
802
+ //#region Resources/Private/Primitives/Form/src/form.registry.d.ts
803
+ type FormMachine = Machine$1<any>;
804
+ //#endregion
805
+ //#region Resources/Private/Primitives/Form/Form.d.ts
806
+ declare class Form extends Component<FormProps, FormApi> {
807
+ static componentName: string;
808
+ private fieldSubscriptions;
809
+ initMachine(props: FormProps): Machine$1<FormSchema>;
810
+ initApi(): FormApi;
811
+ private subscribeToFieldMachines;
812
+ render(): void;
813
+ destroy(): void;
814
+ }
815
+ //#endregion
816
+ //#region Resources/Private/Primitives/Form/src/form.types.d.ts
817
+ interface FieldError {
818
+ messages: string[];
819
+ value?: FormDataEntryValue | FormDataEntryValue[] | null;
820
+ }
821
+ type FormErrors = Record<string, FieldError>;
822
+ type FormDirty = Record<string, boolean>;
823
+ type FormTouched = Record<string, boolean>;
824
+ type FormValueLeaf = string | File;
825
+ interface FormValuesObject {
826
+ [key: string]: FormValueTree;
827
+ }
828
+ interface FormValuesArray extends Array<FormValueTree> {}
829
+ type FormValueTree = FormValueLeaf | FormValuesObject | FormValuesArray;
830
+ interface FormValues {
831
+ get(path: string): FormValueLeaf | null;
832
+ getAll(path: string): FormValueLeaf[];
833
+ has(path: string): boolean;
834
+ pick(path: string): FormValueTree | null;
835
+ toObject(): FormValuesObject;
836
+ }
837
+ interface StandardSchemaPathSegment {
838
+ readonly key: PropertyKey;
839
+ }
840
+ interface StandardSchemaIssue {
841
+ readonly message: string;
842
+ readonly path?: readonly (PropertyKey | StandardSchemaPathSegment)[];
843
+ }
844
+ interface StandardSchemaSuccessResult<Output = unknown> {
845
+ readonly value: Output;
846
+ readonly issues?: undefined;
847
+ }
848
+ interface StandardSchemaFailureResult {
849
+ readonly issues: readonly StandardSchemaIssue[];
850
+ }
851
+ type StandardSchemaResult<Output = unknown> = StandardSchemaSuccessResult<Output> | StandardSchemaFailureResult;
852
+ interface StandardSchemaV1<Output = unknown> {
853
+ readonly '~standard': {
854
+ readonly validate: (value: unknown) => StandardSchemaResult<Output> | Promise<StandardSchemaResult<Output>>;
855
+ };
856
+ }
857
+ interface FormValidationContext {
858
+ values: FormValues;
859
+ fieldName?: string;
860
+ validateWithStandardSchema: <Output = unknown>(schema: StandardSchemaV1<Output>) => FormErrors;
861
+ }
862
+ type FormState = 'invalid' | 'ready' | 'submitting' | 'success' | 'error';
863
+ type FormValidation = StandardSchemaV1 | ((context: FormValidationContext) => FormErrors | null | void);
864
+ type FormSubmitResult = true | false | FormErrors;
865
+ interface FormProps {
866
+ /** The unique identifier of the form. */
867
+ id: string;
868
+ /**
869
+ * Validates the values of the form on the client: a Standard Schema validator such as Zod, or a
870
+ * synchronous callback that gets the `values` and returns the errors by field name. It cannot be
871
+ * set from a Fluid template, only by constructing `Form` in your own entry file.
872
+ */
873
+ validation?: FormValidation;
874
+ /** The object name that prefixes the names of nested form fields. */
875
+ objectName?: string;
876
+ /**
877
+ * How long the fields wait after the last change before they read their value, never less than
878
+ * 50. A `validate` that sends a request should not fire on every keystroke.
879
+ * @default 100
880
+ */
881
+ inputDebounceMs?: number;
882
+ /**
883
+ * Called with the values once the form is valid and submitted. Return `true` for success,
884
+ * `false` for an error, or field errors to mark the form invalid. `post(url)` submits the form
885
+ * as `FormData` and maps a 422 JSON response to field errors for you.
886
+ */
887
+ onSubmit?: ({
888
+ values,
889
+ api,
890
+ event,
891
+ post
892
+ }: {
893
+ values: FormValues;
894
+ api: FormApi;
895
+ event: JSX.FormEvent<HTMLElement>;
896
+ post: (url: string) => Promise<Response>;
897
+ }) => Promise<FormSubmitResult> | FormSubmitResult;
898
+ /** Called every time the form state changes. Use it to update UI the form does not wire itself. */
899
+ render?: (form: Form) => void;
900
+ }
901
+ interface FormSchema {
902
+ props: FormProps;
903
+ context: {
904
+ errorText: string | null;
905
+ successText: string | null;
906
+ };
907
+ refs: {
908
+ serverErrors: FormErrors;
909
+ };
910
+ state: FormState;
911
+ event: EventObject;
912
+ action: string;
913
+ effect: string;
914
+ }
915
+ interface FormApi {
916
+ /** Whether the form is being submitted. */
917
+ isSubmitting: boolean;
918
+ /** Whether the value of any field differs from the one it started with. */
919
+ isDirty: boolean;
920
+ /** Whether any field is invalid. */
921
+ isInvalid: boolean;
922
+ /** Whether the last submit succeeded. */
923
+ isSuccessful: boolean;
924
+ /** Whether the last submit ended in an error. */
925
+ isError: boolean;
926
+ getFormProps(): PropTypes['element'];
927
+ getContentProps(): PropTypes['element'];
928
+ getIndicatorProps(state: FormState): PropTypes['element'];
929
+ getErrorTextProps(): PropTypes['element'];
930
+ getSuccessTextProps(): PropTypes['element'];
931
+ /** The current values of the form. */
932
+ getValues(): FormValues;
933
+ /** The errors of the invalid fields, by field name. */
934
+ getErrors(): FormErrors;
935
+ /** The dirty fields, by field name. */
936
+ getDirty(): FormDirty;
937
+ /** The touched fields, by field name. */
938
+ getTouched(): FormTouched;
939
+ /** The text of the error status of the form, `null` if there is none. */
940
+ getErrorText(): string | null;
941
+ /** Sets the text of the error status. Pass `null` to remove it. */
942
+ setErrorText(text: string | null): void;
943
+ /** The text of the success status of the form, `null` if there is none. */
944
+ getSuccessText(): string | null;
945
+ /** Sets the text of the success status. Pass `null` to remove it. */
946
+ setSuccessText(text: string | null): void;
947
+ /** Removes the error and the success text. */
948
+ clearStatusText(): void;
949
+ /** @internal */
950
+ _userRenderFn: FormProps['render'];
951
+ /** Every field of the form, by name. */
952
+ getAllFields(): Map<string, FieldHandle>;
953
+ /** The field with this name, `undefined` if the form has none. */
954
+ getField(name: string): FieldHandle | undefined;
955
+ /** The `<form>` element. */
956
+ getFormEl(): HTMLFormElement | null;
957
+ /** The `action` of the form, an empty string if it has none. */
958
+ getAction(): string;
959
+ /** Resets the form to its initial state. */
960
+ reset(): void;
961
+ /** Picks up fields that were added or removed after the form was hydrated. */
962
+ syncFields(): void;
963
+ /**
964
+ * Renames a field, keeping its value, touched, dirty and error state. Useful to keep the rows of
965
+ * a FieldArray contiguously indexed after one in the middle was removed.
966
+ */
967
+ renameField(oldName: string, newName: string): void;
968
+ }
969
+ //#endregion
970
+ //#region Resources/Private/Primitives/Field/src/field.value.d.ts
971
+ type FieldValue = FormDataEntryValue | FormDataEntryValue[] | null;
972
+ //#endregion
973
+ //#region Resources/Private/Primitives/Field/src/field.handle.d.ts
974
+ interface FieldDependencyChangeDetail {
975
+ name: string;
976
+ dependencies: Record<string, FieldValue>;
977
+ values: FormValues;
978
+ }
979
+ /** What a field offers on top of Zag's api: its name, its value, its form and its `listenTo` event. */
980
+ interface FieldHandleExtras {
981
+ /** The name of the field. */
982
+ name: string;
983
+ /** The current value of the field. */
984
+ getValue(): FieldValue;
985
+ /** The first error message of the field, `null` if there is none. */
986
+ getErrorText(): string | null;
987
+ /** The root element of the field. */
988
+ getRootEl(): HTMLElement | null;
989
+ /** The machine of the form the field sits in, `undefined` outside of a form. */
990
+ getFormMachine(): FormMachine | undefined;
991
+ /** Disables or enables the field. */
992
+ setDisabled(disabled: boolean): void;
993
+ /** Marks the field as required or optional. */
994
+ setRequired(required: boolean): void;
995
+ /** Makes the field read-only or editable. */
996
+ setReadOnly(readOnly: boolean): void;
997
+ /**
998
+ * Calls `callback` whenever the value of a field named in the `listenTo` prop of this field
999
+ * changes. Returns a function that removes the listener again. For a field without `listenTo` it
1000
+ * never fires, but the returned function is still safe to call.
1001
+ */
1002
+ addDependencyChangeListener(callback: (detail: FieldDependencyChangeDetail) => void): () => void;
1003
+ }
1004
+ /** Zag's api plus the handle extras: what a `Field` instance exposes as `.api`. */
1005
+ type FieldClientApi = FieldApi & FieldHandleExtras;
1006
+ /** What `form.api.getField(name)` returns: the field's state and actions, flat. */
1007
+ type FieldHandle = Pick<FieldApi, 'disabled' | 'required' | 'readOnly' | 'invalid' | 'valid' | 'touched' | 'dirty' | 'filled' | 'focused' | 'validating' | 'errors' | 'validate' | 'clearErrors' | 'reset'> & FieldHandleExtras;
1008
+ //#endregion
1009
+ //#region Resources/Private/Client/src/lib/field-aware-component.d.ts
1010
+ /**
1011
+ * Base class of a primitive that can sit inside a Field. It takes `name`, `disabled`, `readOnly`,
1012
+ * `required` and `invalid` from the closest Field and follows its changes, and it tells the field
1013
+ * once it has hydrated.
1014
+ */
1015
+ declare abstract class FieldAwareComponent<Props, Api> extends Component<Props, Api> {
1016
+ protected subscribedToField: boolean;
1017
+ protected fieldMachine: FieldMachine | undefined;
1018
+ protected closestField: HTMLElement | null;
1019
+ protected abstract propsWithField(props: Partial<Props>, field: FieldClientApi): Props;
1020
+ /** The field's current api, for what a primitive merges into its own props when it renders. */
1021
+ protected get field(): FieldClientApi | undefined;
1022
+ protected getClosestField(): HTMLElement | null;
1023
+ /** Builds the component like `Component.init()`, then tells the field that it is hydrated. */
1024
+ init(): void;
1025
+ protected withFieldProps(props: Props): Props;
1026
+ /**
1027
+ * Applies every later change of the field to the machine props. It waits for the field if that
1028
+ * has not registered yet, and does nothing when there is no field around.
1029
+ */
1030
+ subscribeToFieldService(): void;
1031
+ /**
1032
+ * The field measured its starting value from the server HTML; a primitive may hydrate to a
1033
+ * different state (a defaultChecked checkbox, a Select's selected option).
1034
+ */
1035
+ private notifyFieldHydrated;
1036
+ }
1037
+ //#endregion
1038
+ //#region Resources/Private/Client/src/lib/hydration.d.ts
1039
+ /**
1040
+ * @internal
1041
+ *
1042
+ * A part's own name is lowerCamelCase (mirroring zag-js's own `ids` prop keys), but its attribute
1043
+ * always renders lower-kebab. Keep in sync with: Classes/Utility/ComponentNameUtility.php's
1044
+ * camelCaseToLowerCaseDashed().
1045
+ */
1046
+ declare function toKebabCase(part: string): string;
1047
+ /** @internal */
1048
+ declare function getHydrationData(component: string): Record<string, ComponentHydrationData> | null;
1049
+ declare function getHydrationData(component: string, id: string): ComponentHydrationData | null;
1050
+ /**
1051
+ * Finds a component instance that is already mounted, by the namespaced name it was mounted with and
1052
+ * its hydration id (the `id` prop it was rendered with). Works for instances from `mountAll()` and
1053
+ * `mount()` alike. It is for primitives that compose two independent instances of themselves at
1054
+ * runtime, e.g. the submenus of a Menu.
1055
+ *
1056
+ * @param componentName - The namespaced name, e.g. `ui:menu`.
1057
+ * @param id - The hydration id of the instance.
1058
+ * @returns The instance, or `undefined` if none is mounted under that id.
1059
+ */
1060
+ declare function getComponentInstance<T extends Component<unknown, unknown> = Component<unknown, unknown>>(componentName: string, id: string): T | undefined;
1061
+ /** @internal */
1062
+ declare function getGlobals(): FluidPrimitivesGlobals | null;
1063
+ /** @internal */
1064
+ declare function getGlobal<T = unknown>(key: string): T | undefined;
1065
+ /**
1066
+ * Mounts every instance of a component that is not mounted yet and was not rendered with
1067
+ * `autoMount="{false}"`. It is safe to call more than once, e.g. after lazily inserted DOM adds new
1068
+ * instances: mounted ones are skipped.
1069
+ *
1070
+ * The `props` in the callback are typed from `componentName` via `HydrationPropsFor`. A component
1071
+ * without generated types gets an untyped bag.
1072
+ *
1073
+ * @param componentName - The namespaced name, e.g. `ui:select`.
1074
+ * @param callback - Creates the instance of one hydration entry and returns it.
1075
+ *
1076
+ * @example
1077
+ * ```typescript
1078
+ * mountAll('ui:accordion', ({ props }) => {
1079
+ * const accordion = new Accordion(props);
1080
+ * accordion.init();
1081
+ * return accordion;
1082
+ * });
1083
+ * ```
1084
+ */
1085
+ declare function mountAll<K extends KnownComponentName | (string & {})>(componentName: K, callback: (data: {
1086
+ autoMount: boolean;
1087
+ props: HydrationPropsFor<Extract<K, string>>;
1088
+ createHydrator: () => ComponentHydrator;
1089
+ }) => Component<unknown, unknown> | void): void;
1090
+ /**
1091
+ * Destroys every mounted instance whose root element is `root` or inside it, and forgets it. Call it
1092
+ * before you remove a subtree from the DOM, e.g. a row of a FieldArray.
1093
+ *
1094
+ * Only the `root` part of an instance counts. A component without one, such as Dialog, is never
1095
+ * matched.
1096
+ *
1097
+ * @param root - The element that is about to be removed.
1098
+ */
1099
+ declare function destroyComponentsWithin(root: Element | Document): void;
1100
+ /**
1101
+ * Mounts one instance by its `rootId`, also one that was rendered with `autoMount="{false}"`. Unlike
1102
+ * `mountAll()`, it creates a new instance on every call, which then replaces the one tracked before.
1103
+ * `getComponentInstance()` and `destroyComponentsWithin()` find it like any other.
1104
+ *
1105
+ * The `props` in the callback are typed like those of `mountAll()`.
1106
+ *
1107
+ * @param componentName - The namespaced name, e.g. `ui:dialog`.
1108
+ * @param rootId - The `rootId` the component was rendered with.
1109
+ * @param callback - Creates the instance and returns it.
1110
+ * @returns The instance, or `undefined` if there is no hydration entry for `rootId`.
1111
+ */
1112
+ declare function mount<K extends KnownComponentName | (string & {}), T extends Component<unknown, unknown>>(componentName: K, rootId: string, callback: (data: {
1113
+ autoMount: boolean;
1114
+ props: HydrationPropsFor<Extract<K, string>>;
1115
+ createHydrator: () => ComponentHydrator;
1116
+ }) => T | void): T | undefined;
1117
+ /**
1118
+ * Finds the parts of one component instance. Every part that `ui:ref` renders carries a
1119
+ * `data-<component>-<part>="<rootId>"` attribute, so a lookup needs no id and searches the whole
1120
+ * document by default. That is also what finds content that was portaled away from the root.
1121
+ */
1122
+ declare class ComponentHydrator {
1123
+ /** The name of the component, in camelCase. */
1124
+ componentName: string;
1125
+ /** The kebab-case form of `componentName`, as it appears in attribute names. */
1126
+ clientComponentName: string;
1127
+ /** The document the parts are searched in. */
1128
+ doc: Document;
1129
+ /** The `rootId` the component was rendered with. */
1130
+ rootId: string;
1131
+ /**
1132
+ * @param componentName - The name of the component, in camelCase.
1133
+ * @param rootId - The `rootId` the component was rendered with. Throws if it is missing.
1134
+ * @param doc - The document the parts are searched in.
1135
+ */
1136
+ constructor(componentName: string, rootId: string | undefined, doc?: Document);
1137
+ private get attrPrefix();
1138
+ /** The name of the attribute that marks `part`, e.g. `data-accordion-item-trigger`. */
1139
+ attr(part: string): string;
1140
+ /** The CSS selector of every element of `part` that belongs to this instance. */
1141
+ selector(part: string): string;
1142
+ /** The key that identifies `part`, and optionally one `value` of it, across this instance. */
1143
+ scopeKey(part: string, value?: string): string;
1144
+ /**
1145
+ * Finds the first element of `part`.
1146
+ *
1147
+ * @param part - The name of the part, in camelCase.
1148
+ * @param parent - Where to search, the whole document by default.
1149
+ * @returns The element, or `null` if there is none.
1150
+ */
1151
+ query<T extends Element = HTMLElement>(part: string, parent?: Element | Document): T | null;
1152
+ /**
1153
+ * Finds every element of `part`.
1154
+ *
1155
+ * @param part - The name of the part, in camelCase.
1156
+ * @param parent - Where to search, the whole document by default.
1157
+ */
1158
+ queryAll<T extends Element = HTMLElement>(part: string, parent?: Element | Document): T[];
1159
+ /**
1160
+ * Marks an element as `part` of this instance, like `ui:ref` does on the server. For elements
1161
+ * you create after hydration.
1162
+ *
1163
+ * @param element - The element to mark.
1164
+ * @param part - The name of the part, in camelCase.
1165
+ * @param value - Sets `data-value`, for a part that exists once per item.
1166
+ */
1167
+ stamp(element: Element, part: string, value?: string): void;
1168
+ /** The part this component's own scope marks `el` as (kebab-case), if any. */
1169
+ private getOwnPart;
1170
+ /**
1171
+ * Sets `data-value` on every element within `root` (root included) that is a part of *this*
1172
+ * component's own scope, for a new, real `value` - the shared half of
1173
+ * {@see restampValue}/{@see renameValue}, which differ only in what they each then do about any
1174
+ * nested, independent root component `root` happens to compose (a fresh copy vs. an in-place
1175
+ * rename - see `restampValue`'s own docblock for why the two are never auto-detected from one
1176
+ * another).
1177
+ *
1178
+ * `attributes`, if given, are additionally set on the same elements `value` is applied to - for
1179
+ * primitives whose `render()` reads plain per-element data attributes rather than resolving a
1180
+ * collection item (e.g. RadioGroup's `disabled`/`invalid`, NavigationMenu's `Link` `current`).
1181
+ * A boolean value toggles a bare `data-x` attribute (e.g. `{ disabled: true }` -> `data-disabled`,
1182
+ * present only when true); a string value sets `data-x="value"` directly.
1183
+ */
1184
+ private restampOwnScope;
1185
+ /**
1186
+ * @internal
1187
+ *
1188
+ * Re-stamps `root` for a new, real `value` (via {@see restampOwnScope}) and prepares any
1189
+ * nested, *independent* root component found inside it (e.g. a `Field`+`Input` composed inside
1190
+ * a `FieldArray` row, or any other primitive that composes another one inside its own per-item
1191
+ * markup) as a brand-new instance copied from its own pristine stencil data, via
1192
+ * {@see prepareNestedRootComponents}. Use after cloning a `<template>` (see `Template`) to make
1193
+ * the clone represent one real item/row in a single call, instead of manually setting
1194
+ * `data-value` on the root and separately on every nested value-scoped part (e.g. a combobox
1195
+ * item's own `item-text`/`item-indicator`) *and* separately preparing whatever independent
1196
+ * components that item happens to compose. Fully generic - not
1197
+ * tied to any one primitive - so a `<template>` item "just works" regardless of what it
1198
+ * contains, without the calling primitive needing to know or handle that itself.
1199
+ *
1200
+ * Only for a *freshly cloned* item - one that has never been through this or
1201
+ * {@see renameValue} before (a `<template>`'s content is never mutated by a previous clone, so
1202
+ * this is always true right after `content.cloneNode(true)`). For an *existing* item pulled
1203
+ * from the live DOM whose value is merely changing (e.g. `FieldArray` reindexing a later row
1204
+ * down by one after an earlier row was removed), call {@see renameValue} instead.
1205
+ *
1206
+ * The two used to be auto-detected from a nested component's own *current* id shape (no
1207
+ * `:value` suffix yet vs. already has one) rather than asked for explicitly - but that shape
1208
+ * can't actually tell a never-touched, already-live server-rendered row apart from a
1209
+ * never-touched template clone; both look identical. That silently mis-classified an
1210
+ * already-mounted row as "fresh" the first time an earlier row's removal caused it to be
1211
+ * reindexed: its DOM references moved out from under it (via `restampIdReferences`, which both
1212
+ * paths run) without its `ComponentHydrator.rootId`/`componentInstances` entry following along -
1213
+ * only {@see renameValue}'s path updates those - leaving its already-mounted `Field`/`Input`
1214
+ * instances silently unable to find their own elements again. The caller already knows
1215
+ * unambiguously which case it's in (a fresh `Template` clone vs. an element already in the
1216
+ * document), so it now says so by calling the matching method instead of leaving it to a guess.
1217
+ *
1218
+ * `stencilKey` is the stencil's own {@see scopeKey} (see `Template`'s constructor, its only
1219
+ * caller) - what nested root components `root` composes is looked up from
1220
+ * `window.FluidPrimitives.nestedComponents[stencilKey]` (PHP-recorded, see
1221
+ * `HydrationRegistry::recordNestedComponent()`), not found by scanning `root` itself. That's
1222
+ * what lets this find a nested component regardless of what DOM shape it renders - including
1223
+ * one that renders no identifiable wrapper of its own at all (e.g. `Dialog`'s `Root`, which is
1224
+ * just `<f:slot />` - see `ui:portal`'s own `isRenderStencil` handling for the other half of
1225
+ * making a portalled nested component work inside a stencil).
1226
+ *
1227
+ * Returns the distinct client component names of any nested root components found and
1228
+ * prepared (empty when `root` contains none, the common case - e.g. `FileUpload`'s own item
1229
+ * previews) - call the matching `mountAll()`s for each of these after inserting a freshly
1230
+ * cloned item into the document, per `mountAll`'s own docblock ("after lazily-inserted DOM
1231
+ * adds new instances").
1232
+ */
1233
+ restampValue(root: Element, value: string, stencilKey: string, attributes?: Record<string, boolean | string>): string[];
1234
+ /**
1235
+ * @internal
1236
+ *
1237
+ * Re-stamps `root` for a new, real `value` (via {@see restampOwnScope}) and re-keys every
1238
+ * nested, independent root component found inside it (e.g. a `FieldArray` row's own
1239
+ * `Field`+`Input`) to reference `value` instead of whatever position it previously held - both
1240
+ * their DOM references (via {@see restampIdReferences}) and, for ones that are already live/mounted,
1241
+ * their own `ComponentHydrator.rootId` and their entry in
1242
+ * `window.FluidPrimitives.componentInstances`/`hydrationData` (via
1243
+ * {@see renameNestedComponentEntry}), so their future re-renders keep resolving their own
1244
+ * elements and later lookups (`getComponentInstance`, `destroyComponentsWithin`) keep finding
1245
+ * them under their new id.
1246
+ *
1247
+ * For an *existing* item pulled from the live DOM whose position is merely shifting - never for
1248
+ * a freshly cloned `<template>` item, which has no existing instance/hydration-data entry to
1249
+ * re-key in the first place; use {@see restampValue} for that. See that method's own docblock
1250
+ * for why the two are never auto-detected from one another.
1251
+ *
1252
+ * Looks up what `root` composes from `window.FluidPrimitives.nestedComponents[<scopeKey>]`,
1253
+ * keyed by `root`'s own part and `data-value` *before* this call restamps it, which is why
1254
+ * that's read first, before {@see restampOwnScope} changes it. That's a correct lookup key both
1255
+ * for a row rendered for real (PHP records it there too - see `ComponentHydrationCollector`'s
1256
+ * FieldArray-ambient-context check) and for one `restampValue` prepared earlier (which migrates
1257
+ * the same entry to the row's new key as its own last step, for exactly this reason).
1258
+ *
1259
+ * Restamps id *references* (via {@see restampIdReferences}) across the whole document, not just
1260
+ * `root`'s own subtree - unlike {@see restampValue}, where a fresh clone can't yet have anything
1261
+ * portaled out of it (nothing composed by it has mounted/opened yet), `root` here is an existing,
1262
+ * already-live item, so a nested component it composes may already have portaled its own content
1263
+ * elsewhere in the document (e.g. an open `Popover`'s positioner, rendered via `ui:portal` into
1264
+ * the page footer) by the time this runs. Scoping to `root` alone would restamp that component's
1265
+ * trigger in place but silently miss its portaled content, leaving it referencing a now-stale id.
1266
+ */
1267
+ renameValue(root: Element, value: string): void;
1268
+ /** Nothing to release yet, it exists so every instance can be destroyed alike. */
1269
+ destroy(): void;
1270
+ }
1271
+ declare function getListCollectionFromHydrationData<T extends CollectionItem>(hydrationCollection: {
1272
+ items: T[];
1273
+ itemToValueKey?: string | null;
1274
+ itemToStringKey?: string | null;
1275
+ isItemDisabledKey?: string | null;
1276
+ groupByKey?: string | null;
1277
+ groupSort?: 'asc' | 'desc' | Array<string> | null;
1278
+ }): ListCollection<T>;
1279
+ //#endregion
1280
+ //#region Resources/Private/Client/src/lib/machine.d.ts
1281
+ /**
1282
+ * The Zag machine runtime that components run on. It takes `Partial` props: the `id` that Zag
1283
+ * requires is guaranteed at runtime by `Component.initHydrator()`.
1284
+ */
1285
+ declare class Machine$1<T extends MachineSchema> extends VanillaMachine<T> {
1286
+ constructor(machine: Machine<T>, userProps?: Partial<NonNullable<T['props']>>);
1287
+ /** Changes props at runtime. Only the ones you pass change, the others stay. */
1288
+ updateProps(newProps: Partial<NonNullable<T['props']>> | InputProps<T> | (() => InputProps<T>)): void;
1289
+ }
1290
+ //#endregion
1291
+ //#region Resources/Private/Client/src/lib/spread-props.d.ts
1292
+ /**
1293
+ * Like `spreadProps` for a text control, but it does not assign a `value` the control already
1294
+ * shows. Any assignment, even of the same text, makes the browser treat the value as set by a
1295
+ * script, and it stops reporting `tooShort` (`minlength`) for such a value. These controls mirror
1296
+ * what the user typed into their machine, so that assignment would happen on every keystroke.
1297
+ *
1298
+ * As in `spreadProps`, a value is only considered when it changed since the last call: the control
1299
+ * can be one event ahead of the machine, and must not be reset to the machine's older value.
1300
+ */
1301
+ declare function spreadTextControlProps(node: HTMLInputElement | HTMLTextAreaElement, attrs: Attrs, scopeKey?: string): () => void;
1302
+ //#endregion
1303
+ //#region Resources/Private/Client/src/lib/template.d.ts
1304
+ /** The options of a {@link Template}. */
1305
+ interface TemplateOptions {
1306
+ /**
1307
+ * Makes the clone represent one real item: sets `data-value` on its root and on every part
1308
+ * inside it that exists once per item, and prepares independent root components inside it, such
1309
+ * as a `Field` with an `Input`, so `mountAll()` can mount them. Leave it out for a template
1310
+ * without a per-item value.
1311
+ */
1312
+ value?: string;
1313
+ /**
1314
+ * Data attributes to set next to `value`, on the same elements. A boolean toggles a bare
1315
+ * `data-x` attribute, `{ disabled: true }` sets `data-disabled` and `false` removes it. A string
1316
+ * sets `data-x="value"`. Only has an effect together with `value`.
1317
+ */
1318
+ attributes?: Record<string, boolean | string>;
1319
+ }
1320
+ /**
1321
+ * Clones the content of a `<template>` part, which must have exactly one root element, and throws
1322
+ * otherwise. It is a `DocumentFragment`, so you can append it directly: `root` stays a valid
1323
+ * reference to the element after the fragment has been emptied by the insertion.
1324
+ *
1325
+ * It works for any "clone a `<template>` and fill it with data that doesn't exist at server render
1326
+ * time" case, such as async search results, file upload previews or the rows of a FieldArray.
1327
+ */
1328
+ declare class Template extends DocumentFragment {
1329
+ private readonly hydrator;
1330
+ /** The one root element of the clone. */
1331
+ readonly root: HTMLElement;
1332
+ /**
1333
+ * The client names of the independent root components found inside the clone, empty without
1334
+ * `options.value` or when there are none. Call their `mountAll()` after you insert the clone into
1335
+ * the document.
1336
+ */
1337
+ readonly componentNames: string[];
1338
+ /**
1339
+ * @param hydrator - The hydrator of the component that owns the `<template>`.
1340
+ * @param part - The name of the `<template>` part.
1341
+ * @param options - See `TemplateOptions`.
1342
+ */
1343
+ constructor(hydrator: ComponentHydrator, part: string, options?: TemplateOptions);
1344
+ /** Finds the first element of `part` inside the clone. */
1345
+ query<T extends Element = HTMLElement>(part: string): T | null;
1346
+ /** Finds every element of `part` inside the clone. */
1347
+ queryAll<T extends Element = HTMLElement>(part: string): T[];
1348
+ }
1349
+ //#endregion
1350
+ //#region Resources/Private/Client/src/lib/uid.d.ts
1351
+ /**
1352
+ * Creates an id that is unique within the page, e.g. for a part that needs an `id` to reference.
1353
+ *
1354
+ * @param prefix - Starts the id.
1355
+ */
1356
+ declare function uid(prefix?: string): string;
1357
+ //#endregion
1358
+ export { AsyncList as $, FormValueTree as A, ComponentHydrationData as B, FieldValue as C, FormSubmitResult as D, FormProps as E, FieldSchema as F, HydrationPropsRegistry as G, FluidPrimitivesGlobals as H, extbase as I, ClientPropConverter as J, KnownComponentName as K, DelayedIndicator as L, FormValuesObject as M, Form as N, FormValidation as O, FieldProps as P, registerClientPropConverters as Q, DelayedIndicatorOptions as R, FieldHandle as S, FormErrors as T, HydrationPropsFor as U, ComponentInterface as V, HydrationPropsOverrides as W, ConverterMachineProps as X, ClientPropConverterMap as Y, applyClientPropConverters as Z, mountAll as _, spreadTextControlProps as a, FieldClientApi as b, Machine$1 as c, getComponentInstance as d, AsyncListOptions as et, getGlobal as f, mount as g, getListCollectionFromHydrationData as h, spreadProps as i, FormValues as j, FormValueLeaf as k, ComponentHydrator as l, getHydrationData as m, Template as n, normalizeProps$1 as o, getGlobals as p, NestedComponentEntry as q, TemplateOptions as r, mergeProps as s, uid as t, destroyComponentsWithin as u, toKebabCase as v, FormApi as w, FieldDependencyChangeDetail as x, FieldAwareComponent as y, Component as z };