StaticanimateStart animating the badge with the given characters or predefined character set
Either an array of characters to cycle through or a key from the predefined charsets
Delay between updates in milliseconds (default: 500)
Error If chars is empty or invalid
static animate(chars: string[] | keyof typeof BadgeAnimator.charsets, delay: number = 500): void {
const characterSet = typeof chars === 'string' ? this.charsets[chars] : chars;
if (!characterSet || characterSet.length < 1) {
throw new Error('At least one character is required for badge animation');
}
void this.clear(); // Clear any existing animation, bumping #generation synchronously
this.#chars = characterSet;
this.#delay = delay;
this.#charIndex = 0;
void this.#updateAnimation(this.#generation);
}
StaticclearStop the badge animation and optionally show a final message
Optional text to display before clearing the badge
How long to show the final text before clearing (in milliseconds)
A promise that resolves once the badge text is set.
static async clear(finalText: string = '', duration: number = 5000): Promise<void> {
this.#generation++;
if (this.#timeoutId) {
clearTimeout(this.#timeoutId);
this.#timeoutId = null;
}
// If there's a final status to set, create a timeout to clear it afterwards
if (finalText) {
await this.#setBadgeText(finalText);
setTimeout(() => {
void this.#setBadgeText('');
}, duration);
} else {
await this.#setBadgeText('');
}
}
StaticsetSet the colors of the badge
OptionalfgColor: stringThe foreground (text) color of the badge (hex color code)
OptionalbgColor: stringThe background color of the badge (hex color code)
static setColor(fgColor?: string, bgColor?: string): void {
if (fgColor) {
chrome.action.setBadgeTextColor({
color: fgColor,
});
}
if (bgColor) {
chrome.action.setBadgeBackgroundColor({
color: bgColor,
});
}
}
StaticsetSet the text of the badge. This also clears the animation
The text to display on the badge
A promise that resolves once the badge text is set.
static async setText(text: string): Promise<void> {
void this.clear(); // Stop any running animation without waiting on its own badge update
await this.#setBadgeText(text);
}
Private Static#setSets the badge text via the promise-based chrome.action API (no
callback), recording any rejection instead of letting it float unhandled.
The badge text to set.
A promise that resolves once the attempt settles — never rejects.
static async #setBadgeText(text: string): Promise<void> {
try {
await chrome.action.setBadgeText({ text });
} catch (error) {
void recordError({
source: 'chrome-api',
message: error instanceof Error ? error.message : String(error),
});
}
}
Private Static#updateUpdate the badge to the next character in the sequence. Bails if generation
no longer matches the current generation — a newer animate() or clear()
call superseded this one while it was awaiting its badge update.
The animation generation this call belongs to.
A promise that resolves once the badge text is set.
static async #updateAnimation(generation: number): Promise<void> {
if (generation !== this.#generation || !this.#chars.length) return;
await this.#setBadgeText(this.#chars[this.#charIndex]);
if (generation !== this.#generation) return;
this.#charIndex = (this.#charIndex + 1) % this.#chars.length;
this.#timeoutId = setTimeout(() => void this.#updateAnimation(generation), this.#delay);
}
A utility class for managing Chrome extension badge animations and styling. Provides methods to animate the badge with different character sets, set colors, and control the animation timing. The badge can be used to show loading states, progress indicators, or other status information in the Chrome extension icon.
Example
Source