import { View } from '.'; import extend = require('xtend') import { h } from '../vdom' import { click as clickEvent } from '../event' import { documentMetrics } from '../util' import App from "../App"; import { VNode } from '../vdom' const indentSize:number = 10 export class SidebarDivision { title:string sections:Array constructor(title:string) { this.title = title this.sections = [] } } export class SidebarSection { title:string view:View isOpen:boolean constructor(view:View, title:string) { this.title = title this.view = view this.isOpen = true } } export default abstract class Sidebar { app:App divisions:Array currentDivision:SidebarDivision|null lightMode:boolean width:number constructor(app:App) { this.app = app this.divisions = [] this.currentDivision = null this.lightMode = false this.width = 300 } setLightMode(lightMode:boolean):void { this.lightMode = lightMode } setDivisions(divisions:Array):void { this.divisions = divisions this.currentDivision = divisions[0] || null } setSections(sections:Array):void { let dummyDivision = new SidebarDivision('dummy') dummyDivision.sections = sections this.setDivisions([ dummyDivision ]) } render():VNode { const app:App = this.app var children:Array = [] let divisions = h('div.jfw-sidebar-divisions', h('div.jfw-sidebar-divisions-inner', this.divisions.map((division) => { return h('div.jfw-sidebar-division' + (division === this.currentDivision ? '.selected' : ''), { 'ev-click': clickEvent(clickDivision, { sidebar: this, division: division }) }, division.title) }))) if(this.currentDivision) { let onlyOneSection = this.currentDivision.sections.length === 1 this.currentDivision.sections.forEach((section:SidebarSection) => { if(!onlyOneSection) { if(section.title) { children.push(renderHeader(0, section)) } } let show = section.isOpen || onlyOneSection || !section.title if(show) { if(section.view) { children.push(h('div.jfw-sidebar-section', [ section.view.render() ])) } else { } } }) let sidebarElems:VNode[] = [] if(this.divisions.length > 1) { sidebarElems = sidebarElems.concat(divisions) } sidebarElems.push(h('div.jfw-sidebar-body', children)) return h('div.jfw-sidebar', { style: { 'flex-basis': this.width + 'px' } }, sidebarElems) function renderHeader(indent:number, section:SidebarSection) { return h('div.jfw-sidebar-header', { style: { 'margin-left': (indent * indentSize) + 'px' }, 'ev-click': clickEvent(clickHeader, { app: app, section: section }) }, ([ h(section.isOpen ? 'span.fa.fa-minus-square' : 'span.fa.fa-plus-square', h('span.jfw-sidebar-header-text', section.title)) ])) } } } } function clickDivision(data) { const { sidebar, division } = data sidebar.currentDivision = division sidebar.app.update() } function clickHeader(data) { const { app, section } = data section.isOpen = !section.isOpen app.update() }