@pequity/squirrel 5.4.7 → 5.4.9

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.
Files changed (158) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/chunks/p-date-picker.js +143 -85
  3. package/dist/cjs/chunks/p-dropdown-select.js +4 -4
  4. package/dist/cjs/chunks/p-inline-date-picker.js +117 -67
  5. package/dist/cjs/chunks/p-link.js +1 -1
  6. package/dist/cjs/chunks/p-select.js +1 -1
  7. package/dist/cjs/index.js +37 -37
  8. package/dist/cjs/p-btn.js +2 -2
  9. package/dist/cjs/p-checkbox.js +1 -1
  10. package/dist/cjs/p-chips.js +2 -2
  11. package/dist/cjs/p-input-number.js +3 -3
  12. package/dist/cjs/p-input-search.js +1 -1
  13. package/dist/cjs/p-loading.js +2 -2
  14. package/dist/cjs/p-modal.js +2 -2
  15. package/dist/cjs/p-skeleton-loader.js +1 -1
  16. package/dist/cjs/p-table-td.js +1 -1
  17. package/dist/cjs/p-toggle.js +1 -1
  18. package/dist/cjs/tailwind.js +2 -2
  19. package/dist/cjs/usePTableRowVirtualizer.js +1 -1
  20. package/dist/cjs/useSelectList.js +3 -3
  21. package/dist/es/chunks/p-date-picker.js +144 -86
  22. package/dist/es/chunks/p-dropdown-select.js +4 -4
  23. package/dist/es/chunks/p-inline-date-picker.js +118 -68
  24. package/dist/es/chunks/p-link.js +1 -1
  25. package/dist/es/chunks/p-select.js +1 -1
  26. package/dist/es/index.js +35 -35
  27. package/dist/es/p-btn.js +2 -2
  28. package/dist/es/p-checkbox.js +1 -1
  29. package/dist/es/p-chips.js +2 -2
  30. package/dist/es/p-input-number.js +3 -3
  31. package/dist/es/p-input-search.js +1 -1
  32. package/dist/es/p-loading.js +2 -2
  33. package/dist/es/p-modal.js +2 -2
  34. package/dist/es/p-skeleton-loader.js +1 -1
  35. package/dist/es/p-table-td.js +1 -1
  36. package/dist/es/p-toggle.js +1 -1
  37. package/dist/es/tailwind.js +2 -2
  38. package/dist/es/usePTableRowVirtualizer.js +1 -1
  39. package/dist/es/useSelectList.js +3 -3
  40. package/dist/squirrel/components/index.d.ts +13 -13
  41. package/dist/squirrel/components/p-btn/p-btn.vue.d.ts +2 -2
  42. package/dist/squirrel/components/p-card/p-card.vue.d.ts +3 -2
  43. package/dist/squirrel/components/p-checkbox/p-checkbox.vue.d.ts +2 -1
  44. package/dist/squirrel/components/p-close-btn/p-close-btn.vue.d.ts +1 -1
  45. package/dist/squirrel/components/p-date-picker/p-date-picker.vue.d.ts +27 -30
  46. package/dist/squirrel/components/p-drawer/p-drawer.vue.d.ts +3 -3
  47. package/dist/squirrel/components/p-dropdown-select/p-dropdown-select.vue.d.ts +8 -7
  48. package/dist/squirrel/components/p-file-upload/p-file-upload.vue.d.ts +1 -1
  49. package/dist/squirrel/components/p-icon/p-icon.vue.d.ts +2 -2
  50. package/dist/squirrel/components/p-info-icon/p-info-icon.vue.d.ts +2 -1
  51. package/dist/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue.d.ts +46 -0
  52. package/dist/squirrel/components/p-input/p-input.vue.d.ts +1 -1
  53. package/dist/squirrel/components/p-input-number/p-input-number.vue.d.ts +1 -1
  54. package/dist/squirrel/components/p-input-percent/p-input-percent.vue.d.ts +1 -1
  55. package/dist/squirrel/components/p-input-search/p-input-search.vue.d.ts +2 -2
  56. package/dist/squirrel/components/p-link/p-link.vue.d.ts +2 -1
  57. package/dist/squirrel/components/p-modal/p-modal.vue.d.ts +5 -4
  58. package/dist/squirrel/components/p-pagination-info/p-pagination-info.vue.d.ts +2 -1
  59. package/dist/squirrel/components/p-ring-loader/p-ring-loader.vue.d.ts +1 -1
  60. package/dist/squirrel/components/p-select/p-select.vue.d.ts +3 -2
  61. package/dist/squirrel/components/p-select-btn/p-select-btn.vue.d.ts +3 -2
  62. package/dist/squirrel/components/p-select-list/p-select-list.vue.d.ts +6 -5
  63. package/dist/squirrel/components/p-select-pill/p-select-pill.vue.d.ts +1 -1
  64. package/dist/squirrel/components/p-table/p-table.vue.d.ts +3 -2
  65. package/dist/squirrel/components/p-table-loader/p-table-loader.vue.d.ts +1 -1
  66. package/dist/squirrel/components/p-table-sort/p-table-sort.vue.d.ts +1 -1
  67. package/dist/squirrel/components/p-table-td/p-table-td.vue.d.ts +2 -1
  68. package/dist/squirrel/components/p-tabs/p-tabs.vue.d.ts +2 -2
  69. package/dist/squirrel/components/p-textarea/p-textarea.vue.d.ts +1 -1
  70. package/dist/squirrel/components/p-toggle/p-toggle.vue.d.ts +1 -1
  71. package/dist/squirrel/index.d.ts +1 -1
  72. package/dist/squirrel/utils/index.d.ts +8 -8
  73. package/dist/squirrel/utils/inputClassesMixin.d.ts +1 -1
  74. package/dist/style.css +98 -989
  75. package/package.json +30 -32
  76. package/squirrel/assets/squirrel.css +45 -6
  77. package/squirrel/components/index.ts +37 -37
  78. package/squirrel/components/p-action-bar/p-action-bar.spec.ts +1 -1
  79. package/squirrel/components/p-action-bar/p-action-bar.stories.js +2 -2
  80. package/squirrel/components/p-action-bar/p-action-bar.vue +1 -1
  81. package/squirrel/components/p-alert/p-alert.vue +1 -1
  82. package/squirrel/components/p-btn/p-btn.spec.js +2 -2
  83. package/squirrel/components/p-btn/p-btn.vue +4 -4
  84. package/squirrel/components/p-checkbox/p-checkbox.vue +1 -1
  85. package/squirrel/components/p-chips/p-chips.vue +1 -1
  86. package/squirrel/components/p-date-picker/p-date-picker.spec.js +292 -0
  87. package/squirrel/components/p-date-picker/p-date-picker.stories.js +3 -3
  88. package/squirrel/components/p-date-picker/p-date-picker.vue +45 -90
  89. package/squirrel/components/p-dropdown/p-dropdown.spec.js +1 -1
  90. package/squirrel/components/p-dropdown/p-dropdown.vue +1 -1
  91. package/squirrel/components/p-dropdown-select/p-dropdown-select.spec.js +4 -4
  92. package/squirrel/components/p-dropdown-select/p-dropdown-select.stories.js +2 -2
  93. package/squirrel/components/p-dropdown-select/p-dropdown-select.vue +8 -8
  94. package/squirrel/components/p-file-upload/p-file-upload.vue +2 -2
  95. package/squirrel/components/p-icon/p-icon.spec.js +1 -1
  96. package/squirrel/components/p-icon/p-icon.stories.js +1 -1
  97. package/squirrel/components/p-icon/p-icon.vue +2 -2
  98. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.spec.js +21 -45
  99. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.stories.js +3 -3
  100. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.vue +16 -85
  101. package/squirrel/components/p-input/p-input.stories.js +1 -1
  102. package/squirrel/components/p-input/p-input.vue +1 -1
  103. package/squirrel/components/p-input-number/p-input-number.stories.js +1 -1
  104. package/squirrel/components/p-input-number/p-input-number.vue +3 -3
  105. package/squirrel/components/p-input-percent/p-input-percent.stories.js +1 -1
  106. package/squirrel/components/p-input-percent/p-input-percent.vue +1 -1
  107. package/squirrel/components/p-input-search/p-input-search.stories.js +1 -1
  108. package/squirrel/components/p-input-search/p-input-search.vue +1 -1
  109. package/squirrel/components/p-link/p-link.spec.js +1 -1
  110. package/squirrel/components/p-link/p-link.vue +1 -1
  111. package/squirrel/components/p-loading/p-loading.spec.js +2 -2
  112. package/squirrel/components/p-loading/p-loading.stories.js +2 -2
  113. package/squirrel/components/p-loading/p-loading.vue +1 -1
  114. package/squirrel/components/p-loading/usePLoading.ts +1 -1
  115. package/squirrel/components/p-modal/p-modal-basic.spec.js +1 -1
  116. package/squirrel/components/p-modal/p-modal-events.spec.js +1 -1
  117. package/squirrel/components/p-modal/p-modal-features.spec.js +1 -1
  118. package/squirrel/components/p-modal/p-modal.vue +3 -3
  119. package/squirrel/components/p-pagination/p-pagination.vue +1 -1
  120. package/squirrel/components/p-progress-bar/p-progess-bar.spec.js +1 -1
  121. package/squirrel/components/p-progress-bar/p-progress-bar.vue +1 -1
  122. package/squirrel/components/p-select/p-select.spec.js +1 -1
  123. package/squirrel/components/p-select/p-select.stories.js +1 -1
  124. package/squirrel/components/p-select/p-select.vue +1 -1
  125. package/squirrel/components/p-select-btn/p-select-btn.spec.js +1 -1
  126. package/squirrel/components/p-select-btn/p-select-btn.stories.js +1 -1
  127. package/squirrel/components/p-select-btn/p-select-btn.vue +1 -1
  128. package/squirrel/components/p-select-list/p-select-list.spec.js +4 -4
  129. package/squirrel/components/p-select-list/p-select-list.vue +5 -5
  130. package/squirrel/components/p-select-list/useSelectList.ts +3 -3
  131. package/squirrel/components/p-select-pill/p-select-pill.spec.js +1 -1
  132. package/squirrel/components/p-select-pill/p-select-pill.stories.js +2 -2
  133. package/squirrel/components/p-select-pill/p-select-pill.vue +1 -1
  134. package/squirrel/components/p-skeleton-loader/p-skeleton-loader.vue +1 -1
  135. package/squirrel/components/p-table/p-table.spec.js +2 -2
  136. package/squirrel/components/p-table/p-table.vue +4 -4
  137. package/squirrel/components/p-table/usePTableColResize.spec.js +1 -1
  138. package/squirrel/components/p-table/usePTableColResize.ts +1 -1
  139. package/squirrel/components/p-table/usePTableRowVirtualizer.ts +1 -1
  140. package/squirrel/components/p-table-sort/p-table-sort.spec.js +1 -1
  141. package/squirrel/components/p-table-sort/p-table-sort.stories.js +1 -1
  142. package/squirrel/components/p-table-sort/p-table-sort.vue +1 -1
  143. package/squirrel/components/p-table-td/p-table-td.spec.js +3 -3
  144. package/squirrel/components/p-table-td/p-table-td.stories.js +1 -1
  145. package/squirrel/components/p-table-td/p-table-td.vue +2 -2
  146. package/squirrel/components/p-tabs/p-tabs.vue +1 -1
  147. package/squirrel/components/p-textarea/p-textarea.stories.js +1 -1
  148. package/squirrel/components/p-textarea/p-textarea.vue +1 -1
  149. package/squirrel/components/p-toggle/p-toggle.stories.js +1 -1
  150. package/squirrel/components/p-toggle/p-toggle.vue +1 -1
  151. package/squirrel/composables/useInputClasses.spec.js +1 -1
  152. package/squirrel/index.ts +1 -1
  153. package/squirrel/utils/component.ts +1 -1
  154. package/squirrel/utils/index.ts +18 -18
  155. package/squirrel/utils/inputClassesMixin.ts +1 -1
  156. package/squirrel/utils/pagination.spec.js +2 -2
  157. package/squirrel/utils/sanitization.spec.js +1 -1
  158. package/squirrel/utils/tailwind.ts +3 -2
