nanosplash 4.0.0 → 4.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.
@@ -52,6 +52,7 @@ jobs:
52
52
  - name: Commit and push changes
53
53
  run: |
54
54
  git add .
55
+ git add -f coverage/**/* dist/**/*
55
56
  git commit --allow-empty -m "Build, test, and coverage report"
56
57
  git push
57
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanosplash",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "author": {
5
5
  "name": "Isak K. Hauge",
6
6
  "email": "isakhauge@icloud.com",
@@ -15,7 +15,6 @@
15
15
  "devDependencies": {
16
16
  "@types/jsdom": "^21.1.6",
17
17
  "@types/node": "^20.11.30",
18
- "@types/rollup": "^0.54.0",
19
18
  "@vitest/coverage-v8": "^1.4.0",
20
19
  "@vitest/ui": "^1.4.0",
21
20
  "cross-env": "^7.0.3",
@@ -25,10 +24,10 @@
25
24
  "jsdom": "^24.0.0",
26
25
  "sass": "^1.72.0",
27
26
  "stylelint-prettier": "^5.0.0",
28
- "typescript": "5.4.2",
29
- "typescript-eslint": "^7.2.0",
30
- "vite": "^5.1.6",
31
- "vitepress": "1.0.0-rc.45",
27
+ "typescript": "5.4.3",
28
+ "typescript-eslint": "^7.3.1",
29
+ "vite": "^5.2.6",
30
+ "vitepress": "1.0.1",
32
31
  "vitest": "^1.4.0"
33
32
  },
