or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

auto-update.mdindex.mdmiddleware.mdplatform.md
tile.json

tessl/npm-floating-ui--dom

Floating UI for the web - DOM interface for positioning floating elements like tooltips, popovers, and dropdowns

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@floating-ui/dom@1.7.x

To install, run

npx @tessl/cli install tessl/npm-floating-ui--dom@1.7.0

index.mddocs/

Floating UI DOM

Floating UI DOM is the web implementation of Floating UI, providing a complete solution for positioning floating elements like tooltips, popovers, dropdowns, and menus. It wraps @floating-ui/core with DOM-specific interface logic and offers robust anchor positioning that ensures floating elements stay anchored to their reference elements while avoiding viewport collisions.

Package Information

  • Package Name: @floating-ui/dom
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @floating-ui/dom

Core Imports

import { computePosition, autoUpdate } from "@floating-ui/dom";

For middleware:

import { 
  offset, 
  flip, 
  shift, 
  autoPlacement,
  size,
  hide,
  arrow,
  inline,
  limitShift,
  detectOverflow 
} from "@floating-ui/dom";

For platform:

import { platform } from "@floating-ui/dom";

For types:

import type {
  Placement,
  Strategy,
  Middleware,
  MiddlewareData,
  MiddlewareState,
  ComputePositionReturn,
  VirtualElement,
  Boundary,
  RootBoundary
} from "@floating-ui/dom";

CommonJS:

const { computePosition, autoUpdate, offset, flip, shift } = require("@floating-ui/dom");

Basic Usage

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

// Get reference elements
const referenceElement = document.querySelector("#reference");
const floatingElement = document.querySelector("#floating");

// Compute position
const { x, y } = await computePosition(referenceElement, floatingElement, {
  placement: 'bottom',
  middleware: [
    offset(10),          // Add 10px offset
    flip(),              // Flip when overflowing
    shift({ padding: 5 }) // Shift within padding
  ],
});

// Apply position to floating element
Object.assign(floatingElement.style, {
  position: 'absolute',
  left: `${x}px`,
  top: `${y}px`,
});

Architecture

Floating UI DOM is built around several key components:

  • Core Positioning: computePosition() function that calculates optimal placement coordinates
  • Middleware System: Modular plugins for positioning behaviors (offset, flip, shift, etc.)
  • Auto-Update: Automatic position updates when DOM changes occur
  • Platform Abstraction: DOM platform implementation providing element measurements and calculations
  • Type Safety: Full TypeScript support with comprehensive type definitions

The library uses a platform-agnostic core (@floating-ui/core) with DOM-specific implementations for element measurements, clipping detection, and coordinate calculations.

Capabilities

Core Positioning

Computes the x and y coordinates that will place the floating element next to a given reference element.

function computePosition(
  reference: ReferenceElement,
  floating: FloatingElement,
  options?: Partial<ComputePositionConfig>
): Promise<ComputePositionReturn>;

type ReferenceElement = Element | VirtualElement;
type FloatingElement = HTMLElement;

interface ComputePositionConfig {
  placement?: Placement;
  middleware?: Array<Middleware | null | undefined | false>;
  strategy?: Strategy;
  platform?: Platform;
}

interface ComputePositionReturn {
  x: number;
  y: number;
  placement: Placement;
  strategy: Strategy;
  middlewareData: MiddlewareData;
}

Automatic Updates

Automatically updates the position of the floating element when necessary, returning a cleanup function.

function autoUpdate(
  reference: ReferenceElement,
  floating: FloatingElement,
  update: () => void,
  options?: AutoUpdateOptions
): () => void;

interface AutoUpdateOptions {
  ancestorScroll?: boolean;
  ancestorResize?: boolean;
  elementResize?: boolean;
  layoutShift?: boolean;
  animationFrame?: boolean;
}

Auto-Update

Positioning Middleware

Collection of middleware functions that modify positioning behavior and provide positioning data.

// Core middleware functions
function offset(options?: OffsetOptions): Middleware;
function flip(options?: FlipOptions | Derivable<FlipOptions>): Middleware;
function shift(options?: ShiftOptions | Derivable<ShiftOptions>): Middleware;
function autoPlacement(options?: AutoPlacementOptions | Derivable<AutoPlacementOptions>): Middleware;
function size(options?: SizeOptions | Derivable<SizeOptions>): Middleware;
function hide(options?: HideOptions | Derivable<HideOptions>): Middleware;
function arrow(options: ArrowOptions | Derivable<ArrowOptions>): Middleware;
function inline(options?: InlineOptions | Derivable<InlineOptions>): Middleware;

// Utility
function detectOverflow(
  state: MiddlewareState,
  options?: DetectOverflowOptions | Derivable<DetectOverflowOptions>
): Promise<SideObject>;
function limitShift(options?: LimitShiftOptions | Derivable<LimitShiftOptions>): {
  options: any;
  fn: (state: MiddlewareState) => Coords;
};

Positioning Middleware

Platform API

DOM platform implementation providing element measurements and positioning calculations.

const platform: Platform;

interface Platform {
  // Required methods
  getElementRects(args: {
    reference: ReferenceElement;
    floating: FloatingElement;
    strategy: Strategy;
  }): Promise<ElementRects>;
  getClippingRect(args: {
    element: Element;
    boundary: Boundary;
    rootBoundary: RootBoundary;
    strategy: Strategy;
  }): Promise<Rect>;
  getDimensions(element: Element): Promise<Dimensions>;
  
  // Optional methods
  convertOffsetParentRelativeRectToViewportRelativeRect(args: {
    elements?: Elements;
    rect: Rect;
    offsetParent: Element;
    strategy: Strategy;
  }): Promise<Rect>;
  getOffsetParent(element: Element, polyfill?: (element: HTMLElement) => Element | null): Promise<Element | Window>;
  isElement(value: unknown): Promise<boolean>;
  getDocumentElement(element: Element): Promise<HTMLElement>;
  getClientRects(element: Element): Promise<Array<ClientRectObject>>;
  isRTL(element: Element): Promise<boolean>;
  getScale(element: HTMLElement): Promise<{x: number; y: number}>;
}

Platform API

Core Types

// Element types
interface VirtualElement {
  getBoundingClientRect(): ClientRectObject;
  getClientRects?(): Array<ClientRectObject> | DOMRectList;
  contextElement?: Element;
}

interface ClientRectObject {
  width: number;
  height: number;
  top: number;
  right: number;
  bottom: number;
  left: number;
  x: number;
  y: number;
}

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

// Middleware types
interface Middleware {
  name: string;
  options?: any;
  fn(state: MiddlewareState): Promise<MiddlewareReturn>;
}

interface MiddlewareState {
  x: number;
  y: number;
  initialPlacement: Placement;
  placement: Placement;
  strategy: Strategy;
  middlewareData: MiddlewareData;
  rects: ElementRects;
  elements: Elements;
}

interface MiddlewareReturn extends Partial<Coords> {
  data?: {
    [key: string]: any;
  };
  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;
    };
  };
  size?: {
    availableWidth: number;
    availableHeight: number;
  };
  inline?: {
    alignmentOffset: number;
  };
}

// Utility types
type Derivable<T> = (state: MiddlewareState) => T;
type Boundary = 'clippingAncestors' | Element | Array<Element> | Rect;
type RootBoundary = 'viewport' | 'document' | Rect;
type Axis = 'x' | 'y';

// Placement and positioning types  
type Placement = 'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end';
type Strategy = 'absolute' | 'fixed';
type Side = 'top' | 'right' | 'bottom' | 'left';
type Alignment = 'start' | 'end';

// Geometry types
interface Rect {
  width: number;
  height: number;
  x: number;
  y: number;
}

interface Coords {
  x: number;
  y: number;
}

interface Dimensions {
  width: number;
  height: number;
}

interface ElementRects {
  reference: Rect;
  floating: Rect;
}

interface SideObject {
  top: number;
  right: number;
  bottom: number;
  left: number;
}

Legacy Exports

// Backwards compatibility - will be removed in next major version
function getOverflowAncestors(element: Element): Array<Element>;