@isoftdata/svelte-table 2.10.5 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +388 -388
- package/dist/DraggableRows.svelte +285 -285
- package/dist/Pagination.svelte +303 -303
- package/dist/Table.svelte +1165 -1161
- package/dist/Table.svelte.d.ts +3 -2
- package/dist/Td.svelte +171 -171
- package/dist/TreeRow.svelte +170 -170
- package/package.json +1 -1
package/dist/Pagination.svelte
CHANGED
|
@@ -1,303 +1,303 @@
|
|
|
1
|
-
<script
|
|
2
|
-
module
|
|
3
|
-
lang="ts"
|
|
4
|
-
>
|
|
5
|
-
export type Page = {
|
|
6
|
-
number: number
|
|
7
|
-
startIndex: number
|
|
8
|
-
endIndex: number
|
|
9
|
-
hideOnMobile?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<script
|
|
16
|
-
lang="ts"
|
|
17
|
-
generics="I"
|
|
18
|
-
>
|
|
19
|
-
import type { ClassValue } from 'svelte/elements'
|
|
20
|
-
|
|
21
|
-
import { innerWidth } from 'svelte/reactivity/window'
|
|
22
|
-
|
|
23
|
-
interface Props {
|
|
24
|
-
items: Array<I>
|
|
25
|
-
class?: ClassValue
|
|
26
|
-
currentPageNumber: number
|
|
27
|
-
perPageCount: number
|
|
28
|
-
currentPageItems: Array<I>
|
|
29
|
-
totalItemsCount?: number
|
|
30
|
-
showInfoFooter?: boolean
|
|
31
|
-
lastPageNumber?: number
|
|
32
|
-
pageChange?: (context: { pageNumber: number }) => void
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let {
|
|
36
|
-
//
|
|
37
|
-
items,
|
|
38
|
-
class: classNames = '',
|
|
39
|
-
currentPageNumber = $bindable(),
|
|
40
|
-
perPageCount,
|
|
41
|
-
currentPageItems = $bindable([]),
|
|
42
|
-
totalItemsCount = 0,
|
|
43
|
-
showInfoFooter = false,
|
|
44
|
-
lastPageNumber = $bindable(Math.ceil(totalItemsCount / perPageCount)),
|
|
45
|
-
pageChange,
|
|
46
|
-
}: Props = $props()
|
|
47
|
-
|
|
48
|
-
const computedTotalItemsCount = $derived(totalItemsCount || items.length)
|
|
49
|
-
const pages = $derived(getPages(perPageCount, computedTotalItemsCount))
|
|
50
|
-
const displayPages: Array<Page> = $derived(getDisplayPages(pages, currentPageNumber))
|
|
51
|
-
const mobileSize = $derived(!!innerWidth.current && innerWidth.current < 576)
|
|
52
|
-
const showPagination = $derived(perPageCount && computedTotalItemsCount > perPageCount)
|
|
53
|
-
const buttonWidth = $derived.by(() => {
|
|
54
|
-
// keep all the buttons the same size, but make them big enough to fit large page #s
|
|
55
|
-
if (mobileSize) {
|
|
56
|
-
return lastPageNumber >= 100 ? 51 : lastPageNumber >= 10 ? 40 : 36
|
|
57
|
-
} else {
|
|
58
|
-
return lastPageNumber >= 100 ? 40 : lastPageNumber >= 10 ? 36 : 28
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const numPagesHiddenOnMobile = $derived(
|
|
63
|
-
displayPages.length &&
|
|
64
|
-
displayPages.reduce((sum, page) => {
|
|
65
|
-
if (page.hideOnMobile) {
|
|
66
|
-
return sum++
|
|
67
|
-
}
|
|
68
|
-
return sum
|
|
69
|
-
}, 0),
|
|
70
|
-
)
|
|
71
|
-
const somePagesHidden = $derived(displayPages.length < pages.length || (mobileSize && numPagesHiddenOnMobile > 0))
|
|
72
|
-
$effect(() => {
|
|
73
|
-
if (pages.length && pages.length < currentPageNumber) {
|
|
74
|
-
currentPageNumber = pages.length > 0 ? pages.length : 1
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
$effect(() => {
|
|
78
|
-
const currentPage =
|
|
79
|
-
pages.length > 0 && items.length > perPageCount ? pages.find(page => page.number === currentPageNumber) : null
|
|
80
|
-
currentPageItems = currentPage ? items.slice(currentPage.startIndex, currentPage.endIndex) : items
|
|
81
|
-
})
|
|
82
|
-
$effect(() => {
|
|
83
|
-
lastPageNumber = pages.length
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
export function setPageNumber(pageNumber: number) {
|
|
87
|
-
currentPageNumber = pageNumber
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function setPageVisibleByItemIndex(itemIndex: number) {
|
|
91
|
-
const foundPage = pages.find(page => {
|
|
92
|
-
return itemIndex >= page.startIndex && itemIndex < page.endIndex
|
|
93
|
-
})
|
|
94
|
-
if (foundPage && foundPage.number !== currentPageNumber) {
|
|
95
|
-
currentPageNumber = foundPage.number
|
|
96
|
-
pageChange?.({ pageNumber: foundPage.number })
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function getPages(perPageCount: number, totalItemsCount: number) {
|
|
101
|
-
if (perPageCount > 0) {
|
|
102
|
-
const pagesCount = Math.ceil(totalItemsCount / perPageCount)
|
|
103
|
-
const newPages = new Array<Page>()
|
|
104
|
-
|
|
105
|
-
let n = 1
|
|
106
|
-
while (n <= pagesCount) {
|
|
107
|
-
newPages.push({
|
|
108
|
-
number: n,
|
|
109
|
-
startIndex: n === 1 ? 0 : perPageCount * (n - 1),
|
|
110
|
-
endIndex: perPageCount * n,
|
|
111
|
-
})
|
|
112
|
-
n++
|
|
113
|
-
}
|
|
114
|
-
return newPages
|
|
115
|
-
}
|
|
116
|
-
return []
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function getDisplayPages(pages: Array<Page>, currentPageNumber: number): Array<Page> {
|
|
120
|
-
if (!pages.length) {
|
|
121
|
-
return []
|
|
122
|
-
}
|
|
123
|
-
const lastPageIndex = pages.length - 1
|
|
124
|
-
return pages.reduce((sum, page) => {
|
|
125
|
-
if (
|
|
126
|
-
!(
|
|
127
|
-
lastPageIndex <= 7 ||
|
|
128
|
-
page.number === currentPageNumber || // current page always
|
|
129
|
-
(page.number <= 5 && currentPageNumber <= 4) || // current page in beginning of list
|
|
130
|
-
(page.number > currentPageNumber - 2 && page.number < currentPageNumber + 2) || // one on either side of current
|
|
131
|
-
(page.number >= lastPageIndex - 3 && currentPageNumber >= lastPageIndex - 2)
|
|
132
|
-
)
|
|
133
|
-
) {
|
|
134
|
-
page.hideOnMobile = true // TODO : maybe we don't need this
|
|
135
|
-
} else {
|
|
136
|
-
page.hideOnMobile = false
|
|
137
|
-
}
|
|
138
|
-
if (
|
|
139
|
-
lastPageIndex <= 9 ||
|
|
140
|
-
currentPageNumber == page.number || // current page
|
|
141
|
-
(page.number <= 7 && currentPageNumber <= 4) || // beginning of list
|
|
142
|
-
(page.number > currentPageNumber - 3 && page.number < currentPageNumber + 3) || // middle of list
|
|
143
|
-
(page.number > lastPageIndex - 6 && currentPageNumber > lastPageIndex - 3) // end of list
|
|
144
|
-
) {
|
|
145
|
-
return sum.concat(page)
|
|
146
|
-
}
|
|
147
|
-
return sum
|
|
148
|
-
}, new Array<Page>())
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function pageClicked(pageNumber: number) {
|
|
152
|
-
currentPageNumber = pageNumber
|
|
153
|
-
pageChange?.({ pageNumber })
|
|
154
|
-
}
|
|
155
|
-
</script>
|
|
156
|
-
|
|
157
|
-
{#if showPagination}
|
|
158
|
-
<div class={['d-flex justify-content-center', classNames]}>
|
|
159
|
-
<nav aria-label="Page navigation">
|
|
160
|
-
<ul class="pagination pagination-sm mb-0">
|
|
161
|
-
<li
|
|
162
|
-
class="page-item text-center unselectable hideOnMobile arrowWidth"
|
|
163
|
-
class:disabled={currentPageNumber === 1}
|
|
164
|
-
class:d-none={perPageCount == 0 || !perPageCount}
|
|
165
|
-
>
|
|
166
|
-
<button
|
|
167
|
-
type="button"
|
|
168
|
-
class="page-link w-100"
|
|
169
|
-
onclick={() => pageClicked(1)}
|
|
170
|
-
aria-label="Previous"
|
|
171
|
-
role="link"
|
|
172
|
-
>
|
|
173
|
-
<i class="far fa-chevron-double-left"></i>
|
|
174
|
-
</button>
|
|
175
|
-
</li>
|
|
176
|
-
<li
|
|
177
|
-
class="page-item text-center unselectable arrowWidth"
|
|
178
|
-
class:disabled={currentPageNumber === 1}
|
|
179
|
-
class:d-none={perPageCount == 0 || !perPageCount}
|
|
180
|
-
>
|
|
181
|
-
<button
|
|
182
|
-
class="page-link w-100"
|
|
183
|
-
onclick={() => pageClicked(currentPageNumber - 1)}
|
|
184
|
-
aria-label="Previous"
|
|
185
|
-
>
|
|
186
|
-
<i class="far fa-chevron-left"></i>
|
|
187
|
-
</button>
|
|
188
|
-
</li>
|
|
189
|
-
{#if currentPageNumber > 4 && somePagesHidden}
|
|
190
|
-
<li
|
|
191
|
-
class="page-item text-center"
|
|
192
|
-
style="min-width: {buttonWidth}px;"
|
|
193
|
-
>
|
|
194
|
-
<button
|
|
195
|
-
class="page-link w-100"
|
|
196
|
-
onclick={() => pageClicked(1)}
|
|
197
|
-
aria-label="First"
|
|
198
|
-
>1
|
|
199
|
-
</button>
|
|
200
|
-
</li>
|
|
201
|
-
<li class="page-item text-center disabled arrowWidth">
|
|
202
|
-
<span
|
|
203
|
-
class="page-link w-100"
|
|
204
|
-
style="cursor: default;">...</span
|
|
205
|
-
>
|
|
206
|
-
</li>
|
|
207
|
-
{/if}
|
|
208
|
-
{#each displayPages as page}
|
|
209
|
-
<li
|
|
210
|
-
class="page-item text-center unselectable"
|
|
211
|
-
class:active={page.number === currentPageNumber}
|
|
212
|
-
class:hideOnMobile={page.hideOnMobile}
|
|
213
|
-
style="min-width: {buttonWidth}px;"
|
|
214
|
-
>
|
|
215
|
-
<button
|
|
216
|
-
class="page-link w-100"
|
|
217
|
-
onclick={() => pageClicked(page.number)}>{page.number}</button
|
|
218
|
-
>
|
|
219
|
-
</li>
|
|
220
|
-
{/each}
|
|
221
|
-
{#if currentPageNumber < pages.length - 3 && somePagesHidden}
|
|
222
|
-
<li class="page-item text-center disabled arrowWidth">
|
|
223
|
-
<span
|
|
224
|
-
class="page-link w-100"
|
|
225
|
-
style="cursor: default;">...</span
|
|
226
|
-
>
|
|
227
|
-
</li>
|
|
228
|
-
<li
|
|
229
|
-
class="page-item text-center"
|
|
230
|
-
style="min-width: {buttonWidth}px;"
|
|
231
|
-
>
|
|
232
|
-
<button
|
|
233
|
-
class="page-link w-100"
|
|
234
|
-
onclick={() => pageClicked(pages.length)}
|
|
235
|
-
aria-label="Last"
|
|
236
|
-
>{pages.length}
|
|
237
|
-
</button>
|
|
238
|
-
</li>
|
|
239
|
-
{/if}
|
|
240
|
-
<li
|
|
241
|
-
class="page-item text-center unselectable arrowWidth"
|
|
242
|
-
class:disabled={currentPageNumber === lastPageNumber}
|
|
243
|
-
class:d-none={perPageCount == 0 || !perPageCount}
|
|
244
|
-
>
|
|
245
|
-
<button
|
|
246
|
-
class="page-link w-100"
|
|
247
|
-
onclick={() => pageClicked(currentPageNumber + 1)}
|
|
248
|
-
aria-label="Next"
|
|
249
|
-
>
|
|
250
|
-
<i class="far fa-chevron-right"></i>
|
|
251
|
-
</button>
|
|
252
|
-
</li>
|
|
253
|
-
<li
|
|
254
|
-
class="page-item text-center unselectable hideOnMobile arrowWidth"
|
|
255
|
-
class:disabled={currentPageNumber === lastPageNumber}
|
|
256
|
-
class:d-none={perPageCount == 0 || !perPageCount}
|
|
257
|
-
>
|
|
258
|
-
<button
|
|
259
|
-
class="page-link w-100"
|
|
260
|
-
onclick={() => pageClicked(lastPageNumber)}
|
|
261
|
-
aria-label="Last"
|
|
262
|
-
>
|
|
263
|
-
<i class="far fa-chevron-double-right"></i>
|
|
264
|
-
</button>
|
|
265
|
-
</li>
|
|
266
|
-
</ul>
|
|
267
|
-
{#if showInfoFooter}
|
|
268
|
-
<div class="text-center">
|
|
269
|
-
<small
|
|
270
|
-
>{1 + (currentPageNumber - 1) * perPageCount}-{currentPageNumber * perPageCount > computedTotalItemsCount
|
|
271
|
-
? computedTotalItemsCount
|
|
272
|
-
: currentPageNumber * perPageCount} of {computedTotalItemsCount}
|
|
273
|
-
results</small
|
|
274
|
-
>
|
|
275
|
-
</div>
|
|
276
|
-
{/if}
|
|
277
|
-
</nav>
|
|
278
|
-
</div>
|
|
279
|
-
{/if}
|
|
280
|
-
|
|
281
|
-
<style>
|
|
282
|
-
@media screen and (max-width: 576px) {
|
|
283
|
-
.hideOnMobile {
|
|
284
|
-
display: none;
|
|
285
|
-
}
|
|
286
|
-
.pagination-sm .page-link {
|
|
287
|
-
padding: 0.5rem 0.75rem;
|
|
288
|
-
font-size: 1rem;
|
|
289
|
-
line-height: 1.25;
|
|
290
|
-
}
|
|
291
|
-
.arrowWidth {
|
|
292
|
-
width: 39px;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
@media screen and (min-width: 576px) {
|
|
296
|
-
.arrowWidth {
|
|
297
|
-
width: 31px;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
.page-item:not(:last-child) > .page-link {
|
|
301
|
-
border-right: 0;
|
|
302
|
-
}
|
|
303
|
-
</style>
|
|
1
|
+
<script
|
|
2
|
+
module
|
|
3
|
+
lang="ts"
|
|
4
|
+
>
|
|
5
|
+
export type Page = {
|
|
6
|
+
number: number
|
|
7
|
+
startIndex: number
|
|
8
|
+
endIndex: number
|
|
9
|
+
hideOnMobile?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script
|
|
16
|
+
lang="ts"
|
|
17
|
+
generics="I"
|
|
18
|
+
>
|
|
19
|
+
import type { ClassValue } from 'svelte/elements'
|
|
20
|
+
|
|
21
|
+
import { innerWidth } from 'svelte/reactivity/window'
|
|
22
|
+
|
|
23
|
+
interface Props {
|
|
24
|
+
items: Array<I>
|
|
25
|
+
class?: ClassValue
|
|
26
|
+
currentPageNumber: number
|
|
27
|
+
perPageCount: number
|
|
28
|
+
currentPageItems: Array<I>
|
|
29
|
+
totalItemsCount?: number
|
|
30
|
+
showInfoFooter?: boolean
|
|
31
|
+
lastPageNumber?: number
|
|
32
|
+
pageChange?: (context: { pageNumber: number }) => void
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let {
|
|
36
|
+
//
|
|
37
|
+
items,
|
|
38
|
+
class: classNames = '',
|
|
39
|
+
currentPageNumber = $bindable(),
|
|
40
|
+
perPageCount,
|
|
41
|
+
currentPageItems = $bindable([]),
|
|
42
|
+
totalItemsCount = 0,
|
|
43
|
+
showInfoFooter = false,
|
|
44
|
+
lastPageNumber = $bindable(Math.ceil(totalItemsCount / perPageCount)),
|
|
45
|
+
pageChange,
|
|
46
|
+
}: Props = $props()
|
|
47
|
+
|
|
48
|
+
const computedTotalItemsCount = $derived(totalItemsCount || items.length)
|
|
49
|
+
const pages = $derived(getPages(perPageCount, computedTotalItemsCount))
|
|
50
|
+
const displayPages: Array<Page> = $derived(getDisplayPages(pages, currentPageNumber))
|
|
51
|
+
const mobileSize = $derived(!!innerWidth.current && innerWidth.current < 576)
|
|
52
|
+
const showPagination = $derived(perPageCount && computedTotalItemsCount > perPageCount)
|
|
53
|
+
const buttonWidth = $derived.by(() => {
|
|
54
|
+
// keep all the buttons the same size, but make them big enough to fit large page #s
|
|
55
|
+
if (mobileSize) {
|
|
56
|
+
return lastPageNumber >= 100 ? 51 : lastPageNumber >= 10 ? 40 : 36
|
|
57
|
+
} else {
|
|
58
|
+
return lastPageNumber >= 100 ? 40 : lastPageNumber >= 10 ? 36 : 28
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const numPagesHiddenOnMobile = $derived(
|
|
63
|
+
displayPages.length &&
|
|
64
|
+
displayPages.reduce((sum, page) => {
|
|
65
|
+
if (page.hideOnMobile) {
|
|
66
|
+
return sum++
|
|
67
|
+
}
|
|
68
|
+
return sum
|
|
69
|
+
}, 0),
|
|
70
|
+
)
|
|
71
|
+
const somePagesHidden = $derived(displayPages.length < pages.length || (mobileSize && numPagesHiddenOnMobile > 0))
|
|
72
|
+
$effect(() => {
|
|
73
|
+
if (pages.length && pages.length < currentPageNumber) {
|
|
74
|
+
currentPageNumber = pages.length > 0 ? pages.length : 1
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
$effect(() => {
|
|
78
|
+
const currentPage =
|
|
79
|
+
pages.length > 0 && items.length > perPageCount ? pages.find(page => page.number === currentPageNumber) : null
|
|
80
|
+
currentPageItems = currentPage ? items.slice(currentPage.startIndex, currentPage.endIndex) : items
|
|
81
|
+
})
|
|
82
|
+
$effect(() => {
|
|
83
|
+
lastPageNumber = pages.length
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
export function setPageNumber(pageNumber: number) {
|
|
87
|
+
currentPageNumber = pageNumber
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function setPageVisibleByItemIndex(itemIndex: number) {
|
|
91
|
+
const foundPage = pages.find(page => {
|
|
92
|
+
return itemIndex >= page.startIndex && itemIndex < page.endIndex
|
|
93
|
+
})
|
|
94
|
+
if (foundPage && foundPage.number !== currentPageNumber) {
|
|
95
|
+
currentPageNumber = foundPage.number
|
|
96
|
+
pageChange?.({ pageNumber: foundPage.number })
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getPages(perPageCount: number, totalItemsCount: number) {
|
|
101
|
+
if (perPageCount > 0) {
|
|
102
|
+
const pagesCount = Math.ceil(totalItemsCount / perPageCount)
|
|
103
|
+
const newPages = new Array<Page>()
|
|
104
|
+
|
|
105
|
+
let n = 1
|
|
106
|
+
while (n <= pagesCount) {
|
|
107
|
+
newPages.push({
|
|
108
|
+
number: n,
|
|
109
|
+
startIndex: n === 1 ? 0 : perPageCount * (n - 1),
|
|
110
|
+
endIndex: perPageCount * n,
|
|
111
|
+
})
|
|
112
|
+
n++
|
|
113
|
+
}
|
|
114
|
+
return newPages
|
|
115
|
+
}
|
|
116
|
+
return []
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getDisplayPages(pages: Array<Page>, currentPageNumber: number): Array<Page> {
|
|
120
|
+
if (!pages.length) {
|
|
121
|
+
return []
|
|
122
|
+
}
|
|
123
|
+
const lastPageIndex = pages.length - 1
|
|
124
|
+
return pages.reduce((sum, page) => {
|
|
125
|
+
if (
|
|
126
|
+
!(
|
|
127
|
+
lastPageIndex <= 7 ||
|
|
128
|
+
page.number === currentPageNumber || // current page always
|
|
129
|
+
(page.number <= 5 && currentPageNumber <= 4) || // current page in beginning of list
|
|
130
|
+
(page.number > currentPageNumber - 2 && page.number < currentPageNumber + 2) || // one on either side of current
|
|
131
|
+
(page.number >= lastPageIndex - 3 && currentPageNumber >= lastPageIndex - 2)
|
|
132
|
+
)
|
|
133
|
+
) {
|
|
134
|
+
page.hideOnMobile = true // TODO : maybe we don't need this
|
|
135
|
+
} else {
|
|
136
|
+
page.hideOnMobile = false
|
|
137
|
+
}
|
|
138
|
+
if (
|
|
139
|
+
lastPageIndex <= 9 ||
|
|
140
|
+
currentPageNumber == page.number || // current page
|
|
141
|
+
(page.number <= 7 && currentPageNumber <= 4) || // beginning of list
|
|
142
|
+
(page.number > currentPageNumber - 3 && page.number < currentPageNumber + 3) || // middle of list
|
|
143
|
+
(page.number > lastPageIndex - 6 && currentPageNumber > lastPageIndex - 3) // end of list
|
|
144
|
+
) {
|
|
145
|
+
return sum.concat(page)
|
|
146
|
+
}
|
|
147
|
+
return sum
|
|
148
|
+
}, new Array<Page>())
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function pageClicked(pageNumber: number) {
|
|
152
|
+
currentPageNumber = pageNumber
|
|
153
|
+
pageChange?.({ pageNumber })
|
|
154
|
+
}
|
|
155
|
+
</script>
|
|
156
|
+
|
|
157
|
+
{#if showPagination}
|
|
158
|
+
<div class={['d-flex justify-content-center', classNames]}>
|
|
159
|
+
<nav aria-label="Page navigation">
|
|
160
|
+
<ul class="pagination pagination-sm mb-0">
|
|
161
|
+
<li
|
|
162
|
+
class="page-item text-center unselectable hideOnMobile arrowWidth"
|
|
163
|
+
class:disabled={currentPageNumber === 1}
|
|
164
|
+
class:d-none={perPageCount == 0 || !perPageCount}
|
|
165
|
+
>
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
class="page-link w-100"
|
|
169
|
+
onclick={() => pageClicked(1)}
|
|
170
|
+
aria-label="Previous"
|
|
171
|
+
role="link"
|
|
172
|
+
>
|
|
173
|
+
<i class="far fa-chevron-double-left"></i>
|
|
174
|
+
</button>
|
|
175
|
+
</li>
|
|
176
|
+
<li
|
|
177
|
+
class="page-item text-center unselectable arrowWidth"
|
|
178
|
+
class:disabled={currentPageNumber === 1}
|
|
179
|
+
class:d-none={perPageCount == 0 || !perPageCount}
|
|
180
|
+
>
|
|
181
|
+
<button
|
|
182
|
+
class="page-link w-100"
|
|
183
|
+
onclick={() => pageClicked(currentPageNumber - 1)}
|
|
184
|
+
aria-label="Previous"
|
|
185
|
+
>
|
|
186
|
+
<i class="far fa-chevron-left"></i>
|
|
187
|
+
</button>
|
|
188
|
+
</li>
|
|
189
|
+
{#if currentPageNumber > 4 && somePagesHidden}
|
|
190
|
+
<li
|
|
191
|
+
class="page-item text-center"
|
|
192
|
+
style="min-width: {buttonWidth}px;"
|
|
193
|
+
>
|
|
194
|
+
<button
|
|
195
|
+
class="page-link w-100"
|
|
196
|
+
onclick={() => pageClicked(1)}
|
|
197
|
+
aria-label="First"
|
|
198
|
+
>1
|
|
199
|
+
</button>
|
|
200
|
+
</li>
|
|
201
|
+
<li class="page-item text-center disabled arrowWidth">
|
|
202
|
+
<span
|
|
203
|
+
class="page-link w-100"
|
|
204
|
+
style="cursor: default;">...</span
|
|
205
|
+
>
|
|
206
|
+
</li>
|
|
207
|
+
{/if}
|
|
208
|
+
{#each displayPages as page}
|
|
209
|
+
<li
|
|
210
|
+
class="page-item text-center unselectable"
|
|
211
|
+
class:active={page.number === currentPageNumber}
|
|
212
|
+
class:hideOnMobile={page.hideOnMobile}
|
|
213
|
+
style="min-width: {buttonWidth}px;"
|
|
214
|
+
>
|
|
215
|
+
<button
|
|
216
|
+
class="page-link w-100"
|
|
217
|
+
onclick={() => pageClicked(page.number)}>{page.number}</button
|
|
218
|
+
>
|
|
219
|
+
</li>
|
|
220
|
+
{/each}
|
|
221
|
+
{#if currentPageNumber < pages.length - 3 && somePagesHidden}
|
|
222
|
+
<li class="page-item text-center disabled arrowWidth">
|
|
223
|
+
<span
|
|
224
|
+
class="page-link w-100"
|
|
225
|
+
style="cursor: default;">...</span
|
|
226
|
+
>
|
|
227
|
+
</li>
|
|
228
|
+
<li
|
|
229
|
+
class="page-item text-center"
|
|
230
|
+
style="min-width: {buttonWidth}px;"
|
|
231
|
+
>
|
|
232
|
+
<button
|
|
233
|
+
class="page-link w-100"
|
|
234
|
+
onclick={() => pageClicked(pages.length)}
|
|
235
|
+
aria-label="Last"
|
|
236
|
+
>{pages.length}
|
|
237
|
+
</button>
|
|
238
|
+
</li>
|
|
239
|
+
{/if}
|
|
240
|
+
<li
|
|
241
|
+
class="page-item text-center unselectable arrowWidth"
|
|
242
|
+
class:disabled={currentPageNumber === lastPageNumber}
|
|
243
|
+
class:d-none={perPageCount == 0 || !perPageCount}
|
|
244
|
+
>
|
|
245
|
+
<button
|
|
246
|
+
class="page-link w-100"
|
|
247
|
+
onclick={() => pageClicked(currentPageNumber + 1)}
|
|
248
|
+
aria-label="Next"
|
|
249
|
+
>
|
|
250
|
+
<i class="far fa-chevron-right"></i>
|
|
251
|
+
</button>
|
|
252
|
+
</li>
|
|
253
|
+
<li
|
|
254
|
+
class="page-item text-center unselectable hideOnMobile arrowWidth"
|
|
255
|
+
class:disabled={currentPageNumber === lastPageNumber}
|
|
256
|
+
class:d-none={perPageCount == 0 || !perPageCount}
|
|
257
|
+
>
|
|
258
|
+
<button
|
|
259
|
+
class="page-link w-100"
|
|
260
|
+
onclick={() => pageClicked(lastPageNumber)}
|
|
261
|
+
aria-label="Last"
|
|
262
|
+
>
|
|
263
|
+
<i class="far fa-chevron-double-right"></i>
|
|
264
|
+
</button>
|
|
265
|
+
</li>
|
|
266
|
+
</ul>
|
|
267
|
+
{#if showInfoFooter}
|
|
268
|
+
<div class="text-center">
|
|
269
|
+
<small
|
|
270
|
+
>{1 + (currentPageNumber - 1) * perPageCount}-{currentPageNumber * perPageCount > computedTotalItemsCount
|
|
271
|
+
? computedTotalItemsCount
|
|
272
|
+
: currentPageNumber * perPageCount} of {computedTotalItemsCount}
|
|
273
|
+
results</small
|
|
274
|
+
>
|
|
275
|
+
</div>
|
|
276
|
+
{/if}
|
|
277
|
+
</nav>
|
|
278
|
+
</div>
|
|
279
|
+
{/if}
|
|
280
|
+
|
|
281
|
+
<style>
|
|
282
|
+
@media screen and (max-width: 576px) {
|
|
283
|
+
.hideOnMobile {
|
|
284
|
+
display: none;
|
|
285
|
+
}
|
|
286
|
+
.pagination-sm .page-link {
|
|
287
|
+
padding: 0.5rem 0.75rem;
|
|
288
|
+
font-size: 1rem;
|
|
289
|
+
line-height: 1.25;
|
|
290
|
+
}
|
|
291
|
+
.arrowWidth {
|
|
292
|
+
width: 39px;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
@media screen and (min-width: 576px) {
|
|
296
|
+
.arrowWidth {
|
|
297
|
+
width: 31px;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
.page-item:not(:last-child) > .page-link {
|
|
301
|
+
border-right: 0;
|
|
302
|
+
}
|
|
303
|
+
</style>
|