@fusion.dev/helix-headless 0.2.0 → 0.3.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.
Files changed (127) hide show
  1. package/custom-elements.json +234 -234
  2. package/dist/accordion/item/accordion-item.js +0 -108
  3. package/dist/accordion/root/accordion-root.js +0 -33
  4. package/dist/announcement/root/announcement-root.js +1 -76
  5. package/dist/app-header/root/app-header-root.js +0 -84
  6. package/dist/avatar/group/avatar-group.js +0 -77
  7. package/dist/avatar/root/avatar-root.js +0 -72
  8. package/dist/badge/root/badge-root.js +0 -67
  9. package/dist/bar-chart/root/bar-chart-root.js +3 -263
  10. package/dist/blockquote/root/blockquote-root.js +0 -46
  11. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +0 -72
  12. package/dist/breadcrumbs/root/breadcrumbs-root.js +0 -52
  13. package/dist/button/root/button-root.js +0 -215
  14. package/dist/button-group/root/button-group-root.js +0 -30
  15. package/dist/callout/root/callout-root.js +0 -52
  16. package/dist/card/root/card-root.js +0 -41
  17. package/dist/carousel/root/carousel-root.d.ts +2 -2
  18. package/dist/carousel/root/carousel-root.js +2 -362
  19. package/dist/chat/composer/chat-composer.js +0 -131
  20. package/dist/chat/message/chat-message.js +0 -137
  21. package/dist/chat/root/chat-root.js +0 -193
  22. package/dist/checkbox/root/checkbox-root.js +0 -113
  23. package/dist/checkbox-group/root/checkbox-group-root.js +1 -157
  24. package/dist/code/root/code-root.js +0 -26
  25. package/dist/code-block/root/code-block-root.js +0 -100
  26. package/dist/color-input/root/color-input-root.js +0 -217
  27. package/dist/color-picker/color.js +0 -69
  28. package/dist/color-picker/root/color-picker-root.js +0 -272
  29. package/dist/combobox/root/combobox-root.js +0 -428
  30. package/dist/command/root/command-root.js +0 -177
  31. package/dist/copy-button/root/copy-button-root.js +0 -134
  32. package/dist/data-table/root/data-table-root.js +0 -336
  33. package/dist/data-table/root/order.js +0 -100
  34. package/dist/date-input/root/date-input-root.js +1 -398
  35. package/dist/date-picker/root/date-picker-root.js +0 -358
  36. package/dist/dialog/root/dialog-root.js +0 -189
  37. package/dist/divider/root/divider-root.js +0 -71
  38. package/dist/donut-chart/root/donut-chart-root.js +0 -214
  39. package/dist/drawer/root/drawer-root.js +0 -116
  40. package/dist/drilldown/item/drilldown-item.js +0 -82
  41. package/dist/drilldown/root/drilldown-root.js +0 -91
  42. package/dist/element-events.generated.js +0 -5
  43. package/dist/empty/root/empty-root.js +0 -35
  44. package/dist/file-input/root/file-input-root.js +0 -232
  45. package/dist/format-date/root/format-date-root.js +0 -95
  46. package/dist/heatmap/root/buckets.js +0 -57
  47. package/dist/heatmap/root/heatmap-root.js +0 -313
  48. package/dist/icon/root/icon-root.js +0 -48
  49. package/dist/icon-button/root/icon-button-root.js +0 -30
  50. package/dist/image/root/image-root.js +0 -174
  51. package/dist/index.js +0 -9
  52. package/dist/input/root/input-root.js +0 -228
  53. package/dist/kbd/root/kbd-root.js +0 -117
  54. package/dist/legend/root/legend-root.js +0 -73
  55. package/dist/line-chart/root/line-chart-root.js +0 -172
  56. package/dist/list/item/list-item.js +0 -92
  57. package/dist/list/root/list-root.js +0 -26
  58. package/dist/listbox/root/listbox-root.js +2 -429
  59. package/dist/loader/root/loader-root.js +0 -40
  60. package/dist/megamenu/root/megamenu-root.js +0 -284
  61. package/dist/menu/item/menu-item.js +1 -221
  62. package/dist/menu/root/menu-root.js +1 -171
  63. package/dist/meter/root/meter-root.js +1 -152
  64. package/dist/navigation/root/navigation-root.js +0 -56
  65. package/dist/notifications/notification/notification.js +0 -159
  66. package/dist/notifications/root/notifications-root.js +0 -148
  67. package/dist/number-input/root/number-input-root.js +1 -263
  68. package/dist/option/group/option-group.js +0 -26
  69. package/dist/option/root/option-root.js +0 -157
  70. package/dist/outline/root/outline-root.js +0 -292
  71. package/dist/pagination/root/pagination-root.js +0 -361
  72. package/dist/pagination/size/pagination-size.js +0 -104
  73. package/dist/pagination/summary/pagination-summary.js +0 -90
  74. package/dist/pin-input/root/pin-input-root.js +0 -276
  75. package/dist/popover/root/popover-root.js +0 -103
  76. package/dist/progress/root/progress-root.js +1 -133
  77. package/dist/qr-code/root/qr-code-root.js +0 -96
  78. package/dist/quote/root/quote-root.js +0 -25
  79. package/dist/radio/group/radio-group.js +0 -81
  80. package/dist/radio/root/radio-root.js +0 -85
  81. package/dist/rating/root/rating-root.js +0 -220
  82. package/dist/scroll-area/root/scroll-area-root.js +0 -100
  83. package/dist/select/root/select-root.js +2 -218
  84. package/dist/skeleton/root/skeleton-root.js +0 -20
  85. package/dist/slider/root/slider-root.js +1 -267
  86. package/dist/sparkline/root/sparkline-root.js +3 -164
  87. package/dist/speed-dial/item/speed-dial-item.js +0 -52
  88. package/dist/speed-dial/root/speed-dial-root.js +1 -116
  89. package/dist/splitter/root/splitter-root.js +0 -489
  90. package/dist/stat/group/stat-group.js +0 -18
  91. package/dist/stat/root/stat-root.js +0 -23
  92. package/dist/steps/root/steps-root.js +0 -62
  93. package/dist/steps/step/step.js +0 -131
  94. package/dist/switch/root/switch-root.js +0 -80
  95. package/dist/table/cell/table-cell.js +0 -23
  96. package/dist/table/column/table-column.js +0 -158
  97. package/dist/table/root/table-root.js +0 -82
  98. package/dist/table/row/table-row.js +0 -21
  99. package/dist/tabs/panel/tab-panel.js +0 -49
  100. package/dist/tabs/root/tabs-root.js +0 -98
  101. package/dist/tabs/tab/tab.js +0 -59
  102. package/dist/tag/root/tag-root.js +0 -31
  103. package/dist/textarea/root/textarea-root.js +0 -162
  104. package/dist/time-input/root/time-input-root.js +0 -283
  105. package/dist/time-picker/root/time-picker-root.js +0 -326
  106. package/dist/timeline/item/timeline-item.js +0 -66
  107. package/dist/timeline/root/timeline-root.js +0 -41
  108. package/dist/toast/item/toast-item.js +0 -165
  109. package/dist/toast/root/toast-root.js +0 -51
  110. package/dist/toggle/group/toggle-group.js +0 -150
  111. package/dist/toggle/root/toggle-root.js +0 -78
  112. package/dist/toolbar/root/toolbar-root.js +0 -116
  113. package/dist/tooltip/root/tooltip-root.js +0 -427
  114. package/dist/tour/root/tour-root.js +0 -130
  115. package/dist/tour/stop/tour-stop.js +1 -127
  116. package/dist/tree/item/tree-item.js +0 -198
  117. package/dist/tree/root/tree-root.js +0 -97
  118. package/dist/trend/root/trend-root.js +0 -53
  119. package/dist/video/root/video-root.d.ts +8 -12
  120. package/dist/video/root/video-root.js +5 -756
  121. package/dist/video-playlist/item/video-playlist-item.js +1 -90
  122. package/dist/video-playlist/menu/video-playlist-menu.js +1 -132
  123. package/dist/video-playlist/root/video-playlist-root.js +0 -113
  124. package/dist/virtual-list/root/virtual-list-root.js +0 -105
  125. package/jsx.d.ts +1408 -2576
  126. package/package.json +6 -6
  127. package/vue.d.ts +1 -1
