Skip to content

Commit

Permalink
feat: Card component (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliajforesti committed Nov 8, 2023
1 parent 68674c5 commit e546f5b
Show file tree
Hide file tree
Showing 11 changed files with 357 additions and 0 deletions.
157 changes: 157 additions & 0 deletions packages/fuselage/src/components/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { Button } from '@rocket.chat/fuselage';
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import React from 'react';

import { Card, CardBody, CardCol, CardTitle } from '.';
import { Avatar } from '../Avatar';
import { Badge } from '../Badge';
import Box from '../Box/Box';
import { MenuItem, MenuV2 } from '../Menu';
import { Tag } from '../Tag';
import CardContent from './CardContent';
import CardControls from './CardControls';
import CardFramedIcon from './CardFramedIcon';
import CardHeader from './CardHeader';
import CardHorizontal from './CardHorizontal';

export default {
title: 'Components/Card',
component: Card,
subcomponents: {
CardHorizontal,
CardHeader,
CardTitle,
CardCol,
CardContent,
CardBody,
CardControls,
// CardDivider,
// CardColSection,
// CardColTitle,
// CardFooter,
},
parameters: {
backgrounds: { default: 'dark' },
layout: 'centered',
controls: { hideNoControlsWarning: true },
},
} as ComponentMeta<typeof Card>;

export const Horizontal: ComponentStory<typeof Card> = () => (
<CardHorizontal aria-describedby='lalala'>
<CardContent>
<CardFramedIcon icon='document-eye' />
<CardCol>
<CardTitle variant='h3' info='Card info here'>
Heading 3
</CardTitle>
<CardBody>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium
voluptatem rem praesentium earum ut consectetur.
</CardBody>
</CardCol>
</CardContent>
<CardControls>
<Button>Button</Button>
<Button primary>Button</Button>
<Badge small variant='primary' />
<Tag>Tag</Tag>
<MenuV2 placement='bottom-end'>
<MenuItem key='1'>Profile</MenuItem>
<MenuItem key='2'>Chats</MenuItem>
<MenuItem key='3'>Settings</MenuItem>
</MenuV2>
<span hidden />
</CardControls>
</CardHorizontal>
);
export const HorizontalNoIcon: ComponentStory<typeof Card> = () => (
<CardHorizontal aria-describedby='lalala'>
<CardContent column>
<CardTitle variant='h3' info='Card info here'>
Heading 3
</CardTitle>
<CardBody>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium
voluptatem rem praesentium earum ut consectetur.
</CardBody>
</CardContent>
<CardControls>
<Button>Button</Button>
<Button primary>Button</Button>
<Badge small variant='primary' />
<Tag>Tag</Tag>
<MenuV2 placement='bottom-end'>
<MenuItem key='1'>Profile</MenuItem>
<MenuItem key='2'>Chats</MenuItem>
<MenuItem key='3'>Settings</MenuItem>
</MenuV2>
<span hidden />
</CardControls>
</CardHorizontal>
);

export const HorizontalNoAction: ComponentStory<typeof Card> = () => (
<CardHorizontal>
<CardFramedIcon icon='document-eye' />
<CardCol>
<CardTitle variant='h3'>Heading 3</CardTitle>
<CardBody>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium
voluptatem rem praesentium earum ut consectetur.
</CardBody>
</CardCol>
</CardHorizontal>
);

export const TitleH4: ComponentStory<typeof Card> = () => (
<CardHorizontal>
<CardCol>
<CardTitle variant='h4'>Heading 4</CardTitle>
<CardBody>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium
voluptatem rem praesentium earum ut consectetur.
</CardBody>
</CardCol>
</CardHorizontal>
);
TitleH4.storyName = 'Title h4';

export const TitleH5: ComponentStory<typeof Card> = () => (
<CardHorizontal>
<CardCol>
<CardTitle variant='h5'>Heading 5</CardTitle>
<CardBody>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium
voluptatem rem praesentium earum ut consectetur.
</CardBody>
</CardCol>
</CardHorizontal>
);
TitleH5.storyName = 'Title h5';

const imgUrl =
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAoACgDASIAAhEBAxEB/8QAGwAAAgIDAQAAAAAAAAAAAAAAAAcEBgIDBQj/xAAuEAACAQQAAwcEAQUAAAAAAAABAgMABAUREiExBhMUIkFRYQcWcYGhFTJSgpH/xAAYAQADAQEAAAAAAAAAAAAAAAACAwQBAP/EAB4RAAIBBQEBAQAAAAAAAAAAAAABAgMREiExE0HR/9oADAMBAAIRAxEAPwBuXuIkhBuMe5ib/AHQP49q4L3mLitryTLTSpOiHQI5k/HzXa/qbFOEudVTu1dumWvcTaNCZYZ7vU6g6LxqjOU/24dfs1Ouh9FnkMpd3Reeyx83hAxZZEhkdV9/MBrX71WGPvJcqrJBGveKATtuXXqNU0pu02bTHXD/AGvJAluyxxRd6F4x00o+NdKoVrjbzJdvVe1t5cVLc2ck8qjnohgpPtz2v7G6JtPQ2VJwjlcw+37mchpnK6GtIuv5NFWeTsLNPvxWTvpfjvOEfwKKzEVkSct2vscS/BIzSN0YRkeX81UpPqO8masJETu7OOccY4dswYFQeftv096XV5knuJGdm2T1+agvMXj8jEaHX905QihabvcbuS7X566mLWLwSY8PuRnk/u4eZ0deTl71Ef6hY+0yM88TzeNZY4luYwpVYyduOfrvhPTnr0pXSX9y5mCsyJMdyxxvwq599em+taItqCSNc90ChvZRUruUcT0JiO18Elpk7t8v41LWzacxkBSuvjQ/FFJayjDWrCTepAQ2vUH0oo/Jk3ovpwJJeVCP5CN+lFFaaMqy+nAyuChvrTI2kN9JAsi2ZOy4IBHMnkSCP+iqBexSWdxLazoUljJVlPUH2oorkV10pRc7b1zXb/hZOzuJvM86QWEXeELxOzHSIPcmiiiunVlF2RNTpRkrs//Z';
export const HorizontalWithCustomHeaderAndContent: ComponentStory<
typeof Card
> = () => (
<CardHorizontal>
<CardContent>
<CardCol>
<CardHeader>
<CardTitle variant='h4'>Heading 3</CardTitle>
<Tag variant='featured'>Header tag</Tag>
</CardHeader>
<CardBody>
<Box mie={4}>
<Avatar url={imgUrl} />
</Box>
Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium rem
praesentium earum ut consectetur. Lorem ipsum dolor sit amet. In
adipisci consequatur qui laudantium rem praesentium earum ut
consectetur.
</CardBody>
</CardCol>
</CardContent>
</CardHorizontal>
);
15 changes: 15 additions & 0 deletions packages/fuselage/src/components/Card/Card.styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@use '../../styles/lengths.scss';

.rcx-card__content,
.rcx-card__controls,
.rcx-card__horizontal {
& > * {
margin-inline: lengths.margin(4);
}
}

.rcx-card__horizontal {
& > * {
margin-block: lengths.margin(4);
}
}
27 changes: 27 additions & 0 deletions packages/fuselage/src/components/Card/CardBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Box } from '@rocket.chat/fuselage';
import type { FC, CSSProperties, ComponentProps } from 'react';
import React from 'react';

