@fusion.dev/helix-headless 0.52.1 → 0.53.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 (53) hide show
  1. package/custom-elements.json +668 -270
  2. package/dist/announcement/root/announcement-root.js +2 -5
  3. package/dist/area-chart/root/area-chart-root.js +10 -12
  4. package/dist/bar-chart/root/bar-chart-root.js +4 -5
  5. package/dist/blockquote/root/blockquote-root.js +2 -5
  6. package/dist/chat/composer/chat-composer.js +2 -5
  7. package/dist/chat/message/chat-message.js +4 -11
  8. package/dist/chat/root/chat-root.js +1 -1
  9. package/dist/checkbox-group/root/checkbox-group-root.js +1 -1
  10. package/dist/color-input/root/color-input-root.js +1 -1
  11. package/dist/combobox/root/combobox-root.js +1 -1
  12. package/dist/data-table/root/data-table-root.d.ts +0 -10
  13. package/dist/data-table/root/data-table-root.js +4 -10
  14. package/dist/date-input/root/date-input-root.js +1 -1
  15. package/dist/divider/root/divider-root.js +2 -5
  16. package/dist/donut-chart/root/donut-chart-root.js +5 -6
  17. package/dist/drilldown/item/drilldown-item.d.ts +18 -0
  18. package/dist/drilldown/item/drilldown-item.js +3 -0
  19. package/dist/drilldown/root/drilldown-root.d.ts +20 -1
  20. package/dist/drilldown/root/drilldown-root.js +6 -13
  21. package/dist/file-input/root/file-input-root.js +2 -2
  22. package/dist/filter-input/root/filter-input-root.js +1 -1
  23. package/dist/heatmap/root/buckets.d.ts +2 -2
  24. package/dist/heatmap/root/buckets.js +3 -4
  25. package/dist/heatmap/root/heatmap-root.d.ts +0 -10
  26. package/dist/heatmap/root/heatmap-root.js +2 -8
  27. package/dist/input/root/input-root.js +1 -1
  28. package/dist/line-chart/root/line-chart-root.js +15 -17
  29. package/dist/listbox/root/listbox-root.js +1 -1
  30. package/dist/menu/item/menu-item.js +2 -2
  31. package/dist/notifications/notification/notification.d.ts +3 -9
  32. package/dist/notifications/notification/notification.js +3 -11
  33. package/dist/notifications/root/notifications-root.d.ts +0 -10
  34. package/dist/notifications/root/notifications-root.js +3 -9
  35. package/dist/number-input/root/number-input-root.js +2 -2
  36. package/dist/radio/root/radio-root.d.ts +4 -36
  37. package/dist/radio/root/radio-root.js +2 -27
  38. package/dist/scatter-chart/root/scatter-chart-root.js +10 -11
  39. package/dist/select/root/select-root.js +1 -1
  40. package/dist/slider/root/slider-root.js +1 -1
  41. package/dist/sparkline/root/sparkline-root.js +10 -12
  42. package/dist/switch/root/switch-root.js +2 -5
  43. package/dist/tabs/tab/tab.d.ts +5 -34
  44. package/dist/tabs/tab/tab.js +3 -28
  45. package/dist/textarea/root/textarea-root.js +1 -1
  46. package/dist/time-input/root/time-input-root.js +1 -1
  47. package/dist/toggle/root/toggle-root.d.ts +4 -40
  48. package/dist/toggle/root/toggle-root.js +2 -27
  49. package/dist/tree/item/tree-item.js +2 -2
  50. package/dist/video/root/video-root.js +7 -14
  51. package/package.json +5 -5
  52. package/types/jsx.d.ts +192 -74
  53. package/types/vue.d.ts +36 -16
@@ -4,12 +4,10 @@ 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 { CHART_PLOT, customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
7
+ import { CHART_PLOT, customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import '../../tooltip/index.js';
11
- const WIDTH = 100;
12
- const HEIGHT = 100;
13
11
  let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSource(HelixElement) {
14
12
  constructor() {
15
13
  super(...arguments);
@@ -36,8 +34,8 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
36
34
  return [
37
35
  {
38
36
  index: seriesIndex(depth),
39
- x: (x(one.points.length - 1) / WIDTH) * 100,
40
- y: (y(last.value) / HEIGHT) * 100,
37
+ x: (x(one.points.length - 1) / PLOT_WIDTH) * 100,
38
+ y: (y(last.value) / PLOT_HEIGHT) * 100,
41
39
  },
42
40
  ];
43
41
  });
@@ -49,9 +47,9 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
49
47
  return html `<div id=${CHART_PLOT} part="plot"></div>`;
50
48
  }
51
49
  const domain = this.range(series);
52
- const y = linear(domain, [HEIGHT, 0]);
53
- const slot = WIDTH / readings.length;
54
- const x = linear([0, Math.max(readings.length - 1, 1)], [slot / 2, WIDTH - slot / 2]);
50
+ const y = linear(domain, [PLOT_HEIGHT, 0]);
51
+ const slot = PLOT_WIDTH / readings.length;
52
+ const x = linear([0, Math.max(readings.length - 1, 1)], [slot / 2, PLOT_WIDTH - slot / 2]);
55
53
  return html `${this.renderPlot(series, x, y, domain)} ${this.renderLabels(readings)}`;
56
54
  }
57
55
  renderPlot(series, x, y, domain) {
@@ -71,13 +69,13 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
71
69
  <svg part="svg"
72
70
  data-mirror
73
71
  preserveAspectRatio="none"
74
- viewBox="0 0 ${WIDTH} ${HEIGHT}"
72
+ viewBox="0 0 ${PLOT_WIDTH} ${PLOT_HEIGHT}"
75
73
  xmlns="http://www.w3.org/2000/svg"
76
74
  >
77
75
  ${this.renderGridlines(x, y, domain, series[0]?.points.length ?? 0)}
78
76
  ${floor === undefined
79
77
  ? nothing
80
- : svg `<line part="baseline" x1="0" x2=${WIDTH} y1=${floor} y2=${floor} />`}
78
+ : svg `<line part="baseline" x1="0" x2=${PLOT_WIDTH} y1=${floor} y2=${floor} />`}
81
79
  ${this.renderBand(series[0]?.points.length ?? 0)}
82
80
  ${this.renderGuide(x)}
83
81
  ${series.map((one, depth) => this.renderSeries(one, depth, x, y))}
@@ -91,10 +89,10 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
91
89
  return nothing;
92
90
  }
93
91
  const down = this.rulesCategory
94
- ? Array.from({ length: count }, (_, index) => svg `<line part="gridline" x1=${x(index)} x2=${x(index)} y1="0" y2=${HEIGHT} />`)
92
+ ? Array.from({ length: count }, (_, index) => svg `<line part="gridline" x1=${x(index)} x2=${x(index)} y1="0" y2=${PLOT_HEIGHT} />`)
95
93
  : [];
96
94
  const across = this.rulesValue
97
- ? ticks(domain).map((level) => svg `<line part="gridline" x1="0" x2=${WIDTH} y1=${y(level)} y2=${y(level)} />`)
95
+ ? ticks(domain).map((level) => svg `<line part="gridline" x1="0" x2=${PLOT_WIDTH} y1=${y(level)} y2=${y(level)} />`)
98
96
  : [];
99
97
  return svg `${down}${across}`;
100
98
  }
@@ -103,15 +101,15 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
103
101
  if (at < 0 || count === 0) {
104
102
  return nothing;
105
103
  }
106
- const slot = WIDTH / count;
107
- return svg `<rect height=${HEIGHT} part="band" width=${slot} x=${at * slot} y="0" />`;
104
+ const slot = PLOT_WIDTH / count;
105
+ return svg `<rect height=${PLOT_HEIGHT} part="band" width=${slot} x=${at * slot} y="0" />`;
108
106
  }
109
107
  renderGuide(x) {
110
108
  const at = this.pointer.at;
111
109
  if (at < 0) {
112
110
  return nothing;
113
111
  }
114
- return svg `<line part="guide" x1=${x(at)} x2=${x(at)} y1="0" y2=${HEIGHT} />`;
112
+ return svg `<line part="guide" x1=${x(at)} x2=${x(at)} y1="0" y2=${PLOT_HEIGHT} />`;
115
113
  }
