Skip to content

Commit 39e5824

Browse files
authored
refactor:select (#6295)
* refactor:select * update doc * delete useless
1 parent 9df8317 commit 39e5824

File tree

9 files changed

+973
-31
lines changed

9 files changed

+973
-31
lines changed

components/select/index.en-US.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
category: Components
33
type: Data Entry
44
title: Select
5-
cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
5+
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*zo76T7KQx2UAAAAAAAAAAAAADrJ8AQ/original
66
---
77

88
Select component to select value from options.

components/select/index.tsx

+29-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { App, PropType, Plugin, ExtractPropTypes } from 'vue';
1+
import type { App, Plugin, ExtractPropTypes } from 'vue';
22
import { computed, defineComponent, ref } from 'vue';
33
import classNames from '../_util/classNames';
44
import type { BaseSelectRef } from '../vc-select';
@@ -16,6 +16,10 @@ import type { SizeType } from '../config-provider';
1616
import { initDefaultProps } from '../_util/props-util';
1717
import type { InputStatus } from '../_util/statusUtils';
1818
import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
19+
import { stringType, someType, functionType, booleanType } from '../_util/type';
20+
21+
// CSSINJS
22+
import useStyle from './style';
1923

2024
type RawValue = string | number;
2125

@@ -37,23 +41,19 @@ export const selectProps = () => ({
3741
'getRawInputElement',
3842
'backfill',
3943
]),
40-
value: {
41-
type: [Array, Object, String, Number] as PropType<SelectValue>,
42-
},
43-
defaultValue: {
44-
type: [Array, Object, String, Number] as PropType<SelectValue>,
45-
},
44+
value: someType<SelectValue>([Array, Object, String, Number]),
45+
defaultValue: someType<SelectValue>([Array, Object, String, Number]),
4646
notFoundContent: PropTypes.any,
4747
suffixIcon: PropTypes.any,
4848
itemIcon: PropTypes.any,
49-
size: String as PropType<SizeType>,
50-
mode: String as PropType<'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE'>,
51-
bordered: { type: Boolean, default: true },
49+
size: stringType<SizeType>(),
50+
mode: stringType<'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE'>(),
51+
bordered: booleanType(true),
5252
transitionName: String,
53-
choiceTransitionName: { type: String, default: '' },
54-
placement: String as PropType<SelectCommonPlacement>,
55-
status: String as PropType<InputStatus>,
56-
'onUpdate:value': Function as PropType<(val: SelectValue) => void>,
53+
choiceTransitionName: stringType(''),
54+
placement: stringType<SelectCommonPlacement>(),
55+
status: stringType<InputStatus>(),
56+
'onUpdate:value': functionType<(val: SelectValue) => void>(),
5757
});
5858

