@fusion.dev/helix-headless 0.16.3 → 0.16.5

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.
@@ -2330,12 +2330,22 @@
2330
2330
  "kind": "field",
2331
2331
  "name": "value",
2332
2332
  "type": {
2333
- "text": "string"
2333
+ "text": "number | string"
2334
2334
  },
2335
2335
  "default": "''",
2336
- "description": "The count or short text to show.\n\nAbsent shows a dot, zero shows nothing.",
2336
+ "description": "The count or short text to show.\n\nAbsent shows a dot, zero shows nothing.\n\n**A string, and a number is taken anyway.** What this shows is usually a\ncount, so `value={unread}` is the first thing a React consumer writes, and\na property assignment does not go through the attribute converter that\nwould have made it a string. Read raw it went straight into\n`this.value.trim()`, which threw inside `render` and left the mark showing\nwhatever it had last: measured, a badge set to the number 2 stayed an 8px\ndot with no digit in it, and the console carried\n`TypeError: this.value.trim is not a function`. A component whose whole job\nis showing a count must not lose the count for being handed one.",
2337
2337
  "attribute": "value"
2338
2338
  },
2339
+ {
2340
+ "kind": "field",
2341
+ "name": "given",
2342
+ "type": {
2343
+ "text": "string"
2344
+ },
2345
+ "privacy": "private",
2346
+ "description": "The value as text, whatever it was set to.",
2347
+ "readonly": true
2348
+ },
2339
2349
  {
2340
2350
  "kind": "field",
2341
2351
  "name": "blank",
@@ -2551,10 +2561,10 @@
2551
2561
  {
2552
2562
  "name": "value",
2553
2563
  "type": {
2554
- "text": "string"
2564
+ "text": "number | string"
2555
2565
  },
2556
2566
  "default": "''",
2557
- "description": "The count or short text to show.\n\nAbsent shows a dot, zero shows nothing.",
2567
+ "description": "The count or short text to show.\n\nAbsent shows a dot, zero shows nothing.\n\n**A string, and a number is taken anyway.** What this shows is usually a\ncount, so `value={unread}` is the first thing a React consumer writes, and\na property assignment does not go through the attribute converter that\nwould have made it a string. Read raw it went straight into\n`this.value.trim()`, which threw inside `render` and left the mark showing\nwhatever it had last: measured, a badge set to the number 2 stayed an 8px\ndot with no digit in it, and the console carried\n`TypeError: this.value.trim is not a function`. A component whose whole job\nis showing a count must not lose the count for being handed one.",
2558
2568
  "fieldName": "value"
2559
2569
  }
2560
2570
  ],
@@ -41012,7 +41022,7 @@
41012
41022
  "text": "TemplateResult | typeof nothing"
41013
41023
  }
41014
41024
  },
41015
- "description": "The control that removes the item, with the mark a consumer can replace.\n\n**A method rather than markup inside `render`, and the slot moves with\nit.** A fallback answers a consumer and a seam answers the tier above, which\nare different people: the styled tier wants an icon here, and with the slot\nwritten inline the only way to change it is to reimplement the whole\ntemplate. Moving only the fallback out is not enough: the slot is the thing\na tier redraws.\n\n**The mark is drawn rather than typed, which is what lets it align.** A\ncharacter such as `&times;` is placed by its font rather than by its box:\nmeasured against the ghost button beside it at 8x, the cross carried 6\npixels of ink to the label's 9.5 and sat 1.5 pixels below its center, in two\nboxes whose own centers agreed to a tenth of a pixel. No stylesheet can\ncorrect that, because the offset is inside the glyph. An `<svg>` is centered\non its own viewBox, so it lands where the box says and takes the icon step\nthe row is already set in. It is the `x` the Tag's dismiss draws, so two\ncontrols that mean \"take this away\" are one mark."
41025
+ "description": "The control that removes the item, with the mark a consumer can replace.\n\n**A method rather than markup inside `render`, and the slot moves with\nit.** A fallback answers a consumer and a seam answers the tier above, which\nare different people: the styled tier wants an icon here, and with the slot\nwritten inline the only way to change it is to reimplement the whole\ntemplate. Moving only the fallback out is not enough: the slot is the thing\na tier redraws.\n\n**The mark is drawn rather than typed, which is what lets it align.** A\ncharacter such as `&times;` is placed by its font rather than by its box:\nmeasured against the ghost button beside it at 8x, the cross carried 6\npixels of ink to the label's 9.5 and sat 1.5 pixels below its center, in two\nboxes whose own centers agreed to a tenth of a pixel. No stylesheet can\ncorrect that, because the offset is inside the glyph. An `<svg>` is centered\non its own viewBox, so it lands where the box says and takes the icon step\nthe row is already set in.\n\n**A trash and not the `x` the Tag draws, because the two do not mean the\nsame thing.** A tag's cross takes a token off a field the reader is still\nfilling in, and putting it back is retyping a word. A notification is the\nonly copy of something that happened, and this removes it from the feed for\ngood, so the mark is the one every other interface uses for that and the\nink is `danger`. It is only ever on screen while the row is hovered or\nfocused, so a feed of twenty is not a column of red."
41016
41026
  },
