Skip to content

Commit 9c55f8b

Browse files
authored
Merge branch 'release-1.12.0' into db-provider-a11y
2 parents 034969b + 3c39c0d commit 9c55f8b

19 files changed

Lines changed: 825 additions & 505 deletions

File tree

.secrets.baseline

Lines changed: 268 additions & 278 deletions
Large diffs are not rendered by default.

src/frontend/src/components/ui/__tests__/checkbox.a11y.test.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,21 @@ describe("Checkbox accessibility", () => {
2222
});
2323

2424
describe("CheckBoxDiv accessibility", () => {
25-
// Known gap (a11y-action-plan 1.3): CheckBoxDiv is a visual-only <div>
26-
// with no checkbox role, state, or keyboard support. Fails until the
27-
// fix lands.
2825
it("should_expose_checkbox_role_and_checked_state", () => {
2926
render(<CheckBoxDiv checked />);
3027

3128
const checkbox = screen.getByRole("checkbox");
3229
expect(checkbox).toHaveAttribute("aria-checked", "true");
3330
});
31+
32+
// When the wrapping element owns the toggle semantics (e.g. a toggle
33+
// button) the indicator must NOT expose an interactive "checkbox" role,
34+
// otherwise it nests an interactive role inside another one
35+
// (IBM aria_descendant_valid).
36+
it("should_be_hidden_from_assistive_tech_when_presentational", () => {
37+
const { container } = render(<CheckBoxDiv checked presentational />);
38+
39+
expect(screen.queryByRole("checkbox")).not.toBeInTheDocument();
40+
expect(container.firstChild).toHaveAttribute("aria-hidden", "true");
41+
});
3442
});

src/frontend/src/components/ui/checkbox.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,27 @@ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
2929
const CheckBoxDiv = ({
3030
className = "",
3131
checked,
32+
presentational = false,
33+
"aria-label": ariaLabel,
3234
}: {
3335
className?: string;
3436
checked?: boolean;
37+
// When true, render a purely visual indicator (hidden from assistive tech).
38+
// Use this when the wrapping element already owns the checkbox/toggle
39+
// semantics (e.g. a toggle button), so we don't nest an interactive
40+
// "checkbox" role inside another interactive role (IBM aria_descendant_valid).
41+
presentational?: boolean;
42+
"aria-label"?: string;
3543
}) => (
3644
// Read-only state indicator: activation is owned by the wrapping
3745
// trigger/tooltip, so it exposes checkbox role + state but stays
3846
// non-focusable itself.
3947
<div
40-
role="checkbox"
41-
aria-checked={Boolean(checked)}
42-
aria-readonly="true"
48+
role={presentational ? undefined : "checkbox"}
49+
aria-hidden={presentational ? "true" : undefined}
50+
aria-label={presentational ? undefined : ariaLabel}
51+
aria-checked={presentational ? undefined : Boolean(checked)}
52+
aria-readonly={presentational ? undefined : "true"}
4353
className={cn(
4454
className,
4555
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",

src/frontend/src/locales/de.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(Update verfügbar)",
1414
"account.version": "Version",
1515
"admin.attentionTitle": "Achtung!",
16+
"admin.backButton": "Zurück",
17+
"admin.clearSearch": "Suche löschen",
1618
"admin.cancelButton": "Abbrechen",
1719
"admin.cannotDeactivateSelf": "Sie können Ihr eigenes Konto nicht deaktivieren",
1820
"admin.columnActive": "Aktiv",

src/frontend/src/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@
373373
"admin.deleteTitle": "Delete",
374374
"admin.deleteUserHeader": "Delete User",
375375
"admin.attentionTitle": "Attention!",
376+
"admin.backButton": "Back",
377+
"admin.clearSearch": "Clear search",
376378
"admin.confirmButton": "Confirm",
377379
"admin.editUserConfirmContent": "Are you completely confident about the changes you are making to this user?",
378380
"admin.deleteUserConfirmContent": "Are you sure you want to delete this user? This action cannot be undone.",

src/frontend/src/locales/es.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(hay una actualización disponible)",
1414
"account.version": "Versión",
1515
"admin.attentionTitle": "Atención",
16+
"admin.backButton": "Atrás",
17+
"admin.clearSearch": "Borrar búsqueda",
1618
"admin.cancelButton": "Cancelar",
1719
"admin.cannotDeactivateSelf": "No puedes desactivar tu propia cuenta",
1820
"admin.columnActive": "Activo",

src/frontend/src/locales/fr.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(mise à jour disponible)",
1414
"account.version": "Version",
1515
"admin.attentionTitle": "Attention !",
16+
"admin.backButton": "Retour",
17+
"admin.clearSearch": "Effacer la recherche",
1618
"admin.cancelButton": "Annuler",
1719
"admin.cannotDeactivateSelf": "Vous ne pouvez pas désactiver votre propre compte",
1820
"admin.columnActive": "Actif",

src/frontend/src/locales/ja.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(更新あり)",
1414
"account.version": "バージョン",
1515
"admin.attentionTitle": "注意",
16+
"admin.backButton": "戻る",
17+
"admin.clearSearch": "検索をクリア",
1618
"admin.cancelButton": "キャンセル",
1719
"admin.cannotDeactivateSelf": "ご自身のアカウントを無効にすることはできません",
1820
"admin.columnActive": "アクティブ",

src/frontend/src/locales/pt.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(atualização disponível)",
1414
"account.version": "Versão",
1515
"admin.attentionTitle": "Atenção!",
16+
"admin.backButton": "Voltar",
17+
"admin.clearSearch": "Limpar pesquisa",
1618
"admin.cancelButton": "Cancelar",
1719
"admin.cannotDeactivateSelf": "Você não pode desativar sua própria conta",
1820
"admin.columnActive": "Ativo",

src/frontend/src/locales/zh-Hans.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"account.updateAvailable": "(有更新)",
1414
"account.version": "版本",
1515
"admin.attentionTitle": "注意!",
16+
"admin.backButton": "返回",
17+
"admin.clearSearch": "清除搜索",
1618
"admin.cancelButton": "取消",
1719
"admin.cannotDeactivateSelf": "您无法注销自己的账户",
1820
"admin.columnActive": "活动",

0 commit comments

Comments
 (0)