@optionfactory/fml 9.0.0-rc3 → 9.0.0-rc30

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 (44) hide show
  1. package/README.md +16 -88
  2. package/dist/client-errors.iife.js +40 -49
  3. package/dist/client-errors.iife.js.map +1 -1
  4. package/dist/client-errors.iife.min.js +1 -1
  5. package/dist/client-errors.iife.min.js.map +1 -1
  6. package/dist/custom-elements.json +483 -50
  7. package/dist/fml.css +25 -20
  8. package/dist/fml.css.map +1 -1
  9. package/dist/fml.iife.js +5688 -2542
  10. package/dist/fml.iife.js.map +1 -1
  11. package/dist/fml.iife.min.js +1 -1
  12. package/dist/fml.iife.min.js.map +1 -1
  13. package/dist/ftl.d.mts +398 -227
  14. package/dist/ftl.iife.js +682 -1016
  15. package/dist/ftl.iife.js.map +1 -1
  16. package/dist/ftl.iife.min.js +1 -1
  17. package/dist/ftl.iife.min.js.map +1 -1
  18. package/dist/ftl.min.mjs +1 -1
  19. package/dist/ftl.min.mjs.map +1 -1
  20. package/dist/ftl.mjs +682 -1016
  21. package/dist/ftl.mjs.map +1 -1
  22. package/dist/ful.css +25 -20
  23. package/dist/ful.css.map +1 -1
  24. package/dist/ful.d.mts +3043 -546
  25. package/dist/ful.iife.js +4875 -1387
  26. package/dist/ful.iife.js.map +1 -1
  27. package/dist/ful.iife.min.js +1 -1
  28. package/dist/ful.iife.min.js.map +1 -1
  29. package/dist/ful.min.mjs +1 -1
  30. package/dist/ful.min.mjs.map +1 -1
  31. package/dist/ful.mjs +4873 -1389
  32. package/dist/ful.mjs.map +1 -1
  33. package/dist/httpc.d.mts +143 -123
  34. package/dist/httpc.iife.js +163 -175
  35. package/dist/httpc.iife.js.map +1 -1
  36. package/dist/httpc.iife.min.js +1 -1
  37. package/dist/httpc.iife.min.js.map +1 -1
  38. package/dist/httpc.min.mjs +1 -1
  39. package/dist/httpc.min.mjs.map +1 -1
  40. package/dist/httpc.mjs +163 -175
  41. package/dist/httpc.mjs.map +1 -1
  42. package/dist/vscode.html-custom-data.json +234 -38
  43. package/dist/web-types.json +489 -50
  44. package/package.json +2 -2
@@ -11,14 +11,28 @@
11
11
  "name": "Tooltip",
12
12
  "tagName": "ful-tooltip",
13
13
  "customElement": true,
14
- "description": "An info affordance: a themed icon button toggling a small popover with a short explanation, opened by click and by keyboard like a button, dismissed by Escape or an outside click. placement picks the side the note sits on: bottom (default), top, left or right.",
14
+ "description": "An info affordance: a themed icon button toggling a small popover with a short explanation, opened by click and by keyboard like a button, dismissed by Escape or an outside click. placement picks the side the note sits on: top (default), bottom, left or right.",
15
15
  "attributes": [
16
16
  {
17
17
  "name": "placement",
18
- "description": "Which side of the trigger the note opens on: bottom (the default), top, start or end. The library places the note itself on every platform, so the side is the same everywhere.",
18
+ "description": "Which side of the trigger the note opens on: top (the default), bottom, left or right. Above by default because a note opening downwards covers the control the marker explains. The library places the note itself on every platform, so the side is the same everywhere.",
19
19
  "type": {
20
20
  "text": "string"
21
21
  }
22
+ },
23
+ {
24
+ "name": "icon",
25
+ "description": "The ful-icon the marker shows, for a tooltip meaning something other than plain information. Defaults to the page's Tooltip.config.icon; a name the library does not paint is declared by the page as ful-icon[name='...'] { mask-image: ... }.",
26
+ "type": {
27
+ "text": "string"
28
+ }
29
+ },
30
+ {
31
+ "name": "describes",
32
+ "description": "For a tooltip standing in a field: the note joins the accessible description of that field's control, announced on reaching the field rather than only on opening the marker, and the marker leaves the tab order so a form of hinted fields costs no extra keystrokes to walk. The marker stays clickable, and keeps its tab stop wherever nothing took the note.",
33
+ "type": {
34
+ "text": "boolean"
35
+ }
22
36
  }
23
37
  ],