41017
41027
  {
41018
41028
  "kind": "method",
@@ -75760,7 +75770,7 @@
75760
75770
  "text": "string"
75761
75771
  },
75762
75772
  "default": "''",
75763
- "description": "Controls beyond the ones every player has, named in the order they appear.\n\nA list rather than a property apiece. A bar is a row with a budget, and a\nboolean per feature invites a consumer to switch all of them on: naming\nthem makes the row a decision, and makes the order theirs. Anything\nunrecognized is skipped rather than throwing, since the list is markup and\na typo should cost a control, not a page.\n\n`pip` is offered only where the platform has it, checked rather than\nassumed: it is absent on iPhone and behind a flag in Firefox, and a button\nthat cannot work is worse than one that is not there.\n\nThe names are `speed`, `pip`, `remote` and `download`.\n\n**`download` is named and never assumed.** Offering the file is a decision\nabout the content rather than about the player, and plenty of consumers\ndecline it deliberately. It is also the one control whose success is not\nours to promise: the attribute is ignored cross-origin, so a file served\nfrom somewhere else opens rather than saves, which is the browser's rule\nand not something a player can work around.",
75773
+ "description": "Controls beyond the ones every player has, named in the order they appear.\n\nA list rather than a property apiece. A bar is a row with a budget, and a\nboolean per feature invites a consumer to switch all of them on: naming\nthem makes the row a decision, and makes the order theirs. Anything\nunrecognized is skipped rather than throwing, since the list is markup and\na typo should cost a control, not a page.\n\n`pip` is offered only where the platform has it, checked rather than\nassumed: it is absent on iPhone and behind a flag in Firefox, and a button\nthat cannot work is worse than one that is not there.\n\nThe names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,\n`previous` and `next`.\n\n**`previous` and `next` do nothing to the video, and are offered anyway.**\nThey announce `helix-previous` and `helix-next` and stop there, so what\nthey move is whatever holds the set, which is what `VideoPlaylist` listens\nfor. A player standing alone therefore draws a pair of controls that change\nnothing, and that is deliberate: a player cannot know whether it is inside\na set, and one that hid them until it could prove there was one would be a\nplayer that never offers them. Name them where something is listening.\n\n**`download` is named and never assumed.** Offering the file is a decision\nabout the content rather than about the player, and plenty of consumers\ndecline it deliberately. It is also the one control whose success is not\nours to promise: the attribute is ignored cross-origin, so a file served\nfrom somewhere else opens rather than saves, which is the browser's rule\nand not something a player can work around.",
75764
75774
  "attribute": "extra-controls"
75765
75775
  },
75766
75776
  {
@@ -76916,7 +76926,7 @@
76916
76926
  "text": "string"
76917
76927
  },
76918
76928
  "default": "''",
