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(Accordion): create Accordion and BoxedAccordion components #900

Merged
merged 13 commits into from
Oct 11, 2023
148 changes: 148 additions & 0 deletions playroom/snippets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,153 @@ const menuSnippet = {
group: 'Menu',
};

const accordionSnippets: Array<Snippet> = [
{
group: 'Accordion',
name: 'Accordion',
code: `
<Accordion>
<AccordionItem
asset={<IconInvoicePlanFileRegular />}
title="What is Movistar Money"
content={
<Text3 color={colors.textSecondary}>
It's a loan available to anyone, whether or not you're a Movistar
customer. It offers from €2,000 to €15,000 with a simple and fast
application process, and you receive the money in less than 48 hours.
</Text3>
}
/>
<AccordionItem
asset={<IconLocationMapRegular />}
title="To whom is it aimed?"
content={
<Text3 color={colors.textSecondary}>
The Movistar Money loan service is aimed at anyone, whether you are a{" "}
<TextLink href>Movistar</TextLink> customer or not.
</Text3>
}
/>
<AccordionItem
asset={<IconLockEyeClosedRegular />}
title="Who offers Movistar Money?"
content={
<Text3 color={colors.textSecondary}>
<p>
At Telefónica, we have our own financial institution, Telefonica
Consumer Finance, and agreements with other institutions to assist
you in obtaining your loan.
</p>
<br />
<Image src="https://picsum.photos/1200/1200" aspectRatio="16:9" />
<br />
<p>
Depending on the characteristics of the information you provide us,
your application will be sent to one of the institutions{" "}
<TextLink href>with which Movistar has agreements</TextLink>.
</p>
</Text3>
}
/>
<AccordionItem
asset={<IconIdCardRegular />}
title="How can I hire it?"
content={
<Text3 color={colors.textSecondary}>
It's a very agile process that you can access through the
money.movistar.es website. You can find more detailed information
about the process on our "How It Works" page.
</Text3>
}
/>
<AccordionItem
asset={<IconLifeguardFloatRegular />}
title="What should I do if I don't receive the SMS with the contracting code?"
content={
<Text3 color={colors.textSecondary}>
It may take a few minutes until you receive the SMS with the code. If
you still haven't received the code, you can request a new one by
clicking on "resend SMS."
</Text3>
}
/>
</Accordion>
`,
},
{
group: 'Accordion',
name: 'BoxedAccordion',
code: `
<BoxedAccordion>
<BoxedAccordionItem
asset={<IconInvoicePlanFileRegular />}
title="What is Movistar Money"
content={
<Text3 color={colors.textSecondary}>
It's a loan available to anyone, whether or not you're a Movistar
customer. It offers from €2,000 to €15,000 with a simple and fast
application process, and you receive the money in less than 48 hours.
</Text3>
}
/>
<BoxedAccordionItem
asset={<IconLocationMapRegular />}
title="To whom is it aimed?"
content={
<Text3 color={colors.textSecondary}>
The Movistar Money loan service is aimed at anyone, whether you are a{" "}
<TextLink href>Movistar</TextLink> customer or not.
</Text3>
}
/>
<BoxedAccordionItem
asset={<IconLockEyeClosedRegular />}
title="Who offers Movistar Money?"
content={
<Text3 color={colors.textSecondary}>
<p>
At Telefónica, we have our own financial institution, Telefonica
Consumer Finance, and agreements with other institutions to assist
you in obtaining your loan.
</p>
<br />
<Image src="https://picsum.photos/1200/1200" aspectRatio="16:9" />
<br />
<p>
Depending on the characteristics of the information you provide us,
your application will be sent to one of the institutions{" "}
<TextLink href>with which Movistar has agreements</TextLink>.
</p>
</Text3>
}
/>
<BoxedAccordionItem
asset={<IconIdCardRegular />}
title="How can I hire it?"
content={
<Text3 color={colors.textSecondary}>
It's a very agile process that you can access through the
money.movistar.es website. You can find more detailed information
about the process on our "How It Works" page.
</Text3>
}
/>
<BoxedAccordionItem
asset={<IconLifeguardFloatRegular />}
title="What should I do if I don't receive the SMS with the contracting code?"
content={
<Text3 color={colors.textSecondary}>
It may take a few minutes until you receive the SMS with the code. If
you still haven't received the code, you can request a new one by
clicking on "resend SMS."
</Text3>
}
/>
</BoxedAccordion>
`,
},
];

