Skip to content

Commit 6cc4263

Browse files
committed
✨(frontend) convert to figure/figcaption structure if caption exists
ensure html structure by using figure/figcaption when captions are present Signed-off-by: Cyril <c.gromoff@gmail.com>
1 parent cc4bed6 commit 6cc4263

File tree

2 files changed

+69
-6
lines changed

2 files changed

+69
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
All notable changes to this project will be documented in this file.
32

43
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
@@ -21,6 +20,7 @@ and this project adheres to
2120
- ♿ add document visible in list and openable via enter key #1365
2221
- ♿ add pdf outline property to enable bookmarks display #1368
2322
- ♿ hide decorative icons from assistive tech with aria-hidden #1404
23+
- ♿ fix rgaa 1.9.1: convert to figure/figcaption structure #1426
2424
- ♿ remove redundant aria-label to avoid over-accessibility #1420
2525
- ♿ remove redundant aria-label on hidden icons and update tests #1432
2626
- ♿ improve semantic structure and aria roles of leftpanel #1431
@@ -39,7 +39,6 @@ and this project adheres to
3939
- ♿(frontend) improve accessibility:
4040
- ♿improve NVDA navigation in DocShareModal #1396
4141

42-
4342
## [3.7.0] - 2025-09-12
4443

4544
### Added

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-blocks/AccessibleImageBlock.tsx

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
imageRender,
1111
imageToExternalHTML,
1212
} from '@blocknote/core';
13+
import { t } from 'i18next';
1314

1415
type ImageBlockConfig = typeof imageBlockConfig;
1516

@@ -25,10 +26,73 @@ export const accessibleImageRender = (
2526
const dom = imageRenderComputed.dom;
2627
const imgSelector = dom.querySelector('img');
2728

28-
imgSelector?.setAttribute('alt', '');
29-
imgSelector?.setAttribute('role', 'presentation');
30-
imgSelector?.setAttribute('aria-hidden', 'true');
31-
imgSelector?.setAttribute('tabindex', '-1');
29+
const withCaption =
30+
block.props.caption && dom.querySelector('.bn-file-caption');
31+
32+
const accessibleImageWithCaption = () => {
33+
imgSelector?.setAttribute('alt', block.props.caption);
34+
imgSelector?.removeAttribute('aria-hidden');
35+
imgSelector?.setAttribute('tabindex', '0');
36+
37+
// Fix RGAA 1.9.1: Convert to figure/figcaption structure if caption exists
38+
const captionElement = dom.querySelector('.bn-file-caption');
39+
40+
if (captionElement) {
41+
const figureElement = document.createElement('figure');
42+
43+
// Copy all attributes from the original div
44+
figureElement.className = dom.className;
45+
const styleAttr = dom.getAttribute('style');
46+
if (styleAttr) {
47+
figureElement.setAttribute('style', styleAttr);
48+
}
49+
figureElement.style.setProperty('margin', '0');
50+
51+
Array.from(dom.children).forEach((child) => {
52+
figureElement.appendChild(child.cloneNode(true));
53+
});
54+
55+
// Replace the <p> caption with <figcaption>
56+
const figcaptionElement = document.createElement('figcaption');
57+
const originalCaption = figureElement.querySelector('.bn-file-caption');
58+
if (originalCaption) {
59+
figcaptionElement.className = originalCaption.className;
60+
figcaptionElement.textContent = originalCaption.textContent;
61+
originalCaption.parentNode?.replaceChild(
62+
figcaptionElement,
63+
originalCaption,
64+
);
65+
66+
// Add explicit role and aria-label for better screen reader support
67+
figureElement.setAttribute('role', 'img');
68+
figureElement.setAttribute(
69+
'aria-label',
70+
t(`Image: {{title}}`, { title: figcaptionElement.textContent }),
71+
);
72+
}
73+
74+
// Return the figure element as the new dom
75+
return {
76+
...imageRenderComputed,
77+
dom: figureElement,
78+
};
79+
}
80+
};
81+
82+
const accessibleImage = () => {
83+
imgSelector?.setAttribute('alt', '');
84+
imgSelector?.setAttribute('role', 'presentation');
85+
imgSelector?.setAttribute('aria-hidden', 'true');
86+
imgSelector?.setAttribute('tabindex', '-1');
87+
};
88+
89+
// Set accessibility attributes for the image
90+
const result = withCaption ? accessibleImageWithCaption() : accessibleImage();
91+
92+
// Return the result if accessibleImageWithCaption created a figure, otherwise return original
93+
if (result) {
94+
return result;
95+
}
3296

3397
return {
3498
...imageRenderComputed,

0 commit comments

Comments
 (0)