├── .babelrc ├── .gitignore ├── License ├── README.md ├── dist ├── vue-img-preview.js └── vue-img-preview.js.map ├── package.json ├── src ├── index.js └── vue-img-preview.vue └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { "modules": false } 5 | }] 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | yarn-error.log 5 | index.html 6 | /dist/vue.min.js 7 | -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Damilola JOEL 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue-img-preview [![npm version](https://badge.fury.io/js/vue-img-preview.svg)](https://badge.fury.io/js/vue-img-preview) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/dameety/vue-image-preview/master/License) [![NPM](https://nodei.co/npm/vue-img-preview.png?downloads=true)](https://nodei.co/npm/vue-img-preview/) 2 | 3 | This is a minimal image preview implementation that does only one thing; give users feedback by showing image chosen from a file input. 4 | 5 | ## looks like this (without the form) 6 | 7 | ![demo](https://cloud.githubusercontent.com/assets/10757330/26514483/148ab3b8-426a-11e7-8bd3-e40465e2509e.jpg) 8 | 9 | 10 | ## Installation 11 | 12 | ``` 13 | npm install vue-img-preview --save 14 | ``` 15 | 16 | ## Import 17 | 18 | ``` 19 | import Vue from 'vue' 20 | import {vueImgPreview} from 'vue-img-preview' 21 | 22 | Vue.component('vue-img-preview', vueImgPreview) 23 | 24 | ``` 25 | 26 | ## Browser Usage 27 | 28 | ``` 29 | 30 | 31 | 32 | 41 | 42 | ``` 43 | 44 | ## Then: 45 | 46 | ``` 47 | 58 | ``` 59 | 60 | ## Or Just: 61 | 62 | ``` 63 | 64 | 65 | ``` 66 | 67 | ## Props 68 | 69 | | Name | Default | Type | Decsription | 70 | |------|:--------:|------|-------------| 71 | | input-name | file |String| name of the file input field 72 | | default-image | |String| an image to display when the component loads before the user clicks the file input 73 | | bg-color | #037B38 |String| background color of the select button 74 | | text-color | #ffffff | String| color of the select text 75 | | alt-text | vue img preview | String| alternative text for the image 76 | | button-text | Choose an image | String| text to show on the button 77 | | picker-style | Regular | String | how the image picker should be displayed. Button-text, text-color & bg-color won't work with this. 78 | -------------------------------------------------------------------------------- /dist/vue-img-preview.js: -------------------------------------------------------------------------------- 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r=t();for(var n in r)("object"==typeof exports?exports:e)[n]=r[n]}}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=2)}([function(e,t,r){r(7);var n=r(5)(r(1),r(6),null,null);e.exports=n.exports},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:{defaultImage:{type:String,default:""},inputName:{type:String,default:"file"},bgColor:{type:String,default:"#037B38"},textColor:{type:String,default:"#ffffff"},altText:{type:String,default:"vue img preview"},buttonText:{type:String,default:"Choose an image"},pickerStyle:{type:String,default:"regular"}},data:function(){return{setImage:null,buttonStyle:{backgroundColor:this.bgColor,color:this.textColor}}},computed:{getSetImage:function(){return null!==this.setImage?this.setImage:this.defaultImage}},methods:{chooseImage:function(e){var t=this,r=e.target.files;if(0===r.length)return void(this.setImage=null);var n=new FileReader;n.onload=function(e){t.setImage=e.target.result},n.readAsDataURL(r[0])}}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=r(0),o=r.n(n);r.d(t,"vueImgPreview",function(){return o.a})},function(e,t,r){t=e.exports=r(4)(),t.push([e.i,"@import url(https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css);",""]),t.push([e.i,".vue-img-preview,.vue-img-preview-container{height:100%;width:100%}.vue-img-preview{margin-bottom:5px}#vue-img-preview-button{margin-top:5px;position:relative;overflow:hidden}#vue-img-preview-button input{width:100%;cursor:pointer;position:absolute;top:0;bottom:0;left:0;right:0;opacity:.001}#vue-img-preview-regular{border:1px solid #ccc}#vue-img-preview-regular input{margin-top:10px;margin-bottom:10px;margin-left:10px}",""])},function(e,t){e.exports=function(){var e=[];return e.toString=function(){for(var e=[],t=0;tr.parts.length&&(n.parts.length=r.parts.length)}else{for(var a=[],o=0;o tag\n\n// load the styles\nvar content = __webpack_require__(3);\nif(typeof content === 'string') content = [[module.i, content, '']];\nif(content.locals) module.exports = content.locals;\n// add the styles to the DOM\nvar update = __webpack_require__(8)(\"403010ae\", content, true);\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n Modified by Evan You @yyx990803\n*/\n\nvar hasDocument = typeof document !== 'undefined'\n\nif (typeof DEBUG !== 'undefined' && DEBUG) {\n if (!hasDocument) {\n throw new Error(\n 'vue-style-loader cannot be used in a non-browser environment. ' +\n \"Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.\"\n ) }\n}\n\nvar listToStyles = __webpack_require__(9)\n\n/*\ntype StyleObject = {\n id: number;\n parts: Array\n}\n\ntype StyleObjectPart = {\n css: string;\n media: string;\n sourceMap: ?string\n}\n*/\n\nvar stylesInDom = {/*\n [id: number]: {\n id: number,\n refs: number,\n parts: Array<(obj?: StyleObjectPart) => void>\n }\n*/}\n\nvar head = hasDocument && (document.head || document.getElementsByTagName('head')[0])\nvar singletonElement = null\nvar singletonCounter = 0\nvar isProduction = false\nvar noop = function () {}\n\n// Force single-tag solution on IE6-9, which has a hard limit on the # of \n\n\n// WEBPACK FOOTER //\n// vue-img-preview.vue?72afef30","exports = module.exports = require(\"../node_modules/css-loader/lib/css-base.js\")();\n// imports\nexports.push([module.id, \"@import url(https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css);\", \"\"]);\n\n// module\nexports.push([module.id, \".vue-img-preview,.vue-img-preview-container{height:100%;width:100%}.vue-img-preview{margin-bottom:5px}#vue-img-preview-button{margin-top:5px;position:relative;overflow:hidden}#vue-img-preview-button input{width:100%;cursor:pointer;position:absolute;top:0;bottom:0;left:0;right:0;opacity:.001}#vue-img-preview-regular{border:1px solid #ccc}#vue-img-preview-regular input{margin-top:10px;margin-bottom:10px;margin-left:10px}\", \"\"]);\n\n// exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader?minimize!./~/vue-loader/lib/style-compiler?{\"id\":\"data-v-43d37150\",\"scoped\":false,\"hasInlineConfig\":false}!./~/vue-loader/lib/selector.js?type=styles&index=0!./src/vue-img-preview.vue\n// module id = 3\n// module chunks = 0","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/css-loader/lib/css-base.js\n// module id = 4\n// module chunks = 0","// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/component-normalizer.js\n// module id = 5\n// module chunks = 0","module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"vue-img-preview-container\"\n }, [(_vm.getSetImage) ? _c('img', {\n staticClass: \"vue-img-preview\",\n attrs: {\n \"src\": _vm.getSetImage,\n \"alt\": _vm.altText\n }\n }) : _vm._e(), _vm._v(\" \"), (_vm.pickerStyle !== 'regular') ? _c('button', {\n style: ([_vm.buttonStyle]),\n attrs: {\n \"id\": \"vue-img-preview-button\"\n }\n }, [_c('input', {\n attrs: {\n \"type\": \"file\",\n \"accept\": \"image/*\",\n \"name\": _vm.inputName\n },\n on: {\n \"change\": _vm.chooseImage\n }\n }), _vm._v(\" \"), _c('span', [_vm._v(_vm._s(_vm.buttonText))])]) : _vm._e(), _vm._v(\" \"), (_vm.pickerStyle === 'regular') ? _c('div', {\n staticClass: \"form-group\"\n }, [_c('input', {\n staticClass: \"form-control\",\n attrs: {\n \"type\": \"file\",\n \"accept\": \"image/*\",\n \"name\": _vm.inputName\n },\n on: {\n \"change\": _vm.chooseImage\n }\n })]) : _vm._e()])\n},staticRenderFns: []}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/vue-loader/lib/template-compiler?{\"id\":\"data-v-43d37150\"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/vue-img-preview.vue\n// module id = 6\n// module chunks = 0","// style-loader: Adds some css to the DOM by adding a -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/index.js', 6 | output: { 7 | path: path.resolve(__dirname, './dist'), 8 | publicPath: '/dist/', 9 | filename: 'vue-img-preview.js', 10 | libraryTarget: 'umd' 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.vue$/, 16 | loader: 'vue-loader', 17 | options: { 18 | loaders: { 19 | } 20 | // other vue-loader options go here 21 | } 22 | }, 23 | { 24 | test: /\.js$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/ 27 | }, 28 | { 29 | test: /\.(png|jpg|gif|svg)$/, 30 | loader: 'file-loader', 31 | options: { 32 | name: '[name].[ext]?[hash]' 33 | } 34 | } 35 | ] 36 | }, 37 | resolve: { 38 | alias: { 39 | 'vue$': 'vue/dist/vue.esm.js' 40 | } 41 | }, 42 | devServer: { 43 | historyApiFallback: true, 44 | noInfo: true 45 | }, 46 | performance: { 47 | hints: false 48 | }, 49 | devtool: '#eval-source-map' 50 | } 51 | 52 | if (process.env.NODE_ENV === 'production') { 53 | module.exports.devtool = '#source-map' 54 | module.exports.plugins = (module.exports.plugins || []).concat([ 55 | new webpack.DefinePlugin({ 56 | 'process.env': { 57 | NODE_ENV: '"production"' 58 | } 59 | }), 60 | new webpack.optimize.UglifyJsPlugin({ 61 | sourceMap: true, 62 | compress: { 63 | warnings: false 64 | } 65 | }), 66 | new webpack.LoaderOptionsPlugin({ 67 | minimize: true 68 | }) 69 | ]) 70 | } 71 | --------------------------------------------------------------------------------