@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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-headless",
3
3
  "description": "Headless component tier. Structure, accessibility, state, and form participation. No styling.",
4
- "version": "0.183.0",
4
+ "version": "0.184.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -49,14 +49,14 @@
49
49
  },
50
50
  "bugs": "https://github.com/project-fusion/fusion/issues",
51
51
  "dependencies": {
52
- "@fusion.dev/helix-core": "0.183.0",
53
- "@fusion.dev/helix-icons": "0.183.0",
52
+ "@fusion.dev/helix-core": "0.184.0",
53
+ "@fusion.dev/helix-icons": "0.184.0",
54
54
  "tslib": "^2.8.1",
55
55
  "uqr": "^0.1.3"
56
56
  },
57
57
  "devDependencies": {
58
- "@fusion.dev/helix-cem": "0.183.0",
59
- "@fusion.dev/helix-testing": "0.183.0",
58
+ "@fusion.dev/helix-cem": "0.184.0",
59
+ "@fusion.dev/helix-testing": "0.184.0",
60
60
  "@fusion.dev/scripts": "0.0.0-dev",
61
61
  "@happy-dom/global-registrator": "^20.14.5",
62
62
  "@lit-labs/ssr": "^4.1.0",
package/types/jsx.d.ts CHANGED
@@ -6392,7 +6392,11 @@ whole of it, which Shiki writes, are taken off, so the lines sit level
6392
6392
  with the gutter's numbers and the block keeps one tab stop. The code stays
6393
6393
  in the slot, so the copy button copies it as written and a reader without
6394
6394
  the script still has it. Not called on a server, which has no code to
6395
- read, nor for a diff. */
6395
+ read, nor for a diff.
6396
+
6397
+ Absent, the block draws with the highlighter `registerHighlighter` gave
6398
+ every block, where an entry such as `@fusion.dev/helix-sandbox/code-block`
6399
+ registered one, and plain otherwise. */
6396
6400
  highlight?: (HelixHeadlessCodeBlock["highlight"]) | undefined;
6397
6401
 
6398
6402
  /** A file tab showed its file, whose name `file` now holds. */
@@ -6634,7 +6638,11 @@ whole of it, which Shiki writes, are taken off, so the lines sit level
6634
6638
  with the gutter's numbers and the block keeps one tab stop. The code stays
6635
6639
  in the slot, so the copy button copies it as written and a reader without
6636
6640
  the script still has it. Not called on a server, which has no code to
6637
- read, nor for a diff. */
6641
+ read, nor for a diff.
6642
+
6643
+ Absent, the block draws with the highlighter `registerHighlighter` gave
6644
+ every block, where an entry such as `@fusion.dev/helix-sandbox/code-block`
6645
+ registered one, and plain otherwise. */
6638
6646
  "prop:highlight"?: (HelixHeadlessCodeBlock["highlight"]) | undefined;
6639
6647
  /** A file tab showed its file, whose name `file` now holds. */
6640
6648
  "on:change"?: ((e: HelixHeadlessCodeBlockElementEvent) => void) | undefined;
@@ -21529,7 +21537,11 @@ Cleared as the menu closes and as a submenu opens or closes, so each page
21529
21537
  starts with every row showing. */
21530
21538
  filter?: (HelixHeadlessMenu["filter"]) | undefined;
21531
21539
  /** Whether the menu shows a field above its rows that narrows them as the
21532
- reader types, with focus staying in the field. */
21540
+ reader types, with focus staying in the field, once
21541
+ `@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)
21542
+ is imported. Without that import it does nothing, so a menu that never
21543
+ filters carries none of the filter's code, and a development build says
21544
+ which import is missing. */
21533
21545
  filterable?: (HelixHeadlessMenu["filterable"]) | undefined;
21534
21546
  /** The filter field's name and placeholder. */
21535
21547
  "filter-label"?: (HelixHeadlessMenu["filterLabel"]) | undefined;
@@ -21667,7 +21679,11 @@ Cleared as the menu closes and as a submenu opens or closes, so each page
21667
21679
  starts with every row showing. */
21668
21680
  "prop:filter"?: (HelixHeadlessMenu["filter"]) | undefined;
21669
21681
  /** Whether the menu shows a field above its rows that narrows them as the
21670
- reader types, with focus staying in the field. */
21682
+ reader types, with focus staying in the field, once
21683
+ `@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)
21684
+ is imported. Without that import it does nothing, so a menu that never
21685
+ filters carries none of the filter's code, and a development build says
21686
+ which import is missing. */
21671
21687
  "prop:filterable"?: (HelixHeadlessMenu["filterable"]) | undefined;
21672
21688
  /** The filter field's name and placeholder. */
21673
21689
  "attr:filter-label"?: (HelixHeadlessMenu["filterLabel"]) | undefined;
@@ -31763,6 +31779,12 @@ number, and both are carried as one comma-separated value, which is what a
31763
31779
  form submits. `TimePicker` carries the longer note on the interaction and
31764
31780
  on why a wheel cannot do either. */
31765
31781
  mode?: (HelixHeadlessTimeInput["mode"]) | undefined;
