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

Expose As Is - PageHeader, LinkElement Prop & Logo #1184

Merged
merged 5 commits into from
Oct 29, 2024
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
3 changes: 2 additions & 1 deletion app/scripts/components/common/layout-root/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { ReactNode, useContext, useCallback, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useDeepCompareEffect } from 'use-deep-compare';
import styled from 'styled-components';
import { Outlet } from 'react-router';
Expand Down Expand Up @@ -97,7 +98,7 @@ function LayoutRoot(props: { children?: ReactNode }) {
<NavWrapper
mainNavItems={mainNavItems}
subNavItems={subNavItems}
logo={<Logo />}
logo={<Logo linkProperties={{LinkElement: Link, pathAttributeKeyName: 'to'}} />}
/>
<PageBody id={PAGE_BODY_ID} tabIndex={-1}>
<Outlet />
Expand Down
7 changes: 5 additions & 2 deletions app/scripts/components/common/nav-wrapper.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import styled, { css } from 'styled-components';
import { themeVal } from '@devseed-ui/theme-provider';

import { NavLink } from 'react-router-dom';
import PageHeader from './page-header';
import { useSlidingStickyHeaderProps } from './layout-root/useSlidingStickyHeaderProps';

Expand Down Expand Up @@ -35,7 +35,10 @@ function PageNavWrapper(props) {
shouldSlideHeader={isHeaderHidden}
headerHeight={headerHeight}
>
<PageHeader {...props} />
<PageHeader
{...props}
linkProperties={{ LinkElement: NavLink, pathAttributeKeyName: 'to' }}
/>
</NavWrapper>
);
}
Expand Down
13 changes: 6 additions & 7 deletions app/scripts/components/common/page-header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@devseed-ui/collecticons';

import UnscrollableBody from '../unscrollable-body';
import { LinkProperties } from '../card';
import NavMenuItem from './nav-menu-item';
import { NavItem } from './types';

Expand Down Expand Up @@ -229,14 +230,13 @@ const GlobalMenu = styled.ul`
interface PageHeaderProps {
mainNavItems: NavItem[];
subNavItems: NavItem[];
logo: ReactElement
logo: ReactElement;
linkProperties: LinkProperties;
}


function PageHeader(props: PageHeaderProps) {
const { mainNavItems, subNavItems, logo } = props;
const { mainNavItems, subNavItems, logo, linkProperties } = props;
const { isMediumDown } = useMediaQuery();

const [globalNavRevealed, setGlobalNavRevealed] = useState(false);

const globalNavBodyRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -276,7 +276,6 @@ function PageHeader(props: PageHeaderProps) {
<>
<SROnly href='#' onClick={skipNav}>Skip to main content</SROnly>
<PageHeaderSelf id={HEADER_ID}>

{globalNavRevealed && isMediumDown && <UnscrollableBody />}
{logo}
{isMediumDown && (
Expand Down Expand Up @@ -317,15 +316,15 @@ function PageHeader(props: PageHeaderProps) {
<GlobalNavBlockTitle>Global</GlobalNavBlockTitle>
<GlobalMenu>
{mainNavItems.map((item) => {
return <NavMenuItem key={`${item.title}-nav-item`} item={item} alignment='left' onClick={closeNavOnClick} />;
return <NavMenuItem linkProperties={linkProperties} key={`${item.title}-nav-item`} item={item} alignment='left' onClick={closeNavOnClick} />;
})}
</GlobalMenu>
</SectionsNavBlock>
<SectionsNavBlock>
<GlobalNavBlockTitle>Meta</GlobalNavBlockTitle>
<GlobalMenu>
{subNavItems.map((item) => {
return <NavMenuItem key={`${item.title}-nav-item`} item={item} alignment='right' onClick={closeNavOnClick} />;
return <NavMenuItem linkProperties={linkProperties} key={`${item.title}-nav-item`} item={item} alignment='right' onClick={closeNavOnClick} />;
})}
</GlobalMenu>
</SectionsNavBlock>
Expand Down
30 changes: 30 additions & 0 deletions app/scripts/components/common/page-header/logo-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { ComponentType } from 'react';
import { Tip } from '../tip';
import { LinkProperties } from '../card';
import { Brand, PageTitleSecLink } from './logo';
/**
* LogoContainer that is meant to integrate in the default page header without the dependencies of the veda virtual modules
* and expects the Logo SVG to be passed in as a prop - this will support the instance for refactor
*/

export default function LogoContainer ({ linkProperties, Logo, title, subTitle, version }: {
linkProperties: LinkProperties,
Logo: JSX.Element,
title: string,
subTitle: string,
version: string
}) {
const LinkElement: ComponentType<any> = linkProperties.LinkElement as ComponentType<any>;

return (
<Brand>
<LinkElement {...{[linkProperties.pathAttributeKeyName]: '/'}}>
{Logo}
<span>{title}</span> <span>{subTitle}</span>
</LinkElement>
<Tip content={`v${version}`}>
<PageTitleSecLink {...{as: linkProperties.LinkElement as ComponentType<any>, [linkProperties.pathAttributeKeyName]: '/development'}}>Beta</PageTitleSecLink>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this component can be used by other instances when only logo svg is tweak-able - (ex. ghg overwrote the whole logo)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plan is to use the logo container in the larger page-header component. So i mentioned in my above comment we probably dont have to expose this actually because it would just be integrated in page-header component directly but this would come in the next iteration of implementing the new page-header design. So its more like a set up for next phase 👍🏼

</Tip>
</Brand>
);
}
18 changes: 10 additions & 8 deletions app/scripts/components/common/page-header/logo.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import React, { ComponentType } from 'react';
import styled from 'styled-components';
import { glsp, media, themeVal } from '@devseed-ui/theme-provider';
import { Link } from 'react-router-dom';
import NasaLogo from '../nasa-logo';
import { Tip } from '../tip';
import { LinkProperties } from '../card';
import { ComponentOverride } from '$components/common/page-overrides';

const appTitle = process.env.APP_TITLE;
const appVersion = process.env.APP_VERSION;

const Brand = styled.div`
export const Brand = styled.div`
display: flex;
flex-shrink: 0;

Expand Down Expand Up @@ -74,7 +74,7 @@ const Brand = styled.div`
}
`;

const PageTitleSecLink = styled(Link)`
export const PageTitleSecLink = styled.a`
align-self: end;
font-size: 0.75rem;
font-weight: ${themeVal('type.base.bold')};
Expand All @@ -98,16 +98,18 @@ const PageTitleSecLink = styled(Link)`
`}
`;

