HextaUI

Shimmer

Uma faixa de luz que varre o texto em estados em andamento, com tom derivado da cor do texto e parada com movimento reduzido.

Thinking about your question…

export function ShimmerDemo() {
  return (
    <p className="shimmer text-base text-muted-foreground">
      Thinking about your question…
    </p>
  )
}

Shimmer é um utilitário do Tailwind vindo do tailwind.css do shadcn. O tema do HextaUI já o importa, então se você adicionou o tema ou qualquer componente, já o tem.

pnpm dlx shadcn@latest add https://hextaui.com/r/theme.json

Sem o tema, instale shadcn e importe seu CSS depois do Tailwind.

pnpm add shadcn
app/globals.css
@import "tailwindcss";
@import "shadcn/tailwind.css";
<p className="shimmer text-muted-foreground">Generating response…</p>

Use em textos curtos que descrevem trabalho em andamento, como um assistente pensando, um arquivo sendo processado ou uma etapa em execução. O destaque em movimento diz "ainda trabalhando" sem um spinner ocupando espaço ao lado das palavras.

O texto é pintado com um gradiente via background-clip: text, e uma faixa mais clara desliza sobre ele. A faixa deriva da própria cor do texto, então combina com texto atenuado, em primeiro plano ou colorido sem configuração, e fica mais brilhante no modo escuro, onde uma faixa mais clara se lê melhor.

  • Com movimento reduzido, o gradiente é removido por completo e o texto é renderizado na cor normal.
  • Em layouts da direita para a esquerda a varredura se inverte, então continua percorrendo no sentido de leitura.
  • O texto continua sendo texto de verdade: selecionável, pesquisável e lido normalmente pelos leitores de tela.

Opções

Velocidade, largura da faixa, cor e ângulo são, cada um, uma classe.

export function ShimmerOptions() {
  return (
    <div className="flex flex-col items-start gap-4 text-sm">
      <p className="shimmer text-muted-foreground shimmer-duration-1000">
        Faster: shimmer-duration-1000
      </p>
      <p className="shimmer text-muted-foreground shimmer-spread-24">
        Wider band: shimmer-spread-24
      </p>
      <p className="shimmer text-foreground shimmer-color-info">
        Tinted: shimmer-color-info
      </p>
      <p className="shimmer text-muted-foreground shimmer-angle-45">
        Steeper: shimmer-angle-45
      </p>
    </div>
  )
}

Atualizações de status

Faça o shimmer enquanto uma tarefa roda e depois varra uma vez com shimmer-once ao terminar. Mudar a key reinicia a varredura a cada novo passo.

"use client"

import * as React from "react"
import { cn } from "cn"

import { Button } from "@/components/ui/button"

const steps = ["Reading files…", "Planning changes…", "Writing code…"]

export function ShimmerStatus() {
  const [step, setStep] = React.useState<number | null>(null)

  React.useEffect(() => {
    if (step === null || step >= steps.length) {
      return
    }
    const timer = setTimeout(() => setStep(step + 1), 1600)
    return () => clearTimeout(timer)
  }, [step])

  const done = step !== null && step >= steps.length

  return (
    <div className="flex flex-col items-center gap-4">
      <p
        key={step ?? "idle"}
        role="status"
        className={cn(
          "h-5 text-sm text-muted-foreground",
          step !== null && "shimmer",
          done && "shimmer-duration-1200 shimmer-once"
        )}
      >
        {step === null ? "Ready" : done ? "Done." : steps[step]}
      </p>
      <Button variant="outline" size="sm" onClick={() => setStep(0)}>
        Run task
      </Button>
    </div>
  )
}
<p className="shimmer md:shimmer-none">Generating response…</p>
<p className="shimmer shimmer-reverse">Undoing…</p>
  • Mantenha em uma ou duas linhas. Um parágrafo cintilando cansa a leitura.
  • Coloque o texto em uma região role="status" quando ele muda, para que o novo passo seja anunciado. O shimmer em si é decoração.
  • Para blocos de placeholder em vez de texto, use Skeleton, que faz as superfícies cintilarem com o animate-shimmer do tema.
ClasseDescrição
shimmerVarre um destaque pelo texto, a cada 2s.
shimmer-onceVarre uma vez em vez de repetir.
shimmer-reverseVarre no sentido oposto.
shimmer-noneDesliga, por exemplo em um breakpoint.
shimmer-color-<color>Cor do destaque, do tema ou arbitrária. Aceita um modificador de opacidade.
shimmer-duration-<ms>Duração de uma varredura em milissegundos.
shimmer-spread-<number>Largura da faixa na escala de espaçamento, ou qualquer comprimento. O padrão é 3ch + 40px.
shimmer-angle-<deg>Inclinação da faixa. O padrão é 20°.