@vctqs1/nav-progress-bar 0.0.2-4 → 0.0.2-5

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/README.md CHANGED
@@ -4,6 +4,25 @@ A zero-dependency, CSP-safe top-of-page progress bar built as a native Web Compo
4
4
 
5
5
  > Originally built to solve the [Next.js App Router `loading.js` dead gap](https://github.com/vercel/next.js/issues/43548), but the underlying mechanism (the browser [Navigation API](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)) works anywhere.
6
6
 
7
+ ## Table of Contents
8
+
9
+ - [Features](#features)
10
+ - [Installation](#installation)
11
+ - [Quick Start](#quick-start)
12
+ - [Next.js App Router](#nextjs-app-router)
13
+ - [Nuxt](#nuxt)
14
+ - [SvelteKit](#sveltekit)
15
+ - [Astro](#astro)
16
+ - [Manual start (non-Next.js)](#manual-start-non-nextjs)
17
+ - [Vanilla HTML](#vanilla-html-snippet)
18
+ - [ES Module](#es-module)
19
+ - [Color Configuration](#color-configuration)
20
+ - [API](#api)
21
+ - [How It Works](#how-it-works)
22
+ - [Browser Support](#browser-support)
23
+ - [Debugging](#debugging)
24
+ - [License](#license)
25
+
7
26
  ## Features
8
27
 
9
28
  - **Zero dependencies** — pure Web Component, no React, no Vue, nothing
@@ -25,31 +44,7 @@ yarn add @vctqs1/nav-progress-bar
25
44
 
26
45
  ## Quick Start
27
46
 
28
- ### Vanilla HTML
29
-
30
- ```html
31
- <script type="module">
32
- import { registerNavProgressBar } from '@vctqs1/nav-progress-bar';
33
- registerNavProgressBar();
34
- </script>
35
-
36
- <vctqs1-nav-progress-bar></vctqs1-nav-progress-bar>
37
- ```
38
-
39
- ### ES Module
40
-
41
- ```ts
42
- import { registerNavProgressBar, getNavProgressBar } from '@vctqs1/nav-progress-bar';
43
-
44
- registerNavProgressBar();
45
-
46
- // The bar auto-starts on navigate and auto-finishes on navigatesuccess.
47
- // You can also control it manually:
48
- getNavProgressBar()?.start();
49
- getNavProgressBar()?.finish();
50
- ```
51
-
52
- ## Framework Guides
47
+ Pick your framework below. For most SPA routers the Navigation API fires automatically after `registerNavProgressBar()` — no extra wiring needed. If you need to force a manual start signal, see [Manual start (non-Next.js)](#manual-start-non-nextjs) below.
53
48
 
54
49
  ### Next.js App Router
55
50
 
@@ -181,7 +176,51 @@ registerNavProgressBar();
181
176
 
182
177
  ---
183
178
 
184
- ### Vanilla HTML
179
+ ### Manual start (non-Next.js)
180
+
181
+ Most SPA routers trigger browser navigation events automatically, so the bar starts/finishes on its own after `registerNavProgressBar()`.
182
+ If you need to force an immediate start signal, add a guarded listener:
183
+
184
+ ```ts
185
+ import { registerNavProgressBar, getNavProgressBar } from '@vctqs1/nav-progress-bar';
186
+
187
+ registerNavProgressBar();
188
+
189
+ const nav = (globalThis as { navigation?: EventTarget }).navigation;
190
+ if (nav?.addEventListener) {
191
+ nav.addEventListener('navigate', () => getNavProgressBar()?.start());
192
+ }
193
+ ```
194
+
195
+ ---
196
+
197
+ ### Vanilla HTML (snippet)
198
+
199
+ ```html
200
+ <script type="module">
201
+ import { registerNavProgressBar } from '@vctqs1/nav-progress-bar';
202
+ registerNavProgressBar();
203
+ </script>
204
+
205
+ <vctqs1-nav-progress-bar></vctqs1-nav-progress-bar>
206
+ ```
207
+
208
+ ### ES Module
209
+
210
+ ```ts
211
+ import { registerNavProgressBar, getNavProgressBar } from '@vctqs1/nav-progress-bar';
212
+
213
+ registerNavProgressBar();
214
+
215
+ // The bar auto-starts on navigate and auto-finishes on navigatesuccess.
216
+ // You can also control it manually:
217
+ getNavProgressBar()?.start();
218
+ getNavProgressBar()?.finish();
219
+ ```
220
+
221
+ ---
222
+
223
+ ### Vanilla HTML (full page)
185
224
 
186
225
  ```html
187
226
  <!DOCTYPE html>
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(){let e=globalThis.navigation;if(!(!e||typeof e!=`object`)&&!(!(`addEventListener`in e)||!(`removeEventListener`in e)))return e}var t=class extends HTMLElement{_layoutSheet=void 0;_sheet=void 0;_progressSheet=void 0;_autoTimer=void 0;_startTime=void 0;_options;static get observedAttributes(){return[`primary`]}constructor(e={}){super(),this._options=e}_onNavigateSuccess=()=>this.finish();_onNavigate=()=>this.start();connectedCallback(){this._render();let t=e();t&&(t.addEventListener(`navigate`,this._onNavigate),t.addEventListener(`navigatesuccess`,this._onNavigateSuccess))}disconnectedCallback(){let t=e();t&&(t.removeEventListener(`navigate`,this._onNavigate),t.removeEventListener(`navigatesuccess`,this._onNavigateSuccess)),this._clearTimer()}attributeChangedCallback(){this._sheet&&this._applyColorSheet()}_resolveColor(e,t,n){let r=e??t;return r?r.startsWith(`--`)?`var(${r}, ${n})`:r:n}_buildColorSheet(){let e=this._resolveColor(this.getAttribute(`primary`),this._options.primary,`#006bde`),t=new CSSStyleSheet;return t.insertRule(`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=globalThis.HTMLElement??class{};function t(){let e=globalThis.navigation;if(!(!e||typeof e!=`object`)&&!(!(`addEventListener`in e)||!(`removeEventListener`in e)))return e}var n=class extends e{_layoutSheet=void 0;_sheet=void 0;_progressSheet=void 0;_autoTimer=void 0;_startTime=void 0;_options;static get observedAttributes(){return[`primary`]}constructor(e={}){super(),this._options=e}_onNavigateSuccess=()=>this.finish();_onNavigate=()=>this.start();connectedCallback(){this._render();let e=t();e&&(e.addEventListener(`navigate`,this._onNavigate),e.addEventListener(`navigatesuccess`,this._onNavigateSuccess))}disconnectedCallback(){let e=t();e&&(e.removeEventListener(`navigate`,this._onNavigate),e.removeEventListener(`navigatesuccess`,this._onNavigateSuccess)),this._clearTimer()}attributeChangedCallback(){this._sheet&&this._applyColorSheet()}_resolveColor(e,t,n){let r=e??t;return r?r.startsWith(`--`)?`var(${r}, ${n})`:r:n}_buildColorSheet(){let e=this._resolveColor(this.getAttribute(`primary`),this._options.primary,`#006bde`),t=new CSSStyleSheet;return t.insertRule(`
2
2
  .bar {
3
3
  height: 3px;
4
4
  background: ${e};
@@ -20,4 +20,4 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(){
20
20
  z-index: 9999;
21
21
  pointer-events: none;
22
22
  }
23
- `),this._layoutSheet=t;let n=new CSSStyleSheet;if(n.insertRule(`.bar { width: 0%; }`),this._progressSheet=n,this._sheet=this._buildColorSheet(),e.adoptedStyleSheets=[this._layoutSheet,this._sheet,this._progressSheet],!e.querySelector(`.bar`)){let t=document.createElement(`div`);t.className=`bar`,e.append(t)}}_setWidth(e){this._progressSheet&&this._progressSheet.replaceSync(`.bar { width: ${e}%; }`)}start(){this._clearTimer(),this._setWidth(0),this._applyActive(!0);let e=0;return this._autoTimer=setInterval(()=>{e+=(85-e)*.08,this._setWidth(Math.min(e,85))},200),this}finish(){this._clearTimer();let e=this.shadowRoot?.querySelector(`.bar`);return e?(e.classList.remove(`active`),e.classList.add(`complete`),this._setWidth(100),setTimeout(()=>{e.classList.remove(`complete`),this._setWidth(0),this._applyActive(!1)},700),this):this}_applyActive(e){let t=this.shadowRoot?.querySelector(`.bar`);if(t&&(t.classList.toggle(`active`,e),e&&this._startTime===void 0&&(this._startTime=performance.now()),!e&&this._startTime!==void 0)){let e=performance.now()-this._startTime;console.log(`[top-loading-bar] navigation took ${e.toFixed(0)}ms`),this._startTime=void 0}}_clearTimer(){this._autoTimer!==void 0&&(clearInterval(this._autoTimer),this._autoTimer=void 0)}},n=`vctqs1-nav-progress-bar`;function r(r){if(!(typeof customElements>`u`)&&e()&&!customElements.get(`vctqs1-nav-progress-bar`)){class e extends t{constructor(){super(r)}}customElements.define(n,e)}}function i(){return document.querySelector(n)}exports.NavProgressBar=t,exports.TAG_NAME=n,exports.getNavProgressBar=i,exports.registerNavProgressBar=r;
23
+ `),this._layoutSheet=t;let n=new CSSStyleSheet;if(n.insertRule(`.bar { width: 0%; }`),this._progressSheet=n,this._sheet=this._buildColorSheet(),e.adoptedStyleSheets=[this._layoutSheet,this._sheet,this._progressSheet],!e.querySelector(`.bar`)){let t=document.createElement(`div`);t.className=`bar`,e.append(t)}}_setWidth(e){this._progressSheet&&this._progressSheet.replaceSync(`.bar { width: ${e}%; }`)}start(){this._clearTimer(),this._setWidth(0),this._applyActive(!0);let e=0;return this._autoTimer=setInterval(()=>{e+=(85-e)*.08,this._setWidth(Math.min(e,85))},200),this}finish(){this._clearTimer();let e=this.shadowRoot?.querySelector(`.bar`);return e?(e.classList.remove(`active`),e.classList.add(`complete`),this._setWidth(100),setTimeout(()=>{e.classList.remove(`complete`),this._setWidth(0),this._applyActive(!1)},700),this):this}_applyActive(e){let t=this.shadowRoot?.querySelector(`.bar`);if(t&&(t.classList.toggle(`active`,e),e&&this._startTime===void 0&&(this._startTime=performance.now()),!e&&this._startTime!==void 0)){let e=performance.now()-this._startTime;console.log(`[top-loading-bar] navigation took ${e.toFixed(0)}ms`),this._startTime=void 0}}_clearTimer(){this._autoTimer!==void 0&&(clearInterval(this._autoTimer),this._autoTimer=void 0)}},r=`vctqs1-nav-progress-bar`;function i(e){if(!(typeof customElements>`u`)&&t()&&!customElements.get(`vctqs1-nav-progress-bar`)){class t extends n{constructor(){super(e)}}customElements.define(r,t)}}function a(){return document.querySelector(r)}exports.NavProgressBar=n,exports.TAG_NAME=r,exports.getNavProgressBar=a,exports.registerNavProgressBar=i;
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  //#region src/lib/nav-progress-bar.ts
2
- function e() {
2
+ var e = globalThis.HTMLElement ?? class {};
3
+ function t() {
3
4
  let e = globalThis.navigation;
4
5
  if (!(!e || typeof e != "object") && !(!("addEventListener" in e) || !("removeEventListener" in e))) return e;
5
6
  }
6
- var t = class extends HTMLElement {
7
+ var n = class extends e {
7
8
  _layoutSheet = void 0;
8
9
  _sheet = void 0;
9
10
  _progressSheet = void 0;
@@ -20,12 +21,12 @@ var t = class extends HTMLElement {
20
21
  _onNavigate = () => this.start();
21
22
  connectedCallback() {
22
23
  this._render();
23
- let t = e();
24
- t && (t.addEventListener("navigate", this._onNavigate), t.addEventListener("navigatesuccess", this._onNavigateSuccess));
24
+ let e = t();
25
+ e && (e.addEventListener("navigate", this._onNavigate), e.addEventListener("navigatesuccess", this._onNavigateSuccess));
25
26
  }
26
27
  disconnectedCallback() {
27
- let t = e();
28
- t && (t.removeEventListener("navigate", this._onNavigate), t.removeEventListener("navigatesuccess", this._onNavigateSuccess)), this._clearTimer();
28
+ let e = t();
29
+ e && (e.removeEventListener("navigate", this._onNavigate), e.removeEventListener("navigatesuccess", this._onNavigateSuccess)), this._clearTimer();
29
30
  }
30
31
  attributeChangedCallback() {
31
32
  this._sheet && this._applyColorSheet();
@@ -93,19 +94,19 @@ var t = class extends HTMLElement {
93
94
  _clearTimer() {
94
95
  this._autoTimer !== void 0 && (clearInterval(this._autoTimer), this._autoTimer = void 0);
95
96
  }
96
- }, n = "vctqs1-nav-progress-bar";
97
- function r(r) {
98
- if (!(typeof customElements > "u") && e() && !customElements.get("vctqs1-nav-progress-bar")) {
99
- class e extends t {
97
+ }, r = "vctqs1-nav-progress-bar";
98
+ function i(e) {
99
+ if (!(typeof customElements > "u") && t() && !customElements.get("vctqs1-nav-progress-bar")) {
100
+ class t extends n {
100
101
  constructor() {
101
- super(r);
102
+ super(e);
102
103
  }
103
104
  }
104
- customElements.define(n, e);
105
+ customElements.define(r, t);
105
106
  }
106
107
  }
107
- function i() {
108
- return document.querySelector(n);
108
+ function a() {
109
+ return document.querySelector(r);
109
110
  }
110
111
  //#endregion
111
- export { t as NavProgressBar, n as TAG_NAME, i as getNavProgressBar, r as registerNavProgressBar };
112
+ export { n as NavProgressBar, r as TAG_NAME, a as getNavProgressBar, i as registerNavProgressBar };
@@ -5,6 +5,7 @@ export interface NavProgressBarOptions {
5
5
  /** Primary color of the progress bar (hex, rgb, or CSS custom property) */
6
6
  primary?: string;
7
7
  }
8
+ declare const HTMLElementBase: typeof HTMLElement;
8
9
  /**
9
10
  * A web component that displays a progress bar during navigation.
10
11
  * Integrates with the Navigation API to automatically start/finish the progress bar.
@@ -35,7 +36,7 @@ export interface NavProgressBarOptions {
35
36
  * <nav-progress-bar primary="#006bde"></nav-progress-bar>
36
37
  * ```
37
38
  */
38
- export declare class NavProgressBar extends HTMLElement {
39
+ export declare class NavProgressBar extends HTMLElementBase {
39
40
  private _layoutSheet;
40
41
  private _sheet;
41
42
  private _progressSheet;
@@ -112,4 +113,5 @@ export declare function registerNavProgressBar(options?: NavProgressBarOptions):
112
113
  * ```
113
114
  */
114
115
  export declare function getNavProgressBar(): NavProgressBar | null;
116
+ export {};
115
117
  //# sourceMappingURL=nav-progress-bar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav-progress-bar.d.ts","sourceRoot":"","sources":["../../src/lib/nav-progress-bar.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmBD;;;;;;;;;;;;;;GAcG;AACH;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAC7C,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,UAAU,CAAyD;IAC3E,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,QAAQ,CAAwB;IAExC,MAAM,KAAK,kBAAkB,aAE5B;IAED;;;OAGG;IACH;;;OAGG;gBACS,OAAO,GAAE,qBAA0B;IAK/C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,WAAW,CAAsB;IAEzC,iBAAiB;IAajB,oBAAoB;IAYpB,wBAAwB;IAMxB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,OAAO;IAwCf,OAAO,CAAC,SAAS;IAMjB;;;;OAIG;IACH;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAgBb;;;OAGG;IACH;;;OAGG;IACH,MAAM,IAAI,IAAI;IAmBd,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;CAMpB;AAED,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,EAAG,yBAAkC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,qBAAqB,QAgBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD"}
1
+ {"version":3,"file":"nav-progress-bar.d.ts","sourceRoot":"","sources":["../../src/lib/nav-progress-bar.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,QAAA,MAAM,eAAe,EAAE,OAAO,WAEe,CAAC;AAc9C;;;;;;;;;;;;;;GAcG;AACH;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,eAAe;IACjD,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,UAAU,CAAyD;IAC3E,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,QAAQ,CAAwB;IAExC,MAAM,KAAK,kBAAkB,aAE5B;IAED;;;OAGG;IACH;;;OAGG;gBACS,OAAO,GAAE,qBAA0B;IAK/C,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,WAAW,CAAsB;IAEzC,iBAAiB;IAajB,oBAAoB;IAYpB,wBAAwB;IAMxB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,OAAO;IAwCf,OAAO,CAAC,SAAS;IAMjB;;;;OAIG;IACH;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAgBb;;;OAGG;IACH;;;OAGG;IACH,MAAM,IAAI,IAAI;IAmBd,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;CAMpB;AAED,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,EAAG,yBAAkC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,qBAAqB,QAgBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@vctqs1/nav-progress-bar",
3
- "version": "0.0.2-4",
3
+ "version": "0.0.2-5",
4
+ "repository": "https://github.com/vctqs1/nav-progress-bar",
4
5
  "type": "module",
5
6
  "main": "./dist/index.js",
6
7
  "module": "./dist/index.js",