diff --git a/apps/website/screens/components/avatar/overview/images/avatar_colors.png b/apps/website/screens/components/avatar/overview/images/avatar_colors.png index d6d00bc81..308df2373 100644 Binary files a/apps/website/screens/components/avatar/overview/images/avatar_colors.png and b/apps/website/screens/components/avatar/overview/images/avatar_colors.png differ diff --git a/apps/website/screens/components/footer/code/FooterCodePage.tsx b/apps/website/screens/components/footer/code/FooterCodePage.tsx index 0de8bdbb3..8b09ac243 100644 --- a/apps/website/screens/components/footer/code/FooterCodePage.tsx +++ b/apps/website/screens/components/footer/code/FooterCodePage.tsx @@ -1,11 +1,10 @@ -import { DxcFlex, DxcTable, DxcLink } from "@dxc-technology/halstack-react"; +import { DxcFlex, DxcTable, DxcLink, DxcParagraph } from "@dxc-technology/halstack-react"; import QuickNavContainer from "@/common/QuickNavContainer"; import DocFooter from "@/common/DocFooter"; import StatusBadge from "@/common/StatusBadge"; import Code, { ExtendedTableCode, TableCode } from "@/common/Code"; const logoTypeString = `{ - href?: string; src: string; title?: string; }`; @@ -75,7 +74,7 @@ const sections = [ {logoTypeString} - Logo to be displayed inside the header. + Logo to be displayed inside the footer. - @@ -158,6 +157,23 @@ const sections = [ ), }, + { + title: "DxcFooter.LeftContent", + content: ( + + This compound will be used to display the content on the Left Container under the Logo. + + ), + }, + { + title: "DxcFooter.RigthContent", + content: ( + + This compound will be used to display the content on the Right Container of the footer, if socialLinks are + provided they will always display at the end of the container. + + ), + }, { title: "Examples", subSections: [ diff --git a/packages/lib/src/footer/Footer.stories.tsx b/packages/lib/src/footer/Footer.stories.tsx index ea1e2bfb3..462412ae9 100644 --- a/packages/lib/src/footer/Footer.stories.tsx +++ b/packages/lib/src/footer/Footer.stories.tsx @@ -131,7 +131,10 @@ const Footer = () => ( <> - <DxcFooter /> + <DxcFooter> + <DxcFooter.LeftContent>Holaaa</DxcFooter.LeftContent> + <DxcFooter.RightContent>Hellooo</DxcFooter.RightContent> + </DxcFooter> </ExampleContainer> <ExampleContainer> <Title title="With children, copyright, bottom links and social links" theme="light" level={4} /> diff --git a/packages/lib/src/footer/Footer.tsx b/packages/lib/src/footer/Footer.tsx index 42019cc08..3c0932b16 100644 --- a/packages/lib/src/footer/Footer.tsx +++ b/packages/lib/src/footer/Footer.tsx @@ -1,4 +1,4 @@ -import { useContext } from "react"; +import { ElementType, ReactNode, useContext, Children, isValidElement } from "react"; import styled from "@emotion/styled"; import { responsiveSizes, spaces } from "../common/variables"; import DxcFlex from "../flex/Flex"; @@ -12,51 +12,88 @@ const FooterContainer = styled.footer<{ margin: FooterPropsType["margin"]; mode?: FooterPropsType["mode"]; }>` - background-color: var(--color-bg-neutral-strongest); box-sizing: border-box; display: flex; flex-direction: ${(props) => (props?.mode === "default" ? "column" : "row")}; justify-content: space-between; margin-top: ${(props) => (props.margin ? spaces[props.margin] : "var(--spacing-padding-none)")}; - min-height: ${(props) => (props?.mode === "default" ? "124px" : "40px")}; width: 100%; - gap: var(--spacing-gap-m); - padding: ${(props) => - props?.mode === "default" - ? "var(--spacing-padding-m) var(--spacing-padding-xl)" - : "var(--spacing-padding-s) var(--spacing-padding-xl)"}; - @media (max-width: ${responsiveSizes.medium}rem) { - padding: var(--spacing-padding-l) var(--spacing-padding-ml); + + @media (max-width: ${responsiveSizes.small}rem) { + flex-direction: column; + } +`; + +const MainContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + + @media (min-width: ${responsiveSizes.small}rem) { + min-height: 80px; } + @media (max-width: ${responsiveSizes.small}rem) { flex-direction: column; + align-items: flex-start; + gap: var(--spacing-gap-ml); + padding: var(--spacing-padding-l) var(--spacing-padding-m); } `; const BottomContainer = styled.div` + width: 100%; display: flex; justify-content: space-between; - align-items: flex-end; + align-items: center; + background-color: var(--color-bg-primary-strong); + padding: var(--spacing-padding-none) var(--spacing-padding-xl); + box-sizing: border-box; @media (min-width: ${responsiveSizes.small}rem) { + height: var(--height-xl); flex-direction: row; } + @media (max-width: ${responsiveSizes.small}rem) { flex-direction: column; - align-items: center; + align-items: flex-start; + gap: var(--spacing-gap-ml); + padding: var(--spacing-padding-m); } +`; + +const LeftContainer = styled.div` + display: flex; + gap: var(--spacing-gap-ml); + height: 100%; + color: var(--color-fg-neutral-dark); - border-top: var(--border-width-s) var(--border-style-default) var(--border-color-primary-medium); - margin-top: var(--spacing-gap-m); + @media (min-width: ${responsiveSizes.small}rem) { + max-width: 33.3%; + padding: var(--spacing-padding-l) var(--spacing-padding-xl); + } + + @media (max-width: ${responsiveSizes.small}rem) { + flex-direction: column; + align-items: flex-start; + } `; -const ChildComponents = styled.div` - min-height: var(--height-xxs); - color: var(--color-fg-neutral-bright); +const RightContainer = styled.div` + display: flex; + justify-content: flex-end; + gap: var(--spacing-gap-xl); + height: 100%; + + @media (min-width: ${responsiveSizes.small}rem) { + max-width: 66.66%; + padding: var(--spacing-padding-l) var(--spacing-padding-xl); + } `; const Copyright = styled.div` - margin-top: var(--spacing-padding-xs); font-family: var(--typography-font-family); font-size: var(--typography-label-s); font-weight: var(--typography-label-regular); @@ -96,21 +133,21 @@ const SocialAnchor = styled.a<{ index: number }>` const SocialIconContainer = styled.div` display: flex; align-items: center; - color: var(--color-fg-neutral-bright); + color: var(--color-fg-primary-strong); overflow: hidden; font-size: var(--height-s); svg { - height: var(--height-s); - width: 24px; + height: var(--height-xs); + width: var(--height-xs); + fill: var(--color-fg-primary-strong); } `; -const BottomLinks = styled.div` +const BottomLinks = styled.div<{ hasContent: boolean }>` display: inline-flex; flex-wrap: wrap; align-self: center; - margin-top: var(--spacing-padding-xs); color: var(--color-fg-neutral-bright); @media (min-width: ${responsiveSizes.small}rem) { @@ -119,6 +156,7 @@ const BottomLinks = styled.div` @media (max-width: ${responsiveSizes.small}rem) { max-width: 100%; width: 100%; + display: ${(props) => (props.hasContent ? "inline-flex" : "none")}; } & > span:not(:first-child):before { @@ -133,7 +171,7 @@ const BottomLink = styled.a` font-family: var(--typography-font-family); font-size: var(--typography-label-m); font-weight: var(--typography-label-regular); - color: var(--color-fg-neutral-bright); + color: inherit; &:focus { outline: var(--border-width-m) var(--border-style-default) var(--border-color-secondary-medium); @@ -148,10 +186,13 @@ const getLogoElement = (mode: FooterPropsType["mode"], logo?: FooterPropsType["l } }; +const findChildType = (children: FooterPropsType["children"], childType: ElementType) => + Children.toArray(children).find((child) => isValidElement(child) && child.type === childType); + const DxcFooter = ({ bottomLinks, - children, copyright, + children, logo, margin, mode = "default", @@ -159,37 +200,47 @@ const DxcFooter = ({ tabIndex = 0, }: FooterPropsType): JSX.Element => { const translatedLabels = useContext(HalstackLanguageContext); - const footerLogo = getLogoElement(mode, logo); + const leftContentChild = findChildType(children, LeftContent); + const rightContentChild = findChildType(children, RightContent); return ( <FooterContainer margin={margin} mode={mode}> - <DxcFlex justifyContent="space-between" alignItems="center" wrap="wrap"> - <LogoContainer mode={mode}>{footerLogo}</LogoContainer> - {mode === "default" && ( - <DxcFlex gap="var(--spacing-gap-ml)"> - {socialLinks?.map((link, index) => ( - <Tooltip label={link.title} key={`social${index}${link.href}`}> - <SocialAnchor - href={link.href} - tabIndex={tabIndex} - aria-label={link.title} - key={`social${index}${link.href}`} - index={index} - > - <SocialIconContainer> - {typeof link.logo === "string" ? <DxcIcon icon={link.logo} /> : link.logo} - </SocialIconContainer> - </SocialAnchor> - </Tooltip> - ))} - </DxcFlex> - )} - </DxcFlex> - <ChildComponents>{children}</ChildComponents> {mode === "default" && ( - <BottomContainer> - <BottomLinks> + <MainContainer> + <LeftContainer> + <LogoContainer mode={mode}>{footerLogo}</LogoContainer> + {leftContentChild} + </LeftContainer> + {(socialLinks || rightContentChild) && ( + <RightContainer> + {rightContentChild} + {socialLinks && ( + <DxcFlex gap="var(--spacing-gap-ml)"> + {socialLinks?.map((link, index) => ( + <Tooltip label={link.title} key={`social${index}${link.href}`}> + <SocialAnchor + href={link.href} + tabIndex={tabIndex} + aria-label={link.title} + key={`social${index}${link.href}`} + index={index} + > + <SocialIconContainer> + {typeof link.logo === "string" ? <DxcIcon icon={link.logo} /> : link.logo} + </SocialIconContainer> + </SocialAnchor> + </Tooltip> + ))} + </DxcFlex> + )} + </RightContainer> + )} + </MainContainer> + )} + <BottomContainer> + {mode === "default" ? ( + <BottomLinks hasContent={bottomLinks ? true : false}> {bottomLinks?.map((link, index) => ( <span key={`bottom${index}${link.text}`}> <BottomLink href={link.href} tabIndex={tabIndex}> @@ -198,11 +249,18 @@ const DxcFooter = ({ </span> ))} </BottomLinks> - <Copyright>{copyright ?? translatedLabels.footer.copyrightText(new Date().getFullYear())}</Copyright> - </BottomContainer> - )} + ) : ( + <LogoContainer mode={mode}>{footerLogo}</LogoContainer> + )} + <Copyright>{copyright ?? translatedLabels.footer.copyrightText(new Date().getFullYear())}</Copyright> + </BottomContainer> </FooterContainer> ); }; +const LeftContent = ({ children }: { children: ReactNode }) => <>{children}</>; +const RightContent = ({ children }: { children: ReactNode }) => <>{children}</>; + +DxcFooter.LeftContent = LeftContent; +DxcFooter.RightContent = RightContent; export default DxcFooter; diff --git a/packages/lib/src/footer/Icons.tsx b/packages/lib/src/footer/Icons.tsx index 6eb3b1bf4..a9c5714d4 100644 --- a/packages/lib/src/footer/Icons.tsx +++ b/packages/lib/src/footer/Icons.tsx @@ -5,57 +5,57 @@ export const dxcLogo = ( <path d="M171.5-54.124v12.539h-3.6V-54.124h-4.973v-3.191h13.54v3.191H171.5" transform="translate(-68.528 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M189.96-41.585V-57.315h12.326v3.079h-8.753v3.191h7.7v3.078h-7.7v3.3h8.87v3.078H189.96" transform="translate(-77.56 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M223.558-41.438a8.1,8.1,0,0,1-8.382-8.1v-.045a8.161,8.161,0,0,1,8.522-8.146,8.6,8.6,0,0,1,6.444,2.431l-2.289,2.543a6.133,6.133,0,0,0-4.178-1.778,4.743,4.743,0,0,0-4.738,4.905v.045a4.752,4.752,0,0,0,4.738,4.95,6,6,0,0,0,4.295-1.845l2.288,2.228a8.491,8.491,0,0,1-6.7,2.813" transform="translate(-86.019 65.583)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M254.988-41.585V-47.9h-6.63v6.315h-3.6V-57.315h3.6v6.225h6.63v-6.225h3.594v15.731h-3.594" transform="translate(-95.903 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M285.991-41.585l-7.914-10v10h-3.549V-57.315h3.316l7.657,9.685v-9.685h3.549v15.731h-3.058" transform="translate(-105.869 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M317.2-49.583a4.869,4.869,0,0,0-4.949-4.95,4.793,4.793,0,0,0-4.9,4.905v.045a4.869,4.869,0,0,0,4.949,4.95,4.793,4.793,0,0,0,4.9-4.905Zm-4.949,8.145c-5.043,0-8.661-3.623-8.661-8.1v-.045c0-4.478,3.666-8.146,8.708-8.146s8.66,3.623,8.66,8.1v.045c0,4.477-3.664,8.145-8.708,8.145" transform="translate(-115.631 65.583)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M336.786-41.585V-57.315h3.6v12.584h8.148v3.146H336.786" transform="translate(-126.654 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M372.78-49.583a4.87,4.87,0,0,0-4.949-4.95,4.794,4.794,0,0,0-4.9,4.905v.045a4.869,4.869,0,0,0,4.949,4.95,4.794,4.794,0,0,0,4.9-4.905Zm-4.949,8.145c-5.043,0-8.662-3.623-8.662-8.1v-.045c0-4.478,3.666-8.146,8.708-8.146s8.661,3.623,8.661,8.1v.045c0,4.477-3.666,8.145-8.708,8.145" transform="translate(-135.016 65.583)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M399.735-41.438c-5.09,0-8.592-3.443-8.592-8.1v-.045a8.243,8.243,0,0,1,8.568-8.146,9.18,9.18,0,0,1,6.42,2.16l-2.265,2.634a6.141,6.141,0,0,0-4.272-1.6,4.807,4.807,0,0,0-4.692,4.905v.045a4.8,4.8,0,0,0,4.949,4.995,5.89,5.89,0,0,0,3.384-.945v-2.25h-3.618v-2.992h7.1v6.841a10.837,10.837,0,0,1-6.98,2.5" transform="translate(-145.284 65.583)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M428.664-47.855v6.27h-3.6v-6.2l-6.28-9.528h4.2L426.89-51l3.968-6.315h4.085l-6.28,9.46" transform="translate(-154.162 65.45)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> <path d="M84.218-55.737a10.063,10.063,0,0,1,2.589-4.4,9.792,9.792,0,0,1,6.985-2.77h11.328V-69.3H93.792a17.041,17.041,0,0,0-11.8,4.759,16.344,16.344,0,0,0-3.547,5.115,13.247,13.247,0,0,0-1.122,3.688Zm0,4.877a10.065,10.065,0,0,0,2.589,4.4,9.793,9.793,0,0,0,6.985,2.77h11.328V-37.3H93.792a17.042,17.042,0,0,1-11.8-4.759,16.339,16.339,0,0,1-3.547-5.114,13.251,13.251,0,0,1-1.122-3.688ZM63.1-47.98,54.45-37.3H45.873l12.957-16-12.957-16H54.45L63.1-58.619l8.65-10.68h8.578l-12.957,16,12.957,16H71.749ZM48.875-55.737a13.212,13.212,0,0,0-1.122-3.688,16.359,16.359,0,0,0-3.546-5.115,17.043,17.043,0,0,0-11.8-4.759H21.08v6.393H32.408a9.79,9.79,0,0,1,6.985,2.77,10.072,10.072,0,0,1,2.59,4.4Zm0,4.877a13.215,13.215,0,0,1-1.122,3.688,16.353,16.353,0,0,1-3.546,5.114,17.044,17.044,0,0,1-11.8,4.759H21.08v-6.393H32.408a9.791,9.791,0,0,0,6.985-2.77,10.074,10.074,0,0,0,2.59-4.4h6.892" transform="translate(-21.08 69.298)" - fill="#fff" + fill="var(--color-fg-primary-strong)" /> </g> </svg> diff --git a/packages/lib/src/footer/types.ts b/packages/lib/src/footer/types.ts index 881324c5d..cac55d7f7 100644 --- a/packages/lib/src/footer/types.ts +++ b/packages/lib/src/footer/types.ts @@ -28,10 +28,6 @@ type BottomLink = { }; type Logo = { - /** - * URL to navigate when the logo is clicked. - */ - href?: string; /** * Source of the logo image. */