+ pushed file browser button branch

old
Maxim Komlev 2016-10-07 16:16:08 -07:00
parent 9019239f72
commit 089c5b69f7
11 changed files with 0 additions and 590 deletions

View File

@ -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';

View File

@ -28,4 +28,3 @@ export Table from './table';
export * from './tabs';
export Tooltip from './tooltip';
export TimePicker from './time_picker';
export Pager from './pager';

View File

@ -1,3 +0,0 @@
@import "../button/config";
$button-margin: 0rem .5rem 0rem 0rem !default;

View File

@ -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;

View File

@ -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 };

View File

@ -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 };

View File

@ -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.|

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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 />

View File

@ -146,10 +146,3 @@ $offset: 1.8 * $unit;
height: 40px;
}
}
.pager
{
display: flex;
flex-flow: row nowrap;
justify-content: center;
}