76919
- "description": "Controls beyond the ones every player has, named in the order they appear.\n\nA list rather than a property apiece. A bar is a row with a budget, and a\nboolean per feature invites a consumer to switch all of them on: naming\nthem makes the row a decision, and makes the order theirs. Anything\nunrecognized is skipped rather than throwing, since the list is markup and\na typo should cost a control, not a page.\n\n`pip` is offered only where the platform has it, checked rather than\nassumed: it is absent on iPhone and behind a flag in Firefox, and a button\nthat cannot work is worse than one that is not there.\n\nThe names are `speed`, `pip`, `remote` and `download`.\n\n**`download` is named and never assumed.** Offering the file is a decision\nabout the content rather than about the player, and plenty of consumers\ndecline it deliberately. It is also the one control whose success is not\nours to promise: the attribute is ignored cross-origin, so a file served\nfrom somewhere else opens rather than saves, which is the browser's rule\nand not something a player can work around.",
76929
+ "description": "Controls beyond the ones every player has, named in the order they appear.\n\nA list rather than a property apiece. A bar is a row with a budget, and a\nboolean per feature invites a consumer to switch all of them on: naming\nthem makes the row a decision, and makes the order theirs. Anything\nunrecognized is skipped rather than throwing, since the list is markup and\na typo should cost a control, not a page.\n\n`pip` is offered only where the platform has it, checked rather than\nassumed: it is absent on iPhone and behind a flag in Firefox, and a button\nthat cannot work is worse than one that is not there.\n\nThe names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,\n`previous` and `next`.\n\n**`previous` and `next` do nothing to the video, and are offered anyway.**\nThey announce `helix-previous` and `helix-next` and stop there, so what\nthey move is whatever holds the set, which is what `VideoPlaylist` listens\nfor. A player standing alone therefore draws a pair of controls that change\nnothing, and that is deliberate: a player cannot know whether it is inside\na set, and one that hid them until it could prove there was one would be a\nplayer that never offers them. Name them where something is listening.\n\n**`download` is named and never assumed.** Offering the file is a decision\nabout the content rather than about the player, and plenty of consumers\ndecline it deliberately. It is also the one control whose success is not\nours to promise: the attribute is ignored cross-origin, so a file served\nfrom somewhere else opens rather than saves, which is the browser's rule\nand not something a player can work around.",
76920
76930
  "fieldName": "extraControls"
76921
76931
  },