116
114
  renderTermini(ends) {
117
115
  if (ends.length === 0) {
@@ -132,7 +130,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
132
130
  const index = seriesIndex(depth);
133
131
  const first = points[0];
134
132
  const last = points.at(-1);
135
- const wash = `${path}L${last[0]},${HEIGHT}L${first[0]},${HEIGHT}Z`;
133
+ const wash = `${path}L${last[0]},${PLOT_HEIGHT}L${first[0]},${PLOT_HEIGHT}Z`;
136
134
  return svg `${this.area
137
135
  ? svg `<path
138
136
  d=${wash}
@@ -160,7 +158,7 @@ let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSour
160
158
  return drawTooltip(this.sourceRows, at, this.tag('tooltip'));
161
159
  }
162
160
  const domain = this.range(series);
163
- const scale = linear(domain, [HEIGHT, 0]);
161
+ const scale = linear(domain, [PLOT_HEIGHT, 0]);
164
162
  const tops = series
165
163
  .map((one) => one.points[at]?.value)
166
164
  .filter((one) => one !== undefined)
@@ -305,7 +305,7 @@ let HelixHeadlessListbox = class HelixHeadlessListbox extends MixinCollection(Mi
305
305
  super.willUpdate(changed);
306
306
  hostAria(this.internals, { label: this.label, role: 'listbox' });
307
307
  this.internals.ariaMultiSelectable = this.multiple ? 'true' : null;
308
- if (this.children !== undefined && !this.hydrating) {
308
+ if (this.childrenKnown) {
309
309
  this.place();
310
310
  }
311
311
  }
@@ -58,10 +58,10 @@ let HelixHeadlessMenuItem = class HelixHeadlessMenuItem extends HelixElement {
58
58
  }
59
59
  willUpdate(changed) {
60
60
  super.willUpdate(changed);
61
- if (this.children === undefined || this.hydrating) {
61
+ if (!this.childrenKnown) {
62
62
  return;
63
63
  }
64
- const named = (name) => [...this.children].some((child) => child.slot === name);
64
+ const named = (name) => this.knownChildren.some((child) => child.slot === name);
65
65
  this.submenu = named('submenu');
66
66
  this.start = named('start');
67
67
  }
@@ -1,6 +1,7 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
2
  import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../format-date/index.js';
4
+ declare const HelixHeadlessNotification_base: (new (...args: any[]) => import("@fusion.dev/helix-core").DismissibleElement) & typeof HelixElement;
4
5
  /**
5
6
  * @summary One thing that happened, which a reader may not have seen yet.
6
7
  *
@@ -66,7 +67,7 @@ import '../../format-date/index.js';
66
67
  * @cssstate controls - While it can be dismissed, so the time makes way for the control under a pointer.
67
68
  * @cssstate read - While it has been read.
68
69
  */
69
- export declare class HelixHeadlessNotification extends HelixElement {
70
+ export declare class HelixHeadlessNotification extends HelixHeadlessNotification_base {
70
71
  /**
71
72
  * When it happened, as anything `Date` parses.
72
73
  *
@@ -97,14 +98,6 @@ export declare class HelixHeadlessNotification extends HelixElement {
97
98
  * State to open with, where nothing declared one.
98
99
  */
99
100
  defaultRead: boolean;
100
- /**
101
- * Whether a reader may remove it.
102
- */
103
- dismissible: boolean;
104
- /**
105
- * Accessible name for the dismiss control.
106
- */
107
- dismissLabel: string;
108
101
  /**
109
102
  * Locale for the timestamp.
110
103
  *
@@ -212,3 +205,4 @@ declare global {
212
205
  'helix-headless-notification': HelixHeadlessNotification;
213
206
  }
214
207
  }
208
+ export {};
@@ -4,20 +4,18 @@ 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 { customElement, HelixDismissEvent, HelixElement, HelixReadEvent, hostAria, requestChange, slotFilled, } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, HelixReadEvent, hostAria, MixinDismissible, requestChange, slotFilled, } from '@fusion.dev/helix-core';
8
8
  import { x } from '@fusion.dev/helix-icons';
9
9
  import { nothing } from 'lit';
10
10
  import { property } from 'lit/decorators.js';
11
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
12
  import { html } from 'lit/static-html.js';
13
13
  import '../../format-date/index.js';
14
- let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixElement {
14
+ let HelixHeadlessNotification = class HelixHeadlessNotification extends MixinDismissible(HelixElement) {
15
15
  constructor() {
16
16
  super(...arguments);
17
17
  this.at = '';
18
18
  this.defaultRead = false;
19
- this.dismissible = false;
20
- this.dismissLabel = 'Dismiss';
21
19
  this.locale = '';
22
20
  this.isNotification = true;
23
21
  this.readState = undefined;
@@ -26,7 +24,7 @@ let HelixHeadlessNotification = class HelixHeadlessNotification extends HelixEle
26
24
  };
27
25
  this.handleDismiss = (event) => {
28
26
  event.stopPropagation();
29
- if (this.dispatchEvent(new HelixDismissEvent({ label: this.textContent?.trim() ?? '' }))) {
27
+ if (this.dismiss()) {
30
28
  this.remove();
31
29
  }
32
30
  };
@@ -128,12 +126,6 @@ __decorate([
128
126
  __decorate([
129
127
  property({ attribute: 'default-read', type: Boolean })
130
128
  ], HelixHeadlessNotification.prototype, "defaultRead", void 0);
131
- __decorate([
132
- property({ type: Boolean })
133
- ], HelixHeadlessNotification.prototype, "dismissible", void 0);
134
- __decorate([
135
- property({ attribute: 'dismiss-label' })
136
- ], HelixHeadlessNotification.prototype, "dismissLabel", void 0);
137
129
  __decorate([
138
130
  property()
139
131
  ], HelixHeadlessNotification.prototype, "locale", void 0);
@@ -201,16 +201,6 @@ export declare class HelixHeadlessNotifications extends HelixHeadlessNotificatio
201
201
  * which React reports on hydration and does not patch up.
202
202
  */
203
203
  private markEmpty;
204
- /**
205
- * One region, hidden when its slot holds nothing and nothing of ours fills it.
206
- *
207
- * `hidden` beside the `data-empty` mirror: `data-empty` is the hook the styled
208
- * sheet reads, and this tier ships no sheet, so an empty region left in the box
209
- * tree would be a gap a headless consumer cannot close without knowing to look
210
- * for it. The styled rule stays too, because that sheet sets `display` on these
211
- * parts and therefore outranks the UA's `[hidden]` one.
212
- */
213
- private markRegion;
214
204
  protected updated(changed: PropertyValues): void;
215
205
  protected render(): TemplateResult;
216
206
  private readonly handleMarkAll;
@@ -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 { customElement, HelixElement, HelixReadEvent, hostAria, MixinCollection, slotFilled, } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, HelixReadEvent, hostAria, MixinCollection, markRegion, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinCollection(HelixElement) {
@@ -107,14 +107,8 @@ let HelixHeadlessNotifications = class HelixHeadlessNotifications extends MixinC
107
107
  this.toggleState('media', this.items.some((item) => item.querySelector(':scope > [slot="media"]') !== null));
108
108
  }
109
109
  markEmpty() {
110
- this.markRegion('header', ['header'], '[part="mark-all"]');
111
- this.markRegion('footer', ['footer']);
112
- }
113
- markRegion(part, slots, occupied) {
114
- const region = this.renderRoot?.querySelector(`[part="${part}"]`);
115
- const empty = !slots.some((name) => slotFilled(this.renderRoot?.querySelector(`slot[name="${name}"]`))) && !(occupied && this.renderRoot?.querySelector(occupied));
116
- region?.toggleAttribute('data-empty', empty);
117
- region?.toggleAttribute('hidden', empty);
110
+ markRegion(this.renderRoot, 'header', ['header'], { occupied: '[part="mark-all"]' });
111
+ markRegion(this.renderRoot, 'footer', ['footer']);
118
112
  }
119
113
  updated(changed) {
120
114
  super.updated(changed);
@@ -177,7 +177,7 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
177
177
  }
178
178
  return html `<label
179
179
  part="label"
180
- for="control"
180
+ for=${this.controlId}
181
181
  ?data-hidden=${hidden !== null}
182
182
  @pointercancel=${this.handleScrubEnd}
183
183
  @pointerdown=${this.handleScrubDown}
@@ -254,7 +254,7 @@ let HelixHeadlessNumberInput = class HelixHeadlessNumberInput extends MixinContr
254
254
  ${''}
255
255
  <input
256
256
  part="control"
257
- id="control"
257
+ id=${this.controlId}
258
258
  .value=${this.value}
259
259
  type="text"
260
260
  role="spinbutton"
@@ -1,5 +1,6 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { type TemplateResult } from 'lit';
3
+ declare const HelixHeadlessRadio_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
3
4
  /**
4
5
  * @summary One choice in a radio group.
5
6
  *
@@ -41,11 +42,7 @@ import { type PropertyValues, type TemplateResult } from 'lit';
41
42
  *
42
43
  * @cssstate selected - While it is the one chosen.
43
44
  */
44
- export declare class HelixHeadlessRadio extends HelixElement {
45
- /**
46
- * Whether this choice can be made.
47
- */
48
- disabled: boolean;
45
+ export declare class HelixHeadlessRadio extends HelixHeadlessRadio_base {
49
46
  /**
50
47
  * Whether the markup declared this one chosen, which is what a reset returns to.
51
48
  *
@@ -92,36 +89,6 @@ export declare class HelixHeadlessRadio extends HelixElement {
92
89
  * same reason.
93
90
  */
94
91
  focusable: boolean;
95
- /**
96
- * Whether this is the current choice.
97
- *
98
- * Written by the group.
99
- */
100
- selected: boolean;
101
- /**
102
- * Identifies this choice to the group, and is what the form submits.
103
- */
104
- value: string;
105
- /** Moves focus to this choice, for the group's arrow keys. */
106
- focusItem(): void;
107
- /** Makes this choice and announces it. */
108
- select(): void;
109
- /**
110
- * Mirrors the chosen state where a stylesheet can select on it.
111
- *
112
- * **A custom state rather than the `selected` attribute.** The parent writes
113
- * this: a listbox choosing a row, a tab strip moving the tab, a radio group
114
- * answering for its set. Reflected, that puts the element's own bookkeeping
115
- * onto markup a consumer wrote and a consumer's server never sent, which
116
- * React reconciles and reports as a mismatch, and which a serialized element
117
- * pasted back declares as a choice nobody made. `ElementInternals` holds it
118
- * instead, where it is not in the DOM at all.
119
- *
120
- * Reading `selected` is unaffected and so is writing it: the attribute still
121
- * seeds the property, which is what `<helix-radio selected>` in a consumer's
122
- * markup means. There is no write back.
123
- */
124
- protected willUpdate(changed: PropertyValues): void;
125
92
  protected render(): TemplateResult;
126
93
  }
127
94
  declare global {
@@ -129,3 +96,4 @@ declare global {
129
96
  'helix-headless-radio': HelixHeadlessRadio;
130
97
  }
131
98
  }
99
+ export {};
@@ -4,16 +4,13 @@ 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 { customElement, HelixElement, HelixSelectEvent } from '@fusion.dev/helix-core';
7
+ import { customElement, HelixElement, MixinSelectableItem } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- let HelixHeadlessRadio = class HelixHeadlessRadio extends HelixElement {
10
+ let HelixHeadlessRadio = class HelixHeadlessRadio extends MixinSelectableItem(HelixElement) {
11
11
  constructor() {
12
12
  super(...arguments);
13
- this.disabled = false;
14
13
  this.focusable = false;
15
- this.selected = false;
16
- this.value = '';
17
14
  }
18
15
  get defaultSelected() {
19
16
  return this.hasAttribute('selected');
@@ -21,19 +18,6 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends HelixElement {
21
18
  set defaultSelected(next) {
22
19
  this.toggleAttribute('selected', next);
23
20
  }
24
- focusItem() {
25
- this.partNamed('item')?.focus();
26
- }
27
- select() {
28
- if (this.disabled) {
29
- return;
30
- }
31
- this.dispatchEvent(new HelixSelectEvent({ value: this.value }));
32
- }
33
- willUpdate(changed) {
34
- super.willUpdate(changed);
35
- this.toggleState('selected', this.selected);
36
- }
37
21
  render() {
38
22
  return html `<button
39
23
  part="item"
@@ -50,18 +34,9 @@ let HelixHeadlessRadio = class HelixHeadlessRadio extends HelixElement {
50
34
  </button>`;
51
35
  }
52
36
  };
53
- __decorate([
54
- property({ reflect: true, type: Boolean })
55
- ], HelixHeadlessRadio.prototype, "disabled", void 0);
56
37
  __decorate([
57
38
  property({ attribute: false })
58
39
  ], HelixHeadlessRadio.prototype, "focusable", void 0);
59
- __decorate([
60
- property({ type: Boolean })
61
- ], HelixHeadlessRadio.prototype, "selected", void 0);
62
- __decorate([
63
- property()
64
- ], HelixHeadlessRadio.prototype, "value", void 0);
65
40
  HelixHeadlessRadio = __decorate([
66
41
  customElement('helix-headless-radio')
67
42
  ], HelixHeadlessRadio);
@@ -4,12 +4,10 @@ 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 { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
7
+ import { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, HelixElement, linear, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  import '../../tooltip/index.js';
11
- const WIDTH = 100;
12
- const HEIGHT = 100;
13
11
  const REACH = 24;
14
12
  const coefficient = new Intl.NumberFormat(undefined, {
15
13
  maximumFractionDigits: 2,
@@ -62,7 +60,8 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
62
60
  let found;
63
61
  let best = REACH ** 2;
64
62
  for (const point of this.drawn) {
65
- const distance = ((point.x / WIDTH) * box.width - across) ** 2 + ((point.y / HEIGHT) * box.height - up) ** 2;
63
+ const distance = ((point.x / PLOT_WIDTH) * box.width - across) ** 2 +
64
+ ((point.y / PLOT_HEIGHT) * box.height - up) ** 2;
66
65
  if (distance <= best) {
67
66
  best = distance;
68
67
  found = point;
@@ -112,8 +111,8 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
112
111
  const all = pairs.flat();
113
112
  const x = nice(extent(all.length > 0 ? all.map(([one]) => one) : [0]));
114
113
  const y = nice(extent(all.length > 0 ? all.map(([, one]) => one) : [0]));
115
- const along = linear(x, [0, WIDTH]);
116
- const up = linear(y, [HEIGHT, 0]);
114
+ const along = linear(x, [0, PLOT_WIDTH]);
115
+ const up = linear(y, [PLOT_HEIGHT, 0]);
117
116
  return {
118
117
  pairs: pairs.map((series) => series.map(([one, two]) => [one, two])),
119
118
  points: pairs.flatMap((series, depth) => series.map(([one, two, row]) => ({ depth, row, x: along(one), y: up(two) }))),
@@ -132,8 +131,8 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
132
131
  </div>`;
133
132
  }
134
133
  const format = formatNumbers('');
135
- const along = linear(field.x, [0, WIDTH]);
136
- const up = linear(field.y, [HEIGHT, 0]);
134
+ const along = linear(field.x, [0, PLOT_WIDTH]);
135
+ const up = linear(field.y, [PLOT_HEIGHT, 0]);
137
136
  return html `<div dir="ltr" part="plane">
138
137
  ${this.renderPlot(field, along, up)}
139
138
  <div aria-hidden="true" part="x-axis">
@@ -152,14 +151,14 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
152
151
  return html `<div aria-hidden="true" id=${CHART_PLOT} part="plot">
153
152
  <svg part="svg"
154
153
  preserveAspectRatio="none"
155
- viewBox="0 0 ${WIDTH} ${HEIGHT}"
154
+ viewBox="0 0 ${PLOT_WIDTH} ${PLOT_HEIGHT}"
156
155
  xmlns="http://www.w3.org/2000/svg"
157
156
  >
158
157
  ${this.rulesX
159
- ? ticks(field.x).map((level) => svg `<line part="gridline" x1=${along(level)} x2=${along(level)} y1="0" y2=${HEIGHT} />`)
158
+ ? ticks(field.x).map((level) => svg `<line part="gridline" x1=${along(level)} x2=${along(level)} y1="0" y2=${PLOT_HEIGHT} />`)
160
159
  : nothing}
161
160
  ${this.rulesY
162
- ? ticks(field.y).map((level) => svg `<line part="gridline" x1="0" x2=${WIDTH} y1=${up(level)} y2=${up(level)} />`)
161
+ ? ticks(field.y).map((level) => svg `<line part="gridline" x1="0" x2=${PLOT_WIDTH} y1=${up(level)} y2=${up(level)} />`)
163
162
  : nothing}
164
163
  </svg>
165
164
  ${field.points.map((point) => {
@@ -142,7 +142,7 @@ let HelixHeadlessSelect = class HelixHeadlessSelect extends MixinControllerOpen(
142
142
  return html `${this.renderLabel()}
143
143
  <button
144
144
  part="trigger"
145
- id="control"
145
+ id=${this.controlId}
146
146
  type="button"
147
147
  aria-haspopup="listbox"
148
148
  aria-expanded=${this.open ? 'true' : 'false'}
@@ -146,7 +146,7 @@ let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue
146
146
  ? nothing
147
147
  : html `<input
148
148
  part="control"
149
- id="control"
149
+ id=${this.controlId}
150
150
  type="range"
151
151
  style="--slider-fraction: ${this.fraction}"
152
152
  min=${this.min}
@@ -4,13 +4,11 @@ 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 { customElement, extent, HelixElement, linear, linePath, SourceController, } from '@fusion.dev/helix-core';
7
+ import { customElement, extent, HelixElement, linear, linePath, PLOT_WIDTH, SourceController, writtenList, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing, svg } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
- const BOX = { height: 32, width: 100 };
11
- const readValues = (input) => input
12
- .split(/[\s,]+/)
13
- .filter((one) => one !== '')
10
+ const STRIP_HEIGHT = 32;
11
+ const readValues = (input) => writtenList(input)
14
12
  .map(Number)
15
13
  .filter((one) => Number.isFinite(one));
16
14
  let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
@@ -34,17 +32,17 @@ let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
34
32
  }
35
33
  render() {
36
34
  const points = this.points();
37
- const x = linear([0, Math.max(points.length - 1, 1)], [0, BOX.width]);
35
+ const x = linear([0, Math.max(points.length - 1, 1)], [0, PLOT_WIDTH]);
38
36
  const [low, high] = extent(points.length > 0 ? points : [0]);
39
37
  const y = this.plot === 'bar'
40
- ? linear([Math.min(0, low), Math.max(0, high)], [BOX.height, 0])
41
- : linear([low, high], [BOX.height, 0]);
38
+ ? linear([Math.min(0, low), Math.max(0, high)], [STRIP_HEIGHT, 0])
39
+ : linear([low, high], [STRIP_HEIGHT, 0]);
42
40
  const coordinates = points.map((value, index) => [x(index), y(value)]);
43
41
  const path = this.plot === 'bar' ? '' : linePath(coordinates, this.curve ?? 'smooth');
44
42
  const area = this.plot !== 'bar' && this.plot !== 'line' && path !== ''
45
- ? `${path}L${BOX.width},${BOX.height}L0,${BOX.height}Z`
43
+ ? `${path}L${PLOT_WIDTH},${STRIP_HEIGHT}L0,${STRIP_HEIGHT}Z`
46
44
  : '';
47
- const slot = BOX.width / Math.max(points.length, 1);
45
+ const slot = PLOT_WIDTH / Math.max(points.length, 1);
48
46
  const floor = y(0);
49
47
  const bars = this.plot === 'bar'
50
48
  ? points.map((value, index) => ({
@@ -56,7 +54,7 @@ let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
56
54
  : [];
57
55
  const end = points.length < 2
58
56
  ? undefined
59
- : `--chart-terminus-x: 100%; --chart-terminus-y: ${(y(points[points.length - 1]) / BOX.height) * 100}%`;
57
+ : `--chart-terminus-x: 100%; --chart-terminus-y: ${(y(points[points.length - 1]) / STRIP_HEIGHT) * 100}%`;
60
58
  return html `<svg
61
59
  aria-hidden=${this.label === '' ? 'true' : nothing}
62
60
  aria-label=${this.label === '' ? nothing : this.label}
@@ -65,7 +63,7 @@ let HelixHeadlessSparkline = class HelixHeadlessSparkline extends HelixElement {
65
63
  preserveAspectRatio="none"
66
64
  role=${this.label === '' ? nothing : 'img'}
67
65
  style=${end ?? nothing}
68
- viewBox="0 0 ${BOX.width} ${BOX.height}"
66
+ viewBox="0 0 ${PLOT_WIDTH} ${STRIP_HEIGHT}"
69
67
  >
70
68
  ${svg `<defs>
71
69
  <linearGradient id="sparkline-wash" x1="0" x2="0" y1="0" y2="1">
@@ -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 { AriaForwardController, customElement, HelixFormElement, MixinControllerChecked, MixinField, slotFilled, } from '@fusion.dev/helix-core';
7
+ import { AriaForwardController, customElement, HelixFormElement, MixinControllerChecked, MixinField, markRegion, } from '@fusion.dev/helix-core';
8
8
  import { html, nothing } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerChecked(MixinField(HelixFormElement)) {
@@ -38,10 +38,7 @@ let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerCheck
38
38
  this.sync();
39
39
  }
40
40
  markEmpty() {
41
- const region = this.partNamed('label');
42
- const empty = !slotFilled(this.renderRoot?.querySelector('[part="label"] slot'));
43
- region?.toggleAttribute('data-empty', empty);
44
- region?.toggleAttribute('hidden', empty);
41
+ markRegion(this.renderRoot, 'label', ['']);
45
42
  }
46
43
  render() {
47
44
  return html `<label part="field">
@@ -1,5 +1,6 @@
1
1
  import { HelixElement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { type TemplateResult } from 'lit';
3
+ declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
3
4
  /**
4
5
  * @summary One tab in a tab list.
5
6
  *
@@ -24,39 +25,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
24
25
  *
25
26
  * @cssstate selected - While it is the tab selected.
26
27
  */
27
- export declare class HelixHeadlessTab extends HelixElement {
28
- /**
29
- * Whether the tab can be chosen.
30
- */
31
- disabled: boolean;
32
- /**
33
- * Whether this tab is the current one.
34
- */
35
- selected: boolean;
36
- /**
37
- * Identifies the tab, and pairs it with the panel of the same value.
38
- */
39
- value: string;
40
- /** Moves focus to this tab, for the list's arrow keys. */
41
- focusItem(): void;
42
- /** Selects this tab and announces it. */
43
- select(): void;
44
- /**
45
- * Mirrors the chosen state where a stylesheet can select on it.
46
- *
47
- * **A custom state, not a reflected `selected` attribute.** The parent writes
48
- * this: a listbox choosing a row, a tab strip moving the tab, a radio group
49
- * answering for its set. Reflected, it puts the element's own bookkeeping onto
50
- * markup a consumer wrote and a consumer's server never sent, which React
51
- * reconciles and reports as a mismatch, and which a serialized element pasted
52
- * back declares as a choice nobody made. `ElementInternals` holds it instead,
53
- * where it is not in the DOM at all.
54
- *
55
- * Reading `selected` is unaffected and so is writing it: the attribute still
56
- * seeds the property, which is what `<helix-tab selected>` in a consumer's
57
- * markup means. What stops is the write back.
58
- */
59
- protected willUpdate(changed: PropertyValues): void;
28
+ export declare class HelixHeadlessTab extends HelixHeadlessTab_base {
29
+ protected itemPart: string;
60
30
  protected render(): TemplateResult;
61
31
  }
62
32
  declare global {
@@ -64,3 +34,4 @@ declare global {
64
34
  'helix-headless-tab': HelixHeadlessTab;
65
35
  }
66
36
  }
37
+ export {};