Skip to content

Commit

Permalink
feat: accordion: adds rendercontentalways prop managed by expanded (#816
Browse files Browse the repository at this point in the history
)

* feat: accordion: adds rendercontentalways prop managed by expanded

* chore: accordion: address pr feedback and rename state var
  • Loading branch information
dkilgore-eightfold authored Apr 17, 2024
1 parent e66947d commit 891d37e
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/components/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const __namedExportsOrder = [
];

Single.args = {
renderContentAlways: true,
children: (
<>
<div style={{ height: 'auto' }}>
Expand Down
27 changes: 27 additions & 0 deletions src/components/Accordion/Accordion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Layout from '../Layout';
import { List } from '../List';
import { Stack } from '../Stack';
import { fireEvent, render, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';

Enzyme.configure({ adapter: new Adapter() });

Expand Down Expand Up @@ -220,4 +221,30 @@ describe('Accordion', () => {
expect(() => container).not.toThrowError();
expect(container).toMatchSnapshot();
});

test('renders content always when renderContentAlways is true', () => {
const { queryByText } = render(
<Accordion {...accordionProps} renderContentAlways={true}>
<div>Test Content</div>
</Accordion>
);

expect(queryByText('Test Content')).not.toBeNull();
});

test('does not render content when renderContentAlways is false and expanded is false', async () => {
const { queryByText } = render(
<Accordion
{...accordionProps}
renderContentAlways={false}
expanded={false}
>
<div>Test Content</div>
</Accordion>
);

await waitFor(() => {
expect(queryByText('Test Content')).not.toBeInTheDocument();
});
});
});
64 changes: 47 additions & 17 deletions src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { eventKeys, mergeClasses, uniqueId } from '../../shared/utilities';
import styles from './accordion.module.scss';
import themedComponentStyles from './accordion.theme.module.scss';

const ANIMATION_DURATION: number = 400;

export const AccordionSummary: FC<AccordionSummaryProps> = ({
badgeProps,
children,
Expand Down Expand Up @@ -107,15 +109,39 @@ export const AccordionSummary: FC<AccordionSummaryProps> = ({
};

export const AccordionBody: FC<AccordionBodyProps> = ({
bordered = true,
children,
expanded,
classNames,
expanded,
gradient,
id,
size,
bordered = true,
renderContentAlways,
...rest
}) => {
const [shouldRenderContent, setShouldRenderContent] =
useState<boolean>(renderContentAlways);

let timeout: ReturnType<typeof setTimeout>;

useEffect(() => {
if (renderContentAlways) {
setShouldRenderContent(true);
} else if (expanded) {
setShouldRenderContent(true);
if (timeout) clearTimeout(timeout);
} else {
timeout = setTimeout(() => {
setShouldRenderContent(false);
}, ANIMATION_DURATION);
}
return () => {
if (timeout) {
clearTimeout(timeout);
}
};
}, [expanded, renderContentAlways]);

const accordionBodyContainerStyles: string = mergeClasses(
styles.accordionBodyContainer,
{ [styles.show]: expanded }
Expand All @@ -140,37 +166,40 @@ export const AccordionBody: FC<AccordionBodyProps> = ({
role="region"
{...rest}
>
<div className={accordionBodyStyles}>{children}</div>
<div className={accordionBodyStyles}>
{shouldRenderContent && children}
</div>
</div>
);
};

export const Accordion: FC<AccordionProps> = React.forwardRef(
(
{
badgeProps,
bodyProps,
bordered = true,
children,
classNames,
configContextProps = {
noGradientContext: false,
noThemeContext: false,
},
disabled,
expandButtonProps,
expanded = false,
onAccordionChange,
classNames,
summary,
expandIconProps = { path: IconName.mdiChevronDown },
expandButtonProps,
children,
gradient = false,
id = uniqueId('accordion-'),
headerProps,
bodyProps,
shape = AccordionShape.Pill,
bordered = true,
iconProps,
badgeProps,
id = uniqueId('accordion-'),
onAccordionChange,
renderContentAlways = true,
shape = AccordionShape.Pill,
size = AccordionSize.Large,
summary,
theme,
themeContainerId,
disabled,
...rest
},
ref: Ref<HTMLDivElement>
Expand Down Expand Up @@ -232,11 +261,12 @@ export const Accordion: FC<AccordionProps> = React.forwardRef(
{summary}
</AccordionSummary>
<AccordionBody
id={id}
expanded={isExpanded}
size={size}
bordered={bordered}
expanded={isExpanded}
gradient={gradient}
id={id}
renderContentAlways={renderContentAlways}
size={size}
{...bodyProps}
>
{children}
Expand Down
5 changes: 5 additions & 0 deletions src/components/Accordion/Accordion.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ interface AccordionBaseProps extends OcBaseProps<HTMLDivElement> {
* @returns
*/
onIconButtonClick?: React.MouseEventHandler<HTMLButtonElement>;
/**
* Whether to render Accordion Body content when Accordion `expanded` is `false`.
* @default true
*/
renderContentAlways?: boolean;
/**
* Shape of the accordion
* @default AccordionShape.Pill
Expand Down

0 comments on commit 891d37e

Please sign in to comment.