orn-ui
Atom

ShinyText

Requiere <UIProvider> — Primeros pasos →

Instalación

Instala solo este componente (copia el código fuente a tu proyecto, sin dependencia npm)

npx orn-ui add shiny-text

O instala el paquete completo e impórtalo

pnpm add orn-ui
import { ShinyText } from 'orn-ui/shiny-text';
Depende de:core (theme + icons)transition

Uso

  • cuándo usarlo — Una banda de luz recorre el texto para decir "mirá acá" sin un badge ni un ícono: una tarjeta de upgrade, una etiqueta de beta, el único titular de una pantalla de bienvenida. Uno por pantalla — dos barridos compitiendo no dicen nada.
  • cómo funciona — El texto se parte en caracteres y la opacidad de cada uno sale de un solo valor compartido, así que el efecto entero corre en el hilo nativo. Necesita los caracteres: text recibe un string, no nodos.
  • color / shineColor — El color en reposo y el de la banda que lo recorre. Los dos salen de roles del theme, así que el efecto sigue a una marca propia sin que haya que decírselo.
  • spread — Cuán ancha es la banda, como fracción del texto. Chico es un destello sobre uno o dos caracteres; grande enciende casi toda la línea a la vez y se lee como un latido.
  • animated — En false dibuja texto plano en shineColor — la salida para quien pidió menos movimiento, y el estado que conviene en un test de snapshot.
Clip del demo todavía sin grabar — ver MEDIA.md

Variantes

align="center" — wraps by word on several lines

<ShinyText text="A headline long enough to wrap onto more than one line" align="center" {...strong} />

duration and delay — slow sweep, long pause

<ShinyText text="Taking its time" duration={4000} delay={1200} {...strong} />

animated={false} — plain text in shineColor, same box

<VariantRow>
  <ShinyText text="No sweep at all" animated={false} {...strong} />
</VariantRow>
Código completo del demo
function ColorPairs() {
  const colors = useColors();

  return (
    <View style={{ gap: 16 }}>
      <View style={{ gap: 4 }}>
        <Caption>default — textLight resting, primary shining</Caption>
        <ShinyText text="Default pair" />
      </View>
      <View style={{ gap: 4 }}>
        <Caption>border → text — the widest pair the theme has</Caption>
        <ShinyText text="Maximum contrast" color={colors.border} shineColor={colors.text} />
      </View>
    </View>
  );
}

function Spreads() {
  const colors = useColors();

  return (
    <View style={{ gap: 12 }}>
      <ShinyText text="Narrow glint" spread={0.08} color={colors.border} shineColor={colors.text} />
      <ShinyText text="Soft wide wave" spread={0.6} color={colors.border} shineColor={colors.text} />
    </View>
  );
}

function UpgradeCard() {
  const colors = useColors();

  return (
    <Card>
      <ShinyText text="Pro plan" color={colors.primarySoft} shineColor={colors.primary} />
      <Body style={{ marginTop: 4 }}>Unlimited invoices · priority support</Body>
    </Card>
  );
}

export function ShinyTextDemo() {
  const colors = useColors();
  // El par por defecto sólo cambia luminancia; para mirar *cómo* se mueve la
  // banda conviene el par más separado del tema, que cambia tono también.
  const strong = { color: colors.border, shineColor: colors.text };

  const variants: VariantDef[] = [
    {
      label: 'colors — the resting/shine pair is what makes it readable',
      content: <ColorPairs />,
    },
    {
      label: 'align="center" — wraps by word on several lines',
      content: (
        <ShinyText text="A headline long enough to wrap onto more than one line" align="center" {...strong} />
      ),
    },
    {
      label: 'spread — narrow glint vs. soft wave',
      content: <Spreads />,
    },
    {
      label: 'duration and delay — slow sweep, long pause',
      content: <ShinyText text="Taking its time" duration={4000} delay={1200} {...strong} />,
    },
    {
      label: 'animated={false} — plain text in shineColor, same box',
      content: (
        <VariantRow>
          <ShinyText text="No sweep at all" animated={false} {...strong} />
        </VariantRow>
      ),
    },
    {
      label: 'in a card, with the brand accent',
      content: <UpgradeCard />,
    },
  ];
  return <VariantList variants={variants} />;

Props

Además acepta testID, que se reenvía al nodo raíz. Existe para los tests end-to-end (Maestro maneja la app por el árbol de accesibilidad) y no cambia en nada cómo se ve ni cómo se comporta el componente.

NombreTipoPor defectoDescripción
textstringEl texto a animar. Sólo un string: el efecto necesita los caracteres.
duration?number2400Milisegundos que tarda un barrido de punta a punta.
delay?number600Pausa entre barridos, en ms.
spread?number0.28Ancho de la banda brillante como fracción del texto, de 0 a 1. Valores chicos dan un destello angosto; grandes, un latido.
animated?booleantrueEn false dibuja texto plano en `shineColor`.
color?stringtheme.colors.textLightColor de los caracteres en reposo.
shineColor?stringtheme.colors.primaryColor de la banda que lo recorre.
align?'left' | 'center' | 'right'leftAlineación horizontal de la línea.
style?StyleProp<TextStyle>Sólo tipografía: `color` y `shineColor` ganan sobre cualquier color puesto acá.