Skip to content

Commit edb0b04

Browse files
committed
fixup! ✨(frontend) set empty alt for decorative images in blocknote editor
1 parent db361ad commit edb0b04

File tree

4 files changed

+47
-35
lines changed

4 files changed

+47
-35
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ test.describe('Doc Editor', () => {
286286
expect(await image.getAttribute('src')).toMatch(
287287
/http:\/\/localhost:8083\/media\/.*\/attachments\/.*.png/,
288288
);
289+
290+
await expect(image).toHaveAttribute('role', 'presentation');
291+
await expect(image).toHaveAttribute('alt', '');
292+
await expect(image).toHaveAttribute('tabindex', '-1');
293+
await expect(image).toHaveAttribute('aria-hidden', 'true');
289294
});
290295

291296
test('it checks the AI buttons', async ({ page, browserName }) => {

src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ import { randomColor } from '../utils';
3333

3434
import { BlockNoteSuggestionMenu } from './BlockNoteSuggestionMenu';
3535
import { BlockNoteToolbar } from './BlockNoteToolBar/BlockNoteToolbar';
36-
import { CalloutBlock, DividerBlock } from './custom-blocks';
36+
import {
37+
AccessibleImageBlock,
38+
CalloutBlock,
39+
DividerBlock,
40+
} from './custom-blocks';
3741
import {
3842
InterlinkingLinkInlineContent,
3943
InterlinkingSearchInlineContent,
@@ -50,6 +54,7 @@ const baseBlockNoteSchema = withPageBreak(
5054
...defaultBlockSpecs,
5155
callout: CalloutBlock,
5256
divider: DividerBlock,
57+
image: AccessibleImageBlock,
5358
},
5459
inlineContentSpecs: {
5560
...defaultInlineContentSpecs,
@@ -169,40 +174,6 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
169174
};
170175
}, [setEditor, editor]);
171176

172-
// Accessibility: make all images decorative by default
173-
useEffect(() => {
174-
if (!editor) {
175-
return;
176-
}
177-
178-
const applyDecorativeAlt = () => {
179-
const imgs = document.querySelectorAll<HTMLImageElement>(
180-
'.--docs--editor-container img.bn-visual-media',
181-
);
182-
imgs.forEach((img) => {
183-
img.setAttribute('alt', '');
184-
img.setAttribute('role', 'presentation');
185-
img.setAttribute('aria-hidden', 'true');
186-
});
187-
};
188-
189-
applyDecorativeAlt();
190-
191-
const unsubscribe = editor.onChange(() => {
192-
applyDecorativeAlt();
193-
});
194-
195-
return () => {
196-
try {
197-
if (typeof unsubscribe === 'function') {
198-
unsubscribe();
199-
}
200-
} catch {
201-
/* no-op */
202-
}
203-
};
204-
}, [editor]);
205-
206177
return (
207178
<Box
208179
$padding={{ top: 'md' }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import {
3+
BlockFromConfig,
4+
BlockNoteEditor,
5+
createBlockSpec,
6+
imageBlockConfig,
7+
imageParse,
8+
imageRender,
9+
imageToExternalHTML,
10+
} from '@blocknote/core';
11+
12+
export const accessibleImageRender = (
13+
block: BlockFromConfig<typeof imageBlockConfig, any, any>,
14+
editor: BlockNoteEditor<any, any, any>,
15+
) => {
16+
const imageRenderComputed = imageRender(block, editor);
17+
const dom = imageRenderComputed.dom;
18+
const imgSelector = dom.querySelector('img');
19+
20+
imgSelector?.setAttribute('alt', '');
21+
imgSelector?.setAttribute('role', 'presentation');
22+
imgSelector?.setAttribute('aria-hidden', 'true');
23+
imgSelector?.setAttribute('tabindex', '-1');
24+
25+
return {
26+
...imageRenderComputed,
27+
dom,
28+
};
29+
};
30+
31+
export const AccessibleImageBlock = createBlockSpec(imageBlockConfig, {
32+
render: accessibleImageRender,
33+
parse: imageParse,
34+
toExternalHTML: imageToExternalHTML,
35+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * from './AccessibleImageBlock';
12
export * from './CalloutBlock';
23
export * from './DividerBlock';

0 commit comments

Comments
 (0)