diff --git a/demo/DemoTable.tsx b/demo/DemoTable.tsx index 1b4fb93..62f5df1 100644 --- a/demo/DemoTable.tsx +++ b/demo/DemoTable.tsx @@ -123,7 +123,7 @@ export function DemoTable() new Promise((resolve) => { // Resolving promise in 2s. window.setTimeout(() => { - resolve(Array.from({ length: 15 }).map(() => { + resolve(Array.from({ length: 43 }).map(() => { // Compute random quantity and unit price. const name = randomName(); const quantity = randomQuantity(); @@ -166,6 +166,6 @@ export function DemoTable() ), []); return ( - + ); } diff --git a/src/Smartable/Instance.tsx b/src/Smartable/Instance.tsx index 22a6051..d6d794b 100644 --- a/src/Smartable/Instance.tsx +++ b/src/Smartable/Instance.tsx @@ -5,6 +5,7 @@ import {RowInstance, RowLoader} from "./Row"; import {useAsyncManager} from "./AsyncManager"; import {ColumnHeading} from "./Columns/ColumnHeading"; import {sortRows} from "./Sort"; +import {AutoPaginate} from "@kernelui/core"; /** * Smartable instance component properties. @@ -20,7 +21,52 @@ export interface InstanceProperties extends SmartablePrope /** * Main component for a Smartable table. */ -export function Instance({columns}: InstanceProperties) +export function Instance(props: InstanceProperties) +{ + if (props.paginate) + { // If pagination is enabled. + return + } + else + { // No pagination, simple body render. + return ( + + +
+ ); + } +} + +/** + * Paginated Smartable instance component. + */ +export function PaginatedInstance(props: InstanceProperties) +{ + // Get data from table. + const {data} = useTable(); + + // Get current data state from the async table value. + const {currentDataState} = useAsyncManager(data); + + // Compute page count for the current rows. + const pageCount = Math.ceil((currentDataState?.rows?.length ?? 0) / props.paginate.pageSize); + + return ( + + {(page) => ( + // Render table with table body of the current page. + + +
+ )} +
+ ); +} + +/** + * Base component for a Smartable table. + */ +export function Table({columns, children}: React.PropsWithChildren>) { return ( @@ -28,7 +74,7 @@ export function Instance({columns}: InstanceProperties - + {children}
); @@ -65,7 +111,15 @@ export function ColumnsHeadings({columns}: {columns: Colum ); } -export function TableBody() +/** + * Smartable table body. + */ +export function TableBody({pagination}: { + /** + * Current pagination state. + */ + pagination?: { page: number; pageSize: number; }; +}) { // Get data from table. const {data, columns, columnsSortState, columnsFilterStates} = useTable(); @@ -85,10 +139,17 @@ export function TableBody() ), [currentDataState.rows, columnsFilterStates]); // Memorize sorted rows. - const sortedRows = useMemo(() => ( + let sortedRows = useMemo(() => ( + // Sort rows with the current columns sort state. sortRows(filteredRows, columns, columnsSortState) ), [filteredRows, columns, columnsSortState]); + if (pagination) + { // If pagination is enabled, showing only content of the current page. + const startIndex = (pagination.page - 1) * pagination.pageSize; + sortedRows = sortedRows?.slice(startIndex, startIndex + pagination.pageSize); + } + return ( sortedRows ? ( sortedRows.map((rowData, index) => ( diff --git a/src/Smartable/Smartable.tsx b/src/Smartable/Smartable.tsx index 38069e5..ab9ea40 100644 --- a/src/Smartable/Smartable.tsx +++ b/src/Smartable/Smartable.tsx @@ -34,6 +34,16 @@ export interface SmartableProperties * Default column heading element. */ columnHeadingElement?: React.ReactElement; + + /** + * Table rows pagination. + */ + paginate?: { + /** + * Number of rows per page. + */ + pageSize: number; + }; } /** diff --git a/src/styles/smartable.less b/src/styles/smartable.less index 516ab48..1511c62 100644 --- a/src/styles/smartable.less +++ b/src/styles/smartable.less @@ -1,5 +1,7 @@ table.smartable { + margin: 0.5em auto; + @import "_cells"; @import "_filters"; @import "_headings";