mui / mui/base-ui

[combobox] Hidden input styles in combobox interferes with dnd operations

Open
#3,019 5 comments 1 reaction 0 assignees View on GitHub
component: combobox has workaround
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

# Hidden input with `position: fixed` interferes with drag-and-drop operations

## Description

The Combobox component creates a hidden input element with `position: fixed; top: 0px; left: 0px;` for form integration and accessibility. When the Combobox is used inside draggable elements (e.g., with `@atlaskit/pragmatic-drag-and-drop` or similar libraries), this fixed positioning causes the hidden input to be positioned at the viewport corner, which interferes with drag-and-drop operations and affects the drag preview.

## Environment

- **Base UI Version**: `@base-ui-components/react` (latest)
- **React Version**: 18.x
- **Browser**: Chrome/Firefox/Safari (all affected)

## Reproduction

1. Create a Combobox component inside a draggable container
2. Implement drag-and-drop using any DnD library (e.g., `@atlaskit/pragmatic-drag-and-drop`, `react-dnd`, etc.)
3. Attempt to drag the container
4. Observe that the hidden input element at the top-left corner of the viewport interferes with the drag operation

### Code Example

```tsx
import { Combobox } from '@base-ui-components/react/combobox';
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';

function DraggableCombobox() {
const ref = useRef(null);

useEffect(() => {
const element = ref.current;
if (!element) return;

return draggable({
element,
getInitialData: () => ({ id: 'item-1' }),
});
}, []);

return (



Select option



{/* ... */}





);
}
```

## Expected Behavior

The hidden input should be positioned relative to its parent container (using `position: absolute`) so it doesn't interfere with drag-and-drop operations or appear outside the component's bounds.

## Actual Behavior

The hidden input is created with inline styles:
```html

```

The `position: fixed; top: 0px; left: 0px;` positions the input at the viewport corner, which:
1. Interferes with drag-and-drop calculations
2. Can affect the drag preview generation
3. May capture unintended pointer events in some scenarios

## Suggested Solution

Change the hidden input's positioning from `fixed` to `absolute` to keep it within its parent's bounds:

```diff
- style="position: fixed; top: 0px; left: 0px; ..."
+ style="position: absolute; top: 0px; left: 0px; ..."
```

This maintains the same visual hiding effect while keeping the element scoped to its container, preventing interference with drag-and-drop operations.

## Workaround

Currently using the `inputRef` prop to manually override the positioning:

```tsx
const hiddenInputRef = useRef(null);

useEffect(() => {
const node = hiddenInputRef.current;
if (node) {
node.style.position = 'absolute';
node.style.pointerEvents = 'none';
}
}, []);

{/* ... */}

```

## Additional Context

This issue affects any use case where Combobox is used within draggable UI elements, which is common in:
- Kanban boards
- Sortable lists
- Draggable cards/panels
- Dynamic layouts with DnD

The hidden input serves an important purpose for accessibility and form integration, so it should remain in the DOM—just with positioning that doesn't interfere with parent element interactions.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.