fix(ui): command palette accessibility, theme handling, and edge cases
This commit is contained in:
parent
d75f0e3196
commit
7e56fc5030
3 changed files with 33 additions and 6 deletions
|
|
@ -1505,10 +1505,15 @@
|
|||
placeholder="Search commands, music, settings..."
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
aria-label="Command palette search"
|
||||
role="combobox"
|
||||
aria-expanded="true"
|
||||
aria-controls="command-palette-results"
|
||||
aria-autocomplete="list"
|
||||
/>
|
||||
<kbd class="command-palette-kbd">ESC</kbd>
|
||||
</div>
|
||||
<div id="command-palette-results" class="command-palette-results"></div>
|
||||
<div id="command-palette-results" class="command-palette-results" role="listbox"></div>
|
||||
<div class="command-palette-footer">
|
||||
<span class="command-palette-hint"><kbd>↑↓</kbd> navigate</span>
|
||||
<span class="command-palette-hint"><kbd>↵</kbd> select</span>
|
||||
|
|
|
|||
|
|
@ -642,6 +642,7 @@ class CommandPalette {
|
|||
icon: 'search',
|
||||
label: 'Search Settings...',
|
||||
keywords: ['setting', 'find', 'search', 'preference', 'option', 'configure'],
|
||||
keepOpen: true,
|
||||
action: () => this.enterSettingsMode(),
|
||||
},
|
||||
|
||||
|
|
@ -923,6 +924,7 @@ class CommandPalette {
|
|||
|
||||
appendMusicGroups(musicGroups) {
|
||||
this.removeMusicLoading();
|
||||
this.resultsContainer.querySelector('.cmdk-empty')?.remove();
|
||||
this.resultsContainer.querySelectorAll('[data-music-group]').forEach((el) => el.remove());
|
||||
|
||||
let index = this.flatItems.length;
|
||||
|
|
@ -1000,7 +1002,10 @@ class CommandPalette {
|
|||
createItemElement(item, index) {
|
||||
const el = document.createElement('div');
|
||||
el.className = 'cmdk-item';
|
||||
el.id = `cmdk-item-${index}`;
|
||||
el.setAttribute('role', 'option');
|
||||
el.setAttribute('data-index', index);
|
||||
el.setAttribute('aria-selected', index === this.selectedIndex ? 'true' : 'false');
|
||||
if (index === this.selectedIndex) el.setAttribute('data-selected', 'true');
|
||||
|
||||
let iconHtml = '';
|
||||
|
|
@ -1041,18 +1046,34 @@ class CommandPalette {
|
|||
const idx = parseInt(item.getAttribute('data-index'));
|
||||
if (idx === this.selectedIndex) {
|
||||
item.setAttribute('data-selected', 'true');
|
||||
item.setAttribute('aria-selected', 'true');
|
||||
item.scrollIntoView({ block: 'nearest' });
|
||||
} else {
|
||||
item.removeAttribute('data-selected');
|
||||
item.setAttribute('aria-selected', 'false');
|
||||
}
|
||||
});
|
||||
this.input.setAttribute('aria-activedescendant', `cmdk-item-${this.selectedIndex}`);
|
||||
}
|
||||
|
||||
executeSelected() {
|
||||
async executeSelected() {
|
||||
const item = this.flatItems[this.selectedIndex];
|
||||
if (!item || !item.action) return;
|
||||
|
||||
item.action();
|
||||
if (item.keepOpen) {
|
||||
try {
|
||||
await item.action();
|
||||
} catch (e) {
|
||||
console.error('Command palette action error:', e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await item.action();
|
||||
} catch (e) {
|
||||
console.error('Command palette action error:', e);
|
||||
}
|
||||
this.close();
|
||||
}
|
||||
|
||||
|
|
@ -1132,9 +1153,9 @@ class CommandPalette {
|
|||
}
|
||||
}
|
||||
|
||||
setTheme(theme) {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
async setTheme(theme) {
|
||||
const { themeManager } = await import('./storage.js');
|
||||
themeManager.setTheme(theme);
|
||||
const themeOptions = document.querySelectorAll('.theme-option');
|
||||
themeOptions.forEach((opt) => {
|
||||
if (opt.dataset.theme === theme) opt.classList.add('active');
|
||||
|
|
|
|||
|
|
@ -8527,6 +8527,7 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
/* stylelint-disable-next-line no-descending-specificity */
|
||||
.cmdk-item-icon img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue