@fusion.dev/helix-headless 0.215.2 → 0.216.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.json +1 -1
- package/custom-elements.json +1 -1
- package/dist/area-chart/root/area-chart-root.d.ts +1 -0
- package/dist/area-chart/root/area-chart-root.js +1 -1
- package/dist/bar-chart/root/bar-chart-root.d.ts +1 -0
- package/dist/bar-chart/root/bar-chart-root.js +1 -1
- package/dist/button/root/button-root.d.ts +3 -1
- package/dist/button/root/button-root.js +2 -1
- package/dist/chat/composer/chat-composer.d.ts +18 -1
- package/dist/chat/composer/chat-composer.js +8 -3
- package/dist/checkbox/root/checkbox-root.d.ts +3 -1
- package/dist/checkbox/root/checkbox-root.js +2 -1
- package/dist/code-block/highlight.d.ts +9 -0
- package/dist/code-block/highlight.js +39 -0
- package/dist/code-block/highlighter.d.ts +44 -0
- package/dist/code-block/highlighter.js +44 -0
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/keyed-lines.d.ts +23 -0
- package/dist/code-block/keyed-lines.js +75 -0
- package/dist/code-block/root/code-block-root.d.ts +6 -23
- package/dist/code-block/root/code-block-root.js +8 -25
- package/dist/code-editor/index.d.ts +1 -0
- package/dist/code-editor/index.js +1 -0
- package/dist/code-editor/root/code-editor-root.d.ts +367 -0
- package/dist/code-editor/root/code-editor-root.js +746 -0
- package/dist/code-input/index.d.ts +1 -0
- package/dist/code-input/index.js +1 -0
- package/dist/code-input/root/code-input-root.d.ts +119 -0
- package/dist/code-input/root/code-input-root.js +142 -0
- package/dist/combobox/root/combobox-root.d.ts +6 -1
- package/dist/combobox/root/combobox-root.js +4 -2
- package/dist/command/root/command-root.d.ts +61 -11
- package/dist/command/root/command-root.js +88 -3
- package/dist/donut-chart/root/donut-chart-root.d.ts +1 -0
- package/dist/donut-chart/root/donut-chart-root.js +1 -1
- package/dist/element-events.generated.js +36 -3
- package/dist/filter-input/root/filter-input-root.d.ts +9 -1
- package/dist/filter-input/root/filter-input-root.js +7 -3
- package/dist/heatmap/root/heatmap-root.d.ts +1 -0
- package/dist/heatmap/root/heatmap-root.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/input/root/input-root.d.ts +14 -2
- package/dist/input/root/input-root.js +11 -3
- package/dist/kbd/root/kbd-root.js +9 -2
- package/dist/line-chart/root/line-chart-root.d.ts +1 -0
- package/dist/line-chart/root/line-chart-root.js +1 -1
- package/dist/listbox/root/listbox-root.d.ts +8 -1
- package/dist/listbox/root/listbox-root.js +7 -4
- package/dist/markdown/blocks.d.ts +66 -0
- package/dist/markdown/blocks.js +326 -0
- package/dist/markdown/index.d.ts +6 -0
- package/dist/markdown/index.js +5 -0
- package/dist/markdown/inline.d.ts +57 -0
- package/dist/markdown/inline.js +483 -0
- package/dist/markdown/root/markdown-root.d.ts +99 -0
- package/dist/markdown/root/markdown-root.js +93 -0
- package/dist/markdown/stream.d.ts +47 -0
- package/dist/markdown/stream.js +62 -0
- package/dist/markdown/tree.d.ts +57 -0
- package/dist/markdown/tree.js +144 -0
- package/dist/markdown/writer.d.ts +33 -0
- package/dist/markdown/writer.js +139 -0
- package/dist/menu/root/menu-root.d.ts +53 -0
- package/dist/menu/root/menu-root.js +92 -15
- package/dist/pagination/size/pagination-size.d.ts +3 -0
- package/dist/pagination/size/pagination-size.js +2 -1
- package/dist/scatter-chart/root/scatter-chart-root.d.ts +1 -0
- package/dist/scatter-chart/root/scatter-chart-root.js +1 -1
- package/dist/select/root/select-root.d.ts +6 -1
- package/dist/select/root/select-root.js +4 -2
- package/dist/shortcut-overlay/index.d.ts +1 -0
- package/dist/shortcut-overlay/index.js +1 -0
- package/dist/shortcut-overlay/root/shortcut-overlay-root.d.ts +128 -0
- package/dist/shortcut-overlay/root/shortcut-overlay-root.js +275 -0
- package/dist/slider/root/slider-root.d.ts +3 -1
- package/dist/slider/root/slider-root.js +2 -1
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.d.ts +1 -0
- package/dist/spatial-bar-chart/root/spatial-bar-chart-root.js +1 -1
- package/dist/spatial-heatmap/root/spatial-heatmap-root.d.ts +1 -0
- package/dist/spatial-heatmap/root/spatial-heatmap-root.js +1 -1
- package/dist/spatial-ribbon-chart/root/spatial-ribbon-chart-root.d.ts +1 -0
- package/dist/spatial-ribbon-chart/root/spatial-ribbon-chart-root.js +1 -1
- package/dist/spatial-scatter-chart/root/spatial-scatter-chart-root.d.ts +1 -0
- package/dist/spatial-scatter-chart/root/spatial-scatter-chart-root.js +1 -1
- package/dist/spatial-surface-chart/root/spatial-surface-chart-root.d.ts +1 -0
- package/dist/spatial-surface-chart/root/spatial-surface-chart-root.js +1 -1
- package/dist/spatial-treemap/root/spatial-treemap-root.d.ts +1 -0
- package/dist/spatial-treemap/root/spatial-treemap-root.js +1 -1
- package/dist/switch/root/switch-root.d.ts +3 -1
- package/dist/switch/root/switch-root.js +2 -1
- package/dist/tabs/tab/tab.d.ts +3 -1
- package/dist/tabs/tab/tab.js +2 -1
- package/dist/textarea/root/textarea-root.d.ts +20 -4
- package/dist/textarea/root/textarea-root.js +31 -23
- package/dist/time-input/root/time-input-root.d.ts +6 -0
- package/dist/time-input/root/time-input-root.js +4 -2
- package/dist/time-picker/root/time-picker-root.d.ts +6 -0
- package/dist/time-picker/root/time-picker-root.js +4 -2
- package/dist/toast/root/toast-root.d.ts +64 -0
- package/dist/toast/root/toast-root.js +128 -3
- package/dist/toggle/root/toggle-root.d.ts +3 -1
- package/dist/toggle/root/toggle-root.js +2 -1
- package/dist/virtual-list/root/virtual-list-root.d.ts +18 -2
- package/dist/virtual-list/root/virtual-list-root.js +103 -5
- package/examples.json +1 -1
- package/lint.json +1 -1
- package/package.json +8 -8
- package/types/jsx.d.ts +5315 -596
- package/types/svelte.d.ts +4 -0
- package/types/vue.d.ts +1085 -4
- package/types/words.d.ts +491 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/code-input-root.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './root/code-input-root.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { type CodeBlockHighlighter, HighlighterController } from '../../code-block/highlighter.js';
|
|
3
|
+
import { HelixHeadlessTextarea } from '../../textarea/root/textarea-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* @summary A field for a short piece of code, highlighted as it is typed.
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* A `Textarea` for code: the same field in a form, with the same label, hint,
|
|
9
|
+
* validation, `voice` and selection methods, drawing its text in the
|
|
10
|
+
* highlighter's colors. The reader types in a real `<textarea>`, so the caret,
|
|
11
|
+
* selection, undo, spellcheck being off and autofill being off are the
|
|
12
|
+
* platform's, and the field works before any script loads.
|
|
13
|
+
*
|
|
14
|
+
* - `language` picks the grammar, such as `json`, `css`, `ts`, `html` or `sh`.
|
|
15
|
+
* - The field grows with its text from `rows` lines to `max-rows`, and
|
|
16
|
+
* scrolls past them.
|
|
17
|
+
* - Lines keep their length and the field scrolls sideways, unless `wrap` is
|
|
18
|
+
* `soft`.
|
|
19
|
+
*
|
|
20
|
+
* **The colors are the page's choice.** Helix ships no grammar, so a page
|
|
21
|
+
* that wants color registers a highlighter once, the one Code Block uses:
|
|
22
|
+
* `import '@fusion.dev/helix-sandbox/code-block'` registers Helix's own, or
|
|
23
|
+
* `registerHighlighter` takes Shiki or Prism. Without one the code is drawn
|
|
24
|
+
* plain, and `highlight` sets one for a single field.
|
|
25
|
+
*
|
|
26
|
+
* For a whole file, with line numbers, folding, search and problems listed by
|
|
27
|
+
* line, use `Code Editor`. Code Input is for a few dozen lines in a form: a
|
|
28
|
+
* setting in JSON, a style rule, a query, a template.
|
|
29
|
+
*
|
|
30
|
+
* **Keyboard.** Tab indents the line, or every line the selection touches,
|
|
31
|
+
* and Shift+Tab takes the indent away. Enter starts the next line at the same
|
|
32
|
+
* indent. Escape then Tab leaves the field, so it is never a trap for a reader
|
|
33
|
+
* without a pointer.
|
|
34
|
+
*
|
|
35
|
+
* @since 0.216.0
|
|
36
|
+
* @status experimental
|
|
37
|
+
* @category forms
|
|
38
|
+
* @aliases Code field, Code textarea, JSON input, Syntax highlighted input
|
|
39
|
+
* @documentation https://fusion.dev/helix/components/code-input
|
|
40
|
+
*
|
|
41
|
+
* @slot clear-icon - Replaces the cross on the clear button, under `clearable`.
|
|
42
|
+
* @slot end - After the code, for an icon or an action beside it.
|
|
43
|
+
* @slot feedback - The message that says what is wrong, for content richer than a string. It shows while there is a message.
|
|
44
|
+
* @slot hint - Help under the field, for content richer than the `hint` text.
|
|
45
|
+
* @slot label - The label, for content richer than the `label` text.
|
|
46
|
+
* @slot start - Before the code, for an icon.
|
|
47
|
+
*
|
|
48
|
+
* @event {Event} change - Sent from the textarea when the user finishes an edit.
|
|
49
|
+
* @event {HelixBeforeChangeEvent} helix-before-change - Fired as the text changes, and cancelable.
|
|
50
|
+
* @event {HelixBeforeListenEvent} helix-before-listen - The dictation button was pressed. Cancelable: cancel it to keep the field from listening.
|
|
51
|
+
* @event {HelixClearEvent} helix-clear - Fired after the clear button has emptied the field, after `input` and `change`.
|
|
52
|
+
* @event {HelixListenEvent} helix-listen - Dictation settled on a phrase and put it in the value, after the field's own `input`.
|
|
53
|
+
* @event {Event} input - Fired after the value changes.
|
|
54
|
+
*
|
|
55
|
+
* @csspart clear - The button that empties the field, under `clearable`.
|
|
56
|
+
* @csspart control - The textarea the reader types in, whose own text is transparent over the highlighted text.
|
|
57
|
+
* @csspart feedback - The message that says what is wrong.
|
|
58
|
+
* @csspart field - The box that holds the code.
|
|
59
|
+
* @csspart highlight - The highlighted text, drawn under the textarea.
|
|
60
|
+
* @csspart hint - Help under the field, while nothing is wrong.
|
|
61
|
+
* @csspart label - The label above the field.
|
|
62
|
+
* @csspart layers - The highlighted text and the textarea, one over the other.
|
|
63
|
+
* @csspart scroller - The box that scrolls past `max-rows`, and sideways past a long line.
|
|
64
|
+
* @csspart voice - The dictation button, under `voice`.
|
|
65
|
+
* @csspart voice-listening - The dictation button while it listens. Set alongside `voice`.
|
|
66
|
+
* @csspart voice-status - What a screen reader hears as dictation starts and stops, drawn for no one else.
|
|
67
|
+
*
|
|
68
|
+
* @cssstate blank - The field holds no text.
|
|
69
|
+
* @cssstate invalid - The control has an error to show, from the browser's validation, `validate`, or your `feedback`.
|
|
70
|
+
* @cssstate listening - While the field listens for dictation. The element sets `--dictation-level` on itself meanwhile, from 0 to 1, for a meter.
|
|
71
|
+
*/
|
|
72
|
+
export declare class HelixHeadlessCodeInput extends HelixHeadlessTextarea {
|
|
73
|
+
protected static markRules: string[];
|
|
74
|
+
/**
|
|
75
|
+
* The key this family's words are registered under, its styled tag:
|
|
76
|
+
* `registerWords('de', { 'helix-code-input': { clearLabel: 'Leeren' } })`.
|
|
77
|
+
*/
|
|
78
|
+
static words: string;
|
|
79
|
+
/**
|
|
80
|
+
* Turns the code into highlighted markup for its `language`, for this field
|
|
81
|
+
* alone. Absent, the field draws with the highlighter `registerHighlighter`
|
|
82
|
+
* gave the page, and plain where there is none. The markup is drawn as
|
|
83
|
+
* given, so it escapes the code, as every highlighter does.
|
|
84
|
+
*/
|
|
85
|
+
highlight?: CodeBlockHighlighter | undefined;
|
|
86
|
+
/** The grammar to highlight, such as `json`, `css`, `ts`, `html` or `sh`. Empty is plain text. */
|
|
87
|
+
language: string;
|
|
88
|
+
/**
|
|
89
|
+
* How long lines are drawn: `off` keeps each line its length and scrolls
|
|
90
|
+
* sideways, as code reads, and `soft` wraps at the field's edge.
|
|
91
|
+
*/
|
|
92
|
+
wrap: 'hard' | 'off' | 'soft';
|
|
93
|
+
/** Whether Escape came just before, which lets Tab leave the field. */
|
|
94
|
+
private escaped;
|
|
95
|
+
/** On the page's list of elements a highlighter registration reaches. */
|
|
96
|
+
protected readonly highlighting: HighlighterController;
|
|
97
|
+
/** The page registered another highlighter: draws again with it. */
|
|
98
|
+
highlighterChanged(): void;
|
|
99
|
+
/** The layers grow with the highlighted text, so the textarea never measures itself. */
|
|
100
|
+
protected grow(): void;
|
|
101
|
+
protected firstUpdated(changed: PropertyValues): void;
|
|
102
|
+
protected updated(changed: PropertyValues): void;
|
|
103
|
+
/** The code as markup: highlighted where a highlighter reads its language, plain otherwise. */
|
|
104
|
+
private markup;
|
|
105
|
+
/** Indents or outdents every line the selection touches, and keeps them selected. */
|
|
106
|
+
private shift;
|
|
107
|
+
private readonly handleKeydown;
|
|
108
|
+
/**
|
|
109
|
+
* The textarea over its highlighted text. The text ends in a space where
|
|
110
|
+
* the code ends in a line break, or the highlight would be a line shorter
|
|
111
|
+
* than the textarea and the caret on the last line would sit below it.
|
|
112
|
+
*/
|
|
113
|
+
protected renderControl(): TemplateResult;
|
|
114
|
+
}
|
|
115
|
+
declare global {
|
|
116
|
+
interface HTMLElementTagNameMap {
|
|
117
|
+
'helix-headless-code-input': HelixHeadlessCodeInput;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement, LAYERS_RULE, SCROLLER_RULE, SPOKEN_RULE } from '@fusion.dev/helix-core';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { highlightedLines } from '../../code-block/highlight.js';
|
|
6
|
+
import { HighlighterController, registeredHighlighter, } from '../../code-block/highlighter.js';
|
|
7
|
+
import { keyedLines } from '../../code-block/keyed-lines.js';
|
|
8
|
+
import { HelixHeadlessTextarea } from '../../textarea/root/textarea-root.js';
|
|
9
|
+
const escapeText = (text) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
10
|
+
const INDENT = ' ';
|
|
11
|
+
const lineStart = (text, at) => text.lastIndexOf('\n', at - 1) + 1;
|
|
12
|
+
const lineEnd = (text, at) => {
|
|
13
|
+
const end = text.indexOf('\n', at);
|
|
14
|
+
return end === -1 ? text.length : end;
|
|
15
|
+
};
|
|
16
|
+
const typeText = (control, text) => {
|
|
17
|
+
const typed = typeof document.execCommand === 'function' && document.execCommand('insertText', false, text);
|
|
18
|
+
if (!typed) {
|
|
19
|
+
control.setRangeText(text, control.selectionStart, control.selectionEnd, 'end');
|
|
20
|
+
control.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
let HelixHeadlessCodeInput = class HelixHeadlessCodeInput extends HelixHeadlessTextarea {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.language = '';
|
|
27
|
+
this.wrap = 'off';
|
|
28
|
+
this.escaped = false;
|
|
29
|
+
this.highlighting = new HighlighterController(this);
|
|
30
|
+
this.handleKeydown = (event) => {
|
|
31
|
+
const control = event.target;
|
|
32
|
+
if (event.key === 'Escape') {
|
|
33
|
+
this.escaped = true;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const escaped = this.escaped;
|
|
37
|
+
this.escaped = false;
|
|
38
|
+
if (this.readOnly ||
|
|
39
|
+
event.isComposing ||
|
|
40
|
+
event.altKey ||
|
|
41
|
+
event.ctrlKey ||
|
|
42
|
+
event.metaKey ||
|
|
43
|
+
!(control instanceof HTMLTextAreaElement)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (event.key === 'Tab' && !escaped) {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
const { selectionEnd, selectionStart, value } = control;
|
|
49
|
+
if (event.shiftKey || value.slice(selectionStart, selectionEnd).includes('\n')) {
|
|
50
|
+
this.shift(control, event.shiftKey);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
typeText(control, INDENT);
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (event.key === 'Enter' && !event.shiftKey) {
|
|
58
|
+
const { selectionStart, value } = control;
|
|
59
|
+
const indent = /^[ \t]*/.exec(value.slice(lineStart(value, selectionStart), selectionStart));
|
|
60
|
+
if (indent?.[0]) {
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
typeText(control, `\n${indent[0]}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
static { this.markRules = [SCROLLER_RULE, LAYERS_RULE, SPOKEN_RULE]; }
|
|
68
|
+
static { this.words = 'helix-code-input'; }
|
|
69
|
+
highlighterChanged() {
|
|
70
|
+
this.requestUpdate();
|
|
71
|
+
}
|
|
72
|
+
grow() { }
|
|
73
|
+
firstUpdated(changed) {
|
|
74
|
+
super.firstUpdated(changed);
|
|
75
|
+
const control = this.control;
|
|
76
|
+
control?.setAttribute('autocapitalize', 'off');
|
|
77
|
+
control?.setAttribute('autocorrect', 'off');
|
|
78
|
+
}
|
|
79
|
+
updated(changed) {
|
|
80
|
+
super.updated(changed);
|
|
81
|
+
const scroller = this.partNamed('scroller');
|
|
82
|
+
if (scroller && changed.has('maxRows')) {
|
|
83
|
+
scroller.style.maxBlockSize = this.maxRows ? `${this.maxRows}lh` : '';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
markup() {
|
|
87
|
+
const highlight = this.highlight ?? registeredHighlighter();
|
|
88
|
+
try {
|
|
89
|
+
const markup = highlight && this.value !== '' ? highlight(this.value, this.language) : undefined;
|
|
90
|
+
if (markup !== undefined) {
|
|
91
|
+
return highlightedLines(markup);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
globalThis.reportError?.(error);
|
|
96
|
+
}
|
|
97
|
+
return escapeText(this.value);
|
|
98
|
+
}
|
|
99
|
+
shift(control, outdent) {
|
|
100
|
+
const text = control.value;
|
|
101
|
+
const start = lineStart(text, control.selectionStart);
|
|
102
|
+
const end = lineEnd(text, Math.max(control.selectionStart, control.selectionEnd - 1));
|
|
103
|
+
const lines = text.slice(start, end).split('\n');
|
|
104
|
+
const next = lines.map((line) => outdent ? line.replace(/^(?: {1,2}|\t)/, '') : `${INDENT}${line}`);
|
|
105
|
+
const block = next.join('\n');
|
|
106
|
+
if (block === text.slice(start, end)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
control.setSelectionRange(start, end);
|
|
110
|
+
typeText(control, block);
|
|
111
|
+
control.setSelectionRange(start, start + block.length);
|
|
112
|
+
}
|
|
113
|
+
renderControl() {
|
|
114
|
+
const tail = this.value === '' || this.value.endsWith('\n') ? ' ' : '';
|
|
115
|
+
return html `<div part="scroller" data-scroller>
|
|
116
|
+
<div
|
|
117
|
+
part="layers"
|
|
118
|
+
data-layers
|
|
119
|
+
?data-wrap=${this.wrap !== 'off'}
|
|
120
|
+
spellcheck="false"
|
|
121
|
+
translate="no"
|
|
122
|
+
@keydown=${this.handleKeydown}
|
|
123
|
+
>
|
|
124
|
+
<pre part="highlight" aria-hidden="true">${keyedLines(this.markup())}${tail}</pre>
|
|
125
|
+
${super.renderControl()}
|
|
126
|
+
</div>
|
|
127
|
+
</div>`;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
__decorate([
|
|
131
|
+
property({ attribute: false })
|
|
132
|
+
], HelixHeadlessCodeInput.prototype, "highlight", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
property()
|
|
135
|
+
], HelixHeadlessCodeInput.prototype, "language", void 0);
|
|
136
|
+
__decorate([
|
|
137
|
+
property()
|
|
138
|
+
], HelixHeadlessCodeInput.prototype, "wrap", void 0);
|
|
139
|
+
HelixHeadlessCodeInput = __decorate([
|
|
140
|
+
customElement('helix-headless-code-input')
|
|
141
|
+
], HelixHeadlessCodeInput);
|
|
142
|
+
export { HelixHeadlessCodeInput };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AriaForwardController, HelixFormElement, PopoverController, UpgradeController } from '@fusion.dev/helix-core';
|
|
1
|
+
import { AriaForwardController, HelixFormElement, ListedController, PopoverController, UpgradeController } from '@fusion.dev/helix-core';
|
|
2
2
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../listbox/index.js';
|
|
4
4
|
import '../../tag/root/index.js';
|
|
@@ -120,6 +120,9 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
|
|
|
120
120
|
* @csspart listbox-loading - Shown while the options are loading.
|
|
121
121
|
* @csspart listbox-search - The region holding the field that narrows the list.
|
|
122
122
|
* @csspart listbox-search-field - The filter field inside that region.
|
|
123
|
+
* @csspart listbox-voice - The dictation button in the filter field.
|
|
124
|
+
* @csspart listbox-voice-listening - The dictation button while it listens.
|
|
125
|
+
* @csspart listbox-voice-status - What a screen reader hears as dictation starts and stops.
|
|
123
126
|
* @csspart live - The region VoiceOver hears the highlight, the count and a choice from on Apple devices, drawn once there is one to say. Visually hidden in the styled tier.
|
|
124
127
|
* @csspart rest - The count of choices held beyond `max-tags`. A `<button>` with `expandable`, a `<span>` without it.
|
|
125
128
|
* @csspart surface - The floating panel.
|
|
@@ -140,6 +143,8 @@ declare const HelixHeadlessCombobox_base: (new (...args: any[]) => import("@fusi
|
|
|
140
143
|
* @cssstate open - While the list is open.
|
|
141
144
|
*/
|
|
142
145
|
export declare class HelixHeadlessCombobox extends HelixHeadlessCombobox_base {
|
|
146
|
+
/** On the page's list of controls, where a command palette and a shortcut overlay find it. */
|
|
147
|
+
protected readonly listed: ListedController;
|
|
143
148
|
/**
|
|
144
149
|
* The key this family's words are registered under, its styled tag:
|
|
145
150
|
* `registerWords('de', { 'helix-combobox': { emptyText: 'Keine Treffer' } })`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { AriaForwardController, afterLinkFollowed, auditChildren, chosenValues, countLabel, customElement, DelayController, drawAutofill, drawStatus, formatWords, HelixCreateEvent, HelixFilterEvent, HelixFormElement, handedLocale, MixinControllerOpen, MixinControllerValue, MixinField, MixinTokens, onApple, PopoverController, reportValues, StatusController, submitImplicitly, timeConverter, UpgradeController, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { AriaForwardController, afterLinkFollowed, auditChildren, chosenValues, countLabel, customElement, DelayController, drawAutofill, drawStatus, formatWords, HelixCreateEvent, HelixFilterEvent, HelixFormElement, handedLocale, ListedController, MixinControllerOpen, MixinControllerValue, MixinField, MixinTokens, onApple, PopoverController, reportValues, StatusController, submitImplicitly, timeConverter, UpgradeController, words, wordsLocale, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { caretDown } from '@fusion.dev/helix-icons';
|
|
4
4
|
import { nothing } from 'lit';
|
|
5
5
|
import { property, state } from 'lit/decorators.js';
|
|
@@ -13,6 +13,7 @@ const isInsertion = (event) => !event.inputType?.startsWith('delete');
|
|
|
13
13
|
let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerOpen(MixinTokens(MixinControllerValue(MixinField(HelixFormElement)))) {
|
|
14
14
|
constructor() {
|
|
15
15
|
super(...arguments);
|
|
16
|
+
this.listed = new ListedController(this, 'focus', () => this.internals?.ariaKeyShortcuts);
|
|
16
17
|
this.aria = new AriaForwardController(this, {
|
|
17
18
|
target: () => this.partNamed('control'),
|
|
18
19
|
});
|
|
@@ -586,7 +587,8 @@ let HelixHeadlessCombobox = class HelixHeadlessCombobox extends MixinControllerO
|
|
|
586
587
|
exportparts="empty: listbox-empty, error: listbox-error, feedback: listbox-feedback,
|
|
587
588
|
filter-icon: listbox-filter-icon, filter-mark: listbox-filter-mark, hint: listbox-hint,
|
|
588
589
|
items: listbox-items, label: listbox-label, live: listbox-live, loading: listbox-loading,
|
|
589
|
-
search: listbox-search, search-field: listbox-search-field
|
|
590
|
+
search: listbox-search, search-field: listbox-search-field,
|
|
591
|
+
voice: listbox-voice, voice-listening: listbox-voice-listening, voice-status: listbox-voice-status"
|
|
590
592
|
aria-label=${this.listLabel}
|
|
591
593
|
empty-text=${this.emptyText}
|
|
592
594
|
load-error=${this.loadError}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type DataOptionItem, HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
-
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
3
|
import '../../dialog/index.js';
|
|
4
4
|
import '../../listbox/index.js';
|
|
5
|
+
import '../../option/index.js';
|
|
5
6
|
declare const HelixHeadlessCommand_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
|
|
6
7
|
/**
|
|
7
8
|
* @summary A command palette: a list of commands that opens from anywhere on the page and filters as you type.
|
|
@@ -72,17 +73,17 @@ declare const HelixHeadlessCommand_base: (new (...args: any[]) => import("@fusio
|
|
|
72
73
|
* Aria's `Autocomplete` is. The commands are a `listbox` of `option`s. How many commands typing left, the empty text and
|
|
73
74
|
* the loading text are said in a polite live region.
|
|
74
75
|
*
|
|
75
|
-
* **The
|
|
76
|
-
*
|
|
77
|
-
*
|
|
76
|
+
* **The palette registers Option**, since it draws the controls on screen as
|
|
77
|
+
* options itself with `controls`, so a page that writes commands imports the
|
|
78
|
+
* palette alone. A tier of your own registers its own option, and in
|
|
79
|
+
* development a palette holding one nobody registered says so.
|
|
78
80
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* the page has loaded, with the line to add.
|
|
81
|
+
* **Set `controls` to find anything on screen.** Every labeled Helix control
|
|
82
|
+
* puts itself on the page's list while it is connected, and the palette lists
|
|
83
|
+
* the ones a reader can reach under its own commands once they type, with
|
|
84
|
+
* each one's shortcut. Choosing one closes the palette and presses it, or
|
|
85
|
+
* moves focus into a field. `unlisted` on a control, or on a region around it,
|
|
86
|
+
* leaves it out.
|
|
86
87
|
*
|
|
87
88
|
* @since 0.1.0
|
|
88
89
|
* @status stable
|
|
@@ -106,6 +107,16 @@ declare const HelixHeadlessCommand_base: (new (...args: any[]) => import("@fusio
|
|
|
106
107
|
* @event {HelixSelectEvent} helix-select - A command was chosen, with its `href` where the option is a link. Cancelable: cancel it to keep the palette open, and to keep the browser from following the link.
|
|
107
108
|
* @event {ToggleEvent} toggle - The palette opened or closed. The event carries `newState` and `oldState`.
|
|
108
109
|
*
|
|
110
|
+
* @csspart control - A control on screen, listed with `controls`.
|
|
111
|
+
* @csspart control-description - Its region's name.
|
|
112
|
+
* @csspart control-item - Its row.
|
|
113
|
+
* @csspart control-item-active - Its row while the keyboard is on it.
|
|
114
|
+
* @csspart control-item-selected - Its row while selected.
|
|
115
|
+
* @csspart control-label - Its name.
|
|
116
|
+
* @csspart control-text - Its name and region, as one column.
|
|
117
|
+
* @csspart controls - The group of controls on screen.
|
|
118
|
+
* @csspart controls-items - What holds the group's controls.
|
|
119
|
+
* @csspart controls-label - The group's heading.
|
|
109
120
|
* @csspart dialog-body - The dialog's slot for its content, which holds the list. It draws no box until you give it one.
|
|
110
121
|
* @csspart dialog-dismiss - The dialog's close control, drawn when the dialog is `dismissible`.
|
|
111
122
|
* @csspart dialog-dismiss-mark - The glyph on the dialog's close control, where none is slotted.
|
|
@@ -126,6 +137,9 @@ declare const HelixHeadlessCommand_base: (new (...args: any[]) => import("@fusio
|
|
|
126
137
|
* @csspart listbox-loading - The text shown while the commands are loading.
|
|
127
138
|
* @csspart listbox-search - The region that holds the filter field.
|
|
128
139
|
* @csspart listbox-search-field - The filter field.
|
|
140
|
+
* @csspart listbox-voice - The dictation button in the filter field, under `voice`.
|
|
141
|
+
* @csspart listbox-voice-listening - The dictation button while it listens.
|
|
142
|
+
* @csspart listbox-voice-status - What a screen reader hears as dictation starts and stops.
|
|
129
143
|
* @csspart live - The region a screen reader announces the page shown from, by the words of the command that opens it, drawn once there is one to say. Visually hidden in the styled tier.
|
|
130
144
|
*
|
|
131
145
|
* @cssstate empty - The list shows no commands: there are none, or typing hid every one.
|
|
@@ -140,6 +154,19 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
140
154
|
* `registerWords('de', { 'helix-command': { placeholder: 'Befehle suchen' } })`.
|
|
141
155
|
*/
|
|
142
156
|
static words: string;
|
|
157
|
+
/**
|
|
158
|
+
* Lists the controls on screen below the palette's own commands, once the
|
|
159
|
+
* reader types: every labeled Helix button, field, tab, switch and the
|
|
160
|
+
* rest, by its name, with its shortcut. Choosing one closes the palette and
|
|
161
|
+
* presses the control, or moves focus into a field.
|
|
162
|
+
*
|
|
163
|
+
* A control that is disabled, inert, hidden or under `unlisted` is left out,
|
|
164
|
+
* and so is anything inside the palette. Off by default, so a palette used
|
|
165
|
+
* as a search box lists only what it holds.
|
|
166
|
+
*/
|
|
167
|
+
controls: boolean;
|
|
168
|
+
/** The heading over the controls on screen. */
|
|
169
|
+
controlsLabel: string;
|
|
143
170
|
/**
|
|
144
171
|
* The text shown when the filter matches no commands.
|
|
145
172
|
*/
|
|
@@ -178,6 +205,11 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
178
205
|
* with: one key, said once.
|
|
179
206
|
*/
|
|
180
207
|
hotkey: string;
|
|
208
|
+
/**
|
|
209
|
+
* What the hotkey does, as a list of the page's shortcuts says it, with
|
|
210
|
+
* `{label}` for the palette's `label`.
|
|
211
|
+
*/
|
|
212
|
+
hotkeyLabel: string;
|
|
181
213
|
/**
|
|
182
214
|
* Draws the palette in the page, where it stands, with no dialog: a search
|
|
183
215
|
* over a list of commands, as React Aria's Autocomplete is drawn.
|
|
@@ -263,6 +295,11 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
263
295
|
* {# poleceń} other {# polecenia}}`.
|
|
264
296
|
*/
|
|
265
297
|
resultsLabel: string;
|
|
298
|
+
/**
|
|
299
|
+
* Draws a dictation button in the search field, which listens through the
|
|
300
|
+
* page's speech engine and types what it hears, as a field's `voice` does.
|
|
301
|
+
*/
|
|
302
|
+
voice: boolean;
|
|
266
303
|
/**
|
|
267
304
|
* Whether the consumer put anything under the list.
|
|
268
305
|
*
|
|
@@ -359,6 +396,12 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
359
396
|
private readonly handleAlternate;
|
|
360
397
|
private readonly swallowOptionSelect;
|
|
361
398
|
connectedCallback(): void;
|
|
399
|
+
/** Takes the hotkey off the page's list of shortcuts. */
|
|
400
|
+
private unregister;
|
|
401
|
+
/** The controls on screen, read as the palette opens. */
|
|
402
|
+
private onScreen;
|
|
403
|
+
/** What the reader has typed, since the controls are listed only once they type. */
|
|
404
|
+
private typed;
|
|
362
405
|
disconnectedCallback(): void;
|
|
363
406
|
protected willUpdate(changed: PropertyValues): void;
|
|
364
407
|
protected firstUpdated(changed: PropertyValues): void;
|
|
@@ -388,6 +431,13 @@ export declare class HelixHeadlessCommand extends HelixHeadlessCommand_base {
|
|
|
388
431
|
* from the same template.
|
|
389
432
|
*/
|
|
390
433
|
protected renderDialog(): TemplateResult;
|
|
434
|
+
/** Reads the controls a reader can reach now, leaving out the palette and anything in it. */
|
|
435
|
+
private readControls;
|
|
436
|
+
/**
|
|
437
|
+
* The controls on screen as a group of options, once the reader types, on
|
|
438
|
+
* the first page and only where the commands are children.
|
|
439
|
+
*/
|
|
440
|
+
protected renderControls(): TemplateResult | typeof nothing;
|
|
391
441
|
/**
|
|
392
442
|
* The filterable list of commands, which the dialog holds, or the page with
|
|
393
443
|
* `inline`, behind a seam the styled tier can move.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { auditChildren, customElement, drawStatus, HelixElement, HelixSelectEvent, MixinControllerOpen, matchesChord, StatusController, timeConverter, words, } from '@fusion.dev/helix-core';
|
|
2
|
+
import { auditChildren, chordParts, customElement, drawStatus, formatWords, HelixElement, HelixSelectEvent, keyNames, listControls, MixinControllerOpen, matchesChord, onApple, registerShortcut, runControl, StatusController, timeConverter, words, } from '@fusion.dev/helix-core';
|
|
3
3
|
import { nothing } from 'lit';
|
|
4
4
|
import { property, state } from 'lit/decorators.js';
|
|
5
5
|
import { html } from 'lit/static-html.js';
|
|
6
6
|
import { optionsAmong } from '../../option/among.js';
|
|
7
7
|
import '../../dialog/index.js';
|
|
8
8
|
import '../../listbox/index.js';
|
|
9
|
+
import '../../option/index.js';
|
|
9
10
|
const says = (element, state) => {
|
|
10
11
|
try {
|
|
11
12
|
return element?.matches(`:state(${state})`) ?? false;
|
|
@@ -14,12 +15,16 @@ const says = (element, state) => {
|
|
|
14
15
|
return false;
|
|
15
16
|
}
|
|
16
17
|
};
|
|
18
|
+
const CONTROL = 'helix-control:';
|
|
17
19
|
let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpen(HelixElement) {
|
|
18
20
|
constructor() {
|
|
19
21
|
super(...arguments);
|
|
22
|
+
this.controls = false;
|
|
23
|
+
this.controlsLabel = 'On this screen';
|
|
20
24
|
this.emptyText = 'No commands';
|
|
21
25
|
this.filterDelay = 0;
|
|
22
26
|
this.hotkey = 'mod+k';
|
|
27
|
+
this.hotkeyLabel = 'Open {label}';
|
|
23
28
|
this.inline = false;
|
|
24
29
|
this.items = undefined;
|
|
25
30
|
this.label = 'Commands';
|
|
@@ -30,6 +35,7 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
30
35
|
this.trail = [];
|
|
31
36
|
this.placeholder = 'Search commands';
|
|
32
37
|
this.resultsLabel = '{count, plural, one {# command} other {# commands}}';
|
|
38
|
+
this.voice = false;
|
|
33
39
|
this.footed = false;
|
|
34
40
|
this.handleHotkey = (event) => {
|
|
35
41
|
if (!matchesChord(event, this.hotkey, true) && !matchesChord(event, this.hotkey, false)) {
|
|
@@ -46,6 +52,14 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
46
52
|
event.stopPropagation();
|
|
47
53
|
event.preventDefault();
|
|
48
54
|
const { value } = event.detail;
|
|
55
|
+
const control = value.startsWith(CONTROL)
|
|
56
|
+
? this.onScreen[Number(value.slice(CONTROL.length))]
|
|
57
|
+
: undefined;
|
|
58
|
+
if (control) {
|
|
59
|
+
this.requestOpen(false);
|
|
60
|
+
void this.updateComplete.then(() => runControl(control));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
49
63
|
if (!this.dispatchEvent(new HelixSelectEvent({ value }))) {
|
|
50
64
|
return;
|
|
51
65
|
}
|
|
@@ -103,7 +117,14 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
103
117
|
}
|
|
104
118
|
this.requestOpen(false);
|
|
105
119
|
};
|
|
106
|
-
this.
|
|
120
|
+
this.onScreen = [];
|
|
121
|
+
this.typed = '';
|
|
122
|
+
this.handleFilter = (event) => {
|
|
123
|
+
const typed = event.detail?.value ?? '';
|
|
124
|
+
if (this.typed.trim() === '' && typed.trim() !== '') {
|
|
125
|
+
this.readControls();
|
|
126
|
+
}
|
|
127
|
+
this.typed = typed;
|
|
107
128
|
void Promise.resolve()
|
|
108
129
|
.then(() => this.listbox?.updateComplete)
|
|
109
130
|
.then(() => this.markStatus());
|
|
@@ -148,9 +169,15 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
148
169
|
this.addEventListener('keydown', this.handleBack);
|
|
149
170
|
this.addEventListener('click', this.handleAlternate, { capture: true });
|
|
150
171
|
document.addEventListener('keydown', this.handleHotkey);
|
|
172
|
+
this.unregister = registerShortcut({
|
|
173
|
+
keys: () => (this.inline ? '' : this.hotkey),
|
|
174
|
+
label: () => formatWords(this, 'hotkeyLabel', { label: this.label }),
|
|
175
|
+
owner: this,
|
|
176
|
+
});
|
|
151
177
|
}
|
|
152
178
|
disconnectedCallback() {
|
|
153
179
|
super.disconnectedCallback();
|
|
180
|
+
this.unregister?.();
|
|
154
181
|
this.removeEventListener('helix-select', this.swallowOptionSelect);
|
|
155
182
|
this.removeEventListener('keydown', this.handleAlternate, { capture: true });
|
|
156
183
|
this.removeEventListener('keydown', this.handleBack);
|
|
@@ -196,6 +223,9 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
196
223
|
return;
|
|
197
224
|
}
|
|
198
225
|
if (this.open) {
|
|
226
|
+
this.onScreen = this.controls
|
|
227
|
+
? listControls().filter((control) => control.element !== this && !this.contains(control.element))
|
|
228
|
+
: [];
|
|
199
229
|
this.listbox?.highlight('none');
|
|
200
230
|
this.searchField?.focus();
|
|
201
231
|
}
|
|
@@ -226,13 +256,46 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
226
256
|
${this.renderFooter('footer')}
|
|
227
257
|
</${this.tag('dialog')}>`;
|
|
228
258
|
}
|
|
259
|
+
readControls() {
|
|
260
|
+
this.onScreen = this.controls
|
|
261
|
+
? listControls().filter((control) => control.element !== this && !this.contains(control.element))
|
|
262
|
+
: [];
|
|
263
|
+
}
|
|
264
|
+
renderControls() {
|
|
265
|
+
if (!this.controls ||
|
|
266
|
+
this.typed.trim() === '' ||
|
|
267
|
+
this.page !== '' ||
|
|
268
|
+
this.items !== undefined) {
|
|
269
|
+
return nothing;
|
|
270
|
+
}
|
|
271
|
+
const apple = onApple();
|
|
272
|
+
const group = this.tag('option-group');
|
|
273
|
+
const option = this.tag('option');
|
|
274
|
+
return html `<${group}
|
|
275
|
+
part="controls"
|
|
276
|
+
exportparts="items: controls-items, label: controls-label"
|
|
277
|
+
label=${this.controlsLabel}
|
|
278
|
+
>${this.onScreen.map((control, index) => {
|
|
279
|
+
const [keys] = control.keys;
|
|
280
|
+
const names = keys ? keyNames(chordParts(keys), apple) : undefined;
|
|
281
|
+
return html `<${option}
|
|
282
|
+
part="control"
|
|
283
|
+
exportparts="description: control-description, item: control-item, item-active: control-item-active,
|
|
284
|
+
item-selected: control-item-selected, label: control-label, text: control-text"
|
|
285
|
+
value=${`${CONTROL}${index}`}
|
|
286
|
+
text-value=${control.name}
|
|
287
|
+
description=${control.group || nothing}
|
|
288
|
+
>${control.name}${names ? html `<span slot="end" aria-hidden="true">${names.keys.join(names.separator)}</span>` : nothing}</${option}>`;
|
|
289
|
+
})}</${group}>`;
|
|
290
|
+
}
|
|
229
291
|
renderListbox() {
|
|
230
292
|
return html `<${this.tag('listbox')}
|
|
231
293
|
part="listbox"
|
|
232
294
|
exportparts="empty: listbox-empty, error: listbox-error, feedback: listbox-feedback,
|
|
233
295
|
filter-icon: listbox-filter-icon, filter-mark: listbox-filter-mark, hint: listbox-hint,
|
|
234
296
|
items: listbox-items, label: listbox-label, live: listbox-live, loading: listbox-loading,
|
|
235
|
-
search: listbox-search, search-field: listbox-search-field
|
|
297
|
+
search: listbox-search, search-field: listbox-search-field,
|
|
298
|
+
voice: listbox-voice, voice-listening: listbox-voice-listening, voice-status: listbox-voice-status"
|
|
236
299
|
aria-label=${this.listName}
|
|
237
300
|
empty-text=${this.emptyText}
|
|
238
301
|
filter-delay=${this.filterDelay}
|
|
@@ -247,6 +310,7 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
247
310
|
.items=${this.items}
|
|
248
311
|
.fieldHomeEnd=${this.homeEnd === 'list'}
|
|
249
312
|
layout=${this.layout ?? nothing}
|
|
313
|
+
?voice=${this.voice}
|
|
250
314
|
filterable
|
|
251
315
|
@helix-before-change=${this.handleChange}
|
|
252
316
|
@helix-filter=${this.handleFilter}
|
|
@@ -254,6 +318,7 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
254
318
|
@input=${this.stopInner}
|
|
255
319
|
>
|
|
256
320
|
${this.page === '' ? html `<slot></slot>` : html `<slot name=${`page:${this.page}`}></slot>`}
|
|
321
|
+
${this.renderControls()}
|
|
257
322
|
<!-- Handed on with the text as the fallback, for the reason Combobox
|
|
258
323
|
gives: the list's own fallback never shows behind a passed slot. -->
|
|
259
324
|
<slot name="empty" slot="empty">${this.emptyText}</slot>
|
|
@@ -290,6 +355,13 @@ let HelixHeadlessCommand = class HelixHeadlessCommand extends MixinControllerOpe
|
|
|
290
355
|
return html `${this.renderDialog()}`;
|
|
291
356
|
}
|
|
292
357
|
};
|
|
358
|
+
__decorate([
|
|
359
|
+
property({ type: Boolean })
|
|
360
|
+
], HelixHeadlessCommand.prototype, "controls", void 0);
|
|
361
|
+
__decorate([
|
|
362
|
+
words,
|
|
363
|
+
property({ attribute: 'controls-label' })
|
|
364
|
+
], HelixHeadlessCommand.prototype, "controlsLabel", void 0);
|
|
293
365
|
__decorate([
|
|
294
366
|
words,
|
|
295
367
|
property({ attribute: 'empty-text' })
|
|
@@ -306,6 +378,10 @@ __decorate([
|
|
|
306
378
|
__decorate([
|
|
307
379
|
property()
|
|
308
380
|
], HelixHeadlessCommand.prototype, "hotkey", void 0);
|
|
381
|
+
__decorate([
|
|
382
|
+
words,
|
|
383
|
+
property({ attribute: 'hotkey-label' })
|
|
384
|
+
], HelixHeadlessCommand.prototype, "hotkeyLabel", void 0);
|
|
309
385
|
__decorate([
|
|
310
386
|
property({ reflect: true, type: Boolean })
|
|
311
387
|
], HelixHeadlessCommand.prototype, "inline", void 0);
|
|
@@ -346,9 +422,18 @@ __decorate([
|
|
|
346
422
|
words,
|
|
347
423
|
property({ attribute: 'results-label' })
|
|
348
424
|
], HelixHeadlessCommand.prototype, "resultsLabel", void 0);
|
|
425
|
+
__decorate([
|
|
426
|
+
property({ type: Boolean })
|
|
427
|
+
], HelixHeadlessCommand.prototype, "voice", void 0);
|
|
349
428
|
__decorate([
|
|
350
429
|
state()
|
|
351
430
|
], HelixHeadlessCommand.prototype, "footed", void 0);
|
|
431
|
+
__decorate([
|
|
432
|
+
state()
|
|
433
|
+
], HelixHeadlessCommand.prototype, "onScreen", void 0);
|
|
434
|
+
__decorate([
|
|
435
|
+
state()
|
|
436
|
+
], HelixHeadlessCommand.prototype, "typed", void 0);
|
|
352
437
|
HelixHeadlessCommand = __decorate([
|
|
353
438
|
customElement('helix-headless-command')
|
|
354
439
|
], HelixHeadlessCommand);
|
|
@@ -78,6 +78,7 @@ declare const HelixHeadlessDonutChart_base: typeof HelixElement & (new (...args:
|
|
|
78
78
|
* @csspart segment-active - The slice under the pointer. Set alongside `segment`.
|
|
79
79
|
* @csspart segment-edge - One slice as a closed shape, used to draw its outline.
|
|
80
80
|
* @csspart slice-label - One slice's share, written on the slice under `slice-labels`. Placed with `left` and `top`, or `inset-inline-start` and `top` on a half ring, and carries its series color as `--chart-series`.
|
|
81
|
+
* @csspart sonify - The button that plays the chart as sound, under `sonify`.
|
|
81
82
|
* @csspart summary - The chart's name and each slice's share, written as a sentence for screen readers. Hide it visually.
|
|
82
83
|
* @csspart table - The readings as a table, for a screen reader, rendered only where they were drawn from `data`, a page of them at a time past a few hundred. Hide it visually.
|
|
83
84
|
* @csspart table-pages - Which readings a page of the `table` holds, and the buttons that show the previous and the next page, rendered only while it holds a page. Hide it visually.
|