Skip to content

Commit

Permalink
Router integration
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrookes committed Jan 14, 2020
1 parent 464e6f3 commit 366caf2
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 26 deletions.
35 changes: 35 additions & 0 deletions docs/src/pages/components/pagination/PaginationLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import Pagination from '@material-ui/lab/Pagination';
import PaginationItem from '@material-ui/lab/PaginationItem';

const useStyles = makeStyles(theme => ({
root: {
'& > *': {
marginTop: theme.spacing(2),
},
},
}));

// The use of React.forwardRef will no longer be required for react-router-dom v6.
// See https://github.com/ReactTraining/react-router/issues/6056
const Link = React.forwardRef((props, ref) => <RouterLink innerRef={ref} {...props} />);

export default function PaginationLink() {
return (
<Router>
<Pagination
count={10}
renderItem={item => (
<PaginationItem
to={`/cars${item.page === 1 ? '' : `?page=${item.page}`}`}
component={Link}
{...item}
/>
)}
/>
</Router>
);
}
39 changes: 39 additions & 0 deletions docs/src/pages/components/pagination/PaginationLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import Pagination from '@material-ui/lab/Pagination';
import PaginationItem from '@material-ui/lab/PaginationItem';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
'& > *': {
marginTop: theme.spacing(2),
},
},
}),
);

// The use of React.forwardRef will no longer be required for react-router-dom v6.
// See https://github.com/ReactTraining/react-router/issues/6056
const Link = React.forwardRef<HTMLAnchorElement, RouterLinkProps>((props, ref) => (
<RouterLink innerRef={ref} {...props} />
));

export default function PaginationLink() {
return (
<Router>
<Pagination
count={10}
renderItem={item => (
<PaginationItem
to={`/cars${item.page === 1 ? '' : `?page=${item.page}`}`}
component={Link}
{...item}
/>
)}
/>
</Router>
);
}
42 changes: 42 additions & 0 deletions docs/src/pages/components/pagination/PaginationLink2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { makeStyles } from '@material-ui/core/styles';
import { usePagination } from '@material-ui/lab/Pagination';
import Pagination from '@material-ui/lab/Pagination';
import PaginationItem from '@material-ui/lab/PaginationItem';

const useStyles = makeStyles(theme => ({
root: {
'& > *': {
marginTop: theme.spacing(2),
},
},
}));

// The use of React.forwardRef will no longer be required for react-router-dom v6.
// See https://github.com/ReactTraining/react-router/issues/6056
const Link = React.forwardRef((props, ref) => <RouterLink innerRef={ref} {...props} />);

export default function PaginationLink2() {
const { items } = usePagination({
count: 10,
});

return (
<Router>
<Pagination>
{items.map((item, index) => (
<li>
<PaginationItem
to={`/cars${item.page === 1 ? '' : `?page=${item.page}`}`}
component={Link}
{...item}
key={index.toString()}
/>
</li>
))}
</Pagination>
</Router>
);
}
46 changes: 46 additions & 0 deletions docs/src/pages/components/pagination/PaginationLink2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import { MemoryRouter as Router } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import { usePagination } from '@material-ui/lab/Pagination';
import Pagination from '@material-ui/lab/Pagination';
import PaginationItem from '@material-ui/lab/PaginationItem';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
'& > *': {
marginTop: theme.spacing(2),
},
},
}),
);

// The use of React.forwardRef will no longer be required for react-router-dom v6.
// See https://github.com/ReactTraining/react-router/issues/6056
const Link = React.forwardRef<HTMLAnchorElement, RouterLinkProps>((props, ref) => (
<RouterLink innerRef={ref} {...props} />
));

export default function PaginationLink2() {
const { items } = usePagination({
count: 10,
});

return (
<Router>
<Pagination>
{items.map((item, index) => (
<li>
<PaginationItem
to={`/cars${item.page === 1 ? '' : `?page=${item.page}`}`}
component={Link}
{...item}
key={index.toString()}
/>
</li>
))}
</Pagination>
</Router>
);
}
5 changes: 5 additions & 0 deletions docs/src/pages/components/pagination/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ You can specify how many digits to display either side of current page with the

{{"demo": "pages/components/pagination/PaginationControlled.js"}}

## Router integration

{{"demo": "pages/components/pagination/PaginationLink.js"}}
{{"demo": "pages/components/pagination/PaginationLink2.js"}}

## Accessibility

