Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.

feat(controls): add pagination controls #12

Merged
merged 6 commits into from
Feb 22, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/components/PaginationControl.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from 'react'
import Flexbox from 'flexbox-react'
import '../styles/components/pagination-control.css'
class PaginationControl extends React.Component {
constructor (props) {
super(props)
this.state = {
isPrevPageValid: false,
isNextPageValid: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is fine, just brainstorming. both of these ^^ are derived state. hence, something akin to get isPrevPageValid () { this.state.currentPage > 1 } and the like could feasibly 🔥 down some code! no action requested. just talkin :)

currentPage: 1,
totalItems: props.totalItems,
lastPage: Math.ceil(props.totalItems / props.perPage)
}
this.nextPage = this.nextPage.bind(this)
this.prevPage = this.prevPage.bind(this)
this.validatePage = this.validatePage.bind(this)
this.resetPagination = this.resetPagination.bind(this)
}

componentWillReceiveProps (nextProps) {
if (nextProps.perPage !== this.props.perPage) {
this.resetPagination()
}
}

resetPagination () {
this.setState({
currentPage: 1,
isPrevPageValid: false,
isNextPageValid: true
})
}

nextPage () {
if (this.props.controlsDisabled) {
return false
}
if (this.state.isNextPageValid) {
const currentPage = this.state.currentPage
this.props.navigateToPage(currentPage + 1)
this.setState({ currentPage: currentPage + 1 }, this.validatePage)
}
return false
}

prevPage () {
if (this.props.controlsDisabled) {
return false
}
if (this.state.isPrevPageValid) {
const currentPage = this.state.currentPage
this.props.navigateToPage(currentPage - 1)
this.setState({ currentPage: currentPage - 1 }, this.validatePage)
}
return false
}

validatePage () {
const currentPage = this.state.currentPage
this.setState({
isNextPageValid: currentPage < this.state.lastPage,
isPrevPageValid: currentPage > 1
})
}

render () {
let disabledClass = ''
if (this.props.controlsDisabled) {
disabledClass = 'disabled'
}
let currentCount = this.state.currentPage * this.props.perPage > this.state.totalItems ? this.state.totalItems : this.state.currentPage * this.props.perPage
return (
<Flexbox flexDirection='row' className='consoles__pagination'>
<Flexbox className={`pagination__button pagination__prev ${disabledClass} ${this.state.isPrevPageValid ? '' : 'disabled'}`} onClick={this.prevPage}>
<i className='arrow_carrot-left' aria-hidden='true' />
</Flexbox>
<Flexbox className='pagination__count' alignItems='center'>
<span className='count__current'>{currentCount}</span>
<span>of</span>
<span className='count__total'>{this.state.totalItems}</span>
</Flexbox>
<Flexbox className={`pagination__button pagination__next ${disabledClass} ${this.state.isNextPageValid ? '' : 'disabled'}`} onClick={this.nextPage}>
<i className='arrow_carrot-right' aria-hidden='true' />
</Flexbox>
</Flexbox>

)
}
}

PaginationControl.propTypes = {
totalItems: React.PropTypes.number.isRequired,
navigateToPage: React.PropTypes.func.isRequired,
perPage: React.PropTypes.number.isRequired,
controlsDisabled: React.PropTypes.bool
}

export default PaginationControl
59 changes: 59 additions & 0 deletions src/styles/components/pagination-control.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
@import '../variables.css';
.consoles__pagination {

& .pagination__button {
border: 1px solid var(--buttonBorder);
color: var(--twgray);
cursor: pointer;
display: inline-block;
padding: 0px;
font-size: 2em;
height: 30px;
}
& .pagination__button:active{
border: 1px solid var(--blue);
color: white !important;
background-color: var(--blue);
}
& .pagination__button:hover{
border: 1px solid var(--blue);
color: var(--blue);

}
& .pagination__button.disabled {
border: 1px solid var(--lightgray);
color: var(--lightgray) !important;
}
& .pagination__button.disabled:active {
background-color: white !important;
border: 1px solid var(--lightgray) !important;
color: var(--lightgray) !important;
}
& .pagination__prev {

}
& .pagination__next {

}
& .pagination__count {
border: 1px solid color(#BBBDBF);
color: color(#586A7B);
font-size: var(--small);
margin-left: 1px;
margin-right: 1px;
padding-left: 4px;
padding-right: 4px;
height: 30px;
text-transform: uppercase;
text-align: center;
& .count__current {
margin-right: 5px;
}
& .count__total {
margin-left: 5px;
}
}
}



90 changes: 90 additions & 0 deletions stories/Welcome.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';

const styles = {
main: {
margin: 15,
maxWidth: 600,
lineHeight: 1.4,
fontFamily: '"Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif',
},

logo: {
width: 200,
},

link: {
color: '#1474f3',
textDecoration: 'none',
borderBottom: '1px solid #1474f3',
paddingBottom: 2,
},

code: {
fontSize: 15,
fontWeight: 600,
padding: "2px 5px",
border: "1px solid #eae9e9",
borderRadius: 4,
backgroundColor: '#f3f2f2',
color: '#3a3a3a',
},

codeBlock: {
backgroundColor: '#f3f2f2',
padding: '1px 10px',
margin: '10px 0',
}
};

const codeBlock = `
// Add this code to "src/stories/index.js"

import '../index.css';
import App from '../App';

storiesOf('App', module)
.add('default view', () => (
&lt;App /&gt;
))
`;

export default class Welcome extends React.Component {
showApp(e) {
e.preventDefault();
if(this.props.showApp) this.props.showApp();
}

render() {
return (
<div style={styles.main}>
<h1>Welcome to STORYBOOK</h1>
<p>
This is a UI component dev environment for your app.
</p>
<p>
We've added some basic stories inside the <code style={styles.code}>src/stories</code> directory.
<br/>
A story is a single state of one or more UI components. You can have as many stories as you want.
<br/>
(Basically a story is like a visual test case.)
</p>
<p>
See these sample <a style={styles.link} href='#' onClick={this.showApp.bind(this)}>stories</a> for a component called <code style={styles.code}>Button</code>.
</p>
<p>
Just like that, you can add your own components as stories.
<br />
Here's how to add your <code style={styles.code}>App</code> component as a story.
<div
style={styles.codeBlock}
dangerouslySetInnerHTML={{__html: `<pre>${codeBlock}</pre>`}}
/>
</p>
<p>
Usually we create stories with smaller UI components in the app.<br />
Have a look at the <a style={styles.link} href="https://getstorybook.io/docs/basics/writing-stories" target="_blank">Writing Stories</a> section in our documentation.
</p>
</div>
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be removed, i think. we already have a Welcome component

48 changes: 44 additions & 4 deletions stories/controls.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { storiesOf } from '@kadira/storybook'
import { Radio, Dropdown, Input, Button, Popup } from 'semantic-ui-react'
import FavoriteButton from '../src/components/FavoriteButton'
import StopStartButton from '../src/components/StopStartButton'
import PaginationControl from '../src/components/PaginationControl'
import '../src/styles/app.css'

const dropdownOptions = [
Expand All @@ -17,9 +18,31 @@ const dropdownOptionsTime = [
{ text: '1m', value: '1m' }
]

const paginationSampleData = [
{ text: '1w', value: '1w' },
{ text: '2w', value: '2w' },
{ text: '1m', value: '1m' },
{ text: '1w', value: '1w' },
{ text: '2w', value: '2w' },
{ text: '1m', value: '1m' },
{ text: '1w', value: '1w' },
{ text: '2w', value: '2w' },
{ text: '1m', value: '1m' },
{ text: '1w', value: '1w' },
{ text: '2w', value: '2w' },
{ text: '1m', value: '1m' },
{ text: '1w', value: '1w' },
{ text: '2w', value: '2w' },
{ text: '1m', value: '1m' }
]

function nextPage(){
console.log('this would handle paginating your content');
}

storiesOf('Interactive Controls', module)
.addDecorator((story) => (
<div style={{maxWidth: '200px', marginTop: '15px', marginLeft: '15px'}}>
<div style={{ marginTop: '15px', marginLeft: '15px'}}>
{story()}
</div>
))
Expand Down Expand Up @@ -86,28 +109,45 @@ storiesOf('Interactive Controls', module)
<div>
<div>
<Input />
<br />
Normal
</div>
<div>
<Input error />
<br />
Error
</div>
<div>
<Input focus />
Focused
<br />
Normal
</div>
<div>
<Input disabled />
disabled
<br />
Disabled
</div>
<div>
<Input
icon='search'
placeholder='Browse / Search: Tag, Group, or Operation'
style={{width: '400px'}}
/>
Search
<br />
Search
</div>
</div>

))
.add('Pagination Controls', () => (
<div>
<PaginationControl
totalItems={paginationSampleData.length}
perPage={5}
navigateToPage={nextPage}
controlsDisabled={false}
/>
</div>

))