ASCII and Unicode animated spinners for Flutter.
One widget, 25+ built-in frame sequences — drop in with zero configuration.
⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏ ← braille (Claude style)
| / - \ ← classic pipe
. .. ... ← dots
◐ ◓ ◑ ◒ ← circle
← ↖ ↑ ↗ → ↘ ↓ ↙ ← arrows
▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ← grow
🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 ← moon
dependencies:
unicode_spinner: ^1.0.0import 'package:unicode_spinner/unicode_spinner.dart';
// Named constructor — zero config:
UnicodeSpinner.braille()
// With custom style and speed:
UnicodeSpinner.braille(
style: TextStyle(fontSize: 20, color: Colors.blue),
interval: Duration(milliseconds: 60),
)
// Fully custom frames:
UnicodeSpinner(
frames: ['⠁', '⠂', '⠄', '⠂'],
interval: Duration(milliseconds: 100),
style: TextStyle(fontSize: 18),
)| Named constructor | Frames | Default interval |
|---|---|---|
UnicodeSpinner.braille() |
⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ |
80 ms |
UnicodeSpinner.brailleFull() |
⣾⣽⣻⢿⡿⣟⣯⣷ |
80 ms |
UnicodeSpinner.brailleQuarter() |
⠁⠂⠄⠂ |
100 ms |
UnicodeSpinner.snake() |
⠈⠐⠠⢀⡀⠄⠂⠁ |
80 ms |
UnicodeSpinner.line() |
| / - \\ |
120 ms |
UnicodeSpinner.pipe() |
┤┘┴└├┌┬┐ |
120 ms |
UnicodeSpinner.dots() |
. .. ... |
300 ms |
UnicodeSpinner.dotsBounce() |
●○○ ○●○ ○○● |
200 ms |
UnicodeSpinner.dot() |
· • · |
400 ms |
UnicodeSpinner.circle() |
◐◓◑◒ |
120 ms |
UnicodeSpinner.triangle() |
◢◣◤◥ |
120 ms |
UnicodeSpinner.box() |
▖▘▝▗ |
120 ms |
UnicodeSpinner.square() |
◰◳◲◱ |
120 ms |
UnicodeSpinner.bowtie() |
⊣⊤⊢⊥ |
120 ms |
UnicodeSpinner.hourglass() |
⧗⧖ |
400 ms |
UnicodeSpinner.arrows() |
← ↖ ↑ ↗ → ↘ ↓ ↙ |
100 ms |
UnicodeSpinner.arrowsBold() |
⇐⇑⇒⇓ |
120 ms |
UnicodeSpinner.bar() |
▏▎▍▌▋▊▉█▉▊… |
60 ms |
UnicodeSpinner.grow() |
▁▂▃▄▅▆▇█▇▆▅▄▃▂▁ |
60 ms |
UnicodeSpinner.pulse() |
█▓▒░▒▓ |
100 ms |
UnicodeSpinner.moon() |
🌑🌒🌓🌔🌕🌖🌗🌘 |
120 ms |
UnicodeSpinner.clock() |
🕛🕐🕑🕒…🕚 |
100 ms |
UnicodeSpinner.earth() |
🌍🌎🌏 |
200 ms |
UnicodeSpinner.star() |
✶✸✹✺✹✷ |
120 ms |
You can also access any frame list directly via Spinners.braille,
Spinners.moon, etc. and pass them to UnicodeSpinner(frames: ...).
| Parameter | Type | Default | Description |
|---|---|---|---|
frames |
List<String> |
— | The sequence of strings to cycle through |
interval |
Duration |
80ms |
How long each frame is shown |
style |
TextStyle? |
ambient | Text style (size, color, weight, font) |
semanticsLabel |
String |
'Loading' |
Accessibility label |
ElevatedButton(
onPressed: isLoading ? null : _submit,
child: isLoading
? const UnicodeSpinner.braille(
style: TextStyle(fontSize: 16, color: Colors.white),
)
: const Text('Submit'),
)Row(
mainAxisSize: MainAxisSize.min,
children: [
const UnicodeSpinner.dots(style: TextStyle(fontSize: 14)),
const SizedBox(width: 8),
const Text('Thinking…'),
],
)if (isLoading)
const Center(
child: UnicodeSpinner.braille(
style: TextStyle(fontSize: 32, color: Colors.white),
),
),// Your own sequence — any Unicode or emoji works:
UnicodeSpinner(
frames: const ['🔴', '🟠', '🟡', '🟢', '🔵', '🟣'],
interval: const Duration(milliseconds: 150),
style: const TextStyle(fontSize: 20),
)UnicodeSpinner is a StatefulWidget that drives a Timer.periodic to
advance through frames. It always reserves fixed width equal to the widest
frame, so your layout never shifts. The Timer is cancelled in dispose —
no leaks.
Contributions welcome! Please open an issue or pull request on GitHub.
MIT © Tekeshwar Singh