@fusion.dev/helix-headless 0.183.0 → 0.184.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.
@@ -31992,9 +31992,34 @@
31992
31992
  "kind": "javascript-module",
31993
31993
  "path": "src/code-block/root/code-block-root.ts",
31994
31994
  "declarations": [
31995
+ {
31996
+ "kind": "function",
31997
+ "name": "registerHighlighter",
31998
+ "return": {
31999
+ "type": {
32000
+ "text": "void"
32001
+ }
32002
+ },
32003
+ "parameters": [
32004
+ {
32005
+ "name": "highlighter",
32006
+ "type": {
32007
+ "text": "CodeBlockHighlighter | undefined"
32008
+ }
32009
+ },
32010
+ {
32011
+ "name": "sheet",
32012
+ "optional": true,
32013
+ "type": {
32014
+ "text": "CSSResult"
32015
+ }
32016
+ }
32017
+ ],
32018
+ "description": "Gives every Code Block of both tiers a highlighter, for the blocks that set\nno `highlight` of their own, and the sheet that colors what it returns.\n\n**Opt-in, so a page that shows plain code carries no grammar.** Code Block\nships none: a grammar is the larger part of any highlighter, and a block\nthat registers one for every page makes every page pay for it. A page that\nwants color imports one entry that calls this, such as\n`@fusion.dev/helix-sandbox/code-block`, which reads `css`, `html`, `js`,\n`jsx`, `sh`, `ts` and `tsx` with the sandbox's Lezer grammars and colors\nthem from the `--helix-color-syntax-*` tokens.\n\nA block's own `highlight` wins over this. Blocks already on the page draw\nagain with it, and every block built after has it. `undefined` takes it\naway again."
32019
+ },
31995
32020
  {
31996
32021
  "kind": "class",
31997
- "description": "Renders a `<pre><code>` pair: `pre` keeps the whitespace, and `code` marks it\nas code. Long lines scroll inside the block and do not wrap, because a line\nbreak can be significant in code.\n\nA copy button is on by default. Set `no-copy` to remove it. The button copies\nthe slotted text, so there is no second copy of the code to keep in sync.\n\nFor a fragment of code inside a sentence, use `Code`.\n\nSet `line-numbers` to number the lines in a gutter beside the code, hidden\nfrom the accessibility tree and left out of a copy. Set `mark-lines` to\nmark lines a reader should look at, such as `2, 4-6`: the block draws a\nband behind each run, placed where the lines are laid out, so it follows a\nhighlighter's markup and lines that wrap. `added-lines` and\n`removed-lines` mark lines the same way as inserted and deleted, as\nExpressive Code's `ins` and `del` do, in code that is not a diff. The bands\nare drawn and hidden from screen readers, so say in the text around the\nblock what a marked line means. Set `wrap` to wrap long lines\nrather than scroll them; a gutter then numbers each line where it starts.\nSet `wrappable` for a button in the header that turns `wrap` on and off,\npressed while the lines wrap.\n\nThe header holds the name, the `actions` slot, and the copy button. Slot a\ncontrol into `actions`, such as a button that sets `wrap` or one that opens\nthe code in an editor, and the block draws a header for it even with no\nname. `copy-icon` and `copied-icon` replace the copy button's two icons. Set `highlight` to a\nfunction that turns the code into highlighted markup, such as one wrapping\nShiki or Prism, and the block draws what it returns; it is handed the\nblock's `language`, so one function serves every block. The code stays in\nthe slot, so the copy button and the page's own text are the code as\nwritten.\n\nSet `expandable` on a block whose height is capped, such as by\n`--code-block-max-block-size`, and a button under it shows every line and\nthen fewer again, as a docs site's long example does. The button is drawn\nonly while the cap hides something, says whether the block is expanded with\n`aria-expanded`, names the block it opens with `aria-controls`, and the block\ncarries `:state(expanded)` while it is.\n\nSet `diff` to show a change. Put a unified diff, the output of `git diff` or\n`diff -u`, in the same slot, and the block draws the lines it added and\nremoved. The block never computes a diff itself. Line numbers come from the\nhunk headers and are hidden from the accessibility tree. Changed lines are\n`<ins>` and `<del>` with the `+` and `-` kept as text, so the change does not\ndepend on color. Where a removed line is paired with the added line that\nreplaced it, the words each does not share with the other are the `changed`\npart, so the eye goes to what changed within the line. Each file in the patch is its own block under its own name,\nand its copy button copies the new version of the file. `variant=\"split\"`\nshows the old version beside the new, each removal opposite its replacement.\n`context-lines` folds each long run of unchanged lines, keeping that many\nbeside each change, behind a button that shows them and hides them again,\nas a code host draws a diff written with more context than a reader needs.\n\n**A block that scrolls is a tab stop.** While its lines run past its width or\nits cap, the scroller is a region named for the block, such as \"Code,\napp.ts\", that Tab reaches, so a keyboard scrolls it with the arrow keys in\nevery browser. Chromium and Firefox make a scrolling box focusable on their\nown, and Safari does not. A block that fits is no stop at all.\n\n**The code the block draws is marked untranslated**, `translate=\"no\"` on\nits `<pre>`, so a page translator leaves highlighted lines and a diff as\nwritten. Code in the slot takes its translation mode from the element, which\nwrites nothing onto itself, so set `translate=\"no\"` on the element to keep a\ntranslator off plain code too.\n\nOn the server, the slot renders as ordinary code, so a diff first appears as\nthe patch text in a `<pre>`. The client makes the same first render, which\nkeeps hydration clean, and draws the diff once it can read the content. Diff\nmode is experimental. The rest of the family is stable.\n\n**Several blocks are files**, one shown at a time under a row of tabs, as\nSandbox shows its source panes. Put Code Blocks in the default slot of a\nCode Block, and each is a file named on its tab by its `label` or, without\none, its `language`. `file` holds the name of the file shown. The tabs are a\ntab list: the arrow keys move to a tab and show its file, the two swapping\non a right-to-left page, and Home and End go to the first and the last.\nChoosing one sends `helix-before-change` with the file's name, which you can\ncancel, and `change` once `file` holds it. The files not shown carry\n`hidden`, and the one shown draws no name of its own, its tab naming it. One\nblock draws no tabs. A server cannot see the blocks inside, so the client\ndraws the tabs once it upgrades.",
32022
+ "description": "Renders a `<pre><code>` pair: `pre` keeps the whitespace, and `code` marks it\nas code. Long lines scroll inside the block and do not wrap, because a line\nbreak can be significant in code.\n\nA copy button is on by default. Set `no-copy` to remove it. The button copies\nthe slotted text, so there is no second copy of the code to keep in sync.\n\nFor a fragment of code inside a sentence, use `Code`.\n\nSet `line-numbers` to number the lines in a gutter beside the code, hidden\nfrom the accessibility tree and left out of a copy. Set `mark-lines` to\nmark lines a reader should look at, such as `2, 4-6`: the block draws a\nband behind each run, placed where the lines are laid out, so it follows a\nhighlighter's markup and lines that wrap. `added-lines` and\n`removed-lines` mark lines the same way as inserted and deleted, as\nExpressive Code's `ins` and `del` do, in code that is not a diff. The bands\nare drawn and hidden from screen readers, so say in the text around the\nblock what a marked line means. Set `wrap` to wrap long lines\nrather than scroll them; a gutter then numbers each line where it starts.\nSet `wrappable` for a button in the header that turns `wrap` on and off,\npressed while the lines wrap.\n\nThe header holds the name, the `actions` slot, and the copy button. Slot a\ncontrol into `actions`, such as a button that sets `wrap` or one that opens\nthe code in an editor, and the block draws a header for it even with no\nname. `copy-icon` and `copied-icon` replace the copy button's two icons. Set `highlight` to a\nfunction that turns the code into highlighted markup, such as one wrapping\nShiki or Prism, and the block draws what it returns; it is handed the\nblock's `language`, so one function serves every block. The code stays in\nthe slot, so the copy button and the page's own text are the code as\nwritten.\n\n**Code Block ships no grammar**, so plain code costs you no parser. To color\ncode without a highlighter of your own, import one more entry beside the\nblock's. It colors every block by its `language` (`css`, `html`, `js`,\n`jsx`, `sh`, `ts`, or `tsx`) with the Lezer grammars of the sandbox's\neditor, in the editor's colors:\n\n```js\nimport '@fusion.dev/helix/code-block'\nimport '@fusion.dev/helix-sandbox/code-block'\n```\n\nThat entry calls `registerHighlighter`, which you can also call yourself to\ngive every block one highlighter of your own.\n\nSet `expandable` on a block whose height is capped, such as by\n`--code-block-max-block-size`, and a button under it shows every line and\nthen fewer again, as a docs site's long example does. The button is drawn\nonly while the cap hides something, says whether the block is expanded with\n`aria-expanded`, names the block it opens with `aria-controls`, and the block\ncarries `:state(expanded)` while it is.\n\nSet `diff` to show a change. Put a unified diff, the output of `git diff` or\n`diff -u`, in the same slot, and the block draws the lines it added and\nremoved. The block never computes a diff itself. Line numbers come from the\nhunk headers and are hidden from the accessibility tree. Changed lines are\n`<ins>` and `<del>` with the `+` and `-` kept as text, so the change does not\ndepend on color. Where a removed line is paired with the added line that\nreplaced it, the words each does not share with the other are the `changed`\npart, so the eye goes to what changed within the line. Each file in the patch is its own block under its own name,\nand its copy button copies the new version of the file. `variant=\"split\"`\nshows the old version beside the new, each removal opposite its replacement.\n`context-lines` folds each long run of unchanged lines, keeping that many\nbeside each change, behind a button that shows them and hides them again,\nas a code host draws a diff written with more context than a reader needs.\n\n**A block that scrolls is a tab stop.** While its lines run past its width or\nits cap, the scroller is a region named for the block, such as \"Code,\napp.ts\", that Tab reaches, so a keyboard scrolls it with the arrow keys in\nevery browser. Chromium and Firefox make a scrolling box focusable on their\nown, and Safari does not. A block that fits is no stop at all.\n\n**The code the block draws is marked untranslated**, `translate=\"no\"` on\nits `<pre>`, so a page translator leaves highlighted lines and a diff as\nwritten. Code in the slot takes its translation mode from the element, which\nwrites nothing onto itself, so set `translate=\"no\"` on the element to keep a\ntranslator off plain code too.\n\nOn the server, the slot renders as ordinary code, so a diff first appears as\nthe patch text in a `<pre>`. The client makes the same first render, which\nkeeps hydration clean, and draws the diff once it can read the content. Diff\nmode is experimental. The rest of the family is stable.\n\n**Several blocks are files**, one shown at a time under a row of tabs, as\nSandbox shows its source panes. Put Code Blocks in the default slot of a\nCode Block, and each is a file named on its tab by its `label` or, without\none, its `language`. `file` holds the name of the file shown. The tabs are a\ntab list: the arrow keys move to a tab and show its file, the two swapping\non a right-to-left page, and Home and End go to the first and the last.\nChoosing one sends `helix-before-change` with the file's name, which you can\ncancel, and `change` once `file` holds it. The files not shown carry\n`hidden`, and the one shown draws no name of its own, its tab naming it. One\nblock draws no tabs. A server cannot see the blocks inside, so the client\ndraws the tabs once it upgrades.",
31998
32023
  "name": "HelixHeadlessCodeBlock",
31999
32024
  "cssProperties": [
32000
32025
  {
@@ -32401,7 +32426,7 @@
32401
32426
  "type": {
32402
32427
  "text": "(code: string, language: string) => string | undefined"
32403
32428
  },
32404
- "description": "Turns the code into highlighted markup, which the block draws in place of\nthe plain text.\n\nCalled with the code as written and the block's `language`, and returning\nHTML, such as the output of Shiki's `codeToHtml` or Prism's `highlight`.\nOne function serves every block on a page, each block saying its own\nlanguage:\n\n```js\nfor (const block of document.querySelectorAll('helix-code-block')) {\n block.highlight = (code, lang) => codeToHtml(code, { lang, theme: 'github-light' })\n}\n```\n\n**The markup is drawn as given**, so it has to escape the code it was\nhanded, which those highlighters do. A `<pre>` and `<code>` around the\nwhole of it, which Shiki writes, are taken off, so the lines sit level\nwith the gutter's numbers and the block keeps one tab stop. The code stays\nin the slot, so the copy button copies it as written and a reader without\nthe script still has it. Not called on a server, which has no code to\nread, nor for a diff."
32429
+ "description": "Turns the code into highlighted markup, which the block draws in place of\nthe plain text.\n\nCalled with the code as written and the block's `language`, and returning\nHTML, such as the output of Shiki's `codeToHtml` or Prism's `highlight`.\nOne function serves every block on a page, each block saying its own\nlanguage:\n\n```js\nfor (const block of document.querySelectorAll('helix-code-block')) {\n block.highlight = (code, lang) => codeToHtml(code, { lang, theme: 'github-light' })\n}\n```\n\n**The markup is drawn as given**, so it has to escape the code it was\nhanded, which those highlighters do. A `<pre>` and `<code>` around the\nwhole of it, which Shiki writes, are taken off, so the lines sit level\nwith the gutter's numbers and the block keeps one tab stop. The code stays\nin the slot, so the copy button copies it as written and a reader without\nthe script still has it. Not called on a server, which has no code to\nread, nor for a diff.\n\nAbsent, the block draws with the highlighter `registerHighlighter` gave\nevery block, where an entry such as `@fusion.dev/helix-sandbox/code-block`\nregistered one, and plain otherwise."
32405
32430
  },
32406
32431
  {
32407
32432
  "kind": "field",
@@ -33792,6 +33817,14 @@
33792
33817
  }
33793
33818
  ],
33794
33819
  "exports": [
33820
+ {
33821
+ "kind": "js",
33822
+ "name": "registerHighlighter",
33823
+ "declaration": {
33824
+ "name": "registerHighlighter",
33825
+ "module": "src/code-block/root/code-block-root.ts"
33826
+ }
33827
+ },
33795
33828
  {
33796
33829
  "kind": "js",
33797
33830
  "name": "HelixHeadlessCodeBlock",
@@ -85795,6 +85828,14 @@
85795
85828
  "module": "src/megamenu/index.js"
85796
85829
  }
85797
85830
  },
85831
+ {
85832
+ "kind": "js",
85833
+ "name": "*",
85834
+ "declaration": {
85835
+ "name": "*",
85836
+ "module": "src/menu/filter/index.js"
85837
+ }
85838
+ },
85798
85839
  {
85799
85840
  "kind": "js",
85800
85841
  "name": "*",
@@ -111680,6 +111721,392 @@
111680
111721
  }
111681
111722
  ]
111682
111723
  },
