@fusion.dev/helix-headless 0.30.2 → 0.32.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 (89) hide show
  1. package/custom-elements.json +2171 -152
  2. package/dist/accordion/item/accordion-item.d.ts +2 -0
  3. package/dist/app-header/root/app-header-root.d.ts +2 -0
  4. package/dist/area-chart/root/area-chart-root.d.ts +1 -0
  5. package/dist/bar-chart/root/bar-chart-root.d.ts +2 -0
  6. package/dist/bar-chart/root/bar-chart-root.js +4 -1
  7. package/dist/carousel/root/carousel-root.d.ts +1 -0
  8. package/dist/carousel/root/carousel-root.js +14 -9
  9. package/dist/chat/root/chat-root.d.ts +12 -0
  10. package/dist/chat/root/chat-root.js +4 -0
  11. package/dist/checkbox/root/checkbox-root.d.ts +6 -0
  12. package/dist/checkbox/root/checkbox-root.js +4 -1
  13. package/dist/checkbox-group/root/checkbox-group-root.d.ts +2 -0
  14. package/dist/color-input/root/color-input-root.d.ts +3 -0
  15. package/dist/combobox/root/combobox-root.d.ts +3 -0
  16. package/dist/command/root/command-root.d.ts +2 -0
  17. package/dist/data-table/root/data-table-root.d.ts +16 -0
  18. package/dist/data-table/root/data-table-root.js +13 -5
  19. package/dist/date-input/root/date-input-root.d.ts +10 -0
  20. package/dist/date-input/root/date-input-root.js +6 -2
  21. package/dist/date-picker/root/date-picker-root.d.ts +7 -0
  22. package/dist/date-picker/root/date-picker-root.js +12 -6
  23. package/dist/dialog/root/dialog-root.d.ts +2 -0
  24. package/dist/donut-chart/root/donut-chart-root.d.ts +2 -0
  25. package/dist/donut-chart/root/donut-chart-root.js +3 -2
  26. package/dist/drawer/root/drawer-root.d.ts +2 -0
  27. package/dist/drilldown/item/drilldown-item.d.ts +36 -1
  28. package/dist/drilldown/item/drilldown-item.js +30 -3
  29. package/dist/file-input/root/file-input-root.d.ts +2 -0
  30. package/dist/filter-input/menu/filter-menu.d.ts +16 -0
  31. package/dist/filter-input/menu/filter-menu.js +30 -4
  32. package/dist/filter-input/root/filter-input-root.d.ts +3 -0
  33. package/dist/heatmap/root/heatmap-root.d.ts +1 -0
  34. package/dist/input/root/input-root.d.ts +3 -0
  35. package/dist/input/root/input-root.js +1 -1
  36. package/dist/line-chart/root/line-chart-root.d.ts +1 -0
  37. package/dist/listbox/root/listbox-root.d.ts +2 -0
  38. package/dist/megamenu/root/megamenu-root.d.ts +2 -0
  39. package/dist/menu/root/menu-root.d.ts +5 -0
  40. package/dist/menu/root/menu-root.js +1 -0
  41. package/dist/meter/root/meter-root.d.ts +12 -4
  42. package/dist/meter/root/meter-root.js +10 -6
  43. package/dist/notifications/group/notification-group.d.ts +2 -0
  44. package/dist/notifications/notification/notification.d.ts +4 -0
  45. package/dist/notifications/root/notifications-root.d.ts +2 -0
  46. package/dist/number-input/root/number-input-root.d.ts +2 -0
  47. package/dist/object-inspector/root/object-inspector-root.d.ts +1 -0
  48. package/dist/object-inspector/root/object-inspector-root.js +5 -4
  49. package/dist/option/root/option-root.d.ts +4 -0
  50. package/dist/option/root/option-root.js +4 -1
  51. package/dist/pagination/root/pagination-root.d.ts +5 -0
  52. package/dist/pagination/root/pagination-root.js +2 -2
  53. package/dist/pagination/size/pagination-size.d.ts +27 -3
  54. package/dist/pagination/size/pagination-size.js +16 -2
  55. package/dist/pin-input/root/pin-input-root.d.ts +2 -0
  56. package/dist/popover/root/popover-root.d.ts +2 -0
  57. package/dist/radio/group/radio-group.d.ts +2 -0
  58. package/dist/radio/root/radio-root.d.ts +2 -0
  59. package/dist/rating/root/rating-root.d.ts +2 -0
  60. package/dist/scatter-chart/root/scatter-chart-root.d.ts +2 -0
  61. package/dist/scatter-chart/root/scatter-chart-root.js +1 -1
  62. package/dist/scroll-area/root/scroll-area-root.d.ts +6 -0
  63. package/dist/scroll-area/root/scroll-area-root.js +4 -3
  64. package/dist/select/root/select-root.d.ts +3 -0
  65. package/dist/slider/root/slider-root.d.ts +2 -0
  66. package/dist/speed-dial/root/speed-dial-root.d.ts +2 -0
  67. package/dist/switch/root/switch-root.d.ts +3 -0
  68. package/dist/table/column/table-column.d.ts +16 -2
  69. package/dist/table/column/table-column.js +3 -8
  70. package/dist/tabs/panel/tab-panel.d.ts +2 -0
  71. package/dist/tabs/tab/tab.d.ts +2 -0
  72. package/dist/textarea/root/textarea-root.d.ts +2 -0
  73. package/dist/time-input/root/time-input-root.d.ts +6 -0
  74. package/dist/time-input/root/time-input-root.js +2 -0
  75. package/dist/time-picker/root/time-picker-root.d.ts +20 -5
  76. package/dist/time-picker/root/time-picker-root.js +30 -11
  77. package/dist/toggle/group/toggle-group.d.ts +2 -0
  78. package/dist/toggle/root/toggle-root.d.ts +2 -0
  79. package/dist/tooltip/root/tooltip-root.d.ts +2 -0
  80. package/dist/tour/stop/tour-stop.d.ts +5 -0
  81. package/dist/tour/stop/tour-stop.js +11 -0
  82. package/dist/tree/item/tree-item.d.ts +3 -0
  83. package/dist/video/root/video-root.d.ts +1 -0
  84. package/dist/video/root/video-root.js +1 -1
  85. package/dist/video-playlist/item/video-playlist-item.d.ts +1 -0
  86. package/dist/video-playlist/item/video-playlist-item.js +1 -1
  87. package/package.json +5 -5
  88. package/types/jsx.d.ts +2000 -26
  89. package/types/vue.d.ts +17 -4
@@ -31,6 +31,8 @@ declare const HelixHeadlessAccordionItem_base: (new (...args: any[]) => import("
31
31
  * @csspart content - The revealed region.
32
32
  * @csspart content-inner - The clipping box inside the animated region.
33
33
  * @csspart trigger - The clickable summary row.
34
+ *
35
+ * @cssstate open - While the item is open.
34
36
  */
35
37
  export declare class HelixHeadlessAccordionItem extends HelixHeadlessAccordionItem_base {
36
38
  /**
@@ -36,6 +36,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
36
36
  * @csspart end - The trailing region.
37
37
  * @csspart row - The centered row inside the banner.
38
38
  * @csspart start - The leading region.
39
+ *
40
+ * @cssstate scrolled - While the page is scrolled down from the top, which is when the bar lifts off it.
39
41
  */
40
42
  export declare class HelixHeadlessAppHeader extends HelixElement {
41
43
  /**
@@ -74,6 +74,7 @@ declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args:
74
74
  * @csspart svg - The drawing surface the bands sit on.
75
75
  * @csspart tooltip - The bubble, forwarded from `Tooltip`.
76
76
  * @csspart tooltip-anchor - The `Tooltip` element itself.
77
+ * @csspart tooltip-arrow - The bubble's point, forwarded from `Tooltip`.
77
78
  * @csspart tooltip-cell - One column's name and value inside the tooltip.
78
79
  * @csspart tooltip-label - The reading's own name inside the tooltip.
79
80
  * @csspart tooltip-name - A column's name inside the tooltip.
@@ -41,6 +41,7 @@ declare const HelixHeadlessBarChart_base: typeof HelixElement & (new (...args: a
41
41
  * @csspart baseline - The rule the columns stand on.
42
42
  * @csspart gridline - One rule across the plot, under `gridlines`.
43
43
  * @csspart group - One category's columns, together.
44
+ * @csspart group-active - The group the tooltip is about, beside `group`.
44
45
  * @csspart label - One category's name.
45
46
  * @csspart labels - The row of category names.
46
47
  * @csspart line - A series drawn as a line rather than as columns, under `lines`.
@@ -50,6 +51,7 @@ declare const HelixHeadlessBarChart_base: typeof HelixElement & (new (...args: a
50
51
  * @csspart tick - One number on an axis.
51
52
  * @csspart tooltip - The bubble, forwarded from `Tooltip`.
52
53
  * @csspart tooltip-anchor - The `Tooltip` element itself.
54
+ * @csspart tooltip-arrow - The bubble's point, forwarded from `Tooltip`.
53
55
  * @csspart tooltip-cell - One column's name and value inside the tooltip.
54
56
  * @csspart tooltip-label - The reading's own name inside the tooltip.
55
57
  * @csspart tooltip-name - A column's name inside the tooltip.
@@ -129,7 +129,10 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
129
129
  ? svg `<line part="baseline" x1=${floor} x2=${floor} y1="0" y2="100" />`
130
130
  : svg `<line part="baseline" x1="0" x2="100" y1=${floor} y2=${floor} />`}
131
131
  ${this.renderBand(categories.length, sideways)}
132
- ${categories.map((_, index) => svg `<g data-active=${this.pointer.at === index ? '' : nothing} part="group">
132
+ ${categories.map((_, index) => svg `<g
133
+ data-active=${this.pointer.at === index ? '' : nothing}
134
+ part="group${this.pointer.at === index ? ' group-active' : ''}"
135
+ >
133
136
  ${columns.map(({ one, tone }, depth) => bar(one.points[index]?.value ?? 0, index, depth, tone, against(one)))}
134
137
  </g>`)}
135
138
  ${series.map((one) => lined.has(one.name.trim().toLowerCase())
@@ -31,6 +31,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
31
31
  *
32
32
  * @csspart controls - The row of controls.
33
33
  * @csspart indicator - One of them, and a way to reach that slide.
34
+ * @csspart indicator-current - The one for the slide showing, beside `indicator`.
34
35
  * @csspart indicators - The row of controls saying where the reader is.
35
36
  * @csspart next - The control that moves to the next slide.
36
37
  * @csspart next-mark - The glyph on the next control.
@@ -28,7 +28,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
28
28
  event.preventDefault();
29
29
  this.goTo(this.index + step);
30
30
  this.updateComplete.then(() => {
31
- this.renderRoot.querySelector('[part="indicator"][data-current]')?.focus();
31
+ this.renderRoot.querySelector('[part~="indicator-current"]')?.focus();
32
32
  });
33
33
  };
34
34
  this.settling = false;
@@ -133,15 +133,17 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
133
133
  }
134
134
  const vertical = this.orientation === 'vertical';
135
135
  const target = this.edgeOf(slide, track, this.bleed(track));
136
+ const at = vertical ? { top: target } : { left: target };
136
137
  if (Math.abs(target - (vertical ? track.scrollTop : track.scrollLeft)) < 1) {
138
+ if (this.settling) {
139
+ track.scrollTo({ behavior: 'instant', ...at });
140
+ this.settling = false;
141
+ }
137
142
  return;
138
143
  }
139
144
  const still = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? false;
140
145
  this.settling = true;
141
- track.scrollTo({
142
- behavior: still ? 'instant' : 'smooth',
143
- ...(vertical ? { top: target } : { left: target }),
144
- });
146
+ track.scrollTo({ behavior: still ? 'instant' : 'smooth', ...at });
145
147
  }
146
148
  stop() {
147
149
  this.stopped = true;
@@ -301,16 +303,19 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
301
303
  ${this.slides.length > 1
302
304
  ? html `<div part="indicators" role="group" aria-label=${`${this.label} slides`}>
303
305
  ${''}
304
- ${Array.from({ length: this.positions }).map((_place, at) => html `<button
305
- part="indicator"
306
+ ${Array.from({ length: this.positions }).map((_place, at) => {
307
+ const current = at === (this.showing ?? this.index);
308
+ return html `<button
309
+ part="indicator${current ? ' indicator-current' : ''}"
306
310
  type="button"
307
311
  aria-label=${`Slide ${at + 1}`}
308
312
  aria-current=${at === this.index ? 'true' : nothing}
309
313
  tabindex=${at === this.index ? '0' : '-1'}
310
- ?data-current=${at === (this.showing ?? this.index)}
314
+ ?data-current=${current}
311
315
  @keydown=${this.handleIndicatorKeydown}
312
316
  @click=${() => this.goTo(at)}
313
- ></button>`)}
317
+ ></button>`;
318
+ })}
314
319
  </div>`
315
320
  : nothing}`;
316
321
  }
@@ -86,6 +86,18 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
86
86
  * @csspart live - Where each settled turn is said, for a reader who cannot see it arrive.
87
87
  * @csspart loading - Shown while the history is still on its way.
88
88
  * @csspart log - The transcript, which is the thing that scrolls.
89
+ * @csspart message - A turn fed as data: the message drawn for it, forwarded whole.
90
+ * @csspart message-actions - The controls offered on a fed turn, beside its time.
91
+ * @csspart message-avatar - A fed turn's leading slot's box.
92
+ * @csspart message-body - What a fed turn said, and the line under it.
93
+ * @csspart message-content - A fed turn's text.
94
+ * @csspart message-indicator - A fed turn's default wait.
95
+ * @csspart message-mark - The status glyph beside a fed turn's failure.
96
+ * @csspart message-meta - The line under a fed turn: its time, its state, and its controls.
97
+ * @csspart message-retry - The control offered on a fed turn that failed.
98
+ * @csspart message-sources - What a fed turn was drawn from.
99
+ * @csspart message-state - What has happened to a fed turn, where that is worth saying.
100
+ * @csspart message-time - When a fed turn was said.
89
101
  * @csspart resume - The affordance offered while the reader is away from the bottom.
90
102
  * @csspart status - The status region, which is not part of the log.
91
103
  * @csspart turn - One turn fed as data, around the message drawn for it.
@@ -391,6 +391,10 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
391
391
  return html `<div part="before" role="presentation" style="block-size: ${before}px; flex: none"></div>
392
392
  ${repeat(this.turns.slice(first, last), (turn, offset) => turn.key ?? first + offset, (turn, offset) => html `<div part="turn" data-index=${first + offset}>
393
393
  <${message}
394
+ exportparts="actions: message-actions, avatar: message-avatar, body: message-body,
395
+ content: message-content, indicator: message-indicator, mark: message-mark, message,
396
+ meta: message-meta, retry: message-retry, sources: message-sources,
397
+ state: message-state, time: message-time"
394
398
  author=${turn.author ?? nothing}
395
399
  at=${turn.at ?? nothing}
396
400
  state=${turn.state ?? nothing}
@@ -42,6 +42,12 @@ declare const HelixHeadlessCheckbox_base: (new (...args: any[]) => import("@fusi
42
42
  * @csspart hint - Help under the control, while nothing is wrong.
43
43
  * @csspart label - The label beside it.
44
44
  * @csspart mark - The tick, or the dash when the box is indeterminate.
45
+ * @csspart mark-checked - The mark while the box is checked, beside `mark`.
46
+ * @csspart mark-indeterminate - The mark while the box is indeterminate, beside `mark`.
47
+ *
48
+ * @cssstate checked - While the box is checked.
49
+ * @cssstate has-label - While the label slot holds something to read, which is what draws a label at all.
50
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
45
51
  */
46
52
  export declare class HelixHeadlessCheckbox extends HelixHeadlessCheckbox_base {
47
53
  protected readonly aria: AriaForwardController;
@@ -69,7 +69,10 @@ let HelixHeadlessCheckbox = class HelixHeadlessCheckbox extends MixinControllerC
69
69
  @change=${this.handleChange}
70
70
  @input=${this.stopInner}
71
71
  />
72
- <span part="mark" aria-hidden="true"></span>
72
+ <span
73
+ part="mark${this.checked ? ' mark-checked' : ''}${this.indeterminate ? ' mark-indeterminate' : ''}"
74
+ aria-hidden="true"
75
+ ></span>
73
76
  </span>
74
77
  <span part="label"><slot @slotchange=${this.handleLabelChange}>${this.label}</slot></span>
75
78
  </label>
@@ -41,6 +41,8 @@ declare const HelixHeadlessCheckboxGroup_base: (new (...args: any[]) => import("
41
41
  * @csspart hint - Help under the set.
42
42
  * @csspart items - The list itself, which is what `orientation` lays out.
43
43
  * @csspart label - The group's name, over the set.
44
+ *
45
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
44
46
  */
45
47
  export declare class HelixHeadlessCheckboxGroup extends HelixHeadlessCheckboxGroup_base {
46
48
  /**
@@ -89,6 +89,9 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
89
89
  * @csspart trigger - The control that opens the panel.
90
90
  *
91
91
  * @cssproperty --color-input-swatch - The chosen color, to paint over the transparency check.
92
+ *
93
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
94
+ * @cssstate open - While the picker is open.
92
95
  */
93
96
  export declare class HelixHeadlessColorInput extends HelixHeadlessColorInput_base {
94
97
  protected readonly aria: AriaForwardController;
@@ -78,6 +78,9 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
78
78
  * @csspart tag-dismiss-mark - The glyph on the dismiss control, where none is slotted.
79
79
  * @csspart tag-prefix - The category before the label.
80
80
  * @csspart tags - The row of chosen options, when `multiple` is set.
81
+ *
82
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
83
+ * @cssstate open - While the list is open.
81
84
  */
82
85
  export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
83
86
  protected readonly aria: AriaForwardController;
@@ -57,6 +57,8 @@ declare const HelixHeadlessCommand_base: (new (...args: any[]) => import("@fusio
57
57
  * @csspart listbox-loading - Shown while the options are still on their way.
58
58
  * @csspart listbox-search - The region holding the field that narrows the list.
59
59
  * @csspart listbox-search-field - The field itself.
60
+ *
61
+ * @cssstate open - While the palette is open.
60
62
  */
61
63
  export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
62
64
  /**
@@ -71,6 +71,7 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
71
71
  * @csspart after - The room the rows below the window would have taken. Windowed only.
72
72
  * @csspart before - The room the rows above the window would have taken. Windowed only.
73
73
  * @csspart cell - One cell.
74
+ * @csspart cell-selected - A cell of a selected row, beside `cell`.
74
75
  * @csspart checkbox - A row's checkbox, or the one in the heading that selects them all.
75
76
  * @csspart checkbox-box - The frame the checkbox's input is painted as.
76
77
  * @csspart checkbox-control - The checkbox's input.
@@ -79,14 +80,29 @@ declare const HelixHeadlessDataTable_base: (new (...args: any[]) => import("@fus
79
80
  * @csspart checkbox-hint - Forwarded from the checkbox, and never drawn here.
80
81
  * @csspart checkbox-label - Forwarded from the checkbox; the label is spoken, not shown.
81
82
  * @csspart checkbox-mark - The tick, or the dash while some rows are selected.
83
+ * @csspart checkbox-mark-checked - The mark while its box is checked, beside `checkbox-mark`.
84
+ * @csspart checkbox-mark-indeterminate - The dash while only some rows are selected, beside `checkbox-mark`.
82
85
  * @csspart empty - Shown when no rows match.
83
86
  * @csspart footer - The region below the grid.
84
87
  * @csspart head - The row the column headings sit in. `display: contents`, so it takes no space.
85
88
  * @csspart loading - Shown while the rows are still on their way.
86
89
  * @csspart pagination - The pagination, where this draws one.
90
+ * @csspart pagination-first - The pagination's control that jumps to the first page, under `ends`.
91
+ * @csspart pagination-gap - The pagination's control standing over pages not shown.
92
+ * @csspart pagination-item - One slot in the pagination's run, holding a page or a gap.
93
+ * @csspart pagination-last - The pagination's control that jumps to the last page, under `ends`.
94
+ * @csspart pagination-list - The pagination's run of pages.
95
+ * @csspart pagination-live - The region that says the page changed. Clipped, not hidden.
96
+ * @csspart pagination-mark - The glyph on a first, previous, next or last control.
97
+ * @csspart pagination-next - The pagination's control that moves forward one page.
98
+ * @csspart pagination-page - The pagination's control for one page.
99
+ * @csspart pagination-page-current - The page you are on, beside `pagination-page`.
100
+ * @csspart pagination-previous - The pagination's control that moves back one page.
101
+ * @csspart pagination-status - The pagination's reading of where you are, in `compact`.
87
102
  * @csspart row - One row of data.
88
103
  * @csspart select - The cell holding a row's checkbox.
89
104
  * @csspart select-all - The heading holding the checkbox that selects every row.
105
+ * @csspart select-selected - The checkbox cell of a selected row, beside `select`.
90
106
  * @csspart table - The grid.
91
107
  * @csspart toolbar - The region above the grid.
92
108
  *
@@ -537,9 +537,9 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
537
537
  : undefined;
538
538
  }
539
539
  }
540
- renderCell(column, row) {
540
+ renderCell(column, row, picked) {
541
541
  return html `<span
542
- part="cell"
542
+ part="cell${picked ? ' cell-selected' : ''}"
543
543
  role="gridcell"
544
544
  style=${column.align ? `text-align: ${column.align}` : nothing}
545
545
  >${column.read(row)}</span
@@ -550,7 +550,8 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
550
550
  return html `<${checkbox}
551
551
  part="checkbox"
552
552
  exportparts="box: checkbox-box, control: checkbox-control, feedback: checkbox-feedback,
553
- field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark"
553
+ field: checkbox-field, hint: checkbox-hint, label: checkbox-label, mark: checkbox-mark,
554
+ mark-checked: checkbox-mark-checked, mark-indeterminate: checkbox-mark-indeterminate"
554
555
  aria-label=${name}
555
556
  .checked=${checked}
556
557
  .indeterminate=${indeterminate}
@@ -574,8 +575,10 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
574
575
  data-index=${this.windowed ? start + index : nothing}
575
576
  >
576
577
  ${chosen
577
- ? html `<span part="select" role="gridcell">${this.renderCheckbox(`Select ${named ? String(named.order(row) ?? key) : key}`, picked, false, (event) => this.toggleRow(key, event))}</span>`
578
- : nothing}${columns.map((column) => this.renderCell(column, row))}
578
+ ? html `<span part="select${picked ? ' select-selected' : ''}" role="gridcell"
579
+ >${this.renderCheckbox(`Select ${named ? String(named.order(row) ?? key) : key}`, picked, false, (event) => this.toggleRow(key, event))}</span
580
+ >`
581
+ : nothing}${columns.map((column) => this.renderCell(column, row, picked))}
579
582
  </div>`;
580
583
  })}`;
581
584
  }
@@ -633,6 +636,11 @@ let HelixHeadlessDataTable = class HelixHeadlessDataTable extends MixinCollectio
633
636
  ${this.paginated
634
637
  ? html `<${pagination}
635
638
  part="pagination"
639
+ exportparts="first: pagination-first, gap: pagination-gap, item: pagination-item,
640
+ last: pagination-last, list: pagination-list, live: pagination-live,
641
+ mark: pagination-mark, next: pagination-next, page: pagination-page,
642
+ page-current: pagination-page-current, previous: pagination-previous,
643
+ status: pagination-status"
636
644
  page=${this.page}
637
645
  page-size=${this.pageSize || 1}
638
646
  total=${matched}
@@ -45,7 +45,14 @@ declare const HelixHeadlessDateInput_base: (new (...args: any[]) => import("@fus
45
45
  * @csspart label - The question, over the field.
46
46
  * @csspart picker - The date picker inside it.
47
47
  * @csspart picker-cell - One column of a row, which is what a range paints.
48
+ * @csspart picker-cell-range-end - The cell of a range's last day, beside `picker-cell`.
49
+ * @csspart picker-cell-range-middle - A cell between a range's ends, beside `picker-cell`.
50
+ * @csspart picker-cell-range-start - The cell of a range's first day, beside `picker-cell`.
48
51
  * @csspart picker-day - The shape inside a cell, which is what a single date paints.
52
+ * @csspart picker-day-disabled - A day that cannot be chosen, beside `picker-day`.
53
+ * @csspart picker-day-outside - A day from a neighboring month, beside `picker-day`.
54
+ * @csspart picker-day-selected - The chosen day, or either end of a chosen range, beside `picker-day`.
55
+ * @csspart picker-day-today - Today, beside `picker-day`.
49
56
  * @csspart picker-grid - The grid of days.
50
57
  * @csspart picker-header - The month name and its controls.
51
58
  * @csspart picker-heading - The month and year being shown.
@@ -62,6 +69,9 @@ declare const HelixHeadlessDateInput_base: (new (...args: any[]) => import("@fus
62
69
  * @csspart tags - The row the dates sit in.
63
70
  * @csspart trigger - The control that opens the calendar.
64
71
  * @csspart trigger-icon - The mark on the button that opens the calendar.
72
+ *
73
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
74
+ * @cssstate open - While the calendar is open.
65
75
  */
66
76
  export declare class HelixHeadlessDateInput extends HelixHeadlessDateInput_base {
67
77
  protected readonly aria: AriaForwardController;
@@ -143,8 +143,12 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinPickerEdi
143
143
  renderPicker() {
144
144
  return html `<${this.tag('date-picker')}
145
145
  part="picker"
146
- exportparts="cell: picker-cell, day: picker-day, grid: picker-grid, header: picker-header,
147
- heading: picker-heading, month: picker-month, months: picker-months, next: picker-next,
146
+ exportparts="cell: picker-cell, cell-range-end: picker-cell-range-end,
147
+ cell-range-middle: picker-cell-range-middle, cell-range-start: picker-cell-range-start,
148
+ day: picker-day, day-disabled: picker-day-disabled, day-outside: picker-day-outside,
149
+ day-selected: picker-day-selected, day-today: picker-day-today, grid: picker-grid,
150
+ header: picker-header, heading: picker-heading, month: picker-month, months: picker-months,
151
+ next: picker-next,
148
152
  next-mark: picker-next-mark, previous: picker-previous, previous-mark: picker-previous-mark,
149
153
  week: picker-week, weekday: picker-weekday"
150
154
  ?invalid=${this.resolvedFeedback !== ''}
@@ -35,7 +35,14 @@ declare const HelixHeadlessDatePicker_base: (new (...args: any[]) => import("@fu
35
35
  * @event {Event} input - Announced once the value has moved.
36
36
  *
37
37
  * @csspart cell - One column of a row, which is what a range paints.
38
+ * @csspart cell-range-end - The cell of a range's last day, beside `cell`.
39
+ * @csspart cell-range-middle - A cell between a range's ends, beside `cell`.
40
+ * @csspart cell-range-start - The cell of a range's first day, beside `cell`.
38
41
  * @csspart day - The shape inside a cell, which is what a single date paints.
42
+ * @csspart day-disabled - A day that cannot be chosen, beside `day`.
43
+ * @csspart day-outside - A day from a neighboring month, filling the grid out, beside `day`.
44
+ * @csspart day-selected - The chosen day, or either end of a chosen range, beside `day`.
45
+ * @csspart day-today - Today, beside `day`.
39
46
  * @csspart grid - The grid of days.
40
47
  * @csspart header - The month name and its controls.
41
48
  * @csspart heading - The month and year being shown.
@@ -200,7 +200,7 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
200
200
  this.focused = toIso(date);
201
201
  this.show(date);
202
202
  this.updateComplete.then(() => {
203
- this.renderRoot.querySelector('[part="cell"][tabindex="0"]')?.focus();
203
+ this.renderRoot.querySelector('[part~="cell"][tabindex="0"]')?.focus();
204
204
  });
205
205
  }
206
206
  select(date) {
@@ -355,21 +355,27 @@ let HelixHeadlessDatePicker = class HelixHeadlessDatePicker extends MixinControl
355
355
  const disabled = this.barred(date);
356
356
  const selected = this.isSelected(iso);
357
357
  const outside = !sameMonth(date, month);
358
+ const start = !outside && range !== null && iso === range[0];
359
+ const end = !outside && range !== null && iso === range[1];
360
+ const middle = !outside && range !== null && iso > range[0] && iso < range[1];
358
361
  return html `<span
359
- part="cell"
362
+ part="cell${start ? ' cell-range-start' : ''}${middle ? ' cell-range-middle' : ''}${end ? ' cell-range-end' : ''}"
360
363
  role="gridcell"
361
364
  aria-disabled=${disabled ? 'true' : nothing}
362
365
  aria-label=${full.format(date)}
363
366
  aria-current=${iso === today ? 'date' : nothing}
364
367
  aria-selected=${!outside && selected ? 'true' : nothing}
365
368
  data-outside=${outside ? '' : nothing}
366
- data-range-end=${!outside && range && iso === range[1] ? '' : nothing}
367
- data-range-middle=${!outside && range && iso > range[0] && iso < range[1] ? '' : nothing}
368
- data-range-start=${!outside && range && iso === range[0] ? '' : nothing}
369
+ data-range-end=${end ? '' : nothing}
370
+ data-range-middle=${middle ? '' : nothing}
371
+ data-range-start=${start ? '' : nothing}
369
372
  data-today=${iso === today ? '' : nothing}
370
373
  tabindex=${!outside && iso === anchor ? '0' : '-1'}
371
374
  @click=${outside ? nothing : () => this.select(date)}
372
- ><span part="day">${date.getUTCDate()}</span></span
375
+ ><span
376
+ part="day${!outside && selected && !middle ? ' day-selected' : ''}${iso === today ? ' day-today' : ''}${outside ? ' day-outside' : ''}${disabled ? ' day-disabled' : ''}"
377
+ >${date.getUTCDate()}</span
378
+ ></span
373
379
  >`;
374
380
  })}
375
381
  </div>`)}
@@ -34,6 +34,8 @@ declare const HelixHeadlessDialog_base: (new (...args: any[]) => import("@fusion
34
34
  * @event {Event} toggle - Says the state moved, carrying `newState` and `oldState`.
35
35
  *
36
36
  * @csspart dialog - The native dialog element.
37
+ *
38
+ * @cssstate open - While the dialog is open.
37
39
  */
38
40
  export declare class HelixHeadlessDialog extends HelixHeadlessDialog_base {
39
41
  /**
@@ -28,9 +28,11 @@ declare const HelixHeadlessDonutChart_base: typeof HelixElement & (new (...args:
28
28
  * @csspart mark - The invisible point the tooltip is anchored to.
29
29
  * @csspart plot - The drawing.
30
30
  * @csspart segment - One slice.
31
+ * @csspart segment-active - The slice under the pointer, beside `segment`.
31
32
  * @csspart segment-edge - One slice as a closed shape, for a boundary to trace.
32
33
  * @csspart tooltip - The bubble, forwarded from `Tooltip`.
33
34
  * @csspart tooltip-anchor - The `Tooltip` element itself.
35
+ * @csspart tooltip-arrow - The bubble's point, forwarded from `Tooltip`.
34
36
  * @csspart tooltip-cell - One column's name and value inside the tooltip.
35
37
  * @csspart tooltip-label - The slice's own name inside the tooltip.
36
38
  * @csspart tooltip-name - A column's name inside the tooltip.
@@ -86,15 +86,16 @@ let HelixHeadlessDonutChart = class HelixHeadlessDonutChart extends MixinChartSo
86
86
  renderSegment(share, index) {
87
87
  const circumference = 2 * Math.PI * this.radius;
88
88
  const length = share.fraction * circumference * this.span;
89
+ const active = this.pointer.at === index;
89
90
  return svg `<circle
90
91
  cx=${CENTER}
91
92
  cy=${CENTER}
92
- data-active=${this.pointer.at === index ? '' : nothing}
93
+ data-active=${active ? '' : nothing}
93
94
  data-series=${seriesIndex(index)}
94
95
  fill="none"
95
96
  style="--chart-series: var(--chart-series-${seriesIndex(index)})"
96
97
  @pointerenter=${() => this.pointer.set(index)}
97
- part="segment"
98
+ part="segment${active ? ' segment-active' : ''}"
98
99
  r=${this.radius}
99
100
  stroke-dasharray="${length} ${GAP}"
100
101
  stroke-dashoffset=${-share.start * circumference * this.span}
@@ -45,6 +45,8 @@ declare const HelixHeadlessDrawer_base: (new (...args: any[]) => import("@fusion
45
45
  * @csspart content - The scrolling content region.
46
46
  * @csspart header - The header region.
47
47
  * @csspart panel - The sliding panel.
48
+ *
49
+ * @cssstate open - While the drawer is open.
48
50
  */
49
51
  export declare class HelixHeadlessDrawer extends HelixHeadlessDrawer_base {
50
52
  protected readonly commands: CommandController;
@@ -1,5 +1,5 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { nothing, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  /**
4
4
  * @summary One row of a drill-down, which may hold a page of its own.
5
5
  *
@@ -18,6 +18,11 @@ import { nothing, type TemplateResult } from 'lit';
18
18
  * Choosing is announced, never applied. The row dispatches and the stack
19
19
  * decides whether that means drilling in or choosing a command.
20
20
  *
21
+ * **A row that opens a page says so**, with a caret after its words and
22
+ * `aria-haspopup`, the way `Menu` marks a row with a submenu: a row that goes
23
+ * somewhere and a row that does something otherwise look the same until one is
24
+ * pressed. Not on the server, which cannot see the children and so cannot know.
25
+ *
21
26
  * @since 0.1.0
22
27
  * @status experimental
23
28
  * @aliases Panel item, Drill row
@@ -32,6 +37,7 @@ import { nothing, type TemplateResult } from 'lit';
32
37
  *
33
38
  * @csspart item - The row itself.
34
39
  * @csspart label - The words.
40
+ * @csspart mark - The caret at the end of a row that opens a page, after the `end` slot. A caret points, so a sheet mirrors it in a right-to-left document.
35
41
  */
36
42
  export declare class HelixHeadlessDrilldownItem extends HelixElement {
37
43
  /**
@@ -74,6 +80,35 @@ export declare class HelixHeadlessDrilldownItem extends HelixElement {
74
80
  * Identifies the row to whatever is listening.
75
81
  */
76
82
  value: string;
83
+ /**
84
+ * Whether anything is slotted into `page`.
85
+ *
86
+ * State rather than a getter over `children`, for the reason `Menu.Item`
87
+ * backs `hasSubmenu` the same way: a getter is read during `render()` with
88
+ * nothing to re-read it, so a page a framework fills after the row's first
89
+ * render would open with no caret on the row that leads to it.
90
+ */
91
+ private page;
92
+ /**
93
+ * Reads the children before each render, where they can be known.
94
+ *
95
+ * Not on the server, where there are none to read, nor while hydrating what
96
+ * one sent, whose row carried no caret. `finishHydration` asks for the read
97
+ * that skipped.
98
+ */
99
+ protected willUpdate(changed: PropertyValues): void;
100
+ protected firstUpdated(changed: PropertyValues): void;
101
+ /**
102
+ * Re-reads whether a page is slotted, from whichever `page` slot is current.
103
+ *
104
+ * Bound in the template, on both of them. The row and the page it opens each
105
+ * render a `slot[name="page"]`, and moving between them makes Lit build a new
106
+ * slot and throw the old one away, which fires on its way out with nothing
107
+ * assigned: a listener on the discarded one would clear the caret on every row
108
+ * that has been drilled into and back out of. `Menu.Item.readSubmenu` carries
109
+ * the same note.
110
+ */
111
+ private readonly readPage;
77
112
  /** Moves focus onto the row itself. */
78
113
  focusItem(): void;
79
114
  /** Announces that this row was chosen. */
@@ -5,8 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
8
+ import { caretRight } from '@fusion.dev/helix-icons';
8
9
  import { html, nothing } from 'lit';
9
- import { property } from 'lit/decorators.js';
10
+ import { property, state } from 'lit/decorators.js';
11
+ import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
10
12
  let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixElement {
11
13
  constructor() {
12
14
  super(...arguments);
@@ -16,6 +18,21 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
16
18
  this.onPage = true;
17
19
  this.showingPage = false;
18
20
  this.value = '';
21
+ this.page = false;
22
+ this.readPage = () => {
23
+ const slot = this.renderRoot.querySelector('slot[name="page"]');
24
+ this.page = (slot?.assignedElements().length ?? 0) > 0;
25
+ };
26
+ }
27
+ willUpdate(changed) {
28
+ super.willUpdate(changed);
29
+ if (this.childrenKnown) {
30
+ this.page = this.knownChildren.some((child) => child.slot === 'page');
31
+ }
32
+ }
33
+ firstUpdated(changed) {
34
+ super.firstUpdated(changed);
35
+ this.finishHydration();
19
36
  }
20
37
  focusItem() {
21
38
  this.partNamed('item')?.focus();
@@ -28,7 +45,7 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
28
45
  }
29
46
  render() {
30
47
  if (this.showingPage) {
31
- return html `<slot name="page"></slot>`;
48
+ return html `<slot name="page" @slotchange=${this.readPage}></slot>`;
32
49
  }
33
50
  if (!this.onPage) {
34
51
  return nothing;
@@ -38,13 +55,20 @@ let HelixHeadlessDrilldownItem = class HelixHeadlessDrilldownItem extends HelixE
38
55
  type="button"
39
56
  role="menuitem"
40
57
  aria-disabled=${this.disabled ? 'true' : nothing}
58
+ aria-haspopup=${this.page ? 'menu' : nothing}
41
59
  tabindex=${this.focusable ? '0' : '-1'}
42
60
  @click=${() => this.select()}
43
61
  >
44
62
  <slot name="start"></slot>
45
63
  <span part="label"><slot></slot></span>
46
64
  <slot name="end"></slot>
47
- </button>`;
65
+ ${this.page
66
+ ? html `<svg part="mark" fill="currentColor" viewBox=${caretRight.viewBox} aria-hidden="true">
67
+ ${unsafeSVG(caretRight.content)}
68
+ </svg>`
69
+ : nothing}
70
+ </button>
71
+ <div hidden><slot name="page" @slotchange=${this.readPage}></slot></div>`;
48
72
  }
49
73
  };
50
74
  __decorate([
@@ -62,6 +86,9 @@ __decorate([
62
86
  __decorate([
63
87
  property()
64
88
  ], HelixHeadlessDrilldownItem.prototype, "value", void 0);
89
+ __decorate([
90
+ state()
91
+ ], HelixHeadlessDrilldownItem.prototype, "page", void 0);
65
92
  HelixHeadlessDrilldownItem = __decorate([
66
93
  customElement('helix-headless-drilldown-item')
67
94
  ], HelixHeadlessDrilldownItem);
@@ -51,6 +51,8 @@ declare const HelixHeadlessFileInput_base: (new (...args: any[]) => import("@fus
51
51
  * @csspart size-dismiss-mark - The glyph on the dismiss control, where none is slotted.
52
52
  * @csspart size-prefix - The category before the label.
53
53
  * @csspart trigger - The label that opens the picker.
54
+ *
55
+ * @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
54
56
  */
55
57
  export declare class HelixHeadlessFileInput extends HelixHeadlessFileInput_base {
56
58
  protected readonly aria: AriaForwardController;