Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PPDSC-2152): single accordion #224

Merged
merged 22 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,762 changes: 1,118 additions & 644 deletions src/accordion/__tests__/__snapshots__/accordion.test.tsx.snap

Large diffs are not rendered by default.

385 changes: 268 additions & 117 deletions src/accordion/__tests__/accordion.stories.tsx

Large diffs are not rendered by default.

129 changes: 45 additions & 84 deletions src/accordion/__tests__/accordion.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import {fireEvent} from '@testing-library/react';
import React from 'react';
import {
IconFilledAccountBalance,
IconFilledExpandLess,
IconFilledExpandMore,
} from '../../icons';
import {Block} from '../../block';
import {IconFilledAccountBalance} from '../../icons';
import {
renderToFragmentWithTheme,
renderWithTheme,
} from '../../test/test-utils';
import {TextBlock} from '../../text-block';
import {createTheme} from '../../theme';
import {styled} from '../../utils';
import {Accordion} from '../accordion';

const StyledBlock = styled(Block)`
display: flex;
align-items: center;
`;

describe('Accordion', () => {
mstuartf marked this conversation as resolved.
Show resolved Hide resolved
const defaultProps = {
children: (
Expand All @@ -20,19 +24,24 @@ describe('Accordion', () => {
malesuada lacus ex, sit amet blandit leo lobortis eget.
</TextBlock>
),
header: 'Header',
header: (
<StyledBlock paddingInlineEnd="8px">
<IconFilledAccountBalance
overrides={{size: 'iconSize020', paddingInlineEnd: '8px'}}
/>
Header
</StyledBlock>
),
label: 'Label',
};
test('renders with default props', () => {
const fragment = renderToFragmentWithTheme(Accordion, defaultProps);
expect(fragment).toMatchSnapshot();
});
test('renders with startEnhancer', () => {
test('renders without startEnhancer', () => {
mstuartf marked this conversation as resolved.
Show resolved Hide resolved
const props = {
...defaultProps,
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
header: 'Header',
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
Expand All @@ -41,17 +50,6 @@ describe('Accordion', () => {
const props = {
...defaultProps,
expanded: true,
label: 'Label',
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
indicatorIcon: (
<IconFilledExpandMore
overrides={{
size: 'iconSize020',
}}
/>
),
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
Expand All @@ -60,17 +58,6 @@ describe('Accordion', () => {
const props = {
...defaultProps,
expanded: false,
label: 'Label',
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
indicatorIcon: (
<IconFilledExpandLess
overrides={{
size: 'iconSize020',
}}
/>
),
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
Expand All @@ -79,37 +66,22 @@ describe('Accordion', () => {
const props = {
...defaultProps,
disabled: true,
label: 'Label',
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
indicatorIcon: (
<IconFilledExpandLess
overrides={{
size: 'iconSize020',
}}
/>
),
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
});
test('renders with no divider', () => {
test('renders with no label', () => {
const props = {
...defaultProps,
expanded: true,
applyDivider: false,
label: 'Label',
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
indicatorIcon: (
<IconFilledExpandLess
overrides={{
size: 'iconSize020',
}}
/>
),
label: undefined,
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
});
test('renders with no header', () => {
const props = {
...defaultProps,
header: undefined,
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
Expand All @@ -119,22 +91,24 @@ describe('Accordion', () => {
...defaultProps,
headingAs: 'h4' as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span',
expanded: true,
label: 'Label',
startEnhancer: (
<IconFilledAccountBalance overrides={{size: 'iconSize020'}} />
),
indicatorIcon: (
<IconFilledExpandLess
overrides={{
size: 'iconSize020',
}}
/>
),
};
const fragment = renderToFragmentWithTheme(Accordion, props);
expect(fragment).toMatchSnapshot();
});
test('renders with overrides', () => {
test('should invoke onClick when clicked', () => {
const mockOnClick = jest.fn();
const props = {
...defaultProps,
onClick: mockOnClick,
};
const {getByTestId} = renderWithTheme(Accordion, props);

const headerButton = getByTestId('accordion-control');

fireEvent.click(headerButton);
expect(mockOnClick).toHaveBeenCalled();
});
test('renders with style overrides', () => {
const myCustomAccordionTheme = createTheme({
name: 'my-custom-accordion-theme',
overrides: {
Expand All @@ -156,13 +130,6 @@ describe('Accordion', () => {
color: 'black',
},
},
accordionDividerCustom: {
base: {
borderColor: '#f7aef8',
borderWidth: '{{borders.borderWidth030}}',
borderStyle: 'solid',
},
},
accordionPanelCustom: {
base: {
borderStyle: 'none none dotted none',
Expand All @@ -187,23 +154,17 @@ describe('Accordion', () => {
spaceInline: 'space030',
paddingBlock: 'spaceInset040',
paddingInline: 'spaceInset040',
indicatorIcon: {
stylePreset: 'inkPositive',
},
indicatorLabel: {
stylePreset: 'inkPositive',
typographyPreset: 'utilityButton020',
},
startEnhancer: {
indicatorIcon: {
stylePreset: 'inkPositive',
size: 'iconSize030',
},
},
panel: {
stylePreset: 'accordionPanelCustom',
},
divider: {
stylePreset: 'accordionDividerCustom',
},
},
},
myCustomAccordionTheme,
Expand Down
99 changes: 55 additions & 44 deletions src/accordion/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,92 @@ import {
StyledHeaderWrapper,
StyledAccordionButton,
StyledPanel,
StyledEnhancer,
StyledIndicatorIcon,
StyledIndicatorLabel,
StyledHeader,
StyledDividerWrapper,
StyledPanelWrapper,
StyledIconWrapper,
StyledHeader,
} from './styled';
import {AccordionProps} from './types';
import {AccordionIconProps, AccordionProps} from './types';
import defaults from './defaults';
import stylePresets from './style-presets';
import {useReactKeys} from '../utils/hooks';
import {Divider} from '../divider';
import {IconFilledExpandLess, IconFilledExpandMore} from '../icons';
import {getComponentOverrides} from '../utils/overrides';

const DefaultIcon = ({expanded, overrides}: AccordionIconProps) =>
expanded ? (
<IconFilledExpandLess
overrides={{
size: 'iconSize020',
...overrides,
}}
/>
) : (
<IconFilledExpandMore
overrides={{
size: 'iconSize020',
...overrides,
}}
/>
);

const ThemelessAccordion = React.forwardRef<HTMLDivElement, AccordionProps>(
(
{
headingAs = 'h3',
mutebg marked this conversation as resolved.
Show resolved Hide resolved
header,
label,
startEnhancer,
indicatorIcon,
expanded,
mstuartf marked this conversation as resolved.
Show resolved Hide resolved
applyDivider = true,
disabled = false,
children,
ariaControls,
id,
overrides = {},
overrides,
...props
},
ref,
) => {
const [autoGeneratedID] = useReactKeys(1);
const ariaControlsId = ariaControls || `${autoGeneratedID}-content`;
const ariaLabelledById = id || `${autoGeneratedID}-header`;
const ariaLabelledById = id || `${autoGeneratedID}-control`;

const [IndicatorIcon, indicatorIconProps] = getComponentOverrides(
overrides?.header?.indicatorIcon,
DefaultIcon,
{
expanded,
parentOverrides: overrides,
mutebg marked this conversation as resolved.
Show resolved Hide resolved
},
);

return (
<StyledAccodionContainer ref={ref} {...props}>
{header && (
<StyledHeaderWrapper as={headingAs}>
<StyledAccordionButton
overrides={overrides}
disabled={disabled}
id={ariaLabelledById}
aria-expanded={expanded}
aria-controls={ariaControlsId}
>
{startEnhancer && (
<StyledEnhancer overrides={overrides}>
{startEnhancer}
</StyledEnhancer>
)}
{header && <StyledHeader>{header}</StyledHeader>}
{label && (
<StyledIndicatorLabel overrides={overrides}>
{label}
</StyledIndicatorLabel>
)}
{indicatorIcon && (
<StyledIndicatorIcon overrides={overrides}>
{indicatorIcon}
</StyledIndicatorIcon>
)}
</StyledAccordionButton>
</StyledHeaderWrapper>
)}
<StyledHeaderWrapper as={headingAs}>
<StyledAccordionButton
overrides={overrides}
disabled={disabled}
aria-expanded={expanded}
aria-controls={ariaControlsId}
id={ariaLabelledById}
data-testid="accordion-control"
{...props}
>
<StyledHeader>{header}</StyledHeader>
{label && (
<StyledIndicatorLabel overrides={overrides}>
{label}
</StyledIndicatorLabel>
)}
<StyledIconWrapper>
<IndicatorIcon {...(indicatorIconProps as AccordionIconProps)} />
</StyledIconWrapper>
</StyledAccordionButton>
</StyledHeaderWrapper>
<StyledPanelWrapper expanded={expanded}>
{applyDivider && (
<StyledDividerWrapper overrides={overrides}>
<Divider overrides={overrides.divider} />
</StyledDividerWrapper>
)}
<StyledPanel
mutebg marked this conversation as resolved.
Show resolved Hide resolved
aria-labelledby={ariaLabelledById}
id={ariaControlsId}
data-testid="accordion-content"
role="region"
overrides={overrides}
>
Expand Down
8 changes: 0 additions & 8 deletions src/accordion/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,10 @@ export default {
spaceInline: 'space020',
paddingBlock: 'spaceInset030',
paddingInline: 'spaceInset030',
indicatorIcon: {
stylePreset: 'inkBase',
},
indicatorLabel: {
stylePreset: 'inkBase',
typographyPreset: 'utilityButton030',
},
startEnhancer: {
stylePreset: 'inkBase',
},
},
divider: {stylePreset: 'accordionDivider'},
panel: {
stylePreset: 'accordionPanel',
paddingBlock: 'spaceInset030',
Expand Down
7 changes: 0 additions & 7 deletions src/accordion/style-presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ export default {
color: '{{colors.inkNonEssential}}',
},
},
accordionDivider: {
base: {
borderColor: '{{colors.interface050}}',
borderWidth: '{{borders.borderWidth010}}',
borderStyle: 'solid',
},
},
accordionPanel: {
base: {
borderStyle: 'none none solid none',
Expand Down
Loading