├── .browserslistrc ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── pull_request_template.md ├── .gitignore ├── .lintstagedrc ├── .npmignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── babel.config.js ├── dist └── vue-carousel.min.js ├── docs ├── .gitignore ├── _config.yml ├── db.json ├── package.json ├── public │ ├── api │ │ └── index.html │ ├── css │ │ ├── benchmark.css │ │ ├── index.css │ │ ├── page.css │ │ └── search.css │ ├── examples │ │ └── index.html │ ├── guide │ │ └── index.html │ ├── images │ │ ├── actualize.png │ │ ├── chaitin.png │ │ ├── check.png │ │ ├── down.png │ │ ├── feed.png │ │ ├── htmlburger.png │ │ ├── icons.png │ │ ├── itunescn.png │ │ ├── jsfiddle.png │ │ ├── juejin.png │ │ ├── laravel.png │ │ ├── logo.png │ │ ├── menu.png │ │ ├── monterail.png │ │ ├── patreon.png │ │ ├── paypal.png │ │ ├── search.png │ │ ├── someline.png │ │ ├── strikingly.png │ │ ├── tde.png │ │ ├── transition.png │ │ ├── trisoft.png │ │ └── vuejobs.png │ ├── index.html │ └── js │ │ ├── common.js │ │ ├── smooth-scroll.min.js │ │ ├── vue-carousel.min.js │ │ ├── vue.js │ │ └── vue.min.js ├── scaffolds │ ├── draft.md │ ├── page.md │ └── post.md ├── source │ ├── _posts │ │ └── home.md │ ├── api │ │ └── index.md │ ├── examples │ │ └── index.md │ └── guide │ │ └── index.md ├── themes │ └── vue │ │ ├── _config.yml │ │ ├── layout │ │ ├── index.ejs │ │ ├── layout.ejs │ │ ├── page.ejs │ │ ├── partials │ │ │ ├── header.ejs │ │ │ ├── main_menu.ejs │ │ │ ├── sidebar.ejs │ │ │ └── sponsors.ejs │ │ └── post.ejs │ │ └── source │ │ ├── css │ │ ├── _common.styl │ │ ├── _demo.styl │ │ ├── _header.styl │ │ ├── _migration.styl │ │ ├── _settings.styl │ │ ├── _sidebar.styl │ │ ├── _sponsor.styl │ │ ├── _syntax.styl │ │ ├── benchmark.styl │ │ ├── index.styl │ │ ├── page.styl │ │ └── search.styl │ │ ├── images │ │ ├── 2mhost.png │ │ ├── actualize.png │ │ ├── chaitin.png │ │ ├── check.png │ │ ├── down.png │ │ ├── feed.png │ │ ├── htmlburger.png │ │ ├── icons.png │ │ ├── itunescn.png │ │ ├── jsfiddle.png │ │ ├── juejin.png │ │ ├── laravel.png │ │ ├── logo.png │ │ ├── menu.png │ │ ├── monterail.png │ │ ├── patreon.png │ │ ├── paypal.png │ │ ├── search.png │ │ ├── someline.png │ │ ├── strikingly.png │ │ ├── tde.png │ │ ├── transition.png │ │ ├── trisoft.png │ │ └── vuejobs.png │ │ └── js │ │ ├── common.js │ │ ├── smooth-scroll.min.js │ │ ├── vue-carousel.min.js │ │ ├── vue.js │ │ └── vue.min.js └── yarn.lock ├── package.json ├── play └── index.js ├── postcss.config.js ├── src ├── Carousel.vue ├── Navigation.vue ├── Pagination.vue ├── Slide.vue ├── index.js ├── mixins │ └── autoplay.js └── utils │ └── debounce.js ├── tests ├── client.jest.json ├── client │ ├── components │ │ ├── __snapshots__ │ │ │ ├── carousel.spec.js.snap │ │ │ ├── navigation.spec.js.snap │ │ │ ├── pagination.spec.js.snap │ │ │ └── slide.spec.js.snap │ │ ├── carousel.spec.js │ │ ├── navigation.spec.js │ │ ├── pagination.spec.js │ │ └── slide.spec.js │ ├── index.spec.js │ └── utils │ │ ├── .debounce.spec.js.swp │ │ └── debounce.spec.js └── functional │ └── TODO.md ├── webpack.common.js ├── webpack.prod.js └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | last 2 versions 2 | IE 11 -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["ssense/client", "plugin:vue/base", "plugin:prettier/recommended"] 3 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help squash bugs 4 | 5 | --- 6 | 7 | ## Bug Report 8 | 9 | **Current Behavior** 10 | A clear and concise description of the behavior. 11 | 12 | **Input Code and steps to reproduce** 13 | - You can add a link to a hosted repo, or a JSfiddle, repl.it, etc here 14 | - Or, you can paste your code in a formatted block like so: 15 | 16 | ```js 17 | var your => (code) => here; 18 | ``` 19 | 20 | **Expected behavior/code** 21 | A clear and concise description of what you expected to happen (or code). 22 | 23 | **Babel Configuration (.babelrc, package.json, cli command)** 24 | 25 | ```js 26 | { 27 | "your": { "config": "here" } 28 | } 29 | ``` 30 | 31 | **Environment** 32 | - Babel version(s): [e.g. v6.0.0, v7.0.0-beta.34] 33 | - Node/npm version: [e.g. Node 8/npm 5] 34 | - OS: [e.g. OSX 10.13.4, Windows 10] 35 | 36 | **Possible Solution** 37 | 38 | 39 | **Additional context/Screenshots** 40 | Add any other context about the problem here. If applicable, add screenshots to help explain. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem?** 8 | Please describe. A clear and concise description of what the problem is. Ex. I have an issue when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. Add any considered drawbacks. 12 | 13 | **If any, describe the alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Teachability, Documentation, Adoption, Migration Strategy** 17 | If you can, explain how users will be able to use this and possibly write out a version the docs. Maybe a screenshot or design? 18 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Motivation and Context 7 | 8 | 9 | 10 | ## How Has This Been Tested? 11 | 12 | 13 | 14 | 15 | ## Screenshots (if appropriate): 16 | 17 | ## Types of changes 18 | 19 | - [ ] Bug fix (non-breaking change which fixes an issue) 20 | - [ ] New feature (non-breaking change which adds functionality) 21 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 22 | 23 | ## Checklist: 24 | 25 | 26 | - [ ] My code follows the code style of this project. 27 | - [ ] My change requires a change to the documentation. 28 | - [ ] I have updated the documentation accordingly. 29 | - [ ] I have included a vue-play example (if this is a new feature) 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | .idea/ 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (https://nodejs.org/api/addons.html) 28 | build/Release 29 | 30 | # Dependency directories 31 | node_modules/ 32 | jspm_packages/ 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional eslint cache 38 | .eslintcache 39 | 40 | # Output of 'npm pack' 41 | *.tgz 42 | 43 | # Yarn Integrity file 44 | .yarn-integrity 45 | 46 | # dotenv environment variables file 47 | .env 48 | 49 | # parcel-bundler cache (https://parceljs.org/) 50 | .cache 51 | 52 | # vuepress build output 53 | .vuepress/dist 54 | 55 | # npm package lock file 56 | ./package-lock.json 57 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "linters": { 3 | "src/**/?(*.js|*.vue)": [ 4 | "prettier-eslint --write", 5 | "git add" 6 | ] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | .gitignore 3 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | script: yarn test-coverage 4 | 5 | after_script: 6 | - yarn coveralls 7 | 8 | node_js: 9 | - "8.11.4" -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Some basic conventions for contributing to this project. 4 | 5 | ### General 6 | 7 | Please make sure that there aren't existing pull requests attempting to address the issue mentioned. Likewise, please check for issues related to update, as someone else may be working on the issue in a branch or fork. 8 | 9 | * Non-trivial changes should be discussed in an issue first 10 | * Develop in a topic branch, not master 11 | * Squash your commits 12 | 13 | ### Branching 14 | 15 | **Branch naming conventions** 16 | 17 | * Use grouping tokens (words) at the beginning of your branch names. 18 | * Define and use short lead tokens to differentiate branches in a way that is meaningful to your workflow. 19 | * Use slashes to separate parts of your branch names. 20 | * Do not use bare numbers as leading parts. 21 | * Avoid long descriptive names for long-lived branches. 22 | 23 | **Short well-defined tokens** 24 | 25 | Choose short tokens so they do not add too much noise to every one of your branch names. 26 | ``` 27 | wip Works in progress; stuff we know won't be finished soon 28 | feat Feature I'm adding or expanding 29 | bug Bug fix or experiment 30 | junk Throwaway branch created to experiment 31 | ``` 32 | 33 | ### Linting 34 | 35 | Please be watchful of linting errors before committing code. 36 | 37 | ### Commit Message Format 38 | 39 | Each commit message should include a **type**, a **scope** and a **subject**: 40 | 41 | ``` 42 | (): 43 | ``` 44 | 45 | Lines should not exceed 100 characters. This allows the message to be easier to read on github as well as in various git tools and produces a nice, neat commit log ie: 46 | 47 | ``` 48 | #271 feat(standard): add style config and refactor to match 49 | #270 fix(config): only override publicPath when served by webpack 50 | #269 feat(eslint-config-defaults): replace eslint-config-airbnb 51 | #268 feat(config): allow user to configure webpack stats output 52 | ``` 53 | 54 | #### Type 55 | 56 | Must be one of the following: 57 | 58 | * **feat**: A new feature 59 | * **fix**: A bug fix 60 | * **docs**: Documentation only changes 61 | * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing 62 | semi-colons, etc) 63 | * **refactor**: A code change that neither fixes a bug or adds a feature 64 | * **test**: Adding missing tests 65 | * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation 66 | generation 67 | 68 | #### Scope 69 | 70 | The scope could be anything specifying place of the commit change. For example `webpack`, 71 | `babel`, `redux` etc... 72 | 73 | #### Subject 74 | 75 | The subject contains succinct description of the change: 76 | 77 | * use the imperative, present tense: "change" not "changed" nor "changes" 78 | * don't capitalize first letter 79 | * no dot (.) at the end -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - SSENSE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue Carousel 2 | 3 | [![Build Status](https://travis-ci.org/SSENSE/vue-carousel.svg?branch=master)](https://travis-ci.org/SSENSE/vue-carousel) 4 | [![Coverage Status](https://coveralls.io/repos/github/SSENSE/vue-carousel/badge.svg?branch=master)](https://coveralls.io/github/SSENSE/vue-carousel?branch=master) 5 | [![Latest Stable Version](https://img.shields.io/npm/v/vue-carousel.svg)](https://www.npmjs.com/package/vue-carousel) 6 | 7 | **WARNING: vue-carousel is at pre-alpha stage of development and may undergo significant changes.** 8 | 9 | **Feel free to submit issues and feature requests [here](https://github.com/SSENSE/vue-carousel/issues)**. 10 | 11 | **[Full documentation and examples](https://ssense.github.io/vue-carousel)** 12 | 13 | ## Table of Contents 14 | - [Installation](#installation) 15 | - [Usage](#usage) 16 | - [Development](#development) 17 | - [License](#license) 18 | 19 | ## Installation 20 | 21 | ``` bash 22 | npm install vue-carousel 23 | ``` 24 | 25 | or if you prefer yarn 26 | 27 | ``` bash 28 | yarn add vue-carousel 29 | ``` 30 | 31 | ## Usage 32 | 33 | ### Global 34 | 35 | You may install Vue Carousel globally: 36 | 37 | ``` js 38 | import Vue from 'vue'; 39 | import VueCarousel from 'vue-carousel'; 40 | 41 | Vue.use(VueCarousel); 42 | ``` 43 | This will make **<carousel>** and **<slide>** available to all components within your Vue app. 44 | 45 | ### Local 46 | 47 | Include the carousel directly into your component using import: 48 | 49 | ``` js 50 | import { Carousel, Slide } from 'vue-carousel'; 51 | 52 | export default { 53 | ... 54 | components: { 55 | Carousel, 56 | Slide 57 | } 58 | ... 59 | }; 60 | ``` 61 | 62 | ### Configuration 63 | | Property | Type | Default | Description | 64 | |:----------------------------|:--------|:--------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 65 | | adjustableHeight | Boolean | false | Adjust the height of the carousel for the current slide. 66 | | adjustableHeightEasing | String | | Slide transition easing for adjustableHeight. Any valid CSS transition easing accepted. 67 | | autoplay | Boolean | false | Flag to enable autoplay. | 68 | | autoplayDirection | String | forward | Sets the autoplay direction for the carousel during autoplay. By default it is forward but can also be set to backward. If an incorrect string is supplied it will default to forward. | 69 | | autoplayHoverPause | Boolean | true | Flag to pause autoplay on hover. | 70 | | autoplayTimeout | Number | 2000 | Time elapsed before advancing slide in autoplay. | 71 | | centerMode | Boolean | false | Center images when the size is less than the container width. | 72 | | easing | String | ease | Slide transition easing. Any valid CSS transition easing accepted. | 73 | | loop | Boolean | false | Flag to make the carousel loop around when it reaches the end. | 74 | | minSwipeDistance | Number | 8 | Minimum distance for the swipe to trigger a slide advance. | 75 | | mouseDrag | Boolean | true | Flag to toggle mouse dragging. | 76 | | navigateTo | Number, Array | 0 | Listen for an external navigation request using this prop. When the supplied prop is of type Number the slide with the matching index is animated into view, however you can disable this animation by supplying an Array consisting of exactly two element: the new slide index and a boolean indication whether the change should be animated or not (eg. [3, false] would mean "go to the slide with index 3 without animation"). | 77 | | navigationClickTargetSize | Number | 8 | Amount of padding to apply around the label in pixels. | 78 | | navigationEnabled | Boolean | false | Flag to render the navigation component (next/prev buttons). | 79 | | navigationNextLabel | String | ▶ | Text content of the navigation next button. | 80 | | navigationPrevLabel | String | ◀ | Text content of the navigation prev button. | 81 | | paginationActiveColor | String | #000000 | The fill color of the active pagination dot. Any valid CSS color is accepted. | 82 | | paginationColor | String | #efefef | The fill color of pagination dots. Any valid CSS color is accepted. | 83 | | paginationPosition | String | bottom | The position of pagination dots. Possible values are `bottom`, `bottom-overlay`, `top` and `top-overlay`. The overlay values place the pagination component over the images. | 84 | | paginationEnabled | Boolean | true | Flag to render pagination component. | 85 | | paginationPadding | Number | 10 | The padding inside each pagination dot. Pixel values are accepted. | 86 | | paginationSize | Number | 10 | The size of each pagination dot. Pixel values are accepted. | 87 | | perPage | Number | 2 | Maximum number of slides displayed on each page. | 88 | | perPageCustom | Array | | Configure the number of visible slides with a particular browser width. This will be an array of arrays, ex. [[320, 2], [1199, 4]]. Formatted as [x, y] where x=browser width, and y=number of slides displayed. Ex. [1199, 4] means if (window >= 1199) then show 4 slides per page. | 89 | | resistanceCoef | Number | 20 | Resistance coefficient to dragging on the edge of the carousel. This dictates the effect of the pull as you move towards the boundaries. | 90 | | scrollPerPage | Boolean | true | Scroll per page, not per item. | 91 | | spacePadding | Number | 0 | Stage padding option adds left and right padding style (in pixels) onto VueCarousel-inner. | 92 | | spacePaddingMaxOffsetFactor | Number | 0 | Specify by how much should the space padding value be multiplied of, to re-arange the final slide padding. | 93 | | speed | Number | 500 | Slide transition speed. Number of milliseconds accepted. | 94 | | tagName | String | slide | Name (tag) of slide component. Overwrite with coponent name when extending slide component. | 95 | | touchDrag | Boolean | true | Flag to toggle touch dragging. | 96 | | value | Number | | Support for v-model functionality. Setting this value will change the current page to the number inputted (if between 0 and pageCount). | 97 | 98 | 99 | ### Events 100 | | Event | Type | Emitter | Description | 101 | |:--------------------------|:--------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 102 | | `navigation-click` | | Carousel | Emits when the a navigation button is clicked, with the current direction (`backward` or `forward`) | 103 | | `pagination-click` | | Carousel | Emits when a pagination button is clicked, with the current `pageNumber` | 104 | | `page-change` | Number | Carousel | Emits with the current page number. | 105 | | `slide-click` | Object | Slide | Emits with the *dataset* object of the selected element ·· 106 | | `transition-start` | | Carousel | Emits when the transition end is reached | 107 | | `transition-end` | | Carousel | Emits when the transition start is reached · | 108 | 109 | Lowercase versions of the above events are also emitted, namely—`pagechange`, `slideclick`, `transitionstart` and `transitionend`. 110 | 111 | ### HTML Structure 112 | 113 | Once the **Carousel** and **Slide** components are installed globally or imported, they can be used in templates in the following manner: 114 | 115 | ``` vue 116 | 117 | 118 | Slide 1 Content 119 | 120 | 121 | Slide 2 Content 122 | 123 | 124 | ``` 125 | 126 | To listen for the 'slideclick' event you can do the following: 127 | 128 | ``` vue 129 | 130 | 134 | Slide 1 Content 135 | 136 | ... 137 | 138 | ``` 139 | 140 | ``` js 141 | handleSlideClick (dataset) => { 142 | console.log(dataset.index, dataset.name) 143 | } 144 | ``` 145 | ## Development 146 | 147 | A sandboxed dev environment is provided by [vue-play](https://github.com/vue-play/vue-play). Changes made to the component files will appear in real time in the sandbox. 148 | 149 | To begin development, run: 150 | 151 | ``` bash 152 | yarn install 153 | yarn dev 154 | ``` 155 | 156 | then navigate to `http://localhost:5000` 157 | 158 | To modify and add sandbox scenarios, edit `play/index.js` 159 | 160 | ## License 161 | 162 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. 163 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = (api) => { 2 | const isTest = api.env('test'); 3 | 4 | const config = { 5 | presets: [ 6 | ["@babel/preset-env", { 7 | targets: { 8 | "browsers": ["last 2 versions", "IE 11"] 9 | }, 10 | useBuiltIns: "usage" 11 | }], 12 | ], 13 | }; 14 | 15 | if(isTest) { 16 | api.cache.never(); 17 | } 18 | 19 | return config; 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | archives 2 | [2]* -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: Vue Carousel 7 | subtitle: 8 | description: 9 | author: SSENSE 10 | language: 11 | timezone: 12 | 13 | # URL 14 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 15 | url: http://ssense.github.io/vue-carousel/ 16 | root: /vue-carousel/ 17 | permalink: :year/:month/:day/:title/ 18 | permalink_defaults: 19 | 20 | # Directory 21 | source_dir: source 22 | public_dir: public 23 | tag_dir: tags 24 | archive_dir: archives 25 | category_dir: categories 26 | code_dir: downloads/code 27 | i18n_dir: :lang 28 | skip_render: 29 | 30 | # Writing 31 | new_post_name: :title.md # File name of new posts 32 | default_layout: post 33 | titlecase: false # Transform title into titlecase 34 | external_link: true # Open external links in new tab 35 | filename_case: 0 36 | render_drafts: false 37 | post_asset_folder: false 38 | relative_link: false 39 | future: true 40 | highlight: 41 | enable: true 42 | line_number: true 43 | auto_detect: false 44 | tab_replace: 45 | 46 | # Category & Tag 47 | default_category: uncategorized 48 | category_map: 49 | tag_map: 50 | 51 | # Date / Time format 52 | ## Hexo uses Moment.js to parse and display date 53 | ## You can customize the date format as defined in 54 | ## http://momentjs.com/docs/#/displaying/format/ 55 | date_format: YYYY-MM-DD 56 | time_format: HH:mm:ss 57 | 58 | # Pagination 59 | ## Set per_page to 0 to disable pagination 60 | per_page: 10 61 | pagination_dir: page 62 | 63 | # Extensions 64 | ## Plugins: https://hexo.io/plugins/ 65 | ## Themes: https://hexo.io/themes/ 66 | theme: vue 67 | 68 | # Deployment 69 | ## Docs: https://hexo.io/docs/deployment.html 70 | deploy: 71 | type: 72 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "3.7.1" 7 | }, 8 | "dependencies": { 9 | "hexo": "^3.2.0", 10 | "hexo-generator-archive": "^0.1.4", 11 | "hexo-generator-category": "^0.1.3", 12 | "hexo-generator-index": "^0.2.0", 13 | "hexo-generator-tag": "^0.2.0", 14 | "hexo-renderer-ejs": "^0.2.0", 15 | "hexo-renderer-marked": "^0.2.10", 16 | "hexo-renderer-stylus": "^0.3.1", 17 | "hexo-server": "^0.2.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docs/public/css/benchmark.css: -------------------------------------------------------------------------------- 1 | #benchmark-results { 2 | margin-bottom: 2em; 3 | } 4 | #benchmark-results ul { 5 | list-style-type: none; 6 | padding: 0; 7 | margin-left: 0; 8 | } 9 | #benchmark-results .framework, 10 | #benchmark-results .time, 11 | #benchmark-results .bar, 12 | #benchmark-results .inner { 13 | display: inline-block; 14 | } 15 | #benchmark-results .framework { 16 | width: 4.2em; 17 | margin-right: 1em; 18 | font-weight: 600; 19 | } 20 | #benchmark-results .time { 21 | width: 4.2em; 22 | margin-right: 1em; 23 | } 24 | #benchmark-results .bar { 25 | width: 60%; 26 | } 27 | #benchmark-results .bar.min .inner { 28 | background-color: #e74c3c; 29 | } 30 | #benchmark-results .inner { 31 | height: 3px; 32 | vertical-align: middle; 33 | background-color: #3498db; 34 | } 35 | @media screen and (max-width: 600px) { 36 | #benchmark-results .bar { 37 | width: 45%; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/public/css/index.css: -------------------------------------------------------------------------------- 1 | .gutter pre { 2 | color: #999; 3 | line-height: 1.5em; 4 | } 5 | pre { 6 | color: #525252; 7 | } 8 | pre .function .keyword, 9 | pre .constant { 10 | color: #0092db; 11 | } 12 | pre .keyword, 13 | pre .attribute { 14 | color: #e96900; 15 | } 16 | pre .number, 17 | pre .literal { 18 | color: #ae81ff; 19 | } 20 | pre .tag, 21 | pre .tag .title, 22 | pre .change, 23 | pre .winutils, 24 | pre .flow, 25 | pre .lisp .title, 26 | pre .clojure .built_in, 27 | pre .nginx .title, 28 | pre .tex .special { 29 | color: #2973b7; 30 | } 31 | pre .class .title { 32 | color: #fff; 33 | } 34 | pre .symbol, 35 | pre .symbol .string, 36 | pre .value, 37 | pre .regexp { 38 | color: #42b983; 39 | } 40 | pre .title { 41 | color: #a6e22e; 42 | } 43 | pre .tag .value, 44 | pre .string, 45 | pre .subst, 46 | pre .haskell .type, 47 | pre .preprocessor, 48 | pre .ruby .class .parent, 49 | pre .built_in, 50 | pre .sql .aggregate, 51 | pre .django .template_tag, 52 | pre .django .variable, 53 | pre .smalltalk .class, 54 | pre .javadoc, 55 | pre .django .filter .argument, 56 | pre .smalltalk .localvars, 57 | pre .smalltalk .array, 58 | pre .attr_selector, 59 | pre .pseudo, 60 | pre .addition, 61 | pre .stream, 62 | pre .envvar, 63 | pre .apache .tag, 64 | pre .apache .cbracket, 65 | pre .tex .command, 66 | pre .prompt { 67 | color: #42b983; 68 | } 69 | pre .comment, 70 | pre .java .annotation, 71 | pre .python .decorator, 72 | pre .template_comment, 73 | pre .pi, 74 | pre .doctype, 75 | pre .deletion, 76 | pre .shebang, 77 | pre .apache .sqbracket, 78 | pre .tex .formula { 79 | color: #b3b3b3; 80 | } 81 | pre .coffeescript .javascript, 82 | pre .javascript .xml, 83 | pre .tex .formula, 84 | pre .xml .javascript, 85 | pre .xml .vbscript, 86 | pre .xml .css, 87 | pre .xml .cdata { 88 | opacity: 0.5; 89 | } 90 | body { 91 | font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; 92 | font-size: 15px; 93 | -webkit-font-smoothing: antialiased; 94 | -moz-osx-font-smoothing: grayscale; 95 | color: #34495e; 96 | background-color: #fff; 97 | margin: 0; 98 | } 99 | body.docs { 100 | padding-top: 61px; 101 | } 102 | @media screen and (max-width: 900px) { 103 | body.docs { 104 | padding-top: 0; 105 | } 106 | } 107 | a { 108 | text-decoration: none; 109 | color: #34495e; 110 | } 111 | img { 112 | border: none; 113 | } 114 | h1, 115 | h2, 116 | h3, 117 | h4, 118 | strong { 119 | font-weight: 600; 120 | color: #2c3e50; 121 | } 122 | code, 123 | pre { 124 | font-family: 'Roboto Mono', Monaco, courier, monospace; 125 | font-size: 0.8em; 126 | background-color: #f8f8f8; 127 | -webkit-font-smoothing: initial; 128 | -moz-osx-font-smoothing: initial; 129 | } 130 | code { 131 | color: #e96900; 132 | padding: 3px 5px; 133 | margin: 0 2px; 134 | border-radius: 2px; 135 | white-space: nowrap; 136 | } 137 | em { 138 | color: #7f8c8d; 139 | } 140 | p { 141 | word-spacing: 0.05em; 142 | } 143 | a.button { 144 | padding: 0.75em 2em; 145 | border-radius: 2em; 146 | display: inline-block; 147 | color: #fff; 148 | background-color: #4fc08d; 149 | transition: all 0.15s ease; 150 | box-sizing: border-box; 151 | border: 1px solid #4fc08d; 152 | } 153 | a.button.white { 154 | background-color: #fff; 155 | color: #42b983; 156 | } 157 | .highlight { 158 | overflow-x: auto; 159 | position: relative; 160 | padding: 0; 161 | background-color: #f8f8f8; 162 | padding: 0.8em 0.8em 0.4em; 163 | line-height: 1.1em; 164 | border-radius: 2px; 165 | } 166 | .highlight table, 167 | .highlight tr, 168 | .highlight td { 169 | width: 100%; 170 | border-collapse: collapse; 171 | padding: 0; 172 | margin: 0; 173 | } 174 | .highlight .gutter { 175 | width: 1.5em; 176 | } 177 | .highlight .code pre { 178 | padding: 1.2em 1.4em; 179 | line-height: 1.5em; 180 | margin: 0; 181 | } 182 | .highlight .code .line { 183 | min-height: 1.5em; 184 | } 185 | .highlight.html .code:after, 186 | .highlight.js .code:after, 187 | .highlight.bash .code:after, 188 | .highlight.css .code:after { 189 | position: absolute; 190 | top: 0; 191 | right: 0; 192 | color: #ccc; 193 | text-align: right; 194 | font-size: 0.75em; 195 | padding: 5px 10px 0; 196 | line-height: 15px; 197 | height: 15px; 198 | font-weight: 600; 199 | } 200 | .highlight.html .code:after { 201 | content: 'HTML'; 202 | } 203 | .highlight.js .code:after { 204 | content: 'JS'; 205 | } 206 | .highlight.bash .code:after { 207 | content: 'Shell'; 208 | } 209 | .highlight.css .code:after { 210 | content: 'CSS'; 211 | } 212 | #main { 213 | position: relative; 214 | z-index: 1; 215 | padding: 0 60px 30px; 216 | overflow-x: hidden; 217 | } 218 | #ad { 219 | width: 125px; 220 | position: fixed; 221 | z-index: 99; 222 | bottom: 10px; 223 | right: 10px; 224 | padding: 10px; 225 | background-color: #fff; 226 | border-radius: 3px; 227 | font-size: 13px; 228 | } 229 | #ad a { 230 | display: inline-block; 231 | color: #7f8c8d; 232 | font-weight: normal; 233 | } 234 | #ad span { 235 | color: #7f8c8d; 236 | display: inline-block; 237 | margin-bottom: 5px; 238 | } 239 | #ad img { 240 | width: 125px; 241 | } 242 | #ad .carbon-img, 243 | #ad .carbon-text { 244 | display: block; 245 | margin-bottom: 6px; 246 | font-weight: normal; 247 | color: #34495e; 248 | } 249 | #ad .carbon-poweredby { 250 | color: #aaa; 251 | font-weight: normal; 252 | } 253 | #nav .nav-link { 254 | cursor: pointer; 255 | } 256 | #nav .nav-dropdown-container .nav-link:hover { 257 | border-bottom: none; 258 | } 259 | #nav .nav-dropdown-container:hover .nav-dropdown { 260 | display: block; 261 | } 262 | #nav .nav-dropdown-container.language { 263 | margin-left: 20px; 264 | } 265 | #nav .nav-dropdown-container .arrow { 266 | pointer-events: none; 267 | } 268 | #nav .nav-dropdown { 269 | display: none; 270 | box-sizing: border-box; 271 | max-height: calc(100vh - 61px); 272 | overflow-y: scroll; 273 | position: absolute; 274 | top: 100%; 275 | right: -15px; 276 | background-color: #fff; 277 | padding: 10px 0; 278 | border: 1px solid #ddd; 279 | border-bottom-color: #ccc; 280 | text-align: left; 281 | border-radius: 4px; 282 | white-space: nowrap; 283 | } 284 | #nav .nav-dropdown li { 285 | line-height: 1.8em; 286 | margin: 0; 287 | display: block; 288 | } 289 | #nav .nav-dropdown li > ul { 290 | padding-left: 0; 291 | } 292 | #nav .nav-dropdown li:first-child h4 { 293 | margin-top: 0; 294 | padding-top: 0; 295 | border-top: 0; 296 | } 297 | #nav .nav-dropdown a, 298 | #nav .nav-dropdown h4 { 299 | padding: 0 24px 0 20px; 300 | } 301 | #nav .nav-dropdown h4 { 302 | margin: 0.45em 0 0; 303 | padding-top: 0.45em; 304 | border-top: 1px solid #eee; 305 | } 306 | #nav .nav-dropdown a { 307 | color: #3a5169; 308 | font-size: 0.9em; 309 | display: block; 310 | } 311 | #nav .nav-dropdown a:hover { 312 | color: #42b983; 313 | } 314 | #nav .arrow { 315 | display: inline-block; 316 | vertical-align: middle; 317 | margin-top: -1px; 318 | margin-left: 6px; 319 | margin-right: -14px; 320 | width: 0; 321 | height: 0; 322 | border-left: 4px solid transparent; 323 | border-right: 4px solid transparent; 324 | border-top: 5px solid #ccc; 325 | } 326 | #header { 327 | background-color: #fff; 328 | height: $heading-inner-height; 329 | padding: 10px 60px; 330 | position: relative; 331 | z-index: 2; 332 | } 333 | body.docs #header { 334 | position: fixed; 335 | width: 100%; 336 | top: 0; 337 | } 338 | body.docs #nav { 339 | position: fixed; 340 | } 341 | #nav { 342 | list-style-type: none; 343 | margin: 0; 344 | padding: 0; 345 | position: absolute; 346 | right: 60px; 347 | top: 10px; 348 | height: 40px; 349 | line-height: 40px; 350 | } 351 | #nav .break { 352 | display: none; 353 | } 354 | #nav li { 355 | display: inline-block; 356 | position: relative; 357 | margin: 0 0.6em; 358 | } 359 | .nav-link { 360 | padding-bottom: 3px; 361 | } 362 | .nav-link:hover, 363 | .nav-link.current { 364 | border-bottom: 3px solid #42b983; 365 | } 366 | .search-query { 367 | height: 30px; 368 | line-height: 30px; 369 | box-sizing: border-box; 370 | padding: 0 15px 0 30px; 371 | border: 1px solid #e3e3e3; 372 | color: #2c3e50; 373 | outline: none; 374 | border-radius: 15px; 375 | margin-right: 10px; 376 | transition: border-color 0.2s ease; 377 | background: #fff url("/images/search.png") 8px 5px no-repeat; 378 | background-size: 20px; 379 | vertical-align: middle !important; 380 | } 381 | .search-query:focus { 382 | border-color: #42b983; 383 | } 384 | #logo { 385 | display: inline-block; 386 | font-size: 1.5em; 387 | line-height: 40px; 388 | color: #2c3e50; 389 | font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; 390 | font-weight: 500; 391 | } 392 | #logo img { 393 | vertical-align: middle; 394 | margin-right: 6px; 395 | width: 40px; 396 | height: 40px; 397 | } 398 | #mobile-bar { 399 | position: fixed; 400 | top: 0; 401 | left: 0; 402 | width: 100%; 403 | height: 40px; 404 | background-color: #fff; 405 | z-index: 9; 406 | display: none; 407 | box-shadow: 0 0 2px rgba(0,0,0,0.25); 408 | } 409 | #mobile-bar .menu-button { 410 | position: absolute; 411 | width: 24px; 412 | height: 24px; 413 | top: 8px; 414 | left: 12px; 415 | background: url("../images/menu.png") center center no-repeat; 416 | background-size: 24px; 417 | } 418 | #mobile-bar .logo { 419 | position: absolute; 420 | width: 30px; 421 | height: 30px; 422 | background: url("../images/logo.png") center center no-repeat; 423 | top: 5px; 424 | left: 50%; 425 | margin-left: -15px; 426 | background-size: 30px; 427 | } 428 | .sidebar { 429 | position: absolute; 430 | z-index: 10; 431 | top: 61px; 432 | left: 0; 433 | bottom: 0; 434 | padding: 40px 0 30px 60px; 435 | width: 260px; 436 | margin-right: 20px; 437 | overflow-x: hidden; 438 | overflow-y: auto; 439 | -webkit-overflow-scrolling: touch; 440 | -ms-overflow-style: none; 441 | } 442 | .sidebar h2 { 443 | margin-top: 0.2em; 444 | } 445 | .sidebar ul { 446 | list-style-type: none; 447 | margin: 0; 448 | line-height: 1.8em; 449 | padding-left: 1em; 450 | } 451 | .sidebar .version-select { 452 | vertical-align: middle; 453 | margin-left: 5px; 454 | } 455 | .sidebar .menu-root { 456 | padding-left: 0; 457 | } 458 | .sidebar .menu-sub { 459 | font-size: 0.85em; 460 | } 461 | .sidebar .sidebar-link { 462 | color: #7f8c8d; 463 | } 464 | .sidebar .sidebar-link.current { 465 | font-weight: 600; 466 | color: #42b983; 467 | } 468 | .sidebar .sidebar-link.new:after { 469 | content: "NEW"; 470 | display: inline-block; 471 | font-size: 10px; 472 | font-weight: 600; 473 | color: #fff; 474 | background-color: #42b983; 475 | line-height: 14px; 476 | padding: 0 4px; 477 | border-radius: 3px; 478 | margin-left: 5px; 479 | vertical-align: middle; 480 | position: relative; 481 | top: -1px; 482 | } 483 | .sidebar .sidebar-link:hover { 484 | border-bottom: 2px solid #42b983; 485 | } 486 | .sidebar .section-link.active { 487 | font-weight: bold; 488 | color: #42b983; 489 | } 490 | .sidebar .main-menu { 491 | margin-bottom: 20px; 492 | display: none; 493 | padding-left: 0; 494 | } 495 | .sidebar .main-sponsor { 496 | color: #7f8c8d; 497 | font-size: 0.85em; 498 | } 499 | .sidebar .main-sponsor a { 500 | margin: 10px 0; 501 | } 502 | .sidebar .main-sponsor img, 503 | .sidebar .main-sponsor a { 504 | width: 125px; 505 | display: inline-block; 506 | } 507 | .sidebar .become-backer { 508 | border: 1px solid #42b983; 509 | border-radius: 2em; 510 | display: inline-block; 511 | color: #42b983; 512 | font-size: 0.8em; 513 | width: 125px; 514 | padding: 4px 0; 515 | text-align: center; 516 | margin-bottom: 20px; 517 | } 518 | .sidebar .nav-dropdown h4 { 519 | font-weight: normal; 520 | margin: 0; 521 | } 522 | @media screen and (max-width: 900px) { 523 | .sidebar { 524 | position: fixed; 525 | z-index: 8; 526 | background-color: #f9f9f9; 527 | height: 100%; 528 | top: 0; 529 | left: 0; 530 | padding: 60px 30px 20px; 531 | box-shadow: 0 0 10px rgba(0,0,0,0.2); 532 | box-sizing: border-box; 533 | transition: all 0.4s cubic-bezier(0.4, 0, 0, 1); 534 | -webkit-transform: translate(-280px, 0); 535 | transform: translate(-280px, 0); 536 | } 537 | .sidebar .search-query { 538 | width: 200px; 539 | margin-bottom: 10px; 540 | } 541 | .sidebar .main-menu { 542 | display: block; 543 | } 544 | .sidebar.open { 545 | -webkit-transform: translate(0, 0); 546 | transform: translate(0, 0); 547 | } 548 | } 549 | body { 550 | background-color: #727f80; 551 | } 552 | .sidebar { 553 | display: none; 554 | } 555 | .slide { 556 | padding: 0 12px; 557 | box-sizing: border-box; 558 | } 559 | .slide img { 560 | width: 100%; 561 | } 562 | #mobile-bar.top { 563 | background-color: transparent; 564 | box-shadow: none; 565 | } 566 | #mobile-bar.top .logo { 567 | display: none; 568 | } 569 | #hero { 570 | padding: 50px 40px; 571 | background-color: #fff; 572 | text-align: center; 573 | } 574 | #hero .inner { 575 | max-width: 900px; 576 | margin: 0 auto; 577 | } 578 | #hero .left, 579 | #hero .right { 580 | display: inline-block; 581 | vertical-align: top; 582 | } 583 | #hero .left { 584 | width: 39%; 585 | } 586 | #hero .right { 587 | width: 61%; 588 | } 589 | #hero .hero-logo { 590 | width: 215px; 591 | height: 215px; 592 | float: right; 593 | margin-right: 60px; 594 | } 595 | #hero h1 { 596 | font-weight: 300; 597 | margin: 0; 598 | font-size: 3.2em; 599 | } 600 | #hero h2 { 601 | font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; 602 | font-weight: 500; 603 | font-size: 2.4em; 604 | margin: 0 0 10px; 605 | display: none; 606 | } 607 | #hero .button { 608 | margin: 1em 0; 609 | font-size: 1.05em; 610 | font-weight: 600; 611 | letter-spacing: 0.1em; 612 | } 613 | #hero .button:first-child { 614 | margin-right: 1em; 615 | } 616 | #hero .social-buttons { 617 | list-style-type: none; 618 | padding: 0; 619 | } 620 | #hero .social-buttons li { 621 | display: inline-block; 622 | vertical-align: middle; 623 | margin-right: 15px; 624 | } 625 | #highlights { 626 | background-color: #fff; 627 | padding-bottom: 70px; 628 | } 629 | #highlights .inner { 630 | max-width: 900px; 631 | margin: 0 auto; 632 | text-align: center; 633 | } 634 | #highlights .point { 635 | width: 33%; 636 | display: inline-block; 637 | vertical-align: top; 638 | box-sizing: border-box; 639 | padding: 0 2em; 640 | } 641 | #highlights .point h2 { 642 | color: #42b983; 643 | font-size: 1.5em; 644 | font-weight: 400; 645 | margin: 0; 646 | padding: 0.5em 0; 647 | } 648 | #highlights .point p { 649 | color: #7f8c8d; 650 | } 651 | #sponsors { 652 | text-align: center; 653 | padding: 35px 40px 45px; 654 | background-color: #f6f6f6; 655 | } 656 | #sponsors .inner { 657 | max-width: 700px; 658 | margin: 0px auto; 659 | } 660 | #sponsors h3 { 661 | color: #999; 662 | font-size: 0.9em; 663 | margin: 0 0 10px; 664 | } 665 | #sponsors a { 666 | margin: 20px 15px 0; 667 | position: relative; 668 | } 669 | #sponsors a, 670 | #sponsors img { 671 | width: 100px; 672 | display: inline-block; 673 | vertical-align: middle; 674 | } 675 | #sponsors img { 676 | transition: all 0.3s ease; 677 | filter: contrast(0%); 678 | } 679 | #sponsors img:hover { 680 | filter: none; 681 | } 682 | #sponsors a.vip { 683 | display: block; 684 | margin: 30px auto 15px; 685 | width: 200px; 686 | } 687 | #sponsors a.vip img { 688 | width: 200px; 689 | } 690 | #sponsors .become-sponsor { 691 | margin-top: 40px; 692 | font-size: 0.9em; 693 | font-weight: 700; 694 | width: auto; 695 | background-color: transparent; 696 | } 697 | #footer { 698 | padding: 50px 0; 699 | color: #fff; 700 | text-align: center; 701 | } 702 | #footer a { 703 | font-weight: 700; 704 | color: #fff; 705 | } 706 | @media screen and (max-width: 900px) { 707 | body { 708 | -webkit-text-size-adjust: none; 709 | font-size: 14px; 710 | } 711 | .sidebar { 712 | display: block; 713 | } 714 | #header { 715 | display: none; 716 | } 717 | #mobile-bar { 718 | display: block; 719 | } 720 | #hero { 721 | padding: 50px 40px 30px; 722 | } 723 | #hero .hero-logo { 724 | float: none; 725 | margin: 30px 0 15px; 726 | width: 140px; 727 | height: 140px; 728 | } 729 | #hero .left, 730 | #hero .right { 731 | text-align: center; 732 | width: 100%; 733 | } 734 | #hero h1 { 735 | font-size: 2em; 736 | } 737 | #hero h2 { 738 | display: block; 739 | } 740 | #hero .button { 741 | font-size: 0.9em; 742 | } 743 | #highlights .point { 744 | display: block; 745 | margin: 0 auto; 746 | width: 300px; 747 | padding: 0 40px 30px; 748 | } 749 | #highlights .point:before { 750 | content: "—"; 751 | color: #42b983; 752 | } 753 | } 754 | -------------------------------------------------------------------------------- /docs/public/css/search.css: -------------------------------------------------------------------------------- 1 | .algolia-autocomplete { 2 | line-height: normal; 3 | } 4 | .aa-dropdown-menu { 5 | width: 100%; 6 | border-color: #999; 7 | font-size: 0.9rem; 8 | } 9 | @media (min-width: 768px) { 10 | .aa-dropdown-menu { 11 | min-width: 515px; 12 | } 13 | } 14 | .algolia-docsearch-suggestion { 15 | border-color: #ddd; 16 | } 17 | .algolia-docsearch-suggestion--content { 18 | color: #2c3e50; 19 | } 20 | .algolia-docsearch-suggestion--subcategory-column { 21 | border-color: #ddd; 22 | } 23 | .algolia-docsearch-suggestion--category-header { 24 | background: #42b983; 25 | } 26 | .algolia-docsearch-footer { 27 | border-color: #ddd; 28 | } 29 | .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight { 30 | background: rgba(255,255,255,0.6); 31 | } 32 | .algolia-docsearch-suggestion--highlight { 33 | color: #2c815b; 34 | } 35 | .aa-cursor .algolia-docsearch-suggestion--content { 36 | color: #2c3e50; 37 | } 38 | -------------------------------------------------------------------------------- /docs/public/examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Examples - Vue Carousel 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 |
37 | 49 | 50 | 51 |
52 | 53 | 54 | 62 | 63 |
64 | 65 | 66 |

Examples

67 | 68 |

Basic

No options configured, 10 slides added to the carousel.

69 | 70 | 71 |

Responsive

Configured breakpoints: 2 slides on mobile (<= 480px), 3 slides on tablet (<= 768).
Note: in a JSFiddle iframe, the breakpoint is determined by the iframe’s width.

72 | 73 | 74 |

Scroll per page

Instead of scrolling on a per item basis, the carousel will scroll the configured perPage with each movement.

75 | 76 | 77 |

Scroll per page (custom)

Instead of scrolling on a per item basis, the carousel will scroll the configured by perPageCustom with each movement.

78 | 79 | 80 |

Autoplay

The carousel will auto-advance slides unless the carousel is hovered upon.

81 | 82 | 83 |

Autoplay infinite loop

The carousel will auto-play and loop when reaching the end.

84 | 85 | 86 |

Buttons added to advance the carousel in either direction.

87 | 88 | 89 |

Customized

Customized pagination dot colors and sizes. Customized speed and easing.

90 | 91 | 92 | 93 | 94 | 95 | 101 |
102 | 103 | 104 |
105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 121 | 122 | 123 | 124 | 125 | 126 | 144 | 145 | 146 | 147 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/public/guide/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Guide - Vue Carousel 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 |
37 | 49 | 50 | 51 |
52 | 53 | 54 | 62 | 63 |
64 | 65 | 66 |

Guide

67 | 68 |

Installation

1
npm install -S vue-carousel
69 |

Usage (Global)

You may install Vue Carousel globally:

70 |
1
2
3
4
import Vue from 'vue';
import VueCarousel from 'vue-carousel';

Vue.use(VueCarousel);
71 |

This will make <carousel> and <slide> available to all components within your Vue app.

72 |

Usage (Local)

Include the carousel directly into your component using import:

73 |
1
2
3
4
5
6
7
8
9
10
import { Carousel, Slide } from 'vue-carousel';

export default {
...
components: {
Carousel,
Slide
}
...
};
74 |

HTML Structure

Once the Carousel and Slide components are installed globally or imported, they can be used in templates in the following manner:

75 |
1
2
3
4
5
6
7
8
<carousel>
<slide>
Slide 1 Content
</slide>
<slide>
Slide 2 Content
</slide>
</carousel>
76 | 77 | 83 |
84 | 85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 103 | 104 | 105 | 106 | 107 | 108 | 126 | 127 | 128 | 129 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /docs/public/images/actualize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/actualize.png -------------------------------------------------------------------------------- /docs/public/images/chaitin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/chaitin.png -------------------------------------------------------------------------------- /docs/public/images/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/check.png -------------------------------------------------------------------------------- /docs/public/images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/down.png -------------------------------------------------------------------------------- /docs/public/images/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/feed.png -------------------------------------------------------------------------------- /docs/public/images/htmlburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/htmlburger.png -------------------------------------------------------------------------------- /docs/public/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/icons.png -------------------------------------------------------------------------------- /docs/public/images/itunescn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/itunescn.png -------------------------------------------------------------------------------- /docs/public/images/jsfiddle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/jsfiddle.png -------------------------------------------------------------------------------- /docs/public/images/juejin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/juejin.png -------------------------------------------------------------------------------- /docs/public/images/laravel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/laravel.png -------------------------------------------------------------------------------- /docs/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/logo.png -------------------------------------------------------------------------------- /docs/public/images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/menu.png -------------------------------------------------------------------------------- /docs/public/images/monterail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/monterail.png -------------------------------------------------------------------------------- /docs/public/images/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/patreon.png -------------------------------------------------------------------------------- /docs/public/images/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/paypal.png -------------------------------------------------------------------------------- /docs/public/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/search.png -------------------------------------------------------------------------------- /docs/public/images/someline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/someline.png -------------------------------------------------------------------------------- /docs/public/images/strikingly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/strikingly.png -------------------------------------------------------------------------------- /docs/public/images/tde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/tde.png -------------------------------------------------------------------------------- /docs/public/images/transition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/transition.png -------------------------------------------------------------------------------- /docs/public/images/trisoft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/trisoft.png -------------------------------------------------------------------------------- /docs/public/images/vuejobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/public/images/vuejobs.png -------------------------------------------------------------------------------- /docs/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue Carousel 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 |
37 | 49 | 50 | 51 | 59 | 60 |
61 |
62 |

63 | A flexible, responsive, touch-friendly
carousel for Vue.js 64 |

65 |

66 | GET STARTED 67 | GITHUB 68 |

69 |
70 |
71 | 72 |
73 |
74 |
75 |
76 |
77 | 78 | 102 | 103 |
104 |
105 |
106 |

Flexible

107 |

Slides use Vue's built-in slot system, allowing you to display any type of content in slides (including other Vue components!)

108 |
109 | 110 |
111 |

Responsive

112 |

Breakpoints in Vue Carousel can be configured to have different slide counts depending on the device's display resolution.

113 |
114 | 115 |
116 |

Touch-friendly

117 |

118 | Touch and drag supported on both desktop and mobile devices. 119 |

120 |
121 |
122 |
123 | 124 |
125 |
126 |

SPONSORED BY

