mirror of
https://github.com/youzan/vant.git
synced 2025-10-21 19:24:16 +00:00
[improvement] rename packages dir to src (#3659)
This commit is contained in:
73
src/password-input/demo/index.vue
Normal file
73
src/password-input/demo/index.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<demo-section>
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<van-password-input
|
||||
:value="value1"
|
||||
:info="$t('info')"
|
||||
@focus="keyboard = 'value1'"
|
||||
/>
|
||||
|
||||
<van-number-keyboard
|
||||
:show="!!keyboard"
|
||||
@input="onInput"
|
||||
@delete="onDelete"
|
||||
@blur="keyboard = ''"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('customLength')">
|
||||
<van-password-input
|
||||
:value="value2"
|
||||
:length="4"
|
||||
gutter="15"
|
||||
@focus="keyboard = 'value2'"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('removeMask')">
|
||||
<van-password-input
|
||||
:value="value3"
|
||||
:mask="false"
|
||||
@focus="keyboard = 'value3'"
|
||||
/>
|
||||
</demo-block>
|
||||
</demo-section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
info: '密码为 6 位数字',
|
||||
customLength: '自定义长度',
|
||||
removeMask: '明文展示'
|
||||
},
|
||||
'en-US': {
|
||||
info: 'Some tips',
|
||||
customLength: 'Custom Length',
|
||||
removeMask: 'Remove Mask'
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
value1: '123',
|
||||
value2: '123',
|
||||
value3: '123',
|
||||
keyboard: 'value1'
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onInput(key) {
|
||||
const { keyboard } = this;
|
||||
this[keyboard] = (this[keyboard] + key).slice(0, 6);
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
const { keyboard } = this;
|
||||
this[keyboard] = this[keyboard].slice(0, this[keyboard].length - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
94
src/password-input/en-US.md
Normal file
94
src/password-input/en-US.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# PasswordInput
|
||||
|
||||
### Intro
|
||||
|
||||
The PasswordInput component is usually used with [NumberKeyboard](#/en-US/number-keyboard) Component.
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
import { PasswordInput, NumberKeyboard } from 'vant';
|
||||
|
||||
Vue.use(PasswordInput).use(NumberKeyboard);
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```html
|
||||
<!-- PasswordInput -->
|
||||
<van-password-input
|
||||
:value="value"
|
||||
info="Some tips"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
|
||||
<!-- NumberKeyboard -->
|
||||
<van-number-keyboard
|
||||
:show="showKeyboard"
|
||||
@input="onInput"
|
||||
@delete="onDelete"
|
||||
@blur="showKeyboard = false"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: '123',
|
||||
showKeyboard: true
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onInput(key) {
|
||||
this.value = (this.value + key).slice(0, 6);
|
||||
},
|
||||
onDelete() {
|
||||
this.value = this.value.slice(0, this.value.length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Custom length
|
||||
|
||||
```html
|
||||
<van-password-input
|
||||
:value="value"
|
||||
:length="4"
|
||||
:gutter="15"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
```
|
||||
|
||||
### Without mask
|
||||
|
||||
```html
|
||||
<van-password-input
|
||||
:value="value"
|
||||
:mask="false"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| value | Password value | `String` | `''` |
|
||||
| length | Maxlength of password | `Number` | `6` |
|
||||
| mask | Whether to mask value | `Boolean` | `true` |
|
||||
| info | Bottom info | `String` | - |
|
||||
| error-info | Bottom error info | `String` | - |
|
||||
| gutter | Gutter of input | `Number | String` | `0` |
|
||||
|
||||
### Events
|
||||
|
||||
| Event | Description | Arguments |
|
||||
|------|------|------|
|
||||
| focus | Triggered when input get focused | - |
|
54
src/password-input/index.less
Normal file
54
src/password-input/index.less
Normal file
@@ -0,0 +1,54 @@
|
||||
@import '../style/var';
|
||||
|
||||
.van-password-input {
|
||||
position: relative;
|
||||
margin: @password-input-margin;
|
||||
user-select: none;
|
||||
|
||||
&__info,
|
||||
&__error-info {
|
||||
margin-top: 15px;
|
||||
font-size: @password-input-info-font-size;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__info {
|
||||
color: @password-input-info-color;
|
||||
}
|
||||
|
||||
&__error-info {
|
||||
color: @password-input-error-info-color;
|
||||
}
|
||||
|
||||
&__security {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: @password-input-height;
|
||||
|
||||
&::after {
|
||||
border-radius: @password-input-border-radius;
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
font-size: @password-input-font-size;
|
||||
line-height: @password-input-height;
|
||||
text-align: center;
|
||||
background-color: @password-input-background-color;
|
||||
}
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: @password-input-dot-size;
|
||||
height: @password-input-dot-size;
|
||||
margin: -(@password-input-dot-size / 2) 0 0 -(@password-input-dot-size / 2);
|
||||
background-color: @password-input-dot-color;
|
||||
border-radius: 100%;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
79
src/password-input/index.tsx
Normal file
79
src/password-input/index.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { createNamespace, suffixPx } from '../utils';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
|
||||
// Types
|
||||
import { CreateElement, RenderContext } from 'vue/types';
|
||||
import { DefaultSlots } from '../utils/types';
|
||||
|
||||
export type PasswordInputProps = {
|
||||
mask: boolean;
|
||||
info?: string;
|
||||
value: string;
|
||||
length: number;
|
||||
gutter: number;
|
||||
errorInfo?: string;
|
||||
};
|
||||
|
||||
const [createComponent, bem] = createNamespace('password-input');
|
||||
|
||||
function PasswordInput(
|
||||
h: CreateElement,
|
||||
props: PasswordInputProps,
|
||||
slots: DefaultSlots,
|
||||
ctx: RenderContext<PasswordInputProps>
|
||||
) {
|
||||
const info = props.errorInfo || props.info;
|
||||
|
||||
const Points = [];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
const char = props.value[i];
|
||||
const showBorder = i !== 0 && !props.gutter;
|
||||
|
||||
let style;
|
||||
if (i !== 0 && props.gutter) {
|
||||
style = { marginLeft: suffixPx(props.gutter) };
|
||||
}
|
||||
|
||||
Points.push(
|
||||
<li class={{ 'van-hairline--left': showBorder }} style={style}>
|
||||
{props.mask ? <i style={{ visibility: char ? 'visible' : 'hidden' }} /> : char}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={bem()}>
|
||||
<ul
|
||||
class={[bem('security'), { 'van-hairline--surround': !props.gutter }]}
|
||||
onTouchstart={(event: TouchEvent) => {
|
||||
event.stopPropagation();
|
||||
emit(ctx, 'focus', event);
|
||||
}}
|
||||
{...inherit(ctx, true)}
|
||||
>
|
||||
{Points}
|
||||
</ul>
|
||||
{info && <div class={bem(props.errorInfo ? 'error-info' : 'info')}>{info}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
PasswordInput.props = {
|
||||
info: String,
|
||||
errorInfo: String,
|
||||
gutter: [String, Number],
|
||||
mask: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
default: 6
|
||||
}
|
||||
};
|
||||
|
||||
export default createComponent<PasswordInputProps>(PasswordInput);
|
44
src/password-input/test/__snapshots__/demo.spec.js.snap
Normal file
44
src/password-input/test/__snapshots__/demo.spec.js.snap
Normal file
@@ -0,0 +1,44 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders demo correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div class="van-password-input">
|
||||
<ul class="van-password-input__security van-hairline--surround">
|
||||
<li class=""><i style="visibility: visible;"></i></li>
|
||||
<li class="van-hairline--left"><i style="visibility: visible;"></i></li>
|
||||
<li class="van-hairline--left"><i style="visibility: visible;"></i></li>
|
||||
<li class="van-hairline--left"><i style="visibility: hidden;"></i></li>
|
||||
<li class="van-hairline--left"><i style="visibility: hidden;"></i></li>
|
||||
<li class="van-hairline--left"><i style="visibility: hidden;"></i></li>
|
||||
</ul>
|
||||
<div class="van-password-input__info">密码为 6 位数字</div>
|
||||
</div>
|
||||
<div class="van-number-keyboard van-number-keyboard--default" style="z-index: 100;" name="van-slide-up">
|
||||
<div class="van-number-keyboard__body"><i role="button" tabindex="0" class="van-hairline van-key">1</i><i role="button" tabindex="0" class="van-hairline van-key">2</i><i role="button" tabindex="0" class="van-hairline van-key">3</i><i role="button" tabindex="0" class="van-hairline van-key">4</i><i role="button" tabindex="0" class="van-hairline van-key">5</i><i role="button" tabindex="0" class="van-hairline van-key">6</i><i role="button" tabindex="0" class="van-hairline van-key">7</i><i role="button" tabindex="0" class="van-hairline van-key">8</i><i role="button" tabindex="0" class="van-hairline van-key">9</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray"></i><i role="button" tabindex="0" class="van-hairline van-key">0</i><i role="button" tabindex="0" class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-password-input">
|
||||
<ul class="van-password-input__security">
|
||||
<li class=""><i style="visibility: visible;"></i></li>
|
||||
<li class="" style="margin-left: 15px;"><i style="visibility: visible;"></i></li>
|
||||
<li class="" style="margin-left: 15px;"><i style="visibility: visible;"></i></li>
|
||||
<li class="" style="margin-left: 15px;"><i style="visibility: hidden;"></i></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-password-input">
|
||||
<ul class="van-password-input__security van-hairline--surround">
|
||||
<li class="">1</li>
|
||||
<li class="van-hairline--left">2</li>
|
||||
<li class="van-hairline--left">3</li>
|
||||
<li class="van-hairline--left"></li>
|
||||
<li class="van-hairline--left"></li>
|
||||
<li class="van-hairline--left"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
4
src/password-input/test/demo.spec.js
Normal file
4
src/password-input/test/demo.spec.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import Demo from '../demo';
|
||||
import demoTest from '../../../test/demo-test';
|
||||
|
||||
demoTest(Demo);
|
16
src/password-input/test/index.spec.js
Normal file
16
src/password-input/test/index.spec.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import PasswordInput from '..';
|
||||
import { mount } from '../../../test/utils';
|
||||
|
||||
test('focus event', () => {
|
||||
const focus = jest.fn();
|
||||
const wrapper = mount(PasswordInput, {
|
||||
context: {
|
||||
on: {
|
||||
focus
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.find('.van-password-input__security').trigger('touchstart');
|
||||
expect(focus).toHaveBeenCalledTimes(1);
|
||||
});
|
91
src/password-input/zh-CN.md
Normal file
91
src/password-input/zh-CN.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# PasswordInput 密码输入框
|
||||
|
||||
### 介绍
|
||||
|
||||
密码输入框组件通常与 [数字键盘](#/zh-CN/number-keyboard) 组件配合使用
|
||||
|
||||
### 引入
|
||||
``` javascript
|
||||
import { PasswordInput, NumberKeyboard } from 'vant';
|
||||
|
||||
Vue.use(PasswordInput).use(NumberKeyboard);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础用法
|
||||
|
||||
```html
|
||||
<!-- 密码输入框 -->
|
||||
<van-password-input
|
||||
:value="value"
|
||||
info="密码为 6 位数字"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
|
||||
<!-- 数字键盘 -->
|
||||
<van-number-keyboard
|
||||
:show="showKeyboard"
|
||||
@input="onInput"
|
||||
@delete="onDelete"
|
||||
@blur="showKeyboard = false"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: '123',
|
||||
showKeyboard: true
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
onInput(key) {
|
||||
this.value = (this.value + key).slice(0, 6);
|
||||
},
|
||||
onDelete() {
|
||||
this.value = this.value.slice(0, this.value.length - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义长度
|
||||
|
||||
```html
|
||||
<van-password-input
|
||||
:value="value"
|
||||
:length="4"
|
||||
:gutter="15"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
```
|
||||
|
||||
### 明文展示
|
||||
|
||||
```html
|
||||
<van-password-input
|
||||
:value="value"
|
||||
:mask="false"
|
||||
@focus="showKeyboard = true"
|
||||
/>
|
||||
```
|
||||
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|------|------|------|------|------|
|
||||
| value | 密码值 | `String` | `''` | - |
|
||||
| length | 密码最大长度 | `Number` | `6` | - |
|
||||
| mask | 是否隐藏密码内容 | `Boolean` | `true` | 1.6.6 |
|
||||
| info | 输入框下方文字提示 | `String` | - | - |
|
||||
| error-info | 输入框下方错误提示 | `String` | - | - |
|
||||
| gutter | 输入框格子之间的间距,如 `20px` `2em`,默认单位为`px` | `Number | String` | `0` | 2.0.0 |
|
||||
|
||||
### Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| focus | 输入框聚焦时触发 | - |
|
Reference in New Issue
Block a user