@berish/portal
v1.0.0
Published
Library for creating global DOM elements and working with them as with React components
Downloads
4
Maintainers
Readme
@berish/portal
Library for creating global DOM elements and working with them as with React components
Installation
$ npm install @berish/portal --save
or
$ yarn add @berish/portal
Supports typescript
Get started
First you need to decide where the root of the portals will be located.
import { Root } from '@berish/portal';
class App extends React.Component {
render() {
return (
...
<Root />
...
);
}
}
After that, you can render any element using the portals.
import { Portal } from '@berish/portal';
class TestDiv extends React.Component {
render() {
return <div>Hey bro</div>
}
}
...
someAction() {
Portal.create(TestDiv)();
}
...
With some response from portallable element
import { Portal } from '@berish/portal';
class TestForm extends React.Component {
resolve = () => {
this.props.portal.resolve({name: 'Ravil'})
}
reject = () => {
// Close form with rejected reason
this.props.portal.reject('My some reason')
}
render() {
return (
<div>
<h1>Hey bro, click button</h1>
<button onClick={this.resolve}>Resolve</button>
<button onClick={this.reject}>Reject</button>
</div>
);
}
}
...
async someAction() {
try {
const result = await Portal.create(TestForm)();
console.log(result); // { name: 'Ravil' }
} catch (err) {
console.log(err); // My some reason
}
}
...
Example with modals (real case):
import { Portal } from '@berish/portal';
import { Modal } from 'any-ui-kit'; // example
class TestModal extends React.Component {
save = () => {
this.props.portal.resolve(this.state.someData)
}
cancel = () => {
this.props.portal.resolve();
}
render() {
return (
<Modal onClose={this.cancel} visible={true}>
<h1>Hey bro, click button</h1>
// {...}
<button onClick={this.save}>Save</button>
<button onClick={this.cancel}>Cancel</button>
</Modal>
);
}
}
...
async someAction() {
const result = await Portal.create(TestForm)();
console.log(result); // if clicked at Cancel button - null.
}
API
Root props:
interface IRootProps {
portalName?: string;
children?: React.ReactNode;
}
portalName
- It is scope of Portal (defaults default
). Not required.
children
- Any content that can be rendered on top of the portal (defaults undefined
). Not required.
Portal API:
Portal.scope(portalName?: string); // Select root by portalName
const destroy = Portal.add(element: JSX.Element); // You can show native JSX element. Returns destroy function;
Portal.update(); //Re-render all portal's elements
Portal.listen(cb: (jsxElements: JSX.Element[]) => void); // Listen for updates
const withPortal = Portal.create(component: React.ComponentClass | React.SFC); // HOC of portals
const promise = withPortal(props?: Props, elementId?: string); // Show element in Root, elementId - id for destroy this element manual;
withPortal.destroy(); // Destroy all elements, whos HOC'ed in withPortal
withPortal.destroy(elementId?: string); // Destroy only one element by ID;
promise.elementId; // Automatic generated or manual ID for destroy. You can do withPortal.destroy(promise.elementId);