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: update header menu breakpoints (#173) #175

Merged
merged 3 commits into from
Aug 26, 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
Original file line number Diff line number Diff line change
@@ -1,35 +1,73 @@
import LoginRoundedIcon from "@mui/icons-material/LoginRounded";
import {
ButtonProps as MButtonProps,
IconButton as MIconButton,
IconButtonProps as MIconButtonProps,
} from "@mui/material";
import { useRouter } from "next/router";
import React, { useCallback } from "react";
import React, { ElementType, useCallback } from "react";
import { useAuthentication } from "../../../../../../../../../../hooks/useAuthentication/useAuthentication";
import { AuthenticationMenu } from "./components/AuthenticationMenu/authenticationMenu";
import { RequestAuthentication } from "./components/RequestAuthentication/requestAuthentication";
import { StyledButton } from "./components/Button/button.styles";

export interface AuthenticationProps {
authenticationEnabled?: boolean;
Button: ElementType<MButtonProps> | ElementType<MIconButtonProps>;
closeMenu: () => void;
}

export const Authentication = ({
authenticationEnabled,
Button,
closeMenu,
}: AuthenticationProps): JSX.Element => {
}: AuthenticationProps): JSX.Element | null => {
const { isAuthenticated, requestAuthentication, userProfile } =
useAuthentication();
const router = useRouter();
const onLogout = useCallback((): void => {
location.href = router.basePath;
}, [router]);

if (!authenticationEnabled) return null;

return (
<>
{authenticationEnabled &&
(isAuthenticated && userProfile ? (
<AuthenticationMenu onLogout={onLogout} userProfile={userProfile} />
) : (
<RequestAuthentication
closeMenu={closeMenu}
requestAuthorization={requestAuthentication}
/>
))}
{isAuthenticated && userProfile ? (
<AuthenticationMenu onLogout={onLogout} userProfile={userProfile} />
) : (
<Button
onClick={(): void => {
requestAuthentication();
closeMenu();
}}
/>
)}
</>
);
};

/**
* Renders authentication button.
* @param props - Button props.
* @returns button.
*/
export function renderButton(props: MButtonProps): JSX.Element {
return (
<StyledButton startIcon={<LoginRoundedIcon />} variant="nav" {...props}>
Sign in
</StyledButton>
);
}

