feat: allow using spacebar or enter to trigger buttons

It is a good practice for accessibility.
Cf https://webaim.org/techniques/keyboard/ or
any other resource on the Internet talking about buttons accessibiltiy.
This commit is contained in:
Jef Roelandt 2024-04-23 13:24:41 +02:00
parent 42f82ab95d
commit 60cc2e9369
3 changed files with 31 additions and 8 deletions

View file

@ -7,6 +7,8 @@ import { fade } from '@/lib/motion';
import styles from './favorite.module.css'; import styles from './favorite.module.css';
import { useKeyboardButton } from '@/hooks/useKeyboardButton';
interface FavoriteProps { interface FavoriteProps {
id: string; id: string;
} }
@ -17,11 +19,16 @@ export function Favorite({ id }: FavoriteProps) {
const variants = fade(); const variants = fade();
const handleKeyDown = useKeyboardButton(() => {
toggleFavorite(id);
});
return ( return (
<AnimatePresence initial={false} mode="wait"> <AnimatePresence initial={false} mode="wait">
<button <button
aria-label="Add Sound to Favorites" aria-label="Add Sound to Favorites"
className={cn(styles.favoriteButton, isFavorite && styles.isFavorite)} className={cn(styles.favoriteButton, isFavorite && styles.isFavorite)}
onKeyDown={handleKeyDown}
onClick={e => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
toggleFavorite(id); toggleFavorite(id);

View file

@ -12,6 +12,8 @@ import styles from './sound.module.css';
import type { Sound } from '@/data/types'; import type { Sound } from '@/data/types';
import { useKeyboardButton } from '@/hooks/useKeyboardButton';
interface SoundProps extends Sound { interface SoundProps extends Sound {
functional: boolean; functional: boolean;
hidden: boolean; hidden: boolean;
@ -73,14 +75,9 @@ export function Sound({
toggle(); toggle();
}, [toggle]); }, [toggle]);
const handleKeyDown = useCallback( const handleKeyDown = useKeyboardButton(() => {
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'Enter') {
toggle(); toggle();
} });
},
[toggle],
);
return ( return (
<div <div

View file

@ -0,0 +1,19 @@
import { useCallback } from 'react';
import type { KeyboardEvent } from 'react';
export const useKeyboardButton = (
actionCallback: () => void,
): ((event: KeyboardEvent<HTMLElement>) => void) => {
const handleKeyDown = useCallback(
(event: KeyboardEvent<HTMLElement>) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
actionCallback();
event.stopPropagation();
}
},
[actionCallback],
);
return handleKeyDown;
};