dioxus-type-animation
A customizable Dioxus typewriter animation component inspired by react-type-animation.
This crate provides a TypeAnimation component with a Rust-friendly API for animated typing/deleting effects, delays, callbacks, repeat behavior, custom wrappers, cursor styling, and custom string splitting.
Installation
Add the crate to your Dioxus project:
[]
= "0.7"
= "0.1"
Usage
Basic usage
use *;
use ;
Sequence items
The sequence prop accepts three kinds of items:
SequenceElement::Text(String)/SequenceElement::from("text")— transition to this text.SequenceElement::Delay(u64)/SequenceElement::from(1000_u64)— wait for this many milliseconds.SequenceElement::Callback(Rc<dyn Fn()>)/SequenceElement::from(|| { ... })— run a callback.
use *;
use ;
Repeat behavior
By default, a sequence runs once. Repeat::Count(n) means the animation runs once plus n repeats, matching react-type-animation behavior. Use Repeat::Infinite to loop forever.
use *;
use ;
Speed options
Speed::Preset(value) mirrors the React library's speed={value} prop. Numeric speed values are normalized to abs(value - 100) milliseconds per keystroke, then randomized by ±50% for a natural typing rhythm.
Use Speed::KeyStrokeDelayInMs(value) for an exact base keystroke delay in milliseconds, equivalent to React's { type: "keyStrokeDelayInMs", value } option.
use *;
use ;
Omit deletion animation
Set omit_deletion_animation to true to jump directly to the deletion end-state and only animate writing the new text.
use *;
use ;
Wrapper elements
The default wrapper is Wrapper::Span. You can choose from p, div, span, strong, a, h1-h6, and b via the Wrapper enum.
use *;
use ;
Cursor styling
The blinking cursor is enabled by default. The component automatically injects CSS equivalent to:
.dioxus-type-after
@keyframes dioxus-type-animation__cursor
Disable it with cursor: false:
use *;
use ;
Pre-render the first string
Set pre_render_first_string to true to render the first string immediately before animation starts.
use *;
use ;
Accessibility attributes
You can pass aria_label, aria_hidden, and role. When aria_label is set, the animated visual text is rendered inside an inner aria-hidden="true" span so assistive technology reads the stable label instead of every intermediate typing state.
use *;
use ;
Custom splitter
The default splitter uses text.chars(), similar to JavaScript's [...text]. If you need grapheme-aware splitting for complex emoji or combined characters, provide your own splitter.
use *;
use ;
use Rc;
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
sequence |
Vec<SequenceElement> |
required | Animation sequence of text, delays, and callbacks. |
repeat |
Repeat |
Repeat::Count(0) |
Number of repeats or infinite loop. |
wrapper |
Wrapper |
Wrapper::Span |
HTML element used as wrapper. |
speed |
Speed |
Speed::Preset(40) |
Typing speed. |
deletion_speed |
Option<Speed> |
None |
Deletion speed. Falls back to speed. |
omit_deletion_animation |
bool |
false |
Skip animated deletion steps. |
cursor |
bool |
true |
Show default blinking cursor. |
pre_render_first_string |
bool |
false |
Render first string before animation starts. |
splitter |
Option<StringSplitter> |
None |
Custom text splitting function. |
class |
Option<String> |
None |
Class applied to wrapper. |
style |
Option<String> |
None |
Inline style applied to wrapper. |
aria_label |
Option<String> |
None |
Wrapper aria-label. |
aria_hidden |
Option<String> |
None |
Wrapper aria-hidden. |
role |
Option<String> |
None |
Wrapper role. |
Notes
Like the React implementation, TypeAnimation is intentionally immutable: prop changes are treated as equal and do not restart the animation. If you need to restart with different props, mount a new component instance, for example by changing its Dioxus key.
Callbacks are Rust closures (Rc<dyn Fn()>) instead of React callbacks receiving an HTMLElement | null. The Dioxus implementation drives text with signals rather than directly mutating the DOM.