1+ import { useEffect , useState } from "react" ;
12
23interface PaginationControlsProps {
34 currentPage : number ;
45 totalCount : number ;
56 itemsPerPage : number ;
67 dataLength ?: number ;
7- onNext : ( ) => void ;
8- onPrevious : ( ) => void ;
8+ onPageChange : ( page : number ) => void ;
99}
1010
1111export const PaginationControls = ( {
1212 currentPage,
1313 totalCount,
1414 itemsPerPage,
1515 dataLength,
16- onNext,
17- onPrevious
16+ onPageChange
1817} : PaginationControlsProps ) => {
18+ const [ inputValue , setInputValue ] = useState ( ( currentPage + 1 ) . toString ( ) ) ;
19+
20+ const totalPages = Math . ceil ( totalCount / itemsPerPage ) ;
21+
22+ useEffect ( ( ) => {
23+ setInputValue ( ( currentPage + 1 ) . toString ( ) ) ;
24+ } , [ currentPage ] ) ;
25+ const handleInputChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
26+ setInputValue ( e . target . value ) ;
27+ } ;
28+ const handlePageChange = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
29+ if ( e . key === 'Enter' ) {
30+ const page = parseInt ( inputValue ) ;
31+ if ( ! isNaN ( page ) && page > 0 && page <= totalPages ) {
32+ onPageChange ( page - 1 ) ;
33+ } else {
34+ // Reset to current page if invalid
35+ setInputValue ( ( currentPage + 1 ) . toString ( ) ) ;
36+ }
37+ }
38+ } ;
39+
1940 return (
20- < div className = { 'flex items-center' } >
21- < div style = { { borderRight : '1px solid #00c4ff' } } >
22- < button
23- onClick = { onPrevious }
24- disabled = { currentPage === 0 }
25- className = { 'p-1 bg-transparent border-0 hover:text-blue-400' }
26- >
27- ⟵
28- </ button >
29- < span > { currentPage + 1 } of { Math . ceil ( totalCount / itemsPerPage ) } </ span >
30- < button
31- onClick = { onNext }
32- disabled = { Boolean ( ( dataLength && dataLength < itemsPerPage ) ) }
33- className = { 'p-1 bg-transparent border-0 hover:text-blue-400' }
34- >
35- ⟶
36- </ button >
37- </ div >
38- < div >
39- < span style = { { paddingLeft : '5px' } } > [{ Math . min ( ( ( currentPage ) * itemsPerPage ) + 1 , totalCount ) } ..{ Math . min ( ( currentPage + 1 ) * itemsPerPage , totalCount ) } of { totalCount } ]</ span >
40- </ div >
41+ < div className = { 'flex items-center whitespace-nowrap' } >
42+ < div style = { { borderRight : '1px solid #00c4ff' } } className = "flex items-center" >
43+ < button
44+ onClick = { ( ) => onPageChange ( currentPage - 1 ) }
45+ disabled = { currentPage === 0 }
46+ className = { 'p-1 bg-transparent border-0 hover:text-blue-400' }
47+ >
48+ ⟵
49+ </ button >
50+ < input
51+ // type="number"
52+ min = { 1 }
53+ max = { totalPages }
54+ value = { inputValue }
55+ onChange = { handleInputChange }
56+ onKeyDown = { handlePageChange }
57+ className = "w-12 mx-1 text-center bg-transparent border border-gray-400 focus:outline-none appearance-none"
58+ style = { { WebkitAppearance : 'none' , MozAppearance : 'textfield' } }
59+ />
60+ < span > of { totalPages } </ span >
61+ < button
62+ onClick = { ( ) => onPageChange ( currentPage + 1 ) }
63+ disabled = { Boolean ( ( dataLength && dataLength < itemsPerPage ) ) }
64+ className = { 'p-1 bg-transparent border-0 hover:text-blue-400' }
65+ >
66+ ⟶
67+ </ button >
68+ </ div >
69+ < div >
70+ < span style = { { paddingLeft : '5px' } } > [{ Math . min ( ( ( currentPage ) * itemsPerPage ) + 1 , totalCount ) } ..{ Math . min ( ( currentPage + 1 ) * itemsPerPage , totalCount ) } of { totalCount } ]</ span >
71+ </ div >
4172 </ div >
4273 ) ;
4374} ;
0 commit comments