@pequity/squirrel 2.0.0 → 3.0.0

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.
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("vue");
4
- const lodashEs = require("lodash-es");
5
4
  const LOADING_TEXT = "Loading...";
6
5
  const show = vue.ref(false);
7
6
  const loadingItems = vue.ref([]);
@@ -13,8 +12,10 @@ let timer;
13
12
  const usePLoading = (options) => {
14
13
  const { delay } = { delay: 200, ...options };
15
14
  const scope = vue.getCurrentScope();
16
- const loadingShow = (content2) => {
17
- const loadingId = lodashEs.uniqueId();
15
+ const loadingShow = (loadingItem) => {
16
+ if (!loadingItem.id) {
17
+ throw new Error("id is required");
18
+ }
18
19
  if (loadingItems.value.length === 0 && delay > 0) {
19
20
  timer = setTimeout(() => {
20
21
  show.value = true;
@@ -23,21 +24,15 @@ const usePLoading = (options) => {
23
24
  show.value = true;
24
25
  }
25
26
  loadingItems.value.push({
26
- id: loadingId,
27
- content: content2 && typeof content2 === "object" ? vue.markRaw(content2) : content2 || LOADING_TEXT
27
+ id: loadingItem.id,
28
+ content: loadingItem.content && typeof loadingItem.content === "object" ? vue.markRaw(loadingItem.content) : loadingItem.content || LOADING_TEXT
28
29
  });
29
- const hide = () => {
30
- loadingItems.value = loadingItems.value.filter((item) => item.id !== loadingId);
31
- clearTimeout(timer);
32
- if (loadingItems.value.length === 0) {
33
- show.value = false;
34
- }
35
- };
36
- return hide;
37
30
  };
38
- const loadingHide = () => {
39
- loadingItems.value = [];
40
- show.value = false;
31
+ const loadingHide = (id) => {
32
+ loadingItems.value = id && typeof id === "string" ? loadingItems.value.filter((item) => item.id !== id) : [];
33
+ if (loadingItems.value.length === 0) {
34
+ show.value = false;
35
+ }
41
36
  clearTimeout(timer);
42
37
  };
43
38
  if (scope) {
@@ -1,5 +1,4 @@
1
1
  import { ref, computed, getCurrentScope, onScopeDispose, markRaw } from "vue";
2
- import { uniqueId } from "lodash-es";
3
2
  const LOADING_TEXT = "Loading...";
4
3
  const show = ref(false);
5
4
  const loadingItems = ref([]);
@@ -11,8 +10,10 @@ let timer;
11
10
  const usePLoading = (options) => {
12
11
  const { delay } = { delay: 200, ...options };
13
12
  const scope = getCurrentScope();
14
- const loadingShow = (content2) => {
15
- const loadingId = uniqueId();
13
+ const loadingShow = (loadingItem) => {
14
+ if (!loadingItem.id) {
15
+ throw new Error("id is required");
16
+ }
16
17
  if (loadingItems.value.length === 0 && delay > 0) {
17
18
  timer = setTimeout(() => {
18
19
  show.value = true;
@@ -21,21 +22,15 @@ const usePLoading = (options) => {
21
22
  show.value = true;
22
23
  }
23
24
  loadingItems.value.push({
24
- id: loadingId,
25
- content: content2 && typeof content2 === "object" ? markRaw(content2) : content2 || LOADING_TEXT
25
+ id: loadingItem.id,
26
+ content: loadingItem.content && typeof loadingItem.content === "object" ? markRaw(loadingItem.content) : loadingItem.content || LOADING_TEXT
26
27
  });
27
- const hide = () => {
28
- loadingItems.value = loadingItems.value.filter((item) => item.id !== loadingId);
29
- clearTimeout(timer);
30
- if (loadingItems.value.length === 0) {
31
- show.value = false;
32
- }
33
- };
34
- return hide;
35
28
  };
36
- const loadingHide = () => {
37
- loadingItems.value = [];
38
- show.value = false;
29
+ const loadingHide = (id) => {
30
+ loadingItems.value = id && typeof id === "string" ? loadingItems.value.filter((item) => item.id !== id) : [];
31
+ if (loadingItems.value.length === 0) {
32
+ show.value = false;
33
+ }
39
34
  clearTimeout(timer);
40
35
  };
41
36
  if (scope) {
@@ -3,11 +3,15 @@ type Options = {
3
3
  delay?: number;
4
4
  };
5
5
  type Content = string | Component;
6
+ type LoadingItem = {
7
+ id: string;
8
+ content?: Content;
9
+ };
6
10
  type UsePLoading = {
7
11
  show: Ref<boolean>;
8
12
  content: Content;
9
- loadingShow: (content?: Content) => () => void;
10
- loadingHide: () => void;
13
+ loadingShow: (loadingItem: LoadingItem) => void;
14
+ loadingHide: (id: LoadingItem['id']) => void;
11
15
  };
12
16
  export declare const usePLoading: (options?: Options) => UsePLoading;
13
17
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pequity/squirrel",
3
3
  "description": "Squirrel component library",
4
- "version": "2.0.0",
4
+ "version": "3.0.0",
5
5
  "packageManager": "pnpm@8.9.2",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -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, sleep, waitNT } from '@tests/jest.helpers';
3
+ import { createWrapperFor, waitNT } from '@tests/jest.helpers';
4
4
  import { usePLoading } from '@squirrel/components/p-loading/usePLoading';
5
5
 
6
6
  const createAppWrapper = () =>
@@ -13,30 +13,40 @@ const createWrapper = (options) => {
13
13
  return createWrapperFor(
14
14
  {
15
15
  template: `
16
- <button class="show" @click="loadingShow"></button>
17
- <button class="hide" @click="loadingHide"></button>
16
+ <button class="show-without-id-should-error" @click="loadingShow({content: 'test'})"></button>
17
+ <button class="show" @click="loadingShow({id: 'default'})"></button>
18
+ <button class="hide" @click="loadingHide({id: 'default'})"></button>
18
19
  <button class="request-1-sec" @click="fireRequest(1000)"></button>
19
20
  <button class="request-3-secs" @click="fireRequest(3000)"></button>
20
- <button class="request-1-sec-text" @click="fireRequest(1000, '1 sec')"></button>
21
- <button class="request-3-secs-text" @click="fireRequest(3000, '3 secs')"></button>
21
+ <button class="request-1-sec-text" @click="fireRequestText(1000, '1 sec')"></button>
22
+ <button class="request-3-secs-text" @click="fireRequestText(3000, '3 secs')"></button>
22
23
  <button class="request-1-sec-component" @click="fireRequestComponent(1000)"></button>
23
24
  `,
24
25
  setup() {
25
26
  const { loadingShow, loadingHide } = usePLoading(options);
26
27
 
27
- const fireRequest = async (time, text) => {
28
- const hide = loadingShow(text);
29
- await sleep(time);
30
- hide();
28
+ const fireRequest = async (time) => {
29
+ const id = `default-${time}`;
30
+ loadingShow({ id });
31
+ await new Promise((resolve) => setTimeout(resolve, time));
32
+ loadingHide(id);
33
+ };
34
+
35
+ const fireRequestText = async (time, message) => {
36
+ const id = `text-${time}`;
37
+ loadingShow({ id, content: message });
38
+ await new Promise((resolve) => setTimeout(resolve, time));
39
+ loadingHide(id);
31
40
  };
32
41
 
33
42
  const fireRequestComponent = async (time) => {
34
- const hide = loadingShow(PSkeletonLoader);
43
+ const id = `component-${time}`;
44
+ loadingShow({ id, content: PSkeletonLoader });
35
45
  await new Promise((resolve) => setTimeout(resolve, time));
36
- hide();
46
+ loadingHide(id);
37
47
  };
38
48
 
39
- return { loadingShow, loadingHide, fireRequest, fireRequestComponent };
49
+ return { loadingShow, loadingHide, fireRequest, fireRequestText, fireRequestComponent };
40
50
  },
41
51
  },
42
52
  {
@@ -101,6 +111,24 @@ describe('PLoading.vue', () => {
101
111
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
102
112
  });
103
113
 
114
+ it(`hides all loading indicators when loadingHide gets called without an id`, async () => {
115
+ const wrapper = createWrapper({ delay: 200 });
116
+
117
+ await wrapper.find('.request-1-sec').trigger('click');
118
+
119
+ jest.advanceTimersByTime(500);
120
+ await waitNT(appWrapper.vm);
121
+ expect(appWrapper.find('[aria-busy]').exists()).toBe(true);
122
+
123
+ await wrapper.find('.request-3-secs').trigger('click');
124
+
125
+ jest.advanceTimersByTime(500);
126
+ await waitNT(appWrapper.vm);
127
+
128
+ await wrapper.find('.hide').trigger('click');
129
+ expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
130
+ });
131
+
104
132
  it(`it waits for the queue to clear in order to hide the loading indicator`, async () => {
105
133
  const wrapper = createWrapper({ delay: 200 });
106
134
 
@@ -175,4 +203,19 @@ describe('PLoading.vue', () => {
175
203
  await waitNT(appWrapper.vm);
176
204
  expect(appWrapper.find('[aria-busy]').exists()).toBe(false);
177
205
  });
206
+
207
+ it(`throws an error when loadingShow gets called without an id`, async () => {
208
+ expect(() => {
209
+ createWrapperFor({
210
+ template: `<div></div>`,
211
+ setup() {
212
+ const { loadingShow } = usePLoading({ delay: 200 });
213
+
214
+ loadingShow({ content: 'test' });
215
+
216
+ return { loadingShow };
217
+ },
218
+ });
219
+ }).toThrowError('id is required');
220
+ });
178
221
  });
@@ -24,12 +24,13 @@ export const Default = {
24
24
  render: (args) => ({
25
25
  components: { PLoading, PBtn },
26
26
  setup() {
27
- const { loadingShow } = usePLoading();
27
+ const { loadingShow, loadingHide } = usePLoading();
28
28
 
29
29
  const fireRequest = async (time) => {
30
- const hide = loadingShow();
30
+ const id = `default-${time}`;
31
+ loadingShow({ id });
31
32
  await new Promise((resolve) => setTimeout(resolve, time));
32
- hide();
33
+ loadingHide(id);
33
34
  };
34
35
 
35
36
  return { args, loadingShow, fireRequest };
@@ -53,12 +54,13 @@ export const WithVariableText = {
53
54
  render: (args) => ({
54
55
  components: { PLoading, PBtn },
55
56
  setup() {
56
- const { loadingShow } = usePLoading();
57
+ const { loadingShow, loadingHide } = usePLoading();
57
58
 
58
- const fireRequestText = async (time, text) => {
59
- const hide = loadingShow(text);
59
+ const fireRequestText = async (time, message) => {
60
+ const id = `text-${time}`;
61
+ loadingShow({ id, content: message });
60
62
  await new Promise((resolve) => setTimeout(resolve, time));
61
- hide();
63
+ loadingHide(id);
62
64
  };
63
65
 
64
66
  return { args, loadingShow, fireRequestText };
@@ -81,12 +83,13 @@ export const WithComponentAsContent = {
81
83
  render: (args) => ({
82
84
  components: { PLoading, PBtn },
83
85
  setup() {
84
- const { loadingShow } = usePLoading();
86
+ const { loadingShow, loadingHide } = usePLoading();
85
87
 
86
88
  const fireRequestComponent = async (time) => {
87
- const hide = loadingShow(ComputationStatus);
89
+ const id = `component-${time}`;
90
+ loadingShow({ id, content: ComputationStatus });
88
91
  await new Promise((resolve) => setTimeout(resolve, time));
89
- hide();
92
+ loadingHide(id);
90
93
  };
91
94
 
92
95
  return { args, loadingShow, fireRequestComponent };
@@ -1,5 +1,4 @@
1
1
  import { type Component, type Ref, computed, getCurrentScope, markRaw, onScopeDispose, ref } from 'vue';
2
- import { uniqueId } from 'lodash-es';
3
2
 
4
3
  type Options = {
5
4
  delay?: number;
@@ -9,30 +8,30 @@ type Content = string | Component;
9
8
 
10
9
  type LoadingItem = {
11
10
  id: string;
12
- content: Content;
11
+ content?: Content;
13
12
  };
14
13
 
15
14
  type UsePLoading = {
16
15
  show: Ref<boolean>;
17
16
  content: Content;
18
- loadingShow: (content?: Content) => () => void;
19
- loadingHide: () => void;
17
+ loadingShow: (loadingItem: LoadingItem) => void;
18
+ loadingHide: (id: LoadingItem['id']) => void;
20
19
  };
21
20
 
22
21
  const LOADING_TEXT = 'Loading...';
23
22
  const show = ref(false);
24
23
  const loadingItems = ref<LoadingItem[]>([]);
25
- const content = computed(() => {
26
- return loadingItems.value[loadingItems.value.length - 1]?.content;
27
- });
24
+ const content = computed(() => loadingItems.value[loadingItems.value.length - 1]?.content);
28
25
  let timer: ReturnType<typeof setTimeout>;
29
26
 
30
27
  export const usePLoading = (options?: Options): UsePLoading => {
31
28
  const { delay } = { delay: 200, ...options };
32
29
  const scope = getCurrentScope();
33
30
 
34
- const loadingShow = (content?: Content) => {
35
- const loadingId = uniqueId();
31
+ const loadingShow = (loadingItem: LoadingItem) => {
32
+ if (!loadingItem.id) {
33
+ throw new Error('id is required');
34
+ }
36
35
 
37
36
  if (loadingItems.value.length === 0 && delay > 0) {
38
37
  timer = setTimeout(() => {
@@ -43,25 +42,19 @@ export const usePLoading = (options?: Options): UsePLoading => {
43
42
  }
44
43
 
45
44
  loadingItems.value.push({
46
- id: loadingId,
47
- content: content && typeof content === 'object' ? markRaw(content) : content || LOADING_TEXT,
45
+ id: loadingItem.id,
46
+ content:
47
+ loadingItem.content && typeof loadingItem.content === 'object'
48
+ ? markRaw(loadingItem.content)
49
+ : loadingItem.content || LOADING_TEXT,
48
50
  });
49
-
50
- const hide = () => {
51
- loadingItems.value = loadingItems.value.filter((item) => item.id !== loadingId);
52
- clearTimeout(timer);
53
-
54
- if (loadingItems.value.length === 0) {
55
- show.value = false;
56
- }
57
- };
58
-
59
- return hide;
60
51
  };
61
52
 
62
- const loadingHide = () => {
63
- loadingItems.value = [];
64
- show.value = false;
53
+ const loadingHide = (id?: LoadingItem['id']) => {
54
+ loadingItems.value = id && typeof id === 'string' ? loadingItems.value.filter((item) => item.id !== id) : [];
55
+ if (loadingItems.value.length === 0) {
56
+ show.value = false;
57
+ }
65
58
  clearTimeout(timer);
66
59
  };
67
60