import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { Icon } from '@alifd/next'; import CascaderMenu from './CascaderMenu'; import { AddressNode, NodeIDStrict, SelectionChain } from './Types'; import { nodeChainFromNode, selectionToId, getLabelIntl, getNodeLevelInTree, } from './Common'; import { AddressStore } from './AddressStore'; interface AddressEntryProps { node: AddressNode; onSelect: (node: AddressNode) => void; active: boolean; selected: boolean; maxLevel?: number; } class AddressEntry extends React.Component { static propTypes = { node: PropTypes.object, onSelect: PropTypes.func, active: PropTypes.bool, selected: PropTypes.bool, maxLevel: PropTypes.number, }; constructor(props: AddressEntryProps) { super(props); this.handleMenuClick = this.handleMenuClick.bind(this); } handleMenuClick() { typeof this.props.onSelect == 'function' && this.props.onSelect(this.props.node); } showArrow(props = this.props) { if (props.maxLevel && getNodeLevelInTree(props.node) >= props.maxLevel) { return false; } return !props.node.isLeaf; } render() { const { node, onSelect, active, selected, maxLevel, ...rest } = this.props; return ( {selected ? ( ) : null} {getLabelIntl(node)} {!this.showArrow() ? null : ( )} ); } } interface AddressIntlCascaderProps { value: SelectionChain; onChange: (value: NodeIDStrict) => any; rootNodeId: NodeIDStrict; maxLevel?: number; addressStore: AddressStore; } export default class AddressIntlCascader extends React.Component< AddressIntlCascaderProps, {} > { static propTypes = { value: PropTypes.arrayOf(PropTypes.string), onChange: PropTypes.func, rootNodeId: PropTypes.string, maxLevel: PropTypes.number, addressStore: PropTypes.object, }; static defaultProps = { value: [] }; activeChainSet: Set = new Set(); constructor(props: AddressIntlCascaderProps) { super(props); this.renderMenu = this.renderMenu.bind(this); this.handleSelect = this.handleSelect.bind(this); } handleSelect(node: AddressNode) { typeof this.props.onChange == 'function' && this.props.onChange(node.id); } renderMenu( node: AddressNode, zIndex: number, activeChainSet: Set ) { if (node.isLeaf) { return null; } else if (!node.children) { return null; } const selectedNodeId = selectionToId(this.props.value); return ( {node.children!.map(child => { return ( ); })} ); } render() { const nodeId = selectionToId(this.props.value); const node = this.props.addressStore.impl.getNodeByIdSync(nodeId)!; let nodeChain = nodeChainFromNode(node); const rootPos = nodeChain.findIndex(n => n.id == this.props.rootNodeId); if (rootPos != -1) { nodeChain = nodeChain.slice(rootPos); } this.activeChainSet = new Set(); nodeChain.forEach(v => this.activeChainSet.add(v.id)); const menus = nodeChain .filter( node => !this.props.maxLevel || getNodeLevelInTree(node) < this.props.maxLevel ) .map((node, idx) => this.renderMenu(node, nodeChain.length - idx + 12, this.activeChainSet) ); return {menus}; } }