/**
* Renders authentication icon button.
* @param props - Button props.
* @returns icon button.
*/
export function renderIconButton(props: MIconButtonProps): JSX.Element {
return (
<MIconButton color="ink" {...props}>
<LoginRoundedIcon />
</MIconButton>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import styled from "@emotion/styled";
import { Button as MButton } from "@mui/material";

export const StyledButton = styled(MButton)`
&.MuiButton-nav {
padding: 6px 12px;
}
`;

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DialogProps as MDialogProps } from "@mui/material";

export const DIALOG_PROPS: Partial<MDialogProps> = {
PaperProps: { elevation: 0 },
TransitionProps: { easing: "ease-out" },
fullScreen: true,
hideBackdrop: true,
keepMounted: false,
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ import { ComponentsConfig } from "../../../../../../../../../../../../config/ent
import { Left, Right } from "../../../../../../../../header.styles";
import { Announcements } from "../../../../../../../Announcements/announcements";
import { Actions } from "../../../../actions";
import { Authentication } from "../../../Authentication/authentication";
import { Search } from "../../../Search/search";
import {
Authentication,
renderIconButton as renderAuthenticationIconButton,
} from "../../../Authentication/authentication";
import {
renderIconButton as renderSearchIconButton,
Search,
} from "../../../Search/search";

export interface DialogTitleProps {
actions?: ReactNode;
Expand Down Expand Up @@ -36,13 +42,15 @@ export const Toolbar = ({
<Actions>
{/* Search */}
<Search
Button={renderSearchIconButton}
closeMenu={onClose}
searchEnabled={searchEnabled}
searchURL={searchURL}
/>
{/* Authentication */}
<Authentication
authenticationEnabled={authenticationEnabled}
Button={renderAuthenticationIconButton}
closeMenu={onClose}
/>
{/* Additional actions i.e. call-to-action button */}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import MenuRoundedIcon from "@mui/icons-material/MenuRounded";
import { Dialog as MDialog, Fade, IconButton } from "@mui/material";
import React, { CSSProperties, forwardRef, Fragment, useEffect } from "react";
import { useBreakpoint } from "../../../../../../../../../../hooks/useBreakpoint";
import { getMenuNavigationLinks } from "../../../../../../common/utils";
import { HeaderProps } from "../../../../../../header";
import { AppBar } from "../../../../../../header.styles";
import { Content } from "../../../../content.styles";
import { Slogan } from "../../../Slogan/slogan";
import { DIALOG_PROPS } from "./common/constants";
import { Navigation } from "./components/Content/components/Navigation/navigation.styles";
import { Socials } from "./components/Content/components/Socials/socials.styles";
import { Toolbar } from "./components/Toolbar/toolbar";

export interface MenuProps {
closeMenu: () => void;
headerProps: HeaderProps;
isMenuIn: boolean;
open: boolean;
openMenu: () => void;
pathname?: string;
Expand All @@ -22,36 +23,38 @@ export interface MenuProps {

export const Menu = forwardRef<HTMLButtonElement, MenuProps>(
function HeaderMenu(
{ closeMenu, headerProps, open, openMenu, pathname, style }: MenuProps,
{
closeMenu,
headerProps,
isMenuIn,
open,
openMenu,
pathname,
style,
}: MenuProps,
ref
): JSX.Element | null {
const { navigation, slogan, socialMedia } = headerProps;
const { smDown } = useBreakpoint();

// Set drawer open state to false on change of media breakpoint from small desktop "md" and up.
useEffect(() => {
if (smDown) return;
if (isMenuIn) return;
closeMenu();
}, [closeMenu, smDown]);
}, [closeMenu, isMenuIn]);

if (!smDown) return null;
if (!isMenuIn) return null;

return (
<Fragment>
<IconButton color="ink" onClick={openMenu} ref={ref} style={style}>
<MenuRoundedIcon />
</IconButton>
<MDialog
disableScrollLock
fullScreen
hideBackdrop
keepMounted={false}
{...DIALOG_PROPS}
onClose={closeMenu}
open={open}
PaperProps={{ elevation: 0 }}
TransitionComponent={Fade}
transitionDuration={smDown ? 600 : 0}
TransitionProps={{ easing: "ease-out" }}
transitionDuration={isMenuIn ? 600 : 0}
>
<AppBar component="div" elevation={0}>
<Toolbar onClose={closeMenu} {...headerProps} />
Expand All @@ -61,6 +64,7 @@ export const Menu = forwardRef<HTMLButtonElement, MenuProps>(
<Navigation
closeAncestor={closeMenu}
headerProps={headerProps}
isMenuIn={isMenuIn}
links={getMenuNavigationLinks(navigation)}
pathname={pathname}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import styled from "@emotion/styled";
import { Button as MButton } from "@mui/material";

export const StyledButton = styled(MButton)`
&.MuiButton-nav {
padding: 6px 12px;
}
`;

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
import React, { useState } from "react";
import {
ButtonProps as MButtonProps,
IconButton as MIconButton,
IconButtonProps as MIconButtonProps,
} from "@mui/material";
import React, { ElementType, useState } from "react";
import { SearchIcon } from "../../../../../../../../../common/CustomIcon/components/SearchIcon/searchIcon";
import { StyledButton } from "./components/Button/button.styles";
import SearchBar from "./components/SearchBar/searchBar";
import { SearchButton } from "./components/SearchButton/searchButton";

export interface SearchProps {
Button: ElementType<MButtonProps> | ElementType<MIconButtonProps>;
closeMenu: () => void;
searchEnabled?: boolean;
searchURL?: string;
}

export const Search = ({
Button,
closeMenu,
searchEnabled,
searchURL,
}: SearchProps): JSX.Element => {
}: SearchProps): JSX.Element | null => {
const [searchOpen, setSearchOpen] = useState<boolean>(false);

if (!searchEnabled) return null;

return (
<>
{searchEnabled && (
<SearchButton openSearch={(): void => setSearchOpen(true)} />
)}
<Button onClick={(): void => setSearchOpen(true)} />
<SearchBar
closeMenu={closeMenu}
closeSearch={(): void => setSearchOpen(false)}
Expand All @@ -28,3 +37,29 @@ export const Search = ({
</>
);
};

/**
* Renders search button.
* @param props - Button props.
* @returns button.
*/
export function renderButton(props: MButtonProps): JSX.Element {
return (
<StyledButton startIcon={<SearchIcon />} variant="nav" {...props}>
Search
</StyledButton>
);
}

/**
* Renders search icon button.
* @param props - Button props.
* @returns icon button.
*/
export function renderIconButton(props: MIconButtonProps): JSX.Element {
return (
<MIconButton color="ink" {...props}>
<SearchIcon fontSize="medium" />
</MIconButton>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DialogProps as MDialogProps } from "@mui/material";

export const DIALOG_PROPS: Partial<MDialogProps> = {
PaperProps: { elevation: 0 },
fullScreen: true,
hideBackdrop: true,
keepMounted: false,
transitionDuration: 300,
};
Loading
Loading