@fusion.dev/helix-headless 0.153.0 → 0.154.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/types/vue.d.ts CHANGED
@@ -2163,10 +2163,6 @@ twice what this says once.
2163
2163
  Reflected and undefaulted, so a card that has not asked reads as a card
2164
2164
  with no attribute on it and the stylesheet only describes the departure. */
2165
2165
  mediaPlacement?: (HelixHeadlessCard["mediaPlacement"]) | undefined;
2166
- /** */
2167
- "aria-labelledby"?: unknown;
2168
- /** */
2169
- "aria-label"?: unknown;
2170
2166
  };
2171
2167
 
2172
2168
  export type HelixHeadlessCardVueEvents = {};
@@ -2983,6 +2979,22 @@ export type HelixHeadlessCheckboxVueEvents = {
2983
2979
  };
2984
2980
 
2985
2981
  export type HelixHeadlessCodeBlockVueProps = {
2982
+ /** The name of a block that scrolls, which is a tab stop while it does.
2983
+
2984
+ Where the block has a name, the scroller says it too, such as "Code,
2985
+ app.ts", as `code-name-label` puts it. */
2986
+ "code-label"?: (HelixHeadlessCodeBlock["codeLabel"]) | undefined;
2987
+ /** The name of a block that scrolls, which is a tab stop while it does.
2988
+
2989
+ Where the block has a name, the scroller says it too, such as "Code,
2990
+ app.ts", as `code-name-label` puts it. */
2991
+ codeLabel?: (HelixHeadlessCodeBlock["codeLabel"]) | undefined;
2992
+ /** The name of a block that scrolls, where the block has a name. `{code}` is
2993
+ `code-label` and `{name}` the block's name. */
2994
+ "code-name-label"?: (HelixHeadlessCodeBlock["codeNameLabel"]) | undefined;
2995
+ /** The name of a block that scrolls, where the block has a name. `{code}` is
2996
+ `code-label` and `{name}` the block's name. */
2997
+ codeNameLabel?: (HelixHeadlessCodeBlock["codeNameLabel"]) | undefined;
2986
2998
  /** The expand button's words while the block shows every line. */
2987
2999
  "collapse-label"?: (HelixHeadlessCodeBlock["collapseLabel"]) | undefined;
2988
3000
  /** The expand button's words while the block shows every line. */
@@ -7538,6 +7550,11 @@ the value instead.
7538
7550
  A name written `prefix:name` asks the library registered under that
7539
7551
  prefix. */
7540
7552
  name?: (HelixHeadlessIcon["name"]) | undefined;
7553
+ /** The URL of an SVG file to draw, fetched once a page and drawn in
7554
+ `currentColor` where the file does not color its shapes.
7555
+
7556
+ Wins over `name`; `icon` wins over both. Absent draws `name`. */
7557
+ src?: (HelixHeadlessIcon["src"]) | undefined;
7541
7558
  /** The icon to draw, as an object you import.
7542
7559
 
7543
7560
  **The scalable door, and the one this library uses internally.** An icon is
@@ -7554,9 +7571,9 @@ for. Set both and this wins, the value being the more specific statement. */
7554
7571
  };
7555
7572
 
7556
7573
  export type HelixHeadlessIconVueEvents = {
7557
- /** `name` matches no registered icon and no library answers it, so nothing is drawn. */
7574
+ /** `name` matches no registered icon and no library answers it, or `src` is no SVG, so nothing is drawn. */
7558
7575
  error: HelixHeadlessIconElementEvent;
7559
- /** A glyph a library gave later for `name` is drawn. */
7576
+ /** A glyph a library gave later for `name`, or the file at `src`, is drawn. */
7560
7577
  load: HelixHeadlessIconElementEvent;
7561
7578
  };
7562
7579
 
@@ -11784,6 +11801,20 @@ export type HelixHeadlessQrCodeVueEvents = {
11784
11801
  export type HelixHeadlessQuoteVueProps = {
11785
11802
  /** URL identifying where the quotation came from. */
11786
11803
  cite?: (HelixHeadlessQuote["cite"]) | undefined;
11804
+ /** Whether to leave the quotation marks off, for a quotation set where the
11805
+ page draws its own.
11806
+
11807
+ Negative, because the marks are on by default and a boolean attribute is
11808
+ true whenever it is present. Reflected, because a stylesheet takes the
11809
+ marks off on it. */
11810
+ "no-marks"?: (HelixHeadlessQuote["noMarks"]) | undefined;
11811
+ /** Whether to leave the quotation marks off, for a quotation set where the
11812
+ page draws its own.
11813
+
11814
+ Negative, because the marks are on by default and a boolean attribute is
11815
+ true whenever it is present. Reflected, because a stylesheet takes the
11816
+ marks off on it. */
11817
+ noMarks?: (HelixHeadlessQuote["noMarks"]) | undefined;
11787
11818
  };
11788
11819
 
11789
11820
  export type HelixHeadlessQuoteVueEvents = {};
@@ -13245,7 +13276,10 @@ export type HelixHeadlessSplitterVueEvents = {
13245
13276
  };
13246
13277
 
13247
13278
  export type HelixHeadlessStatGroupVueProps = {
13248
- /** Accessible name for the group. */
13279
+ /** Accessible name for the group, which makes it a group.
13280
+
13281
+ Absent leaves the stats with no group around them, unless `aria-label` or
13282
+ `aria-labelledby` names it. */
13249
13283
  label?: (HelixHeadlessStatGroup["label"]) | undefined;
13250
13284
  };
13251
13285
 
@@ -13278,6 +13312,29 @@ reports a hydration mismatch. The absent attribute is the column, which the
13278
13312
  stylesheet reads as the base case, and the server spec asserts the host
13279
13313
  carries nothing nobody wrote. */
13280
13314
  direction?: (HelixHeadlessStat["direction"]) | undefined;
13315
+ /** `Intl.NumberFormat` options `value` is written with, such as
13316
+ `{"notation":"compact"}` for `1.2M` or `{"style":"percent"}` for `98%`,
13317
+ written as JSON in the attribute.
13318
+
13319
+ Absent writes the number as the locale writes any number. */
13320
+ "format-options"?: (HelixHeadlessStat["formatOptions"]) | undefined;
13321
+ /** `Intl.NumberFormat` options `value` is written with, such as
13322
+ `{"notation":"compact"}` for `1.2M` or `{"style":"percent"}` for `98%`,
13323
+ written as JSON in the attribute.
13324
+
13325
+ Absent writes the number as the locale writes any number. */
13326
+ formatOptions?: (HelixHeadlessStat["formatOptions"]) | undefined;
13327
+ /** The locale `value` is written in, such as `de` for `1.234.567`.
13328
+
13329
+ Absent reads the nearest `lang`, then the runtime's own. Set it on a page
13330
+ rendered on a server, so the server and the browser write the figure
13331
+ alike. */
13332
+ locale?: (HelixHeadlessStat["locale"]) | undefined;
13333
+ /** The figure as a number, written with `format-options` in `locale` in
13334
+ place of a slotted value.
13335
+
13336
+ Absent leaves the figure to the slot. */
13337
+ value?: (HelixHeadlessStat["value"]) | undefined;
13281
13338
  };
13282
13339
 
13283
13340
  export type HelixHeadlessStatVueEvents = {};
