jiro-ui
Version:
A Mithril.js UI library based from construct-ui
83 lines (71 loc) • 2.27 kB
text/typescript
import m from 'mithril';
import { Tree, TreeNode, ITreeNodeAttrs, Popover, Icons, Menu, MenuItem, Classes, Icon } from '@/';
import { Example } from '@shared/examples';
import { data, IModel } from './data';
const EXAMPLE_SRC = 'components/tree/examples/index.ts';
export class TreeExample {
private expandedMap: Map<string | number, boolean>;
private selectedId: string | number | undefined;
public oninit() {
this.expandedMap = new Map();
}
public view() {
return m(Example, { center: false, src: EXAMPLE_SRC }, [
m(Tree, {
class: 'cui-example-tree-component',
nodes: data.map(item => this.renderNode(item))
})
]);
}
private renderNode(item: IModel): m.Vnode<ITreeNodeAttrs> {
const { children = [], id, type } = item;
const hasChildren = children.length !== 0;
const contentRight = m(Popover, {
hasArrow: false,
class: Classes.POPOVER_MENU,
closeOnContentClick: true,
content: m(Menu, [
m(MenuItem, {
iconLeft: Icons.COPY,
label: 'Copy'
}),
m(MenuItem, {
iconLeft: Icons.TRASH_2,
intent: 'negative',
label: 'Delete'
})
]),
position: 'bottom-end',
trigger: m(Icon, {
name: Icons.MORE_HORIZONTAL,
onclick: () => console.log(item)
})
});
const contentLeft = m(Icon, {
name: type === 'Folder' ? Icons.FOLDER : Icons.FILE_TEXT
});
return m(TreeNode, {
contentLeft,
contentRight: type === 'File' && contentRight,
children: children.map(child => this.renderNode(child)),
hasCaret: hasChildren,
label: `${type} ${id}`,
key: id,
isExpanded: this.expandedMap.has(id),
isSelected: this.selectedId === id,
onExpand: this.handleNodeExpand,
onCollapse: this.handleNodeCollapse,
onClick: this.handleClick
});
}
private handleNodeExpand = (node: ITreeNodeAttrs) => {
this.expandedMap.set(node.key, true);
}
private handleNodeCollapse = (node: ITreeNodeAttrs) => {
this.expandedMap.delete(node.key);
}
private handleClick = (node: ITreeNodeAttrs) => {
const id = node.key;
this.selectedId = this.selectedId === id ? undefined : id;
}
}