Skip to content

Commit ca2c77e

Browse files
authored
refactor(input): update input style (#2876)
* refactor(input): update input style * refactor(form): update form style about input component * refactor(input): update clearable icon style Modify the clearable icon style to prevent the width of the input box from changing due to the insertion of the icon
1 parent 51fb7cd commit ca2c77e

File tree

6 files changed

+87
-60
lines changed

6 files changed

+87
-60
lines changed

components/form/style/index.less

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,23 +136,11 @@
136136

137137
form {
138138
.has-feedback {
139-
.@{ant-prefix}-input {
140-
padding-right: @input-padding-horizontal-base + @input-affix-width;
141-
}
142-
143139
// https://github.com/ant-design/ant-design/issues/19884
144140
.@{ant-prefix}-input-affix-wrapper {
145141
.@{ant-prefix}-input-suffix {
146142
padding-right: 18px;
147143
}
148-
.@{ant-prefix}-input {
149-
padding-right: @input-padding-horizontal-base + @input-affix-width * 2;
150-
}
151-
&.@{ant-prefix}-input-affix-wrapper-input-with-clear-btn {
152-
.@{ant-prefix}-input {
153-
padding-right: @input-padding-horizontal-base + @input-affix-width * 3;
154-
}
155-
}
156144
}
157145

158146
// Fix overlapping between feedback icon and <Select>'s arrow.

components/input/ClearableLabeledInput.jsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,30 @@ const ClearableLabeledInput = {
3333
addonBefore: PropTypes.any,
3434
addonAfter: PropTypes.any,
3535
readonly: PropTypes.bool,
36+
isFocused: PropTypes.bool,
37+
style: PropTypes.object,
3638
},
3739
methods: {
3840
renderClearIcon(prefixCls) {
3941
const { allowClear, value, disabled, readonly, inputType, handleReset } = this.$props;
40-
if (
41-
!allowClear ||
42-
disabled ||
43-
readonly ||
44-
value === undefined ||
45-
value === null ||
46-
value === ''
47-
) {
42+
if (!allowClear) {
4843
return null;
4944
}
45+
const showClearIcon =
46+
!disabled && !readonly && value !== undefined && value !== null && value !== '';
5047
const className =
5148
inputType === ClearableInputType[0]
5249
? `${prefixCls}-textarea-clear-icon`
5350
: `${prefixCls}-clear-icon`;
54-
return <CloseCircleFilled onClick={handleReset} class={className} role="button" />;
51+
return (
52+
<CloseCircleFilled
53+
onClick={handleReset}
54+
class={classNames(className, {
55+
[`${className}-hidden`]: !showClearIcon,
56+
})}
57+
role="button"
58+
/>
59+
);
5560
},
5661

5762
renderSuffix(prefixCls) {
@@ -81,12 +86,13 @@ const ClearableLabeledInput = {
8186
) : null;
8287

8388
const affixWrapperCls = classNames(this.$attrs?.class, `${prefixCls}-affix-wrapper`, {
89+
[`${prefixCls}-affix-wrapper-focused`]: props.isFocused,
90+
[`${prefixCls}-affix-wrapper-disabled`]: props.disabled,
8491
[`${prefixCls}-affix-wrapper-sm`]: props.size === 'small',
8592
[`${prefixCls}-affix-wrapper-lg`]: props.size === 'large',
8693
[`${prefixCls}-affix-wrapper-input-with-clear-btn`]:
8794
props.suffix && props.allowClear && this.$props.value,
8895
});
89-
9096
return (
9197
<span class={affixWrapperCls} style={props.style}>
9298
{prefix}

components/input/Input.jsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ export default {
6464
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
6565
return {
6666
stateValue: typeof value === 'undefined' ? '' : value,
67+
isFocused: false,
6768
};
6869
},
6970
watch: {
@@ -87,6 +88,16 @@ export default {
8788
}
8889
},
8990
methods: {
91+
handleInputFocus(e) {
92+
this.isFocused = true;
93+
this.onFocus && this.onFocus(e);
94+
},
95+
96+
handleInputBlur(e) {
97+
this.isFocused = false;
98+
this.onBlur && this.onBlur(e);
99+
},
100+
90101
focus() {
91102
this.input.focus();
92103
},
@@ -147,7 +158,15 @@ export default {
147158
'inputPrefixCls',
148159
'loading',
149160
]);
150-
const { handleKeyDown, handleChange, size, disabled, $attrs } = this;
161+
const {
162+
handleKeyDown,
163+
handleChange,
164+
handleInputFocus,
165+
handleInputBlur,
166+
size,
167+
disabled,
168+
$attrs,
169+
} = this;
151170

152171
const inputProps = {
153172
...otherProps,
@@ -160,6 +179,8 @@ export default {
160179
key: 'ant-input',
161180
onInput: handleChange,
162181
onChange: handleChange,
182+
onFocus: handleInputFocus,
183+
onBlur: handleInputBlur,
163184
};
164185
if (!inputProps.autofocus) {
165186
delete inputProps.autofocus;
@@ -205,7 +226,7 @@ export default {
205226
// return <TextArea {...textareaProps} ref="input" />;
206227
// }
207228
const { prefixCls: customizePrefixCls } = this.$props;
208-
const { stateValue } = this.$data;
229+
const { stateValue, isFocused } = this.$data;
209230
const getPrefixCls = this.configProvider.getPrefixCls;
210231
const prefixCls = getPrefixCls('input', customizePrefixCls);
211232
const addonAfter = getComponent(this, 'addonAfter');
@@ -224,6 +245,7 @@ export default {
224245
addonBefore,
225246
suffix,
226247
prefix,
248+
isFocused,
227249
};
228250
return <ClearableLabeledInput {...props} ref={this.saveClearableInput} />;
229251
},

components/input/style/index.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@
4141
vertical-align: 0;
4242
}
4343

44+
.@{ant-prefix}-input-clear-icon-hidden {
45+
visibility: hidden;
46+
}
47+
48+
.@{ant-prefix}-input-textarea-clear-icon-hidden {
49+
visibility: hidden;
50+
}
51+
4452
.@{ant-prefix}-input-textarea-clear-icon {
4553
.clear-icon;
4654
position: absolute;

components/input/style/mixin.less

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
@import '../../style/themes/index';
22
@import '../../style/mixins/index';
33

4+
@input-affix-margin: 4px;
45
@input-affix-width: 19px;
56
@input-affix-with-clear-btn-width: 38px;
67

78
// size mixins for input
89
.input-lg() {
9-
height: @input-height-lg;
1010
padding: @input-padding-vertical-lg @input-padding-horizontal-lg;
1111
font-size: @font-size-lg;
1212
}
1313

1414
.input-sm() {
15-
height: @input-height-sm;
1615
padding: @input-padding-vertical-sm @input-padding-horizontal-sm;
1716
}
1817

@@ -47,7 +46,6 @@
4746
position: relative;
4847
display: inline-block;
4948
width: 100%;
50-
height: @input-height-base;
5149
padding: @input-padding-vertical-base @input-padding-horizontal-base;
5250
color: @input-color;
5351
font-size: @font-size-base;
@@ -264,12 +262,6 @@
264262
height: @input-height-sm;
265263
}
266264

267-
.@{inputClass}-affix-wrapper {
268-
display: table-cell;
269-
float: left;
270-
width: 100%;
271-
}
272-
273265
&&-compact {
274266
display: block;
275267
.clearfix;
@@ -297,6 +289,10 @@
297289
border-radius: 0;
298290
}
299291

292+
& > .@{inputClass}-affix-wrapper {
293+
display: inline-flex;
294+
}
295+
300296
& > *:not(:last-child) {
301297
margin-right: -@border-width-base;
302298
border-right-width: @border-width-base;
@@ -364,17 +360,44 @@
364360

365361
.input-affix-wrapper(@inputClass) {
366362
position: relative;
367-
display: inline-block;
363+
display: inline-flex;
364+
border: @border-width-base @border-style-base @input-border-color;
365+
border-radius: @border-radius-base;
366+
padding: @input-padding-vertical-base @input-padding-horizontal-base;
368367
width: 100%;
369368
text-align: start;
370369

371-
&:hover .@{inputClass}:not(.@{inputClass}-disabled) {
370+
&:hover {
372371
.hover();
373372
}
374373

374+
&-disabled {
375+
.disabled();
376+
}
377+
378+
&-focused {
379+
.active();
380+
}
381+
382+
// Size
383+
&-lg {
384+
.input-lg();
385+
}
386+
387+
&-sm {
388+
.input-sm();
389+
}
390+
375391
.@{inputClass} {
376392
position: relative;
377393
text-align: inherit;
394+
border: none;
395+
padding: 0;
396+
&:focus {
397+
border: none;
398+
outline: none;
399+
box-shadow: none;
400+
}
378401
}
379402

380403
// Should not break align of icon & text
@@ -385,14 +408,10 @@
385408
// https://codesandbox.io/embed/nifty-benz-gb7ml
386409
.@{inputClass}-prefix,
387410
.@{inputClass}-suffix {
388-
position: absolute;
389-
top: 50%;
390-
z-index: 2;
391411
display: flex;
392412
align-items: center;
393413
color: @input-color;
394-
line-height: 0;
395-
transform: translateY(-50%);
414+
white-space: nowrap;
396415

397416
:not(.anticon) {
398417
line-height: @line-height-base;
@@ -407,27 +426,11 @@
407426
}
408427

409428
.@{inputClass}-prefix {
410-
left: @input-padding-horizontal-base + 1px;
429+
margin-right: @input-affix-margin;
411430
}
412431

413432
.@{inputClass}-suffix {
414-
right: @input-padding-horizontal-base + 1px;
415-
}
416-
417-
.@{inputClass}:not(:first-child) {
418-
padding-left: @input-padding-horizontal-base + @input-affix-width;
419-
}
420-
421-
.@{inputClass}:not(:last-child) {
422-
padding-right: @input-padding-horizontal-base + @input-affix-width;
423-
}
424-
425-
&.@{inputClass}-affix-wrapper-input-with-clear-btn .@{inputClass}:not(:last-child) {
426-
padding-right: @input-padding-horizontal-base + @input-affix-with-clear-btn-width;
427-
}
428-
429-
&.@{inputClass}-affix-wrapper-textarea-with-clear-btn .@{inputClass} {
430-
padding-right: 22px;
433+
margin-left: @input-affix-margin;
431434
}
432435
}
433436

@@ -438,7 +441,7 @@
438441
// https://codesandbox.io/s/wizardly-sun-u10br
439442
cursor: pointer;
440443
transition: color 0.3s;
441-
444+
margin: 0 @input-affix-margin;
442445
&:hover {
443446
color: @text-color-secondary;
444447
}

components/style/themes/default.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
@input-padding-horizontal-lg: @input-padding-horizontal;
319319
@input-padding-vertical-base: 4px;
320320
@input-padding-vertical-sm: 1px;
321-
@input-padding-vertical-lg: 6px;
321+
@input-padding-vertical-lg: 6.5px;
322322
@input-placeholder-color: hsv(0, 0, 75%);
323323
@input-color: @text-color;
324324
@input-border-color: @border-color-base;

0 commit comments

Comments
 (0)