Skip to content

Commit

Permalink
✨ Card Component
Browse files Browse the repository at this point in the history
  • Loading branch information
dohye1 committed Mar 21, 2023
1 parent 01095de commit 30e0fd8
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Card from './Card';
import { Story, Meta } from '@storybook/react';
import { CardProps } from './Card.types';
import { Heading } from '../@foundations/Typography';
import { Paragraph } from '../@foundations/Typography';

export default {
title: 'Components/Card/DefaultCard',
component: Card,
parameters: {
layout: 'centered',
viewport: 'responsive',
},
} as Meta;

const Template: Story<CardProps> = ({ ...args }) => {
return (
<Card {...args} flexDirection="column" padding={20} display="flex">
<Heading size={200}>Heading</Heading>
<Paragraph size={300}>Paragraph</Paragraph>
</Card>
);
};

export const Default = Template.bind({});
Default.args = {};

export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
};
74 changes: 74 additions & 0 deletions src/Card/Card.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import styled, { css } from 'styled-components';
import { Box } from '../Layout';

const CommonStyle = css`
${({ theme }) => css`
border: 1px solid ${theme.colors.N400};
background-color: ${theme.colors.N0};
border-radius: 8px;
width: fit-content;
height: fit-content;
box-sizing: border-box;
`}
`;

export const DefaultCard = styled(Box)<{ disabled?: boolean }>`
${({ theme, disabled }) => css`
${CommonStyle}
&:hover {
box-shadow: 0px 4px 8px rgba(16, 24, 64, 0.08);
}
&:focus,
&:active {
border: 1px solid ${theme.colors.B400};
background-color: ${theme.colors.N50};
}
${disabled &&
css`
&,
&:hover,
&:focus,
&:active {
box-shadow: none;
border-color: transparent;
background-color: ${theme.colors.N50};
}
`}
`}
`;

export const SelectableCard = styled(Box)<{
disabled?: boolean;
selected?: boolean;
}>`
${({ theme, disabled, selected }) => css`
${CommonStyle}
cursor: pointer;
&:hover {
box-shadow: 0px 4px 8px rgba(16, 24, 64, 0.08);
}
&:focus,
&:active {
${theme.commonStyles.outline};
box-shadow: 0px 4px 8px rgba(16, 24, 64, 0.08);
}
${disabled &&
css`
&,
&:hover,
&:focus,
&:active {
cursor: default;
box-shadow: none;
outline: none;
border-color: transparent;
background-color: ${theme.colors.N75};
}
`}
${selected &&
css`
border-color: ${theme.colors.B400};
background-color: ${theme.colors.N50};
`}
`}
`;
11 changes: 11 additions & 0 deletions src/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Styled from './Card.styled';
import { CardProps } from './Card.types';

const Card = ({ type = 'default', children, ...props }: CardProps) => {
const CardComponent =
type === 'default' ? Styled.DefaultCard : Styled.SelectableCard;

return <CardComponent {...props}>{children}</CardComponent>;
};

export default Card;
16 changes: 16 additions & 0 deletions src/Card/Card.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BoxProps } from '../Layout/Box.types';

type CommonCardProps = BoxProps & {
disabled?: boolean;
};

export type DefaultCardProps = CommonCardProps & {
type?: 'default';
};

export type SelectableCardProps = CommonCardProps & {
type: 'selectable';
selected?: boolean;
};

export type CardProps = DefaultCardProps | SelectableCardProps;
40 changes: 40 additions & 0 deletions src/Card/SelectableCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Card from './Card';
import { Story, Meta } from '@storybook/react';
import { CardProps } from './Card.types';
import { useState } from 'react';
import { Heading, Paragraph } from '../@foundations/Typography';

export default {
title: 'Components/Card/SelectableCard',
component: Card,
parameters: {
layout: 'centered',
viewport: 'responsive',
},
} as Meta;

const Template: Story<CardProps> = ({ ...args }) => {
const [selected, setSelected] = useState(false);
return (
<Card
flexDirection="column"
padding={20}
display="flex"
type="selectable"
selected={selected}
onClick={() => setSelected((prev) => !prev)}
{...args}
>
<Heading size={200}>Heading</Heading>
<Paragraph size={300}>Paragraph</Paragraph>
</Card>
);
};

export const Default = Template.bind({});
Default.args = {};

export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
};
1 change: 1 addition & 0 deletions src/Card/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Card } from './Card';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export * from './Alerts';
export * from './Avatar';
export * from './Badge';
export * from './Button';
export * from './Card';
export * from './Checkbox';
export * from './CornerDialog';
export * from './Dialog';
Expand Down

0 comments on commit 30e0fd8

Please sign in to comment.