@fusion.dev/helix 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
@@ -59,6 +59,7 @@ import type {
59
59
  HelixEmpty,
60
60
  HelixFileInput,
61
61
  HelixFilterEvent,
62
+ HelixFilterInput,
62
63
  HelixFlex,
63
64
  HelixFormatDate,
64
65
  HelixGrid,
@@ -4064,6 +4065,10 @@ the resolved state for stylesheets, which is what the mirror is for. */
4064
4065
  "default-open"?: (HelixCombobox["defaultOpen"]) | undefined;
4065
4066
  /** Initial open state for uncontrolled use, where nothing declared one. */
4066
4067
  defaultOpen?: (HelixCombobox["defaultOpen"]) | undefined;
4068
+ /** How many tokens to show before the rest become a count. */
4069
+ "max-tags"?: (HelixCombobox["maxTags"]) | undefined;
4070
+ /** How many tokens to show before the rest become a count. */
4071
+ maxTags?: (HelixCombobox["maxTags"]) | undefined;
4067
4072
  /** The value the markup declared, which is where a reset returns to. */
4068
4073
  "default-value"?: (HelixCombobox["defaultValue"]) | undefined;
4069
4074
  /** The value the markup declared, which is where a reset returns to. */
@@ -4118,32 +4123,6 @@ message belongs. */
4118
4123
  "loading-text"?: (HelixCombobox["loadingText"]) | undefined;
4119
4124
  /** What the list says while they are on their way. */
4120
4125
  loadingText?: (HelixCombobox["loadingText"]) | undefined;
4121
- /** How many tags to draw before the rest become a count. `multiple` only.
4122
-
4123
- `0` is all of them, and is the default: a cap that guesses is worse than no
4124
- cap, because the number that fits depends on the width of the field and the
4125
- length of what is in it, neither of which this element knows. What a cap is
4126
- genuinely for is a field in a row or a table cell, where a set of twelve
4127
- choices would push everything below it down a line at a time.
4128
-
4129
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
4130
- on, where a row that silently stops is a field that appears to have lost
4131
- what was put in it. Date Input and Time Input carry the same property and
4132
- the same reasoning. */
4133
- "max-tags"?: (HelixCombobox["maxTags"]) | undefined;
4134
- /** How many tags to draw before the rest become a count. `multiple` only.
4135
-
4136
- `0` is all of them, and is the default: a cap that guesses is worse than no
4137
- cap, because the number that fits depends on the width of the field and the
4138
- length of what is in it, neither of which this element knows. What a cap is
4139
- genuinely for is a field in a row or a table cell, where a set of twelve
4140
- choices would push everything below it down a line at a time.
4141
-
4142
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
4143
- on, where a row that silently stops is a field that appears to have lost
4144
- what was put in it. Date Input and Time Input carry the same property and
4145
- the same reasoning. */
4146
- maxTags?: (HelixCombobox["maxTags"]) | undefined;
4147
4126
  /** Whether more than one option can be chosen.
4148
4127
 
4149
4128
  The list already does the work: `value` comes apart on commas, a press
@@ -4238,6 +4217,10 @@ the resolved state for stylesheets, which is what the mirror is for. */
4238
4217
  "bool:default-open"?: (HelixCombobox["defaultOpen"]) | undefined;
4239
4218
  /** Initial open state for uncontrolled use, where nothing declared one. */
4240
4219
  "prop:defaultOpen"?: (HelixCombobox["defaultOpen"]) | undefined;
4220
+ /** How many tokens to show before the rest become a count. */
4221
+ "attr:max-tags"?: (HelixCombobox["maxTags"]) | undefined;
4222
+ /** How many tokens to show before the rest become a count. */
4223
+ "prop:maxTags"?: (HelixCombobox["maxTags"]) | undefined;
4241
4224
  /** The value the markup declared, which is where a reset returns to. */
4242
4225
  "attr:default-value"?: (HelixCombobox["defaultValue"]) | undefined;
4243
4226
  /** The value the markup declared, which is where a reset returns to. */
@@ -4292,32 +4275,6 @@ message belongs. */
4292
4275
  "attr:loading-text"?: (HelixCombobox["loadingText"]) | undefined;
4293
4276
  /** What the list says while they are on their way. */
4294
4277
  "prop:loadingText"?: (HelixCombobox["loadingText"]) | undefined;
4295
- /** How many tags to draw before the rest become a count. `multiple` only.
4296
-
4297
- `0` is all of them, and is the default: a cap that guesses is worse than no
4298
- cap, because the number that fits depends on the width of the field and the
4299
- length of what is in it, neither of which this element knows. What a cap is
4300
- genuinely for is a field in a row or a table cell, where a set of twelve
4301
- choices would push everything below it down a line at a time.
4302
-
4303
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
4304
- on, where a row that silently stops is a field that appears to have lost
4305
- what was put in it. Date Input and Time Input carry the same property and
4306
- the same reasoning. */
4307
- "attr:max-tags"?: (HelixCombobox["maxTags"]) | undefined;
4308
- /** How many tags to draw before the rest become a count. `multiple` only.
4309
-
4310
- `0` is all of them, and is the default: a cap that guesses is worse than no
4311
- cap, because the number that fits depends on the width of the field and the
4312
- length of what is in it, neither of which this element knows. What a cap is
4313
- genuinely for is a field in a row or a table cell, where a set of twelve
4314
- choices would push everything below it down a line at a time.
4315
-
4316
- The remainder is counted rather than hidden. `+3` is a fact a reader can act
4317
- on, where a row that silently stops is a field that appears to have lost
4318
- what was put in it. Date Input and Time Input carry the same property and
4319
- the same reasoning. */
4320
- "prop:maxTags"?: (HelixCombobox["maxTags"]) | undefined;
4321
4278
  /** Whether more than one option can be chosen.
4322
4279
 
4323
4280
  The list already does the work: `value` comes apart on commas, a press
@@ -6985,6 +6942,171 @@ Here rather than on each control. */
6985
6942
  textContent?: (string | number) | undefined;
6986
6943
  };
