fix(ui): command palette accessibility, theme handling, and edge cases

This commit is contained in:
akane 2026-03-21 11:56:34 -07:00
parent d75f0e3196
commit 7e56fc5030
3 changed files with 33 additions and 6 deletions

View file

@ -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>&uarr;&darr;</kbd> navigate</span>
<span class="command-palette-hint"><kbd>&crarr;</kbd> select</span>

View file

@ -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');

View file

@ -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;