Skip to content

Commit

Permalink
[CPT-2535] Add property to place accordion icon on the left (#4522)
Browse files Browse the repository at this point in the history
  • Loading branch information
angelinastavniiciuc authored Sep 4, 2024
1 parent 2903881 commit 34f55d4
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-pots-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@toptal/picasso-accordion': minor
---

- add `expandIconPlacement` prop to Picasso Accordion
36 changes: 26 additions & 10 deletions packages/base/Accordion/src/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AccordionDetails } from '../AccordionDetails'
import styles from './styles'

export type Borders = 'all' | 'middle' | 'none'
export type ExpandIconPlacement = 'left' | 'right'

const useStyles = makeStyles<Theme>(styles, {
name: 'PicassoAccordion',
Expand All @@ -44,6 +45,8 @@ export interface Props
disabled?: boolean
/** Customize icon indicating expanded status */
expandIcon?: ReactElement
/** Customize icon placement */
expandIconPlacement?: ExpandIconPlacement
/** Defines where the horizontal borders show */
borders?: Borders
/** Callback invoked when `Accordion` item is toggled */
Expand Down Expand Up @@ -75,6 +78,7 @@ export const Accordion = forwardRef<HTMLElement, Props>(function Accordion(
expanded,
defaultExpanded,
expandIcon,
expandIconPlacement = 'right',
borders,
disabled,
className,
Expand Down Expand Up @@ -110,6 +114,23 @@ export const Accordion = forwardRef<HTMLElement, Props>(function Accordion(

const appliedBorders = children || expanded ? (borders as Borders) : 'none'

const renderExpandIcon = (expandIconPosition: 'left' | 'right') => {
if (expandIcon) {
return decorateWithExpandIconClasses(expandIcon, expandIconClass)
}

return (
<div
className={cx({
[classes.expandIconAlignTop]: true,
[classes.expandIconLeft]: expandIconPosition === 'left',
})}
>
<ButtonAction icon={<ArrowDownMinor16 className={expandIconClass} />} />
</div>
)
}

return (
<MUIAccordion
{...rest}
Expand All @@ -129,22 +150,17 @@ export const Accordion = forwardRef<HTMLElement, Props>(function Accordion(
<AccordionSummary
classes={{
root: classes.summary,
content: classes.content,
content: `${classes.content} ${
expandIconPlacement === 'left' ? classes.contentRight : ''
}`,
}}
expandIcon={null}
onClick={handleSummaryClick}
data-testid={testIds?.accordionSummary}
>
{expandIconPlacement === 'left' && renderExpandIcon('left')}
{children}
{expandIcon ? (
decorateWithExpandIconClasses(expandIcon, expandIconClass)
) : (
<div className={classes.expandIconAlignTop}>
<ButtonAction
icon={<ArrowDownMinor16 className={expandIconClass} />}
/>
</div>
)}
{expandIconPlacement === 'right' && renderExpandIcon('right')}
</AccordionSummary>
) : (
<EmptyAccordionSummary data-testid={testIds?.emptyAccordionSummary} />
Expand Down
84 changes: 84 additions & 0 deletions packages/base/Accordion/src/Accordion/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,87 @@ exports[`Accordion renders disabled 1`] = `
</div>
</div>
`;

exports[`Accordion renders expand icon on the left if the \`expandIconPlacement\` prop is provided 1`] = `
<div>
<div
class="Picasso-root"
>
<div
class="MuiPaper-root MuiAccordion-root PicassoAccordion-root PicassoAccordion-bordersAll MuiAccordion-rounded MuiPaper-elevation0 MuiPaper-rounded"
>
<div
aria-disabled="false"
aria-expanded="false"
class="MuiButtonBase-root MuiAccordionSummary-root WithStyles(ForwardRef(AccordionSummary))-root PicassoAccordion-summary"
role="button"
tabindex="0"
>
<div
class="MuiAccordionSummary-content WithStyles(ForwardRef(AccordionSummary))-content PicassoAccordion-content PicassoAccordion-contentRight"
>
<div
class="PicassoAccordion-expandIconAlignTop PicassoAccordion-expandIconLeft"
>
<button
aria-disabled="false"
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-none [&+&]:ml-4 cursor-pointer border-none px-0 bg-transparent h-[1.5em] hover:text-blue hover:underline active:text-blue active:underline focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-visible:rounded-sm"
data-component-type="button"
role="button"
tabindex="0"
type="button"
>
<span
class="items-center inline-flex font-semibold text-blue text-md"
>
<svg
class="PicassoSvgArrowDownMinor16-root text-[1.2em] flex-1 w-4 h-4 text-graphite PicassoAccordion-expandIcon"
style="min-width: 16px; min-height: 16px;"
viewBox="0 0 16 16"
>
<path
d="m11.997 5.29.707.707-4 4-.707.707-.707-.707-4-4 .707-.707 4 4 4-4Z"
/>
</svg>
</span>
</button>
</div>
<div
class="PicassoAccordion-summaryWrapper"
data-testid="accordion-summary"
>
What is a dog?
</div>
</div>
</div>
<div
class="MuiCollapse-root MuiCollapse-hidden"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<div
role="region"
>
<div
class="flex p-0"
>
<div
class="PicassoAccordion-detailsWrapper"
data-testid="accordion-details"
>
A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import { Accordion, Grid } from '@toptal/picasso'

const Example = () => (
<Grid>
<Grid.Item sm={6}>
<Accordion
expandIconPlacement='left'
defaultExpanded
content={<DetailsDogDefinitionPanel />}
>
<Accordion.Summary>What is a dog?</Accordion.Summary>
</Accordion>
</Grid.Item>
</Grid>
)

const DetailsDogDefinitionPanel = () => (
<Accordion.Details>
A dog is a type of domesticated animal. Known for its loyalty and
faithfulness, it can be found as a welcome guest in many households across
the world.
</Accordion.Details>
)

export default Example
9 changes: 9 additions & 0 deletions packages/base/Accordion/src/Accordion/story/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ page
},
'base/Accordion'
)
.addExample(
'Accordion/story/ExpandIconPlacement.example.tsx',
{
title: 'Expand Icon Placement',
description:
'Accordion expand icon is placed to the right until the `expandIconPlacement` prop is set to `left`.',
},
'base/Accordion'
)
.addExample(
'Accordion/story/BorderedGroups.example.tsx',
{
Expand Down
6 changes: 6 additions & 0 deletions packages/base/Accordion/src/Accordion/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ export default ({ palette, typography }: Theme) => {
height: '1.5em',
alignSelf: 'flex-start',
},
expandIconLeft: {
marginRight: '0.5em',
},
summary: {
color: palette.common.black,
},
Expand All @@ -101,5 +104,8 @@ export default ({ palette, typography }: Theme) => {
justifyContent: 'space-between',
lineHeight: '1.5em',
},
contentRight: {
justifyContent: 'normal',
},
})
}
6 changes: 6 additions & 0 deletions packages/base/Accordion/src/Accordion/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ describe('Accordion', () => {
expect(handleChange).toHaveBeenCalledTimes(3)
})

it('renders expand icon on the left if the `expandIconPlacement` prop is provided', () => {
const { container } = renderAccordion({ expandIconPlacement: 'left' })

expect(container).toMatchSnapshot()
})

it('renders disabled', async () => {
const { container } = renderAccordion({ disabled: true })

Expand Down

0 comments on commit 34f55d4

Please sign in to comment.