Skip to content

Commit

Permalink
updated directive, component and core functions
Browse files Browse the repository at this point in the history
  • Loading branch information
dipaksarkar committed Jul 15, 2022
1 parent d75ca26 commit 0850a86
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 63 deletions.
8 changes: 0 additions & 8 deletions .prettierrc.js

This file was deleted.

8 changes: 8 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"proseWrap": "always",
"tabWidth": 2,
"printWidth": 130,
"semi": false,
"singleQuote": true
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
},
"prettier.requireConfig": true
}
6 changes: 3 additions & 3 deletions docs/.vuepress/components/BaseInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<script>
export default {
name: "BaseInput",
name: 'BaseInput',
props: {
modelValue: {
default: undefined,
Expand All @@ -19,8 +19,8 @@ export default {
required: false,
},
},
emits: ["update:modelValue"],
};
emits: ['update:modelValue'],
}
</script>

<style scoped></style>
27 changes: 24 additions & 3 deletions docs/.vuepress/components/PlayGround.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
/>
<div class="mt-2">
Number value: <code class="ml-2">{{ price }}</code>
Expand All @@ -16,9 +20,12 @@
<div class="font-medium mb-2">Directive</div>
<BaseInput
v-if="updated"
:modelValue="priceDirective"
@update:model-value="(val) => (priceDirective = val)"
v-model="priceDirective"
v-number="config"
@update:model-value="onChange"
@input="onInput"
@focus="onFocus"
@blur="onBlur"
/>
<div class="mt-2">
Value: <code class="ml-2">{{ priceDirective }}</code>
Expand All @@ -35,7 +42,7 @@
Export
</button>
<Dialog v-model="exportDialogVisible">
<pre class="white--text m-0" style="margin: 0">{{ config }}</pre>
<pre class="m-0" style="margin: 0">{{ config }}</pre>
</Dialog>
</div>
</div>
Expand Down Expand Up @@ -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)
},
},
}
</script>
1 change: 1 addition & 0 deletions src/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import directive from './directive'
import options from './options'
export default {
name: 'Number',
props: {
modelValue: {
required: true,
Expand Down
58 changes: 23 additions & 35 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -90,36 +78,33 @@ 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
}

// 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())
}
}

Expand All @@ -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
}

Expand All @@ -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
Expand All @@ -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())
}
}
22 changes: 17 additions & 5 deletions src/directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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) => {
Expand All @@ -57,5 +69,5 @@ export default {

unmounted: (el) => {
core.getInputElement(el)[CONFIG_KEY].cleanup()
}
},
}
11 changes: 3 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
},
}

0 comments on commit 0850a86

Please sign in to comment.