mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat(components): [input] add password-icon slot (#23772)
* feat(components): [input] add `password-icon` slot * Update docs/en-US/component/input.md * docs: simply example * docs: improve example --------- Co-authored-by: rzzf <cszhjh@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
---
|
||||
---
|
||||
title: Input
|
||||
lang: en-US
|
||||
---
|
||||
@@ -51,7 +51,7 @@ input/formatter
|
||||
|
||||
## Password box
|
||||
|
||||
:::demo Make a toggle-able password Input with the `show-password` attribute.
|
||||
:::demo Make a toggle-able password Input with the `show-password` attribute. Since ^(2.13.6), the `password-icon` slot is supported to override the default icon.
|
||||
|
||||
input/password
|
||||
|
||||
@@ -172,12 +172,13 @@ input/length-limiting
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description |
|
||||
| ------- | ------------------------------------------------------------------------- |
|
||||
| prefix | content as Input prefix, only works when `type` is not 'textarea' |
|
||||
| suffix | content as Input suffix, only works when `type` is not 'textarea' |
|
||||
| prepend | content to prepend before Input, only works when `type` is not 'textarea' |
|
||||
| append | content to append after Input, only works when `type` is not 'textarea' |
|
||||
| Name | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| prefix | content as Input prefix, only works when `type` is not 'textarea' |
|
||||
| suffix | content as Input suffix, only works when `type` is not 'textarea' |
|
||||
| prepend | content to prepend before Input, only works when `type` is not 'textarea' |
|
||||
| append | content to append after Input, only works when `type` is not 'textarea' |
|
||||
| password-icon ^(2.13.6) | content as Input password icon, only works when `show-password` is true. The scope variable is `{ visible: boolean }` |
|
||||
|
||||
### Exposes
|
||||
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
<template>
|
||||
<el-input
|
||||
v-model="input"
|
||||
style="width: 240px"
|
||||
type="password"
|
||||
placeholder="Please input password"
|
||||
show-password
|
||||
/>
|
||||
<div class="input-group">
|
||||
<el-input
|
||||
v-model="input"
|
||||
style="width: 240px"
|
||||
type="password"
|
||||
placeholder="Please input password"
|
||||
show-password
|
||||
/>
|
||||
<el-input
|
||||
v-model="input"
|
||||
style="width: 240px"
|
||||
type="password"
|
||||
placeholder="Please input password"
|
||||
show-password
|
||||
>
|
||||
<template #password-icon="{ visible }">
|
||||
<el-icon :size="16">
|
||||
<Unlock v-if="visible" />
|
||||
<Lock v-else />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { Lock, Unlock } from '@element-plus/icons-vue'
|
||||
|
||||
const input = ref('')
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -614,6 +614,36 @@ describe('Input.vue', () => {
|
||||
expect(input.element.selectionEnd).toBe(4)
|
||||
})
|
||||
|
||||
test('password-icon slot', async () => {
|
||||
const wrapper = mount(() => (
|
||||
<Input
|
||||
modelValue="123"
|
||||
showPassword
|
||||
v-slots={{
|
||||
'password-icon': ({ visible }: { visible: boolean }) => (
|
||||
<span class="custom-password-icon">
|
||||
{visible ? 'Hide' : 'Show'}
|
||||
</span>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
))
|
||||
|
||||
const icon = wrapper.find('.el-input__password')
|
||||
expect(icon.exists()).toBe(true)
|
||||
|
||||
// Initial state: password hidden
|
||||
expect(wrapper.find('.custom-password-icon').text()).toBe('Show')
|
||||
|
||||
// Click to toggle
|
||||
await icon.trigger('click')
|
||||
expect(wrapper.find('.custom-password-icon').text()).toBe('Hide')
|
||||
|
||||
// Click again
|
||||
await icon.trigger('click')
|
||||
expect(wrapper.find('.custom-password-icon').text()).toBe('Show')
|
||||
})
|
||||
|
||||
describe('form item accessibility integration', () => {
|
||||
test('automatic id attachment', async () => {
|
||||
const wrapper = mount(() => (
|
||||
|
||||
@@ -83,7 +83,9 @@
|
||||
@mousedown.prevent="NOOP"
|
||||
@mouseup.prevent="NOOP"
|
||||
>
|
||||
<component :is="passwordIcon" />
|
||||
<slot name="password-icon" :visible="passwordVisible">
|
||||
<component :is="passwordIcon" />
|
||||
</slot>
|
||||
</el-icon>
|
||||
<span
|
||||
v-if="isWordLimitVisible"
|
||||
|
||||
Reference in New Issue
Block a user