Skip to content

Commit db59f48

Browse files
authored
Merge pull request #23 from chrismanciero/pagination-component
Pagination control
2 parents 14cf99a + 3424292 commit db59f48

File tree

4 files changed

+275
-2
lines changed

4 files changed

+275
-2
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import React from 'react';
2+
import {
3+
DocsTile,
4+
DocsText,
5+
Separator,
6+
Header,
7+
Description,
8+
Import,
9+
Properties,
10+
Pagination
11+
} from '../';
12+
13+
export const PaginationComponent = () => {
14+
const handleClick = event => {
15+
console.log(`Page clicked - ${event}`);
16+
};
17+
return (
18+
<div>
19+
<Header>Pagination</Header>
20+
<Description>
21+
Pagination is commonly used for tables and tiles. It allows users to see
22+
how many pages of content exist, to navigate and highlights which page
23+
they are currently viewing. This control does not handle how many tiles
24+
or rows to display in a table. This control simply adds a nice user
25+
experience to handle how to navigate through a collection. The handling
26+
of which items to display needs to be handled in the function that is
27+
passed in the onClick method of the Pagination control.
28+
</Description>
29+
<Import module="Pagination" path="/fundamental-react/src/" />
30+
31+
<Separator />
32+
33+
<Properties
34+
type="Inputs"
35+
properties={[
36+
{
37+
name: 'itemsTotal',
38+
description:
39+
'Number (required) - Total number of items. itemsTotal / itemsPerPage calculates how many navigation items should be shown in the control.'
40+
},
41+
{
42+
name: 'onClick',
43+
description:
44+
'Func (required) - Function to execute on click of page number, previous or next indicator. Page number value is sent to function.'
45+
},
46+
{
47+
name: 'itemsPerPage',
48+
description:
49+
'Number (default: 10) - Number of items to display on page.'
50+
},
51+
{
52+
name: 'initialPage',
53+
description:
54+
'Number (default: page 1) - Initial page to be selected.'
55+
},
56+
{
57+
name: 'displayTotal',
58+
description:
59+
'Boolean (default: true) - Boolean value for whether or not to show total number of items. true - show total number and totalText string, false - hide total number and totalText string.'
60+
},
61+
{
62+
name: 'totalText',
63+
description:
64+
'String (default: "items") - String to display next to the total number of items.'
65+
}
66+
]}
67+
/>
68+
69+
<Separator />
70+
71+
<h2>First Page</h2>
72+
<Description>
73+
When the first page is active, the Back arrow should be disabled.
74+
</Description>
75+
<DocsTile>
76+
<Pagination itemsTotal={101} onClick={handleClick} />
77+
</DocsTile>
78+
<DocsText
79+
>{`<Pagination itemsTotal={101} onClick={handleClick}/>`}</DocsText>
80+
<Separator />
81+
82+
<h2>Last Page</h2>
83+
<Description>
84+
When the last page is active, the Next arrow should be disabled.
85+
</Description>
86+
<DocsTile>
87+
<Pagination itemsTotal={101} initialPage={11} onClick={handleClick} />
88+
</DocsTile>
89+
<DocsText
90+
>{`<Pagination itemsTotal={101} initalPage={11} onClick={handleClick}/>`}</DocsText>
91+
<Separator />
92+
93+
<h2>Items per Page</h2>
94+
<Description>Set how many items per page.</Description>
95+
<DocsTile>
96+
<Pagination
97+
itemsTotal={101}
98+
itemsPerPage={25}
99+
displayTotal={false}
100+
onClick={handleClick}
101+
/>
102+
</DocsTile>
103+
<DocsText
104+
>{`<Pagination itemsTotal={101} itemsPerPage={25} displayTotal={false} onClick={handleClick}/>`}</DocsText>
105+
106+
<Separator />
107+
108+
<h2>Set Initial Page</h2>
109+
<Description>Set initial page to be selected</Description>
110+
<DocsTile>
111+
<Pagination itemsTotal={101} initialPage={6} onClick={handleClick} />
112+
</DocsTile>
113+
<DocsText
114+
>{`<Pagination itemsTotal={101} initalPage={6} onClick={handleClick}/>`}</DocsText>
115+
<Separator />
116+
117+
<h2>Hide Total</h2>
118+
<Description>
119+
Only show page numbers, Previous and Next controls
120+
</Description>
121+
<DocsTile>
122+
<Pagination
123+
itemsTotal={101}
124+
displayTotal={false}
125+
onClick={handleClick}
126+
/>
127+
</DocsTile>
128+
<DocsText
129+
>{`<Pagination itemsTotal={101} displayTotal={false} onClick={handleClick}/>`}</DocsText>
130+
<Separator />
131+
132+
<h2>Total Text</h2>
133+
<Description>Customize text to show next to item total</Description>
134+
<DocsTile>
135+
<Pagination
136+
itemsTotal={101}
137+
onClick={handleClick}
138+
totalText="Dalmations"
139+
/>
140+
</DocsTile>
141+
<DocsText
142+
>{`<Pagination itemsTotal={101} totalText="Dalmations" onClick={handleClick}/>`}</DocsText>
143+
<Separator />
144+
</div>
145+
);
146+
};