24
38
  "slots": [
@@ -34,7 +48,7 @@
34
48
  "name": "Dialog",
35
49
  "tagName": "ful-dialog",
36
50
  "customElement": true,
37
- "description": "A modal dialog on the native platform: header, body and buttons, the header attribute naming its heading, opened by any element carrying dialog-target set to its id, or programmatically through open()/ask(), which resolve with the data-result of the button that closed the dialog (null on Escape). Longer explanations belong here, shorter ones in ful-tooltip.",
51
+ "description": "A modal dialog on the native platform: header, body and buttons, the header attribute naming its heading, opened by any element carrying dialog-target set to its id, or programmatically through open()/ask(), which answer with how the dialog ended, or through update(callback), which opens it on a loading state and then shows either what the callback delivered or the problems of a rejection. dismiss(reason) dismisses it as the close button would, refusable and guarded alike, answering whether it closed. Longer explanations belong here, shorter ones in ful-tooltip. Dialog.ask(header, body, buttons) and Dialog.confirm(header, body, labels) ask a question in a transient one, building, showing, answering and removing the element themselves; a confirm's cancel, close and Escape all answer the negative.",
38
52
  "attributes": [
39
53
  {
40
54
  "name": "header",
@@ -42,22 +56,47 @@
42
56
  "type": {
43
57
  "text": "string"
44
58
  }
59
+ },
60
+ {
61
+ "name": "requires-answer",
62
+ "description": "For the dialog that must be answered: the close button is not rendered and Escape is refused, so the only way out is a button carrying a result. Both, since a close button withheld while Escape still worked would be decoration rather than a rule.",
63
+ "type": {
64
+ "text": "boolean"
65
+ }
66
+ },
67
+ {
68
+ "name": "close-on-submit",
69
+ "description": "For the dialog whose answer is a form succeeding rather than a button being pressed: its own form submitting successfully closes it and answers with the response. Opt in, and its own form only, a ful-form the body holds directly, since a ful-table wraps its filters in a form of its own and searching one is not the dialog being answered. Such a dialog renders no acknowledge button of its own, the form's submit being its answer.",
70
+ "type": {
71
+ "text": "boolean"
72
+ }
73
+ },
74
+ {
75
+ "name": "guard-dismiss",
76
+ "description": "For the dialog holding a form the user edits: a dismissal nobody refused, while a ful-form of the dialog under track-changes holds edits not saved yet, first asks the user through Dialog.confirm whether to close and drop them, with the localized dialog.discard texts. Gestures and dismiss() are asked about; close(), a data-result button, close-on-submit and update() are answers or the page deciding, and ask nothing. A second Escape with no interaction in between closes it whatever the user would answer.",
77
+ "type": {
78
+ "text": "boolean"
79
+ }
45
80
  }
46
81
  ],
47
82
  "slots": [
83
+ {
84
+ "name": "header",
85
+ "description": "Content beside the title and before it: an icon, a badge, a status. It sits outside the heading rather than in it, the header attribute setting the heading through text."
86
+ },
48
87
  {
49
88
  "name": "",
50
89
  "description": "The dialog body."
51
90
  },
52
91
  {
53
92
  "name": "buttons",
54
- "description": "Buttons closing the dialog; each carries a data-result that ask() resolves with. Without this slot a localized acknowledge button is shown."
93
+ "description": "Buttons closing the dialog; each carries a data-result that the answer carries back. Without this slot a localized acknowledge button is shown. A dialog closing on its form renders none either way, so the slot is for buttons beside the form, not for suppressing one."
55
94
  }
56
95
  ],
57
96
  "events": [
58
97
  {
59
98
  "name": "close",
60
- "description": "Fired when the dialog closes, carrying the data-result of the button that closed it, or null on Escape; ask() and open() resolve with the same answer, and a dialog leaving the document while open answers its waiters with null.",
99
+ "description": "Fired when the dialog closes, carrying how it ended: dismissed tells a cancel from an answer, result the data-result of the button that closed it, response what a submit answered with. ask() and open() resolve with the same object, and a dialog leaving the document while open answers its waiters with a dismissal.",
61
100
  "type": {
62
101
  "text": "CustomEvent"
63
102
  }
@@ -68,6 +107,13 @@
68
107
  "type": {
69
108
  "text": "CustomEvent"
70
109
  }
110
+ },
111
+ {
112
+ "name": "dialog:dismiss",
113
+ "description": "Fired before the close button, Escape, a backdrop click or dismiss(reason) closes the dialog, with detail.reason (button, escape, backdrop or the one dismiss() was given): cancelable, so preventDefault() keeps it open. Not fired for a data-result button, close-on-submit or close(). A second Escape with no interaction in between closes the dialog whatever the page does, and its dialog:dismiss is then not cancelable.",
114
+ "type": {
115
+ "text": "CustomEvent"
116
+ }
71
117
  }
72
118
  ]
73
119
  },
@@ -76,10 +122,10 @@
76
122
  "name": "Drawer",
77
123
  "tagName": "ful-drawer",
78
124
  "customElement": true,
