Style paginator component

This commit is contained in:
2022-04-03 20:14:08 +02:00
parent 9846fab54c
commit 27d17874f4
15 changed files with 299 additions and 52 deletions

View File

@ -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>

View 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',
})

View 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)}
>&lt;</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)}
>&gt;</a
>
</li>
{/if}
</ul>

View 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])
})
})
})

View 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}`
}