@fusion.dev/helix-headless 0.53.0 → 0.53.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 (77) hide show
  1. package/custom-elements.json +141 -141
  2. package/dist/accordion/item/accordion-item.d.ts +13 -13
  3. package/dist/accordion/root/accordion-root.d.ts +1 -1
  4. package/dist/area-chart/root/area-chart-root.js +1 -1
  5. package/dist/avatar/group/avatar-group.d.ts +11 -11
  6. package/dist/bar-chart/root/bar-chart-root.d.ts +1 -1
  7. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +6 -6
  8. package/dist/button/root/button-root.d.ts +1 -1
  9. package/dist/card/root/card-root.d.ts +1 -1
  10. package/dist/carousel/root/carousel-root.d.ts +14 -14
  11. package/dist/chat/composer/chat-composer.d.ts +6 -6
  12. package/dist/chat/root/chat-root.d.ts +9 -9
  13. package/dist/checkbox/root/checkbox-root.d.ts +2 -2
  14. package/dist/checkbox/root/checkbox-root.js +1 -1
  15. package/dist/code-block/root/code-block-root.d.ts +5 -5
  16. package/dist/color-input/root/color-input-root.d.ts +3 -3
  17. package/dist/color-picker/root/color-picker-root.d.ts +14 -14
  18. package/dist/combobox/root/combobox-root.d.ts +25 -5
  19. package/dist/combobox/root/combobox-root.js +6 -4
  20. package/dist/command/root/command-root.d.ts +6 -7
  21. package/dist/data-table/root/data-table-root.d.ts +61 -38
  22. package/dist/data-table/root/data-table-root.js +8 -3
  23. package/dist/data-table/root/order.d.ts +3 -3
  24. package/dist/date-input/root/date-input-root.d.ts +12 -11
  25. package/dist/dialog/root/dialog-root.d.ts +4 -4
  26. package/dist/drawer/root/drawer-root.d.ts +5 -5
  27. package/dist/filter-input/menu/filter-menu.d.ts +7 -1
  28. package/dist/filter-input/menu/filter-menu.js +2 -1
  29. package/dist/filter-input/root/filter-input-root.d.ts +6 -6
  30. package/dist/format-date/root/format-date-root.d.ts +6 -5
  31. package/dist/heatmap/root/heatmap-root.d.ts +11 -16
  32. package/dist/image/root/image-root.d.ts +4 -4
  33. package/dist/input/root/input-root.d.ts +7 -7
  34. package/dist/line-chart/root/line-chart-root.d.ts +1 -2
  35. package/dist/list/item/list-item.d.ts +6 -7
  36. package/dist/list/root/list-root.d.ts +4 -4
  37. package/dist/megamenu/root/megamenu-root.d.ts +4 -4
  38. package/dist/notifications/notification/notification.d.ts +10 -10
  39. package/dist/notifications/root/notifications-root.d.ts +1 -1
  40. package/dist/option/root/option-root.d.ts +3 -3
  41. package/dist/pagination/root/pagination-root.d.ts +2 -2
  42. package/dist/pin-input/root/pin-input-root.d.ts +4 -4
  43. package/dist/popover/root/popover-root.d.ts +7 -6
  44. package/dist/radio/root/radio-root.d.ts +12 -2
  45. package/dist/radio/root/radio-root.js +5 -1
  46. package/dist/select/root/select-root.d.ts +24 -0
  47. package/dist/select/root/select-root.js +4 -1
  48. package/dist/speed-dial/root/speed-dial-root.d.ts +8 -9
  49. package/dist/stat/root/stat-root.d.ts +3 -3
  50. package/dist/steps/root/steps-root.d.ts +1 -1
  51. package/dist/steps/step/step.d.ts +5 -5
  52. package/dist/switch/root/switch-root.js +1 -1
  53. package/dist/table/column/table-column.d.ts +28 -28
  54. package/dist/table/root/table-root.d.ts +14 -17
  55. package/dist/table/row/table-row.d.ts +4 -4
  56. package/dist/tabs/panel/tab-panel.d.ts +2 -2
  57. package/dist/tabs/root/tabs-root.js +11 -4
  58. package/dist/tabs/tab/tab.d.ts +11 -1
  59. package/dist/tabs/tab/tab.js +5 -1
  60. package/dist/time-input/root/time-input-root.d.ts +13 -13
  61. package/dist/time-picker/root/time-picker-root.d.ts +8 -8
  62. package/dist/toast/root/toast-root.d.ts +2 -2
  63. package/dist/toggle/root/toggle-root.d.ts +16 -6
  64. package/dist/toggle/root/toggle-root.js +5 -1
  65. package/dist/tooltip/root/tooltip-root.d.ts +2 -2
  66. package/dist/tour/stop/tour-stop.d.ts +3 -3
  67. package/dist/tree/item/tree-item.d.ts +2 -2
  68. package/dist/tree/item/tree-item.js +4 -3
  69. package/dist/tree/root/tree-root.d.ts +8 -7
  70. package/dist/tree/root/tree-root.js +9 -5
  71. package/dist/video-playlist/menu/video-playlist-menu.d.ts +7 -1
  72. package/dist/video-playlist/menu/video-playlist-menu.js +4 -2
  73. package/dist/video-playlist/root/video-playlist-root.d.ts +5 -5
  74. package/dist/video-playlist/root/video-playlist-root.js +2 -3
  75. package/package.json +5 -5
  76. package/types/jsx.d.ts +754 -780
  77. package/types/vue.d.ts +172 -185
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type TemplateResult } from 'lit';
2
+ import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessToggle_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
4
4
  /**
5
5
  * @summary One option in a toggle group.
@@ -37,11 +37,11 @@ export declare class HelixHeadlessToggle extends HelixHeadlessToggle_base {
37
37
  * **The attribute, read when it is asked for, and never a snapshot taken in
38
38
  * the constructor.** A field initializer runs there, and an element the HTML
39
39
  * parser created has none of its attributes yet at that moment: measured on
40
- * this element, on `Option` and on `Radio`, `<helix-toggle value="light"
41
- * selected>` reported `defaultSelected` as `false` both from parsed markup
42
- * and from `createElement` followed by `setAttribute`, which is every way a
43
- * consumer writes one. The snapshot could only ever be true for an element
44
- * already in the document when `customElements.define` ran.
40
+ * this element, on `Option` and on `Radio`, `<helix-headless-toggle
41
+ * value="light" selected>` reported `defaultSelected` as `false` both from
42
+ * parsed markup and from `createElement` followed by `setAttribute`, which is
43
+ * every way a consumer writes one. The snapshot could only ever be true for
44
+ * an element already in the document when `customElements.define` ran.
45
45
  *
46
46
  * Nothing overwrites it either, which is what makes reading it late correct
47
47
  * rather than merely later: `selected` does not reflect, for the reason
@@ -65,6 +65,16 @@ export declare class HelixHeadlessToggle extends HelixHeadlessToggle_base {
65
65
  * hydration reports and does not patch up.
66
66
  */
67
67
  focusable: boolean;
68
+ /**
69
+ * Asks for the render that follows a hydration, so the stop stops being every
70
+ * choice's.
71
+ *
72
+ * `tabindex` reads `childrenKnown` and a hydrating render is one where that is
73
+ * false, which is what keeps the hydrating render the server's. Nothing else
74
+ * would ask: the group writes an already-false `focusable` onto every choice
75
+ * but one, which changes nothing and so re-renders nothing.
76
+ */
77
+ protected firstUpdated(changed: PropertyValues): void;
68
78
  protected render(): TemplateResult;
69
79
  }
70
80
  declare global {
@@ -18,6 +18,10 @@ let HelixHeadlessToggle = class HelixHeadlessToggle extends MixinSelectableItem(
18
18
  set defaultSelected(next) {
19
19
  this.toggleAttribute('selected', next);
20
20
  }
21
+ firstUpdated(changed) {
22
+ super.firstUpdated(changed);
23
+ this.finishHydration();
24
+ }
21
25
  render() {
22
26
  return html `<button
23
27
  part="item"
@@ -25,7 +29,7 @@ let HelixHeadlessToggle = class HelixHeadlessToggle extends MixinSelectableItem(
25
29
  role="radio"
26
30
  aria-checked=${this.selected ? 'true' : 'false'}
27
31
  ?disabled=${this.disabled}
28
- tabindex=${this.selected || this.focusable ? '0' : '-1'}
32
+ tabindex=${this.selected || this.focusable || !this.childrenKnown ? '0' : '-1'}
29
33
  @click=${() => this.select()}
30
34
  >
31
35
  <slot></slot>
@@ -21,8 +21,8 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
21
21
  * the ordinary way:
22
22
  *
23
23
  * ```html
24
- * <helix-button id="save" aria-describedby="save-tip">Save</helix-button>
25
- * <helix-tooltip id="save-tip" for="save" content="Save your work"></helix-tooltip>
24
+ * <helix-headless-button id="save" aria-describedby="save-tip">Save</helix-headless-button>
25
+ * <helix-headless-tooltip id="save-tip" for="save" content="Save your work"></helix-headless-tooltip>
26
26
  * ```
27
27
  *
28
28
  * The reference points at *this host*, not at the bubble in its shadow root:
@@ -20,9 +20,9 @@ import '../../button/index.js';
20
20
  * - **When it shows.** Which is `current`, and which the root decides.
21
21
  *
22
22
  * What it does not own is the heading, the paragraph, the picture and the
23
- * layout. Slot a `helix-card`, or a heading and a line of prose, or anything
24
- * else. Fixed `title` and `body` parts would be a component deciding what a
25
- * tour is allowed to say.
23
+ * layout. Slot a `Card`, or a heading and a line of prose, or anything else.
24
+ * Fixed `title` and `body` parts would be a component deciding what a tour is
25
+ * allowed to say.
26
26
  *
27
27
  * **The buttons are slot fallback, so the common case costs nothing and the
28
28
  * uncommon one is possible.** Write nothing and get Back, Next and Skip already
@@ -186,8 +186,8 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
186
186
  * holds it instead, where it is not in the DOM at all.
187
187
  *
188
188
  * Reading `selected` is unaffected and so is writing it: the attribute still
189
- * seeds the property, which is what `<helix-tree-item selected>` in a consumer's
190
- * markup means. What stops is the write back.
189
+ * seeds the property, which is what `<helix-headless-tree-item selected>` in
190
+ * a consumer's markup means. What stops is the write back.
191
191
  */
192
192
  protected willUpdate(changed: PropertyValues): void;
193
193
  protected render(): TemplateResult;
@@ -104,14 +104,15 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
104
104
  render() {
105
105
  const linked = this.href !== '';
106
106
  const level = this.level ?? 1;
107
+ const depth = this.level ?? nothing;
107
108
  const expanded = this.branch ? (this.open ? 'true' : 'false') : nothing;
108
- const tabIndex = this.focusable ? '0' : '-1';
109
+ const tabIndex = this.focusable || !this.childrenKnown ? '0' : '-1';
109
110
  return html `<div
110
111
  part="item"
111
112
  role=${linked ? 'none' : 'treeitem'}
112
113
  aria-expanded=${linked ? nothing : expanded}
113
114
  aria-selected=${linked ? nothing : this.selected ? 'true' : 'false'}
114
- aria-level=${linked ? nothing : level}
115
+ aria-level=${linked ? nothing : depth}
115
116
  tabindex=${linked ? nothing : tabIndex}
116
117
  >
117
118
  ${linked
@@ -123,7 +124,7 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
123
124
  rel=${this.rel || nothing}
124
125
  aria-expanded=${expanded}
125
126
  aria-selected=${this.selected ? 'true' : 'false'}
126
- aria-level=${level}
127
+ aria-level=${depth}
127
128
  tabindex=${tabIndex}
128
129
  style="--tree-level: ${level}"
129
130
  @click=${this.handleRowClick}
@@ -74,14 +74,15 @@ export declare class HelixHeadlessTree extends HelixHeadlessTree_base {
74
74
  /**
75
75
  * Every item, in the order a reader moving down would meet them.
76
76
  *
77
- * Selected by tag, never by `'*'` and a filter: this is the array a single
78
- * arrow press rebuilds, and `'*'` makes it every descendant element in the
79
- * tree, labels and icons and whatever a consumer slotted into a row included.
77
+ * **By identity rather than by tag**, which is the same reason Splitter
78
+ * writes out at `findOuter`: a tag list names one tier's element from the
79
+ * other's package, and misses any third tag, which is exactly what
80
+ * subclassing an item produces. The item then never enters the array a single
81
+ * arrow press rebuilds, so it is silently unreachable from the keyboard.
80
82
  *
81
- * The two tag names rather than `instanceof` on everything: a styled
82
- * `helix-tree-item` extends the base, so both names are needed, and the
83
- * `instanceof` stays as the type guard because a consumer can write either
84
- * tag and neither selector proves what the element is.
83
+ * `'*'` and a filter rather than a tag: the walk is one native pass and the
84
+ * `instanceof` is what narrows it, so the labels, icons and whatever a
85
+ * consumer slotted into a row are gone by the time the array exists.
85
86
  */
86
87
  private get items();
87
88
  /** Items a reader can actually reach: not inside a collapsed branch. */
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { closestInstance, customElement, HelixElement, inlineStep, MixinCollection, MixinControllerActive, scrollItemIntoView, } from '@fusion.dev/helix-core';
7
+ import { closestInstance, customElement, HelixElement, inlineStep, MixinCollection, MixinControllerActive, scrollItemIntoView, whenHydrated, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import { HelixHeadlessTreeItem } from '../item/tree-item.js';
@@ -81,7 +81,7 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
81
81
  };
82
82
  }
83
83
  get items() {
84
- return [...this.querySelectorAll('helix-tree-item, helix-headless-tree-item')].filter((node) => node instanceof HelixHeadlessTreeItem);
84
+ return [...this.querySelectorAll('*')].filter((node) => node instanceof HelixHeadlessTreeItem);
85
85
  }
86
86
  get visibleItems() {
87
87
  return this.items.filter((item) => {
@@ -101,8 +101,8 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
101
101
  const held = visible.find((item) => item.focusable);
102
102
  const stop = held ?? chosen;
103
103
  for (const item of this.items) {
104
- item.selected = item.value !== '' && item.value === this.active;
105
- item.focusable = item === stop;
104
+ const selected = item.value !== '' && item.value === this.active;
105
+ const focusable = item === stop;
106
106
  let level = 1;
107
107
  let parent = item.parentElement;
108
108
  while (parent && parent !== this) {
@@ -111,7 +111,11 @@ let HelixHeadlessTree = class HelixHeadlessTree extends MixinCollection(MixinCon
111
111
  }
112
112
  parent = parent.parentElement;
113
113
  }
114
- item.level = level;
114
+ whenHydrated(item, () => {
115
+ item.selected = selected;
116
+ item.focusable = focusable;
117
+ item.level = level;
118
+ });
115
119
  }
116
120
  }
117
121
  move(from, delta) {
@@ -61,7 +61,13 @@ export declare class HelixHeadlessVideoPlaylistMenu extends HelixElement {
61
61
  private foundPlaylist;
62
62
  /** The playlist this menu belongs to, found upward through the slots. */
63
63
  private get playlist();
64
- /** The playlist's entries, in the order it holds them. */
64
+ /**
65
+ * The playlist's entries, in the order it holds them.
66
+ *
67
+ * By identity rather than by tag, the same reason the playlist itself reads
68
+ * them that way: a tag list names one tier's element from the other's package
69
+ * and misses any third one.
70
+ */
65
71
  private get entries();
66
72
  /**
67
73
  * Watches the playlist for entries arriving, and re-reads it on every open.
@@ -9,9 +9,9 @@ import { list } from '@fusion.dev/helix-icons';
9
9
  import { nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { html } from 'lit/static-html.js';
12
+ import { HelixHeadlessVideoPlaylistItem } from '../item/video-playlist-item.js';
12
13
  import { HelixHeadlessVideoPlaylist } from '../root/video-playlist-root.js';
13
14
  import '../../menu/index.js';
14
- const ITEMS = 'helix-video-playlist-item, helix-headless-video-playlist-item';
15
15
  let HelixHeadlessVideoPlaylistMenu = class HelixHeadlessVideoPlaylistMenu extends HelixElement {
16
16
  constructor() {
17
17
  super(...arguments);
@@ -39,7 +39,9 @@ let HelixHeadlessVideoPlaylistMenu = class HelixHeadlessVideoPlaylistMenu extend
39
39
  }
40
40
  get entries() {
41
41
  const playlist = this.playlist;
42
- return playlist ? [...playlist.querySelectorAll(ITEMS)] : [];
42
+ return playlist
43
+ ? [...playlist.querySelectorAll('*')].filter((one) => one instanceof HelixHeadlessVideoPlaylistItem)
44
+ : [];
43
45
  }
44
46
  watch() {
45
47
  this.foundPlaylist ??= closestInstance(this, HelixHeadlessVideoPlaylist) ?? undefined;
@@ -35,7 +35,7 @@ declare const HelixHeadlessVideoPlaylist_base: (new (...args: any[]) => import("
35
35
  * @documentation https://fusion.dev/helix/components/video-playlist
36
36
  *
37
37
  * @slot - The entries.
38
- * @slot player - The `helix-video` they play in.
38
+ * @slot player - The player the entries take turns in.
39
39
  *
40
40
  * @event {HelixActivateEvent} helix-activate - Fired once the current one has moved, so the element already holds it.
41
41
  * @event {HelixBeforeActivateEvent} helix-before-activate - Fired before the current entry changes, and cancelable.
@@ -80,10 +80,10 @@ export declare class HelixHeadlessVideoPlaylist extends HelixHeadlessVideoPlayli
80
80
  /**
81
81
  * The player, whichever tag the consumer slotted.
82
82
  *
83
- * Asked of the slot rather than matched by tag name: the headless tier's
84
- * player is `helix-headless-video` and the styled tier's is `helix-video`, and
85
- * a consumer bringing a third under either name should still be driven. What
86
- * is needed of it is `src`, which is the whole of the contract.
83
+ * Asked of the slot rather than matched by tag name: each tier registers its
84
+ * own player under its own name, and a consumer bringing a third should still
85
+ * be driven. What is needed of it is `src`, which is the whole of the
86
+ * contract.
87
87
  */
88
88
  private get player();
89
89
  /** Moves by one, and does nothing at either end. */
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { customElement, HelixElement, MixinControllerActive } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
+ import { HelixHeadlessVideoPlaylistItem } from '../item/video-playlist-item.js';
10
11
  let HelixHeadlessVideoPlaylist = class HelixHeadlessVideoPlaylist extends MixinControllerActive(HelixElement) {
11
12
  constructor() {
12
13
  super(...arguments);
@@ -34,9 +35,7 @@ let HelixHeadlessVideoPlaylist = class HelixHeadlessVideoPlaylist extends MixinC
34
35
  };
35
36
  }
36
37
  get items() {
37
- return [
38
- ...this.querySelectorAll('helix-video-playlist-item, helix-headless-video-playlist-item'),
39
- ].filter((one) => one.value !== '');
38
+ return [...this.querySelectorAll('*')].filter((one) => one instanceof HelixHeadlessVideoPlaylistItem && one.value !== '');
40
39
  }
41
40
  get player() {
42
41
  const slot = this.renderRoot?.querySelector('slot[name="player"]');
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.53.0",
4
+ "version": "0.53.2",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -46,14 +46,14 @@
46
46
  },
47
47
  "bugs": "https://github.com/project-fusion/fusion/issues",
48
48
  "dependencies": {
49
- "@fusion.dev/helix-core": "0.53.0",
50
- "@fusion.dev/helix-icons": "0.53.0",
49
+ "@fusion.dev/helix-core": "0.53.2",
50
+ "@fusion.dev/helix-icons": "0.53.2",
51
51
  "uqr": "^0.1.3"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@custom-elements-manifest/analyzer": "^0.11.0",
55
- "@fusion.dev/helix-cem": "0.53.0",
56
- "@fusion.dev/helix-testing": "0.53.0",
55
+ "@fusion.dev/helix-cem": "0.53.2",
56
+ "@fusion.dev/helix-testing": "0.53.2",
57
57
  "@fusion.dev/scripts": "0.0.0-dev",
58
58
  "@happy-dom/global-registrator": "^20.0.0",
59
59
  "@lit-labs/ssr": "^4.1.0",