Pagination
A set of presentational components for building pagination UI.
Import
import { Pagination } from "@dhua5922/react-native-kit";
Basic Example
Live Editor
function Example() { return ( <Pagination> <Pagination.Item> <Pagination.First /> </Pagination.Item> <Pagination.Item> <Pagination.Previous /> </Pagination.Item> <Pagination.Item disabled>Page 1 of 20</Pagination.Item> <Pagination.Item> <Pagination.Next /> </Pagination.Item> <Pagination.Item> <Pagination.Last /> </Pagination.Item> </Pagination> ); }
Result
Loading...
Paginated Table Example
Live Editor
function PaginatedList() { const [currentPage, setCurrentPage] = useState(0); const pageSize = 3; const headers = ["Header 1", "Header 2"]; const list = [ ["Cell 1", "Cell 2"], ["Cell 3", "Cell 4"], ["Cell 5", "Cell 6"], ["Cell 7", "Cell 8"], ["Cell 9", "Cell 10"], ["Cell 11", "Cell 12"], ["Cell 13", "Cell 14"], ["Cell 15", "Cell 16"], ]; const startIndex = currentPage * pageSize; const paginatedRows = list.slice(startIndex, startIndex + pageSize); return ( <> <Table border hover striped> <Table.tr> {headers.map((header, index) => ( <Table.th key={index}>{header}</Table.th> ))} </Table.tr> {paginatedRows.map((row, index) => ( <Table.tr key={index} striped={index % 2 === 0}> {row.map((children, index) => ( <Table.td key={index}>{children}</Table.td> ))} </Table.tr> ))} </Table> <Center> <Pagination style={{ marginTop: 20 }}> <Pagination.Item onPress={() => setCurrentPage(0)}> <Pagination.First /> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage(Math.max(0, currentPage - 1))} > <Pagination.Previous /> </Pagination.Item> <Pagination.Item disabled> <Text> Page {currentPage + 1} of {Math.ceil(list.length / pageSize)} </Text> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage( Math.min(currentPage + 1, Math.floor(list.length / pageSize)), ) } > <Pagination.Next /> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage(Math.floor(list.length / pageSize))} > <Pagination.Last /> </Pagination.Item> </Pagination> </Center> </> ); }
Result
Loading...
Paginated Table With Filtering Example
Live Editor
function PaginatedList() { const pageSize = 3; const headers = [ { columnName: "First Name", propertyName: "firstName", }, { columnName: "Last Name", propertyName: "lastName", }, ]; const list = [ { firstName: "Matt", lastName: "Steve", }, { firstName: "John", lastName: "Paul", }, { firstName: "Kate", lastName: "Like", }, { firstName: "Bart", lastName: "Homer", }, { firstName: "Cain", lastName: "Kin", }, { firstName: "Dylan", lastName: "Port", }, { firstName: "Ava", lastName: "Alter", }, { firstName: "Lex", lastName: "Altman", }, ]; const [filteredList, setFilteredList] = useState(list.slice()); const [tableHeaders, setTableHeaders] = useState( headers.map((header) => ({ ...header, showMenu: false, isSortAscending: false, isSortDescending: false, filterValue: "", isCheckingEqual: false, pickedEqualCheck: false, isCheckingContains: false, pickedContainsCheck: false, })), ); const [currentPage, setCurrentPage] = useState(0); const startIndex = currentPage * pageSize; const paginatedRows = filteredList.slice(startIndex, startIndex + pageSize); const lastPageNumDisplay = Math.ceil(filteredList.length / pageSize || 1); const lastPageIndex = lastPageNumDisplay - 1; function modifyTableHeader(updatedTableHeader, index) { function differentChosenSortMapping() { const hasChoseDifferentSortProperty = updatedTableHeader.isSortAscending || updatedTableHeader.isSortDescending; return (header) => ({ ...header, isSortAscending: hasChoseDifferentSortProperty ? false : header.isSortAscending, isSortDescending: hasChoseDifferentSortProperty ? false : header.isSortDescending, }); } setTableHeaders([ ...tableHeaders.slice(0, index).map(differentChosenSortMapping()), { ...tableHeaders[index], ...updatedTableHeader }, ...tableHeaders.slice(index + 1).map(differentChosenSortMapping()), ]); } function sort(firstValue, secondValue) { const stringA = firstValue.toLowerCase(); const stringB = secondValue.toLowerCase(); if (stringA < stringB) { return -1; } else if (stringA > stringB) { return 1; } return 0; } function filterList() { let newList = list .filter((person) => { return tableHeaders.every((header, index) => { const value = ("" + person[header.propertyName]).toLowerCase(); if (header.pickedEqualCheck && header.isCheckingEqual) { return value === header.filterValue.toLowerCase(); } else if (header.pickedContainsCheck && header.isCheckingContains) { return value.includes(header.filterValue.toLowerCase()); } return true; }); }) .slice(); const headerWithSort = tableHeaders.find( (header) => header.isSortAscending || header.isSortDescending, ); headerWithSort && newList.sort((personA, personB) => headerWithSort.isSortAscending ? sort( personA[headerWithSort.propertyName], personB[headerWithSort.propertyName], ) : sort( personB[headerWithSort.propertyName], personA[headerWithSort.propertyName], ), ); return newList; } useEffect(() => { setFilteredList(filterList()); }, [JSON.stringify(tableHeaders)]); return ( <> <Table border hover striped> <Table.tr> {tableHeaders.map((header, columnIndex) => ( <Table.th key={columnIndex}> <Menu showMenu={header.showMenu} onShowMenu={() => modifyTableHeader({ showMenu: true }, columnIndex) } onHideMenu={() => modifyTableHeader({ showMenu: false }, columnIndex) } > <Menu.Toggle > <Row> <Text bold>{header.columnName} </Text> {(header.isCheckingEqual || header.isCheckingContains) && ( <FontAwesome5 name="filter" size={20} /> )} {header.isSortAscending && "↑"} {header.isSortDescending && "↓"} </Row> </Menu.Toggle> <Menu.Content> {[ { label: "Clear Filter", active: false, onPress: () => modifyTableHeader( { ...header, showMenu: false, isSortAscending: false, isSortDescending: false, filterValue: "", isCheckingEqual: false, pickedEqualCheck: false, isCheckingContains: false, pickedContainsCheck: false, }, columnIndex, ), }, { label: "Sort Ascending", active: header.isSortAscending, onPress: () => modifyTableHeader( { isSortAscending: true, isSortDescending: false, showMenu: false, }, columnIndex, ), }, { label: "Sort Descending", active: header.isSortDescending, onPress: () => modifyTableHeader( { isSortAscending: false, isSortDescending: true, showMenu: false, }, columnIndex, ), }, { label: "Equals", active: header.pickedEqualCheck, onPress: () => modifyTableHeader( { pickedEqualCheck: true, pickedContainsCheck: false, }, columnIndex, ), }, { label: "Contains", active: header.pickedContainsCheck, onPress: () => modifyTableHeader( { pickedEqualCheck: false, pickedContainsCheck: true, }, columnIndex, ), }, ].map(({ label, onPress, active }, index) => ( <Menu.Item key={index}> <Pressable onPress={() => { onPress(); setCurrentPage(0); }} > {active && "-> "} {label} </Pressable> </Menu.Item> ))} <Menu.Item> <Input.Search placeholder="Type filter value here" value={header.filterValue} onChangeText={(text) => { modifyTableHeader( { filterValue: text, }, columnIndex, ); }} /> </Menu.Item> <Menu.Item onPress={() => {}}> <Row style={{ justifyContent: "flex-end" }}> <Button style={{ marginRight: 8 }} onPress={() => { setFilteredList( filterList( header.isSortAscending, header.isSortDescending, header.propertyName, ), ); modifyTableHeader( { isCheckingEqual: header.pickedEqualCheck, isCheckingContains: header.pickedContainsCheck, showMenu: false, }, columnIndex, ); }} > OK </Button> <Button onPress={() => { modifyTableHeader( { showMenu: false, }, columnIndex, ); }} > CANCEL </Button> </Row> </Menu.Item> </Menu.Content> </Menu> </Table.th> ))} </Table.tr> {paginatedRows.map((person, index) => ( <Table.tr key={index} striped={index % 2 === 0}> {tableHeaders.map((header, headerIndex) => ( <Table.td key={headerIndex}> {person[header.propertyName]} </Table.td> ))} </Table.tr> ))} </Table> <Center> <Pagination style={{ marginTop: 20 }}> <Pagination.Item onPress={() => setCurrentPage(0)}> <Pagination.First /> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage(Math.max(0, currentPage - 1))} > <Pagination.Previous /> </Pagination.Item> <Pagination.Item disabled> <Text> Page {currentPage + 1} of {lastPageNumDisplay} </Text> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage(Math.min(currentPage + 1, lastPageIndex)) } > <Pagination.Next /> </Pagination.Item> <Pagination.Item onPress={() => setCurrentPage(lastPageIndex)}> <Pagination.Last /> </Pagination.Item> </Pagination> </Center> </> ); }
Result
Loading...
Props
note
Include all props from Row