const buttonSnippets: Array<Snippet> = [
{name: 'ButtonPrimary', code: '<ButtonPrimary onPress={() => {}}>Action</ButtonPrimary>'},
{name: 'ButtonSecondary', code: '<ButtonSecondary onPress={() => {}}>Action</ButtonSecondary>'},
Expand Down Expand Up @@ -2458,6 +2605,7 @@ export default [
{group: 'Badge', name: 'Icon with badge', code: '<Badge value="5"><IconSettingsRegular /></Badge>'},
{group: 'Text', name: 'Text', code: '<Text>some text</Text>'},
...headerSnippets,
...accordionSnippets,
...listSnippets,
...listSnippetsAvatar,
...listRowSnippets,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
marcoskolodny marked this conversation as resolved.
Show resolved Hide resolved
marcoskolodny marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions src/__screenshot_tests__/accordion-screenshot-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {openStoryPage, screen} from '../test-utils';

test.each`
component | inverse | singleOpen
${'Accordion'} | ${false} | ${false}
${'Accordion'} | ${false} | ${true}
${'Accordion'} | ${true} | ${false}
${'Accordion'} | ${true} | ${true}
${'Boxed accordion'} | ${false} | ${false}
${'Boxed accordion'} | ${false} | ${true}
${'Boxed accordion'} | ${true} | ${false}
${'Boxed accordion'} | ${true} | ${true}
`('$component. inverse($inverse) singleOpen($singleOpen)', async ({component, inverse, singleOpen}) => {
await openStoryPage({
id: `components-accordions--${component.toLowerCase().replace(' ', '-')}-story`,
device: 'MOBILE_IOS',
args: {
inverse,
singleOpen,
},
});

const accordion = await screen.findByTestId('accordion');

expect(await accordion.screenshot()).toMatchImageSnapshot();

await (await screen.findByTestId('accordion-item-1')).click();
await (await screen.findByTestId('accordion-item-1')).click();
await (await screen.findByTestId('accordion-item-2')).click();
await (await screen.findByTestId('accordion-item-4')).click();
await (await screen.findByTestId('accordion-item-6')).click();

expect(await accordion.screenshot()).toMatchImageSnapshot();
});
140 changes: 140 additions & 0 deletions src/__stories__/accordion-story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import * as React from 'react';
import {
Accordion,
AccordionItem,
Avatar,
Box,
BoxedAccordion,
BoxedAccordionItem,
Circle,
IconLikeFilled,
IconMobileDeviceRegular,
Image,
Placeholder,
ResponsiveLayout,
skinVars,
} from '..';
import usingVrImg from './images/using-vr.jpg';
import laptopImg from './images/laptop.jpg';
import avatarImg from './images/avatar.jpg';
import touchImg from './images/touch.jpg';
import personPortraitImg from './images/person-portrait.jpg';

export default {
title: 'Components/Accordions',
parameters: {fullScreen: true},
};

type Args = {title: string; subtitle: string; singleOpen: boolean; inverse: boolean};

const Template: StoryComponent<Args & {type?: 'boxed'}> = ({title, subtitle, singleOpen, inverse, type}) => {
const content = <Placeholder height={100} />;

const AccordionComponent = type === 'boxed' ? BoxedAccordion : Accordion;
const ItemComponent = type === 'boxed' ? BoxedAccordionItem : AccordionItem;

return (
<ResponsiveLayout fullWidth isInverse={inverse}>
<Box padding={16}>
<AccordionComponent singleOpen={singleOpen} dataAttributes={{testid: 'accordion'}}>
<ItemComponent
title={title}
subtitle={subtitle}
content={content}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-1'}}
/>
<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<IconLikeFilled size={24} />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-2'}}
/>
<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={
<Circle backgroundColor={skinVars.colors.brandLow} size={40}>
<IconMobileDeviceRegular color={skinVars.colors.brand} />
</Circle>
}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-3'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Circle size={40} backgroundImage={laptopImg} />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-4'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Image src={usingVrImg} height={80} aspectRatio="16:9" />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-5'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Image src={personPortraitImg} width={80} aspectRatio="7:10" />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-6'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Image src={touchImg} width={80} />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-7'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Avatar size={40} src={avatarImg} />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-8'}}
/>

<ItemComponent
title={title}
subtitle={subtitle}
content={content}
asset={<Avatar size={40} initials="MS" />}
{...(type === 'boxed' && {isInverse: inverse})}
dataAttributes={{testid: 'accordion-item-9'}}
/>
</AccordionComponent>
</Box>
</ResponsiveLayout>
);
};

const defaultArgs = {
title: 'Title',
subtitle: 'Subtitle',
singleOpen: false,
inverse: false,
};

export const AccordionStory: StoryComponent<Args> = (args) => <Template {...args} />;
AccordionStory.storyName = 'Accordion';
AccordionStory.args = defaultArgs;

export const BoxedAccordionStory: StoryComponent<Args> = (args) => <Template type="boxed" {...args} />;
BoxedAccordionStory.storyName = 'BoxedAccordion';
BoxedAccordionStory.args = defaultArgs;
Loading