### ARIA
Expand Down
11 changes: 6 additions & 5 deletions packages/material-ui-lab/src/Pagination/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const styles = {
display: 'flex',
flexWrap: 'wrap',
alignItems: 'center',
listStyleType: 'none',
padding: 0, // Reset
margin: 0, // Reset
},
Expand All @@ -25,7 +26,7 @@ const Pagination = React.forwardRef(function Pagination(props, ref) {
component: Component = 'ul',
getItemAriaLabel: getAriaLabel,
items,
renderItem = (item, index) => <PaginationItem {...item} key={index.toString()} />,
renderItem = item => <PaginationItem {...item} />,
shape = 'round',
size,
variant = 'text',
Expand All @@ -43,7 +44,8 @@ const Pagination = React.forwardRef(function Pagination(props, ref) {
ref={ref}
{...other}
>
{children || items.map((item, index) => renderItem({ ...item, ...itemProps }, index))}
{children ||
items.map((item, index) => <li>{renderItem({ key: index.toString(), ...item, ...itemProps })}</li>)}
</ul>
);
});
Expand Down Expand Up @@ -73,13 +75,12 @@ Pagination.propTypes = {
/**
* The component used for the root node.
* Either a string to use a DOM element or a component.
* By default, it maps the variant to a good default headline component.
*/
component: PropTypes.elementType,
/**
* The total number of pages.
*/
count: PropTypes.number.isRequired,
count: PropTypes.number,
/**
* If `true`, all the pagination component will be disabled.
*/
Expand Down Expand Up @@ -111,7 +112,7 @@ Pagination.propTypes = {
/**
* The current page.
*/
page: PropTypes.number.isRequired,
page: PropTypes.number,
/**
* Render the item.
*
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui-lab/src/Pagination/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default } from './Pagination';
export { default as usePagination } from './usePagination';
6 changes: 3 additions & 3 deletions packages/material-ui-lab/src/Pagination/usePagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
export default function usePagination(props) {
const {
boundaryRange = 0,
count,
count = 0,
disabled = false,
hideNextButton = false,
hidePrevButton = false,
Expand Down Expand Up @@ -38,7 +38,7 @@ export default function usePagination(props) {
}, [pageProp, isControlled]);
}

const handleChange = (event, value) => {
const handleClick = (event, value) => {
if (!isControlled) {
setPageState(value);
}
Expand Down Expand Up @@ -109,7 +109,7 @@ export default function usePagination(props) {

const itemProps = {
disabled,
onChange: handleChange,
onClick: handleClick,
page,
};

Expand Down
36 changes: 18 additions & 18 deletions packages/material-ui-lab/src/PaginationItem/PaginationItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import { capitalize } from '@material-ui/core/utils';
const styles = theme => ({
/* Styles applied to the root element. */
root: {
listStyleType: 'none',
},
/* Styles applied to the button element. */
button: {
borderRadius: '50%',
width: 32,
height: 32,
Expand Down Expand Up @@ -50,7 +46,7 @@ const styles = theme => ({
outlined: {
border: `1px solid ${
theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
}`,
}`,
'&:hover, &:focus': {
backgroundColor: fade(theme.palette.action.active, 0.05),
},
Expand All @@ -59,7 +55,7 @@ const styles = theme => ({
backgroundColor: fade(theme.palette.action.disabled, 0.03),
border: `1px solid ${
theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.13)' : 'rgba(255, 255, 255, 0.13)'
}`,
}`,
pointerEvents: 'none',
},
'&$selected': {
Expand Down Expand Up @@ -218,10 +214,11 @@ function PaginationItem(props) {
classes,
className,
color = 'standard',
component,
disabled,
getAriaLabel,
page,
onChange: handleChange,
onClick: handleClick,
selected,
shape = 'round',
size = 'medium',
Expand All @@ -230,7 +227,7 @@ function PaginationItem(props) {
...other
} = props;

const buttonClass = clsx(classes.button, classes[variant], classes[shape], {
const buttonClass = clsx(classes.root, classes[variant], classes[shape], {
[classes[`${variant}${capitalize(color)}`]]: color !== 'standard',
[classes.disabled]: disabled,
[classes.selected]: selected,
Expand All @@ -240,27 +237,25 @@ function PaginationItem(props) {
return (
<React.Fragment>
{type === 'ellipsis' ? (
<li className={clsx(classes.root, className)} {...other}>
<div className={classes.ellipsis}>...</div>
</li>
<div className={classes.ellipsis}>...</div>
) : (
<li className={clsx(classes.root, className)} {...other}>
<ButtonBase
component={component}
aria-label={
getAriaLabel ? getAriaLabel(type, page, selected) : ariaLabel(type, page, selected)
}
aria-current={selected ? 'page' : undefined}
onClick={event => handleChange(event, page)}
onClick={event => handleClick(event, page)}
className={buttonClass}
{...other}
>
{type === 'page' && page}
{type === 'previous' && <NavigateBeforeIcon />}
{type === 'next' && <NavigateNextIcon />}
{type === 'first' && <FirstPageIcon />}
{type === 'last' && <LastPageIcon />}
</ButtonBase>
</li>
)}
)}
</React.Fragment>
);
}
Expand All @@ -278,6 +273,11 @@ PaginationItem.propTypes = {
* The active color.
*/
color: PropTypes.oneOf(['standard', 'primary', 'secondary']),
/**
* The component used for the root node.
* Either a string to use a DOM element or a component.
*/
component: PropTypes.elementType,
/**
* If `true`, the button will be disabled.
*/
Expand All @@ -297,11 +297,11 @@ PaginationItem.propTypes = {
* @param {object} event The event source of the callback.
* @param {number} page The page selected.
*/
onChange: PropTypes.func.isRequired,
onClick: PropTypes.func,
/**
* The current page number.
*/
page: PropTypes.number.isRequired,
page: PropTypes.number,
/**
* If `true` the pagination item is selected.
*/
Expand All @@ -324,4 +324,4 @@ PaginationItem.propTypes = {
variant: PropTypes.oneOf(['text', 'outlined']),
};

export default withStyles(styles, { name: 'MuiPaginationItem' })(PaginationItem);
export default withStyles(styles, { name: 'PaginationItem' })(PaginationItem);

0 comments on commit 366caf2

Please sign in to comment.