@fusion.dev/helix-headless 0.12.2 → 0.13.0

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.
package/types/jsx.d.ts CHANGED
@@ -55,6 +55,7 @@ import type {
55
55
  HelixHeadlessDrilldownItem,
56
56
  HelixHeadlessEmpty,
57
57
  HelixHeadlessFileInput,
58
+ HelixHeadlessFilterInput,
58
59
  HelixHeadlessFormatDate,
59
60
  HelixHeadlessHeatmap,
60
61
  HelixHeadlessIcon,
@@ -3022,32 +3023,6 @@ message belongs. */
3022
3023
  "loading-text"?: (HelixHeadlessCombobox["loadingText"]) | undefined;
3023
3024
  /** What the list says while they are on their way. */
3024
3025
  loadingText?: (HelixHeadlessCombobox["loadingText"]) | undefined;
3025
- /** How many tags to draw before the rest become a count. `multiple` only.
3026
-
3027
- `0` is all of them, and is the default: a cap that guesses is worse than no
3028
- cap, because the number that fits depends on the width of the field and the
3029
- length of what is in it, neither of which this element knows. What a cap is
3030
- genuinely for is a field in a row or a table cell, where a set of twelve
3031
- choices would push everything below it down a line at a time.
3032
-
3033
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
3034
- on, where a row that silently stops is a field that appears to have lost
3035
- what was put in it. Date Input and Time Input carry the same property and
3036
- the same reasoning. */
3037
- "max-tags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3038
- /** How many tags to draw before the rest become a count. `multiple` only.
3039
-
3040
- `0` is all of them, and is the default: a cap that guesses is worse than no
3041
- cap, because the number that fits depends on the width of the field and the
3042
- length of what is in it, neither of which this element knows. What a cap is
3043
- genuinely for is a field in a row or a table cell, where a set of twelve
3044
- choices would push everything below it down a line at a time.
3045
-
3046
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
3047
- on, where a row that silently stops is a field that appears to have lost
3048
- what was put in it. Date Input and Time Input carry the same property and
3049
- the same reasoning. */
3050
- maxTags?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3051
3026
  /** Whether more than one option can be chosen.
3052
3027
 
3053
3028
  The list already does the work: `value` comes apart on commas, a press
@@ -3087,6 +3062,10 @@ the resolved state for stylesheets, which is what the mirror is for. */
3087
3062
  "default-open"?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
3088
3063
  /** Initial open state for uncontrolled use, where nothing declared one. */
3089
3064
  defaultOpen?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
3065
+ /** How many tokens to show before the rest become a count. */
3066
+ "max-tags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3067
+ /** How many tokens to show before the rest become a count. */
3068
+ maxTags?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3090
3069
  /** The value the markup declared, which is where a reset returns to. */
3091
3070
  "default-value"?: (HelixHeadlessCombobox["defaultValue"]) | undefined;
3092
3071
  /** The value the markup declared, which is where a reset returns to. */
@@ -3198,32 +3177,6 @@ message belongs. */
3198
3177
  "attr:loading-text"?: (HelixHeadlessCombobox["loadingText"]) | undefined;
3199
3178
  /** What the list says while they are on their way. */
3200
3179
  "prop:loadingText"?: (HelixHeadlessCombobox["loadingText"]) | undefined;
3201
- /** How many tags to draw before the rest become a count. `multiple` only.
3202
-
3203
- `0` is all of them, and is the default: a cap that guesses is worse than no
3204
- cap, because the number that fits depends on the width of the field and the
3205
- length of what is in it, neither of which this element knows. What a cap is
3206
- genuinely for is a field in a row or a table cell, where a set of twelve
3207
- choices would push everything below it down a line at a time.
3208
-
3209
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
3210
- on, where a row that silently stops is a field that appears to have lost
3211
- what was put in it. Date Input and Time Input carry the same property and
3212
- the same reasoning. */
3213
- "attr:max-tags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3214
- /** How many tags to draw before the rest become a count. `multiple` only.
3215
-
3216
- `0` is all of them, and is the default: a cap that guesses is worse than no
3217
- cap, because the number that fits depends on the width of the field and the
3218
- length of what is in it, neither of which this element knows. What a cap is
3219
- genuinely for is a field in a row or a table cell, where a set of twelve
3220
- choices would push everything below it down a line at a time.
3221
-
3222
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
3223
- on, where a row that silently stops is a field that appears to have lost
3224
- what was put in it. Date Input and Time Input carry the same property and
3225
- the same reasoning. */
3226
- "prop:maxTags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3227
3180
  /** Whether more than one option can be chosen.
3228
3181
 
3229
3182
  The list already does the work: `value` comes apart on commas, a press
@@ -3263,6 +3216,10 @@ the resolved state for stylesheets, which is what the mirror is for. */
3263
3216
  "bool:default-open"?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
3264
3217
  /** Initial open state for uncontrolled use, where nothing declared one. */
3265
3218
  "prop:defaultOpen"?: (HelixHeadlessCombobox["defaultOpen"]) | undefined;
3219
+ /** How many tokens to show before the rest become a count. */
3220
+ "attr:max-tags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3221
+ /** How many tokens to show before the rest become a count. */
3222
+ "prop:maxTags"?: (HelixHeadlessCombobox["maxTags"]) | undefined;
3266
3223
  /** The value the markup declared, which is where a reset returns to. */
3267
3224
  "attr:default-value"?: (HelixHeadlessCombobox["defaultValue"]) | undefined;
3268
3225
  /** The value the markup declared, which is where a reset returns to. */
@@ -5808,6 +5765,171 @@ Here rather than on each control. */
5808
5765
  textContent?: (string | number) | undefined;
5809
5766
  };
