diff --git a/frontend/packages/shared/CHANGELOG.MD b/frontend/packages/shared/CHANGELOG.MD index 4df77fd7e..955662bcd 100644 --- a/frontend/packages/shared/CHANGELOG.MD +++ b/frontend/packages/shared/CHANGELOG.MD @@ -14,13 +14,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - New `NativeSelect` and `NativeSelectWithLabel` components for mobile phone use +- Extracted `Pagination` component to ensure that pagination controls are consistent across usages ### Changed - `LanguageSelect` to use `NativeSelect` when rendered on mobile phone - `LanguageSelect` now requires `onLanguageChange` prop -- `ComboBox` to use fall back to `NativeSelect` when render on mobile phone +- `ComboBox` to fall back to `NativeSelect` when render on mobile phone - `ComboBox` onChange prop signature has changed to: `onChange: (value?: string) => void` +- `Pagination` rowsPerPage select to fall back to `NativeSelect` on mobile phone ## [1.9.30] - 2023-10-24 diff --git a/frontend/packages/shared/src/components/Table/ManagedPaginatedTable.tsx b/frontend/packages/shared/src/components/Table/ManagedPaginatedTable.tsx index f35498b59..5f9970233 100644 --- a/frontend/packages/shared/src/components/Table/ManagedPaginatedTable.tsx +++ b/frontend/packages/shared/src/components/Table/ManagedPaginatedTable.tsx @@ -1,10 +1,8 @@ -import { Table, TableBody, TablePagination } from '@mui/material'; -import { ChangeEvent, Fragment, useRef } from 'react'; +import { Table, TableBody } from '@mui/material'; +import { Fragment, useRef } from 'react'; -import { - defaultDisplayedRowsLabel, - PaginatedTableProps, -} from './PaginatedTable'; +import { PaginatedTableProps } from './PaginatedTable'; +import { Pagination } from './Pagination'; import { WithId } from '../../interfaces/with'; import './Table.scss'; @@ -24,47 +22,37 @@ export function ManagedPaginatedTable({ header, data, getRowDetails, - rowsPerPageOptions, className, stickyHeader, showBottomPagination = true, - rowsPerPageLabel, headerContent, page, size = 'medium', onPageChange, rowsPerPage, onRowsPerPageChange, - labelDisplayedRows, - backIconButtonProps, - nextIconButtonProps, + ...paginationOnlyProps }: ManagedPaginatedTableProps): JSX.Element { const headerRef = useRef(null); const handlePageChange = (page: number) => { onPageChange(page); headerRef.current?.scrollIntoView(); }; - const handleRowsPerPageChange = (event: ChangeEvent) => { + const handleRowsPerPageChange = (rowsPerPage: number) => { handlePageChange(0); - onRowsPerPageChange(+event.target.value); + onRowsPerPageChange(rowsPerPage); }; const count = data.length; - const Pagination = () => ( - handlePageChange(newPage)} + const paginationControls = ( + ); @@ -72,7 +60,7 @@ export function ManagedPaginatedTable({ <>
{headerContent} - + {paginationControls}
({
{showBottomPagination && ( -
- -
+
{paginationControls}
)} ); diff --git a/frontend/packages/shared/src/components/Table/PaginatedTable.tsx b/frontend/packages/shared/src/components/Table/PaginatedTable.tsx index 5c5572d66..5ff6f8d4b 100644 --- a/frontend/packages/shared/src/components/Table/PaginatedTable.tsx +++ b/frontend/packages/shared/src/components/Table/PaginatedTable.tsx @@ -3,22 +3,14 @@ import { LabelDisplayedRowsArgs, Table, TableBody, - TablePagination, } from '@mui/material'; -import { ChangeEvent, Fragment, useRef, useState } from 'react'; +import { Fragment, useRef, useState } from 'react'; import { CustomTableProps } from './CustomTable'; +import { Pagination } from './Pagination'; import { WithId } from '../../interfaces/with'; import './Table.scss'; -export const defaultDisplayedRowsLabel = ({ - from, - to, - count, -}: LabelDisplayedRowsArgs) => { - return `${from} - ${to} / ${count}`; -}; - export interface PaginatedTableProps extends CustomTableProps { initialRowsPerPage: number; @@ -48,17 +40,13 @@ export function PaginatedTable({ data, getRowDetails, initialRowsPerPage, - rowsPerPageOptions, className, stickyHeader, showBottomPagination = true, - rowsPerPageLabel, headerContent, size = 'medium', - labelDisplayedRows, - backIconButtonProps, - nextIconButtonProps, controlledPaging, + ...paginationOnlyProps }: PaginatedTableProps): JSX.Element { const headerRef = useRef(null); const [internalPage, setInternalPage] = useState(0); @@ -67,29 +55,23 @@ export function PaginatedTable({ setPage(page); headerRef.current?.scrollIntoView(); }; - const handleRowsPerPageChange = (event: ChangeEvent) => { + const handleRowsPerPageChange = (rowsPerPage: number) => { handlePageChange(0); - setRowsPerPage(+event.target.value); + setRowsPerPage(rowsPerPage); }; const page = controlledPaging?.page ?? internalPage; const setPage = controlledPaging?.setPage ?? setInternalPage; const count = data.length; - const Pagination = ({ page }: { page: number }) => ( - handlePageChange(newPage)} + const paginationControls = ( + ); @@ -97,7 +79,7 @@ export function PaginatedTable({ <>
{headerContent} - + {paginationControls}
({ })}
- {showBottomPagination && } + {showBottomPagination && { paginationControls }} ); } diff --git a/frontend/packages/shared/src/components/Table/Pagination.tsx b/frontend/packages/shared/src/components/Table/Pagination.tsx new file mode 100644 index 000000000..76fbcf9d9 --- /dev/null +++ b/frontend/packages/shared/src/components/Table/Pagination.tsx @@ -0,0 +1,55 @@ +import { LabelDisplayedRowsArgs, TablePagination } from '@mui/material'; + +import { PaginatedTableProps } from './PaginatedTable'; +import { useWindowProperties } from '../../hooks'; +import { WithId } from '../../interfaces'; +import './Table.scss'; + +interface PaginationProps { + count: number; + handlePageChange: (page: number) => void; + handleRowsPerPageChange: (rowsPerPage: number) => void; + page: number; + rowsPerPage: number; +} + +const defaultDisplayedRowsLabel = ({ + from, + to, + count, +}: LabelDisplayedRowsArgs) => { + return `${from} - ${to} / ${count}`; +}; + +export function Pagination({ + count, + handlePageChange, + handleRowsPerPageChange, + labelDisplayedRows, + page, + rowsPerPage, + rowsPerPageOptions, + rowsPerPageLabel, + backIconButtonProps, + nextIconButtonProps, +}: Partial> & PaginationProps): JSX.Element { + const { isPhone } = useWindowProperties(); + + return ( + handlePageChange(newPage)} + page={page} + onRowsPerPageChange={(e) => handleRowsPerPageChange(+e.target.value)} + rowsPerPage={rowsPerPage} + rowsPerPageOptions={rowsPerPageOptions} + labelRowsPerPage={rowsPerPageLabel} + labelDisplayedRows={labelDisplayedRows ?? defaultDisplayedRowsLabel} + backIconButtonProps={backIconButtonProps} + nextIconButtonProps={nextIconButtonProps} + SelectProps={{ native: isPhone }} + /> + ); +} diff --git a/frontend/packages/shared/src/components/index.tsx b/frontend/packages/shared/src/components/index.tsx index 218401b99..f14530aa0 100644 --- a/frontend/packages/shared/src/components/index.tsx +++ b/frontend/packages/shared/src/components/index.tsx @@ -33,8 +33,9 @@ export { DropDownMenuButton } from './DropDownMenuButton/DropDownMenuButton'; export { SkipLink } from './SkipLink/SkipLink'; export { Svg } from './Svg/Svg'; export { CustomTable } from './Table/CustomTable'; -export { PaginatedTable } from './Table/PaginatedTable'; export { ManagedPaginatedTable } from './Table/ManagedPaginatedTable'; +export { PaginatedTable } from './Table/PaginatedTable'; +export { Pagination } from './Table/Pagination'; export { ToggleFilterGroup } from './ToggleFilterGroup/ToggleFilterGroup'; export { LangSelector } from './LangSelector/LangSelector'; export { InfoText } from './InfoText/InfoText';