├── .gitignore
├── README.md
├── deploy-docs.sh
├── docs
├── README.md
├── SUMMARY.md
├── backend.md
├── commands.md
├── e2e.md
├── env.md
├── linter.md
├── pre-processors.md
├── prerender.md
├── proxy.md
├── static.md
├── structure.md
└── unit.md
├── meta.js
├── package.json
└── template
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── README.md
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── webpack.base.conf.js
├── webpack.bundle.conf.js
├── webpack.dev.conf.js
└── webpack.docs.conf.js
├── config
├── dev.env.js
├── index.js
├── prod.env.js
└── test.env.js
├── docs
├── assets
│ ├── _functions.sass
│ ├── base
│ │ ├── _animations.sass
│ │ ├── _functions.sass
│ │ ├── _global.sass
│ │ ├── _media.sass
│ │ ├── _mixins.sass
│ │ ├── _typo.sass
│ │ ├── _z-stack.scss
│ │ └── normalize.scss
│ ├── components
│ │ ├── _avatars.sass
│ │ ├── _breadcrumbs.sass
│ │ ├── _buttons.sass
│ │ ├── _dropdown.sass
│ │ ├── _flex_grid.sass
│ │ ├── _grid.sass
│ │ ├── _inputs.sass
│ │ ├── _lists.sass
│ │ ├── _mobile_nav.sass
│ │ ├── _offcanvas.sass
│ │ ├── _panels.sass
│ │ ├── _table.sass
│ │ └── _tabs.sass
│ ├── github.svg
│ ├── layout
│ │ └── _topbar.sass
│ ├── logo.png
│ ├── main.sass
│ ├── multiselect.sass
│ ├── prism.scss
│ └── utils
│ │ ├── _utils.sass
│ │ └── _visibility.sass
├── docs.scss
├── index.pug
├── main.js
└── partials
│ ├── _footer.pug
│ ├── _getting-started.pug
│ ├── _nav.pug
│ ├── _start.pug
│ ├── api
│ ├── _events.pug
│ ├── _props.pug
│ └── _slots.pug
│ └── examples
│ └── _section.pug
├── index.html
├── package.json
├── src
├── MyComponent.vue
└── index.js
├── static
├── .gitkeep
├── monterail-logo.png
├── prism.js
└── vue-logo.png
└── test
├── e2e
├── custom-assertions
│ └── elementCount.js
├── nightwatch.conf.js
├── runner.js
└── specs
│ └── test.js
└── unit
├── .eslintrc
├── index.js
├── karma.conf.js
└── specs
└── Hello.spec.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | docs/_book
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-component-template
2 |
3 | > A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction for open source Vue components.
4 |
5 | > Based on the official vue-webpack-boilerplate template
6 |
7 | > This template is Vue 2.0 compatible.
8 |
9 | ## Documentation
10 |
11 | - [For this template](http://vuejs-templates.github.io/webpack): common questions specific to this template are answered and each part is described in greater detail
12 | - [For Vue 2.0](http://vuejs.org/guide/): general information about how to work with Vue, not specific to this template
13 |
14 | ## Usage
15 |
16 | This is a project template for [vue-cli](https://github.com/vuejs/vue-cli). **It is recommended to use npm 3+ for a more efficient dependency tree.**
17 |
18 | ``` bash
19 | $ npm install -g vue-cli
20 | $ vue init monterail/vue-component-template my-project
21 | $ cd my-project
22 | $ npm install
23 | $ npm run dev
24 | ```
25 |
26 | ## What's Included
27 |
28 | - `npm run dev`: first-in-class development experience.
29 | - Webpack + `vue-loader` for single file Vue components.
30 | - State preserving hot-reload
31 | - State preserving compilation error overlay
32 | - Lint-on-save with ESLint
33 | - Source maps
34 |
35 | - `npm run bundle`: Create UMD bundle.
36 |
37 | - `npm run docs`: Create docs inside `/gh-pages` ready to be published
38 |
39 | - `npm run unit`: Unit tests run in PhantomJS with [Karma](http://karma-runner.github.io/0.13/index.html) + [Mocha](http://mochajs.org/) + [karma-webpack](https://github.com/webpack/karma-webpack).
40 | - Supports ES2015 in test files.
41 | - Supports all webpack loaders.
42 | - Easy mock injection.
43 |
44 | - `npm run e2e`: End-to-end tests with [Nightwatch](http://nightwatchjs.org/).
45 | - Run tests in multiple browsers in parallel.
46 | - Works with one command out of the box:
47 | - Selenium and chromedriver dependencies automatically handled.
48 | - Automatically spawns the Selenium server.
49 |
--------------------------------------------------------------------------------
/deploy-docs.sh:
--------------------------------------------------------------------------------
1 | cd docs
2 | rm -rf _book
3 | gitbook build
4 | cd _book
5 | git init
6 | git add -A
7 | git commit -m 'update book'
8 | git push -f git@github.com:vuejs-templates/webpack.git master:gh-pages
9 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | This boilerplate is targeted towards large, serious projects and assumes you are somewhat familiar with Webpack and `vue-loader`. Make sure to also read [`vue-loader`'s documentation](http://vuejs.github.io/vue-loader/index.html) for common workflow recipes.
4 |
5 | If you just want to try out `vue-loader` or whip out a quick prototype, use the [webpack-simple](https://github.com/vuejs-templates/webpack-simple) template instead.
6 |
7 | ## Quickstart
8 |
9 | To use this template, scaffold a project with [vue-cli](https://github.com/vuejs/vue-cli). **It is recommended to use npm 3+ for a more efficient dependency tree.**
10 |
11 | ``` bash
12 | $ npm install -g vue-cli
13 | $ vue init webpack my-project
14 | $ cd my-project
15 | $ npm install
16 | $ npm run dev
17 | ```
18 |
--------------------------------------------------------------------------------
/docs/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | - [Project Structure](structure.md)
4 | - [Build Commands](commands.md)
5 | - [Linter Configuration](linter.md)
6 | - [Pre-Processors](pre-processors.md)
7 | - [Handling Static Assets](static.md)
8 | - [Environment Variables](env.md)
9 | - [Integrate with Backend Framework](backend.md)
10 | - [API Proxying During Development](proxy.md)
11 | - [Unit Testing](unit.md)
12 | - [End-to-end Testing](e2e.md)
13 | - [Prerendering for SEO](prerender.md)
14 |
--------------------------------------------------------------------------------
/docs/backend.md:
--------------------------------------------------------------------------------
1 | # Integrating with Backend Framework
2 |
3 | If you are building a purely-static app (one that is deployed separately from the backend API), then you probably don't even need to edit `config/index.js`. However, if you want to integrate this template with an existing backend framework, e.g. Rails/Django/Laravel, which comes with their own project structures, you can edit `config/index.js` to directly generate front-end assets into your backend project.
4 |
5 | Let's take a look at the default `config/index.js`:
6 |
7 | ``` js
8 | var path = require('path')
9 |
10 | module.exports = {
11 | build: {
12 | index: path.resolve(__dirname, 'dist/index.html'),
13 | assetsRoot: path.resolve(__dirname, 'dist'),
14 | assetsSubDirectory: 'static',
15 | assetsPublicPath: '/',
16 | productionSourceMap: true
17 | },
18 | dev: {
19 | port: 8080,
20 | proxyTable: {}
21 | }
22 | }
23 | ```
24 |
25 | Inside the `build` section, we have the following options:
26 |
27 | ### `build.index`
28 |
29 | > Must be an absolute path on your local file system.
30 |
31 | This is where the `index.html` (with injected asset URLs) will be generated.
32 |
33 | If you are using this template with a backend-framework, you can edit `index.html` accordingly and point this path to a view file rendered by your backend app, e.g. `app/views/layouts/application.html.erb` for a Rails app, or `resources/views/index.blade.php` for a Laravel app.
34 |
35 | ### `build.assetsRoot`
36 |
37 | > Must be an absolute path on your local file system.
38 |
39 | This should point to the root directory that contains all the static assets for your app. For example, `public/` for both Rails/Laravel.
40 |
41 | ### `build.assetsSubDirectory`
42 |
43 | Nest webpack-generated assets under this directory in `build.assetsRoot`, so that they are not mixed with other files you may have in `build.assetsRoot`. For example, if `build.assetsRoot` is `/path/to/dist`, and `build.assetsSubDirectory` is `static`, then all Webpack assets will be generated in `path/to/dist/static`.
44 |
45 | This directory will be cleaned before each build, so it should only contain assets generated by the build.
46 |
47 | Files inside `static/` will be copied into this directory as-is during build. This means if you change this prefix, all your absolute URLs referencing files in `static/` will also need to be changed. See [Handling Static Assets](static.md) for more details.
48 |
49 | ### `build.assetsPublicPath`
50 |
51 | This should be the URL path where your `build.assetsRoot` will be served from over HTTP. In most cases, this will be root (`/`). Only change this if your backend framework serves static assets with a path prefix. Internally, this is passed to Webpack as `output.publicPath`.
52 |
53 | ### `build.productionSourceMap`
54 |
55 | Whether to generate source maps for production build.
56 |
57 | ### `dev.port`
58 |
59 | Specify the port for the dev server to listen to.
60 |
61 | ### `dev.proxyTable`
62 |
63 | Define proxy rules for the dev server. See [API Proxying During Development](proxy.md) for more details.
64 |
--------------------------------------------------------------------------------
/docs/commands.md:
--------------------------------------------------------------------------------
1 | # Build Commands
2 |
3 | All build commands are executed via [NPM Scripts](https://docs.npmjs.com/misc/scripts).
4 |
5 | ### `npm run dev`
6 |
7 | > Starts a Node.js local development server. See [API Proxying During Development](proxy.md) for more details.
8 |
9 | - Webpack + `vue-loader` for single file Vue components.
10 | - State preserving hot-reload
11 | - State preserving compilation error overlay
12 | - Lint-on-save with ESLint
13 | - Source maps
14 |
15 | ### `npm run build`
16 |
17 | > Build assets for production. See [Integrating with Backend Framework](backend.md) for more details.
18 |
19 | - JavaScript minified with [UglifyJS](https://github.com/mishoo/UglifyJS2).
20 | - HTML minified with [html-minifier](https://github.com/kangax/html-minifier).
21 | - CSS across all components extracted into a single file and minified with [cssnano](https://github.com/ben-eb/cssnano).
22 | - All static assets compiled with version hashes for efficient long-term caching, and a production `index.html` is auto-generated with proper URLs to these generated assets.
23 | - Also see [deployment notes](#how-do-i-deploy-built-assets-with-my-backend-framework).
24 |
25 | ### `npm run unit`
26 |
27 | > Run unit tests in PhantomJS with [Karma](http://karma-runner.github.io/0.13/index.html). See [Unit Testing](unit.md) for more details.
28 |
29 | - Supports ES2015 in test files.
30 | - Supports all webpack loaders.
31 | - Easy [mock injection](http://vuejs.github.io/vue-loader/en/workflow/testing-with-mocks.html).
32 |
33 | ### `npm run e2e`
34 |
35 | > Run end-to-end tests with [Nightwatch](http://nightwatchjs.org/). See [End-to-end Testing](e2e.md) for more details.
36 |
37 | - Run tests in multiple browsers in parallel.
38 | - Works with one command out of the box:
39 | - Selenium and chromedriver dependencies automatically handled.
40 | - Automatically spawns the Selenium server.
41 |
--------------------------------------------------------------------------------
/docs/e2e.md:
--------------------------------------------------------------------------------
1 | # End-to-end Testing
2 |
3 | This boilerplate uses [Nightwatch.js](http://nightwatchjs.org) for e2e tests. Nightwatch.js is a highly integrated e2e test runner built on top of Selenium. This boilerplate comes with Selenium server and chromedriver binaries pre-configured for you, so you don't have to mess with these yourself.
4 |
5 | Let's take a look at the files in the `test/e2e` directory:
6 |
7 | - `runner.js`
8 |
9 | A Node.js script that starts the dev server, and then launches Nightwatch to run tests against it. This is the script that will run when you run `npm run e2e`.
10 |
11 | - `nightwatch.conf.js`
12 |
13 | Nightwatch configuration file. See [Nightwatch's docs on configuration](http://nightwatchjs.org/guide#settings-file) for more details.
14 |
15 | - `custom-assertions/`
16 |
17 | Custom assertions that can be used in Nightwatch tests. See [Nightwatch's docs on writing custom assertions](http://nightwatchjs.org/guide#writing-custom-assertions) for more details.
18 |
19 | - `specs/`
20 |
21 | You actual tests! See [Nightwatch's docs on writing tests](http://nightwatchjs.org/guide#writing-tests) and [API reference](http://nightwatchjs.org/api) for more details.
22 |
23 | ### Running Tests in More Browsers
24 |
25 | To configure which browsers to run the tests in, add an entry under "test_settings" in [`test/e2e/nightwatch.conf.js`](https://github.com/vuejs-templates/webpack/blob/master/template/test/e2e/nightwatch.conf.js#L17-L39) , and also the `--env` flag in [`test/e2e/runner.js`](https://github.com/vuejs-templates/webpack/blob/master/template/test/e2e/runner.js#L15). If you wish to configure remote testing on services like SauceLabs, you can either make the Nightwatch config conditional based on environment variables, or use a separate config file altogether. Consult [Nightwatch's docs on Selenium](http://nightwatchjs.org/guide#selenium-settings) for more details.
26 |
--------------------------------------------------------------------------------
/docs/env.md:
--------------------------------------------------------------------------------
1 | # Environment Variables
2 |
3 | Sometimes it is practical to have different config values according to the environment that the application is running in.
4 |
5 | As an example:
6 |
7 | ```js
8 | // config/prod.env.js
9 | module.exports = {
10 | NODE_ENV: '"production"',
11 | DEBUG_MODE: false,
12 | API_KEY: '"..."' // this is shared between all environments
13 | }
14 |
15 | // config/dev.env.js
16 | module.exports = merge(prodEnv, {
17 | NODE_ENV: '"development"',
18 | DEBUG_MODE: true // this overrides the DEBUG_MODE value of prod.env
19 | })
20 |
21 | // config/test.env.js
22 | module.exports = merge(devEnv, {
23 | NODE_ENV: '"testing"'
24 | })
25 | ```
26 |
27 | > **Note:** string variables need to be wrapped into single and double quotes `'"..."'`
28 |
29 | So, the environment variables are:
30 | - Production
31 | - NODE_ENV = 'production',
32 | - DEBUG_MODE = false,
33 | - API_KEY = '...'
34 | - Development
35 | - NODE_ENV = 'development',
36 | - DEBUG_MODE = true,
37 | - API_KEY = '...'
38 | - Testing
39 | - NODE_ENV = 'testing',
40 | - DEBUG_MODE = true,
41 | - API_KEY = '...'
42 |
43 | As we can see, `test.env` inherits the `dev.env` and the `dev.env` inherits the `prod.env`.
44 |
45 | ### Usage
46 |
47 | It is simple to use the environment variables in your code. For example:
48 |
49 | ```js
50 | Vue.config.debug = process.env.DEBUG_MODE
51 | ```
--------------------------------------------------------------------------------
/docs/linter.md:
--------------------------------------------------------------------------------
1 | # Linter Configuration
2 |
3 | This boilerplate uses [ESLint](http://eslint.org/) as the linter, and uses the [Standard](https://github.com/feross/standard/blob/master/RULES.md) preset with some small customizations.
4 |
5 | If you are not happy with the default linting rules, you have several options:
6 |
7 | 1. Overwrite individual rules in `.eslintrc.js`. For example, you can add the following rule to enforce semicolons instead of omitting them:
8 |
9 | ``` js
10 | "semi": [2, "always"]
11 | ```
12 |
13 | 2. Pick a different ESLint preset when generating the project, for example [eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb).
14 |
15 | 3. Pick "none" for ESLint preset when generating the project and define your own rules. See [ESLint documentation](http://eslint.org/docs/rules/) for more details.
16 |
--------------------------------------------------------------------------------
/docs/pre-processors.md:
--------------------------------------------------------------------------------
1 | # Pre-Processors
2 |
3 | This boilerplate has pre-configured CSS extraction for most popular CSS pre-processors including LESS, SASS, Stylus, and PostCSS. To use a pre-processor, all you need to do is installing the appropriate webpack loader for it. For example, to use SASS:
4 |
5 | ``` bash
6 | npm install sass-loader node-sass --save-dev
7 | ```
8 |
9 | Note you also need to install `node-sass` because `sass-loader` depends on it as a peer dependency.
10 |
11 | ### Using Pre-Processors inside Components
12 |
13 | Once installed, you can use the pre-processors inside your `*.vue` components using the `lang` attribute on `
19 | ```
20 |
21 | ### A note on SASS syntax
22 |
23 | - `lang="scss"` corresponds to the CSS-superset syntax (with curly braces and semicolones).
24 | - `lang="sass"` corresponds to the indentation-based syntax.
25 |
26 | ### PostCSS
27 |
28 | Styles in `*.vue` files are piped through PostCSS by default, so you don't need to use a specific loader for it. You can simply add PostCSS plugins you want to use in `build/webpack.base.conf.js` under the `vue` block:
29 |
30 | ``` js
31 | // build/webpack.base.conf.js
32 | module.exports = {
33 | // ...
34 | vue: {
35 | postcss: [/* your plugins */]
36 | }
37 | }
38 | ```
39 |
40 | See [vue-loader's related documentation](http://vuejs.github.io/vue-loader/en/features/postcss.html) for more details.
41 |
42 | ### Standalone CSS Files
43 |
44 | To ensure consistent extraction and processing, it is recommended to import global, standalone style files from your root `App.vue` component, for example:
45 |
46 | ``` html
47 |
48 |
49 | ```
50 |
51 | Note you should probably only do this for the styles written by yourself for your application. For existing libraries e.g. Bootstrap or Semantic UI, you can place them inside `/static` and reference them directly in `index.html`. This avoids extra build time and also is better for browser caching. (See [Static Asset Handling](static.md))
52 |
--------------------------------------------------------------------------------
/docs/prerender.md:
--------------------------------------------------------------------------------
1 | # Prerendering for SEO
2 |
3 | If you want to prerender routes that will not significantly change once pushed to production, use this Webpack plugin: [prerender-spa-plugin](https://www.npmjs.com/package/prerender-spa-plugin), which has been tested for use with Vue. For pages that _do_ frequently change, [Prerender.io](https://prerender.io/) and [Netlify](https://www.netlify.com/pricing) both offer plans for regularly re-prerendering your content for search engines.
4 |
5 | ## Using `prerender-spa-plugin`
6 |
7 | 1. Install it as a dev dependency:
8 |
9 | ```bash
10 | npm install --save-dev prerender-spa-plugin
11 | ```
12 |
13 | 2. Require it in **build/webpack.prod.conf.js**:
14 |
15 | ```js
16 | // This line should go at the top of the file where other 'imports' live in
17 | var PrerenderSpaPlugin = require('prerender-spa-plugin')
18 | ```
19 |
20 | 3. Configure it in the `plugins` array (also in **build/webpack.prod.conf.js**):
21 |
22 | ```js
23 | new PrerenderSpaPlugin(
24 | // Path to compiled app
25 | path.join(__dirname, '../dist'),
26 | // List of endpoints you wish to prerender
27 | [ '/' ]
28 | )
29 | ```
30 |
31 | If you also wanted to prerender `/about` and `/contact`, then that array would be `[ '/', '/about', '/contact' ]`.
32 |
--------------------------------------------------------------------------------
/docs/proxy.md:
--------------------------------------------------------------------------------
1 | # API Proxying During Development
2 |
3 | When integrating this boilerplate with an existing backend, a common need is to access the backend API when using the dev server. To achieve that, we can run the dev server and the API backend side-by-side (or remotely), and let the dev server proxy all API requests to the actual backend.
4 |
5 | To configure the proxy rules, edit `dev.proxyTable` option in `config/index.js`. The dev server is using [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) for proxying, so you should refer to its docs for detailed usage. But here's a simple example:
6 |
7 | ``` js
8 | // config/index.js
9 | module.exports = {
10 | // ...
11 | dev: {
12 | proxyTable: {
13 | // proxy all requests starting with /api to jsonplaceholder
14 | '/api': {
15 | target: 'http://jsonplaceholder.typicode.com',
16 | changeOrigin: true,
17 | pathRewrite: {
18 | '^/api': ''
19 | }
20 | }
21 | }
22 | }
23 | }
24 | ```
25 |
26 | The above example will proxy the request `/api/posts/1` to `http://jsonplaceholder.typicode.com/posts/1`.
27 |
--------------------------------------------------------------------------------
/docs/static.md:
--------------------------------------------------------------------------------
1 | # Handing Static Assets
2 |
3 | You will notice in the project structure we have two directories for static assets: `src/assets` and `static/`. What is the difference between them?
4 |
5 | ### Webpacked Assets
6 |
7 | To answer this question, we first need to understand how Webpack deals with static assets. In `*.vue` components, all your templates and CSS are parsed by `vue-html-loader` and `css-loader` to look for asset URLs. For example, in `` and `background: url(./logo.png)`, `"./logo.png"` is a relative asset path and will be **resolved by Webpack as a module dependency**.
8 |
9 | Because `logo.png` is not JavaScript, when treated as a module dependency, we need to use `url-loader` and `file-loader` to process it. This boilerplate has already configured these loaders for you, so you basically get features such as filename fingerprinting and conditional base64 inlining for free, while being able to use relative/module paths without worrying about deployment.
10 |
11 | Since these assets may be inlined/copied/renamed during build, they are essentially part of your source code. This is why it is recommended to place Webpack-processed static assets inside `/src`, along side other source files. In fact, you don't even have to put them all in `/src/assets`: you can organize them based on the module/component using them. For example, you can put each component in its own directory, with its static assets right next to it.
12 |
13 | ### Asset Resolving Rules
14 |
15 | - **Relative URLs**, e.g. `./assets/logo.png` will be interpreted as a module dependency. They will be replaced with an auto-generated URL based on your Webpack output configuration.
16 |
17 | - **Non-prefixed URLs**, e.g. `assets/logo.png` will be treated the same as the relative URLs and translated into `./assets/logo.png`.
18 |
19 | - **URLs prefixed with `~`** are treated as a module request, similar to `require('some-module/image.png')`. You need to use this prefix if you want to leverage Webpack's module resolving configurations. For example if you have a resolve alias for `assets`, you need to use `
` to ensure that alias is respected.
20 |
21 | - **Root-relative URLs**, e.g. `/assets/logo.png` are not processed at all.
22 |
23 | ### Getting Asset Paths in JavaScript
24 |
25 | In order for Webpack to return the correct asset paths, you need to use `require('./relative/path/to/file.jpg')`, which will get processed by `file-loader` and returns the resolved URL. For example:
26 |
27 | ``` js
28 | computed: {
29 | background () {
30 | return require('./bgs/' + this.id + '.jpg')
31 | }
32 | }
33 | ```
34 |
35 | **Note the above example will include every image under `./bgs/` in the final build.** This is because Webpack cannot guess which of them will be used at runtime, so it includes them all.
36 |
37 | ### "Real" Static Assets
38 |
39 | In comparison, files in `static/` are not processed by Webpack at all: they are directly copied to their final destination as-is, with the same filename. You must reference these files using absolute paths, which is determined by joining `build.assetsPublicPath` and `build.assetsSubDirectory` in `config.js`.
40 |
41 | As an example, with the following default values:
42 |
43 | ``` js
44 | // config.js
45 | module.exports = {
46 | // ...
47 | build: {
48 | assetsPublicPath: '/',
49 | assetsSubDirectory: 'static'
50 | }
51 | }
52 | ```
53 |
54 | Any file placed in `static/` should be referenced using the absolute URL `/static/[filename]`. If you change `assetSubDirectory` to `assets`, then these URLs will need to be changed to `/assets/[filename]`.
55 |
56 | We will learn more about the config file in the section about [backend integration](backend.md).
57 |
--------------------------------------------------------------------------------
/docs/structure.md:
--------------------------------------------------------------------------------
1 | # Project Structure
2 |
3 | ``` bash
4 | .
5 | ├── build/ # webpack config files
6 | │ └── ...
7 | ├── config/
8 | │ ├── index.js # main project config
9 | │ └── ...
10 | ├── src/
11 | │ ├── main.js # app entry file
12 | │ ├── App.vue # main app component
13 | │ ├── components/ # ui components
14 | │ │ └── ...
15 | │ └── assets/ # module assets (processed by webpack)
16 | │ └── ...
17 | ├── static/ # pure static assets (directly copied)
18 | ├── test/
19 | │ └── unit/ # unit tests
20 | │ │ ├── specs/ # test spec files
21 | │ │ ├── index.js # test build entry file
22 | │ │ └── karma.conf.js # test runner config file
23 | │ └── e2e/ # e2e tests
24 | │ │ ├── specs/ # test spec files
25 | │ │ ├── custom-assertions/ # custom assertions for e2e tests
26 | │ │ ├── runner.js # test runner script
27 | │ │ └── nightwatch.conf.js # test runner config file
28 | ├── .babelrc # babel config
29 | ├── .editorconfig.js # editor config
30 | ├── .eslintrc.js # eslint config
31 | ├── index.html # index.html template
32 | └── package.json # build scripts and dependencies
33 | ```
34 |
35 | ### `build/`
36 |
37 | This directory holds the actual configurations for both the development server and the production webpack build. Normally you don't need to touch these files unless you want to customize Webpack loaders, in which case you should probably look at `build/webpack.base.conf.js`.
38 |
39 | ### `config/index.js`
40 |
41 | This is the main configuration file that exposes some of the most common configuration options for the build setup. See [API Proxying During Development](proxy.md) and [Integrating with Backend Framework](backend.md) for more details.
42 |
43 | ### `src/`
44 |
45 | This is where most of your application code will live in. How to structure everything inside this directory is largely up to you; if you are using Vuex, you can consult the [recommendations for Vuex applications](http://vuex.vuejs.org/en/structure.html).
46 |
47 | ### `static/`
48 |
49 | This directory is an escape hatch for static assets that you do not want to process with Webpack. They will be directly copied into the same directory where webpack-built assets are generated.
50 |
51 | See [Handling Static Assets](static.md) for more details.
52 |
53 | ### `test/unit`
54 |
55 | Contains unit test related files. See [Unit Testing](unit.md) for more details.
56 |
57 | ### `test/e2e`
58 |
59 | Contains e2e test related files. See [End-to-end Testing](e2e.md) for more details.
60 |
61 | ### `index.html`
62 |
63 | This is the **template** `index.html` for our single page application. During development and builds, Webpack will generate assets, and the URLs for those generated assets will be automatically injected into this template to render the final HTML.
64 |
65 | ### `package.json`
66 |
67 | The NPM package meta file that contains all the build dependencies and [build commands](commands.md).
68 |
--------------------------------------------------------------------------------
/docs/unit.md:
--------------------------------------------------------------------------------
1 | # Unit Testing
2 |
3 | An overview of the tools used by this boilerplate for unit testing:
4 |
5 | - [Karma](http://karma-runner.github.io/0.13/index.html): the test runner that launches browsers, runs the tests and reports the results to us.
6 | - [karma-webpack](https://github.com/webpack/karma-webpack): the plugin for Karma that bundles our tests using Webpack.
7 | - [Mocha](https://mochajs.org/): the test framework that we write test specs with.
8 | - [Chai](http://chaijs.com/): test assertion library that provides better assertion syntax.
9 | - [Sinon](http://sinonjs.org/): test utility library that provides spies, stubs and mocks.
10 |
11 | Chai and Sinon are integrated using [karma-sinon-chai](https://github.com/kmees/karma-sinon-chai), so all Chai interfaces (`should`, `expect`, `assert`) and `sinon` are globally available in test files.
12 |
13 | And the files:
14 |
15 | - `index.js`
16 |
17 | This is the entry file used by `karma-webpack` to bundle all the test code and source code (for coverage purposes). You can ignore it for the most part.
18 |
19 | - `specs/`
20 |
21 | This directory is where you write your actual tests. You can use full ES2015 and all supported Webpack loaders in your tests.
22 |
23 | - `karma.conf.js`
24 |
25 | This is the Karma configuration file. See [Karma docs](http://karma-runner.github.io/0.13/index.html) for more details.
26 |
27 | ## Running Tests in More Browsers
28 |
29 | You can run the tests in multiple real browsers by installing more [karma launchers](http://karma-runner.github.io/0.13/config/browsers.html) and adjusting the `browsers` field in `test/unit/karma.conf.js`.
30 |
31 | ## Mocking Dependencies
32 |
33 | This boilerplate comes with [inject-loader](https://github.com/plasticine/inject-loader) installed by default. For usage with `*.vue` components, see [vue-loader docs on testing with mocks](http://vue-loader.vuejs.org/en/workflow/testing-with-mocks.html).
34 |
--------------------------------------------------------------------------------
/meta.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "helpers": {
3 | "if_or": function (v1, v2, options) {
4 | if (v1 || v2) {
5 | return options.fn(this);
6 | }
7 |
8 | return options.inverse(this);
9 | }
10 | },
11 | "prompts": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "message": "Project name"
16 | },
17 | "description": {
18 | "type": "string",
19 | "required": false,
20 | "message": "Project description",
21 | "default": "A Vue.js project"
22 | },
23 | "author": {
24 | "type": "string",
25 | "message": "Author"
26 | },
27 | "build": {
28 | "type": "list",
29 | "message": "Vue build",
30 | "choices": [
31 | {
32 | "name": "Runtime + Compiler: recommended for most users",
33 | "value": "standalone",
34 | "short": "standalone"
35 | },
36 | {
37 | "name": "Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - render functions are required elsewhere",
38 | "value": "runtime",
39 | "short": "runtime"
40 | }
41 | ]
42 | },
43 | "lint": {
44 | "type": "confirm",
45 | "message": "Use ESLint to lint your code?"
46 | },
47 | "lintConfig": {
48 | "when": "lint",
49 | "type": "list",
50 | "message": "Pick an ESLint preset",
51 | "choices": [
52 | {
53 | "name": "Standard (https://github.com/feross/standard)",
54 | "value": "standard",
55 | "short": "Standard"
56 | },
57 | {
58 | "name": "AirBNB (https://github.com/airbnb/javascript)",
59 | "value": "airbnb",
60 | "short": "AirBNB"
61 | },
62 | {
63 | "name": "none (configure it yourself)",
64 | "value": "none",
65 | "short": "none"
66 | }
67 | ]
68 | },
69 | "unit": {
70 | "type": "confirm",
71 | "message": "Setup unit tests with Karma + Mocha?"
72 | },
73 | "e2e": {
74 | "type": "confirm",
75 | "message": "Setup e2e tests with Nightwatch?"
76 | }
77 | },
78 | "filters": {
79 | ".eslintrc.js": "lint",
80 | ".eslintignore": "lint",
81 | "config/test.env.js": "unit || e2e",
82 | "test/unit/**/*": "unit",
83 | "test/e2e/**/*": "e2e"
84 | },
85 | "completeMessage": "To get started:\n\n cd {{destDirName}}\n npm install\n npm run dev\n\nDocumentation can be found at https://vuejs-templates.github.io/webpack"
86 | };
87 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-cli-template-webpack",
3 | "version": "2.0.0",
4 | "license": "MIT",
5 | "description": "A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction.",
6 | "scripts": {
7 | "docs": "cd docs && gitbook serve",
8 | "deploy-docs": "bash ./deploy-docs.sh"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/template/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2"],
3 | "plugins": ["transform-runtime"],
4 | "comments": false
5 | }
6 |
--------------------------------------------------------------------------------
/template/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/template/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*.js
2 | config/*.js
3 |
--------------------------------------------------------------------------------
/template/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: 'babel-eslint',
4 | parserOptions: {
5 | sourceType: 'module'
6 | },
7 | {{#if_eq lintConfig "standard"}}
8 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
9 | extends: 'standard',
10 | {{/if_eq}}
11 | {{#if_eq lintConfig "airbnb"}}
12 | extends: 'airbnb-base',
13 | {{/if_eq}}
14 | // required to lint *.vue files
15 | plugins: [
16 | 'html'
17 | ],
18 | {{#if_eq lintConfig "airbnb"}}
19 | // check if imports actually resolve
20 | 'settings': {
21 | 'import/resolver': {
22 | 'webpack': {
23 | 'config': 'build/webpack.base.conf.js'
24 | }
25 | }
26 | },
27 | {{/if_eq}}
28 | // add your custom rules here
29 | 'rules': {
30 | {{#if_eq lintConfig "standard"}}
31 | // allow paren-less arrow functions
32 | 'arrow-parens': 0,
33 | // allow async-await
34 | 'generator-star-spacing': 0,
35 | {{/if_eq}}
36 | {{#if_eq lintConfig "airbnb"}}
37 | // don't require .vue extension when importing
38 | 'import/extensions': ['error', 'always', {
39 | 'js': 'never',
40 | 'vue': 'never'
41 | }],
42 | {{/if_eq}}
43 | // allow debugger during development
44 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/template/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 | {{#unit}}
6 | test/unit/coverage
7 | {{/unit}}
8 | {{#e2e}}
9 | test/e2e/reports
10 | selenium-debug.log
11 | {{/e2e}}
12 |
--------------------------------------------------------------------------------
/template/README.md:
--------------------------------------------------------------------------------
1 | # {{ name }}
2 |
3 | > {{ description }}
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm run dev
13 |
14 | # create UMD bundle.
15 | npm run bundle
16 |
17 | # Create docs inside /gh-pages ready to be published
18 | npm run docs
19 |
20 | {{#unit}}
21 | # run unit tests
22 | npm run unit
23 | {{/unit}}
24 | {{#e2e}}
25 |
26 | # run e2e tests
27 | npm run e2e
28 | {{/e2e}}
29 | {{#if_or unit e2e}}
30 |
31 | # run all tests
32 | npm test
33 | {{/if_or}}
34 | ```
35 |
36 | 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).
37 |
--------------------------------------------------------------------------------
/template/build/build.js:
--------------------------------------------------------------------------------
1 | // https://github.com/shelljs/shelljs
2 | require('./check-versions')()
3 | require('shelljs/global')
4 | env.NODE_ENV = 'production'
5 |
6 | var path = require('path')
7 | var config = require('../config')
8 | var ora = require('ora')
9 | var webpack = require('webpack')
10 | var webpackConfig = require('./webpack.docs.conf')
11 |
12 | console.log(
13 | ' Tip:\n' +
14 | ' Built files are meant to be served over an HTTP server.\n' +
15 | ' Opening index.html over file:// won\'t work.\n'
16 | )
17 |
18 | var spinner = ora('building for production...')
19 | spinner.start()
20 |
21 | var assetsPath = path.join(config.docs.assetsRoot, config.docs.assetsSubDirectory)
22 | rm('-rf', assetsPath)
23 | mkdir('-p', assetsPath)
24 | cp('-R', 'static/*', assetsPath)
25 |
26 | webpack(webpackConfig, function (err, stats) {
27 | spinner.stop()
28 | if (err) throw err
29 | process.stdout.write(stats.toString({
30 | colors: true,
31 | modules: false,
32 | children: false,
33 | chunks: false,
34 | chunkModules: false
35 | }) + '\n')
36 | })
37 |
--------------------------------------------------------------------------------
/template/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var semver = require('semver')
2 | var chalk = require('chalk')
3 | var packageConfig = require('../package.json')
4 | var exec = function (cmd) {
5 | return require('child_process')
6 | .execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | },
15 | {
16 | name: 'npm',
17 | currentVersion: exec('npm --version'),
18 | versionRequirement: packageConfig.engines.npm
19 | }
20 | ]
21 |
22 | module.exports = function () {
23 | var warnings = []
24 | for (var i = 0; i < versionRequirements.length; i++) {
25 | var mod = versionRequirements[i]
26 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
27 | warnings.push(mod.name + ': ' +
28 | chalk.red(mod.currentVersion) + ' should be ' +
29 | chalk.green(mod.versionRequirement)
30 | )
31 | }
32 | }
33 |
34 | if (warnings.length) {
35 | console.log('')
36 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
37 | console.log()
38 | for (var i = 0; i < warnings.length; i++) {
39 | var warning = warnings[i]
40 | console.log(' ' + warning)
41 | }
42 | console.log()
43 | process.exit(1)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/template/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/template/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 | var config = require('../config')
3 | if (!process.env.NODE_ENV) process.env.NODE_ENV = config.dev.env
4 | var path = require('path')
5 | var express = require('express')
6 | var webpack = require('webpack')
7 | var opn = require('opn')
8 | var proxyMiddleware = require('http-proxy-middleware')
9 | var webpackConfig = {{#if_or unit e2e}}process.env.NODE_ENV === 'testing'
10 | ? require('./webpack.prod.conf')
11 | : {{/if_or}}require('./webpack.dev.conf')
12 |
13 | // default port where dev server listens for incoming traffic
14 | var port = process.env.PORT || config.dev.port
15 | // Define HTTP proxies to your custom API backend
16 | // https://github.com/chimurai/http-proxy-middleware
17 | var proxyTable = config.dev.proxyTable
18 |
19 | var app = express()
20 | var compiler = webpack(webpackConfig)
21 |
22 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
23 | publicPath: webpackConfig.output.publicPath,
24 | stats: {
25 | colors: true,
26 | chunks: false
27 | }
28 | })
29 |
30 | var hotMiddleware = require('webpack-hot-middleware')(compiler)
31 | // force page reload when html-webpack-plugin template changes
32 | compiler.plugin('compilation', function (compilation) {
33 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
34 | hotMiddleware.publish({ action: 'reload' })
35 | cb()
36 | })
37 | })
38 |
39 | // proxy api requests
40 | Object.keys(proxyTable).forEach(function (context) {
41 | var options = proxyTable[context]
42 | if (typeof options === 'string') {
43 | options = { target: options }
44 | }
45 | app.use(proxyMiddleware(context, options))
46 | })
47 |
48 | // handle fallback for HTML5 history API
49 | app.use(require('connect-history-api-fallback')())
50 |
51 | // serve webpack bundle output
52 | app.use(devMiddleware)
53 |
54 | // enable hot-reload and state-preserving
55 | // compilation error display
56 | app.use(hotMiddleware)
57 |
58 | // serve pure static assets
59 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
60 | app.use(staticPath, express.static('./static'))
61 |
62 | module.exports = app.listen(port, function (err) {
63 | if (err) {
64 | console.log(err)
65 | return
66 | }
67 | var uri = 'http://localhost:' + port
68 | console.log('Listening at ' + uri + '\n')
69 |
70 | // when env is testing, don't need open it
71 | if (process.env.NODE_ENV !== 'testing') {
72 | opn(uri)
73 | }
74 | })
75 |
--------------------------------------------------------------------------------
/template/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.docs.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 | // generate loader string to be used with extract text plugin
15 | function generateLoaders (loaders) {
16 | var sourceLoader = loaders.map(function (loader) {
17 | var extraParamChar
18 | if (/\?/.test(loader)) {
19 | loader = loader.replace(/\?/, '-loader?')
20 | extraParamChar = '&'
21 | } else {
22 | loader = loader + '-loader'
23 | extraParamChar = '?'
24 | }
25 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
26 | }).join('!')
27 |
28 | // Extract CSS when that option is specified
29 | // (which is the case during production docs)
30 | if (options.extract) {
31 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
32 | } else {
33 | return ['vue-style-loader', sourceLoader].join('!')
34 | }
35 | }
36 |
37 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
38 | return {
39 | css: generateLoaders(['css']),
40 | postcss: generateLoaders(['css']),
41 | less: generateLoaders(['css', 'less']),
42 | sass: generateLoaders(['css', 'sass?indentedSyntax']),
43 | scss: generateLoaders(['css', 'sass']),
44 | stylus: generateLoaders(['css', 'stylus']),
45 | styl: generateLoaders(['css', 'stylus'])
46 | }
47 | }
48 |
49 | // Generate loaders for standalone style files (outside of .vue)
50 | exports.styleLoaders = function (options) {
51 | var output = []
52 | var loaders = exports.cssLoaders(options)
53 | for (var extension in loaders) {
54 | var loader = loaders[extension]
55 | output.push({
56 | test: new RegExp('\\.' + extension + '$'),
57 | loader: loader
58 | })
59 | }
60 | return output
61 | }
62 |
--------------------------------------------------------------------------------
/template/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var utils = require('./utils')
4 | var projectRoot = path.resolve(__dirname, '../')
5 |
6 | var env = process.env.NODE_ENV
7 | // check env & config/index.js to decide weither to enable CSS Sourcemaps for the
8 | // various preprocessor loaders added to vue-loader at the end of this file
9 | var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
10 | var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
11 | var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
12 |
13 | module.exports = {
14 | entry: {
15 | app: './docs/main.js'
16 | },
17 | output: {
18 | path: config.docs.assetsRoot,
19 | publicPath: process.env.NODE_ENV === 'production' ? config.docs.assetsPublicPath : config.dev.assetsPublicPath,
20 | filename: '[name].js'
21 | },
22 | resolve: {
23 | extensions: ['', '.js', '.vue'],
24 | fallback: [path.join(__dirname, '../node_modules')],
25 | alias: {
26 | {{#if_eq build "standalone"}}
27 | 'vue$': 'vue/dist/vue',
28 | {{/if_eq}}
29 | 'src': path.resolve(__dirname, '../src'),
30 | 'assets': path.resolve(__dirname, '../src/assets'),
31 | 'components': path.resolve(__dirname, '../src/components')
32 | }
33 | },
34 | resolveLoader: {
35 | fallback: [path.join(__dirname, '../node_modules')]
36 | },
37 | module: {
38 | {{#lint}}
39 | preLoaders: [
40 | {
41 | test: /\.vue$/,
42 | loader: 'eslint',
43 | include: projectRoot,
44 | exclude: /node_modules/
45 | },
46 | {
47 | test: /\.js$/,
48 | loader: 'eslint',
49 | include: projectRoot,
50 | exclude: /node_modules/
51 | }
52 | ],
53 | {{/lint}}
54 | loaders: [
55 | {
56 | test: /\.vue$/,
57 | loader: 'vue'
58 | },
59 | {
60 | test: /\.js$/,
61 | loader: 'babel',
62 | include: projectRoot,
63 | exclude: /node_modules/
64 | },
65 | {
66 | test: /\.json$/,
67 | loader: 'json'
68 | },
69 | {
70 | test: /\.pug$/,
71 | loader: 'pug'
72 | },
73 | {
74 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
75 | loader: 'url',
76 | query: {
77 | limit: 10000,
78 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
79 | }
80 | },
81 | {
82 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
83 | loader: 'url',
84 | query: {
85 | limit: 10000,
86 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
87 | }
88 | }
89 | ]
90 | },
91 | {{#lint}}
92 | eslint: {
93 | formatter: require('eslint-friendly-formatter')
94 | },
95 | {{/lint}}
96 | vue: {
97 | loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
98 | postcss: [
99 | require('autoprefixer')({
100 | browsers: ['last 2 versions']
101 | })
102 | ]
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/template/build/webpack.bundle.conf.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const CopyWebpackPlugin = require('copy-webpack-plugin')
3 | const base = require('./webpack.base.conf')
4 | const config = require('../config')
5 |
6 | base.entry = {
7 | lib: './src/index.js'
8 | }
9 |
10 | base.output = {
11 | path: config.bundle.assetsRoot,
12 | publicPath: config.bundle.assetsPublicPath,
13 | filename: '{{ name }}.min.js',
14 | library: '{{ name }}',
15 | libraryTarget: 'umd'
16 | }
17 |
18 | var webpackConfig = Object.assign({}, base)
19 |
20 | webpackConfig.plugins = (webpackConfig.plugins || []).concat([
21 | new webpack.DefinePlugin({
22 | 'process.env': {
23 | NODE_ENV: '"production"'
24 | }
25 | }),
26 | new webpack.optimize.UglifyJsPlugin({
27 | compress: { warnings: false }
28 | }),
29 | new webpack.optimize.OccurenceOrderPlugin(),
30 | new CopyWebpackPlugin([
31 | { from: './src/' }
32 | ], {
33 | ignore: ['.DS_Store', 'index.js']
34 | })
35 | ])
36 |
37 | module.exports = webpackConfig
38 |
--------------------------------------------------------------------------------
/template/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var webpack = require('webpack')
3 | var merge = require('webpack-merge')
4 | var utils = require('./utils')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 |
8 | // add hot-reload related code to entry chunks
9 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
10 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
11 | })
12 |
13 | module.exports = merge(baseWebpackConfig, {
14 | module: {
15 | loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
16 | },
17 | // eval-source-map is faster for development
18 | devtool: '#eval-source-map',
19 | plugins: [
20 | new webpack.DefinePlugin({
21 | 'process.env': config.dev.env
22 | }),
23 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
24 | new webpack.optimize.OccurenceOrderPlugin(),
25 | new webpack.HotModuleReplacementPlugin(),
26 | new webpack.NoErrorsPlugin(),
27 | // https://github.com/ampedandwired/html-webpack-plugin
28 | new HtmlWebpackPlugin({
29 | filename: 'index.html',
30 | template: 'docs/index.pug',
31 | inject: true
32 | })
33 | ]
34 | })
35 |
--------------------------------------------------------------------------------
/template/build/webpack.docs.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var utils = require('./utils')
4 | var webpack = require('webpack')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
8 | var HtmlWebpackPlugin = require('html-webpack-plugin')
9 | var env = {{#if_or unit e2e}}process.env.NODE_ENV === 'testing'
10 | ? require('../config/test.env')
11 | : {{/if_or}}config.docs.env
12 |
13 | var webpackConfig = merge(baseWebpackConfig, {
14 | module: {
15 | loaders: utils.styleLoaders({ sourceMap: config.docs.productionSourceMap, extract: true })
16 | },
17 | devtool: config.docs.productionSourceMap ? '#source-map' : false,
18 | output: {
19 | path: config.docs.assetsRoot,
20 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
21 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
22 | },
23 | vue: {
24 | loaders: utils.cssLoaders({
25 | sourceMap: config.docs.productionSourceMap,
26 | extract: true
27 | })
28 | },
29 | plugins: [
30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
31 | new webpack.DefinePlugin({
32 | 'process.env': env
33 | }),
34 | new webpack.optimize.UglifyJsPlugin({
35 | compress: {
36 | warnings: false
37 | }
38 | }),
39 | new webpack.optimize.OccurenceOrderPlugin(),
40 | // extract css into its own file
41 | new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
42 | // generate dist index.html with correct asset hash for caching.
43 | // you can customize output by editing /index.html
44 | // see https://github.com/ampedandwired/html-webpack-plugin
45 | new HtmlWebpackPlugin({
46 | filename: {{#if_or unit e2e}}process.env.NODE_ENV === 'testing'
47 | ? 'index.html'
48 | : {{/if_or}}config.docs.index,
49 | template: 'docs/index.html',
50 | inject: true,
51 | minify: {
52 | removeComments: true,
53 | collapseWhitespace: true,
54 | removeAttributeQuotes: true
55 | // more options:
56 | // https://github.com/kangax/html-minifier#options-quick-reference
57 | },
58 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
59 | chunksSortMode: 'dependency'
60 | }),
61 | // split vendor js into its own file
62 | new webpack.optimize.CommonsChunkPlugin({
63 | name: 'vendor',
64 | minChunks: function (module, count) {
65 | // any required modules inside node_modules are extracted to vendor
66 | return (
67 | module.resource &&
68 | /\.js$/.test(module.resource) &&
69 | module.resource.indexOf(
70 | path.join(__dirname, '../node_modules')
71 | ) === 0
72 | )
73 | }
74 | }),
75 | // extract webpack runtime and module manifest to its own file in order to
76 | // prevent vendor hash from being updated whenever app bundle is updated
77 | new webpack.optimize.CommonsChunkPlugin({
78 | name: 'manifest',
79 | chunks: ['vendor']
80 | })
81 | ]
82 | })
83 |
84 | module.exports = webpackConfig
85 |
--------------------------------------------------------------------------------
/template/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/template/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | dev: {
6 | env: require('./dev.env'),
7 | port: 8080,
8 | assetsSubDirectory: 'static',
9 | assetsPublicPath: '/',
10 | proxyTable: {},
11 | // CSS Sourcemaps off by default because relative paths are "buggy"
12 | // with this option, according to the CSS-Loader README
13 | // (https://github.com/webpack/css-loader#sourcemaps)
14 | // In our experience, they generally work as expected,
15 | // just be aware of this issue when enabling this option.
16 | cssSourceMap: false
17 | },
18 | bundle: {
19 | env: require('./prod.env'),
20 | assetsRoot: path.resolve(__dirname, '../dist'),
21 | assetsPublicPath: '/'
22 | },
23 | docs: {
24 | env: require('./prod.env'),
25 | index: path.resolve(__dirname, '../gh-pages/index.html'),
26 | assetsRoot: path.resolve(__dirname, '../gh-pages'),
27 | assetsSubDirectory: 'static',
28 | assetsPublicPath: '',
29 | productionSourceMap: true
30 | },
31 | }
32 |
--------------------------------------------------------------------------------
/template/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/template/config/test.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var devEnv = require('./dev.env')
3 |
4 | module.exports = merge(devEnv, {
5 | NODE_ENV: '"testing"'
6 | })
7 |
--------------------------------------------------------------------------------
/template/docs/assets/_functions.sass:
--------------------------------------------------------------------------------
1 | @function no-unit($value)
2 | @return $value / ($value * 0 + 1)
3 |
4 | @function to-rem($rem, $base-size: 16px)
5 | $rem: no-unit($rem) / no-unit($base-size) * 1rem
6 | @if ($rem == 0rem)
7 | $rem: 0
8 | @return $rem
9 |
10 | @function rem($values)
11 | $values-list: length($values)
12 |
13 | @if $values-list == 1
14 | @return to-rem($values)
15 |
16 | $rem-list: ()
17 |
18 | @for $i from 1 through $values-list
19 | $rem-list: append($rem-list, to-rem(nth($values, $i)))
20 |
21 | @return $rem-list
22 |
23 | @mixin spinner($size: 16px, $color: #333, $border-width: 2px)
24 | width: rem($size)
25 |
26 | &:before,
27 | &:after
28 | position: absolute
29 | content: ''
30 | top: 50%
31 | left: 50%
32 | margin: rem($size / -2 0 0 $size / -2)
33 | width: rem($size)
34 | height: rem($size)
35 | border-radius: 100%
36 | border-color: $color transparent transparent
37 | border-style: solid
38 | border-width: $border-width
39 | box-shadow: 0 0 0 1px transparent
40 |
41 | &:before
42 | animation: spinning 1.8s cubic-bezier(0.41, 0.26, 0.2, 0.62)
43 | animation-iteration-count: infinite
44 |
45 | &:after
46 | animation: spinning 1.8s cubic-bezier(0.51, 0.09, 0.21, 0.8)
47 | animation-iteration-count: infinite
48 |
49 | @keyframes spinning
50 | 0%
51 | transform: rotate3d(0, 0, 1, 0)
52 | 100%
53 | transform: rotate3d(0, 0, 1, 720deg)
54 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_animations.sass:
--------------------------------------------------------------------------------
1 | @keyframes spinning
2 | 0%
3 | transform: rotate3d(0, 0, 1, 0)
4 | 100%
5 | transform: rotate3d(0, 0, 1, 720deg)
6 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_functions.sass:
--------------------------------------------------------------------------------
1 | @function no-unit($value)
2 | @return $value / ($value * 0 + 1)
3 |
4 | @function to-rem($rem, $base-size: $global-font-size)
5 | $rem: no-unit($rem) / no-unit($base-size) * 1rem
6 | @if ($rem == 0rem)
7 | $rem: 0
8 | @return $rem
9 |
10 | @function rem($values)
11 | $values-list: length($values)
12 |
13 | @if $values-list == 1
14 | @return to-rem($values)
15 |
16 | $rem-list: ()
17 |
18 | @for $i from 1 through $values-list
19 | $rem-list: append($rem-list, to-rem(nth($values, $i)))
20 |
21 | @return $rem-list
22 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_global.sass:
--------------------------------------------------------------------------------
1 | $primary-color: #41B883
2 |
3 | $secondary-color: #374853
4 | $secondary-lighten-color: #939EA5
5 | $tertiary-color: #F3F3F3
6 | $quaternary-color: #bbb
7 |
8 | $bright-grey-color: #E8E8E8
9 |
10 | $error-color: #f04124
11 | $success-color: #43AC6A
12 | $alert-color: #f08a24
13 | $info-color: #5fadd6
14 |
15 | $global-radius: 5px
16 |
17 | // z-index stack concept
18 | // Please go to utils/_z-stack.scss for easy config
19 | // .sass syntax lacks multiline list declarations ;(
20 |
21 |
22 | // global
23 | $global-font-size: 16px
24 | $global-font: 'Lato', sans-serif
25 | $global-font-secondary: 'Dosis', sans-serif
26 | $global-font-weight-light: 300
27 | $global-font-weight: 300
28 | $global-font-weight-bold: 700
29 | $global-font-weight-black: 700
30 | $global-font-color: $secondary-color
31 | $global-font-inverted: #fff
32 | $global-background: #fff
33 | $global-support-background: #fafafa
34 | $global-grid-columns: 12
35 | $global-page-width: 1400px
36 | $global-gutter: 40px
37 | $global-v-gutter: 30px
38 | $global-topbar-height: 70px
39 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_media.sass:
--------------------------------------------------------------------------------
1 | $screen: "only screen" !default
2 |
3 | $small: 640px
4 | $medium: 1024px
5 | $large: 1440px
6 | $xlarge: 1920px
7 |
8 | $landscape: "#{$screen} and (orientation: landscape)"
9 | $portrait: "#{$screen} and (orientation: portrait)"
10 |
11 | $small-up: $screen !default
12 | $small-only: "#{$screen} and (max-width: #{$small})" !default
13 |
14 | $medium-up: "#{$screen} and (min-width: #{$small})" !default
15 | $medium-only: "#{$screen} and (min-width: #{$small}) and (max-width: #{$medium})" !default
16 |
17 | $large-up: "#{$screen} and (min-width: #{$medium})" !default
18 | $large-only: "#{$screen} and (min-width: #{$medium}) and (max-width: #{$large})" !default
19 |
20 | $xlarge-up: "#{$screen} and (min-width: #{$large})" !default
21 | $xlarge-only: "#{$screen} and (min-width: #{$large}) and (max-width: #{$xlarge})" !default
22 |
23 | $xxlarge-up: "#{$screen} and (min-width: #{$xlarge})" !default
24 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_mixins.sass:
--------------------------------------------------------------------------------
1 | @mixin clearfix
2 | &:before,
3 | &:after
4 | content: ""
5 | display: table
6 | &:after
7 | clear: both
8 |
9 | @mixin spinner($size: 16px, $color: #333, $border-width: 2px)
10 | width: rem($size)
11 |
12 | &:before,
13 | &:after
14 | position: absolute
15 | content: ''
16 | top: 50%
17 | left: 50%
18 | margin: rem($size / -2 0 0 $size / -2)
19 | width: rem($size)
20 | height: rem($size)
21 | border-radius: 100%
22 | border-color: $color transparent transparent
23 | border-style: solid
24 | border-width: $border-width
25 | box-shadow: 0 0 0 1px transparent
26 |
27 | &:before
28 | animation: spinning 2.4s cubic-bezier(0.41, 0.26, 0.2, 0.62)
29 | animation-iteration-count: infinite
30 |
31 | &:after
32 | animation: spinning 2.4s cubic-bezier(0.51, 0.09, 0.21, 0.8)
33 | animation-iteration-count: infinite
34 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_typo.sass:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Lato:700,300)
2 | @import url('https://fonts.googleapis.com/css?family=Dosis:400')
3 |
4 | // config
5 | $header-line-height: 1.2
6 | $header-color: $secondary-color
7 |
8 | $header-h1-family: $global-font-secondary
9 | $header-h1-size-ratio-lg: 2.5 // 48px
10 | $header-h1-size-ratio-md: 2.5 // 40px
11 | $header-h1-size-ratio-sm: 2 // 32px
12 | $header-h1-weight: $global-font-weight-bold
13 |
14 | $header-h2-family: $global-font-secondary
15 | $header-h2-size-ratio-lg: 1.8 // 36px
16 | $header-h2-size-ratio-md: 1.8 // 32px
17 | $header-h2-size-ratio-sm: 1.625 // 26px
18 | $header-h2-weight: $global-font-weight-bold
19 |
20 | $header-h3-family: $global-font-secondary
21 | $header-h3-size-ratio-lg: 1.5 // 28px
22 | $header-h3-size-ratio-md: 1.5 // 24px
23 | $header-h3-size-ratio-sm: 1.375 // 22px
24 | $header-h3-weight: $global-font-weight-bold
25 |
26 | $header-h4-family: $global-font
27 | $header-h4-size-ratio-sm: 1.375
28 | $header-h4-size-ratio-md: 1.375
29 | $header-h4-size-ratio-lg: 1.125
30 | $header-h4-weight: $global-font-weight-light
31 |
32 | $paragraph-family: $global-font
33 | $paragraph-font-size-ratio-lg: 1.125 // 18px
34 | $paragraph-font-size-ratio-md: 1.125 // 18px
35 | $paragraph-font-size-ratio-sm: 1 // 16px
36 | $paragraph-font-weight: $global-font-weight
37 | $paragraph-line-height: 1.8
38 | $paragraph-color: $secondary-color
39 |
40 | $hr-margin: 30px
41 | $hr-border: 1px solid $bright-grey-color
42 |
43 | $blockquote-family: $global-font-secondary
44 | $blockqoute-cite-family: $global-font
45 | $blockquote-font-size: 16px
46 | $blockquote-line-height: 1.8
47 | $blockquote-color: $secondary-lighten-color
48 | $blockquote-padding: 5px 20px
49 | $blockquote-border: 1px solid $bright-grey-color
50 |
51 | $label-font-size: 14px
52 |
53 | body
54 | color: $global-font-color
55 | font-size: $global-font-size
56 |
57 | *::selection,
58 | background: $primary-color
59 | color: #fff
60 |
61 | .typo__h1,
62 | .typo__h2,
63 | .typo__h3,
64 | .typo__h4,
65 | .typo__h5
66 | margin-top: 0
67 | margin-bottom: rem($global-font-size)
68 | color: $header-color
69 | line-height: $header-line-height
70 |
71 | .typo__h1
72 | font:
73 | family: $header-h1-family
74 | weight: $header-h1-weight
75 | size: rem($header-h1-size-ratio-sm * $global-font-size)
76 | margin-bottom: rem(40px)
77 |
78 | @media #{$medium-up}
79 | font-size: rem($header-h1-size-ratio-md * $global-font-size)
80 |
81 | @media #{$large-up}
82 | font-size: rem($header-h1-size-ratio-lg * $global-font-size)
83 |
84 | .typo__h2
85 | font:
86 | family: $header-h2-family
87 | weight: $header-h2-weight
88 | size: rem($header-h2-size-ratio-sm * $global-font-size)
89 | padding-top: rem(60px)
90 |
91 | @media #{$medium-up}
92 | font-size: rem($header-h2-size-ratio-md * $global-font-size)
93 |
94 | @media #{$large-up}
95 | font-size: rem($header-h2-size-ratio-lg * $global-font-size)
96 |
97 | .typo__h3
98 | font:
99 | family: $header-h3-family
100 | weight: $header-h3-weight
101 | size: rem($header-h3-size-ratio-sm * $global-font-size)
102 |
103 | @media #{$medium-up}
104 | font-size: rem($header-h3-size-ratio-md * $global-font-size)
105 |
106 | @media #{$large-up}
107 | font-size: rem($header-h3-size-ratio-lg * $global-font-size)
108 |
109 | .typo__h4
110 | font:
111 | family: $header-h4-family
112 | weight: $header-h4-weight
113 | size: rem($header-h4-size-ratio-sm * $global-font-size)
114 |
115 | @media #{$medium-up}
116 | font-size: rem($header-h4-size-ratio-md * $global-font-size)
117 |
118 | @media #{$large-up}
119 | font-size: rem($header-h4-size-ratio-lg * $global-font-size)
120 |
121 | .typo__p
122 | margin-top: 0
123 | margin-bottom: rem($paragraph-font-size-ratio-sm * $global-font-size)
124 | line-height: $paragraph-line-height
125 | font:
126 | family: $paragraph-family
127 | weight: $paragraph-font-weight
128 | size: rem($paragraph-font-size-ratio-sm * $global-font-size)
129 |
130 | @media #{$medium-up}
131 | font-size: rem($paragraph-font-size-ratio-md * $global-font-size)
132 |
133 | @media #{$large-up}
134 | font-size: rem($paragraph-font-size-ratio-lg * $global-font-size)
135 |
136 | .typo__blockquote
137 | font:
138 | family: $blockquote-family
139 | size: rem($blockquote-font-size)
140 | color: $blockquote-color
141 | margin: 0px
142 | border-left: $blockquote-border
143 | padding: rem($blockquote-padding)
144 | line-height: $blockquote-line-height
145 | text-align: left
146 |
147 | cite
148 | font:
149 | size: rem($blockquote-font-size - 2px)
150 | weight: $global-font-weight-bold
151 | family: $blockqoute-cite-family
152 | style: normal
153 | margin-top: 6px
154 | display: block
155 | color: $secondary-color
156 |
157 | &:before
158 | content: "\2014 \0020"
159 |
160 | .typo__hr
161 | border: none
162 | border-bottom: $hr-border
163 | margin: rem($hr-margin) 0
164 | outline: none
165 |
166 | .typo__link
167 | color: $primary-color
168 | text-decoration: none
169 | font-weight: 700
170 |
171 | .typo__label
172 | font-family: $global-font
173 | font-weight: $global-font-weight
174 | font-size: rem($label-font-size)
175 | color: $quaternary-color
176 | margin: rem(20px) 0 rem(10px)
177 | display: block
178 |
179 | .typo__text
180 | font-family: $global-font
181 | font-size: rem($label-font-size + 2px)
182 | display: block
183 | margin: 0
184 | line-height: 1.4
185 |
186 | .typo--bold, strong
187 | font-weight: $global-font-weight-bold
188 |
189 | kbd
190 | color: $primary-color
191 | padding: 3px 5px
192 | border-radius: 4px
193 | background: $tertiary-color
194 |
--------------------------------------------------------------------------------
/template/docs/assets/base/_z-stack.scss:
--------------------------------------------------------------------------------
1 | $z-index-list:
2 | modal,
3 | modal-bg,
4 | mobile-trigger,
5 | panel,
6 | topbar,
7 | mobile,
8 | notify,
9 | sidebar,
10 | dropdown,
11 | content,
12 | offcanvas;
13 |
14 | @function z-index($element, $stack: $z-index-list, $step: 100) {
15 | $z-index-value: (length($stack) - index($stack, $element)) * $step + $step;
16 | @return $z-index-value;
17 | }
18 |
--------------------------------------------------------------------------------
/template/docs/assets/base/normalize.scss:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | button,
291 | html input[type="button"], /* 1 */
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_avatars.sass:
--------------------------------------------------------------------------------
1 | $avatar-size: 120px
2 | $avatar-size-small: 60px
3 |
4 | .avatar
5 | display: inline-block
6 | vertical-align: middle
7 | max-width: 100%
8 | max-height: rem($avatar-size)
9 | border-radius: $global-radius
10 | margin-bottom: rem(10px)
11 | margin-top: rem(10px)
12 |
13 | & + &
14 | margin-left: rem(12px)
15 |
16 | &--small
17 | max-height: rem($avatar-size-small)
18 |
19 | &--round
20 | border-radius: 100%
21 |
22 | .avatar__description
23 | margin-left: rem(10px)
24 | vertical-align: middle
25 | display: inline-block
26 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_breadcrumbs.sass:
--------------------------------------------------------------------------------
1 | .breadcrumbs
2 | font:
3 | size: rem(12px)
4 | weight: $global-font-weight
5 | line-height: rem(20px)
6 | text-transform: uppercase
7 | color: $secondary-color
8 | margin: rem($global-v-gutter) 0
9 |
10 | a.breadcrumbs__element
11 | color: $primary-color
12 | text-decoration: none
13 |
14 | &:after
15 | content: "/"
16 | margin: rem(0 5px)
17 |
18 | .breadcrumbs__element
19 | display: inline-block
20 |
21 | &:last-child
22 | font-weight: $global-font-weight-black
23 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_buttons.sass:
--------------------------------------------------------------------------------
1 | // config
2 | $button-height-xlarge: 60px
3 | $button-height-large: 50px
4 | $button-height: 40px
5 | $button-height-small: 30px
6 | $button-padding-xlarge: 14px 50px 15px
7 | $button-padding-large: 11px 40px 13px
8 | $button-padding: 8px 30px 10px
9 | $button-padding-small: 6px 20px 6px
10 | $button-size-xlarge: 18px
11 | $button-size-large: 16px
12 | $button-size: 14px
13 | $button-size-small: 12px
14 | $button-hollow-border: 1px
15 | $button-background: $primary-color
16 | $button-color: $global-font-inverted
17 | $button-font-weight: $global-font-weight-bold
18 | $button-border-radius: $global-radius
19 | $button-border: 3px
20 |
21 | @mixin button-variant($name, $color)
22 | .button--#{$name}
23 | background: $color
24 | border-bottom: $button-border solid darken($color, 20%)
25 |
26 | &:hover,
27 | &:focus
28 | background: darken($color, 10%)
29 | cursor: pointer
30 |
31 | .button
32 | font:
33 | family: $global-font
34 | size: rem($button-size)
35 | weight: $global-font-weight
36 | color: $button-color
37 | min-height: rem($button-height)
38 | line-height: 1.4
39 | padding: rem($button-padding)
40 | box-sizing: border-box
41 | position: relative
42 | display: inline-block
43 | background: $button-background
44 | border: none
45 | border-radius: $button-border-radius
46 | z-index: 1
47 | overflow: hidden
48 | outline: none
49 | vertical-align: middle
50 | transition: 0.1s background ease, 0.1s border-color ease, 0.1s color ease
51 | border-bottom: $button-border solid darken($primary-color, 20%)
52 | text-decoration: none
53 |
54 | &:hover,
55 | &:focus
56 | background: darken($button-background, 10%)
57 | cursor: pointer
58 |
59 | &:active
60 | background: darken($button-background, 20%)
61 |
62 | &:focus
63 | outline: none
64 |
65 | &--small
66 | padding: rem($button-padding-small)
67 | font-size: rem($button-size-small)
68 | min-height: rem($button-height-small)
69 |
70 | &--xlarge
71 | padding: rem($button-padding-xlarge)
72 | font-size: rem($button-size-xlarge)
73 | min-height: rem($button-height-xlarge)
74 |
75 | &--large
76 | padding: rem($button-padding-large)
77 | font-size: rem($button-size-large)
78 | min-height: rem($button-height-large)
79 |
80 | &--fake
81 | background: none
82 | color: $secondary-color
83 | border-color: transparent
84 |
85 | &:hover, &:focus
86 | background: rgba(#000, 0.05)
87 |
88 | &--hollow
89 | background: none
90 | color: $secondary-color
91 | border: $button-hollow-border solid darken($bright-grey-color, 25%)
92 |
93 | &:hover,
94 | &:focus
95 | background: rgba(#000, 0.05)
96 | color: darken($secondary-color, 80%)
97 | border: $button-hollow-border solid darken($bright-grey-color, 80%)
98 | cursor: pointer
99 |
100 | &--expanded
101 | width: 100%
102 |
103 | +button-variant('secondary', $secondary-color)
104 | +button-variant('success', $success-color)
105 | +button-variant('error', $alert-color)
106 | +button-variant('info', $info-color)
107 |
108 | .button__group
109 | margin-bottom: $grid-gutter-width / 2
110 | width: 100%
111 |
112 | .button
113 | display: inline-block
114 | margin:
115 | right: 0
116 | bottom: 0
117 | border-radius: 0
118 |
119 | &:first-child
120 | border-top-left-radius: $button-border-radius
121 | border-bottom-left-radius: $button-border-radius
122 |
123 | &:last-child
124 | border-top-right-radius: $button-border-radius
125 | border-bottom-right-radius: $button-border-radius
126 |
127 | $button-group-count: 3
128 |
129 | @for $i from 1 through $button-group-count
130 |
131 | .button__group--#{$i}
132 |
133 | .button
134 | width: 100% / $i
135 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_dropdown.sass:
--------------------------------------------------------------------------------
1 | // config
2 | $dropdown-height: 40px
3 | $dropdown-font: $global-font
4 | $dropdown-font-size: 14px
5 | $dropdown-line-height: 16px
6 | $dropdown-font-weight: $global-font-weight
7 | $dropdown-background: $global-background
8 | $dropdown-hover-bg: $global-support-background
9 | $dropdown-border: $bright-grey-color
10 | $dropdown-border-radius: $global-radius
11 | $dropdown-padding: ($dropdown-height - $dropdown-line-height) / 2
12 |
13 | .dropdown
14 | box-sizing: content-box
15 |
16 | *
17 | box-sizing: border-box
18 |
19 | display: block
20 | position: relative
21 | background: $dropdown-background
22 | width: 100%
23 | height: rem($dropdown-height)
24 | text-align: left
25 | font:
26 | family: $dropdown-font
27 | size: rem($dropdown-font-size)
28 | weight: $dropdown-font-weight
29 |
30 | &:hover,
31 | &--active
32 | z-index: z-index(dropdown)
33 |
34 | .dropdown__current,
35 | .dropdown__input
36 | border-bottom-left-radius: 0
37 | border-bottom-right-radius: 0
38 |
39 | .dropdown__list
40 | display: block
41 |
42 | .dropdown__input
43 | margin-bottom: 0
44 |
45 | .dropdown--disabled
46 | background: darken($dropdown-background, 7%)
47 | pointer-events: none
48 |
49 | .dropdown__current,
50 | .dropdown__select
51 | background: darken($dropdown-background, 7%)
52 | color: darken($dropdown-background, 35%)
53 |
54 | .dropdown__list
55 | display: none
56 | position: relative
57 | list-style: none
58 | padding: 0
59 | margin: 0
60 | background: $dropdown-background
61 | border: 1px solid $dropdown-border
62 | border-top: none
63 |
64 | .dropdown__option
65 | display: block
66 | padding: rem($dropdown-padding)
67 | min-height: rem($dropdown-height)
68 | line-height: rem(16px)
69 | color: $global-font-color
70 | font-weight: 300
71 | text-decoration: none
72 | text-transform: none
73 | vertical-align: middle
74 |
75 | &:hover, &:focus
76 | background: $dropdown-hover-bg
77 |
78 | .dropdown__icon
79 | margin-right: rem(8px)
80 |
81 | .dropdown__img
82 | display: inline-block
83 | margin-right: rem(6px)
84 | vertical-align: middle
85 | max-height: rem(18px)
86 | max-width: rem($dropdown-height)
87 |
88 | .dropdown__option--disabled
89 | background: darken($dropdown-background, 7%)
90 | color: darken($dropdown-background, 35%)
91 | cursor: text
92 | pointer-events: none
93 |
94 | &:visited
95 | color: darken($dropdown-background, 35%)
96 |
97 | &:hover,
98 | &:focus
99 | background: darken($dropdown-hover-bg, 3%)
100 |
101 | .dropdown__current
102 | line-height: rem($dropdown-line-height)
103 | min-height: rem($dropdown-height)
104 | box-sizing: border-box
105 | display: block
106 | overflow: hidden
107 | padding: rem($dropdown-padding)
108 | padding-right: 30px
109 | white-space: nowrap
110 | margin: 0
111 | color: $global-font-color
112 | text-decoration: none
113 | border-radius: $dropdown-border-radius
114 | border: 1px solid $dropdown-border
115 | cursor: pointer
116 |
117 | .dropdown__select
118 | line-height: rem(16px)
119 | display: block
120 | position: absolute
121 | box-sizing: border-box
122 | width: rem($dropdown-height)
123 | height: 100%
124 | right: rem(1px)
125 | top: rem(1px)
126 | padding: rem(4px 8px)
127 | margin: 0
128 | color: $global-font-color
129 | text-decoration: none
130 | border-left: 1px solid $dropdown-border
131 | text-align: center
132 | background: $dropdown-background
133 | cursor: pointer
134 |
135 | &:before
136 | position: absolute
137 | right: 15px
138 | top: $dropdown-height / 2 - 8
139 | color: #999
140 | margin-top: rem(4px)
141 | border-style: solid
142 | border-width: 5px 5px 0 5px
143 | border-color: #999999 transparent transparent transparent
144 | content: ""
145 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_flex_grid.sass:
--------------------------------------------------------------------------------
1 | =calc-flex-columns($class, $i: 1)
2 | @for $i from 1 through $flex-columns
3 | .flex__unit--#{$class}-#{$i}
4 | width: percentage($i / $flex-columns)
5 | flex: 0 0 percentage($i / $flex-columns)
6 |
7 | // config
8 | $flex-columns: $global-grid-columns
9 | $flex-gutter-width: $global-gutter
10 | $flex-max-width: $global-page-width
11 | $flex-equal-height-columns: true
12 |
13 | .flex__column,
14 | .flex__columns
15 | flex: 0 0 auto
16 | width: 100%
17 | padding: 0 ($flex-gutter-width/2)
18 |
19 | .flex__column--top
20 | align-self: flex-start
21 |
22 | .flex__column--middle
23 | align-self: center
24 |
25 | .flex__column--bottom
26 | align-self: flex-end
27 |
28 | .flex__row
29 | display: flex
30 | flex-wrap: wrap
31 | margin: 0 auto
32 | max-width: $flex-max-width
33 |
34 | @if $flex-equal-height-columns
35 | align-items: stretch
36 | @else
37 | align-items: flex-start
38 |
39 | .flex__row
40 | margin: 0 ($flex-gutter-width/-2)
41 | max-width: none
42 |
43 | &.flex__row--collapse
44 |
45 | & > .flex__column
46 | padding-left: 0
47 | padding-right: 0
48 |
49 | .flex__row--centered
50 | justify-content: center
51 |
52 | .flex__row--top
53 | align-items: flex-start
54 |
55 | .flex__row--middle
56 | align-items: center
57 |
58 | .flex__row--bottom
59 | align-items: flex-end
60 |
61 | .flex__row--stretch
62 | align-items: stretch
63 |
64 | +calc-flex-columns(sm)
65 |
66 | @media #{$medium-up}
67 | +calc-flex-columns(md)
68 |
69 | @media #{$large-up}
70 | +calc-flex-columns(lg)
71 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_grid.sass:
--------------------------------------------------------------------------------
1 | =calc-grid-columns($class, $i: 1)
2 | @for $i from 1 through $grid-columns
3 | .grid__unit--#{$class}-#{$i}
4 | width: percentage($i / $grid-columns)
5 |
6 | .grid__push--#{$class}-#{$i}
7 | left: percentage($i / $grid-columns)
8 | right: auto
9 |
10 | .grid__pull--#{$class}-#{$i}
11 | right: percentage($i / $grid-columns)
12 | left: auto
13 |
14 | .grid__offset--#{$class}-#{$i}
15 | margin-left: percentage($i / $grid-columns)
16 |
17 | .blocks--#{$class}-#{$i} .blocks__element
18 | width: calc(#{percentage(1 / ($grid-columns / ($grid-columns / $i)))} - #{$grid-gutter-width / 2})
19 |
20 | // config
21 | $grid-columns: $global-grid-columns
22 | $grid-gutter-width: $global-gutter
23 | $grid-max-width: $global-page-width
24 |
25 | html, body
26 | font-size: 100%
27 | height: 100%
28 |
29 | html
30 | overflow-y: auto
31 | box-sizing: border-box
32 |
33 | *, *:before, *:after
34 | box-sizing: inherit
35 |
36 | .grid__column,
37 | .grid__columns
38 | box-sizing: border-box
39 | display: inline-block
40 | font-size: 1rem
41 | margin: 0
42 | text-align: left
43 | vertical-align: top
44 | width: 100%
45 | position: relative
46 | padding: 0 ($grid-gutter-width/2)
47 |
48 | .grid__column--centered
49 | display: block
50 | margin: 0 auto
51 |
52 | .grid__row--middle
53 | .grid__column,
54 | .grid__columns
55 | vertical-align: middle
56 |
57 | .grid__row--bottom
58 | .grid__column,
59 | .grid__columns
60 | vertical-align: bottom
61 |
62 | .grid__row
63 | +clearfix
64 |
65 | display: block
66 | font-size: 0
67 | margin: 0 auto
68 | box-sizing: border-box
69 | padding: 0
70 | text-align: left
71 | max-width: $grid-max-width
72 |
73 | .grid__row
74 | margin: 0 ($grid-gutter-width/-2)
75 |
76 |
77 | &.grid__row--collapse
78 |
79 | & > .grid__column
80 | padding-left: 0
81 | padding-right: 0
82 |
83 | .grid__row--full
84 | max-width: 100%
85 |
86 | .grid__row--centered
87 | text-align: center
88 |
89 | .grid__push--small-reset
90 | left: auto !important
91 | right: auto !important
92 |
93 | .blocks
94 | margin: 0 $grid-gutter-width / -4
95 |
96 | .blocks__element
97 | position: relative
98 | float: left
99 | box-sizing: border-box
100 | transition: background .2s ease
101 | margin: $grid-gutter-width/4
102 |
103 |
104 | +calc-grid-columns(sm)
105 |
106 | @media #{$medium-up}
107 |
108 | html, body
109 | overflow-x: initial
110 |
111 | .grid__push--md-reset
112 | left: auto
113 | right: auto
114 |
115 | +calc-grid-columns(md)
116 |
117 | @media #{$large-up}
118 |
119 | .grid__push--lg-reset
120 | left: auto
121 | right: auto
122 |
123 | +calc-grid-columns(lg)
124 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_inputs.sass:
--------------------------------------------------------------------------------
1 | // config
2 | $input-font: $global-font
3 | $input-font-color: $secondary-color
4 | $input-font-weight: $global-font-weight
5 | $input-font-size: 14px
6 | $input-height: 40px
7 | $input-border-width: 1px
8 | $input-border-color: $bright-grey-color
9 | $input-border: $input-border-width solid $input-border-color
10 | $input-label-left-margin: 14px
11 | $input-padding: 0 13px
12 | $input-margin-bottom: $global-font-size * 2
13 | $input-label-color: lighten($input-font-color, 10%)
14 | $input-label-size: 13px
15 | $input-background: $global-background
16 | $input-radius: $global-radius
17 | $input-select-font-size: 14px
18 | $input-select-background: $global-background
19 | $input-message-font-size: 12px
20 | $input-message-margin: 5px
21 |
22 | $input-addon-weight: 700
23 |
24 | .form
25 | position: relative
26 |
27 | .form__input,
28 | .form__textarea
29 | position: relative
30 | margin:
31 | bottom: rem($input-margin-bottom)
32 |
33 | .form__input,
34 | .form__textarea
35 | font:
36 | family: $input-font
37 | size: rem($input-font-size)
38 | weight: $input-font-weight
39 | color: $global-font-color
40 | line-height: rem($input-height - 2*$input-border-width)
41 | min-height: rem($input-height - 2*$input-border-width)
42 | position: relative
43 | border: $input-border
44 | border-radius: $input-radius
45 | background: $input-background
46 | padding: rem($input-padding)
47 | width: 100%
48 | transition: border .1s ease
49 | box-sizing: border-box
50 |
51 | &:hover
52 | border-color: darken($input-border-color, 10%)
53 |
54 | &:focus
55 | border-color: darken($input-border-color, 25%)
56 | outline: none
57 |
58 | &--with-left-icon
59 | padding-left: rem(45px)
60 |
61 | &--with-right-icon
62 | padding-right: rem(45px)
63 |
64 | .form__icon
65 | position: absolute
66 | pointer-events: none
67 | top: -1px
68 | height: rem($input-height)
69 | line-height: rem($input-height)
70 |
71 | &--right
72 | right: rem(15px)
73 |
74 | &--left
75 | left: rem(13px)
76 |
77 | .form__textarea
78 | max-width: 100%
79 | min-height: rem(82px)
80 | resize: none
81 | line-height: 1.4
82 | padding-top: $input-height / 4
83 |
84 | .form__label
85 | font-size: rem($input-label-size)
86 | color: $input-label-color
87 | margin:
88 | bottom: rem(5px)
89 | left: rem($input-label-left-margin)
90 | display: block
91 | font-family: $global-font
92 |
93 | .form__label--inline
94 | @extend .form__label
95 |
96 | display: inline-block
97 | margin-right: rem($grid-gutter-width / 2)
98 | margin-left: rem($grid-gutter-width / 5)
99 |
100 | .form-group
101 | margin-bottom: rem($input-margin-bottom)
102 |
103 | .form__input,
104 | .form__textarea
105 | margin-bottom: 0
106 |
107 | .form-group--merged
108 | font-size: 0
109 | display: table
110 | width: 100%
111 | border-collapse: separate
112 |
113 | .form__label
114 | display: table-caption
115 |
116 | .form-group__input,
117 | .form-group__addon,
118 | .form-group__button
119 | display: table-cell
120 | vertical-align: middle
121 | margin: 0
122 | white-space: nowrap
123 |
124 | .form-group__addon:first-child,
125 | .form-group__input:first-child,
126 | .form-group__button:first-child .button
127 | border-top-right-radius: 0
128 | border-bottom-right-radius: 0
129 | margin-right: -1px
130 |
131 | .form-group__addon:last-child,
132 | .form-group__input:last-child,
133 | .form-group__button:last-child .button
134 | border-top-left-radius: 0
135 | border-bottom-left-radius: 0
136 | margin-left: -1px
137 |
138 | .form-group__input:not(:first-child):not(:last-child),
139 | .form-group__addon:not(:first-child):not(:last-child),
140 | .form-group__button:not(:first-child):not(:last-child) .button
141 | border-radius: 0
142 |
143 | .form-group__button:not(:first-child):not(:last-child) .button
144 | margin-left: -1px
145 | margin-right: -1px
146 |
147 | .form-group__addon:first-child
148 | border-right: none
149 |
150 | .form-group__addon:last-child
151 | border-left: none
152 |
153 | .form-group__addon
154 | background: $tertiary-color
155 | border: $input-border
156 | border-radius: $input-radius
157 | height: rem($input-height - 2*$input-border-width)
158 | line-height: rem($input-height - 2*$input-border-width)
159 | width: 1%
160 | padding: $input-padding
161 | font:
162 | size: $input-font-size
163 | text-align: center
164 |
165 | .form-group__button
166 | width: 1%
167 |
168 | .button
169 | margin: 0
170 | padding-right: rem(20px)
171 | padding-left: rem(20px)
172 |
173 | .form-group__message
174 | font-size: rem($input-message-font-size)
175 | line-height: 1
176 | display: none
177 | margin:
178 | left: $input-label-left-margin
179 | top: rem(($input-margin-bottom * -1) + $input-message-margin)
180 | // Magic now :)
181 | bottom: rem(($input-margin-bottom) - ($input-message-font-size + $input-message-margin))
182 |
183 | .form-group--alert,
184 | .form-group--error
185 | animation:
186 | name: shakeError
187 | fill-mode: forward
188 | duration: .6s
189 | timing-function: ease-in-out
190 |
191 | .form-group--success
192 | .form__label
193 | color: $success-color
194 |
195 | .form-group__addon
196 | color: white
197 | border-color: lighten($success-color, 20%)
198 | background: lighten($success-color, 20%)
199 |
200 | input,
201 | textarea,
202 | input:focus,
203 | input:hover
204 | border-color: lighten($success-color, 20%)
205 |
206 | & + .form-group__message
207 | display: block
208 | color: lighten($success-color, 15%)
209 |
210 | .form-group--error
211 | .form__label
212 | color: $error-color
213 |
214 | .form-group__addon
215 | color: white
216 | border-color: lighten($error-color, 20%)
217 | background: lighten($error-color, 20%)
218 |
219 | input,
220 | textarea,
221 | input:focus,
222 | input:hover
223 | border-color: lighten($error-color, 20%)
224 |
225 | & + .form-group__message
226 | display: block
227 | color: lighten($error-color, 15%)
228 |
229 | .form-group--alert
230 | .form__label
231 | color: $alert-color
232 |
233 | .form-group__addon
234 | color: white
235 | border-color: lighten($alert-color, 20%)
236 | background: lighten($alert-color, 20%)
237 |
238 | input,
239 | textarea,
240 | input:focus,
241 | input:hover
242 | border-color: lighten($alert-color, 20%)
243 |
244 | & + .form-group__message
245 | display: block
246 | color: lighten($alert-color, 15%)
247 |
248 | @keyframes shakeError
249 | $shake-distance: rem(6px)
250 | 0%
251 | transform: translateX(0)
252 |
253 | 15%
254 | transform: translateX($shake-distance)
255 |
256 | 30%
257 | transform: translateX(-$shake-distance)
258 |
259 | 45%
260 | transform: translateX($shake-distance)
261 |
262 | 60%
263 | transform: translateX(-$shake-distance)
264 |
265 | 75%
266 | transform: translateX($shake-distance)
267 |
268 | 90%
269 | transform: translateX(-$shake-distance)
270 |
271 | 100%
272 | transform: translateX(0)
273 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_lists.sass:
--------------------------------------------------------------------------------
1 | .list
2 | font:
3 | family: $global-font
4 | size: rem(16px)
5 | color: $secondary-color
6 | letter-spacing: 0.4px
7 | line-height: 32px
8 | list-style: none
9 |
10 | .list--sticky
11 | position: fixed
12 | top: 0
13 |
14 | .list__heading
15 | font:
16 | family: $global-font-secondary
17 | size: rem(14px)
18 | weight: $global-font-weight-bold
19 | line-height: rem(30px)
20 | color: $primary-color
21 | text-transform: uppercase
22 | letter-spacing: 0.4px
23 | margin: rem($global-v-gutter 0 10px)
24 |
25 | .list__link
26 | color: $secondary-color
27 | text-decoration: none
28 | display: block
29 | padding: rem(0 10px)
30 | margin-left: rem(-10px)
31 | border-radius: 5px
32 |
33 | &--active
34 | background: $tertiary-color
35 |
36 | &--disabled
37 | color: $secondary-lighten-color
38 | pointer-events: none
39 |
40 | .list__dl
41 | font-family: $global-font
42 | font-weight: $global-font-weight
43 |
44 | .list__dt
45 | font-size: rem(14px)
46 | margin-bottom: rem(10px)
47 | color: $quaternary-color
48 |
49 | .list__dd
50 | font-size: rem($global-font-size)
51 | margin-left: 0
52 | margin-bottom: rem(20px)
53 | line-height: 1.4
54 |
55 | .list__ul,
56 | .list__ol
57 | margin: rem(0 0 0 30px)
58 | padding: 0
59 | line-height: 1.8
60 | font-weight: $global-font-weight
61 |
62 | .list__ul
63 | list-style: square
64 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_mobile_nav.sass:
--------------------------------------------------------------------------------
1 | @import ../base/global
2 |
3 | // config
4 | $mobile-trigger-width: 55px
5 | $mobile-trigger-height: 50px
6 | $mobile-tab-height: 70px
7 | $mobile-tab-bg: $primary-color
8 | $mobile-tab-font-size: 20px
9 | $mobile-nav-bg: rgba(darken($secondary-color, 10%), .95)
10 | $mobile-link-height: 70px
11 | $mobile-link-font-size: 16px
12 | $mobile-link-color: $global-font-inverted
13 | $mobile-link-border: $global-font-color
14 | $mobile-link-bg: $primary-color
15 |
16 | =mobile-tabs-count($i: 3)
17 | .mobile__tabs--#{$i}
18 | .mobile__tab
19 | width: percentage(1 / $i)
20 |
21 |
22 | @media #{$small-only}
23 | .mobile__block-overflow
24 | overflow: hidden
25 |
26 | .mobile
27 | z-index: z-index(mobile)
28 | position: fixed
29 | height: 100%
30 | width: 100%
31 | top: 0
32 | left: 0
33 | background: $mobile-nav-bg
34 | transform: translateY(-100%)
35 | transition: transform .3s ease
36 |
37 | @media #{$large-up}
38 | display: none
39 |
40 | .mobile__trigger
41 | z-index: z-index(mobile-trigger)
42 | display: inline-block
43 | border: none
44 | width: rem(55px)
45 | height: rem(50px)
46 | margin-left: rem(-15px)
47 | cursor: pointer
48 | position: relative
49 | line-height: 100%
50 | background: none
51 | vertical-align: middle
52 |
53 | span
54 | position: absolute
55 | top: rem(23px)
56 | left: rem(15px)
57 | right: rem(15px)
58 | display: block
59 | height: rem(3px)
60 | background: $secondary-color
61 | transition: transform .3s ease, top .1s ease
62 |
63 | &:before,
64 | &:after
65 | content: ""
66 | position: absolute
67 | display: block
68 | left: 0
69 | width: 100%
70 | background: $secondary-color
71 | height: 100%
72 | transition: transform .3s ease, top .2s ease
73 | transform-origin: 50% 50%
74 |
75 | &:before
76 | top: rem(-7px)
77 |
78 | &:after
79 | top: rem(7px)
80 |
81 | &:hover
82 |
83 | span:before
84 | top: rem(-9px)
85 |
86 | span:after
87 | top: rem(9px)
88 |
89 | .mobile--show,
90 | .offcanvas--right
91 |
92 | .mobile__trigger
93 |
94 | span
95 | background: transparent
96 |
97 | span:before, span:after
98 |
99 | top: 0
100 |
101 | span:before
102 | transform: rotate3d(0,0,1,45deg)
103 |
104 | span:after
105 | transform: rotate3d(0,0,1,-45deg)
106 |
107 | .mobile
108 | transform: translateY(0)
109 |
110 | li
111 | opacity: 1
112 | transform: translateX(0)
113 |
114 | .mobile__panel
115 | position: relative
116 | display: block
117 | height: 100%
118 |
119 | .mobile__tabs
120 | position: absolute
121 | bottom: 0
122 | left: 0
123 | width: 100%
124 | height: rem($mobile-tab-height)
125 | border-top: 1px solid darken($mobile-tab-bg, 10%)
126 | font-size: 0
127 | vertical-align: middle
128 |
129 | +mobile-tabs-count(3)
130 |
131 | .mobile__tab
132 | box-sizing: border-box
133 | font-size: rem($mobile-tab-font-size)
134 | text-align: center
135 | display: inline-block
136 | color: #fff
137 | background: $mobile-tab-bg
138 | height: 100%
139 | vertical-align: middle
140 | padding: rem(16px)
141 | border-right: 1px solid darken($mobile-tab-bg, 10%)
142 |
143 | &:last-child
144 | border-right: none
145 |
146 | &:hover
147 | color: #fff
148 | background: darken($mobile-tab-bg, 10%)
149 |
150 | small
151 | display: block
152 | font-size: 60%
153 | margin-top: rem(5px)
154 |
155 | i
156 | top: rem(-10px)
157 |
158 | .mobile__nav
159 | position: absolute
160 | height: calc(100% - #{rem($mobile-tab-height)} - #{rem(20px)} - #{rem($global-topbar-height)})
161 | width: 100%
162 | top: rem($global-topbar-height)
163 | overflow-y: scroll
164 | left: 0
165 | padding: 0
166 | margin: 0
167 | font-weight: $global-font-weight
168 | text-transform: uppercase
169 |
170 | .mobile__option
171 | box-sizing: border-box
172 | display: inline-block
173 | width: 100%
174 | position: relative
175 | text-align: center
176 | vertical-align: middle
177 |
178 | .mobile__link
179 | display: block
180 | width: 100%
181 | line-height: rem($mobile-link-height)
182 | font-size: rem($mobile-link-font-size)
183 | letter-spacing: 1px
184 | cursor: pointer
185 | color: $mobile-link-color
186 | // background: $mobile-link-bg
187 | border-bottom: 1px solid $mobile-link-border
188 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_offcanvas.sass:
--------------------------------------------------------------------------------
1 | $offcanvas-position: absolute
2 | $offcanvas-background: $tertiary-color
3 | $offcanvas-width: 250px
4 |
5 | .topbar
6 | transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
7 |
8 | .offcanvas
9 | position: relative
10 | min-height: 100%
11 |
12 | .offcanvas__content
13 | z-index: z-index(offcanvas)
14 | position: $offcanvas-position
15 | background: $offcanvas-background
16 | width: calc(100% - 60px)
17 | height: 100%
18 | overflow: auto
19 |
20 | @media #{$medium-up}
21 | width: rem($offcanvas-width)
22 |
23 | .offcanvas__wrapper
24 | background: $global-background
25 | position: relative
26 | z-index: z-index(content)
27 | transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
28 | box-shadow: -2px 0 15px rgba(0, 0, 0, 0.1)
29 |
30 | .offcanvas--right,
31 | .offcanvas--left
32 |
33 | .offcanvas
34 | overflow: hidden
35 |
36 | .offcanvas--right
37 |
38 | .offcanvas__wrapper,
39 | .topbar
40 | transform: translate3d(calc(100% - 60px), 0, 0)
41 |
42 | @media #{$medium-up}
43 | transform: translate3d(rem($offcanvas-width), 0, 0)
44 |
45 | .offcanvas--left
46 |
47 | .offcanvas
48 | overflow: hidden
49 |
50 | .topbar,
51 | .offcanvas__wrapper
52 | transform: translate3d(calc(-100% + 60px), 0, 0)
53 |
54 | @media #{$medium-up}
55 | transform: translate3d(rem(-$offcanvas-width), 0, 0)
56 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_panels.sass:
--------------------------------------------------------------------------------
1 | $panel-position: fixed
2 | $panel-background: $global-background
3 | $panel-size: 30%
4 | $panel-header-height: $global-topbar-height
5 |
6 | @mixin panel($name: panel, $side: right, $size: $panel-size, $position: fixed)
7 | .#{$name}
8 | @extend %panel
9 |
10 | position: $panel-position
11 |
12 | @if $side == right
13 | top: 0
14 | right: 0
15 | transform: translate3d(100%, 0, 0)
16 | box-shadow: -2px 0 10px rgba(0,0,0,0.1)
17 | width: calc(100% - 60px)
18 | min-height: 100%
19 | height: 100%
20 |
21 | @media #{$medium-up}
22 | width: $panel-size
23 |
24 | @if $side == left
25 | top: 0
26 | left: 0
27 | transform: translate3d(-100%, 0, 0)
28 | box-shadow: 2px 0 10px rgba(0,0,0,0.1)
29 | width: calc(100% - 60px)
30 | min-height: 100%
31 | height: 100%
32 |
33 | @media #{$medium-up}
34 | width: $panel-size
35 |
36 | @if $side == top
37 | top: 0
38 | left: 0
39 | right: 0
40 | transform: translate3d(0, -100%, 0)
41 | box-shadow: 0 2px 10px rgba(0,0,0,0.1)
42 | height: calc(100% - 200px)
43 |
44 | @media #{$medium-up}
45 | height: $panel-size
46 |
47 | @if $side == bottom
48 | bottom: 0
49 | left: 0
50 | right: 0
51 | transform: translate3d(0, 100%, 0)
52 | box-shadow: 0 -2px 10px rgba(0,0,0,0.1)
53 | height: calc(100% - 200px)
54 |
55 | @media #{$medium-up}
56 | height: $panel-size
57 |
58 | .#{$name}--active
59 |
60 | .#{$name}
61 | transform: translate3d(0, 0, 0)
62 |
63 | +panel(panel, right)
64 |
65 | %panel
66 | overflow: auto
67 | z-index: z-index(panel)
68 | background: $panel-background
69 | transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)
70 |
71 | .panel__header
72 | @extend .typo__h4
73 |
74 | line-height: rem($panel-header-height)
75 | display: block
76 | text-align: center
77 | margin-bottom: rem($global-v-gutter)
78 | border-bottom: $hr-border
79 |
80 |
81 | // TODO: Needs refactor
82 | .panel__close
83 | display: block
84 | cursor: pointer
85 | position: absolute
86 | transition: opacity .2s ease
87 | padding: 0
88 | background: none
89 | border: none
90 | z-index: 2
91 | transform: translate3d(0, 0, 0)
92 | top: rem($global-v-gutter)
93 | left: rem($global-gutter / 2)
94 | line-height: 1
95 |
96 | &:before
97 | content: "\d7"
98 | font-size: rem(20px)
99 | color: $secondary-color
100 | display: block
101 | z-index: 2
102 | transform: scale(1.6)
103 | transition: transform 0.3s cubic-bezier(0.51, -0.15, 0.48, 1.24), color 0.2s ease-in-out
104 |
105 | &:after
106 | content: ""
107 | z-index: -1
108 | position: absolute
109 | border-radius: 100%
110 | transform: scale(0)
111 | display: block
112 | background: $secondary-color
113 | transition: transform .2s cubic-bezier(0.54, -0.46, 0.36, 1.79)
114 | top: rem(-8px)
115 | left: rem(-9px)
116 | height: rem(32px)
117 | width: rem(32px)
118 |
119 | &:hover, &:focus
120 |
121 | &:before
122 | color: $global-background
123 | transform: scale(1)
124 |
125 | &:after
126 | transform: scale(1)
127 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_table.sass:
--------------------------------------------------------------------------------
1 | @import ../base/global
2 |
3 | // config
4 | $table-border: darken($tertiary-color, 5%)
5 | $table-font-size: 16px
6 | $table-padding: 14px 16px
7 | $table-bg: $global-support-background
8 | $table-even-bg: $global-background
9 |
10 | =table-row-variant($name, $color, $hover-modifier)
11 | .table__tr--#{$name}
12 | border-left: rem(4px) solid $color
13 |
14 | &:hover
15 | background: lighten($color, $hover-modifier)
16 |
17 | .table
18 | font:
19 | family: $global-font
20 | size: rem($table-font-size)
21 | weight: $global-font-weight
22 | margin-bottom: rem(40px)
23 | line-height: 1.4
24 |
25 | .table__tr
26 | border-bottom: 1px solid $table-border
27 | box-sizing: border-box
28 | border-left: rem(4px) solid transparent
29 |
30 | &:nth-child(even)
31 | background: #fafafa
32 |
33 | &:hover
34 | background: #f4f4f4
35 |
36 | +table-row-variant(primary, $primary-color, 48%)
37 |
38 | .table__td,
39 | .table__th
40 | padding: rem($table-padding)
41 |
42 | .table__th
43 | border-bottom: 1px solid #ccc
44 |
45 | .table__container
46 | overflow-x: auto
47 |
48 | .table--full-size
49 | width: 100%
50 |
51 | .table--fixed
52 | table-layout: fixed
53 |
--------------------------------------------------------------------------------
/template/docs/assets/components/_tabs.sass:
--------------------------------------------------------------------------------
1 | @import ../base/global
2 |
3 | // config
4 | $tabs-bg: $global-background
5 | $tabs-bg-active: $global-background
6 | $tabs-font-size: 16px
7 | $tabs-height: 40px
8 | $tabs-link-weight: $global-font-weight
9 | $tabs-border: $tertiary-color
10 | $tabs-padding: 0 20px
11 | $tabs-width: 3px
12 |
13 | %tabs
14 | display: flex
15 | align-items: stretch
16 | min-height: rem($tabs-height)
17 |
18 | %tabs__link
19 | display: block
20 | padding: rem($tabs-padding)
21 | font:
22 | family: $global-font
23 | size: rem($tabs-font-size)
24 | weight: $tabs-link-weight
25 | text-decoration: none
26 | cursor: pointer
27 | line-height: rem($tabs-height)
28 | color: $secondary-lighten-color
29 | transition: color .2s ease
30 |
31 | %tabs__link--active
32 | font-weight: $global-font-weight-bold
33 | color: $secondary-color
34 |
35 | =tabs($name: tabs, $style: row, $inverted-content-side: false, $line-side: bottom)
36 | @if $style == column
37 | @if $inverted-content-side
38 | $line-side: left
39 | @else
40 | $line-side: right
41 | @else
42 | @if $inverted-content-side
43 | $line-side: top
44 | @else
45 | $line-side: bottom
46 |
47 | .#{$name}
48 | @extend %tabs
49 |
50 | flex-direction: $style
51 | border-#{$line-side}: $tabs-width solid $bright-grey-color
52 | margin-#{$line-side}: -$tabs-width
53 |
54 | .#{$name}__link
55 | @extend %tabs__link
56 |
57 | border-#{$line-side}: $tabs-width solid $bright-grey-color
58 | margin-#{$line-side}: -$tabs-width
59 |
60 | &:hover,
61 | &:focus
62 | color: $global-font-color
63 |
64 | .#{$name}__link--active
65 | @extend %tabs__link--active
66 |
67 | border-color: $primary-color
68 |
69 | +tabs(tabs, row)
70 |
71 | +tabs(vertical-tabs, column, false)
72 |
--------------------------------------------------------------------------------
/template/docs/assets/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/template/docs/assets/layout/_topbar.sass:
--------------------------------------------------------------------------------
1 | $topbar-bg: $global-support-background
2 | $topbar-bg-hover: $global-background
3 | $topbar-color: $secondary-color
4 | $topbar-border: $tertiary-color
5 | $topbar-link-underline: $primary-color
6 |
7 | $topbar-font-weight: $global-font-weight
8 | $topbar-font: $global-font
9 | $topbar-font-size: 14px
10 | $topbar-height: $global-topbar-height
11 | $topbar-dropdown-font-size: 14px
12 |
13 | .topbar--sticky
14 |
15 | .offcanvas__wrapper,
16 | .content
17 | padding-top: rem($topbar-height)
18 |
19 | .topbar
20 | position: fixed
21 | top: 0
22 | left: 0
23 | right: 0
24 | z-index: z-index(topbar)
25 |
26 |
27 | .topbar
28 | background: $topbar-bg
29 | width: 100%
30 | display: block
31 | box-sizing: content-box
32 | height: rem($topbar-height)
33 | color: $topbar-color
34 | line-height: rem($topbar-height)
35 | font-family: $topbar-font
36 | padding: 0
37 | border-bottom: 1px solid $topbar-border
38 | box-shadow: 0 1px 3px rgba(#000, 0.1)
39 |
40 | .topbar__logo,
41 | .topbar__link
42 | position: relative
43 |
44 |
45 | .topbar__logo
46 | font-weight: 700
47 | font-size: rem(16px)
48 | height: rem($topbar-height)
49 | vertical-align: middle
50 | text-decoration: none
51 | color: $topbar-color
52 |
53 | &:visited
54 | color: $topbar-color
55 |
56 | small
57 | font-weight: $global-font-weight
58 | margin-left: 5px
59 |
60 | img, svg
61 | max-height: rem($topbar-height - 15px)
62 | padding: 0 5px 5px 0
63 | display: inline-block
64 | vertical-align: middle
65 |
66 | .topbar__nav
67 | list-style: none
68 | float: left
69 | font-size: rem($topbar-font-size)
70 | font-weight: $topbar-font-weight
71 | margin: 0
72 | padding: 0
73 | height: rem($topbar-height)
74 | font-size: rem(0)
75 |
76 | .topbar__option
77 | display: inline-block
78 | font-size: rem($topbar-font-size)
79 | height: 100%
80 | vertical-align: top
81 | text-transform: uppercase
82 |
83 |
84 | .topbar__option--has-dropdown
85 |
86 | .topbar__link:before
87 | content: ""
88 | width: 0
89 | height: 0
90 | border-style: solid
91 | border-width: rem(5px 5px 0 5px)
92 | border-color: $topbar-color transparent transparent transparent
93 | display: inline-block
94 | margin-right: rem($grid-gutter-width / 5)
95 | padding-bottom: rem(2px)
96 |
97 |
98 | .topbar__separator
99 | display: inline-block
100 | border-left: 1px solid $topbar-border
101 | height: 100%
102 | vertical-align: top
103 |
104 | .topbar__link
105 | display: block
106 | font-size: rem($topbar-font-size)
107 | padding: 0 rem($topbar-font-size * 1.5)
108 | color: $topbar-color
109 | text-decoration: none
110 | transition: background .1s ease
111 |
112 | &:hover,
113 | &:visited
114 | color: $topbar-color
115 |
116 | &:hover, &:focus
117 | outline: none
118 | background: $topbar-bg-hover
119 |
120 | .topbar__right
121 | float: right
122 |
123 | .topbar__left
124 | float: left
125 |
126 |
127 | // dropdown extension
128 | .topbar__option
129 | .dropdown
130 | height: 100%
131 | width: auto
132 | background: none
133 |
134 | .topbar__link:after,
135 | .user:after
136 | content: ""
137 | position: absolute
138 | bottom: rem(-1px)
139 | left: 0
140 | width: 0
141 | height: rem(2px)
142 | background: $primary-color
143 | transition: width .15s ease
144 |
145 | &:hover
146 | .topbar__link:after,
147 | .user:after
148 | width: 100%
149 |
150 |
151 | .dropdown__current
152 | height: 100%
153 |
154 | .dropdown__list
155 | position: absolute
156 | margin-left: rem(-1px)
157 | margin-top: rem(1px)
158 | min-width: 100%
159 | white-space: nowrap
160 |
161 | .dropdown__option
162 | line-height: rem($topbar-height / 2)
163 | border-bottom: 1px solid $tertiary-color
164 | font-size: rem($topbar-dropdown-font-size)
165 | padding-left: rem($topbar-font-size * 1.5)
166 | padding-right: rem($topbar-font-size * 1.5)
167 |
--------------------------------------------------------------------------------
/template/docs/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/monterail/vue-component-template/10a6c1bf1996c7248d997425a98c656f689940ec/template/docs/assets/logo.png
--------------------------------------------------------------------------------
/template/docs/assets/main.sass:
--------------------------------------------------------------------------------
1 | // BASE
2 | @import base/mixins
3 | @import base/z-stack
4 | @import base/normalize
5 | @import base/animations
6 | @import base/global
7 | @import base/functions
8 | @import base/media
9 | @import base/typo
10 |
11 | // COMPONENTS
12 |
13 | @import components/grid
14 | @import components/table
15 | @import components/buttons
16 | @import components/inputs
17 | @import components/lists
18 |
19 | // TODO: OVERRIDING UTILS (which has to be loaded last to reduce the use of !important)
20 | @import utils/visibility
21 | @import utils/utils
22 |
--------------------------------------------------------------------------------
/template/docs/assets/multiselect.sass:
--------------------------------------------------------------------------------
1 | .multiselect__spinner
2 | position: absolute
3 | right: 1px
4 | top: 1px
5 | width: 3rem
6 | height: 2.1875rem
7 | background: #fff
8 | display: block
9 |
10 | &:before,
11 | &:after
12 | position: absolute
13 | content: ''
14 | top: 50%
15 | left: 50%
16 | margin: 0.875rem 0 0 0.875rem
17 | width: 1rem
18 | height: 1rem
19 | border-radius: 100%
20 | border-color: #41B883 transparent transparent
21 | border-style: solid
22 | border-width: 2px
23 | box-shadow: 0 0 0 1px transparent
24 |
25 | &:before
26 | animation: spinning 2.4s cubic-bezier(0.41, 0.26, 0.2, 0.62)
27 | animation-iteration-count: infinite
28 |
29 | &:after
30 | animation: spinning 2.4s cubic-bezier(0.51, 0.09, 0.21, 0.8)
31 | animation-iteration-count: infinite
32 |
33 | .multiselect__loading-transition
34 | transition: opacity 0.4s ease-in-out
35 | opacity: 1
36 |
37 | .multiselect__loading-enter,
38 | .multiselect__loading-leave
39 | opacity: 0
40 |
41 | .multiselect,
42 | .multiselect__input,
43 | .multiselect__single
44 | font:
45 | family: inherit
46 | size: 0.875rem
47 | weight: lighter
48 |
49 | .multiselect
50 | box-sizing: content-box
51 |
52 | *
53 | box-sizing: border-box
54 |
55 | display: block
56 | position: relative
57 | width: 100%
58 | min-height: 2.5rem
59 | text-align: left
60 | color: #35495E
61 |
62 | &:focus
63 | outline: none
64 |
65 | &--active
66 | z-index: 50
67 |
68 | .multiselect__current,
69 | .multiselect__input,
70 | .multiselect__tags
71 | border-bottom-left-radius: 0
72 | border-bottom-right-radius: 0
73 |
74 | .multiselect__select
75 | transform: rotateZ(180deg)
76 |
77 | .multiselect__input,
78 | .multiselect__single
79 | position: relative
80 | display: inline-block
81 | min-height: 1.25rem
82 | line-height: 1.25rem
83 | border: none
84 | border-radius: 0.3125rem
85 | background: #fff
86 | padding: 1px 0 0 0.3125rem
87 | width: auto
88 | transition: border .1s ease
89 | box-sizing: border-box
90 | margin-bottom: 0.5rem
91 |
92 | &:hover
93 | border-color: darken(#E8E8E8, 10%)
94 |
95 | &:focus
96 | border-color: darken(#E8E8E8, 25%)
97 | outline: none
98 |
99 | .multiselect__single
100 | padding-left: 0.375rem
101 | margin-bottom: 0.5rem
102 |
103 | .multiselect__tags
104 | min-height: 2.5rem
105 | display: block
106 | padding: 0.5rem 2.5rem 0 0.5rem
107 | border-radius: 0.3125rem
108 | border: 1px solid #E8E8E8
109 | background: #fff
110 |
111 | .multiselect__tag
112 | position: relative
113 | display: inline-block
114 | padding: 0.25rem 1.625rem 0.25rem 0.625rem
115 | border-radius: 0.3125rem
116 | margin-right: 0.625rem
117 | color: #fff
118 | line-height: 1
119 | background: #41B883
120 | margin-bottom: 0.5rem
121 |
122 | .multiselect__tag-icon
123 | cursor: pointer
124 | margin-left: 7px
125 | position: absolute
126 | right: 0
127 | top: 0
128 | bottom: 0
129 | font:
130 | weight: 700
131 | style: initial
132 | width: 1.375rem
133 | text-align: center
134 | line-height: 1.375rem
135 | transition: all 0.2s ease
136 | border-radius: 0.3125rem
137 |
138 | &:after
139 | content: "\00D7"
140 | color: darken(#41B883, 20%)
141 | font-size: 0.875rem
142 |
143 | &:focus, &:hover
144 | background: darken(#41B883, 8%)
145 |
146 | &:after
147 | color: white
148 |
149 | .multiselect__current
150 | line-height: 1rem
151 | min-height: 2.5rem
152 | box-sizing: border-box
153 | display: block
154 | overflow: hidden
155 | padding: 0.5rem 0.75rem 0
156 | padding-right: 1.875rem
157 | white-space: nowrap
158 | margin: 0
159 | text-decoration: none
160 | border-radius: 0.3125rem
161 | border: 1px solid #E8E8E8
162 | cursor: pointer
163 |
164 | .multiselect__select
165 | line-height: 1rem
166 | display: block
167 | position: absolute
168 | box-sizing: border-box
169 | width: 2.5rem
170 | height: 2.375rem
171 | right: 1px
172 | top: 1px
173 | padding: 0.25rem 0.5rem
174 | margin: 0
175 | text-decoration: none
176 | text-align: center
177 | cursor: pointer
178 | transition: transform 0.2s ease
179 |
180 | &:before
181 | position: relative
182 | right: 0
183 | top: 65%
184 | color: #999
185 | margin-top: 0.25rem
186 | border-style: solid
187 | border-width: 0.3125rem 0.3125rem 0 0.3125rem
188 | border-color: #999999 transparent transparent transparent
189 | content: ""
190 |
191 | .multiselect__placeholder
192 | color: #ADADAD
193 | display: inline-block
194 | margin-bottom: 0.625rem
195 | padding-top: 0.125rem
196 |
197 | .multiselect--active &
198 | display: none
199 |
200 | .multiselect__content
201 | position: absolute
202 | list-style: none
203 | display: block
204 | background: #fff
205 | width: 100%
206 | max-height: 15rem
207 | overflow: auto
208 | padding: 0
209 | margin: 0
210 | border: 1px solid #E8E8E8
211 | border-top: none
212 | border-bottom-left-radius: 0.3125rem
213 | border-bottom-right-radius: 0.3125rem
214 | z-index: 50
215 |
216 | &::webkit-scrollbar
217 | display: none
218 |
219 | .multiselect__option
220 | display: block
221 | padding: 0.75rem
222 | min-height: 2.5rem
223 | line-height: 1rem
224 | font-weight: 300
225 | text-decoration: none
226 | text-transform: none
227 | vertical-align: middle
228 | position: relative
229 | cursor: pointer
230 |
231 | &:after
232 | top: 0
233 | right: 0
234 | position: absolute
235 | line-height: 2.5rem
236 | padding-right: 0.75rem
237 | padding-left: 1.25rem
238 |
239 | &--highlight
240 | background: #41B883
241 | outline: none
242 | color: white
243 |
244 | &:after
245 | content: attr(data-select)
246 | color: white
247 |
248 | &--selected
249 | background: #F3F3F3
250 | color: #35495E
251 | font-weight: bold
252 |
253 | &:after
254 | content: attr(data-selected)
255 | font-weight: 300
256 | color: darken(#F3F3F3, 20%)
257 |
258 | .multiselect__option--selected.multiselect__option--highlight
259 | background: #FF6A6A
260 | color: #fff
261 | font-weight: lighter
262 |
263 | &:after
264 | content: attr(data-deselect)
265 | color: #fff
266 |
267 | .multiselect--disabled
268 | background: darken(#fff, 7%)
269 | pointer-events: none
270 |
271 | .multiselect__current,
272 | .multiselect__select
273 | background: darken(#fff, 7%)
274 | color: darken(#fff, 35%)
275 |
276 | .multiselect__option--disabled
277 | background: darken(#fff, 7%)
278 | color: darken(#fff, 35%)
279 | cursor: text
280 | pointer-events: none
281 |
282 | &:visited
283 | color: darken(#fff, 35%)
284 |
285 | &:hover,
286 | &:focus
287 | background: darken(#41B883, 3%)
288 |
289 | .multiselect-transition
290 | transition: all .3s ease
291 |
292 | .multiselect-enter, .multiselect-leave
293 | opacity: 0
294 | max-height: 0 !important
295 |
--------------------------------------------------------------------------------
/template/docs/assets/prism.scss:
--------------------------------------------------------------------------------
1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+coffeescript+css-extras+git+jade+sass+scss&plugins=show-language+remove-initial-line-feed */
2 | /**
3 | * prism.js default theme for JavaScript, CSS and HTML
4 | * Based on dabblet (http://dabblet.com)
5 | * @author Lea Verou
6 | */
7 |
8 | code[class*="language-"],
9 | pre[class*="language-"] {
10 | color: black;
11 | text-shadow: 0 1px white;
12 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
13 | direction: ltr;
14 | text-align: left;
15 | white-space: pre;
16 | word-spacing: normal;
17 | word-break: normal;
18 | word-wrap: normal;
19 | line-height: 1.5;
20 |
21 | -moz-tab-size: 4;
22 | -o-tab-size: 4;
23 | tab-size: 4;
24 |
25 | -webkit-hyphens: none;
26 | -moz-hyphens: none;
27 | -ms-hyphens: none;
28 | hyphens: none;
29 | }
30 |
31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
33 | text-shadow: none;
34 | background: #b3d4fc;
35 | }
36 |
37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
38 | code[class*="language-"]::selection, code[class*="language-"] ::selection {
39 | text-shadow: none;
40 | background: #b3d4fc;
41 | }
42 |
43 | @media print {
44 | code[class*="language-"],
45 | pre[class*="language-"] {
46 | text-shadow: none;
47 | }
48 | }
49 |
50 | /* Code blocks */
51 | pre[class*="language-"] {
52 | padding: 1.3em 1em;
53 | margin: 0 0 20px 0;
54 | overflow: auto;
55 | }
56 |
57 | :not(pre) > code[class*="language-"],
58 | pre[class*="language-"] {
59 | background: #F3F5F6;
60 | }
61 |
62 | /* Inline code */
63 | :not(pre) > code[class*="language-"] {
64 | padding: .1em;
65 | border-radius: .3em;
66 | white-space: normal;
67 | }
68 |
69 | .token.comment,
70 | .token.prolog,
71 | .token.doctype,
72 | .token.cdata {
73 | color: slategray;
74 | }
75 |
76 | .token.punctuation {
77 | color: #999;
78 | }
79 |
80 | .namespace {
81 | opacity: .7;
82 | }
83 |
84 | .token.property,
85 | .token.tag,
86 | .token.boolean,
87 | .token.number,
88 | .token.constant,
89 | .token.symbol,
90 | .token.deleted {
91 | color: #905;
92 | }
93 |
94 | .token.selector,
95 | .token.attr-name,
96 | .token.string,
97 | .token.char,
98 | .token.builtin,
99 | .token.inserted {
100 | color: #690;
101 | }
102 |
103 | .token.operator,
104 | .token.entity,
105 | .token.url,
106 | .language-css .token.string,
107 | .style .token.string {
108 | color: #a67f59;
109 | background: hsla(0, 0%, 100%, .5);
110 | }
111 |
112 | .token.atrule,
113 | .token.attr-value,
114 | .token.keyword {
115 | color: #07a;
116 | }
117 |
118 | .token.function {
119 | color: #DD4A68;
120 | }
121 |
122 | .token.regex,
123 | .token.important,
124 | .token.variable {
125 | color: #e90;
126 | }
127 |
128 | .token.important,
129 | .token.bold {
130 | font-weight: bold;
131 | }
132 | .token.italic {
133 | font-style: italic;
134 | }
135 |
136 | .token.entity {
137 | cursor: help;
138 | }
139 |
140 | div.prism-show-language {
141 | position: relative;
142 | }
143 |
144 | div.prism-show-language > div.prism-show-language-label[data-language] {
145 | color: black;
146 | background-color: #CFCFCF;
147 | opacity: 0.5;
148 | display: inline-block;
149 | position: absolute;
150 | bottom: auto;
151 | left: auto;
152 | top: 0;
153 | right: 0;
154 | width: auto;
155 | height: auto;
156 | font-size: 0.9em;
157 | border-radius: 0 0 0 5px;
158 | padding: 0.1em 0.5em;
159 | text-shadow: none;
160 | z-index: 1;
161 | -webkit-box-shadow: none;
162 | -moz-box-shadow: none;
163 | box-shadow: none;
164 | -webkit-transform: none;
165 | -moz-transform: none;
166 | -ms-transform: none;
167 | -o-transform: none;
168 | transform: none;
169 | }
170 |
--------------------------------------------------------------------------------
/template/docs/assets/utils/_utils.sass:
--------------------------------------------------------------------------------
1 | .utils--center
2 | text-align: center
3 |
4 | .utils--right
5 | text-align: right
6 |
--------------------------------------------------------------------------------
/template/docs/assets/utils/_visibility.sass:
--------------------------------------------------------------------------------
1 | @media #{$small-only}
2 | .small--hidden
3 | display: none !important
4 |
5 | @media #{$medium-only}
6 | .medium--hidden
7 | display: none !important
8 |
9 | @media #{$medium-up}
10 | .medium-up--hidden
11 | display: none !important
12 |
13 | @media #{$large-only}
14 | .large--hidden
15 | display: none !important
16 |
17 | @media #{$large-up}
18 | .large-up--hidden
19 | display: none !important
20 |
21 | @media #{$xlarge-only}
22 | .xlarge--hidden
23 | display: none !important
24 |
--------------------------------------------------------------------------------
/template/docs/docs.scss:
--------------------------------------------------------------------------------
1 | @import './assets/main';
2 | @import './assets/prism';
3 |
4 | .invalid {
5 | .typo__label {
6 | color: $error-color;
7 | }
8 | .multiselect__tags {
9 | border-color: $error-color !important;
10 | }
11 | }
12 |
13 | body {
14 | background: #fff;
15 | color: #35495E;
16 | font-family: 'Lato', Helvetica, sans-serif;
17 | text-decoration: none;
18 | }
19 |
20 | .start {
21 | text-align: center;
22 | display: block;
23 | background: linear-gradient(to left bottom, #8cc1f7 0%, #9cffd3 100%);
24 |
25 | .typo__h1 {
26 | padding-top: rem(40px);
27 | position: relative;
28 | }
29 |
30 | .typo__h3 {
31 | padding: rem(20px 0)
32 | }
33 |
34 | @media #{$medium-up} {
35 | min-height: 100vh;
36 | }
37 |
38 | .button {
39 | margin-bottom: rem(24px);
40 | }
41 | }
42 |
43 | .start__list {
44 | padding-top: rem(30px)
45 | }
46 |
47 | .docs {
48 | text-align: left;
49 | padding-top: rem(60px)
50 | }
51 |
52 | .center-vertically {
53 | position: relative;
54 |
55 | @media #{$medium-up} {
56 | position: absolute;
57 | height: 600px;
58 | left: 0;
59 | right: 0;
60 | top: 50%;
61 | transform: translateY(-50%);
62 | }
63 | }
64 |
65 | .multiselect-example__container {
66 | margin: 0 auto 60px;
67 | }
68 |
69 | .button {
70 | margin: rem(0 10px)
71 | }
72 |
73 | .logo {
74 | height: rem(70px);
75 | margin-right: rem(20px);
76 | vertical-align: middle;
77 | display: inline-block;
78 | }
79 |
80 | .monterail-logo {
81 | width: 100px;
82 | height: 100px;
83 | margin-bottom: rem(30px)
84 | }
85 |
86 | .monterail-link {
87 | color: #D20C03
88 | }
89 |
90 | .button--github {
91 | padding-left: rem(60px);
92 |
93 | &:before {
94 | content: url('./assets/github.svg');
95 | left: rem(25px);
96 | position: absolute;
97 | }
98 | }
99 |
100 | .version {
101 | position: absolute;
102 | bottom: rem(-7px);
103 | font-size: rem(20px);
104 | color: $secondary-color;
105 | transform: translateX(-100%);
106 | }
107 |
--------------------------------------------------------------------------------
/template/docs/index.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html(lang="en")
3 | head
4 | meta(charset='utf-8')
5 | meta(name='viewport', content='width=device-width,initial-scale=1,maximum-scale=1')
6 | title {{ name }} | A Vue.js library
7 | link(rel='icon', href='static/vue-logo.png', type='image/x-icon')
8 | meta(name='description', content='{{ description }}')
9 | meta(property='og:title', content='{{ name }} | A Vue.js library.')
10 | meta(property='og:site_name', content='{{ name }} | A Vue.js library.')
11 | meta(property='og:url', content='http://monterail.github.io/vue-multiselect')
12 | meta(property='og:description', content='{{ description }}')
13 | meta(property='og:image', content='http://monterail.github.io/vue-multiselect/static/vue-logo.png')
14 | meta(property='twitter:image', content='http://monterail.github.io/vue-multiselect/static/vue-logo.png')
15 | meta(property='twitter:title', content='{{ name }} | A Vue.js library.')
16 | meta(property='twitter:description', content='{{ description }}')
17 | body
18 | #app
19 | include ./partials/_start
20 |
21 | .grid__row.docs
22 | .grid__columns.grid__unit--sm-3.small--hidden
23 | include ./partials/_nav
24 | .grid__columns.grid__unit--sm-12.grid__unit--md-9
25 | include ./partials/_getting-started
26 |
27 | hr.typo__hr
28 | h1.typo__h1 Examples
29 |
30 | hr.typo__hr
31 | include ./partials/examples/_section
32 |
33 | include ./partials/api/_props
34 | include ./partials/api/_events
35 | include ./partials/api/_slots
36 |
37 | include ./partials/_footer
38 |
39 | script(src='static/prism.js')
40 |
--------------------------------------------------------------------------------
/template/docs/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | require('./docs.scss')
4 |
5 | function throttle (callback, limit) {
6 | var wait = false
7 | return function () {
8 | if (!wait) {
9 | callback.call()
10 | wait = true
11 | setTimeout(function () {
12 | wait = false
13 | }, limit)
14 | }
15 | }
16 | }
17 |
18 | const SL = ', 100%, 85%'
19 |
20 | /* eslint-disable no-new */
21 | new Vue({
22 | el: '#app',
23 | data () {
24 | return {
25 | isNavSticky: false,
26 | firstColor: Math.floor(Math.random() * 255),
27 | secondColor: Math.floor(Math.random() * 255)
28 | }
29 | },
30 | computed: {
31 | gradient () {
32 | return {
33 | background: `linear-gradient(to left bottom, hsl(${this.firstColor + SL}) 0%, hsl(${this.secondColor + SL}) 100%)`
34 | }
35 | }
36 | },
37 | methods: {
38 | adjustNav () {
39 | this.isNavSticky = window.scrollY > window.innerHeight
40 | }
41 | },
42 | mounted () {
43 | this.adjustNav()
44 | window.addEventListener('scroll', throttle(this.adjustNav, 50))
45 | }
46 | })
47 |
--------------------------------------------------------------------------------
/template/docs/partials/_footer.pug:
--------------------------------------------------------------------------------
1 | section.utils--center
2 | h4.typo__h4
3 | | Created by {{ author }}
4 | strong
5 | a.typo__link(href='https://twitter.com/', target='_BLANK')
6 | | {{ author }} twitter handle
7 | h4.typo__h4
8 | | With love from
9 | strong
10 | a.typo__link.monterail-link(href='http://monterail.com', target='_BLANK') Monterail
11 | a(href='http://monterail.com', target='_BLANK')
12 | img.monterail-logo(src='static/monterail-logo.png')
13 |
--------------------------------------------------------------------------------
/template/docs/partials/_getting-started.pug:
--------------------------------------------------------------------------------
1 | .grid__row
2 | .grid__column
3 | section.docs#getting-started
4 | h1.typo__h1 Getting started
5 | hr.typo__hr
6 |
7 | .grid__row
8 | .grid__column
9 | h2.typo__h2 Installation
10 | pre.language-bash
11 | code.
12 | npm install {{ name }} --save
13 |
14 | .grid__column
15 | h2.typo__h2 Basic usage
16 | pre.language-jade
17 | code.
18 | multiselect(
19 | v-model="selected",
20 | :options="options"
21 | )
22 | pre.language-javascript
23 | code.
24 | import {{ name }} from '{{ name }}'
25 | export default {
26 | components: { {{ name }} }
27 | }
28 |
29 | .grid__row
30 | .grid__column
31 | h2.typo__h2 Package content
32 |
33 | .grid__column.grid__unit--md-5
34 | p.typo__p
35 | | {{ description }}
36 |
--------------------------------------------------------------------------------
/template/docs/partials/_nav.pug:
--------------------------------------------------------------------------------
1 | mixin nav-element(componentName, href)
2 | li.list__element
3 | a.link.list__link(href="##{href}")= componentName
4 |
5 | ul.list(
6 | :class="{ 'list--sticky': isNavSticky }"
7 | )
8 | li.list__heading Setup
9 | +nav-element('Getting Started', 'getting-started')
10 |
11 | li.list__heading Examples
12 | +nav-element('Section', 'section')
13 |
14 | li.list__heading API
15 | +nav-element('Props', 'props')
16 | +nav-element('Events', 'events')
17 | +nav-element('Slots', 'slots')
18 |
--------------------------------------------------------------------------------
/template/docs/partials/_start.pug:
--------------------------------------------------------------------------------
1 | section.start(
2 | :style="gradient"
3 | )
4 | .center-vertically
5 | h1.typo__h1
6 | img.logo(src="./static/vue-logo.png")
7 | | {{ name }}
8 | small.version (version here)
9 | h3.typo__h3 {{ Description }}
10 | = ' for '
11 | a.typo__link(href="http://vuejs.org" target="_BLANK") Vue.js
12 |
13 | .grid__row.grid__row--centered
14 | .grid__column.grid__unit--md-6
15 | .multiselect-example__container
16 | .grid__row.start__list
17 | .grid__column.grid__unit--md-6.list
18 | ul.list__ul
19 | li.typo__li Perks here
20 | li.typo__li And here
21 | li.typo__li: a.typo__link(href="#search") And here with a link
22 | .grid__column.grid__unit--md-6.list
23 | ul.list__ul
24 | li.typo__li Perks here
25 | li.typo__li And here
26 | li.typo__li: a.typo__link(href="#search") And here with a link
27 |
28 | .grid__row.grid__row--centered
29 | .grid__column.utils--center
30 | a.button.button--large.button--secondary.button--github(href="https://github.com/monterail" target="_BLANK") View on GitHub
31 | a.button.button--large(href="#getting-started") Getting started & examples
32 |
--------------------------------------------------------------------------------
/template/docs/partials/api/_events.pug:
--------------------------------------------------------------------------------
1 | h2.typo__h2#events Events
2 | .grid__row
3 | .table__container
4 | table.table.table--full-size
5 | thead
6 | tr.table__tr
7 | th.table__th(width="150") Name
8 | th.table__th(width="100") Attributes
9 | th.table__th(width="150") Listen to
10 | th.table__th(width="250") Description
11 | tbody
12 | tr.table__tr
13 | td.table__td: strong Input
14 | td.table__td: kbd (value, id)
15 | td.table__td: kbd @input
16 | td.table__td
17 | | Emitted after
18 | = " "
19 | kbd this.value
20 | | changes
21 |
--------------------------------------------------------------------------------
/template/docs/partials/api/_props.pug:
--------------------------------------------------------------------------------
1 | h2.typo__h2#props Props
2 | .grid__row
3 | .table__container
4 | table.table.table--full-size.table--fixed
5 | thead
6 | tr.table__tr
7 | th.table__th(width="100") Name
8 | th.table__th(width="80") Type
9 | th.table__th(width="180") Default
10 | th.table__th(width="200") Description
11 | tbody
12 | tr.table__tr
13 | td.table__td: strong Id
14 | td.table__td Integer||String
15 | td.table__td
16 | td.table__td.
17 | Used to identify the component in events.
18 |
--------------------------------------------------------------------------------
/template/docs/partials/api/_slots.pug:
--------------------------------------------------------------------------------
1 | h2.typo__h2#slots Slots
2 | .grid__row
3 | .table__container
4 | table.table.table--full-size.table--fixed
5 | thead
6 | tr.table__tr
7 | th.table__th(width="200") Name
8 | th.table__th Description
9 | tbody
10 | tr.table__tr
11 | td.table__td: strong MaxElements
12 | td.table__td
13 | | Shows when the maximum options have been selected.
14 |
--------------------------------------------------------------------------------
/template/docs/partials/examples/_section.pug:
--------------------------------------------------------------------------------
1 | h2.typo__h2#tagging Section
2 | p.typo__p
3 | | Section description
4 | .grid__row
5 | .grid__column.grid__unit--md-5
6 | label.typo__label Section
7 | | Code here
8 |
9 | .grid__column.grid__unit--md-7
10 | label.typo__label Code sample
11 | pre.language-jade
12 | code.
13 | multiselect(
14 | :options="taggingOptions",
15 | v-model="taggingSelected",
16 | :multiple="true",
17 | :searchable="searchable",
18 | :taggable="true",
19 | @tag="addTag",
20 | tag-placeholder="Add this as new tag"
21 | placeholder="Type to search or add tag"
22 | label="name"
23 | track-by="code"
24 | )
25 | span(slot="noResult").
26 | Oops! No elements found. Consider changing the search query.
27 |
28 | pre.language-javascript
29 | code.
30 | addTag (newTag) {
31 | const tag = {
32 | name: newTag,
33 | // Just for example needs as we use Array of Objects that should have other properties filled.
34 | // For primitive values you can simply push the tag into options and selected arrays.
35 | code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
36 | }
37 | this.taggingOptions.push(tag)
38 | this.taggingSelected.push(tag)
39 | }
40 |
--------------------------------------------------------------------------------
/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |