Skip to content

Commit

Permalink
fix: rework accordion component animation (carbon-design-system#9818)
Browse files Browse the repository at this point in the history
  • Loading branch information
cesardlinx committed Oct 12, 2023
1 parent 725a8ea commit 7c32a37
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 44 deletions.
32 changes: 25 additions & 7 deletions packages/react/src/components/Accordion/AccordionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ interface AccordionItemProps {
* The callback function to run on the `onAnimationEnd`
* event for the list item.
*/
handleAnimationEnd?: AnimationEventHandler<HTMLLIElement>;
handleAnimationEnd?: AnimationEventHandler<HTMLElement>;
}

interface AccordionToggleProps {
Expand Down Expand Up @@ -117,7 +117,6 @@ function AccordionItem({
...rest
}: PropsWithChildren<AccordionItemProps>) {
const [isOpen, setIsOpen] = useState(open);
const [animation, setAnimation] = useState('');
const accordionState = useContext(AccordionContext);

const disabledIsControlled = typeof controlledDisabled === 'boolean';
Expand All @@ -130,7 +129,6 @@ function AccordionItem({
const className = cx({
[`${prefix}--accordion__item`]: true,
[`${prefix}--accordion__item--active`]: isOpen,
[`${prefix}--accordion__item--${animation}`]: animation,
[`${prefix}--accordion__item--disabled`]: disabled,
[customClassName]: !!customClassName,
});
Expand All @@ -140,8 +138,24 @@ function AccordionItem({
// When the AccordionItem heading is clicked, toggle the open state of the
// panel
function onClick(event) {
const toggleElement = event.target;

let content = toggleElement.nextElementSibling;

// when toggle element is not the button
if (toggleElement.nodeName !== 'BUTTON') {
content = toggleElement.parentElement.nextElementSibling;
}

if (content.style.maxBlockSize) {
// accordion closes
content.style.maxBlockSize = null;
} else {
// accordion opens
content.style.maxBlockSize = content.scrollHeight + 15 + 'px';
}

const nextValue = !isOpen;
setAnimation(isOpen ? '' : 'expanding');
setIsOpen(nextValue);
if (onHeadingClick) {
// TODO: normalize signature, potentially:
Expand All @@ -164,7 +178,7 @@ function AccordionItem({
}

return (
<li className={className} {...rest} onAnimationEnd={onAnimationEnd}>
<li className={className} {...rest}>
<Toggle
disabled={disabled}
aria-controls={id}
Expand All @@ -178,8 +192,12 @@ function AccordionItem({
{title}
</Text>
</Toggle>
<div id={id} className={`${prefix}--accordion__content`}>
{children}
<div
className={`${prefix}--accordion__wrapper`}
onTransitionEnd={onAnimationEnd}>
<div id={id} className={`${prefix}--accordion__content`}>
{children}
</div>
</div>
</li>
);
Expand Down
50 changes: 13 additions & 37 deletions packages/styles/scss/components/accordion/_accordion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ $content-padding: 0 0 0 $spacing-05 !default;
display: list-item;
overflow: visible;
border-block-start: 1px solid $border-subtle;
transition: all $duration-fast-02 motion(standard, productive);

&:last-child {
border-block-end: 1px solid $border-subtle;
Expand Down Expand Up @@ -144,11 +143,18 @@ $content-padding: 0 0 0 $spacing-05 !default;
text-align: start;
}

.#{$prefix}--accordion__wrapper {
// Properties for when the accordion closes
padding: 0;
max-block-size: 0;
opacity: 0;
transition: all $duration-fast-02 motion(entrance, productive);
writing-mode: horizontal-tb;
}

.#{$prefix}--accordion__content {
display: none;
overflow: hidden;
padding-inline: layout.density('padding-inline');
// Transition property for when the accordion closes
transition: padding motion(standard, productive) $duration-fast-02;

// Custom breakpoints based on issue #4993
@include breakpoint-up(480px) {
Expand Down Expand Up @@ -189,44 +195,14 @@ $content-padding: 0 0 0 $spacing-05 !default;
display: block;
}

@keyframes collapse-accordion {
0% {
@include -content-visible;
}

100% {
@include -content-hidden;
}
}

@keyframes expand-accordion {
0% {
@include -content-hidden;
}

100% {
@include -content-visible;
}
}

.#{$prefix}--accordion__item--collapsing .#{$prefix}--accordion__content {
animation: $duration-fast-02 motion(standard, productive) collapse-accordion;
}

.#{$prefix}--accordion__item--expanding .#{$prefix}--accordion__content {
animation: $duration-fast-02 motion(standard, productive) expand-accordion;
}

.#{$prefix}--accordion__item--active {
overflow: visible;

.#{$prefix}--accordion__content {
display: block;
.#{$prefix}--accordion__wrapper {
// Properties for when the accordion opens
opacity: 1;
padding-block: $spacing-03;
padding-block-end: $spacing-06;
// Transition property for when the accordion opens
transition: padding-top motion(entrance, productive) $duration-fast-02,
padding-bottom motion(entrance, productive) $duration-fast-02;
}

.#{$prefix}--accordion__arrow {
Expand Down

0 comments on commit 7c32a37

Please sign in to comment.