diff --git a/.changeset/wet-seals-rule.md b/.changeset/wet-seals-rule.md new file mode 100644 index 00000000..36824670 --- /dev/null +++ b/.changeset/wet-seals-rule.md @@ -0,0 +1,5 @@ +--- +'@smile/react-front-kit': minor +--- + +Add collapse function for infoCard component diff --git a/packages/react-front-kit/src/Components/InfoCard/InfoCard.stories.tsx b/packages/react-front-kit/src/Components/InfoCard/InfoCard.stories.tsx index 0c67f6aa..d792979c 100644 --- a/packages/react-front-kit/src/Components/InfoCard/InfoCard.stories.tsx +++ b/packages/react-front-kit/src/Components/InfoCard/InfoCard.stories.tsx @@ -17,6 +17,7 @@ type IStory = StoryObj; export const InfoCard: IStory = { args: { children:

Customizable content

, + collapse: true, content: (

Jean-Michel DUPONT, + title:

Jean-Michel DUPONT

, }, }; diff --git a/packages/react-front-kit/src/Components/InfoCard/InfoCard.style.tsx b/packages/react-front-kit/src/Components/InfoCard/InfoCard.style.tsx new file mode 100644 index 00000000..8d16a2af --- /dev/null +++ b/packages/react-front-kit/src/Components/InfoCard/InfoCard.style.tsx @@ -0,0 +1,105 @@ +import type { IMantineBreakpoint } from './InfoCard'; + +import { createStyles } from '@mantine/core'; + +export const useStyles = createStyles( + (theme, responsiveBreakpoint: IMantineBreakpoint) => ({ + collapseButton: { + [`@media screen and (max-width: ${theme.breakpoints[responsiveBreakpoint]})`]: + { + margin: 'auto', + }, + margin: '12px', + }, + collapseButtonCenter: { + marginBottom: 'auto', + marginTop: 'auto', + }, + collapseRight: { + height: '100%', + width: '100%', + }, + container: { + [`@media screen and (max-width: ${theme.breakpoints[responsiveBreakpoint]})`]: + { + flexDirection: 'column', + margin: 'auto', + width: 'fit-content', + }, + display: 'flex', + flexWarp: 'wrap', + gap: 10, + justifyContent: 'space-between', + position: 'relative', + zIndex: 1, + }, + contentItem: { + alignItems: 'center', + cursor: 'pointer', + display: 'flex', + fontSize: '20px', + justifyContent: 'center', + }, + contentItemGroup: { + alignItems: 'center', + display: 'flex', + gap: 16, + justifyContent: 'left', + maxWidth: 175, + }, + contentItems: { + [`@media screen and (max-width: ${theme.breakpoints[responsiveBreakpoint]})`]: + { + minWidth: '0px', + }, + columnGap: 40, + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'left', + marginBottom: '28px', + rowGap: 10, + }, + leftContainer: { + [`@media screen and (max-width: ${theme.breakpoints[responsiveBreakpoint]})`]: + { + minWidth: '0px !important', + }, + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + minWidth: '390px', + }, + motif: { + left: -40, + position: 'absolute', + top: -60, + zIndex: 0, + }, + rightContainer: { + [`@media screen and (max-width: ${theme.breakpoints[responsiveBreakpoint]})`]: + { + maxWidth: 440, + }, + display: 'flex', + height: '100%', + width: '100%', + }, + root: { + overflow: 'hidden', + padding: '24px 48px', + position: 'relative', + width: '100%', + }, + title: { + 'h1, h2, h3, h4 h5, p': { + fontSize: '26px', + fontWeight: 700, + }, + }, + topContent: { + display: 'flex', + flexDirection: 'column', + rowGap: 24, + }, + }), +); diff --git a/packages/react-front-kit/src/Components/InfoCard/InfoCard.tsx b/packages/react-front-kit/src/Components/InfoCard/InfoCard.tsx index ff840b10..0a7fb5e4 100644 --- a/packages/react-front-kit/src/Components/InfoCard/InfoCard.tsx +++ b/packages/react-front-kit/src/Components/InfoCard/InfoCard.tsx @@ -3,88 +3,14 @@ import type { ActionIconProps, PaperProps } from '@mantine/core'; import type { CSSProperties, ReactElement } from 'react'; -import { ActionIcon, Paper, useMantineTheme } from '@mantine/core'; -import { createStyles } from '@mantine/styles'; +import { ActionIcon, Collapse, Paper, useMantineTheme } from '@mantine/core'; +import { useDisclosure } from '@mantine/hooks'; +import { CaretDown, CaretUp } from '@phosphor-icons/react'; +import { useStyles } from './InfoCard.style'; import { Motif } from './Motif'; -const useStyles = createStyles(() => ({ - container: { - '@media (max-width: 834px)': { - flexDirection: 'column', - margin: 'auto', - width: 'fit-content', - }, - display: 'flex', - flexWarp: 'wrap', - gap: 10, - justifyContent: 'space-between', - position: 'relative', - zIndex: 1, - }, - content: { - // marginTop: 10, - }, - contentItem: { - alignItems: 'center', - cursor: 'pointer', - display: 'flex', - fontSize: '20px', - justifyContent: 'center', - }, - contentItemGroup: { - alignItems: 'center', - display: 'flex', - gap: 16, - justifyContent: 'left', - maxWidth: 175, - }, - contentItems: { - '@media (max-width: 834px)': { - minWidth: '0px', - }, - columnGap: 40, - display: 'flex', - flexWrap: 'wrap', - justifyContent: 'left', - rowGap: 10, - }, - leftContainer: { - display: 'flex', - flexDirection: 'column', - gap: 28, - justifyContent: 'space-between', - }, - motif: { - left: -40, - position: 'absolute', - top: -60, - zIndex: 0, - }, - rightContainer: { - '@media (min-width: 834px)': { - maxWidth: 440, - }, - display: 'flex', - width: '100%', - }, - root: { - overflow: 'hidden', - position: 'relative', - width: '100%', - }, - title: { - 'h1, h2, h3, h4 h5, p': { - fontSize: '26px', - fontWeight: 700, - }, - }, - topContent: { - display: 'flex', - flexDirection: 'column', - rowGap: 24, - }, -})); +export type IMantineBreakpoint = 'lg' | 'md' | 'sm' | 'xs'; export interface IContentItem { icon?: ReactElement; @@ -95,10 +21,12 @@ export interface IContentItem { export interface IInfoCardProps extends PaperProps { children?: ReactElement; + collapse?: boolean; content?: ReactElement; contentItems?: IContentItem[]; leftContainerStyle?: CSSProperties; motif?: ReactElement; + responsiveBreakpoint?: IMantineBreakpoint; rightContainerStyle?: CSSProperties; title?: ReactElement; } @@ -108,60 +36,76 @@ export function InfoCard(props: IInfoCardProps): ReactElement { const theme = useMantineTheme(); const { children, + collapse = true, content, contentItems = [], leftContainerStyle, motif = , rightContainerStyle, + responsiveBreakpoint = 'sm', title, ...PaperProps } = props; - const { classes } = useStyles(); + + const { classes } = useStyles(responsiveBreakpoint); + const [opened, { toggle }] = useDisclosure(true); return ( - +
{motif}
{Boolean(title) &&
{title}
} - {Boolean(contentItems.length > 0) && ( -
- {contentItems.map((item, key) => ( -
- {Boolean(item.icon) && ( - item.onAction?.(item)} - radius="sm" - size={40} - variant="filled" - {...item.iconProps} - > - {item.icon} - - )} - {Boolean(item.label) && {item.label}} -
- ))} -
- )} + + {Boolean(contentItems.length > 0) && ( +
+ {contentItems.map((item, key) => ( +
+ {Boolean(item.icon) && ( + item.onAction?.(item)} + radius="sm" + size={40} + variant="filled" + {...item.iconProps} + > + {item.icon} + + )} + {Boolean(item.label) && {item.label}} +
+ ))} +
+ )} +
- {Boolean(content) &&
{content}
} -
-
- {children} + {Boolean(content) &&
{content}
}
+ +
+ {children} +
+
+ {Boolean(collapse) && ( + + {opened ? ( + + ) : ( + + )} + + )}
); diff --git a/packages/react-front-kit/src/Components/InfoCard/__snapshots__/InfoCard.test.tsx.snap b/packages/react-front-kit/src/Components/InfoCard/__snapshots__/InfoCard.test.tsx.snap index 355c0d23..f6f88c82 100644 --- a/packages/react-front-kit/src/Components/InfoCard/__snapshots__/InfoCard.test.tsx.snap +++ b/packages/react-front-kit/src/Components/InfoCard/__snapshots__/InfoCard.test.tsx.snap @@ -3,7 +3,7 @@ exports[`InfoCard matches snapshot 1`] = `
+ > +
+
+
+
+ aria-hidden="false" + class="mantine-15w1456" + style="box-sizing: border-box;" + > +
+
+
+
+