Skip to content

BUG: Missing radiogroup role and accessible label in ShareAlbumDialog mode selector #1529

Description

@TarunyaProgrammer

Is there an existing issue for this?

  • I have searched the existing issues

What happened?

What happened?

Problem Statement

In ShareAlbumDialog.tsx, the share mode selector allows users to choose between "Local network" and "Internet" sharing. The selector buttons define role="radio" and aria-checked={mode === option.value}. However, the wrapping parent element is a standard div without role="radiogroup" or an accessible name (aria-label).

Under the WAI-ARIA 1.2 specification, elements with role="radio" require an enclosing role="radiogroup" parent container. Without this, assistive technologies (such as screen readers) treat each button as an isolated orphan radio button rather than a cohesive group of mutually exclusive options.

Context and Origin

The share dialog and mode selection were introduced in PR #1478 (feat: share an album beyond the local network, commit d1ccba1), building upon the album sharing feature in PR #1469 / PR #1473.

Root Cause Analysis

In frontend/src/components/Albums/ShareAlbumDialog.tsx (lines 479-498):

<div className="bg-muted grid w-full grid-cols-2 gap-1 rounded-lg p-1">
  {MODE_OPTIONS.map((option) => (
    <button
      key={option.value}
      type="button"
      role="radio"
      aria-checked={mode === option.value}
      onClick={() => handleModeChange(option.value)}
      className={cn(
        'flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors',
        mode === option.value
          ? 'bg-background text-foreground shadow-sm'
          : 'text-muted-foreground hover:text-foreground',
      )}
    >
      <option.icon className="h-4 w-4" />
      {option.label}
    </button>
  ))}
</div>

The buttons declare role="radio", but the parent container <div className="bg-muted..."> does not declare role="radiogroup" or aria-label="Share mode".

In contrast, the "Keep sharing" section right below in the same file (line 518) correctly implements a radiogroup structure using the design system's <RadioGroup> component:

<RadioGroup value={expiry} onValueChange={setExpiry}>

Impact on Accessibility (WCAG 2.1 / WAI-ARIA)

  1. WAI-ARIA 1.2 Violation (aria-required-parent): A radio role is semantically invalid unless contained within an element with role="radiogroup".
  2. Loss of Group Context: Screen readers (VoiceOver, NVDA, JAWS) do not announce the grouping label or position in group (e.g., "1 of 2", "2 of 2"). The user is not informed what setting these mutually exclusive choices configure.
  3. Automated Accessibility Audit Failure: Tools like axe-core, Lighthouse, and Accessibility Inspector flag aria-required-parent errors on this container.

Visual Proof

Image

Steps to Reproduce

  1. Open PictoPy.
  2. Navigate to Albums, open any album, and click the Share button to open ShareAlbumDialog.
  3. Inspect the DOM structure of the "Local network" / "Internet" toggle button bar using DevTools or run an automated accessibility audit (axe / Lighthouse).
  4. Observe the aria-required-parent error indicating role="radio" elements lack a parent with role="radiogroup".

Expected Behavior

The container element enclosing the mode selection buttons should specify role="radiogroup" and provide an explicit accessible label (aria-label="Share mode"), allowing screen readers to announce the grouping context and option indices.

Actual Behavior

The buttons are wrapped in a generic <div> with no accessibility role or label, causing the radio buttons to be announced as unlinked controls.

Proposed Solution

Add role="radiogroup" and an appropriate aria-label to the container div in frontend/src/components/Albums/ShareAlbumDialog.tsx:

<div
  role="radiogroup"
  aria-label="Share mode"
  className="bg-muted grid w-full grid-cols-2 gap-1 rounded-lg p-1"
>

I have verified the issue and would like to submit a PR to resolve this if assigned.

Record

  • I agree to follow this project's Code of Conduct

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions