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 (модальное окно)

Наследует [React Native Modal](https://reactnative.dev/docs/modal).

Модальное окно может быть использована, когда пользователю необходимо сообщить о критической информации, требовать принятия решений или взаимодействовать со сложным под приложением без перехода на новую страницу или прерывания рабочего процесса.

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

## Простой пример

```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>
  </>
)
```

## Управление видимостью

Для управления видимостью модального окна есть три варианта:

1. Передав скоуп модель в свойство `$visible` из состояния которой идет управление видимостью.

```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. Передав свойство `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. Передав `ref`, который получит методы `open()` и `close()` для управления видимостью.

```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` в свойство `variant`.

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

return (
  <React.Fragment>
    <Button onPress={() => $visible.set(true)}>
      Открыть полноэкранную модалку
    </Button>
    <Modal
      variant='fullscreen'
      title='Полноэкранный пример'
      $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>
)
```

## Продвинутое использование

Модальное окно состоит из трех частей - `Header`, `Content` и `Actions`. Эти части можно использовать для добавления пользовательской разметки, `Header` используется вместо `title`, `Content` используется вместо `children` и `Actions` используется вместо обработчиков `onCancel`, `onConfirm`. Их можно использовать по отдельности.

```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>
)
```

## Свойства

```jsx pure-example noscroll
return (
  <Table styleName='table'>
    <Thead>
      <Tr>
        <Th>Имя</Th>
        <Th>Тип</Th>
        <Th>Описание</Th>
      </Tr>
    </Thead>
    <Tbody>
      <Tr>
        <Td>showCross</Td>
        <Td>bool</Td>
        <Td>
          <Span>
            Показать крестик в заголовке.
            <Span bold> Значение по умолчанию: </Span>
            `true`.
          </Span>
        </Td>
      </Tr>
      <Tr>
        <Td>enableBackdropPress</Td>
        <Td>bool</Td>
        <Td>
          <Span>
            Делает фон кликабельным.
            <Span bold> Значение по умолчанию: </Span>
            `true`.
          </Span>
        </Td>
      </Tr>
      <Tr>
        <Td>onBackdropPress</Td>
        <Td>function</Td>
        <Td>
          Функция обратного вызова, которая будет вызвана, когда
          пользователь нажмет на фон (требуется, чтобы
          параметр `enableBackdropPress` был установлен в значение `true`).
        </Td>
      </Tr>
      <Tr>
        <Td>onCrossPress</Td>
        <Td>function</Td>
        <Td>
          Функция обратного вызова, которая будет вызвана,
          когда пользователь нажмет на крестик.
        </Td>
      </Tr>
      <Tr>
        <Td>onDismiss</Td>
        <Td>function</Td>
        <Td>
          Функция обратного вызова, которая будет вызвана
          после закрытия модального окна.
        </Td>
      </Tr>
      <Tr>
        <Td>onOrientationChange</Td>
        <Td>function</Td>
        <Td>
          Функция обратного вызова, которая будет вызвана при изменении
          ориентации во время отображения компонента.
        </Td>
      </Tr>
      <Tr>
        <Td>onCancel</Td>
        <Td>function</Td>
        <Td>
          Показать только одну кнопку `OK`, которая использует этот обработчик.
        </Td>
      </Tr>
      <Tr>
        <Td>onConfirm</Td>
        <Td>function</Td>
        <Td>
          Показать две кнопки: `ОК` которая используется этот
          обработчик и `Cancel` которая используется обработчик `onCancel`.
        </Td>
      </Tr>
      <Tr>
        <Td>onRequestClose</Td>
        <Td>function</Td>
        <Td>
          Функция обратного вызова, которая будет вызвана,
          когда пользователь запрашивает закрытие модального окна, например,
          нажимает кнопку аппаратного возврата на Android,
          кнопку меню на Apple TV или `Esc` в браузере.
          Она также будет вызвана в конце обработчиков: `onCrossPress`,
          `onBackdropPress`, `onCancel` и `onConfirm`. Если вы хотите
          изменить это поведение по умолчанию для обработчиков,
          передайте функцию для соответствующего обработчика,
          в которой вызовите `event.preventDefault()` в начале функции.
        </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}
/>
