Awesome
Mithril Modal Examples
There are lots of ways to implement modal-style popups in a Mithril.js app. These are a few example techniques.
Imperative Style
Probably the most straightforward to implement and often the easiest to use. This takes the approach of conditionally rendering a single Modal component at the top level of the DOM, at the very end of the top level nodes. This placement in the DOM ensures it will render over everything else.
Visibility of the modal is controlled by a simple isOpen
flag, which is changed by calling the openModal
and closeModal
functions. The openModal
function also accepts some paramters for content that should be rendered in the Modal.
See the imperative
directory in this repo for sources.
Caveats
While you can open a modal from anywhere in your app, this approach requires that you render the Modal component itself in a root-level component. This implementation can only render one modal at a time (though it could be developed further to handle a stack of modals.)
Declarative (Portal) Style
This technique uses a portal-like technique to append a DOM node to the end of the document body and temporarily mounts a separate vnode tree there. When the modal is removed, that DOM node and vnode tree are cleaned up.
This allows you to declaratively render a modal component nested anywhere within your vdom.
See the declarative
directory in this repo for sources.
Caveats
The "portal" approach may have trouble if you're rendering the body tag itself with Mithril, and if the top-level dom nodes within the body are changing while the modal exists. Otherwise, it should safely co-exist with the rest of your Mithril DOM/VDOM.
Declarative composed from re-usable parts
We might want to create a less opinionated, more re-usable declarative Overlay
component that relies on this portal-like behaviour. Then render a Modal
component (or anything else) within that. Here is a Flems demo that uses this technique.
See the declarative-composed
directory in this repo for sources.
Note that the examples use ES6 and modern CSS. Sources would need to be compiled to ES5 and include style prefixes for older browsers.