CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-floating-ui--dom

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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>;
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@floating-ui/dom@1.7.x
Publish Source
CLI
Badge
tessl/npm-floating-ui--dom badge