111724
+ {
111725
+ "kind": "javascript-module",
111726
+ "path": "src/menu/filter/index.ts",
111727
+ "declarations": [],
111728
+ "exports": [
111729
+ {
111730
+ "kind": "js",
111731
+ "name": "filterMenu",
111732
+ "declaration": {
111733
+ "name": "filterMenu",
111734
+ "module": "./menu-filter.js"
111735
+ }
111736
+ },
111737
+ {
111738
+ "kind": "js",
111739
+ "name": "MenuFilterController",
111740
+ "declaration": {
111741
+ "name": "MenuFilterController",
111742
+ "module": "./menu-filter.js"
111743
+ }
111744
+ }
111745
+ ]
111746
+ },
111747
+ {
111748
+ "kind": "javascript-module",
111749
+ "path": "src/menu/filter/menu-filter.ts",
111750
+ "declarations": [
111751
+ {
111752
+ "kind": "function",
111753
+ "name": "drawFilter",
111754
+ "return": {
111755
+ "type": {
111756
+ "text": "TemplateResult"
111757
+ }
111758
+ },
111759
+ "parameters": [
111760
+ {
111761
+ "name": "host",
111762
+ "type": {
111763
+ "text": "HelixHeadlessMenu"
111764
+ }
111765
+ },
111766
+ {
111767
+ "name": "rows",
111768
+ "type": {
111769
+ "text": "TemplateResult"
111770
+ }
111771
+ },
111772
+ {
111773
+ "name": "busy",
111774
+ "type": {
111775
+ "text": "string | typeof nothing"
111776
+ }
111777
+ },
111778
+ {
111779
+ "name": "onInput",
111780
+ "type": {
111781
+ "text": "(event: Event) => void"
111782
+ }
111783
+ }
111784
+ ],
111785
+ "description": "The field and then the `menu`: a menu holds menu items and nothing else, so\nthe field stands beside it, as React Aria's `Autocomplete` puts its search\nfield beside its menu. The menu calls it through its filter, so the parts it\nwrites are the menu's."
111786
+ },
111787
+ {
111788
+ "kind": "class",
111789
+ "description": "Narrows a `filterable` menu's rows as the reader types in a field above\nthem, with focus staying in the field and the highlight moving through the\nrows that are left.\n\n**Its own entry**, `@fusion.dev/helix-headless/menu/filter`, so a menu that\nnever filters carries none of this. Importing the entry gives every menu of\nthe tier one, and `filterable` turns it on. Menu's description says what a\nreader gets; this is the part of it the menu does not hold:\n\n- the field and the `menu` after it, which the menu draws in its surface\n- which rows the filter keeps, and the words each matched, marked\n- the keys the field answers: Up and Down move the highlight, Enter presses\n the highlighted row, and Escape clears the filter before it closes\n- `helix-filter`, sent as the text changes, which a listener cancels to\n keep every row showing\n- how many rows are kept, or `no-results-text`, said in the live region\n\nThe styled tier's entry hands in the sheet that draws the field, which the\nmenu adopts while it filters.",
111790
+ "name": "MenuFilterController",
111791
+ "members": [
111792
+ {
111793
+ "kind": "field",
111794
+ "name": "host",
111795
+ "type": {
111796
+ "text": "HelixHeadlessMenu"
111797
+ },
111798
+ "privacy": "private",
111799
+ "readonly": true,
111800
+ "default": "host"
111801
+ },
111802
+ {
111803
+ "kind": "field",
111804
+ "name": "inside",
111805
+ "type": {
111806
+ "text": "Inside"
111807
+ },
111808
+ "privacy": "private",
111809
+ "readonly": true,
111810
+ "description": "The same menu, read through what it keeps to itself."
111811
+ },
111812
+ {
111813
+ "kind": "field",
111814
+ "name": "sheet",
111815
+ "type": {
111816
+ "text": "CSSResult | undefined"
111817
+ },
111818
+ "description": "The sheet the menu adopts while it filters, from the styled tier.",
111819
+ "default": "sheet"
111820
+ },
111821
+ {
111822
+ "kind": "field",
111823
+ "name": "highlighted",
111824
+ "type": {
111825
+ "text": "Row | undefined"
111826
+ },
111827
+ "description": "The row the keys reached while focus stays in the field."
111828
+ },
111829
+ {
111830
+ "kind": "field",
111831
+ "name": "page",
111832
+ "type": {
111833
+ "text": "Row | null"
111834
+ },
111835
+ "privacy": "private",
111836
+ "default": "null",
111837
+ "description": "The submenu the filter narrows, or null for the top page."
111838
+ },
111839
+ {
111840
+ "kind": "field",
111841
+ "name": "refused",
111842
+ "type": {
111843
+ "text": "string | undefined"
111844
+ },
111845
+ "privacy": "private",
111846
+ "description": "The filter a listener refused, which narrows nothing."
111847
+ },
111848
+ {
111849
+ "kind": "field",
111850
+ "name": "seen",
111851
+ "type": {
111852
+ "text": "string"
111853
+ },
111854
+ "privacy": "private",
111855
+ "default": "''",
111856
+ "description": "The filter the last update saw, so a change moves a highlight it hid."
111857
+ },
111858
+ {
111859
+ "kind": "method",
111860
+ "name": "hostConnected",
111861
+ "return": {
111862
+ "type": {
111863
+ "text": "void"
111864
+ }
111865
+ }
111866
+ },
111867
+ {
111868
+ "kind": "method",
111869
+ "name": "hostDisconnected",
111870
+ "return": {
111871
+ "type": {
111872
+ "text": "void"
111873
+ }
111874
+ }
111875
+ },
111876
+ {
111877
+ "kind": "field",
111878
+ "name": "field",
111879
+ "type": {
111880
+ "text": "HTMLInputElement | null"
111881
+ },
111882
+ "description": "The field, while it is drawn.",
111883
+ "readonly": true
111884
+ },
111885
+ {
111886
+ "kind": "field",
111887
+ "name": "filtering",
111888
+ "type": {
111889
+ "text": "boolean"
111890
+ },
111891
+ "description": "Whether the filter is narrowing the rows.",
111892
+ "readonly": true
111893
+ },
111894
+ {
111895
+ "kind": "method",
111896
+ "name": "kept",
111897
+ "return": {
111898
+ "type": {
111899
+ "text": "boolean"
111900
+ }
111901
+ },
111902
+ "parameters": [
111903
+ {
111904
+ "name": "row",
111905
+ "type": {
111906
+ "text": "Row"
111907
+ }
111908
+ }
111909
+ ],
111910
+ "description": "Whether the filter keeps a row: one of another page, or one whose words it matches."
111911
+ },
111912
+ {
111913
+ "kind": "field",
111914
+ "name": "keptRows",
111915
+ "type": {
111916
+ "text": "Row[]"
111917
+ },
111918
+ "privacy": "private",
111919
+ "description": "The rows of the page the filter narrows that it keeps.",
111920
+ "readonly": true
111921
+ },
111922
+ {
111923
+ "kind": "method",
111924
+ "name": "request",
111925
+ "return": {
111926
+ "type": {
111927
+ "text": "void"
111928
+ }
111929
+ },
111930
+ "parameters": [
111931
+ {
111932
+ "name": "value",
111933
+ "type": {
111934
+ "text": "string"
111935
+ }
111936
+ }
111937
+ ],
111938
+ "description": "Asks to filter by new text, which the field and `filter` then hold. A\nrefusal keeps every row showing, for a page that narrows them itself."
111939
+ },
111940
+ {
111941
+ "kind": "method",
111942
+ "name": "by",
111943
+ "privacy": "private",
111944
+ "return": {
111945
+ "type": {
111946
+ "text": "void"
111947
+ }
111948
+ },
111949
+ "parameters": [
111950
+ {
111951
+ "name": "value",
111952
+ "type": {
111953
+ "text": "string"
111954
+ }
111955
+ }
111956
+ ],
111957
+ "description": "Filters by what the reader typed, and highlights the first row kept."
111958
+ },
111959
+ {
111960
+ "kind": "method",
111961
+ "name": "highlight",
111962
+ "return": {
111963
+ "type": {
111964
+ "text": "void"
111965
+ }
111966
+ },
111967
+ "parameters": [
111968
+ {
111969
+ "name": "row",
111970
+ "type": {
111971
+ "text": "Row | undefined"
111972
+ }
111973
+ }
111974
+ ],
111975
+ "description": "Puts the highlight on a row, which the field names with\n`aria-activedescendant`. An element reference, because the field is in\nthe menu's shadow root and the row in the tree around it, the one\ndirection a reference crosses."
111976
+ },
111977
+ {
111978
+ "kind": "method",
111979
+ "name": "keydown",
111980
+ "return": {
111981
+ "type": {
111982
+ "text": "boolean"
111983
+ }
111984
+ },
111985
+ "parameters": [
111986
+ {
111987
+ "name": "event",
111988
+ "type": {
111989
+ "text": "KeyboardEvent"
111990
+ }
111991
+ },
111992
+ {
111993
+ "name": "items",
111994
+ "type": {
111995
+ "text": "Row[]"
111996
+ }
111997
+ },
111998
+ {
111999
+ "name": "at",
112000
+ "type": {
112001
+ "text": "number"
112002
+ }
112003
+ }
112004
+ ],
112005
+ "description": "Answers a key the field takes, and returns whether it did: Up and Down\nmove the highlight through the rows kept, Enter presses the highlighted\nrow, and Escape over text empties the filter, the next one going back or\nclosing."
112006
+ },
112007
+ {
112008
+ "kind": "field",
112009
+ "name": "handleMouseDown",
112010
+ "privacy": "private",
112011
+ "readonly": true,
112012
+ "description": "Keeps focus in the field through a press on a row or the way back, as\nReact Aria's virtual focus does: the press still chooses."
112013
+ },
112014
+ {
112015
+ "kind": "field",
112016
+ "name": "handleInput",
112017
+ "privacy": "private",
112018
+ "readonly": true
112019
+ },
112020
+ {
112021
+ "kind": "method",
112022
+ "name": "status",
112023
+ "return": {
112024
+ "type": {
112025
+ "text": "TemplateResult | undefined"
112026
+ }
112027
+ },
112028
+ "description": "What a filter that keeps no rows shows, or nothing where it keeps some.\n\nIt sets what the live region says as well: `no-results-text` where the\nfilter keeps no rows, and how many it keeps where it keeps some, as React\nAria and Web Awesome say the count. Only \"No matches\" was said before\nthat, so a filter that kept forty rows and one that kept one sounded the\nsame."
112029
+ },
112030
+ {
112031
+ "kind": "method",
112032
+ "name": "drawFilter",
112033
+ "return": {
112034
+ "type": {
112035
+ "text": "TemplateResult"
112036
+ }
112037
+ },
112038
+ "parameters": [
112039
+ {
112040
+ "name": "rows",
112041
+ "type": {
112042
+ "text": "TemplateResult"
112043
+ }
112044
+ },
112045
+ {
112046
+ "name": "busy",
112047
+ "type": {
112048
+ "text": "string | typeof nothing"
112049
+ }
112050
+ }
112051
+ ],
112052
+ "description": "The field and then the `menu`, for the menu to draw in its surface. See `drawFilter`."
112053
+ }
112054
+ ],
112055
+ "helix": {}
112056
+ },
112057
+ {
112058
+ "kind": "function",
112059
+ "name": "filterMenu",
112060
+ "return": {
112061
+ "type": {
112062
+ "text": "void"
112063
+ }
112064
+ },
112065
+ "parameters": [
112066
+ {
112067
+ "name": "element",
112068
+ "type": {
112069
+ "text": "typeof HelixHeadlessMenu"
112070
+ }
112071
+ },
112072
+ {
112073
+ "name": "sheet",
112074
+ "optional": true,
112075
+ "type": {
112076
+ "text": "CSSResult"
112077
+ }
112078
+ }
112079
+ ],
112080
+ "description": "Gives every menu of a class a `MenuFilterController`, which `filterable`\nturns on.\n\nThe entries call it for their own tier's class: the headless entry for\n`HelixHeadlessMenu`, and the styled one for `HelixMenu`, with the sheet that\ndraws the field. **Menus already on the page are given one too**, and drawn\nagain, so a page that imports the menu and then this entry gets the field."
112081
+ }
112082
+ ],
112083
+ "exports": [
112084
+ {
112085
+ "kind": "js",
112086
+ "name": "drawFilter",
112087
+ "declaration": {
112088
+ "name": "drawFilter",
112089
+ "module": "src/menu/filter/menu-filter.ts"
112090
+ }
112091
+ },
112092
+ {
112093
+ "kind": "js",
112094
+ "name": "MenuFilterController",
112095
+ "declaration": {
112096
+ "name": "MenuFilterController",
112097
+ "module": "src/menu/filter/menu-filter.ts"
112098
+ }
112099
+ },
112100
+ {
112101
+ "kind": "js",
112102
+ "name": "filterMenu",
112103
+ "declaration": {
112104
+ "name": "filterMenu",
112105
+ "module": "src/menu/filter/menu-filter.ts"
112106
+ }
112107
+ }
112108
+ ]
112109
+ },
111683
112110
  {
111684
112111
  "kind": "javascript-module",
111685
112112
  "path": "src/menu/index.ts",
@@ -112736,7 +113163,7 @@
112736
113163
  "declarations": [
112737
113164
  {
112738
113165
  "kind": "class",
112739
- "description": "The trigger is slotted and stays your own element, as with the tooltip. The\nmenu renders its surface in the top layer with the popover API, so an\nancestor with `overflow: hidden` does not clip it and it needs no `z-index`.\n\nSlot a `helix-button` or `helix-icon-button` as the trigger, and the menu\ntells it that it opens a menu and whether the menu is open, inside its own\nshadow root. On a plain element, such as a `<button>`, the menu writes\n`aria-haspopup=\"menu\"` and `aria-expanded`, from a frame after its own first\nrender, so a server's markup is never changed while a framework hydrates it.\nIt never writes `aria-expanded` where you wrote it yourself.\n\nSubmenus drill down by default. A submenu replaces the panel's content, and a\nback row returns to the previous page. One panel stays inside a narrow\nwindow, and works on touch screens, which have no hover. Focus follows a\nmouse resting on a row in either mode, and a drilled page is a `menu` named\nby the row that opened it.\n\n**`submenus=\"flyout\"` opens each submenu in a panel of its own beside its\nrow**, as React Aria's `SubmenuTrigger` and Radix's `Sub` do. Resting the\npointer on the row opens it, and a pointer crossing toward the open panel\nover the rows between keeps it open, as Radix's grace area does. Right Arrow\nopens a row's submenu on its first row, and Left Arrow or Escape closes it\nand returns focus to the row, the two arrows swapping on a right-to-left\npage. The row says `aria-expanded`, and the panel is a `menu` named by the\nrow.\n\nThe root holds which page is open, because only one page shows at a time. It\nsets this on items as a property, never as an attribute. An attribute written\nonto your element after it upgrades causes a hydration mismatch.\n\nGroup rows under a heading with `Menu.Section`, which is a `group` named by\nits heading. Between runs of rows, a `<helix-divider>` is a separator a\nscreen reader announces.\n\nKeys: Enter, Space or Down Arrow on the trigger opens the menu on its first\nrow, and Up Arrow on its last. In the menu, Up and Down Arrow move between\nrows, Home and End go to the first and the last, a typed letter moves to\nthe next row whose name starts with it, Enter and Space choose (Space on a\nchoice row changes it and leaves the menu open), Right Arrow\nopens a row's submenu and Left Arrow goes back, the two swapping on a\nright-to-left page. Left Arrow on the top page does nothing. Escape closes\nthe menu and returns focus to the trigger. Tab closes it and moves on.\n\nWhile it is open, the surface carries the trigger's width as\n`--floating-anchor-inline-size` and the room left below it as\n`--floating-available-block-size`, as Radix's dropdown menu publishes its\ntrigger's width, for a menu as wide as its trigger:\n`helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }`.\n\n**The choices in one place.** `checkedValues` holds the values of the rows\nthat are checked, anywhere in the menu, and setting it checks exactly\nthose rows, as React Aria's `selectedKeys` does. `change` is sent on the\nmenu when a reader's choice changes it.\n\nWith `context`, the trigger is an area and the menu is its context menu: a\nright-click, a long press, Shift+F10 or the menu key over the area opens it\nat the pointer, or at the area's corner from the keyboard, as Radix's context\nmenu does. A press on the area does not open it, and closing it returns focus\nto where it was. A touch or a pen held still on the area opens it too, on\nevery browser, since iOS sends no `contextmenu` for one.\n\n**A trigger with its own action.** With `open-on=\"long-press\"`, a press on\nthe trigger is the trigger's own, and a press held for half a second opens\nthe menu, as React Aria's `trigger=\"longPress\"` does. Alt+Down or Alt+Up\nopens it from the keyboard, and the trigger is described by\n`long-press-label`, which says so.\n\n**A filter field.** With `filterable`, the menu opens with focus in a field\nabove its rows, and typing narrows the rows of the page the keys move in,\nas React Aria's `Autocomplete` around a `Menu` does. A row is kept where its\nwords hold the filter, in any case, or where `filterMatch` says so. Each\npage starts unfiltered, and the filter is cleared as the menu closes. Where\ntyping keeps no row, the menu shows `no-results-text`. Focus stays in the\nfield: Up and Down Arrow move the highlight through the rows that are left,\nEnter chooses the highlighted row, Right Arrow opens its submenu, Left Arrow\non a submenu goes back, and Escape clears the filter and then closes the\nmenu. A screen reader hears how many rows the filter keeps\n(`results-label`). Home, End and the other keys move the caret and type. The field names\nthe highlighted row with `aria-activedescendant`, and the rows are a `menu`\nafter the field. Cancel `helix-filter` to keep every row\nshowing and narrow the rows yourself, such as by replacing them with rows\nfrom a server.",
113166
+ "description": "The trigger is slotted and stays your own element, as with the tooltip. The\nmenu renders its surface in the top layer with the popover API, so an\nancestor with `overflow: hidden` does not clip it and it needs no `z-index`.\n\nSlot a `helix-button` or `helix-icon-button` as the trigger, and the menu\ntells it that it opens a menu and whether the menu is open, inside its own\nshadow root. On a plain element, such as a `<button>`, the menu writes\n`aria-haspopup=\"menu\"` and `aria-expanded`, from a frame after its own first\nrender, so a server's markup is never changed while a framework hydrates it.\nIt never writes `aria-expanded` where you wrote it yourself.\n\nSubmenus drill down by default. A submenu replaces the panel's content, and a\nback row returns to the previous page. One panel stays inside a narrow\nwindow, and works on touch screens, which have no hover. Focus follows a\nmouse resting on a row in either mode, and a drilled page is a `menu` named\nby the row that opened it.\n\n**`submenus=\"flyout\"` opens each submenu in a panel of its own beside its\nrow**, as React Aria's `SubmenuTrigger` and Radix's `Sub` do. Resting the\npointer on the row opens it, and a pointer crossing toward the open panel\nover the rows between keeps it open, as Radix's grace area does. Right Arrow\nopens a row's submenu on its first row, and Left Arrow or Escape closes it\nand returns focus to the row, the two arrows swapping on a right-to-left\npage. The row says `aria-expanded`, and the panel is a `menu` named by the\nrow.\n\nThe root holds which page is open, because only one page shows at a time. It\nsets this on items as a property, never as an attribute. An attribute written\nonto your element after it upgrades causes a hydration mismatch.\n\nGroup rows under a heading with `Menu.Section`, which is a `group` named by\nits heading. Between runs of rows, a `<helix-divider>` is a separator a\nscreen reader announces.\n\nKeys: Enter, Space or Down Arrow on the trigger opens the menu on its first\nrow, and Up Arrow on its last. In the menu, Up and Down Arrow move between\nrows, Home and End go to the first and the last, a typed letter moves to\nthe next row whose name starts with it, Enter and Space choose (Space on a\nchoice row changes it and leaves the menu open), Right Arrow\nopens a row's submenu and Left Arrow goes back, the two swapping on a\nright-to-left page. Left Arrow on the top page does nothing. Escape closes\nthe menu and returns focus to the trigger. Tab closes it and moves on.\n\nWhile it is open, the surface carries the trigger's width as\n`--floating-anchor-inline-size` and the room left below it as\n`--floating-available-block-size`, as Radix's dropdown menu publishes its\ntrigger's width, for a menu as wide as its trigger:\n`helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }`.\n\n**The choices in one place.** `checkedValues` holds the values of the rows\nthat are checked, anywhere in the menu, and setting it checks exactly\nthose rows, as React Aria's `selectedKeys` does. `change` is sent on the\nmenu when a reader's choice changes it.\n\nWith `context`, the trigger is an area and the menu is its context menu: a\nright-click, a long press, Shift+F10 or the menu key over the area opens it\nat the pointer, or at the area's corner from the keyboard, as Radix's context\nmenu does. A press on the area does not open it, and closing it returns focus\nto where it was. A touch or a pen held still on the area opens it too, on\nevery browser, since iOS sends no `contextmenu` for one.\n\n**A trigger with its own action.** With `open-on=\"long-press\"`, a press on\nthe trigger is the trigger's own, and a press held for half a second opens\nthe menu, as React Aria's `trigger=\"longPress\"` does. Alt+Down or Alt+Up\nopens it from the keyboard, and the trigger is described by\n`long-press-label`, which says so.\n\n**A filter field** is a separate import, `@fusion.dev/helix/menu/filter`, so\na menu that never filters carries none of its code:\n\n```js\nimport '@fusion.dev/helix/menu'\nimport '@fusion.dev/helix/menu/filter'\n```\n\nWith it imported and `filterable` set, the menu opens with focus in a field\nabove its rows, and typing narrows the rows of the page the keys move in,\nas React Aria's `Autocomplete` around a `Menu` does. A row is kept where its\nwords hold the filter, in any case, or where `filterMatch` says so. Each\npage starts unfiltered, and the filter is cleared as the menu closes. Where\ntyping keeps no row, the menu shows `no-results-text`. Focus stays in the\nfield: Up and Down Arrow move the highlight through the rows that are left,\nEnter chooses the highlighted row, Right Arrow opens its submenu, Left Arrow\non a submenu goes back, and Escape clears the filter and then closes the\nmenu. A screen reader hears how many rows the filter keeps\n(`results-label`). Home, End and the other keys move the caret and type. The field names\nthe highlighted row with `aria-activedescendant`, and the rows are a `menu`\nafter the field. Cancel `helix-filter` to keep every row\nshowing and narrow the rows yourself, such as by replacing them with rows\nfrom a server.",
112740
113167
  "name": "HelixHeadlessMenu",
112741
113168
  "cssProperties": [
112742
113169
  {
@@ -112903,7 +113330,7 @@
112903
113330
  "text": "boolean"
112904
113331
  },
112905
113332
  "default": "false",
112906
- "description": "Whether the menu shows a field above its rows that narrows them as the\nreader types, with focus staying in the field.",
113333
+ "description": "Whether the menu shows a field above its rows that narrows them as the\nreader types, with focus staying in the field, once\n`@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)\nis imported. Without that import it does nothing, so a menu that never\nfilters carries none of the filter's code, and a development build says\nwhich import is missing.",
112907
113334
  "attribute": "filterable"
112908
113335
  },
112909
113336
  {
@@ -113258,41 +113685,21 @@
113258
113685
  },
113259
113686
  {
113260
113687
  "kind": "field",
113261
- "name": "field",
113688
+ "name": "filterer",
113262
113689
  "type": {
113263
- "text": "HTMLInputElement | null"
113690
+ "text": "MenuFilterController | undefined"
113264
113691
  },
113265
113692
  "privacy": "private",
113266
- "description": "The filter field, with `filterable`.",
113267
- "readonly": true
113693
+ "description": "The filter `menu/filter` gives this menu, which `filterable` turns on.\n\nDeclared and never initialized, because the entry sets it from the\nconstructor Lit runs initializers in, which is before this class's own\nfields: an initializer here would set it back to `undefined`."
113268
113694
  },
113269
113695
  {
113270
113696
  "kind": "field",
113271
- "name": "filterPage",
113697
+ "name": "filters",
113272
113698
  "type": {
113273
- "text": "HelixHeadlessMenuItem | null"
113699
+ "text": "MenuFilterController | undefined"
113274
113700
  },
113275
113701
  "privacy": "private",
113276
- "default": "null",
113277
- "description": "The submenu the filter narrows, or null for the top page."
113278
- },
113279
- {
113280
- "kind": "field",
113281
- "name": "refused",
113282
- "type": {
113283
- "text": "string | undefined"
113284
- },
113285
- "privacy": "private",
113286
- "description": "The filter a listener refused, which narrows nothing."
113287
- },
113288
- {
113289
- "kind": "field",
113290
- "name": "filtering",
113291
- "type": {
113292
- "text": "boolean"
113293
- },
113294
- "privacy": "private",
113295
- "description": "Whether the filter is narrowing the rows.",
113702
+ "description": "The filter, while `filterable` is set and `menu/filter` is imported.",
113296
113703
  "readonly": true
113297
113704
  },
113298
113705
  {
@@ -113312,7 +113719,7 @@
113312
113719
  }
113313
113720
  }
113314
113721
  ],
113315
- "description": "Whether the filter keeps a row: one of another page, or one whose words it matches."
113722
+ "description": "Whether the filter keeps a row, which every row is without one."
113316
113723
  },
