Last active
April 28, 2020 17:07
-
-
Save lighth7015/008299f0042df5bdc6a637ffa0aa5c28 to your computer and use it in GitHub Desktop.
Stack Menu Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { h } from "react"; | |
export default | |
class AppDrawer extends React.Component<AppDrawerProps, AppDrawerState> { | |
state: AppDrawerState = { | |
current: [0] | |
}; | |
private entries: Array<MenuItem> = [ | |
{ | |
title: "Navigation", | |
items: [ | |
{ type: MenuTypes.Category, index: 0 }, | |
{ type: MenuTypes.MenuItem, index: 1 }, | |
{ type: MenuTypes.MenuItem, index: 2 }, | |
{ type: MenuTypes.Divider }, | |
{ type: MenuTypes.Category, index: 3 } | |
] | |
}, | |
{ | |
title: "Welcome to Firehouse", | |
route: "/" | |
}, | |
{ | |
title: "Second Item", | |
route: "second" | |
}, | |
{ | |
title: "Submenu", | |
items: [] | |
} | |
]; | |
private get items(): MenuEntries { | |
const { entries, state: { current = [ 0 ] }} = this; | |
const [ index ] = current; | |
const { items: children = [] }: MenuItem = entries[index]; | |
const items: MenuEntries = []; | |
const iterator: ReducerIterator<NavEntry> = ( items: MenuEntries, child: NavEntry, index: number ) => { | |
const menu: MenuItem = { title: '', type: child.type, items: [] }; | |
if (child.type !== MenuTypes.Divider) { | |
const { type: _unused, ...props } = child; | |
Object.assign(menu, props); | |
} | |
items.push(menu); | |
return items; | |
}; | |
if (len(current) > 1) { | |
console.log( 'Prepend parent.' ); | |
} | |
return children.reduce( iterator, [] ) as MenuEntries; | |
} | |
render(props: AppDrawerProps, { current }: AppDrawerState) { | |
const callback: SetStateFunc = this.setState.bind(this); | |
console.log(this.items); | |
return ( | |
<ul>{ | |
this.items.map((menu: MenuItem, index: number) => ( | |
<MenuEntry | |
key={index} items={this.entries} | |
scope={current} onUpdate={callback} | |
menu={menu} index={index} /> | |
)) | |
}</ul> | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const len: (t: any[]) => number = (t: any[]) => t.length; | |
enum MenuTypes { Category, MenuItem, Divider } | |
interface InlineStyle { | |
[prop: string]: any; | |
} | |
interface StyleContainer { | |
[prop: string]: InlineStyle; | |
} | |
interface AppDrawerProps { | |
opened?: boolean; | |
shouldCollapse: boolean; | |
} | |
interface AppDrawerState { | |
current: Array<number>; | |
} | |
interface NavEntry { | |
type: MenuTypes; | |
index?: number; | |
} | |
interface MenuItem { | |
type?: MenuTypes; | |
title: string; | |
route?: string | undefined; | |
items?: Array<NavEntry>; | |
} | |
type MenuEntries = Array<MenuItem>; | |
type NavEntries = Array<NavEntry>; | |
type ReducerIterator<T = any, Container = Array<T>> = ( items: Container | any, child: T, index: number ) => Container; | |
type SetStateFunc = (state: AppDrawerState) => void; | |
interface MenuEntryProps { | |
menu: MenuItem; | |
index: number; | |
scope: Array<number>; | |
items: Array<MenuItem>; | |
onUpdate: SetStateFunc; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment