├── .browserslistrc ├── .eslintignore ├── babel.config.js ├── public ├── favicon.ico ├── images │ └── demo.gif └── index.html ├── src ├── assets │ └── css │ │ └── tailwind.css ├── main.js ├── index.js ├── App.vue └── components │ ├── PageButton.vue │ └── Pagination.vue ├── tailwind.config.js ├── tests ├── .eslintrc.js └── unit │ └── components │ ├── PageButton.test.js │ └── Pagination.test.js ├── .eslintrc.js ├── .gitignore ├── postcss.config.js ├── CONTRIBUTING.md ├── jest.config.js ├── LICENSE ├── CHANGELOG.md ├── package.json └── README.md /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | tests/coverage 4 | babel.config.js 5 | tailwind.config.js 6 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app', 4 | ], 5 | }; 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arnedesmedt/vue-ads-pagination/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | 3 | @tailwind components; 4 | 5 | @tailwind utilities; 6 | -------------------------------------------------------------------------------- /public/images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arnedesmedt/vue-ads-pagination/HEAD/public/images/demo.gif -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | prefix: 'vue-ads-', 3 | theme: {}, 4 | variants: {}, 5 | plugins: [], 6 | }; 7 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App'; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: h => h(App), 8 | }).$mount('#app'); 9 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './assets/css/tailwind.css'; 2 | 3 | import Pagination from './components/Pagination'; 4 | import VueAdsPageButton from './components/PageButton'; 5 | 6 | export default Pagination; 7 | 8 | export { VueAdsPageButton }; 9 | -------------------------------------------------------------------------------- /tests/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true, 4 | }, 5 | rules: { 6 | 'no-new': 'off', 7 | 'no-unused-expressions': 'off', 8 | 'no-template-curly-in-string': 'off', 9 | 'import/no-extraneous-dependencies': 'off', 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | env: { 5 | node: true, 6 | }, 7 | 8 | extends: [ 9 | 'plugin:vue/essential', 10 | '@vue/standard', 11 | 'eslint-config-ads', 12 | 'eslint-config-ads/vue', 13 | ], 14 | 15 | parserOptions: { 16 | parser: 'babel-eslint', 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # test coverage 6 | /tests/coverage/* 7 | 8 | # local env files 9 | .env.local 10 | .env.*.local 11 | 12 | # Log files 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Editor directories and files 18 | .idea 19 | .vscode 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | tailwindcss: './tailwind.config.js', 5 | '@fullhuman/postcss-purgecss': { 6 | content: [ 7 | './src/components/*.vue', 8 | ], 9 | whitelistPatterns: [ 10 | /^focus:vue-ads-outline-none$/, 11 | /^hover:vue-ads-bg-gray-100$/, 12 | ], 13 | }, 14 | 'postcss-import': {}, 15 | 'postcss-url': {}, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | 4 | If you would like to contribute to the current project, follow these rules: 5 | 6 | - One pull request per issue (bug, feature, ...). 7 | - Create feature branches. 8 | - Test the changes if possible. Pull requests that doesn't pass the tests, will not be accepted (`npm run test:unit`). 9 | - Update the [README.md](README.md) file if necessary. 10 | - Update the [CHANGELOG.md](CHANGELOG.md) if necessary. 11 | 12 | Do you want to start now? Check the [issues tab](https://gitlab.com/arnedesmedt/vue-ads-pagination/issues) in gitlab, fork and start coding! 13 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | 'js', 4 | 'jsx', 5 | 'json', 6 | 'vue', 7 | ], 8 | transform: { 9 | '^.+\\.vue$': 'vue-jest', 10 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', 11 | '^.+\\.jsx?$': 'babel-jest', 12 | }, 13 | moduleNameMapper: { 14 | '^@/(.*)$': '/src/$1', 15 | }, 16 | snapshotSerializers: [ 17 | 'jest-serializer-vue', 18 | ], 19 | testMatch: [ 20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)', 21 | ], 22 | testURL: 'http://localhost/', 23 | }; 24 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | vue-ads-pagination 10 | 11 | 12 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Arne De Smedt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | #### v2.1.1 - 14/01/2019 4 | 5 | - Split the page-change event in a page-change event and a range-change event: 6 | If you dont have a second page by default and you're adding items, then the external end variable won't change 7 | because no page-change event was triggered. This is now solved via the range-change event. 8 | 9 | #### v2.0.5 - 27/11/2018 10 | 11 | - Not all pages were shown properly. Fixed it. 12 | 13 | #### v2.0.4 - 24/11/2018 14 | 15 | - Prefix the tailwind classes with `vue-ads-`. 16 | 17 | #### v2.0.3 - 08/11/2018 18 | 19 | - Prefix the tailwind classes with `ads-`. 20 | 21 | #### v2.0.2 - 08/11/2018 22 | 23 | - Add a disable-styling property on the VueAdsPageButton to remove all stylings on the button. 24 | 25 | #### v2.0.0 - 09/10/2018 26 | 27 | - Small rewrite of the paginator: 28 | - Make it possible to use your own buttons or extend the default VueAdsPageButton, by adding a buttons template. 29 | - So now we could remove the detailClasses and buttonClasses for custom styling. 30 | - Remove the range object and add their attributes as clear properties. Only use start and end anymore. 31 | - Purge the css. 32 | - Move configs from package.json to separate files. 33 | 34 | #### v1.1.0 - 22/08/2018 35 | 36 | - Add a loading property to inidicate if the current page is loading 37 | - Add the detailClasses and buttonClasses property to custom style the detail box and the buttons 38 | 39 | #### v1.0.1 - 14/08/2018 40 | 41 | - Make the emitted events case insensitive. 42 | 43 | #### v1.0.0 - 14/08/2018 44 | 45 | - Initial release. 46 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": false, 3 | "name": "vue-ads-pagination", 4 | "description": "A Vue pagination plugin.", 5 | "license": "MIT", 6 | "author": "Arne De Smedt (https://twitter.com/ArneSmedt)", 7 | "homepage": "https://github.com/arnedesmedt/vue-ads-pagination", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/arnedesmedt/vue-ads-pagination.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/arnedesmedt/vue-ads-pagination/issues" 14 | }, 15 | "version": "2.1.7", 16 | "main": "./dist/vue-ads-pagination.common.js", 17 | "files": [ 18 | "/dist" 19 | ], 20 | "scripts": { 21 | "build": "vue-cli-service build", 22 | "build:bundle": "vue-cli-service build --target lib --name vue-ads-pagination ./src/index.js", 23 | "lint": "vue-cli-service lint", 24 | "package-lint": "prettier-package-json --write --tab-width=4 ./package.json", 25 | "serve": "vue-cli-service serve", 26 | "test:unit": "vue-cli-service test:unit", 27 | "preversion": "export NODE_ENV=production && npm run lint && npm run package-lint", 28 | "version": "npm run build:bundle", 29 | "postversion": "git push && git push --tags" 30 | }, 31 | "dependencies": { 32 | "@fortawesome/fontawesome-free": "^5.11.2", 33 | "vue": "^2.6.10" 34 | }, 35 | "devDependencies": { 36 | "@fullhuman/postcss-purgecss": "^1.3.0", 37 | "@vue/cli-plugin-babel": "^4.0.5", 38 | "@vue/cli-plugin-eslint": "^4.0.5", 39 | "@vue/cli-plugin-unit-jest": "^4.0.5", 40 | "@vue/cli-service": "^4.0.5", 41 | "@vue/eslint-config-standard": "^4.0.0", 42 | "@vue/test-utils": "^1.0.0-beta.25", 43 | "babel-core": "7.0.0-bridge.0", 44 | "babel-eslint": "^10.0.3", 45 | "babel-jest": "^24.9.0", 46 | "eslint": "^4.19.1", 47 | "eslint-config-ads": "^1.0.7", 48 | "eslint-plugin-vue": "^6.0.1", 49 | "postcss-import": "^12.0.1", 50 | "postcss-url": "^8.0.0", 51 | "prettier-package-json": "^2.1.0", 52 | "tailwindcss": "^1.1.3", 53 | "vue-template-compiler": "^2.6.10" 54 | }, 55 | "keywords": [ 56 | "component", 57 | "pagination", 58 | "vue" 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /tests/unit/components/PageButton.test.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils'; 2 | import PageButton from '@/components/PageButton'; 3 | 4 | describe('PageButton', () => { 5 | let pageButton; 6 | 7 | beforeEach(() => { 8 | 9 | pageButton = shallowMount(PageButton, { 10 | propsData: { 11 | page: 0, 12 | html: '0', 13 | }, 14 | }); 15 | }); 16 | 17 | it('emits a page change if the button has a page and is not active', () => { 18 | pageButton.trigger('click'); 19 | 20 | expect(pageButton.emitted()['page-change']).toBeTruthy(); 21 | }); 22 | 23 | it('doesn\'t emit a page change if the button has a page and is active', () => { 24 | pageButton.setProps({ 25 | active: true, 26 | }); 27 | pageButton.trigger('click'); 28 | 29 | expect(pageButton.emitted()['page-change']).toBeUndefined(); 30 | }); 31 | 32 | it('doesn\'t emit a page change if the button is disabled', () => { 33 | pageButton.setProps({ 34 | disabled: true, 35 | }); 36 | pageButton.trigger('click'); 37 | 38 | expect(pageButton.emitted()['page-change']).toBeUndefined(); 39 | }); 40 | 41 | it('doesn\'t emit a page change if the button doesn\'t have a numeric page', () => { 42 | pageButton.setProps({ 43 | page: '...', 44 | }); 45 | pageButton.trigger('click'); 46 | 47 | expect(pageButton.emitted()['page-change']).toBeUndefined(); 48 | }); 49 | 50 | it('shows a loader when the page is active and the loading property is true', () => { 51 | pageButton.setProps({ 52 | active: true, 53 | loading: true, 54 | }); 55 | 56 | expect(pageButton.find('i').is('i')).toBeTruthy(); 57 | }); 58 | 59 | it('doesn\'t show a loader when the page is active and the loading property is false', () => { 60 | pageButton.setProps({ 61 | active: true, 62 | loading: false, 63 | }); 64 | 65 | expect(pageButton.find('span').is('span')).toBeTruthy(); 66 | }); 67 | 68 | it('doesn\'t add styling if the styling is disabled', () => { 69 | pageButton.setProps({ 70 | disableStyling: true, 71 | }); 72 | 73 | expect(pageButton.vm.buttonClasses).toEqual({}); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /src/components/PageButton.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 99 | -------------------------------------------------------------------------------- /tests/unit/components/Pagination.test.js: -------------------------------------------------------------------------------- 1 | import { shallowMount, mount } from '@vue/test-utils'; 2 | import Pagination from '@/components/Pagination.vue'; 3 | import PageButton from '@/components/PageButton.vue'; 4 | 5 | describe('VueAdsPagination', () => { 6 | let pagination; 7 | let props; 8 | 9 | beforeEach(() => { 10 | props = { 11 | itemsPerPage: 10, 12 | maxVisiblePages: 5, 13 | page: 0, 14 | totalItems: 150, 15 | loading: false, 16 | }; 17 | 18 | pagination = shallowMount(Pagination, { 19 | propsData: props, 20 | }); 21 | }); 22 | 23 | it('does not allow negative pages', () => { 24 | expect(pagination.vm.$options.props.page.validator(-1)).toBeFalsy(); 25 | }); 26 | 27 | it('throws an error if the page is greater than the totalPages', () => { 28 | expect(() => { 29 | props.page = 20; 30 | pagination = shallowMount(Pagination, { 31 | propsData: props, 32 | }); 33 | }).toThrow('page may be maximum the total number of pages minus one'); 34 | }); 35 | 36 | 37 | it('does not allow negative totalItems', () => { 38 | expect(pagination.vm.$options.props.totalItems.validator(-1)).toBeFalsy(); 39 | }); 40 | 41 | it('does not allow negative itemsPerPage', () => { 42 | expect(pagination.vm.$options.props.itemsPerPage.validator(-1)).toBeFalsy(); 43 | }); 44 | 45 | 46 | it('does not allow negative maxVisiblePages', () => { 47 | expect(pagination.vm.$options.props.maxVisiblePages.validator(-1)).toBeFalsy(); 48 | }); 49 | 50 | it('calculates the correct start and end', () => { 51 | let start = pagination.vm.start; 52 | let end = pagination.vm.end; 53 | 54 | expect(start).toBe(0); 55 | expect(end).toBe(10); 56 | }); 57 | 58 | it('calculates the start and end of the second page', () => { 59 | pagination.setProps({ 60 | page: 1, 61 | }); 62 | 63 | let start = pagination.vm.start; 64 | let end = pagination.vm.end; 65 | 66 | expect(start).toBe(10); 67 | expect(end).toBe(20); 68 | }); 69 | 70 | 71 | it('totalPages is zero if itemsPerPage is zero', () => { 72 | pagination.setProps({ 73 | itemsPerPage: 0, 74 | }); 75 | 76 | expect(pagination.vm.totalPages).toBe(0); 77 | }); 78 | 79 | it('returns the correct number of pages', () => { 80 | expect(pagination.vm.totalPages).toBe(15); 81 | }); 82 | 83 | it('returns the correct pages if their are more pages then maxVisiblePages', () => { 84 | expect(pagination.vm.pages).toEqual([ 85 | -1, 86 | 0, 87 | 1, 88 | 2, 89 | 3, 90 | 4, 91 | 5, 92 | 6, 93 | '...', 94 | 14, 95 | 1, 96 | ]); 97 | }); 98 | 99 | it('returns the correct pages if their are less pages then maxVisiblePages', () => { 100 | pagination.setProps({ 101 | totalItems: 20, 102 | }); 103 | expect(pagination.vm.pages).toEqual([ 104 | -1, 105 | 0, 106 | 1, 107 | 1, 108 | ]); 109 | }); 110 | 111 | it('uses the slot for displaying the range', () => { 112 | const pagination = shallowMount(Pagination, { 113 | propsData: props, 114 | scopedSlots: { 115 | default: '

' + 116 | 'Items {{ props.start }} tot {{ props.end }} van de {{ props.total }}' + 117 | '

', 118 | }, 119 | }); 120 | 121 | expect(pagination.find('#range').text()).toEqual('Items 1 tot 10 van de 150'); 122 | }); 123 | 124 | 125 | 126 | it('uses the buttons slot for displaying the buttons', () => { 127 | const pagination = shallowMount(Pagination, { 128 | propsData: props, 129 | scopedSlots: { 130 | buttons: '
' + 131 | '{{ button.page }}' + 132 | '
', 133 | }, 134 | }); 135 | 136 | expect(pagination.find('#buttons').text()).toEqual('-10123456...141'); 137 | }); 138 | 139 | it('emits the current range if the page changes from outside', () => { 140 | pagination.setProps({ 141 | page: 2, 142 | }); 143 | 144 | expect(pagination.emitted()['range-change']).toBeTruthy(); 145 | expect(pagination.emitted()['range-change'][1]).toEqual([ 146 | 20, 147 | 30, 148 | ]); 149 | }); 150 | 151 | it('emits the current page if a button is clicked', () => { 152 | pagination = mount(Pagination, { 153 | propsData: props, 154 | }); 155 | 156 | pagination.findAll(PageButton).at(2).trigger('click'); 157 | 158 | expect(pagination.emitted()['page-change']).toBeTruthy(); 159 | expect(pagination.emitted()['page-change'][0]).toEqual([ 160 | 1, 161 | ]); 162 | }); 163 | 164 | it('adds a loading icon on the active page', () => { 165 | pagination.setProps({ 166 | page: 2, 167 | loading: true, 168 | }); 169 | 170 | expect(pagination.vm.buttons[3].loading).toBeTruthy(); 171 | }); 172 | 173 | it('set the end variable not to the page end if the page is not fully filled', () => { 174 | pagination.setProps({ 175 | totalItems: 8, 176 | }); 177 | 178 | expect(pagination.vm.end).toBe(8); 179 | }); 180 | 181 | it('has a page in the middle', () => { 182 | pagination.setProps({ 183 | page: 8, 184 | }); 185 | 186 | expect(pagination.vm.pages).toEqual([ 187 | 7, 188 | 0, 189 | '...', 190 | 6, 191 | 7, 192 | 8, 193 | 9, 194 | 10, 195 | '...', 196 | 14, 197 | 9, 198 | ]); 199 | }); 200 | 201 | it('has a page in the end', () => { 202 | pagination.setProps({ 203 | page: 13, 204 | }); 205 | 206 | expect(pagination.vm.pages).toEqual([ 207 | 12, 208 | 0, 209 | '...', 210 | 8, 211 | 9, 212 | 10, 213 | 11, 214 | 12, 215 | 13, 216 | 14, 217 | 14, 218 | ]); 219 | }); 220 | }); 221 | -------------------------------------------------------------------------------- /src/components/Pagination.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 233 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-ads-pagination 2 | 3 | Vue ads pagination is a vue js pagination component. 4 | On the left side you find some information about the shown items. 5 | On the right side you can select a specific, the first, last, next or previous page. 6 | 7 | All the components can be overriden by your own components, 8 | or you can add your own styles to the default components. 9 | 10 | ## Demo 11 | 12 | I've written a demo in [JSFiddle](https://jsfiddle.net/arnedesmedt/18n9k6vm) 13 | 14 | ## Installation 15 | 16 | You can install the package via npm or yarn. 17 | 18 | #### NPM 19 | 20 | ```npm install vue-ads-pagination --save``` 21 | 22 | #### YARN 23 | 24 | ```yarn add vue-ads-pagination``` 25 | 26 | ## Usage 27 | 28 | You can add the vue-ads-pagination component by using the following code in your project. 29 | 30 | ```vue 31 | 60 | 61 | 94 | ``` 95 | 96 | ### Components 97 | 98 | #### VueAdsPagination 99 | 100 | ##### Properties 101 | 102 | - `page`: *(type: number, default: 0)* A zero-based number to set the page. 103 | Be aware you need to update the page property by the result of the page-change action! 104 | - `items-per-page`: *(type: number, default: 10)* The maximum amount of items on one page. 105 | - `max-visible-pages`: *(type: number, default: 5)* The maximum number of pages to be visible if their are too many pages. 106 | - `total-items`: *(type: number, required)* The total amount of items. 107 | - `loading`: *(type: boolean, default: false)* Indicates if the current page is loading. 108 | 109 | ##### Events 110 | 111 | - `page-change`: Emitted on creation, to know the initial state, and if another page is clicked. It contains the following parameters: 112 | - `page`: *(type: number)* The zero-based current page. 113 | 114 | - `range-change`: Emitted on creation, to know the initial state, and if another page is clicked or the total items change and you're on the last page. 115 | It contains the following parameters: 116 | - `start`: *(type: number)* A zero-based number to identify the first item. 117 | - `end`: *(type: number)* A zero-based number to identify the last item. 118 | 119 | ##### Templates 120 | 121 | ###### Default 122 | 123 | You can add a default template to use a custom pagination detail box. 124 | The scope contains 3 variables: 125 | 126 | - `start`: *(type: number)* The included start item. 127 | - `end`: *(type: number)* The included end item. 128 | - `total`: *(type: number)* The total number of visible items. 129 | 130 | ```vue 131 | 134 | ``` 135 | 136 | ###### Buttons 137 | 138 | If you want to use your own buttons, control their behaviour our style them in a different way. 139 | You can create your own button component and loop over it in this slot or use the predefined VueAdsPageButton. 140 | This is a scoped slot that contains an array of buttons. 141 | 142 | - `buttons`: *(type: Array)* A list of all buttons currently used. One button is an object that contains the following attributes: 143 | - `page`: *(type: number||string)* This is the zero based page or the string '...'. 144 | Note that the value of this attribute for the next and previous icons is calculated by the current page. 145 | If the current page is 2, the previous page will be 1 and the next page is 3. 146 | - `active`: *(type: boolean)* Is the current page active? 147 | - `disabled`: *(type: boolean)* Is the current button disabled? 148 | - `html`: *(type: string)* This string is shown in the button. So you can use icons for the previous and next button. 149 | - `title`: *(type: string)* If you want to add a title to the button, you can fill this attribute. 150 | - `loading`: *(type: boolean)* Indicates if the button has to show a loading icon. 151 | 152 | ```vue 153 | 164 | ``` 165 | 166 | #### VueAdsPageButton 167 | 168 | This is the default button. If you want to add extra classes. Add the template above and add the class attribute. 169 | 170 | ##### Properties 171 | 172 | - `page`: *(type: number||string, default: 0)* A zero-based number that represents the page or '...'. 173 | - `active`: *(type: boolean, default: false)* Is the current button active? 174 | - `disabled`: *(type: boolean, default: false)* Is the current button disabled? 175 | - `html`: *(type: string, required)* This string is shown in the button. 176 | - `title`: *(type: string, default: '')* If you want to add a title to the button, you can fill this attribute. 177 | - `loading`: *(type: boolean, default: false)* Indicates if the button has to show a loading icon. 178 | - `disable-styling`: *(type: boolean, default: false)* Remove all styling classes. 179 | 180 | 181 | ##### Events 182 | 183 | - `page-change`: Emitted when the button is clicked. 184 | 185 | ## Testing 186 | 187 | We use the jest framework for testing this pagination component. Run the following command to test it: 188 | 189 | ``` 190 | npm run test:unit 191 | ``` 192 | 193 | ## Changelog 194 | 195 | Read the [CHANGELOG](CHANGELOG.md) file to check what has changed. 196 | 197 | ## Issues 198 | 199 | If you have any issues (bugs, features, ...) on the current project, add them [here](https://gitlab.com/arnedesmedt/vue-ads-pagination/issues/new). 200 | 201 | ## Contributing 202 | 203 | Do you like to contribute to this project? Please, read the [CONTRIBUTING](CONTRIBUTING.md) file. 204 | 205 | ## Social 206 | 207 | [1]: http://www.twitter.com/arnesmedt 208 | [1.1]: http://i.imgur.com/wWzX9uB.png (@ArneSmedt) 209 | - Follow me on [![alt text][1.1]][1] 210 | 211 | ## Donate 212 | 213 | Want to make a donation? 214 | That would be highly appreciated! 215 | 216 | Make a donation via [PayPal](https://www.paypal.me/arnedesmedt). 217 | --------------------------------------------------------------------------------