Skip to content

Commit a755b36

Browse files
committed
♿️(frontend) fix more options menu feedback for screen readers
Pin/unpin: vocal announce only. Duplicate, copy: toast only.
1 parent 9991820 commit a755b36

File tree

7 files changed

+46
-9
lines changed

7 files changed

+46
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to
99
### Changed
1010

1111
- 💫(frontend) fix the help button to the bottom in tree #2073
12+
- ♿️(frontend) fix more options menu feedback for screen readers #2071
1213

1314
## [v4.8.2] - 2026-03-19
1415

src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,9 @@ test.describe('Doc Header', () => {
474474
// Copy content to clipboard
475475
await page.getByLabel('Open the document options').click();
476476
await getMenuItem(page, 'Copy as Markdown').click();
477-
await expect(page.getByText('Copied to clipboard')).toBeVisible();
477+
await expect(
478+
page.getByText('Copied as Markdown to clipboard'),
479+
).toBeVisible();
478480

479481
// Test that clipboard is in Markdown format
480482
const handle = await page.evaluateHandle(() =>

src/frontend/apps/impress/src/features/docs/doc-header/hooks/useCopyCurrentEditorToClipboard.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export const useCopyCurrentEditorToClipboard = () => {
1313

1414
return async (asFormat: 'html' | 'markdown') => {
1515
if (!editor) {
16-
toast(t('Editor unavailable'), VariantType.ERROR, { duration: 3000 });
16+
const message = t('Editor unavailable');
17+
toast(message, VariantType.ERROR, { duration: 3000 });
1718
return;
1819
}
1920

@@ -23,10 +24,20 @@ export const useCopyCurrentEditorToClipboard = () => {
2324
? await editor.blocksToHTMLLossy()
2425
: await editor.blocksToMarkdownLossy();
2526
await navigator.clipboard.writeText(editorContentFormatted);
26-
toast(t('Copied to clipboard'), VariantType.SUCCESS, { duration: 3000 });
27+
const successMessage =
28+
asFormat === 'markdown'
29+
? t('Copied as Markdown to clipboard')
30+
: t('Copied to clipboard');
31+
32+
toast(successMessage, VariantType.SUCCESS, { duration: 3000 });
2733
} catch (error) {
2834
console.error(error);
29-
toast(t('Failed to copy to clipboard'), VariantType.ERROR, {
35+
const errorMessage =
36+
asFormat === 'markdown'
37+
? t('Failed to copy as Markdown to clipboard')
38+
: t('Failed to copy to clipboard');
39+
40+
toast(errorMessage, VariantType.ERROR, {
3041
duration: 3000,
3142
});
3243
}

src/frontend/apps/impress/src/features/docs/doc-management/api/useCreateFavoriteDoc.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { announce } from '@react-aria/live-announcer';
12
import { useMutation, useQueryClient } from '@tanstack/react-query';
3+
import { useTranslation } from 'react-i18next';
24

35
import { APIError, errorCauses, fetchAPI } from '@/api';
46

@@ -29,6 +31,8 @@ export function useCreateFavoriteDoc({
2931
listInvalidQueries,
3032
}: CreateFavoriteDocProps) {
3133
const queryClient = useQueryClient();
34+
const { t } = useTranslation();
35+
3236
return useMutation<void, APIError, CreateFavoriteDocParams>({
3337
mutationFn: createFavoriteDoc,
3438
onSuccess: () => {
@@ -37,7 +41,15 @@ export function useCreateFavoriteDoc({
3741
queryKey: [queryKey],
3842
});
3943
});
44+
45+
const message = t('Document pinned successfully!');
46+
announce(message, 'polite');
47+
4048
onSuccess?.();
4149
},
50+
onError: () => {
51+
const message = t('Failed to pin the document.');
52+
announce(message, 'assertive');
53+
},
4254
});
4355
}

src/frontend/apps/impress/src/features/docs/doc-management/api/useDeleteFavoriteDoc.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { announce } from '@react-aria/live-announcer';
12
import { useMutation, useQueryClient } from '@tanstack/react-query';
3+
import { useTranslation } from 'react-i18next';
24

35
import { APIError, errorCauses, fetchAPI } from '@/api';
46

@@ -29,6 +31,8 @@ export function useDeleteFavoriteDoc({
2931
listInvalidQueries,
3032
}: DeleteFavoriteDocProps) {
3133
const queryClient = useQueryClient();
34+
const { t } = useTranslation();
35+
3236
return useMutation<void, APIError, DeleteFavoriteDocParams>({
3337
mutationFn: deleteFavoriteDoc,
3438
onSuccess: () => {
@@ -37,7 +41,15 @@ export function useDeleteFavoriteDoc({
3741
queryKey: [queryKey],
3842
});
3943
});
44+
45+
const message = t('Document unpinned successfully!');
46+
announce(message, 'polite');
47+
4048
onSuccess?.();
4149
},
50+
onError: () => {
51+
const message = t('Failed to unpin the document.');
52+
announce(message, 'assertive');
53+
},
4254
});
4355
}

src/frontend/apps/impress/src/features/docs/doc-management/api/useDuplicateDoc.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,16 @@ export function useDuplicateDoc(options?: DuplicateDocOptions) {
8888
queryKey: [KEY_LIST_DOC],
8989
});
9090

91-
toast(t('Document duplicated successfully!'), VariantType.SUCCESS, {
91+
const message = t('Document duplicated successfully!');
92+
toast(message, VariantType.SUCCESS, {
9293
duration: 3000,
9394
});
9495

9596
void options?.onSuccess?.(data, variables, onMutateResult, context);
9697
},
9798
onError: (error, variables, onMutateResult, context) => {
98-
toast(t('Failed to duplicate the document...'), VariantType.ERROR, {
99+
const message = t('Failed to duplicate the document...');
100+
toast(message, VariantType.ERROR, {
99101
duration: 3000,
100102
});
101103

src/frontend/apps/impress/src/hooks/useClipboard.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
VariantType,
33
useToastProvider,
44
} from '@gouvfr-lasuite/cunningham-react';
5-
import { announce } from '@react-aria/live-announcer';
65
import { useCallback } from 'react';
76
import { useTranslation } from 'react-i18next';
87

@@ -19,14 +18,12 @@ export const useClipboard = () => {
1918
toast(message, VariantType.SUCCESS, {
2019
duration: 3000,
2120
});
22-
announce(message, 'polite');
2321
})
2422
.catch(() => {
2523
const message = errorMessage ?? t('Failed to copy to clipboard');
2624
toast(message, VariantType.ERROR, {
2725
duration: 3000,
2826
});
29-
announce(message, 'assertive');
3027
});
3128
},
3229
[t, toast],

0 commit comments

Comments
 (0)