# Dialogs

Learn more about how UI extensions can render pages inside of a native Hygraph dialog, or modal, via the openDialog method.

UI extensions can render pages inside of a native Hygraph dialog, or modal, via the `openDialog` method.

Values can be sent to the dialog when opening it, and the dialog can return values to the main extension when closing using the `onCloseDialog` method.

## Example

  **Native JS**

```html
<!-- index.html -->

<script>
  // const declaration = ...
  init({
    declaration,
  }).then(({ status, props }) => {
    if (status === 'ok') {
      const { value, onChange, openDialog } = props;

      const onButtonClick = openDialog('./dialog.html', { value }).then(
        (response) => {
          if (response) onChange(response);
        }
      );
      document
        .getElementById('button')
        .addEventListener('click', onButtonClick);
    }
  });
</script>

<button id="button">Open Dialog</button>

<!-- dialog.html -->

<script>
  const input = document.getElementById('input');
  const cancel = document.getElementById('cancel');
  const ok = document.getElementById('ok');

  init({ declaration }).then(({ status, props }) => {
    if (status === 'ok') {
      const { onCloseDialog, value } = props;
      input.value = value;
      cancel.addEventListener('click', () => onCloseDialog());
      ok.addEventListener('click', () => onCloseDialog(input.value));
    }
  });
</script>
<p>
  <input id="input" />
</p>
<p>
  <button id="cancel">Cancel</button>
  <button id="ok">Ok</button>
</p>
```

  
  **React**

```js
import {
  Wrapper,
  useUiExtensionDialog,
  useFieldExtension,
} from '@graphcms/uix-react-sdk';

import { BrowserRouter, Route, Switch } from 'react-router-dom';

// const declaration = ....

const Button = () => {
  const { value, onChange, openDialog } = useFieldExtension();

  const handleOpenDialog = () => {
    openDialog('./dialog', { value }).then((response) => {
      if (response) {
        onChange(response);
      }
    });
  };
  return <button onClick={handleOpenDialog}>Open dialog</button>;
};

const Dialog = () => {
  const { onCloseDialog, value } = useUiExtensionDialog();
  const [state, setState] = React.useState(value);

  return (
    <>
      <p>
        <input value={state} onChange={(e) => setState(e.target.value)} />
      </p>
      <p>
        <button onClick={() => onCloseDialog()}>Cancel</button>
        <button onClick={() => onCloseDialog(state)}>Ok</button>
      </p>
    </>
  );
};

const Extension = () => (
  <Wrapper declaration={declaration}>
    <BrowserRouter>
      <Switch>
        <Route path="/dialog" exact>
          <Dialog />
        </Route>
        <Route path="/" exact>
          <Button />
        </Route>
      </Switch>
    </BrowserRouter>
  </Wrapper>
);
```


## Options

In addition to the values you may want to send to the dialog, the second parameter of `openDialog(url, options)` can take the following options:

| name                  | type                        | description                                           |
| --------------------- | --------------------------- | ----------------------------------------------------- |
| `disableOverlayClick` | `boolean` (default `false`) | disable closing the modal when clicking outside of it |
| `maxWidth`            | `string`                    | set a custom width to the modal                       |
| `ariaLabel`           | `string`                    | modal title for assisitive devices or voice-over      |

## Typescript

By default dialog options and return types are of type `any`, but you can narrow down dialog types:

```ts
// declare your dialog options and return types
type DialogProps = { question: string };
type DialogReturn = string;

function Button() {
  const { openDialog } = useUiExtension();

  const handleOpenDialog = () =>
    openDialog<DialogReturn, DialogProps>(
      'dialog',
      { question: 'what ?' } // vlidated by typescript
    ).then((answer) => {
      // `answer` is of type `string` instead of `any`
    });
  return <button onClick={handleOpenDialog}>Open question</button>;
}

function Dialog() {
  const { onCloseDialog, question } = useUiExtensionDialog<
    DialogReturn,
    DialogProps
  >();
  const [answer, setAnswer] = React.useState<DialogReturn>('');
  const onCancel = () => onCloseDialog(null);
  const onSubmit = () => onCloseDialog(answer);
  return (
    <div>
      <h2>{question}</h2>
      <input onChange={(e) => setAnswer(e.target.value)} value={answer} />
      <button onClick={onCancel}>Cancel</button>
      <button onClick={onSubmit}>Submit</button>
    </div>
  );
}
```
