Skip to content
This repository was archived by the owner on Oct 20, 2025. It is now read-only.

Commit 782b925

Browse files
authored
Progress bar (#41)
1 parent 944c566 commit 782b925

File tree

9 files changed

+200
-37
lines changed

9 files changed

+200
-37
lines changed

app/package-lock.json

Lines changed: 28 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/resources/js/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ createApp({
2020
.use(SpladePlugin, {
2121
"max_keep_alive": 10,
2222
"transform_anchors": false,
23+
"progress_bar": true
2324
})
2425
.mount(el);

lib/Splade.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,21 @@ function restore(key, useLocalStorage) {
289289

290290
//
291291

292+
function fireEvent(name, data) {
293+
if (isSsr) {
294+
return;
295+
}
296+
297+
document.dispatchEvent(new CustomEvent(`splade:${name}`, { detail: data }));
298+
}
299+
292300
function request(url, method, data, headers, replace) {
293301
if (!isSsr) {
294302
remember("scrollY", window.scrollY);
295303
}
296304

305+
fireEvent("request", { url, method, data, headers, replace });
306+
297307
const promise = Axios({
298308
method,
299309
url,
@@ -304,13 +314,22 @@ function request(url, method, data, headers, replace) {
304314
Accept: "text/html, application/xhtml+xml",
305315
...headers,
306316
},
317+
onUploadProgress: progress => {
318+
if (data instanceof FormData) {
319+
progress.percentage = Math.round(progress.loaded / progress.total * 100);
320+
fireEvent("request-progress", { url, method, data, headers, replace, progress });
321+
}
322+
},
307323
});
308324

309325
promise
310326
.then((response) => {
311327
newPageFromResponse(response, replace);
328+
fireEvent("request-response", { url, method, data, headers, replace, response });
312329
})
313330
.catch((error) => {
331+
fireEvent("request-error", { url, method, data, headers, replace, error });
332+
314333
const spladeData = error.response.data.splade;
315334

316335
if (spladeData) {

lib/SpladePlugin.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import has from "lodash-es/has";
2+
import isObject from "lodash-es/isObject";
23
import Confirm from "./Components/Confirm.vue";
34
import Data from "./Components/Data.vue";
45
import Defer from "./Components/Defer.vue";
@@ -21,6 +22,7 @@ import Toasts from "./Components/Toasts.vue";
2122
import Toggle from "./Components/Toggle.vue";
2223
import Transition from "./Components/Transition.vue";
2324
import { Splade } from "./Splade.js";
25+
import { SpladeProgress } from "./SpladeProgress.js";
2426

2527
export default {
2628
install: (app, options) => {
@@ -29,6 +31,7 @@ export default {
2931
options.prefix = has(options, "prefix") ? options.prefix : "Splade";
3032
options.transform_anchors = has(options, "transform_anchors") ? options.transform_anchors : false;
3133
options.link_component = has(options, "link_component") ? options.link_component : "Link";
34+
options.progress_bar = has(options, "progress_bar") ? options.progress_bar : false;
3235

3336
const prefix = options.prefix;
3437

@@ -60,5 +63,26 @@ export default {
6063

6164
app.provide("$splade", app.config.globalProperties.$splade);
6265
app.provide("$spladeOptions", app.config.globalProperties.$spladeOptions);
66+
67+
if (options.progress_bar) {
68+
const progressDefaults = {
69+
delay: 250,
70+
color: "#4B5563",
71+
css: true,
72+
spinner: false,
73+
};
74+
75+
if(!isObject(options.progress_bar)){
76+
options.progress_bar = {};
77+
}
78+
79+
["delay", "color", "css", "spinner"].forEach((option) => {
80+
if(!has(options.progress_bar, option)) {
81+
options.progress_bar[option] = progressDefaults[option];
82+
}
83+
});
84+
85+
SpladeProgress.init(options.progress_bar);
86+
}
6387
}
6488
};

lib/SpladeProgress.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
const SpladeProgress = {
2+
injectCSS(color) {
3+
const element = document.createElement("style");
4+
element.type = "text/css";
5+
element.textContent = `
6+
#nprogress {
7+
pointer-events: none;
8+
}
9+
#nprogress .bar {
10+
background: ${color};
11+
position: fixed;
12+
z-index: 1031;
13+
top: 0;
14+
left: 0;
15+
width: 100%;
16+
height: 2px;
17+
}
18+
#nprogress .peg {
19+
display: block;
20+
position: absolute;
21+
right: 0px;
22+
width: 100px;
23+
height: 100%;
24+
box-shadow: 0 0 10px ${color}, 0 0 5px ${color};
25+
opacity: 1.0;
26+
-webkit-transform: rotate(3deg) translate(0px, -4px);
27+
-ms-transform: rotate(3deg) translate(0px, -4px);
28+
transform: rotate(3deg) translate(0px, -4px);
29+
}
30+
#nprogress .spinner {
31+
display: block;
32+
position: fixed;
33+
z-index: 1031;
34+
top: 15px;
35+
right: 15px;
36+
}
37+
#nprogress .spinner-icon {
38+
width: 18px;
39+
height: 18px;
40+
box-sizing: border-box;
41+
border: solid 2px transparent;
42+
border-top-color: ${color};
43+
border-left-color: ${color};
44+
border-radius: 50%;
45+
-webkit-animation: nprogress-spinner 400ms linear infinite;
46+
animation: nprogress-spinner 400ms linear infinite;
47+
}
48+
.nprogress-custom-parent {
49+
overflow: hidden;
50+
position: relative;
51+
}
52+
.nprogress-custom-parent #nprogress .spinner,
53+
.nprogress-custom-parent #nprogress .bar {
54+
position: absolute;
55+
}
56+
@-webkit-keyframes nprogress-spinner {
57+
0% { -webkit-transform: rotate(0deg); }
58+
100% { -webkit-transform: rotate(360deg); }
59+
}
60+
@keyframes nprogress-spinner {
61+
0% { transform: rotate(0deg); }
62+
100% { transform: rotate(360deg); }
63+
}
64+
`;
65+
document.head.appendChild(element);
66+
},
67+
68+
timeout: null,
69+
70+
start(event, delay, NProgress) {
71+
SpladeProgress.timeout = setTimeout(() => NProgress.start(), delay);
72+
},
73+
74+
progress(event, NProgress) {
75+
if (NProgress.isStarted() && event.detail.progress.percentage) {
76+
NProgress.set(Math.max(NProgress.status, event.detail.progress.percentage / 100 * 0.9));
77+
}
78+
},
79+
80+
stop(event, NProgress) {
81+
clearTimeout(SpladeProgress.timeout);
82+
NProgress.done();
83+
NProgress.remove();
84+
},
85+
86+
init(options) {
87+
const self = this;
88+
import("nprogress").then((NProgress) => {
89+
document.addEventListener("splade:request", (event) => self.start(event, options.delay, NProgress));
90+
document.addEventListener("splade:request-progress", (event) => self.progress(event, NProgress));
91+
document.addEventListener("splade:request-response", (event) => self.stop(event, NProgress));
92+
document.addEventListener("splade:request-error", (event) => self.stop(event, NProgress));
93+
94+
NProgress.configure({ showSpinner: options.spinner });
95+
96+
if(options.css) {
97+
this.injectCSS(options.color);
98+
}
99+
});
100+
}
101+
};
102+
103+
export { SpladeProgress };

package-lock.json

Lines changed: 18 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"dependencies": {
4343
"autosize": "^5.0.1",
4444
"choices.js": "^10.1.0",
45-
"flatpickr": "^4.6.13"
45+
"flatpickr": "^4.6.13",
46+
"nprogress": "^0.2.0"
4647
}
47-
}
48+
}

0 commit comments

Comments
 (0)