From 4904be0c8365ec536d502236c459fae4b921d927 Mon Sep 17 00:00:00 2001 From: Meolocious <90854445+Meolocious@users.noreply.github.com> Date: Thu, 19 Sep 2024 08:58:41 +0200 Subject: [PATCH] [B2BP-876] - Page-Switch new component (#409) * added page switch * modified page switch * ... * commit code change * commit code change * commit changeset * Resolve type errors * change subtitle to richtext * change style * change style * change div to stack * change stories --------- Co-authored-by: salvatorediocaro Co-authored-by: Simone Salsi Co-authored-by: Simone Salsi <59611877+simosalsi@users.noreply.github.com> --- .changeset/large-ladybugs-admire.md | 5 + .../Page-Switch/Page-Switch.helpers.tsx | 300 ++++++++++++++++++ .../components/Page-Switch/Page-Switch.tsx | 156 +++++++++ .../react-components/components/index.ts | 2 + .../types/Page-Switch/Page-Switch.types.ts | 31 ++ .../react-components/types/index.ts | 2 + .../src/components/BannerLink.tsx | 2 +- apps/nextjs-website/src/components/Cards.tsx | 2 +- .../components/PageSection/PageSection.tsx | 3 + .../src/components/PageSwitch.tsx | 47 +++ .../src/lib/fetch/types/PageSection.ts | 22 ++ .../stories/Page-Switch/dark.stories.tsx | 18 ++ .../stories/Page-Switch/light.stories.tsx | 18 ++ .../stories/Page-Switch/pageSwitchCommons.tsx | 274 ++++++++++++++++ 14 files changed, 880 insertions(+), 2 deletions(-) create mode 100644 .changeset/large-ladybugs-admire.md create mode 100644 apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.helpers.tsx create mode 100644 apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.tsx create mode 100644 apps/nextjs-website/react-components/types/Page-Switch/Page-Switch.types.ts create mode 100644 apps/nextjs-website/src/components/PageSwitch.tsx create mode 100644 apps/nextjs-website/stories/Page-Switch/dark.stories.tsx create mode 100644 apps/nextjs-website/stories/Page-Switch/light.stories.tsx create mode 100644 apps/nextjs-website/stories/Page-Switch/pageSwitchCommons.tsx diff --git a/.changeset/large-ladybugs-admire.md b/.changeset/large-ladybugs-admire.md new file mode 100644 index 000000000..1fb738e56 --- /dev/null +++ b/.changeset/large-ladybugs-admire.md @@ -0,0 +1,5 @@ +--- +"nextjs-website": minor +--- + +Implement Page-Switch new component diff --git a/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.helpers.tsx b/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.helpers.tsx new file mode 100644 index 000000000..9b5039c31 --- /dev/null +++ b/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.helpers.tsx @@ -0,0 +1,300 @@ +import React from 'react'; +import { + ButtonSwitchRowBlockProps, + PageSwitchBaseProps, +} from '../../types/Page-Switch/Page-Switch.types'; +import { CtaButtons, Subtitle, Title } from '../common/Common'; +import { TextColor } from '../common/Common.helpers'; +import { + Button, + ButtonGroup, + Menu, + MenuItem, + Stack, + useMediaQuery, + useTheme, +} from '@mui/material'; +import { ArrowDropDown } from '@mui/icons-material'; + +export const TitleSubtitleBlock = ({ + title, + subtitle, + theme, +}: PageSwitchBaseProps) => { + const muiTheme = useTheme(); + + const linkStyles = { + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + textDecorationColor: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + fontWeight: '700', + '&:hover': { + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + }, + }; + + const styledSubtitle = subtitle + ? React.cloneElement(subtitle, { + style: { + textAlign: 'center', + }, + children: React.Children.map(subtitle.props.children, (child) => { + if (typeof child === 'string') return child; + if (child?.type === 'a') { + return React.cloneElement(child, { + style: linkStyles, + }); + } + return child; + }), + }) + : undefined; + + return ( + + + {subtitle && ( + <Subtitle + variant='body2' + textColor={TextColor(theme)} + subtitle={styledSubtitle || subtitle} + textAlign='center' + marginBottom={4} + /> + )} + </Stack> + ); +}; + +const SplitButton = ({ + buttons, + selectedButton, + onButtonClick, + theme, +}: ButtonSwitchRowBlockProps) => { + const muiTheme = useTheme(); + const { palette } = useTheme(); + const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null); + const [open, setOpen] = React.useState(false); + + const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => { + setAnchorEl(event.currentTarget); + setOpen((prevOpen) => !prevOpen); + }; + + const handleMenuItemClick = (button: { id: number; text: string }) => { + onButtonClick(button.id); + setOpen(false); + }; + + const closeMenu = () => { + setOpen(false); + }; + + const anchorRef = React.useRef<HTMLDivElement>(null); + + return ( + <React.Fragment> + <ButtonGroup + variant='outlined' + ref={anchorRef} + aria-label='Split button' + sx={{ display: 'flex', justifyContent: 'center' }} + > + <Button + onClick={() => { + onButtonClick(selectedButton.id); + }} + sx={{ + backgroundColor: 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + borderColor: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + '&:hover': { + backgroundColor: 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + }, + }} + > + {selectedButton.text} + </Button> + <Button + aria-controls={open ? 'split-button-menu' : undefined} + aria-expanded={open ? 'true' : undefined} + aria-haspopup='menu' + onClick={handleButtonClick} + sx={{ + backgroundColor: 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + borderColor: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + '&:hover': { + backgroundColor: 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + }, + }} + > + <ArrowDropDown /> + </Button> + </ButtonGroup> + <Menu + id='split-button-menu' + anchorEl={anchorEl} + open={open} + onClose={closeMenu} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'center', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'center', + }} + MenuListProps={{ + 'aria-labelledby': 'split-button', + }} + PaperProps={{ + sx: { + bgcolor: + theme === 'light' ? 'background.paper' : 'background.default', + color: theme === 'light' ? 'text.primary' : 'text.secondary', + }, + }} + > + {buttons.map((button) => ( + <MenuItem + key={button.id} + selected={button.id === selectedButton.id} + onClick={() => { + handleMenuItemClick(button); + }} + sx={{ + backgroundColor: 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + '&:hover': { + backgroundColor: 'transparent', + color: muiTheme.palette.primary.main, + }, + '&.Mui-selected': { + backgroundColor: + palette.custom.editorialSwitchButtonsBackgroundLightBlue, + color: + theme === 'dark' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.main, + }, + '&.Mui-selected:hover': { + backgroundColor: + palette.custom.editorialSwitchButtonsBackgroundLightBlue, + color: + theme === 'dark' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.main, + }, + '&:not(.Mui-selected)': { + color: muiTheme.palette.primary.main, + }, + }} + > + {button.text} + </MenuItem> + ))} + </Menu> + </React.Fragment> + ); +}; + +export const ButtonSwitchRowBlock = ({ + buttons, + onButtonClick, + theme, + selectedButton, +}: ButtonSwitchRowBlockProps) => { + const muiTheme = useTheme(); + const { palette } = useTheme(); + const isLarge = useMediaQuery(muiTheme.breakpoints.up('lg')); + const isSmallScreen = useMediaQuery(muiTheme.breakpoints.down('sm')); + + return isLarge ? ( + <Stack direction={isSmallScreen ? 'column' : 'row'} spacing={2}> + {CtaButtons({ + ctaButtons: buttons.map((button) => ({ + text: button.text, + sx: { + width: { md: 'auto', xs: '100%' }, + backgroundColor: + button.id === selectedButton.id + ? palette.custom.editorialSwitchButtonsBackgroundLightBlue + : 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + '&:hover': { + backgroundColor: + button.id === selectedButton.id + ? palette.custom.editorialSwitchButtonsBackgroundLightBlue + : 'transparent', + color: + theme === 'light' + ? muiTheme.palette.primary.main + : muiTheme.palette.primary.contrastText, + }, + }, + variant: 'outlined', + onClick: () => onButtonClick(button.id), + })), + theme, + })} + </Stack> + ) : ( + <SplitButton + buttons={buttons} + selectedButton={selectedButton} + onButtonClick={onButtonClick} + theme={theme} + /> + ); +}; diff --git a/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.tsx b/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.tsx new file mode 100644 index 000000000..8dbeeadc4 --- /dev/null +++ b/apps/nextjs-website/react-components/components/Page-Switch/Page-Switch.tsx @@ -0,0 +1,156 @@ +import React, { useEffect, useState } from 'react'; +import { Box, ButtonGroup, Button } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; +import ContainerRC from '../common/ContainerRC'; +import { BackgroundColor } from '../common/Common.helpers'; +import { + ButtonSwitchRowBlock, + TitleSubtitleBlock, +} from './Page-Switch.helpers'; +import { + PageSwitchProps, + PageSwitchSection, + PageSwitchContent, +} from '../../types/Page-Switch/Page-Switch.types'; +import Editorial from '../Editorial/Editorial'; +import Cards from '../Cards/Cards'; +import BannerLink from '../BannerLink/BannerLink'; + +const renderContent = (contents: PageSwitchContent[]) => { + return contents.map((content, index) => { + switch (content.type) { + case 'Editorial': + return <Editorial key={index} {...content.props} />; + case 'Cards': + return <Cards key={index} {...content.props} />; + case 'BannerLink': + return <BannerLink key={index} {...content.props} />; + default: + return null; + } + }); +}; + +const PageSwitch = ({ sections, theme, title, subtitle }: PageSwitchProps) => { + if (sections[0] === undefined) { + return null; + } + + const [currentSection, setCurrentSection] = useState<PageSwitchSection>( + sections[0] + ); + + const handleButtonClick = (sectionID: number) => { + const section = sections.find((s) => s.id === sectionID); + if (section !== undefined) { + setCurrentSection(section); + } + }; + + const [isMobile, setIsMobile] = useState( + typeof window !== 'undefined' ? window.innerWidth <= 1024 : false + ); + + useEffect((): void | VoidFunction => { + const handleResize = () => { + setIsMobile( + typeof window !== 'undefined' ? window.innerWidth <= 1024 : false + ); + }; + + if (typeof window !== 'undefined') { + window.addEventListener('resize', handleResize); + return () => { + window.removeEventListener('resize', handleResize); + }; + } + }, []); + + const { palette } = useTheme(); + + const backgroundColor = BackgroundColor(theme); + + return ( + <Box> + <ContainerRC + sx={{ display: 'grid', justifyContent: 'center', alignItems: 'center' }} + background={backgroundColor} + > + <TitleSubtitleBlock + title={title} + {...(subtitle && { subtitle })} + theme={theme} + /> + {isMobile ? ( + <ButtonSwitchRowBlock + buttons={sections.map((s) => ({ + id: s.id, + text: s.buttonText, + }))} + selectedButton={{ + id: currentSection.id, + text: currentSection.buttonText, + }} + onButtonClick={handleButtonClick} + theme={theme} + /> + ) : ( + <ButtonGroup + variant="outlined" + aria-label="buttonGroup" + sx={{ margin: '16px 0' }} + > + {sections.map((section) => ( + <Button + key={section.id} + onClick={() => handleButtonClick(section.id)} + sx={{ + backgroundColor: + section.id === currentSection.id + ? theme === 'light' + ? palette.custom + .editorialSwitchButtonsBackgroundLightBlue + : palette.background.paper + : 'transparent', + color: + section.id === currentSection.id + ? theme === 'light' + ? palette.primary.main + : palette.custom.primaryColorDark + : theme === 'light' + ? palette.primary.main + : palette.primary.contrastText, + borderColor: + theme === 'light' + ? palette.primary.main + : palette.background.paper, + '&:hover': { + backgroundColor: + theme === 'light' + ? palette.custom + .editorialSwitchButtonsBackgroundLightBlue + : palette.background.paper, + color: + theme === 'light' + ? palette.primary.main + : palette.custom.primaryColorDark, + borderColor: + theme === 'light' + ? palette.primary.main + : palette.background.paper, + }, + }} + disableRipple + > + {section.buttonText} + </Button> + ))} + </ButtonGroup> + )} + </ContainerRC> + {renderContent(currentSection.contents)} + </Box> + ); +}; + +export default PageSwitch; diff --git a/apps/nextjs-website/react-components/components/index.ts b/apps/nextjs-website/react-components/components/index.ts index 2b14076ec..333545288 100644 --- a/apps/nextjs-website/react-components/components/index.ts +++ b/apps/nextjs-website/react-components/components/index.ts @@ -22,6 +22,7 @@ import HighlightBox from './HighlightBox/HighlightBox'; import Stats from './Stats/Stats'; import RowText from './RowText/RowText'; import TextSection from './TextSection/TextSection'; +import PageSwitch from './Page-Switch/Page-Switch'; export { Hero, @@ -48,4 +49,5 @@ export { Stats, RowText, TextSection, + PageSwitch, }; diff --git a/apps/nextjs-website/react-components/types/Page-Switch/Page-Switch.types.ts b/apps/nextjs-website/react-components/types/Page-Switch/Page-Switch.types.ts new file mode 100644 index 000000000..31243b1e0 --- /dev/null +++ b/apps/nextjs-website/react-components/types/Page-Switch/Page-Switch.types.ts @@ -0,0 +1,31 @@ +import { EditorialProps } from '../Editorial/Editorial.types'; +import { CardsProps } from '../Cards/Cards.types'; +import { BannerLinkProps } from '../BannerLink/BannerLink.types'; + +export interface PageSwitchBaseProps { + title: string; + subtitle?: JSX.Element; + theme: 'dark' | 'light'; +} + +export interface PageSwitchSection { + id: number; + buttonText: string; + contents: PageSwitchContent[]; +} + +export type PageSwitchContent = + | { type: 'Editorial'; props: EditorialProps } + | { type: 'Cards'; props: CardsProps } + | { type: 'BannerLink'; props: BannerLinkProps }; + +export interface PageSwitchProps extends PageSwitchBaseProps { + sections: PageSwitchSection[]; +} + +export interface ButtonSwitchRowBlockProps { + buttons: { id: number; text: string }[]; + onButtonClick: (sectionID: number) => void; + selectedButton: { id: number; text: string }; + theme: 'dark' | 'light'; +} diff --git a/apps/nextjs-website/react-components/types/index.ts b/apps/nextjs-website/react-components/types/index.ts index f19dbd96d..c7be60ed7 100644 --- a/apps/nextjs-website/react-components/types/index.ts +++ b/apps/nextjs-website/react-components/types/index.ts @@ -22,6 +22,7 @@ import { HighlightBoxProps } from './HighlightBox/HighlightBox.types'; import { StatsProps } from './Stats/Stats.types'; import { RowTextProps } from './RowText/RowText.types'; import { TextSectionProps } from './TextSection/TextSection.types'; +import { PageSwitchProps } from './Page-Switch/Page-Switch.types'; export type { HeroProps, @@ -48,4 +49,5 @@ export type { StatsProps, RowTextProps, TextSectionProps, + PageSwitchProps, }; diff --git a/apps/nextjs-website/src/components/BannerLink.tsx b/apps/nextjs-website/src/components/BannerLink.tsx index d232a1ab3..f1e8846fb 100644 --- a/apps/nextjs-website/src/components/BannerLink.tsx +++ b/apps/nextjs-website/src/components/BannerLink.tsx @@ -4,7 +4,7 @@ import { BannerLink as BannerLinkRC } from '@react-components/components'; import { BannerLinkProps } from '@react-components/types/BannerLink/BannerLink.types'; import { BannerLinkSection } from '@/lib/fetch/types/PageSection'; -const makeBannerLinkProps = ({ +export const makeBannerLinkProps = ({ sections, ...rest }: BannerLinkSection): BannerLinkProps => ({ diff --git a/apps/nextjs-website/src/components/Cards.tsx b/apps/nextjs-website/src/components/Cards.tsx index 5f250354f..ecea8fa68 100644 --- a/apps/nextjs-website/src/components/Cards.tsx +++ b/apps/nextjs-website/src/components/Cards.tsx @@ -5,7 +5,7 @@ import { Cards as CardsRC } from '@react-components/components'; import { CardsProps } from '@react-components/types'; import { CardsSection } from '@/lib/fetch/types/PageSection'; -const makeCardsProps = ({ +export const makeCardsProps = ({ items, title, subtitle, diff --git a/apps/nextjs-website/src/components/PageSection/PageSection.tsx b/apps/nextjs-website/src/components/PageSection/PageSection.tsx index 8ef031285..5f058bbc4 100644 --- a/apps/nextjs-website/src/components/PageSection/PageSection.tsx +++ b/apps/nextjs-website/src/components/PageSection/PageSection.tsx @@ -19,6 +19,7 @@ import HighlightBox from '../HighlightBox'; import Stats from '../Stats'; import RowText from '../RowText'; import TextSection from '../TextSection'; +import PageSwitch from '../PageSwitch'; import { PageSection as PageSectionData } from '@/lib/fetch/types/PageSection'; // eslint-disable-next-line complexity const PageSection = (props: PageSectionData) => { @@ -64,6 +65,8 @@ const PageSection = (props: PageSectionData) => { return <RowText {...props} />; case 'sections.text-section': return <TextSection {...props} />; + case 'sections.page-switch': + return <PageSwitch {...props} />; default: return null; } diff --git a/apps/nextjs-website/src/components/PageSwitch.tsx b/apps/nextjs-website/src/components/PageSwitch.tsx new file mode 100644 index 000000000..de00c1163 --- /dev/null +++ b/apps/nextjs-website/src/components/PageSwitch.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { makeEditorialProps } from './Editorial'; +import { makeCardsProps } from './Cards'; +import { makeBannerLinkProps } from './BannerLink'; +import MarkdownRenderer from './MarkdownRenderer'; +import { PageSwitch as PageSwitchRC } from '@react-components/components'; +import { PageSwitchProps } from '@react-components/types'; +import { PageSwitchSection } from '@/lib/fetch/types/PageSection'; + +const makePageSwitchProps = ({ + subtitle, + sections, + ...rest +}: PageSwitchSection): PageSwitchProps => ({ + ...(subtitle && { subtitle: MarkdownRenderer({ markdown: subtitle }) }), + sections: sections.map((section) => ({ + id: section.id, + buttonText: section.buttonText, + contents: section.contents.map((props) => { + // eslint-disable-next-line no-underscore-dangle + switch (props.__component) { + case 'sections.editorial': + return { + type: 'Editorial', + props: makeEditorialProps(props), + }; + case 'sections.cards': + return { + type: 'Cards', + props: makeCardsProps(props), + }; + case 'sections.banner-link': + return { + type: 'BannerLink', + props: makeBannerLinkProps(props), + }; + } + }), + })), + ...rest, +}); + +const PageSwitch = (props: PageSwitchSection) => ( + <PageSwitchRC {...makePageSwitchProps(props)} /> +); + +export default PageSwitch; diff --git a/apps/nextjs-website/src/lib/fetch/types/PageSection.ts b/apps/nextjs-website/src/lib/fetch/types/PageSection.ts index 9035bae00..b320e2c0d 100644 --- a/apps/nextjs-website/src/lib/fetch/types/PageSection.ts +++ b/apps/nextjs-website/src/lib/fetch/types/PageSection.ts @@ -342,6 +342,26 @@ const HighlightBoxSectionCodec = t.strict({ sectionID: t.union([t.string, t.null]), }); +const PageSwitchContentCodec = t.union([ + EditorialSectionCodec, + CardsSectionCodec, + BannerLinkSectionCodec, +]); + +const PageSwitchSectionCodec = t.strict({ + __component: t.literal('sections.page-switch'), + theme: t.union([t.literal('light'), t.literal('dark')]), + title: t.string, + subtitle: t.union([t.string, t.null]), + sections: t.array( + t.strict({ + id: t.number, + buttonText: t.string, + contents: t.array(PageSwitchContentCodec), + }) + ), +}); + export const PageSectionCodec = t.union([ HeroSectionCodec, EditorialSectionCodec, @@ -364,6 +384,7 @@ export const PageSectionCodec = t.union([ StatsSectionCodec, RowTextSectionCodec, TextSectionSectionCodec, + PageSwitchSectionCodec, ]); export type PageSection = t.TypeOf<typeof PageSectionCodec>; @@ -392,3 +413,4 @@ export type HighlightBoxSection = t.TypeOf<typeof HighlightBoxSectionCodec>; export type StatsSection = t.TypeOf<typeof StatsSectionCodec>; export type RowTextSection = t.TypeOf<typeof RowTextSectionCodec>; export type TextSectionSection = t.TypeOf<typeof TextSectionSectionCodec>; +export type PageSwitchSection = t.TypeOf<typeof PageSwitchSectionCodec>; diff --git a/apps/nextjs-website/stories/Page-Switch/dark.stories.tsx b/apps/nextjs-website/stories/Page-Switch/dark.stories.tsx new file mode 100644 index 000000000..08c9953cb --- /dev/null +++ b/apps/nextjs-website/stories/Page-Switch/dark.stories.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { StoryFn, Meta } from '@storybook/react'; +import { PageSwitch } from '@react-components/components'; +import { PageSwitchProps } from '@react-components/types'; +import { defaultPropsDark } from './pageSwitchCommons'; + +const meta: Meta<typeof PageSwitch> = { + title: 'Components/PageSwitch/Dark', + component: PageSwitch, +}; +export default meta; + +const PageSwitchTemplate: StoryFn<PageSwitchProps> = (args) => <PageSwitch {...args} />; + +export const Default: StoryFn<typeof PageSwitch> = PageSwitchTemplate.bind({}); +Default.args = { + ...defaultPropsDark, +}; diff --git a/apps/nextjs-website/stories/Page-Switch/light.stories.tsx b/apps/nextjs-website/stories/Page-Switch/light.stories.tsx new file mode 100644 index 000000000..c21db5449 --- /dev/null +++ b/apps/nextjs-website/stories/Page-Switch/light.stories.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { StoryFn, Meta } from '@storybook/react'; +import { PageSwitch } from '@react-components/components'; +import { PageSwitchProps } from '@react-components/types'; +import { defaultPropsLight } from './pageSwitchCommons'; + +const meta: Meta<typeof PageSwitch> = { + title: 'Components/PageSwitch/Light', + component: PageSwitch, +}; +export default meta; + +const PageSwitchTemplate: StoryFn<PageSwitchProps> = (args) => <PageSwitch {...args} />; + +export const Default: StoryFn<typeof PageSwitch> = PageSwitchTemplate.bind({}); +Default.args = { + ...defaultPropsLight, +}; diff --git a/apps/nextjs-website/stories/Page-Switch/pageSwitchCommons.tsx b/apps/nextjs-website/stories/Page-Switch/pageSwitchCommons.tsx new file mode 100644 index 000000000..702586ccc --- /dev/null +++ b/apps/nextjs-website/stories/Page-Switch/pageSwitchCommons.tsx @@ -0,0 +1,274 @@ +import { StoryFn } from '@storybook/react'; +import { PageSwitch } from '@react-components/components'; +import { PageSwitchProps } from '@react-components/types'; +import MailIcon from '@mui/icons-material/Mail'; + +export const PageSwitchTemplate: StoryFn<PageSwitchProps> = (args) => ( + <PageSwitch {...args} /> +); + +const generateDefaultProps = ( + theme: 'light' | 'dark' +): Partial<PageSwitchProps> => ({ + theme, + title: 'Top Title', + subtitle: ( + <p> + Top subtitle with <a href='/'>link</a> + </p> + ), + sections: [ + { + id: 1, + buttonText: 'Button 1', + contents: [ + { + type: 'Editorial', + props: { + theme: 'light', + title: 'Editorial 1', + body: 'Light Editorial', + width: 'standard', + image: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pa-infoblock-5.png' + alt='placeholder' + /> + ), + mobileImage: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pi-infoblock-1.png' + alt='placeholder' + /> + ), + sectionID: '', + }, + }, + { + type: 'Cards', + props: { + theme: 'dark', + items: [ + { + title: 'Card 1', + text: 'This is card 1', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + { + title: 'Card 2', + text: 'This is card 2', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + ], + text: { + title: 'Cards', + subtitle: 'Cards subtitle', + body: 'Cards Body', + }, + sectionID: '', + textPosition: 'left', + }, + }, + { + type: 'BannerLink', + props: { + theme: 'light', + sections: [ + { + title: 'Scrivici', + body: ( + <p> + Richiedi assistenza via email scrivendo a{' '} + <a href='mailto:destinatari-send@assistenza.pagopa.it'> + destinatari-send@assistenza.pagopa.it + </a> + </p> + ), + icon: <MailIcon style={{ fontSize: 60 }} />, + ctaButtons: [ + { + text: 'Scrivici', + variant: 'contained', + href: 'mailto:destinatari-send@assistenza.pagopa.it', + }, + ], + }, + ], + sectionID: '', + }, + }, + ], + }, + { + id: 2, + buttonText: 'Button 2', + contents: [ + { + type: 'Editorial', + props: { + theme: 'dark', + title: 'Editorial 2', + body: 'Dark Editorial', + width: 'standard', + image: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pa-infoblock-5.png' + alt='placeholder' + /> + ), + mobileImage: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pi-infoblock-1.png' + alt='placeholder' + /> + ), + sectionID: '', + }, + }, + { + type: 'Cards', + props: { + theme: 'light', + items: [ + { + title: 'Card 3', + text: 'This is card 3', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + { + title: 'Card 4', + text: 'This is card 4', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + ], + text: { + title: 'Cards 2', + subtitle: 'Cards subtitle 2', + body: 'Cards Body 2', + }, + sectionID: '', + textPosition: 'left', + }, + }, + { + type: 'BannerLink', + props: { + theme: 'dark', + sections: [ + { + title: 'Contattaci', + body: ( + <p> + Richiedi assistenza via email scrivendo a{' '} + <a href='mailto:destinatari-send@assistenza.pagopa.it'> + destinatari-send@assistenza.pagopa.it + </a> + </p> + ), + icon: <MailIcon style={{ fontSize: 60 }} />, + ctaButtons: [ + { + text: 'Contattaci', + variant: 'contained', + href: 'mailto:destinatari-send@assistenza.pagopa.it', + }, + ], + }, + ], + sectionID: '', + }, + }, + ], + }, + { + id: 3, + buttonText: 'Button 3', + contents: [ + { + type: 'Editorial', + props: { + theme: 'light', + title: 'Editorial 3', + body: 'Light Editorial 3', + width: 'standard', + image: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pa-infoblock-5.png' + alt='placeholder' + /> + ), + mobileImage: ( + <img + src='https://notifichedigitali.pagopa.it/static/images/pi-infoblock-1.png' + alt='placeholder' + /> + ), + sectionID: '', + }, + }, + { + type: 'Cards', + props: { + theme: 'dark', + items: [ + { + title: 'Card 5', + text: 'This is card 5', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + { + title: 'Card 6', + text: 'This is card 6', + iconURL: + 'https://d2mk0pc4ejgxx6.cloudfront.net/light_icon_f76dbe7883.svg', + }, + ], + text: { + title: 'Cards 3', + subtitle: 'Cards subtitle 3', + body: 'Cards Body 3', + }, + sectionID: '', + textPosition: 'left', + }, + }, + { + type: 'BannerLink', + props: { + theme: 'light', + sections: [ + { + title: 'Aiuto', + body: ( + <p> + Richiedi assistenza via email scrivendo a{' '} + <a href='mailto:destinatari-send@assistenza.pagopa.it'> + destinatari-send@assistenza.pagopa.it + </a> + </p> + ), + icon: <MailIcon style={{ fontSize: 60 }} />, + ctaButtons: [ + { + text: 'Aiuto', + variant: 'contained', + href: 'mailto:destinatari-send@assistenza.pagopa.it', + }, + ], + }, + ], + sectionID: '', + }, + }, + ], + }, + ], +}); + +export const defaultPropsDark = generateDefaultProps('dark'); +export const defaultPropsLight = generateDefaultProps('light');