Skip to content

Commit

Permalink
Fix Table
Browse files Browse the repository at this point in the history
  • Loading branch information
fortezhuo committed Apr 14, 2023
1 parent 21a8198 commit a4f9fe7
Show file tree
Hide file tree
Showing 9 changed files with 7,342 additions and 65 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module.exports = {
'@typescript-eslint/prefer-optional-chain': 'off',
"@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/no-redeclare": "off",
"@typescript-eslint/restrict-plus-operands": "off"
},
settings: {
react: {
Expand Down
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"trailingComma": "all",
"singleQuote": false,
"printWidth": 100,
"tabWidth": 2
}
9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tawasukha/ui",
"version": "0.0.21",
"version": "0.0.24",
"type": "module",
"types": "dist/index.d.ts",
"exports": {
Expand Down Expand Up @@ -80,13 +80,6 @@
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"prettier": {
"semi": false,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
},
"dependencies": {
"@fontsource/abeezee": "^4.5.10",
"@rehookify/datepicker": "^4.3.2",
Expand Down
172 changes: 172 additions & 0 deletions src/components/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { cx } from "../helpers/cva"
import { forwardRef, useCallback, useMemo } from "react"
import { Icon } from "./icon"

export const DOTS = "..."

const range = (start: number, end: number) => {
const length = end - start + 1
return Array.from({ length }, (_, idx) => idx + start)
}

export type PaginationParameter = {
totalCount: number
pageSize: number
siblingCount?: number
currentPage: number
}

export const usePagination = ({
totalCount,
pageSize,
siblingCount = 1,
currentPage,
}: PaginationParameter) => {
const paginationRange = useMemo(() => {
const totalPageCount = Math.ceil(totalCount / pageSize)

const totalPageNumbers = siblingCount + 5

if (totalPageNumbers >= totalPageCount) {
return range(1, totalPageCount)
}

const leftSiblingIndex = Math.max(currentPage - siblingCount, 1)
const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPageCount)

const shouldShowLeftDots = leftSiblingIndex > 2
const shouldShowRightDots = rightSiblingIndex < totalPageCount - 2

const firstPageIndex = 1
const lastPageIndex = totalPageCount

if (!shouldShowLeftDots && shouldShowRightDots) {
const leftItemCount = 3 + 2 * siblingCount
const leftRange = range(1, leftItemCount)

return [...leftRange, DOTS, totalPageCount]
}

if (shouldShowLeftDots && !shouldShowRightDots) {
const rightItemCount = 3 + 2 * siblingCount
const rightRange = range(totalPageCount - rightItemCount + 1, totalPageCount)
return [firstPageIndex, DOTS, ...rightRange]
}

if (shouldShowLeftDots && shouldShowRightDots) {
const middleRange = range(leftSiblingIndex, rightSiblingIndex)
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex]
}
}, [totalCount, pageSize, siblingCount, currentPage])

return paginationRange || []
}

const pageClassName = "px-3 py-2 text-md text-base-3 bg-base-1 hover:bg-primary-1"
const buttonClassName =
"flex items-center px-4 py-2 text-md text-base-3 bg-base-1 hover:bg-primary-1 hover:text-primary-3 transition-colors duration-200 border rounded-md gap-x-2"

export type PaginationProps = {
onPageChange: (page: number) => void
totalCount: number
siblingCount?: number
currentPage: number
pageSize: number
}

export const Pagination = forwardRef<HTMLDivElement, PaginationProps>(function Pagination(
{ onPageChange, totalCount, siblingCount = 1, currentPage, pageSize },
ref,
) {
const paginationRange = usePagination({
currentPage,
totalCount,
siblingCount,
pageSize,
})

const lastPage = useMemo(() => paginationRange[paginationRange.length - 1], [paginationRange])

const onNext = useCallback(() => {
if (typeof lastPage === "number" && currentPage < lastPage) {
onPageChange(currentPage + 1)
}
}, [currentPage, onPageChange])

const onPrevious = useCallback(() => {
if (currentPage !== 1) {
onPageChange(currentPage - 1)
}
}, [currentPage, onPageChange])

const display = useMemo(() => {
const first = (currentPage - 1) * pageSize + 1
const last = currentPage * pageSize

return `${first}-${last > totalCount ? last : totalCount} / ${totalCount}`
}, [currentPage, pageSize])

return (
<div className="flex items-center justify-between py-4 text-base-3 text-md">
<div className="flex">
<span className="hidden md:block">Data : {display}</span>
<div className="flex flex-col gap-x-2 sm:flex-row md:hidden">
<span>Page : </span>
<span>
{currentPage} / {lastPage}
</span>
</div>
</div>
<div className="flex items-center justify-between gap-x-2">
{!(currentPage === 0 || paginationRange.length < 2) && (
<>
<a
onClick={onPrevious}
className={cx(
buttonClassName,
currentPage === 1 ? "cursor-not-allowed" : "cursor-pointer",
)}
>
<Icon name="ChevronLeftIcon" className="w-4 h-4" />
<span>Prev</span>
</a>
<div className="items-center hidden lg:flex gap-x-1 mx-1">
{paginationRange.map((pageNumber: number | string, i: number) => {
return pageNumber === DOTS ? (
<a key={i} className={cx(pageClassName, "cursor-not-allowed")}>
...
</a>
) : (
<a
key={i}
className={cx(
pageClassName,
currentPage === pageNumber
? "text-primary-3 cursor-not-allowed"
: "cursor-pointer",
)}
onClick={() => {
if (typeof pageNumber === "number") onPageChange(pageNumber)
}}
>
{pageNumber}
</a>
)
})}
</div>
<a
onClick={onNext}
className={cx(
buttonClassName,
currentPage === lastPage ? "cursor-not-allowed" : "cursor-pointer",
)}
>
<span>Next</span>
<Icon name="ChevronRightIcon" className="w-4 h-4" />
</a>
</>
)}
</div>
</div>
)
})
83 changes: 67 additions & 16 deletions src/components/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,89 @@ import { forwardRef } from "react"
import { type DivProps } from "react-html-props"
import { cx } from "cva"

export interface TableCellProps extends DivProps { }
export interface TableCellProps extends DivProps {}

export const TableCell = forwardRef<HTMLDivElement, TableCellProps>(function TableCell({ className, ...props }, ref) {
return <div ref={ref} className={cx("table-cell py-3.5 px-4", className)} {...props} />
export const TableCell = forwardRef<HTMLDivElement, TableCellProps>(function TableCell(
{ className, ...props },
ref,
) {
return (
<div ref={ref} className={cx("table-cell py-3.5 px-4 break-words", className)} {...props} />
)
})

export interface TableRowProps extends DivProps {
dark?: boolean
}

export const TableRow = forwardRef<HTMLDivElement, TableRowProps>(function TableCell({ dark, className, ...props }, ref) {
return <div ref={ref} className={cx("table-row font-normal hover:bg-primary-1 hover:text-primary-5", dark ? "bg-base-1" : "", className)} {...props} />
export const TableRow = forwardRef<HTMLDivElement, TableRowProps>(function TableCell(
{ dark, className, ...props },
ref,
) {
return (
<div
ref={ref}
className={cx(
"table-row font-normal hover:bg-primary-1 hover:text-primary-5",
dark ? "bg-base-1" : "",
className,
)}
{...props}
/>
)
})

export interface TableBody extends DivProps {
dark?: boolean
}

export const TableBody = forwardRef<HTMLDivElement, TableBody>(function TableBody({ dark, className, ...props }, ref) {
return <div ref={ref} className={cx("table-row-group divide-y divide-base-2 text-base-5 text-md", dark ? "bg-base-1" : "bg-base", className)} {...props} />
export const TableBody = forwardRef<HTMLDivElement, TableBody>(function TableBody(
{ dark, className, ...props },
ref,
) {
return (
<div
ref={ref}
className={cx(
"table-row-group divide-y divide-base-2 text-base-5 text-md",
dark ? "bg-base-1" : "bg-base",
className,
)}
{...props}
/>
)
})

export interface TableHeadProps extends DivProps { }
export interface TableHeadProps extends DivProps {}

export const TableHead = forwardRef<HTMLDivElement, TableHeadProps>(function TableBody({ className, ...props }, ref) {
return <div ref={ref} className={cx("table-header-group bg-primary-2 text-primary-4 text-md text-left", className)} {...props} />
export const TableHead = forwardRef<HTMLDivElement, TableHeadProps>(function TableBody(
{ className, ...props },
ref,
) {
return (
<div
ref={ref}
className={cx("table-header-group bg-primary-2 text-primary-4 text-md text-left", className)}
{...props}
/>
)
})

export interface TableProps extends DivProps { }
export interface TableProps extends DivProps {}

export const Table = forwardRef<HTMLDivElement, TableProps>(function Table({ className, ...props }, ref) {
return <div ref={ref} className={cx("shadow-lg shadow-offset inline-block min-w-full overflow-x-auto rounded-lg", className)}>
<div className={"table table-fixed w-full border-collapse"} {...props} />
</div>
})
export const Table = forwardRef<HTMLDivElement, TableProps>(function Table(
{ className, ...props },
ref,
) {
return (
<div
ref={ref}
className={cx(
"shadow shadow-offset inline-block min-w-full overflow-x-auto rounded-lg",
className,
)}
>
<div className={"table table-fixed w-full border-collapse"} {...props} />
</div>
)
})
Loading

0 comments on commit a4f9fe7

Please sign in to comment.