type CardBodyProps = {
flexDirection?: CSSProperties['flexDirection'];
height?: ComponentProps<typeof Box>['height'];
};

const CardBody: FC<CardBodyProps> = ({
children,
flexDirection = 'row',
height,
}) => (
<Box
fontScale='c1'
display='flex'
flexDirection={flexDirection}
flexGrow={1}
height={height}
rcx-card__body
>
{children}
</Box>
);

export default CardBody;
17 changes: 17 additions & 0 deletions packages/fuselage/src/components/Card/CardCol.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Box } from '@rocket.chat/fuselage';
import type { FC } from 'react';
import React from 'react';

const CardCol: FC = ({ children }) => (
<Box
rcx-card__col
display='flex'
// flexGrow={1}
flexDirection='column'
fontScale='c1'
>
{children}
</Box>
);

export default CardCol;
29 changes: 29 additions & 0 deletions packages/fuselage/src/components/Card/CardContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { ReactNode } from 'react';
import React from 'react';

import Box from '../Box/Box';

const CardContent = ({
children,
// flexDirection,
column = undefined,
...props
}: {
children: ReactNode;
// flexDirection?: CSSProperties['flexDirection'];
column?: true | undefined;
}) => (
<Box
rcx-card__content
display='flex'
alignItems={column ? 'flex-start' : 'center'}
// flexGrow={1}
flexDirection={column ? 'column' : 'row'}
fontScale='c1'
{...props}
>
{children}
</Box>
);

