├── .gitignore ├── LICENSE.md ├── package.json ├── readme.md ├── src └── Flash.vue ├── webpack.config.js └── webpack.mix.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | .DS_Store 4 | mix-manifest.json 5 | demo/app.js 6 | demo -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Andrew Leach 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": "vue-flash", 3 | "description": "A Vue.js flash component heavily inspired by Jeffrey Way of Laracasts", 4 | "version": "2.1.3", 5 | "main": "src/Flash.vue", 6 | "repository": "andyleach/Vue-Flash", 7 | "author": "andyleach", 8 | "devDependencies": { 9 | "laravel-mix": "^0.11.4" 10 | }, 11 | "scripts": { 12 | "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules", 13 | "watch": "cross-env NODE_ENV=development webpack --watch --progress --hide-modules", 14 | "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot", 15 | "production": "cross-env NODE_ENV=production webpack --progress --hide-modules" 16 | }, 17 | "dependencies": { 18 | "vue": "^2.6.10" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Vue Flash 2 |

Heavily based upon the work by Jeffrey Way at Laracasts. 3 | If you are interested in learning more about the lesson this package is based upon you 4 | may view it in his Let's 5 | Build A Forum With Laravel course. I highly recommend anyone interested in Vue or Laravel subscribe to Laracasts, it's the best $9 a month you can spend.

6 | 7 |

Demo

8 | 9 | ## Setup 10 | 11 | ```javascript 12 | /** 13 | * Vue is a modern JavaScript library for building interactive web interfaces 14 | * using reactive data binding and reusable components. Vue's API is clean 15 | * and simple, leaving you to focus on building your next great project. 16 | */ 17 | window.Vue = require('vue/dist/vue.js'); 18 | 19 | /** 20 | * Our Vuejs event handler which we will be using for flash messaging 21 | * @type {Vue} 22 | */ 23 | window.events = new Vue(); 24 | 25 | /** 26 | * Our Flash function which will be used to add new flash events to our event handler 27 | * 28 | * @param String message Our alert message 29 | * @param String type The type of alert we want to show 30 | */ 31 | window.flash = function(message, type) { 32 | window.events.$emit('flash', message, type); 33 | }; 34 | 35 | Vue.component('flash', require('vue-flash')); 36 | 37 | var app = new Vue({ 38 | el: '#app', 39 | }).$mount(); 40 | ``` 41 | 42 | ## Usage 43 | 44 | ```javascript 45 | flash('Hello World', 'success'); 46 | flash('Hello World', 'error'); 47 | flash('Hello World', 'warning'); 48 | flash('Hello World', 'info'); 49 | ``` 50 | 51 | ### Customizing Alert Classes 52 |

By default, Vue-Flash uses the alert classes from Twitter Boostrap, however it also supports the ability to integrate with the css framework of your choice using the types prop. Using this prop you can assign alert classes to a specific alert type as an object as example of which can be found below.

53 | 54 | ```javascript 55 | { 56 | base: 'alert', 57 | success: 'alert-success', 58 | error: 'alert-danger', 59 | warning: 'alert-warning', 60 | info: 'alert-info' 61 | } 62 | ``` 63 | 64 | ### Supporting Icon Libraries 65 |

By default, Vue-Flash does not include any icon libraries because I wish to keep dependencies to an absolute minimum so that the user of the package can decide what to include and what to not include. If however you desire to include a icon library this feature can be turned on if you set the displayIcons(:display-icons="true") property to true. Default values for what icons(Font Awesome) are used for a alert type have been preset to for success, error, warning and info. If you wish to set your own you can use the same format as when setting alert classes. See below for an example: 66 | 67 | ```javascript 68 | { 69 | base: 'fa', 70 | success: 'fa-check-circle', 71 | error: 'fa-exclamation-circle', 72 | warning: 'fa-exclamation-circle', 73 | info: 'fa-info-circle' 74 | } 75 | ``` 76 | 77 | ### Props 78 | 79 | | Name | Type | Default | Restrictions | 80 | |------------|---------|----------------|-------------------------------| 81 | | timeout | Number | 3000 | | 82 | | transition | String | slide-fade | fade, slide-fade, bounce | 83 | | types | Object | See above | | 84 | | icons | Object | See above | | 85 | ## License 86 |

Vue-Flash is open-sourced software licensed under the MIT license.

87 | -------------------------------------------------------------------------------- /src/Flash.vue: -------------------------------------------------------------------------------- 1 | 10 | 110 | 164 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | let path = require('path'); 2 | let glob = require('glob'); 3 | let webpack = require('webpack'); 4 | let Mix = require('laravel-mix').config; 5 | let webpackPlugins = require('laravel-mix').plugins; 6 | 7 | /* 8 | |-------------------------------------------------------------------------- 9 | | Mix Initialization 10 | |-------------------------------------------------------------------------- 11 | | 12 | | As our first step, we'll require the project's Laravel Mix file 13 | | and record the user's requested compilation and build steps. 14 | | Once those steps have been recorded, we may get to work. 15 | | 16 | */ 17 | 18 | Mix.initialize(); 19 | 20 | 21 | 22 | /* 23 | |-------------------------------------------------------------------------- 24 | | Webpack Context 25 | |-------------------------------------------------------------------------- 26 | | 27 | | This prop will determine the appropriate context, when running Webpack. 28 | | Since you have the option of publishing this webpack.config.js file 29 | | to your project root, we will dynamically set the path for you. 30 | | 31 | */ 32 | 33 | module.exports.context = Mix.Paths.root(); 34 | 35 | 36 | 37 | /* 38 | |-------------------------------------------------------------------------- 39 | | Webpack Entry 40 | |-------------------------------------------------------------------------- 41 | | 42 | | We'll first specify the entry point for Webpack. By default, we'll 43 | | assume a single bundled file, but you may call Mix.extract() 44 | | to make a separate bundle specifically for vendor libraries. 45 | | 46 | */ 47 | 48 | module.exports.entry = Mix.entry().get(); 49 | 50 | 51 | 52 | /* 53 | |-------------------------------------------------------------------------- 54 | | Webpack Output 55 | |-------------------------------------------------------------------------- 56 | | 57 | | Webpack naturally requires us to specify our desired output path and 58 | | file name. We'll simply echo what you passed to with Mix.js(). 59 | | Note that, for Mix.version(), we'll properly hash the file. 60 | | 61 | */ 62 | 63 | module.exports.output = Mix.output(); 64 | 65 | 66 | 67 | /* 68 | |-------------------------------------------------------------------------- 69 | | Rules 70 | |-------------------------------------------------------------------------- 71 | | 72 | | Webpack rules allow us to register any number of loaders and options. 73 | | Out of the box, we'll provide a handful to get you up and running 74 | | as quickly as possible, though feel free to add to this list. 75 | | 76 | */ 77 | 78 | let plugins = []; 79 | 80 | if (Mix.options.extractVueStyles) { 81 | var vueExtractTextPlugin = Mix.vueExtractTextPlugin(); 82 | 83 | plugins.push(vueExtractTextPlugin); 84 | } 85 | 86 | let rules = [ 87 | { 88 | test: /\.vue$/, 89 | loader: 'vue-loader', 90 | options: { 91 | loaders: Mix.options.extractVueStyles ? { 92 | js: 'babel-loader' + Mix.babelConfig(), 93 | scss: vueExtractTextPlugin.extract({ 94 | use: 'css-loader!sass-loader', 95 | fallback: 'vue-style-loader' 96 | }), 97 | sass: vueExtractTextPlugin.extract({ 98 | use: 'css-loader!sass-loader?indentedSyntax', 99 | fallback: 'vue-style-loader' 100 | }), 101 | stylus: vueExtractTextPlugin.extract({ 102 | use: 'css-loader!stylus-loader?paths[]=node_modules', 103 | fallback: 'vue-style-loader' 104 | }), 105 | css: vueExtractTextPlugin.extract({ 106 | use: 'css-loader', 107 | fallback: 'vue-style-loader' 108 | }) 109 | }: { 110 | js: 'babel-loader' + Mix.babelConfig(), 111 | scss: 'vue-style-loader!css-loader!sass-loader', 112 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax', 113 | stylus: 'vue-style-loader!css-loader!stylus-loader?paths[]=node_modules' 114 | }, 115 | 116 | postcss: Mix.options.postCss 117 | } 118 | }, 119 | 120 | { 121 | test: /\.jsx?$/, 122 | exclude: /(node_modules|bower_components)/, 123 | loader: 'babel-loader' + Mix.babelConfig() 124 | }, 125 | 126 | { 127 | test: /\.css$/, 128 | loaders: ['style-loader', 'css-loader'] 129 | }, 130 | 131 | { 132 | test: /\.s[ac]ss$/, 133 | include: /node_modules/, 134 | loaders: ['style-loader', 'css-loader', 'sass-loader'] 135 | }, 136 | 137 | { 138 | test: /\.html$/, 139 | loaders: ['html-loader'] 140 | }, 141 | 142 | { 143 | test: /\.(png|jpe?g|gif)$/, 144 | loaders: [ 145 | { 146 | loader: 'file-loader', 147 | options: { 148 | name: path => { 149 | if (! /node_modules|bower_components/.test(path)) { 150 | return 'images/[name].[ext]?[hash]'; 151 | } 152 | 153 | return 'images/vendor/' + path 154 | .replace(/\\/g, '/') 155 | .replace( 156 | /((.*(node_modules|bower_components))|images|image|img|assets)\//g, '' 157 | ) + '?[hash]'; 158 | }, 159 | publicPath: Mix.options.resourceRoot 160 | } 161 | }, 162 | 'img-loader' 163 | ] 164 | }, 165 | 166 | { 167 | test: /\.(woff2?|ttf|eot|svg|otf)$/, 168 | loader: 'file-loader', 169 | options: { 170 | name: path => { 171 | if (! /node_modules|bower_components/.test(path)) { 172 | return 'fonts/[name].[ext]?[hash]'; 173 | } 174 | 175 | return 'fonts/vendor/' + path 176 | .replace(/\\/g, '/') 177 | .replace( 178 | /((.*(node_modules|bower_components))|fonts|font|assets)\//g, '' 179 | ) + '?[hash]'; 180 | }, 181 | publicPath: Mix.options.resourceRoot 182 | } 183 | }, 184 | 185 | { 186 | test: /\.(cur|ani)$/, 187 | loader: 'file-loader', 188 | options: { 189 | name: '[name].[ext]?[hash]', 190 | publicPath: Mix.options.resourceRoot 191 | } 192 | } 193 | ]; 194 | 195 | if (Mix.preprocessors) { 196 | Mix.preprocessors.forEach(preprocessor => { 197 | rules.push(preprocessor.rules()); 198 | 199 | plugins.push(preprocessor.extractPlugin); 200 | }); 201 | } 202 | 203 | module.exports.module = { rules }; 204 | 205 | 206 | 207 | /* 208 | |-------------------------------------------------------------------------- 209 | | Resolve 210 | |-------------------------------------------------------------------------- 211 | | 212 | | Here, we may set any options/aliases that affect Webpack's resolving 213 | | of modules. To begin, we will provide the necessary Vue alias to 214 | | load the Vue common library. You may delete this, if needed. 215 | | 216 | */ 217 | 218 | module.exports.resolve = { 219 | extensions: ['*', '.js', '.jsx', '.vue'], 220 | 221 | alias: { 222 | 'vue$': 'vue/dist/vue.common.js' 223 | } 224 | }; 225 | 226 | 227 | 228 | /* 229 | |-------------------------------------------------------------------------- 230 | | Stats 231 | |-------------------------------------------------------------------------- 232 | | 233 | | By default, Webpack spits a lot of information out to the terminal, 234 | | each you time you compile. Let's keep things a bit more minimal 235 | | and hide a few of those bits and pieces. Adjust as you wish. 236 | | 237 | */ 238 | 239 | module.exports.stats = { 240 | hash: false, 241 | version: false, 242 | timings: false, 243 | children: false, 244 | errors: false 245 | }; 246 | 247 | process.noDeprecation = true; 248 | 249 | module.exports.performance = { hints: false }; 250 | 251 | 252 | 253 | /* 254 | |-------------------------------------------------------------------------- 255 | | Devtool 256 | |-------------------------------------------------------------------------- 257 | | 258 | | Sourcemaps allow us to access our original source code within the 259 | | browser, even if we're serving a bundled script or stylesheet. 260 | | You may activate sourcemaps, by adding Mix.sourceMaps(). 261 | | 262 | */ 263 | 264 | module.exports.devtool = Mix.options.sourcemaps; 265 | 266 | 267 | 268 | /* 269 | |-------------------------------------------------------------------------- 270 | | Webpack Dev Server Configuration 271 | |-------------------------------------------------------------------------- 272 | | 273 | | If you want to use that flashy hot module replacement feature, then 274 | | we've got you covered. Here, we'll set some basic initial config 275 | | for the Node server. You very likely won't want to edit this. 276 | | 277 | */ 278 | module.exports.devServer = { 279 | historyApiFallback: true, 280 | noInfo: true, 281 | compress: true, 282 | quiet: true 283 | }; 284 | 285 | 286 | 287 | /* 288 | |-------------------------------------------------------------------------- 289 | | Plugins 290 | |-------------------------------------------------------------------------- 291 | | 292 | | Lastly, we'll register a number of plugins to extend and configure 293 | | Webpack. To get you started, we've included a handful of useful 294 | | extensions, for versioning, OS notifications, and much more. 295 | | 296 | */ 297 | 298 | plugins.push( 299 | new webpack.ProvidePlugin(Mix.autoload || {}), 300 | 301 | new webpackPlugins.FriendlyErrorsWebpackPlugin({ clearConsole: Mix.options.clearConsole }), 302 | 303 | new webpackPlugins.StatsWriterPlugin({ 304 | filename: 'mix-manifest.json', 305 | transform: Mix.manifest.transform.bind(Mix.manifest), 306 | }), 307 | 308 | new webpack.LoaderOptionsPlugin({ 309 | minimize: Mix.inProduction, 310 | options: { 311 | postcss: Mix.options.postCss, 312 | context: __dirname, 313 | output: { path: './' } 314 | } 315 | }) 316 | ); 317 | 318 | if (Mix.browserSync) { 319 | plugins.push( 320 | new webpackPlugins.BrowserSyncPlugin( 321 | Object.assign({ 322 | host: 'localhost', 323 | port: 3000, 324 | proxy: 'app.dev', 325 | files: [ 326 | 'app/**/*.php', 327 | 'resources/views/**/*.php', 328 | 'public/js/**/*.js', 329 | 'public/css/**/*.css' 330 | ] 331 | }, Mix.browserSync), 332 | { 333 | reload: false 334 | } 335 | ) 336 | ); 337 | } 338 | 339 | if (Mix.options.notifications) { 340 | plugins.push( 341 | new webpackPlugins.WebpackNotifierPlugin({ 342 | title: 'Laravel Mix', 343 | alwaysNotify: true, 344 | contentImage: Mix.Paths.root('node_modules/laravel-mix/icons/laravel.png') 345 | }) 346 | ); 347 | } 348 | 349 | if (Mix.copy) { 350 | Mix.copy.forEach(copy => { 351 | plugins.push( 352 | new webpackPlugins.CopyWebpackPlugin([copy]) 353 | ); 354 | }); 355 | } 356 | 357 | if (Mix.entry().hasExtractions()) { 358 | plugins.push( 359 | new webpack.optimize.CommonsChunkPlugin({ 360 | names: Mix.entry().getExtractions(), 361 | minChunks: Infinity 362 | }) 363 | ); 364 | } 365 | 366 | if (Mix.options.versioning) { 367 | plugins.push( 368 | new webpack[Mix.inProduction ? 'HashedModuleIdsPlugin': 'NamedModulesPlugin'](), 369 | new webpackPlugins.WebpackChunkHashPlugin() 370 | ); 371 | } 372 | 373 | if (Mix.options.purifyCss) { 374 | let PurifyCSSPlugin = require('purifycss-webpack'); 375 | 376 | // By default, we'll scan all Blade and Vue files in our project. 377 | let paths = glob.sync(Mix.Paths.root('resources/views/**/*.blade.php')).concat( 378 | Mix.entry().scripts.reduce((carry, js) => { 379 | return carry.concat(glob.sync(js.base + '/**/*.vue')); 380 | }, []) 381 | ); 382 | 383 | plugins.push(new PurifyCSSPlugin( 384 | Object.assign({ paths }, Mix.options.purifyCss, { minimize: Mix.inProduction }) 385 | )); 386 | } 387 | 388 | if (Mix.inProduction) { 389 | plugins.push( 390 | new webpack.DefinePlugin({ 391 | 'process.env': { 392 | NODE_ENV: '"production"' 393 | } 394 | }) 395 | ); 396 | 397 | if (Mix.options.uglify) { 398 | plugins.push( 399 | new webpack.optimize.UglifyJsPlugin(Mix.options.uglify) 400 | ); 401 | } 402 | } 403 | 404 | plugins.push( 405 | new webpackPlugins.WebpackOnBuildPlugin( 406 | stats => global.events.fire('build', stats) 407 | ) 408 | ); 409 | 410 | if (! Mix.entry().hasScripts()) { 411 | plugins.push(new webpackPlugins.MockEntryPlugin(Mix.output().path)); 412 | } 413 | 414 | module.exports.plugins = plugins; 415 | 416 | 417 | 418 | /* 419 | |-------------------------------------------------------------------------- 420 | | Mix Finalizing 421 | |-------------------------------------------------------------------------- 422 | | 423 | | Now that we've declared the entirety of our Webpack configuration, the 424 | | final step is to scan for any custom configuration in the Mix file. 425 | | If mix.webpackConfig() is called, we'll merge it in, and build! 426 | | 427 | */ 428 | 429 | if (Mix.webpackConfig) { 430 | module.exports = require('webpack-merge').smart( 431 | module.exports, Mix.webpackConfig 432 | ); 433 | } -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel application. By default, we are compiling the Sass 10 | | file for your application, as well as bundling up your JS files. 11 | | 12 | */ 13 | mix.js('demo/src/app.js', 'demo'); 14 | --------------------------------------------------------------------------------