-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: APP-3056 - Implement Collapsible and CardCollapsible core compo…
…nents (#165)
- Loading branch information
1 parent
c412e92
commit a704fd2
Showing
12 changed files
with
568 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
76 changes: 76 additions & 0 deletions
76
src/core/components/cards/cardCollapsible/cardCollapsible.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { CardCollapsible } from './cardCollapsible'; | ||
|
||
/** | ||
* CardCollapsible component that can wrap any content and visually collapse it for space-saving purposes. | ||
*/ | ||
const meta: Meta<typeof CardCollapsible> = { | ||
title: 'Core/Components/Cards/CardCollapsible', | ||
component: CardCollapsible, | ||
tags: ['autodocs'], | ||
parameters: { | ||
design: { | ||
type: 'figma', | ||
url: 'https://www.figma.com/file/jfKRr1V9evJUp1uBeyP3Zz/v1.0.0?node-id=10157-27011&t=RVJHJFTrLMnhgYnJ-4', | ||
}, | ||
}, | ||
}; | ||
|
||
type Story = StoryObj<typeof CardCollapsible>; | ||
|
||
/** | ||
* Default usage example of the CardCollapsible component. | ||
*/ | ||
export const Default: Story = { | ||
args: { buttonLabelClosed: 'Read more', buttonLabelOpened: 'Read less' }, | ||
render: (args) => ( | ||
<CardCollapsible {...args}> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, | ||
consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec | ||
sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt | ||
scelerisque. | ||
</p> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
</p> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, | ||
consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec | ||
sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt | ||
scelerisque.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur | ||
tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam | ||
nec sapien nec turpis tincidunt scelerisque. | ||
</p> | ||
</CardCollapsible> | ||
), | ||
}; | ||
|
||
/** | ||
* CardCollapsible component with an image as the content. | ||
*/ | ||
export const WithImage: Story = { | ||
args: { | ||
buttonLabelClosed: 'See more', | ||
buttonLabelOpened: 'See less', | ||
}, | ||
render: (args) => ( | ||
<CardCollapsible {...args}> | ||
<img src="https://source.unsplash.com/800x600/?landscape" alt="A beautiful landscape" /> | ||
</CardCollapsible> | ||
), | ||
}; | ||
|
||
export default meta; |
33 changes: 33 additions & 0 deletions
33
src/core/components/cards/cardCollapsible/cardCollapsible.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { render, screen } from '@testing-library/react'; | ||
import { CardCollapsible, type ICardCollapsibleProps } from './cardCollapsible'; | ||
|
||
global.ResizeObserver = class { | ||
observe() {} | ||
unobserve() {} | ||
disconnect() {} | ||
}; | ||
|
||
describe('<CardCollapsible /> component', () => { | ||
const createTestComponent = (props?: Partial<ICardCollapsibleProps>) => { | ||
const completeProps = { ...props }; | ||
|
||
return <CardCollapsible {...completeProps} />; | ||
}; | ||
|
||
it('renders without crashing', () => { | ||
const children = 'Content of the card'; | ||
render(createTestComponent({ children })); | ||
expect(screen.getByText('Content of the card')).toBeInTheDocument(); | ||
}); | ||
|
||
it('forwards props to the Collapsible component', () => { | ||
const defaultOpen = true; | ||
const buttonLabelOpened = 'Close'; | ||
const buttonLabelClosed = 'Open'; | ||
jest.spyOn(HTMLElement.prototype, 'scrollHeight', 'get').mockReturnValue(500); | ||
|
||
render(createTestComponent({ buttonLabelOpened, defaultOpen })); | ||
expect(screen.queryByText(buttonLabelClosed)).not.toBeInTheDocument(); | ||
expect(screen.getByText(buttonLabelOpened)).toBeInTheDocument(); | ||
}); | ||
}); |
22 changes: 22 additions & 0 deletions
22
src/core/components/cards/cardCollapsible/cardCollapsible.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import classNames from 'classnames'; | ||
import { Collapsible, type ICollapsibleProps } from '../../collapsible'; | ||
import { Card } from '../card'; | ||
|
||
export interface ICardCollapsibleProps extends Omit<ICollapsibleProps, 'buttonVariant' | 'className'> { | ||
/** | ||
* Additional class names to apply to the card. | ||
*/ | ||
className?: string; | ||
} | ||
|
||
export const CardCollapsible: React.FC<ICardCollapsibleProps> = (props) => { | ||
const { children, className, ...otherProps } = props; | ||
|
||
return ( | ||
<Card className={classNames('p-4 md:p-6', className)}> | ||
<Collapsible showOverlay={true} {...otherProps}> | ||
{children} | ||
</Collapsible> | ||
</Card> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { CardCollapsible, type ICardCollapsibleProps } from './cardCollapsible'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './card'; | ||
export * from './cardCollapsible'; | ||
export * from './cardEmptyState'; | ||
export * from './cardSummary'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { type ComponentProps } from 'react'; | ||
|
||
export type CollapsedSize = 'sm' | 'md' | 'lg'; | ||
|
||
export interface ICollapsibleProps extends ComponentProps<'div'> { | ||
/** | ||
* The initial height of the collapsible container while closed. @default md | ||
*/ | ||
collapsedSize?: CollapsedSize; | ||
/** | ||
* Custom pixel height for the collapsible container that will override collapsedSize prop if defined. | ||
*/ | ||
customCollapsedHeight?: number; | ||
/** | ||
* Controlled state of the collapsible container. @default false | ||
*/ | ||
isOpen?: boolean; | ||
/** | ||
* Default state of the collapsible container. @default false | ||
*/ | ||
defaultOpen?: boolean; | ||
/** | ||
* The label to display on the trigger button when the collapsible container is closed. | ||
*/ | ||
buttonLabelClosed?: string; | ||
/** | ||
* The label to display on the trigger button when the collapsible container is open. | ||
*/ | ||
buttonLabelOpened?: string; | ||
/** | ||
* Show overlay when the collapsible container is open. @default false | ||
*/ | ||
showOverlay?: boolean; | ||
/** | ||
* Callback function that is called when the collapsible container is toggled. | ||
*/ | ||
onToggle?: (isOpen: boolean) => void; | ||
} |
142 changes: 142 additions & 0 deletions
142
src/core/components/collapsible/collapsible.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import { useState } from 'react'; | ||
import { Collapsible } from './collapsible'; | ||
|
||
/** | ||
* Collapsible component that can wrap any content and visually collapse it for space-saving purposes. | ||
*/ | ||
const meta: Meta<typeof Collapsible> = { | ||
title: 'Core/Components/Collapsible', | ||
component: Collapsible, | ||
tags: ['autodocs'], | ||
parameters: { | ||
design: { | ||
type: 'figma', | ||
url: 'https://www.figma.com/file/jfKRr1V9evJUp1uBeyP3Zz/v1.0.0?node-id=10157-27011&t=RVJHJFTrLMnhgYnJ-4', | ||
}, | ||
}, | ||
}; | ||
|
||
type Story = StoryObj<typeof Collapsible>; | ||
|
||
/** | ||
* Default usage example of the Collapsible component. | ||
*/ | ||
export const Default: Story = { | ||
args: { buttonLabelClosed: 'Read more', buttonLabelOpened: 'Read less' }, | ||
render: (args) => ( | ||
<Collapsible {...args}> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, | ||
consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec | ||
sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt | ||
scelerisque. | ||
</p> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
</p> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien | ||
nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla | ||
nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, | ||
consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec | ||
sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt | ||
scelerisque.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur | ||
tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. Nullam | ||
nec sapien nec turpis tincidunt scelerisque. | ||
</p> | ||
</Collapsible> | ||
), | ||
}; | ||
|
||
/** | ||
* Collapsible component with a short text as the content to show overflow detection. | ||
*/ | ||
export const ShortContent: Story = { | ||
args: { buttonLabelClosed: 'Read more', buttonLabelOpened: 'Read less' }, | ||
render: (args) => ( | ||
<Collapsible {...args}> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. | ||
Nulla facilisi. | ||
</p> | ||
</Collapsible> | ||
), | ||
}; | ||
|
||
/** | ||
* Collapsible component with an image as the content with defaultOpen true. | ||
*/ | ||
export const WithImage: Story = { | ||
args: { | ||
buttonLabelClosed: 'See more', | ||
buttonLabelOpened: 'See less', | ||
defaultOpen: true, | ||
}, | ||
render: (args) => ( | ||
<Collapsible {...args}> | ||
<img | ||
src="https://source.unsplash.com/800x600/?landscape" | ||
alt="A beautiful landscape" | ||
className="h-auto w-full" | ||
/> | ||
</Collapsible> | ||
), | ||
}; | ||
|
||
/** | ||
* Controlled usage example of the Collapsible component. | ||
*/ | ||
export const Controlled: Story = { | ||
args: { | ||
buttonLabelOpened: 'Collapse content', | ||
buttonLabelClosed: 'Expand content', | ||
collapsedSize: 'sm', | ||
}, | ||
render: (args) => { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
const handleToggle = (toggle: boolean) => { | ||
setIsOpen(toggle); | ||
}; | ||
|
||
return ( | ||
<Collapsible {...args} isOpen={isOpen} onToggle={handleToggle}> | ||
<p> | ||
This is some example content within the Collapsible component. When expanded, the content will be | ||
fully visible. | ||
</p> | ||
<br /> | ||
<p> | ||
Controlled usage ensures that the parent controls the open and closed states and updates the | ||
component accordingly. | ||
</p> | ||
<br /> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc consectetur | ||
tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla facilisi. | ||
Nullam nec sapien nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, consectetur | ||
adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec | ||
turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt | ||
scelerisque.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nulla nec nunc | ||
consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. Nulla | ||
facilisi. Nullam nec sapien nec turpis tincidunt scelerisque.Lorem ipsum dolor sit amet, consectetur | ||
adipiscing elit. Sed ac nulla nec nunc consectetur tincidunt. Nulla facilisi. Nullam nec sapien nec | ||
turpis tincidunt scelerisque. Nulla facilisi. Nullam nec sapien nec turpis tincidunt scelerisque. | ||
</p> | ||
</Collapsible> | ||
); | ||
}, | ||
}; | ||
|
||
export default meta; |
Oops, something went wrong.