Floating

PreviousNext

API reference for @platejs/floating.

@platejs/floating contains the React hooks and rectangle utilities used by floating toolbars, cursor-anchored UI, and virtual elements in Plate. It wraps Floating UI and exports the Floating UI primitives Plate components use.

Installation

pnpm add @platejs/floating
pnpm add @platejs/floating

Ownership

SurfaceOwnerUse
useVirtualFloating@platejs/floatinguseFloating with a controlled virtual reference element.
useFloatingToolbarState@platejs/floatingBuilds toolbar state from editor focus, selection, read-only state, and Floating UI options.
useFloatingToolbar@platejs/floatingTurns toolbar state into DOM props, ref, outside-click ref, and hidden state.
Rect utilities@platejs/floatingConvert editor ranges, DOM selection, and client rect arrays into Floating UI-compatible rects.
Floating UI exports@platejs/floatingRe-exported middleware and hooks from @floating-ui/react.

Virtual Floating

useVirtualFloating creates a Floating UI virtual reference. Use it when the floating element follows a selection, cursor, or computed rectangle instead of a real DOM reference element.

Virtual floating element
import {
  flip,
  getDefaultBoundingClientRect,
  offset,
  useVirtualFloating,
} from '@platejs/floating';
 
export function SelectionPopover({
  open,
  rect,
}: {
  open: boolean;
  rect?: DOMRect;
}) {
  const floating = useVirtualFloating({
    getBoundingClientRect: () => rect ?? getDefaultBoundingClientRect(),
    middleware: [offset(8), flip()],
    open,
    placement: 'top',
  });
 
  return (
    <div ref={floating.refs.setFloating} style={floating.style}>
      Selection actions
    </div>
  );
}
Virtual floating element
import {
  flip,
  getDefaultBoundingClientRect,
  offset,
  useVirtualFloating,
} from '@platejs/floating';
 
export function SelectionPopover({
  open,
  rect,
}: {
  open: boolean;
  rect?: DOMRect;
}) {
  const floating = useVirtualFloating({
    getBoundingClientRect: () => rect ?? getDefaultBoundingClientRect(),
    middleware: [offset(8), flip()],
    open,
    placement: 'top',
  });
 
  return (
    <div ref={floating.refs.setFloating} style={floating.style}>
      Selection actions
    </div>
  );
}

OptionsUseVirtualFloatingOptions

    Supplies the virtual element rect. Defaults to getDefaultBoundingClientRect.

    When false, the returned style sets display: 'none'.

    Defaults to Floating UI autoUpdate.

    Forwarded to Floating UI useFloating.

ReturnsUseVirtualFloatingReturn

    Absolute/fixed position style: position, left, top, display, and visibility.

    Mutable virtual reference element. The hook updates its getBoundingClientRect.

    Floating UI refs. Attach refs.setFloating to the floating element.

    Floating UI manual position update.

Floating Toolbar

Floating toolbar setup is split into two hooks. Build state first, then pass that state to useFloatingToolbar.

Floating toolbar state
import {
  flip,
  offset,
  useFloatingToolbar,
  useFloatingToolbarState,
} from '@platejs/floating';
import { useEditorId, useEventEditorValue } from 'platejs/react';
 
export function ToolbarShell() {
  const editorId = useEditorId();
  const focusedEditorId = useEventEditorValue('focus');
 
  const state = useFloatingToolbarState({
    editorId,
    focusedEditorId,
    floatingOptions: {
      middleware: [offset(12), flip({ padding: 12 })],
      placement: 'top',
    },
  });
 
  const { clickOutsideRef, hidden, props, ref } = useFloatingToolbar(state);
 
  if (hidden) return null;
 
  return (
    <div ref={clickOutsideRef}>
      <div ref={ref} {...props}>
        Toolbar
      </div>
    </div>
  );
}
Floating toolbar state
import {
  flip,
  offset,
  useFloatingToolbar,
  useFloatingToolbarState,
} from '@platejs/floating';
import { useEditorId, useEventEditorValue } from 'platejs/react';
 
export function ToolbarShell() {
  const editorId = useEditorId();
  const focusedEditorId = useEventEditorValue('focus');
 
  const state = useFloatingToolbarState({
    editorId,
    focusedEditorId,
    floatingOptions: {
      middleware: [offset(12), flip({ padding: 12 })],
      placement: 'top',
    },
  });
 
  const { clickOutsideRef, hidden, props, ref } = useFloatingToolbar(state);
 
  if (hidden) return null;
 
  return (
    <div ref={clickOutsideRef}>
      <div ref={ref} {...props}>
        Toolbar
      </div>
    </div>
  );
}

OptionsFloatingToolbarState & { editorId: string; focusedEditorId: string | null }

    Current editor id.

    Focused editor id from useEventEditorValue('focus').

    Options passed to useVirtualFloating.

    Force the toolbar closed.

    Allow the toolbar to show when the editor is read-only.

ReturnsReturnType<typeof useFloatingToolbarState>

    Internal toolbar state for useFloatingToolbar.

OptionsReturnType<typeof useFloatingToolbarState>

    State returned by useFloatingToolbarState.

Returnsobject

    Ref from useOnClickOutside. It closes the toolbar and ignores .ignore-click-outside/toolbar.

    true when the toolbar should not render.

    Props to spread on the toolbar root.

    Floating element ref callback.

The toolbar opens only for an expanded selection with text. It stays hidden while the mouse is down, when hideToolbar is true, when a different editor owns focus, or when the editor is read-only and showWhenReadOnly is not set.

Rectangle Utilities

These helpers normalize editor locations and DOM ranges into rectangles.

Methods

    Returns a zero-size offscreen rect used as a safe Floating UI fallback.

    Creates a Floating UI virtual element with getDefaultBoundingClientRect.

    Creates a ref-like object whose current.getBoundingClientRect() reads editor locations. It throws when no rect exists and no fallbackRect is provided.

    Reads one or more editor locations, converts them to DOM ranges, and returns the merged bounding rect. If at is omitted, it uses editor.selection.

    Returns the DOM rect for a range, or getDefaultBoundingClientRect() when the range or DOM range is missing.

    Returns the selection rect only when the editor selection is expanded. Collapsed selections return the default rect.

    Returns window.getSelection().getRangeAt(0).getBoundingClientRect(), or the default rect when no DOM selection exists.

    Creates a DOMRect-like object and computes width, height, x, and y.

    Merges client rects by min left/top and max right/bottom. It throws when the array is empty.

Floating UI Re-exports

@platejs/floating re-exports the Floating UI middleware and React hooks used by Plate UI, including autoUpdate, flip, hide, inline, offset, shift, size, useFloating, useInteractions, useClick, useDismiss, FloatingPortal, and related types.

Use those exports when a Plate UI component already imports from @platejs/floating; use @floating-ui/react directly only when the component is not coupled to Plate.

  • Toolbar covers the registry floating-toolbar component that consumes these hooks.
  • Plate Store covers useEditorId and useEventEditorValue.