Socket
Socket
Sign inDemoInstall

vue-currency-input

Package Overview
Dependencies
23
Maintainers
1
Versions
89
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.22.3 to 2.0.0-beta.0

871

dist/vue-currency-input.esm.js
/**
* Vue Currency Input 1.22.3
* Vue Currency Input 2.0.0-beta.0
* (c) 2018-2020 Matthias Stiller
* @license MIT
*/
var escapeRegExp = function (str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); };
var removeLeadingZeros = function (str) { return str.replace(/^0+(0$|[^0])/, '$1'); };
var count = function (str, search) { return (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length; };
var startsWith = function (str, search) { return str.substring(0, search.length) === search; };
var substringBefore = function (str, search) { return str.substring(0, str.indexOf(search)); };
import { getCurrentInstance, isVue3, ref, computed, onMounted, watch } from 'vue-demi';
var DECIMAL_SYMBOLS = [',', '.', '٫'];
var NumberFormat = function NumberFormat (options) {
var currency = options.currency;
var locale = options.locale;
var precision = options.precision;
var autoDecimalMode = options.autoDecimalMode;
var valueAsInteger = options.valueAsInteger;
var numberFormat = new Intl.NumberFormat(locale, typeof currency === 'string' ? { currency: currency, style: 'currency' } : { minimumFractionDigits: 1 });
var ps = numberFormat.format(123456);
this.locale = locale;
this.currency = currency;
this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(function (i) { return i.toLocaleString(locale); });
this.decimalSymbol = count(ps, this.digits[0]) ? ps.substr(ps.indexOf(this.digits[6]) + 1, 1) : undefined;
this.groupingSymbol = ps.substr(ps.indexOf(this.digits[3]) + 1, 1);
this.minusSymbol = substringBefore(Number(-1).toLocaleString(locale), this.digits[1]);
if (this.decimalSymbol === undefined) {
this.minimumFractionDigits = this.maximumFractionDigits = 0;
} else if (typeof precision === 'number') {
this.minimumFractionDigits = this.maximumFractionDigits = precision;
} else if (typeof precision === 'object' && !autoDecimalMode && !valueAsInteger) {
this.minimumFractionDigits = precision.min || 0;
this.maximumFractionDigits = precision.max !== undefined ? precision.max : 20;
} else if (typeof currency === 'string') {
this.minimumFractionDigits = numberFormat.resolvedOptions().minimumFractionDigits;
this.maximumFractionDigits = numberFormat.resolvedOptions().maximumFractionDigits;
} else {
this.minimumFractionDigits = this.maximumFractionDigits = 2;
}
if (typeof currency === 'string') {
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const removeLeadingZeros = (str) => str.replace(/^0+(0$|[^0])/, '$1');
const count = (str, search) => (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length;
const startsWith = (str, search) => str.substring(0, search.length) === search;
const substringBefore = (str, search) => str.substring(0, str.indexOf(search));
const DECIMAL_SYMBOLS = [',', '.', '٫'];
class NumberFormat {
constructor (options) {
const { currency, locale, precision, autoDecimalDigits } = options;
const numberFormat = new Intl.NumberFormat(locale, { currency, style: 'currency' });
const ps = numberFormat.format(123456);
this.locale = locale;
this.currency = currency;
this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => i.toLocaleString(locale));
this.decimalSymbol = count(ps, this.digits[0]) ? ps.substr(ps.indexOf(this.digits[6]) + 1, 1) : undefined;
this.groupingSymbol = ps.substr(ps.indexOf(this.digits[3]) + 1, 1);
this.minusSymbol = substringBefore(Number(-1).toLocaleString(locale), this.digits[1]);
if (this.decimalSymbol === undefined) {
this.minimumFractionDigits = this.maximumFractionDigits = 0;
} else if (typeof precision === 'number') {
this.minimumFractionDigits = this.maximumFractionDigits = precision;
} else if (typeof precision === 'object' && !autoDecimalDigits) {
this.minimumFractionDigits = precision.min || 0;
this.maximumFractionDigits = precision.max !== undefined ? precision.max : 20;
} else {
this.minimumFractionDigits = numberFormat.resolvedOptions().minimumFractionDigits;
this.maximumFractionDigits = numberFormat.resolvedOptions().maximumFractionDigits;
}
this.prefix = substringBefore(ps, this.digits[1]);
this.negativePrefix = substringBefore(numberFormat.format(-1), this.digits[1]);
this.suffix = ps.substring(ps.lastIndexOf(this.decimalSymbol ? this.digits[0] : this.digits[6]) + 1);
} else {
this.prefix = (currency || {}).prefix || '';
this.negativePrefix = "" + (this.minusSymbol) + (this.prefix);
this.suffix = (currency || {}).suffix || '';
}
};
NumberFormat.prototype.parse = function parse (str, valueAsInteger) {
if ( valueAsInteger === void 0 ) valueAsInteger = false;
if (str) {
var negative = this.isNegative(str);
str = this.normalizeDigits(str);
str = this.stripCurrencySymbol(str);
str = this.stripMinusSymbol(str);
var fraction = this.decimalSymbol ? ("(" + (escapeRegExp(this.decimalSymbol)) + "\\d*)?") : '';
var match = str.match(new RegExp(("^" + (this.integerPattern()) + fraction + "$")));
if (match) {
var number = Number(("" + (negative ? '-' : '') + ((this.onlyDigits(match[1]))) + "." + ((this.onlyDigits(match[3] || '')))));
return valueAsInteger ? Number(number.toFixed(this.maximumFractionDigits).split('.').join('')) : number
parse (str) {
if (str) {
const negative = this.isNegative(str);
str = this.normalizeDigits(str);
str = this.stripCurrencySymbol(str);
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] || ''))}`)
}
}
return null
}
return null
};
NumberFormat.prototype.format = function format (number, options) {
if ( options === void 0 ) options = {
minimumFractionDigits: this.minimumFractionDigits,
maximumFractionDigits: this.maximumFractionDigits
};
if (typeof this.currency === 'string') {
return number.toLocaleString(this.locale, Object.assign({}, {style: 'currency',
currency: this.currency},
options))
} else {
return this.insertCurrencySymbol(Math.abs(number).toLocaleString(this.locale, options), number < 0 || (number === 0 && (1 / number < 0)))
format (number, options = {
minimumFractionDigits: this.minimumFractionDigits,
maximumFractionDigits: this.maximumFractionDigits
}) {
return number.toLocaleString(this.locale, {
style: 'currency',
currency: this.currency,
...options
})
}
};
NumberFormat.prototype.integerPattern = function integerPattern () {
return ("(0|[1-9]\\d{0,2}(" + (escapeRegExp(this.groupingSymbol)) + "?\\d{3})*)")
};
NumberFormat.prototype.toFraction = function toFraction (str) {
return ("" + (this.digits[0]) + (this.decimalSymbol) + ((this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))))
};
NumberFormat.prototype.isFractionIncomplete = function isFractionIncomplete (str) {
return !!this.normalizeDigits(str).match(new RegExp(("^" + (this.integerPattern()) + (escapeRegExp(this.decimalSymbol)) + "$")))
};
NumberFormat.prototype.isNegative = function isNegative (str) {
return startsWith(str, this.negativePrefix) || startsWith(str.replace('-', this.minusSymbol), this.minusSymbol)
};
NumberFormat.prototype.insertCurrencySymbol = function insertCurrencySymbol (str, negative) {
return ("" + (negative ? this.negativePrefix : this.prefix) + str + (this.suffix))
};
NumberFormat.prototype.stripMinusSymbol = function stripMinusSymbol (str) {
return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '')
};
NumberFormat.prototype.stripCurrencySymbol = function stripCurrencySymbol (str) {
return str.replace(this.negativePrefix, '').replace(this.prefix, '').replace(this.suffix, '')
};
NumberFormat.prototype.normalizeDecimalSymbol = function normalizeDecimalSymbol (str, from) {
var this$1 = this;
DECIMAL_SYMBOLS.forEach(function (s) {
str = str.substr(0, from) + str.substr(from).replace(s, this$1.decimalSymbol);
});
return str
};
NumberFormat.prototype.normalizeDigits = function normalizeDigits (str) {
if (this.digits[0] !== '0') {
this.digits.forEach(function (digit, index) {
str = str.replace(new RegExp(digit, 'g'), index);
});
integerPattern () {
return `(0|[1-9]\\d{0,2}(${escapeRegExp(this.groupingSymbol)}?\\d{3})*)`
}
return str
};
NumberFormat.prototype.onlyDigits = function onlyDigits (str) {
return this.normalizeDigits(str).replace(/\D+/g, '')
};
NumberFormat.prototype.onlyLocaleDigits = function onlyLocaleDigits (str) {
return str.replace(new RegExp(("[^" + (this.digits.join('')) + "]*"), 'g'), '')
};
var DEFAULT_OPTIONS = {
locale: undefined,
currency: 'EUR',
valueAsInteger: false,
distractionFree: true,
precision: undefined,
autoDecimalMode: false,
valueRange: undefined,
allowNegative: true
};
var parse = function (formattedValue, options) {
var mergedOptions = Object.assign({}, DEFAULT_OPTIONS, options);
return new NumberFormat(mergedOptions).parse(formattedValue, mergedOptions.valueAsInteger)
};
var getValue = function (ref) { return (ref.$el || ref).$ci.getValue(); };
var setValue = function (ref, value) {
(ref.$el || ref).$ci.setValue(value);
};
var equal = function (a, b) {
if (a === b) {
return true
toFraction (str) {
return `${this.digits[0]}${this.decimalSymbol}${(this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))}`
}
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
return false
isFractionIncomplete (str) {
return !!this.normalizeDigits(str).match(new RegExp(`^${this.integerPattern()}${escapeRegExp(this.decimalSymbol)}$`))
}
var keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false
isNegative (str) {
return startsWith(str, this.negativePrefix) || startsWith(str.replace('-', this.minusSymbol), this.minusSymbol)
}
if (!keys.every(Object.prototype.hasOwnProperty.bind(b))) {
return false
insertCurrencySymbol (str, negative) {
return `${negative ? this.negativePrefix : this.prefix}${str}${this.suffix}`
}
return keys.every(function (key) { return equal(a[key], b[key]); })
};
var DefaultNumberMask = function DefaultNumberMask (numberFormat) {
this.numberFormat = numberFormat;
};
DefaultNumberMask.prototype.conformToMask = function conformToMask (str, previousConformedValue) {
var this$1 = this;
if ( previousConformedValue === void 0 ) previousConformedValue = '';
var negative = this.numberFormat.isNegative(str);
var checkIncompleteValue = function (str) {
if (str === '' && negative && previousConformedValue !== this$1.numberFormat.negativePrefix) {
return ''
} else if (this$1.numberFormat.maximumFractionDigits > 0) {
if (this$1.numberFormat.isFractionIncomplete(str)) {
return str
} else if (startsWith(str, this$1.numberFormat.decimalSymbol)) {
return this$1.numberFormat.toFraction(str)
}
}
return null
};
var value = str;
value = this.numberFormat.stripCurrencySymbol(value);
value = this.numberFormat.stripMinusSymbol(value);
var incompleteValue = checkIncompleteValue(value);
if (incompleteValue != null) {
return this.numberFormat.insertCurrencySymbol(incompleteValue, negative)
stripMinusSymbol (str) {
return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '')
}
var ref = value.split(this.numberFormat.decimalSymbol);
var integer = ref[0];
var fraction = ref.slice(1);
var integerDigits = removeLeadingZeros(this.numberFormat.onlyDigits(integer));
var fractionDigits = this.numberFormat.onlyDigits(fraction.join('')).substr(0, this.numberFormat.maximumFractionDigits);
var invalidFraction = fraction.length > 0 && fractionDigits.length === 0;
var invalidNegativeValue = integerDigits === '' && negative && (previousConformedValue === str.slice(0, -1) || previousConformedValue !== this.numberFormat.negativePrefix);
if (invalidFraction || invalidNegativeValue) {
return previousConformedValue
} else if (integerDigits.match(/\d+/)) {
return {
numberValue: Number(("" + (negative ? '-' : '') + integerDigits + "." + fractionDigits)),
fractionDigits: fractionDigits
stripCurrencySymbol (str) {
return str.replace(this.negativePrefix, '').replace(this.prefix, '').replace(this.suffix, '')
}
normalizeDecimalSymbol (str, from) {
DECIMAL_SYMBOLS.forEach((s) => {
str = str.substr(0, from) + str.substr(from).replace(s, this.decimalSymbol);
});
return str
}
normalizeDigits (str) {
if (this.digits[0] !== '0') {
this.digits.forEach((digit, index) => {
str = str.replace(new RegExp(digit, 'g'), index);
});
}
} else {
return ''
return str
}
};
var AutoDecimalModeNumberMask = function AutoDecimalModeNumberMask (numberFormat) {
this.numberFormat = numberFormat;
};
AutoDecimalModeNumberMask.prototype.conformToMask = function conformToMask (str) {
if (str === '') {
return ''
onlyDigits (str) {
return this.normalizeDigits(str).replace(/\D+/g, '')
}
var negative = this.numberFormat.isNegative(str);
var numberValue = this.numberFormat.stripMinusSymbol(str) === ''
? -0
: Number(("" + (negative ? '-' : '') + (removeLeadingZeros(this.numberFormat.onlyDigits(str))))) / Math.pow(10, this.numberFormat.minimumFractionDigits);
return {
numberValue: numberValue,
fractionDigits: numberValue.toFixed(this.numberFormat.minimumFractionDigits).slice(-this.numberFormat.minimumFractionDigits)
onlyLocaleDigits (str) {
return str.replace(new RegExp(`[^${this.digits.join('')}]*`, 'g'), '')
}
};
}
var getCaretPositionAfterFormat = function (newValue, inputtedValue, caretPosition, numberFormat, options) {
var prefix = numberFormat.prefix;
var suffix = numberFormat.suffix;
var decimalSymbol = numberFormat.decimalSymbol;
var maximumFractionDigits = numberFormat.maximumFractionDigits;
var groupingSymbol = numberFormat.groupingSymbol;
var decimalSymbolPosition = inputtedValue.indexOf(decimalSymbol) + 1;
var caretPositionFromLeft = inputtedValue.length - caretPosition;
if (Math.abs(newValue.length - inputtedValue.length) > 1 && caretPosition <= decimalSymbolPosition) {
return newValue.indexOf(decimalSymbol) + 1
} else if (newValue.substr(caretPosition, 1) === groupingSymbol && count(newValue, groupingSymbol) === count(inputtedValue, groupingSymbol) + 1) {
return newValue.length - caretPositionFromLeft - 1
} else {
if (!options.autoDecimalMode && decimalSymbolPosition !== 0 && caretPosition > decimalSymbolPosition) {
if (numberFormat.onlyDigits(inputtedValue.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) {
caretPositionFromLeft -= 1;
class DefaultNumberMask {
constructor (numberFormat) {
this.numberFormat = numberFormat;
}
conformToMask (str, previousConformedValue = '') {
const negative = this.numberFormat.isNegative(str);
const checkIncompleteValue = (str) => {
if (str === '' && negative && previousConformedValue !== this.numberFormat.negativePrefix) {
return ''
} else if (this.numberFormat.maximumFractionDigits > 0) {
if (this.numberFormat.isFractionIncomplete(str)) {
return str
} else if (startsWith(str, this.numberFormat.decimalSymbol)) {
return this.numberFormat.toFraction(str)
}
}
return null
};
let value = str;
value = this.numberFormat.stripCurrencySymbol(value);
value = this.numberFormat.stripMinusSymbol(value);
const incompleteValue = checkIncompleteValue(value);
if (incompleteValue != null) {
return this.numberFormat.insertCurrencySymbol(incompleteValue, negative)
}
return options.distractionFree.hideCurrencySymbol
? newValue.length - caretPositionFromLeft
: Math.max(newValue.length - Math.max(caretPositionFromLeft, suffix.length), prefix.length === 0 ? 0 : prefix.length + 1)
const [integer, ...fraction] = value.split(this.numberFormat.decimalSymbol);
const integerDigits = removeLeadingZeros(this.numberFormat.onlyDigits(integer));
const fractionDigits = this.numberFormat.onlyDigits(fraction.join('')).substr(0, this.numberFormat.maximumFractionDigits);
const invalidFraction = fraction.length > 0 && fractionDigits.length === 0;
const invalidNegativeValue = integerDigits === '' && negative && (previousConformedValue === str.slice(0, -1) || previousConformedValue !== this.numberFormat.negativePrefix);
if (invalidFraction || invalidNegativeValue) {
return previousConformedValue
} else if (integerDigits.match(/\d+/)) {
return {
numberValue: Number(`${negative ? '-' : ''}${integerDigits}.${fractionDigits}`),
fractionDigits
}
} else {
return ''
}
}
};
var getDistractionFreeCaretPosition = function (numberFormat, options, value, caretPosition) {
var result = caretPosition;
if (options.distractionFree.hideCurrencySymbol) {
result -= numberFormat.prefix.length;
}
class AutoDecimalDigitsNumberMask {
constructor (numberFormat) {
this.numberFormat = numberFormat;
}
if (options.distractionFree.hideGroupingSymbol) {
result -= count(value.substring(0, caretPosition), numberFormat.groupingSymbol);
conformToMask (str) {
if (str === '') {
return ''
}
const negative = this.numberFormat.isNegative(str);
const numberValue = this.numberFormat.stripMinusSymbol(str) === ''
? -0
: Number(`${negative ? '-' : ''}${removeLeadingZeros(this.numberFormat.onlyDigits(str))}`) / Math.pow(10, this.numberFormat.minimumFractionDigits);
return {
numberValue,
fractionDigits: numberValue.toFixed(this.numberFormat.minimumFractionDigits).slice(-this.numberFormat.minimumFractionDigits)
}
}
return Math.max(0, result)
};
}
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var NumberInput = function NumberInput (el, options, callbackFns) {
this.el = el;
this.callbackFns = callbackFns;
this.numberValue = null;
this.addEventListener();
this.init(options);
this.setValue(this.currencyFormat.parse(this.el.value));
const MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
const DEFAULT_OPTIONS = {
locale: undefined,
currency: undefined,
valueAsInteger: false,
distractionFree: true,
precision: undefined,
autoDecimalDigits: false,
valueRange: undefined,
allowNegative: true
};
NumberInput.prototype.init = function init (newOptions) {
var options = Object.assign({}, newOptions);
var distractionFree = options.distractionFree;
var autoDecimalMode = options.autoDecimalMode;
var valueRange = options.valueRange;
if (typeof distractionFree === 'boolean') {
options.distractionFree = {
hideCurrencySymbol: distractionFree,
hideNegligibleDecimalDigits: distractionFree,
hideGroupingSymbol: distractionFree
};
class NumberInput {
constructor (el, options, callbackFns) {
this.el = el;
this.callbackFns = callbackFns;
this.numberValue = null;
this.addEventListener();
this.init(options);
this.setValue(this.currencyFormat.parse(this.el.value));
}
if (valueRange) {
options.valueRange = {
min: valueRange.min !== undefined ? Math.max(valueRange.min, -MAX_SAFE_INTEGER) : -MAX_SAFE_INTEGER,
max: valueRange.max !== undefined ? Math.min(valueRange.max, MAX_SAFE_INTEGER) : MAX_SAFE_INTEGER
};
} else {
options.valueRange = {
min: -MAX_SAFE_INTEGER,
max: MAX_SAFE_INTEGER
};
init (options) {
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative } = { ...DEFAULT_OPTIONS, ...options };
this.autoDecimalDigits = autoDecimalDigits;
this.valueAsInteger = valueAsInteger;
this.allowNegative = allowNegative;
this.hideCurrencySymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideCurrencySymbol;
this.hideNegligibleDecimalDigitsOnFocus = distractionFree === true || !!(distractionFree || {}).hideNegligibleDecimalDigits;
this.hideGroupingSymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideGroupingSymbol;
if (valueRange) {
this.valueRange = {
min: valueRange.min !== undefined ? Math.max(valueRange.min, -MAX_SAFE_INTEGER) : -MAX_SAFE_INTEGER,
max: valueRange.max !== undefined ? Math.min(valueRange.max, MAX_SAFE_INTEGER) : MAX_SAFE_INTEGER
};
} else {
this.valueRange = {
min: -MAX_SAFE_INTEGER,
max: MAX_SAFE_INTEGER
};
}
if (autoDecimalDigits) {
this.hideNegligibleDecimalDigitsOnFocus = false;
this.el.setAttribute('inputmode', 'numeric');
} else {
this.el.setAttribute('inputmode', 'decimal');
}
this.currencyFormat = new NumberFormat(options);
this.numberMask = autoDecimalDigits ? new AutoDecimalDigitsNumberMask(this.currencyFormat) : new DefaultNumberMask(this.currencyFormat);
}
if (autoDecimalMode) {
options.distractionFree.hideNegligibleDecimalDigits = false;
this.el.setAttribute('inputmode', 'numeric');
} else {
this.el.setAttribute('inputmode', 'decimal');
setOptions (options) {
this.init(options);
this.applyFixedFractionFormat(this.numberValue, true);
}
this.options = options;
this.currencyFormat = new NumberFormat(this.options);
this.numberMask = options.autoDecimalMode ? new AutoDecimalModeNumberMask(this.currencyFormat) : new DefaultNumberMask(this.currencyFormat);
};
NumberInput.prototype.setOptions = function setOptions (options) {
this.init(options);
this.applyFixedFractionFormat(this.numberValue, true);
};
NumberInput.prototype.applyFixedFractionFormat = function applyFixedFractionFormat (number, forcedChange) {
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null);
if (number !== this.numberValue || forcedChange) {
this.callbackFns.onChange(this.getValue());
applyFixedFractionFormat (number, forcedChange) {
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null);
if (number !== this.numberValue || forcedChange) {
this.callbackFns.onChange(this.getValue());
}
}
};
NumberInput.prototype.getValue = function getValue () {
return this.currencyFormat.parse(this.formattedValue, this.options.valueAsInteger)
};
NumberInput.prototype.setValue = function setValue (value) {
var newValue = this.options.valueAsInteger && value != null ? value / Math.pow(10, this.currencyFormat.maximumFractionDigits) : value;
if (newValue !== this.numberValue) {
this.applyFixedFractionFormat(newValue);
getValue () {
const numberValue = this.valueAsInteger && this.numberValue != null ? Number(this.numberValue.toFixed(this.currencyFormat.maximumFractionDigits).split('.').join('')) : this.numberValue;
return {
number: numberValue,
formatted: this.formattedValue
}
}
};
NumberInput.prototype.validateValueRange = function validateValueRange (value) {
var ref = this.options.valueRange;
var min = ref.min;
var max = ref.max;
return Math.min(Math.max(value, min), max)
};
NumberInput.prototype.updateInputValue = function updateInputValue (value, hideNegligibleDecimalDigits) {
if ( hideNegligibleDecimalDigits === void 0 ) hideNegligibleDecimalDigits = false;
if (value != null) {
if (this.decimalSymbolInsertedAt !== undefined) {
value = this.currencyFormat.normalizeDecimalSymbol(value, this.decimalSymbolInsertedAt);
this.decimalSymbolInsertedAt = undefined;
setValue (value) {
const newValue = this.valueAsInteger && value != null ? value / Math.pow(10, this.currencyFormat.maximumFractionDigits) : value;
if (newValue !== this.numberValue) {
this.applyFixedFractionFormat(newValue);
}
var conformedValue = this.numberMask.conformToMask(value, this.formattedValue);
var formattedValue;
if (typeof conformedValue === 'object') {
var numberValue = conformedValue.numberValue;
var fractionDigits = conformedValue.fractionDigits;
var ref = this.currencyFormat;
var maximumFractionDigits = ref.maximumFractionDigits;
var minimumFractionDigits = ref.minimumFractionDigits;
if (this.focus) {
minimumFractionDigits = maximumFractionDigits;
}
validateValueRange (value) {
const { min, max } = this.valueRange;
return Math.min(Math.max(value, min), max)
}
format (value, hideNegligibleDecimalDigits = false) {
if (value != null) {
if (this.decimalSymbolInsertedAt !== undefined) {
value = this.currencyFormat.normalizeDecimalSymbol(value, this.decimalSymbolInsertedAt);
this.decimalSymbolInsertedAt = undefined;
}
minimumFractionDigits = hideNegligibleDecimalDigits
? fractionDigits.replace(/0+$/, '').length
: Math.min(minimumFractionDigits, fractionDigits.length);
formattedValue = numberValue > MAX_SAFE_INTEGER
? this.formattedValue
: this.currencyFormat.format(numberValue, {
useGrouping: !(this.focus && this.options.distractionFree.hideGroupingSymbol),
minimumFractionDigits: minimumFractionDigits,
maximumFractionDigits: maximumFractionDigits
});
const conformedValue = this.numberMask.conformToMask(value, this.formattedValue);
let formattedValue;
if (typeof conformedValue === 'object') {
const { numberValue, fractionDigits } = conformedValue;
let { maximumFractionDigits, minimumFractionDigits } = this.currencyFormat;
if (this.focus) {
minimumFractionDigits = maximumFractionDigits;
}
minimumFractionDigits = hideNegligibleDecimalDigits
? fractionDigits.replace(/0+$/, '').length
: Math.min(minimumFractionDigits, fractionDigits.length);
formattedValue = numberValue > MAX_SAFE_INTEGER
? this.formattedValue
: this.currencyFormat.format(numberValue, {
useGrouping: !(this.focus && this.hideGroupingSymbolOnFocus),
minimumFractionDigits,
maximumFractionDigits
});
} else {
formattedValue = conformedValue;
}
if (!this.allowNegative) {
formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);
}
if (this.focus && this.hideCurrencySymbolOnFocus) {
formattedValue = formattedValue
.replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSymbol)
.replace(this.currencyFormat.prefix, '')
.replace(this.currencyFormat.suffix, '');
}
this.el.value = formattedValue;
this.numberValue = this.currencyFormat.parse(formattedValue);
} else {
formattedValue = conformedValue;
this.el.value = this.numberValue = null;
}
if (!this.options.allowNegative) {
formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);
}
if (this.focus && this.options.distractionFree.hideCurrencySymbol) {
formattedValue = formattedValue
.replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSymbol)
.replace(this.currencyFormat.prefix, '')
.replace(this.currencyFormat.suffix, '');
}
this.el.value = formattedValue;
this.numberValue = this.currencyFormat.parse(formattedValue);
} else {
this.el.value = this.numberValue = null;
this.formattedValue = this.el.value;
this.callbackFns.onInput(this.getValue());
}
this.formattedValue = this.el.value;
};
NumberInput.prototype.format = function format (value) {
this.updateInputValue(value);
this.callbackFns.onInput(this.getValue());
};
NumberInput.prototype.addEventListener = function addEventListener () {
var this$1 = this;
this.el.addEventListener('input', function () {
var ref = this$1.el;
var value = ref.value;
var selectionStart = ref.selectionStart;
this$1.format(value);
if (this$1.focus) {
this$1.setCaretPosition(getCaretPositionAfterFormat(this$1.formattedValue, value, selectionStart, this$1.currencyFormat, this$1.options));
}
}, { capture: true });
this.el.addEventListener('focus', function () {
this$1.focus = true;
var ref = this$1.options.distractionFree;
var hideCurrencySymbol = ref.hideCurrencySymbol;
var hideGroupingSymbol = ref.hideGroupingSymbol;
var hideNegligibleDecimalDigits = ref.hideNegligibleDecimalDigits;
if (hideCurrencySymbol || hideGroupingSymbol || hideNegligibleDecimalDigits) {
setTimeout(function () {
var ref = this$1.el;
var value = ref.value;
var selectionStart = ref.selectionStart;
var selectionEnd = ref.selectionEnd;
if (value) {
this$1.updateInputValue(this$1.el.value, hideNegligibleDecimalDigits);
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;
}
}
}
}
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length)
};
this.setCaretPosition(getCaretPositionAfterFormat());
}
}, { capture: true });
this.el.addEventListener('focus', () => {
this.focus = true;
setTimeout(() => {
const { value, selectionStart, selectionEnd } = this.el;
if ((this.hideCurrencySymbolOnFocus || this.hideGroupingSymbolOnFocus || this.hideNegligibleDecimalDigitsOnFocus) && value) {
this.format(value, this.hideNegligibleDecimalDigitsOnFocus);
}
if (Math.abs(selectionStart - selectionEnd) > 0) {
this$1.setCaretPosition(0, this$1.el.value.length);
this.setCaretPosition(0, this.el.value.length);
} else {
this$1.setCaretPosition(getDistractionFreeCaretPosition(this$1.currencyFormat, this$1.options, value, selectionStart));
const getSelectionStart = () => {
const { prefix, suffix, groupingSymbol } = this.currencyFormat;
if (!this.hideCurrencySymbolOnFocus) {
if (selectionStart > value.length - suffix.length) {
return this.formattedValue.length - suffix.length
} else if (selectionStart < prefix.length) {
return prefix.length
}
}
let result = selectionStart;
if (this.hideCurrencySymbolOnFocus) {
result -= prefix.length;
}
if (this.hideGroupingSymbolOnFocus) {
result -= count(value.substring(0, selectionStart), groupingSymbol);
}
return result
};
this.setCaretPosition(getSelectionStart());
}
});
}
});
this.el.addEventListener('keypress', function (e) {
if (DECIMAL_SYMBOLS.includes(e.key)) {
this$1.decimalSymbolInsertedAt = this$1.el.selectionStart;
}
});
this.el.addEventListener('blur', function () {
this$1.focus = false;
if (this$1.numberValue != null) {
this$1.applyFixedFractionFormat(this$1.numberValue);
}
});
this.el.addEventListener('change', function () {
this$1.callbackFns.onChange(this$1.getValue());
});
};
NumberInput.prototype.setCaretPosition = function setCaretPosition (start, end) {
if ( end === void 0 ) end = start;
this.el.setSelectionRange(start, end); };
var directive = {
bind: function bind (el, ref, vnode) {
var optionsFromBinding = ref.value;
var inputElement = el.tagName.toLowerCase() === 'input' ? el : el.querySelector('input');
if (!inputElement) {
throw new Error('No input element found')
}
var options = Object.assign({}, DEFAULT_OPTIONS,
(vnode.context.$ci || {}).globalOptions,
optionsFromBinding);
var listeners = (vnode.data && vnode.data.on) || (vnode.componentOptions && vnode.componentOptions.listeners) || {};
var emit = function (event, data) {
if (listeners[event]) {
listeners[event](vnode.componentOptions ? data : { target: { value: data } });
});
this.el.addEventListener('keypress', (e) => {
if (DECIMAL_SYMBOLS.includes(e.key)) {
this.decimalSymbolInsertedAt = this.el.selectionStart;
}
};
el.$ci = new NumberInput(inputElement, options, {
onChange: function () { emit('change', inputElement.value); },
onInput: function () { emit('input', inputElement.value); }
});
},
componentUpdated: function componentUpdated (el, ref) {
var value = ref.value;
var oldValue = ref.oldValue;
if (!equal(value, oldValue)) {
el.$ci.setOptions(value);
}
this.el.addEventListener('blur', () => {
this.focus = false;
if (this.numberValue != null) {
this.applyFixedFractionFormat(this.numberValue);
}
});
this.el.addEventListener('change', () => {
this.callbackFns.onChange(this.getValue());
});
}
};
setCaretPosition (start, end = start) { this.el.setSelectionRange(start, end); }
}
var component = {
render: function render (h) {
var this$1 = this;
return h('input', {
directives: [{
name: 'currency',
value: this.options
}],
on: Object.assign({}, this.$listeners,
{change: function () {
this$1.$emit('change', getValue(this$1.$el));
},
input: function () {
var numberValue = getValue(this$1.$el);
if (this$1.value !== numberValue) {
this$1.$emit('input', numberValue);
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;
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];
}
return options
}, {}));
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;
}
}})
})
},
directives: {
currency: directive
},
name: 'CurrencyInput',
props: {
value: {
type: Number,
default: null
},
locale: {
type: String,
default: undefined
},
currency: {
type: [String, Object],
default: undefined
},
distractionFree: {
type: [Boolean, Object],
default: undefined
},
precision: {
type: [Number, Object],
default: undefined
},
autoDecimalMode: {
type: Boolean,
default: undefined
},
valueAsInteger: {
type: Boolean,
default: undefined
},
valueRange: {
type: Object,
default: undefined
},
allowNegative: {
type: Boolean,
default: undefined
});
numberInput.setValue(numberValue.value);
}
}
},
mounted: function mounted () {
this.setValue(this.value);
},
computed: {
options: function options () {
var this$1 = this;
var options = Object.assign({}, DEFAULT_OPTIONS,
(this.$ci || {}).globalOptions);
Object.keys(DEFAULT_OPTIONS).forEach(function (key) {
if (this$1[key] !== undefined) {
options[key] = this$1[key];
}
});
return options
}
},
watch: {
value: 'setValue'
},
methods: {
setValue: function setValue$1 (value) {
setValue(this.$el, value);
}
}
});
watch(numberValue, (value) => {
numberInput.setValue(value);
});
watch(options, (options) => {
numberInput.setOptions(options);
});
return { formattedValue }
};
var plugin = {
install: function install (Vue, ref) {
if ( ref === void 0 ) ref = {};
var componentName = ref.componentName; if ( componentName === void 0 ) componentName = component.name;
var directiveName = ref.directiveName; if ( directiveName === void 0 ) directiveName = 'currency';
var globalOptions = ref.globalOptions; if ( globalOptions === void 0 ) globalOptions = {};
Vue.component(componentName, component);
Vue.directive(directiveName, directive);
Vue.prototype.$ci = {
parse: function (formattedValue, options) { return parse(formattedValue, Object.assign({}, globalOptions, options)); },
getValue: getValue,
setValue: setValue,
globalOptions: globalOptions
};
}
};
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(plugin);
}
export default plugin;
export { directive as CurrencyDirective, component as CurrencyInput, getValue, parse, setValue };
export default useCurrencyInput;
/**
* Vue Currency Input 1.22.3
* Vue Currency Input 2.0.0-beta.0
* (c) 2018-2020 Matthias Stiller

@@ -7,573 +7,416 @@ * @license MIT

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VueCurrencyInput = {}));
}(this, (function (exports) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue-demi')) :
typeof define === 'function' && define.amd ? define(['exports', 'vue-demi'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VueCurrencyInput = {}, global.VueDemi));
}(this, (function (exports, vueDemi) { 'use strict';
var escapeRegExp = function (str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); };
var removeLeadingZeros = function (str) { return str.replace(/^0+(0$|[^0])/, '$1'); };
var count = function (str, search) { return (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length; };
var startsWith = function (str, search) { return str.substring(0, search.length) === search; };
var substringBefore = function (str, search) { return str.substring(0, str.indexOf(search)); };
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const removeLeadingZeros = (str) => str.replace(/^0+(0$|[^0])/, '$1');
const count = (str, search) => (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length;
const startsWith = (str, search) => str.substring(0, search.length) === search;
const substringBefore = (str, search) => str.substring(0, str.indexOf(search));
var DECIMAL_SYMBOLS = [',', '.', '٫'];
var NumberFormat = function NumberFormat (options) {
var currency = options.currency;
var locale = options.locale;
var precision = options.precision;
var autoDecimalMode = options.autoDecimalMode;
var valueAsInteger = options.valueAsInteger;
var numberFormat = new Intl.NumberFormat(locale, typeof currency === 'string' ? { currency: currency, style: 'currency' } : { minimumFractionDigits: 1 });
var ps = numberFormat.format(123456);
this.locale = locale;
this.currency = currency;
this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(function (i) { return i.toLocaleString(locale); });
this.decimalSymbol = count(ps, this.digits[0]) ? ps.substr(ps.indexOf(this.digits[6]) + 1, 1) : undefined;
this.groupingSymbol = ps.substr(ps.indexOf(this.digits[3]) + 1, 1);
this.minusSymbol = substringBefore(Number(-1).toLocaleString(locale), this.digits[1]);
if (this.decimalSymbol === undefined) {
this.minimumFractionDigits = this.maximumFractionDigits = 0;
} else if (typeof precision === 'number') {
this.minimumFractionDigits = this.maximumFractionDigits = precision;
} else if (typeof precision === 'object' && !autoDecimalMode && !valueAsInteger) {
this.minimumFractionDigits = precision.min || 0;
this.maximumFractionDigits = precision.max !== undefined ? precision.max : 20;
} else if (typeof currency === 'string') {
this.minimumFractionDigits = numberFormat.resolvedOptions().minimumFractionDigits;
this.maximumFractionDigits = numberFormat.resolvedOptions().maximumFractionDigits;
} else {
this.minimumFractionDigits = this.maximumFractionDigits = 2;
}
if (typeof currency === 'string') {
const DECIMAL_SYMBOLS = [',', '.', '٫'];
class NumberFormat {
constructor (options) {
const { currency, locale, precision, autoDecimalDigits } = options;
const numberFormat = new Intl.NumberFormat(locale, { currency, style: 'currency' });
const ps = numberFormat.format(123456);
this.locale = locale;
this.currency = currency;
this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => i.toLocaleString(locale));
this.decimalSymbol = count(ps, this.digits[0]) ? ps.substr(ps.indexOf(this.digits[6]) + 1, 1) : undefined;
this.groupingSymbol = ps.substr(ps.indexOf(this.digits[3]) + 1, 1);
this.minusSymbol = substringBefore(Number(-1).toLocaleString(locale), this.digits[1]);
if (this.decimalSymbol === undefined) {
this.minimumFractionDigits = this.maximumFractionDigits = 0;
} else if (typeof precision === 'number') {
this.minimumFractionDigits = this.maximumFractionDigits = precision;
} else if (typeof precision === 'object' && !autoDecimalDigits) {
this.minimumFractionDigits = precision.min || 0;
this.maximumFractionDigits = precision.max !== undefined ? precision.max : 20;
} else {
this.minimumFractionDigits = numberFormat.resolvedOptions().minimumFractionDigits;
this.maximumFractionDigits = numberFormat.resolvedOptions().maximumFractionDigits;
}
this.prefix = substringBefore(ps, this.digits[1]);
this.negativePrefix = substringBefore(numberFormat.format(-1), this.digits[1]);
this.suffix = ps.substring(ps.lastIndexOf(this.decimalSymbol ? this.digits[0] : this.digits[6]) + 1);
} else {
this.prefix = (currency || {}).prefix || '';
this.negativePrefix = "" + (this.minusSymbol) + (this.prefix);
this.suffix = (currency || {}).suffix || '';
}
};
NumberFormat.prototype.parse = function parse (str, valueAsInteger) {
if ( valueAsInteger === void 0 ) valueAsInteger = false;
if (str) {
var negative = this.isNegative(str);
str = this.normalizeDigits(str);
str = this.stripCurrencySymbol(str);
str = this.stripMinusSymbol(str);
var fraction = this.decimalSymbol ? ("(" + (escapeRegExp(this.decimalSymbol)) + "\\d*)?") : '';
var match = str.match(new RegExp(("^" + (this.integerPattern()) + fraction + "$")));
if (match) {
var number = Number(("" + (negative ? '-' : '') + ((this.onlyDigits(match[1]))) + "." + ((this.onlyDigits(match[3] || '')))));
return valueAsInteger ? Number(number.toFixed(this.maximumFractionDigits).split('.').join('')) : number
parse (str) {
if (str) {
const negative = this.isNegative(str);
str = this.normalizeDigits(str);
str = this.stripCurrencySymbol(str);
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] || ''))}`)
}
}
return null
}
return null
};
NumberFormat.prototype.format = function format (number, options) {
if ( options === void 0 ) options = {
minimumFractionDigits: this.minimumFractionDigits,
maximumFractionDigits: this.maximumFractionDigits
};
if (typeof this.currency === 'string') {
return number.toLocaleString(this.locale, Object.assign({}, {style: 'currency',
currency: this.currency},
options))
} else {
return this.insertCurrencySymbol(Math.abs(number).toLocaleString(this.locale, options), number < 0 || (number === 0 && (1 / number < 0)))
format (number, options = {
minimumFractionDigits: this.minimumFractionDigits,
maximumFractionDigits: this.maximumFractionDigits
}) {
return number.toLocaleString(this.locale, {
style: 'currency',
currency: this.currency,
...options
})
}
};
NumberFormat.prototype.integerPattern = function integerPattern () {
return ("(0|[1-9]\\d{0,2}(" + (escapeRegExp(this.groupingSymbol)) + "?\\d{3})*)")
};
NumberFormat.prototype.toFraction = function toFraction (str) {
return ("" + (this.digits[0]) + (this.decimalSymbol) + ((this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))))
};
NumberFormat.prototype.isFractionIncomplete = function isFractionIncomplete (str) {
return !!this.normalizeDigits(str).match(new RegExp(("^" + (this.integerPattern()) + (escapeRegExp(this.decimalSymbol)) + "$")))
};
NumberFormat.prototype.isNegative = function isNegative (str) {
return startsWith(str, this.negativePrefix) || startsWith(str.replace('-', this.minusSymbol), this.minusSymbol)
};
NumberFormat.prototype.insertCurrencySymbol = function insertCurrencySymbol (str, negative) {
return ("" + (negative ? this.negativePrefix : this.prefix) + str + (this.suffix))
};
NumberFormat.prototype.stripMinusSymbol = function stripMinusSymbol (str) {
return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '')
};
NumberFormat.prototype.stripCurrencySymbol = function stripCurrencySymbol (str) {
return str.replace(this.negativePrefix, '').replace(this.prefix, '').replace(this.suffix, '')
};
NumberFormat.prototype.normalizeDecimalSymbol = function normalizeDecimalSymbol (str, from) {
var this$1 = this;
DECIMAL_SYMBOLS.forEach(function (s) {
str = str.substr(0, from) + str.substr(from).replace(s, this$1.decimalSymbol);
});
return str
};
NumberFormat.prototype.normalizeDigits = function normalizeDigits (str) {
if (this.digits[0] !== '0') {
this.digits.forEach(function (digit, index) {
str = str.replace(new RegExp(digit, 'g'), index);
});
integerPattern () {
return `(0|[1-9]\\d{0,2}(${escapeRegExp(this.groupingSymbol)}?\\d{3})*)`
}
return str
};
NumberFormat.prototype.onlyDigits = function onlyDigits (str) {
return this.normalizeDigits(str).replace(/\D+/g, '')
};
NumberFormat.prototype.onlyLocaleDigits = function onlyLocaleDigits (str) {
return str.replace(new RegExp(("[^" + (this.digits.join('')) + "]*"), 'g'), '')
};
var DEFAULT_OPTIONS = {
locale: undefined,
currency: 'EUR',
valueAsInteger: false,
distractionFree: true,
precision: undefined,
autoDecimalMode: false,
valueRange: undefined,
allowNegative: true
};
var parse = function (formattedValue, options) {
var mergedOptions = Object.assign({}, DEFAULT_OPTIONS, options);
return new NumberFormat(mergedOptions).parse(formattedValue, mergedOptions.valueAsInteger)
};
var getValue = function (ref) { return (ref.$el || ref).$ci.getValue(); };
var setValue = function (ref, value) {
(ref.$el || ref).$ci.setValue(value);
};
var equal = function (a, b) {
if (a === b) {
return true
toFraction (str) {
return `${this.digits[0]}${this.decimalSymbol}${(this.onlyLocaleDigits(str.substr(1)).substr(0, this.maximumFractionDigits))}`
}
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
return false
isFractionIncomplete (str) {
return !!this.normalizeDigits(str).match(new RegExp(`^${this.integerPattern()}${escapeRegExp(this.decimalSymbol)}$`))
}
var keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false
isNegative (str) {
return startsWith(str, this.negativePrefix) || startsWith(str.replace('-', this.minusSymbol), this.minusSymbol)
}
if (!keys.every(Object.prototype.hasOwnProperty.bind(b))) {
return false
insertCurrencySymbol (str, negative) {
return `${negative ? this.negativePrefix : this.prefix}${str}${this.suffix}`
}
return keys.every(function (key) { return equal(a[key], b[key]); })
};
var DefaultNumberMask = function DefaultNumberMask (numberFormat) {
this.numberFormat = numberFormat;
};
DefaultNumberMask.prototype.conformToMask = function conformToMask (str, previousConformedValue) {
var this$1 = this;
if ( previousConformedValue === void 0 ) previousConformedValue = '';
var negative = this.numberFormat.isNegative(str);
var checkIncompleteValue = function (str) {
if (str === '' && negative && previousConformedValue !== this$1.numberFormat.negativePrefix) {
return ''
} else if (this$1.numberFormat.maximumFractionDigits > 0) {
if (this$1.numberFormat.isFractionIncomplete(str)) {
return str
} else if (startsWith(str, this$1.numberFormat.decimalSymbol)) {
return this$1.numberFormat.toFraction(str)
}
}
return null
};
var value = str;
value = this.numberFormat.stripCurrencySymbol(value);
value = this.numberFormat.stripMinusSymbol(value);
var incompleteValue = checkIncompleteValue(value);
if (incompleteValue != null) {
return this.numberFormat.insertCurrencySymbol(incompleteValue, negative)
stripMinusSymbol (str) {
return str.replace('-', this.minusSymbol).replace(this.minusSymbol, '')
}
var ref = value.split(this.numberFormat.decimalSymbol);
var integer = ref[0];
var fraction = ref.slice(1);
var integerDigits = removeLeadingZeros(this.numberFormat.onlyDigits(integer));
var fractionDigits = this.numberFormat.onlyDigits(fraction.join('')).substr(0, this.numberFormat.maximumFractionDigits);
var invalidFraction = fraction.length > 0 && fractionDigits.length === 0;
var invalidNegativeValue = integerDigits === '' && negative && (previousConformedValue === str.slice(0, -1) || previousConformedValue !== this.numberFormat.negativePrefix);
if (invalidFraction || invalidNegativeValue) {
return previousConformedValue
} else if (integerDigits.match(/\d+/)) {
return {
numberValue: Number(("" + (negative ? '-' : '') + integerDigits + "." + fractionDigits)),
fractionDigits: fractionDigits
stripCurrencySymbol (str) {
return str.replace(this.negativePrefix, '').replace(this.prefix, '').replace(this.suffix, '')
}
normalizeDecimalSymbol (str, from) {
DECIMAL_SYMBOLS.forEach((s) => {
str = str.substr(0, from) + str.substr(from).replace(s, this.decimalSymbol);
});
return str
}
normalizeDigits (str) {
if (this.digits[0] !== '0') {
this.digits.forEach((digit, index) => {
str = str.replace(new RegExp(digit, 'g'), index);
});
}
} else {
return ''
return str
}
};
var AutoDecimalModeNumberMask = function AutoDecimalModeNumberMask (numberFormat) {
this.numberFormat = numberFormat;
};
AutoDecimalModeNumberMask.prototype.conformToMask = function conformToMask (str) {
if (str === '') {
return ''
onlyDigits (str) {
return this.normalizeDigits(str).replace(/\D+/g, '')
}
var negative = this.numberFormat.isNegative(str);
var numberValue = this.numberFormat.stripMinusSymbol(str) === ''
? -0
: Number(("" + (negative ? '-' : '') + (removeLeadingZeros(this.numberFormat.onlyDigits(str))))) / Math.pow(10, this.numberFormat.minimumFractionDigits);
return {
numberValue: numberValue,
fractionDigits: numberValue.toFixed(this.numberFormat.minimumFractionDigits).slice(-this.numberFormat.minimumFractionDigits)
onlyLocaleDigits (str) {
return str.replace(new RegExp(`[^${this.digits.join('')}]*`, 'g'), '')
}
};
}
var getCaretPositionAfterFormat = function (newValue, inputtedValue, caretPosition, numberFormat, options) {
var prefix = numberFormat.prefix;
var suffix = numberFormat.suffix;
var decimalSymbol = numberFormat.decimalSymbol;
var maximumFractionDigits = numberFormat.maximumFractionDigits;
var groupingSymbol = numberFormat.groupingSymbol;
var decimalSymbolPosition = inputtedValue.indexOf(decimalSymbol) + 1;
var caretPositionFromLeft = inputtedValue.length - caretPosition;
if (Math.abs(newValue.length - inputtedValue.length) > 1 && caretPosition <= decimalSymbolPosition) {
return newValue.indexOf(decimalSymbol) + 1
} else if (newValue.substr(caretPosition, 1) === groupingSymbol && count(newValue, groupingSymbol) === count(inputtedValue, groupingSymbol) + 1) {
return newValue.length - caretPositionFromLeft - 1
} else {
if (!options.autoDecimalMode && decimalSymbolPosition !== 0 && caretPosition > decimalSymbolPosition) {
if (numberFormat.onlyDigits(inputtedValue.substr(decimalSymbolPosition)).length - 1 === maximumFractionDigits) {
caretPositionFromLeft -= 1;
class DefaultNumberMask {
constructor (numberFormat) {
this.numberFormat = numberFormat;
}
conformToMask (str, previousConformedValue = '') {
const negative = this.numberFormat.isNegative(str);
const checkIncompleteValue = (str) => {
if (str === '' && negative && previousConformedValue !== this.numberFormat.negativePrefix) {
return ''
} else if (this.numberFormat.maximumFractionDigits > 0) {
if (this.numberFormat.isFractionIncomplete(str)) {
return str
} else if (startsWith(str, this.numberFormat.decimalSymbol)) {
return this.numberFormat.toFraction(str)
}
}
return null
};
let value = str;
value = this.numberFormat.stripCurrencySymbol(value);
value = this.numberFormat.stripMinusSymbol(value);
const incompleteValue = checkIncompleteValue(value);
if (incompleteValue != null) {
return this.numberFormat.insertCurrencySymbol(incompleteValue, negative)
}
return options.distractionFree.hideCurrencySymbol
? newValue.length - caretPositionFromLeft
: Math.max(newValue.length - Math.max(caretPositionFromLeft, suffix.length), prefix.length === 0 ? 0 : prefix.length + 1)
const [integer, ...fraction] = value.split(this.numberFormat.decimalSymbol);
const integerDigits = removeLeadingZeros(this.numberFormat.onlyDigits(integer));
const fractionDigits = this.numberFormat.onlyDigits(fraction.join('')).substr(0, this.numberFormat.maximumFractionDigits);
const invalidFraction = fraction.length > 0 && fractionDigits.length === 0;
const invalidNegativeValue = integerDigits === '' && negative && (previousConformedValue === str.slice(0, -1) || previousConformedValue !== this.numberFormat.negativePrefix);
if (invalidFraction || invalidNegativeValue) {
return previousConformedValue
} else if (integerDigits.match(/\d+/)) {
return {
numberValue: Number(`${negative ? '-' : ''}${integerDigits}.${fractionDigits}`),
fractionDigits
}
} else {
return ''
}
}
};
var getDistractionFreeCaretPosition = function (numberFormat, options, value, caretPosition) {
var result = caretPosition;
if (options.distractionFree.hideCurrencySymbol) {
result -= numberFormat.prefix.length;
}
class AutoDecimalDigitsNumberMask {
constructor (numberFormat) {
this.numberFormat = numberFormat;
}
if (options.distractionFree.hideGroupingSymbol) {
result -= count(value.substring(0, caretPosition), numberFormat.groupingSymbol);
conformToMask (str) {
if (str === '') {
return ''
}
const negative = this.numberFormat.isNegative(str);
const numberValue = this.numberFormat.stripMinusSymbol(str) === ''
? -0
: Number(`${negative ? '-' : ''}${removeLeadingZeros(this.numberFormat.onlyDigits(str))}`) / Math.pow(10, this.numberFormat.minimumFractionDigits);
return {
numberValue,
fractionDigits: numberValue.toFixed(this.numberFormat.minimumFractionDigits).slice(-this.numberFormat.minimumFractionDigits)
}
}
return Math.max(0, result)
};
}
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
var NumberInput = function NumberInput (el, options, callbackFns) {
this.el = el;
this.callbackFns = callbackFns;
this.numberValue = null;
this.addEventListener();
this.init(options);
this.setValue(this.currencyFormat.parse(this.el.value));
const MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
const DEFAULT_OPTIONS = {
locale: undefined,
currency: undefined,
valueAsInteger: false,
distractionFree: true,
precision: undefined,
autoDecimalDigits: false,
valueRange: undefined,
allowNegative: true
};
NumberInput.prototype.init = function init (newOptions) {
var options = Object.assign({}, newOptions);
var distractionFree = options.distractionFree;
var autoDecimalMode = options.autoDecimalMode;
var valueRange = options.valueRange;
if (typeof distractionFree === 'boolean') {
options.distractionFree = {
hideCurrencySymbol: distractionFree,
hideNegligibleDecimalDigits: distractionFree,
hideGroupingSymbol: distractionFree
};
class NumberInput {
constructor (el, options, callbackFns) {
this.el = el;
this.callbackFns = callbackFns;
this.numberValue = null;
this.addEventListener();
this.init(options);
this.setValue(this.currencyFormat.parse(this.el.value));
}
if (valueRange) {
options.valueRange = {
min: valueRange.min !== undefined ? Math.max(valueRange.min, -MAX_SAFE_INTEGER) : -MAX_SAFE_INTEGER,
max: valueRange.max !== undefined ? Math.min(valueRange.max, MAX_SAFE_INTEGER) : MAX_SAFE_INTEGER
};
} else {
options.valueRange = {
min: -MAX_SAFE_INTEGER,
max: MAX_SAFE_INTEGER
};
init (options) {
const { distractionFree, autoDecimalDigits, valueRange, valueAsInteger, allowNegative } = { ...DEFAULT_OPTIONS, ...options };
this.autoDecimalDigits = autoDecimalDigits;
this.valueAsInteger = valueAsInteger;
this.allowNegative = allowNegative;
this.hideCurrencySymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideCurrencySymbol;
this.hideNegligibleDecimalDigitsOnFocus = distractionFree === true || !!(distractionFree || {}).hideNegligibleDecimalDigits;
this.hideGroupingSymbolOnFocus = distractionFree === true || !!(distractionFree || {}).hideGroupingSymbol;
if (valueRange) {
this.valueRange = {
min: valueRange.min !== undefined ? Math.max(valueRange.min, -MAX_SAFE_INTEGER) : -MAX_SAFE_INTEGER,
max: valueRange.max !== undefined ? Math.min(valueRange.max, MAX_SAFE_INTEGER) : MAX_SAFE_INTEGER
};
} else {
this.valueRange = {
min: -MAX_SAFE_INTEGER,
max: MAX_SAFE_INTEGER
};
}
if (autoDecimalDigits) {
this.hideNegligibleDecimalDigitsOnFocus = false;
this.el.setAttribute('inputmode', 'numeric');
} else {
this.el.setAttribute('inputmode', 'decimal');
}
this.currencyFormat = new NumberFormat(options);
this.numberMask = autoDecimalDigits ? new AutoDecimalDigitsNumberMask(this.currencyFormat) : new DefaultNumberMask(this.currencyFormat);
}
if (autoDecimalMode) {
options.distractionFree.hideNegligibleDecimalDigits = false;
this.el.setAttribute('inputmode', 'numeric');
} else {
this.el.setAttribute('inputmode', 'decimal');
setOptions (options) {
this.init(options);
this.applyFixedFractionFormat(this.numberValue, true);
}
this.options = options;
this.currencyFormat = new NumberFormat(this.options);
this.numberMask = options.autoDecimalMode ? new AutoDecimalModeNumberMask(this.currencyFormat) : new DefaultNumberMask(this.currencyFormat);
};
NumberInput.prototype.setOptions = function setOptions (options) {
this.init(options);
this.applyFixedFractionFormat(this.numberValue, true);
};
NumberInput.prototype.applyFixedFractionFormat = function applyFixedFractionFormat (number, forcedChange) {
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null);
if (number !== this.numberValue || forcedChange) {
this.callbackFns.onChange(this.getValue());
applyFixedFractionFormat (number, forcedChange) {
this.format(number != null ? this.currencyFormat.format(this.validateValueRange(number)) : null);
if (number !== this.numberValue || forcedChange) {
this.callbackFns.onChange(this.getValue());
}
}
};
NumberInput.prototype.getValue = function getValue () {
return this.currencyFormat.parse(this.formattedValue, this.options.valueAsInteger)
};
NumberInput.prototype.setValue = function setValue (value) {
var newValue = this.options.valueAsInteger && value != null ? value / Math.pow(10, this.currencyFormat.maximumFractionDigits) : value;
if (newValue !== this.numberValue) {
this.applyFixedFractionFormat(newValue);
getValue () {
const numberValue = this.valueAsInteger && this.numberValue != null ? Number(this.numberValue.toFixed(this.currencyFormat.maximumFractionDigits).split('.').join('')) : this.numberValue;
return {
number: numberValue,
formatted: this.formattedValue
}
}
};
NumberInput.prototype.validateValueRange = function validateValueRange (value) {
var ref = this.options.valueRange;
var min = ref.min;
var max = ref.max;
return Math.min(Math.max(value, min), max)
};
NumberInput.prototype.updateInputValue = function updateInputValue (value, hideNegligibleDecimalDigits) {
if ( hideNegligibleDecimalDigits === void 0 ) hideNegligibleDecimalDigits = false;
if (value != null) {
if (this.decimalSymbolInsertedAt !== undefined) {
value = this.currencyFormat.normalizeDecimalSymbol(value, this.decimalSymbolInsertedAt);
this.decimalSymbolInsertedAt = undefined;
setValue (value) {
const newValue = this.valueAsInteger && value != null ? value / Math.pow(10, this.currencyFormat.maximumFractionDigits) : value;
if (newValue !== this.numberValue) {
this.applyFixedFractionFormat(newValue);
}
var conformedValue = this.numberMask.conformToMask(value, this.formattedValue);
var formattedValue;
if (typeof conformedValue === 'object') {
var numberValue = conformedValue.numberValue;
var fractionDigits = conformedValue.fractionDigits;
var ref = this.currencyFormat;
var maximumFractionDigits = ref.maximumFractionDigits;
var minimumFractionDigits = ref.minimumFractionDigits;
if (this.focus) {
minimumFractionDigits = maximumFractionDigits;
}
validateValueRange (value) {
const { min, max } = this.valueRange;
return Math.min(Math.max(value, min), max)
}
format (value, hideNegligibleDecimalDigits = false) {
if (value != null) {
if (this.decimalSymbolInsertedAt !== undefined) {
value = this.currencyFormat.normalizeDecimalSymbol(value, this.decimalSymbolInsertedAt);
this.decimalSymbolInsertedAt = undefined;
}
minimumFractionDigits = hideNegligibleDecimalDigits
? fractionDigits.replace(/0+$/, '').length
: Math.min(minimumFractionDigits, fractionDigits.length);
formattedValue = numberValue > MAX_SAFE_INTEGER
? this.formattedValue
: this.currencyFormat.format(numberValue, {
useGrouping: !(this.focus && this.options.distractionFree.hideGroupingSymbol),
minimumFractionDigits: minimumFractionDigits,
maximumFractionDigits: maximumFractionDigits
});
const conformedValue = this.numberMask.conformToMask(value, this.formattedValue);
let formattedValue;
if (typeof conformedValue === 'object') {
const { numberValue, fractionDigits } = conformedValue;
let { maximumFractionDigits, minimumFractionDigits } = this.currencyFormat;
if (this.focus) {
minimumFractionDigits = maximumFractionDigits;
}
minimumFractionDigits = hideNegligibleDecimalDigits
? fractionDigits.replace(/0+$/, '').length
: Math.min(minimumFractionDigits, fractionDigits.length);
formattedValue = numberValue > MAX_SAFE_INTEGER
? this.formattedValue
: this.currencyFormat.format(numberValue, {
useGrouping: !(this.focus && this.hideGroupingSymbolOnFocus),
minimumFractionDigits,
maximumFractionDigits
});
} else {
formattedValue = conformedValue;
}
if (!this.allowNegative) {
formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);
}
if (this.focus && this.hideCurrencySymbolOnFocus) {
formattedValue = formattedValue
.replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSymbol)
.replace(this.currencyFormat.prefix, '')
.replace(this.currencyFormat.suffix, '');
}
this.el.value = formattedValue;
this.numberValue = this.currencyFormat.parse(formattedValue);
} else {
formattedValue = conformedValue;
this.el.value = this.numberValue = null;
}
if (!this.options.allowNegative) {
formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);
}
if (this.focus && this.options.distractionFree.hideCurrencySymbol) {
formattedValue = formattedValue
.replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSymbol)
.replace(this.currencyFormat.prefix, '')
.replace(this.currencyFormat.suffix, '');
}
this.el.value = formattedValue;
this.numberValue = this.currencyFormat.parse(formattedValue);
} else {
this.el.value = this.numberValue = null;
this.formattedValue = this.el.value;
this.callbackFns.onInput(this.getValue());
}
this.formattedValue = this.el.value;
};
NumberInput.prototype.format = function format (value) {
this.updateInputValue(value);
this.callbackFns.onInput(this.getValue());
};
NumberInput.prototype.addEventListener = function addEventListener () {
var this$1 = this;
this.el.addEventListener('input', function () {
var ref = this$1.el;
var value = ref.value;
var selectionStart = ref.selectionStart;
this$1.format(value);
if (this$1.focus) {
this$1.setCaretPosition(getCaretPositionAfterFormat(this$1.formattedValue, value, selectionStart, this$1.currencyFormat, this$1.options));
}
}, { capture: true });
this.el.addEventListener('focus', function () {
this$1.focus = true;
var ref = this$1.options.distractionFree;
var hideCurrencySymbol = ref.hideCurrencySymbol;
var hideGroupingSymbol = ref.hideGroupingSymbol;
var hideNegligibleDecimalDigits = ref.hideNegligibleDecimalDigits;
if (hideCurrencySymbol || hideGroupingSymbol || hideNegligibleDecimalDigits) {
setTimeout(function () {
var ref = this$1.el;
var value = ref.value;
var selectionStart = ref.selectionStart;
var selectionEnd = ref.selectionEnd;
if (value) {
this$1.updateInputValue(this$1.el.value, hideNegligibleDecimalDigits);
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;
}
}
}
}
return this.hideCurrencySymbolOnFocus ? newValueLength - caretPositionFromLeft : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length)
};
this.setCaretPosition(getCaretPositionAfterFormat());
}
}, { capture: true });
this.el.addEventListener('focus', () => {
this.focus = true;
setTimeout(() => {
const { value, selectionStart, selectionEnd } = this.el;
if ((this.hideCurrencySymbolOnFocus || this.hideGroupingSymbolOnFocus || this.hideNegligibleDecimalDigitsOnFocus) && value) {
this.format(value, this.hideNegligibleDecimalDigitsOnFocus);
}
if (Math.abs(selectionStart - selectionEnd) > 0) {
this$1.setCaretPosition(0, this$1.el.value.length);
this.setCaretPosition(0, this.el.value.length);
} else {
this$1.setCaretPosition(getDistractionFreeCaretPosition(this$1.currencyFormat, this$1.options, value, selectionStart));
const getSelectionStart = () => {
const { prefix, suffix, groupingSymbol } = this.currencyFormat;
if (!this.hideCurrencySymbolOnFocus) {
if (selectionStart > value.length - suffix.length) {
return this.formattedValue.length - suffix.length
} else if (selectionStart < prefix.length) {
return prefix.length
}
}
let result = selectionStart;
if (this.hideCurrencySymbolOnFocus) {
result -= prefix.length;
}
if (this.hideGroupingSymbolOnFocus) {
result -= count(value.substring(0, selectionStart), groupingSymbol);
}
return result
};
this.setCaretPosition(getSelectionStart());
}
});
}
});
this.el.addEventListener('keypress', function (e) {
if (DECIMAL_SYMBOLS.includes(e.key)) {
this$1.decimalSymbolInsertedAt = this$1.el.selectionStart;
}
});
this.el.addEventListener('blur', function () {
this$1.focus = false;
if (this$1.numberValue != null) {
this$1.applyFixedFractionFormat(this$1.numberValue);
}
});
this.el.addEventListener('change', function () {
this$1.callbackFns.onChange(this$1.getValue());
});
};
NumberInput.prototype.setCaretPosition = function setCaretPosition (start, end) {
if ( end === void 0 ) end = start;
this.el.setSelectionRange(start, end); };
var directive = {
bind: function bind (el, ref, vnode) {
var optionsFromBinding = ref.value;
var inputElement = el.tagName.toLowerCase() === 'input' ? el : el.querySelector('input');
if (!inputElement) {
throw new Error('No input element found')
}
var options = Object.assign({}, DEFAULT_OPTIONS,
(vnode.context.$ci || {}).globalOptions,
optionsFromBinding);
var listeners = (vnode.data && vnode.data.on) || (vnode.componentOptions && vnode.componentOptions.listeners) || {};
var emit = function (event, data) {
if (listeners[event]) {
listeners[event](vnode.componentOptions ? data : { target: { value: data } });
});
this.el.addEventListener('keypress', (e) => {
if (DECIMAL_SYMBOLS.includes(e.key)) {
this.decimalSymbolInsertedAt = this.el.selectionStart;
}
};
el.$ci = new NumberInput(inputElement, options, {
onChange: function () { emit('change', inputElement.value); },
onInput: function () { emit('input', inputElement.value); }
});
},
componentUpdated: function componentUpdated (el, ref) {
var value = ref.value;
var oldValue = ref.oldValue;
if (!equal(value, oldValue)) {
el.$ci.setOptions(value);
}
this.el.addEventListener('blur', () => {
this.focus = false;
if (this.numberValue != null) {
this.applyFixedFractionFormat(this.numberValue);
}
});
this.el.addEventListener('change', () => {
this.callbackFns.onChange(this.getValue());
});
}
};
setCaretPosition (start, end = start) { this.el.setSelectionRange(start, end); }
}
var component = {
render: function render (h) {
var this$1 = this;
return h('input', {
directives: [{
name: 'currency',
value: this.options
}],
on: Object.assign({}, this.$listeners,
{change: function () {
this$1.$emit('change', getValue(this$1.$el));
},
input: function () {
var numberValue = getValue(this$1.$el);
if (this$1.value !== numberValue) {
this$1.$emit('input', numberValue);
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;
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];
}
return options
}, {}));
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;
}
}})
})
},
directives: {
currency: directive
},
name: 'CurrencyInput',
props: {
value: {
type: Number,
default: null
},
locale: {
type: String,
default: undefined
},
currency: {
type: [String, Object],
default: undefined
},
distractionFree: {
type: [Boolean, Object],
default: undefined
},
precision: {
type: [Number, Object],
default: undefined
},
autoDecimalMode: {
type: Boolean,
default: undefined
},
valueAsInteger: {
type: Boolean,
default: undefined
},
valueRange: {
type: Object,
default: undefined
},
allowNegative: {
type: Boolean,
default: undefined
});
numberInput.setValue(numberValue.value);
}
}
},
mounted: function mounted () {
this.setValue(this.value);
},
computed: {
options: function options () {
var this$1 = this;
var options = Object.assign({}, DEFAULT_OPTIONS,
(this.$ci || {}).globalOptions);
Object.keys(DEFAULT_OPTIONS).forEach(function (key) {
if (this$1[key] !== undefined) {
options[key] = this$1[key];
}
});
return options
}
},
watch: {
value: 'setValue'
},
methods: {
setValue: function setValue$1 (value) {
setValue(this.$el, value);
}
}
});
vueDemi.watch(numberValue, (value) => {
numberInput.setValue(value);
});
vueDemi.watch(options, (options) => {
numberInput.setOptions(options);
});
return { formattedValue }
};
var plugin = {
install: function install (Vue, ref) {
if ( ref === void 0 ) ref = {};
var componentName = ref.componentName; if ( componentName === void 0 ) componentName = component.name;
var directiveName = ref.directiveName; if ( directiveName === void 0 ) directiveName = 'currency';
var globalOptions = ref.globalOptions; if ( globalOptions === void 0 ) globalOptions = {};
Vue.component(componentName, component);
Vue.directive(directiveName, directive);
Vue.prototype.$ci = {
parse: function (formattedValue, options) { return parse(formattedValue, Object.assign({}, globalOptions, options)); },
getValue: getValue,
setValue: setValue,
globalOptions: globalOptions
};
}
};
exports.default = useCurrencyInput;
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(plugin);
}
exports.CurrencyDirective = directive;
exports.CurrencyInput = component;
exports.default = plugin;
exports.getValue = getValue;
exports.parse = parse;
exports.setValue = setValue;
Object.defineProperty(exports, '__esModule', { value: true });
})));
{
"name": "vue-currency-input",
"description": "Easy input of currency formatted numbers for Vue.js.",
"version": "1.22.3",
"version": "2.0.0-beta.0",
"license": "MIT",

@@ -13,4 +13,3 @@ "unpkg": "dist/vue-currency-input.umd.js",

"dist/*.js",
"src",
"nuxt"
"src/index.d.ts"
],

