/** * TextAnimation — the five ways a piece of text arrives. * * ```tsx * * * * * * ``` * * ## Why one component with five parts * * They are one idea — a value that changes and wants to be seen changing — * and they share every prop that says *how*: `duration`, `delay`, `loop`, * `enabled`. Put on the `TextAnimation` root, those become the defaults for * everything inside it, so a hero with three of these in it is configured once * rather than three times. * * ## What React Native forces * * Nested `Text` is the only thing that gets real line-breaking, and it cannot * be transformed — a `translateY` on it is ignored. So the two parts that * animate a whole string, `Typing` and `Counting`, stay real text and keep * wrapping; the three that slide glyphs past each other lay out as rows of * views, which buys the transform and costs line-breaking. None of the three * is ever a paragraph, so the trade only ever falls the right way. * * ## Why the digits are drawn rather than measured * * A number animated as React state is a re-render per frame. `Counting` runs * the value on the UI thread and only crosses back when the *rounded* number * changes, which for a whole number is a couple of dozen times rather than * sixty a second. The sliding and scrolling parts do not cross back at all: * every digit is already rendered, and the animation is a transform on a * column of them. */ import { type ReactNode } from 'react'; import { type ViewProps } from 'react-native'; import { type TextProps } from '../../primitives/text.js'; export interface TextAnimationProps extends ViewProps { className?: string; /** * How long one pass takes, in milliseconds. What that measures depends on * the part: a keystroke for `Typing`, a phrase's turn on screen for * `Rotating`, the whole journey for the three that count. */ duration?: number; /** How long to wait before starting, in milliseconds. */ delay?: number; /** Start again from the beginning when the run finishes. */ loop?: boolean; /** * Animate at all. `false` draws the finished text or the final number * immediately, which is also what a reduced-motion setting does. */ enabled?: boolean; children?: ReactNode; } /** * Shared configuration, and a row to lay the parts out in. * * Optional in every case — each part works standalone with its own props, and * this is only here so a line with three of them in it says `duration` once. */ declare function TextAnimationRoot({ className, duration, delay, loop, enabled, children, ...props }: TextAnimationProps): import("react").JSX.Element; declare namespace TextAnimationRoot { var displayName: string; } export interface TextAnimationTypingProps extends Omit { className?: string; /** * What to type. An array is typed, held, erased and replaced by the next, * which is the shape a rotating headline wants. */ text: string | string[]; /** Milliseconds per keystroke. */ duration?: number; /** Milliseconds before the first keystroke. */ delay?: number; /** How long a finished string sits before it is erased, in milliseconds. */ hold?: number; /** Start again after the last string. Only means anything for an array. */ loop?: boolean; /** Draw a blinking caret after the text. */ caret?: boolean; /** Styles the caret. */ caretClassName?: string; /** Called once the last string has finished being typed. */ onDone?: () => void; enabled?: boolean; } /** * A string arriving one character at a time. * * The text is React state rather than anything on the UI thread, and it has * to be: a character is a different string, and a string is a re-render * whichever thread decided on it. That is fine at a keystroke every 50-odd * milliseconds, which is three orders of magnitude slower than a frame. * * It reserves no space. A line that grows as it types pushes whatever is under * it down the screen on every keystroke, so give the container a height, or * type into a block that has one already. */ declare function TextAnimationTyping({ className, text, duration, delay, hold, loop, caret, caretClassName, onDone, enabled, ...props }: TextAnimationTypingProps): import("react").JSX.Element; declare namespace TextAnimationTyping { var displayName: string; } export interface TextAnimationRotatingProps extends Omit { className?: string; /** The phrases to cycle. One string never rotates, which is a valid state. */ text: string | string[]; /** How long each phrase holds, in milliseconds. */ duration?: number; /** Milliseconds before the first change. */ delay?: number; enabled?: boolean; } /** * One phrase replaced by the next, the outgoing one leaving upward and the * incoming one arriving from below. * * The box is sized by the longest phrase and not by the current one. A box * that resizes as the words change makes the line around it jump, which is * more distracting than the effect is interesting — and a box sized by the * *first* phrase clips every longer one that follows, which is worse than * either. * * So the width comes from a sizer: every phrase, laid out invisibly in a view * with no height. Yoga still takes a column's width from its children when * their height is fixed at zero, so the box ends up as wide as the longest * phrase and as tall as one line of them. */ declare function TextAnimationRotating({ className, text, duration, delay, enabled, ...props }: TextAnimationRotatingProps): import("react").JSX.Element; declare namespace TextAnimationRotating { var displayName: string; } export interface TextAnimationCountingProps extends Omit { className?: string; /** Where the number ends up. */ value: number; /** Where it starts from. Defaults to zero. */ from?: number; /** How long the whole journey takes, in milliseconds. */ duration?: number; /** Milliseconds before it starts. */ delay?: number; /** Digits after the point. */ decimals?: number; /** * Formatting for the number, as `Intl.NumberFormat` options — a currency, a * percentage, grouped thousands. Falls back to a plain fixed-point string on * an engine whose `Intl` cannot do it. */ formatOptions?: Intl.NumberFormatOptions; enabled?: boolean; } /** * A number counting up to itself. * * The text is rewritten from a Reanimated reaction rather than from state: * sixty re-renders a second for a number that is only ever a string is the * kind of thing that makes an otherwise still screen drop frames. Only the * rounded value crosses back to JavaScript, so the work per frame is one * comparison and, at most, one `setState` on a value that actually changed. */ declare function TextAnimationCounting({ className, value, from, duration, delay, decimals, formatOptions, enabled, ...props }: TextAnimationCountingProps): import("react").JSX.Element; declare namespace TextAnimationCounting { var displayName: string; } export interface TextAnimationSlidingProps extends ViewProps { className?: string; /** The number to show. Each digit rolls to its new value independently. */ value: number; /** Digits after the point. */ decimals?: number; /** Pad the whole part to this many digits with leading zeroes. */ padStart?: number; /** A separator every three digits — `','` for `1,024`. */ thousandSeparator?: string; /** The decimal mark. */ decimalSeparator?: string; /** Styles the digits. */ textClassName?: string; /** Size of the digits, as on `Text`. */ size?: TextProps['size']; /** Weight of the digits, as on `Text`. */ weight?: TextProps['weight']; /** Milliseconds before the roll starts. */ delay?: number; enabled?: boolean; } /** * An odometer: every digit is a column of ten, and each column rolls to the * one it should be showing. * * Nothing here is measured at runtime. A column is ten stacked digits and the * whole thing is moved by a fraction of its own height, so the roll needs no * `onLayout`, no first frame at the wrong offset, and no re-render per digit * per frame. The height comes from one hidden `0` in flow, which is what makes * the column as tall as the font is rather than as tall as a number happens to * be. */ declare function TextAnimationSliding({ className, value, decimals, padStart, thousandSeparator, decimalSeparator, textClassName, size, weight, delay, enabled, ...props }: TextAnimationSlidingProps): import("react").JSX.Element; declare namespace TextAnimationSliding { var displayName: string; } export interface TextAnimationScrollingProps extends ViewProps { className?: string; /** The value to land on. */ value: number; /** The gap between the values either side of it. */ step?: number; /** How many values to show above and below the one in the window. */ around?: number; /** How long the run takes, in milliseconds. */ duration?: number; /** Milliseconds before it starts. */ delay?: number; /** Formatting for each value, as `Intl.NumberFormat` options. */ formatOptions?: Intl.NumberFormatOptions; /** Styles the values. */ textClassName?: string; /** Size of the values, as on `Text`. */ size?: TextProps['size']; /** Weight of the values, as on `Text`. */ weight?: TextProps['weight']; /** * Draw a band behind the value in the window, so the one being chosen is * told apart from the scale around it. */ highlight?: boolean; /** Styles that band. */ highlightClassName?: string; /** * What the top and bottom of the window fade into — a theme token name, or * any colour. It has to be told: the fade is painted, so it can only be the * right colour if it is the colour of whatever is behind the window. * Defaults to `--color-background`; pass `--color-card` inside a card. * * `false` turns the fade off, for a window on a surface that is not one flat * colour. */ fadeColor?: string | false; enabled?: boolean; } /** * A column of values scrolling past a window, coming to rest on one. * * The difference from `Sliding` is what the reader is being told. An odometer * says *this number changed*; a column that scrolls past its neighbours says * *this number was chosen from a scale*, and the values either side of it are * the scale. Reach for it for a target, a threshold, a picked quantity — and * for a plain change of value, reach for the other one. */ declare function TextAnimationScrolling({ className, value, step, around, duration, delay, formatOptions, textClassName, size, weight, highlight, highlightClassName, fadeColor, enabled, ...props }: TextAnimationScrollingProps): import("react").JSX.Element; declare namespace TextAnimationScrolling { var displayName: string; } export declare const TextAnimation: typeof TextAnimationRoot & { Typing: typeof TextAnimationTyping; Rotating: typeof TextAnimationRotating; Counting: typeof TextAnimationCounting; Sliding: typeof TextAnimationSliding; Scrolling: typeof TextAnimationScrolling; }; export {}; //# sourceMappingURL=index.d.ts.map