@pequity/squirrel 5.4.8 → 5.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pequity/squirrel",
3
3
  "description": "Squirrel component library",
4
- "version": "5.4.8",
4
+ "version": "5.4.10",
5
5
  "packageManager": "pnpm@9.12.3",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -38,12 +38,11 @@
38
38
  "main": "./dist/cjs/index.js",
39
39
  "module": "./dist/es/index.js",
40
40
  "peerDependencies": {
41
- "@popperjs/core": "^2.11.8",
42
41
  "@tanstack/vue-virtual": "^3.8.3",
42
+ "@vuepic/vue-datepicker": "^10.0.0",
43
43
  "dayjs": "^1.11.12",
44
44
  "floating-vue": "^5.2.2",
45
45
  "lodash-es": "^4.17.21",
46
- "v-calendar": "^3.1.2",
47
46
  "vue": "^3.4.33",
48
47
  "vue-currency-input": "^3.1.0",
49
48
  "vue-router": "^4.4.0",
@@ -54,7 +53,6 @@
54
53
  "@commitlint/config-conventional": "^19.5.0",
55
54
  "@pequity/eslint-config": "^1.0.1",
56
55
  "@playwright/test": "^1.48.2",
57
- "@popperjs/core": "2.11.8",
58
56
  "@semantic-release/changelog": "^6.0.3",
59
57
  "@semantic-release/git": "^10.0.1",
60
58
  "@storybook/addon-a11y": "^8.4.2",
@@ -69,14 +67,15 @@
69
67
  "@storybook/theming": "^8.4.2",
70
68
  "@storybook/vue3": "^8.4.2",
71
69
  "@storybook/vue3-vite": "^8.4.2",
72
- "@tanstack/vue-virtual": "3.10.8",
70
+ "@tanstack/vue-virtual": "3.10.9",
73
71
  "@types/jsdom": "^21.1.7",
74
72
  "@types/lodash-es": "^4.17.12",
75
73
  "@types/node": "^22.9.0",
76
- "@vitejs/plugin-vue": "^5.1.4",
74
+ "@vitejs/plugin-vue": "^5.1.5",
77
75
  "@vitest/coverage-v8": "^2.1.4",
78
76
  "@vue/compiler-sfc": "3.5.12",
79
77
  "@vue/test-utils": "^2.4.6",
78
+ "@vuepic/vue-datepicker": "10.0.0",
80
79
  "autoprefixer": "^10.4.20",
81
80
  "dayjs": "1.11.13",
82
81
  "eslint": "^9.14.0",
@@ -89,7 +88,7 @@
89
88
  "lint-staged": "^15.2.10",
90
89
  "lodash-es": "4.17.21",
91
90
  "make-coverage-badge": "^1.2.0",
92
- "postcss": "^8.4.47",
91
+ "postcss": "^8.4.49",
93
92
  "prettier": "^3.3.3",
94
93
  "prettier-plugin-tailwindcss": "^0.6.8",
95
94
  "resolve-tspaths": "^0.8.22",
@@ -100,8 +99,7 @@
100
99
  "svgo": "^3.3.2",
101
100
  "tailwindcss": "^3.4.14",
102
101
  "typescript": "5.6.3",
103
- "v-calendar": "3.1.2",
104
- "vite": "^5.4.10",
102
+ "vite": "^5.4.11",
105
103
  "vitest": "^2.1.4",
106
104
  "vue": "3.5.12",
107
105
  "vue-currency-input": "3.1.0",
@@ -1,6 +1,6 @@
1
1
  @import 'floating-vue/dist/style.css';
2
2
  @import 'vue-toastification/dist/index.css';
3
- @import 'v-calendar/style.css';
3
+ @import '@vuepic/vue-datepicker/dist/main.css';
4
4
 
5
5
  :root {
6
6
  /* Design system colors */
@@ -76,16 +76,55 @@
76
76
  overflow-wrap: break-word;
77
77
  }
78
78
 
79
- /* Datepicker - v-calendar */
80
- .vc-container.vc-blue {
81
- font-family: Inter;
82
- }
83
-
84
79
  /* Skeleton fade */
85
80
  .skeleton-fade {
86
81
  mask-image: linear-gradient(rgba(0, 0, 0, 1), transparent);
87
82
  }
88
83
 
84
+ /* Date picker - Vue datepicker */
85
+ :root {
86
+ --dp-font-family: 'Inter', 'Helvetica', 'Arial', 'sans-serif';
87
+ --dp-cell-border-radius: 50%;
88
+ }
89
+
90
+ .dp__theme_light {
91
+ --dp-background-color: rgb(var(--color-surface));
92
+ --dp-text-color: rgb(var(--color-on-surface));
93
+ --dp-hover-color: rgb(var(--color-p-blue-10));
94
+ --dp-hover-text-color: rgb(var(--color-p-gray-100));
95
+ --dp-hover-icon-color: rgb(var(--color-p-gray-40));
96
+ --dp-primary-color: rgb(var(--color-primary));
97
+ --dp-primary-disabled-color: rgb(var(--color-p-blue-40));
98
+ --dp-primary-text-color: rgb(var(--color-surface));
99
+ --dp-secondary-color: rgb(var(--color-p-gray-30));
100
+ --dp-border-color: rgb(var(--color-p-gray-30));
101
+ --dp-menu-border-color: rgb(var(--color-p-gray-30));
102
+ --dp-border-color-hover: rgb(var(--color-p-gray-30));
103
+ --dp-border-color-focus: rgb(var(--color-p-gray-30));
104
+ --dp-disabled-color: rgb(var(--color-p-blue-10));
105
+ --dp-scroll-bar-background: rgb(var(--color-p-blue-10));
106
+ --dp-scroll-bar-color: rgb(var(--color-p-gray-40));
107
+ --dp-success-color: rgb(var(--color-on-success));
108
+ --dp-success-color-disabled: rgb(var(--color-p-green-40));
109
+ --dp-icon-color: rgb(var(--color-p-gray-40));
110
+ --dp-danger-color: rgb(var(--color-on-error));
111
+ --dp-marker-color: rgb(var(--color-on-error));
112
+ --dp-tooltip-color: rgb(var(--color-p-blue-10));
113
+ --dp-disabled-color-text: rgb(var(--color-p-gray-40));
114
+ --dp-highlight-color: rgb(var(--color-p-blue-15));
115
+ --dp-range-between-dates-background-color: var(--dp-hover-color, rgb(var(--color-p-blue-10)));
116
+ --dp-range-between-dates-text-color: var(--dp-hover-text-color, rgb(var(--color-p-gray-100)));
117
+ --dp-range-between-border-color: var(--dp-hover-color, rgb(var(--color-p-blue-10)));
118
+ }
119
+
120
+ .dp__theme_light .dp__today {
121
+ border: 1px solid rgb(var(--color-p-blue-40));
122
+ }
123
+
124
+ [data-has-error='true'] .dp__theme_light {
125
+ border-color: var(--dp-danger-color, rgb(var(--color-on-error)));
126
+ }
127
+
89
128
  /* Toasts - vue-toastification */
90
129
  .Vue-Toastification__toast {
91
130
  font-family: Inter;
@@ -0,0 +1,292 @@
1
+ import PDatePicker from '@squirrel/components/p-date-picker/p-date-picker.vue';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
+
4
+ const createWrapper = (props) => {
5
+ return createWrapperFor(PDatePicker, {
6
+ props,
7
+ });
8
+ };
9
+
10
+ describe('PDatePicker.vue', () => {
11
+ it('renders a datepicker', () => {
12
+ const wrapper = createWrapper();
13
+
14
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
15
+
16
+ expect(datePicker.props()).toMatchObject({
17
+ modelValue: '',
18
+ minDate: null,
19
+ maxDate: null,
20
+ timezone: null,
21
+ });
22
+
23
+ expect(wrapper.find('label').exists()).toBe(false);
24
+ expect(wrapper.find('div.text-xs.text-on-error.mt-1').isVisible()).toBe(false);
25
+ });
26
+
27
+ it('passes all props to the datepicker', () => {
28
+ const wrapper = createWrapper({
29
+ modelValue: '2024-05-19',
30
+ minDate: new Date('2024-05-01'),
31
+ maxDate: new Date('2024-05-31'),
32
+ timezone: 'UTC',
33
+ });
34
+
35
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
36
+
37
+ expect(datePicker.props().modelValue).toBe('2024-05-19');
38
+ expect(datePicker.props().minDate).toEqual(new Date('2024-05-01'));
39
+ expect(datePicker.props().maxDate).toEqual(new Date('2024-05-31'));
40
+ expect(datePicker.props().timezone).toBe('UTC');
41
+ });
42
+
43
+ it('renders a label when the label prop is set', () => {
44
+ const wrapper = createWrapper({ label: 'test datepicker' });
45
+
46
+ const pInput = wrapper.findComponent({ name: 'PInput' });
47
+
48
+ expect(pInput.props().label).toBe('test datepicker');
49
+ });
50
+
51
+ it('hides the component when the hidden prop is set', () => {
52
+ const wrapper = createWrapper({ hidden: true });
53
+
54
+ expect(wrapper.classes()).toContain('hidden');
55
+ });
56
+
57
+ it('adds the required class when the required prop is set', () => {
58
+ const wrapper = createWrapper({ label: 'test datepicker', required: true });
59
+
60
+ const pInput = wrapper.findComponent({ name: 'PInput' });
61
+
62
+ expect(pInput.props().required).toBe(true);
63
+ });
64
+
65
+ it('passes listeners to the input', async () => {
66
+ const testFn = vi.fn();
67
+
68
+ const wrapper = createWrapperFor({
69
+ template: `<PDatePicker v-model="dateStrVal" @input="testEvent" />`,
70
+ components: { PDatePicker },
71
+ data() {
72
+ return {
73
+ dateStrVal: '2024-09-01',
74
+ };
75
+ },
76
+ methods: {
77
+ testEvent() {
78
+ testFn();
79
+ },
80
+ },
81
+ });
82
+
83
+ const input = wrapper.find('input');
84
+
85
+ await input.trigger('input');
86
+
87
+ expect(testFn).toHaveBeenCalled();
88
+ });
89
+
90
+ it('sets the disabled state correctly', () => {
91
+ const wrapper = createWrapperFor(PDatePicker, { props: { label: 'test datepicker', disabled: true } });
92
+
93
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
94
+ const input = wrapper.find('input');
95
+
96
+ expect(datePicker.props().disabled).toBe(true);
97
+ expect(input.element.disabled).toBe(true);
98
+ });
99
+
100
+ it('updates the value bound with v-model', async () => {
101
+ // Since VueDatePicker emits are not defined on PDatePicker we need to Spy on console.warn and mock the implementation to suppress the warning:
102
+ // [Vue warn]: Component emitted event "update:modelValue" but it is neither declared in the emits option nor as an "onUpdate:view" prop.
103
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
104
+
105
+ const wrapper = createWrapperFor({
106
+ template: `<PDatePicker v-model="dateStrVal" />`,
107
+ components: { PDatePicker },
108
+ data() {
109
+ return {
110
+ dateStrVal: '2024-09-01',
111
+ };
112
+ },
113
+ });
114
+
115
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
116
+
117
+ datePicker.vm.$emit('update:modelValue', '2024-09-02');
118
+
119
+ expect(wrapper.vm.dateStrVal).toBe('2024-09-02');
120
+
121
+ warnSpy.mockRestore();
122
+ });
123
+
124
+ it('sets the error state correctly', () => {
125
+ const wrapper = createWrapper({
126
+ label: 'test datepicker',
127
+ errorMsg: 'datepicker has error',
128
+ });
129
+
130
+ const pInput = wrapper.findComponent({ name: 'PInput' });
131
+
132
+ expect(pInput.props().errorMsg).toBe('datepicker has error');
133
+ });
134
+
135
+ it('input listens to the tab event', async () => {
136
+ const testFn = vi.fn();
137
+
138
+ const wrapper = createWrapperFor({
139
+ template: `<PDatePicker v-model="dateStrVal" @keydown.tab="testEvent"><input type="text" /></PDatePicker>`,
140
+ components: { PDatePicker },
141
+ data() {
142
+ return {
143
+ dateStrVal: '2024-09-01',
144
+ };
145
+ },
146
+ methods: {
147
+ testEvent() {
148
+ testFn();
149
+ },
150
+ },
151
+ });
152
+
153
+ const input = wrapper.find('input');
154
+
155
+ await input.trigger('keydown.tab');
156
+
157
+ expect(testFn).toHaveBeenCalled();
158
+ });
159
+
160
+ it('clears the datepicker value when the input gets cleared', async () => {
161
+ // Since VueDatePicker emits are not defined on PDatePicker we need to Spy on console.warn and mock the implementation to suppress the warning:
162
+ // [Vue warn]: Component emitted event "update:modelValue" but it is neither declared in the emits option nor as an "onUpdate:view" prop.
163
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
164
+
165
+ const wrapper = createWrapperFor({
166
+ template: `<PDatePicker v-model="dateStrVal" />`,
167
+ components: { PDatePicker },
168
+ data() {
169
+ return {
170
+ dateStrVal: '2024-09-01',
171
+ };
172
+ },
173
+ });
174
+
175
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
176
+
177
+ await datePicker.vm.$emit('update:modelValue', '');
178
+
179
+ expect(wrapper.vm.dateStrVal).toBe('');
180
+
181
+ warnSpy.mockRestore();
182
+ });
183
+
184
+ it('does not clear the datepicker value when the input has a value', async () => {
185
+ // Since VueDatePicker emits are not defined on PDatePicker we need to Spy on console.warn and mock the implementation to suppress the warning:
186
+ // [Vue warn]: Component emitted event "update:modelValue" but it is neither declared in the emits option nor as an "onUpdate:view" prop.
187
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
188
+
189
+ const wrapper = createWrapperFor({
190
+ template: `<PDatePicker v-model="dateStrVal" />`,
191
+ components: { PDatePicker },
192
+ data() {
193
+ return {
194
+ dateStrVal: '2024-09-01',
195
+ };
196
+ },
197
+ });
198
+
199
+ const datePicker = wrapper.findComponent({ name: 'VueDatePicker' });
200
+
201
+ await datePicker.vm.$emit('update:modelValue', '2024-09-02');
202
+
203
+ expect(wrapper.vm.dateStrVal).toBe('2024-09-02');
204
+
205
+ warnSpy.mockRestore();
206
+ });
207
+
208
+ it('calls onInput, onEnter, and onTab when respective events occur', async () => {
209
+ // Mock the scoped slot functions
210
+ const onInput = vi.fn();
211
+ const onEnter = vi.fn();
212
+ const onTab = vi.fn();
213
+ const onFocus = vi.fn();
214
+ const onBlur = vi.fn();
215
+ const onClear = vi.fn();
216
+
217
+ // Stub VueDatePicker and pass the scoped slot props to the PInput component
218
+ const wrapper = createWrapperFor(PDatePicker, {
219
+ global: {
220
+ stubs: {
221
+ VueDatePicker: {
222
+ template: `
223
+ <div>
224
+ <slot name="dp-input"
225
+ :value="value"
226
+ :onInput="onInput"
227
+ :onEnter="onEnter"
228
+ :onTab="onTab"
229
+ :onFocus="onFocus"
230
+ :onBlur="onBlur"
231
+ :onClear="onClear"
232
+ />
233
+ </div>
234
+ `,
235
+ data() {
236
+ return {
237
+ value: '',
238
+ };
239
+ },
240
+ methods: {
241
+ onInput,
242
+ onEnter,
243
+ onTab,
244
+ onFocus,
245
+ onBlur,
246
+ onClear,
247
+ },
248
+ },
249
+ },
250
+ },
251
+ });
252
+
253
+ const input = wrapper.find('input');
254
+
255
+ // Simulate the input and keyboard events
256
+ await input.setValue('2023-10-21');
257
+ await input.trigger('input');
258
+ await input.trigger('keydown.enter');
259
+ await input.trigger('keydown.tab');
260
+
261
+ // Simulate focus and blur events
262
+ await input.trigger('focus');
263
+ await input.trigger('blur');
264
+
265
+ // Simulate clearing the input (which should trigger onClear)
266
+ await input.setValue('');
267
+ await input.trigger('input');
268
+
269
+ expect(onInput).toHaveBeenCalled();
270
+ expect(onEnter).toHaveBeenCalled();
271
+ expect(onTab).toHaveBeenCalled();
272
+ expect(onFocus).toHaveBeenCalled();
273
+ expect(onBlur).toHaveBeenCalled();
274
+ expect(onClear).toHaveBeenCalled();
275
+ });
276
+
277
+ it('returns the placeholder if it is provided in props', async () => {
278
+ const wrapper = createWrapperFor(PDatePicker, { props: { placeholder: 'Select a date', format: 'dd-MMM-yyyy' } });
279
+
280
+ const input = wrapper.find('input');
281
+
282
+ expect(input.element.placeholder).toBe('Select a date');
283
+ });
284
+
285
+ it('returns the format if no placeholder is provided', async () => {
286
+ const wrapper = createWrapperFor(PDatePicker, { props: { placeholder: '', format: 'dd-MMM-yyyy' } });
287
+
288
+ const input = wrapper.find('input');
289
+
290
+ expect(input.element.placeholder).toBe('dd-MMM-yyyy');
291
+ });
292
+ });
@@ -15,8 +15,8 @@ export default {
15
15
  docs: {
16
16
  description: {
17
17
  component: `Allows users to enter a date either through text input, or by choosing a date from the calendar.
18
- This component uses \`v-date-picker\` from [V-Calendar](https://vcalendar.io/) internally.
19
- So please take a look also there at their extensive [documentation](https://vcalendar.io/api/v2.0/).`,
18
+ This component uses \`VueDatePicker\` from [@vuepic/vue-datepicker](https://vue3datepicker.com) internally.
19
+ So please take a look also there at their extensive [documentation](https://vue3datepicker.com/).`,
20
20
  },
21
21
  },
22
22
  },
@@ -1,126 +1,81 @@
1
1
  <template>
2
- <div :class="[{ hidden: $attrs.hidden }, $attrs.class]" :data-has-error="!!errorMsg" :style="style">
3
- <slot name="label" :label="label" :label-classes="labelClasses">
4
- <label v-if="label" :class="labelClasses">
5
- {{ label }}
6
- </label>
7
- </slot>
8
- <DatePicker
9
- v-model="innerValue"
10
- :select-attribute="selectAttribute"
11
- :popover="{ visibility: 'click', placement: 'auto' }"
12
- :min-date="minDate || null"
13
- :max-date="maxDate || null"
14
- :masks="masks"
15
- :timezone="timezone"
16
- >
17
- <template #default="{ inputValue, inputEvents }">
18
- <PInput
19
- :value="inputValue"
20
- v-bind="attrsWithoutClassAndStyle"
21
- :placeholder="displayPlaceholder"
22
- v-on="inputEvents"
23
- />
24
- </template>
25
- </DatePicker>
26
- <div v-show="errorMsg" :class="errorMsgClasses">{{ errorMsg }}</div>
27
- </div>
2
+ <VueDatePicker v-model="model" :class="[{ hidden: $attrs.hidden }, $attrs.class]" v-bind="datePickerProps">
3
+ <template #dp-input="{ value, onInput, onEnter, onTab, onFocus, onBlur, onClear }">
4
+ <PInput
5
+ :model-value="value"
6
+ v-bind="inputPropsAndAttrs"
7
+ @input="handleInput($event, onInput, onClear)"
8
+ @keydown.enter="onEnter($event)"
9
+ @keydown.tab="onTab($event)"
10
+ @focus="onFocus"
11
+ @blur="onBlur"
12
+ />
13
+ </template>
14
+ </VueDatePicker>
28
15
  </template>
29
16
 
30
17
  <script setup lang="ts">
31
18
  import PInput from '@squirrel/components/p-input/p-input.vue';
32
- import { useInputClasses } from '@squirrel/composables/useInputClasses';
33
- import dayjs from 'dayjs';
34
- import { isDate, isString } from 'lodash-es';
35
- import { DatePicker } from 'v-calendar';
36
- import { computed, nextTick, ref, type StyleValue, useAttrs, watch } from 'vue';
19
+ import VueDatePicker, { type VueDatePickerProps } from '@vuepic/vue-datepicker';
20
+ import { computed, useAttrs } from 'vue';
37
21
 
38
22
  defineOptions({
39
23
  name: 'PDatePicker',
40
24
  inheritAttrs: false,
41
25
  });
42
26
 
43
- // The type of the select attribute is defined in node_modules/v-calendar/dist/types/src/utils/attribute.d.ts
44
- // but there was no way to import it, so as a workaround we cast the selectAttribute as `any`.
45
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
- const selectAttribute = { highlight: { class: 'bg-primary', contentClass: 'text-white' } } as any;
47
-
48
- const DEFAULT_MASKS = {
49
- // The mask for the input
50
- input: 'DD-MMM-YYYY',
51
- // The mask for the model value
52
- data: 'YYYY-MM-DD',
53
- };
54
-
55
27
  type Props = {
56
- modelValue?: string | null;
57
28
  label?: string;
58
29
  errorMsg?: string;
59
30
  required?: boolean;
60
- minDate?: Date | null;
61
- maxDate?: Date | null;
62
- timezone?: string;
63
- };
31
+ } & VueDatePickerProps;
64
32
 
65
33
  const props = withDefaults(defineProps<Props>(), {
66
- modelValue: '',
67
34
  label: '',
68
35
  errorMsg: '',
69
36
  required: false,
70
- minDate: null,
71
- maxDate: null,
72
- timezone: '',
37
+ inline: false,
38
+ autoApply: true,
39
+ enableTimePicker: false,
40
+ modelType: 'yyyy-MM-dd',
41
+ hideOffsetDates: true,
42
+ weekStart: 0,
43
+ textInput: true,
44
+ format: 'dd-MMM-yyyy',
73
45
  });
74
46
 
75
- const emit = defineEmits<{
76
- 'update:modelValue': [value: string | null];
77
- }>();
47
+ const model = defineModel<Date | string | null>({ default: '' });
78
48
 
79
49
  // Data
80
- const { labelClasses, errorMsgClasses } = useInputClasses(props);
81
50
  const attrs = useAttrs();
82
- // innerValue is a Date object
83
- const innerValue = ref<Date | null>(null);
84
- const stopWatch = ref(false);
85
51
 
86
52
  // Computed
87
- const masks = computed(() => {
88
- return Object.assign(DEFAULT_MASKS, attrs.masks);
89
- });
53
+ const datePickerProps = computed(() => {
54
+ const { modelValue: _, ...propsWithoutModelValue } = props;
90
55
 
91
- const displayPlaceholder = computed(() => {
92
- return isString(attrs.placeholder) ? attrs.placeholder : masks.value.input;
56
+ return propsWithoutModelValue;
93
57
  });
94
58
 
95
- const attrsWithoutClassAndStyle = computed(() => {
96
- const { class: classes, style, ...rest } = attrs;
59
+ const inputPropsAndAttrs = computed(() => {
60
+ const { class: classes, style, ...res } = attrs;
97
61
 
98
- return rest;
99
- });
62
+ res.label = props.label;
63
+ res.errorMsg = props.errorMsg;
64
+ res.required = props.required;
65
+ res.disabled = props.disabled;
66
+ res.placeholder = props.placeholder ? props.placeholder : props.format;
100
67
 
101
- const style = computed(() => {
102
- return attrs.style as StyleValue;
68
+ return res;
103
69
  });
104
70
 
105
- // Watch
106
- watch(
107
- () => props.modelValue,
108
- (nV) => {
109
- if (!stopWatch.value) {
110
- innerValue.value = nV ? dayjs(nV, masks.value.data).toDate() : null;
111
- }
112
- },
113
- { immediate: true }
114
- );
71
+ // Methods
72
+ const handleInput = (e: Event, onInputFn: (e: Event) => void, onClearFn: (e: Event) => void) => {
73
+ if (e.target instanceof HTMLInputElement && e.target.value === '') {
74
+ onClearFn(e);
115
75
 
116
- watch(innerValue, (nV) => {
117
- // We're emitting back a formatted String (value) or null in case we have an invalid date
118
- const toEmit = isDate(nV) && nV.toString() !== 'Invalid Date' ? dayjs(nV).format(masks.value.data) : null;
119
- // Stop watching when updating the value by clicking in the datepicker, in order to prevent double-emit.
120
- stopWatch.value = true;
121
- emit('update:modelValue', toEmit);
122
- nextTick(() => {
123
- stopWatch.value = false;
124
- });
125
- });
76
+ return;
77
+ }
78
+
79
+ return onInputFn(e);
80
+ };
126
81
  </script>