mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-09 15:38:03 -05:00
feat(ui): added pagination component
This commit is contained in:
@@ -1,8 +1,22 @@
|
|||||||
import { themes } from '@storybook/theming';
|
import { themes } from "@storybook/theming";
|
||||||
import '../src/styles/globals.css';
|
import "react-day-picker/dist/style.css";
|
||||||
|
import "../src/styles/globals.css";
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
|
backgrounds: {
|
||||||
|
default: "dark",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
name: "dark",
|
||||||
|
value: "rgb(14, 16, 20)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "paper",
|
||||||
|
value: "rgb(30, 31, 34)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
controls: {
|
controls: {
|
||||||
matchers: {
|
matchers: {
|
||||||
color: /(background|color)$/i,
|
color: /(background|color)$/i,
|
||||||
@@ -10,6 +24,6 @@ export const parameters = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
darkMode: {
|
darkMode: {
|
||||||
dark: { ...themes.dark, appContentBg: 'rgb(14,16,20)', appBg: 'rgb(14,16,20)' }
|
dark: { ...themes.dark, appContentBg: "rgb(14,16,20)", appBg: "rgb(14,16,20)" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
29
frontend/src/components/v2/Pagination/Pagination.stories.tsx
Normal file
29
frontend/src/components/v2/Pagination/Pagination.stories.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// eslint-disable-next-line
|
||||||
|
import { useArgs } from "@storybook/client-api";
|
||||||
|
import type { Meta } from "@storybook/react";
|
||||||
|
|
||||||
|
import { Pagination, PaginationProps } from "./Pagination";
|
||||||
|
|
||||||
|
const meta: Meta<typeof Pagination> = {
|
||||||
|
title: "Components/Pagination",
|
||||||
|
component: Pagination,
|
||||||
|
tags: ["v2"],
|
||||||
|
args: {
|
||||||
|
count: 50
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
// type Story = StoryObj<typeof Pagination>;
|
||||||
|
|
||||||
|
export const Primary = (args: PaginationProps) => {
|
||||||
|
const [, updateArgs] = useArgs();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Pagination
|
||||||
|
{...args}
|
||||||
|
onChangePage={(page) => updateArgs({ page })}
|
||||||
|
onChangePerPage={(perPage) => updateArgs({ perPage, page: 1 })}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
95
frontend/src/components/v2/Pagination/Pagination.tsx
Normal file
95
frontend/src/components/v2/Pagination/Pagination.tsx
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import {
|
||||||
|
faCaretDown,
|
||||||
|
faCheck,
|
||||||
|
faChevronLeft,
|
||||||
|
faChevronRight
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from "../Dropdown";
|
||||||
|
import { IconButton } from "../IconButton";
|
||||||
|
|
||||||
|
export type PaginationProps = {
|
||||||
|
count: number;
|
||||||
|
page: number;
|
||||||
|
perPage?: number;
|
||||||
|
onChangePage: (pageNumber: number) => void;
|
||||||
|
onChangePerPage: (newRows: number) => void;
|
||||||
|
className: string;
|
||||||
|
perPageList?: number[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Pagination = ({
|
||||||
|
count,
|
||||||
|
page = 1,
|
||||||
|
perPage = 20,
|
||||||
|
onChangePage,
|
||||||
|
onChangePerPage,
|
||||||
|
perPageList = [10, 20, 50, 100],
|
||||||
|
className
|
||||||
|
}: PaginationProps) => {
|
||||||
|
const prevPageNumber = Math.max(1, page - 1);
|
||||||
|
const canGoPrev = page > 1;
|
||||||
|
|
||||||
|
const upperLimit = Math.ceil(count / perPage);
|
||||||
|
const nextPageNumber = Math.min(upperLimit, page + 1);
|
||||||
|
const canGoNext = page + 1 <= upperLimit;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
"flex items-center justify-end text-white w-full p-4 bg-mineshaft-700",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="mr-6 flex items-center space-x-2">
|
||||||
|
<div className="text-sm">
|
||||||
|
{(page - 1) * perPage} - {(page - 1) * perPage + perPage} of {count}
|
||||||
|
</div>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<IconButton ariaLabel="per-page-list" variant="plain">
|
||||||
|
<FontAwesomeIcon icon={faCaretDown} />
|
||||||
|
</IconButton>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent className="min-w-fit">
|
||||||
|
{perPageList.map((perPageOption) => (
|
||||||
|
<DropdownMenuItem
|
||||||
|
key={`pagination-per-page-options-${perPageOption}`}
|
||||||
|
icon={perPage === perPageOption && <FontAwesomeIcon size="sm" icon={faCheck} />}
|
||||||
|
iconPos="right"
|
||||||
|
onClick={() => onChangePerPage(perPageOption)}
|
||||||
|
>
|
||||||
|
{perPageOption} rows per page
|
||||||
|
</DropdownMenuItem>
|
||||||
|
))}
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
|
<IconButton
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="pagination-prev"
|
||||||
|
onClick={() => onChangePage(prevPageNumber)}
|
||||||
|
isDisabled={!canGoPrev}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faChevronLeft} />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
variant="plain"
|
||||||
|
ariaLabel="pagination-next"
|
||||||
|
onClick={() => onChangePage(nextPageNumber)}
|
||||||
|
isDisabled={!canGoNext}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faChevronRight} />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
2
frontend/src/components/v2/Pagination/index.tsx
Normal file
2
frontend/src/components/v2/Pagination/index.tsx
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export type { PaginationProps } from "./Pagination";
|
||||||
|
export { Pagination } from "./Pagination";
|
||||||
Reference in New Issue
Block a user