Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 19 additions & 3 deletions apps/website/screens/components/footer/code/FooterCodePage.tsx
Original file line number Diff line number Diff line change
@@ -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;
}`;
Expand Down Expand Up @@ -75,7 +74,7 @@ const sections = [
<ExtendedTableCode>{logoTypeString}</ExtendedTableCode>
</td>
</td>
<td>Logo to be displayed inside the header.</td>
<td>Logo to be displayed inside the footer.</td>
<td>-</td>
</tr>
<tr>
Expand Down Expand Up @@ -158,6 +157,23 @@ const sections = [
</DxcTable>
),
},
{
title: "DxcFooter.LeftContent",
content: (
<DxcParagraph>
This compound will be used to display the content on the Left Container under the Logo.
</DxcParagraph>
),
},
{
title: "DxcFooter.RigthContent",
content: (
<DxcParagraph>
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.
</DxcParagraph>
),
},
{
title: "Examples",
subSections: [
Expand Down
5 changes: 4 additions & 1 deletion packages/lib/src/footer/Footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ const Footer = () => (
<>
<ExampleContainer>
<Title title="Default" theme="light" level={4} />
<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} />
Expand Down
166 changes: 112 additions & 54 deletions packages/lib/src/footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand All @@ -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);
Expand All @@ -148,48 +186,61 @@ 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",
socialLinks,
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}>
Expand All @@ -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;
22 changes: 11 additions & 11 deletions packages/lib/src/footer/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Loading
Loading