@pequity/squirrel 5.2.2 → 5.2.3

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 (55) hide show
  1. package/dist/cjs/p-input-search.js +3 -2
  2. package/dist/cjs/p-modal.js +5 -2
  3. package/dist/es/p-input-search.js +3 -2
  4. package/dist/es/p-modal.js +5 -2
  5. package/dist/style.css +27 -27
  6. package/package.json +22 -27
  7. package/squirrel/components/p-action-bar/p-action-bar.spec.js +1 -1
  8. package/squirrel/components/p-alert/p-alert.spec.js +1 -1
  9. package/squirrel/components/p-avatar/p-avatar.spec.js +1 -1
  10. package/squirrel/components/p-btn/p-btn.spec.js +3 -7
  11. package/squirrel/components/p-card/p-card.spec.js +1 -1
  12. package/squirrel/components/p-checkbox/p-checkbox.spec.js +1 -1
  13. package/squirrel/components/p-chips/p-chips.spec.js +1 -1
  14. package/squirrel/components/p-close-btn/p-close-btn.spec.js +1 -1
  15. package/squirrel/components/p-dropdown/p-dropdown.spec.js +5 -9
  16. package/squirrel/components/p-dropdown-select/p-dropdown-select.spec.js +4 -5
  17. package/squirrel/components/p-file-upload/p-file-upload.spec.js +1 -1
  18. package/squirrel/components/p-icon/p-icon.spec.js +16 -29
  19. package/squirrel/components/p-info-icon/p-info-icon.spec.js +1 -1
  20. package/squirrel/components/p-inline-date-picker/p-inline-date-picker.spec.js +4 -4
  21. package/squirrel/components/p-input/p-input.spec.js +1 -1
  22. package/squirrel/components/p-input-number/p-input-number.spec.js +1 -1
  23. package/squirrel/components/p-input-percent/p-input-percent.spec.js +1 -1
  24. package/squirrel/components/p-input-search/p-input-search.spec.js +1 -1
  25. package/squirrel/components/p-input-search/p-input-search.vue +1 -1
  26. package/squirrel/components/p-link/p-link.spec.js +3 -7
  27. package/squirrel/components/p-loading/p-loading.spec.js +23 -23
  28. package/squirrel/components/p-modal/p-modal-basic.spec.js +1 -1
  29. package/squirrel/components/p-modal/p-modal-events.spec.js +1 -1
  30. package/squirrel/components/p-modal/p-modal-features.spec.js +1 -1
  31. package/squirrel/components/p-modal/p-modal.vue +4 -0
  32. package/squirrel/components/p-pagination/p-pagination.spec.js +1 -1
  33. package/squirrel/components/p-pagination-info/p-pagination-info.spec.js +1 -1
  34. package/squirrel/components/p-progress-bar/p-progess-bar.spec.js +1 -1
  35. package/squirrel/components/p-ring-loader/p-ring-loader.spec.js +1 -1
  36. package/squirrel/components/p-select/p-select.spec.js +1 -1
  37. package/squirrel/components/p-select-btn/p-select-btn.spec.js +1 -1
  38. package/squirrel/components/p-select-list/p-select-list.spec.js +4 -5
  39. package/squirrel/components/p-select-pill/p-select-pill.spec.js +1 -1
  40. package/squirrel/components/p-skeleton-loader/p-skeleton-loader.spec.js +1 -1
  41. package/squirrel/components/p-table/p-table.spec.js +1 -1
  42. package/squirrel/components/p-table-header-cell/p-filter-icon.spec.js +1 -1
  43. package/squirrel/components/p-table-header-cell/p-table-header-cell.spec.js +1 -1
  44. package/squirrel/components/p-table-loader/p-table-loader.spec.js +1 -1
  45. package/squirrel/components/p-table-sort/p-table-sort.spec.js +1 -1
  46. package/squirrel/components/p-table-td/p-table-td.spec.js +36 -1
  47. package/squirrel/components/p-tabs/p-tabs.spec.js +1 -1
  48. package/squirrel/components/p-textarea/p-textarea.spec.js +1 -1
  49. package/squirrel/components/p-toggle/p-toggle.spec.js +1 -1
  50. package/squirrel/composables/useInputClasses.spec.js +41 -0
  51. package/squirrel/index.spec.js +21 -0
  52. package/squirrel/utils/dom.spec.js +2 -3
  53. package/squirrel/utils/listKeyboardNavigation.spec.js +5 -9
  54. package/squirrel/utils/sanitization.spec.js +1 -1
  55. package/squirrel/utils/tailwind.spec.js +27 -0
@@ -1,5 +1,5 @@
1
1
  import PInput from '@squirrel/components/p-input/p-input.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PInput.vue', () => {
5
5
  it('renders correctly', async () => {
@@ -1,5 +1,5 @@
1
1
  import PInputNumber from '@squirrel/components/p-input-number/p-input-number.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  const baseClasses = () => [
5
5
  'text-night',
@@ -1,5 +1,5 @@
1
1
  import PInputPercent from '@squirrel/components/p-input-percent/p-input-percent.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  const prefixClasses = {
5
5
  sm: 'text-sm h-8 left-2',
@@ -1,5 +1,5 @@
1
1
  import PInputSearch from '@squirrel/components/p-input-search/p-input-search.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PInputSearch.vue', () => {
5
5
  it('renders correctly', async () => {
@@ -92,7 +92,7 @@ export default defineComponent({
92
92
  clearSearch() {
93
93
  this.query = '';
94
94
  requestAnimationFrame(() => {
95
- (this.$refs.searchInput as PInputInstance).$el.querySelector('input').focus();
95
+ (this.$refs.searchInput as PInputInstance)?.$el.querySelector('input').focus();
96
96
  });
97
97
  },
98
98
  keydownEnter() {
@@ -1,11 +1,11 @@
1
1
  import PLink from '@squirrel/components/p-link/p-link.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
  import { isExternalLink } from '@squirrel/utils/link';
4
4
  import { sanitizeUrl } from '@squirrel/utils/sanitization';
5
5
 
6
- jest.mock('@squirrel/utils/sanitization');
6
+ vi.mock('@squirrel/utils/sanitization');
7
7
 
8
- jest.mock('@squirrel/utils/link');
8
+ vi.mock('@squirrel/utils/link');
9
9
 
10
10
  const createWrapper = (props, attrs) => {
11
11
  return createWrapperFor(PLink, {
@@ -23,10 +23,6 @@ const createWrapper = (props, attrs) => {
23
23
  };
24
24
 
25
25
  describe('PLink.vue', () => {
26
- afterEach(() => {
27
- jest.clearAllMocks();
28
- });
29
-
30
26
  it('renders a router link when the link is internal', () => {
31
27
  isExternalLink.mockReturnValue(false);
32
28
 
@@ -1,6 +1,6 @@
1
1
  import PLoading from '@squirrel/components/p-loading/p-loading.vue';
2
2
  import PSkeletonLoader from '@squirrel/components/p-skeleton-loader/p-skeleton-loader.vue';
3
- import { createWrapperFor, waitNT } from '@tests/jest.helpers';
3
+ import { createWrapperFor, waitNT } from '@tests/vitest.helpers';
4
4
  import { defineComponent, ref } from 'vue';
5
5
  import { usePLoading } from '@squirrel/components/p-loading/usePLoading';
6
6
 
@@ -65,11 +65,11 @@ describe('PLoading.vue', () => {
65
65
  let appWrapper;
66
66
 
67
67
  beforeAll(() => {
68
- jest.useFakeTimers();
68
+ vi.useFakeTimers();
69
69
  });
70
70
 
71
71
  afterAll(() => {
72
- jest.useRealTimers();
72
+ vi.useRealTimers();
73
73
  });
74
74
 
75
75
  beforeEach(() => {
@@ -94,7 +94,7 @@ describe('PLoading.vue', () => {
94
94
  const wrapper = createWrapper({ delay: 1000 });
95
95
 
96
96
  await wrapper.find('.show').trigger('click');
97
- jest.advanceTimersByTime(500);
97
+ vi.advanceTimersByTime(500);
98
98
  await waitNT(appWrapper.vm);
99
99
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
100
100
  });
@@ -104,11 +104,11 @@ describe('PLoading.vue', () => {
104
104
 
105
105
  await wrapper.find('.request-1-sec').trigger('click');
106
106
 
107
- jest.advanceTimersByTime(500);
107
+ vi.advanceTimersByTime(500);
108
108
  await waitNT(appWrapper.vm);
109
109
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
110
110
 
111
- jest.advanceTimersByTime(1000);
111
+ vi.advanceTimersByTime(1000);
112
112
  await waitNT(appWrapper.vm);
113
113
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
114
114
  });
@@ -118,13 +118,13 @@ describe('PLoading.vue', () => {
118
118
 
119
119
  await wrapper.find('.request-1-sec').trigger('click');
120
120
 
121
- jest.advanceTimersByTime(500);
121
+ vi.advanceTimersByTime(500);
122
122
  await waitNT(appWrapper.vm);
123
123
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
124
124
 
125
125
  await wrapper.find('.request-3-secs').trigger('click');
126
126
 
127
- jest.advanceTimersByTime(500);
127
+ vi.advanceTimersByTime(500);
128
128
  await waitNT(appWrapper.vm);
129
129
 
130
130
  await wrapper.find('.hide').trigger('click');
@@ -136,17 +136,17 @@ describe('PLoading.vue', () => {
136
136
 
137
137
  await wrapper.find('.request-1-sec').trigger('click');
138
138
 
139
- jest.advanceTimersByTime(500);
139
+ vi.advanceTimersByTime(500);
140
140
  await waitNT(appWrapper.vm);
141
141
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
142
142
 
143
143
  await wrapper.find('.request-3-secs').trigger('click');
144
144
 
145
- jest.advanceTimersByTime(1000);
145
+ vi.advanceTimersByTime(1000);
146
146
  await waitNT(appWrapper.vm);
147
147
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
148
148
 
149
- jest.advanceTimersByTime(2000);
149
+ vi.advanceTimersByTime(2000);
150
150
  await waitNT(appWrapper.vm);
151
151
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
152
152
  });
@@ -156,13 +156,13 @@ describe('PLoading.vue', () => {
156
156
 
157
157
  await wrapper.find('.show').trigger('click');
158
158
 
159
- jest.advanceTimersByTime(500);
159
+ vi.advanceTimersByTime(500);
160
160
  await waitNT(appWrapper.vm);
161
161
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
162
162
 
163
163
  await wrapper.find('.show').trigger('click');
164
164
 
165
- jest.advanceTimersByTime(200);
165
+ vi.advanceTimersByTime(200);
166
166
  await waitNT(appWrapper.vm);
167
167
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
168
168
  });
@@ -172,21 +172,21 @@ describe('PLoading.vue', () => {
172
172
 
173
173
  await wrapper.find('.request-3-secs-text').trigger('click');
174
174
 
175
- jest.advanceTimersByTime(300);
175
+ vi.advanceTimersByTime(300);
176
176
  await waitNT(appWrapper.vm);
177
177
  expect(appWrapper.find('[aria-busy]').text()).toBe('3 secs');
178
178
 
179
179
  await wrapper.find('.request-1-sec-text').trigger('click');
180
180
 
181
- jest.advanceTimersByTime(300);
181
+ vi.advanceTimersByTime(300);
182
182
  await waitNT(appWrapper.vm);
183
183
  expect(appWrapper.find('[aria-busy]').text()).toBe('1 sec');
184
184
 
185
- jest.advanceTimersByTime(1200);
185
+ vi.advanceTimersByTime(1200);
186
186
  await waitNT(appWrapper.vm);
187
187
  expect(appWrapper.find('[aria-busy]').text()).toBe('3 secs');
188
188
 
189
- jest.advanceTimersByTime(1200);
189
+ vi.advanceTimersByTime(1200);
190
190
  await waitNT(appWrapper.vm);
191
191
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
192
192
  });
@@ -196,12 +196,12 @@ describe('PLoading.vue', () => {
196
196
 
197
197
  await wrapper.find('.request-1-sec-component').trigger('click');
198
198
 
199
- jest.advanceTimersByTime(300);
199
+ vi.advanceTimersByTime(300);
200
200
  await waitNT(appWrapper.vm);
201
201
  expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
202
202
  expect(appWrapper.findComponent(PSkeletonLoader).exists()).toBe(true);
203
203
 
204
- jest.advanceTimersByTime(800);
204
+ vi.advanceTimersByTime(800);
205
205
  await waitNT(appWrapper.vm);
206
206
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
207
207
  });
@@ -270,7 +270,7 @@ describe('PLoading.vue', () => {
270
270
 
271
271
  await wrapper.find('.request-1-sec-component-props').trigger('click');
272
272
 
273
- jest.advanceTimersByTime(300);
273
+ vi.advanceTimersByTime(300);
274
274
  await waitNT(appWrapper.vm);
275
275
  const getTestComponent = () => appWrapper.findComponent(TestComponent);
276
276
 
@@ -278,12 +278,12 @@ describe('PLoading.vue', () => {
278
278
  expect(getTestComponent().exists()).toBe(true);
279
279
  expect(getTestComponent().props().modelValue).toBe(10);
280
280
 
281
- jest.advanceTimersByTime(300);
281
+ vi.advanceTimersByTime(300);
282
282
  await waitNT(appWrapper.vm);
283
283
  await wrapper.find('.update-props').trigger('click');
284
284
  expect(getTestComponent().props().modelValue).toBe(20);
285
285
 
286
- jest.advanceTimersByTime(500);
286
+ vi.advanceTimersByTime(500);
287
287
  await waitNT(appWrapper.vm);
288
288
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
289
289
  });
@@ -293,7 +293,7 @@ describe('PLoading.vue', () => {
293
293
 
294
294
  await wrapper.find('.request-1-sec-component').trigger('click');
295
295
 
296
- jest.advanceTimersByTime(300);
296
+ vi.advanceTimersByTime(300);
297
297
  await waitNT(appWrapper.vm);
298
298
 
299
299
  expect(wrapper.vm.show).toBe(true);
@@ -1,6 +1,6 @@
1
1
  import PModal from '@squirrel/components/p-modal/p-modal.vue';
2
2
  import { mount } from '@vue/test-utils';
3
- import { waitRAF } from '@tests/jest.helpers';
3
+ import { waitRAF } from '@tests/vitest.helpers';
4
4
 
5
5
  const createWrapperContainer = (componentArgs) => {
6
6
  const args = componentArgs || {};
@@ -1,6 +1,6 @@
1
1
  import PModal from '@squirrel/components/p-modal/p-modal.vue';
2
2
  import { mount } from '@vue/test-utils';
3
- import { sleep, waitRAF } from '@tests/jest.helpers';
3
+ import { sleep, waitRAF } from '@tests/vitest.helpers';
4
4
 
5
5
  const createWrapper = () => {
6
6
  return mount(PModal, {
@@ -1,6 +1,6 @@
1
1
  import PModal from '@squirrel/components/p-modal/p-modal.vue';
2
2
  import { mount } from '@vue/test-utils';
3
- import { sleep, waitNT } from '@tests/jest.helpers';
3
+ import { sleep, waitNT } from '@tests/vitest.helpers';
4
4
 
5
5
  const originalOffsetHeight = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetHeight');
6
6
  const originalOffsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth');
@@ -277,6 +277,10 @@ const getTopZindex = () => {
277
277
  };
278
278
 
279
279
  const handleFocus = (wrapper: HTMLElement) => {
280
+ if (!wrapper) {
281
+ return;
282
+ }
283
+
280
284
  const autofocus = wrapper.querySelector('[autofocus]') as HTMLElement;
281
285
 
282
286
  if (autofocus) {
@@ -1,5 +1,5 @@
1
1
  import PPagination from '@squirrel/components/p-pagination/p-pagination.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PPagination.vue', () => {
5
5
  it('renders the controls correctly', async () => {
@@ -1,5 +1,5 @@
1
1
  import PPaginationInfo from '@squirrel/components/p-pagination-info/p-pagination-info.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PPaginationInfo.vue', () => {
5
5
  it.each([
@@ -1,5 +1,5 @@
1
1
  import PProgressBar from '@squirrel/components/p-progress-bar/p-progress-bar.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  const items = [
5
5
  { vaLue: 50, label: 'bar1', color: 'rgb(204, 204, 204)' },
@@ -1,5 +1,5 @@
1
1
  import PRingLoader from '@squirrel/components/p-ring-loader/p-ring-loader.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PRingLoader.vue', () => {
5
5
  it('renders correctly with custom props', async () => {
@@ -1,6 +1,6 @@
1
1
  import PSelect from '@squirrel/components/p-select/p-select.vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
- import { createWrapperFor, sleep, waitNT } from '@tests/jest.helpers';
3
+ import { createWrapperFor, sleep, waitNT } from '@tests/vitest.helpers';
4
4
 
5
5
  const baseClasses = () => [
6
6
  'text-night',
@@ -1,6 +1,6 @@
1
1
  import PSelectBtn from '@squirrel/components/p-select-btn/p-select-btn.vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
- import { createWrapperFor } from '@tests/jest.helpers';
3
+ import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  const items = [
6
6
  { textCustom: 'Option 1', valueCustom: 1 },
@@ -1,12 +1,12 @@
1
1
  import PSelectList from '@squirrel/components/p-select-list/p-select-list.vue';
2
2
  import filterListItems from '@squirrel/components/p-dropdown-select/p-dropdown-select.mock.json';
3
3
  import { cloneDeep } from 'lodash-es';
4
- import { createWrapperFor, sleep } from '@tests/jest.helpers';
4
+ import { createWrapperFor, sleep } from '@tests/vitest.helpers';
5
5
  import { ref } from 'vue';
6
6
  import { useVirtualizer } from '@tanstack/vue-virtual';
7
7
 
8
- jest.mock('@tanstack/vue-virtual', () => ({
9
- useVirtualizer: jest.fn(),
8
+ vi.mock('@tanstack/vue-virtual', () => ({
9
+ useVirtualizer: vi.fn(),
10
10
  }));
11
11
 
12
12
  const createMockedVirtualizer = (count) => {
@@ -67,13 +67,12 @@ const cleanup = async (wrapper) => {
67
67
 
68
68
  describe('PSelectList.vue', () => {
69
69
  beforeEach(() => {
70
- jest.spyOn(console, 'warn').mockImplementation(() => {});
70
+ vi.spyOn(console, 'warn').mockImplementation(() => {});
71
71
  });
72
72
 
73
73
  // When using `attachTo: document.body` we have to cleanup the DOM and call `wrapper.destroy()` after each test
74
74
  afterEach(() => {
75
75
  document.body.innerHTML = '';
76
- jest.clearAllMocks();
77
76
  });
78
77
 
79
78
  it('renders correctly', async () => {
@@ -1,5 +1,5 @@
1
1
  import PSelectPill from '@squirrel/components/p-select-pill/p-select-pill.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  const ACTIVE_CLASS = 'text-p-purple-60';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import PSkeletonLoader from '@squirrel/components/p-skeleton-loader/p-skeleton-loader.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PSkeletonLoader.vue', () => {
5
5
  it.each([
@@ -5,7 +5,7 @@ import {
5
5
  isFirstColFixedInjectionKey,
6
6
  isLastColFixedInjectionKey,
7
7
  } from '@squirrel/components/p-table/p-table.types';
8
- import { createWrapperFor } from '@tests/jest.helpers';
8
+ import { createWrapperFor } from '@tests/vitest.helpers';
9
9
  import { defineComponent, h, inject } from 'vue';
10
10
 
11
11
  const columns = [
@@ -1,5 +1,5 @@
1
1
  import PFilterIcon from '@squirrel/components/p-table-header-cell/p-table-filter-icon.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PFilterIcon.vue', () => {
5
5
  it('renders a filter icon', async () => {
@@ -1,6 +1,6 @@
1
1
  import PFilterIcon from '@squirrel/components/p-table-header-cell/p-table-filter-icon.vue';
2
2
  import PTableHeaderCell from '@squirrel/components/p-table-header-cell/p-table-header-cell.vue';
3
- import { createWrapperFor } from '@tests/jest.helpers';
3
+ import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  describe('PTableHeaderCell.vue', () => {
6
6
  it('renders correctly', async () => {
@@ -1,6 +1,6 @@
1
1
  import PTable from '@squirrel/components/p-table/p-table.vue';
2
2
  import PTableLoader from '@squirrel/components/p-table-loader/p-table-loader.vue';
3
- import { createWrapperFor } from '@tests/jest.helpers';
3
+ import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  describe('PTableLoader.vue', () => {
6
6
  it('matches the PTable classes', async () => {
@@ -1,6 +1,6 @@
1
1
  import PTableSort from '@squirrel/components/p-table-sort/p-table-sort.vue';
2
2
  import { SORTING_TYPES } from '@squirrel/components/p-table-sort/p-table-sort.config';
3
- import { createWrapperFor } from '@tests/jest.helpers';
3
+ import { createWrapperFor } from '@tests/vitest.helpers';
4
4
 
5
5
  describe('PTableSort.vue', () => {
6
6
  it('renders correctly', async () => {
@@ -1,10 +1,12 @@
1
1
  import PTableTd from '@squirrel/components/p-table-td/p-table-td.vue';
2
2
  import {
3
3
  colsInjectionKey,
4
+ isColsResizableInjectionKey,
4
5
  isFirstColFixedInjectionKey,
5
6
  isLastColFixedInjectionKey,
6
7
  } from '@squirrel/components/p-table/p-table.types';
7
- import { createWrapperFor } from '@tests/jest.helpers';
8
+ import { createWrapperFor } from '@tests/vitest.helpers';
9
+ import { expect } from 'vitest';
8
10
  import { ref } from 'vue';
9
11
 
10
12
  const DEFAULT_TD_CLASSES = [
@@ -23,6 +25,16 @@ const DEFAULT_TD_CLASSES = [
23
25
 
24
26
  const DEFAULT_INNER_DIV_CLASSES = ['w-max', 'px-2'];
25
27
 
28
+ const GRADIENT_TD_CLASSES = [
29
+ 'min-w-[80px]',
30
+ 'border-l',
31
+ 'border-p-gray-30',
32
+ 'bg-gradient-to-r',
33
+ 'from-white',
34
+ 'via-p-gray-10',
35
+ 'to-p-gray-10',
36
+ ];
37
+
26
38
  describe('PTableTd.vue', () => {
27
39
  it('renders a td', async () => {
28
40
  const wrapper = createWrapperFor(PTableTd, {
@@ -145,4 +157,27 @@ describe('PTableTd.vue', () => {
145
157
 
146
158
  expect([...innerDiv.classes()].sort()).toEqual(['w-max', 'pl-2', 'pr-4'].sort());
147
159
  });
160
+
161
+ it(`renders a td with a gradient when it's the last sticky column`, async () => {
162
+ const wrapper = createWrapperFor(PTableTd, {
163
+ props: { colIndex: 2, isEditable: true },
164
+ slots: { default: `Cell content` },
165
+ global: {
166
+ provide: {
167
+ [colsInjectionKey]: ref([{ id: 1 }, { id: 2 }, { id: 3 }]),
168
+ [isColsResizableInjectionKey]: ref(true),
169
+ [isLastColFixedInjectionKey]: ref(false),
170
+ },
171
+ },
172
+ });
173
+
174
+ const tds = wrapper.findAll('td');
175
+
176
+ expect(tds.length).toBe(2);
177
+
178
+ const gradientTd = tds[1];
179
+
180
+ expect(gradientTd.exists()).toBe(true);
181
+ expect(gradientTd.classes()).toEqual(GRADIENT_TD_CLASSES);
182
+ });
148
183
  });
@@ -1,5 +1,5 @@
1
1
  import PTabs from '@squirrel/components/p-tabs/p-tabs.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
  import { markRaw } from 'vue';
4
4
 
5
5
  const Tab1Icon = markRaw({ template: `<i data-icon="icon-tab1"></i>` });
@@ -1,5 +1,5 @@
1
1
  import PTextarea from '@squirrel/components/p-textarea/p-textarea.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PTextarea.vue', () => {
5
5
  it('renders correctly', async () => {
@@ -1,5 +1,5 @@
1
1
  import PToggle from '@squirrel/components/p-toggle/p-toggle.vue';
2
- import { createWrapperFor } from '@tests/jest.helpers';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
3
 
4
4
  describe('PToggle.vue', () => {
5
5
  it('renders correctly', async () => {
@@ -1,3 +1,4 @@
1
+ import { SPACING_LEFT, SPACING_PREFIX, SPACING_RIGHT, SPACING_SUFFIX } from '@squirrel/utils/inputClassesShared';
1
2
  import { reactive } from 'vue';
2
3
  import { useInputClasses } from '@squirrel/composables/useInputClasses';
3
4
 
@@ -164,4 +165,44 @@ describe('useInputClasses', () => {
164
165
  );
165
166
  expect(errorMsgClasses.value).toBe('text-xs text-on-error mt-1');
166
167
  });
168
+
169
+ it('should apply the SPACING_PREFIX when prefix is true', () => {
170
+ const props = reactive({
171
+ size: 'md',
172
+ prefix: true,
173
+ });
174
+ const { inputClasses } = useInputClasses(props);
175
+
176
+ expect(inputClasses.value).toContain(SPACING_PREFIX.md);
177
+ });
178
+
179
+ it('should apply the SPACING_SUFFIX when suffix is true', () => {
180
+ const props = reactive({
181
+ size: 'md',
182
+ suffix: true,
183
+ });
184
+ const { inputClasses } = useInputClasses(props);
185
+
186
+ expect(inputClasses.value).toContain(SPACING_SUFFIX.md);
187
+ });
188
+
189
+ it('should apply SPACING_LEFT when prefix is false', () => {
190
+ const props = reactive({
191
+ size: 'md',
192
+ prefix: false,
193
+ });
194
+ const { inputClasses } = useInputClasses(props);
195
+
196
+ expect(inputClasses.value).toContain(SPACING_LEFT.md);
197
+ });
198
+
199
+ it('should apply SPACING_RIGHT when suffix is false', () => {
200
+ const props = reactive({
201
+ size: 'md',
202
+ suffix: false,
203
+ });
204
+ const { inputClasses } = useInputClasses(props);
205
+
206
+ expect(inputClasses.value).toContain(SPACING_RIGHT.md);
207
+ });
167
208
  });
@@ -0,0 +1,21 @@
1
+ describe('index.ts module exports', () => {
2
+ it('should export from @squirrel/tailwind/config', async () => {
3
+ const config = await import('@squirrel/tailwind/config');
4
+ expect(config).toBeDefined();
5
+ });
6
+
7
+ it('should export from @squirrel/components', async () => {
8
+ const components = await import('@squirrel/components');
9
+ expect(components).toBeDefined();
10
+ });
11
+
12
+ it('should export from @squirrel/composables', async () => {
13
+ const composables = await import('@squirrel/composables');
14
+ expect(composables).toBeDefined();
15
+ });
16
+
17
+ it('should export from @squirrel/utils', async () => {
18
+ const utils = await import('@squirrel/utils');
19
+ expect(utils).toBeDefined();
20
+ });
21
+ });
@@ -6,13 +6,12 @@ describe('isVisible', () => {
6
6
  beforeEach(() => {
7
7
  element = document.createElement('div');
8
8
  // Simulate element dimensions since jsdom doesn't support layout
9
- jest.spyOn(element, 'offsetWidth', 'get').mockImplementation(() => 100);
10
- jest.spyOn(element, 'offsetHeight', 'get').mockImplementation(() => 100);
9
+ vi.spyOn(element, 'offsetWidth', 'get').mockImplementation(() => 100);
10
+ vi.spyOn(element, 'offsetHeight', 'get').mockImplementation(() => 100);
11
11
  });
12
12
 
13
13
  afterEach(() => {
14
14
  element = null;
15
- jest.clearAllMocks();
16
15
  });
17
16
 
18
17
  it('throws an error when no element is provided', () => {
@@ -53,20 +53,16 @@ describe('listKeyboardNavigation', () => {
53
53
  };
54
54
 
55
55
  it('initializes correctly', () => {
56
- document.addEventListener = jest.fn().mockImplementationOnce();
56
+ document.addEventListener = vi.fn().mockImplementationOnce();
57
57
 
58
58
  const navigationSvc = createTestSvc();
59
59
 
60
60
  navigationSvc.init();
61
61
 
62
- expect(navigationSvc).toHaveProperty(
63
- 'getItems',
64
- 'getFocusedItem',
65
- 'clearFocusedState',
66
- 'setFocusedItem',
67
- 'listKeydown',
68
- 'init',
69
- 'destroy'
62
+ ['getItems', 'getFocusedItem', 'clearFocusedState', 'setFocusedItem', 'listKeydown', 'init', 'destroy'].forEach(
63
+ (method) => {
64
+ expect(navigationSvc).toHaveProperty(method);
65
+ }
70
66
  );
71
67
 
72
68
  expect(document.addEventListener).toBeCalledWith('keydown', navigationSvc.listKeydown);
@@ -1,7 +1,7 @@
1
1
  import { sanitizeUrl } from '@squirrel/utils/sanitization';
2
2
 
3
3
  describe('sanitizeUrl', () => {
4
- const consoleMock = jest.spyOn(console, 'warn').mockImplementation(() => undefined);
4
+ const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
5
5
 
6
6
  afterAll(() => {
7
7
  consoleMock.mockReset();