├── .babelrc ├── .gitignore ├── LICENSE.md ├── README.md ├── build ├── build.js ├── build.rollup.js ├── check-versions.js ├── code-loader.js ├── dev-client.js ├── dev-server.js ├── example_loader.js ├── inject-loader.js ├── rollup.config.js ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── dist ├── vue-universal-modal.css ├── vue-universal-modal.js ├── vue-universal-modal.js.map ├── vue-universal-modal.min.css └── vue-universal-modal.min.js ├── docs ├── index.html └── static │ ├── avatars │ ├── 1.png │ ├── 2.png │ ├── 3.jpg │ ├── 4.jpg │ └── 5.jpg │ ├── css │ ├── app.95846c59d07da10696a8bc676fddd16a.css │ └── app.95846c59d07da10696a8bc676fddd16a.css.map │ ├── images │ ├── 1.jpg │ ├── 10.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ ├── 9.jpg │ └── wide │ │ ├── 1.png │ │ ├── 2.jpg │ │ ├── 3.png │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ └── 7.png │ ├── img │ └── 1.e289a36.png │ ├── js │ ├── app.3ea48f7cca359e904af7.js │ ├── app.3ea48f7cca359e904af7.js.map │ ├── manifest.426f53d0521bbe6e946b.js │ ├── manifest.426f53d0521bbe6e946b.js.map │ ├── vendor.de6a133fd23cae40d923.js │ └── vendor.de6a133fd23cae40d923.js.map │ └── logo.png ├── es ├── close-icon.js ├── index.js ├── modal-wrapper.js ├── modal.js └── utils │ └── bus.js ├── lib ├── close-icon.js ├── index.js ├── modal-wrapper.js ├── modal.js └── utils │ └── bus.js ├── package-lock.json ├── package.json ├── rollup.config.js └── src ├── close-icon.js ├── index.js ├── modal-wrapper.js ├── modal.js ├── style.scss └── utils └── bus.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { 4 | "targets": { 5 | "browsers": ["last 2 versions", "safari >= 7"] 6 | }, 7 | "modules": false 8 | }] 9 | ], 10 | "plugins": [ 11 | "syntax-dynamic-import" 12 | ], 13 | "env": { 14 | "development": { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | demo/ 4 | npm-debug.log -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - vuNemesis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #vue-universal-modal 2 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /build/build.rollup.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var path = require('path') 3 | var chalk = require('chalk') 4 | var rollup = require('rollup') 5 | var babel = require('rollup-plugin-babel') 6 | var uglify = require('rollup-plugin-uglify') 7 | // var minify = require('uglify-es').minify; 8 | 9 | var version = process.env.VERSION || require('../package.json').version 10 | var author = process.env.VERSION || require('../package.json').author 11 | var license = process.env.VERSION || require('../package.json').license 12 | 13 | var banner = 14 | '/**\n' + 15 | ' * Vue-universal-slider v' + version + '\n' + 16 | ' * (c) ' + new Date().getFullYear() + ' ' + author + '\n' + 17 | ' * @license ' + license + '\n' + 18 | ' */\n' 19 | 20 | rollup.rollup({ 21 | entry: path.resolve(__dirname, '..', 'src/index.js'), 22 | plugins: [ 23 | babel(), 24 | uglify() 25 | ] 26 | }) 27 | .then(bundle => { 28 | return write(path.resolve(__dirname, '../dist/vue-universal-slider.js'), bundle.generate({ 29 | format: 'umd', 30 | moduleName: 'vue-universal-slider' 31 | }).code) 32 | }) 33 | .then(() => { 34 | console.log(chalk.green('\nAwesome! Vue-universal-slider v' + version + ' builded.\n')) 35 | }) 36 | .catch(console.log) 37 | 38 | function getSize (code) { 39 | return (code.length / 1024).toFixed(2) + 'kb' 40 | } 41 | 42 | function write (dest, code) { 43 | return new Promise(function (resolve, reject) { 44 | code = banner + code 45 | fs.writeFile(dest, code, function (err) { 46 | if (err) return reject(err) 47 | console.log(chalk.blue(dest) + ' ' + getSize(code)) 48 | resolve() 49 | }) 50 | }) 51 | } 52 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /build/code-loader.js: -------------------------------------------------------------------------------- 1 | const compiler = require("vue-template-compiler"); 2 | const _ = require('lodash'); 3 | 4 | module.exports = function (source, map) { 5 | var callback = this.async(); 6 | this.loadModule(`!raw-loader!${this.resourcePath}`, (err, sourceParent, sourceMap, module) => { 7 | const raw = eval(sourceParent) 8 | const example = parseSource(raw, source) 9 | callback(null, 'module.exports = function(Component) {Component.options.__example = ' + JSON.stringify(example).trim() + '}', map) 10 | }) 11 | // this.callback(null, 'module.exports = function(Component) {if(!Component.options.__examples) Component.options.__examples = []; Component.options.__examples.push(' + 12 | // JSON.stringify(source).trim() + 13 | // ')}', map) 14 | } 15 | 16 | // module.exports.pitch = function(remainingRequest, precedingRequest, data) { 17 | 18 | // }; 19 | 20 | function parseSource(source, sourceExample) { 21 | const blocks = compiler.parseComponent(source, { pad: "space" }) 22 | const template = blocks.template ? _.trim(blocks.template.content) : '' 23 | const script = blocks.script ? _.trim(blocks.script.content) : '' 24 | let info = {} 25 | let key 26 | const blocksExample = compiler.parseComponent(sourceExample, { pad: "space" }) 27 | if(blocksExample.customBlocks.length) { 28 | blocksExample.customBlocks.forEach(block => { 29 | info[block.type] = _.trim(block.content) 30 | }) 31 | key = info.title ? _.camelCase(info.title) : '' 32 | } 33 | return { 34 | key, 35 | template, 36 | script, 37 | info 38 | } 39 | } -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | var compiler = webpack(webpackConfig) 25 | 26 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 27 | publicPath: webpackConfig.output.publicPath, 28 | quiet: true 29 | }) 30 | 31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 32 | log: () => {} 33 | }) 34 | // force page reload when html-webpack-plugin template changes 35 | compiler.plugin('compilation', function (compilation) { 36 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 37 | hotMiddleware.publish({ action: 'reload' }) 38 | cb() 39 | }) 40 | }) 41 | 42 | // proxy api requests 43 | Object.keys(proxyTable).forEach(function (context) { 44 | var options = proxyTable[context] 45 | if (typeof options === 'string') { 46 | options = { target: options } 47 | } 48 | app.use(proxyMiddleware(options.filter || context, options)) 49 | }) 50 | 51 | // handle fallback for HTML5 history API 52 | app.use(require('connect-history-api-fallback')()) 53 | 54 | // serve webpack bundle output 55 | app.use(devMiddleware) 56 | 57 | // enable hot-reload and state-preserving 58 | // compilation error display 59 | app.use(hotMiddleware) 60 | 61 | // serve pure static assets 62 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 63 | app.use(staticPath, express.static('./demo/static')) 64 | 65 | var uri = 'http://localhost:' + port 66 | 67 | var _resolve 68 | var readyPromise = new Promise(resolve => { 69 | _resolve = resolve 70 | }) 71 | 72 | console.log('> Starting dev server...') 73 | devMiddleware.waitUntilValid(() => { 74 | console.log('> Listening at ' + uri + '\n') 75 | // when env is testing, don't need open it 76 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 77 | opn(uri) 78 | } 79 | _resolve() 80 | }) 81 | 82 | var server = app.listen(port) 83 | 84 | module.exports = { 85 | ready: readyPromise, 86 | close: () => { 87 | server.close() 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /build/example_loader.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var fs = require('fs-extended'); 3 | const _ = require('lodash'); 4 | const Babel = require('babel-standalone'); 5 | const compiler = require("vue-template-compiler"); 6 | 7 | module.exports = function loader(source, map) { 8 | let ex = [] 9 | let props = {} 10 | const blocks = compiler.parseComponent(source, { pad: "space" }) 11 | 12 | if(blocks.script && blocks.script.content) { 13 | const { code } = Babel.transform( 14 | blocks.script.content, { presets: ["es2015"] }, 15 | ); 16 | props = eval(`const exports = {};${code}`); // eslint-disable-line 17 | } 18 | 19 | if(blocks.customBlocks.length) { 20 | const examples = blocks.customBlocks.filter(block => block.type ==='example') 21 | if(examples.length) { 22 | examples.forEach((example, index) => { 23 | let title, description, script, template, key, code, data, info 24 | const blocksExample = compiler.parseComponent(example.content, { pad: "space" }) 25 | if(blocksExample.customBlocks.length) { 26 | title = blocksExample.customBlocks.find(block => block.type ==='title') 27 | description = blocksExample.customBlocks.find(block => block.type ==='description') 28 | info = blocksExample.customBlocks.find(block => block.type ==='info') 29 | 30 | script = blocksExample.script 31 | template = blocksExample.template 32 | 33 | key = title ? _.camelCase(title.content) : '' 34 | title = title ? _.trim(title.content) : '' 35 | description = description ? _.trim(description.content) : '' 36 | script = script ? _.trim(script.content) : '' 37 | template = template ? _.trim(template.content) : '' 38 | code = '\n\n -------------------------------------------------------------------------------- /docs/static/avatars/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/avatars/1.png -------------------------------------------------------------------------------- /docs/static/avatars/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/avatars/2.png -------------------------------------------------------------------------------- /docs/static/avatars/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/avatars/3.jpg -------------------------------------------------------------------------------- /docs/static/avatars/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/avatars/4.jpg -------------------------------------------------------------------------------- /docs/static/avatars/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/avatars/5.jpg -------------------------------------------------------------------------------- /docs/static/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/1.jpg -------------------------------------------------------------------------------- /docs/static/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/10.jpg -------------------------------------------------------------------------------- /docs/static/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/2.jpg -------------------------------------------------------------------------------- /docs/static/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/3.jpg -------------------------------------------------------------------------------- /docs/static/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/4.jpg -------------------------------------------------------------------------------- /docs/static/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/5.jpg -------------------------------------------------------------------------------- /docs/static/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/6.jpg -------------------------------------------------------------------------------- /docs/static/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/7.jpg -------------------------------------------------------------------------------- /docs/static/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/8.jpg -------------------------------------------------------------------------------- /docs/static/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/9.jpg -------------------------------------------------------------------------------- /docs/static/images/wide/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/1.png -------------------------------------------------------------------------------- /docs/static/images/wide/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/2.jpg -------------------------------------------------------------------------------- /docs/static/images/wide/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/3.png -------------------------------------------------------------------------------- /docs/static/images/wide/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/4.jpg -------------------------------------------------------------------------------- /docs/static/images/wide/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/5.jpg -------------------------------------------------------------------------------- /docs/static/images/wide/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/6.jpg -------------------------------------------------------------------------------- /docs/static/images/wide/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/images/wide/7.png -------------------------------------------------------------------------------- /docs/static/img/1.e289a36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vuNemesis/vue-universal-modal/5f45d122b2b8f1e678b4ff73c03e9aa908c633a7/docs/static/img/1.e289a36.png -------------------------------------------------------------------------------- /docs/static/js/app.3ea48f7cca359e904af7.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{1:function(t,e,u){"use strict";var a=u(7),i=u(28),n=u(6);u.d(e,"c",function(){return i.a}),u.d(e,"b",function(){return n.a});var o={};o.install=function(t){t.prototype.$modals=new t({name:"$modals",created:function(){var t=this;a.a.$on("opened",function(e){t.$emit("modals:opened",e)}),a.a.$on("closed",function(e){t.$emit("modals:closed",e)}),a.a.$on("destroyed",function(e){t.$emit("modals:destroyed",e)}),this.$on("new",function(e){t.open(e)}),this.$on("close",function(e){t.close(e)}),this.$on("dismiss",function(e){t.dismiss(e||null)})},methods:{open:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;a.a.$emit("new",t)},close:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;a.a.$emit("close",t)},dismiss:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;a.a.$emit("dismiss",t)}}}),t.mixin({created:function(){this.$on("modals:new",function(t){a.a.$emit("new",t)}),this.$on("modals:close",function(t){a.a.$emit("close",t)}),this.$on("modals:dismiss",function(t){a.a.$emit("dismiss",t)})}})},"undefined"!=typeof window&&window.Vue&&window.Vue.use(o),e.a=o},10:function(t,e,u){"use strict";e.a={name:"page-row",functional:!0,props:{title:{type:String,default:""},margin:{type:Number,default:0}},render:function(t,e){var u=e.props,a=e.children;return t("div",{class:"page-row",style:{marginBottom:u.margin+"em"}},[u.title&&t("div",{class:"page-row__title"},u.title),a])}}},11:function(t,e,u){"use strict";var a=u(5),i=u(227),n=u(217),o=u.n(n),s=u(215),m=u.n(s),l=u(218),r=u.n(l),c=u(216),d=u.n(c);a.a.use(i.a),e.a=new i.a({scrollBehavior:function(t,e,u){return t.hash?{selector:t.hash}:{x:0,y:0}},routes:[{path:"/",name:"Home",component:o.a},{path:"/examples",name:"Examples",component:d.a},{path:"/docs",name:"Docs",component:m.a},{path:"/props",name:"Props",component:r.a}]})},12:function(t,e){},16:function(t,e,u){function a(t){u(30)}var i=u(0)(u(19),u(222),a,null,null);t.exports=i.exports},17:function(t,e,u){var a=u(0)(u(20),u(221),null,null,null);t.exports=a.exports},18:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(5),i=u(16),n=u.n(i),o=u(14),s=u.n(o),m=u(13),l=u.n(m),r=u(11),c=u(17),d=u.n(c),p=u(10),v=u(1),f=u(12),_=(u.n(f),u(15)),b=u.n(_);a.a.config.productionTip=!1,s.a.use(l.a),a.a.component(d.a.name,d.a),a.a.component(p.a.name,p.a),a.a.use(v.a),a.a.component(v.b.name,v.b),a.a.use(b.a),new a.a({el:"#app",router:r.a,render:function(t){return t(n.a)}})},19:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(1);e.default={name:"app",components:{ModalWrapper:a.c}}},20:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={name:"page-content"}},21:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(9),i=u.n(a);e.default={name:"content-modal",components:{vModal:i.a},props:{lorem:{type:Boolean,default:!1},modal:{type:Boolean,default:!1},escape:{type:Boolean,default:!1},dismiss:{type:Boolean,default:!0}},methods:{openModal:function(){this.$modals.open({component:i.a,isBottom:!0,isLeft:!0,props:{header:!0,footer:!0}})}}}},213:function(t,e,u){t.exports=u.p+"static/img/1.e289a36.png"},214:function(t,e,u){var a=u(0)(u(21),u(224),null,null,null);t.exports=a.exports},215:function(t,e,u){var a=u(0)(u(23),u(219),null,null,null);t.exports=a.exports},216:function(t,e,u){var a=u(0)(u(24),u(220),null,null,null);t.exports=a.exports},217:function(t,e,u){var a=u(0)(u(25),u(223),null,null,null);t.exports=a.exports},218:function(t,e,u){var a=u(0)(u(26),u(225),null,null,null);t.exports=a.exports},219:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",[u("div",{staticStyle:{padding:"0 2em 2em"}},[u("p",[t._v("Variants")]),t._v(" "),u("pre",{directives:[{name:"highlightjs",rawName:"v-highlightjs"}]},[u("code",{staticClass:"js",staticStyle:{"font-size":"0.9em",padding:"1em"}},[t._v(t._s(t.formatJS(t.variants)))])])]),t._v(" "),u("div",{staticStyle:{padding:"0 2em 2em"}},[u("p",[t._v("Simple")]),t._v(" "),u("pre",{directives:[{name:"highlightjs",rawName:"v-highlightjs"}]},[u("code",{staticClass:"js",staticStyle:{"font-size":"0.9em",padding:"1em"}},[t._v(t._s(t.formatJS(t.example1)))])])]),t._v(" "),u("div",{staticStyle:{padding:"0 2em 2em"}},[u("p",[t._v("Custom")]),t._v(" "),u("pre",{directives:[{name:"highlightjs",rawName:"v-highlightjs"}]},[u("code",{staticClass:"js",staticStyle:{"font-size":"0.9em",padding:"1em"}},[t._v(t._s(t.formatJS(t.example2)))])])]),t._v(" "),u("div",{staticStyle:{padding:"0 2em 2em"}},[u("p",[t._v("Modal with the most simple component")]),t._v(" "),u("pre",{directives:[{name:"highlightjs",rawName:"v-highlightjs"}]},[u("code",{staticClass:"js",staticStyle:{"font-size":"0.9em",padding:"1em"}},[t._v(t._s(t.formatJS(t.example3)))])])])])},staticRenderFns:[]}},22:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(213),i=u.n(a);e.default={name:"v-modal",props:{title:String,header:Boolean,footer:Boolean,closeCallback:{type:Boolean,default:!1},lorem:{type:Boolean,default:!0}},data:function(){return{avatar:i.a,isLorem:this.lorem}},methods:{closeBack:function(){this.$modals.close({data:"data"})},close:function(){this.$modals.dismiss()}}}},220:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",[u("page-row",{attrs:{title:"Variant",margin:2}},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(0)}}},[t._v("Simple")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(1)}}},[t._v("Long content")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(2)}}},[t._v("Scroll")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(3)}}},[t._v("Fullscreen")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(20)}}},[t._v("Scroll & Fullscreen")])])]),t._v(" "),u("page-row",{attrs:{margin:2,title:"Position"}},[u("div",[u("div",{staticClass:"row"},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(7)}}},[t._v("top left")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(8)}}},[t._v("top")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(9)}}},[t._v("top right")])])]),t._v(" "),u("div",{staticClass:"row"},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(4)}}},[t._v("left center")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(5)}}},[t._v("center")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(6)}}},[t._v("right center")])])]),t._v(" "),u("div",{staticClass:"row"},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(10)}}},[t._v("bottom left")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(11)}}},[t._v("bottom")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(12)}}},[t._v("bottom right")])])])])]),t._v(" "),u("page-row",{attrs:{title:"Scroll with left/right position",margin:2}},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(13)}}},[t._v("Left")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(14)}}},[t._v("Right")])])]),t._v(" "),u("page-row",{attrs:{title:"Header and footer slots",margin:2}},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(15)}}},[t._v("Header")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(16)}}},[t._v("Footer")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-small uk-button-primary",on:{click:function(e){t.openModal(17)}}},[t._v("Header & Footer")])])]),t._v(" "),u("page-row",{attrs:{title:"Callback",margin:2}},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(18)}}},[t._v("onDismiss")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(19)}}},[t._v("onClose")])])]),t._v(" "),u("page-row",{attrs:{title:"Other",margin:2}},[u("div",{staticClass:"uk-button-group"},[u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(21)}}},[t._v("Multi modals")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(22)}}},[t._v("Escapable")]),t._v(" "),u("button",{staticClass:"uk-button uk-button-primary uk-button-small",on:{click:function(e){t.openModal(23)}}},[t._v("Without dismiss by pressing the mask")])])])],1)},staticRenderFns:[]}},221:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",{staticClass:"page-content"},[u("router-view")],1)},staticRenderFns:[]}},222:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",{attrs:{id:"app"}},[u("nav",{staticClass:"uk-navbar-container"},[u("div",{staticClass:"uk-navbar-left"},[u("ul",{staticClass:"uk-navbar-nav"},[u("li",{staticClass:"uk-active"},[u("router-link",{attrs:{to:"/"}},[u("b",[t._v("Vue-universal-modal")])])],1),t._v(" "),u("li",{},[u("router-link",{attrs:{to:"/docs"}},[t._v("Docs")])],1),t._v(" "),u("li",{},[u("router-link",{attrs:{to:"/props"}},[t._v("Props")])],1),t._v(" "),u("li",{},[u("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0)])])]),t._v(" "),u("page-content"),t._v(" "),u("modal-wrapper")],1)},staticRenderFns:[function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("li",[u("a",{attrs:{target:"_blank",href:"https://github.com/vuNemesis/vue-universal-modal"}},[u("span",{attrs:{"uk-icon":"github"}})])])}]}},223:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement;return(t._self._c||e)("div",[t._v("\n In progress...\n")])},staticRenderFns:[]}},224:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",[t.escape&&t.dismiss?u("div",[t._v("Press the "),u("b",[t._v("Esc")]),t._v("-key to dismiss the modal")]):t._e(),t._v(" "),t.escape&&!t.dismiss?u("div",[t._v("Press the "),u("b",[t._v("Esc")]),t._v("-key or "),u("b",[t._v("Cancel")]),t._v("-button to dismiss the modal")]):t._e(),t._v(" "),t.escape?t._e():u("div",[t._v("\n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.\n "),t.lorem?[u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")])]:t._e()],2),t._v(" "),t.dismiss?t._e():u("div",{staticStyle:{"margin-top":"2em"}},[u("button",{staticClass:"uk-button uk-button-smaller uk-button-primary",on:{click:function(e){t.$modals.dismiss()}}},[t._v("Cancel")])]),t._v(" "),t.modal?u("div",{staticStyle:{"margin-top":"2em"}},[u("button",{staticClass:"uk-button uk-button-smaller uk-button-primary",on:{click:t.openModal}},[t._v("Open modal")])]):t._e()])},staticRenderFns:[]}},225:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("div",[u("div",{staticStyle:{padding:"0 2em 2em"}},[u("h4",[t._v("Props for Modal component and for new modal options")]),t._v(" "),u("table",{staticClass:"uk-table uk-table-divider uk-table-small uk-table-striped"},[t._m(0),t._v(" "),u("tbody",t._l(t.properties,function(e,a){return u("tr",{key:a},[u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.name))]),t._v(" "),u("td",{staticClass:"uk-width-small"},[u("small",[t._v(t._s(e.type))])]),t._v(" "),u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.default))]),t._v(" "),u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.accepted))]),t._v(" "),u("td",[t._v(t._s(e.description))])])}))])]),t._v(" "),u("div",{staticStyle:{padding:"0 2em 2em"}},[u("h4",[t._v("Add props for new modal options")]),t._v(" "),u("table",{staticClass:"uk-table uk-table-divider uk-table-small"},[t._m(1),t._v(" "),u("tbody",t._l(t.addProperties,function(e,a){return u("tr",{key:a},[u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.name))]),t._v(" "),u("td",{staticClass:"uk-width-small"},[u("small",[t._v(t._s(e.type))])]),t._v(" "),u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.default))]),t._v(" "),u("td",{staticClass:"uk-width-small"},[t._v(t._s(e.accepted))]),t._v(" "),u("td",[t._v(t._s(e.description))])])}))])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("thead",[u("tr",[u("th",[t._v("Property")]),t._v(" "),u("th",[t._v("Type")]),t._v(" "),u("th",[t._v("Default")]),t._v(" "),u("th",[t._v("Accepted")]),t._v(" "),u("th",[t._v("Description")])])])},function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("thead",[u("tr",[u("th",[t._v("Property")]),t._v(" "),u("th",[t._v("Type")]),t._v(" "),u("th",[t._v("Default")]),t._v(" "),u("th",[t._v("Accepted")]),t._v(" "),u("th",[t._v("Description")])])])}]}},226:function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,u=t._self._c||e;return u("vu-modal",{attrs:{title:"Test modal",isScroll:!0,size:"p50",center:!0,escapable:!0}},[t.header?u("div",{staticStyle:{display:"flex","justify-content":"left","align-items":"center"},attrs:{slot:"header"},slot:"header"},[u("img",{attrs:{src:t.avatar,width:"30",height:"30"}}),t._v(" "),u("div",{staticStyle:{"padding-left":"10px"}},[t._v("Basic modal")])]):t._e(),t._v(" "),u("div",[u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),t.isLorem?[u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")]),t._v(" "),u("p",[t._v("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia consequuntur minus sint quidem ut tenetur dicta sunt voluptates numquam. Eum totam ex maxime aut recusandae quae laborum fugit ab autem.")])]:t._e()],2),t._v(" "),t.footer?u("div",{attrs:{slot:"footer"},slot:"footer"},[t.closeCallback?u("button",{staticClass:"uk-button uk-button-smaller uk-button-primary",on:{click:t.closeBack}},[t._v("Close with onClose callback")]):t._e(),t._v(" "),u("button",{staticClass:"uk-button uk-button-smaller uk-button-primary",on:{click:t.close}},[t._v("Cancel")])]):t._e()])},staticRenderFns:[]}},23:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(209);u.n(a);e.default={name:"docs-page",methods:{formatJS:function(t){return u.i(a.js)(t,{indent_size:2,indent_char:" ",wrap_attributes:"auto",wrap_attributes_indent_size:2,end_with_newline:!1})},formatHTML:function(t){var e=t.replace(/><(?!\/i|\/label|\/span|option)/g,">\n<");return u.i(a.html)(e,{indent_size:2,indent_char:" ",wrap_attributes:"auto",wrap_attributes_indent_size:2,end_with_newline:!1})}},data:function(){return{variants:"\n // the following three options are available in any component\n this.$modals.open(options)\n this.$modals.$emit('new', options)\n this.$emit('modals:new', options)\n\n // the next option can be used anywhere, for this import the Bus from VueUniversalModal\n Bus.$emit('new', options) \n ",example1:"\n this.$modals.open({\n title: 'Simple modal',\n component: Simple\n })\n ",example2:"\n this.$modals.open({\n title: 'Custom modal',\n component: Custom,\n isScroll: true,\n center: true,\n size: 'p90'\n })\n ",example3:"\n this.$modals.open({\n title: 'Custom modal',\n component: {\n template: \"
i'm template :)
\"\n }\n })\n "}}}},24:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=u(214),i=u.n(a),n=u(9),o=u.n(n);u(1);e.default={name:"examples-page",data:function(){return{modals:[{title:"Simple modal",component:i.a},{title:"Long modal",component:i.a,props:{lorem:!0}},{title:"Scroll modal",component:i.a,isScroll:!0,props:{lorem:!0}},{title:"Fullscreen modal",component:i.a,fullscreen:!0,props:{lorem:!0}},{title:"Left center position modal",component:i.a,isLeft:!0,center:!0},{title:"Center modal",component:i.a,center:!0},{title:"Right center position modal",component:i.a,isRight:!0,center:!0},{title:"Top left position modal",component:i.a,isTop:!0,isLeft:!0},{title:"Top position modal",component:i.a,isTop:!0},{title:"Top right position modal",component:i.a,isTop:!0,isRight:!0},{title:"Bottom left position modal",component:i.a,isBottom:!0,isLeft:!0},{title:"Bottom position modal",component:i.a,isBottom:!0},{title:"Bottom right position modal",component:i.a,isBottom:!0,isRight:!0},{title:"Scroll left modal",component:i.a,isScroll:!0,isLeft:!0,props:{lorem:!0}},{title:"Scroll right modal",component:i.a,isScroll:!0,isRight:!0,props:{lorem:!0}},{title:"Custom header slot",component:o.a,props:{header:!0}},{title:"Custom footer slot",component:o.a,props:{footer:!0}},{title:"Custom header and footer slot",component:o.a,props:{header:!0,footer:!0}},{title:"Callback onDismiss",component:o.a,props:{footer:!0},onDismiss:function(){alert("onDismiss callback call!")}},{title:"Callback onClose",component:o.a,props:{footer:!0,closeCallback:!0},onClose:function(){alert("onClose callback call!")}},{title:"Fullscreen & Scroll modal",component:i.a,fullscreen:!0,isScroll:!0,props:{lorem:!0}},{title:"Multi modal",component:i.a,props:{modal:!0}},{title:"Escapable modal",component:i.a,escapable:!0,center:!0,props:{escape:!0}},{title:"Without dismiss by pressing the mask",component:i.a,escapable:!0,center:!0,dismissable:!1,props:{escape:!0,dismiss:!1}}]}},created:function(){},methods:{openModal:function(t){this.$modals.open(this.modals[t])}}}},25:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={name:"example-page"}},26:function(t,e,u){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={name:"props-page",data:function(){return{addProperties:[{name:"component",description:"",default:"is required",type:"Vue component",accepted:""},{name:"onDismiss",description:"",default:"-",type:"Function",accepted:""},{name:"onClose",description:"",default:"-",type:"Function",accepted:""}],properties:[{name:"title",description:"",default:"-",type:"String",accepted:""},{name:"size",description:"",default:"md",type:"String",accepted:"xs, sm, md, lg, xl, p50, p70, p90"},{name:"className",description:"",default:"-",type:"String",accepted:""},{name:"fullscreen",description:"",default:"false",type:"Boolean",accepted:""},{name:"center",description:"",default:"false",type:"Boolean",accepted:""},{name:"isScroll",description:"",default:"false",type:"Boolean",accepted:""},{name:"isTop",description:"",default:"false",type:"Boolean",accepted:""},{name:"isBottom",description:"",default:"false",type:"Boolean",accepted:""},{name:"isLeft",description:"",default:"false",type:"Boolean",accepted:""},{name:"isRight",description:"",default:"false",type:"Boolean",accepted:""},{name:"escapable",description:"",default:"false",type:"Boolean",accepted:""},{name:"dismissable",description:"",default:"true",type:"Boolean",accepted:""},{name:"bodyPadding",description:"",default:"true",type:"Boolean",accepted:""}]}}}},27:function(t,e,u){"use strict";e.a={name:"close-icon",functional:!0,render:function(t){return t("svg",{attrs:{width:"12px",height:"12px",viewBox:"0 0 12 12",xmlSpace:"preserve"}},[t("line",{attrs:{x1:1,y1:11,x2:11,y2:1},style:{strokeLinecap:"round",strokeLinejoin:"round"}}),t("line",{attrs:{x1:1,y1:1,x2:11,y2:11},style:{strokeLinecap:"round",strokeLinejoin:"round"}})])}}},28:function(t,e,u){"use strict";var a=u(29),i=(u.n(a),u(7)),n=u(6);e.a={name:"vu-modal-wrapper",data:function(){return{modals:[]}},mounted:function(){"undefined"!=typeof document&&document.body.addEventListener("keydown",this.handleTabKey),"undefined"!=typeof document&&document.body.addEventListener("keyup",this.handleEscapeKey)},destroyed:function(){"undefined"!=typeof document&&document.body.removeEventListener("keydown",this.handleTabKey),"undefined"!=typeof document&&document.body.removeEventListener("keyup",this.handleEscapeKey)},created:function(){var t=this;i.a.$on("new",function(e){var u={title:"",dismissable:!0,center:!1,fullscreen:!1,isTop:!1,isBottom:!1,isLeft:!1,isRight:!1,isScroll:!1,className:"",size:"md",escapable:!1,bodyPadding:!0,onClose:function(){},onDismiss:function(){}},a={},n=void 0;if((n=!e.component.template&&e.component.render.call(t,t.$createElement))&&n.componentOptions&&"vu-modal"===n.componentOptions.Ctor.extendOptions.componentName){var o=n.componentOptions.propsData;a={isVmodal:!0,options:Object.assign(u,o,e)}}else a={isVmodal:!1,options:Object.assign(u,e)};n=null,t.modals.push(a),i.a.$emit("opened",{index:t.$last,instance:a}),t.body&&t.body.classList.add("modals-open")}),i.a.$on("close",function(e){var u=null;e&&e.$index&&(u=e.$index),null===u&&(u=t.$last),t.close(e,u)}),i.a.$on("dismiss",function(e){null===e&&(e=t.$last),t.dismiss(e)})},methods:{splice:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;-1!==t&&this.modals.length&&(null===t?this.modals.pop():this.modals.splice(t,1),this.modals.length||(this.body&&this.body.classList.remove("modals-open"),i.a.$emit("destroyed")))},doClose:function(t){this.modals.length&&this.modals[t]&&this.splice(t)},close:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(0!==this.modals.length){var u=e;e&&"function"==typeof e&&(u=e(t,this.modals)),"number"!=typeof u&&(u=this.$last),i.a.$emit("closed",{index:u,instance:this.modals[e],data:t}),!1!==u&&this.modals[u]&&!1===this.modals[u].options.onClose(t)||this.doClose(u)}},dismiss:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=t;t&&"function"==typeof t&&(e=t(this.$last)),"number"!=typeof e&&(e=this.$last),!1!==this.modals[e].options.onDismiss()&&(i.a.$emit("dismissed",{index:e,instance:this.modals[e]}),this.doClose(e))},handleTabKey:function(t){9===t.keyCode&&this.modals.length&&t.preventDefault()},handleEscapeKey:function(t){if(27===t.keyCode&&this.modals.length){if(!this.modals.length)return;this.current.options.escapable&&this.dismiss()}}},computed:{current:function(){return this.modals[this.$last]},$last:function(){return this.modals.length-1},body:function(){if("undefined"!=typeof document)return document.querySelector("body")},wrapperStyle:function(){return{"z-index":5e3+this.$last+1}}},render:function(t){var e=this;if(!this.modals.length)return null;var u=this.modals.map(function(u,a){var i=void 0;return i=u.isVmodal?t(u.options.component,{props:Object.assign({},{vModal:Object.assign(u.options,{disabled:a!=e.$last})},u.options.props)}):t(n.a,{props:Object.assign(u.options,{disabled:a!=e.$last})},[t(u.options.component,{props:u.options.props})]),t("div",{class:["vu-modal__mask",{"vu-modal__mask--disabled":a!=e.$last}],on:{click:function(){u.options.dismissable&&e.dismiss()}},key:a},[i])});return t("div",{class:"vu-modal__wrapper"},[u])}}},29:function(t,e){},30:function(t,e){},6:function(t,e,u){"use strict";var a=u(27);e.a={name:"vu-modal",componentName:"vu-modal",props:{title:{type:String,default:""},className:{type:String,default:""},isScroll:{type:Boolean,default:!1},escapable:{type:Boolean,default:!1},dismissable:{type:Boolean,default:!0},fullscreen:{type:Boolean,default:!1},isTop:{type:Boolean,default:!1},isBottom:{type:Boolean,default:!1},isLeft:{type:Boolean,default:!1},isRight:{type:Boolean,default:!1},center:{type:Boolean,default:!1},size:{type:String,default:"md"},bodyPadding:{type:Boolean,default:!0}},mounted:function(){this.$el.focus&&this.$el.focus()},computed:{propsData:function(){return this.$parent.$vnode.data.props&&this.$parent.$vnode.data.props.vModal?this.$parent.$vnode.data.props.vModal:this.$props}},render:function(t){var e=this,u=this.propsData,i=u.dismissable,n=u.title,o=u.isScroll,s=u.fullscreen,m=u.isTop,l=u.isBottom,r=u.isLeft,c=u.isRight,d=u.center,p=u.size,v=u.className,f=u.bodyPadding,_=i?t("div",{class:"vu-modal__close-btn",on:{click:function(){e.$modals.dismiss()}}},[t(a.a)]):null,b=this.$slots.header?this.$slots.header:n?t("span",{class:["vu-modal__cmp-header-title"]},n):null,g=b?t("div",{class:["vu-modal__cmp-header"]},[b]):null,h=t("div",{class:["vu-modal__cmp-body"],style:{overflowY:o?"auto":null,padding:f?"1em":0}},[this.$slots.default]),q=this.$slots.footer?t("div",{class:["vu-modal__cmp-footer"]},[this.$slots.footer]):null,k={},x="-50%",y="0";return d&&(x="-50%",y="-50%"),(c||r)&&(x="0%"),!m&&!l||o||d||(y="0%"),k.transform="translate("+x+", "+y+")",t("div",{style:k,attrs:{tabindex:-1},class:["vu-modal__cmp",{"vu-modal__cmp--is-fullscreen":s,"vu-modal__cmp--is-center":d,"vu-modal__cmp--is-top":m&&!o&&!d,"vu-modal__cmp--is-bottom":l&&!o&&!d,"vu-modal__cmp--is-left":r,"vu-modal__cmp--is-right":c},o&&s&&"vu-modal__cmp--is-scroll-fullscreen",o&&!s&&"vu-modal__cmp--is-scroll",!s&&"vu-modal__cmp--"+p,v],on:{click:function(t){t.stopPropagation()}}},[_,g,h,q])}}},7:function(t,e,u){"use strict";function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=function(){function t(t,e){for(var u=0;u 0 && arguments[0] !== undefined ? arguments[0] : null; 42 | 43 | Bus.$emit('new', options); 44 | }, 45 | close: function close() { 46 | var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 47 | 48 | Bus.$emit('close', data); 49 | }, 50 | dismiss: function dismiss() { 51 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 52 | 53 | Bus.$emit('dismiss', index); 54 | } 55 | } 56 | }); 57 | 58 | Vue.mixin({ 59 | created: function created() { 60 | this.$on('modals:new', function (options) { 61 | Bus.$emit('new', options); 62 | }); 63 | 64 | this.$on('modals:close', function (data) { 65 | Bus.$emit('close', data); 66 | }); 67 | 68 | this.$on('modals:dismiss', function (index) { 69 | Bus.$emit('dismiss', index); 70 | }); 71 | } 72 | }); 73 | }; 74 | 75 | if (typeof window !== 'undefined' && window.Vue) { 76 | window.Vue.use(VuModal); 77 | } 78 | 79 | export default VuModal; 80 | 81 | export { ModalWrapper, Modal, Bus }; -------------------------------------------------------------------------------- /es/modal-wrapper.js: -------------------------------------------------------------------------------- 1 | import './style.scss'; 2 | import Bus from './utils/bus'; 3 | import ModalCmp from './modal'; 4 | 5 | export default { 6 | name: 'vu-modal-wrapper', 7 | data: function data() { 8 | return { 9 | modals: [] 10 | }; 11 | }, 12 | mounted: function mounted() { 13 | if (typeof document !== 'undefined') { 14 | document.body.addEventListener('keydown', this.handleTabKey); 15 | } 16 | 17 | if (typeof document !== 'undefined') { 18 | document.body.addEventListener('keyup', this.handleEscapeKey); 19 | } 20 | }, 21 | destroyed: function destroyed() { 22 | if (typeof document !== 'undefined') { 23 | document.body.removeEventListener('keydown', this.handleTabKey); 24 | } 25 | 26 | if (typeof document !== 'undefined') { 27 | document.body.removeEventListener('keyup', this.handleEscapeKey); 28 | } 29 | }, 30 | created: function created() { 31 | var _this = this; 32 | 33 | Bus.$on('new', function (options) { 34 | var defaults = { 35 | title: '', 36 | dismissable: true, 37 | center: false, 38 | fullscreen: false, 39 | isTop: false, 40 | isBottom: false, 41 | isLeft: false, 42 | isRight: false, 43 | isScroll: false, 44 | className: '', 45 | size: 'md', 46 | escapable: false, 47 | bodyPadding: true, 48 | onClose: function onClose() {}, 49 | onDismiss: function onDismiss() {} 50 | }; 51 | 52 | var instance = {}; 53 | var rendered = void 0; 54 | if (options.component.template) { 55 | rendered = false; 56 | } else { 57 | rendered = options.component.render.call(_this, _this.$createElement); 58 | } 59 | 60 | if (rendered && rendered.componentOptions && rendered.componentOptions.Ctor.extendOptions.componentName === 'vu-modal') { 61 | var propsData = rendered.componentOptions.propsData; 62 | instance = { 63 | isVmodal: true, 64 | options: Object.assign(defaults, propsData, options) 65 | }; 66 | } else { 67 | instance = { 68 | isVmodal: false, 69 | options: Object.assign(defaults, options) 70 | }; 71 | } 72 | rendered = null; 73 | 74 | _this.modals.push(instance); 75 | 76 | Bus.$emit('opened', { 77 | index: _this.$last, 78 | instance: instance 79 | }); 80 | 81 | _this.body && _this.body.classList.add('modals-open'); 82 | }); 83 | 84 | Bus.$on('close', function (data) { 85 | var index = null; 86 | 87 | if (data && data.$index) index = data.$index; 88 | 89 | if (index === null) index = _this.$last; 90 | 91 | _this.close(data, index); 92 | }); 93 | 94 | Bus.$on('dismiss', function (index) { 95 | if (index === null) index = _this.$last; 96 | 97 | _this.dismiss(index); 98 | }); 99 | }, 100 | 101 | methods: { 102 | splice: function splice() { 103 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 104 | 105 | if (index === -1) return; 106 | 107 | if (!this.modals.length) return; 108 | 109 | if (index === null) this.modals.pop();else this.modals.splice(index, 1); 110 | 111 | if (!this.modals.length) { 112 | this.body && this.body.classList.remove('modals-open'); 113 | Bus.$emit('destroyed'); 114 | } 115 | }, 116 | doClose: function doClose(index) { 117 | if (!this.modals.length) return; 118 | 119 | if (!this.modals[index]) return; 120 | 121 | this.splice(index); 122 | }, 123 | close: function close() { 124 | var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 125 | var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 126 | 127 | if (this.modals.length === 0) return; 128 | 129 | var localIndex = index; 130 | 131 | if (index && typeof index === 'function') { 132 | localIndex = index(data, this.modals); 133 | } 134 | 135 | if (typeof localIndex !== 'number') localIndex = this.$last; 136 | 137 | Bus.$emit('closed', { 138 | index: localIndex, 139 | instance: this.modals[index], 140 | data: data 141 | }); 142 | 143 | if (localIndex !== false && this.modals[localIndex]) { 144 | if (this.modals[localIndex].options.onClose(data) === false) { 145 | return; 146 | } 147 | } 148 | this.doClose(localIndex); 149 | }, 150 | dismiss: function dismiss() { 151 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 152 | 153 | var localIndex = index; 154 | 155 | if (index && typeof index === 'function') localIndex = index(this.$last); 156 | 157 | if (typeof localIndex !== 'number') localIndex = this.$last; 158 | 159 | if (this.modals[localIndex].options.onDismiss() === false) return; 160 | 161 | Bus.$emit('dismissed', { 162 | index: localIndex, 163 | instance: this.modals[localIndex] 164 | }); 165 | 166 | this.doClose(localIndex); 167 | }, 168 | handleTabKey: function handleTabKey(e) { 169 | if (e.keyCode === 9 && this.modals.length) { 170 | e.preventDefault(); 171 | } 172 | }, 173 | handleEscapeKey: function handleEscapeKey(e) { 174 | if (e.keyCode === 27 && this.modals.length) { 175 | if (!this.modals.length) return; 176 | if (this.current.options.escapable) this.dismiss(); 177 | } 178 | } 179 | }, 180 | computed: { 181 | current: function current() { 182 | return this.modals[this.$last]; 183 | }, 184 | $last: function $last() { 185 | return this.modals.length - 1; 186 | }, 187 | body: function body() { 188 | if (typeof document !== 'undefined') { 189 | return document.querySelector('body'); 190 | } 191 | }, 192 | wrapperStyle: function wrapperStyle() { 193 | return { 194 | 'z-index': 5000 + this.$last + 1 195 | }; 196 | } 197 | }, 198 | render: function render(h) { 199 | var _this2 = this; 200 | 201 | if (!this.modals.length) { 202 | return null; 203 | }; 204 | 205 | var modals = this.modals.map(function (modal, index) { 206 | var modalComponent = void 0; 207 | 208 | if (modal.isVmodal) { 209 | modalComponent = h(modal.options.component, { 210 | props: Object.assign({}, { vModal: Object.assign(modal.options, { disabled: index != _this2.$last }) }, modal.options.props) 211 | }); 212 | } else { 213 | modalComponent = h(ModalCmp, { 214 | props: Object.assign(modal.options, { disabled: index != _this2.$last }) 215 | }, [h(modal.options.component, { 216 | props: modal.options.props 217 | })]); 218 | } 219 | return h('div', { 220 | class: ['vu-modal__mask', { 'vu-modal__mask--disabled': index != _this2.$last }], 221 | on: { click: function click() { 222 | modal.options.dismissable && _this2.dismiss(); 223 | } }, 224 | key: index 225 | }, [modalComponent]); 226 | }); 227 | 228 | return h('div', { 229 | class: 'vu-modal__wrapper' 230 | }, [modals]); 231 | } 232 | }; -------------------------------------------------------------------------------- /es/modal.js: -------------------------------------------------------------------------------- 1 | import CloseIcon from './close-icon'; 2 | export default { 3 | name: 'vu-modal', 4 | componentName: 'vu-modal', 5 | props: { 6 | title: { 7 | type: String, 8 | default: '' 9 | }, 10 | className: { 11 | type: String, 12 | default: '' 13 | }, 14 | isScroll: { 15 | type: Boolean, 16 | default: false 17 | }, 18 | escapable: { 19 | type: Boolean, 20 | default: false 21 | }, 22 | dismissable: { 23 | type: Boolean, 24 | default: true 25 | }, 26 | fullscreen: { 27 | type: Boolean, 28 | default: false 29 | }, 30 | isTop: { 31 | type: Boolean, 32 | default: false 33 | }, 34 | isBottom: { 35 | type: Boolean, 36 | default: false 37 | }, 38 | isLeft: { 39 | type: Boolean, 40 | default: false 41 | }, 42 | isRight: { 43 | type: Boolean, 44 | default: false 45 | }, 46 | center: { 47 | type: Boolean, 48 | default: false 49 | }, 50 | size: { 51 | type: String, 52 | default: 'md' 53 | }, 54 | bodyPadding: { 55 | type: Boolean, 56 | default: true 57 | } 58 | }, 59 | mounted: function mounted() { 60 | if (this.$el.focus) { 61 | this.$el.focus(); 62 | } 63 | }, 64 | 65 | computed: { 66 | propsData: function propsData() { 67 | return this.$parent.$vnode.data.props && this.$parent.$vnode.data.props.vModal ? this.$parent.$vnode.data.props.vModal : this.$props; 68 | } 69 | }, 70 | render: function render(h) { 71 | var _this = this; 72 | 73 | var _propsData = this.propsData, 74 | dismissable = _propsData.dismissable, 75 | title = _propsData.title, 76 | isScroll = _propsData.isScroll, 77 | fullscreen = _propsData.fullscreen, 78 | isTop = _propsData.isTop, 79 | isBottom = _propsData.isBottom, 80 | isLeft = _propsData.isLeft, 81 | isRight = _propsData.isRight, 82 | center = _propsData.center, 83 | size = _propsData.size, 84 | className = _propsData.className, 85 | bodyPadding = _propsData.bodyPadding; 86 | 87 | 88 | var closeBtn = dismissable ? h('div', { 89 | class: 'vu-modal__close-btn', 90 | on: { 91 | click: function click() { 92 | _this.$modals.dismiss(); 93 | } 94 | } 95 | }, [h(CloseIcon)]) : null; 96 | 97 | var headerContent = this.$slots.header ? this.$slots.header : title ? h('span', { class: ['vu-modal__cmp-header-title'] }, title) : null; 98 | 99 | var header = headerContent ? h('div', { 100 | class: ['vu-modal__cmp-header'] 101 | }, [headerContent]) : null; 102 | 103 | var body = h('div', { 104 | class: ['vu-modal__cmp-body'], 105 | style: { 106 | overflowY: isScroll ? 'auto' : null, 107 | padding: bodyPadding ? '1em' : 0 108 | } 109 | }, [this.$slots.default]); 110 | 111 | var footer = this.$slots.footer ? h('div', { 112 | class: ['vu-modal__cmp-footer'] 113 | }, [this.$slots.footer]) : null; 114 | 115 | var style = {}; 116 | var translateX = '-50%'; 117 | var translateY = '0'; 118 | if (center) { 119 | translateX = '-50%'; 120 | translateY = '-50%'; 121 | } 122 | if (isRight || isLeft) { 123 | translateX = '0%'; 124 | } 125 | 126 | if ((isTop || isBottom) && !isScroll && !center) { 127 | translateY = '0%'; 128 | } 129 | style.transform = 'translate(' + translateX + ', ' + translateY + ')'; 130 | 131 | return h('div', { 132 | style: style, 133 | attrs: { tabindex: -1 }, 134 | class: ['vu-modal__cmp', { 135 | 'vu-modal__cmp--is-fullscreen': fullscreen, 136 | 'vu-modal__cmp--is-center': center, 137 | 'vu-modal__cmp--is-top': isTop && !isScroll && !center, 138 | 'vu-modal__cmp--is-bottom': isBottom && !isScroll && !center, 139 | 'vu-modal__cmp--is-left': isLeft, 140 | 'vu-modal__cmp--is-right': isRight 141 | }, isScroll && fullscreen && 'vu-modal__cmp--is-scroll-fullscreen', isScroll && !fullscreen && 'vu-modal__cmp--is-scroll', !fullscreen && 'vu-modal__cmp--' + size, className], 142 | on: { click: function click(event) { 143 | event.stopPropagation(); 144 | } } 145 | }, [closeBtn, header, body, footer]); 146 | } 147 | }; -------------------------------------------------------------------------------- /es/utils/bus.js: -------------------------------------------------------------------------------- 1 | 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; }; }(); 2 | 3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4 | 5 | var instance = null; 6 | 7 | var EventBus = function () { 8 | function EventBus() { 9 | _classCallCheck(this, EventBus); 10 | 11 | if (!instance) { 12 | this.events = {}; 13 | instance = this; 14 | } 15 | return instance; 16 | } 17 | 18 | _createClass(EventBus, [{ 19 | key: "$emit", 20 | value: function $emit(event, message) { 21 | if (!this.events[event]) return; 22 | var callbacks = this.events[event]; 23 | for (var i = 0, l = callbacks.length; i < l; i++) { 24 | var callback = callbacks[i]; 25 | callback.call(this, message); 26 | } 27 | } 28 | }, { 29 | key: "$on", 30 | value: function $on(event, callback) { 31 | if (!this.events[event]) this.events[event] = []; 32 | this.events[event].push(callback); 33 | } 34 | }]); 35 | 36 | return EventBus; 37 | }(); 38 | 39 | export default new EventBus(); -------------------------------------------------------------------------------- /lib/close-icon.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'close-icon', 3 | functional: true, 4 | render: function render(h) { 5 | return h('svg', { 6 | attrs: { 7 | width: '12px', 8 | height: '12px', 9 | viewBox: '0 0 12 12', 10 | xmlSpace: 'preserve' 11 | } 12 | }, [h('line', { 13 | attrs: { 14 | x1: 1, 15 | y1: 11, 16 | x2: 11, 17 | y2: 1 18 | }, 19 | style: { 20 | strokeLinecap: 'round', 21 | strokeLinejoin: 'round' 22 | } 23 | }), h('line', { 24 | attrs: { 25 | x1: 1, 26 | y1: 1, 27 | x2: 11, 28 | y2: 11 29 | }, 30 | style: { 31 | strokeLinecap: 'round', 32 | strokeLinejoin: 'round' 33 | } 34 | })]); 35 | } 36 | }; -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import Bus from './utils/bus'; 2 | import ModalWrapper from './modal-wrapper'; 3 | import Modal from './modal'; 4 | 5 | var VuModal = {}; 6 | VuModal.install = function (Vue) { 7 | Vue.prototype.$modals = new Vue({ 8 | name: '$modals', 9 | 10 | created: function created() { 11 | var _this = this; 12 | 13 | Bus.$on('opened', function (data) { 14 | _this.$emit('modals:opened', data); 15 | }); 16 | 17 | Bus.$on('closed', function (data) { 18 | _this.$emit('modals:closed', data); 19 | }); 20 | 21 | Bus.$on('destroyed', function (data) { 22 | _this.$emit('modals:destroyed', data); 23 | }); 24 | 25 | this.$on('new', function (options) { 26 | _this.open(options); 27 | }); 28 | 29 | this.$on('close', function (data) { 30 | _this.close(data); 31 | }); 32 | 33 | this.$on('dismiss', function (index) { 34 | _this.dismiss(index || null); 35 | }); 36 | }, 37 | 38 | 39 | methods: { 40 | open: function open() { 41 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 42 | 43 | Bus.$emit('new', options); 44 | }, 45 | close: function close() { 46 | var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 47 | 48 | Bus.$emit('close', data); 49 | }, 50 | dismiss: function dismiss() { 51 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 52 | 53 | Bus.$emit('dismiss', index); 54 | } 55 | } 56 | }); 57 | 58 | Vue.mixin({ 59 | created: function created() { 60 | this.$on('modals:new', function (options) { 61 | Bus.$emit('new', options); 62 | }); 63 | 64 | this.$on('modals:close', function (data) { 65 | Bus.$emit('close', data); 66 | }); 67 | 68 | this.$on('modals:dismiss', function (index) { 69 | Bus.$emit('dismiss', index); 70 | }); 71 | } 72 | }); 73 | }; 74 | 75 | if (typeof window !== 'undefined' && window.Vue) { 76 | window.Vue.use(VuModal); 77 | } 78 | 79 | export default VuModal; 80 | 81 | export { ModalWrapper, Modal, Bus }; -------------------------------------------------------------------------------- /lib/modal-wrapper.js: -------------------------------------------------------------------------------- 1 | import './style.scss'; 2 | import Bus from './utils/bus'; 3 | import ModalCmp from './modal'; 4 | 5 | export default { 6 | name: 'vu-modal-wrapper', 7 | data: function data() { 8 | return { 9 | modals: [] 10 | }; 11 | }, 12 | mounted: function mounted() { 13 | if (typeof document !== 'undefined') { 14 | document.body.addEventListener('keydown', this.handleTabKey); 15 | } 16 | 17 | if (typeof document !== 'undefined') { 18 | document.body.addEventListener('keyup', this.handleEscapeKey); 19 | } 20 | }, 21 | destroyed: function destroyed() { 22 | if (typeof document !== 'undefined') { 23 | document.body.removeEventListener('keydown', this.handleTabKey); 24 | } 25 | 26 | if (typeof document !== 'undefined') { 27 | document.body.removeEventListener('keyup', this.handleEscapeKey); 28 | } 29 | }, 30 | created: function created() { 31 | var _this = this; 32 | 33 | Bus.$on('new', function (options) { 34 | var defaults = { 35 | title: '', 36 | dismissable: true, 37 | center: false, 38 | fullscreen: false, 39 | isTop: false, 40 | isBottom: false, 41 | isLeft: false, 42 | isRight: false, 43 | isScroll: false, 44 | className: '', 45 | size: 'md', 46 | escapable: false, 47 | bodyPadding: true, 48 | onClose: function onClose() {}, 49 | onDismiss: function onDismiss() {} 50 | }; 51 | 52 | var instance = {}; 53 | var rendered = void 0; 54 | if (options.component.template) { 55 | rendered = false; 56 | } else { 57 | rendered = options.component.render.call(_this, _this.$createElement); 58 | } 59 | 60 | if (rendered && rendered.componentOptions && rendered.componentOptions.Ctor.extendOptions.componentName === 'vu-modal') { 61 | var propsData = rendered.componentOptions.propsData; 62 | instance = { 63 | isVmodal: true, 64 | options: Object.assign(defaults, propsData, options) 65 | }; 66 | } else { 67 | instance = { 68 | isVmodal: false, 69 | options: Object.assign(defaults, options) 70 | }; 71 | } 72 | rendered = null; 73 | 74 | _this.modals.push(instance); 75 | 76 | Bus.$emit('opened', { 77 | index: _this.$last, 78 | instance: instance 79 | }); 80 | 81 | _this.body && _this.body.classList.add('modals-open'); 82 | }); 83 | 84 | Bus.$on('close', function (data) { 85 | var index = null; 86 | 87 | if (data && data.$index) index = data.$index; 88 | 89 | if (index === null) index = _this.$last; 90 | 91 | _this.close(data, index); 92 | }); 93 | 94 | Bus.$on('dismiss', function (index) { 95 | if (index === null) index = _this.$last; 96 | 97 | _this.dismiss(index); 98 | }); 99 | }, 100 | 101 | methods: { 102 | splice: function splice() { 103 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 104 | 105 | if (index === -1) return; 106 | 107 | if (!this.modals.length) return; 108 | 109 | if (index === null) this.modals.pop();else this.modals.splice(index, 1); 110 | 111 | if (!this.modals.length) { 112 | this.body && this.body.classList.remove('modals-open'); 113 | Bus.$emit('destroyed'); 114 | } 115 | }, 116 | doClose: function doClose(index) { 117 | if (!this.modals.length) return; 118 | 119 | if (!this.modals[index]) return; 120 | 121 | this.splice(index); 122 | }, 123 | close: function close() { 124 | var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 125 | var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 126 | 127 | if (this.modals.length === 0) return; 128 | 129 | var localIndex = index; 130 | 131 | if (index && typeof index === 'function') { 132 | localIndex = index(data, this.modals); 133 | } 134 | 135 | if (typeof localIndex !== 'number') localIndex = this.$last; 136 | 137 | Bus.$emit('closed', { 138 | index: localIndex, 139 | instance: this.modals[index], 140 | data: data 141 | }); 142 | 143 | if (localIndex !== false && this.modals[localIndex]) { 144 | if (this.modals[localIndex].options.onClose(data) === false) { 145 | return; 146 | } 147 | } 148 | this.doClose(localIndex); 149 | }, 150 | dismiss: function dismiss() { 151 | var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 152 | 153 | var localIndex = index; 154 | 155 | if (index && typeof index === 'function') localIndex = index(this.$last); 156 | 157 | if (typeof localIndex !== 'number') localIndex = this.$last; 158 | 159 | if (this.modals[localIndex].options.onDismiss() === false) return; 160 | 161 | Bus.$emit('dismissed', { 162 | index: localIndex, 163 | instance: this.modals[localIndex] 164 | }); 165 | 166 | this.doClose(localIndex); 167 | }, 168 | handleTabKey: function handleTabKey(e) { 169 | if (e.keyCode === 9 && this.modals.length) { 170 | e.preventDefault(); 171 | } 172 | }, 173 | handleEscapeKey: function handleEscapeKey(e) { 174 | if (e.keyCode === 27 && this.modals.length) { 175 | if (!this.modals.length) return; 176 | if (this.current.options.escapable) this.dismiss(); 177 | } 178 | } 179 | }, 180 | computed: { 181 | current: function current() { 182 | return this.modals[this.$last]; 183 | }, 184 | $last: function $last() { 185 | return this.modals.length - 1; 186 | }, 187 | body: function body() { 188 | if (typeof document !== 'undefined') { 189 | return document.querySelector('body'); 190 | } 191 | }, 192 | wrapperStyle: function wrapperStyle() { 193 | return { 194 | 'z-index': 5000 + this.$last + 1 195 | }; 196 | } 197 | }, 198 | render: function render(h) { 199 | var _this2 = this; 200 | 201 | if (!this.modals.length) { 202 | return null; 203 | }; 204 | 205 | var modals = this.modals.map(function (modal, index) { 206 | var modalComponent = void 0; 207 | 208 | if (modal.isVmodal) { 209 | modalComponent = h(modal.options.component, { 210 | props: Object.assign({}, { vModal: Object.assign(modal.options, { disabled: index != _this2.$last }) }, modal.options.props) 211 | }); 212 | } else { 213 | modalComponent = h(ModalCmp, { 214 | props: Object.assign(modal.options, { disabled: index != _this2.$last }) 215 | }, [h(modal.options.component, { 216 | props: modal.options.props 217 | })]); 218 | } 219 | return h('div', { 220 | class: ['vu-modal__mask', { 'vu-modal__mask--disabled': index != _this2.$last }], 221 | on: { click: function click() { 222 | modal.options.dismissable && _this2.dismiss(); 223 | } }, 224 | key: index 225 | }, [modalComponent]); 226 | }); 227 | 228 | return h('div', { 229 | class: 'vu-modal__wrapper' 230 | }, [modals]); 231 | } 232 | }; -------------------------------------------------------------------------------- /lib/modal.js: -------------------------------------------------------------------------------- 1 | import CloseIcon from './close-icon'; 2 | export default { 3 | name: 'vu-modal', 4 | componentName: 'vu-modal', 5 | props: { 6 | title: { 7 | type: String, 8 | default: '' 9 | }, 10 | className: { 11 | type: String, 12 | default: '' 13 | }, 14 | isScroll: { 15 | type: Boolean, 16 | default: false 17 | }, 18 | escapable: { 19 | type: Boolean, 20 | default: false 21 | }, 22 | dismissable: { 23 | type: Boolean, 24 | default: true 25 | }, 26 | fullscreen: { 27 | type: Boolean, 28 | default: false 29 | }, 30 | isTop: { 31 | type: Boolean, 32 | default: false 33 | }, 34 | isBottom: { 35 | type: Boolean, 36 | default: false 37 | }, 38 | isLeft: { 39 | type: Boolean, 40 | default: false 41 | }, 42 | isRight: { 43 | type: Boolean, 44 | default: false 45 | }, 46 | center: { 47 | type: Boolean, 48 | default: false 49 | }, 50 | size: { 51 | type: String, 52 | default: 'md' 53 | }, 54 | bodyPadding: { 55 | type: Boolean, 56 | default: true 57 | } 58 | }, 59 | mounted: function mounted() { 60 | if (this.$el.focus) { 61 | this.$el.focus(); 62 | } 63 | }, 64 | 65 | computed: { 66 | propsData: function propsData() { 67 | return this.$parent.$vnode.data.props && this.$parent.$vnode.data.props.vModal ? this.$parent.$vnode.data.props.vModal : this.$props; 68 | } 69 | }, 70 | render: function render(h) { 71 | var _this = this; 72 | 73 | var _propsData = this.propsData, 74 | dismissable = _propsData.dismissable, 75 | title = _propsData.title, 76 | isScroll = _propsData.isScroll, 77 | fullscreen = _propsData.fullscreen, 78 | isTop = _propsData.isTop, 79 | isBottom = _propsData.isBottom, 80 | isLeft = _propsData.isLeft, 81 | isRight = _propsData.isRight, 82 | center = _propsData.center, 83 | size = _propsData.size, 84 | className = _propsData.className, 85 | bodyPadding = _propsData.bodyPadding; 86 | 87 | 88 | var closeBtn = dismissable ? h('div', { 89 | class: 'vu-modal__close-btn', 90 | on: { 91 | click: function click() { 92 | _this.$modals.dismiss(); 93 | } 94 | } 95 | }, [h(CloseIcon)]) : null; 96 | 97 | var headerContent = this.$slots.header ? this.$slots.header : title ? h('span', { class: ['vu-modal__cmp-header-title'] }, title) : null; 98 | 99 | var header = headerContent ? h('div', { 100 | class: ['vu-modal__cmp-header'] 101 | }, [headerContent]) : null; 102 | 103 | var body = h('div', { 104 | class: ['vu-modal__cmp-body'], 105 | style: { 106 | overflowY: isScroll ? 'auto' : null, 107 | padding: bodyPadding ? '1em' : 0 108 | } 109 | }, [this.$slots.default]); 110 | 111 | var footer = this.$slots.footer ? h('div', { 112 | class: ['vu-modal__cmp-footer'] 113 | }, [this.$slots.footer]) : null; 114 | 115 | var style = {}; 116 | var translateX = '-50%'; 117 | var translateY = '0'; 118 | if (center) { 119 | translateX = '-50%'; 120 | translateY = '-50%'; 121 | } 122 | if (isRight || isLeft) { 123 | translateX = '0%'; 124 | } 125 | 126 | if ((isTop || isBottom) && !isScroll && !center) { 127 | translateY = '0%'; 128 | } 129 | style.transform = 'translate(' + translateX + ', ' + translateY + ')'; 130 | 131 | return h('div', { 132 | style: style, 133 | attrs: { tabindex: -1 }, 134 | class: ['vu-modal__cmp', { 135 | 'vu-modal__cmp--is-fullscreen': fullscreen, 136 | 'vu-modal__cmp--is-center': center, 137 | 'vu-modal__cmp--is-top': isTop && !isScroll && !center, 138 | 'vu-modal__cmp--is-bottom': isBottom && !isScroll && !center, 139 | 'vu-modal__cmp--is-left': isLeft, 140 | 'vu-modal__cmp--is-right': isRight 141 | }, isScroll && fullscreen && 'vu-modal__cmp--is-scroll-fullscreen', isScroll && !fullscreen && 'vu-modal__cmp--is-scroll', !fullscreen && 'vu-modal__cmp--' + size, className], 142 | on: { click: function click(event) { 143 | event.stopPropagation(); 144 | } } 145 | }, [closeBtn, header, body, footer]); 146 | } 147 | }; -------------------------------------------------------------------------------- /lib/utils/bus.js: -------------------------------------------------------------------------------- 1 | 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; }; }(); 2 | 3 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 4 | 5 | var instance = null; 6 | 7 | var EventBus = function () { 8 | function EventBus() { 9 | _classCallCheck(this, EventBus); 10 | 11 | if (!instance) { 12 | this.events = {}; 13 | instance = this; 14 | } 15 | return instance; 16 | } 17 | 18 | _createClass(EventBus, [{ 19 | key: "$emit", 20 | value: function $emit(event, message) { 21 | if (!this.events[event]) return; 22 | var callbacks = this.events[event]; 23 | for (var i = 0, l = callbacks.length; i < l; i++) { 24 | var callback = callbacks[i]; 25 | callback.call(this, message); 26 | } 27 | } 28 | }, { 29 | key: "$on", 30 | value: function $on(event, callback) { 31 | if (!this.events[event]) this.events[event] = []; 32 | this.events[event].push(callback); 33 | } 34 | }]); 35 | 36 | return EventBus; 37 | }(); 38 | 39 | export default new EventBus(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-universal-modal", 3 | "version": "1.0.0", 4 | "description": "A Vue.js universal modal component", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "jsnext:main": "es/index.js", 8 | "unpkg": "dist/vue-universal-modal.min.js", 9 | "author": "Andrey vuNemesis ", 10 | "scripts": { 11 | "dev": "node build/dev-server.js", 12 | "clean": "rimraf lib dist es", 13 | "build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min && npm run build:es", 14 | "build:demo": "node build/build.js", 15 | "test": "echo \"Error: no test specified\" && exit 1", 16 | "init": "curl -u 'vuNemesis' https://api.github.com/user/repos -d '{\"name\":\"vue-universal-modal\"}'", 17 | "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib", 18 | "build:commonjs:watch": "npm run build:commonjs -- --watch", 19 | "build:es": "cross-env BABEL_ENV=es babel src --out-dir es", 20 | "build:es:watch": "npm run build:es -- --watch", 21 | "build:umd": "cross-env BABEL_ENV=es NODE_ENV=development node_modules/.bin/rollup src/index.js --config --sourcemap --output dist/vue-universal-modal.js", 22 | "build:umd:watch": "npm run build:umd -- --watch", 23 | "build:umd:min": "cross-env BABEL_ENV=es NODE_ENV=production rollup src/index.js --config --output dist/vue-universal-modal.min.js" 24 | }, 25 | "devDependencies": { 26 | "autoprefixer": "^6.7.2", 27 | "babel-cli": "^6.14.0", 28 | "babel-core": "^6.22.1", 29 | "babel-loader": "^6.2.10", 30 | "babel-plugin-external-helpers": "^6.22.0", 31 | "babel-plugin-syntax-dynamic-import": "^6.18.0", 32 | "babel-plugin-transform-relative-paths": "^0.1.0", 33 | "babel-plugin-transform-runtime": "^6.22.0", 34 | "babel-polyfill": "^6.13.0", 35 | "babel-preset-env": "^1.6.1", 36 | "babel-preset-es2015": "^6.22.0", 37 | "babel-preset-es2015-rollup": "^1.2.0", 38 | "babel-preset-stage-2": "^6.22.0", 39 | "babel-register": "^6.22.0", 40 | "babel-standalone": "^6.26.0", 41 | "chalk": "^1.1.3", 42 | "connect-history-api-fallback": "^1.3.0", 43 | "copy-webpack-plugin": "^4.0.1", 44 | "cross-env": "^5.1.3", 45 | "css-loader": "^0.28.0", 46 | "eventsource-polyfill": "^0.9.6", 47 | "express": "^4.14.1", 48 | "extract-text-webpack-plugin": "^2.0.0", 49 | "file-loader": "^0.11.1", 50 | "friendly-errors-webpack-plugin": "^1.1.3", 51 | "fs-extended": "^0.2.1", 52 | "html-webpack-plugin": "^2.28.0", 53 | "http-proxy-middleware": "^0.17.3", 54 | "js-beautify": "^1.7.5", 55 | "node-sass": "^4.7.2", 56 | "opn": "^4.0.2", 57 | "optimize-css-assets-webpack-plugin": "^1.3.0", 58 | "ora": "^1.2.0", 59 | "raw-loader": "^0.5.1", 60 | "resolve-url-loader": "^2.2.1", 61 | "rimraf": "^2.6.0", 62 | "rollup": "^0.35.15", 63 | "rollup-plugin-babel": "^2.6.1", 64 | "rollup-plugin-collect-sass": "^1.0.9", 65 | "rollup-plugin-commonjs": "^8.3.0", 66 | "rollup-plugin-node-resolve": "^3.0.3", 67 | "rollup-plugin-postcss": "^1.2.8", 68 | "rollup-plugin-replace": "^2.0.0", 69 | "rollup-plugin-scss": "^0.4.0", 70 | "rollup-plugin-uglify": "^1.0.1", 71 | "rollup-watch": "^4.3.1", 72 | "sass-loader": "^6.0.6", 73 | "semver": "^5.3.0", 74 | "shelljs": "^0.7.6", 75 | "uglify-js": "git://github.com/mishoo/UglifyJS2#harmony", 76 | "uikit": "^3.0.0-beta.40", 77 | "url-loader": "^0.5.8", 78 | "vue": "^2.3.3", 79 | "vue-functional-data-merge": "^2.0.4", 80 | "vue-highlightjs": "^1.3.3", 81 | "vue-loader": "^12.1.0", 82 | "vue-router": "^2.3.1", 83 | "vue-style-loader": "^3.0.1", 84 | "vue-template-compiler": "^2.3.3", 85 | "webpack": "^2.6.1", 86 | "webpack-bundle-analyzer": "^2.2.1", 87 | "webpack-dev-middleware": "^1.10.0", 88 | "webpack-hot-middleware": "^2.18.0", 89 | "webpack-merge": "^4.1.0" 90 | }, 91 | "files": [ 92 | "dist", 93 | "lib", 94 | "es", 95 | "src" 96 | ], 97 | "repository": { 98 | "type": "git", 99 | "url": "git://github.com/vuNemesis/vue-universal-modal.git" 100 | }, 101 | "bugs": { 102 | "url": "https://github.com/vuNemesis/vue-universal-modal/issues" 103 | }, 104 | "engines": { 105 | "node": ">= 4.0.0", 106 | "npm": ">= 3.0.0" 107 | }, 108 | "homepage": "https://github.com/vuNemesis/vue-universal-modal", 109 | "keywords": [ 110 | "vue", 111 | "vue.js", 112 | "modal", 113 | "component" 114 | ], 115 | "license": "MIT" 116 | } 117 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve'; 2 | import commonjs from 'rollup-plugin-commonjs'; 3 | import babel from 'rollup-plugin-babel'; 4 | import uglify from 'rollup-plugin-uglify'; 5 | import replace from 'rollup-plugin-replace'; 6 | import scss from 'rollup-plugin-scss'; 7 | import postcss from 'rollup-plugin-postcss'; 8 | import autoprefixer from 'autoprefixer'; 9 | // import pkg from './package.json'; 10 | 11 | var env = process.env.NODE_ENV 12 | var config = { 13 | exports: 'named', 14 | format: 'umd', 15 | moduleName: 'VueUniversalModal', 16 | plugins: [ 17 | // scss({ 18 | // output: 'dist/vue-universal-slider.css' 19 | // }), 20 | postcss({ 21 | extract: env === 'production' ? 'dist/vue-universal-modal.min.css' : 'dist/vue-universal-modal.css', 22 | plugins: [autoprefixer], 23 | minimize: env === 'production' ? true : false 24 | }), 25 | resolve({ 26 | jsnext: true, 27 | main: true, 28 | browser: true, 29 | }), 30 | // due to https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module 31 | commonjs(), 32 | // commonjs({ 33 | // include: 'node_modules/**', 34 | // namedExports: { './node_module/invariant.js': ['default'] } 35 | // }), 36 | babel({ 37 | exclude: 'node_modules/**' 38 | }), 39 | replace({ 40 | 'process.env.NODE_ENV': JSON.stringify(env) 41 | }) 42 | ] 43 | } 44 | 45 | if (env === 'production') { 46 | config.plugins.push( 47 | uglify({ 48 | compress: { 49 | pure_getters: true, 50 | unsafe: true, 51 | unsafe_comps: true, 52 | warnings: false 53 | } 54 | }) 55 | ) 56 | } 57 | 58 | export default config 59 | 60 | // export default [ 61 | // // browser-friendly UMD build 62 | // { 63 | // input: 'src/index.js', 64 | // output: { 65 | // name: 'VueUniversalSlider', 66 | // file: "dist/vue-universal-slider.umd.js", 67 | // format: 'umd' 68 | // }, 69 | // plugins: [ 70 | // resolve({ 71 | // jsnext: true, 72 | // main: true, 73 | // browser: true, 74 | // }), 75 | // commonjs(), 76 | // babel({ 77 | // exclude: ['node_modules/**'] 78 | // }), 79 | // (process.env.NODE_ENV === 'production' && uglify()), 80 | // ] 81 | // }, 82 | 83 | // // CommonJS (for Node) and ES module (for bundlers) build. 84 | // // (We could have three entries in the configuration array 85 | // // instead of two, but it's quicker to generate multiple 86 | // // builds from a single configuration where possible, using 87 | // // an array for the `output` option, where we can specify 88 | // // `file` and `format` for each target) 89 | // { 90 | // input: 'src/index.js', 91 | // // external: ['ms'], 92 | // output: [ 93 | // { file: "dist/vue-universal-slider.cjs.js", format: 'cjs' }, 94 | // { file: "dist/vue-universal-slider.esm.js", format: 'es' } 95 | // ], 96 | // plugins: [ 97 | // babel({ 98 | // exclude: ['node_modules/**'] 99 | // }), 100 | // (process.env.NODE_ENV === 'production' && uglify()), 101 | // ] 102 | // } 103 | // ]; -------------------------------------------------------------------------------- /src/close-icon.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'close-icon', 3 | functional: true, 4 | render(h) { 5 | return h('svg', { 6 | attrs: { 7 | width: '12px', 8 | height: '12px', 9 | viewBox: '0 0 12 12', 10 | xmlSpace: 'preserve' 11 | } 12 | }, [ 13 | h('line', { 14 | attrs: { 15 | x1: 1, 16 | y1: 11, 17 | x2: 11, 18 | y2: 1 19 | }, 20 | style: { 21 | strokeLinecap: 'round', 22 | strokeLinejoin: 'round', 23 | } 24 | }), 25 | h('line', { 26 | attrs: { 27 | x1: 1, 28 | y1: 1, 29 | x2: 11, 30 | y2: 11 31 | }, 32 | style: { 33 | strokeLinecap: 'round', 34 | strokeLinejoin: 'round', 35 | } 36 | }) 37 | ]) 38 | } 39 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Bus from './utils/bus'; 2 | import ModalWrapper from './modal-wrapper'; 3 | import Modal from './modal' 4 | 5 | const VuModal = {} 6 | VuModal.install = (Vue) => { 7 | Vue.prototype.$modals = new Vue({ 8 | name: '$modals', 9 | 10 | created() { 11 | Bus.$on('opened', data => { 12 | this.$emit('modals:opened', data); 13 | }); 14 | 15 | Bus.$on('closed', data => { 16 | this.$emit('modals:closed', data); 17 | }); 18 | 19 | Bus.$on('destroyed', data => { 20 | this.$emit('modals:destroyed', data); 21 | }); 22 | 23 | this.$on('new', options => { 24 | this.open(options); 25 | }); 26 | 27 | this.$on('close', data => { 28 | this.close(data); 29 | }); 30 | 31 | this.$on('dismiss', index => { 32 | this.dismiss(index || null); 33 | }); 34 | }, 35 | 36 | methods: { 37 | open(options = null) { 38 | Bus.$emit('new', options); 39 | }, 40 | 41 | close(data = null) { 42 | Bus.$emit('close', data); 43 | }, 44 | 45 | dismiss(index = null) { 46 | Bus.$emit('dismiss', index); 47 | } 48 | } 49 | }); 50 | 51 | Vue.mixin({ 52 | created() { 53 | this.$on('modals:new', options => { 54 | Bus.$emit('new', options); 55 | }); 56 | 57 | this.$on('modals:close', data => { 58 | Bus.$emit('close', data); 59 | }); 60 | 61 | this.$on('modals:dismiss', index => { 62 | Bus.$emit('dismiss', index); 63 | }); 64 | } 65 | }); 66 | } 67 | 68 | if (typeof window !== 'undefined' && window.Vue) { 69 | window.Vue.use(VuModal); 70 | } 71 | 72 | export default VuModal; 73 | 74 | export { 75 | ModalWrapper, 76 | Modal, 77 | Bus 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/modal-wrapper.js: -------------------------------------------------------------------------------- 1 | import './style.scss' 2 | import Bus from './utils/bus' 3 | import ModalCmp from './modal' 4 | 5 | export default { 6 | name: 'vu-modal-wrapper', 7 | data () { 8 | return { 9 | modals: [] 10 | } 11 | }, 12 | mounted() { 13 | if (typeof document !== 'undefined') { 14 | document.body.addEventListener('keydown', this.handleTabKey) 15 | } 16 | 17 | if (typeof document !== 'undefined') { 18 | document.body.addEventListener('keyup', this.handleEscapeKey) 19 | } 20 | }, 21 | destroyed() { 22 | if (typeof document !== 'undefined') { 23 | document.body.removeEventListener('keydown', this.handleTabKey) 24 | } 25 | 26 | if (typeof document !== 'undefined') { 27 | document.body.removeEventListener('keyup', this.handleEscapeKey) 28 | } 29 | }, 30 | created() { 31 | Bus.$on('new', options => { 32 | const defaults = { 33 | title: '', 34 | dismissable: true, 35 | center: false, 36 | fullscreen: false, 37 | isTop: false, 38 | isBottom: false, 39 | isLeft: false, 40 | isRight: false, 41 | isScroll: false, 42 | className: '', 43 | size: 'md', 44 | escapable: false, 45 | bodyPadding: true, 46 | onClose() {}, 47 | onDismiss() {} 48 | }; 49 | 50 | let instance = {} 51 | let rendered 52 | if(options.component.template) { 53 | rendered = false 54 | } else { 55 | rendered = options.component.render.call(this, this.$createElement) 56 | } 57 | 58 | if(rendered && rendered.componentOptions && rendered.componentOptions.Ctor.extendOptions.componentName === 'vu-modal') { 59 | const propsData = rendered.componentOptions.propsData 60 | instance = { 61 | isVmodal: true, 62 | options: Object.assign(defaults, propsData, options) 63 | } 64 | } else { 65 | instance = { 66 | isVmodal: false, 67 | options: Object.assign(defaults, options) 68 | } 69 | } 70 | rendered = null 71 | 72 | this.modals.push(instance); 73 | 74 | Bus.$emit('opened', { 75 | index: this.$last, 76 | instance 77 | }); 78 | 79 | this.body && this.body.classList.add('modals-open'); 80 | }); 81 | 82 | Bus.$on('close', data => { 83 | let index = null; 84 | 85 | if (data && data.$index) 86 | index = data.$index; 87 | 88 | if (index === null) 89 | index = this.$last; 90 | 91 | this.close(data, index); 92 | }); 93 | 94 | Bus.$on('dismiss', index => { 95 | if (index === null) 96 | index = this.$last; 97 | 98 | this.dismiss(index); 99 | }); 100 | }, 101 | methods: { 102 | splice(index = null) { 103 | if (index === -1) 104 | return; 105 | 106 | if (!this.modals.length) 107 | return; 108 | 109 | if (index === null) 110 | this.modals.pop(); 111 | else 112 | this.modals.splice(index, 1); 113 | 114 | if (!this.modals.length) { 115 | this.body && this.body.classList.remove('modals-open'); 116 | Bus.$emit('destroyed'); 117 | } 118 | }, 119 | 120 | doClose(index) { 121 | if (!this.modals.length) 122 | return; 123 | 124 | if (!this.modals[index]) 125 | return; 126 | 127 | this.splice(index); 128 | }, 129 | 130 | close(data = null, index = null) { 131 | if (this.modals.length === 0) 132 | return; 133 | 134 | let localIndex = index; 135 | 136 | if (index && typeof index === 'function') { 137 | localIndex = index(data, this.modals); 138 | } 139 | 140 | if (typeof localIndex !== 'number') 141 | localIndex = this.$last; 142 | 143 | Bus.$emit('closed', { 144 | index: localIndex, 145 | instance: this.modals[index], 146 | data 147 | }); 148 | 149 | if (localIndex !== false && this.modals[localIndex]) { 150 | if(this.modals[localIndex].options.onClose(data) === false) { 151 | return 152 | } 153 | } 154 | this.doClose(localIndex); 155 | }, 156 | 157 | dismiss(index = null) { 158 | let localIndex = index; 159 | 160 | if (index && typeof index === 'function') 161 | localIndex = index(this.$last); 162 | 163 | if (typeof localIndex !== 'number') 164 | localIndex = this.$last; 165 | 166 | if (this.modals[localIndex].options.onDismiss() === false) 167 | return; 168 | 169 | Bus.$emit('dismissed', { 170 | index: localIndex, 171 | instance: this.modals[localIndex] 172 | }); 173 | 174 | this.doClose(localIndex); 175 | }, 176 | 177 | handleTabKey(e) { 178 | if (e.keyCode === 9 && this.modals.length) { 179 | e.preventDefault() 180 | } 181 | }, 182 | 183 | handleEscapeKey(e) { 184 | if (e.keyCode === 27 && this.modals.length) { 185 | if (!this.modals.length) 186 | return; 187 | if (this.current.options.escapable) 188 | this.dismiss(); 189 | } 190 | } 191 | }, 192 | computed: { 193 | current() { 194 | return this.modals[this.$last]; 195 | }, 196 | $last() { 197 | return this.modals.length - 1; 198 | }, 199 | body() { 200 | if (typeof document !== 'undefined') { 201 | return document.querySelector('body'); 202 | } 203 | }, 204 | wrapperStyle() { 205 | return { 206 | 'z-index': 5000 + this.$last + 1 207 | } 208 | } 209 | }, 210 | render(h) { 211 | if(!this.modals.length) { 212 | return null 213 | }; 214 | 215 | let modals = this.modals.map((modal, index) => { 216 | let modalComponent 217 | 218 | if(modal.isVmodal) { 219 | modalComponent = h(modal.options.component, { 220 | props: Object.assign({}, {vModal: Object.assign(modal.options, { disabled: index != this.$last })}, modal.options.props) 221 | }) 222 | } else { 223 | modalComponent = h(ModalCmp, { 224 | props: Object.assign(modal.options, { disabled: index != this.$last }) 225 | }, [ 226 | h(modal.options.component, { 227 | props: modal.options.props 228 | }) 229 | ]) 230 | } 231 | return h('div', { 232 | class: ['vu-modal__mask', {'vu-modal__mask--disabled': index != this.$last }], 233 | on: {click: () => {modal.options.dismissable && this.dismiss()}}, 234 | key: index 235 | }, [ 236 | modalComponent 237 | ]) 238 | }) 239 | 240 | return h('div', { 241 | class: 'vu-modal__wrapper', 242 | }, [ modals ]) 243 | } 244 | }; 245 | 246 | 247 | -------------------------------------------------------------------------------- /src/modal.js: -------------------------------------------------------------------------------- 1 | import CloseIcon from './close-icon' 2 | export default { 3 | name: 'vu-modal', 4 | componentName: 'vu-modal', 5 | props: { 6 | title: { 7 | type: String, 8 | default: '' 9 | }, 10 | className: { 11 | type: String, 12 | default: '' 13 | }, 14 | isScroll: { 15 | type: Boolean, 16 | default: false 17 | }, 18 | escapable: { 19 | type: Boolean, 20 | default: false 21 | }, 22 | dismissable: { 23 | type: Boolean, 24 | default: true 25 | }, 26 | fullscreen: { 27 | type: Boolean, 28 | default: false 29 | }, 30 | isTop: { 31 | type: Boolean, 32 | default: false 33 | }, 34 | isBottom: { 35 | type: Boolean, 36 | default: false 37 | }, 38 | isLeft: { 39 | type: Boolean, 40 | default: false 41 | }, 42 | isRight: { 43 | type: Boolean, 44 | default: false 45 | }, 46 | center: { 47 | type: Boolean, 48 | default: false 49 | }, 50 | size: { 51 | type: String, 52 | default: 'md' 53 | }, 54 | bodyPadding: { 55 | type: Boolean, 56 | default: true 57 | } 58 | }, 59 | mounted() { 60 | if(this.$el.focus) { 61 | this.$el.focus() 62 | } 63 | }, 64 | computed: { 65 | propsData() { 66 | return (this.$parent.$vnode.data.props && this.$parent.$vnode.data.props.vModal) ? this.$parent.$vnode.data.props.vModal : this.$props 67 | } 68 | }, 69 | render(h) { 70 | const { dismissable, title, isScroll, fullscreen, isTop, isBottom, isLeft, isRight, center, size, className, bodyPadding } = this.propsData 71 | 72 | const closeBtn = dismissable 73 | ? h('div', { 74 | class: 'vu-modal__close-btn', 75 | on: { 76 | click: () => {this.$modals.dismiss()} 77 | } 78 | }, [h(CloseIcon)]) 79 | : null 80 | 81 | const headerContent = this.$slots.header 82 | ? this.$slots.header 83 | : title 84 | ? h('span', {class: ['vu-modal__cmp-header-title']}, title) 85 | : null 86 | 87 | const header = headerContent 88 | ? h('div', { 89 | class: ['vu-modal__cmp-header'] 90 | }, [ headerContent ]) 91 | : null 92 | 93 | const body = h('div', { 94 | class: ['vu-modal__cmp-body'], 95 | style: { 96 | overflowY: isScroll ? 'auto' : null, 97 | padding: bodyPadding ? '1em' : 0 98 | } 99 | }, [ this.$slots.default ]) 100 | 101 | const footer = this.$slots.footer 102 | ? h('div', { 103 | class: ['vu-modal__cmp-footer'] 104 | }, [ this.$slots.footer ]) 105 | : null 106 | 107 | let style = {} 108 | let translateX = '-50%' 109 | let translateY = '0' 110 | if(center) { 111 | translateX = '-50%' 112 | translateY = '-50%' 113 | } 114 | if(isRight || isLeft) { 115 | translateX = '0%' 116 | } 117 | 118 | if((isTop || isBottom) && !isScroll && !center) { 119 | translateY = '0%' 120 | } 121 | style.transform = `translate(${translateX}, ${translateY})` 122 | 123 | return h('div', { 124 | style, 125 | attrs: { tabindex: -1}, 126 | class: ['vu-modal__cmp', { 127 | 'vu-modal__cmp--is-fullscreen': fullscreen, 128 | 'vu-modal__cmp--is-center': center, 129 | 'vu-modal__cmp--is-top': isTop && !isScroll && !center, 130 | 'vu-modal__cmp--is-bottom': isBottom && !isScroll && !center, 131 | 'vu-modal__cmp--is-left': isLeft, 132 | 'vu-modal__cmp--is-right': isRight 133 | }, 134 | isScroll && fullscreen && 'vu-modal__cmp--is-scroll-fullscreen', 135 | isScroll && !fullscreen && 'vu-modal__cmp--is-scroll', 136 | !fullscreen && `vu-modal__cmp--${size}`, 137 | className 138 | ], 139 | on: {click: (event) => {event.stopPropagation()}} 140 | }, [ 141 | closeBtn, 142 | header, 143 | body, 144 | footer 145 | ]) 146 | } 147 | }; 148 | -------------------------------------------------------------------------------- /src/style.scss: -------------------------------------------------------------------------------- 1 | body.modals-open { 2 | overflow: hidden; 3 | } 4 | 5 | .vu-modal { 6 | &__wrapper { 7 | position: fixed; 8 | top: 0; 9 | left: 0; 10 | right: 0; 11 | bottom: 0; 12 | z-index: 5000; 13 | overflow-x: hidden; 14 | overflow-y: auto; 15 | transition: opacity .4s ease; 16 | } 17 | 18 | &__mask { 19 | background-color: rgba(0, 0, 0, .5); 20 | position: absolute; 21 | width: 100%; 22 | height: 100%; 23 | overflow-y: scroll; 24 | &--disabled { 25 | background-color: rgba(0, 0, 0, 0); 26 | } 27 | } 28 | 29 | &__cmp { 30 | display: flex; 31 | flex-direction: column; 32 | border-radius: 0px; 33 | background: #FFF; 34 | box-shadow: 3px 5px 20px #333; 35 | margin: 30px auto; 36 | position: absolute; 37 | left: 50%; 38 | transform: translateX(-50%); 39 | width: 650px; 40 | 41 | // &--disabled { 42 | // opacity: 0.2; 43 | 44 | // &::after { 45 | // background: transparent; 46 | // content: ''; 47 | // position: absolute; 48 | // top: 0; 49 | // left: 0; 50 | // right: 0; 51 | // bottom: 0; 52 | // z-index: 100; 53 | // } 54 | // } 55 | 56 | &--is-center { 57 | margin: auto; 58 | top: 50%; 59 | } 60 | &--is-scroll { 61 | max-height: 90%; 62 | } 63 | 64 | &--is-scroll-fullscreen { 65 | max-height: 100%; 66 | } 67 | 68 | &--is-fullscreen { 69 | width: 100%; 70 | min-height: 100%; 71 | margin: 0 0; 72 | } 73 | 74 | &--is-bottom { 75 | bottom: 0; 76 | } 77 | 78 | &--is-top { 79 | top: 0; 80 | } 81 | 82 | &--is-right { 83 | right: 0; 84 | margin-right: 30px; 85 | } 86 | 87 | &--is-left { 88 | left: 0; 89 | margin-left: 30px; 90 | } 91 | 92 | &--xl { 93 | width: 1024px; 94 | } 95 | 96 | &--lg { 97 | width: 850px; 98 | } 99 | 100 | &--md { 101 | width: 650px; 102 | } 103 | 104 | &--sm { 105 | width: 550px; 106 | } 107 | 108 | &--xs { 109 | width: 350px; 110 | } 111 | 112 | &--p50 { 113 | width: 50%; 114 | } 115 | 116 | &--p70 { 117 | width: 70%; 118 | } 119 | 120 | &--p90 { 121 | width: 90%; 122 | } 123 | 124 | &-body { 125 | padding: 1em; 126 | &::-webkit-scrollbar { 127 | width: 6px; 128 | } 129 | 130 | &::-webkit-scrollbar-track { 131 | -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 132 | } 133 | 134 | &::-webkit-scrollbar-thumb { 135 | background-color: darkgrey; 136 | outline: 1px solid slategrey; 137 | } 138 | } 139 | 140 | &-header { 141 | user-select: none; 142 | border-bottom: 1px solid #EEE; 143 | padding: 1em; 144 | text-align: left; 145 | &-title { 146 | font-size: 16px; 147 | font-weight: 800; 148 | } 149 | } 150 | 151 | &-footer { 152 | border-top: solid 1px #EEE; 153 | user-select: none; 154 | padding: 1em; 155 | text-align: right; 156 | } 157 | } 158 | 159 | &__close-btn { 160 | user-select: none; 161 | position: absolute; 162 | right: 12px; 163 | top: 5px; 164 | line { 165 | stroke: grey; 166 | stroke-width: 2; 167 | } 168 | &:hover { 169 | cursor: pointer; 170 | line { 171 | stroke: black; 172 | } 173 | } 174 | } 175 | } 176 | 177 | // .vuModal-enter, 178 | // .vuModal-leave-active { 179 | // opacity: 0; 180 | // } 181 | 182 | // .vuModal-enter .vu-modal__cmp, 183 | // .vuModal-leave-active .vu-modal__cmp { 184 | // opacity: 0; 185 | // transform: translateX(-50%) translateY(-30px) scale(0.95); 186 | // } 187 | 188 | // .vuModal-enter-active, .vuModal-leave-active { 189 | // transition: all 1s; 190 | // } 191 | // .vuModal-enter, .vuModal-leave-to /* .list-leave-active до версии 2.1.8 */ { 192 | // opacity: 0; 193 | // } -------------------------------------------------------------------------------- /src/utils/bus.js: -------------------------------------------------------------------------------- 1 | let instance = null; 2 | 3 | class EventBus { 4 | constructor() { 5 | if (!instance) { 6 | this.events = {}; 7 | instance = this; 8 | } 9 | return instance; 10 | } 11 | 12 | $emit(event, message) { 13 | if (!this.events[event]) 14 | return; 15 | const callbacks = this.events[event]; 16 | for (let i = 0, l = callbacks.length; i < l; i++) { 17 | const callback = callbacks[i]; 18 | callback.call(this, message); 19 | } 20 | } 21 | 22 | $on(event, callback) { 23 | if (!this.events[event]) 24 | this.events[event] = []; 25 | this.events[event].push(callback); 26 | } 27 | } 28 | 29 | export default new EventBus(); --------------------------------------------------------------------------------