Skip to content

Commit 1e1a1bd

Browse files
committed
Merge remote-tracking branch 'origin/feat-vue3' into next
2 parents e165b1e + 2fb52d6 commit 1e1a1bd

File tree

14 files changed

+162
-69
lines changed

14 files changed

+162
-69
lines changed

BACKERS.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
<h2 align="center">Backers</h2>
2626
<p align="center">
27+
<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank"><img width="64" style="border-radius: 50%;" src="https://gitee.com/chu1204505056/image/raw/master/vue-admin-beautiful.png" title="vue-admin-beautiful"></a>
2728
<a href="https://github.com/limichange" target="_blank"><img width="64" style="border-radius: 50%;" src="https://avatars0.githubusercontent.com/u/1947344?s=400&v=4" title="limichange donation total 24$ by qq from 2018.9"></a>
2829
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a>
2930
<a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a>

README-zh_CN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Become a sponsor and get your logo on our README on Github with a link to your s
105105

106106
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ant-design-vue#backer)]
107107

108-
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a>
108+
<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank"><img width="64" style="border-radius: 50%;" src="https://gitee.com/chu1204505056/image/raw/master/vue-admin-beautiful.png" title="vue-admin-beautiful"></a> <a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a>
109109

110110
## Patreon
111111

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Become a sponsor and get your logo on our README on Github with a link to your s
9999

100100
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ant-design-vue#backer)]
101101

102-
<a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a><a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a>
102+
<a href="https://github.com/chuzhixin/vue-admin-beautiful" target="_blank"><img width="64" style="border-radius: 50%;" src="https://gitee.com/chu1204505056/image/raw/master/vue-admin-beautiful.png" title="vue-admin-beautiful"></a> <a href="https://opencollective.com/ant-design-vue/backer/0/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/0/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/1/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/1/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/2/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/2/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/3/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/3/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/4/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/4/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/5/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/5/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/6/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/6/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/7/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/7/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/8/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/8/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a> <a href="https://opencollective.com/ant-design-vue/backer/10/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/10/avatar.svg"></a><a href="https://opencollective.com/ant-design-vue/backer/9/website" target="_blank"><img src="https://opencollective.com/ant-design-vue/backer/9/avatar.svg"></a>
103103

104104
## Patreon
105105

components/form/style/index.less

-12
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.tsx

