import { ArgTypes, Meta, Story } from "@storybook/addon-docs/blocks";
import { Drawer } from ".";
import * as DrawerStories from "./Drawer.stories";
import TestingDocs from "../../../../../.storybook/pages/jestHTMLDialogPolyfillTestingDocs.mdx";

<Meta of={DrawerStories} />

# Drawer

The `Drawer` component is used for displaying data that overlays the content
beneath. It can be comprised of header and main content sections, both of which
are optional.

## Install

```bash
yarn add @simplybusiness/mobius
```

## Usage

```js
import { Drawer } from "@simplybusiness/mobius";
```

## Examples

### Basic Drawer

Drawer `open` state should be set in a parent container and passed in as a prop, along with an `onClose` function to set open state to false (or otherwise hide the Drawer). Set the `direction` prop to one of `left`, `top`, `right`, or `bottom`.

You will also need to set some trigger element or event to show the Drawer. Ordinarily that will be a button, but any user event will work.

```jsx
import { useState } from "react";
import { Drawer, DrawerProps } from "@simplybusiness/mobius";

const Demo = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Show Drawer</Button>
      <Drawer
        isOpen={open}
        onClose={() => setOpen(false)}
        direction="right"
        closeLabel="Close"
      >
        <Drawer.Header>Heading</Drawer.Header>
        <Drawer.Content>Some content in main panel.</Drawer.Content>
      </Drawer>
    </>
  );
};
```

<Story of={DrawerStories.Default} />

### Logo Header

Drawer `open` state should be set in a parent container and passed in as a prop, along with an `onClose` function to set open state to false (or otherwise hide the Drawer). Set the `direction` prop to one of `left`, `top`, `right`, or `bottom`.

You will also need to set some trigger element or event to show the Drawer. Ordinarily that will be a button, but any user event will work.

```jsx
import { useState } from "react";
import { Drawer, DrawerProps } from "@simplybusiness/mobius";

const LogoHeader = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Show Drawer</Button>

      <Drawer
        isOpen={open}
        onClose={() => setOpen(false)}
        direction="right"
        closeLabel="Close"
      >
        <Drawer.Header>
          <img
            src="https://quote.simplybusiness.com/assets/logos/insurers/harborway_insurance.png"
            alt="Provider logo"
          />
        </Drawer.Header>
        <Drawer.Content>Some content in main panel.</Drawer.Content>
      </Drawer>
    </>
  );
};
```

<Story of={DrawerStories.WithLogoHeader} />

### Closing Drawer from a child component

As of `@simplybusiness/mobius` version 4.5.0 `Drawer` component can be closed from a child component using the `useDrawer()` hook.

The hook provides `onClose` method and `closeLabel` string that can be used to close the drawer.

`onClose` method will ensure that the drawer is closed using its CSS transition, as well as `onClose` prop firing, if provided.

If you previously used `onClose` and/or `closeLabel` props provided by default to all children props, you will need to replace these with `useDrawer()`.

Parent component for both old and new implementations remains the same:

```jsx
import { Drawer, Button } from "@simplybusiness/mobius";

const ParentComponent = () => {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Open</Button>

      <Drawer
        isOpen={open}
        onClose={() => setOpen(false)}
        direction="right"
        closeLabel="Close"
      >
        <Drawer.Header>Title</Drawer.Header>
        <Drawer.Content>Content</Drawer.Content>
      </Drawer>
    </>
  );
};
```

Old implementation for child component:

```jsx
import { Button } from "@simplybusiness/mobius";

const ChildComponent = ({ onClose, closeLabel }) => (
  <Button onClick={onClose}>{closeLabel}</Button>
);
```

New implementation for child component:

```jsx
import { useDrawer, Button } from "@simplybusiness/mobius";

const ChildComponent = () => {
  const { onClose, closeLabel } = useDrawer();

  return <Button onClick={onClose}>{closeLabel}</Button>;
};
```

The motivation behind this change is to provide a more consistent and predictable API for the `Drawer` component.

This particularly applies to components that already have props named `onClose` and `closeLabel`, which may lead to unexpected side effects.

<TestingDocs />

## Props

<ArgTypes of={Drawer} />

## Component HTML Structure and Class names

The following HTML is rendered for a simple Drawer:

```html
<dialog class="mobius-drawer --right open">
  <header class="mobius-drawer__header">
    <button aria-label="Close" class="mobius-drawer__close">
      <svg class="mobius-icon svg-inline--mobius-icon" ...>{cross}</svg>
    </button>
  </header>
  <div class="mobius-drawer__content">Sample content</div>
</dialog>
```

Class names are augmented with the following flags if true (affected classes shown above):

- \--left
- \--right
- \--top
- \--bottom
