initial commit

This commit is contained in:
2021-12-10 12:03:04 +00:00
commit c46c7ddbf0
3643 changed files with 582794 additions and 0 deletions

View File

@ -0,0 +1,231 @@
/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Label from '@woocommerce/base-components/label';
/**
* Internal dependencies
*/
import { getIndexes } from './utils.js';
import './style.scss';
const Pagination = ( {
currentPage,
displayFirstAndLastPages,
displayNextAndPreviousArrows,
pagesToDisplay,
onPageChange,
totalPages,
} ) => {
let { minIndex, maxIndex } = getIndexes(
pagesToDisplay,
currentPage,
totalPages
);
const showFirstPage = displayFirstAndLastPages && Boolean( minIndex !== 1 );
const showLastPage =
displayFirstAndLastPages && Boolean( maxIndex !== totalPages );
const showFirstPageEllipsis =
displayFirstAndLastPages && Boolean( minIndex > 3 );
const showLastPageEllipsis =
displayFirstAndLastPages && Boolean( maxIndex < totalPages - 2 );
// Handle the cases where there would be an ellipsis replacing one single page
if ( showFirstPage && minIndex === 3 ) {
minIndex = minIndex - 1;
}
if ( showLastPage && maxIndex === totalPages - 2 ) {
maxIndex = maxIndex + 1;
}
const pages = [];
if ( minIndex && maxIndex ) {
for ( let i = minIndex; i <= maxIndex; i++ ) {
pages.push( i );
}
}
return (
<div className="wc-block-pagination wc-block-components-pagination">
<Label
screenReaderLabel={ __(
'Navigate to another page',
'woocommerce'
) }
/>
{ displayNextAndPreviousArrows && (
<button
className="wc-block-pagination-page wc-block-components-pagination__page wc-block-components-pagination-page--arrow"
onClick={ () => onPageChange( currentPage - 1 ) }
title={ __(
'Previous page',
'woocommerce'
) }
disabled={ currentPage <= 1 }
>
<Label
label="&larr;"
screenReaderLabel={ __(
'Previous page',
'woocommerce'
) }
/>
</button>
) }
{ showFirstPage && (
<button
className={ classNames(
'wc-block-pagination-page',
'wc-block-components-pagination__page',
{
'wc-block-pagination-page--active':
currentPage === 1,
'wc-block-components-pagination__page--active':
currentPage === 1,
}
) }
onClick={ () => onPageChange( 1 ) }
disabled={ currentPage === 1 }
>
<Label
label={ 1 }
screenReaderLabel={ sprintf(
/* translators: %d is the page number (1, 2, 3...). */
__( 'Page %d', 'woocommerce' ),
1
) }
/>
</button>
) }
{ showFirstPageEllipsis && (
<span
className="wc-block-pagination-ellipsis wc-block-components-pagination__ellipsis"
aria-hidden="true"
>
{ __( '…', 'woocommerce' ) }
</span>
) }
{ pages.map( ( page ) => {
return (
<button
key={ page }
className={ classNames(
'wc-block-pagination-page',
'wc-block-components-pagination__page',
{
'wc-block-pagination-page--active':
currentPage === page,
'wc-block-components-pagination__page--active':
currentPage === page,
}
) }
onClick={
currentPage === page
? null
: () => onPageChange( page )
}
disabled={ currentPage === page }
>
<Label
label={ page }
screenReaderLabel={ sprintf(
/* translators: %d is the page number (1, 2, 3...). */
__( 'Page %d', 'woocommerce' ),
page
) }
/>
</button>
);
} ) }
{ showLastPageEllipsis && (
<span
className="wc-block-pagination-ellipsis wc-block-components-pagination__ellipsis"
aria-hidden="true"
>
{ __( '…', 'woocommerce' ) }
</span>
) }
{ showLastPage && (
<button
className={ classNames(
'wc-block-pagination-page',
'wc-block-components-pagination__page',
{
'wc-block-pagination-page--active':
currentPage === totalPages,
'wc-block-components-pagination__page--active':
currentPage === totalPages,
}
) }
onClick={ () => onPageChange( totalPages ) }
disabled={ currentPage === totalPages }
>
<Label
label={ totalPages }
screenReaderLabel={ sprintf(
/* translators: %d is the page number (1, 2, 3...). */
__( 'Page %d', 'woocommerce' ),
totalPages
) }
/>
</button>
) }
{ displayNextAndPreviousArrows && (
<button
className="wc-block-pagination-page wc-block-components-pagination__page wc-block-components-pagination-page--arrow"
onClick={ () => onPageChange( currentPage + 1 ) }
title={ __( 'Next page', 'woocommerce' ) }
disabled={ currentPage >= totalPages }
>
<Label
label="&rarr;"
screenReaderLabel={ __(
'Next page',
'woocommerce'
) }
/>
</button>
) }
</div>
);
};
Pagination.propTypes = {
/**
* Number of the page currently being displayed.
*/
currentPage: PropTypes.number.isRequired,
/**
* Total number of pages.
*/
totalPages: PropTypes.number.isRequired,
/**
* Displays first and last pages if they are not in the current range of pages displayed.
*/
displayFirstAndLastPages: PropTypes.bool,
/**
* Displays arrows to navigate to the previous and next pages.
*/
displayNextAndPreviousArrows: PropTypes.bool,
/**
* Callback function called when the user triggers a page change.
*/
onPageChange: PropTypes.func,
/**
* Number of pages to display at the same time, including the active page
* and the pages displayed before and after it. It doesn't include the first
* and last pages.
*/
pagesToDisplay: PropTypes.number,
};
Pagination.defaultProps = {
displayFirstAndLastPages: true,
displayNextAndPreviousArrows: true,
pagesToDisplay: 3,
};
export default Pagination;

View File

@ -0,0 +1,56 @@
.wc-block-components-pagination {
margin: 0 auto $gap;
}
.wc-block-components-pagination__page,
.wc-block-components-pagination__ellipsis {
@include font-size(regular);
color: #333;
display: inline-block;
font-weight: normal;
}
.wc-block-components-pagination__page {
border-color: transparent;
padding: 0.3em 0.6em;
min-width: 2.2em;
@include breakpoint("<782px") {
padding: 0.1em 0.2em;
min-width: 1.6em;
}
// Twenty Twenty register a background color for buttons that is too specific
// and broad at the same time `button:not(.toggle)` so we're engaing in a
// specify war with them here.
// https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1203
&:not(.toggle) {
background-color: transparent;
}
}
.wc-block-components-pagination__ellipsis {
padding: 0.3em;
@include breakpoint("<782px") {
padding: 0.1em;
}
}
.wc-block-components-pagination__page--active[disabled] {
color: #333;
font-weight: bold;
opacity: 1 !important;
&:hover,
&:focus {
background-color: inherit;
color: #333;
opacity: 1 !important;
}
}
html[dir="rtl"] .wc-block-components-pagination-page--arrow span {
display: inline-block;
transform: scale(-1, 1);
}

View File

@ -0,0 +1,40 @@
/**
* Internal dependencies
*/
import { getIndexes } from '../utils.js';
describe( 'getIndexes', () => {
describe( 'when on the first page', () => {
test( 'indexes include the first pages available', () => {
expect( getIndexes( 5, 1, 100 ) ).toEqual( {
minIndex: 2,
maxIndex: 6,
} );
} );
test( 'indexes are null if there are 2 pages or less', () => {
expect( getIndexes( 5, 1, 1 ) ).toEqual( {
minIndex: null,
maxIndex: null,
} );
} );
} );
describe( 'when on a page in the middle', () => {
test( 'indexes include pages before and after the current page', () => {
expect( getIndexes( 5, 50, 100 ) ).toEqual( {
minIndex: 48,
maxIndex: 52,
} );
} );
} );
describe( 'when on the last page', () => {
test( 'indexes include the last pages available', () => {
expect( getIndexes( 5, 100, 100 ) ).toEqual( {
minIndex: 95,
maxIndex: 99,
} );
} );
} );
} );

View File

@ -0,0 +1,34 @@
/**
* Given the number of pages to display, the current page and the total pages,
* returns the min and max index of the pages to display in the pagination component.
*
* @param {number} pagesToDisplay Maximum number of pages to display in the pagination component.
* @param {number} currentPage Page currently visible.
* @param {number} totalPages Total pages available.
* @return {Object} Object containing the min and max index to display in the pagination component.
*/
export const getIndexes = ( pagesToDisplay, currentPage, totalPages ) => {
if ( totalPages <= 2 ) {
return { minIndex: null, maxIndex: null };
}
const extraPagesToDisplay = pagesToDisplay - 1;
const tentativeMinIndex = Math.max(
Math.floor( currentPage - extraPagesToDisplay / 2 ),
2
);
const maxIndex = Math.min(
Math.ceil(
currentPage +
( extraPagesToDisplay - ( currentPage - tentativeMinIndex ) )
),
totalPages - 1
);
const minIndex = Math.max(
Math.floor(
currentPage - ( extraPagesToDisplay - ( maxIndex - currentPage ) )
),
2
);
return { minIndex, maxIndex };
};