+17-11
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,29 @@ const ClearableLabeledInput = defineComponent({
3535
addonBefore: PropTypes.VNodeChild,
3636
addonAfter: PropTypes.VNodeChild,
3737
readonly: PropTypes.looseBool,
38+
isFocused: PropTypes.looseBool,
3839
},
3940
methods: {
4041
renderClearIcon(prefixCls: string) {
4142
const { allowClear, value, disabled, readonly, inputType, handleReset } = this.$props;
42-
if (
43-
!allowClear ||
44-
disabled ||
45-
readonly ||
46-
value === undefined ||
47-
value === null ||
48-
value === ''
49-
) {
43+
if (!allowClear) {
5044
return null;
5145
}
46+
const showClearIcon =
47+
!disabled && !readonly && value !== undefined && value !== null && value !== '';
5248
const className =
5349
inputType === ClearableInputType[0]
5450
? `${prefixCls}-textarea-clear-icon`
5551
: `${prefixCls}-clear-icon`;
56-
return <CloseCircleFilled onClick={handleReset} class={className} role="button" />;
52+
return (
53+
<CloseCircleFilled
54+
onClick={handleReset}
55+
class={classNames(className, {
56+
[`${className}-hidden`]: !showClearIcon,
57+
})}
58+
role="button"
59+
/>
60+
);
5761
},
5862

5963
renderSuffix(prefixCls: string) {
@@ -71,6 +75,7 @@ const ClearableLabeledInput = defineComponent({
7175

7276
renderLabeledIcon(prefixCls: string, element: VNode): VNode {
7377
const props = this.$props;
78+
const { style } = this.$attrs;
7479
const suffix = this.renderSuffix(prefixCls);
7580
if (!hasPrefixSuffix(this)) {
7681
return cloneElement(element, {
@@ -83,14 +88,15 @@ const ClearableLabeledInput = defineComponent({
8388
) : null;
8489

8590
const affixWrapperCls = classNames(this.$attrs?.class, `${prefixCls}-affix-wrapper`, {
91+
[`${prefixCls}-affix-wrapper-focused`]: props.isFocused,
92+
[`${prefixCls}-affix-wrapper-disabled`]: props.disabled,
8693
[`${prefixCls}-affix-wrapper-sm`]: props.size === 'small',
8794
[`${prefixCls}-affix-wrapper-lg`]: props.size === 'large',
8895
[`${prefixCls}-affix-wrapper-input-with-clear-btn`]:
8996
props.suffix && props.allowClear && this.$props.value,
9097
});
91-
9298
return (
93-
<span class={affixWrapperCls} style={this.$attrs?.style}>
99+
<span class={affixWrapperCls} style={style}>
94100
{prefix}
95101
{cloneElement(element, {
96102
style: null,

components/input/Input.tsx

+24-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export default defineComponent({
6767
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
6868
return {
6969
stateValue: typeof value === 'undefined' ? '' : value,
70+
isFocused: false,
7071
};
7172
},
7273
watch: {
@@ -90,6 +91,16 @@ export default defineComponent({
9091
}
9192
},
9293
methods: {
94+
handleInputFocus(e) {
95+
this.isFocused = true;
96+
this.onFocus && this.onFocus(e);
97+
},
98+
99+
handleInputBlur(e) {
100+
this.isFocused = false;
101+
this.onBlur && this.onBlur(e);
102+
},
103+
93104
focus() {
94105
this.input.focus();
95106
},
@@ -148,7 +159,15 @@ export default defineComponent({
148159
'inputPrefixCls',
149160
'loading',
150161
]);
151-
const { handleKeyDown, handleChange, size, disabled, $attrs } = this;
162+
const {
163+
handleKeyDown,
164+
handleChange,
165+
handleInputFocus,
166+
handleInputBlur,
167+
size,
168+
disabled,
169+
$attrs,
170+
} = this;
152171

153172
const inputProps: any = {
154173
...otherProps,
@@ -161,6 +180,8 @@ export default defineComponent({
161180
key: 'ant-input',
162181
onInput: handleChange,
163182
onChange: handleChange,
183+
onFocus: handleInputFocus,
184+
onBlur: handleInputBlur,
164185
};
165186
if (!inputProps.autofocus) {
166187
delete inputProps.autofocus;
@@ -197,7 +218,7 @@ export default defineComponent({
197218
},
198219
render() {
199220
const { prefixCls: customizePrefixCls } = this.$props;
200-
const { stateValue } = this.$data;
221+
const { stateValue, isFocused } = this.$data;
201222
const getPrefixCls = this.configProvider.getPrefixCls;
202223
const prefixCls = getPrefixCls('input', customizePrefixCls);
203224
const addonAfter = getComponent(this, 'addonAfter');
@@ -216,6 +237,7 @@ export default defineComponent({
216237
addonBefore,
217238
suffix,
218239
prefix,
240+
isFocused,
219241
};
220242
return <ClearableLabeledInput {...props} ref={this.saveClearableInput} />;
221243
},

components/input/TextArea.tsx

+35-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import inputProps from './inputProps';
55
import { hasProp, getOptionProps } from '../_util/props-util';
66
import { defaultConfigProvider } from '../config-provider';
77
import { fixControlledValue, resolveOnChange } from './Input';
8+
import classNames from '../_util/classNames';
89
import PropTypes, { withUndefined } from '../_util/vue-types';
910

1011
const TextAreaProps = {
1112
...inputProps,
1213
autosize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
1314
autoSize: withUndefined(PropTypes.oneOfType([Object, Boolean])),
15+
showCount: PropTypes.looseBool,
1416
};
1517

1618
export default defineComponent({
@@ -102,9 +104,13 @@ export default defineComponent({
102104

103105
renderTextArea(prefixCls: string) {
104106
const props = getOptionProps(this);
107+
const { style, class: customClass } = this.$attrs;
105108
const resizeProps = {
106109
...props,
107110
...this.$attrs,
111+
style: style && !props.showCount,
112+
class: customClass && !props.showCount,
113+
showCount: null,
108114
prefixCls,
109115
onInput: this.handleChange,
110116
onChange: this.handleChange,
@@ -114,19 +120,44 @@ export default defineComponent({
114120
},
115121
},
116122
render() {
117-
const { stateValue, prefixCls: customizePrefixCls } = this;
123+
const { stateValue, prefixCls: customizePrefixCls, maxlength, showCount } = this;
124+
const { style, class: customClass } = this.$attrs;
118125
const getPrefixCls = this.configProvider.getPrefixCls;
119126
const prefixCls = getPrefixCls('input', customizePrefixCls);
120-
127+
let value = fixControlledValue(stateValue);
128+
// Max length value
129+
const hasMaxlength = Number(maxlength) > 0;
130+
value = hasMaxlength ? value.slice(0, maxlength) : value;
121131
const props: any = {
122132
...getOptionProps(this),
123133
...this.$attrs,
124134
prefixCls,
125135
inputType: 'text',
126-
value: fixControlledValue(stateValue),
127136
element: this.renderTextArea(prefixCls),
128137
handleReset: this.handleReset,
129138
};
130-
return <ClearableLabeledInput {...props} ref={this.saveClearableInput} />;
139+
140+
let textareaNode = (
141+
<ClearableLabeledInput {...props} value={value} ref={this.saveClearableInput} />
142+
);
143+
144+
if (showCount) {
145+
const valueLength = [...value].length;
146+
const dataCount = `${valueLength}${hasMaxlength ? ` / ${maxlength}` : ''}`;
147+
textareaNode = (
148+
<div
149+
class={classNames(
150+
`${prefixCls}-textarea`,
151+
`${prefixCls}-textarea-show-count`,
152+
customClass,
153+
)}
154+
style={style}
155+
data-count={dataCount}
156+
>
157+
{textareaNode}
158+
</div>
159+
);
160+
}
161+
return textareaNode;
131162
},
132163
});

components/input/__tests__/__snapshots__/index.test.js.snap

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ exports[`Input.Search should support suffix 1`] = `<span class="ant-input-search
77
exports[`TextArea should support disabled 1`] = `<textarea disabled="" class="ant-input ant-input-disabled"></textarea>`;
88
99
exports[`TextArea should support maxlength 1`] = `<textarea maxlength="10" class="ant-input"></textarea>`;
10+
11+
exports[`TextArea should support showCount 1`] = `<div class="ant-input-textarea ant-input-textarea-show-count" data-count="3 / 10"><textarea maxlength="10" class="ant-input"></textarea></div>`;

components/input/__tests__/index.test.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('Input', () => {
2929
props: { allowClear: true, defaultValue: '111', disabled: true },
3030
sync: false,
3131
});
32-
expect(wrapper.findAll('.ant-input-clear-icon').length).toBe(0);
32+
expect(wrapper.findAll('.ant-input-clear-icon-hidden').length).toBeTruthy();
3333
});
3434
});
3535

@@ -68,6 +68,17 @@ describe('TextArea', () => {
6868
expect(wrapper.html()).toMatchSnapshot();
6969
});
7070
});
71+
72+
it('should support showCount', async () => {
73+
const wrapper = mount(TextArea, {
74+
props: { showCount: true, defaultValue: '111', maxlength: 10 },
75+
sync: false,
76+
});
77+
expect(wrapper.find('.ant-input-textarea-show-count')).toBeTruthy();
78+
await asyncExpect(() => {
79+
expect(wrapper.html()).toMatchSnapshot();
80+
});
81+
});
7182
});
7283

7384
// describe('As Form Control', () => {

components/input/style/index.less

+17
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;
@@ -49,4 +57,13 @@
4957
margin: 8px 8px 0 0;
5058
}
5159

60+
.@{ant-prefix}-input-textarea {
61+
&-show-count::after {
62+
display: block;
63+
color: @text-color-secondary;
64+
text-align: right;
65+
content: attr(data-count);
66+
}
67+
}
68+
5269
@import './search-input';

0 commit comments

Comments
 (0)