Skip to content

Commit

Permalink
Add BccPagination component (#300)
Browse files Browse the repository at this point in the history
Closes #157
  • Loading branch information
starkris51 authored Apr 18, 2024
1 parent 5a2c864 commit 1636a57
Show file tree
Hide file tree
Showing 6 changed files with 535 additions and 0 deletions.
61 changes: 61 additions & 0 deletions design-library/src/components/BccPagination/BccPagination.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@layer components {

.bcc-pagination {
@apply flex flex-row items-center justify-between
}

.bcc-pagination-left {
@apply flex-row-reverse
}

.bcc-pagination-center {
@apply flex-row justify-evenly
}

.bcc-pagination-rowsperpage-container {
@apply inline-flex flex-row items-center gap-2 text-secondary
}

.bcc-pagination-rowsperpage {
@apply w-[72px]
}

.bcc-pagination-button-container {
@apply inline-flex items-center
}

.bcc-pagination-button {
@apply select-none inline-flex items-center tracking-wide border border-s-[0.5px] border-on-primary justify-center active:shadow-inner focus-visible:outline focus-visible:outline-2 focus-visible:outline-emphasis focus-visible:outline-offset-2;
@apply cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed disabled:pointer-events-none;

/* Default base size */
@apply text-sm gap-x-2;

@apply px-3 py-1.5 w-[33px] h-[33px] bg-primary text-secondary hover:bg-secondary-hover;

}

.bcc-pagination-button-selected {
@apply bg-secondary font-semibold text-interactive;
}

.bcc-pagination-elipsis {
@apply select-none inline-flex items-center tracking-wide border border-s-[0.5px] border-on-primary justify-center;
@apply text-base leading-5 gap-x-2;
@apply px-3 py-1.5 w-[33px] h-[33px] bg-primary text-secondary;

}

.bcc-pagination-arrow-left {
@apply w-10 border rounded-l-md text-interactive;
}

.bcc-pagination-arrow-right {
@apply w-10 border-s-[0.5px] rounded-r-md text-interactive;
}

.bcc-pagination-button-icon { /* base size */
@apply w-4 h-4;
}

}
61 changes: 61 additions & 0 deletions design-library/src/components/BccPagination/BccPagination.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { describe, it, expect } from "vitest";

import { mount } from "@vue/test-utils";
import BccPagination from "./BccPagination.vue";

describe("BccPagination", () => {
it("renders the right amount of page numbers", async () => {
const wrapper = mount(BccPagination, {
props: {
total: 12,
rowsPerPage: 2,
},
});

expect(wrapper.emitted("update:totalPages")![0]).toEqual([6]);
});
it("renders an ellipsis on both sides", async () => {
const wrapper = mount(BccPagination, {
props: {
total: 16,
rowsPerPage: 1,
displayLeftEllipsis: true,
displayRightEllipsis: true,
},
});

await wrapper.find(".bcc-pagination-arrow-right").trigger("click");
await wrapper.find(".bcc-pagination-arrow-right").trigger("click");
await wrapper.find(".bcc-pagination-arrow-right").trigger("click");

expect(wrapper.findAll(".bcc-pagination-elipsis").at(0)).toBeTruthy();
expect(wrapper.findAll(".bcc-pagination-elipsis").at(1)).toBeTruthy();
});
it("updating the rowsPerPage updates the rendered page numbers", async () => {
const wrapper = mount(BccPagination, {
props: {
total: 16,
rowsPerPage: 1,
rowsPerPageOptions: [1, 3, 5, 7, 9],
},
});

expect(wrapper.findAll(".bcc-pagination-button").at(4)?.html()).contains("16");

await wrapper.find(".bcc-select").setValue("3");

expect(wrapper.findAll(".bcc-pagination-button").at(4)?.html()).contains("6");

await wrapper.find(".bcc-select").setValue("5");

expect(wrapper.findAll(".bcc-pagination-button").at(4)?.html()).contains("4");

await wrapper.find(".bcc-select").setValue("7");

expect(wrapper.findAll(".bcc-pagination-button").at(3)?.html()).contains("3");

await wrapper.find(".bcc-select").setValue("9");

expect(wrapper.findAll(".bcc-pagination-button").at(2)?.html()).contains("2");
});
});
257 changes: 257 additions & 0 deletions design-library/src/components/BccPagination/BccPagination.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
import BccPagination from "./BccPagination.vue";
import BccTable from "../BccTable/BccTable.vue";
import BccButton from "../BccButton/BccButton.vue";
import BccBadge from "../BccBadge/BccBadge.vue";
import { ChevronRightIcon } from "@bcc-code/icons-vue";

import type { Meta, StoryFn } from "@storybook/vue3";
import { computed, ref } from "vue";

export default {
title: "Other/BccPagination",
component: BccPagination,
argTypes: {
align: {
options: ["left", "center", "right"],
control: { type: "radio" },
},
},
} as Meta<typeof BccPagination>;

const Template: StoryFn<typeof BccPagination> = (args) => ({
components: { BccPagination },
setup() {
return { args };
},
template: `
<BccPagination :total="args.total" :align="args.align" :displayRowsPerPage="args.displayRowsPerPage" :displayLeftEllipsis="args.displayLeftEllipsis" :displayRightEllipsis="args.displayRightEllipsis" :rowsPerPageOptions="args.rowsPerPageOptions" :rowsPerPage="args.rowsPerPage" :maxButtonsDisplayed="args.maxButtonsDisplayed"/>
`,
});

export const Example = Template.bind({});
Example.args = {
total: 100,
rowsPerPageOptions: [5, 10, 25, 50],
rowsPerPage: 5,
align: "right",
maxButtonsDisplayed: 3,
displayLeftEllipsis: true,
displayRightEllipsis: true,
displayRowsPerPage: true,
};

const TempTable: StoryFn<typeof BccPagination> = () => ({
components: { BccPagination, BccTable, BccButton, BccBadge },
setup() {
const columns = ref([
{
text: "Year group",
key: "year_group",
sortable: false,
},
{
text: "Name",
key: "name",
sortable: false,
},
{
text: "Status",
key: "status",
sortable: false,
},
{
text: "Progress",
key: "progress.amount",
sortable: false,
},
{
text: "Actions",
key: "actions",
sortable: false,
},
]);

const items = ref([
{
id: 1,
year_group: "23/24",
name: "Ola Nordmann",
status: { text: "On Track", context: "success" },
progress: {
amount: 2,
},
},
{
id: 2,
year_group: "22/23",
name: "Johan Oscar",
status: { text: "Finished", context: "info" },
progress: {
amount: 25,
},
},
{
id: 3,
year_group: "22/23",
name: "Ada Lovelace",
status: { text: "Behind Schedule", context: "warning" },
progress: {
amount: 15,
},
},
{
id: 4,
year_group: "23/24",
name: "Firmus Piett",
status: { text: "On Track", context: "success" },
progress: {
amount: 15,
},
},
{
id: 5,
year_group: "22/23",
name: "John Pork",
status: { text: "On Track", context: "warning" },
progress: {
amount: 45,
},
},
{
id: 6,
year_group: "23/24",
name: "John Doe",
status: { text: "Behind Schedule", context: "info" },
progress: {
amount: 80,
},
},
{
id: 7,
year_group: "22/23",
name: "G Man",
status: { text: "Finished", context: "sucess" },
progress: {
amount: 100,
},
},
{
id: 8,
year_group: "23/24",
name: "Jane Doe",
status: { text: "Finished", context: "info" },
progress: {
amount: 37,
},
},
{
id: 9,
year_group: "23/24",
name: "Daphne Bennet",
status: { text: "Behind Schedule", context: "warning" },
progress: {
amount: 45,
},
},
{
id: 10,
year_group: "22/24",
name: "Lorem Ipsum",
status: { text: "On Track", context: "warning" },
progress: {
amount: 10,
},
},
{
id: 11,
year_group: "22/23",
name: "Nathaniel B",
status: { text: "On Track", context: "sucess" },
progress: {
amount: 95,
},
},
{
id: 12,
year_group: "22/23",
name: "Nathaniel T",
status: { text: "On Track", context: "sucess" },
progress: {
amount: 20,
},
},
]);

const page = ref(1);
const rowsPerPage = ref(4);
const start = computed(() => {
return (page.value - 1) * rowsPerPage.value;
});
const end = computed(() => {
return start.value + rowsPerPage.value;
});
const paginatedItems = computed(() => items.value.slice(start.value, end.value));

return { paginatedItems, page, columns, rowsPerPage, items, ChevronRightIcon };
},
template: `
<BccTable :items="paginatedItems" :columns="columns">
<template #item.status="{ item }">
<BccBadge :context="item.status.context">{{ item.status.text }}</BccBadge>
</template>
<template #item.actions="{ item }">
<BccButton variant="tertiary" size="sm" :padding="false" :icon="ChevronRightIcon" iconRight>Evaluation</BccButton>
</template>
</BccTable>
<BccPagination :total="items.length" v-model:currentPage="page" v-model:rowsPerPage="rowsPerPage" :rowsPerPageOptions="[1, 2, 4, 6]" :rowsPerPage="4"/>
`,
});
export const Table = TempTable.bind({});

const TempAlign: StoryFn<typeof BccPagination> = (args) => ({
components: { BccPagination },
setup() {
return { args };
},
template: `
<div class="flex flex-col gap-5">
<BccPagination :total="30" align="left"/>
<BccPagination :total="30" align="right"/>
<BccPagination :total="30" align="center"/>
</div>
`,
});

export const Align = TempAlign.bind({});

const TempElipsis: StoryFn<typeof BccPagination> = (args) => ({
components: { BccPagination },
setup() {
return { args };
},
template: `
<div class="flex flex-col gap-5">
<BccPagination :total="40" align="left" :displayRightEllipsis="false" :displayRowsPerPage="false" />
<BccPagination :total="40" align="left" :displayLeftEllipsis="false" :displayRowsPerPage="false" />
<BccPagination :total="40" align="left" :displayLeftEllipsis="false" :displayRightEllipsis="false" :displayRowsPerPage="false" />
</div>
`,
});

export const Elipsis = TempElipsis.bind({});

const TempMaxButtons: StoryFn<typeof BccPagination> = (args) => ({
components: { BccPagination },
setup() {
return { args };
},
template: `
<div class="flex flex-col gap-5">
<BccPagination :total="60" :rowsPerPage="5" :maxButtonsDisplayed="3" align="left" :displayRowsPerPage="false" />
<BccPagination :total="60" :rowsPerPage="5" :maxButtonsDisplayed="5" align="left" :displayRowsPerPage="false" />
<BccPagination :total="60" :rowsPerPage="5" :maxButtonsDisplayed="10" align="left" :displayRowsPerPage="false" />
</div>
`,
});

export const MaxButtons = TempMaxButtons.bind({});
Loading

0 comments on commit 1636a57

Please sign in to comment.