export default function Logo () {
export default function Logo ({ linkProperties }: { linkProperties: LinkProperties }) {
const LinkElement: ComponentType<any> = linkProperties.LinkElement as ComponentType<any>;

return (
<ComponentOverride with='headerBrand'>
<Brand>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am having trouble understanding how exporting Logo can work, when ComponentOverride component imports elements from the virtual moduleveda directly (https://github.com/NASA-IMPACT/veda-ui/blob/main/app/scripts/components/common/page-overrides.tsx#L3) Can you help me understand how this works?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the instsances except OG dashboard overrides this component with each instance's branding : ex. https://github.com/US-GHG-Center/veda-config-ghg/blob/16fe5b7c08e67f78e1a2a27727a82ff28034f4bc/overrides/components/header-brand/component.tsx#L4 🤔 which makes me wonder if this component is worth exporting at all. how do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not worth exporting, and we could anyway pass any ReactElement as a logo prop from Next.js: https://github.com/NASA-IMPACT/veda-ui/pull/1184/files#diff-86e372214b3b1dff36fcabf602d3ea911690d226a6e0bed48fee30b571864756R233

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very good point, thanks for making it 👍🏼 It might make sense in this case to separate the actual logo/svg from the styled container and have the logo/svg passed as a prop. I'll have to remove the veda virtual module dependency though so might have to recreate the same without the override 🤔, let me give it more thought!

Copy link
Collaborator Author

@sandrahoang686 sandrahoang686 Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a separate LogoContainer component that takes in the SVG logo as a prop along with other attributres like title. When working on the new page header design implementation, we might not have to expose this container though as its meant to just fit in the page header itself, might just have instance pass in only the SVG itself but this will work best for now for our current state of code.

<Link to='/'>
<LinkElement {...{[linkProperties.pathAttributeKeyName]: '/'}}>
<NasaLogo />
<span>Earthdata</span> <span>{appTitle}</span>
</Link>
</LinkElement>
<Tip content={`v${appVersion}`}>
<PageTitleSecLink to='/development'>Beta</PageTitleSecLink>
<PageTitleSecLink {...{as: linkProperties.LinkElement as ComponentType<any>, [linkProperties.pathAttributeKeyName]: '/development'}}>Beta</PageTitleSecLink>
</Tip>
</Brand>
</ComponentOverride>);
Expand Down
42 changes: 27 additions & 15 deletions app/scripts/components/common/page-header/nav-menu-item.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import React, { ComponentType } from 'react';
import styled from 'styled-components';
import { NavLink } from 'react-router-dom';
import {
glsp,
media,
Expand All @@ -13,10 +12,12 @@ import { DropMenu, DropMenuItem } from '@devseed-ui/dropdown';

import DropdownScrollable from '../dropdown-scrollable';
import GoogleForm from '../google-form';
import { LinkProperties } from '../card';
import { AlignmentEnum, InternalNavLink, ExternalNavLink, NavLinkItem, DropdownNavLink, ModalNavLink, NavItem, NavItemType } from './types.d';
import GlobalMenuLinkCSS from '$styles/menu-link';
import { useMediaQuery } from '$utils/use-media-query';


const rgbaFixed = rgba as any;

export const GlobalNavActions = styled.div`
Expand All @@ -38,9 +39,10 @@ export const GlobalNavToggle = styled(Button)`
z-index: 2000;
`;

const GlobalMenuLink = styled(NavLink)`
const GlobalMenuLink = styled.a`
${GlobalMenuLinkCSS}
`;

const GlobalMenuButton = styled(Button)`
${GlobalMenuLinkCSS}
`;
Expand All @@ -60,12 +62,17 @@ const DropMenuNavItem = styled(DropMenuItem)`

const LOG = true;

function LinkDropMenuNavItem({ child, onClick }: { child: NavLinkItem, onClick?:() => void}) {
function LinkDropMenuNavItem({ child, onClick, linkProperties }: { child: NavLinkItem, onClick?:() => void, linkProperties: LinkProperties }) {
const { title, type, ...rest } = child;
const linkProps = {
as: linkProperties.LinkElement as ComponentType<any>,
[linkProperties.pathAttributeKeyName]: (rest as InternalNavLink).to,
};

if (type === NavItemType.INTERNAL_LINK) {
return (
<li>
<DropMenuNavItem as={NavLink} to={(rest as InternalNavLink).to} onClick={onClick} data-dropdown='click.close'>
<DropMenuNavItem {...linkProps} onClick={onClick} data-dropdown='click.close'>
{title}
</DropMenuNavItem>
</li>
Expand All @@ -89,18 +96,23 @@ function LinkDropMenuNavItem({ child, onClick }: { child: NavLinkItem, onClick?:
}


export default function NavMenuItem({ item, alignment, onClick }: {item: NavItem, alignment?: AlignmentEnum, onClick?: () => void }) {
export default function NavMenuItem({ item, alignment, onClick, linkProperties }: {item: NavItem, alignment?: AlignmentEnum, onClick?: () => void, linkProperties: LinkProperties }) {
const { isMediumDown } = useMediaQuery();
const { title, type, ...rest } = item;

if (type === NavItemType.INTERNAL_LINK) {
return (
<li key={`${title}-nav-item`}>
<GlobalMenuLink to={(rest as InternalNavLink).to} onClick={onClick}>
{title}
</GlobalMenuLink>
</li>
const linkProps = {
as: linkProperties.LinkElement as ComponentType<any>,
[linkProperties.pathAttributeKeyName]: (rest as InternalNavLink).to,
};
return (
<li key={`${title}-nav-item`}>
<GlobalMenuLink {...linkProps} onClick={onClick}>
{title}
</GlobalMenuLink>
</li>

);
);
} else if (item.type === NavItemType.EXTERNAL_LINK) {
return (
<li key={`${title}-nav-item`}>
Expand All @@ -127,7 +139,7 @@ export default function NavMenuItem({ item, alignment, onClick }: {item: NavItem
<>
<li><GlobalMenuItem>{title} </GlobalMenuItem></li>
{item.children.map((child) => {
return <LinkDropMenuNavItem key={`${title}-dropdown-menu`} child={child} onClick={onClick} />;
return <LinkDropMenuNavItem key={`${title}-dropdown-menu`} child={child} onClick={onClick} linkProperties={linkProperties} />;
})}
</>
);
Expand All @@ -144,7 +156,7 @@ export default function NavMenuItem({ item, alignment, onClick }: {item: NavItem
>
<DropMenu>
{(item as DropdownNavLink).children.map((child) => {
return <LinkDropMenuNavItem key={`${title}-dropdown-menu`} child={child} />;
return <LinkDropMenuNavItem key={`${title}-dropdown-menu`} child={child} linkProperties={linkProperties} />;
})}
</DropMenu>
</DropdownScrollable>
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { PageMainContent } from '$styles/page';
import PageHero from '$components/common/page-hero';
import StoriesHubContent from '$components/stories/hub/hub-content';
import { useFiltersWithQS } from '$components/common/catalog/controls/hooks/use-filters-with-query';
import PageHeader from '$components/common/page-header';
import LogoContainer from '$components/common/page-header/logo-container';


export {
Expand All @@ -36,8 +38,10 @@ export {
DevseedUiThemeProvider,
PageMainContent,
PageHero,
PageHeader,
ReactQueryProvider,
StoriesHubContent,
LogoContainer,
// HOOKS and utility functions
useFiltersWithQS
};
Loading