@fusion.dev/helix-headless 0.218.0 → 0.220.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/code-editor/root/code-editor-root.d.ts +48 -51
- package/dist/code-editor/root/code-editor-root.js +67 -249
- 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 +4 -1
- 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/find/index.d.ts +1 -0
- package/dist/find/index.js +1 -0
- package/dist/find/root/find-root.d.ts +314 -0
- package/dist/find/root/find-root.js +577 -0
- package/dist/graph/root/graph-root.d.ts +11 -0
- package/dist/graph/root/graph-root.js +4 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- 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 +18 -3
- package/dist/log/group/log-group.js +31 -4
- 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 +60 -32
- package/dist/terminal/root/terminal-root.js +82 -178
- 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/dist/tree/item/tree-item.d.ts +11 -0
- package/dist/tree/item/tree-item.js +19 -1
- package/examples.json +1 -1
- package/lint.json +1 -1
- package/package.json +5 -5
- package/types/jsx.d.ts +2222 -118
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +468 -19
- package/types/words.d.ts +96 -1
|
@@ -4,21 +4,13 @@ import { arrowClockwise, asterisk, broom, caretDown, caretUp, copy, cornersOut,
|
|
|
4
4
|
import { nothing } from 'lit';
|
|
5
5
|
import { property, state } from 'lit/decorators.js';
|
|
6
6
|
import { keyed } from 'lit/directives/keyed.js';
|
|
7
|
-
import { live } from 'lit/directives/live.js';
|
|
8
7
|
import { html } from 'lit/static-html.js';
|
|
9
8
|
import '../../button/index.js';
|
|
9
|
+
import '../../find/index.js';
|
|
10
10
|
import '../../icon-button/index.js';
|
|
11
|
+
import '../../tooltip/index.js';
|
|
11
12
|
import '../../toolbar/index.js';
|
|
12
13
|
import { isTab, shortcutOf, spokenChord } from '../keys.js';
|
|
13
|
-
const readable = (source) => {
|
|
14
|
-
try {
|
|
15
|
-
new RegExp(source);
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
14
|
const ANSI = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
|
|
23
15
|
const camel = (name) => name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
24
16
|
const unset = (color) => color === '' || color === 'transparent' || /^rgba\(\s*0,\s*0,\s*0,\s*0\s*\)$/.test(color);
|
|
@@ -57,10 +49,6 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
57
49
|
this.tabMovesFocusLabel = 'Tab moves focus. Press {key} to type Tab in the terminal.';
|
|
58
50
|
this.tabTypesLabel = 'Tab types in the terminal.';
|
|
59
51
|
this.findOpen = false;
|
|
60
|
-
this.query = '';
|
|
61
|
-
this.matchIndex = -1;
|
|
62
|
-
this.matchCount = undefined;
|
|
63
|
-
this.invalid = false;
|
|
64
52
|
this.tabMovesFocus = false;
|
|
65
53
|
this.anySelected = false;
|
|
66
54
|
this.hasActions = false;
|
|
@@ -117,19 +105,33 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
117
105
|
event.stopPropagation();
|
|
118
106
|
}
|
|
119
107
|
};
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
|
|
108
|
+
this.finder = {
|
|
109
|
+
end: () => {
|
|
110
|
+
this.searchedWith = undefined;
|
|
111
|
+
this.renderer?.findEnd?.();
|
|
112
|
+
},
|
|
113
|
+
find: (query, direction) => {
|
|
114
|
+
const options = {
|
|
115
|
+
backward: direction === 'previous',
|
|
116
|
+
caseSensitive: query.caseSensitive,
|
|
117
|
+
incremental: direction === 'first',
|
|
118
|
+
regex: query.regex,
|
|
119
|
+
wholeWord: query.wholeWord,
|
|
120
|
+
};
|
|
121
|
+
const searching = `${options.caseSensitive} ${options.regex} ${options.wholeWord}`;
|
|
122
|
+
if (this.searchedWith !== undefined && this.searchedWith !== searching) {
|
|
123
|
+
this.renderer?.findEnd?.();
|
|
124
|
+
}
|
|
125
|
+
this.searchedWith = searching;
|
|
126
|
+
this.findMatchCase = query.caseSensitive;
|
|
127
|
+
this.findRegex = query.regex;
|
|
128
|
+
this.findWholeWord = query.wholeWord;
|
|
129
|
+
this.renderer?.find?.(query.search, options);
|
|
130
|
+
return undefined;
|
|
131
|
+
},
|
|
123
132
|
};
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
event.preventDefault();
|
|
127
|
-
this.closeFind();
|
|
128
|
-
}
|
|
129
|
-
else if (event.key === 'Enter') {
|
|
130
|
-
event.preventDefault();
|
|
131
|
-
this.search(event.shiftKey);
|
|
132
|
-
}
|
|
133
|
+
this.handleFindToggle = (event) => {
|
|
134
|
+
this.findOpen = event.newState === 'open';
|
|
133
135
|
};
|
|
134
136
|
this.handleActions = (event) => {
|
|
135
137
|
this.hasActions = event.target.assignedNodes().length > 0;
|
|
@@ -220,9 +222,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
220
222
|
},
|
|
221
223
|
found: (index, count) => {
|
|
222
224
|
if (current()) {
|
|
223
|
-
this.
|
|
224
|
-
this.matchCount = count;
|
|
225
|
-
this.say(this.countText);
|
|
225
|
+
this.find?.sink.found({ count, index });
|
|
226
226
|
}
|
|
227
227
|
},
|
|
228
228
|
input: (data, binary = false) => {
|
|
@@ -299,17 +299,6 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
299
299
|
? renderer.selection !== undefined
|
|
300
300
|
: renderer.find !== undefined;
|
|
301
301
|
}
|
|
302
|
-
get countText() {
|
|
303
|
-
if (this.invalid) {
|
|
304
|
-
return this.findInvalidLabel;
|
|
305
|
-
}
|
|
306
|
-
return this.matchCount === undefined
|
|
307
|
-
? ''
|
|
308
|
-
: formatWords(this, 'matchesLabel', {
|
|
309
|
-
count: this.matchCount,
|
|
310
|
-
index: Math.max(this.matchIndex, 0) + 1,
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
302
|
get tabKey() {
|
|
314
303
|
return spokenChord('tab-focus', onApple());
|
|
315
304
|
}
|
|
@@ -354,8 +343,9 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
354
343
|
}
|
|
355
344
|
release() {
|
|
356
345
|
this.restoreInput();
|
|
357
|
-
this.
|
|
358
|
-
|
|
346
|
+
if (this.find) {
|
|
347
|
+
this.find.element.open = false;
|
|
348
|
+
}
|
|
359
349
|
this.anySelected = false;
|
|
360
350
|
}
|
|
361
351
|
takes(shortcut) {
|
|
@@ -372,45 +362,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
372
362
|
return true;
|
|
373
363
|
}
|
|
374
364
|
async openFind() {
|
|
375
|
-
this.
|
|
376
|
-
await this.updateComplete;
|
|
377
|
-
const field = this.partNamed('find-field');
|
|
378
|
-
field?.focus();
|
|
379
|
-
field?.select();
|
|
380
|
-
if (this.query !== '') {
|
|
381
|
-
this.search(false, true);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
closeFind() {
|
|
385
|
-
this.findOpen = false;
|
|
386
|
-
this.matchCount = undefined;
|
|
387
|
-
this.matchIndex = -1;
|
|
388
|
-
this.renderer?.findEnd?.();
|
|
389
|
-
this.focus();
|
|
390
|
-
}
|
|
391
|
-
search(backward, incremental = false) {
|
|
392
|
-
if (this.query === '' || (this.findRegex && !readable(this.query))) {
|
|
393
|
-
this.invalid = this.query !== '';
|
|
394
|
-
this.matchCount = undefined;
|
|
395
|
-
this.renderer?.findEnd?.();
|
|
396
|
-
if (this.invalid) {
|
|
397
|
-
this.say(this.findInvalidLabel);
|
|
398
|
-
}
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
this.invalid = false;
|
|
402
|
-
this.renderer?.find?.(this.query, {
|
|
403
|
-
backward,
|
|
404
|
-
caseSensitive: this.findMatchCase,
|
|
405
|
-
incremental,
|
|
406
|
-
regex: this.findRegex,
|
|
407
|
-
wholeWord: this.findWholeWord,
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
toggleOption(option) {
|
|
411
|
-
this[option] = !this[option];
|
|
412
|
-
this.renderer?.findEnd?.();
|
|
413
|
-
this.search(false, true);
|
|
365
|
+
await this.find?.element.show();
|
|
414
366
|
}
|
|
415
367
|
async copySelection() {
|
|
416
368
|
const text = this.renderer?.selection?.() ?? '';
|
|
@@ -441,6 +393,15 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
441
393
|
if (this.renderer && (changed.has('inputLabel') || changed.has('tabHintLabel'))) {
|
|
442
394
|
this.nameInput();
|
|
443
395
|
}
|
|
396
|
+
this.attachFind();
|
|
397
|
+
}
|
|
398
|
+
attachFind() {
|
|
399
|
+
const element = this.partNamed('find') ?? undefined;
|
|
400
|
+
if (element === this.find?.element) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
this.find?.sink.detach();
|
|
404
|
+
this.find = element ? { element, sink: element.attach(this.finder) } : undefined;
|
|
444
405
|
}
|
|
445
406
|
connectedCallback() {
|
|
446
407
|
super.connectedCallback();
|
|
@@ -457,23 +418,26 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
457
418
|
renderControls() {
|
|
458
419
|
const toolbar = this.tag('toolbar');
|
|
459
420
|
const button = this.tag('icon-button');
|
|
421
|
+
const tip = this.tag('tooltip');
|
|
460
422
|
return html `<${toolbar} part="controls" exportparts="toolbar: controls-toolbar" label=${this.controlsLabel}>
|
|
461
423
|
<slot name="actions" part="actions" @slotchange=${this.handleActions}></slot>
|
|
462
424
|
${this.draws('find')
|
|
463
425
|
? html `<${button}
|
|
464
|
-
part="find"
|
|
465
|
-
|
|
426
|
+
part="find-toggle"
|
|
427
|
+
id="find"
|
|
428
|
+
exportparts="button: find-toggle-button, live: find-toggle-live, spinner: find-toggle-spinner, text: find-toggle-text"
|
|
466
429
|
.expanded=${this.findOpen}
|
|
467
430
|
label=${this.findLabel}
|
|
468
|
-
@click=${() => (this.findOpen ? this.
|
|
431
|
+
@click=${() => (this.findOpen ? this.find?.element.hide() : void this.openFind())}
|
|
469
432
|
@helix-press=${stopPress}
|
|
470
433
|
>
|
|
471
434
|
<slot name="find-icon">${drawIcon(magnifyingGlass)}</slot>
|
|
472
|
-
</${button}>`
|
|
435
|
+
</${button}><${tip} for="find" content=${this.findLabel} 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}>`
|
|
473
436
|
: nothing}
|
|
474
437
|
${this.draws('copy')
|
|
475
438
|
? html `<${button}
|
|
476
439
|
part="copy"
|
|
440
|
+
id="copy"
|
|
477
441
|
exportparts="button: copy-button, live: copy-live, spinner: copy-spinner, text: copy-text"
|
|
478
442
|
?disabled=${!this.anySelected}
|
|
479
443
|
label=${this.copyLabel}
|
|
@@ -481,22 +445,24 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
481
445
|
@helix-press=${stopPress}
|
|
482
446
|
>
|
|
483
447
|
<slot name="copy-icon">${drawIcon(copy)}</slot>
|
|
484
|
-
</${button}>`
|
|
448
|
+
</${button}><${tip} for="copy" content=${this.copyLabel} 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}>`
|
|
485
449
|
: nothing}
|
|
486
450
|
${this.draws('clear')
|
|
487
451
|
? html `<${button}
|
|
488
452
|
part="clear"
|
|
453
|
+
id="clear"
|
|
489
454
|
exportparts="button: clear-button, live: clear-live, spinner: clear-spinner, text: clear-text"
|
|
490
455
|
label=${this.clearLabel}
|
|
491
456
|
@click=${() => this.clear()}
|
|
492
457
|
@helix-press=${stopPress}
|
|
493
458
|
>
|
|
494
459
|
<slot name="clear-icon">${drawIcon(broom)}</slot>
|
|
495
|
-
</${button}>`
|
|
460
|
+
</${button}><${tip} for="clear" content=${this.clearLabel} 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}>`
|
|
496
461
|
: nothing}
|
|
497
462
|
${this.draws('fullscreen')
|
|
498
463
|
? html `<${button}
|
|
499
464
|
part="fullscreen"
|
|
465
|
+
id="fullscreen"
|
|
500
466
|
exportparts="button: fullscreen-button, live: fullscreen-live, spinner: fullscreen-spinner, text: fullscreen-text"
|
|
501
467
|
aria-pressed=${this.filled ? 'true' : 'false'}
|
|
502
468
|
label=${this.fullscreenLabel}
|
|
@@ -504,7 +470,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
504
470
|
@helix-press=${stopPress}
|
|
505
471
|
>
|
|
506
472
|
<slot name="fullscreen-icon">${drawIcon(cornersOut)}</slot>
|
|
507
|
-
</${button}>`
|
|
473
|
+
</${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}>`
|
|
508
474
|
: nothing}
|
|
509
475
|
</${toolbar}>`;
|
|
510
476
|
}
|
|
@@ -512,84 +478,34 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
512
478
|
if (!this.draws('find')) {
|
|
513
479
|
return nothing;
|
|
514
480
|
}
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
exportparts="button: find-whole-word-button, live: find-whole-word-live, spinner: find-whole-word-spinner, text: find-whole-word-text"
|
|
544
|
-
aria-pressed=${this.findWholeWord ? 'true' : 'false'}
|
|
545
|
-
label=${this.findWholeWordLabel}
|
|
546
|
-
@click=${() => this.toggleOption('findWholeWord')}
|
|
547
|
-
@helix-press=${stopPress}
|
|
548
|
-
>
|
|
549
|
-
<slot name="find-whole-word-icon">${drawIcon(textAUnderline)}</slot>
|
|
550
|
-
</${button}>
|
|
551
|
-
<${button}
|
|
552
|
-
part="find-regex"
|
|
553
|
-
exportparts="button: find-regex-button, live: find-regex-live, spinner: find-regex-spinner, text: find-regex-text"
|
|
554
|
-
aria-pressed=${this.findRegex ? 'true' : 'false'}
|
|
555
|
-
label=${this.findRegexLabel}
|
|
556
|
-
@click=${() => this.toggleOption('findRegex')}
|
|
557
|
-
@helix-press=${stopPress}
|
|
558
|
-
>
|
|
559
|
-
<slot name="find-regex-icon">${drawIcon(asterisk)}</slot>
|
|
560
|
-
</${button}>
|
|
561
|
-
<slot name="find-actions" part="find-actions"></slot>
|
|
562
|
-
<${button}
|
|
563
|
-
part="find-previous"
|
|
564
|
-
exportparts="button: find-previous-button, live: find-previous-live, spinner: find-previous-spinner, text: find-previous-text"
|
|
565
|
-
?disabled=${!this.matchCount}
|
|
566
|
-
label=${this.findPreviousLabel}
|
|
567
|
-
@click=${() => this.search(true)}
|
|
568
|
-
@helix-press=${stopPress}
|
|
569
|
-
>
|
|
570
|
-
<slot name="find-previous-icon">${drawIcon(caretUp)}</slot>
|
|
571
|
-
</${button}>
|
|
572
|
-
<${button}
|
|
573
|
-
part="find-next"
|
|
574
|
-
exportparts="button: find-next-button, live: find-next-live, spinner: find-next-spinner, text: find-next-text"
|
|
575
|
-
?disabled=${!this.matchCount}
|
|
576
|
-
label=${this.findNextLabel}
|
|
577
|
-
@click=${() => this.search(false)}
|
|
578
|
-
@helix-press=${stopPress}
|
|
579
|
-
>
|
|
580
|
-
<slot name="find-next-icon">${drawIcon(caretDown)}</slot>
|
|
581
|
-
</${button}>
|
|
582
|
-
<${button}
|
|
583
|
-
part="find-close"
|
|
584
|
-
exportparts="button: find-close-button, live: find-close-live, spinner: find-close-spinner, text: find-close-text"
|
|
585
|
-
label=${this.findCloseLabel}
|
|
586
|
-
@click=${() => this.closeFind()}
|
|
587
|
-
@helix-press=${stopPress}
|
|
588
|
-
>
|
|
589
|
-
<slot name="find-close-icon">${drawIcon(x)}</slot>
|
|
590
|
-
</${button}>
|
|
591
|
-
</${toolbar}>
|
|
592
|
-
</div>`;
|
|
481
|
+
const find = this.tag('find');
|
|
482
|
+
return html `<${find}
|
|
483
|
+
part="find"
|
|
484
|
+
exportparts="actions: find-actions, bar: find-bar, close: find-close, close-button: find-close-button, close-live: find-close-live, close-spinner: find-close-spinner, close-text: find-close-text, controls: find-controls, controls-toolbar: find-controls-toolbar, count: find-count, field: find-field, live: find-live, match-case: find-match-case, match-case-button: find-match-case-button, match-case-live: find-match-case-live, match-case-pressed: find-match-case-pressed, match-case-spinner: find-match-case-spinner, match-case-text: find-match-case-text, next: find-next, next-button: find-next-button, next-live: find-next-live, next-spinner: find-next-spinner, next-text: find-next-text, previous: find-previous, previous-button: find-previous-button, previous-live: find-previous-live, previous-spinner: find-previous-spinner, previous-text: find-previous-text, regex: find-regex, regex-button: find-regex-button, regex-live: find-regex-live, regex-pressed: find-regex-pressed, regex-spinner: find-regex-spinner, regex-text: find-regex-text, replace-all-button: find-replace-all-button, replace-all-live: find-replace-all-live, replace-all-spinner: find-replace-all-spinner, replace-all-text: find-replace-all-text, replace-all: find-replace-all, replace-button: find-replace-button, replace-field: find-replace-field, replace-live: find-replace-live, replace-spinner: find-replace-spinner, replace-text: find-replace-text, replace-toggle-button: find-replace-toggle-button, replace-toggle-live: find-replace-toggle-live, replace-toggle-spinner: find-replace-toggle-spinner, replace-toggle-text: find-replace-toggle-text, replace-toggle: find-replace-toggle, replace: find-replace, whole-word: find-whole-word, whole-word-button: find-whole-word-button, whole-word-live: find-whole-word-live, whole-word-pressed: find-whole-word-pressed, whole-word-spinner: find-whole-word-spinner, whole-word-text: find-whole-word-text"
|
|
485
|
+
close-label=${this.findCloseLabel}
|
|
486
|
+
controls-label=${this.findControlsLabel}
|
|
487
|
+
invalid-label=${this.findInvalidLabel}
|
|
488
|
+
label=${this.findLabel}
|
|
489
|
+
?match-case=${this.findMatchCase}
|
|
490
|
+
match-case-label=${this.findMatchCaseLabel}
|
|
491
|
+
matches-label=${this.matchesLabel}
|
|
492
|
+
next-label=${this.findNextLabel}
|
|
493
|
+
previous-label=${this.findPreviousLabel}
|
|
494
|
+
?regex=${this.findRegex}
|
|
495
|
+
regex-label=${this.findRegexLabel}
|
|
496
|
+
shortcut=""
|
|
497
|
+
?whole-word=${this.findWholeWord}
|
|
498
|
+
whole-word-label=${this.findWholeWordLabel}
|
|
499
|
+
@toggle=${this.handleFindToggle}
|
|
500
|
+
>
|
|
501
|
+
<slot name="find-actions" slot="actions"></slot>
|
|
502
|
+
<slot name="find-match-case-icon" slot="match-case-icon">${drawIcon(textAa)}</slot>
|
|
503
|
+
<slot name="find-whole-word-icon" slot="whole-word-icon">${drawIcon(textAUnderline)}</slot>
|
|
504
|
+
<slot name="find-regex-icon" slot="regex-icon">${drawIcon(asterisk)}</slot>
|
|
505
|
+
<slot name="find-previous-icon" slot="previous-icon">${drawIcon(caretUp)}</slot>
|
|
506
|
+
<slot name="find-next-icon" slot="next-icon">${drawIcon(caretDown)}</slot>
|
|
507
|
+
<slot name="find-close-icon" slot="close-icon">${drawIcon(x)}</slot>
|
|
508
|
+
</${find}>`;
|
|
593
509
|
}
|
|
594
510
|
renderLook() {
|
|
595
511
|
return html `<span data-look hidden aria-hidden="true" style="color: transparent">
|
|
@@ -765,18 +681,6 @@ __decorate([
|
|
|
765
681
|
__decorate([
|
|
766
682
|
state()
|
|
767
683
|
], HelixHeadlessTerminal.prototype, "findOpen", void 0);
|
|
768
|
-
__decorate([
|
|
769
|
-
state()
|
|
770
|
-
], HelixHeadlessTerminal.prototype, "query", void 0);
|
|
771
|
-
__decorate([
|
|
772
|
-
state()
|
|
773
|
-
], HelixHeadlessTerminal.prototype, "matchIndex", void 0);
|
|
774
|
-
__decorate([
|
|
775
|
-
state()
|
|
776
|
-
], HelixHeadlessTerminal.prototype, "matchCount", void 0);
|
|
777
|
-
__decorate([
|
|
778
|
-
state()
|
|
779
|
-
], HelixHeadlessTerminal.prototype, "invalid", void 0);
|
|
780
684
|
__decorate([
|
|
781
685
|
state()
|
|
782
686
|
], HelixHeadlessTerminal.prototype, "tabMovesFocus", void 0);
|
|
@@ -10,7 +10,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
|
|
|
10
10
|
* The toolbar is one tab stop, and the arrow keys move between its controls, so
|
|
11
11
|
* three toolbars take three presses of Tab to pass. Any element the browser can
|
|
12
12
|
* focus counts as a control, including your own elements. A child that takes no
|
|
13
|
-
* focus, such as a divider, is skipped. A menu is reached at its trigger.
|
|
13
|
+
* focus, such as a divider, is skipped. A menu is reached at its trigger. A
|
|
14
|
+
* disabled control is skipped too, except a Button with
|
|
15
|
+
* `focusable-when-disabled`, which the arrows still reach so its tooltip can
|
|
16
|
+
* say why it is disabled.
|
|
14
17
|
*
|
|
15
18
|
* A Divider in the toolbar is a separator across the toolbar's axis, as React
|
|
16
19
|
* Aria's is: vertical in a horizontal toolbar and horizontal in a vertical
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HelixElement, OpenPhaseController, type Placement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { type CSSResultGroup, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
4
4
|
/**
|
|
5
5
|
* @summary A short text that appears next to an element on hover and focus.
|
|
@@ -85,6 +85,7 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
|
|
|
85
85
|
* @cssstate placed-top - While the bubble sits above its trigger.
|
|
86
86
|
*/
|
|
87
87
|
export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
88
|
+
static styles: CSSResultGroup;
|
|
88
89
|
/**
|
|
89
90
|
* The text shown in the bubble.
|
|
90
91
|
*
|
|
@@ -314,6 +315,12 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
314
315
|
* every control turns the scan into a series of pauses.
|
|
315
316
|
*/
|
|
316
317
|
private readonly showLater;
|
|
318
|
+
/**
|
|
319
|
+
* Shows for a pointer or for focus, unless a menu or popover is open that
|
|
320
|
+
* the tooltip is not inside. `show()` and `open` are the consumer's own and
|
|
321
|
+
* are not refused.
|
|
322
|
+
*/
|
|
323
|
+
private showForReader;
|
|
317
324
|
/**
|
|
318
325
|
* The pointer reached the bubble, in the `for` form.
|
|
319
326
|
*
|
|
@@ -442,6 +449,21 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
|
|
|
442
449
|
* renders as its name, then the trigger's text.
|
|
443
450
|
*/
|
|
444
451
|
private triggerSays;
|
|
452
|
+
/**
|
|
453
|
+
* A menu or popover opened outside the tooltip, so the tooltip yields to it.
|
|
454
|
+
*
|
|
455
|
+
* **A tooltip outside an open panel sits over the panel the reader is
|
|
456
|
+
* using.** A menu opened from the keyboard, or from a control beside the
|
|
457
|
+
* trigger while the pointer is still on it, is opened with no `click` on the
|
|
458
|
+
* trigger and no `pointerleave`, so neither takes the bubble down. Opening a
|
|
459
|
+
* menu by its keys from a trigger inside the tooltip also moves focus into
|
|
460
|
+
* the menu, and that `focusin` showed the bubble again. A pointer or focus
|
|
461
|
+
* does not show the bubble while such a panel is open, and this closes one
|
|
462
|
+
* they hold up as the panel opens. A bubble the consumer opened with `show()`
|
|
463
|
+
* or `open` holds nothing and stays.
|
|
464
|
+
*/
|
|
465
|
+
private readonly yieldTo;
|
|
466
|
+
private stopYielding;
|
|
445
467
|
connectedCallback(): void;
|
|
446
468
|
disconnectedCallback(): void;
|
|
447
469
|
protected firstUpdated(changed: PropertyValues): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { anchorElement, arrowReach, customElement, elementById, focusTarget, HelixElement, hostAria, linkDescription, MixinControllerOpen, numberConverter, OpenPhaseController, onUnlessFalse, PopoverController, reportRuntime, sideOf, timeConverter, unlinkDescription, } from '@fusion.dev/helix-core';
|
|
3
|
-
import { html } from 'lit';
|
|
2
|
+
import { anchorElement, arrowReach, customElement, elementById, focusTarget, HelixElement, hintInside, hintMayShow, hostAria, linkDescription, MixinControllerOpen, numberConverter, OpenPhaseController, onPanelOpen, onUnlessFalse, PopoverController, reportRuntime, sideOf, timeConverter, unlinkDescription, } from '@fusion.dev/helix-core';
|
|
3
|
+
import { css, html } from 'lit';
|
|
4
4
|
import { property, state } from 'lit/decorators.js';
|
|
5
5
|
const GENERIC = new Set(['div', 'p', 'section', 'span']);
|
|
6
6
|
const WARMTH = Symbol.for('fusion.helix.tooltip.warmth');
|
|
@@ -28,6 +28,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
28
28
|
anchor: () => this.trigger,
|
|
29
29
|
arrow: () => this.partNamed('arrow'),
|
|
30
30
|
boundary: () => [this, this.named],
|
|
31
|
+
hints: 'keep',
|
|
31
32
|
offset: () => this.offset + arrowReach(this.partNamed('arrow')),
|
|
32
33
|
onDismiss: () => {
|
|
33
34
|
this.holds.clear();
|
|
@@ -65,10 +66,10 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
65
66
|
const warm = warmth();
|
|
66
67
|
const others = [...warm.showing].some((one) => one !== this);
|
|
67
68
|
if (others || performance.now() - warm.hidAt < this.skipDelay) {
|
|
68
|
-
this.
|
|
69
|
+
this.showForReader();
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
this.timer = setTimeout(() => this.
|
|
72
|
+
this.timer = setTimeout(() => this.showForReader(), this.delay);
|
|
72
73
|
};
|
|
73
74
|
this.holdOnBubble = () => {
|
|
74
75
|
if (!this.hoverable) {
|
|
@@ -97,7 +98,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
100
|
this.holds.add('focus');
|
|
100
|
-
this.
|
|
101
|
+
this.showForReader();
|
|
101
102
|
};
|
|
102
103
|
this.releaseFocus = () => {
|
|
103
104
|
this.holds.delete('focus');
|
|
@@ -115,7 +116,18 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
115
116
|
this.link(true, event.type === 'focusin' && first instanceof Element ? first : undefined);
|
|
116
117
|
};
|
|
117
118
|
this.audited = false;
|
|
119
|
+
this.yieldTo = (surface) => {
|
|
120
|
+
if (this.open && this.holds.size > 0 && !hintInside(surface, this)) {
|
|
121
|
+
this.holds.clear();
|
|
122
|
+
this.hide();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
static { this.styles = css `
|
|
127
|
+
:host {
|
|
128
|
+
display: contents;
|
|
118
129
|
}
|
|
130
|
+
`; }
|
|
119
131
|
get trigger() {
|
|
120
132
|
const named = this.named;
|
|
121
133
|
if (named) {
|
|
@@ -180,6 +192,11 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
180
192
|
}
|
|
181
193
|
this.bubbleLayer.hide();
|
|
182
194
|
}
|
|
195
|
+
showForReader() {
|
|
196
|
+
if (hintMayShow(this)) {
|
|
197
|
+
this.show();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
183
200
|
release() {
|
|
184
201
|
if (this.holds.size === 0) {
|
|
185
202
|
this.hide();
|
|
@@ -277,6 +294,9 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
277
294
|
});
|
|
278
295
|
return;
|
|
279
296
|
}
|
|
297
|
+
if (this.triggerSays(this.describedText)) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
280
300
|
reportRuntime({
|
|
281
301
|
kind: 'unlinked-trigger',
|
|
282
302
|
message: `<${this.localName} for="${this.for}"> is not read out with its trigger. The link is ` +
|
|
@@ -294,12 +314,15 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
|
|
|
294
314
|
}
|
|
295
315
|
connectedCallback() {
|
|
296
316
|
super.connectedCallback();
|
|
317
|
+
this.stopYielding ??= onPanelOpen(this.yieldTo);
|
|
297
318
|
if (this.hasUpdated) {
|
|
298
319
|
this.bind();
|
|
299
320
|
}
|
|
300
321
|
}
|
|
301
322
|
disconnectedCallback() {
|
|
302
323
|
super.disconnectedCallback();
|
|
324
|
+
this.stopYielding?.();
|
|
325
|
+
this.stopYielding = undefined;
|
|
303
326
|
this.unbind();
|
|
304
327
|
this.holds.clear();
|
|
305
328
|
clearTimeout(this.timer);
|
|
@@ -306,6 +306,7 @@ export declare class HelixHeadlessTour extends HelixHeadlessTour_base {
|
|
|
306
306
|
private light;
|
|
307
307
|
/** Keeps `sizer` on the lit target, and on nothing once there is none. */
|
|
308
308
|
private watch;
|
|
309
|
+
private readonly handleSlotChange;
|
|
309
310
|
protected render(): TemplateResult;
|
|
310
311
|
}
|
|
311
312
|
declare global {
|
|
@@ -75,6 +75,9 @@ let HelixHeadlessTour = class HelixHeadlessTour extends MixinControllerOpen(Heli
|
|
|
75
75
|
};
|
|
76
76
|
this.followed = false;
|
|
77
77
|
this.veiled = false;
|
|
78
|
+
this.handleSlotChange = () => {
|
|
79
|
+
this.requestUpdate();
|
|
80
|
+
};
|
|
78
81
|
}
|
|
79
82
|
static { this.words = 'helix-tour'; }
|
|
80
83
|
get index() {
|
|
@@ -415,7 +418,7 @@ let HelixHeadlessTour = class HelixHeadlessTour extends MixinControllerOpen(Heli
|
|
|
415
418
|
aria-hidden="true"
|
|
416
419
|
style=${`left: ${spot.left}px; top: ${spot.top}px; block-size: ${spot.height}px; inline-size: ${spot.width}px; --tour-spotlight-x: ${spot.left}px; --tour-spotlight-y: ${spot.top}px; --tour-spotlight-width: ${spot.width}px; --tour-spotlight-height: ${spot.height}px`}
|
|
417
420
|
></div>`}
|
|
418
|
-
<slot></slot>`;
|
|
421
|
+
<slot @slotchange=${this.handleSlotChange}></slot>`;
|
|
419
422
|
}
|
|
420
423
|
};
|
|
421
424
|
__decorate([
|
|
@@ -31,6 +31,7 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
|
|
|
31
31
|
this.floating = new PopoverController(this, {
|
|
32
32
|
anchor: () => this.target,
|
|
33
33
|
arrow: () => this.partNamed('arrow'),
|
|
34
|
+
hints: 'keep',
|
|
34
35
|
offset: () => {
|
|
35
36
|
const tour = this.parentElement;
|
|
36
37
|
return (tour?.spotlightPadding ?? 0) + arrowReach(this.partNamed('arrow'));
|
|
@@ -29,6 +29,10 @@ declare const HelixHeadlessTreeItem_base: (new (...args: any[]) => import("@fusi
|
|
|
29
29
|
* A `disabled` item is reached by the arrow keys and announced as unavailable,
|
|
30
30
|
* and a press, Enter or Space on it does nothing.
|
|
31
31
|
*
|
|
32
|
+
* A closed branch's children are hidden until found: the browser's find and
|
|
33
|
+
* Find search them, and the branch opens on the one that holds the match,
|
|
34
|
+
* unless `helix-before-open` is canceled.
|
|
35
|
+
*
|
|
32
36
|
* A `lazy` item is a branch whose children you load when it opens: opening it
|
|
33
37
|
* sends `helix-load`, the row says it is busy, and the children you add appear
|
|
34
38
|
* in it. Remove `lazy` once they are in.
|
|
@@ -264,6 +268,13 @@ export declare class HelixHeadlessTreeItem extends HelixHeadlessTreeItem_base {
|
|
|
264
268
|
* its children.
|
|
265
269
|
*/
|
|
266
270
|
private follow;
|
|
271
|
+
/**
|
|
272
|
+
* A search found a match among the closed branch's children, and shows it
|
|
273
|
+
* next: the browser's find or Find. The branch opens, and where the page
|
|
274
|
+
* refuses, its children are hidden again once the search has shown them, as
|
|
275
|
+
* Accordion's section is.
|
|
276
|
+
*/
|
|
277
|
+
private readonly handleBeforeMatch;
|
|
267
278
|
/** A press on the check mark checks the item and leaves a branch as it is. */
|
|
268
279
|
private readonly handleCheckClick;
|
|
269
280
|
private readonly handleToggleClick;
|
|
@@ -21,6 +21,19 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
21
21
|
this.focusable = false;
|
|
22
22
|
this.value = '';
|
|
23
23
|
this.branch = false;
|
|
24
|
+
this.handleBeforeMatch = (event) => {
|
|
25
|
+
if (this.open || this.requestOpen(true)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const group = event.currentTarget;
|
|
29
|
+
const observer = new MutationObserver(() => {
|
|
30
|
+
observer.disconnect();
|
|
31
|
+
if (!this.open && !group.hasAttribute('hidden')) {
|
|
32
|
+
group.setAttribute('hidden', 'until-found');
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
observer.observe(group, { attributeFilter: ['hidden'] });
|
|
36
|
+
};
|
|
24
37
|
this.handleCheckClick = (event) => {
|
|
25
38
|
event.preventDefault();
|
|
26
39
|
event.stopPropagation();
|
|
@@ -227,7 +240,12 @@ let HelixHeadlessTreeItem = class HelixHeadlessTreeItem extends MixinControllerO
|
|
|
227
240
|
branch reports children it has no relationship to. The pattern is
|
|
228
241
|
\`treeitem\` containing \`group\`, which is also what an \`<li>\`
|
|
229
242
|
holding a \`<ul>\` is. -->
|
|
230
|
-
<div
|
|
243
|
+
<div
|
|
244
|
+
part="group"
|
|
245
|
+
role=${this.open ? 'group' : nothing}
|
|
246
|
+
hidden=${this.open ? nothing : 'until-found'}
|
|
247
|
+
@beforematch=${this.handleBeforeMatch}
|
|
248
|
+
>
|
|
231
249
|
<slot name="children"></slot>
|
|
232
250
|
</div>
|
|
233
251
|
</div>`;
|