feat: menubar

This commit is contained in:
cha0s 2020-07-02 02:18:03 -05:00
parent 3bedccaa3a
commit aedaed4df6
2 changed files with 138 additions and 0 deletions

57
src/client/menubar.jsx Normal file
View File

@ -0,0 +1,57 @@
import {compose} from '@avocado/core';
import contempo from 'contempo';
import PropTypes from 'prop-types';
import React from 'react';
const decorate = compose(
contempo(require('./menubar.raw.scss')),
);
const renderTree = (tree) => (
<ul>
{tree.map((branch) => {
const {
children = [],
label,
onClick = () => {},
onPointerDown = () => {},
} = branch;
return (
<li>
<button onClick={onClick} onPointerDown={onPointerDown} type="button">{label}</button>
{children.length > 0 && renderTree(children)}
</li>
);
})}
</ul>
);
const MenuBar = (props) => {
const {icon, tree} = props;
const rendered = renderTree(tree.map((branch) => ({
...branch,
onPointerDown: (event) => {
if (window.document.activeElement === event.target) {
event.target.blur();
event.preventDefault();
}
},
})));
return (
<div className="menubar">
{icon && <span className="menubar__icon">{icon}</span>}
{React.cloneElement(rendered, {className: 'menubar__top-list'})}
</div>
);
};
MenuBar.defaultProps = {
icon: null,
};
MenuBar.propTypes = {
icon: PropTypes.node,
tree: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
};
export default decorate(MenuBar);

View File

@ -0,0 +1,81 @@
:scope {
background-color: #444444;
display: flex;
font-family: var(--title-font-family);
position: relative;
z-index: 1000;
}
li {
cursor: pointer;
display: flex;
height: 2.5em;
&:hover, &:focus-within {
background-color: #555555;
}
}
li button {
padding: 0 1em;
}
.menubar__icon {
height: 2.5em;
padding: 0.5em;
text-align: center;
width: 2.5em;
}
.menubar__icon img {
height: 100%;
}
.menubar__top-list {
display: flex;
}
.menubar__top-list > li {
position: relative;
button {
background-color: transparent;
border: none;
text-align: left;
&:focus {
box-shadow: none;
}
}
> ul {
display: none;
}
&:focus-within > ul {
display: flex;
top: 2.5em;
z-index: 1;
li > button {
min-width: 15em;
}
}
&:focus-within ul {
background-color: #272727;
box-shadow: 0 0 3px black;
flex-direction: column;
left: 0;
position: absolute;
}
> ul ul {
display: none;
transform: translate(100%, 0%);
}
> ul > li:hover ul, > ul ul > li:hover {
display: flex;
}
}