@@ -26,2 +25,4 @@ "sideeffects": false,

"vue",
"composition api",
"composable",
"text mask",

@@ -31,5 +32,6 @@ "input mask",

"money input",
"format",
"number format",
"i18n",
"ISO 4217"
"ISO 4217",
"ECMA-402"
],

@@ -45,3 +47,4 @@ "scripts": {

"peerDependencies": {
"vue": "^2.5"
"@vue/composition-api": "^1.0.0-beta.1",
"vue": "^2.5 || ^3.0.0"
},

@@ -54,4 +57,6 @@ "devDependencies": {

"@vue/cli-service": "~4.4.1",
"@vue/composition-api": "^1.0.0-beta.14",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/test-utils": "^1.0.3",
"@vuepress/plugin-pwa": "^1.6.0",
"babel-eslint": "^10.1.0",

@@ -66,3 +71,2 @@ "core-js": "^3.6.5",

"rollup": "^2.15.0",
"rollup-plugin-buble": "^0.19.8",
"rollup-plugin-cleanup": "^3.1.1",

@@ -72,5 +76,8 @@ "rollup-plugin-filesize": "^9.0.0",

"vue-template-compiler": "^2.6.11",
"vuepress": "^1.5.1",
"vuepress": "^1.6.0",
"vuetify": "^2.1.15"
},
"dependencies": {
"vue-demi": "^0.4.0"
}
}

