|
|
|
import LeftOutlined from '@ant-design/icons/LeftOutlined';
|
|
|
|
import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
|
|
|
|
import RightOutlined from '@ant-design/icons/RightOutlined';
|
|
|
|
import classNames from 'classnames';
|
|
|
|
import type {
|
|
|
|
BaseOptionType,
|
|
|
|
DefaultOptionType,
|
|
|
|
FieldNames,
|
|
|
|
MultipleCascaderProps as RcMultipleCascaderProps,
|
|
|
|
ShowSearchType,
|
|
|
|
SingleCascaderProps as RcSingleCascaderProps,
|
|
|
|
} from 'rc-cascader';
|
|
|
|
import RcCascader from 'rc-cascader';
|
|
|
|
import omit from 'rc-util/lib/omit';
|
|
|
|
import * as React from 'react';
|
|
|
|
import { ConfigContext } from '../config-provider';
|
|
|
|
import defaultRenderEmpty from '../config-provider/defaultRenderEmpty';
|
|
|
|
import DisabledContext from '../config-provider/DisabledContext';
|
|
|
|
import type { SizeType } from '../config-provider/SizeContext';
|
|
|
|
import SizeContext from '../config-provider/SizeContext';
|
|
|
|
import { useCompactItemContext } from '../space/Compact';
|
|
|
|
|
|
|
|
import { FormItemInputContext } from '../form/context';
|
|
|
|
import getIcons from '../select/utils/iconUtil';
|
|
|
|
import type { SelectCommonPlacement } from '../_util/motion';
|
|
|
|
import { getTransitionDirection, getTransitionName } from '../_util/motion';
|
|
|
|
import type { InputStatus } from '../_util/statusUtils';
|
|
|
|
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
|
|
|
|
import warning from '../_util/warning';
|
|
|
|
|
|
|
|
import useSelectStyle from '../select/style';
|
|
|
|
import useStyle from './style';
|
|
|
|
import genPurePanel from '../_util/PurePanel';
|
|
|
|
|
|
|
|
// Align the design since we use `rc-select` in root. This help:
|
|
|
|
// - List search content will show all content
|
|
|
|
// - Hover opacity style
|
|
|
|
// - Search filter match case
|
|
|
|
|
|
|
|
export { BaseOptionType, DefaultOptionType };
|
|
|
|
|
|
|
|
export type FieldNamesType = FieldNames;
|
|
|
|
|
|
|
|
export type FilledFieldNamesType = Required<FieldNamesType>;
|
|
|
|
|
|
|
|
const { SHOW_CHILD, SHOW_PARENT } = RcCascader;
|
|
|
|
|
|
|
|
function highlightKeyword(str: string, lowerKeyword: string, prefixCls: string | undefined) {
|
|
|
|
const cells = str
|
|
|
|
.toLowerCase()
|
|
|
|
.split(lowerKeyword)
|
|
|
|
.reduce((list, cur, index) => (index === 0 ? [cur] : [...list, lowerKeyword, cur]), []);
|
|
|
|
const fillCells: React.ReactNode[] = [];
|
|
|
|
let start = 0;
|
|
|
|
|
|
|
|
cells.forEach((cell, index) => {
|
|
|
|
const end = start + cell.length;
|
|
|
|
let originWorld: React.ReactNode = str.slice(start, end);
|
|
|
|
start = end;
|
|
|
|
|
|
|
|
if (index % 2 === 1) {
|
|
|
|
originWorld = (
|
|
|
|
// eslint-disable-next-line react/no-array-index-key
|
|
|
|
<span className={`${prefixCls}-menu-item-keyword`} key={`seperator-${index}`}>
|
|
|
|
{originWorld}
|
|
|
|
</span>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fillCells.push(originWorld);
|
|
|
|
});
|
|
|
|
|
|
|
|
return fillCells;
|
|
|
|
}
|
|
|
|
|
|
|
|
const defaultSearchRender: ShowSearchType['render'] = (inputValue, path, prefixCls, fieldNames) => {
|
|
|
|
const optionList: React.ReactNode[] = [];
|
|
|
|
|
|
|
|
// We do lower here to save perf
|
|
|
|
const lower = inputValue.toLowerCase();
|
|
|
|
|
|
|