Problem

WCAG 2.5.3 Label in Name requires that the accessible name of a control contains the visible label text. In ConfigTranslationController, "Edit", "Delete", and "Add" links are repeated for every language with no aria-label or visually-hidden text to distinguish them.

Visible text: "Edit", "Delete", "Add" (repeated per language row)

Accessible name: "Edit", "Delete", "Add" (identical for every row)

A speech recognition user who says "Click Edit" will see all matching links highlighted with numbers. They must then say the correct number to select the one they want — for every single action.


Proposed resolution

Add aria-label attributes that include the language name:

For the original language edit link (around line 210):

$operations['edit'] = [
  'title' => $this->t('Edit'),
  'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]),
  'attributes' => [
    'aria-label' => $this->t('Edit @language', ['@language' => $language->getName()]),
  ],
];

For translated language links (around lines 230-266):

$operations['add'] = [
  'title' => $this->t('Add'),
  'url' => Url::fromRoute($mapper->getAddRouteName(), $mapper->getAddRouteParameters()),
  'attributes' => [
    'class' => ['use-ajax'],
    'data-dialog-type' => 'modal',
    'data-dialog-options' => Json::encode(['width' => 880]),
    'aria-label' => $this->t('Add @language translation', ['@language' => $language->getName()]),
  ],
];

$operations['edit'] = [
  'title' => $this->t('Edit'),
  'url' => Url::fromRoute($mapper->getEditRouteName(), $mapper->getEditRouteParameters()),
  'attributes' => [
    'class' => ['use-ajax'],
    'data-dialog-type' => 'modal',
    'data-dialog-options' => Json::encode(['width' => 880]),
    'aria-label' => $this->t('Edit @language translation', ['@language' => $language->getName()]),
  ],
];

$operations['delete'] = [
  'title' => $this->t('Delete'),
  'url' => Url::fromRoute($mapper->getDeleteRouteName(), $mapper->getDeleteRouteParameters()),
  'attributes' => [
    'class' => ['use-ajax'],
    'data-dialog-type' => 'modal',
    'data-dialog-options' => Json::encode(['width' => 880]),
    'aria-label' => $this->t('Delete @language translation', ['@language' => $language->getName()]),
  ],
];

File

  • core/modules/config_translation/src/Controller/ConfigTranslationController.php — lines 209-266

Test

Add a FunctionalJavascript test that:

  1. Enables multilingual with at least two languages
  2. Visits a config translation overview page
  3. Asserts each language row's Edit, Delete, and Add links have unique aria-labels containing the language name

Related

AI Disclaimer: This was done with a lot of help from AI.

Comments

mgifford created an issue. See original summary.

mgifford’s picture

mgifford’s picture

Issue summary: View changes