Style paginator component
This commit is contained in:
@ -21,7 +21,7 @@
|
||||
<ul class={tagsListClass}>
|
||||
{#each post.tags as tag}
|
||||
<li class={tagsListLiClass}>
|
||||
<a href="/blog?tag={tag}">{tag}</a>
|
||||
<a href="/blog/tags/{tag}">{tag}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
21
src/components/paginator/Paginator.css.ts
Normal file
21
src/components/paginator/Paginator.css.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { sprinkles } from '$lib/styles/sprinkles.css'
|
||||
|
||||
export const listClass = sprinkles({
|
||||
listStyle: 'none',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
})
|
||||
|
||||
export const listItemClass = sprinkles({
|
||||
paddingX: '1x',
|
||||
})
|
||||
|
||||
export const activePage = sprinkles({
|
||||
//fontStyle: 'italic',
|
||||
fontWeight: 'bold',
|
||||
paddingX: '2x',
|
||||
})
|
||||
|
||||
export const pageLinkClass = sprinkles({
|
||||
paddingX: '1x',
|
||||
})
|
52
src/components/paginator/Paginator.svelte
Normal file
52
src/components/paginator/Paginator.svelte
Normal file
@ -0,0 +1,52 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
activePage,
|
||||
listClass,
|
||||
listItemClass,
|
||||
pageLinkClass,
|
||||
} from './Paginator.css'
|
||||
|
||||
import { getPaginatorPages, createHref } from './paginatorUtils'
|
||||
|
||||
// TODO styles
|
||||
export const Divider = 'divider'
|
||||
|
||||
export let href: string
|
||||
export let page: number
|
||||
export let pageSize: number
|
||||
export let totalCount: number
|
||||
export let filters: Record<string, string>
|
||||
let paginatorPages: (number | typeof Divider)[]
|
||||
|
||||
$: paginatorPages = getPaginatorPages({ page, pageSize, totalCount })
|
||||
</script>
|
||||
|
||||
<ul class={listClass}>
|
||||
{#if page !== 1}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, page - 1)}
|
||||
><</a
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
{#each paginatorPages as pageNumber}
|
||||
{#if pageNumber === Divider}
|
||||
<li class={listItemClass}>...</li>
|
||||
{:else if page === pageNumber}
|
||||
<li class="{listItemClass} {activePage}">{pageNumber}</li>
|
||||
{:else}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, pageNumber)}
|
||||
>{pageNumber}</a
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
{#if page !== paginatorPages.length}
|
||||
<li class="{listItemClass} ">
|
||||
<a class={pageLinkClass} href={createHref(href, filters, page + 1)}
|
||||
>></a
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
52
src/components/paginator/paginatorUtils.test.ts
Normal file
52
src/components/paginator/paginatorUtils.test.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { Divider, getPaginatorPages } from './paginatorUtils'
|
||||
|
||||
describe('Paginator component', () => {
|
||||
describe('Paginator generates feasable pages to display', () => {
|
||||
test('Page: 1/5', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 1, totalCount: 5, pageSize: 1 })
|
||||
).toEqual([1, 2, 3, 4, 5])
|
||||
})
|
||||
test('Page: 4/7', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 4, totalCount: 7, pageSize: 1 })
|
||||
).toEqual([1, 2, 3, 4, 5, 6, 7])
|
||||
})
|
||||
test('Page: 4/8', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 4, totalCount: 8, pageSize: 1 })
|
||||
).toEqual([1, 2, 3, 4, 5, 6, Divider, 8])
|
||||
})
|
||||
test('Page: 1/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 1, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, 2, 3, 4, 5, 6, Divider, 10])
|
||||
})
|
||||
test('Page: 2/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 2, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, 2, 3, 4, 5, 6, Divider, 10])
|
||||
})
|
||||
test('Page: 5/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 5, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, Divider, 3, 4, 5, 6, 7, Divider, 10])
|
||||
})
|
||||
test('Page: 7/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 7, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, Divider, 5, 6, 7, 8, 9, 10])
|
||||
})
|
||||
test('Page: 8/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 8, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, Divider, 5, 6, 7, 8, 9, 10])
|
||||
})
|
||||
test('Page: 10/10', () => {
|
||||
expect(
|
||||
getPaginatorPages({ page: 10, totalCount: 10, pageSize: 1 })
|
||||
).toEqual([1, Divider, 5, 6, 7, 8, 9, 10])
|
||||
})
|
||||
})
|
||||
})
|
50
src/components/paginator/paginatorUtils.ts
Normal file
50
src/components/paginator/paginatorUtils.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { toParams } from '$lib/pagination/searchParams'
|
||||
import { last, range } from 'ramda'
|
||||
|
||||
export const Divider = 'divider'
|
||||
|
||||
export function getPaginatorPages({
|
||||
page,
|
||||
pageSize,
|
||||
totalCount,
|
||||
}: {
|
||||
page: number
|
||||
pageSize: number
|
||||
totalCount: number
|
||||
}) {
|
||||
const maxLinksLength = 7
|
||||
const linksAroundActive = 2
|
||||
const totalPages = Math.ceil(totalCount / pageSize)
|
||||
const daco = range(1, totalPages + 1).reduce((acc, link) => {
|
||||
const isFirst = link === 1
|
||||
const isLast = link === totalPages
|
||||
const isPageOnStart = page <= 3 && link < maxLinksLength
|
||||
const isPageOnEnd =
|
||||
page >= totalPages - 3 && link > totalPages - maxLinksLength + 1
|
||||
|
||||
if ([isFirst, isLast, isPageOnStart, isPageOnEnd].some((value) => value)) {
|
||||
return [...acc, link]
|
||||
}
|
||||
|
||||
if (link < page - linksAroundActive || link > page + linksAroundActive) {
|
||||
if (last(acc) === Divider) {
|
||||
return acc
|
||||
}
|
||||
return [...acc, Divider]
|
||||
}
|
||||
|
||||
return [...acc, link]
|
||||
}, [])
|
||||
|
||||
return daco
|
||||
}
|
||||
|
||||
export function createHref(
|
||||
href: string,
|
||||
filters: Record<string, string>,
|
||||
pageNumber: number
|
||||
) {
|
||||
const filtersPath = toParams(filters)
|
||||
console.log(filtersPath, filters)
|
||||
return `/${href}/${filtersPath ? filtersPath + '/' : ''}page/${pageNumber}`
|
||||
}
|
Reference in New Issue
Block a user