31782
+ /** The words on the list's button that chooses the current time, drawn with
31783
+ `show-now`. */
31784
+ "now-label"?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
31785
+ /** The words on the list's button that chooses the current time, drawn with
31786
+ `show-now`. */
31787
+ nowLabel?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
31766
31788
  /** Placeholder text shown before a time is entered. */
31767
31789
  placeholder?: (HelixHeadlessTimeInput["placeholder"]) | undefined;
31768
31790
  /** The message shown when a range holds more than two times.
@@ -31803,6 +31825,14 @@ removes rather than as "Remove" said once per time. */
31803
31825
  may give them, the field writes them, and the list's `step` counts seconds.
31804
31826
  See Time Picker's `seconds`. */
31805
31827
  seconds?: (HelixHeadlessTimeInput["seconds"]) | undefined;
31828
+ /** Draws a button under the times in the list that chooses the current time,
31829
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
31830
+ are `now-label`. */
31831
+ "show-now"?: (HelixHeadlessTimeInput["showNow"]) | undefined;
31832
+ /** Draws a button under the times in the list that chooses the current time,
31833
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
31834
+ are `now-label`. */
31835
+ showNow?: (HelixHeadlessTimeInput["showNow"]) | undefined;
31806
31836
  /** How far apart the offered times are, in minutes, or in seconds with
31807
31837
  `seconds`. */
31808
31838
  step?: (HelixHeadlessTimeInput["step"]) | undefined;
@@ -32171,6 +32201,12 @@ number, and both are carried as one comma-separated value, which is what a
32171
32201
  form submits. `TimePicker` carries the longer note on the interaction and
32172
32202
  on why a wheel cannot do either. */
32173
32203
  "prop:mode"?: (HelixHeadlessTimeInput["mode"]) | undefined;
32204
+ /** The words on the list's button that chooses the current time, drawn with
32205
+ `show-now`. */
32206
+ "attr:now-label"?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
32207
+ /** The words on the list's button that chooses the current time, drawn with
32208
+ `show-now`. */
32209
+ "prop:nowLabel"?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
32174
32210
  /** Placeholder text shown before a time is entered. */
32175
32211
  "prop:placeholder"?: (HelixHeadlessTimeInput["placeholder"]) | undefined;
32176
32212
  /** The message shown when a range holds more than two times.
@@ -32211,6 +32247,14 @@ removes rather than as "Remove" said once per time. */
32211
32247
  may give them, the field writes them, and the list's `step` counts seconds.
32212
32248
  See Time Picker's `seconds`. */
32213
32249
  "prop:seconds"?: (HelixHeadlessTimeInput["seconds"]) | undefined;
32250
+ /** Draws a button under the times in the list that chooses the current time,
32251
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
32252
+ are `now-label`. */
32253
+ "bool:show-now"?: (HelixHeadlessTimeInput["showNow"]) | undefined;
32254
+ /** Draws a button under the times in the list that chooses the current time,
32255
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
32256
+ are `now-label`. */
32257
+ "prop:showNow"?: (HelixHeadlessTimeInput["showNow"]) | undefined;
32214
32258
  /** How far apart the offered times are, in minutes, or in seconds with
32215
32259
  `seconds`. */
32216
32260
  "prop:step"?: (HelixHeadlessTimeInput["step"]) | undefined;
@@ -42127,6 +42171,20 @@ export type CustomElements = {
42127
42171
  * the slot, so the copy button and the page's own text are the code as
42128
42172
  * written.
42129
42173
  *
42174
+ * **Code Block ships no grammar**, so plain code costs you no parser. To color
42175
+ * code without a highlighter of your own, import one more entry beside the
42176
+ * block's. It colors every block by its `language` (`css`, `html`, `js`,
42177
+ * `jsx`, `sh`, `ts`, or `tsx`) with the Lezer grammars of the sandbox's
42178
+ * editor, in the editor's colors:
42179
+ *
42180
+ * ```js
42181
+ * import '@fusion.dev/helix/code-block'
42182
+ * import '@fusion.dev/helix-sandbox/code-block'
42183
+ * ```
42184
+ *
42185
+ * That entry calls `registerHighlighter`, which you can also call yourself to
42186
+ * give every block one highlighter of your own.
42187
+ *
42130
42188
  * Set `expandable` on a block whose height is capped, such as by
42131
42189
  * `--code-block-max-block-size`, and a button under it shows every line and
42132
42190
  * then fewer again, as a docs site's long example does. The button is drawn