34
33
  "exports": {
@@ -1,206 +1,174 @@
1
1
  // @ts-strict
2
2
  import style from '../style/ns.sass?inline'
3
3
  import { NanosplashInterface } from './types/NanosplashInterface'
4
- import {
5
- DOMSelector,
6
- ElementReference,
7
- NSElement,
8
- ScopedSelectors,
9
- } from './types/Types'
4
+ import { ElementReference, NSElement } from './types/Types'
5
+ import type { DOMWindow } from 'jsdom'
10
6
  import { version } from '../../package.json'
11
7
 
12
- const styleId: string = 'ns'
13
- const doc: Document = document
14
- const bod: HTMLElement = doc.body
15
-
16
- /**
17
- * # Scope
18
- * Creates scoped selectors.
19
- * @param node Node to query.
20
- * @returns An object containing two, slightly different functions that
21
- * retrieves elements from the DOM.
22
- */
23
- const scope = (node: ParentNode): ScopedSelectors =>
24
- (all => ({
25
- all,
26
- first: (ref: string) => all(ref)[0] ?? null,
27
- }))((ref: string) => Array.from(node.querySelectorAll(ref)))
28
-
29
8
  /**
30
- * # Get all
31
- * @param selector CSS selector used to match nodes in the DOM.
32
- * @returns An array of Element nodes.
33
- */
34
- const getAll = (selector: DOMSelector): Element[] => scope(doc).all(selector)
35
-
36
- /**
37
- * # Get
38
- * @param selector CSS selector used to match nodes in the DOM.
39
- * @returns Firs Element node from the DOM matching the selector.
40
- */
41
- const get = (selector: DOMSelector): Element | null =>
42
- scope(doc).first(selector)
43
-
44
- /**
45
- * # Get All Nanosplashes
46
- * @returns An array of all Nanosplash elements in the DOM.
47
- */
48
- const getAllNs = (): NSElement[] => getAll('.ns') as NSElement[]
49
-
50
- /**
51
- * # Parse Ref
52
- * @param ref Element reference which could be a selector or an Element.
53
- * @returns The Element node or null.
54
- */
55
- const parseRef = (ref: ElementReference): Element | null =>
56
- ref instanceof Element ? ref : get(ref)
57
-
58
- /**
59
- * # Create HTMLDivElement
60
- * @param className Optional string containing class names.
61
- * @param children Optional list of Nodes or strings.
62
- * @returns The newly created HTMLDivElement.
63
- */
64
- const div = (
65
- className?: string,
66
- ...children: (Node | string)[]
67
- ): HTMLDivElement => {
68
- const node: HTMLDivElement = doc.createElement('div')
69
- if (className) node.classList.add(className)
70
- node.append(...children)
71
- return node
72
- }
73
-
74
- /**
75
- * # Parse
76
- * @param html HTML string.
77
- * @returns Parsed node.
78
- */
79
- const parse = (html: string): Node => {
80
- const node: HTMLDivElement = div()
81
- node.innerHTML = html
82
- return node.firstChild as Node
83
- }
84
-
85
- /**
86
- * # Make Nanosplash Element
87
- * @returns Nanpslash DOM element.
9
+ * # Use Nanosplash
10
+ * @returns Nanosplash API.
88
11
  */
89
- const makeNs = (): NSElement => {
90
- const circle: string = '<circle class=path cx=25 cy=25 r=20 fill=none />'
91
- const svg = parse(`<svg viewBox="0 0 50 50">${circle}</svg>`) as Element
92
- const node = div('ns', div('nst'), div('nss', svg)) as NSElement
93
- node.nsId = Date.now()
94
- return node
95
- }
12
+ export const useNs = (
13
+ win?: (Window | (Window & typeof globalThis)) | DOMWindow
14
+ ): NanosplashInterface => {
15
+ const doc = () => (win ?? window).document
16
+ const bod = () => doc().body
17
+
18
+ const all = (node: ParentNode, ref: string) =>
19
+ Array.from(node.querySelectorAll(ref))
20
+ const first = (node: ParentNode, ref: string) => all(node, ref)[0] ?? null
21
+
22
+ /**
23
+ * # Get All Nanosplashes
24
+ * @returns An array of all Nanosplash elements in the DOM.
25
+ */
26
+ const getAllNs = (): NSElement[] => all(doc(), '.ns') as NSElement[]
27
+
28
+ /**
29
+ * # Parse Ref
30
+ * @param ref Element reference which could be a selector or an Element.
31
+ * @returns The Element node or null.
32
+ */
33
+ const parseRef = (ref: ElementReference): Element | null =>
34
+ ref instanceof Element ? ref : first(doc(), ref)
35
+
36
+ /**
37
+ * # Create HTMLDivElement
38
+ * @param className Optional string containing class names.
39
+ * @param children Optional list of Nodes or strings.
40
+ * @returns The newly created HTMLDivElement.
41
+ */
42
+ const div = (
43
+ className?: string,
44
+ ...children: (Node | string)[]
45
+ ): HTMLDivElement => {
46
+ const node: HTMLDivElement = doc().createElement('div')
47
+ if (className) node.classList.add(className)
48
+ node.append(...children)
49
+ return node
50
+ }
96
51
 
97
- /**
98
- * # Peek Nanosplash Queue
99
- * Collect all Nanosplash elements in the DOM, sort them by their NS ID
100
- * in ascending order, and return the first element.
101
- * @returns The front of the queue.
102
- */
103
- const peekNsQueue = (): NSElement | null =>
104
- getAllNs().sort((a: NSElement, b: NSElement) => a.nsId - b.nsId)[0] ?? null
52
+ /**
53
+ * # Parse
54
+ * @param html HTML string.
55
+ * @returns Parsed node.
56
+ */
57
+ const parse = (html: string): Node => {
58
+ const node: HTMLDivElement = div()
59
+ node.innerHTML = html
60
+ return node.firstChild as Node
61
+ }
105
62
 
106
- /**
107
- * # Set Nanosplash Text
108
- * Replace the text node to trigger the animation which in turn is invoked
109
- * by the connected callback in the DOM.
110
- * @param ns Nanosplash element.
111
- * @param text Text to display adjacent to spinner.
112
- */
113
- const setNsText = (ns: NSElement, text: string): void => {
114
- const oldNsText = scope(ns).first('.nst') as Element | null
115
- if (!text) return oldNsText?.remove()
116
- const newNsText = div('nst', text)
117
- if (oldNsText) {
118
- oldNsText.replaceWith(newNsText)
119
- } else {
120
- ns.insertBefore(newNsText, ns.firstChild)
63
+ /**
64
+ * # Make Nanosplash Element
65
+ * @returns Nanpslash DOM element.
66
+ */
67
+ const makeNs = (): NSElement => {
68
+ const circle: string = '<circle class=path cx=25 cy=25 r=20 fill=none/>'
69
+ const svg = parse(`<svg viewBox="0 0 50 50">${circle}</svg>`) as Element
70
+ const node = div('ns', div('nst'), div('nss', svg)) as NSElement
71
+ node.nsId = Date.now()
72
+ return node
121
73
  }
122
- }
123
74
 
124
- /**
125
- * # Set Nanosplash Parent
126
- * Define where inside the DOM to spawn the Nansoplash.
127
- * @param ns Nanosplash element.
128
- * @param parent NS element's parent to be.
129
- */
130
- const setNsParent = (ns: NSElement, parent: Element): void => {
131
- const child = parent.firstElementChild
132
- if (child) {
133
- parent.insertBefore(ns, child)
75
+ /**
76
+ * # Peek Nanosplash Queue
77
+ * Collect all Nanosplash elements in the DOM, sort them by their NS ID
78
+ * in ascending order, and return the first element.
79
+ * @returns The front of the queue.
80
+ */
81
+ const peekNsQueue = (): NSElement | null =>
82
+ getAllNs().sort((a: NSElement, b: NSElement) => a.nsId - b.nsId)[0] ?? null
83
+
84
+ /**
85
+ * # Set Nanosplash Text
86
+ * Replace the text node to trigger the animation which in turn is invoked
87
+ * by the connected callback in the DOM.
88
+ * @param ns Nanosplash element.
89
+ * @param text Text to display adjacent to spinner.
90
+ */
91
+ const setNsText = (ns: NSElement, text: string): void => {
92
+ const oldNsText = first(ns, '.nst') as Element | null
93
+ if (!text) return oldNsText?.remove()
94
+ const newNsText = div('nst', text)
95
+ if (oldNsText) {
96
+ oldNsText.replaceWith(newNsText)
97
+ } else {
98
+ ns.insertBefore(newNsText, ns.firstChild)
99
+ }
134
100
  }
135
- parent.append(ns)
136
- parent.classList.add('nsh')
137
- }
138
101
 
139
- /**
140
- * # Show Nanosplash
141
- * @param text Text to display adjacent to spinner.
142
- * @param inside Selector or element in which the NS element will be spawned.
143
- * @returns The ID if the NS element which is a UTC integer.
144
- */
145
- const show = (text?: string, inside?: string | Element): number | null => {
146
- const parent: Element | null = (
147
- inside ? parseRef(inside) : bod
148
- ) as Element | null
149
- let ns: NSElement
150
- const recycledNs = scope(parent ?? bod).first('& > .ns')
151
- if (recycledNs) {
152
- ns = recycledNs as NSElement
153
- } else {
154
- ns = makeNs()
155
- setNsParent(ns, parent as Element)
102
+ /**
103
+ * # Set Nanosplash Parent
104
+ * Define where inside the DOM to spawn the Nansoplash.
105
+ * @param ns Nanosplash element.
106
+ * @param parent NS element's parent to be.
107
+ */
108
+ const setNsParent = (ns: NSElement, parent: Element): void => {
109
+ const child = parent.firstElementChild
110
+ if (child) {
111
+ parent.insertBefore(ns, child)
112
+ }
113
+ parent.append(ns)
114
+ parent.classList.add('nsh')
156
115
  }
157
- setNsText(ns, text ?? '')
158
- const top: string = scrollY + 'px'
159
- bod.style.setProperty('--ns-top', top)
160
- return ns.nsId
161
- }
162
116
 
163
- /**
164
- * # Remove Nanosplash
165
- * @param ns Nanosplash elememnt.
166
- */
167
- const removeNs = (ns?: Element | null): void => {
168
- ns?.parentElement?.classList.remove('nsh')
169
- ns?.remove()
170
- }
117
+ /**
118
+ * # Show Nanosplash
119
+ * @param text Text to display adjacent to spinner.
120
+ * @param inside Selector or element in which the NS element will be spawned.
121
+ * @returns The ID if the NS element which is a UTC integer.
122
+ */
123
+ const show = (text?: string, inside?: string | Element): number | null => {
124
+ const parent: Element | null = (
125
+ inside ? parseRef(inside) : bod
126
+ ) as Element | null
127
+ let ns: NSElement
128
+ const recycledNs = first(parent ?? bod(), '& > .ns')
129
+ if (recycledNs) {
130
+ ns = recycledNs as NSElement
131
+ } else {
132
+ ns = makeNs()
133
+ setNsParent(ns, parent as Element)
134
+ }
135
+ setNsText(ns, text ?? '')
136
+ const top: string = scrollY + 'px'
137
+ bod().style.setProperty('--ns-top', top)
138
+ return ns.nsId
139
+ }
171
140
 
172
- /**
173
- * # Find Nanosplash
174
- * @param id The UTC integer returned from the `show` function.
175
- * @returns Null or the corresponding Nanosplash element.
176
- */
177
- const findNs = (id: number) => getAllNs().find(v => v.nsId === id) ?? null
141
+ /**
142
+ * # Remove Nanosplash
143
+ * @param ns Nanosplash elememnt.
144
+ */
145
+ const removeNs = (ns?: Element | null): void => {
146
+ ns?.parentElement?.classList.remove('nsh')
147
+ ns?.remove()
148
+ }
178
149
 
179
- /**
180
- * # Hide Nanosplash
181
- * Hide agnostically in FIFO order, specifically by ID, or all by the asterisk
182
- * which will delete all Nanosplashes.
183
- * @param id Optional ID of a Nanosplash element or '*' .
184
- */
185
- const hide = (id?: number | '*'): void => {
186
- if (id === '*') getAll('.ns').forEach(removeNs)
187
- else removeNs(typeof id === 'number' ? findNs(id) : peekNsQueue())
188
- }
150
+ /**
151
+ * # Find Nanosplash
152
+ * @param id The UTC integer returned from the `show` function.
153
+ * @returns Null or the corresponding Nanosplash element.
154
+ */
155
+ const findNs = (id: number) => getAllNs().find(v => v.nsId === id) ?? null
156
+
157
+ /**
158
+ * # Hide Nanosplash
159
+ * Hide agnostically in FIFO order, specifically by ID, or all by the asterisk
160
+ * which will delete all Nanosplashes.
161
+ * @param id Optional ID of a Nanosplash element or '*' .
162
+ */
163
+ const hide = (id?: number | '*'): void => {
164
+ if (id === '*') all(doc(), '.ns').forEach(removeNs)
165
+ else removeNs(typeof id === 'number' ? findNs(id) : peekNsQueue())
166
+ }
189
167
 
190
- /**
191
- * # Add CSS
192
- */
193
- const addCssToBody = (): void => {
194
- get('#' + styleId)?.remove()
195
- bod.append(parse(`<style id=${styleId}>${style}</style>`))
196
- }
168
+ // Add CSS to window
169
+ first(doc(), '#ns')?.remove()
170
+ bod().append(parse(`<style id="ns">${style}</style>`))
197
171
 
198
- /**
199
- * # Use Nanosplash
200
- * @returns Nanosplash API.
201
- */
202
- export const useNs = (): NanosplashInterface => {
203
- addCssToBody()
204
172
  return {
205
173
  show,
206
174
  hide,
package/src/ts/main.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  // @ts-strict
2
2
  import { useNs } from './Nanosplash'
3
- window.ns = useNs() // Attach API to global scope (Window)
3
+ window.addEventListener('load', function () {
4
+ this.ns = useNs(this)
5
+ })
@@ -5,19 +5,6 @@ export type UTCInteger = Integer
5
5
  export type DOMSelector = string
6
6
  export type ElementReference = DOMSelector | Element
7
7
 
8
- export interface ScopedSelectors {
9
- /**
10
- * @param selector Selector to match with a DOM element.
11
- * @returns An array of elements matching with the selector.
12
- */
13
- all: (selector: DOMSelector) => Element[]
14
- /**
15
- * @param selector Selector to match with a DOM element.
16
- * @returns Null or the first element in the DOM to match the selector.
17
- */
18
- first: (selector: DOMSelector) => Element | null
19
- }
20
-
21
8
  export interface NSElement extends HTMLDivElement {
22
9
  nsId: number
23
10
  }
@@ -1,20 +1,10 @@
1
- import { describe, it, test, expect, beforeEach } from 'vitest'
1
+ import { describe, it, expect, beforeEach } from 'vitest'
2
2
  import { JSDOM } from 'jsdom'
3
- import { NanosplashInterface } from '../src/ts/types/NanosplashInterface'
3
+ import { useNs } from '../src/ts/Nanosplash'
4
4
 
5
- let dom = new JSDOM()
6
- let document: Document | null = null
7
- let ns: NanosplashInterface | null = null
8
-
9
- async function updateGlobals() {
10
- dom = new JSDOM()
11
- // @ts-ignore
12
- globalThis.window = dom.window
13
- document = globalThis.document = dom.window.document
14
- ns = globalThis.window.ns = (await import('../src/ts/Nanosplash')).useNs()
15
- }
16
-
17
- beforeEach(updateGlobals)
5
+ const dom = new JSDOM()
6
+ var window = dom.window
7
+ const ns = (window.ns = useNs(window))
18
8
 
19
9
  describe('Nanosplash API', () => {
20
10
  it('should be defined', () => {
package/dist/cjs/ns.cjs DELETED
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b='@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:root{--ns-top: 0px}.ns,body.nsh,body.nsh:before,.nsh:before{width:100%;height:100%}.ns,.nsh:before{bottom:0;right:0}.ns{display:flex;justify-content:center;align-items:center}.nsh{--color: DarkSlateGray;--size: 20px;--relSize: calc(var(--size) * .9);--font: "Helvetica", "Arial", sans-serif;--weight: 400;--bg: rgba(255, 255, 255, .9);--zIdx: 999999999;--blur: blur(5px)}.nsh{position:relative;z-index:var(--zIdx)}.nsh:before{position:absolute;background-color:var(--bg);content:"";backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit}body.nsh,body.nsh:before{position:fixed;top:var(--ns-top);left:0}.ns{position:absolute;z-index:calc(var(--zIdx) + 2);animation:nsFade 2s;gap:var(--relSize)}.nst{color:var(--color);font-size:var(--size);font-family:var(--font);font-weight:var(--weight);max-width:80dvw;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-shadow:0 0 .06rem rgba(47,79,79,.25);filter:drop-shadow(0 0 .07rem rgba(0,0,0,.25));animation:nsAscend .5s}.nss{display:block;width:var(--relSize);height:var(--relSize);animation:nsAscend .5s}.nss>svg{animation:nsRotate 2s linear infinite;position:relative;width:inherit;height:inherit;stroke-width:8}.nss .path{stroke:var(--color);stroke-linecap:round;animation:nsDash 1.5s ease-in-out infinite}',m="4.0.0",l="ns",i=document,r=i.body,a=e=>(s=>({all:s,first:t=>s(t)[0]??null}))(s=>Array.from(e.querySelectorAll(s))),f=e=>a(i).all(e),h=e=>a(i).first(e),p=()=>f(".ns"),u=e=>e instanceof Element?e:h(e),n=(e,...s)=>{const t=i.createElement("div");return e&&t.classList.add(e),t.append(...s),t},v=e=>{const s=n();return s.innerHTML=e,s.firstChild},g=()=>{const s=v('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'),t=n("ns",n("nst"),n("nss",s));return t.nsId=Date.now(),t},k=()=>p().sort((e,s)=>e.nsId-s.nsId)[0]??null,w=(e,s)=>{const t=a(e).first(".nst");if(!s)return t==null?void 0:t.remove();const o=n("nst",s);t?t.replaceWith(o):e.insertBefore(o,e.firstChild)},x=(e,s)=>{const t=s.firstElementChild;t&&s.insertBefore(e,t),s.append(e),s.classList.add("nsh")},z=(e,s)=>{const t=s?u(s):r;let o;const c=a(t??r).first("& > .ns");c?o=c:(o=g(),x(o,t)),w(o,e??"");const y=scrollY+"px";return r.style.setProperty("--ns-top",y),o.nsId},d=e=>{var s;(s=e==null?void 0:e.parentElement)==null||s.classList.remove("nsh"),e==null||e.remove()},I=e=>p().find(s=>s.nsId===e)??null,N=e=>{e==="*"?f(".ns").forEach(d):d(typeof e=="number"?I(e):k())},A=()=>{var e;(e=h("#"+l))==null||e.remove(),r.append(v(`<style id=${l}>${b}</style>`))},S=()=>(A(),{show:z,hide:N,version:m});exports.useNs=S;
package/dist/es/ns.js DELETED
@@ -1,44 +0,0 @@
1
- const b = '@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:root{--ns-top: 0px}.ns,body.nsh,body.nsh:before,.nsh:before{width:100%;height:100%}.ns,.nsh:before{bottom:0;right:0}.ns{display:flex;justify-content:center;align-items:center}.nsh{--color: DarkSlateGray;--size: 20px;--relSize: calc(var(--size) * .9);--font: "Helvetica", "Arial", sans-serif;--weight: 400;--bg: rgba(255, 255, 255, .9);--zIdx: 999999999;--blur: blur(5px)}.nsh{position:relative;z-index:var(--zIdx)}.nsh:before{position:absolute;background-color:var(--bg);content:"";backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit}body.nsh,body.nsh:before{position:fixed;top:var(--ns-top);left:0}.ns{position:absolute;z-index:calc(var(--zIdx) + 2);animation:nsFade 2s;gap:var(--relSize)}.nst{color:var(--color);font-size:var(--size);font-family:var(--font);font-weight:var(--weight);max-width:80dvw;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-shadow:0 0 .06rem rgba(47,79,79,.25);filter:drop-shadow(0 0 .07rem rgba(0,0,0,.25));animation:nsAscend .5s}.nss{display:block;width:var(--relSize);height:var(--relSize);animation:nsAscend .5s}.nss>svg{animation:nsRotate 2s linear infinite;position:relative;width:inherit;height:inherit;stroke-width:8}.nss .path{stroke:var(--color);stroke-linecap:round;animation:nsDash 1.5s ease-in-out infinite}', m = "4.0.0", l = "ns", i = document, r = i.body, a = (e) => /* @__PURE__ */ ((s) => ({
2
- all: s,
3
- first: (t) => s(t)[0] ?? null
4
- }))((s) => Array.from(e.querySelectorAll(s))), f = (e) => a(i).all(e), h = (e) => a(i).first(e), p = () => f(".ns"), u = (e) => e instanceof Element ? e : h(e), n = (e, ...s) => {
5
- const t = i.createElement("div");
6
- return e && t.classList.add(e), t.append(...s), t;
7
- }, v = (e) => {
8
- const s = n();
9
- return s.innerHTML = e, s.firstChild;
10
- }, g = () => {
11
- const s = v('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'), t = n("ns", n("nst"), n("nss", s));
12
- return t.nsId = Date.now(), t;
13
- }, k = () => p().sort((e, s) => e.nsId - s.nsId)[0] ?? null, w = (e, s) => {
14
- const t = a(e).first(".nst");
15
- if (!s)
16
- return t == null ? void 0 : t.remove();
17
- const o = n("nst", s);
18
- t ? t.replaceWith(o) : e.insertBefore(o, e.firstChild);
19
- }, x = (e, s) => {
20
- const t = s.firstElementChild;
21
- t && s.insertBefore(e, t), s.append(e), s.classList.add("nsh");
22
- }, z = (e, s) => {
23
- const t = s ? u(s) : r;
24
- let o;
25
- const c = a(t ?? r).first("& > .ns");
26
- c ? o = c : (o = g(), x(o, t)), w(o, e ?? "");
27
- const y = scrollY + "px";
28
- return r.style.setProperty("--ns-top", y), o.nsId;
29
- }, d = (e) => {
30
- var s;
31
- (s = e == null ? void 0 : e.parentElement) == null || s.classList.remove("nsh"), e == null || e.remove();
32
- }, I = (e) => p().find((s) => s.nsId === e) ?? null, A = (e) => {
33
- e === "*" ? f(".ns").forEach(d) : d(typeof e == "number" ? I(e) : k());
34
- }, N = () => {
35
- var e;
36
- (e = h("#" + l)) == null || e.remove(), r.append(v(`<style id=${l}>${b}</style>`));
37
- }, S = () => (N(), {
38
- show: z,
39
- hide: A,
40
- version: m
41
- });
42
- export {
43
- S as useNs
44
- };
@@ -1 +0,0 @@
1
- (function(){"use strict";const y='@keyframes nsRotate{to{transform:rotate(360deg)}}@keyframes nsDash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes nsFade{0%{opacity:0}to{opacity:1}}@keyframes nsAscend{0%{opacity:0;transform:translateY(13px)}to{opacity:1;transform:translateY(0)}}:root{--ns-top: 0px}.ns,body.nsh,body.nsh:before,.nsh:before{width:100%;height:100%}.ns,.nsh:before{bottom:0;right:0}.ns{display:flex;justify-content:center;align-items:center}.nsh{--color: DarkSlateGray;--size: 20px;--relSize: calc(var(--size) * .9);--font: "Helvetica", "Arial", sans-serif;--weight: 400;--bg: rgba(255, 255, 255, .9);--zIdx: 999999999;--blur: blur(5px)}.nsh{position:relative;z-index:var(--zIdx)}.nsh:before{position:absolute;background-color:var(--bg);content:"";backdrop-filter:var(--blur);-webkit-backdrop-filter:var(--blur);z-index:calc(var(--zIdx) + 1);border-radius:inherit}body.nsh,body.nsh:before{position:fixed;top:var(--ns-top);left:0}.ns{position:absolute;z-index:calc(var(--zIdx) + 2);animation:nsFade 2s;gap:var(--relSize)}.nst{color:var(--color);font-size:var(--size);font-family:var(--font);font-weight:var(--weight);max-width:80dvw;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-shadow:0 0 .06rem rgba(47,79,79,.25);filter:drop-shadow(0 0 .07rem rgba(0,0,0,.25));animation:nsAscend .5s}.nss{display:block;width:var(--relSize);height:var(--relSize);animation:nsAscend .5s}.nss>svg{animation:nsRotate 2s linear infinite;position:relative;width:inherit;height:inherit;stroke-width:8}.nss .path{stroke:var(--color);stroke-linecap:round;animation:nsDash 1.5s ease-in-out infinite}',b="4.0.0",c="ns",r=document,i=r.body,a=e=>(s=>({all:s,first:t=>s(t)[0]??null}))(s=>Array.from(e.querySelectorAll(s))),l=e=>a(r).all(e),d=e=>a(r).first(e),f=()=>l(".ns"),m=e=>e instanceof Element?e:d(e),o=(e,...s)=>{const t=r.createElement("div");return e&&t.classList.add(e),t.append(...s),t},h=e=>{const s=o();return s.innerHTML=e,s.firstChild},u=()=>{const s=h('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'),t=o("ns",o("nst"),o("nss",s));return t.nsId=Date.now(),t},g=()=>f().sort((e,s)=>e.nsId-s.nsId)[0]??null,w=(e,s)=>{const t=a(e).first(".nst");if(!s)return t==null?void 0:t.remove();const n=o("nst",s);t?t.replaceWith(n):e.insertBefore(n,e.firstChild)},k=(e,s)=>{const t=s.firstElementChild;t&&s.insertBefore(e,t),s.append(e),s.classList.add("nsh")},x=(e,s)=>{const t=s?m(s):i;let n;const v=a(t??i).first("& > .ns");v?n=v:(n=u(),k(n,t)),w(n,e??"");const S=scrollY+"px";return i.style.setProperty("--ns-top",S),n.nsId},p=e=>{var s;(s=e==null?void 0:e.parentElement)==null||s.classList.remove("nsh"),e==null||e.remove()},z=e=>f().find(s=>s.nsId===e)??null,I=e=>{e==="*"?l(".ns").forEach(p):p(typeof e=="number"?z(e):g())},A=()=>{var e;(e=d("#"+c))==null||e.remove(),i.append(h(`<style id=${c}>${y}</style>`))},N=()=>(A(),{show:x,hide:I,version:b});window.ns=N()})();