@@ -3,11 +3,14 @@ import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
3
3
import PropTypes from '../_util/vue-types' ;
4
4
import { cloneElement } from '../_util/vnode' ;
5
5
import type { PropType , VNode } from 'vue' ;
6
- import { ref , defineComponent } from 'vue' ;
6
+ import { defineComponent } from 'vue' ;
7
7
import { tuple } from '../_util/type' ;
8
8
import type { Direction , SizeType } from '../config-provider' ;
9
9
import type { MouseEventHandler } from '../_util/EventInterface' ;
10
- import { getInputClassName , hasAddon , hasPrefixSuffix } from './util' ;
10
+ import { hasAddon } from './util' ;
11
+ import { FormItemInputContext } from '../form/FormItemContext' ;
12
+ import type { InputStatus } from '../_util/statusUtils' ;
13
+ import { getMergedStatus , getStatusClassNames } from '../_util/statusUtils' ;
11
14
12
15
const ClearableInputType = [ 'text' , 'input' ] ;
13
16
@@ -34,20 +37,13 @@ export default defineComponent({
34
37
bordered : { type : Boolean , default : true } ,
35
38
triggerFocus : { type : Function as PropType < ( ) => void > } ,
36
39
hidden : Boolean ,
40
+ status : String as PropType < InputStatus > ,
37
41
} ,
38
42
setup ( props , { slots, attrs } ) {
39
- const containerRef = ref ( ) ;
40
- const onInputMouseUp : MouseEventHandler = e => {
41
- if ( containerRef . value ?. contains ( e . target as Element ) ) {
42
- const { triggerFocus } = props ;
43
- triggerFocus ?.( ) ;
44
- }
45
- } ;
43
+ const statusContext = FormItemInputContext . useInject ( ) ;
44
+
46
45
const renderClearIcon = ( prefixCls : string ) => {
47
- const { allowClear, value, disabled, readonly, handleReset, suffix = slots . suffix } = props ;
48
- if ( ! allowClear ) {
49
- return null ;
50
- }
46
+ const { value, disabled, readonly, handleReset, suffix = slots . suffix } = props ;
51
47
const needClear = ! disabled && ! readonly && value ;
52
48
const className = `${ prefixCls } -clear-icon` ;
53
49
return (
@@ -66,133 +62,20 @@ export default defineComponent({
66
62
/>
67
63
) ;
68
64
} ;
69
-
70
- const renderSuffix = ( prefixCls : string ) => {
71
- const { suffix = slots . suffix ?.( ) , allowClear } = props ;
72
- if ( suffix || allowClear ) {
73
- return (
74
- < span class = { `${ prefixCls } -suffix` } >
75
- { renderClearIcon ( prefixCls ) }
76
- { suffix }
77
- </ span >
78
- ) ;
79
- }
80
- return null ;
81
- } ;
82
-
83
- const renderLabeledIcon = ( prefixCls : string , element : VNode ) => {
65
+ const renderTextAreaWithClearIcon = ( prefixCls : string , element : VNode ) => {
84
66
const {
85
- focused,
86
67
value,
87
- prefix = slots . prefix ?.( ) ,
88
- size,
89
- suffix = slots . suffix ?.( ) ,
90
- disabled,
91
68
allowClear,
92
69
direction,
93
- readonly,
94
70
bordered,
95
71
hidden,
72
+ status : customStatus ,
96
73
addonAfter = slots . addonAfter ,
97
74
addonBefore = slots . addonBefore ,
98
75
} = props ;
99
- const suffixNode = renderSuffix ( prefixCls ) ;
100
- if ( ! hasPrefixSuffix ( { prefix, suffix, allowClear } ) ) {
101
- return cloneElement ( element , {
102
- value,
103
- } ) ;
104
- }
105
-
106
- const prefixNode = prefix ? < span class = { `${ prefixCls } -prefix` } > { prefix } </ span > : null ;
107
-
108
- const affixWrapperCls = classNames ( `${ prefixCls } -affix-wrapper` , {
109
- [ `${ prefixCls } -affix-wrapper-focused` ] : focused ,
110
- [ `${ prefixCls } -affix-wrapper-disabled` ] : disabled ,
111
- [ `${ prefixCls } -affix-wrapper-sm` ] : size === 'small' ,
112
- [ `${ prefixCls } -affix-wrapper-lg` ] : size === 'large' ,
113
- [ `${ prefixCls } -affix-wrapper-input-with-clear-btn` ] : suffix && allowClear && value ,
114
- [ `${ prefixCls } -affix-wrapper-rtl` ] : direction === 'rtl' ,
115
- [ `${ prefixCls } -affix-wrapper-readonly` ] : readonly ,
116
- [ `${ prefixCls } -affix-wrapper-borderless` ] : ! bordered ,
117
- // className will go to addon wrapper
118
- [ `${ attrs . class } ` ] : ! hasAddon ( { addonAfter, addonBefore } ) && attrs . class ,
119
- } ) ;
120
- return (
121
- < span
122
- ref = { containerRef }
123
- class = { affixWrapperCls }
124
- style = { attrs . style }
125
- onMouseup = { onInputMouseUp }
126
- hidden = { hidden }
127
- >
128
- { prefixNode }
129
- { cloneElement ( element , {
130
- style : null ,
131
- value,
132
- class : getInputClassName ( prefixCls , bordered , size , disabled ) ,
133
- } ) }
134
- { suffixNode }
135
- </ span >
136
- ) ;
137
- } ;
138
-
139
- const renderInputWithLabel = ( prefixCls : string , labeledElement : VNode ) => {
140
- const {
141
- addonBefore = slots . addonBefore ?.( ) ,
142
- addonAfter = slots . addonAfter ?.( ) ,
143
- size,
144
- direction,
145
- hidden,
146
- } = props ;
147
- // Not wrap when there is not addons
148
- if ( ! hasAddon ( { addonBefore, addonAfter } ) ) {
149
- return labeledElement ;
150
- }
151
-
152
- const wrapperClassName = `${ prefixCls } -group` ;
153
- const addonClassName = `${ wrapperClassName } -addon` ;
154
- const addonBeforeNode = addonBefore ? (
155
- < span class = { addonClassName } > { addonBefore } </ span >
156
- ) : null ;
157
- const addonAfterNode = addonAfter ? < span class = { addonClassName } > { addonAfter } </ span > : null ;
158
-
159
- const mergedWrapperClassName = classNames ( `${ prefixCls } -wrapper` , wrapperClassName , {
160
- [ `${ wrapperClassName } -rtl` ] : direction === 'rtl' ,
161
- } ) ;
162
76
163
- const mergedGroupClassName = classNames (
164
- `${ prefixCls } -group-wrapper` ,
165
- {
166
- [ `${ prefixCls } -group-wrapper-sm` ] : size === 'small' ,
167
- [ `${ prefixCls } -group-wrapper-lg` ] : size === 'large' ,
168
- [ `${ prefixCls } -group-wrapper-rtl` ] : direction === 'rtl' ,
169
- } ,
170
- attrs . class ,
171
- ) ;
172
-
173
- // Need another wrapper for changing display:table to display:inline-block
174
- // and put style prop in wrapper
175
- return (
176
- < span class = { mergedGroupClassName } style = { attrs . style } hidden = { hidden } >
177
- < span class = { mergedWrapperClassName } >
178
- { addonBeforeNode }
179
- { cloneElement ( labeledElement , { style : null } ) }
180
- { addonAfterNode }
181
- </ span >
182
- </ span >
183
- ) ;
184
- } ;
77
+ const { status : contextStatus , hasFeedback } = statusContext ;
185
78
186
- const renderTextAreaWithClearIcon = ( prefixCls : string , element : VNode ) => {
187
- const {
188
- value,
189
- allowClear,
190
- direction,
191
- bordered,
192
- hidden,
193
- addonAfter = slots . addonAfter ,
194
- addonBefore = slots . addonBefore ,
195
- } = props ;
196
79
if ( ! allowClear ) {
197
80
return cloneElement ( element , {
198
81
value,
@@ -201,6 +84,11 @@ export default defineComponent({
201
84
const affixWrapperCls = classNames (
202
85
`${ prefixCls } -affix-wrapper` ,
203
86
`${ prefixCls } -affix-wrapper-textarea-with-clear-btn` ,
87
+ getStatusClassNames (
88
+ `${ prefixCls } -affix-wrapper` ,
89
+ getMergedStatus ( contextStatus , customStatus ) ,
90
+ hasFeedback ,
91
+ ) ,
204
92
{
205
93
[ `${ prefixCls } -affix-wrapper-rtl` ] : direction === 'rtl' ,
206
94
[ `${ prefixCls } -affix-wrapper-borderless` ] : ! bordered ,
@@ -209,7 +97,7 @@ export default defineComponent({
209
97
} ,
210
98
) ;
211
99
return (
212
- < span class = { affixWrapperCls } style = { attrs . style } hidden = { hidden } >
100
+ < span className = { affixWrapperCls } style = { attrs . style } hidden = { hidden } >
213
101
{ cloneElement ( element , {
214
102
style : null ,
215
103
value,
@@ -224,7 +112,7 @@ export default defineComponent({
224
112
if ( inputType === ClearableInputType [ 0 ] ) {
225
113
return renderTextAreaWithClearIcon ( prefixCls , element ) ;
226
114
}
227
- return renderInputWithLabel ( prefixCls , renderLabeledIcon ( prefixCls , element ) ) ;
115
+ return null ;
228
116
} ;
229
117
} ,
230
118
} ) ;
0 commit comments