113317
113724
  {
113318
113725
  "kind": "method",
@@ -113331,41 +113738,7 @@
113331
113738
  }
113332
113739
  }
113333
113740
  ],
113334
- "description": "Asks to filter by new text, which the field and `filter` then hold. A\nrefusal keeps every row showing, for a page that narrows them itself."
113335
- },
113336
- {
113337
- "kind": "field",
113338
- "name": "handleFilterInput",
113339
- "privacy": "private",
113340
- "readonly": true
113341
- },
113342
- {
113343
- "kind": "method",
113344
- "name": "filterBy",
113345
- "privacy": "private",
113346
- "return": {
113347
- "type": {
113348
- "text": "void"
113349
- }
113350
- },
113351
- "parameters": [
113352
- {
113353
- "name": "value",
113354
- "type": {
113355
- "text": "string"
113356
- }
113357
- }
113358
- ],
113359
- "description": "Filters by what the reader typed, and highlights the first row kept."
113360
- },
113361
- {
113362
- "kind": "field",
113363
- "name": "highlighted",
113364
- "type": {
113365
- "text": "HelixHeadlessMenuItem | undefined"
113366
- },
113367
- "privacy": "private",
113368
- "description": "The row the keys reached while focus stays in the filter field."
113741
+ "description": "Asks to filter by new text. See `MenuFilterController.request`."
113369
113742
  },
