@fusion.dev/helix-headless 0.23.0 → 0.24.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.
- package/custom-elements.json +48376 -26638
- package/dist/announcement/root/announcement-root.d.ts +19 -5
- package/dist/area-chart/index.d.ts +1 -0
- package/dist/area-chart/index.js +1 -0
- package/dist/area-chart/root/area-chart-root.d.ts +182 -0
- package/dist/area-chart/root/area-chart-root.js +205 -0
- package/dist/carousel/root/carousel-root.d.ts +1 -0
- package/dist/carousel/root/carousel-root.js +18 -2
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/message/chat-message.d.ts +7 -0
- package/dist/chat/message/chat-message.js +2 -1
- package/dist/chat/root/chat-root.d.ts +195 -4
- package/dist/chat/root/chat-root.js +316 -23
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +2 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +12 -2
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/patch.d.ts +62 -0
- package/dist/code-block/patch.js +93 -0
- package/dist/code-block/root/code-block-root.d.ts +82 -17
- package/dist/code-block/root/code-block-root.js +83 -6
- package/dist/color-picker/root/color-picker-root.d.ts +4 -3
- package/dist/color-picker/root/color-picker-root.js +4 -1
- package/dist/data-table/root/data-table-root.d.ts +195 -23
- package/dist/data-table/root/data-table-root.js +308 -27
- package/dist/description-list/index.d.ts +2 -0
- package/dist/description-list/index.js +2 -0
- package/dist/description-list/item/description-list-item.d.ts +39 -0
- package/dist/description-list/item/description-list-item.js +26 -0
- package/dist/description-list/root/description-list-root.d.ts +56 -0
- package/dist/description-list/root/description-list-root.js +21 -0
- package/dist/element-events.generated.js +27 -6
- package/dist/filter-input/chip/filter-chip.d.ts +114 -0
- package/dist/filter-input/chip/filter-chip.js +61 -0
- package/dist/filter-input/field/filter-field.d.ts +128 -0
- package/dist/filter-input/field/filter-field.js +70 -0
- package/dist/filter-input/grammar.d.ts +96 -0
- package/dist/filter-input/grammar.js +133 -0
- package/dist/filter-input/index.d.ts +5 -0
- package/dist/filter-input/index.js +5 -0
- package/dist/filter-input/menu/filter-menu.d.ts +153 -0
- package/dist/filter-input/menu/filter-menu.js +164 -0
- package/dist/filter-input/operator/filter-operator.d.ts +105 -0
- package/dist/filter-input/operator/filter-operator.js +39 -0
- package/dist/filter-input/root/filter-input-root.d.ts +118 -9
- package/dist/filter-input/root/filter-input-root.js +96 -2
- package/dist/format-date/root/format-date-root.js +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/line-chart/root/line-chart-root.d.ts +9 -2
- package/dist/listbox/root/listbox-root.d.ts +8 -7
- package/dist/listbox/root/listbox-root.js +7 -2
- package/dist/menu/item/menu-item.d.ts +31 -6
- package/dist/menu/item/menu-item.js +18 -5
- package/dist/menu/root/menu-root.js +7 -2
- package/dist/notifications/group/notification-group.d.ts +129 -0
- package/dist/notifications/group/notification-group.js +106 -0
- package/dist/notifications/index.d.ts +1 -0
- package/dist/notifications/index.js +1 -0
- package/dist/notifications/notification/notification.d.ts +39 -13
- package/dist/notifications/notification/notification.js +11 -8
- package/dist/notifications/root/notifications-root.d.ts +57 -1
- package/dist/notifications/root/notifications-root.js +35 -4
- package/dist/number-input/root/number-input-root.d.ts +21 -1
- package/dist/number-input/root/number-input-root.js +18 -5
- package/dist/object-inspector/index.d.ts +1 -0
- package/dist/object-inspector/index.js +1 -0
- package/dist/object-inspector/root/object-inspector-root.d.ts +183 -0
- package/dist/object-inspector/root/object-inspector-root.js +348 -0
- package/dist/outline/root/outline-root.d.ts +16 -1
- package/dist/outline/root/outline-root.js +27 -9
- package/dist/radio/group/radio-group.d.ts +1 -0
- package/dist/scatter-chart/index.d.ts +1 -0
- package/dist/scatter-chart/index.js +1 -0
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +144 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +205 -0
- package/dist/skip-link/index.d.ts +1 -0
- package/dist/skip-link/index.js +1 -0
- package/dist/skip-link/root/skip-link-root.d.ts +81 -0
- package/dist/skip-link/root/skip-link-root.js +58 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +1 -0
- package/dist/speed-dial/root/speed-dial-root.js +6 -2
- package/dist/steps/root/steps-root.d.ts +1 -0
- package/dist/table/column/table-column.d.ts +79 -0
- package/dist/table/column/table-column.js +125 -5
- package/dist/table/root/table-root.d.ts +2 -0
- package/dist/table/root/table-root.js +12 -3
- package/dist/time-picker/root/time-picker-root.d.ts +9 -0
- package/dist/time-picker/root/time-picker-root.js +5 -0
- package/dist/toast/root/toast-root.d.ts +2 -0
- package/dist/tooltip/root/tooltip-root.js +1 -1
- package/dist/tour/root/tour-root.d.ts +1 -0
- package/dist/tree/item/tree-item.d.ts +7 -4
- package/dist/tree/item/tree-item.js +4 -1
- package/dist/video/root/video-root.d.ts +23 -1
- package/dist/video/root/video-root.js +42 -22
- package/dist/virtual-list/root/virtual-list-root.d.ts +10 -6
- package/dist/virtual-list/root/virtual-list-root.js +10 -4
- package/package.json +5 -5
- package/types/jsx.d.ts +4535 -346
- package/types/svelte.d.ts +11 -0
- package/types/vue.d.ts +737 -39
|
@@ -46,12 +46,26 @@ export declare class HelixHeadlessAnnouncement extends HelixHeadlessAnnouncement
|
|
|
46
46
|
* Which color the band wears.
|
|
47
47
|
*
|
|
48
48
|
* Paint only: unlike `Callout`, no value here draws a mark, changes the label,
|
|
49
|
-
* or moves the live region off polite.
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
49
|
+
* or moves the live region off polite. `neutral` is the resting value, said
|
|
50
|
+
* out loud so a consumer can put a band back to it from markup.
|
|
51
|
+
*
|
|
52
|
+
* **The set is `Tag`'s and `Badge`'s, and now actually is.** This doc claimed
|
|
53
|
+
* to match `Tag` while differing from it in both directions: it carried
|
|
54
|
+
* `surface`, which `Tag` does not, and lacked `accent`, which `Tag` has. Three
|
|
55
|
+
* components saying what a thing means, in three vocabularies, one of which
|
|
56
|
+
* described itself as a fourth.
|
|
57
|
+
*
|
|
58
|
+
* `accent` is the second emphasis, a rotation off the brand seed rather than a
|
|
59
|
+
* color of its own, so it stays in relation when somebody rethemes. `primary`
|
|
60
|
+
* is the seed itself.
|
|
61
|
+
*
|
|
62
|
+
* **`surface` was never a color and has moved to `separation`**, which is the
|
|
63
|
+
* axis that owns where a box sits relative to the page. It said the band rode
|
|
64
|
+
* the surface step instead of the sunken one, which is an elevation, and a
|
|
65
|
+
* band can be `info` and elevated at once: two values true together are two
|
|
66
|
+
* axes, which is the test the registry answers to.
|
|
53
67
|
*/
|
|
54
|
-
tone?: 'danger' | 'info' | 'neutral' | 'primary' | 'success' | '
|
|
68
|
+
tone?: 'accent' | 'danger' | 'info' | 'neutral' | 'primary' | 'success' | 'warning';
|
|
55
69
|
protected willUpdate(changed: PropertyValues): void;
|
|
56
70
|
protected updated(changed: PropertyValues): void;
|
|
57
71
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/area-chart-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/area-chart-root.js';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { type Curve, HelixElement, type Row } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type TemplateResult } from 'lit';
|
|
3
|
+
import '../../tooltip/index.js';
|
|
4
|
+
/** The table as parts of a total: which columns, what each holds, and the running sums. */
|
|
5
|
+
export interface AreaStack {
|
|
6
|
+
/** The table's columns that hold numbers, by their place among its cells. */
|
|
7
|
+
columns: number[];
|
|
8
|
+
/** Each column's running sum at each reading, the top edge of its band. */
|
|
9
|
+
layers: number[][];
|
|
10
|
+
/** Each column's heading. */
|
|
11
|
+
names: string[];
|
|
12
|
+
/** Every reading's total. */
|
|
13
|
+
totals: number[];
|
|
14
|
+
/** Each column's own reading, not yet summed. */
|
|
15
|
+
values: number[][];
|
|
16
|
+
}
|
|
17
|
+
declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartSourceInterface);
|
|
18
|
+
/**
|
|
19
|
+
* @summary How a total is made up over time, as bands stacked on one another.
|
|
20
|
+
*
|
|
21
|
+
* @description
|
|
22
|
+
* The chart for a composition: every column of the table is a part, the parts
|
|
23
|
+
* sum to the whole at each reading, and the top edge is that whole. What a line
|
|
24
|
+
* chart of the same table cannot show is the share, which here is the
|
|
25
|
+
* thickness of a band.
|
|
26
|
+
*
|
|
27
|
+
* **Not `Line Chart` with `area`.** That washes each series from the floor on
|
|
28
|
+
* its own, so the series overlap; this adds them. Reach for `Line Chart` when
|
|
29
|
+
* the question is how each series moved, and for this when it is how the whole
|
|
30
|
+
* is made up.
|
|
31
|
+
*
|
|
32
|
+
* **It measures from zero, always**, which is `BarChart`'s rule and for the same
|
|
33
|
+
* reason: a band's thickness *is* its value, so a range that starts anywhere
|
|
34
|
+
* else draws every part in proportion to nothing. `LineChart` measures from its
|
|
35
|
+
* own range because a line claims a position; a band claims an amount.
|
|
36
|
+
*
|
|
37
|
+
* **Straight between readings unless asked otherwise.** A band's top edge is a
|
|
38
|
+
* sum, and a curve fitted through one sum can pass under the curve fitted
|
|
39
|
+
* through the sum beneath it, so a smoothed stack can draw a part as less than
|
|
40
|
+
* nothing between two readings. Straight segments between ordered points stay
|
|
41
|
+
* ordered. `curve="smooth"` is there for a stack that is read as a shape.
|
|
42
|
+
*
|
|
43
|
+
* **`share` draws each reading as a hundred percent**, so the bands are the
|
|
44
|
+
* parts' shares and the top edge is flat. It answers "which part grew" where
|
|
45
|
+
* the default answers "did the whole grow".
|
|
46
|
+
*
|
|
47
|
+
* **What a reader without the picture is told is the total and the share**, not
|
|
48
|
+
* every band in turn. The table beside the chart already reads out every
|
|
49
|
+
* number; what the drawing adds is the composition, so the summary says the
|
|
50
|
+
* latest reading's total and each part's share of it. The drawing itself is
|
|
51
|
+
* `aria-hidden`.
|
|
52
|
+
*
|
|
53
|
+
* Every numeric column is a part. A table that carries its own total column
|
|
54
|
+
* would count it twice, so leave it out of the table the chart reads.
|
|
55
|
+
* A negative reading is drawn as none: a part of a whole cannot be less than
|
|
56
|
+
* nothing, and a band that folded under its neighbor would say it was.
|
|
57
|
+
*
|
|
58
|
+
* @since 0.1.0
|
|
59
|
+
* @status experimental
|
|
60
|
+
* @category charts
|
|
61
|
+
* @aliases Stacked Area Chart, Composition Chart, Stream Chart
|
|
62
|
+
* @documentation https://helix.fusion.dev/components/area-chart
|
|
63
|
+
*
|
|
64
|
+
* @csspart area - One part's band.
|
|
65
|
+
* @csspart baseline - The rule at zero, which is the floor of the drawing.
|
|
66
|
+
* @csspart gridline - One rule across the plot, under `gridlines`.
|
|
67
|
+
* @csspart guide - A rule down the reading a pointer is resting on.
|
|
68
|
+
* @csspart label - One reading's name.
|
|
69
|
+
* @csspart labels - The row of reading names.
|
|
70
|
+
* @csspart line - The top edge of one part's band.
|
|
71
|
+
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
72
|
+
* @csspart plot - The drawing.
|
|
73
|
+
* @csspart summary - The total and the shares at the latest reading, for a reader who cannot see the bands.
|
|
74
|
+
* @csspart svg - The drawing surface the bands sit on.
|
|
75
|
+
* @csspart tooltip - The bubble, forwarded from `Tooltip`.
|
|
76
|
+
* @csspart tooltip-anchor - The `Tooltip` element itself.
|
|
77
|
+
* @csspart tooltip-cell - One column's name and value inside the tooltip.
|
|
78
|
+
* @csspart tooltip-label - The reading's own name inside the tooltip.
|
|
79
|
+
* @csspart tooltip-name - A column's name inside the tooltip.
|
|
80
|
+
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
81
|
+
*/
|
|
82
|
+
export declare class HelixHeadlessAreaChart extends HelixHeadlessAreaChart_base {
|
|
83
|
+
/**
|
|
84
|
+
* How a band's edge gets from one reading to the next.
|
|
85
|
+
*
|
|
86
|
+
* Absent is `straight`, for the reason the class doc gives, and absent rather
|
|
87
|
+
* than defaulted because a reflecting property with a default writes its
|
|
88
|
+
* attribute onto every host, including the ones nobody configured.
|
|
89
|
+
*/
|
|
90
|
+
curve?: Curve;
|
|
91
|
+
/**
|
|
92
|
+
* Which rules are drawn across the plot, if any.
|
|
93
|
+
*
|
|
94
|
+
* The same three values `LineChart` takes, with the same fallback: a bare
|
|
95
|
+
* `gridlines`, or anything unrecognized, rules the levels. Drawn over the bands
|
|
96
|
+
* rather than under them, because the bands are opaque and a rule under one is
|
|
97
|
+
* a rule nobody sees.
|
|
98
|
+
*/
|
|
99
|
+
gridlines?: 'both' | 'category' | 'value';
|
|
100
|
+
/**
|
|
101
|
+
* Whether each reading is drawn as a hundred percent.
|
|
102
|
+
*
|
|
103
|
+
* Absent stacks the amounts, so the top edge is the total. Set, every reading
|
|
104
|
+
* fills the height and the bands are shares of it.
|
|
105
|
+
*/
|
|
106
|
+
share: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* What to call the sum of the parts, in the tooltip and the summary.
|
|
109
|
+
*/
|
|
110
|
+
totalLabel: string;
|
|
111
|
+
private warnedAboutNegatives;
|
|
112
|
+
/** Whether the levels are ruled, which is every value but `category`. */
|
|
113
|
+
protected get rulesValue(): boolean;
|
|
114
|
+
/** Whether each reading is ruled, which only two values ask for. */
|
|
115
|
+
protected get rulesCategory(): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* The table as parts of a total.
|
|
118
|
+
*
|
|
119
|
+
* Read from the rows rather than from `series`, because `series` drops a
|
|
120
|
+
* column's empty cells and so numbers each column's readings on its own: a
|
|
121
|
+
* blank in one column would slide every reading after it one place left, and
|
|
122
|
+
* a sum across columns would then add different months together. A blank is
|
|
123
|
+
* none of that part, which is what a blank in a breakdown means.
|
|
124
|
+
*/
|
|
125
|
+
protected get stack(): AreaStack;
|
|
126
|
+
/**
|
|
127
|
+
* Says once that a reading was below zero, and what was drawn instead.
|
|
128
|
+
*
|
|
129
|
+
* Once per element, and in a browser only: a server render warning per
|
|
130
|
+
* request is one nobody can act on.
|
|
131
|
+
*/
|
|
132
|
+
private warnNegative;
|
|
133
|
+
protected render(): TemplateResult;
|
|
134
|
+
/**
|
|
135
|
+
* The bands, behind a seam the styled tier can move.
|
|
136
|
+
*
|
|
137
|
+
* **Each band is drawn as everything beneath its top edge, the widest first.**
|
|
138
|
+
* The next one down then covers the lower part of it, so what shows of each is
|
|
139
|
+
* the strip between its edge and the edge below. Drawing each band as its own
|
|
140
|
+
* closed strip would need the edge below traced backwards, and a curve traced
|
|
141
|
+
* backwards is not guaranteed to be the same curve: the two would part by a
|
|
142
|
+
* hairline and the page would show through between every pair.
|
|
143
|
+
*/
|
|
144
|
+
protected renderPlot(stack: AreaStack, count: number, x: (value: number) => number, y: (value: number) => number, domain: [number, number]): TemplateResult;
|
|
145
|
+
/** One band: everything under its top edge, and the edge itself. */
|
|
146
|
+
protected renderLayer(layer: number[], depth: number, x: (value: number) => number, y: (value: number) => number): TemplateResult | typeof nothing;
|
|
147
|
+
/** The grid, or nothing, at the levels `ticks` picks and through each reading. */
|
|
148
|
+
protected renderGridlines(x: (value: number) => number, y: (value: number) => number, domain: [number, number], count: number): TemplateResult | typeof nothing;
|
|
149
|
+
/**
|
|
150
|
+
* A rule down the reading the tooltip is about.
|
|
151
|
+
*
|
|
152
|
+
* Over the bands rather than under them, which is the one place this differs
|
|
153
|
+
* from `LineChart`: a line leaves the ground showing, and a stack does not.
|
|
154
|
+
*/
|
|
155
|
+
protected renderGuide(x: (value: number) => number): TemplateResult | typeof nothing;
|
|
156
|
+
/** The reading names, as HTML beside the drawing so they do not scale with it. */
|
|
157
|
+
protected renderLabels(readings: string[]): TemplateResult;
|
|
158
|
+
/**
|
|
159
|
+
* What a reader who cannot see the bands is told.
|
|
160
|
+
*
|
|
161
|
+
* The latest reading, because that is the question a composition is asked
|
|
162
|
+
* first, and the table has every other one. Each part in the table's order,
|
|
163
|
+
* which is the legend's and the bands' order, so the words and the picture
|
|
164
|
+
* name the parts the same way round.
|
|
165
|
+
*/
|
|
166
|
+
protected renderSummary(stack: AreaStack, rows: Row[]): TemplateResult;
|
|
167
|
+
/**
|
|
168
|
+
* The rows the tooltip reads, with each part's share and the total added.
|
|
169
|
+
*
|
|
170
|
+
* The total is a cell of its own with no number on it, so the tooltip gives it
|
|
171
|
+
* no series color: it is the sum of the bands, not a band.
|
|
172
|
+
*/
|
|
173
|
+
private tallied;
|
|
174
|
+
/** What a pointer resting on a reading shows, above the top of the stack. */
|
|
175
|
+
protected renderTooltip(stack: AreaStack, y: (value: number) => number): TemplateResult | typeof nothing;
|
|
176
|
+
}
|
|
177
|
+
declare global {
|
|
178
|
+
interface HTMLElementTagNameMap {
|
|
179
|
+
'helix-headless-area-chart': HelixHeadlessAreaChart;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export {};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, drawTooltip, formatNumbers, HelixElement, linear, linePath, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing, svg } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
import '../../tooltip/index.js';
|
|
11
|
+
const WIDTH = 100;
|
|
12
|
+
const HEIGHT = 100;
|
|
13
|
+
const percent = new Intl.NumberFormat(undefined, { maximumFractionDigits: 0, style: 'percent' });
|
|
14
|
+
let HelixHeadlessAreaChart = class HelixHeadlessAreaChart extends MixinChartSource(HelixElement) {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.share = false;
|
|
18
|
+
this.totalLabel = 'Total';
|
|
19
|
+
this.warnedAboutNegatives = false;
|
|
20
|
+
}
|
|
21
|
+
get rulesValue() {
|
|
22
|
+
return this.gridlines !== undefined && this.gridlines !== 'category';
|
|
23
|
+
}
|
|
24
|
+
get rulesCategory() {
|
|
25
|
+
return this.gridlines === 'both' || this.gridlines === 'category';
|
|
26
|
+
}
|
|
27
|
+
get stack() {
|
|
28
|
+
const rows = this.sourceRows;
|
|
29
|
+
const width = Math.max(0, ...rows.map((row) => row.cells.length));
|
|
30
|
+
const columns = Array.from({ length: width }, (_, column) => column).filter((column) => rows.some((row) => row.cells[column]?.value !== undefined));
|
|
31
|
+
const values = columns.map((column) => rows.map((row) => {
|
|
32
|
+
const value = row.cells[column]?.value ?? 0;
|
|
33
|
+
if (value < 0) {
|
|
34
|
+
this.warnNegative();
|
|
35
|
+
}
|
|
36
|
+
return Math.max(0, value);
|
|
37
|
+
}));
|
|
38
|
+
const totals = rows.map((_, index) => values.reduce((sum, column) => sum + (column[index] ?? 0), 0));
|
|
39
|
+
const drawn = this.share
|
|
40
|
+
? values.map((column) => column.map((value, index) => {
|
|
41
|
+
const total = totals[index] ?? 0;
|
|
42
|
+
return total > 0 ? value / total : 0;
|
|
43
|
+
}))
|
|
44
|
+
: values;
|
|
45
|
+
const layers = [];
|
|
46
|
+
let running = rows.map(() => 0);
|
|
47
|
+
for (const column of drawn) {
|
|
48
|
+
running = running.map((sum, index) => sum + (column[index] ?? 0));
|
|
49
|
+
layers.push(running);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
columns,
|
|
53
|
+
layers,
|
|
54
|
+
names: columns.map((column) => rows.find((row) => row.cells[column])?.cells[column]?.name ?? ''),
|
|
55
|
+
totals,
|
|
56
|
+
values,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
warnNegative() {
|
|
60
|
+
if (this.warnedAboutNegatives || typeof window === 'undefined') {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.warnedAboutNegatives = true;
|
|
64
|
+
console.warn(`<${this.localName}> read a negative number and drew it as none. Its bands are parts of a ` +
|
|
65
|
+
'total, and a part cannot be less than nothing: a band drawn below its neighbor would say ' +
|
|
66
|
+
'the part took some of the one beneath it away. A series that crosses zero is a line, so ' +
|
|
67
|
+
'reach for `helix-line-chart`.');
|
|
68
|
+
}
|
|
69
|
+
render() {
|
|
70
|
+
const rows = this.sourceRows;
|
|
71
|
+
const stack = this.stack;
|
|
72
|
+
if (rows.length === 0 || stack.columns.length === 0) {
|
|
73
|
+
return html `<div id="helix-chart-plot" part="plot"></div>`;
|
|
74
|
+
}
|
|
75
|
+
const top = this.share ? 1 : Math.max(0, ...stack.totals);
|
|
76
|
+
const domain = [0, top > 0 ? top : 1];
|
|
77
|
+
const y = linear(domain, [HEIGHT, 0]);
|
|
78
|
+
const slot = WIDTH / rows.length;
|
|
79
|
+
const x = linear([0, Math.max(rows.length - 1, 1)], [slot / 2, WIDTH - slot / 2]);
|
|
80
|
+
return html `${this.renderPlot(stack, rows.length, x, y, domain)}
|
|
81
|
+
${this.renderLabels(rows.map((row) => row.label))} ${this.renderSummary(stack, rows)}`;
|
|
82
|
+
}
|
|
83
|
+
renderPlot(stack, count, x, y, domain) {
|
|
84
|
+
const order = stack.layers.map((_, depth) => depth).reverse();
|
|
85
|
+
return html `<div aria-hidden="true" id="helix-chart-plot" part="plot">
|
|
86
|
+
<svg part="svg"
|
|
87
|
+
preserveAspectRatio="none"
|
|
88
|
+
viewBox="0 0 ${WIDTH} ${HEIGHT}"
|
|
89
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
90
|
+
>
|
|
91
|
+
${order.map((depth) => this.renderLayer(stack.layers[depth] ?? [], depth, x, y))}
|
|
92
|
+
${this.renderGridlines(x, y, domain, count)}
|
|
93
|
+
<line part="baseline" x1="0" x2=${WIDTH} y1=${HEIGHT} y2=${HEIGHT} />
|
|
94
|
+
${this.renderGuide(x)}
|
|
95
|
+
</svg>
|
|
96
|
+
${this.renderTooltip(stack, y)}
|
|
97
|
+
</div>`;
|
|
98
|
+
}
|
|
99
|
+
renderLayer(layer, depth, x, y) {
|
|
100
|
+
const points = layer.map((value, index) => [x(index), y(value)]);
|
|
101
|
+
const path = linePath(points, this.curve ?? 'straight');
|
|
102
|
+
if (path === '') {
|
|
103
|
+
return nothing;
|
|
104
|
+
}
|
|
105
|
+
const index = seriesIndex(depth);
|
|
106
|
+
const first = points[0];
|
|
107
|
+
const last = points.at(-1);
|
|
108
|
+
const wash = `${path}L${last[0]},${HEIGHT}L${first[0]},${HEIGHT}Z`;
|
|
109
|
+
return svg `<path
|
|
110
|
+
d=${wash}
|
|
111
|
+
data-series=${index}
|
|
112
|
+
part="area"
|
|
113
|
+
style="--chart-series: var(--chart-series-${index})"
|
|
114
|
+
/><path
|
|
115
|
+
d=${path}
|
|
116
|
+
data-series=${index}
|
|
117
|
+
fill="none"
|
|
118
|
+
part="line"
|
|
119
|
+
style="--chart-series: var(--chart-series-${index})"
|
|
120
|
+
/>`;
|
|
121
|
+
}
|
|
122
|
+
renderGridlines(x, y, domain, count) {
|
|
123
|
+
if (this.gridlines === undefined) {
|
|
124
|
+
return nothing;
|
|
125
|
+
}
|
|
126
|
+
const down = this.rulesCategory
|
|
127
|
+
? Array.from({ length: count }, (_, index) => svg `<line part="gridline" x1=${x(index)} x2=${x(index)} y1="0" y2=${HEIGHT} />`)
|
|
128
|
+
: [];
|
|
129
|
+
const across = this.rulesValue
|
|
130
|
+
? ticks(domain)
|
|
131
|
+
.filter((level) => level > domain[0])
|
|
132
|
+
.map((level) => svg `<line part="gridline" x1="0" x2=${WIDTH} y1=${y(level)} y2=${y(level)} />`)
|
|
133
|
+
: [];
|
|
134
|
+
return svg `${down}${across}`;
|
|
135
|
+
}
|
|
136
|
+
renderGuide(x) {
|
|
137
|
+
const at = this.pointer.at;
|
|
138
|
+
if (at < 0) {
|
|
139
|
+
return nothing;
|
|
140
|
+
}
|
|
141
|
+
return svg `<line part="guide" x1=${x(at)} x2=${x(at)} y1="0" y2=${HEIGHT} />`;
|
|
142
|
+
}
|
|
143
|
+
renderLabels(readings) {
|
|
144
|
+
return html `<div aria-hidden="true" part="labels">
|
|
145
|
+
${readings.map((one) => html `<span part="label">${one}</span>`)}
|
|
146
|
+
</div>`;
|
|
147
|
+
}
|
|
148
|
+
renderSummary(stack, rows) {
|
|
149
|
+
const last = rows.length - 1;
|
|
150
|
+
const total = stack.totals[last] ?? 0;
|
|
151
|
+
const format = formatNumbers('');
|
|
152
|
+
const shares = stack.names.map((name, depth) => `${name} ${percent.format(total > 0 ? (stack.values[depth]?.[last] ?? 0) / total : 0)}`);
|
|
153
|
+
const named = this.named ? `${this.named}, ` : '';
|
|
154
|
+
return html `<p part="summary">
|
|
155
|
+
${named}${rows[last]?.label ?? ''}: ${this.totalLabel} ${format(total)}; ${shares.join(', ')}.
|
|
156
|
+
</p>`;
|
|
157
|
+
}
|
|
158
|
+
tallied(rows, stack) {
|
|
159
|
+
const format = formatNumbers('');
|
|
160
|
+
return rows.map((row, index) => {
|
|
161
|
+
const total = stack.totals[index] ?? 0;
|
|
162
|
+
return {
|
|
163
|
+
...row,
|
|
164
|
+
cells: [
|
|
165
|
+
...row.cells.map((cell, column) => this.share && cell.value !== undefined && stack.columns.includes(column) && total > 0
|
|
166
|
+
? {
|
|
167
|
+
...cell,
|
|
168
|
+
text: `${cell.text} (${percent.format(Math.max(0, cell.value) / total)})`,
|
|
169
|
+
}
|
|
170
|
+
: cell),
|
|
171
|
+
{ name: this.totalLabel, text: format(total) },
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
renderTooltip(stack, y) {
|
|
177
|
+
const at = this.pointer.at;
|
|
178
|
+
const rows = this.tallied(this.sourceRows, stack);
|
|
179
|
+
if (at < 0) {
|
|
180
|
+
return drawTooltip(rows, at, this.tag('tooltip'));
|
|
181
|
+
}
|
|
182
|
+
const slot = 100 / rows.length;
|
|
183
|
+
return drawTooltip(rows, at, this.tag('tooltip'), {
|
|
184
|
+
placement: 'top',
|
|
185
|
+
x: `${at * slot + slot / 2}%`,
|
|
186
|
+
y: `${y(stack.layers.at(-1)?.[at] ?? 0)}%`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
__decorate([
|
|
191
|
+
property({ reflect: true })
|
|
192
|
+
], HelixHeadlessAreaChart.prototype, "curve", void 0);
|
|
193
|
+
__decorate([
|
|
194
|
+
property()
|
|
195
|
+
], HelixHeadlessAreaChart.prototype, "gridlines", void 0);
|
|
196
|
+
__decorate([
|
|
197
|
+
property({ reflect: true, type: Boolean })
|
|
198
|
+
], HelixHeadlessAreaChart.prototype, "share", void 0);
|
|
199
|
+
__decorate([
|
|
200
|
+
property({ attribute: 'total-label' })
|
|
201
|
+
], HelixHeadlessAreaChart.prototype, "totalLabel", void 0);
|
|
202
|
+
HelixHeadlessAreaChart = __decorate([
|
|
203
|
+
customElement('helix-headless-area-chart')
|
|
204
|
+
], HelixHeadlessAreaChart);
|
|
205
|
+
export { HelixHeadlessAreaChart };
|
|
@@ -350,6 +350,7 @@ export declare class HelixHeadlessCarousel extends HelixElement {
|
|
|
350
350
|
/** Pauses without forgetting that the reader wanted it running. */
|
|
351
351
|
private readonly pause;
|
|
352
352
|
protected willUpdate(changed: PropertyValues): void;
|
|
353
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
353
354
|
protected updated(changed: PropertyValues): void;
|
|
354
355
|
/**
|
|
355
356
|
* Puts each slide into the pane rendered for it.
|
|
@@ -92,7 +92,7 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
92
92
|
return [...(this.renderRoot?.querySelectorAll?.('[part="slide"]') ?? [])];
|
|
93
93
|
}
|
|
94
94
|
get slides() {
|
|
95
|
-
return
|
|
95
|
+
return this.knownChildren.filter((child) => child instanceof HTMLElement);
|
|
96
96
|
}
|
|
97
97
|
goTo(index) {
|
|
98
98
|
if (this.slides.length === 0) {
|
|
@@ -195,9 +195,16 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
195
195
|
if (!this.hasUpdated) {
|
|
196
196
|
this.rotating = this.autoplay;
|
|
197
197
|
}
|
|
198
|
+
if (changed.has('index')) {
|
|
199
|
+
this.showing = undefined;
|
|
200
|
+
}
|
|
198
201
|
hostAria(this.internals, { label: this.label, role: 'group' });
|
|
199
202
|
this.internals.ariaRoleDescription = 'carousel';
|
|
200
203
|
}
|
|
204
|
+
firstUpdated(changed) {
|
|
205
|
+
super.firstUpdated(changed);
|
|
206
|
+
this.finishHydration();
|
|
207
|
+
}
|
|
201
208
|
updated(changed) {
|
|
202
209
|
super.updated(changed);
|
|
203
210
|
if (changed.has('index')) {
|
|
@@ -211,6 +218,12 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
211
218
|
this.assign();
|
|
212
219
|
}
|
|
213
220
|
assign() {
|
|
221
|
+
if (this.assignsByName) {
|
|
222
|
+
this.slides.forEach((slide, index) => {
|
|
223
|
+
this.route(slide, `slide-${index + 1}`);
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
214
227
|
const panes = this.renderRoot?.querySelectorAll?.('[part="slide"] slot');
|
|
215
228
|
if (!panes) {
|
|
216
229
|
return;
|
|
@@ -276,7 +289,10 @@ let HelixHeadlessCarousel = class HelixHeadlessCarousel extends HelixElement {
|
|
|
276
289
|
aria-roledescription="slide"
|
|
277
290
|
aria-label=${`${index + 1} of ${this.slides.length}`}
|
|
278
291
|
>
|
|
279
|
-
<slot
|
|
292
|
+
<slot
|
|
293
|
+
name=${this.assignsByName ? `slide-${index + 1}` : nothing}
|
|
294
|
+
@slotchange=${() => this.requestUpdate()}
|
|
295
|
+
></slot>
|
|
280
296
|
</div>`)}
|
|
281
297
|
</div>
|
|
282
298
|
${this.slides.length > 1
|
package/dist/chat/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { HelixHeadlessChatComposer } from './composer/chat-composer.js';
|
|
2
2
|
export { HelixHeadlessChatMessage } from './message/chat-message.js';
|
|
3
|
-
export { HelixHeadlessChat } from './root/chat-root.js';
|
|
3
|
+
export { type ChatTurn, HelixHeadlessChat } from './root/chat-root.js';
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* What a turn that did not send is called, where nobody said otherwise.
|
|
5
|
+
*
|
|
6
|
+
* Exported because the transcript says it too: a failure is announced in the
|
|
7
|
+
* words the turn shows, and two defaults for one phrase are two phrases.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FAILED_LABEL = "Not sent";
|
|
3
10
|
/**
|
|
4
11
|
* @summary One turn in a conversation, and what has happened to it.
|
|
5
12
|
*
|
|
@@ -8,11 +8,12 @@ import { customElement, HelixElement, HelixSendEvent, hostAria, relativeTime, sl
|
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property, state } from 'lit/decorators.js';
|
|
10
10
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
11
|
+
export const FAILED_LABEL = 'Not sent';
|
|
11
12
|
let HelixHeadlessChatMessage = class HelixHeadlessChatMessage extends HelixElement {
|
|
12
13
|
constructor() {
|
|
13
14
|
super(...arguments);
|
|
14
15
|
this.at = '';
|
|
15
|
-
this.failedLabel =
|
|
16
|
+
this.failedLabel = FAILED_LABEL;
|
|
16
17
|
this.locale = '';
|
|
17
18
|
this.retryLabel = 'Try again';
|
|
18
19
|
this.sendingLabel = 'Sending';
|