UNPKG

@base-ui-components/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

204 lines 6.81 kB
import * as React from 'react'; import { type Rect } from '@floating-ui/utils'; import { useFloating, type FloatingRootContext, type VirtualElement, type Padding, type FloatingContext, type Side as PhysicalSide, type Middleware, type FloatingTreeStore } from "../floating-ui-react/index.js"; export type Side = 'top' | 'bottom' | 'left' | 'right' | 'inline-end' | 'inline-start'; export type Align = 'start' | 'center' | 'end'; export type Boundary = 'clipping-ancestors' | Element | Element[] | Rect; export type OffsetFunction = (data: { side: Side; align: Align; anchor: { width: number; height: number; }; positioner: { width: number; height: number; }; }) => number; interface SideFlipMode { /** * How to avoid collisions on the side axis. */ side?: 'flip' | 'none'; /** * How to avoid collisions on the align axis. */ align?: 'flip' | 'shift' | 'none'; /** * If both sides on the preferred axis do not fit, determines whether to fallback * to a side on the perpendicular axis and which logical side to prefer. */ fallbackAxisSide?: 'start' | 'end' | 'none'; } interface SideShiftMode { /** * How to avoid collisions on the side axis. */ side?: 'shift' | 'none'; /** * How to avoid collisions on the align axis. */ align?: 'shift' | 'none'; /** * If both sides on the preferred axis do not fit, determines whether to fallback * to a side on the perpendicular axis and which logical side to prefer. */ fallbackAxisSide?: 'start' | 'end' | 'none'; } export type CollisionAvoidance = SideFlipMode | SideShiftMode; /** * Provides standardized anchor positioning behavior for floating elements. Wraps Floating UI's * `useFloating` hook. */ export declare function useAnchorPositioning(params: useAnchorPositioning.Parameters): useAnchorPositioning.ReturnValue; export interface UseAnchorPositioningSharedParameters { /** * An element to position the popup against. * By default, the popup will be positioned against the trigger. */ anchor?: Element | null | VirtualElement | React.RefObject<Element | null> | (() => Element | VirtualElement | null); /** * Determines which CSS `position` property to use. * @default 'absolute' */ positionMethod?: 'absolute' | 'fixed'; /** * Which side of the anchor element to align the popup against. * May automatically change to avoid collisions. * @default 'bottom' */ side?: Side; /** * Distance between the anchor and the popup in pixels. * Also accepts a function that returns the distance to read the dimensions of the anchor * and positioner elements, along with its side and alignment. * * The function takes a `data` object parameter with the following properties: * - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. * - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. * - `data.side`: which side of the anchor element the positioner is aligned against. * - `data.align`: how the positioner is aligned relative to the specified side. * * @example * ```jsx * <Positioner * sideOffset={({ side, align, anchor, positioner }) => { * return side === 'top' || side === 'bottom' * ? anchor.height * : anchor.width; * }} * /> * ``` * * @default 0 */ sideOffset?: number | OffsetFunction; /** * How to align the popup relative to the specified side. * @default 'center' */ align?: Align; /** * Additional offset along the alignment axis in pixels. * Also accepts a function that returns the offset to read the dimensions of the anchor * and positioner elements, along with its side and alignment. * * The function takes a `data` object parameter with the following properties: * - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. * - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. * - `data.side`: which side of the anchor element the positioner is aligned against. * - `data.align`: how the positioner is aligned relative to the specified side. * * @example * ```jsx * <Positioner * alignOffset={({ side, align, anchor, positioner }) => { * return side === 'top' || side === 'bottom' * ? anchor.width * : anchor.height; * }} * /> * ``` * * @default 0 */ alignOffset?: number | OffsetFunction; /** * An element or a rectangle that delimits the area that the popup is confined to. * @default 'clipping-ancestors' */ collisionBoundary?: Boundary; /** * Additional space to maintain from the edge of the collision boundary. * @default 5 */ collisionPadding?: Padding; /** * Whether to maintain the popup in the viewport after * the anchor element was scrolled out of view. * @default false */ sticky?: boolean; /** * Minimum distance to maintain between the arrow and the edges of the popup. * * Use it to prevent the arrow element from hanging out of the rounded corners of a popup. * @default 5 */ arrowPadding?: number; /** * Whether to disable the popup from tracking any layout shift of its positioning anchor. * @default false */ disableAnchorTracking?: boolean; /** * Determines how to handle collisions when positioning the popup. * * @example * ```jsx * <Positioner * collisionAvoidance={{ * side: 'shift', * align: 'shift', * fallbackAxisSide: 'none', * }} * /> * ``` * */ collisionAvoidance?: CollisionAvoidance; } export interface UseAnchorPositioningParameters extends useAnchorPositioning.SharedParameters { keepMounted?: boolean; trackCursorAxis?: 'none' | 'x' | 'y' | 'both'; floatingRootContext?: FloatingRootContext; mounted: boolean; disableAnchorTracking: boolean; nodeId?: string; adaptiveOrigin?: Middleware; collisionAvoidance: CollisionAvoidance; shiftCrossAxis?: boolean; lazyFlip?: boolean; externalTree?: FloatingTreeStore; } export interface UseAnchorPositioningReturnValue { positionerStyles: React.CSSProperties; arrowStyles: React.CSSProperties; arrowRef: React.RefObject<Element | null>; arrowUncentered: boolean; side: Side; align: Align; physicalSide: PhysicalSide; anchorHidden: boolean; refs: ReturnType<typeof useFloating>['refs']; context: FloatingContext; isPositioned: boolean; update: () => void; } export declare namespace useAnchorPositioning { type SharedParameters = UseAnchorPositioningSharedParameters; type Parameters = UseAnchorPositioningParameters; type ReturnValue = UseAnchorPositioningReturnValue; } export {};