Skip to content

Commit

Permalink
fix collapsible transition behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
Spencer Canner committed Feb 16, 2021
1 parent ba6cc73 commit 692009a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
1 change: 1 addition & 0 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
- Fixed `ActionList` `Item` not disabling properly when url prop is passed ([#3979](https://github.com/Shopify/polaris-react/pull/3979))
- Update `IndexTable`'s checkbox header to be aligned with other headers ([#3990](https://github.com/Shopify/polaris-react/issues/3990))
- Fixed `CheckableButton` missing border when focused ([#3987](https://github.com/Shopify/polaris-react/issues/3987))
- Fixed `Collapsible` bug where animation complete logic was being prematurely triggered by transitions in the children ([#4000](https://github.com/Shopify/polaris-react/pull/4000))

### Documentation

Expand Down
27 changes: 16 additions & 11 deletions src/components/Collapsible/Collapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function Collapsible({
const [height, setHeight] = useState(0);
const [isOpen, setIsOpen] = useState(open);
const [animationState, setAnimationState] = useState<AnimationState>('idle');
const collapisbleContainer = useRef<HTMLDivElement>(null);
const collapsibleContainer = useRef<HTMLDivElement>(null);

const isFullyOpen = animationState === 'idle' && open && isOpen;
const isFullyClosed = animationState === 'idle' && !open && !isOpen;
Expand All @@ -59,10 +59,15 @@ export function Collapsible({
},
};

const handleCompleteAnimation = useCallback(() => {
setAnimationState('idle');
setIsOpen(open);
}, [open]);
const handleCompleteAnimation = useCallback(
({target}: React.TransitionEvent<HTMLDivElement>) => {
if (target === collapsibleContainer.current) {
setAnimationState('idle');
setIsOpen(open);
}
},
[open],
);

useEffect(() => {
if (open !== isOpen) {
Expand All @@ -71,32 +76,32 @@ export function Collapsible({
}, [open, isOpen]);

useEffect(() => {
if (!open || !collapisbleContainer.current) return;
if (!open || !collapsibleContainer.current) return;
// If collapsible defaults to open, set an initial height
setHeight(collapisbleContainer.current.scrollHeight);
setHeight(collapsibleContainer.current.scrollHeight);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (!collapisbleContainer.current) return;
if (!collapsibleContainer.current) return;

switch (animationState) {
case 'idle':
break;
case 'measuring':
setHeight(collapisbleContainer.current.scrollHeight);
setHeight(collapsibleContainer.current.scrollHeight);
setAnimationState('animating');
break;
case 'animating':
setHeight(open ? collapisbleContainer.current.scrollHeight : 0);
setHeight(open ? collapsibleContainer.current.scrollHeight : 0);
}
}, [animationState, open, isOpen]);

return (
<div
id={id}
style={collapsibleStyles}
ref={collapisbleContainer}
ref={collapsibleContainer}
className={wrapperClassName}
onTransitionEnd={handleCompleteAnimation}
aria-expanded={open}
Expand Down

0 comments on commit 692009a

Please sign in to comment.