src/Pagination/Pagination.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import React, { Component } from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
export class Pagination extends Component {
5+
constructor(props, context) {
6+
super(props, context);
7+
8+
this.state = {
9+
selectedPage: this.props.initialPage || 1
10+
};
11+
}
12+
13+
// number of pages to show
14+
numberOfPages = 0;
15+
16+
// page directly clicked
17+
pageClicked = event => {
18+
this.setState(
19+
{
20+
selectedPage: +event.target.text
21+
},
22+
() => this.props.onClick(this.state.selectedPage)
23+
);
24+
};
25+
26+
// advance to previous page
27+
navigateBack = () => {
28+
if (this.state.selectedPage === 1) {
29+
return;
30+
}
31+
32+
this.setState(
33+
prevState => {
34+
selectedPage: prevState.selectedPage--;
35+
},
36+
() => this.props.onClick(this.state.selectedPage)
37+
);
38+
};
39+
40+
// advance to next page
41+
navigateForward = () => {
42+
if (this.state.selectedPage === this.numberOfPages) {
43+
return;
44+
}
45+
46+
this.setState(
47+
prevState => {
48+
selectedPage: prevState.selectedPage++;
49+
},
50+
() => this.props.onClick(this.state.selectedPage)
51+
);
52+
};
53+
54+
// create pagination links
55+
createPaginationLinks = (numberOfPages = 1, initialPage = 1) => {
56+
// create an array with number of pages and fill it with links
57+
const aPages = Array(numberOfPages)
58+
.fill()
59+
.map((link, index) => (
60+
<a
61+
key={index}
62+
href="#"
63+
className="fd-pagination__link"
64+
aria-selected={this.state.selectedPage === index + 1}
65+
onClick={this.pageClicked}
66+
>
67+
{index + 1}
68+
</a>
69+
));
70+
return aPages;
71+
};
72+
73+
render() {
74+
const {
75+
itemsTotal,
76+
itemsPerPage = 10,
77+
initialPage,
78+
displayTotal = true,
79+
totalText
80+
} = this.props;
81+
82+
// calculate number of pages based on item total and items per page
83+
this.numberOfPages = Math.ceil(itemsTotal / itemsPerPage);
84+
85+
return (
86+
<div className="fd-pagination">
87+
{displayTotal ? (
88+
<span className="fd-pagination__total">
89+
{itemsTotal} {totalText || 'items'}
90+
</span>
91+
) : (
92+
''
93+
)}
94+
95+
<nav className="fd-pagination__nav">
96+
<a
97+
href="#"
98+
className="fd-pagination__link fd-pagination__link--previous"
99+
aria-label="Previous"
100+
aria-disabled={this.state.selectedPage === 1}
101+
onClick={this.navigateBack}
102+
/>
103+
{this.createPaginationLinks(this.numberOfPages, initialPage)}
104+
<a
105+
href="#"
106+
className="fd-pagination__link fd-pagination__link--next"
107+
aria-label="Next"
108+
aria-disabled={this.state.selectedPage === this.numberOfPages}
109+
onClick={this.navigateForward}
110+
/>
111+
</nav>
112+
</div>
113+
);
114+
}
115+
}
116+
117+
Pagination.propTypes = {
118+
itemsPerPage: PropTypes.number.isRequired,
119+
itemsTotal: PropTypes.number.isRequired,
120+
onClick: PropTypes.func.isRequired,
121+
initialPage: PropTypes.number,
122+
displayTotal: PropTypes.bool,
123+
totalText: PropTypes.string
124+
};

src/Routes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { Component } from 'react';
22
import { BrowserRouter, Route, Switch, Link, NavLink } from 'react-router-dom';
33

4-
54
import { ActionBarComponent } from './ActionBar/ActionBar.Component';
65
import { AlertComponent } from './Alert/Alert.Component';
76
import { BadgeComponent } from './Badge/Badge.Component';
@@ -19,6 +18,7 @@ import { InputGroupComponent } from './InputGroup/InputGroup.Component';
1918
import { ListGroupComponent } from './ListGroup/ListGroup.Component';
2019
import { MegaMenuComponent } from './MegaMenu/MegaMenu.Component';
2120
import { MenuComponent } from './Menu/Menu.Component';
21+
import { PaginationComponent } from './Pagination/Pagination.Component'
2222
import { SideNavigationComponent } from './SideNavigation/SideNavigation.Component';
2323
import { TableComponent } from './Table/Table.Component';
2424
import { TabsComponent } from './Tabs/Tabs.Component';
@@ -49,6 +49,7 @@ export default class Routes extends Component {
4949
{ url: '/listGroup', name: 'List Group', component: ListGroupComponent },
5050
{ url: '/megaMenu', name: 'Mega Menu', component: MegaMenuComponent },
5151
{ url: '/menu', name: 'Menu', component: MenuComponent },
52+
{ url: '/pagination', name: 'Pagination', component: PaginationComponent },
5253
{ url: '/sideNavigation', name: 'Side Navigation', component: SideNavigationComponent },
5354
{ url: '/table', name: 'Table', component: TableComponent },
5455
{ url: '/tabs', name: 'Tabs', component: TabsComponent },

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {InputGroup, FormGroup } from '../src/InputGroup/InputGroup'
2121
import {ListGroup, ListGroupItem, ListGroupItemActions, ListGroupItemCheckbox } from '../src/ListGroup/ListGroup'
2222
import {MegaMenu, MegaMenuList, MegaMenuGroup} from '../src/MegaMenu/MegaMenu'
2323
import {Menu, MenuList, MenuItem, MenuGroup} from '../src/Menu/Menu'
24+
import {Pagination} from '../src/Pagination/Pagination'
2425
import {SideNav, SideNavList, SideNavItem, SideNavGroup} from '../src/SideNavigation/SideNavigation'
2526
import {Table} from '../src/Table/Table'
2627
import {Tabs, TabComponent} from '../src/Tabs/Tabs'
@@ -87,7 +88,8 @@ export {
8788
Menu,
8889
MenuList,
8990
MenuItem,
90-
MenuGroup,
91+
MenuGroup,
92+
Pagination,
9193
SideNav,
9294
SideNavList,
9395
SideNavItem,

0 commit comments

Comments
 (0)