Components Text Animation

Petal Pro is the full SaaS app this is built for

Auth, billing, admin, and Claude Code integration included. One purchase, unlimited projects.

Text Animation

Animated text effects for hero sections and landing pages. Gradient and shimmer are pure CSS. Word rotate and the typing effect use small JS hooks but render their full text server-side, so they still work without JavaScript and search engines see real text.
Gradient text

Text filled with a gradient that sweeps from end to end. Pure CSS, no hook required. Set the font size and weight with the class attr.

Build Phoenix apps faster
heex

Change the colors with color_from and color_to, and the sweep time with duration.

From idea to production
heex
Shimmer text

Muted text with a band of light passing over it, the classic "✨ Introducing ..." pill treatment. Pure CSS. Control the speed with duration.

✨ Introducing Petal Components v4
heex
Word rotate

Cycles through a list of words with a smooth roll-up transition. Requires the PetalWordRotate hook from the petal_components JS bundle, and the id attr is required. The first word is rendered server-side, so there's no layout jump and crawlers see a complete sentence.

Petal makes your app beautiful.
heex
Typing effect

Types text out character by character with a blinking caret. Requires the PetalTypingEffect hook from the petal_components JS bundle, and the id attr is required. The full text is rendered server-side and replayed on mount, so it reads fine without JavaScript and stays visible to search engines. Set loop to delete and retype forever.

mix igniter.install petal_components
heex
Properties

gradient_text

elixir
          
  attr :color_from, :string, default: "#ffaa40", doc: "start color of the gradient"
  attr :color_to, :string, default: "#9c40ff", doc: "end color of the gradient"
  attr :duration, :string, default: "8s", doc: "time for one full gradient sweep"
  attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
  attr :rest, :global

  slot :inner_block, required: true
  
        

shimmer_text

elixir
          
  attr :duration, :string, default: "2.5s", doc: "time for one full shimmer pass"
  attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
  attr :rest, :global

  slot :inner_block, required: true
  
        

word_rotate

elixir
          
  attr :id, :string, required: true
  attr :words, :list, required: true, doc: "the words to cycle through"
  attr :interval, :integer, default: 2500, doc: "milliseconds each word stays on screen"
  attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
  attr :rest, :global
  
        

typing_effect

elixir
          
  attr :id, :string, required: true
  attr :text, :string, required: true, doc: "the text to type out"
  attr :speed, :integer, default: 60, doc: "milliseconds per character"
  attr :start_delay, :integer, default: 0, doc: "milliseconds to wait before typing starts"
  attr :loop, :boolean, default: false, doc: "delete the text and type it again, forever"
  attr :cursor, :boolean, default: true, doc: "show a blinking caret"
  attr :class, :any, default: nil, doc: "extra classes (set font size/weight here)"
  attr :rest, :global