/**
* 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