Skip to content

Commit 656d14f

Browse files
committed
feat: add select responsive
1 parent 501204c commit 656d14f

21 files changed

+364
-286
lines changed

components/select/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface LabeledValue {
2020
label: VNodeChild;
2121
}
2222
export type SizeType = 'small' | 'middle' | 'large' | undefined;
23-
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[];
23+
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[] | undefined;
2424

2525
export interface InternalSelectProps<VT> extends Omit<RcSelectProps<VT>, 'mode'> {
2626
suffixIcon?: VNodeChild;

components/select/style/index.less

+17-7
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
background: @input-disabled-bg;
3838
cursor: not-allowed;
3939

40+
.@{select-prefix-cls}-multiple& {
41+
background: @select-multiple-disabled-background;
42+
}
43+
4044
input {
4145
cursor: not-allowed;
4246
}
@@ -66,7 +70,12 @@
6670
display: inline-block;
6771
cursor: pointer;
6872

69-
&:not(.@{select-prefix-cls}-disabled):hover &-selector {
73+
&:not(&-customize-input) &-selector {
74+
.select-selector();
75+
.select-search-input-without-border();
76+
}
77+
78+
&:not(&-disabled):hover &-selector {
7079
.hover();
7180
}
7281

@@ -93,6 +102,7 @@
93102
color: @input-placeholder-color;
94103
white-space: nowrap;
95104
text-overflow: ellipsis;
105+
pointer-events: none;
96106

97107
// IE11 css hack. `*::-ms-backdrop,` is a must have
98108
@media all and (-ms-high-contrast: none) {
@@ -189,21 +199,21 @@
189199
outline: none;
190200
box-shadow: @box-shadow-base;
191201

192-
&.slide-up-enter.slide-up-enter-active&-placement-bottomLeft,
193-
&.slide-up-appear.slide-up-appear-active&-placement-bottomLeft {
202+
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-bottomLeft,
203+
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-bottomLeft {
194204
animation-name: antSlideUpIn;
195205
}
196206

197-
&.slide-up-enter.slide-up-enter-active&-placement-topLeft,
198-
&.slide-up-appear.slide-up-appear-active&-placement-topLeft {
207+
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topLeft,
208+
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topLeft {
199209
animation-name: antSlideDownIn;
200210
}
201211

202-
&.slide-up-leave.slide-up-leave-active&-placement-bottomLeft {
212+
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-bottomLeft {
203213
animation-name: antSlideUpOut;
204214
}
205215

206-
&.slide-up-leave.slide-up-leave-active&-placement-topLeft {
216+
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topLeft {
207217
animation-name: antSlideDownOut;
208218
}
209219

components/select/style/multiple.less

+39-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@import './index';
22

3+
@select-overflow-prefix-cls: ~'@{select-prefix-cls}-selection-overflow';
34
@select-multiple-item-border-width: 1px;
45

56
@select-multiple-padding: max(
@@ -13,13 +14,25 @@
1314
* since chrome may update to redesign with its align logic.
1415
*/
1516

17+
// =========================== Overflow ===========================
18+
.@{select-overflow-prefix-cls} {
19+
position: relative;
20+
display: flex;
21+
flex: auto;
22+
flex-wrap: wrap;
23+
max-width: 100%;
24+
25+
&-item {
26+
flex: none;
27+
align-self: center;
28+
max-width: 100%;
29+
}
30+
}
31+
1632
.@{select-prefix-cls} {
1733
&-multiple {
1834
// ========================= Selector =========================
1935
.@{select-prefix-cls}-selector {
20-
.select-selector();
21-
.select-search-input-without-border();
22-
2336
display: flex;
2437
flex-wrap: wrap;
2538
align-items: center;
@@ -59,16 +72,17 @@
5972

6073
height: @select-multiple-item-height;
6174
margin-top: @select-multiple-item-spacing-half;
62-
margin-right: @input-padding-vertical-base;
6375
margin-bottom: @select-multiple-item-spacing-half;
64-
padding: 0 (@padding-xs / 2) 0 @padding-xs;
6576
line-height: @select-multiple-item-height - @select-multiple-item-border-width * 2;
6677
background: @select-selection-item-bg;
6778
border: 1px solid @select-selection-item-border-color;
6879
border-radius: @border-radius-base;
6980
cursor: default;
7081
transition: font-size 0.3s, line-height 0.3s, height 0.3s;
7182
user-select: none;
83+
margin-inline-end: @input-padding-vertical-base;
84+
padding-inline-start: @padding-xs;
85+
padding-inline-end: (@padding-xs / 2);
7286

7387
.@{select-prefix-cls}-disabled& {
7488
color: @select-multiple-item-disabled-color;
@@ -81,7 +95,7 @@
8195
display: inline-block;
8296
margin-right: (@padding-xs / 2);
8397
overflow: hidden;
84-
white-space: nowrap;
98+
white-space: pre; // fix whitespace wrapping. custom tags display all whitespace within.
8599
text-overflow: ellipsis;
86100
}
87101

@@ -90,10 +104,9 @@
90104
display: inline-block;
91105
color: @text-color-secondary;
92106
font-weight: bold;
93-
font-size: @font-size-sm;
107+
font-size: 10px;
94108
line-height: inherit;
95109
cursor: pointer;
96-
.iconfont-size-under-12px(10px);
97110

98111
> .@{iconfont-css-prefix} {
99112
vertical-align: -0.2em;
@@ -106,14 +119,24 @@
106119
}
107120

108121
// ========================== Input ==========================
122+
.@{select-overflow-prefix-cls}-item + .@{select-overflow-prefix-cls}-item {
123+
.@{select-prefix-cls}-selection-search {
124+
margin-inline-start: 0;
125+
}
126+
}
127+
109128
.@{select-prefix-cls}-selection-search {
110129
position: relative;
111-
margin-left: (@select-multiple-padding / 2);
130+
max-width: 100%;
131+
margin-top: @select-multiple-item-spacing-half;
132+
margin-bottom: @select-multiple-item-spacing-half;
133+
margin-inline-start: @input-padding-horizontal-base - @input-padding-vertical-base;
112134

113135
&-input,
114136
&-mirror {
137+
height: @select-multiple-item-height;
115138
font-family: @font-family;
116-
line-height: @line-height-base;
139+
line-height: @select-multiple-item-height;
117140
transition: all 0.3s;
118141
}
119142

@@ -127,14 +150,9 @@
127150
top: 0;
128151
left: 0;
129152
z-index: 999;
130-
white-space: nowrap;
153+
white-space: pre; // fix whitespace wrapping caused width calculation bug
131154
visibility: hidden;
132155
}
133-
134-
// https://github.com/ant-design/ant-design/issues/22906
135-
&:first-child .@{select-prefix-cls}-selection-search-input {
136-
margin-left: 6.5px;
137-
}
138156
}
139157

140158
// ======================= Placeholder =======================
@@ -166,8 +184,8 @@
166184
}
167185

168186
.@{select-prefix-cls}-selection-search {
169-
height: @select-selection-height + @select-multiple-padding;
170-
line-height: @select-selection-height + @select-multiple-padding;
187+
height: @select-selection-height;
188+
line-height: @select-selection-height;
171189

172190
&-input,
173191
&-mirror {
@@ -186,10 +204,9 @@
186204
.@{select-prefix-cls}-selection-placeholder {
187205
left: @input-padding-horizontal-sm;
188206
}
189-
// https://github.com/ant-design/ant-design/issues/22906
190-
.@{select-prefix-cls}-selection-search:first-child
191-
.@{select-prefix-cls}-selection-search-input {
192-
margin-left: 3px;
207+
// https://github.com/ant-design/ant-design/issues/29559
208+
.@{select-prefix-cls}-selection-search {
209+
margin-inline-start: 3px;
193210
}
194211
}
195212
&.@{select-prefix-cls}-lg {

components/select/style/rtl.less

+2-22
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@
6666
// ======================== Selections ========================
6767
.@{select-prefix-cls}-selection-item {
6868
.@{select-prefix-cls}-rtl& {
69-
margin-right: 0;
70-
margin-left: @input-padding-vertical-base;
71-
padding: 0 @padding-xs 0 (@padding-xs / 2);
7269
text-align: right;
7370
}
7471
// It's ok not to do this, but 24px makes bottom narrow in view should adjust
@@ -83,11 +80,6 @@
8380

8481
// ========================== Input ==========================
8582
.@{select-prefix-cls}-selection-search {
86-
.@{select-prefix-cls}-rtl& {
87-
margin-right: (@select-multiple-padding / 2);
88-
margin-left: @input-padding-vertical-base;
89-
}
90-
9183
&-mirror {
9284
.@{select-prefix-cls}-rtl& {
9385
right: 0;
@@ -119,7 +111,7 @@
119111
}
120112

121113
// single
122-
@selection-item-padding: ceil((@font-size-base * 1.25));
114+
@selection-item-padding: ceil(@font-size-base * 1.25);
123115

124116
.@{select-prefix-cls}-single {
125117
// ========================= Selector =========================
@@ -150,18 +142,6 @@
150142
}
151143
}
152144

153-
// ========================== Input ==========================
154-
// We only change the style of non-customize input which is only support by `combobox` mode.
155-
156-
// Not customize
157-
&:not(.@{select-prefix-cls}-customize-input) {
158-
.@{select-prefix-cls}-selector {
159-
.@{select-prefix-cls}-rtl& {
160-
padding: 0 @input-padding-horizontal-base;
161-
}
162-
}
163-
}
164-
165145
// ============================================================
166146
// == Size ==
167147
// ============================================================
@@ -172,7 +152,7 @@
172152
// With arrow should provides `padding-right` to show the arrow
173153
&.@{select-prefix-cls}-show-arrow .@{select-prefix-cls}-selection-search {
174154
.@{select-prefix-cls}-rtl& {
175-
right: 0;
155+
right: @input-padding-horizontal-sm - 1px;
176156
}
177157
}
178158

components/select/style/single.less

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@import './index';
22

3-
@selection-item-padding: ceil((@font-size-base * 1.25));
3+
@selection-item-padding: ceil(@font-size-base * 1.25);
44

55
.@{select-prefix-cls}-single {
66
// ========================= Selector =========================
@@ -76,10 +76,7 @@
7676
// Not customize
7777
&:not(.@{select-prefix-cls}-customize-input) {
7878
.@{select-prefix-cls}-selector {
79-
.select-selector();
80-
.select-search-input-without-border();
8179
width: 100%;
82-
8380
height: @input-height-base;
8481
padding: 0 @input-padding-horizontal-base;
8582

components/vc-overflow/Item.tsx

+11-13
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,17 @@ export default defineComponent({
9090
</Component>
9191
);
9292

93-
if (responsive) {
94-
itemNode = (
95-
<ResizeObserver
96-
onResize={({ offsetWidth }) => {
97-
internalRegisterSize(offsetWidth);
98-
}}
99-
>
100-
{itemNode}
101-
</ResizeObserver>
102-
);
103-
}
104-
105-
return itemNode;
93+
// 使用 disabled 避免结构不一致 导致子组件 rerender
94+
return (
95+
<ResizeObserver
96+
disabled={!responsive}
97+
onResize={({ offsetWidth }) => {
98+
internalRegisterSize(offsetWidth);
99+
}}
100+
>
101+
{itemNode}
102+
</ResizeObserver>
103+
);
106104
};
107105
},
108106
});

components/vc-overflow/Overflow.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,12 @@ const Overflow = defineComponent({
370370
)}
371371
</Component>
372372
);
373-
374-
if (isResponsive.value) {
375-
overflowNode = <ResizeObserver onResize={onOverflowResize}>{overflowNode}</ResizeObserver>;
376-
}
377-
378-
return overflowNode;
373+
// 使用 disabled 避免结构不一致 导致子组件 rerender
374+
return (
375+
<ResizeObserver disabled={!isResponsive.value} onResize={onOverflowResize}>
376+
{overflowNode}
377+
</ResizeObserver>
378+
);
379379
};
380380
},
381381
});

components/vc-select/OptionList.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ const OptionList = defineComponent<OptionListProps, { state?: any }>({
237237
// >>> Close
238238
case KeyCode.ESC: {
239239
props.onToggleOpen(false);
240+
if (props.open) {
241+
event.stopPropagation();
242+
}
240243
}
241244
}
242245
},

components/vc-select/Select.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import generateSelector, { SelectProps } from './generate';
4646
import { DefaultValueType } from './interface/generator';
4747
import warningProps from './utils/warningPropsUtil';
4848
import { defineComponent, ref } from 'vue';
49-
import { getSlot } from '../_util/props-util';
5049
import omit from 'lodash-es/omit';
5150

5251
const RefSelect = generateSelector<SelectOptionsType>({
@@ -69,21 +68,27 @@ export type ExportedSelectProps<
6968
> = SelectProps<SelectOptionsType, ValueType>;
7069

7170
const Select = defineComponent<Omit<ExportedSelectProps, 'children'>>({
72-
setup() {
71+
setup(props, { attrs, expose, slots }) {
7372
const selectRef = ref(null);
74-
return {
75-
selectRef,
73+
expose({
7674
focus: () => {
7775
selectRef.value?.focus();
7876
},
7977
blur: () => {
8078
selectRef.value?.blur();
8179
},
80+
});
81+
return () => {
82+
return (
83+
<RefSelect
84+
ref={selectRef}
85+
{...(props as any)}
86+
{...attrs}
87+
children={slots.default?.() || []}
88+
/>
89+
);
8290
};
8391
},
84-
render() {
85-
return <RefSelect ref="selectRef" {...this.$props} {...this.$attrs} children={getSlot(this)} />;
86-
},
8792
});
8893
Select.inheritAttrs = false;
8994
Select.props = omit(RefSelect.props, ['children']);

0 commit comments

Comments
 (0)