@rc-component/cascader 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +300 -0
  3. package/assets/index.less +3 -0
  4. package/assets/list.less +106 -0
  5. package/assets/panel.less +7 -0
  6. package/assets/select.less +3 -0
  7. package/es/Cascader.d.ts +88 -0
  8. package/es/Cascader.js +230 -0
  9. package/es/OptionList/CacheContent.d.ts +7 -0
  10. package/es/OptionList/CacheContent.js +8 -0
  11. package/es/OptionList/Checkbox.d.ts +10 -0
  12. package/es/OptionList/Checkbox.js +24 -0
  13. package/es/OptionList/Column.d.ts +21 -0
  14. package/es/OptionList/Column.js +175 -0
  15. package/es/OptionList/List.d.ts +6 -0
  16. package/es/OptionList/List.js +216 -0
  17. package/es/OptionList/index.d.ts +4 -0
  18. package/es/OptionList/index.js +13 -0
  19. package/es/OptionList/useActive.d.ts +6 -0
  20. package/es/OptionList/useActive.js +26 -0
  21. package/es/OptionList/useKeyboard.d.ts +10 -0
  22. package/es/OptionList/useKeyboard.js +165 -0
  23. package/es/Panel.d.ts +5 -0
  24. package/es/Panel.js +116 -0
  25. package/es/context.d.ts +21 -0
  26. package/es/context.js +3 -0
  27. package/es/hooks/useDisplayValues.d.ts +10 -0
  28. package/es/hooks/useDisplayValues.js +44 -0
  29. package/es/hooks/useEntities.d.ts +10 -0
  30. package/es/hooks/useEntities.js +35 -0
  31. package/es/hooks/useMissingValues.d.ts +3 -0
  32. package/es/hooks/useMissingValues.js +17 -0
  33. package/es/hooks/useOptions.d.ts +9 -0
  34. package/es/hooks/useOptions.js +20 -0
  35. package/es/hooks/useSearchConfig.d.ts +2 -0
  36. package/es/hooks/useSearchConfig.js +27 -0
  37. package/es/hooks/useSearchOptions.d.ts +4 -0
  38. package/es/hooks/useSearchOptions.js +63 -0
  39. package/es/hooks/useSelect.d.ts +4 -0
  40. package/es/hooks/useSelect.js +49 -0
  41. package/es/hooks/useValues.d.ts +9 -0
  42. package/es/hooks/useValues.js +21 -0
  43. package/es/index.d.ts +5 -0
  44. package/es/index.js +4 -0
  45. package/es/utils/commonUtil.d.ts +18 -0
  46. package/es/utils/commonUtil.js +69 -0
  47. package/es/utils/treeUtil.d.ts +9 -0
  48. package/es/utils/treeUtil.js +35 -0
  49. package/es/utils/warningPropsUtil.d.ts +4 -0
  50. package/es/utils/warningPropsUtil.js +29 -0
  51. package/lib/Cascader.d.ts +88 -0
  52. package/lib/Cascader.js +239 -0
  53. package/lib/OptionList/CacheContent.d.ts +7 -0
  54. package/lib/OptionList/CacheContent.js +16 -0
  55. package/lib/OptionList/Checkbox.d.ts +10 -0
  56. package/lib/OptionList/Checkbox.js +33 -0
  57. package/lib/OptionList/Column.d.ts +21 -0
  58. package/lib/OptionList/Column.js +185 -0
  59. package/lib/OptionList/List.d.ts +6 -0
  60. package/lib/OptionList/List.js +224 -0
  61. package/lib/OptionList/index.d.ts +4 -0
  62. package/lib/OptionList/index.js +22 -0
  63. package/lib/OptionList/useActive.d.ts +6 -0
  64. package/lib/OptionList/useActive.js +34 -0
  65. package/lib/OptionList/useKeyboard.d.ts +10 -0
  66. package/lib/OptionList/useKeyboard.js +175 -0
  67. package/lib/Panel.d.ts +5 -0
  68. package/lib/Panel.js +125 -0
  69. package/lib/context.d.ts +21 -0
  70. package/lib/context.js +11 -0
  71. package/lib/hooks/useDisplayValues.d.ts +10 -0
  72. package/lib/hooks/useDisplayValues.js +53 -0
  73. package/lib/hooks/useEntities.d.ts +10 -0
  74. package/lib/hooks/useEntities.js +44 -0
  75. package/lib/hooks/useMissingValues.d.ts +3 -0
  76. package/lib/hooks/useMissingValues.js +25 -0
  77. package/lib/hooks/useOptions.d.ts +9 -0
  78. package/lib/hooks/useOptions.js +29 -0
  79. package/lib/hooks/useSearchConfig.d.ts +2 -0
  80. package/lib/hooks/useSearchConfig.js +36 -0
  81. package/lib/hooks/useSearchOptions.d.ts +4 -0
  82. package/lib/hooks/useSearchOptions.js +71 -0
  83. package/lib/hooks/useSelect.d.ts +4 -0
  84. package/lib/hooks/useSelect.js +55 -0
  85. package/lib/hooks/useValues.d.ts +9 -0
  86. package/lib/hooks/useValues.js +29 -0
  87. package/lib/index.d.ts +5 -0
  88. package/lib/index.js +16 -0
  89. package/lib/utils/commonUtil.d.ts +18 -0
  90. package/lib/utils/commonUtil.js +83 -0
  91. package/lib/utils/treeUtil.d.ts +9 -0
  92. package/lib/utils/treeUtil.js +42 -0
  93. package/lib/utils/warningPropsUtil.d.ts +4 -0
  94. package/lib/utils/warningPropsUtil.js +37 -0
  95. package/package.json +88 -0
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ import { convertDataToEntities } from "rc-tree/es/utils/treeUtil";
3
+ import { VALUE_SPLIT } from "../utils/commonUtil";
4
+ /** Lazy parse options data into conduct-able info to avoid perf issue in single mode */
5
+ export default ((options, fieldNames) => {
6
+ const cacheRef = React.useRef({
7
+ options: [],
8
+ info: {
9
+ keyEntities: {},
10
+ pathKeyEntities: {}
11
+ }
12
+ });
13
+ const getEntities = React.useCallback(() => {
14
+ if (cacheRef.current.options !== options) {
15
+ cacheRef.current.options = options;
16
+ cacheRef.current.info = convertDataToEntities(options, {
17
+ fieldNames: fieldNames,
18
+ initWrapper: wrapper => ({
19
+ ...wrapper,
20
+ pathKeyEntities: {}
21
+ }),
22
+ processEntity: (entity, wrapper) => {
23
+ const pathKey = entity.nodes.map(node => node[fieldNames.value]).join(VALUE_SPLIT);
24
+ wrapper.pathKeyEntities[pathKey] = entity;
25
+
26
+ // Overwrite origin key.
27
+ // this is very hack but we need let conduct logic work with connect path
28
+ entity.key = pathKey;
29
+ }
30
+ });
31
+ }
32
+ return cacheRef.current.info.pathKeyEntities;
33
+ }, [fieldNames, options]);
34
+ return getEntities;
35
+ });
@@ -0,0 +1,3 @@
1
+ import type { DefaultOptionType, InternalFieldNames, SingleValueType } from '../Cascader';
2
+ export type GetMissValues = ReturnType<typeof useMissingValues>;
3
+ export default function useMissingValues(options: DefaultOptionType[], fieldNames: InternalFieldNames): (rawValues: SingleValueType[]) => [SingleValueType[], SingleValueType[]];
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { toPathOptions } from "../utils/treeUtil";
3
+ export default function useMissingValues(options, fieldNames) {
4
+ return React.useCallback(rawValues => {
5
+ const missingValues = [];
6
+ const existsValues = [];
7
+ rawValues.forEach(valueCell => {
8
+ const pathOptions = toPathOptions(valueCell, options, fieldNames);
9
+ if (pathOptions.every(opt => opt.option)) {
10
+ existsValues.push(valueCell);
11
+ } else {
12
+ missingValues.push(valueCell);
13
+ }
14
+ });
15
+ return [existsValues, missingValues];
16
+ }, [options, fieldNames]);
17
+ }
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import type { DefaultOptionType } from '..';
3
+ import type { InternalFieldNames, SingleValueType } from '../Cascader';
4
+ import { type GetEntities } from './useEntities';
5
+ export default function useOptions(mergedFieldNames: InternalFieldNames, options?: DefaultOptionType[]): [
6
+ mergedOptions: DefaultOptionType[],
7
+ getPathKeyEntities: GetEntities,
8
+ getValueByKeyPath: (pathKeys: React.Key[]) => SingleValueType[]
9
+ ];
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import useEntities from "./useEntities";
3
+ export default function useOptions(mergedFieldNames, options) {
4
+ const mergedOptions = React.useMemo(() => options || [], [options]);
5
+
6
+ // Only used in multiple mode, this fn will not call in single mode
7
+ const getPathKeyEntities = useEntities(mergedOptions, mergedFieldNames);
8
+
9
+ /** Convert path key back to value format */
10
+ const getValueByKeyPath = React.useCallback(pathKeys => {
11
+ const keyPathEntities = getPathKeyEntities();
12
+ return pathKeys.map(pathKey => {
13
+ const {
14
+ nodes
15
+ } = keyPathEntities[pathKey];
16
+ return nodes.map(node => node[mergedFieldNames.value]);
17
+ });
18
+ }, [getPathKeyEntities, mergedFieldNames]);
19
+ return [mergedOptions, getPathKeyEntities, getValueByKeyPath];
20
+ }
@@ -0,0 +1,2 @@
1
+ import type { CascaderProps, ShowSearchType } from '../Cascader';
2
+ export default function useSearchConfig(showSearch?: CascaderProps['showSearch']): [boolean, ShowSearchType<import("../Cascader").DefaultOptionType, string>];
@@ -0,0 +1,27 @@
1
+ import warning from "@rc-component/util/es/warning";
2
+ import * as React from 'react';
3
+ // Convert `showSearch` to unique config
4
+ export default function useSearchConfig(showSearch) {
5
+ return React.useMemo(() => {
6
+ if (!showSearch) {
7
+ return [false, {}];
8
+ }
9
+ let searchConfig = {
10
+ matchInputWidth: true,
11
+ limit: 50
12
+ };
13
+ if (showSearch && typeof showSearch === 'object') {
14
+ searchConfig = {
15
+ ...searchConfig,
16
+ ...showSearch
17
+ };
18
+ }
19
+ if (searchConfig.limit <= 0) {
20
+ searchConfig.limit = false;
21
+ if (process.env.NODE_ENV !== 'production') {
22
+ warning(false, "'limit' of showSearch should be positive number or false.");
23
+ }
24
+ }
25
+ return [true, searchConfig];
26
+ }, [showSearch]);
27
+ }
@@ -0,0 +1,4 @@
1
+ import type { DefaultOptionType, InternalFieldNames, ShowSearchType } from '../Cascader';
2
+ export declare const SEARCH_MARK = "__rc_cascader_search_mark__";
3
+ declare const useSearchOptions: (search: string, options: DefaultOptionType[], fieldNames: InternalFieldNames, prefixCls: string, config: ShowSearchType, enableHalfPath?: boolean) => DefaultOptionType[];
4
+ export default useSearchOptions;
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ export const SEARCH_MARK = '__rc_cascader_search_mark__';
3
+ const defaultFilter = (search, options, {
4
+ label = ''
5
+ }) => options.some(opt => String(opt[label]).toLowerCase().includes(search.toLowerCase()));
6
+ const defaultRender = (inputValue, path, prefixCls, fieldNames) => path.map(opt => opt[fieldNames.label]).join(' / ');
7
+ const useSearchOptions = (search, options, fieldNames, prefixCls, config, enableHalfPath) => {
8
+ const {
9
+ filter = defaultFilter,
10
+ render = defaultRender,
11
+ limit = 50,
12
+ sort
13
+ } = config;
14
+ return React.useMemo(() => {
15
+ const filteredOptions = [];
16
+ if (!search) {
17
+ return [];
18
+ }
19
+ function dig(list, pathOptions, parentDisabled = false) {
20
+ list.forEach(option => {
21
+ // Perf saving when `sort` is disabled and `limit` is provided
22
+ if (!sort && limit !== false && limit > 0 && filteredOptions.length >= limit) {
23
+ return;
24
+ }
25
+ const connectedPathOptions = [...pathOptions, option];
26
+ const children = option[fieldNames.children];
27
+ const mergedDisabled = parentDisabled || option.disabled;
28
+
29
+ // If current option is filterable
30
+ if (
31
+ // If is leaf option
32
+ !children || children.length === 0 ||
33
+ // If is changeOnSelect or multiple
34
+ enableHalfPath) {
35
+ if (filter(search, connectedPathOptions, {
36
+ label: fieldNames.label
37
+ })) {
38
+ filteredOptions.push({
39
+ ...option,
40
+ disabled: mergedDisabled,
41
+ [fieldNames.label]: render(search, connectedPathOptions, prefixCls, fieldNames),
42
+ [SEARCH_MARK]: connectedPathOptions,
43
+ [fieldNames.children]: undefined
44
+ });
45
+ }
46
+ }
47
+ if (children) {
48
+ dig(option[fieldNames.children], connectedPathOptions, mergedDisabled);
49
+ }
50
+ });
51
+ }
52
+ dig(options, []);
53
+
54
+ // Do sort
55
+ if (sort) {
56
+ filteredOptions.sort((a, b) => {
57
+ return sort(a[SEARCH_MARK], b[SEARCH_MARK], search, fieldNames);
58
+ });
59
+ }
60
+ return limit !== false && limit > 0 ? filteredOptions.slice(0, limit) : filteredOptions;
61
+ }, [search, options, fieldNames, prefixCls, render, enableHalfPath, filter, sort, limit]);
62
+ };
63
+ export default useSearchOptions;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import type { InternalValueType, ShowCheckedStrategy, SingleValueType } from '../Cascader';
3
+ import type { GetEntities } from './useEntities';
4
+ export default function useSelect(multiple: boolean, triggerChange: (nextValues: InternalValueType) => void, checkedValues: SingleValueType[], halfCheckedValues: SingleValueType[], missingCheckedValues: SingleValueType[], getPathKeyEntities: GetEntities, getValueByKeyPath: (pathKeys: React.Key[]) => SingleValueType[], showCheckedStrategy?: ShowCheckedStrategy): (valuePath: SingleValueType) => void;
@@ -0,0 +1,49 @@
1
+ import { conductCheck } from "rc-tree/es/utils/conductUtil";
2
+ import { toPathKey, toPathKeys } from "../utils/commonUtil";
3
+ import { formatStrategyValues } from "../utils/treeUtil";
4
+ export default function useSelect(multiple, triggerChange, checkedValues, halfCheckedValues, missingCheckedValues, getPathKeyEntities, getValueByKeyPath, showCheckedStrategy) {
5
+ return valuePath => {
6
+ if (!multiple) {
7
+ triggerChange(valuePath);
8
+ } else {
9
+ // Prepare conduct required info
10
+ const pathKey = toPathKey(valuePath);
11
+ const checkedPathKeys = toPathKeys(checkedValues);
12
+ const halfCheckedPathKeys = toPathKeys(halfCheckedValues);
13
+ const existInChecked = checkedPathKeys.includes(pathKey);
14
+ const existInMissing = missingCheckedValues.some(valueCells => toPathKey(valueCells) === pathKey);
15
+
16
+ // Do update
17
+ let nextCheckedValues = checkedValues;
18
+ let nextMissingValues = missingCheckedValues;
19
+ if (existInMissing && !existInChecked) {
20
+ // Missing value only do filter
21
+ nextMissingValues = missingCheckedValues.filter(valueCells => toPathKey(valueCells) !== pathKey);
22
+ } else {
23
+ // Update checked key first
24
+ const nextRawCheckedKeys = existInChecked ? checkedPathKeys.filter(key => key !== pathKey) : [...checkedPathKeys, pathKey];
25
+ const pathKeyEntities = getPathKeyEntities();
26
+
27
+ // Conduction by selected or not
28
+ let checkedKeys;
29
+ if (existInChecked) {
30
+ ({
31
+ checkedKeys
32
+ } = conductCheck(nextRawCheckedKeys, {
33
+ checked: false,
34
+ halfCheckedKeys: halfCheckedPathKeys
35
+ }, pathKeyEntities));
36
+ } else {
37
+ ({
38
+ checkedKeys
39
+ } = conductCheck(nextRawCheckedKeys, true, pathKeyEntities));
40
+ }
41
+
42
+ // Roll up to parent level keys
43
+ const deDuplicatedKeys = formatStrategyValues(checkedKeys, getPathKeyEntities, showCheckedStrategy);
44
+ nextCheckedValues = getValueByKeyPath(deDuplicatedKeys);
45
+ }
46
+ triggerChange([...nextMissingValues, ...nextCheckedValues]);
47
+ }
48
+ };
49
+ }
@@ -0,0 +1,9 @@
1
+ import type { DataEntity } from 'rc-tree/lib/interface';
2
+ import * as React from 'react';
3
+ import type { SingleValueType } from '../Cascader';
4
+ import type { GetMissValues } from './useMissingValues';
5
+ export default function useValues(multiple: boolean, rawValues: SingleValueType[], getPathKeyEntities: () => Record<string, DataEntity>, getValueByKeyPath: (pathKeys: React.Key[]) => SingleValueType[], getMissingValues: GetMissValues): [
6
+ checkedValues: SingleValueType[],
7
+ halfCheckedValues: SingleValueType[],
8
+ missingCheckedValues: SingleValueType[]
9
+ ];
@@ -0,0 +1,21 @@
1
+ import { conductCheck } from "rc-tree/es/utils/conductUtil";
2
+ import * as React from 'react';
3
+ import { toPathKeys } from "../utils/commonUtil";
4
+ export default function useValues(multiple, rawValues, getPathKeyEntities, getValueByKeyPath, getMissingValues) {
5
+ // Fill `rawValues` with checked conduction values
6
+ return React.useMemo(() => {
7
+ const [existValues, missingValues] = getMissingValues(rawValues);
8
+ if (!multiple || !rawValues.length) {
9
+ return [existValues, [], missingValues];
10
+ }
11
+ const keyPathValues = toPathKeys(existValues);
12
+ const keyPathEntities = getPathKeyEntities();
13
+ const {
14
+ checkedKeys,
15
+ halfCheckedKeys
16
+ } = conductCheck(keyPathValues, true, keyPathEntities);
17
+
18
+ // Convert key back to value cells
19
+ return [getValueByKeyPath(checkedKeys), getValueByKeyPath(halfCheckedKeys), missingValues];
20
+ }, [multiple, rawValues, getPathKeyEntities, getValueByKeyPath, getMissingValues]);
21
+ }
package/es/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import Cascader from './Cascader';
2
+ import Panel from './Panel';
3
+ export type { BaseOptionType, DefaultOptionType, CascaderProps, FieldNames, ShowSearchType, CascaderRef, } from './Cascader';
4
+ export { Panel };
5
+ export default Cascader;
package/es/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import Cascader from "./Cascader";
2
+ import Panel from "./Panel";
3
+ export { Panel };
4
+ export default Cascader;
@@ -0,0 +1,18 @@
1
+ import type { DefaultOptionType, FieldNames, InternalFieldNames, InternalValueType, SingleValueType } from '../Cascader';
2
+ export declare const VALUE_SPLIT = "__RC_CASCADER_SPLIT__";
3
+ export declare const SHOW_PARENT = "SHOW_PARENT";
4
+ export declare const SHOW_CHILD = "SHOW_CHILD";
5
+ /**
6
+ * Will convert value to string, and join with `VALUE_SPLIT`
7
+ */
8
+ export declare function toPathKey(value: SingleValueType): string;
9
+ /**
10
+ * Batch convert value to string, and join with `VALUE_SPLIT`
11
+ */
12
+ export declare function toPathKeys(value: SingleValueType[]): string[];
13
+ export declare function toPathValueStr(pathKey: string): string[];
14
+ export declare function fillFieldNames(fieldNames?: FieldNames): InternalFieldNames;
15
+ export declare function isLeaf(option: DefaultOptionType, fieldNames: FieldNames): any;
16
+ export declare function scrollIntoParentView(element: HTMLElement): void;
17
+ export declare function getFullPathKeys(options: DefaultOptionType[], fieldNames: FieldNames): any[];
18
+ export declare function toRawValues(value?: InternalValueType): SingleValueType[];
@@ -0,0 +1,69 @@
1
+ import { SEARCH_MARK } from "../hooks/useSearchOptions";
2
+ export const VALUE_SPLIT = '__RC_CASCADER_SPLIT__';
3
+ export const SHOW_PARENT = 'SHOW_PARENT';
4
+ export const SHOW_CHILD = 'SHOW_CHILD';
5
+
6
+ /**
7
+ * Will convert value to string, and join with `VALUE_SPLIT`
8
+ */
9
+ export function toPathKey(value) {
10
+ return value.join(VALUE_SPLIT);
11
+ }
12
+
13
+ /**
14
+ * Batch convert value to string, and join with `VALUE_SPLIT`
15
+ */
16
+ export function toPathKeys(value) {
17
+ return value.map(toPathKey);
18
+ }
19
+ export function toPathValueStr(pathKey) {
20
+ return pathKey.split(VALUE_SPLIT);
21
+ }
22
+ export function fillFieldNames(fieldNames) {
23
+ const {
24
+ label,
25
+ value,
26
+ children
27
+ } = fieldNames || {};
28
+ const val = value || 'value';
29
+ return {
30
+ label: label || 'label',
31
+ value: val,
32
+ key: val,
33
+ children: children || 'children'
34
+ };
35
+ }
36
+ export function isLeaf(option, fieldNames) {
37
+ return option.isLeaf ?? !option[fieldNames.children]?.length;
38
+ }
39
+ export function scrollIntoParentView(element) {
40
+ const parent = element.parentElement;
41
+ if (!parent) {
42
+ return;
43
+ }
44
+ const elementToParent = element.offsetTop - parent.offsetTop; // offsetParent may not be parent.
45
+ if (elementToParent - parent.scrollTop < 0) {
46
+ parent.scrollTo({
47
+ top: elementToParent
48
+ });
49
+ } else if (elementToParent + element.offsetHeight - parent.scrollTop > parent.offsetHeight) {
50
+ parent.scrollTo({
51
+ top: elementToParent + element.offsetHeight - parent.offsetHeight
52
+ });
53
+ }
54
+ }
55
+ export function getFullPathKeys(options, fieldNames) {
56
+ return options.map(item => item[SEARCH_MARK]?.map(opt => opt[fieldNames.value]));
57
+ }
58
+ function isMultipleValue(value) {
59
+ return Array.isArray(value) && Array.isArray(value[0]);
60
+ }
61
+ export function toRawValues(value) {
62
+ if (!value) {
63
+ return [];
64
+ }
65
+ if (isMultipleValue(value)) {
66
+ return value;
67
+ }
68
+ return (value.length === 0 ? [] : [value]).map(val => Array.isArray(val) ? val : [val]);
69
+ }
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" />
2
+ import type { SingleValueType, DefaultOptionType, InternalFieldNames, ShowCheckedStrategy } from '../Cascader';
3
+ import type { GetEntities } from '../hooks/useEntities';
4
+ export declare function formatStrategyValues(pathKeys: React.Key[], getKeyPathEntities: GetEntities, showCheckedStrategy?: ShowCheckedStrategy): import("react").Key[];
5
+ export declare function toPathOptions(valueCells: SingleValueType, options: DefaultOptionType[], fieldNames: InternalFieldNames, stringMode?: boolean): {
6
+ value: SingleValueType[number];
7
+ index: number;
8
+ option: DefaultOptionType;
9
+ }[];
@@ -0,0 +1,35 @@
1
+ import { SHOW_CHILD } from "./commonUtil";
2
+ export function formatStrategyValues(pathKeys, getKeyPathEntities, showCheckedStrategy) {
3
+ const valueSet = new Set(pathKeys);
4
+ const keyPathEntities = getKeyPathEntities();
5
+ return pathKeys.filter(key => {
6
+ const entity = keyPathEntities[key];
7
+ const parent = entity ? entity.parent : null;
8
+ const children = entity ? entity.children : null;
9
+ if (entity && entity.node.disabled) {
10
+ return true;
11
+ }
12
+ return showCheckedStrategy === SHOW_CHILD ? !(children && children.some(child => child.key && valueSet.has(child.key))) : !(parent && !parent.node.disabled && valueSet.has(parent.key));
13
+ });
14
+ }
15
+ export function toPathOptions(valueCells, options, fieldNames,
16
+ // Used for loadingKeys which saved loaded keys as string
17
+ stringMode = false) {
18
+ let currentList = options;
19
+ const valueOptions = [];
20
+ for (let i = 0; i < valueCells.length; i += 1) {
21
+ const valueCell = valueCells[i];
22
+ const foundIndex = currentList?.findIndex(option => {
23
+ const val = option[fieldNames.value];
24
+ return stringMode ? String(val) === String(valueCell) : val === valueCell;
25
+ });
26
+ const foundOption = foundIndex !== -1 ? currentList?.[foundIndex] : null;
27
+ valueOptions.push({
28
+ value: foundOption?.[fieldNames.value] ?? valueCell,
29
+ index: foundIndex,
30
+ option: foundOption
31
+ });
32
+ currentList = foundOption?.[fieldNames.children];
33
+ }
34
+ return valueOptions;
35
+ }
@@ -0,0 +1,4 @@
1
+ import type { DefaultOptionType, FieldNames, InternalCascaderProps } from '../Cascader';
2
+ declare function warningProps(props: InternalCascaderProps): void;
3
+ export declare function warningNullOptions(options: DefaultOptionType[], fieldNames: FieldNames): void;
4
+ export default warningProps;
@@ -0,0 +1,29 @@
1
+ import warning from "@rc-component/util/es/warning";
2
+ function warningProps(props) {
3
+ const {
4
+ popupVisible,
5
+ popupPlacement
6
+ } = props;
7
+ warning(popupVisible === undefined, '`popupVisible` is deprecated. Please use `open` instead.');
8
+ warning(popupPlacement === undefined, '`popupPlacement` is deprecated. Please use `placement` instead.');
9
+ }
10
+
11
+ // value in Cascader options should not be null
12
+ export function warningNullOptions(options, fieldNames) {
13
+ if (options) {
14
+ const recursiveOptions = optionsList => {
15
+ for (let i = 0; i < optionsList.length; i++) {
16
+ const option = optionsList[i];
17
+ if (option[fieldNames?.value] === null) {
18
+ warning(false, '`value` in Cascader options should not be `null`.');
19
+ return true;
20
+ }
21
+ if (Array.isArray(option[fieldNames?.children]) && recursiveOptions(option[fieldNames?.children])) {
22
+ return true;
23
+ }
24
+ }
25
+ };
26
+ recursiveOptions(options);
27
+ }
28
+ }
29
+ export default warningProps;
@@ -0,0 +1,88 @@
1
+ import type { BuildInPlacements } from '@rc-component/trigger/lib/interface';
2
+ import type { BaseSelectPropsWithoutPrivate, BaseSelectRef } from '@rc-component/select';
3
+ import type { Placement } from '@rc-component/select/lib/BaseSelect';
4
+ import * as React from 'react';
5
+ import Panel from './Panel';
6
+ import { SHOW_CHILD, SHOW_PARENT } from './utils/commonUtil';
7
+ export interface BaseOptionType {
8
+ disabled?: boolean;
9
+ disableCheckbox?: boolean;
10
+ label?: React.ReactNode;
11
+ value?: string | number | null;
12
+ children?: DefaultOptionType[];
13
+ }
14
+ export type DefaultOptionType = BaseOptionType & Record<string, any>;
15
+ export interface ShowSearchType<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType> {
16
+ filter?: (inputValue: string, options: OptionType[], fieldNames: FieldNames<OptionType, ValueField>) => boolean;
17
+ render?: (inputValue: string, path: OptionType[], prefixCls: string, fieldNames: FieldNames<OptionType, ValueField>) => React.ReactNode;
18
+ sort?: (a: OptionType[], b: OptionType[], inputValue: string, fieldNames: FieldNames<OptionType, ValueField>) => number;
19
+ matchInputWidth?: boolean;
20
+ limit?: number | false;
21
+ }
22
+ export type ShowCheckedStrategy = typeof SHOW_PARENT | typeof SHOW_CHILD;
23
+ interface BaseCascaderProps<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType> extends Omit<BaseSelectPropsWithoutPrivate, 'tokenSeparators' | 'labelInValue' | 'mode' | 'showSearch'> {
24
+ id?: string;
25
+ prefixCls?: string;
26
+ fieldNames?: FieldNames<OptionType, ValueField>;
27
+ optionRender?: (option: OptionType) => React.ReactNode;
28
+ children?: React.ReactElement;
29
+ changeOnSelect?: boolean;
30
+ displayRender?: (label: string[], selectedOptions?: OptionType[]) => React.ReactNode;
31
+ checkable?: boolean | React.ReactNode;
32
+ showCheckedStrategy?: ShowCheckedStrategy;
33
+ autoClearSearchValue?: boolean;
34
+ showSearch?: boolean | ShowSearchType<OptionType>;
35
+ searchValue?: string;
36
+ onSearch?: (value: string) => void;
37
+ expandTrigger?: 'hover' | 'click';
38
+ options?: OptionType[];
39
+ /** @private Internal usage. Do not use in your production. */
40
+ dropdownPrefixCls?: string;
41
+ loadData?: (selectOptions: OptionType[]) => void;
42
+ /** @deprecated Use `open` instead */
43
+ popupVisible?: boolean;
44
+ popupClassName?: string;
45
+ dropdownMenuColumnStyle?: React.CSSProperties;
46
+ /** @deprecated Use `placement` instead */
47
+ popupPlacement?: Placement;
48
+ placement?: Placement;
49
+ builtinPlacements?: BuildInPlacements;
50
+ onPopupVisibleChange?: (open: boolean) => void;
51
+ expandIcon?: React.ReactNode;
52
+ loadingIcon?: React.ReactNode;
53
+ }
54
+ export interface FieldNames<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType> {
55
+ label?: keyof OptionType;
56
+ value?: keyof OptionType | ValueField;
57
+ children?: keyof OptionType;
58
+ }
59
+ export type ValueType<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType> = keyof OptionType extends ValueField ? unknown extends OptionType['value'] ? OptionType[ValueField] : OptionType['value'] : OptionType[ValueField];
60
+ export type GetValueType<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType, Multiple extends boolean | React.ReactNode = false> = false extends Multiple ? ValueType<Required<OptionType>, ValueField>[] : ValueType<Required<OptionType>, ValueField>[][];
61
+ export interface CascaderProps<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType, Multiple extends boolean | React.ReactNode = false> extends BaseCascaderProps<OptionType, ValueField> {
62
+ checkable?: Multiple;
63
+ value?: GetValueType<OptionType, ValueField, Multiple>;
64
+ defaultValue?: GetValueType<OptionType, ValueField, Multiple>;
65
+ onChange?: (value: GetValueType<OptionType, ValueField, Multiple>, selectOptions: OptionType[]) => void;
66
+ }
67
+ export type SingleValueType = (string | number)[];
68
+ export type InternalValueType = SingleValueType | SingleValueType[];
69
+ export interface InternalFieldNames extends Required<FieldNames> {
70
+ key: string;
71
+ }
72
+ export type InternalCascaderProps = Omit<CascaderProps, 'onChange' | 'value' | 'defaultValue'> & {
73
+ value?: InternalValueType;
74
+ defaultValue?: InternalValueType;
75
+ onChange?: (value: InternalValueType, selectOptions: BaseOptionType[] | BaseOptionType[][]) => void;
76
+ };
77
+ export type CascaderRef = Omit<BaseSelectRef, 'scrollTo'>;
78
+ declare const Cascader: (<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType, Multiple extends React.ReactNode = false>(props: CascaderProps<OptionType, ValueField, Multiple> & {
79
+ children?: React.ReactNode;
80
+ } & {
81
+ ref?: React.Ref<CascaderRef> | undefined;
82
+ }) => React.ReactElement) & {
83
+ displayName?: string | undefined;
84
+ SHOW_PARENT: typeof SHOW_PARENT;
85
+ SHOW_CHILD: typeof SHOW_CHILD;
86
+ Panel: typeof Panel;
87
+ };
88
+ export default Cascader;