Skip to content

Commit a84cc34

Browse files
chore: Remove LinkProperties from PageHeader in favor of VedaUIProvider (#1382)
**Related Ticket:** #1381 **Related PRs:** NASA-IMPACT/next-veda-ui#36 ### Description of Changes * Removed `LinkProperties` prop from PageHeader and down the tree. * Abstracted VedaUIProvider wrapper out so it can also wrap around tests * Updated tests ### Notes & Questions About Changes _{Add additonal notes and outstanding questions here related to changes in this pull request}_ ### Validation / Testing * Make sure pageheader navigation is working as expected
2 parents dfcb297 + e24db17 commit a84cc34

File tree

11 files changed

+90
-97
lines changed

11 files changed

+90
-97
lines changed

app/scripts/components/common/nav-wrapper.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import styled, { css } from 'styled-components';
33
import { themeVal } from '@devseed-ui/theme-provider';
44
import { NavLink } from 'react-router-dom';
5-
import { default as PageHeaderLegacy } from './page-header-legacy';
5+
import PageHeaderLegacy from './page-header-legacy';
66
import PageHeader from './page-header';
77
import { useSlidingStickyHeaderProps } from './layout-root/useSlidingStickyHeaderProps';
88
import NasaLogoColor from './nasa-logo-color';
@@ -38,12 +38,7 @@ function NavWrapper(props) {
3838
const { isHeaderHidden, headerHeight } = useSlidingStickyHeaderProps();
3939

4040
return isUSWDSEnabled ? (
41-
<PageHeader
42-
{...props}
43-
logoSvg={<NasaLogoColor />}
44-
linkProperties={{ LinkElement: NavLink, pathAttributeKeyName: 'to' }}
45-
title={appTitle}
46-
/>
41+
<PageHeader {...props} logoSvg={<NasaLogoColor />} title={appTitle} />
4742
) : (
4843
<NavWrapperContainer
4944
id={HEADER_WRAPPER_ID}

app/scripts/components/common/page-header-legacy/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,14 @@ const GlobalMenu = styled.ul`
229229
`}
230230
`;
231231

232-
interface PageHeaderProps {
232+
interface PageHeaderLegacyProps {
233233
mainNavItems: NavItem[];
234234
subNavItems: NavItem[];
235235
logo: ReactElement;
236236
linkProperties: LinkProperties;
237237
}
238238

239-
function PageHeader(props: PageHeaderProps) {
239+
function PageHeaderLegacy(props: PageHeaderLegacyProps) {
240240
const { mainNavItems, subNavItems, logo, linkProperties } = props;
241241
const { isMediumDown } = useMediaQuery();
242242
const [globalNavRevealed, setGlobalNavRevealed] = useState(false);
@@ -357,4 +357,4 @@ function PageHeader(props: PageHeaderProps) {
357357
);
358358
}
359359

360-
export default PageHeader;
360+
export default PageHeaderLegacy;

app/scripts/components/common/page-header/index.tsx

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ import {
1010
USWDSNavMenuButton,
1111
USWDSExtendedNav
1212
} from '$uswds';
13-
import { LinkProperties } from '$types/veda';
13+
1414
interface PageHeaderProps {
1515
mainNavItems: NavItem[];
1616
subNavItems: NavItem[];
1717
logoSvg?: SVGElement | JSX.Element;
18-
linkProperties: LinkProperties;
1918
title: string;
2019
version?: string;
2120
accessibilityHomeShortCutText?: string;
@@ -25,7 +24,6 @@ export default function PageHeader({
2524
mainNavItems,
2625
subNavItems,
2726
logoSvg: Logo,
28-
linkProperties,
2927
title,
3028
version,
3129
accessibilityHomeShortCutText
@@ -44,14 +42,13 @@ export default function PageHeader({
4442
}, []);
4543

4644
const primaryItems = useMemo(
47-
() =>
48-
createDynamicNavMenuList(mainNavItems, linkProperties, isOpen, setIsOpen),
49-
[mainNavItems, linkProperties, isOpen]
45+
() => createDynamicNavMenuList(mainNavItems, isOpen, setIsOpen),
46+
[mainNavItems, isOpen]
5047
);
5148

5249
const secondaryItems = useMemo(
53-
() => createDynamicNavMenuList(subNavItems, linkProperties),
54-
[subNavItems, linkProperties]
50+
() => createDynamicNavMenuList(subNavItems),
51+
[subNavItems]
5552
);
5653

5754
const skipNav = (e) => {
@@ -64,22 +61,13 @@ export default function PageHeader({
6461

6562
return (
6663
<>
67-
<button
68-
type='button'
69-
className='usa-skipnav'
70-
onClick={skipNav}
71-
>
64+
<button type='button' className='usa-skipnav' onClick={skipNav}>
7265
{accessibilityHomeShortCutText || 'Skip to main content'}
7366
</button>
7467
<USWDSHeader extended={true} showMobileOverlay={expanded}>
7568
<div className='usa-navbar'>
7669
<USWDSHeaderTitle>
77-
<LogoContainer
78-
linkProperties={linkProperties}
79-
LogoSvg={Logo}
80-
title={title}
81-
version={version}
82-
/>
70+
<LogoContainer LogoSvg={Logo} title={title} version={version} />
8371
</USWDSHeaderTitle>
8472
<USWDSNavMenuButton onClick={toggleExpansion} label='Menu' />
8573
</div>

app/scripts/components/common/page-header/logo-container/index.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { ComponentType } from 'react';
22
import { Tip } from '../../tip';
3-
import { LinkProperties } from '$types/veda';
43
import './logo-container.scss';
4+
import { useVedaUI } from '$context/veda-ui-provider';
55

66
/**
77
* LogoContainer that is meant to integrate in the default
@@ -11,34 +11,33 @@ import './logo-container.scss';
1111
*/
1212

1313
export default function LogoContainer({
14-
linkProperties,
1514
LogoSvg,
1615
title,
1716
version
1817
}: {
19-
linkProperties: LinkProperties;
2018
LogoSvg?: SVGElement | JSX.Element;
2119
title: string;
2220
version?: string;
2321
}) {
24-
const LinkElement: ComponentType<any> =
25-
linkProperties.LinkElement as ComponentType<any>;
22+
const {
23+
navigation: { LinkComponent, linkProps }
24+
} = useVedaUI();
2625

2726
return (
2827
<div id='logo-container'>
29-
<LinkElement
28+
<LinkComponent
3029
id='logo-container-link'
31-
{...{ [linkProperties.pathAttributeKeyName]: '/' }}
30+
{...{ [linkProps.pathAttributeKeyName]: '/' }}
3231
>
33-
{LogoSvg}
32+
{LogoSvg as any}
3433
<span>{title}</span>
35-
</LinkElement>
34+
</LinkComponent>
3635
<Tip content={version ? `v${version}` : 'beta version'}>
3736
<div
3837
id='logo-container-beta-tag'
3938
{...{
40-
as: linkProperties.LinkElement as ComponentType<any>,
41-
[linkProperties.pathAttributeKeyName]: '/development'
39+
as: LinkComponent,
40+
[linkProps.pathAttributeKeyName]: '/development'
4241
}}
4342
>
4443
{version || 'BETA'}

app/scripts/components/common/page-header/logo-container/logo-container.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
gap: themeVars.$veda-uswds-spacing-105;
1212
font-weight: themeVars.$veda-uswds-fontweight-bold;
1313
font-size: themeVars.$veda-uswds-fontsize-lg;
14+
color: themeVars.$veda-uswds-color-base-ink;
1415
}
1516

1617
#nasa-logo-pos {

app/scripts/components/common/page-header/nav/create-dynamic-nav-menu-list.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import { NavItem, NavItemType } from '../types';
33
import { NavDropDownButton } from './nav-dropdown-button';
44
import { NavItemExternalLink, NavItemInternalLink } from './nav-item-links';
55
import { NavItemCTA } from './nav-item-cta';
6-
import { LinkProperties } from '$types/veda';
76
import { SetState } from '$types/aliases';
87

98
export const createDynamicNavMenuList = (
109
navItems: NavItem[],
11-
linkProperties: LinkProperties,
1210
isOpen?: boolean[],
1311
setIsOpen?: SetState<boolean[]>
1412
): JSX.Element[] => {
@@ -22,14 +20,13 @@ export const createDynamicNavMenuList = (
2220
item,
2321
isOpen,
2422
setIsOpen,
25-
index,
26-
linkProperties
23+
index
2724
}}
2825
/>
2926
);
3027

3128
case NavItemType.INTERNAL_LINK:
32-
return <NavItemInternalLink {...{ item, linkProperties }} />;
29+
return <NavItemInternalLink item={item} />;
3330

3431
case NavItemType.EXTERNAL_LINK:
3532
return <NavItemExternalLink item={item} />;

app/scripts/components/common/page-header/nav/nav-dropdown-button.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,20 @@ import { DropdownNavLink } from '../types';
33
import { createDynamicNavMenuList } from './create-dynamic-nav-menu-list';
44
import { USWDSNavDropDownButton, USWDSMenu } from '$uswds';
55
import { SetState } from '$types/aliases';
6-
import { LinkProperties } from '$types/veda';
76
import { useClickOutside } from '$utils/use-click-outside';
87

98
interface NavDropDownButtonProps {
109
item: DropdownNavLink;
1110
isOpen: boolean[];
1211
setIsOpen: SetState<boolean[]>;
1312
index: number;
14-
linkProperties: LinkProperties;
1513
}
1614

1715
export const NavDropDownButton = ({
1816
item,
1917
isOpen,
2018
setIsOpen,
21-
index,
22-
linkProperties
19+
index
2320
}: NavDropDownButtonProps) => {
2421
const onToggle = (index: number, setIsOpen: SetState<boolean[]>): void => {
2522
setIsOpen((prevIsOpen) => {
@@ -42,7 +39,7 @@ export const NavDropDownButton = ({
4239
}
4340
}, [index, isOpen, setIsOpen]);
4441
const dropdownRef = useClickOutside(handleClickOutside);
45-
const submenuItems = createDynamicNavMenuList(item.children, linkProperties);
42+
const submenuItems = createDynamicNavMenuList(item.children);
4643

4744
return (
4845
<div key={item.id} ref={dropdownRef}>
Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import React from 'react';
22
import { ExternalNavLink, InternalNavLink } from '../types';
3-
import { LinkProperties } from '$types/veda';
3+
import { useVedaUI } from '$context/veda-ui-provider';
44

55
interface NavItemExternalLinkProps {
66
item: ExternalNavLink;
77
}
88

99
interface NavItemInternalLinkProps {
1010
item: InternalNavLink;
11-
linkProperties: LinkProperties;
1211
}
1312

1413
export const NavItemExternalLink = ({ item }: NavItemExternalLinkProps) => {
@@ -26,26 +25,22 @@ export const NavItemExternalLink = ({ item }: NavItemExternalLinkProps) => {
2625
);
2726
};
2827

29-
export const NavItemInternalLink = ({
30-
item,
31-
linkProperties
32-
}: NavItemInternalLinkProps) => {
33-
if (linkProperties.LinkElement) {
34-
const path = {
35-
[linkProperties.pathAttributeKeyName]: (item as InternalNavLink).to
36-
};
37-
const LinkElement = linkProperties.LinkElement;
38-
return (
39-
<LinkElement
40-
key={item.id}
41-
{...path}
42-
className='usa-nav__link'
43-
id={item.id}
44-
>
45-
<span>{item.title}</span>
46-
</LinkElement>
47-
);
48-
}
49-
// If the link provided is invalid, do not render the element
50-
return null;
28+
export const NavItemInternalLink = ({ item }: NavItemInternalLinkProps) => {
29+
const {
30+
navigation: { LinkComponent, linkProps }
31+
} = useVedaUI();
32+
33+
const path = {
34+
[linkProps.pathAttributeKeyName]: (item as InternalNavLink).to
35+
};
36+
return (
37+
<LinkComponent
38+
key={item.id}
39+
{...path}
40+
className='usa-nav__link'
41+
id={item.id}
42+
>
43+
<span>{item.title}</span>
44+
</LinkComponent>
45+
);
5146
};
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import React, { ComponentType } from 'react';
1+
import React from 'react';
22
import { render, screen, within } from '@testing-library/react';
33
import userEvent from '@testing-library/user-event';
44

5+
import { BrowserRouter } from 'react-router-dom';
56
import { navItems } from '../../../../../mock/veda.config.js';
67
import NasaLogoColor from '../nasa-logo-color';
8+
import { VedaUIConfigProvider } from '../../../../../test/utils.js';
79
import { NavItem } from './types';
810
import PageHeader from './index';
911

@@ -13,22 +15,21 @@ import PageHeader from './index';
1315
const mockMainNavItems: NavItem[] = navItems.mainNavItems;
1416
const mockSubNavItems: NavItem[] = navItems.subNavItems;
1517

16-
const mockLinkProperties = {
17-
pathAttributeKeyName: 'to',
18-
LinkElement: 'a' as unknown as ComponentType
19-
};
2018
const testTitle = 'Test Title';
2119

2220
describe('PageHeader', () => {
2321
beforeEach(() => {
2422
render(
25-
<PageHeader
26-
mainNavItems={mockMainNavItems}
27-
subNavItems={mockSubNavItems}
28-
logoSvg={<NasaLogoColor />}
29-
title={testTitle}
30-
linkProperties={mockLinkProperties}
31-
/>
23+
<BrowserRouter basename=''>
24+
<VedaUIConfigProvider>
25+
<PageHeader
26+
mainNavItems={mockMainNavItems}
27+
subNavItems={mockSubNavItems}
28+
logoSvg={<NasaLogoColor />}
29+
title={testTitle}
30+
/>
31+
</VedaUIConfigProvider>
32+
</BrowserRouter>
3233
);
3334
});
3435

@@ -45,7 +46,7 @@ describe('PageHeader', () => {
4546

4647
expect(primaryNav.childElementCount).toEqual(mockMainNavItems.length);
4748
expect(secondaryNav.childElementCount).toEqual(mockSubNavItems.length);
48-
expect(within(primaryNav).getByText('Test')).toBeInTheDocument();
49+
expect(within(primaryNav).getByText('TestDropdown1')).toBeInTheDocument();
4950
expect(within(primaryNav).getByText('Data Catalog')).toBeInTheDocument();
5051
expect(within(primaryNav).getByText('Exploration')).toBeInTheDocument();
5152
expect(within(primaryNav).getByText('Stories')).toBeInTheDocument();
@@ -59,11 +60,9 @@ describe('PageHeader', () => {
5960
expect(navElement).toBeInTheDocument();
6061

6162
const primaryNav = within(navElement).getAllByRole('list')[0];
62-
const navItem = screen.getByText('Test');
63-
expect(
64-
within(primaryNav).getByText('dropdown menu item 1')
65-
).not.toBeVisible();
63+
const navItem = screen.getByText('TestDropdown1');
64+
expect(within(primaryNav).getByText('route to stories')).not.toBeVisible();
6665
await user.click(navItem);
67-
expect(within(primaryNav).getByText('dropdown menu item 1')).toBeVisible();
66+
expect(within(primaryNav).getByText('route to stories')).toBeVisible();
6867
});
6968
});

mock/veda.config.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@ function checkEnvFlag(value) {
77
let mainNavItems = [
88
{
99
id: 'test',
10-
title: 'Test',
10+
title: 'TestDropdown1',
1111
type: 'dropdown',
1212
children: [
1313
{
1414
id: 'dropdown-menu-item-1',
15-
title: 'dropdown menu item 1',
15+
title: 'route to stories',
1616
to: '/stories',
1717
type: 'internalLink'
1818
}
1919
]
2020
},
2121
{
2222
id: 'another-test',
23-
title: 'Another Test',
23+
title: 'TestDropdown2',
2424
type: 'dropdown',
2525
children: [
2626
{
2727
id: 'dropdown-menu-item-2',
28-
title: 'dropdown menu item 2',
29-
to: '/stories',
28+
title: 'route to about',
29+
to: '/about',
3030
type: 'internalLink'
3131
}
3232
]

0 commit comments

Comments
 (0)