@optionfactory/fml 8.0.3 → 9.0.0-rc10

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 (50) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +87 -0
  3. package/dist/client-errors.iife.js +30 -9
  4. package/dist/client-errors.iife.js.map +1 -1
  5. package/dist/client-errors.iife.min.js +1 -1
  6. package/dist/client-errors.iife.min.js.map +1 -1
  7. package/dist/custom-elements.json +1622 -415
  8. package/dist/fml.css +21 -10
  9. package/dist/fml.css.map +1 -1
  10. package/dist/fml.d.mts +3 -1322
  11. package/dist/fml.iife.js +5767 -2313
  12. package/dist/fml.iife.js.map +1 -1
  13. package/dist/fml.iife.min.js +1 -1
  14. package/dist/fml.iife.min.js.map +1 -1
  15. package/dist/fml.min.mjs +1 -1
  16. package/dist/fml.min.mjs.map +1 -1
  17. package/dist/fml.mjs +6 -8737
  18. package/dist/fml.mjs.map +1 -1
  19. package/dist/ftl.d.mts +430 -92
  20. package/dist/ftl.iife.js +1314 -809
  21. package/dist/ftl.iife.js.map +1 -1
  22. package/dist/ftl.iife.min.js +1 -1
  23. package/dist/ftl.iife.min.js.map +1 -1
  24. package/dist/ftl.min.mjs +1 -1
  25. package/dist/ftl.min.mjs.map +1 -1
  26. package/dist/ftl.mjs +1313 -810
  27. package/dist/ftl.mjs.map +1 -1
  28. package/dist/ful.css +21 -10
  29. package/dist/ful.css.map +1 -1
  30. package/dist/ful.d.mts +973 -252
  31. package/dist/ful.iife.js +4176 -1416
  32. package/dist/ful.iife.js.map +1 -1
  33. package/dist/ful.iife.min.js +1 -1
  34. package/dist/ful.iife.min.js.map +1 -1
  35. package/dist/ful.min.mjs +1 -1
  36. package/dist/ful.min.mjs.map +1 -1
  37. package/dist/ful.mjs +4163 -1416
  38. package/dist/ful.mjs.map +1 -1
  39. package/dist/httpc.d.mts +114 -19
  40. package/dist/httpc.iife.js +253 -83
  41. package/dist/httpc.iife.js.map +1 -1
  42. package/dist/httpc.iife.min.js +1 -1
  43. package/dist/httpc.iife.min.js.map +1 -1
  44. package/dist/httpc.min.mjs +1 -1
  45. package/dist/httpc.min.mjs.map +1 -1
  46. package/dist/httpc.mjs +250 -84
  47. package/dist/httpc.mjs.map +1 -1
  48. package/dist/vscode.html-custom-data.json +660 -58
  49. package/dist/web-types.json +1577 -354
  50. package/package.json +16 -8
package/dist/ful.d.mts CHANGED
@@ -1,24 +1,24 @@
1
1
  import { ParsedElement } from './ftl.mjs';
2
- declare class LocalStorage extends Storage {
3
- static save(k: any, v: any): void;
4
- static load(k: any): any;
5
- static remove(k: any): void;
6
- static pop(k: any): any;
7
- }
8
- declare class SessionStorage extends Storage {
9
- static save(k: any, v: any): void;
10
- static load(k: any): any;
11
- static remove(k: any): void;
12
- static pop(k: any): any;
13
- }
14
- declare class VersionedLocalStorage {
15
- static save(key: any, revision: any, data: any): void;
16
- static load(key: any, revision: any): any;
17
- }
18
- declare class VersionedSessionStorage {
19
- static save(key: any, revision: any, data: any): void;
20
- static load(key: any, revision: any): any;
21
- }
2
+ declare const LocalStorage: {
3
+ save: (k: any, v: any) => void;
4
+ load: (k: any) => any;
5
+ remove: (k: any) => void;
6
+ pop: (k: any) => any;
7
+ };
8
+ declare const SessionStorage: {
9
+ save: (k: any, v: any) => void;
10
+ load: (k: any) => any;
11
+ remove: (k: any) => void;
12
+ pop: (k: any) => any;
13
+ };
14
+ declare const VersionedLocalStorage: {
15
+ save(key: any, revision: any, data: any): void;
16
+ load(key: any, revision: any): any;
17
+ };
18
+ declare const VersionedSessionStorage: {
19
+ save(key: any, revision: any, data: any): void;
20
+ load(key: any, revision: any): any;
21
+ };
22
22
  export type AsyncExtension = {
23
23
  promises: Promise<any>[];
24
24
  };
