⚗️ create <OverlayManager /> component
This commit is contained in:
parent
c58cdc29c3
commit
371e4ccdde
3 changed files with 57 additions and 129 deletions
|
@ -6,119 +6,20 @@ import { remSize, prop, common } from '../theme';
|
||||||
import IconButton from './mobile/IconButton';
|
import IconButton from './mobile/IconButton';
|
||||||
import Button from '../common/Button';
|
import Button from '../common/Button';
|
||||||
|
|
||||||
|
|
||||||
// <ul className="nav__dropdown">
|
|
||||||
|
|
||||||
|
|
||||||
// <ul className="nav__dropdown">
|
|
||||||
|
|
||||||
// <li className="nav__dropdown-item">
|
|
||||||
// <button
|
|
||||||
// onFocus={this.handleFocusForLang}
|
|
||||||
// onBlur={this.handleBlur}
|
|
||||||
// value="it"
|
|
||||||
// onClick={e => this.handleLangSelection(e)}
|
|
||||||
// >
|
|
||||||
// Italian (Test Fallback)
|
|
||||||
// </button>
|
|
||||||
// </li>
|
|
||||||
// <li className="nav__dropdown-item">
|
|
||||||
// <button
|
|
||||||
// onFocus={this.handleFocusForLang}
|
|
||||||
// onBlur={this.handleBlur}
|
|
||||||
// value="en-US"
|
|
||||||
// onClick={e => this.handleLangSelection(e)}
|
|
||||||
// >English
|
|
||||||
// </button>
|
|
||||||
// </li>
|
|
||||||
// <li className="nav__dropdown-item">
|
|
||||||
// <button
|
|
||||||
// onFocus={this.handleFocusForLang}
|
|
||||||
// onBlur={this.handleBlur}
|
|
||||||
// value="es-419"
|
|
||||||
// onClick={e => this.handleLangSelection(e)}
|
|
||||||
// >
|
|
||||||
// Español
|
|
||||||
// </button>
|
|
||||||
// </li>
|
|
||||||
// </ul>
|
|
||||||
|
|
||||||
// 'nav__item--open'
|
|
||||||
|
|
||||||
// %dropdown-open {
|
|
||||||
// @include themify() {
|
|
||||||
// background-color: map-get($theme-map, 'modal-background-color');
|
|
||||||
// border: 1px solid map-get($theme-map, 'modal-border-color');
|
|
||||||
// box-shadow: 0 0 18px 0 getThemifyVariable('shadow-color');
|
|
||||||
// color: getThemifyVariable('primary-text-color');
|
|
||||||
// }
|
|
||||||
// text-align: left;
|
|
||||||
// width: ${remSize(180)};
|
|
||||||
// display: flex;
|
|
||||||
// position: absolute;
|
|
||||||
// flex-direction: column;
|
|
||||||
// top: 95%;
|
|
||||||
// height: auto;
|
|
||||||
// z-index: 9999;
|
|
||||||
// border-radius: ${remSize(6)};
|
|
||||||
// & li:first-child {
|
|
||||||
// border-radius: ${remSize(5)} ${remSize(5)} 0 0;
|
|
||||||
// }
|
|
||||||
// & li:last-child {
|
|
||||||
// border-radius: 0 0 ${remSize(5)} ${remSize(5)};
|
|
||||||
// }
|
|
||||||
// -------------
|
|
||||||
// & li {
|
|
||||||
// & button,
|
|
||||||
// & a {
|
|
||||||
// @include themify() {
|
|
||||||
// color: getThemifyVariable('primary-text-color');
|
|
||||||
// }
|
|
||||||
// width: 100%;
|
|
||||||
// text-align: left;
|
|
||||||
// padding: ${remSize(8)} ${remSize(16)};
|
|
||||||
// }
|
|
||||||
// height: ${remSize(35)};
|
|
||||||
// cursor: pointer;
|
|
||||||
// display: flex;
|
|
||||||
// align-items: center;
|
|
||||||
// }
|
|
||||||
// & li:hover {
|
|
||||||
// @include themify() {
|
|
||||||
// background-color: getThemifyVariable('button-background-hover-color');
|
|
||||||
// color: getThemifyVariable('button-hover-color')
|
|
||||||
// }
|
|
||||||
// & button, & a {
|
|
||||||
// @include themify() {
|
|
||||||
// color: getThemifyVariable('button-hover-color');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// %dropdown-open-left {
|
|
||||||
// @extend %dropdown-open;
|
|
||||||
// left: 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// %dropdown-open-right {
|
|
||||||
// @extend %dropdown-open;
|
|
||||||
// right: 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
const DropdownWrapper = styled.ul`
|
const DropdownWrapper = styled.ul`
|
||||||
background-color: ${prop('Modal.background')};
|
background-color: ${prop('Modal.background')};
|
||||||
border: 1px solid ${prop('Modal.border')};
|
border: 1px solid ${prop('Modal.border')};
|
||||||
box-shadow: 0 0 18px 0 ${prop('shadowColor')};
|
box-shadow: 0 0 18px 0 ${prop('shadowColor')};
|
||||||
color: ${prop('primaryTextColor')};
|
color: ${prop('primaryTextColor')};
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: ${remSize(64)};
|
||||||
|
right: ${remSize(16)};
|
||||||
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: ${remSize(180)};
|
width: ${remSize(180)};
|
||||||
display: flex;
|
display: flex;
|
||||||
position: absolute;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
top: 95%;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
border-radius: ${remSize(6)};
|
border-radius: ${remSize(6)};
|
||||||
|
@ -150,14 +51,10 @@ const DropdownWrapper = styled.ul`
|
||||||
padding: ${remSize(8)} ${remSize(16)};
|
padding: ${remSize(8)} ${remSize(16)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// { onPress
|
// TODO: Add Icon to the left of the items in the menu
|
||||||
// ? <IconButton
|
// const MaybeIcon = (Element, label) => Element && <Element aria-label={label} />;
|
||||||
// : <Link to={to}>{title}</Link>}
|
|
||||||
|
|
||||||
const MaybeIcon = (Element, label) => Element && <Element aria-label={label} />;
|
|
||||||
|
|
||||||
const Dropdown = ({ items }) => (
|
const Dropdown = ({ items }) => (
|
||||||
<DropdownWrapper>
|
<DropdownWrapper>
|
||||||
|
@ -165,7 +62,7 @@ const Dropdown = ({ items }) => (
|
||||||
{items && items.map(({ title, icon, href }) => (
|
{items && items.map(({ title, icon, href }) => (
|
||||||
<li key={`nav-${title && title.toLowerCase()}`}>
|
<li key={`nav-${title && title.toLowerCase()}`}>
|
||||||
<Link to={href}>
|
<Link to={href}>
|
||||||
{MaybeIcon(icon, `Navigate to ${title}`)}
|
{/* {MaybeIcon(icon, `Navigate to ${title}`)} */}
|
||||||
{title}
|
{title}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -34,7 +34,8 @@ class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app">
|
||||||
{this.state.isMounted && !window.devToolsExtension && getConfig('NODE_ENV') === 'development' && <DevTools />}
|
{/* FIXME: Remove && false */}
|
||||||
|
{false && this.state.isMounted && !window.devToolsExtension && getConfig('NODE_ENV') === 'development' && <DevTools />}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useRef, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
|
@ -42,6 +42,42 @@ const BottomBarContent = styled.h2`
|
||||||
// const overlays = {};
|
// const overlays = {};
|
||||||
// const OverlayManager = name => overlays[name] || null;
|
// const OverlayManager = name => overlays[name] || null;
|
||||||
|
|
||||||
|
const OverlayManager = ({ ref, overlay, hideOverlay }) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = ({ target }) => {
|
||||||
|
if (ref && ref.current && !ref.current.contains(target)) { hideOverlay(); console.log('click'); }
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
return () => { document.removeEventListener('mousedown', handleClickOutside); };
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
|
const headerNavOptions = [
|
||||||
|
{ icon: PreferencesIcon, title: 'Preferences', href: '/mobile/preferences' },
|
||||||
|
{ icon: PreferencesIcon, title: 'Examples', href: '/mobile/examples' },
|
||||||
|
{ icon: PreferencesIcon, title: 'Original View', href: '/mobile/preferences' }
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={(r) => { if (ref) { ref.current = r; } }}>
|
||||||
|
{(overlay === 'dropdown') && <Dropdown items={headerNavOptions} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const refPropType = PropTypes.oneOfType([
|
||||||
|
PropTypes.func,
|
||||||
|
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
|
||||||
|
]);
|
||||||
|
|
||||||
|
OverlayManager.propTypes = {
|
||||||
|
ref: refPropType.isRequired,
|
||||||
|
overlay: PropTypes.string,
|
||||||
|
hideOverlay: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
OverlayManager.defaultProps = { overlay: null };
|
||||||
|
|
||||||
|
|
||||||
const MobileIDEView = (props) => {
|
const MobileIDEView = (props) => {
|
||||||
const {
|
const {
|
||||||
|
@ -53,18 +89,15 @@ const MobileIDEView = (props) => {
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [tmController, setTmController] = useState(null); // eslint-disable-line
|
const [tmController, setTmController] = useState(null); // eslint-disable-line
|
||||||
const [overlay, setOverlay] = useState(null); // eslint-disable-line
|
const [overlayName, setOverlay] = useState(null); // eslint-disable-line
|
||||||
|
|
||||||
// const overlayActive = name => (overlay === name);
|
// TODO: Move this to OverlayController (?)
|
||||||
|
const hideOverlay = () => setOverlay(null);
|
||||||
|
const overlayRef = useRef();
|
||||||
|
|
||||||
const headerNavOptions = [
|
|
||||||
{ icon: PreferencesIcon, title: 'Preferences', href: '/mobile/preferences' },
|
|
||||||
{ icon: PreferencesIcon, title: 'Examples', href: '/mobile/examples' },
|
|
||||||
{ icon: PreferencesIcon, title: 'Original View', href: '/mobile/preferences' }
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen fullscreen>
|
<Screen fullscreen >
|
||||||
<Header
|
<Header
|
||||||
title={project.name}
|
title={project.name}
|
||||||
subtitle={selectedFile.name}
|
subtitle={selectedFile.name}
|
||||||
|
@ -81,10 +114,6 @@ const MobileIDEView = (props) => {
|
||||||
<IconButton to="/mobile/preview" onClick={() => { startSketch(); }} icon={PlayIcon} aria-label="Run sketch" />
|
<IconButton to="/mobile/preview" onClick={() => { startSketch(); }} icon={PlayIcon} aria-label="Run sketch" />
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
|
|
||||||
{/* TODO: Overlays */}
|
|
||||||
<Dropdown items={headerNavOptions} />
|
|
||||||
|
|
||||||
<IDEWrapper>
|
<IDEWrapper>
|
||||||
<Editor
|
<Editor
|
||||||
lintWarning={preferences.lintWarning}
|
lintWarning={preferences.lintWarning}
|
||||||
|
@ -122,11 +151,12 @@ const MobileIDEView = (props) => {
|
||||||
/>
|
/>
|
||||||
</IDEWrapper>
|
</IDEWrapper>
|
||||||
|
|
||||||
{/*
|
{/* TODO: Create Overlay Manager */}
|
||||||
<Footer>
|
{<OverlayManager
|
||||||
<Console />
|
ref={overlayRef}
|
||||||
<BottomBarContent>Bottom Bar</BottomBarContent>
|
overlay={overlayName}
|
||||||
</Footer> */}
|
hideOverlay={hideOverlay}
|
||||||
|
/>}
|
||||||
</Screen>
|
</Screen>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue