diff --git a/src/components/HamburgerMenu/index.tsx b/src/components/HamburgerMenu/index.tsx index 9a2a76d850..3557cb15a8 100644 --- a/src/components/HamburgerMenu/index.tsx +++ b/src/components/HamburgerMenu/index.tsx @@ -1,33 +1,46 @@ import cn from 'classnames' -import React, { useCallback, useState, useEffect } from 'react' +import React, { + useEffect, + useState, + useCallback, + MouseEvent, + KeyboardEvent +} from 'react' import HamburgerIcon from '../HamburgerIcon' import Link from '../Link' - import { logEvent } from '../../utils/front/ga' + import { getFirstPage } from '../../utils/shared/sidebar' import { ReactComponent as LogoSVG } from '../../../static/img/logo-white.svg' import { ReactComponent as TwitterIcon } from '../SocialIcon/twitter.svg' import { ReactComponent as GithubIcon } from '../SocialIcon/github.svg' -import { useHeaderIsScrolled } from '../../utils/front/scroll' import styles from './styles.module.css' const docsPage = getFirstPage() -const HamburgerMenu: React.FC = () => { - const [isOpened, setOpened] = useState(false) - const collapsed = useHeaderIsScrolled() +export type HamburgerHelpers = { + opened: boolean + setOpened: (newState: boolean) => void + handleToggle: () => void + handleKeyDown: (e: KeyboardEvent) => void + handleClose: () => void + handleItemClick: (name: string) => (e: MouseEvent) => void +} + +export const useHamburgerMenu: () => HamburgerHelpers = () => { + const [opened, setOpened] = useState(false) - const toggleMobileMenu = useCallback(() => setOpened(!isOpened), [isOpened]) - const openOnEnterKey = useCallback(e => { + const handleToggle = useCallback(() => setOpened(!opened), [opened]) + const handleKeyDown = useCallback(e => { if (e.which === 13) { - toggleMobileMenu() + handleToggle() } }, []) - const close = useCallback(() => setOpened(false), [isOpened]) - const itemClick = useCallback( + const handleClose = useCallback(() => setOpened(false), [opened]) + const handleItemClick = useCallback( item => (): void => { close() logEvent('hamburger', item) @@ -36,197 +49,217 @@ const HamburgerMenu: React.FC = () => { ) useEffect(() => { - const method = isOpened ? 'add' : 'remove' - + const method = opened ? 'add' : 'remove' document.body.classList[method](styles.hiddenScrollbar) - }, [isOpened]) + }, [opened]) - return ( -
- + return { + opened, + setOpened, + handleToggle, + handleKeyDown, + handleClose, + handleItemClick + } +} -
-
- - - -
- - - Get started +export const HamburgerMenu: React.FC< + Pick< + HamburgerHelpers, + 'opened' | 'handleItemClick' | 'handleKeyDown' | 'handleToggle' + > & { + collapsed: boolean + } +> = ({ opened, handleItemClick }) => { + return ( +
+
+ +
+
    +
  • + + Features + +
  • +
  • + + Doc + +
  • +
  • + + Blog + +
  • +
  • + + Community + +
      +
    • + + + Meet Us + +
    • +
    • + + + Contribute + +
    • +
    • + + + Learn + +
    • +
    • + + + Events + +
    • +
    +
  • +
  • + + Support + +
      +
    • + + + E-Mail + +
    • +
    • + + + GitHub + +
    • +
    • + + + Discord + +
    • +
    • + + + Twitter + +
    • +
    +
  • +
+ + Get started +
) } -export default HamburgerMenu +export const HamburgerButton: React.FC<{ + opened: boolean + collapsed: boolean + handleClick: (e: MouseEvent) => void + handleKeyDown: (e: KeyboardEvent) => void +}> = ({ opened, collapsed, handleClick, handleKeyDown }) => ( + +) diff --git a/src/components/LayoutHeader/alert.tsx b/src/components/LayoutHeader/alert.tsx new file mode 100644 index 0000000000..4c3efeb05e --- /dev/null +++ b/src/components/LayoutHeader/alert.tsx @@ -0,0 +1,25 @@ +import cn from 'classnames' +import React from 'react' + +import { ReactComponent as GitHubIcon } from '../SocialIcon/github.svg' +import Link from '../Link' + +import styles from './styles.module.css' + +const LayoutAlert: React.FC<{ collapsed: boolean }> = ({ collapsed }) => ( +
+ + 🚀 + {' '} + Check out our newest tool, CML!{' '} + + + +
+) + +export default LayoutAlert diff --git a/src/components/LayoutHeader/index.tsx b/src/components/LayoutHeader/index.tsx index b8efa526c6..92d00ffd8b 100644 --- a/src/components/LayoutHeader/index.tsx +++ b/src/components/LayoutHeader/index.tsx @@ -3,61 +3,74 @@ import React from 'react' import includes from 'lodash/includes' import { LayoutModifiers, ILayoutModifiable } from '../MainLayout' -import { ReactComponent as GitHubIcon } from '../SocialIcon/github.svg' import LayoutWidthContainer from '../LayoutWidthContainer' import Link from '../Link' import Nav from './Nav' +import { + HamburgerMenu, + HamburgerButton, + useHamburgerMenu +} from '../HamburgerMenu' import { useHeaderIsScrolled } from '../../utils/front/scroll' import { ReactComponent as LogoSVG } from '../../../static/img/logo.svg' import styles from './styles.module.css' +import LayoutAlert from './alert' + const LayoutHeader: React.FC> = ({ modifiers }) => { + const { + opened, + handleToggle, + handleKeyDown, + handleItemClick + } = useHamburgerMenu() + const scrolled = useHeaderIsScrolled() const hasCollapsedModifier = includes(modifiers, LayoutModifiers.Collapsed) - const collapsed = hasCollapsedModifier || useHeaderIsScrolled() + const collapsed = opened || hasCollapsedModifier || scrolled return ( - + + + ) } diff --git a/src/components/LayoutHeader/styles.module.css b/src/components/LayoutHeader/styles.module.css index 4803d582b2..9456bb5e3d 100644 --- a/src/components/LayoutHeader/styles.module.css +++ b/src/components/LayoutHeader/styles.module.css @@ -1,12 +1,23 @@ .placeholder { + transition: height 0.2s linear; height: var(--layout-header-height); - &.collapsed { - height: var(--layout-header-height-collapsed); + &.withAlert { + height: calc(var(--layout-header-height) + var(--layout-alert-height)); } @media (--xs-scr) { height: var(--layout-header-height-collapsed); + + &.withAlert { + height: calc( + var(--layout-header-height-collapsed) + var(--layout-alert-height) + ); + } + } + + &.collapsed { + height: var(--layout-header-height-collapsed); } } @@ -61,8 +72,8 @@ } .alert { - height: 35px; - line-height: 35px; + height: var(--layout-alert-height); + line-height: var(--layout-alert-height); font-size: 18px; text-align: center; width: 100%; diff --git a/src/components/MainLayout/index.tsx b/src/components/MainLayout/index.tsx index 41ab52505e..8fa76ef0f8 100644 --- a/src/components/MainLayout/index.tsx +++ b/src/components/MainLayout/index.tsx @@ -2,7 +2,6 @@ import React, { useEffect } from 'react' import { IPageProps } from '../Page' import LayoutHeader from '../LayoutHeader' -import HamburgerMenu from '../HamburgerMenu' import LayoutFooter from '../LayoutFooter' import { handleFirstTab } from '../../utils/front/accessibility' @@ -52,7 +51,6 @@ const MainLayout: LayoutComponent = ({ return ( <> -
{children}
diff --git a/src/components/Page/base.css b/src/components/Page/base.css index b76e5b878a..da3a28cbf6 100644 --- a/src/components/Page/base.css +++ b/src/components/Page/base.css @@ -23,6 +23,7 @@ --layout-width-wide: 1200px; --layout-header-height: 98px; --layout-header-height-collapsed: 78px; + --layout-alert-height: 35px; } html {