Material ripple
Splash screen
RTL support
RTL mode
Theme settings panel
PAGE LAYOUT
LAYOUT OPTIONS
{{option[1]}}
Fixed navbar
Fixed footer
Reversed
Collapsed sidenav
THEME
NAVBAR BG
{{option}}
SIDENAV BG
{{option}}
FOOTER BG
{{option}}
Vue Starter
{% if settingsPanel -%}
{% endif %} {% if materialRipple %} {% endif %} {%- if materialRipple and not settingsPanel -%} {% endif %} {% if settingsPanel %} {% endif %} {% if splashScreen %}
CompanyName
{% endif %}
'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const path = require('path') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, // cheap-module-eval-source-map is faster for development devtool: config.dev.devtool, // these devServer options should be customized in /config/index.js devServer: { clientLogLevel: 'warning', historyApiFallback: { rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true, contentBase: false, // since we use CopyWebpackPlugin. compress: true, host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser, overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false, publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable, quiet: true, // necessary for FriendlyErrorsPlugin watchOptions: { poll: config.dev.poll, } }, plugins: [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*'] } ]) ] }) {% if settingsPanel %} {% set tabs = ' ' %} {% else %} {% set tabs = '' %} {% endif %} {% if not settingsPanel %}module.exports = {% else %}module.exports = Promise.all([ {% endif %}new Promise((resolve, reject) => { {{tabs}} portfinder.basePort = process.env.PORT || config.dev.port {{tabs}} portfinder.getPort((err, port) => { {{tabs}} if (err) { {{tabs}} reject(err) {{tabs}} } else { {{tabs}} // publish the new Port, necessary for e2e tests {{tabs}} process.env.PORT = port {{tabs}} // add port to devServer config {{tabs}} devWebpackConfig.devServer.port = port {{tabs}} // Add FriendlyErrorsPlugin {{tabs}} devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ {{tabs}} compilationSuccessInfo: { {{tabs}} messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], {{tabs}} }, {{tabs}} onErrors: config.dev.notifyOnErrors {{tabs}} ? utils.createNotifierCallback() {{tabs}} : undefined {{tabs}} })) {{tabs}} {{tabs}} resolve(devWebpackConfig) {{tabs}} } {{tabs}} }) {{tabs}}}){% if settingsPanel %}, require('./webpack.static.conf') ]) {% endif %}
'use strict' const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const env = require('../config/prod.env') const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), // Setting the following option to `false` will not extract CSS from codesplit chunks. // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 allChunks: true, }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), // enable scope hoisting new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } {% if settingsPanel %} module.exports = [webpackConfig, require('./webpack.static.conf')] {% else %} module.exports = webpackConfig {% endif %}
'use strict' const path = require('path') const webpack = require('webpack') const utils = require('./utils') const config = require('../config') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') function resolve (dir) { return path.join(__dirname, '..', dir) } const env = process.env.NODE_ENV === 'production' ? config.build.env : config.dev.env const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const loaderOptions = { minimize: process.env.NODE_ENV === 'production', sourceMap: process.env.NODE_ENV === 'production' ? config.build.productionSourceMap : config.dev.cssSourceMap } const assetsRoot = config.build.assetsRoot const publicPath = process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath const filename = process.env.NODE_ENV === 'production' ? '[name].css' : '[name].js' const webpackConfig = { entry: { 'appwork': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/appwork.scss', 'appwork-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/appwork-material.scss', 'bootstrap': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/bootstrap.scss', 'bootstrap-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/bootstrap-material.scss', 'colors': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/colors.scss', 'colors-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/colors-material.scss', 'uikit': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/uikit.scss', 'theme-air': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-air.scss', 'theme-air-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-air-material.scss', 'theme-corporate': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-corporate.scss', 'theme-corporate-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-corporate-material.scss', 'theme-cotton': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-cotton.scss', 'theme-cotton-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-cotton-material.scss', 'theme-gradient': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-gradient.scss', 'theme-gradient-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-gradient-material.scss', 'theme-paper': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-paper.scss', 'theme-paper-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-paper-material.scss', 'theme-shadow': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-shadow.scss', 'theme-shadow-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-shadow-material.scss', 'theme-soft': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-soft.scss', 'theme-soft-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-soft-material.scss', 'theme-sunrise': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-sunrise.scss', 'theme-sunrise-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-sunrise-material.scss', 'theme-twitlight': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-twitlight.scss', 'theme-twitlight-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-twitlight-material.scss', 'theme-vibrant': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-vibrant.scss', 'theme-vibrant-material': './src/vendor/styles{% if rtlSupport %}/rtl{% endif %}/theme-vibrant-material.scss' }, output: { path: path.posix.join(assetsRoot, utils.assetsPath('vendor/styles')), publicPath: path.posix.join(publicPath, utils.assetsPath('vendor/styles')), filename: filename }, module: { rules: [{ test: /\.scss$/, use: ExtractTextPlugin.extract({ use: [{ loader: 'css-loader', options: { minimize: loaderOptions.minimize, sourceMap: loaderOptions.sourceMap } }, { loader: 'postcss-loader', options: { sourceMap: loaderOptions.sourceMap } }, { loader: 'sass-loader', options: { sourceMap: loaderOptions.sourceMap } }], fallback: 'style-loader' }) }] }, plugins: [ new webpack.DefinePlugin({ 'process.env': env }), new ExtractTextPlugin({ filename: '[name].css' }), ], resolve: { extensions: ['.scss', '.css', '.js', '.json'], alias: { '@': resolve('src'), 'node_modules': resolve('node_modules') } } } if (process.env.NODE_ENV === 'production') { webpackConfig.devtool = config.build.productionSourceMap ? config.build.devtool : false webpackConfig.plugins.push( new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }) ) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } } else { webpackConfig.devtool = config.dev.devtool webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin()) webpackConfig.plugins.push(new webpack.NamedModulesPlugin()) webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin()) } if (process.env.NODE_ENV === 'development') { const portfinder = require('portfinder') module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { // Add FriendlyErrorsPlugin webpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${HOST || config.dev.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(webpackConfig) } }) }) } else { module.exports = webpackConfig }
import layoutHelpers from '@/layout/helpers.js' {% if settingsPanel -%} import themeSettings from '@/vendor/libs/theme-settings/theme-settings.js' {%- endif %} export default function () { return { // Layout helpers layoutHelpers, {% if settingsPanel -%} // Theme settings themeSettings, {%- endif %} // Check for RTL layout get isRTL () { return document.documentElement.getAttribute('dir') === 'rtl' || document.body.getAttribute('dir') === 'rtl' }, // Check if IE get isIE () { return typeof document['documentMode'] === 'number' }, // Check if IE10 get isIE10 () { return this.isIE && document['documentMode'] === 10 }, // Layout navbar color get layoutNavbarBg () { {% if settingsPanel -%} return this.themeSettings.getOption('navbarBg') || '{{navbarBg}}' {%- else -%} return '{{navbarBg}}' {%- endif %} }, // Layout sidenav color get layoutSidenavBg () { {% if settingsPanel -%} return this.themeSettings.getOption('sidenavBg') || '{{sidenavBg}}' {%- else -%} return '{{sidenavBg}}' {%- endif %} }, // Layout footer color get layoutFooterBg () { {% if settingsPanel -%} return this.themeSettings.getOption('footerBg') || '{{footerBg}}' {%- else -%} return '{{footerBg}}' {%- endif %} }, // Animate scrollTop scrollTop (to, duration, element = document.scrollingElement || document.documentElement) { if (element.scrollTop === to) return const start = element.scrollTop const change = to - start const startDate = +new Date() // t = current time; b = start value; c = change in value; d = duration const easeInOutQuad = (t, b, c, d) => { t /= d / 2 if (t < 1) return c / 2 * t * t + b t-- return -c / 2 * (t * (t - 2) - 1) + b } const animateScroll = () => { const currentDate = +new Date() const currentTime = currentDate - startDate element.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration)) if (currentTime < duration) { requestAnimationFrame(animateScroll) } else { element.scrollTop = to } } animateScroll() } } }
import Vue from 'vue' import Router from 'vue-router' import Meta from 'vue-meta' import globals from '@/globals' // Layouts import {{layoutClass(pageLayout)}} from '@/layout/{{layoutClass(pageLayout)}}' Vue.use(Router) Vue.use(Meta) const router = new Router({ base: '/', mode: 'history', routes: [{ path: '/', component: {{layoutClass(pageLayout)}}, children: [{ path: '', component: () => import('@/components/Home') }, { path: 'page-2', component: () => import('@/components/Page2') }] }] }) router.afterEach(() => { {% if splashScreen -%} // Remove initial splash screen const splashScreen = document.querySelector('.app-splash-screen') if (splashScreen) { splashScreen.style.opacity = 0 setTimeout(() => splashScreen && splashScreen.parentNode.removeChild(splashScreen), 300) } {% endif -%} // On small screens collapse sidenav if (window.layoutHelpers && window.layoutHelpers.isSmallScreen() && !window.layoutHelpers.isCollapsed()) { setTimeout(() => window.layoutHelpers.setCollapsed(true, true), 10) } // Scroll to top of the page globals().scrollTop(0, 0) }) router.beforeEach((to, from, next) => { // Set loading state document.body.classList.add('app-loading') // Add tiny timeout to finish page transition setTimeout(() => next(), 10) }) export default router
{% if not settingsPanel -%} {%- endif %}