Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding title attribute to Footer social links #1646

Merged
merged 7 commits into from Jul 11, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/src/date-input/Calendar.tsx
Expand Up @@ -3,7 +3,7 @@ import React, { useState, useMemo, useEffect } from "react";
import styled from "styled-components";
import { CalendarPropsType } from "./types";
import useTranslatedLabels from "../useTranslatedLabels";
import { DxcFlex } from "../main";
import DxcFlex from "../flex/Flex";

const getDays = (innerDate: Dayjs) => {
const monthDayCells = [];
Expand Down
2 changes: 1 addition & 1 deletion lib/src/file-input/FileItem.tsx
@@ -1,6 +1,6 @@
import React from "react";
import styled, { ThemeProvider } from "styled-components";
import { DxcFlex } from "../main";
import DxcFlex from "../flex/Flex";
import useTheme from "../useTheme";
import useTranslatedLabels from "../useTranslatedLabels";
import { FileItemProps } from "./types";
Expand Down
11 changes: 11 additions & 0 deletions lib/src/footer/Footer.stories.tsx
Expand Up @@ -26,6 +26,7 @@ const social = [
</g>
</svg>
),
title: "Linkedin",
},
{
href: "https://twitter.com/dxctechnology",
Expand All @@ -37,6 +38,7 @@ const social = [
/>
</svg>
),
title: "Twitter",
},
{
href: "https://www.facebook.com/DXCTechnology/",
Expand All @@ -63,6 +65,7 @@ const social = [
</g>
</svg>
),
title: "Facebook",
},
];

Expand Down Expand Up @@ -109,6 +112,14 @@ export const Chromatic = () => (
</div>
</DxcFooter>
</ExampleContainer>
<ExampleContainer pseudoState="pseudo-focus">
<Title title="Focused bottom and social links" theme="light" level={4} />
<DxcFooter copyright="Copyright" socialLinks={social} bottomLinks={bottom}>
<div>
<a href="https://www.linkedin.com/company/dxctechnology">Linkedin</a>
</div>
</DxcFooter>
</ExampleContainer>
<Title title="Margins" theme="light" level={2} />
<ExampleContainer>
<Title title="Xxsmall margin" theme="light" level={4} />
Expand Down
2 changes: 2 additions & 0 deletions lib/src/footer/Footer.test.js
Expand Up @@ -6,6 +6,7 @@ const social = [
{
href: "https://www.test.com/social",
logo: "https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/images/icon-and-image-large-icon-settings_2x.png",
title: "test",
},
];
const bottom = [
Expand Down Expand Up @@ -72,6 +73,7 @@ describe("Footer component tests", () => {
);
const socialIcon = getAllByRole("link")[0];
expect(socialIcon.getAttribute("href")).toBe("https://www.test.com/social");
expect(socialIcon.getAttribute("aria-label")).toBe("test");
const bottomLink = getByText("bottom-link-text");
expect(bottomLink.getAttribute("href")).toBe("https://www.test.com/bottom");
expect(getByText("test-copyright")).toBeTruthy();
Expand Down
183 changes: 85 additions & 98 deletions lib/src/footer/Footer.tsx
Expand Up @@ -6,6 +6,7 @@ import useTranslatedLabels from "../useTranslatedLabels";
import { BackgroundColorProvider } from "../BackgroundColorContext";
import { dxcLogo } from "./Icons";
import FooterPropsType from "./types";
import DxcFlex from "../flex/Flex";

const DxcFooter = ({
socialLinks,
Expand All @@ -23,89 +24,79 @@ const DxcFooter = ({
return dxcLogo;
}
if (typeof colorsTheme.footer.logo === "string") {
return <LogoImg alt={translatedLabels.formFields.logoAlternativeText} src={colorsTheme.footer.logo}></LogoImg>;
return <LogoImg alt={translatedLabels.formFields.logoAlternativeText} src={colorsTheme.footer.logo} />;
}
return colorsTheme.footer.logo;
}, [colorsTheme.footer.logo]);

const socialLink = socialLinks?.map((link, index) => (
<SocialAnchor
tabIndex={tabIndex}
key={`social${index}${link.href}`}
index={index}
href={link && link.href ? link.href : ""}
>
<SocialIconContainer>
{typeof link.logo === "string" ? <SocialIconImg src={link.logo} /> : link.logo}
</SocialIconContainer>
</SocialAnchor>
));

const bottomLink = bottomLinks?.map((link, index) => (
<span key={`bottom${index}${link.text}`}>
<BottomLink tabIndex={tabIndex} href={link && link.href ? link.href : ""}>
{link && link.text ? link.text : ""}
</BottomLink>
<Point>·</Point>
</span>
));
}, [colorsTheme]);

return (
<ThemeProvider theme={colorsTheme.footer}>
<FooterContainer margin={margin}>
<FooterHeader>
<DxcFlex justifyContent="space-between" alignItems="center" wrap="wrap" gap="1.5rem">
<LogoContainer>{footerLogo}</LogoContainer>
<SocialLinkContainer>{socialLink}</SocialLinkContainer>
</FooterHeader>
<div>
<ChildComponents>
<BackgroundColorProvider color={colorsTheme.footer.backgroundColor}>{children}</BackgroundColorProvider>
</ChildComponents>
<FooterFooter className="footerFooter">
<BottomLinks>{bottomLink}</BottomLinks>
<Copyright>{copyright || translatedLabels.footer.copyrightText(new Date().getFullYear())}</Copyright>
</FooterFooter>
</div>
<DxcFlex>
{socialLinks?.map((link, index) => (
<SocialAnchor
href={link.href}
tabIndex={tabIndex}
title={link.title}
aria-label={link.title}
key={`social${index}${link.href}`}
index={index}
>
<SocialIconContainer>
{typeof link.logo === "string" ? <img src={link.logo} /> : link.logo}
</SocialIconContainer>
</SocialAnchor>
))}
</DxcFlex>
</DxcFlex>
<ChildComponents>
<BackgroundColorProvider color={colorsTheme.footer.backgroundColor}>{children}</BackgroundColorProvider>
</ChildComponents>
<BottomContainer>
<BottomLinks>
{bottomLinks?.map((link, index) => (
<span key={`bottom${index}${link.text}`}>
<BottomLink href={link.href} tabIndex={tabIndex}>
{link.text}
</BottomLink>
</span>
))}
</BottomLinks>
<Copyright>{copyright || translatedLabels.footer.copyrightText(new Date().getFullYear())}</Copyright>
</BottomContainer>
</FooterContainer>
</ThemeProvider>
);
};

const FooterContainer = styled.footer<{ margin: FooterPropsType["margin"] }>`
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
min-height: ${(props) => props.theme.height};
margin-top: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")};
background-color: ${(props) => props.theme.backgroundColor};

@media (min-width: ${responsiveSizes.small}rem) {
padding: 24px 36px 24px 36px;
}

@media (max-width: ${responsiveSizes.small}rem) {
padding: 20px;
}

background-color: ${(props) => props.theme.backgroundColor};
margin-top: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")};
width: 100%;
box-sizing: border-box;
min-height: ${(props) => props.theme.height};
display: flex;
flex-direction: column;
justify-content: space-between;
`;

const FooterHeader = styled.div`
display: flex;
justify-content: space-between;
flex-wrap: wrap;
row-gap: 24px;
`;

const FooterFooter = styled.div`
const BottomContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: flex-end;

@media (min-width: ${responsiveSizes.small}rem) {
flex-direction: row;
}

@media (max-width: ${responsiveSizes.small}rem) {
flex-direction: column;
align-items: center;
Expand All @@ -116,32 +107,13 @@ const FooterFooter = styled.div`
margin-top: 16px;
`;

const BottomLinks = styled.div`
padding-top: ${(props) => props.theme.bottomLinksDividerSpacing};
display: inline-flex;
flex-wrap: wrap;

@media (min-width: ${responsiveSizes.small}rem) {
max-width: 60%;
}

@media (max-width: ${responsiveSizes.small}rem) {
max-width: 100%;
width: 100%;
}

& > span:last-child span {
display: none;
}
align-self: center;
`;

const ChildComponents = styled.div`
min-height: 16px;
overflow: hidden;
`;

const Copyright = styled.div`
padding-top: ${(props) => props.theme.bottomLinksDividerSpacing};
font-family: ${(props) => props.theme.copyrightFontFamily};
font-size: ${(props) => props.theme.copyrightFontSize};
font-style: ${(props) => props.theme.copyrightFontStyle};
Expand All @@ -158,11 +130,9 @@ const Copyright = styled.div`
width: 100%;
text-align: left;
}

padding-top: ${(props) => props.theme.bottomLinksDividerSpacing};
`;

const LogoContainer = styled.div`
const LogoContainer = styled.span`
max-height: ${(props) => props.theme.logoHeight};
width: ${(props) => props.theme.logoWidth};
`;
Expand All @@ -172,39 +142,51 @@ const LogoImg = styled.img`
width: ${(props) => props.theme.logoWidth};
`;

const SocialLinkContainer = styled.div`
display: flex;
align-self: center;
`;

const SocialAnchor = styled.a<{ index: number }>`
& {
display: inline-flex;
margin-left: ${(props) => (props.index === 0 ? "0px" : props.theme.socialLinksGutter)};
display: inline-flex;
margin-left: ${(props) => (props.index === 0 ? "0px" : props.theme.socialLinksGutter)};
border-radius: 4px;

&:focus {
outline: 2px solid #0095ff;
outline-offset: 2px;
}
`;

const SocialIconImg = styled.img``;

const SocialIconContainer = styled.div`
& {
display: inline-flex;
height: ${(props) => props.theme.socialLinksSize};
width: ${(props) => props.theme.socialLinksSize};
color: ${(props) => props.theme.socialLinksColor};
}

display: flex;
align-items: center;
height: ${(props) => props.theme.socialLinksSize};
width: ${(props) => props.theme.socialLinksSize};
color: ${(props) => props.theme.socialLinksColor};
overflow: hidden;

img,
svg {
height: 100%;
width: 100%;
}
`;

const Point = styled.span`
margin: 0px 10px;
color: ${(props) => props.theme.bottomLinksFontColor};
const BottomLinks = styled.div`
display: inline-flex;
flex-wrap: wrap;
align-self: center;
padding-top: ${(props) => props.theme.bottomLinksDividerSpacing};
color: #fff;

@media (min-width: ${responsiveSizes.small}rem) {
max-width: 60%;
}
@media (max-width: ${responsiveSizes.small}rem) {
max-width: 100%;
width: 100%;
}

& > span:not(:first-child):before {
content: "·";
padding: 0 0.5rem;
}
`;

const BottomLink = styled.a`
Expand All @@ -214,6 +196,11 @@ const BottomLink = styled.a`
font-size: ${(props) => props.theme.bottomLinksFontSize};
font-style: ${(props) => props.theme.bottomLinksFontStyle};
font-weight: ${(props) => props.theme.bottomLinksFontWeight};
border-radius: 2px;

&:focus {
outline: 2px solid #0095ff;
}
`;

export default DxcFooter;
17 changes: 11 additions & 6 deletions lib/src/footer/types.ts
Expand Up @@ -8,24 +8,29 @@ type Size = {
type SVG = React.ReactNode & React.SVGProps<SVGSVGElement>;

type SocialLink = {
/**
* URL of the page the link goes to.
*/
href: string;
/**
* Element used as the icon for the link.
*/
logo: string | SVG;
/**
* URL of the page the link goes to.
* Value for the HTML properties title and aria-label.
*/
href: string;
title: string;
};

type BottomLink = {
/**
* Text for the link.
*/
text: string;
/**
* URL of the page the link goes to.
*/
href: string;
/**
* Text for the link.
*/
text: string;
};

type FooterPropsType = {
Expand Down
3 changes: 3 additions & 0 deletions lib/src/layout/ApplicationLayout.tsx
Expand Up @@ -34,14 +34,17 @@ const defaultFooter = () => (
{
href: "https://www.linkedin.com/company/dxctechnology",
logo: linkedinLogo,
title: "Linkedin",
},
{
href: "https://twitter.com/dxctechnology",
logo: twitterLogo,
title: "Twitter",
},
{
href: "https://www.facebook.com/DXCTechnology/",
logo: facebookLogo,
title: "Facebook",
},
]}
/>
Expand Down