@@ -17080,7 +17137,7 @@ export interface WcToolkitVueGlobalComponents {
17080
17137
  HelixHeadlessAvatarVueProps,
17081
17138
  HelixHeadlessAvatarVueEvents
17082
17139
  >;
17083
- /** Badge wraps the element it decorates and pins an indicator to its corner, so the wrapped element keeps its place in the layout. What the indicator shows depends on 'value': - A 'value' of zero shows no indicator. - No 'value' shows a dot. - Any other value shows the value. Above 'max', the indicator shows '{max}+', so its width stays the same as the count grows. 'format-options' writes a count with 'Intl.NumberFormat', in 'locale': 'format-options='{"notation":"compact"}'' shows 1,200 as '1.2K'. Absent, the count is shown as it was given. A count is announced from its own text, and 'label' replaces that with a fuller name, such as '4 unread'. A dot needs a 'label'. Without one, the dot is a colored circle that screen readers do not announce. **A badge wrapped around a control describes it.** The control is the first element in the badge that takes focus, and its description is the badge's words, so focusing '<helix-badge value="8" label="{count} unread"><button>Inbox </button></helix-badge>' announces "Inbox, button, 8 unread", current as the count changes. A control that already has a description keeps its own. The count is also a status of its own, read when it changes. **Put the badge inside the control to have its count read with the control's name**, as Web Awesome and Shoelace do: '<button>Inbox <helix-badge value="8" label="8 unread"></helix-badge></button>' is the button "Inbox 8 unread", and stays current as the count changes. The styled tier's 'placement="inline"' draws the mark in the line for that case. */
17140
+ /** Badge wraps the element it decorates and pins an indicator to its corner, so the wrapped element keeps its place in the layout. What the indicator shows depends on 'value': - A 'value' of zero shows no indicator. - No 'value' shows a dot. - Any other value shows the value. Above 'max', the indicator shows '{max}+', so its width stays the same as the count grows. 'format-options' writes a count with 'Intl.NumberFormat', in 'locale': 'format-options='{"notation":"compact"}'' shows 1,200 as '1.2K'. Absent, the count is shown as it was given. A count is announced from its own text, and 'label' replaces that with a fuller name, such as '4 unread'. A dot needs a 'label'. Without one, the dot is a colored circle that screen readers do not announce. **A badge wrapped around a control describes it.** The control is the first element in the badge that takes focus, and its description is the badge's words, so focusing '<helix-badge value="8" label="{count} unread"><button>Inbox </button></helix-badge>' announces "Inbox, button, 8 unread", current as the count changes. A control that already has a description keeps its own. The count is also a status of its own, read when it changes. **Put the badge inside the control to have its count read with the control's name**, as Web Awesome and Shoelace do: '<button>Inbox <helix-badge value="8" label="8 unread"></helix-badge></button>' is the button "Inbox 8 unread", and stays current as the count changes. The styled tier's 'placement="inline"' draws the mark in the line for that case. **An icon goes inside the mark** through the 'icon' slot, before the count, as Web Awesome's badge takes one at its start. With no 'value' the icon is the whole mark, such as a check on an avatar, drawn where the dot would be. The icon is hidden from screen readers: the count and 'label' are what the mark says. */
17084
17141
  "helix-headless-badge": DefineCustomElement<
17085
17142
  HelixHeadlessBadge,
17086
17143
  HelixHeadlessBadgeVueProps,
@@ -17146,7 +17203,7 @@ export interface WcToolkitVueGlobalComponents {
17146
17203
  HelixHeadlessCanvasVueProps,
17147
17204
  HelixHeadlessCanvasVueEvents
17148
17205
  >;
17149
- /** The header, body, and footer regions are slots, because they have no state, behavior, or API of their own. You bring your own markup, so a title can be a real '<h2>'. The host is the surface. The element itself takes the border, the radius, and the grid, so you style 'Card' directly and there is no wrapper part to reach through with '::part'. Name the card with 'label', as a Stat Group is named, or with 'aria-label' or 'aria-labelledby'. These are the only names that work with server rendering, because reading a title from the light DOM needs a DOM, and the server has none. 'label' is set through 'ElementInternals', so it writes no attribute onto the card. **A named card is a group**, so a reader entering it hears its name; an unnamed one has no role, since a group with no name only adds "group" to what a reader says. Each region's slot is a part of the same name, 'body' for the main content, as Web Awesome's card names its regions. A slot draws no box, so a part passes inherited properties to what is slotted, and a page wanting a box there gives it one with 'display'. 'header-actions' and 'footer-actions' hold controls at the end of the header's and the footer's line, as Web Awesome's card does. While one holds something, its line is a 'header-row' or 'footer-row' part; otherwise there is no wrapper and every region is a bare slot. A server cannot see slotted content, so served actions sit on their own line until the script runs. **The card says which regions it holds**, as ':state(has-media)', ':state(has-header)' and ':state(has-footer)', so a sheet can draw a card with a header differently, as Web Awesome's 'with-header' does, with no attribute written onto the card. Read in the browser, so a served card carries none until the script runs. */
17206
+ /** The header, body, and footer regions are slots, because they have no state, behavior, or API of their own. You bring your own markup, so a title can be a real '<h2>'. The host is the surface. The element itself takes the border, the radius, and the grid, so you style 'Card' directly and there is no wrapper part to reach through with '::part'. Name the card with 'label', as a Stat Group is named, or with 'aria-label' or 'aria-labelledby'. 'label' is set through 'ElementInternals', so it writes no attribute onto the card. **A named card is a group**, so a reader entering it hears its name; an unnamed one has no role, since a group with no name only adds "group" to what a reader says. **With none of those, a heading in 'header' names the card**, such as the '<h2>' of its title, by reference, so the name follows the heading's words. Reading a heading needs a DOM, so a served card is named by it once the script runs; 'label', 'aria-label' and 'aria-labelledby' are the names a server writes. Each region's slot is a part of the same name, 'body' for the main content, as Web Awesome's card names its regions. A slot draws no box, so a part passes inherited properties to what is slotted, and a page wanting a box there gives it one with 'display'. 'header-actions' and 'footer-actions' hold controls at the end of the header's and the footer's line, as Web Awesome's card does. While one holds something, its line is a 'header-row' or 'footer-row' part; otherwise there is no wrapper and every region is a bare slot. A server cannot see slotted content, so a served card has no row; the styled tier sets served actions at the end of their line from the stylesheet alone, so they do not move when the script runs. **The card says which regions it holds**, as ':state(has-media)', ':state(has-header)' and ':state(has-footer)', so a sheet can draw a card with a header differently, as Web Awesome's 'with-header' does, with no attribute written onto the card. Read in the browser, so a served card carries none until the script runs. */
17150
17207
  "helix-headless-card": DefineCustomElement<
17151
17208
  HelixHeadlessCard,
17152
17209
  HelixHeadlessCardVueProps,
@@ -17188,13 +17245,13 @@ export interface WcToolkitVueGlobalComponents {
17188
17245
  HelixHeadlessCheckboxVueProps,
17189
17246
  HelixHeadlessCheckboxVueEvents
17190
17247
  >;
17191
- /** 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 '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. 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. 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. */
17248
+ /** 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 '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. 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. **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. */
17192
17249
  "helix-headless-code-block": DefineCustomElement<
17193
17250
  HelixHeadlessCodeBlock,
17194
17251
  HelixHeadlessCodeBlockVueProps,
17195
17252
  HelixHeadlessCodeBlockVueEvents
17196
17253
  >;
17197
- /** Renders a real '<code>' element, which marks the text as code for translation tools and document search. A styled span carries no such meaning, and a screen reader announces nothing about it. 'Code' is inline only and never scrolls. For a block of code with its own box, its own overflow, and copying, use 'CodeBlock', which is a separate family. */
17254
+ /** Renders a real '<code>' element, which marks the text as code for translation tools and document search. A styled span carries no such meaning, and a screen reader announces nothing about it. **Set 'translate="no"' on the element to keep a page translator off the code.** A translator that rewrites prose would also rewrite an identifier. The slotted text takes its translation mode from the element, its parent in the page, and the element writes nothing onto itself, so the attribute is yours to set. The '<code>' inside carries 'translate="no"' for anything the element draws itself. 'Code' is inline only and never scrolls. For a block of code with its own box, its own overflow, and copying, use 'CodeBlock', which is a separate family. */
17198
17255
  "helix-headless-code": DefineCustomElement<
17199
17256
  HelixHeadlessCode,
17200
17257
  HelixHeadlessCodeVueProps,
@@ -17296,7 +17353,7 @@ export interface WcToolkitVueGlobalComponents {
17296
17353
  HelixHeadlessDrilldownVueProps,
17297
17354
  HelixHeadlessDrilldownVueEvents
17298
17355
  >;
17299
- /** Shows what would be in a region and the one action that would fill it, so an empty region does not look like one that failed to load. The message is announced, because an empty view often replaces content that was loading, and the announcement tells a screen reader user that the search returned nothing. It is announced from a status region of its own, which is rendered empty and filled a frame after the view appears. Screen readers read a region that arrives with its text already in it inconsistently. For the seven seconds the region holds its copy, the heading and the message are hidden from screen readers, so the words are in the page once. Every region is a bare slot. There is no 'empty-state-heading' or 'empty-state-actions' element: assign your own heading and actions to the slots. **Or give the heading as words.** 'heading' draws them in a 'heading' part that is a heading at 'heading-level', 3 where it is not set, so a page rendering from data or on a server gets a heading a reader finds in the outline without writing the element. A heading slotted in replaces it. **Whatever is slotted into 'heading' is read as a heading.** An element that is no heading, such as a '<span>' or a '<p>', is set inside the 'heading' part at 'heading-level', so a screen reader still finds it in the outline. A heading element, or an element holding one, keeps its own level. A server cannot see the slotted element, so a served '<span>' becomes a heading once the script runs. */
17356
+ /** Shows what would be in a region and the one action that would fill it, so an empty region does not look like one that failed to load. The message is announced, because an empty view often replaces content that was loading, and the announcement tells a screen reader user that the search returned nothing. It is announced from a status region of its own, which is rendered empty and filled a frame after the view appears. Screen readers read a region that arrives with its text already in it inconsistently. For the seven seconds the region holds its copy, the heading and the message are hidden from screen readers, so the words are in the page once. Every region is a bare slot. There is no 'empty-state-heading' or 'empty-state-actions' element: assign your own heading and actions to the slots. The icon, the message and the actions slots are parts of the same names, as Card's regions are. A slot draws no box, so a part passes inherited properties, such as color and font, to what is slotted, and a page wanting a box there gives it one with 'display', such as a row of actions with 'display: flex'. **The view says which regions it holds**, as ':state(has-icon)' and ':state(has-actions)', so a sheet can space a view with no icon or no actions differently. Read in the browser, so a served view carries neither until the script runs. **Or give the heading as words.** 'heading' draws them in a 'heading' part that is a heading at 'heading-level', 3 where it is not set, so a page rendering from data or on a server gets a heading a reader finds in the outline without writing the element. A heading slotted in replaces it. **Whatever is slotted into 'heading' is read as a heading.** An element that is no heading, such as a '<span>' or a '<p>', is set inside the 'heading' part at 'heading-level', so a screen reader still finds it in the outline. A heading element, or an element holding one, keeps its own level. A server cannot see the slotted element, so a served '<span>' becomes a heading once the script runs. */
17300
17357
  "helix-headless-empty": DefineCustomElement<
17301
17358
  HelixHeadlessEmpty,
17302
17359
  HelixHeadlessEmptyVueProps,
@@ -17362,7 +17419,7 @@ export interface WcToolkitVueGlobalComponents {
17362
17419
  HelixHeadlessIconButtonVueProps,
17363
17420
  HelixHeadlessIconButtonVueEvents
17364
17421
  >;
17365
- /** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers the whole set, so any name in it draws. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. A name with no match renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. **A decorative icon that is all a control holds is reported.** In a development build, a button or a link whose only content is an icon with no 'label', and which has no name of its own, warns 'missing-name' once, through the runtime channel every Helix warning uses. */
17422
+ /** The icons are Phosphor, drawn on a 256 box at stroke-width 16. Each glyph renders its full inner markup, because most icons are several elements, each with its own stroke and fill. The markup is generated at build time from SVG files in this repository and never comes from user input, so rendering it with 'unsafeSVG' is safe. The '<svg>' carries 'fill="currentColor"'. The generator keeps only the inner markup, and Phosphor sets its fill on the root tag that the generator discards. Without it, the 65 solid glyphs fall back to black and disappear on a dark background. Shapes that set their own 'fill' or 'stroke' are unaffected. **A name is looked up in a registry.** The family's entry registers the whole set, so any name in it draws. The element's own entry, '@fusion.dev/helix-headless/icon/root', registers none: a page that imports it and calls 'registerIcons' with the glyphs it names ships those and no others. 'registerIconLibrary' resolves names under a prefix of your own, such as 'lucide:camera', at once or later, and the element fires 'load' when a glyph that came later is drawn. A glyph registered after the element rendered is drawn then. **Or point 'src' at an SVG file**, such as 'src="/icons/rocket.svg"', and the element fetches it and draws its shapes in 'currentColor' where the file does not color them. A file is fetched once a page, however many icons name it, and 'load' fires when it is drawn. Scripts, event handlers and 'javascript:' links in the file are taken out before it is drawn. A server fetches nothing, so a served icon with a 'src' is drawn once the script runs. A name with no match, or a 'src' that is no SVG, renders nothing, and the element fires 'error', so a typo in a name can be heard. It waits until the page has loaded and painted first, so a library a later module registers is not taken for a typo. An icon is decorative by default and hidden from assistive technology. Set 'label' only when the icon is the only carrier of meaning, such as in a button with no text. An 'aria-label' on the element works too: the element is then an image with that name. **A decorative icon that is all a control holds is reported.** In a development build, a button or a link whose only content is an icon with no 'label', and which has no name of its own, warns 'missing-name' once, through the runtime channel every Helix warning uses. */
17366
17423
  "helix-headless-icon": DefineCustomElement<
17367
17424
  HelixHeadlessIcon,
17368
17425
  HelixHeadlessIconVueProps,
@@ -17632,7 +17689,7 @@ export interface WcToolkitVueGlobalComponents {
17632
17689
  HelixHeadlessQrCodeVueProps,
17633
17690
  HelixHeadlessQrCodeVueEvents
17634
17691
  >;
17635
- /** Renders a real '<q>', so the browser supplies the quotation marks. It inserts the correct marks for the document's language and nests them correctly when one quotation sits inside another. Do not type quotation marks into the content: one that starts or ends with a typed mark warns once, with the runtime kind 'typed-marks'. A quotation in a language other than the page's takes 'lang' on the element, and its marks follow it: 'lang="de"' sets „…“ and 'lang="fr"' «…» inside an English page. For a passage set off from the surrounding text, use a blockquote. */
17692
+ /** Renders a real '<q>', so the browser supplies the quotation marks. It inserts the correct marks for the document's language and nests them correctly when one quotation sits inside another. Do not type quotation marks into the content: one that starts or ends with a typed mark warns once, with the runtime kind 'typed-marks'. A quotation in a language other than the page's takes 'lang' on the element, and its marks follow it: 'lang="de"' sets „…“ and 'lang="fr"' «…» inside an English page. **'no-marks' leaves the marks off**, for a quotation set where the page draws its own, such as a pull quote with a large decorative mark beside it or a table of sayings. The quotation still counts toward nesting, so a quote inside it takes the inner marks it would have had. Text with marks typed into it raises no warning under 'no-marks'. For a passage set off from the surrounding text, use a blockquote. */
17636
17693
  "helix-headless-quote": DefineCustomElement<
17637
17694
  HelixHeadlessQuote,
17638
17695
  HelixHeadlessQuoteVueProps,
@@ -17722,13 +17779,13 @@ export interface WcToolkitVueGlobalComponents {
17722
17779
  HelixHeadlessSplitterVueProps,
17723
17780
  HelixHeadlessSplitterVueEvents
17724
17781
  >;
17725
- /** Screen readers announce the stats as a group. The figures are read together and their order has no meaning, so the group does not announce positions such as "1 of 4". */
17782
+ /** **A named group is a group**, so a screen reader announces the stats together under its name, such as "Usage, group". Name it with 'label', 'aria-label' or 'aria-labelledby'. An unnamed one has no role, since a group with no name only adds "group" to what a reader says, as an unnamed Card has none. The figures are read together and their order has no meaning, so the group does not announce positions such as "1 of 4". */
17726
17783
  "helix-headless-stat-group": DefineCustomElement<
17727
17784
  HelixHeadlessStatGroup,
17728
17785
  HelixHeadlessStatGroupVueProps,
17729
17786
  HelixHeadlessStatGroupVueEvents
17730
17787
  >;
17731
- /** The label comes first in the markup and the value after it, so a screen reader reads what the figure counts before the number. Visually, the number stands out either way. Both are bare slots. An element that assigned itself a slot on connect would add an attribute after upgrade, which markup rendered on the server by React does not have. **A stat with a label is a group named by it**, so a reader moving through a dashboard hears "Revenue, group" and then the figure, its unit and its trend as one reading, rather than a run of loose words. The role and the name are set through 'ElementInternals' once the label is known, which writes no attribute; a stat with no label has no role. Put a 'Trend' in the 'trend' slot to have it read inside the group, after the figure it qualifies. */
17788
+ /** The label comes first in the markup and the value after it, so a screen reader reads what the figure counts before the number. Visually, the number stands out either way. Both are bare slots. An element that assigned itself a slot on connect would add an attribute after upgrade, which markup rendered on the server by React does not have. **A stat with a label is a group named by it**, so a reader moving through a dashboard hears "Revenue, group" and then the figure, its unit and its trend as one reading, rather than a run of loose words. The role and the name are set through 'ElementInternals' once the label is known, which writes no attribute; a stat with no label has no role. Put a 'Trend' in the 'trend' slot to have it read inside the group, after the figure it qualifies. **Or give the figure as a number.** 'value' is written with 'Intl.NumberFormat', in 'locale' and with 'format-options', so 'value="1234567" format-options='{"notation":"compact"}'' shows '1.2M', and a server writes it as the browser does. A number in 'value' takes the place of a slotted figure. **Each slot is a part of the same name**, and 'value' for the figure, so a page reaches the label, the unit and the trend from outside. A slot draws no box, so a part passes inherited properties to what is slotted. **The stat says which pieces it holds**, as ':state(has-label)', ':state(has-unit)' and ':state(has-trend)', read in the browser, so a served stat carries none until the script runs. */
17732
17789
  "helix-headless-stat": DefineCustomElement<
17733
17790
  HelixHeadlessStat,
17734
17791
  HelixHeadlessStatVueProps,
package/types/words.d.ts CHANGED
@@ -538,6 +538,19 @@ declare module '@fusion.dev/helix-core' {
538
538
  valueMissingMessage: Message
539
539
  }
540
540
  'helix-code-block': {
541
+ /**
542
+ * The name of a block that scrolls, which is a tab stop while it does.
543
+ *
544
+ * English: `Code`
545
+ */
546
+ codeLabel: Message
547
+ /**
548
+ * The name of a block that scrolls, where the block has a name. `{code}` is
549
+ * `code-label` and `{name}` the block's name.
550
+ *
551
+ * English: `{code}, {name}`
552
+ */
553
+ codeNameLabel: Message
541
554
  /**
542
555
  * The expand button's words while the block shows every line.
543
556
  *