diff --git a/.prettierrc.js b/.prettierrc.js
deleted file mode 100644
index e284c47..0000000
--- a/.prettierrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-module.exports = {
- trailingComma: 'es5',
- proseWrap: 'always',
- tabWidth: 2,
- printWidth: 120,
- semi: true,
- singleQuote: true,
-}
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..c640d1c
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,8 @@
+{
+ "trailingComma": "es5",
+ "proseWrap": "always",
+ "tabWidth": 2,
+ "printWidth": 130,
+ "semi": false,
+ "singleQuote": true
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index f2ff13c..c680b6f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,5 +6,6 @@
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
- }
+ },
+ "prettier.requireConfig": true
}
diff --git a/docs/.vuepress/components/BaseInput.vue b/docs/.vuepress/components/BaseInput.vue
index 77616ec..1d12d9e 100644
--- a/docs/.vuepress/components/BaseInput.vue
+++ b/docs/.vuepress/components/BaseInput.vue
@@ -9,7 +9,7 @@
diff --git a/docs/.vuepress/components/PlayGround.vue b/docs/.vuepress/components/PlayGround.vue
index 71c4739..21cc470 100644
--- a/docs/.vuepress/components/PlayGround.vue
+++ b/docs/.vuepress/components/PlayGround.vue
@@ -7,6 +7,10 @@
v-model="price"
v-bind="config"
class="shadow-sm rounded-md text-base transition-all disabled:cursor-not-allowed disabled:border-gray-300 disabled:text-gray-300 focus:border-primary focus:ring focus:ring-offset-0 focus:ring-primary focus:ring-opacity-50"
+ @update:model-value="onChange"
+ @input="onInput"
+ @focus="onFocus"
+ @blur="onBlur"
/>
Number value:
{{ price }}
@@ -16,9 +20,12 @@
Directive
(priceDirective = val)"
+ v-model="priceDirective"
v-number="config"
+ @update:model-value="onChange"
+ @input="onInput"
+ @focus="onFocus"
+ @blur="onBlur"
/>
Value:
{{ priceDirective }}
@@ -35,7 +42,7 @@
Export
@@ -117,5 +124,19 @@ export default {
},
},
},
+ methods: {
+ onChange() {
+ console.log('onChange', arguments)
+ },
+ onInput() {
+ console.log('onInput', arguments)
+ },
+ onFocus() {
+ console.log('onFocus', arguments)
+ },
+ onBlur() {
+ console.log('onBlur', arguments)
+ },
+ },
}
diff --git a/src/component.vue b/src/component.vue
index 48e7646..cffba8a 100644
--- a/src/component.vue
+++ b/src/component.vue
@@ -15,6 +15,7 @@ import directive from './directive'
import options from './options'
export default {
+ name: 'Number',
props: {
modelValue: {
required: true,
diff --git a/src/core.js b/src/core.js
index dc51dda..c94840a 100644
--- a/src/core.js
+++ b/src/core.js
@@ -26,18 +26,6 @@ export function FacadeChangeEvent() {
})
}
-/**
- * Creates a CustomEvent('blur') with detail = { facade: true }
- * used as a way to identify our own blur event
- */
-export function FacadeBlurEvent() {
- return new CustomEvent('blur', {
- bubbles: true,
- cancelable: true,
- detail: { facade: true },
- })
-}
-
/**
* ensure that the element we're attaching to is an input element
* if not try to find an input element in this elements childrens
@@ -90,24 +78,25 @@ export function updateValue(
oldValue = oldValue || ''
currentValue = currentValue || ''
- const number = new NumberFormat(config).clean(clean && !config.reverseFill)
- let masked = number.format(currentValue)
- let unmasked = number.clean(!config.reverseFill).unformat(currentValue)
-
- // check value with in range max and min value
- if (clean) {
- if (Number(config.max) && unmasked > Number(config.max)) {
- masked = number.format(config.max)
- unmasked = number.unformat(config.max)
- } else if (Number(config.min) && unmasked < Number(config.min)) {
- masked = number.format(config.min)
- unmasked = number.unformat(config.min)
+ if (force || oldValue !== currentValue) {
+ const number = new NumberFormat(config).clean(clean && !config.reverseFill)
+ let masked = number.format(currentValue)
+ let unmasked = number.clean(!config.reverseFill).unformat(currentValue)
+
+ // check value with in range max and min value
+ if (clean) {
+ if (Number(config.max) && unmasked > Number(config.max)) {
+ masked = number.format(config.max)
+ unmasked = number.unformat(config.max)
+ } else if (Number(config.min) && unmasked < Number(config.min)) {
+ masked = number.format(config.min)
+ unmasked = number.unformat(config.min)
+ }
}
- }
- if (force || oldValue !== currentValue) {
el[CONFIG_KEY].oldValue = masked
el.unmaskedValue = unmasked
+
// safari makes the cursor jump to the end if el.value gets assign even if to the same value
if (el.value !== masked) {
el.value = masked
@@ -115,11 +104,7 @@ export function updateValue(
// this part needs to be outside the above IF statement for vuetify in firefox
// drawback is that we endup with two's input events in firefox
- return (
- emit &&
- el.dispatchEvent(FacadeInputEvent()) &&
- el.dispatchEvent(FacadeChangeEvent())
- )
+ return emit && el.dispatchEvent(FacadeInputEvent())
}
}
@@ -130,8 +115,9 @@ export function updateValue(
*/
export function inputHandler(event) {
const { target, detail } = event
+
// We dont need to run this method on the event we emit (prevent event loop)
- if (detail && detail.facade) {
+ if (detail?.facade) {
return false
}
@@ -143,6 +129,7 @@ export function inputHandler(event) {
const { oldValue, config } = target[CONFIG_KEY]
updateValue(target, null, { emit: false }, event)
+
// updated cursor position
positionFromEnd = Math.max(positionFromEnd, config.suffix.length)
positionFromEnd = target.value.length - positionFromEnd
@@ -161,16 +148,17 @@ export function inputHandler(event) {
*/
export function blurHandler(event) {
const { target, detail } = event
+
// We dont need to run this method on the event we emit (prevent event loop)
- if (detail && detail.facade) {
+ if (detail?.facade) {
return false
}
const { oldValue } = target[CONFIG_KEY]
- updateValue(target, null, { force: true, clean: true }, event)
+ updateValue(target, null, { force: true, emit: false, clean: true }, event)
if (oldValue !== target.value) {
- target.dispatchEvent(FacadeBlurEvent())
+ target.dispatchEvent(FacadeChangeEvent())
}
}
diff --git a/src/directive.js b/src/directive.js
index 6b47d8d..4008a3f 100644
--- a/src/directive.js
+++ b/src/directive.js
@@ -22,7 +22,12 @@ export default {
const handlerOwner = el.parentElement || el
// use anonymous event handler to avoid inadvertently removing masking for all inputs within a container
- const oninput = (e) => core.inputHandler(e)
+ const oninput = (e) => {
+ if (e.target !== el) {
+ return
+ }
+ core.inputHandler(e, el)
+ }
handlerOwner.addEventListener('input', oninput, true)
@@ -31,17 +36,24 @@ export default {
// check decimal key and insert to current element
// updated cursor position after format the value
el.onkeydown = (e) => {
- if (([110, 190].includes(e.keyCode) || e.key === config.decimal) && !el.value.includes(config.decimal)) {
+ if (
+ ([110, 190].includes(e.keyCode) || e.key === config.decimal) &&
+ !el.value.includes(config.decimal)
+ ) {
e.preventDefault()
el.setRangeText(config.decimal)
el.dispatchEvent(new Event('input'))
core.updateCursor(el, el.value.indexOf(config.decimal) + 1)
- } else if (([110, 190].includes(e.keyCode) || e.key === config.decimal) && el.value.includes(config.decimal)) {
+ } else if (
+ ([110, 190].includes(e.keyCode) || e.key === config.decimal) &&
+ el.value.includes(config.decimal)
+ ) {
e.preventDefault()
}
}
- option.cleanup = () => handlerOwner.removeEventListener('input', oninput, true)
+ option.cleanup = () =>
+ handlerOwner.removeEventListener('input', oninput, true)
},
updated: (el, { value, oldValue, modifiers }, vnode) => {
@@ -57,5 +69,5 @@ export default {
unmounted: (el) => {
core.getInputElement(el)[CONFIG_KEY].cleanup()
- }
+ },
}
diff --git a/src/index.js b/src/index.js
index 7e40a65..0170451 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,19 +3,14 @@ import vNumber from './directive'
import options from './options'
import NumberFormat from './number-format'
-export {
- number,
- vNumber,
- options,
- NumberFormat
-}
+export { number, vNumber, options, NumberFormat }
export default {
- install(app, config) {
+ install(app, config = {}) {
if (config) {
Object.assign(options, config)
}
app.directive('number', vNumber)
app.component('number', number)
- }
+ },
}