Pagination.astro (4623B)
1 --- 2 interface Props { 3 pages: number; 4 currentPage?: number; 5 } 6 7 const { pages, currentPage = 1 } = Astro.props; 8 const parsed_url = new URL(Astro.request.url); 9 const prev_page_params = new URLSearchParams(parsed_url.searchParams); 10 prev_page_params.set('page', (currentPage-1).toString()); 11 const next_page_params = new URLSearchParams(parsed_url.searchParams); 12 next_page_params.set('page', (currentPage+1).toString()); 13 const range = Array(pages+1).fill(0, currentPage === 1 ? currentPage : currentPage - 1 , Math.min(currentPage + 5, pages+1)); 14 --- 15 16 <div id="nav"> 17 {currentPage != 1 ? 18 <a id="left" href={`/results?${prev_page_params.toString()}`}> 19 <svg 20 width="24" 21 height="24" 22 viewBox="0 0 24 24" 23 fill="none" 24 xmlns="http://www.w3.org/2000/svg" 25 > 26 <g clip-path="url(#clip0_13_147)"> 27 <path 28 d="M20 11H7.83L13.42 5.41L12 4L4 12L12 20L13.41 18.59L7.83 13H20V11Z" 29 fill="#323232"></path> 30 </g> 31 <defs> 32 <clipPath id="clip0_13_147"> 33 <rect width="24" height="24" fill="white"></rect> 34 </clipPath> 35 </defs> 36 </svg> 37 </a>:<></>} 38 {range.map( 39 (_, i) => { 40 const new_params = new URLSearchParams(parsed_url.searchParams); 41 new_params.set('page', i.toString()); 42 return ( 43 <> 44 { 45 i === currentPage ? ( 46 i === 1 ? <a class="middle current rounded-start" href={`/results?${new_params.toString()}`}>{i}</a> : (i === pages && !(Math.min(currentPage + 5, currentPage) !== pages) ? <a class="middle current rounded-end" href={`/results?${new_params.toString()}`}>{i}</a> : <a class="middle current" href={`/results?${new_params.toString()}`}>{i}</a>) 47 ) : (i === pages && !(Math.min(currentPage + 5, currentPage) !== pages) ? <a class="middle rounded-end" href={`/results?${new_params.toString()}`}>{i}</a> : <a class="middle" href={`/results?${new_params.toString()}`}>{i}</a>) 48 } 49 </> 50 ); 51 })} 52 {Math.min(currentPage + 5, currentPage) !== pages ? 53 <a id="right" href={`/results?${next_page_params.toString()}`}> 54 <svg 55 width="24" 56 height="24" 57 viewBox="0 0 24 24" 58 fill="none" 59 xmlns="http://www.w3.org/2000/svg" 60 > 61 <g clip-path="url(#clip0_13_150)"> 62 <path 63 d="M12 4L10.59 5.41L16.17 11H4V13H16.17L10.59 18.59L12 20L20 12L12 4Z" 64 fill="#323232"></path> 65 </g> 66 <defs> 67 <clipPath id="clip0_13_150"> 68 <rect width="24" height="24" fill="white"></rect> 69 </clipPath> 70 </defs> 71 </svg> 72 </a>:<></>} 73 </div> 74 75 <style lang="scss"> 76 #nav { 77 display: flex; 78 justify-content: center; 79 align-items: center; 80 align-self: stretch; 81 color: #000; 82 font-size: 20px; 83 font-style: normal; 84 font-weight: 400; 85 #left, 86 #right, 87 .middle { 88 display: flex; 89 justify-content: center; 90 align-items: center; 91 cursor: pointer; 92 } 93 94 #left:hover, 95 #right:hover, 96 .middle:hover { 97 background: var(--colors-neutral-200, #e5e5e5); 98 } 99 100 .current { 101 background: var(--colors-neutral-200, #e5e5e5) !important; 102 } 103 104 .rounded-start { 105 border-radius: 0; 106 border-top-left-radius: 5px; 107 border-bottom-left-radius: 5px; 108 } 109 110 .rounded-end { 111 border-radius: 0; 112 border-top-right-radius: 5px; 113 border-bottom-right-radius: 5px; 114 } 115 116 #left { 117 border-radius: var(--border-radius-full, 9999px) 0px 0px 118 var(--border-radius-full, 9999px); 119 background: var(--colors-neutral-100, #f5f5f5); 120 width: 50px; 121 height: 50px; 122 flex-shrink: 0; 123 } 124 #right { 125 border-radius: 0px var(--border-radius-full, 9999px) 126 var(--border-radius-full, 9999px) 0px; 127 background: var(--colors-neutral-100, #f5f5f5); 128 width: 50px; 129 height: 50px; 130 flex-shrink: 0; 131 } 132 .middle { 133 background: var(--colors-neutral-100, #f5f5f5); 134 width: 50px; 135 height: 50px; 136 flex-shrink: 0; 137 } 138 } 139 </style>