import * as React from "react"; import * as _ from "lodash"; import styled, { StyledComponentClass } from "styled-components"; import DefaultCheckBox, { CheckBox } from "../Checkbox"; import { COLOR_PALETTE } from "../../constants/colors"; import * as DefaultStyles from "./style"; import { CheckItem } from "../../types/global" export namespace HierarchyList { export interface State { openItems: { id: boolean }; } /** * TODO: We need the check clicked, items, and checkedItems props to be required * right now they are optional for if you want to use this component to make a custom layout * for the list picker you don't need to initalize the default props because the list picker does that * Want to have an internal/external representation of this component with the req/optional props */ export interface Props { checkClicked?: (item) => void; items?: CheckItem[]; styles?: HierarchyList.Styles; checkedItems?: CheckItem[]; keyPrefix?: string; readonly?: boolean; checkBox?: (props: CheckBox.Props) => JSX.Element; id?: string; name?: string; } export interface Styles { CheckListOuterContainer?: any; CheckListContainer?: any; ChildrenContainer?: any; CheckItemContainer?: any; Value?: any; RotatingArrow?: any; } } const defaultState = { openItems: { id: false }, }; class HierarchyList extends React.Component< HierarchyList.Props, HierarchyList.State > { constructor(props: HierarchyList.Props) { super(props); this.state = defaultState; } private toggleOpen = (id: string): void => { const openItems = _.clone(this.state.openItems); openItems[id] = !openItems[id]; this.setState({ openItems }); }; private isSelected(id: string): boolean { return Boolean( this.props.checkedItems && this.props.checkedItems.find(item => item.id === id) ); } private renderChildren = (Styles: HierarchyList.Styles, item: CheckItem, indentation: number) => { const open = this.state.openItems[item.id]; const hasChildren = Boolean(item.children.length); const CheckBox = this.props.checkBox || DefaultCheckBox; const key = `${this.props.keyPrefix}-${item.id}`; return ( this.toggleOpen(item.id)} clickable={hasChildren} indentation={indentation} bgColor={ indentation ? COLOR_PALETTE.BLUE_LIGHT_1 : COLOR_PALETTE.BLUE_LIGHT_4 } id={this.props.id && this.props.id + '-check-item-container'} name={this.props.name && this.props.name + '-check-item-container'} > this.props.checkClicked ? this.props.checkClicked(item) : null } value={this.isSelected(item.id)} id={this.props.id ? this.props.id : item.name} name={this.props.name && this.props.name} /> {item.name} {hasChildren && ( )} {open && item.children.map(child => this.renderChildren(Styles, child, indentation + 1) )} ); }; public render(): JSX.Element { const Styles: HierarchyList.Styles = _.merge(DefaultStyles, this.props.styles); return ( {_.map(this.props.items, item => this.renderChildren(Styles, item, 0) )} ); } } export default HierarchyList;