5810
5767
 
5768
+ /** `HelixHeadlessFilterInput` component event */
5769
+ export type HelixHeadlessFilterInputElementEvent<E = Event> = TypedEvent<
5770
+ HelixHeadlessFilterInput,
5771
+ E
5772
+ >;
5773
+ /** `helix-before-change` event type */
5774
+ export type HelixHeadlessFilterInputHelixBeforeChangeElementEvent =
5775
+ HelixHeadlessFilterInputElementEvent<HelixBeforeChangeEvent>;
5776
+
5777
+ export type HelixHeadlessFilterInputProps = {
5778
+ /** Whether the field offers a button that empties it.
5779
+
5780
+ The text only. The tokens are the consumer's markup and this element is not
5781
+ entitled to take them out of the document, which is the same reason
5782
+ `hideOverflow` marks the ones over the cap `hidden` rather than removing
5783
+ them. */
5784
+ clearable?: (HelixHeadlessFilterInput["clearable"]) | undefined;
5785
+ /** What the clear button is called, since an icon has no name of its own. */
5786
+ "clear-label"?: (HelixHeadlessFilterInput["clearLabel"]) | undefined;
5787
+ /** What the clear button is called, since an icon has no name of its own. */
5788
+ clearLabel?: (HelixHeadlessFilterInput["clearLabel"]) | undefined;
5789
+ /** Shown while the field is empty.
5790
+
5791
+ Not a label: it goes when typing starts. */
5792
+ placeholder?: (HelixHeadlessFilterInput["placeholder"]) | undefined;
5793
+ /** How many tokens to show before the rest become a count. */
5794
+ "max-tags"?: (HelixHeadlessFilterInput["maxTags"]) | undefined;
5795
+ /** How many tokens to show before the rest become a count. */
5796
+ maxTags?: (HelixHeadlessFilterInput["maxTags"]) | undefined;
5797
+ /** The value the markup declared, which is where a reset returns to. */
5798
+ "default-value"?: (HelixHeadlessFilterInput["defaultValue"]) | undefined;
5799
+ /** The value the markup declared, which is where a reset returns to. */
5800
+ defaultValue?: (HelixHeadlessFilterInput["defaultValue"]) | undefined;
5801
+ /** What the control holds now, and what its form submits.
5802
+
5803
+ One property, not two, so `input.value` answers the question anyone
5804
+ asking it meant. Writing always applies; `<helix-input value="x">` is the
5805
+ same statement in markup, and `default-value` is how markup seeds a value
5806
+ a reset should return to. */
5807
+ value?: (HelixHeadlessFilterInput["value"]) | undefined;
5808
+ /** What is wrong, in the reader's words rather than the browser's. */
5809
+ feedback?: (HelixHeadlessFilterInput["feedback"]) | undefined;
5810
+ /** Help under the control, shown while there is nothing wrong. */
5811
+ hint?: (HelixHeadlessFilterInput["hint"]) | undefined;
5812
+ /** The accessible name, and the fallback for the `label` slot. */
5813
+ label?: (HelixHeadlessFilterInput["label"]) | undefined;
5814
+ /** Whether the form refuses to submit without it. */
5815
+ required?: (HelixHeadlessFilterInput["required"]) | undefined;
5816
+ /** Whether the control is non-interactive.
5817
+
5818
+ Reflected, because the styled tier selects on it, and mirrored to
5819
+ `aria-disabled` rather than removing the element from the accessibility
5820
+ tree, so a screen reader can still announce that the control exists.
5821
+
5822
+ The mirror itself is in `willUpdate` below, here rather than in each
5823
+ control, because here is where `disabled` is. */
5824
+ disabled?: (HelixHeadlessFilterInput["disabled"]) | undefined;
5825
+ /** Name submitted with the form.
5826
+
5827
+ **Reflected, and it is the exception to "reflect only what CSS selects
5828
+ on".** The platform builds a form's entry list from the `name` *content
5829
+ attribute*, not from the property, so a control named through the property
5830
+ submitted under no name at all and was silently dropped. Measured: two
5831
+ inputs in one form, one named by attribute and one by property, and the
5832
+ form carried a single entry.
5833
+
5834
+ Safe for a React consumer, which is what the rule is protecting: React
5835
+ renders a custom element's props as attributes on the server, so the name
5836
+ is already in the markup being hydrated and reflecting it writes what is
5837
+ there. It is only a change to the markup when a consumer assigns it
5838
+ imperatively later, and nothing is hydrating by then.
5839
+
5840
+ Here rather than on each control. */
5841
+ name?: (HelixHeadlessFilterInput["name"]) | undefined;
5842
+
5843
+ /** Relayed from the input once the reader has finished. */
5844
+ onchange?: ((e: HelixHeadlessFilterInputElementEvent) => void) | undefined;
5845
+ /** Fired as the text changes, and cancelable. */
5846
+ "onhelix-before-change"?: ((
5847
+ e: HelixHeadlessFilterInputHelixBeforeChangeElementEvent,
5848
+ ) => void) | undefined;
5849
+ /** Announced once the text has moved. */
5850
+ oninput?: ((e: HelixHeadlessFilterInputElementEvent) => void) | undefined;
5851
+ };
5852
+
5853
+ export type HelixHeadlessFilterInputSolidJsProps = {
5854
+ /** Whether the field offers a button that empties it.
5855
+
5856
+ The text only. The tokens are the consumer's markup and this element is not
5857
+ entitled to take them out of the document, which is the same reason
5858
+ `hideOverflow` marks the ones over the cap `hidden` rather than removing
5859
+ them. */
5860
+ "prop:clearable"?: (HelixHeadlessFilterInput["clearable"]) | undefined;
5861
+ /** What the clear button is called, since an icon has no name of its own. */
5862
+ "attr:clear-label"?: (HelixHeadlessFilterInput["clearLabel"]) | undefined;
5863
+ /** What the clear button is called, since an icon has no name of its own. */
5864
+ "prop:clearLabel"?: (HelixHeadlessFilterInput["clearLabel"]) | undefined;
5865
+ /** Shown while the field is empty.
5866
+
5867
+ Not a label: it goes when typing starts. */
5868
+ "prop:placeholder"?: (HelixHeadlessFilterInput["placeholder"]) | undefined;
5869
+ /** How many tokens to show before the rest become a count. */
5870
+ "attr:max-tags"?: (HelixHeadlessFilterInput["maxTags"]) | undefined;
5871
+ /** How many tokens to show before the rest become a count. */
5872
+ "prop:maxTags"?: (HelixHeadlessFilterInput["maxTags"]) | undefined;
5873
+ /** The value the markup declared, which is where a reset returns to. */
5874
+ "attr:default-value"?: (HelixHeadlessFilterInput["defaultValue"]) | undefined;
5875
+ /** The value the markup declared, which is where a reset returns to. */
5876
+ "prop:defaultValue"?: (HelixHeadlessFilterInput["defaultValue"]) | undefined;
5877
+ /** What the control holds now, and what its form submits.
5878
+
5879
+ One property, not two, so `input.value` answers the question anyone
5880
+ asking it meant. Writing always applies; `<helix-input value="x">` is the
5881
+ same statement in markup, and `default-value` is how markup seeds a value
5882
+ a reset should return to. */
5883
+ "prop:value"?: (HelixHeadlessFilterInput["value"]) | undefined;
5884
+ /** What is wrong, in the reader's words rather than the browser's. */
5885
+ "prop:feedback"?: (HelixHeadlessFilterInput["feedback"]) | undefined;
5886
+ /** Help under the control, shown while there is nothing wrong. */
5887
+ "prop:hint"?: (HelixHeadlessFilterInput["hint"]) | undefined;
5888
+ /** The accessible name, and the fallback for the `label` slot. */
5889
+ "prop:label"?: (HelixHeadlessFilterInput["label"]) | undefined;
5890
+ /** Whether the form refuses to submit without it. */
5891
+ "prop:required"?: (HelixHeadlessFilterInput["required"]) | undefined;
5892
+ /** Whether the control is non-interactive.
5893
+
5894
+ Reflected, because the styled tier selects on it, and mirrored to
5895
+ `aria-disabled` rather than removing the element from the accessibility
5896
+ tree, so a screen reader can still announce that the control exists.
5897
+
5898
+ The mirror itself is in `willUpdate` below, here rather than in each
5899
+ control, because here is where `disabled` is. */
5900
+ "prop:disabled"?: (HelixHeadlessFilterInput["disabled"]) | undefined;
5901
+ /** Name submitted with the form.
5902
+
5903
+ **Reflected, and it is the exception to "reflect only what CSS selects
5904
+ on".** The platform builds a form's entry list from the `name` *content
5905
+ attribute*, not from the property, so a control named through the property
5906
+ submitted under no name at all and was silently dropped. Measured: two
5907
+ inputs in one form, one named by attribute and one by property, and the
5908
+ form carried a single entry.
5909
+
5910
+ Safe for a React consumer, which is what the rule is protecting: React
5911
+ renders a custom element's props as attributes on the server, so the name
5912
+ is already in the markup being hydrated and reflecting it writes what is
5913
+ there. It is only a change to the markup when a consumer assigns it
5914
+ imperatively later, and nothing is hydrating by then.
5915
+
5916
+ Here rather than on each control. */
5917
+ "prop:name"?: (HelixHeadlessFilterInput["name"]) | undefined;
5918
+ /** Relayed from the input once the reader has finished. */
5919
+ "on:change"?: ((e: HelixHeadlessFilterInputElementEvent) => void) | undefined;
5920
+ /** Fired as the text changes, and cancelable. */
5921
+ "on:helix-before-change"?: ((
5922
+ e: HelixHeadlessFilterInputHelixBeforeChangeElementEvent,
5923
+ ) => void) | undefined;
5924
+ /** Announced once the text has moved. */
5925
+ "on:input"?: ((e: HelixHeadlessFilterInputElementEvent) => void) | undefined;
5926
+
5927
+ /** Set the innerHTML of the element */
5928
+ innerHTML?: (string) | undefined;
5929
+ /** Set the textContent of the element */
5930
+ textContent?: (string | number) | undefined;
5931
+ };
5932
+
5811
5933
  export type HelixHeadlessFormatDateProps = {
5812
5934
  /** The timestamp, as anything `Date` parses.
5813
5935
 
@@ -18216,18 +18338,6 @@ export type CustomElements = {
18216
18338
  * Passed straight to the list, which is where the rows are and so where the
18217
18339
  * message belongs.
18218
18340
  * - `loading-text`/`loadingText`: What the list says while they are on their way.
18219
- * - `max-tags`/`maxTags`: How many tags to draw before the rest become a count. `multiple` only.
18220
- *
18221
- * `0` is all of them, and is the default: a cap that guesses is worse than no
18222
- * cap, because the number that fits depends on the width of the field and the
18223
- * length of what is in it, neither of which this element knows. What a cap is
18224
- * genuinely for is a field in a row or a table cell, where a set of twelve
18225
- * choices would push everything below it down a line at a time.
18226
- *
18227
- * The remainder is counted rather than hidden. `+3` is a fact a reader can act
18228
- * on, where a row that silently stops is a field that appears to have lost
18229
- * what was put in it. Date Input and Time Input carry the same property and
18230
- * the same reasoning.
18231
18341
  * - `multiple`: Whether more than one option can be chosen.
18232
18342
  *
18233
18343
  * The list already does the work: `value` comes apart on commas, a press
@@ -18257,6 +18367,7 @@ export type CustomElements = {
18257
18367
  * last reader did rather than what the author wrote. `:state(open)` carries
18258
18368
  * the resolved state for stylesheets, which is what the mirror is for.
18259
18369
  * - `default-open`/`defaultOpen`: Initial open state for uncontrolled use, where nothing declared one.
18370
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
18260
18371
  * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
18261
18372
  * - `value`: What the control holds now, and what its form submits.
18262
18373
  *
@@ -20387,6 +20498,186 @@ export type CustomElements = {
20387
20498
  HelixHeadlessFileInputProps & BaseProps<HelixHeadlessFileInput> & BaseEvents<HelixHeadlessFileInput>
20388
20499
  >;
20389
20500
 
20501
+ /**
20502
+ * **The tokens are the consumer's own elements, slotted.** What a filter narrows
20503
+ * by belongs to the consumer's model rather than to this element: a facet with a
20504
+ * prefix, a saved query, a range. So they are slotted rather than rendered from
20505
+ * a list of strings, and removing one is a request this element makes rather
20506
+ * than a change it applies. Combobox is the other way round, and that is the
20507
+ * difference between the two: its tokens are a view of a selection it owns,
20508
+ * drawn from options it was handed.
20509
+ *
20510
+ * **`value` is the text being typed, not the tokens**, which is what makes this
20511
+ * a field a consumer can listen to. Every keystroke announces `input` with the
20512
+ * text on the element, so a table narrows as the reader types. The tokens need
20513
+ * no reporting back, being markup the consumer already holds.
20514
+ *
20515
+ * Backspace on an empty field asks the last token to go, through the same
20516
+ * `helix-dismiss` its own remove control fires, so a consumer who handled the
20517
+ * pointer has already handled the keyboard.
20518
+ *
20519
+ * ## Attributes & Properties
20520
+ *
20521
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
20522
+ *
20523
+ * - `clearable`: Whether the field offers a button that empties it.
20524
+ *
20525
+ * The text only. The tokens are the consumer's markup and this element is not
20526
+ * entitled to take them out of the document, which is the same reason
20527
+ * `hideOverflow` marks the ones over the cap `hidden` rather than removing
20528
+ * them.
20529
+ * - `clear-label`/`clearLabel`: What the clear button is called, since an icon has no name of its own.
20530
+ * - `placeholder`: Shown while the field is empty.
20531
+ *
20532
+ * Not a label: it goes when typing starts.
20533
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
20534
+ * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
20535
+ * - `value`: What the control holds now, and what its form submits.
20536
+ *
20537
+ * One property, not two, so `input.value` answers the question anyone
20538
+ * asking it meant. Writing always applies; `<helix-input value="x">` is the
20539
+ * same statement in markup, and `default-value` is how markup seeds a value
20540
+ * a reset should return to.
20541
+ * - `feedback`: What is wrong, in the reader's words rather than the browser's.
20542
+ * - `hint`: Help under the control, shown while there is nothing wrong.
20543
+ * - `label`: The accessible name, and the fallback for the `label` slot.
20544
+ * - `required`: Whether the form refuses to submit without it.
20545
+ * - `disabled`: Whether the control is non-interactive.
20546
+ *
20547
+ * Reflected, because the styled tier selects on it, and mirrored to
20548
+ * `aria-disabled` rather than removing the element from the accessibility
20549
+ * tree, so a screen reader can still announce that the control exists.
20550
+ *
20551
+ * The mirror itself is in `willUpdate` below, here rather than in each
20552
+ * control, because here is where `disabled` is.
20553
+ * - `name`: Name submitted with the form.
20554
+ *
20555
+ * **Reflected, and it is the exception to "reflect only what CSS selects
20556
+ * on".** The platform builds a form's entry list from the `name` *content
20557
+ * attribute*, not from the property, so a control named through the property
20558
+ * submitted under no name at all and was silently dropped. Measured: two
20559
+ * inputs in one form, one named by attribute and one by property, and the
20560
+ * form carried a single entry.
20561
+ *
20562
+ * Safe for a React consumer, which is what the rule is protecting: React
20563
+ * renders a custom element's props as attributes on the server, so the name
20564
+ * is already in the markup being hydrated and reflecting it writes what is
20565
+ * there. It is only a change to the markup when a consumer assigns it
20566
+ * imperatively later, and nothing is hydrating by then.
20567
+ *
20568
+ * Here rather than on each control.
20569
+ * - `form`: The form this control belongs to, if any. (property only) (readonly)
20570
+ * - `labels`: Labels associated with this control. (property only) (readonly)
20571
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
20572
+ *
20573
+ * **Named `whenSettled` because `settled` is taken four times over**, by
20574
+ * Image, Splitter and both color controls, none of them about transitions. A
20575
+ * base class takes the name every subclass then cannot use.
20576
+ *
20577
+ * **The state it reports cannot be watched, which is why this exists.** A
20578
+ * custom state is deliberately not in the DOM, so there is no
20579
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
20580
+ * instead.
20581
+ *
20582
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
20583
+ * the suppression is still active in. That is the distinction `readyToMove`
20584
+ * in `@fusion.dev/helix-testing` is written around.
20585
+ *
20586
+ * It never resolves where `requestAnimationFrame` never fires, which is a
20587
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
20588
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
20589
+ *
20590
+ * ## Events
20591
+ *
20592
+ * Events that will be emitted by the component.
20593
+ *
20594
+ * - `change`: Relayed from the input once the reader has finished.
20595
+ * - `helix-before-change`: Fired as the text changes, and cancelable.
20596
+ * - `input`: Announced once the text has moved.
20597
+ *
20598
+ * ## Slots
20599
+ *
20600
+ * Areas where markup can be added to the component.
20601
+ *
20602
+ * - `end`: After the text, for a count or a control.
20603
+ * - `start`: Before the text, for a search icon.
20604
+ * - `tags`: What is already narrowing the results, as `Tag`s.
20605
+ *
20606
+ * ## Methods
20607
+ *
20608
+ * Methods that can be called to access component functionality.
20609
+ *
20610
+ * - `focus(options?: FocusOptions) => void`: Puts the caret in the field, the way a label pointing at one would.
20611
+ * - `requestValue(next: string) => boolean`: Requests a new value, and reports whether the request stood.
20612
+ *
20613
+ * Announces before it acts, so `preventDefault()` on the `helix-before-change` is
20614
+ * a refusal and nothing moves. Nobody refusing means the control updates
20615
+ * itself, whether or not a consumer declared `value`: a declared property
20616
+ * is a seed and a correction, the way `<input value>` is, and a consumer
20617
+ * who wants the change for themselves refuses it and assigns their own.
20618
+ * - `formResetCallback() => void`: Returns the control to the value its markup declared.
20619
+ *
20620
+ * Both halves are dropped, the consumer's and the control's, because a
20621
+ * reset means the form is as it was served. Clearing only the internal one
20622
+ * would leave a control that had been written to stuck at that value.
20623
+ * - `formStateRestoreCallback(state: string | null) => void`: Restores the value when the browser brings a form back.
20624
+ *
20625
+ * Falling back to `defaultValue` rather than to empty, because a restore
20626
+ * with no state is a form the browser has nothing recorded for, which is
20627
+ * the same situation as a fresh one.
20628
+ * - `formDisabledCallback(disabled: boolean) => void`: The platform's notice that an ancestor fieldset changed.
20629
+ *
20630
+ * **The argument is the effective state, and taking it whole is what latched
20631
+ * every control in the library.** The platform calls this for the element's
20632
+ * own `disabled` as well as for a fieldset, and our own arrives here at the
20633
+ * worst possible moment: reflecting `disabled` to the attribute happens
20634
+ * inside Lit's `update()`, the UA fires this synchronously from that write,
20635
+ * and a reactive write during an update is a change-in-update Lit does not
20636
+ * re-render for. So `formDisabled` ran exactly one update behind forever.
20637
+ *
20638
+ * Measured on Slider, logging what `render` saw:
20639
+ *
20640
+ * ```
20641
+ * set true disabled true formDisabled false isDisabled true
20642
+ * set false disabled false formDisabled true isDisabled true <- stale
20643
+ * (no third render)
20644
+ * ```
20645
+ *
20646
+ * The host came out right every time, `disabled` false, `:disabled` not
20647
+ * matching, and the inner control kept the attribute, so a control disabled
20648
+ * once could never be re-enabled. It only shows when something re-enables,
20649
+ * which is the same shape of bug `inheritDisabled` was written for.
20650
+ *
20651
+ * Our own half is already in `this.disabled` and `isDisabled` is an or, so
20652
+ * this records only what the fieldset adds. That also removes the write
20653
+ * entirely on the own-disabled path rather than moving it.
20654
+ *
20655
+ * The one case this cannot see is a control that is disabled itself *and*
20656
+ * inside a disabled fieldset, whose own `disabled` is then removed: the
20657
+ * effective state does not change, so the platform does not call again, and
20658
+ * the fieldset's hold is not recorded. There is no callback to learn it from
20659
+ * and reading `:disabled` here would answer about the attribute we are in the
20660
+ * middle of removing.
20661
+ *
20662
+ * ## CSS Parts
20663
+ *
20664
+ * Custom selectors for styling elements within the component.
20665
+ *
20666
+ * - `clear`: The button that empties the field.
20667
+ * - `control`: The input itself.
20668
+ * - `feedback`: What is wrong with it.
20669
+ * - `field`: The box holding everything.
20670
+ * - `hint`: Help under the field, while nothing is wrong.
20671
+ * - `label`: The question, over the field.
20672
+ * - `rest`: How many tokens did not fit.
20673
+ * - `tags`: The row the tokens sit in.
20674
+ */
20675
+ "helix-headless-filter-input": Partial<
20676
+ HelixHeadlessFilterInputProps &
20677
+ BaseProps<HelixHeadlessFilterInput> &
20678
+ BaseEvents<HelixHeadlessFilterInput>
20679
+ >;
20680
+
20390
20681
  /**
20391
20682
  * A date in a page is almost never wanted as an ISO string, and formatting one
20392
20683
  * in the consumer's own code means every consumer ships a copy of the same
@@ -32446,18 +32737,6 @@ export type CustomElementsSolidJs = {
32446
32737
  * Passed straight to the list, which is where the rows are and so where the
32447
32738
  * message belongs.
32448
32739
  * - `loading-text`/`loadingText`: What the list says while they are on their way.
32449
- * - `max-tags`/`maxTags`: How many tags to draw before the rest become a count. `multiple` only.
32450
- *
32451
- * `0` is all of them, and is the default: a cap that guesses is worse than no
32452
- * cap, because the number that fits depends on the width of the field and the
32453
- * length of what is in it, neither of which this element knows. What a cap is
32454
- * genuinely for is a field in a row or a table cell, where a set of twelve
32455
- * choices would push everything below it down a line at a time.
32456
- *
32457
- * The remainder is counted rather than hidden. `+3` is a fact a reader can act
32458
- * on, where a row that silently stops is a field that appears to have lost
32459
- * what was put in it. Date Input and Time Input carry the same property and
32460
- * the same reasoning.
32461
32740
  * - `multiple`: Whether more than one option can be chosen.
32462
32741
  *
32463
32742
  * The list already does the work: `value` comes apart on commas, a press
@@ -32487,6 +32766,7 @@ export type CustomElementsSolidJs = {
32487
32766
  * last reader did rather than what the author wrote. `:state(open)` carries
32488
32767
  * the resolved state for stylesheets, which is what the mirror is for.
32489
32768
  * - `default-open`/`defaultOpen`: Initial open state for uncontrolled use, where nothing declared one.
32769
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
32490
32770
  * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
32491
32771
  * - `value`: What the control holds now, and what its form submits.
32492
32772
  *
@@ -34651,6 +34931,187 @@ export type CustomElementsSolidJs = {
34651
34931
  BaseEvents<HelixHeadlessFileInput>
34652
34932
  >;
34653
34933
 
34934
+ /**
34935
+ * **The tokens are the consumer's own elements, slotted.** What a filter narrows
34936
+ * by belongs to the consumer's model rather than to this element: a facet with a
34937
+ * prefix, a saved query, a range. So they are slotted rather than rendered from
34938
+ * a list of strings, and removing one is a request this element makes rather
34939
+ * than a change it applies. Combobox is the other way round, and that is the
34940
+ * difference between the two: its tokens are a view of a selection it owns,
34941
+ * drawn from options it was handed.
34942
+ *
34943
+ * **`value` is the text being typed, not the tokens**, which is what makes this
34944
+ * a field a consumer can listen to. Every keystroke announces `input` with the
34945
+ * text on the element, so a table narrows as the reader types. The tokens need
34946
+ * no reporting back, being markup the consumer already holds.
34947
+ *
34948
+ * Backspace on an empty field asks the last token to go, through the same
34949
+ * `helix-dismiss` its own remove control fires, so a consumer who handled the
34950
+ * pointer has already handled the keyboard.
34951
+ *
34952
+ * ## Attributes & Properties
34953
+ *
34954
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
34955
+ *
34956
+ * - `clearable`: Whether the field offers a button that empties it.
34957
+ *
34958
+ * The text only. The tokens are the consumer's markup and this element is not
34959
+ * entitled to take them out of the document, which is the same reason
34960
+ * `hideOverflow` marks the ones over the cap `hidden` rather than removing
34961
+ * them.
34962
+ * - `clear-label`/`clearLabel`: What the clear button is called, since an icon has no name of its own.
34963
+ * - `placeholder`: Shown while the field is empty.
34964
+ *
34965
+ * Not a label: it goes when typing starts.
34966
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
34967
+ * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
34968
+ * - `value`: What the control holds now, and what its form submits.
34969
+ *
34970
+ * One property, not two, so `input.value` answers the question anyone
34971
+ * asking it meant. Writing always applies; `<helix-input value="x">` is the
34972
+ * same statement in markup, and `default-value` is how markup seeds a value
34973
+ * a reset should return to.
34974
+ * - `feedback`: What is wrong, in the reader's words rather than the browser's.
34975
+ * - `hint`: Help under the control, shown while there is nothing wrong.
34976
+ * - `label`: The accessible name, and the fallback for the `label` slot.
34977
+ * - `required`: Whether the form refuses to submit without it.
34978
+ * - `disabled`: Whether the control is non-interactive.
34979
+ *
34980
+ * Reflected, because the styled tier selects on it, and mirrored to
34981
+ * `aria-disabled` rather than removing the element from the accessibility
34982
+ * tree, so a screen reader can still announce that the control exists.
34983
+ *
34984
+ * The mirror itself is in `willUpdate` below, here rather than in each
34985
+ * control, because here is where `disabled` is.
34986
+ * - `name`: Name submitted with the form.
34987
+ *
34988
+ * **Reflected, and it is the exception to "reflect only what CSS selects
34989
+ * on".** The platform builds a form's entry list from the `name` *content
34990
+ * attribute*, not from the property, so a control named through the property
34991
+ * submitted under no name at all and was silently dropped. Measured: two
34992
+ * inputs in one form, one named by attribute and one by property, and the
34993
+ * form carried a single entry.
34994
+ *
34995
+ * Safe for a React consumer, which is what the rule is protecting: React
34996
+ * renders a custom element's props as attributes on the server, so the name
34997
+ * is already in the markup being hydrated and reflecting it writes what is
34998
+ * there. It is only a change to the markup when a consumer assigns it
34999
+ * imperatively later, and nothing is hydrating by then.
35000
+ *
35001
+ * Here rather than on each control.
35002
+ * - `form`: The form this control belongs to, if any. (property only) (readonly)
35003
+ * - `labels`: Labels associated with this control. (property only) (readonly)
35004
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
35005
+ *
35006
+ * **Named `whenSettled` because `settled` is taken four times over**, by
35007
+ * Image, Splitter and both color controls, none of them about transitions. A
35008
+ * base class takes the name every subclass then cannot use.
35009
+ *
35010
+ * **The state it reports cannot be watched, which is why this exists.** A
35011
+ * custom state is deliberately not in the DOM, so there is no
35012
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
35013
+ * instead.
35014
+ *
35015
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
35016
+ * the suppression is still active in. That is the distinction `readyToMove`
35017
+ * in `@fusion.dev/helix-testing` is written around.
35018
+ *
35019
+ * It never resolves where `requestAnimationFrame` never fires, which is a
35020
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
35021
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
35022
+ *
35023
+ * ## Events
35024
+ *
35025
+ * Events that will be emitted by the component.
35026
+ *
35027
+ * - `change`: Relayed from the input once the reader has finished.
35028
+ * - `helix-before-change`: Fired as the text changes, and cancelable.
35029
+ * - `input`: Announced once the text has moved.
35030
+ *
35031
+ * ## Slots
35032
+ *
35033
+ * Areas where markup can be added to the component.
35034
+ *
35035
+ * - `end`: After the text, for a count or a control.
35036
+ * - `start`: Before the text, for a search icon.
35037
+ * - `tags`: What is already narrowing the results, as `Tag`s.
35038
+ *
35039
+ * ## Methods
35040
+ *
35041
+ * Methods that can be called to access component functionality.
35042
+ *
35043
+ * - `focus(options?: FocusOptions) => void`: Puts the caret in the field, the way a label pointing at one would.
35044
+ * - `requestValue(next: string) => boolean`: Requests a new value, and reports whether the request stood.
35045
+ *
35046
+ * Announces before it acts, so `preventDefault()` on the `helix-before-change` is
35047
+ * a refusal and nothing moves. Nobody refusing means the control updates
35048
+ * itself, whether or not a consumer declared `value`: a declared property
35049
+ * is a seed and a correction, the way `<input value>` is, and a consumer
35050
+ * who wants the change for themselves refuses it and assigns their own.
35051
+ * - `formResetCallback() => void`: Returns the control to the value its markup declared.
35052
+ *
35053
+ * Both halves are dropped, the consumer's and the control's, because a
35054
+ * reset means the form is as it was served. Clearing only the internal one
35055
+ * would leave a control that had been written to stuck at that value.
35056
+ * - `formStateRestoreCallback(state: string | null) => void`: Restores the value when the browser brings a form back.
35057
+ *
35058
+ * Falling back to `defaultValue` rather than to empty, because a restore
35059
+ * with no state is a form the browser has nothing recorded for, which is
35060
+ * the same situation as a fresh one.
35061
+ * - `formDisabledCallback(disabled: boolean) => void`: The platform's notice that an ancestor fieldset changed.
35062
+ *
35063
+ * **The argument is the effective state, and taking it whole is what latched
35064
+ * every control in the library.** The platform calls this for the element's
35065
+ * own `disabled` as well as for a fieldset, and our own arrives here at the
35066
+ * worst possible moment: reflecting `disabled` to the attribute happens
35067
+ * inside Lit's `update()`, the UA fires this synchronously from that write,
35068
+ * and a reactive write during an update is a change-in-update Lit does not
35069
+ * re-render for. So `formDisabled` ran exactly one update behind forever.
35070
+ *
35071
+ * Measured on Slider, logging what `render` saw:
35072
+ *
35073
+ * ```
35074
+ * set true disabled true formDisabled false isDisabled true
35075
+ * set false disabled false formDisabled true isDisabled true <- stale
35076
+ * (no third render)
35077
+ * ```
35078
+ *
35079
+ * The host came out right every time, `disabled` false, `:disabled` not
35080
+ * matching, and the inner control kept the attribute, so a control disabled
35081
+ * once could never be re-enabled. It only shows when something re-enables,
35082
+ * which is the same shape of bug `inheritDisabled` was written for.
35083
+ *
35084
+ * Our own half is already in `this.disabled` and `isDisabled` is an or, so
35085
+ * this records only what the fieldset adds. That also removes the write
35086
+ * entirely on the own-disabled path rather than moving it.
35087
+ *
35088
+ * The one case this cannot see is a control that is disabled itself *and*
35089
+ * inside a disabled fieldset, whose own `disabled` is then removed: the
35090
+ * effective state does not change, so the platform does not call again, and
35091
+ * the fieldset's hold is not recorded. There is no callback to learn it from
35092
+ * and reading `:disabled` here would answer about the attribute we are in the
35093
+ * middle of removing.
35094
+ *
35095
+ * ## CSS Parts
35096
+ *
35097
+ * Custom selectors for styling elements within the component.
35098
+ *
35099
+ * - `clear`: The button that empties the field.
35100
+ * - `control`: The input itself.
35101
+ * - `feedback`: What is wrong with it.
35102
+ * - `field`: The box holding everything.
35103
+ * - `hint`: Help under the field, while nothing is wrong.
35104
+ * - `label`: The question, over the field.
35105
+ * - `rest`: How many tokens did not fit.
35106
+ * - `tags`: The row the tokens sit in.
35107
+ */
35108
+ "helix-headless-filter-input": Partial<
35109
+ HelixHeadlessFilterInputProps &
35110
+ HelixHeadlessFilterInputSolidJsProps &
35111
+ BaseProps<HelixHeadlessFilterInput> &
35112
+ BaseEvents<HelixHeadlessFilterInput>
35113
+ >;
35114
+
34654
35115
  /**
34655
35116
  * A date in a page is almost never wanted as an ISO string, and formatting one
34656
35117
  * in the consumer's own code means every consumer ships a copy of the same