@fusion.dev/helix-headless 0.0.0-dev → 0.0.2

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.
Files changed (210) hide show
  1. package/custom-elements.json +4513 -4483
  2. package/dist/accordion/item/accordion-item.d.ts +13 -15
  3. package/dist/accordion/item/accordion-item.js +15 -17
  4. package/dist/announcement/root/announcement-root.d.ts +7 -25
  5. package/dist/announcement/root/announcement-root.js +7 -20
  6. package/dist/app-header/root/app-header-root.d.ts +10 -17
  7. package/dist/app-header/root/app-header-root.js +9 -18
  8. package/dist/avatar/group/avatar-group.d.ts +10 -19
  9. package/dist/avatar/group/avatar-group.js +12 -17
  10. package/dist/avatar/root/avatar-root.d.ts +8 -8
  11. package/dist/avatar/root/avatar-root.js +19 -20
  12. package/dist/badge/root/badge-root.d.ts +6 -6
  13. package/dist/badge/root/badge-root.js +13 -13
  14. package/dist/bar-chart/root/bar-chart-root.d.ts +21 -29
  15. package/dist/bar-chart/root/bar-chart-root.js +42 -57
  16. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +12 -18
  17. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +13 -16
  18. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +9 -28
  19. package/dist/breadcrumbs/root/breadcrumbs-root.js +9 -28
  20. package/dist/button/root/button-root.d.ts +84 -94
  21. package/dist/button/root/button-root.js +82 -92
  22. package/dist/callout/root/callout-root.d.ts +4 -5
  23. package/dist/carousel/root/carousel-root.d.ts +59 -71
  24. package/dist/carousel/root/carousel-root.js +73 -101
  25. package/dist/chat/composer/chat-composer.d.ts +29 -33
  26. package/dist/chat/composer/chat-composer.js +40 -44
  27. package/dist/chat/message/chat-message.d.ts +25 -25
  28. package/dist/chat/message/chat-message.js +26 -26
  29. package/dist/chat/root/chat-root.d.ts +28 -41
  30. package/dist/chat/root/chat-root.js +27 -40
  31. package/dist/checkbox/root/checkbox-root.d.ts +10 -12
  32. package/dist/checkbox/root/checkbox-root.js +29 -35
  33. package/dist/checkbox-group/root/checkbox-group-root.d.ts +32 -45
  34. package/dist/checkbox-group/root/checkbox-group-root.js +53 -79
  35. package/dist/code-block/root/code-block-root.d.ts +3 -4
  36. package/dist/code-block/root/code-block-root.js +8 -12
  37. package/dist/color-input/root/color-input-root.d.ts +36 -37
  38. package/dist/color-input/root/color-input-root.js +29 -34
  39. package/dist/color-picker/color.d.ts +7 -8
  40. package/dist/color-picker/color.js +7 -8
  41. package/dist/color-picker/root/color-picker-root.d.ts +55 -57
  42. package/dist/color-picker/root/color-picker-root.js +60 -64
  43. package/dist/combobox/root/combobox-root.d.ts +53 -58
  44. package/dist/combobox/root/combobox-root.js +85 -94
  45. package/dist/command/root/command-root.d.ts +8 -8
  46. package/dist/command/root/command-root.js +29 -33
  47. package/dist/copy-button/root/copy-button-root.d.ts +21 -24
  48. package/dist/copy-button/root/copy-button-root.js +25 -35
  49. package/dist/data-table/root/data-table-root.d.ts +77 -76
  50. package/dist/data-table/root/data-table-root.js +95 -84
  51. package/dist/data-table/root/order.d.ts +2 -2
  52. package/dist/data-table/root/order.js +1 -3
  53. package/dist/date-input/root/date-input-root.d.ts +88 -93
  54. package/dist/date-input/root/date-input-root.js +147 -158
  55. package/dist/date-picker/root/date-picker-root.d.ts +75 -83
  56. package/dist/date-picker/root/date-picker-root.js +120 -143
  57. package/dist/dialog/root/dialog-root.d.ts +41 -24
  58. package/dist/dialog/root/dialog-root.js +47 -24
  59. package/dist/divider/root/divider-root.d.ts +5 -6
  60. package/dist/divider/root/divider-root.js +4 -5
  61. package/dist/donut-chart/root/donut-chart-root.d.ts +22 -25
  62. package/dist/donut-chart/root/donut-chart-root.js +37 -51
  63. package/dist/drawer/root/drawer-root.d.ts +24 -29
  64. package/dist/drawer/root/drawer-root.js +15 -22
  65. package/dist/drilldown/item/drilldown-item.d.ts +14 -14
  66. package/dist/drilldown/item/drilldown-item.js +24 -26
  67. package/dist/drilldown/root/drilldown-root.d.ts +8 -10
  68. package/dist/drilldown/root/drilldown-root.js +6 -7
  69. package/dist/element-events.generated.js +1 -1
  70. package/dist/file-input/root/file-input-root.d.ts +20 -24
  71. package/dist/file-input/root/file-input-root.js +42 -57
  72. package/dist/format-date/root/format-date-root.js +1 -1
  73. package/dist/heatmap/root/buckets.d.ts +8 -8
  74. package/dist/heatmap/root/buckets.js +8 -8
  75. package/dist/heatmap/root/heatmap-root.d.ts +57 -63
  76. package/dist/heatmap/root/heatmap-root.js +72 -83
  77. package/dist/icon/root/icon-root.d.ts +4 -4
  78. package/dist/icon/root/icon-root.js +9 -9
  79. package/dist/icon-button/root/icon-button-root.d.ts +4 -6
  80. package/dist/icon-button/root/icon-button-root.js +4 -6
  81. package/dist/image/root/image-root.d.ts +49 -59
  82. package/dist/image/root/image-root.js +55 -65
  83. package/dist/index.d.ts +5 -5
  84. package/dist/index.js +5 -5
  85. package/dist/input/root/input-root.d.ts +61 -85
  86. package/dist/input/root/input-root.js +79 -106
  87. package/dist/kbd/root/kbd-root.d.ts +8 -7
  88. package/dist/kbd/root/kbd-root.js +71 -11
  89. package/dist/legend/root/legend-root.d.ts +1 -1
  90. package/dist/legend/root/legend-root.js +4 -5
  91. package/dist/line-chart/root/line-chart-root.d.ts +26 -30
  92. package/dist/line-chart/root/line-chart-root.js +10 -10
  93. package/dist/list/item/list-item.d.ts +14 -18
  94. package/dist/list/item/list-item.js +18 -22
  95. package/dist/list/root/list-root.d.ts +4 -4
  96. package/dist/list/root/list-root.js +3 -3
  97. package/dist/listbox/root/listbox-root.d.ts +31 -58
  98. package/dist/listbox/root/listbox-root.js +66 -109
  99. package/dist/megamenu/root/megamenu-root.d.ts +34 -35
  100. package/dist/megamenu/root/megamenu-root.js +53 -58
  101. package/dist/menu/item/menu-item.d.ts +39 -53
  102. package/dist/menu/item/menu-item.js +50 -64
  103. package/dist/menu/root/menu-root.d.ts +30 -40
  104. package/dist/menu/root/menu-root.js +49 -82
  105. package/dist/meter/root/meter-root.d.ts +49 -53
  106. package/dist/meter/root/meter-root.js +22 -27
  107. package/dist/navigation/root/navigation-root.js +11 -19
  108. package/dist/notifications/notification/notification.d.ts +16 -22
  109. package/dist/notifications/notification/notification.js +21 -27
  110. package/dist/notifications/root/notifications-root.d.ts +31 -39
  111. package/dist/notifications/root/notifications-root.js +41 -52
  112. package/dist/number-input/root/number-input-root.d.ts +31 -33
  113. package/dist/number-input/root/number-input-root.js +37 -39
  114. package/dist/option/root/option-root.d.ts +73 -74
  115. package/dist/option/root/option-root.js +62 -64
  116. package/dist/outline/root/outline-root.d.ts +38 -44
  117. package/dist/outline/root/outline-root.js +66 -82
  118. package/dist/pagination/root/pagination-root.d.ts +87 -92
  119. package/dist/pagination/root/pagination-root.js +116 -123
  120. package/dist/pagination/size/pagination-size.d.ts +31 -50
  121. package/dist/pagination/size/pagination-size.js +35 -55
  122. package/dist/pagination/summary/pagination-summary.d.ts +12 -12
  123. package/dist/pagination/summary/pagination-summary.js +18 -18
  124. package/dist/pin-input/root/pin-input-root.d.ts +53 -70
  125. package/dist/pin-input/root/pin-input-root.js +74 -94
  126. package/dist/popover/root/popover-root.d.ts +15 -20
  127. package/dist/popover/root/popover-root.js +19 -36
  128. package/dist/progress/root/progress-root.d.ts +12 -14
  129. package/dist/progress/root/progress-root.js +22 -25
  130. package/dist/qr-code/root/qr-code-root.d.ts +11 -11
  131. package/dist/qr-code/root/qr-code-root.js +12 -14
  132. package/dist/radio/group/radio-group.js +19 -26
  133. package/dist/radio/root/radio-root.d.ts +12 -13
  134. package/dist/radio/root/radio-root.js +12 -13
  135. package/dist/rating/root/rating-root.d.ts +25 -30
  136. package/dist/rating/root/rating-root.js +43 -50
  137. package/dist/scroll-area/root/scroll-area-root.d.ts +11 -14
  138. package/dist/scroll-area/root/scroll-area-root.js +39 -33
  139. package/dist/select/root/select-root.d.ts +7 -12
  140. package/dist/select/root/select-root.js +40 -55
  141. package/dist/slider/root/slider-root.d.ts +53 -60
  142. package/dist/slider/root/slider-root.js +74 -85
  143. package/dist/sparkline/root/sparkline-root.d.ts +43 -47
  144. package/dist/sparkline/root/sparkline-root.js +23 -32
  145. package/dist/speed-dial/item/speed-dial-item.d.ts +6 -6
  146. package/dist/speed-dial/item/speed-dial-item.js +9 -9
  147. package/dist/speed-dial/root/speed-dial-root.d.ts +21 -25
  148. package/dist/speed-dial/root/speed-dial-root.js +32 -40
  149. package/dist/splitter/root/splitter-root.d.ts +98 -111
  150. package/dist/splitter/root/splitter-root.js +96 -123
  151. package/dist/stat/root/stat-root.d.ts +2 -7
  152. package/dist/stat/root/stat-root.js +0 -5
  153. package/dist/steps/step/step.d.ts +19 -24
  154. package/dist/steps/step/step.js +27 -32
  155. package/dist/switch/root/switch-root.js +2 -2
  156. package/dist/table/column/table-column.d.ts +54 -60
  157. package/dist/table/column/table-column.js +95 -68
  158. package/dist/table/root/table-root.d.ts +5 -6
  159. package/dist/table/root/table-root.js +7 -10
  160. package/dist/tabs/panel/tab-panel.d.ts +21 -25
  161. package/dist/tabs/panel/tab-panel.js +25 -29
  162. package/dist/tabs/root/tabs-root.d.ts +25 -34
  163. package/dist/tabs/root/tabs-root.js +22 -28
  164. package/dist/tabs/tab/tab.d.ts +12 -12
  165. package/dist/tabs/tab/tab.js +19 -20
  166. package/dist/textarea/root/textarea-root.d.ts +36 -36
  167. package/dist/textarea/root/textarea-root.js +43 -47
  168. package/dist/time-input/root/time-input-root.d.ts +58 -68
  169. package/dist/time-input/root/time-input-root.js +62 -77
  170. package/dist/time-picker/root/time-picker-root.d.ts +73 -79
  171. package/dist/time-picker/root/time-picker-root.js +72 -84
  172. package/dist/timeline/item/timeline-item.d.ts +8 -11
  173. package/dist/timeline/item/timeline-item.js +8 -11
  174. package/dist/timeline/root/timeline-root.d.ts +5 -7
  175. package/dist/timeline/root/timeline-root.js +5 -7
  176. package/dist/toast/item/toast-item.d.ts +9 -27
  177. package/dist/toast/item/toast-item.js +19 -41
  178. package/dist/toast/root/toast-root.d.ts +10 -14
  179. package/dist/toast/root/toast-root.js +4 -5
  180. package/dist/toggle/group/toggle-group.d.ts +6 -15
  181. package/dist/toggle/group/toggle-group.js +21 -36
  182. package/dist/toggle/root/toggle-root.d.ts +26 -27
  183. package/dist/toggle/root/toggle-root.js +30 -31
  184. package/dist/toolbar/root/toolbar-root.d.ts +7 -10
  185. package/dist/toolbar/root/toolbar-root.js +10 -14
  186. package/dist/tooltip/root/tooltip-root.d.ts +52 -59
  187. package/dist/tooltip/root/tooltip-root.js +98 -93
  188. package/dist/tour/root/tour-root.d.ts +19 -23
  189. package/dist/tour/root/tour-root.js +31 -41
  190. package/dist/tour/stop/tour-stop.d.ts +14 -15
  191. package/dist/tour/stop/tour-stop.js +31 -34
  192. package/dist/tree/item/tree-item.d.ts +30 -35
  193. package/dist/tree/item/tree-item.js +43 -55
  194. package/dist/tree/root/tree-root.d.ts +7 -10
  195. package/dist/tree/root/tree-root.js +33 -42
  196. package/dist/trend/root/trend-root.d.ts +3 -5
  197. package/dist/trend/root/trend-root.js +5 -9
  198. package/dist/video/root/video-root.d.ts +100 -124
  199. package/dist/video/root/video-root.js +142 -176
  200. package/dist/video-playlist/item/video-playlist-item.d.ts +16 -16
  201. package/dist/video-playlist/item/video-playlist-item.js +24 -24
  202. package/dist/video-playlist/menu/video-playlist-menu.d.ts +5 -8
  203. package/dist/video-playlist/menu/video-playlist-menu.js +20 -29
  204. package/dist/video-playlist/root/video-playlist-root.d.ts +16 -11
  205. package/dist/video-playlist/root/video-playlist-root.js +21 -25
  206. package/dist/virtual-list/root/virtual-list-root.d.ts +8 -12
  207. package/dist/virtual-list/root/virtual-list-root.js +11 -16
  208. package/jsx.d.ts +9797 -12561
  209. package/package.json +6 -6
  210. package/vue.d.ts +2684 -3228
