vue-currency-input
Advanced tools
Comparing version 2.0.0-beta.0 to 2.0.0-beta.1
/** | ||
* Vue Currency Input 2.0.0-beta.0 | ||
* Vue Currency Input 2.0.0-beta.1 | ||
* (c) 2018-2020 Matthias Stiller | ||
* @license MIT | ||
*/ | ||
import { getCurrentInstance, isVue3, ref, computed, onMounted, watch } from 'vue-demi'; | ||
import { ref, getCurrentInstance, isVue3, computed, onMounted, onUnmounted } from 'vue-demi'; | ||
@@ -15,2 +15,3 @@ const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); | ||
const DECIMAL_SYMBOLS = [',', '.', '٫']; | ||
const INTEGER_PATTERN = '(0|[1-9]\\d*)'; | ||
class NumberFormat { | ||
@@ -48,6 +49,6 @@ constructor (options) { | ||
str = this.stripMinusSymbol(str); | ||
const fraction = this.decimalSymbol ? `(${escapeRegExp(this.decimalSymbol)}\\d*)?` : ''; | ||
const match = str.match(new RegExp(`^${this.integerPattern()}${fraction}$`)); | ||
if (match) { | ||
return Number(`${negative ? '-' : ''}${(this.onlyDigits(match[1]))}.${(this.onlyDigits(match[3] || ''))}`) | ||
const fraction = this.decimalSymbol ? `(?:${escapeRegExp(this.decimalSymbol)}(\\d*))?` : ''; | ||
const match = this.stripGroupingSymbol(str).match(new RegExp(`^${INTEGER_PATTERN}${fraction}$`)); | ||
if (match && this.isValidIntegerFormat(str.split(this.decimalSymbol)[0], Number(match[1]))) { | ||
return Number(`${negative ? '-' : ''}${(this.onlyDigits(match[1]))}.${(this.onlyDigits(match[2] || ''))}`) | ||
} | ||
@@ -57,2 +58,8 @@ } | ||
} | ||
isValidIntegerFormat (formattedNumber, number) { | ||
return [ | ||
this.normalizeDigits(number.toLocaleString(this.locale, { useGrouping: true })), | ||
this.normalizeDigits(number.toLocaleString(this.locale, { useGrouping: false })) | ||
].includes(formattedNumber) | ||
} | ||
format (number, options = { | ||
@@ -68,5 +75,2 @@ minimumFractionDigits: this.minimumFractionDigits, | ||
} | ||
integerPattern () { | ||
return `(0|[1-9]\\d{0,2}(${escapeRegExp(this.groupingSymbol)}?\\d{3})*)` | ||
} | ||
toFraction (str) { | ||
@@ -76,3 +80,3 @@ return `${this.digits[0]}${this.decimalSymbol}${(this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))}` | ||
isFractionIncomplete (str) { | ||
return !!this.normalizeDigits(str).match(new RegExp(`^${this.integerPattern()}${escapeRegExp(this.decimalSymbol)}$`)) | ||
return !!this.normalizeDigits(this.stripGroupingSymbol(str)).match(new RegExp(`^${INTEGER_PATTERN}${escapeRegExp(this.decimalSymbol)}$`)) | ||
} | ||
@@ -85,2 +89,5 @@ isNegative (str) { | ||
} | ||
stripGroupingSymbol (str) { | ||
return str.replace(new RegExp(escapeRegExp(this.groupingSymbol), 'g'), '') | ||
} | ||
stripMinusSymbol (str) { | ||
@@ -184,8 +191,8 @@ return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '') | ||
valueRange: undefined, | ||
allowNegative: true | ||
allowNegative: true, | ||
useGrouping: true | ||
}; | ||
class NumberInput { | ||
constructor (el, options, callbackFns) { | ||
constructor (el, options) { | ||
this.el = el; | ||
this.callbackFns = callbackFns; | ||
this.numberValue = null; | ||
@@ -197,6 +204,7 @@ this.addEventListener(); | ||
init (options) { | ||
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative } = { ...DEFAULT_OPTIONS, ...options }; | ||
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative, useGrouping } = { ...DEFAULT_OPTIONS, ...options }; | ||
this.autoDecimalDigits = autoDecimalDigits; | ||
this.valueAsInteger = valueAsInteger; | ||
this.allowNegative = allowNegative; | ||
this.useGrouping = useGrouping; | ||
this.hideCurrencySymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideCurrencySymbol; | ||
@@ -229,6 +237,11 @@ this.hideNegligibleDecimalDigitsOnFocus = distractionFree === true || !!(distractionFree || {}).hideNegligibleDecimalDigits; | ||
} | ||
dispatchEvent (eventName) { | ||
const event = document.createEvent('CustomEvent'); | ||
event.initCustomEvent(eventName, true, true, { ...this.getValue() }); | ||
this.el.dispatchEvent(event); | ||
} | ||
applyFixedFractionFormat (number, forcedChange) { | ||
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null); | ||
if (number !== this.numberValue || forcedChange) { | ||
this.callbackFns.onChange(this.getValue()); | ||
this.dispatchEvent('change'); | ||
} | ||
@@ -273,3 +286,3 @@ } | ||
: this.currencyFormat.format(numberValue, { | ||
useGrouping: !(this.focus && this.hideGroupingSymbolOnFocus), | ||
useGrouping: this.useGrouping && !(this.focus && this.hideGroupingSymbolOnFocus), | ||
minimumFractionDigits, | ||
@@ -296,31 +309,33 @@ maximumFractionDigits | ||
this.formattedValue = this.el.value; | ||
this.callbackFns.onInput(this.getValue()); | ||
this.dispatchEvent('input'); | ||
} | ||
addEventListener () { | ||
this.el.addEventListener('input', () => { | ||
const { value, selectionStart } = this.el; | ||
this.format(value); | ||
if (this.focus) { | ||
const getCaretPositionAfterFormat = () => { | ||
const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat; | ||
let caretPositionFromLeft = value.length - selectionStart; | ||
const newValueLength = this.formattedValue.length; | ||
if (this.formattedValue.substr(selectionStart, 1) === groupingSymbol && count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) { | ||
return newValueLength - caretPositionFromLeft - 1 | ||
} | ||
if (decimalSymbol) { | ||
const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1; | ||
if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) { | ||
return this.formattedValue.indexOf(decimalSymbol) + 1 | ||
} else { | ||
if (!this.autoDecimalDigits && selectionStart > decimalSymbolPosition) { | ||
if (this.currencyFormat.onlyDigits(value.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) { | ||
caretPositionFromLeft -= 1; | ||
this.el.addEventListener('input', (e) => { | ||
if (!e.detail) { | ||
const { value, selectionStart } = this.el; | ||
this.format(value); | ||
if (this.focus) { | ||
const getCaretPositionAfterFormat = () => { | ||
const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat; | ||
let caretPositionFromLeft = value.length - selectionStart; | ||
const newValueLength = this.formattedValue.length; | ||
if (this.formattedValue.substr(selectionStart, 1) === groupingSymbol && count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) { | ||
return newValueLength - caretPositionFromLeft - 1 | ||
} | ||
if (decimalSymbol) { | ||
const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1; | ||
if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) { | ||
return this.formattedValue.indexOf(decimalSymbol) + 1 | ||
} else { | ||
if (!this.autoDecimalDigits && selectionStart > decimalSymbolPosition) { | ||
if (this.currencyFormat.onlyDigits(value.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) { | ||
caretPositionFromLeft -= 1; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length) | ||
}; | ||
this.setCaretPosition(getCaretPositionAfterFormat()); | ||
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length) | ||
}; | ||
this.setCaretPosition(getCaretPositionAfterFormat()); | ||
} | ||
} | ||
@@ -371,4 +386,6 @@ }, { capture: true }); | ||
}); | ||
this.el.addEventListener('change', () => { | ||
this.callbackFns.onChange(this.getValue()); | ||
this.el.addEventListener('change', (e) => { | ||
if (!e.detail) { | ||
this.dispatchEvent('change'); | ||
} | ||
}); | ||
@@ -380,47 +397,59 @@ } | ||
const findInput = (el) => el.tagName.toLowerCase() === 'input' ? el : el.querySelector('input'); | ||
var useCurrencyInput = ({ inputRef, props, emit }) => { | ||
let numberInput; | ||
const currentInstance = getCurrentInstance(); | ||
const lazy = isVue3 && (currentInstance.attrs.modelModifiers || {}).lazy; | ||
var useCurrencyInput = (options) => { | ||
let numberInput, input; | ||
const inputRef = ref(null); | ||
const formattedValue = ref(null); | ||
const instance = getCurrentInstance(); | ||
const emit = (event, value) => isVue3 ? instance.emit(event, value) : instance.proxy.$emit(event, value); | ||
const lazyModel = isVue3 && (instance.attrs.modelModifiers || {}).lazy; | ||
const numberValue = computed(() => isVue3 ? instance.props.modelValue : instance.props.value); | ||
const inputEvent = isVue3 ? 'update:modelValue' : 'input'; | ||
const changeEvent = isVue3 ? 'update:modelValue' : 'change'; | ||
const formattedValue = ref(null); | ||
const numberValue = computed(() => props[isVue3 ? 'modelValue' : 'value']); | ||
const options = computed(() => Object.keys(DEFAULT_OPTIONS).reduce((options, key) => { | ||
if (props[key] !== undefined) { | ||
options[key] = props[key]; | ||
const changeEvent = isVue3 && lazyModel ? 'update:modelValue' : 'change'; | ||
const hasInputEventListener = (!!instance.attrs['onUpdate:modelValue'] && !lazyModel) || !!instance.proxy.$listeners[inputEvent]; | ||
const hasChangeEventListener = lazyModel || !!instance.attrs.onChange || !!instance.proxy.$listeners[changeEvent]; | ||
const onInput = (e) => { | ||
if (e.detail) { | ||
if (numberValue.value !== e.detail.number) { | ||
emit(inputEvent, e.detail.number); | ||
} | ||
formattedValue.value = e.detail.formatted; | ||
} | ||
return options | ||
}, {})); | ||
}; | ||
const onChange = (e) => { | ||
if (e.detail) { | ||
emit(changeEvent, e.detail.number); | ||
formattedValue.value = e.detail.formatted; | ||
} | ||
}; | ||
onMounted(() => { | ||
if (inputRef.value) { | ||
const input = '$el' in inputRef.value ? findInput(inputRef.value.$el) : inputRef.value; | ||
if (input == null) { | ||
throw new Error('No input element found') | ||
} else { | ||
numberInput = new NumberInput(input, options.value, { | ||
onInput (value) { | ||
if (!lazy && numberValue.value !== value.number) { | ||
emit(inputEvent, value.number); | ||
} | ||
formattedValue.value = value.formatted; | ||
}, | ||
onChange (value) { | ||
emit(changeEvent, value.number); | ||
formattedValue.value = value.formatted; | ||
} | ||
}); | ||
numberInput.setValue(numberValue.value); | ||
input = '$el' in inputRef.value ? findInput(inputRef.value.$el) : inputRef.value; | ||
if (input == null) { | ||
throw new Error('No input element found') | ||
} else { | ||
numberInput = new NumberInput(input, options); | ||
if (hasInputEventListener) { | ||
input.addEventListener('input', onInput); | ||
} | ||
if (hasChangeEventListener) { | ||
input.addEventListener('change', onChange); | ||
} | ||
numberInput.setValue(numberValue.value); | ||
} | ||
}); | ||
watch(numberValue, (value) => { | ||
numberInput.setValue(value); | ||
onUnmounted(() => { | ||
if (hasInputEventListener) { | ||
input.removeEventListener('input', onInput); | ||
} | ||
if (hasChangeEventListener) { | ||
input.removeEventListener('change', onChange); | ||
} | ||
}); | ||
watch(options, (options) => { | ||
numberInput.setOptions(options); | ||
}); | ||
return { formattedValue } | ||
return { | ||
inputRef, | ||
formattedValue, | ||
setValue: (value) => numberInput.setValue(value), | ||
setOptions: (options) => numberInput.setOptions(options) | ||
} | ||
}; | ||
export default useCurrencyInput; |
/** | ||
* Vue Currency Input 2.0.0-beta.0 | ||
* Vue Currency Input 2.0.0-beta.1 | ||
* (c) 2018-2020 Matthias Stiller | ||
@@ -19,2 +19,3 @@ * @license MIT | ||
const DECIMAL_SYMBOLS = [',', '.', '٫']; | ||
const INTEGER_PATTERN = '(0|[1-9]\\d*)'; | ||
class NumberFormat { | ||
@@ -52,6 +53,6 @@ constructor (options) { | ||
str = this.stripMinusSymbol(str); | ||
const fraction = this.decimalSymbol ? `(${escapeRegExp(this.decimalSymbol)}\\d*)?` : ''; | ||
const match = str.match(new RegExp(`^${this.integerPattern()}${fraction}$`)); | ||
if (match) { | ||
return Number(`${negative ? '-' : ''}${(this.onlyDigits(match[1]))}.${(this.onlyDigits(match[3] || ''))}`) | ||
const fraction = this.decimalSymbol ? `(?:${escapeRegExp(this.decimalSymbol)}(\\d*))?` : ''; | ||
const match = this.stripGroupingSymbol(str).match(new RegExp(`^${INTEGER_PATTERN}${fraction}$`)); | ||
if (match && this.isValidIntegerFormat(str.split(this.decimalSymbol)[0], Number(match[1]))) { | ||
return Number(`${negative ? '-' : ''}${(this.onlyDigits(match[1]))}.${(this.onlyDigits(match[2] || ''))}`) | ||
} | ||
@@ -61,2 +62,8 @@ } | ||
} | ||
isValidIntegerFormat (formattedNumber, number) { | ||
return [ | ||
this.normalizeDigits(number.toLocaleString(this.locale, { useGrouping: true })), | ||
this.normalizeDigits(number.toLocaleString(this.locale, { useGrouping: false })) | ||
].includes(formattedNumber) | ||
} | ||
format (number, options = { | ||
@@ -72,5 +79,2 @@ minimumFractionDigits: this.minimumFractionDigits, | ||
} | ||
integerPattern () { | ||
return `(0|[1-9]\\d{0,2}(${escapeRegExp(this.groupingSymbol)}?\\d{3})*)` | ||
} | ||
toFraction (str) { | ||
@@ -80,3 +84,3 @@ return `${this.digits[0]}${this.decimalSymbol}${(this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))}` | ||
isFractionIncomplete (str) { | ||
return !!this.normalizeDigits(str).match(new RegExp(`^${this.integerPattern()}${escapeRegExp(this.decimalSymbol)}$`)) | ||
return !!this.normalizeDigits(this.stripGroupingSymbol(str)).match(new RegExp(`^${INTEGER_PATTERN}${escapeRegExp(this.decimalSymbol)}$`)) | ||
} | ||
@@ -89,2 +93,5 @@ isNegative (str) { | ||
} | ||
stripGroupingSymbol (str) { | ||
return str.replace(new RegExp(escapeRegExp(this.groupingSymbol), 'g'), '') | ||
} | ||
stripMinusSymbol (str) { | ||
@@ -188,8 +195,8 @@ return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '') | ||
valueRange: undefined, | ||
allowNegative: true | ||
allowNegative: true, | ||
useGrouping: true | ||
}; | ||
class NumberInput { | ||
constructor (el, options, callbackFns) { | ||
constructor (el, options) { | ||
this.el = el; | ||
this.callbackFns = callbackFns; | ||
this.numberValue = null; | ||
@@ -201,6 +208,7 @@ this.addEventListener(); | ||
init (options) { | ||
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative } = { ...DEFAULT_OPTIONS, ...options }; | ||
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative, useGrouping } = { ...DEFAULT_OPTIONS, ...options }; | ||
this.autoDecimalDigits = autoDecimalDigits; | ||
this.valueAsInteger = valueAsInteger; | ||
this.allowNegative = allowNegative; | ||
this.useGrouping = useGrouping; | ||
this.hideCurrencySymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideCurrencySymbol; | ||
@@ -233,6 +241,11 @@ this.hideNegligibleDecimalDigitsOnFocus = distractionFree === true || !!(distractionFree || {}).hideNegligibleDecimalDigits; | ||
} | ||
dispatchEvent (eventName) { | ||
const event = document.createEvent('CustomEvent'); | ||
event.initCustomEvent(eventName, true, true, { ...this.getValue() }); | ||
this.el.dispatchEvent(event); | ||
} | ||
applyFixedFractionFormat (number, forcedChange) { | ||
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null); | ||
if (number !== this.numberValue || forcedChange) { | ||
this.callbackFns.onChange(this.getValue()); | ||
this.dispatchEvent('change'); | ||
} | ||
@@ -277,3 +290,3 @@ } | ||
: this.currencyFormat.format(numberValue, { | ||
useGrouping: !(this.focus && this.hideGroupingSymbolOnFocus), | ||
useGrouping: this.useGrouping && !(this.focus && this.hideGroupingSymbolOnFocus), | ||
minimumFractionDigits, | ||
@@ -300,31 +313,33 @@ maximumFractionDigits | ||
this.formattedValue = this.el.value; | ||
this.callbackFns.onInput(this.getValue()); | ||
this.dispatchEvent('input'); | ||
} | ||
addEventListener () { | ||
this.el.addEventListener('input', () => { | ||
const { value, selectionStart } = this.el; | ||
this.format(value); | ||
if (this.focus) { | ||
const getCaretPositionAfterFormat = () => { | ||
const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat; | ||
let caretPositionFromLeft = value.length - selectionStart; | ||
const newValueLength = this.formattedValue.length; | ||
if (this.formattedValue.substr(selectionStart, 1) === groupingSymbol && count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) { | ||
return newValueLength - caretPositionFromLeft - 1 | ||
} | ||
if (decimalSymbol) { | ||
const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1; | ||
if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) { | ||
return this.formattedValue.indexOf(decimalSymbol) + 1 | ||
} else { | ||
if (!this.autoDecimalDigits && selectionStart > decimalSymbolPosition) { | ||
if (this.currencyFormat.onlyDigits(value.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) { | ||
caretPositionFromLeft -= 1; | ||
this.el.addEventListener('input', (e) => { | ||
if (!e.detail) { | ||
const { value, selectionStart } = this.el; | ||
this.format(value); | ||
if (this.focus) { | ||
const getCaretPositionAfterFormat = () => { | ||
const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat; | ||
let caretPositionFromLeft = value.length - selectionStart; | ||
const newValueLength = this.formattedValue.length; | ||
if (this.formattedValue.substr(selectionStart, 1) === groupingSymbol && count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) { | ||
return newValueLength - caretPositionFromLeft - 1 | ||
} | ||
if (decimalSymbol) { | ||
const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1; | ||
if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) { | ||
return this.formattedValue.indexOf(decimalSymbol) + 1 | ||
} else { | ||
if (!this.autoDecimalDigits && selectionStart > decimalSymbolPosition) { | ||
if (this.currencyFormat.onlyDigits(value.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) { | ||
caretPositionFromLeft -= 1; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length) | ||
}; | ||
this.setCaretPosition(getCaretPositionAfterFormat()); | ||
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length) | ||
}; | ||
this.setCaretPosition(getCaretPositionAfterFormat()); | ||
} | ||
} | ||
@@ -375,4 +390,6 @@ }, { capture: true }); | ||
}); | ||
this.el.addEventListener('change', () => { | ||
this.callbackFns.onChange(this.getValue()); | ||
this.el.addEventListener('change', (e) => { | ||
if (!e.detail) { | ||
this.dispatchEvent('change'); | ||
} | ||
}); | ||
@@ -384,45 +401,57 @@ } | ||
const findInput = (el) => el.tagName.toLowerCase() === 'input' ? el : el.querySelector('input'); | ||
var useCurrencyInput = ({ inputRef, props, emit }) => { | ||
let numberInput; | ||
const currentInstance = vueDemi.getCurrentInstance(); | ||
const lazy = vueDemi.isVue3 && (currentInstance.attrs.modelModifiers || {}).lazy; | ||
var useCurrencyInput = (options) => { | ||
let numberInput, input; | ||
const inputRef = vueDemi.ref(null); | ||
const formattedValue = vueDemi.ref(null); | ||
const instance = vueDemi.getCurrentInstance(); | ||
const emit = (event, value) => vueDemi.isVue3 ? instance.emit(event, value) : instance.proxy.$emit(event, value); | ||
const lazyModel = vueDemi.isVue3 && (instance.attrs.modelModifiers || {}).lazy; | ||
const numberValue = vueDemi.computed(() => vueDemi.isVue3 ? instance.props.modelValue : instance.props.value); | ||
const inputEvent = vueDemi.isVue3 ? 'update:modelValue' : 'input'; | ||
const changeEvent = vueDemi.isVue3 ? 'update:modelValue' : 'change'; | ||
const formattedValue = vueDemi.ref(null); | ||
const numberValue = vueDemi.computed(() => props[vueDemi.isVue3 ? 'modelValue' : 'value']); | ||
const options = vueDemi.computed(() => Object.keys(DEFAULT_OPTIONS).reduce((options, key) => { | ||
if (props[key] !== undefined) { | ||
options[key] = props[key]; | ||
const changeEvent = vueDemi.isVue3 && lazyModel ? 'update:modelValue' : 'change'; | ||
const hasInputEventListener = (!!instance.attrs['onUpdate:modelValue'] && !lazyModel) || !!instance.proxy.$listeners[inputEvent]; | ||
const hasChangeEventListener = lazyModel || !!instance.attrs.onChange || !!instance.proxy.$listeners[changeEvent]; | ||
const onInput = (e) => { | ||
if (e.detail) { | ||
if (numberValue.value !== e.detail.number) { | ||
emit(inputEvent, e.detail.number); | ||
} | ||
formattedValue.value = e.detail.formatted; | ||
} | ||
return options | ||
}, {})); | ||
}; | ||
const onChange = (e) => { | ||
if (e.detail) { | ||
emit(changeEvent, e.detail.number); | ||
formattedValue.value = e.detail.formatted; | ||
} | ||
}; | ||
vueDemi.onMounted(() => { | ||
if (inputRef.value) { | ||
const input = '$el' in inputRef.value ? findInput(inputRef.value.$el) : inputRef.value; | ||
if (input == null) { | ||
throw new Error('No input element found') | ||
} else { | ||
numberInput = new NumberInput(input, options.value, { | ||
onInput (value) { | ||
if (!lazy && numberValue.value !== value.number) { | ||
emit(inputEvent, value.number); | ||
} | ||
formattedValue.value = value.formatted; | ||
}, | ||
onChange (value) { | ||
emit(changeEvent, value.number); | ||
formattedValue.value = value.formatted; | ||
} | ||
}); | ||
numberInput.setValue(numberValue.value); | ||
input = '$el' in inputRef.value ? findInput(inputRef.value.$el) : inputRef.value; | ||
if (input == null) { | ||
throw new Error('No input element found') | ||
} else { | ||
numberInput = new NumberInput(input, options); | ||
if (hasInputEventListener) { | ||
input.addEventListener('input', onInput); | ||
} | ||
if (hasChangeEventListener) { | ||
input.addEventListener('change', onChange); | ||
} | ||
numberInput.setValue(numberValue.value); | ||
} | ||
}); | ||
vueDemi.watch(numberValue, (value) => { | ||
numberInput.setValue(value); | ||
vueDemi.onUnmounted(() => { | ||
if (hasInputEventListener) { | ||
input.removeEventListener('input', onInput); | ||
} | ||
if (hasChangeEventListener) { | ||
input.removeEventListener('change', onChange); | ||
} | ||
}); | ||
vueDemi.watch(options, (options) => { | ||
numberInput.setOptions(options); | ||
}); | ||
return { formattedValue } | ||
return { | ||
inputRef, | ||
formattedValue, | ||
setValue: (value) => numberInput.setValue(value), | ||
setOptions: (options) => numberInput.setOptions(options) | ||
} | ||
}; | ||
@@ -429,0 +458,0 @@ |
{ | ||
"name": "vue-currency-input", | ||
"description": "Easy input of currency formatted numbers for Vue.js.", | ||
"version": "2.0.0-beta.0", | ||
"version": "2.0.0-beta.1", | ||
"license": "MIT", | ||
@@ -39,9 +39,7 @@ "unpkg": "dist/vue-currency-input.umd.js", | ||
"lint": "vue-cli-service lint", | ||
"test:unit": "vue-cli-service test:unit", | ||
"docs:dev": "vuepress dev docs", | ||
"docs:build": "vuepress build docs" | ||
"test:unit": "vue-cli-service test:unit" | ||
}, | ||
"peerDependencies": { | ||
"@vue/composition-api": "^1.0.0-beta.1", | ||
"vue": "^2.5 || ^3.0.0" | ||
"@vue/composition-api": "^1.0.0-beta.22", | ||
"vue": "^2.6 || ^3.0.0" | ||
}, | ||
@@ -54,6 +52,5 @@ "devDependencies": { | ||
"@vue/cli-service": "~4.4.1", | ||
"@vue/composition-api": "^1.0.0-beta.14", | ||
"@vue/composition-api": "^1.0.0-beta.22", | ||
"@vue/eslint-config-standard": "^5.1.2", | ||
"@vue/test-utils": "^1.0.3", | ||
"@vuepress/plugin-pwa": "^1.6.0", | ||
"babel-eslint": "^10.1.0", | ||
@@ -72,8 +69,7 @@ "core-js": "^3.6.5", | ||
"vue-template-compiler": "^2.6.11", | ||
"vuepress": "^1.6.0", | ||
"vuetify": "^2.1.15" | ||
}, | ||
"dependencies": { | ||
"vue-demi": "^0.4.0" | ||
"vue-demi": "^0.5.3" | ||
} | ||
} |
@@ -17,5 +17,5 @@ [](https://travis-ci.com/dm4t2/vue-currency-input) | ||
* Format as you type | ||
* Built on standards: Uses the [ECMAScript Internationalization API (ECMA-402)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) for currency formatting | ||
* Standard-compliant currency formatting based on [ECMAScript Internationalization API (ECMA-402)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) | ||
* Distraction free (hides the formatting on focus for easier input) | ||
* Allows handling values as integer numbers for full precision | ||
* Allows float values to be exported as integer numbers depending on used precision (`$1.99` ➔ `199` cents) | ||
* Auto decimal digits (automatically inserts the decimal symbol, using the last inputted digits as decimal digits) | ||
@@ -22,0 +22,0 @@ * Built-in value range validation |
@@ -1,3 +0,1 @@ | ||
import { Ref } from 'vue-demi' | ||
export interface DistractionFreeOptions { | ||
@@ -22,13 +20,7 @@ hideCurrencySymbol?: boolean, | ||
valueRange?: NumberRange, | ||
allowNegative?: boolean | ||
allowNegative?: boolean, | ||
useGrouping?: boolean | ||
} | ||
export interface ComposableOptions { | ||
inputRef: Ref, | ||
props: any, | ||
emit (event: string, value: number | null): void | ||
} | ||
declare const useCurrencyInput: ({ emit, inputRef, props }: ComposableOptions) => { | ||
declare const useCurrencyInput: (options: CurrencyInputOptions) => { | ||
formattedValue: string | ||
@@ -35,0 +27,0 @@ } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
44494
22
902
0
+ Addedvue-demi@0.5.4(transitive)
- Removedvue-demi@0.4.5(transitive)
Updatedvue-demi@^0.5.3