diff --git a/src/Pagination/PageLink.js b/src/Pagination/PageLink.js new file mode 100644 index 00000000..0ff31959 --- /dev/null +++ b/src/Pagination/PageLink.js @@ -0,0 +1,82 @@ +// @flow +import * as React from 'react'; +import styled from 'styled-components'; +import { darken2, darken3 } from '../utils/darken'; +import { type ThemeProps } from '../utils/type.flow'; + +export type Props = { + to: number, + onClick: number => void, + disabled?: boolean, + active?: boolean, +}; +export type SquareButtonTextProps = { + disabled: boolean, + active: boolean, +}; + +export const SquareButtonText: React.ComponentType = styled.div` + width: 24px; + height: 24px; + + display: flex; + align-items: center; + justify-content: center; + + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: ${({ active, theme }: SquareButtonTextProps & ThemeProps) => + active ? darken3(theme.color.primary) : 'transparent'}; + transition: border-color cubic-bezier(0.47, 0, 0.75, 0.72) 0.3s; + background-color: ${({ active, theme }: SquareButtonTextProps & ThemeProps) => + active ? darken2(theme.color.primary) : 'unset'}; + color: ${({ + active, + disabled, + theme, + }: SquareButtonTextProps & ThemeProps) => { + if (disabled) return theme.color.grayBase; + if (active) return theme.color.white; + return theme.color.primary; + }}; + cursor: ${({ disabled }: SquareButtonTextProps & ThemeProps) => + disabled ? 'unset' : 'pointer'}; + + &:hover { + border-color: ${({ + active, + disabled, + theme, + }: SquareButtonTextProps & ThemeProps) => { + if (disabled) return 'transparent'; + if (active) return darken3(theme.color.primary); + return theme.color.primary; + }}; + } +`; + +const PageLink = ({ + to, + onClick, + disabled = false, + active = false, + ...otherProps +}: Props) => { + const onClickableClick = React.useCallback(() => { + if (!disabled) { + onClick(to); + } + }); + + return ( + + ); +}; + +export default React.memo(PageLink); diff --git a/src/Pagination/Pagination.example.js b/src/Pagination/Pagination.example.js new file mode 100644 index 00000000..5c70ca2d --- /dev/null +++ b/src/Pagination/Pagination.example.js @@ -0,0 +1,80 @@ +// @flow +import * as React from 'react'; +import { storiesOf } from '@storybook/react'; +import { action } from '@storybook/addon-actions'; +import Pagination from '.'; + +storiesOf('Pagination', module) + .add( + '10 pages', + () => ( +
+ + + + + + + + + + +
+ ), + { + info: { + text: ``, + inline: true, + source: false, + }, + }, + ) + .add( + '1 page', + () => , + { + info: { + text: ``, + inline: true, + source: false, + }, + }, + ) + .add( + '5 pages', + () => ( +
+ + + + + +
+ ), + { + info: { + text: ``, + inline: true, + source: false, + }, + }, + ) + .add( + 'useState', + () => { + const StatefulPagination = () => { + const [value, setValue] = React.useState(1); + const onChange = setValue; + + return ; + }; + return ; + }, + { + info: { + text: ``, + inline: true, + source: false, + }, + }, + ); diff --git a/src/Pagination/Pagination.js b/src/Pagination/Pagination.js new file mode 100644 index 00000000..8c74b7ab --- /dev/null +++ b/src/Pagination/Pagination.js @@ -0,0 +1,69 @@ +// @flow +import * as React from 'react'; +import * as R from 'ramda'; +import { + IconChevronLeft, + IconChevronRight, + IconChevronFirst, + IconChevronLast, + IconMoreHoriz, +} from '../Icons'; +import { Container } from './styled-components'; +import PageLink from './PageLink'; +import getPaginationRange from '../utils/getPaginationRange'; + +export type Props = { + pages: number, // Total number of pages. + value: number, // Current page + onChange: (page: number) => void, +}; + +const Pagination = ({ pages, value, onChange, ...otherProps }: Props) => { + const range = React.useMemo(() => getPaginationRange({ pages, value }), [ + pages, + value, + ]); + const isFirstPage = React.useMemo(() => value === 1, [value]); + const isLastPage = React.useMemo(() => value === pages, [pages, value]); + const isFirstPageIncluded = React.useMemo(() => R.head(range) === 1, [range]); + const isLastPageIncluded = React.useMemo(() => R.last(range) === pages, [ + range, + pages, + ]); + + return ( + + + + + + + + + {!isFirstPageIncluded && ( + + + + )} + {range.map(n => ( + + {n} + + ))} + {!isLastPageIncluded && ( + + + + )} + + + + + + + + + ); +}; + +export default React.memo(Pagination); diff --git a/src/Pagination/__snapshots__/Pagination.example.storyshot b/src/Pagination/__snapshots__/Pagination.example.storyshot new file mode 100644 index 00000000..88cb4bd8 --- /dev/null +++ b/src/Pagination/__snapshots__/Pagination.example.storyshot @@ -0,0 +1,14245 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Pagination 1 page 1`] = ` +.c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 20px; +} + +.c0 > * + * { + margin-left: 5px; +} + +.c1 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #D1D2D3; + cursor: unset; +} + +.c1:hover { + border-color: transparent; +} + +.c2 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: rgb(0,130,179); + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: rgb(0,144,198); + color: #FFFFFF; + cursor: pointer; +} + +.c2:hover { + border-color: rgb(0,130,179); +} + + + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+`; + +exports[`Storyshots Pagination 5 pages 1`] = ` +.c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 20px; +} + +.c0 > * + * { + margin-left: 5px; +} + +.c1 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #D1D2D3; + cursor: unset; +} + +.c1:hover { + border-color: transparent; +} + +.c2 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: rgb(0,130,179); + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: rgb(0,144,198); + color: #FFFFFF; + cursor: pointer; +} + +.c2:hover { + border-color: rgb(0,130,179); +} + +.c3 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #00A1DE; + cursor: pointer; +} + +.c3:hover { + border-color: #00A1DE; +} + +
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Pagination 10 pages 1`] = ` +.c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 20px; +} + +.c0 > * + * { + margin-left: 5px; +} + +.c1 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #D1D2D3; + cursor: unset; +} + +.c1:hover { + border-color: transparent; +} + +.c2 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: rgb(0,130,179); + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: rgb(0,144,198); + color: #FFFFFF; + cursor: pointer; +} + +.c2:hover { + border-color: rgb(0,130,179); +} + +.c3 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #00A1DE; + cursor: pointer; +} + +.c3:hover { + border-color: #00A1DE; +} + +
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ 6 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ 8 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 5 +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ 8 +
+
+
+ + +
+ 9 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ 8 +
+
+
+ + +
+ 9 +
+
+
+ + +
+ 10 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ 8 +
+
+
+ + +
+ 9 +
+
+
+ + +
+ 10 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+ + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 6 +
+
+
+ + +
+ 7 +
+
+
+ + +
+ 8 +
+
+
+ + +
+ 9 +
+
+
+ + +
+ 10 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+
+`; + +exports[`Storyshots Pagination useState 1`] = ` +.c0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 20px; +} + +.c0 > * + * { + margin-left: 5px; +} + +.c1 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #D1D2D3; + cursor: unset; +} + +.c1:hover { + border-color: transparent; +} + +.c2 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: rgb(0,130,179); + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: rgb(0,144,198); + color: #FFFFFF; + cursor: pointer; +} + +.c2:hover { + border-color: rgb(0,130,179); +} + +.c3 { + width: 24px; + height: 24px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + border-radius: 3px; + border-width: 1px; + border-style: solid; + border-color: transparent; + -webkit-transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + transition: border-color cubic-bezier(0.47,0,0.75,0.72) 0.3s; + background-color: unset; + color: #00A1DE; + cursor: pointer; +} + +.c3:hover { + border-color: #00A1DE; +} + + + + * + * { + margin-left: 5px; + } +", + ], + }, + "displayName": "styled-components__Container", + "foldedComponentIds": Array [], + "render": [Function], + "styledComponentId": "styled-components__Container-sc-12upg06-0", + "target": "div", + "toString": [Function], + "warnTooManyClasses": [Function], + "withComponent": [Function], + } + } + forwardedRef={null} + > +
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ 1 +
+
+
+ + +
+ 2 +
+
+
+ + +
+ 3 +
+
+
+ + +
+ 4 +
+
+
+ + +
+ 5 +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+ + +
+ + + + + +
+
+
+
+
+
+
+`; diff --git a/src/Pagination/index.js b/src/Pagination/index.js new file mode 100644 index 00000000..cf8613ca --- /dev/null +++ b/src/Pagination/index.js @@ -0,0 +1,2 @@ +// @flow +export { default } from './Pagination'; diff --git a/src/Pagination/styled-components.js b/src/Pagination/styled-components.js new file mode 100644 index 00000000..da45c867 --- /dev/null +++ b/src/Pagination/styled-components.js @@ -0,0 +1,15 @@ +// @flow +import styled from 'styled-components'; + +export const Container = styled.div` + display: flex; + align-items: center; + justify-content: center; + margin-top: 20px; + + > * + * { + margin-left: 5px; + } +`; + +export default Container; diff --git a/src/index.js b/src/index.js index f7ee5147..5444da91 100644 --- a/src/index.js +++ b/src/index.js @@ -44,6 +44,7 @@ export { default as Menu } from './Menu'; export { default as MenuItem } from './MenuItem'; export { default as Orderbox } from './Orderbox'; export { default as P } from './P'; +export { default as Pagination } from './Pagination'; export { default as Panel } from './Panel'; export { default as PanelIcon } from './PanelIcon'; export { default as Popover } from './Popover'; diff --git a/src/utils/__tests__/getPaginationRange.test.js b/src/utils/__tests__/getPaginationRange.test.js new file mode 100644 index 00000000..83709b6d --- /dev/null +++ b/src/utils/__tests__/getPaginationRange.test.js @@ -0,0 +1,115 @@ +// @flow +import getPaginationRange from '../getPaginationRange'; + +it('should return correct range', () => { + expect(getPaginationRange({ pages: 1, value: 1 })).toMatchInlineSnapshot(` +Array [ + 1, +] +`); + + expect(getPaginationRange({ pages: 2, value: 1 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, +] +`); + expect(getPaginationRange({ pages: 2, value: 2 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, +] +`); + + expect(getPaginationRange({ pages: 5, value: 1 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 5, value: 2 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 5, value: 3 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 5, value: 4 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 5, value: 5 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + + expect(getPaginationRange({ pages: 10, value: 1 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 10, value: 3 })).toMatchInlineSnapshot(` +Array [ + 1, + 2, + 3, + 4, + 5, +] +`); + expect(getPaginationRange({ pages: 10, value: 4 })).toMatchInlineSnapshot(` +Array [ + 2, + 3, + 4, + 5, + 6, +] +`); + expect(getPaginationRange({ pages: 10, value: 7 })).toMatchInlineSnapshot(` +Array [ + 5, + 6, + 7, + 8, + 9, +] +`); + expect(getPaginationRange({ pages: 10, value: 10 })).toMatchInlineSnapshot(` +Array [ + 6, + 7, + 8, + 9, + 10, +] +`); +}); diff --git a/src/utils/getPaginationRange.js b/src/utils/getPaginationRange.js new file mode 100644 index 00000000..79188d46 --- /dev/null +++ b/src/utils/getPaginationRange.js @@ -0,0 +1,32 @@ +// @flow +import * as R from 'ramda'; + +const getPaginationRange = ({ + pages, + value, +}: { + pages: number, + value: number, +}): Array => { + if (pages <= 5) { + return R.range(1, pages + 1); + } + + // Note: get neighborhood + const range = R.range(value - 2, value + 2 + 1); + + const head = range[0]; + if (head <= 0) { + return range.map(n => n - head + 1); + } + + const last = range[range.length - 1]; + if (last > pages) { + const diff = last - pages; + return range.map(n => n - diff); + } + + return range; +}; + +export default getPaginationRange; diff --git a/src/utils/index.js b/src/utils/index.js index fcfe5795..44382b1a 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -5,6 +5,7 @@ export * from './theme'; export { default as emptyFunction } from './emptyFunction'; export { default as getCurrentYear } from './getCurrentYear'; +export { default as getPaginationRange } from './getPaginationRange'; export { default as isString } from './isString'; export { default as localTimeFormat } from './localTimeFormat'; export { default as opacity } from './opacity';