mantinedev/mantine · error · Error

Popover.ContextMenu component children should be an element

Error message

Popover.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported

What it means

Popover.ContextMenu attaches right-click/long-press handlers and a ref to its single child to anchor the popover. If getSingleElementChild finds no single element (fragment, string, number, empty), the handlers have nowhere to bind and the component throws.

Source

Thrown at packages/@mantine/core/src/components/Popover/PopoverContextMenu/PopoverContextMenu.tsx:22

import { usePopoverContext } from '../Popover.context';

export interface PopoverContextMenuProps {
  /** Element that opens the popover when right-clicked. Dropdown is positioned at the cursor. The trigger element must not call `event.preventDefault()` in its own `onContextMenu` handler, otherwise the native context menu is not suppressed. */
  children: React.ReactNode;

  /** If set, the right-click trigger is disabled and the browser's default context menu is shown */
  disabled?: boolean;

  /** Delay in ms before a touch long-press opens the dropdown on touch devices, `500` by default */
  longPressDelay?: number;
}

export function PopoverContextMenu(props: PopoverContextMenuProps) {
  const { children, disabled, longPressDelay } = useProps('PopoverContextMenu', null, props);

  const child = getSingleElementChild(children);
  if (!child) {
    throw new Error(
      'Popover.ContextMenu component children should be an element or a component that accepts ref. Fragments, strings, numbers and other primitive values are not supported'
    );
  }

  const ctx = usePopoverContext();

  const handlers = useContextMenuHandlers({
    childProps: child.props as any,
    disabled: disabled || ctx.disabled,
    opened: ctx.opened,
    longPressDelay,
    setReference: ctx.reference as unknown as (node: object) => void,
    open: () => {
      if (!ctx.opened) {
        ctx.onToggle();
      }
    },
  });

View on GitHub (pinned to 8a284e2c2c)

Solutions

  1. Pass a single DOM element or ref-forwarding component as the child
  2. Wrap primitives in a span/div
  3. Add React.forwardRef to custom targets

Example fix

// before
<Popover.ContextMenu>{label}</Popover.ContextMenu>

// after
<Popover.ContextMenu><span>{label}</span></Popover.ContextMenu>
Defensive patterns

Strategy: type-guard

Validate before calling

// Wrap primitives in a span before using them as Popover.ContextMenu child

Type guard

const hasSingleElementChild = (children: React.ReactNode): boolean =>
  Array.isArray(children)
    ? children.filter(Boolean).length === 1 && isElement(children.find(Boolean))
    : isElement(children);

Prevention

When it happens

Trigger: Child of Popover.ContextMenu is a primitive, fragment, multiple siblings, or a non-ref-forwarding component; the disabled prop silences behavior but the children check still runs.

Common situations: Adding right-click popovers to canvas/table UIs where the target got wrapped in a fragment or a non-forwarding HOC.

Related errors


AI-assisted analysis of mantinedev/mantine@8a284e2c2c (2026-08-28). Data as JSON: /api/errors/de3a02c953d96fc7. Report an issue: GitHub.