From 0850a86035a99a346d3d4436f1e0e0ee7d7b6437 Mon Sep 17 00:00:00 2001 From: Dipak Sarkar Date: Fri, 15 Jul 2022 12:35:18 +0530 Subject: [PATCH] updated directive, component and core functions --- .prettierrc.js | 8 ---- .prettierrc.json | 8 ++++ .vscode/settings.json | 3 +- docs/.vuepress/components/BaseInput.vue | 6 +-- docs/.vuepress/components/PlayGround.vue | 27 +++++++++-- src/component.vue | 1 + src/core.js | 58 ++++++++++-------------- src/directive.js | 22 +++++++-- src/index.js | 11 ++--- 9 files changed, 81 insertions(+), 63 deletions(-) delete mode 100644 .prettierrc.js create mode 100644 .prettierrc.json 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
Value: {{ priceDirective }} @@ -35,7 +42,7 @@ Export -
{{ config }}
+
{{ config }}
@@ -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) - } + }, }