mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-01 13:36:55 +08:00
feat(input-number): add input number component.
This commit is contained in:
parent
795cd615f4
commit
99e70c8e9e
@ -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...)
|
82
demo/components/inputNumberDemo.vue
Normal file
82
demo/components/inputNumberDemo.vue
Normal 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>
|
@ -74,6 +74,10 @@ export default {
|
||||
name: 'Input',
|
||||
path: '/n-input'
|
||||
},
|
||||
{
|
||||
name: 'InputNumber',
|
||||
path: '/n-input-number'
|
||||
},
|
||||
{
|
||||
name: 'Message',
|
||||
path: '/n-message'
|
||||
|
@ -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 }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -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>`
|
||||
|
2
index.js
2
index.js
@ -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 {
|
||||
|
8
packages/common/InputNumber/index.js
Normal file
8
packages/common/InputNumber/index.js
Normal 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
|
109
packages/common/InputNumber/src/main.vue
Normal file
109
packages/common/InputNumber/src/main.vue
Normal 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>
|
Loading…
Reference in New Issue
Block a user