diff --git a/.babelrc b/.babelrc index d5876c1..eaf3238 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,3 @@ { - "presets": ["es2015", "stage-0"], - "plugins": ["transform-runtime"] + "presets": ["es2015", "stage-0"] } diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 34af377..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -build/*.js -config/*.js diff --git a/.eslintrc b/.eslintrc index 80fd083..610dc10 100644 --- a/.eslintrc +++ b/.eslintrc @@ -28,9 +28,9 @@ "arguments": true, "window": true }, - root: true, - parserOptions: { - sourceType: 'module' + "root": true, + "parserOptions": { + "sourceType": "module" }, "parser": "babel-eslint", "rules": { diff --git a/.gitignore b/.gitignore index be86a2b..33fee71 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .DS_Store node_modules/ -dist/ npm-debug.log selenium-debug.log test/unit/coverage diff --git a/TODO.md b/TODO.md deleted file mode 100644 index f5355bf..0000000 --- a/TODO.md +++ /dev/null @@ -1,3 +0,0 @@ -## TODO LIST - -Moved to GitHub Projects diff --git a/build/build.js b/build/build.js deleted file mode 100644 index 374f19e..0000000 --- a/build/build.js +++ /dev/null @@ -1,34 +0,0 @@ -// https://github.com/shelljs/shelljs -require('shelljs/global') -env.NODE_ENV = 'production' - -var path = require('path') -var config = require('../config') -var ora = require('ora') -var webpack = require('webpack') -var webpackConfig = require('./webpack.prod.conf') - -console.log( - ' Tip:\n' + - ' Built files are meant to be served over an HTTP server.\n' + - ' Opening index.html over file:// won\'t work.\n' -) - -var spinner = ora('building for production...') -spinner.start() - -var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) -rm('-rf', assetsPath) -mkdir('-p', assetsPath) - -webpack(webpackConfig, function (err, stats) { - spinner.stop() - if (err) throw err - process.stdout.write(stats.toString({ - colors: true, - modules: false, - children: false, - chunks: false, - chunkModules: false - }) + '\n') -}) diff --git a/build/config.js b/build/config.js new file mode 100644 index 0000000..f89a0b7 --- /dev/null +++ b/build/config.js @@ -0,0 +1,34 @@ +import path from 'path'; + +const config = { + projectRoot: path.resolve(__dirname, '../'), + rootPath: path.resolve(__dirname, '../dist'), + nodePath: path.resolve(__dirname, '../node_modules'), + docsPath: 'docs', + indexPath: 'docs/index.html', + publicPath: '/', + assetsPath: '/' +}; + +let dev = { + server: { + port: process.env.PORT || '8080' + }, + env: { + NODE_ENV: '"development"' + } +}; + +let prod = { + env: { + NODE_ENV: '"production"' + } +}; + +if (config.env === 'production') { + Object.assign(config, prod); +} else { + Object.assign(config, dev); +} + +export default config; diff --git a/build/dev-client.js b/build/dev-client.js deleted file mode 100644 index 18aa1e2..0000000 --- a/build/dev-client.js +++ /dev/null @@ -1,9 +0,0 @@ -/* eslint-disable */ -require('eventsource-polyfill') -var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') - -hotClient.subscribe(function (event) { - if (event.action === 'reload') { - window.location.reload() - } -}) diff --git a/build/dev-server.js b/build/dev-server.js deleted file mode 100644 index 3833a2a..0000000 --- a/build/dev-server.js +++ /dev/null @@ -1,65 +0,0 @@ -var path = require('path') -var express = require('express') -var webpack = require('webpack') -var config = require('../config') -var proxyMiddleware = require('http-proxy-middleware') -var webpackConfig = process.env.NODE_ENV === 'testing' - ? require('./webpack.prod.conf') - : require('./webpack.dev.conf') - -// default port where dev server listens for incoming traffic -var port = process.env.PORT || config.dev.port -// Define HTTP proxies to your custom API backend -// https://github.com/chimurai/http-proxy-middleware -var proxyTable = config.dev.proxyTable - -var app = express() -var compiler = webpack(webpackConfig) - -var devMiddleware = require('webpack-dev-middleware')(compiler, { - publicPath: webpackConfig.output.publicPath, - stats: { - colors: true, - chunks: false - } -}) - -var hotMiddleware = require('webpack-hot-middleware')(compiler) -// force page reload when html-webpack-plugin template changes -compiler.plugin('compilation', function (compilation) { - compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { - hotMiddleware.publish({ action: 'reload' }) - cb() - }) -}) - -// proxy api requests -Object.keys(proxyTable).forEach(function (context) { - var options = proxyTable[context] - if (typeof options === 'string') { - options = { target: options } - } - app.use(proxyMiddleware(context, options)) -}) - -// handle fallback for HTML5 history API -app.use(require('connect-history-api-fallback')()) - -// serve webpack bundle output -app.use(devMiddleware) - -// enable hot-reload and state-preserving -// compilation error display -app.use(hotMiddleware) - -// serve pure static assets -var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) -app.use(staticPath, express.static('./static')) - -module.exports = app.listen(port, function (err) { - if (err) { - console.log(err) - return - } - console.log('Listening at http://localhost:' + port + '\n') -}) diff --git a/build/server/build-docs.js b/build/server/build-docs.js new file mode 100644 index 0000000..38f388d --- /dev/null +++ b/build/server/build-docs.js @@ -0,0 +1,5 @@ +import webpack from 'webpack'; +import build from './build'; +import webpackConfig from '../webpack/prod-docs'; + +webpack(webpackConfig, build); diff --git a/build/server/build-lib.js b/build/server/build-lib.js new file mode 100644 index 0000000..289665e --- /dev/null +++ b/build/server/build-lib.js @@ -0,0 +1,5 @@ +import webpack from 'webpack'; +import build from './build'; +import webpackConfig from '../webpack/prod-lib'; + +webpack(webpackConfig, build); diff --git a/build/server/build.js b/build/server/build.js new file mode 100644 index 0000000..4e8e9f7 --- /dev/null +++ b/build/server/build.js @@ -0,0 +1,25 @@ +import ora from 'ora'; + +const spinner = ora({ + text: 'Building...', + spinner: 'circleQuarters', + color: 'green' +}); + +spinner.start(); + +export default function done(error, stats) { + if (error) { + throw error; + } + + process.stdout.write('\n\n' + stats.toString({ + colors: true, + modules: false, + children: false, + chunks: false, + chunkModules: false + }) + '\n'); + + spinner.stop(); +} diff --git a/build/server/client.js b/build/server/client.js new file mode 100644 index 0000000..19e8258 --- /dev/null +++ b/build/server/client.js @@ -0,0 +1,8 @@ +import 'eventsource-polyfill'; +import hotClient from 'webpack-hot-middleware/client?noInfo=true&reload=true'; + +hotClient.subscribe((event) => { + if (event.action === 'reload') { + window.location.reload(); + } +}); diff --git a/build/server/index.js b/build/server/index.js new file mode 100644 index 0000000..bc7ad10 --- /dev/null +++ b/build/server/index.js @@ -0,0 +1,51 @@ +import path from 'path'; +import express from 'express'; +import chalk from 'chalk'; +import webpack from 'webpack'; +import devMiddleware from 'webpack-dev-middleware'; +import hotMiddleware from 'webpack-hot-middleware'; +import historyApiFallback from 'connect-history-api-fallback'; +import config from '../config'; +import webpackConfig from '../webpack/dev'; + + +const app = express(); +const compiler = webpack(webpackConfig); +const devMiddlewareInstance = devMiddleware(compiler, { + publicPath: config.publicPath, + index: config.indexPath, + stats: { + colors: true, + chunks: false + } +}); + +const hotMiddlewareInstance = hotMiddleware(compiler); + +compiler.plugin('compilation', (compilation) => { + compilation.plugin('html-webpack-plugin-after-emit', (data, done) => { + hotMiddlewareInstance.publish({ action: 'reload' }); + done(); + }); +}); + +app.use(historyApiFallback()); +app.use(devMiddlewareInstance); +app.use(hotMiddlewareInstance); +app.use(express.static(__dirname + config.devPath)); + +app.get('*', function(req, res) { + res.sendFile(path.join(__dirname, 'index.html')); +}); + +export default app.listen(config.server.port, (error) => { + let uri = 'http://localhost:' + config.server.port; + + if (error) { + console.log(chalk.red(error)); + + return; + } + + console.log(chalk.blue('Listening at ' + uri + '\n')); +}); diff --git a/build/utils.js b/build/utils.js deleted file mode 100644 index d294e35..0000000 --- a/build/utils.js +++ /dev/null @@ -1,56 +0,0 @@ -var path = require('path') -var config = require('../config') -var ExtractTextPlugin = require('extract-text-webpack-plugin') - -exports.assetsPath = function (_path) { - return path.posix.join(config.build.assetsSubDirectory, _path) -} - -exports.cssLoaders = function (options) { - options = options || {} - // generate loader string to be used with extract text plugin - function generateLoaders (loaders) { - var sourceLoader = loaders.map(function (loader) { - var extraParamChar - if (/\?/.test(loader)) { - loader = loader.replace(/\?/, '-loader?') - extraParamChar = '&' - } else { - loader = loader + '-loader' - extraParamChar = '?' - } - return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') - }).join('!') - - if (options.extract) { - return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) - } else { - return ['vue-style-loader', sourceLoader].join('!') - } - } - - // http://vuejs.github.io/vue-loader/configurations/extract-css.html - return { - css: generateLoaders(['css']), - postcss: generateLoaders(['css']), - less: generateLoaders(['css', 'less']), - sass: generateLoaders(['css', 'sass?indentedSyntax']), - scss: generateLoaders(['css', 'sass']), - stylus: generateLoaders(['css', 'stylus']), - styl: generateLoaders(['css', 'stylus']) - } -} - -// Generate loaders for standalone style files (outside of .vue) -exports.styleLoaders = function (options) { - var output = [] - var loaders = exports.cssLoaders(options) - for (var extension in loaders) { - var loader = loaders[extension] - output.push({ - test: new RegExp('\\.' + extension + '$'), - loader: loader - }) - } - return output -} diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js deleted file mode 100644 index 63ecd80..0000000 --- a/build/webpack.base.conf.js +++ /dev/null @@ -1,90 +0,0 @@ -var path = require('path'); -var config = require('../config'); -var utils = require('./utils'); -var projectRoot = path.resolve(__dirname, '../'); - -module.exports = { - entry: { - app: './src/docs/index.js' - }, - output: { - path: config.build.assetsRoot, - publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, - filename: '[name].js' - }, - resolve: { - extensions: ['', '.js', '.vue'], - fallback: [path.join(__dirname, '../node_modules')], - alias: { - src: path.resolve(__dirname, '../src'), - assets: path.resolve(__dirname, '../src/assets'), - components: path.resolve(__dirname, '../src/components') - } - }, - resolveLoader: { - fallback: [path.join(__dirname, '../node_modules')] - }, - module: { - preLoaders: [ - { - test: /\.vue$/, - loader: 'eslint', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.js$/, - loader: 'eslint', - include: projectRoot, - exclude: /node_modules/ - } - ], - loaders: [ - { - test: /\.vue$/, - loader: 'vue' - }, - { - test: /\.js$/, - loader: 'babel', - include: projectRoot, - exclude: /node_modules/ - }, - { - test: /\.json$/, - loader: 'json' - }, - { - test: /\.theme$/, - loaders: ['raw', 'sass'] - }, - { - test: /\.html$/, - loader: 'vue-html' - }, - { - test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, - loader: 'url', - query: { - limit: 10000, - name: utils.assetsPath('img/[name].[hash:7].[ext]') - } - }, - { - test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, - loader: 'url', - query: { - limit: 10000, - name: utils.assetsPath('fonts/[name].[hash:7].[ext]') - } - } - ] - }, - eslint: { - fix: true, - formatter: require('eslint-friendly-formatter') - }, - vue: { - loaders: utils.cssLoaders() - } -}; diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js deleted file mode 100644 index d36053b..0000000 --- a/build/webpack.dev.conf.js +++ /dev/null @@ -1,34 +0,0 @@ -var config = require('../config'); -var webpack = require('webpack'); -var merge = require('webpack-merge'); -var utils = require('./utils'); -var baseWebpackConfig = require('./webpack.base.conf'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); - -// add hot-reload related code to entry chunks -Object.keys(baseWebpackConfig.entry).forEach(function(name) { - baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]); -}); - -module.exports = merge(baseWebpackConfig, { - module: { - loaders: utils.styleLoaders() - }, - // eval-source-map is faster for development - devtool: '#inline-source-map', - plugins: [ - new webpack.DefinePlugin({ - 'process.env': config.dev.env - }), - // https://github.com/glenjamin/webpack-hot-middleware#installation--usage - new webpack.optimize.OccurenceOrderPlugin(), - new webpack.HotModuleReplacementPlugin(), - new webpack.NoErrorsPlugin(), - // https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: 'index.html', - template: 'index.html', - inject: true - }) - ] -}); diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js deleted file mode 100644 index 3593393..0000000 --- a/build/webpack.prod.conf.js +++ /dev/null @@ -1,98 +0,0 @@ -var path = require('path'); -var config = require('../config'); -var utils = require('./utils'); -var webpack = require('webpack'); -var merge = require('webpack-merge'); -var baseWebpackConfig = require('./webpack.base.conf'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var env = process.env.NODE_ENV === 'testing' ? require('../config/test.env') : config.build.env; - -var webpackConfig = merge(baseWebpackConfig, { - module: { - loaders: utils.styleLoaders({ - extract: true - }) - }, - output: { - path: config.build.assetsRoot, - filename: utils.assetsPath('[name].min.js'), - chunkFilename: utils.assetsPath('[id].min.js') - }, - vue: { - loaders: utils.cssLoaders({ - extract: true - }) - }, - plugins: [ - // http://vuejs.github.io/vue-loader/workflow/production.html - new webpack.DefinePlugin({ - 'process.env': env - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false - } - }), - new webpack.optimize.OccurenceOrderPlugin(), - // extract css into its own file - new ExtractTextPlugin(utils.assetsPath('[name].min.css')), - // 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: process.env.NODE_ENV === 'testing' ? 'index.html' : 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' - }), - // split vendor js into its own file - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks: function(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', - chunks: ['vendor'] - }) - ] -}); - -if (config.build.productionGzip) { - var 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 - }) - ); -} - -module.exports = webpackConfig; diff --git a/build/webpack/base.js b/build/webpack/base.js new file mode 100644 index 0000000..411a958 --- /dev/null +++ b/build/webpack/base.js @@ -0,0 +1,103 @@ +import path from 'path'; +import webpack from 'webpack'; +import autoprefixer from 'autoprefixer'; +import eslintFormatter from 'eslint-friendly-formatter'; +import config from '../config'; + + +const buildAssetsPath = (_path) => { + return path.posix.join(_path); +}; + +export default { + entry: { + 'docs/docs': './docs/src/index.js' + }, + output: { + path: config.rootPath, + publicPath: config.publicPath, + filename: '[name].js' + }, + resolve: { + extensions: ['', '.js', '.vue'], + fallback: [config.nodePath], + alias: { + vue: 'vue/dist/vue.common.js' + } + }, + resolveLoader: { + fallback: [config.nodePath] + }, + module: { + preLoaders: [ + { + test: /\.vue$/, + loader: 'eslint', + include: config.projectRoot, + exclude: /node_modules/ + }, + { + test: /\.js$/, + loader: 'eslint', + include: config.projectRoot, + exclude: /node_modules/ + } + ], + loaders: [ + { + test: /\.vue$/, + loader: 'vue' + }, + { + test: /\.js$/, + loader: 'babel', + include: config.projectRoot, + exclude: /node_modules/ + }, + { + test: /\.css$/, + loader: 'vue-style-loader!css-loader' + }, + { + test: /\.scss$/, + loader: 'vue-style-loader!css-loader!sass-loader' + }, + { + test: /\.theme$/, + loaders: ['raw', 'sass-loader'] + }, + { + test: /\.html$/, + loader: 'vue-html' + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url', + query: { + limit: 10000, + name: buildAssetsPath('img/[name].[hash:7].[ext]') + } + } + ] + }, + eslint: { + fix: true, + formatter: eslintFormatter + }, + vue: { + loaders: { + css: 'vue-style-loader!css-loader', + scss: 'vue-style-loader!css-loader!sass-loader' + }, + postcss: [ + autoprefixer({ + browsers: ['last 2 versions'] + }) + ] + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': config.env + }) + ] +}; diff --git a/build/webpack/dev.js b/build/webpack/dev.js new file mode 100644 index 0000000..b464a26 --- /dev/null +++ b/build/webpack/dev.js @@ -0,0 +1,21 @@ +import webpack from 'webpack'; +import merge from 'webpack-merge'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import baseWebpackConfig from './base'; + +Object.keys(baseWebpackConfig.entry).forEach((name) => { + baseWebpackConfig.entry[name] = ['./build/server/client'].concat(baseWebpackConfig.entry[name]); +}); + +export default merge(baseWebpackConfig, { + devtool: '#inline-source-map', + plugins: [ + new webpack.HotModuleReplacementPlugin(), + new webpack.NoErrorsPlugin(), + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'docs/index.html', + inject: true + }) + ] +}); diff --git a/build/webpack/prod-docs.js b/build/webpack/prod-docs.js new file mode 100644 index 0000000..db38a5c --- /dev/null +++ b/build/webpack/prod-docs.js @@ -0,0 +1,47 @@ +import webpack from 'webpack'; +import merge from 'webpack-merge'; +import ExtractTextPlugin from 'extract-text-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import config from '../config'; +import baseWebpackConfig from './base'; + +export default merge(baseWebpackConfig, { + vue: { + loaders: { + css: ExtractTextPlugin.extract('css'), + scss: ExtractTextPlugin.extract(['css', 'sass']) + } + }, + plugins: [ + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }), + new webpack.optimize.OccurenceOrderPlugin(), + new ExtractTextPlugin('[name].css'), + new HtmlWebpackPlugin({ + filename: 'index.html', + template: config.indexPath, + inject: true, + minify: { + caseSensitive: true, + collapseBooleanAttributes: true, + collapseWhitespace: true, + minifyCSS: true, + minifyJS: true, + preventAttributesEscaping: true, + removeAttributeQuotes: true, + removeComments: true, + removeCommentsFromCDATA: true, + removeEmptyAttributes: true, + removeOptionalTags: true, + removeRedundantAttributes: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true, + useShortDoctype: true + }, + chunksSortMode: 'dependency' + }) + ] +}); diff --git a/build/webpack/prod-lib.js b/build/webpack/prod-lib.js new file mode 100644 index 0000000..6ef6e34 --- /dev/null +++ b/build/webpack/prod-lib.js @@ -0,0 +1,49 @@ +import fs from 'fs'; +import path from 'path'; +import webpack from 'webpack'; +import merge from 'webpack-merge'; +import ExtractTextPlugin from 'extract-text-webpack-plugin'; +import config from '../config'; +import baseConfig from './base'; + +function getDirectories(src) { + return fs.readdirSync(src).filter((file) => { + return fs.statSync(path.join(src, file)).isDirectory(); + }); +} + +const componentsPath = 'src/components'; +const components = getDirectories(path.resolve(__dirname, '../../', componentsPath)); + +baseConfig.entry = { + 'vue-material': ['./src/index.js'], + 'components/mdCore/index': ['./src/core'] +}; + +components.forEach((component) => { + baseConfig.entry[path.join('components', component, 'index')] = ['./' + path.join(componentsPath, component)]; +}); + +export default merge(baseConfig, { + output: { + path: config.rootPath, + filename: '[name].js', + library: 'VueMaterial', + libraryTarget: 'umd' + }, + vue: { + loaders: { + css: ExtractTextPlugin.extract('css'), + scss: ExtractTextPlugin.extract(['css', 'sass']) + } + }, + plugins: [ + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }), + new webpack.optimize.OccurenceOrderPlugin(), + new ExtractTextPlugin('[name].css') + ] +}); diff --git a/config/dev.env.js b/config/dev.env.js deleted file mode 100644 index efead7c..0000000 --- a/config/dev.env.js +++ /dev/null @@ -1,6 +0,0 @@ -var merge = require('webpack-merge') -var prodEnv = require('./prod.env') - -module.exports = merge(prodEnv, { - NODE_ENV: '"development"' -}) diff --git a/config/index.js b/config/index.js deleted file mode 100644 index c4378db..0000000 --- a/config/index.js +++ /dev/null @@ -1,22 +0,0 @@ -// see http://vuejs-templates.github.io/webpack for documentation. -var path = require('path') - -module.exports = { - build: { - env: require('./prod.env'), - index: path.resolve(__dirname, '../dist/index.html'), - assetsRoot: path.resolve(__dirname, '../dist'), - assetsSubDirectory: '', - assetsPublicPath: '/', - productionSourceMap: true, - productionGzip: false, - productionGzipExtensions: ['js', 'css'] - }, - dev: { - env: require('./dev.env'), - port: 8080, - assetsSubDirectory: '', - assetsPublicPath: '/', - proxyTable: {} - } -} diff --git a/config/prod.env.js b/config/prod.env.js deleted file mode 100644 index 773d263..0000000 --- a/config/prod.env.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - NODE_ENV: '"production"' -} diff --git a/config/test.env.js b/config/test.env.js deleted file mode 100644 index 89f90de..0000000 --- a/config/test.env.js +++ /dev/null @@ -1,6 +0,0 @@ -var merge = require('webpack-merge') -var devEnv = require('./dev.env') - -module.exports = merge(devEnv, { - NODE_ENV: '"testing"' -}) diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..249cf86 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,27 @@ +# Vue.js Material Docs + +> Material Design for Vue.js + +## Build Setup + +``` bash +### install dependencies +npm install + +### serve with hot reload at localhost:8080 +npm run dev + +### build for production with minification +npm run build + +### run unit tests +npm run unit + +### run e2e tests +npm run e2e + +### run all tests +npm test +``` + +For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/index.html b/docs/index.html similarity index 100% rename from index.html rename to docs/index.html diff --git a/src/docs/App.vue b/docs/src/App.vue similarity index 99% rename from src/docs/App.vue rename to docs/src/App.vue index bf2a23a..e808fb4 100644 --- a/src/docs/App.vue +++ b/docs/src/App.vue @@ -148,7 +148,7 @@ - - diff --git a/src/core/index.js b/src/core/index.js new file mode 100644 index 0000000..231088c --- /dev/null +++ b/src/core/index.js @@ -0,0 +1,24 @@ +/* Code Components */ +import MdTheme from './components/mdTheme'; +import MdInkRipple from './components/mdInkRipple'; +import CoreTheme from './stylesheets/core.theme'; + +/* Core Stylesheets */ +import './stylesheets/core.scss'; + +export default function install(Vue) { + if (install.installed) { + console.warn('Vue Material is already installed.'); + + return; + } + + install.installed = true; + + Vue.material = { + styles: [CoreTheme] + }; + + Vue.use(MdTheme); + Vue.use(MdInkRipple); +} diff --git a/src/core/stylesheets/base.scss b/src/core/stylesheets/base.scss new file mode 100644 index 0000000..56afb83 --- /dev/null +++ b/src/core/stylesheets/base.scss @@ -0,0 +1,56 @@ +/* Structure + ========================================================================== */ + +html { + height: 100%; + box-sizing: border-box; + + *, + *:before, + *:after { + box-sizing: inherit; + } +} + +body { + min-height: 100%; + margin: 0; + position: relative; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + color: rgba(#000, .87); + font-family: $font-roboto; + @extend .md-body-1; +} + + +/* Fluid Media + ========================================================================== */ + +audio, +img, +svg, +object, +embed, +canvas, +video, +iframe { + max-width: 100%; + height: auto; + font-style: italic; + vertical-align: middle; +} + + +/* Suppress the focus outline on links that cannot be accessed via keyboard. + This prevents an unwanted focus outline from appearing around elements + that might still respond to pointer events. + ========================================================================== */ + +[tabindex="-1"]:focus { + outline: none !important; +} diff --git a/src/core/stylesheets/core.scss b/src/core/stylesheets/core.scss new file mode 100644 index 0000000..c24e799 --- /dev/null +++ b/src/core/stylesheets/core.scss @@ -0,0 +1,4 @@ +@import './variables'; +@import './base'; +@import './scrollbar'; +@import './typography'; diff --git a/src/core/stylesheets/core.theme b/src/core/stylesheets/core.theme index d452ad6..6f4521c 100644 --- a/src/core/stylesheets/core.theme +++ b/src/core/stylesheets/core.theme @@ -1,7 +1,4 @@ .THEME_NAME { - color: #{'BACKGROUND-CONTRAST-0.87'}; - background-color: #{'BACKGROUND-COLOR-50'}; - :not(input):not(textarea)::selection { background: #{'ACCENT-COLOR'}; color: #{'ACCENT-CONTRAST'}; @@ -16,6 +13,10 @@ } } +body.THEME_NAME { + color: #{'BACKGROUND-CONTRAST-0.87'}; + background-color: #{'BACKGROUND-COLOR-50'}; +} /* Typography */ diff --git a/src/core/stylesheets/scrollbar.scss b/src/core/stylesheets/scrollbar.scss new file mode 100644 index 0000000..9131b46 --- /dev/null +++ b/src/core/stylesheets/scrollbar.scss @@ -0,0 +1,28 @@ +::-webkit-scrollbar { + width: 10px; + height: 10px; + box-shadow: inset 1px 1px 0 rgba(#000, .12); + transition: $swift-ease-in-out; + background-color: rgba(#000, .05); + + &:hover { + box-shadow: inset 1px 1px 0 rgba(#000, .054), + inset 0 -1px 0 rgba(#000, .038); + background-color: rgba(#000, .087); + } +} + +::-webkit-scrollbar-button { + display: none; +} + +::-webkit-scrollbar-corner { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: rgba(#000, .26); + box-shadow: inset 1px 1px 0 rgba(#000, .054), + inset 0 -1px 0 rgba(#000, .087); + transition: $swift-ease-in-out; +} diff --git a/src/core/stylesheets/structure.scss b/src/core/stylesheets/structure.scss deleted file mode 100644 index 1df1501..0000000 --- a/src/core/stylesheets/structure.scss +++ /dev/null @@ -1,43 +0,0 @@ -body { - min-height: 100%; - margin: 0; - position: relative; - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: rgba(#000, .87); - font-family: $font-roboto; - @extend .md-body-1; -} - -::-webkit-scrollbar { - width: 10px; - height: 10px; - box-shadow: inset 1px 1px 0 rgba(#000, .1); - transition: $swift-ease-in-out; - background-color: rgba(#000, .05); - - &:hover { - box-shadow: inset 1px 1px 0 rgba(#000, .05), - inset 0 -1px 0 rgba(#000, .03); - background-color: rgba(#000, .08); - } -} - -::-webkit-scrollbar-button { - display: none; -} - -::-webkit-scrollbar-corner { - background-color: transparent; -} - -::-webkit-scrollbar-thumb { - background-color: rgba(#000, .2); - box-shadow: inset 1px 1px 0 rgba(#000, .05), - inset 0 -1px 0 rgba(#000, .07); - transition: $swift-ease-in-out; -} diff --git a/src/core/stylesheets/type.scss b/src/core/stylesheets/typography.scss similarity index 100% rename from src/core/stylesheets/type.scss rename to src/core/stylesheets/typography.scss diff --git a/src/core/stylesheets/utils/commons.scss b/src/core/stylesheets/utils/commons.scss deleted file mode 100644 index aa9b80b..0000000 --- a/src/core/stylesheets/utils/commons.scss +++ /dev/null @@ -1,96 +0,0 @@ -/* Apply the border-box box model to HTML and inheriting - to all children elements - ========================================================================== */ - -html { - box-sizing: border-box; - - *, - *:before, - *:after { - box-sizing: inherit; - } -} - - - -/* Always hide an element when it has the `hidden` HTML attribute. - ========================================================================== */ - -[hidden] { - display: none !important; -} - - - -/* Fluid Media - ========================================================================== */ - -audio, -img, -svg, -object, -embed, -canvas, -video, -iframe { - max-width: 100%; - height: auto; - font-style: italic; - vertical-align: middle; -} - - - -/* Remove figure extra margin - ========================================================================== */ - -figure { - margin-right: auto; - margin-left: auto; - - > img { - display: block; - } -} - - - -/* Remove outline from button - ========================================================================== */ - -button:focus { - outline: none; -} - - - -/* Suppress the focus outline on links that cannot be accessed via keyboard. - This prevents an unwanted focus outline from appearing around elements - that might still respond to pointer events. - ========================================================================== */ - -[tabindex="-1"]:focus { - outline: none !important; -} - - - -/* Remove extra vertical spacing when nesting lists - ========================================================================== */ - -li { - > ul, - > ol { - margin-bottom: 0; - } -} - - - -/* Remove spacing between table cells - ========================================================================== */ - -table { - empty-cells: show; -} diff --git a/src/core/stylesheets/utils/mixins.scss b/src/core/stylesheets/utils/mixins.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..24a4539 --- /dev/null +++ b/src/index.js @@ -0,0 +1,53 @@ +import mdCore from './core'; +import mdAvatar from './components/mdAvatar'; +import mdBottomBar from './components/mdBottomBar'; +import mdButton from './components/mdButton'; +import mdButtonToggle from './components/mdButtonToggle'; +import mdCheckbox from './components/mdCheckbox'; +import mdDivider from './components/mdDivider'; +import mdIcon from './components/mdIcon'; +import mdInputContainer from './components/mdInputContainer'; +import mdList from './components/mdList'; +import mdRadio from './components/mdRadio'; +import mdSelect from './components/mdSelect'; +import mdSidenav from './components/mdSidenav'; +import mdSubheader from './components/mdSubheader'; +import mdSwitch from './components/mdSwitch'; +import mdTabs from './components/mdTabs'; +import mdToolbar from './components/mdToolbar'; +import mdTooltip from './components/mdTooltip'; +import mdWhiteframe from './components/mdWhiteframe'; + +let options = { + mdCore, + mdAvatar, + mdBottomBar, + mdButton, + mdButtonToggle, + mdCheckbox, + mdDivider, + mdIcon, + mdInputContainer, + mdList, + mdRadio, + mdSelect, + mdSidenav, + mdSubheader, + mdSwitch, + mdTabs, + mdToolbar, + mdTooltip, + mdWhiteframe +}; + +options.install = (Vue) => { + for (let component in options) { + let componentInstaller = options[component]; + + if (componentInstaller && component !== 'install') { + Vue.use(componentInstaller); + } + } +}; + +export default options; diff --git a/src/vue-material.js b/src/vue-material.js deleted file mode 100644 index 9648217..0000000 --- a/src/vue-material.js +++ /dev/null @@ -1,54 +0,0 @@ -import './core/core'; -import MdAvatar from './components/mdAvatar'; -import MdBottomBar from './components/mdBottomBar'; -import MdButton from './components/mdButton'; -import MdButtonToggle from './components/mdButtonToggle'; -import MdCheckbox from './components/mdCheckbox'; -import MdDivider from './components/mdDivider'; -import MdIcon from './components/mdIcon'; -import MdInkRipple from './components/mdInkRipple'; -import MdInputContainer from './components/mdInputContainer'; -import MdList from './components/mdList'; -import mdRadio from './components/mdRadio'; -import MdSelect from './components/mdSelect'; -import MdSidenav from './components/mdSidenav'; -import MdSubheader from './components/mdSubheader'; -import mdSwitch from './components/mdSwitch'; -import mdTabs from './components/mdTabs'; -import MdToolbar from './components/mdToolbar'; -import MdTooltip from './components/mdTooltip'; -import MdWhiteframe from './components/mdWhiteframe'; -import MdTheme from './components/mdTheme'; - -let options = { - MdAvatar, - MdBottomBar, - MdButton, - MdButtonToggle, - MdCheckbox, - MdDivider, - MdIcon, - MdInkRipple, - MdInputContainer, - MdList, - mdRadio, - MdSelect, - MdSidenav, - MdSubheader, - mdSwitch, - mdTabs, - MdToolbar, - MdTooltip, - MdWhiteframe, - MdTheme -}; - -options.enableAll = (Vue) => { - for (let component in options) { - if (component !== 'MdTheme' && component !== 'enableAll') { - Vue.use(options[component]); - } - } -}; - -export default options;