├── lib ├── paginator.css ├── Paginator.js.map └── Paginator.js ├── src ├── paginator.css └── Paginator.jsx ├── .gitignore ├── examples ├── es6 │ └── src │ │ ├── main.jsx │ │ └── index.tpl.html └── es5 │ └── index.html ├── LICENSE ├── package.json ├── webpack.config.js └── README.md /lib/paginator.css: -------------------------------------------------------------------------------- 1 | .pagination li a .glyphicon{ 2 | line-height: inherit; 3 | } -------------------------------------------------------------------------------- /src/paginator.css: -------------------------------------------------------------------------------- 1 | .pagination li a .glyphicon{ 2 | line-height: inherit; 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /examples/es6/src/main.jsx: -------------------------------------------------------------------------------- 1 | import Paginator from '../../../src/Paginator.jsx'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | 5 | const App = React.createClass({ 6 | pages:{ 7 | current: 10, 8 | total: 1000 9 | }, 10 | pageClick(page){ 11 | console.log("I should do something regarding page "+page); 12 | }, 13 | render(){ 14 | return( 15 | 16 | ) 17 | } 18 | }); 19 | 20 | ReactDOM.render(, document.getElementById('the_paginator')); 21 | -------------------------------------------------------------------------------- /examples/es6/src/index.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Reacomponents - Paginator ES5 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Fabio Oliveira Costa 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 | -------------------------------------------------------------------------------- /examples/es5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Reacomponents - Paginator ES5 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 30 | 31 | -------------------------------------------------------------------------------- /src/Paginator.jsx: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from 'react'; 4 | 5 | const Paginator = React.createClass({ 6 | getDefaultProps(){ 7 | return { 8 | max: 10, 9 | current: 1 10 | } 11 | }, 12 | 13 | render(){ 14 | let current = this.props.current; 15 | let total = this.props.total; 16 | let max = this.props.max; 17 | 18 | let start = Math.max(current - Math.round(max/2) ,1); 19 | 20 | let end = Math.min((start+max)-1,total); 21 | if(end - start < max) { 22 | start = Math.max(1,end - (max)-1); 23 | } 24 | let hasLess = null; 25 | let previous = null; 26 | if(start != 1){ 27 | hasLess = ( 28 |
  • ...
  • 29 | ); 30 | previous = ( 31 |
  • 32 | 33 | this.props.onPage(current-1)}> 34 | 35 |
  • 36 | ); 37 | } 38 | let hasMore =null; 39 | let next = null; 40 | if(end... 43 | ); 44 | next = ( 45 |
  • 46 | 47 | this.props.onPage(current+1)}> 48 | 49 |
  • 50 | ); 51 | } 52 | let getLinks= (start,end)=>{ 53 | const links = []; 54 | for(let i=start;i<=end;i++){ 55 | let className = i==current?'active':''; 56 | links.push(
  • this.props.onPage(i)}>{i}
  • ); 57 | } 58 | return links; 59 | }; 60 | return( 61 |
    62 |
      63 | {previous} 64 | {hasLess} 65 | {getLinks(start,end)} 66 | {hasMore} 67 | {next} 68 |
    69 |
    70 | ) 71 | } 72 | }) 73 | require('./paginator.css'); 74 | export default Paginator; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_bootstrap_paginator", 3 | "version": "1.0.2", 4 | "description": "A contextual paginator on top of react and bootstrap", 5 | "main": "lib/Paginator.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "example:es6": "PORT=8080 webpack-dev-server --history-api-fallback", 9 | "example:es6:build":"webpack", 10 | "prepublish": "npm run pre:babel && npm run pre:bundle && npm run pre:uglify", 11 | "pre:babel": "babel ./src --out-dir ./lib --source-maps --presets es2015,react --plugins babel-plugin-add-module-exports --copy-files", 12 | "pre:bundle": "browserify -t browserify-css -t browserify-global-shim ./lib/Paginator.js -o ./build/react-paginator.js --standalone ReactPaginator", 13 | "pre:uglify": "uglifyjs ./build/react-paginator.js --compress --mangle --output ./build/react-paginator.min.js --source-map ./build/react-paginator.min.js.map" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/drFabio/reactBootstrapPaginator.git" 18 | }, 19 | "keywords": [ 20 | "react", 21 | "bootstrap", 22 | "paginator" 23 | ], 24 | "author": { 25 | "name": "Fabio Oliveira Costa", 26 | "email": "" 27 | }, 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/drFabio/reactBootstrapPaginator/issues" 31 | }, 32 | "homepage": "https://github.com/drFabio/reactBootstrapPaginator#readme", 33 | "devDependencies": { 34 | "babel-cli": "^6.5.1", 35 | "babel-core": "^6.5.2", 36 | "babel-loader": "^6.2.2", 37 | "babel-plugin-add-module-exports": "^0.1.2", 38 | "babel-preset-es2015": "^6.5.0", 39 | "babel-preset-react": "^6.5.0", 40 | "babelify": "^7.2.0", 41 | "browserify": "^13.0.0", 42 | "browserify-css": "^0.9.0", 43 | "browserify-global-shim": "^1.0.3", 44 | "uglify-js": "^2.6.2", 45 | "extract-text-webpack-plugin": "^1.0.1", 46 | "html-webpack-plugin": "^2.8.1", 47 | "webpack": "^1.12.13", 48 | "webpack-dev-server": "^1.14.1", 49 | "webpack-merge": "^0.7.3", 50 | "node-sass": "^3.4.2", 51 | "sass-loader": "^3.1.2", 52 | "style-loader": "^0.13.0" 53 | }, 54 | "dependencies": { 55 | "react": "^0.14.7" 56 | }, 57 | "browserify-global-shim": { 58 | "react": "React" 59 | }, 60 | "browserify-css": { 61 | "autoInject": true, 62 | "minify": true, 63 | "rootDir": "." 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const webpack = require("webpack"); 5 | const path = require("path"); 6 | const merge = require('webpack-merge'); 7 | const PATHS = { 8 | app: path.join(__dirname, 'examples/es6/src/main.jsx'), 9 | build: path.join(__dirname, 'examples/es6/public/') 10 | }; 11 | 12 | const common = { 13 | entry: PATHS.app, 14 | devtool: 'source-map', 15 | output: { 16 | filename: 'resources/bundle.js', 17 | path: PATHS.build, 18 | sourceMapFilename: 'resources/[file].map' 19 | 20 | }, 21 | module: { 22 | loaders: [ 23 | { 24 | test: /\.jsx?$/, 25 | exclude: /(node_modules|bower_components)/, 26 | loader: 'babel-loader', 27 | query: { 28 | presets: ['react', 'es2015'] //Babel transformation usually on .babelrc 29 | } 30 | }, 31 | { 32 | test: /\.scss$/, 33 | loaders: ["style", "css", "sass?includePaths[]="+ path.resolve(__dirname, 'app/src/styles/')] 34 | }, 35 | { 36 | test: /\.css$/, 37 | loaders: ["style", "css"] 38 | }, 39 | ] 40 | }, 41 | resolve: { 42 | extensions: ['', '.js', '.jsx'] 43 | }, 44 | 'plugins':[ 45 | new HtmlWebpackPlugin({ 46 | template: 'examples/es6/src/index.tpl.html', 47 | inject: 'body', 48 | filename: 'index.html' 49 | }) 50 | ] 51 | } 52 | const TARGET = process.env.npm_lifecycle_event; 53 | 54 | if(TARGET === 'example:es6' || !TARGET) { 55 | let config = { 56 | //Data that dev server will consume 57 | devServer: { 58 | contentBase: PATHS.build, 59 | 60 | // Enable history API fallback so HTML5 History API based 61 | // routing works. This is a good default that will come 62 | // in handy in more complicated setups. 63 | historyApiFallback: true, 64 | hot: true, 65 | inline: true, 66 | progress: true, 67 | 68 | // Display only errors to reduce the amount of output. 69 | stats: 'errors-only', 70 | 71 | // Parse host and port from env so this is easy to customize. 72 | // 73 | // If you use Vagrant or Cloud9, set 74 | // host: process.env.HOST || '0.0.0.0'; 75 | // 76 | // 0.0.0.0 is available to all network devices unlike default 77 | // localhost 78 | host: process.env.HOST || '0.0.0.0', 79 | port: process.env.PORT || '8080' 80 | }, 81 | 'plugins':[ 82 | new webpack.HotModuleReplacementPlugin() 83 | ] 84 | }; 85 | module.exports = merge(common, config); 86 | } 87 | else if(TARGET === 'build') { 88 | module.exports = common; 89 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # reactBootstrapPaginator 2 | A contextual paginator on top of react and bootstrap 3 | ## Installation 4 | ```shell 5 | npm install react_bootstrap_paginator 6 | ``` 7 | ## What do you mean with contextual paginator? 8 | 9 | I mean that it's presentation will change according to the context. 10 | 11 | If you have the pages 1-10 , are on the first one and want to show 10 pages it will look like this: 12 | ![1_to_10](https://cloud.githubusercontent.com/assets/2636143/13376102/9acd464c-dd90-11e5-9e18-2035c6a12b95.png) 13 | 14 | **Notice no arrow or dots indicating more** 15 | 16 | On 1-50 and you are on page 30 it would look like this: 17 | 18 | ![1-50](https://cloud.githubusercontent.com/assets/2636143/13376100/9ac9a96a-dd90-11e5-9774-0f48a88fb999.png) 19 | 20 | **Notice both arrows , dots indicating more pages** 21 | 22 | And if you are on the last page it will look like this: 23 | 24 | ![end](https://cloud.githubusercontent.com/assets/2636143/13376101/9acc64c0-dd90-11e5-9655-a30c765d8d6c.png) 25 | 26 | **Notice no right arrow and no right dots** 27 | ## Usage ES5 standalone 28 | I have a codepen example [here](http://codepen.io/drFabio/pen/yOemVV) 29 | ```html 30 | 31 | 32 | 33 | 34 | Reacomponents - Paginator ES5 35 | 36 | 37 | 38 |
    39 | 40 | 41 | 42 | 43 | 44 | 59 | 60 | 61 | ``` 62 | 63 | ## Usage ES6 64 | ```es6 65 | import Paginator from '../../../src/Paginator.jsx'; 66 | import React from 'react'; 67 | import ReactDOM from 'react-dom'; 68 | const App = React.createClass({ 69 | pages:{ 70 | current: 10, 71 | total: 1000 72 | }, 73 | pageClick(page){ 74 | console.log("I should do something regarding page "+page); 75 | }, 76 | render(){ 77 | return( 78 | 79 | ) 80 | } 81 | }); 82 | ReactDOM.render(, document.getElementById('the_paginator')); 83 | ``` 84 | -------------------------------------------------------------------------------- /lib/Paginator.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/Paginator.jsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;AAIA,IAAM,YAAY,gBAAM,WAAN,CAAkB;;AAChC,gDAAiB;AACb,eAAO;AACL,iBAAK,EAAL;AACA,qBAAS,CAAT;SAFF,CADa;KADe;AAQhC,8BAAQ;;;AACJ,YAAI,UAAU,KAAK,KAAL,CAAW,OAAX,CADV;AAEJ,YAAI,QAAQ,KAAK,KAAL,CAAW,KAAX,CAFR;AAGJ,YAAI,MAAM,KAAK,KAAL,CAAW,GAAX,CAHN;;AAKJ,YAAI,QAAQ,KAAK,GAAL,CAAS,UAAU,KAAK,KAAL,CAAW,MAAI,CAAJ,CAArB,EAA6B,CAAtC,CAAR,CALA;;AAOJ,YAAI,MAAM,KAAK,GAAL,CAAS,QAAM,GAAN,EAAU,KAAnB,CAAN,CAPA;AAQJ,YAAG,MAAM,KAAN,GAAc,GAAd,EAAmB;AAClB,oBAAQ,KAAK,GAAL,CAAS,CAAT,EAAW,MAAM,GAAN,CAAnB,CADkB;SAAtB;AAGA,YAAI,UAAU,IAAV,CAXA;AAYJ,YAAI,WAAW,IAAX,CAZA;AAaJ,YAAG,SAAS,CAAT,EAAW;AACV,sBACI;;;gBAAK;;;;iBAAL;aADJ,CADU;AAIV,uBACI;;;gBACE;;sBAAG,MAAK,oBAAL,EAAH;oBACE,wCAAM,WAAU,kCAAV,EAA6C,SAAS,iBAAC,CAAD;mCAAK,MAAK,KAAL,CAAW,MAAX,CAAkB,UAAQ,CAAR;yBAAvB,EAA5D,CADF;iBADF;aADJ,CAJU;SAAd;AAYA,YAAI,UAAS,IAAT,CAzBA;AA0BJ,YAAI,OAAO,IAAP,CA1BA;AA2BJ,YAAG,MAAI,KAAJ,EAAU;AACT,sBACI;;;gBAAK;;;;iBAAL;aADJ,CADS;AAIT,mBACI;;;gBACI;;sBAAG,MAAK,oBAAL,EAAH;oBACI,wCAAM,WAAU,mCAAV,EAA8C,SAAS,iBAAC,CAAD;mCAAK,MAAK,KAAL,CAAW,MAAX,CAAkB,UAAQ,CAAR;yBAAvB,EAA7D,CADJ;iBADJ;aADJ,CAJS;SAAb;AAYA,YAAI,WAAU,SAAV,QAAU,CAAC,KAAD,EAAO,GAAP,EAAa;AACvB,gBAAM,QAAQ,EAAR,CADiB;;uCAEf;AACJ,oBAAI,YAAY,KAAG,OAAH,GAAW,QAAX,GAAoB,EAApB;AAChB,sBAAM,IAAN,CAAW;;sBAAI,KAAK,CAAL,EAAQ,WAAW,SAAX,EAAZ;oBAAkC;;0BAAG,MAAK,oBAAL,EAA0B,SAAS,iBAAC,CAAD;uCAAK,MAAK,KAAL,CAAW,MAAX,CAAkB,CAAlB;6BAAL,EAAtC;wBAAkE,CAAlE;qBAAlC;iBAAX;cAJmB;;AAEvB,iBAAI,IAAI,IAAE,KAAF,EAAQ,KAAG,GAAH,EAAO,GAAvB,EAA2B;sBAAnB,GAAmB;aAA3B;AAIA,mBAAO,KAAP,CANuB;SAAb,CAvCV;AA+CJ,eACI;;cAAK,WAAU,aAAV,EAAL;YACI;;kBAAI,WAAU,YAAV,EAAJ;gBACK,QADL;gBAEK,OAFL;gBAGK,SAAS,KAAT,EAAe,GAAf,CAHL;gBAIK,OAJL;gBAKK,IALL;aADJ;SADJ,CA/CI;KARwB;CAAlB,CAAZ;AAoEN,QAAQ,iBAAR;kBACgB","file":"Paginator.js","sourcesContent":["'use strict';\n\nimport React from 'react';\n\nconst Paginator = React.createClass({\n getDefaultProps(){\n return {\n max: 10,\n current: 1\n }\n }, \n\n render(){\n let current = this.props.current;\n let total = this.props.total;\n let max = this.props.max;\n\n let start = Math.max(current - Math.round(max/2) ,1);\n\n let end = Math.min(start+max,total);\n if(end - start < max) {\n start = Math.max(1,end - max);\n }\n let hasLess = null;\n let previous = null;\n if(start != 1){\n hasLess = (\n
  • ...
  • \n );\n previous = (\n
  • \n \n this.props.onPage(current-1)}>\n \n
  • \n );\n }\n let hasMore =null;\n let next = null;\n if(end...\n );\n next = (\n
  • \n \n this.props.onPage(current+1)}>\n \n
  • \n );\n }\n let getLinks= (start,end)=>{\n const links = [];\n for(let i=start;i<=end;i++){\n let className = i==current?'active':'';\n links.push(
  • this.props.onPage(i)}>{i}
  • );\n }\n return links;\n };\n return(\n
    \n
      \n {previous}\n {hasLess}\n {getLinks(start,end)}\n {hasMore}\n {next}\n
    \n
    \n )\n }\n})\nrequire('./paginator.css');\nexport default Paginator;"]} -------------------------------------------------------------------------------- /lib/Paginator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _react = require('react'); 8 | 9 | var _react2 = _interopRequireDefault(_react); 10 | 11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 12 | 13 | var Paginator = _react2.default.createClass({ 14 | displayName: 'Paginator', 15 | getDefaultProps: function getDefaultProps() { 16 | return { 17 | max: 10, 18 | current: 1 19 | }; 20 | }, 21 | render: function render() { 22 | var _this = this; 23 | 24 | var current = this.props.current; 25 | var total = this.props.total; 26 | var max = this.props.max; 27 | 28 | var start = Math.max(current - Math.round(max / 2), 1); 29 | 30 | var end = Math.min(start + max, total); 31 | if (end - start < max) { 32 | start = Math.max(1, end - max); 33 | } 34 | var hasLess = null; 35 | var previous = null; 36 | if (start != 1) { 37 | hasLess = _react2.default.createElement( 38 | 'li', 39 | null, 40 | _react2.default.createElement( 41 | 'a', 42 | null, 43 | '...' 44 | ) 45 | ); 46 | previous = _react2.default.createElement( 47 | 'li', 48 | null, 49 | _react2.default.createElement( 50 | 'a', 51 | { href: 'javascript:void(0)' }, 52 | _react2.default.createElement('span', { className: 'glyphicon glyphicon-chevron-left', onClick: function onClick(e) { 53 | return _this.props.onPage(current - 1); 54 | } }) 55 | ) 56 | ); 57 | } 58 | var hasMore = null; 59 | var next = null; 60 | if (end < total) { 61 | hasMore = _react2.default.createElement( 62 | 'li', 63 | null, 64 | _react2.default.createElement( 65 | 'a', 66 | null, 67 | '...' 68 | ) 69 | ); 70 | next = _react2.default.createElement( 71 | 'li', 72 | null, 73 | _react2.default.createElement( 74 | 'a', 75 | { href: 'javascript:void(0)' }, 76 | _react2.default.createElement('span', { className: 'glyphicon glyphicon-chevron-right', onClick: function onClick(e) { 77 | return _this.props.onPage(current + 1); 78 | } }) 79 | ) 80 | ); 81 | } 82 | var getLinks = function getLinks(start, end) { 83 | var links = []; 84 | 85 | var _loop = function _loop(i) { 86 | var className = i == current ? 'active' : ''; 87 | links.push(_react2.default.createElement( 88 | 'li', 89 | { key: i, className: className }, 90 | _react2.default.createElement( 91 | 'a', 92 | { href: 'javascript:void(0)', onClick: function onClick(e) { 93 | return _this.props.onPage(i); 94 | } }, 95 | i 96 | ) 97 | )); 98 | }; 99 | 100 | for (var i = start; i <= end; i++) { 101 | _loop(i); 102 | } 103 | return links; 104 | }; 105 | return _react2.default.createElement( 106 | 'div', 107 | { className: 'text-center' }, 108 | _react2.default.createElement( 109 | 'ul', 110 | { className: 'pagination' }, 111 | previous, 112 | hasLess, 113 | getLinks(start, end), 114 | hasMore, 115 | next 116 | ) 117 | ); 118 | } 119 | }); 120 | require('./paginator.css'); 121 | exports.default = Paginator; 122 | module.exports = exports['default']; 123 | //# sourceMappingURL=Paginator.js.map --------------------------------------------------------------------------------