Skip to content

Commit

Permalink
feat(community-pagination): creating pagination component
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-bunce authored and theetrain committed Apr 17, 2019
1 parent 4641ad0 commit 9ffeae9
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 0 deletions.
150 changes: 150 additions & 0 deletions packages/Pagination/Pagination.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'

import safeRest from '@tds/shared-safe-rest'
import DecorativeIcon from '@tds/core-decorative-icon'
import Panels from './Panels'
import Panel from './Panel/Panel'
import styles from './Pagination.scss'

/**
* @version ./package.json
*/
class Pagination extends Component {
constructor(props) {
super(props)
this.state = {
current: 1,
panels: this.props.children.length,
showPrevious: false,
showNext: true,
}
this.mapNumeric = this.mapNumeric.bind(this)
this.handleButtonState = this.handleButtonState.bind(this)
this.handleClick = this.handleClick.bind(this)
}

componentDidMount() {
this.handleButtonState()
}

generateKey = pre => {
return `${pre}_${new Date().getTime()}`
}

mapNumeric = () => {
return this.props.children.map((item, i) => {
const index = i + 1
let { current } = this.state
const { panels } = this.state
current = parseInt(current, 10) || 0
if (current === index) {
return (
<li key={this.generateKey(i)} className={styles.current}>
{index}
</li>
)
}

if (panels < 7 || index === 1 || index === panels) {
return (
<li key={this.generateKey(i)} className={styles.regular}>
<button value={index} onClick={e => this.handleClick(e)}>
{index}
</button>
</li>
)
}
if (
index === current ||
index === current + 1 ||
index === current - 1 ||
(current < 3 && index < 5) ||
(current > panels - 2 && index > panels - 4)
) {
return (
<li key={this.generateKey(i)} className={styles.regular}>
<button value={index} onClick={e => this.handleClick(e)}>
{index}
</button>
</li>
)
}
if (
index === current - 2 ||
index === current + 2 ||
(current < 3 && index === 5) ||
(current > panels - 2 && index === panels - 5)
) {
return (
<li key={this.generateKey(i)} className={styles.ellipsis}>
...
</li>
)
}

return null
})
}

handleClick = e => {
e.preventDefault()
const value = parseInt(e.target.value, 10) || 0
if (value > this.state.panels || value < 1) {
return null
}
return this.setState({ current: value }, this.handleButtonState)
}

handleButtonState = () => {
if (this.state.current !== 1) {
this.setState({ showPrevious: true })
} else {
this.setState({ showPrevious: false })
}
if (this.state.current !== this.state.panels) {
this.setState({ showNext: true })
} else {
this.setState({ showNext: false })
}
}

render() {
const { children, ...rest } = this.props
const { current } = this.state
const increaseNumber = parseInt(current + 1, 10)
const decreaseNumber = parseInt(current - 1, 10)
return (
<div {...safeRest(rest)} className={styles.container}>
<Panels {...rest} key={this.generateKey(current)}>
{children[current - 1] && children[current - 1]}
</Panels>
<div className={styles.controls}>
{this.state.showPrevious && (
<p className={styles.previous}>
<button value={decreaseNumber} onClick={e => this.handleClick(e)}>
<DecorativeIcon symbol="leftChevron" /> Previous
</button>
</p>
)}
<ul className={styles.pagination}>{this.mapNumeric()}</ul>
{this.state.showNext && (
<p className={styles.next}>
<button value={increaseNumber} onClick={e => this.handleClick(e)}>
Next <DecorativeIcon symbol="chevron" />
</button>
</p>
)}
</div>
</div>
)
}
}

Pagination.propTypes = {
children: PropTypes.node.isRequired,
}

Pagination.Panel = Panel

export default Pagination
17 changes: 17 additions & 0 deletions packages/Pagination/Pagination.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```jsx
<Pagination>
<Pagination.Panel>Content 1</Pagination.Panel>
<Pagination.Panel>Content 2</Pagination.Panel>
<Pagination.Panel>Content 3</Pagination.Panel>
<Pagination.Panel>Content 4</Pagination.Panel>
<Pagination.Panel>Content 5</Pagination.Panel>
<Pagination.Panel>Content 6</Pagination.Panel>
<Pagination.Panel>Content 7</Pagination.Panel>
<Pagination.Panel>Content 8</Pagination.Panel>
<Pagination.Panel>
<div>
<p>This is a paragraph on the 9th panel</p>
</div>
</Pagination.Panel>
</Pagination>
```
3 changes: 3 additions & 0 deletions packages/Pagination/Pagination.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.container {
opacity: 1;
}
1 change: 1 addition & 0 deletions packages/Pagination/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TDS Community: Pagination
47 changes: 47 additions & 0 deletions packages/Pagination/__tests__/Pagination.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react'
import { mount } from 'enzyme'

import Pagination from '../Pagination'

describe('Pagination', () => {
const children = (
<Pagination>
<Pagination.Panel>Content 1</Pagination.Panel>
<Pagination.Panel>Content 2</Pagination.Panel>
<Pagination.Panel>Content 3</Pagination.Panel>
<Pagination.Panel>Content 4</Pagination.Panel>
<Pagination.Panel>Content 5</Pagination.Panel>
<Pagination.Panel>Content 6</Pagination.Panel>
<Pagination.Panel>Content 7</Pagination.Panel>
<Pagination.Panel>Content 8</Pagination.Panel>
<Pagination.Panel>
<div>
<p>This is a paragraph on the 9th panel</p>
</div>
</Pagination.Panel>
</Pagination>
)
const doMount = () => mount(children)

it('renders', () => {
const pagination = doMount()

expect(pagination).toMatchSnapshot()
})

it('does other things', () => {
const pagination = doMount()

expect(pagination).toExist()
})

it('does not allow custom CSS', () => {
const pagination = doMount({
className: 'my-custom-class',
style: { color: 'hotpink' },
})

expect(pagination).not.toHaveProp('className', 'my-custom-class')
expect(pagination).not.toHaveProp('style')
})
})
4 changes: 4 additions & 0 deletions packages/Pagination/index.cjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require('./dist/index.css')
const Pagination = require('./dist/index.cjs')

module.exports = Pagination
4 changes: 4 additions & 0 deletions packages/Pagination/index.es.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './dist/index.css'
import Pagination from './dist/index.es'

export default Pagination
32 changes: 32 additions & 0 deletions packages/Pagination/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@tds/community-pagination",
"version": "1.0.0-preview",
"description": "",
"main": "index.cjs.js",
"module": "index.es.js",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/telus/tds-community.git"
},
"publishConfig": {
"access": "public"
},
"author": "TELUS digital",
"engines": {
"node": ">=8"
},
"bugs": {
"url": "https://github.com/telus/tds-community/issues"
},
"homepage": "http://tds.telus.com",
"peerDependencies": {
"react": ">=15",
"react-dom": ">=15"
},
"dependencies": {
"@tds/shared-safe-rest": "^1.0.0",
"pagination": "^0.4.6",
"prop-types": "^15.6.2"
}
}
7 changes: 7 additions & 0 deletions packages/Pagination/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import configure from '../../config/rollup.config'
import { dependencies } from './package.json'

export default configure({
input: './Pagination.jsx',
dependencies,
})

0 comments on commit 9ffeae9

Please sign in to comment.