├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── README.MD ├── example ├── index.html └── index.js ├── package.json ├── src ├── index.js └── msgbox.vue ├── webpack.base.js ├── webpack.config.js └── webpack.example.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | ecmaFeatures: 2 | modules: true 3 | 4 | rules: 5 | indent: [ 1, 2, SwitchCase: 1 ] 6 | quotes: [ 1, single ] 7 | linebreak-style: [ 1, unix ] 8 | semi: [ 1, always ] 9 | no-undef: [ 1 ] 10 | no-console: [ 0 ] 11 | no-unused-vars: [ 1 ] 12 | space-infix-ops: [ 1 ] 13 | no-multi-spaces: [ 1 ] 14 | no-fallthrough: [ 0 ] 15 | 16 | env: 17 | es6: true 18 | browser: true 19 | 20 | extends: 'eslint:recommended' 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | coverage 5 | .idea 6 | .jshintrc 7 | /lib/ 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | dist 4 | coverage 5 | .idea 6 | .jshintrc 7 | /examples/ 8 | webpack.config.js 9 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | vue-msgbox is a message box (like Sweet Alert) for vue.js. 4 | 5 | # Install 6 | 7 | Get source from npm. 8 | 9 | ```bash 10 | $ npm install vue-msgbox --save 11 | ``` 12 | 13 | Supported UMD library and individual CSS file. 14 | 15 | ```bash 16 | ./lib/ 17 | ├── vue-msgbox.js 18 | └── vue-msgbox.css 19 | ./src/ 20 | ├── index.js 21 | └── msgbox.vue 22 | ``` 23 | 24 | ```JavaScript 25 | // For ES6 module 26 | import MessageBox from 'vue-msgbox'; 27 | 28 | // For commonJS 29 | const MessageBox = require('vue-msgbox').default; 30 | 31 | // For global variable, import from script label, then 32 | const MessageBox = VueMsgbox.default; 33 | 34 | // Import from src code for debugging or self building 35 | import MessageBox from 'vue-msgbox/src'; 36 | ``` 37 | 38 | And import CSS file: 39 | ```javascript 40 | require('vue-msgbox/lib/vue-msgbox.css'); 41 | ``` 42 | 43 | # Usage 44 | 45 | ## Basic usage 46 | 47 | ```JavaScript 48 | MessageBox("Good job!", "You clicked the button!", "success");// title, message, type 49 | ``` 50 | 51 | Or pass an object as options, and second parameter as callback: 52 | 53 | ```JavaScript 54 | MessageBox({ 55 | title: 'I\'m a title', 56 | message: 'I\'m a message', 57 | type: 'success', 58 | showCancelButton: true 59 | }, function(action) { 60 | console.log('callback:', action); 61 | MessageBox('Clicked: ' + action); 62 | }); 63 | ``` 64 | 65 | ## Promise based usage 66 | 67 | ### Basic usage 68 | 69 | ```JavaScript 70 | MessageBox({ 71 | title: 'I\'m a title', 72 | message: 'I\'m a message', 73 | type: 'success', 74 | showCancelButton: true 75 | }).then(function(action) { 76 | console.log('callback:', action); 77 | MessageBox('Clicked: ' + action); 78 | }); 79 | ``` 80 | 81 | ### alert 82 | 83 | ```JavaScript 84 | MessageBox.alert(message, title, options); 85 | ``` 86 | 87 | ```JavaScript 88 | MessageBox.alert('message').then(function(action) { 89 | ... 90 | }); 91 | ``` 92 | 93 | ### confirm 94 | 95 | If user press cancel button, then this promise will be rejected. 96 | 97 | ```JavaScript 98 | MessageBox.confirm(message, title, options); 99 | ``` 100 | 101 | ```JavaScript 102 | MessageBox.confirm('message').then(function(action) { 103 | ... 104 | }); 105 | ``` 106 | 107 | ### prompt 108 | 109 | If user press cancel button, then this promise will be rejected. 110 | 111 | ```JavaScript 112 | MessageBox.prompt(message, title, options); 113 | ``` 114 | 115 | ```JavaScript 116 | MessageBox.prompt('message').then(function(value, action) { 117 | ... 118 | }); 119 | ``` 120 | 121 | # Options 122 | 123 | | Option | Description | 124 | | ----- | ----- | 125 | | title | The title of MessageBox. | 126 | | message | The content of MessageBox. | 127 | | type | The status type of MessageBox: success, warning, error | 128 | | showConfirmButton | Boolean(default true) visible of confirm button. | 129 | | showCancelButton | Boolean(default false) visible of cancel button. | 130 | | confirmButtonText | The text of confirm button. | 131 | | confirmButtonPosition | (Default:right) The position of confirm button, default is right. | 132 | | confirmButtonHighlight | (Default:false) Highlight confirm button if confirmButtonHighlight is true. | 133 | | cancelButtonText | The text of cancel button. | 134 | | cancelButtonHighlight | (Default:false) Highlight cancel button if cancelButtonHighlight is true. | 135 | | confirmButtonClass | Extra className of confirm button. | 136 | | cancelButtonClass | Extra className of cancel button. | 137 | | showInput | Boolean(default false) visible of input. | 138 | | inputValue | value of input. | 139 | | inputPlaceholder | placeholder of input. | 140 | | inputPattern | Regexp(default null). validation pattern of input. | 141 | | inputValidator | validate function of input, if validator return a string, MessageBox will use it as inputErrorMessage. | 142 | | inputErrorMessage | error message when inputPattern test inputValue failed. | 143 | 144 | # Develop 145 | 146 | Coding with watching and hot-reload. 147 | 148 | ```bash 149 | $ npm run dev 150 | ``` 151 | 152 | Develop on real remote device. 153 | 154 | ```bash 155 | $ npm run remote-dev {{ YOUR IP ADDRESS }} 156 | ``` 157 | 158 | # License 159 | MIT 160 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | vue-msgbox examples 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | // /* global VueMsgbox */ 2 | // const MessageBox = VueMsgbox.default; 3 | 4 | // For develop 5 | import MessageBox from '../src'; 6 | 7 | // title, message, type 8 | // MessageBox('Good job!', 'You openned the demo page!', 'success'); 9 | 10 | document.querySelector('[showbase]').addEventListener('click', () => { 11 | MessageBox({ 12 | title: 'I\'m a title', 13 | message: 'I\'m a message', 14 | type: 'success', 15 | showCancelButton: true 16 | }, function(action) { 17 | console.log('callback:', action); 18 | MessageBox.alert('Clicked: ' + action); 19 | }); 20 | }); 21 | 22 | document.querySelector('[showpromisebase]').addEventListener('click', () => { 23 | MessageBox({ 24 | title: 'I\'m a title', 25 | message: 'I\'m a message', 26 | type: 'success', 27 | showCancelButton: true 28 | }).then(function(action) { 29 | console.log('callback:', action); 30 | MessageBox.alert('Clicked: ' + action); 31 | }); 32 | }); 33 | 34 | document.querySelector('[showalert]').addEventListener('click', () => { 35 | MessageBox.alert('EXTERMINATE! EXTERMINATE!', 'Dalek say', {}); 36 | }); 37 | 38 | document.querySelector('[showconfirm]').addEventListener('click', () => { 39 | MessageBox.confirm('Hey! K9! Choose one.') 40 | .then(function() { 41 | MessageBox.alert('GOOD DOG!'); 42 | }) 43 | .catch(() => { 44 | MessageBox.alert('BAAAD DOG!!'); 45 | }); 46 | }); 47 | 48 | document.querySelector('[showprompt]').addEventListener('click', () => { 49 | MessageBox.prompt('Input your name: ', '', { 50 | inputPlaceholder: '2-12 words', 51 | inputValue: 'name', 52 | inputPattern: /^.{2,12}$/, 53 | inputErrorMessage: 'Wrong! Wrong! DELETE! DELETE!' 54 | }) 55 | .then(function(value, action) { 56 | console.log(value); 57 | console.log(action); 58 | return; 59 | }); 60 | }); 61 | 62 | document.querySelector('[showprompt2]').addEventListener('click', () => { 63 | MessageBox.prompt('Input your name: ', '', { 64 | inputPlaceholder: '2-12 words', 65 | inputValue: 'name', 66 | confirmButtonPosition: 'left', 67 | inputValidator(value) { 68 | if (value.length < 2 || value.length > 12) { 69 | return 'length should be 2-12' 70 | } 71 | } 72 | }) 73 | .then(function(value, action) { 74 | console.log(value); 75 | console.log(action); 76 | return; 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-msgbox", 3 | "version": "2.0.2", 4 | "description": "A message box (like Sweet Alert) for vue.js.", 5 | "main": "lib/vue-msgbox.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --config ./webpack.example.config.js --inline --hot", 8 | "remote-dev": "webpack-dev-server --config ./webpack.example.config.js --inline --hot --host", 9 | "build": "webpack -p", 10 | "prepublish": "webpack -p" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/ElemeFE/vue-msgbox.git" 15 | }, 16 | "keywords": [ 17 | "message box", 18 | "alert", 19 | "confirm", 20 | "vue" 21 | ], 22 | "author": "long.zhang@ele.me", 23 | "license": "MIT", 24 | "devDependencies": { 25 | "babel-cli": "^6.3.15", 26 | "babel-core": "^6.3.15", 27 | "babel-loader": "^6.2.0", 28 | "babel-plugin-transform-runtime": "^6.3.13", 29 | "babel-preset-es2015": "^6.3.13", 30 | "babel-preset-stage-2": "^6.5.0", 31 | "css-loader": "^0.23.1", 32 | "eslint": "^1.10.3", 33 | "eslint-loader": "^1.1.1", 34 | "extract-text-webpack-plugin": "^1.0.1", 35 | "file-loader": "^0.8.5", 36 | "style-loader": "^0.13.0", 37 | "url-loader": "^0.5.7", 38 | "vue": "^2.0.3", 39 | "vue-hot-reload-api": "^1.2.2", 40 | "vue-html-loader": "^1.0.0", 41 | "vue-loader": "^9.7.0", 42 | "webpack": "^1.12.9", 43 | "webpack-dev-server": "^1.14.0" 44 | }, 45 | "dependencies": { 46 | "vue-popup": "^0.2.9" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var CONFIRM_TEXT = '确定'; 2 | var CANCEL_TEXT = '取消'; 3 | 4 | var defaults = { 5 | title: '提示', 6 | message: '', 7 | type: '', 8 | showInput: false, 9 | showClose: true, 10 | modalFade: false, 11 | lockScroll: false, 12 | closeOnClickModal: true, 13 | inputValue: null, 14 | inputPlaceholder: '', 15 | inputPattern: null, 16 | inputValidator: null, 17 | inputErrorMessage: '', 18 | showConfirmButton: true, 19 | showCancelButton: false, 20 | confirmButtonPosition: 'right', 21 | confirmButtonHighlight: false, 22 | cancelButtonHighlight: false, 23 | confirmButtonText: CONFIRM_TEXT, 24 | cancelButtonText: CANCEL_TEXT, 25 | confirmButtonClass: '', 26 | cancelButtonClass: '' 27 | }; 28 | 29 | import Vue from 'vue'; 30 | import msgboxVue from './msgbox.vue'; 31 | 32 | var merge = function(target) { 33 | for (var i = 1, j = arguments.length; i < j; i++) { 34 | var source = arguments[i]; 35 | for (var prop in source) { 36 | if (source.hasOwnProperty(prop)) { 37 | var value = source[prop]; 38 | if (value !== undefined) { 39 | target[prop] = value; 40 | } 41 | } 42 | } 43 | } 44 | 45 | return target; 46 | }; 47 | 48 | var MessageBoxConstructor = Vue.extend(msgboxVue); 49 | 50 | var currentMsg, instance; 51 | var msgQueue = []; 52 | 53 | const defaultCallback = action => { 54 | if (currentMsg) { 55 | var callback = currentMsg.callback; 56 | if (typeof callback === 'function') { 57 | if (instance.showInput) { 58 | callback(instance.inputValue, action); 59 | } else { 60 | callback(action); 61 | } 62 | } 63 | if (currentMsg.resolve) { 64 | var $type = currentMsg.options.$type; 65 | if ($type === 'confirm' || $type === 'prompt') { 66 | if (action === 'confirm') { 67 | if (instance.showInput) { 68 | currentMsg.resolve({ value: instance.inputValue, action }); 69 | } else { 70 | currentMsg.resolve(action); 71 | } 72 | } else if (action === 'cancel' && currentMsg.reject) { 73 | currentMsg.reject(action); 74 | } 75 | } else { 76 | currentMsg.resolve(action); 77 | } 78 | } 79 | } 80 | }; 81 | 82 | var initInstance = function() { 83 | instance = new MessageBoxConstructor({ 84 | el: document.createElement('div') 85 | }); 86 | 87 | instance.callback = defaultCallback; 88 | }; 89 | 90 | var showNextMsg = function() { 91 | if (!instance) { 92 | initInstance(); 93 | } 94 | 95 | if (!instance.value || instance.closeTimer) { 96 | if (msgQueue.length > 0) { 97 | currentMsg = msgQueue.shift(); 98 | 99 | var options = currentMsg.options; 100 | for (var prop in options) { 101 | if (options.hasOwnProperty(prop)) { 102 | instance[prop] = options[prop]; 103 | } 104 | } 105 | if (options.callback === undefined) { 106 | instance.callback = defaultCallback; 107 | } 108 | ['modal', 'showClose', 'closeOnClickModal', 'closeOnPressEscape'].forEach(prop => { 109 | if (instance[prop] === undefined) { 110 | instance[prop] = true; 111 | } 112 | }); 113 | document.body.appendChild(instance.$el); 114 | 115 | Vue.nextTick(() => { 116 | instance.value = true; 117 | }); 118 | } 119 | } 120 | }; 121 | 122 | var MessageBox = function(options, callback) { 123 | if (typeof options === 'string') { 124 | options = { 125 | title: options 126 | }; 127 | if (arguments[1]) { 128 | options.message = arguments[1]; 129 | } 130 | if (arguments[2]) { 131 | options.type = arguments[2]; 132 | } 133 | } else if (options.callback && !callback) { 134 | callback = options.callback; 135 | } 136 | 137 | if (typeof Promise !== 'undefined') { 138 | return new Promise(function(resolve, reject) { // eslint-disable-line 139 | msgQueue.push({ 140 | options: merge({}, defaults, MessageBox.defaults || {}, options), 141 | callback: callback, 142 | resolve: resolve, 143 | reject: reject 144 | }); 145 | 146 | showNextMsg(); 147 | }); 148 | } else { 149 | msgQueue.push({ 150 | options: merge({}, defaults, MessageBox.defaults || {}, options), 151 | callback: callback 152 | }); 153 | 154 | showNextMsg(); 155 | } 156 | }; 157 | 158 | MessageBox.setDefaults = function(defaults) { 159 | MessageBox.defaults = defaults; 160 | }; 161 | 162 | MessageBox.alert = function(message, title, options) { 163 | if (typeof title === 'object') { 164 | options = title; 165 | title = ''; 166 | } 167 | return MessageBox(merge({ 168 | title: title, 169 | message: message, 170 | $type: 'alert', 171 | closeOnPressEscape: false, 172 | closeOnClickModal: false 173 | }, options)); 174 | }; 175 | 176 | MessageBox.confirm = function(message, title, options) { 177 | if (typeof title === 'object') { 178 | options = title; 179 | title = ''; 180 | } 181 | return MessageBox(merge({ 182 | title: title, 183 | message: message, 184 | $type: 'confirm', 185 | showCancelButton: true 186 | }, options)); 187 | }; 188 | 189 | MessageBox.prompt = function(message, title, options) { 190 | if (typeof title === 'object') { 191 | options = title; 192 | title = ''; 193 | } 194 | return MessageBox(merge({ 195 | title: title, 196 | message: message, 197 | showCancelButton: true, 198 | showInput: true, 199 | $type: 'prompt' 200 | }, options)); 201 | }; 202 | 203 | MessageBox.close = function() { 204 | instance.value = false; 205 | msgQueue = []; 206 | currentMsg = null; 207 | }; 208 | 209 | export default MessageBox; 210 | export { MessageBox }; 211 | -------------------------------------------------------------------------------- /src/msgbox.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 138 | 139 | 140 | 301 | -------------------------------------------------------------------------------- /webpack.base.js: -------------------------------------------------------------------------------- 1 | /*eslint-env node */ 2 | module.exports = { 3 | module: { 4 | loaders: [ 5 | { test: /\.vue$/, loader: 'vue' }, 6 | { test: /\.js$/, loader: 'babel' } 7 | ] 8 | }, 9 | vue: { 10 | loaders: { 11 | js: 'babel!eslint' 12 | } 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /*eslint-env node */ 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 3 | var options = require('./webpack.base.js'); 4 | options.entry = './src'; 5 | options.output = { 6 | library: 'VueMsgbox', 7 | libraryTarget: 'umd', 8 | filename: 'vue-msgbox.js', 9 | path: './lib' 10 | }; 11 | options.externals = { 12 | vue: { 13 | root: 'Vue', 14 | commonjs: 'vue', 15 | commonjs2: 'vue', 16 | amd: 'vue' 17 | } 18 | }; 19 | options.plugins = [new ExtractTextPlugin('vue-msgbox.css')]; 20 | options.vue.loaders.css = ExtractTextPlugin.extract('style', 'css'); 21 | module.exports = options; 22 | -------------------------------------------------------------------------------- /webpack.example.config.js: -------------------------------------------------------------------------------- 1 | /*eslint-env node */ 2 | var options = require('./webpack.base.js'); 3 | options.entry = './example'; 4 | options.output = { 5 | filename: './example/dist/build.js', 6 | publicPath: '/' 7 | }; 8 | module.exports = options; 9 | --------------------------------------------------------------------------------