@tdm-design/ui 0.0.14 → 0.0.16
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/dist/@tdm-design/ui.js +113056 -0
- package/dist/@tdm-design/ui.js.map +1 -0
- package/dist/@tdm-design/ui.min.js +369 -0
- package/dist/@tdm-design/ui.min.js.LICENSE.txt +129 -0
- package/dist/@tdm-design/ui.min.js.map +1 -0
- package/dist/reset.css +246 -0
- package/dist/tdm-with-locales.js +369 -0
- package/dist/tdm-with-locales.js.LICENSE.txt +129 -0
- package/dist/tdm-with-locales.js.map +1 -0
- package/dist/tdm.css +1 -0
- package/es/config-provider/context.d.ts +1 -1
- package/es/drawer/style/index.js +5 -1
- package/es/index.d.ts +2 -2
- package/es/index.js +1 -1
- package/es/modal/style/confirm.js +6 -2
- package/es/modal/style/index.js +7 -2
- package/es/select/Select.d.ts +130 -0
- package/es/select/Select.js +333 -0
- package/es/select/SingleDisplaySelect.d.ts +5 -0
- package/es/select/SingleDisplaySelect.js +153 -0
- package/es/select/SortableSelect.d.ts +5 -0
- package/es/select/SortableSelect.js +173 -0
- package/es/select/index.d.ts +7 -124
- package/es/select/index.js +7 -274
- package/es/select/style/select-input-multiple.js +4 -1
- package/es/version/token.json +1 -1
- package/es/version/version.d.ts +1 -1
- package/es/version/version.js +1 -1
- package/lib/config-provider/context.d.ts +1 -1
- package/lib/drawer/style/index.js +5 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +14 -1
- package/lib/modal/style/confirm.js +6 -2
- package/lib/modal/style/index.js +7 -2
- package/lib/select/Select.d.ts +130 -0
- package/lib/select/Select.js +340 -0
- package/lib/select/SingleDisplaySelect.d.ts +5 -0
- package/lib/select/SingleDisplaySelect.js +160 -0
- package/lib/select/SortableSelect.d.ts +5 -0
- package/lib/select/SortableSelect.js +180 -0
- package/lib/select/index.d.ts +7 -124
- package/lib/select/index.js +32 -274
- package/lib/select/style/select-input-multiple.js +4 -1
- package/lib/version/token.json +1 -1
- package/lib/version/version.d.ts +1 -1
- package/lib/version/version.js +1 -1
- package/package.json +11 -4
|
@@ -175,7 +175,7 @@ export type FloatButtonConfig = ComponentStyleConfig & Pick<FloatButtonProps, 'c
|
|
|
175
175
|
export type FloatButtonGroupConfig = ComponentStyleConfig & Pick<FloatButtonGroupProps, 'closeIcon' | 'classNames' | 'styles'>;
|
|
176
176
|
export type PaginationConfig = ComponentStyleConfig & Pick<PaginationProps, 'showSizeChanger' | 'totalBoundaryShowSizeChanger' | 'classNames' | 'styles'>;
|
|
177
177
|
export type ProgressConfig = ComponentStyleConfig & Pick<ProgressProps, 'classNames' | 'styles'>;
|
|
178
|
-
export type SelectConfig = ComponentStyleConfig & Pick<SelectProps, 'showSearch' | 'variant' | 'classNames' | 'styles' | 'optionFilterProp'>;
|
|
178
|
+
export type SelectConfig = ComponentStyleConfig & Pick<SelectProps, 'showSearch' | 'variant' | 'classNames' | 'styles' | 'optionFilterProp' | 'maxLines'>;
|
|
179
179
|
export type SpaceConfig = ComponentStyleConfig & Pick<SpaceProps, 'size' | 'classNames' | 'styles'>;
|
|
180
180
|
export type TooltipConfig = Pick<TooltipProps, 'className' | 'style' | 'styles' | 'classNames' | 'arrow' | 'trigger'> & {
|
|
181
181
|
/**
|
package/es/drawer/style/index.js
CHANGED
|
@@ -180,10 +180,14 @@ const genDrawerStyle = token => {
|
|
|
180
180
|
},
|
|
181
181
|
[`${componentCls}-title`]: {
|
|
182
182
|
flex: 1,
|
|
183
|
+
minWidth: 0,
|
|
183
184
|
margin: 0,
|
|
184
185
|
fontWeight: token.fontWeightStrong,
|
|
185
186
|
fontSize: fontSizeLG,
|
|
186
|
-
lineHeight: lineHeightLG
|
|
187
|
+
lineHeight: lineHeightLG,
|
|
188
|
+
whiteSpace: 'nowrap',
|
|
189
|
+
overflow: 'hidden',
|
|
190
|
+
textOverflow: 'ellipsis'
|
|
187
191
|
},
|
|
188
192
|
// Body
|
|
189
193
|
[`${componentCls}-body`]: {
|
package/es/index.d.ts
CHANGED
|
@@ -68,8 +68,8 @@ export { default as Row } from './row';
|
|
|
68
68
|
export type { RowProps } from './row';
|
|
69
69
|
export { default as Segmented } from './segmented';
|
|
70
70
|
export type { SegmentedProps } from './segmented';
|
|
71
|
-
export { default as Select } from './select';
|
|
72
|
-
export type { RefSelectProps, SelectProps } from './select';
|
|
71
|
+
export { default as Select, SortableSelect, SingleDisplaySelect } from './select';
|
|
72
|
+
export type { RefSelectProps, SelectProps, SortableSelectProps, SingleDisplaySelectProps } from './select';
|
|
73
73
|
export { default as Skeleton } from './skeleton';
|
|
74
74
|
export type { SkeletonProps } from './skeleton';
|
|
75
75
|
export { default as Slider } from './slider';
|
package/es/index.js
CHANGED
|
@@ -75,7 +75,7 @@ export { default as Radio } from './radio';
|
|
|
75
75
|
export { default as Result } from './result';
|
|
76
76
|
export { default as Row } from './row';
|
|
77
77
|
export { default as Segmented } from './segmented';
|
|
78
|
-
export { default as Select } from './select';
|
|
78
|
+
export { default as Select, SortableSelect, SingleDisplaySelect } from './select';
|
|
79
79
|
export { default as Skeleton } from './skeleton';
|
|
80
80
|
export { default as Slider } from './slider';
|
|
81
81
|
export { default as Space } from './space';
|
|
@@ -55,7 +55,8 @@ const genModalConfirmStyle = token => {
|
|
|
55
55
|
display: 'flex',
|
|
56
56
|
flexDirection: 'column',
|
|
57
57
|
flex: 'auto',
|
|
58
|
-
gap: token.marginXXS
|
|
58
|
+
gap: token.marginXXS,
|
|
59
|
+
minWidth: 0
|
|
59
60
|
},
|
|
60
61
|
[`${confirmComponentCls}-body-no-icon ${confirmComponentCls}-paragraph`]: {
|
|
61
62
|
maxWidth: '100%'
|
|
@@ -64,7 +65,10 @@ const genModalConfirmStyle = token => {
|
|
|
64
65
|
color: token.colorTextStrong,
|
|
65
66
|
fontWeight: token.fontWeightStrong,
|
|
66
67
|
fontSize: fontSizeTextLG,
|
|
67
|
-
lineHeight: lineHeightTextLG
|
|
68
|
+
lineHeight: lineHeightTextLG,
|
|
69
|
+
whiteSpace: 'nowrap',
|
|
70
|
+
overflow: 'hidden',
|
|
71
|
+
textOverflow: 'ellipsis'
|
|
68
72
|
},
|
|
69
73
|
[`${confirmComponentCls}-container`]: {
|
|
70
74
|
color: token.colorText,
|
package/es/modal/style/index.js
CHANGED
|
@@ -119,7 +119,10 @@ const genModalStyle = token => {
|
|
|
119
119
|
fontWeight: token.fontWeightStrong,
|
|
120
120
|
fontSize: token.titleFontSize,
|
|
121
121
|
lineHeight: token.titleLineHeight,
|
|
122
|
-
wordWrap: 'break-word'
|
|
122
|
+
wordWrap: 'break-word',
|
|
123
|
+
whiteSpace: 'nowrap',
|
|
124
|
+
overflow: 'hidden',
|
|
125
|
+
textOverflow: 'ellipsis'
|
|
123
126
|
},
|
|
124
127
|
[`${componentCls}-container`]: {
|
|
125
128
|
position: 'relative',
|
|
@@ -178,9 +181,11 @@ const genModalStyle = token => {
|
|
|
178
181
|
background: token.headerBg,
|
|
179
182
|
borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0`,
|
|
180
183
|
padding: token.headerPadding,
|
|
184
|
+
paddingInlineEnd: token.calc(token.modalHeaderHeight).equal(),
|
|
181
185
|
borderBottom: token.headerBorderBottom,
|
|
182
186
|
// boxShadow: token.boxShadowMD,
|
|
183
|
-
flex: '0 0 auto'
|
|
187
|
+
flex: '0 0 auto',
|
|
188
|
+
overflow: 'hidden'
|
|
184
189
|
},
|
|
185
190
|
[`${componentCls}-body`]: {
|
|
186
191
|
fontSize: token.fontSize,
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { BaseSelectRef, SelectProps as RcSelectProps } from '@rc-component/select';
|
|
3
|
+
import { OptGroup, Option } from '@rc-component/select';
|
|
4
|
+
import type { OptionProps } from '@rc-component/select/lib/Option';
|
|
5
|
+
import type { BaseOptionType, DefaultOptionType } from '@rc-component/select/lib/Select';
|
|
6
|
+
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
|
|
7
|
+
import type { SelectCommonPlacement } from '../_util/motion';
|
|
8
|
+
import type { InputStatus } from '../_util/statusUtils';
|
|
9
|
+
import type { Variant } from '../config-provider';
|
|
10
|
+
import type { SizeType } from '../config-provider/SizeContext';
|
|
11
|
+
type RawValue = string | number;
|
|
12
|
+
export type { BaseOptionType, DefaultOptionType, OptionProps, BaseSelectRef as RefSelectProps };
|
|
13
|
+
export interface LabeledValue {
|
|
14
|
+
key?: string;
|
|
15
|
+
value: RawValue;
|
|
16
|
+
label: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[] | undefined;
|
|
19
|
+
export interface InternalSelectProps<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType> extends Omit<RcSelectProps<ValueType, OptionType>, 'mode'> {
|
|
20
|
+
rootClassName?: string;
|
|
21
|
+
prefix?: React.ReactNode;
|
|
22
|
+
suffixIcon?: React.ReactNode;
|
|
23
|
+
size?: SizeType;
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
mode?: 'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE' | 'combobox';
|
|
26
|
+
/** @deprecated Use `variant` instead. */
|
|
27
|
+
bordered?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated `showArrow` is deprecated which will be removed in next major version. It will be a
|
|
30
|
+
* default behavior, you can hide it by setting `suffixIcon` to null.
|
|
31
|
+
*/
|
|
32
|
+
showArrow?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* @since 5.13.0
|
|
35
|
+
* @default "outlined"
|
|
36
|
+
*/
|
|
37
|
+
variant?: Variant;
|
|
38
|
+
classNames?: SelectSemanticClassNames & {
|
|
39
|
+
popup?: SelectPopupSemanticClassNames;
|
|
40
|
+
};
|
|
41
|
+
styles?: SelectSemanticStyles & {
|
|
42
|
+
popup?: SelectPopupSemanticStyles;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* @description Whether the option is a filter item
|
|
46
|
+
* @default false
|
|
47
|
+
* @type boolean
|
|
48
|
+
* TDM_CUSTOM: custom select filter (BEGIN)
|
|
49
|
+
*/
|
|
50
|
+
isFilterItem?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export type SelectSemanticName = keyof SelectSemanticClassNames & keyof SelectSemanticStyles;
|
|
53
|
+
export type SelectSemanticClassNames = {
|
|
54
|
+
root?: string;
|
|
55
|
+
prefix?: string;
|
|
56
|
+
suffix?: string;
|
|
57
|
+
input?: string;
|
|
58
|
+
placeholder?: string;
|
|
59
|
+
content?: string;
|
|
60
|
+
item?: string;
|
|
61
|
+
itemContent?: string;
|
|
62
|
+
itemRemove?: string;
|
|
63
|
+
clear?: string;
|
|
64
|
+
};
|
|
65
|
+
export type SelectSemanticStyles = {
|
|
66
|
+
root?: React.CSSProperties;
|
|
67
|
+
prefix?: React.CSSProperties;
|
|
68
|
+
suffix?: React.CSSProperties;
|
|
69
|
+
input?: React.CSSProperties;
|
|
70
|
+
placeholder?: React.CSSProperties;
|
|
71
|
+
content?: React.CSSProperties;
|
|
72
|
+
item?: React.CSSProperties;
|
|
73
|
+
itemContent?: React.CSSProperties;
|
|
74
|
+
itemRemove?: React.CSSProperties;
|
|
75
|
+
clear?: React.CSSProperties;
|
|
76
|
+
};
|
|
77
|
+
export type SelectPopupSemanticName = keyof SelectPopupSemanticClassNames & keyof SelectPopupSemanticStyles;
|
|
78
|
+
export type SelectPopupSemanticClassNames = {
|
|
79
|
+
root?: string;
|
|
80
|
+
listItem?: string;
|
|
81
|
+
list?: string;
|
|
82
|
+
};
|
|
83
|
+
export type SelectPopupSemanticStyles = {
|
|
84
|
+
root?: React.CSSProperties;
|
|
85
|
+
listItem?: React.CSSProperties;
|
|
86
|
+
list?: React.CSSProperties;
|
|
87
|
+
};
|
|
88
|
+
export type SelectClassNamesType = SemanticClassNamesType<SelectProps, SelectSemanticClassNames, {
|
|
89
|
+
popup?: SelectPopupSemanticClassNames;
|
|
90
|
+
}>;
|
|
91
|
+
export type SelectStylesType = SemanticStylesType<SelectProps, SelectSemanticStyles, {
|
|
92
|
+
popup?: SelectPopupSemanticStyles;
|
|
93
|
+
}>;
|
|
94
|
+
export interface SelectProps<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType> extends Omit<InternalSelectProps<ValueType, OptionType>, 'mode' | 'getInputElement' | 'getRawInputElement' | 'backfill' | 'placement' | 'dropdownClassName' | 'dropdownStyle'> {
|
|
95
|
+
placement?: SelectCommonPlacement;
|
|
96
|
+
mode?: 'multiple' | 'tags';
|
|
97
|
+
status?: InputStatus;
|
|
98
|
+
/**
|
|
99
|
+
* @description Maximum number of lines to display tags before collapsing into `+N`
|
|
100
|
+
* @type number
|
|
101
|
+
*/
|
|
102
|
+
maxLines?: number;
|
|
103
|
+
/** @deprecated Please use `classNames.popup.root` instead */
|
|
104
|
+
popupClassName?: string;
|
|
105
|
+
/** @deprecated Please use `classNames.popup.root` instead */
|
|
106
|
+
dropdownClassName?: string;
|
|
107
|
+
/** @deprecated Please use `styles.popup` instead */
|
|
108
|
+
dropdownStyle?: React.CSSProperties;
|
|
109
|
+
/** @deprecated Please use `popupRender` instead */
|
|
110
|
+
dropdownRender?: SelectProps['popupRender'];
|
|
111
|
+
/** @deprecated Please use `onOpenChange` instead */
|
|
112
|
+
onDropdownVisibleChange?: SelectProps['onPopupVisibleChange'];
|
|
113
|
+
/** @deprecated Please use `popupMatchSelectWidth` instead */
|
|
114
|
+
dropdownMatchSelectWidth?: boolean | number;
|
|
115
|
+
popupMatchSelectWidth?: boolean | number;
|
|
116
|
+
styles?: SelectStylesType;
|
|
117
|
+
classNames?: SelectClassNamesType;
|
|
118
|
+
onOpenChange?: (visible: boolean) => void;
|
|
119
|
+
}
|
|
120
|
+
declare const Select: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
|
|
121
|
+
displayName?: string;
|
|
122
|
+
SECRET_COMBOBOX_MODE_DO_NOT_USE: string;
|
|
123
|
+
/** @deprecated Please use `options` instead. */
|
|
124
|
+
Option: typeof Option;
|
|
125
|
+
/** @deprecated Please use `options` instead. */
|
|
126
|
+
OptGroup: typeof OptGroup;
|
|
127
|
+
_InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel;
|
|
128
|
+
};
|
|
129
|
+
declare const PurePanel: (props: import("../_util/type").AnyObject) => React.JSX.Element;
|
|
130
|
+
export default Select;
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// TODO: 4.0 - codemod should help to change `filterOption` to support node props.
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import RcSelect, { OptGroup, Option } from '@rc-component/select';
|
|
6
|
+
import { omit } from '@rc-component/util';
|
|
7
|
+
import { clsx } from 'clsx';
|
|
8
|
+
import { useMergeSemantic, useZIndex } from '../_util/hooks';
|
|
9
|
+
import { getTransitionName } from '../_util/motion';
|
|
10
|
+
import genPurePanel from '../_util/PurePanel';
|
|
11
|
+
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
|
|
12
|
+
import { devUseWarning } from '../_util/warning';
|
|
13
|
+
import { ConfigContext } from '../config-provider';
|
|
14
|
+
import { useComponentConfig } from '../config-provider/context';
|
|
15
|
+
import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
|
|
16
|
+
import DisabledContext from '../config-provider/DisabledContext';
|
|
17
|
+
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
|
18
|
+
import useSize from '../config-provider/hooks/useSize';
|
|
19
|
+
import { FormItemInputContext } from '../form/context';
|
|
20
|
+
import useVariants from '../form/hooks/useVariants';
|
|
21
|
+
import { useCompactItemContext } from '../space/Compact';
|
|
22
|
+
import { useToken } from '../theme/internal';
|
|
23
|
+
import mergedBuiltinPlacements from './mergedBuiltinPlacements';
|
|
24
|
+
import useStyle from './style';
|
|
25
|
+
import useIcons from './useIcons';
|
|
26
|
+
import usePopupRender from './usePopupRender';
|
|
27
|
+
import useShowArrow from './useShowArrow';
|
|
28
|
+
const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
|
29
|
+
const InternalSelect = (props, ref) => {
|
|
30
|
+
const {
|
|
31
|
+
prefixCls: customizePrefixCls,
|
|
32
|
+
bordered,
|
|
33
|
+
className,
|
|
34
|
+
rootClassName,
|
|
35
|
+
getPopupContainer,
|
|
36
|
+
popupClassName,
|
|
37
|
+
dropdownClassName,
|
|
38
|
+
listHeight = 256,
|
|
39
|
+
placement,
|
|
40
|
+
listItemHeight: customListItemHeight,
|
|
41
|
+
size: customizeSize,
|
|
42
|
+
disabled: customDisabled,
|
|
43
|
+
notFoundContent,
|
|
44
|
+
status: customStatus,
|
|
45
|
+
builtinPlacements,
|
|
46
|
+
dropdownMatchSelectWidth,
|
|
47
|
+
popupMatchSelectWidth,
|
|
48
|
+
direction: propDirection,
|
|
49
|
+
style,
|
|
50
|
+
allowClear,
|
|
51
|
+
variant: customizeVariant,
|
|
52
|
+
popupStyle,
|
|
53
|
+
dropdownStyle,
|
|
54
|
+
transitionName,
|
|
55
|
+
tagRender,
|
|
56
|
+
maxCount,
|
|
57
|
+
prefix,
|
|
58
|
+
dropdownRender,
|
|
59
|
+
/**
|
|
60
|
+
* @since 5.25.0
|
|
61
|
+
*/
|
|
62
|
+
popupRender,
|
|
63
|
+
onDropdownVisibleChange,
|
|
64
|
+
onOpenChange,
|
|
65
|
+
styles,
|
|
66
|
+
classNames,
|
|
67
|
+
isFilterItem,
|
|
68
|
+
// TDM_CUSTOM: custom select filter
|
|
69
|
+
optionFilterProp,
|
|
70
|
+
maxLines,
|
|
71
|
+
...rest
|
|
72
|
+
} = props;
|
|
73
|
+
const {
|
|
74
|
+
getPopupContainer: getContextPopupContainer,
|
|
75
|
+
getPrefixCls,
|
|
76
|
+
renderEmpty,
|
|
77
|
+
direction: contextDirection,
|
|
78
|
+
virtual,
|
|
79
|
+
popupMatchSelectWidth: contextPopupMatchSelectWidth,
|
|
80
|
+
popupOverflow
|
|
81
|
+
} = React.useContext(ConfigContext);
|
|
82
|
+
const {
|
|
83
|
+
showSearch,
|
|
84
|
+
optionFilterProp: contextOptionFilterProp,
|
|
85
|
+
maxLines: contextMaxLines,
|
|
86
|
+
style: contextStyle,
|
|
87
|
+
styles: contextStyles,
|
|
88
|
+
className: contextClassName,
|
|
89
|
+
classNames: contextClassNames
|
|
90
|
+
} = useComponentConfig('select');
|
|
91
|
+
const mergedMaxLines = maxLines ?? contextMaxLines;
|
|
92
|
+
const [, token] = useToken();
|
|
93
|
+
const listItemHeight = customListItemHeight ?? token?.controlHeight;
|
|
94
|
+
const prefixCls = getPrefixCls('select', customizePrefixCls);
|
|
95
|
+
const rootPrefixCls = getPrefixCls();
|
|
96
|
+
const direction = propDirection ?? contextDirection;
|
|
97
|
+
const {
|
|
98
|
+
compactSize,
|
|
99
|
+
compactItemClassnames
|
|
100
|
+
} = useCompactItemContext(prefixCls, direction);
|
|
101
|
+
const [variant, enableVariantCls] = useVariants('select', customizeVariant, bordered);
|
|
102
|
+
const rootCls = useCSSVarCls(prefixCls);
|
|
103
|
+
const [hashId, cssVarCls] = useStyle(prefixCls, rootCls);
|
|
104
|
+
const mode = React.useMemo(() => {
|
|
105
|
+
const {
|
|
106
|
+
mode: m
|
|
107
|
+
} = props;
|
|
108
|
+
if (m === 'combobox') {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
if (m === SECRET_COMBOBOX_MODE_DO_NOT_USE) {
|
|
112
|
+
return 'combobox';
|
|
113
|
+
}
|
|
114
|
+
return m;
|
|
115
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
116
|
+
}, [props.mode]);
|
|
117
|
+
const isMultiple = mode === 'multiple' || mode === 'tags';
|
|
118
|
+
const showSuffixIcon = useShowArrow(props.suffixIcon, props.showArrow);
|
|
119
|
+
const mergedPopupMatchSelectWidth = popupMatchSelectWidth ?? dropdownMatchSelectWidth ?? contextPopupMatchSelectWidth;
|
|
120
|
+
const mergedPopupRender = usePopupRender(popupRender || dropdownRender);
|
|
121
|
+
const mergedOnOpenChange = onOpenChange || onDropdownVisibleChange;
|
|
122
|
+
// ===================== Form Status =====================
|
|
123
|
+
const {
|
|
124
|
+
status: contextStatus,
|
|
125
|
+
hasFeedback,
|
|
126
|
+
isFormItemInput,
|
|
127
|
+
feedbackIcon
|
|
128
|
+
} = React.useContext(FormItemInputContext);
|
|
129
|
+
const mergedStatus = getMergedStatus(contextStatus, customStatus);
|
|
130
|
+
// ===================== Empty =====================
|
|
131
|
+
let mergedNotFound;
|
|
132
|
+
if (notFoundContent !== undefined) {
|
|
133
|
+
mergedNotFound = notFoundContent;
|
|
134
|
+
} else if (mode === 'combobox') {
|
|
135
|
+
mergedNotFound = null;
|
|
136
|
+
} else {
|
|
137
|
+
mergedNotFound = renderEmpty?.('Select') || /*#__PURE__*/React.createElement(DefaultRenderEmpty, {
|
|
138
|
+
componentName: "Select"
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// ===================== Icons =====================
|
|
142
|
+
const {
|
|
143
|
+
suffixIcon,
|
|
144
|
+
itemIcon,
|
|
145
|
+
removeIcon,
|
|
146
|
+
clearIcon
|
|
147
|
+
} = useIcons({
|
|
148
|
+
...rest,
|
|
149
|
+
multiple: isMultiple,
|
|
150
|
+
hasFeedback,
|
|
151
|
+
feedbackIcon,
|
|
152
|
+
showSuffixIcon,
|
|
153
|
+
prefixCls,
|
|
154
|
+
componentName: 'Select'
|
|
155
|
+
});
|
|
156
|
+
const mergedAllowClear = allowClear === true ? {
|
|
157
|
+
clearIcon
|
|
158
|
+
} : allowClear;
|
|
159
|
+
const selectProps = omit(rest, ['suffixIcon', 'itemIcon']);
|
|
160
|
+
const mergedSize = useSize(ctx => customizeSize ?? compactSize ?? ctx);
|
|
161
|
+
// ===================== Disabled =====================
|
|
162
|
+
const disabled = React.useContext(DisabledContext);
|
|
163
|
+
const mergedDisabled = customDisabled ?? disabled;
|
|
164
|
+
// ========== Merged Props for Semantic ==================
|
|
165
|
+
const mergedProps = {
|
|
166
|
+
...props,
|
|
167
|
+
variant,
|
|
168
|
+
status: mergedStatus,
|
|
169
|
+
disabled: mergedDisabled,
|
|
170
|
+
size: mergedSize
|
|
171
|
+
};
|
|
172
|
+
const [mergedClassNames, mergedStyles] = useMergeSemantic([contextClassNames, classNames], [contextStyles, styles], {
|
|
173
|
+
props: mergedProps
|
|
174
|
+
}, {
|
|
175
|
+
popup: {
|
|
176
|
+
_default: 'root'
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const mergedPopupClassName = clsx(mergedClassNames.popup?.root, popupClassName, dropdownClassName, {
|
|
180
|
+
[`${prefixCls}-dropdown-${direction}`]: direction === 'rtl'
|
|
181
|
+
}, rootClassName, cssVarCls, rootCls, hashId);
|
|
182
|
+
const mergedPopupStyle = {
|
|
183
|
+
...mergedStyles.popup?.root,
|
|
184
|
+
...(popupStyle ?? dropdownStyle)
|
|
185
|
+
};
|
|
186
|
+
const mergedClassName = clsx({
|
|
187
|
+
[`${prefixCls}-lg`]: mergedSize === 'large',
|
|
188
|
+
[`${prefixCls}-sm`]: mergedSize === 'small',
|
|
189
|
+
[`${prefixCls}-rtl`]: direction === 'rtl',
|
|
190
|
+
[`${prefixCls}-${variant}`]: enableVariantCls,
|
|
191
|
+
[`${prefixCls}-in-form-item`]: isFormItemInput,
|
|
192
|
+
// TDM_CUSTOM: custom select filter
|
|
193
|
+
[`${prefixCls}-filter`]: isFilterItem
|
|
194
|
+
}, getStatusClassNames(prefixCls, mergedStatus, hasFeedback), compactItemClassnames, contextClassName, className, mergedClassNames.root, rootClassName, cssVarCls, rootCls, hashId);
|
|
195
|
+
// ===================== Placement =====================
|
|
196
|
+
const memoPlacement = React.useMemo(() => {
|
|
197
|
+
if (placement !== undefined) {
|
|
198
|
+
return placement;
|
|
199
|
+
}
|
|
200
|
+
return direction === 'rtl' ? 'bottomRight' : 'bottomLeft';
|
|
201
|
+
}, [placement, direction]);
|
|
202
|
+
// ====================== Warning ======================
|
|
203
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
204
|
+
const warning = devUseWarning('Select');
|
|
205
|
+
const deprecatedProps = {
|
|
206
|
+
dropdownMatchSelectWidth: 'popupMatchSelectWidth',
|
|
207
|
+
dropdownStyle: 'styles.popup.root',
|
|
208
|
+
dropdownClassName: 'classNames.popup.root',
|
|
209
|
+
popupClassName: 'classNames.popup.root',
|
|
210
|
+
dropdownRender: 'popupRender',
|
|
211
|
+
onDropdownVisibleChange: 'onOpenChange',
|
|
212
|
+
bordered: 'variant'
|
|
213
|
+
};
|
|
214
|
+
Object.entries(deprecatedProps).forEach(([oldProp, newProp]) => {
|
|
215
|
+
warning.deprecated(!(oldProp in props), oldProp, newProp);
|
|
216
|
+
});
|
|
217
|
+
process.env.NODE_ENV !== "production" ? warning(!('showArrow' in props), 'deprecated', '`showArrow` is deprecated which will be removed in next major version. It will be a default behavior, you can hide it by setting `suffixIcon` to null.') : void 0;
|
|
218
|
+
process.env.NODE_ENV !== "production" ? warning(!(typeof maxCount !== 'undefined' && !isMultiple), 'usage', '`maxCount` only works with mode `multiple` or `tags`') : void 0;
|
|
219
|
+
}
|
|
220
|
+
// ====================== MaxLines ======================
|
|
221
|
+
const internalSelectRef = React.useRef(null);
|
|
222
|
+
React.useImperativeHandle(ref, () => internalSelectRef.current);
|
|
223
|
+
const [linesMaxTagCount, setLinesMaxTagCount] = React.useState(undefined);
|
|
224
|
+
const calculateMaxLinesTags = React.useCallback(() => {
|
|
225
|
+
if (!mergedMaxLines || !isMultiple) return;
|
|
226
|
+
const container = internalSelectRef.current?.nativeElement;
|
|
227
|
+
if (!container) return;
|
|
228
|
+
const tagElements = container.querySelectorAll(`.${prefixCls}-selection-item, .${prefixCls}-content-item`);
|
|
229
|
+
if (tagElements.length === 0) {
|
|
230
|
+
setLinesMaxTagCount(undefined);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const firstTagTop = tagElements[0].offsetTop;
|
|
234
|
+
const tagHeight = tagElements[0].offsetHeight || 24;
|
|
235
|
+
const rowHeightThreshold = tagHeight + 6;
|
|
236
|
+
const maxAllowedTop = firstTagTop + rowHeightThreshold * (mergedMaxLines - 1);
|
|
237
|
+
let fitCount = tagElements.length;
|
|
238
|
+
for (let i = 0; i < tagElements.length; i++) {
|
|
239
|
+
const el = tagElements[i];
|
|
240
|
+
if (el.offsetTop > maxAllowedTop) {
|
|
241
|
+
fitCount = Math.max(1, i - 1);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (fitCount < tagElements.length) {
|
|
246
|
+
setLinesMaxTagCount(fitCount);
|
|
247
|
+
} else {
|
|
248
|
+
setLinesMaxTagCount(undefined);
|
|
249
|
+
}
|
|
250
|
+
}, [mergedMaxLines, isMultiple, prefixCls]);
|
|
251
|
+
React.useLayoutEffect(() => {
|
|
252
|
+
if (!mergedMaxLines || !isMultiple) {
|
|
253
|
+
setLinesMaxTagCount(undefined);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
setLinesMaxTagCount(undefined);
|
|
257
|
+
const timer = requestAnimationFrame(() => {
|
|
258
|
+
calculateMaxLinesTags();
|
|
259
|
+
});
|
|
260
|
+
return () => cancelAnimationFrame(timer);
|
|
261
|
+
}, [props.value, mergedMaxLines, isMultiple, calculateMaxLinesTags]);
|
|
262
|
+
React.useLayoutEffect(() => {
|
|
263
|
+
if (!mergedMaxLines || !isMultiple) return;
|
|
264
|
+
const container = internalSelectRef.current?.nativeElement;
|
|
265
|
+
if (!container || typeof ResizeObserver === 'undefined') return;
|
|
266
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
267
|
+
calculateMaxLinesTags();
|
|
268
|
+
});
|
|
269
|
+
resizeObserver.observe(container);
|
|
270
|
+
return () => resizeObserver.disconnect();
|
|
271
|
+
}, [mergedMaxLines, isMultiple, calculateMaxLinesTags]);
|
|
272
|
+
// ====================== zIndex =========================
|
|
273
|
+
const [zIndex] = useZIndex('SelectLike', mergedStyles.popup?.root?.zIndex ?? mergedPopupStyle?.zIndex);
|
|
274
|
+
// ====================== Render =======================
|
|
275
|
+
return /*#__PURE__*/React.createElement(RcSelect, {
|
|
276
|
+
ref: internalSelectRef,
|
|
277
|
+
virtual: virtual,
|
|
278
|
+
classNames: mergedClassNames,
|
|
279
|
+
styles: mergedStyles,
|
|
280
|
+
showSearch: showSearch,
|
|
281
|
+
optionFilterProp: optionFilterProp ?? contextOptionFilterProp ?? 'label',
|
|
282
|
+
...selectProps,
|
|
283
|
+
maxTagCount: mergedMaxLines && isMultiple ? linesMaxTagCount : props.maxTagCount ?? (isMultiple ? maxCount : undefined),
|
|
284
|
+
style: {
|
|
285
|
+
...mergedStyles.root,
|
|
286
|
+
...contextStyle,
|
|
287
|
+
...style
|
|
288
|
+
},
|
|
289
|
+
popupMatchSelectWidth: mergedPopupMatchSelectWidth,
|
|
290
|
+
transitionName: getTransitionName(rootPrefixCls, 'slide-up', transitionName),
|
|
291
|
+
builtinPlacements: mergedBuiltinPlacements(builtinPlacements, popupOverflow),
|
|
292
|
+
listHeight: listHeight,
|
|
293
|
+
listItemHeight: listItemHeight,
|
|
294
|
+
mode: mode,
|
|
295
|
+
prefixCls: prefixCls,
|
|
296
|
+
placement: memoPlacement,
|
|
297
|
+
direction: direction,
|
|
298
|
+
prefix: prefix,
|
|
299
|
+
suffixIcon: suffixIcon,
|
|
300
|
+
menuItemSelectedIcon: itemIcon,
|
|
301
|
+
removeIcon: removeIcon,
|
|
302
|
+
allowClear: mergedAllowClear,
|
|
303
|
+
notFoundContent: mergedNotFound,
|
|
304
|
+
className: mergedClassName,
|
|
305
|
+
getPopupContainer: getPopupContainer || getContextPopupContainer,
|
|
306
|
+
popupClassName: mergedPopupClassName,
|
|
307
|
+
disabled: mergedDisabled,
|
|
308
|
+
popupStyle: {
|
|
309
|
+
...mergedStyles.popup?.root,
|
|
310
|
+
...mergedPopupStyle,
|
|
311
|
+
zIndex
|
|
312
|
+
},
|
|
313
|
+
maxCount: isMultiple ? maxCount : undefined,
|
|
314
|
+
tagRender: isMultiple ? tagRender : undefined,
|
|
315
|
+
popupRender: mergedPopupRender,
|
|
316
|
+
onPopupVisibleChange: mergedOnOpenChange
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
320
|
+
InternalSelect.displayName = 'Select';
|
|
321
|
+
}
|
|
322
|
+
const Select = /*#__PURE__*/React.forwardRef(InternalSelect);
|
|
323
|
+
// We don't care debug panel
|
|
324
|
+
/* istanbul ignore next */
|
|
325
|
+
const PurePanel = genPurePanel(Select, 'popupAlign');
|
|
326
|
+
Select.SECRET_COMBOBOX_MODE_DO_NOT_USE = SECRET_COMBOBOX_MODE_DO_NOT_USE;
|
|
327
|
+
Select.Option = Option;
|
|
328
|
+
Select.OptGroup = OptGroup;
|
|
329
|
+
Select._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
|
|
330
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
331
|
+
Select.displayName = 'Select';
|
|
332
|
+
}
|
|
333
|
+
export default Select;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { SelectProps, BaseOptionType, DefaultOptionType } from './Select';
|
|
3
|
+
export type SingleDisplaySelectProps<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType> = SelectProps<ValueType, OptionType>;
|
|
4
|
+
declare const SingleDisplaySelect: <ValueType extends any[] = any[], OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: SingleDisplaySelectProps<ValueType, OptionType>) => React.JSX.Element;
|
|
5
|
+
export default SingleDisplaySelect;
|