# useHasOverflow
> Detects whether an element has horizontal or vertical overflow.

Detects whether an element has scrollable overflow horizontally or vertically — i.e. whether its `scrollWidth`/`scrollHeight` exceed its `clientWidth`/`clientHeight`. Optionally observes DOM mutations to keep overflow state up to date.

Use this hook when you need to know whether a container has scrollable content (for example, to toggle a `Card.Header` divider or `Dialog.Body` dividers). For detecting whether rendered content is being clipped (e.g. truncation tooltips), use [`useHasContentOverflow`](https://next.wave-design-system.pages.dev/hooks/use-has-content-overflow.md) — it measures the content's rendered rect with sub-pixel precision and avoids false positives caused by `scrollWidth` rounding.

## Import

```js
import { useHasOverflow } from '@volue/wave-react';
```

## Example

A typical use of this hook is conditionally adding a divider to the header of a scrollable surface like [`Card`](https://next.wave-design-system.pages.dev/components/card.md) or [`Dialog`](https://next.wave-design-system.pages.dev/components/dialog.md) only when its body becomes scrollable. Add or remove items below to see the divider appear and disappear as the body's `scrollHeight` crosses its `clientHeight`.

```jsx
() => {
  const [bodyRef, , hasVerticalOverflow] = useHasOverflow({
    observeMutations: true
  });
  const [count, setCount] = React.useState(3);

  return (
    <Card.Root css={{ maxWidth: 240, maxHeight: 200 }}>
      <Card.Header withDivider={hasVerticalOverflow}>
        {`Items (${count})`}
      </Card.Header>
      <Card.Body ref={bodyRef}>
        <Flex flow="column" gap="spacingXs">
          {Array.from({ length: count }, (_, i) => (
            <Text key={i}>{`Item ${i + 1}`}</Text>
          ))}
        </Flex>
      </Card.Body>
      <Card.Footer as={Flex} variant="withBackground" gap="spacingS">
        <Button
          variant="outline"
          size="small"
          leftIcon={<SvgIcon iconName="add" />}
          onClick={() => setCount(c => c + 1)}
        >
          {'Add'}
        </Button>
        <Button
          variant="outline"
          size="small"
          leftIcon={<SvgIcon iconName="minus" />}
          onClick={() => setCount(c => Math.max(1, c - 1))}
          isDisabled={count <= 1}
        >
          {'Remove'}
        </Button>
      </Card.Footer>
    </Card.Root>
  );
};
```

---

## API reference

### Arguments

| Name               | Type                   | Default               | Description                                                                                                                                                                                       | Required |
| ------------------ | ---------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `observeMutations` | `boolean`              | `false`               | Whether to observe DOM mutations to recheck overflow.                                                                                                                                             |          |
| `mutationOptions`  | `MutationObserverInit` | `{ childList: true }` | Configuration for the [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) when `observeMutations` is `true`. By default, it observes changes to the child list. |          |

### Returns

`[setElement: (el: T | null) => void, hasHorizontalOverflow: boolean, hasVerticalOverflow: boolean]` — A tuple with a ref callback and two booleans indicating overflow state.
