feat(input-number): add input number component.

This commit is contained in:
07akioni 2019-07-10 19:07:16 +08:00
parent 795cd615f4
commit 99e70c8e9e
8 changed files with 225 additions and 2 deletions

View File

@ -69,6 +69,8 @@ Vue.use(naiveUi)
|Table|🚧|❌|Function is not fulfilled|
|Tooltip|😍|❌|Remove the dependency of Popper.js|
|Popup|😍|❌|May be need to merge with Tooltip|
|InputNumber|🚧|||
|Radio|🚧|||
## Todo
1. Z-index management on `Select` & `Tooltip` & `Modal`(Low Priority)
2. Full featured table component(Medium Priority)
@ -77,4 +79,5 @@ Vue.use(naiveUi)
5. Complete unit test for all existing components(High Priority)
6. Create a Markdown webpack loader to convert documentation(Low Priority)
7. Refactor documentation page(for code clairity)
8. Code refactor for some 😢 messy code(which is my bad...)
8. Code refactor for some 😢 messy code(which is my bad...)
9. Refactor CSS use mixins(which means I should learn SCSS hard...)

View File

@ -0,0 +1,82 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
InputNumber
</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">
{{ value }}
<n-input-number v-model="value" />
</div>
<div class="n-doc-section__source">
<textarea><n-input-number v-model="value" /></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Min and Max
</div>
<div class="n-doc-section__view">
{{ value }}
<n-input-number
v-model="value"
:min="-5"
:max="5"
/>
</div>
<div class="n-doc-section__source">
<textarea><n-input-number
v-model="value"
:min="-5"
:max="5"
/></textarea>
</div>
</div>
<div class="n-doc-section">
<div class="n-doc-section__header">
Step
</div>
<div class="n-doc-section__view">
{{ value }}
<n-input-number
v-model="value"
:min="-10"
:max="10"
step="3"
/>
</div>
<div class="n-doc-section__source">
<textarea><n-input-number
v-model="value"
:min="-10"
:max="10"
step="3"
/></textarea>
</div>
</div>
</div>
</div>
</template>
<script>
import docCodeEditorMixin from './docCodeEditorMixin'
export default {
mixins: [docCodeEditorMixin],
data () {
return {
value: 'plx'
}
},
methods: {
}
}
</script>

View File

@ -74,6 +74,10 @@ export default {
name: 'Input',
path: '/n-input'
},
{
name: 'InputNumber',
path: '/n-input-number'
},
{
name: 'Message',
path: '/n-message'

View File

@ -22,6 +22,7 @@ import tooltipDemo from './components/tooltipDemo'
import popupDemo from './components/popupDemo'
import alertDemo from './components/alertDemo'
import datePickerDemo from './components/datePickerDemo'
import inputNumberDemo from './components/inputNumberDemo'
import notificationDemo from './components/notificationDemo'
import nimbusConfirmCardDemo from './components/nimbusConfirmCardDemo'
@ -62,7 +63,8 @@ const routes = [
{ path: '/n-nimbus-confirm-card', component: nimbusConfirmCardDemo },
{ path: '/n-pagination', component: paginationDemo },
{ path: '/n-alert', component: alertDemo },
{ path: '/n-date-picker', component: datePickerDemo }
{ path: '/n-date-picker', component: datePickerDemo },
{ path: '/n-input-number', component: inputNumberDemo }
]
},
{

View File

@ -170,6 +170,18 @@ Vue.use(naiveUi)
<td style="text-align:center;"></td>
<td>May be need to merge with Tooltip</td>
</tr>
<tr>
<td>InputNumber</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
<tr>
<td>Radio</td>
<td style="text-align:center;">🚧</td>
<td style="text-align:center;"></td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="todo">Todo</h2>
@ -182,4 +194,5 @@ Vue.use(naiveUi)
<li>Create a Markdown webpack loader to convert documentation(Low Priority)</li>
<li>Refactor documentation page(for code clairity)</li>
<li>Code refactor for some 😢 messy code(which is my bad)</li>
<li>Refactor CSS use mixins(which means I should learn SCSS hard)</li>
</ol></div>`

View File

@ -21,6 +21,7 @@ import Tooltip from './packages/common/Tooltip'
import Popup from './packages/common/Popup'
import Alert from './packages/common/Alert'
import DatePicker from './packages/common/DatePicker'
import InputNumber from './packages/common/InputNumber'
import ServiceCard from './packages/nimbus/ServiceCard'
import HomeLayout from './packages/nimbus/HomeLayout'
@ -59,6 +60,7 @@ function install (Vue) {
Popup.install(Vue)
Alert.install(Vue)
DatePicker.install(Vue)
InputNumber.install(Vue)
}
export default {

View File

@ -0,0 +1,8 @@
/* istanbul ignore file */
import NInputNumber from './src/main.vue'
NInputNumber.install = function (Vue) {
Vue.component(NInputNumber.name, NInputNumber)
}
export default NInputNumber

View File

@ -0,0 +1,109 @@
<template>
<div>
<button @click="minus">
-
</button><input
type="text"
:value="value"
><button @click="add">
+
</button>
</div>
</template>
<script>
const DEFAULT_STEP = 1
function parseNumber (number) {
if (number === null) return null
if (typeof number === 'number') {
return number
} else {
const parsedNumber = Number(number)
if (Number.isNaN(parsedNumber)) return null
else {
return parsedNumber
}
}
}
export default {
name: 'NInputNumber',
model: {
prop: 'value',
event: 'change'
},
props: {
value: {
type: [Number, String],
default: null
},
step: {
type: [Number, String],
default: DEFAULT_STEP
},
min: {
type: [Number, String],
default: null
},
max: {
type: [Number, String],
default: null
}
},
computed: {
safeStep () {
const parsedNumber = parseNumber(this.step)
if (parsedNumber !== null) return parsedNumber === 0 ? DEFAULT_STEP : Math.abs(parsedNumber)
else return DEFAULT_STEP
},
safeMin () {
const parsedNumber = parseNumber(this.min)
if (parsedNumber !== null) return parsedNumber
else return null
},
safeMax () {
const parsedNumber = parseNumber(this.max)
if (parsedNumber !== null) return parsedNumber
else return null
}
},
created () {
this.guardCurrentValue()
},
methods: {
guardCurrentValue () {
if (typeof this.value !== 'number') {
const parsedNumber = Number(this.value)
if (Number.isNaN(parsedNumber)) {
this.$emit('change', 0)
} else {
this.$emit('change', parsedNumber)
}
}
},
add () {
this.guardCurrentValue()
const previousValue = this.value
let valueAfterChange = this.value + this.safeStep
if (this.safeMax !== null && valueAfterChange > this.safeMax) {
valueAfterChange = this.safeMax
}
if (valueAfterChange !== previousValue) {
this.$emit('change', valueAfterChange)
}
},
minus () {
this.guardCurrentValue()
const previousValue = this.value
let valueAfterChange = this.value - this.safeStep
if (this.safeMin !== null && valueAfterChange < this.safeMin) {
valueAfterChange = this.safeMin
}
if (valueAfterChange !== previousValue) {
this.$emit('change', valueAfterChange)
}
}
}
}
</script>