# ShinyText

> Atom — orn-ui

> ⚠️ Requiere <UIProvider>: Este componente (como todos los de orn-ui) debe renderizarse dentro de un ancestro <UIProvider>, o lanza un error en runtime. See https://orn-ui-docs.vercel.app/getting-started.md

> Corre en Expo SDK 54, 55, 56 y 57, y en React Native puro >=0.81 con react >=19.1. Sin módulos nativos — funciona en Expo Go, sin prebuild.

## Instalación

Instala solo este componente (copia el código fuente a tu proyecto, sin dependencia npm)
```bash
npx orn-ui add shiny-text
```

O instala el paquete completo e impórtalo
```tsx
pnpm add orn-ui
import { ShinyText } from 'orn-ui/shiny-text';
```

Depende de: core (theme + icons), transition

## Variantes

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

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

### duration and delay — slow sweep, long pause

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

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

```tsx
<VariantRow>
  <ShinyText text="No sweep at all" animated={false} {...strong} />
</VariantRow>
```

## Código completo del demo

```tsx
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

| Nombre | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `text` | `string` | — | El texto a animar. Sólo un string: el efecto necesita los caracteres. |
| `duration?` | `number` | 2400 | Milisegundos que tarda un barrido de punta a punta. |
| `delay?` | `number` | 600 | Pausa entre barridos, en ms. |
| `spread?` | `number` | 0.28 | Ancho de la banda brillante como fracción del texto, de 0 a 1. Valores chicos dan un destello angosto; grandes, un latido. |
| `animated?` | `boolean` | true | En false dibuja texto plano en `shineColor`. |
| `color?` | `string` | theme.colors.textLight | Color de los caracteres en reposo. |
| `shineColor?` | `string` | theme.colors.primary | Color de la banda que lo recorre. |
| `align?` | `'left' \| 'center' \| 'right'` | left | Alineación horizontal de la línea. |
| `style?` | `StyleProp<TextStyle>` | — | Sólo tipografía: `color` y `shineColor` ganan sobre cualquier color puesto acá. |
