Skip to content
Merged
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
24 changes: 24 additions & 0 deletions apps/website/screens/components/footer/code/FooterCodePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ const sections = [
<TableCode>0</TableCode>
</td>
</tr>
<tr>
<td>variant</td>
Comment thread
Jialecl marked this conversation as resolved.
<td>
<TableCode>'branded' | 'neutral'</TableCode>
</td>
<td>
The available footer variants:
<ul>
<li>
<strong>branded</strong>: Footer with branded styling, using the primary brand background and
contrasting content colors.
</li>
<li>
<strong>neutral</strong>: Footer with neutral styling, using a neutral background and content colors
instead of the branded treatment.
</li>
</ul>
Changing the variant only changes the footer's visual styling; its layout, content, and behavior remain
the same.
</td>
<td>
<TableCode>'branded'</TableCode>
</td>
</tr>
</tbody>
</DxcTable>
),
Expand Down
37 changes: 29 additions & 8 deletions packages/lib/src/footer/Footer.stories.tsx
Comment thread
Jialecl marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,20 @@ const bottomLong = [
},
];

const Footer = () => (
const FooterExamples = ({ variant }: { variant?: "branded" | "neutral" }) => (
<>
<ExampleContainer>
<Title title="Default" theme="light" level={4} />
<DxcFooter />
<DxcFooter variant={variant} />
</ExampleContainer>
<ExampleContainer>
<Title title="With custom logo" theme="light" level={4} />
<DxcFooter logo={{ src: woodenDockImage, alt: "Custom logo" }} />
<DxcFooter variant={variant} logo={{ src: woodenDockImage, alt: "Custom logo" }} />
</ExampleContainer>
<ExampleContainer>
<Title title="With children, copyright, bottom links and social links" theme="light" level={4} />
<DxcFooter
variant={variant}
socialLinks={social}
bottomLinks={bottom}
leftContent={
Expand Down Expand Up @@ -248,6 +249,7 @@ const Footer = () => (
<ExampleContainer>
<Title title="With long content" theme="light" level={4} />
<DxcFooter
variant={variant}
socialLinks={social}
bottomLinks={bottomLong}
copyright="This is a long copyright text, this is a long copyright text, this is a long copyright text, this is a long copyright text, this is a long copyright text, this is a long copyright text, this is a long copyright text."
Expand Down Expand Up @@ -341,6 +343,7 @@ const Footer = () => (
<ExampleContainer>
<Title title="With children, copyright, bottom links and social links from material" theme="light" level={4} />
<DxcFooter
variant={variant}
copyright="Copyright"
socialLinks={socialMaterialIcons}
bottomLinks={bottom}
Expand Down Expand Up @@ -381,6 +384,7 @@ const Footer = () => (
<ExampleContainer pseudoState="pseudo-focus">
<Title title="Focused bottom and social links" theme="light" level={4} />
<DxcFooter
variant={variant}
copyright="Copyright"
socialLinks={social}
bottomLinks={bottom}
Expand Down Expand Up @@ -420,11 +424,11 @@ const Footer = () => (
</ExampleContainer>
<ExampleContainer>
<Title title="Reduced" theme="light" level={4} />
<DxcFooter mode="reduced" />
<DxcFooter variant={variant} mode="reduced" />
</ExampleContainer>
<ExampleContainer>
<Title title="Reduced with custom logo" theme="light" level={4} />
<DxcFooter mode="reduced" logo={{ src: woodenDockImage, alt: "Custom logo" }} />
<DxcFooter variant={variant} mode="reduced" logo={{ src: woodenDockImage, alt: "Custom logo" }} />
</ExampleContainer>
<ExampleContainer>
<Title title="Themed footer" theme="light" level={4} />
Expand All @@ -436,14 +440,27 @@ const Footer = () => (
},
}}
>
<DxcFooter />
<DxcFooter mode="reduced" />
<DxcFooter logo={{ src: woodenDockImage, alt: "Custom logo" }} />
<DxcFlex direction="column" gap="var(--spacing-gap-xl)">
<DxcFooter variant={variant} />
<DxcFooter variant={variant} mode="reduced" />
<DxcFooter variant={variant} logo={{ src: woodenDockImage, alt: "Custom logo" }} />
</DxcFlex>
</HalstackProvider>
</ExampleContainer>
</>
);

const Footer = () => (
<>
<Title title="Default" theme="light" level={3} />
<FooterExamples />
<Title title="Neutral" theme="light" level={3} />
<FooterExamples variant="neutral" />
</>
);

const NeutralFooter = () => <FooterExamples variant="neutral" />;

const dxcLogo = (
<svg xmlns="http://www.w3.org/2000/svg" width="73" height="40" viewBox="0 0 73 40">
<title>DXC Logo</title>
Expand Down Expand Up @@ -667,6 +684,10 @@ export const Chromatic: Story = {
render: Footer,
};

export const Neutral: Story = {
render: NeutralFooter,
};

export const Responsive: Story = {
render: Footer,
parameters: {
Expand Down
14 changes: 9 additions & 5 deletions packages/lib/src/footer/Footer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ describe("Footer component tests", () => {
const { getByTitle } = render(<DxcFooter />);
expect(getByTitle("DXC Logo")).toBeTruthy();
});
test("Footer renders the reduced neutral logo in black", () => {
const { container } = render(<DxcFooter mode="reduced" variant="neutral" />);
expect(container.querySelector("svg path")?.getAttribute("fill")).toBe("#0E1020");
});
test("Footer renders with social links", () => {
const { getByRole } = render(<DxcFooter socialLinks={social} />);
const socialIcon = getByRole("link");
Expand Down Expand Up @@ -109,11 +113,11 @@ describe("Footer component tests", () => {
});

describe("getContrastColor function", () => {
test("should return black color for light backgrounds", () => {
expect(getContrastColor("#FFFFFF")).toBe("var(--color-fg-neutral-dark)");
expect(getContrastColor("#F5F5F5")).toBe("var(--color-fg-neutral-dark)");
expect(getContrastColor("rgb(255, 255, 255)")).toBe("var(--color-fg-neutral-dark)");
expect(getContrastColor("rgb(245, 245, 245)")).toBe("var(--color-fg-neutral-dark)");
test("should return primary stronger for light backgrounds", () => {
expect(getContrastColor("#FFFFFF")).toBe("var(--color-fg-primary-stronger)");
expect(getContrastColor("#F5F5F5")).toBe("var(--color-fg-primary-stronger)");
expect(getContrastColor("rgb(255, 255, 255)")).toBe("var(--color-fg-primary-stronger)");
expect(getContrastColor("rgb(245, 245, 245)")).toBe("var(--color-fg-primary-stronger)");
});

test("should return white color for dark backgrounds", () => {
Expand Down
12 changes: 7 additions & 5 deletions packages/lib/src/footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,14 @@ const SocialIconContainer = styled.div`
}
`;

const BottomContainer = styled.div<{ textColor: string; width: number }>`
const BottomContainer = styled.div<{ textColor: string; width: number; variant: FooterPropsType["variant"] }>`
width: 100%;
min-height: var(--height-xl);
display: grid;
grid-template-columns: 60% var(--spacing-gap-ml) 1fr;
align-items: center;
background-color: var(--color-bg-primary-strong);
background-color: ${({ variant }) => (variant === "branded" ? "var(--color-bg-primary-strong)" : "var(--color-bg-primary-lightest)")};
border-top: ${({ variant }) => (variant === "branded" ? "" : "var(--border-width-s) var(--border-style-default) var(--border-color-primary-stronger)")};
color: ${({ textColor }) => textColor};
padding: var(--spacing-padding-none) var(--spacing-padding-xl);
box-sizing: border-box;
Expand Down Expand Up @@ -213,6 +214,7 @@ const DxcFooter = ({
mode = "default",
rightContent,
socialLinks,
variant = "branded",
tabIndex = 0,
}: FooterPropsType): JSX.Element => {
const translatedLabels = use(HalstackLanguageContext).labels;
Expand All @@ -233,10 +235,10 @@ const DxcFooter = ({
) : themedLogos?.footerReducedLogo ? (
<LogoImg mode={mode} alt={"Footer logo"} src={themedLogos.footerReducedLogo} title={"Footer logo"} />
) : (
dxcSmallLogo
dxcSmallLogo(variant === "neutral" ? "#0E1020" : undefined)
);
}
}, [mode, logo, themedLogos]);
}, [mode, logo, themedLogos, variant]);

const footerRef = useRef<HTMLDivElement>(null);
const width = useWidth(footerRef);
Expand Down Expand Up @@ -285,7 +287,7 @@ const DxcFooter = ({
)}
</MainContainer>
)}
<BottomContainer ref={bottomContainerRef} textColor={textColor} width={width}>
<BottomContainer ref={bottomContainerRef} variant={variant} textColor={textColor} width={width}>
{mode === "default" && bottomLinks && (
<BottomLinks textColor={textColor} width={width}>
{bottomLinks?.map((link, index) => (
Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/footer/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ export const dxcLogo = (
</svg>
);

export const dxcSmallLogo = (
export const dxcSmallLogo = (color = "#F6F3F0") => (
<svg xmlns="http://www.w3.org/2000/svg" width="57" height="16" viewBox="0 0 57 16" fill="none">
<path
d="M14.585 4.05054C16.7623 4.05054 18.5344 5.82924 18.5345 8.01646C18.5345 10.2037 16.7623 11.9823 14.585 11.9823H4.04297V10.3637H14.585C15.8752 10.3637 16.9251 9.31046 16.9251 8.01646C16.9251 6.72239 15.8752 5.6693 14.585 5.6693H4.04297V4.05054H14.585ZM52.8906 5.66923H42.3486C41.0584 5.66923 40.0085 6.72239 40.0085 8.01646C40.0085 9.31046 41.0584 10.3636 42.3486 10.3636H52.8906V11.9823H42.3486C40.1704 11.9823 38.3992 10.2036 38.3991 8.01646C38.3991 5.82924 40.1714 4.05048 42.3486 4.05048H52.8906V5.66923ZM36.858 5.66923C35.1351 5.66924 33.9253 6.43576 32.6444 7.24706C32.2289 7.51079 31.8077 7.77646 31.3684 8.01359C31.8076 8.25066 32.2289 8.51626 32.6444 8.78006C33.9253 9.59132 35.1351 10.3579 36.858 10.3579V11.9766C34.6703 11.9766 33.1386 11.0063 31.7868 10.1503C30.6631 9.43899 29.6928 8.82386 28.5038 8.82386C27.3147 8.82386 26.3444 9.43806 25.2207 10.1503C23.8689 11.0063 22.3372 11.9766 20.1495 11.9766V10.3579C21.8724 10.3579 23.0822 9.59132 24.3631 8.78006C24.7786 8.51626 25.2 8.25066 25.6392 8.01359C25.2 7.77646 24.7786 7.51079 24.3631 7.24706C23.0822 6.43576 21.8724 5.66923 20.1495 5.66923V4.05048C22.3372 4.05048 23.8689 5.02078 25.2207 5.87776C26.3444 6.58904 27.3147 7.20419 28.5038 7.20419V7.20319C29.6928 7.20319 30.6631 6.58908 31.7868 5.87684C33.1386 5.02082 34.6703 4.05049 36.858 4.05048V5.66923Z"
fill="#F6F3F0"
fill={color}
/>
</svg>
);
4 changes: 4 additions & 0 deletions packages/lib/src/footer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ type FooterPropsType = {
* inside the leftContent and rightContent.
*/
tabIndex?: number;
/**
* Visual variant of the footer.
*/
variant?: "branded" | "neutral";
};

export default FooterPropsType;
2 changes: 1 addition & 1 deletion packages/lib/src/footer/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function getLuminance(color: string): number {

export const getContrastColor = (bgColor: string) => {
const luminance = getLuminance(bgColor);
return luminance > 0.179 ? "var(--color-fg-neutral-dark)" : "var(--color-fg-neutral-bright)";
return luminance > 0.179 ? "var(--color-fg-primary-stronger)" : "var(--color-fg-neutral-bright)";
};

export const getResponsiveStyles = {
Expand Down
Loading