Typing Animation
RzTypingAnimation renders typewriter-style text for one string or a sequence of words. It is a single component backed by Alpine.js that emits stable SSR markup with a predictable root Id, making it straightforward to replace with HTMX partial swaps.
Under the Hood
The component initializes x-data="rzTypingAnimation" on a direct Alpine child container, uses a hidden source span when Words is not supplied, gates optional startup with IntersectionObserver, and runs a timer-based typing/deleting loop. There is no teleport strategy and no Blazor runtime interactivity.
Basic Usage
<RzTypingAnimation>Hello World! 👋</RzTypingAnimation>Multiple Words and Looping
<RzTypingAnimation Words="@(["Design 🎨", "Build 🔨", "Ship 🚀"])" Loop="true" />Timing Controls
<RzTypingAnimation
Words="@(["Fast typing", "Slow delete"])"
TypeSpeed="50"
DeleteSpeed="150"
PauseDelay="2000"
Delay="300"
Loop="true" />Cursor Options
<RzTypingAnimation Words="@(["No cursor"])" ShowCursor="false" />
<RzTypingAnimation Words="@(["Blink on"])" BlinkCursor="true" Loop="true" />
<RzTypingAnimation Words="@(["Blink off"])" BlinkCursor="false" Loop="true" />
<RzTypingAnimation Words="@(["Line cursor"])" CursorStyle="TypingAnimationCursorStyle.Line" Loop="true" />
<RzTypingAnimation Words="@(["Block cursor"])" CursorStyle="TypingAnimationCursorStyle.Block" Loop="true" />
<RzTypingAnimation Words="@(["Underscore cursor"])" CursorStyle="TypingAnimationCursorStyle.Underscore" Loop="true" />Start on View
<div class="min-h-[32rem]">
<div class="h-56"></div>
<RzTypingAnimation Words="@(["Starts when visible"])" StartOnView="true" />
</div>HTMX Integration
Docs limitation
This static docs site does not execute a real endpoint call here, but the markup below is the production HTMX replacement pattern.
<div id="typing-animation-region">
<RzTypingAnimation Words="@(["Initial", "Server state"])" Loop="true" />
</div>
<RzButton
hx-get="/components/typing-animation/partial"
hx-target="#typing-animation-region"
hx-swap="outerHTML">
Replace Animation via HTMX
</RzButton>app.MapGet("/components/typing-animation/partial", () =>
{
return Results.Content(
"<div id=\"typing-animation-region\"><span>...server-rendered RzTypingAnimation output...</span></div>",
"text/html");
});Non-Loop Final Word Behavior
<RzTypingAnimation Words="@(["Plan", "Build", "Done"])" Loop="false" />Component Parameters
| Property | Description | Type | Default |
|---|---|---|---|
ChildContent | Text source used when Words is not supplied. | RenderFragment? | null |
Words | Sequence of words or phrases to animate. | IReadOnlyList<string>? | null |
Duration | Base typing speed in milliseconds per character. | int | 100 |
TypeSpeed | Optional typing-speed override. | int? | null |
DeleteSpeed | Optional delete-speed override, defaults to half typing speed. | int? | null |
Delay | Initial delay before first typing tick. | int | 0 |
PauseDelay | Pause duration after a word is fully typed. | int | 1000 |
Loop | Repeats the sequence continuously when true. | bool | false |
StartOnView | Defers starting until visible in the viewport. | bool | true |
ShowCursor | Renders the cursor slot when true. | bool | true |
BlinkCursor | Applies blink animation class to the visible cursor. | bool | true |
CursorStyle | Controls line, block, or underscore cursor glyph. | TypingAnimationCursorStyle | TypingAnimationCursorStyle.Line |
Element | Overrides the outer root element tag. | string? | "span" |
Id | Stable id used for Alpine root mapping and replacement targeting. | string? | auto-generated |
Interoperability Note
The Alpine state machine is internal implementation detail. Supported integration is SSR replacement (for example, HTMX swaps) or full server rerender, not direct consumer calls into Alpine methods.