export default CardContent;
15 changes: 15 additions & 0 deletions packages/fuselage/src/components/Card/CardControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

import Box from '../Box/Box';

const CardControls = ({ ...props }) => (
<Box
display='flex'
flexGrow={1}
alignItems='center'
rcx-card__action-area
{...props}
/>
);

export default CardControls;
14 changes: 14 additions & 0 deletions packages/fuselage/src/components/Card/CardFramedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { ComponentProps } from 'react';
import React from 'react';

import { IconButton } from '../Button';

const CardFramedIcon = ({
icon,
...props
}: ComponentProps<typeof IconButton>) => (
<IconButton secondary small icon={icon} {...props} />
// <Icon name={name} size='x24' {...props} />
);

export default CardFramedIcon;
11 changes: 11 additions & 0 deletions packages/fuselage/src/components/Card/CardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Box } from '@rocket.chat/fuselage';
import type { ReactNode } from 'react';
import React from 'react';

const CardHeader = ({ children }: { children: ReactNode }) => (
<Box color='default' display='flex' alignItems='center' rcx-card__header>
{children}
</Box>
);

export default CardHeader;
33 changes: 33 additions & 0 deletions packages/fuselage/src/components/Card/CardHorizontal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Box } from '@rocket.chat/fuselage';
import { useBreakpoints } from '@rocket.chat/fuselage-hooks';
import type { AllHTMLAttributes, FC } from 'react';
import React from 'react';

import './Card.styles.scss';

const CardHorizontal: FC<Omit<AllHTMLAttributes<HTMLElement>, 'is'>> = ({
...props
}) => {
const breakpoints = useBreakpoints();
const isMobile = !breakpoints.includes('sm');

return (
<Box
borderRadius='x8'
pb={4}
pi={12}
display='flex'
flexDirection={'row'}
justifyContent='center'
alignItems='center'
flexWrap={isMobile ? 'wrap' : 'nowrap'}
bg='light'
color='default'
rcx-card
rcx-card__horizontal
{...props}
/>
);
};

export default CardHorizontal;
31 changes: 31 additions & 0 deletions packages/fuselage/src/components/Card/CardTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Box } from '@rocket.chat/fuselage';
import type { ReactNode } from 'react';
import React from 'react';

import { LabelInfo } from '../Label/LabelInfo';

const CardTitle = ({
children,
info,
variant = 'h4',
}: {
children: ReactNode;
info?: string;
variant?: 'h3' | 'h4' | 'h5';
}) => (
<Box
fontScale={variant}
is={variant}
color='default'
mie={4}
display='flex'
flexDirection='row'
alignItems='center'
rcx-card__title
>
{children}
{info && <LabelInfo title={info} />}
</Box>
);

export default CardTitle;
8 changes: 8 additions & 0 deletions packages/fuselage/src/components/Card/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { default as Card } from './Card';
export { default as CardBody } from './CardBody';
export { default as CardCol } from './CardCol';
export { default as CardTitle } from './CardTitle';
export { default as CardControls } from './CardControls';
export { default as CardContent } from './CardContent';
export { default as CardHorizontal } from './CardHorizontal';
export { default as CardHeader } from './CardHeader';

0 comments on commit e546f5b

Please sign in to comment.