@dodlhuat/basix 1.2.8 → 1.2.9
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/package.json +1 -1
- package/js/bottom-sheet.ts +0 -224
- package/js/calendar.ts +0 -774
- package/js/carousel.ts +0 -222
- package/js/chart.ts +0 -694
- package/js/code-viewer.ts +0 -188
- package/js/context-menu.ts +0 -252
- package/js/datepicker.ts +0 -640
- package/js/dropdown.ts +0 -180
- package/js/editor.ts +0 -492
- package/js/file-uploader.ts +0 -361
- package/js/flyout-menu.ts +0 -255
- package/js/gallery.ts +0 -237
- package/js/group-picker.ts +0 -451
- package/js/lightbox.ts +0 -333
- package/js/modal.ts +0 -171
- package/js/popover.ts +0 -221
- package/js/position.ts +0 -111
- package/js/push-menu.ts +0 -286
- package/js/range-slider.ts +0 -33
- package/js/scroll.ts +0 -47
- package/js/scrollbar.ts +0 -335
- package/js/select.ts +0 -235
- package/js/sidebar-nav.ts +0 -66
- package/js/stepper.ts +0 -109
- package/js/table.ts +0 -459
- package/js/tabs.ts +0 -280
- package/js/theme.ts +0 -235
- package/js/timepicker.ts +0 -202
- package/js/toast.ts +0 -134
- package/js/tooltip.ts +0 -196
- package/js/tree.ts +0 -244
- package/js/tsconfig.json +0 -19
- package/js/utils.ts +0 -119
- package/js/virtual-dropdown.ts +0 -396
package/js/code-viewer.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
type SupportedLanguage = 'javascript' | 'js' | 'html' | 'css';
|
|
2
|
-
|
|
3
|
-
class CodeViewer {
|
|
4
|
-
private container: HTMLElement;
|
|
5
|
-
private code: string;
|
|
6
|
-
private language: string;
|
|
7
|
-
|
|
8
|
-
constructor(elementOrSelector: string | HTMLElement, code: string, language: SupportedLanguage = 'javascript') {
|
|
9
|
-
const element = typeof elementOrSelector === 'string'
|
|
10
|
-
? document.querySelector<HTMLElement>(elementOrSelector)
|
|
11
|
-
: elementOrSelector;
|
|
12
|
-
|
|
13
|
-
if (!element) {
|
|
14
|
-
throw new Error(`CodeViewer: Element not found for selector "${elementOrSelector}"`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
this.container = element;
|
|
18
|
-
this.code = code;
|
|
19
|
-
this.language = language.toLowerCase();
|
|
20
|
-
this.render();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
private highlight(code: string): string {
|
|
24
|
-
switch(this.language) {
|
|
25
|
-
case 'javascript':
|
|
26
|
-
case 'js':
|
|
27
|
-
return this.highlightJavaScript(code);
|
|
28
|
-
case 'html':
|
|
29
|
-
return this.highlightHTML(code);
|
|
30
|
-
case 'css':
|
|
31
|
-
return this.highlightCSS(code);
|
|
32
|
-
default:
|
|
33
|
-
return this.escape(code);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private escape(str: string): string {
|
|
38
|
-
return str
|
|
39
|
-
.replace(/&/g, '&')
|
|
40
|
-
.replace(/</g, '<')
|
|
41
|
-
.replace(/>/g, '>')
|
|
42
|
-
.replace(/"/g, '"')
|
|
43
|
-
.replace(/'/g, ''');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private highlightJavaScript(code: string): string {
|
|
47
|
-
const strings: string[] = [];
|
|
48
|
-
|
|
49
|
-
code = code.replace(/`(?:[^`\\]|\\[\s\S])*`/g, (match) => {
|
|
50
|
-
strings.push(match);
|
|
51
|
-
return `###STRING${strings.length - 1}###`;
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
code = code.replace(/"(?:[^"\\]|\\[\s\S])*"/g, (match) => {
|
|
55
|
-
strings.push(match);
|
|
56
|
-
return `###STRING${strings.length - 1}###`;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
code = code.replace(/'(?:[^'\\]|\\[\s\S])*'/g, (match) => {
|
|
60
|
-
strings.push(match);
|
|
61
|
-
return `###STRING${strings.length - 1}###`;
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const comments: string[] = [];
|
|
65
|
-
code = code.replace(/(\/\/.*$)/gm, (match) => {
|
|
66
|
-
comments.push(match);
|
|
67
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
68
|
-
});
|
|
69
|
-
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
70
|
-
comments.push(match);
|
|
71
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
code = this.escape(code);
|
|
75
|
-
|
|
76
|
-
const keywords = 'const|let|var|function|class|if|else|for|while|return|new|this|super|extends|import|export|from|default|async|await|try|catch|throw|switch|case|break|continue';
|
|
77
|
-
code = code.replace(new RegExp(`\\b(${keywords})\\b`, 'g'), '<span class="keyword">$1</span>');
|
|
78
|
-
|
|
79
|
-
code = code.replace(/\b(\d+(?:\.\d+)?)\b/g, '<span class="number">$1</span>');
|
|
80
|
-
|
|
81
|
-
strings.forEach((str, i) => {
|
|
82
|
-
code = code.replace(`###STRING${i}###`, '<span class="string">' + this.escape(str) + '</span>');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
comments.forEach((comment, i) => {
|
|
86
|
-
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + this.escape(comment) + '</span>');
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
return code;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private highlightHTML(code: string): string {
|
|
93
|
-
code = this.escape(code);
|
|
94
|
-
|
|
95
|
-
code = code.replace(/(<!--[\s\S]*?-->)/g, '###COMMENT_START###$1###COMMENT_END###');
|
|
96
|
-
|
|
97
|
-
code = code.replace(/(<\/?)([a-zA-Z0-9]+)([^&]*?)(>)/g, (match, open, tagName, attrs, close) => {
|
|
98
|
-
attrs = attrs.replace(/\s+([a-zA-Z-]+)(=?)("[^&]*?"|'[^&]*?')?/g, (m: string, attrName: string, eq: string, attrValue?: string) => {
|
|
99
|
-
let result = ' <span class="attribute">' + attrName + '</span>';
|
|
100
|
-
if (eq) result += eq;
|
|
101
|
-
if (attrValue) result += '<span class="string">' + attrValue + '</span>';
|
|
102
|
-
return result;
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return open + '<span class="tag">' + tagName + '</span>' + attrs + '<span class="punctuation">' + close + '</span>';
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
code = code.replace(/###COMMENT_START###(.*?)###COMMENT_END###/g, '<span class="comment">$1</span>');
|
|
109
|
-
|
|
110
|
-
return code;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private highlightCSS(code: string): string {
|
|
114
|
-
code = this.escape(code);
|
|
115
|
-
|
|
116
|
-
const comments: string[] = [];
|
|
117
|
-
code = code.replace(/(\/\*[\s\S]*?\*\/)/g, (match) => {
|
|
118
|
-
comments.push(match);
|
|
119
|
-
return `###COMMENT${comments.length - 1}###`;
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const strings: string[] = [];
|
|
123
|
-
code = code.replace(/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/g, (match) => {
|
|
124
|
-
strings.push(match);
|
|
125
|
-
return `###STRING${strings.length - 1}###`;
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
code = code.replace(/^([^{]+)(?={)/gm, (match) => {
|
|
129
|
-
return '<span class="selector">' + match.trim() + '</span>';
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
code = code.replace(/([a-z-]+)(\s*):/gi, '<span class="property">$1</span>$2:');
|
|
133
|
-
|
|
134
|
-
code = code.replace(/:\s*([0-9.]+(?:px|em|rem|%|vh|vw|s|ms)?)/g, ': <span class="number">$1</span>');
|
|
135
|
-
|
|
136
|
-
strings.forEach((str, i) => {
|
|
137
|
-
code = code.replace(`###STRING${i}###`, '<span class="string">' + str + '</span>');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
comments.forEach((comment, i) => {
|
|
141
|
-
code = code.replace(`###COMMENT${i}###`, '<span class="comment">' + comment + '</span>');
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
return code;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private async copyCode(): Promise<void> {
|
|
148
|
-
try {
|
|
149
|
-
await navigator.clipboard.writeText(this.code);
|
|
150
|
-
const btn = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
151
|
-
|
|
152
|
-
if (!btn) return;
|
|
153
|
-
|
|
154
|
-
btn.textContent = 'copied!';
|
|
155
|
-
btn.classList.add('copied');
|
|
156
|
-
|
|
157
|
-
setTimeout(() => {
|
|
158
|
-
btn.textContent = 'Copy';
|
|
159
|
-
btn.classList.remove('copied');
|
|
160
|
-
}, 2000);
|
|
161
|
-
} catch (err) {
|
|
162
|
-
console.error('Error:', err);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private render(): void {
|
|
167
|
-
const highlighted = this.highlight(this.code);
|
|
168
|
-
|
|
169
|
-
this.container.innerHTML = `
|
|
170
|
-
<div class="code-display">
|
|
171
|
-
<div class="code-header">
|
|
172
|
-
<span class="code-language">${this.language}</span>
|
|
173
|
-
<button class="copy-button">Copy</button>
|
|
174
|
-
</div>
|
|
175
|
-
<div class="code-content">
|
|
176
|
-
<pre>${highlighted}</pre>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
`;
|
|
180
|
-
|
|
181
|
-
const copyButton = this.container.querySelector<HTMLButtonElement>('.copy-button');
|
|
182
|
-
if (copyButton) {
|
|
183
|
-
copyButton.addEventListener('click', () => this.copyCode());
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
export { CodeViewer };
|
|
188
|
-
export type { SupportedLanguage };
|
package/js/context-menu.ts
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
interface ContextMenuItemDef {
|
|
2
|
-
label: string;
|
|
3
|
-
icon?: string;
|
|
4
|
-
shortcut?: string;
|
|
5
|
-
disabled?: boolean;
|
|
6
|
-
destructive?: boolean;
|
|
7
|
-
action?: (target: HTMLElement) => void;
|
|
8
|
-
submenu?: ContextMenuInput[];
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type ContextMenuInput = ContextMenuItemDef | 'separator' | { group: string };
|
|
12
|
-
|
|
13
|
-
class ContextMenu {
|
|
14
|
-
private items: ContextMenuInput[];
|
|
15
|
-
private targets: HTMLElement[];
|
|
16
|
-
private menuEl: HTMLElement | null = null;
|
|
17
|
-
private currentTarget: HTMLElement | null = null;
|
|
18
|
-
private abortController = new AbortController();
|
|
19
|
-
|
|
20
|
-
constructor(
|
|
21
|
-
selectorOrElement: string | HTMLElement | HTMLElement[],
|
|
22
|
-
items: ContextMenuInput[]
|
|
23
|
-
) {
|
|
24
|
-
this.items = items;
|
|
25
|
-
|
|
26
|
-
if (typeof selectorOrElement === 'string') {
|
|
27
|
-
this.targets = Array.from(document.querySelectorAll<HTMLElement>(selectorOrElement));
|
|
28
|
-
} else if (Array.isArray(selectorOrElement)) {
|
|
29
|
-
this.targets = selectorOrElement;
|
|
30
|
-
} else {
|
|
31
|
-
this.targets = [selectorOrElement];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
this.init();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private init(): void {
|
|
38
|
-
const { signal } = this.abortController;
|
|
39
|
-
|
|
40
|
-
this.targets.forEach((target) => {
|
|
41
|
-
target.addEventListener('contextmenu', (e: MouseEvent) => {
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
this.currentTarget = target;
|
|
44
|
-
this.open(e.clientX, e.clientY);
|
|
45
|
-
}, { signal });
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
document.addEventListener('click', () => this.close(), { signal });
|
|
49
|
-
|
|
50
|
-
// Close on right-click outside the menu
|
|
51
|
-
document.addEventListener('contextmenu', (e: MouseEvent) => {
|
|
52
|
-
if (this.menuEl && !this.menuEl.contains(e.target as Node)) {
|
|
53
|
-
this.close();
|
|
54
|
-
}
|
|
55
|
-
}, { signal, capture: true });
|
|
56
|
-
|
|
57
|
-
document.addEventListener('keydown', (e: KeyboardEvent) => {
|
|
58
|
-
if (!this.menuEl) return;
|
|
59
|
-
if (e.key === 'Escape') { this.close(); }
|
|
60
|
-
if (e.key === 'ArrowDown') { e.preventDefault(); this.moveFocus(1); }
|
|
61
|
-
if (e.key === 'ArrowUp') { e.preventDefault(); this.moveFocus(-1); }
|
|
62
|
-
if (e.key === 'Enter') { e.preventDefault(); this.activateFocused(); }
|
|
63
|
-
}, { signal });
|
|
64
|
-
|
|
65
|
-
// Close on scroll outside the menu
|
|
66
|
-
window.addEventListener('scroll', (e: Event) => {
|
|
67
|
-
if (!this.menuEl?.contains(e.target as Node)) this.close();
|
|
68
|
-
}, { signal, capture: true });
|
|
69
|
-
|
|
70
|
-
window.addEventListener('resize', () => this.close(), { signal });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
private open(x: number, y: number): void {
|
|
74
|
-
this.close();
|
|
75
|
-
|
|
76
|
-
this.menuEl = this.buildMenu(this.items);
|
|
77
|
-
document.body.appendChild(this.menuEl);
|
|
78
|
-
|
|
79
|
-
// Use offsetWidth/offsetHeight — unaffected by CSS transform
|
|
80
|
-
const w = this.menuEl.offsetWidth;
|
|
81
|
-
const h = this.menuEl.offsetHeight;
|
|
82
|
-
const vw = window.innerWidth;
|
|
83
|
-
const vh = window.innerHeight;
|
|
84
|
-
|
|
85
|
-
const left = x + w > vw ? vw - w - 8 : x;
|
|
86
|
-
const top = y + h > vh ? vh - h - 8 : y;
|
|
87
|
-
|
|
88
|
-
// Set transform-origin to match the corner the menu opens from
|
|
89
|
-
const originX = x + w > vw ? 'right' : 'left';
|
|
90
|
-
const originY = y + h > vh ? 'bottom' : 'top';
|
|
91
|
-
|
|
92
|
-
this.menuEl.style.left = `${left}px`;
|
|
93
|
-
this.menuEl.style.top = `${top}px`;
|
|
94
|
-
this.menuEl.style.transformOrigin = `${originY} ${originX}`;
|
|
95
|
-
|
|
96
|
-
requestAnimationFrame(() => this.menuEl?.classList.add('is-visible'));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
private close(): void {
|
|
100
|
-
if (!this.menuEl) return;
|
|
101
|
-
const el = this.menuEl;
|
|
102
|
-
this.menuEl = null;
|
|
103
|
-
|
|
104
|
-
el.classList.remove('is-visible');
|
|
105
|
-
|
|
106
|
-
// Wait for exit transition then remove from DOM
|
|
107
|
-
el.addEventListener('transitionend', () => el.remove(), { once: true });
|
|
108
|
-
setTimeout(() => el.isConnected && el.remove(), 200);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
private buildMenu(items: ContextMenuInput[]): HTMLElement {
|
|
112
|
-
const ul = document.createElement('ul');
|
|
113
|
-
ul.className = 'context-menu';
|
|
114
|
-
|
|
115
|
-
for (const item of items) {
|
|
116
|
-
if (item === 'separator') {
|
|
117
|
-
const li = document.createElement('li');
|
|
118
|
-
li.className = 'context-menu-separator';
|
|
119
|
-
ul.appendChild(li);
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if ('group' in item) {
|
|
124
|
-
const li = document.createElement('li');
|
|
125
|
-
li.className = 'context-menu-group-label';
|
|
126
|
-
li.textContent = item.group;
|
|
127
|
-
ul.appendChild(li);
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
ul.appendChild(this.buildItem(item));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return ul;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private buildItem(def: ContextMenuItemDef): HTMLElement {
|
|
138
|
-
const li = document.createElement('li');
|
|
139
|
-
li.className = 'context-menu-item';
|
|
140
|
-
|
|
141
|
-
if (def.disabled) li.classList.add('is-disabled');
|
|
142
|
-
if (def.destructive) li.classList.add('is-destructive');
|
|
143
|
-
if (def.submenu) li.classList.add('has-submenu');
|
|
144
|
-
|
|
145
|
-
// Always render icon slot — keeps label column aligned across all items
|
|
146
|
-
const iconWrap = document.createElement('span');
|
|
147
|
-
iconWrap.className = 'context-menu-icon';
|
|
148
|
-
if (def.icon) {
|
|
149
|
-
iconWrap.innerHTML = `<svg class="icon-svg"><use href="svg-icons/icons.svg#${def.icon}"/></svg>`;
|
|
150
|
-
}
|
|
151
|
-
li.appendChild(iconWrap);
|
|
152
|
-
|
|
153
|
-
const label = document.createElement('span');
|
|
154
|
-
label.className = 'context-menu-label';
|
|
155
|
-
label.textContent = def.label;
|
|
156
|
-
li.appendChild(label);
|
|
157
|
-
|
|
158
|
-
if (def.shortcut) {
|
|
159
|
-
const sc = document.createElement('span');
|
|
160
|
-
sc.className = 'context-menu-shortcut';
|
|
161
|
-
sc.textContent = def.shortcut;
|
|
162
|
-
li.appendChild(sc);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (def.submenu) {
|
|
166
|
-
const chevron = document.createElement('span');
|
|
167
|
-
chevron.className = 'context-menu-chevron';
|
|
168
|
-
li.appendChild(chevron);
|
|
169
|
-
|
|
170
|
-
const submenuEl = this.buildMenu(def.submenu);
|
|
171
|
-
li.appendChild(submenuEl);
|
|
172
|
-
|
|
173
|
-
// Determine flip synchronously from parent position — no rAF flash
|
|
174
|
-
const shouldFlip = (): boolean => {
|
|
175
|
-
const rect = li.getBoundingClientRect();
|
|
176
|
-
return rect.right + submenuEl.offsetWidth > window.innerWidth;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// Delay timer prevents the submenu closing when mouse travels from
|
|
180
|
-
// item → submenu (mouseleave fires before mouseenter on the submenu)
|
|
181
|
-
let closeTimer: ReturnType<typeof setTimeout> | null = null;
|
|
182
|
-
|
|
183
|
-
const openSub = () => {
|
|
184
|
-
if (closeTimer) { clearTimeout(closeTimer); closeTimer = null; }
|
|
185
|
-
this.closeAllSubmenus(li.closest<HTMLElement>('.context-menu')!);
|
|
186
|
-
li.classList.toggle('submenu-flip', shouldFlip());
|
|
187
|
-
li.classList.add('is-active');
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
const closeSub = () => {
|
|
191
|
-
closeTimer = setTimeout(() => li.classList.remove('is-active'), 120);
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
li.addEventListener('mouseenter', openSub);
|
|
195
|
-
li.addEventListener('mouseleave', closeSub);
|
|
196
|
-
submenuEl.addEventListener('mouseenter', () => {
|
|
197
|
-
if (closeTimer) { clearTimeout(closeTimer); closeTimer = null; }
|
|
198
|
-
});
|
|
199
|
-
submenuEl.addEventListener('mouseleave', closeSub);
|
|
200
|
-
} else if (!def.disabled) {
|
|
201
|
-
li.addEventListener('click', (e: MouseEvent) => {
|
|
202
|
-
e.stopPropagation();
|
|
203
|
-
def.action?.(this.currentTarget!);
|
|
204
|
-
this.close();
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return li;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private closeAllSubmenus(menu: HTMLElement): void {
|
|
212
|
-
// Only close direct-child submenus of this menu level
|
|
213
|
-
Array.from(menu.children).forEach((child) => {
|
|
214
|
-
child.classList.remove('is-active');
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
private getFocusableItems(): HTMLElement[] {
|
|
219
|
-
if (!this.menuEl) return [];
|
|
220
|
-
return Array.from(
|
|
221
|
-
this.menuEl.children
|
|
222
|
-
).filter(
|
|
223
|
-
(el): el is HTMLElement =>
|
|
224
|
-
el.classList.contains('context-menu-item') &&
|
|
225
|
-
!el.classList.contains('is-disabled')
|
|
226
|
-
) as HTMLElement[];
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
private moveFocus(direction: 1 | -1): void {
|
|
230
|
-
const items = this.getFocusableItems();
|
|
231
|
-
if (!items.length) return;
|
|
232
|
-
|
|
233
|
-
const currentIndex = items.findIndex((el) => el.classList.contains('is-focused'));
|
|
234
|
-
const nextIndex = (currentIndex + direction + items.length) % items.length;
|
|
235
|
-
|
|
236
|
-
items[currentIndex]?.classList.remove('is-focused');
|
|
237
|
-
items[nextIndex].classList.add('is-focused');
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private activateFocused(): void {
|
|
241
|
-
this.menuEl
|
|
242
|
-
?.querySelector<HTMLElement>('.context-menu-item.is-focused')
|
|
243
|
-
?.click();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
public destroy(): void {
|
|
247
|
-
this.close();
|
|
248
|
-
this.abortController.abort();
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export { ContextMenu, type ContextMenuInput, type ContextMenuItemDef };
|