Skip to content

floatingUIOptions.useFloatingOptions completely overwrites internal settings instead of merging #2308

@ysds

Description

@ysds

Describe the bug

When passing floatingUIOptions={{ useFloatingOptions: { strategy: "fixed" } }} to components like FormattingToolbarController, SideMenuController, or LinkToolbarController, the internal useFloatingOptions settings (including open, onOpenChange, placement, and middleware) are completely overwritten instead of being merged. This causes the toolbar/menu to not appear at all.

To Reproduce

  1. Use a BlockNoteView inside a scrollable container
  2. Pass floatingUIOptions with useFloatingOptions.strategy: "fixed" to any controller:
<FormattingToolbarController
  floatingUIOptions={{
    useFloatingOptions: { strategy: "fixed" },
  }}
  formattingToolbar={() => <CustomFormattingToolbar />}
/>
  1. The formatting toolbar does not appear when selecting text

Expected behavior

The strategy: "fixed" option should be merged with the internal useFloatingOptions settings, preserving open, onOpenChange, placement, and middleware while adding/overriding only the strategy property.

Root cause

Looking at the source code in FormattingToolbarController:

const c = useMemo(
  () => ({
    useFloatingOptions: {
      open: o,
      onOpenChange: (a, u, d) => { /* ... */ },
      placement: i,
      middleware: [offset(10), shift(), flip()]
    },
    elementProps: { /* ... */ },
    ...e.floatingUIOptions  // <-- This spreads at the top level
  }),
  [/* ... */]
);

The spread ...e.floatingUIOptions replaces the entire useFloatingOptions object if provided, rather than merging nested properties.

Misc

  • Node version: 24.12.0
  • Package manager: npm
  • Browser: Chrome
  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖

Metadata

Metadata

Assignees

Labels

bugIncorrect or unexpected behavior in existing functionality.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions