Closed maxime4000 closed 3 years ago
I don't understand the problem here. Can you clarify why something like the following snippet will not work for you?
const [isModalOpen, setIsModalOpen] = React.useState(false);
toaster.informational("Toast message", { link: { title: "Details", onClick: () => setIsModalOpen(true) } });
From where I instantiate the toast, I'm in a service and not in any React component. I don't have a parent. It's simply a function that call the function of toaster that create a toast in ToastMaster. In fact, scratch option 2, it would probably don't work for me as I'm not in a hook.
Can you try calling ReactDOM.render(<Modal ..../>)
from the onClick callback?
I can make the modal appear, but I still need someone to control the isOpen and onClose props. So I can render a wrapper component to do that, but I'm still instantiating a component that will stay active in the site and I cannot unmount it. It's better than nothing, but not quite a good solution. I can still wait for a better solution before doing the work.
The simpliest solution would be that link can be a ReactNode element so when the Toast disappear, the modal is unmount. I could also layout my toast to have my own link in the content, but I prefer if the solution I come with is more official/supported and not an hack to make it work.
Supporting ReactNode in link
may make it simple on your end, but it sends the "mess" on our side and complicates the API (as it needs to support title
/onClick
as well as custom ReactNode).
I can render a wrapper component to do that, but I'm still instantiating a component that will stay active in the site and I cannot unmount it.
This is not different from how our toaster currently works. See this line: https://github.com/iTwin/iTwinUI-react/blob/dfa94c8f4ee22be1cb8a7dc478be55040c51ed6e/src/core/Toast/Toaster.tsx#L73
The toast wrapper div and container stays in the DOM even when all toasts are cleared.
If you want, you can even try rendering your modal in the same container by passing 'iui-toasts-container'
into getContainer
.
Closing this since it's fairly trivial to render modal from toast.
See working example: https://codesandbox.io/s/itwinui-react-minimal-example-forked-eyi59?file=/src/CustomToaster.tsx
Feature
Toast are good to display small text of information. The link props is mostly use to view the full details of the toast. Where would you display that information in your application ? My first choice is a modal. But how can you generate a modal dynamically from a onClick event ? For toast, the Toaster class can generate Toast with his function, but there is no such option with Modal. So there is a few way to make this happen. I would go with option 3.
useModal() : { addModal({}: ModalProps) }
Examples
const CustomModalButton = ({info}) => { const [ isOpen, toggleOpen] = useToggle(false); return <> <Button onClick={() => toggleOpen()}>View more {isOpen && ( <Modal isOpen={isOpen} title={t("keyMoreInfo")} onClose={onClose} isDismissible={true} closeOnEsc={false} closeOnExternalClick={false}> {info} )} </> }