import * as React from 'react'; import { useFloating, type Padding } from '@floating-ui/react-native'; import type { LayoutChangeEvent } from 'react-native'; /** * A physical side, or a logical one that follows the writing direction: * `inline-start` is the left in LTR and the right in RTL. */ export type Side = 'top' | 'right' | 'bottom' | 'left' | 'inline-start' | 'inline-end'; /** The physical side a `Side` resolves to, which is what floating-ui places by. */ export type PhysicalSide = 'top' | 'right' | 'bottom' | 'left'; export type Align = 'start' | 'center' | 'end'; /** * Positions a floating element against an anchor. * * Upstream vendors `floating-ui-react` and drives it from * `utils/useAnchorPositioning.ts`. Here the same engine is used through its * official React Native binding, so `flip`/`shift`/`limitShift`/`arrow` * behave identically instead of being re-derived. * * `sameScrollView: false` makes floating-ui measure the anchor with * `measureInWindow` (and add the Android status bar height), producing screen * coordinates. Popups therefore have to be rendered in a container whose origin * is the top of the screen — which is what a `statusBarTranslucent` `Modal` is. * * There is no `autoUpdate` equivalent: nothing in React Native observes layout * globally. Call `update()` whenever the anchor or the popup is laid out — the * parts wire this to their `onLayout`. */ export declare function useAnchorPositioning(params?: UseAnchorPositioningParameters): UseAnchorPositioningReturnValue; export interface UseAnchorPositioningSharedParameters { /** * Which side of the anchor to position against. * @default 'bottom' */ side?: Side | undefined; /** * Distance between the anchor and the popup, in points. * @default 0 */ sideOffset?: number | undefined; /** * How to align the popup relative to the anchor. * @default 'center' */ align?: Align | undefined; /** * Additional offset along the alignment axis, in points. * @default 0 */ alignOffset?: number | undefined; /** * Minimum distance to keep between the popup and the edge of the screen. * @default 5 */ collisionPadding?: Padding | undefined; /** * Whether to keep the popup anchored even when it would slide off screen, * instead of stopping it at the anchor's edge. * @default false */ sticky?: boolean | undefined; /** * Minimum distance to keep between the arrow and the popup's corners. * @default 5 */ arrowPadding?: number | undefined; } export interface UseAnchorPositioningParameters extends UseAnchorPositioningSharedParameters { /** * Whether the popup is open. Opening re-measures the anchor, which is what * keeps a popup whose content stays mounted from reopening at the position * its trigger had the last time — after the page behind it has scrolled, for * instance. */ open?: boolean | undefined; } export interface UseAnchorPositioningReturnValue { /** * The side the popup was actually placed on, which differs from the requested * `side` when `flip` had to move it. */ side: PhysicalSide; /** * The alignment the popup was actually placed with. */ align: Align; positionerStyles: { position: 'absolute'; left: number; top: number; }; arrowStyles: { left?: number; top?: number; }; arrowRef: React.RefObject; /** * Must be spread onto the `Arrow` part. * * floating-ui's `arrow` middleware needs the arrow element to exist and to * have been measured, and on React Native measuring is asynchronous. The * first position is computed as soon as the anchor and the popup have their * refs — before the arrow has laid out — and nothing observes layout globally * to try again. Without this the middleware returns no data and the arrow * sits in the popup's top-left corner. */ onArrowLayout: (event: LayoutChangeEvent) => void; refs: ReturnType['refs']; /** * Recomputes the position. Nothing observes layout globally in React Native, * so parts call this from their `onLayout`. */ update: () => void; } //# sourceMappingURL=useAnchorPositioning.d.ts.map