mirror of
https://github.com/strapi/strapi.git
synced 2025-12-26 14:44:31 +00:00
Move Pagination and PageSize to helper plugin and add tests
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
02bb3a516c
commit
da8bec4d5f
@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Box, Row } from '@strapi/parts';
|
||||
import Pagination from './Pagination';
|
||||
import PageSize from './PageSize';
|
||||
import { Pagination, PageSize } from '@strapi/helper-plugin';
|
||||
|
||||
const PaginationFooter = ({ pagination }) => {
|
||||
return (
|
||||
|
||||
@ -547,10 +547,6 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.c59 {
|
||||
line-height: revert;
|
||||
}
|
||||
|
||||
.c55 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
@ -562,27 +558,6 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c57 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c58 {
|
||||
color: #271fe0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.c58:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c56 {
|
||||
font-size: 0.7rem;
|
||||
pointer-events: none;
|
||||
@ -597,16 +572,16 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
||||
fill: #c0c0cf;
|
||||
}
|
||||
|
||||
.c60 {
|
||||
.c57 {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.c60 svg path {
|
||||
.c57 svg path {
|
||||
fill: #666687;
|
||||
}
|
||||
|
||||
.c60:focus svg path,
|
||||
.c60:hover svg path {
|
||||
.c57:focus svg path,
|
||||
.c57:hover svg path {
|
||||
fill: #4a4a6a;
|
||||
}
|
||||
|
||||
@ -1347,30 +1322,11 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c57 c58 active"
|
||||
href="/settings/user?pageSize=10&page=1&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c37"
|
||||
>
|
||||
Go to page 1
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c9 c10 c59"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="false"
|
||||
class="c55 c60 active"
|
||||
class="c55 c57 active"
|
||||
href="/settings/user?pageSize=10&page=1&sort=firstname"
|
||||
>
|
||||
<div
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ThemeProvider, lightTheme } from '@strapi/parts';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
export const parameters = {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
@ -13,12 +14,14 @@ export const parameters = {
|
||||
|
||||
export const decorators = [
|
||||
Story => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<IntlProvider messages={{ en: {} }} textComponent="span" locale="en">
|
||||
<main>
|
||||
<Story />
|
||||
</main>
|
||||
</IntlProvider>
|
||||
</ThemeProvider>
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<IntlProvider messages={{ en: {} }} textComponent="span" locale="en">
|
||||
<main>
|
||||
<Story />
|
||||
</main>
|
||||
</IntlProvider>
|
||||
</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
),
|
||||
];
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
<!--- PageSize.stories.mdx --->
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||
import { Main, Box } from '@strapi/parts';
|
||||
import useQueryParams from '../../hooks/useQueryParams';
|
||||
import PageSize from './index';
|
||||
|
||||
<Meta title="components/PageSize" />
|
||||
|
||||
# PageSize
|
||||
|
||||
This component is used to change the page size.
|
||||
|
||||
## Imports
|
||||
|
||||
```js
|
||||
import { PageSize } from '@strapi/helper-plugin';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
<Canvas>
|
||||
<Story name="base">
|
||||
{() => {
|
||||
const [{ query }, setQuery] = useQueryParams();
|
||||
useEffect(() => {
|
||||
setQuery({ pageSize: 10 });
|
||||
}, []);
|
||||
return (
|
||||
<Main>
|
||||
<Box paddingTop={6}>
|
||||
<PageSize />
|
||||
</Box>
|
||||
</Main>
|
||||
);
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
### Props
|
||||
|
||||
This component does not have props.
|
||||
@ -1,22 +1,25 @@
|
||||
/**
|
||||
*
|
||||
* PageSize
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Row, Select, Option } from '@strapi/parts';
|
||||
import { useQueryParams } from '@strapi/helper-plugin';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useQueryParams from '../../hooks/useQueryParams';
|
||||
|
||||
const PageSize = () => {
|
||||
const { formatMessage } = useIntl();
|
||||
const [
|
||||
{
|
||||
query: { pageSize },
|
||||
},
|
||||
setQuery,
|
||||
] = useQueryParams();
|
||||
const [{ query }, setQuery] = useQueryParams();
|
||||
|
||||
const handleChange = e => {
|
||||
setQuery({
|
||||
pageSize: e,
|
||||
page: 1,
|
||||
});
|
||||
};
|
||||
const pageSize = query?.pageSize || '10';
|
||||
|
||||
return (
|
||||
<Row>
|
||||
@ -34,13 +37,13 @@ const PageSize = () => {
|
||||
<Option value="100">100</Option>
|
||||
</Select>
|
||||
{/* <Box paddingLeft={2}>
|
||||
<Text textColor="neutral600" as="label" htmlFor="page-size">
|
||||
{formatMessage({
|
||||
id: 'components.PageFooter.select',
|
||||
defaultMessage: 'Entries per page',
|
||||
})}
|
||||
</Text>
|
||||
</Box> */}
|
||||
<Text textColor="neutral600" as="label" htmlFor="page-size">
|
||||
{formatMessage({
|
||||
id: 'components.PageFooter.select',
|
||||
defaultMessage: 'Entries per page',
|
||||
})}
|
||||
</Text>
|
||||
</Box> */}
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,261 @@
|
||||
/**
|
||||
*
|
||||
* Tests for PageSize
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { ThemeProvider, lightTheme } from '@strapi/parts';
|
||||
import PageSize from '../index';
|
||||
|
||||
const messages = {
|
||||
en: {
|
||||
'components.PageFooter.select': 'Entries per page',
|
||||
},
|
||||
};
|
||||
|
||||
const makeApp = history => (
|
||||
<Router history={history}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<IntlProvider locale="en" messages={messages} textComponent="span">
|
||||
<PageSize />
|
||||
</IntlProvider>
|
||||
</ThemeProvider>
|
||||
</Router>
|
||||
);
|
||||
|
||||
describe('<PageSize />', () => {
|
||||
it('renders and matches the snapshot', () => {
|
||||
const history = createMemoryHistory();
|
||||
const {
|
||||
container: { firstChild },
|
||||
getByText,
|
||||
} = render(makeApp(history));
|
||||
|
||||
expect(firstChild).toMatchInlineSnapshot(`
|
||||
.c2 {
|
||||
font-weight: 500;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
font-weight: 400;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.43;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c7 {
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.c9 {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c1 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.c1 > * {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.c1 > * + * {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.c4:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.c3 {
|
||||
position: relative;
|
||||
border: 1px solid #dcdce4;
|
||||
padding-right: 12px;
|
||||
border-radius: 4px;
|
||||
background: #ffffff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.c3:focus-within {
|
||||
border: 1px solid #4945ff;
|
||||
}
|
||||
|
||||
.c10 {
|
||||
background: transparent;
|
||||
border: none;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.c10 svg {
|
||||
height: 0.6875rem;
|
||||
width: 0.6875rem;
|
||||
}
|
||||
|
||||
.c10 svg path {
|
||||
fill: #666687;
|
||||
}
|
||||
|
||||
.c11 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.c11 svg {
|
||||
width: 0.375rem;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
min-height: 2.5rem;
|
||||
}
|
||||
|
||||
<div
|
||||
class="c0"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="c1"
|
||||
>
|
||||
<span
|
||||
class="c2"
|
||||
for="select-1"
|
||||
id="select-1-label"
|
||||
>
|
||||
Entries per page
|
||||
</span>
|
||||
<div
|
||||
class="c3"
|
||||
>
|
||||
<button
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-labelledby="select-1-label select-1-content"
|
||||
class="c4"
|
||||
id="select-1"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="c5 c6"
|
||||
>
|
||||
<div
|
||||
class="c0"
|
||||
>
|
||||
<div
|
||||
class="c7"
|
||||
>
|
||||
<span
|
||||
class="c8"
|
||||
id="select-1-content"
|
||||
>
|
||||
10
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c0"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="c9 c10 c11"
|
||||
tabindex="-1"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 14 8"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M14 .889a.86.86 0 01-.26.625L7.615 7.736A.834.834 0 017 8a.834.834 0 01-.615-.264L.26 1.514A.861.861 0 010 .889c0-.24.087-.45.26-.625A.834.834 0 01.875 0h12.25c.237 0 .442.088.615.264a.86.86 0 01.26.625z"
|
||||
fill="#32324D"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
expect(getByText('10')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display the pageSize correctly', () => {
|
||||
const history = createMemoryHistory();
|
||||
|
||||
history.push({ search: 'pageSize=50' });
|
||||
|
||||
const { getByText } = render(makeApp(history));
|
||||
|
||||
expect(getByText('50')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,43 @@
|
||||
<!--- Pagination.stories.mdx --->
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||
import { Main, Box } from '@strapi/parts';
|
||||
import useQueryParams from '../../hooks/useQueryParams';
|
||||
import Pagination from './index';
|
||||
|
||||
<Meta title="components/Pagination" />
|
||||
|
||||
# Pagination
|
||||
|
||||
This component is used to change the page size.
|
||||
|
||||
## Imports
|
||||
|
||||
```js
|
||||
import { Pagination } from '@strapi/helper-plugin';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
<Canvas>
|
||||
<Story name="base">
|
||||
{() => {
|
||||
const [{ query }, setQuery] = useQueryParams();
|
||||
useEffect(() => {
|
||||
setQuery({ pageSize: 10, page: 1, sort: 'firstname' });
|
||||
}, []);
|
||||
return (
|
||||
<Main>
|
||||
<Box paddingTop={6}>
|
||||
<Pagination pagination={{ pageCount: 10 }} />
|
||||
</Box>
|
||||
</Main>
|
||||
);
|
||||
}}
|
||||
</Story>
|
||||
</Canvas>
|
||||
|
||||
### Props
|
||||
|
||||
<ArgsTable of={Pagination} />
|
||||
@ -30,7 +30,7 @@ import { stringify } from 'qs';
|
||||
|
||||
const Pagination = ({ pagination: { pageCount } }) => {
|
||||
const [{ query }] = useQueryParams();
|
||||
const activePage = parseInt(query.page, 10);
|
||||
const activePage = parseInt(query?.page || '1', 10);
|
||||
const { pathname } = useLocation();
|
||||
const { formatMessage } = useIntl();
|
||||
const makeSearch = page => stringify({ ...query, page }, { encode: false });
|
||||
@ -47,6 +47,39 @@ const Pagination = ({ pagination: { pageCount } }) => {
|
||||
</PageLink>,
|
||||
];
|
||||
|
||||
if (pageCount <= 4) {
|
||||
const links = Array.from({ length: pageCount })
|
||||
.map((_, i) => i + 1)
|
||||
.map(number => {
|
||||
return (
|
||||
<PageLink key={number} number={number} to={`${pathname}?${makeSearch(number)}`}>
|
||||
{formatMessage(
|
||||
{ id: 'components.pagination.go-to', defaultMessage: 'Go to page {page}' },
|
||||
{ page: number }
|
||||
)}
|
||||
</PageLink>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<PaginationCompo activePage={activePage} pageCount={pageCount}>
|
||||
<PreviousLink to={`${pathname}?${previousSearch}`}>
|
||||
{formatMessage({
|
||||
id: 'components.pagination.go-to-previous',
|
||||
defaultMessage: 'Go to previous page',
|
||||
})}
|
||||
</PreviousLink>
|
||||
{links}
|
||||
<NextLink to={`${pathname}?${nextSearch}`}>
|
||||
{formatMessage({
|
||||
id: 'components.pagination.go-to-next',
|
||||
defaultMessage: 'Go to next page',
|
||||
})}
|
||||
</NextLink>
|
||||
</PaginationCompo>
|
||||
);
|
||||
}
|
||||
|
||||
let firstLinksToCreate = [];
|
||||
let lastLinks = [];
|
||||
let lastLinksToCreate = [];
|
||||
@ -0,0 +1,559 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Pagination /> should display the dots correctly 1`] = `
|
||||
.c6 {
|
||||
font-weight: 400;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c11 {
|
||||
font-weight: 500;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
border: 0;
|
||||
-webkit-clip: rect(0 0 0 0);
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.c1 > * + * {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.c7 {
|
||||
line-height: revert;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c9 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c5:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c10 {
|
||||
color: #271fe0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.c10:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c3 {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.c3 svg path {
|
||||
fill: #666687;
|
||||
}
|
||||
|
||||
.c3:focus svg path,
|
||||
.c3:hover svg path {
|
||||
fill: #4a4a6a;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
<nav
|
||||
aria-label="pagination"
|
||||
class=""
|
||||
>
|
||||
<ul
|
||||
class="c0 c1"
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="false"
|
||||
class="c2 c3 active"
|
||||
href="/test?page=4&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to previous page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.88 14.12L3.773 8 9.88 1.88 8 0 0 8l8 8 1.88-1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c5 active"
|
||||
href="/test?page=1&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 1
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="c2 c8"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
And 4 other links
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
…
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c5 active"
|
||||
href="/test?page=4&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 4
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
4
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c9 c10 active"
|
||||
href="/test?page=5&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 5
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c11 c7"
|
||||
>
|
||||
5
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c5 active"
|
||||
href="/test?page=6&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 6
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
6
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="c2 c8"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
And 8 other links
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
…
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c5 active"
|
||||
href="/test?page=10&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 10
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c6 c7"
|
||||
>
|
||||
10
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="false"
|
||||
class="c2 c3 active"
|
||||
href="/test?page=6&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to next page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0 1.88L6.107 8 0 14.12 1.88 16l8-8-8-8L0 1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
`;
|
||||
|
||||
exports[`<Pagination /> should work when the pageCount is inferior or equal to 4 1`] = `
|
||||
.c7 {
|
||||
font-weight: 500;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c10 {
|
||||
font-weight: 400;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
border: 0;
|
||||
-webkit-clip: rect(0 0 0 0);
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.c1 > * + * {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
line-height: revert;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
color: #271fe0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.c6:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c9 {
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c9:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c3 {
|
||||
font-size: 0.7rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.c3 svg path {
|
||||
fill: #c0c0cf;
|
||||
}
|
||||
|
||||
.c3:focus svg path,
|
||||
.c3:hover svg path {
|
||||
fill: #c0c0cf;
|
||||
}
|
||||
|
||||
.c11 {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.c11 svg path {
|
||||
fill: #666687;
|
||||
}
|
||||
|
||||
.c11:focus svg path,
|
||||
.c11:hover svg path {
|
||||
fill: #4a4a6a;
|
||||
}
|
||||
|
||||
<nav
|
||||
aria-label="pagination"
|
||||
class=""
|
||||
>
|
||||
<ul
|
||||
class="c0 c1"
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="true"
|
||||
class="c2 c3 active"
|
||||
href="/test"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to previous page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.88 14.12L3.773 8 9.88 1.88 8 0 0 8l8 8 1.88-1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c5 c6 active"
|
||||
href="/test?page=1&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 1
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c7 c8"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c9 active"
|
||||
href="/test?page=2&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 2
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c10 c8"
|
||||
>
|
||||
2
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c9 active"
|
||||
href="/test?page=3&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 3
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c10 c8"
|
||||
>
|
||||
3
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c2 c9 active"
|
||||
href="/test?page=4&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 4
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c10 c8"
|
||||
>
|
||||
4
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="false"
|
||||
class="c2 c11 active"
|
||||
href="/test?page=2&pageSize=10&sort=firstname"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to next page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0 1.88L6.107 8 0 14.12 1.88 16l8-8-8-8L0 1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
`;
|
||||
@ -0,0 +1,301 @@
|
||||
/**
|
||||
*
|
||||
* Tests for Pagination
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { ThemeProvider, lightTheme } from '@strapi/parts';
|
||||
import Pagination from '../index';
|
||||
|
||||
const messages = {
|
||||
en: {
|
||||
'components.pagination.go-to': 'Go to page {page}',
|
||||
'components.pagination.go-to-previous': 'Go to previous page',
|
||||
'components.pagination.remaining-links': 'And {number} other links',
|
||||
'components.pagination.go-to-next': 'Go to next page',
|
||||
},
|
||||
};
|
||||
|
||||
const makeApp = (history, pageCount) => (
|
||||
<Router history={history}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<IntlProvider locale="en" messages={messages} textComponent="span">
|
||||
<Pagination pagination={{ pageCount }} />
|
||||
</IntlProvider>
|
||||
</ThemeProvider>
|
||||
</Router>
|
||||
);
|
||||
|
||||
describe('<Pagination />', () => {
|
||||
it('renders and matches the snapshot', () => {
|
||||
const history = createMemoryHistory();
|
||||
const {
|
||||
container: { firstChild },
|
||||
} = render(makeApp(history, 1));
|
||||
|
||||
expect(firstChild).toMatchInlineSnapshot(`
|
||||
.c7 {
|
||||
font-weight: 500;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
color: #32324d;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c4 {
|
||||
border: 0;
|
||||
-webkit-clip: rect(0 0 0 0);
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.c1 > * + * {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
line-height: revert;
|
||||
}
|
||||
|
||||
.c2 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
-webkit-text-decoration: none;
|
||||
text-decoration: none;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
color: #271fe0;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.c6:hover {
|
||||
box-shadow: 0px 1px 4px rgba(33,33,52,0.1);
|
||||
}
|
||||
|
||||
.c3 {
|
||||
font-size: 0.7rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.c3 svg path {
|
||||
fill: #c0c0cf;
|
||||
}
|
||||
|
||||
.c3:focus svg path,
|
||||
.c3:hover svg path {
|
||||
fill: #c0c0cf;
|
||||
}
|
||||
|
||||
<nav
|
||||
aria-label="pagination"
|
||||
class=""
|
||||
>
|
||||
<ul
|
||||
class="c0 c1"
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="true"
|
||||
class="c2 c3 active"
|
||||
href="/"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to previous page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.88 14.12L3.773 8 9.88 1.88 8 0 0 8l8 8 1.88-1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="c5 c6 active"
|
||||
href="/?page=1"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to page 1
|
||||
</div>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="c7 c8"
|
||||
>
|
||||
1
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
aria-current="page"
|
||||
aria-disabled="true"
|
||||
class="c2 c3 active"
|
||||
href="/"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="c4"
|
||||
>
|
||||
Go to next page
|
||||
</div>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 10 16"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M0 1.88L6.107 8 0 14.12 1.88 16l8-8-8-8L0 1.88z"
|
||||
fill="#32324D"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
`);
|
||||
});
|
||||
|
||||
it('should display 3 links when the active page is 1 and the pageCount is greater than 5', () => {
|
||||
const history = createMemoryHistory();
|
||||
render(makeApp(history, 10));
|
||||
|
||||
expect(screen.getByText('Go to page 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 2')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 3')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('And 8 other links')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 10')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should change the page correctly', async () => {
|
||||
const history = createMemoryHistory();
|
||||
history.push({ pathname: '/test', search: 'page=3&pageSize=10&sort=firstname' });
|
||||
render(makeApp(history, 10));
|
||||
|
||||
expect(screen.getByText('Go to page 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 2')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 3')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 4')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 5')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('And 6 other links')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 10')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText('Go to page 4'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(history.location.pathname).toEqual('/test');
|
||||
expect(history.location.search).toEqual('?page=4&pageSize=10&sort=firstname');
|
||||
expect(screen.queryByText('Go to page 5')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('should display the dots correctly', () => {
|
||||
const history = createMemoryHistory();
|
||||
history.push({ pathname: '/test', search: 'page=5&pageSize=10&sort=firstname' });
|
||||
const {
|
||||
container: { firstChild },
|
||||
} = render(makeApp(history, 10));
|
||||
|
||||
expect(firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should work when the pageCount is inferior or equal to 4', async () => {
|
||||
const history = createMemoryHistory();
|
||||
history.push({ pathname: '/test', search: 'page=1&pageSize=10&sort=firstname' });
|
||||
const {
|
||||
container: { firstChild },
|
||||
} = render(makeApp(history, 4));
|
||||
|
||||
expect(firstChild).toMatchSnapshot();
|
||||
|
||||
fireEvent.click(screen.getByText('Go to page 2'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(history.location.pathname).toEqual('/test');
|
||||
expect(history.location.search).toEqual('?page=2&pageSize=10&sort=firstname');
|
||||
expect(screen.getByText('Go to page 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 2')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 3')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 4')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText('Go to page 3'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(history.location.pathname).toEqual('/test');
|
||||
expect(history.location.search).toEqual('?page=3&pageSize=10&sort=firstname');
|
||||
expect(screen.getByText('Go to page 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 2')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 3')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 4')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText('Go to page 4'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(history.location.pathname).toEqual('/test');
|
||||
expect(history.location.search).toEqual('?page=4&pageSize=10&sort=firstname');
|
||||
expect(screen.getByText('Go to page 1')).toBeInTheDocument();
|
||||
expect(screen.getByText('Go to page 2')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 3')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Go to page 4')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -195,6 +195,8 @@ export { default as SettingsPageTitle } from './components/SettingsPageTitle';
|
||||
export { default as Search } from './components/Search';
|
||||
export { default as Status } from './components/Status';
|
||||
export { default as Form } from './components/Form';
|
||||
export { default as Pagination } from './components/Pagination';
|
||||
export { default as PageSize } from './components/PageSize';
|
||||
|
||||
// New icons
|
||||
export { default as SortIcon } from './icons/SortIcon';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user