@@ -9,54 +9,26 @@ [![Build Status](https://travis-ci.com/dm4t2/vue-currency-input.svg?branch=master)](https://travis-ci.com/dm4t2/vue-currency-input)

# Vue Currency Input
The Vue Currency Input plugin allows an easy input of currency formatted numbers. It provides both a standalone component (`<currency-input>`) and a custom Vue directive (`v-currency`) for decorating existing input components with currency format capabilities.
Vue Currency Input allows an easy input of currency formatted numbers. Powered by the [Vue Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html), it provides a Vue composable for decorating input components with currency format capabilities.
[![](docs/vue-currency-input.gif)](https://dm4t2.github.io/vue-currency-input)
[![](docs/vue-currency-input.gif)](https://vue-currency-input-next.netlify.app/)
## Features
* [Tiny bundle size](https://bundlephobia.com/result?p=vue-currency-input) and zero dependencies
* Supports both Vue 2 and Vue 3
* [Tiny bundle size](https://bundlephobia.com/result?p=vue-currency-input)
* Format as you type
* Locale dependent, ISO-compliant currency formatting based on [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat)
* 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
* Distraction free (hides the formatting on focus for easier input)
* Allows handling values as integer numbers for full precision
* Auto decimal mode (automatically inserts the decimal symbol, using the last inputted digits as decimal digits)
* Auto decimal digits (automatically inserts the decimal symbol, using the last inputted digits as decimal digits)
* Built-in value range validation
* Works with input components of popular frameworks like [Vuetify](https://codesandbox.io/s/using-vue-currency-input-with-vuetify-kd7d1) or [Element](https://codesandbox.io/s/using-vue-currency-input-with-element-ui-z8gik)
* Works with input components of popular frameworks like [Vuetify](https://vuetifyjs.com/en/components/text-fields/), [Quasar](https://quasar.dev/vue-components/input) or [Element](https://element.eleme.io/#/en-US/component/input)
## Live Demo
Check out the [playground](https://dm4t2.github.io/vue-currency-input/playground/) to see it in action.
Check out the [playground](https://vue-currency-input-next.netlify.app/playground/) to see it in action.
## Quick Start
Install the npm package:
``` bash
npm install vue-currency-input
# OR
yarn add vue-currency-input
```
Add the Vue plugin in your `main.js`:
``` js
import Vue from 'vue'
import VueCurrencyInput from 'vue-currency-input'
Vue.use(VueCurrencyInput)
```
Use the `<currency-input`> component:
``` vue
<template>
<currency-input v-model="value" />
</template>
<script>
export default {
data: () => ({ value: 1000 })
}
</script>
```
## Documentation
Please refer to the [project home page](https://dm4t2.github.io/vue-currency-input) for a detailed documentation.
Please refer to the [project home page](https://vue-currency-input-next.netlify.app/) for a detailed documentation.
## Support me
If you find this plugin helpful or you want to support the development, buy me a coffee:
If you find my work helpful, or you want to support the development, star the repo or buy me a coffee:
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/D1D6SXEA)

@@ -1,8 +0,3 @@

import { Component, DirectiveOptions, PluginFunction } from 'vue'
import { Ref } from 'vue-demi'
export interface CurrencyOptions {
prefix?: string,
suffix?: string
}
export interface DistractionFreeOptions {

@@ -21,7 +16,7 @@ hideCurrencySymbol?: boolean,

locale?: string,
currency?: string | CurrencyOptions,
currency: string,
valueAsInteger?: boolean,
distractionFree?: boolean | DistractionFreeOptions,
precision?: number | NumberRange,
autoDecimalMode?: boolean,
autoDecimalDigits?: boolean,
valueRange?: NumberRange,

@@ -31,38 +26,13 @@ allowNegative?: boolean

export interface PluginOptions {
globalOptions?: CurrencyInputOptions,
componentName?: string,
directiveName?: string
export interface ComposableOptions {
inputRef: Ref,
props: any,
emit (event: string, value: number | null): void
}
export interface VueCurrencyInput {
install: PluginFunction<PluginOptions>
declare const useCurrencyInput: ({ emit, inputRef, props }: ComposableOptions) => {
formattedValue: string
}
declare const VueCurrencyInput: VueCurrencyInput
export default VueCurrencyInput
export const CurrencyDirective: DirectiveOptions
export const CurrencyInput: Component
export function parse (formattedValue: string, options: CurrencyInputOptions): number | null
export function getValue (el: HTMLInputElement): number | null
export function setValue (el: HTMLInputElement, value: Number): void
declare module 'vue/types/vue' {
interface Vue {
$ci: {
globalOptions: CurrencyInputOptions
parse (formattedValue: string, options: CurrencyInputOptions): number | null
getValue (el: HTMLInputElement): number | null
setValue (el: HTMLInputElement, value: Number): void
}
}
}
export default useCurrencyInput
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc