or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-middleware.mdbasic-middleware.mdcore-positioning.mdindex.mdoverflow-detection.md
tile.json

core-positioning.mddocs/

Core Positioning

Core positioning functionality providing the main computePosition function for calculating optimal floating element coordinates.

Capabilities

Compute Position

Main function that computes x and y coordinates for positioning floating elements relative to reference elements.

/**
 * Computes the x and y coordinates that will place the floating element
 * next to a given reference element.
 * This export does not have any platform interface logic. You will need to
 * write one for the platform you are using Floating UI with.
 * 
 * @param reference - The reference element
 * @param floating - The floating element
 * @param config - Configuration object
 * @returns Promise resolving to positioning result
 */
function computePosition(
  reference: unknown,
  floating: unknown,
  config: ComputePositionConfig
): Promise<ComputePositionReturn>;

interface ComputePositionConfig {
  /** Object to interface with the current platform (required) */
  platform: Platform;
  /** Where to place the floating element relative to the reference element */
  placement?: Placement;
  /** The strategy to use when positioning the floating element */
  strategy?: Strategy;
  /** Array of middleware objects to modify positioning or provide data */
  middleware?: Array<Middleware | null | undefined | false>;
}

interface ComputePositionReturn {
  /** Final x coordinate for the floating element */
  x: number;
  /** Final y coordinate for the floating element */
  y: number;
  /** The final chosen placement of the floating element */
  placement: Placement;
  /** The strategy used to position the floating element */
  strategy: Strategy;
  /** Object containing data returned from all middleware, keyed by their name */
  middlewareData: MiddlewareData;
}

Usage Examples:

import { computePosition, offset, flip } from "@floating-ui/core";

// Basic positioning
const result = await computePosition(button, tooltip, {
  placement: "top",
  platform: domPlatform
});

// With middleware
const result = await computePosition(button, dropdown, {
  placement: "bottom-start",
  strategy: "absolute",
  middleware: [
    offset(10),
    flip(),
    shift({ padding: 8 })
  ],
  platform: domPlatform
});

// Access computed values
console.log(`Position: ${result.x}, ${result.y}`);
console.log(`Final placement: ${result.placement}`);
console.log(`Middleware data:`, result.middlewareData);

Platform Interface

Required platform interface for DOM operations. Must be implemented for each platform (DOM, React Native, etc.). The first three methods are required; all others are optional but may be needed for advanced features.

interface Platform {
  /** Get element rectangles (required) */
  getElementRects(args: {
    reference: ReferenceElement;
    floating: FloatingElement;
    strategy: Strategy;
  }): Promise<ElementRects> | ElementRects;
  
  /** Get clipping rectangle (required) */
  getClippingRect(args: {
    element: any;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    strategy: Strategy;
  }): Promise<Rect> | Rect;
  
  /** Get element dimensions (required) */
  getDimensions(element: any): Promise<Dimensions> | Dimensions;
  
  /** Convert offset parent relative rect to viewport relative (optional) */
  convertOffsetParentRelativeRectToViewportRelativeRect?(args: {
    elements?: Elements;
    rect: Rect;
    offsetParent: any;
    strategy: Strategy;
  }): Promise<Rect> | Rect;
  
  /** Get offset parent element (optional) */
  getOffsetParent?(element: any): Promise<any> | any;
  
  /** Check if value is an element (optional) */
  isElement?(value: any): Promise<boolean> | boolean;
  
  /** Get document element (optional) */
  getDocumentElement?(element: any): Promise<any> | any;
  
  /** Get client rectangles for inline elements (optional) */
  getClientRects?(element: any): Promise<Array<ClientRectObject>> | Array<ClientRectObject>;
  
  /** Check if element uses RTL direction (optional) */
  isRTL?(element: any): Promise<boolean> | boolean;
  
  /** Get element scale factors (optional) */
  getScale?(element: any): Promise<{x: number; y: number}> | {x: number; y: number};
}

Middleware System

Interface for creating custom middleware that can modify positioning behavior.

interface Middleware {
  /** Unique name for the middleware */
  name: string;
  /** Options passed to the middleware */
  options?: any;
  /** Function that performs the middleware logic */
  fn: (state: MiddlewareState) => Promise<MiddlewareReturn> | MiddlewareReturn;
}

interface MiddlewareState {
  /** Current x coordinate */
  x: number;
  /** Current y coordinate */
  y: number;
  /** Initial placement before middleware modifications */
  initialPlacement: Placement;
  /** Current placement (may be modified by middleware) */
  placement: Placement;
  /** Positioning strategy */
  strategy: Strategy;
  /** Data from previously executed middleware */
  middlewareData: MiddlewareData;
  /** Reference and floating elements */
  elements: Elements;
  /** Element rectangles */
  rects: ElementRects;
  /** Platform interface */
  platform: Platform;
}

interface MiddlewareReturn {
  /** New x coordinate (optional) */
  x?: number;
  /** New y coordinate (optional) */
  y?: number;
  /** Data to store in middlewareData (optional) */
  data?: { [key: string]: any };
  /** Reset positioning with new placement or rects (optional) */
  reset?: boolean | {
    placement?: Placement;
    rects?: boolean | ElementRects;
  };
}

interface MiddlewareData {
  [key: string]: any;
  arrow?: Partial<Coords> & { centerOffset: number; alignmentOffset?: number };
  autoPlacement?: { index?: number; overflows: Array<{ placement: Placement; overflows: Array<number> }> };
  flip?: { index?: number; overflows: Array<{ placement: Placement; overflows: Array<number> }> };
  hide?: { referenceHidden?: boolean; escaped?: boolean; referenceHiddenOffsets?: SideObject; escapedOffsets?: SideObject };
  offset?: Coords & { placement: Placement };
  shift?: Coords & { enabled: { [key in Axis]: boolean } };
}

Custom Middleware Example:

// Custom middleware that adds a random offset
const randomOffset = (): Middleware => ({
  name: "randomOffset",
  fn({ x, y }) {
    return {
      x: x + Math.random() * 10 - 5,
      y: y + Math.random() * 10 - 5,
      data: { randomApplied: true }
    };
  }
});

// Use in computePosition
const result = await computePosition(reference, floating, {
  middleware: [randomOffset()],
  platform: domPlatform
});

Core Types

// Element types
type ReferenceElement = any;
type FloatingElement = any;

interface Elements {
  reference: ReferenceElement;
  floating: FloatingElement;
}

// Boundary types
type Boundary = any;
type RootBoundary = "viewport" | "document" | Rect;
type ElementContext = "reference" | "floating";

// Function option type
type Derivable<T> = (state: MiddlewareState) => T;