mirror of
				https://github.com/KevinMidboe/vue-js-modal.git
				synced 2025-10-29 18:00:20 +00:00 
			
		
		
		
	Replaced with the newer version
This commit is contained in:
		
							
								
								
									
										6
									
								
								.babelrc
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								.babelrc
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| { | { | ||||||
|   "presets": ["es2015", "stage-2"], |   "presets": [ | ||||||
|   "plugins": ["transform-runtime"], |     ["es2015", { "modules": false }] | ||||||
|   "comments": false |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,9 +0,0 @@ | |||||||
| root = true |  | ||||||
|  |  | ||||||
| [*] |  | ||||||
| charset = utf-8 |  | ||||||
| indent_style = space |  | ||||||
| indent_size = 2 |  | ||||||
| end_of_line = lf |  | ||||||
| insert_final_newline = true |  | ||||||
| trim_trailing_whitespace = true |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| build/*.js |  | ||||||
| config/*.js |  | ||||||
							
								
								
									
										30
									
								
								.eslintrc.js
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								.eslintrc.js
									
									
									
									
									
								
							| @@ -1,30 +0,0 @@ | |||||||
| module.exports = { |  | ||||||
|   root: true, |  | ||||||
|   parser: 'babel-eslint', |  | ||||||
|   parserOptions: { |  | ||||||
|     sourceType: 'module' |  | ||||||
|   }, |  | ||||||
|   extends: 'airbnb-base', |  | ||||||
|   plugins: [ |  | ||||||
|     'html' |  | ||||||
|   ], |  | ||||||
|   'settings': { |  | ||||||
|     'import/resolver': { |  | ||||||
|       'webpack': { |  | ||||||
|         'config': './webpack.base.config.js' |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   'rules': { |  | ||||||
|     // don't require .vue extension when importing |  | ||||||
|     'no-new': 0, |  | ||||||
|     'prefer-template': 0, |  | ||||||
|     'no-unused-vars': 0, |  | ||||||
|     'no-console': 0, |  | ||||||
|     'import/extensions': ['error', 'always', { |  | ||||||
|       'js': 'never', |  | ||||||
|       'vue': 'never' |  | ||||||
|     }], |  | ||||||
|     'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
| .DS_Store | .DS_Store | ||||||
| node_modules/ | node_modules/ | ||||||
|  | dist/ | ||||||
| npm-debug.log | npm-debug.log | ||||||
|   | |||||||
							
								
								
									
										201
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								LICENSE.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,201 @@ | |||||||
|  |                                  Apache License | ||||||
|  |                            Version 2.0, January 2004 | ||||||
|  |                         http://www.apache.org/licenses/ | ||||||
|  |  | ||||||
|  |    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||||
|  |  | ||||||
|  |    1. Definitions. | ||||||
|  |  | ||||||
|  |       "License" shall mean the terms and conditions for use, reproduction, | ||||||
|  |       and distribution as defined by Sections 1 through 9 of this document. | ||||||
|  |  | ||||||
|  |       "Licensor" shall mean the copyright owner or entity authorized by | ||||||
|  |       the copyright owner that is granting the License. | ||||||
|  |  | ||||||
|  |       "Legal Entity" shall mean the union of the acting entity and all | ||||||
|  |       other entities that control, are controlled by, or are under common | ||||||
|  |       control with that entity. For the purposes of this definition, | ||||||
|  |       "control" means (i) the power, direct or indirect, to cause the | ||||||
|  |       direction or management of such entity, whether by contract or | ||||||
|  |       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||||
|  |       outstanding shares, or (iii) beneficial ownership of such entity. | ||||||
|  |  | ||||||
|  |       "You" (or "Your") shall mean an individual or Legal Entity | ||||||
|  |       exercising permissions granted by this License. | ||||||
|  |  | ||||||
|  |       "Source" form shall mean the preferred form for making modifications, | ||||||
|  |       including but not limited to software source code, documentation | ||||||
|  |       source, and configuration files. | ||||||
|  |  | ||||||
|  |       "Object" form shall mean any form resulting from mechanical | ||||||
|  |       transformation or translation of a Source form, including but | ||||||
|  |       not limited to compiled object code, generated documentation, | ||||||
|  |       and conversions to other media types. | ||||||
|  |  | ||||||
|  |       "Work" shall mean the work of authorship, whether in Source or | ||||||
|  |       Object form, made available under the License, as indicated by a | ||||||
|  |       copyright notice that is included in or attached to the work | ||||||
|  |       (an example is provided in the Appendix below). | ||||||
|  |  | ||||||
|  |       "Derivative Works" shall mean any work, whether in Source or Object | ||||||
|  |       form, that is based on (or derived from) the Work and for which the | ||||||
|  |       editorial revisions, annotations, elaborations, or other modifications | ||||||
|  |       represent, as a whole, an original work of authorship. For the purposes | ||||||
|  |       of this License, Derivative Works shall not include works that remain | ||||||
|  |       separable from, or merely link (or bind by name) to the interfaces of, | ||||||
|  |       the Work and Derivative Works thereof. | ||||||
|  |  | ||||||
|  |       "Contribution" shall mean any work of authorship, including | ||||||
|  |       the original version of the Work and any modifications or additions | ||||||
|  |       to that Work or Derivative Works thereof, that is intentionally | ||||||
|  |       submitted to Licensor for inclusion in the Work by the copyright owner | ||||||
|  |       or by an individual or Legal Entity authorized to submit on behalf of | ||||||
|  |       the copyright owner. For the purposes of this definition, "submitted" | ||||||
|  |       means any form of electronic, verbal, or written communication sent | ||||||
|  |       to the Licensor or its representatives, including but not limited to | ||||||
|  |       communication on electronic mailing lists, source code control systems, | ||||||
|  |       and issue tracking systems that are managed by, or on behalf of, the | ||||||
|  |       Licensor for the purpose of discussing and improving the Work, but | ||||||
|  |       excluding communication that is conspicuously marked or otherwise | ||||||
|  |       designated in writing by the copyright owner as "Not a Contribution." | ||||||
|  |  | ||||||
|  |       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||||
|  |       on behalf of whom a Contribution has been received by Licensor and | ||||||
|  |       subsequently incorporated within the Work. | ||||||
|  |  | ||||||
|  |    2. Grant of Copyright License. Subject to the terms and conditions of | ||||||
|  |       this License, each Contributor hereby grants to You a perpetual, | ||||||
|  |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||||
|  |       copyright license to reproduce, prepare Derivative Works of, | ||||||
|  |       publicly display, publicly perform, sublicense, and distribute the | ||||||
|  |       Work and such Derivative Works in Source or Object form. | ||||||
|  |  | ||||||
|  |    3. Grant of Patent License. Subject to the terms and conditions of | ||||||
|  |       this License, each Contributor hereby grants to You a perpetual, | ||||||
|  |       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||||
|  |       (except as stated in this section) patent license to make, have made, | ||||||
|  |       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||||
|  |       where such license applies only to those patent claims licensable | ||||||
|  |       by such Contributor that are necessarily infringed by their | ||||||
|  |       Contribution(s) alone or by combination of their Contribution(s) | ||||||
|  |       with the Work to which such Contribution(s) was submitted. If You | ||||||
|  |       institute patent litigation against any entity (including a | ||||||
|  |       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||||
|  |       or a Contribution incorporated within the Work constitutes direct | ||||||
|  |       or contributory patent infringement, then any patent licenses | ||||||
|  |       granted to You under this License for that Work shall terminate | ||||||
|  |       as of the date such litigation is filed. | ||||||
|  |  | ||||||
|  |    4. Redistribution. You may reproduce and distribute copies of the | ||||||
|  |       Work or Derivative Works thereof in any medium, with or without | ||||||
|  |       modifications, and in Source or Object form, provided that You | ||||||
|  |       meet the following conditions: | ||||||
|  |  | ||||||
|  |       (a) You must give any other recipients of the Work or | ||||||
|  |           Derivative Works a copy of this License; and | ||||||
|  |  | ||||||
|  |       (b) You must cause any modified files to carry prominent notices | ||||||
|  |           stating that You changed the files; and | ||||||
|  |  | ||||||
|  |       (c) You must retain, in the Source form of any Derivative Works | ||||||
|  |           that You distribute, all copyright, patent, trademark, and | ||||||
|  |           attribution notices from the Source form of the Work, | ||||||
|  |           excluding those notices that do not pertain to any part of | ||||||
|  |           the Derivative Works; and | ||||||
|  |  | ||||||
|  |       (d) If the Work includes a "NOTICE" text file as part of its | ||||||
|  |           distribution, then any Derivative Works that You distribute must | ||||||
|  |           include a readable copy of the attribution notices contained | ||||||
|  |           within such NOTICE file, excluding those notices that do not | ||||||
|  |           pertain to any part of the Derivative Works, in at least one | ||||||
|  |           of the following places: within a NOTICE text file distributed | ||||||
|  |           as part of the Derivative Works; within the Source form or | ||||||
|  |           documentation, if provided along with the Derivative Works; or, | ||||||
|  |           within a display generated by the Derivative Works, if and | ||||||
|  |           wherever such third-party notices normally appear. The contents | ||||||
|  |           of the NOTICE file are for informational purposes only and | ||||||
|  |           do not modify the License. You may add Your own attribution | ||||||
|  |           notices within Derivative Works that You distribute, alongside | ||||||
|  |           or as an addendum to the NOTICE text from the Work, provided | ||||||
|  |           that such additional attribution notices cannot be construed | ||||||
|  |           as modifying the License. | ||||||
|  |  | ||||||
|  |       You may add Your own copyright statement to Your modifications and | ||||||
|  |       may provide additional or different license terms and conditions | ||||||
|  |       for use, reproduction, or distribution of Your modifications, or | ||||||
|  |       for any such Derivative Works as a whole, provided Your use, | ||||||
|  |       reproduction, and distribution of the Work otherwise complies with | ||||||
|  |       the conditions stated in this License. | ||||||
|  |  | ||||||
|  |    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||||
|  |       any Contribution intentionally submitted for inclusion in the Work | ||||||
|  |       by You to the Licensor shall be under the terms and conditions of | ||||||
|  |       this License, without any additional terms or conditions. | ||||||
|  |       Notwithstanding the above, nothing herein shall supersede or modify | ||||||
|  |       the terms of any separate license agreement you may have executed | ||||||
|  |       with Licensor regarding such Contributions. | ||||||
|  |  | ||||||
|  |    6. Trademarks. This License does not grant permission to use the trade | ||||||
|  |       names, trademarks, service marks, or product names of the Licensor, | ||||||
|  |       except as required for reasonable and customary use in describing the | ||||||
|  |       origin of the Work and reproducing the content of the NOTICE file. | ||||||
|  |  | ||||||
|  |    7. Disclaimer of Warranty. Unless required by applicable law or | ||||||
|  |       agreed to in writing, Licensor provides the Work (and each | ||||||
|  |       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||||
|  |       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||||
|  |       implied, including, without limitation, any warranties or conditions | ||||||
|  |       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||||
|  |       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||||
|  |       appropriateness of using or redistributing the Work and assume any | ||||||
|  |       risks associated with Your exercise of permissions under this License. | ||||||
|  |  | ||||||
|  |    8. Limitation of Liability. In no event and under no legal theory, | ||||||
|  |       whether in tort (including negligence), contract, or otherwise, | ||||||
|  |       unless required by applicable law (such as deliberate and grossly | ||||||
|  |       negligent acts) or agreed to in writing, shall any Contributor be | ||||||
|  |       liable to You for damages, including any direct, indirect, special, | ||||||
|  |       incidental, or consequential damages of any character arising as a | ||||||
|  |       result of this License or out of the use or inability to use the | ||||||
|  |       Work (including but not limited to damages for loss of goodwill, | ||||||
|  |       work stoppage, computer failure or malfunction, or any and all | ||||||
|  |       other commercial damages or losses), even if such Contributor | ||||||
|  |       has been advised of the possibility of such damages. | ||||||
|  |  | ||||||
|  |    9. Accepting Warranty or Additional Liability. While redistributing | ||||||
|  |       the Work or Derivative Works thereof, You may choose to offer, | ||||||
|  |       and charge a fee for, acceptance of support, warranty, indemnity, | ||||||
|  |       or other liability obligations and/or rights consistent with this | ||||||
|  |       License. However, in accepting such obligations, You may act only | ||||||
|  |       on Your own behalf and on Your sole responsibility, not on behalf | ||||||
|  |       of any other Contributor, and only if You agree to indemnify, | ||||||
|  |       defend, and hold each Contributor harmless for any liability | ||||||
|  |       incurred by, or claims asserted against, such Contributor by reason | ||||||
|  |       of your accepting any such warranty or additional liability. | ||||||
|  |  | ||||||
|  |    END OF TERMS AND CONDITIONS | ||||||
|  |  | ||||||
|  |    APPENDIX: How to apply the Apache License to your work. | ||||||
|  |  | ||||||
|  |       To apply the Apache License to your work, attach the following | ||||||
|  |       boilerplate notice, with the fields enclosed by brackets "{}" | ||||||
|  |       replaced with your own identifying information. (Don't include | ||||||
|  |       the brackets!)  The text should be enclosed in the appropriate | ||||||
|  |       comment syntax for the file format. We also recommend that a | ||||||
|  |       file or class name and description of purpose be included on the | ||||||
|  |       same "printed page" as the copyright notice for easier | ||||||
|  |       identification within third-party archives. | ||||||
|  |  | ||||||
|  |    Copyright {yyyy} {name of copyright owner} | ||||||
|  |  | ||||||
|  |    Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |    you may not use this file except in compliance with the License. | ||||||
|  |    You may obtain a copy of the License at | ||||||
|  |  | ||||||
|  |        http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  | ||||||
|  |    Unless required by applicable law or agreed to in writing, software | ||||||
|  |    distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |    See the License for the specific language governing permissions and | ||||||
|  |    limitations under the License. | ||||||
							
								
								
									
										250
									
								
								Modal/Modal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								Modal/Modal.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | |||||||
|  | <template> | ||||||
|  |   <transition name="overlay-fade"> | ||||||
|  |     <div v-if="visibility.overlay" | ||||||
|  |          class="nice-modal-overlay" | ||||||
|  |          @mousedown.stop="toggle(false)"> | ||||||
|  |       <transition :name="transition"> | ||||||
|  |         <div v-if="visibility.modal" | ||||||
|  |              v-bind:class="modalClass" | ||||||
|  |              v-bind:style="modalStyle" | ||||||
|  |              v-on:mousedown.stop | ||||||
|  |              ref="modal"> | ||||||
|  |           <slot></slot> | ||||||
|  |           <resizer v-if="resizable" @resize="resize"/> | ||||||
|  |         </div> | ||||||
|  |       </transition> | ||||||
|  |     </div> | ||||||
|  |   </transition> | ||||||
|  | </template> | ||||||
|  | <script> | ||||||
|  |   import Vue from 'vue'; | ||||||
|  |   import Modal from './index'; | ||||||
|  |   import Resizer from './Resizer.vue'; | ||||||
|  |  | ||||||
|  |   export default { | ||||||
|  |     name: 'Modal', | ||||||
|  |     props: { | ||||||
|  |       name: { | ||||||
|  |         required: true, | ||||||
|  |         type: [String, Number], | ||||||
|  |       }, | ||||||
|  |       delay: { | ||||||
|  |         type: Number, | ||||||
|  |         default: 0, | ||||||
|  |       }, | ||||||
|  |       resizable: { | ||||||
|  |         type: Boolean, | ||||||
|  |         default: false | ||||||
|  |       }, | ||||||
|  |       adaptive: { | ||||||
|  |         type: Boolean, | ||||||
|  |         default: false | ||||||
|  |       }, | ||||||
|  |       transition: { | ||||||
|  |         type: String, | ||||||
|  |       }, | ||||||
|  |       classes: { | ||||||
|  |         type: [String, Array], | ||||||
|  |         default: 'nice-modal', | ||||||
|  |       }, | ||||||
|  |       width: { | ||||||
|  |         type: Number, | ||||||
|  |         default: 600 | ||||||
|  |       }, | ||||||
|  |       height: { | ||||||
|  |         type: Number, | ||||||
|  |         default: 300 | ||||||
|  |       }, | ||||||
|  |       minWidth: { | ||||||
|  |         type: Number, | ||||||
|  |         default: 0 | ||||||
|  |       }, | ||||||
|  |       minHeight: { | ||||||
|  |         type: Number, | ||||||
|  |         default: 0 | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     components: { | ||||||
|  |       Resizer | ||||||
|  |     }, | ||||||
|  |     data() { | ||||||
|  |       return { | ||||||
|  |         visible: false, | ||||||
|  |  | ||||||
|  |         visibility: { | ||||||
|  |           modal: false, | ||||||
|  |           overlay: false | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         modal: { | ||||||
|  |           width: this.width, | ||||||
|  |           height: this.height | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         window: { | ||||||
|  |           width: window.innerWidth, | ||||||
|  |           height: window.innerWidth | ||||||
|  |         } | ||||||
|  |       }; | ||||||
|  |     }, | ||||||
|  |     watch: { | ||||||
|  |       visible(value) { | ||||||
|  |         if (this.delay > 0) { | ||||||
|  |           if (value) { | ||||||
|  |             this.visibility.overlay = true; | ||||||
|  |             setTimeout(() => this.visibility.modal = true, this.delay); | ||||||
|  |           } else { | ||||||
|  |             this.visibility.modal = false; | ||||||
|  |             setTimeout(() => this.visibility.overlay = false, this.delay); | ||||||
|  |           } | ||||||
|  |         } else { | ||||||
|  |           this.visibility.overlay = value; | ||||||
|  |           Vue.nextTick(() => this.visibility.modal = value); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     created() { | ||||||
|  |       Modal.event.$on('toggle', (name, state, params) => { | ||||||
|  |         if (name === this.name) { | ||||||
|  |           this.toggle(!this.visible, params); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       window.addEventListener('resize', this.onWindowResize); | ||||||
|  |     }, | ||||||
|  |     beforeMount() { | ||||||
|  |       this.onWindowResize(); | ||||||
|  |     }, | ||||||
|  |     computed: { | ||||||
|  |       position() { | ||||||
|  |         return { | ||||||
|  |           left: (this.window.width - this.modal.width) / 2, | ||||||
|  |           top: (this.window.height - this.modal.height) / 2 | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       modalClass() { | ||||||
|  |         return ['modal', this.classes]; | ||||||
|  |       }, | ||||||
|  |       modalStyle() { | ||||||
|  |         return { | ||||||
|  |           top: this.position.top + 'px', | ||||||
|  |           left: this.position.left + 'px', | ||||||
|  |           width: this.modal.width + 'px', | ||||||
|  |           height: this.modal.height + 'px' | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     methods: { | ||||||
|  |       onWindowResize() { | ||||||
|  |         this.window.width = window.innerWidth; | ||||||
|  |         this.window.height = window.innerHeight; | ||||||
|  |  | ||||||
|  |         if (this.adaptive) { | ||||||
|  |           this.modal.width = this.window.width > this.width | ||||||
|  |             ? this.width | ||||||
|  |             : this.window.width | ||||||
|  |  | ||||||
|  |           this.modal.height = this.window.height > this.height | ||||||
|  |             ? this.height | ||||||
|  |             : this.window.height; | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       genEventObject(params) { | ||||||
|  |         return Vue.util.extend( | ||||||
|  |           { | ||||||
|  |             name: this.name, | ||||||
|  |             ref: this.$refs.modal, | ||||||
|  |             timestamp: Date.now() | ||||||
|  |           }, | ||||||
|  |           params || {}); | ||||||
|  |       }, | ||||||
|  |       resize(event) { | ||||||
|  |         this.modal.width = event.size.width; | ||||||
|  |  | ||||||
|  |         let resizeEvent = this.genEventObject({ | ||||||
|  |           size: this.modal | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.$emit('resize', resizeEvent); | ||||||
|  |       }, | ||||||
|  |       toggle(state, params) { | ||||||
|  |         const beforeEventName = this.visible ? 'before-close' : 'before-open'; | ||||||
|  |         const afterEventName = this.visible ? 'closed' : 'opened'; | ||||||
|  |  | ||||||
|  |         let stopEventExecution = false; | ||||||
|  |  | ||||||
|  |         const beforeEvent = this.genEventObject({ | ||||||
|  |           stop: () => stopEventExecution = false, | ||||||
|  |           state, | ||||||
|  |           params | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         this.$emit(beforeEventName, beforeEvent); | ||||||
|  |  | ||||||
|  |         if (!stopEventExecution) { | ||||||
|  |           this.visible = !!state; | ||||||
|  |  | ||||||
|  |           const afterEvent = this.genEventObject({ | ||||||
|  |             state, | ||||||
|  |             params | ||||||
|  |           }); | ||||||
|  |  | ||||||
|  |           this.$emit(afterEventName, afterEvent); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  | </script> | ||||||
|  | <style lang="scss" scoped> | ||||||
|  |   .nice-modal-overlay { | ||||||
|  |     position: fixed; | ||||||
|  |     left: 0; | ||||||
|  |     top: 0; | ||||||
|  |     width: 100vw; | ||||||
|  |     height: 100vh; | ||||||
|  |     background: rgba(0, 0, 0, 0.2); | ||||||
|  |     z-index: 999; | ||||||
|  |     opacity: 1; | ||||||
|  |  | ||||||
|  |     .modal { | ||||||
|  |       position: relative; | ||||||
|  |       overflow: hidden; | ||||||
|  |       box-sizing: border-box; | ||||||
|  |  | ||||||
|  |       background-color: white; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .overlay-fade-enter-active, .overlay-fade-leave-active { | ||||||
|  |     transition: all 0.2s; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .overlay-fade-enter, .overlay-fade-leave-active { | ||||||
|  |     opacity: 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .nice-modal-fade-enter-active, .nice-modal-fade-leave-active { | ||||||
|  |     transition: all 0.5s; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .nice-modal-fade-enter, .nice-modal-fade-leave-active { | ||||||
|  |     opacity: 0; | ||||||
|  |     transform: translateY(-20px); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .nice-modal { | ||||||
|  |     background: white; | ||||||
|  |     text-align: left; | ||||||
|  |     border-radius: 3px; | ||||||
|  |     box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4); | ||||||
|  |     padding: 0; | ||||||
|  |  | ||||||
|  |     &.nice-modal-fullscreen { | ||||||
|  |       width: 100vw; | ||||||
|  |       height: 100vh; | ||||||
|  |       margin: 0; | ||||||
|  |       left: 0; | ||||||
|  |       top: 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										103
									
								
								Modal/Resizer.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								Modal/Resizer.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | <template> | ||||||
|  |   <div :class="{'vue-modal-resizer': true, 'clicked': clicked}"> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <script> | ||||||
|  | import util from '../util'; | ||||||
|  | export default { | ||||||
|  |   name: 'Resizer', | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       clicked: false, | ||||||
|  |       min: { | ||||||
|  |         height: 50, | ||||||
|  |         width: 0 | ||||||
|  |       }, | ||||||
|  |       size: {} | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.$el.addEventListener('mousedown', this.start, false); | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     start(event) { | ||||||
|  |       this.clicked = true; | ||||||
|  |  | ||||||
|  |       window.addEventListener('mousemove', this.mousemove, false); | ||||||
|  |       window.addEventListener('mouseup', this.stop, false); | ||||||
|  |  | ||||||
|  |       util.stopEvent(event); | ||||||
|  |     }, | ||||||
|  |     stop() { | ||||||
|  |       this.clicked = false; | ||||||
|  |  | ||||||
|  |       window.removeEventListener('mousemove', this.mousemove, false); | ||||||
|  |       window.removeEventListener('mouseup', this.stop, false); | ||||||
|  |  | ||||||
|  |       this.$emit('resize-stop', { | ||||||
|  |         element: this.$el.parentElement, | ||||||
|  |         size: this.size | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     mousemove(event) { | ||||||
|  |       this.resize(event); | ||||||
|  |     }, | ||||||
|  |     resize(event) { | ||||||
|  |       var el = this.$el.parentElement; | ||||||
|  |  | ||||||
|  |       if (event.clientX < window.innerWidth / 2) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (el) { | ||||||
|  |         var width = event.clientX - el.offsetLeft; | ||||||
|  |         var height = event.clientY - el.offsetTop; | ||||||
|  |  | ||||||
|  |         if (height < this.min.height) { | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.size = {width, height}; | ||||||
|  |         el.style.width = width + 'px'; | ||||||
|  |         el.style.height = height + 'px'; | ||||||
|  |  | ||||||
|  |         this.$emit('resize', { | ||||||
|  |           element: el, | ||||||
|  |           size: this.size | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | <style lang="scss"> | ||||||
|  | .vue-modal-resizer { | ||||||
|  |     display: block; | ||||||
|  |     overflow: hidden; | ||||||
|  |     position: absolute; | ||||||
|  |     width: 12px; | ||||||
|  |     height: 12px; | ||||||
|  |     right: 0; | ||||||
|  |     bottom: 0; | ||||||
|  |     z-index: 9999999; | ||||||
|  |     background: transparent; | ||||||
|  |     cursor: se-resize; | ||||||
|  |  | ||||||
|  |     &:after { | ||||||
|  |       display: block; | ||||||
|  |       position: absolute; | ||||||
|  |       content: ''; | ||||||
|  |       background: transparent; | ||||||
|  |       left: 0; | ||||||
|  |       top: 0; | ||||||
|  |     	width: 0; | ||||||
|  |     	height: 0; | ||||||
|  |     	border-bottom: 10px solid #ddd; | ||||||
|  |     	border-left: 10px solid transparent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     &.clicked:after { | ||||||
|  |       border-bottom: 10px solid #369BE9; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										30
									
								
								Modal/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Modal/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | import Vue from 'vue'; | ||||||
|  | import Modal from './Modal.vue'; | ||||||
|  |  | ||||||
|  | const VueModal = { | ||||||
|  |   install(Vue, options = {}) { | ||||||
|  |     if (!this.hasOwnProperty("event")) { | ||||||
|  |       this.event = new Vue(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const $modal = { | ||||||
|  |       show(name, params) { | ||||||
|  |         VueModal.event.$emit('toggle', name, true, params); | ||||||
|  |       }, | ||||||
|  |       hide(name, params) { | ||||||
|  |         VueModal.event.$emit('toggle', name, false, params); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     Object.defineProperty(Vue.prototype, '$modal', { | ||||||
|  |       get: () => $modal | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     Vue.component('nice-modal', Modal); | ||||||
|  |     return null; | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | Vue.use(VueModal); | ||||||
|  |  | ||||||
|  | export default VueModal; | ||||||
							
								
								
									
										48
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,45 +1,7 @@ | |||||||
| # vue-modal | ##nice-vue-components | ||||||
|  |  | ||||||
| A simple modal component for Vue.js | A collection of vue components | ||||||
|  |  | ||||||
| ##Install | * Beeper | ||||||
|  | * Notification | ||||||
| ##Usage | * Modal | ||||||
| Example: |  | ||||||
|  |  | ||||||
| main.js: |  | ||||||
| ```js |  | ||||||
| import Vue from 'vue'; |  | ||||||
| import App from './App'; |  | ||||||
| import VueModal from 'vue-modal'; |  | ||||||
|  |  | ||||||
| Vue.use(VueModal); |  | ||||||
|  |  | ||||||
| new Vue({ |  | ||||||
|   el: '#app', |  | ||||||
|   template: '<App/>', |  | ||||||
|   components: { App }, |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
| App.vue: |  | ||||||
| ```html |  | ||||||
| <template> |  | ||||||
|   <div id="app"> |  | ||||||
|     <h1>Test page</h1> |  | ||||||
|     <button @click="modal('basic')">Show modal</button> |  | ||||||
|     <modal name="basic">Hello! Im a modal!</modal> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: 'app', |  | ||||||
|   methods: { |  | ||||||
|     modal(name) => this.$modal.show(name), |  | ||||||
|   }, |  | ||||||
| }; |  | ||||||
| </script> |  | ||||||
| ``` |  | ||||||
| ##License |  | ||||||
| MIT |  | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								dist/vue-modal.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								dist/vue-modal.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,37 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div id="app"> |  | ||||||
|     <h1>Test page</h1> |  | ||||||
|     <button @click="showModal('basic')">Show basic modal</button> |  | ||||||
|     <transition name="fade"> |  | ||||||
|       <modal name="basic">Hello! Im basic modal!</modal> |  | ||||||
|     </transition> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|   name: 'app', |  | ||||||
|   methods: { |  | ||||||
|     showModal(name) => this.$modal.show(name), |  | ||||||
|   }, |  | ||||||
| }; |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style> |  | ||||||
| #app { |  | ||||||
|   font-family: 'Avenir', Helvetica, Arial, sans-serif; |  | ||||||
|   -webkit-font-smoothing: antialiased; |  | ||||||
|   -moz-osx-font-smoothing: grayscale; |  | ||||||
|   text-align: center; |  | ||||||
|   color: #2c3e50; |  | ||||||
|   margin-top: 60px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .fade-enter-active, .fade-leave-active { |  | ||||||
|   transition: all .3s; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .fade-enter, .fade-leave-active { |  | ||||||
|   opacity: 0; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,10 +1,11 @@ | |||||||
| <!DOCTYPE html> | <!DOCTYPE html> | ||||||
| <html> | <html lang="en"> | ||||||
|   <head> |   <head> | ||||||
|     <meta charset="utf-8"> |     <meta charset="utf-8"> | ||||||
|     <title>vue-modal</title> |     <title>Examples</title> | ||||||
|   </head> |   </head> | ||||||
|   <body> |   <body> | ||||||
|     <div id="app"></div> |     <div id="app"></div> | ||||||
|  |     <script src="/dist/build.js"></script> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|   | |||||||
| @@ -1,11 +0,0 @@ | |||||||
| import Vue from 'vue'; |  | ||||||
| import App from './App'; |  | ||||||
| import VueModal from '../src/index'; |  | ||||||
|  |  | ||||||
| Vue.use(VueModal); |  | ||||||
|  |  | ||||||
| new Vue({ |  | ||||||
|   el: '#app', |  | ||||||
|   template: '<App/>', |  | ||||||
|   components: { App }, |  | ||||||
| }); |  | ||||||
							
								
								
									
										104
									
								
								examples/src/App.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								examples/src/App.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | <template> | ||||||
|  |   <div id="app"> | ||||||
|  |     <h2> | ||||||
|  |       Beeper | ||||||
|  |       <nice-beep class="inline-beep" color="#23d813" :frequency="1200"/> | ||||||
|  |     </h2> | ||||||
|  |     <div> | ||||||
|  |       tl;dr | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |     <h2>Notifications</h2> | ||||||
|  |     <nice-notifications name="example-1" animation="fade"/> | ||||||
|  |     <nice-notifications position="bottom left"/> | ||||||
|  |     <button @click="notifyExample0">Example 1</button> | ||||||
|  |     <button @click="notifyExample1">Example 2</button> | ||||||
|  |  | ||||||
|  |     <h2>Modals</h2> | ||||||
|  |     <nice-modal name="example-modal" | ||||||
|  |                 transition="nice-modal-fade" | ||||||
|  |                 :delay="200" | ||||||
|  |                 :adaptive="true" | ||||||
|  |                 :resizable="true"> | ||||||
|  |       <div style="height: 100%; box-sizing: border-box; padding: 10px; font-size: 13px; overflow: auto"> | ||||||
|  |           Appropriately exploit professional infrastructures rather than unique | ||||||
|  |           growth strategies. Assertively build leveraged growth strategies | ||||||
|  |           vis-a-vis multimedia based vortals. Progressively simplify | ||||||
|  |           cross-platform value through interactive imperatives. Objectively | ||||||
|  |           implement enabled web services after plug-and-play ROI. Distinctively | ||||||
|  |           impact inexpensive schemas before installed base imperatives. | ||||||
|  |           Holisticly benchmark pandemic process improvements without wireless | ||||||
|  |           experiences. | ||||||
|  |           Efficiently create worldwide partnerships after tactical vortals. | ||||||
|  |           Uniquely productize enabled platforms vis-a-vis timely processes. | ||||||
|  |           Conveniently unleash standards compliant niches through highly | ||||||
|  |           efficient testing procedures. Rapidiously enable pandemic niche | ||||||
|  |           markets whereas viral markets. | ||||||
|  |           Assertively simplify alternative partnerships and error-free | ||||||
|  |           e-commerce. Professionally formulate 24/365 internal or "organic" | ||||||
|  |           sources through equity invested mindshare. Globally redefine unique | ||||||
|  |           best practices for. | ||||||
|  |       </div> | ||||||
|  |     </nice-modal> | ||||||
|  |     <button @click="modalExample0">Example 1</button> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | const ID = ((i) => () => i++)(0); | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: 'app', | ||||||
|  |   methods: { | ||||||
|  |     notifyExample0() { | ||||||
|  |       this.$notify({ | ||||||
|  |         type: 'error', | ||||||
|  |         group: 'example-1', | ||||||
|  |         title: 'Error message', | ||||||
|  |         text: 'This is error message #' + ID() | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     notifyExample1() { | ||||||
|  |       this.$notify({ | ||||||
|  |         type: 'warn', | ||||||
|  |         duration: 10000, | ||||||
|  |         title: 'Warning message', | ||||||
|  |         text: | ||||||
|  |           ` | ||||||
|  |           Warning #${ID()} <br> | ||||||
|  |           Notification will dissapear in 10 sec<br> | ||||||
|  |           Rendering <b>HTML</b> | ||||||
|  |           ` | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     modalExample0() { | ||||||
|  |       this.$modal.show('example-modal'); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss"> | ||||||
|  | body { | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 50px; | ||||||
|  |   box-sizing: border-box; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #app { | ||||||
|  |   font-family: 'Avenir', Helvetica, Arial, sans-serif; | ||||||
|  |   -webkit-font-smoothing: antialiased; | ||||||
|  |   -moz-osx-font-smoothing: grayscale; | ||||||
|  |   color: #2c3e50; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | h1, h2 { | ||||||
|  |   font-weight: normal; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .inline-beep { | ||||||
|  |   display: inline-block; | ||||||
|  |   position: relative !important; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | </style> | ||||||
							
								
								
									
										8
									
								
								examples/src/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/src/main.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | import Vue from 'vue'; | ||||||
|  | import App from './App.vue'; | ||||||
|  | import Modal from '../../Modal'; | ||||||
|  |  | ||||||
|  | new Vue({ | ||||||
|  |   el: '#app', | ||||||
|  |   render: h => h(App) | ||||||
|  | }); | ||||||
							
								
								
									
										67
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,60 +1,31 @@ | |||||||
| { | { | ||||||
|   "name": "vue-modal", |   "name": "examples", | ||||||
|   "version": "0.0.1", |   "description": "Examples of using components", | ||||||
|   "description": "A Vue.js simple modal dialog component", |   "version": "1.0.0", | ||||||
|   "author": "euvl <yev.vlasenko@gmail.com>", |   "author": "euvl <yev.vlasenko@gmail.com>", | ||||||
|   "private": true, |   "private": false, | ||||||
|   "license": "MIT", |   "main": "./components/index.js", | ||||||
|   "main": "./dist/vue-modal.js", |   "scripts": { | ||||||
|   "repository": { |     "examples": "cross-env NODE_ENV=development webpack-dev-server --open --hot" | ||||||
|     "type": "git", |  | ||||||
|     "url": "git+https://github.com/euvl/vue-modal.git" |  | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "babel-runtime": "^6.18.0", |     "vue": "^2.1.10", | ||||||
|     "autoprefixer": "^6.4.0", |  | ||||||
|     "babel-core": "^6.0.0", |     "babel-core": "^6.0.0", | ||||||
|     "babel-eslint": "^7.0.0", |     "babel-loader": "^6.2.10", | ||||||
|     "babel-loader": "^6.0.0", |  | ||||||
|     "babel-plugin-transform-runtime": "^6.0.0", |  | ||||||
|     "babel-preset-es2015": "^6.0.0", |     "babel-preset-es2015": "^6.0.0", | ||||||
|     "babel-preset-stage-2": "^6.0.0", |     "cross-env": "^3.0.0", | ||||||
|     "babel-register": "^6.0.0", |  | ||||||
|     "chalk": "^1.1.3", |  | ||||||
|     "connect-history-api-fallback": "^1.1.0", |  | ||||||
|     "css-loader": "^0.25.0", |     "css-loader": "^0.25.0", | ||||||
|     "eslint": "^3.7.1", |  | ||||||
|     "eslint-friendly-formatter": "^2.0.5", |  | ||||||
|     "eslint-loader": "^1.5.0", |  | ||||||
|     "eslint-plugin-html": "^1.3.0", |  | ||||||
|     "eslint-config-airbnb-base": "^8.0.0", |  | ||||||
|     "eslint-import-resolver-webpack": "^0.6.0", |  | ||||||
|     "eslint-plugin-import": "^1.16.0", |  | ||||||
|     "eventsource-polyfill": "^0.9.6", |  | ||||||
|     "express": "^4.13.3", |  | ||||||
|     "extract-text-webpack-plugin": "^1.0.1", |  | ||||||
|     "file-loader": "^0.9.0", |     "file-loader": "^0.9.0", | ||||||
|     "function-bind": "^1.0.2", |     "node-sass": "^4.5.0", | ||||||
|     "html-webpack-plugin": "^2.8.1", |     "sass-loader": "^5.0.1", | ||||||
|     "http-proxy-middleware": "^0.17.2", |     "vue-hot-reload-api": "^2.0.8", | ||||||
|     "json-loader": "^0.5.4", |     "vue-loader": "^10.0.0", | ||||||
|     "semver": "^5.3.0", |     "vue-style-loader": "^2.0.0", | ||||||
|     "opn": "^4.0.2", |     "vue-template-compiler": "^2.1.0", | ||||||
|     "ora": "^0.3.0", |     "webpack": "^2.2.0", | ||||||
|     "shelljs": "^0.7.4", |     "webpack-dev-server": "^2.2.0" | ||||||
|     "url-loader": "^0.5.7", |  | ||||||
|     "vue-loader": "^9.4.0", |  | ||||||
|     "vue-style-loader": "^1.0.0", |  | ||||||
|     "webpack": "^1.13.2", |  | ||||||
|     "webpack-dev-middleware": "^1.8.3", |  | ||||||
|     "webpack-hot-middleware": "^2.12.2", |  | ||||||
|     "webpack-merge": "^0.14.1" |  | ||||||
|   }, |  | ||||||
|   "engines": { |  | ||||||
|     "node": ">= 4.0.0", |  | ||||||
|     "npm": ">= 3.0.0" |  | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "vue": "^2.0.5" |     "velocity-animate": "^1.4.2" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										146
									
								
								src/Modal.vue
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								src/Modal.vue
									
									
									
									
									
								
							| @@ -1,146 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <div class="vue-modal-overlay" v-if="visibleOverlay" @click.stop="toggle(false)"> |  | ||||||
|     <transition :name="transition"> |  | ||||||
|       <div :class="modalclass" ref="modal" :style="styles" v-show="visibleModal" @click.stop> |  | ||||||
|         <template v-if="withTitle"> |  | ||||||
|           <div class="modal-title"> |  | ||||||
|             <slot name="title-left"/> |  | ||||||
|             <slot name="title-right"/> |  | ||||||
|           </div> |  | ||||||
|         </template> |  | ||||||
|         <slot/> |  | ||||||
|       </div> |  | ||||||
|     </transition> |  | ||||||
|   </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|   import Vue from 'vue'; |  | ||||||
|   import VueModal from './modal'; |  | ||||||
|  |  | ||||||
|   const props = { |  | ||||||
|     name: { |  | ||||||
|       required: true, |  | ||||||
|       type: [String, Number], |  | ||||||
|     }, |  | ||||||
|     withTitle: { |  | ||||||
|       type: Boolean, |  | ||||||
|       default: false, |  | ||||||
|     }, |  | ||||||
|     delay: { |  | ||||||
|       type: Number, |  | ||||||
|       default: 0, |  | ||||||
|     }, |  | ||||||
|     position: { |  | ||||||
|       type: Array, |  | ||||||
|     }, |  | ||||||
|     transition: { |  | ||||||
|       type: String, |  | ||||||
|     }, |  | ||||||
|     classes: { |  | ||||||
|       type: [String, Array], |  | ||||||
|       default: 'vue-modal', |  | ||||||
|     }, |  | ||||||
|     width: { |  | ||||||
|       type: Number, |  | ||||||
|       default: 600, |  | ||||||
|     }, |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   export default { |  | ||||||
|     name: 'Modal', |  | ||||||
|     props, |  | ||||||
|     data() { |  | ||||||
|       return { |  | ||||||
|         visible: false, |  | ||||||
|         visibleModal: false, |  | ||||||
|         visibleOverlay: false, |  | ||||||
|       }; |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|       visible(value) { |  | ||||||
|         if (this.delay > 0) { |  | ||||||
|           if (value) { |  | ||||||
|             this.visibleOverlay = true; |  | ||||||
|             setTimeout(() => { this.visibleModal = true; }, |  | ||||||
|               this.delay); |  | ||||||
|           } else { |  | ||||||
|             this.visibleModal = false; |  | ||||||
|             setTimeout(() => { this.visibleOverlay = false; }, |  | ||||||
|               this.delay); |  | ||||||
|           } |  | ||||||
|         } else { |  | ||||||
|           this.visibleOverlay = value; |  | ||||||
|  |  | ||||||
|           Vue.nextTick(() => { |  | ||||||
|             this.visibleModal = value; |  | ||||||
|           }); |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     created() { |  | ||||||
|       VueModal.event.$on('toggle', (name, state) => { |  | ||||||
|         if (name === this.name) { |  | ||||||
|           this.toggle(!this.visible); |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|     }, |  | ||||||
|     computed: { |  | ||||||
|       modalclass() { |  | ||||||
|         return ['modal', this.classes]; |  | ||||||
|       }, |  | ||||||
|       styles() { |  | ||||||
|         return { |  | ||||||
|           'margin-left': (-this.width / 2) + 'px', |  | ||||||
|           width: this.width + 'px', |  | ||||||
|         }; |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|       toggle(state) { |  | ||||||
|         const before = this.visible ? 'before-close' : 'before-open'; |  | ||||||
|         const after = this.visible ? 'opened' : 'closed'; |  | ||||||
|  |  | ||||||
|         this.$emit(before, this.name); |  | ||||||
|         this.visible = !!state; |  | ||||||
|         this.$emit(after, this.name); |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|   }; |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style> |  | ||||||
|   .vue-modal-overlay { |  | ||||||
|     position: fixed; |  | ||||||
|     left: 0; |  | ||||||
|     top: 0; |  | ||||||
|     width: 100vw; |  | ||||||
|     height: 100vh; |  | ||||||
|     background: rgba(0, 0, 0, 0.1); |  | ||||||
|     z-index: 999; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .vue-modal-fade-enter-active, .vue-modal-fade-leave-active { |  | ||||||
|     transition: all .3s; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .vue-modal-fade-enter, .vue-modal-fade-leave-active { |  | ||||||
|     opacity: 0; |  | ||||||
|     transform: translateY(-20px); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .vue-modal { |  | ||||||
|     position: absolute; |  | ||||||
|     background: white; |  | ||||||
|     position: relative; |  | ||||||
|     text-align: left; |  | ||||||
|  |  | ||||||
|     left: 50%; |  | ||||||
|     top: 20%; |  | ||||||
|  |  | ||||||
|     box-sizing: border-box; |  | ||||||
|     border-radius: 3px; |  | ||||||
|     box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4); |  | ||||||
|     padding: 5px; |  | ||||||
|   } |  | ||||||
| </style> |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| import VueModal from './modal'; |  | ||||||
|  |  | ||||||
| export default VueModal; |  | ||||||
							
								
								
									
										43
									
								
								src/modal.js
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								src/modal.js
									
									
									
									
									
								
							| @@ -1,43 +0,0 @@ | |||||||
| import Vue from 'vue'; |  | ||||||
| import Modal from './Modal.vue'; |  | ||||||
|  |  | ||||||
| const VueModal = { |  | ||||||
|   event: new Vue(), |  | ||||||
|   install(self, options = {}) { |  | ||||||
|     if (this.installed) { |  | ||||||
|       return console.log('Modal component is already installed.'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     this.installed = true; |  | ||||||
|  |  | ||||||
|     const modal = { |  | ||||||
|       toggle(name, state, params) { |  | ||||||
|         const opts = typeof state === 'object' && typeof params === 'undefined' |  | ||||||
|           ? state |  | ||||||
|           : params; |  | ||||||
|  |  | ||||||
|         VueModal.event |  | ||||||
|           .$emit('toggle', name, state); |  | ||||||
|       }, |  | ||||||
|       show(name, params = {}) { |  | ||||||
|         VueModal.event |  | ||||||
|           .$emit('toggle', name, true); |  | ||||||
|       }, |  | ||||||
|       hide(name, params = {}) { |  | ||||||
|         VueModal.event |  | ||||||
|           .$emit('toggle', name, false); |  | ||||||
|       }, |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     Object.defineProperty(Vue.prototype, '$modal', { |  | ||||||
|       get() { |  | ||||||
|         return modal; |  | ||||||
|       }, |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     Vue.component('modal', Modal); |  | ||||||
|     return null; |  | ||||||
|   }, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default VueModal; |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| module.exports = { |  | ||||||
|   entry: './src/index.js', |  | ||||||
|   output: { |  | ||||||
|     path: './dist', |  | ||||||
|     publicPath: 'dist/', |  | ||||||
|     filename: 'vue-modal.js' |  | ||||||
|   }, |  | ||||||
|   module: { |  | ||||||
|     loaders: [ |  | ||||||
|       { |  | ||||||
|         test: /\.vue$/, |  | ||||||
|         loader: 'vue' |  | ||||||
|       }, |  | ||||||
|       { |  | ||||||
|         test: /\.js$/, |  | ||||||
|         loader: 'babel!eslint', |  | ||||||
|         exclude: /node_modules/ |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   }, |  | ||||||
|   vue: { |  | ||||||
|     loaders: { |  | ||||||
|       js: 'babel!eslint' |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
							
								
								
									
										75
									
								
								webpack.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								webpack.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  |  | ||||||
|  | var path = require('path') | ||||||
|  | var webpack = require('webpack') | ||||||
|  |  | ||||||
|  | module.exports = { | ||||||
|  |   entry: './examples/src/main.js', | ||||||
|  |   output: { | ||||||
|  |     path: path.resolve(__dirname, './dist'), | ||||||
|  |     publicPath: '/dist/', | ||||||
|  |     filename: 'build.js' | ||||||
|  |   }, | ||||||
|  |   externals: [ | ||||||
|  |  | ||||||
|  |   ], | ||||||
|  |   module: { | ||||||
|  |     rules: [ | ||||||
|  |       { | ||||||
|  |         test: /\.vue$/, | ||||||
|  |         loader: 'vue-loader', | ||||||
|  |         options: { | ||||||
|  |           loaders: { | ||||||
|  |             'scss': 'vue-style-loader!css-loader!sass-loader', | ||||||
|  |             'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax' | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         test: /\.js$/, | ||||||
|  |         loader: 'babel-loader', | ||||||
|  |         exclude: /node_modules/ | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         test: /\.(png|jpg|gif|svg)$/, | ||||||
|  |         loader: 'file-loader', | ||||||
|  |         options: { | ||||||
|  |           name: '[name].[ext]?[hash]' | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   resolve: { | ||||||
|  |     alias: { | ||||||
|  |       'vue': 'vue/dist/vue.js', | ||||||
|  |       'nice-vue-components$':  path.resolve(__dirname, './components/index.js') | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   devServer: { | ||||||
|  |     historyApiFallback: true | ||||||
|  |   }, | ||||||
|  |   performance: { | ||||||
|  |     hints: false | ||||||
|  |   }, | ||||||
|  |   devtool: '#eval-source-map' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if (process.env.NODE_ENV === 'production') { | ||||||
|  |   module.exports.devtool = '#source-map' | ||||||
|  |   // http://vue-loader.vuejs.org/en/workflow/production.html | ||||||
|  |   module.exports.plugins = (module.exports.plugins || []).concat([ | ||||||
|  |     new webpack.DefinePlugin({ | ||||||
|  |       'process.env': { | ||||||
|  |         NODE_ENV: '"production"' | ||||||
|  |       } | ||||||
|  |     }), | ||||||
|  |     new webpack.optimize.UglifyJsPlugin({ | ||||||
|  |       sourceMap: true, | ||||||
|  |       compress: { | ||||||
|  |         warnings: false | ||||||
|  |       } | ||||||
|  |     }), | ||||||
|  |     new webpack.LoaderOptionsPlugin({ | ||||||
|  |       minimize: true | ||||||
|  |     }) | ||||||
|  |   ]) | ||||||
|  | } | ||||||
| @@ -1,8 +0,0 @@ | |||||||
| var config = require('./webpack.base.config'); |  | ||||||
|  |  | ||||||
| config.devtool = 'eval-source-map'; |  | ||||||
| config.devServer = { |  | ||||||
|   noInfo: true |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| module.exports = config; |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| var webpack = require('webpack'); |  | ||||||
| var config = require('./webpack.base.config'); |  | ||||||
|  |  | ||||||
| config.plugins = (config.plugins || []).concat([ |  | ||||||
|   new webpack.DefinePlugin({ |  | ||||||
|     'process.env': { |  | ||||||
|       NODE_ENV: '"production"' |  | ||||||
|     } |  | ||||||
|   }), |  | ||||||
|   new webpack.optimize.UglifyJsPlugin({ |  | ||||||
|     compress: { |  | ||||||
|       warnings: false |  | ||||||
|     } |  | ||||||
|   }), |  | ||||||
|   new webpack.optimize.OccurenceOrderPlugin() |  | ||||||
| ]); |  | ||||||
|  |  | ||||||
| module.exports = config; |  | ||||||
		Reference in New Issue
	
	Block a user