@fusion.dev/helix 0.12.3 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20753,6 +20753,18 @@
20753
20753
  "module": "src/combobox/root/combobox-root.ts"
20754
20754
  }
20755
20755
  },
20756
+ {
20757
+ "type": {
20758
+ "text": "HelixFilterEvent"
20759
+ },
20760
+ "description": "Fired as the reader types, carrying the text the list is being narrowed to. Cancelable: refusing it leaves the list whole, and is how a consumer takes the filtering for themselves.",
20761
+ "name": "helix-filter",
20762
+ "reactProp": "onhelix-filter",
20763
+ "inheritedFrom": {
20764
+ "name": "HelixHeadlessCombobox",
20765
+ "module": "src/combobox/root/combobox-root.ts"
20766
+ }
20767
+ },
20756
20768
  {
20757
20769
  "type": {
20758
20770
  "text": "Event"
@@ -34363,7 +34375,7 @@
34363
34375
  },
34364
34376
  {
34365
34377
  "kind": "javascript-module",
34366
- "path": "src/flex/index.ts",
34378
+ "path": "src/filter-input/index.ts",
34367
34379
  "declarations": [],
34368
34380
  "exports": [
34369
34381
  {
@@ -34371,14 +34383,14 @@
34371
34383
  "name": "*",
34372
34384
  "declaration": {
34373
34385
  "name": "*",
34374
- "module": "src/flex/root/flex-root.js"
34386
+ "module": "src/filter-input/root/filter-input-root.js"
34375
34387
  }
34376
34388
  }
34377
34389
  ]
34378
34390
  },
34379
34391
  {
34380
34392
  "kind": "javascript-module",
34381
- "path": "src/flex/root/flex-root.css.ts",
34393
+ "path": "src/filter-input/root/filter-input-root.css.ts",
34382
34394
  "declarations": [
34383
34395
  {
34384
34396
  "kind": "variable",
@@ -34391,241 +34403,1632 @@
34391
34403
  "name": "styles",
34392
34404
  "declaration": {
34393
34405
  "name": "styles",
34394
- "module": "src/flex/root/flex-root.css.ts"
34406
+ "module": "src/filter-input/root/filter-input-root.css.ts"
34395
34407
  }
34396
34408
  }
34397
34409
  ]
34398
34410
  },
34399
34411
  {
34400
34412
  "kind": "javascript-module",
34401
- "path": "src/flex/root/flex-root.ts",
34413
+ "path": "src/filter-input/root/filter-input-root.ts",
34402
34414
  "declarations": [
34403
34415
  {
34404
34416
  "kind": "class",
34405
- "description": "The host is the flex container itself and the only child is a slot, so the\nelement adds no box of its own: `<helix-flex>` costs exactly the `<div>` it\nreplaces.\n\nThere is no separate Stack. A stack is this with `direction=\"column\"`, and a\nsecond element whose whole definition is one default of the first is a name\nto learn rather than a capability to gain.\n\nGap takes a space token name rather than a length, so spacing stays on the\nscale. A layout that can say `gap=\"13px\"` is one that will.\n\nPresentation only, so there is no headless tier: the split exists to keep\nbehavior separate from styling, and this is entirely styling.",
34406
- "name": "HelixFlex",
34407
- "slots": [
34408
- {
34409
- "description": "The items to lay out.",
34410
- "name": ""
34411
- }
34412
- ],
34413
- "members": [
34414
- {
34415
- "kind": "field",
34416
- "name": "align",
34417
- "type": {
34418
- "text": "'start' | 'center' | 'end' | 'stretch' | 'baseline' | undefined"
34419
- },
34420
- "description": "Alignment across the direction.",
34421
- "attribute": "align",
34422
- "reflects": true
34423
- },
34424
- {
34425
- "kind": "field",
34426
- "name": "direction",
34427
- "type": {
34428
- "text": "'row' | 'column' | undefined"
34429
- },
34430
- "description": "Whether items run across or down.",
34431
- "attribute": "direction",
34432
- "reflects": true
34433
- },
34434
- {
34435
- "kind": "field",
34436
- "name": "gap",
34437
- "type": {
34438
- "text": "'none' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | undefined"
34439
- },
34440
- "description": "Space between items, named on the space scale.",
34441
- "attribute": "gap",
34442
- "reflects": true
34443
- },
34417
+ "description": "The frame is the field rather than the input, so the tokens sit inside the\nsame box as the text and the focus ring is drawn once around the whole\ncontrol. It grows down a line at a time as tokens are added, which is the\narrangement Combobox takes when it is holding a selection.\n\n**The tokens are the consumer's own elements**, so the only thing said about\nthem here is to keep their size and not run past the field. A `Tag` slotted\ninto `tags` already looks like one; anything else looks like whatever it is.\n\nHeight comes from the region, like every other control: `data-density` on\nwhatever holds it, not a `size` here.",
34418
+ "name": "HelixFilterInput",
34419
+ "cssProperties": [
34444
34420
  {
34445
- "kind": "field",
34446
- "name": "inline",
34447
- "type": {
34448
- "text": "boolean"
34449
- },
34450
- "default": "false",
34451
- "description": "Flows with surrounding text instead of taking the full width.",
34452
- "attribute": "inline",
34453
- "reflects": true
34421
+ "description": "Fill behind the field.",
34422
+ "name": "--filter-input-background-color"
34454
34423
  },
34455
34424
  {
34456
- "kind": "field",
34457
- "name": "justify",
34458
- "type": {
34459
- "text": "'start' | 'center' | 'end' | 'between' | 'around' | undefined"
34460
- },
34461
- "description": "Distribution along the direction.",
34462
- "attribute": "justify",
34463
- "reflects": true
34425
+ "description": "Smallest the text keeps as tokens fill the line, before it wraps to its own.",
34426
+ "name": "--filter-input-control-size"
34464
34427
  },
34465
34428
  {
34466
- "kind": "field",
34467
- "name": "wrap",
34468
- "type": {
34469
- "text": "boolean"
34470
- },
34471
- "default": "false",
34472
- "description": "Whether items wrap onto more lines.",
34473
- "attribute": "wrap",
34474
- "reflects": true
34475
- },
34429
+ "description": "Height of the field with nothing in it, which it grows from.",
34430
+ "name": "--filter-input-size"
34431
+ }
34432
+ ],
34433
+ "members": [
34476
34434
  {
34477
34435
  "kind": "field",
34478
- "name": "tier",
34436
+ "name": "maxTags",
34479
34437
  "type": {
34480
- "text": "string"
34438
+ "text": "number"
34481
34439
  },
34482
- "static": true,
34483
- "default": "'helix-headless-'",
34484
- "description": "The prefix this tier registers its elements under.\n\n**A component that renders another renders its own tier's version of it**,\nso `helix-headless-pagination-size` composes `helix-headless-select` and\n`helix-pagination-size` composes `helix-select`. One template says\n`${this.tag('select')}` and each tier answers with its own name.\n\n**The public tag may not be the composed one, in either tier.** Using it\ncosts three things: the name means two different things depending on what a\nconsumer imported, the headless tier composes an element it does not ship,\nand the composition cannot be tested there at all, because there is no\n`helix-select` on that tier to test it against.\n\n**A prefix rather than an override per composition**, which was the first\nplan and does not compile. An override re-renders the fragment from the\nsubclass, and the fragment reads members the base keeps private:\n`PaginationSize` alone would have had to widen `options`, `current` and\n`handleChange` to `protected` so a subclass could say the same thing again.\nSixteen families of that is a lot of encapsulation spent on saying one\nword differently.",
34440
+ "default": "0",
34441
+ "description": "How many tokens to show before the rest become a count.",
34442
+ "attribute": "max-tags",
34485
34443
  "inheritedFrom": {
34486
- "name": "HelixElement",
34487
- "module": "src/helix-element/helix-element.ts"
34444
+ "name": "MixinTokens",
34445
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
34488
34446
  }
34489
34447
  },
34490
34448
  {
34491
34449
  "kind": "method",
34492
- "name": "tag",
34450
+ "name": "renderTokenRow",
34493
34451
  "privacy": "protected",
34494
34452
  "return": {
34495
34453
  "type": {
34496
- "text": "StaticValue"
34454
+ "text": "TemplateResult | typeof nothing"
34497
34455
  }
34498
34456
  },
34499
34457
  "parameters": [
34500
34458
  {
34501
- "name": "name",
34459
+ "name": "content",
34502
34460
  "type": {
34503
- "text": "string"
34461
+ "text": "unknown"
34462
+ }
34463
+ },
34464
+ {
34465
+ "name": "over",
34466
+ "type": {
34467
+ "text": "number"
34504
34468
  }
34505
34469
  }
34506
34470
  ],
34507
- "description": "One composed tag, as a static value a template can interpolate.\n\n`unsafeStatic` is safe by construction: the name is a literal in our own\nsource and the prefix is one of two strings this class defines. Called per\nrender and not cached, which costs nothing, because `static-html` keys its\ntemplate cache on the joined string rather than on the object.",
34508
34471
  "inheritedFrom": {
34509
- "name": "HelixElement",
34510
- "module": "src/helix-element/helix-element.ts"
34472
+ "name": "MixinTokens",
34473
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
34511
34474
  }
34512
34475
  },
34513
34476
  {
34514
- "kind": "field",
34515
- "name": "internals",
34516
- "type": {
34517
- "text": "ElementInternals"
34518
- },
34477
+ "kind": "method",
34478
+ "name": "hideOverflow",
34519
34479
  "privacy": "protected",
34520
- "readonly": true,
34521
- "description": "The element's semantics, set without touching the DOM.\n\n`ElementInternals` sets the implicit role, which an author's own `role`\nattribute still overrides, and it writes no attribute. Setting `role` on the\nhost directly would: that is an attribute the element gives itself after it\nupgrades, which a React consumer's server markup never had, and hydration\nreports it as a mismatch.\n\nAvailable during server rendering. Lit's shim implements `attachInternals`,\nso nothing here needs a guard.",
34480
+ "return": {
34481
+ "type": {
34482
+ "text": "number"
34483
+ }
34484
+ },
34485
+ "parameters": [
34486
+ {
34487
+ "name": "slot",
34488
+ "type": {
34489
+ "text": "HTMLSlotElement | null | undefined"
34490
+ }
34491
+ }
34492
+ ],
34522
34493
  "inheritedFrom": {
34523
- "name": "HelixElement",
34524
- "module": "src/helix-element/helix-element.ts"
34494
+ "name": "MixinTokens",
34495
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
34525
34496
  }
34526
34497
  },
34527
34498
  {
34528
34499
  "kind": "method",
34529
- "name": "toggleState",
34500
+ "name": "tokenKeydown",
34530
34501
  "privacy": "protected",
34531
34502
  "return": {
34532
34503
  "type": {
34533
- "text": "void"
34504
+ "text": "boolean"
34534
34505
  }
34535
34506
  },
34536
34507
  "parameters": [
34537
34508
  {
34538
- "name": "name",
34509
+ "name": "event",
34539
34510
  "type": {
34540
- "text": "string"
34511
+ "text": "KeyboardEvent"
34541
34512
  }
34542
34513
  },
34543
34514
  {
34544
- "name": "on",
34515
+ "name": "typed",
34545
34516
  "type": {
34546
- "text": "boolean"
34517
+ "text": "string"
34547
34518
  }
34548
34519
  }
34549
34520
  ],
34550
- "description": "Records a boolean fact about this element as a custom state.\n\n**The host belongs to whoever rendered it, and a component's own\nbookkeeping may not be kept there.** An attribute written on the first\nupdate is markup a consumer's server never sent, so a React consumer\nhydrates a DOM that has gained attributes since and reports a mismatch it\nwill not patch up. A custom state is not in the DOM at all: it carries the\nfact to a stylesheet through `:state()` and leaves the markup alone, so the\nserver's output and the client's agree by construction.\n\n`SETTLED` carries the long version of that argument; `checked`, `open`,\n`invalid` and `has-label` are recorded the same way, each of them a state a\n`default-*` attribute resolves before React reaches the node.\n\n**Deferring the definitions is not a fix and could not be.** Importing them\nfrom an effect so the upgrades fall the other side of hydration works only\nwhile hydration is one pass: anything that splits it, a streamed segment or\na suspended boundary, puts an upgrade back inside the window. Timing cannot\nbe the guarantee when the fact is kept somewhere React reconciles.\n\nFeature-tested rather than assumed, the way `hostAria` tests element\nreferences. An engine without `CustomStateSet` records nothing and keeps\nwhatever the resting rule draws, which is the safe direction to fail.\n\n**The engines the test is for are browsers**: Safari below 17.4 and Firefox\nbelow 126, where the write is a `TypeError`, so a component bypassing this\nfails to render rather than rendering without whatever the state draws.\nLit's server shim sets `states`, so the guard passes there and records a\nstate nothing reads, which is harmless.",
34551
34521
  "inheritedFrom": {
34552
- "name": "HelixElement",
34553
- "module": "src/helix-element/helix-element.ts"
34522
+ "name": "MixinTokens",
34523
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
34524
+ }
34525
+ },
34526
+ {
34527
+ "kind": "method",
34528
+ "name": "removeLastToken",
34529
+ "privacy": "protected",
34530
+ "return": {
34531
+ "type": {
34532
+ "text": "void"
34533
+ }
34534
+ },
34535
+ "description": "Asks the last token to go, rather than taking it.\n\n`dismiss()` is the tag's own, so this is the code path its remove control\nalready runs on a press: the consumer hears one `helix-dismiss`, cancels it\nor removes the element, and never learns which of the two asked. A slotted\nnode that is not a `Tag` has no such method and is left alone, because\nhiding a consumer's element on Backspace would be this element deciding\nsomething it was never given.",
34536
+ "inheritedFrom": {
34537
+ "name": "MixinTokens",
34538
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
34554
34539
  }
34555
34540
  },
34556
34541
  {
34557
34542
  "kind": "field",
34558
- "name": "whenSettled",
34543
+ "name": "defaultValue",
34559
34544
  "type": {
34560
- "text": "Promise<void>"
34545
+ "text": "string"
34561
34546
  },
34562
- "readonly": true,
34563
- "description": "Resolves a frame after the first update, when transitions are switched on.\n\n**Named `whenSettled` because `settled` is taken four times over**, by\nImage, Splitter and both color controls, none of them about transitions. A\nbase class takes the name every subclass then cannot use.\n\n**The state it reports cannot be watched, which is why this exists.** A\ncustom state is deliberately not in the DOM, so there is no\n`MutationObserver` equivalent for `ElementInternals.states`. Await this\ninstead.\n\nSeparate from `updateComplete`, which resolves in the microtask checkpoint\nthe suppression is still active in. That is the distinction `readyToMove`\nin `@fusion.dev/helix-testing` is written around.\n\nIt never resolves where `requestAnimationFrame` never fires, which is a\nserver, a hidden tab, and happy-dom. Callers that must not hang race it\nagainst a timeout; `readyToMove` does exactly that.",
34564
- "default": "new Promise<void>((resolve) => { this.resolveSettled = resolve })",
34547
+ "default": "''",
34548
+ "description": "The value the markup declared, which is where a reset returns to.",
34549
+ "attribute": "default-value",
34565
34550
  "inheritedFrom": {
34566
- "name": "HelixElement",
34567
- "module": "src/helix-element/helix-element.ts"
34551
+ "name": "MixinControllerValue",
34552
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34568
34553
  }
34569
34554
  },
34570
34555
  {
34571
34556
  "kind": "field",
34572
- "name": "resolveSettled",
34557
+ "name": "value",
34573
34558
  "type": {
34574
- "text": "() => void"
34559
+ "text": "string"
34560
+ },
34561
+ "description": "What the control holds now, and what its form submits.\n\nOne property, not two, so `input.value` answers the question anyone\nasking it meant. Writing always applies; `<helix-input value=\"x\">` is the\nsame statement in markup, and `default-value` is how markup seeds a value\na reset should return to.",
34562
+ "attribute": "value",
34563
+ "inheritedFrom": {
34564
+ "name": "MixinControllerValue",
34565
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34566
+ }
34567
+ },
34568
+ {
34569
+ "kind": "field",
34570
+ "name": "valueState",
34571
+ "type": {
34572
+ "text": "string | undefined"
34575
34573
  },
34576
34574
  "privacy": "private",
34577
- "description": "Resolves `whenSettled`, once, from the frame that records the state.",
34575
+ "default": "undefined",
34576
+ "description": "The state, whoever set it, and `undefined` until somebody has.\n\nOne field and not two. Writing always applies, the way a native control\ndoes when a script assigns to it.",
34578
34577
  "inheritedFrom": {
34579
- "name": "HelixElement",
34580
- "module": "src/helix-element/helix-element.ts"
34578
+ "name": "MixinControllerValue",
34579
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34581
34580
  }
34582
34581
  },
34583
34582
  {
34584
34583
  "kind": "field",
34585
- "name": "stopInner",
34584
+ "name": "announcesInput",
34585
+ "type": {
34586
+ "text": "boolean"
34587
+ },
34586
34588
  "privacy": "protected",
34587
34589
  "readonly": true,
34588
- "description": "Stops an inner control's own announcement at this element's boundary.\n\n**A composed control is one control to a consumer, and the natives had no\nequivalent of the stop the prefixed events already get.** `<helix-select>`\nrenders a `<helix-listbox>`, and both announce: the listbox dispatches\n`input` and `change` from its own host, `input` is composed by\nspecification, and a consumer listening on the select therefore heard one\nchoice twice. Measured before this existed, on the styled tier, one choice\non the inner listbox: select `input` twice and `change` three times,\ncombobox, date input, time input and color input twice each. `Command` was\nthe only one that was right, because it happened to reach for\n`stopImmediatePropagation` for a different reason.\n\nBound on the child in the parent's template, so it runs while the event is\nstill at the child and before it can cross. The guard is for the case where\na component binds this on itself: an element must never stop its own\nannouncement, which is the one it exists to make.\n\nThis is the same job the `helix-before-*` handlers do with their own\n`stopPropagation`, and it is separate rather than folded into them because\na consumer may legitimately refuse a request without the notification ever\nhappening: the two travel at different times and one can be absent.",
34590
+ "default": "false",
34591
+ "description": "Whether a reader edits this continuously, which decides the native name.\n\nThe request event is `helix-before-change` whatever the answer; this\ndecides which native event announces the result, `input` while a reader\nis editing against `change` when they are done, which is the distinction\nthe platform already draws.\n\nDiscrete by default: only a control the reader edits continuously says\notherwise.",
34589
34592
  "inheritedFrom": {
34590
- "name": "HelixElement",
34591
- "module": "src/helix-element/helix-element.ts"
34593
+ "name": "MixinControllerValue",
34594
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34592
34595
  }
34593
34596
  },
34594
34597
  {
34595
34598
  "kind": "method",
34596
- "name": "relayNativeEvent",
34597
- "privacy": "protected",
34599
+ "name": "announceNatively",
34600
+ "privacy": "private",
34598
34601
  "return": {
34599
34602
  "type": {
34600
34603
  "text": "void"
34601
34604
  }
34602
34605
  },
34603
- "parameters": [
34604
- {
34605
- "name": "event",
34606
- "type": {
34607
- "text": "Event"
34608
- }
34609
- },
34610
- {
34611
- "name": "init",
34612
- "optional": true,
34613
- "type": {
34614
- "text": "EventInit"
34615
- }
34616
- }
34617
- ],
34618
- "description": "Re-emits a native event from the host, under its own name.\n\nA native event fired by an inner `<input>` or `<textarea>` is not composed,\nso it stops at the shadow boundary and a consumer listening on\n`<helix-input>` hears nothing. Re-dispatching it from the host is what\nmakes the component behave like the control it wraps.\n\nThe relayed event keeps the native name deliberately. `change` is `change`,\nwhich is what a consumer already knows to listen for, and it is what\nreaches React: its synthetic system claims `onChange` and wires it to that\nname, so a prefixed one would never arrive.\n\n`composed` is not forced. It defaults to the original event's own value, so\na relayed `change` stops at the next shadow boundary exactly as a native\none would. Pass it explicitly only where escaping is the intent, and say so\nwhere you do.",
34606
+ "description": "Announces the applied value under the platform's own name.\n\n**After `apply`, never before**, which is the whole reason this is\nseparate from the request event: a native handler reads\n`event.target.value`, and it has to be the value that was just applied.\n\n**Both, for a discrete control, because that is what the platform does.**\nA native `<select>` sends `input` and then `change` from one choice: the\nvalue moved, and the reader is also done. A continuous control announces\n`input` here and relays `change` from its inner control when the reader\nis done, so the pair keeps the platform's timings rather than reporting a\ncommit on every keystroke.",
34619
34607
  "inheritedFrom": {
34620
- "name": "HelixElement",
34621
- "module": "src/helix-element/helix-element.ts"
34608
+ "name": "MixinControllerValue",
34609
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34622
34610
  }
34623
34611
  },
34624
34612
  {
34625
34613
  "kind": "method",
34626
- "name": "finalizeStyles",
34627
- "privacy": "protected",
34628
- "static": true,
34614
+ "name": "requestValue",
34615
+ "return": {
34616
+ "type": {
34617
+ "text": "boolean"
34618
+ }
34619
+ },
34620
+ "parameters": [
34621
+ {
34622
+ "name": "next",
34623
+ "type": {
34624
+ "text": "string"
34625
+ }
34626
+ }
34627
+ ],
34628
+ "description": "Requests a new value, and reports whether the request stood.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-change` is\na refusal and nothing moves. Nobody refusing means the control updates\nitself, whether or not a consumer declared `value`: a declared property\nis a seed and a correction, the way `<input value>` is, and a consumer\nwho wants the change for themselves refuses it and assigns their own.",
34629
+ "inheritedFrom": {
34630
+ "name": "MixinControllerValue",
34631
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34632
+ },
34633
+ "type": {
34634
+ "text": "requestValue(next: string) => boolean"
34635
+ }
34636
+ },
34637
+ {
34638
+ "kind": "method",
34639
+ "name": "formResetCallback",
34640
+ "return": {
34641
+ "type": {
34642
+ "text": "void"
34643
+ }
34644
+ },
34645
+ "description": "Returns the control to the value its markup declared.\n\nBoth halves are dropped, the consumer's and the control's, because a\nreset means the form is as it was served. Clearing only the internal one\nwould leave a control that had been written to stuck at that value.",
34646
+ "inheritedFrom": {
34647
+ "name": "MixinControllerValue",
34648
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34649
+ },
34650
+ "type": {
34651
+ "text": "formResetCallback() => void"
34652
+ }
34653
+ },
34654
+ {
34655
+ "kind": "method",
34656
+ "name": "formStateRestoreCallback",
34657
+ "return": {
34658
+ "type": {
34659
+ "text": "void"
34660
+ }
34661
+ },
34662
+ "parameters": [
34663
+ {
34664
+ "name": "state",
34665
+ "type": {
34666
+ "text": "string | null"
34667
+ }
34668
+ }
34669
+ ],
34670
+ "description": "Restores the value when the browser brings a form back.\n\nFalling back to `defaultValue` rather than to empty, because a restore\nwith no state is a form the browser has nothing recorded for, which is\nthe same situation as a fresh one.",
34671
+ "inheritedFrom": {
34672
+ "name": "MixinControllerValue",
34673
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
34674
+ },
34675
+ "type": {
34676
+ "text": "formStateRestoreCallback(state: string | null) => void"
34677
+ }
34678
+ },
34679
+ {
34680
+ "kind": "field",
34681
+ "name": "feedback",
34682
+ "type": {
34683
+ "text": "string"
34684
+ },
34685
+ "default": "''",
34686
+ "description": "What is wrong, in the reader's words rather than the browser's.",
34687
+ "attribute": "feedback",
34688
+ "inheritedFrom": {
34689
+ "name": "MixinField",
34690
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34691
+ }
34692
+ },
34693
+ {
34694
+ "kind": "field",
34695
+ "name": "hint",
34696
+ "type": {
34697
+ "text": "string"
34698
+ },
34699
+ "default": "''",
34700
+ "description": "Help under the control, shown while there is nothing wrong.",
34701
+ "attribute": "hint",
34702
+ "inheritedFrom": {
34703
+ "name": "MixinField",
34704
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34705
+ }
34706
+ },
34707
+ {
34708
+ "kind": "field",
34709
+ "name": "label",
34710
+ "type": {
34711
+ "text": "string"
34712
+ },
34713
+ "default": "''",
34714
+ "description": "The accessible name, and the fallback for the `label` slot.",
34715
+ "attribute": "label",
34716
+ "inheritedFrom": {
34717
+ "name": "MixinField",
34718
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34719
+ }
34720
+ },
34721
+ {
34722
+ "kind": "field",
34723
+ "name": "required",
34724
+ "type": {
34725
+ "text": "boolean"
34726
+ },
34727
+ "default": "false",
34728
+ "description": "Whether the form refuses to submit without it.",
34729
+ "attribute": "required",
34730
+ "reflects": true,
34731
+ "inheritedFrom": {
34732
+ "name": "MixinField",
34733
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34734
+ }
34735
+ },
34736
+ {
34737
+ "kind": "field",
34738
+ "name": "touched",
34739
+ "type": {
34740
+ "text": "boolean"
34741
+ },
34742
+ "privacy": "private",
34743
+ "default": "false",
34744
+ "description": "Whether the reader has had a go at the field yet.\n\n**Not `:user-invalid`**, which is the platform's own answer to \"is this\nfield wrong *yet*\" and cannot work here, for a structural reason rather\nthan a browser bug: it tracks interaction with the element it is on, and\nnobody interacts with this element. The reader types into an `<input>`\ninside its shadow root, so the host's interaction flag is never set and\nthe selector never matches. Measured after submitting an invalid required\nfield and again after editing one and leaving it: false both times, while\n`:invalid` matched both times.\n\nSo the moments are listened for instead, and both of them demonstrably\nreach the host: `invalid` when a form is submitted with this control\nfailing, and `change` when the reader has edited and committed. Focus\nalone is deliberately not one of them. Tabbing past an empty required\nfield should not be answered with an error.\n\n**A composite control has to construct its own `change`, and this mixin\ndeliberately does not do it for them.** A native `change` is\n`composed: false`, so a control built from several inner inputs never\nrelays one to its host: `Input` gets this free from its one control,\nwhile a `PinInput` of four boxes has no inner `change` that means the\ncode is entered, so a half-entered code is never `touched` and can never\nsay what is wrong with it.\n\n**The obvious shared fix is for `touched` to take a `focusout`, and it is\nthe wrong one**, because it is the paragraph above undone: a `focusout`\nfires on the reader who tabbed past and typed nothing, which is exactly\nthe case this refuses to call an error. What a composite needs is not a\nfocus moment, it is the native meaning of `change`, \"edited, then left\",\nand the editing half is the part a mixin up here cannot see.\n\n**Nor is there one shape to extract yet.** The two composites solve it\ndifferently and both are right: `PinInput` is focus-driven, taking a\nbaseline when focus arrives from outside the row and announcing on the\nway out if it moved, and `DateInput` is value-driven, stopping its inner\n`change` and announcing once the date itself moves. Only one of them has\na leaving moment at all, so generalizing from the pair is generalizing\nfrom one. The trigger for lifting it is a third control that needs the\nfocus-driven shape, at which point what moves up is the\nbaseline-and-commit pair rather than `touched`.",
34745
+ "inheritedFrom": {
34746
+ "name": "MixinField",
34747
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34748
+ }
34749
+ },
34750
+ {
34751
+ "kind": "field",
34752
+ "name": "validates",
34753
+ "type": {
34754
+ "text": "boolean"
34755
+ },
34756
+ "privacy": "private",
34757
+ "description": "Whether this element may be asked about its own validity at all.\n\nReading the static the platform itself reads to decide, rather than\nprobing: `validity` and `validationMessage` throw `NotSupportedError` on\nan element that is not form-associated, and a group whose members each\nsubmit themselves is not. Such a control still shows a message, it just\nhas to be given one.",
34758
+ "readonly": true,
34759
+ "inheritedFrom": {
34760
+ "name": "MixinField",
34761
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34762
+ }
34763
+ },
34764
+ {
34765
+ "kind": "method",
34766
+ "name": "renderGroupLabel",
34767
+ "privacy": "protected",
34768
+ "return": {
34769
+ "type": {
34770
+ "text": "TemplateResult | typeof nothing"
34771
+ }
34772
+ },
34773
+ "description": "A label over a set rather than beside a control.\n\nA plain element and not a `<label for>`, because a group is not a single\ncontrol and there is nothing for `for` to point at. What names the group\nis `linkHost`, pointing the host's internals at this element.",
34774
+ "inheritedFrom": {
34775
+ "name": "MixinField",
34776
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34777
+ }
34778
+ },
34779
+ {
34780
+ "kind": "method",
34781
+ "name": "renderLabel",
34782
+ "privacy": "protected",
34783
+ "return": {
34784
+ "type": {
34785
+ "text": "TemplateResult | typeof nothing"
34786
+ }
34787
+ },
34788
+ "description": "A label above the control, pointing at it.\n\nA real `<label for>`, so pressing the words focuses the field and the\nbrowser does the forwarding. It resolves because `for` looks within the\nsame tree, and the control it names is in this shadow root.\n\n**Nothing at all when there is no label**, which is the same rule the\nhint and the feedback follow: none of the three is always used, and an\nelement rendered empty is not free. It still generates a box, so it still\ntakes a row of the grid and a gap on either side of it, which is a field\nthat has moved down the page for a label nobody wrote. `nothing` leaves\ncomment markers rather than a node, so the gap has nothing to sit between.\n\n**`aria-label` names without showing**, and it is forwarded rather than\nleft where the consumer put it. A custom element has no way to delegate a\nlabel to the control inside it, so an `aria-label` on the host reaches\nnothing: measured, the inner input came back with no label and no name of\nits own while the attribute sat on the wrapper. What happens instead is\nthat the label is rendered and clipped, so the name arrives through the\nsame `<label for>` a visible one does.\n\nThe rule is that `label` means a label, `aria-label` means a name, and\nneither means an unnamed field a screen reader announces as \"edit text\".",
34789
+ "inheritedFrom": {
34790
+ "name": "MixinField",
34791
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34792
+ }
34793
+ },
34794
+ {
34795
+ "kind": "method",
34796
+ "name": "renderHint",
34797
+ "privacy": "protected",
34798
+ "return": {
34799
+ "type": {
34800
+ "text": "TemplateResult | typeof nothing"
34801
+ }
34802
+ },
34803
+ "description": "Help under the control, unless something has gone wrong.\n\nThe two share a place rather than stacking, so a field is one line of\nsmall text either way and nothing below it moves when the message\nchanges. What the reader needs at that moment is what is wrong, and a\nhint that survives the error it describes is a second line to read before\ngetting to the one that matters.",
34804
+ "inheritedFrom": {
34805
+ "name": "MixinField",
34806
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34807
+ }
34808
+ },
34809
+ {
34810
+ "kind": "method",
34811
+ "name": "renderFeedback",
34812
+ "privacy": "protected",
34813
+ "return": {
34814
+ "type": {
34815
+ "text": "TemplateResult | typeof nothing"
34816
+ }
34817
+ },
34818
+ "description": "The validation message, in the hint's place.\n\n`role=\"alert\"` rather than a live region on the whole field, so what is\nannounced is the message and not the label and help along with it.",
34819
+ "inheritedFrom": {
34820
+ "name": "MixinField",
34821
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34822
+ }
34823
+ },
34824
+ {
34825
+ "kind": "method",
34826
+ "name": "linkHost",
34827
+ "privacy": "protected",
34828
+ "return": {
34829
+ "type": {
34830
+ "text": "void"
34831
+ }
34832
+ },
34833
+ "description": "Points the host at its own label and description nodes, for a group.\n\nA control's `<input>` and its hint are both in the shadow root, so a\nplain `aria-describedby` resolves between them. A group's host is in the\nlight DOM and its hint is not, so the IDREF cannot reach and\n`element.ariaDescribedByElements` drops the reference outright. Only the\n`ElementInternals` form keeps it, measured in Chrome 148: two of two\nkept through internals, zero of one through the element.\n\nClient only, and deliberately, because element references need the nodes\nto exist and on the server they do not. The name is therefore also set as\na plain string by the component, which a server can write, and the\nreference here overrides it wherever a consumer slotted something richer\nthan a string. A group with only a property for a label reads the same\neither way.",
34834
+ "inheritedFrom": {
34835
+ "name": "MixinField",
34836
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34837
+ }
34838
+ },
34839
+ {
34840
+ "kind": "field",
34841
+ "name": "shownFeedback",
34842
+ "type": {
34843
+ "text": "string"
34844
+ },
34845
+ "privacy": "private",
34846
+ "default": "''",
34847
+ "description": "What the last render put on screen, so a change can be noticed.",
34848
+ "inheritedFrom": {
34849
+ "name": "MixinField",
34850
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34851
+ }
34852
+ },
34853
+ {
34854
+ "kind": "method",
34855
+ "name": "refreshFeedback",
34856
+ "privacy": "protected",
34857
+ "return": {
34858
+ "type": {
34859
+ "text": "void"
34860
+ }
34861
+ },
34862
+ "description": "Re-reads the platform's verdict, for a control that has just reported one.\n\nValidity changes through `ElementInternals` rather than through a\nproperty, so nothing schedules an update for it. Worse, the order is\nagainst us: this mixin sits above the control in the prototype chain, so\nits `updated` runs before the control's own, which is where `setValidity`\nis called. Reading the verdict here would always read the previous one,\nwhich is what left a corrected field still showing the error it had\nbefore. So the control says when it has reported, and this schedules the\none further update that needs. It converges because the second pass finds\nnothing changed.",
34863
+ "inheritedFrom": {
34864
+ "name": "MixinField",
34865
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34866
+ }
34867
+ },
34868
+ {
34869
+ "kind": "method",
34870
+ "name": "reportRequired",
34871
+ "privacy": "protected",
34872
+ "return": {
34873
+ "type": {
34874
+ "text": "void"
34875
+ }
34876
+ },
34877
+ "parameters": [
34878
+ {
34879
+ "name": "empty",
34880
+ "type": {
34881
+ "text": "boolean"
34882
+ }
34883
+ },
34884
+ {
34885
+ "name": "message",
34886
+ "type": {
34887
+ "text": "string"
34888
+ }
34889
+ },
34890
+ {
34891
+ "name": "anchor",
34892
+ "type": {
34893
+ "text": "string"
34894
+ }
34895
+ }
34896
+ ],
34897
+ "description": "Reports \"required and empty\" and refreshes the message, or clears both.\n\nTwo things differ between the controls that call this, so those are the\narguments: whether the control is empty, which only it can say, and the\nsentence to say about it, which is different for a box, a switch and a\nset. The anchor is looked up here because every one of them anchors on a\nrendered part and the browser needs somewhere to point the bubble.\n\nThe message is not derived from the control's kind, deliberately. \"Tick\nthis box\" and \"Choose one\" are not the same instruction and a lookup\ntable would be one more thing to keep in step with the components.",
34898
+ "inheritedFrom": {
34899
+ "name": "MixinField",
34900
+ "module": "src/mixins/mixin-field/mixin-field.ts"
34901
+ }
34902
+ },
34903
+ {
34904
+ "kind": "field",
34905
+ "name": "aria",
34906
+ "privacy": "protected",
34907
+ "readonly": true,
34908
+ "default": "new AriaForwardController(this, { target: () => this.renderRoot?.querySelector<HTMLElement>('[part=\"control\"]') ?? null, })",
34909
+ "inheritedFrom": {
34910
+ "name": "HelixHeadlessFilterInput",
34911
+ "module": "src/filter-input/root/filter-input-root.ts"
34912
+ }
34913
+ },
34914
+ {
34915
+ "kind": "field",
34916
+ "name": "clearable",
34917
+ "type": {
34918
+ "text": "boolean"
34919
+ },
34920
+ "default": "false",
34921
+ "description": "Whether the field offers a button that empties it.\n\nThe text only. The tokens are the consumer's markup and this element is not\nentitled to take them out of the document, which is the same reason\n`hideOverflow` marks the ones over the cap `hidden` rather than removing\nthem.",
34922
+ "attribute": "clearable",
34923
+ "inheritedFrom": {
34924
+ "name": "HelixHeadlessFilterInput",
34925
+ "module": "src/filter-input/root/filter-input-root.ts"
34926
+ }
34927
+ },
34928
+ {
34929
+ "kind": "field",
34930
+ "name": "clearLabel",
34931
+ "type": {
34932
+ "text": "string"
34933
+ },
34934
+ "default": "'Clear'",
34935
+ "description": "What the clear button is called, since an icon has no name of its own.",
34936
+ "attribute": "clear-label",
34937
+ "inheritedFrom": {
34938
+ "name": "HelixHeadlessFilterInput",
34939
+ "module": "src/filter-input/root/filter-input-root.ts"
34940
+ }
34941
+ },
34942
+ {
34943
+ "kind": "field",
34944
+ "name": "placeholder",
34945
+ "type": {
34946
+ "text": "string"
34947
+ },
34948
+ "default": "''",
34949
+ "description": "Shown while the field is empty.\n\nNot a label: it goes when typing starts.",
34950
+ "attribute": "placeholder",
34951
+ "inheritedFrom": {
34952
+ "name": "HelixHeadlessFilterInput",
34953
+ "module": "src/filter-input/root/filter-input-root.ts"
34954
+ }
34955
+ },
34956
+ {
34957
+ "kind": "field",
34958
+ "name": "over",
34959
+ "type": {
34960
+ "text": "number"
34961
+ },
34962
+ "privacy": "private",
34963
+ "default": "0",
34964
+ "description": "How many tokens did not fit, which is what the row's count renders.",
34965
+ "inheritedFrom": {
34966
+ "name": "HelixHeadlessFilterInput",
34967
+ "module": "src/filter-input/root/filter-input-root.ts"
34968
+ }
34969
+ },
34970
+ {
34971
+ "kind": "field",
34972
+ "name": "releaseCaret",
34973
+ "type": {
34974
+ "text": "(() => void) | undefined"
34975
+ },
34976
+ "privacy": "private",
34977
+ "description": "The caret, held across a value the consumer wrote rather than the reader.\n\nSet in `willUpdate` and spent in `updated`, because Lit's `.value` binding\nlands between the two and takes the selection with it. See `holdCaret`.",
34978
+ "inheritedFrom": {
34979
+ "name": "HelixHeadlessFilterInput",
34980
+ "module": "src/filter-input/root/filter-input-root.ts"
34981
+ }
34982
+ },
34983
+ {
34984
+ "kind": "field",
34985
+ "name": "shadowRootOptions",
34986
+ "type": {
34987
+ "text": "ShadowRootInit"
34988
+ },
34989
+ "static": true,
34990
+ "default": "{ ...HelixFormElement.shadowRootOptions, delegatesFocus: true, }",
34991
+ "description": "Focus is delegated to the input, so the host is never the focus target.",
34992
+ "inheritedFrom": {
34993
+ "name": "HelixHeadlessFilterInput",
34994
+ "module": "src/filter-input/root/filter-input-root.ts"
34995
+ }
34996
+ },
34997
+ {
34998
+ "kind": "field",
34999
+ "name": "control",
35000
+ "type": {
35001
+ "text": "HTMLInputElement | null"
35002
+ },
35003
+ "privacy": "private",
35004
+ "readonly": true,
35005
+ "inheritedFrom": {
35006
+ "name": "HelixHeadlessFilterInput",
35007
+ "module": "src/filter-input/root/filter-input-root.ts"
35008
+ }
35009
+ },
35010
+ {
35011
+ "kind": "field",
35012
+ "name": "tokens",
35013
+ "type": {
35014
+ "text": "HTMLSlotElement | null"
35015
+ },
35016
+ "privacy": "private",
35017
+ "readonly": true,
35018
+ "inheritedFrom": {
35019
+ "name": "HelixHeadlessFilterInput",
35020
+ "module": "src/filter-input/root/filter-input-root.ts"
35021
+ }
35022
+ },
35023
+ {
35024
+ "kind": "field",
35025
+ "name": "showsClear",
35026
+ "type": {
35027
+ "text": "boolean"
35028
+ },
35029
+ "privacy": "private",
35030
+ "description": "Whether there is a clear button on screen right now.",
35031
+ "readonly": true,
35032
+ "inheritedFrom": {
35033
+ "name": "HelixHeadlessFilterInput",
35034
+ "module": "src/filter-input/root/filter-input-root.ts"
35035
+ }
35036
+ },
35037
+ {
35038
+ "kind": "field",
35039
+ "name": "handleInput",
35040
+ "privacy": "private",
35041
+ "readonly": true,
35042
+ "description": "Every keystroke, cancelable, and put back where it is refused.\n\nStopped for the reason `Input` gives: `input` is composed, so the inner\ncontrol's own would arrive beside the one the mixin announces and a consumer\nwould hear one keystroke twice, once carrying the value from before it.",
35043
+ "inheritedFrom": {
35044
+ "name": "HelixHeadlessFilterInput",
35045
+ "module": "src/filter-input/root/filter-input-root.ts"
35046
+ }
35047
+ },
35048
+ {
35049
+ "kind": "field",
35050
+ "name": "handleChange",
35051
+ "privacy": "private",
35052
+ "readonly": true,
35053
+ "description": "Relayed, because `change` does not cross a shadow boundary on its own.",
35054
+ "inheritedFrom": {
35055
+ "name": "HelixHeadlessFilterInput",
35056
+ "module": "src/filter-input/root/filter-input-root.ts"
35057
+ }
35058
+ },
35059
+ {
35060
+ "kind": "field",
35061
+ "name": "handleClear",
35062
+ "privacy": "private",
35063
+ "readonly": true,
35064
+ "description": "Empties the text and gives the caret back.\n\nFocus returns to the input rather than staying on a button that is about to\ndisappear, which would otherwise land on the body.",
35065
+ "inheritedFrom": {
35066
+ "name": "HelixHeadlessFilterInput",
35067
+ "module": "src/filter-input/root/filter-input-root.ts"
35068
+ }
35069
+ },
35070
+ {
35071
+ "kind": "field",
35072
+ "name": "handleKeydown",
35073
+ "privacy": "private",
35074
+ "readonly": true,
35075
+ "inheritedFrom": {
35076
+ "name": "HelixHeadlessFilterInput",
35077
+ "module": "src/filter-input/root/filter-input-root.ts"
35078
+ }
35079
+ },
35080
+ {
35081
+ "kind": "field",
35082
+ "name": "handleTokens",
35083
+ "privacy": "private",
35084
+ "readonly": true,
35085
+ "description": "The row again, whenever what is in it changes.",
35086
+ "inheritedFrom": {
35087
+ "name": "HelixHeadlessFilterInput",
35088
+ "module": "src/filter-input/root/filter-input-root.ts"
35089
+ }
35090
+ },
35091
+ {
35092
+ "kind": "method",
35093
+ "name": "focus",
35094
+ "return": {
35095
+ "type": {
35096
+ "text": "void"
35097
+ }
35098
+ },
35099
+ "parameters": [
35100
+ {
35101
+ "name": "options",
35102
+ "optional": true,
35103
+ "type": {
35104
+ "text": "FocusOptions"
35105
+ }
35106
+ }
35107
+ ],
35108
+ "description": "Puts the caret in the field, the way a label pointing at one would.",
35109
+ "type": {
35110
+ "text": "focus(options?: FocusOptions) => void"
35111
+ },
35112
+ "inheritedFrom": {
35113
+ "name": "HelixHeadlessFilterInput",
35114
+ "module": "src/filter-input/root/filter-input-root.ts"
35115
+ }
35116
+ },
35117
+ {
35118
+ "kind": "field",
35119
+ "name": "formAssociated",
35120
+ "type": {
35121
+ "text": "boolean"
35122
+ },
35123
+ "static": true,
35124
+ "readonly": true,
35125
+ "default": "true",
35126
+ "description": "Opts the element into form ownership, labels, and submission.",
35127
+ "inheritedFrom": {
35128
+ "name": "HelixFormElement",
35129
+ "module": "src/helix-form-element/helix-form-element.ts"
35130
+ }
35131
+ },
35132
+ {
35133
+ "kind": "field",
35134
+ "name": "disabled",
35135
+ "type": {
35136
+ "text": "boolean"
35137
+ },
35138
+ "default": "false",
35139
+ "description": "Whether the control is non-interactive.\n\nReflected, because the styled tier selects on it, and mirrored to\n`aria-disabled` rather than removing the element from the accessibility\ntree, so a screen reader can still announce that the control exists.\n\nThe mirror itself is in `willUpdate` below, here rather than in each\ncontrol, because here is where `disabled` is.",
35140
+ "attribute": "disabled",
35141
+ "reflects": true,
35142
+ "inheritedFrom": {
35143
+ "name": "HelixFormElement",
35144
+ "module": "src/helix-form-element/helix-form-element.ts"
35145
+ }
35146
+ },
35147
+ {
35148
+ "kind": "field",
35149
+ "name": "formDisabled",
35150
+ "type": {
35151
+ "text": "boolean"
35152
+ },
35153
+ "privacy": "protected",
35154
+ "default": "false",
35155
+ "description": "Whether an ancestor `<fieldset disabled>` has switched this control off.\n\nThe platform tells a form-associated element through `formDisabledCallback`\nand nothing else does, so without this a control inside a disabled fieldset\nstays fully typeable and announces itself as enabled.\n\nThe submission half is already the platform's: measured, the fieldset's\ncontrols are absent from the form's entry list and the host matches\n`:disabled`, so the value never goes anywhere. What is missing without this\nis everything a reader can see or touch.\n\nState rather than the `disabled` property. Writing that would reflect an\nattribute the consumer's server markup does not have, which React reports\non hydration and does not patch up, and it would also silently overwrite\nwhat the consumer set.",
35156
+ "inheritedFrom": {
35157
+ "name": "HelixFormElement",
35158
+ "module": "src/helix-form-element/helix-form-element.ts"
35159
+ }
35160
+ },
35161
+ {
35162
+ "kind": "method",
35163
+ "name": "formDisabledCallback",
35164
+ "return": {
35165
+ "type": {
35166
+ "text": "void"
35167
+ }
35168
+ },
35169
+ "parameters": [
35170
+ {
35171
+ "name": "disabled",
35172
+ "type": {
35173
+ "text": "boolean"
35174
+ }
35175
+ }
35176
+ ],
35177
+ "description": "The platform's notice that an ancestor fieldset changed.\n\n**The argument is the effective state, and taking it whole is what latched\nevery control in the library.** The platform calls this for the element's\nown `disabled` as well as for a fieldset, and our own arrives here at the\nworst possible moment: reflecting `disabled` to the attribute happens\ninside Lit's `update()`, the UA fires this synchronously from that write,\nand a reactive write during an update is a change-in-update Lit does not\nre-render for. So `formDisabled` ran exactly one update behind forever.\n\nMeasured on Slider, logging what `render` saw:\n\n```\nset true disabled true formDisabled false isDisabled true\nset false disabled false formDisabled true isDisabled true <- stale\n(no third render)\n```\n\nThe host came out right every time, `disabled` false, `:disabled` not\nmatching, and the inner control kept the attribute, so a control disabled\nonce could never be re-enabled. It only shows when something re-enables,\nwhich is the same shape of bug `inheritDisabled` was written for.\n\nOur own half is already in `this.disabled` and `isDisabled` is an or, so\nthis records only what the fieldset adds. That also removes the write\nentirely on the own-disabled path rather than moving it.\n\nThe one case this cannot see is a control that is disabled itself *and*\ninside a disabled fieldset, whose own `disabled` is then removed: the\neffective state does not change, so the platform does not call again, and\nthe fieldset's hold is not recorded. There is no callback to learn it from\nand reading `:disabled` here would answer about the attribute we are in the\nmiddle of removing.",
35178
+ "inheritedFrom": {
35179
+ "name": "HelixFormElement",
35180
+ "module": "src/helix-form-element/helix-form-element.ts"
35181
+ },
35182
+ "type": {
35183
+ "text": "formDisabledCallback(disabled: boolean) => void"
35184
+ }
35185
+ },
35186
+ {
35187
+ "kind": "field",
35188
+ "name": "name",
35189
+ "type": {
35190
+ "text": "string"
35191
+ },
35192
+ "default": "''",
35193
+ "description": "Name submitted with the form.\n\n**Reflected, and it is the exception to \"reflect only what CSS selects\non\".** The platform builds a form's entry list from the `name` *content\nattribute*, not from the property, so a control named through the property\nsubmitted under no name at all and was silently dropped. Measured: two\ninputs in one form, one named by attribute and one by property, and the\nform carried a single entry.\n\nSafe for a React consumer, which is what the rule is protecting: React\nrenders a custom element's props as attributes on the server, so the name\nis already in the markup being hydrated and reflecting it writes what is\nthere. It is only a change to the markup when a consumer assigns it\nimperatively later, and nothing is hydrating by then.\n\nHere rather than on each control.",
35194
+ "attribute": "name",
35195
+ "reflects": true,
35196
+ "inheritedFrom": {
35197
+ "name": "HelixFormElement",
35198
+ "module": "src/helix-form-element/helix-form-element.ts"
35199
+ }
35200
+ },
35201
+ {
35202
+ "kind": "field",
35203
+ "name": "form",
35204
+ "type": {
35205
+ "text": "HTMLFormElement | null"
35206
+ },
35207
+ "description": "The form this control belongs to, if any.",
35208
+ "readonly": true,
35209
+ "helix": {
35210
+ "references": [
35211
+ {
35212
+ "label": "form-associated custom elements",
35213
+ "url": "https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements"
35214
+ }
35215
+ ]
35216
+ },
35217
+ "inheritedFrom": {
35218
+ "name": "HelixFormElement",
35219
+ "module": "src/helix-form-element/helix-form-element.ts"
35220
+ }
35221
+ },
35222
+ {
35223
+ "kind": "field",
35224
+ "name": "labels",
35225
+ "type": {
35226
+ "text": "NodeList"
35227
+ },
35228
+ "description": "Labels associated with this control.",
35229
+ "readonly": true,
35230
+ "helix": {
35231
+ "references": [
35232
+ {
35233
+ "label": "form-associated custom elements",
35234
+ "url": "https://html.spec.whatwg.org/multipage/custom-elements.html#form-associated-custom-elements"
35235
+ }
35236
+ ]
35237
+ },
35238
+ "inheritedFrom": {
35239
+ "name": "HelixFormElement",
35240
+ "module": "src/helix-form-element/helix-form-element.ts"
35241
+ }
35242
+ },
35243
+ {
35244
+ "kind": "field",
35245
+ "name": "tier",
35246
+ "type": {
35247
+ "text": "string"
35248
+ },
35249
+ "static": true,
35250
+ "default": "'helix-headless-'",
35251
+ "description": "The prefix this tier registers its elements under.\n\n**A component that renders another renders its own tier's version of it**,\nso `helix-headless-pagination-size` composes `helix-headless-select` and\n`helix-pagination-size` composes `helix-select`. One template says\n`${this.tag('select')}` and each tier answers with its own name.\n\n**The public tag may not be the composed one, in either tier.** Using it\ncosts three things: the name means two different things depending on what a\nconsumer imported, the headless tier composes an element it does not ship,\nand the composition cannot be tested there at all, because there is no\n`helix-select` on that tier to test it against.\n\n**A prefix rather than an override per composition**, which was the first\nplan and does not compile. An override re-renders the fragment from the\nsubclass, and the fragment reads members the base keeps private:\n`PaginationSize` alone would have had to widen `options`, `current` and\n`handleChange` to `protected` so a subclass could say the same thing again.\nSixteen families of that is a lot of encapsulation spent on saying one\nword differently.",
35252
+ "inheritedFrom": {
35253
+ "name": "HelixElement",
35254
+ "module": "src/helix-element/helix-element.ts"
35255
+ }
35256
+ },
35257
+ {
35258
+ "kind": "method",
35259
+ "name": "tag",
35260
+ "privacy": "protected",
35261
+ "return": {
35262
+ "type": {
35263
+ "text": "StaticValue"
35264
+ }
35265
+ },
35266
+ "parameters": [
35267
+ {
35268
+ "name": "name",
35269
+ "type": {
35270
+ "text": "string"
35271
+ }
35272
+ }
35273
+ ],
35274
+ "description": "One composed tag, as a static value a template can interpolate.\n\n`unsafeStatic` is safe by construction: the name is a literal in our own\nsource and the prefix is one of two strings this class defines. Called per\nrender and not cached, which costs nothing, because `static-html` keys its\ntemplate cache on the joined string rather than on the object.",
35275
+ "inheritedFrom": {
35276
+ "name": "HelixElement",
35277
+ "module": "src/helix-element/helix-element.ts"
35278
+ }
35279
+ },
35280
+ {
35281
+ "kind": "field",
35282
+ "name": "internals",
35283
+ "type": {
35284
+ "text": "ElementInternals"
35285
+ },
35286
+ "privacy": "protected",
35287
+ "readonly": true,
35288
+ "description": "The element's semantics, set without touching the DOM.\n\n`ElementInternals` sets the implicit role, which an author's own `role`\nattribute still overrides, and it writes no attribute. Setting `role` on the\nhost directly would: that is an attribute the element gives itself after it\nupgrades, which a React consumer's server markup never had, and hydration\nreports it as a mismatch.\n\nAvailable during server rendering. Lit's shim implements `attachInternals`,\nso nothing here needs a guard.",
35289
+ "inheritedFrom": {
35290
+ "name": "HelixElement",
35291
+ "module": "src/helix-element/helix-element.ts"
35292
+ }
35293
+ },
35294
+ {
35295
+ "kind": "method",
35296
+ "name": "toggleState",
35297
+ "privacy": "protected",
35298
+ "return": {
35299
+ "type": {
35300
+ "text": "void"
35301
+ }
35302
+ },
35303
+ "parameters": [
35304
+ {
35305
+ "name": "name",
35306
+ "type": {
35307
+ "text": "string"
35308
+ }
35309
+ },
35310
+ {
35311
+ "name": "on",
35312
+ "type": {
35313
+ "text": "boolean"
35314
+ }
35315
+ }
35316
+ ],
35317
+ "description": "Records a boolean fact about this element as a custom state.\n\n**The host belongs to whoever rendered it, and a component's own\nbookkeeping may not be kept there.** An attribute written on the first\nupdate is markup a consumer's server never sent, so a React consumer\nhydrates a DOM that has gained attributes since and reports a mismatch it\nwill not patch up. A custom state is not in the DOM at all: it carries the\nfact to a stylesheet through `:state()` and leaves the markup alone, so the\nserver's output and the client's agree by construction.\n\n`SETTLED` carries the long version of that argument; `checked`, `open`,\n`invalid` and `has-label` are recorded the same way, each of them a state a\n`default-*` attribute resolves before React reaches the node.\n\n**Deferring the definitions is not a fix and could not be.** Importing them\nfrom an effect so the upgrades fall the other side of hydration works only\nwhile hydration is one pass: anything that splits it, a streamed segment or\na suspended boundary, puts an upgrade back inside the window. Timing cannot\nbe the guarantee when the fact is kept somewhere React reconciles.\n\nFeature-tested rather than assumed, the way `hostAria` tests element\nreferences. An engine without `CustomStateSet` records nothing and keeps\nwhatever the resting rule draws, which is the safe direction to fail.\n\n**The engines the test is for are browsers**: Safari below 17.4 and Firefox\nbelow 126, where the write is a `TypeError`, so a component bypassing this\nfails to render rather than rendering without whatever the state draws.\nLit's server shim sets `states`, so the guard passes there and records a\nstate nothing reads, which is harmless.",
35318
+ "inheritedFrom": {
35319
+ "name": "HelixElement",
35320
+ "module": "src/helix-element/helix-element.ts"
35321
+ }
35322
+ },
35323
+ {
35324
+ "kind": "field",
35325
+ "name": "whenSettled",
35326
+ "type": {
35327
+ "text": "Promise<void>"
35328
+ },
35329
+ "readonly": true,
35330
+ "description": "Resolves a frame after the first update, when transitions are switched on.\n\n**Named `whenSettled` because `settled` is taken four times over**, by\nImage, Splitter and both color controls, none of them about transitions. A\nbase class takes the name every subclass then cannot use.\n\n**The state it reports cannot be watched, which is why this exists.** A\ncustom state is deliberately not in the DOM, so there is no\n`MutationObserver` equivalent for `ElementInternals.states`. Await this\ninstead.\n\nSeparate from `updateComplete`, which resolves in the microtask checkpoint\nthe suppression is still active in. That is the distinction `readyToMove`\nin `@fusion.dev/helix-testing` is written around.\n\nIt never resolves where `requestAnimationFrame` never fires, which is a\nserver, a hidden tab, and happy-dom. Callers that must not hang race it\nagainst a timeout; `readyToMove` does exactly that.",
35331
+ "default": "new Promise<void>((resolve) => { this.resolveSettled = resolve })",
35332
+ "inheritedFrom": {
35333
+ "name": "HelixElement",
35334
+ "module": "src/helix-element/helix-element.ts"
35335
+ }
35336
+ },
35337
+ {
35338
+ "kind": "field",
35339
+ "name": "resolveSettled",
35340
+ "type": {
35341
+ "text": "() => void"
35342
+ },
35343
+ "privacy": "private",
35344
+ "description": "Resolves `whenSettled`, once, from the frame that records the state.",
35345
+ "inheritedFrom": {
35346
+ "name": "HelixElement",
35347
+ "module": "src/helix-element/helix-element.ts"
35348
+ }
35349
+ },
35350
+ {
35351
+ "kind": "field",
35352
+ "name": "stopInner",
35353
+ "privacy": "protected",
35354
+ "readonly": true,
35355
+ "description": "Stops an inner control's own announcement at this element's boundary.\n\n**A composed control is one control to a consumer, and the natives had no\nequivalent of the stop the prefixed events already get.** `<helix-select>`\nrenders a `<helix-listbox>`, and both announce: the listbox dispatches\n`input` and `change` from its own host, `input` is composed by\nspecification, and a consumer listening on the select therefore heard one\nchoice twice. Measured before this existed, on the styled tier, one choice\non the inner listbox: select `input` twice and `change` three times,\ncombobox, date input, time input and color input twice each. `Command` was\nthe only one that was right, because it happened to reach for\n`stopImmediatePropagation` for a different reason.\n\nBound on the child in the parent's template, so it runs while the event is\nstill at the child and before it can cross. The guard is for the case where\na component binds this on itself: an element must never stop its own\nannouncement, which is the one it exists to make.\n\nThis is the same job the `helix-before-*` handlers do with their own\n`stopPropagation`, and it is separate rather than folded into them because\na consumer may legitimately refuse a request without the notification ever\nhappening: the two travel at different times and one can be absent.",
35356
+ "inheritedFrom": {
35357
+ "name": "HelixElement",
35358
+ "module": "src/helix-element/helix-element.ts"
35359
+ }
35360
+ },
35361
+ {
35362
+ "kind": "method",
35363
+ "name": "relayNativeEvent",
35364
+ "privacy": "protected",
35365
+ "return": {
35366
+ "type": {
35367
+ "text": "void"
35368
+ }
35369
+ },
35370
+ "parameters": [
35371
+ {
35372
+ "name": "event",
35373
+ "type": {
35374
+ "text": "Event"
35375
+ }
35376
+ },
35377
+ {
35378
+ "name": "init",
35379
+ "optional": true,
35380
+ "type": {
35381
+ "text": "EventInit"
35382
+ }
35383
+ }
35384
+ ],
35385
+ "description": "Re-emits a native event from the host, under its own name.\n\nA native event fired by an inner `<input>` or `<textarea>` is not composed,\nso it stops at the shadow boundary and a consumer listening on\n`<helix-input>` hears nothing. Re-dispatching it from the host is what\nmakes the component behave like the control it wraps.\n\nThe relayed event keeps the native name deliberately. `change` is `change`,\nwhich is what a consumer already knows to listen for, and it is what\nreaches React: its synthetic system claims `onChange` and wires it to that\nname, so a prefixed one would never arrive.\n\n`composed` is not forced. It defaults to the original event's own value, so\na relayed `change` stops at the next shadow boundary exactly as a native\none would. Pass it explicitly only where escaping is the intent, and say so\nwhere you do.",
35386
+ "inheritedFrom": {
35387
+ "name": "HelixElement",
35388
+ "module": "src/helix-element/helix-element.ts"
35389
+ }
35390
+ },
35391
+ {
35392
+ "kind": "method",
35393
+ "name": "finalizeStyles",
35394
+ "privacy": "protected",
35395
+ "static": true,
35396
+ "return": {
35397
+ "type": {
35398
+ "text": "CSSResultOrNative[]"
35399
+ }
35400
+ },
35401
+ "parameters": [
35402
+ {
35403
+ "name": "styles",
35404
+ "optional": true,
35405
+ "type": {
35406
+ "text": "CSSResultOrNative | CSSResultOrNative[]"
35407
+ }
35408
+ }
35409
+ ],
35410
+ "description": "Prepends the shadow-root reset to every subclass's styles, so no component\nhas to remember to include it.",
35411
+ "inheritedFrom": {
35412
+ "name": "HelixElement",
35413
+ "module": "src/helix-element/helix-element.ts"
35414
+ }
35415
+ }
35416
+ ],
35417
+ "superclass": {
35418
+ "name": "HelixHeadlessFilterInput",
35419
+ "package": "@fusion.dev/helix-headless/filter-input"
35420
+ },
35421
+ "summary": "A field that narrows something else, beside what is already narrowing it.",
35422
+ "helix": {
35423
+ "category": "forms",
35424
+ "since": "0.1.0",
35425
+ "status": "experimental",
35426
+ "documentation": "https://helix.fusion.dev/components/filter-input",
35427
+ "aliases": [
35428
+ "SearchField",
35429
+ "FacetInput",
35430
+ "TokenInput"
35431
+ ],
35432
+ "tier": "styled",
35433
+ "group": "FilterInput",
35434
+ "part": "Root",
35435
+ "examples": [
35436
+ {
35437
+ "description": "A filter field, grown to hold what has already narrowed the rows.",
35438
+ "slug": "preview"
35439
+ },
35440
+ {
35441
+ "description": "A button that empties the text, which is not the same as clearing the filter.",
35442
+ "slug": "clearable"
35443
+ },
35444
+ {
35445
+ "description": "Backspace on an empty field asks the same way the close control does.",
35446
+ "slug": "dismissing"
35447
+ },
35448
+ {
35449
+ "description": "A cap for a field in a row, where the rest becomes a count.",
35450
+ "slug": "max-tags"
35451
+ }
35452
+ ],
35453
+ "source": "helix/styled/src/filter-input"
35454
+ },
35455
+ "tagName": "helix-filter-input",
35456
+ "customElement": true,
35457
+ "attributes": [
35458
+ {
35459
+ "name": "max-tags",
35460
+ "type": {
35461
+ "text": "number"
35462
+ },
35463
+ "default": "0",
35464
+ "description": "How many tokens to show before the rest become a count.",
35465
+ "fieldName": "maxTags",
35466
+ "inheritedFrom": {
35467
+ "name": "MixinTokens",
35468
+ "module": "src/mixins/mixin-tokens/mixin-tokens.ts"
35469
+ }
35470
+ },
35471
+ {
35472
+ "name": "default-value",
35473
+ "type": {
35474
+ "text": "string"
35475
+ },
35476
+ "default": "''",
35477
+ "description": "The value the markup declared, which is where a reset returns to.",
35478
+ "fieldName": "defaultValue",
35479
+ "inheritedFrom": {
35480
+ "name": "MixinControllerValue",
35481
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
35482
+ }
35483
+ },
35484
+ {
35485
+ "name": "value",
35486
+ "type": {
35487
+ "text": "string"
35488
+ },
35489
+ "description": "What the control holds now, and what its form submits.\n\nOne property, not two, so `input.value` answers the question anyone\nasking it meant. Writing always applies; `<helix-input value=\"x\">` is the\nsame statement in markup, and `default-value` is how markup seeds a value\na reset should return to.",
35490
+ "fieldName": "value",
35491
+ "inheritedFrom": {
35492
+ "name": "MixinControllerValue",
35493
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
35494
+ }
35495
+ },
35496
+ {
35497
+ "name": "feedback",
35498
+ "type": {
35499
+ "text": "string"
35500
+ },
35501
+ "default": "''",
35502
+ "description": "What is wrong, in the reader's words rather than the browser's.",
35503
+ "fieldName": "feedback",
35504
+ "inheritedFrom": {
35505
+ "name": "MixinField",
35506
+ "module": "src/mixins/mixin-field/mixin-field.ts"
35507
+ }
35508
+ },
35509
+ {
35510
+ "name": "hint",
35511
+ "type": {
35512
+ "text": "string"
35513
+ },
35514
+ "default": "''",
35515
+ "description": "Help under the control, shown while there is nothing wrong.",
35516
+ "fieldName": "hint",
35517
+ "inheritedFrom": {
35518
+ "name": "MixinField",
35519
+ "module": "src/mixins/mixin-field/mixin-field.ts"
35520
+ }
35521
+ },
35522
+ {
35523
+ "name": "label",
35524
+ "type": {
35525
+ "text": "string"
35526
+ },
35527
+ "default": "''",
35528
+ "description": "The accessible name, and the fallback for the `label` slot.",
35529
+ "fieldName": "label",
35530
+ "inheritedFrom": {
35531
+ "name": "MixinField",
35532
+ "module": "src/mixins/mixin-field/mixin-field.ts"
35533
+ }
35534
+ },
35535
+ {
35536
+ "name": "required",
35537
+ "type": {
35538
+ "text": "boolean"
35539
+ },
35540
+ "default": "false",
35541
+ "description": "Whether the form refuses to submit without it.",
35542
+ "fieldName": "required",
35543
+ "inheritedFrom": {
35544
+ "name": "MixinField",
35545
+ "module": "src/mixins/mixin-field/mixin-field.ts"
35546
+ }
35547
+ },
35548
+ {
35549
+ "name": "clearable",
35550
+ "type": {
35551
+ "text": "boolean"
35552
+ },
35553
+ "default": "false",
35554
+ "description": "Whether the field offers a button that empties it.\n\nThe text only. The tokens are the consumer's markup and this element is not\nentitled to take them out of the document, which is the same reason\n`hideOverflow` marks the ones over the cap `hidden` rather than removing\nthem.",
35555
+ "fieldName": "clearable",
35556
+ "inheritedFrom": {
35557
+ "name": "HelixHeadlessFilterInput",
35558
+ "module": "src/filter-input/root/filter-input-root.ts"
35559
+ }
35560
+ },
35561
+ {
35562
+ "name": "clear-label",
35563
+ "type": {
35564
+ "text": "string"
35565
+ },
35566
+ "default": "'Clear'",
35567
+ "description": "What the clear button is called, since an icon has no name of its own.",
35568
+ "fieldName": "clearLabel",
35569
+ "inheritedFrom": {
35570
+ "name": "HelixHeadlessFilterInput",
35571
+ "module": "src/filter-input/root/filter-input-root.ts"
35572
+ }
35573
+ },
35574
+ {
35575
+ "name": "placeholder",
35576
+ "type": {
35577
+ "text": "string"
35578
+ },
35579
+ "default": "''",
35580
+ "description": "Shown while the field is empty.\n\nNot a label: it goes when typing starts.",
35581
+ "fieldName": "placeholder",
35582
+ "inheritedFrom": {
35583
+ "name": "HelixHeadlessFilterInput",
35584
+ "module": "src/filter-input/root/filter-input-root.ts"
35585
+ }
35586
+ },
35587
+ {
35588
+ "name": "disabled",
35589
+ "type": {
35590
+ "text": "boolean"
35591
+ },
35592
+ "default": "false",
35593
+ "description": "Whether the control is non-interactive.\n\nReflected, because the styled tier selects on it, and mirrored to\n`aria-disabled` rather than removing the element from the accessibility\ntree, so a screen reader can still announce that the control exists.\n\nThe mirror itself is in `willUpdate` below, here rather than in each\ncontrol, because here is where `disabled` is.",
35594
+ "fieldName": "disabled",
35595
+ "inheritedFrom": {
35596
+ "name": "HelixFormElement",
35597
+ "module": "src/helix-form-element/helix-form-element.ts"
35598
+ }
35599
+ },
35600
+ {
35601
+ "name": "name",
35602
+ "type": {
35603
+ "text": "string"
35604
+ },
35605
+ "default": "''",
35606
+ "description": "Name submitted with the form.\n\n**Reflected, and it is the exception to \"reflect only what CSS selects\non\".** The platform builds a form's entry list from the `name` *content\nattribute*, not from the property, so a control named through the property\nsubmitted under no name at all and was silently dropped. Measured: two\ninputs in one form, one named by attribute and one by property, and the\nform carried a single entry.\n\nSafe for a React consumer, which is what the rule is protecting: React\nrenders a custom element's props as attributes on the server, so the name\nis already in the markup being hydrated and reflecting it writes what is\nthere. It is only a change to the markup when a consumer assigns it\nimperatively later, and nothing is hydrating by then.\n\nHere rather than on each control.",
35607
+ "fieldName": "name",
35608
+ "inheritedFrom": {
35609
+ "name": "HelixFormElement",
35610
+ "module": "src/helix-form-element/helix-form-element.ts"
35611
+ }
35612
+ }
35613
+ ],
35614
+ "events": [
35615
+ {
35616
+ "name": "input",
35617
+ "type": {
35618
+ "text": "Event"
35619
+ },
35620
+ "description": "Announced once the text has moved.",
35621
+ "inheritedFrom": {
35622
+ "name": "MixinControllerValue",
35623
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
35624
+ },
35625
+ "reactProp": "oninput"
35626
+ },
35627
+ {
35628
+ "name": "change",
35629
+ "type": {
35630
+ "text": "Event"
35631
+ },
35632
+ "description": "Relayed from the input once the reader has finished.",
35633
+ "inheritedFrom": {
35634
+ "name": "MixinControllerValue",
35635
+ "module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
35636
+ },
35637
+ "reactProp": "onchange"
35638
+ },
35639
+ {
35640
+ "type": {
35641
+ "text": "HelixBeforeChangeEvent"
35642
+ },
35643
+ "description": "Fired as the text changes, and cancelable.",
35644
+ "name": "helix-before-change",
35645
+ "reactProp": "onhelix-before-change",
35646
+ "inheritedFrom": {
35647
+ "name": "HelixHeadlessFilterInput",
35648
+ "module": "src/filter-input/root/filter-input-root.ts"
35649
+ }
35650
+ }
35651
+ ],
35652
+ "slots": [
35653
+ {
35654
+ "description": "After the text, for a count or a control.",
35655
+ "name": "end",
35656
+ "inheritedFrom": {
35657
+ "name": "HelixHeadlessFilterInput",
35658
+ "module": "src/filter-input/root/filter-input-root.ts"
35659
+ }
35660
+ },
35661
+ {
35662
+ "description": "Before the text, for a search icon.",
35663
+ "name": "start",
35664
+ "inheritedFrom": {
35665
+ "name": "HelixHeadlessFilterInput",
35666
+ "module": "src/filter-input/root/filter-input-root.ts"
35667
+ }
35668
+ },
35669
+ {
35670
+ "description": "What is already narrowing the results, as `Tag`s.",
35671
+ "name": "tags",
35672
+ "inheritedFrom": {
35673
+ "name": "HelixHeadlessFilterInput",
35674
+ "module": "src/filter-input/root/filter-input-root.ts"
35675
+ }
35676
+ }
35677
+ ],
35678
+ "cssParts": [
35679
+ {
35680
+ "description": "The button that empties the field.",
35681
+ "name": "clear",
35682
+ "inheritedFrom": {
35683
+ "name": "HelixHeadlessFilterInput",
35684
+ "module": "src/filter-input/root/filter-input-root.ts"
35685
+ }
35686
+ },
35687
+ {
35688
+ "description": "The input itself.",
35689
+ "name": "control",
35690
+ "inheritedFrom": {
35691
+ "name": "HelixHeadlessFilterInput",
35692
+ "module": "src/filter-input/root/filter-input-root.ts"
35693
+ }
35694
+ },
35695
+ {
35696
+ "description": "What is wrong with it.",
35697
+ "name": "feedback",
35698
+ "inheritedFrom": {
35699
+ "name": "HelixHeadlessFilterInput",
35700
+ "module": "src/filter-input/root/filter-input-root.ts"
35701
+ }
35702
+ },
35703
+ {
35704
+ "description": "The box holding everything.",
35705
+ "name": "field",
35706
+ "inheritedFrom": {
35707
+ "name": "HelixHeadlessFilterInput",
35708
+ "module": "src/filter-input/root/filter-input-root.ts"
35709
+ }
35710
+ },
35711
+ {
35712
+ "description": "Help under the field, while nothing is wrong.",
35713
+ "name": "hint",
35714
+ "inheritedFrom": {
35715
+ "name": "HelixHeadlessFilterInput",
35716
+ "module": "src/filter-input/root/filter-input-root.ts"
35717
+ }
35718
+ },
35719
+ {
35720
+ "description": "The question, over the field.",
35721
+ "name": "label",
35722
+ "inheritedFrom": {
35723
+ "name": "HelixHeadlessFilterInput",
35724
+ "module": "src/filter-input/root/filter-input-root.ts"
35725
+ }
35726
+ },
35727
+ {
35728
+ "description": "How many tokens did not fit.",
35729
+ "name": "rest",
35730
+ "inheritedFrom": {
35731
+ "name": "HelixHeadlessFilterInput",
35732
+ "module": "src/filter-input/root/filter-input-root.ts"
35733
+ }
35734
+ },
35735
+ {
35736
+ "description": "The row the tokens sit in.",
35737
+ "name": "tags",
35738
+ "inheritedFrom": {
35739
+ "name": "HelixHeadlessFilterInput",
35740
+ "module": "src/filter-input/root/filter-input-root.ts"
35741
+ }
35742
+ }
35743
+ ],
35744
+ "modulePath": "src/filter-input/root/filter-input-root.ts",
35745
+ "definitionPath": "src/filter-input/root/filter-input-root.ts"
35746
+ }
35747
+ ],
35748
+ "exports": [
35749
+ {
35750
+ "kind": "js",
35751
+ "name": "HelixFilterInput",
35752
+ "declaration": {
35753
+ "name": "HelixFilterInput",
35754
+ "module": "src/filter-input/root/filter-input-root.ts"
35755
+ }
35756
+ },
35757
+ {
35758
+ "kind": "custom-element-definition",
35759
+ "name": "helix-filter-input",
35760
+ "declaration": {
35761
+ "name": "HelixFilterInput",
35762
+ "module": "src/filter-input/root/filter-input-root.ts"
35763
+ }
35764
+ }
35765
+ ]
35766
+ },
35767
+ {
35768
+ "kind": "javascript-module",
35769
+ "path": "src/flex/index.ts",
35770
+ "declarations": [],
35771
+ "exports": [
35772
+ {
35773
+ "kind": "js",
35774
+ "name": "*",
35775
+ "declaration": {
35776
+ "name": "*",
35777
+ "module": "src/flex/root/flex-root.js"
35778
+ }
35779
+ }
35780
+ ]
35781
+ },
35782
+ {
35783
+ "kind": "javascript-module",
35784
+ "path": "src/flex/root/flex-root.css.ts",
35785
+ "declarations": [
35786
+ {
35787
+ "kind": "variable",
35788
+ "name": "styles"
35789
+ }
35790
+ ],
35791
+ "exports": [
35792
+ {
35793
+ "kind": "js",
35794
+ "name": "styles",
35795
+ "declaration": {
35796
+ "name": "styles",
35797
+ "module": "src/flex/root/flex-root.css.ts"
35798
+ }
35799
+ }
35800
+ ]
35801
+ },
35802
+ {
35803
+ "kind": "javascript-module",
35804
+ "path": "src/flex/root/flex-root.ts",
35805
+ "declarations": [
35806
+ {
35807
+ "kind": "class",
35808
+ "description": "The host is the flex container itself and the only child is a slot, so the\nelement adds no box of its own: `<helix-flex>` costs exactly the `<div>` it\nreplaces.\n\nThere is no separate Stack. A stack is this with `direction=\"column\"`, and a\nsecond element whose whole definition is one default of the first is a name\nto learn rather than a capability to gain.\n\nGap takes a space token name rather than a length, so spacing stays on the\nscale. A layout that can say `gap=\"13px\"` is one that will.\n\nPresentation only, so there is no headless tier: the split exists to keep\nbehavior separate from styling, and this is entirely styling.",
35809
+ "name": "HelixFlex",
35810
+ "slots": [
35811
+ {
35812
+ "description": "The items to lay out.",
35813
+ "name": ""
35814
+ }
35815
+ ],
35816
+ "members": [
35817
+ {
35818
+ "kind": "field",
35819
+ "name": "align",
35820
+ "type": {
35821
+ "text": "'start' | 'center' | 'end' | 'stretch' | 'baseline' | undefined"
35822
+ },
35823
+ "description": "Alignment across the direction.",
35824
+ "attribute": "align",
35825
+ "reflects": true
35826
+ },
35827
+ {
35828
+ "kind": "field",
35829
+ "name": "direction",
35830
+ "type": {
35831
+ "text": "'row' | 'column' | undefined"
35832
+ },
35833
+ "description": "Whether items run across or down.",
35834
+ "attribute": "direction",
35835
+ "reflects": true
35836
+ },
35837
+ {
35838
+ "kind": "field",
35839
+ "name": "gap",
35840
+ "type": {
35841
+ "text": "'none' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | undefined"
35842
+ },
35843
+ "description": "Space between items, named on the space scale.",
35844
+ "attribute": "gap",
35845
+ "reflects": true
35846
+ },
35847
+ {
35848
+ "kind": "field",
35849
+ "name": "inline",
35850
+ "type": {
35851
+ "text": "boolean"
35852
+ },
35853
+ "default": "false",
35854
+ "description": "Flows with surrounding text instead of taking the full width.",
35855
+ "attribute": "inline",
35856
+ "reflects": true
35857
+ },
35858
+ {
35859
+ "kind": "field",
35860
+ "name": "justify",
35861
+ "type": {
35862
+ "text": "'start' | 'center' | 'end' | 'between' | 'around' | undefined"
35863
+ },
35864
+ "description": "Distribution along the direction.",
35865
+ "attribute": "justify",
35866
+ "reflects": true
35867
+ },
35868
+ {
35869
+ "kind": "field",
35870
+ "name": "wrap",
35871
+ "type": {
35872
+ "text": "boolean"
35873
+ },
35874
+ "default": "false",
35875
+ "description": "Whether items wrap onto more lines.",
35876
+ "attribute": "wrap",
35877
+ "reflects": true
35878
+ },
35879
+ {
35880
+ "kind": "field",
35881
+ "name": "tier",
35882
+ "type": {
35883
+ "text": "string"
35884
+ },
35885
+ "static": true,
35886
+ "default": "'helix-headless-'",
35887
+ "description": "The prefix this tier registers its elements under.\n\n**A component that renders another renders its own tier's version of it**,\nso `helix-headless-pagination-size` composes `helix-headless-select` and\n`helix-pagination-size` composes `helix-select`. One template says\n`${this.tag('select')}` and each tier answers with its own name.\n\n**The public tag may not be the composed one, in either tier.** Using it\ncosts three things: the name means two different things depending on what a\nconsumer imported, the headless tier composes an element it does not ship,\nand the composition cannot be tested there at all, because there is no\n`helix-select` on that tier to test it against.\n\n**A prefix rather than an override per composition**, which was the first\nplan and does not compile. An override re-renders the fragment from the\nsubclass, and the fragment reads members the base keeps private:\n`PaginationSize` alone would have had to widen `options`, `current` and\n`handleChange` to `protected` so a subclass could say the same thing again.\nSixteen families of that is a lot of encapsulation spent on saying one\nword differently.",
35888
+ "inheritedFrom": {
35889
+ "name": "HelixElement",
35890
+ "module": "src/helix-element/helix-element.ts"
35891
+ }
35892
+ },
35893
+ {
35894
+ "kind": "method",
35895
+ "name": "tag",
35896
+ "privacy": "protected",
35897
+ "return": {
35898
+ "type": {
35899
+ "text": "StaticValue"
35900
+ }
35901
+ },
35902
+ "parameters": [
35903
+ {
35904
+ "name": "name",
35905
+ "type": {
35906
+ "text": "string"
35907
+ }
35908
+ }
35909
+ ],
35910
+ "description": "One composed tag, as a static value a template can interpolate.\n\n`unsafeStatic` is safe by construction: the name is a literal in our own\nsource and the prefix is one of two strings this class defines. Called per\nrender and not cached, which costs nothing, because `static-html` keys its\ntemplate cache on the joined string rather than on the object.",
35911
+ "inheritedFrom": {
35912
+ "name": "HelixElement",
35913
+ "module": "src/helix-element/helix-element.ts"
35914
+ }
35915
+ },
35916
+ {
35917
+ "kind": "field",
35918
+ "name": "internals",
35919
+ "type": {
35920
+ "text": "ElementInternals"
35921
+ },
35922
+ "privacy": "protected",
35923
+ "readonly": true,
35924
+ "description": "The element's semantics, set without touching the DOM.\n\n`ElementInternals` sets the implicit role, which an author's own `role`\nattribute still overrides, and it writes no attribute. Setting `role` on the\nhost directly would: that is an attribute the element gives itself after it\nupgrades, which a React consumer's server markup never had, and hydration\nreports it as a mismatch.\n\nAvailable during server rendering. Lit's shim implements `attachInternals`,\nso nothing here needs a guard.",
35925
+ "inheritedFrom": {
35926
+ "name": "HelixElement",
35927
+ "module": "src/helix-element/helix-element.ts"
35928
+ }
35929
+ },
35930
+ {
35931
+ "kind": "method",
35932
+ "name": "toggleState",
35933
+ "privacy": "protected",
35934
+ "return": {
35935
+ "type": {
35936
+ "text": "void"
35937
+ }
35938
+ },
35939
+ "parameters": [
35940
+ {
35941
+ "name": "name",
35942
+ "type": {
35943
+ "text": "string"
35944
+ }
35945
+ },
35946
+ {
35947
+ "name": "on",
35948
+ "type": {
35949
+ "text": "boolean"
35950
+ }
35951
+ }
35952
+ ],
35953
+ "description": "Records a boolean fact about this element as a custom state.\n\n**The host belongs to whoever rendered it, and a component's own\nbookkeeping may not be kept there.** An attribute written on the first\nupdate is markup a consumer's server never sent, so a React consumer\nhydrates a DOM that has gained attributes since and reports a mismatch it\nwill not patch up. A custom state is not in the DOM at all: it carries the\nfact to a stylesheet through `:state()` and leaves the markup alone, so the\nserver's output and the client's agree by construction.\n\n`SETTLED` carries the long version of that argument; `checked`, `open`,\n`invalid` and `has-label` are recorded the same way, each of them a state a\n`default-*` attribute resolves before React reaches the node.\n\n**Deferring the definitions is not a fix and could not be.** Importing them\nfrom an effect so the upgrades fall the other side of hydration works only\nwhile hydration is one pass: anything that splits it, a streamed segment or\na suspended boundary, puts an upgrade back inside the window. Timing cannot\nbe the guarantee when the fact is kept somewhere React reconciles.\n\nFeature-tested rather than assumed, the way `hostAria` tests element\nreferences. An engine without `CustomStateSet` records nothing and keeps\nwhatever the resting rule draws, which is the safe direction to fail.\n\n**The engines the test is for are browsers**: Safari below 17.4 and Firefox\nbelow 126, where the write is a `TypeError`, so a component bypassing this\nfails to render rather than rendering without whatever the state draws.\nLit's server shim sets `states`, so the guard passes there and records a\nstate nothing reads, which is harmless.",
35954
+ "inheritedFrom": {
35955
+ "name": "HelixElement",
35956
+ "module": "src/helix-element/helix-element.ts"
35957
+ }
35958
+ },
35959
+ {
35960
+ "kind": "field",
35961
+ "name": "whenSettled",
35962
+ "type": {
35963
+ "text": "Promise<void>"
35964
+ },
35965
+ "readonly": true,
35966
+ "description": "Resolves a frame after the first update, when transitions are switched on.\n\n**Named `whenSettled` because `settled` is taken four times over**, by\nImage, Splitter and both color controls, none of them about transitions. A\nbase class takes the name every subclass then cannot use.\n\n**The state it reports cannot be watched, which is why this exists.** A\ncustom state is deliberately not in the DOM, so there is no\n`MutationObserver` equivalent for `ElementInternals.states`. Await this\ninstead.\n\nSeparate from `updateComplete`, which resolves in the microtask checkpoint\nthe suppression is still active in. That is the distinction `readyToMove`\nin `@fusion.dev/helix-testing` is written around.\n\nIt never resolves where `requestAnimationFrame` never fires, which is a\nserver, a hidden tab, and happy-dom. Callers that must not hang race it\nagainst a timeout; `readyToMove` does exactly that.",
35967
+ "default": "new Promise<void>((resolve) => { this.resolveSettled = resolve })",
35968
+ "inheritedFrom": {
35969
+ "name": "HelixElement",
35970
+ "module": "src/helix-element/helix-element.ts"
35971
+ }
35972
+ },
35973
+ {
35974
+ "kind": "field",
35975
+ "name": "resolveSettled",
35976
+ "type": {
35977
+ "text": "() => void"
35978
+ },
35979
+ "privacy": "private",
35980
+ "description": "Resolves `whenSettled`, once, from the frame that records the state.",
35981
+ "inheritedFrom": {
35982
+ "name": "HelixElement",
35983
+ "module": "src/helix-element/helix-element.ts"
35984
+ }
35985
+ },
35986
+ {
35987
+ "kind": "field",
35988
+ "name": "stopInner",
35989
+ "privacy": "protected",
35990
+ "readonly": true,
35991
+ "description": "Stops an inner control's own announcement at this element's boundary.\n\n**A composed control is one control to a consumer, and the natives had no\nequivalent of the stop the prefixed events already get.** `<helix-select>`\nrenders a `<helix-listbox>`, and both announce: the listbox dispatches\n`input` and `change` from its own host, `input` is composed by\nspecification, and a consumer listening on the select therefore heard one\nchoice twice. Measured before this existed, on the styled tier, one choice\non the inner listbox: select `input` twice and `change` three times,\ncombobox, date input, time input and color input twice each. `Command` was\nthe only one that was right, because it happened to reach for\n`stopImmediatePropagation` for a different reason.\n\nBound on the child in the parent's template, so it runs while the event is\nstill at the child and before it can cross. The guard is for the case where\na component binds this on itself: an element must never stop its own\nannouncement, which is the one it exists to make.\n\nThis is the same job the `helix-before-*` handlers do with their own\n`stopPropagation`, and it is separate rather than folded into them because\na consumer may legitimately refuse a request without the notification ever\nhappening: the two travel at different times and one can be absent.",
35992
+ "inheritedFrom": {
35993
+ "name": "HelixElement",
35994
+ "module": "src/helix-element/helix-element.ts"
35995
+ }
35996
+ },
35997
+ {
35998
+ "kind": "method",
35999
+ "name": "relayNativeEvent",
36000
+ "privacy": "protected",
36001
+ "return": {
36002
+ "type": {
36003
+ "text": "void"
36004
+ }
36005
+ },
36006
+ "parameters": [
36007
+ {
36008
+ "name": "event",
36009
+ "type": {
36010
+ "text": "Event"
36011
+ }
36012
+ },
36013
+ {
36014
+ "name": "init",
36015
+ "optional": true,
36016
+ "type": {
36017
+ "text": "EventInit"
36018
+ }
36019
+ }
36020
+ ],
36021
+ "description": "Re-emits a native event from the host, under its own name.\n\nA native event fired by an inner `<input>` or `<textarea>` is not composed,\nso it stops at the shadow boundary and a consumer listening on\n`<helix-input>` hears nothing. Re-dispatching it from the host is what\nmakes the component behave like the control it wraps.\n\nThe relayed event keeps the native name deliberately. `change` is `change`,\nwhich is what a consumer already knows to listen for, and it is what\nreaches React: its synthetic system claims `onChange` and wires it to that\nname, so a prefixed one would never arrive.\n\n`composed` is not forced. It defaults to the original event's own value, so\na relayed `change` stops at the next shadow boundary exactly as a native\none would. Pass it explicitly only where escaping is the intent, and say so\nwhere you do.",
36022
+ "inheritedFrom": {
36023
+ "name": "HelixElement",
36024
+ "module": "src/helix-element/helix-element.ts"
36025
+ }
36026
+ },
36027
+ {
36028
+ "kind": "method",
36029
+ "name": "finalizeStyles",
36030
+ "privacy": "protected",
36031
+ "static": true,
34629
36032
  "return": {
34630
36033
  "type": {
34631
36034
  "text": "CSSResultOrNative[]"
@@ -39461,6 +40864,14 @@
39461
40864
  "module": "src/file-input/index.js"
39462
40865
  }
39463
40866
  },
40867
+ {
40868
+ "kind": "js",
40869
+ "name": "*",
40870
+ "declaration": {
40871
+ "name": "*",
40872
+ "module": "src/filter-input/index.js"
40873
+ }
40874
+ },
39464
40875
  {
39465
40876
  "kind": "js",
39466
40877
  "name": "*",