@@ -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
+ });
@@ -1,5 +1,5 @@
1
- import PDatePicker from '@squirrel/components/p-date-picker/p-date-picker.vue';
2
1
  import { fieldArgTypes } from '@root/stories/common/field';
2
+ import PDatePicker from '@squirrel/components/p-date-picker/p-date-picker.vue';
3
3
 
4
4
  export default {
5
5
  title: 'Components/PDatePicker',
@@ -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 dayjs from 'dayjs';
33
- import { DatePicker } from 'v-calendar';
34
- import { type StyleValue, computed, nextTick, ref, useAttrs, watch } from 'vue';
35
- import { isDate, isString } from 'lodash-es';
36
- import { useInputClasses } from '@squirrel/composables/useInputClasses';
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>
@@ -1,6 +1,6 @@
1
1
  import PDropdown from '@squirrel/components/p-dropdown/p-dropdown.vue';
2
- import { createWrapperFor } from '@tests/vitest.helpers';
3
2
  import { setupListKeyboardNavigation } from '@squirrel/utils/listKeyboardNavigation';
3
+ import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  vi.mock('@squirrel/utils/listKeyboardNavigation', () => {
6
6
  return {
@@ -88,7 +88,7 @@ import {
88
88
  type ListKeyboardNavigationInstance,
89
89
  setupListKeyboardNavigation,
90
90
  } from '@squirrel/utils/listKeyboardNavigation';
91
- import { type PropType, defineComponent } from 'vue';
91
+ import { defineComponent, type PropType } from 'vue';
92
92
 
93
93
  type VPopper = {
94
94
  $refs: {
@@ -1,9 +1,9 @@
1
- import PDropdownSelect from '@squirrel/components/p-dropdown-select/p-dropdown-select.vue';
2
1
  import filterListItems from '@squirrel/components/p-dropdown-select/p-dropdown-select.mock.json';
3
- import { cloneDeep } from 'lodash-es';
2
+ import PDropdownSelect from '@squirrel/components/p-dropdown-select/p-dropdown-select.vue';
3
+ import { useVirtualizer } from '@tanstack/vue-virtual';
4
4
  import { createWrapperFor, sleep, waitRAF } from '@tests/vitest.helpers';
5
+ import { cloneDeep } from 'lodash-es';
5
6
  import { ref } from 'vue';
6
- import { useVirtualizer } from '@tanstack/vue-virtual';
7
7
 
8
8
  vi.mock('@tanstack/vue-virtual', () => ({
9
9
  useVirtualizer: vi.fn(),
@@ -415,7 +415,7 @@ describe('PDropdownSelect.vue', () => {
415
415
  cleanup(wrapper);
416
416
  });
417
417
 
418
- it.each([true, false])('renders correctly when "multiple" is set to %s ', async (val) => {
418
+ it.each([true, false])('renders correctly when "multiple" is set to %s', async (val) => {
419
419
  const items = cloneDeep(filterListItems).slice(0, 20);
420
420
  const wrapper = createWrapper({ items }, { multiple: val });
421
421
 
@@ -1,7 +1,7 @@
1
- import PDropdownSelect from '@squirrel/components/p-dropdown-select/p-dropdown-select.vue';
1
+ import { fieldArgTypes } from '@root/stories/common/field';
2
2
  import filterListItems from '@squirrel/components/p-dropdown-select/p-dropdown-select.mock.json';
3
+ import PDropdownSelect from '@squirrel/components/p-dropdown-select/p-dropdown-select.vue';
3
4
  import { cloneDeep } from 'lodash-es';
4
- import { fieldArgTypes } from '@root/stories/common/field';
5
5
  import { ref } from 'vue';
6
6
 
7
7
  const items1 = filterListItems.slice(0, 999);
@@ -160,23 +160,23 @@
160
160
  import PDropdown from '@squirrel/components/p-dropdown/p-dropdown.vue';
161
161
  import PIcon from '@squirrel/components/p-icon/p-icon.vue';
162
162
  import PInputSearch from '@squirrel/components/p-input-search/p-input-search.vue';
163
+ import { type ModelValue, type Size, SIZES } from '@squirrel/components/p-select-list/p-select-list.types';
164
+ import { useSelectList } from '@squirrel/components/p-select-list/useSelectList';
165
+ import { useInputClasses } from '@squirrel/composables/useInputClasses';
166
+ import { toString } from '@squirrel/utils/string';
167
+ import { splitStringForHighlight } from '@squirrel/utils/text';
168
+ import { omit } from 'lodash-es';
163
169
  import {
164
170
  type ComponentPublicInstance,
165
- type PropType,
166
- type StyleValue,
167
171
  computed,
168
172
  onMounted,
169
173
  onUnmounted,
174
+ type PropType,
170
175
  ref,
176
+ type StyleValue,
171
177
  useAttrs,
172
178
  watch,
173
179
  } from 'vue';
174
- import { type ModelValue, SIZES, type Size } from '@squirrel/components/p-select-list/p-select-list.types';
175
- import { omit } from 'lodash-es';
176
- import { splitStringForHighlight } from '@squirrel/utils/text';
177
- import { toString } from '@squirrel/utils/string';
178
- import { useInputClasses } from '@squirrel/composables/useInputClasses';
179
- import { useSelectList } from '@squirrel/components/p-select-list/useSelectList';
180
180
 
181
181
  type AnyValue = string | number | boolean | null | undefined | Record<string, unknown>;
182
182
  type AnyObject = Record<string, AnyValue>;
@@ -70,10 +70,10 @@
70
70
 
71
71
  <script setup lang="ts">
72
72
  import { type FileUploadFile } from '@squirrel/components/p-file-upload/p-file-upload.types';
73
- import { type PropType, computed, onMounted, ref, shallowRef } from 'vue';
74
73
  import { formatBytes, getFileExtension } from '@squirrel/components/p-file-upload/p-file-upload.utils';
75
- import { uniq } from 'lodash-es';
76
74
  import { useInputClasses } from '@squirrel/composables/useInputClasses';
75
+ import { uniq } from 'lodash-es';
76
+ import { computed, onMounted, type PropType, ref, shallowRef } from 'vue';
77
77
  import { useToast } from 'vue-toastification';
78
78
 
79
79
  defineOptions({
@@ -1,5 +1,5 @@
1
- import PIcon from '@squirrel/components/p-icon/p-icon.vue';
2
1
  import { P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
2
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
3
3
  import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  const createWrapper = (props, attrs) => {
@@ -1,5 +1,5 @@
1
- import PIcon from '@squirrel/components/p-icon/p-icon.vue';
2
1
  import { P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
2
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
3
3
 
4
4
  export default {
5
5
  title: 'Components/PIcon',
@@ -3,9 +3,9 @@
3
3
  </template>
4
4
 
5
5
  <script setup lang="ts">
6
- import { type IconifyIconAttributes } from 'iconify-icon';
7
- import { type PIconAlias, P_ICON_ALIASES } from '@squirrel/components/p-icon/p-icon.types';
8
6
  import 'iconify-icon';
7
+ import { P_ICON_ALIASES, type PIconAlias } from '@squirrel/components/p-icon/p-icon.types';
8
+ import { type IconifyIconAttributes } from 'iconify-icon';
9
9
 
10
10
  defineOptions({
11
11
  name: 'PIcon',