From 977cbede1d4117367453a0faf9260c5fd002a592 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 06:18:35 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improve=20accessibili?= =?UTF-8?q?ty=20and=20fix=20build=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix TypeScript build error in GameScreenshotsCarousel.tsx by removing unused state. - Convert non-semantic interactive spans to buttons in GameCard.tsx. - Add ARIA labels and focus-visible styles to tags and badges. - Improve keyboard accessibility in GameDetailHeader.tsx. Co-authored-by: Gamepulse <8333979+Gamepulse@users.noreply.github.com> --- .Jules/palette.md | 7 +++++ src/components/Library/GameCard.tsx | 27 ++++++++++--------- src/components/Library/GameDetailHeader.tsx | 16 ++++++++--- .../Library/GameScreenshotsCarousel.tsx | 2 -- 4 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 .Jules/palette.md diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 0000000..6b89342 --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,7 @@ +## 2025-05-14 - [A11y: Semantic Buttons and Focus States] +**Learning:** Using semantic ` ))} {remainingCount > 0 && ( @@ -73,19 +74,20 @@ const GameCard: React.FC = ({ game, onClick, viewMode, onFilter, return (
{allMetadata.map((item) => ( - { e.stopPropagation(); e.preventDefault(); console.log('[GameCard] Metadata tag clicked:', item.type, item.name); onFilter?.(item.type, item.name); }} - className="px-1.5 py-0.5 text-xs rounded bg-gray-700/50 theme-text-muted hover:bg-indigo-600/30 transition-colors cursor-pointer select-none" - role="button" + className="px-1.5 py-0.5 text-xs rounded bg-gray-700/50 theme-text-muted hover:bg-indigo-600/30 transition-colors cursor-pointer select-none focus-visible:ring-2 focus-visible:ring-indigo-500" + aria-label={`${t(item.type as any)}: ${item.name}`} > {item.name} - + ))}
); @@ -132,18 +134,19 @@ const GameCard: React.FC = ({ game, onClick, viewMode, onFilter, const label = COMPLETION_STATUS_LABELS[completion_status as keyof typeof COMPLETION_STATUS_LABELS] || completion_status; return ( - { e.stopPropagation(); e.preventDefault(); console.log('[GameCard] Status badge clicked:', completion_status); onFilter?.('status', completion_status); }} - className={`absolute top-2 left-2 px-2 py-1 rounded-full text-xs text-white ${statusColors[completion_status] || 'bg-gray-600'} hover:opacity-80 transition-opacity cursor-pointer select-none`} - role="button" + className={`absolute top-2 left-2 px-2 py-1 rounded-full text-xs text-white z-10 ${statusColors[completion_status] || 'bg-gray-600'} hover:opacity-80 transition-opacity cursor-pointer select-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-white`} + aria-label={`${t('completionStatus')}: ${label}`} > {label} - + ); }; diff --git a/src/components/Library/GameDetailHeader.tsx b/src/components/Library/GameDetailHeader.tsx index aa3d128..4e1bccc 100644 --- a/src/components/Library/GameDetailHeader.tsx +++ b/src/components/Library/GameDetailHeader.tsx @@ -276,8 +276,10 @@ export function GameDetailHeader({ game, onGameUpdated, onPlatformChange, onFilt {game.genres.map((genre) => ( @@ -292,8 +294,10 @@ export function GameDetailHeader({ game, onGameUpdated, onPlatformChange, onFilt {game.game_modes.map((mode) => ( @@ -308,8 +312,10 @@ export function GameDetailHeader({ game, onGameUpdated, onPlatformChange, onFilt {game.player_perspectives.map((persp) => ( @@ -324,8 +330,10 @@ export function GameDetailHeader({ game, onGameUpdated, onPlatformChange, onFilt {game.themes.map((theme) => ( diff --git a/src/components/Library/GameScreenshotsCarousel.tsx b/src/components/Library/GameScreenshotsCarousel.tsx index 6a4e37c..bfae3b8 100644 --- a/src/components/Library/GameScreenshotsCarousel.tsx +++ b/src/components/Library/GameScreenshotsCarousel.tsx @@ -20,7 +20,6 @@ export function GameScreenshotsCarousel({ gameId }: GameScreenshotsCarouselProps const [igdbScreenshots, setIgdbScreenshots] = useState([]); const [currentIndex, setCurrentIndex] = useState(0); const [loading, setLoading] = useState(true); - const [hasIgdbId, setHasIgdbId] = useState(false); useEffect(() => { const loadScreenshots = async () => { @@ -29,7 +28,6 @@ export function GameScreenshotsCarousel({ gameId }: GameScreenshotsCarouselProps // Load game data to check IGDB ID try { const game = await invoke<{ igdb_id: number | null }>("get_game_by_id", { id: gameId }); - setHasIgdbId(!!game?.igdb_id); // Load IGDB screenshots if available if (game?.igdb_id) {