From cf796328650123ac61c32fd2a28d493e46140605 Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso Date: Thu, 23 Oct 2025 20:10:22 +0200 Subject: [PATCH 1/3] First approach to the new footer component --- packages/lib/src/footer/Footer.stories.tsx | 5 +- packages/lib/src/footer/Footer.tsx | 129 +++++++++++++-------- packages/lib/src/footer/Icons.tsx | 44 +++---- 3 files changed, 108 insertions(+), 70 deletions(-) diff --git a/packages/lib/src/footer/Footer.stories.tsx b/packages/lib/src/footer/Footer.stories.tsx index ea1e2bfb37..462412ae94 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 42019cc088..e33b69158e 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,19 +12,12 @@ 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); } @@ -33,10 +26,18 @@ const FooterContainer = styled.footer<{ } `; +const MainContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + min-height: 80px; +`; + const BottomContainer = styled.div` display: flex; justify-content: space-between; - align-items: flex-end; + align-items: center; @media (min-width: ${responsiveSizes.small}rem) { flex-direction: row; @@ -45,18 +46,33 @@ const BottomContainer = styled.div` flex-direction: column; align-items: center; } + width: 100%; + height: var(--height-xl); + background-color: var(--color-bg-primary-strong); + padding: var(--spacing-padding-none) var(--spacing-padding-xl); + box-sizing: border-box; +`; - border-top: var(--border-width-s) var(--border-style-default) var(--border-color-primary-medium); - margin-top: var(--spacing-gap-m); +const LeftContainer = styled.div` + display: flex; + flex-direction: column; + gap: var(--spacing-gap-ml); + max-width: 33.3%; + height: 100%; + color: var(--color-fg-neutral-dark); + padding: var(--spacing-padding-l) var(--spacing-padding-xl); `; -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); + max-width: 66.66%; + height: 100%; + 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,7 +112,7 @@ 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); @@ -110,8 +126,7 @@ const BottomLinks = styled.div` display: inline-flex; flex-wrap: wrap; align-self: center; - margin-top: var(--spacing-padding-xs); - color: var(--color-fg-neutral-bright); + color: var(--color-fg-neutral-dark); @media (min-width: ${responsiveSizes.small}rem) { max-width: 60%; @@ -148,10 +163,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,36 +177,46 @@ 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> + <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> {bottomLinks?.map((link, index) => ( <span key={`bottom${index}${link.text}`}> @@ -198,11 +226,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 6eb3b1bf42..88562bef81 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> @@ -68,57 +68,57 @@ export const dxcSmallLogo = ( <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="white" /> <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="white" /> <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="white" /> <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="white" /> <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="white" /> <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="white" /> <path d="M336.786-41.585V-57.315h3.6v12.584h8.148v3.146H336.786" transform="translate(-126.654 65.45)" - fill="#fff" + fill="white" /> <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="white" /> <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="white" /> <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="white" /> <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="white" /> </g> </svg> From e7799ce303382c55d84b9fde500dad04158b8ac8 Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso <pfelguerosogalguera@gmail.com> Date: Fri, 31 Oct 2025 10:18:46 +0100 Subject: [PATCH 2/3] Refactor utility functions to provide default values for color, background, size, font size, icon size, border width, outline width, and mode color. --- packages/lib/src/avatar/utils.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/lib/src/avatar/utils.ts b/packages/lib/src/avatar/utils.ts index 9040621285..f47bc79adb 100644 --- a/packages/lib/src/avatar/utils.ts +++ b/packages/lib/src/avatar/utils.ts @@ -97,9 +97,11 @@ const modeColorMap = { error: "var(--color-fg-error-medium)", }; -export const getColor = (color: AvatarPropsType["color"]) => (color ? contextualColorMap[color].text : undefined); +export const getColor = (color: AvatarPropsType["color"]) => + color && contextualColorMap[color] ? contextualColorMap[color].text : contextualColorMap.neutral.text; + export const getBackgroundColor = (color: AvatarPropsType["color"]) => - color ? contextualColorMap[color].background : undefined; + color && contextualColorMap[color] ? contextualColorMap[color].background : contextualColorMap.neutral.background; export const getBorderRadius = (shape: AvatarPropsType["shape"], size: AvatarPropsType["size"]) => { if (shape === "circle") { @@ -111,20 +113,22 @@ export const getBorderRadius = (shape: AvatarPropsType["shape"], size: AvatarPro return "100%"; }; -export const getSize = (size: AvatarPropsType["size"]) => (size ? sizeMap[size] : "var(--height-xl)"); +export const getSize = (size: AvatarPropsType["size"]) => (size && sizeMap[size] ? sizeMap[size] : "var(--height-xl)"); -export const getFontSize = (size: AvatarPropsType["size"]) => (size ? fontSizeMap[size] : "var(--typography-label-l)"); +export const getFontSize = (size: AvatarPropsType["size"]) => + size && fontSizeMap[size] ? fontSizeMap[size] : "var(--typography-label-l)"; -export const getIconSize = (size: AvatarPropsType["size"]) => (size ? iconSizeMap[size] : "var(--height-s)"); +export const getIconSize = (size: AvatarPropsType["size"]) => + size && iconSizeMap[size] ? iconSizeMap[size] : "var(--height-s)"; export const getBorderWidth = (size: AvatarPropsType["size"]) => - size ? borderWidthMap[size] : "var(--border-width-s)"; + size && borderWidthMap[size] ? borderWidthMap[size] : "var(--border-width-s)"; export const getOutlineWidth = (size: AvatarPropsType["size"]) => - size ? outlineWidthMap[size] : "var(--border-width-m)"; + size && outlineWidthMap[size] ? outlineWidthMap[size] : "var(--border-width-m)"; export const getModeColor = (mode: Required<AvatarPropsType>["status"]["mode"]) => - mode ? modeColorMap[mode] : "var(--color-fg-neutral-strong)"; + mode && modeColorMap[mode] ? modeColorMap[mode] : "var(--color-fg-neutral-strong)"; export const getInitials = (label?: string): string => { if (!label) return ""; From 180297005604b0a6c0a0fddfb2c1e39244661a8a Mon Sep 17 00:00:00 2001 From: PelayoFelgueroso <pfelguerosogalguera@gmail.com> Date: Fri, 31 Oct 2025 10:29:09 +0100 Subject: [PATCH 3/3] Remove unwanted changes --- packages/lib/src/footer/Footer.stories.tsx | 5 +- packages/lib/src/footer/Footer.tsx | 129 ++++++++------------- packages/lib/src/footer/Icons.tsx | 44 +++---- 3 files changed, 70 insertions(+), 108 deletions(-) diff --git a/packages/lib/src/footer/Footer.stories.tsx b/packages/lib/src/footer/Footer.stories.tsx index 462412ae94..ea1e2bfb37 100644 --- a/packages/lib/src/footer/Footer.stories.tsx +++ b/packages/lib/src/footer/Footer.stories.tsx @@ -131,10 +131,7 @@ const Footer = () => ( <> <ExampleContainer> <Title title="Default" theme="light" level={4} /> - <DxcFooter> - <DxcFooter.LeftContent>Holaaa</DxcFooter.LeftContent> - <DxcFooter.RightContent>Hellooo</DxcFooter.RightContent> - </DxcFooter> + <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 e33b69158e..42019cc088 100644 --- a/packages/lib/src/footer/Footer.tsx +++ b/packages/lib/src/footer/Footer.tsx @@ -1,4 +1,4 @@ -import { ElementType, ReactNode, useContext, Children, isValidElement } from "react"; +import { useContext } from "react"; import styled from "@emotion/styled"; import { responsiveSizes, spaces } from "../common/variables"; import DxcFlex from "../flex/Flex"; @@ -12,12 +12,19 @@ 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); } @@ -26,18 +33,10 @@ const FooterContainer = styled.footer<{ } `; -const MainContainer = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - min-height: 80px; -`; - const BottomContainer = styled.div` display: flex; justify-content: space-between; - align-items: center; + align-items: flex-end; @media (min-width: ${responsiveSizes.small}rem) { flex-direction: row; @@ -46,33 +45,18 @@ const BottomContainer = styled.div` flex-direction: column; align-items: center; } - width: 100%; - height: var(--height-xl); - background-color: var(--color-bg-primary-strong); - padding: var(--spacing-padding-none) var(--spacing-padding-xl); - box-sizing: border-box; -`; -const LeftContainer = styled.div` - display: flex; - flex-direction: column; - gap: var(--spacing-gap-ml); - max-width: 33.3%; - height: 100%; - color: var(--color-fg-neutral-dark); - padding: var(--spacing-padding-l) var(--spacing-padding-xl); + border-top: var(--border-width-s) var(--border-style-default) var(--border-color-primary-medium); + margin-top: var(--spacing-gap-m); `; -const RightContainer = styled.div` - display: flex; - justify-content: flex-end; - gap: var(--spacing-gap-xl); - max-width: 66.66%; - height: 100%; - padding: var(--spacing-padding-l) var(--spacing-padding-xl); +const ChildComponents = styled.div` + min-height: var(--height-xxs); + color: var(--color-fg-neutral-bright); `; 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); @@ -112,7 +96,7 @@ const SocialAnchor = styled.a<{ index: number }>` const SocialIconContainer = styled.div` display: flex; align-items: center; - color: var(--color-fg-primary-strong); + color: var(--color-fg-neutral-bright); overflow: hidden; font-size: var(--height-s); @@ -126,7 +110,8 @@ const BottomLinks = styled.div` display: inline-flex; flex-wrap: wrap; align-self: center; - color: var(--color-fg-neutral-dark); + margin-top: var(--spacing-padding-xs); + color: var(--color-fg-neutral-bright); @media (min-width: ${responsiveSizes.small}rem) { max-width: 60%; @@ -163,13 +148,10 @@ 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, - copyright, children, + copyright, logo, margin, mode = "default", @@ -177,46 +159,36 @@ 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" && ( - <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" ? ( + <BottomContainer> <BottomLinks> {bottomLinks?.map((link, index) => ( <span key={`bottom${index}${link.text}`}> @@ -226,18 +198,11 @@ const DxcFooter = ({ </span> ))} </BottomLinks> - ) : ( - <LogoContainer mode={mode}>{footerLogo}</LogoContainer> - )} - <Copyright>{copyright ?? translatedLabels.footer.copyrightText(new Date().getFullYear())}</Copyright> - </BottomContainer> + <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 88562bef81..6eb3b1bf42 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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <path d="M336.786-41.585V-57.315h3.6v12.584h8.148v3.146H336.786" transform="translate(-126.654 65.45)" - fill="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> <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="var(--color-fg-primary-strong)" + fill="#fff" /> </g> </svg> @@ -68,57 +68,57 @@ export const dxcSmallLogo = ( <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <path d="M336.786-41.585V-57.315h3.6v12.584h8.148v3.146H336.786" transform="translate(-126.654 65.45)" - fill="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> <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="white" + fill="#fff" /> </g> </svg>