113370
113743
  {
113371
113744
  "kind": "method",
@@ -113384,7 +113757,7 @@
113384
113757
  }
113385
113758
  }
113386
113759
  ],
113387
- "description": "Moves the reader to a row: focus, or with `filterable` the highlight,\nwhich the field names with `aria-activedescendant`. An element reference,\nbecause the field is in this shadow root and the row in the tree around\nit, the one direction a reference crosses."
113760
+ "description": "Moves the reader to a row: focus, or with a filter the highlight, focus\nstaying in the filter field."
113388
113761
  },
113389
113762
  {
113390
113763
  "kind": "field",
@@ -113630,13 +114003,6 @@
113630
114003
  "readonly": true,
113631
114004
  "description": "A press on the trigger starting: the start of a held one under\n`open-on=\"long-press\"`, or a touch or a pen held on a context menu's area."
113632
114005
  },
113633
- {
113634
- "kind": "field",
113635
- "name": "handleMouseDown",
113636
- "privacy": "private",
113637
- "readonly": true,
113638
- "description": "Keeps focus in the filter field through a press on a row or the way\nback, as React Aria's virtual focus does: the press still chooses."
113639
- },
113640
114006
  {
113641
114007
  "kind": "field",
113642
114008
  "name": "handlePointerMove",
@@ -114573,7 +114939,7 @@
114573
114939
  "text": "boolean"
114574
114940
  },
