+ pushed file browser button branch
parent
9019239f72
commit
089c5b69f7
|
@ -25,4 +25,3 @@ export const TABLE = 'RTTable';
|
|||
export const TABS = 'RTTabs';
|
||||
export const TOOLTIP = 'RTTooltip';
|
||||
export const TIME_PICKER = 'RTTimePicker';
|
||||
export const PAGER = 'RTPager';
|
||||
|
|
|
@ -28,4 +28,3 @@ export Table from './table';
|
|||
export * from './tabs';
|
||||
export Tooltip from './tooltip';
|
||||
export TimePicker from './time_picker';
|
||||
export Pager from './pager';
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
@import "../button/config";
|
||||
|
||||
$button-margin: 0rem .5rem 0rem 0rem !default;
|
|
@ -1,111 +0,0 @@
|
|||
import * as React from "react";
|
||||
import ReactToolbox from "./index";
|
||||
|
||||
export interface PagerTheme {
|
||||
/**
|
||||
* Used for the root element.
|
||||
*/
|
||||
pager?: string;
|
||||
/**
|
||||
* Used for the active page.
|
||||
*/
|
||||
active?: string;
|
||||
/**
|
||||
* Used for the next and previous page buttons.
|
||||
*/
|
||||
leftRightArrowButton?: string;
|
||||
/**
|
||||
* Used for the next and previous range pages buttons.
|
||||
*/
|
||||
leftRightRangeButton?: string;
|
||||
/**
|
||||
* Used for the regular page buttons.
|
||||
*/
|
||||
pagesButton?: string;
|
||||
}
|
||||
|
||||
interface PagerProps extends ReactToolbox.Props {
|
||||
/**
|
||||
* Used for the previous button content.
|
||||
*/
|
||||
prevButtonContent?: string;
|
||||
/**
|
||||
* Used for the left range button content
|
||||
*/
|
||||
rangeLeftButtonContent?: string;
|
||||
/**
|
||||
* Used for the right range button content
|
||||
*/
|
||||
rangeRightButtonContent?: string;
|
||||
/**
|
||||
* Used for the next button content
|
||||
*/
|
||||
nextButtonContent?: string;
|
||||
/**
|
||||
* A Number with the currently selected page
|
||||
*/
|
||||
currentPage?: number;
|
||||
/**
|
||||
* A Number of last page.
|
||||
*/
|
||||
lastPage?: number;
|
||||
/**
|
||||
* A Number of pages visible in control except next, previous and ranges buttons, the minimum value is 2.
|
||||
*/
|
||||
visiblePagesBlockSize?: number;
|
||||
/**
|
||||
* Callback called when the page is changing.
|
||||
*/
|
||||
onPageChange?: Function;
|
||||
/**
|
||||
* Classnames object defining the component style.
|
||||
*/
|
||||
theme?: PagerTheme;
|
||||
/**
|
||||
* This class will be applied to the root elemt.
|
||||
*/
|
||||
pagerClassName?: string;
|
||||
/**
|
||||
* Defining default style of next, previous buttons.
|
||||
* it can have following styles:
|
||||
* accent,
|
||||
* flat,
|
||||
* inverse,
|
||||
* mini,
|
||||
* neutral,
|
||||
* primary,
|
||||
* raised,
|
||||
* toggle
|
||||
*/
|
||||
leftRightArrowButtonTypes?: object;
|
||||
/**
|
||||
* Defining default style of left, right range buttons.
|
||||
* it can have following styles:
|
||||
* accent,
|
||||
* flat,
|
||||
* inverse,
|
||||
* mini,
|
||||
* neutral,
|
||||
* primary,
|
||||
* raised,
|
||||
* toggle
|
||||
*/
|
||||
leftRightRangeButtonTypes?: object;
|
||||
/**
|
||||
* Defining default style of regular page buttons.
|
||||
* it can have following styles:
|
||||
* accent,
|
||||
* flat,
|
||||
* inverse,
|
||||
* mini,
|
||||
* neutral,
|
||||
* primary,
|
||||
* raised,
|
||||
* toggle
|
||||
*/
|
||||
pagesButtonTypes?: object;
|
||||
}
|
||||
|
||||
export class Pager extends React.Component<PagerProps, {}> { }
|
||||
|
||||
export default Pager;
|
|
@ -1,11 +0,0 @@
|
|||
import { themr } from 'react-css-themr';
|
||||
import { PAGER } from '../identifiers.js';
|
||||
import { pagerFactory } from './pager.js';
|
||||
import { Button } from '../button';
|
||||
import theme from './theme.scss';
|
||||
|
||||
const Pager = pagerFactory(Button);
|
||||
|
||||
const ThemedPager = themr(PAGER, theme)(Pager);
|
||||
export default ThemedPager;
|
||||
export { ThemedPager as Pager };
|
|
@ -1,299 +0,0 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { themr } from 'react-css-themr';
|
||||
|
||||
import InjectButton from '../button';
|
||||
import { PAGER } from '../identifiers.js';
|
||||
|
||||
const isOnePage = (first, last) => {
|
||||
return first === last || !last;
|
||||
};
|
||||
|
||||
const isBorderPage = (curr, border) => {
|
||||
return curr === border;
|
||||
};
|
||||
|
||||
const initialVisiblePagesBlockSize = 3;
|
||||
const initialCurrentPage = 1;
|
||||
const first = 1;
|
||||
|
||||
const factory = (Button) => {
|
||||
class Pager extends Component {
|
||||
|
||||
static propTypes = {
|
||||
currentPage: React.PropTypes.number.isRequired,
|
||||
lastPage: React.PropTypes.number.isRequired,
|
||||
leftRightArrowButtonTypes: React.PropTypes.object,
|
||||
leftRightRangeButtonTypes: React.PropTypes.object,
|
||||
nextButtonContent: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
onPageChange: React.PropTypes.func,
|
||||
pagerClassName: PropTypes.string,
|
||||
pagesButtonTypes: React.PropTypes.object,
|
||||
prevButtonContent: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
rangeLeftButtonContent: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
rangeRightButtonContent: React.PropTypes.oneOfType([
|
||||
React.PropTypes.string,
|
||||
React.PropTypes.element
|
||||
]),
|
||||
theme: PropTypes.shape({
|
||||
pager: PropTypes.string,
|
||||
active: PropTypes.string,
|
||||
leftRightArrowButton: PropTypes.string,
|
||||
leftRightRangeButton: PropTypes.string,
|
||||
pagesButton: PropTypes.string
|
||||
}),
|
||||
visiblePagesBlockSize: React.PropTypes.number.isRequired
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
currentPage: initialCurrentPage,
|
||||
lastPage: initialCurrentPage,
|
||||
leftRightArrowButtonTypes: {raised: true},
|
||||
leftRightRangeButtonTypes: {flat: true},
|
||||
nextButtonContent: '\u003E',
|
||||
pagesButtonTypes: {flat: true},
|
||||
prevButtonContent: '\u003C',
|
||||
rangeLeftButtonContent: '...',
|
||||
rangeRightButtonContent: '...',
|
||||
visiblePagesBlockSize: initialVisiblePagesBlockSize
|
||||
}
|
||||
|
||||
state = {
|
||||
currentPage: this.props.currentPage,
|
||||
lastPage: this.props.lastPage
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (nextProps.currentPage && !isNaN(Number(nextProps.currentPage))
|
||||
&& this.state.currentPage !== nextProps.currentPage) {
|
||||
this.setState({
|
||||
currentPage: Number(nextProps.currentPage < first ? first : nextProps.currentPage)
|
||||
});
|
||||
}
|
||||
if (nextProps.lastPage && !isNaN(Number(nextProps.lastPage))
|
||||
&& this.state.lastPage !== nextProps.lastPage) {
|
||||
this.setState({
|
||||
lastPage: Number(nextProps.lastPage < first ? first : nextProps.lastPage)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handlerPageClick (page) {
|
||||
const oldValue = this.state.currentPage;
|
||||
const newValue = page;
|
||||
|
||||
if (this.props.onPageChange) {
|
||||
this.props.onPageChange(oldValue, newValue);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentPage: newValue
|
||||
});
|
||||
}
|
||||
|
||||
handlerRangeClick (key) {
|
||||
const curr = this.state.currentPage;
|
||||
const last = this.state.lastPage;
|
||||
|
||||
const right = !this._ranges.rightStart ? last : this._ranges.rightStart;
|
||||
const left = !this._ranges.leftEnd ? first : this._ranges.leftEnd;
|
||||
|
||||
let newValue = curr;
|
||||
let sum = first + left;
|
||||
if (key === 'prev') {
|
||||
newValue = (sum >> 1); //rounding to left
|
||||
} else {
|
||||
sum = last + right;
|
||||
newValue = (sum >> 1) + (sum % 2); //rounding to right
|
||||
}
|
||||
|
||||
if (this.props.onPageChange) {
|
||||
this.props.onPageChange(curr, newValue);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentPage: newValue
|
||||
});
|
||||
}
|
||||
|
||||
handlerPrevNextClick (key) {
|
||||
const oldValue = this.state.currentPage;
|
||||
const newValue = key === 'prev' ? oldValue - 1 : oldValue + 1;
|
||||
|
||||
if (this.props.onPageChange) {
|
||||
this.props.onPageChange(oldValue, newValue);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentPage: newValue
|
||||
});
|
||||
}
|
||||
|
||||
//fields
|
||||
_ranges = {
|
||||
leftEnd: null,
|
||||
rightStart: null
|
||||
}
|
||||
|
||||
//rendering
|
||||
//private methods
|
||||
renderPages (currPage, lastPage) {
|
||||
let curr = currPage;
|
||||
let last = lastPage < first ? first : lastPage;
|
||||
if (curr < first || curr > last) {
|
||||
curr = curr < first ? first : curr > last ? last : curr;
|
||||
this.setState({
|
||||
currentPage: curr
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* adjustment of start and end elements at range to have equal elements during navigation
|
||||
* 2 - because we already have the rendered first and last button
|
||||
*/
|
||||
const adjustment = 2;
|
||||
const content = [];
|
||||
|
||||
const blockSize = this.props.visiblePagesBlockSize === 1 ? adjustment : this.props.visiblePagesBlockSize;
|
||||
|
||||
const padding = blockSize >> 1;
|
||||
const left = curr - padding * (blockSize % 2); //in case of even visiblePagesBlockSize
|
||||
const right = curr + padding;
|
||||
|
||||
const blocksNumber = Math.ceil(last / blockSize);
|
||||
let currentBlock = Math.ceil(curr / blockSize);
|
||||
|
||||
let start = ((currentBlock - 1) * blockSize) + first;
|
||||
let end = start + blockSize - first;
|
||||
|
||||
if (currentBlock === 1) { //adjust set of buttons if current is on the left boundary
|
||||
end += adjustment;
|
||||
end = (last - first) === end ? last : end;
|
||||
} else if (currentBlock < blocksNumber) { //adjustment set of buttons if current is between boundaries
|
||||
start = left;
|
||||
end = right;
|
||||
|
||||
currentBlock = Math.ceil(end / blockSize);
|
||||
}
|
||||
|
||||
if (currentBlock === blocksNumber) { //adjustment set of buttons if current is on the right boundary
|
||||
start = last - (blockSize + adjustment - first);
|
||||
start = start - 1 <= first ? first : start;
|
||||
end = last;
|
||||
}
|
||||
|
||||
if (currentBlock > 1 && (start - 1) > first) {
|
||||
content.push(
|
||||
<Button
|
||||
key={first}
|
||||
{...this.props.pagesButtonTypes}
|
||||
className={classnames(this.props.theme.pagesButton, (curr === first ? this.props.theme.active : null))}
|
||||
onClick={this.handlerPageClick.bind(this, first)}>
|
||||
{ String(first) }
|
||||
</Button>
|
||||
);
|
||||
|
||||
content.push(
|
||||
<Button
|
||||
key={'prev'}
|
||||
{...this.props.leftRightRangeButtonTypes}
|
||||
className={classnames(this.props.theme.leftRightRangeButton)}
|
||||
onClick={this.handlerRangeClick.bind(this, 'prev')}>
|
||||
{ this.props.rangeLeftButtonContent }
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
for (let i = start; i <= last && i <= end; ++i) {
|
||||
content.push(
|
||||
<Button
|
||||
key={i}
|
||||
{...this.props.pagesButtonTypes}
|
||||
className={classnames(this.props.theme.pagesButton, (curr === i ? this.props.theme.active : null))}
|
||||
onClick={this.handlerPageClick.bind(this, i)}>
|
||||
{ String(i) }
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
if (currentBlock < blocksNumber && end < last) {
|
||||
content.push(
|
||||
<Button
|
||||
key={'next'}
|
||||
{...this.props.leftRightRangeButtonTypes}
|
||||
className={classnames(this.props.theme.leftRightRangeButton)}
|
||||
onClick={this.handlerRangeClick.bind(this, 'next')}>
|
||||
{ this.props.rangeRightButtonContent }
|
||||
</Button>
|
||||
);
|
||||
|
||||
content.push(
|
||||
<Button
|
||||
key={last}
|
||||
{...this.props.pagesButtonTypes}
|
||||
className={classnames(this.props.theme.pagesButton, (curr === last ? this.props.theme.active : null))}
|
||||
onClick={this.handlerPageClick.bind(this, last)}>
|
||||
{ String(last) }
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// keep range boundaries to calculate correct navigation through the range
|
||||
this._ranges.leftEnd = start;
|
||||
this._ranges.rightStart = end - 1;
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
render () {
|
||||
const {leftRightArrowButtonTypes, prevButtonContent, nextButtonContent,
|
||||
pagerClassName, lastPage, theme} = this.props;
|
||||
|
||||
if (lastPage < first) {
|
||||
console.error('ArgumentOutOfRangeException: last Page must be bigger or equal first = 1.');
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-react-toolbox='pager' className={classnames(theme.pager, pagerClassName)} >
|
||||
|
||||
<Button
|
||||
{...leftRightArrowButtonTypes}
|
||||
disabled={isOnePage(first, this.state.lastPage) || isBorderPage(this.state.currentPage, first)}
|
||||
className={theme.leftRightArrowButton}
|
||||
onClick={this.handlerPrevNextClick.bind(this, 'prev')}>
|
||||
{ prevButtonContent }
|
||||
</Button>
|
||||
{
|
||||
this.renderPages(this.state.currentPage, this.state.lastPage)
|
||||
}
|
||||
<Button
|
||||
{...leftRightArrowButtonTypes}
|
||||
disabled={isOnePage(first, this.state.lastPage) || isBorderPage(this.state.currentPage, this.state.lastPage)}
|
||||
className={theme.leftRightArrowButton}
|
||||
onClick={this.handlerPrevNextClick.bind(this, 'next')}>
|
||||
{ nextButtonContent }
|
||||
</Button>
|
||||
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
return Pager;
|
||||
};
|
||||
|
||||
const Pager = factory(InjectButton);
|
||||
|
||||
export default themr(PAGER)(Pager);
|
||||
export {
|
||||
factory as pagerFactory
|
||||
};
|
||||
export { Pager };
|
|
@ -1,63 +0,0 @@
|
|||
# Pager
|
||||
|
||||
Provides functionality of pagination control, actually the component is not defined at(https://www.google.com/design/spec/components), but designed by using standart components from material design.
|
||||
It is easy to use and configure, also it is highly customizable.
|
||||
|
||||
<!-- example -->
|
||||
```jsx
|
||||
import Pager from 'react-toolbox/lib/pager';
|
||||
import FontIcon from 'react-toolbox/lib/font_icon';
|
||||
|
||||
const ProgressTest = () => {
|
||||
|
||||
var onPageChange = function (oldPage, newPage)
|
||||
{
|
||||
//server call to update content according current page
|
||||
console.info("Previous page : " + oldPage + ", Selected page: " + newPage);
|
||||
}
|
||||
|
||||
return (
|
||||
<Pager
|
||||
prevButtonContent={ (<FontIcon value='chevron_left' />) }
|
||||
nextButtonContent={ (<FontIcon value='chevron_right' />) }
|
||||
rangeLeftButtonContent={(<FontIcon value='more_horiz' />)}
|
||||
rangeRightButtonContent={(<FontIcon value='more_horiz' />)}
|
||||
lastPage={29}
|
||||
currentPage={5}
|
||||
visiblePagesBlockSize={3}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
If you want to provide a theme via context, the component key is `RTPager`.
|
||||
|
||||
## Properties
|
||||
|
||||
| Name | Type | Default | Description|
|
||||
|:-----|:-----|:-----|:-----|
|
||||
| `prevButtonContent` | `String` | `\u003C` | Used for the previous button content.|
|
||||
| `nextButtonContent` | `String` | `\u003E` | Used for the next button content.|
|
||||
| `rangeLeftButtonContent` | `String` | `...` | Used for the left range button content.|
|
||||
| `rangeRightButtonContent` | `String` | `...` | Used for the right range button content.|
|
||||
| `currentPage` | `Number` | `1` | A Number with the currently selected page.|
|
||||
| `lastPage` | `Number` | `1` | A Number of last page.|
|
||||
| `visiblePagesBlockSize` | `Number` | `3` | A Number of pages visible in control except next, previous and ranges buttons, the minimum value is 2.|
|
||||
| `onPageChange` | `Function` | | Callback called when the page is changing.|
|
||||
| `theme` | `String` | | Classnames object defining the component style.|
|
||||
| `pagerClassName` | `String` | | This class will be applied to the root elemt.|
|
||||
| `leftRightArrowButtonTypes` | `Object` | {raised: true} | Defining default style of next, previous buttons.|
|
||||
| `leftRightRangeButtonTypes` | `Object` | {flat: true} | Defining default style of left, right range buttons.|
|
||||
| `pagesButtonTypes` | `Object` | {flat: true} | Defining default style of regular page buttons.|
|
||||
|
||||
|
||||
## Theme
|
||||
|
||||
| Name | Description|
|
||||
|:---------|:-----------|
|
||||
| `pager` | Used for the root element.|
|
||||
| `active` | Used for the active page.|
|
||||
| `leftRightArrowButton` | Used for the next and previous page buttons.|
|
||||
| `leftRightRangeButton` | Used for the next and previous range pages buttons.|
|
||||
| `pagesButton` | Used for the regular page buttons.|
|
|
@ -1,25 +0,0 @@
|
|||
@import "../colors";
|
||||
@import "../globals";
|
||||
@import "../mixins";
|
||||
@import "./config";
|
||||
|
||||
.pager {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.leftRightArrowButton,
|
||||
.leftRightRangeButton,
|
||||
.pagesButton {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
|
||||
min-width: $button-height;
|
||||
margin: $button-margin;
|
||||
}
|
||||
|
||||
.active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import Pager from '../../components/pager';
|
||||
import FontIcon from '../../components/font_icon';
|
||||
import Input from '../../components/input';
|
||||
import style from '../style';
|
||||
|
||||
class PagerTest extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
visiblePagesBlockSize: PropTypes.number
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
visiblePagesBlockSize: 3
|
||||
}
|
||||
|
||||
state = {
|
||||
lastPage: 29,
|
||||
currentPage: 5
|
||||
}
|
||||
|
||||
onInputChange = (name, value) => {
|
||||
const state = this.state;
|
||||
|
||||
state[name] = value;
|
||||
|
||||
this.setState({
|
||||
...state
|
||||
});
|
||||
}
|
||||
|
||||
onPageChange (oldPage, newPage) {
|
||||
console.info('Previous page : ' + oldPage + ', Selected page: ' + newPage);
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
return (
|
||||
<section>
|
||||
<h5>Pager</h5>
|
||||
<p>Pager based on Material design.</p>
|
||||
|
||||
<div className={style.pager}>
|
||||
<Pager
|
||||
prevButtonContent={<FontIcon value='chevron_left' />}
|
||||
nextButtonContent={<FontIcon value='chevron_right' />}
|
||||
rangeLeftButtonContent={<FontIcon value='more_horiz' />}
|
||||
rangeRightButtonContent={<FontIcon value='more_horiz' />}
|
||||
lastPage={this.state.lastPage}
|
||||
currentPage={this.state.currentPage}
|
||||
visiblePagesBlockSize={this.props.visiblePagesBlockSize}
|
||||
onPageChange={this.onPageChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
type='number'
|
||||
value={this.state.lastPage}
|
||||
label='Last Page' onChange={this.onInputChange.bind(this, 'lastPage')}
|
||||
/>
|
||||
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PagerTest;
|
|
@ -19,7 +19,6 @@ import Input from './components/input';
|
|||
import Layout from './components/layout';
|
||||
import List from './components/list';
|
||||
import Menu from './components/menu';
|
||||
import Pager from './components/pager';
|
||||
import Pickers from './components/pickers';
|
||||
import Progress from './components/progress';
|
||||
import Radio from './components/radio';
|
||||
|
@ -64,7 +63,6 @@ const Root = () => (
|
|||
<List />
|
||||
<Menu />
|
||||
<Pickers />
|
||||
<Pager />
|
||||
<Progress />
|
||||
<Radio />
|
||||
<Slider />
|
||||
|
|
|
@ -146,10 +146,3 @@ $offset: 1.8 * $unit;
|
|||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.pager
|
||||
{
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
}
|
Loading…
Reference in New Issue