Simple and powerful react popup component.
This package is available on npm as react-popup. Install it using npm install react-popup
. Currently only working in CommonJS environments.
Start by rendering the react component into an element on the page. You will need the react
and react-dom
packages. See configuration options at the end of this page.
Important: The component is meant to work as a global component. You should only mount it once, not everytime you want to use it, in other components. Preferably mount it as far up the DOM tree as possible to avoid positioning problems.
import React from 'react';
import ReactDom from 'react-dom';
import Popup from 'react-popup';
ReactDom.render(
<Popup />,
document.getElementById('popupContainer')
);
Right now we do not support css in js. We use simple classes that you need to use in order for the popup to display correctly. See demo CSS for an example.
Displaying an alert box couldn't be easier. Just call the alert
method on the popup with the text as the first argument and an optional title as the second one.
Popup.alert('I am alert, nice to meet you');
Pro tip: If you dispatch multiple popups they will be queued and displayed one at the time as the popups closes.
The prompt helper has been removed in v0.7.0. To help you out a bit, here's an example of how you can do it yourself, the recommended way. More about plugins further down.
/** The prompt content component */
class Prompt extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.defaultValue
};
this.onChange = (e) => this._onChange(e);
}
componentDidUpdate(prevProps, prevState) {
if (prevState.value !== this.state.value) {
this.props.onChange(this.state.value);
}
}
_onChange(e) {
let value = e.target.value;
this.setState({value: value});
}
render() {
return <input type="text" placeholder={this.props.placeholder} className="mm-popup__input" value={this.state.value} onChange={this.onChange} />;
}
}
/** Prompt plugin */
Popup.registerPlugin('prompt', function (defaultValue, placeholder, callback) {
let promptValue = null;
let promptChange = function (value) {
promptValue = value;
};
this.create({
title: 'What\'s your name?',
content: <Prompt onChange={promptChange} placeholder={placeholder} value={defaultValue} />,
buttons: {
left: ['cancel'],
right: [{
text: 'Save',
key: '⌘+s',
className: 'success',
action: function () {
callback(promptValue);
Popup.close();
}
}]
}
});
});
/** Call the plugin */
Popup.plugins().prompt('', 'Type your name', function (value) {
Popup.alert('You typed: ' + value);
});
You can customize the buttons with classes, text and on click actions. The value for "key" is sent directly to keymaster, check their documentation to see what you can use.
Popup.create({
title: null,
content: 'This popup uses the create method directly to get more control. This popup demonstrates custom buttons.',
buttons: {
left: [{
text: 'Cancel',
className: 'danger',
action: function () {
Popup.alert('You pressed the Cancel btn');
/** Close this popup. Close will always close the current visible one, if one is visible */
Popup.close();
}
}],
right: [{
text: 'Alt',
key: 'ctrl+enter',
action: function () {
// Passing true as the second argument to the create method
// displays it directly, without interupting the queue.
Popup.create({
title: null,
content: 'I was configured to display right away, without affecting the queue. Closing this will display the previously visible popup.',
buttons: {
left: ['cancel'],
right: []
}
}, true);
}
}, {
text: 'Save',
className: 'success',
action: function () {
Popup.alert('You pressed the Save btn');
/** Close this popup. Close will always close the current visible one, if one is visible */
Popup.close();
}
}]
}
});
It is possible to store popups in variables and reuse them. Instead of using one of the helper methods (alert and prompt) you use the register
method. You can also set a third parameter on alert
and prompt
to true
.
let mySpecialPopup = Popup.register({
title: 'I am special',
content: 'Since I am special you might need me again later. Save me!',
buttons: {
left: ['cancel'],
right: ['ok']
}
});
Popup.queue(mySpecialPopup);
In addition to locally reusable popups you can also store your custom popups globally. Let's say you want a popover that you know you will be using on several places in your application. Instead of duplicated code, you can register it once.
Popup.registerPlugin('popover', function (content, target) {
this.create({
content: content,
className: 'popover',
noOverlay: true,
position: function (box) {
let bodyRect = document.body.getBoundingClientRect();
let btnRect = target.getBoundingClientRect();
let btnOffsetTop = btnRect.top - bodyRect.top;
let btnOffsetLeft = btnRect.left - bodyRect.left;
let scroll = document.documentElement.scrollTop || document.body.scrollTop;
box.style.top = (btnOffsetTop - box.offsetHeight - 10) - scroll + 'px';
box.style.left = (btnOffsetLeft + (target.offsetWidth / 2) - (box.offsetWidth / 2)) + 'px';
box.style.margin = 0;
box.style.opacity = 1;
}
});
});
Popup.plugins().popover('This popup will be displayed right above this button.', element);
Note that in this example I'm using custom positioning. All popups can have a position property. It can be an object with x and y or a function. If you use a function you get complete control over the box. The box is invisible (opacity=0) by default so you need to make it visible in your function as in the example above.
If you want to display the popup immediately, and go back to the previous one after the new one is closed, pass `true` as the second argument to the `create` method:
Popup.create({
title: 'Immediate popup',
content: 'This popup will be displayed straight away',
className: 'alert',
buttons: {
right: ['ok']
}
}, true);
There are multiple options you can set when you attach the popup component to the DOM. See below for a complete list.
<Popup
className="mm-popup"
btnClass="mm-popup__btn"
closeBtn={true}
closeHtml={null}
defaultOk="Ok"
defaultCancel="Cancel"
wildClasses={false}
escToClose={true} />
Sometimes you might want to wipe the popup queue completely, making sure no more popups will be displayed after you close the current one. To do this, just call Popup.clearQueue(). Remember that this will only clear the queue, you have to close the currently visible popup yourself (Popup.close()).