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-textO instala el paquete completo e impórtalo
pnpm add orn-ui
import { ShinyText } from 'orn-ui/shiny-text';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.
| 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á. |