# components/Overlay (zidane-ui)

Import: `import { … } from 'zidane-ui'`. Source: [ui/src/components/Overlay.tsx](https://github.com/Tahul/zidane/blob/main/ui/src/components/Overlay.tsx).

## Components

### `Overlay`

Component.

Renders a layer above the page through a portal: a scrim that fades in and out, with the
surface drawn by `children`. It adds scroll lock, Esc to close, focus return on close and,
with `trapFocus`, a modal focus trap that makes the rest of the page inert. The layer stays
mounted until the scrim's exit finishes.

```ts
function Overlay(props: OverlayProps): ReactPortal | null
```

**Parameters**

- `props` (`OverlayProps`): Component props.

**Returns** `ReactPortal | null`

**Props**

- `children` (`(state: 'open' | 'closed') => ReactNode`): Renders the surface. It receives `open` or `closed`, to put on the surface's `data-state`. The
  state is `closed` on the first frame and during exit, so CSS has a from-state.
- `className?` (`string`): Position of the layer (the scrim fills it).
- `closeOnEscape?` (`boolean`, default `true`): Close the layer on Esc while it is the topmost layer.
- `exitMs?` (`number`, deprecated): Exit duration in milliseconds. Ignored.

  **Deprecated.** The exit lasts as long as its motion; kept so older callers compile.
- `inertSelector?` (`string`): Elements made `inert` while open (e.g. `main, footer`).
- `onClose` (`() => void`): Called when the scrim is clicked, or on Esc when `closeOnEscape` is on.
- `open` (`boolean`): Whether the layer is shown.
- `scrimClassName?` (`string`, default `''`): Extra classes on the scrim.
- `style?` (`CSSProperties`): Inline styles on the root element, merged after the component's own.
- `trapFocus?` (`boolean`, default `true`): Make the layer modal: focus moves in on open, Tab stays inside, and the rest of `body` goes
  inert.

Source: [ui/src/components/Overlay.tsx:250](https://github.com/Tahul/zidane/blob/main/ui/src/components/Overlay.tsx#L250)

## Functions

### `useLayer`

Function.

The behaviour of a layer whose root (`layerRef`, a child of `body`) is
portaled by the caller: scroll lock, stacking, Esc, focus and the inert
background, as described above. Overlay and Lightbox both run on it.
Returns whether this layer is the topmost one right now, for a caller
that handles more keys of its own.

```ts
function useLayer(
  open: boolean,
  layerRef: RefObject<HTMLElement | null>,
  options?: LayerOptions,
): () => boolean
```

**Parameters**

- `open` (`boolean`): Whether the layer is open. Scroll lock, stacking, Esc handling and the focus trap
  run only while it is.
- `layerRef` (`RefObject<HTMLElement | null>`): Ref to the layer's root element, a child of `body` the caller portals.
- `options?` (`LayerOptions`, default `{}`): Esc handling, focus trap and inert background options, see [`LayerOptions`](https://zidane.si/docs/reference/ui-components-overlay.md#LayerOptions).

**Returns** `() => boolean`

Source: [ui/src/components/Overlay.tsx:110](https://github.com/Tahul/zidane/blob/main/ui/src/components/Overlay.tsx#L110)

## Interfaces

### `LayerOptions`

Interface.

Options of [`useLayer`](https://zidane.si/docs/reference/ui-components-overlay.md#useLayer).

```ts
interface LayerOptions
```

**Properties**

- `inertSelector?` (`string`): Elements made `inert` while open (e.g. `main, footer`).
- `initialFocus?` (`RefObject<HTMLElement | null>`): Where focus lands on open when nothing inside took it already; else the first control, else the layer.
- `onEscape?` (`() => void`): Called on Esc while this is the topmost layer. Omit to leave Esc alone (it still never reaches a layer below).
- `trapFocus?` (`boolean`): Modal: focus moves in, Tab stays in, the rest of `body` goes inert. Default true.

Source: [ui/src/components/Overlay.tsx:87](https://github.com/Tahul/zidane/blob/main/ui/src/components/Overlay.tsx#L87)

### `OverlayProps`

Interface.

Props for [`Overlay`](https://zidane.si/docs/reference/ui-components-overlay.md#Overlay).

```ts
interface OverlayProps
```

**Properties**

- `children` (`(state: 'open' | 'closed') => ReactNode`): Renders the surface. It receives `open` or `closed`, to put on the surface's `data-state`. The
  state is `closed` on the first frame and during exit, so CSS has a from-state.
- `className?` (`string`): Position of the layer (the scrim fills it).
- `closeOnEscape?` (`boolean`, default `true`): Close the layer on Esc while it is the topmost layer.
- `exitMs?` (`number`, deprecated): Exit duration in milliseconds. Ignored.

  **Deprecated.** The exit lasts as long as its motion; kept so older callers compile.
- `inertSelector?` (`string`): Elements made `inert` while open (e.g. `main, footer`).
- `onClose` (`() => void`): Called when the scrim is clicked, or on Esc when `closeOnEscape` is on.
- `open` (`boolean`): Whether the layer is shown.
- `scrimClassName?` (`string`, default `''`): Extra classes on the scrim.
- `style?` (`CSSProperties`): Inline styles on the root element, merged after the component's own.
- `trapFocus?` (`boolean`, default `true`): Make the layer modal: focus moves in on open, Tab stays inside, and the rest of `body` goes
  inert.

Source: [ui/src/components/Overlay.tsx:202](https://github.com/Tahul/zidane/blob/main/ui/src/components/Overlay.tsx#L202)
