From 8da6497457c1bc566beb09783fa8ef022bec940d Mon Sep 17 00:00:00 2001 From: ghalestrilo Date: Wed, 29 Jul 2020 16:01:40 -0300 Subject: [PATCH] :recycle: create useAsModal HOC --- client/components/OverlayManager.jsx | 11 ++++---- client/modules/IDE/pages/MobileIDEView.jsx | 29 ++++++++++++++++++---- client/utils/custom-hooks.js | 26 ++++++++++++++++--- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/client/components/OverlayManager.jsx b/client/components/OverlayManager.jsx index dd39284e..91c2b760 100644 --- a/client/components/OverlayManager.jsx +++ b/client/components/OverlayManager.jsx @@ -5,7 +5,7 @@ import { createPortal } from 'react-dom'; import Dropdown from './Dropdown'; import { PreferencesIcon } from '../common/icons'; -import { useHideOnBlur } from '../utils/custom-hooks'; +import { useModalBehavior } from '../utils/custom-hooks'; const OverlayManager = ({ overlay, hideOverlay }) => { @@ -23,13 +23,14 @@ const OverlayManager = ({ overlay, hideOverlay }) => { }, ]; - const setRef = useHideOnBlur(hideOverlay); + // const setRef = useModalBehavior(hideOverlay); + // const [visible, trigger, setRef] = useModalBehavior(); const jsx = ( -
- {overlay === 'dropdown' && } -
+ {/*
+ {visible && } +
*/}
); diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 08dec5c7..db256264 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -29,8 +29,11 @@ import Footer from '../../../components/mobile/Footer'; import IDEWrapper from '../../../components/mobile/IDEWrapper'; import Console from '../components/Console'; import { remSize } from '../../../theme'; -import OverlayManager from '../../../components/OverlayManager'; +// import OverlayManager from '../../../components/OverlayManager'; import ActionStrip from '../../../components/mobile/ActionStrip'; +import { useAsModal } from '../../../utils/custom-hooks'; +import { PreferencesIcon } from '../../../common/icons'; +import Dropdown from '../../../components/Dropdown'; const isUserOwner = ({ project, user }) => (project.owner && project.owner.id === user.id); @@ -39,6 +42,20 @@ const Expander = styled.div` height: ${props => (props.expanded ? remSize(160) : remSize(27))}; `; +const headerNavOptions = [ + { + icon: PreferencesIcon, + title: 'Preferences', + href: '/mobile/preferences', + }, + { icon: PreferencesIcon, title: 'Examples', href: '/mobile/examples' }, + { + icon: PreferencesIcon, + title: 'Original Editor', + href: '/mobile/preferences', + }, +]; + const MobileIDEView = (props) => { const { @@ -56,6 +73,8 @@ const MobileIDEView = (props) => { const hideOverlay = () => setOverlay(null); // const overlayRef = useRef({}); + const [triggerNavDropdown, NavDropDown] = useAsModal(); + return (
{ } > setOverlay('dropdown')} + onClick={triggerNavDropdown} icon={MoreIcon} aria-label="Options" /> @@ -114,12 +133,12 @@ const MobileIDEView = (props) => { {ide.consoleIsExpanded && } - - + {/* + /> */} ); }; diff --git a/client/utils/custom-hooks.js b/client/utils/custom-hooks.js index 9cacdd41..2776b5bf 100644 --- a/client/utils/custom-hooks.js +++ b/client/utils/custom-hooks.js @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useMemo, useState } from 'react'; export const noop = () => {}; @@ -14,13 +14,22 @@ export const useDidUpdate = (callback, deps) => { }, deps); }; -export const useHideOnBlur = (hideOverlay) => { +// Usage: const ref = useModalBehavior(() => setSomeState(false)) +// place this ref on a component +export const useModalBehavior = (hideOverlay) => { const ref = useRef({}); + + // Return values const setRef = (r) => { ref.current = r; }; + const [visible, setVisible] = useState(true); + const trigger = () => setVisible(true); + + const hide = () => setVisible(false); + const handleClickOutside = ({ target }) => { if (ref && ref.current && !ref.current.contains(target)) { - hideOverlay(); + hide(); } }; @@ -29,5 +38,14 @@ export const useHideOnBlur = (hideOverlay) => { return () => document.removeEventListener('mousedown', handleClickOutside); }, [ref]); - return setRef; + return [visible, trigger, setRef]; +}; + +// TODO: This is HOC, not a hook. Where do we put it? +export const useAsModal = (component) => { + const [visible, trigger, setRef] = useModalBehavior(); + + const wrapper = () => (
{visible && component}
); // eslint-disable-line + + return [trigger, wrapper]; };