nanosplash 4.1.3 → 4.1.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
@@ -1,54 +1,171 @@
1
- # Nanosplash
1
+ <h1 align="center">Nanosplash</h1>
2
+
3
+ <p align="center"><strong>The tiny loading screen for web artisans</strong></p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/nanosplash"><img src="https://img.shields.io/npm/v/nanosplash?label=npm" alt="npm version"></a>
7
+ <a href="https://www.npmjs.com/package/nanosplash"><img src="https://img.shields.io/npm/dw/nanosplash" alt="npm downloads per week"></a>
8
+ <a href="https://bundlejs.com/?q=nanosplash"><img src="https://img.shields.io/bundlejs/size/nanosplash?label=gzipped" alt="bundle size, minified and gzipped"></a>
9
+ <a href="https://github.com/isakhauge/nanosplash/actions/workflows/ci.yml"><img src="https://github.com/isakhauge/nanosplash/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
10
+ <a href="https://coveralls.io/github/isakhauge/nanosplash?branch=main"><img src="https://coveralls.io/repos/github/isakhauge/nanosplash/badge.svg?branch=main" alt="Coverage status"></a>
11
+ <a href="./types/global.d.ts"><img src="https://img.shields.io/badge/TypeScript-ready-3178c6?logo=typescript&logoColor=white" alt="TypeScript ready"></a>
12
+ <a href="./LICENSE"><img src="https://img.shields.io/github/license/isakhauge/nanosplash?color=green" alt="MIT license"></a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <img src="https://raw.githubusercontent.com/isakhauge/nanosplash/main/assets/demo.svg" width="720" alt="Nanosplash demo: a translucent overlay with a spinner and the labels 'Loading user' and 'Loading posts' appears over a page, then fades away">
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://raw.githack.com/isakhauge/nanosplash/main/docs/index.html"><strong>Live demo</strong></a>
21
+ &nbsp;&nbsp;·&nbsp;&nbsp;
22
+ <a href="./docs.md"><strong>Full documentation</strong></a>
23
+ &nbsp;&nbsp;·&nbsp;&nbsp;
24
+ <a href="./CHANGELOG.md"><strong>Changelog</strong></a>
25
+ </p>
26
+
27
+ ## Why Nanosplash
28
+
29
+ - **~2.6 kB gzipped.** Smaller than most icons. Nothing else to ship.
30
+ - **Zero dependencies.** Plain TypeScript, plain CSS, injected once on first use.
31
+ - **Framework-agnostic.** Works in vanilla JS, React, Vue, Svelte, Angular, or any plain `<script>` tag.
32
+ - **Three-call API.** `show()`, `hide()`, `version`. Nothing to learn, nothing to configure.
33
+ - **Fullscreen or scoped.** Overlay the whole page or any element you pass in, by selector or reference.
34
+ - **Labeled async jobs.** Hand `show()` your promises. The label updates per step and the splash hides itself when done.
35
+ - **Anti-flicker timing.** Optional `showDelay` and `minDuration` so fast requests never blink a spinner.
36
+ - **Accessible and themeable.** `role="status"`, `aria-live`, reduced-motion support, automatic dark mode, and `--ns-*` CSS custom properties.
37
+ - **ESM, CJS, and IIFE builds** with bundled TypeScript types.
38
+
39
+ ## Install
2
40
 
3
- **The tiny loading screen for web artisans**
41
+ ```bash
42
+ npm install nanosplash
43
+ ```
4
44
 
