Skip to content

Commit

Permalink
Add support for arrays of active event keys to Accordion (#1286)
Browse files Browse the repository at this point in the history
* Add support for arrays of active event keys to Accordion

* Add misc CSS things Nat wants

* Fix css logic

* Fix CSS to avoid doubling the top border
  • Loading branch information
Dchyk authored Sep 6, 2024
1 parent d3b2725 commit 448a43c
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 5 deletions.
86 changes: 86 additions & 0 deletions src/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,48 @@ Default.args = {
title: 'Accordion Toggle',
};

export function AlwaysOpen(args) {
return (
<Accordion alwaysOpen>
<AccordionItem eventKey="0">
<AccordionToggle
eventKey="0"
leadingIcon={faCreditCard}
{...args}
/>
<AccordionCollapse eventKey="0">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</AccordionCollapse>
</AccordionItem>
<AccordionItem eventKey="1">
<AccordionToggle
eventKey="1"
leadingIcon={faCreditCard}
{...args}
/>
<AccordionCollapse eventKey="1">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</AccordionCollapse>
</AccordionItem>
</Accordion>
);
}

AlwaysOpen.args = {
chevronLeft: false,
disabled: false,
helperText: 'helper text',
title: 'Accordion Toggle - always open',
};

export function DefaultOpen(args) {
return (
<Accordion defaultActiveKey="1">
Expand Down Expand Up @@ -307,6 +349,50 @@ Borderless.args = {
title: 'Accordion Toggle',
};

export function BorderlessBorderBottomFlushToggles(args) {
return (
<Accordion flush>
<AccordionItem borderless eventKey="0">
<AccordionToggle
borderBottom
eventKey="0"
flush
{...args}
/>
<AccordionCollapse eventKey="0">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</AccordionCollapse>
</AccordionItem>
<AccordionItem borderless eventKey="1">
<AccordionToggle
borderBottom
eventKey="1"
flush
{...args}
/>
<AccordionCollapse eventKey="1">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</AccordionCollapse>
</AccordionItem>
</Accordion>
);
}

BorderlessBorderBottomFlushToggles.args = {
chevronLeft: false,
disabled: false,
helperText: 'helper text',
title: 'Accordion Toggle',
};

export function InCard(args) {
return (
<>
Expand Down
6 changes: 6 additions & 0 deletions src/Accordion/AccordionCollapse.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@
padding-top: 0px !important;
}
}
/* If the parent AccordionToggle has a border-bottom applied, remove the top one here */
.borderBottom {
.AccordionCollapse {
border-top: none;
}
}
8 changes: 8 additions & 0 deletions src/Accordion/AccordionToggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
grid-template-areas: 'content chevron-right';
padding: 16px 24px;

&.borderBottom {
border-bottom: 1px solid var(--ux-gray-400);
}

&.flush {
padding: 16px 4px;
}

&--right {
grid-area: chevron-right;

Expand Down
18 changes: 13 additions & 5 deletions src/Accordion/AccordionToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import AccordionContext from 'react-bootstrap/AccordionContext';
import './AccordionToggle.scss';
import { faChevronUp } from '@fortawesome/pro-solid-svg-icons';

import { isEventKeyActive } from './utils';

type AccordionToggleProps = {
borderBottom?: boolean;
/**
Set Chevron icon to open/close quarter turn from lateral
*/
Expand All @@ -30,6 +33,7 @@ type AccordionToggleProps = {
*/
disabled?: boolean;
eventKey: string;
flush?: boolean;
helperText?: string;
leadingIcon?: object;
title?: string;
Expand All @@ -38,13 +42,15 @@ type AccordionToggleProps = {
};

function AccordionToggle({
borderBottom,
children,
chevronLateral,
chevronLeft,
chevronRight,
collapsedText,
disabled,
eventKey,
flush,
helperText,
leadingIcon,
title,
Expand All @@ -54,10 +60,12 @@ function AccordionToggle({
}: AccordionToggleProps) {
const { activeEventKey } = React.useContext(AccordionContext);

const eventKeyIsActive = isEventKeyActive(eventKey, activeEventKey);

const [isCollapsed, setIsCollapsed] = useState(true);

const decoratedOnClick = useAccordionButton(eventKey, () => {
if (eventKey !== activeEventKey) {
if (!eventKeyIsActive) {
setIsCollapsed(false);
}
setIsCollapsed((prev) => !prev);
Expand All @@ -68,14 +76,14 @@ function AccordionToggle({
};

useEffect(() => {
if (activeEventKey && eventKey !== activeEventKey) {
if (!eventKeyIsActive) {
handleCloseInactiveToggle();
}

if (activeEventKey && eventKey === activeEventKey) {
if (eventKeyIsActive) {
setIsCollapsed(((prev) => !prev));
}
}, [activeEventKey, eventKey]);
}, [eventKeyIsActive]);

return (
<button
Expand All @@ -92,7 +100,7 @@ function AccordionToggle({
type="button"
onClick={decoratedOnClick}
>
<div className="AccordionToggle__container">
<div className={classNames('AccordionToggle__container', { flush }, { borderBottom })}>
<div className="AccordionToggle__container--content">
{chevronLeft && (
<span className="AccordionToggle__chevron-left">
Expand Down
9 changes: 9 additions & 0 deletions src/Accordion/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { AccordionEventKey } from 'react-bootstrap/esm/AccordionContext';

export function isEventKeyActive(eventKey: string | null | undefined,
activeEventKey: AccordionEventKey) {
if (!eventKey) return false;

return (Array.isArray(activeEventKey) && activeEventKey.includes(eventKey)) ||
eventKey === activeEventKey;
}

0 comments on commit 448a43c

Please sign in to comment.