Skip to content

Commit

Permalink
feat(accordion): implements styles and finishes a11y features
Browse files Browse the repository at this point in the history
  • Loading branch information
gui-santos committed Jul 30, 2020
1 parent 11801c3 commit e777282
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,59 @@
@import 'settings/colors';
@import 'settings/typography';
@import 'settings/transitions';
@import 'settings/dimensions';

.Accordion {
display: inline-block;
box-sizing: border-box;
padding: 0;
margin: 0;
list-style: none;

& li {
border-bottom: 1px solid var(--color-element-mid);

&:first-child {
border-top: 1px solid var(--color-element-mid);
}
}
}

.Accordion--start {
& .AccordionHeader svg {
min-width: 9px; /* necessary to algin the chevron properly */
margin-right: var(--spacing-xs);
}
}

.Accordion--end {
& .AccordionHeader {
flex-direction: row-reverse;
justify-content: space-between;
}
}

.AccordionHeader {
display: flex;
flex-direction: row;
align-items: center;
border: 0;
padding: 1rem;
background-color: transparent;
font-family: var(--font-stack-primary);
font-size: var(--font-size-l);
font-weight: var(--font-weight-demi-bold);
line-height: var(--line-height-default);
color: var(--color-text-base);
width: 100%;
cursor: pointer;
transition: background-color var(--transition-duration-default)
var(--transition-easing-default);

&:hover {
background-color: var(--color-element-lightest);
}
&:focus {
outline: none;
background-color: var(--color-element-lightest);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,56 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { text } from '@storybook/addon-knobs';
import { text, select } from '@storybook/addon-knobs';

import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
import Typography from '../Typography/Typography';
import Paragraph from '../Typography/Paragraph';
import notes from './README.md';

storiesOf('(alpha))|Accordion', module)
.addParameters({
propTypes: Accordion['__docgenInfo'],
})
.add('default', () => (
<Accordion className={text('className', '')}>
<AccordionItem />
<AccordionItem />
<AccordionItem />
</Accordion>
));
.add(
'default',
() => (
<Accordion
align={select('Align', ['start', 'end'], Accordion.defaultProps.align)}
>
<AccordionItem title={text('First accordion title', 'First accordion')}>
<Typography>
<Paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</Paragraph>
</Typography>
</AccordionItem>
<AccordionItem
title={text('Second accordion title', 'Second accordion')}
>
<Typography>
<Paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</Paragraph>
</Typography>
</AccordionItem>
<AccordionItem title={text('Third accordion title', 'Third accordion')}>
<Typography>
<Paragraph>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
</Paragraph>
</Typography>
</AccordionItem>
</Accordion>
),
{ notes },
);
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { FC } from 'react';
import React from 'react';
import cn from 'classnames';

import styles from './Accordion.css';

type AlignTypes = 'start' | 'end';

export interface AccordionProps {
/**
* Class names to be appended to the className prop of the Accordion wrapper
Expand All @@ -16,19 +18,27 @@ export interface AccordionProps {
* An ID used for testing purposes applied as a data attribute (data-test-id)
*/
testId?: string;
/**
* Specify the alignment of the chevron inside the accordion header
*/
align?: AlignTypes;
}

const defaultProps = {
align: 'end',
testId: 'cf-ui-accordion',
};

export const Accordion: FC<AccordionProps> = ({
className,
export const Accordion = ({
align,
children,
className,
testId,
...otherProps
}: AccordionProps) => {
const classNames = cn(styles.Accordion, className);
const classNames = cn(styles.Accordion, className, {
[styles[`Accordion--${align}`]]: align,
});

return (
<ul className={classNames} data-test-id={testId} {...otherProps}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React, { FC } from 'react';
import Subheading from '../../Typography/Subheading';
import Icon from '../../Icon';

import styles from '../Accordion.css';

interface AccordionHeaderProps {
children: React.ReactNode;
handleClick: VoidFunction;
Expand All @@ -23,9 +25,13 @@ export const AccordionHeader: FC<AccordionHeaderProps> = ({
aria-expanded={isOpen}
aria-controls={`accordion-panel--${ariaId}`}
id={`accordion--${ariaId}`}
className={styles.AccordionHeader}
onClick={handleClick}
>
<Icon icon={isOpen ? 'ChevronDown' : 'ChevronRight'} />
<Icon
icon={isOpen ? 'ChevronDownTrimmed' : 'ChevronRightTrimmed'}
color="secondary"
/>
{children}
</button>
</Subheading>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,34 @@ export interface AccordionItemProps {
*/
testId?: string;
/**
* A boolean that controls if the content of the accordion is expanded or not
* The accordion title
*/
isOpen?: boolean;
title: React.ReactNode;
}

const defaultProps: AccordionItemProps = {
testId: 'cf-ui-accordion',
title: 'Accordion Title',
testId: 'cf-ui-accordion-item',
};

const AccordionItem: FC<AccordionItemProps> = ({
title,
testId,
children,
}: AccordionItemProps) => {
const [isExpanded, setIsExpanded] = useState(false);
const id = useId();

const onClick = () => setIsExpanded(!isExpanded);

return (
<li data-test-id={testId}>
<li data-test-id={`${testId}-${id}`}>
<AccordionHeader handleClick={onClick} isOpen={isExpanded} ariaId={id}>
Accordion {id}
{title}
</AccordionHeader>

<AccordionPanel ariaId={id} isOpen={isExpanded}>
Content for accordion {id}
{children}
</AccordionPanel>
</li>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
@import 'settings/colors';
@import 'settings/typography';
@import 'settings/transitions';
@import 'settings/dimensions';

.AccordionPanel {
box-sizing: border-box;
overflow: hidden;
padding: 0 var(--spacing-m);
height: 0;
/* max-height: 0; */
/* transition: all 1s ease-in-out; */
}

.AccordionPanel--expanded {
padding: 0 var(--spacing-m) var(--spacing-m);
height: auto;
/* max-height: 600px; */
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import cn from 'classnames';
import styles from './AccordionPanel.css';

interface AccordionPanelProps {
children: React.ReactNode;
children?: React.ReactNode;
ariaId?: number;
isOpen: boolean;
ariaId: number | null;
}

const defaultProps: AccordionPanelProps = {
isOpen: false,
};

export const AccordionPanel: FC<AccordionPanelProps> = ({
children,
isOpen,
Expand All @@ -27,8 +31,6 @@ export const AccordionPanel: FC<AccordionPanelProps> = ({
</div>
);
};
AccordionPanel.defaultProps = {
isOpen: false,
};
AccordionPanel.defaultProps = defaultProps;

export default AccordionPanel;

0 comments on commit e777282

Please sign in to comment.