114575
114941
  "default": "false",
114576
- "description": "Whether the menu shows a field above its rows that narrows them as the\nreader types, with focus staying in the field.",
114942
+ "description": "Whether the menu shows a field above its rows that narrows them as the\nreader types, with focus staying in the field, once\n`@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)\nis imported. Without that import it does nothing, so a menu that never\nfilters carries none of the filter's code, and a development build says\nwhich import is missing.",
114577
114943
  "fieldName": "filterable"
114578
114944
  },
114579
114945
  {
@@ -172618,6 +172984,19 @@
172618
172984
  "attribute": "mode",
172619
172985
  "reflects": true
172620
172986
  },
172987
+ {
172988
+ "kind": "field",
172989
+ "name": "nowLabel",
172990
+ "type": {
172991
+ "text": "string"
172992
+ },
172993
+ "default": "'Now'",
172994
+ "description": "The words on the list's button that chooses the current time, drawn with\n`show-now`.",
172995
+ "attribute": "now-label",
172996
+ "helix": {
172997
+ "words": true
172998
+ }
172999
+ },
172621
173000
  {
172622
173001
  "kind": "field",
172623
173002
  "name": "placeholder",
@@ -172693,6 +173072,16 @@
172693
173072
  "description": "Whether times carry their seconds: the value is `HH:mm:ss`, a typed time\nmay give them, the field writes them, and the list's `step` counts seconds.\nSee Time Picker's `seconds`.",
172694
173073
  "attribute": "seconds"
172695
173074
  },