6987
6944
 
6945
+ /** `HelixFilterInput` component event */
6946
+ export type HelixFilterInputElementEvent<E = Event> = TypedEvent<
6947
+ HelixFilterInput,
6948
+ E
6949
+ >;
6950
+ /** `helix-before-change` event type */
6951
+ export type HelixFilterInputHelixBeforeChangeElementEvent =
6952
+ HelixFilterInputElementEvent<HelixBeforeChangeEvent>;
6953
+
6954
+ export type HelixFilterInputProps = {
6955
+ /** How many tokens to show before the rest become a count. */
6956
+ "max-tags"?: (HelixFilterInput["maxTags"]) | undefined;
6957
+ /** How many tokens to show before the rest become a count. */
6958
+ maxTags?: (HelixFilterInput["maxTags"]) | undefined;
6959
+ /** The value the markup declared, which is where a reset returns to. */
6960
+ "default-value"?: (HelixFilterInput["defaultValue"]) | undefined;
6961
+ /** The value the markup declared, which is where a reset returns to. */
6962
+ defaultValue?: (HelixFilterInput["defaultValue"]) | undefined;
6963
+ /** What the control holds now, and what its form submits.
6964
+
6965
+ One property, not two, so `input.value` answers the question anyone
6966
+ asking it meant. Writing always applies; `<helix-input value="x">` is the
6967
+ same statement in markup, and `default-value` is how markup seeds a value
6968
+ a reset should return to. */
6969
+ value?: (HelixFilterInput["value"]) | undefined;
6970
+ /** What is wrong, in the reader's words rather than the browser's. */
6971
+ feedback?: (HelixFilterInput["feedback"]) | undefined;
6972
+ /** Help under the control, shown while there is nothing wrong. */
6973
+ hint?: (HelixFilterInput["hint"]) | undefined;
6974
+ /** The accessible name, and the fallback for the `label` slot. */
6975
+ label?: (HelixFilterInput["label"]) | undefined;
6976
+ /** Whether the form refuses to submit without it. */
6977
+ required?: (HelixFilterInput["required"]) | undefined;
6978
+ /** Whether the field offers a button that empties it.
6979
+
6980
+ The text only. The tokens are the consumer's markup and this element is not
6981
+ entitled to take them out of the document, which is the same reason
6982
+ `hideOverflow` marks the ones over the cap `hidden` rather than removing
6983
+ them. */
6984
+ clearable?: (HelixFilterInput["clearable"]) | undefined;
6985
+ /** What the clear button is called, since an icon has no name of its own. */
6986
+ "clear-label"?: (HelixFilterInput["clearLabel"]) | undefined;
6987
+ /** What the clear button is called, since an icon has no name of its own. */
6988
+ clearLabel?: (HelixFilterInput["clearLabel"]) | undefined;
6989
+ /** Shown while the field is empty.
6990
+
6991
+ Not a label: it goes when typing starts. */
6992
+ placeholder?: (HelixFilterInput["placeholder"]) | undefined;
6993
+ /** Whether the control is non-interactive.
6994
+
6995
+ Reflected, because the styled tier selects on it, and mirrored to
6996
+ `aria-disabled` rather than removing the element from the accessibility
6997
+ tree, so a screen reader can still announce that the control exists.
6998
+
6999
+ The mirror itself is in `willUpdate` below, here rather than in each
7000
+ control, because here is where `disabled` is. */
7001
+ disabled?: (HelixFilterInput["disabled"]) | undefined;
7002
+ /** Name submitted with the form.
7003
+
7004
+ **Reflected, and it is the exception to "reflect only what CSS selects
7005
+ on".** The platform builds a form's entry list from the `name` *content
7006
+ attribute*, not from the property, so a control named through the property
7007
+ submitted under no name at all and was silently dropped. Measured: two
7008
+ inputs in one form, one named by attribute and one by property, and the
7009
+ form carried a single entry.
7010
+
7011
+ Safe for a React consumer, which is what the rule is protecting: React
7012
+ renders a custom element's props as attributes on the server, so the name
7013
+ is already in the markup being hydrated and reflecting it writes what is
7014
+ there. It is only a change to the markup when a consumer assigns it
7015
+ imperatively later, and nothing is hydrating by then.
7016
+
7017
+ Here rather than on each control. */
7018
+ name?: (HelixFilterInput["name"]) | undefined;
7019
+
7020
+ /** Announced once the text has moved. */
7021
+ oninput?: ((e: HelixFilterInputElementEvent) => void) | undefined;
7022
+ /** Relayed from the input once the reader has finished. */
7023
+ onchange?: ((e: HelixFilterInputElementEvent) => void) | undefined;
7024
+ /** Fired as the text changes, and cancelable. */
7025
+ "onhelix-before-change"?: ((
7026
+ e: HelixFilterInputHelixBeforeChangeElementEvent,
7027
+ ) => void) | undefined;
7028
+ };
7029
+
7030
+ export type HelixFilterInputSolidJsProps = {
7031
+ /** How many tokens to show before the rest become a count. */
7032
+ "attr:max-tags"?: (HelixFilterInput["maxTags"]) | undefined;
7033
+ /** How many tokens to show before the rest become a count. */
7034
+ "prop:maxTags"?: (HelixFilterInput["maxTags"]) | undefined;
7035
+ /** The value the markup declared, which is where a reset returns to. */
7036
+ "attr:default-value"?: (HelixFilterInput["defaultValue"]) | undefined;
7037
+ /** The value the markup declared, which is where a reset returns to. */
7038
+ "prop:defaultValue"?: (HelixFilterInput["defaultValue"]) | undefined;
7039
+ /** What the control holds now, and what its form submits.
7040
+
7041
+ One property, not two, so `input.value` answers the question anyone
7042
+ asking it meant. Writing always applies; `<helix-input value="x">` is the
7043
+ same statement in markup, and `default-value` is how markup seeds a value
7044
+ a reset should return to. */
7045
+ "prop:value"?: (HelixFilterInput["value"]) | undefined;
7046
+ /** What is wrong, in the reader's words rather than the browser's. */
7047
+ "prop:feedback"?: (HelixFilterInput["feedback"]) | undefined;
7048
+ /** Help under the control, shown while there is nothing wrong. */
7049
+ "prop:hint"?: (HelixFilterInput["hint"]) | undefined;
7050
+ /** The accessible name, and the fallback for the `label` slot. */
7051
+ "prop:label"?: (HelixFilterInput["label"]) | undefined;
7052
+ /** Whether the form refuses to submit without it. */
7053
+ "prop:required"?: (HelixFilterInput["required"]) | undefined;
7054
+ /** Whether the field offers a button that empties it.
7055
+
7056
+ The text only. The tokens are the consumer's markup and this element is not
7057
+ entitled to take them out of the document, which is the same reason
7058
+ `hideOverflow` marks the ones over the cap `hidden` rather than removing
7059
+ them. */
7060
+ "prop:clearable"?: (HelixFilterInput["clearable"]) | undefined;
7061
+ /** What the clear button is called, since an icon has no name of its own. */
7062
+ "attr:clear-label"?: (HelixFilterInput["clearLabel"]) | undefined;
7063
+ /** What the clear button is called, since an icon has no name of its own. */
7064
+ "prop:clearLabel"?: (HelixFilterInput["clearLabel"]) | undefined;
7065
+ /** Shown while the field is empty.
7066
+
7067
+ Not a label: it goes when typing starts. */
7068
+ "prop:placeholder"?: (HelixFilterInput["placeholder"]) | undefined;
7069
+ /** Whether the control is non-interactive.
7070
+
7071
+ Reflected, because the styled tier selects on it, and mirrored to
7072
+ `aria-disabled` rather than removing the element from the accessibility
7073
+ tree, so a screen reader can still announce that the control exists.
7074
+
7075
+ The mirror itself is in `willUpdate` below, here rather than in each
7076
+ control, because here is where `disabled` is. */
7077
+ "prop:disabled"?: (HelixFilterInput["disabled"]) | undefined;
7078
+ /** Name submitted with the form.
7079
+
7080
+ **Reflected, and it is the exception to "reflect only what CSS selects
7081
+ on".** The platform builds a form's entry list from the `name` *content
7082
+ attribute*, not from the property, so a control named through the property
7083
+ submitted under no name at all and was silently dropped. Measured: two
7084
+ inputs in one form, one named by attribute and one by property, and the
7085
+ form carried a single entry.
7086
+
7087
+ Safe for a React consumer, which is what the rule is protecting: React
7088
+ renders a custom element's props as attributes on the server, so the name
7089
+ is already in the markup being hydrated and reflecting it writes what is
7090
+ there. It is only a change to the markup when a consumer assigns it
7091
+ imperatively later, and nothing is hydrating by then.
7092
+
7093
+ Here rather than on each control. */
7094
+ "prop:name"?: (HelixFilterInput["name"]) | undefined;
7095
+ /** Announced once the text has moved. */
7096
+ "on:input"?: ((e: HelixFilterInputElementEvent) => void) | undefined;
7097
+ /** Relayed from the input once the reader has finished. */
7098
+ "on:change"?: ((e: HelixFilterInputElementEvent) => void) | undefined;
7099
+ /** Fired as the text changes, and cancelable. */
7100
+ "on:helix-before-change"?: ((
7101
+ e: HelixFilterInputHelixBeforeChangeElementEvent,
7102
+ ) => void) | undefined;
7103
+
7104
+ /** Set the innerHTML of the element */
7105
+ innerHTML?: (string) | undefined;
7106
+ /** Set the textContent of the element */
7107
+ textContent?: (string | number) | undefined;
7108
+ };
7109
+
6988
7110
  export type HelixFlexProps = {
6989
7111
  /** Alignment across the direction. */
6990
7112
  align?: (HelixFlex["align"]) | undefined;
@@ -21295,6 +21417,7 @@ export type CustomElements = {
21295
21417
  * last reader did rather than what the author wrote. `:state(open)` carries
21296
21418
  * the resolved state for stylesheets, which is what the mirror is for.
21297
21419
  * - `default-open`/`defaultOpen`: Initial open state for uncontrolled use, where nothing declared one.
21420
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
21298
21421
  * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
21299
21422
  * - `value`: What the control holds now, and what its form submits.
21300
21423
  *
@@ -21326,18 +21449,6 @@ export type CustomElements = {
21326
21449
  * Passed straight to the list, which is where the rows are and so where the
21327
21450
  * message belongs.
21328
21451
  * - `loading-text`/`loadingText`: What the list says while they are on their way.
21329
- * - `max-tags`/`maxTags`: How many tags to draw before the rest become a count. `multiple` only.
21330
- *
21331
- * `0` is all of them, and is the default: a cap that guesses is worse than no
21332
- * cap, because the number that fits depends on the width of the field and the
21333
- * length of what is in it, neither of which this element knows. What a cap is
21334
- * genuinely for is a field in a row or a table cell, where a set of twelve
21335
- * choices would push everything below it down a line at a time.
21336
- *
21337
- * The remainder is counted rather than hidden. `+3` is a fact a reader can act
21338
- * on, where a row that silently stops is a field that appears to have lost
21339
- * what was put in it. Date Input and Time Input carry the same property and
21340
- * the same reasoning.
21341
21452
  * - `multiple`: Whether more than one option can be chosen.
21342
21453
  *
21343
21454
  * The list already does the work: `value` comes apart on commas, a press
@@ -23584,6 +23695,187 @@ export type CustomElements = {
23584
23695
  HelixFileInputProps & BaseProps<HelixFileInput> & BaseEvents<HelixFileInput>
23585
23696
  >;
23586
23697
 
23698
+ /**
23699
+ * The frame is the field rather than the input, so the tokens sit inside the
23700
+ * same box as the text and the focus ring is drawn once around the whole
23701
+ * control. It grows down a line at a time as tokens are added, which is the
23702
+ * arrangement Combobox takes when it is holding a selection.
23703
+ *
23704
+ * **The tokens are the consumer's own elements**, so the only thing said about
23705
+ * them here is to keep their size and not run past the field. A `Tag` slotted
23706
+ * into `tags` already looks like one; anything else looks like whatever it is.
23707
+ *
23708
+ * Height comes from the region, like every other control: `data-density` on
23709
+ * whatever holds it, not a `size` here.
23710
+ *
23711
+ * ## Attributes & Properties
23712
+ *
23713
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
23714
+ *
23715
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
23716
+ * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
23717
+ * - `value`: What the control holds now, and what its form submits.
23718
+ *
23719
+ * One property, not two, so `input.value` answers the question anyone
23720
+ * asking it meant. Writing always applies; `<helix-input value="x">` is the
23721
+ * same statement in markup, and `default-value` is how markup seeds a value
23722
+ * a reset should return to.
23723
+ * - `feedback`: What is wrong, in the reader's words rather than the browser's.
23724
+ * - `hint`: Help under the control, shown while there is nothing wrong.
23725
+ * - `label`: The accessible name, and the fallback for the `label` slot.
23726
+ * - `required`: Whether the form refuses to submit without it.
23727
+ * - `clearable`: Whether the field offers a button that empties it.
23728
+ *
23729
+ * The text only. The tokens are the consumer's markup and this element is not
23730
+ * entitled to take them out of the document, which is the same reason
23731
+ * `hideOverflow` marks the ones over the cap `hidden` rather than removing
23732
+ * them.
23733
+ * - `clear-label`/`clearLabel`: What the clear button is called, since an icon has no name of its own.
23734
+ * - `placeholder`: Shown while the field is empty.
23735
+ *
23736
+ * Not a label: it goes when typing starts.
23737
+ * - `disabled`: Whether the control is non-interactive.
23738
+ *
23739
+ * Reflected, because the styled tier selects on it, and mirrored to
23740
+ * `aria-disabled` rather than removing the element from the accessibility
23741
+ * tree, so a screen reader can still announce that the control exists.
23742
+ *
23743
+ * The mirror itself is in `willUpdate` below, here rather than in each
23744
+ * control, because here is where `disabled` is.
23745
+ * - `name`: Name submitted with the form.
23746
+ *
23747
+ * **Reflected, and it is the exception to "reflect only what CSS selects
23748
+ * on".** The platform builds a form's entry list from the `name` *content
23749
+ * attribute*, not from the property, so a control named through the property
23750
+ * submitted under no name at all and was silently dropped. Measured: two
23751
+ * inputs in one form, one named by attribute and one by property, and the
23752
+ * form carried a single entry.
23753
+ *
23754
+ * Safe for a React consumer, which is what the rule is protecting: React
23755
+ * renders a custom element's props as attributes on the server, so the name
23756
+ * is already in the markup being hydrated and reflecting it writes what is
23757
+ * there. It is only a change to the markup when a consumer assigns it
23758
+ * imperatively later, and nothing is hydrating by then.
23759
+ *
23760
+ * Here rather than on each control.
23761
+ * - `form`: The form this control belongs to, if any. (property only) (readonly)
23762
+ * - `labels`: Labels associated with this control. (property only) (readonly)
23763
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
23764
+ *
23765
+ * **Named `whenSettled` because `settled` is taken four times over**, by
23766
+ * Image, Splitter and both color controls, none of them about transitions. A
23767
+ * base class takes the name every subclass then cannot use.
23768
+ *
23769
+ * **The state it reports cannot be watched, which is why this exists.** A
23770
+ * custom state is deliberately not in the DOM, so there is no
23771
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
23772
+ * instead.
23773
+ *
23774
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
23775
+ * the suppression is still active in. That is the distinction `readyToMove`
23776
+ * in `@fusion.dev/helix-testing` is written around.
23777
+ *
23778
+ * It never resolves where `requestAnimationFrame` never fires, which is a
23779
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
23780
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
23781
+ *
23782
+ * ## Events
23783
+ *
23784
+ * Events that will be emitted by the component.
23785
+ *
23786
+ * - `input`: Announced once the text has moved.
23787
+ * - `change`: Relayed from the input once the reader has finished.
23788
+ * - `helix-before-change`: Fired as the text changes, and cancelable.
23789
+ *
23790
+ * ## Slots
23791
+ *
23792
+ * Areas where markup can be added to the component.
23793
+ *
23794
+ * - `end`: After the text, for a count or a control.
23795
+ * - `start`: Before the text, for a search icon.
23796
+ * - `tags`: What is already narrowing the results, as `Tag`s.
23797
+ *
23798
+ * ## Methods
23799
+ *
23800
+ * Methods that can be called to access component functionality.
23801
+ *
23802
+ * - `requestValue(next: string) => boolean`: Requests a new value, and reports whether the request stood.
23803
+ *
23804
+ * Announces before it acts, so `preventDefault()` on the `helix-before-change` is
23805
+ * a refusal and nothing moves. Nobody refusing means the control updates
23806
+ * itself, whether or not a consumer declared `value`: a declared property
23807
+ * is a seed and a correction, the way `<input value>` is, and a consumer
23808
+ * who wants the change for themselves refuses it and assigns their own.
23809
+ * - `formResetCallback() => void`: Returns the control to the value its markup declared.
23810
+ *
23811
+ * Both halves are dropped, the consumer's and the control's, because a
23812
+ * reset means the form is as it was served. Clearing only the internal one
23813
+ * would leave a control that had been written to stuck at that value.
23814
+ * - `formStateRestoreCallback(state: string | null) => void`: Restores the value when the browser brings a form back.
23815
+ *
23816
+ * Falling back to `defaultValue` rather than to empty, because a restore
23817
+ * with no state is a form the browser has nothing recorded for, which is
23818
+ * the same situation as a fresh one.
23819
+ * - `focus(options?: FocusOptions) => void`: Puts the caret in the field, the way a label pointing at one would.
23820
+ * - `formDisabledCallback(disabled: boolean) => void`: The platform's notice that an ancestor fieldset changed.
23821
+ *
23822
+ * **The argument is the effective state, and taking it whole is what latched
23823
+ * every control in the library.** The platform calls this for the element's
23824
+ * own `disabled` as well as for a fieldset, and our own arrives here at the
23825
+ * worst possible moment: reflecting `disabled` to the attribute happens
23826
+ * inside Lit's `update()`, the UA fires this synchronously from that write,
23827
+ * and a reactive write during an update is a change-in-update Lit does not
23828
+ * re-render for. So `formDisabled` ran exactly one update behind forever.
23829
+ *
23830
+ * Measured on Slider, logging what `render` saw:
23831
+ *
23832
+ * ```
23833
+ * set true disabled true formDisabled false isDisabled true
23834
+ * set false disabled false formDisabled true isDisabled true <- stale
23835
+ * (no third render)
23836
+ * ```
23837
+ *
23838
+ * The host came out right every time, `disabled` false, `:disabled` not
23839
+ * matching, and the inner control kept the attribute, so a control disabled
23840
+ * once could never be re-enabled. It only shows when something re-enables,
23841
+ * which is the same shape of bug `inheritDisabled` was written for.
23842
+ *
23843
+ * Our own half is already in `this.disabled` and `isDisabled` is an or, so
23844
+ * this records only what the fieldset adds. That also removes the write
23845
+ * entirely on the own-disabled path rather than moving it.
23846
+ *
23847
+ * The one case this cannot see is a control that is disabled itself *and*
23848
+ * inside a disabled fieldset, whose own `disabled` is then removed: the
23849
+ * effective state does not change, so the platform does not call again, and
23850
+ * the fieldset's hold is not recorded. There is no callback to learn it from
23851
+ * and reading `:disabled` here would answer about the attribute we are in the
23852
+ * middle of removing.
23853
+ *
23854
+ * ## CSS Custom Properties
23855
+ *
23856
+ * CSS variables available for styling the component.
23857
+ *
23858
+ * - `--filter-input-background-color`: Fill behind the field. (default: `undefined`)
23859
+ * - `--filter-input-control-size`: Smallest the text keeps as tokens fill the line, before it wraps to its own. (default: `undefined`)
23860
+ * - `--filter-input-size`: Height of the field with nothing in it, which it grows from. (default: `undefined`)
23861
+ *
23862
+ * ## CSS Parts
23863
+ *
23864
+ * Custom selectors for styling elements within the component.
23865
+ *
23866
+ * - `clear`: The button that empties the field.
23867
+ * - `control`: The input itself.
23868
+ * - `feedback`: What is wrong with it.
23869
+ * - `field`: The box holding everything.
23870
+ * - `hint`: Help under the field, while nothing is wrong.
23871
+ * - `label`: The question, over the field.
23872
+ * - `rest`: How many tokens did not fit.
23873
+ * - `tags`: The row the tokens sit in.
23874
+ */
23875
+ "helix-filter-input": Partial<
23876
+ HelixFilterInputProps & BaseProps<HelixFilterInput> & BaseEvents<HelixFilterInput>
23877
+ >;
23878
+
23587
23879
  /**
23588
23880
  * The host is the flex container itself and the only child is a slot, so the
23589
23881
  * element adds no box of its own: `<helix-flex>` costs exactly the `<div>` it
@@ -37077,6 +37369,7 @@ export type CustomElementsSolidJs = {
37077
37369
  * last reader did rather than what the author wrote. `:state(open)` carries
37078
37370
  * the resolved state for stylesheets, which is what the mirror is for.
37079
37371
  * - `default-open`/`defaultOpen`: Initial open state for uncontrolled use, where nothing declared one.
37372
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
37080
37373
  * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
37081
37374
  * - `value`: What the control holds now, and what its form submits.
37082
37375
  *
@@ -37108,18 +37401,6 @@ export type CustomElementsSolidJs = {
37108
37401
  * Passed straight to the list, which is where the rows are and so where the
37109
37402
  * message belongs.
37110
37403
  * - `loading-text`/`loadingText`: What the list says while they are on their way.
37111
- * - `max-tags`/`maxTags`: How many tags to draw before the rest become a count. `multiple` only.
37112
- *
37113
- * `0` is all of them, and is the default: a cap that guesses is worse than no
37114
- * cap, because the number that fits depends on the width of the field and the
37115
- * length of what is in it, neither of which this element knows. What a cap is
37116
- * genuinely for is a field in a row or a table cell, where a set of twelve
37117
- * choices would push everything below it down a line at a time.
37118
- *
37119
- * The remainder is counted rather than hidden. `+3` is a fact a reader can act
37120
- * on, where a row that silently stops is a field that appears to have lost
37121
- * what was put in it. Date Input and Time Input carry the same property and
37122
- * the same reasoning.
37123
37404
  * - `multiple`: Whether more than one option can be chosen.
37124
37405
  *
37125
37406
  * The list already does the work: `value` comes apart on commas, a press
@@ -39410,6 +39691,190 @@ export type CustomElementsSolidJs = {
39410
39691
  BaseEvents<HelixFileInput>
39411
39692
  >;
39412
39693
 
39694
+ /**
39695
+ * The frame is the field rather than the input, so the tokens sit inside the
39696
+ * same box as the text and the focus ring is drawn once around the whole
39697
+ * control. It grows down a line at a time as tokens are added, which is the
39698
+ * arrangement Combobox takes when it is holding a selection.
39699
+ *
39700
+ * **The tokens are the consumer's own elements**, so the only thing said about
39701
+ * them here is to keep their size and not run past the field. A `Tag` slotted
39702
+ * into `tags` already looks like one; anything else looks like whatever it is.
39703
+ *
39704
+ * Height comes from the region, like every other control: `data-density` on
39705
+ * whatever holds it, not a `size` here.
39706
+ *
39707
+ * ## Attributes & Properties
39708
+ *
39709
+ * Component attributes and properties that can be applied to the element or by using JavaScript.
39710
+ *
39711
+ * - `max-tags`/`maxTags`: How many tokens to show before the rest become a count.
39712
+ * - `default-value`/`defaultValue`: The value the markup declared, which is where a reset returns to.
39713
+ * - `value`: What the control holds now, and what its form submits.
39714
+ *
39715
+ * One property, not two, so `input.value` answers the question anyone
39716
+ * asking it meant. Writing always applies; `<helix-input value="x">` is the
39717
+ * same statement in markup, and `default-value` is how markup seeds a value
39718
+ * a reset should return to.
39719
+ * - `feedback`: What is wrong, in the reader's words rather than the browser's.
39720
+ * - `hint`: Help under the control, shown while there is nothing wrong.
39721
+ * - `label`: The accessible name, and the fallback for the `label` slot.
39722
+ * - `required`: Whether the form refuses to submit without it.
39723
+ * - `clearable`: Whether the field offers a button that empties it.
39724
+ *
39725
+ * The text only. The tokens are the consumer's markup and this element is not
39726
+ * entitled to take them out of the document, which is the same reason
39727
+ * `hideOverflow` marks the ones over the cap `hidden` rather than removing
39728
+ * them.
39729
+ * - `clear-label`/`clearLabel`: What the clear button is called, since an icon has no name of its own.
39730
+ * - `placeholder`: Shown while the field is empty.
39731
+ *
39732
+ * Not a label: it goes when typing starts.
39733
+ * - `disabled`: Whether the control is non-interactive.
39734
+ *
39735
+ * Reflected, because the styled tier selects on it, and mirrored to
39736
+ * `aria-disabled` rather than removing the element from the accessibility
39737
+ * tree, so a screen reader can still announce that the control exists.
39738
+ *
39739
+ * The mirror itself is in `willUpdate` below, here rather than in each
39740
+ * control, because here is where `disabled` is.
39741
+ * - `name`: Name submitted with the form.
39742
+ *
39743
+ * **Reflected, and it is the exception to "reflect only what CSS selects
39744
+ * on".** The platform builds a form's entry list from the `name` *content
39745
+ * attribute*, not from the property, so a control named through the property
39746
+ * submitted under no name at all and was silently dropped. Measured: two
39747
+ * inputs in one form, one named by attribute and one by property, and the
39748
+ * form carried a single entry.
39749
+ *
39750
+ * Safe for a React consumer, which is what the rule is protecting: React
39751
+ * renders a custom element's props as attributes on the server, so the name
39752
+ * is already in the markup being hydrated and reflecting it writes what is
39753
+ * there. It is only a change to the markup when a consumer assigns it
39754
+ * imperatively later, and nothing is hydrating by then.
39755
+ *
39756
+ * Here rather than on each control.
39757
+ * - `form`: The form this control belongs to, if any. (property only) (readonly)
39758
+ * - `labels`: Labels associated with this control. (property only) (readonly)
39759
+ * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
39760
+ *
39761
+ * **Named `whenSettled` because `settled` is taken four times over**, by
39762
+ * Image, Splitter and both color controls, none of them about transitions. A
39763
+ * base class takes the name every subclass then cannot use.
39764
+ *
39765
+ * **The state it reports cannot be watched, which is why this exists.** A
39766
+ * custom state is deliberately not in the DOM, so there is no
39767
+ * `MutationObserver` equivalent for `ElementInternals.states`. Await this
39768
+ * instead.
39769
+ *
39770
+ * Separate from `updateComplete`, which resolves in the microtask checkpoint
39771
+ * the suppression is still active in. That is the distinction `readyToMove`
39772
+ * in `@fusion.dev/helix-testing` is written around.
39773
+ *
39774
+ * It never resolves where `requestAnimationFrame` never fires, which is a
39775
+ * server, a hidden tab, and happy-dom. Callers that must not hang race it
39776
+ * against a timeout; `readyToMove` does exactly that. (property only) (readonly)
39777
+ *
39778
+ * ## Events
39779
+ *
39780
+ * Events that will be emitted by the component.
39781
+ *
39782
+ * - `input`: Announced once the text has moved.
39783
+ * - `change`: Relayed from the input once the reader has finished.
39784
+ * - `helix-before-change`: Fired as the text changes, and cancelable.
39785
+ *
39786
+ * ## Slots
39787
+ *
39788
+ * Areas where markup can be added to the component.
39789
+ *
39790
+ * - `end`: After the text, for a count or a control.
39791
+ * - `start`: Before the text, for a search icon.
39792
+ * - `tags`: What is already narrowing the results, as `Tag`s.
39793
+ *
39794
+ * ## Methods
39795
+ *
39796
+ * Methods that can be called to access component functionality.
39797
+ *
39798
+ * - `requestValue(next: string) => boolean`: Requests a new value, and reports whether the request stood.
39799
+ *
39800
+ * Announces before it acts, so `preventDefault()` on the `helix-before-change` is
39801
+ * a refusal and nothing moves. Nobody refusing means the control updates
39802
+ * itself, whether or not a consumer declared `value`: a declared property
39803
+ * is a seed and a correction, the way `<input value>` is, and a consumer
39804
+ * who wants the change for themselves refuses it and assigns their own.
39805
+ * - `formResetCallback() => void`: Returns the control to the value its markup declared.
39806
+ *
39807
+ * Both halves are dropped, the consumer's and the control's, because a
39808
+ * reset means the form is as it was served. Clearing only the internal one
39809
+ * would leave a control that had been written to stuck at that value.
39810
+ * - `formStateRestoreCallback(state: string | null) => void`: Restores the value when the browser brings a form back.
39811
+ *
39812
+ * Falling back to `defaultValue` rather than to empty, because a restore
39813
+ * with no state is a form the browser has nothing recorded for, which is
39814
+ * the same situation as a fresh one.
39815
+ * - `focus(options?: FocusOptions) => void`: Puts the caret in the field, the way a label pointing at one would.
39816
+ * - `formDisabledCallback(disabled: boolean) => void`: The platform's notice that an ancestor fieldset changed.
39817
+ *
39818
+ * **The argument is the effective state, and taking it whole is what latched
39819
+ * every control in the library.** The platform calls this for the element's
39820
+ * own `disabled` as well as for a fieldset, and our own arrives here at the
39821
+ * worst possible moment: reflecting `disabled` to the attribute happens
39822
+ * inside Lit's `update()`, the UA fires this synchronously from that write,
39823
+ * and a reactive write during an update is a change-in-update Lit does not
39824
+ * re-render for. So `formDisabled` ran exactly one update behind forever.
39825
+ *
39826
+ * Measured on Slider, logging what `render` saw:
39827
+ *
39828
+ * ```
39829
+ * set true disabled true formDisabled false isDisabled true
39830
+ * set false disabled false formDisabled true isDisabled true <- stale
39831
+ * (no third render)
39832
+ * ```
39833
+ *
39834
+ * The host came out right every time, `disabled` false, `:disabled` not
39835
+ * matching, and the inner control kept the attribute, so a control disabled
39836
+ * once could never be re-enabled. It only shows when something re-enables,
39837
+ * which is the same shape of bug `inheritDisabled` was written for.
39838
+ *
39839
+ * Our own half is already in `this.disabled` and `isDisabled` is an or, so
39840
+ * this records only what the fieldset adds. That also removes the write
39841
+ * entirely on the own-disabled path rather than moving it.
39842
+ *
39843
+ * The one case this cannot see is a control that is disabled itself *and*
39844
+ * inside a disabled fieldset, whose own `disabled` is then removed: the
39845
+ * effective state does not change, so the platform does not call again, and
39846
+ * the fieldset's hold is not recorded. There is no callback to learn it from
39847
+ * and reading `:disabled` here would answer about the attribute we are in the
39848
+ * middle of removing.
39849
+ *
39850
+ * ## CSS Custom Properties
39851
+ *
39852
+ * CSS variables available for styling the component.
39853
+ *
39854
+ * - `--filter-input-background-color`: Fill behind the field. (default: `undefined`)
39855
+ * - `--filter-input-control-size`: Smallest the text keeps as tokens fill the line, before it wraps to its own. (default: `undefined`)
39856
+ * - `--filter-input-size`: Height of the field with nothing in it, which it grows from. (default: `undefined`)
39857
+ *
39858
+ * ## CSS Parts
39859
+ *
39860
+ * Custom selectors for styling elements within the component.
39861
+ *
39862
+ * - `clear`: The button that empties the field.
39863
+ * - `control`: The input itself.
39864
+ * - `feedback`: What is wrong with it.
39865
+ * - `field`: The box holding everything.
39866
+ * - `hint`: Help under the field, while nothing is wrong.
39867
+ * - `label`: The question, over the field.
39868
+ * - `rest`: How many tokens did not fit.
39869
+ * - `tags`: The row the tokens sit in.
39870
+ */
39871
+ "helix-filter-input": Partial<
39872
+ HelixFilterInputProps &
39873
+ HelixFilterInputSolidJsProps &
39874
+ BaseProps<HelixFilterInput> &
39875
+ BaseEvents<HelixFilterInput>
39876
+ >;
39877
+
39413
39878
  /**
39414
39879
  * The host is the flex container itself and the only child is a slot, so the
39415
39880
  * element adds no box of its own: `<helix-flex>` costs exactly the `<div>` it
@@ -50181,6 +50646,12 @@ export type CustomCssProperties = {
50181
50646
  "--file-input-background-color"?: (string) | undefined;
50182
50647
  /** Padding inside the field. */
50183
50648
  "--file-input-padding"?: (string) | undefined;
50649
+ /** Fill behind the field. */
50650
+ "--filter-input-background-color"?: (string) | undefined;
50651
+ /** Smallest the text keeps as tokens fill the line, before it wraps to its own. */
50652
+ "--filter-input-control-size"?: (string) | undefined;
50653
+ /** Height of the field with nothing in it, which it grows from. */
50654
+ "--filter-input-size"?: (string) | undefined;
50184
50655
  /** An explicit track list, which wins over `min` and `columns`. For a layout of unequal tracks, which neither attribute can say. */
50185
50656
  "--grid-columns"?: (string) | undefined;
50186
50657
  /** How tall a cell is. A row of a tall thin cell is what a status page draws. */