nanosplash 4.0.4 → 4.0.6

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.
@@ -0,0 +1,32 @@
1
+ name: CI General (non-persistent)
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - production
7
+ - test
8
+ pull_request:
9
+ branches-ignore:
10
+ - production
11
+ - test
12
+
13
+ jobs:
14
+ call-test-non-persistent:
15
+ name: Running Test (non-persistent)
16
+ uses: './.github/workflows/reusable.test.yml'
17
+ with:
18
+ persistent: false
19
+
20
+ call-lint-non-persistent:
21
+ needs: call-test-non-persistent
22
+ name: Running Linting (non-persistent)
23
+ uses: './.github/workflows/reusable.lint.yml'
24
+ with:
25
+ run-linting: true
26
+
27
+ call-build-non-persistent:
28
+ needs: call-lint-non-persistent
29
+ name: Running build (non-persistent)
30
+ uses: './.github/workflows/reusable.build.yml'
31
+ with:
32
+ persistent: false
@@ -0,0 +1,54 @@
1
+ name: CI Prepare for Production
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ production ]
6
+
7
+ jobs:
8
+ call-lint-non-persistent:
9
+ name: Lint (non-persistent)
10
+ uses: './.github/workflows/reusable.lint.yml'
11
+ with:
12
+ run-linting: true
13
+
14
+ call-format-non-persistent:
15
+ needs: call-lint-non-persistent
16
+ name: Format (non-persistent)
17
+ uses: './.github/workflows/reusable.format.yml'
18
+ with:
19
+ persistent: false
20
+
21
+ call-test-non-persistent:
22
+ needs: call-format-non-persistent
23
+ name: Test (non-persistent)
24
+ uses: './.github/workflows/reusable.test.yml'
25
+ with:
26
+ persistent: false
27
+
28
+ call-build-non-persistent:
29
+ needs: call-test-non-persistent
30
+ name: Build (non-persistent)
31
+ uses: './.github/workflows/reusable.build.yml'
32
+ with:
33
+ persistent: false
34
+
35
+ call-npm-publish-non-persistent:
36
+ needs: call-build-non-persistent
37
+ name: NPM Publish Dry-Run (non-persistent)
38
+ uses: './.github/workflows/reusable.npm-publish.yml'
39
+ with:
40
+ persistent: false
41
+
42
+ call-format:
43
+ needs: call-npm-publish-non-persistent
44
+ name: Format
45
+ uses: './.github/workflows/reusable.format.yml'
46
+ with:
47
+ persistent: true
48
+
49
+ call-build:
50
+ needs: call-format
51
+ name: Build
52
+ uses: './.github/workflows/reusable.build.yml'
53
+ with:
54
+ persistent: true
@@ -0,0 +1,68 @@
1
+ name: CI Production & Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [ production ]
6
+
7
+ jobs:
8
+ call-lint-non-persistent:
9
+ name: Lint (non-persistent)
10
+ uses: './.github/workflows/reusable.lint.yml'
11
+ with:
12
+ run-linting: true
13
+
14
+ call-format-non-persistent:
15
+ needs: call-lint-non-persistent
16
+ name: Format (non-persistent)
17
+ uses: './.github/workflows/reusable.format.yml'
18
+ with:
19
+ persistent: false
20
+
21
+ call-test-non-persistent:
22
+ needs: call-format-non-persistent
23
+ name: Test (non-persistent)
24
+ uses: './.github/workflows/reusable.test.yml'
25
+ with:
26
+ persistent: false
27
+
28
+ call-build-non-persistent:
29
+ needs: call-test-non-persistent
30
+ name: Build (non-persistent)
31
+ uses: './.github/workflows/reusable.build.yml'
32
+ with:
33
+ persistent: false
34
+
35
+ call-npm-publish-dryrun:
36
+ needs: call-build-non-persistent
37
+ name: NPM Publish Dry-Run (non-persistent)
38
+ uses: './.github/workflows/reusable.npm-publish.yml'
39
+ with:
40
+ persistent: false
41
+
42
+ call-format:
43
+ needs: call-npm-publish-dryrun
44
+ name: Format
45
+ uses: './.github/workflows/reusable.format.yml'
46
+ with:
47
+ persistent: true
48
+
49
+ call-test-and-coverage:
50
+ needs: call-format
51
+ name: Test & Coverage
52
+ uses: './.github/workflows/reusable.test.yml'
53
+ with:
54
+ persistent: true
55
+
56
+ call-build:
57
+ needs: call-test-and-coverage
58
+ name: Build
59
+ uses: './.github/workflows/reusable.build.yml'
60
+ with:
61
+ persistent: true
62
+
63
+ call-npm-publish:
64
+ needs: call-build
65
+ name: NPM Publish
66
+ uses: './.github/workflows/reusable.npm-publish.yml'
67
+ with:
68
+ persistent: true
@@ -0,0 +1,56 @@
1
+ name: CI Test
2
+
3
+ on:
4
+ push:
5
+ branches: [ test ]
6
+ pull_request:
7
+ branches: [ test ]
8
+
9
+ jobs:
10
+ call-lint-non-persistent:
11
+ name: Lint (non-persistent)
12
+ uses: './.github/workflows/reusable.lint.yml'
13
+ with:
14
+ run-linting: true
15
+
16
+ call-format-non-persistent:
17
+ needs: call-lint-non-persistent
18
+ name: Format (non-persistent)
19
+ uses: './.github/workflows/reusable.format.yml'
20
+ with:
21
+ persistent: false
22
+
23
+ call-test-non-persistent:
24
+ needs: call-format-non-persistent
25
+ name: Test (non-persistent)
26
+ uses: './.github/workflows/reusable.test.yml'
27
+ with:
28
+ persistent: false
29
+
30
+ call-build-non-persistent:
31
+ needs: call-test-non-persistent
32
+ name: Build (non-persistent)
33
+ uses: './.github/workflows/reusable.build.yml'
34
+ with:
35
+ persistent: false
36
+
37
+ call-npm-publish-non-persistent:
38
+ needs: call-build-non-persistent
39
+ name: NPM Publish Dry-Run (non-persistent)
40
+ uses: './.github/workflows/reusable.npm-publish.yml'
41
+ with:
42
+ persistent: false
43
+
44
+ call-format:
45
+ needs: call-npm-publish-non-persistent
46
+ name: Format
47
+ uses: './.github/workflows/reusable.format.yml'
48
+ with:
49
+ persistent: true
50
+
51
+ call-build:
52
+ needs: call-format
53
+ name: Build
54
+ uses: './.github/workflows/reusable.build.yml'
55
+ with:
56
+ persistent: true
@@ -0,0 +1,42 @@
1
+ name: Reusable - Build
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ persistent:
7
+ required: true
8
+ type: boolean
9
+
10
+ jobs:
11
+ run-vite-build:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ # Checking out the repository with the latest version
16
+ - uses: actions/checkout@v4
17
+
18
+ # Setting up the latest Bun.js version
19
+ - name: Set up Bun.js
20
+ uses: oven-sh/setup-bun@v2
21
+ with:
22
+ bun-version: 'latest'
23
+
24
+ # Installing dependencies using Bun
25
+ - name: Install Dependencies
26
+ run: bun install
27
+
28
+ # Running Vite Build
29
+ - name: Run Vite Build
30
+ run: bun run build
31
+
32
+ # Committing built files to the current branch
33
+ - name: Commit Built Files
34
+ if: ${{ inputs.persist }}
35
+ run: |
36
+ git config --global user.name "GitHub Actions"
37
+ git config --global user.email "actions@github.com"
38
+ git add .
39
+ git commit -m "GitHub Actions: Build" --allow-empty
40
+ git push
41
+ env:
42
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,55 @@
1
+ name: Reusable - Prettier Formatting
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ persistent:
7
+ required: true
8
+ type: boolean
9
+
10
+ jobs:
11
+ run-prettier:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ # Checking out the repository with the latest version
16
+ - uses: actions/checkout@v4
17
+
18
+ # Setting up the latest Bun.js version
19
+ - name: Set up Bun.js
20
+ uses: oven-sh/setup-bun@v2
21
+ with:
22
+ bun-version: 'latest'
23
+
24
+ # Installing dependencies using Bun
25
+ - name: Install Dependencies
26
+ run: bun install
27
+
28
+ # Running Prettier using Bun
29
+ - name: Run Prettier Format
30
+ run: bun run format
31
+
32
+ # Committing formatted files to the current branch
33
+ - name: Commit Formatted Files
34
+ if: ${{ inputs.persistent }}
35
+ run: |
36
+ git config --global user.name "GitHub Actions"
37
+ git config --global user.email "actions@github.com"
38
+
39
+ # Stage all changes
40
+ git add .
41
+
42
+ # Check if there are any staged changes
43
+ if ! git diff --cached --quiet; then
44
+ echo "There are changes to commit and push."
45
+
46
+ # Commit the changes
47
+ git commit -m "GitHub Actions: Format using Prettier"
48
+
49
+ # Push to the current branch
50
+ git push
51
+ else
52
+ echo "No changes to commit."
53
+ fi
54
+ env:
55
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,30 @@
1
+ name: Reusable - ESLint (non-persistent)
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ run-linting:
7
+ required: true
8
+ type: boolean
9
+
10
+ jobs:
11
+ run-eslint:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ # Checking out the repository with the latest version
16
+ - uses: actions/checkout@v4
17
+
18
+ # Setting up the latest Bun.js version
19
+ - name: Set up Bun.js
20
+ uses: oven-sh/setup-bun@v2
21
+ with:
22
+ bun-version: 'latest'
23
+
24
+ # Installing dependencies using Bun
25
+ - name: Install Dependencies
26
+ run: bun install
27
+
28
+ # Running Vitest with coverage using Bun
29
+ - name: Run ESLint
30
+ run: bun run lint
@@ -0,0 +1,61 @@
1
+ name: Reusable - NPM Publish
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ persistent:
7
+ required: true
8
+ type: boolean
9
+
10
+ jobs:
11
+ npm-publish:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ # Checking out the repository with the latest version
16
+ - uses: actions/checkout@v4
17
+
18
+ # Setting up the latest Node.js version
19
+ - name: Set up Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: 'latest'
23
+ registry-url: 'https://registry.npmjs.org' # Specify NPM registry
24
+
25
+ # Installing dependencies
26
+ - name: Install Dependencies
27
+ run: npm install --no-package-lock
28
+
29
+ # Get the version inside package.json
30
+ - name: Get version from package.json
31
+ id: get-version
32
+ run: |
33
+ VERSION=$(node -p "require('./package.json').version")
34
+ echo "VERSION=$VERSION" >> $GITHUB_ENV
35
+
36
+ # Publishing to NPM (dry-run for testing purposes)
37
+ - name: Publish to NPM (dry-run)
38
+ run: npm publish --dry-run
39
+ env:
40
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
41
+
42
+ # Commit the version tag made by NPM
43
+ - name: Commit version tag
44
+ if: ${{ inputs.persist }}
45
+ run: |
46
+ git config --global user.name "GitHub Actions"
47
+ git config --global user.email "actions@github.com"
48
+ git add .
49
+ git commit -m "GitHub Actions: NPM build ${{ env.VERSION }}" --allow-empty
50
+ git push origin
51
+ env:
52
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ - name: Configure npm for authentication
55
+ run: echo "https://registry.npmjs.org/:_authToken=${{ secrets.NPM_PUBLISH_TOKEN }}" > ~/.npmrc
56
+
57
+ - name: Publish to NPM
58
+ if: ${{ inputs.persistent }}
59
+ run: npm publish
60
+ env:
61
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
@@ -0,0 +1,50 @@
1
+ name: Reusable - Run Tests
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ persistent:
7
+ required: true
8
+ type: boolean
9
+
10
+ jobs:
11
+ run-vitest:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ # Checking out the repository with the latest version
16
+ - uses: actions/checkout@v4
17
+
18
+ # Setting up the latest Bun.js version
19
+ - name: Set up Bun.js
20
+ uses: oven-sh/setup-bun@v2
21
+ with:
22
+ bun-version: 'latest'
23
+
24
+ # Installing dependencies using Bun
25
+ - name: Install Dependencies
26
+ run: bun install
27
+
28
+ # Running Vitest with coverage using Bun
29
+ - name: Run Vitest
30
+ run: bunx vitest
31
+
32
+ # Committing coverage artifacts to the current branch
33
+ - name: Commit Build
34
+ if: ${{ inputs.persistent }}
35
+ run: |
36
+ git config --global user.name "GitHub Actions"
37
+ git config --global user.email "actions@github.com"
38
+ git add .
39
+ git commit -m "GitHub Actions: Create Test Coverage" --allow-empty
40
+ git push
41
+ env:
42
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43
+
44
+ # Uploading coverage to Coveralls
45
+ - name: Upload Coverage to Coveralls
46
+ if: ${{ inputs.persistent }}
47
+ uses: coverallsapp/github-action@v2
48
+ with:
49
+ github-token: ${{ secrets.GITHUB_TOKEN }}
50
+ path-to-lcov: ./coverage/lcov.info
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **The tiny loading screen for web artisans**
4
4
 
5
- [![CI Production: Build, Test, Publish](https://github.com/isakhauge/nanosplash/actions/workflows/ci.prod.yml/badge.svg)](https://github.com/isakhauge/nanosplash/actions/workflows/ci.prod.yml)
5
+ [![CI Production: Build, Test, Publish](https://github.com/isakhauge/nanosplash/actions/workflows/ci.prod.push.yml/badge.svg)](https://github.com/isakhauge/nanosplash/actions/workflows/ci.prod.push.yml)
6
6
  [![Coverage Status](https://coveralls.io/repos/github/isakhauge/nanosplash/badge.svg?branch=production)](https://coveralls.io/github/isakhauge/nanosplash?branch=production)
7
7
 
8
8
  ---
@@ -161,7 +161,7 @@
161
161
  <div class='footer quiet pad2 space-top1 center small'>
162
162
  Code coverage generated by
163
163
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
164
- at 2025-06-07T22:57:20.354Z
164
+ at 2025-06-09T11:27:59.134Z
165
165
  </div>
166
166
  <script src="prettify.js"></script>
167
167
  <script>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2025-06-07T22:57:20.354Z
104
+ at 2025-06-09T11:27:59.134Z
105
105
  </div>
106
106
  <script src="../../prettify.js"></script>
107
107
  <script>
@@ -532,7 +532,7 @@ export const useNs: Func&lt;INanosplash&gt; = (): INanosplash =&gt; {
532
532
  <div class='footer quiet pad2 space-top1 center small'>
533
533
  Code coverage generated by
534
534
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
535
- at 2025-06-07T22:57:20.354Z
535
+ at 2025-06-09T11:27:59.134Z
536
536
  </div>
537
537
  <script src="../../prettify.js"></script>
538
538
  <script>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2025-06-07T22:57:20.354Z
104
+ at 2025-06-09T11:27:59.134Z
105
105
  </div>
106
106
  <script src="../../prettify.js"></script>
107
107
  <script>
@@ -109,7 +109,7 @@ export const Selectors = {
109
109
  <div class='footer quiet pad2 space-top1 center small'>
110
110
  Code coverage generated by
111
111
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
112
- at 2025-06-07T22:57:20.354Z
112
+ at 2025-06-09T11:27:59.134Z
113
113
  </div>
114
114
  <script src="../../prettify.js"></script>
115
115
  <script>
@@ -85,7 +85,7 @@
85
85
  <div class='footer quiet pad2 space-top1 center small'>
86
86
  Code coverage generated by
87
87
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
88
- at 2025-06-07T22:57:20.354Z
88
+ at 2025-06-09T11:27:59.134Z
89
89
  </div>
90
90
  <script src="../prettify.js"></script>
91
91
  <script>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2025-06-07T22:57:20.354Z
104
+ at 2025-06-09T11:27:59.134Z
105
105
  </div>
106
106
  <script src="../prettify.js"></script>
107
107
  <script>
@@ -85,7 +85,7 @@ export interface INSElement extends HTMLDivElement {
85
85
  <div class='footer quiet pad2 space-top1 center small'>
86
86
  Code coverage generated by
87
87
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
88
- at 2025-06-07T22:57:20.354Z
88
+ at 2025-06-09T11:27:59.134Z
89
89
  </div>
90
90
  <script src="../../prettify.js"></script>
91
91
  <script>
@@ -289,7 +289,7 @@ export interface INanosplash {
289
289
  <div class='footer quiet pad2 space-top1 center small'>
290
290
  Code coverage generated by
291
291
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
292
- at 2025-06-07T22:57:20.354Z
292
+ at 2025-06-09T11:27:59.134Z
293
293
  </div>
294
294
  <script src="../../prettify.js"></script>
295
295
  <script>
@@ -116,7 +116,7 @@
116
116
  <div class='footer quiet pad2 space-top1 center small'>
117
117
  Code coverage generated by
118
118
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
119
- at 2025-06-07T22:57:20.354Z
119
+ at 2025-06-09T11:27:59.134Z
120
120
  </div>
121
121
  <script src="../../prettify.js"></script>
122
122
  <script>
@@ -274,7 +274,7 @@ export const parseHtml = &lt;T extends HTMLElement&gt;(html: HTMLString): T =&gt
274
274
  <div class='footer quiet pad2 space-top1 center small'>
275
275
  Code coverage generated by
276
276
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
277
- at 2025-06-07T22:57:20.354Z
277
+ at 2025-06-09T11:27:59.134Z
278
278
  </div>
279
279
  <script src="../../prettify.js"></script>
280
280
  <script>
@@ -101,7 +101,7 @@
101
101
  <div class='footer quiet pad2 space-top1 center small'>
102
102
  Code coverage generated by
103
103
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2025-06-07T22:57:20.354Z
104
+ at 2025-06-09T11:27:59.134Z
105
105
  </div>
106
106
  <script src="../../prettify.js"></script>
107
107
  <script>
@@ -0,0 +1,135 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=`@keyframes nsRotate {
2
+ 100% {
3
+ transform: rotate(360deg);
4
+ }
5
+ }
6
+
7
+ @keyframes nsDash {
8
+ 0% {
9
+ stroke-dasharray: 1, 150;
10
+ stroke-dashoffset: 0;
11
+ }
12
+ 50% {
13
+ stroke-dasharray: 90, 150;
14
+ stroke-dashoffset: -35;
15
+ }
16
+ 100% {
17
+ stroke-dasharray: 90, 150;
18
+ stroke-dashoffset: -124;
19
+ }
20
+ }
21
+
22
+ @keyframes nsFade {
23
+ from {
24
+ opacity: 0;
25
+ }
26
+ to {
27
+ opacity: 1;
28
+ }
29
+ }
30
+
31
+ @keyframes nsAscend {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(13px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ :root {
43
+ --ns-top: 0;
44
+ }
45
+
46
+ /* Nanosplash host */
47
+ .nsh {
48
+ --color: DarkSlateGray;
49
+ --size: 20px;
50
+ --relSize: calc(var(--size) * 0.9);
51
+ --font: 'Inter', 'Helvetica', 'Arial';
52
+ --weight: 400;
53
+ --bg: rgba(255, 255, 255, 0.9);
54
+ --zIdx: 9999999999;
55
+ --blur: blur(5px);
56
+
57
+ position: relative;
58
+ z-index: var(--zIdx);
59
+ &::before {
60
+ width: 100%;
61
+ height: 100%;
62
+ bottom: 0; /* Not sure why */
63
+ right: 0; /* Not sure why */
64
+ position: absolute;
65
+ content: '';
66
+ background-color: var(--bg);
67
+ backdrop-filter: var(--blur);
68
+ -webkit-backdrop-filter: var(--blur);
69
+ z-index: calc(var(--zIdx) + 1);
70
+ border-radius: var(--size);
71
+ }
72
+ }
73
+
74
+ /* For when the Nanosplash host is the document body */
75
+ body.nsh {
76
+ &,
77
+ &::before {
78
+ width: 100%;
79
+ height: 100%;
80
+ position: fixed;
81
+ top: var(--ns-top);
82
+ left: 0;
83
+ }
84
+ }
85
+
86
+ /* Nanosplash main element */
87
+ .ns {
88
+ width: 100%;
89
+ height: 100%;
90
+ bottom: 0; /* Not sure why */
91
+ right: 0; /* Not sure why */
92
+ display: flex;
93
+ justify-content: center;
94
+ align-items: center;
95
+ position: absolute;
96
+ z-index: calc(var(--zIdx) + 2);
97
+ animation: nsFade 2s;
98
+ gap: var(--relSize);
99
+ }
100
+
101
+ /* Nanosplash text */
102
+ .nst {
103
+ color: var(--color);
104
+ font-size: var(--size);
105
+ font-family: var(--font), sans-serif;
106
+ font-weight: var(--weight);
107
+ max-width: 80dvw;
108
+ white-space: nowrap;
109
+ text-overflow: ellipsis;
110
+ overflow: hidden;
111
+ text-shadow: 0 0 0.06rem rgba(0, 0, 0, 0.25);
112
+ filter: drop-shadow(0 0 0.07rem rgba(0, 0, 0, 0.25));
113
+ animation: nsAscend 0.5s;
114
+ }
115
+
116
+ /* Nanosplash spinner */
117
+ .nss {
118
+ display: block;
119
+ width: var(--relSize);
120
+ height: var(--relSize);
121
+ animation: nsAscend 0.5s;
122
+ & > svg {
123
+ animation: nsRotate 2s linear infinite;
124
+ position: relative;
125
+ width: inherit;
126
+ height: inherit;
127
+ stroke-width: 8;
128
+ }
129
+ & .path {
130
+ stroke: var(--color);
131
+ stroke-linecap: round;
132
+ animation: nsDash 1.5s ease-in-out infinite;
133
+ }
134
+ }
135
+ `,d=()=>globalThis.document,l=()=>globalThis.document.body,y=t=>Array.from(t),v=(t,o)=>y(t.querySelectorAll(o)),h=(t,o)=>v(t,o)[0]??null,I=t=>t instanceof Element?t:h(d(),t),c=(t,...o)=>{const a=d().createElement("div");return t&&a.classList.add(t),a.append(...o),a},m=t=>{const o=c();return o.innerHTML=t,o.firstChild},r={ns:"ns",nsHost:"nsh",nsText:"nst",nsSpinner:"nss"},u={ns:"."+r.ns,nsText:"."+r.nsText},A="4.0.5",E=()=>{const t=()=>v(d(),u.ns),o=()=>{const e=m('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'),s=c(r.ns,c(r.nsText),c(r.nsSpinner,e));return s.nsId=Date.now(),s},a=()=>t().sort((n,e)=>n.nsId-e.nsId),b=()=>a()[0]??null,g=(n,e)=>{var i;if((i=h(n,u.nsText))==null||i.remove(),!e)return;const s=c(r.nsText,e);n.insertBefore(s,n.firstChild)},w=(n,e)=>{const s=e.firstElementChild;s&&e.insertBefore(n,s),e.append(n),e.classList.add(r.nsHost)},x=n=>y(n.children).find(s=>s.classList.contains(r.ns)),k=(n,e)=>{const s=e?I(e)??l():l();let i;const p=x(s);if(p?i=p:(i=o(),w(i,s)),g(i,n??""),s===l()){const S=scrollY+"px";l().style.setProperty("--ns-top",S)}return i.nsId},f=n=>{var e;(e=n==null?void 0:n.parentElement)==null||e.classList.remove(r.nsHost),n==null||n.remove()},N=n=>t().find(e=>e.nsId===n)??null,z=n=>{n==="*"?t().forEach(f):f(typeof n=="number"?N(n):b())};return(()=>{var e;(e=h(d(),"#ns"))==null||e.remove();const n=m(`<style id="ns">${T}</style>`);l().append(n)})(),{show:k,hide:z,version:A}};exports.useNs=E;
@@ -0,0 +1,197 @@
1
+ const S = `@keyframes nsRotate {
2
+ 100% {
3
+ transform: rotate(360deg);
4
+ }
5
+ }
6
+
7
+ @keyframes nsDash {
8
+ 0% {
9
+ stroke-dasharray: 1, 150;
10
+ stroke-dashoffset: 0;
11
+ }
12
+ 50% {
13
+ stroke-dasharray: 90, 150;
14
+ stroke-dashoffset: -35;
15
+ }
16
+ 100% {
17
+ stroke-dasharray: 90, 150;
18
+ stroke-dashoffset: -124;
19
+ }
20
+ }
21
+
22
+ @keyframes nsFade {
23
+ from {
24
+ opacity: 0;
25
+ }
26
+ to {
27
+ opacity: 1;
28
+ }
29
+ }
30
+
31
+ @keyframes nsAscend {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(13px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ :root {
43
+ --ns-top: 0;
44
+ }
45
+
46
+ /* Nanosplash host */
47
+ .nsh {
48
+ --color: DarkSlateGray;
49
+ --size: 20px;
50
+ --relSize: calc(var(--size) * 0.9);
51
+ --font: 'Inter', 'Helvetica', 'Arial';
52
+ --weight: 400;
53
+ --bg: rgba(255, 255, 255, 0.9);
54
+ --zIdx: 9999999999;
55
+ --blur: blur(5px);
56
+
57
+ position: relative;
58
+ z-index: var(--zIdx);
59
+ &::before {
60
+ width: 100%;
61
+ height: 100%;
62
+ bottom: 0; /* Not sure why */
63
+ right: 0; /* Not sure why */
64
+ position: absolute;
65
+ content: '';
66
+ background-color: var(--bg);
67
+ backdrop-filter: var(--blur);
68
+ -webkit-backdrop-filter: var(--blur);
69
+ z-index: calc(var(--zIdx) + 1);
70
+ border-radius: var(--size);
71
+ }
72
+ }
73
+
74
+ /* For when the Nanosplash host is the document body */
75
+ body.nsh {
76
+ &,
77
+ &::before {
78
+ width: 100%;
79
+ height: 100%;
80
+ position: fixed;
81
+ top: var(--ns-top);
82
+ left: 0;
83
+ }
84
+ }
85
+
86
+ /* Nanosplash main element */
87
+ .ns {
88
+ width: 100%;
89
+ height: 100%;
90
+ bottom: 0; /* Not sure why */
91
+ right: 0; /* Not sure why */
92
+ display: flex;
93
+ justify-content: center;
94
+ align-items: center;
95
+ position: absolute;
96
+ z-index: calc(var(--zIdx) + 2);
97
+ animation: nsFade 2s;
98
+ gap: var(--relSize);
99
+ }
100
+
101
+ /* Nanosplash text */
102
+ .nst {
103
+ color: var(--color);
104
+ font-size: var(--size);
105
+ font-family: var(--font), sans-serif;
106
+ font-weight: var(--weight);
107
+ max-width: 80dvw;
108
+ white-space: nowrap;
109
+ text-overflow: ellipsis;
110
+ overflow: hidden;
111
+ text-shadow: 0 0 0.06rem rgba(0, 0, 0, 0.25);
112
+ filter: drop-shadow(0 0 0.07rem rgba(0, 0, 0, 0.25));
113
+ animation: nsAscend 0.5s;
114
+ }
115
+
116
+ /* Nanosplash spinner */
117
+ .nss {
118
+ display: block;
119
+ width: var(--relSize);
120
+ height: var(--relSize);
121
+ animation: nsAscend 0.5s;
122
+ & > svg {
123
+ animation: nsRotate 2s linear infinite;
124
+ position: relative;
125
+ width: inherit;
126
+ height: inherit;
127
+ stroke-width: 8;
128
+ }
129
+ & .path {
130
+ stroke: var(--color);
131
+ stroke-linecap: round;
132
+ animation: nsDash 1.5s ease-in-out infinite;
133
+ }
134
+ }
135
+ `, d = () => globalThis.document, l = () => globalThis.document.body, v = (t) => Array.from(t), u = (t, o) => v(t.querySelectorAll(o)), h = (t, o) => u(t, o)[0] ?? null, T = (t) => t instanceof Element ? t : h(d(), t), c = (t, ...o) => {
136
+ const a = d().createElement("div");
137
+ return t && a.classList.add(t), a.append(...o), a;
138
+ }, m = (t) => {
139
+ const o = c();
140
+ return o.innerHTML = t, o.firstChild;
141
+ }, r = {
142
+ ns: "ns",
143
+ nsHost: "nsh",
144
+ nsText: "nst",
145
+ nsSpinner: "nss"
146
+ }, y = {
147
+ ns: "." + r.ns,
148
+ nsText: "." + r.nsText
149
+ }, A = "4.0.5", H = () => {
150
+ const t = () => u(d(), y.ns), o = () => {
151
+ const e = m('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'), s = c(
152
+ r.ns,
153
+ c(r.nsText),
154
+ c(r.nsSpinner, e)
155
+ );
156
+ return s.nsId = Date.now(), s;
157
+ }, a = () => t().sort((n, e) => n.nsId - e.nsId), b = () => a()[0] ?? null, g = (n, e) => {
158
+ var i;
159
+ if ((i = h(n, y.nsText)) == null || i.remove(), !e) return;
160
+ const s = c(r.nsText, e);
161
+ n.insertBefore(s, n.firstChild);
162
+ }, w = (n, e) => {
163
+ const s = e.firstElementChild;
164
+ s && e.insertBefore(n, s), e.append(n), e.classList.add(r.nsHost);
165
+ }, x = (n) => v(n.children).find(
166
+ (s) => s.classList.contains(r.ns)
167
+ ), k = (n, e) => {
168
+ const s = e ? T(e) ?? l() : l();
169
+ let i;
170
+ const p = x(s);
171
+ if (p ? i = p : (i = o(), w(i, s)), g(i, n ?? ""), s === l()) {
172
+ const I = scrollY + "px";
173
+ l().style.setProperty("--ns-top", I);
174
+ }
175
+ return i.nsId;
176
+ }, f = (n) => {
177
+ var e;
178
+ (e = n == null ? void 0 : n.parentElement) == null || e.classList.remove(r.nsHost), n == null || n.remove();
179
+ }, N = (n) => t().find((e) => e.nsId === n) ?? null, z = (n) => {
180
+ n === "*" ? t().forEach(f) : f(typeof n == "number" ? N(n) : b());
181
+ };
182
+ return (() => {
183
+ var e;
184
+ (e = h(d(), "#ns")) == null || e.remove();
185
+ const n = m(
186
+ `<style id="ns">${S}</style>`
187
+ );
188
+ l().append(n);
189
+ })(), {
190
+ show: k,
191
+ hide: z,
192
+ version: A
193
+ };
194
+ };
195
+ export {
196
+ H as useNs
197
+ };
@@ -0,0 +1,135 @@
1
+ (function(){"use strict";const w=`@keyframes nsRotate {
2
+ 100% {
3
+ transform: rotate(360deg);
4
+ }
5
+ }
6
+
7
+ @keyframes nsDash {
8
+ 0% {
9
+ stroke-dasharray: 1, 150;
10
+ stroke-dashoffset: 0;
11
+ }
12
+ 50% {
13
+ stroke-dasharray: 90, 150;
14
+ stroke-dashoffset: -35;
15
+ }
16
+ 100% {
17
+ stroke-dasharray: 90, 150;
18
+ stroke-dashoffset: -124;
19
+ }
20
+ }
21
+
22
+ @keyframes nsFade {
23
+ from {
24
+ opacity: 0;
25
+ }
26
+ to {
27
+ opacity: 1;
28
+ }
29
+ }
30
+
31
+ @keyframes nsAscend {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(13px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ :root {
43
+ --ns-top: 0;
44
+ }
45
+
46
+ /* Nanosplash host */
47
+ .nsh {
48
+ --color: DarkSlateGray;
49
+ --size: 20px;
50
+ --relSize: calc(var(--size) * 0.9);
51
+ --font: 'Inter', 'Helvetica', 'Arial';
52
+ --weight: 400;
53
+ --bg: rgba(255, 255, 255, 0.9);
54
+ --zIdx: 9999999999;
55
+ --blur: blur(5px);
56
+
57
+ position: relative;
58
+ z-index: var(--zIdx);
59
+ &::before {
60
+ width: 100%;
61
+ height: 100%;
62
+ bottom: 0; /* Not sure why */
63
+ right: 0; /* Not sure why */
64
+ position: absolute;
65
+ content: '';
66
+ background-color: var(--bg);
67
+ backdrop-filter: var(--blur);
68
+ -webkit-backdrop-filter: var(--blur);
69
+ z-index: calc(var(--zIdx) + 1);
70
+ border-radius: var(--size);
71
+ }
72
+ }
73
+
74
+ /* For when the Nanosplash host is the document body */
75
+ body.nsh {
76
+ &,
77
+ &::before {
78
+ width: 100%;
79
+ height: 100%;
80
+ position: fixed;
81
+ top: var(--ns-top);
82
+ left: 0;
83
+ }
84
+ }
85
+
86
+ /* Nanosplash main element */
87
+ .ns {
88
+ width: 100%;
89
+ height: 100%;
90
+ bottom: 0; /* Not sure why */
91
+ right: 0; /* Not sure why */
92
+ display: flex;
93
+ justify-content: center;
94
+ align-items: center;
95
+ position: absolute;
96
+ z-index: calc(var(--zIdx) + 2);
97
+ animation: nsFade 2s;
98
+ gap: var(--relSize);
99
+ }
100
+
101
+ /* Nanosplash text */
102
+ .nst {
103
+ color: var(--color);
104
+ font-size: var(--size);
105
+ font-family: var(--font), sans-serif;
106
+ font-weight: var(--weight);
107
+ max-width: 80dvw;
108
+ white-space: nowrap;
109
+ text-overflow: ellipsis;
110
+ overflow: hidden;
111
+ text-shadow: 0 0 0.06rem rgba(0, 0, 0, 0.25);
112
+ filter: drop-shadow(0 0 0.07rem rgba(0, 0, 0, 0.25));
113
+ animation: nsAscend 0.5s;
114
+ }
115
+
116
+ /* Nanosplash spinner */
117
+ .nss {
118
+ display: block;
119
+ width: var(--relSize);
120
+ height: var(--relSize);
121
+ animation: nsAscend 0.5s;
122
+ & > svg {
123
+ animation: nsRotate 2s linear infinite;
124
+ position: relative;
125
+ width: inherit;
126
+ height: inherit;
127
+ stroke-width: 8;
128
+ }
129
+ & .path {
130
+ stroke: var(--color);
131
+ stroke-linecap: round;
132
+ animation: nsDash 1.5s ease-in-out infinite;
133
+ }
134
+ }
135
+ `,d=()=>globalThis.document,a=()=>globalThis.document.body,f=t=>Array.from(t),p=(t,o)=>f(t.querySelectorAll(o)),h=(t,o)=>p(t,o)[0]??null,b=t=>t instanceof Element?t:h(d(),t),l=(t,...o)=>{const c=d().createElement("div");return t&&c.classList.add(t),c.append(...o),c},m=t=>{const o=l();return o.innerHTML=t,o.firstChild},r={ns:"ns",nsHost:"nsh",nsText:"nst",nsSpinner:"nss"},u={ns:"."+r.ns,nsText:"."+r.nsText},g="4.0.5",x=()=>{const t=()=>p(d(),u.ns),o=()=>{const e=m('<svg viewBox="0 0 50 50"><circle class=path cx=25 cy=25 r=20 fill=none /></svg>'),s=l(r.ns,l(r.nsText),l(r.nsSpinner,e));return s.nsId=Date.now(),s},c=()=>t().sort((n,e)=>n.nsId-e.nsId),k=()=>c()[0]??null,N=(n,e)=>{var i;if((i=h(n,u.nsText))==null||i.remove(),!e)return;const s=l(r.nsText,e);n.insertBefore(s,n.firstChild)},z=(n,e)=>{const s=e.firstElementChild;s&&e.insertBefore(n,s),e.append(n),e.classList.add(r.nsHost)},I=n=>f(n.children).find(s=>s.classList.contains(r.ns)),S=(n,e)=>{const s=e?b(e)??a():a();let i;const y=I(s);if(y?i=y:(i=o(),z(i,s)),N(i,n??""),s===a()){const E=scrollY+"px";a().style.setProperty("--ns-top",E)}return i.nsId},v=n=>{var e;(e=n==null?void 0:n.parentElement)==null||e.classList.remove(r.nsHost),n==null||n.remove()},T=n=>t().find(e=>e.nsId===n)??null,A=n=>{n==="*"?t().forEach(v):v(typeof n=="number"?T(n):k())};return(()=>{var e;(e=h(d(),"#ns"))==null||e.remove();const n=m(`<style id="ns">${w}</style>`);a().append(n)})(),{show:S,hide:A,version:g}};window.addEventListener("load",function(){this.ns=x()})})();
package/eslint.config.js CHANGED
@@ -9,6 +9,6 @@ export default tseslint.config(
9
9
  tseslint.configs.strict,
10
10
  tseslint.configs.stylistic,
11
11
  {
12
- ignores: ["node_modules", "dist"],
12
+ ignores: ["node_modules", "dist", "coverage"],
13
13
  }
14
14
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nanosplash",
3
3
  "private": false,
4
- "version": "4.0.4",
4
+ "version": "4.0.6",
5
5
  "type": "module",
6
6
  "author": {
7
7
  "name": "Isak K. Hauge",
@@ -40,9 +40,10 @@
40
40
  "preview": "vite preview",
41
41
  "lint": "eslint . --fix",
42
42
  "format": "prettier --write \"src/**/*.ts\" \"vite.config.ts\"",
43
- "test": "bun run vitest"
43
+ "test": "bunx vitest --coverage"
44
44
  },
45
45
  "types": "./src/types/global.d.ts",
46
+ "main": "./dist/es/ns.es.js",
46
47
  "exports": {
47
48
  ".": {
48
49
  "types": "./src/types/global.d.ts",
@@ -51,7 +52,7 @@
51
52
  "default": "./dist/es/ns.es.js"
52
53
  }
53
54
  },
54
- "source": "./src/composables/ns.ts",
55
+ "source": "./dist/es/ns.es.js",
55
56
  "unpkg": "./dist/iife/ns.iife.js",
56
57
  "devDependencies": {
57
58
  "@eslint/js": "^9.28.0",
@@ -68,9 +69,7 @@
68
69
  "prettier": "3.5.3",
69
70
  "typescript": "^5.8.3",
70
71
  "typescript-eslint": "^8.33.0",
71
- "vite": "^6.3.5"
72
- },
73
- "dependencies": {
72
+ "vite": "^6.3.5",
74
73
  "vitest": "^3.1.4"
75
74
  }
76
75
  }
package/tests/ns.spec.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="vitest" />
2
1
  import { describe, it, expect, beforeEach } from 'vitest'
3
2
  import {useNs} from "@/composables/ns";
4
3
  import type {INSElement} from "@/interfaces/INSElement";
@@ -1,68 +0,0 @@
1
- name: CI Production
2
-
3
- on:
4
- pull_request:
5
- branches: [ production ]
6
-
7
- jobs:
8
- build-and-test:
9
- runs-on: ubuntu-latest
10
-
11
- steps:
12
- # Checking out the repository with the latest version
13
- - uses: actions/checkout@v4
14
- with:
15
- ref: production
16
-
17
- # Setting up the latest Node.js version
18
- - name: Set up Node.js
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: 'latest'
22
-
23
- # Setting up the latest Bun.js version
24
- - name: Set up Bun.js
25
- uses: oven-sh/setup-bun@v2
26
- with:
27
- bun-version: 'latest'
28
-
29
- # Configuring git for GitHub Actions
30
- - name: Configure Git
31
- run: |
32
- git config --global user.name "GitHub Actions"
33
- git config --global user.email "actions@github.com"
34
- git config --global init.defaultBranch production
35
-
36
- # Installing dependencies using Bun
37
- - name: Install Dependencies
38
- run: bun install
39
-
40
- # Running build using Bun
41
- - name: Run Build
42
- run: bun run build
43
-
44
- # Committing build artifacts to the production branch
45
- - name: Commit Build
46
- run: |
47
- git add .
48
- git commit -m "GitHub Actions: Persist build artifacts[ci skip]" || echo "No changes to commit"
49
- git push origin production
50
- env:
51
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52
-
53
- # Running Vitest with coverage using Bun
54
- - name: Run Vitest with Coverage
55
- run: bunx vitest run --coverage
56
-
57
- # Uploading coverage to Coveralls
58
- - name: Upload Coverage to Coveralls
59
- uses: coverallsapp/github-action@v2
60
- with:
61
- github-token: ${{ secrets.GITHUB_TOKEN }}
62
- path-to-lcov: ./coverage/lcov.info
63
-
64
- # Publishing to NPM
65
- - name: Publish to NPM
66
- run: bunx npm publish
67
- env:
68
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}