refactor(input): add props.clearable

This commit is contained in:
07akioni 2019-08-23 14:20:10 +08:00
parent 48c22a2ec2
commit c04bff1d1a
17 changed files with 611 additions and 453 deletions

View File

@ -1,391 +0,0 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
Input / n-input
</n-gradient-text>
</div>
<div class="n-doc-body">
<div class="n-doc-section">
<div class="n-doc-section__header">
Basic Usage
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="input"
size="small"
/>
<br>
<n-input
v-model="value"
type="input"
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="input"
size="small"
/>
<n-input
v-model="value"
type="input"
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Password
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="password"
size="large"
icon="md-person"
maxlength="16"
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="password"
size="large"
icon="md-person"
maxlength="16"
/>
<br>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Event
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
@blur="handleBlur"
@focus="handleFocus"
@change="handleChange"
@keyup="handleKeyUp"
@input="handleInput"
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
@blur="handleBlur"
@focus="handleFocus"
@change="handleChange"
@keyup="handleKeyUp"
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
},
methods: {
handleFocus () {
this.$NMessage.success('focus')
},
handleBlur () {
this.$NMessage.success('blur')
},
handleInput (value) {
this.$NMessage.success('input: ' + value)
},
handleChange (value) {
this.$NMessage.success('change: ' + value)
},
handleKeyUp (e) {
this.$NMessage.success('keyup')
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Icon
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="input"
size="large"
icon="ios-search"
/>
<br>
<n-input
v-model="value"
type="input"
size="large"
icon="md-settings"
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="input"
size="small"
icon="ios-search"
/>
<n-input
v-model="value"
type="input"
size="large"
icon="md-settings"
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Round
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="input"
size="small"
round
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="input"
size="small"
round
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
placeholder
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
round
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
round
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
disabled
</div>
<div class="n-doc-section__view">
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
disabled
round
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
round
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Textarea
</div>
<div class="n-doc-section__view not-code">
<n-input
v-model="value"
placeholder="Nowhere Man"
type="textarea"
size="small"
:rows="5"
/>
<br>
<n-input
v-model="value"
type="textarea"
:rows="3"
/>
<br>
value: {{ value }}
</div>
<div class="n-doc-section__source">
<textarea v-pre>
<n-input
v-model="value"
placeholder="Nowhere Man"
type="textarea"
size="small"
:rows="5"
/>
<n-input
v-model="value"
type="textarea"
:rows="3"
/>
value: {{ value }}
<script>
export default {
data () {
return {
value: null
}
}
}
</script>
</textarea>
</div>
</div>
</div>
</div>
</template>
<script>
import docCodeEditorMixin from './docCodeEditorMixin'
export default {
mixins: [docCodeEditorMixin],
data () {
return {
value: null
}
},
methods: {
handleFocus () {
this.$NMessage.success('focus')
},
handleBlur () {
this.$NMessage.success('blur')
},
handleInput (value) {
this.$NMessage.success('input: ' + value)
},
handleChange (value) {
this.$NMessage.success('change: ' + value)
},
handleKeyUp (e) {
this.$NMessage.success('keyup')
}
}
}
</script>
<style scoped>
.n-doc-section__view {
display: block!important;
}
</style>

View File

@ -0,0 +1,42 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Basic Usage
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
size="small"
/>
<n-input
v-model="value"
type="input"
/>
<n-input
v-model="value"
type="input"
size="large"
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">{{ JSON.stringify(value) }}</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,49 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Clearable
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
placeholder="Stairway to Heaven"
round
clearable
/>
<n-input
v-model="value"
type="password"
placeholder="Stairway to Heaven"
round
clearable
/>
<n-input
v-model="value"
type="textarea"
placeholder="Stairway to Heaven"
round
clearable
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">{{ JSON.stringify(value) }}</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,43 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Disabled
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
disabled
round
/>
<n-input
v-model="value"
type="textarea"
size="small"
placeholder="Stairway to Heaven"
disabled
round
/>
<!--EXAMPLE_END-->
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: 'text'
}
}
}
</script>

View File

@ -0,0 +1,71 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Event
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
@blur="handleBlur"
@focus="handleFocus"
@change="handleChange"
@keyup="handleKeyUp"
@input="handleInput"
/>
<n-input
v-model="value"
disabled
@blur="handleBlur"
@focus="handleFocus"
@change="handleChange"
@keyup="handleKeyUp"
@input="handleInput"
/>
<n-input
v-model="value"
type="textarea"
@blur="handleBlur"
@focus="handleFocus"
@change="handleChange"
@keyup="handleKeyUp"
@input="handleInput"
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">Inspect some value here</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
},
methods: {
handleFocus () {
this.$NMessage.success('focus')
},
handleBlur () {
this.$NMessage.success('blur')
},
handleChange (value) {
this.$NMessage.success('change: ' + value)
},
handleKeyUp (e) {
this.$NMessage.success('keyup')
},
handleInput (v) {
this.$NMessage.success('input: ' + v)
}
}
}
</script>

View File

@ -0,0 +1,63 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Icon
</div>
<div
class="n-doc-section__view"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
size="small"
icon="ios-search"
/>
<n-input
v-model="value"
type="input"
icon="ios-search"
/>
<n-input
v-model="value"
type="input"
size="large"
icon="md-settings"
/>
<n-input
v-model="value"
type="input"
size="small"
icon="ios-search"
round
/>
<n-input
v-model="value"
type="input"
icon="ios-search"
round
/>
<n-input
v-model="value"
type="input"
size="large"
icon="md-settings"
round
/>
<!--EXAMPLE_END-->
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,56 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
Input / n-input
</n-gradient-text>
</div>
<div class="n-doc-body">
<basic-usage />
<password />
<event />
<icon />
<round />
<placeholder />
<disabled />
<textarea-demo />
<clearable />
</div>
</div>
</template>
<script>
import basicUsage from './basicUsage.demo.vue'
import password from './password.demo'
import event from './event.demo'
import icon from './icon.demo'
import round from './round.demo'
import placeholder from './placeholder.demo'
import disabled from './disabled.demo'
import textareaDemo from './textarea.demo'
import clearable from './clearable.demo'
export default {
components: {
basicUsage,
password,
event,
icon,
round,
placeholder,
disabled,
textareaDemo,
clearable
},
data () {
return {
}
},
methods: {
}
}
</script>

View File

@ -0,0 +1,35 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Password
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="password"
size="large"
icon="md-person"
maxlength="16"
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">{{ JSON.stringify(value) }}</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,41 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Placeholder
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
size="small"
placeholder="Stairway to Heaven"
round
/>
<n-input
v-model="value"
type="textarea"
size="small"
placeholder="Stairway to Heaven"
round
/>
<!--EXAMPLE_END-->
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,62 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Round
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
type="input"
size="small"
round
/>
<n-input
v-model="value"
type="input"
round
/>
<n-input
v-model="value"
type="input"
size="large"
round
/>
<n-input
v-model="value"
type="textarea"
size="small"
round
/>
<n-input
v-model="value"
type="textarea"
round
/>
<n-input
v-model="value"
type="textarea"
size="large"
round
/>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect">{{ JSON.stringify(value) }}</pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -0,0 +1,40 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Textarea
</div>
<div
class="n-doc-section__view"
style="flex-wrap: wrap;"
>
<!--EXAMPLE_START-->
<n-input
v-model="value"
placeholder="Nowhere Man"
type="textarea"
size="small"
:rows="5"
/>
<n-input
v-model="value"
type="textarea"
size="large"
:rows="3"
/>
<!--EXAMPLE_END-->
</div>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
value: null
}
}
}
</script>

View File

