@fusion.dev/helix-headless 0.219.0 → 0.221.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/code-editor/root/code-editor-root.d.ts +68 -71
- package/dist/code-editor/root/code-editor-root.js +67 -249
- package/dist/editor/index.d.ts +1 -0
- package/dist/editor/index.js +1 -0
- package/dist/editor/root/editor-root.d.ts +611 -0
- package/dist/editor/root/editor-root.js +860 -0
- package/dist/element-events.generated.js +4 -1
- 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/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/log/group/log-group.d.ts +11 -2
- package/dist/log/group/log-group.js +17 -3
- package/dist/terminal/root/terminal-root.d.ts +49 -32
- package/dist/terminal/root/terminal-root.js +72 -181
- 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 +1782 -74
- package/types/svelte.d.ts +2 -0
- package/types/vue.d.ts +292 -4
- package/types/words.d.ts +227 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HelixElement, type TerminalResizeDetail } from '@fusion.dev/helix-core';
|
|
2
2
|
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../button/index.js';
|
|
4
|
+
import '../../find/index.js';
|
|
4
5
|
import '../../icon-button/index.js';
|
|
5
6
|
import '../../tooltip/index.js';
|
|
6
7
|
import '../../toolbar/index.js';
|
|
@@ -164,6 +165,7 @@ export interface TerminalSink {
|
|
|
164
165
|
* @slot restart-icon - Replaces the glyph inside the Restart button.
|
|
165
166
|
*
|
|
166
167
|
* @event {HelixCopyEvent} helix-copy - The copy control or its key put the selection on the clipboard.
|
|
168
|
+
* @event {HelixFoundEvent} helix-found - The find bar searched or moved among the matches, with `count` and the current match's `index`, counting from 0, or -1 for none.
|
|
167
169
|
* @event {HelixTerminalBellEvent} helix-terminal-bell - The program rang the bell. The frame flashes once.
|
|
168
170
|
* @event {HelixTerminalInputEvent} helix-terminal-input - The reader typed or pasted, with `data` encoded for the program. Write it to the process. Not sent while `readonly`, or once `exit-code` is set.
|
|
169
171
|
* @event {HelixTerminalLinkEvent} helix-terminal-link - A link in the output was activated, with its `href`. Cancelable: cancel it to open the link yourself. Left alone, a web address opens in a new tab.
|
|
@@ -185,23 +187,23 @@ export interface TerminalSink {
|
|
|
185
187
|
* @csspart copy-spinner - The ring the copy button turns while it is pending.
|
|
186
188
|
* @csspart copy-text - The box the copy button's icon sits in.
|
|
187
189
|
* @csspart exit-actions - The `exit-actions` slot, beside Restart in the status line.
|
|
188
|
-
* @csspart find - The
|
|
189
|
-
* @csspart find-actions - The `find-actions` slot,
|
|
190
|
-
* @csspart find-bar - The bar
|
|
191
|
-
* @csspart find-button - The find button's inner button.
|
|
190
|
+
* @csspart find - The find bar under the header, where the reader searches the output: a Find of its own.
|
|
191
|
+
* @csspart find-actions - The `find-actions` slot, in the find bar's toolbar.
|
|
192
|
+
* @csspart find-bar - The find bar's strip: the field, the count, and the toolbar.
|
|
192
193
|
* @csspart find-close - The button that closes the find bar.
|
|
193
194
|
* @csspart find-close-button - The find bar's close button's inner button.
|
|
194
195
|
* @csspart find-close-live - The find bar's close button's live region, which speaks while the button is pending.
|
|
195
196
|
* @csspart find-close-spinner - The ring the find bar's close button turns while it is pending.
|
|
196
197
|
* @csspart find-close-text - The box the find bar's close button's icon sits in.
|
|
197
|
-
* @csspart find-controls - The toolbar at the end of the find bar: your find actions,
|
|
198
|
+
* @csspart find-controls - The toolbar at the end of the find bar: the options, your find actions, and the buttons that move between matches and close the bar.
|
|
198
199
|
* @csspart find-controls-toolbar - The box inside the find bar's toolbar that lays its buttons out.
|
|
199
200
|
* @csspart find-count - Which match is current and how many there are, such as "3 of 12 matches".
|
|
200
201
|
* @csspart find-field - The search field in the find bar.
|
|
201
|
-
* @csspart find-live - The find
|
|
202
|
+
* @csspart find-live - The find bar's live region, which says the count as it changes.
|
|
202
203
|
* @csspart find-match-case - The button that matches case in the find bar. Pressed while it does.
|
|
203
204
|
* @csspart find-match-case-button - The match case button's inner button.
|
|
204
205
|
* @csspart find-match-case-live - The match case button's live region, which speaks while the button is pending.
|
|
206
|
+
* @csspart find-match-case-pressed - The match case button while case has to match, beside `find-match-case`.
|
|
205
207
|
* @csspart find-match-case-spinner - The ring the match case button turns while it is pending.
|
|
206
208
|
* @csspart find-match-case-text - The box the match case button's icon sits in.
|
|
207
209
|
* @csspart find-next - The button that moves to the next match.
|
|
@@ -217,13 +219,34 @@ export interface TerminalSink {
|
|
|
217
219
|
* @csspart find-regex - The button that reads the find field as a regular expression. Pressed while it does.
|
|
218
220
|
* @csspart find-regex-button - The regular expression button's inner button.
|
|
219
221
|
* @csspart find-regex-live - The regular expression button's live region, which speaks while the button is pending.
|
|
222
|
+
* @csspart find-regex-pressed - The regular expression button while the field reads as one, beside `find-regex`.
|
|
220
223
|
* @csspart find-regex-spinner - The ring the regular expression button turns while it is pending.
|
|
221
224
|
* @csspart find-regex-text - The box the regular expression button's icon sits in.
|
|
222
|
-
* @csspart find-
|
|
223
|
-
* @csspart find-
|
|
225
|
+
* @csspart find-replace - The find bar's Replace button, which a terminal does not draw, since its output cannot be changed.
|
|
226
|
+
* @csspart find-replace-all - The find bar's Replace all button, which a terminal does not draw.
|
|
227
|
+
* @csspart find-replace-all-button - The Replace all button's inner button.
|
|
228
|
+
* @csspart find-replace-all-live - The Replace all button's live region, which speaks while the button is pending.
|
|
229
|
+
* @csspart find-replace-all-spinner - The ring the Replace all button turns while it is pending.
|
|
230
|
+
* @csspart find-replace-all-text - The box the Replace all button's words sits in.
|
|
231
|
+
* @csspart find-replace-button - The Replace button's inner button.
|
|
232
|
+
* @csspart find-replace-field - The find bar's replace field, which a terminal does not draw.
|
|
233
|
+
* @csspart find-replace-live - The Replace button's live region, which speaks while the button is pending.
|
|
234
|
+
* @csspart find-replace-spinner - The ring the Replace button turns while it is pending.
|
|
235
|
+
* @csspart find-replace-text - The box the Replace button's words sits in.
|
|
236
|
+
* @csspart find-replace-toggle - The button that shows the find bar's replace row, which a terminal does not draw.
|
|
237
|
+
* @csspart find-replace-toggle-button - The replace toggle's inner button.
|
|
238
|
+
* @csspart find-replace-toggle-live - The replace toggle's live region, which speaks while the button is pending.
|
|
239
|
+
* @csspart find-replace-toggle-spinner - The ring the replace toggle turns while it is pending.
|
|
240
|
+
* @csspart find-replace-toggle-text - The box the replace toggle's icon sits in.
|
|
241
|
+
* @csspart find-toggle - The button in the header that opens and closes the find bar. Expanded while it is open.
|
|
242
|
+
* @csspart find-toggle-button - The find button's inner button.
|
|
243
|
+
* @csspart find-toggle-live - The find button's live region, which speaks while the button is pending.
|
|
244
|
+
* @csspart find-toggle-spinner - The ring the find button turns while it is pending.
|
|
245
|
+
* @csspart find-toggle-text - The box the find button's icon sits in.
|
|
224
246
|
* @csspart find-whole-word - The button that matches whole words only in the find bar. Pressed while it does.
|
|
225
247
|
* @csspart find-whole-word-button - The whole word button's inner button.
|
|
226
248
|
* @csspart find-whole-word-live - The whole word button's live region, which speaks while the button is pending.
|
|
249
|
+
* @csspart find-whole-word-pressed - The whole word button while only whole words match, beside `find-whole-word`.
|
|
227
250
|
* @csspart find-whole-word-spinner - The ring the whole word button turns while it is pending.
|
|
228
251
|
* @csspart find-whole-word-text - The box the whole word button's icon sits in.
|
|
229
252
|
* @csspart fullscreen - The button that makes the terminal fill the screen. Pressed while it does.
|
|
@@ -385,16 +408,12 @@ export declare class HelixHeadlessTerminal extends HelixElement {
|
|
|
385
408
|
tabMovesFocusLabel: string;
|
|
386
409
|
/** What screen readers hear when Tab goes back to typing in the terminal. */
|
|
387
410
|
tabTypesLabel: string;
|
|
388
|
-
/** Whether the find bar is open. */
|
|
411
|
+
/** Whether the find bar is open, as it last said. */
|
|
389
412
|
private findOpen;
|
|
390
|
-
/**
|
|
391
|
-
private
|
|
392
|
-
/** The
|
|
393
|
-
private
|
|
394
|
-
/** How many matches the search found, or `undefined` before one ran. */
|
|
395
|
-
private matchCount;
|
|
396
|
-
/** Whether the regular expression in the field cannot be read, which the count says instead. */
|
|
397
|
-
private invalid;
|
|
413
|
+
/** The find bar drawn now, and how the renderer reports a search to it. */
|
|
414
|
+
private find;
|
|
415
|
+
/** The options the renderer last searched with, which a search with others ends first. */
|
|
416
|
+
private searchedWith;
|
|
398
417
|
/** Whether Tab moves focus, after Control+M. */
|
|
399
418
|
private tabMovesFocus;
|
|
400
419
|
/** Whether any text is selected in the grid. */
|
|
@@ -468,8 +487,6 @@ export declare class HelixHeadlessTerminal extends HelixElement {
|
|
|
468
487
|
private say;
|
|
469
488
|
/** Whether `controls`, or the resting controls, names a control the renderer can answer. */
|
|
470
489
|
private draws;
|
|
471
|
-
/** The find bar's count, as the reader reads it. */
|
|
472
|
-
private get countText();
|
|
473
490
|
/** The chord that switches Tab, as a reader says it. */
|
|
474
491
|
private get tabKey();
|
|
475
492
|
/**
|
|
@@ -490,16 +507,15 @@ export declare class HelixHeadlessTerminal extends HelixElement {
|
|
|
490
507
|
* a key the frame takes never reaches the program.
|
|
491
508
|
*/
|
|
492
509
|
private readonly handleKeys;
|
|
493
|
-
/** Opens the find bar and puts focus in its field
|
|
510
|
+
/** Opens the find bar and puts focus in its field. */
|
|
494
511
|
private openFind;
|
|
495
|
-
/**
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
private readonly
|
|
502
|
-
private readonly handleFindKeys;
|
|
512
|
+
/**
|
|
513
|
+
* The renderer, as the find bar searches through it. The renderer reports
|
|
514
|
+
* the matches through `found`, once it has counted them.
|
|
515
|
+
*/
|
|
516
|
+
private readonly finder;
|
|
517
|
+
/** The find bar opened or closed, which the find button shows. */
|
|
518
|
+
private readonly handleFindToggle;
|
|
503
519
|
/** Copies the selection, and says so. */
|
|
504
520
|
private copySelection;
|
|
505
521
|
private readonly handleActions;
|
|
@@ -512,6 +528,8 @@ export declare class HelixHeadlessTerminal extends HelixElement {
|
|
|
512
528
|
*/
|
|
513
529
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
514
530
|
protected updated(changed: PropertyValues<this>): void;
|
|
531
|
+
/** Hands the find bar drawn now the renderer to search through, once per bar. */
|
|
532
|
+
private attachFind;
|
|
515
533
|
connectedCallback(): void;
|
|
516
534
|
disconnectedCallback(): void;
|
|
517
535
|
/** Whether any built-in control is drawn. */
|
|
@@ -526,10 +544,9 @@ export declare class HelixHeadlessTerminal extends HelixElement {
|
|
|
526
544
|
*/
|
|
527
545
|
protected renderControls(): TemplateResult;
|
|
528
546
|
/**
|
|
529
|
-
* The find bar,
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
* would be out of their reach.
|
|
547
|
+
* The find bar, a Find of the frame's own that searches through the
|
|
548
|
+
* renderer, kept in the tree while closed so its field keeps what was
|
|
549
|
+
* typed. The frame takes the find key itself, so the bar takes none.
|
|
533
550
|
*/
|
|
534
551
|
protected renderFind(): TemplateResult | typeof nothing;
|
|
535
552
|
/**
|
|
@@ -4,22 +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
11
|
import '../../tooltip/index.js';
|
|
12
12
|
import '../../toolbar/index.js';
|
|
13
13
|
import { isTab, shortcutOf, spokenChord } from '../keys.js';
|
|
14
|
-
const readable = (source) => {
|
|
15
|
-
try {
|
|
16
|
-
new RegExp(source);
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
14
|
const ANSI = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
|
|
24
15
|
const camel = (name) => name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
25
16
|
const unset = (color) => color === '' || color === 'transparent' || /^rgba\(\s*0,\s*0,\s*0,\s*0\s*\)$/.test(color);
|
|
@@ -58,10 +49,6 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
58
49
|
this.tabMovesFocusLabel = 'Tab moves focus. Press {key} to type Tab in the terminal.';
|
|
59
50
|
this.tabTypesLabel = 'Tab types in the terminal.';
|
|
60
51
|
this.findOpen = false;
|
|
61
|
-
this.query = '';
|
|
62
|
-
this.matchIndex = -1;
|
|
63
|
-
this.matchCount = undefined;
|
|
64
|
-
this.invalid = false;
|
|
65
52
|
this.tabMovesFocus = false;
|
|
66
53
|
this.anySelected = false;
|
|
67
54
|
this.hasActions = false;
|
|
@@ -118,19 +105,33 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
118
105
|
event.stopPropagation();
|
|
119
106
|
}
|
|
120
107
|
};
|
|
121
|
-
this.
|
|
122
|
-
|
|
123
|
-
|
|
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
|
+
},
|
|
124
132
|
};
|
|
125
|
-
this.
|
|
126
|
-
|
|
127
|
-
event.preventDefault();
|
|
128
|
-
this.closeFind();
|
|
129
|
-
}
|
|
130
|
-
else if (event.key === 'Enter') {
|
|
131
|
-
event.preventDefault();
|
|
132
|
-
this.search(event.shiftKey);
|
|
133
|
-
}
|
|
133
|
+
this.handleFindToggle = (event) => {
|
|
134
|
+
this.findOpen = event.newState === 'open';
|
|
134
135
|
};
|
|
135
136
|
this.handleActions = (event) => {
|
|
136
137
|
this.hasActions = event.target.assignedNodes().length > 0;
|
|
@@ -221,9 +222,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
221
222
|
},
|
|
222
223
|
found: (index, count) => {
|
|
223
224
|
if (current()) {
|
|
224
|
-
this.
|
|
225
|
-
this.matchCount = count;
|
|
226
|
-
this.say(this.countText);
|
|
225
|
+
this.find?.sink.found({ count, index });
|
|
227
226
|
}
|
|
228
227
|
},
|
|
229
228
|
input: (data, binary = false) => {
|
|
@@ -300,17 +299,6 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
300
299
|
? renderer.selection !== undefined
|
|
301
300
|
: renderer.find !== undefined;
|
|
302
301
|
}
|
|
303
|
-
get countText() {
|
|
304
|
-
if (this.invalid) {
|
|
305
|
-
return this.findInvalidLabel;
|
|
306
|
-
}
|
|
307
|
-
return this.matchCount === undefined
|
|
308
|
-
? ''
|
|
309
|
-
: formatWords(this, 'matchesLabel', {
|
|
310
|
-
count: this.matchCount,
|
|
311
|
-
index: Math.max(this.matchIndex, 0) + 1,
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
302
|
get tabKey() {
|
|
315
303
|
return spokenChord('tab-focus', onApple());
|
|
316
304
|
}
|
|
@@ -355,8 +343,9 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
355
343
|
}
|
|
356
344
|
release() {
|
|
357
345
|
this.restoreInput();
|
|
358
|
-
this.
|
|
359
|
-
|
|
346
|
+
if (this.find) {
|
|
347
|
+
this.find.element.open = false;
|
|
348
|
+
}
|
|
360
349
|
this.anySelected = false;
|
|
361
350
|
}
|
|
362
351
|
takes(shortcut) {
|
|
@@ -373,45 +362,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
373
362
|
return true;
|
|
374
363
|
}
|
|
375
364
|
async openFind() {
|
|
376
|
-
this.
|
|
377
|
-
await this.updateComplete;
|
|
378
|
-
const field = this.partNamed('find-field');
|
|
379
|
-
field?.focus();
|
|
380
|
-
field?.select();
|
|
381
|
-
if (this.query !== '') {
|
|
382
|
-
this.search(false, true);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
closeFind() {
|
|
386
|
-
this.findOpen = false;
|
|
387
|
-
this.matchCount = undefined;
|
|
388
|
-
this.matchIndex = -1;
|
|
389
|
-
this.renderer?.findEnd?.();
|
|
390
|
-
this.focus();
|
|
391
|
-
}
|
|
392
|
-
search(backward, incremental = false) {
|
|
393
|
-
if (this.query === '' || (this.findRegex && !readable(this.query))) {
|
|
394
|
-
this.invalid = this.query !== '';
|
|
395
|
-
this.matchCount = undefined;
|
|
396
|
-
this.renderer?.findEnd?.();
|
|
397
|
-
if (this.invalid) {
|
|
398
|
-
this.say(this.findInvalidLabel);
|
|
399
|
-
}
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
this.invalid = false;
|
|
403
|
-
this.renderer?.find?.(this.query, {
|
|
404
|
-
backward,
|
|
405
|
-
caseSensitive: this.findMatchCase,
|
|
406
|
-
incremental,
|
|
407
|
-
regex: this.findRegex,
|
|
408
|
-
wholeWord: this.findWholeWord,
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
toggleOption(option) {
|
|
412
|
-
this[option] = !this[option];
|
|
413
|
-
this.renderer?.findEnd?.();
|
|
414
|
-
this.search(false, true);
|
|
365
|
+
await this.find?.element.show();
|
|
415
366
|
}
|
|
416
367
|
async copySelection() {
|
|
417
368
|
const text = this.renderer?.selection?.() ?? '';
|
|
@@ -442,6 +393,15 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
442
393
|
if (this.renderer && (changed.has('inputLabel') || changed.has('tabHintLabel'))) {
|
|
443
394
|
this.nameInput();
|
|
444
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;
|
|
445
405
|
}
|
|
446
406
|
connectedCallback() {
|
|
447
407
|
super.connectedCallback();
|
|
@@ -463,12 +423,12 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
463
423
|
<slot name="actions" part="actions" @slotchange=${this.handleActions}></slot>
|
|
464
424
|
${this.draws('find')
|
|
465
425
|
? html `<${button}
|
|
466
|
-
part="find"
|
|
426
|
+
part="find-toggle"
|
|
467
427
|
id="find"
|
|
468
|
-
exportparts="button: find-button, live: find-live, spinner: find-spinner, text: find-text"
|
|
428
|
+
exportparts="button: find-toggle-button, live: find-toggle-live, spinner: find-toggle-spinner, text: find-toggle-text"
|
|
469
429
|
.expanded=${this.findOpen}
|
|
470
430
|
label=${this.findLabel}
|
|
471
|
-
@click=${() => (this.findOpen ? this.
|
|
431
|
+
@click=${() => (this.findOpen ? this.find?.element.hide() : void this.openFind())}
|
|
472
432
|
@helix-press=${stopPress}
|
|
473
433
|
>
|
|
474
434
|
<slot name="find-icon">${drawIcon(magnifyingGlass)}</slot>
|
|
@@ -518,91 +478,34 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
|
|
|
518
478
|
if (!this.draws('find')) {
|
|
519
479
|
return nothing;
|
|
520
480
|
}
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
<${button}
|
|
550
|
-
part="find-whole-word"
|
|
551
|
-
id="find-whole-word"
|
|
552
|
-
exportparts="button: find-whole-word-button, live: find-whole-word-live, spinner: find-whole-word-spinner, text: find-whole-word-text"
|
|
553
|
-
aria-pressed=${this.findWholeWord ? 'true' : 'false'}
|
|
554
|
-
label=${this.findWholeWordLabel}
|
|
555
|
-
@click=${() => this.toggleOption('findWholeWord')}
|
|
556
|
-
@helix-press=${stopPress}
|
|
557
|
-
>
|
|
558
|
-
<slot name="find-whole-word-icon">${drawIcon(textAUnderline)}</slot>
|
|
559
|
-
</${button}><${tip} for="find-whole-word" content=${this.findWholeWordLabel} 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}>
|
|
560
|
-
<${button}
|
|
561
|
-
part="find-regex"
|
|
562
|
-
id="find-regex"
|
|
563
|
-
exportparts="button: find-regex-button, live: find-regex-live, spinner: find-regex-spinner, text: find-regex-text"
|
|
564
|
-
aria-pressed=${this.findRegex ? 'true' : 'false'}
|
|
565
|
-
label=${this.findRegexLabel}
|
|
566
|
-
@click=${() => this.toggleOption('findRegex')}
|
|
567
|
-
@helix-press=${stopPress}
|
|
568
|
-
>
|
|
569
|
-
<slot name="find-regex-icon">${drawIcon(asterisk)}</slot>
|
|
570
|
-
</${button}><${tip} for="find-regex" content=${this.findRegexLabel} 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}>
|
|
571
|
-
<slot name="find-actions" part="find-actions"></slot>
|
|
572
|
-
<${button}
|
|
573
|
-
part="find-previous"
|
|
574
|
-
id="find-previous"
|
|
575
|
-
exportparts="button: find-previous-button, live: find-previous-live, spinner: find-previous-spinner, text: find-previous-text"
|
|
576
|
-
?disabled=${!this.matchCount}
|
|
577
|
-
label=${this.findPreviousLabel}
|
|
578
|
-
@click=${() => this.search(true)}
|
|
579
|
-
@helix-press=${stopPress}
|
|
580
|
-
>
|
|
581
|
-
<slot name="find-previous-icon">${drawIcon(caretUp)}</slot>
|
|
582
|
-
</${button}><${tip} for="find-previous" content=${this.findPreviousLabel} 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}>
|
|
583
|
-
<${button}
|
|
584
|
-
part="find-next"
|
|
585
|
-
id="find-next"
|
|
586
|
-
exportparts="button: find-next-button, live: find-next-live, spinner: find-next-spinner, text: find-next-text"
|
|
587
|
-
?disabled=${!this.matchCount}
|
|
588
|
-
label=${this.findNextLabel}
|
|
589
|
-
@click=${() => this.search(false)}
|
|
590
|
-
@helix-press=${stopPress}
|
|
591
|
-
>
|
|
592
|
-
<slot name="find-next-icon">${drawIcon(caretDown)}</slot>
|
|
593
|
-
</${button}><${tip} for="find-next" content=${this.findNextLabel} 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}>
|
|
594
|
-
<${button}
|
|
595
|
-
part="find-close"
|
|
596
|
-
id="find-close"
|
|
597
|
-
exportparts="button: find-close-button, live: find-close-live, spinner: find-close-spinner, text: find-close-text"
|
|
598
|
-
label=${this.findCloseLabel}
|
|
599
|
-
@click=${() => this.closeFind()}
|
|
600
|
-
@helix-press=${stopPress}
|
|
601
|
-
>
|
|
602
|
-
<slot name="find-close-icon">${drawIcon(x)}</slot>
|
|
603
|
-
</${button}><${tip} for="find-close" content=${this.findCloseLabel} 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}>
|
|
604
|
-
</${toolbar}>
|
|
605
|
-
</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}>`;
|
|
606
509
|
}
|
|
607
510
|
renderLook() {
|
|
608
511
|
return html `<span data-look hidden aria-hidden="true" style="color: transparent">
|
|
@@ -778,18 +681,6 @@ __decorate([
|
|
|
778
681
|
__decorate([
|
|
779
682
|
state()
|
|
780
683
|
], HelixHeadlessTerminal.prototype, "findOpen", void 0);
|
|
781
|
-
__decorate([
|
|
782
|
-
state()
|
|
783
|
-
], HelixHeadlessTerminal.prototype, "query", void 0);
|
|
784
|
-
__decorate([
|
|
785
|
-
state()
|
|
786
|
-
], HelixHeadlessTerminal.prototype, "matchIndex", void 0);
|
|
787
|
-
__decorate([
|
|
788
|
-
state()
|
|
789
|
-
], HelixHeadlessTerminal.prototype, "matchCount", void 0);
|
|
790
|
-
__decorate([
|
|
791
|
-
state()
|
|
792
|
-
], HelixHeadlessTerminal.prototype, "invalid", void 0);
|
|
793
684
|
__decorate([
|
|
794
685
|
state()
|
|
795
686
|
], HelixHeadlessTerminal.prototype, "tabMovesFocus", void 0);
|
|
@@ -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>`;
|