Skip to content

Commit 3a8afb5

Browse files
authored
feat: input.password add iconRender (#3320)
* feat: input.password add iconRender * feat: input.password support slot iconRender
1 parent 2f467d7 commit 3a8afb5

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

components/input/Password.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import classNames from '../_util/classNames';
22
import { getComponent, getOptionProps } from '../_util/props-util';
3+
import { cloneElement } from '../_util/vnode';
34
import Input from './Input';
45
import EyeOutlined from '@ant-design/icons-vue/EyeOutlined';
56
import EyeInvisibleOutlined from '@ant-design/icons-vue/EyeInvisibleOutlined';
@@ -23,6 +24,9 @@ export default defineComponent({
2324
inputPrefixCls: PropTypes.string.def('ant-input'),
2425
action: PropTypes.string.def('click'),
2526
visibilityToggle: PropTypes.looseBool.def(true),
27+
iconRender: PropTypes.func.def((visible: boolean) =>
28+
visible ? <EyeOutlined /> : <EyeInvisibleOutlined />,
29+
),
2630
},
2731
setup() {
2832
return {
@@ -55,6 +59,8 @@ export default defineComponent({
5559
getIcon() {
5660
const { prefixCls, action } = this.$props;
5761
const iconTrigger = ActionMap[action] || '';
62+
const iconRender = this.$slots.iconRender || this.$props.iconRender;
63+
const icon = iconRender(this.visible);
5864
const iconProps = {
5965
[iconTrigger]: this.onVisibleChange,
6066
onMousedown: (e: Event) => {
@@ -70,11 +76,7 @@ export default defineComponent({
7076
class: `${prefixCls}-icon`,
7177
key: 'passwordIcon',
7278
};
73-
return this.visible ? (
74-
<EyeOutlined {...iconProps} />
75-
) : (
76-
<EyeInvisibleOutlined {...iconProps} />
77-
);
79+
return cloneElement(icon, iconProps);
7880
},
7981
},
8082
render() {

components/input/__tests__/index.test.js

+33
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { asyncExpect } from '@/tests/utils';
33
import Input from '..';
44
// import Form from '../../form';
55
import focusTest from '../../../tests/shared/focusTest';
6+
import { WifiOutlined, SyncOutlined } from '@ant-design/icons-vue';
67

78
const { TextArea, Password } = Input;
89

@@ -131,3 +132,35 @@ describe('Input.Search', () => {
131132
}, 100);
132133
});
133134
});
135+
136+
describe('Input.Password', () => {
137+
it('should support iconRender', async () => {
138+
const wrapper = mount(Input.Password, {
139+
props: { iconRender: visible => (visible ? <SyncOutlined /> : <WifiOutlined />) },
140+
sync: false,
141+
});
142+
await asyncExpect(() => {
143+
expect(wrapper.findAll('.anticon-wifi').length).toBe(1);
144+
wrapper.find('.anticon-wifi').trigger('click');
145+
}, 100);
146+
await asyncExpect(() => {
147+
expect(wrapper.findAll('.anticon-sync').length).toBe(1);
148+
}, 100);
149+
});
150+
151+
it('should support slot iconRender', async () => {
152+
const wrapper = mount(Input.Password, {
153+
slots: {
154+
iconRender: visible => (visible ? <SyncOutlined /> : <WifiOutlined />),
155+
},
156+
sync: false,
157+
});
158+
await asyncExpect(() => {
159+
expect(wrapper.findAll('.anticon-wifi').length).toBe(1);
160+
wrapper.find('.anticon-wifi').trigger('click');
161+
}, 100);
162+
await asyncExpect(() => {
163+
expect(wrapper.findAll('.anticon-sync').length).toBe(1);
164+
}, 100);
165+
});
166+
});

0 commit comments

Comments
 (0)