unicode-animations 0.1.9 → 1.0.0
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 +69 -88
- package/dist/braille.cjs +22 -38
- package/dist/braille.d.cts +1 -1
- package/dist/braille.d.ts +1 -1
- package/dist/braille.global.js +385 -0
- package/dist/braille.js +1 -1
- package/dist/{chunk-MLXIK7E7.js → chunk-F2BWZODB.js} +22 -38
- package/dist/index.cjs +22 -38
- package/dist/index.js +1 -1
- package/package.json +33 -8
- package/scripts/demo.cjs +48 -15
- package/scripts/demo.html +512 -0
- package/scripts/postinstall.cjs +108 -56
package/README.md
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Unicode spinner animations as raw frame data — no dependencies, works everywhere.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Demo
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
See all 18 spinners animating live:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx unicode-animations --web # open browser demo
|
|
11
|
+
npx unicode-animations # cycle through all in terminal
|
|
12
|
+
npx unicode-animations helix # preview a specific spinner
|
|
13
|
+
npx unicode-animations --list # list all spinners
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
## Install
|
|
@@ -32,7 +33,7 @@ Each spinner is a `{ frames: string[], interval: number }` object.
|
|
|
32
33
|
|
|
33
34
|
## Examples
|
|
34
35
|
|
|
35
|
-
###
|
|
36
|
+
### CLI tool — spinner during async work
|
|
36
37
|
|
|
37
38
|
```js
|
|
38
39
|
import spinners from 'unicode-animations';
|
|
@@ -41,114 +42,103 @@ const { frames, interval } = spinners.braille;
|
|
|
41
42
|
let i = 0;
|
|
42
43
|
|
|
43
44
|
const spinner = setInterval(() => {
|
|
44
|
-
process.stdout.write(`\r ${frames[i++ % frames.length]}
|
|
45
|
+
process.stdout.write(`\r\x1B[2K ${frames[i++ % frames.length]} Deploying to production...`);
|
|
45
46
|
}, interval);
|
|
46
47
|
|
|
47
|
-
await
|
|
48
|
+
await deploy();
|
|
48
49
|
|
|
49
50
|
clearInterval(spinner);
|
|
50
|
-
process.stdout.write('\r ✔
|
|
51
|
+
process.stdout.write('\r\x1B[2K ✔ Deployed.\n');
|
|
51
52
|
```
|
|
52
53
|
|
|
53
|
-
###
|
|
54
|
-
|
|
55
|
-
The grid-based spinners produce wider animated patterns — useful for visual flair in CLI tools:
|
|
54
|
+
### Reusable spinner helper
|
|
56
55
|
|
|
57
56
|
```js
|
|
58
57
|
import spinners from 'unicode-animations';
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
function createSpinner(msg, name = 'braille') {
|
|
60
|
+
const { frames, interval } = spinners[name];
|
|
61
|
+
let i = 0, text = msg;
|
|
62
|
+
const timer = setInterval(() => {
|
|
63
|
+
process.stdout.write(`\r\x1B[2K ${frames[i++ % frames.length]} ${text}`);
|
|
64
|
+
}, interval);
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
return {
|
|
67
|
+
update(msg) { text = msg; },
|
|
68
|
+
stop(msg) { clearInterval(timer); process.stdout.write(`\r\x1B[2K ✔ ${msg}\n`); },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const s = createSpinner('Connecting to database...');
|
|
73
|
+
const db = await connect();
|
|
74
|
+
s.update(`Running ${migrations.length} migrations...`);
|
|
75
|
+
await db.migrate(migrations);
|
|
76
|
+
s.stop('Database ready.');
|
|
66
77
|
```
|
|
67
78
|
|
|
68
|
-
###
|
|
79
|
+
### Multi-step pipeline
|
|
69
80
|
|
|
70
81
|
```js
|
|
71
82
|
import spinners from 'unicode-animations';
|
|
72
83
|
|
|
73
|
-
function
|
|
84
|
+
async function runWithSpinner(label, fn, name = 'braille') {
|
|
85
|
+
const { frames, interval } = spinners[name];
|
|
74
86
|
let i = 0;
|
|
75
|
-
const { frames, interval } = spinner;
|
|
76
87
|
const timer = setInterval(() => {
|
|
77
|
-
process.stdout.write(`\r\x1B[2K ${frames[i++ % frames.length]} ${
|
|
88
|
+
process.stdout.write(`\r\x1B[2K ${frames[i++ % frames.length]} ${label}`);
|
|
78
89
|
}, interval);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
clearInterval(timer);
|
|
84
|
-
process.stdout.write(`\r\x1B[2K ✔ ${finalMsg}\n`);
|
|
85
|
-
},
|
|
86
|
-
};
|
|
90
|
+
const result = await fn();
|
|
91
|
+
clearInterval(timer);
|
|
92
|
+
process.stdout.write(`\r\x1B[2K ✔ ${label}\n`);
|
|
93
|
+
return result;
|
|
87
94
|
}
|
|
88
95
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
await
|
|
93
|
-
spin.stop('Done.');
|
|
96
|
+
await runWithSpinner('Linting...', lint, 'scan');
|
|
97
|
+
await runWithSpinner('Running tests...', test, 'helix');
|
|
98
|
+
await runWithSpinner('Building...', build, 'cascade');
|
|
99
|
+
await runWithSpinner('Publishing...', publish, 'braille');
|
|
94
100
|
```
|
|
95
101
|
|
|
96
|
-
###
|
|
102
|
+
### React component
|
|
97
103
|
|
|
98
|
-
```
|
|
104
|
+
```jsx
|
|
105
|
+
import { useState, useEffect } from 'react';
|
|
99
106
|
import spinners from 'unicode-animations';
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
function Spinner({ name = 'braille', children }) {
|
|
109
|
+
const [frame, setFrame] = useState(0);
|
|
110
|
+
const s = spinners[name];
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
const timer = setInterval(
|
|
114
|
+
() => setFrame(f => (f + 1) % s.frames.length),
|
|
115
|
+
s.interval
|
|
116
|
+
);
|
|
117
|
+
return () => clearInterval(timer);
|
|
118
|
+
}, [name]);
|
|
119
|
+
|
|
120
|
+
return <span style={{ fontFamily: 'monospace' }}>{s.frames[frame]} {children}</span>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Usage: <Spinner name="helix">Generating response...</Spinner>
|
|
111
124
|
```
|
|
112
125
|
|
|
113
|
-
### Browser —
|
|
126
|
+
### Browser — status indicator
|
|
114
127
|
|
|
115
128
|
```js
|
|
116
129
|
import spinners from 'unicode-animations';
|
|
117
130
|
|
|
118
131
|
const el = document.getElementById('status');
|
|
119
|
-
const { frames, interval } = spinners.
|
|
132
|
+
const { frames, interval } = spinners.orbit;
|
|
120
133
|
let i = 0;
|
|
121
134
|
|
|
122
135
|
const spinner = setInterval(() => {
|
|
123
|
-
el.textContent = `${frames[i++ % frames.length]}
|
|
136
|
+
el.textContent = `${frames[i++ % frames.length]} Syncing...`;
|
|
124
137
|
}, interval);
|
|
125
138
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
el.textContent = '✔ Ready';
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### React component
|
|
134
|
-
|
|
135
|
-
```jsx
|
|
136
|
-
import { useState, useEffect } from 'react';
|
|
137
|
-
import spinners from 'unicode-animations';
|
|
138
|
-
|
|
139
|
-
function Spinner({ name = 'braille', text = 'Loading...' }) {
|
|
140
|
-
const [frame, setFrame] = useState(0);
|
|
141
|
-
const spinner = spinners[name];
|
|
142
|
-
|
|
143
|
-
useEffect(() => {
|
|
144
|
-
const timer = setInterval(() => {
|
|
145
|
-
setFrame(f => (f + 1) % spinner.frames.length);
|
|
146
|
-
}, spinner.interval);
|
|
147
|
-
return () => clearInterval(timer);
|
|
148
|
-
}, [name]);
|
|
149
|
-
|
|
150
|
-
return <span>{spinner.frames[frame]} {text}</span>;
|
|
151
|
-
}
|
|
139
|
+
await sync();
|
|
140
|
+
clearInterval(spinner);
|
|
141
|
+
el.textContent = '✔ Synced';
|
|
152
142
|
```
|
|
153
143
|
|
|
154
144
|
## All spinners
|
|
@@ -158,8 +148,8 @@ function Spinner({ name = 'braille', text = 'Loading...' }) {
|
|
|
158
148
|
| Name | Preview | Interval |
|
|
159
149
|
|------|---------|----------|
|
|
160
150
|
| `braille` | `⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏` | 80ms |
|
|
161
|
-
| `braillewave` |
|
|
162
|
-
| `dna` |
|
|
151
|
+
| `braillewave` | `⠁⠂⠄⡀` → `⠂⠄⡀⢀` | 100ms |
|
|
152
|
+
| `dna` | `⠋⠉⠙⠚` → `⠉⠙⠚⠒` | 80ms |
|
|
163
153
|
|
|
164
154
|
### Grid animations (braille)
|
|
165
155
|
|
|
@@ -181,15 +171,6 @@ function Spinner({ name = 'braille', text = 'Loading...' }) {
|
|
|
181
171
|
| `fillsweep` | 11 | 100ms |
|
|
182
172
|
| `diagswipe` | 16 | 60ms |
|
|
183
173
|
|
|
184
|
-
### Non-braille classics
|
|
185
|
-
|
|
186
|
-
| Name | Preview | Interval |
|
|
187
|
-
|------|---------|----------|
|
|
188
|
-
| `arc` | `◜ ◠ ◝ ◞ ◡ ◟` | 100ms |
|
|
189
|
-
| `halfmoon` | `◐ ◓ ◑ ◒` | 180ms |
|
|
190
|
-
| `line` | `\| / — \` | 100ms |
|
|
191
|
-
| `blocks` | `▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▇ ▆ ▅ ▄ ▃ ▂` | 100ms |
|
|
192
|
-
|
|
193
174
|
## Custom spinners
|
|
194
175
|
|
|
195
176
|
Create your own braille spinners using the grid utilities:
|
|
@@ -228,7 +209,7 @@ interface Spinner {
|
|
|
228
209
|
| `gridToBraille(grid)` | `(boolean[][]) => string` |
|
|
229
210
|
| `makeGrid(rows, cols)` | `(number, number) => boolean[][]` |
|
|
230
211
|
| `Spinner` | TypeScript interface |
|
|
231
|
-
| `BrailleSpinnerName` | Union type of all
|
|
212
|
+
| `BrailleSpinnerName` | Union type of all 18 spinner names |
|
|
232
213
|
|
|
233
214
|
### Exports from `'unicode-animations/braille'`
|
|
234
215
|
|
package/dist/braille.cjs
CHANGED
|
@@ -56,6 +56,7 @@ function gridToBraille(grid) {
|
|
|
56
56
|
return result;
|
|
57
57
|
}
|
|
58
58
|
function makeGrid(rows, cols) {
|
|
59
|
+
if (rows <= 0 || cols <= 0) return [];
|
|
59
60
|
return Array.from({ length: rows }, () => Array(cols).fill(false));
|
|
60
61
|
}
|
|
61
62
|
function genScan() {
|
|
@@ -334,31 +335,31 @@ var spinners = {
|
|
|
334
335
|
},
|
|
335
336
|
braillewave: {
|
|
336
337
|
frames: [
|
|
337
|
-
"\u2801\u2802\u2804\u2840
|
|
338
|
-
"\
|
|
339
|
-
"\
|
|
340
|
-
"\u2820\u2810
|
|
341
|
-
"\u2880\u2820\u2810\u2808
|
|
342
|
-
"\
|
|
343
|
-
"\
|
|
344
|
-
"\u2802\u2804
|
|
338
|
+
"\u2801\u2802\u2804\u2840",
|
|
339
|
+
"\u2802\u2804\u2840\u2880",
|
|
340
|
+
"\u2804\u2840\u2880\u2820",
|
|
341
|
+
"\u2840\u2880\u2820\u2810",
|
|
342
|
+
"\u2880\u2820\u2810\u2808",
|
|
343
|
+
"\u2820\u2810\u2808\u2801",
|
|
344
|
+
"\u2810\u2808\u2801\u2802",
|
|
345
|
+
"\u2808\u2801\u2802\u2804"
|
|
345
346
|
],
|
|
346
347
|
interval: 100
|
|
347
348
|
},
|
|
348
349
|
dna: {
|
|
349
350
|
frames: [
|
|
350
|
-
"\u280B\u2809\u2819\u281A
|
|
351
|
-
"\u2819\u281A\u2812
|
|
352
|
-
"\
|
|
353
|
-
"\
|
|
354
|
-
"\
|
|
355
|
-
"\
|
|
356
|
-
"\
|
|
357
|
-
"\
|
|
358
|
-
"\
|
|
359
|
-
"\
|
|
360
|
-
"\
|
|
361
|
-
"\
|
|
351
|
+
"\u280B\u2809\u2819\u281A",
|
|
352
|
+
"\u2809\u2819\u281A\u2812",
|
|
353
|
+
"\u2819\u281A\u2812\u2802",
|
|
354
|
+
"\u281A\u2812\u2802\u2802",
|
|
355
|
+
"\u2812\u2802\u2802\u2812",
|
|
356
|
+
"\u2802\u2802\u2812\u2832",
|
|
357
|
+
"\u2802\u2812\u2832\u2834",
|
|
358
|
+
"\u2812\u2832\u2834\u2824",
|
|
359
|
+
"\u2832\u2834\u2824\u2804",
|
|
360
|
+
"\u2834\u2824\u2804\u280B",
|
|
361
|
+
"\u2824\u2804\u280B\u2809",
|
|
362
|
+
"\u2804\u280B\u2809\u2819"
|
|
362
363
|
],
|
|
363
364
|
interval: 80
|
|
364
365
|
},
|
|
@@ -377,24 +378,7 @@ var spinners = {
|
|
|
377
378
|
checkerboard: { frames: genCheckerboard(), interval: 250 },
|
|
378
379
|
helix: { frames: genHelix(), interval: 80 },
|
|
379
380
|
fillsweep: { frames: genFillSweep(), interval: 100 },
|
|
380
|
-
diagswipe: { frames: genDiagonalSwipe(), interval: 60 }
|
|
381
|
-
// === Non-braille classics ===
|
|
382
|
-
arc: {
|
|
383
|
-
frames: ["\u25DC", "\u25E0", "\u25DD", "\u25DE", "\u25E1", "\u25DF"],
|
|
384
|
-
interval: 100
|
|
385
|
-
},
|
|
386
|
-
halfmoon: {
|
|
387
|
-
frames: ["\u25D0", "\u25D3", "\u25D1", "\u25D2"],
|
|
388
|
-
interval: 180
|
|
389
|
-
},
|
|
390
|
-
line: {
|
|
391
|
-
frames: ["|", "/", "\u2014", "\\"],
|
|
392
|
-
interval: 100
|
|
393
|
-
},
|
|
394
|
-
blocks: {
|
|
395
|
-
frames: ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588", "\u2587", "\u2586", "\u2585", "\u2584", "\u2583", "\u2582"],
|
|
396
|
-
interval: 100
|
|
397
|
-
}
|
|
381
|
+
diagswipe: { frames: genDiagonalSwipe(), interval: 60 }
|
|
398
382
|
};
|
|
399
383
|
var braille_default = spinners;
|
|
400
384
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/braille.d.cts
CHANGED
|
@@ -9,7 +9,7 @@ interface Spinner {
|
|
|
9
9
|
readonly frames: readonly string[];
|
|
10
10
|
readonly interval: number;
|
|
11
11
|
}
|
|
12
|
-
type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe'
|
|
12
|
+
type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe';
|
|
13
13
|
/**
|
|
14
14
|
* Convert a 2D boolean grid into a braille string.
|
|
15
15
|
* grid[row][col] = true means dot is raised.
|
package/dist/braille.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ interface Spinner {
|
|
|
9
9
|
readonly frames: readonly string[];
|
|
10
10
|
readonly interval: number;
|
|
11
11
|
}
|
|
12
|
-
type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe'
|
|
12
|
+
type BrailleSpinnerName = 'braille' | 'braillewave' | 'dna' | 'scan' | 'rain' | 'scanline' | 'pulse' | 'snake' | 'sparkle' | 'cascade' | 'columns' | 'orbit' | 'breathe' | 'waverows' | 'checkerboard' | 'helix' | 'fillsweep' | 'diagswipe';
|
|
13
13
|
/**
|
|
14
14
|
* Convert a 2D boolean grid into a braille string.
|
|
15
15
|
* grid[row][col] = true means dot is raised.
|