From 9c0311546b7f4a47b8af1bcba1db6787618d5d0c Mon Sep 17 00:00:00 2001
From: Konv Suu <2583695112@qq.com>
Date: Fri, 18 Aug 2023 17:03:16 +0800
Subject: [PATCH] feat(input): add password visible feature (#6863)
* feat(input): modify visibilityToggle feature
* test: update snapshot and update test cases
* Update Password.tsx
* Update Password.tsx
* chore: update
* chore: update demo and test
---------
Co-authored-by: tangjinzhou <415800467@qq.com>
---
components/input/Password.tsx | 13 ++++++--
.../__tests__/__snapshots__/demo.test.js.snap | 33 ++++++++++++++++---
components/input/__tests__/index.test.js | 26 +++++++++++++++
components/input/demo/password-input.vue | 29 +++++++++++++++-
components/input/index.en-US.md | 8 +++--
components/input/index.zh-CN.md | 8 +++--
6 files changed, 103 insertions(+), 14 deletions(-)
diff --git a/components/input/Password.tsx b/components/input/Password.tsx
index 0a62f90619..0d65270b42 100644
--- a/components/input/Password.tsx
+++ b/components/input/Password.tsx
@@ -6,7 +6,8 @@ import EyeOutlined from '@ant-design/icons-vue/EyeOutlined';
import EyeInvisibleOutlined from '@ant-design/icons-vue/EyeInvisibleOutlined';
import type { InputProps } from './inputProps';
import inputProps from './inputProps';
-import { computed, defineComponent, shallowRef } from 'vue';
+import type { PropType } from 'vue';
+import { computed, defineComponent, shallowRef, watchEffect } from 'vue';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
@@ -26,9 +27,11 @@ export default defineComponent({
inputPrefixCls: String,
action: { type: String, default: 'click' },
visibilityToggle: { type: Boolean, default: true },
+ visible: { type: Boolean, default: undefined },
+ 'onUpdate:visible': Function as PropType<(visible: boolean) => void>,
iconRender: Function,
},
- setup(props, { slots, attrs, expose }) {
+ setup(props, { slots, attrs, expose, emit }) {
const visible = shallowRef(false);
const onVisibleChange = () => {
const { disabled } = props;
@@ -36,7 +39,13 @@ export default defineComponent({
return;
}
visible.value = !visible.value;
+ emit('update:visible', visible.value);
};
+ watchEffect(() => {
+ if (props.visible !== undefined) {
+ visible.value = !!props.visible;
+ }
+ });
const inputRef = shallowRef();
const focus = () => {
inputRef.value?.focus();
diff --git a/components/input/__tests__/__snapshots__/demo.test.js.snap b/components/input/__tests__/__snapshots__/demo.test.js.snap
index ba0df76926..416dd244ca 100644
--- a/components/input/__tests__/__snapshots__/demo.test.js.snap
+++ b/components/input/__tests__/__snapshots__/demo.test.js.snap
@@ -33,8 +33,8 @@ exports[`renders ./components/input/demo/addon.vue correctly 1`] = `
`;
exports[`renders ./components/input/demo/allow-clear.vue correctly 1`] = `
-
-
+
`;
@@ -124,14 +124,37 @@ exports[`renders ./components/input/demo/group.vue correctly 1`] = `
`;
exports[`renders ./components/input/demo/password-input.vue correctly 1`] = `
-
-
+
`;
exports[`renders ./components/input/demo/presuffix.vue correctly 1`] = `
`;
diff --git a/components/input/__tests__/index.test.js b/components/input/__tests__/index.test.js
index 6a15b2f4ff..5dad154468 100644
--- a/components/input/__tests__/index.test.js
+++ b/components/input/__tests__/index.test.js
@@ -163,4 +163,30 @@ describe('Input.Password', () => {
expect(wrapper.findAll('.anticon-sync').length).toBe(1);
}, 100);
});
+
+ it('should support visibilityToggle(boolean)', async () => {
+ const wrapper = mount(Input.Password, { props: { visibilityToggle: false }, sync: false });
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.anticon-eye').length).toBe(0);
+ }, 100);
+ });
+
+ it('should support visible', async () => {
+ const cbMock = jest.fn();
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.anticon-eye').length).toBe(1);
+ }, 100);
+
+ await asyncExpect(() => {
+ wrapper.find('.anticon-eye').trigger('click');
+ }, 100);
+
+ expect(cbMock).toHaveBeenCalledWith(false);
+ });
});
diff --git a/components/input/demo/password-input.vue b/components/input/demo/password-input.vue
index ff05b81a51..c2c4ec6660 100644
--- a/components/input/demo/password-input.vue
+++ b/components/input/demo/password-input.vue
@@ -16,9 +16,36 @@ Input type of password.
-
+
+
+
+
+
+
+
+
+
+
+
+ {{ visible ? 'Hide' : 'Show' }}
+
+
diff --git a/components/input/index.en-US.md b/components/input/index.en-US.md
index 0a0cb4f2dd..a57cd983c2 100644
--- a/components/input/index.en-US.md
+++ b/components/input/index.en-US.md
@@ -94,6 +94,8 @@ Supports all props of `Input`.
#### Input.Password (Added in 1.14.0)
-| Property | Description | Type | Default |
-| ---------------- | -------------------------- | ------- | ------- |
-| visibilityToggle | Whether show toggle button | boolean | true |
+| Property | Description | Type | Default |
+| ---------------- | ------------------------------------------------------ | ------- | ------- |
+| visible(v-model) | password visibility | boolean | false |
+| iconRender | Custom toggle button | slot | - |
+| visibilityToggle | Whether show toggle button or control password visible | boolean | true |
diff --git a/components/input/index.zh-CN.md b/components/input/index.zh-CN.md
index d6c3e01b2e..06489389d4 100644
--- a/components/input/index.zh-CN.md
+++ b/components/input/index.zh-CN.md
@@ -95,6 +95,8 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sBqqTatJ-AkAAA
#### Input.Password (1.14.0 中新增)
-| 参数 | 说明 | 类型 | 默认值 |
-| ---------------- | ---------------- | ------- | ------ |
-| visibilityToggle | 是否显示切换按钮 | boolean | true |
+| 参数 | 说明 | 类型 | 默认值 |
+| ---------------- | -------------------------------- | ------- | ------ |
+| visible(v-model) | 密码是否可见 | boolean | false |
+| iconRender | 自定义切换按钮 | slot | - |
+| visibilityToggle | 是否显示切换按钮或者控制密码显隐 | boolean | true |