Skip to content

Instantly share code, notes, and snippets.

@SebastianHGonzalez
Last active September 19, 2019 16:08
Show Gist options
  • Save SebastianHGonzalez/7bf33e8367310b86e7aeed2a755251e2 to your computer and use it in GitHub Desktop.
Save SebastianHGonzalez/7bf33e8367310b86e7aeed2a755251e2 to your computer and use it in GitHub Desktop.
import React, { useCallback, useMemo } from "react";
import { string, func, number } from "prop-types";
import styled from "styled-components";
import DefaultButton from "components/common/input/Button";
import I18n from "components/common/I18n";
import Dots from "components/common/icons/Dots";
const Button = styled(DefaultButton)`
margin: 0 0.25rem;
font-size: 10px;
`;
function Pagination({ className, current, total, onChange, collapseWindow }) {
const shouldDisplay = useMemo(
() => createShouldDisplay(current, collapseWindow),
[current, collapseWindow]
);
return (
<div className={className}>
<PageButton
page={current - 1}
onChange={onChange}
disabled={current <= 0}
>
<I18n id="previous" />
</PageButton>
{current - collapseWindow > 0 && (
<PageButton page={0} onChange={onChange} />
)}
{current - collapseWindow > 1 && <Dots />}
{new Array(total)
.fill()
.map(
(_, thisPage) =>
shouldDisplay(thisPage) && (
<PageButton
key={thisPage}
page={thisPage}
onChange={onChange}
active={thisPage == current}
/>
)
)}
{current + collapseWindow < total - 2 && <Dots />}
{current + collapseWindow < total - 1 && (
<PageButton page={total - 1} onChange={onChange} />
)}
<PageButton
page={current + 1}
onChange={onChange}
disabled={current >= total - 1}
>
<I18n id="next" />
</PageButton>
</div>
);
}
Pagination.propTypes = {
className: string,
onChange: func,
current: number.isRequired,
total: number.isRequired
};
Pagination.defaultProps = {
className: undefined,
collapseWindow: 1,
onChange: noop
};
export default styled(Pagination)`
display: flex;
align-items: center;
justify-self: center;
`;
const StyledButton = styled(Button).attrs(
({ active, theme: { primary, neutralContrast } }) => ({
style: {
color: active ? primary : neutralContrast,
borderColor: active ? primary : neutralContrast
}
})
)``;
function PageButton({ page, onChange, disabled, active, children }) {
const handleClick = useCallback(() => {
onChange(page);
});
return (
<StyledButton
small
outline
onClick={handleClick}
disabled={disabled}
active={active}
>
{children || +page + 1}
</StyledButton>
);
}
function noop() {}
function createShouldDisplay(current, collapseWindow) {
const upperLimit = current + collapseWindow;
const lowerLimit = current - collapseWindow;
return function shouldDisplay(page) {
return page >= lowerLimit && page <= upperLimit;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment