/**
* SplitView — two stacked panes whose seam settles on one of a few named
* heights rather than wherever the finger stopped.
*
* ```tsx
*
* {map}
*
*
*
* {list}
*
* ```
*
* The snapping is the difference between this and a free-resize split. A layout
* with a few right answers — a map over a list, a preview over an editor — is
* better served by a control that lands on one of them than by one that lets
* the reader stop three points short of it and live with the result.
*
* Snap points are ratios of the room the two panes share, so they mean the same
* thing on any screen and a rotation costs no re-measuring. That room is the
* container minus the drag area, which takes real layout height: half means
* half of what is actually divisible rather than half of a number the seam then
* eats into.
*
* The split view has no height of its own — give it one, or put it in something
* that has one, or it collapses and takes its panes with it.
*
* Dragging runs on the UI thread. `onSnap` fires once the pane has settled
* rather than on every frame, because a layout that round-trips through React
* sixty times a second is the one thing that makes this feel slow.
*/
import { type ReactNode } from 'react';
import { type ViewProps } from 'react-native';
import { type SharedValue } from 'react-native-reanimated';
export type SplitViewVariant = 'panes' | 'seam';
interface SplitViewContextValue {
/** The top pane's height in points. Written by drags, read by both panes. */
topHeight: SharedValue;
/** True while a finger is on the seam. */
dragging: SharedValue;
/** Snap heights in points, in order. Empty until the container is measured. */
points: number[];
minPx: number;
maxPx: number;
room: number;
measured: boolean;
disabled: boolean;
snapIndex: number;
animate: boolean;
snapTo: (index: number) => void;
measureDragArea: (height: number) => void;
dragAreaHeight: number;
variant: SplitViewVariant;
}
/**
* Reads the live layout from inside a split view, and moves the seam.
*
* `topHeight` is a shared value on the UI thread — read it in a worklet, not in
* render, where it is only ever the number the last commit happened to see.
*/
export declare function useSplitView(): SplitViewContextValue;
export interface SplitViewProps extends ViewProps {
className?: string;
/**
* How the split is drawn. `panes` gives each half its own rounded surface on
* a recessed ground, with the grip in the gap between them; `seam` is a
* hairline grip on a shared background, for a split inside something that
* already has a surface of its own.
*/
variant?: SplitViewVariant;
/**
* Heights the seam settles on. A number at or below `1` is a fraction of the
* room the panes share; anything larger is points. Defaults to
* `[0.2, 0.5, 0.8]`.
*/
snapPoints?: readonly number[];
/** Smallest the top pane may get, as a fraction or in points. Defaults to `100`. */
minHeight?: number;
/**
* Largest the top pane may get, as a fraction or in points. A negative number
* is measured back from the bottom — `-80` leaves eighty points for the other
* pane. Defaults to all the room there is.
*/
maxHeight?: number;
/** Which snap point the seam starts at when uncontrolled. Defaults to `1`. */
defaultSnapIndex?: number;
/** Controlled snap index. Pair it with `onSnapIndexChange`. */
snapIndex?: number;
/** Called with the index the seam settled on. */
onSnapIndexChange?: (index: number) => void;
/** Called once the pane has settled, with the index and its height in points. */
onSnap?: (index: number, topHeight: number) => void;
/** Freezes the seam. The panes keep the heights they have. */
disabled?: boolean;
/** Springs to the starting snap point on mount instead of opening at it. */
animateOnMount?: boolean;
children?: ReactNode;
}
declare function SplitViewRoot({ className, variant, snapPoints, minHeight, maxHeight, defaultSnapIndex, snapIndex: snapIndexProp, onSnapIndexChange, onSnap, disabled, animateOnMount, children, onLayout, ...props }: SplitViewProps): import("react").JSX.Element;
declare namespace SplitViewRoot {
var displayName: string;
}
export interface SplitViewPaneProps extends ViewProps {
className?: string;
children?: ReactNode;
}
/**
* The upper pane.
*
* It clips what is inside it, so a pane dragged short hides its content rather
* than pushing it through the seam. Content that outgrows it is the caller's to
* scroll — put a `ScrollView` in here and it behaves like any other scroller in
* a box whose height changes.
*/
declare function SplitViewTop({ className, children, style, ...props }: SplitViewPaneProps): import("react").JSX.Element;
declare namespace SplitViewTop {
var displayName: string;
}
/**
* The lower pane. It takes exactly the room the upper one gave up, with no
* second measurement — which is what keeps the two adding to the container on
* every frame of a drag rather than only at rest.
*/
declare function SplitViewBottom({ className, children, ...props }: SplitViewPaneProps): import("react").JSX.Element;
declare namespace SplitViewBottom {
var displayName: string;
}
export interface SplitViewDragAreaProps extends ViewProps {
className?: string;
/** What a screen reader calls the seam. Defaults to "Resize panes". */
accessibilityLabel?: string;
children?: ReactNode;
}
/**
* The seam, and the target for the drag.
*
* It takes real layout height rather than floating over the panes, because that
* height is what the snap points are fractions of: a finger-sized target that
* did not take room would make `0.5` mean half of a number the seam then ate
* into. Give it padding to make the target larger — the room it takes is
* measured, so the arithmetic follows.
*/
declare function SplitViewDragArea({ className, accessibilityLabel, children, onLayout, ...props }: SplitViewDragAreaProps): import("react").JSX.Element;
declare namespace SplitViewDragArea {
var displayName: string;
}
export interface SplitViewHandleProps extends ViewProps {
className?: string;
children?: ReactNode;
}
/**
* The grip inside the drag area. It grows a little while the seam is moving,
* which is the only thing on screen saying the gesture was received before the
* panes have moved far enough to say it themselves.
*/
declare function SplitViewHandle({ className, children, style, ...props }: SplitViewHandleProps): import("react").JSX.Element;
declare namespace SplitViewHandle {
var displayName: string;
}
export declare const SplitView: typeof SplitViewRoot & {
Top: typeof SplitViewTop;
Bottom: typeof SplitViewBottom;
DragArea: typeof SplitViewDragArea;
Handle: typeof SplitViewHandle;
};
export { DEFAULT_MIN_HEIGHT, DEFAULT_SNAP_POINTS, nearestSnapIndex, normalizeSnapIndex, resolveLength, resolveSnapPoints, } from './split-view-math.js';
//# sourceMappingURL=index.d.ts.map