diff --git a/src/directive.ts b/src/directive.ts index e5b948d..cb0ef07 100644 --- a/src/directive.ts +++ b/src/directive.ts @@ -17,11 +17,18 @@ export const vMaska: MaskaDirective = (el, binding) => { if (binding.value != null) { const binded = binding.value - opts.onMaska = (detail: MaskaDetail) => { + const onMaska = (detail: MaskaDetail): void => { binded.masked = detail.masked binded.unmasked = detail.unmasked binded.completed = detail.completed } + + opts.onMaska = + opts.onMaska == null + ? onMaska + : Array.isArray(opts.onMaska) + ? [...opts.onMaska, onMaska] + : [opts.onMaska, onMaska] } masks.set(input, new MaskInput(input, opts)) diff --git a/src/mask-input.ts b/src/mask-input.ts index 076454f..5840db7 100644 --- a/src/mask-input.ts +++ b/src/mask-input.ts @@ -1,8 +1,10 @@ import { Mask, MaskOptions } from './mask' import { parseMask, parseOpts, parseTokens } from './parser' +type OnMaskaType = (detail: MaskaDetail) => void + export interface MaskInputOptions extends MaskOptions { - onMaska?: (detail: MaskaDetail) => void + onMaska?: OnMaskaType | OnMaskaType[] preProcess?: (value: string) => string postProcess?: (value: string) => string } @@ -142,7 +144,11 @@ export class MaskInput { } if (this.options.onMaska != null) { - this.options.onMaska(detail) + if (Array.isArray(this.options.onMaska)) { + this.options.onMaska.forEach((f) => f(detail)) + } else { + this.options.onMaska(detail) + } } input.dispatchEvent(new CustomEvent('maska', { detail })) } diff --git a/test/components/Callbacks.vue b/test/components/Callbacks.vue new file mode 100644 index 0000000..392ee35 --- /dev/null +++ b/test/components/Callbacks.vue @@ -0,0 +1,24 @@ + + + diff --git a/test/directive.test.ts b/test/directive.test.ts index 4b3daae..0870459 100644 --- a/test/directive.test.ts +++ b/test/directive.test.ts @@ -5,6 +5,7 @@ import { mount } from '@vue/test-utils' import BindInitial from './components/BindInitial.vue' import BindMasked from './components/BindMasked.vue' import BindUnmasked from './components/BindUnmasked.vue' +import Callbacks from './components/Callbacks.vue' import Completed from './components/Completed.vue' import Config from './components/Config.vue' import DataAttr from './components/DataAttr.vue' @@ -154,6 +155,35 @@ test('events', async () => { expect(wrapper.emitted('mask')[1][0]).toHaveProperty('completed', true) }) +test('callbacks', async () => { + const wrapper = mount(Callbacks) + const input1 = wrapper.get('#input1') + const input2 = wrapper.get('#input2') + + await input1.setValue('1') + expect(wrapper.emitted()).toHaveProperty('mask1') + expect(wrapper.emitted('mask1')).toHaveLength(1) + expect(wrapper.emitted('mask1')[0][0]).toHaveProperty('completed', false) + + await input1.setValue('12') + expect(wrapper.emitted('mask1')).toHaveLength(2) + expect(wrapper.emitted('mask1')[1][0]).toHaveProperty('completed', true) + + await input2.setValue('1') + expect(wrapper.emitted()).toHaveProperty('mask2') + expect(wrapper.emitted()).toHaveProperty('mask3') + expect(wrapper.emitted('mask2')).toHaveLength(1) + expect(wrapper.emitted('mask3')).toHaveLength(1) + expect(wrapper.emitted('mask2')[0][0]).toHaveProperty('completed', false) + expect(wrapper.emitted('mask3')[0][0]).toHaveProperty('completed', false) + + await input2.setValue('12') + expect(wrapper.emitted('mask2')).toHaveLength(2) + expect(wrapper.emitted('mask3')).toHaveLength(2) + expect(wrapper.emitted('mask2')[1][0]).toHaveProperty('completed', true) + expect(wrapper.emitted('mask3')[1][0]).toHaveProperty('completed', true) +}) + test('options api component', async () => { const wrapper = mount(Options) const input = wrapper.get('input') diff --git a/test/mask-input.test.ts b/test/mask-input.test.ts index eedb845..19a2c92 100644 --- a/test/mask-input.test.ts +++ b/test/mask-input.test.ts @@ -63,6 +63,26 @@ describe('test init', () => { ) }) + test('test callbacks', async () => { + document.body.innerHTML = `` + const input = document.getElementById('input') + const onMaska1 = vi.fn() + const onMaska2 = vi.fn() + + new MaskInput(input, { onMaska: [onMaska1, onMaska2] }) + + await user.type(input, '12') + expect(onMaska1).toHaveBeenCalledTimes(2) + expect(onMaska2).toHaveBeenCalledTimes(2) + expect(onMaska1).toHaveBeenLastCalledWith( + expect.objectContaining({ + masked: '1-2', + unmasked: '12', + completed: true + }) + ) + }) + test('test hooks', async () => { document.body.innerHTML = `` const input = document.getElementById('input')