@fusion.dev/helix-headless 0.152.0 → 0.154.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 (41) hide show
  1. package/custom-elements.json +1143 -62
  2. package/dist/area-chart/root/area-chart-root.d.ts +16 -1
  3. package/dist/area-chart/root/area-chart-root.js +3 -3
  4. package/dist/badge/root/badge-root.d.ts +15 -2
  5. package/dist/badge/root/badge-root.js +20 -3
  6. package/dist/bar-chart/root/bar-chart-root.d.ts +16 -1
  7. package/dist/bar-chart/root/bar-chart-root.js +3 -3
  8. package/dist/card/root/card-root.d.ts +31 -11
  9. package/dist/card/root/card-root.js +25 -11
  10. package/dist/code/root/code-root.d.ts +7 -0
  11. package/dist/code/root/code-root.js +1 -1
  12. package/dist/code-block/root/code-block-root.d.ts +37 -1
  13. package/dist/code-block/root/code-block-root.js +38 -5
  14. package/dist/empty/root/empty-root.d.ts +19 -1
  15. package/dist/empty/root/empty-root.js +13 -4
  16. package/dist/heatmap/root/heatmap-root.d.ts +3 -0
  17. package/dist/heatmap/root/heatmap-root.js +2 -8
  18. package/dist/icon/fetch.d.ts +20 -0
  19. package/dist/icon/fetch.js +70 -0
  20. package/dist/icon/root/icon-root.d.ts +27 -5
  21. package/dist/icon/root/icon-root.js +41 -17
  22. package/dist/line-chart/root/line-chart-root.d.ts +16 -1
  23. package/dist/line-chart/root/line-chart-root.js +3 -3
  24. package/dist/loader/root/loader-root.d.ts +5 -0
  25. package/dist/progress/root/progress-root.d.ts +16 -1
  26. package/dist/progress/root/progress-root.js +12 -4
  27. package/dist/quote/root/quote-root.d.ts +17 -1
  28. package/dist/quote/root/quote-root.js +15 -2
  29. package/dist/scatter-chart/root/scatter-chart-root.d.ts +16 -1
  30. package/dist/scatter-chart/root/scatter-chart-root.js +3 -3
  31. package/dist/skeleton/root/skeleton-root.d.ts +7 -0
  32. package/dist/skeleton/root/skeleton-root.js +4 -1
  33. package/dist/stat/group/stat-group.d.ts +23 -4
  34. package/dist/stat/group/stat-group.js +13 -1
  35. package/dist/stat/root/stat-root.d.ts +46 -1
  36. package/dist/stat/root/stat-root.js +29 -5
  37. package/lint.json +1 -1
  38. package/package.json +5 -5
  39. package/types/jsx.d.ts +1434 -62
  40. package/types/vue.d.ts +297 -24
  41. package/types/words.d.ts +69 -0
@@ -24,7 +24,7 @@ export interface ScatterField {
24
24
  y: [number, number];
25
25
  yNames: string[];
26
26
  }