79
- "description": "A side panel drawer on the native dialog platform: a header with its title (the title attribute, or update()'s own) and close button, and a body that opens in a loading state, then shows either the content delivered by update(title, callback) (or the slotted one, when it is never updated) or the error a rejecting callback carries. placement picks the side, end by default, start its mirror. Any element carrying dialog-target set to its id opens it too.",
125
+ "description": "A side panel drawer on the native dialog platform: a header with its title (the header attribute, or update()'s own) and close button, and a body that shows the slotted content or, under update(header, callback), opens in a loading state and then shows either the content the callback delivered or the error a rejecting callback carries. placement picks the side, end by default, start its mirror. open()/ask() answer with how the drawer ended, as a ful-dialog's do, an ask() on a drawer update() opened waiting for that opening's ending; dismiss(reason) dismisses it as the close button would, refusable and guarded alike, answering whether it closed. Any element carrying dialog-target set to its id opens it too.",
80
126
  "attributes": [
81
127
  {
82
- "name": "title",
128
+ "name": "header",
83
129
  "description": "The drawer's title, shown in its header. Text only, and also what update() re-titles the panel with.",
84
130
  "type": {
85
131
  "text": "string"
@@ -91,6 +137,20 @@
91
137
  "type": {
92
138
  "text": "string"
93
139
  }
140
+ },
141
+ {
142
+ "name": "close-on-submit",
143
+ "description": "For the drawer whose ending is a form succeeding rather than its close button being pressed: the form its content holds directly submitting successfully closes it, the close event carrying the response. Opt in, and its own form only, since a ful-table wraps its filters in a form of its own and searching one is not the drawer finishing.",
144
+ "type": {
145
+ "text": "boolean"
146
+ }
147
+ },
148
+ {
149
+ "name": "guard-dismiss",
150
+ "description": "For the drawer holding a form the user edits: a dismissal nobody refused, while a ful-form of the drawer under track-changes holds edits not saved yet, first asks the user through Dialog.confirm whether to close and drop them, with the localized dialog.discard texts. Gestures and dismiss() are asked about; close(), a data-result button, close-on-submit and update() are answers or the page deciding, and ask nothing. A second Escape with no interaction in between closes it whatever the user would answer.",
151
+ "type": {
152
+ "text": "boolean"
153
+ }
94
154
  }
95
155
  ],
96
156
  "slots": [
@@ -106,7 +166,7 @@
106
166
  "events": [
107
167
  {
108
168
  "name": "close",
109
- "description": "Fired when the drawer closes, by its close button or Escape.",
169
+ "description": "Fired when the drawer closes, carrying how it ended, the same object a ful-dialog answers with: dismissed tells the close button and Escape from an answer, result the data-result of the button, or the argument of close(result), that closed it, and response what a submit answered with under close-on-submit, a save answering with no body at all being a save all the same. ask() and open() resolve with the same object, and a drawer leaving the document while open answers its waiters with a dismissal.",
110
170
  "type": {
111
171
  "text": "CustomEvent"
112
172
  }
@@ -117,15 +177,40 @@
117
177
  "type": {
118
178
  "text": "CustomEvent"
119
179
  }
180
+ },
181
+ {
182
+ "name": "drawer:dismiss",
183
+ "description": "Fired before the close button, Escape, a backdrop click or dismiss(reason) closes the drawer, with detail.reason (button, escape, backdrop or the one dismiss() was given): cancelable, so preventDefault() keeps it open. Not fired for a data-result button, close-on-submit or close(). A second Escape with no interaction in between closes the drawer at once, and its drawer:dismiss is then not cancelable.",
184
+ "type": {
185
+ "text": "CustomEvent"
186
+ }
120
187
  }
121
188
  ]
122
189
  },
190
+ {
191
+ "kind": "class",
192
+ "name": "Menu",
193
+ "tagName": "ful-menu",
194
+ "customElement": true,
195
+ "description": "A menu of commands on the native popover platform: the invoker named by for toggles it, or, without for, one menu serves many invokers and showFor(invoker) opens it beside the one it is for. Light dismiss and Escape come from the browser, and the element adds the menu semantics and the keyboard protocol (roving focus with the arrows, Home and End, type-ahead, Enter and Space to activate, Escape and every close handing the focus back to the invoker). The items are the buttons and links written inside it, kept as they are and given their menuitem role; activation is the item's own click, which the menu only follows by closing.",
196
+ "attributes": [
197
+ {
198
+ "name": "for",
199
+ "description": "The id of the invoker the menu belongs to: it toggles the menu, carries aria-haspopup and aria-expanded, and takes the focus back when the menu closes. Read once at the upgrade, so the invoker must already be in the page by then. Without it the menu is shared, opened by showFor(invoker).",
200
+ "type": {
201
+ "text": "string"
202
+ }
203
+ }
204
+ ],
205
+ "slots": [],
206
+ "events": []
207
+ },
123
208
  {
124
209
  "kind": "class",
125
210
  "name": "Toasts",
126
211
  "tagName": "ful-toasts",
127
212
  "customElement": true,
128
- "description": "A transient feedback region, one per page: each show() (or a show-toast document event carrying the same detail) appends a toast that dismisses itself after its timeout, the element's timeout attribute or five seconds by default, and carries its own dismiss button. severity picks the theme and the announcement, info by default, success, warning and error, the error one announced as an alert; a Failure message shows its problems' reasons.",
213
+ "description": "A transient feedback region, one per page: each show() (or a show-toast document event carrying the same detail) appends a toast that dismisses itself after its timeout, the element's timeout attribute or five seconds by default, and carries its own dismiss button. severity picks the theme and the announcement, info by default, success, warning and error, the error one announced as an alert; a Failure message shows its problems' reasons. The timer holds while the toast is hovered or holds the focus, and action: { label, onClick } renders a button beside the message whose click answers and retires the toast, the same option travelling in the event detail.",
129
214
  "attributes": [
130
215
  {
131
216
  "name": "timeout",
@@ -147,7 +232,7 @@
147
232
  "attributes": [
148
233
  {
149
234
  "name": "active",
150
- "description": "The index of the visible panel, zero based, reflected as the active attribute. Clicks, the arrow keys and the property all move it, each move answering with a change event.",
235
+ "description": "The index of the visible panel, zero based, reflected as the active attribute. Clicks, the arrow keys and the property all move it, each move answering with a tabs:change event.",
151
236
  "type": {
152
237
  "text": "number"
153
238
  }
@@ -165,8 +250,8 @@
165
250
  ],
166
251
  "events": [
167
252
  {
168
- "name": "change",
169
- "description": "Fired with the active index and the previous one whenever the visible panel moves.",
253
+ "name": "tabs:change",
254
+ "description": "Fired with the active index and the previous one whenever the visible panel moves. A name of its own rather than the fields' change: the panels are the host's children, so every native change of a field inside them bubbles through the host under that name.",
170
255
  "type": {
171
256
  "text": "CustomEvent"
172
257
  }
@@ -208,7 +293,7 @@
208
293
  "name": "Wizard",
209
294
  "tagName": "ful-wizard",
210
295
  "customElement": true,
211
- "description": "A wizard: a progress of steps over one-of-N sections. The steps are declared as step elements in the steps slot, the sections as the slotless children, paired in order; each section may carry a data-step name, which is what move() answers to, next() and prev() walk the neighbors, and the current step is the aria-current=step claim carried in lockstep by the step and its section, so the chrome, including which section is shown, follows the claim alone. Each move answers with a change event.",
296
+ "description": "A wizard: a progress of steps over one-of-N sections. The steps are declared as step elements in the steps slot, the sections as the slotless children, paired in order; each section may carry a data-step name, which is what move() answers to, next() and prev() walk the neighbors, and the current step is the aria-current=step claim carried in lockstep by the step and its section, so the chrome, including which section is shown, follows the claim alone. Each move answers with a wizard:change event.",
212
297
  "attributes": [
213
298
  {
214
299
  "name": "progress",
@@ -230,8 +315,8 @@
230
315
  ],
231
316
  "events": [
232
317
  {
233
- "name": "change",
234
- "description": "Fired with the index and the data-step name after next(), prev() or move() land on a different step.",
318
+ "name": "wizard:change",
319
+ "description": "Fired with the index and the data-step name after next(), prev() or move() land on a different step. Named apart from change so the bubbling change of a field inside a step never reaches its listeners.",
235
320
  "type": {
236
321
  "text": "CustomEvent"
237
322
  }
@@ -307,6 +392,20 @@
307
392
  "type": {
308
393
  "text": "string"
309
394
  }
395
+ },
396
+ {
397
+ "name": "track-changes",
398
+ "description": "Keeps track of the edits not saved yet: dirty answers whether a field the user edited since the last commit holds another value, the host matches :state(dirty) and the submit buttons carry a dot while it does. A successful submit commits, and so does the form once its fields have rendered; commit() is for a save of the page's own, and save() submits only while there is something to save, answering whether nothing unsaved is left. A ful-drawer or ful-dialog under guard-dismiss asks before a dismissal drops the edits.",
399
+ "type": {
400
+ "text": "boolean"
401
+ }
402
+ },
403
+ {
404
+ "name": "guard-leave",
405
+ "description": "Asks before the page is left while the form holds edits not saved yet, through the browser's own prompt. Implies track-changes.",
406
+ "type": {
407
+ "text": "boolean"
408
+ }
310
409
  }
311
410
  ],
312
411
  "slots": [],
@@ -320,21 +419,28 @@
320
419
  },
321
420
  {
322
421
  "name": "submit:requested",
323
- "description": "Fired after the submit was accepted, to let a listener resolve the response itself.",
422
+ "description": "Fired after the submit was accepted, to let a listener resolve the response itself. Register it through AsyncEvents.asyncOn: the form awaits only such a listener, and one added with addEventListener is not waited for.",
324
423
  "type": {
325
424
  "text": "CustomEvent"
326
425
  }
327
426
  },
328
427
  {
329
428
  "name": "submit:success",
330
- "description": "Fired with the submitted values and the mapped response.",
429
+ "description": "Fired with the submitted values and the mapped response, once the form has settled: the spinner is released, the buttons are no longer held off and a listener may submit again.",
331
430
  "type": {
332
431
  "text": "CustomEvent"
333
432
  }
334
433
  },
335
434
  {
336
435
  "name": "submit:failure",
337
- "description": "Fired with the exception when the submit fails. The form does not rethrow.",
436
+ "description": "Fired with the exception when the submit fails, once the form has settled: the spinner is released and the problems of a Failure are already shown, so a listener writing errors has the last word. The form does not rethrow: submit() resolves false, as it resolves true after submit:success.",
437
+ "type": {
438
+ "text": "CustomEvent"
439
+ }
440
+ },
441
+ {
442
+ "name": "dirty:change",
443
+ "description": "Fired under track-changes when the form starts or stops holding edits not saved yet, with dirty in the detail.",
338
444
  "type": {
339
445
  "text": "CustomEvent"
340
446
  }
@@ -409,11 +515,11 @@
409
515
  "name": "Input",
410
516
  "tagName": "ful-input",
411
517
  "customElement": true,
412
- "description": "A labelled text input. Use type to pick any native input type, or textarea; keep names the characters that survive a keystroke and reject the ones that do not, the caret staying among the survivors, and the uppercase and trim claims shape the value before it is read; v-type=number decodes the value to a number, blank staying null and a value that does not decode kept as it is, an undeclared type defaulting to number. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only.",
518
+ "description": "A labelled text input. Use type to pick any native input type, the keypad types numeric and decimal, or textarea; keep names the characters that survive a keystroke and reject the ones that do not, the caret staying among the survivors, and the uppercase and trim claims shape the value before it is read; v-type=number decodes the value to a number, blank staying null and a value that does not decode kept as it is, an undeclared type defaulting to number. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only.",
413
519
  "attributes": [
414
520
  {
415
521
  "name": "type",
416
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
522
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
417
523
  "type": {
418
524
  "text": "string"
419
525
  }
@@ -427,7 +533,7 @@
427
533
  },
428
534
  {
429
535
  "name": "keep",
430
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
536
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
431
537
  "type": {
432
538
  "text": "string"
433
539
  }
@@ -453,6 +559,13 @@
453
559
  "text": "boolean"
454
560
  }
455
561
  },
562
+ {
563
+ "name": "unsigned",
564
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
565
+ "type": {
566
+ "text": "boolean"
567
+ }
568
+ },
456
569
  {
457
570
  "name": "autocomplete",
458
571
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -533,7 +646,7 @@
533
646
  "attributes": [
534
647
  {
535
648
  "name": "type",
536
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
649
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
537
650
  "type": {
538
651
  "text": "string"
539
652
  }
@@ -547,7 +660,7 @@
547
660
  },
548
661
  {
549
662
  "name": "keep",
550
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
663
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
551
664
  "type": {
552
665
  "text": "string"
553
666
  }
@@ -573,6 +686,13 @@
573
686
  "text": "boolean"
574
687
  }
575
688
  },
689
+ {
690
+ "name": "unsigned",
691
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
692
+ "type": {
693
+ "text": "boolean"
694
+ }
695
+ },
576
696
  {
577
697
  "name": "autocomplete",
578
698
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -756,7 +876,7 @@
756
876
  "attributes": [
757
877
  {
758
878
  "name": "type",
759
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
879
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
760
880
  "type": {
761
881
  "text": "string"
762
882
  }
@@ -770,7 +890,7 @@
770
890
  },
771
891
  {
772
892
  "name": "keep",
773
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
893
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
774
894
  "type": {
775
895
  "text": "string"
776
896
  }
@@ -796,6 +916,13 @@
796
916
  "text": "boolean"
797
917
  }
798
918
  },
919
+ {
920
+ "name": "unsigned",
921
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
922
+ "type": {
923
+ "text": "boolean"
924
+ }
925
+ },
799
926
  {
800
927
  "name": "autocomplete",
801
928
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -897,7 +1024,7 @@
897
1024
  "attributes": [
898
1025
  {
899
1026
  "name": "type",
900
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
1027
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
901
1028
  "type": {
902
1029
  "text": "string"
903
1030
  }
@@ -911,7 +1038,7 @@
911
1038
  },
912
1039
  {
913
1040
  "name": "keep",
914
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
1041
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
915
1042
  "type": {
916
1043
  "text": "string"
917
1044
  }
@@ -937,6 +1064,13 @@
937
1064
  "text": "boolean"
938
1065
  }
939
1066
  },
1067
+ {
1068
+ "name": "unsigned",
1069
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
1070
+ "type": {
1071
+ "text": "boolean"
1072
+ }
1073
+ },
940
1074
  {
941
1075
  "name": "autocomplete",
942
1076
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1038,7 +1172,7 @@
1038
1172
  "attributes": [
1039
1173
  {
1040
1174
  "name": "type",
1041
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
1175
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
1042
1176
  "type": {
1043
1177
  "text": "string"
1044
1178
  }
@@ -1052,7 +1186,7 @@
1052
1186
  },
1053
1187
  {
1054
1188
  "name": "keep",
1055
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
1189
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
1056
1190
  "type": {
1057
1191
  "text": "string"
1058
1192
  }
@@ -1078,6 +1212,13 @@
1078
1212
  "text": "boolean"
1079
1213
  }
1080
1214
  },
1215
+ {
1216
+ "name": "unsigned",
1217
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
1218
+ "type": {
1219
+ "text": "boolean"
1220
+ }
1221
+ },
1081
1222
  {
1082
1223
  "name": "autocomplete",
1083
1224
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1260,7 +1401,7 @@
1260
1401
  },
1261
1402
  {
1262
1403
  "name": "autoload",
1263
- "description": "Loads the first page while upgrading, instead of waiting for a reload(). The load is not awaited, so a slow or failing loader cannot hold up the page.",
1404
+ "description": "Loads the first page while upgrading, instead of waiting for a reload(). With a filters slot the load goes through the filter form's submit, so its submit listeners shape it as they shape the later loads. The load is not awaited, so a slow or failing loader cannot hold up the page.",
1264
1405
  "type": {
1265
1406
  "text": "boolean"
1266
1407
  }
@@ -1271,6 +1412,20 @@
1271
1412
  "type": {
1272
1413
  "text": "number"
1273
1414
  }
1415
+ },
1416
+ {
1417
+ "name": "src",
1418
+ "description": "The url the default loader asks for rows; without it the table loads from an in-memory loader fed through withLoader. Stays live: writing it builds the loader again and reloads from the first page, keeping the sort and the filters.",
1419
+ "type": {
1420
+ "text": "string"
1421
+ }
1422
+ },
1423
+ {
1424
+ "name": "method",
1425
+ "description": "The http method the default loader sends, GET by default. Stays live, as src does.",
1426
+ "type": {
1427
+ "text": "string"
1428
+ }
1274
1429
  }
1275
1430
  ],
1276
1431
  "slots": [
@@ -1282,12 +1437,31 @@
1282
1437
  "name": "caption",
1283
1438
  "description": "The caption of the table."
1284
1439
  },
1440
+ {
1441
+ "name": "empty",
1442
+ "description": "Shown in place of the rows when a load returns none, replacing the localized default message. Rendered per load in the rows' own scope, so its expressions read schema, pageRequest, filterRequest and pageResponse: an empty state can tell nothing-there from a filter that matched nothing."
1443
+ },
1285
1444
  {
1286
1445
  "name": "footer",
1287
1446
  "description": "Content rendered in the table footer."
1288
1447
  }
1289
1448
  ],
1290
- "events": []
1449
+ "events": [
1450
+ {
1451
+ "name": "load:success",
1452
+ "description": "Fired once a load has settled, after the rows are in place, the elements in them have rendered and the busy state is gone, carrying the page response and the three requests that asked for it. Not fired for a load a newer one superseded, which owns nothing.",
1453
+ "type": {
1454
+ "text": "CustomEvent"
1455
+ }
1456
+ },
1457
+ {
1458
+ "name": "load:failure",
1459
+ "description": "Fired when a load rejects, after the error row is shown, carrying the exception and the three requests. Telling this from an empty result is what the aria-busy attribute alone cannot do.",
1460
+ "type": {
1461
+ "text": "CustomEvent"
1462
+ }
1463
+ }
1464
+ ]
1291
1465
  },
1292
1466
  {
1293
1467
  "kind": "class",
@@ -1371,7 +1545,7 @@
1371
1545
  "attributes": [
1372
1546
  {
1373
1547
  "name": "type",
1374
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
1548
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
1375
1549
  "type": {
1376
1550
  "text": "string"
1377
1551
  }
@@ -1385,7 +1559,7 @@
1385
1559
  },
1386
1560
  {
1387
1561
  "name": "keep",
1388
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
1562
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
1389
1563
  "type": {
1390
1564
  "text": "string"
1391
1565
  }
@@ -1411,6 +1585,13 @@
1411
1585
  "text": "boolean"
1412
1586
  }
1413
1587
  },
1588
+ {
1589
+ "name": "unsigned",
1590
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
1591
+ "type": {
1592
+ "text": "boolean"
1593
+ }
1594
+ },
1414
1595
  {
1415
1596
  "name": "autocomplete",
1416
1597
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1418,6 +1599,13 @@
1418
1599
  "text": "string"
1419
1600
  }
1420
1601
  },
1602
+ {
1603
+ "name": "operator",
1604
+ "description": "Fixes the operator for the element's life: no menu and no button render, and every tuple carries it. The plural is the menu's whitelist; declaring both warns, the singular winning, and an unknown name warns and pins the filter's default.",
1605
+ "type": {
1606
+ "text": "string"
1607
+ }
1608
+ },
1421
1609
  {
1422
1610
  "name": "disabled",
1423
1611
  "description": "The field's own disabled claim: the control is disabled and the field is left out of the submitted values, composed with a disabled fieldset ancestry. The property reflects the claim only, matches(':disabled') tells the effective state.",
@@ -1498,7 +1686,7 @@
1498
1686
  "attributes": [
1499
1687
  {
1500
1688
  "name": "type",
1501
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
1689
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
1502
1690
  "type": {
1503
1691
  "text": "string"
1504
1692
  }
@@ -1512,7 +1700,7 @@
1512
1700
  },
1513
1701
  {
1514
1702
  "name": "keep",
1515
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
1703
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
1516
1704
  "type": {
1517
1705
  "text": "string"
1518
1706
  }
@@ -1538,6 +1726,13 @@
1538
1726
  "text": "boolean"
1539
1727
  }
1540
1728
  },
1729
+ {
1730
+ "name": "unsigned",
1731
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
1732
+ "type": {
1733
+ "text": "boolean"
1734
+ }
1735
+ },
1541
1736
  {
1542
1737
  "name": "autocomplete",
1543
1738
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1545,6 +1740,13 @@
1545
1740
  "text": "string"
1546
1741
  }
1547
1742
  },
1743
+ {
1744
+ "name": "operator",
1745
+ "description": "Fixes the operator for the element's life: no menu and no button render, and every tuple carries it. The plural is the menu's whitelist; declaring both warns, the singular winning, and an unknown name warns and pins the filter's default.",
1746
+ "type": {
1747
+ "text": "string"
1748
+ }
1749
+ },
1548
1750
  {
1549
1751
  "name": "disabled",
1550
1752
  "description": "The field's own disabled claim: the control is disabled and the field is left out of the submitted values, composed with a disabled fieldset ancestry. The property reflects the claim only, matches(':disabled') tells the effective state.",
@@ -1625,7 +1827,7 @@
1625
1827
  "attributes": [
1626
1828
  {
1627
1829
  "name": "type",
1628
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
1830
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
1629
1831
  "type": {
1630
1832
  "text": "string"
1631
1833
  }
@@ -1639,7 +1841,7 @@
1639
1841
  },
1640
1842
  {
1641
1843
  "name": "keep",
1642
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
1844
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
1643
1845
  "type": {
1644
1846
  "text": "string"
1645
1847
  }
@@ -1665,6 +1867,13 @@
1665
1867
  "text": "boolean"
1666
1868
  }
1667
1869
  },
1870
+ {
1871
+ "name": "unsigned",
1872
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
1873
+ "type": {
1874
+ "text": "boolean"
1875
+ }
1876
+ },
1668
1877
  {
1669
1878
  "name": "autocomplete",
1670
1879
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1672,6 +1881,13 @@
1672
1881
  "text": "string"
1673
1882
  }
1674
1883
  },
1884
+ {
1885
+ "name": "operator",
1886
+ "description": "Fixes the operator for the element's life: no menu and no button render, and every tuple carries it. The plural is the menu's whitelist; declaring both warns, the singular winning, and an unknown name warns and pins the filter's default.",
1887
+ "type": {
1888
+ "text": "string"
1889
+ }
1890
+ },
1675
1891
  {
1676
1892
  "name": "disabled",
1677
1893
  "description": "The field's own disabled claim: the control is disabled and the field is left out of the submitted values, composed with a disabled fieldset ancestry. The property reflects the claim only, matches(':disabled') tells the effective state.",
@@ -1819,11 +2035,11 @@
1819
2035
  "name": "TextFilter",
1820
2036
  "tagName": "ful-filter-text",
1821
2037
  "customElement": true,
1822
- "description": "A ful-table filter over text, with an operator such as CONTAINS or STARTS_WITH and a case sensitivity. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only. A multiple ful-select used as a filter emits the bare value array the in-list annotations expect.",
2038
+ "description": "A ful-table filter over text, with an operator such as CONTAINS or STARTS_WITH and a case sensitivity. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only.",
1823
2039
  "attributes": [
1824
2040
  {
1825
2041
  "name": "type",
1826
- "description": "Any native input type, or the literal textarea to render one. Defaults to number under v-type=number, and a declared type wins.",
2042
+ "description": "Any native input type, the literal textarea to render one, or numeric and decimal, which render a text input carrying that inputmode and filter what can be typed: numeric takes digits and a leading minus, decimal one separator as well, answering it as a dot whatever the keyboard offered. Neither enforces min, max or step, which the native number type still does. Defaults to number under v-type=number, and a declared type wins.",
1827
2043
  "type": {
1828
2044
  "text": "string"
1829
2045
  }
@@ -1837,7 +2053,7 @@
1837
2053
  },
1838
2054
  {
1839
2055
  "name": "keep",
1840
- "description": "A regular expression naming the characters that survive a keystroke, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class.",
2056
+ "description": "A regular expression naming what survives: on every input event the whole value is filtered to its matches, concatenated, so keep=\"[0-9]\" is digits only. It matches rather than negating, so it takes a pattern and not only a character class, and the pattern must match each partial value typed on the way to a complete one.",
1841
2057
  "type": {
1842
2058
  "text": "string"
1843
2059
  }
@@ -1863,6 +2079,13 @@
1863
2079
  "text": "boolean"
1864
2080
  }
1865
2081
  },
2082
+ {
2083
+ "name": "unsigned",
2084
+ "description": "Refuses the leading minus a numeric or decimal field otherwise takes. It narrows the type's own filter rather than replacing it, so a decimal still keeps one separator and still answers with a dot. Meaningless on any other type, where the sign is the native control's business, and a declared keep or reject still outranks it.",
2085
+ "type": {
2086
+ "text": "boolean"
2087
+ }
2088
+ },
1866
2089
  {
1867
2090
  "name": "autocomplete",
1868
2091
  "description": "The autofill token the browser classifies the control by, one of the names the html autocomplete grammar defines (name, given-name, street-address, postal-code, one-time-code, off, ...). It is set on the control itself because the control carries form=\"\", which leaves it without a form owner to inherit a form-wide setting from. Read once at the upgrade. A value outside the grammar reads as on, so an identifier of your own does not switch autofill off.",
@@ -1870,6 +2093,20 @@
1870
2093
  "text": "string"
1871
2094
  }
1872
2095
  },
2096
+ {
2097
+ "name": "operator",
2098
+ "description": "Fixes the operator for the element's life: no menu and no button render, and every tuple carries it. The plural is the menu's whitelist; declaring both warns, the singular winning, and an unknown name warns and pins the filter's default.",
2099
+ "type": {
2100
+ "text": "string"
2101
+ }
2102
+ },
2103
+ {
2104
+ "name": "sensitivity",
2105
+ "description": "Fixes the case sensitivity for the element's life, on the operator's terms: the button leaves and every tuple carries it.",
2106
+ "type": {
2107
+ "text": "string"
2108
+ }
2109
+ },
1873
2110
  {
1874
2111
  "name": "disabled",
1875
2112
  "description": "The field's own disabled claim: the control is disabled and the field is left out of the submitted values, composed with a disabled fieldset ancestry. The property reflects the claim only, matches(':disabled') tells the effective state.",
@@ -1950,10 +2187,10 @@
1950
2187
  },
1951
2188
  {
1952
2189
  "kind": "class",
1953
- "name": "Select",
1954
- "tagName": "ful-select",
2190
+ "name": "InFilter",
2191
+ "tagName": "ful-filter-in",
1955
2192
  "customElement": true,
1956
- "description": "A combobox backed by a loader that acts like a select: the field mirrors the label of a single selection, clicking anywhere on it toggles the dropdown, which opens highlighting the current selection, and Home, End, PageUp, PageDown and Alt+arrows navigate it. A multiple selection renders as ful-badge chips. Without src the slotted options are the vocabulary; with src the options are fetched once (method, POST by default, preload fetching them while upgrading, revision caching them in local storage) or asked per query under mode=chunked, the response shaped through the k-expr/l-expr/d-expr/m-expr expressions or a response-mapper component, and every key coerced as k-type declares. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only.",
2193
+ "description": "A ful-table filter over set membership, answering for both of data-jpa's set annotations: InEnum and InList take the same array of values and no operator, differing only in what the server converts them to. The vocabulary comes from wherever a select's does, slotted options or a loader, and the value is an array whether one key was chosen or several, an empty selection contributing nothing rather than an empty array. It picks one key unless multiple is declared, as a ful-select does.",
1957
2194
  "attributes": [
1958
2195
  {
1959
2196
  "name": "name",
@@ -1971,21 +2208,187 @@
1971
2208
  },
1972
2209
  {
1973
2210
  "name": "k-type",
1974
- "description": "How a key coerces when it arrives from the response or from the value attribute: number, string or bool.",
2211
+ "description": "How a key coerces when it arrives from the response or from the value attribute: number, string or boolean.",
1975
2212
  "type": {
1976
2213
  "text": "string"
1977
2214
  }
1978
2215
  },
2216
+ {
2217
+ "name": "mode",
2218
+ "description": "chunked asks the endpoint per query instead of fetching the vocabulary once, for a list too large to hold.",
2219
+ "type": {
2220
+ "text": "string"
2221
+ }
2222
+ },
2223
+ {
2224
+ "name": "preload",
2225
+ "description": "Fetches the vocabulary while the element upgrades rather than on first use. The field paints immediately either way; the options arrive when they arrive.",
2226
+ "type": {
2227
+ "text": "boolean"
2228
+ }
2229
+ },
2230
+ {
2231
+ "name": "revision",
2232
+ "description": "Caches the fetched vocabulary in local storage under this revision; a load under a different one is a miss that evicts the entry. It is the cache's namespace, so a vocabulary that differs per user wants the principal in it. Left valueless, the revision the registry's 'revision' component answers is used, so a page states its build once instead of every element repeating it.",
2233
+ "type": {
2234
+ "text": "string"
2235
+ }
2236
+ },
2237
+ {
2238
+ "name": "k-expr",
2239
+ "description": "The expression yielding an option's key, evaluated against each row of the response. Set it together with l-expr to shape a response without a mapper component.",
2240
+ "type": {
2241
+ "text": "string"
2242
+ }
2243
+ },
2244
+ {
2245
+ "name": "l-expr",
2246
+ "description": "The expression yielding an option's label, evaluated against each row of the response.",
2247
+ "type": {
2248
+ "text": "string"
2249
+ }
2250
+ },
2251
+ {
2252
+ "name": "d-expr",
2253
+ "description": "The expression yielding the rows from the response body; the body itself when absent.",
2254
+ "type": {
2255
+ "text": "string"
2256
+ }
2257
+ },
2258
+ {
2259
+ "name": "m-expr",
2260
+ "description": "The expression yielding an option's metadata, evaluated against each row; the whole row when absent.",
2261
+ "type": {
2262
+ "text": "string"
2263
+ }
2264
+ },
2265
+ {
2266
+ "name": "response-mapper",
2267
+ "description": "The registered component name that turns a response into { key, label, metadata } entries. The k-expr/l-expr pair takes precedence; without either, the response is read as positional rows.",
2268
+ "type": {
2269
+ "text": "string"
2270
+ }
2271
+ },
2272
+ {
2273
+ "name": "operator",
2274
+ "description": "A fixed operator sent in front of the chosen keys, for the field a compare reads rather than a set: absent the value is the bare array an InEnum or an InList takes, present it is [operator, ...keys]. No menu is rendered either way, the operator being the author naming the server's comparison rather than a choice offered to whoever is filtering. The criterion reports it, so a chip can show it.",
2275
+ "type": {
2276
+ "text": "string"
2277
+ }
2278
+ },
2279
+ {
2280
+ "name": "disabled",
2281
+ "description": "The field's own disabled claim: the control is disabled and the field is left out of the submitted values, composed with a disabled fieldset ancestry. The property reflects the claim only, matches(':disabled') tells the effective state.",
2282
+ "type": {
2283
+ "text": "boolean"
2284
+ }
2285
+ },
2286
+ {
2287
+ "name": "readonly",
2288
+ "description": "Renders the control but does not let it be edited. A readonly field still contributes its value to the form.",
2289
+ "type": {
2290
+ "text": "boolean"
2291
+ }
2292
+ },
2293
+ {
2294
+ "name": "required",
2295
+ "description": "Marks the field as required for assistive technologies and shows the required marker on its label.",
2296
+ "type": {
2297
+ "text": "boolean"
2298
+ }
2299
+ },
2300
+ {
2301
+ "name": "value",
2302
+ "description": "Comma separated list of the selected keys. Empty contributes nothing, so the table drops the filter rather than sending an empty set.",
2303
+ "type": {
2304
+ "text": "string"
2305
+ }
2306
+ },
2307
+ {
2308
+ "name": "multiple",
2309
+ "description": "Always on for this element: a set of one is still a set, and a single selection would answer a bare key where the filter request wants an array.",
2310
+ "type": {
2311
+ "text": "boolean"
2312
+ }
2313
+ },
2314
+ {
2315
+ "name": "item-list",
2316
+ "description": "Shows the selection as a ful-item-list under the control. For a multiple select the list replaces the ful-badge chips, which it hides; a single select keeps its label in the field as well.",
2317
+ "type": {
2318
+ "text": "boolean"
2319
+ }
2320
+ },
1979
2321
  {
1980
2322
  "name": "src",
1981
- "description": "The url the vocabulary is fetched from. Without it the slotted <option> elements are the whole vocabulary, held in memory.",
2323
+ "description": "The url the vocabulary is fetched from. Without it the slotted <option> elements are the whole vocabulary, held in memory. Stays live: writing it builds the loader again and reloads as reload() does, dropping a selected key the new vocabulary does not know.",
1982
2324
  "type": {
1983
2325
  "text": "string"
1984
2326
  }
1985
2327
  },
1986
2328
  {
1987
2329
  "name": "method",
1988
- "description": "The method the vocabulary is fetched with; POST when absent.",
2330
+ "description": "The method the vocabulary is fetched with; POST when absent. Stays live, as src does.",
2331
+ "type": {
2332
+ "text": "string"
2333
+ }
2334
+ }
2335
+ ],
2336
+ "slots": [
2337
+ {
2338
+ "name": "",
2339
+ "description": "The label of the field."
2340
+ },
2341
+ {
2342
+ "name": "info",
2343
+ "description": "Extra content rendered next to the label, for a hint or a help icon."
2344
+ },
2345
+ {
2346
+ "name": "before",
2347
+ "description": "An addon rendered inside the input group, before the control."
2348
+ },
2349
+ {
2350
+ "name": "after",
2351
+ "description": "An addon rendered inside the input group, after the control."
2352
+ },
2353
+ {
2354
+ "name": "dropdown",
2355
+ "description": "Replaces the template used to render the options."
2356
+ }
2357
+ ],
2358
+ "events": [
2359
+ {
2360
+ "name": "change",
2361
+ "description": "Fired with the selected keys, or undefined when nothing is picked.",
2362
+ "type": {
2363
+ "text": "CustomEvent"
2364
+ }
2365
+ }
2366
+ ]
2367
+ },
2368
+ {
2369
+ "kind": "class",
2370
+ "name": "Select",
2371
+ "tagName": "ful-select",
2372
+ "customElement": true,
2373
+ "description": "A combobox backed by a loader that acts like a select: the field mirrors the label of a single selection, clicking anywhere on it toggles the dropdown, which opens highlighting the current selection, and Home, End, PageUp, PageDown and Alt+arrows navigate it. A multiple selection renders as ful-badge chips. Without src the slotted options are the vocabulary; with src the options are fetched once (method, POST by default, preload fetching them while upgrading, revision caching them in local storage) or asked per query under mode=chunked, the response shaped through the k-expr/l-expr/d-expr/m-expr expressions or a response-mapper component, and every key coerced as k-type declares. Disabled follows native semantics: the attribute is the field's own claim, honored together with a disabled fieldset ancestry through :disabled, while the property reflects the claim only.",
2374
+ "attributes": [
2375
+ {
2376
+ "name": "name",
2377
+ "description": "The field name the surrounding form submits the selection under.",
2378
+ "type": {
2379
+ "text": "string"
2380
+ }
2381
+ },
2382
+ {
2383
+ "name": "loader",
2384
+ "description": "The registered component name the select loads its vocabulary through; loaders:select when absent.",
2385
+ "type": {
2386
+ "text": "string"
2387
+ }
2388
+ },
2389
+ {
2390
+ "name": "k-type",
2391
+ "description": "How a key coerces when it arrives from the response or from the value attribute: number, string or boolean.",
1989
2392
  "type": {
1990
2393
  "text": "string"
1991
2394
  }
@@ -2006,7 +2409,7 @@
2006
2409
  },
2007
2410
  {
2008
2411
  "name": "revision",
2009
- "description": "Caches the fetched vocabulary in local storage under this revision; a load under a different one is a miss that evicts the entry. It is the cache's namespace, so a vocabulary that differs per user wants the principal in it.",
2412
+ "description": "Caches the fetched vocabulary in local storage under this revision; a load under a different one is a miss that evicts the entry. It is the cache's namespace, so a vocabulary that differs per user wants the principal in it. Left valueless, the revision the registry's 'revision' component answers is used, so a page states its build once instead of every element repeating it.",
2010
2413
  "type": {
2011
2414
  "text": "string"
2012
2415
  }
@@ -2069,7 +2472,7 @@
2069
2472
  },
2070
2473
  {
2071
2474
  "name": "value",
2072
- "description": "The selected keys, comma separated, whether or not the select is multiple. A key given here is trimmed and cannot contain a comma; assign such a key through the property instead. The property answers a key for a single select and an array for a multiple one.",
2475
+ "description": "The selected keys, comma separated, whether or not the select is multiple. A key given here is trimmed and cannot contain a comma; assign such a key through the property instead. The property answers a key for a single select and an array for a multiple one. A single select reads a present but empty attribute as the empty key, the one an <option value=\"\"> carries, where an absent attribute means no selection; a multiple select reads it as no keys.",
2073
2476
  "type": {
2074
2477
  "text": "string"
2075
2478
  }
@@ -2083,10 +2486,24 @@
2083
2486
  },
2084
2487
  {
2085
2488
  "name": "item-list",
2086
- "description": "Shows the selection as a ful-item-list under the control as well, in addition to the field itself (the label for a single select, the ful-badge chips when multiple).",
2489
+ "description": "Shows the selection as a ful-item-list under the control. For a multiple select the list replaces the ful-badge chips, which it hides; a single select keeps its label in the field as well.",
2087
2490
  "type": {
2088
2491
  "text": "boolean"
2089
2492
  }
2493
+ },
2494
+ {
2495
+ "name": "src",
2496
+ "description": "The url the vocabulary is fetched from. Without it the slotted <option> elements are the whole vocabulary, held in memory. Stays live: writing it builds the loader again and reloads as reload() does, dropping a selected key the new vocabulary does not know.",
2497
+ "type": {
2498
+ "text": "string"
2499
+ }
2500
+ },
2501
+ {
2502
+ "name": "method",
2503
+ "description": "The method the vocabulary is fetched with; POST when absent. Stays live, as src does.",
2504
+ "type": {
2505
+ "text": "string"
2506
+ }
2090
2507
  }
2091
2508
  ],
2092
2509
  "slots": [
@@ -2126,7 +2543,7 @@
2126
2543
  "name": "Dropdown",
2127
2544
  "tagName": "ful-dropdown",
2128
2545
  "customElement": true,
2129
- "description": "The options popup of a ful-select, with a localized no-results message when the search matches nothing. Rarely used on its own.",
2546
+ "description": "The options popup of a ful-select, with a localized no-results message when the search matches nothing. An entry whose metadata.disabled is truthy is refused: its row carries aria-disabled and metadata.reason as its title, the arrows and Home/End walk past it, and a click on it changes nothing. Rarely used on its own.",
2130
2547
  "attributes": [
2131
2548
  {
2132
2549
  "name": "listbox",
@@ -2180,6 +2597,14 @@
2180
2597
  "module": "dist/fml.mjs"
2181
2598
  }
2182
2599
  },
2600
+ {
2601
+ "kind": "custom-element-definition",
2602
+ "name": "ful-menu",
2603
+ "declaration": {
2604
+ "name": "Menu",
2605
+ "module": "dist/fml.mjs"
2606
+ }
2607
+ },
2183
2608
  {
2184
2609
  "kind": "custom-element-definition",
2185
2610
  "name": "ful-toasts",
@@ -2356,6 +2781,14 @@
2356
2781
  "module": "dist/fml.mjs"
2357
2782
  }
2358
2783
  },
2784
+ {
2785
+ "kind": "custom-element-definition",
2786
+ "name": "ful-filter-in",
2787
+ "declaration": {
2788
+ "name": "InFilter",
2789
+ "module": "dist/fml.mjs"
2790
+ }
2791
+ },
2359
2792
  {
2360
2793
  "kind": "custom-element-definition",
2361
2794
  "name": "ful-select",