@pequity/squirrel 2.0.0 → 3.0.1
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/dist/cjs/p-loading.js +5 -2
- package/dist/cjs/usePLoading.js +11 -16
- package/dist/es/p-loading.js +5 -2
- package/dist/es/usePLoading.js +11 -16
- package/dist/squirrel/components/p-loading/usePLoading.d.ts +6 -2
- package/dist/style.css +6 -6
- package/package.json +24 -24
- package/squirrel/components/p-loading/p-loading.spec.js +55 -12
- package/squirrel/components/p-loading/p-loading.stories.js +13 -10
- package/squirrel/components/p-loading/p-loading.vue +5 -2
- package/squirrel/components/p-loading/usePLoading.ts +18 -25
package/dist/cjs/p-loading.js
CHANGED
|
@@ -30,7 +30,10 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
30
30
|
},
|
|
31
31
|
{ flush: "post" }
|
|
32
32
|
);
|
|
33
|
-
const isComponent = (content2) =>
|
|
33
|
+
const isComponent = (content2) => {
|
|
34
|
+
const isComponent2 = typeof content2 === "object" && content2 !== null;
|
|
35
|
+
return isComponent2;
|
|
36
|
+
};
|
|
34
37
|
return (_ctx, _cache) => {
|
|
35
38
|
return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
|
|
36
39
|
vue.createVNode(vue.Transition, {
|
|
@@ -67,5 +70,5 @@ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
|
|
|
67
70
|
};
|
|
68
71
|
}
|
|
69
72
|
});
|
|
70
|
-
const pLoading = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
73
|
+
const pLoading = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-8c0c66ab"]]);
|
|
71
74
|
module.exports = pLoading;
|
package/dist/cjs/usePLoading.js
CHANGED
|
@@ -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 = (
|
|
17
|
-
|
|
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:
|
|
27
|
-
content:
|
|
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
|
-
|
|
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) {
|
package/dist/es/p-loading.js
CHANGED
|
@@ -29,7 +29,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
29
29
|
},
|
|
30
30
|
{ flush: "post" }
|
|
31
31
|
);
|
|
32
|
-
const isComponent = (content2) =>
|
|
32
|
+
const isComponent = (content2) => {
|
|
33
|
+
const isComponent2 = typeof content2 === "object" && content2 !== null;
|
|
34
|
+
return isComponent2;
|
|
35
|
+
};
|
|
33
36
|
return (_ctx, _cache) => {
|
|
34
37
|
return openBlock(), createElementBlock(Fragment, null, [
|
|
35
38
|
createVNode(Transition, {
|
|
@@ -66,7 +69,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
66
69
|
};
|
|
67
70
|
}
|
|
68
71
|
});
|
|
69
|
-
const pLoading = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
72
|
+
const pLoading = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-8c0c66ab"]]);
|
|
70
73
|
export {
|
|
71
74
|
pLoading as default
|
|
72
75
|
};
|
package/dist/es/usePLoading.js
CHANGED
|
@@ -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 = (
|
|
15
|
-
|
|
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:
|
|
25
|
-
content:
|
|
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
|
-
|
|
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: (
|
|
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/dist/style.css
CHANGED
|
@@ -381,12 +381,12 @@ from {
|
|
|
381
381
|
to {
|
|
382
382
|
opacity: 0;
|
|
383
383
|
}
|
|
384
|
-
}.fadeInDown[data-v-
|
|
384
|
+
}.fadeInDown[data-v-8c0c66ab] {
|
|
385
385
|
animation-duration: 0.4s;
|
|
386
386
|
animation-fill-mode: both;
|
|
387
|
-
animation-name: fadeInDown-
|
|
387
|
+
animation-name: fadeInDown-8c0c66ab;
|
|
388
388
|
}
|
|
389
|
-
@keyframes fadeInDown-
|
|
389
|
+
@keyframes fadeInDown-8c0c66ab {
|
|
390
390
|
0% {
|
|
391
391
|
opacity: 0;
|
|
392
392
|
transform: translate3d(0, -100%, 0);
|
|
@@ -396,12 +396,12 @@ to {
|
|
|
396
396
|
transform: none;
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
.fadeOutUp[data-v-
|
|
399
|
+
.fadeOutUp[data-v-8c0c66ab] {
|
|
400
400
|
animation-duration: 0.25s;
|
|
401
401
|
animation-fill-mode: both;
|
|
402
|
-
animation-name: fadeOutUp-
|
|
402
|
+
animation-name: fadeOutUp-8c0c66ab;
|
|
403
403
|
}
|
|
404
|
-
@keyframes fadeOutUp-
|
|
404
|
+
@keyframes fadeOutUp-8c0c66ab {
|
|
405
405
|
0% {
|
|
406
406
|
opacity: 1;
|
|
407
407
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pequity/squirrel",
|
|
3
3
|
"description": "Squirrel component library",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.1",
|
|
5
5
|
"packageManager": "pnpm@8.9.2",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
@@ -50,34 +50,34 @@
|
|
|
50
50
|
"vue-toastification": "^2.0.0-rc.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@babel/core": "^7.24.
|
|
54
|
-
"@babel/preset-env": "^7.24.
|
|
53
|
+
"@babel/core": "^7.24.9",
|
|
54
|
+
"@babel/preset-env": "^7.24.8",
|
|
55
55
|
"@commitlint/cli": "^19.3.0",
|
|
56
56
|
"@commitlint/config-conventional": "^19.2.2",
|
|
57
57
|
"@pequity/eslint-config": "^0.0.13",
|
|
58
58
|
"@popperjs/core": "2.11.8",
|
|
59
59
|
"@semantic-release/changelog": "^6.0.3",
|
|
60
60
|
"@semantic-release/git": "^10.0.1",
|
|
61
|
-
"@storybook/addon-a11y": "^8.
|
|
62
|
-
"@storybook/addon-actions": "^8.
|
|
63
|
-
"@storybook/addon-essentials": "^8.
|
|
64
|
-
"@storybook/addon-interactions": "^8.
|
|
65
|
-
"@storybook/addon-links": "^8.
|
|
66
|
-
"@storybook/blocks": "^8.
|
|
61
|
+
"@storybook/addon-a11y": "^8.2.4",
|
|
62
|
+
"@storybook/addon-actions": "^8.2.4",
|
|
63
|
+
"@storybook/addon-essentials": "^8.2.4",
|
|
64
|
+
"@storybook/addon-interactions": "^8.2.4",
|
|
65
|
+
"@storybook/addon-links": "^8.2.4",
|
|
66
|
+
"@storybook/blocks": "^8.2.4",
|
|
67
67
|
"@storybook/jest": "^0.2.3",
|
|
68
|
-
"@storybook/manager-api": "^8.
|
|
69
|
-
"@storybook/test-runner": "^0.19.
|
|
68
|
+
"@storybook/manager-api": "^8.2.4",
|
|
69
|
+
"@storybook/test-runner": "^0.19.1",
|
|
70
70
|
"@storybook/testing-library": "^0.2.2",
|
|
71
|
-
"@storybook/theming": "^8.
|
|
72
|
-
"@storybook/vue3": "^8.
|
|
73
|
-
"@storybook/vue3-vite": "^8.
|
|
74
|
-
"@tanstack/vue-virtual": "3.8.
|
|
71
|
+
"@storybook/theming": "^8.2.4",
|
|
72
|
+
"@storybook/vue3": "^8.2.4",
|
|
73
|
+
"@storybook/vue3-vite": "^8.2.4",
|
|
74
|
+
"@tanstack/vue-virtual": "3.8.3",
|
|
75
75
|
"@types/jest": "^29.5.12",
|
|
76
76
|
"@types/jsdom": "^21.1.7",
|
|
77
77
|
"@types/lodash-es": "^4.17.12",
|
|
78
|
-
"@types/node": "^20.14.
|
|
78
|
+
"@types/node": "^20.14.11",
|
|
79
79
|
"@vitejs/plugin-vue": "^5.0.5",
|
|
80
|
-
"@vue/compiler-sfc": "3.4.
|
|
80
|
+
"@vue/compiler-sfc": "3.4.32",
|
|
81
81
|
"@vue/test-utils": "^2.4.6",
|
|
82
82
|
"@vue/vue3-jest": "^29.2.6",
|
|
83
83
|
"autoprefixer": "^10.4.19",
|
|
@@ -94,20 +94,20 @@
|
|
|
94
94
|
"lodash-es": "4.17.21",
|
|
95
95
|
"make-coverage-badge": "^1.2.0",
|
|
96
96
|
"postcss": "^8.4.39",
|
|
97
|
-
"prettier": "^3.3.
|
|
97
|
+
"prettier": "^3.3.3",
|
|
98
98
|
"prettier-plugin-tailwindcss": "^0.6.5",
|
|
99
99
|
"resolve-tspaths": "^0.8.19",
|
|
100
100
|
"rimraf": "^5.0.8",
|
|
101
|
-
"sass": "^1.77.
|
|
101
|
+
"sass": "^1.77.8",
|
|
102
102
|
"semantic-release": "^24.0.0",
|
|
103
|
-
"storybook": "^8.
|
|
103
|
+
"storybook": "^8.2.4",
|
|
104
104
|
"svgo": "^3.3.2",
|
|
105
|
-
"tailwindcss": "^3.4.
|
|
106
|
-
"ts-jest": "^29.
|
|
105
|
+
"tailwindcss": "^3.4.6",
|
|
106
|
+
"ts-jest": "^29.2.2",
|
|
107
107
|
"typescript": "5.5.3",
|
|
108
108
|
"v-calendar": "3.1.2",
|
|
109
|
-
"vite": "^5.3.
|
|
110
|
-
"vue": "3.4.
|
|
109
|
+
"vite": "^5.3.4",
|
|
110
|
+
"vue": "3.4.32",
|
|
111
111
|
"vue-currency-input": "3.1.0",
|
|
112
112
|
"vue-router": "4.4.0",
|
|
113
113
|
"vue-toastification": "2.0.0-rc.5",
|
|
@@ -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,
|
|
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="
|
|
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="
|
|
21
|
-
<button class="request-3-secs-text" @click="
|
|
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
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
43
|
+
const id = `component-${time}`;
|
|
44
|
+
loadingShow({ id, content: PSkeletonLoader });
|
|
35
45
|
await new Promise((resolve) => setTimeout(resolve, time));
|
|
36
|
-
|
|
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
|
|
30
|
+
const id = `default-${time}`;
|
|
31
|
+
loadingShow({ id });
|
|
31
32
|
await new Promise((resolve) => setTimeout(resolve, time));
|
|
32
|
-
|
|
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,
|
|
59
|
-
const
|
|
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
|
-
|
|
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
|
|
89
|
+
const id = `component-${time}`;
|
|
90
|
+
loadingShow({ id, content: ComputationStatus });
|
|
88
91
|
await new Promise((resolve) => setTimeout(resolve, time));
|
|
89
|
-
|
|
92
|
+
loadingHide(id);
|
|
90
93
|
};
|
|
91
94
|
|
|
92
95
|
return { args, loadingShow, fireRequestComponent };
|
|
@@ -40,8 +40,11 @@ watch(
|
|
|
40
40
|
{ flush: 'post' }
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
const isComponent = (content: unknown): content is Component =>
|
|
44
|
-
typeof content === 'object' && content !== null
|
|
43
|
+
const isComponent = (content: unknown): content is Component => {
|
|
44
|
+
const isComponent = typeof content === 'object' && content !== null;
|
|
45
|
+
|
|
46
|
+
return isComponent;
|
|
47
|
+
};
|
|
45
48
|
</script>
|
|
46
49
|
|
|
47
50
|
<style scoped lang="scss">
|
|
@@ -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
|
|
11
|
+
content?: Content;
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
type UsePLoading = {
|
|
16
15
|
show: Ref<boolean>;
|
|
17
16
|
content: Content;
|
|
18
|
-
loadingShow: (
|
|
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 = (
|
|
35
|
-
|
|
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:
|
|
47
|
-
content:
|
|
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
|
-
|
|
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
|
|