@@ -30,6 +30,12 @@ export type AsyncEvent = Event & {
30
30
  * @property {Promise<any>[]} promises
31
31
  * @typedef {Event & { async?: AsyncExtension }} AsyncEvent
32
32
  */
33
+ /**
34
+ * Dispatching an event and waiting for what its listeners answer. A listener
35
+ * registered through `asyncOn` attaches its promise to the event, and
36
+ * `fireAsync` resolves once they have all settled: `broadcast` collects every
37
+ * answer, `pipeline` allows at most one, `delegate` requires exactly one.
38
+ */
33
39
  declare class AsyncEvents {
34
40
  /**
35
41
  * Dispatches an event and handles asynchronous resolution based on the execution mode.
@@ -64,36 +70,113 @@ declare class AsyncEvents {
64
70
  */
65
71
  static mixInto(...classes: Function[]): void;
66
72
  }
73
+ export type Claim = {
74
+ readonly stale: boolean;
75
+ };
76
+ /**
77
+ * @typedef {{ readonly stale: boolean }} Claim
78
+ */
79
+ /**
80
+ * The generations of claims over one contended resource. Every take() starts a
81
+ * new generation, superseding every claim before it, and a holder asks its
82
+ * claim `stale` before painting chrome, storing state or throwing towards a
83
+ * caller: a superseded outcome owns nothing. hold() joins the current
84
+ * generation without superseding it (a fetch that any later reconfiguration
85
+ * must detach), and invalidate() supersedes without claiming (a hide ending
86
+ * every pending show). One Claims per contended resource: a component whose
87
+ * dropdown, value labels and loader configuration contend separately holds one
88
+ * each.
89
+ */
90
+ declare class Claims {
91
+ #private;
92
+ /**
93
+ * Starts a new generation, superseding every earlier claim, and holds it.
94
+ * @returns {Claim}
95
+ */
96
+ take(): Claim;
97
+ /**
98
+ * Holds the current generation without superseding anything.
99
+ * @returns {Claim}
100
+ */
101
+ hold(): Claim;
102
+ /** Supersedes every claim without holding a new one. */
103
+ invalidate(): void;
104
+ }
105
+ export type Describable = {
106
+ describedBy(el: HTMLElement): boolean;
107
+ };
108
+ /**
109
+ * The protocol by which content standing inside a field becomes part of the
110
+ * accessible description of that field's control.
111
+ *
112
+ * A field owns its control's `aria-describedby`: it is the only thing that
113
+ * knows which element the description belongs on, and it already writes the
114
+ * entry for its own error region. Content the author slotted into the field
115
+ * cannot write that attribute itself without becoming a second owner of it, and
116
+ * it cannot be wired by the field either, because a slotted custom element
117
+ * renders after the field has mounted and has nothing to point at when the
118
+ * field looks.
119
+ *
120
+ * So the content asks, once it has something to offer. `describable(el)`
121
+ * answers the nearest ancestor that accepts a description, and the caller hands
122
+ * its element to that ancestor's `describedBy`, which answers whether it was
123
+ * taken. Nothing here names a field or a tooltip: the relation is expressed as
124
+ * a capability, so the two ends need not import each other, which matters
125
+ * because the library's own arrow runs from the forms to the disclosures.
126
+ *
127
+ * The lookup lives here rather than at its one call site so the protocol has a
128
+ * name, a place to be documented and a single definition to change.
129
+ */
130
+ /**
131
+ * @typedef {{ describedBy(el: HTMLElement): boolean }} Describable
132
+ */
133
+ /**
134
+ * The nearest ancestor of `el` that accepts elements into the description of
135
+ * whatever it considers its control, or null when nothing in the ancestry does.
136
+ * @param {Element} el
137
+ * @returns {(Element & Describable) | null}
138
+ */
139
+ declare const describable: (el: Element) => (Element & Describable) | null;
140
+ /**
141
+ * Sleeping, debouncing and throttling. Debounce and throttle both return the
142
+ * wrapped function together with a cancel function.
143
+ */
67
144
  declare class Timing {
68
- static sleep(ms: any): Promise<any>;
69
- static DEBOUNCE_DEFAULT: number;
70
- static DEBOUNCE_IMMEDIATE: number;
145
+ /** Resolves after the given milliseconds. @param {number} ms */
146
+ static sleep(ms: number): Promise<any>;
71
147
  /**
72
148
  * Executes only after a period of inactivity (pause in events).
73
149
  * Respond to the "end" of a series of events.
74
- * @param {*} timeoutMs
75
- * @param {*} func
76
- * @param {*} [options]
150
+ * @param {number} timeoutMs
151
+ * @param {function} func
152
+ * @param {{ immediate?: boolean }} [options] - immediate fires on the leading edge instead of the trailing one
77
153
  * @returns {[function, function]}
78
154
  */
79
- static debounce(timeoutMs: any, func: any, options?: any): [Function, Function];
80
- static THROTTLE_DEFAULT: number;
81
- static THROTTLE_NO_LEADING: number;
82
- static THROTTLE_NO_TRAILING: number;
155
+ static debounce(timeoutMs: number, func: Function, options?: {
156
+ immediate?: boolean;
157
+ }): [Function, Function];
83
158
  /**
84
159
  * Executes at most once per specified time interval, regardless of ongoing events.
85
- * @param {*} timeoutMs
86
- * @param {*} func
87
- * @param {*} [options]
160
+ * @param {number} timeoutMs
161
+ * @param {function} func
162
+ * @param {{ leading?: boolean, trailing?: boolean }} [options] - which edges of the interval call, both by default
88
163
  * @returns {[function, function]}
89
164
  */
90
- static throttle(timeoutMs: any, func: any, options?: any): [Function, Function];
165
+ static throttle(timeoutMs: number, func: Function, options?: {
166
+ leading?: boolean;
167
+ trailing?: boolean;
168
+ }): [Function, Function];
91
169
  }
170
+ /** Field wiring: extracting and filling values, pinning problems to the fields they name. */
92
171
  declare class Bindings {
172
+ #private;
93
173
  /**
174
+ * Flattens a nested object into dotted keys, stopping wherever `stops` names
175
+ * a key: a field named `address` takes the whole object, while one named
176
+ * `address.city` takes the leaf.
94
177
  * @param {{ [x: string]: any; }} obj
95
178
  * @param {string} prefix
96
- * @param {Set<String>} stops
179
+ * @param {Set<String>} stops - the names the form actually has fields for
97
180
  * @return {{ [x: string]: any; }}
98
181
  */
99
182
  static flatten(obj: {
@@ -102,15 +185,20 @@ declare class Bindings {
102
185
  [x: string]: any;
103
186
  };
104
187
  /**
188
+ * Writes a value into an object at a dotted path, creating the intermediate
189
+ * objects and arrays the path implies. A numeric segment makes an array.
105
190
  * @param {any} result
106
- * @param {string} path
191
+ * @param {string} path - a field name, `a.b` or `a[0].b`
107
192
  * @param {any} value
108
193
  */
109
194
  static providePath(result: any, path: string, value: any): any;
110
195
  /**
111
- *
196
+ * Reads one control's value the way its kind demands: an unchecked radio
197
+ * answers undefined so it contributes nothing, a checkbox answers its
198
+ * checked state, a multiple select answers its selected values, and a blank
199
+ * native control answers null rather than an empty string.
112
200
  * @param {Element & {dataset?: any} & {checked?: boolean} & {value?: any}} el
113
- * @returns
201
+ * @returns {any} the value, or undefined where the control contributes none
114
202
  */
115
203
  static extract(el: Element & {
116
204
  dataset?: any;
@@ -119,17 +207,13 @@ declare class Bindings {
119
207
  } & {
120
208
  value?: any;
121
209
  }): any;
210
+ static extractFrom(form: any, submitter: any): {};
122
211
  /**
123
- *
124
- * @param {HTMLFormElement} form
125
- * @param {HTMLElement} [submitter]
126
- * @returns
127
- */
128
- static extractFrom(form: HTMLFormElement, submitter?: HTMLElement): {};
129
- /**
130
- *
212
+ * Writes a value into one control, the inverse of `extract`: a radio is
213
+ * checked when its own value matches, a checkbox takes the value as its
214
+ * checked state, and a multiple select selects the options the list names.
131
215
  * @param {Element & {dataset?: any} & {checked?: boolean} & {value?: any}} el
132
- * @returns
216
+ * @param {any} raw the value as it arrived, coerced per control kind
133
217
  */
134
218
  static mutate(el: Element & {
135
219
  dataset?: any;
@@ -141,82 +225,305 @@ declare class Bindings {
141
225
  static mutateIn(form: any, values: any): void;
142
226
  static errors(form: any, es: any, scrollOnError: any): void;
143
227
  }
228
+ /**
229
+ * The base of every form-associated ful field: a form-associated custom element
230
+ * carrying the validity protocol, the field error live region, focus
231
+ * delegation, the label chrome and the disabled, readonly and required claims.
232
+ *
233
+ * A subclass owns its template, its value semantics and its change events. It
234
+ * implements `_build(conf)`, which builds its dom and returns the pieces the
235
+ * base drives: the control, the error region, the label, and the optional
236
+ * `claims`, `announces`, `freeze` and `also`. The base does the wiring,
237
+ * the mounting and the application of the declared state. Nothing in the base
238
+ * is there to be called from a subclass's build.
239
+ *
240
+ * The pieces are the contract: the claim setters, the validity protocol and
241
+ * the aria wiring all act on them, so a field with no native control returns a
242
+ * focusable piece of its own chrome as the control. The getters and `focus()`
243
+ * are the only members that tolerate a not-yet-rendered element, where page
244
+ * code may read a claim or ask for the focus before the upgrade; the
245
+ * properties go live only after the render, as ParsedElement documents. The
246
+ * base references no ful vocabulary, only what its subclasses return to it.
247
+ */
248
+ declare class Field extends ParsedElement {
249
+ #private;
250
+ static formAssociated: boolean;
251
+ /**
252
+ * The claim attributes and the value are observed here so every field,
253
+ * including the custom ones, keeps them live after the upgrade: the
254
+ * attribute is a third way to author a claim, beside the markup and the
255
+ * property,
256
+ * exactly as a native input's. The value defaults to the string mapper and
257
+ * every field with its own vocabulary overrides it (`value:bool`,
258
+ * `value:csv`, `value:json`).
259
+ */
260
+ static observed: string[];
261
+ /** the role the element internals carry, 'presentation' unless the control is its own */
262
+ static ROLE: string;
263
+ constructor();
264
+ /**
265
+ * Adds an element to the accessible description of the field's control and
266
+ * answers whether the field took it.
267
+ *
268
+ * A field takes one whenever it is offered, before its own render as
269
+ * readily as after: content slotted into a field is a custom element of its
270
+ * own and may upgrade on either side of the field it stands in, which
271
+ * happens in both directions in practice, a tooltip beating an async select
272
+ * to its render while losing to a plain input. A description handed over
273
+ * early waits here and is written the moment the field has somewhere to
274
+ * write it, so the caller never has to know the order.
275
+ *
276
+ * The reference lands on the element handed over rather than on a wrapper
277
+ * around it: a hidden element is included in a description only where it is
278
+ * named directly, and content that reaches the description through a
279
+ * wrapper is skipped while it is hidden. A popover closed until someone
280
+ * opens it is exactly that, so the caller passes the popover itself.
281
+ *
282
+ * An attribute rather than `ariaDescribedByElements`: the property reflects
283
+ * to nothing, so the description would live in the accessibility tree alone
284
+ * and vanish entirely on a browser without aria element reflection.
285
+ *
286
+ * This is the field's half of the description protocol; `describable` in
287
+ * `ful/descriptions.mjs` is the half the content uses to find the field.
288
+ * @param {HTMLElement} el
289
+ * @returns {boolean}
290
+ */
291
+ describedBy(el: HTMLElement): boolean;
292
+ focus(options: any): void;
293
+ /**
294
+ * Clears or reports one validation problem: the text lands on the field's
295
+ * live region and the state on the element internals, driving `:invalid`
296
+ * styling. Validation is the server's: the submit travels regardless, and
297
+ * the problems come back pinned here. The error mapping pins on the most
298
+ * specific field name a problem's context reaches, handing over the
299
+ * remaining path ('' on an exact match): the base ignores it, a composite
300
+ * field owning a whole subtree overrides to route the problem to the inner
301
+ * control it names.
302
+ * @param {string} [error]
303
+ * @param {string} [context] the path below this field's name, '' when exact
304
+ */
305
+ setCustomValidity(error?: string, context?: string): void;
306
+ /** Submits the associated form through its first submitter, as Enter on a native control would. */
307
+ _requestSubmit(): void;
308
+ /**
309
+ * Dispatches the field's change event: bubbling, not cancelable, the value
310
+ * in the detail. Every field announces through this one method, and the detail
311
+ * always carries the field's own `value`, so a listener can rely on
312
+ * `el.value === evt.detail.value` whatever the field is. A field with more to
313
+ * say adds keys beside it; none can replace it.
314
+ * @param {Record<string, any>} [extras]
315
+ */
316
+ _notifyChange(extras?: Record<string, any>): void;
317
+ /**
318
+ * Whether the field's chrome should answer a gesture. Badges, dropzones,
319
+ * menus and labels are not form controls, so their handlers must ask the
320
+ * effective state: matches(':disabled') covers the fieldset ancestry the
321
+ * disabled property deliberately does not reflect, readonly the field's
322
+ * own claim.
323
+ */
324
+ _interactive(): boolean;
325
+ /**
326
+ * The field's value: every concrete field owns its semantics and overrides
327
+ * this pair. The base pair exists so the form integration (the reset
328
+ * protocol among others) has a member to write through; a custom field
329
+ * forgetting its own keeps the base's inert one.
330
+ * @type {any}
331
+ */
332
+ get value(): any;
333
+ set value(v: any);
334
+ /**
335
+ * A reset restores the field's declared value, as a native control's reset
336
+ * restores its markup default: the `value` attribute goes back through the
337
+ * element's own mapper and value setter, so every field resets through its
338
+ * own semantics. A field whose value is not attribute backed overrides this.
339
+ */
340
+ formResetCallback(): void;
341
+ /**
342
+ * The disabled protocol follows the semantics of a native form control:
343
+ *
344
+ * - the `disabled` attribute on the host is the field's own claim, and nothing
345
+ * but its author ever writes or removes it, in markup or through the
346
+ * property. The framework never claims on the form's behalf, so there is
347
+ * nothing to unclaim and nothing to lose: a field declared disabled inside
348
+ * a disabled `<fieldset>` stays disabled when the fieldset comes back,
349
+ * exactly like a native input keeps its attribute.
350
+ * - the effective state is the claim OR a disabled fieldset ancestry, which
351
+ * the platform maintains on its own: `:disabled` matches both, a disabled
352
+ * field is left out of the submitted values, and the inner native controls
353
+ * are reached by the ancestry as descendants of the fieldset.
354
+ * - the property reflects the claim only, like a native input's: a field
355
+ * disabled by its ancestry reads `false` while `matches(':disabled')`
356
+ * tells the effective state. Un-claiming inside a disabled fieldset
357
+ * cannot enable the field.
358
+ * - the inner controls mirror the claim and nothing else: the ancestry state
359
+ * is never written anywhere, so it can never go stale, and the browser
360
+ * composes the two on its own when it disables and re-enables a fieldset's
361
+ * descendants. Subclass setters call super for the claim, then reach their
362
+ * own controls, which mirror the claim like a native input's would.
363
+ *
364
+ * Because of this, formDisabledCallback carries nothing the framework needs
365
+ * to apply, and the protocol does not define it.
366
+ */
367
+ get disabled(): boolean;
368
+ set disabled(d: boolean);
369
+ /**
370
+ * A field is readonly through its control's native readOnly when it has one:
371
+ * the control stays focusable and its text selectable, only editing is off.
372
+ * Fields whose chrome must freeze too (popovers, buttons, label clicks) name
373
+ * a `freeze` piece instead, whose gestures the base refuses while the claim
374
+ * holds; the claim reflects on the host either way.
375
+ */
376
+ get readonly(): boolean;
377
+ set readonly(v: boolean);
378
+ /**
379
+ * A field is required through aria: the claim reflects on the host, the
380
+ * announcement lives on the adopted control.
381
+ */
382
+ get required(): boolean;
383
+ set required(d: boolean);
384
+ /**
385
+ * The field's render is the base's: the subclass builds its dom in `_build`
386
+ * and hands back what it built, the base wiring the pieces, mounting the
387
+ * fragment and applying the declared state. Nothing in the base is there to
388
+ * be called from a subclass's build. `_build` may be async (a select
389
+ * awaiting its prefetch); a field that builds synchronously stays so.
390
+ */
391
+ render(conf: any): Promise<void> | undefined;
392
+ /**
393
+ * Builds the field's dom and answers the pieces the base drives. The one
394
+ * method a concrete field implements beside its value pair, and the only
395
+ * place its dom is created; the base does the wiring and the mounting.
396
+ *
397
+ * - `fragment` is mounted on the host
398
+ * - `control` is the focusable target: focus, the aria and, by default, all
399
+ * three claims reach it
400
+ * - `error` is the field's live region
401
+ * - `label`, when given, names the control and focuses it on click
402
+ * - `described` moves the description off the control and onto another
403
+ * element, the host where no single control can carry it: the error
404
+ * region and anything `describedBy` is later handed both land there
405
+ * - `claims` moves the three claims onto a wrapper the field disables as a
406
+ * whole, leaving focus and aria on the control
407
+ * - `announces` is the element whose role carries `aria-readonly` and
408
+ * `aria-required`, the host where the widget role lives there; `null` for a
409
+ * field whose control has no role that accepts them
410
+ * - `freeze` is for a field with no usable native readOnly: the readonly
411
+ * claim refuses the gestures inside it, leaving it focusable and readable
412
+ * - `also` are further controls mirroring disabled and readOnly beside the
413
+ * first
414
+ *
415
+ * A subclass extending another field's build spreads the pieces it answered
416
+ * and overrides the keys it owns.
417
+ * @param {{slots: any}} conf
418
+ * @returns {any}
419
+ */
420
+ _build(conf: {
421
+ slots: any;
422
+ }): any;
423
+ }
424
+ /** Submits a form's values as json to a url, mapping the request and the response through the configured mappers. */
144
425
  declare class RemoteJsonFormLoader {
145
426
  #private;
146
427
  constructor(http: any, url: any, method: any, requestMapper: any, responseMapper: any);
147
428
  prepare(values: any, form: any): any;
148
- submit(values: any, form: any): Promise<any>;
429
+ submit(request: any, form: any): Promise<any>;
149
430
  transform(response: any, form: any): any;
150
431
  }
432
+ /** Submits a form without a request: the request mapper produces the result the response mapper then reads, for a form handled entirely on the page. */
151
433
  declare class LocalFormLoader {
152
434
  #private;
153
435
  constructor(requestMapper: any, responseMapper: any);
154
436
  prepare(values: any, form: any): Promise<any>;
155
- submit(values: any, form: any, response: any): Promise<any>;
437
+ submit(request: any, form: any, response: any): Promise<any>;
156
438
  transform(response: any, form: any): Promise<any>;
157
439
  }
440
+ /**
441
+ * Builds the form's loader from its attributes: a local one when no action is
442
+ * declared, a json post to it otherwise.
443
+ *
444
+ * A component registered under the `loader` attribute replaces this one and
445
+ * must implement three methods, called in this order:
446
+ *
447
+ * - `prepare(values, form)` turns the extracted values into the request to send
448
+ * - `submit(request, form, response)` performs it and returns the response. The
449
+ * third argument is whatever a `submit:requested` listener already answered,
450
+ * which is how a loader with nothing to send returns it unchanged
451
+ * - `transform(response, form)` turns that response into the detail of the
452
+ * `submit:success` event
453
+ *
454
+ * A rejection from any of the three is reported as a `submit:failure`.
455
+ */
158
456
  declare class FormLoader {
159
457
  static create(el: any, conf: any): LocalFormLoader | RemoteJsonFormLoader;
160
458
  }
459
+ /**
460
+ * Wraps its fields in a native form, extracts their values on submit and hands
461
+ * them to a loader (loaders:form, or the action url as a json post),
462
+ * announcing failures through the errors setter.
463
+ */
161
464
  declare class Form extends ParsedElement {
162
465
  #private;
466
+ static attributes: string[];
163
467
  form: any;
164
468
  render(): void;
165
469
  /**
166
- *
470
+ * Submits once: a submit while one is in flight is dropped before the
471
+ * values are even extracted, so nothing fires and nothing travels; the
472
+ * settled exchange re-arms the form. A write must not double behind a
473
+ * second Enter or a programmatic call racing the first.
167
474
  * @param {HTMLElement} [submitter]
168
475
  * @returns
169
476
  */
170
477
  submit(submitter?: HTMLElement): Promise<void>;
478
+ /** The native reset, routing every field through its own value semantics. */
171
479
  reset(): void;
480
+ /** Shows the spinners and holds the submit buttons off, overlapping spins sharing one claim. */
172
481
  spinner(spin: any): void;
482
+ /** The values of the fields the form contains, extracted and filled back through Bindings. */
173
483
  set values(vs: {});
174
484
  get values(): {};
485
+ /** Pins problems to the fields they name, the banner taking the nameless ones. */
175
486
  set errors(es: any);
176
487
  }
177
- declare class Input extends ParsedElement {
178
- internals: ElementInternals;
488
+ /** A labelled text input over any native type or textarea; the temporal inputs are its subclasses. */
489
+ declare class Input extends Field {
179
490
  static observed: string[];
491
+ static attributes: string[];
180
492
  static slots: boolean;
181
493
  static template: string;
182
- static formAssociated: boolean;
183
494
  _input: any;
184
- _fieldError: any;
185
- constructor();
186
- _type(): string;
187
- _fragment(type: any, slots: any): any;
188
- render({ slots, observed, disabled, skipObservedSetup }: {
189
- disabled: any;
190
- observed: any;
191
- skipObservedSetup: any;
495
+ _type(): any;
496
+ _build({ slots }: {
192
497
  slots: any;
193
- }): void;
498
+ }): {
499
+ fragment: any;
500
+ control: any;
501
+ error: any;
502
+ label: any;
503
+ };
194
504
  get value(): any;
195
505
  set value(value: any);
196
- get readonly(): any;
197
- set readonly(v: any);
198
- get disabled(): boolean;
199
- set disabled(d: boolean);
200
- get required(): boolean;
201
- set required(d: boolean);
202
506
  get placeholder(): any;
203
507
  set placeholder(d: any);
204
- focus(options: any): void;
205
- setCustomValidity(error: any): void;
206
- formResetCallback(): void;
207
508
  }
509
+ /** Formats the yyyy-mm-dd date in its content in the page's locale, or the one its locale attribute names. */
208
510
  declare class LocalDate extends ParsedElement {
511
+ static attributes: string[];
209
512
  render(): void;
210
513
  }
514
+ /** Formats the ISO instant in its content in the page's locale and timezone. */
211
515
  declare class Instant extends ParsedElement {
516
+ #private;
517
+ static attributes: string[];
212
518
  render(): void;
213
519
  static isoToLocal(iso: any): string;
520
+ static localToIso(local: any): string | null;
214
521
  }
522
+ /** A date input whose bounds accept a date, now, or an offset such as +1d. */
215
523
  declare class InputLocalDate extends Input {
216
524
  #private;
217
525
  static observed: string[];
218
526
  _type(): string;
219
- render(conf: any): void;
220
527
  get min(): any;
221
528
  set min(v: any);
222
529
  get max(): any;
@@ -224,6 +531,7 @@ declare class InputLocalDate extends Input {
224
531
  get step(): any;
225
532
  set step(v: any);
226
533
  }
534
+ /** A time input whose bounds accept a time, now, or an hour or minute offset, snapped to the step grid. */
227
535
  declare class InputLocalTime extends InputLocalDate {
228
536
  #private;
229
537
  _type(): string;
@@ -232,10 +540,10 @@ declare class InputLocalTime extends InputLocalDate {
232
540
  get max(): any;
233
541
  set max(v: any);
234
542
  }
543
+ /** A datetime input whose value is read and written as an ISO instant. */
235
544
  declare class InputInstant extends Input {
236
545
  static observed: string[];
237
546
  _type(): string;
238
- render(conf: any): void;
239
547
  get value(): string | null;
240
548
  set value(v: string | null);
241
549
  get min(): string | null;
@@ -245,38 +553,18 @@ declare class InputInstant extends Input {
245
553
  get step(): any;
246
554
  set step(v: any);
247
555
  }
556
+ /** A file input with an optional dropzone and item list, enforcing the size and count limits it declares. */
248
557
  declare class InputFile extends Input {
249
558
  #private;
250
- static l10n: {
251
- en: {
252
- dropzonelabel: string;
253
- unacceptablefiletype: string;
254
- maxfilesizeexceeded: string;
255
- maxtotalsizeexceeded: string;
256
- maxfilesexceeded: string;
257
- };
258
- it: {
259
- dropzonelabel: string;
260
- unacceptablefiletype: string;
261
- maxfilesizeexceeded: string;
262
- maxtotalsizeexceeded: string;
263
- maxfilesexceeded: string;
264
- };
265
- es: {
266
- dropzonelabel: string;
267
- unacceptablefiletype: string;
268
- maxfilesizeexceeded: string;
269
- maxtotalsizeexceeded: string;
270
- maxfilesexceeded: string;
271
- };
272
- fr: {
273
- dropzonelabel: string;
274
- unacceptablefiletype: string;
275
- maxfilesizeexceeded: string;
276
- maxtotalsizeexceeded: string;
277
- maxfilesexceeded: string;
278
- };
279
- };
559
+ /** how long a warning stands before the field retires it, matching the css fade */
560
+ static WARNING_TIMEOUT: number;
561
+ /**
562
+ * A FileList holding exactly these files. The platform gives no way to
563
+ * build one but through a DataTransfer, and every place that narrows a
564
+ * selection rebuilt it by hand: five loops and three empty ones.
565
+ * @param {Iterable<File>} [files]
566
+ */
567
+ static list(files?: Iterable<File>): FileList;
280
568
  static observed: string[];
281
569
  _type(): string;
282
570
  static template: string;
@@ -284,7 +572,13 @@ declare class InputFile extends Input {
284
572
  items: string;
285
573
  warning: string;
286
574
  };
287
- render(conf: any): void;
575
+ _build(conf: any): {
576
+ fragment: any;
577
+ control: any;
578
+ error: any;
579
+ label: any;
580
+ freeze: any;
581
+ };
288
582
  warning(key: any, args: any): void;
289
583
  get accept(): any;
290
584
  set accept(vs: any);
@@ -296,18 +590,70 @@ declare class InputFile extends Input {
296
590
  set file(v: any);
297
591
  get value(): any;
298
592
  set value(v: any);
593
+ formResetCallback(): void;
299
594
  get totalsize(): any;
300
- get maxfiles(): any;
301
- set maxfiles(v: any);
302
- get maxfilesize(): any;
303
- set maxfilesize(v: any);
304
- get maxtotalsize(): any;
305
- set maxtotalsize(v: any);
306
- get itemlist(): any;
307
- set itemlist(v: any);
595
+ get maxFiles(): any;
596
+ set maxFiles(v: any);
597
+ get maxFileSize(): any;
598
+ set maxFileSize(v: any);
599
+ get maxTotalSize(): any;
600
+ set maxTotalSize(v: any);
601
+ get itemList(): any;
602
+ set itemList(v: any);
308
603
  get dropzone(): any;
309
604
  set dropzone(v: any);
310
605
  }
606
+ /**
607
+ * CSS anchor positioning for a popover and the invoker it belongs to, with the
608
+ * hand-placed fallback for the platforms that do not have it.
609
+ */
610
+ declare class Anchors {
611
+ /**
612
+ * Anchors a popover to its invoker.
613
+ *
614
+ * The invoker is given an `anchor-name` and the popover a `position-anchor`
615
+ * pointing at it, which is what a stylesheet needs to place the popover
616
+ * itself: the library's own menus say `top: anchor(bottom); left:
617
+ * anchor(left)`. **Writing that css is the caller's half of this.** Without
618
+ * it the popover lands wherever the user agent puts a popover, which is not
619
+ * beside the invoker.
620
+ *
621
+ * Where the platform has no anchor positioning the popover is placed here
622
+ * instead, beside the invoker whenever it opens, clamped into the viewport,
623
+ * following it on scroll and resize, and cleaned up on close. That placement
624
+ * draws the geometry the css above describes, so the two agree.
625
+ *
626
+ * @param {HTMLElement} invoker the element the popover belongs to
627
+ * @param {HTMLElement} popover the `[popover]` element to place
628
+ * @param {object} [options]
629
+ * @param {string} [options.prefix] prefixes the generated anchor name and id,
630
+ * so the dom says which component a name belongs to
631
+ * @param {boolean} [options.invoke] points the invoker's `popovertarget` at
632
+ * the popover, giving toggle and light dismiss with no script of your own
633
+ * @param {boolean} [options.expanded] keeps the invoker's `aria-expanded` in
634
+ * step with the popover
635
+ * @param {boolean} [options.stretch] widens the popover to its invoker, which
636
+ * is what a combobox dropdown wants
637
+ * @param {boolean} [options.handPlace] places here on every platform rather
638
+ * than only as a fallback, which a popover asks for when it needs to know
639
+ * where its invoker ended up: the tooltip's note points a callout at it, and
640
+ * a pseudo-element cannot read an anchor outside its own containing block.
641
+ * Such a popover declares no anchor placement in css, there being none to
642
+ * agree with
643
+ */
644
+ static wire(invoker: HTMLElement, popover: HTMLElement, { prefix, invoke, expanded, stretch, handPlace }?: {
645
+ prefix?: string;
646
+ invoke?: boolean;
647
+ expanded?: boolean;
648
+ stretch?: boolean;
649
+ handPlace?: boolean;
650
+ }): void;
651
+ }
652
+ /**
653
+ * Fetches a select's whole vocabulary from a url and serves every later read
654
+ * from it. Concurrent callers share one request, the options may be cached in
655
+ * local storage under a revision, and reconfiguring the url discards both.
656
+ */
311
657
  declare class RemoteLoader {
312
658
  #private;
313
659
  constructor({ http, url, method, responseMapper, prefetch, revision }: {
@@ -321,8 +667,15 @@ declare class RemoteLoader {
321
667
  prefetch(): Promise<void>;
322
668
  exact(...keys: any[]): Promise<any>;
323
669
  load(needle: any): Promise<any>;
670
+ /**
671
+ * Drops the cached vocabulary so the next question refetches it. Any fetch
672
+ * still in flight is detached: its outcome belongs to the configuration that
673
+ * started it and must neither be served nor stored for the new one.
674
+ */
675
+ invalidate(): Promise<void>;
324
676
  reconfigureUrl(url: any): Promise<void>;
325
677
  }
678
+ /** Asks the endpoint per query instead of fetching the vocabulary once, for a list too large to hold in memory. */
326
679
  declare class PartialRemoteLoader {
327
680
  #private;
328
681
  constructor({ http, url, method, responseMapper }: {
@@ -331,22 +684,65 @@ declare class PartialRemoteLoader {
331
684
  responseMapper: any;
332
685
  url: any;
333
686
  });
687
+ /**
688
+ * Nothing is held between queries, so there is no cache to drop: the method
689
+ * exists so a caller can invalidate any loader without knowing which it has.
690
+ */
691
+ invalidate(): Promise<void>;
692
+ reconfigureUrl(url: any): Promise<void>;
334
693
  exact(...keys: any[]): Promise<any>;
335
694
  load(needle: any): Promise<any>;
336
695
  }
696
+ /** Serves a select's options from an array held in memory, which is what the slotted `<option>` elements become. */
337
697
  declare class InMemoryLoader {
338
698
  #private;
339
699
  constructor(data: any);
340
700
  update(data: any): void;
701
+ /** The vocabulary is the data itself: update replaces it, so there is nothing to drop. */
702
+ invalidate(): Promise<void>;
341
703
  exact(...keys: any[]): any;
342
704
  load(needle: any): any;
343
705
  }
706
+ /**
707
+ * Builds the select's loader from its attributes: the slotted options in
708
+ * memory, or a remote or chunked loader over src.
709
+ *
710
+ * A component registered under the `loader` attribute replaces this one and
711
+ * must implement the same three methods, each answering `{ key, label,
712
+ * metadata }` entries:
713
+ *
714
+ * - `prefetch()` warms the vocabulary if it can, and resolves either way
715
+ * - `load(needle)` answers the entries matching the typed text, all of them
716
+ * when the needle is nullish, which is the empty search the list opens with
717
+ * - `exact(...keys)` answers the entries for those keys, used to label a value
718
+ * assigned without going through the list
719
+ */
344
720
  declare class SelectLoader {
345
721
  #private;
722
+ /**
723
+ * Builds a loader from a plain configuration, reading no dom: `data` alone
724
+ * is the in-memory vocabulary, a `url` is fetched whole or, under
725
+ * `mode: 'chunked'`, per query. A test, or a caller holding its own
726
+ * configuration, builds a loader this way; `create` is the same thing with
727
+ * an element's attributes parsed first.
728
+ * @param {{ data?: any[], http?: any, url?: string, method?: string, mode?: string, prefetch?: boolean, revision?: string|null, responseMapper?: any }} conf
729
+ */
730
+ static from({ data, http, url, method, mode, prefetch, revision, responseMapper }: {
731
+ data?: any[];
732
+ http?: any;
733
+ url?: string;
734
+ method?: string;
735
+ mode?: string;
736
+ prefetch?: boolean;
737
+ revision?: string | null;
738
+ responseMapper?: any;
739
+ }): InMemoryLoader | PartialRemoteLoader | RemoteLoader;
346
740
  static create(el: any, conf: any): InMemoryLoader | PartialRemoteLoader | RemoteLoader;
347
741
  }
742
+ /** The options popup of a select: listbox semantics, one loading claim per show, a localized empty state. */
348
743
  declare class Dropdown extends ParsedElement {
349
744
  #private;
745
+ static attributes: string[];
350
746
  static slots: boolean;
351
747
  static template: string;
352
748
  static templates: {
@@ -356,151 +752,131 @@ declare class Dropdown extends ParsedElement {
356
752
  slots: any;
357
753
  }): void;
358
754
  acceptSelection(): void;
359
- update(values: any): void;
755
+ update(values: any, keys?: any[]): void;
360
756
  hide(): void;
361
757
  get shown(): boolean;
362
- show(loader: any): Promise<void>;
363
- moveOrShow(forward: any, loader: any): Promise<void>;
758
+ show(loader: any, keys?: any[]): Promise<void>;
759
+ moveOrShow(forward: any, loader: any, keys?: any[]): Promise<void>;
760
+ jump(first: any): void;
761
+ page(forward: any): void;
364
762
  }
365
- declare class Select extends ParsedElement {
763
+ /** A combobox acting like a select over a loader's vocabulary, single or multiple. */
764
+ declare class Select extends Field {
366
765
  #private;
766
+ static attributes: string[];
367
767
  static observed: string[];
368
768
  static slots: boolean;
369
769
  static template: string;
370
770
  static templates: {
371
771
  items: string;
372
772
  };
373
- static formAssociated: boolean;
374
- internals: ElementInternals;
375
- constructor();
376
- render({ slots, observed, disabled }: {
377
- disabled: any;
378
- observed: any;
773
+ _build({ slots }: {
379
774
  slots: any;
380
- }): Promise<void>;
775
+ }): {
776
+ fragment: any;
777
+ control: any;
778
+ error: any;
779
+ label: any;
780
+ };
781
+ /** Hands the loader to the callback, for runtime reconfigurations. */
381
782
  withLoader(fn: any): Promise<any>;
783
+ /**
784
+ * Drops whatever the loader is holding and asks it about the current selection
785
+ * again, which is what a select whose vocabulary depends on another control
786
+ * needs when that control changes. A key the loader no longer knows is dropped
787
+ * from the selection, so a value invalidated by the change does not survive it,
788
+ * and one it still knows keeps its place with a fresh label.
789
+ *
790
+ * Pass a url first where the vocabulary lives at a different address:
791
+ *
792
+ * citta.addEventListener('change', async () => {
793
+ * await cap.withLoader((l) => l.reconfigureUrl(`/api/cap?citta=${citta.value}`));
794
+ * await cap.reload();
795
+ * });
796
+ */
797
+ reload(): Promise<void>;
382
798
  set value(vs: any);
383
799
  get value(): any;
384
- get entry(): [any, any][] | [any, any];
385
- get disabled(): boolean;
386
- set disabled(d: boolean);
387
- get readonly(): any;
388
- set readonly(v: any);
389
- get required(): boolean;
390
- set required(d: boolean);
391
- get itemlist(): any;
392
- set itemlist(v: any);
393
- focus(options: any): void;
394
- setCustomValidity(error: any): void;
800
+ /** The selection as {key, label, metadata} entries, the change detail's vocabulary: the only one for a single select, every one when multiple. */
801
+ get entry(): any;
802
+ get multiple(): any;
803
+ set multiple(v: any);
804
+ get itemList(): any;
805
+ set itemList(v: any);
395
806
  }
396
- declare class RadioGroup extends ParsedElement {
807
+ /** A group of radios declared as ful-radio children, a fieldset carrying the group semantics. */
808
+ declare class RadioGroup extends Field {
397
809
  #private;
398
- internals: ElementInternals;
399
- static observed: string[];
810
+ static attributes: string[];
400
811
  static slots: boolean;
812
+ static ROLE: string;
401
813
  static template: string;
402
- static formAssociated: boolean;
403
- constructor();
404
- render({ slots, observed, disabled }: {
405
- disabled: any;
406
- observed: any;
814
+ /**
815
+ * @param {{slots: any}} conf
816
+ * @returns {any}
817
+ */
818
+ _build({ slots }: {
407
819
  slots: any;
408
- }): void;
820
+ }): any;
409
821
  get value(): string | boolean | null;
410
822
  set value(value: string | boolean | null);
411
- get readonly(): any;
412
- set readonly(v: any);
413
- get disabled(): boolean;
414
- set disabled(d: boolean);
415
- get required(): boolean;
416
- set required(d: boolean);
417
- focus(options: any): void;
418
- setCustomValidity(error: any): void;
419
823
  }
420
- declare class Checkbox extends ParsedElement {
824
+ /** A checkbox, or a switch under the type=switch claim. */
825
+ declare class Checkbox extends Field {
421
826
  #private;
422
- internals: ElementInternals;
827
+ static attributes: string[];
423
828
  static observed: string[];
424
829
  static slots: boolean;
425
830
  static template: string;
426
- static formAssociated: boolean;
427
- constructor();
428
- render({ slots, observed, disabled }: {
429
- disabled: any;
430
- observed: any;
831
+ _build({ slots }: {
431
832
  slots: any;
432
- }): void;
833
+ }): {
834
+ fragment: any;
835
+ control: any;
836
+ error: any;
837
+ label: any;
838
+ freeze: any;
839
+ };
433
840
  get value(): any;
434
841
  set value(value: any);
435
- get readonly(): any;
436
- set readonly(v: any);
437
- get disabled(): boolean;
438
- set disabled(d: boolean);
439
- get required(): boolean;
440
- set required(d: boolean);
441
- focus(options: any): void;
442
- setCustomValidity(error: any): void;
443
- }
444
- declare class Spinner extends ParsedElement {
445
- static slots: boolean;
446
- static template: string;
447
- render({ slots }: {
448
- slots: any;
449
- }): void;
450
842
  }
843
+ /** The sort control of a table header: focusable, keyboard-activated, walking asc, desc, unsorted. */
451
844
  declare class SortButton extends ParsedElement {
452
845
  #private;
846
+ static attributes: string[];
453
847
  static observed: string[];
454
- render({ observed }: {
455
- observed: any;
456
- }): void;
848
+ render(): void;
457
849
  get order(): any;
458
850
  set order(value: any);
459
851
  }
852
+ /** The pager: a window of page links around the current one, and the reload control. */
460
853
  declare class Pagination extends ParsedElement {
461
854
  #private;
462
855
  static observed: string[];
463
- static l10n: {
464
- en: {
465
- showing: string;
466
- navigation: string;
467
- previous: string;
468
- next: string;
469
- };
470
- it: {
471
- showing: string;
472
- navigation: string;
473
- previous: string;
474
- next: string;
475
- };
476
- es: {
477
- showing: string;
478
- navigation: string;
479
- previous: string;
480
- next: string;
481
- };
482
- fr: {
483
- showing: string;
484
- navigation: string;
485
- previous: string;
486
- next: string;
487
- };
488
- };
856
+ static attributes: string[];
489
857
  static config: {
490
858
  prevIcon: string;
491
859
  nextIcon: string;
492
860
  reloadIcon: string;
493
861
  };
494
862
  static template: string;
495
- render({ observed }: {
496
- observed: any;
863
+ render(): void;
864
+ /**
865
+ * Moves the pager to a page, a page count, or both, and repaints once. The
866
+ * two are one state: writing them one at a time repainted the bar twice per
867
+ * load, the first pass drawing the new page against the old count.
868
+ * @param {{ current?: number|null, total?: number|null }} [state]
869
+ */
870
+ update({ current: toCurrent, total: toTotal }?: {
871
+ current?: number | null;
872
+ total?: number | null;
497
873
  }): void;
498
- update(current: any, total: any): void;
499
874
  get total(): number;
500
875
  set total(value: number);
501
876
  get current(): number;
502
877
  set current(value: number);
503
878
  }
879
+ /** Reads the schema declaration into the header and row templates a table renders from. */
504
880
  declare class TableSchemaParser {
505
881
  static parse(nodeOrFragment: any, template: any): {
506
882
  headersTemplate: any;
@@ -512,31 +888,47 @@ declare class TableSchemaParser {
512
888
  length: number;
513
889
  };
514
890
  }
891
+ /** Serves a table's rows from an array held in memory, applying the sort and the paging itself. */
892
+ declare class InMemoryTableLoader {
893
+ #private;
894
+ constructor(data: any);
895
+ load(pageRequest: any, sortRequest: any, filterRequest: any): Promise<{
896
+ data: any;
897
+ size: any;
898
+ }>;
899
+ update(data: any): void;
900
+ }
901
+ /** Requests one page of rows from a url, passing the page, the sort and the filters to the endpoint. */
902
+ declare class RemoteTableLoader {
903
+ #private;
904
+ constructor(http: any, url: any, method: any, responseMapper?: (response: any) => any);
905
+ load(pageRequest: any, sortRequest: any, filterRequest: any): Promise<any>;
906
+ }
907
+ /**
908
+ * Builds the table's loader from its attributes: an in-memory one, or the
909
+ * remote loader over src.
910
+ *
911
+ * A component registered under the `loader` attribute replaces this one and
912
+ * must implement `load(pageRequest, sortRequest, filterRequest)`, answering
913
+ * `{ data, page, size }` for the requested page. `pageRequest` carries the page
914
+ * index and its size, `sortRequest` the column and direction, and
915
+ * `filterRequest` the values of the filters in the slot.
916
+ */
917
+ declare class TableLoader {
918
+ static create(el: any, conf: any): InMemoryTableLoader | RemoteTableLoader;
919
+ }
920
+ /** A table loading its rows from a loader, with sorting, pagination and an optional filter form. */
515
921
  declare class Table extends ParsedElement {
516
922
  #private;
923
+ static attributes: string[];
924
+ /**
925
+ * The page size stays live: a rows-per-page control is a normal thing to
926
+ * put next to a table, and the size is the one piece of the request an
927
+ * author changes after the table is up. The rest of the request is the
928
+ * table's own state, moved by the pager, the sorters and the filter form.
929
+ */
930
+ static observed: string[];
517
931
  static slots: boolean;
518
- static l10n: {
519
- en: {
520
- initial: string;
521
- error: string;
522
- nodata: string;
523
- };
524
- it: {
525
- initial: string;
526
- error: string;
527
- nodata: string;
528
- };
529
- es: {
530
- initial: string;
531
- error: string;
532
- nodata: string;
533
- };
534
- fr: {
535
- initial: string;
536
- error: string;
537
- nodata: string;
538
- };
539
- };
540
932
  static config: {
541
933
  searchIcon: string;
542
934
  };
@@ -544,54 +936,383 @@ declare class Table extends ParsedElement {
544
936
  static templates: {
545
937
  row: string;
546
938
  };
547
- render({ slots, observed }: {
548
- observed: any;
939
+ /** How many rows a page asks the loader for: the size the next load will carry. */
940
+ get pageSize(): number;
941
+ /**
942
+ * Changes the page size and reloads from the first page, the current index
943
+ * meaning nothing under a new size. A table that has not loaded yet only
944
+ * records it: writing the size is not a request to start loading, which is
945
+ * what `autoload` and `reload()` are for.
946
+ *
947
+ * Absent or null is the default of ten, so removing the attribute restores
948
+ * it rather than asking the loader for NaN rows.
949
+ */
950
+ set pageSize(value: number);
951
+ render({ slots }: {
549
952
  slots: any;
550
953
  }): Promise<void>;
551
954
  reload(): Promise<void>;
552
955
  load(pageRequest: any, sortRequest: any, filterRequest: any): Promise<void>;
956
+ /** Hands the loader to the callback, for runtime reconfigurations. */
553
957
  withLoader(fn: any): Promise<any>;
554
958
  resetWithFilter(filterRequest: any): Promise<void>;
555
959
  }
556
- declare class InstantFilter extends Input {
557
- #private;
960
+ /**
961
+ * The shared shape of every operator-and-operands filter: an operator menu, one
962
+ * or two operands of the type the subclass declares, and a tuple that mirrors
963
+ * the data-jpa compare annotations.
964
+ */
965
+ declare class CompareFilter extends Input {
558
966
  static observed: string[];
967
+ static OPERATORS: string[];
968
+ static DEFAULT_OPERATOR: string;
559
969
  static template: string;
560
- render(conf: any): void;
561
- get value(): any[] | undefined;
562
- set value(v: any[] | undefined);
563
- get readonly(): any;
564
- set readonly(v: any);
970
+ _operator: any;
971
+ _container: any;
972
+ _value1: any;
973
+ _value2: any;
974
+ _build(conf: any): {
975
+ fragment: any;
976
+ control: any;
977
+ error: any;
978
+ label: any;
979
+ freeze: any;
980
+ also: any[];
981
+ };
982
+ _showDefaultOperator(): void;
983
+ formResetCallback(): void;
984
+ _type(): string;
985
+ _serialize(v: any): any;
986
+ _deserialize(v: any): any;
987
+ _defaultOperator(): string;
988
+ _vocabulary(): string[];
989
+ _declaredOperators: any;
990
+ get operators(): any;
991
+ set operators(declared: any);
992
+ get value(): any[] | null;
993
+ set value(v: any[] | null);
994
+ _tuple(): any[] | null;
995
+ _applyTuple(v: any): void;
996
+ _showOperator(operator: any): void;
997
+ /** only a BETWEEN carries a second operand */
998
+ _syncBetween(): void;
565
999
  get disabled(): boolean;
566
1000
  set disabled(d: boolean);
1001
+ /** every menu button the filter composes, so one claim reaches them all */
1002
+ _choices(): any[];
567
1003
  }
568
- declare class LocalDateFilter extends Input {
569
- #private;
1004
+ /** The compare filter over ISO instants, defaulting to LTE. */
1005
+ declare class InstantFilter extends CompareFilter {
1006
+ _defaultOperator(): string;
1007
+ _type(): string;
1008
+ _serialize(v: any): string | null;
1009
+ _deserialize(v: any): string;
1010
+ }
1011
+ /** The compare filter over dates. */
1012
+ declare class LocalDateFilter extends CompareFilter {
1013
+ _type(): string;
1014
+ }
1015
+ /** The compare filter over numbers. */
1016
+ declare class NumberFilter extends CompareFilter {
1017
+ _type(): string;
1018
+ }
1019
+ /** The compare filter over text, carrying a case sensitivity beside the operator. */
1020
+ declare class TextFilter extends CompareFilter {
570
1021
  static observed: string[];
571
1022
  static template: string;
572
- render(conf: any): void;
573
- get value(): any[] | undefined;
574
- set value(v: any[] | undefined);
575
- get readonly(): any;
576
- set readonly(v: any);
1023
+ _defaultOperator(): string;
1024
+ _vocabulary(): string[];
1025
+ _sensitivityButton: any;
1026
+ _build(conf: any): {
1027
+ fragment: any;
1028
+ control: any;
1029
+ error: any;
1030
+ label: any;
1031
+ freeze: any;
1032
+ also: any[];
1033
+ };
1034
+ _choices(): any[];
1035
+ get _sensitivity(): any;
1036
+ _declaredSensitivities: any;
1037
+ get sensitivities(): any;
1038
+ set sensitivities(declared: any);
1039
+ get value(): any[] | null;
1040
+ set value(v: any[] | null);
1041
+ formResetCallback(): void;
1042
+ }
1043
+ /** The boolean filter: an EQ or NEQ operator and an any/yes/no menu. */
1044
+ declare class BooleanFilter extends Field {
1045
+ static observed: string[];
1046
+ static slots: boolean;
1047
+ static OPERATORS: string[];
1048
+ static DEFAULT_OPERATOR: string;
1049
+ static template: string;
1050
+ _operator: any;
1051
+ _value: any;
1052
+ _container: any;
1053
+ _build({ slots }: {
1054
+ slots: any;
1055
+ }): {
1056
+ fragment: any;
1057
+ control: any;
1058
+ error: any;
1059
+ label: any;
1060
+ announces: null;
1061
+ freeze: any;
1062
+ };
1063
+ _declaredOperators: any;
1064
+ get operators(): any;
1065
+ set operators(declared: any);
1066
+ _vocabulary(): string[];
1067
+ get value(): any[] | null;
1068
+ set value(v: any[] | null);
577
1069
  get disabled(): boolean;
578
1070
  set disabled(d: boolean);
579
1071
  }
580
- declare class TextFilter extends Input {
1072
+ /**
1073
+ * An info icon button toggling a popover with a short explanation.
1074
+ *
1075
+ * The marker is the page's `config.icon`, and the `icon` attribute names a
1076
+ * `ful-icon` for the tooltip that means something other than plain information:
1077
+ * a caveat, a warning, a setting. A name the library does not paint is the
1078
+ * page's own, declared as `ful-icon[name='...'] { mask-image: ... }`.
1079
+ *
1080
+ * `describes` is for the tooltip standing in a field: the note becomes part of
1081
+ * the accessible description of that field's control, so it is announced on
1082
+ * reaching the field rather than only on opening the marker, and the marker
1083
+ * leaves the tab order, so a form of hinted fields costs no extra keystrokes to
1084
+ * walk. The marker stays clickable, and stays a tab stop wherever the note was
1085
+ * not taken, a tooltip claiming `describes` outside a field among them: the
1086
+ * stop only goes where something else delivers the content.
1087
+ */
1088
+ declare class Tooltip extends ParsedElement {
1089
+ #private;
1090
+ static slots: boolean;
1091
+ static attributes: string[];
1092
+ static config: {
1093
+ icon: string;
1094
+ };
1095
+ static template: string;
1096
+ render({ slots }: {
1097
+ slots: any;
1098
+ }): void;
1099
+ }
1100
+ export type DialogOutcome = {
1101
+ dismissed: boolean;
1102
+ result: string | null;
1103
+ response: any;
1104
+ };
1105
+ /**
1106
+ * A modal dialog on the native platform, open()/ask() resolving with the
1107
+ * closer's data-result.
1108
+ *
1109
+ * The header carries a close button, as the drawer's does: Escape dismisses a
1110
+ * modal on its own, but nothing says so, and a dialog whose only exit is a key
1111
+ * you have to know about leaves a pointer with nowhere to go. It answers the way
1112
+ * Escape does, with null.
1113
+ *
1114
+ * `requires-answer` is for the dialog that must be answered: the close button is not
1115
+ * rendered and Escape is refused, so the only way out is a button that carries a
1116
+ * result. It has to be both, a close button withheld while Escape still worked
1117
+ * being decoration rather than a rule.
1118
+ *
1119
+ * The chrome is reachable by class as well as by tag, so a plain `<dialog
1120
+ * class="ful-dialog">` written by a page gets the same look whatever its
1121
+ * structure: the tag form matches a direct child, and `ful-dialog-header`,
1122
+ * `ful-dialog-body` and `ful-dialog-footer` match at any depth, which is what a
1123
+ * dialog whose content is wrapped in a form needs.
1124
+ */
1125
+ /**
1126
+ * How a dialog ended: `dismissed` tells a cancel from an answer, `result` carries
1127
+ * the `data-result` of the button that closed it and `response` what a submit
1128
+ * answered with, the one that did not happen being null.
1129
+ * @typedef {{ dismissed: boolean, result: string|null, response: any }} DialogOutcome
1130
+ */
1131
+ declare class Dialog extends ParsedElement {
581
1132
  #private;
1133
+ static attributes: string[];
1134
+ static slots: boolean;
1135
+ static template: string;
1136
+ render({ slots }: {
1137
+ slots: any;
1138
+ }): void;
1139
+ disconnectedCallback(): void;
1140
+ open(): Promise<any>;
1141
+ ask(): Promise<any>;
1142
+ /**
1143
+ * Opens the dialog and waits for the callback, as `ful-drawer`'s does: a
1144
+ * resolved value paints the body (which is returned), a rejection paints the
1145
+ * problems and travels to the caller, and an update superseded by a newer one
1146
+ * paints nothing. The title is the `header` attribute, configuration like the
1147
+ * rest of the dialog's chrome, so what update() owns is the body alone.
1148
+ */
1149
+ update(cb: any): Promise<any>;
1150
+ /**
1151
+ * Re-fires section:requested on the body, open or closed: the explicit
1152
+ * request for a body that wants refreshing. A failed refresh paints its
1153
+ * problems, nothing rejects: update() stays the rejecting call.
1154
+ */
1155
+ refresh(): Promise<any[] | undefined>;
1156
+ close(result: any): void;
1157
+ }
1158
+ /**
1159
+ * A side panel drawer on the native dialog platform, update() owning its
1160
+ * open-deliver cycle.
1161
+ *
1162
+ * The `header` slot is content beside the title, before it: an icon, a badge, a
1163
+ * status. It sits outside the heading rather than in it because `update()` sets
1164
+ * the title through `textContent`, which would take anything nested there with
1165
+ * it.
1166
+ */
1167
+ declare class Drawer extends ParsedElement {
1168
+ #private;
1169
+ static attributes: string[];
1170
+ static slots: boolean;
1171
+ static template: string;
1172
+ render({ slots }: {
1173
+ slots: any;
1174
+ }): void;
1175
+ get title(): any;
1176
+ set title(v: any);
1177
+ /**
1178
+ * Opens the drawer under the given title and waits for the callback: a
1179
+ * resolved value paints the content section (which is returned), a
1180
+ * rejection paints the problems and travels to the caller, and an update
1181
+ * superseded by a newer one paints nothing.
1182
+ */
1183
+ update(title: any, cb: any): Promise<any>;
1184
+ /**
1185
+ * Re-fires section:requested on the content, open or closed: the explicit
1186
+ * request for a body that wants refreshing. A failed refresh paints its
1187
+ * problems, nothing rejects: update() stays the rejecting call.
1188
+ */
1189
+ refresh(): Promise<any[] | undefined>;
1190
+ open(): void;
1191
+ close(): void;
1192
+ }
1193
+ /** A transient feedback region: each show() stacks a toast that retires on its own timer. */
1194
+ declare class Toasts extends ParsedElement {
1195
+ #private;
1196
+ static attributes: string[];
1197
+ connectedCallback(): void;
1198
+ disconnectedCallback(): void;
1199
+ render(): void;
1200
+ /**
1201
+ * Appends a toast carrying the message (a Failure shows its problems'
1202
+ * reasons, one per line), severity picking the theme and the announcement,
1203
+ * the toast retiring through its own timer or its dismiss button.
1204
+ * @param {any} message
1205
+ * @param {any} [options] severity and timeout
1206
+ * @returns {HTMLElement}
1207
+ */
1208
+ show(message: any, options?: any): HTMLElement;
1209
+ }
1210
+ /**
1211
+ * A tab panel: one visible panel at a time, announced through the tab pattern
1212
+ * (a tablist of tab buttons, each panel a tabpanel named by its tab). The tabs
1213
+ * are declared as <tab> elements in the tabs slot, the panels as the slotless
1214
+ * children, paired in order. Entering a panel fires the section:requested
1215
+ * family on it (generic and #index, panels being nameless) and awaits the
1216
+ * answers, so a panel can deliver itself asynchronously.
1217
+ */
1218
+ declare class Tabs extends ParsedElement {
1219
+ #private;
1220
+ static slots: boolean;
582
1221
  static observed: string[];
583
1222
  static template: string;
584
- render(conf: any): void;
585
- get value(): any[] | undefined;
586
- set value(v: any[] | undefined);
1223
+ render({ slots }: {
1224
+ slots: any;
1225
+ }): void;
1226
+ get active(): number;
1227
+ /**
1228
+ * Re-fires the section:requested family on the panel (by index or the
1229
+ * panel element itself), whether active or not: the explicit request for a
1230
+ * content that wants refreshing. A failed refresh paints its problems,
1231
+ * nothing rejects: there is no caller to reject towards.
1232
+ */
1233
+ refresh(ref: any): Promise<any[] | undefined> | undefined;
1234
+ set active(v: number);
1235
+ }
1236
+ /**
1237
+ * An accordion over native details/summary disclosures: the platform carries
1238
+ * the semantics, the keyboard and the toggling, the chrome paints the group.
1239
+ * With the exclusive claim the render assigns one shared name to every panel,
1240
+ * which is the platform's own exclusive grouping: opening one closes the others.
1241
+ */
1242
+ declare class Accordion extends ParsedElement {
1243
+ #private;
1244
+ static slots: boolean;
1245
+ static observed: string[];
1246
+ static template: string;
1247
+ render({ slots }: {
1248
+ slots: any;
1249
+ }): void;
1250
+ get exclusive(): boolean;
1251
+ set exclusive(v: boolean);
587
1252
  }
588
- declare class LocalizationModule {
589
- static t(k: any, ...args: any[]): any;
590
- static tl(k: any, args?: any[]): any;
1253
+ /**
1254
+ * A wizard: a progress of steps over one-of-N sections, the homeinsurance
1255
+ * layout distilled. The steps are declared as <step> elements in the steps
1256
+ * slot, the sections as the slotless children, paired in order; each section
1257
+ * may carry a data-step name, which is what move() answers to. The current
1258
+ * step is the aria-current=step claim, carried in lockstep by the step and
1259
+ * its section: the chrome (including which section is shown) follows the
1260
+ * claim alone, so the markup state and the style can never disagree. The
1261
+ * progress chrome shows the current step alone by default; the progress
1262
+ * attribute picks another shape over the same claims (timeline, dots, none).
1263
+ * Entering a section
1264
+ * fires the section:requested family on it and awaits the answers, so a
1265
+ * section can deliver itself asynchronously; move() resolves when the entered
1266
+ * section is painted, and rejects when its delivery fails.
1267
+ */
1268
+ declare class Wizard extends ParsedElement {
1269
+ #private;
1270
+ static slots: boolean;
1271
+ static observed: string[];
1272
+ static template: string;
1273
+ render({ slots }: {
1274
+ slots: any;
1275
+ }): void;
1276
+ get index(): number;
1277
+ get step(): any;
1278
+ get progress(): any;
1279
+ set progress(v: any);
1280
+ next(): Promise<any[] | undefined> | undefined;
1281
+ prev(): Promise<any[] | undefined> | undefined;
1282
+ move(ref: any): Promise<any[] | undefined> | undefined;
1283
+ /**
1284
+ * Re-fires the section:requested family on the named section (or the
1285
+ * section element itself), whether active or not: the explicit request for a
1286
+ * content that wants refreshing. A failed refresh paints its problems,
1287
+ * nothing rejects: move() stays the rejecting call.
1288
+ */
1289
+ refresh(ref: any): Promise<any[] | undefined> | undefined;
591
1290
  }
1291
+ /**
1292
+ * Registers everything ful provides on a registry: the elements, the loader
1293
+ * components, an http client, and the translations for the configured
1294
+ * language. A page calls `registry.plugin(new Plugin({…})).configure()` once.
1295
+ */
592
1296
  declare class Plugin {
1297
+ #private;
1298
+ /**
1299
+ * @param {{ language?: string, translations?: Record<string, any>, httpClient?: any }} [options]
1300
+ * `language` is fixed for the page: a full BCP-47 tag or a primary subtag,
1301
+ * defaulting to the browser's language. `translations` is a flat
1302
+ * active-language map applied over the built-in translations: reword built-in
1303
+ * keys ('pagination.showing', …) or add your own ('checkout.total', …).
1304
+ * `httpClient` is the client every ful component fetches through, registered
1305
+ * as the `http-client` component: where an unauthorized session goes is an
1306
+ * application decision, so a page that does not want the default's redirect
1307
+ * to '/' builds its own.
1308
+ */
1309
+ constructor(options?: {
1310
+ language?: string;
1311
+ translations?: Record<string, any>;
1312
+ httpClient?: any;
1313
+ });
593
1314
  configure(registry: any): void;
594
1315
  }
595
- export { AsyncEvents, Bindings, Checkbox, Dropdown, Form, FormLoader, Input, InputFile, InputInstant, InputLocalDate, InputLocalTime, Instant, InstantFilter, LocalDate, LocalDateFilter, LocalStorage, LocalizationModule, Pagination, Plugin, RadioGroup, Select, SelectLoader, SessionStorage, SortButton, Spinner, Table, TableSchemaParser, TextFilter, Timing, VersionedLocalStorage, VersionedSessionStorage };
1316
+ export { Accordion, Anchors, AsyncEvents, Bindings, BooleanFilter, Checkbox, Claims, CompareFilter, Dialog, Drawer, Dropdown, Field, Form, FormLoader, Input, InputFile, InputInstant, InputLocalDate, InputLocalTime, Instant, InstantFilter, LocalDate, LocalDateFilter, LocalStorage, NumberFilter, Pagination, Plugin, RadioGroup, Select, SelectLoader, SessionStorage, SortButton, Table, TableLoader, TableSchemaParser, Tabs, TextFilter, Timing, Toasts, Tooltip, VersionedLocalStorage, VersionedSessionStorage, Wizard, describable };
596
1317
 
597
1318
  export as namespace ful;