@@ -14,8 +14,8 @@ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
14
14
  shifts every attribute after it by one. See `renderTime`. */
15
15
  import { html } from 'lit/static-html.js';
16
16
  /* Side-effect import, because this template interpolates the family's tag and a
17
- custom element registers on import. Both tiers import it, each resolving to
18
- its own; `check:composed` enforces that. */
17
+ custom element registers on import. Both tiers import it, the relative path
18
+ resolving to each tier's own element. */
19
19
  import '../../format-date/index.js';
20
20
  /**
21
21
  * @summary One thing that happened, which a reader may not have seen yet.
@@ -92,16 +92,16 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
92
92
  * Whether a reader may remove it.
93
93
  */
94
94
  this.dismissible = false;
95
+ /**
96
+ * Accessible name for the dismiss control.
97
+ */
98
+ this.dismissLabel = 'Dismiss';
95
99
  /**
96
100
  * Locale for the timestamp.
97
101
  *
98
102
  * Empty is the runtime's own.
99
103
  */
100
104
  this.locale = '';
101
- /**
102
- * Accessible name for the dismiss control.
103
- */
104
- this.dismissLabel = 'Dismiss';
105
105
  /**
106
106
  * @internal Read by the list to identify its children across the light DOM,
107
107
  * which is cheaper than `instanceof` and is why this is public rather than
@@ -130,18 +130,13 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
130
130
  * changes nothing until a new value arrives. `default-read` seeds a state
131
131
  * this element then owns.
132
132
  *
133
- * **Not reflected, and it was until 27 Aug 2026.** The reason given was that
134
- * unread is a visual state and a stylesheet has no other way to know, which
135
- * is the same reason the four mixins mirror theirs, and the mirror may not be
136
- * the property's own attribute: `<helix-notification default-read>`
137
- * came back from a server without `read` and gained it on the first update,
138
- * which React reports as a hydration mismatch, and a copy of the serialized
139
- * element re-parses that attribute as a declaration. `:state(read)` is what
140
- * the stylesheet reads now. Found by `hydration.dom.spec.ts` on the day it
141
- * learned to mount an element a consumer had configured rather than a bare
142
- * one.
143
- *
144
- *
133
+ * **Not reflected.** Unread is a visual state, which is why the four mixins
134
+ * mirror theirs, but the mirror may not be the property's own attribute:
135
+ * `<helix-notification default-read>` comes back from a server without `read`
136
+ * and would gain it on the first update, which React reports as a hydration
137
+ * mismatch, and which a copy of the serialized element re-parses as a
138
+ * declaration. `:state(read)` is what the stylesheet reads.
139
+ * `hydration.dom.spec.ts` holds it.
145
140
  */
