Skip to content

Commit

Permalink
feat: adding toggle text as an option for accordion component
Browse files Browse the repository at this point in the history
  • Loading branch information
evilelam committed Nov 27, 2024
1 parent b70e69d commit 68e9b80
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "pcln-design-system",
"comment": "adding new prop useTextToggle to accordion component",
"type": "patch"
}
],
"packageName": "pcln-design-system"
}
18 changes: 18 additions & 0 deletions packages/core/src/Accordion/Accordion.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ describe('Accordion', () => {
expect(onToggle).toHaveBeenCalled()
})

it('toggles items with text toggle', () => {
const onToggle = jest.fn()
const items = testItems[0]
render(<Accordion items={[items]} onToggle={onToggle} useTextToggle />)
const header1 = screen.getByText('Header 1')
const moreTextTriggers = screen.getByText(/more/i)
const lessTextTriggers = screen.getByText(/less/i)

expect(moreTextTriggers).toHaveStyle('display: none')
expect(lessTextTriggers).toHaveStyle('display: inline')

fireEvent.click(header1)

expect(onToggle).toHaveBeenCalled()
expect(moreTextTriggers).toHaveStyle('display: inline')
expect(lessTextTriggers).toHaveStyle('display: none')
})

it('toggles items isExternallyControlled', () => {
const onToggle = jest.fn()
render(<Accordion items={testItems} onToggle={onToggle} isExternallyControlled />)
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const items = [
</>
),
value: 'item-1',
headerBg: 'success.light',
hoverBg: 'success.light',
},
{
headerLabel: (
Expand All @@ -58,6 +60,8 @@ const items = [
</>
),
value: 'item-2',
headerBg: 'success.light',
hoverBg: 'success.light',
},
{
content: (
Expand All @@ -69,6 +73,8 @@ const items = [
</>
),
value: 'item-3',
headerBg: 'success.light',
hoverBg: 'success.light',
},
]

Expand Down Expand Up @@ -141,6 +147,10 @@ export const ChevronClose = {
render: (args) => <Accordion {...args} isAnimatedChevron items={items} />,
}

export const UseTextToggle = {
render: (args) => <Accordion {...args} items={items} useTextToggle itemsState={['item-1', 'item-2']} />,
}

export const TrackStateMultiple = {
render: (args) => {
const [itemsState, setItemsState] = useState(['item-1', 'item-3'])
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/Accordion/Accordion.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,40 @@ export const StyledContent = styled(Accordion.Content)`
`

export const StyledTrigger = styled(Accordion.Trigger).attrs(borderRadiusAttrs)`
span[data-text-toggle='open'],
span[data-text-toggle='closed'] {
padding-left: 8px;
}
all: unset;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
color: ${(props) => (props.variation === 'hug' ? getPaletteColor('text.lightest')(props) : '')};
&[data-state='open'] .chevron {
transform: rotate(180deg);
}
&[data-state='closed'] {
span[data-text-toggle='open'] {
display: none;
}
span[data-text-toggle='closed'] {
display: inline;
}
${(props) =>
props.variation === 'flatCard' ? `background-color: ${getPaletteColor('background.light')(props)}` : ''}
}
&[data-state='open'] {
span[data-text-toggle='open'] {
display: inline;
}
span[data-text-toggle='closed'] {
display: none;
}
}
${(props) =>
props.variation === 'ladder'
? ''
Expand Down
74 changes: 45 additions & 29 deletions packages/core/src/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
StyledItem,
StyledTrigger,
} from './Accordion.styled'
import { Text } from '../Text/Text'

/**
* @public
Expand All @@ -23,6 +24,7 @@ export type AccordionProps = SpaceProps & {
variation?: string
isExternallyControlled?: boolean
headerDividerColor?: string
useTextToggle?: boolean
}

/**
Expand Down Expand Up @@ -50,6 +52,7 @@ export function Accordion({
variation = 'default',
p = '12px',
headerDividerColor,
useTextToggle = false,
...props
}: AccordionProps): React.ReactElement {
return items ? (
Expand All @@ -66,35 +69,48 @@ export function Accordion({
isolation: 'isolate',
}}
>
{items.map((child: AccordionItemProps, index) => (
<RadixAccordion.Item key={child.value} asChild value={child.value}>
<StyledItem
variation={variation}
overflow='hidden'
borderRadius='12px'
marginBottom='12px'
headerBg={child.headerBg}
hoverBg={child.hoverBg}
data-testid={`styled-item-${child.value}`}
headerDividerColor={index > 0 && headerDividerColor}
>
<StyledTrigger {...props} p={p} variation={variation}>
<Flex width='100%' justifyContent='space-between' alignItems='center'>
{child.headerLabel}
{child.headerActions ? (
<Box onClick={(e) => e.preventDefault()}>{child.headerActions}</Box>
) : null}
</Flex>
<IconContainer margin='auto' height='25px'>
<StyledChevron className='chevron' variation={variation} />
</IconContainer>
</StyledTrigger>
<StyledContent {...props} p={p} variation={variation} contentBg={child.contentBg}>
{child.content}
</StyledContent>
</StyledItem>
</RadixAccordion.Item>
))}
{items.map((child: AccordionItemProps, index) => {
return (
<RadixAccordion.Item key={child.value} asChild value={child.value}>
<StyledItem
variation={variation}
overflow='hidden'
borderRadius='12px'
marginBottom='12px'
headerBg={child.headerBg}
hoverBg={child.hoverBg}
data-testid={`styled-item-${child.value}`}
headerDividerColor={index > 0 && headerDividerColor}
>
<StyledTrigger {...props} p={p} variation={variation} hoverBg={child.hoverBg}>
<Flex width='100%' justifyContent='space-between' alignItems='center'>
{child.headerLabel}
{child.headerActions ? (
<Box onClick={(e) => e.preventDefault()}>{child.headerActions}</Box>
) : null}
</Flex>
{useTextToggle ? (
<>
<Text.span textStyle='captionBold' color='primary.base' data-text-toggle='open'>
Less
</Text.span>
<Text.span textStyle='captionBold' color='primary.base' data-text-toggle='closed'>
More
</Text.span>
</>
) : (
<IconContainer margin='auto' height='25px'>
<StyledChevron className='chevron' variation={variation} />
</IconContainer>
)}
</StyledTrigger>
<StyledContent {...props} p={p} variation={variation} contentBg={child.contentBg}>
{child.content}
</StyledContent>
</StyledItem>
</RadixAccordion.Item>
)
})}
</StyledAccordionRoot>
) : null
}

0 comments on commit 68e9b80

Please sign in to comment.