@frixaco/anitrack 0.0.6 → 0.0.8
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/package.json +12 -8
- package/progress-bar.ts +100 -0
package/package.json
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frixaco/anitrack",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"module": "index.ts",
|
|
3
|
+
"version": "0.0.8",
|
|
5
4
|
"type": "module",
|
|
6
5
|
"bin": {
|
|
7
6
|
"anitrack": "./index.ts"
|
|
8
7
|
},
|
|
9
8
|
"files": [
|
|
10
9
|
"index.ts",
|
|
11
|
-
"colors.ts"
|
|
10
|
+
"colors.ts",
|
|
11
|
+
"progress-bar.ts",
|
|
12
|
+
"README.md"
|
|
12
13
|
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"bun": ">=1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
13
20
|
"scripts": {
|
|
14
21
|
"dev": "bun run index.ts"
|
|
15
22
|
},
|
|
16
23
|
"dependencies": {
|
|
17
|
-
"@frixaco/letui": "^0.0.
|
|
24
|
+
"@frixaco/letui": "^0.0.11"
|
|
18
25
|
},
|
|
19
26
|
"devDependencies": {
|
|
20
|
-
"@types/bun": "1.3.
|
|
21
|
-
},
|
|
22
|
-
"peerDependencies": {
|
|
23
|
-
"typescript": "^5"
|
|
27
|
+
"@types/bun": "1.3.9"
|
|
24
28
|
}
|
|
25
29
|
}
|
package/progress-bar.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Node } from "@frixaco/letui";
|
|
2
|
+
import { $, ff, Row, Text } from "@frixaco/letui";
|
|
3
|
+
|
|
4
|
+
export type LoadingBarProps = {
|
|
5
|
+
dotColor: number;
|
|
6
|
+
trackColor: number;
|
|
7
|
+
flexGrow?: number;
|
|
8
|
+
interval?: number; // ms between frames
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type LoadingBarController = {
|
|
12
|
+
node: Node;
|
|
13
|
+
start: () => void;
|
|
14
|
+
stop: () => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function LoadingBar(props: LoadingBarProps): LoadingBarController {
|
|
18
|
+
const { dotColor, trackColor, flexGrow = 1, interval = 80 } = props;
|
|
19
|
+
|
|
20
|
+
const position = $(0);
|
|
21
|
+
const direction = $(1); // 1 = right, -1 = left
|
|
22
|
+
const active = $(false);
|
|
23
|
+
let timer: Timer | null = null;
|
|
24
|
+
|
|
25
|
+
const leftTrack = Text({
|
|
26
|
+
text: "",
|
|
27
|
+
background: trackColor,
|
|
28
|
+
foreground: trackColor,
|
|
29
|
+
});
|
|
30
|
+
const dot = Text({ text: "", background: dotColor, foreground: dotColor });
|
|
31
|
+
const rightTrack = Text({
|
|
32
|
+
text: "",
|
|
33
|
+
background: trackColor,
|
|
34
|
+
foreground: trackColor,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const node = Row({ flexGrow }, [leftTrack, dot, rightTrack]);
|
|
38
|
+
|
|
39
|
+
// React to position changes
|
|
40
|
+
ff(() => {
|
|
41
|
+
const isActive = active();
|
|
42
|
+
const pos = position();
|
|
43
|
+
const width = node.frameWidth();
|
|
44
|
+
if (width === 0 || !isActive) return;
|
|
45
|
+
|
|
46
|
+
const maxPos = width - 1;
|
|
47
|
+
const clampedPos = Math.max(0, Math.min(pos, maxPos));
|
|
48
|
+
|
|
49
|
+
leftTrack.setStyle?.({ text: " ".repeat(clampedPos) });
|
|
50
|
+
dot.setStyle?.({ text: " " });
|
|
51
|
+
rightTrack.setStyle?.({ text: " ".repeat(maxPos - clampedPos) });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
function clearTimer() {
|
|
55
|
+
if (timer) {
|
|
56
|
+
clearInterval(timer);
|
|
57
|
+
timer = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function start() {
|
|
62
|
+
if (active()) return;
|
|
63
|
+
active(true);
|
|
64
|
+
position(0);
|
|
65
|
+
direction(1);
|
|
66
|
+
|
|
67
|
+
timer = setInterval(() => {
|
|
68
|
+
const width = node.frameWidth();
|
|
69
|
+
if (width === 0) return;
|
|
70
|
+
|
|
71
|
+
const maxPos = width - 1;
|
|
72
|
+
const pos = position();
|
|
73
|
+
const dir = direction();
|
|
74
|
+
|
|
75
|
+
const step = 12;
|
|
76
|
+
const nextPos = pos + dir * step;
|
|
77
|
+
if (nextPos >= maxPos) {
|
|
78
|
+
direction(-1);
|
|
79
|
+
position(maxPos);
|
|
80
|
+
} else if (nextPos <= 0) {
|
|
81
|
+
direction(1);
|
|
82
|
+
position(0);
|
|
83
|
+
} else {
|
|
84
|
+
position(nextPos);
|
|
85
|
+
}
|
|
86
|
+
}, interval);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function stop() {
|
|
90
|
+
clearTimer();
|
|
91
|
+
active(false);
|
|
92
|
+
position(0);
|
|
93
|
+
// Clear all three segments
|
|
94
|
+
leftTrack.setStyle?.({ text: "" });
|
|
95
|
+
dot.setStyle?.({ text: "" });
|
|
96
|
+
rightTrack.setStyle?.({ text: "" });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { node, start, stop };
|
|
100
|
+
}
|