|
|
@ -4,6 +4,7 @@ import arrayTreeFilter from 'array-tree-filter'; |
|
|
|
import classNames from 'classnames'; |
|
|
|
import omit from 'omit.js'; |
|
|
|
import KeyCode from 'rc-util/lib/KeyCode'; |
|
|
|
import { polyfill } from 'react-lifecycles-compat'; |
|
|
|
import Input from '../input'; |
|
|
|
import Icon from '../icon'; |
|
|
|
import { ConfigConsumer, ConfigProviderProps } from '../config-provider'; |
|
|
@ -103,6 +104,7 @@ export interface CascaderState { |
|
|
|
value: string[]; |
|
|
|
popupVisible: boolean | undefined; |
|
|
|
flattenOptions: CascaderOptionType[][] | undefined; |
|
|
|
prevProps: CascaderProps; |
|
|
|
} |
|
|
|
|
|
|
|
interface CascaderLocale { |
|
|
@ -180,9 +182,29 @@ function getFilledFieldNames(props: CascaderProps) { |
|
|
|
return names; |
|
|
|
} |
|
|
|
|
|
|
|
function flattenTree( |
|
|
|
options: CascaderOptionType[], |
|
|
|
props: CascaderProps, |
|
|
|
ancestor: CascaderOptionType[] = [], |
|
|
|
) { |
|
|
|
const names: FilledFieldNamesType = getFilledFieldNames(props); |
|
|
|
let flattenOptions = [] as CascaderOptionType[][]; |
|
|
|
const childrenName = names.children; |
|
|
|
options.forEach(option => { |
|
|
|
const path = ancestor.concat(option); |
|
|
|
if (props.changeOnSelect || !option[childrenName] || !option[childrenName].length) { |
|
|
|
flattenOptions.push(path); |
|
|
|
} |
|
|
|
if (option[childrenName]) { |
|
|
|
flattenOptions = flattenOptions.concat(flattenTree(option[childrenName], props, path)); |
|
|
|
} |
|
|
|
}); |
|
|
|
return flattenOptions; |
|
|
|
} |
|
|
|
|
|
|
|
const defaultDisplayRender = (label: string[]) => label.join(' / '); |
|
|
|
|
|
|
|
export default class Cascader extends React.Component<CascaderProps, CascaderState> { |
|
|
|
class Cascader extends React.Component<CascaderProps, CascaderState> { |
|
|
|
static defaultProps = { |
|
|
|
prefixCls: 'ant-cascader', |
|
|
|
inputPrefixCls: 'ant-input', |
|
|
@ -194,6 +216,24 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta |
|
|
|
notFoundContent: 'Not Found', |
|
|
|
}; |
|
|
|
|
|
|
|
static getDerivedStateFromProps(nextProps: CascaderProps, { prevProps }: CascaderState) { |
|
|
|
const newState: Partial<CascaderState> = { |
|
|
|
prevProps: nextProps, |
|
|
|
}; |
|
|
|
|
|
|
|
if ('value' in nextProps) { |
|
|
|
newState.value = nextProps.value || []; |
|
|
|
} |
|
|
|
if ('popupVisible' in nextProps) { |
|
|
|
newState.popupVisible = nextProps.popupVisible; |
|
|
|
} |
|
|
|
if (nextProps.showSearch && prevProps.options !== nextProps.options) { |
|
|
|
newState.flattenOptions = flattenTree(nextProps.options, nextProps); |
|
|
|
} |
|
|
|
|
|
|
|
return newState; |
|
|
|
} |
|
|
|
|
|
|
|
cachedOptions: CascaderOptionType[]; |
|
|
|
|
|
|
|
private input: Input; |
|
|
@ -205,24 +245,11 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta |
|
|
|
inputValue: '', |
|
|
|
inputFocused: false, |
|
|
|
popupVisible: props.popupVisible, |
|
|
|
flattenOptions: props.showSearch ? this.flattenTree(props.options, props) : undefined, |
|
|
|
flattenOptions: props.showSearch ? flattenTree(props.options, props) : undefined, |
|
|
|
prevProps: props, |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps: CascaderProps) { |
|
|
|
if ('value' in nextProps) { |
|
|
|
this.setState({ value: nextProps.value || [] }); |
|
|
|
} |
|
|
|
if ('popupVisible' in nextProps) { |
|
|
|
this.setState({ popupVisible: nextProps.popupVisible }); |
|
|
|
} |
|
|
|
if (nextProps.showSearch && this.props.options !== nextProps.options) { |
|
|
|
this.setState({ |
|
|
|
flattenOptions: this.flattenTree(nextProps.options, nextProps), |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => { |
|
|
|
this.setState({ inputValue: '' }); |
|
|
|
if (selectedOptions[0].__IS_FILTERED_OPTION) { |
|
|
@ -312,26 +339,6 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
flattenTree( |
|
|
|
options: CascaderOptionType[], |
|
|
|
props: CascaderProps, |
|
|
|
ancestor: CascaderOptionType[] = [], |
|
|
|
) { |
|
|
|
const names: FilledFieldNamesType = getFilledFieldNames(props); |
|
|
|
let flattenOptions = [] as CascaderOptionType[][]; |
|
|
|
const childrenName = names.children; |
|
|
|
options.forEach(option => { |
|
|
|
const path = ancestor.concat(option); |
|
|
|
if (props.changeOnSelect || !option[childrenName] || !option[childrenName].length) { |
|
|
|
flattenOptions.push(path); |
|
|
|
} |
|
|
|
if (option[childrenName]) { |
|
|
|
flattenOptions = flattenOptions.concat(this.flattenTree(option[childrenName], props, path)); |
|
|
|
} |
|
|
|
}); |
|
|
|
return flattenOptions; |
|
|
|
} |
|
|
|
|
|
|
|
generateFilteredOptions(prefixCls: string | undefined) { |
|
|
|
const { showSearch, notFoundContent } = this.props; |
|
|
|
const names: FilledFieldNamesType = getFilledFieldNames(this.props); |
|
|
@ -564,3 +571,7 @@ export default class Cascader extends React.Component<CascaderProps, CascaderSta |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
polyfill(Cascader); |
|
|
|
|
|
|
|
export default Cascader; |
|
|
|