/** * Timeline — a vertical sequence of events. * * One `value` on the root says how far the sequence has got, and every item * resolves its own state from its `step` against it — completed below, active * at, inactive above. Stating it once is the point: a timeline whose items each * carried their own state would let you write two active items, or none. * * State is resolved in JS and handed down through context into `tv()` variants * rather than being read off the element, because React Native has no * attribute selectors for a stylesheet to key off. `Steps` resolves its states * the same way, so the two read as siblings. * * ## Two orientations * * Vertical is the default and the ordinary case. Horizontal lays the items out * as columns on a rail that runs off the side of the screen and is swiped * through, which is the arrangement a long span of time wants: a decade of * entries read top to bottom is a page nobody reaches the end of. * * The objection to a horizontal timeline is that each item gets a fifth of a * phone's width, which will not hold a date and a title. The answer is that it * does not have to fit — the rail is wider than the screen, and a column takes * the width its contents need. An item with nothing on it collapses to a tick, * so a quiet stretch compresses and a busy one keeps its room. * * ```tsx * * * * 09:12 * Design * * * * * Checkout language approved * 10:18 * * … * * * * ``` */ import { type ReactElement, type ReactNode } from 'react'; import { View, type FlatListProps, type ListRenderItemInfo, type Text as RNText, type ViewProps } from 'react-native'; import { type TextProps } from '../../primitives/text.js'; export type TimelineVariant = 'dot' | 'icon' | 'numbered' | 'card' | 'compact'; /** Semantic colour for a single event, independent of progress. */ export type TimelineTone = 'default' | 'info' | 'success' | 'warning' | 'danger'; /** Which way the sequence runs. */ export type TimelineOrientation = 'vertical' | 'horizontal'; export interface TimelineProps extends ViewProps { className?: string; /** Steps at or below this index render as completed. */ value?: number; variant?: TimelineVariant; /** * Which way the sequence runs. `horizontal` lays the items out as columns on * a rail wider than the screen, swiped through rather than scrolled down. */ orientation?: TimelineOrientation; /** * Horizontal only: land a flick on a column rather than between two. * * On by default, because the thing being moved between is a column — stopping * halfway shows two half-columns and no whole one. */ snap?: boolean; /** * Horizontal only: a tick as the reading edge passes from one column to the * next. Needs `snap`, since a scroll that lands anywhere has no detents to * feel. Off by default — a haptic per column is a lot for a long history, and * whether this one is worth feeling is the caller's call. */ haptics?: boolean; /** * Horizontal only: which column is at the reading edge, reported as it * changes. * * For anything outside the rail that belongs to the column being read — a * masthead naming it, a caption, a picture. Without it that block can only * show the same thing for the whole run, which makes a swipe through ten * columns a swipe under one unchanging heading. * * The index is the column's position among the rendered items, not its * `step`: `step` is the progress value and may be sparse or repeated, so it * cannot address a column. * * It fires on the crossing, not per frame — the reading edge passing from * one column to the next — so it is a state update per column rather than * per scroll event. */ onColumnChange?: (index: number) => void; children?: ReactNode; } export interface TimelineListProps extends Omit, 'data' | 'renderItem' | 'horizontal' | 'getItemLayout' | 'onScroll' | 'snapToOffsets' | 'CellRendererComponent'> { /** Complete event collection; rows outside the native window stay unmounted. */ data: readonly T[]; /** Render one `Timeline.Item`. Its step, width, and last marker are owned by the list. */ renderItem: (info: ListRenderItemInfo) => ReactElement; /** Width of each column, or a resolver for mixed-width histories. */ itemWidth?: number | ((item: T, index: number) => number); /** Steps at or below this index render as completed. */ value?: number; variant?: TimelineVariant; snap?: boolean; } /** * Opt-in bounded mount path for long horizontal histories. The compound * `Timeline` API remains the simpler choice for short or mixed-content lists. */ declare function TimelineList({ data, renderItem, itemWidth: requestedWidth, value, variant, snap, initialNumToRender, maxToRenderPerBatch, windowSize, className, ...props }: TimelineListProps): import("react").JSX.Element; declare namespace TimelineList { var displayName: string; } export interface TimelineItemProps extends ViewProps { className?: string; /** Position in the sequence, zero-based. */ step: number; /** Force the completed state regardless of the timeline's value. */ completed?: boolean; /** Colours the node and label — for event kind rather than progress. */ tone?: TimelineTone; /** Set on the final item so its rail stops at the indicator. */ last?: boolean; /** * Horizontal only: how wide this column is, in points. * * Left out, a column that carries content takes a readable width and one that * carries none collapses to a tick — so a quiet stretch of the sequence * compresses instead of paying full width for nothing. Set it to override * that for a column that needs more or less room than its contents suggest. * It must be finite and greater than zero; invalid values use the content default. */ width?: number; children?: ReactNode; } export interface TimelineIndicatorProps extends ViewProps { className?: string; /** Replaces the default node contents — an icon, say. */ children?: ReactNode; } export interface TimelineStatProps extends ViewProps { className?: string; label: string; value: string; } export interface TimelineMastheadProps extends ViewProps { className?: string; /** * What sits above the two lines — a logo pair, an avatar stack, a single * mark. Anything; the slot only lays it out in a row. */ media?: ReactNode; /** The small line: what kind of thing the run below is. */ label?: string; /** The name of it, in the size the eye lands on first. */ title?: string; /** Anything else, below the title. */ children?: ReactNode; } export declare const Timeline: import("react").ForwardRefExoticComponent> & { List: typeof TimelineList; Item: import("react").ForwardRefExoticComponent>; Aside: import("react").ForwardRefExoticComponent>; Masthead: import("react").ForwardRefExoticComponent>; Indicator: import("react").ForwardRefExoticComponent>; Content: import("react").ForwardRefExoticComponent>; Header: import("react").ForwardRefExoticComponent>; Heading: import("react").ForwardRefExoticComponent>; Date: import("react").ForwardRefExoticComponent>; Label: import("react").ForwardRefExoticComponent>; Meta: import("react").ForwardRefExoticComponent>; Title: import("react").ForwardRefExoticComponent>; Trailing: import("react").ForwardRefExoticComponent>; Description: import("react").ForwardRefExoticComponent>; Stats: import("react").ForwardRefExoticComponent>; Stat: import("react").ForwardRefExoticComponent>; }; export {}; //# sourceMappingURL=index.d.ts.map