@@ -42299,7 +42357,11 @@ export type CustomElements = {
42299
42357
  * with the gutter's numbers and the block keeps one tab stop. The code stays
42300
42358
  * in the slot, so the copy button copies it as written and a reader without
42301
42359
  * the script still has it. Not called on a server, which has no code to
42302
- * read, nor for a diff. (property only)
42360
+ * read, nor for a diff.
42361
+ *
42362
+ * Absent, the block draws with the highlighter `registerHighlighter` gave
42363
+ * every block, where an entry such as `@fusion.dev/helix-sandbox/code-block`
42364
+ * registered one, and plain otherwise. (property only)
42303
42365
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
42304
42366
  *
42305
42367
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -53664,7 +53726,15 @@ export type CustomElements = {
53664
53726
  * opens it from the keyboard, and the trigger is described by
53665
53727
  * `long-press-label`, which says so.
53666
53728
  *
53667
- * **A filter field.** With `filterable`, the menu opens with focus in a field
53729
+ * **A filter field** is a separate import, `@fusion.dev/helix/menu/filter`, so
53730
+ * a menu that never filters carries none of its code:
53731
+ *
53732
+ * ```js
53733
+ * import '@fusion.dev/helix/menu'
53734
+ * import '@fusion.dev/helix/menu/filter'
53735
+ * ```
53736
+ *
53737
+ * With it imported and `filterable` set, the menu opens with focus in a field
53668
53738
  * above its rows, and typing narrows the rows of the page the keys move in,
53669
53739
  * as React Aria's `Autocomplete` around a `Menu` does. A row is kept where its
53670
53740
  * words hold the filter, in any case, or where `filterMatch` says so. Each
@@ -53697,7 +53767,11 @@ export type CustomElements = {
53697
53767
  * Cleared as the menu closes and as a submenu opens or closes, so each page
53698
53768
  * starts with every row showing.
53699
53769
  * - `filterable`: Whether the menu shows a field above its rows that narrows them as the
53700
- * reader types, with focus staying in the field.
53770
+ * reader types, with focus staying in the field, once
53771
+ * `@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)
53772
+ * is imported. Without that import it does nothing, so a menu that never
53773
+ * filters carries none of the filter's code, and a development build says
53774
+ * which import is missing.
53701
53775
  * - `filter-label`/`filterLabel`: The filter field's name and placeholder.
53702
53776
  * - `label`: Accessible name for the surface.
53703
53777
  *
@@ -62684,6 +62758,8 @@ export type CustomElements = {
62684
62758
  * number, and both are carried as one comma-separated value, which is what a
62685
62759
  * form submits. `TimePicker` carries the longer note on the interaction and
62686
62760
  * on why a wheel cannot do either.
62761
+ * - `now-label`/`nowLabel`: The words on the list's button that chooses the current time, drawn with
62762
+ * `show-now`.
62687
62763
  * - `placeholder`: Placeholder text shown before a time is entered.
62688
62764
  * - `range-length-message`/`rangeLengthMessage`: The message shown when a range holds more than two times.
62689
62765
  *
@@ -62701,6 +62777,9 @@ export type CustomElements = {
62701
62777
  * - `seconds`: Whether times carry their seconds: the value is `HH:mm:ss`, a typed time
62702
62778
  * may give them, the field writes them, and the list's `step` counts seconds.
62703
62779
  * See Time Picker's `seconds`.
62780
+ * - `show-now`/`showNow`: Draws a button under the times in the list that chooses the current time,
62781
+ * moved to the nearest time on offer. See Time Picker's `show-now`. Its words
62782
+ * are `now-label`.
62704
62783
  * - `step`: How far apart the offered times are, in minutes, or in seconds with
62705
62784
  * `seconds`.
62706
62785
  * - `time-style`/`timeStyle`: Whether the field shows the time in the local style or as the value
@@ -71901,6 +71980,20 @@ export type CustomElementsSolidJs = {
71901
71980
  * the slot, so the copy button and the page's own text are the code as
71902
71981
  * written.
71903
71982
  *
71983
+ * **Code Block ships no grammar**, so plain code costs you no parser. To color
71984
+ * code without a highlighter of your own, import one more entry beside the
71985
+ * block's. It colors every block by its `language` (`css`, `html`, `js`,
71986
+ * `jsx`, `sh`, `ts`, or `tsx`) with the Lezer grammars of the sandbox's
71987
+ * editor, in the editor's colors:
71988
+ *
71989
+ * ```js
71990
+ * import '@fusion.dev/helix/code-block'
71991
+ * import '@fusion.dev/helix-sandbox/code-block'
71992
+ * ```
71993
+ *
71994
+ * That entry calls `registerHighlighter`, which you can also call yourself to
71995
+ * give every block one highlighter of your own.
71996
+ *
71904
71997
  * Set `expandable` on a block whose height is capped, such as by
71905
71998
  * `--code-block-max-block-size`, and a button under it shows every line and
71906
71999
  * then fewer again, as a docs site's long example does. The button is drawn
@@ -72073,7 +72166,11 @@ export type CustomElementsSolidJs = {
72073
72166
  * with the gutter's numbers and the block keeps one tab stop. The code stays
72074
72167
  * in the slot, so the copy button copies it as written and a reader without
72075
72168
  * the script still has it. Not called on a server, which has no code to
72076
- * read, nor for a diff. (property only)
72169
+ * read, nor for a diff.
72170
+ *
72171
+ * Absent, the block draws with the highlighter `registerHighlighter` gave
72172
+ * every block, where an entry such as `@fusion.dev/helix-sandbox/code-block`
72173
+ * registered one, and plain otherwise. (property only)
72077
72174
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
72078
72175
  *
72079
72176
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -83558,7 +83655,15 @@ export type CustomElementsSolidJs = {
83558
83655
  * opens it from the keyboard, and the trigger is described by
83559
83656
  * `long-press-label`, which says so.
83560
83657
  *
83561
- * **A filter field.** With `filterable`, the menu opens with focus in a field
83658
+ * **A filter field** is a separate import, `@fusion.dev/helix/menu/filter`, so
83659
+ * a menu that never filters carries none of its code:
83660
+ *
83661
+ * ```js
83662
+ * import '@fusion.dev/helix/menu'
83663
+ * import '@fusion.dev/helix/menu/filter'
83664
+ * ```
83665
+ *
83666
+ * With it imported and `filterable` set, the menu opens with focus in a field
83562
83667
  * above its rows, and typing narrows the rows of the page the keys move in,
83563
83668
  * as React Aria's `Autocomplete` around a `Menu` does. A row is kept where its
83564
83669
  * words hold the filter, in any case, or where `filterMatch` says so. Each
@@ -83591,7 +83696,11 @@ export type CustomElementsSolidJs = {
83591
83696
  * Cleared as the menu closes and as a submenu opens or closes, so each page
83592
83697
  * starts with every row showing.
83593
83698
  * - `filterable`: Whether the menu shows a field above its rows that narrows them as the
83594
- * reader types, with focus staying in the field.
83699
+ * reader types, with focus staying in the field, once
83700
+ * `@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)
83701
+ * is imported. Without that import it does nothing, so a menu that never
83702
+ * filters carries none of the filter's code, and a development build says
83703
+ * which import is missing.
83595
83704
  * - `filter-label`/`filterLabel`: The filter field's name and placeholder.
83596
83705
  * - `label`: Accessible name for the surface.
83597
83706
  *
@@ -92692,6 +92801,8 @@ export type CustomElementsSolidJs = {
92692
92801
  * number, and both are carried as one comma-separated value, which is what a
92693
92802
  * form submits. `TimePicker` carries the longer note on the interaction and
92694
92803
  * on why a wheel cannot do either.
92804
+ * - `now-label`/`nowLabel`: The words on the list's button that chooses the current time, drawn with
92805
+ * `show-now`.
92695
92806
  * - `placeholder`: Placeholder text shown before a time is entered.
92696
92807
  * - `range-length-message`/`rangeLengthMessage`: The message shown when a range holds more than two times.
92697
92808
  *
@@ -92709,6 +92820,9 @@ export type CustomElementsSolidJs = {
92709
92820
  * - `seconds`: Whether times carry their seconds: the value is `HH:mm:ss`, a typed time
92710
92821
  * may give them, the field writes them, and the list's `step` counts seconds.
92711
92822
  * See Time Picker's `seconds`.
92823
+ * - `show-now`/`showNow`: Draws a button under the times in the list that chooses the current time,
92824
+ * moved to the nearest time on offer. See Time Picker's `show-now`. Its words
92825
+ * are `now-label`.
92712
92826
  * - `step`: How far apart the offered times are, in minutes, or in seconds with
92713
92827
  * `seconds`.
92714
92828
  * - `time-style`/`timeStyle`: Whether the field shows the time in the local style or as the value
package/types/vue.d.ts CHANGED
@@ -40,6 +40,7 @@ import type {
40
40
  HelixHeadlessChat,
41
41
  HelixHeadlessCheckboxGroup,
42
42
  HelixHeadlessCheckbox,
43
+ registerHighlighter,
43
44
  HelixHeadlessCodeBlock,
44
45
  HelixHeadlessCode,
45
46
  HelixHeadlessColorInput,
@@ -3432,7 +3433,11 @@ whole of it, which Shiki writes, are taken off, so the lines sit level
3432
3433
  with the gutter's numbers and the block keeps one tab stop. The code stays
3433
3434
  in the slot, so the copy button copies it as written and a reader without
3434
3435
  the script still has it. Not called on a server, which has no code to
3435
- read, nor for a diff. */
3436
+ read, nor for a diff.
3437
+
3438
+ Absent, the block draws with the highlighter `registerHighlighter` gave
3439
+ every block, where an entry such as `@fusion.dev/helix-sandbox/code-block`
3440
+ registered one, and plain otherwise. */
3436
3441
  highlight?: (HelixHeadlessCodeBlock["highlight"]) | undefined;
3437
3442
  };
3438
3443
 
@@ -11042,7 +11047,11 @@ Cleared as the menu closes and as a submenu opens or closes, so each page
11042
11047
  starts with every row showing. */
11043
11048
  filter?: (HelixHeadlessMenu["filter"]) | undefined;
11044
11049
  /** Whether the menu shows a field above its rows that narrows them as the
11045
- reader types, with focus staying in the field. */
11050
+ reader types, with focus staying in the field, once
11051
+ `@fusion.dev/helix/menu/filter` (or `@fusion.dev/helix-headless/menu/filter`)
11052
+ is imported. Without that import it does nothing, so a menu that never
11053
+ filters carries none of the filter's code, and a development build says
11054
+ which import is missing. */
11046
11055
  filterable?: (HelixHeadlessMenu["filterable"]) | undefined;
11047
11056
  /** The filter field's name and placeholder. */
11048
11057
  "filter-label"?: (HelixHeadlessMenu["filterLabel"]) | undefined;
@@ -16294,6 +16303,12 @@ number, and both are carried as one comma-separated value, which is what a
16294
16303
  form submits. `TimePicker` carries the longer note on the interaction and
16295
16304
  on why a wheel cannot do either. */
16296
16305
  mode?: (HelixHeadlessTimeInput["mode"]) | undefined;
16306
+ /** The words on the list's button that chooses the current time, drawn with
16307
+ `show-now`. */
16308
+ "now-label"?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
16309
+ /** The words on the list's button that chooses the current time, drawn with
16310
+ `show-now`. */
16311
+ nowLabel?: (HelixHeadlessTimeInput["nowLabel"]) | undefined;
16297
16312
  /** Placeholder text shown before a time is entered. */
16298
16313
  placeholder?: (HelixHeadlessTimeInput["placeholder"]) | undefined;
16299
16314
  /** The message shown when a range holds more than two times.
@@ -16334,6 +16349,14 @@ removes rather than as "Remove" said once per time. */
16334
16349
  may give them, the field writes them, and the list's `step` counts seconds.
16335
16350
  See Time Picker's `seconds`. */
16336
16351
  seconds?: (HelixHeadlessTimeInput["seconds"]) | undefined;
16352
+ /** Draws a button under the times in the list that chooses the current time,
16353
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
16354
+ are `now-label`. */
16355
+ "show-now"?: (HelixHeadlessTimeInput["showNow"]) | undefined;
16356
+ /** Draws a button under the times in the list that chooses the current time,
16357
+ moved to the nearest time on offer. See Time Picker's `show-now`. Its words
16358
+ are `now-label`. */
16359
+ showNow?: (HelixHeadlessTimeInput["showNow"]) | undefined;
16337
16360
  /** How far apart the offered times are, in minutes, or in seconds with
16338
16361
  `seconds`. */
16339
16362
  step?: (HelixHeadlessTimeInput["step"]) | undefined;
@@ -19444,7 +19467,7 @@ export interface WcToolkitVueGlobalComponents {
19444
19467
  HelixHeadlessCheckboxVueProps,
19445
19468
  HelixHeadlessCheckboxVueEvents
19446
19469
  >;
19447
- /** Renders a '<pre><code>' pair: 'pre' keeps the whitespace, and 'code' marks it as code. Long lines scroll inside the block and do not wrap, because a line break can be significant in code. A copy button is on by default. Set 'no-copy' to remove it. The button copies the slotted text, so there is no second copy of the code to keep in sync. For a fragment of code inside a sentence, use 'Code'. Set 'line-numbers' to number the lines in a gutter beside the code, hidden from the accessibility tree and left out of a copy. Set 'mark-lines' to mark lines a reader should look at, such as '2, 4-6': the block draws a band behind each run, placed where the lines are laid out, so it follows a highlighter's markup and lines that wrap. 'added-lines' and 'removed-lines' mark lines the same way as inserted and deleted, as Expressive Code's 'ins' and 'del' do, in code that is not a diff. The bands are drawn and hidden from screen readers, so say in the text around the block what a marked line means. Set 'wrap' to wrap long lines rather than scroll them; a gutter then numbers each line where it starts. Set 'wrappable' for a button in the header that turns 'wrap' on and off, pressed while the lines wrap. The header holds the name, the 'actions' slot, and the copy button. Slot a control into 'actions', such as a button that sets 'wrap' or one that opens the code in an editor, and the block draws a header for it even with no name. 'copy-icon' and 'copied-icon' replace the copy button's two icons. Set 'highlight' to a function that turns the code into highlighted markup, such as one wrapping Shiki or Prism, and the block draws what it returns; it is handed the block's 'language', so one function serves every block. The code stays in the slot, so the copy button and the page's own text are the code as written. Set 'expandable' on a block whose height is capped, such as by '--code-block-max-block-size', and a button under it shows every line and then fewer again, as a docs site's long example does. The button is drawn only while the cap hides something, says whether the block is expanded with 'aria-expanded', names the block it opens with 'aria-controls', and the block carries ':state(expanded)' while it is. Set 'diff' to show a change. Put a unified diff, the output of 'git diff' or 'diff -u', in the same slot, and the block draws the lines it added and removed. The block never computes a diff itself. Line numbers come from the hunk headers and are hidden from the accessibility tree. Changed lines are '<ins>' and '<del>' with the '+' and '-' kept as text, so the change does not depend on color. Where a removed line is paired with the added line that replaced it, the words each does not share with the other are the 'changed' part, so the eye goes to what changed within the line. Each file in the patch is its own block under its own name, and its copy button copies the new version of the file. 'variant="split"' shows the old version beside the new, each removal opposite its replacement. 'context-lines' folds each long run of unchanged lines, keeping that many beside each change, behind a button that shows them and hides them again, as a code host draws a diff written with more context than a reader needs. **A block that scrolls is a tab stop.** While its lines run past its width or its cap, the scroller is a region named for the block, such as "Code, app.ts", that Tab reaches, so a keyboard scrolls it with the arrow keys in every browser. Chromium and Firefox make a scrolling box focusable on their own, and Safari does not. A block that fits is no stop at all. **The code the block draws is marked untranslated**, 'translate="no"' on its '<pre>', so a page translator leaves highlighted lines and a diff as written. Code in the slot takes its translation mode from the element, which writes nothing onto itself, so set 'translate="no"' on the element to keep a translator off plain code too. On the server, the slot renders as ordinary code, so a diff first appears as the patch text in a '<pre>'. The client makes the same first render, which keeps hydration clean, and draws the diff once it can read the content. Diff mode is experimental. The rest of the family is stable. **Several blocks are files**, one shown at a time under a row of tabs, as Sandbox shows its source panes. Put Code Blocks in the default slot of a Code Block, and each is a file named on its tab by its 'label' or, without one, its 'language'. 'file' holds the name of the file shown. The tabs are a tab list: the arrow keys move to a tab and show its file, the two swapping on a right-to-left page, and Home and End go to the first and the last. Choosing one sends 'helix-before-change' with the file's name, which you can cancel, and 'change' once 'file' holds it. The files not shown carry 'hidden', and the one shown draws no name of its own, its tab naming it. One block draws no tabs. A server cannot see the blocks inside, so the client draws the tabs once it upgrades. */
19470
+ /** Renders a '<pre><code>' pair: 'pre' keeps the whitespace, and 'code' marks it as code. Long lines scroll inside the block and do not wrap, because a line break can be significant in code. A copy button is on by default. Set 'no-copy' to remove it. The button copies the slotted text, so there is no second copy of the code to keep in sync. For a fragment of code inside a sentence, use 'Code'. Set 'line-numbers' to number the lines in a gutter beside the code, hidden from the accessibility tree and left out of a copy. Set 'mark-lines' to mark lines a reader should look at, such as '2, 4-6': the block draws a band behind each run, placed where the lines are laid out, so it follows a highlighter's markup and lines that wrap. 'added-lines' and 'removed-lines' mark lines the same way as inserted and deleted, as Expressive Code's 'ins' and 'del' do, in code that is not a diff. The bands are drawn and hidden from screen readers, so say in the text around the block what a marked line means. Set 'wrap' to wrap long lines rather than scroll them; a gutter then numbers each line where it starts. Set 'wrappable' for a button in the header that turns 'wrap' on and off, pressed while the lines wrap. The header holds the name, the 'actions' slot, and the copy button. Slot a control into 'actions', such as a button that sets 'wrap' or one that opens the code in an editor, and the block draws a header for it even with no name. 'copy-icon' and 'copied-icon' replace the copy button's two icons. Set 'highlight' to a function that turns the code into highlighted markup, such as one wrapping Shiki or Prism, and the block draws what it returns; it is handed the block's 'language', so one function serves every block. The code stays in the slot, so the copy button and the page's own text are the code as written. **Code Block ships no grammar**, so plain code costs you no parser. To color code without a highlighter of your own, import one more entry beside the block's. It colors every block by its 'language' ('css', 'html', 'js', 'jsx', 'sh', 'ts', or 'tsx') with the Lezer grammars of the sandbox's editor, in the editor's colors: '''js import '@fusion.dev/helix/code-block' import '@fusion.dev/helix-sandbox/code-block' ''' That entry calls 'registerHighlighter', which you can also call yourself to give every block one highlighter of your own. Set 'expandable' on a block whose height is capped, such as by '--code-block-max-block-size', and a button under it shows every line and then fewer again, as a docs site's long example does. The button is drawn only while the cap hides something, says whether the block is expanded with 'aria-expanded', names the block it opens with 'aria-controls', and the block carries ':state(expanded)' while it is. Set 'diff' to show a change. Put a unified diff, the output of 'git diff' or 'diff -u', in the same slot, and the block draws the lines it added and removed. The block never computes a diff itself. Line numbers come from the hunk headers and are hidden from the accessibility tree. Changed lines are '<ins>' and '<del>' with the '+' and '-' kept as text, so the change does not depend on color. Where a removed line is paired with the added line that replaced it, the words each does not share with the other are the 'changed' part, so the eye goes to what changed within the line. Each file in the patch is its own block under its own name, and its copy button copies the new version of the file. 'variant="split"' shows the old version beside the new, each removal opposite its replacement. 'context-lines' folds each long run of unchanged lines, keeping that many beside each change, behind a button that shows them and hides them again, as a code host draws a diff written with more context than a reader needs. **A block that scrolls is a tab stop.** While its lines run past its width or its cap, the scroller is a region named for the block, such as "Code, app.ts", that Tab reaches, so a keyboard scrolls it with the arrow keys in every browser. Chromium and Firefox make a scrolling box focusable on their own, and Safari does not. A block that fits is no stop at all. **The code the block draws is marked untranslated**, 'translate="no"' on its '<pre>', so a page translator leaves highlighted lines and a diff as written. Code in the slot takes its translation mode from the element, which writes nothing onto itself, so set 'translate="no"' on the element to keep a translator off plain code too. On the server, the slot renders as ordinary code, so a diff first appears as the patch text in a '<pre>'. The client makes the same first render, which keeps hydration clean, and draws the diff once it can read the content. Diff mode is experimental. The rest of the family is stable. **Several blocks are files**, one shown at a time under a row of tabs, as Sandbox shows its source panes. Put Code Blocks in the default slot of a Code Block, and each is a file named on its tab by its 'label' or, without one, its 'language'. 'file' holds the name of the file shown. The tabs are a tab list: the arrow keys move to a tab and show its file, the two swapping on a right-to-left page, and Home and End go to the first and the last. Choosing one sends 'helix-before-change' with the file's name, which you can cancel, and 'change' once 'file' holds it. The files not shown carry 'hidden', and the one shown draws no name of its own, its tab naming it. One block draws no tabs. A server cannot see the blocks inside, so the client draws the tabs once it upgrades. */
19448
19471
  "helix-headless-code-block": DefineCustomElement<
19449
19472
  HelixHeadlessCodeBlock,
19450
19473
  HelixHeadlessCodeBlockVueProps,
@@ -19768,7 +19791,7 @@ export interface WcToolkitVueGlobalComponents {
19768
19791
  HelixHeadlessMenuItemVueProps,
19769
19792
  HelixHeadlessMenuItemVueEvents
19770
19793
  >;
19771
- /** The trigger is slotted and stays your own element, as with the tooltip. The menu renders its surface in the top layer with the popover API, so an ancestor with 'overflow: hidden' does not clip it and it needs no 'z-index'. Slot a 'helix-button' or 'helix-icon-button' as the trigger, and the menu tells it that it opens a menu and whether the menu is open, inside its own shadow root. On a plain element, such as a '<button>', the menu writes 'aria-haspopup="menu"' and 'aria-expanded', from a frame after its own first render, so a server's markup is never changed while a framework hydrates it. It never writes 'aria-expanded' where you wrote it yourself. Submenus drill down by default. A submenu replaces the panel's content, and a back row returns to the previous page. One panel stays inside a narrow window, and works on touch screens, which have no hover. Focus follows a mouse resting on a row in either mode, and a drilled page is a 'menu' named by the row that opened it. **'submenus="flyout"' opens each submenu in a panel of its own beside its row**, as React Aria's 'SubmenuTrigger' and Radix's 'Sub' do. Resting the pointer on the row opens it, and a pointer crossing toward the open panel over the rows between keeps it open, as Radix's grace area does. Right Arrow opens a row's submenu on its first row, and Left Arrow or Escape closes it and returns focus to the row, the two arrows swapping on a right-to-left page. The row says 'aria-expanded', and the panel is a 'menu' named by the row. The root holds which page is open, because only one page shows at a time. It sets this on items as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. Group rows under a heading with 'Menu.Section', which is a 'group' named by its heading. Between runs of rows, a '<helix-divider>' is a separator a screen reader announces. Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first row, and Up Arrow on its last. In the menu, Up and Down Arrow move between rows, Home and End go to the first and the last, a typed letter moves to the next row whose name starts with it, Enter and Space choose (Space on a choice row changes it and leaves the menu open), Right Arrow opens a row's submenu and Left Arrow goes back, the two swapping on a right-to-left page. Left Arrow on the top page does nothing. Escape closes the menu and returns focus to the trigger. Tab closes it and moves on. While it is open, the surface carries the trigger's width as '--floating-anchor-inline-size' and the room left below it as '--floating-available-block-size', as Radix's dropdown menu publishes its trigger's width, for a menu as wide as its trigger: 'helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }'. **The choices in one place.** 'checkedValues' holds the values of the rows that are checked, anywhere in the menu, and setting it checks exactly those rows, as React Aria's 'selectedKeys' does. 'change' is sent on the menu when a reader's choice changes it. With 'context', the trigger is an area and the menu is its context menu: a right-click, a long press, Shift+F10 or the menu key over the area opens it at the pointer, or at the area's corner from the keyboard, as Radix's context menu does. A press on the area does not open it, and closing it returns focus to where it was. A touch or a pen held still on the area opens it too, on every browser, since iOS sends no 'contextmenu' for one. **A trigger with its own action.** With 'open-on="long-press"', a press on the trigger is the trigger's own, and a press held for half a second opens the menu, as React Aria's 'trigger="longPress"' does. Alt+Down or Alt+Up opens it from the keyboard, and the trigger is described by 'long-press-label', which says so. **A filter field.** With 'filterable', the menu opens with focus in a field above its rows, and typing narrows the rows of the page the keys move in, as React Aria's 'Autocomplete' around a 'Menu' does. A row is kept where its words hold the filter, in any case, or where 'filterMatch' says so. Each page starts unfiltered, and the filter is cleared as the menu closes. Where typing keeps no row, the menu shows 'no-results-text'. Focus stays in the field: Up and Down Arrow move the highlight through the rows that are left, Enter chooses the highlighted row, Right Arrow opens its submenu, Left Arrow on a submenu goes back, and Escape clears the filter and then closes the menu. A screen reader hears how many rows the filter keeps ('results-label'). Home, End and the other keys move the caret and type. The field names the highlighted row with 'aria-activedescendant', and the rows are a 'menu' after the field. Cancel 'helix-filter' to keep every row showing and narrow the rows yourself, such as by replacing them with rows from a server. */
19794
+ /** The trigger is slotted and stays your own element, as with the tooltip. The menu renders its surface in the top layer with the popover API, so an ancestor with 'overflow: hidden' does not clip it and it needs no 'z-index'. Slot a 'helix-button' or 'helix-icon-button' as the trigger, and the menu tells it that it opens a menu and whether the menu is open, inside its own shadow root. On a plain element, such as a '<button>', the menu writes 'aria-haspopup="menu"' and 'aria-expanded', from a frame after its own first render, so a server's markup is never changed while a framework hydrates it. It never writes 'aria-expanded' where you wrote it yourself. Submenus drill down by default. A submenu replaces the panel's content, and a back row returns to the previous page. One panel stays inside a narrow window, and works on touch screens, which have no hover. Focus follows a mouse resting on a row in either mode, and a drilled page is a 'menu' named by the row that opened it. **'submenus="flyout"' opens each submenu in a panel of its own beside its row**, as React Aria's 'SubmenuTrigger' and Radix's 'Sub' do. Resting the pointer on the row opens it, and a pointer crossing toward the open panel over the rows between keeps it open, as Radix's grace area does. Right Arrow opens a row's submenu on its first row, and Left Arrow or Escape closes it and returns focus to the row, the two arrows swapping on a right-to-left page. The row says 'aria-expanded', and the panel is a 'menu' named by the row. The root holds which page is open, because only one page shows at a time. It sets this on items as a property, never as an attribute. An attribute written onto your element after it upgrades causes a hydration mismatch. Group rows under a heading with 'Menu.Section', which is a 'group' named by its heading. Between runs of rows, a '<helix-divider>' is a separator a screen reader announces. Keys: Enter, Space or Down Arrow on the trigger opens the menu on its first row, and Up Arrow on its last. In the menu, Up and Down Arrow move between rows, Home and End go to the first and the last, a typed letter moves to the next row whose name starts with it, Enter and Space choose (Space on a choice row changes it and leaves the menu open), Right Arrow opens a row's submenu and Left Arrow goes back, the two swapping on a right-to-left page. Left Arrow on the top page does nothing. Escape closes the menu and returns focus to the trigger. Tab closes it and moves on. While it is open, the surface carries the trigger's width as '--floating-anchor-inline-size' and the room left below it as '--floating-available-block-size', as Radix's dropdown menu publishes its trigger's width, for a menu as wide as its trigger: 'helix-menu::part(surface) { min-inline-size: var(--floating-anchor-inline-size) }'. **The choices in one place.** 'checkedValues' holds the values of the rows that are checked, anywhere in the menu, and setting it checks exactly those rows, as React Aria's 'selectedKeys' does. 'change' is sent on the menu when a reader's choice changes it. With 'context', the trigger is an area and the menu is its context menu: a right-click, a long press, Shift+F10 or the menu key over the area opens it at the pointer, or at the area's corner from the keyboard, as Radix's context menu does. A press on the area does not open it, and closing it returns focus to where it was. A touch or a pen held still on the area opens it too, on every browser, since iOS sends no 'contextmenu' for one. **A trigger with its own action.** With 'open-on="long-press"', a press on the trigger is the trigger's own, and a press held for half a second opens the menu, as React Aria's 'trigger="longPress"' does. Alt+Down or Alt+Up opens it from the keyboard, and the trigger is described by 'long-press-label', which says so. **A filter field** is a separate import, '@fusion.dev/helix/menu/filter', so a menu that never filters carries none of its code: '''js import '@fusion.dev/helix/menu' import '@fusion.dev/helix/menu/filter' ''' With it imported and 'filterable' set, the menu opens with focus in a field above its rows, and typing narrows the rows of the page the keys move in, as React Aria's 'Autocomplete' around a 'Menu' does. A row is kept where its words hold the filter, in any case, or where 'filterMatch' says so. Each page starts unfiltered, and the filter is cleared as the menu closes. Where typing keeps no row, the menu shows 'no-results-text'. Focus stays in the field: Up and Down Arrow move the highlight through the rows that are left, Enter chooses the highlighted row, Right Arrow opens its submenu, Left Arrow on a submenu goes back, and Escape clears the filter and then closes the menu. A screen reader hears how many rows the filter keeps ('results-label'). Home, End and the other keys move the caret and type. The field names the highlighted row with 'aria-activedescendant', and the rows are a 'menu' after the field. Cancel 'helix-filter' to keep every row showing and narrow the rows yourself, such as by replacing them with rows from a server. */
19772
19795
  "helix-headless-menu": DefineCustomElement<
19773
19796
  HelixHeadlessMenu,
19774
19797
  HelixHeadlessMenuVueProps,
package/types/words.d.ts CHANGED
@@ -3284,6 +3284,13 @@ declare module '@fusion.dev/helix-core' {
3284
3284
  * English: `{kind, select, date {Enter a whole date.} other {Enter a whole time.}}`
3285
3285
  */
3286
3286
  incompleteMessage: Message
3287
+ /**
3288
+ * The words on the list's button that chooses the current time, drawn with
3289
+ * `show-now`.
3290
+ *
3291
+ * English: `Now`
3292
+ */
3293
+ nowLabel: Message
3287
3294
  /**
3288
3295
  * Placeholder text shown before a time is entered.
3289
3296
  *