@ -8,7 +8,7 @@
>
<transition name="n-cancel-mark--transition">
<div
v-if="!arrow || (showCancelMarkCross && clearable)"
v-if="!arrow || (mouseHovered && clearable)"
class="n-cancel-mark-cross"
:class="{
'n-cancel-mark-cross--arrow': arrow
@ -20,7 +20,7 @@
</transition>
<transition name="n-cancel-mark--transition">
<div
v-if="(arrow && !clearable) || (arrow && !showCancelMarkCross)"
v-if="(arrow && !clearable) || (arrow && !mouseHovered)"
class="n-cancel-mark-arrow"
:class="{
'n-cancel-mark-arrow--active': active,
@ -61,18 +61,18 @@ export default {
},
data () {
return {
showCancelMarkCross: false
mouseHovered: false
}
},
watch: {
clearable (newValue) {
if (!newValue) {
this.showCancelMarkCross = false
this.mouseHovered = false
}
},
show (newValue) {
if (!newValue) {
this.showCancelMarkCross = false
this.mouseHovered = false
}
}
},
@ -81,10 +81,10 @@ export default {
this.$emit('clear', e)
},
handleMouseEnter () {
if (!this.disabled && this.clearable) this.showCancelMarkCross = true
this.mouseHovered = true
},
handleMouseLeave () {
if (!this.disabled && this.clearable) this.showCancelMarkCross = false
this.mouseHovered = false
}
}
}

View File

