Wormhole/Portal
Both Ember.js and React allow rendering content outside the normal component tree hierarchy. This "portal" pattern is used for modals, tooltips, and dropdowns that need to get out of their container's styling constraints. The pattern is useful for avoiding overflow issues with modals and their parent dom nodes.
In Ember, use the built-in {{in-element}}
helper (v3.20+) or the ember-wormhole
addon for older versions (doc). React provides createPortal()
as a core API (doc).
Ember
Modern approach (v3.20+) - Built-in {{in-element}}
helper:
{{#in-element this.destinationElement}}
<div>Hello cheatsheet!</div>
{{/in-element}}
// Component class
export default class MyComponent extends Component {
destinationElement = document.getElementById('modal-root'); // destination would be an id here of modal
}
Legacy approach - ember-wormhole
addon:
{{#ember-wormhole to="modal-root"}}
Hello cheatsheet!
{{/ember-wormhole}}
React
Basic usage - createPortal()
from react-dom:
import { createPortal } from 'react-dom';
function PortalHello() {
return createPortal(
<div>Hello cheatsheet!</div>,
document.getElementById('modal-root') // destination would be an id here
);
}
Modal example with conditional rendering:
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return createPortal(
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body // adds destination of the body of the whole document
);
}
Further notes
- Ember ember-elsewhere addon is an alternative to
{{in-element}}
andember-wormhole