146
141
  get read() {
147
142
  return this.readState ?? this.defaultRead;
@@ -205,11 +200,11 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
205
200
  * it.** A fallback answers a consumer and a seam answers the tier above, which
206
201
  * are different people: the styled tier wants an icon here, and with the slot
207
202
  * written inline the only way to change it is to reimplement the whole
208
- * template. `check:fallbacks` holds that, and moving only the fallback out was
209
- * not enough, which is the right rule: the slot is the thing a tier redraws.
203
+ * template. Moving only the fallback out is not enough: the slot is the thing
204
+ * a tier redraws.
210
205
  *
211
- * **The mark is drawn rather than typed, which is what lets it align.** It was
212
- * `&times;`, and a character is placed by its font rather than by its box:
206
+ * **The mark is drawn rather than typed, which is what lets it align.** A
207
+ * character such as `&times;` is placed by its font rather than by its box:
213
208
  * measured against the ghost button beside it at 8x, the cross carried 6
214
209
  * pixels of ink to the label's 9.5 and sat 1.5 pixels below its center, in two
215
210
  * boxes whose own centers agreed to a tenth of a pixel. No stylesheet can
@@ -246,8 +241,7 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
246
241
  *
247
242
  * The tag is interpolated rather than written, so each tier renders its own:
248
243
  * the base tier may not name a styled element, and a styled item inherits this
249
- * template without having a tag of its own to remind anybody. `check:composed`
250
- * holds both halves.
244
+ * template without having a tag of its own to remind anybody.
251
245
  *
252
246
  * `exportparts` and no `part` of its own, which is the rule about a part
253
247
  * already named for its role: the child publishes `time`, the role here is
@@ -293,12 +287,12 @@ __decorate([
293
287
  __decorate([
294
288
  property({ type: Boolean })
295
289
  ], HelixHeadlessNotification.prototype, "dismissible", void 0);
296
- __decorate([
297
- property()
298
- ], HelixHeadlessNotification.prototype, "locale", void 0);
299
290
  __decorate([
300
291
  property({ attribute: 'dismiss-label' })
301
292
  ], HelixHeadlessNotification.prototype, "dismissLabel", void 0);
293
+ __decorate([
294
+ property()
295
+ ], HelixHeadlessNotification.prototype, "locale", void 0);
302
296
  HelixHeadlessNotification = __decorate([
303
297
  customElement('helix-headless-notification')
304
298
  ], HelixHeadlessNotification);
@@ -6,26 +6,22 @@ declare const HelixHeadlessNotifications_base: (new (...args: any[]) => import("
6
6
  * @summary A feed a reader comes back to, made of notifications they may not have seen.
7
7
  *
8
8
  * @description
9
- * **Slotted children rather than a data property**, which is the opposite of the
10
- * choice `helix-data-table` made and correct for the opposite reason. A table's
11
- * rows are homogeneous values a consumer wants windowed; a notification is a
12
- * small piece of somebody's own markup, with an avatar and a link and a button
13
- * in it, and there are tens of them rather than thousands. Writing them out is
14
- * the web-component reading of a list and lets an item hold anything.
9
+ * **Slotted children rather than a data property.** A notification is a small
10
+ * piece of somebody's own markup, with an avatar and a link and a button in it,
11
+ * and there are tens of them rather than thousands, so writing them out lets an
12
+ * item hold anything.
15
13
  *
16
- * **The cost is stated rather than discovered: this does not virtualize, and it
17
- * cannot.** Windowing needs the list to own the data, and here the consumer owns
18
- * it: N notifications is N elements by construction. That is the same trade
19
- * `25-data-table.md` §2.2 rejected for a table and accepts here, because the
20
- * sizes are not comparable. A feed that really does hold thousands wants a data
21
- * table with a custom cell, and this component will not grow into one.
14
+ * **This does not virtualize, and it cannot.** Windowing needs the list to own
15
+ * the data, and here the consumer owns it: N notifications is N elements by
16
+ * construction. A feed that really does hold thousands wants a data table with a
17
+ * custom cell, and this component will not grow into one.
22
18
  *
23
19
  * **Read state is reported, never invented.** Marking read is usually a round
24
20
  * trip: this element asks its items and each item asks the consumer, so a
25
21
  * refused `helix-read` leaves everything alone and a consumer who owns `read`
26
22
  * sees nothing change until they say so. `unread` is derived from the items and
27
- * reflected, so a stylesheet and a badge can both read it without either of them
28
- * counting.
23
+ * written to an attribute, so a stylesheet and a badge can both read it without
24
+ * either of them counting.
29
25
  *
30
26
  * @since 0.1.0
31
27
  * @status experimental
@@ -72,17 +68,15 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
72
68
  /**
73
69
  * How many items are unread, counted from the items themselves.
74
70
  *
75
- * Read-only for the reason it is derived: a count the consumer could set is a
76
- * second source of truth for something the items already know, and the first
77
- * time the two disagreed the badge would be right and the list would not.
71
+ * Read-only because it is derived: a count the consumer could set is a second
72
+ * source of truth for something the items already know.
78
73
  *
79
- * **The attribute is written in `updated` rather than reflected, and the
80
- * difference is a bug that shipped.** `@property({ reflect: true })` on a
81
- * getter with no setter reflects once: Lit reflects what is in
82
- * `changedProperties`, and nothing puts a derived getter there after the first
83
- * update. Measured with two items, one marked read: the property answered 1
84
- * and the attribute still said 2, so a badge reading the attribute showed a
85
- * count for an item the reader had just opened.
74
+ * **The attribute is written in `updated`, never reflected.**
75
+ * `@property({ reflect: true })` on a getter with no setter reflects once: Lit
76
+ * reflects what is in `changedProperties`, and nothing puts a derived getter
77
+ * there after the first update. Measured with two items, one marked read: the
78
+ * property answered 1 and the attribute still said 2, so a badge reading the
79
+ * attribute showed a count for an item the reader had just opened.
86
80
  */
87
81
  get unread(): number;
88
82
  /** The notifications declared as children, in the order they are written. */
@@ -116,11 +110,11 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
116
110
  *
117
111
  * **A fact no item can answer for itself**, which is why it is here. An item
118
112
  * knows about its own media slot and nothing about its neighbors, so a feed
119
- * where some rows have an avatar and some do not drew two different left
120
- * edges for its text and had no way to notice: measured on a four item feed,
121
- * the rows without media started their text 32 pixels to the left of the rows
122
- * with it. The styled tier turns this into a width; this tier ships no
123
- * stylesheet and is unaffected.
113
+ * where some rows have an avatar and some do not draws two different left
114
+ * edges for its text: measured on a four item feed, the rows without media
115
+ * started their text 32 pixels to the left of the rows with it. The styled
116
+ * tier turns this into a width; this tier ships no stylesheet and is
117
+ * unaffected.
124
118
  *
125
119
  * Read off the light DOM rather than off the items, so it does not depend on
126
120
  * which children have upgraded by the time this runs.
@@ -129,16 +123,14 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
129
123
  /**
130
124
  * Says on each region whether anything is in it.
131
125
  *
132
- * **The stylesheet used to ask, and could not.** The rule read
133
- * `[part="header"]:not(:has(> slot:has(*)))`, which is two faults at once.
134
- * `:has()` may not be nested inside `:has()`, so the selector fails to parse
135
- * and the whole rule is discarded; and a slot's assigned nodes are not its DOM
136
- * children, so `slot:has(*)` reports whether the slot has *fallback* rather
137
- * than whether a consumer filled it, and would have been false either way.
138
- * Both verified in a browser: `insertRule` throws a `SyntaxError` on the
139
- * first, and an assigned element still leaves `slot.matches(':has(*)')` false.
140
- * A feed with no header drew its rule under nothing, and one with no footer
141
- * drew another over nothing.
126
+ * **A stylesheet cannot ask this, and the obvious selector fails twice over.**
127
+ * `[part="header"]:not(:has(> slot:has(*)))`: `:has()` may not be nested
128
+ * inside `:has()`, so the selector fails to parse and the whole rule is
129
+ * discarded; and a slot's assigned nodes are not its DOM children, so
130
+ * `slot:has(*)` reports whether the slot has *fallback* rather than whether a
131
+ * consumer filled it, and would have been false either way. Both verified in a
132
+ * browser: `insertRule` throws a `SyntaxError` on the first, and an assigned
133
+ * element still leaves `slot.matches(':has(*)')` false.
142
134
  *
143
135
  * `slotFilled` is what the rest of the library already asks with. It is said
144
136
  * on the region inside this shadow root rather than on the host, because an
@@ -11,26 +11,22 @@ import { property } from 'lit/decorators.js';
11
11
  * @summary A feed a reader comes back to, made of notifications they may not have seen.
12
12
  *
13
13
  * @description
14
- * **Slotted children rather than a data property**, which is the opposite of the
15
- * choice `helix-data-table` made and correct for the opposite reason. A table's
16
- * rows are homogeneous values a consumer wants windowed; a notification is a
17
- * small piece of somebody's own markup, with an avatar and a link and a button
18
- * in it, and there are tens of them rather than thousands. Writing them out is
19
- * the web-component reading of a list and lets an item hold anything.
14
+ * **Slotted children rather than a data property.** A notification is a small
15
+ * piece of somebody's own markup, with an avatar and a link and a button in it,
16
+ * and there are tens of them rather than thousands, so writing them out lets an
17
+ * item hold anything.
20
18
  *
21
- * **The cost is stated rather than discovered: this does not virtualize, and it
22
- * cannot.** Windowing needs the list to own the data, and here the consumer owns
23
- * it: N notifications is N elements by construction. That is the same trade
24
- * `25-data-table.md` §2.2 rejected for a table and accepts here, because the
25
- * sizes are not comparable. A feed that really does hold thousands wants a data
26
- * table with a custom cell, and this component will not grow into one.
19
+ * **This does not virtualize, and it cannot.** Windowing needs the list to own
20
+ * the data, and here the consumer owns it: N notifications is N elements by
21
+ * construction. A feed that really does hold thousands wants a data table with a
22
+ * custom cell, and this component will not grow into one.
27
23
  *
28
24
  * **Read state is reported, never invented.** Marking read is usually a round
29
25
  * trip: this element asks its items and each item asks the consumer, so a
30
26
  * refused `helix-read` leaves everything alone and a consumer who owns `read`
31
27
  * sees nothing change until they say so. `unread` is derived from the items and
32
- * reflected, so a stylesheet and a badge can both read it without either of them
33
- * counting.
28
+ * written to an attribute, so a stylesheet and a badge can both read it without
29
+ * either of them counting.
34
30
  *
35
31
  * @since 0.1.0
36
32
  * @status experimental
@@ -104,17 +100,15 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
104
100
  /**
105
101
  * How many items are unread, counted from the items themselves.
106
102
  *
107
- * Read-only for the reason it is derived: a count the consumer could set is a
108
- * second source of truth for something the items already know, and the first
109
- * time the two disagreed the badge would be right and the list would not.
103
+ * Read-only because it is derived: a count the consumer could set is a second
104
+ * source of truth for something the items already know.
110
105
  *
111
- * **The attribute is written in `updated` rather than reflected, and the
112
- * difference is a bug that shipped.** `@property({ reflect: true })` on a
113
- * getter with no setter reflects once: Lit reflects what is in
114
- * `changedProperties`, and nothing puts a derived getter there after the first
115
- * update. Measured with two items, one marked read: the property answered 1
116
- * and the attribute still said 2, so a badge reading the attribute showed a
117
- * count for an item the reader had just opened.
106
+ * **The attribute is written in `updated`, never reflected.**
107
+ * `@property({ reflect: true })` on a getter with no setter reflects once: Lit
108
+ * reflects what is in `changedProperties`, and nothing puts a derived getter
109
+ * there after the first update. Measured with two items, one marked read: the
110
+ * property answered 1 and the attribute still said 2, so a badge reading the
111
+ * attribute showed a count for an item the reader had just opened.
118
112
  */
119
113
  get unread() {
120
114
  return this.items.filter((item) => !item.read).length;
@@ -123,7 +117,7 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
123
117
  get items() {
124
118
  /* `?? []` is the server. Lit's element shim carries attributes and not a
125
119
  tree, so `children` is undefined there, and this getter is reached from
126
- `unread`, which is reflected and therefore read during the first update. */
120
+ `unread` during the first update. */
127
121
  return [...(this.children ?? [])].filter((child) => 'isNotification' in child && child.isNotification === true);
128
122
  }
129
123
  /**
@@ -178,11 +172,11 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
178
172
  *
179
173
  * **A fact no item can answer for itself**, which is why it is here. An item
180
174
  * knows about its own media slot and nothing about its neighbors, so a feed
181
- * where some rows have an avatar and some do not drew two different left
182
- * edges for its text and had no way to notice: measured on a four item feed,
183
- * the rows without media started their text 32 pixels to the left of the rows
184
- * with it. The styled tier turns this into a width; this tier ships no
185
- * stylesheet and is unaffected.
175
+ * where some rows have an avatar and some do not draws two different left
176
+ * edges for its text: measured on a four item feed, the rows without media
177
+ * started their text 32 pixels to the left of the rows with it. The styled
178
+ * tier turns this into a width; this tier ships no stylesheet and is
179
+ * unaffected.
186
180
  *
187
181
  * Read off the light DOM rather than off the items, so it does not depend on
188
182
  * which children have upgraded by the time this runs.
@@ -193,16 +187,14 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
193
187
  /**
194
188
  * Says on each region whether anything is in it.
195
189
  *
196
- * **The stylesheet used to ask, and could not.** The rule read
197
- * `[part="header"]:not(:has(> slot:has(*)))`, which is two faults at once.
198
- * `:has()` may not be nested inside `:has()`, so the selector fails to parse
199
- * and the whole rule is discarded; and a slot's assigned nodes are not its DOM
200
- * children, so `slot:has(*)` reports whether the slot has *fallback* rather
201
- * than whether a consumer filled it, and would have been false either way.
202
- * Both verified in a browser: `insertRule` throws a `SyntaxError` on the
203
- * first, and an assigned element still leaves `slot.matches(':has(*)')` false.
204
- * A feed with no header drew its rule under nothing, and one with no footer
205
- * drew another over nothing.
190
+ * **A stylesheet cannot ask this, and the obvious selector fails twice over.**
191
+ * `[part="header"]:not(:has(> slot:has(*)))`: `:has()` may not be nested
192
+ * inside `:has()`, so the selector fails to parse and the whole rule is
193
+ * discarded; and a slot's assigned nodes are not its DOM children, so
194
+ * `slot:has(*)` reports whether the slot has *fallback* rather than whether a
195
+ * consumer filled it, and would have been false either way. Both verified in a
196
+ * browser: `insertRule` throws a `SyntaxError` on the first, and an assigned
197
+ * element still leaves `slot.matches(':has(*)')` false.
206
198
  *
207
199
  * `slotFilled` is what the rest of the library already asks with. It is said
208
200
  * on the region inside this shadow root rather than on the host, because an
@@ -211,7 +203,7 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
211
203
  */
212
204
  markEmpty() {
213
205
  /* The header is not empty while this element is drawing its own control into
214
- it, which is the case the old selector spelled with a second `:not`. */
206
+ it. */
215
207
  this.markRegion('header', ['header'], '[part="mark-all"]');
216
208
  this.markRegion('footer', ['footer']);
217
209
  }
@@ -234,21 +226,18 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
234
226
  super.updated(changed);
235
227
  /* Before `markEmpty`, which reads what is assigned: on a feed with no items
236
228
  nothing else ever schedules a second update, so a header asked about
237
- before its slot was filled stayed hidden for the life of the element. The
238
- empty feed is the one state where the header is the only thing on screen,
239
- and it was the one state that lost it. */
229
+ before its slot was filled stays hidden for the life of the element. The
230
+ empty feed is the one state where the header is the only thing on screen. */
240
231
  this.assign();
241
232
  this.markEmpty();
242
233
  this.markMedia();
243
234
  /* Written after the render rather than reflected during it, so it follows
244
- every change rather than only the first, and so the server's output and a
245
- hydrating consumer's markup agree that neither has it yet. */
246
- /* **Zero is the absence of the attribute, not `unread="0"`.** Writing it at
247
- rest put an attribute on the host that a consumer's server never sent, and
248
- the comment above claimed the opposite: writing in `updated` is not "after
249
- hydration", it is the same microtask checkpoint `firstUpdated` runs in,
250
- which is exactly how `data-settled` was a bug on three routes. Only a
251
- departure from resting writes. */
235
+ every change rather than only the first.
236
+
237
+ **Zero is the absence of the attribute, not `unread="0"`.** Writing it at
238
+ rest puts an attribute on the host that a consumer's server never sent,
239
+ and `updated` is no later than hydration: it is the same microtask
240
+ checkpoint `firstUpdated` runs in. Only a departure from resting writes. */
252
241
  const unread = this.unread > 0 ? String(this.unread) : null;
253
242
  if (this.getAttribute('unread') !== unread) {
254
243
  if (unread === null) {
@@ -71,27 +71,19 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
71
71
  * What the browser may autofill here, as one of the platform's own tokens.
72
72
  *
73
73
  * Empty leaves the attribute off, which is the browser's default and is what
74
- * lets autofill work at all. This used to be hardcoded `off`, so a reader
75
- * could never have a birthday or a postal code filled in for them and a
76
- * consumer had no way to ask for it. See 295.
74
+ * lets autofill work at all. Hardcoding `off` here is what stops a reader
75
+ * having a birthday or a postal code filled in for them, with no way for a
76
+ * consumer to ask for it.
77
77
  */
78
78
  autocomplete: string;
79
79
  /**
80
- * Smallest value the reader may reach.
81
- *
82
- * Absent has no floor.
83
- */
84
- min?: number;
85
- /**
86
- * Largest value the reader may reach.
87
- *
88
- * Absent has no ceiling.
80
+ * Accessible name for the control that steps down.
89
81
  */
90
- max?: number;
82
+ decrementLabel: string;
91
83
  /**
92
- * How far one step moves.
84
+ * Accessible name for the control that steps up.
93
85
  */
94
- step: number;
86
+ incrementLabel: string;
95
87
  /**
96
88
  * How far `PageUp` and `PageDown` move.
97
89
  *
@@ -100,6 +92,18 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
100
92
  * what a reader wants from a whole key.
101
93
  */
102
94
  largeStep?: number;
95
+ /**
96
+ * Largest value the reader may reach.
97
+ *
98
+ * Absent has no ceiling.
99
+ */
100
+ max?: number;
101
+ /**
102
+ * Smallest value the reader may reach.
103
+ *
104
+ * Absent has no floor.
105
+ */
106
+ min?: number;
103
107
  /**
104
108
  * Shown while the field is empty.
105
109
  *
@@ -122,13 +126,9 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
122
126
  */
123
127
  scrub: boolean;
124
128
  /**
125
- * Accessible name for the control that steps down.
126
- */
127
- decrementLabel: string;
128
- /**
129
- * Accessible name for the control that steps up.
129
+ * How far one step moves.
130
130
  */
131
- incrementLabel: string;
131
+ step: number;
132
132
  /** Focus is delegated to the field, so the host is never the focus target. */
133
133
  static shadowRootOptions: ShadowRootInit;
134
134
  private get control();
@@ -164,17 +164,15 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
164
164
  /**
165
165
  * The label is the surface, which is where the convention already is.
166
166
  *
167
- * A grip was drawn first, an icon of its own at the leading edge, and it was
168
- * a second control in a field that already has three. Every tool that does
167
+ * Not a grip of its own at the leading edge, which is the obvious answer and
168
+ * is a second control in a field that already has three. Every tool that does
169
169
  * this well drags the *name* of the value: the label is present on every
170
170
  * field, costs no chrome, and a reader who wants to know what they are
171
171
  * dragging is already looking at it.
172
172
  *
173
173
  * Overridden rather than handled on the host, because the handlers have to
174
174
  * sit on the element that takes the capture. The markup is the mixin's, said
175
- * again here, which is the duplication #76 exists to remove: when base
176
- * renders break into methods a styled tier can extend, this becomes a call to
177
- * `super` with three listeners added.
175
+ * again here, which is the duplication #76 exists to remove.
178
176
  *
179
177
  * A label with nothing in it is still nothing. `scrub` on a field whose label
180
178
  * is empty leaves no surface, which is honest: there is nowhere to put the
@@ -221,13 +219,13 @@ export declare class HelixHeadlessNumberInput extends HelixHeadlessNumberInput_b
221
219
  * and filling it with `min` would put a number in a form the reader never
222
220
  * gave.
223
221
  *
224
- * **And text that is not a number is left alone, which this cleared at
225
- * first.** Typing `2.7e` and tabbing away emptied the field: the reader looks
226
- * back and their entry is gone with nothing saying why, and the likeliest
227
- * cause is a fat finger on a number they had almost finished. Nothing is lost
228
- * by keeping it, because `sync` has already marked it `badInput`, so the field
229
- * shows as wrong and the form refuses to submit. Destroying the evidence of a
230
- * mistake is not the same as preventing one.
222
+ * **And text that is not a number is left alone.** Clearing it means typing
223
+ * `2.7e` and tabbing away empties the field: the reader looks back and their
224
+ * entry is gone with nothing saying why, and the likeliest cause is a fat
225
+ * finger on a number they had almost finished. Nothing is lost by keeping it,
226
+ * because `sync` has already marked it `badInput`, so the field shows as wrong
227
+ * and the form refuses to submit. Destroying the evidence of a mistake is not
228
+ * the same as preventing one.
231
229
  */
232
230
  private readonly handleBlur;
233
231
  /** Relayed, because `change` does not cross a shadow boundary on its own. */
@@ -107,15 +107,19 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
107
107
  * What the browser may autofill here, as one of the platform's own tokens.
108
108
  *
109
109
  * Empty leaves the attribute off, which is the browser's default and is what
110
- * lets autofill work at all. This used to be hardcoded `off`, so a reader
111
- * could never have a birthday or a postal code filled in for them and a
112
- * consumer had no way to ask for it. See 295.
110
+ * lets autofill work at all. Hardcoding `off` here is what stops a reader
111
+ * having a birthday or a postal code filled in for them, with no way for a
112
+ * consumer to ask for it.
113
113
  */
114
114
  this.autocomplete = '';
115
115
  /**
116
- * How far one step moves.
116
+ * Accessible name for the control that steps down.
117
117
  */
118
- this.step = 1;
118
+ this.decrementLabel = 'Decrease';
119
+ /**
120
+ * Accessible name for the control that steps up.
121
+ */
122
+ this.incrementLabel = 'Increase';
119
123
  /**
120
124
  * Shown while the field is empty.
121
125
  *
@@ -138,13 +142,9 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
138
142
  */
139
143
  this.scrub = false;
140
144
  /**
141
- * Accessible name for the control that steps down.
142
- */
143
- this.decrementLabel = 'Decrease';
144
- /**
145
- * Accessible name for the control that steps up.
145
+ * How far one step moves.
146
146
  */
147
- this.incrementLabel = 'Increase';
147
+ this.step = 1;
148
148
  /** Where the pointer went down, and what the value was there. */
149
149
  this.scrubFrom = 0;
150
150
  this.scrubValue = 0;
@@ -228,13 +228,13 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
228
228
  * and filling it with `min` would put a number in a form the reader never
229
229
  * gave.
230
230
  *
231
- * **And text that is not a number is left alone, which this cleared at
232
- * first.** Typing `2.7e` and tabbing away emptied the field: the reader looks
233
- * back and their entry is gone with nothing saying why, and the likeliest
234
- * cause is a fat finger on a number they had almost finished. Nothing is lost
235
- * by keeping it, because `sync` has already marked it `badInput`, so the field
236
- * shows as wrong and the form refuses to submit. Destroying the evidence of a
237
- * mistake is not the same as preventing one.
231
+ * **And text that is not a number is left alone.** Clearing it means typing
232
+ * `2.7e` and tabbing away empties the field: the reader looks back and their
233
+ * entry is gone with nothing saying why, and the likeliest cause is a fat
234
+ * finger on a number they had almost finished. Nothing is lost by keeping it,
235
+ * because `sync` has already marked it `badInput`, so the field shows as wrong
236
+ * and the form refuses to submit. Destroying the evidence of a mistake is not
237
+ * the same as preventing one.
238
238
  */
239
239
  this.handleBlur = () => {
240
240
  const control = this.control;
@@ -270,8 +270,8 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
270
270
  else if (event.key === 'PageDown') {
271
271
  this.stepDown(true);
272
272
  /* Guarded the way `nudge` is. A read-only field still receives keydown,
273
- so Home on one with a `min` silently rewrote the value that the arrows
274
- beside it correctly refused to touch. */
273
+ so an unguarded Home on one with a `min` silently rewrites the value
274
+ that the arrows beside it correctly refuse to touch. */
275
275
  }
276
276
  else if (event.key === 'Home' &&
277
277
  this.min !== undefined &&
@@ -322,9 +322,9 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
322
322
  const stepped = anchor + Math.round((value - anchor) / step) * step;
323
323
  const floored = this.min === undefined ? stepped : Math.max(this.min, stepped);
324
324
  const capped = this.max === undefined ? floored : Math.min(this.max, floored);
325
- /* Decimal places from the step and the anchor together: a step of 0.25 from
326
- an anchor of 0.1 lands on 0.35, which needs two rather than the two the
327
- step alone would give by luck. */
325
+ /* Decimal places from the step and the anchor together: a step of 0.5 from
326
+ an anchor of 0.25 lands on 0.75, which needs two rather than the one the
327
+ step alone would give. */
328
328
  const places = Math.max(decimals(step), decimals(anchor));
329
329
  return Number(capped.toFixed(places));
330
330
  }
@@ -365,17 +365,15 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
365
365
  /**
366
366
  * The label is the surface, which is where the convention already is.
367
367
  *
368
- * A grip was drawn first, an icon of its own at the leading edge, and it was
369
- * a second control in a field that already has three. Every tool that does
368
+ * Not a grip of its own at the leading edge, which is the obvious answer and
369
+ * is a second control in a field that already has three. Every tool that does
370
370
  * this well drags the *name* of the value: the label is present on every
371
371
  * field, costs no chrome, and a reader who wants to know what they are
372
372
  * dragging is already looking at it.
373
373
  *
374
374
  * Overridden rather than handled on the host, because the handlers have to
375
375
  * sit on the element that takes the capture. The markup is the mixin's, said
376
- * again here, which is the duplication #76 exists to remove: when base
377
- * renders break into methods a styled tier can extend, this becomes a call to
378
- * `super` with three listeners added.
376
+ * again here, which is the duplication #76 exists to remove.
379
377
  *
380
378
  * A label with nothing in it is still nothing. `scrub` on a field whose label
381
379
  * is empty leaves no surface, which is honest: there is nowhere to put the
@@ -544,17 +542,20 @@ __decorate([
544
542
  property()
545
543
  ], HelixHeadlessNumberInput.prototype, "autocomplete", void 0);
546
544
  __decorate([
547
- property({ type: Number })
548
- ], HelixHeadlessNumberInput.prototype, "min", void 0);
545
+ property({ attribute: 'decrement-label' })
546
+ ], HelixHeadlessNumberInput.prototype, "decrementLabel", void 0);
547
+ __decorate([
548
+ property({ attribute: 'increment-label' })
549
+ ], HelixHeadlessNumberInput.prototype, "incrementLabel", void 0);
550
+ __decorate([
551
+ property({ attribute: 'large-step', type: Number })
552
+ ], HelixHeadlessNumberInput.prototype, "largeStep", void 0);
549
553
  __decorate([
550
554
  property({ type: Number })
551
555
  ], HelixHeadlessNumberInput.prototype, "max", void 0);
552
556
  __decorate([
553
557
  property({ type: Number })
554
- ], HelixHeadlessNumberInput.prototype, "step", void 0);
555
- __decorate([
556
- property({ attribute: 'large-step', type: Number })
557
- ], HelixHeadlessNumberInput.prototype, "largeStep", void 0);
558
+ ], HelixHeadlessNumberInput.prototype, "min", void 0);
558
559
  __decorate([
559
560
  property()
560
561
  ], HelixHeadlessNumberInput.prototype, "placeholder", void 0);
@@ -565,11 +566,8 @@ __decorate([
565
566
  property({ reflect: true, type: Boolean })
566
567
  ], HelixHeadlessNumberInput.prototype, "scrub", void 0);
567
568
  __decorate([
568
- property({ attribute: 'decrement-label' })
569
- ], HelixHeadlessNumberInput.prototype, "decrementLabel", void 0);
570
- __decorate([
571
- property({ attribute: 'increment-label' })
572
- ], HelixHeadlessNumberInput.prototype, "incrementLabel", void 0);
569
+ property({ type: Number })
570
+ ], HelixHeadlessNumberInput.prototype, "step", void 0);
573
571
  HelixHeadlessNumberInput = __decorate([
574
572
  customElement('helix-headless-number-input')
575
573
  ], HelixHeadlessNumberInput);