--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Modal from './Modal.vue';
2 | import VoerroModal from './interface';
3 |
4 | if (document.querySelector('#voerro-vue-modal-demo-vqk6etkfjrcpsjg5')) {
5 | window.Modal = Modal;
6 | window.VoerroModal = VoerroModal;
7 | }
8 |
9 | export { Modal, VoerroModal };
--------------------------------------------------------------------------------
/src/interface.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 |
3 | window.VoerroModalEvent = new Vue();
4 |
5 | class VoerroModal {
6 | constructor () {}
7 |
8 | static show(optionsOrId, options) {
9 | window.VoerroModalEvent.$emit('show', optionsOrId, options);
10 | }
11 |
12 | static hide (id = null) {
13 | window.VoerroModalEvent.$emit('hide', id);
14 | }
15 | }
16 |
17 | export default VoerroModal;
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Alexander Zavyalov
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.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@voerro/vue-modal",
3 | "description": "A flexible & responsive modal component for Vue.js 2",
4 | "version": "1.4.0",
5 | "author": "Alexander Zavyalov (http://voerro.com)",
6 | "license": "MIT",
7 | "main": "src/main.js",
8 | "keywords": [
9 | "vue",
10 | "vuejs",
11 | "modal",
12 | "component",
13 | "plugin",
14 | "responsive",
15 | "flexible"
16 | ],
17 | "scripts": {
18 | "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
19 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
20 | },
21 | "dependencies": {
22 | "vue": "^2.5.0"
23 | },
24 | "browserslist": [
25 | "> 1%",
26 | "last 2 versions",
27 | "not ie <= 8"
28 | ],
29 | "devDependencies": {
30 | "babel-core": "^6.26.0",
31 | "babel-loader": "^7.1.2",
32 | "babel-preset-env": "^1.6.0",
33 | "babel-preset-stage-3": "^6.24.1",
34 | "cross-env": "^5.0.5",
35 | "css-loader": "^0.28.7",
36 | "file-loader": "^1.1.4",
37 | "node-sass": "^4.5.3",
38 | "sass-loader": "^6.0.6",
39 | "vue-loader": "^13.0.5",
40 | "vue-template-compiler": "^2.4.4",
41 | "webpack": "^3.6.0",
42 | "webpack-dev-server": "^2.9.1"
43 | },
44 | "repository": "https://github.com/voerro/vue-modal"
45 | }
46 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry: './src/main.js',
6 | output: {
7 | path: path.resolve(__dirname, './dist'),
8 | publicPath: '/dist/',
9 | filename: 'build.js'
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.css$/,
15 | use: [
16 | 'vue-style-loader',
17 | 'css-loader'
18 | ],
19 | },
20 | {
21 | test: /\.scss$/,
22 | use: [
23 | 'vue-style-loader',
24 | 'css-loader',
25 | 'sass-loader'
26 | ],
27 | },
28 | {
29 | test: /\.sass$/,
30 | use: [
31 | 'vue-style-loader',
32 | 'css-loader',
33 | 'sass-loader?indentedSyntax'
34 | ],
35 | },
36 | {
37 | test: /\.vue$/,
38 | loader: 'vue-loader',
39 | options: {
40 | loaders: {
41 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
42 | // the "scss" and "sass" values for the lang attribute to the right configs here.
43 | // other preprocessors should work out of the box, no loader config like this necessary.
44 | 'scss': [
45 | 'vue-style-loader',
46 | 'css-loader',
47 | 'sass-loader'
48 | ],
49 | 'sass': [
50 | 'vue-style-loader',
51 | 'css-loader',
52 | 'sass-loader?indentedSyntax'
53 | ]
54 | }
55 | // other vue-loader options go here
56 | }
57 | },
58 | {
59 | test: /\.js$/,
60 | loader: 'babel-loader',
61 | exclude: /node_modules/
62 | },
63 | {
64 | test: /\.(png|jpg|gif|svg)$/,
65 | loader: 'file-loader',
66 | options: {
67 | name: '[name].[ext]?[hash]'
68 | }
69 | }
70 | ]
71 | },
72 | resolve: {
73 | alias: {
74 | 'vue$': 'vue/dist/vue.esm.js'
75 | },
76 | extensions: ['*', '.js', '.vue', '.json']
77 | },
78 | devServer: {
79 | historyApiFallback: true,
80 | noInfo: true,
81 | overlay: true
82 | },
83 | performance: {
84 | hints: false
85 | },
86 | devtool: '#eval-source-map'
87 | }
88 |
89 | if (process.env.NODE_ENV === 'production') {
90 | module.exports.devtool = '#source-map'
91 | // http://vue-loader.vuejs.org/en/workflow/production.html
92 | module.exports.plugins = (module.exports.plugins || []).concat([
93 | new webpack.DefinePlugin({
94 | 'process.env': {
95 | NODE_ENV: '"production"'
96 | }
97 | }),
98 | new webpack.optimize.UglifyJsPlugin({
99 | sourceMap: true,
100 | compress: {
101 | warnings: false
102 | }
103 | }),
104 | new webpack.LoaderOptionsPlugin({
105 | minimize: true
106 | })
107 | ])
108 | }
109 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue Modal
2 |
3 | [](https://www.npmjs.com/package/@voerro/vue-modal)
4 | [](https://www.npmjs.com/package/@voerro/vue-modal)
5 | [](https://opensource.org/licenses/MIT)
6 |
7 | A flexible & responsive modal component for Vue.js 2. Looks nice and clean on all devices.
8 |
9 | [Live Demo](https://voerro.github.io/vue-modal/)
10 |
11 | ## Installation via NPM
12 |
13 | ```
14 | npm i @voerro/vue-modal --save-dev
15 | ```
16 | or
17 | ```
18 | npm i @voerro/vue-modal --save
19 | ```
20 |
21 | Then import the component:
22 |
23 | ```javascript
24 | import { Modal, VoerroModal } from '@voerro/vue-modal';
25 |
26 | Vue.component('modal', Modal);
27 | window.VoerroModal = VoerroModal;
28 | ```
29 |
30 | ## Usage
31 |
32 | Add an empty component somewhere inside your template.
33 |
34 | ```html
35 |
36 | ```
37 |
38 | ### Generating Modals Dynamically
39 |
40 | Call `VoerroModal.show()` from anywhere in your script/Vue code. Example call:
41 |
42 | ```
43 | VoerroModal.show({
44 | title: 'Modal Title',
45 | body: 'Modal Body (HTML is supported here)',
46 | buttons: [
47 | {
48 | text: 'Ok',
49 | handler: () => {
50 | alert('You pressed Ok');
51 | }
52 | },
53 | {
54 | text: 'Cancel'
55 | }
56 | ]
57 | });
58 | ```
59 |
60 | You can add as many buttons as you need. When you press a button, the button's `handler` gets called and then the modal closes. If there's no handler, the modal will close immediately without any additional actions taking place.
61 |
62 | #### Buttons - Options
63 |
64 | To add buttons to a modal include an array of button objects. Each object can have the following properties (options):
65 |
66 | Property | Type | Default | Required | Description
67 | --- | --- | --- | --- | ---
68 | text | String | '' | yes | The text of the button
69 | handler | function | undefined | no | The function which will be called on button press. The default action is to hide the modal, so you don't have to include anything if the button click should only close the modal.
70 | preventDefault | Boolean | undefined (false) | no | Even if you provide a handler, the modal will be closed after the action is done. To prevent that set this property to true.
71 | class | String | '' | no | Additional CSS class(es) to add to the button.
72 | type | String | 'button' | no | Button type: 'submit', 'reset', or 'button'.
73 |
74 | #### Ajax
75 |
76 | You can fetch the modal's body via Ajax. To do so provide a `bodyUrl` URL instead of a `body`. Example:
77 |
78 | ```
79 | VoerroModal.show({
80 | title: 'Modal Title',
81 | bodyUrl: 'http://example.com/add-user-modal',
82 | buttons: [
83 | {
84 | text: 'Submit',
85 | handler: () => {
86 | alert('Submitting the form...');
87 | }
88 | },
89 | {
90 | text: 'Cancel'
91 | }
92 | ]
93 | });
94 | ```
95 |
96 | ### Inline Modals
97 |
98 | You can have multiple inline modals. "Inline" means a modal's content is stored within the HTML code of a page. Each modal should have a unique id. See an example below.
99 |
100 | HTML:
101 |
102 | ```html
103 |
104 | Inline Title
105 |
106 |
107 | This body, as well as the title, are stored directly within the HTML of your page.
108 |
109 |
110 |
111 | You'll have to implement the buttons completely yourself, in case you need them of course.
112 |
113 |
114 |
115 |
116 | Inline 2
117 |
118 |
This is a different inline modal with a different id.
119 |
120 | ```
121 |
122 | JS/ES:
123 |
124 | ```javascript
125 | // Show the modal with the id = 'inline-modal'
126 | VoerroModal.show('inline-modal');
127 |
128 | // Show the modal with the id = 'inline-modal-two'
129 | VoerroModal.show('inline-modal-two');
130 | ```
131 |
132 | You can still include an object with options (including dynamically generated buttons) in the method call.
133 |
134 | ```javascript
135 | VoerroModal.show('inline-modal', {
136 | buttons: [
137 | {
138 | text: 'Ok',
139 | handler: () => {
140 | alert('You pressed ok');
141 | }
142 | },
143 | { text: 'CLose' }
144 | ]
145 | });
146 | ```
147 |
148 | *Note: don't delete the empty `` component from your page if you also want to use dynamically generated modals.*
149 |
150 | ### `` Properties
151 |
152 | Property | Type | Default | Required | Description
153 | --- | --- | --- | --- | ---
154 | id | String | undefined | no | Id of the modal
155 | dismissible | Boolean | true | no | Whether a modal can be closed by clicking on the close button or on the overlay outside the modal. When applied to the global `` component becomes the default for all the dynamically generated modals. Can be overridden for individual modals.
156 | header | Boolean | true | no | Whether to show the header. When applied to the global `` component becomes the default for all the dynamically generated modals. Can be overridden for individual modals.
157 |
158 | ### VoerroModal Methods
159 |
160 | Method | Description | Arguments
161 | ---| --- | ---
162 | show (options) | Generate and show a modal | *options* - an object with options
**Available Options:** *title* - String - modal's title *body* - String - modal's body (HTML is supported) *bodyUrl* - String - URL to fetch modal's body from (AJAX) *buttons* - Array - an array of objects describing buttons *dismissible* - Boolean - Whether the modal can be closed by clicking on the close button or on the overlay outside the modal. *header* - Boolean - Whether to show the header.
163 | show (id) | Show an inline modal by id | *id* - the id of a modal to be shown
164 | hide (id) | Hide a modal by id | *id* - the id of a modal to be hidden.
165 | hide () | Hide the currently open dynamically generated modal | -
166 |
167 | ## License
168 |
169 | This is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
--------------------------------------------------------------------------------
/src/Modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Modals can have as many buttons as you need, each with a unique handler/action. A button without a handler simply closes the modal.
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Loading Modal's Body via AJAX
100 |
101 |
102 |
This works as a regular modal, except you need to provide a URL to fetch the content instead of a body.
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
Inline Modals
121 |
122 |
123 | Inline Title
124 |
125 |
This body, as well as the title, are stored directly within the HTML of your page.
126 |
127 |
You can put something else in the footer if you don't need the buttons (or provide the buttons via options like with dynamically generated modals)
128 |
129 |
130 |
131 | Inline 2
132 |
133 |
This is a different inline modal with a different id. Don't include the footer slot if you don't need it.
134 |
135 |
136 |
137 | Inline 3
138 |
139 |
The buttons for this modal are generated dynamically.
140 |
141 |
142 |
You can also define multiple modals inline with Vue slots. Each modal should have a unique id. Open this page's source code and find the two <modal> blocks defining these modals if you want to see how it works.
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | Hiding Modals Programmatically
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | Options
172 |
173 |
174 |
Undismissible Modals. An undismissible modal can not be dismissed by pressing on the close button or on the overlay outside the modal. An action (a button click) is required to close the modal.
175 |
176 |
177 |
178 |
179 |
180 |
181 | No Header
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 | Prevent Default Button's Action. By default the active modal will be closed after you press on any of the buttons (even if that button has a handler). Luckily, you can prevent that.
190 |