import { useState, useRef } from 'react'
import { $root, useValue } from 'startupjs'
import { Sandbox } from '@startupjs/docs'
import Button from '../Button'
import Span from '../typography/Span'
import Modal from './'
import Table from '../table/Table'
import Thead from '../table/Thead'
import Tbody from '../table/Tbody'
import Tr from '../table/Tr'
import Th from '../table/Th'
import Td from '../table/Td'
import './index.mdx.styl'

# Modal

Inherits [React Native Modal](https://reactnative.dev/docs/modal).

Modal can be used when the user needs to inform about critical information, require decisions or interact a complex sub-application without navigating to a new page or interrupting the workflow.

```jsx
import { Modal } from '@startupjs/ui'
```

## Simple example

```jsx example
const [visible, setVisible] = useState(false)

return (
  <>
    <Modal
      visible={visible}
      title='Text in modal'
      onRequestClose={setVisible}
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
    </Modal>
    <Button onPress={() => setVisible(true)}>
      Open modal
    </Button>
  </>
)
```

## Managing visibility

There are three options for managing visiblity of a modal:

1. By passing the scoped model to the `$visible` property from the state of which visibility is controlled.

```jsx example
const [, $visible] = useValue()

return (
  <React.Fragment>
    <Button onPress={() => $visible.set(true)}>
      Open
    </Button>
    <Modal
      title='Example'
      $visible={$visible}
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
    </Modal>
  </React.Fragment>
)
```

2. By passing the `visible` property that determines whether modal is visible.

```jsx example
const [visible, setVisible] = useState(false)

return (
  <React.Fragment>
    <Button onPress={() => setVisible(true)}>
      Open
    </Button>
    <Modal
      title='Example'
      visible={visible}
      onRequestClose={() => setVisible(false)}
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
    </Modal>
  </React.Fragment>
)
```

3. By passing `ref`, which will receive the `open()` and `close()` methods to control visibility.

```jsx example
const modalRef = useRef()

return (
  <React.Fragment>
    <Button onPress={() => modalRef.current.open()}>
      Open
    </Button>
    <Modal
      title='Example'
      ref={modalRef}
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
    </Modal>
  </React.Fragment>
)
```

## Fullscreen modal

By default the modal shows like window in center of the page. To make it fullscreen, you need pass the string `fullscreen` to the `variant` property.

```jsx example
const [visible, $visible] = useValue(false)

return (
  <React.Fragment>
    <Button onPress={() => $visible.set(true)}>
      Open fullscreen modal
    </Button>
    <Modal
      variant='fullscreen'
      title='Fullscreen example'
      $visible={$visible}
      onCancel={() => console.log('onCancel')}
      onConfirm={() => console.log('onConfirm')}
    >
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
    </Modal>
  </React.Fragment>
)
```

## Advanced usage

Modal consists of three parts - `Header`, `Content` and `Actions`. These parts can be used to add custom markup, the `Header` is used instead of `title`, the `Content` is used instead of children and the `Actions` is used instead of handlers `onCancel`, `onConfirm`. They can be used separately.

```jsx example
const [visible, $visible] = useValue(false)

return (
  <React.Fragment>
    <Button onPress={() => $visible.set(true)}>
      Open advanced modal
    </Button>
    <Modal $visible={$visible}>
      <Modal.Header>Advanced modal</Modal.Header>
      <Modal.Content>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit.
      </Modal.Content>
      <Modal.Actions>
        <Button
          shape='circle'
          onPress={() => $visible.set(false)}
        >
          Custom close
        </Button>
        <Button
          pushed
          shape='circle'
          onPress={() => $visible.set(false)}
        >
          Custom confirm
        </Button>
      </Modal.Actions>
    </Modal>
  </React.Fragment>
)
```

## Props

```jsx pure-example noscroll
return (
  <Table styleName='table'>
    <Thead>
      <Tr>
        <Th>Name</Th>
        <Th>Type</Th>
        <Th>Description</Th>
      </Tr>
    </Thead>
    <Tbody>
      <Tr>
        <Td>showCross</Td>
        <Td>bool</Td>
        <Td>
          <Span>
            Show a cross in the header.
            <Span bold> Default: </Span>
            `true`.
          </Span>
        </Td>
      </Tr>
      <Tr>
        <Td>enableBackdropPress</Td>
        <Td>bool</Td>
        <Td>
          <Span>
            Makes the backdrop clickable.
            <Span bold> Default: </Span>
            `true`.
          </Span>
        </Td>
      </Tr>
      <Tr>
        <Td>onBackdropPress</Td>
        <Td>function</Td>
        <Td>
          A callback function that will be called when the user clicks on the
          backdrop (requires `enableBackdropPress` to be set to `true`).
        </Td>
      </Tr>
      <Tr>
        <Td>onCrossPress</Td>
        <Td>function</Td>
        <Td>
          A callback function that will be called when user clicks on the cross.
        </Td>
      </Tr>
      <Tr>
        <Td>onDismiss</Td>
        <Td>function</Td>
        <Td>
          A callback function that will be called once the modal has been dismissed.
        </Td>
      </Tr>
      <Tr>
        <Td>onOrientationChange</Td>
        <Td>function</Td>
        <Td>
          A callback function that will be called when the orientation changes
          while the component is being displayed.
        </Td>
      </Tr>
      <Tr>
        <Td>onCancel</Td>
        <Td>function</Td>
        <Td>
          Show only the one `OK` button that uses this handler.
        </Td>
      </Tr>
      <Tr>
        <Td>onConfirm</Td>
        <Td>function</Td>
        <Td>
          Show two buttons: `OK` which uses this handler and `Cancel` which uses the `onCancel` handler.
        </Td>
      </Tr>
      <Tr>
        <Td>onRequestClose</Td>
        <Td>function</Td>
        <Td>
          A callback function that will be called when user requests to close
          the modal, for example, taps the hardware back button
          on Android, the menu button on Apple TV or `Esc` on browser.
          It will also be called at the end of handlers: `onCrossPress`,
          `onBackdropPress`, `onCancel` and `onConfirm`. If you want to
          change this default behavior for handlers, pass a function for the
          corresponding handler in which call the `event.preventDefault()`
          at the beginning of the function.
        </Td>
      </Tr>
    </Tbody>
  </Table>
)
```

## Sandbox

### Modal

<Sandbox
  Component={Modal}
  props={{ $visible: $root.scope('_session.Props.Modal.visible') }}
  $props={$root.scope('_session.Props.Modal')}
  {...{ _comment: "HACK to make alive sandbox when user click on 'visible' checkbox" }}
/>

### Modal.Header

<Sandbox
  Component={Modal.Header}
/>

### Modal.Content

<Sandbox
  Component={Modal.Content}
/>

### Modal.Actions

<Sandbox
  Component={Modal.Actions}
/>