5959
export type SelectProps = Partial<ExtractPropTypes<ReturnType<typeof selectProps>>>;
@@ -123,6 +123,10 @@ const Select = defineComponent({
123123
getPrefixCls,
124124
getPopupContainer,
125125
} = useConfigInject('select', props);
126+
127+
// style
128+
const [wrapSSR, hashId] = useStyle(prefixCls);
129+
126130
const rootPrefixCls = computed(() => getPrefixCls());
127131
// ===================== Placement =====================
128132
const placement = computed(() => {
@@ -150,6 +154,7 @@ const Select = defineComponent({
150154
[`${prefixCls.value}-in-form-item`]: formItemInputContext.isFormItemInput,
151155
},
152156
getStatusClassNames(prefixCls.value, mergedStatus.value, formItemInputContext.hasFeedback),
157+
hashId.value,
153158
),
154159
);
155160
const triggerChange: SelectProps['onChange'] = (...args) => {
@@ -224,10 +229,15 @@ const Select = defineComponent({
224229
'status',
225230
]);
226231

227-
const rcSelectRtlDropdownClassName = classNames(dropdownClassName, {
228-
[`${prefixCls.value}-dropdown-${direction.value}`]: direction.value === 'rtl',
229-
});
230-
return (
232+
const rcSelectRtlDropdownClassName = classNames(
233+
dropdownClassName,
234+
{
235+
[`${prefixCls.value}-dropdown-${direction.value}`]: direction.value === 'rtl',
236+
},
237+
hashId.value,
238+
);
239+
240+
return wrapSSR(
231241
<RcSelect
232242
ref={selectRef}
233243
virtual={virtual}
@@ -259,7 +269,7 @@ const Select = defineComponent({
259269
optionLabelRender={slots.optionLabel}
260270
maxTagPlaceholder={props.maxTagPlaceholder || slots.maxTagPlaceholder}
261271
showArrow={hasFeedback || showArrow}
262-
></RcSelect>
272+
></RcSelect>,
263273
);
264274
};
265275
},

components/select/index.zh-CN.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ category: Components
33
subtitle: 选择器
44
type: 数据录入
55
title: Select
6-
cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
6+
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*zo76T7KQx2UAAAAAAAAAAAAADrJ8AQ/original
77
---
88

99
下拉选择器。
@@ -60,8 +60,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg
6060
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | 3.3.0 |
6161
| removeIcon | 自定义的多选框清除图标 | VNode \| slot | - | |
6262
| searchValue | 控制搜索文本 | string | - | |
63-
| showArrow | 是否显示下拉小箭头 | boolean | 单选为true,多选为false | |
64-
| showSearch | 配置是否可搜索 | boolean | 单选为false,多选为true | |
63+
| showArrow | 是否显示下拉小箭头 | boolean | 单选为 true,多选为 false | |
64+
| showSearch | 配置是否可搜索 | boolean | 单选为 false,多选为 true | |
6565
| size | 选择框大小,可选 `large` `small` | string | default | |
6666
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
6767
| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | |

components/select/style/dropdown.tsx

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import type { CSSObject } from '../../_util/cssinjs';
2+
import type { SelectToken } from '.';
3+
import {
4+
initMoveMotion,
5+
initSlideMotion,
6+
slideDownIn,
7+
slideDownOut,
8+
slideUpIn,
9+
slideUpOut,
10+
} from '../../_style/motion';
11+
import type { GenerateStyle } from '../../theme/internal';
12+
import { resetComponent, textEllipsis } from '../../_style';
13+
14+
const genItemStyle: GenerateStyle<SelectToken, CSSObject> = token => {
15+
const { controlPaddingHorizontal } = token;
16+
17+
return {
18+
position: 'relative',
19+
display: 'block',
20+
minHeight: token.controlHeight,
21+
padding: `${
22+
(token.controlHeight - token.fontSize * token.lineHeight) / 2
23+
}px ${controlPaddingHorizontal}px`,
24+
color: token.colorText,
25+
fontWeight: 'normal',
26+
fontSize: token.fontSize,
27+
lineHeight: token.lineHeight,
28+
boxSizing: 'border-box',
29+
};
30+
};
31+
32+
const genSingleStyle: GenerateStyle<SelectToken> = token => {
33+
const { antCls, componentCls } = token;
34+
35+
const selectItemCls = `${componentCls}-item`;
36+
37+
return [
38+
{
39+
[`${componentCls}-dropdown`]: {
40+
// ========================== Popup ==========================
41+
...resetComponent(token),
42+
43+
position: 'absolute',
44+
top: -9999,
45+
zIndex: token.zIndexPopup,
46+
boxSizing: 'border-box',
47+
padding: token.paddingXXS,
48+
overflow: 'hidden',
49+
fontSize: token.fontSize,
50+
// Fix select render lag of long text in chrome
51+
// https://github.com/ant-design/ant-design/issues/11456
52+
// https://github.com/ant-design/ant-design/issues/11843
53+
fontVariant: 'initial',
54+
backgroundColor: token.colorBgElevated,
55+
borderRadius: token.borderRadiusLG,
56+
outline: 'none',
57+
boxShadow: token.boxShadowSecondary,
58+
59+
[`
60+
&${antCls}-slide-up-enter${antCls}-slide-up-enter-active${componentCls}-dropdown-placement-bottomLeft,
61+
&${antCls}-slide-up-appear${antCls}-slide-up-appear-active${componentCls}-dropdown-placement-bottomLeft
62+
`]: {
63+
animationName: slideUpIn,
64+
},
65+
66+
[`
67+
&${antCls}-slide-up-enter${antCls}-slide-up-enter-active${componentCls}-dropdown-placement-topLeft,
68+
&${antCls}-slide-up-appear${antCls}-slide-up-appear-active${componentCls}-dropdown-placement-topLeft
69+
`]: {
70+
animationName: slideDownIn,
71+
},
72+
73+
[`&${antCls}-slide-up-leave${antCls}-slide-up-leave-active${componentCls}-dropdown-placement-bottomLeft`]:
74+
{
75+
animationName: slideUpOut,
76+
},
77+
78+
[`&${antCls}-slide-up-leave${antCls}-slide-up-leave-active${componentCls}-dropdown-placement-topLeft`]:
79+
{
80+
animationName: slideDownOut,
81+
},
82+
83+
'&-hidden': {
84+
display: 'none',
85+
},
86+
87+
'&-empty': {
88+
color: token.colorTextDisabled,
89+
},
90+
91+
// ========================= Options =========================
92+
[`${selectItemCls}-empty`]: {
93+
...genItemStyle(token),
94+
color: token.colorTextDisabled,
95+
},
96+
97+
[`${selectItemCls}`]: {
98+
...genItemStyle(token),
99+
cursor: 'pointer',
100+
transition: `background ${token.motionDurationSlow} ease`,
101+
borderRadius: token.borderRadiusSM,
102+
103+
// =========== Group ============
104+
'&-group': {
105+
color: token.colorTextDescription,
106+
fontSize: token.fontSizeSM,
107+
cursor: 'default',
108+
},
109+
110+
// =========== Option ===========
111+
'&-option': {
112+
display: 'flex',
113+
114+
'&-content': {
115+
flex: 'auto',
116+
...textEllipsis,
117+
},
118+
119+
'&-state': {
120+
flex: 'none',
121+
},
122+
123+
[`&-active:not(${selectItemCls}-option-disabled)`]: {
124+
backgroundColor: token.controlItemBgHover,
125+
},
126+
127+
[`&-selected:not(${selectItemCls}-option-disabled)`]: {
128+
color: token.colorText,
129+
fontWeight: token.fontWeightStrong,
130+
backgroundColor: token.controlItemBgActive,
131+
132+
[`${selectItemCls}-option-state`]: {
133+
color: token.colorPrimary,
134+
},
135+
},
136+
'&-disabled': {
137+
[`&${selectItemCls}-option-selected`]: {
138+
backgroundColor: token.colorBgContainerDisabled,
139+
},
140+
141+
color: token.colorTextDisabled,
142+
cursor: 'not-allowed',
143+
},
144+
145+
'&-grouped': {
146+
paddingInlineStart: token.controlPaddingHorizontal * 2,
147+
},
148+
},
149+
},
150+
151+
// =========================== RTL ===========================
152+
'&-rtl': {
153+
direction: 'rtl',
154+
},
155+
},
156+
},
157+
158+
// Follow code may reuse in other components
159+
initSlideMotion(token, 'slide-up'),
160+
initSlideMotion(token, 'slide-down'),
161+
initMoveMotion(token, 'move-up'),
162+
initMoveMotion(token, 'move-down'),
163+
];
164+
};
165+
166+
export default genSingleStyle;

0 commit comments

Comments
 (0)