@@ -7,58 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { CommandController, customElement, HelixElement, MixinControllerOpen, onUnlessFalse, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- /**
11
- * @summary A panel that slides in from an edge.
12
- *
13
- * @description
14
- * Takes `MixinControllerOpen`, so `open`, `defaultOpen` and the
15
- * `helix-before-open` and `helix-before-close` requests behave exactly as they
16
- * do on an accordion item, and a consumer already knows the API.
17
- *
18
- * Modal by default, which is three things together and not one: focus is
19
- * trapped inside, Escape and an outside press close it, and the page behind is
20
- * covered. A panel with the look of a modal and none of its behavior is worse
21
- * than an inline one, because it invites the reader to treat it as blocking.
22
- *
23
- * Content stays mounted when closed, so it is in the server's markup and can
24
- * animate. A closed `<dialog>` is already out of the tab order and out of the
25
- * accessibility tree, so nothing here writes `inert`. The `role`, the
26
- * `aria-modal` and the scrim come from the element too, and
27
- * `drawer-root.ssr.spec.ts` asserts the panel carries no hand-written `inert`
28
- * and no hand-written `role`.
29
- *
30
- * Opened declaratively with the platform's invoker attributes:
31
- *
32
- * ```html
33
- * <helix-button commandfor="nav" command="--toggle">Menu</helix-button>
34
- * <helix-drawer id="nav">…</helix-drawer>
35
- * ```
36
- *
37
- * @since 0.1.0
38
- * @status experimental
39
- * @category overlays
40
- * @aliases Sheet, Sidebar, Panel, Off-canvas
41
- * @documentation https://helix.fusion.dev/components/drawer
42
- *
43
- * @slot - The drawer's content.
44
- * @slot header - Content pinned above the scrolling area.
45
- *
46
- * @event {Event} close - Relayed, because the platform's own does not escape.
47
- * @event {HelixBeforeCloseEvent} helix-before-close - Fired before the panel closes, and cancelable.
48
- * @event {HelixBeforeOpenEvent} helix-before-open - Fired before the panel opens. Cancelable: refusing it takes the decision and nothing moves.
49
- * @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
50
- *
51
- * @csspart content - The scrolling content region.
52
- * @csspart header - The header region.
53
- * @csspart panel - The sliding panel.
54
- */
55
10
  let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(HelixElement) {
56
11
  constructor() {
57
12
  super(...arguments);
58
- /* Opened and closed from anywhere on the page, without a line of script:
59
- `<helix-button commandfor="…" command="--show">`. The same three commands
60
- the dialog answers, because they are the same act: a drawer and a dialog
61
- differ in where they sit, not in what opening one means. */
62
13
  this.commands = new CommandController(this, {
63
14
  commands: {
64
15
  '--close': () => this.requestOpen(false),
@@ -66,82 +17,25 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
66
17
  '--toggle': () => this.toggleOpen(),
67
18
  },
68
19
  });
69
- /**
70
- * Accessible name for the panel.
71
- */
72
20
  this.label = '';
73
- /**
74
- * Whether the drawer blocks the page behind it.
75
- *
76
- * Turning this off removes the focus trap and the scrim together, because
77
- * they are one decision: a panel that traps focus without covering the page
78
- * strands the reader, and one that covers without trapping lets them tab
79
- * behind the cover.
80
- *
81
- * Not reflected. It stays `true` by default, since a drawer that silently
82
- * lost its focus trap because a consumer forgot a word would be worse than an
83
- * attribute on the host, and nothing selects on it: the scrim is rendered or
84
- * not, rather than shown or hidden by CSS.
85
- */
86
21
  this.modal = true;
87
- /** What a value set before the element existed is kept in. */
88
22
  this.returned = '';
89
- /**
90
- * Escape, routed through the request so a listener can refuse it.
91
- *
92
- * A native dialog closes itself on Escape, which would shut the drawer while
93
- * the consumer's state still said open: the bug that makes a modal impossible
94
- * to reopen. `Dialog` intercepts it for the same reason.
95
- */
96
23
  this.handleCancel = (event) => {
97
24
  event.preventDefault();
98
25
  this.requestOpen(false);
99
26
  };
100
- /** A close that happened anyway is reflected back rather than argued with. */
101
27
  this.handleClose = (event) => {
102
28
  if (this.open) {
103
29
  this.requestOpen(false);
104
30
  }
105
- /* And under the platform's own name, from the host. `close` on a `<dialog>`
106
- neither bubbles nor is composed, so the one the browser just fired reaches
107
- nobody outside this shadow root, which is the same reason `Avatar` relays
108
- `load`. Announced after the state has moved, so a consumer binding
109
- `onClose` reads a dialog that is already shut.
110
-
111
- `cancel` is deliberately not relayed. `handleCancel` prevents it so that
112
- Escape is a request rather than an act, so the native one never completes:
113
- relaying it would announce a dismissal that was refused. */
114
31
  this.relayNativeEvent(event);
115
32
  };
116
- /**
117
- * A press on the backdrop, which lands on the dialog element itself.
118
- *
119
- * The panel fills only part of the dialog's box, so a press beside it hits
120
- * the dialog and not a child. A native `<dialog>` does not close on that, and
121
- * it is the gesture that most obviously means close.
122
- */
123
33
  this.handleBackdrop = (event) => {
124
34
  if (event.target === this.panel && this.modal) {
125
35
  this.requestOpen(false);
126
36
  }
127
37
  };
128
38
  }
129
- /**
130
- * What the dialog closed with, the way `<dialog>` reports it.
131
- *
132
- * **The whole point of a `<dialog>` returning a value is lost behind a shadow
133
- * boundary**, which is where this one is: `querySelector` does not reach the
134
- * element, so a consumer could neither set the value nor read it back. A
135
- * drawer asking which of its actions dismissed it is the ordinary case and had
136
- * no answer.
137
- *
138
- * Written before `open` is set to false rather than passed to a `close(value)`
139
- * call, because this component has no such method: it is driven by `open`
140
- * alone, and `Dialog`'s `close()` is the one that takes the value directly.
141
- *
142
- * Held here as well as on the element, so a value set before the first render
143
- * survives to it and a consumer reading one back gets what they wrote.
144
- */
145
39
  get returnValue() {
146
40
  return this.panel?.returnValue ?? this.returned;
147
41
  }
@@ -152,18 +46,11 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
152
46
  panel.returnValue = value;
153
47
  }
154
48
  }