27
- declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartSourceInterface);
27
+ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartSourceInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartStatusInterface);
28
28
  /**
29
29
  * @summary A chart that shows whether two measures move together, with one point per row.
30
30
  *
@@ -71,17 +71,32 @@ declare const HelixHeadlessScatterChart_base: typeof HelixElement & (new (...arg
71
71
  * tap or key, and `helix-reading-press` says a reading was clicked, tapped, or
72
72
  * pressed with Enter or Space, for a page that opens what a reading stands for.
73
73
  *
74
+ * **`data` takes the readings as data** where the page has no table to point
75
+ * `for` at, in a table's shape: the column headings, then one row per reading
76
+ * with its label first. A table is still the better source where the page can
77
+ * show one, since it reads before any script runs.
78
+ *
79
+ * **A chart with nothing to draw says so.** A table with no readings shows
80
+ * `empty-text`, "No readings", in the plot, and `loading` shows `loading-text`
81
+ * there until readings arrive. The `empty` and `loading` slots take markup in
82
+ * their place, such as a link to add the first reading.
83
+ *
74
84
  * @since 0.1.0
75
85
  * @status stable
76
86
  * @category charts
77
87
  * @aliases Scatter Plot, XY Chart, Correlation Chart, Dot Plot
78
88
  * @documentation https://fusion.dev/helix/components/scatter-chart
79
89
  *
90
+ * @slot empty - Content shown in place of the drawing when the table has no readings, such as a link to add the first. Falls back to `empty-text`.
91
+ * @slot loading - Content shown in place of the drawing while `loading` is set and there are no readings yet. Falls back to `loading-text`.
92
+ *
80
93
  * @event {HelixReadingChangeEvent} helix-reading-change - The reading shown moved, or was put away: `index` is the row, or `-1` for none, with its `label`, the `series` the keys rest on, and the `pointerType` that moved it.
81
94
  * @event {HelixReadingPressEvent} helix-reading-press - A reading was clicked, tapped, or pressed with Enter or Space, with the same detail as `helix-reading-change`.
82
95
  *
96
+ * @csspart empty - The words in place of the drawing when the table has no readings: the `empty` slot, falling back to `empty-text`. Not drawn while the table cannot be read yet, on the server and during hydration.
83
97
  * @csspart gridline - One line across the plot, drawn when `gridlines` is set.
84
98
  * @csspart live - The readout: a polite live region that says the row the keys moved to. Hide it visually.
99
+ * @csspart loading - The words in place of the drawing while `loading` is set and there are no readings: the `loading` slot, falling back to `loading-text`.
85
100
  * @csspart mark - The invisible point the tooltip is anchored to.
86
101
  * @csspart plane - The grid that holds the plot, both axes, and their names. It runs left to right on every page.
87
102
  * @csspart plot - The drawing, which takes focus to be read by key.
@@ -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 { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, formatWords, HelixElement, HelixReadingChangeEvent, HelixReadingPressEvent, isRtl, linear, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, words, wordsLocale, } from '@fusion.dev/helix-core';
7
+ import { CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, formatWords, HelixElement, HelixReadingChangeEvent, HelixReadingPressEvent, isRtl, linear, MixinChartSource, MixinChartStatus, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, ticks, words, wordsLocale, } 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';
@@ -33,7 +33,7 @@ const nice = ([low, high]) => {
33
33
  const round = (value) => Number(value.toPrecision(12));
34
34
  return [round(Math.floor(low / step) * step), round(Math.ceil(high / step) * step)];
35
35
  };
36
- let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinChartSource(HelixElement) {
36
+ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinChartStatus(MixinChartSource(HelixElement)) {
37
37
  constructor() {
38
38
  super(...arguments);
39
39
  this.correlationLabel = 'correlation';
@@ -140,7 +140,7 @@ let HelixHeadlessScatterChart = class HelixHeadlessScatterChart extends MixinCha
140
140
  this.drawn = field.points;
141
141
  if (field.points.length === 0) {
142
142
  return html `<div dir="ltr" part="plane">
143
- <div id=${CHART_PLOT} part="plot"></div>
143
+ <div id=${CHART_PLOT} part="plot">${this.renderStatus()}</div>
144
144
  </div>`;
145
145
  }
146
146
  const format = formatNumbers(wordsLocale(this));
@@ -61,6 +61,13 @@ export declare class HelixHeadlessSkeleton extends HelixElement {
61
61
  protected willUpdate(changed: PropertyValues): void;
62
62
  protected firstUpdated(changed: PropertyValues): void;
63
63
  protected render(): TemplateResult;
64
+ /**
65
+ * The placeholder shape and the sheen inside it.
66
+ *
67
+ * A method, so a tier above can draw the placeholder as several shapes, as
68
+ * the styled tier draws a paragraph of lines.
69
+ */
70
+ protected renderShape(): TemplateResult;
64
71
  }
