Dialogs
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.
<script>
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>
<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>
import {
Wrapper,
useUiExtensionDialog,
useFieldExtension,
} from '@graphcms/uix-react-sdk';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
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>
);
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 |
By default dialog options and return types are of type any
, but you can narrow down dialog types:
type DialogProps = { question: string };
type DialogReturn = string;
function Button() {
const { openDialog } = useUiExtension();
const handleOpenDialog = () =>
openDialog<DialogReturn, DialogProps>(
'dialog',
{ question: 'what ?' },
).then((answer) => {
});
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>
);
}