CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-floating-ui--react

React library for creating accessible floating UI elements like tooltips, popovers, and dropdowns with advanced positioning

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

core-positioning.mddocs/

Core Positioning

Essential hooks for creating and positioning floating elements with collision detection, automatic updates, and context management.

Capabilities

useFloating Hook

Main hook that provides data to position a floating element and context for adding interactions.

/**
 * Main hook for positioning floating elements
 * @param options - Configuration options for positioning and behavior
 * @returns Positioning data, context, and element refs
 */
function useFloating<RT extends ReferenceType = ReferenceType>(
  options?: UseFloatingOptions<RT>
): UseFloatingReturn<RT>;

interface UseFloatingOptions<RT extends ReferenceType = ReferenceType> {
  placement?: Placement;
  strategy?: Strategy;
  middleware?: Array<Middleware | null | undefined | false>;
  platform?: Platform;
  elements?: {
    reference?: Element | null;
    floating?: HTMLElement | null;
  };
  transform?: boolean;
  whileElementsMounted?: (
    reference: ReferenceType,
    floating: HTMLElement,
    update: () => void
  ) => void | (() => void);
  open?: boolean;
  onOpenChange?: (open: boolean, event?: Event, reason?: OpenChangeReason) => void;
  nodeId?: string;
  rootContext?: FloatingRootContext<RT>;
}

interface UseFloatingReturn<RT extends ReferenceType = ReferenceType> {
  x: number;
  y: number;
  strategy: Strategy;
  placement: Placement;
  middlewareData: MiddlewareData;
  isPositioned: boolean;
  context: FloatingContext<RT>;
  refs: ExtendedRefs<RT>;
  elements: ExtendedElements<RT>;
  floatingStyles: React.CSSProperties;
  update(): void;
}

Usage Examples:

import { useFloating, offset, flip, shift } from '@floating-ui/react';
import { useState } from 'react';

// Basic positioning
function BasicTooltip() {
  const [isOpen, setIsOpen] = useState(false);

  const { refs, floatingStyles, context } = useFloating({
    placement: 'top',
    open: isOpen,
    onOpenChange: setIsOpen,
    middleware: [offset(10), flip(), shift({ padding: 5 })],
  });

  return (
    <>
      <button ref={refs.setReference}>Reference</button>
      {isOpen && (
        <div ref={refs.setFloating} style={floatingStyles}>
          Tooltip
        </div>
      )}
    </>
  );
}

// With external elements
function ExternalElements() {
  const [referenceEl, setReferenceEl] = useState<HTMLElement | null>(null);
  const [floatingEl, setFloatingEl] = useState<HTMLElement | null>(null);

  const { floatingStyles } = useFloating({
    elements: {
      reference: referenceEl,
      floating: floatingEl,
    },
    middleware: [offset(10)],
  });

  return (
    <>
      <button ref={setReferenceEl}>Reference</button>
      <div ref={setFloatingEl} style={floatingStyles}>
        Floating element
      </div>
    </>
  );
}

useFloatingRootContext Hook

Creates a root context that can be shared between multiple floating UI hooks and components.

/**
 * Creates a root context for floating UI state management
 * @param options - Required context configuration
 * @returns Root context for sharing between hooks
 */
function useFloatingRootContext(
  options: UseFloatingRootContextOptions
): FloatingRootContext;

interface UseFloatingRootContextOptions {
  open?: boolean;
  onOpenChange?: (open: boolean, event?: Event, reason?: OpenChangeReason) => void;
  elements: {
    reference: Element | null;
    floating: HTMLElement | null;
  };
}

Usage Example:

import { useFloatingRootContext, useClick, useInteractions } from '@floating-ui/react';
import { useState } from 'react';

function SharedContext() {
  const [isOpen, setIsOpen] = useState(false);
  const [referenceEl, setReferenceEl] = useState<HTMLElement | null>(null);
  const [floatingEl, setFloatingEl] = useState<HTMLElement | null>(null);

  const rootContext = useFloatingRootContext({
    open: isOpen,
    onOpenChange: setIsOpen,
    elements: {
      reference: referenceEl,
      floating: floatingEl,
    },
  });

  const click = useClick(rootContext);
  const { getReferenceProps, getFloatingProps } = useInteractions([click]);

  return (
    <>
      <button ref={setReferenceEl} {...getReferenceProps()}>
        Trigger
      </button>
      {isOpen && (
        <div ref={setFloatingEl} {...getFloatingProps()}>
          Content
        </div>
      )}
    </>
  );
}

useMergeRefs Hook

Merges multiple refs into a single callback ref for component composition.

/**
 * Merges an array of refs into a single memoized callback ref
 * @param refs - Array of refs to merge, including undefined values
 * @returns Single callback ref or null
 */
function useMergeRefs<Instance>(
  refs: Array<React.Ref<Instance> | undefined>
): null | React.RefCallback<Instance>;

Usage Example:

import { useMergeRefs } from '@floating-ui/react';
import { useRef, forwardRef } from 'react';

const MyComponent = forwardRef<HTMLDivElement, {}>((props, ref) => {
  const internalRef = useRef<HTMLDivElement>(null);
  const mergedRef = useMergeRefs([ref, internalRef]);

  return <div ref={mergedRef} {...props} />;
});

useId Hook

React 18's useId hook with fallback for earlier versions.

/**
 * Uses React 18's built-in useId() when available, fallback for earlier versions
 * @returns Unique string ID or undefined
 */
const useId: () => string | undefined;

Usage Example:

import { useId } from '@floating-ui/react';

function LabeledInput() {
  const id = useId();

  return (
    <>
      <label htmlFor={id}>Input Label</label>
      <input id={id} type="text" />
    </>
  );
}

Core Types

interface ExtendedRefs<RT> {
  reference: React.MutableRefObject<ReferenceType | null>;
  floating: React.MutableRefObject<HTMLElement | null>;
  domReference: React.MutableRefObject<NarrowedElement<RT> | null>;
  setReference(node: RT | null): void;
  setFloating(node: HTMLElement | null): void;
  setPositionReference(node: ReferenceType | null): void;
}

interface ExtendedElements<RT> {
  reference: ReferenceType | null;
  floating: HTMLElement | null;
  domReference: NarrowedElement<RT> | null;
}

interface ContextData {
  openEvent?: Event;
  floatingContext?: FloatingContext;
  typing?: boolean;
  [key: string]: any;
}

interface FloatingEvents {
  emit<T extends string>(event: T, data?: any): void;
  on(event: string, handler: (data: any) => void): void;
  off(event: string, handler: (data: any) => void): void;
}

type NarrowedElement<T> = T extends Element ? T : Element;

docs

core-positioning.md

focus-management.md

index.md

interaction-hooks.md

layout-components.md

list-navigation.md

positioning-middleware.md

transitions.md

tree-context.md

tile.json