65
72
  declare global {
66
73
  interface HTMLElementTagNameMap {
@@ -38,7 +38,10 @@ let HelixHeadlessSkeleton = class HelixHeadlessSkeleton extends HelixElement {
38
38
  render() {
39
39
  return html `<span part="content" ?inert=${this.loading}
40
40
  ><slot @slotchange=${() => this.requestUpdate()}></slot></span
41
- ><span part="skeleton"><span part="sheen"></span></span>`;
41
+ >${this.renderShape()}`;
42
+ }
43
+ renderShape() {
44
+ return html `<span part="skeleton"><span part="sheen"></span></span>`;
42
45
  }
43
46
  };
44
47
  __decorate([
@@ -4,9 +4,12 @@ import { type PropertyValues, type TemplateResult } from 'lit';
4
4
  * @summary A row of related measurements.
5
5
  *
6
6
  * @description
7
- * Screen readers announce the stats as a group. The figures are read together
8
- * and their order has no meaning, so the group does not announce positions such
9
- * as "1 of 4".
7
+ * **A named group is a group**, so a screen reader announces the stats
8
+ * together under its name, such as "Usage, group". Name it with `label`,
9
+ * `aria-label` or `aria-labelledby`. An unnamed one has no role, since a group
10
+ * with no name only adds "group" to what a reader says, as an unnamed Card
11
+ * has none. The figures are read together and their order has no meaning, so
12
+ * the group does not announce positions such as "1 of 4".
10
13
  *
11
14
  * @since 0.1.0
12
15
  * @status stable
@@ -17,9 +20,25 @@ import { type PropertyValues, type TemplateResult } from 'lit';
17
20
  */
18
21
  export declare class HelixHeadlessStatGroup extends HelixElement {
19
22
  /**
20
- * Accessible name for the group.
23
+ * Accessible name for the group, which makes it a group.
24
+ *
25
+ * Absent leaves the stats with no group around them, unless `aria-label` or
26
+ * `aria-labelledby` names it.
21
27
  */
22
28
  label: string;
29
+ /**
30
+ * Hears a name written on the element, which no property mirrors.
31
+ *
32
+ * Lit observes the attributes of its own properties only, and `ariaLabel`
33
+ * and `ariaLabelledByElements` belong to the platform.
34
+ */
35
+ static get observedAttributes(): string[];
36
+ /**
37
+ * Called by the browser when an observed attribute changes. A name written
38
+ * or taken off asks for an update, because it decides whether the stats are
39
+ * a group.
40
+ */
41
+ attributeChangedCallback(name: string, old: string | null, value: string | null): void;
23
42
  protected willUpdate(changed: PropertyValues): void;
24
43
  protected render(): TemplateResult;
25
44
  }
@@ -12,9 +12,21 @@ let HelixHeadlessStatGroup = class HelixHeadlessStatGroup extends HelixElement {
12
12
  super(...arguments);
13
13
  this.label = '';
14
14
  }
15
+ static get observedAttributes() {
16
+ return [...super.observedAttributes, 'aria-label', 'aria-labelledby'];
17
+ }
18
+ attributeChangedCallback(name, old, value) {
19
+ super.attributeChangedCallback(name, old, value);
20
+ if (name === 'aria-label' || name === 'aria-labelledby') {
21
+ this.requestUpdate();
22
+ }
23
+ }
15
24
  willUpdate(changed) {
16
25
  super.willUpdate(changed);
17
- hostAria(this.internals, { label: this.label, role: 'group' });
26
+ const named = this.label.trim() !== '' ||
27
+ Boolean(this.getAttribute?.('aria-label')?.trim()) ||
28
+ Boolean(this.getAttribute?.('aria-labelledby')?.trim());
29
+ hostAria(this.internals, { label: this.label, role: named ? 'group' : '' });
18
30
  }
19
31
  render() {
20
32
  return html `<slot></slot>`;
@@ -19,6 +19,19 @@ import { type PropertyValues, type TemplateResult } from 'lit';
19
19
  * attribute; a stat with no label has no role. Put a `Trend` in the `trend`
20
20
  * slot to have it read inside the group, after the figure it qualifies.
21
21
  *
22
+ * **Or give the figure as a number.** `value` is written with
23
+ * `Intl.NumberFormat`, in `locale` and with `format-options`, so
24
+ * `value="1234567" format-options='{"notation":"compact"}'` shows `1.2M`, and
25
+ * a server writes it as the browser does. A number in `value` takes the place
26
+ * of a slotted figure.
27
+ *
28
+ * **Each slot is a part of the same name**, and `value` for the figure, so a
29
+ * page reaches the label, the unit and the trend from outside. A slot draws no
30
+ * box, so a part passes inherited properties to what is slotted. **The stat
31
+ * says which pieces it holds**, as `:state(has-label)`, `:state(has-unit)` and
32
+ * `:state(has-trend)`, read in the browser, so a served stat carries none
33
+ * until the script runs.
34
+ *
22
35
  * @since 0.1.0
23
36
  * @status stable
24
37
  * @category data
@@ -30,7 +43,14 @@ import { type PropertyValues, type TemplateResult } from 'lit';
30
43
  * @slot trend - How the value moved, usually a `Trend`, read after the value inside the stat's group.
31
44
  * @slot unit - The unit, shown beside the value.
32
45
  *
33
- * @csspart value - The slot the value is written in. A slot draws no box, so it takes the inherited properties, such as color and font, and passes them to the value.
46
+ * @csspart label - The slot the label arrives through, drawing no box, as `value` does.
47
+ * @csspart trend - The slot the trend arrives through, drawing no box, as `value` does.
48
+ * @csspart unit - The slot the unit arrives through, drawing no box, as `value` does.
49
+ * @csspart value - The slot the value is written in, or the figure `value` writes. A slot draws no box, so it takes the inherited properties, such as color and font, and passes them to the value.
50
+ *
51
+ * @cssstate has-label - Something is slotted into `label`.
52
+ * @cssstate has-trend - Something is slotted into `trend`.
53
+ * @cssstate has-unit - Something is slotted into `unit`.
34
54
  */
35
55
  export declare class HelixHeadlessStat extends HelixElement {
36
56
  /**
@@ -61,9 +81,34 @@ export declare class HelixHeadlessStat extends HelixElement {
61
81
  * carries nothing nobody wrote.
62
82
  */
63
83
  direction?: 'column-reverse' | 'row' | 'row-reverse';
84
+ /**
85
+ * `Intl.NumberFormat` options `value` is written with, such as
86
+ * `{"notation":"compact"}` for `1.2M` or `{"style":"percent"}` for `98%`,
87
+ * written as JSON in the attribute.
88
+ *
89
+ * Absent writes the number as the locale writes any number.
90
+ */
91
+ formatOptions?: Intl.NumberFormatOptions;
92
+ /**
93
+ * The locale `value` is written in, such as `de` for `1.234.567`.
94
+ *
95
+ * Absent reads the nearest `lang`, then the runtime's own. Set it on a page
96
+ * rendered on a server, so the server and the browser write the figure
97
+ * alike.
98
+ */
99
+ locale: string;
100
+ /**
101
+ * The figure as a number, written with `format-options` in `locale` in
102
+ * place of a slotted value.
103
+ *
104
+ * Absent leaves the figure to the slot.
105
+ */
106
+ value?: number;
64
107
  protected willUpdate(changed: PropertyValues): void;
65
108
  protected firstUpdated(changed: PropertyValues): void;
66
109
  protected updated(changed: PropertyValues): void;
110
+ /** Says which pieces the stat holds, one call apiece so each pairs with its `@cssstate`. */
111
+ private readonly readPieces;
67
112
  protected render(): TemplateResult;
68
113
  }
69
114
  declare global {
@@ -4,10 +4,20 @@ 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, hostAria, reportRuntime, slottedWords, } from '@fusion.dev/helix-core';
7
+ import { customElement, formatNumber, HelixElement, hostAria, reportRuntime, slotFilled, slottedWords, wordsLocale, } from '@fusion.dev/helix-core';
8
8
  import { html } from 'lit';
9
9
  import { property } from 'lit/decorators.js';
10
10
  let HelixHeadlessStat = class HelixHeadlessStat extends HelixElement {
11
+ constructor() {
12
+ super(...arguments);
13
+ this.locale = '';
14
+ this.readPieces = () => {
15
+ const filled = (name) => slotFilled(this.renderRoot?.querySelector(`slot[name="${name}"]`));
16
+ this.toggleState('has-label', filled('label'));
17
+ this.toggleState('has-unit', filled('unit'));
18
+ this.toggleState('has-trend', filled('trend'));
19
+ };
20
+ }
11
21
  willUpdate(changed) {
12
22
  super.willUpdate(changed);
13
23
  const labels = this.knownChildren.filter((child) => child.slot === 'label');
@@ -25,6 +35,7 @@ let HelixHeadlessStat = class HelixHeadlessStat extends HelixElement {
25
35
  }
26
36
  updated(changed) {
27
37
  super.updated(changed);
38
+ this.readPieces();
28
39
  const given = this.direction;
29
40
  if (changed.has('direction') && (given === 'up' || given === 'down' || given === 'neutral')) {
30
41
  reportRuntime({
@@ -37,15 +48,28 @@ let HelixHeadlessStat = class HelixHeadlessStat extends HelixElement {
37
48
  }
38
49
  }
39
50
  render() {
40
- return html `<slot name="label" @slotchange=${() => this.requestUpdate()}></slot>
41
- <slot part="value"></slot>
42
- <slot name="unit"></slot>
43
- <slot name="trend"></slot>`;
51
+ const value = this.value;
52
+ const figure = value === undefined || !Number.isFinite(value)
53
+ ? ''
54
+ : formatNumber(value, wordsLocale(this), this.formatOptions);
55
+ return html `<slot name="label" part="label" @slotchange=${() => this.requestUpdate()}></slot>
56
+ ${figure === '' ? html `<slot part="value"></slot>` : html `<span part="value">${figure}</span>`}
57
+ <slot name="unit" part="unit" @slotchange=${this.readPieces}></slot>
58
+ <slot name="trend" part="trend" @slotchange=${this.readPieces}></slot>`;
44
59
  }
45
60
  };
46
61
  __decorate([
47
62
  property({ reflect: true })
48
63
  ], HelixHeadlessStat.prototype, "direction", void 0);
64
+ __decorate([
65
+ property({ attribute: 'format-options', type: Object })
66
+ ], HelixHeadlessStat.prototype, "formatOptions", void 0);
67
+ __decorate([
68
+ property()
69
+ ], HelixHeadlessStat.prototype, "locale", void 0);
70
+ __decorate([
71
+ property({ type: Number })
72
+ ], HelixHeadlessStat.prototype, "value", void 0);
49
73
  HelixHeadlessStat = __decorate([
50
74
  customElement('helix-headless-stat')
51
75
  ], HelixHeadlessStat);