@fusion.dev/helix-headless 0.149.1 → 0.151.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 +1211 -110
- package/dist/area-chart/root/area-chart-root.d.ts +36 -0
- package/dist/area-chart/root/area-chart-root.js +17 -2
- package/dist/bar-chart/root/bar-chart-root.d.ts +28 -4
- package/dist/bar-chart/root/bar-chart-root.js +17 -4
- package/dist/button/root/button-root.d.ts +5 -0
- package/dist/button/root/button-root.js +3 -0
- package/dist/callout/root/callout-root.d.ts +20 -0
- package/dist/callout/root/callout-root.js +19 -4
- package/dist/chat/composer/chat-composer.d.ts +30 -0
- package/dist/chat/composer/chat-composer.js +47 -2
- package/dist/chat/root/chat-root.d.ts +10 -0
- package/dist/chat/root/chat-root.js +14 -0
- package/dist/color-input/root/color-input-root.d.ts +1 -0
- package/dist/color-picker/root/color-picker-root.js +1 -0
- package/dist/combobox/root/combobox-root.d.ts +12 -1
- package/dist/combobox/root/combobox-root.js +8 -0
- package/dist/copy-button/root/copy-button-root.d.ts +4 -3
- package/dist/copy-button/root/copy-button-root.js +5 -1
- package/dist/data-table/root/data-table-root.d.ts +34 -2
- package/dist/data-table/root/data-table-root.js +63 -2
- package/dist/date-input/root/date-input-root.d.ts +1 -0
- package/dist/divider/root/divider-root.d.ts +8 -6
- package/dist/divider/root/divider-root.js +10 -2
- package/dist/element-events.generated.js +5 -1
- package/dist/filter-input/chip/filter-chip.d.ts +2 -1
- package/dist/filter-input/root/filter-input-root.d.ts +5 -0
- package/dist/filter-input/root/filter-input-root.js +7 -0
- package/dist/kbd/root/kbd-root.d.ts +7 -1
- package/dist/kbd/root/kbd-root.js +8 -4
- package/dist/line-chart/root/line-chart-root.d.ts +36 -0
- package/dist/line-chart/root/line-chart-root.js +15 -2
- package/dist/number-input/root/number-input-root.d.ts +6 -0
- package/dist/number-input/root/number-input-root.js +14 -3
- package/dist/option/root/option-root.d.ts +17 -8
- package/dist/option/root/option-root.js +18 -4
- package/dist/radio/group/radio-group.d.ts +8 -1
- package/dist/radio/group/radio-group.js +15 -1
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +18 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +38 -15
- package/dist/slider/root/slider-root.d.ts +8 -0
- package/dist/slider/root/slider-root.js +6 -3
- package/dist/table/column/table-column.js +3 -2
- package/dist/table/grid-controller.d.ts +14 -2
- package/dist/table/grid-controller.js +27 -1
- package/dist/table/root/table-root.d.ts +30 -4
- package/dist/table/root/table-root.js +45 -7
- package/dist/table/row/table-row.d.ts +12 -2
- package/dist/table/row/table-row.js +8 -2
- package/dist/tag/group/tag-group.d.ts +22 -1
- package/dist/tag/group/tag-group.js +63 -3
- package/dist/tag/root/tag-root.d.ts +9 -0
- package/dist/tag/root/tag-root.js +5 -1
- package/dist/time-input/root/time-input-root.d.ts +1 -0
- package/dist/toggle/group/toggle-group.d.ts +6 -0
- package/dist/toggle/group/toggle-group.js +16 -1
- package/dist/toggle/root/toggle-root.d.ts +21 -3
- package/dist/toggle/root/toggle-root.js +22 -5
- package/dist/video/root/video-root.d.ts +6 -0
- package/dist/video/root/video-root.js +5 -1
- package/dist/video-playlist/root/video-playlist-root.d.ts +4 -0
- package/dist/video-playlist/root/video-playlist-root.js +4 -1
- package/dist/virtual-list/root/virtual-list-root.d.ts +23 -1
- package/dist/virtual-list/root/virtual-list-root.js +21 -2
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +808 -156
- package/types/vue.d.ts +223 -59
- package/types/words.d.ts +4 -2
|
@@ -52,6 +52,9 @@ declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args:
|
|
|
52
52
|
* compare the parts with each other; the scale then fits the largest part
|
|
53
53
|
* rather than the total.
|
|
54
54
|
*
|
|
55
|
+
* `value-axis` draws the scale's numbers beside the plot, at the levels
|
|
56
|
+
* `gridlines` rules: amounts in `locale`, or percentages under `share`.
|
|
57
|
+
*
|
|
55
58
|
* The drawing is hidden from screen readers. The text summary gives the latest
|
|
56
59
|
* reading's total and each part's share of it, and the table beside the chart
|
|
57
60
|
* has every number.
|
|
@@ -65,13 +68,22 @@ declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args:
|
|
|
65
68
|
* Every numeric column is a part, so leave a total column out of the table the
|
|
66
69
|
* chart reads, or it is counted twice. A negative reading is drawn as zero.
|
|
67
70
|
*
|
|
71
|
+
* **A tap shows the reading under it**, and keeps it until a tap lands
|
|
72
|
+
* elsewhere. `helix-reading-change` says each move of the reading, by pointer,
|
|
73
|
+
* tap or key, and `helix-reading-press` says a reading was clicked, tapped, or
|
|
74
|
+
* pressed with Enter or Space, for a page that opens what a reading stands for.
|
|
75
|
+
*
|
|
68
76
|
* @since 0.1.0
|
|
69
77
|
* @status stable
|
|
70
78
|
* @category charts
|
|
71
79
|
* @aliases Stacked Area Chart, Composition Chart, Banded Chart
|
|
72
80
|
* @documentation https://fusion.dev/helix/components/area-chart
|
|
73
81
|
*
|
|
82
|
+
* @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.
|
|
83
|
+
* @event {HelixReadingPressEvent} helix-reading-press - A reading was clicked, tapped, or pressed with Enter or Space, with the same detail as `helix-reading-change`.
|
|
84
|
+
*
|
|
74
85
|
* @csspart area - One part's band.
|
|
86
|
+
* @csspart axis - The numbers of the scale beside the plot, under `value-axis`.
|
|
75
87
|
* @csspart baseline - The rule at zero, which is the floor of the drawing.
|
|
76
88
|
* @csspart gridline - One rule across the plot, under `gridlines`.
|
|
77
89
|
* @csspart guide - A rule down the reading a pointer is resting on.
|
|
@@ -83,6 +95,7 @@ declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args:
|
|
|
83
95
|
* @csspart plot - The drawing, which takes focus to be read by key.
|
|
84
96
|
* @csspart summary - The total and each part's share at the latest reading, written as a sentence for screen readers.
|
|
85
97
|
* @csspart svg - The drawing surface the bands sit on.
|
|
98
|
+
* @csspart tick - One number on the axis, placed with `inset-block-start` at its level.
|
|
86
99
|
* @csspart tooltip - The bubble, forwarded from `Tooltip`.
|
|
87
100
|
* @csspart tooltip-anchor - The `Tooltip` element itself.
|
|
88
101
|
* @csspart tooltip-arrow - The bubble's point, forwarded from `Tooltip`.
|
|
@@ -99,6 +112,8 @@ declare const HelixHeadlessAreaChart_base: typeof HelixElement & (new (...args:
|
|
|
99
112
|
* @csspart tooltip-right - The bubble while it is right of the reading, beside `tooltip`.
|
|
100
113
|
* @csspart tooltip-top - The bubble while it is above the reading, beside `tooltip`.
|
|
101
114
|
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
115
|
+
*
|
|
116
|
+
* @cssproperty --area-chart-axis - The width of the axis, in `ch`, set from the widest number on it. Written by the component on the axis.
|
|
102
117
|
*/
|
|
103
118
|
export declare class HelixHeadlessAreaChart extends HelixHeadlessAreaChart_base {
|
|
104
119
|
/**
|
|
@@ -106,6 +121,13 @@ export declare class HelixHeadlessAreaChart extends HelixHeadlessAreaChart_base
|
|
|
106
121
|
* `registerWords('de', { 'helix-area-chart': { totalLabel: 'Summe' } })`.
|
|
107
122
|
*/
|
|
108
123
|
static words: string;
|
|
124
|
+
/**
|
|
125
|
+
* Sends the reading's moves and presses as `helix-reading-change` and
|
|
126
|
+
* `helix-reading-press`, which the pointer hears. Here and not in a
|
|
127
|
+
* constructor, where the manifest's analyzer reads the assignment as a
|
|
128
|
+
* member of this class.
|
|
129
|
+
*/
|
|
130
|
+
connectedCallback(): void;
|
|
109
131
|
/**
|
|
110
132
|
* How a band's edge gets from one reading to the next.
|
|
111
133
|
*
|
|
@@ -161,6 +183,14 @@ export declare class HelixHeadlessAreaChart extends HelixHeadlessAreaChart_base
|
|
|
161
183
|
* The name for the sum of the parts, shown in the tooltip and the summary.
|
|
162
184
|
*/
|
|
163
185
|
totalLabel: string;
|
|
186
|
+
/**
|
|
187
|
+
* Draws the scale's numbers beside the plot, the `axis` part, at the levels
|
|
188
|
+
* `gridlines` rules: amounts, or percentages under `share`.
|
|
189
|
+
*
|
|
190
|
+
* Absent draws none: bands read as a composition need no numbers beside
|
|
191
|
+
* them, and the tooltip and the table hold every reading.
|
|
192
|
+
*/
|
|
193
|
+
valueAxis: boolean;
|
|
164
194
|
private warnedAboutNegatives;
|
|
165
195
|
/** Whether the levels are ruled, which is every value but `category`. */
|
|
166
196
|
protected get rulesValue(): boolean;
|
|
@@ -184,6 +214,12 @@ export declare class HelixHeadlessAreaChart extends HelixHeadlessAreaChart_base
|
|
|
184
214
|
*/
|
|
185
215
|
private warnNegative;
|
|
186
216
|
protected render(): TemplateResult;
|
|
217
|
+
/**
|
|
218
|
+
* The scale's numbers beside the plot, under `value-axis`: amounts written
|
|
219
|
+
* in the chart's locale, or percentages under `share`. A seam, so a
|
|
220
|
+
* subclass can write the numbers its own way, such as a currency.
|
|
221
|
+
*/
|
|
222
|
+
protected renderAxis(y: (value: number) => number, domain: [number, number]): TemplateResult;
|
|
187
223
|
/**
|
|
188
224
|
* The bands, behind a seam the styled tier can move.
|
|
189
225
|
*
|
|
@@ -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, formatNumbers, formatWords, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, reportRuntime, seriesIndex, ticks, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { CHART_PLOT, customElement, drawTooltip, drawValueAxis, formatNumbers, formatWords, HelixElement, HelixReadingChangeEvent, HelixReadingPressEvent, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, reportRuntime, 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';
|
|
@@ -27,9 +27,16 @@ let HelixHeadlessAreaChart = class HelixHeadlessAreaChart extends MixinChartSour
|
|
|
27
27
|
this.share = false;
|
|
28
28
|
this.summaryLabel = '{reading}: {totalLabel} {total}; {shares}.';
|
|
29
29
|
this.totalLabel = 'Total';
|
|
30
|
+
this.valueAxis = false;
|
|
30
31
|
this.warnedAboutNegatives = false;
|
|
31
32
|
}
|
|
32
33
|
static { this.words = 'helix-area-chart'; }
|
|
34
|
+
connectedCallback() {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.pointer.onReading = (heard, detail) => this.dispatchEvent(heard === 'press'
|
|
37
|
+
? new HelixReadingPressEvent(detail)
|
|
38
|
+
: new HelixReadingChangeEvent(detail));
|
|
39
|
+
}
|
|
33
40
|
get rulesValue() {
|
|
34
41
|
return this.gridlines !== undefined && this.gridlines !== 'category';
|
|
35
42
|
}
|
|
@@ -100,9 +107,14 @@ let HelixHeadlessAreaChart = class HelixHeadlessAreaChart extends MixinChartSour
|
|
|
100
107
|
const y = linear(domain, [PLOT_HEIGHT, 0]);
|
|
101
108
|
const slot = PLOT_WIDTH / rows.length;
|
|
102
109
|
const x = linear([0, Math.max(rows.length - 1, 1)], [slot / 2, PLOT_WIDTH - slot / 2]);
|
|
103
|
-
return html `${this.renderPlot(stack, rows.length, x, y, domain)}
|
|
110
|
+
return html `${this.valueAxis ? this.renderAxis(y, domain) : nothing}${this.renderPlot(stack, rows.length, x, y, domain)}
|
|
104
111
|
${this.renderLabels(rows.map((row) => row.label))} ${this.renderSummary(stack, rows)}`;
|
|
105
112
|
}
|
|
113
|
+
renderAxis(y, domain) {
|
|
114
|
+
const locale = wordsLocale(this);
|
|
115
|
+
const percent = percentIn(locale);
|
|
116
|
+
return drawValueAxis(domain, (value) => (y(value) / PLOT_HEIGHT) * 100, this.share ? (value) => percent.format(value) : formatNumbers(locale), (widest) => `--area-chart-axis: ${widest}ch`);
|
|
117
|
+
}
|
|
106
118
|
renderPlot(stack, count, x, y, domain) {
|
|
107
119
|
const order = stack.layers.map((_, depth) => depth).reverse();
|
|
108
120
|
return html `<div
|
|
@@ -249,6 +261,9 @@ __decorate([
|
|
|
249
261
|
words,
|
|
250
262
|
property({ attribute: 'total-label' })
|
|
251
263
|
], HelixHeadlessAreaChart.prototype, "totalLabel", void 0);
|
|
264
|
+
__decorate([
|
|
265
|
+
property({ attribute: 'value-axis', reflect: true, type: Boolean })
|
|
266
|
+
], HelixHeadlessAreaChart.prototype, "valueAxis", void 0);
|
|
252
267
|
HelixHeadlessAreaChart = __decorate([
|
|
253
268
|
customElement('helix-headless-area-chart')
|
|
254
269
|
], HelixHeadlessAreaChart);
|
|
@@ -30,13 +30,21 @@ declare const HelixHeadlessBarChart_base: typeof HelixElement & (new (...args: a
|
|
|
30
30
|
* The component writes the custom properties below with numbers it computes,
|
|
31
31
|
* and the stylesheet that draws the chart reads them. Do not set them yourself.
|
|
32
32
|
*
|
|
33
|
+
* **A tap shows the reading under it**, and keeps it until a tap lands
|
|
34
|
+
* elsewhere. `helix-reading-change` says each move of the reading, by pointer,
|
|
35
|
+
* tap or key, and `helix-reading-press` says a reading was clicked, tapped, or
|
|
36
|
+
* pressed with Enter or Space, for a page that opens what a reading stands for.
|
|
37
|
+
*
|
|
33
38
|
* @since 0.1.0
|
|
34
39
|
* @status stable
|
|
35
40
|
* @category charts
|
|
36
41
|
* @aliases Column Chart, Categorical Chart
|
|
37
42
|
* @documentation https://fusion.dev/helix/components/bar-chart
|
|
38
43
|
*
|
|
39
|
-
* @
|
|
44
|
+
* @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.
|
|
45
|
+
* @event {HelixReadingPressEvent} helix-reading-press - A reading was clicked, tapped, or pressed with Enter or Space, with the same detail as `helix-reading-change`.
|
|
46
|
+
*
|
|
47
|
+
* @csspart axis - The numbers of one scale: the primary under `value-axis`, and both when `secondary` splits the chart into two scales.
|
|
40
48
|
* @csspart band - The category band under the pointer.
|
|
41
49
|
* @csspart bar - One column.
|
|
42
50
|
* @csspart bar-wash-end - The far stop of a bar's gradient, where one is used.
|
|
@@ -83,6 +91,13 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
|
|
|
83
91
|
* `registerWords('de', { 'helix-bar-chart': { highestLabel: 'Höchster Wert' } })`.
|
|
84
92
|
*/
|
|
85
93
|
static words: string;
|
|
94
|
+
/**
|
|
95
|
+
* Sends the reading's moves and presses as `helix-reading-change` and
|
|
96
|
+
* `helix-reading-press`, which the pointer hears. Here and not in a
|
|
97
|
+
* constructor, where the manifest's analyzer reads the assignment as a
|
|
98
|
+
* member of this class.
|
|
99
|
+
*/
|
|
100
|
+
connectedCallback(): void;
|
|
86
101
|
/**
|
|
87
102
|
* Which gridlines are drawn across the plot, if any.
|
|
88
103
|
*
|
|
@@ -199,6 +214,15 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
|
|
|
199
214
|
* the reading as the table writes it.
|
|
200
215
|
*/
|
|
201
216
|
summaryLabel: string;
|
|
217
|
+
/**
|
|
218
|
+
* Draws the numbers of the scale the bars are measured on, the `axis` part,
|
|
219
|
+
* at the levels `gridlines` rules: down the side of columns, and along the
|
|
220
|
+
* bottom of bars under `orientation="horizontal"`.
|
|
221
|
+
*
|
|
222
|
+
* Absent draws none with one scale, since bars compared with each other need
|
|
223
|
+
* no numbers. With `secondary` both scales are drawn whatever this says.
|
|
224
|
+
*/
|
|
225
|
+
valueAxis: boolean;
|
|
202
226
|
/** The series names on the second scale, lowercased and trimmed. */
|
|
203
227
|
private get scaled();
|
|
204
228
|
/** The series names drawn as a line, lowercased and trimmed for matching. */
|
|
@@ -251,8 +275,8 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
|
|
|
251
275
|
* a small chart is furniture that makes the drawing smaller for no reading a
|
|
252
276
|
* reader was going to do. With two scales that argument inverts: a reader
|
|
253
277
|
* cannot tell there are two, cannot tell which series is on which, and cannot
|
|
254
|
-
* recover either from the picture. So this appears with `secondary
|
|
255
|
-
*
|
|
278
|
+
* recover either from the picture. So this appears with `secondary`, and
|
|
279
|
+
* with one scale only where `value-axis` asks for its numbers.
|
|
256
280
|
*
|
|
257
281
|
* **Beside the plot and not inside it.** Inside, the numbers are drawn over
|
|
258
282
|
* the drawing, and a horizontal chart shows it immediately: its value axis
|
|
@@ -263,7 +287,7 @@ export declare class HelixHeadlessBarChart extends HelixHeadlessBarChart_base {
|
|
|
263
287
|
* to the right.
|
|
264
288
|
*
|
|
265
289
|
* A column of the host grid instead, which the stylesheet grows only when
|
|
266
|
-
* `secondary` is set. That is what the
|
|
290
|
+
* `secondary` or `value-axis` is set. That is what the two reflect for.
|
|
267
291
|
*
|
|
268
292
|
* The primary hugs the edge the drawing starts at and the secondary the edge
|
|
269
293
|
* it ends at: down the two sides for columns, along the bottom and top for
|
|
@@ -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 { byRow, CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, formatWords, HelixElement, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesKey, seriesNames, ticks, unbroken, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { byRow, CHART_PLOT, customElement, drawTooltip, extent, formatNumbers, formatWords, HelixElement, HelixReadingChangeEvent, HelixReadingPressEvent, linear, linePath, MixinChartSource, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesKey, seriesNames, ticks, unbroken, 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 { stackEnds, stackedReadings, stackSpans } from '../stack.js';
|
|
@@ -15,8 +15,15 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
15
15
|
this.highestLabel = 'Highest';
|
|
16
16
|
this.stacked = false;
|
|
17
17
|
this.summaryLabel = '{highestLabel}: {readings}.';
|
|
18
|
+
this.valueAxis = false;
|
|
18
19
|
}
|
|
19
20
|
static { this.words = 'helix-bar-chart'; }
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
super.connectedCallback();
|
|
23
|
+
this.pointer.onReading = (heard, detail) => this.dispatchEvent(heard === 'press'
|
|
24
|
+
? new HelixReadingPressEvent(detail)
|
|
25
|
+
: new HelixReadingChangeEvent(detail));
|
|
26
|
+
}
|
|
20
27
|
get scaled() {
|
|
21
28
|
return new Set(seriesNames(this.secondary));
|
|
22
29
|
}
|
|
@@ -61,14 +68,17 @@ let HelixHeadlessBarChart = class HelixHeadlessBarChart extends MixinChartSource
|
|
|
61
68
|
const other = [Math.min(0, second), Math.max(0, top)];
|
|
62
69
|
const z = scaled.size > 0 ? linear(other, range) : undefined;
|
|
63
70
|
const format = formatNumbers(wordsLocale(this));
|
|
64
|
-
const
|
|
71
|
+
const levels = [...ticks(domain), ...(z === undefined ? [] : ticks(other))];
|
|
72
|
+
const widest = z === undefined && !this.valueAxis
|
|
65
73
|
? 0
|
|
66
|
-
: Math.max(
|
|
74
|
+
: Math.max(1, ...levels.map((level) => format(level).length));
|
|
67
75
|
const lone = series.filter(own);
|
|
68
76
|
const tint = lone.length === 1 && lone[0] !== undefined
|
|
69
77
|
? `--bar-chart-secondary: var(--chart-series-${seriesIndex(series.indexOf(lone[0]))})`
|
|
70
78
|
: undefined;
|
|
71
|
-
return html `${z === undefined
|
|
79
|
+
return html `${z === undefined && !this.valueAxis
|
|
80
|
+
? nothing
|
|
81
|
+
: this.renderAxis(y, domain, 'primary', sideways, widest)}${this.renderPlot(series, categories, y, domain, floor, z)}${z === undefined ? nothing : this.renderAxis(z, other, 'secondary', sideways, widest, tint)}${this.renderLabels(categories)}${this.renderSummary(series)}`;
|
|
72
82
|
}
|
|
73
83
|
renderSummary(series) {
|
|
74
84
|
const rows = this.sourceRows;
|
|
@@ -309,6 +319,9 @@ __decorate([
|
|
|
309
319
|
words,
|
|
310
320
|
property({ attribute: 'summary-label' })
|
|
311
321
|
], HelixHeadlessBarChart.prototype, "summaryLabel", void 0);
|
|
322
|
+
__decorate([
|
|
323
|
+
property({ attribute: 'value-axis', reflect: true, type: Boolean })
|
|
324
|
+
], HelixHeadlessBarChart.prototype, "valueAxis", void 0);
|
|
312
325
|
HelixHeadlessBarChart = __decorate([
|
|
313
326
|
customElement('helix-headless-bar-chart')
|
|
314
327
|
], HelixHeadlessBarChart);
|
|
@@ -222,6 +222,11 @@ export declare class HelixHeadlessButton extends HelixFormElement {
|
|
|
222
222
|
* inconsistently.
|
|
223
223
|
*/
|
|
224
224
|
private sayPending;
|
|
225
|
+
/**
|
|
226
|
+
* @internal Says `words` in the button's live region, for a subclass with
|
|
227
|
+
* news of its own, as `CopyButton` says the result of a copy.
|
|
228
|
+
*/
|
|
229
|
+
protected sayStatus(words: string): void;
|
|
225
230
|
/**
|
|
226
231
|
* @internal The live region a pending button speaks in, for a subclass that
|
|
227
232
|
* replaces the template, as `CopyButton` does.
|
|
@@ -74,6 +74,9 @@ let HelixHeadlessButton = class HelixHeadlessButton extends HelixFormElement {
|
|
|
74
74
|
}
|
|
75
75
|
this.status.say(this.pending && focused ? this.pendingLabel : '', { clear: false });
|
|
76
76
|
}
|
|
77
|
+
sayStatus(words) {
|
|
78
|
+
this.status.say(words);
|
|
79
|
+
}
|
|
77
80
|
renderLive() {
|
|
78
81
|
return drawStatus(this.status);
|
|
79
82
|
}
|
|
@@ -48,6 +48,16 @@ export declare class HelixHeadlessCallout extends HelixHeadlessCallout_base {
|
|
|
48
48
|
*/
|
|
49
49
|
static words: string;
|
|
50
50
|
protected willUpdate(changed: PropertyValues): void;
|
|
51
|
+
/**
|
|
52
|
+
* The dismiss button's name, read by screen readers, with `{label}` for
|
|
53
|
+
* what the callout is called: its heading, or the tone's name where it has
|
|
54
|
+
* none.
|
|
55
|
+
*
|
|
56
|
+
* "Dismiss Scheduled maintenance" says which of several callouts the button
|
|
57
|
+
* takes away, where every button was "Dismiss". A label without `{label}` is
|
|
58
|
+
* read as written.
|
|
59
|
+
*/
|
|
60
|
+
dismissLabel: string;
|
|
51
61
|
/**
|
|
52
62
|
* What kind of attention the passage needs.
|
|
53
63
|
*
|
|
@@ -96,6 +106,16 @@ export declare class HelixHeadlessCallout extends HelixHeadlessCallout_base {
|
|
|
96
106
|
* above.
|
|
97
107
|
*/
|
|
98
108
|
protected renderDismissIcon(): TemplateResult;
|
|
109
|
+
/**
|
|
110
|
+
* The dismiss button's name: `dismissLabel` with the heading's words, or the
|
|
111
|
+
* tone's name.
|
|
112
|
+
*
|
|
113
|
+
* The heading is read from the children, so a server and a hydrating render
|
|
114
|
+
* name the button for the tone, and the update after names it for the
|
|
115
|
+
* heading.
|
|
116
|
+
*/
|
|
117
|
+
private dismissName;
|
|
118
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
99
119
|
protected render(): TemplateResult;
|
|
100
120
|
}
|
|
101
121
|
declare global {
|
|
@@ -4,13 +4,14 @@ 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, drawDismiss, drawDismissGlyph, HelixElement, hostAria, MixinDismissible, TONE_MARKS, toneMark, words, wordsConverter, } from '@fusion.dev/helix-core';
|
|
7
|
+
import { customElement, drawDismiss, drawDismissGlyph, formatWords, HelixElement, hostAria, MixinDismissible, slottedWords, TONE_MARKS, toneMark, words, wordsConverter, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { html, nothing } from 'lit';
|
|
9
9
|
import { property } from 'lit/decorators.js';
|
|
10
10
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
11
11
|
let HelixHeadlessCallout = class HelixHeadlessCallout extends MixinDismissible(HelixElement) {
|
|
12
12
|
constructor() {
|
|
13
13
|
super(...arguments);
|
|
14
|
+
this.dismissLabel = 'Dismiss {label}';
|
|
14
15
|
this.toneLabel = '';
|
|
15
16
|
this.toneLabels = {
|
|
16
17
|
danger: 'Error',
|
|
@@ -26,7 +27,7 @@ let HelixHeadlessCallout = class HelixHeadlessCallout extends MixinDismissible(H
|
|
|
26
27
|
hostAria(this.internals, { role: 'note' });
|
|
27
28
|
}
|
|
28
29
|
renderIcon(icon, _label) {
|
|
29
|
-
return html `<slot name="icon">
|
|
30
|
+
return html `<slot name="icon" aria-hidden="true">
|
|
30
31
|
<svg part="icon-mark" fill="currentColor" viewBox=${icon.viewBox} aria-hidden="true">
|
|
31
32
|
${unsafeSVG(icon.content)}
|
|
32
33
|
</svg>
|
|
@@ -37,23 +38,37 @@ let HelixHeadlessCallout = class HelixHeadlessCallout extends MixinDismissible(H
|
|
|
37
38
|
${drawDismissGlyph()}
|
|
38
39
|
</slot>`;
|
|
39
40
|
}
|
|
41
|
+
dismissName(tone) {
|
|
42
|
+
const heading = this.childrenKnown ? slottedWords(this, ['heading']) : '';
|
|
43
|
+
return this.dismissLabel.includes('{label}')
|
|
44
|
+
? formatWords(this, 'dismissLabel', { label: heading || tone }).trim()
|
|
45
|
+
: this.dismissLabel;
|
|
46
|
+
}
|
|
47
|
+
firstUpdated(changed) {
|
|
48
|
+
super.firstUpdated(changed);
|
|
49
|
+
this.finishHydration();
|
|
50
|
+
}
|
|
40
51
|
render() {
|
|
41
52
|
const tone = this.tone === 'neutral' ? 'neutral' : toneMark(this.tone) ? (this.tone ?? 'info') : 'info';
|
|
42
53
|
const { icon } = toneMark(tone) ?? TONE_MARKS.info;
|
|
43
54
|
const named = this.toneLabel || (this.toneLabels[tone] ?? '');
|
|
44
55
|
return html `<span part="icon" role="img" aria-label=${named}>${this.renderIcon(icon, named)}</span>
|
|
45
56
|
<div part="content">
|
|
46
|
-
<slot name="heading"></slot>
|
|
57
|
+
<slot name="heading" @slotchange=${() => this.requestUpdate()}></slot>
|
|
47
58
|
<slot></slot>
|
|
48
59
|
</div>${this.dismissible
|
|
49
60
|
? drawDismiss({
|
|
50
|
-
label: this.
|
|
61
|
+
label: this.dismissName(named),
|
|
51
62
|
mark: this.renderDismissIcon(),
|
|
52
63
|
onDismiss: () => this.dismiss(),
|
|
53
64
|
})
|
|
54
65
|
: nothing}`;
|
|
55
66
|
}
|
|
56
67
|
};
|
|
68
|
+
__decorate([
|
|
69
|
+
words,
|
|
70
|
+
property({ attribute: 'dismiss-label' })
|
|
71
|
+
], HelixHeadlessCallout.prototype, "dismissLabel", void 0);
|
|
57
72
|
__decorate([
|
|
58
73
|
property({ reflect: true })
|
|
59
74
|
], HelixHeadlessCallout.prototype, "tone", void 0);
|
|
@@ -20,6 +20,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
20
20
|
* disabled>` turns the composer off. Sending is still `helix-send`, and it
|
|
21
21
|
* does not submit the form.
|
|
22
22
|
*
|
|
23
|
+
* **`required`, `minlength` and `maxlength` are checked by the browser**, as
|
|
24
|
+
* on a `<textarea>`, and the message is the browser's. `maxlength` stops the
|
|
25
|
+
* field taking more. A draft that fails them does not send, and the composer
|
|
26
|
+
* takes `:state(invalid)` and `aria-invalid` once the reader has tried to send
|
|
27
|
+
* it, the form was submitted, or the reader edited the field and left it.
|
|
28
|
+
* Tabbing past an empty composer marks nothing.
|
|
29
|
+
*
|
|
23
30
|
* **`typing` says whether the user is writing**, and `helix-typing` is sent
|
|
24
31
|
* each time it changes: when they start, and when they send or stop for
|
|
25
32
|
* `typing-timeout` milliseconds. Pass it on to show "is typing" to the other
|
|
@@ -45,6 +52,8 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
45
52
|
* @csspart send - The send button.
|
|
46
53
|
* @csspart start - The box around the `start` slot.
|
|
47
54
|
* @csspart tools - The row under the field.
|
|
55
|
+
*
|
|
56
|
+
* @cssstate invalid - The draft fails `required`, `minlength`, `maxlength`, or a custom error, and the reader has tried to send or submit it, or edited the field and left it.
|
|
48
57
|
*/
|
|
49
58
|
export declare class HelixHeadlessChatComposer extends HelixFormElement {
|
|
50
59
|
/**
|
|
@@ -56,10 +65,24 @@ export declare class HelixHeadlessChatComposer extends HelixFormElement {
|
|
|
56
65
|
* The field's name, read by screen readers.
|
|
57
66
|
*/
|
|
58
67
|
label: string;
|
|
68
|
+
/**
|
|
69
|
+
* The most characters a draft can have. The field stops taking more.
|
|
70
|
+
*/
|
|
71
|
+
maxLength?: number;
|
|
72
|
+
/**
|
|
73
|
+
* The fewest characters a draft can have, once the reader has written in
|
|
74
|
+
* the field, as on a `<textarea>`.
|
|
75
|
+
*/
|
|
76
|
+
minLength?: number;
|
|
59
77
|
/**
|
|
60
78
|
* Placeholder text shown in an empty field.
|
|
61
79
|
*/
|
|
62
80
|
placeholder: string;
|
|
81
|
+
/**
|
|
82
|
+
* Whether the form needs a draft to submit. An empty draft never sends,
|
|
83
|
+
* required or not.
|
|
84
|
+
*/
|
|
85
|
+
required: boolean;
|
|
63
86
|
/**
|
|
64
87
|
* How many rows the field opens at.
|
|
65
88
|
*
|
|
@@ -97,6 +120,10 @@ export declare class HelixHeadlessChatComposer extends HelixFormElement {
|
|
|
97
120
|
readonly isChatComposer = true;
|
|
98
121
|
/** Whether the user is writing, which `helix-typing` announces. */
|
|
99
122
|
private writing;
|
|
123
|
+
/** Whether the reader has tried to send or submit the draft, or edited it and left. */
|
|
124
|
+
private touched;
|
|
125
|
+
/** Whether the composer shows that its draft is wrong. */
|
|
126
|
+
private shownInvalid;
|
|
100
127
|
/** The pause after which the user has stopped writing. */
|
|
101
128
|
private readonly pause;
|
|
102
129
|
/**
|
|
@@ -121,6 +148,8 @@ export declare class HelixHeadlessChatComposer extends HelixFormElement {
|
|
|
121
148
|
private get declared();
|
|
122
149
|
/** Puts back the draft the markup declared when the form is reset. */
|
|
123
150
|
formResetCallback(): void;
|
|
151
|
+
/** The reader has had a go at the draft, so whether it is wrong can be shown. */
|
|
152
|
+
private readonly touch;
|
|
124
153
|
/** Brings back the draft when the browser restores the form. */
|
|
125
154
|
formStateRestoreCallback(state: string | File | FormData | null): void;
|
|
126
155
|
/**
|
|
@@ -133,6 +162,7 @@ export declare class HelixHeadlessChatComposer extends HelixFormElement {
|
|
|
133
162
|
*/
|
|
134
163
|
private markEmpty;
|
|
135
164
|
protected updated(changed: PropertyValues): void;
|
|
165
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
136
166
|
protected willUpdate(changed: PropertyValues): void;
|
|
137
167
|
/**
|
|
138
168
|
* The control that offers the turn, behind a seam so a tier can draw its own.
|
|
@@ -6,8 +6,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { customElement, DelayController, HelixFormElement, HelixSendEvent, HelixTypingEvent, hostAria, markRegion, words, } from '@fusion.dev/helix-core';
|
|
8
8
|
import { arrowElbowDownLeft } from '@fusion.dev/helix-icons';
|
|
9
|
-
import { html } from 'lit';
|
|
10
|
-
import { property } from 'lit/decorators.js';
|
|
9
|
+
import { html, nothing } from 'lit';
|
|
10
|
+
import { property, state } from 'lit/decorators.js';
|
|
11
11
|
import { live } from 'lit/directives/live.js';
|
|
12
12
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
13
13
|
let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFormElement {
|
|
@@ -15,6 +15,7 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
15
15
|
super(...arguments);
|
|
16
16
|
this.label = 'Message';
|
|
17
17
|
this.placeholder = '';
|
|
18
|
+
this.required = false;
|
|
18
19
|
this.rows = 1;
|
|
19
20
|
this.sendLabel = 'Send';
|
|
20
21
|
this.submitOn = 'enter';
|
|
@@ -22,7 +23,13 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
22
23
|
this.value = '';
|
|
23
24
|
this.isChatComposer = true;
|
|
24
25
|
this.writing = false;
|
|
26
|
+
this.touched = false;
|
|
27
|
+
this.shownInvalid = false;
|
|
25
28
|
this.pause = new DelayController(this, { renders: false });
|
|
29
|
+
this.touch = () => {
|
|
30
|
+
this.touched = true;
|
|
31
|
+
this.requestUpdate();
|
|
32
|
+
};
|
|
26
33
|
this.handleInput = (event) => {
|
|
27
34
|
event.stopPropagation();
|
|
28
35
|
this.value = event.target.value;
|
|
@@ -65,10 +72,15 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
65
72
|
if (value === '' || this.isDisabled) {
|
|
66
73
|
return false;
|
|
67
74
|
}
|
|
75
|
+
if (!this.internals.validity.valid) {
|
|
76
|
+
this.touch();
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
68
79
|
if (!this.dispatchEvent(new HelixSendEvent({ value }))) {
|
|
69
80
|
return false;
|
|
70
81
|
}
|
|
71
82
|
this.value = '';
|
|
83
|
+
this.touched = false;
|
|
72
84
|
this.markTyping(false);
|
|
73
85
|
return true;
|
|
74
86
|
}
|
|
@@ -78,6 +90,8 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
78
90
|
formResetCallback() {
|
|
79
91
|
super.formResetCallback();
|
|
80
92
|
this.value = this.declared;
|
|
93
|
+
this.touched = false;
|
|
94
|
+
this.requestUpdate();
|
|
81
95
|
}
|
|
82
96
|
formStateRestoreCallback(state) {
|
|
83
97
|
this.value = typeof state === 'string' ? state : this.declared;
|
|
@@ -93,6 +107,20 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
93
107
|
if (changed.has('value')) {
|
|
94
108
|
this.internals.setFormValue(this.value === '' ? null : this.value);
|
|
95
109
|
}
|
|
110
|
+
const field = this.partNamed('field');
|
|
111
|
+
if (field?.validity) {
|
|
112
|
+
this.internals.setValidity(field.validity, field.validationMessage, field);
|
|
113
|
+
}
|
|
114
|
+
const invalid = this.touched && !this.internals.validity.valid;
|
|
115
|
+
this.toggleState('invalid', invalid);
|
|
116
|
+
this.internals.ariaInvalid = invalid ? 'true' : null;
|
|
117
|
+
if (invalid !== this.shownInvalid) {
|
|
118
|
+
this.shownInvalid = invalid;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
firstUpdated(changed) {
|
|
122
|
+
super.firstUpdated(changed);
|
|
123
|
+
this.addEventListener('invalid', this.touch);
|
|
96
124
|
}
|
|
97
125
|
willUpdate(changed) {
|
|
98
126
|
super.willUpdate(changed);
|
|
@@ -124,7 +152,12 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixFor
|
|
|
124
152
|
aria-label=${this.label}
|
|
125
153
|
placeholder=${this.placeholder}
|
|
126
154
|
rows=${this.rows}
|
|
155
|
+
?required=${this.required}
|
|
156
|
+
minlength=${this.minLength ?? nothing}
|
|
157
|
+
maxlength=${this.maxLength ?? nothing}
|
|
158
|
+
aria-invalid=${this.shownInvalid ? 'true' : nothing}
|
|
127
159
|
?disabled=${this.isDisabled}
|
|
160
|
+
@change=${this.touch}
|
|
128
161
|
@input=${this.handleInput}
|
|
129
162
|
@keydown=${this.handleKey}
|
|
130
163
|
></textarea>
|
|
@@ -140,9 +173,18 @@ __decorate([
|
|
|
140
173
|
words,
|
|
141
174
|
property()
|
|
142
175
|
], HelixHeadlessChatComposer.prototype, "label", void 0);
|
|
176
|
+
__decorate([
|
|
177
|
+
property({ attribute: 'maxlength', type: Number })
|
|
178
|
+
], HelixHeadlessChatComposer.prototype, "maxLength", void 0);
|
|
179
|
+
__decorate([
|
|
180
|
+
property({ attribute: 'minlength', type: Number })
|
|
181
|
+
], HelixHeadlessChatComposer.prototype, "minLength", void 0);
|
|
143
182
|
__decorate([
|
|
144
183
|
property()
|
|
145
184
|
], HelixHeadlessChatComposer.prototype, "placeholder", void 0);
|
|
185
|
+
__decorate([
|
|
186
|
+
property({ type: Boolean })
|
|
187
|
+
], HelixHeadlessChatComposer.prototype, "required", void 0);
|
|
146
188
|
__decorate([
|
|
147
189
|
property({ type: Number })
|
|
148
190
|
], HelixHeadlessChatComposer.prototype, "rows", void 0);
|
|
@@ -159,6 +201,9 @@ __decorate([
|
|
|
159
201
|
__decorate([
|
|
160
202
|
property()
|
|
161
203
|
], HelixHeadlessChatComposer.prototype, "value", void 0);
|
|
204
|
+
__decorate([
|
|
205
|
+
state()
|
|
206
|
+
], HelixHeadlessChatComposer.prototype, "shownInvalid", void 0);
|
|
162
207
|
HelixHeadlessChatComposer = __decorate([
|
|
163
208
|
customElement('helix-headless-chat-composer')
|
|
164
209
|
], HelixHeadlessChatComposer);
|
|
@@ -331,6 +331,16 @@ export declare class HelixHeadlessChat extends HelixHeadlessChat_base {
|
|
|
331
331
|
get messages(): HelixHeadlessChatMessage[];
|
|
332
332
|
/** The element that scrolls, once there is one. */
|
|
333
333
|
private get log();
|
|
334
|
+
/**
|
|
335
|
+
* Makes the log a tab stop while it scrolls, and takes the stop away when it
|
|
336
|
+
* does not.
|
|
337
|
+
*
|
|
338
|
+
* **A reader on a keyboard scrolls the history from the log itself.**
|
|
339
|
+
* Chromium and Firefox make a box that scrolls focusable on their own, and
|
|
340
|
+
* Safari does not, so there the arrow keys could not reach a long history.
|
|
341
|
+
* A log that fits is no stop at all, so Tab goes straight to the composer.
|
|
342
|
+
*/
|
|
343
|
+
private markScroller;
|
|
334
344
|
/** Whether the reader is within `threshold` of the bottom right now. */
|
|
335
345
|
private get atBottom();
|
|
336
346
|
/** What identifies a turn fed as data: its key, or the object it is. */
|
|
@@ -78,6 +78,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
78
78
|
});
|
|
79
79
|
this.filled = undefined;
|
|
80
80
|
this.handleResize = () => {
|
|
81
|
+
this.markScroller();
|
|
81
82
|
if (this.pinned) {
|
|
82
83
|
this.stick();
|
|
83
84
|
}
|
|
@@ -141,6 +142,18 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
141
142
|
get log() {
|
|
142
143
|
return this.partNamed('log');
|
|
143
144
|
}
|
|
145
|
+
markScroller() {
|
|
146
|
+
const log = this.log;
|
|
147
|
+
if (!log) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (log.scrollHeight > log.clientHeight) {
|
|
151
|
+
log.tabIndex = 0;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
log.removeAttribute('tabindex');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
144
157
|
get atBottom() {
|
|
145
158
|
const log = this.log;
|
|
146
159
|
if (!log) {
|
|
@@ -421,6 +434,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
421
434
|
this.virtualize.measure();
|
|
422
435
|
}
|
|
423
436
|
this.watchSizes();
|
|
437
|
+
this.markScroller();
|
|
424
438
|
this.remember();
|
|
425
439
|
this.reachHistory();
|
|
426
440
|
this.announce();
|
|
@@ -45,6 +45,7 @@ declare const HelixHeadlessColorInput_base: (new (...args: any[]) => import("@fu
|
|
|
45
45
|
* @slot end - Content at the trailing end, before the trigger.
|
|
46
46
|
* @slot feedback - The message that says what is wrong with the value.
|
|
47
47
|
* @slot hint - Help text under the field.
|
|
48
|
+
* @slot label - The label, for content richer than the `label` text.
|
|
48
49
|
* @slot panel-footer - Content in the panel under the picker, such as a note or an action.
|
|
49
50
|
* @slot panel-header - Content in the panel above the picker, such as a heading or a shortcut.
|
|
50
51
|
* @slot start - Content at the leading end of the field, inside its border.
|
|
@@ -503,6 +503,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinPicke
|
|
|
503
503
|
min="0"
|
|
504
504
|
max="100"
|
|
505
505
|
tabindex="-1"
|
|
506
|
+
style="writing-mode: vertical-lr; direction: rtl"
|
|
506
507
|
aria-label=${axisName(this.brightnessLabel)}
|
|
507
508
|
aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
|
|
508
509
|
aria-valuetext=${reversed}
|