@ -1,17 +1,19 @@
<template>
<div
v-if="type==='textarea'"
class="n-input"
:class="{
'is-disabled': disabled
'n-input--disabled': disabled,
[`n-input--${size}-size`]: true,
'n-input--textarea': type==='textarea',
'n-input--round': round,
'n-input--icon': icon,
'n-input--clearable': clearable
}"
>
<textarea
v-if="type==='textarea'"
ref="textarea"
class="n-input__textarea"
:class="{
[`n-input__textarea--${size}-size`]: true
}"
:rows="rows"
:placeholder="placeholder"
:value="value"
@ -25,23 +27,11 @@
@compositionstart="handleCompositionStart"
@compositionend="handleCompositionEnd"
/>
</div>
<div
v-else
class="n-input"
:class="{
'is-disabled': disabled
}"
>
<input
v-else
ref="input"
:type="type"
class="n-input__input"
:class="{
[`n-input__input--${size}-size`]: true,
[`n-input__input--round`]: round,
[`n-input__input--icon`]: icon
}"
:placeholder="placeholder"
:disabled="disabled === true"
:maxlength="maxlength"
@ -61,17 +51,26 @@
>
<n-icon :type="icon" />
</div>
<div class="n-input__cancel-mark">
<n-cancel-mark
:show="!disabled && !!value"
:clearable="clearable"
@clear="handleClear"
/>
</div>
</div>
</template>
<script>
import nIcon from '../../Icon'
import NIcon from '../../Icon'
import Emitter from '../../../mixins/emitter'
import NCancelMark from '../../CancelMark'
export default {
name: 'NInput',
components: {
nIcon
NIcon,
NCancelMark
},
mixins: [ Emitter ],
inject: {
@ -79,10 +78,6 @@ export default {
default: null
}
},
model: {
prop: 'value',
event: 'input'
},
props: {
type: {
type: String,
@ -119,6 +114,10 @@ export default {
maxlength: {
type: [String, Number],
default: 'false'
},
clearable: {
type: Boolean,
default: false
}
},
data () {
@ -160,6 +159,10 @@ export default {
},
handleClick (e) {
this.$emit('click', e)
},
handleClear (e) {
this.$emit('change', '')
this.$emit('input', '')
}
}
}

View File

@ -259,11 +259,8 @@ export default {
computed: {
selected () {
if (this.multiple) {
console.log('this.selectedOptions.length', this.selectedOptions.length)
return !!this.selectedOptions.length
} else {
console.log('this.selectedOption', this.selectedOption)
return !!this.selectedOption
}
},

View File

@ -8,6 +8,7 @@
position: relative;
height: 16px;
width: 16px;
vertical-align: bottom;
}
@include b(cancel-mark-cross) {

View File

@ -4,18 +4,6 @@
@include b(input) {
position: relative;
width: 100%;
&.is-disabled {
cursor: not-allowed;
.n-input__input, .n-input__textarea {
cursor: not-allowed;
background-color: $disabled-input-background-color;
color: $disabled-input-text-color;
box-shadow: none;
&::placeholder {
color: $disabled-input-placeholder-color;
}
}
}
.n-input__icon {
position: absolute;
line-height: 18px;
@ -36,7 +24,14 @@
top: calc(50% - 9px);
margin-left: 12px;
}
& .n-input__input, .n-input__textarea {
.n-input__cancel-mark {
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-50%);
line-height: 16px;
}
.n-input__input, .n-input__textarea {
-webkit-appearance: none;
box-sizing: border-box;
border: none;
@ -49,6 +44,7 @@
caret-color: $input-caret-color;
box-shadow: none;
transition: box-shadow .3s $default-cubic-bezier, background-color .3s $default-cubic-bezier;
vertical-align: bottom;
&:focus:hover {
box-shadow: inset 0 0 0px 1px $main-color, 0px 0px 10px 1px #366555;
}
@ -64,39 +60,89 @@
opacity: 1;
}
}
.n-input__input {
&.n-input__input--small-size {
&.n-input--small-size {
&:not(.n-input--textarea) {
height: $small-height;
}
.n-input__textarea {
font-size: $small-input-font-size;
}
.n-input__input {
height: $small-height;
line-height: $small-height;
padding: 0 14px;
font-size: $small-input-font-size;
}
&.n-input__input--default-size, &.n-input__input--medium-size {
}
&.n-input--default-size, &.n-input--medium-size {
&:not(.n-input--textarea) {
height: $default-height;
}
.n-input__textarea {
font-size: $default-input-font-size;
}
.n-input__input {
height: $default-height;
line-height: $default-height;
padding: 0 14px;
font-size: $default-input-font-size;
}
&.n-input__input--large-size {
}
&.n-input--large-size {
&:not(.n-input--textarea) {
height: $large-height;
}
.n-input__textarea {
font-size: $large-input-font-size;
}
.n-input__input {
height: $large-height;
line-height: $large-height;
padding: 0 14px;
font-size: $large-input-font-size;
}
}
.n-input__input.n-input__input--round {
&.n-input__input--small-size {
border-radius: $small-height / 2;
&.n-input--round {
.n-input__input {
padding-left: 18px;
}
&.n-input__input--default-size, &.n-input__input--medium-size {
border-radius: $default-height / 2;
&.n-input--small-size {
.n-input__input, .n-input__textarea {
border-radius: $small-height / 2;
}
}
&.n-input__input--large-size {
border-radius: $large-height / 2;
&.n-input--default-size, &.n-input--medium-size {
.n-input__input, .n-input__textarea {
border-radius: $default-height / 2;
}
}
&.n-input--large-size {
.n-input__input, .n-input__textarea {
border-radius: $large-height / 2;
}
}
}
.n-input__input.n-input__input--icon {
padding-left: 40px;
&.n-input--icon {
.n-input__input {
padding-left: 40px;
}
}
&.n-input--disabled {
cursor: not-allowed;
.n-input__input, .n-input__textarea {
cursor: not-allowed;
background-color: $disabled-input-background-color;
color: $disabled-input-text-color;
box-shadow: none!important;
&::placeholder {
color: $disabled-input-placeholder-color;
}
}
}
&.n-input--clearable {
.n-input__input, .n-input__textarea {
padding-right: 42px;
}
}
.n-input__textarea {
padding: 10px 14px;

View File

@ -19,9 +19,9 @@ $slow-out-cubic-bezier: cubic-bezier(0.4, 0.0, 1, 1);
/**
* n-input
*/
$small-input-font-size: 14px;
$small-input-font-size: 13px;
$default-input-font-size: 14px;
$large-input-font-size: 14px;
$large-input-font-size: 15px;
$input-background-color: rgba(255, 255, 255, 0.12);
$disabled-input-background-color:rgba(255,255,255,0.06);
$disabled-input-text-color: rgba(255, 255, 255, .2);