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

feat: Implement page footer with USWDS components #1285

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a014680
initial commit
snmln Dec 3, 2024
4e4fef7
adding outstanding footer imports
snmln Dec 3, 2024
7f300ea
pushing up initial slim work
snmln Dec 4, 2024
545697e
Move uswds footer behind feature flag
AliceR Dec 5, 2024
6f58910
Disable eslint to not warn, explanation in comment
AliceR Dec 5, 2024
f838337
Move Connections component behind the same FF
AliceR Dec 5, 2024
9f059df
Hide new USWDS footer behind feature flag (#1287)
snmln Dec 5, 2024
e856157
usa foot implementation
snmln Dec 5, 2024
a82d132
Merge branch 'main' into 1135-Refactor-Layout-Components-Footer
AliceR Dec 9, 2024
65dacea
adding uswds style infrastructure
snmln Dec 9, 2024
1aafd0c
Merge branch '1135-Refactor-Layout-Components-Footer' into 1135-slim-…
snmln Dec 9, 2024
18f0173
implementing styling and creating interface
snmln Dec 9, 2024
60398ed
wiring up config
snmln Dec 9, 2024
a5b4502
correcting styles
snmln Dec 10, 2024
c47e331
Merge branch '1135-Refactor-Layout-Components-Footer' into 1135-slim-…
snmln Dec 10, 2024
e629882
correct ts and lint errors
snmln Dec 10, 2024
a7a91ec
correctin merge conflict issues.
snmln Dec 10, 2024
d0a4cd4
updating styles
snmln Dec 10, 2024
59dd97e
dialing in css
snmln Dec 10, 2024
4bdf994
refactor: 1135 slim footer (#1308)
snmln Dec 10, 2024
e2afeed
Fix hideFooter prop name
AliceR Dec 11, 2024
9f4a2fd
Add back comments to .env
AliceR Dec 11, 2024
fe545d4
Remove duplicated styles
AliceR Dec 11, 2024
f224268
wiring up menu items
snmln Dec 11, 2024
02e5b61
fix: hideFooter prop name, small cleanup (#1315)
AliceR Dec 12, 2024
89a9421
fix: svg logo to not require css styles
AliceR Dec 11, 2024
0755ef6
Pass svg logo as prop to footer
AliceR Dec 12, 2024
4e3a21a
fix: svg logo (#1316)
AliceR Dec 12, 2024
2d175f1
adding comment in createDynamicNavMenuList
snmln Dec 12, 2024
6bf3149
wirign up dynamic link creation
snmln Dec 12, 2024
bb5dcad
Merge branch '1135-Refactor-Layout-Components-Footer' into 1135-wirin…
snmln Dec 12, 2024
886912e
cleaning up veda.config and styling
snmln Dec 13, 2024
8c3c769
fix: 1135 wiring up veda config (#1320)
AliceR Dec 16, 2024
d830c03
Add comments to .env
AliceR Dec 16, 2024
5089c7e
Revert "Add comments to .env"
AliceR Dec 16, 2024
98fd9ed
Merge remote-tracking branch 'origin' into 1135-Refactor-Layout-Compo…
AliceR Dec 16, 2024
c7846f8
Remove TODO as completed
AliceR Dec 16, 2024
fc7d58e
Add page footer to exported components
AliceR Dec 16, 2024
75f6fd3
createing jest tests
snmln Dec 16, 2024
d72afea
correcting test
snmln Dec 16, 2024
d43dccc
fix:1335 creating footer test suite (#1330)
AliceR Dec 17, 2024
a9fd5ce
Add secondary footer content to footer config
AliceR Dec 17, 2024
e039620
fix: Add secondary footer content to footer config (#1331)
snmln Dec 17, 2024
c13d9c1
Merge branch 'main' into 1135-Refactor-Layout-Components-Footer
AliceR Dec 19, 2024
13c9cb9
Update color mappings, use system token instead of theme token
AliceR Dec 19, 2024
8ff3230
Merge branch 'main' into 1135-Refactor-Layout-Components-Footer
AliceR Dec 19, 2024
b45d108
Replace values with theme vars
AliceR Dec 19, 2024
3584e15
Add role and aria-label to svg logo
AliceR Dec 19, 2024
c149d5b
Merge branch 'main' into 1135-Refactor-Layout-Components-Footer
AliceR Dec 19, 2024
23850fd
corrcting layout, line-height, and coloring issues
snmln Dec 20, 2024
0c78b01
updating documentation
snmln Dec 23, 2024
c4f1b24
updating documentation
snmln Dec 23, 2024
b5fad30
updating tests
snmln Dec 24, 2024
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
4 changes: 3 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ GOOGLE_FORM = 'https://docs.google.com/forms/d/e/1FAIpQLSfGcd3FDsM3kQIOVKjzdPn4f
SHOW_CONFIGURABLE_COLOR_MAP = 'TRUE'

# Enables the refactor page header component that uses the USWDS design system
ENABLE_USWDS_PAGE_HEADER = 'TRUE'
ENABLE_USWDS_PAGE_HEADER = 'TRUE'
# Enables the refactor page footer component that uses the USWDS design system
ENABLE_USWDS_PAGE_FOOTER = 'TRUE'
26 changes: 23 additions & 3 deletions app/scripts/components/common/layout-root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ import styled from 'styled-components';
import { Outlet } from 'react-router';
import { reveal } from '@devseed-ui/animation';
import { getBannerFromVedaConfig, getCookieConsentFromVedaConfig } from 'veda';

import MetaTags from '../meta-tags';
import PageFooter from '../page-footer';
import PageFooterLegacy from '../page-footer-legacy';
import NasaLogoColor from '../nasa-logo-color';

const Banner = React.lazy(() => import('../banner'));
const CookieConsent = React.lazy(() => import('../cookie-consent'));

Expand All @@ -24,11 +28,14 @@ import NavWrapper from '$components/common/nav-wrapper';
import Logo from '$components/common/page-header-legacy/logo';
import {
mainNavItems,
subNavItems
subNavItems,
footerSettings
} from '$components/common/page-header/default-config';
import { checkEnvFlag } from '$utils/utils';

const appTitle = process.env.APP_TITLE;
const appDescription = process.env.APP_DESCRIPTION;
const isUSWDSEnabled = checkEnvFlag(process.env.ENABLE_USWDS_PAGE_FOOTER);

export const PAGE_BODY_ID = 'pagebody';

Expand Down Expand Up @@ -58,7 +65,8 @@ function LayoutRoot(props: { children?: ReactNode }) {
useEffect(() => {
// When there is no cookie consent form set up
!cookieConsentContent && setGoogleTagManager();
}, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // Empty dependency array ensures this effect runs only once, and not during SSR

const { title, thumbnail, description, hideFooter } =
useContext(LayoutRootContext);
Expand Down Expand Up @@ -98,7 +106,19 @@ function LayoutRoot(props: { children?: ReactNode }) {
/>
)}
</PageBody>
<PageFooter isHidden={hideFooter} />
{isUSWDSEnabled ? (
<PageFooter
settings={footerSettings}
primarySection={{
mainNavItems,
subNavItems
}}
hideFooter={hideFooter}
logoSvg={<NasaLogoColor />}
/>
) : (
<PageFooterLegacy hideFooter={hideFooter} />
)}
</Page>
);
}
Expand Down
452 changes: 245 additions & 207 deletions app/scripts/components/common/nasa-logo-color.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ const InfoList = styled.dl`
}
`;

function PageFooter(props) {
function PageFooterLegacy(props) {
const nowDate = new Date();

return (
Expand Down Expand Up @@ -174,8 +174,8 @@ function PageFooter(props) {
);
}

export default PageFooter;
export default PageFooterLegacy;

PageFooter.propTypes = {
PageFooterLegacy.propTypes = {
isHidden: T.bool
};
141 changes: 141 additions & 0 deletions app/scripts/components/common/page-footer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import React, { useMemo } from 'react';
import { Icon } from '@trussworks/react-uswds';
import { NavItemType } from '../page-header/types';
import { NavItemCTA } from '../page-header/nav/nav-item-cta';
import {
USWDSFooter,
USWDSFooterNav,
USWDSAddress
} from '$components/common/uswds';

import './styles.scss';

interface PageFooterProps {
primarySection: any;
settings: any;
hideFooter?: boolean;
logoSvg?: SVGElement | JSX.Element;
}
//TODO: clean up PageFooterProps, Unexpected any. Specify a different interface.

export default function PageFooter({
settings,
primarySection,
hideFooter,
logoSvg
}: PageFooterProps) {
const returnToTopButton = () => {
return (
<div
id='return-to-top-container'
className='margin-left-auto margin-right-auto'
>
<a className='usa-link text-primary' href='#'>
Return to top
</a>
</div>
);
};

const { returnToTop, secondarySection } = settings;
/* eslint-disable */
const { mainNavItems, subNavItems } = primarySection;

const createNavElement = (navItems, linkClasses) => {
//removing 'dropdown' items from array
let cleanedNavItems = navItems.filter((a) => {
if (a.type !== 'dropdown') {
return a;
}
});

return cleanedNavItems.map((item) => {
switch (item.type) {
case NavItemType.ACTION:
return <NavItemCTA item={item} customClasses={linkClasses} />;

case NavItemType.EXTERNAL_LINK:
return (
<a className={linkClasses} href={item.to} key={item.id}>
{item.title}
</a>
);
case NavItemType.INTERNAL_LINK:
return (
<a className={linkClasses} href={item.to} key={item.id}>
{item.title}
</a>
);

default:
return <></>;
}
});
};

const primaryItems = useMemo(
() => createNavElement(mainNavItems, 'usa-footer__primary-link'),
[mainNavItems]
);
const secondaryItems = useMemo(
() =>
createNavElement(subNavItems, 'usa-link text-base-dark text-underline'),
[mainNavItems]
);
return (
<>
<USWDSFooter
size='slim'
returnToTop={returnToTop && returnToTopButton()}
className={hideFooter && 'display-none'}
primary={
<div
id='footer_primary_container'
className=' grid-row bg-base-lightest usa-footer__primary-container'
>
<div className='mobile-lg:grid-col-8'>
<USWDSFooterNav
aria-label='Footer navigation'
size='slim'
links={primaryItems}
/>
</div>
<div className='tablet:grid-col-4'>
<USWDSAddress
size='slim'
className='flex-justify-end'
items={secondaryItems}
/>
</div>
</div>
}
secondary={
<div id='footer_secondary_container' className='grid-row'>
<div id='logo-container'>
<a id='logo-container-link' href='#'>
{logoSvg as JSX.Element}
<span className='footer-text'>
NASA EarthData 2024 • v0.17.0
AliceR marked this conversation as resolved.
Show resolved Hide resolved
{/* {version} */}
</span>
</a>
</div>
<div className='grid-col-4 footer-text grid-gap-6 flex-justify-end'>
<span>NASA Official: </span>
AliceR marked this conversation as resolved.
Show resolved Hide resolved
<a
key={secondarySection.type}
href={`mailto:${secondarySection.to}`}
>
<Icon.Mail
className='margin-right-1 width-205 height-auto position-relative'
id='mail_icon'
/>
{secondarySection.title}
</a>
</div>
</div>
}
/>
</>
);
}
43 changes: 43 additions & 0 deletions app/scripts/components/common/page-footer/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@use '$styles/veda-ui-theme-vars.scss' as themeVars;

.footer-text {
color: white;
AliceR marked this conversation as resolved.
Show resolved Hide resolved
align-self: center;
display: flex;
font-size: themeVars.$veda-uswds-fontsize-sm;
font-weight: themeVars.$veda-uswds-fontweight-regular;
gap: themeVars.$veda-uswds-spacing-105;
}

#return-to-top-container {
padding: themeVars.$veda-uswds-padding-4 themeVars.$veda-uswds-padding-5;
max-width: 64rem;
AliceR marked this conversation as resolved.
Show resolved Hide resolved
}
#footer_primary_container {
padding: themeVars.$veda-uswds-padding-4 themeVars.$veda-uswds-padding-5;
background-color: themeVars.$veda-uswds-color-base-lightest;
}
.usa-footer__secondary-section {
background-color: themeVars.$veda-uswds-color-base-darkest;
}

.usa-footer__primary-section {
background-color: themeVars.$veda-uswds-color-base-lightest;
text-underline-offset: themeVars.$veda-uswds-spacing-5;
}

#mail_icon {
top: 50%;
transform: translateY(-50%);
}

.usa-footer__address > .grid-row {
justify-content: flex-end;
}

address {
font-style: normal;
font-weight: themeVars.$veda-uswds-fontweight-regular;
font-size: themeVars.$veda-uswds-fontsize-sm;
text-underline-offset: themeVars.$veda-uswds-spacing-5;
}
24 changes: 20 additions & 4 deletions app/scripts/components/common/page-header/default-config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { getString, getNavItemsFromVedaConfig } from 'veda';
import {
getString,
getNavItemsFromVedaConfig,
getFooterSettingsFromVedaConfig
} from 'veda';
import {
InternalNavLink,
ExternalNavLink,
ActionNavItem,
DropdownNavLink,
NavItemType,
ActionNavItem
NavItemType
} from '$components/common/page-header/types';

import {
Expand All @@ -22,6 +26,7 @@ let defaultMainNavItems: (
)[] = [
{
id: 'data-catalog',

title: 'Data Catalog',
to: DATASETS_PATH,
type: NavItemType.INTERNAL_LINK
Expand Down Expand Up @@ -64,6 +69,15 @@ let defaultSubNavItems: (
}
];

const defaultFooterSettings = {
secondarySection: {
title: 'email test',
to: '/data-catalog',
type: 'Email'
},
returnToTop: true
};

if (process.env.GOOGLE_FORM !== undefined) {
defaultSubNavItems = [
...defaultSubNavItems,
Expand All @@ -80,5 +94,7 @@ const mainNavItems =
getNavItemsFromVedaConfig()?.mainNavItems ?? defaultMainNavItems;
const subNavItems =
getNavItemsFromVedaConfig()?.subNavItems ?? defaultSubNavItems;
const footerSettings =
getFooterSettingsFromVedaConfig() ?? defaultFooterSettings;

export { mainNavItems, subNavItems };
export { mainNavItems, subNavItems, footerSettings };
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
display: flex;
font-family: themeVars.$veda-uswds-basefont-sans;
gap: themeVars.$veda-uswds-spacing-105;
max-height: 2.5rem;

#logo-container-link {
display: flex;
Expand All @@ -13,25 +14,12 @@
font-size: themeVars.$veda-uswds-fontsize-lg;
}

#nasa-logo-pos {
opacity: 1;
transform: translate(0, -100%);
/* TODO: Fix the svg to not require any styles!
* - set opacity to 1 in svg and fix translation
*/
}

@media (width <= themeVars.$veda-uswds-spacing-desktop) {
#nasa-logo-pos {
svg {
display: none;
}
}

svg {
height: 2.5rem;
width: auto;
}

#logo-container-beta-tag {
color: white;
align-self: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const createDynamicNavMenuList = (
isOpen?: boolean[],
setIsOpen?: SetState<boolean[]>
): JSX.Element[] => {
// @TODO:Need to elevate this functionality to outside of the header. Allow this function to take classname as an argument so we can dynamcally create different types of links across multiple compoenents and apply various visual styling.
return navItems.map((item, index) => {
switch (item.type) {
case NavItemType.DROPDOWN:
Expand Down
Loading
Loading