Skip to content

Commit

Permalink
Support focus loop
Browse files Browse the repository at this point in the history
  • Loading branch information
mj12albert committed Sep 12, 2024
1 parent 1e53b78 commit 93364ca
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/data/api/accordion-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"default": "0"
},
"disabled": { "type": { "name": "bool" }, "default": "false" },
"loop": { "type": { "name": "bool" }, "default": "true" },
"onOpenChange": { "type": { "name": "func" } },
"openMultiple": { "type": { "name": "bool" }, "default": "true" },
"render": { "type": { "name": "union", "description": "element<br>&#124;&nbsp;func" } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"description": "The default value representing the currently open <code>Accordion.Item</code> This is the uncontrolled counterpart of <code>value</code>."
},
"disabled": { "description": "If <code>true</code>, the component is disabled." },
"loop": {
"description": "If <code>true</code>, focus will loop when moving focus between <code>Trigger</code>s using the arrow keys."
},
"onOpenChange": {
"description": "Callback fired when an Accordion section is opened or closed. The value representing the involved section is provided as an argument."
},
Expand Down
8 changes: 8 additions & 0 deletions packages/mui-base/src/Accordion/Root/AccordionRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const AccordionRoot = React.forwardRef(function AccordionRoot(
direction,
disabled = false,
htmlHidden,
loop,
onOpenChange,
openMultiple = true,
orientation,
Expand All @@ -52,6 +53,7 @@ const AccordionRoot = React.forwardRef(function AccordionRoot(
direction,
disabled,
defaultValue,
loop,
orientation,
onOpenChange,
openMultiple,
Expand Down Expand Up @@ -158,6 +160,12 @@ AccordionRoot.propTypes /* remove-proptypes */ = {
* @ignore
*/
htmlHidden: PropTypes.oneOf(['hidden', 'until-found']),
/**
* If `true`, focus will loop when moving focus between `Trigger`s using
* the arrow keys.
* @default true
*/
loop: PropTypes.bool,
/**
* Callback fired when an Accordion section is opened or closed.
* The value representing the involved section is provided as an argument.
Expand Down
21 changes: 18 additions & 3 deletions packages/mui-base/src/Accordion/Root/useAccordionRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export function useAccordionRoot(
animated = true,
disabled = false,
direction = 'ltr',
loop = true,
onOpenChange = NOOP,
orientation = 'vertical',
openMultiple = true,
Expand Down Expand Up @@ -102,11 +103,19 @@ export function useAccordionRoot(
const thisIndex = triggers.indexOf(event.target as HTMLButtonElement);

function toNext() {
nextIndex = Math.min(thisIndex + 1, lastIndex);
if (loop) {
nextIndex = thisIndex + 1 > lastIndex ? 0 : thisIndex + 1;
} else {
nextIndex = Math.min(thisIndex + 1, lastIndex);
}
}

function toPrev() {
nextIndex = thisIndex - 1;
if (loop) {
nextIndex = thisIndex === 0 ? lastIndex : thisIndex - 1;
} else {
nextIndex = thisIndex - 1;
}
}

switch (event.key) {
Expand Down Expand Up @@ -154,7 +163,7 @@ export function useAccordionRoot(
},
});
},
[direction, orientation],
[direction, loop, orientation],
);

return React.useMemo(
Expand Down Expand Up @@ -214,6 +223,12 @@ export namespace useAccordionRoot {
* @default 'ltr'
*/
direction?: Direction;
/**
* If `true`, focus will loop when moving focus between `Trigger`s using
* the arrow keys.
* @default true
*/
loop?: boolean;
/**
* Callback fired when an Accordion section is opened or closed.
* The value representing the involved section is provided as an argument.
Expand Down

0 comments on commit 93364ca

Please sign in to comment.