├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── dist └── react-singleton.js ├── example ├── .babelrc ├── components │ └── Hello.js ├── index.html ├── index.js ├── package.json └── webpack.config.js ├── package.json └── src └── react-singleton.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react", "stage-1"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .tmp 4 | .npmignore 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | node_modules 3 | .DS_Store 4 | .tmp 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-singleton 2 | 3 | ## Demo 4 | You can find example in folder [example](https://github.com/Caesor/react-singleton/tree/master/example) 5 | 6 | ## Usage with React 7 | 8 | ### 1、Install the package 9 | `npm install react-singleton --save` 10 | 11 | ### 2、Import component 12 | ``` 13 | // ES6 14 | import Singleton from 'react-singleton' 15 | // ES5 16 | var Singleton = require('react-singleton').default 17 | ``` 18 | 19 | ###3、Decorate the target component 20 | ``` 21 | class Alert extends Component {...} 22 | 23 | export default new Singleton(Alert) 24 | ``` 25 | 26 | ###4、Using as your need 27 | ``` 28 | // Example 1: 29 | 30 | import Alert from 'component/Alert' 31 | 32 | Alert.show(); 33 | // you can pass the props with a object in show method 34 | Alert.show({ 35 | title: xxx, 36 | content: xxx 37 | }) 38 | // destroy the DOM node 39 | Alert.hide(); 40 | 41 | // Example 2: 42 | 43 | import Tips from 'components/Tips' 44 | 45 | // Tips will disappear in 2 second on default. 46 | Tips.popup(); 47 | // You can change the timer as you need 48 | Tips.popup({ 49 | text: xxx 50 | }, 3000); 51 | ``` 52 | -------------------------------------------------------------------------------- /dist/react-singleton.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _reactDom = require('react-dom'); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 16 | 17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18 | 19 | var Singleton = function () { 20 | function Singleton(component) { 21 | _classCallCheck(this, Singleton); 22 | 23 | this.dom = null; 24 | this.component = component; 25 | this.instance = null; 26 | } 27 | 28 | _createClass(Singleton, [{ 29 | key: 'show', 30 | value: function show(option) { 31 | if (!this.dom) { 32 | this.dom = document.createElement('div'); 33 | document.body.appendChild(this.dom); 34 | } 35 | this.instance = (0, _reactDom.render)(_react2.default.createElement(this.component, option), this.dom); 36 | this.instance.setState({ 37 | show: true 38 | }); 39 | } 40 | }, { 41 | key: 'hide', 42 | value: function hide() { 43 | var _this = this; 44 | 45 | if (this.instance) { 46 | this.instance.setState({ 47 | show: false 48 | }, function () { 49 | setTimeout(function () { 50 | (0, _reactDom.unmountComponentAtNode)(_this.dom); 51 | }, 100); 52 | }); 53 | } 54 | } 55 | }]); 56 | 57 | return Singleton; 58 | }(); 59 | 60 | exports.default = Singleton; -------------------------------------------------------------------------------- /example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react", "stage-1"] 3 | } 4 | -------------------------------------------------------------------------------- /example/components/Hello.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Singleton from 'react-singleton' 3 | 4 | class Hello extends Component { 5 | state = { 6 | show: true 7 | } 8 | render() { 9 | return ( 10 |
11 |

This is a hello tips

12 |
13 | ) 14 | } 15 | } 16 | 17 | export default new Singleton(Hello) 18 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | examaple 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { render } from 'react-dom' 3 | import Hello from './components/Hello' 4 | 5 | class Main extends Component { 6 | render() { 7 | return ( 8 |
9 | 10 | 11 |
12 | ) 13 | } 14 | } 15 | render( 16 |
, 17 | document.getElementById('app') 18 | ) 19 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --history-api-fallback --no-info --open" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-core": "^6.21.0", 13 | "babel-loader": "^6.2.10", 14 | "babel-preset-es2015": "^6.18.0", 15 | "babel-preset-react": "^6.16.0", 16 | "babel-preset-stage-1": "^6.16.0", 17 | "webpack": "^1.14.0", 18 | "webpack-dev-server": "^1.16.2" 19 | }, 20 | "dependencies": { 21 | "react": "^15.4.1", 22 | "react-dom": "^15.4.1", 23 | "react-singleton": "^1.3.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /example/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './index.js', 5 | output: { 6 | path: path.join(__dirname, 'dist'), 7 | filename: 'bundle.js' 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.(js|jsx)$/, 12 | loaders: ['babel'], 13 | exclude: /node_modules/, 14 | include: [__dirname] 15 | }] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-singleton", 3 | "version": "1.3.2", 4 | "description": "Rending a singleton react component in DOM", 5 | "main": "dist/react-singleton.js", 6 | "scripts": { 7 | "build": "babel src --out-dir dist", 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "prepublish": "npm run build" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/Caesor/react-singleton.git" 14 | }, 15 | "keywords": [ 16 | "react", 17 | "singleton" 18 | ], 19 | "author": "liaozksysu@gmail.com", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/Caesor/react-singleton/issues" 23 | }, 24 | "homepage": "https://github.com/Caesor/react-singleton#readme", 25 | "dependencies": { 26 | "react": "^15.4.1", 27 | "react-dom": "^15.4.1" 28 | }, 29 | "devDependencies": { 30 | "babel-core": "^6.21.0", 31 | "babel-loader": "^6.2.10", 32 | "babel-preset-es2015": "^6.18.0", 33 | "babel-preset-react": "^6.16.0", 34 | "babel-preset-stage-1": "^6.16.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/react-singleton.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, unmountComponentAtNode } from 'react-dom' 3 | 4 | export default class Singleton { 5 | constructor(component){ 6 | this.dom = null; 7 | this.component = component; 8 | this.instance = null; 9 | } 10 | 11 | show(option) { 12 | if(!this.dom) { 13 | this.dom = document.createElement('div'); 14 | document.body.appendChild(this.dom); 15 | } 16 | this.instance = render(, this.dom); 17 | this.instance.setState({ 18 | show: true 19 | }); 20 | } 21 | 22 | hide() { 23 | if (this.instance) { 24 | this.instance.setState({ 25 | show: false 26 | }, () => { 27 | setTimeout(() => { 28 | unmountComponentAtNode(this.dom); 29 | }, 100); 30 | }); 31 | } 32 | } 33 | } 34 | --------------------------------------------------------------------------------