diff --git a/src/@newrelic/gatsby-theme-newrelic/icons/newrelic/nav-collapse.js b/src/@newrelic/gatsby-theme-newrelic/icons/newrelic/nav-collapse.js index 516a6b8bfc4..91f9664935b 100644 --- a/src/@newrelic/gatsby-theme-newrelic/icons/newrelic/nav-collapse.js +++ b/src/@newrelic/gatsby-theme-newrelic/icons/newrelic/nav-collapse.js @@ -29,7 +29,7 @@ const NavCollapseIcon = (props) => { const [rectSpring] = useSpring( () => ({ delay: 280, - from: { x: '0' }, + from: { x: '0px' }, to: { x: '14px' }, reverse: sidebar, config: RECT_SPRING, diff --git a/src/components/MainLayoutContext.js b/src/components/MainLayoutContext.js index 3f2e67c8c2c..759fc1996b9 100644 --- a/src/components/MainLayoutContext.js +++ b/src/components/MainLayoutContext.js @@ -1,4 +1,13 @@ import { createContext, useContext } from 'react'; export const MainLayoutContext = createContext(); +/** + * exposes whether the site's left nav sidebar is currently open + * + * @example + * + * ```js + * const [sidebar] = useMainLayoutContext(); // true | false + * ``` + */ export const useMainLayoutContext = () => useContext(MainLayoutContext); diff --git a/src/layouts/HomepageLayout.js b/src/layouts/HomepageLayout.js deleted file mode 100644 index c220d46c1c7..00000000000 --- a/src/layouts/HomepageLayout.js +++ /dev/null @@ -1,440 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; -import PropTypes from 'prop-types'; -import { - GlobalHeader, - Layout, - Link, - Logo, - MobileHeader, - useLayout, - Icon, - Button, - SearchInput, - useTessen, - useTranslation, - useLoggedIn, - LoggedInProvider, -} from '@newrelic/gatsby-theme-newrelic'; -import cx from 'classnames'; -import styled from '@emotion/styled'; -import { css } from '@emotion/react'; -import { scroller } from 'react-scroll'; -import SEO from '../components/SEO'; -import RootNavigation from '../components/RootNavigation'; -import NavFooter from '../components/NavFooter'; -import { useLocation, navigate } from '@reach/router'; -import { MainLayoutContext } from '../components/MainLayoutContext'; -import { - ToggleViewContext, - TOGGLE_VIEWS, - ToggleSelector, -} from '../components/ToggleView'; - -const HomepageLayout = ({ children, pageContext }) => { - const tessen = useTessen(); - const { loggedIn } = useLoggedIn(); - const { sidebarWidth } = useLayout(); - const { locale, slug } = pageContext; - const location = useLocation(); - const [isMobileNavOpen, setIsMobileNavOpen] = useState(false); - const [searchTerm, setSearchTerm] = useState(''); - const [sidebar, setSidebar] = useState(true); - const { t } = useTranslation(); - const navHeaderHeight = '100px'; - const isStyleGuide = - slug.match(/\/docs\/style-guide/) || slug.match(/\/docs\/agile-handbook/); - const addTrailingSlash = (path) => { - if (path.endsWith('/')) { - return path; - } else { - return path.concat('/'); - } - }; - - useEffect(() => { - setIsMobileNavOpen(false); - // react scroll causes the page to crash if it doesn't find an element - // so we're checking for the element before firing - const pathName = addTrailingSlash(location.pathname); - const scrollElement = document.getElementsByName(pathName); - if (location.pathname !== '/' && scrollElement.length === 1) { - scroller.scrollTo(pathName, { - duration: 600, - delay: 0, - smooth: 'easeInOutQuart', - containerId: 'nav', - offset: -5, - }); - } - }, [location.pathname]); - - const hasToggled = useRef(false); - const [currentView, setCurrentView] = useState(TOGGLE_VIEWS.newUserView); - const [showTooltip, setShowTooltip] = useState(); - const updateView = (id) => { - hasToggled.current = true; - setCurrentView(id); - }; - const showAnimatedSearchBar = currentView === TOGGLE_VIEWS.newUserView; - - const SAVED_TOGGLE_VIEW_KEY = 'docs-website/homepage-selected-view'; - - /* `useLocalStorage` hook doesn't work here because SSR doesn't have access to - * localStorage, so when it gets to the client, the current tab is already set - * and the client doesn't know to update it. - * - */ - useEffect(() => { - const storedToggleView = window.localStorage.getItem(SAVED_TOGGLE_VIEW_KEY); - - const chooseViewByLoggedIn = loggedIn - ? TOGGLE_VIEWS.defaultView - : TOGGLE_VIEWS.newUserView; - - if (!storedToggleView && loggedIn !== null) { - setCurrentView( - loggedIn ? TOGGLE_VIEWS.defaultView : TOGGLE_VIEWS.newUserView - ); - setCurrentView(chooseViewByLoggedIn); - } - - /* prevents the tooltip from continuing to show on every render - * of the defaultview if it's triggered by the toggle buttons - * and only on initial page load to defaultview - */ - if (loggedIn) { - setShowTooltip(storedToggleView !== TOGGLE_VIEWS.newUserView); - } else if (!loggedIn) { - setShowTooltip(storedToggleView === TOGGLE_VIEWS.defaultView); - } - if (storedToggleView) { - setCurrentView(storedToggleView); - } - }, [setCurrentView, loggedIn]); - - useEffect(() => { - if (hasToggled.current) { - window.localStorage.setItem(SAVED_TOGGLE_VIEW_KEY, currentView); - } - }, [currentView]); - - return ( - <> - - - - - - - - - -
- { - setSearchTerm(e.target.value); - }} - onSubmit={() => { - tessen.track({ - eventName: 'personaViewSearch', - category: 'SearchInput', - searchTerm, - }); - navigate(`?q=${searchTerm || ''}`); - }} - className={cx(showAnimatedSearchBar && 'visible')} - /> - -
- div { - height: 100%; - overflow: hidden; - } - background: var(--erno-black); - - ${!sidebar && - css` - height: 50px; - width: 50px; - border: none; - z-index: 2; - position: absolute; - top: 1.5rem; - left: 6px; - background-color: transparent; - & > div { - padding: 0; - `} - hr { - border: none; - height: 1rem; - margin: 0; - } - `} - > -
-
- - - - -
- {sidebar && ( - setSearchTerm(e.target.value)} - onSubmit={() => { - tessen.track({ - eventName: 'homepageSidebarSearch', - category: 'SearchInput', - searchTerm, - }); - navigate(`?q=${searchTerm || ''}`); - }} - css={css` - margin: 1.5rem 0 2rem; - svg { - color: var(--primary-text-color); - } - `} - /> - )} -
- {sidebar && ( - <> - - - - )} -
- - {children} - - -
-
-
-
- - ); -}; - -const AnimatedSearchInput = styled(SearchInput)` - justify-self: end; - width: 150px; - transition: width 1200ms cubic-bezier(0.7, 0, 0.35, 1); - display: none; - &.visible { - display: grid; - } - input { - justify-self: end; - width: 0.5rem; - border: none; - background: none; - padding-left: 0.75rem; - height: 30px; - } - svg { - stroke: #fff; - right: 0.75rem; - transition: stroke, width, height 0.55s ease; - width: 1.25rem; - height: 1.25rem; - } - &:focus-within { - svg { - transition: stroke, width, height 0.55s ease; - stroke: var(--erno-black); - width: 0.75rem; - height: 0.75rem; - } - } - &:hover { - width: 150px; - svg { - transition: stroke, width, height 0.55s ease; - stroke: var(--erno-black); - width: 0.75rem; - height: 0.75rem; - } - } - &:hover input, - input:active, - input:focus { - box-shadow: none; - width: 150px; - border: 1px solid var(--system-text-primary-light); - background: #fff; - color: var(--system-text-primary-light); - &::placeholder { - color: var(--system-text-primary-light); - } - } -`; - -HomepageLayout.propTypes = { - children: PropTypes.node, - pageContext: PropTypes.object, -}; - -export default HomepageLayout; diff --git a/src/layouts/MainLayout.js b/src/layouts/MainLayout.js index 9ff2c5acd86..97db4665fbc 100644 --- a/src/layouts/MainLayout.js +++ b/src/layouts/MainLayout.js @@ -67,42 +67,49 @@ const MainLayout = ({ children, pageContext }) => { }, [sidebar]); const navCollapser = ( - + @media (max-width: 1240px) { + ${!sidebar && + `translate: calc(calc(var(--sidebar-width) * -1) + 141px);`} + } + `} + onClick={() => { + tessen.track({ + eventName: sidebar ? 'closeNav' : 'openNav', + category: 'NavCollapserClick', + }); + setSidebar(!sidebar); + }} + > + + + ); return ( @@ -117,7 +124,6 @@ const MainLayout = ({ children, pageContext }) => { - {navCollapser} { } `} > + {navCollapser}