Skip to content

Commit e6c6b0c

Browse files
feat: improve accessibility of icon-only buttons (#221)
Added `aria-label`s, `aria-hidden="true"` to SVGs, and proper `focus-visible` states to icon-only buttons in `VeoProjectForm.tsx` and `AssetLibrary.tsx` to improve keyboard navigation and screen reader support. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: thebearwithabite <216692431+thebearwithabite@users.noreply.github.com>
1 parent 1b97eb7 commit e6c6b0c

3 files changed

Lines changed: 11 additions & 9 deletions

File tree

.jules/palette.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 2024-03-16 - Make hover-only actions keyboard accessible
22
**Learning:** Actions hidden behind `opacity-0` and revealed with `group-hover:opacity-100` are completely inaccessible to keyboard-only users navigating via Tab. This is a common pattern for "secondary" actions like undo/delete buttons in lists.
33
**Action:** When using `opacity-0 group-hover:opacity-100` to hide secondary actions, always pair it with `focus-visible:opacity-100`, `focus-visible:ring-2`, and `focus-visible:outline-none` to ensure the action becomes visible and clearly highlighted when focused via keyboard navigation.
4-
## 2024-04-12 - Sidebar Navigation Accessibility
5-
**Learning:** React Router Links used for navigation items without `aria-current` lack semantic indication of the active page for screen readers, while visible text is sufficient without additional `aria-label`. Redundant `aria-hidden="true"` on decorative icons inside the link improves screen reader experience.
6-
**Action:** Always add `aria-current={isActive ? 'page' : undefined}` to active navigation links, apply explicit `focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none` classes for keyboard accessibility, and hide decorative inner icons with `aria-hidden="true"`.
4+
## 2024-05-23 - Accessible Icon-Only Buttons in Custom Design System
5+
**Learning:** In the liquid glass design system, visually hidden icon-only buttons (like remove buttons on hover) require specific focus-visible utility classes (`focus-visible:opacity-100 focus-visible:scale-100`) combined with standard focus rings to remain keyboard accessible.
6+
**Action:** Always pair `group-hover:opacity-100` on hidden icon buttons with explicit `focus-visible:opacity-100` and standard focus ring utilities (`focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none`) to ensure keyboard users can discover and interact with them. Apply `aria-hidden="true"` to the inner SVGs and `aria-label` to the buttons.

frontend_v2/src/components/veo/AssetLibrary.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,9 @@ const AssetCard = ({ asset, onRemove, onUpload }: AssetCardProps) => {
237237
<button
238238
onClick={onRemove}
239239
type="button"
240-
className="absolute top-2 right-2 z-20 bg-black/60 backdrop-blur-md text-white/60 hover:text-white rounded-full p-1.5 opacity-0 group-hover:opacity-100 transition-all border border-white/10 scale-90 group-hover:scale-100">
241-
<XMarkIcon className="w-3 h-3" />
240+
aria-label="Remove asset"
241+
className="absolute top-2 right-2 z-20 bg-black/60 backdrop-blur-md text-white/60 hover:text-white rounded-full p-1.5 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 focus-visible:scale-100 transition-all border border-white/10 scale-90 group-hover:scale-100 focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none">
242+
<XMarkIcon className="w-3 h-3" aria-hidden="true" />
242243
</button>
243244

244245
<div className="aspect-[4/3] bg-black/40 relative overflow-hidden">
@@ -289,9 +290,10 @@ const AssetCard = ({ asset, onRemove, onUpload }: AssetCardProps) => {
289290
<button
290291
type="button"
291292
onClick={handleCopyDescription}
292-
className="text-white/20 hover:text-white transition-colors flex-shrink-0 mt-0.5"
293+
aria-label="Copy description"
294+
className="text-white/20 hover:text-white transition-colors flex-shrink-0 mt-0.5 focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none"
293295
title="Copy Name & Description">
294-
{copied ? <CheckCircle2Icon className="w-3 h-3 text-green-400" /> : <ClipboardDocumentIcon className="w-3 h-3" />}
296+
{copied ? <CheckCircle2Icon className="w-3 h-3 text-green-400" aria-hidden="true" /> : <ClipboardDocumentIcon className="w-3 h-3" aria-hidden="true" />}
295297
</button>
296298
</div>
297299
</div>

frontend_v2/src/components/veo/VeoProjectForm.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ const VeoProjectForm: React.FC<VeoProjectFormProps> = ({
103103
<div className="flex justify-between items-center mb-8 relative z-10">
104104
<p className="text-[11px] text-white/40 font-bold uppercase tracking-widest leading-none">Draft your scene beats or upload a screenplay</p>
105105
<div className="flex gap-2">
106-
<button type="button" onClick={() => scriptFileInputRef.current?.click()} className="p-3 bg-black/40 border border-white/5 rounded-xl hover:bg-white/10 text-white/40 hover:text-white transition-all"><FileUploadIcon className="w-4 h-4" /></button>
107-
<button type="button" className="p-3 bg-black/40 border border-white/5 rounded-xl hover:bg-white/10 text-white/40 hover:text-white transition-all"><FileAudioIcon className="w-4 h-4" /></button>
106+
<button type="button" onClick={() => scriptFileInputRef.current?.click()} aria-label="Upload script" className="p-3 bg-black/40 border border-white/5 rounded-xl hover:bg-white/10 text-white/40 hover:text-white transition-all focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none"><FileUploadIcon className="w-4 h-4" aria-hidden="true" /></button>
107+
<button type="button" aria-label="Upload audio" className="p-3 bg-black/40 border border-white/5 rounded-xl hover:bg-white/10 text-white/40 hover:text-white transition-all focus-visible:ring-2 focus-visible:ring-background/50 focus-visible:outline-none"><FileAudioIcon className="w-4 h-4" aria-hidden="true" /></button>
108108
</div>
109109
</div>
110110

0 commit comments

Comments
 (0)