Skip to content

Commit

Permalink
Use core Nav logic in MobileNav.
Browse files Browse the repository at this point in the history
  • Loading branch information
lindapaiste committed Aug 10, 2023
1 parent 60a02f1 commit 7e13ecf
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 103 deletions.
28 changes: 19 additions & 9 deletions client/components/Nav/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React, {
} from 'react';
import { MenuOpenContext, NavBarContext } from './contexts';

function NavBar({ children }) {
function NavBar({ children, className }) {
const [dropdownOpen, setDropdownOpen] = useState('none');

const timerRef = useRef(null);
Expand Down Expand Up @@ -55,6 +55,15 @@ function NavBar({ children }) {
timerRef.current = setTimeout(() => setDropdownOpen('none'), 10);
}, [timerRef, setDropdownOpen]);

const toggleDropdownOpen = useCallback(
(dropdown) => {
setDropdownOpen((prevState) =>
prevState === dropdown ? 'none' : dropdown
);
},
[setDropdownOpen]
);

const contextValue = useMemo(
() => ({
createDropdownHandlers: (dropdown) => ({
Expand All @@ -64,9 +73,7 @@ function NavBar({ children }) {
);
},
onClick: () => {
setDropdownOpen((prevState) =>
prevState === 'none' ? dropdown : 'none'
);
toggleDropdownOpen(dropdown);
},
onBlur: handleBlur,
onFocus: clearHideTimeout
Expand All @@ -80,15 +87,16 @@ function NavBar({ children }) {
clearHideTimeout();
setDropdownOpen(dropdown);
}
})
}),
toggleDropdownOpen
}),
[setDropdownOpen, clearHideTimeout, handleBlur]
[setDropdownOpen, toggleDropdownOpen, clearHideTimeout, handleBlur]
);

return (
<NavBarContext.Provider value={contextValue}>
<header>
<nav className="nav" ref={nodeRef}>
<nav className={className} ref={nodeRef}>
<MenuOpenContext.Provider value={dropdownOpen}>
{children}
</MenuOpenContext.Provider>
Expand All @@ -99,11 +107,13 @@ function NavBar({ children }) {
}

NavBar.propTypes = {
children: PropTypes.node
children: PropTypes.node,
className: PropTypes.string
};

NavBar.defaultProps = {
children: null
children: null,
className: 'nav'
};

export default NavBar;
8 changes: 7 additions & 1 deletion client/components/Nav/NavDropdownMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useContext, useMemo } from 'react';
import TriangleIcon from '../../images/down-filled-triangle.svg';
import { MenuOpenContext, NavBarContext, ParentMenuContext } from './contexts';

function NavDropdownMenu({ id, title, children }) {
export function useMenuProps(id) {
const activeMenu = useContext(MenuOpenContext);

const isOpen = id === activeMenu;
Expand All @@ -16,6 +16,12 @@ function NavDropdownMenu({ id, title, children }) {
id
]);

return { isOpen, handlers };
}

