@rc-component/select 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.
- package/LICENSE.md +9 -0
- package/README.md +191 -0
- package/assets/index.css +306 -0
- package/assets/index.less +397 -0
- package/es/BaseSelect/Polite.d.ts +7 -0
- package/es/BaseSelect/Polite.js +26 -0
- package/es/BaseSelect/index.d.ts +118 -0
- package/es/BaseSelect/index.js +569 -0
- package/es/OptGroup.d.ts +12 -0
- package/es/OptGroup.js +6 -0
- package/es/Option.d.ts +14 -0
- package/es/Option.js +6 -0
- package/es/OptionList.d.ts +10 -0
- package/es/OptionList.js +379 -0
- package/es/Select.d.ts +114 -0
- package/es/Select.js +480 -0
- package/es/SelectContext.d.ts +23 -0
- package/es/SelectContext.js +6 -0
- package/es/SelectTrigger.d.ts +30 -0
- package/es/SelectTrigger.js +138 -0
- package/es/Selector/Input.d.ts +27 -0
- package/es/Selector/Input.js +114 -0
- package/es/Selector/MultipleSelector.d.ts +16 -0
- package/es/Selector/MultipleSelector.js +185 -0
- package/es/Selector/SingleSelector.d.ts +8 -0
- package/es/Selector/SingleSelector.js +104 -0
- package/es/Selector/index.d.ts +85 -0
- package/es/Selector/index.js +184 -0
- package/es/TransBtn.d.ts +12 -0
- package/es/TransBtn.js +30 -0
- package/es/hooks/useAllowClear.d.ts +8 -0
- package/es/hooks/useAllowClear.js +26 -0
- package/es/hooks/useBaseProps.d.ts +13 -0
- package/es/hooks/useBaseProps.js +10 -0
- package/es/hooks/useCache.d.ts +7 -0
- package/es/hooks/useCache.js +40 -0
- package/es/hooks/useDelayReset.d.ts +5 -0
- package/es/hooks/useDelayReset.js +24 -0
- package/es/hooks/useFilterOptions.d.ts +3 -0
- package/es/hooks/useFilterOptions.js +57 -0
- package/es/hooks/useId.d.ts +5 -0
- package/es/hooks/useId.js +29 -0
- package/es/hooks/useLayoutEffect.d.ts +5 -0
- package/es/hooks/useLayoutEffect.js +17 -0
- package/es/hooks/useLock.d.ts +7 -0
- package/es/hooks/useLock.js +27 -0
- package/es/hooks/useOptions.d.ts +12 -0
- package/es/hooks/useOptions.js +45 -0
- package/es/hooks/useRefFunc.d.ts +5 -0
- package/es/hooks/useRefFunc.js +14 -0
- package/es/hooks/useSelectTriggerControl.d.ts +1 -0
- package/es/hooks/useSelectTriggerControl.js +27 -0
- package/es/index.d.ts +10 -0
- package/es/index.js +7 -0
- package/es/interface.d.ts +23 -0
- package/es/interface.js +1 -0
- package/es/utils/__mocks__/platformUtil.d.ts +1 -0
- package/es/utils/__mocks__/platformUtil.js +3 -0
- package/es/utils/commonUtil.d.ts +9 -0
- package/es/utils/commonUtil.js +32 -0
- package/es/utils/keyUtil.d.ts +2 -0
- package/es/utils/keyUtil.js +16 -0
- package/es/utils/legacyUtil.d.ts +3 -0
- package/es/utils/legacyUtil.js +44 -0
- package/es/utils/platformUtil.d.ts +1 -0
- package/es/utils/platformUtil.js +4 -0
- package/es/utils/valueUtil.d.ts +24 -0
- package/es/utils/valueUtil.js +128 -0
- package/es/utils/warningPropsUtil.d.ts +4 -0
- package/es/utils/warningPropsUtil.js +119 -0
- package/lib/BaseSelect/Polite.d.ts +7 -0
- package/lib/BaseSelect/Polite.js +34 -0
- package/lib/BaseSelect/index.d.ts +118 -0
- package/lib/BaseSelect/index.js +579 -0
- package/lib/OptGroup.d.ts +12 -0
- package/lib/OptGroup.js +12 -0
- package/lib/Option.d.ts +14 -0
- package/lib/Option.js +12 -0
- package/lib/OptionList.d.ts +10 -0
- package/lib/OptionList.js +387 -0
- package/lib/Select.d.ts +114 -0
- package/lib/Select.js +487 -0
- package/lib/SelectContext.d.ts +23 -0
- package/lib/SelectContext.js +13 -0
- package/lib/SelectTrigger.d.ts +30 -0
- package/lib/SelectTrigger.js +147 -0
- package/lib/Selector/Input.d.ts +27 -0
- package/lib/Selector/Input.js +123 -0
- package/lib/Selector/MultipleSelector.d.ts +16 -0
- package/lib/Selector/MultipleSelector.js +194 -0
- package/lib/Selector/SingleSelector.d.ts +8 -0
- package/lib/Selector/SingleSelector.js +113 -0
- package/lib/Selector/index.d.ts +85 -0
- package/lib/Selector/index.js +191 -0
- package/lib/TransBtn.d.ts +12 -0
- package/lib/TransBtn.js +39 -0
- package/lib/hooks/useAllowClear.d.ts +8 -0
- package/lib/hooks/useAllowClear.js +34 -0
- package/lib/hooks/useBaseProps.d.ts +13 -0
- package/lib/hooks/useBaseProps.js +19 -0
- package/lib/hooks/useCache.d.ts +7 -0
- package/lib/hooks/useCache.js +49 -0
- package/lib/hooks/useDelayReset.d.ts +5 -0
- package/lib/hooks/useDelayReset.js +31 -0
- package/lib/hooks/useFilterOptions.d.ts +3 -0
- package/lib/hooks/useFilterOptions.js +66 -0
- package/lib/hooks/useId.d.ts +5 -0
- package/lib/hooks/useId.js +40 -0
- package/lib/hooks/useLayoutEffect.d.ts +5 -0
- package/lib/hooks/useLayoutEffect.js +25 -0
- package/lib/hooks/useLock.d.ts +7 -0
- package/lib/hooks/useLock.js +34 -0
- package/lib/hooks/useOptions.d.ts +12 -0
- package/lib/hooks/useOptions.js +52 -0
- package/lib/hooks/useRefFunc.d.ts +5 -0
- package/lib/hooks/useRefFunc.js +21 -0
- package/lib/hooks/useSelectTriggerControl.d.ts +1 -0
- package/lib/hooks/useSelectTriggerControl.js +35 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.js +37 -0
- package/lib/interface.d.ts +23 -0
- package/lib/interface.js +5 -0
- package/lib/utils/__mocks__/platformUtil.d.ts +1 -0
- package/lib/utils/__mocks__/platformUtil.js +9 -0
- package/lib/utils/commonUtil.d.ts +9 -0
- package/lib/utils/commonUtil.js +42 -0
- package/lib/utils/keyUtil.d.ts +2 -0
- package/lib/utils/keyUtil.js +22 -0
- package/lib/utils/legacyUtil.d.ts +3 -0
- package/lib/utils/legacyUtil.js +53 -0
- package/lib/utils/platformUtil.d.ts +1 -0
- package/lib/utils/platformUtil.js +10 -0
- package/lib/utils/valueUtil.d.ts +24 -0
- package/lib/utils/valueUtil.js +140 -0
- package/lib/utils/warningPropsUtil.d.ts +4 -0
- package/lib/utils/warningPropsUtil.js +129 -0
- package/package.json +86 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type RawValueType = string | number;
|
|
3
|
+
export interface FlattenOptionData<OptionType> {
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
data: OptionType;
|
|
6
|
+
key: React.Key;
|
|
7
|
+
value?: RawValueType;
|
|
8
|
+
groupOption?: boolean;
|
|
9
|
+
group?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface DisplayValueType {
|
|
12
|
+
key?: React.Key;
|
|
13
|
+
value?: RawValueType;
|
|
14
|
+
label?: React.ReactNode;
|
|
15
|
+
title?: React.ReactNode;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
index?: number;
|
|
18
|
+
}
|
|
19
|
+
export type RenderNode = React.ReactNode | ((props: any) => React.ReactNode);
|
|
20
|
+
export type RenderDOMFunc = (props: any) => HTMLElement;
|
|
21
|
+
export type Mode = 'multiple' | 'tags' | 'combobox';
|
|
22
|
+
export type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
|
|
23
|
+
export type DisplayInfoType = 'add' | 'remove' | 'clear';
|
package/es/interface.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isPlatformMac(): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DisplayValueType } from '../BaseSelect';
|
|
2
|
+
export declare function toArray<T>(value: T | T[]): T[];
|
|
3
|
+
export declare const isClient: HTMLElement;
|
|
4
|
+
/** Is client side and not jsdom */
|
|
5
|
+
export declare const isBrowserClient: HTMLElement;
|
|
6
|
+
export declare function hasValue(value: any): boolean;
|
|
7
|
+
/** combo mode no value judgment function */
|
|
8
|
+
export declare function isComboNoValue(value: any): boolean;
|
|
9
|
+
export declare function getTitle(item: DisplayValueType): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function toArray(value) {
|
|
2
|
+
if (Array.isArray(value)) {
|
|
3
|
+
return value;
|
|
4
|
+
}
|
|
5
|
+
return value !== undefined ? [value] : [];
|
|
6
|
+
}
|
|
7
|
+
export const isClient = typeof window !== 'undefined' && window.document && window.document.documentElement;
|
|
8
|
+
|
|
9
|
+
/** Is client side and not jsdom */
|
|
10
|
+
export const isBrowserClient = process.env.NODE_ENV !== 'test' && isClient;
|
|
11
|
+
export function hasValue(value) {
|
|
12
|
+
return value !== undefined && value !== null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** combo mode no value judgment function */
|
|
16
|
+
export function isComboNoValue(value) {
|
|
17
|
+
return !value && value !== 0;
|
|
18
|
+
}
|
|
19
|
+
function isTitleType(title) {
|
|
20
|
+
return ['string', 'number'].includes(typeof title);
|
|
21
|
+
}
|
|
22
|
+
export function getTitle(item) {
|
|
23
|
+
let title = undefined;
|
|
24
|
+
if (item) {
|
|
25
|
+
if (isTitleType(item.title)) {
|
|
26
|
+
title = item.title.toString();
|
|
27
|
+
} else if (isTitleType(item.label)) {
|
|
28
|
+
title = item.label.toString();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return title;
|
|
32
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import KeyCode from "@rc-component/util/es/KeyCode";
|
|
2
|
+
|
|
3
|
+
/** keyCode Judgment function */
|
|
4
|
+
export function isValidateOpenKey(currentKeyCode) {
|
|
5
|
+
return (
|
|
6
|
+
// Undefined for Edge bug:
|
|
7
|
+
// https://github.com/ant-design/ant-design/issues/51292
|
|
8
|
+
currentKeyCode &&
|
|
9
|
+
// Other keys
|
|
10
|
+
![
|
|
11
|
+
// System function button
|
|
12
|
+
KeyCode.ESC, KeyCode.SHIFT, KeyCode.BACKSPACE, KeyCode.TAB, KeyCode.WIN_KEY, KeyCode.ALT, KeyCode.META, KeyCode.WIN_KEY_RIGHT, KeyCode.CTRL, KeyCode.SEMICOLON, KeyCode.EQUALS, KeyCode.CAPS_LOCK, KeyCode.CONTEXT_MENU,
|
|
13
|
+
// F1-F12
|
|
14
|
+
KeyCode.F1, KeyCode.F2, KeyCode.F3, KeyCode.F4, KeyCode.F5, KeyCode.F6, KeyCode.F7, KeyCode.F8, KeyCode.F9, KeyCode.F10, KeyCode.F11, KeyCode.F12].includes(currentKeyCode)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import toArray from "@rc-component/util/es/Children/toArray";
|
|
3
|
+
function convertNodeToOption(node) {
|
|
4
|
+
const {
|
|
5
|
+
key,
|
|
6
|
+
props: {
|
|
7
|
+
children,
|
|
8
|
+
value,
|
|
9
|
+
...restProps
|
|
10
|
+
}
|
|
11
|
+
} = node;
|
|
12
|
+
return {
|
|
13
|
+
key,
|
|
14
|
+
value: value !== undefined ? value : key,
|
|
15
|
+
children,
|
|
16
|
+
...restProps
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function convertChildrenToData(nodes, optionOnly = false) {
|
|
20
|
+
return toArray(nodes).map((node, index) => {
|
|
21
|
+
if (! /*#__PURE__*/React.isValidElement(node) || !node.type) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const {
|
|
25
|
+
type: {
|
|
26
|
+
isSelectOptGroup
|
|
27
|
+
},
|
|
28
|
+
key,
|
|
29
|
+
props: {
|
|
30
|
+
children,
|
|
31
|
+
...restProps
|
|
32
|
+
}
|
|
33
|
+
} = node;
|
|
34
|
+
if (optionOnly || !isSelectOptGroup) {
|
|
35
|
+
return convertNodeToOption(node);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
key: `__RC_SELECT_GRP__${key === null ? index : key}__`,
|
|
39
|
+
label: key,
|
|
40
|
+
...restProps,
|
|
41
|
+
options: convertChildrenToData(children)
|
|
42
|
+
};
|
|
43
|
+
}).filter(data => data);
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isPlatformMac(): boolean;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BaseOptionType, DefaultOptionType } from '../Select';
|
|
2
|
+
import type { FieldNames } from '../Select';
|
|
3
|
+
import type { FlattenOptionData } from '../interface';
|
|
4
|
+
export declare function isValidCount(value?: number): boolean;
|
|
5
|
+
export declare function fillFieldNames(fieldNames: FieldNames | undefined, childrenAsData: boolean): {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
options: string;
|
|
9
|
+
groupLabel: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Flat options into flatten list.
|
|
13
|
+
* We use `optionOnly` here is aim to avoid user use nested option group.
|
|
14
|
+
* Here is simply set `key` to the index if not provided.
|
|
15
|
+
*/
|
|
16
|
+
export declare function flattenOptions<OptionType extends BaseOptionType = DefaultOptionType>(options: OptionType[], { fieldNames, childrenAsData }?: {
|
|
17
|
+
fieldNames?: FieldNames;
|
|
18
|
+
childrenAsData?: boolean;
|
|
19
|
+
}): FlattenOptionData<OptionType>[];
|
|
20
|
+
/**
|
|
21
|
+
* Inject `props` into `option` for legacy usage
|
|
22
|
+
*/
|
|
23
|
+
export declare function injectPropsWithOption<T extends object>(option: T): T;
|
|
24
|
+
export declare const getSeparatedContent: (text: string, tokens: string[], end?: number) => string[];
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import warning from "@rc-component/util/es/warning";
|
|
2
|
+
function getKey(data, index) {
|
|
3
|
+
const {
|
|
4
|
+
key
|
|
5
|
+
} = data;
|
|
6
|
+
let value;
|
|
7
|
+
if ('value' in data) {
|
|
8
|
+
({
|
|
9
|
+
value
|
|
10
|
+
} = data);
|
|
11
|
+
}
|
|
12
|
+
if (key !== null && key !== undefined) {
|
|
13
|
+
return key;
|
|
14
|
+
}
|
|
15
|
+
if (value !== undefined) {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
return `rc-index-key-${index}`;
|
|
19
|
+
}
|
|
20
|
+
export function isValidCount(value) {
|
|
21
|
+
return typeof value !== 'undefined' && !Number.isNaN(value);
|
|
22
|
+
}
|
|
23
|
+
export function fillFieldNames(fieldNames, childrenAsData) {
|
|
24
|
+
const {
|
|
25
|
+
label,
|
|
26
|
+
value,
|
|
27
|
+
options,
|
|
28
|
+
groupLabel
|
|
29
|
+
} = fieldNames || {};
|
|
30
|
+
const mergedLabel = label || (childrenAsData ? 'children' : 'label');
|
|
31
|
+
return {
|
|
32
|
+
label: mergedLabel,
|
|
33
|
+
value: value || 'value',
|
|
34
|
+
options: options || 'options',
|
|
35
|
+
groupLabel: groupLabel || mergedLabel
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Flat options into flatten list.
|
|
41
|
+
* We use `optionOnly` here is aim to avoid user use nested option group.
|
|
42
|
+
* Here is simply set `key` to the index if not provided.
|
|
43
|
+
*/
|
|
44
|
+
export function flattenOptions(options, {
|
|
45
|
+
fieldNames,
|
|
46
|
+
childrenAsData
|
|
47
|
+
} = {}) {
|
|
48
|
+
const flattenList = [];
|
|
49
|
+
const {
|
|
50
|
+
label: fieldLabel,
|
|
51
|
+
value: fieldValue,
|
|
52
|
+
options: fieldOptions,
|
|
53
|
+
groupLabel
|
|
54
|
+
} = fillFieldNames(fieldNames, false);
|
|
55
|
+
function dig(list, isGroupOption) {
|
|
56
|
+
if (!Array.isArray(list)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
list.forEach(data => {
|
|
60
|
+
if (isGroupOption || !(fieldOptions in data)) {
|
|
61
|
+
const value = data[fieldValue];
|
|
62
|
+
|
|
63
|
+
// Option
|
|
64
|
+
flattenList.push({
|
|
65
|
+
key: getKey(data, flattenList.length),
|
|
66
|
+
groupOption: isGroupOption,
|
|
67
|
+
data,
|
|
68
|
+
label: data[fieldLabel],
|
|
69
|
+
value
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
let grpLabel = data[groupLabel];
|
|
73
|
+
if (grpLabel === undefined && childrenAsData) {
|
|
74
|
+
grpLabel = data.label;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Option Group
|
|
78
|
+
flattenList.push({
|
|
79
|
+
key: getKey(data, flattenList.length),
|
|
80
|
+
group: true,
|
|
81
|
+
data,
|
|
82
|
+
label: grpLabel
|
|
83
|
+
});
|
|
84
|
+
dig(data[fieldOptions], true);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
dig(options, false);
|
|
89
|
+
return flattenList;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Inject `props` into `option` for legacy usage
|
|
94
|
+
*/
|
|
95
|
+
export function injectPropsWithOption(option) {
|
|
96
|
+
const newOption = {
|
|
97
|
+
...option
|
|
98
|
+
};
|
|
99
|
+
if (!('props' in newOption)) {
|
|
100
|
+
Object.defineProperty(newOption, 'props', {
|
|
101
|
+
get() {
|
|
102
|
+
warning(false, 'Return type is option instead of Option instance. Please read value directly instead of reading from `props`.');
|
|
103
|
+
return newOption;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return newOption;
|
|
108
|
+
}
|
|
109
|
+
export const getSeparatedContent = (text, tokens, end) => {
|
|
110
|
+
if (!tokens || !tokens.length) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
let match = false;
|
|
114
|
+
const separate = (str, [token, ...restTokens]) => {
|
|
115
|
+
if (!token) {
|
|
116
|
+
return [str];
|
|
117
|
+
}
|
|
118
|
+
const list = str.split(token);
|
|
119
|
+
match = match || list.length > 1;
|
|
120
|
+
return list.reduce((prevList, unitStr) => [...prevList, ...separate(unitStr, restTokens)], []).filter(Boolean);
|
|
121
|
+
};
|
|
122
|
+
const list = separate(text, tokens);
|
|
123
|
+
if (match) {
|
|
124
|
+
return typeof end !== 'undefined' ? list.slice(0, end) : list;
|
|
125
|
+
} else {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import toNodeArray from "@rc-component/util/es/Children/toArray";
|
|
2
|
+
import warning, { noteOnce } from "@rc-component/util/es/warning";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { isMultiple } from "../BaseSelect";
|
|
5
|
+
import { toArray } from "./commonUtil";
|
|
6
|
+
import { convertChildrenToData } from "./legacyUtil";
|
|
7
|
+
function warningProps(props) {
|
|
8
|
+
const {
|
|
9
|
+
mode,
|
|
10
|
+
options,
|
|
11
|
+
children,
|
|
12
|
+
backfill,
|
|
13
|
+
allowClear,
|
|
14
|
+
placeholder,
|
|
15
|
+
getInputElement,
|
|
16
|
+
showSearch,
|
|
17
|
+
onSearch,
|
|
18
|
+
defaultOpen,
|
|
19
|
+
autoFocus,
|
|
20
|
+
labelInValue,
|
|
21
|
+
value,
|
|
22
|
+
optionLabelProp
|
|
23
|
+
} = props;
|
|
24
|
+
const multiple = isMultiple(mode);
|
|
25
|
+
const mergedShowSearch = showSearch !== undefined ? showSearch : multiple || mode === 'combobox';
|
|
26
|
+
const mergedOptions = options || convertChildrenToData(children);
|
|
27
|
+
|
|
28
|
+
// `tags` should not set option as disabled
|
|
29
|
+
warning(mode !== 'tags' || mergedOptions.every(opt => !opt.disabled), 'Please avoid setting option to disabled in tags mode since user can always type text as tag.');
|
|
30
|
+
|
|
31
|
+
// `combobox` & `tags` should option be `string` type
|
|
32
|
+
if (mode === 'tags' || mode === 'combobox') {
|
|
33
|
+
const hasNumberValue = mergedOptions.some(item => {
|
|
34
|
+
if (item.options) {
|
|
35
|
+
return item.options.some(opt => typeof ('value' in opt ? opt.value : opt.key) === 'number');
|
|
36
|
+
}
|
|
37
|
+
return typeof ('value' in item ? item.value : item.key) === 'number';
|
|
38
|
+
});
|
|
39
|
+
warning(!hasNumberValue, '`value` of Option should not use number type when `mode` is `tags` or `combobox`.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// `combobox` should not use `optionLabelProp`
|
|
43
|
+
warning(mode !== 'combobox' || !optionLabelProp, '`combobox` mode not support `optionLabelProp`. Please set `value` on Option directly.');
|
|
44
|
+
|
|
45
|
+
// Only `combobox` support `backfill`
|
|
46
|
+
warning(mode === 'combobox' || !backfill, '`backfill` only works with `combobox` mode.');
|
|
47
|
+
|
|
48
|
+
// Only `combobox` support `getInputElement`
|
|
49
|
+
warning(mode === 'combobox' || !getInputElement, '`getInputElement` only work with `combobox` mode.');
|
|
50
|
+
|
|
51
|
+
// Customize `getInputElement` should not use `allowClear` & `placeholder`
|
|
52
|
+
noteOnce(mode !== 'combobox' || !getInputElement || !allowClear || !placeholder, 'Customize `getInputElement` should customize clear and placeholder logic instead of configuring `allowClear` and `placeholder`.');
|
|
53
|
+
|
|
54
|
+
// `onSearch` should use in `combobox` or `showSearch`
|
|
55
|
+
if (onSearch && !mergedShowSearch && mode !== 'combobox' && mode !== 'tags') {
|
|
56
|
+
warning(false, '`onSearch` should work with `showSearch` instead of use alone.');
|
|
57
|
+
}
|
|
58
|
+
noteOnce(!defaultOpen || autoFocus, '`defaultOpen` makes Select open without focus which means it will not close by click outside. You can set `autoFocus` if needed.');
|
|
59
|
+
if (value !== undefined && value !== null) {
|
|
60
|
+
const values = toArray(value);
|
|
61
|
+
warning(!labelInValue || values.every(val => typeof val === 'object' && ('key' in val || 'value' in val)), '`value` should in shape of `{ value: string | number, label?: ReactNode }` when you set `labelInValue` to `true`');
|
|
62
|
+
warning(!multiple || Array.isArray(value), '`value` should be array when `mode` is `multiple` or `tags`');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Syntactic sugar should use correct children type
|
|
66
|
+
if (children) {
|
|
67
|
+
let invalidateChildType = null;
|
|
68
|
+
toNodeArray(children).some(node => {
|
|
69
|
+
if (! /*#__PURE__*/React.isValidElement(node) || !node.type) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const {
|
|
73
|
+
type
|
|
74
|
+
} = node;
|
|
75
|
+
if (type.isSelectOption) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (type.isSelectOptGroup) {
|
|
79
|
+
const allChildrenValid = toNodeArray(node.props.children).every(subNode => {
|
|
80
|
+
if (! /*#__PURE__*/React.isValidElement(subNode) || !node.type || subNode.type.isSelectOption) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
invalidateChildType = subNode.type;
|
|
84
|
+
return false;
|
|
85
|
+
});
|
|
86
|
+
if (allChildrenValid) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
invalidateChildType = type;
|
|
92
|
+
return true;
|
|
93
|
+
});
|
|
94
|
+
if (invalidateChildType) {
|
|
95
|
+
warning(false, `\`children\` should be \`Select.Option\` or \`Select.OptGroup\` instead of \`${invalidateChildType.displayName || invalidateChildType.name || invalidateChildType}\`.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// value in Select option should not be null
|
|
101
|
+
// note: OptGroup has options too
|
|
102
|
+
export function warningNullOptions(options, fieldNames) {
|
|
103
|
+
if (options) {
|
|
104
|
+
const recursiveOptions = (optionsList, inGroup = false) => {
|
|
105
|
+
for (let i = 0; i < optionsList.length; i++) {
|
|
106
|
+
const option = optionsList[i];
|
|
107
|
+
if (option[fieldNames?.value] === null) {
|
|
108
|
+
warning(false, '`value` in Select options should not be `null`.');
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (!inGroup && Array.isArray(option[fieldNames?.options]) && recursiveOptions(option[fieldNames?.options], true)) {
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
recursiveOptions(options);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export default warningProps;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Polite;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
9
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
|
+
function Polite(props) {
|
|
11
|
+
const {
|
|
12
|
+
visible,
|
|
13
|
+
values
|
|
14
|
+
} = props;
|
|
15
|
+
if (!visible) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Only cut part of values since it's a screen reader
|
|
20
|
+
const MAX_COUNT = 50;
|
|
21
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
22
|
+
"aria-live": "polite",
|
|
23
|
+
style: {
|
|
24
|
+
width: 0,
|
|
25
|
+
height: 0,
|
|
26
|
+
position: 'absolute',
|
|
27
|
+
overflow: 'hidden',
|
|
28
|
+
opacity: 0
|
|
29
|
+
}
|
|
30
|
+
}, `${values.slice(0, MAX_COUNT).map(({
|
|
31
|
+
label,
|
|
32
|
+
value
|
|
33
|
+
}) => ['number', 'string'].includes(typeof label) ? label : value).join(', ')}`, values.length > MAX_COUNT ? ', ...' : null);
|
|
34
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { AlignType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
|
|
2
|
+
import type { ScrollConfig, ScrollTo } from 'rc-virtual-list/lib/List';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import type { DisplayInfoType, DisplayValueType, Mode, Placement, RawValueType, RenderDOMFunc, RenderNode } from '../interface';
|
|
5
|
+
export type { DisplayInfoType, DisplayValueType, Mode, Placement, RenderDOMFunc, RenderNode, RawValueType, };
|
|
6
|
+
export interface RefOptionListProps {
|
|
7
|
+
onKeyDown: React.KeyboardEventHandler;
|
|
8
|
+
onKeyUp: React.KeyboardEventHandler;
|
|
9
|
+
scrollTo?: (args: number | ScrollConfig) => void;
|
|
10
|
+
}
|
|
11
|
+
export type CustomTagProps = {
|
|
12
|
+
label: React.ReactNode;
|
|
13
|
+
value: any;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
onClose: (event?: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
|
16
|
+
closable: boolean;
|
|
17
|
+
isMaxTag: boolean;
|
|
18
|
+
index: number;
|
|
19
|
+
};
|
|
20
|
+
export interface BaseSelectRef {
|
|
21
|
+
focus: (options?: FocusOptions) => void;
|
|
22
|
+
blur: () => void;
|
|
23
|
+
scrollTo: ScrollTo;
|
|
24
|
+
nativeElement: HTMLElement;
|
|
25
|
+
}
|
|
26
|
+
export interface BaseSelectPrivateProps {
|
|
27
|
+
id: string;
|
|
28
|
+
prefixCls: string;
|
|
29
|
+
omitDomProps?: string[];
|
|
30
|
+
displayValues: DisplayValueType[];
|
|
31
|
+
onDisplayValuesChange: (values: DisplayValueType[], info: {
|
|
32
|
+
type: DisplayInfoType;
|
|
33
|
+
values: DisplayValueType[];
|
|
34
|
+
}) => void;
|
|
35
|
+
/** Current dropdown list active item string value */
|
|
36
|
+
activeValue?: string;
|
|
37
|
+
/** Link search input with target element */
|
|
38
|
+
activeDescendantId?: string;
|
|
39
|
+
onActiveValueChange?: (value: string | null) => void;
|
|
40
|
+
searchValue: string;
|
|
41
|
+
autoClearSearchValue?: boolean;
|
|
42
|
+
/** Trigger onSearch, return false to prevent trigger open event */
|
|
43
|
+
onSearch: (searchValue: string, info: {
|
|
44
|
+
source: 'typing' | 'effect' | 'submit' | 'blur';
|
|
45
|
+
}) => void;
|
|
46
|
+
/** Trigger when search text match the `tokenSeparators`. Will provide split content */
|
|
47
|
+
onSearchSplit?: (words: string[]) => void;
|
|
48
|
+
OptionList: React.ForwardRefExoticComponent<React.PropsWithoutRef<any> & React.RefAttributes<RefOptionListProps>>;
|
|
49
|
+
/** Tell if provided `options` is empty */
|
|
50
|
+
emptyOptions: boolean;
|
|
51
|
+
}
|
|
52
|
+
export type BaseSelectPropsWithoutPrivate = Omit<BaseSelectProps, keyof BaseSelectPrivateProps>;
|
|
53
|
+
export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttributes {
|
|
54
|
+
className?: string;
|
|
55
|
+
style?: React.CSSProperties;
|
|
56
|
+
title?: string;
|
|
57
|
+
showSearch?: boolean;
|
|
58
|
+
tagRender?: (props: CustomTagProps) => React.ReactElement;
|
|
59
|
+
direction?: 'ltr' | 'rtl';
|
|
60
|
+
maxLength?: number;
|
|
61
|
+
showScrollBar?: boolean | 'optional';
|
|
62
|
+
tabIndex?: number;
|
|
63
|
+
autoFocus?: boolean;
|
|
64
|
+
notFoundContent?: React.ReactNode;
|
|
65
|
+
placeholder?: React.ReactNode;
|
|
66
|
+
onClear?: () => void;
|
|
67
|
+
choiceTransitionName?: string;
|
|
68
|
+
mode?: Mode;
|
|
69
|
+
disabled?: boolean;
|
|
70
|
+
loading?: boolean;
|
|
71
|
+
open?: boolean;
|
|
72
|
+
defaultOpen?: boolean;
|
|
73
|
+
onPopupVisibleChange?: (open: boolean) => void;
|
|
74
|
+
/** @private Internal usage. Do not use in your production. */
|
|
75
|
+
getInputElement?: () => JSX.Element;
|
|
76
|
+
/** @private Internal usage. Do not use in your production. */
|
|
77
|
+
getRawInputElement?: () => JSX.Element;
|
|
78
|
+
maxTagTextLength?: number;
|
|
79
|
+
maxTagCount?: number | 'responsive';
|
|
80
|
+
maxTagPlaceholder?: React.ReactNode | ((omittedValues: DisplayValueType[]) => React.ReactNode);
|
|
81
|
+
tokenSeparators?: string[];
|
|
82
|
+
allowClear?: boolean | {
|
|
83
|
+
clearIcon?: RenderNode;
|
|
84
|
+
};
|
|
85
|
+
prefix?: React.ReactNode;
|
|
86
|
+
suffixIcon?: RenderNode;
|
|
87
|
+
/**
|
|
88
|
+
* Clear all icon
|
|
89
|
+
* @deprecated Please use `allowClear` instead
|
|
90
|
+
**/
|
|
91
|
+
clearIcon?: RenderNode;
|
|
92
|
+
/** Selector remove icon */
|
|
93
|
+
removeIcon?: RenderNode;
|
|
94
|
+
animation?: string;
|
|
95
|
+
transitionName?: string;
|
|
96
|
+
popupStyle?: React.CSSProperties;
|
|
97
|
+
popupClassName?: string;
|
|
98
|
+
popupMatchSelectWidth?: boolean | number;
|
|
99
|
+
popupRender?: (menu: React.ReactElement) => React.ReactElement;
|
|
100
|
+
popupAlign?: AlignType;
|
|
101
|
+
placement?: Placement;
|
|
102
|
+
builtinPlacements?: BuildInPlacements;
|
|
103
|
+
getPopupContainer?: RenderDOMFunc;
|
|
104
|
+
showAction?: ('focus' | 'click')[];
|
|
105
|
+
onBlur?: React.FocusEventHandler<HTMLElement>;
|
|
106
|
+
onFocus?: React.FocusEventHandler<HTMLElement>;
|
|
107
|
+
onKeyUp?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
108
|
+
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
109
|
+
onMouseDown?: React.MouseEventHandler<HTMLDivElement>;
|
|
110
|
+
onPopupScroll?: React.UIEventHandler<HTMLDivElement>;
|
|
111
|
+
onInputKeyDown?: React.KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
112
|
+
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
|
|
113
|
+
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
|
|
114
|
+
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
115
|
+
}
|
|
116
|
+
export declare const isMultiple: (mode: Mode) => boolean;
|
|
117
|
+
declare const BaseSelect: React.ForwardRefExoticComponent<BaseSelectProps & React.RefAttributes<BaseSelectRef>>;
|
|
118
|
+
export default BaseSelect;
|