76922
76932
  {
@@ -46,8 +46,20 @@ export declare class HelixHeadlessBadge extends HelixElement {
46
46
  * The count or short text to show.
47
47
  *
48
48
  * Absent shows a dot, zero shows nothing.
49
+ *
50
+ * **A string, and a number is taken anyway.** What this shows is usually a
51
+ * count, so `value={unread}` is the first thing a React consumer writes, and
52
+ * a property assignment does not go through the attribute converter that
53
+ * would have made it a string. Read raw it went straight into
54
+ * `this.value.trim()`, which threw inside `render` and left the mark showing
55
+ * whatever it had last: measured, a badge set to the number 2 stayed an 8px
56
+ * dot with no digit in it, and the console carried
57
+ * `TypeError: this.value.trim is not a function`. A component whose whole job
58
+ * is showing a count must not lose the count for being handed one.
49
59
  */
50
- value: string;
60
+ value: number | string;
61
+ /** The value as text, whatever it was set to. */
62
+ private get given();
51
63
  /** Whether the value counts nothing, in which case there is no mark. */
52
64
  private get blank();
53
65
  /** What the indicator reads, once the cap has been applied. */
@@ -13,15 +13,18 @@ let HelixHeadlessBadge = class HelixHeadlessBadge extends HelixElement {
13
13
  this.label = '';
14
14
  this.value = '';
15
15
  }
16
+ get given() {
17
+ return String(this.value ?? '');
18
+ }
16
19
  get blank() {
17
- return this.value.trim() !== '' && Number(this.value) === 0;
20
+ return this.given.trim() !== '' && Number(this.given) === 0;
18
21
  }
19
22
  get text() {
20
- const count = Number(this.value);
23
+ const count = Number(this.given);
21
24
  if (this.max !== undefined && Number.isFinite(count) && count > this.max) {
22
25
  return `${this.max}+`;
23
26
  }
24
- return this.value;
27
+ return this.given;
25
28
  }
26
29
  render() {
27
30
  const blank = this.blank;
@@ -146,8 +146,15 @@ export declare class HelixHeadlessNotification extends HelixElement {
146
146
  * boxes whose own centers agreed to a tenth of a pixel. No stylesheet can
147
147
  * correct that, because the offset is inside the glyph. An `<svg>` is centered
148
148
  * on its own viewBox, so it lands where the box says and takes the icon step
149
- * the row is already set in. It is the `x` the Tag's dismiss draws, so two
150
- * controls that mean "take this away" are one mark.
149
+ * the row is already set in.
150
+ *
151
+ * **A trash and not the `x` the Tag draws, because the two do not mean the
152
+ * same thing.** A tag's cross takes a token off a field the reader is still
153
+ * filling in, and putting it back is retyping a word. A notification is the
154
+ * only copy of something that happened, and this removes it from the feed for
155
+ * good, so the mark is the one every other interface uses for that and the
156
+ * ink is `danger`. It is only ever on screen while the row is hovered or
157
+ * focused, so a feed of twenty is not a column of red.
151
158
  */
152
159
  protected renderDismiss(): TemplateResult | typeof nothing;
153
160
  /**
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { customElement, HelixDismissEvent, HelixElement, HelixReadEvent, hostAria, requestChange, slotFilled, } from '@fusion.dev/helix-core';
8
- import { x } from '@fusion.dev/helix-icons';
8
+ import { trash } from '@fusion.dev/helix-icons';
9
9
  import { nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
@@ -83,9 +83,9 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
83
83
  data-glyph
84
84
  fill="currentColor"
85
85
  part="dismiss-mark"
86
- viewBox=${x.viewBox}
86
+ viewBox=${trash.viewBox}
87
87
  >
88
- ${unsafeSVG(x.content)}
88
+ ${unsafeSVG(trash.content)}
89
89
  </svg>
90
90
  </slot>
91
91
  </button>`;
@@ -159,7 +159,16 @@ export declare class HelixHeadlessVideo extends HelixElement {
159
159
  * assumed: it is absent on iPhone and behind a flag in Firefox, and a button
160
160
  * that cannot work is worse than one that is not there.
161
161
  *
162
- * The names are `speed`, `pip`, `remote` and `download`.
162
+ * The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
163
+ * `previous` and `next`.
164
+ *
165
+ * **`previous` and `next` do nothing to the video, and are offered anyway.**
166
+ * They announce `helix-previous` and `helix-next` and stop there, so what
167
+ * they move is whatever holds the set, which is what `VideoPlaylist` listens
168
+ * for. A player standing alone therefore draws a pair of controls that change
169
+ * nothing, and that is deliberate: a player cannot know whether it is inside
170
+ * a set, and one that hid them until it could prove there was one would be a
171
+ * player that never offers them. Name them where something is listening.
163
172
  *
164
173
  * **`download` is named and never assumed.** Offering the file is a decision
165
174
  * about the content rather than about the player, and plenty of consumers
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.16.3",
4
+ "version": "0.16.5",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -45,14 +45,14 @@
45
45
  },
46
46
  "bugs": "https://github.com/project-fusion/fusion/issues",
47
47
  "dependencies": {
48
- "@fusion.dev/helix-core": "0.16.3",
49
- "@fusion.dev/helix-icons": "0.16.3",
48
+ "@fusion.dev/helix-core": "0.16.5",
49
+ "@fusion.dev/helix-icons": "0.16.5",
50
50
  "uqr": "^0.1.3"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@custom-elements-manifest/analyzer": "^0.11.0",
54
- "@fusion.dev/helix-cem": "0.16.3",
55
- "@fusion.dev/helix-testing": "0.16.3",
54
+ "@fusion.dev/helix-cem": "0.16.5",
55
+ "@fusion.dev/helix-testing": "0.16.5",
56
56
  "@fusion.dev/scripts": "0.0.0-dev",
57
57
  "@happy-dom/global-registrator": "^20.0.0",
58
58
  "@lit-labs/ssr": "^3.3.0",
package/types/jsx.d.ts CHANGED
@@ -802,7 +802,17 @@ Past it the indicator reads `{max}+`. */
802
802
  max?: (HelixHeadlessBadge["max"]) | undefined;
803
803
  /** The count or short text to show.
804
804
 
805
- Absent shows a dot, zero shows nothing. */
805
+ Absent shows a dot, zero shows nothing.
806
+
807
+ **A string, and a number is taken anyway.** What this shows is usually a
808
+ count, so `value={unread}` is the first thing a React consumer writes, and
809
+ a property assignment does not go through the attribute converter that
810
+ would have made it a string. Read raw it went straight into
811
+ `this.value.trim()`, which threw inside `render` and left the mark showing
812
+ whatever it had last: measured, a badge set to the number 2 stayed an 8px
813
+ dot with no digit in it, and the console carried
814
+ `TypeError: this.value.trim is not a function`. A component whose whole job
815
+ is showing a count must not lose the count for being handed one. */
806
816
  value?: (HelixHeadlessBadge["value"]) | undefined;
807
817
  };
808
818
 
@@ -817,7 +827,17 @@ Past it the indicator reads `{max}+`. */
817
827
  "prop:max"?: (HelixHeadlessBadge["max"]) | undefined;
818
828
  /** The count or short text to show.
819
829
 
820
- Absent shows a dot, zero shows nothing. */
830
+ Absent shows a dot, zero shows nothing.
831
+
832
+ **A string, and a number is taken anyway.** What this shows is usually a
833
+ count, so `value={unread}` is the first thing a React consumer writes, and
834
+ a property assignment does not go through the attribute converter that
835
+ would have made it a string. Read raw it went straight into
836
+ `this.value.trim()`, which threw inside `render` and left the mark showing
837
+ whatever it had last: measured, a badge set to the number 2 stayed an 8px
838
+ dot with no digit in it, and the console carried
839
+ `TypeError: this.value.trim is not a function`. A component whose whole job
840
+ is showing a count must not lose the count for being handed one. */
821
841
  "prop:value"?: (HelixHeadlessBadge["value"]) | undefined;
822
842
 
823
843
  /** Set the innerHTML of the element */
@@ -15173,7 +15193,16 @@ a typo should cost a control, not a page.
15173
15193
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
15174
15194
  that cannot work is worse than one that is not there.
15175
15195
 
15176
- The names are `speed`, `pip`, `remote` and `download`.
15196
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
15197
+ `previous` and `next`.
15198
+
15199
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
15200
+ They announce `helix-previous` and `helix-next` and stop there, so what
15201
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
15202
+ for. A player standing alone therefore draws a pair of controls that change
15203
+ nothing, and that is deliberate: a player cannot know whether it is inside
15204
+ a set, and one that hid them until it could prove there was one would be a
15205
+ player that never offers them. Name them where something is listening.
15177
15206
 
15178
15207
  **`download` is named and never assumed.** Offering the file is a decision
15179
15208
  about the content rather than about the player, and plenty of consumers
@@ -15194,7 +15223,16 @@ a typo should cost a control, not a page.
15194
15223
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
15195
15224
  that cannot work is worse than one that is not there.
15196
15225
 
15197
- The names are `speed`, `pip`, `remote` and `download`.
15226
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
15227
+ `previous` and `next`.
15228
+
15229
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
15230
+ They announce `helix-previous` and `helix-next` and stop there, so what
15231
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
15232
+ for. A player standing alone therefore draws a pair of controls that change
15233
+ nothing, and that is deliberate: a player cannot know whether it is inside
15234
+ a set, and one that hid them until it could prove there was one would be a
15235
+ player that never offers them. Name them where something is listening.
15198
15236
 
15199
15237
  **`download` is named and never assumed.** Offering the file is a decision
15200
15238
  about the content rather than about the player, and plenty of consumers
@@ -15402,7 +15440,16 @@ a typo should cost a control, not a page.
15402
15440
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
15403
15441
  that cannot work is worse than one that is not there.
15404
15442
 
15405
- The names are `speed`, `pip`, `remote` and `download`.
15443
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
15444
+ `previous` and `next`.
15445
+
15446
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
15447
+ They announce `helix-previous` and `helix-next` and stop there, so what
15448
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
15449
+ for. A player standing alone therefore draws a pair of controls that change
15450
+ nothing, and that is deliberate: a player cannot know whether it is inside
15451
+ a set, and one that hid them until it could prove there was one would be a
15452
+ player that never offers them. Name them where something is listening.
15406
15453
 
15407
15454
  **`download` is named and never assumed.** Offering the file is a decision
15408
15455
  about the content rather than about the player, and plenty of consumers
@@ -15423,7 +15470,16 @@ a typo should cost a control, not a page.
15423
15470
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
15424
15471
  that cannot work is worse than one that is not there.
15425
15472
 
15426
- The names are `speed`, `pip`, `remote` and `download`.
15473
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
15474
+ `previous` and `next`.
15475
+
15476
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
15477
+ They announce `helix-previous` and `helix-next` and stop there, so what
15478
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
15479
+ for. A player standing alone therefore draws a pair of controls that change
15480
+ nothing, and that is deliberate: a player cannot know whether it is inside
15481
+ a set, and one that hid them until it could prove there was one would be a
15482
+ player that never offers them. Name them where something is listening.
15427
15483
 
15428
15484
  **`download` is named and never assumed.** Offering the file is a decision
15429
15485
  about the content rather than about the player, and plenty of consumers
@@ -16143,6 +16199,16 @@ export type CustomElements = {
16143
16199
  * - `value`: The count or short text to show.
16144
16200
  *
16145
16201
  * Absent shows a dot, zero shows nothing.
16202
+ *
16203
+ * **A string, and a number is taken anyway.** What this shows is usually a
16204
+ * count, so `value={unread}` is the first thing a React consumer writes, and
16205
+ * a property assignment does not go through the attribute converter that
16206
+ * would have made it a string. Read raw it went straight into
16207
+ * `this.value.trim()`, which threw inside `render` and left the mark showing
16208
+ * whatever it had last: measured, a badge set to the number 2 stayed an 8px
16209
+ * dot with no digit in it, and the console carried
16210
+ * `TypeError: this.value.trim is not a function`. A component whose whole job
16211
+ * is showing a count must not lose the count for being handed one.
16146
16212
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
16147
16213
  *
16148
16214
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -29753,7 +29819,16 @@ export type CustomElements = {
29753
29819
  * assumed: it is absent on iPhone and behind a flag in Firefox, and a button
29754
29820
  * that cannot work is worse than one that is not there.
29755
29821
  *
29756
- * The names are `speed`, `pip`, `remote` and `download`.
29822
+ * The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
29823
+ * `previous` and `next`.
29824
+ *
29825
+ * **`previous` and `next` do nothing to the video, and are offered anyway.**
29826
+ * They announce `helix-previous` and `helix-next` and stop there, so what
29827
+ * they move is whatever holds the set, which is what `VideoPlaylist` listens
29828
+ * for. A player standing alone therefore draws a pair of controls that change
29829
+ * nothing, and that is deliberate: a player cannot know whether it is inside
29830
+ * a set, and one that hid them until it could prove there was one would be a
29831
+ * player that never offers them. Name them where something is listening.
29757
29832
  *
29758
29833
  * **`download` is named and never assumed.** Offering the file is a decision
29759
29834
  * about the content rather than about the player, and plenty of consumers
@@ -30565,6 +30640,16 @@ export type CustomElementsSolidJs = {
30565
30640
  * - `value`: The count or short text to show.
30566
30641
  *
30567
30642
  * Absent shows a dot, zero shows nothing.
30643
+ *
30644
+ * **A string, and a number is taken anyway.** What this shows is usually a
30645
+ * count, so `value={unread}` is the first thing a React consumer writes, and
30646
+ * a property assignment does not go through the attribute converter that
30647
+ * would have made it a string. Read raw it went straight into
30648
+ * `this.value.trim()`, which threw inside `render` and left the mark showing
30649
+ * whatever it had last: measured, a badge set to the number 2 stayed an 8px
30650
+ * dot with no digit in it, and the console carried
30651
+ * `TypeError: this.value.trim is not a function`. A component whose whole job
30652
+ * is showing a count must not lose the count for being handed one.
30568
30653
  * - `whenSettled`: Resolves a frame after the first update, when transitions are switched on.
30569
30654
  *
30570
30655
  * **Named `whenSettled` because `settled` is taken four times over**, by
@@ -44434,7 +44519,16 @@ export type CustomElementsSolidJs = {
44434
44519
  * assumed: it is absent on iPhone and behind a flag in Firefox, and a button
44435
44520
  * that cannot work is worse than one that is not there.
44436
44521
  *
44437
- * The names are `speed`, `pip`, `remote` and `download`.
44522
+ * The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
44523
+ * `previous` and `next`.
44524
+ *
44525
+ * **`previous` and `next` do nothing to the video, and are offered anyway.**
44526
+ * They announce `helix-previous` and `helix-next` and stop there, so what
44527
+ * they move is whatever holds the set, which is what `VideoPlaylist` listens
44528
+ * for. A player standing alone therefore draws a pair of controls that change
44529
+ * nothing, and that is deliberate: a player cannot know whether it is inside
44530
+ * a set, and one that hid them until it could prove there was one would be a
44531
+ * player that never offers them. Name them where something is listening.
44438
44532
  *
44439
44533
  * **`download` is named and never assumed.** Offering the file is a decision
44440
44534
  * about the content rather than about the player, and plenty of consumers
package/types/vue.d.ts CHANGED
@@ -426,7 +426,17 @@ Past it the indicator reads `{max}+`. */
426
426
  max?: (HelixHeadlessBadge["max"]) | undefined;
427
427
  /** The count or short text to show.
428
428
 
429
- Absent shows a dot, zero shows nothing. */
429
+ Absent shows a dot, zero shows nothing.
430
+
431
+ **A string, and a number is taken anyway.** What this shows is usually a
432
+ count, so `value={unread}` is the first thing a React consumer writes, and
433
+ a property assignment does not go through the attribute converter that
434
+ would have made it a string. Read raw it went straight into
435
+ `this.value.trim()`, which threw inside `render` and left the mark showing
436
+ whatever it had last: measured, a badge set to the number 2 stayed an 8px
437
+ dot with no digit in it, and the console carried
438
+ `TypeError: this.value.trim is not a function`. A component whose whole job
439
+ is showing a count must not lose the count for being handed one. */
430
440
  value?: (HelixHeadlessBadge["value"]) | undefined;
431
441
  };
432
442
 
@@ -7819,7 +7829,16 @@ a typo should cost a control, not a page.
7819
7829
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
7820
7830
  that cannot work is worse than one that is not there.
7821
7831
 
7822
- The names are `speed`, `pip`, `remote` and `download`.
7832
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
7833
+ `previous` and `next`.
7834
+
7835
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
7836
+ They announce `helix-previous` and `helix-next` and stop there, so what
7837
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
7838
+ for. A player standing alone therefore draws a pair of controls that change
7839
+ nothing, and that is deliberate: a player cannot know whether it is inside
7840
+ a set, and one that hid them until it could prove there was one would be a
7841
+ player that never offers them. Name them where something is listening.
7823
7842
 
7824
7843
  **`download` is named and never assumed.** Offering the file is a decision
7825
7844
  about the content rather than about the player, and plenty of consumers
@@ -7840,7 +7859,16 @@ a typo should cost a control, not a page.
7840
7859
  assumed: it is absent on iPhone and behind a flag in Firefox, and a button
7841
7860
  that cannot work is worse than one that is not there.
7842
7861
 
7843
- The names are `speed`, `pip`, `remote` and `download`.
7862
+ The names are `speed`, `pip`, `remote`, `download`, `rewind`, `forward`,
7863
+ `previous` and `next`.
7864
+
7865
+ **`previous` and `next` do nothing to the video, and are offered anyway.**
7866
+ They announce `helix-previous` and `helix-next` and stop there, so what
7867
+ they move is whatever holds the set, which is what `VideoPlaylist` listens
7868
+ for. A player standing alone therefore draws a pair of controls that change
7869
+ nothing, and that is deliberate: a player cannot know whether it is inside
7870
+ a set, and one that hid them until it could prove there was one would be a
7871
+ player that never offers them. Name them where something is listening.
7844
7872
 
7845
7873
  **`download` is named and never assumed.** Offering the file is a decision
7846
7874
  about the content rather than about the player, and plenty of consumers