173075
+ {
173076
+ "kind": "field",
173077
+ "name": "showNow",
173078
+ "type": {
173079
+ "text": "boolean"
173080
+ },
173081
+ "default": "false",
173082
+ "description": "Draws a button under the times in the list that chooses the current time,\nmoved to the nearest time on offer. See Time Picker's `show-now`. Its words\nare `now-label`.",
173083
+ "attribute": "show-now"
173084
+ },
172696
173085
  {
172697
173086
  "kind": "field",
172698
173087
  "name": "step",
@@ -175910,6 +176299,15 @@
175910
176299
  "description": "How many times the field holds at once.\n\nAbsent is one. `range` holds a start and an end, `multiple` holds any\nnumber, and both are carried as one comma-separated value, which is what a\nform submits. `TimePicker` carries the longer note on the interaction and\non why a wheel cannot do either.",
175911
176300
  "fieldName": "mode"
175912
176301
  },
176302
+ {
176303
+ "name": "now-label",
176304
+ "type": {
176305
+ "text": "string"
176306
+ },
176307
+ "default": "'Now'",
176308
+ "description": "The words on the list's button that chooses the current time, drawn with\n`show-now`.",
176309
+ "fieldName": "nowLabel"
176310
+ },
175913
176311
  {
175914
176312
  "name": "placeholder",
175915
176313
  "type": {
@@ -175964,6 +176362,15 @@
175964
176362
  "description": "Whether times carry their seconds: the value is `HH:mm:ss`, a typed time\nmay give them, the field writes them, and the list's `step` counts seconds.\nSee Time Picker's `seconds`.",
175965
176363
  "fieldName": "seconds"
175966
176364
  },
176365
+ {
176366
+ "name": "show-now",
176367
+ "type": {
176368
+ "text": "boolean"
176369
+ },
176370
+ "default": "false",
176371
+ "description": "Draws a button under the times in the list that chooses the current time,\nmoved to the nearest time on offer. See Time Picker's `show-now`. Its words\nare `now-label`.",
176372
+ "fieldName": "showNow"
176373
+ },
175967
176374
  {
175968
176375
  "name": "step",
175969
176376
  "type": {
@@ -202148,6 +202555,6 @@
202148
202555
  ],
202149
202556
  "helix": {
202150
202557
  "package": "@fusion.dev/helix-headless",
202151
- "version": "0.183.0"
202558
+ "version": "0.184.0"
202152
202559
  }
202153
202560
  }