Skip to content

Commit

Permalink
[joy-ui][Accordion] Fix AccordionDetails tabindex when expanding (#43246
Browse files Browse the repository at this point in the history
)

Signed-off-by: Shrey Bhadja <[email protected]>
Co-authored-by: Aarón García Hervás <[email protected]>
  • Loading branch information
Shreypatel13ll and aarongarciah authored Sep 19, 2024
1 parent 4663ab4 commit 4c30e68
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
46 changes: 46 additions & 0 deletions packages/mui-joy/src/AccordionDetails/AccordionDetails.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,51 @@ describe('<AccordionDetails />', () => {
expect(screen.getByRole('button')).to.have.attribute('aria-expanded', 'true');
expect(screen.getByTestId('textbox')).to.have.property('tabIndex', 2);
});

it('should retain the default tab index if not explicitly set', () => {
render(
<Accordion>
<AccordionSummary>title</AccordionSummary>
<AccordionDetails>
<input data-testid="textbox" />
</AccordionDetails>
</Accordion>,
);

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', -1);

fireEvent.click(screen.getByRole('button')); // open

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', 0);

fireEvent.click(screen.getByRole('button')); // close

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', -1);

fireEvent.click(screen.getByRole('button')); // reopen

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', 0);
});

it('should retain the -1 tab index when explicitly set', () => {
render(
<Accordion>
<AccordionSummary>title</AccordionSummary>
<AccordionDetails>
<input data-testid="textbox" tabIndex={-1} />
</AccordionDetails>
</Accordion>,
);

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', -1);

fireEvent.click(screen.getByRole('button')); // open

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', -1);

fireEvent.click(screen.getByRole('button')); // close

expect(screen.getByTestId('textbox')).to.have.property('tabIndex', -1);
});
});
});
25 changes: 13 additions & 12 deletions packages/mui-joy/src/AccordionDetails/AccordionDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,27 +98,28 @@ const AccordionDetails = React.forwardRef(function AccordionDetails(inProps, ref
const handleRef = useForkRef(rootRef, ref);

React.useEffect(() => {
// When accordion is closed, prevent tabbing into the details content.
if (rootRef.current) {
const elements = rootRef.current.querySelectorAll(
'a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])',
);
elements.forEach((elm) => {
if (expanded) {
const prevTabIndex = elm.getAttribute('data-prev-tabindex');
const currentTabIndex = elm.getAttribute('tabindex');

if (currentTabIndex && prevTabIndex) {
// restore tabindex
elm.setAttribute('tabindex', prevTabIndex);
elm.removeAttribute('data-prev-tabindex');
}
elements.forEach((elm) => {
const currentTabIndex = elm.getAttribute('tabindex');
const prevTabIndex = elm.getAttribute('data-prev-tabindex');

if (!prevTabIndex && !currentTabIndex) {
if (expanded) {
// Restore the previous tabindex if it exists, or remove it if it was "unset"
if (prevTabIndex === 'unset') {
elm.removeAttribute('tabindex');
} else if (prevTabIndex !== null) {
elm.setAttribute('tabindex', prevTabIndex);
}
elm.removeAttribute('data-prev-tabindex');
} else {
elm.setAttribute('data-prev-tabindex', elm.getAttribute('tabindex') || '');
// If element has no data-prev-tabindex, store the current tabindex or "unset"
if (prevTabIndex === null) {
elm.setAttribute('data-prev-tabindex', currentTabIndex || 'unset');
}
elm.setAttribute('tabindex', '-1');
}
});
Expand Down

0 comments on commit 4c30e68

Please sign in to comment.