function NavDropdownMenu({ id, title, children }) {
const { isOpen, handlers } = useMenuProps(id);

return (
<li className={classNames('nav__item', isOpen && 'nav__item--open')}>
<button {...handlers}>
Expand Down
10 changes: 6 additions & 4 deletions client/components/Nav/NavMenuItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useContext, useMemo } from 'react';
import ButtonOrLink from '../../common/ButtonOrLink';
import { NavBarContext, ParentMenuContext } from './contexts';

function NavMenuItem({ hideIf, ...rest }) {
function NavMenuItem({ hideIf, className, ...rest }) {
const parent = useContext(ParentMenuContext);

const { createMenuItemHandlers } = useContext(NavBarContext);
Expand All @@ -18,7 +18,7 @@ function NavMenuItem({ hideIf, ...rest }) {
}

return (
<li className="nav__dropdown-item">
<li className={className}>
<ButtonOrLink {...rest} {...handlers} />
</li>
);
Expand All @@ -31,13 +31,15 @@ NavMenuItem.propTypes = {
/**
* Provides a way to deal with optional items.
*/
hideIf: PropTypes.bool
hideIf: PropTypes.bool,
className: PropTypes.string
};

NavMenuItem.defaultProps = {
onClick: null,
value: null,
hideIf: false
hideIf: false,
className: 'nav__dropdown-item'
};

export default NavMenuItem;
3 changes: 2 additions & 1 deletion client/components/Nav/contexts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export const MenuOpenContext = createContext('none');

export const NavBarContext = createContext({
createDropdownHandlers: () => ({}),
createMenuItemHandlers: () => ({})
createMenuItemHandlers: () => ({}),
toggleDropdownOpen: () => {}
});
160 changes: 72 additions & 88 deletions client/modules/IDE/components/Header/MobileNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import styled from 'styled-components';
import { useDispatch, useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import {
NavBarContext,
ParentMenuContext
} from '../../../../components/Nav/contexts';
import NavBar from '../../../../components/Nav/NavBar';
import { useMenuProps } from '../../../../components/Nav/NavDropdownMenu';
import NavMenuItem from '../../../../components/Nav/NavMenuItem';
import { prop, remSize } from '../../../../theme';
import AsteriskIcon from '../../../../images/p5-asterisk.svg';
import IconButton from '../../../../components/mobile/IconButton';
Expand All @@ -20,7 +26,7 @@ import { useSketchActions } from '../../hooks';
import { CmControllerContext } from '../../pages/IDEView';
import { selectSketchPath } from '../../selectors/project';

const Nav = styled.div`
const Nav = styled(NavBar)`
background: ${prop('MobilePanel.default.background')};
color: ${prop('primaryTextColor')};
padding: ${remSize(8)} 0;
Expand All @@ -33,6 +39,7 @@ const Nav = styled.div`
`;

const LogoContainer = styled.div`
cursor: pointer;
width: ${remSize(28)};
aspect-ratio: 1;
margin-left: ${remSize(14)};
Expand Down Expand Up @@ -74,8 +81,7 @@ const Options = styled.div`
}
/* Drop Down menu */
> div > button:focus + ul,
> div > ul > button:focus ~ div > ul {
ul.opened {
transform: scale(1);
opacity: 1;
}
Expand Down Expand Up @@ -130,9 +136,7 @@ const Options = styled.div`
> li {
display: flex;
width: 100%;
a {
width: 100%;
}
a,
button {
width: 100%;
padding: ${remSize(8)} ${remSize(15)} ${remSize(8)} ${remSize(10)};
Expand All @@ -148,7 +152,17 @@ const Options = styled.div`
}
`;

const MobileNav = (props) => {
const Logo = () => {
const { toggleDropdownOpen } = useContext(NavBarContext);

return (
<LogoContainer onClick={() => toggleDropdownOpen('more')}>
<AsteriskIcon />
</LogoContainer>
);
};

const MobileNav = () => {
const project = useSelector((state) => state.project);
const user = useSelector((state) => state.user);

Expand Down Expand Up @@ -182,12 +196,9 @@ const MobileNav = (props) => {

const title = useMemo(resolveTitle, [project, pathname]);

const Logo = AsteriskIcon;
return (
<Nav>
<LogoContainer>
<Logo />
</LogoContainer>
<Logo />
<Title>
<h1>{title}</h1>
{project?.owner && title === project.name && (
Expand Down Expand Up @@ -222,24 +233,22 @@ const AccountMenu = () => {
const user = useSelector((state) => state.user);
const dispatch = useDispatch();

const { isOpen, handlers } = useMenuProps('account');

return (
<div>
<IconButton icon={AccountIcon} />
<ul>
<li className="user">{user.username}</li>
<li>
<Link to={`/${user.username}/sketches`}>
<button>My Stuff</button>
</Link>
</li>
<li>
<Link to="/account">
<button>Settings</button>
</Link>
</li>
<li>
<button onClick={() => dispatch(logoutUser())}>Log Out</button>
</li>
<IconButton icon={AccountIcon} {...handlers} />
<ul className={isOpen ? 'opened' : ''}>
<ParentMenuContext.Provider value="account">
<li className="user">{user.username}</li>
<NavMenuItem href={`/${user.username}/sketches`}>
My Stuff
</NavMenuItem>
<NavMenuItem href="/account">Settings</NavMenuItem>
<NavMenuItem onClick={() => dispatch(logoutUser())}>
Log Out
</NavMenuItem>
</ParentMenuContext.Provider>
</ul>
</div>
);
Expand All @@ -256,80 +265,55 @@ const MoreMenu = () => {

const cmRef = useContext(CmControllerContext);

const { isOpen, handlers } = useMenuProps('more');

return (
<div>
<IconButton icon={MoreIcon} />
<ul>
<b>{t('Nav.File.Title')}</b>
<li>
<button onClick={newSketch}>{t('Nav.File.New')}</button>
</li>
<li>
<button onClick={() => saveSketch(cmRef.current)}>
<IconButton icon={MoreIcon} {...handlers} />
<ul className={isOpen ? 'opened' : ''}>
<ParentMenuContext.Provider value="more">
<b>{t('Nav.File.Title')}</b>
<NavMenuItem onClick={newSketch}>{t('Nav.File.New')}</NavMenuItem>

<NavMenuItem onClick={() => saveSketch(cmRef.current)}>
{t('Common.Save')}
</button>
</li>
<li>
<Link to="/p5/sketches">
<button>{t('Nav.File.Examples')}</button>
</Link>
</li>
<b>{t('Nav.Edit.Title')}</b>
<li>
<button onClick={cmRef.current?.tidyCode}>
</NavMenuItem>
<NavMenuItem href="/p5/sketches">
{t('Nav.File.Examples')}
</NavMenuItem>
<b>{t('Nav.Edit.Title')}</b>
<NavMenuItem onClick={cmRef.current?.tidyCode}>
{t('Nav.Edit.TidyCode')}
</button>
</li>
<li>
<button onClick={cmRef.current?.showFind}>
</NavMenuItem>
<NavMenuItem onClick={cmRef.current?.showFind}>
{t('Nav.Edit.Find')}
</button>
</li>
<b>{t('Nav.Sketch.Title')}</b>
<li>
<button onClick={() => dispatch(newFile(rootFile.id))}>
</NavMenuItem>
<b>{t('Nav.Sketch.Title')}</b>
<NavMenuItem onClick={() => dispatch(newFile(rootFile.id))}>
{t('Nav.Sketch.AddFile')}
</button>
</li>
<li>
<button onClick={() => dispatch(newFolder(rootFile.id))}>
</NavMenuItem>
<NavMenuItem onClick={() => dispatch(newFolder(rootFile.id))}>
{t('Nav.Sketch.AddFolder')}
</button>
</li>
{/* TODO: Add Translations */}
<b>Settings</b>
<li>
<button
</NavMenuItem>
{/* TODO: Add Translations */}
<b>Settings</b>
<NavMenuItem
onClick={() => {
dispatch(openPreferences());
}}
>
Preferences
</button>
</li>
<li>
<button>Language</button>
</li>
<b>{t('Nav.Help.Title')}</b>
<li>
<button onClick={() => dispatch(showKeyboardShortcutModal())}>
</NavMenuItem>
<NavMenuItem>Language</NavMenuItem>
<b>{t('Nav.Help.Title')}</b>
<NavMenuItem onClick={() => dispatch(showKeyboardShortcutModal())}>
{t('Nav.Help.KeyboardShortcuts')}
</button>
</li>
<li>
<button
onClick={() => {
window.location = 'https://p5js.org/reference/';
}}
>
</NavMenuItem>
<NavMenuItem href="https://p5js.org/reference/">
{t('Nav.Help.Reference')}
</button>
</li>
<li>
<Link to="/about">
<button>{t('Nav.Help.About')}</button>
</Link>
</li>
</NavMenuItem>
<NavMenuItem href="/about">{t('Nav.Help.About')}</NavMenuItem>
</ParentMenuContext.Provider>
</ul>
</div>
);
Expand Down

0 comments on commit 7e13ecf

Please sign in to comment.