Skip to content

Commit c4c32e7

Browse files
authored
fix: Properly clean up inert if element is hidden via sub dialog combobox (#8739)
* fix: Properly clean up inert if element is hidden via sub dialog combobox * get rid of tests in favor of story
1 parent 216cd6d commit c4c32e7

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

packages/@react-aria/overlays/src/ariaHideOutside.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ export function ariaHideOutside(targets: Element[], options?: AriaHideOutsideOpt
5656
element.setAttribute('aria-hidden', 'true');
5757
} else {
5858
element.removeAttribute('aria-hidden');
59+
if (element instanceof windowObj.HTMLElement) {
60+
// We only ever call setHidden with hidden = false when the nodeCount is 1 aka
61+
// we are trying to make the element visible to screen readers again, so remove inert as well
62+
element.inert = false;
63+
}
5964
}
6065
};
6166

packages/react-aria-components/stories/Modal.stories.tsx

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {Button, Dialog, DialogTrigger, Heading, Modal, ModalOverlay} from 'react-aria-components';
13+
import {Button, ComboBox, Dialog, DialogTrigger, Heading, Input, Label, ListBox, Modal, ModalOverlay, Popover, TextField} from 'react-aria-components';
1414
import {Meta, StoryFn} from '@storybook/react';
1515
import React, {useEffect} from 'react';
1616
import './styles.css';
17+
import {MyListBoxItem} from './utils';
18+
import styles from '../example/index.css';
19+
1720

1821
export default {
1922
title: 'React Aria Components/Modal',
@@ -188,3 +191,83 @@ export const ModalInteractionOutsideDefaultOverlayExample: ModalStory = () => {
188191
</DialogTrigger>
189192
);
190193
};
194+
195+
function InertTest() {
196+
return (
197+
<DialogTrigger>
198+
<Button>Open modal</Button>
199+
<ModalOverlay
200+
isDismissable
201+
style={{
202+
position: 'fixed',
203+
zIndex: 100,
204+
top: 0,
205+
left: 0,
206+
bottom: 0,
207+
right: 0,
208+
background: 'rgba(0, 0, 0, 0.5)',
209+
display: 'flex',
210+
alignItems: 'center',
211+
justifyContent: 'center'
212+
}}>
213+
<Modal
214+
style={{
215+
background: 'Canvas',
216+
color: 'CanvasText',
217+
border: '1px solid gray',
218+
padding: 30
219+
}}>
220+
<Dialog>
221+
{() => (
222+
<>
223+
<TextField>
224+
<Label>First name</Label>
225+
<Input />
226+
</TextField>
227+
<DialogTrigger>
228+
<Button>Combobox Trigger</Button>
229+
<Popover placement="bottom start">
230+
<Dialog>
231+
{() => (
232+
<ComboBox
233+
menuTrigger="focus"
234+
autoFocus
235+
name="combo-box-example"
236+
data-testid="combo-box-example"
237+
allowsEmptyCollection>
238+
<Label style={{display: 'block'}}>Test</Label>
239+
<div style={{display: 'flex'}}>
240+
<Input />
241+
<Button>
242+
<span aria-hidden="true" style={{padding: '0 2px'}}></span>
243+
</Button>
244+
</div>
245+
<ListBox
246+
className={styles.menu}>
247+
<MyListBoxItem>Foo</MyListBoxItem>
248+
<MyListBoxItem>Bar</MyListBoxItem>
249+
<MyListBoxItem>Baz</MyListBoxItem>
250+
<MyListBoxItem href="http://google.com">Google</MyListBoxItem>
251+
</ListBox>
252+
</ComboBox>
253+
)}
254+
</Dialog>
255+
</Popover>
256+
</DialogTrigger>
257+
</>
258+
)}
259+
</Dialog>
260+
</Modal>
261+
</ModalOverlay>
262+
</DialogTrigger>
263+
);
264+
}
265+
266+
export const InertTestStory = {
267+
render: () => <InertTest />,
268+
parameters: {
269+
description: {
270+
data: 'You should be able to click "Combobox Trigger" and then click on the textfield, closing the subdialog. A second click should move focus into the textfield'
271+
}
272+
}
273+
};

0 commit comments

Comments
 (0)