Skip to content

Commit fc8925a

Browse files
authored
feat: add optional ariaLabel prop (#532)
* feat: add ariaLabel prop * update docs * Update docs
1 parent 7006025 commit fc8925a

3 files changed

Lines changed: 38 additions & 4 deletions

File tree

react-responsive-modal/__tests__/index.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,18 @@ describe('modal', () => {
533533
expect(document.getElementById(modalId)).toBeInTheDocument();
534534
});
535535
});
536+
537+
describe('prop: ariaLabel', () => {
538+
it('should render modal with aria-label attribute', async () => {
539+
const ariaLabel = 'Custom modal label';
540+
const { getByTestId } = render(
541+
<Modal open onClose={() => null} ariaLabel={ariaLabel}>
542+
<div>modal content</div>
543+
</Modal>,
544+
);
545+
546+
const modal = getByTestId('modal');
547+
expect(modal.getAttribute('aria-label')).toBe(ariaLabel);
548+
});
549+
});
536550
});

react-responsive-modal/src/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ export interface ModalProps {
120120
* Default to 'dialog'.
121121
*/
122122
role?: string;
123+
/**
124+
* ARIA label for modal
125+
*/
126+
ariaLabel?: string;
123127
/**
124128
* ARIA label for modal
125129
*/
@@ -179,6 +183,7 @@ export const Modal = React.forwardRef(
179183
classNames,
180184
styles,
181185
role = 'dialog',
186+
ariaLabel,
182187
ariaDescribedby,
183188
ariaLabelledby,
184189
containerId,
@@ -351,6 +356,7 @@ export const Modal = React.forwardRef(
351356
id={modalId}
352357
role={role}
353358
aria-modal="true"
359+
aria-label={ariaLabel}
354360
aria-labelledby={ariaLabelledby}
355361
aria-describedby={ariaDescribedby}
356362
data-testid="modal"

website/src/docs/index.mdx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,31 @@ By default, the Modal will be rendered at the end of the html body tag. If you w
155155

156156
## Accessibility
157157

158-
- Use the `aria-labelledby` and `aria-describedby` props to follow the [ARIA best practices](https://www.w3.org/TR/wai-aria-practices/#dialog_modal).
158+
- Follow the [ARIA best practices](https://www.w3.org/TR/wai-aria-practices/#dialog_modal) by using either:
159+
- `ariaLabelledby` and `ariaDescribedby` props to reference visible content, OR
160+
- `ariaLabel` prop for a simple accessible label
159161

160162
```javascript
163+
// Option 1: Using ariaLabelledby and ariaDescribedby
161164
<Modal
162165
open={open}
163166
onClose={onCloseModal}
164-
aria-labelledby="my-modal-title"
165-
aria-describedby="my-modal-description"
167+
ariaLabelledby="my-modal-title"
168+
ariaDescribedby="my-modal-description"
166169
>
167170
<h2 id="my-modal-title">My Title</h2>
168171
<p id="my-modal-description">My Description</p>
169172
</Modal>
173+
174+
// Option 2: Using ariaLabel
175+
<Modal
176+
open={open}
177+
onClose={onCloseModal}
178+
ariaLabel="Modal Title"
179+
>
180+
<h2>Preferences</h2>
181+
<p>Update your settings below</p>
182+
</Modal>
170183
```
171184

172185
- `aria-modal` is set to true automatically.
@@ -197,7 +210,8 @@ By default, the Modal will be rendered at the end of the html body tag. If you w
197210
| **animationDuration** | `number` | 300 | Animation duration in milliseconds. |
198211
| **role** | `string` | "dialog" | ARIA role for modal |
199212
| **ref** | `React.RefElement<HTMLDivElement>` | undefined | Ref for modal dialog element |
200-
| **ariaLabelledby** | `string` | | ARIA label for modal |
213+
| **ariaLabel** | `string` | | ARIA label for modal |
214+
| **ariaLabelledby** | `string` | | ARIA labelledby for modal |
201215
| **ariaDescribedby** | `string` | | ARIA description for modal |
202216
| **containerId** | `string` | | id attribute for modal container |
203217
| **modalId** | `string` | | id attribute for modal | |

0 commit comments

Comments
 (0)