5
- [![CI Production: Build, Test](https://github.com/isakhauge/nanosplash/actions/workflows/ci.yml/badge.svg)](https://github.com/isakhauge/nanosplash/actions/workflows/ci.yml)
6
- [![Coverage Status](https://coveralls.io/repos/github/isakhauge/nanosplash/badge.svg?branch=main)](https://coveralls.io/github/isakhauge/nanosplash?branch=main)
45
+ Or drop it in from a CDN with no build step. This exposes a global `useNs`:
7
46
 
8
- ![Nanosplash features: tiny 3kb gzipped, high performance, zero dependencies, minimalistic design, exports ES/CJS/IIFE, 3 function API](https://raw.githubusercontent.com/isakhauge/nanosplash/main/assets/feature-grid.svg)
47
+ ```html
48
+ <script src="https://unpkg.com/nanosplash/dist/iife/ns.iife.js"></script>
49
+ ```
50
+
51
+ ## Quick start
9
52
 
10
53
  ```js
11
- // Anti-flicker: appear only if slower than 150 ms, stay at least 400 ms
12
- const ns = useNs({ showDelay: 150, minDuration: 400 })
54
+ import { useNs } from 'nanosplash'
55
+
56
+ const ns = useNs()
13
57
 
14
- // Fullscreen
15
58
  ns.show('Loading')
59
+ // ...do work...
60
+ ns.hide()
61
+ ```
16
62
 
17
- // Specific element
18
- ns.show('Loading', '#my-div')
63
+ ## Usage
19
64
 
20
- // Hide
21
- ns.hide()
65
+ ### Fullscreen or scoped to an element
66
+
67
+ ```js
68
+ ns.show() // fullscreen spinner, no text
69
+ ns.show('Loading') // fullscreen spinner with a label
70
+ ns.show('Fetching data', '#dashboard') // inside an element, by CSS selector
71
+ ns.show('Please wait', document.querySelector('.card')) // by element reference
72
+ ```
73
+
74
+ Calling `show()` again on the same container updates the label instead of stacking a second spinner. The fullscreen splash never touches the page's scroll position.
22
75
 
23
- // Run a job under a splash: shows before the job starts, hides when settled
24
- const data = await ns.show(['Loading', () => fetchData()])
76
+ ### Run work under a splash
25
77
 
26
- // Run labeled jobs sequentially under one splash label updates per step,
27
- // results come back as a typed tuple in order
28
- const [user, posts] = await ns.show([
78
+ Pass a `[label, job]` pair and the splash lives exactly as long as the job. Pass several pairs and they run in order under one splash, with the label updating as each step starts. Results come back as a typed tuple.
79
+
80
+ ```js
81
+ const user = await ns.show(['Loading user', () => fetchUser()])
82
+
83
+ const [profile, posts] = await ns.show([
29
84
  ['Loading user', () => fetchUser()],
30
85
  ['Loading posts', () => fetchPosts()],
31
86
  ])
32
87
  ```
33
88
 
34
- Still just two functions. Accessible out of the box (`role="status"`, `aria-live="polite"`, `aria-busy`, `prefers-reduced-motion`) and themeable via `--ns-*` CSS custom properties.
89
+ Rejections propagate after the splash is hidden, so a normal `try`/`catch` works.
35
90
 
36
- ## Live demo
91
+ ### Hide
37
92
 
38
- **[Try every feature live →](https://raw.githack.com/isakhauge/nanosplash/main/docs/index.html)**
93
+ ```js
94
+ ns.hide() // hide the oldest active splash
95
+ ns.hide(id) // hide one specific splash, using the id returned by show()
96
+ ns.hide('*') // hide every active splash
97
+ ```
39
98
 
40
- Self-contained, runs the real library, no build step. Prefer to run it yourself? Clone the repo and open [`docs/index.html`](./docs/index.html) directly in a browser — no server required.
99
+ ### Anti-flicker timing
41
100
 
42
- ## Installation
101
+ Configure once and every splash from that instance follows the same rules. The splash stays invisible for `showDelay` ms and, once visible, stays for at least `minDuration` ms. Requests that finish inside the delay never show a spinner at all.
43
102
 
44
- ```bash
45
- npm install nanosplash
103
+ ```js
104
+ const ns = useNs({ showDelay: 150, minDuration: 400 })
46
105
  ```
47
106
 
48
- ```html
49
- <script src="https://unpkg.com/nanosplash/dist/iife/ns.iife.js"></script>
107
+ ## Theming
108
+
109
+ Nanosplash ships light and dark defaults that follow `prefers-color-scheme`, with a `data-theme="light|dark"` attribute on the root element as an override. All defaults are declared at zero specificity, so any rule of yours wins regardless of load order.
110
+
111
+ ```css
112
+ :root {
113
+ --ns-color: tomato;
114
+ --ns-size: 24px;
115
+ --ns-bg: rgba(0, 0, 0, 0.8);
116
+ }
117
+
118
+ /* Theme only the loaders inside one panel */
119
+ #dashboard {
120
+ --ns-color: white;
121
+ --ns-bg: rgba(0, 0, 0, 0.6);
122
+ }
50
123
  ```
51
124
 
52
- ## Documentation
125
+ | Property | Default | Controls |
126
+ | ------------------- | ------------------------------- | ------------------------------------- |
127
+ | `--ns-color` | `DarkSlateGray` | Spinner and text color |
128
+ | `--ns-size` | `20px` | Base size; the spinner scales from it |
129
+ | `--ns-font` | `'Inter', 'Helvetica', 'Arial'` | Label font stack |
130
+ | `--ns-weight` | `400` | Label font weight |
131
+ | `--ns-bg` | `rgba(255, 255, 255, 0.9)` | Overlay background |
132
+ | `--ns-blur` | `blur(5px)` | Backdrop blur |
133
+ | `--ns-shadow-color` | `rgba(0, 0, 0, 0.25)` | Text and spinner shadow |
134
+ | `--ns-z-index` | `9999999999` | Overlay z-index |
135
+
136
+ ## Accessibility
137
+
138
+ - The splash has `role="status"` and `aria-live="polite"`, so the label is announced when it appears or changes.
139
+ - The host container gets `aria-busy="true"` while a splash is active and loses it on hide.
140
+ - Under `prefers-reduced-motion: reduce`, fades and entrance animations are disabled and the spinner rotates slowly with a static arc.
141
+
142
+ ## API at a glance
143
+
144
+ | Call | Returns | Description |
145
+ | ---------------------------------- | ------------------------- | --------------------------------------------------------------------------- |
146
+ | `useNs(options?)` | `{ show, hide, version }` | Create an API instance. `options` sets `showDelay` and `minDuration`. |
147
+ | `show(label?, inside?)` | `number \| null` | Show a splash. Returns its id, or `null` if `inside` could not be resolved. |
148
+ | `show([label, job], inside?)` | `Promise<T>` | Run one job under a splash and resolve with its result. |
149
+ | `show([[label, job], …], inside?)` | `Promise<[T1, T2, …]>` | Run jobs sequentially under one splash and resolve with a tuple. |
150
+ | `hide(id?)` | `void` | Hide the oldest splash, a specific id, or all with `'*'`. |
151
+ | `version` | `string` | The installed Nanosplash version. |
152
+
153
+ `inside` accepts an `Element` or a CSS selector string. See the [full documentation](./docs.md) for every detail, including instance recycling, FIFO ordering, and host classes.
154
+
155
+ ## Module formats
156
+
157
+ | Format | Entry | Use |
158
+ | ------ | ---------------------- | ----------------------------------------------------- |
159
+ | ESM | `dist/es/ns.es.js` | `import { useNs } from 'nanosplash'` |
160
+ | CJS | `dist/cjs/ns.cjs.js` | `const { useNs } = require('nanosplash')` |
161
+ | IIFE | `dist/iife/ns.iife.js` | `<script>` tag from unpkg or jsDelivr, global `useNs` |
162
+
163
+ Types ship in the package, so editors pick them up automatically.
164
+
165
+ ## Contributing
166
+
167
+ Found a bug or want a feature? [Open an issue](https://github.com/isakhauge/nanosplash/issues) or send a pull request.
168
+
169
+ ## License
53
170
 
54
- [Read the full docs here](./docs.md)
171
+ [MIT](./LICENSE) © Isak Hauge
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:"Inter", "Helvetica", "Arial";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:"";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);white-space:nowrap;text-overflow:ellipsis;max-width:80dvw;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}`,t=()=>globalThis.document,n=()=>globalThis.document.body,r=e=>Array.from(e),i=(e,t)=>r(e.querySelectorAll(t)),a=(e,t)=>i(e,t)[0]??null,o=e=>e instanceof Element?e:a(t(),e),s=(e,...n)=>{let r=t().createElement(`div`);return e&&r.classList.add(e),r.append(...n),r},c=e=>{let t=s();return t.innerHTML=e,t.firstChild},l={ns:`ns`,nsHost:`nsh`,nsText:`nst`,nsSpinner:`nss`},u={ns:`.`+l.ns,nsHost:`.`+l.nsHost,nsText:`.`+l.nsText,nsSpinner:`.`+l.nsSpinner},d=`4.1.3`,f=1,p=e=>Array.isArray(e)&&typeof e[1]==`function`,m=m=>{let h=()=>i(t(),u.ns),g=()=>{let e=c(`<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>`);e.setAttribute(`aria-hidden`,`true`);let t=s(l.ns,s(l.nsText),s(l.nsSpinner,e));return t.setAttribute(`role`,`status`),t.setAttribute(`aria-live`,`polite`),t.nsId=f++,t},_=()=>h().filter(e=>e.nsHideTimer===void 0).sort((e,t)=>e.nsId-t.nsId),v=()=>_()[0]??null,y=(e,t)=>{if(a(e,u.nsText)?.remove(),!t)return;let n=s(l.nsText,t);e.insertBefore(n,e.firstChild)},b=(e,t)=>{let n=t.firstElementChild;n?t.insertBefore(e,n):t.append(e),t.classList.add(l.nsHost),t.setAttribute(`aria-busy`,`true`)},x=(e,t)=>{e.nsShownAt=performance.now(),e.nsShowDelay=m?.showDelay??0,e.nsMinDuration=m?.minDuration??0,t.style.setProperty(`--ns-show-delay`,e.nsShowDelay+`ms`)},S=e=>r(e.children).find(e=>e.classList.contains(l.ns)),C=(e,t)=>{let r=t?o(t):n();if(!r)return null;k();let i,a=S(r);return a?(i=a,clearTimeout(i.nsHideTimer),i.nsHideTimer=void 0):(i=g(),b(i,r)),x(i,r),y(i,e??``),i.nsId},w=e=>{let t=e.parentElement;t&&(t.classList.remove(l.nsHost),t.removeAttribute(`aria-busy`),t.style.removeProperty(`--ns-show-delay`)),e.remove()},T=e=>{if(!e||e.nsHideTimer!==void 0)return;let t=e.nsShowDelay??0,n=performance.now()-((e.nsShownAt??0)+t),r=t>0&&n<0,i=(e.nsMinDuration??0)-n;if(!r&&i>0){e.nsHideTimer=setTimeout(()=>w(e),i);return}w(e)},E=e=>h().find(t=>t.nsId===e)??null,D=e=>{e===`*`?h().forEach(T):T(typeof e==`number`?E(e):v())},O=()=>c(`<style id="ns">${e}</style>`),k=()=>{let e=a(t(),`#ns`),n=O();if(!e){t().head.append(n);return}e.textContent!==n.textContent&&e.replaceWith(n)},A=async(e,t)=>{if(e.length===0)return[];let n=[],r=null;try{for(let[i,a]of e)r=C(i,t),n.push(await a())}finally{r!==null&&D(r)}return n};return{show:((e,t)=>p(e)?A([e],t).then(e=>e[0]):Array.isArray(e)?A(e,t):C(e,t)),hide:D,version:d}};exports.useNs=m;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:"Inter", "Helvetica", "Arial";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:"";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);max-width:calc(80% - var(--relSize));white-space:nowrap;text-overflow:ellipsis;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}body.nsh>.ns .nst{max-width:min(40rem,80dvw)}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}`,t=()=>globalThis.document,n=()=>t().body,r=e=>Array.from(e),i=(e,t)=>r(e.querySelectorAll(t)),a=(e,t)=>i(e,t)[0]??null,o=e=>e instanceof Element?e:a(t(),e),s=(e,...n)=>{let r=t().createElement(`div`);return e&&r.classList.add(e),r.append(...n),r},c=e=>{let t=s();return t.innerHTML=e,t.firstChild},l={ns:`ns`,nsHost:`nsh`,nsText:`nst`,nsSpinner:`nss`},u={ns:`.`+l.ns,nsHost:`.`+l.nsHost,nsText:`.`+l.nsText,nsSpinner:`.`+l.nsSpinner},d=`4.1.5`,f=1,p=e=>Array.isArray(e)&&typeof e[1]==`function`,m=300,h=()=>globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches??!1,g=(e,t,n)=>typeof e.animate!=`function`||h()?Promise.resolve():e.animate(t,{duration:m,easing:n}).finished.catch(()=>void 0),_=m=>{let h=()=>i(t(),u.ns),_=()=>{let e=c(`<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>`);e.setAttribute(`aria-hidden`,`true`);let t=s(l.ns,s(l.nsSpinner,e),s(l.nsText));return t.setAttribute(`role`,`status`),t.setAttribute(`aria-live`,`polite`),t.nsId=f++,t},v=()=>h().filter(e=>e.nsHideTimer===void 0).sort((e,t)=>e.nsId-t.nsId),y=()=>v()[0]??null,b=(e,t)=>{let n=a(e,u.nsText);if(!t){n?.remove();return}if(!n){e.append(s(l.nsText,t));return}if(!n.textContent){n.textContent=t;return}if(n.textContent===t)return;let r=n.offsetWidth;n.textContent=t;let i=n.offsetWidth;g(n,[{opacity:0,transform:`translateY(10px)`},{opacity:1,transform:`none`}],`ease-out`),n.style.overflow=`visible`,g(n,[{width:`${r}px`},{width:`${i}px`}],`ease`).then(()=>{n.textContent===t&&(n.style.overflow=``)})},x=(e,t)=>{let n=t.firstElementChild;n?t.insertBefore(e,n):t.append(e),t.classList.add(l.nsHost),t.setAttribute(`aria-busy`,`true`)},S=(e,t)=>{e.nsShownAt=performance.now(),e.nsShowDelay=m?.showDelay??0,e.nsMinDuration=m?.minDuration??0,t.style.setProperty(`--ns-show-delay`,e.nsShowDelay+`ms`)},C=e=>r(e.children).find(e=>e.classList.contains(l.ns)),w=(e,t)=>{let r=t?o(t):n();if(!r)return null;A();let i,a=C(r);return a?(i=a,clearTimeout(i.nsHideTimer),i.nsHideTimer=void 0):(i=_(),x(i,r)),S(i,r),b(i,e??``),i.nsId},T=e=>{let t=e.parentElement;t&&(t.classList.remove(l.nsHost),t.removeAttribute(`aria-busy`),t.style.removeProperty(`--ns-show-delay`)),e.remove()},E=e=>{if(!e||e.nsHideTimer!==void 0)return;let t=e.nsShowDelay??0,n=performance.now()-((e.nsShownAt??0)+t),r=t>0&&n<0,i=(e.nsMinDuration??0)-n;if(!r&&i>0){e.nsHideTimer=setTimeout(()=>T(e),i);return}T(e)},D=e=>h().find(t=>t.nsId===e)??null,O=e=>{e===`*`?h().forEach(E):E(typeof e==`number`?D(e):y())},k=()=>c(`<style id="ns">${e}</style>`),A=()=>{let e=a(t(),`#ns`),n=k();if(!e){t().head.append(n);return}e.textContent!==n.textContent&&e.replaceWith(n)},j=async(e,t)=>{if(e.length===0)return[];let n=[],r=null;try{for(let[i,a]of e)r=w(i,t),n.push(await a())}finally{r!==null&&O(r)}return n};return{show:((e,t)=>p(e)?j([e],t).then(e=>e[0]):Array.isArray(e)?j(e,t):w(e,t)),hide:O,version:d}};exports.useNs=_;
package/dist/es/ns.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/style/ns.css?inline
2
- var e = () => globalThis.document, t = () => globalThis.document.body, n = (e) => Array.from(e), r = (e, t) => n(e.querySelectorAll(t)), i = (e, t) => r(e, t)[0] ?? null, a = (t) => t instanceof Element ? t : i(e(), t), o = (t, ...n) => {
2
+ var e = () => globalThis.document, t = () => e().body, n = (e) => Array.from(e), r = (e, t) => n(e.querySelectorAll(t)), i = (e, t) => r(e, t)[0] ?? null, a = (t) => t instanceof Element ? t : i(e(), t), o = (t, ...n) => {
3
3
  let r = e().createElement("div");
4
4
  return t && r.classList.add(t), r.append(...n), r;
5
5
  }, s = (e) => {
@@ -15,62 +15,88 @@ var e = () => globalThis.document, t = () => globalThis.document.body, n = (e) =
15
15
  nsHost: "." + c.nsHost,
16
16
  nsText: "." + c.nsText,
17
17
  nsSpinner: "." + c.nsSpinner
18
- }, u = "4.1.3", d = 1, f = (e) => Array.isArray(e) && typeof e[1] == "function", p = (p) => {
19
- let m = () => r(e(), l.ns), h = () => {
18
+ }, u = "4.1.5", d = 1, f = (e) => Array.isArray(e) && typeof e[1] == "function", p = 300, m = () => globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? !1, h = (e, t, n) => typeof e.animate != "function" || m() ? Promise.resolve() : e.animate(t, {
19
+ duration: p,
20
+ easing: n
21
+ }).finished.catch(() => void 0), g = (p) => {
22
+ let m = () => r(e(), l.ns), g = () => {
20
23
  let e = s("<svg viewBox=\"0 0 50 50\"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>");
21
24
  e.setAttribute("aria-hidden", "true");
22
- let t = o(c.ns, o(c.nsText), o(c.nsSpinner, e));
25
+ let t = o(c.ns, o(c.nsSpinner, e), o(c.nsText));
23
26
  return t.setAttribute("role", "status"), t.setAttribute("aria-live", "polite"), t.nsId = d++, t;
24
- }, g = () => m().filter((e) => e.nsHideTimer === void 0).sort((e, t) => e.nsId - t.nsId), _ = () => g()[0] ?? null, v = (e, t) => {
25
- if (i(e, l.nsText)?.remove(), !t) return;
26
- let n = o(c.nsText, t);
27
- e.insertBefore(n, e.firstChild);
28
- }, y = (e, t) => {
27
+ }, _ = () => m().filter((e) => e.nsHideTimer === void 0).sort((e, t) => e.nsId - t.nsId), v = () => _()[0] ?? null, y = (e, t) => {
28
+ let n = i(e, l.nsText);
29
+ if (!t) {
30
+ n?.remove();
31
+ return;
32
+ }
33
+ if (!n) {
34
+ e.append(o(c.nsText, t));
35
+ return;
36
+ }
37
+ if (!n.textContent) {
38
+ n.textContent = t;
39
+ return;
40
+ }
41
+ if (n.textContent === t) return;
42
+ let r = n.offsetWidth;
43
+ n.textContent = t;
44
+ let a = n.offsetWidth;
45
+ h(n, [{
46
+ opacity: 0,
47
+ transform: "translateY(10px)"
48
+ }, {
49
+ opacity: 1,
50
+ transform: "none"
51
+ }], "ease-out"), n.style.overflow = "visible", h(n, [{ width: `${r}px` }, { width: `${a}px` }], "ease").then(() => {
52
+ n.textContent === t && (n.style.overflow = "");
53
+ });
54
+ }, b = (e, t) => {
29
55
  let n = t.firstElementChild;
30
56
  n ? t.insertBefore(e, n) : t.append(e), t.classList.add(c.nsHost), t.setAttribute("aria-busy", "true");
31
- }, b = (e, t) => {
57
+ }, x = (e, t) => {
32
58
  e.nsShownAt = performance.now(), e.nsShowDelay = p?.showDelay ?? 0, e.nsMinDuration = p?.minDuration ?? 0, t.style.setProperty("--ns-show-delay", e.nsShowDelay + "ms");
33
- }, x = (e) => n(e.children).find((e) => e.classList.contains(c.ns)), S = (e, n) => {
59
+ }, S = (e) => n(e.children).find((e) => e.classList.contains(c.ns)), C = (e, n) => {
34
60
  let r = n ? a(n) : t();
35
61
  if (!r) return null;
36
- O();
37
- let i, o = x(r);
38
- return o ? (i = o, clearTimeout(i.nsHideTimer), i.nsHideTimer = void 0) : (i = h(), y(i, r)), b(i, r), v(i, e ?? ""), i.nsId;
39
- }, C = (e) => {
62
+ k();
63
+ let i, o = S(r);
64
+ return o ? (i = o, clearTimeout(i.nsHideTimer), i.nsHideTimer = void 0) : (i = g(), b(i, r)), x(i, r), y(i, e ?? ""), i.nsId;
65
+ }, w = (e) => {
40
66
  let t = e.parentElement;
41
67
  t && (t.classList.remove(c.nsHost), t.removeAttribute("aria-busy"), t.style.removeProperty("--ns-show-delay")), e.remove();
42
- }, w = (e) => {
68
+ }, T = (e) => {
43
69
  if (!e || e.nsHideTimer !== void 0) return;
44
70
  let t = e.nsShowDelay ?? 0, n = performance.now() - ((e.nsShownAt ?? 0) + t), r = t > 0 && n < 0, i = (e.nsMinDuration ?? 0) - n;
45
71
  if (!r && i > 0) {
46
- e.nsHideTimer = setTimeout(() => C(e), i);
72
+ e.nsHideTimer = setTimeout(() => w(e), i);
47
73
  return;
48
74
  }
49
- C(e);
50
- }, T = (e) => m().find((t) => t.nsId === e) ?? null, E = (e) => {
51
- e === "*" ? m().forEach(w) : w(typeof e == "number" ? T(e) : _());
52
- }, D = () => s("<style id=\"ns\">@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:\"Inter\", \"Helvetica\", \"Arial\";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:\"\";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);white-space:nowrap;text-overflow:ellipsis;max-width:80dvw;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}</style>"), O = () => {
53
- let t = i(e(), "#ns"), n = D();
75
+ w(e);
76
+ }, E = (e) => m().find((t) => t.nsId === e) ?? null, D = (e) => {
77
+ e === "*" ? m().forEach(T) : T(typeof e == "number" ? E(e) : v());
78
+ }, O = () => s("<style id=\"ns\">@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:\"Inter\", \"Helvetica\", \"Arial\";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:\"\";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);max-width:calc(80% - var(--relSize));white-space:nowrap;text-overflow:ellipsis;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}body.nsh>.ns .nst{max-width:min(40rem,80dvw)}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}</style>"), k = () => {
79
+ let t = i(e(), "#ns"), n = O();
54
80
  if (!t) {
55
81
  e().head.append(n);
56
82
  return;
57
83
  }
58
84
  t.textContent !== n.textContent && t.replaceWith(n);
59
- }, k = async (e, t) => {
85
+ }, A = async (e, t) => {
60
86
  if (e.length === 0) return [];
61
87
  let n = [], r = null;
62
88
  try {
63
- for (let [i, a] of e) r = S(i, t), n.push(await a());
89
+ for (let [i, a] of e) r = C(i, t), n.push(await a());
64
90
  } finally {
65
- r !== null && E(r);
91
+ r !== null && D(r);
66
92
  }
67
93
  return n;
68
94
  };
69
95
  return {
70
- show: ((e, t) => f(e) ? k([e], t).then((e) => e[0]) : Array.isArray(e) ? k(e, t) : S(e, t)),
71
- hide: E,
96
+ show: ((e, t) => f(e) ? A([e], t).then((e) => e[0]) : Array.isArray(e) ? A(e, t) : C(e, t)),
97
+ hide: D,
72
98
  version: u
73
99
  };
74
100
  };
75
101
  //#endregion
76
- export { p as useNs };
102
+ export { g as useNs };
@@ -1 +1 @@
1
- (function(){var e=()=>globalThis.document,t=()=>globalThis.document.body,n=e=>Array.from(e),r=(e,t)=>n(e.querySelectorAll(t)),i=(e,t)=>r(e,t)[0]??null,a=t=>t instanceof Element?t:i(e(),t),o=(t,...n)=>{let r=e().createElement(`div`);return t&&r.classList.add(t),r.append(...n),r},s=e=>{let t=o();return t.innerHTML=e,t.firstChild},c={ns:`ns`,nsHost:`nsh`,nsText:`nst`,nsSpinner:`nss`},l={ns:`.`+c.ns,nsHost:`.`+c.nsHost,nsText:`.`+c.nsText,nsSpinner:`.`+c.nsSpinner},u=`4.1.3`,d=1,f=e=>Array.isArray(e)&&typeof e[1]==`function`,p=p=>{let m=()=>r(e(),l.ns),h=()=>{let e=s(`<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>`);e.setAttribute(`aria-hidden`,`true`);let t=o(c.ns,o(c.nsText),o(c.nsSpinner,e));return t.setAttribute(`role`,`status`),t.setAttribute(`aria-live`,`polite`),t.nsId=d++,t},g=()=>m().filter(e=>e.nsHideTimer===void 0).sort((e,t)=>e.nsId-t.nsId),_=()=>g()[0]??null,v=(e,t)=>{if(i(e,l.nsText)?.remove(),!t)return;let n=o(c.nsText,t);e.insertBefore(n,e.firstChild)},y=(e,t)=>{let n=t.firstElementChild;n?t.insertBefore(e,n):t.append(e),t.classList.add(c.nsHost),t.setAttribute(`aria-busy`,`true`)},b=(e,t)=>{e.nsShownAt=performance.now(),e.nsShowDelay=p?.showDelay??0,e.nsMinDuration=p?.minDuration??0,t.style.setProperty(`--ns-show-delay`,e.nsShowDelay+`ms`)},x=e=>n(e.children).find(e=>e.classList.contains(c.ns)),S=(e,n)=>{let r=n?a(n):t();if(!r)return null;O();let i,o=x(r);return o?(i=o,clearTimeout(i.nsHideTimer),i.nsHideTimer=void 0):(i=h(),y(i,r)),b(i,r),v(i,e??``),i.nsId},C=e=>{let t=e.parentElement;t&&(t.classList.remove(c.nsHost),t.removeAttribute(`aria-busy`),t.style.removeProperty(`--ns-show-delay`)),e.remove()},w=e=>{if(!e||e.nsHideTimer!==void 0)return;let t=e.nsShowDelay??0,n=performance.now()-((e.nsShownAt??0)+t),r=t>0&&n<0,i=(e.nsMinDuration??0)-n;if(!r&&i>0){e.nsHideTimer=setTimeout(()=>C(e),i);return}C(e)},T=e=>m().find(t=>t.nsId===e)??null,E=e=>{e===`*`?m().forEach(w):w(typeof e==`number`?T(e):_())},D=()=>s(`<style id="ns">@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:"Inter", "Helvetica", "Arial";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:"";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);white-space:nowrap;text-overflow:ellipsis;max-width:80dvw;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}</style>`),O=()=>{let t=i(e(),`#ns`),n=D();if(!t){e().head.append(n);return}t.textContent!==n.textContent&&t.replaceWith(n)},k=async(e,t)=>{if(e.length===0)return[];let n=[],r=null;try{for(let[i,a]of e)r=S(i,t),n.push(await a())}finally{r!==null&&E(r)}return n};return{show:((e,t)=>f(e)?k([e],t).then(e=>e[0]):Array.isArray(e)?k(e,t):S(e,t)),hide:E,version:u}};window.addEventListener(`load`,()=>{window.ns=p()})})();
1
+ (function(){var e=()=>globalThis.document,t=()=>e().body,n=e=>Array.from(e),r=(e,t)=>n(e.querySelectorAll(t)),i=(e,t)=>r(e,t)[0]??null,a=t=>t instanceof Element?t:i(e(),t),o=(t,...n)=>{let r=e().createElement(`div`);return t&&r.classList.add(t),r.append(...n),r},s=e=>{let t=o();return t.innerHTML=e,t.firstChild},c={ns:`ns`,nsHost:`nsh`,nsText:`nst`,nsSpinner:`nss`},l={ns:`.`+c.ns,nsHost:`.`+c.nsHost,nsText:`.`+c.nsText,nsSpinner:`.`+c.nsSpinner},u=`4.1.5`,d=1,f=e=>Array.isArray(e)&&typeof e[1]==`function`,p=300,m=()=>globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches??!1,h=(e,t,n)=>typeof e.animate!=`function`||m()?Promise.resolve():e.animate(t,{duration:p,easing:n}).finished.catch(()=>void 0),g=p=>{let m=()=>r(e(),l.ns),g=()=>{let e=s(`<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>`);e.setAttribute(`aria-hidden`,`true`);let t=o(c.ns,o(c.nsSpinner,e),o(c.nsText));return t.setAttribute(`role`,`status`),t.setAttribute(`aria-live`,`polite`),t.nsId=d++,t},_=()=>m().filter(e=>e.nsHideTimer===void 0).sort((e,t)=>e.nsId-t.nsId),v=()=>_()[0]??null,y=(e,t)=>{let n=i(e,l.nsText);if(!t){n?.remove();return}if(!n){e.append(o(c.nsText,t));return}if(!n.textContent){n.textContent=t;return}if(n.textContent===t)return;let r=n.offsetWidth;n.textContent=t;let a=n.offsetWidth;h(n,[{opacity:0,transform:`translateY(10px)`},{opacity:1,transform:`none`}],`ease-out`),n.style.overflow=`visible`,h(n,[{width:`${r}px`},{width:`${a}px`}],`ease`).then(()=>{n.textContent===t&&(n.style.overflow=``)})},b=(e,t)=>{let n=t.firstElementChild;n?t.insertBefore(e,n):t.append(e),t.classList.add(c.nsHost),t.setAttribute(`aria-busy`,`true`)},x=(e,t)=>{e.nsShownAt=performance.now(),e.nsShowDelay=p?.showDelay??0,e.nsMinDuration=p?.minDuration??0,t.style.setProperty(`--ns-show-delay`,e.nsShowDelay+`ms`)},S=e=>n(e.children).find(e=>e.classList.contains(c.ns)),C=(e,n)=>{let r=n?a(n):t();if(!r)return null;k();let i,o=S(r);return o?(i=o,clearTimeout(i.nsHideTimer),i.nsHideTimer=void 0):(i=g(),b(i,r)),x(i,r),y(i,e??``),i.nsId},w=e=>{let t=e.parentElement;t&&(t.classList.remove(c.nsHost),t.removeAttribute(`aria-busy`),t.style.removeProperty(`--ns-show-delay`)),e.remove()},T=e=>{if(!e||e.nsHideTimer!==void 0)return;let t=e.nsShowDelay??0,n=performance.now()-((e.nsShownAt??0)+t),r=t>0&&n<0,i=(e.nsMinDuration??0)-n;if(!r&&i>0){e.nsHideTimer=setTimeout(()=>w(e),i);return}w(e)},E=e=>m().find(t=>t.nsId===e)??null,D=e=>{e===`*`?m().forEach(T):T(typeof e==`number`?E(e):v())},O=()=>s(`<style id="ns">@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1 150;stroke-dashoffset:0}50%{stroke-dasharray:90 150;stroke-dashoffset:-35px}to{stroke-dasharray:90 150;stroke-dashoffset:-124px}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:where(:root){--ns-color:DarkSlateGray;--ns-size:20px;--ns-font:"Inter", "Helvetica", "Arial";--ns-weight:400;--ns-bg:#ffffffe6;--ns-z-index:10000000000;--ns-blur:blur(5px);--ns-shadow-color:#00000040;--ns-show-delay:0s}@media (prefers-color-scheme:dark){:where(:root:not([data-theme=light])){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}}:where(:root[data-theme=dark]){--ns-color:#fafafa;--ns-bg:#09090bd9;--ns-shadow-color:#ffffff59}.nsh{--color:var(--ns-color);--size:var(--ns-size);--relSize:calc(var(--size) * .9);--font:var(--ns-font);--weight:var(--ns-weight);--bg:var(--ns-bg);--zIdx:var(--ns-z-index);--blur:var(--ns-blur);--shadowColor:var(--ns-shadow-color);z-index:var(--zIdx);position:relative}.nsh:before{animation:.2s linear backwards nsFade;animation-delay:var(--ns-show-delay);content:"";background-color:var(--bg);width:100%;height:100%;-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit;position:absolute;bottom:0;right:0}body.nsh:before,body.nsh>.ns{position:fixed;inset:0}.ns{width:100%;height:100%;z-index:calc(var(--zIdx) + 2);animation:2s backwards nsFade;animation-delay:var(--ns-show-delay);justify-content:center;align-items:center;gap:var(--relSize);display:flex;position:absolute;bottom:0;right:0}.nst{color:var(--color);font-size:var(--size);font-family:var(--font), sans-serif;font-weight:var(--weight);max-width:calc(80% - var(--relSize));white-space:nowrap;text-overflow:ellipsis;text-shadow:0 0 .06rem var(--shadowColor);filter:drop-shadow(0 0 .07rem var(--shadowColor));animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);overflow:hidden}body.nsh>.ns .nst{max-width:min(40rem,80dvw)}.nss{width:var(--relSize);height:var(--relSize);animation:.5s backwards nsAscend;animation-delay:var(--ns-show-delay);filter:drop-shadow(0 0 .07rem var(--shadowColor));display:block}.nss>svg{width:inherit;height:inherit;stroke-width:8px;transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:2s linear infinite nsRotate;position:relative}.nss .path{stroke:var(--color);stroke-linecap:round;animation:1.5s ease-in-out infinite nsDash}@media (prefers-reduced-motion:reduce){.ns,.nst,.nss,.nsh:before{animation-duration:0s}.nss>svg{transform-origin:50%;will-change:transform;backface-visibility:hidden;animation:6s linear infinite nsRotate}.nss .path{stroke-dasharray:90 150;stroke-dashoffset:-35px;animation:none}}</style>`),k=()=>{let t=i(e(),`#ns`),n=O();if(!t){e().head.append(n);return}t.textContent!==n.textContent&&t.replaceWith(n)},A=async(e,t)=>{if(e.length===0)return[];let n=[],r=null;try{for(let[i,a]of e)r=C(i,t),n.push(await a())}finally{r!==null&&D(r)}return n};return{show:((e,t)=>f(e)?A([e],t).then(e=>e[0]):Array.isArray(e)?A(e,t):C(e,t)),hide:D,version:u}};window.addEventListener(`load`,()=>{window.ns=g()})})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanosplash",
3
- "version": "4.1.3",
3
+ "version": "4.1.5",
4
4
  "private": false,
5
5
  "description": "The tiny loading screen for web artisans",
6
6
  "keywords": [
@@ -21,6 +21,7 @@
21
21
  "vite"
22
22
  ],
23
23
  "homepage": "https://github.com/isakhauge/nanosplash",
24
+ "license": "MIT",
24
25
  "author": {
25
26
  "name": "Isak K. Hauge",
26
27
  "email": "isakhauge@icloud.com",