mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-06 20:10:12 +02:00
fix tab index on command palette play buttons
This commit is contained in:
@@ -134,6 +134,7 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
||||
const [pages, setPages] = useState<CommandPalettePages[]>([CommandPalettePages.HOME]);
|
||||
const activePage = pages[pages.length - 1];
|
||||
const isHome = activePage === CommandPalettePages.HOME;
|
||||
const commandRootRef = useRef<HTMLDivElement>(null);
|
||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const popPage = useCallback(() => {
|
||||
@@ -189,8 +190,33 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
||||
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
||||
searchInputRef.current?.focus();
|
||||
}
|
||||
|
||||
if (e.key === 'Tab' && !e.shiftKey) {
|
||||
const root = commandRootRef.current;
|
||||
if (!root) return;
|
||||
|
||||
const selectedItem = root.querySelector(
|
||||
'[cmdk-item][aria-selected="true"]',
|
||||
) as HTMLElement | null;
|
||||
|
||||
if (!selectedItem) return;
|
||||
|
||||
const focusTarget = selectedItem.querySelector(
|
||||
'button:not([disabled]), [tabindex]:not([tabindex="-1"])',
|
||||
) as HTMLElement | null;
|
||||
|
||||
if (!focusTarget) return;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
focusTarget.focus();
|
||||
});
|
||||
}
|
||||
}}
|
||||
onValueChange={setValue}
|
||||
ref={commandRootRef}
|
||||
value={value}
|
||||
>
|
||||
<CommandPaletteSearch
|
||||
|
||||
@@ -32,3 +32,14 @@
|
||||
background: alpha(var(--theme-colors-foreground-muted), 0.3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
width: var(--theme-font-size-sm);
|
||||
height: var(--theme-font-size-sm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,24 @@ import { Text } from '/@/shared/components/text/text';
|
||||
import { ExplicitStatus, LibraryItem, Song } from '/@/shared/types/domain-types';
|
||||
import { Play } from '/@/shared/types/types';
|
||||
|
||||
const createPlayKeyDownHandler = (
|
||||
playType: Play,
|
||||
disabled: boolean,
|
||||
onPlay: (type: Play) => void,
|
||||
) => {
|
||||
return (e: React.KeyboardEvent) => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (!disabled) {
|
||||
onPlay(playType);
|
||||
}
|
||||
} else if (e.key === 'Tab') {
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
interface LibraryCommandItemProps {
|
||||
disabled?: boolean;
|
||||
explicitStatus?: ExplicitStatus | null;
|
||||
@@ -119,29 +137,47 @@ export const LibraryCommandItem = ({
|
||||
</div>
|
||||
</div>
|
||||
{showControls && (
|
||||
<ActionIconGroup>
|
||||
<ActionIconGroup className={styles.controls}>
|
||||
<PlayTooltip disabled={disabled} type={Play.NOW}>
|
||||
<ActionIcon
|
||||
icon="mediaPlay"
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
variant="default"
|
||||
{...handlePlayNow.handlers}
|
||||
{...handlePlayNow.props}
|
||||
onKeyDown={createPlayKeyDownHandler(
|
||||
Play.NOW,
|
||||
Boolean(disabled ?? handlePlayNow.props.disabled),
|
||||
handlePlay,
|
||||
)}
|
||||
/>
|
||||
</PlayTooltip>
|
||||
<PlayTooltip disabled={disabled} type={Play.NEXT}>
|
||||
<ActionIcon
|
||||
icon="mediaPlayNext"
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
variant="default"
|
||||
{...handlePlayNext.handlers}
|
||||
{...handlePlayNext.props}
|
||||
onKeyDown={createPlayKeyDownHandler(
|
||||
Play.NEXT,
|
||||
Boolean(disabled ?? handlePlayNext.props.disabled),
|
||||
handlePlay,
|
||||
)}
|
||||
/>
|
||||
</PlayTooltip>
|
||||
<PlayTooltip disabled={disabled} type={Play.LAST}>
|
||||
<ActionIcon
|
||||
icon="mediaPlayLast"
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
variant="default"
|
||||
{...handlePlayLast.handlers}
|
||||
{...handlePlayLast.props}
|
||||
onKeyDown={createPlayKeyDownHandler(
|
||||
Play.LAST,
|
||||
Boolean(disabled ?? handlePlayLast.props.disabled),
|
||||
handlePlay,
|
||||
)}
|
||||
/>
|
||||
</PlayTooltip>
|
||||
</ActionIconGroup>
|
||||
|
||||
Reference in New Issue
Block a user