<PageCard>

# useDismiss

Closes the floating element when a dismissal is requested — by
default, when the user presses the `escape` key or outside of the
floating element with their pointer.

```js
import {useDismiss} from '@floating-ui/react';
```

This is useful to ensure the floating element is closed when the
user is finished interacting with it, including keyboard support.

<ShowFor packages={['react-dom']}>

<PackageLimited>@floating-ui/react only</PackageLimited>

</ShowFor>

</PageCard>

## Usage

This Hook returns event handler props.

To use it, pass it the `context{:.const}` object returned from
`useFloating(){:js}`, and then feed its result into the
`useInteractions(){:js}` array. The returned prop getters are
then spread onto the elements for rendering.

```js {9-13} /context/
function App() {
  const [isOpen, setIsOpen] = useState(false);

  const {refs, floatingStyles, context} = useFloating({
    open: isOpen,
    onOpenChange: setIsOpen,
  });

  const dismiss = useDismiss(context);

  const {getReferenceProps, getFloatingProps} = useInteractions([
    dismiss,
  ]);

  return (
    <>
      <div ref={refs.setReference} {...getReferenceProps()}>
        Reference element
      </div>
      {isOpen && (
        <div
          ref={refs.setFloating}
          style={floatingStyles}
          {...getFloatingProps()}
        >
          Floating element
        </div>
      )}
    </>
  );
}
```

## Props

```ts
interface UseDismissProps {
  enabled?: boolean;
  escapeKey?: boolean;
  referencePress?: boolean;
  referencePressEvent?: 'pointerdown' | 'mousedown' | 'click';
  outsidePress?: boolean | ((event: MouseEvent) => boolean);
  outsidePressEvent?: 'pointerdown' | 'mousedown' | 'click';
  ancestorScroll?: boolean;
  bubbles?:
    | boolean
    | {escapeKey?: boolean; outsidePress?: boolean};
  capture?:
    | boolean
    | {escapeKey?: boolean; outsidePress?: boolean};
}
```

### `enabled{:.key}`

default: `true{:js}`

Conditionally enable/disable the Hook.

```js
useDismiss(context, {
  enabled: false,
});
```

### `escapeKey{:.key}`

default: `true{:js}`

Whether to dismiss the floating element upon pressing the `esc`
key.

```js
useDismiss(context, {
  escapeKey: false,
});
```

### `referencePress{:.key}`

default: `false{:js}`

Whether to dismiss the floating element upon pressing the
reference element.

```js
useDismiss(context, {
  referencePress: true,
});
```

You likely want to ensure the `move{:.key}` option in the
`useHover(){:js}` hook has been disabled when this is in use.

#### Keyboard press dismissal

If you'd like to ensure the floating element is also dismissed
upon "pressing" the reference element via the keyboard, you can
add in your own handler(s) for this.

```js
getReferenceProps({
  // for a native <button>
  onClick() {
    setOpen(false);
  },
});
```

### `referencePressEvent{:.key}`

default: `'pointerdown'{:js}`

The type of event to use to determine a "press".

```js
useDismiss(context, {
  // Eager on both mouse + touch input.
  referencePressEvent: 'pointerdown',
  // Eager on mouse input; lazy on touch input.
  referencePressEvent: 'mousedown',
  // Lazy on both mouse + touch input.
  referencePressEvent: 'click',
});
```

### `outsidePress{:.key}`

default: `true{:js}`

Whether to dismiss the floating element upon pressing outside of
both the floating and reference elements.

```js
useDismiss(context, {
  outsidePress: false,
});
```

If you have another element, like a toast, that is rendered
outside the floating element's React tree and don't want the
floating element to close when pressing it, you can guard the
check like so:

```js
useDismiss(context, {
  // Same as `true`, but with a custom guard check.
  outsidePress: (event) => !event.target.closest('.toast'),
});
```

<Notice>
  This option handles many edge cases, including browser
  extension elements injected after the floating element renders
  to prevent them from closing. If your toast is injected after
  render, this won't be necessary.
</Notice>

```js
function App() {
  // The toast is not inside the Dialog's React tree, so we
  // need to add a guard to consider it a child of the Dialog
  // to prevent the Dialog's outside press from closing it.
  return (
    <>
      <Dialog />
      <Toast className="toast" />
    </>
  );
}
```

### `outsidePressEvent{:.key}`

default: `'pointerdown'{:js}`

The type of event to use to determine a "press".

```js
useDismiss(context, {
  // Eager on both mouse + touch input.
  outsidePressEvent: 'pointerdown',
  // Eager on mouse input; lazy on touch input.
  outsidePressEvent: 'mousedown',
  // Lazy on both mouse + touch input.
  outsidePressEvent: 'click',
});
```

### `ancestorScroll{:.key}`

default: `false{:js}`

Whether to dismiss the floating element upon scrolling an
overflow ancestor.

```js
useDismiss(context, {
  ancestorScroll: true,
});
```

### `bubbles{:.key}`

default: `undefined{:js}`

Determines whether event listeners bubble upwards through a tree
of floating elements.

- `escapeKey{:.key}` determines whether pressing the `esc` key
  bubbles, causing ancestor floating elements to dismiss as well.
  For instance, if you're dismissing a tooltip inside a dialog
  using the `esc` key, you likely don't want the dialog to
  dismiss as well until a second key press, which is the default
  behavior.
- `outsidePress{:.key}` determines whether pressing outside of a
  child floating element bubbles, causing ancestor floating
  elements to dismiss as well. Setting this to `false{:js}`
  requires a [`FloatingTree`](/docs/FloatingTree) to be set up.

```js
useDismiss(context, {
  // Configure bubbling for all relevant events:
  bubbles: false,
  // Or, individually configure by event:
  bubbles: {
    escapeKey: true, // false by default
    outsidePress: false, // true by default
  },
});
```

### `capture{:.key}`

default: `undefined{:js}`

Determines whether to use capture phase event listeners.

```js
useDismiss(context, {
  // Configure capturing for all relevant events:
  capture: true,
  // Or, individually configure by event:
  capture: {
    escapeKey: true, // false by default
    outsidePress: false, // true by default
  },
});
```

## Reacting to dismissal

To react to the dismissal event, you can check for the
`reason{:.param}` string in the `onOpenChange{:.function}`
callback:

```js /reason/
useFloating({
  open: isOpen,
  onOpenChange(nextOpen, event, reason) {
    setIsOpen(nextOpen);

    // Other ones include 'reference-press' and 'ancestor-scroll'
    // if enabled.
    if (reason === 'escape-key' || reason === 'outside-press') {
      console.log('Dismissed');
    }
  },
});
```

## Troubleshooting

### Does not close when clicking in an iframe

You can use the
[`FloatingOverlay` component](/docs/FloatingOverlay) which will
"cover" iframes to ensure clicks are captured in the same
document as the floating element, as the click occurs on the
overlay backdrop. This guarantees "outside press" detection will
work.
