You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
11 KiB

import React from 'react';
import RcCascader from 'rc-cascader';
9 years ago
import Input from '../input';
9 years ago
import Icon from '../icon';
9 years ago
import arrayTreeFilter from 'array-tree-filter';
import classNames from 'classnames';
import splitObject from '../_util/splitObject';
import omit from 'omit.js';
9 years ago
export interface CascaderOptionType {
value: string;
label: string;
disabled?: boolean;
children?: Array<CascaderOptionType>;
}
9 years ago
export type CascaderExpandTrigger = 'click' | 'hover'
export interface ShowSearchType {
filter?: (inputValue: string, path: CascaderOptionType[]) => boolean;
render?: (inputValue: string, path: CascaderOptionType[], prefixCls: string) => React.ReactNode;
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number;
matchInputWidth?: boolean;
}
9 years ago
export interface CascaderProps {
/** 可选项数据源 */
options: Array<CascaderOptionType>;
/** 默认的选中项 */
defaultValue?: Array<CascaderOptionType>;
/** 指定选中项 */
value?: Array<CascaderOptionType>;
/** 选择完成后的回调 */
onChange?: (value: string, selectedOptions?: Array<CascaderOptionType>) => void;
/** 选择后展示的渲染函数 */
displayRender?: (label: Array<string>, selectedOptions?: Array<CascaderOptionType>) => React.ReactNode;
/** 自定义样式 */
style?: React.CSSProperties;
/** 自定义类名 */
className?: string;
/** 自定义浮层类名 */
popupClassName?: string;
/** 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` */
popupPlacement?: string;
/** 输入框占位文本*/
placeholder?: string;
/** 输入框大小,可选 `large` `default` `small` */
size?: string;
/** 禁用*/
disabled?: boolean;
/** 是否支持清除*/
allowClear?: boolean;
showSearch?: boolean | ShowSearchType;
notFoundContent?: React.ReactNode;
/** 次级菜单的展开方式,可选 'click' 和 'hover' */
expandTrigger?: CascaderExpandTrigger;
/** 当此项为 true 时,点选每级菜单选项值都会发生变化 */
changeOnSelect?: boolean;
/** 浮层可见变化时回调 */
onPopupVisibleChange?: (popupVisible: boolean) => void;
prefixCls?: string;
inputPrefixCls?: string;
}
function highlightKeyword(str: string, keyword: string, prefixCls: string) {
return str.split(keyword)
.map((node: string, index: number) => index === 0 ? node : [
<span className={`${prefixCls}-menu-item-keyword`} key="seperator">{keyword}</span>,
node,
]);
}
function defaultFilterOption(inputValue, path) {
return path.some(option => option.label.indexOf(inputValue) > -1);
}
function defaultRenderFilteredOption(inputValue, path, prefixCls) {
return path.map(({ label }, index) => {
const node = label.indexOf(inputValue) > -1 ? highlightKeyword(label, inputValue, prefixCls) : label;
return index === 0 ? node : [' / ', node];
});
}
function defaultSortFilteredOption(a, b, inputValue) {
function callback(elem) {
return elem.label.indexOf(inputValue) > -1;
}
return a.findIndex(callback) - b.findIndex(callback);
}