@fusion.dev/helix-headless 0.215.3 → 0.216.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/api.json +1 -1
- package/custom-elements.json +1 -1
- package/dist/area-chart/root/area-chart-root.d.ts +1 -0
- package/dist/area-chart/root/area-chart-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +1 -0
- package/dist/bar-chart/root/bar-chart-root.js +1 -1
- package/dist/button/root/button-root.d.ts +3 -1
- package/dist/button/root/button-root.js +2 -1
- package/dist/chat/composer/chat-composer.d.ts +18 -1
- package/dist/chat/composer/chat-composer.js +8 -3
- package/dist/checkbox/root/checkbox-root.d.ts +3 -1
- package/dist/checkbox/root/checkbox-root.js +2 -1
- package/dist/code-block/highlight.d.ts +9 -0
- package/dist/code-block/highlight.js +39 -0
- package/dist/code-block/highlighter.d.ts +44 -0
- package/dist/code-block/highlighter.js +44 -0
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/keyed-lines.d.ts +23 -0
- package/dist/code-block/keyed-lines.js +75 -0
- package/dist/code-block/root/code-block-root.d.ts +6 -23
- package/dist/code-block/root/code-block-root.js +8 -25
- package/dist/code-editor/index.d.ts +1 -0
- package/dist/code-editor/index.js +1 -0
- package/dist/code-editor/root/code-editor-root.d.ts +367 -0
- package/dist/code-editor/root/code-editor-root.js +746 -0
- package/dist/code-input/index.d.ts +1 -0
- package/dist/code-input/index.js +1 -0
- package/dist/code-input/root/code-input-root.d.ts +119 -0
- package/dist/code-input/root/code-input-root.js +142 -0
- package/dist/combobox/root/combobox-root.d.ts +6 -1
- package/dist/combobox/root/combobox-root.js +4 -2
- package/dist/command/root/command-root.d.ts +61 -11
- package/dist/command/root/command-root.js +88 -3
- package/dist/donut-chart/root/donut-chart-root.d.ts +1 -0
- package/dist/donut-chart/root/donut-chart-root.js +1 -1
- package/dist/element-events.generated.js +36 -3
- package/dist/filter-input/root/filter-input-root.d.ts +9 -1
- package/dist/filter-input/root/filter-input-root.js +7 -3
- package/dist/heatmap/root/heatmap-root.d.ts +1 -0
- package/dist/heatmap/root/heatmap-root.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/input/root/input-root.d.ts +14 -2
- package/dist/input/root/input-root.js +11 -3
- package/dist/kbd/root/kbd-root.js +9 -2
- package/dist/line-chart/root/line-chart-root.d.ts +1 -0
- package/dist/line-chart/root/line-chart-root.js +1 -1
- package/dist/listbox/root/listbox-root.d.ts +8 -1
- package/dist/listbox/root/listbox-root.js +7 -4
- package/dist/markdown/blocks.d.ts +66 -0
- package/dist/markdown/blocks.js +326 -0
- package/dist/markdown/index.d.ts +6 -0
- package/dist/markdown/index.js +5 -0
- package/dist/markdown/inline.d.ts +57 -0
- package/dist/markdown/inline.js +483 -0
- package/dist/markdown/root/markdown-root.d.ts +99 -0
- package/dist/markdown/root/markdown-root.js +93 -0
- package/dist/markdown/stream.d.ts +47 -0
- package/dist/markdown/stream.js +62 -0
- package/dist/markdown/tree.d.ts +57 -0
- package/dist/markdown/tree.js +144 -0
- package/dist/markdown/writer.d.ts +33 -0
- package/dist/markdown/writer.js +139 -0
- package/dist/menu/root/menu-root.d.ts +53 -0
- package/dist/menu/root/menu-root.js +92 -15
- package/dist/pagination/size/pagination-size.d.ts +3 -0
- package/dist/pagination/size/pagination-size.js +2 -1
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +1 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +1 -1
- package/dist/select/root/select-root.d.ts +6 -1
- package/dist/select/root/select-root.js +4 -2
- package/dist/shortcut-overlay/index.d.ts +1 -0
- package/dist/shortcut-overlay/index.js +1 -0
- package/dist/shortcut-overlay/root/shortcut-overlay-root.d.ts +128 -0
- package/dist/shortcut-overlay/root/shortcut-overlay-root.js +275 -0
- package/dist/slider/root/slider-root.d.ts +3 -1
- package/dist/slider/root/slider-root.js +2 -1
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.d.ts +1 -0
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.js +1 -1
- package/dist/spatial-heatmap/root/spatial-heatmap-root.d.ts +1 -0
- package/dist/spatial-heatmap/root/spatial-heatmap-root.js +1 -1
- package/dist/spatial-ribbon-chart/root/spatial-ribbon-chart-root.d.ts +1 -0
- package/dist/spatial-ribbon-chart/root/spatial-ribbon-chart-root.js +1 -1
- package/dist/spatial-scatter-chart/root/spatial-scatter-chart-root.d.ts +1 -0
- package/dist/spatial-scatter-chart/root/spatial-scatter-chart-root.js +1 -1
- package/dist/spatial-surface-chart/root/spatial-surface-chart-root.d.ts +1 -0
- package/dist/spatial-surface-chart/root/spatial-surface-chart-root.js +1 -1
- package/dist/spatial-treemap/root/spatial-treemap-root.d.ts +1 -0
- package/dist/spatial-treemap/root/spatial-treemap-root.js +1 -1
- package/dist/switch/root/switch-root.d.ts +3 -1
- package/dist/switch/root/switch-root.js +2 -1
- package/dist/tabs/tab/tab.d.ts +3 -1
- package/dist/tabs/tab/tab.js +2 -1
- package/dist/textarea/root/textarea-root.d.ts +20 -4
- package/dist/textarea/root/textarea-root.js +31 -23
- package/dist/time-input/root/time-input-root.d.ts +6 -0
- package/dist/time-input/root/time-input-root.js +4 -2
- package/dist/time-picker/root/time-picker-root.d.ts +6 -0
- package/dist/time-picker/root/time-picker-root.js +4 -2
- package/dist/toast/root/toast-root.d.ts +64 -0
- package/dist/toast/root/toast-root.js +128 -3
- package/dist/toggle/root/toggle-root.d.ts +3 -1
- package/dist/toggle/root/toggle-root.js +2 -1
- package/dist/virtual-list/root/virtual-list-root.d.ts +18 -2
- package/dist/virtual-list/root/virtual-list-root.js +103 -5
- package/examples.json +1 -1
- package/lint.json +1 -1
- package/package.json +6 -6
- package/types/jsx.d.ts +5315 -596
- package/types/svelte.d.ts +4 -0
- package/types/vue.d.ts +1085 -4
- package/types/words.d.ts +491 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { chordParts, customElement, HelixElement, keyClaimed, keyNames, listControls, listShortcuts, matchesChord, onApple, timeConverter, words, } from '@fusion.dev/helix-core';
|
|
3
|
+
import { css, nothing } from 'lit';
|
|
4
|
+
import { property, state } from 'lit/decorators.js';
|
|
5
|
+
import { html } from 'lit/static-html.js';
|
|
6
|
+
import '../../dialog/index.js';
|
|
7
|
+
const HELD = {
|
|
8
|
+
alt: () => 'Alt',
|
|
9
|
+
ctrl: () => 'Control',
|
|
10
|
+
mod: (apple) => (apple ? 'Meta' : 'Control'),
|
|
11
|
+
shift: () => 'Shift',
|
|
12
|
+
};
|
|
13
|
+
const printed = (keys, apple) => {
|
|
14
|
+
const names = keyNames(chordParts(keys), apple);
|
|
15
|
+
return names.keys.join(names.separator);
|
|
16
|
+
};
|
|
17
|
+
let HelixHeadlessShortcutOverlay = class HelixHeadlessShortcutOverlay extends HelixElement {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.delay = 600;
|
|
21
|
+
this.emptyLabel = 'No shortcuts on this screen.';
|
|
22
|
+
this.hold = 'mod';
|
|
23
|
+
this.label = 'Keyboard shortcuts';
|
|
24
|
+
this.sheetKeys = '?';
|
|
25
|
+
this.badges = [];
|
|
26
|
+
this.sheetOpen = false;
|
|
27
|
+
this.rows = [];
|
|
28
|
+
this.cancel = () => {
|
|
29
|
+
this.hide();
|
|
30
|
+
};
|
|
31
|
+
this.handleKeydown = (event) => {
|
|
32
|
+
const apple = onApple();
|
|
33
|
+
if (event.key === HELD[this.hold](apple)) {
|
|
34
|
+
if (!event.repeat && this.timer === undefined && !this.showing) {
|
|
35
|
+
this.timer = setTimeout(() => {
|
|
36
|
+
this.timer = undefined;
|
|
37
|
+
this.show();
|
|
38
|
+
}, this.delay);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.hide();
|
|
43
|
+
if (this.sheetKeys !== '' && !keyClaimed(event) && matchesChord(event, this.sheetKeys, apple)) {
|
|
44
|
+
event.preventDefault();
|
|
45
|
+
this.showSheet();
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
this.handleKeyup = (event) => {
|
|
49
|
+
if (event.key === HELD[this.hold](onApple())) {
|
|
50
|
+
this.hide();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
static { this.styles = css `
|
|
55
|
+
:host {
|
|
56
|
+
display: contents;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
[part='badges'] {
|
|
60
|
+
background: none;
|
|
61
|
+
border: 0;
|
|
62
|
+
inset: 0;
|
|
63
|
+
margin: 0;
|
|
64
|
+
overflow: visible;
|
|
65
|
+
padding: 0;
|
|
66
|
+
pointer-events: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[part='badge'] {
|
|
70
|
+
left: 0;
|
|
71
|
+
position: fixed;
|
|
72
|
+
top: 0;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[part='badge'][data-compact] [part='badge-name'] {
|
|
77
|
+
display: none;
|
|
78
|
+
}
|
|
79
|
+
`; }
|
|
80
|
+
static { this.words = 'helix-shortcut-overlay'; }
|
|
81
|
+
get showing() {
|
|
82
|
+
return this.badges.length > 0;
|
|
83
|
+
}
|
|
84
|
+
connectedCallback() {
|
|
85
|
+
super.connectedCallback();
|
|
86
|
+
document.addEventListener('keydown', this.handleKeydown, true);
|
|
87
|
+
document.addEventListener('keyup', this.handleKeyup, true);
|
|
88
|
+
document.addEventListener('pointerdown', this.cancel, true);
|
|
89
|
+
document.addEventListener('scroll', this.cancel, true);
|
|
90
|
+
window.addEventListener('blur', this.cancel);
|
|
91
|
+
window.addEventListener('resize', this.cancel);
|
|
92
|
+
}
|
|
93
|
+
disconnectedCallback() {
|
|
94
|
+
super.disconnectedCallback();
|
|
95
|
+
document.removeEventListener('keydown', this.handleKeydown, true);
|
|
96
|
+
document.removeEventListener('keyup', this.handleKeyup, true);
|
|
97
|
+
document.removeEventListener('pointerdown', this.cancel, true);
|
|
98
|
+
document.removeEventListener('scroll', this.cancel, true);
|
|
99
|
+
window.removeEventListener('blur', this.cancel);
|
|
100
|
+
window.removeEventListener('resize', this.cancel);
|
|
101
|
+
this.cancel();
|
|
102
|
+
}
|
|
103
|
+
show() {
|
|
104
|
+
const apple = onApple();
|
|
105
|
+
const width = window.innerWidth;
|
|
106
|
+
const height = window.innerHeight;
|
|
107
|
+
const badges = [];
|
|
108
|
+
for (const control of listControls()) {
|
|
109
|
+
const box = control.element.getBoundingClientRect();
|
|
110
|
+
const [keys] = control.keys;
|
|
111
|
+
if (!keys || box.bottom < 0 || box.top > height || box.right < 0 || box.left > width) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
badges.push({
|
|
115
|
+
keys: printed(keys, apple),
|
|
116
|
+
left: box.left + box.width / 2,
|
|
117
|
+
name: control.name,
|
|
118
|
+
top: box.bottom,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
this.badges = badges;
|
|
122
|
+
this.toggleState('showing', badges.length > 0);
|
|
123
|
+
}
|
|
124
|
+
hide() {
|
|
125
|
+
clearTimeout(this.timer);
|
|
126
|
+
this.timer = undefined;
|
|
127
|
+
if (this.badges.length > 0) {
|
|
128
|
+
this.badges = [];
|
|
129
|
+
this.toggleState('showing', false);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
showSheet() {
|
|
133
|
+
this.hide();
|
|
134
|
+
this.rows = this.sheetRows();
|
|
135
|
+
this.sheetOpen = true;
|
|
136
|
+
}
|
|
137
|
+
hideSheet() {
|
|
138
|
+
this.sheetOpen = false;
|
|
139
|
+
}
|
|
140
|
+
sheetRows() {
|
|
141
|
+
const apple = onApple();
|
|
142
|
+
const controls = listControls().filter((control) => control.keys.length > 0);
|
|
143
|
+
const owned = new Set(controls.map((control) => control.element));
|
|
144
|
+
const rows = controls.flatMap((control) => control.keys.map((keys) => ({ keys: printed(keys, apple), name: control.name })));
|
|
145
|
+
for (const shortcut of listShortcuts()) {
|
|
146
|
+
if (shortcut.target && owned.has(shortcut.target)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
rows.push({ keys: printed(shortcut.keys, apple), name: shortcut.label });
|
|
150
|
+
}
|
|
151
|
+
const seen = new Set();
|
|
152
|
+
return rows.filter((row) => {
|
|
153
|
+
const key = `${row.keys}\u0000${row.name}`;
|
|
154
|
+
if (seen.has(key)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
seen.add(key);
|
|
158
|
+
return true;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
updated(changed) {
|
|
162
|
+
super.updated(changed);
|
|
163
|
+
const layer = this.partNamed('badges');
|
|
164
|
+
if (changed.has('badges') &&
|
|
165
|
+
layer?.showPopover &&
|
|
166
|
+
this.badges.length > 0 &&
|
|
167
|
+
!layer.matches(':popover-open')) {
|
|
168
|
+
layer.showPopover();
|
|
169
|
+
}
|
|
170
|
+
if (changed.has('badges')) {
|
|
171
|
+
this.arrange();
|
|
172
|
+
}
|
|
173
|
+
if (changed.has('badges') &&
|
|
174
|
+
this.badges.length > 0 &&
|
|
175
|
+
globalThis.document?.fonts?.status === 'loading') {
|
|
176
|
+
void document.fonts.ready.then(() => {
|
|
177
|
+
if (this.badges.length > 0) {
|
|
178
|
+
this.show();
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
arrange() {
|
|
184
|
+
const placed = [];
|
|
185
|
+
const margin = 4;
|
|
186
|
+
const width = window.innerWidth;
|
|
187
|
+
const height = window.innerHeight;
|
|
188
|
+
const drawn = [...(this.renderRoot.querySelectorAll('[part~="badge"]') ?? [])];
|
|
189
|
+
drawn.forEach((element, index) => {
|
|
190
|
+
const badge = this.badges[index];
|
|
191
|
+
if (!badge) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const box = (compact, top) => {
|
|
195
|
+
element.toggleAttribute('data-compact', compact);
|
|
196
|
+
const { height: tall, width: wide } = element.getBoundingClientRect();
|
|
197
|
+
const left = Math.round(Math.min(Math.max(badge.left - wide / 2, margin), width - wide - margin));
|
|
198
|
+
const at = Math.round(Math.min(Math.max(top, margin), height - tall - margin));
|
|
199
|
+
return { bottom: at + tall, left, right: left + wide, top: at };
|
|
200
|
+
};
|
|
201
|
+
const hits = (one) => placed.filter((other) => one.left < other.right &&
|
|
202
|
+
one.right > other.left &&
|
|
203
|
+
one.top < other.bottom &&
|
|
204
|
+
one.bottom > other.top);
|
|
205
|
+
const under = badge.top + margin;
|
|
206
|
+
let place = box(false, under);
|
|
207
|
+
if (hits(place).length > 0) {
|
|
208
|
+
place = box(true, under);
|
|
209
|
+
}
|
|
210
|
+
for (let tries = 0; tries < 4 && hits(place).length > 0; tries += 1) {
|
|
211
|
+
const below = Math.max(...hits(place).map((other) => other.bottom));
|
|
212
|
+
place = box(true, below + 2);
|
|
213
|
+
}
|
|
214
|
+
element.style.left = `${place.left}px`;
|
|
215
|
+
element.style.top = `${place.top}px`;
|
|
216
|
+
placed.push(place);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
render() {
|
|
220
|
+
const dialog = this.tag('dialog');
|
|
221
|
+
return html `${this.badges.length > 0
|
|
222
|
+
? html `<div part="badges" popover="manual" aria-hidden="true">
|
|
223
|
+
${this.badges.map((badge) => html `<span part="badge"
|
|
224
|
+
><kbd part="badge-keys">${badge.keys}</kbd> <span part="badge-name">${badge.name}</span></span
|
|
225
|
+
>`)}
|
|
226
|
+
</div>`
|
|
227
|
+
: nothing}<${dialog}
|
|
228
|
+
part="sheet"
|
|
229
|
+
exportparts="body: sheet-body, dismiss: sheet-dismiss, dismiss-mark: sheet-dismiss-mark,
|
|
230
|
+
footer: sheet-footer, header: sheet-header, surface: sheet-surface"
|
|
231
|
+
label=${this.label}
|
|
232
|
+
.open=${this.sheetOpen}
|
|
233
|
+
@close=${() => {
|
|
234
|
+
this.sheetOpen = false;
|
|
235
|
+
}}
|
|
236
|
+
>
|
|
237
|
+
<h2 slot="header">${this.label}</h2>
|
|
238
|
+
${this.rows.length === 0
|
|
239
|
+
? html `<p part="empty">${this.emptyLabel}</p>`
|
|
240
|
+
: html `<dl part="list">
|
|
241
|
+
${this.rows.map((row) => html `<div part="row"><dt part="name">${row.name}</dt><dd part="keys"><kbd>${row.keys}</kbd></dd></div>`)}
|
|
242
|
+
</dl>`}
|
|
243
|
+
</${dialog}>`;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
__decorate([
|
|
247
|
+
property({ converter: timeConverter('delay', 600) })
|
|
248
|
+
], HelixHeadlessShortcutOverlay.prototype, "delay", void 0);
|
|
249
|
+
__decorate([
|
|
250
|
+
words,
|
|
251
|
+
property({ attribute: 'empty-label' })
|
|
252
|
+
], HelixHeadlessShortcutOverlay.prototype, "emptyLabel", void 0);
|
|
253
|
+
__decorate([
|
|
254
|
+
property()
|
|
255
|
+
], HelixHeadlessShortcutOverlay.prototype, "hold", void 0);
|
|
256
|
+
__decorate([
|
|
257
|
+
words,
|
|
258
|
+
property()
|
|
259
|
+
], HelixHeadlessShortcutOverlay.prototype, "label", void 0);
|
|
260
|
+
__decorate([
|
|
261
|
+
property({ attribute: 'sheet-keys' })
|
|
262
|
+
], HelixHeadlessShortcutOverlay.prototype, "sheetKeys", void 0);
|
|
263
|
+
__decorate([
|
|
264
|
+
state()
|
|
265
|
+
], HelixHeadlessShortcutOverlay.prototype, "badges", void 0);
|
|
266
|
+
__decorate([
|
|
267
|
+
state()
|
|
268
|
+
], HelixHeadlessShortcutOverlay.prototype, "sheetOpen", void 0);
|
|
269
|
+
__decorate([
|
|
270
|
+
state()
|
|
271
|
+
], HelixHeadlessShortcutOverlay.prototype, "rows", void 0);
|
|
272
|
+
HelixHeadlessShortcutOverlay = __decorate([
|
|
273
|
+
customElement('helix-headless-shortcut-overlay')
|
|
274
|
+
], HelixHeadlessShortcutOverlay);
|
|
275
|
+
export { HelixHeadlessShortcutOverlay };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, ListedController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessSlider_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
@@ -106,6 +106,8 @@ declare const HelixHeadlessSlider_base: (new (...args: any[]) => import("@fusion
|
|
|
106
106
|
* @cssstate invalid - The slider has an error to show, from the browser's validation or from your `feedback`.
|
|
107
107
|
*/
|
|
108
108
|
export declare class HelixHeadlessSlider extends HelixHeadlessSlider_base {
|
|
109
|
+
/** On the page's list of controls, where a command palette and a shortcut overlay find it. */
|
|
110
|
+
protected readonly listed: ListedController;
|
|
109
111
|
/**
|
|
110
112
|
* The key this family's words are registered under, its styled tag:
|
|
111
113
|
* `registerWords('de', { 'helix-slider': { rangeText: '{start} bis {end}' } })`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { AriaForwardController, customElement, formatNumber, formatWords, HelixFormElement, isRtl, MixinControllerValue, MixinField, numberConverter, reportValues, restoreValue, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { AriaForwardController, customElement, formatNumber, formatWords, HelixFormElement, isRtl, ListedController, MixinControllerValue, MixinField, numberConverter, reportValues, restoreValue, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { html, nothing } from 'lit';
|
|
4
4
|
import { property, state } from 'lit/decorators.js';
|
|
5
5
|
const SLIDER_KEYS = new Set([
|
|
@@ -15,6 +15,7 @@ const SLIDER_KEYS = new Set([
|
|
|
15
15
|
let HelixHeadlessSlider = class HelixHeadlessSlider extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(...arguments);
|
|
18
|
+
this.listed = new ListedController(this, 'focus', () => this.internals?.ariaKeyShortcuts);
|
|
18
19
|
this.aria = new AriaForwardController(this, {
|
|
19
20
|
target: () => this.partNamed('control'),
|
|
20
21
|
});
|
|
@@ -86,6 +86,7 @@ declare const HelixHeadlessSpatialBarChart_base: typeof HelixElement & (new (...
|
|
|
86
86
|
* @csspart plot - The box the drawing fills, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
87
87
|
* @csspart ring - The outline around the bar the pointer or the keys rest on, painted after it, so the bars in front of it cover it.
|
|
88
88
|
* @csspart ring-behind - The same outline, faint and dashed, drawn over every bar, so the part of the bar the pointer or the keys rest on that others hide still shows.
|
|
89
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
89
90
|
* @csspart summary - The number of bars, series, and categories, and the range of values, written as a sentence for screen readers, which describes the plot. Hide it visually.
|
|
90
91
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
91
92
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|
|
@@ -154,7 +154,7 @@ let HelixHeadlessSpatialBarChart = class HelixHeadlessSpatialBarChart extends Mi
|
|
|
154
154
|
${readable ? this.renderLive(field, at) : nothing}
|
|
155
155
|
${this.renderTooltip(cell?.value === undefined ? undefined : cell.row)}
|
|
156
156
|
</div>
|
|
157
|
-
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderTable()}`;
|
|
157
|
+
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderSonify()}${this.renderTable()}`;
|
|
158
158
|
}
|
|
159
159
|
renderFallback(field, at) {
|
|
160
160
|
const view = boxView(field.axes, this.camera, [], this.noBox);
|
|
@@ -107,6 +107,7 @@ type DrawnCorners = {
|
|
|
107
107
|
* @csspart left-face - The side of a prism facing the light more: from the isometric view, the side toward the next row, drawn at its lower left. Left out where the view shows no side.
|
|
108
108
|
* @csspart right-face - The side of a prism facing the light less: from the isometric view, the side toward the next column, drawn at its lower right. Left out where the view shows one side or none.
|
|
109
109
|
* @csspart row - A column of the strip, which a grid reads as a row, under `selection-mode`. It holds the column's grid cells, which draw nothing: the prisms are painted apart, in the order the view needs.
|
|
110
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
110
111
|
* @csspart strip - The box the drawing fills, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
111
112
|
* @csspart top-face - The top of a prism, which carries the reading's tone.
|
|
112
113
|
*
|
|
@@ -216,7 +216,7 @@ let HelixHeadlessSpatialHeatmap = class HelixHeadlessSpatialHeatmap extends Heli
|
|
|
216
216
|
<span part="end"><slot name="end"></slot></span>
|
|
217
217
|
</div>${readable ? this.renderOverview(cells) : nothing}${this.status.spoken
|
|
218
218
|
? html `<span part="selection" role="status">${this.status.said}</span>`
|
|
219
|
-
: nothing}${this.renderTable()}`;
|
|
219
|
+
: nothing}${this.renderSonify()}${this.renderTable()}`;
|
|
220
220
|
}
|
|
221
221
|
renderPrism(prism, active, picked, grid, tone) {
|
|
222
222
|
return svg `<g
|
|
@@ -83,6 +83,7 @@ declare const HelixHeadlessSpatialRibbonChart_base: typeof HelixElement & (new (
|
|
|
83
83
|
* @csspart plot - The box the drawing fills, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
84
84
|
* @csspart ribbon - One ribbon, its faces in its series' color.
|
|
85
85
|
* @csspart ring - The ring around the reading the pointer or the keys rest on, drawn over the ribbons.
|
|
86
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
86
87
|
* @csspart summary - The number of readings, series, and places, and the range of values, written as a sentence for screen readers, which describes the plot. Hide it visually.
|
|
87
88
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
88
89
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|
|
@@ -150,7 +150,7 @@ let HelixHeadlessSpatialRibbonChart = class HelixHeadlessSpatialRibbonChart exte
|
|
|
150
150
|
${readable ? this.renderLive(field, at) : nothing}
|
|
151
151
|
${this.renderTooltip(cell?.value === undefined ? undefined : cell.row)}
|
|
152
152
|
</div>
|
|
153
|
-
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderTable()}`;
|
|
153
|
+
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderSonify()}${this.renderTable()}`;
|
|
154
154
|
}
|
|
155
155
|
renderFallback(field, at) {
|
|
156
156
|
const view = boxView(field.axes, this.camera, [], this.noBox);
|
|
@@ -81,6 +81,7 @@ declare const HelixHeadlessSpatialScatterChart_base: typeof HelixElement & (new
|
|
|
81
81
|
* @csspart point - One point of the chart's own drawing.
|
|
82
82
|
* @csspart point-active - The point the pointer or the keys rest on, in the chart's own drawing. Set alongside `point`.
|
|
83
83
|
* @csspart ring - The ring around the point the pointer or the keys rest on, drawn over every point.
|
|
84
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
84
85
|
* @csspart summary - The three measures and the number of points, written as a sentence for screen readers, which describes the plot. Hide it visually.
|
|
85
86
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
86
87
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|
|
@@ -152,7 +152,7 @@ let HelixHeadlessSpatialScatterChart = class HelixHeadlessSpatialScatterChart ex
|
|
|
152
152
|
${this.renderLive(points, at)}
|
|
153
153
|
${this.renderTooltip(points[at]?.row)}
|
|
154
154
|
</div>
|
|
155
|
-
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderTable()}`;
|
|
155
|
+
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderSonify()}${this.renderTable()}`;
|
|
156
156
|
}
|
|
157
157
|
renderFallback(field, at) {
|
|
158
158
|
const view = boxView(field.axes, this.camera, [], this.noBox);
|
|
@@ -82,6 +82,7 @@ declare const HelixHeadlessSpatialSurfaceChart_base: typeof HelixElement & (new
|
|
|
82
82
|
* @csspart mark - The invisible point the tooltip is anchored to, where the renderer draws the reading.
|
|
83
83
|
* @csspart plot - The box the drawing fills, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
84
84
|
* @csspart ring - The ring around the reading the pointer or the keys rest on, drawn over the surface.
|
|
85
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
85
86
|
* @csspart summary - The measures, the number of readings, and the range of heights, written as a sentence for screen readers, which describes the plot. Hide it visually.
|
|
86
87
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
87
88
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|
|
@@ -159,7 +159,7 @@ let HelixHeadlessSpatialSurfaceChart = class HelixHeadlessSpatialSurfaceChart ex
|
|
|
159
159
|
${readable ? this.renderLive(field, at) : nothing}
|
|
160
160
|
${this.renderTooltip(field.cells[at]?.row)}
|
|
161
161
|
</div>
|
|
162
|
-
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderTable()}`;
|
|
162
|
+
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderSonify()}${this.renderTable()}`;
|
|
163
163
|
}
|
|
164
164
|
renderFallback(field, at) {
|
|
165
165
|
const view = boxView(field.axes, this.camera, [], this.noBox);
|
|
@@ -86,6 +86,7 @@ declare const HelixHeadlessSpatialTreemap_base: typeof HelixElement & (new (...a
|
|
|
86
86
|
* @csspart plot - The box the drawing fills, which takes focus to be read by key. It is named by the host's `aria-labelledby` or `aria-label`, then by `label`, then by the caption of the table.
|
|
87
87
|
* @csspart ring - The outline around the block the pointer or the keys rest on, painted after it, so the blocks in front of it cover it.
|
|
88
88
|
* @csspart ring-behind - The same outline, faint and dashed, drawn over every block, so the part of the block the pointer or the keys rest on that others hide still shows.
|
|
89
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
89
90
|
* @csspart summary - The number of items and groups and the range of their sizes, written as a sentence for screen readers, which describes the plot. Hide it visually.
|
|
90
91
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
91
92
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|
|
@@ -152,7 +152,7 @@ let HelixHeadlessSpatialTreemap = class HelixHeadlessSpatialTreemap extends Mixi
|
|
|
152
152
|
${readable ? this.renderLive(field, at) : nothing}
|
|
153
153
|
${this.renderTooltip(field.blocks[at]?.row)}
|
|
154
154
|
</div>
|
|
155
|
-
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderTable()}`;
|
|
155
|
+
${readable ? this.renderSummary(field) : this.renderStatus()}${this.renderSonify()}${this.renderTable()}`;
|
|
156
156
|
}
|
|
157
157
|
renderFallback(field, at) {
|
|
158
158
|
const view = boxView(field.axes, this.camera, [], this.noBox);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement, HostClickController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, HostClickController, ListedController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerCheckedInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
@@ -58,6 +58,8 @@ declare const HelixHeadlessSwitch_base: (new (...args: any[]) => import("@fusion
|
|
|
58
58
|
* @cssstate invalid - The control has an error to show, from the browser's validation or from your `feedback`.
|
|
59
59
|
*/
|
|
60
60
|
export declare class HelixHeadlessSwitch extends HelixHeadlessSwitch_base {
|
|
61
|
+
/** On the page's list of controls, where a command palette and a shortcut overlay find it. */
|
|
62
|
+
protected readonly listed: ListedController;
|
|
61
63
|
/**
|
|
62
64
|
* The key this family's words are registered under, its styled tag:
|
|
63
65
|
* `registerWords('de', { 'helix-switch': { valueMissingMessage: '...' } })`.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { AriaForwardController, customElement, HelixFormElement, HostClickController, MixinControllerChecked, MixinField, markRegion, words, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { AriaForwardController, customElement, HelixFormElement, HostClickController, ListedController, MixinControllerChecked, MixinField, markRegion, words, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { html, nothing } from 'lit';
|
|
4
4
|
import { property } from 'lit/decorators.js';
|
|
5
5
|
let HelixHeadlessSwitch = class HelixHeadlessSwitch extends MixinControllerChecked(MixinField(HelixFormElement)) {
|
|
6
6
|
constructor() {
|
|
7
7
|
super(...arguments);
|
|
8
|
+
this.listed = new ListedController(this, 'press', () => this.internals?.ariaKeyShortcuts);
|
|
8
9
|
this.aria = new AriaForwardController(this, {
|
|
9
10
|
label: true,
|
|
10
11
|
target: () => this.partNamed('control'),
|
package/dist/tabs/tab/tab.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HelixElement } from '@fusion.dev/helix-core';
|
|
1
|
+
import { HelixElement, ListedController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.dev/helix-core").DismissibleElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSelectableItemInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
@@ -41,6 +41,8 @@ declare const HelixHeadlessTab_base: (new (...args: any[]) => import("@fusion.de
|
|
|
41
41
|
* @interactive button
|
|
42
42
|
*/
|
|
43
43
|
export declare class HelixHeadlessTab extends HelixHeadlessTab_base {
|
|
44
|
+
/** On the page's list of controls, where a command palette and a shortcut overlay find it. */
|
|
45
|
+
protected readonly listed: ListedController;
|
|
44
46
|
/**
|
|
45
47
|
* The key this family's words are registered under, its styled tag:
|
|
46
48
|
* `registerWords('de', { 'helix-tab': { dismissLabel: 'Schließen' } })`.
|
package/dist/tabs/tab/tab.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { customElement, glyphPath, HelixElement, MixinDismissible, MixinSelectableItem, plainClick, reflectElements, words, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { customElement, glyphPath, HelixElement, ListedController, MixinDismissible, MixinSelectableItem, plainClick, reflectElements, words, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { x } from '@fusion.dev/helix-icons';
|
|
4
4
|
import { html, nothing } from 'lit';
|
|
5
5
|
import { property } from 'lit/decorators.js';
|
|
6
6
|
let HelixHeadlessTab = class HelixHeadlessTab extends MixinDismissible(MixinSelectableItem(HelixElement)) {
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
|
+
this.listed = new ListedController(this, 'press', () => this.internals?.ariaKeyShortcuts);
|
|
9
10
|
this.itemPart = 'tab';
|
|
10
11
|
this.controls = undefined;
|
|
11
12
|
this.dismissLabel = 'Close';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement, type OwnRule } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, ListedController, type OwnRule } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
-
declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
3
|
+
declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusion.dev/helix-core").VoiceElement) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary A multi-line text field.
|
|
6
6
|
*
|
|
@@ -46,7 +46,9 @@ declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusi
|
|
|
46
46
|
*
|
|
47
47
|
* @event {Event} change - Sent from the textarea when the user finishes an edit.
|
|
48
48
|
* @event {HelixBeforeChangeEvent} helix-before-change - Fired as the text changes, and cancelable.
|
|
49
|
+
* @event {HelixBeforeListenEvent} helix-before-listen - The dictation button was pressed. Cancelable: cancel it to keep the field from listening.
|
|
49
50
|
* @event {HelixClearEvent} helix-clear - Fired after the clear button has emptied the field, after `input` and `change`.
|
|
51
|
+
* @event {HelixListenEvent} helix-listen - Dictation settled on a phrase and put it in the value, after the field's own `input`.
|
|
50
52
|
* @event {Event} input - Fired after the value changes.
|
|
51
53
|
*
|
|
52
54
|
* @csspart clear - The button that empties the field, under `clearable`.
|
|
@@ -55,11 +57,18 @@ declare const HelixHeadlessTextarea_base: (new (...args: any[]) => import("@fusi
|
|
|
55
57
|
* @csspart field - The box that holds the textarea.
|
|
56
58
|
* @csspart hint - Help under the field, while nothing is wrong.
|
|
57
59
|
* @csspart label - The label above the field.
|
|
60
|
+
* @csspart voice - The dictation button, under `voice`.
|
|
61
|
+
* @csspart voice-listening - The dictation button while it listens. Set alongside `voice`.
|
|
62
|
+
* @csspart voice-status - What a screen reader hears as dictation starts and stops, drawn for no one else.
|
|
58
63
|
*
|
|
59
64
|
* @cssstate blank - The field holds no text.
|
|
60
65
|
* @cssstate invalid - The control has an error to show, from the browser's validation, `validate`, or your `feedback`.
|
|
66
|
+
* @cssstate listening - While the field listens for dictation. The element sets `--dictation-level` on itself meanwhile, from 0 to 1, for a meter.
|
|
61
67
|
*/
|
|
62
68
|
export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
|
|
69
|
+
protected static markRules: string[];
|
|
70
|
+
/** On the page's list of controls, where a command palette and a shortcut overlay find it. */
|
|
71
|
+
protected readonly listed: ListedController;
|
|
63
72
|
/**
|
|
64
73
|
* The key this family's words are registered under, its styled tag:
|
|
65
74
|
* `registerWords('de', { 'helix-textarea': { clearLabel: 'Leeren' } })`.
|
|
@@ -140,7 +149,8 @@ export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
|
|
|
140
149
|
readOnly: boolean;
|
|
141
150
|
/** Focus is delegated to the control, so the host is never the target. */
|
|
142
151
|
static shadowRootOptions: ShadowRootInit;
|
|
143
|
-
|
|
152
|
+
/** The textarea, for a family built on this one to read. */
|
|
153
|
+
protected get control(): HTMLTextAreaElement | null;
|
|
144
154
|
/**
|
|
145
155
|
* Every keystroke, cancelable, and put back where it is refused.
|
|
146
156
|
*
|
|
@@ -162,7 +172,7 @@ export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
|
|
|
162
172
|
* Reset to `auto` first, because `scrollHeight` of an element already sized to
|
|
163
173
|
* its content is that size, so without the reset the box can only ever grow.
|
|
164
174
|
*/
|
|
165
|
-
|
|
175
|
+
protected grow(): void;
|
|
166
176
|
/**
|
|
167
177
|
* Re-measures when the box changes rather than only when a property does.
|
|
168
178
|
*
|
|
@@ -269,6 +279,12 @@ export declare class HelixHeadlessTextarea extends HelixHeadlessTextarea_base {
|
|
|
269
279
|
wrap: 'hard' | 'off' | 'soft';
|
|
270
280
|
/** The cross on the clear button, behind a seam a tier can move. */
|
|
271
281
|
protected renderClearIcon(): TemplateResult;
|
|
282
|
+
/**
|
|
283
|
+
* The `<textarea>` itself, behind a seam a family built on this one wraps:
|
|
284
|
+
* Code Input draws its highlighted text under it.
|
|
285
|
+
*/
|
|
286
|
+
protected renderControl(): TemplateResult;
|
|
287
|
+
protected voiceField(): HTMLInputElement | HTMLTextAreaElement | null;
|
|
272
288
|
protected render(): TemplateResult;
|
|
273
289
|
}
|
|
274
290
|
declare global {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { AriaForwardController, applyOwnRule, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, isRtl, MixinControllerValue, MixinField, numberConverter, restoreValue, words, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { AriaForwardController, applyOwnRule, customElement, drawIcon, HelixClearEvent, HelixFormElement, holdCaret, isRtl, ListedController, MixinControllerValue, MixinField, MixinVoice, numberConverter, restoreValue, SPOKEN_RULE, words, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { x } from '@fusion.dev/helix-icons';
|
|
4
4
|
import { html, nothing } from 'lit';
|
|
5
5
|
import { property } from 'lit/decorators.js';
|
|
6
6
|
import { grownHeight, lineMetrics } from '../grow.js';
|
|
7
|
-
let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerValue(MixinField(HelixFormElement)) {
|
|
7
|
+
let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinVoice(MixinControllerValue(MixinField(HelixFormElement))) {
|
|
8
8
|
constructor() {
|
|
9
9
|
super(...arguments);
|
|
10
|
+
this.listed = new ListedController(this, 'focus', () => this.internals?.ariaKeyShortcuts);
|
|
10
11
|
this.aria = new AriaForwardController(this, {
|
|
11
12
|
target: () => this.partNamed('control'),
|
|
12
13
|
});
|
|
@@ -44,6 +45,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
44
45
|
this.rows = 3;
|
|
45
46
|
this.wrap = 'soft';
|
|
46
47
|
}
|
|
48
|
+
static { this.markRules = [SPOKEN_RULE]; }
|
|
47
49
|
static { this.words = 'helix-textarea'; }
|
|
48
50
|
static { this.shadowRootOptions = {
|
|
49
51
|
...HelixFormElement.shadowRootOptions,
|
|
@@ -186,30 +188,36 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
186
188
|
renderClearIcon() {
|
|
187
189
|
return html `<slot name="clear-icon">${drawIcon(x)}</slot>`;
|
|
188
190
|
}
|
|
191
|
+
renderControl() {
|
|
192
|
+
return html `<textarea
|
|
193
|
+
part="control"
|
|
194
|
+
id=${this.controlId}
|
|
195
|
+
.value=${this.value}
|
|
196
|
+
rows=${this.rows}
|
|
197
|
+
cols=${this.cols ?? nothing}
|
|
198
|
+
wrap=${this.wrap}
|
|
199
|
+
name=${this.name || nothing}
|
|
200
|
+
placeholder=${this.placeholder || nothing}
|
|
201
|
+
autocomplete=${this.autocomplete || nothing}
|
|
202
|
+
minlength=${this.minLength ?? nothing}
|
|
203
|
+
maxlength=${this.maxLength ?? nothing}
|
|
204
|
+
aria-describedby=${this.describedBy ?? nothing}
|
|
205
|
+
aria-invalid=${this.invalidity ?? nothing}
|
|
206
|
+
?disabled=${this.isDisabled}
|
|
207
|
+
?readonly=${this.readOnly}
|
|
208
|
+
?required=${this.required}
|
|
209
|
+
@input=${this.handleInput}
|
|
210
|
+
@change=${this.handleChange}
|
|
211
|
+
></textarea>`;
|
|
212
|
+
}
|
|
213
|
+
voiceField() {
|
|
214
|
+
return this.partNamed('control');
|
|
215
|
+
}
|
|
189
216
|
render() {
|
|
190
217
|
return html `${this.renderLabel()}
|
|
191
218
|
<div part="field">
|
|
192
219
|
<slot name="start"></slot>
|
|
193
|
-
|
|
194
|
-
part="control"
|
|
195
|
-
id=${this.controlId}
|
|
196
|
-
.value=${this.value}
|
|
197
|
-
rows=${this.rows}
|
|
198
|
-
cols=${this.cols ?? nothing}
|
|
199
|
-
wrap=${this.wrap}
|
|
200
|
-
name=${this.name || nothing}
|
|
201
|
-
placeholder=${this.placeholder || nothing}
|
|
202
|
-
autocomplete=${this.autocomplete || nothing}
|
|
203
|
-
minlength=${this.minLength ?? nothing}
|
|
204
|
-
maxlength=${this.maxLength ?? nothing}
|
|
205
|
-
aria-describedby=${this.describedBy ?? nothing}
|
|
206
|
-
aria-invalid=${this.invalidity ?? nothing}
|
|
207
|
-
?disabled=${this.isDisabled}
|
|
208
|
-
?readonly=${this.readOnly}
|
|
209
|
-
?required=${this.required}
|
|
210
|
-
@input=${this.handleInput}
|
|
211
|
-
@change=${this.handleChange}
|
|
212
|
-
></textarea>
|
|
220
|
+
${this.renderControl()}
|
|
213
221
|
<slot name="end"></slot>
|
|
214
222
|
${this.clearable && this.value !== '' && !this.isDisabled && !this.readOnly
|
|
215
223
|
? html `<button
|
|
@@ -220,7 +228,7 @@ let HelixHeadlessTextarea = class HelixHeadlessTextarea extends MixinControllerV
|
|
|
220
228
|
>
|
|
221
229
|
${this.renderClearIcon()}
|
|
222
230
|
</button>`
|
|
223
|
-
: nothing}
|
|
231
|
+
: nothing}${this.renderVoice()}
|
|
224
232
|
</div>
|
|
225
233
|
${this.renderHint()}${this.renderFeedback()}`;
|
|
226
234
|
}
|