import {themeable} from '../theme'; import React from 'react'; import {uncontrollable} from 'uncontrollable'; import Checkbox from './Checkbox'; import {Option} from './Select'; import {autobind, eachTree, everyTree} from '../utils/helper'; import Spinner from './Spinner'; import {BaseRadiosProps, BaseRadios} from './ListRadios'; import {localeable} from '../locale'; import {Icon} from './icons'; export interface TreeRadiosProps extends BaseRadiosProps { expand: 'all' | 'first' | 'root' | 'none'; } export interface TreeRadiosState { expanded: Array; } export class TreeRadios extends BaseRadios { state: TreeRadiosState = { expanded: [] }; static defaultProps = { ...BaseRadios.defaultProps, expand: 'first' as 'first' }; componentDidMount() { this.syncExpanded(); } componentDidUpdate(prevProps: TreeRadiosProps) { const props = this.props; if ( !this.state.expanded.length && (props.expand !== prevProps.expand || props.options !== prevProps.options) ) { this.syncExpanded(); } } syncExpanded() { const options = this.props.options; const mode = this.props.expand; const expanded: Array = []; if (!Array.isArray(options)) { return; } if (mode === 'first' || mode === 'root') { options.every((option, index) => { if (Array.isArray(option.children)) { expanded.push(`${index}`); return mode === 'root'; } return true; }); } else if (mode === 'all') { everyTree(options, (option, index, level, paths, indexes) => { if (Array.isArray(option.children)) { expanded.push(`${indexes.concat(index).join('-')}`); } return true; }); } this.setState({expanded}); } toggleCollapsed(option: Option, index: string) { const onDeferLoad = this.props.onDeferLoad; const expanded = this.state.expanded.concat(); const idx = expanded.indexOf(index); if (~idx) { expanded.splice(idx, 1); } else { expanded.push(index); } this.setState( { expanded: expanded }, option.defer && onDeferLoad ? () => onDeferLoad(option) : undefined ); } renderItem(option: Option, index: number, indexes: Array = []) { const { disabled, classnames: cx, itemClassName, itemRender, showRadio } = this.props; const id = indexes.join('-'); let hasChildren = Array.isArray(option.children) && option.children.length; const checked = option === this.selected; const expaned = !!~this.state.expanded.indexOf(id); return (
this.toggleOption(option)} > {hasChildren || option.defer ? ( ) => { e.stopPropagation(); this.toggleCollapsed(option, id); }} className={cx('Table-expandBtn', expaned ? 'is-active' : '')} > ) : null}
{itemRender(option)}
{option.defer && option.loading ? : null} {(!option.defer || option.loaded) && option.value !== undefined && showRadio !== false ? ( ) : null}
{hasChildren ? (
{option.children!.map((option, key) => this.renderItem(option, key, indexes.concat(key)) )}
) : null}
); } render() { const { value, options, className, placeholder, classnames: cx, option2value, translate: __ } = this.props; this.selected = BaseRadios.resolveSelected(value, options, option2value); let body: Array = []; if (Array.isArray(options) && options.length) { body = options.map((option, key) => this.renderItem(option, key, [key])); } return (
{body && body.length ? ( body ) : (
{__(placeholder)}
)}
); } } export default themeable( localeable( uncontrollable(TreeRadios, { value: 'onChange' }) ) );