feat(input): add show-password-on prop

This commit is contained in:
07akioni 2021-09-04 18:25:57 +08:00
parent 5f50b7982c
commit 829ded4727
7 changed files with 57 additions and 32 deletions

View File

@ -5,6 +5,7 @@
### Breaking Changes
- `n-tree-select`'s `leaf-only` props is deprecated, please use `check-strategy="child"` instead.
- `n-input`'s `show-password-toggle` is deprecated, please use `show-password-on="click"` instead.
### Fixes
@ -34,7 +35,8 @@
- `n-pagination` export `PaginationInfo` type.
- `n-data-table` export `DataTableCreateSummary` type.
- `n-code` add `inline` prop, closes [#834](https://github.com/TuSimple/naive-ui/issues/834)
- `n-collapse` add 'header-extra' slot, closes [#1046](https://github.com/TuSimple/naive-ui/issues/1046).
- `n-collapse` add `header-extra` slot, closes [#1046](https://github.com/TuSimple/naive-ui/issues/1046).
- `n-input` add `show-password-on` prop.
## 2.16.7 (2021-08-27)

View File

@ -5,6 +5,7 @@
### Breaking Changes
- `n-tree-select``leaf-only` 属性被废弃,请使用 `check-strategy="child"`
- `n-input``show-password-toggle` 属性被废弃,请使用 `show-password-on="click"`
### Fixes
@ -34,7 +35,8 @@
- `n-pagination` 导出 `PaginationInfo` 类型
- `n-data-table` 导出 `DataTableCreateSummary` 类型
- `n-code` 新增 `inline` 属性, 关闭 [#834](https://github.com/TuSimple/naive-ui/issues/834)
- `n-collapse` 新增 slot: 'header-extra',关闭 [#1046](https://github.com/TuSimple/naive-ui/issues/1046)
- `n-collapse` 新增 `header-extra` slot关闭 [#1046](https://github.com/TuSimple/naive-ui/issues/1046)
- `n-input` 新增 `show-password-on` 属性
## 2.16.7 (2021-08-27)

View File

@ -20,7 +20,7 @@ count
focus
```
## Props
## API
### Input Props
@ -43,7 +43,7 @@ focus
| rows | `number` | `3` | Input rows, only works when type is `textarea`. |
| separator | `string` | `undefined` | The separator bewteen pairwise inputs. |
| show-count | `boolean` | `false` | Whether to show word count. |
| show-password-toggle | `boolean` | `false` | Controls the display and hiding of passwords |
| show-password-on | `'click' \| 'mousedown'` | `undefined` | The timing to show the password. |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Input size. |
| type | `'text' \| 'password' \| 'textarea'` | `'text'` | Input type. |
| value | `string \| [string, string] \| null` | `undefined` | Value of input. When `pair` is `true`, `value` is an array. |
@ -53,8 +53,6 @@ focus
| on-focus | `() => void` | `undefined` | Callback triggered when the input focus. |
| on-update:value | `(value: string \| [string, string]) => void` | `undefined` | Callback triggered when the input value changes. |
## Slots
### Input Slots
| Name | Parameters | Description |
@ -63,20 +61,18 @@ focus
| suffix | `()` | The suffix content of the input. |
| separator | `()` | The separator content of the input, only works when `pare` is true and it's priority higher than the separator prop. |
### Input Group Slots
### InputGroup Slots
| Name | Parameters | Description |
| ------- | ---------- | ------------------------------- |
| default | `()` | The content of the input group. |
### Input Group Label Slots
### InputGroupLabel Slots
| Name | Parameters | Description |
| ------- | ---------- | ------------------------------------- |
| default | `()` | The content of the input group label. |
## Methods
### Input Methods
| Name | Type | Description |

View File

@ -3,7 +3,7 @@
```html
<n-input
type="password"
show-password-toggle
show-password-on="mousedown"
placeholder="Password"
:maxlength="8"
/>

View File

@ -20,7 +20,7 @@ count
focus
```
## Props
## API
### Input Props
@ -43,7 +43,7 @@ focus
| rows | `number` | `3` | 输入框行数,对 type="textarea" 有效 |
| separator | `string` | `undefined` | 成对输入框中间的分隔符 |
| show-count | `boolean` | `false` | 是否显示字数统计 |
| show-password-toggle | `boolean` | `false` | 控制密码的显示隐藏 |
| show-password-on | `'click' \| 'mousedown'` | `undefined` | 显示密码的时机 |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 输入框尺寸 |
| type | `'text' \| 'password' \| 'textarea'` | `'text'` | 输入框类型 |
| value | `string \| [string, string] \| null` | `undefined` | 文本输入的值。如果是 `pair``true``value` 是一个数组 |
@ -54,8 +54,6 @@ focus
| on-input | `() => void` | `undefined` | 输入框值 change 时触发 |
| on-update:value | `(value: string \| [string, string]) => void` | `undefined` | 输入框值 change 时触发 |
## Slots
### Input Slots
| 属性 | 类型 | 说明 |
@ -64,20 +62,18 @@ focus
| suffix | `()` | 输入框尾部内容 |
| separator | `()` | 成对输入框之间分隔符,仅 `pair` = true 生效且优先级高于 separator 属性 |
### Input Group Slots
### InputGroup Slots
| 属性 | 类型 | 说明 |
| ------- | ---- | ------------ |
| default | `()` | 输入组的内容 |
### Input Group Label Slots
### InputGroupLabel Slots
| 属性 | 类型 | 说明 |
| ------- | ---- | ---------------- |
| default | `()` | 输入组标签的内容 |
## Methods
### Input Methods
| 名称 | 类型 | 说明 |

View File

@ -3,7 +3,7 @@
```html
<n-input
type="password"
show-password-toggle
show-password-on="mousedown"
placeholder="密码"
:maxlength="8"
/>

View File

@ -24,7 +24,7 @@ import { NBaseClear, NBaseIcon, NBaseSuffix } from '../../_internal'
import { EyeIcon, EyeOffIcon } from '../../_internal/icons'
import { useTheme, useLocale, useFormItem, useConfig } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { call, createKey, ExtractPublicPropTypes } from '../../_utils'
import { call, createKey, ExtractPublicPropTypes, warnOnce } from '../../_utils'
import type { MaybeArray } from '../../_utils'
import { inputLight } from '../styles'
import type { InputTheme } from '../styles'
@ -38,6 +38,7 @@ import {
import { len, isEmptyValue } from './utils'
import WordCount from './WordCount'
import style from './styles/input.cssr'
import { off, on } from 'evtd'
const inputProps = {
...(useTheme.props as ThemeProps<InputTheme>),
@ -81,7 +82,7 @@ const inputProps = {
default: false
},
passivelyActivated: Boolean,
showPasswordToggle: Boolean,
showPasswordOn: String as PropType<'mousedown' | 'click'>,
stateful: {
type: Boolean,
default: true
@ -130,7 +131,9 @@ const inputProps = {
MaybeArray<(e: FocusEvent) => void>
>,
internalDeactivateOnEnter: Boolean,
internalForceFocus: Boolean
internalForceFocus: Boolean,
/** deprecated */
showPasswordToggle: Boolean
}
export type InputProps = ExtractPublicPropTypes<typeof inputProps>
@ -139,6 +142,16 @@ export default defineComponent({
name: 'Input',
props: inputProps,
setup (props) {
if (__DEV__) {
watchEffect(() => {
if (props.showPasswordToggle) {
warnOnce(
'input',
'`show-password-toggle` is deprecated, please use `showPasswordOn="click"` instead'
)
}
})
}
const { mergedClsPrefixRef, mergedBorderedRef } = useConfig(props)
const themeRef = useTheme(
'Input',
@ -241,6 +254,14 @@ export default defineComponent({
}
})
// passwordVisible
const mergedShowPasswordOnRef = computed(() => {
const { showPasswordOn } = props
if (showPasswordOn) {
return showPasswordOn
}
if (props.showPasswordToggle) return 'click'
return undefined
})
const passwordVisibleRef = ref<boolean>(false)
// text-decoration
const textDecorationStyleRef = computed(() => {
@ -515,15 +536,24 @@ export default defineComponent({
}
function handlePasswordToggleClick (): void {
if (mergedDisabledRef.value) return
if (mergedShowPasswordOnRef.value !== 'click') return
passwordVisibleRef.value = !passwordVisibleRef.value
}
function handlePasswordToggleMousedown (e: MouseEvent): void {
if (mergedDisabledRef.value) return
e.preventDefault()
}
function handlePasswordToggleMouseup (e: MouseEvent): void {
if (mergedDisabledRef.value) return
e.preventDefault()
const preventDefaultOnce = (e: MouseEvent): void => {
e.preventDefault()
off('mouseup', document, preventDefaultOnce)
}
on('mouseup', document, preventDefaultOnce)
if (mergedShowPasswordOnRef.value !== 'mousedown') return
passwordVisibleRef.value = true
const hidePassword = (): void => {
passwordVisibleRef.value = false
off('mouseup', document, hidePassword)
}
on('mouseup', document, hidePassword)
}
function handleWrapperKeyDown (e: KeyboardEvent): void {
props.onKeydown?.(e)
@ -674,6 +704,7 @@ export default defineComponent({
textDecorationStyle: textDecorationStyleRef,
mergedClsPrefix: mergedClsPrefixRef,
mergedBordered: mergedBorderedRef,
mergedShowPasswordOn: mergedShowPasswordOnRef,
// methods
handleCompositionStart,
handleCompositionEnd,
@ -690,7 +721,6 @@ export default defineComponent({
handleClear,
handlePasswordToggleClick,
handlePasswordToggleMousedown,
handlePasswordToggleMouseup,
handleWrapperKeyDown,
handleTextAreaMirrorResize,
mergedTheme: themeRef,
@ -900,7 +930,7 @@ export default defineComponent({
ref="inputElRef"
type={
this.type === 'password' &&
this.showPasswordToggle &&
this.mergedShowPasswordOn &&
this.passwordVisible
? 'text'
: this.type
@ -947,7 +977,7 @@ export default defineComponent({
(this.$slots.suffix ||
this.clearable ||
this.showCount ||
this.showPasswordToggle ||
this.mergedShowPasswordOn ||
this.loading !== undefined) ? (
<div class={`${mergedClsPrefix}-input__suffix`}>
{[
@ -973,12 +1003,11 @@ export default defineComponent({
this.showCount && this.type !== 'textarea' ? (
<WordCount />
) : null,
this.showPasswordToggle && this.type === 'password' ? (
this.mergedShowPasswordOn && this.type === 'password' ? (
<NBaseIcon
clsPrefix={mergedClsPrefix}
class={`${mergedClsPrefix}-input__eye`}
onMousedown={this.handlePasswordToggleMousedown}
onMouseup={this.handlePasswordToggleMouseup}
onClick={this.handlePasswordToggleClick}
>
{{