@fusion.dev/helix-headless 0.217.0 → 0.219.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/breadcrumbs/breadcrumb/breadcrumb.d.ts +13 -2
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +19 -9
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +16 -1
- package/dist/breadcrumbs/root/breadcrumbs-root.js +6 -0
- package/dist/button/root/button-root.d.ts +33 -0
- package/dist/button/root/button-root.js +13 -3
- package/dist/canvas/root/canvas-root.d.ts +11 -0
- package/dist/canvas/root/canvas-root.js +1 -0
- package/dist/chat/composer/chat-composer.d.ts +221 -6
- package/dist/chat/composer/chat-composer.js +249 -19
- 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 +1 -0
- package/dist/chat/root/chat-root.js +1 -1
- package/dist/copy-button/root/copy-button-root.js +3 -3
- package/dist/device-screen/root/device-screen-root.d.ts +11 -0
- package/dist/device-screen/root/device-screen-root.js +22 -10
- package/dist/dialog/root/dialog-root.js +6 -1
- package/dist/drilldown/item/drilldown-item.js +1 -1
- package/dist/element-events.generated.js +1 -0
- package/dist/filter-input/root/filter-input-root.d.ts +4 -3
- package/dist/filter-input/root/filter-input-root.js +1 -20
- package/dist/graph/root/graph-root.d.ts +11 -0
- package/dist/graph/root/graph-root.js +4 -1
- package/dist/input/root/input-root.d.ts +6 -0
- package/dist/input/root/input-root.js +7 -0
- package/dist/lightbox/root/lightbox-root.d.ts +4 -1
- package/dist/lightbox/root/lightbox-root.js +10 -8
- package/dist/listbox/root/listbox-root.d.ts +21 -0
- package/dist/listbox/root/listbox-root.js +37 -2
- package/dist/log/group/log-group.d.ts +7 -1
- package/dist/log/group/log-group.js +14 -1
- package/dist/log/root/log-root.d.ts +13 -3
- package/dist/log/root/log-root.js +5 -2
- package/dist/map/root/map-root.d.ts +11 -0
- package/dist/map/root/map-root.js +28 -12
- package/dist/menu/root/menu-root.d.ts +8 -0
- package/dist/menu/root/menu-root.js +22 -1
- package/dist/menu/section/menu-section.d.ts +10 -0
- package/dist/menu/section/menu-section.js +10 -0
- package/dist/meter/index.d.ts +1 -0
- package/dist/meter/index.js +1 -0
- package/dist/meter/root/meter-root.d.ts +16 -1
- package/dist/meter/root/meter-root.js +27 -11
- package/dist/meter/segment/meter-segment.d.ts +74 -0
- package/dist/meter/segment/meter-segment.js +47 -0
- package/dist/scroll-area/root/scroll-area-root.d.ts +20 -3
- package/dist/scroll-area/root/scroll-area-root.js +23 -4
- package/dist/spatial-bar-chart/bars.d.ts +125 -5
- package/dist/spatial-bar-chart/bars.js +194 -17
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.d.ts +148 -6
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.js +285 -16
- package/dist/splitter/root/splitter-root.js +1 -0
- package/dist/tabs/root/tabs-root.d.ts +4 -0
- package/dist/tabs/tab/tab.d.ts +1 -0
- package/dist/tabs/tab/tab.js +2 -2
- package/dist/tag/root/tag-root.d.ts +1 -1
- package/dist/terminal/root/terminal-root.d.ts +11 -0
- package/dist/terminal/root/terminal-root.js +23 -10
- package/dist/toolbar/root/toolbar-root.d.ts +4 -1
- package/dist/tooltip/root/tooltip-root.d.ts +23 -1
- package/dist/tooltip/root/tooltip-root.js +28 -5
- package/dist/tour/root/tour-root.d.ts +1 -0
- package/dist/tour/root/tour-root.js +4 -1
- package/dist/tour/stop/tour-stop.js +1 -0
- package/examples.json +1 -1
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +1373 -52
- package/types/svelte.d.ts +1 -0
- package/types/vue.d.ts +312 -17
- package/types/words.d.ts +9 -1
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { customElement, DelayController, HelixFormElement, HelixSendEvent, HelixTypingEvent, hostAria, MixinVoice, markRegion, numberConverter, SPOKEN_RULE, timeConverter, words, } from '@fusion.dev/helix-core';
|
|
3
|
-
import { arrowElbowDownLeft } from '@fusion.dev/helix-icons';
|
|
2
|
+
import { customElement, DelayController, deepActiveElement, HelixFormElement, HelixSendEvent, HelixStopEvent, HelixTypingEvent, hostAria, MixinVoice, markRegion, motionPaused, numberConverter, onMotionChange, pressedOwnControl, reducedMotion, SPOKEN_RULE, timeConverter, words, } from '@fusion.dev/helix-core';
|
|
3
|
+
import { arrowElbowDownLeft, stop } from '@fusion.dev/helix-icons';
|
|
4
4
|
import { html, nothing } from 'lit';
|
|
5
5
|
import { property, state } from 'lit/decorators.js';
|
|
6
6
|
import { live } from 'lit/directives/live.js';
|
|
7
7
|
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
8
|
+
import { html as staticHtml } from 'lit/static-html.js';
|
|
9
|
+
import '../../tooltip/index.js';
|
|
10
|
+
const EXAMPLE_SHOWN = 6500;
|
|
11
|
+
const EXAMPLE_SHORT = 40;
|
|
12
|
+
const EXAMPLE_PER_CHARACTER = 60;
|
|
13
|
+
const EXAMPLE_LONGEST = 10000;
|
|
14
|
+
const EXAMPLE_LEAVE = 250;
|
|
15
|
+
const EXAMPLE_CROSS = 100;
|
|
16
|
+
const EXAMPLE_ENTER = 350;
|
|
17
|
+
export function exampleShown(example) {
|
|
18
|
+
const extra = Math.max(0, Array.from(example).length - EXAMPLE_SHORT);
|
|
19
|
+
return Math.min(EXAMPLE_LONGEST, EXAMPLE_SHOWN + extra * EXAMPLE_PER_CHARACTER);
|
|
20
|
+
}
|
|
8
21
|
let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoice(HelixFormElement) {
|
|
9
22
|
constructor() {
|
|
10
23
|
super(...arguments);
|
|
24
|
+
this.attached = false;
|
|
25
|
+
this.busy = false;
|
|
11
26
|
this.feedback = '';
|
|
12
27
|
this.label = 'Message';
|
|
13
28
|
this.placeholder = '';
|
|
29
|
+
this.placeholders = [];
|
|
30
|
+
this.queue = false;
|
|
14
31
|
this.required = false;
|
|
15
32
|
this.rows = 1;
|
|
33
|
+
this.sendDisabled = false;
|
|
16
34
|
this.sendLabel = 'Send';
|
|
35
|
+
this.sendReason = '';
|
|
36
|
+
this.stopLabel = 'Stop';
|
|
17
37
|
this.submitOn = 'enter';
|
|
18
38
|
this.typingTimeout = 3000;
|
|
19
39
|
this.value = '';
|
|
@@ -22,6 +42,9 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
22
42
|
this.touched = false;
|
|
23
43
|
this.edited = false;
|
|
24
44
|
this.shownInvalid = false;
|
|
45
|
+
this.example = 0;
|
|
46
|
+
this.focused = false;
|
|
47
|
+
this.onScreen = true;
|
|
25
48
|
this.pause = new DelayController(this, { renders: false });
|
|
26
49
|
this.touch = () => {
|
|
27
50
|
this.touched = true;
|
|
@@ -32,6 +55,19 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
32
55
|
this.touch();
|
|
33
56
|
}
|
|
34
57
|
};
|
|
58
|
+
this.handleAttachmentsDown = (event) => {
|
|
59
|
+
const region = event.currentTarget;
|
|
60
|
+
if (event.button !== 0 || pressedOwnControl(event, region) || this.isDisabled) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
this.partNamed('field')?.focus();
|
|
65
|
+
};
|
|
66
|
+
this.focusedOn = 'elsewhere';
|
|
67
|
+
this.handleFocus = (event) => {
|
|
68
|
+
this.focused = event.type === 'focus';
|
|
69
|
+
this.turnExamples();
|
|
70
|
+
};
|
|
35
71
|
this.handleInput = (event) => {
|
|
36
72
|
event.stopPropagation();
|
|
37
73
|
this.value = event.target.value;
|
|
@@ -42,6 +78,9 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
42
78
|
this.handleSend = () => {
|
|
43
79
|
this.send();
|
|
44
80
|
};
|
|
81
|
+
this.handleStop = () => {
|
|
82
|
+
this.dispatchEvent(new HelixStopEvent());
|
|
83
|
+
};
|
|
45
84
|
this.handleKey = (event) => {
|
|
46
85
|
if (event.key !== 'Enter' || this.submitOn !== 'enter') {
|
|
47
86
|
return;
|
|
@@ -77,7 +116,7 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
77
116
|
send() {
|
|
78
117
|
this.stopListening();
|
|
79
118
|
const value = this.value.trim();
|
|
80
|
-
if (this.isDisabled) {
|
|
119
|
+
if (this.isDisabled || this.sendDisabled || (this.busy && !this.queue)) {
|
|
81
120
|
return false;
|
|
82
121
|
}
|
|
83
122
|
if (value === '') {
|
|
@@ -116,12 +155,154 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
116
155
|
this.value = typeof state === 'string' ? state : this.declared;
|
|
117
156
|
}
|
|
118
157
|
markEmpty() {
|
|
119
|
-
for (const name of ['start', 'end']) {
|
|
158
|
+
for (const name of ['attachments', 'start', 'end']) {
|
|
120
159
|
markRegion(this.renderRoot, name, [name]);
|
|
121
160
|
}
|
|
122
161
|
}
|
|
162
|
+
get idling() {
|
|
163
|
+
return (this.knownChildren.some((child) => child.getAttribute('slot') === 'idle') &&
|
|
164
|
+
!this.busy &&
|
|
165
|
+
!this.attached &&
|
|
166
|
+
this.value.trim() === '');
|
|
167
|
+
}
|
|
168
|
+
get carrying() {
|
|
169
|
+
return this.knownChildren.some((child) => child.getAttribute('slot') === 'attachments');
|
|
170
|
+
}
|
|
171
|
+
noteFocus() {
|
|
172
|
+
if (!this.hasUpdated) {
|
|
173
|
+
this.focusedOn = 'elsewhere';
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const active = deepActiveElement();
|
|
177
|
+
const send = this.partNamed('send');
|
|
178
|
+
const idle = this.renderRoot
|
|
179
|
+
?.querySelector('slot[name="idle"]')
|
|
180
|
+
?.assignedElements({ flatten: true });
|
|
181
|
+
this.focusedOn =
|
|
182
|
+
active !== null && active === send
|
|
183
|
+
? 'send'
|
|
184
|
+
: active !== null && idle?.some((element) => element === active || element.contains(active))
|
|
185
|
+
? 'idle'
|
|
186
|
+
: 'elsewhere';
|
|
187
|
+
}
|
|
188
|
+
keepFocus() {
|
|
189
|
+
if (this.focusedOn === 'send' && this.idling) {
|
|
190
|
+
const idle = this.renderRoot
|
|
191
|
+
?.querySelector('slot[name="idle"]')
|
|
192
|
+
?.assignedElements({ flatten: true })[0];
|
|
193
|
+
idle?.focus();
|
|
194
|
+
}
|
|
195
|
+
else if (this.focusedOn === 'idle' && !this.idling) {
|
|
196
|
+
this.partNamed('send')?.focus();
|
|
197
|
+
}
|
|
198
|
+
this.focusedOn = 'elsewhere';
|
|
199
|
+
}
|
|
200
|
+
connectedCallback() {
|
|
201
|
+
super.connectedCallback();
|
|
202
|
+
this.unmoved ??= onMotionChange(() => this.turnExamples());
|
|
203
|
+
if (typeof IntersectionObserver === 'function' && this.sight === undefined) {
|
|
204
|
+
this.sight = new IntersectionObserver((entries) => {
|
|
205
|
+
const seen = entries.at(-1)?.isIntersecting ?? this.onScreen;
|
|
206
|
+
if (seen !== this.onScreen) {
|
|
207
|
+
this.onScreen = seen;
|
|
208
|
+
this.turnExamples();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
this.sight.observe(this);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
disconnectedCallback() {
|
|
215
|
+
super.disconnectedCallback();
|
|
216
|
+
this.unmoved?.();
|
|
217
|
+
this.unmoved = undefined;
|
|
218
|
+
this.sight?.disconnect();
|
|
219
|
+
this.sight = undefined;
|
|
220
|
+
this.onScreen = true;
|
|
221
|
+
this.stopExamples();
|
|
222
|
+
}
|
|
223
|
+
renderExamples() {
|
|
224
|
+
const { length } = this.placeholders;
|
|
225
|
+
const at = (index) => ({ index, text: this.placeholders[index % length] ?? '' });
|
|
226
|
+
const leaving = this.leavingExample;
|
|
227
|
+
return this.renderExample(at(this.example), leaving === undefined ? undefined : at(leaving));
|
|
228
|
+
}
|
|
229
|
+
get shownPlaceholder() {
|
|
230
|
+
const { length } = this.placeholders;
|
|
231
|
+
return length > 0 ? (this.placeholders[this.example % length] ?? '') : this.placeholder;
|
|
232
|
+
}
|
|
233
|
+
turnExamples() {
|
|
234
|
+
const free = this.isConnected &&
|
|
235
|
+
this.placeholders.length > 1 &&
|
|
236
|
+
this.value === '' &&
|
|
237
|
+
this.onScreen &&
|
|
238
|
+
!reducedMotion() &&
|
|
239
|
+
!motionPaused();
|
|
240
|
+
if (!free) {
|
|
241
|
+
this.stopExamples();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (this.focused) {
|
|
245
|
+
clearTimeout(this.turning);
|
|
246
|
+
this.turning = undefined;
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (this.turning === undefined && this.crossing === undefined && this.leaving === undefined) {
|
|
250
|
+
this.turning = setTimeout(() => this.leaveExample(), exampleShown(this.shownPlaceholder));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
leaveExample() {
|
|
254
|
+
this.turning = undefined;
|
|
255
|
+
if (reducedMotion() || motionPaused()) {
|
|
256
|
+
this.stopExamples();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
clearTimeout(this.entering);
|
|
260
|
+
this.entering = undefined;
|
|
261
|
+
this.toggleState('example-entering', false);
|
|
262
|
+
this.toggleState('example-leaving', true);
|
|
263
|
+
this.leavingExample = this.example;
|
|
264
|
+
this.crossing = setTimeout(() => this.arriveExample(), EXAMPLE_CROSS);
|
|
265
|
+
this.leaving = setTimeout(() => {
|
|
266
|
+
this.leaving = undefined;
|
|
267
|
+
this.leavingExample = undefined;
|
|
268
|
+
this.toggleState('example-leaving', false);
|
|
269
|
+
}, EXAMPLE_LEAVE);
|
|
270
|
+
}
|
|
271
|
+
arriveExample() {
|
|
272
|
+
this.crossing = undefined;
|
|
273
|
+
this.example = (this.example + 1) % Math.max(this.placeholders.length, 1);
|
|
274
|
+
this.toggleState('example-entering', true);
|
|
275
|
+
this.entering = setTimeout(() => {
|
|
276
|
+
this.entering = undefined;
|
|
277
|
+
this.toggleState('example-entering', false);
|
|
278
|
+
this.exampleLanded();
|
|
279
|
+
}, EXAMPLE_ENTER);
|
|
280
|
+
this.turnExamples();
|
|
281
|
+
}
|
|
282
|
+
stopExamples() {
|
|
283
|
+
clearTimeout(this.turning);
|
|
284
|
+
clearTimeout(this.crossing);
|
|
285
|
+
clearTimeout(this.leaving);
|
|
286
|
+
clearTimeout(this.entering);
|
|
287
|
+
this.turning = undefined;
|
|
288
|
+
this.crossing = undefined;
|
|
289
|
+
this.leaving = undefined;
|
|
290
|
+
this.entering = undefined;
|
|
291
|
+
this.leavingExample = undefined;
|
|
292
|
+
this.toggleState('example-leaving', false);
|
|
293
|
+
this.toggleState('example-entering', false);
|
|
294
|
+
this.exampleLanded();
|
|
295
|
+
}
|
|
296
|
+
exampleLanded() { }
|
|
297
|
+
renderExample(_example, _leaving) {
|
|
298
|
+
return nothing;
|
|
299
|
+
}
|
|
123
300
|
updated(changed) {
|
|
124
301
|
super.updated(changed);
|
|
302
|
+
this.keepFocus();
|
|
303
|
+
if (changed.has('placeholders') || changed.has('value')) {
|
|
304
|
+
this.turnExamples();
|
|
305
|
+
}
|
|
125
306
|
this.markEmpty();
|
|
126
307
|
if (changed.has('value')) {
|
|
127
308
|
this.internals.setFormValue(this.value, this.value);
|
|
@@ -139,6 +320,7 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
139
320
|
}
|
|
140
321
|
firstUpdated(changed) {
|
|
141
322
|
super.firstUpdated(changed);
|
|
323
|
+
this.finishHydration();
|
|
142
324
|
this.addEventListener('invalid', () => {
|
|
143
325
|
if (!this.checkingValidity) {
|
|
144
326
|
this.touch();
|
|
@@ -148,32 +330,42 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
148
330
|
willUpdate(changed) {
|
|
149
331
|
super.willUpdate(changed);
|
|
150
332
|
hostAria(this.internals, { label: this.label, role: 'group' });
|
|
333
|
+
this.noteFocus();
|
|
151
334
|
}
|
|
152
335
|
renderSend() {
|
|
153
|
-
|
|
336
|
+
const mark = this.busy ? stop : arrowElbowDownLeft;
|
|
337
|
+
const held = this.sendDisabled && !this.busy;
|
|
338
|
+
const reasoned = held && !this.isDisabled && this.sendReason !== '';
|
|
339
|
+
const control = html `<button
|
|
154
340
|
part="send"
|
|
155
341
|
type="button"
|
|
156
|
-
aria-label=${this.sendLabel}
|
|
157
|
-
|
|
158
|
-
|
|
342
|
+
aria-label=${this.busy ? this.stopLabel : this.sendLabel}
|
|
343
|
+
aria-disabled=${reasoned ? 'true' : nothing}
|
|
344
|
+
aria-describedby=${reasoned ? 'send-reason' : nothing}
|
|
345
|
+
?disabled=${this.isDisabled || (held && !reasoned)}
|
|
346
|
+
@click=${this.busy ? this.handleStop : this.handleSend}
|
|
159
347
|
>
|
|
160
|
-
<svg
|
|
161
|
-
|
|
162
|
-
fill="currentColor"
|
|
163
|
-
viewBox=${arrowElbowDownLeft.viewBox}
|
|
164
|
-
aria-hidden="true"
|
|
165
|
-
>
|
|
166
|
-
${unsafeSVG(arrowElbowDownLeft.content)}
|
|
348
|
+
<svg part="mark" fill="currentColor" viewBox=${mark.viewBox} aria-hidden="true">
|
|
349
|
+
${unsafeSVG(mark.content)}
|
|
167
350
|
</svg>
|
|
168
351
|
</button>`;
|
|
352
|
+
if (!reasoned) {
|
|
353
|
+
return control;
|
|
354
|
+
}
|
|
355
|
+
return staticHtml `<${this.tag('tooltip')} id="send-reason" content=${this.sendReason}
|
|
356
|
+
exportparts="arrow: reason-arrow, arrow-bottom: reason-arrow-bottom, arrow-left: reason-arrow-left, arrow-right: reason-arrow-right, arrow-top: reason-arrow-top, surface: reason-surface, surface-bottom: reason-surface-bottom, surface-left: reason-surface-left, surface-right: reason-surface-right, surface-top: reason-surface-top"
|
|
357
|
+
>${control}</${this.tag('tooltip')}>`;
|
|
169
358
|
}
|
|
170
359
|
render() {
|
|
171
360
|
return html `<div part="composer">
|
|
361
|
+
<div part="attachments" ?hidden=${!this.carrying} @mousedown=${this.handleAttachmentsDown}
|
|
362
|
+
><slot name="attachments" @slotchange=${() => this.markEmpty()}></slot
|
|
363
|
+
></div>
|
|
172
364
|
<textarea
|
|
173
365
|
part="field"
|
|
174
366
|
.value=${live(this.value)}
|
|
175
367
|
aria-label=${this.label}
|
|
176
|
-
placeholder=${this.
|
|
368
|
+
placeholder=${this.shownPlaceholder}
|
|
177
369
|
rows=${this.rows}
|
|
178
370
|
?required=${this.required}
|
|
179
371
|
minlength=${this.minLength ?? nothing}
|
|
@@ -181,20 +373,36 @@ let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends MixinVoi
|
|
|
181
373
|
aria-invalid=${this.shownInvalid ? 'true' : nothing}
|
|
182
374
|
aria-describedby=${this.feedback === '' ? nothing : 'feedback'}
|
|
183
375
|
?disabled=${this.isDisabled}
|
|
376
|
+
@blur=${this.handleFocus}
|
|
184
377
|
@change=${this.handleChange}
|
|
378
|
+
@focus=${this.handleFocus}
|
|
185
379
|
@input=${this.handleInput}
|
|
186
380
|
@keydown=${this.handleKey}
|
|
187
381
|
></textarea>
|
|
382
|
+
${this.placeholders.length > 1 ? this.renderExamples() : nothing}
|
|
188
383
|
<div part="tools">
|
|
189
|
-
<span part="start"><slot name="start"></slot></span>
|
|
190
|
-
<span part="end"><slot name="end"></slot></span>
|
|
191
|
-
${this.renderVoice()}
|
|
384
|
+
<span part="start"><slot name="start" @slotchange=${() => this.markEmpty()}></slot></span>
|
|
385
|
+
<span part="end"><slot name="end" @slotchange=${() => this.markEmpty()}></slot></span>
|
|
386
|
+
${this.renderVoice()}
|
|
387
|
+
<span part="idle" ?hidden=${!this.idling}
|
|
388
|
+
><slot
|
|
389
|
+
name="idle"
|
|
390
|
+
@slotchange=${() => this.requestUpdate()}
|
|
391
|
+
></slot
|
|
392
|
+
></span>
|
|
393
|
+
${this.idling ? nothing : this.renderSend()}
|
|
192
394
|
</div>
|
|
193
395
|
</div>${this.feedback === ''
|
|
194
396
|
? nothing
|
|
195
397
|
: html `<p part="feedback" id="feedback" role="alert">${this.feedback}</p>`}`;
|
|
196
398
|
}
|
|
197
399
|
};
|
|
400
|
+
__decorate([
|
|
401
|
+
property({ reflect: true, type: Boolean })
|
|
402
|
+
], HelixHeadlessChatComposer.prototype, "attached", void 0);
|
|
403
|
+
__decorate([
|
|
404
|
+
property({ reflect: true, type: Boolean })
|
|
405
|
+
], HelixHeadlessChatComposer.prototype, "busy", void 0);
|
|
198
406
|
__decorate([
|
|
199
407
|
property()
|
|
200
408
|
], HelixHeadlessChatComposer.prototype, "feedback", void 0);
|
|
@@ -211,16 +419,32 @@ __decorate([
|
|
|
211
419
|
__decorate([
|
|
212
420
|
property()
|
|
213
421
|
], HelixHeadlessChatComposer.prototype, "placeholder", void 0);
|
|
422
|
+
__decorate([
|
|
423
|
+
property({ attribute: false })
|
|
424
|
+
], HelixHeadlessChatComposer.prototype, "placeholders", void 0);
|
|
425
|
+
__decorate([
|
|
426
|
+
property({ reflect: true, type: Boolean })
|
|
427
|
+
], HelixHeadlessChatComposer.prototype, "queue", void 0);
|
|
214
428
|
__decorate([
|
|
215
429
|
property({ type: Boolean })
|
|
216
430
|
], HelixHeadlessChatComposer.prototype, "required", void 0);
|
|
217
431
|
__decorate([
|
|
218
432
|
property({ converter: numberConverter('rows', 1) })
|
|
219
433
|
], HelixHeadlessChatComposer.prototype, "rows", void 0);
|
|
434
|
+
__decorate([
|
|
435
|
+
property({ attribute: 'send-disabled', type: Boolean })
|
|
436
|
+
], HelixHeadlessChatComposer.prototype, "sendDisabled", void 0);
|
|
220
437
|
__decorate([
|
|
221
438
|
words,
|
|
222
439
|
property({ attribute: 'send-label' })
|
|
223
440
|
], HelixHeadlessChatComposer.prototype, "sendLabel", void 0);
|
|
441
|
+
__decorate([
|
|
442
|
+
property({ attribute: 'send-reason' })
|
|
443
|
+
], HelixHeadlessChatComposer.prototype, "sendReason", void 0);
|
|
444
|
+
__decorate([
|
|
445
|
+
words,
|
|
446
|
+
property({ attribute: 'stop-label' })
|
|
447
|
+
], HelixHeadlessChatComposer.prototype, "stopLabel", void 0);
|
|
224
448
|
__decorate([
|
|
225
449
|
property({ attribute: 'submit-on' })
|
|
226
450
|
], HelixHeadlessChatComposer.prototype, "submitOn", void 0);
|
|
@@ -233,6 +457,12 @@ __decorate([
|
|
|
233
457
|
__decorate([
|
|
234
458
|
state()
|
|
235
459
|
], HelixHeadlessChatComposer.prototype, "shownInvalid", void 0);
|
|
460
|
+
__decorate([
|
|
461
|
+
state()
|
|
462
|
+
], HelixHeadlessChatComposer.prototype, "example", void 0);
|
|
463
|
+
__decorate([
|
|
464
|
+
state()
|
|
465
|
+
], HelixHeadlessChatComposer.prototype, "leavingExample", void 0);
|
|
236
466
|
HelixHeadlessChatComposer = __decorate([
|
|
237
467
|
customElement('helix-headless-chat-composer')
|
|
238
468
|
], HelixHeadlessChatComposer);
|
|
@@ -26,6 +26,11 @@ export declare const FAILED_LABEL = "Not sent";
|
|
|
26
26
|
* a page in another language sets them once there. The time moves on by
|
|
27
27
|
* itself, so "now" becomes "1 minute ago" while the page is open.
|
|
28
28
|
*
|
|
29
|
+
* **What a turn carries goes in `attachments`**, above the bubble rather
|
|
30
|
+
* in it: a picture inside a tinted bubble is framed twice, and one sent with
|
|
31
|
+
* no words is an empty bubble around it. It sits against the same edge as the
|
|
32
|
+
* turn, and the words keep their bubble under it.
|
|
33
|
+
*
|
|
29
34
|
* **An agent's work goes in `work`, and its answer in the content.** The work,
|
|
30
35
|
* its thinking, the commands it ran and what they printed, is a record read
|
|
31
36
|
* the way a log is, so a `Log` with `separation="plain"` and `quiet` sits there
|
|
@@ -40,6 +45,7 @@ export declare const FAILED_LABEL = "Not sent";
|
|
|
40
45
|
*
|
|
41
46
|
* @slot - The turn's content.
|
|
42
47
|
* @slot actions - Controls for the turn, such as copy, retry, or react.
|
|
48
|
+
* @slot attachments - What the turn carries, such as images or files, above its content and outside the bubble, against the author's edge.
|
|
43
49
|
* @slot avatar - The author's avatar.
|
|
44
50
|
* @slot indicator - The indicator shown before the first token arrives.
|
|
45
51
|
* Defaults to the typing indicator.
|
|
@@ -49,6 +55,7 @@ export declare const FAILED_LABEL = "Not sent";
|
|
|
49
55
|
* @event {HelixSendEvent} helix-send - Fired when the user retries a failed message. Cancelable: if it is not canceled, the turn is sent again. Canceling it leaves the failure and the retry button as they were.
|
|
50
56
|
*
|
|
51
57
|
* @csspart actions - The controls on the turn, beside its time.
|
|
58
|
+
* @csspart attachments - The box around the `attachments` slot, above the content and outside the bubble.
|
|
52
59
|
* @csspart avatar - The box around the `avatar` slot.
|
|
53
60
|
* @csspart body - The content and the line under it.
|
|
54
61
|
* @csspart content - Your own markup.
|
|
@@ -108,7 +108,7 @@ let HelixHeadlessChatMessage = class HelixHeadlessChatMessage extends HelixEleme
|
|
|
108
108
|
}
|
|
109
109
|
markEmpty() {
|
|
110
110
|
markRegion(this.renderRoot, 'content', [''], { hide: false });
|
|
111
|
-
for (const name of ['work', 'sources', 'actions']) {
|
|
111
|
+
for (const name of ['work', 'attachments', 'sources', 'actions']) {
|
|
112
112
|
markRegion(this.renderRoot, name, [name]);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -121,6 +121,7 @@ let HelixHeadlessChatMessage = class HelixHeadlessChatMessage extends HelixEleme
|
|
|
121
121
|
<span part="avatar"><slot name="avatar"></slot></span>
|
|
122
122
|
<div part="body">
|
|
123
123
|
<div part="work"><slot name="work" @slotchange=${this.handleFill}></slot></div>
|
|
124
|
+
<div part="attachments"><slot name="attachments" @slotchange=${this.handleFill}></slot></div>
|
|
124
125
|
<div part="content">
|
|
125
126
|
<slot @slotchange=${this.handleFill}></slot>
|
|
126
127
|
${this.renderIndicator()}
|
|
@@ -138,6 +138,7 @@ declare const HelixHeadlessChat_base: (new (...args: any[]) => import("@fusion.d
|
|
|
138
138
|
* @csspart log - The transcript, which scrolls. On this tier, it needs only a block size.
|
|
139
139
|
* @csspart message - The message drawn for a turn from `turns`, forwarded whole.
|
|
140
140
|
* @csspart message-actions - The controls on a turn from `turns`, beside its time.
|
|
141
|
+
* @csspart message-attachments - The attachments above the bubble of a turn from `turns`.
|
|
141
142
|
* @csspart message-avatar - The avatar box of a turn from `turns`.
|
|
142
143
|
* @csspart message-avatar-mine - The avatar box of a turn from `turns` by `me`.
|
|
143
144
|
* @csspart message-body - The content of a turn from `turns`, and the line under it.
|
|
@@ -705,7 +705,7 @@ let HelixHeadlessChat = class HelixHeadlessChat extends MixinCollection(HelixEle
|
|
|
705
705
|
return html `<div part="before" role="presentation" style="block-size: ${before}px; flex: none"></div>
|
|
706
706
|
${repeat(this.turns.slice(first, last), (turn, offset) => turn.key ?? first + offset, (turn, offset) => html `<div part="turn" data-index=${first + offset}>
|
|
707
707
|
<${message}
|
|
708
|
-
exportparts="actions: message-actions, avatar: message-avatar, body: message-body,
|
|
708
|
+
exportparts="actions: message-actions, attachments: message-attachments, avatar: message-avatar, body: message-body,
|
|
709
709
|
content: message-content, indicator: message-indicator, mark: message-mark, message,
|
|
710
710
|
meta: message-meta, retry: message-retry, sources: message-sources,
|
|
711
711
|
state: message-state, time: message-time, work: message-work${secondNames(SECOND_NAMES.author, turn.author)}${secondNames(SECOND_NAMES.state, turn.state)}"
|
|
@@ -24,7 +24,7 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
24
24
|
this.showedResult = false;
|
|
25
25
|
this.clipboard = new CopyController(this, { after: () => this.feedbackDuration });
|
|
26
26
|
this.handleCopy = async (event) => {
|
|
27
|
-
if (this.
|
|
27
|
+
if (this.refusesPress) {
|
|
28
28
|
event.preventDefault();
|
|
29
29
|
event.stopImmediatePropagation();
|
|
30
30
|
return;
|
|
@@ -100,12 +100,12 @@ let HelixHeadlessCopyButton = class HelixHeadlessCopyButton extends HelixHeadles
|
|
|
100
100
|
part="button"
|
|
101
101
|
type="button"
|
|
102
102
|
aria-busy=${this.pending ? 'true' : nothing}
|
|
103
|
-
aria-disabled=${this.
|
|
103
|
+
aria-disabled=${this.refusesPress ? 'true' : nothing}
|
|
104
104
|
aria-label=${this.says}
|
|
105
105
|
data-copied=${this.copied ? '' : nothing}
|
|
106
106
|
data-failed=${this.failed ? '' : nothing}
|
|
107
107
|
tabindex=${this.focusable ? nothing : '-1'}
|
|
108
|
-
?disabled=${this.isDisabled}
|
|
108
|
+
?disabled=${this.isDisabled && !this.heldDisabled}
|
|
109
109
|
@click=${this.handleCopy}
|
|
110
110
|
@keydown=${this.notePress}
|
|
111
111
|
@pointerdown=${this.notePress}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChildrenController, type DeviceButton, HelixElement, ToolbarController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../icon-button/index.js';
|
|
4
|
+
import '../../tooltip/index.js';
|
|
4
5
|
/**
|
|
5
6
|
* @summary A device's screen, drawn from a stream you supply, that sends taps, swipes, keys, and button presses back to the device.
|
|
6
7
|
*
|
|
@@ -143,6 +144,16 @@ import '../../icon-button/index.js';
|
|
|
143
144
|
* @csspart screenshot-live - The screenshot button's live region, which speaks while the button is pending.
|
|
144
145
|
* @csspart screenshot-spinner - The ring the screenshot button turns while it is pending.
|
|
145
146
|
* @csspart screenshot-text - The box the screenshot button's icon sits in.
|
|
147
|
+
* @csspart tooltip-arrow - The arrow of the tooltip that names each button, forwarded from `Tooltip`.
|
|
148
|
+
* @csspart tooltip-arrow-bottom - The arrow while the bubble is below its button, on the bubble's top edge. Set together with `tooltip-arrow`.
|
|
149
|
+
* @csspart tooltip-arrow-left - The arrow while the bubble is left of its button, on the bubble's right edge. Set together with `tooltip-arrow`.
|
|
150
|
+
* @csspart tooltip-arrow-right - The arrow while the bubble is right of its button, on the bubble's left edge. Set together with `tooltip-arrow`.
|
|
151
|
+
* @csspart tooltip-arrow-top - The arrow while the bubble is above its button, on the bubble's bottom edge. Set together with `tooltip-arrow`.
|
|
152
|
+
* @csspart tooltip-surface - The bubble of the tooltip that names each button, forwarded from `Tooltip`.
|
|
153
|
+
* @csspart tooltip-surface-bottom - The bubble while it is below its button. Set together with `tooltip-surface`.
|
|
154
|
+
* @csspart tooltip-surface-left - The bubble while it is left of its button. Set together with `tooltip-surface`.
|
|
155
|
+
* @csspart tooltip-surface-right - The bubble while it is right of its button. Set together with `tooltip-surface`.
|
|
156
|
+
* @csspart tooltip-surface-top - The bubble while it is above its button. Set together with `tooltip-surface`.
|
|
146
157
|
* @csspart touch - A ring where a touch is or was.
|
|
147
158
|
* @csspart touch-held - A ring under a finger that is down, beside `touch`, with `show-touches`.
|
|
148
159
|
* @csspart volume-down - The Volume down button.
|
|
@@ -6,6 +6,7 @@ import { property, state } from 'lit/decorators.js';
|
|
|
6
6
|
import { repeat } from 'lit/directives/repeat.js';
|
|
7
7
|
import { html } from 'lit/static-html.js';
|
|
8
8
|
import '../../icon-button/index.js';
|
|
9
|
+
import '../../tooltip/index.js';
|
|
9
10
|
import { gestureOf } from '../gesture.js';
|
|
10
11
|
import { quarterTurns, turn, unturn, unturnDistance } from '../turn.js';
|
|
11
12
|
const MARK_SHOWS = 700;
|
|
@@ -546,6 +547,7 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
546
547
|
return nothing;
|
|
547
548
|
}
|
|
548
549
|
const button = this.tag('icon-button');
|
|
550
|
+
const tip = this.tag('tooltip');
|
|
549
551
|
const off = this.readonly;
|
|
550
552
|
const raised = this.controlsRaised;
|
|
551
553
|
return html `<div
|
|
@@ -557,6 +559,7 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
557
559
|
${this.draws('back')
|
|
558
560
|
? html `<${button}
|
|
559
561
|
part="back"
|
|
562
|
+
id="back"
|
|
560
563
|
exportparts="button: back-button, live: back-live, spinner: back-spinner, text: back-text"
|
|
561
564
|
?disabled=${off}
|
|
562
565
|
label=${this.backLabel}
|
|
@@ -566,11 +569,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
566
569
|
@pointerdown=${this.handleHoldStart}
|
|
567
570
|
>
|
|
568
571
|
<slot name="back-icon">${drawIcon(caretLeft)}</slot>
|
|
569
|
-
</${button}>`
|
|
572
|
+
</${button}><${tip} for="back" content=${this.backLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
570
573
|
: nothing}
|
|
571
574
|
${this.draws('home')
|
|
572
575
|
? html `<${button}
|
|
573
576
|
part="home"
|
|
577
|
+
id="home"
|
|
574
578
|
exportparts="button: home-button, live: home-live, spinner: home-spinner, text: home-text"
|
|
575
579
|
?disabled=${off}
|
|
576
580
|
label=${this.homeLabel}
|
|
@@ -580,11 +584,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
580
584
|
@pointerdown=${this.handleHoldStart}
|
|
581
585
|
>
|
|
582
586
|
<slot name="home-icon">${drawIcon(house)}</slot>
|
|
583
|
-
</${button}>`
|
|
587
|
+
</${button}><${tip} for="home" content=${this.homeLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
584
588
|
: nothing}
|
|
585
589
|
${this.draws('recents')
|
|
586
590
|
? html `<${button}
|
|
587
591
|
part="recents"
|
|
592
|
+
id="recents"
|
|
588
593
|
exportparts="button: recents-button, live: recents-live, spinner: recents-spinner, text: recents-text"
|
|
589
594
|
?disabled=${off}
|
|
590
595
|
label=${this.recentsLabel}
|
|
@@ -594,11 +599,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
594
599
|
@pointerdown=${this.handleHoldStart}
|
|
595
600
|
>
|
|
596
601
|
<slot name="recents-icon">${drawIcon(square)}</slot>
|
|
597
|
-
</${button}>`
|
|
602
|
+
</${button}><${tip} for="recents" content=${this.recentsLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
598
603
|
: nothing}
|
|
599
604
|
${this.draws('power')
|
|
600
605
|
? html `<${button}
|
|
601
606
|
part="power"
|
|
607
|
+
id="power"
|
|
602
608
|
exportparts="button: power-button, live: power-live, spinner: power-spinner, text: power-text"
|
|
603
609
|
?disabled=${off}
|
|
604
610
|
label=${this.powerLabel}
|
|
@@ -608,11 +614,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
608
614
|
@pointerdown=${this.handleHoldStart}
|
|
609
615
|
>
|
|
610
616
|
<slot name="power-icon">${drawIcon(power)}</slot>
|
|
611
|
-
</${button}>`
|
|
617
|
+
</${button}><${tip} for="power" content=${this.powerLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
612
618
|
: nothing}
|
|
613
619
|
${this.draws('volume')
|
|
614
620
|
? html `<${button}
|
|
615
621
|
part="volume-up"
|
|
622
|
+
id="volume-up"
|
|
616
623
|
exportparts="button: volume-up-button, live: volume-up-live, spinner: volume-up-spinner, text: volume-up-text"
|
|
617
624
|
?disabled=${off}
|
|
618
625
|
label=${this.volumeUpLabel}
|
|
@@ -622,9 +629,10 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
622
629
|
@pointerdown=${this.handleHoldStart}
|
|
623
630
|
>
|
|
624
631
|
<slot name="volume-up-icon">${drawIcon(speakerHigh)}</slot>
|
|
625
|
-
</${button}>
|
|
632
|
+
</${button}><${tip} for="volume-up" content=${this.volumeUpLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
|
|
626
633
|
<${button}
|
|
627
634
|
part="volume-down"
|
|
635
|
+
id="volume-down"
|
|
628
636
|
exportparts="button: volume-down-button, live: volume-down-live, spinner: volume-down-spinner, text: volume-down-text"
|
|
629
637
|
?disabled=${off}
|
|
630
638
|
label=${this.volumeDownLabel}
|
|
@@ -634,11 +642,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
634
642
|
@pointerdown=${this.handleHoldStart}
|
|
635
643
|
>
|
|
636
644
|
<slot name="volume-down-icon">${drawIcon(speakerLow)}</slot>
|
|
637
|
-
</${button}>`
|
|
645
|
+
</${button}><${tip} for="volume-down" content=${this.volumeDownLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
638
646
|
: nothing}
|
|
639
647
|
${this.draws('rotate')
|
|
640
648
|
? html `<${button}
|
|
641
649
|
part="rotate-left"
|
|
650
|
+
id="rotate-left"
|
|
642
651
|
exportparts="button: rotate-left-button, live: rotate-left-live, spinner: rotate-left-spinner, text: rotate-left-text"
|
|
643
652
|
?disabled=${off}
|
|
644
653
|
label=${this.rotateLeftLabel}
|
|
@@ -648,9 +657,10 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
648
657
|
@pointerdown=${this.handleHoldStart}
|
|
649
658
|
>
|
|
650
659
|
<slot name="rotate-left-icon">${drawIcon(arrowCounterClockwise)}</slot>
|
|
651
|
-
</${button}>
|
|
660
|
+
</${button}><${tip} for="rotate-left" content=${this.rotateLeftLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
|
|
652
661
|
<${button}
|
|
653
662
|
part="rotate-right"
|
|
663
|
+
id="rotate-right"
|
|
654
664
|
exportparts="button: rotate-right-button, live: rotate-right-live, spinner: rotate-right-spinner, text: rotate-right-text"
|
|
655
665
|
?disabled=${off}
|
|
656
666
|
label=${this.rotateRightLabel}
|
|
@@ -660,11 +670,12 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
660
670
|
@pointerdown=${this.handleHoldStart}
|
|
661
671
|
>
|
|
662
672
|
<slot name="rotate-right-icon">${drawIcon(arrowClockwise)}</slot>
|
|
663
|
-
</${button}>`
|
|
673
|
+
</${button}><${tip} for="rotate-right" content=${this.rotateRightLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
664
674
|
: nothing}
|
|
665
675
|
${this.draws('screenshot')
|
|
666
676
|
? html `<${button}
|
|
667
677
|
part="screenshot"
|
|
678
|
+
id="screenshot"
|
|
668
679
|
exportparts="button: screenshot-button, live: screenshot-live, spinner: screenshot-spinner, text: screenshot-text"
|
|
669
680
|
label=${this.screenshotLabel}
|
|
670
681
|
?raised=${raised}
|
|
@@ -672,12 +683,13 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
672
683
|
@helix-press=${stopPress}
|
|
673
684
|
>
|
|
674
685
|
<slot name="screenshot-icon">${drawIcon(camera)}</slot>
|
|
675
|
-
</${button}>`
|
|
686
|
+
</${button}><${tip} for="screenshot" content=${this.screenshotLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
676
687
|
: nothing}
|
|
677
688
|
<slot name="controls" @slotchange=${this.handleSlotChange}></slot>
|
|
678
689
|
${this.draws('fullscreen')
|
|
679
690
|
? html `<${button}
|
|
680
691
|
part="fullscreen"
|
|
692
|
+
id="fullscreen"
|
|
681
693
|
exportparts="button: fullscreen-button, live: fullscreen-live, spinner: fullscreen-spinner, text: fullscreen-text"
|
|
682
694
|
aria-pressed=${this.filled ? 'true' : 'false'}
|
|
683
695
|
label=${this.fullscreenLabel}
|
|
@@ -686,7 +698,7 @@ let HelixHeadlessDeviceScreen = class HelixHeadlessDeviceScreen extends HelixEle
|
|
|
686
698
|
@helix-press=${stopPress}
|
|
687
699
|
>
|
|
688
700
|
<slot name="fullscreen-icon">${drawIcon(cornersOut)}</slot>
|
|
689
|
-
</${button}>`
|
|
701
|
+
</${button}><${tip} for="fullscreen" content=${this.fullscreenLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
|
|
690
702
|
: nothing}
|
|
691
703
|
</div>`;
|
|
692
704
|
}
|