127 | 128 | 129 | 130 |
131 | We're Hiring! 132 | Contribute 133 |
134 |
135 | 136 | 140 | 141 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 169 | 170 | 171 | 172 | 173 | 174 | 192 | 193 | 194 | 195 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /docs/public/js/common.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | initMobileMenu() 4 | if (PAGE_TYPE) { 5 | initVersionSelect() 6 | initSubHeaders() 7 | initApiSpecLinks() 8 | initLocationHashFuzzyMatching() 9 | } 10 | 11 | function initApiSpecLinks () { 12 | var apiContent = document.querySelector('.content.api') 13 | if (apiContent) { 14 | var apiTitles = [].slice.call(apiContent.querySelectorAll('h3')) 15 | apiTitles.forEach(function (titleNode) { 16 | var ulNode = titleNode.parentNode.nextSibling 17 | if (ulNode.tagName !== 'UL') { 18 | ulNode = ulNode.nextSibling 19 | } 20 | if (ulNode.tagName === 'UL') { 21 | var specNode = document.createElement('li') 22 | var specLink = createSourceSearchPath(titleNode.textContent) 23 | specNode.innerHTML = 'Source' 24 | ulNode.appendChild(specNode) 25 | } 26 | }) 27 | } 28 | 29 | function createSourceSearchPath(query) { 30 | return 'https://github.com/search?utf8=%E2%9C%93&q=repo%3Avuejs%2Fvue+extension%3Ajs+' + encodeURIComponent(query) + '+&type=Code' 31 | } 32 | } 33 | 34 | function initLocationHashFuzzyMatching () { 35 | var hash = window.location.hash 36 | if (!hash) return 37 | var hashTarget = document.getElementById(hash) 38 | if (!hashTarget) { 39 | var normalizedHash = normalizeHash(hash) 40 | var possibleHashes = [].slice.call(document.querySelectorAll('[id]')) 41 | .map(function (el) { return el.id }) 42 | possibleHashes.sort(function (hashA, hashB) { 43 | var distanceA = levenshteinDistance(normalizedHash, normalizeHash(hashA)) 44 | var distanceB = levenshteinDistance(normalizedHash, normalizeHash(hashB)) 45 | if (distanceA < distanceB) return -1 46 | if (distanceA > distanceB) return 1 47 | return 0 48 | }) 49 | window.location.hash = possibleHashes[0] 50 | } 51 | 52 | function normalizeHash (rawHash) { 53 | return rawHash 54 | .toLowerCase() 55 | .replace(/\-(?:deprecated|removed|replaced|changed|obsolete)$/, '') 56 | } 57 | 58 | function levenshteinDistance (a, b) { 59 | var m = [] 60 | if (!(a && b)) return (b || a).length 61 | for (var i = 0; i <= b.length; m[i] = [i++]) {} 62 | for (var j = 0; j <= a.length; m[0][j] = j++) {} 63 | for (var i = 1; i <= b.length; i++) { 64 | for (var j = 1; j <= a.length; j++) { 65 | m[i][j] = b.charAt(i - 1) === a.charAt(j - 1) 66 | ? m[i - 1][j - 1] 67 | : m[i][j] = Math.min( 68 | m[i - 1][j - 1] + 1, 69 | Math.min(m[i][j - 1] + 1, m[i - 1][j] + 1)) 70 | } 71 | } 72 | return m[b.length][a.length] 73 | } 74 | } 75 | 76 | /** 77 | * Mobile burger menu button for toggling sidebar 78 | */ 79 | 80 | function initMobileMenu () { 81 | var mobileBar = document.getElementById('mobile-bar') 82 | var sidebar = document.querySelector('.sidebar') 83 | var menuButton = mobileBar.querySelector('.menu-button') 84 | 85 | menuButton.addEventListener('click', function () { 86 | sidebar.classList.toggle('open') 87 | }) 88 | 89 | document.body.addEventListener('click', function (e) { 90 | if (e.target !== menuButton && !sidebar.contains(e.target)) { 91 | sidebar.classList.remove('open') 92 | } 93 | }) 94 | } 95 | 96 | /** 97 | * Doc version select 98 | */ 99 | 100 | function initVersionSelect () { 101 | // version select 102 | var versionSelect = document.querySelector('.version-select') 103 | versionSelect && versionSelect.addEventListener('change', function (e) { 104 | var version = e.target.value 105 | var section = window.location.pathname.match(/\/v\d\/(\w+?)\//)[1] 106 | if (version === 'SELF') return 107 | window.location.assign( 108 | 'http://' + 109 | version + 110 | (version && '.') + 111 | 'vuejs.org/' + section + '/' 112 | ) 113 | }) 114 | } 115 | 116 | /** 117 | * Sub headers in sidebar 118 | */ 119 | 120 | function initSubHeaders () { 121 | var each = [].forEach 122 | var main = document.getElementById('main') 123 | var header = document.getElementById('header') 124 | var sidebar = document.querySelector('.sidebar') 125 | var content = document.querySelector('.content') 126 | 127 | // build sidebar 128 | var currentPageAnchor = sidebar.querySelector('.sidebar-link.current') 129 | var isAPI = document.querySelector('.content').classList.contains('api') 130 | if (currentPageAnchor || isAPI) { 131 | var allHeaders = [] 132 | var sectionContainer 133 | if (isAPI) { 134 | sectionContainer = document.querySelector('.menu-root') 135 | } else { 136 | sectionContainer = document.createElement('ul') 137 | sectionContainer.className = 'menu-sub' 138 | currentPageAnchor.parentNode.appendChild(sectionContainer) 139 | } 140 | var headers = content.querySelectorAll('h2') 141 | if (headers.length) { 142 | each.call(headers, function (h) { 143 | sectionContainer.appendChild(makeLink(h)) 144 | var h3s = collectH3s(h) 145 | allHeaders.push(h) 146 | allHeaders.push.apply(allHeaders, h3s) 147 | if (h3s.length) { 148 | sectionContainer.appendChild(makeSubLinks(h3s, isAPI)) 149 | } 150 | }) 151 | } else { 152 | headers = content.querySelectorAll('h3') 153 | each.call(headers, function (h) { 154 | sectionContainer.appendChild(makeLink(h)) 155 | allHeaders.push(h) 156 | }) 157 | } 158 | 159 | var animating = false 160 | sectionContainer.addEventListener('click', function (e) { 161 | e.preventDefault() 162 | if (e.target.classList.contains('section-link')) { 163 | sidebar.classList.remove('open') 164 | setActive(e.target) 165 | animating = true 166 | setTimeout(function () { 167 | animating = false 168 | }, 400) 169 | } 170 | }, true) 171 | 172 | // make links clickable 173 | allHeaders.forEach(makeHeaderClickable) 174 | 175 | smoothScroll.init({ 176 | speed: 400, 177 | offset: 0 178 | }) 179 | } 180 | 181 | var hoveredOverSidebar = false 182 | sidebar.addEventListener('mouseover', function () { 183 | hoveredOverSidebar = true 184 | }) 185 | sidebar.addEventListener('mouseleave', function () { 186 | hoveredOverSidebar = false 187 | }) 188 | 189 | // listen for scroll event to do positioning & highlights 190 | window.addEventListener('scroll', updateSidebar) 191 | window.addEventListener('resize', updateSidebar) 192 | 193 | function updateSidebar () { 194 | var doc = document.documentElement 195 | var top = doc && doc.scrollTop || document.body.scrollTop 196 | if (animating || !allHeaders) return 197 | var last 198 | for (var i = 0; i < allHeaders.length; i++) { 199 | var link = allHeaders[i] 200 | if (link.offsetTop > top) { 201 | if (!last) last = link 202 | break 203 | } else { 204 | last = link 205 | } 206 | } 207 | if (last) 208 | setActive(last.id, !hoveredOverSidebar) 209 | } 210 | 211 | function makeLink (h) { 212 | var link = document.createElement('li') 213 | var text = h.textContent.replace(/\(.*\)$/, '') 214 | link.innerHTML = 215 | '' + 216 | htmlEscape(text) + 217 | '' 218 | return link 219 | } 220 | 221 | function htmlEscape (text) { 222 | return text 223 | .replace(/&/g, '&') 224 | .replace(/"/g, '"') 225 | .replace(/'/g, ''') 226 | .replace(//g, '>') 228 | } 229 | 230 | function collectH3s (h) { 231 | var h3s = [] 232 | var next = h.nextSibling 233 | while (next && next.tagName !== 'H2') { 234 | if (next.tagName === 'H3') { 235 | h3s.push(next) 236 | } 237 | next = next.nextSibling 238 | } 239 | return h3s 240 | } 241 | 242 | function makeSubLinks (h3s, small) { 243 | var container = document.createElement('ul') 244 | if (small) { 245 | container.className = 'menu-sub' 246 | } 247 | h3s.forEach(function (h) { 248 | container.appendChild(makeLink(h)) 249 | }) 250 | return container 251 | } 252 | 253 | function setActive (id, shouldScrollIntoView) { 254 | var previousActive = sidebar.querySelector('.section-link.active') 255 | var currentActive = typeof id === 'string' 256 | ? sidebar.querySelector('.section-link[href="#' + id + '"]') 257 | : id 258 | if (currentActive !== previousActive) { 259 | if (previousActive) previousActive.classList.remove('active') 260 | currentActive.classList.add('active') 261 | if (shouldScrollIntoView) { 262 | var currentPageOffset = currentPageAnchor 263 | ? currentPageAnchor.offsetTop - 8 264 | : 0 265 | var currentActiveOffset = currentActive.offsetTop + currentActive.parentNode.clientHeight 266 | var sidebarHeight = sidebar.clientHeight 267 | var currentActiveIsInView = ( 268 | currentActive.offsetTop >= sidebar.scrollTop && 269 | currentActiveOffset <= sidebar.scrollTop + sidebarHeight 270 | ) 271 | var linkNotFurtherThanSidebarHeight = currentActiveOffset - currentPageOffset < sidebarHeight 272 | var newScrollTop = currentActiveIsInView 273 | ? sidebar.scrollTop 274 | : linkNotFurtherThanSidebarHeight 275 | ? currentPageOffset 276 | : currentActiveOffset - sidebarHeight 277 | sidebar.scrollTop = newScrollTop 278 | } 279 | } 280 | } 281 | 282 | function makeHeaderClickable (link) { 283 | var wrapper = document.createElement('a') 284 | wrapper.href = '#' + link.id 285 | wrapper.setAttribute('data-scroll', '') 286 | link.parentNode.insertBefore(wrapper, link) 287 | wrapper.appendChild(link) 288 | } 289 | } 290 | })() 291 | -------------------------------------------------------------------------------- /docs/public/js/smooth-scroll.min.js: -------------------------------------------------------------------------------- 1 | /** smooth-scroll v5.1.2, by Chris Ferdinandi | http://github.com/cferdinandi/smooth-scroll | Licensed under MIT: http://gomakethings.com/mit/ */ 2 | !function(t,e){"function"==typeof define&&define.amd?define("smoothScroll",e(t)):"object"==typeof exports?module.exports=e(t):t.smoothScroll=e(t)}(this,function(t){"use strict";var e,n={},o=!!document.querySelector&&!!t.addEventListener,r={speed:500,easing:"easeInOutCubic",offset:0,updateURL:!0,callbackBefore:function(){},callbackAfter:function(){}},a=function(t,e,n){if("[object Object]"===Object.prototype.toString.call(t))for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.call(n,t[o],o,t);else for(var r=0,a=t.length;a>r;r++)e.call(n,t[r],r,t)},c=function(t,e){var n={};return a(t,function(e,o){n[o]=t[o]}),a(e,function(t,o){n[o]=e[o]}),n},u=function(t,e){for(var n=e.charAt(0);t&&t!==document;t=t.parentNode)if("."===n){if(t.classList.contains(e.substr(1)))return t}else if("#"===n){if(t.id===e.substr(1))return t}else if("["===n&&t.hasAttribute(e.substr(1,e.length-2)))return t;return!1},i=function(t){for(var e,n=String(t),o=n.length,r=-1,a="",c=n.charCodeAt(0);++r=1&&31>=e||127==e||0===r&&e>=48&&57>=e||1===r&&e>=48&&57>=e&&45===c?"\\"+e.toString(16)+" ":e>=128||45===e||95===e||e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e?n.charAt(r):"\\"+n.charAt(r)}return a},s=function(t,e){var n;return"easeInQuad"===t&&(n=e*e),"easeOutQuad"===t&&(n=e*(2-e)),"easeInOutQuad"===t&&(n=.5>e?2*e*e:-1+(4-2*e)*e),"easeInCubic"===t&&(n=e*e*e),"easeOutCubic"===t&&(n=--e*e*e+1),"easeInOutCubic"===t&&(n=.5>e?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1),"easeInQuart"===t&&(n=e*e*e*e),"easeOutQuart"===t&&(n=1- --e*e*e*e),"easeInOutQuart"===t&&(n=.5>e?8*e*e*e*e:1-8*--e*e*e*e),"easeInQuint"===t&&(n=e*e*e*e*e),"easeOutQuint"===t&&(n=1+--e*e*e*e*e),"easeInOutQuint"===t&&(n=.5>e?16*e*e*e*e*e:1+16*--e*e*e*e*e),n||e},f=function(t,e,n){var o=0;if(t.offsetParent)do o+=t.offsetTop,t=t.offsetParent;while(t);return o=o-e-n,o>=0?o:0},l=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},d=function(t){return t&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(t):{}},h=function(t,e){history.pushState&&(e||"true"===e)&&history.pushState({pos:t.id},"",window.location.pathname+t)};n.animateScroll=function(e,n,o){var a=c(a||r,o||{}),u=d(e?e.getAttribute("data-options"):null);a=c(a,u),n="#"+i(n.substr(1));var p,m,b,v=document.querySelector("[data-scroll-header]"),g=null===v?0:v.offsetHeight+v.offsetTop,O=t.pageYOffset,y=f(document.querySelector(n),g,parseInt(a.offset,10)),I=y-O,S=l(),A=0;h(n,a.updateURL);var Q=function(o,r,c){var u=t.pageYOffset;(o==r||u==r||t.innerHeight+u>=S)&&(clearInterval(c),a.callbackAfter(e,n))},C=function(){A+=16,m=A/parseInt(a.speed,10),m=m>1?1:m,b=O+I*s(a.easing,m),t.scrollTo(0,Math.floor(b)),Q(b,y,p)},H=function(){a.callbackBefore(e,n),p=setInterval(C,16)};0===t.pageYOffset&&t.scrollTo(0,0),H()};var p=function(t){var o=u(t.target,"[data-scroll]");o&&"a"===o.tagName.toLowerCase()&&(t.preventDefault(),n.animateScroll(o,o.hash,e,t))};return n.destroy=function(){e&&(document.removeEventListener("click",p,!1),e=null)},n.init=function(t){o&&(n.destroy(),e=c(r,t||{}),document.addEventListener("click",p,!1))},n}); -------------------------------------------------------------------------------- /docs/scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /docs/scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /docs/scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /docs/source/_posts/home.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: home 3 | date: 2016-12-29 15:37:46 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /docs/source/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: API 3 | --- 4 | 5 | ## Global config 6 | 7 | ### adjustableHeight 8 | 9 | Adjust the height of the carousel for the current slide. 10 | 11 | * **Type**: `Boolean` 12 | * **Default**: `false` 13 | 14 | ### adjustableHeightEasing 15 | 16 | Slide transition easing for adjustableHeight. 17 | 18 | * **Type**: `String` 19 | 20 | ### autoplay 21 | 22 | Flag to enable autoplay. 23 | 24 | * **Type**: `Boolean` 25 | * **Default**: `false` 26 | 27 | ### autoplayDirection 28 | 29 | Sets the autoplay direction for the carousel during autoplay. 30 | 31 | * **Type**: `String` 32 | * **Default**: `forward` 33 | 34 | ### autoplayTimeout 35 | 36 | Time elapsed before advancing slide in autoplay. 37 | 38 | * **Type**: `Number` 39 | * **Default**: `2000` 40 | 41 | ### autoplayHoverPause 42 | 43 | Flag to pause autoplay on hover. 44 | 45 | * **Type**: `Boolean` 46 | * **Default**: `true` 47 | 48 | ### centerMode 49 | 50 | Center images when the size is less than the container width 51 | 52 | * **Type**: `Boolean` 53 | * **Default**: `false` 54 | 55 | ### easing 56 | 57 | Transition speed between slides. Any valid CSS transition easing is accepted. 58 | 59 | * **Type**: `String` 60 | * **Default**: `ease` 61 | 62 | ### loop 63 | 64 | Flag to make the carousel loop (wrap) when it reaches either end. 65 | 66 | * **Type**: `Boolean` 67 | * **Default**: `false` 68 | 69 | ### minSwipeDistance 70 | 71 | Minimum distance in pixels to swipe before a slide advance is triggered. 72 | 73 | * **Type**: `Number` 74 | * **Default**: `8` 75 | 76 | ### mouseDrag 77 | 78 | Flag to toggle mouse dragging. 79 | 80 | * **Type**: `Boolean` 81 | * **Default** `true` 82 | 83 | ### perPage 84 | 85 | Maximum number of slides displayed on each page. 86 | 87 | * **Type**: `Number` 88 | * **Default**: `2` 89 | 90 | ### perPageCustom 91 | 92 | Configure the number of visible slides for responsive breakpoints. 93 | 94 | This will be an array of arrays. Each array is formatted as [x, y] where x is the browser width, and y is the number of slides displayed. 95 | 96 | * **Type**: `Array` 97 | * **Usage**: 98 | 99 | ``` html 100 | 101 | ``` 102 | 103 | A mobile-first strategy is used to determine the matching breakpoint. In the above example, the [perPage](/vue-carousel/api#perPage) variable has not been set, so the default of **2** is used. If the window size is greater than or equal to 768px, then 3 slides are shown. If the width is greater than or equal to 1024, then 4 slides are shown. 104 | 105 | ### resistanceCoef 106 | 107 | Resistance coefficient to dragging on the edge of the carousel. This dictates the effect of the pull as you move towards the boundaries. 108 | 109 | * **Type**: `Number` 110 | * **Default**: `20` 111 | 112 | ### scrollPerPage 113 | 114 | Scroll per page, not per item. 115 | 116 | * **Type**: `Boolean` 117 | * **Default**: `true` 118 | 119 | ### size 120 | 121 | Size of each pagination dot. Pixel values are accepted. 122 | 123 | * **Type** `Number` 124 | * **Default**: `10` 125 | 126 | ### spacePadding 127 | 128 | Stage padding option adds left and right padding style (in pixels) onto VueCarousel-inner. 129 | 130 | * **Type**: `Number` 131 | * **Default**: `0` 132 | 133 | ### spacePaddingMaxOffsetFactor 134 | 135 | Specify by how much should the space padding value be multiplied of, to re-arange the final slide padding. 136 | 137 | * **Type** `Number` 138 | * **Default**: `0` 139 | 140 | ### speed 141 | 142 | Slide transition speed. Number of milliseconds accepted. 143 | 144 | * **Type** `Number` 145 | * **Default**: `500` 146 | 147 | ### value 148 | 149 | Support for v-model functionality. 150 | Setting this value will change the current page to the number inputted (if between 0 and pageCount). 151 | 152 | * **Type** `Number` 153 | 154 | ## Navigation 155 | 156 | Configure the navigation component (next/prev buttons) 157 | 158 | ### navigationEnabled 159 | 160 | Flag to render the navigation component (next/prev buttons). 161 | 162 | * **Type**: `Boolean` 163 | * **Default**: `false` 164 | 165 | ### navigateTo 166 | 167 | Allow carousel parent to programatically navigate to a specific slide (zero based index). Recommend using parent data attribute pageNo and carousel pageChange event to keep pageNo in sync with carousel.currentPage to handle subsequent navigation. 168 | 169 | * **Type**: `Number` 170 | * **Default**: 0 171 | 172 | ### navigationClickTargetSize 173 | 174 | Amount of padding to apply around the label in pixels. 175 | 176 | * **Type**: `Number` 177 | * **Default**: `8` 178 | 179 | ### navigationNextLabel 180 | 181 | Text content of the navigation next button. 182 | 183 | * **Type**: `String` 184 | * **Default**: `▶` 185 | 186 | ### navigationPrevLabel 187 | 188 | Text content of the navigation prev button. 189 | 190 | * **Type**: `String` 191 | * **Default**: `◀` 192 | 193 | ### navigateTo 194 | 195 | Allow carousel parent to programatically navigate to a specific slide (zero based index). Recommend using parent data attribute pageNo and carousel pageChange event to keep pageNo in sync with carousel.currentPage to handle subsequent navigation. To disable the sliding animation the following syntax is to be followed- :navigateTo=[index, false] where index is the slide number (starts from zero) you want to navigate to. 196 | * **Type**: `Number` | `Array` 197 | * **Default**: 0 198 | 199 | ## Pagination 200 | 201 | Configure the pagination component (clickable page dots) 202 | 203 | ### paginationEnabled 204 | 205 | Flag to render pagination component. 206 | 207 | * **Type**: `Boolean` 208 | * **Default**: `true` 209 | 210 | ### paginationActiveColor 211 | 212 | The fill color of the active pagination dot. Any valid CSS color is accepted. 213 | 214 | * **Type**: `String` 215 | * **Default**: `#000000` 216 | 217 | ### paginationColor 218 | 219 | The fill color of pagination dots. Any valid CSS color is accepted. 220 | 221 | * **Type**: `String` 222 | * **Default**: `#efefef` 223 | 224 | ### paginationPosition 225 | 226 | The position of pagination dots. Possible values are `bottom`, `bottom-overlay`, `top` and `top-overlay`. The overlay values place the pagination component over the images. 227 | 228 | * **Type**: `String` 229 | * **Default**: `bottom` 230 | 231 | ### paginationPadding 232 | 233 | The padding inside each pagination dot. Pixel values are accepted. 234 | 235 | * **Type**: `Number` 236 | * **Default**: `10` 237 | 238 | ### paginationSize 239 | 240 | The size of each pagination dot. Pixel values are accepted. 241 | 242 | * **Type**: `Number` 243 | * **Default**: `10` 244 | 245 | ### spacePadding 246 | 247 | Stage padding option adds left and right padding style (in pixels) onto VueCarousel-inner. 248 | 249 | * **Type**: `Number` 250 | * **Default**: `0` 251 | 252 | ## Custom Pagination & Navigation 253 | 254 | Use named slots to render pagination and navigation using components. 255 | 256 | ``` html 257 | 258 | 259 | Slide 1 Content 260 | 261 | 262 | Slide 2 Content 263 | 264 | 265 | 266 | 267 | 268 | ``` 269 | 270 | Your components can access the `carousel` provider by adding the following to you component configuration: 271 | 272 | ``` 273 | name: "numbered-pagination", 274 | inject: ["carousel"] 275 | ``` 276 | 277 | ## Events 278 | 279 | Events emitted from components 280 | 281 | ### page-change 282 | 283 | `page-change` event emits the value of the current page. 284 | 285 | * **Type**: `Number` 286 | * **Emitter**: `Carousel` 287 | 288 | ### slide-click 289 | 290 | `slide-click` event throws the *dataset* object of the selected element. 291 | 292 | * **Type**: `Object` 293 | * **Emitter**: `Slide` 294 | 295 | ### transition-start 296 | 297 | `transition-start` event is thrown when the transition starts. 298 | 299 | * **Type**: `none` 300 | * **Emitter**: `Carousel` 301 | 302 | ### transition-end 303 | 304 | `transition-end` event is thrown when the transition end is reached. 305 | 306 | * **Type**: `none` 307 | * **Emitter**: `Carousel` 308 | 309 | > Lowercase versions of the above events are also emitted, namely—`pagechange`, `slideclick`, `transitionstart` and `transitionend`. 310 | 311 | 312 | ### navigation-click 313 | 314 | Emits when the a navigation button is clicked, with the current direction (`backward` or `forward`) 315 | 316 | * **Type**: `String` 317 | * **Emitter**: `Carousel` 318 | 319 | ### pagination-click 320 | 321 | Emits when a pagination button is clicked, with the current `pageNumber` 322 | 323 | * **Type**: `Number` 324 | * **Emitter**: `Carousel` 325 | 326 | > Lowercase versions of the above events are also emitted, namely—`pagechange`, `slideclick`, `transitionstart` and `transitionend`. 327 | -------------------------------------------------------------------------------- /docs/source/examples/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Examples 3 | --- 4 | 5 | ## Basic 6 | 7 | No options configured, 10 slides added to the carousel. 8 | 9 | 10 | 11 | ## Responsive 12 | 13 | Configured breakpoints: 2 slides on mobile (<= 480px), 3 slides on tablet (<= 768). 14 | **Note: in a JSFiddle iframe, the breakpoint is determined by the iframe's width.** 15 | 16 | 17 | 18 | ## Scroll per page 19 | 20 | Instead of scrolling on a per item basis, the carousel will scroll the configured [perPage](/vue-carousel/api#perPage) with each movement. 21 | 22 | 23 | 24 | ## Scroll per page (custom) 25 | 26 | Instead of scrolling on a per item basis, the carousel will scroll the configured by [perPageCustom](/vue-carousel/api#perPageCustom) with each movement. 27 | 28 | 29 | 30 | ## Autoplay 31 | 32 | The carousel will auto-advance slides unless the carousel is hovered upon. 33 | 34 | 35 | 36 | ## Autoplay infinite loop 37 | 38 | The carousel will auto-play and loop when reaching the end. 39 | 40 | 41 | 42 | ## Navigation 43 | 44 | Buttons added to advance the carousel in either direction. 45 | 46 | 47 | 48 | ## Customized 49 | 50 | Customized pagination dot colors and sizes. Customized speed and easing. 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/source/guide/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Guide 3 | --- 4 | 5 | ## Installation 6 | 7 | ``` bash 8 | npm install -S vue-carousel 9 | ``` 10 | 11 | ## Usage (Global) 12 | 13 | You may install Vue Carousel globally: 14 | 15 | ``` js 16 | import Vue from 'vue'; 17 | import VueCarousel from 'vue-carousel'; 18 | 19 | Vue.use(VueCarousel); 20 | ``` 21 | This will make **<carousel>** and **<slide>** available to all components within your Vue app. 22 | 23 | ## Usage (Local) 24 | 25 | Include the carousel directly into your component using import: 26 | 27 | ``` js 28 | import { Carousel, Slide } from 'vue-carousel'; 29 | 30 | export default { 31 | ... 32 | components: { 33 | Carousel, 34 | Slide 35 | } 36 | ... 37 | }; 38 | ``` 39 | 40 | ## HTML Structure 41 | 42 | Once the **Carousel** and **Slide** components are installed globally or imported, they can be used in templates in the following manner: 43 | 44 | ``` html 45 | 46 | 47 | Slide 1 Content 48 | 49 | 50 | Slide 2 Content 51 | 52 | 53 | ``` -------------------------------------------------------------------------------- /docs/themes/vue/_config.yml: -------------------------------------------------------------------------------- 1 | site_description: "Vue Carousel - A flexible, responsive, touch-friendly carousel for Vue.js" 2 | vue_version: 2.1.7 3 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/index.ejs: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |
9 |

10 | A flexible, responsive, touch-friendly
carousel for Vue.js 11 |

12 |

13 | GET STARTED 14 | GITHUB 15 |

16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 | 25 | 49 | 50 |
51 |
52 |
53 |

Flexible

54 |

Slides use Vue's built-in slot system, allowing you to display any type of content in slides (including other Vue components!)

55 |
56 | 57 |
58 |

Responsive

59 |

Breakpoints in Vue Carousel can be configured to have different slide counts depending on the device's display resolution.

60 |
61 | 62 |
63 |

Touch-friendly

64 |

65 | Touch and drag supported on both desktop and mobile devices. 66 |

67 |
68 |
69 |
70 | 71 |
72 |
73 |

SPONSORED BY

74 | <%- partial('partials/sponsors') %> 75 |
76 | We're Hiring! 77 | Contribute 78 |
79 |
80 | 81 | 85 | 86 | 98 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/layout.ejs: -------------------------------------------------------------------------------- 1 | <% var isIndex = page.path === 'index.html' %> 2 | 3 | 4 | 5 | <%- page.title ? page.title + ' - ' : '' %>Vue Carousel 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | <%- css(isIndex ? 'css/index' : 'css/page') %> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
> 35 | 36 | 37 |
38 | <%- partial('partials/header') %> 39 | <% if (!isIndex) { %> 40 |
41 | <% if (page.blog_index) { %> 42 | <%- partial('partials/blog') %> 43 | <% } else { %> 44 | <%- body %> 45 | <% } %> 46 |
47 | 48 | <% } else { %> 49 | <%- body %> 50 | <% } %> 51 | 52 | 53 | 54 | 55 | 56 | 65 | 66 | 67 | 68 | <%- css('css/search') %> 69 | 70 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/page.ejs: -------------------------------------------------------------------------------- 1 | <% if (page.type) { %> 2 | <%- partial('partials/sidebar', { type: page.type, index: page.index }) %> 3 | <% } else { %> 4 | 9 | <% } %> 10 |
11 | <% if (page.type) { %> 12 | <%- partial('partials/ad') %> 13 | <% } %> 14 | <% if (page.title.trim()) { %> 15 |

<%- page.title %><%- page.type === 'examples' ? ' Example' : '' %>

16 | <% } %> 17 | <%- page.content %> 18 | <% if (page.type === 'guide') { %> 19 | 27 | <% } %> 28 | 34 |
35 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/partials/header.ejs: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/partials/main_menu.ejs: -------------------------------------------------------------------------------- 1 |
  • Guide
  • 2 |
  • API
  • 3 |
  • Examples
  • 4 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/partials/sidebar.ejs: -------------------------------------------------------------------------------- 1 | 67 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/partials/sponsors.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/themes/vue/layout/post.ejs: -------------------------------------------------------------------------------- 1 | 21 |
    22 | <%- partial('partials/ad') %> 23 |

    <%- page.title %>

    24 |

    <%- page.date.format('MMM D[,] YYYY') %>

    25 | <%- page.content %> 26 |
    27 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_common.styl: -------------------------------------------------------------------------------- 1 | @import "_settings" 2 | @import "_syntax" 3 | 4 | body 5 | font-family $body-font 6 | font-size $body-font-size 7 | -webkit-font-smoothing antialiased 8 | -moz-osx-font-smoothing grayscale 9 | color $medium 10 | background-color white 11 | margin 0 12 | &.docs 13 | padding-top: $header-height 14 | 15 | @media screen and (max-width: 900px) 16 | body.docs 17 | padding-top: 0 18 | 19 | a 20 | text-decoration none 21 | color $medium 22 | 23 | img 24 | border none 25 | 26 | h1, h2, h3, h4, strong 27 | font-weight 600 28 | color $dark 29 | 30 | code, pre 31 | font-family $code-font 32 | font-size $code-font-size 33 | background-color $codebg 34 | -webkit-font-smoothing initial 35 | -moz-osx-font-smoothing initial 36 | 37 | code 38 | color #e96900 39 | padding 3px 5px 40 | margin 0 2px 41 | border-radius 2px 42 | white-space nowrap 43 | 44 | em 45 | color $light 46 | 47 | p 48 | word-spacing 0.05em 49 | 50 | a.button 51 | padding 0.75em 2em 52 | border-radius 2em 53 | display inline-block 54 | color #fff 55 | background-color lighten($green, 8%) 56 | transition all .15s ease 57 | box-sizing border-box 58 | border 1px solid lighten($green, 8%) 59 | &.white 60 | background-color #fff 61 | color $green 62 | 63 | .highlight 64 | overflow-x auto 65 | position relative 66 | padding 0 67 | background-color $codebg 68 | padding .8em .8em .4em 69 | line-height 1.1em 70 | border-radius $radius 71 | table, tr, td 72 | width 100% 73 | border-collapse collapse 74 | padding 0 75 | margin 0 76 | .gutter 77 | width 1.5em 78 | .code 79 | $code-line-height = 1.5em 80 | pre 81 | padding 1.2em 1.4em 82 | line-height $code-line-height 83 | margin 0 84 | .line 85 | min-height $code-line-height 86 | &.html, &.js, &.bash, &.css 87 | .code:after 88 | position absolute 89 | top 0 90 | right 0 91 | color #ccc 92 | text-align right 93 | font-size .75em 94 | padding 5px 10px 0 95 | line-height 15px 96 | height 15px 97 | font-weight 600 98 | &.html .code:after 99 | content 'HTML' 100 | &.js .code:after 101 | content 'JS' 102 | &.bash .code:after 103 | content 'Shell' 104 | &.css .code:after 105 | content 'CSS' 106 | 107 | #main 108 | position relative 109 | z-index 1 110 | padding 0 60px 30px 111 | overflow-x hidden 112 | 113 | #ad 114 | width 125px 115 | // text-align center 116 | position fixed 117 | z-index 99 118 | bottom 10px 119 | right 10px 120 | padding 10px 121 | background-color #fff 122 | border-radius 3px 123 | font-size 13px 124 | a 125 | display inline-block 126 | color $light 127 | font-weight normal 128 | span 129 | color $light 130 | display inline-block 131 | margin-bottom 5px 132 | img 133 | width 125px 134 | .carbon-img, .carbon-text 135 | display block 136 | margin-bottom 6px 137 | font-weight normal 138 | color $medium 139 | .carbon-poweredby 140 | color #aaa 141 | font-weight normal 142 | 143 | #nav 144 | .nav-link 145 | cursor pointer 146 | .nav-dropdown-container 147 | .nav-link 148 | &:hover 149 | border-bottom none 150 | &:hover 151 | .nav-dropdown 152 | display block 153 | &.language 154 | margin-left 20px 155 | .arrow 156 | pointer-events none 157 | .nav-dropdown 158 | display none 159 | box-sizing border-box 160 | max-height "calc(100vh - %s)" % $header-height 161 | overflow-y scroll 162 | position absolute 163 | top 100% 164 | right -15px 165 | background-color #fff 166 | padding 10px 0 167 | border 1px solid #ddd 168 | border-bottom-color #ccc 169 | text-align left 170 | border-radius 4px 171 | white-space nowrap 172 | li 173 | line-height 1.8em 174 | margin 0 175 | display block 176 | > ul 177 | padding-left: 0 178 | &:first-child 179 | h4 180 | margin-top 0 181 | padding-top: 0 182 | border-top: 0 183 | a, h4 184 | padding 0 24px 0 20px 185 | h4 186 | // text-transform uppercase 187 | margin .45em 0 0 188 | padding-top: .45em 189 | border-top: 1px solid #eee 190 | a 191 | color lighten($dark, 10%) 192 | font-size .9em 193 | display block 194 | &:hover 195 | color $green 196 | .arrow 197 | display inline-block 198 | vertical-align middle 199 | margin-top -1px 200 | margin-left 6px 201 | margin-right -14px 202 | width 0 203 | height 0 204 | border-left 4px solid transparent 205 | border-right 4px solid transparent 206 | border-top 5px solid #ccc 207 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_demo.styl: -------------------------------------------------------------------------------- 1 | #demo, .demo 2 | border 1px solid #eee 3 | border-radius $radius 4 | padding 25px 35px 5 | margin-top 1em 6 | margin-bottom 40px 7 | font-size 1.2em 8 | line-height 1.5em 9 | -webkit-user-select none 10 | -moz-user-select none 11 | -ms-user-select none 12 | user-select none 13 | overflow-x auto 14 | h1 15 | margin 0 0 .5em 16 | font-size 1.8em 17 | ul, ol 18 | padding-left 1.5em 19 | padding-bottom .2em !important 20 | &:first-child 21 | margin-top 0 22 | &:last-child 23 | margin-bottom 0 24 | li 25 | color $medium 26 | // !!TODO: Check to make sure this isn't here for a good reason. 27 | // cursor pointer 28 | // -ms-user-select none 29 | // -moz-user-select none 30 | // -webkit-user-select none 31 | &.done 32 | color $light 33 | text-decoration line-through 34 | p 35 | margin 0 !important 36 | padding 0 !important 37 | &:first-child 38 | margin-top 0 39 | &:last-child 40 | margin-bottom 0 41 | textarea 42 | width 100% 43 | resize vertical 44 | 45 | 46 | 47 | ul#demo, ul.demo 48 | li 49 | margin-left 1.5em 50 | 51 | @media screen and (max-width: 900px) 52 | #demo, .demo 53 | margin-left 0 54 | 55 | .benchmark-table 56 | margin: 0 auto 57 | text-align center 58 | 59 | tbody > tr > th 60 | text-align right 61 | 62 | th, td 63 | padding: 3px 7px 64 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_header.styl: -------------------------------------------------------------------------------- 1 | $header-height = 40px 2 | 3 | #header 4 | background-color #fff 5 | height: $heading-inner-height 6 | padding $heading-padding-vertical 60px 7 | position relative 8 | z-index 2 9 | 10 | body.docs 11 | #header 12 | position fixed 13 | width 100% 14 | top 0 15 | #nav 16 | position fixed 17 | 18 | #nav 19 | list-style-type none 20 | margin 0 21 | padding 0 22 | position absolute 23 | right 60px 24 | top $heading-padding-vertical 25 | height $header-height 26 | line-height $header-height 27 | .break 28 | display none 29 | li 30 | display inline-block 31 | position relative 32 | margin 0 .6em 33 | 34 | .nav-link 35 | padding-bottom 3px 36 | &:hover, &.current 37 | border-bottom 3px solid $green 38 | 39 | .search-query 40 | height 30px 41 | line-height 30px 42 | box-sizing border-box 43 | padding 0 15px 0 30px 44 | border 1px solid #e3e3e3 45 | color $dark 46 | outline none 47 | border-radius 15px 48 | margin-right 10px 49 | transition border-color .2s ease 50 | background #fff url(/images/search.png) 8px 5px no-repeat 51 | background-size 20px 52 | vertical-align middle !important 53 | &:focus 54 | border-color $green 55 | 56 | #logo 57 | display inline-block 58 | font-size 1.5em 59 | line-height $header-height 60 | color $dark 61 | font-family $logo-font 62 | font-weight 500 63 | img 64 | vertical-align middle 65 | margin-right 6px 66 | width $header-height 67 | height $header-height 68 | 69 | #mobile-bar 70 | position fixed 71 | top 0 72 | left 0 73 | width 100% 74 | height 40px 75 | background-color #fff 76 | z-index 9 77 | display none 78 | box-shadow 0 0 2px rgba(0,0,0,.25) 79 | .menu-button 80 | position absolute 81 | width 24px 82 | height 24px 83 | top 8px 84 | left 12px 85 | background url(../images/menu.png) center center no-repeat 86 | background-size 24px 87 | .logo 88 | position absolute 89 | width 30px 90 | height 30px 91 | background url(../images/logo.png) center center no-repeat 92 | top 5px 93 | left 50% 94 | margin-left -15px 95 | background-size 30px 96 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_migration.styl: -------------------------------------------------------------------------------- 1 | .content.guide[class*="migration"] 2 | h2, h3 3 | > sup 4 | margin-left: .3em 5 | color: #b9465c 6 | .upgrade-path 7 | padding: 2em 8 | background: rgba(73, 195, 140, .1) 9 | border-radius: 2px 10 | > h4 11 | margin-top: 0 12 | > p:last-child 13 | margin-bottom: 0 14 | 15 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_settings.styl: -------------------------------------------------------------------------------- 1 | // font faces 2 | $body-font = 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif 3 | $logo-font = 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif 4 | $code-font = 'Roboto Mono', Monaco, courier, monospace 5 | 6 | // font sizes 7 | $body-font-size = 15px 8 | $code-font-size = .8em 9 | 10 | // colors 11 | $dark = #2c3e50 12 | $medium = #34495e 13 | $light = #7f8c8d 14 | $green = #42b983 15 | $border = #dddddd 16 | $codebg = #f8f8f8 17 | $red = #ff6666 18 | 19 | $radius = 2px 20 | $content-padding-top = 30px 21 | $header-inner-height = 41px 22 | $heading-padding-vertical = 10px 23 | $header-height = $header-inner-height + $heading-padding-vertical * 2 24 | $mobile-header-height = 40px 25 | $heading-link-padding-top = $header-height + $content-padding-top 26 | $mobile-heading-link-padding-top = $mobile-header-height + $content-padding-top 27 | $h2-margin-top = 45px 28 | $h3-margin-top = 52px 29 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_sidebar.styl: -------------------------------------------------------------------------------- 1 | @import "_settings" 2 | 3 | .sidebar 4 | position absolute 5 | z-index 10 6 | top $header-height 7 | left 0 8 | bottom 0 9 | padding $content-padding-top + 10px 0 $content-padding-top 60px 10 | width 260px 11 | margin-right 20px 12 | overflow-x hidden 13 | overflow-y auto 14 | -webkit-overflow-scrolling touch 15 | -ms-overflow-style none 16 | h2 17 | margin-top .2em 18 | ul 19 | list-style-type none 20 | margin 0 21 | line-height 1.8em 22 | padding-left 1em 23 | .version-select 24 | vertical-align middle 25 | margin-left 5px 26 | .menu-root 27 | padding-left 0 28 | .menu-sub 29 | font-size .85em 30 | .sidebar-link 31 | color $light 32 | &.current 33 | font-weight 600 34 | color $green 35 | &.new 36 | &:after 37 | content "NEW" 38 | display inline-block 39 | font-size 10px 40 | font-weight 600 41 | color #fff 42 | background-color $green 43 | line-height 14px 44 | padding 0 4px 45 | border-radius 3px 46 | margin-left 5px 47 | vertical-align middle 48 | position relative 49 | top -1px 50 | &:hover 51 | border-bottom 2px solid $green 52 | .section-link 53 | &.active 54 | font-weight bold 55 | color $green 56 | .main-menu 57 | margin-bottom 20px 58 | display none 59 | padding-left 0 60 | .main-sponsor 61 | color $light 62 | font-size .85em 63 | a 64 | margin 10px 0 65 | img, a 66 | width 125px 67 | display inline-block 68 | .become-backer 69 | border 1px solid $green 70 | border-radius 2em 71 | display inline-block 72 | color $green 73 | font-size .8em 74 | width 125px 75 | padding 4px 0 76 | text-align center 77 | margin-bottom 20px 78 | .nav-dropdown 79 | h4 80 | font-weight normal 81 | margin: 0 82 | 83 | @media screen and (max-width: 900px) 84 | .sidebar 85 | position fixed 86 | z-index 8 87 | background-color #f9f9f9 88 | height 100% 89 | top 0 90 | left 0 91 | padding 60px 30px 20px 92 | box-shadow 0 0 10px rgba(0,0,0,.2) 93 | box-sizing border-box 94 | transition all .4s cubic-bezier(0.4, 0, 0, 1) 95 | -webkit-transform translate(-280px, 0) 96 | transform translate(-280px, 0) 97 | .search-query 98 | width 200px 99 | margin-bottom 10px 100 | .main-menu 101 | display block 102 | &.open 103 | -webkit-transform translate(0, 0) 104 | transform translate(0, 0) 105 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_sponsor.styl: -------------------------------------------------------------------------------- 1 | .sponsors-page 2 | a, img 3 | width 120px 4 | display inline-block 5 | vertical-align middle 6 | a 7 | margin 10px 20px 8 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/_syntax.styl: -------------------------------------------------------------------------------- 1 | .gutter pre 2 | color: #999 3 | line-height: 1.5em 4 | 5 | pre 6 | color: #525252 7 | .function .keyword, 8 | .constant 9 | color: #0092db 10 | .keyword, 11 | .attribute 12 | color: #e96900 13 | .number, 14 | .literal 15 | color: #AE81FF 16 | .tag, 17 | .tag .title, 18 | .change, 19 | .winutils, 20 | .flow, 21 | .lisp .title, 22 | .clojure .built_in, 23 | .nginx .title, 24 | .tex .special 25 | color: #2973b7 26 | .class .title 27 | color: white 28 | .symbol, 29 | .symbol .string, 30 | .value, 31 | .regexp 32 | color: $green 33 | .title 34 | color: #A6E22E 35 | .tag .value, 36 | .string, 37 | .subst, 38 | .haskell .type, 39 | .preprocessor, 40 | .ruby .class .parent, 41 | .built_in, 42 | .sql .aggregate, 43 | .django .template_tag, 44 | .django .variable, 45 | .smalltalk .class, 46 | .javadoc, 47 | .django .filter .argument, 48 | .smalltalk .localvars, 49 | .smalltalk .array, 50 | .attr_selector, 51 | .pseudo, 52 | .addition, 53 | .stream, 54 | .envvar, 55 | .apache .tag, 56 | .apache .cbracket, 57 | .tex .command, 58 | .prompt 59 | color: $green 60 | .comment, 61 | .java .annotation, 62 | .python .decorator, 63 | .template_comment, 64 | .pi, 65 | .doctype, 66 | .deletion, 67 | .shebang, 68 | .apache .sqbracket, 69 | .tex .formula 70 | color: #b3b3b3 71 | .coffeescript .javascript, 72 | .javascript .xml, 73 | .tex .formula, 74 | .xml .javascript, 75 | .xml .vbscript, 76 | .xml .css, 77 | .xml .cdata 78 | opacity: 0.5 79 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/benchmark.styl: -------------------------------------------------------------------------------- 1 | #benchmark-results 2 | margin-bottom 2em 3 | ul 4 | list-style-type none 5 | padding 0 6 | margin-left 0 7 | 8 | .framework, .time, .bar, .inner 9 | display inline-block 10 | 11 | .framework 12 | width 4.2em 13 | //text-align right 14 | margin-right 1em 15 | font-weight 600 16 | 17 | .time 18 | width 4.2em 19 | margin-right 1em 20 | 21 | .bar 22 | width 60% 23 | &.min .inner 24 | background-color #e74c3c 25 | 26 | .inner 27 | height 3px 28 | vertical-align middle 29 | background-color #3498db 30 | 31 | @media screen and (max-width: 600px) 32 | #benchmark-results 33 | .bar 34 | width 45% -------------------------------------------------------------------------------- /docs/themes/vue/source/css/index.styl: -------------------------------------------------------------------------------- 1 | @import "_common" 2 | @import "_header" 3 | @import '_sidebar' 4 | 5 | $width = 900px 6 | $space = 50px 7 | 8 | body 9 | background-color darken($light, 10%) 10 | 11 | .sidebar 12 | display none 13 | 14 | .slide 15 | padding 0 12px 16 | box-sizing border-box 17 | img 18 | width 100% 19 | 20 | #mobile-bar 21 | &.top 22 | background-color transparent 23 | box-shadow none 24 | .logo 25 | display none 26 | 27 | #hero 28 | padding $space 40px 29 | background-color #fff 30 | text-align center 31 | .inner 32 | max-width $width 33 | margin 0 auto 34 | .left, .right 35 | display inline-block 36 | vertical-align top 37 | .left 38 | width 39% 39 | .right 40 | width 61% 41 | .hero-logo 42 | width 215px 43 | height 215px 44 | float right 45 | margin-right 60px 46 | h1 47 | font-weight 300 48 | margin 0 49 | font-size 3.2em 50 | h2 51 | font-family $logo-font 52 | font-weight 500 53 | font-size 2.4em 54 | margin 0 0 10px 55 | display none 56 | .button 57 | margin 1em 0 58 | font-size 1.05em 59 | font-weight 600 60 | letter-spacing .1em 61 | &:first-child 62 | margin-right 1em 63 | .social-buttons 64 | list-style-type none 65 | padding 0 66 | li 67 | display inline-block 68 | vertical-align middle 69 | margin-right 15px 70 | 71 | #highlights 72 | background-color #fff 73 | padding-bottom 70px 74 | .inner 75 | max-width $width 76 | margin 0 auto 77 | text-align center 78 | .point 79 | width 33% 80 | display inline-block 81 | vertical-align top 82 | box-sizing border-box 83 | padding 0 2em 84 | h2 85 | color $green 86 | font-size 1.5em 87 | font-weight 400 88 | margin 0 89 | padding .5em 0 90 | p 91 | color $light 92 | 93 | #sponsors 94 | text-align center 95 | padding 35px 40px 45px 96 | background-color #f6f6f6 97 | .inner 98 | max-width 700px 99 | margin 0px auto 100 | h3 101 | color #999 102 | font-size .9em 103 | margin 0 0 10px 104 | a 105 | margin 20px 15px 0 106 | position relative 107 | a, img 108 | width 100px 109 | display inline-block 110 | vertical-align middle 111 | img 112 | transition all .3s ease 113 | filter contrast(0%) 114 | &:hover 115 | filter none 116 | a.vip 117 | display block 118 | margin 30px auto 15px 119 | width 200px 120 | img 121 | width 200px 122 | .become-sponsor 123 | margin-top 40px 124 | font-size .9em 125 | font-weight 700 126 | width auto 127 | background-color transparent 128 | 129 | #footer 130 | padding $space 0 131 | color #fff 132 | text-align center 133 | a 134 | font-weight 700 135 | color #fff 136 | 137 | @media screen and (max-width: $width) 138 | body 139 | -webkit-text-size-adjust none 140 | font-size 14px 141 | .sidebar 142 | display block 143 | #header 144 | display none 145 | #mobile-bar 146 | display block 147 | #hero 148 | padding $space 40px 30px 149 | .hero-logo 150 | float none 151 | margin 30px 0 15px 152 | width 140px 153 | height 140px 154 | .left, .right 155 | text-align center 156 | width 100% 157 | h1 158 | font-size 2em 159 | h2 160 | display block 161 | .button 162 | font-size .9em 163 | #highlights 164 | .point 165 | display block 166 | margin 0 auto 167 | width 300px 168 | padding 0 40px 30px 169 | &:before 170 | content "—" 171 | color $green 172 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/page.styl: -------------------------------------------------------------------------------- 1 | @import "_common" 2 | @import "_header" 3 | @import "_demo" 4 | @import "_sponsor" 5 | @import "_migration" 6 | @import "_sidebar" 7 | 8 | #header 9 | box-shadow 0 0 1px rgba(0,0,0,.25) 10 | transition background-color .3s ease-in-out 11 | 12 | .content 13 | position relative 14 | padding 2.2em 0 15 | max-width 600px 16 | margin 0 auto 17 | &.api 18 | > a:first-of-type > h2 19 | margin-top 0 20 | padding-top: 0 21 | ul 22 | padding-left 1.25em 23 | line-height 1.4em 24 | ul, p 25 | margin .6em 0 26 | a.button 27 | font-size .9em 28 | color #fff 29 | margin .2em 0 30 | width 180px 31 | text-align center 32 | padding 12px 24px 33 | display inline-block 34 | vertical-align middle 35 | img 36 | max-width 100% 37 | span.light 38 | color $light 39 | span.info 40 | font-size .85em 41 | display inline-block 42 | vertical-align middle 43 | width 280px 44 | margin-left 20px 45 | h1 46 | margin 0 0 1em 47 | h2, h3 48 | &:before 49 | content '' 50 | display block 51 | margin-top -1 * $heading-link-padding-top 52 | height $heading-link-padding-top 53 | visibility hidden 54 | h2 55 | margin $h2-margin-top 0 .8em 56 | padding-bottom .7em 57 | border-bottom 1px solid $border 58 | z-index: -1 59 | h3 60 | margin $h3-margin-top 0 1.2em 61 | position relative 62 | z-index: -1 63 | &:after 64 | content "#" 65 | color $green 66 | position absolute 67 | left -0.7em 68 | bottom -2px 69 | font-size 1.2em 70 | font-weight bold 71 | figure 72 | margin 1.2em 0 73 | p, ul, ol 74 | line-height 1.6em 75 | // HACK: Create area underneath paragraphs 76 | // and lists that will be on top of heading 77 | // anchors, for easier text highlighting. 78 | margin 1.2em 0 -1.2em 79 | padding-bottom 1.2em 80 | position relative 81 | z-index: 1 82 | ul, ol 83 | padding-left 1.5em 84 | a 85 | color $green 86 | font-weight 600 87 | blockquote 88 | margin 2em 0 89 | padding-left 20px 90 | border-left 4px solid $green 91 | p 92 | font-weight 600 93 | margin-left 0 94 | iframe 95 | margin 1em 0 96 | > table 97 | border 2px solid $white 98 | margin 1.2em auto 99 | padding: 1em 100 | td, th 101 | line-height 1.6em 102 | padding .5em 1.4em 103 | border none 104 | td 105 | background-color: lighten($codebg, 60%) 106 | th 107 | background-color: $green 108 | color: #fff 109 | padding-top: .85em 110 | padding-bottom .85em 111 | text-align left 112 | tbody 113 | code 114 | background-color #efefef 115 | p.tip 116 | padding 12px 24px 12px 30px 117 | margin 2em 0 118 | border-left 4px solid $red 119 | background-color $codebg 120 | position relative 121 | border-bottom-right-radius $radius 122 | border-top-right-radius $radius 123 | 124 | &:before 125 | position absolute 126 | top 14px 127 | left -12px 128 | background-color $red 129 | color #fff 130 | content "!" 131 | width 20px 132 | height 20px 133 | border-radius 100% 134 | text-align center 135 | line-height 20px 136 | font-weight bold 137 | font-family $logo-font 138 | font-size 14px 139 | 140 | code 141 | background-color #efefef 142 | 143 | em 144 | color $medium 145 | 146 | .guide-links 147 | margin-top 2em 148 | height 1em 149 | 150 | .footer 151 | color $light 152 | margin-top 2em 153 | padding-top 2em 154 | border-top 1px solid #e5e5e5 155 | font-size .9em 156 | 157 | #main.fix-sidebar 158 | .sidebar 159 | position fixed 160 | 161 | @media screen and (min-width: 1590px) 162 | #header 163 | background-color rgba(255,255,255,.4) 164 | 165 | @media screen and (max-width: 1300px) 166 | .content.with-sidebar 167 | margin-left 290px 168 | #ad 169 | z-index 7 170 | position relative 171 | padding 0 172 | bottom 0 173 | right 0 174 | float right 175 | padding 0 0 20px 30px 176 | 177 | @media screen and (max-width: 900px) 178 | body 179 | -webkit-text-size-adjust none 180 | font-size 14px 181 | #header 182 | display none 183 | #logo 184 | display none 185 | .nav-link 186 | padding-bottom 1px 187 | &:hover, &.current 188 | border-bottom 2px solid $green 189 | #mobile-bar 190 | display block 191 | #main 192 | padding 2em 1.4em 0 193 | .highlight pre 194 | padding 1.2em 1em 195 | .content 196 | &.with-sidebar 197 | margin auto 198 | h2, h3 199 | &:before 200 | content '' 201 | display block 202 | margin-top -1 * $mobile-heading-link-padding-top 203 | height $mobile-heading-link-padding-top 204 | visibility hidden 205 | .footer 206 | margin-left 0 207 | text-align center 208 | 209 | @media screen and (max-width: 560px) 210 | #downloads 211 | text-align center 212 | margin-bottom 25px 213 | .info 214 | margin-top 5px 215 | margin-left 0 216 | iframe 217 | margin: 0 !important 218 | -------------------------------------------------------------------------------- /docs/themes/vue/source/css/search.styl: -------------------------------------------------------------------------------- 1 | @import '_settings' 2 | 3 | $border = #ddd 4 | 5 | .algolia-autocomplete 6 | line-height normal 7 | 8 | .aa-dropdown-menu 9 | width 100% 10 | border-color #999 11 | font-size 0.9rem 12 | 13 | @media (min-width: 768px) 14 | .aa-dropdown-menu 15 | min-width: 515px 16 | 17 | .algolia-docsearch-suggestion 18 | border-color $border 19 | 20 | .algolia-docsearch-suggestion--content 21 | color $dark 22 | 23 | .algolia-docsearch-suggestion--subcategory-column 24 | border-color $border 25 | 26 | .algolia-docsearch-suggestion--category-header 27 | background: $green 28 | 29 | .algolia-docsearch-footer 30 | border-color $border 31 | 32 | .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight 33 | background rgba(255, 255, 255, 0.6) 34 | 35 | .algolia-docsearch-suggestion--highlight 36 | color: #2c815b 37 | 38 | .aa-cursor .algolia-docsearch-suggestion--content 39 | color: $dark 40 | -------------------------------------------------------------------------------- /docs/themes/vue/source/images/2mhost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/2mhost.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/actualize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/actualize.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/chaitin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/chaitin.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/check.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/down.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/feed.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/htmlburger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/htmlburger.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/icons.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/itunescn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/itunescn.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/jsfiddle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/jsfiddle.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/juejin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/juejin.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/laravel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/laravel.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/logo.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/menu.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/monterail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/monterail.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/patreon.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/paypal.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/search.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/someline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/someline.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/strikingly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/strikingly.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/tde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/tde.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/transition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/transition.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/trisoft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/trisoft.png -------------------------------------------------------------------------------- /docs/themes/vue/source/images/vuejobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/docs/themes/vue/source/images/vuejobs.png -------------------------------------------------------------------------------- /docs/themes/vue/source/js/common.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | initMobileMenu() 4 | if (PAGE_TYPE) { 5 | initVersionSelect() 6 | initSubHeaders() 7 | initApiSpecLinks() 8 | initLocationHashFuzzyMatching() 9 | } 10 | 11 | function initApiSpecLinks () { 12 | var apiContent = document.querySelector('.content.api') 13 | if (apiContent) { 14 | var apiTitles = [].slice.call(apiContent.querySelectorAll('h3')) 15 | apiTitles.forEach(function (titleNode) { 16 | var ulNode = titleNode.parentNode.nextSibling 17 | if (ulNode.tagName !== 'UL') { 18 | ulNode = ulNode.nextSibling 19 | } 20 | if (ulNode.tagName === 'UL') { 21 | var specNode = document.createElement('li') 22 | var specLink = createSourceSearchPath(titleNode.textContent) 23 | specNode.innerHTML = 'Source' 24 | ulNode.appendChild(specNode) 25 | } 26 | }) 27 | } 28 | 29 | function createSourceSearchPath(query) { 30 | return 'https://github.com/search?utf8=%E2%9C%93&q=repo%3Avuejs%2Fvue+extension%3Ajs+' + encodeURIComponent(query) + '+&type=Code' 31 | } 32 | } 33 | 34 | function initLocationHashFuzzyMatching () { 35 | var hash = window.location.hash 36 | if (!hash) return 37 | var hashTarget = document.getElementById(hash) 38 | if (!hashTarget) { 39 | var normalizedHash = normalizeHash(hash) 40 | var possibleHashes = [].slice.call(document.querySelectorAll('[id]')) 41 | .map(function (el) { return el.id }) 42 | possibleHashes.sort(function (hashA, hashB) { 43 | var distanceA = levenshteinDistance(normalizedHash, normalizeHash(hashA)) 44 | var distanceB = levenshteinDistance(normalizedHash, normalizeHash(hashB)) 45 | if (distanceA < distanceB) return -1 46 | if (distanceA > distanceB) return 1 47 | return 0 48 | }) 49 | window.location.hash = possibleHashes[0] 50 | } 51 | 52 | function normalizeHash (rawHash) { 53 | return rawHash 54 | .toLowerCase() 55 | .replace(/\-(?:deprecated|removed|replaced|changed|obsolete)$/, '') 56 | } 57 | 58 | function levenshteinDistance (a, b) { 59 | var m = [] 60 | if (!(a && b)) return (b || a).length 61 | for (var i = 0; i <= b.length; m[i] = [i++]) {} 62 | for (var j = 0; j <= a.length; m[0][j] = j++) {} 63 | for (var i = 1; i <= b.length; i++) { 64 | for (var j = 1; j <= a.length; j++) { 65 | m[i][j] = b.charAt(i - 1) === a.charAt(j - 1) 66 | ? m[i - 1][j - 1] 67 | : m[i][j] = Math.min( 68 | m[i - 1][j - 1] + 1, 69 | Math.min(m[i][j - 1] + 1, m[i - 1][j] + 1)) 70 | } 71 | } 72 | return m[b.length][a.length] 73 | } 74 | } 75 | 76 | /** 77 | * Mobile burger menu button for toggling sidebar 78 | */ 79 | 80 | function initMobileMenu () { 81 | var mobileBar = document.getElementById('mobile-bar') 82 | var sidebar = document.querySelector('.sidebar') 83 | var menuButton = mobileBar.querySelector('.menu-button') 84 | 85 | menuButton.addEventListener('click', function () { 86 | sidebar.classList.toggle('open') 87 | }) 88 | 89 | document.body.addEventListener('click', function (e) { 90 | if (e.target !== menuButton && !sidebar.contains(e.target)) { 91 | sidebar.classList.remove('open') 92 | } 93 | }) 94 | } 95 | 96 | /** 97 | * Doc version select 98 | */ 99 | 100 | function initVersionSelect () { 101 | // version select 102 | var versionSelect = document.querySelector('.version-select') 103 | versionSelect && versionSelect.addEventListener('change', function (e) { 104 | var version = e.target.value 105 | var section = window.location.pathname.match(/\/v\d\/(\w+?)\//)[1] 106 | if (version === 'SELF') return 107 | window.location.assign( 108 | 'http://' + 109 | version + 110 | (version && '.') + 111 | 'vuejs.org/' + section + '/' 112 | ) 113 | }) 114 | } 115 | 116 | /** 117 | * Sub headers in sidebar 118 | */ 119 | 120 | function initSubHeaders () { 121 | var each = [].forEach 122 | var main = document.getElementById('main') 123 | var header = document.getElementById('header') 124 | var sidebar = document.querySelector('.sidebar') 125 | var content = document.querySelector('.content') 126 | 127 | // build sidebar 128 | var currentPageAnchor = sidebar.querySelector('.sidebar-link.current') 129 | var isAPI = document.querySelector('.content').classList.contains('api') 130 | if (currentPageAnchor || isAPI) { 131 | var allHeaders = [] 132 | var sectionContainer 133 | if (isAPI) { 134 | sectionContainer = document.querySelector('.menu-root') 135 | } else { 136 | sectionContainer = document.createElement('ul') 137 | sectionContainer.className = 'menu-sub' 138 | currentPageAnchor.parentNode.appendChild(sectionContainer) 139 | } 140 | var headers = content.querySelectorAll('h2') 141 | if (headers.length) { 142 | each.call(headers, function (h) { 143 | sectionContainer.appendChild(makeLink(h)) 144 | var h3s = collectH3s(h) 145 | allHeaders.push(h) 146 | allHeaders.push.apply(allHeaders, h3s) 147 | if (h3s.length) { 148 | sectionContainer.appendChild(makeSubLinks(h3s, isAPI)) 149 | } 150 | }) 151 | } else { 152 | headers = content.querySelectorAll('h3') 153 | each.call(headers, function (h) { 154 | sectionContainer.appendChild(makeLink(h)) 155 | allHeaders.push(h) 156 | }) 157 | } 158 | 159 | var animating = false 160 | sectionContainer.addEventListener('click', function (e) { 161 | e.preventDefault() 162 | if (e.target.classList.contains('section-link')) { 163 | sidebar.classList.remove('open') 164 | setActive(e.target) 165 | animating = true 166 | setTimeout(function () { 167 | animating = false 168 | }, 400) 169 | } 170 | }, true) 171 | 172 | // make links clickable 173 | allHeaders.forEach(makeHeaderClickable) 174 | 175 | smoothScroll.init({ 176 | speed: 400, 177 | offset: 0 178 | }) 179 | } 180 | 181 | var hoveredOverSidebar = false 182 | sidebar.addEventListener('mouseover', function () { 183 | hoveredOverSidebar = true 184 | }) 185 | sidebar.addEventListener('mouseleave', function () { 186 | hoveredOverSidebar = false 187 | }) 188 | 189 | // listen for scroll event to do positioning & highlights 190 | window.addEventListener('scroll', updateSidebar) 191 | window.addEventListener('resize', updateSidebar) 192 | 193 | function updateSidebar () { 194 | var doc = document.documentElement 195 | var top = doc && doc.scrollTop || document.body.scrollTop 196 | if (animating || !allHeaders) return 197 | var last 198 | for (var i = 0; i < allHeaders.length; i++) { 199 | var link = allHeaders[i] 200 | if (link.offsetTop > top) { 201 | if (!last) last = link 202 | break 203 | } else { 204 | last = link 205 | } 206 | } 207 | if (last) 208 | setActive(last.id, !hoveredOverSidebar) 209 | } 210 | 211 | function makeLink (h) { 212 | var link = document.createElement('li') 213 | var text = h.textContent.replace(/\(.*\)$/, '') 214 | link.innerHTML = 215 | '' + 216 | htmlEscape(text) + 217 | '' 218 | return link 219 | } 220 | 221 | function htmlEscape (text) { 222 | return text 223 | .replace(/&/g, '&') 224 | .replace(/"/g, '"') 225 | .replace(/'/g, ''') 226 | .replace(//g, '>') 228 | } 229 | 230 | function collectH3s (h) { 231 | var h3s = [] 232 | var next = h.nextSibling 233 | while (next && next.tagName !== 'H2') { 234 | if (next.tagName === 'H3') { 235 | h3s.push(next) 236 | } 237 | next = next.nextSibling 238 | } 239 | return h3s 240 | } 241 | 242 | function makeSubLinks (h3s, small) { 243 | var container = document.createElement('ul') 244 | if (small) { 245 | container.className = 'menu-sub' 246 | } 247 | h3s.forEach(function (h) { 248 | container.appendChild(makeLink(h)) 249 | }) 250 | return container 251 | } 252 | 253 | function setActive (id, shouldScrollIntoView) { 254 | var previousActive = sidebar.querySelector('.section-link.active') 255 | var currentActive = typeof id === 'string' 256 | ? sidebar.querySelector('.section-link[href="#' + id + '"]') 257 | : id 258 | if (currentActive !== previousActive) { 259 | if (previousActive) previousActive.classList.remove('active') 260 | currentActive.classList.add('active') 261 | if (shouldScrollIntoView) { 262 | var currentPageOffset = currentPageAnchor 263 | ? currentPageAnchor.offsetTop - 8 264 | : 0 265 | var currentActiveOffset = currentActive.offsetTop + currentActive.parentNode.clientHeight 266 | var sidebarHeight = sidebar.clientHeight 267 | var currentActiveIsInView = ( 268 | currentActive.offsetTop >= sidebar.scrollTop && 269 | currentActiveOffset <= sidebar.scrollTop + sidebarHeight 270 | ) 271 | var linkNotFurtherThanSidebarHeight = currentActiveOffset - currentPageOffset < sidebarHeight 272 | var newScrollTop = currentActiveIsInView 273 | ? sidebar.scrollTop 274 | : linkNotFurtherThanSidebarHeight 275 | ? currentPageOffset 276 | : currentActiveOffset - sidebarHeight 277 | sidebar.scrollTop = newScrollTop 278 | } 279 | } 280 | } 281 | 282 | function makeHeaderClickable (link) { 283 | var wrapper = document.createElement('a') 284 | wrapper.href = '#' + link.id 285 | wrapper.setAttribute('data-scroll', '') 286 | link.parentNode.insertBefore(wrapper, link) 287 | wrapper.appendChild(link) 288 | } 289 | } 290 | })() 291 | -------------------------------------------------------------------------------- /docs/themes/vue/source/js/smooth-scroll.min.js: -------------------------------------------------------------------------------- 1 | /** smooth-scroll v5.1.2, by Chris Ferdinandi | http://github.com/cferdinandi/smooth-scroll | Licensed under MIT: http://gomakethings.com/mit/ */ 2 | !function(t,e){"function"==typeof define&&define.amd?define("smoothScroll",e(t)):"object"==typeof exports?module.exports=e(t):t.smoothScroll=e(t)}(this,function(t){"use strict";var e,n={},o=!!document.querySelector&&!!t.addEventListener,r={speed:500,easing:"easeInOutCubic",offset:0,updateURL:!0,callbackBefore:function(){},callbackAfter:function(){}},a=function(t,e,n){if("[object Object]"===Object.prototype.toString.call(t))for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.call(n,t[o],o,t);else for(var r=0,a=t.length;a>r;r++)e.call(n,t[r],r,t)},c=function(t,e){var n={};return a(t,function(e,o){n[o]=t[o]}),a(e,function(t,o){n[o]=e[o]}),n},u=function(t,e){for(var n=e.charAt(0);t&&t!==document;t=t.parentNode)if("."===n){if(t.classList.contains(e.substr(1)))return t}else if("#"===n){if(t.id===e.substr(1))return t}else if("["===n&&t.hasAttribute(e.substr(1,e.length-2)))return t;return!1},i=function(t){for(var e,n=String(t),o=n.length,r=-1,a="",c=n.charCodeAt(0);++r=1&&31>=e||127==e||0===r&&e>=48&&57>=e||1===r&&e>=48&&57>=e&&45===c?"\\"+e.toString(16)+" ":e>=128||45===e||95===e||e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e?n.charAt(r):"\\"+n.charAt(r)}return a},s=function(t,e){var n;return"easeInQuad"===t&&(n=e*e),"easeOutQuad"===t&&(n=e*(2-e)),"easeInOutQuad"===t&&(n=.5>e?2*e*e:-1+(4-2*e)*e),"easeInCubic"===t&&(n=e*e*e),"easeOutCubic"===t&&(n=--e*e*e+1),"easeInOutCubic"===t&&(n=.5>e?4*e*e*e:(e-1)*(2*e-2)*(2*e-2)+1),"easeInQuart"===t&&(n=e*e*e*e),"easeOutQuart"===t&&(n=1- --e*e*e*e),"easeInOutQuart"===t&&(n=.5>e?8*e*e*e*e:1-8*--e*e*e*e),"easeInQuint"===t&&(n=e*e*e*e*e),"easeOutQuint"===t&&(n=1+--e*e*e*e*e),"easeInOutQuint"===t&&(n=.5>e?16*e*e*e*e*e:1+16*--e*e*e*e*e),n||e},f=function(t,e,n){var o=0;if(t.offsetParent)do o+=t.offsetTop,t=t.offsetParent;while(t);return o=o-e-n,o>=0?o:0},l=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},d=function(t){return t&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(t):{}},h=function(t,e){history.pushState&&(e||"true"===e)&&history.pushState({pos:t.id},"",window.location.pathname+t)};n.animateScroll=function(e,n,o){var a=c(a||r,o||{}),u=d(e?e.getAttribute("data-options"):null);a=c(a,u),n="#"+i(n.substr(1));var p,m,b,v=document.querySelector("[data-scroll-header]"),g=null===v?0:v.offsetHeight+v.offsetTop,O=t.pageYOffset,y=f(document.querySelector(n),g,parseInt(a.offset,10)),I=y-O,S=l(),A=0;h(n,a.updateURL);var Q=function(o,r,c){var u=t.pageYOffset;(o==r||u==r||t.innerHeight+u>=S)&&(clearInterval(c),a.callbackAfter(e,n))},C=function(){A+=16,m=A/parseInt(a.speed,10),m=m>1?1:m,b=O+I*s(a.easing,m),t.scrollTo(0,Math.floor(b)),Q(b,y,p)},H=function(){a.callbackBefore(e,n),p=setInterval(C,16)};0===t.pageYOffset&&t.scrollTo(0,0),H()};var p=function(t){var o=u(t.target,"[data-scroll]");o&&"a"===o.tagName.toLowerCase()&&(t.preventDefault(),n.animateScroll(o,o.hash,e,t))};return n.destroy=function(){e&&(document.removeEventListener("click",p,!1),e=null)},n.init=function(t){o&&(n.destroy(),e=c(r,t||{}),document.addEventListener("click",p,!1))},n}); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-carousel", 3 | "version": "0.18.0", 4 | "description": "A flexible, responsive, touch-friendly carousel for Vue.js", 5 | "main": "dist/vue-carousel.min.js", 6 | "scripts": { 7 | "build": "webpack --config webpack.prod.js && npm run updateDocAssets", 8 | "coveralls": "cat coverage/client/lcov.info | ./node_modules/.bin/coveralls", 9 | "dev": "vue-play start --standalone", 10 | "dev:build": "vue-play build", 11 | "docs:build": "npm run build && rm -rf ./docs/public && mkdir ./docs/public/ && cd ./docs/public/ && git init && git remote add origin git@github.com:SSENSE/vue-carousel.git && git fetch && git checkout -f gh-pages && cd .. && npm install && ./node_modules/.bin/hexo clean && ./node_modules/.bin/hexo generate", 12 | "lint": "prettier-eslint --write \"src/**/?(*.js|*.vue)\" || exit 1", 13 | "precommit": "lint-staged && npm run test", 14 | "test": "npm run test:client", 15 | "test:client": "jest --config tests/client.jest.json", 16 | "test:client:coverage": "jest --config tests/client.jest.json --coverage", 17 | "test-coverage": "npm run test:client:coverage", 18 | "updateDocAssets": "cp ./dist/vue-carousel.min.js ./docs/themes/vue/source/js/" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+ssh://git@github.com/SSENSE/vue-carousel.git" 23 | }, 24 | "keywords": [ 25 | "Vue", 26 | "carousel", 27 | "slider", 28 | "responsive" 29 | ], 30 | "author": "todd.beauchamp@ssense.com", 31 | "license": "MIT", 32 | "bugs": { 33 | "url": "https://github.com/ssense/vue-carousel/issues" 34 | }, 35 | "homepage": "https://github.com/ssense/vue-carousel#readme", 36 | "dependencies": { 37 | "global": "^4.3.2", 38 | "regenerator-runtime": "^0.12.1", 39 | "vue": "^2.5.17" 40 | }, 41 | "resolutions": { 42 | "babel-core": "7.0.0-bridge.0" 43 | }, 44 | "devDependencies": { 45 | "@babel/core": "^7.0.0", 46 | "@babel/polyfill": "^7.0.0", 47 | "@babel/preset-env": "^7.0.0", 48 | "@vue/test-utils": "^1.0.0-beta.26", 49 | "babel-jest": "^24.5.0", 50 | "babel-loader": "^8.0.1", 51 | "babel-plugin-istanbul": "^5.1.1", 52 | "coveralls": "^3.0.1", 53 | "css-loader": "^1.0.0", 54 | "eslint": "^3.19.0", 55 | "eslint-config-airbnb-base": "^11.0.1", 56 | "eslint-config-prettier": "^2.9.0", 57 | "eslint-config-ssense": "^0.1.0", 58 | "eslint-config-vue": "^2.0.1", 59 | "eslint-plugin-fp": "^2.3.0", 60 | "eslint-plugin-import": "^2.2.0", 61 | "eslint-plugin-prettier": "^2.6.0", 62 | "eslint-plugin-vue": "^4.0.0", 63 | "html-webpack-plugin": "^3.2.0", 64 | "husky": "^0.12.0", 65 | "isparta": "^4.0.0", 66 | "isparta-loader": "^2.0.0", 67 | "jest": "^24.5.0", 68 | "jest-serializer-vue": "^2.0.2", 69 | "lint-staged": "^8.1.0", 70 | "prettier": "^1.10.2", 71 | "prettier-eslint": "^8.8.1", 72 | "prettier-eslint-cli": "^4.7.0", 73 | "shelljs": "^0.7.5", 74 | "uglifyjs-webpack-plugin": "^1.3.0", 75 | "vue-jest": "^3.0.4", 76 | "vue-loader": "^15.3.0", 77 | "vue-play": "^3.2.1", 78 | "vue-play-cli": "^1.1.1", 79 | "vue-style-loader": "^4.1.2", 80 | "vue-template-compiler": "^2.5.17", 81 | "webpack": "^4.16.5", 82 | "webpack-cli": "^3.1.0", 83 | "webpack-merge": "^4.1.4" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'autoprefixer': {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/Navigation.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 81 | 82 | 128 | -------------------------------------------------------------------------------- /src/Pagination.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 146 | 147 | 185 | -------------------------------------------------------------------------------- /src/Slide.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 110 | 111 | 129 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Carousel from "./Carousel.vue"; 2 | import Slide from "./Slide.vue"; 3 | 4 | const install = Vue => { 5 | Vue.component("carousel", Carousel); 6 | Vue.component("slide", Slide); 7 | }; 8 | 9 | export default { 10 | install 11 | }; 12 | 13 | export { Carousel, Slide }; 14 | -------------------------------------------------------------------------------- /src/mixins/autoplay.js: -------------------------------------------------------------------------------- 1 | const autoplay = { 2 | props: { 3 | /** 4 | * Flag to enable autoplay 5 | */ 6 | autoplay: { 7 | type: Boolean, 8 | default: false 9 | }, 10 | /** 11 | * Time elapsed before advancing slide 12 | */ 13 | autoplayTimeout: { 14 | type: Number, 15 | default: 2000 16 | }, 17 | /** 18 | * Flag to pause autoplay on hover 19 | */ 20 | autoplayHoverPause: { 21 | type: Boolean, 22 | default: true 23 | }, 24 | /** 25 | * Autoplay direction. User can insert backward to make autoplay move from right to left 26 | */ 27 | autoplayDirection: { 28 | type: String, 29 | default: "forward" 30 | } 31 | }, 32 | data() { 33 | return { 34 | autoplayInterval: null 35 | }; 36 | }, 37 | destroyed() { 38 | if (!this.$isServer) { 39 | this.$el.removeEventListener("mouseenter", this.pauseAutoplay); 40 | this.$el.removeEventListener("mouseleave", this.startAutoplay); 41 | } 42 | }, 43 | methods: { 44 | pauseAutoplay() { 45 | if (this.autoplayInterval) { 46 | this.autoplayInterval = clearInterval(this.autoplayInterval); 47 | } 48 | }, 49 | startAutoplay() { 50 | if (this.autoplay) { 51 | this.autoplayInterval = setInterval( 52 | this.autoplayAdvancePage, 53 | this.autoplayTimeout 54 | ); 55 | } 56 | }, 57 | restartAutoplay() { 58 | this.pauseAutoplay(); 59 | this.startAutoplay(); 60 | }, 61 | autoplayAdvancePage() { 62 | this.advancePage(this.autoplayDirection); 63 | } 64 | }, 65 | mounted() { 66 | if (!this.$isServer && this.autoplayHoverPause) { 67 | this.$el.addEventListener("mouseenter", this.pauseAutoplay); 68 | this.$el.addEventListener("mouseleave", this.startAutoplay); 69 | } 70 | 71 | this.startAutoplay(); 72 | } 73 | }; 74 | 75 | export default autoplay; 76 | -------------------------------------------------------------------------------- /src/utils/debounce.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable fp/no-let */ 2 | /* 3 | * Returns a function, that, as long as it continues to be invoked, will not 4 | * be triggered. The function will be called after it stops being called for 5 | * N milliseconds. If `immediate` is passed, trigger the function on the 6 | * leading edge, instead of the trailing. 7 | */ 8 | const debounce = (func, wait, immediate) => { 9 | let timeout; 10 | return () => { 11 | const context = this; 12 | const later = () => { 13 | timeout = null; 14 | if (!immediate) { 15 | func.apply(context); 16 | } 17 | }; 18 | const callNow = immediate && !timeout; 19 | clearTimeout(timeout); 20 | timeout = setTimeout(later, wait); 21 | if (callNow) { 22 | func.apply(context); 23 | } 24 | }; 25 | }; 26 | 27 | export default debounce; 28 | -------------------------------------------------------------------------------- /tests/client.jest.json: -------------------------------------------------------------------------------- 1 | { 2 | "verbose": true, 3 | "rootDir": "../", 4 | "transform": { 5 | "^.+\\.js?$": "babel-jest", 6 | "^.+\\.vue$": "vue-jest" 7 | }, 8 | "snapshotSerializers": [ 9 | "jest-serializer-vue" 10 | ], 11 | "testPathIgnorePatterns": [ 12 | "/node_modules/", 13 | "/debug/" 14 | ], 15 | "collectCoverageFrom": [ 16 | "src/**/*.{vue,js}" 17 | ], 18 | "moduleFileExtensions": [ 19 | "node", 20 | "json", 21 | "vue", 22 | "js" 23 | ], 24 | "testRegex": ".*\\.spec.js$", 25 | "coverageDirectory": "/coverage", 26 | "coverageReporters": [ 27 | "json", 28 | "html", 29 | "text", 30 | "text-summary", 31 | "lcov" 32 | ], 33 | "coverageThreshold": { 34 | "global": { 35 | "branches": 50, 36 | "functions": 50, 37 | "lines": 50, 38 | "statements": 50 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/client/components/__snapshots__/navigation.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Navigation canAdvanceBackward should not be able to advanced backwards 1`] = `
    `; 4 | 5 | exports[`Navigation canAdvanceForward should not be able to advance forwards 1`] = `
    `; 6 | 7 | exports[`Navigation should match the stored snapshot 1`] = `
    `; 8 | -------------------------------------------------------------------------------- /tests/client/components/__snapshots__/pagination.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Pagination Component should match the stored snapshot 1`] = ` 4 | 7 | `; 8 | 9 | exports[`Pagination Component should not contain a button 1`] = ` 10 | 13 | `; 14 | -------------------------------------------------------------------------------- /tests/client/components/__snapshots__/slide.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Slide should match the stored snapshot 1`] = ``; 4 | -------------------------------------------------------------------------------- /tests/client/components/navigation.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils'; 2 | 3 | import Navigation from '../../../src/Navigation.vue'; 4 | 5 | describe('Navigation', () => { 6 | let carousel; 7 | 8 | beforeEach(() => { 9 | carousel = { 10 | canAdvanceForward: true, 11 | canAdvanceBackward: true 12 | }; 13 | }); 14 | 15 | it('should match the stored snapshot', () => { 16 | const wrapper = shallowMount(Navigation, { 17 | provide: { carousel }, 18 | }); 19 | 20 | expect(wrapper).toMatchSnapshot(); 21 | }); 22 | 23 | it('should render a next button', () => { 24 | const wrapper = shallowMount(Navigation, { 25 | provide: { carousel }, 26 | }); 27 | 28 | expect(wrapper.find('.VueCarousel-navigation-next').exists()).toBeTruthy(); 29 | }); 30 | 31 | it('should render a prev button', () => { 32 | const wrapper = shallowMount(Navigation, { 33 | provide: { carousel }, 34 | }); 35 | 36 | expect(wrapper.find('.VueCarousel-navigation-prev').exists()).toBeTruthy(); 37 | }); 38 | 39 | describe('navigationclick events', () => { 40 | it('should emit page advance when next is clicked', () => { 41 | const wrapper = shallowMount(Navigation, { 42 | provide: { carousel }, 43 | }); 44 | 45 | wrapper.find('.VueCarousel-navigation-next').trigger('click'); 46 | 47 | expect(wrapper.emitted().navigationclick[0][0]).toBe('forward') 48 | }); 49 | 50 | it('should emit page advance backward when prev is clicked', () => { 51 | const wrapper = shallowMount(Navigation, { 52 | provide: { carousel }, 53 | }); 54 | 55 | wrapper.find('.VueCarousel-navigation-prev').trigger('click'); 56 | 57 | expect(wrapper.emitted().navigationclick[0][0]).toBe('backward') 58 | }); 59 | }); 60 | 61 | describe('canAdvanceForward', () => { 62 | it('should be able to advance forwards', () => { 63 | const wrapper = shallowMount(Navigation, { 64 | provide: { carousel }, 65 | }); 66 | 67 | expect(wrapper.vm.canAdvanceForward).toBeTruthy() 68 | }); 69 | 70 | it('should not be able to advance forwards', () => { 71 | carousel.canAdvanceForward = false; 72 | 73 | const wrapper = shallowMount(Navigation, { 74 | provide: { carousel }, 75 | }); 76 | 77 | expect(wrapper.vm.canAdvanceForward).toBeFalsy(); 78 | expect(wrapper).toMatchSnapshot(); 79 | }); 80 | }); 81 | 82 | describe('canAdvanceBackward', () => { 83 | it('should be able to advanced backwards', () => { 84 | const wrapper = shallowMount(Navigation, { 85 | provide: { carousel }, 86 | }); 87 | 88 | expect(wrapper.vm.canAdvanceBackward).toBeTruthy() 89 | }); 90 | 91 | it('should not be able to advanced backwards', () => { 92 | carousel.canAdvanceBackward = false; 93 | 94 | const wrapper = shallowMount(Navigation, { 95 | provide: { carousel }, 96 | }); 97 | 98 | expect(wrapper.vm.canAdvanceBackward).toBeFalsy(); 99 | expect(wrapper).toMatchSnapshot(); 100 | }); 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /tests/client/components/pagination.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils'; 2 | import Pagination from '../../../src/Pagination'; 3 | 4 | describe('Pagination Component', () => { 5 | let carousel; 6 | 7 | beforeEach(() => { 8 | carousel = { 9 | pageCount: 1, 10 | paginationPadding: 1, 11 | paginationSize: 1, 12 | paginationActiveColor: 'red', 13 | paginationColor: 'blue', 14 | paginationPosition: 'top', 15 | slideCount: 2, 16 | scrollPerPage: true, 17 | currentPerPage: 2, 18 | currentPage: 0, 19 | $children: [ 20 | { 21 | title: 'title1' 22 | } 23 | ] 24 | }; 25 | }); 26 | 27 | it('should match the stored snapshot', () => { 28 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 29 | 30 | expect(wrapper).toMatchSnapshot(); 31 | }); 32 | 33 | it('should not contain a button', () => { 34 | carousel.pageCount = 0; 35 | 36 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 37 | 38 | expect(wrapper.find('button').exists()).toBe(false); 39 | expect(wrapper).toMatchSnapshot(); 40 | }); 41 | 42 | it('should contain a button', () => { 43 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 44 | 45 | expect(wrapper.find('button').exists()).toBe(true); 46 | }); 47 | 48 | it('should set the correct title', () => { 49 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 50 | 51 | expect(wrapper.vm.getDotTitle(0)).toBe('title1'); 52 | }); 53 | 54 | it('should emit paginationclick button event with index 0 when button is clicked', () => { 55 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 56 | 57 | wrapper.find('button').trigger('click'); 58 | 59 | expect(wrapper.emitted().paginationclick[0][0]).toBe(0); 60 | }); 61 | 62 | describe('paginationCount', () => { 63 | it('should be set to pageCount if scrollPerPage is enabled', () => { 64 | carousel.scrollPerPage = true; 65 | carousel.pageCount = 1; 66 | 67 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 68 | 69 | expect(wrapper.vm.paginationCount).toBe(1); 70 | }); 71 | 72 | it('should be set to 0 if the slideCount is undefined and scrollPerPage is disabled', () => { 73 | carousel.scrollPerPage = false; 74 | carousel.slideCount = undefined; 75 | 76 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 77 | 78 | expect(wrapper.vm.paginationCount).toBe(0); 79 | }); 80 | 81 | it('should be set to 1 if the slideCount is 1 and scrollPerPage is disabled', () => { 82 | carousel.scrollPerPage = false; 83 | carousel.slideCount = 1; 84 | 85 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 86 | 87 | expect(wrapper.vm.paginationCount).toBe(1); 88 | }); 89 | }); 90 | 91 | describe('isCurrentDot', () => { 92 | let wrapper; 93 | 94 | beforeEach(() => { 95 | wrapper = shallowMount(Pagination, { provide: { carousel } }); 96 | }); 97 | 98 | it('should be false when not the current dot', () => { 99 | expect(wrapper.vm.isCurrentDot(1)).toBe(false); 100 | }); 101 | 102 | it('should be true when it is the current dot', () => { 103 | expect(wrapper.vm.isCurrentDot(0)).toBe(true); 104 | }) 105 | }); 106 | 107 | // TODO: What is with this expected behaviour? 108 | describe('paginationPropertyBasedOnPosition', () => { 109 | // `bottom`, `bottom-overlay`, `top` and `top-overlay` 110 | it('should be set to bottom if paginationPosition is set to top', () => { 111 | carousel.paginationPosition = 'top'; 112 | 113 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 114 | 115 | expect(wrapper.vm.paginationPropertyBasedOnPosition).toBe('bottom'); 116 | }); 117 | 118 | it('should be set to bottom if paginationPosition is set to top-overlay', () => { 119 | carousel.paginationPosition = 'top-overlay'; 120 | 121 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 122 | 123 | expect(wrapper.vm.paginationPropertyBasedOnPosition).toBe('bottom'); 124 | }); 125 | 126 | it('should be set to top if paginationPosition is set to bottom', () => { 127 | carousel.paginationPosition = 'bottom'; 128 | 129 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 130 | 131 | expect(wrapper.vm.paginationPropertyBasedOnPosition).toBe('top'); 132 | }); 133 | 134 | it('should be set to top if paginationPosition is set to bottom-overlay', () => { 135 | carousel.paginationPosition = 'bottom-overlay'; 136 | 137 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 138 | 139 | expect(wrapper.vm.paginationPropertyBasedOnPosition).toBe('top'); 140 | }); 141 | }); 142 | 143 | describe('paginationPositionModifierName', () => { 144 | it('should be the paginationPosition if set to top-overlay', () => { 145 | carousel.paginationPosition = 'top-overlay'; 146 | 147 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 148 | 149 | expect(wrapper.vm.paginationPositionModifierName).toBe('top-overlay'); 150 | }); 151 | 152 | it('should be the paginationPosition if set to bottom-overlay', () => { 153 | carousel.paginationPosition = 'bottom-overlay'; 154 | 155 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 156 | 157 | expect(wrapper.vm.paginationPositionModifierName).toBe('bottom-overlay'); 158 | }); 159 | 160 | it('should be undefined if set to top', () => { 161 | carousel.paginationPosition = 'top'; 162 | 163 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 164 | 165 | expect(wrapper.vm.paginationPositionModifierName).toBeUndefined(); 166 | }); 167 | 168 | it('should be undefined if set to bottom', () => { 169 | carousel.paginationPosition = 'bottom'; 170 | 171 | const wrapper = shallowMount(Pagination, { provide: { carousel } }); 172 | 173 | expect(wrapper.vm.paginationPositionModifierName).toBeUndefined(); 174 | }); 175 | }); 176 | }); 177 | -------------------------------------------------------------------------------- /tests/client/components/slide.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils'; 2 | 3 | import Slide from '../../../src/Slide.vue'; 4 | 5 | describe('Slide', () => { 6 | let carousel; 7 | 8 | beforeEach(() => { 9 | carousel = { 10 | isTouch: true, 11 | adjustableHeight: true, 12 | dragStartX: 0, 13 | minSwipeDistance: 10, 14 | perPage: 3, 15 | currentPage: 0, 16 | $children: [ 17 | { 18 | _uid: 0, 19 | _isMounted: true, 20 | $el: { 21 | className: 'VueCarousel-slide' 22 | } 23 | } 24 | ] 25 | }; 26 | }); 27 | 28 | it('should match the stored snapshot', () => { 29 | const wrapper = shallowMount(Slide, { 30 | propsData: { title: 'fooTitle' }, 31 | provide: { carousel } 32 | }); 33 | 34 | expect(wrapper).toMatchSnapshot(); 35 | }); 36 | 37 | describe('isActive', () => { 38 | // TODO: Cannot reliably test because of the implementation using _uid 39 | it.skip('should be the active slide', () => {}); 40 | 41 | it('should not be the active slide', () => { 42 | const wrapper = shallowMount(Slide, { 43 | propsData: { title: 'fooTitle' }, 44 | provide: { carousel } 45 | }); 46 | 47 | expect(wrapper.vm.isActive).toBeFalsy(); 48 | }); 49 | }); 50 | 51 | describe('isCenter', () => { 52 | it('should not be center slide if there is an even number of slides', () => { 53 | carousel.perPage = 2; 54 | 55 | const wrapper = shallowMount(Slide, { 56 | propsData: { title: 'fooTitle' }, 57 | provide: { carousel } 58 | }); 59 | 60 | expect(wrapper.vm.isCenter).toBeFalsy(); 61 | }); 62 | 63 | // TODO: Cannot reliably test because of the implementation using _uid 64 | it.skip('should be the center slide', () => {}); 65 | 66 | it('should not be the center slide', () => { 67 | const wrapper = shallowMount(Slide, { 68 | propsData: { title: 'fooTitle' }, 69 | provide: { carousel } 70 | }); 71 | 72 | expect(wrapper.vm.isCenter).toBeFalsy(); 73 | }); 74 | }); 75 | 76 | describe('isAdjustableHeight', () => { 77 | it('should be adjustable', () => { 78 | const wrapper = shallowMount(Slide, { 79 | propsData: { title: 'fooTitle' }, 80 | provide: { carousel } 81 | }); 82 | 83 | expect(wrapper.vm.isAdjustableHeight).toBeTruthy(); 84 | }); 85 | 86 | it('should not be adjustable', () => { 87 | carousel.adjustableHeight = false; 88 | 89 | const wrapper = shallowMount(Slide, { 90 | propsData: { title: 'fooTitle' }, 91 | provide: { carousel } 92 | }); 93 | 94 | expect(wrapper.vm.isAdjustableHeight).toBeFalsy(); 95 | }); 96 | }); 97 | 98 | describe('onTouchEnd', () => { 99 | it('should emit slideclick event if carousel isTouch', () => { 100 | const wrapper = shallowMount(Slide, { 101 | propsData: { title: 'fooTitle' }, 102 | provide: { carousel } 103 | }); 104 | 105 | wrapper.vm.onTouchEnd({ changedTouches: [{ clientX: 9 }], currentTarget: { dataset: { foo: 'dataset' } } }); 106 | 107 | expect(wrapper.emitted().slideclick[0][0]).toEqual({"foo": "dataset"}); 108 | }); 109 | 110 | it('should emit slideclick event if carousel is not isTouch', () => { 111 | carousel.isTouch = false; 112 | 113 | const wrapper = shallowMount(Slide, { 114 | propsData: { title: 'fooTitle' }, 115 | provide: { carousel } 116 | }); 117 | 118 | wrapper.vm.onTouchEnd({ clientX: 9, currentTarget: { dataset: { foo: 'dataset' } }}); 119 | 120 | expect(wrapper.emitted().slideclick[0][0]).toEqual({"foo": "dataset"}); 121 | }); 122 | 123 | it('shoud not emit slideclick event', () => { 124 | const wrapper = shallowMount(Slide, { 125 | propsData: { title: 'fooTitle' }, 126 | provide: { carousel } 127 | }); 128 | 129 | wrapper.vm.onTouchEnd({ clientX: 11, currentTarget: { dataset: { foo: 'dataset' } } }); 130 | 131 | expect(wrapper.emitted().slideclick).toBeUndefined(); 132 | }); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /tests/client/index.spec.js: -------------------------------------------------------------------------------- 1 | import index, { Carousel, Slide } from '../../src/index.js'; 2 | import { createLocalVue } from '@vue/test-utils'; 3 | 4 | describe('index', () => { 5 | it('should export a slide component', () => { 6 | expect(Slide).toBeDefined() 7 | }) 8 | 9 | it('should export a Carousel component', () => { 10 | expect(Carousel).toBeDefined(); 11 | }); 12 | 13 | it('Installs the defauly export as a plugin', () => { 14 | const vue = createLocalVue(); 15 | vue.use(index); 16 | expect(vue.options.components.carousel).toBeDefined(); 17 | expect(vue.options.components.slide).toBeDefined(); 18 | }) 19 | }); 20 | -------------------------------------------------------------------------------- /tests/client/utils/.debounce.spec.js.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SSENSE/vue-carousel/7c8e213e6773100b7cfad19b3ee88feebd777970/tests/client/utils/.debounce.spec.js.swp -------------------------------------------------------------------------------- /tests/client/utils/debounce.spec.js: -------------------------------------------------------------------------------- 1 | import debounce from '../../../src/utils/debounce.js'; 2 | 3 | jest.useFakeTimers(); 4 | 5 | describe('debounce', () => { 6 | it('immediately calls the passed function if call now is true and no timeout is passed', () => { 7 | const testfn = jest.fn(); 8 | const db = debounce(testfn, 0, true); 9 | db(); 10 | expect(testfn).toHaveBeenCalled(); 11 | }); 12 | 13 | it('calls the method in the passed amount of time', () => { 14 | const testfn = jest.fn(); 15 | const db = debounce(testfn, 10000, false); 16 | db(); 17 | jest.advanceTimersByTime(5000); 18 | expect(testfn).not.toBeCalled(); 19 | 20 | jest.advanceTimersByTime(5000); 21 | expect(testfn).toHaveBeenCalled(); 22 | }) 23 | }); 24 | -------------------------------------------------------------------------------- /tests/functional/TODO.md: -------------------------------------------------------------------------------- 1 | # Function UI Tests 2 | 3 | This is a document to keep track of the functional ui tests we want to implement. Please add to this file as you discover new UI tests you would like to add. 4 | 5 | ## autoplay 6 | 7 | * display the second slide after waiting the timeout duration with direction forward 8 | * display the first slide after waiting the timeout duration with direction backward 9 | * no autoplay advance on hover 10 | * autoplay advance on hover when hover pause false 11 | * loop to the first slide when looping is enabled 12 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const npmCfg = require('./package.json'); 4 | const projectRoot = path.resolve(__dirname, './'); 5 | 6 | const { VueLoaderPlugin } = require('vue-loader'); 7 | 8 | const banner = [ 9 | 'vue-carousel v' + npmCfg.version, 10 | '(c) ' + (new Date().getFullYear()) + ' ' + npmCfg.author, 11 | npmCfg.homepage 12 | ].join('\n') 13 | 14 | module.exports = { 15 | entry: ['./src/'], 16 | output: { 17 | path: path.resolve(__dirname, './dist'), 18 | filename: 'vue-carousel.js', 19 | library: 'VueCarousel', 20 | libraryTarget: 'umd' 21 | }, 22 | resolve: { 23 | extensions: ['.js', '.vue'], 24 | modules: [ 25 | path.join(__dirname, 'node_modules') 26 | ], 27 | alias: { 28 | 'vue$': 'vue/dist/vue.common.js', 29 | } 30 | }, 31 | resolveLoader: { 32 | modules: [ 33 | path.join(__dirname, 'node_modules') 34 | ] 35 | }, 36 | module: { 37 | rules: [ 38 | { 39 | test: /\.vue$/, 40 | loader: 'vue-loader' 41 | }, 42 | { 43 | test: /\.js$/, 44 | loader: 'babel-loader', 45 | options: { 46 | presets: [ 47 | ['@babel/preset-env', { 48 | useBuiltIns: 'usage' 49 | }] 50 | ], 51 | comments: false 52 | }, 53 | include: projectRoot, 54 | exclude: /node_modules/ 55 | }, 56 | { 57 | test: /\.css$/, 58 | use: [ 'vue-style-loader', 'css-loader' ] 59 | } 60 | ] 61 | }, 62 | plugins: [ 63 | new webpack.BannerPlugin(banner), 64 | new VueLoaderPlugin() 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /webpack.prod.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 4 | 5 | module.exports = merge(common, { 6 | mode: 'production', 7 | output: { 8 | filename: 'vue-carousel.min.js' 9 | }, 10 | plugins: [ 11 | new UglifyJsPlugin({ 12 | sourceMap: false 13 | }) 14 | ] 15 | }); 16 | --------------------------------------------------------------------------------