From 26620f34717abd9692c70fac99453f4f3164f4d5 Mon Sep 17 00:00:00 2001 From: Cyril Date: Tue, 18 Nov 2025 14:35:03 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20improve=20share=20modal?= =?UTF-8?q?=20button=20accessibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added aria-labels to remove and invite buttons Signed-off-by: Cyril --- CHANGELOG.md | 5 +++++ .../__tests__/app-impress/doc-member-create.spec.ts | 8 ++++---- .../apps/e2e/__tests__/app-impress/utils-share.ts | 2 +- .../doc-share/components/DocShareAddMemberList.tsx | 12 +++++++++++- .../components/DocShareAddMemberListItem.tsx | 5 +++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd6591525..18749ca183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to ## [Unreleased] +### Fixed + +- ♿(frontend) improve accessibility: + - ♿(frontend) improve share modal button accessibility #1626 + ## [3.10.0] - 2025-11-18 ### Added diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts index 11fdb734f7..36b5813477 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts @@ -84,7 +84,7 @@ test.describe('Document create member', () => { // Validate await page.getByRole('menuitem', { name: 'Administrator' }).click(); - await page.getByRole('button', { name: 'Invite' }).click(); + await page.getByRole('button', { name: /^Invite / }).click(); // Check invitation added await expect( @@ -135,7 +135,7 @@ test.describe('Document create member', () => { (response) => response.url().includes('/invitations/') && response.status() === 201, ); - await page.getByRole('button', { name: 'Invite' }).click(); + await page.getByRole('button', { name: /^Invite / }).click(); // Check invitation sent @@ -154,7 +154,7 @@ test.describe('Document create member', () => { response.url().includes('/invitations/') && response.status() === 400, ); - await page.getByRole('button', { name: 'Invite' }).click(); + await page.getByRole('button', { name: /^Invite / }).click(); await expect( page.getByText(`"${email}" is already invited to the document.`), ).toBeVisible(); @@ -191,7 +191,7 @@ test.describe('Document create member', () => { response.url().includes('/invitations/') && response.status() === 201, ); - await page.getByRole('button', { name: 'Invite' }).click(); + await page.getByRole('button', { name: /^Invite / }).click(); // Check invitation sent const responseCreateInvitation = await responsePromiseCreateInvitation; diff --git a/src/frontend/apps/e2e/__tests__/app-impress/utils-share.ts b/src/frontend/apps/e2e/__tests__/app-impress/utils-share.ts index 23dfc0aaf6..dcc798da6a 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/utils-share.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/utils-share.ts @@ -40,7 +40,7 @@ export const addNewMember = async ( // Choose a role await page.getByLabel('doc-role-dropdown').click(); await page.getByRole('menuitem', { name: role }).click(); - await page.getByRole('button', { name: 'Invite' }).click(); + await page.getByRole('button', { name: /^Invite / }).click(); return users[index].email; }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx index b797eb96ca..3008f960c7 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberList.tsx @@ -108,6 +108,12 @@ export const DocShareAddMemberList = ({ afterInvite?.(); setIsLoading(false); }; + const inviteLabel = + selectedUsers.length === 1 + ? t('Invite {{name}}', { + name: selectedUsers[0].full_name || selectedUsers[0].email, + }) + : t('Invite {{count}} members', { count: selectedUsers.length }); return ( - diff --git a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberListItem.tsx b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberListItem.tsx index 047217fe03..fe678923c4 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberListItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareAddMemberListItem.tsx @@ -1,4 +1,5 @@ import { Button } from '@openfun/cunningham-react'; +import { useTranslation } from 'react-i18next'; import { css } from 'styled-components'; import { Box, Icon, Text } from '@/components'; @@ -10,6 +11,7 @@ type Props = { onRemoveUser?: (user: User) => void; }; export const DocShareAddMemberListItem = ({ user, onRemoveUser }: Props) => { + const { t } = useTranslation(); const { spacingsTokens, colorsTokens, fontSizesTokens } = useCunninghamTheme(); @@ -42,6 +44,9 @@ export const DocShareAddMemberListItem = ({ user, onRemoveUser }: Props) => { size="nano" onClick={() => onRemoveUser?.(user)} icon={} + aria-label={t('Remove {{name}} from the invite list', { + name: user.full_name || user.email, + })} /> );