# Dismissable Layer
> Lower level component for creating nested layers that can be dismissed one by one by user interactions.

## Import

```js
import { DismissableLayer } from '@gemini-suite/vera-react';
```

## Examples

### Basic

By default, **DismissableLayer** can be dismissed by clicking or touching anywhere outside of it or by pressing <Kbd>Escape</Kbd> key.

```jsx
() => {
  const [isOpen, setIsOpen] = React.useState(false);
  const openButtonRef = React.useRef(null);

  return (
    <Flex flow="column" cross="start">
      <Button ref={openButtonRef} onClick={() => setIsOpen(isOpen => !isOpen)}>
        {isOpen ? 'Close' : 'Open'} layer
      </Button>
      {isOpen ? (
        <DismissableLayer
          as={Slot}
          onDismiss={() => setIsOpen(false)}
          onPointerDownOutside={event => {
            if (event.target === openButtonRef.current) {
              event.preventDefault();
            }
          }}
        >
          <Box
            css={{
              border: '2px dashed $borderNeutralSubtle',
              padding: '$spacingM'
            }}
          >
            Press <Kbd>Escape</Kbd> or click outside me to dismiss.
          </Box>
        </DismissableLayer>
      ) : null}
    </Flex>
  );
};
```

### Prevent dismiss

By calling `event.preventDefault` inside `onPointerDownOutside` or `onEscapeKeyDown` handlers, you can prevent the layer from dismissing.

```jsx
() => {
  const [isOpen, setIsOpen] = React.useState(false);
  const openButtonRef = React.useRef(null);

  return (
    <Flex flow="column" cross="start">
      <Button ref={openButtonRef} onClick={() => setIsOpen(isOpen => !isOpen)}>
        {isOpen ? 'Close' : 'Open'} layer
      </Button>
      {isOpen ? (
        <DismissableLayer
          as={Slot}
          onDismiss={() => setIsOpen(false)}
          onEscapeKeyDown={event => {
            event.preventDefault();
          }}
          onPointerDownOutside={event => {
            if (event.target === openButtonRef.current) {
              event.preventDefault();
            }
          }}
        >
          <Box
            css={{
              border: '2px dashed $borderNeutralSubtle',
              padding: '$spacingM'
            }}
          >
            You can only dismiss me by clicking outside.
          </Box>
        </DismissableLayer>
      ) : null}
    </Flex>
  );
};
```

### Nested

Given a group of nested layers, each **DismissableLayer** should dismiss just itself. This comes useful in scenarios such as opening a [Popover](/components/popover) inside a [Dialog](/components/dialog).

```jsx
() => {
  function DismissableBox({ idx = 0, ...props }) {
    const [isOpen, setIsOpen] = React.useState(false);
    const openButtonRef = React.useRef(null);

    return (
      <DismissableLayer
        {...props}
        css={{
          padding: '$spacingXl',
          backgroundColor: 'rgba(0,0,0,.035)',
          borderRadius: '$m',
          width: '100%'
        }}
      >
        <Flex flow="column" cross="start">
          <Button
            ref={openButtonRef}
            onClick={() => setIsOpen(isOpen => !isOpen)}
          >
            {isOpen ? 'Close' : 'Open'} layer {idx + 1}
          </Button>
          {isOpen ? (
            <DismissableBox
              idx={idx + 1}
              onPointerDownOutside={event => {
                if (event.target === openButtonRef.current) {
                  event.preventDefault();
                }
              }}
              onDismiss={() => setIsOpen(false)}
            />
          ) : null}
        </Flex>
      </DismissableLayer>
    );
  }

  return <DismissableBox />;
};
```

---

## API Reference

| Name                   | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                  | Required |
| ---------------------- | --------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`                   | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css`                  | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                 |          |
| `onDismiss`            | `() => void`                                              |         | Event handler called when the layer dismisses.                                                                                                                                                                                                                                               |          |
| `onPointerDownOutside` | `(event: Event) => void`                                  |         | Event handler called when a pointer event occurs outside the layer. It can be prevented with `event.preventDefault`.                                                                                                                                                                         |          |
| `onEscapeKeyDown`      | `(event: KeyboardEvent) => void`                          |         | Event handler called when the escape key is down. It can be prevented with `event.preventDefault`.                                                                                                                                                                                           |          |
