@inkline/inkline
Version:
Inkline is the Vue.js UI/UX Library built for creating your next design system
198 lines • 5.63 kB
JavaScript
import { defineComponent } from 'vue';
import IButton from '../IButton/index.vue';
import IInput from '../IInput/index.vue';
import { uid } from '../../helpers/index.mjs';
import { defaultPropValue, sizePropValidator } from '../../mixins/props/index.mjs';
const componentName = 'INumberInput';
export default defineComponent({
name: componentName,
components: {
IButton
},
extends: IInput,
props: {
/**
* The color variant of the input
* @type light | dark
* @default light
* @name color
*/
color: {
type: String,
default: defaultPropValue(componentName, 'color')
},
/**
* Display the input as clearable
* @type Boolean
* @default false
* @name clearable
*/
clearable: {
type: Boolean,
default: false
},
/**
* The disabled state of the input
* @type Boolean
* @default false
* @name disabled
*/
disabled: {
type: Boolean,
default: false
},
/**
* The id of the internal input element
* @type String
* @default
* @name id
*/
id: {
type: String,
default: ''
},
/**
* Used to set the field value
* @type String | Number
* @default
* @name modelValue
*/
modelValue: {
type: [String, Number],
default: ''
},
/**
* The unique identifier of the input
* @type String
* @default uid()
* @name name
*/
name: {
type: [String, Number],
default() {
return uid('input');
}
},
/**
* The readonly state of the input
* @type Boolean
* @default false
* @name readonly
*/
readonly: {
type: Boolean,
default: false
},
/**
* The size variant of the input
* @type sm | md | lg
* @default md
* @name size
*/
size: {
type: String,
default: defaultPropValue(componentName, 'size'),
validator: sizePropValidator
},
/**
* The tabindex of the input
* @type Number | String
* @default 0
* @name tabindex
*/
tabindex: {
type: [Number, String],
default: 0
},
/**
* The minimum allowed input value
* @type Number
* @default -Infinity
* @name min
*/
min: {
type: [Number, String],
default: -Infinity
},
/**
* The maximum allowed input value
* @type Number
* @default +Infinity
* @name max
*/
max: {
type: [Number, String],
default: Infinity
},
/**
* The precision of the input value, for floating point numbers
* @type Number
* @default 0
* @name precision
*/
precision: {
type: Number,
default: 0
},
/**
* The increment step to increase or decrease the value by
* @type Number
* @default 1
* @name step
*/
step: {
type: Number,
default: 1
}
},
emits: [
/**
* Event emitted for setting the modelValue
* @event update:modelValue
*/
'update:modelValue'
],
watch: {
modelValue: {
immediate: true,
handler(value) {
let newValue = (value || '').toString()
.replace(/^[^0-9-]/, '')
.replace(/^(-)[^0-9]/, '$1')
.replace(new RegExp(`^(-?[0-9]+)[^0-9${this.precision > 0 ? '.' : ''}]`), '$1');
if (this.precision > 0) {
newValue = newValue
.replace(/^(-?[0-9]+\.)[^0-9]/, '$1')
.replace(new RegExp(`^(-?[0-9]+\\.[0-9]{0,${this.precision}}).*`), '$1');
}
if (parseFloat(newValue) >= parseFloat(this.max))
newValue = this.max.toString();
if (parseFloat(newValue) <= parseFloat(this.min))
newValue = this.min.toString();
this.parent.onInput?.(this.name, newValue);
this.$emit('update:modelValue', newValue);
}
}
},
methods: {
decrease() {
this.$emit('update:modelValue', this.formatPrecision((Number(this.modelValue) - this.step).toString()));
},
increase() {
this.$emit('update:modelValue', this.formatPrecision((Number(this.modelValue) + this.step).toString()));
},
formatPrecision(value) {
const parts = value.split('.');
let decimals = parts[1] || '';
for (let i = decimals.length; i < this.precision; i += 1) {
decimals += '0';
}
return this.precision > 0 ? `${parts[0]}.${decimals}` : parts[0];
},
onBlurFormatPrecision(event) {
this.$emit('update:modelValue', this.formatPrecision(Number(this.modelValue).toString()));
this.parent.onBlur?.(this.name, event);
}
}
});
//# sourceMappingURL=script.mjs.map