Skip to content

Instantly share code, notes, and snippets.

@joake

joake/form.tsx Secret

Created March 24, 2020 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joake/041072c84aacef62dea7f7673e650d5f to your computer and use it in GitHub Desktop.
Save joake/041072c84aacef62dea7f7673e650d5f to your computer and use it in GitHub Desktop.
<SelectField name="docking" label="Slide in from" default={"left"}>
<SelectItemField label="Slide in from left" value="left" />
<SelectItemField label="Slide in from right" value="right" />
<SelectItemField label="Slide in from top" value="top" />
<SelectItemField label="Slide in from bottom" value="bottom" />
</SelectField>
<MenuField name="burgerMenu"/>
import { Icon, useEditorState, useMenu, useRoute, store, Portal, Link, IMenuItem } from 'vev';
import { Fragment, useState, useEffect } from 'react';
const DOCK_ANI = {
left: 'slide-right',
right: 'slide-left',
top: 'slide-down',
bottom: 'slide-up'
};
export default function({ docking }: Props) {
const [open, setOpen] = useState<boolean>(false);
const { disabled, rule, selected } = useEditorState();
const menu = useMenu();
useEffect(() => store('scrollTop', () => setOpen(false)), []);
useEffect(() => store('route', () => setOpen(false)), []);
useEffect(() => {
console.log('rule', rule);
if (rule === 'host') setOpen(false);
else setOpen(true);
}, [rule, selected, disabled]);
return (
<Fragment>
<div className="icon-container" onClick={() => setOpen(true)}>
<Icon d="menu" className="menu-icon" />
</div>
<Portal
dock={docking || 'left'}
className="sidenav"
hide={!open}
animation={DOCK_ANI[docking || 'left']}
closeTrigger="click"
onRequestClose={() => setOpen(false)}
>
<div className="close-button" onClick={() => setOpen(false)}>
<Icon d="close" />
</div>
{menu.children.map((item) => (
<MenuItem key={item.key} item={item} openSub={rule === '.menu-item-children'} />
))}
</Portal>
</Fragment>
);
}
interface MenuItemProps {
item: IMenuItem;
openSub?: boolean;
}
function MenuItem({ openSub, item }: MenuItemProps) {
const [open, setOpen] = useState(false);
const { pageKey } = useRoute();
const { title, link, children = [] } = item;
let cl = 'menu-item';
if (link && link.page === pageKey) cl += ' menu-item-active';
return (
<div className={cl}>
<div className="menu-link-wrapper">
<Link to={item.link}>{title}</Link>
{children.length > 0 && (
<i onClick={() => setOpen(!open)}>
<Icon d={open ? 'collapse' : 'uncollapse'} />
</i>
)}
</div>
{children.length > 0 && (
<div className={`menu-item-children${!open && !openSub ? ' collapsed' : ''}`}>
{children.map((item) => (
<MenuItem key={item.key} item={item} />
))}
</div>
)}
</div>
);
}
:host{
width:vev(48px);
height:vev(48px);
background:vev();
color:vev();
border:vev();
border-radius: vev();
box-shadow:vev();
padding:vev(5px);
opacity: vev();
}
.icon-container {
color: vev(#000000);
font-family: vev();
}
.menu-icon{
width:100%;
height:100%;
fill: currentColor;
}
a{
padding:vev(10px);
background:vev();
opacity: vev();
background:vev();
box-shadow: vev();
text-shadow: vev();
border:vev();
border-radius: vev();
color:vev();
font-size: vev();
line-height: vev();
word-spacing: vev();
letter-spacing: vev();
text-transform: vev();
text-align: vev();
}
a.active {
padding:vev(10px);
background:vev();
opacity: vev();
background:vev();
box-shadow: vev();
text-shadow: vev();
border:vev();
border-radius: vev();
color:vev();
font-size: vev();
line-height: vev();
word-spacing: vev();
letter-spacing: vev();
text-transform: vev();
text-align: vev();
}
.sidenav {
height: vev(100%);
width: vev(320px);
z-index: 1000;
overflow-x: hidden;
transition: all 0.5s ease-in-out;
background:vev(white);
padding-top: vev(30px);
opacity: vev();
text-shadow:vev();
font-family: vev();
box-shadow: vev();
border:vev();
border-radius: vev();
color:vev(black);
font-size: vev();
font-weight: vev();
line-height: vev();
word-spacing: vev();
letter-spacing: vev();
text-transform: vev();
text-align: vev();
}
.close-button {
position: absolute;
cursor: pointer;
z-index: 12;
top: 5px;
right: 8px;
width: auto;
height: auto;
line-height: 1.8em;
text-align: center;
margin: vev();
}
.menu-link-wrapper {
width: 100%;
display:flex;
justify-content:center;
align-items:center;
a{
flex:1 1;
}
i {
cursor: pointer;
padding:8px;
}
}
.menu-item a {
display: inline-block;
width: 100%;
height: 100%;
color: inherit;
text-decoration: none;
}
.menu-item-children {
background:vev(#f5f5f5);
opacity:vev();
padding:vev(0 0 0 15px);
box-shadow: vev();
border:vev();
border-radius: vev();
color:vev();
font-size: vev();
line-height: vev();
word-spacing: vev();
letter-spacing: vev();
text-transform: vev();
text-align: vev();
font-family: vev();
font-weight: vev();
overflow: hidden;
transition: max-height 0.3s, padding 0.3s;
max-height: 2000px;
&.collapsed {
max-height: 0px;
padding-top: 0 !important;
padding-bottom: 0 !important;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment