mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-18 19:28:05 +08:00
Fix implicit any error for Cascader
This commit is contained in:
parent
2fe2e35a52
commit
ecaf3a0883
@ -23,7 +23,7 @@ Cascade selection box.
|
|||||||
| allowClear | whether allow clear | boolean | true |
|
| allowClear | whether allow clear | boolean | true |
|
||||||
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false |
|
| changeOnSelect | change value on each selection if set to true, see above demo for details | boolean | false |
|
||||||
| className | additional css class | string | - |
|
| className | additional css class | string | - |
|
||||||
| defaultValue | initial selected value | [CascaderOptionType](https://git.io/vMMoK)\[] | \[] |
|
| defaultValue | initial selected value | string\[] | \[] |
|
||||||
| disabled | whether disabled select | boolean | false |
|
| disabled | whether disabled select | boolean | false |
|
||||||
| displayRender | render function of displaying selected options | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
| displayRender | render function of displaying selected options | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
||||||
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
|
| expandTrigger | expand current item when click or hover, one of 'click' 'hover' | string | 'click' |
|
||||||
@ -37,7 +37,7 @@ Cascade selection box.
|
|||||||
| showSearch | Whether show search input in single mode. | boolean\|object | false |
|
| showSearch | Whether show search input in single mode. | boolean\|object | false |
|
||||||
| size | input size, one of `large` `default` `small` | string | `default` |
|
| size | input size, one of `large` `default` `small` | string | `default` |
|
||||||
| style | additional style | string | - |
|
| style | additional style | string | - |
|
||||||
| value | selected value | [CascaderOptionType](https://git.io/vMMoK)\[] | - |
|
| value | selected value | string\[] | - |
|
||||||
| onChange | callback when finishing cascader select | `(value, selectedOptions) => void` | - |
|
| onChange | callback when finishing cascader select | `(value, selectedOptions) => void` | - |
|
||||||
| onPopupVisibleChange | callback when popup shown or hidden | `(value) => void` | - |
|
| onPopupVisibleChange | callback when popup shown or hidden | `(value) => void` | - |
|
||||||
| popupVisible | set visible of cascader popup | boolean | - |
|
| popupVisible | set visible of cascader popup | boolean | - |
|
||||||
|
@ -9,16 +9,17 @@ import Icon from '../icon';
|
|||||||
|
|
||||||
export interface CascaderOptionType {
|
export interface CascaderOptionType {
|
||||||
value: string;
|
value: string;
|
||||||
label: string;
|
label: React.ReactNode;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
children?: Array<CascaderOptionType>;
|
children?: Array<CascaderOptionType>;
|
||||||
|
__IS_FILTERED_OPTION?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CascaderExpandTrigger = 'click' | 'hover';
|
export type CascaderExpandTrigger = 'click' | 'hover';
|
||||||
|
|
||||||
export interface ShowSearchType {
|
export interface ShowSearchType {
|
||||||
filter?: (inputValue: string, path: CascaderOptionType[]) => boolean;
|
filter?: (inputValue: string, path: CascaderOptionType[]) => boolean;
|
||||||
render?: (inputValue: string, path: CascaderOptionType[], prefixCls: string) => React.ReactNode;
|
render?: (inputValue: string, path: CascaderOptionType[], prefixCls: string | undefined) => React.ReactNode;
|
||||||
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number;
|
sort?: (a: CascaderOptionType[], b: CascaderOptionType[], inputValue: string) => number;
|
||||||
matchInputWidth?: boolean;
|
matchInputWidth?: boolean;
|
||||||
}
|
}
|
||||||
@ -27,9 +28,9 @@ export interface CascaderProps {
|
|||||||
/** 可选项数据源 */
|
/** 可选项数据源 */
|
||||||
options: CascaderOptionType[];
|
options: CascaderOptionType[];
|
||||||
/** 默认的选中项 */
|
/** 默认的选中项 */
|
||||||
defaultValue?: CascaderOptionType[];
|
defaultValue?: string[];
|
||||||
/** 指定选中项 */
|
/** 指定选中项 */
|
||||||
value?: CascaderOptionType[];
|
value?: string[];
|
||||||
/** 选择完成后的回调 */
|
/** 选择完成后的回调 */
|
||||||
onChange?: (value: string[], selectedOptions?: CascaderOptionType[]) => void;
|
onChange?: (value: string[], selectedOptions?: CascaderOptionType[]) => void;
|
||||||
/** 选择后展示的渲染函数 */
|
/** 选择后展示的渲染函数 */
|
||||||
@ -62,9 +63,18 @@ export interface CascaderProps {
|
|||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
inputPrefixCls?: string;
|
inputPrefixCls?: string;
|
||||||
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
|
||||||
|
popupVisible?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function highlightKeyword(str: string, keyword: string, prefixCls: string) {
|
export interface CascaderState {
|
||||||
|
inputFocused: boolean;
|
||||||
|
inputValue: string;
|
||||||
|
value: string[];
|
||||||
|
popupVisible: boolean | undefined;
|
||||||
|
flattenOptions: CascaderOptionType[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
|
||||||
return str.split(keyword)
|
return str.split(keyword)
|
||||||
.map((node: string, index: number) => index === 0 ? node : [
|
.map((node: string, index: number) => index === 0 ? node : [
|
||||||
<span className={`${prefixCls}-menu-item-keyword`} key="seperator">{keyword}</span>,
|
<span className={`${prefixCls}-menu-item-keyword`} key="seperator">{keyword}</span>,
|
||||||
@ -72,28 +82,29 @@ function highlightKeyword(str: string, keyword: string, prefixCls: string) {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultFilterOption(inputValue, path) {
|
function defaultFilterOption(inputValue: string, path: CascaderOptionType[]) {
|
||||||
return path.some(option => option.label.indexOf(inputValue) > -1);
|
return path.some(option => (option.label as string).indexOf(inputValue) > -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultRenderFilteredOption(inputValue, path, prefixCls) {
|
function defaultRenderFilteredOption(inputValue: string, path: CascaderOptionType[], prefixCls: string | undefined) {
|
||||||
return path.map(({ label }, index) => {
|
return path.map(({ label }, index) => {
|
||||||
const node = label.indexOf(inputValue) > -1 ? highlightKeyword(label, inputValue, prefixCls) : label;
|
const node = (label as string).indexOf(inputValue) > -1 ?
|
||||||
|
highlightKeyword(label as string, inputValue, prefixCls) : label;
|
||||||
return index === 0 ? node : [' / ', node];
|
return index === 0 ? node : [' / ', node];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function defaultSortFilteredOption(a, b, inputValue) {
|
function defaultSortFilteredOption(a: any[], b: any[], inputValue: string) {
|
||||||
function callback(elem) {
|
function callback(elem: CascaderOptionType) {
|
||||||
return elem.label.indexOf(inputValue) > -1;
|
return (elem.label as string).indexOf(inputValue) > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.findIndex(callback) - b.findIndex(callback);
|
return a.findIndex(callback) - b.findIndex(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDisplayRender = label => label.join(' / ');
|
const defaultDisplayRender = (label: string[]) => label.join(' / ');
|
||||||
|
|
||||||
export default class Cascader extends React.Component<CascaderProps, any> {
|
export default class Cascader extends React.Component<CascaderProps, CascaderState> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
prefixCls: 'ant-cascader',
|
prefixCls: 'ant-cascader',
|
||||||
inputPrefixCls: 'ant-input',
|
inputPrefixCls: 'ant-input',
|
||||||
@ -110,7 +121,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
|
|
||||||
private input: Input;
|
private input: Input;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: CascaderProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
value: props.value || props.defaultValue || [],
|
value: props.value || props.defaultValue || [],
|
||||||
@ -121,7 +132,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps: CascaderProps) {
|
||||||
if ('value' in nextProps) {
|
if ('value' in nextProps) {
|
||||||
this.setState({ value: nextProps.value || [] });
|
this.setState({ value: nextProps.value || [] });
|
||||||
}
|
}
|
||||||
@ -133,7 +144,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChange = (value, selectedOptions) => {
|
handleChange = (value: any, selectedOptions: any[]) => {
|
||||||
this.setState({ inputValue: '' });
|
this.setState({ inputValue: '' });
|
||||||
if (selectedOptions[0].__IS_FILTERED_OPTION) {
|
if (selectedOptions[0].__IS_FILTERED_OPTION) {
|
||||||
const unwrappedValue = value[0];
|
const unwrappedValue = value[0];
|
||||||
@ -144,7 +155,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
this.setValue(value, selectedOptions);
|
this.setValue(value, selectedOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopupVisibleChange = (popupVisible) => {
|
handlePopupVisibleChange = (popupVisible: boolean) => {
|
||||||
if (!('popupVisible' in this.props)) {
|
if (!('popupVisible' in this.props)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
popupVisible,
|
popupVisible,
|
||||||
@ -165,7 +176,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputClick = (e) => {
|
handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {
|
||||||
const { inputFocused, popupVisible } = this.state;
|
const { inputFocused, popupVisible } = this.state;
|
||||||
// Prevent `Trigger` behaviour.
|
// Prevent `Trigger` behaviour.
|
||||||
if (inputFocused || popupVisible) {
|
if (inputFocused || popupVisible) {
|
||||||
@ -174,18 +185,18 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
if (e.keyCode === KeyCode.BACKSPACE) {
|
if (e.keyCode === KeyCode.BACKSPACE) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInputChange = (e) => {
|
handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const inputValue = e.target.value;
|
const inputValue = e.target.value;
|
||||||
this.setState({ inputValue });
|
this.setState({ inputValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue = (value, selectedOptions = []) => {
|
setValue = (value: string[], selectedOptions: any[] = []) => {
|
||||||
if (!('value' in this.props)) {
|
if (!('value' in this.props)) {
|
||||||
this.setState({ value });
|
this.setState({ value });
|
||||||
}
|
}
|
||||||
@ -199,12 +210,14 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
const { options, displayRender = defaultDisplayRender as Function } = this.props;
|
const { options, displayRender = defaultDisplayRender as Function } = this.props;
|
||||||
const value = this.state.value;
|
const value = this.state.value;
|
||||||
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
|
||||||
const selectedOptions = arrayTreeFilter(options, (o, level) => o.value === unwrappedValue[level]);
|
const selectedOptions: CascaderOptionType[] = arrayTreeFilter(options,
|
||||||
|
(o: CascaderOptionType, level: number) => o.value === unwrappedValue[level],
|
||||||
|
);
|
||||||
const label = selectedOptions.map(o => o.label);
|
const label = selectedOptions.map(o => o.label);
|
||||||
return displayRender(label, selectedOptions);
|
return displayRender(label, selectedOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSelection = (e) => {
|
clearSelection = (e: React.MouseEvent<HTMLElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (!this.state.inputValue) {
|
if (!this.state.inputValue) {
|
||||||
@ -215,7 +228,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flattenTree(options, changeOnSelect, ancestor = []) {
|
flattenTree(options: CascaderOptionType[], changeOnSelect: boolean | undefined, ancestor: CascaderOptionType[] = []) {
|
||||||
let flattenOptions: any = [];
|
let flattenOptions: any = [];
|
||||||
options.forEach((option) => {
|
options.forEach((option) => {
|
||||||
const path = ancestor.concat(option);
|
const path = ancestor.concat(option);
|
||||||
@ -229,7 +242,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
return flattenOptions;
|
return flattenOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateFilteredOptions(prefixCls) {
|
generateFilteredOptions(prefixCls: string | undefined) {
|
||||||
const { showSearch, notFoundContent } = this.props;
|
const { showSearch, notFoundContent } = this.props;
|
||||||
const {
|
const {
|
||||||
filter = defaultFilterOption,
|
filter = defaultFilterOption,
|
||||||
@ -241,14 +254,14 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
.sort((a, b) => sort(a, b, inputValue));
|
.sort((a, b) => sort(a, b, inputValue));
|
||||||
|
|
||||||
if (filtered.length > 0) {
|
if (filtered.length > 0) {
|
||||||
return filtered.map((path) => {
|
return filtered.map((path: any) => {
|
||||||
return {
|
return {
|
||||||
__IS_FILTERED_OPTION: true,
|
__IS_FILTERED_OPTION: true,
|
||||||
path,
|
path,
|
||||||
label: render(inputValue, path, prefixCls),
|
label: render(inputValue, path, prefixCls),
|
||||||
value: path.map(o => o.value),
|
value: path.map((o: CascaderOptionType) => o.value),
|
||||||
disabled: path.some(o => o.disabled),
|
disabled: path.some((o: CascaderOptionType) => o.disabled),
|
||||||
};
|
} as CascaderOptionType;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return [{ label: notFoundContent, value: 'ANT_CASCADER_NOT_FOUND', disabled: true }];
|
return [{ label: notFoundContent, value: 'ANT_CASCADER_NOT_FOUND', disabled: true }];
|
||||||
@ -262,7 +275,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
|
|||||||
this.input.blur();
|
this.input.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
saveInput = (node) => {
|
saveInput = (node: Input) => {
|
||||||
this.input = node;
|
this.input = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ subtitle: 级联选择
|
|||||||
| allowClear | 是否支持清除 | boolean | true |
|
| allowClear | 是否支持清除 | boolean | true |
|
||||||
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false |
|
| changeOnSelect | 当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false |
|
||||||
| className | 自定义类名 | string | - |
|
| className | 自定义类名 | string | - |
|
||||||
| defaultValue | 默认的选中项 | [CascaderOptionType](https://git.io/vMMoK)\[] | \[] |
|
| defaultValue | 默认的选中项 | string\[] | \[] |
|
||||||
| disabled | 禁用 | boolean | false |
|
| disabled | 禁用 | boolean | false |
|
||||||
| displayRender | 选择后展示的渲染函数 | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
| displayRender | 选择后展示的渲染函数 | `(label, selectedOptions) => ReactNode` | `label => label.join(' / ')` |
|
||||||
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
|
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | 'click' |
|
||||||
@ -38,7 +38,7 @@ subtitle: 级联选择
|
|||||||
| showSearch | 在选择框中显示搜索框 | boolean | false |
|
| showSearch | 在选择框中显示搜索框 | boolean | false |
|
||||||
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
|
| size | 输入框大小,可选 `large` `default` `small` | string | `default` |
|
||||||
| style | 自定义样式 | string | - |
|
| style | 自定义样式 | string | - |
|
||||||
| value | 指定选中项 | [CascaderOptionType](https://git.io/vMMoK)\[] | - |
|
| value | 指定选中项 | string\[] | - |
|
||||||
| onChange | 选择完成后的回调 | `(value, selectedOptions) => void` | - |
|
| onChange | 选择完成后的回调 | `(value, selectedOptions) => void` | - |
|
||||||
| onPopupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - |
|
| onPopupVisibleChange | 显示/隐藏浮层的回调 | `(value) => void` | - |
|
||||||
| popupVisible | 控制浮层显隐 | boolean | - |
|
| popupVisible | 控制浮层显隐 | boolean | - |
|
||||||
|
Loading…
Reference in New Issue
Block a user