From e546f5b3e9d727829ebeafb918d1d0cf90e81c59 Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Wed, 8 Nov 2023 16:30:43 -0300 Subject: [PATCH] feat: `Card` component (wip) --- .../src/components/Card/Card.stories.tsx | 157 ++++++++++++++++++ .../src/components/Card/Card.styles.scss | 15 ++ .../fuselage/src/components/Card/CardBody.tsx | 27 +++ .../fuselage/src/components/Card/CardCol.tsx | 17 ++ .../src/components/Card/CardContent.tsx | 29 ++++ .../src/components/Card/CardControls.tsx | 15 ++ .../src/components/Card/CardFramedIcon.tsx | 14 ++ .../src/components/Card/CardHeader.tsx | 11 ++ .../src/components/Card/CardHorizontal.tsx | 33 ++++ .../src/components/Card/CardTitle.tsx | 31 ++++ .../fuselage/src/components/Card/index.ts | 8 + 11 files changed, 357 insertions(+) create mode 100644 packages/fuselage/src/components/Card/Card.stories.tsx create mode 100644 packages/fuselage/src/components/Card/Card.styles.scss create mode 100644 packages/fuselage/src/components/Card/CardBody.tsx create mode 100644 packages/fuselage/src/components/Card/CardCol.tsx create mode 100644 packages/fuselage/src/components/Card/CardContent.tsx create mode 100644 packages/fuselage/src/components/Card/CardControls.tsx create mode 100644 packages/fuselage/src/components/Card/CardFramedIcon.tsx create mode 100644 packages/fuselage/src/components/Card/CardHeader.tsx create mode 100644 packages/fuselage/src/components/Card/CardHorizontal.tsx create mode 100644 packages/fuselage/src/components/Card/CardTitle.tsx create mode 100644 packages/fuselage/src/components/Card/index.ts diff --git a/packages/fuselage/src/components/Card/Card.stories.tsx b/packages/fuselage/src/components/Card/Card.stories.tsx new file mode 100644 index 0000000000..cefa274702 --- /dev/null +++ b/packages/fuselage/src/components/Card/Card.stories.tsx @@ -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; + +export const Horizontal: ComponentStory = () => ( + + + + + + Heading 3 + + + Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium + voluptatem rem praesentium earum ut consectetur. + + + + + + + + Tag + + Profile + Chats + Settings + + + +); +export const HorizontalNoIcon: ComponentStory = () => ( + + + + Heading 3 + + + Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium + voluptatem rem praesentium earum ut consectetur. + + + + + + + Tag + + Profile + Chats + Settings + + + +); + +export const HorizontalNoAction: ComponentStory = () => ( + + + + Heading 3 + + Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium + voluptatem rem praesentium earum ut consectetur. + + + +); + +export const TitleH4: ComponentStory = () => ( + + + Heading 4 + + Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium + voluptatem rem praesentium earum ut consectetur. + + + +); +TitleH4.storyName = 'Title h4'; + +export const TitleH5: ComponentStory = () => ( + + + Heading 5 + + Lorem ipsum dolor sit amet. In adipisci consequatur qui laudantium + voluptatem rem praesentium earum ut consectetur. + + + +); +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 +> = () => ( + + + + + Heading 3 + Header tag + + + + + + 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. + + + + +); diff --git a/packages/fuselage/src/components/Card/Card.styles.scss b/packages/fuselage/src/components/Card/Card.styles.scss new file mode 100644 index 0000000000..26f8789761 --- /dev/null +++ b/packages/fuselage/src/components/Card/Card.styles.scss @@ -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); + } +} diff --git a/packages/fuselage/src/components/Card/CardBody.tsx b/packages/fuselage/src/components/Card/CardBody.tsx new file mode 100644 index 0000000000..72d749be96 --- /dev/null +++ b/packages/fuselage/src/components/Card/CardBody.tsx @@ -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['height']; +}; + +const CardBody: FC = ({ + children, + flexDirection = 'row', + height, +}) => ( + + {children} + +); + +export default CardBody; diff --git a/packages/fuselage/src/components/Card/CardCol.tsx b/packages/fuselage/src/components/Card/CardCol.tsx new file mode 100644 index 0000000000..8b74fc1309 --- /dev/null +++ b/packages/fuselage/src/components/Card/CardCol.tsx @@ -0,0 +1,17 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { FC } from 'react'; +import React from 'react'; + +const CardCol: FC = ({ children }) => ( + + {children} + +); + +export default CardCol; diff --git a/packages/fuselage/src/components/Card/CardContent.tsx b/packages/fuselage/src/components/Card/CardContent.tsx new file mode 100644 index 0000000000..1bf93e1ce2 --- /dev/null +++ b/packages/fuselage/src/components/Card/CardContent.tsx @@ -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; +}) => ( + + {children} + +); + +export default CardContent; diff --git a/packages/fuselage/src/components/Card/CardControls.tsx b/packages/fuselage/src/components/Card/CardControls.tsx new file mode 100644 index 0000000000..18112d7c0e --- /dev/null +++ b/packages/fuselage/src/components/Card/CardControls.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import Box from '../Box/Box'; + +const CardControls = ({ ...props }) => ( + +); + +export default CardControls; diff --git a/packages/fuselage/src/components/Card/CardFramedIcon.tsx b/packages/fuselage/src/components/Card/CardFramedIcon.tsx new file mode 100644 index 0000000000..def37ddd80 --- /dev/null +++ b/packages/fuselage/src/components/Card/CardFramedIcon.tsx @@ -0,0 +1,14 @@ +import type { ComponentProps } from 'react'; +import React from 'react'; + +import { IconButton } from '../Button'; + +const CardFramedIcon = ({ + icon, + ...props +}: ComponentProps) => ( + + // +); + +export default CardFramedIcon; diff --git a/packages/fuselage/src/components/Card/CardHeader.tsx b/packages/fuselage/src/components/Card/CardHeader.tsx new file mode 100644 index 0000000000..89f5503b1e --- /dev/null +++ b/packages/fuselage/src/components/Card/CardHeader.tsx @@ -0,0 +1,11 @@ +import { Box } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; +import React from 'react'; + +const CardHeader = ({ children }: { children: ReactNode }) => ( + + {children} + +); + +export default CardHeader; diff --git a/packages/fuselage/src/components/Card/CardHorizontal.tsx b/packages/fuselage/src/components/Card/CardHorizontal.tsx new file mode 100644 index 0000000000..2c7abd931f --- /dev/null +++ b/packages/fuselage/src/components/Card/CardHorizontal.tsx @@ -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, 'is'>> = ({ + ...props +}) => { + const breakpoints = useBreakpoints(); + const isMobile = !breakpoints.includes('sm'); + + return ( + + ); +}; + +export default CardHorizontal; diff --git a/packages/fuselage/src/components/Card/CardTitle.tsx b/packages/fuselage/src/components/Card/CardTitle.tsx new file mode 100644 index 0000000000..285165df2d --- /dev/null +++ b/packages/fuselage/src/components/Card/CardTitle.tsx @@ -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'; +}) => ( + + {children} + {info && } + +); + +export default CardTitle; diff --git a/packages/fuselage/src/components/Card/index.ts b/packages/fuselage/src/components/Card/index.ts new file mode 100644 index 0000000000..5eccb3013b --- /dev/null +++ b/packages/fuselage/src/components/Card/index.ts @@ -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';