Skip to content

Commit

Permalink
Fix pagination bar (fixes #246 and closes #278) (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
Iinh committed Dec 22, 2020
1 parent cc71310 commit 8df4f3c
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 24 deletions.
172 changes: 169 additions & 3 deletions src/__snapshots__/storyshots.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -585,21 +585,63 @@ exports[`Storyshots ItemList Default 1`] = `
class="flex text-gray-700"
>
<div
class="flex h-12 font-medium bg-gray-200"
class="h-12 w-12 mr-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer bg-teal-600 text-white"
>
<svg
class="feather feather-chevron-left w-6 h-6"
fill="none"
height="100%"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="15 18 9 12 15 6"
/>
</svg>
</div>
<div
class="flex h-12 font-medium rounded-full bg-gray-200"
>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer leading-5 bg-teal-600 text-white"
class="w-12 md:flex justify-center items-center hidden cursor-pointer bg-teal-600 text-white"
>
1
</div>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer leading-5 "
class="w-12 md:flex justify-center items-center hidden cursor-pointer "
>
2
</div>
</div>
<div
class="h-12 w-12 ml-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer "
>
<svg
class="feather feather-chevron-right w-6 h-6"
fill="none"
height="100%"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="9 18 15 12 9 6"
/>
</svg>
</div>
</div>
</div>
Expand All @@ -625,6 +667,130 @@ exports[`Storyshots Markdown Text 1`] = `
</section>
`;

exports[`Storyshots Pagination Default 1`] = `
<section
class="storybook-snapshot-container"
>
<p>
Page
<code>
1
</code>
of
<code>
21
</code>
(
<code>
1
</code>
-
<code>
8
</code>
on
<code>
204
</code>
items)
</p>
<div
class="flex flex-col items-center my-12"
>
<div
class="flex text-gray-700"
>
<div
class="h-12 w-12 mr-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer bg-teal-600 text-white"
>
<svg
class="feather feather-chevron-left w-6 h-6"
fill="none"
height="100%"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="15 18 9 12 15 6"
/>
</svg>
</div>
<div
class="flex h-12 font-medium rounded-full bg-gray-200"
>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer bg-teal-600 text-white"
>
1
</div>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer "
>
2
</div>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer "
>
3
</div>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer "
>
...
</div>
<div
class="w-12 md:flex justify-center items-center hidden cursor-pointer "
>
21
</div>
</div>
<div
class="h-12 w-12 ml-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer "
>
<svg
class="feather feather-chevron-right w-6 h-6"
fill="none"
height="100%"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="100%"
xmlns="http://www.w3.org/2000/svg"
>
<polyline
points="9 18 15 12 9 6"
/>
</svg>
</div>
</div>
</div>
</section>
`;

exports[`Storyshots Pill Deprecated 1`] = `
<section
class="storybook-snapshot-container"
Expand Down
63 changes: 42 additions & 21 deletions src/components/Pagination.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
<script context="module">
import { chunk } from "lodash";
let DEFAULT_ITEMS_PER_PAGE = 20;
export const paginateData = (
array,
totalPages,
perPage = DEFAULT_ITEMS_PER_PAGE
) => {
let result = [];
let localData = array.slice();
for (let i = totalPages; i > 0; i -= 1) {
result.push(
localData.splice(0, Math.max(Math.floor(localData.length / i), perPage))
);
}
return result;
};
export const makePages = (page, data, perPage = DEFAULT_ITEMS_PER_PAGE) => {
if (data.length === 0) return {};
let total = data.length;
let currentPage = page;
let lastPage = Math.ceil(total / perPage);
let pages = paginateData(data, lastPage, perPage);
let pages = chunk([...data], perPage);
let from = page + perPage * (page - 1);
let to = page * perPage;
return {
Expand Down Expand Up @@ -50,6 +38,8 @@

<script>
import { createEventDispatcher } from "svelte";
import BackButton from "./icons/BackButton.svelte";
import ForwardButton from "./icons/ForwardButton.svelte";
export let currentPage;
export let lastPage;
Expand All @@ -58,9 +48,30 @@
export let total;
const dispatch = createEventDispatcher();
function range(size, startAt = 0) {
return [...Array(size).keys()].map((i) => i + startAt);
}
export const truncatedPagination = (current, last) => {
// Source: https://gist.github.com/kottenator/9d936eb3e4e3c3e02598#gistcomment-3413141
const center = [
current - 2,
current - 1,
current,
current + 1,
current + 2,
];
const filteredCenter = center.filter((p) => p > 1 && p < last);
const includeThreeLeft = current === 5;
const includeThreeRight = current === last - 4;
const includeLeftDots = current > 5;
const includeRightDots = current < last - 4;
if (includeThreeLeft) filteredCenter.unshift(2);
if (includeThreeRight) filteredCenter.push(total - 1);
if (includeLeftDots) filteredCenter.unshift("...");
if (includeRightDots) filteredCenter.push("...");
if (total <= 1) return [1];
return [1, ...filteredCenter, last];
};
function changePage(page) {
if (page !== currentPage) {
Expand All @@ -84,14 +95,24 @@

<div class="flex flex-col items-center my-12">
<div class="flex text-gray-700">
<div class="flex h-12 font-medium bg-gray-200">
{#each range(lastPage, 1) as page}
<div
on:click|preventDefault={() => changePage(currentPage !== 1 ? currentPage - 1 : 1)}
class="h-12 w-12 mr-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer {currentPage === 1 ? 'bg-teal-600 text-white' : ''}">
<BackButton />
</div>
<div class="flex h-12 font-medium rounded-full bg-gray-200">
{#each truncatedPagination(currentPage, lastPage) as page}
<div
on:click|preventDefault={() => changePage(page)}
class="w-12 md:flex justify-center items-center hidden cursor-pointer leading-5 {page === currentPage ? 'bg-teal-600 text-white' : ''}">
class="w-12 md:flex justify-center items-center hidden cursor-pointer {page === currentPage ? 'bg-teal-600 text-white' : ''}">
{page}
</div>
{/each}
</div>
<div
on:click|preventDefault={() => changePage(currentPage !== lastPage ? currentPage + 1 : lastPage)}
class="h-12 w-12 ml-1 flex justify-center items-center rounded-full bg-gray-200 cursor-pointer {currentPage === lastPage ? 'bg-teal-600 text-white' : ''}">
<ForwardButton />
</div>
</div>
</div>
13 changes: 13 additions & 0 deletions src/components/icons/BackButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-chevron-left w-6 h-6">
<polyline points="15 18 9 12 15 6" />
</svg>
13 changes: 13 additions & 0 deletions src/components/icons/ForwardButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="feather feather-chevron-right w-6 h-6">
<polyline points="9 18 15 12 9 6" />
</svg>
25 changes: 25 additions & 0 deletions stories/pagination.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { text } from "@storybook/addon-knobs";
import Pagination from "../src/components/Pagination.svelte";

const paginationState = {
total: 204,
currentPage: 1,
lastPage: 21,
from: 1,
to: 8,
};

export default {
title: "Pagination",
};

export const Default = () => ({
Component: Pagination,
props: {
currentPage: text("Current page number", paginationState.currentPage),
lastPage: text("Last page number", paginationState.lastPage),
from: text("From item", paginationState.from),
to: text("To item", paginationState.to),
total: text("Total number of items", paginationState.total),
},
});

0 comments on commit 8df4f3c

Please sign in to comment.