155
- /** The panel, which is a real `<dialog>`. */
156
49
  get panel() {
157
50
  return this.renderRoot?.querySelector('[part="panel"]') ?? null;
158
51
  }
159
52
  updated(changed) {
160
53
  super.updated(changed);
161
- /* After render, and only on a difference: `showModal()` on an open dialog
162
- throws and `close()` on a shut one fires a second `close` event.
163
- *
164
- * `showModal` when modal and `show` when not, which is the whole of what
165
- * `modal` means: both put the panel in the top layer, and only the first
166
- * brings a backdrop, a focus trap and `inert` behind it. */
167
54
  const panel = this.panel;
168
55
  if (!panel) {
169
56
  return;
@@ -181,9 +68,6 @@ let HelixHeadlessDrawer = class HelixHeadlessDrawer extends MixinControllerOpen(
181
68
  }
182
69
  }
183
70
  render() {
184
- /* No `role`, no `aria-modal`, no `inert`, no `tabindex`: a `<dialog>` opened
185
- with `showModal()` carries all four, and each hand-written version was a
186
- thing that could drift from what the element actually did. */
187
71
  return html `<dialog
188
72
  part="panel"
189
73
  closedby=${this.closedBy ?? nothing}
@@ -7,88 +7,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- /**
11
- * @summary One row of a drill-down, which may hold a page of its own.
12
- *
13
- * @description
14
- * A row that opens a page *contains* that page: its rows are this row's own
15
- * children, assigned to the `page` slot. The tree is the structure, so there
16
- * are no ids to wire and a consumer who moves a row has moved its page with it.
17
- *
18
- * **It renders one of three things**, and which one is the stack's business
19
- * rather than its own. On the page showing, it is a row. Showing its own page,
20
- * it contributes that page's rows and nothing else, because its row belongs to
21
- * the page above. On neither, it renders nothing at all: the rows are in the
22
- * light DOM and come back untouched, so there is no state to keep and nothing
23
- * to hide with an attribute this element would have to write onto itself.
24
- *
25
- * Choosing is announced, never applied. The row dispatches and the stack
26
- * decides whether that means drilling in or choosing a command.
27
- *
28
- * @since 0.1.0
29
- * @status experimental
30
- * @aliases Panel item, Drill row
31
- * @documentation https://helix.fusion.dev/components/drilldown
32
- *
33
- * @slot - The words naming this row.
34
- * @slot end - After the words, usually a mark or a count.
35
- * @slot page - The rows of the page this one opens.
36
- * @slot start - Before the words, usually an icon.
37
- *
38
- * @event {HelixSelectEvent} helix-select - Fired when the row is chosen. Cancelable: refusing it takes the decision and nothing moves.
39
- *
40
- * @csspart item - The row itself.
41
- * @csspart label - The words.
42
- */
43
10
  let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixElement {
44
11
  constructor() {
45
12
  super(...arguments);
46
- /**
47
- * Whether the row can be reached at all.
48
- */
49
13
  this.disabled = false;
50
- /**
51
- * Whether this row holds the region's tab stop. Written by the stack.
52
- *
53
- * A drill-down keeps one stop and moves within it on the arrows, so every
54
- * other row is at `-1`. Leave it off every row, including the first, and
55
- * nothing in the region is tab-reachable: the keyboard cannot get in without
56
- * first clicking something with a pointer.
57
- *
58
- * No attribute, the same as `Button`'s: this is coordination between
59
- * elements, and writing `tabindex` onto a host the consumer rendered is a
60
- * change a React consumer's hydration reports and does not patch up. The stop
61
- * lands inside this shadow root instead.
62
- */
63
14
  this.focusable = false;
64
- /**
65
- * @internal Read by a parent to identify its children across the light DOM,
66
- * which is cheaper than `instanceof` and is why this is public rather than
67
- * protected. Not a consumer's to read or set.
68
- */
69
15
  this.isDrilldownItem = true;
70
- /**
71
- * Whether the page showing is the one this row is on.
72
- *
73
- * Written by the stack.
74
- */
75
16
  this.onPage = true;
76
- /**
77
- * Whether this row's own page is the one showing.
78
- *
79
- * Written by the stack.
80
- */
81
17
  this.showingPage = false;
82
- /**
83
- * Identifies the row to whatever is listening.
84
- */
85
18
  this.value = '';
86
19
  }
87
- /** Moves focus onto the row itself. */
88
20
  focusItem() {
89
21
  this.renderRoot.querySelector('[part="item"]')?.focus();
90
22
  }
91
- /** Announces that this row was chosen. */
92
23
  select() {
93
24
  if (this.disabled) {
94
25
  return;
@@ -102,19 +33,6 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
102
33
  if (!this.onPage) {
103
34
  return nothing;
104
35
  }
105
- /* A real `<button>`, and `role="menuitem"` on it.
106
- *
107
- * A `<div role="button">` with a click handler cannot be activated from the
108
- * keyboard: Enter and Space are behavior the platform gives a real button
109
- * and gives nothing else. Same argument `Button` makes for rendering one
110
- * rather than reproducing it.
111
- *
112
- * `menuitem` because the stack says `role="menu"`, and a menu whose
113
- * children are buttons is not a menu: a reader would be told the count of
114
- * items by one role and the kind of them by the other.
115
- *
116
- * `aria-disabled` rather than `disabled`, so a row that cannot be chosen is
117
- * still reachable and still announces why. `select()` is what refuses. */
118
36
  return html `<button
119
37
  part="item"
120
38
  type="button"
@@ -10,67 +10,16 @@ import { html, nothing } from 'lit';
10
10
  import { property, state } from 'lit/decorators.js';
11
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
12
  import { HelixHeadlessDrilldownItem } from '../item/drilldown-item.js';
13
- /**
14
- * @summary A stack of pages, one showing at a time, with a way back.
15
- *
16
- * @description
17
- * One panel that changes rather than panels opening beside each other. That is
18
- * the right shape wherever there is no room for a second column: a phone has
19
- * none, and a touch screen has no hover to open one with.
20
- *
21
- * **Not a `Menu`, and the difference is what it is for rather than how it
22
- * looks.** A menu is a thing that opens from a trigger and closes when it is
23
- * done; this is a region that sits where it is put, inside a drawer or a
24
- * sidebar or a settings panel. `Menu` drills too, through the same controller,
25
- * because a menu deep enough to need pages wants exactly this behavior without
26
- * being this component.
27
- *
28
- * **Navigation, never a value.** Rows are places to go and commands to run, so
29
- * nothing here is form-associated and nothing is submitted. A drill-down that
30
- * reported a value would be a `Listbox` whose options happen to nest, and that
31
- * is the component to reach for instead.
32
- *
33
- * **The tree is the state.** A row that opens a page contains that page, so the
34
- * stack holds one reference and reads the rest from the DOM. See
35
- * `DrilldownController`, which is where this behavior lives and which `Menu`
36
- * shares.
37
- *
38
- * @since 0.1.0
39
- * @status experimental
40
- * @category navigation
41
- * @aliases Panel, Nested list, Drill-in
42
- * @documentation https://helix.fusion.dev/components/drilldown
43
- *
44
- * @slot - The rows of the top page.
45
- *
46
- * @event {HelixSelectEvent} helix-select - Fired when a row with no page is chosen. Cancelable: refusing it takes the decision and nothing moves.
47
- *
48
- * @csspart back - The control that returns one page.
49
- * @csspart back-mark - The glyph on the back control.
50
- * @csspart empty - Shown when there are no entries to show.
51
- * @csspart header - The bar above a page, holding the way back and its name.
52
- * @csspart loading - Shown while the entries are still on their way.
53
- * @csspart page - The region the rows are in.
54
- * @csspart title - The name of the page showing.
55
- */
56
13
  let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollection(HelixElement) {
57
14
  constructor() {
58
15
  super(...arguments);
59
- /**
60
- * Accessible name for the region.
61
- */
62
16
  this.label = 'Navigation';
63
- /**
64
- * What the control returning from a page reads.
65
- */
66
17
  this.backLabel = 'Back';
67
18
  this.drilldown = new DrilldownController(this, {
68
19
  isRow: (element) => 'isDrilldownItem' in element && element.isDrilldownItem === true,
69
20
  root: () => [...this.children],
70
21
  slot: 'page',
71
22
  });
72
- /* The stop follows the reader. Arrowing to a row and tabbing away and back
73
- should return to where they were, not to the top of the page. */
74
23
  this.handleFocusIn = (event) => {
75
24
  const item = this.drilldown.rows.find((row) => row.contains(event.target));
76
25
  if (item && !item.disabled) {
@@ -84,10 +33,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
84
33
  if (!(item instanceof HelixHeadlessDrilldownItem) || !this.items.includes(item)) {
85
34
  return;
86
35
  }
87
- /* A row with a page drills rather than announcing. The event is stopped so
88
- a consumer listening for a choice does not hear navigation as one: going
89
- somewhere and choosing something are different acts, and a consumer that
90
- had to tell them apart would be doing the stack's job. */
91
36
  if (this.drilldown.hasPage(item)) {
92
37
  event.stopPropagation();
93
38
  this.enter(item);
@@ -108,8 +53,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
108
53
  (event.key === 'Home' ? items[0] : items[items.length - 1])?.focusItem();
109
54
  return;
110
55
  }
111
- /* Left and Escape both go back, and neither closes anything: this is a
112
- region rather than an overlay, so there is nothing above it to close. */
113
56
  if (event.key === 'ArrowLeft' || event.key === 'Escape') {
114
57
  if (this.back()) {
115
58
  event.preventDefault();
@@ -126,21 +69,9 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
126
69
  }
127
70
  };
128
71
  }
129
- /** The rows on the page showing, which is what the keys move over. */
130
72
  get items() {
131
73
  return this.drilldown.rows.filter((item) => !item.disabled);
132
74
  }
133
- /**
134
- * Puts the region's one tab stop on the first row of the page showing.
135
- *
136
- * One row holds the stop and the arrows move within, which is the roving
137
- * pattern the toolbar uses and the one a `menu` wants. Every row at `-1` is
138
- * a region the keyboard cannot get into at all without a pointer first.
139
- *
140
- * Called after every update, because the set changes with the page: drilling
141
- * in replaces the rows outright, and the stop has to land on rows that are
142
- * actually showing.
143
- */
144
75
  placeTabStop() {
145
76
  const items = this.items;
146
77
  const held = items.find((item) => item.focusable);
@@ -149,7 +80,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
149
80
  item.focusable = item === stop;
150
81
  }
151
82
  }
152
- /** Shows a row's page, and puts focus on the first row of it. */
153
83
  enter(item) {
154
84
  if (!this.drilldown.enter(item)) {
155
85
  return;
@@ -157,14 +87,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
157
87
  this.direction = 'forward';
158
88
  this.updateComplete.then(() => this.items[0]?.focusItem());
159
89
  }
160
- /**
161
- * Returns one page, and reports whether there was one to return to.
162
- *
163
- * Focus lands on the row that opened the page being left, which is why the
164
- * row is read before going back rather than after: a reader who drills in and
165
- * comes straight out should be on the row they pressed, not at the top of a
166
- * list they have already read.
167
- */
168
90
  back() {
169
91
  const leaving = this.drilldown.page;
170
92
  if (!this.drilldown.back()) {
@@ -176,12 +98,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
176
98
  }
177
99
  connectedCallback() {
178
100
  super.connectedCallback();
179
- /* Capture, and that is not a detail. A consumer listens on this host too,
180
- so a bubble-phase listener here is a sibling of theirs: `stopPropagation`
181
- does nothing to another listener on the same node, and whether the
182
- navigation is swallowed comes down to which was registered first.
183
- Capture reaches the host before the row it came from, so stopping there
184
- stops it for everyone, whatever order anybody bound in. */
185
101
  this.addEventListener('helix-select', this.handleSelect, true);
186
102
  this.addEventListener('keydown', this.handleKeydown);
187
103
  this.addEventListener('focusin', this.handleFocusIn);
@@ -198,9 +114,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
198
114
  }
199
115
  updated(changed) {
200
116
  super.updated(changed);
201
- /* Which rows are on the page showing, written onto the rows themselves
202
- because only the stack knows: a row cannot see its own depth. Client
203
- only, since the server has no tree to walk. */
204
117
  const page = this.drilldown.page;
205
118
  for (const child of this.children) {
206
119
  if (!(child instanceof HelixHeadlessDrilldownItem)) {
@@ -217,7 +130,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
217
130
  this.setAttribute('data-direction', this.direction);
218
131
  }
219
132
  }
220
- /** Walks the tree marking which rows are on the page showing. */
221
133
  mark(item, page, onPage) {
222
134
  item.onPage = onPage;
223
135
  item.showingPage = item === page;
@@ -246,9 +158,6 @@ let HelixHeadlessDrilldown = class HelixHeadlessDrilldown extends MixinCollectio
246
158
  };
247
159
  __decorate([
248
160
  property()
249
- /* Not "Menu". This component's own description is built around not being one,
250
- and a default accessible name is the one place that claim reaches a
251
- reader. */
252
161
  ], HelixHeadlessDrilldown.prototype, "label", void 0);
253
162
  __decorate([
254
163
  property({ attribute: 'back-label' })
@@ -1,8 +1,3 @@
1
- /* Generated by `bun run gen:element-events` from this package's manifest. Do not edit.
2
- *
3
- * Which events each tag dispatches, registered so the React prop audit can tell
4
- * a handler on the wrong element from one on the right one. See
5
- * `helix/core/src/events/element-events.ts`. */
6
1
  import { registerElementEvents } from '@fusion.dev/helix-core';
7
2
  registerElementEvents({
8
3
  'helix-headless-accordion-item': ['helix-before-close', 'helix-before-open', 'toggle'],
@@ -7,44 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, hostAria } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- /**
11
- * @summary Says that a region has nothing in it, and what to do about it.
12
- *
13
- * @description
14
- * An empty region with no explanation is indistinguishable from one that failed
15
- * to load, so this exists to tell the difference: what would be here, and the
16
- * one action that would put something here.
17
- *
18
- * `role="status"` on a polite live region, because an empty view usually
19
- * arrives in place of content that was being fetched. Announcing it is the only
20
- * way a screen-reader user learns the search returned nothing, rather than
21
- * being left waiting.
22
- *
23
- * Every region is a bare slot. The reference ships an `empty-state-heading` and
24
- * an `empty-state-actions` whose only job is to assign themselves a slot on
25
- * connect, which is a component for something the consumer can write.
26
- *
27
- * @since 0.1.0
28
- * @status stable
29
- * @category feedback
30
- * @aliases Placeholder, NoResults, Blank
31
- * @documentation https://helix.fusion.dev/components/empty
32
- *
33
- * @slot - Why, and what to do about it.
34
- * @slot actions - The way out.
35
- * @slot heading - What is missing.
36
- * @slot icon - A mark above the heading.
37
- */
38
10
  let HelixHeadlessEmpty = class HelixHeadlessEmpty extends HelixElement {
39
11
  constructor() {
40
12
  super(...arguments);
41
- /**
42
- * Whether the state is announced when it appears.
43
- *
44
- * On by default: an empty view almost always replaces something that was
45
- * loading. Turn it off for one that was on the page from the start, which
46
- * has nothing to announce because nothing changed.
47
- */
48
13
  this.noAnnounce = false;
49
14
  }
50
15
  willUpdate(changed) {