react-cust-table
Version:
> Multiple responsive design, Pagination support, Collapsible row, Easy Customization,
280 lines (259 loc) • 9.68 kB
JavaScript
import * as React from 'react';
import { Children, useState, useEffect } from 'react';
import styled from 'styled-components';
function Each({ render, of }) {
if (!of?.length) {
return React.createElement(React.Fragment, null);
}
return Children.toArray(of.map((item, index) => render(item, index)));
}
const Main = styled.div `
flex: 1;
display: flex;
flex-direction: column;
max-height: 100%;
`;
const TableContainer = styled.div `
flex: 1;
max-height: 100%;
overflow-y: auto;
`;
const MainTable = styled.table `
width: 100%;
border-spacing: 0;
flex: 1;
background-color: var(--table-bg, #fff);
border-radius: 0.5rem;
border-collapse: collapse;
font-family: inherit;
&.cardTable {
@media (max-width: 650px) {
thead tr th:not(.collapseCell) {
display: none;
}
tbody tr td:not(.collapseCell) {
display: block;
padding: 0.5rem 1rem;
&:first-child {
padding-top: 1rem;
}
&:last-child {
padding-bottom: 1rem;
}
&::before {
content: attr(data-cell) ": ";
font-weight: 700;
text-transform: capitalize;
}
}
}
}
`;
const Thead = styled.thead `
background-color: var(--table-thead-bg, #fff);
border-bottom: 1px solid #ccc;
position: sticky;
top: 0;
z-index: 1;
`;
const Row = styled.tr `
&:not(:last-child) {
border-bottom: 1px solid #ccc;
}
&.collapseAbleRow {
cursor: pointer;
}
&.errorRow {
color: var(--table-error-color, #ff3632);
td {
color: #ce0c0c;
text-align: center;
}
}
`;
const Td = styled.td `
font-size: var(--table-cell-fs, 0.875rem);
color: var(--table-cell-color, #5f6d7e);
padding: 0.75rem 1.5rem;
vertical-align: middle;
font-weight: var(--table-cell-fw, 500);
word-wrap: break-word;
`;
const Th = styled.th `
color: var(--table-heading-color, #5f6d7e);
padding: 1rem 1.25rem;
font-size: var(--table-cell-fs, 0.875rem);
font-weight: var(--table-heading-fw, 700);
line-height: var(--table-cell-line-height, 1.125rem);
letter-spacing: -0.00069rem;
vertical-align: top;
text-align: left;
`;
const CollapseCell = styled.td `
text-align: center;
`;
const PaginationContainer = styled.div `
display: flex;
align-items: center;
justify-content: center;
background: var(--table-pagination-bg, #fff);
margin-top: 1rem;
font-weight: 500;
`;
const PaginationContainerMain = styled.div `
display: flex;
justify-content: center;
align-items: center;
background: inherit;
padding: 1rem 1.5rem;
gap: 1rem;
.btn {
border: none;
outline: none;
background: var(--pagination-btn-bg, none);
color: var(--pagination-btn-font-color, #000);
display: flex;
align-items: center;
gap: 0.5rem;
font-family: inherit;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.25rem;
letter-spacing: -0.00088rem;
&:disabled {
color: var(--pagination-disabled, #ccc);
}
}
ul {
display: flex;
flex-wrap: wrap;
margin: 0;
padding: 0;
li {
list-style: none;
line-height: 45px;
text-align: center;
font-size: 18px;
font-weight: 500;
cursor: pointer;
user-select: none;
transition: all 0.3s ease;
&.numb {
color: var(--pagination-numb-fc, #ccc);
margin: 0 3px;
line-height: 45px;
border-radius: var(--pagination-numb-curve, 50%);
background: var(--pagination-numb-bg, #fff);
display: flex;
width: 2.5rem;
height: 2.5rem;
padding: 0rem 1rem;
justify-content: center;
align-items: center;
font-family: inherit;
font-size: 0.875rem;
font-weight: 500;
line-height: 1.25rem;
letter-spacing: -0.00088rem;
transition: all 0.5s ease-in-out;
&.first {
margin: 0px 3px 0 -5px;
}
&.last {
margin: 0px -5px 0 3px;
}
}
&.dots {
font-size: 22px;
cursor: default;
color: #ccc;
}
&.active,
&:hover {
color: var(--pagination-numb-active-fc, #000);
background: var(--pagination-btn-active-bg, #a4a4a4);
}
}
}
`;
const Pagination = ({ totalPages = 10, currentPage = 1, setCurrentPage, prevBtnLabel = "Prev", nextBtnLabel = "Next", }) => {
const handlePageChange = (page) => {
if (setCurrentPage) {
setCurrentPage(page);
}
else {
console.error("setCurrentPage function is not provided. Please pass the setCurrentPage function to enable pagination.");
}
};
const renderPagination = () => {
const liTags = [];
let beforePage = currentPage - 1;
let afterPage = currentPage + 1;
if (currentPage > 2) {
liTags.push(React.createElement("li", { key: "first", className: `first numb`, onClick: () => handlePageChange(1) },
React.createElement("span", null, "1")));
if (currentPage > 3) {
liTags.push(React.createElement("li", { key: "dots1", className: `dots` },
React.createElement("span", null, "...")));
}
}
for (let plength = beforePage; plength <= afterPage; plength++) {
if (plength > totalPages) {
continue;
}
if (plength === 0) {
plength = plength + 1;
}
liTags.push(React.createElement("li", { key: plength, className: `numb ${currentPage === plength ? "active" : ""}`, onClick: () => handlePageChange(plength) },
React.createElement("span", null, plength)));
}
if (currentPage < totalPages - 1) {
if (currentPage < totalPages - 2) {
liTags.push(React.createElement("li", { key: "dots2", className: `dots` },
React.createElement("span", null, "...")));
}
liTags.push(React.createElement("li", { key: "last", className: `last numb`, onClick: () => handlePageChange(totalPages) },
React.createElement("span", null, totalPages)));
}
return liTags;
};
return (React.createElement(PaginationContainerMain, null,
React.createElement("button", { disabled: !(currentPage > 1), className: `btn prev`, onClick: () => currentPage > 1 && handlePageChange(currentPage - 1) }, prevBtnLabel),
React.createElement("ul", null, renderPagination()),
React.createElement("button", { disabled: !(currentPage < totalPages), className: `btn next`, onClick: () => currentPage < totalPages && handlePageChange(currentPage + 1) }, nextBtnLabel)));
};
const Table = ({ columns, data, isPaginated, pageNo = 1, setPageNo, totalPages = 0, tableClassName = "", pageSize = data?.length || 0, isCollapse, prevBtnLabel, nextBtnLabel, CollapseChild, isMultiCollapse, collapseRowClass = "", responsiveType = "scroll", }) => {
const [activeRow, setActiveRow] = useState([]);
useEffect(() => {
if (isCollapse) {
setActiveRow(data.map(() => false));
}
}, [data, isCollapse]);
const handleCollapseRow = (index) => {
if (isCollapse) {
if (isMultiCollapse) {
setActiveRow((prev) => prev.map((e, idx) => (idx === index ? !e : e)));
}
else {
setActiveRow((prev) => prev.map((e, idx) => (idx === index ? !e : false)));
}
}
};
return (React.createElement(Main, null,
React.createElement(TableContainer, null,
React.createElement(MainTable, { className: responsiveType === "card" ? "cardTable " : "" + tableClassName },
React.createElement(Thead, null,
React.createElement("tr", null,
React.createElement(Each, { of: columns, render: (col) => (React.createElement(Th, { style: { width: col.width, ...col.style }, className: col.headingClassName }, col.header)) }))),
React.createElement("tbody", null, data?.length > 0 ? (React.createElement(Each, { of: data, render: (ele, index) => (React.createElement(React.Fragment, { key: index },
React.createElement(Row, { className: isCollapse ? "collapseAbleRow" : "", onClick: () => handleCollapseRow(index) },
React.createElement(Each, { of: columns, render: (col) => (React.createElement(Td, { "data-cell": col.header, style: col.style }, col.accessor(ele, index, pageNo && (pageNo - 1) * pageSize + index + 1))) })),
isCollapse && activeRow[index] && CollapseChild && (React.createElement(Row, { className: collapseRowClass },
React.createElement(CollapseCell, { colSpan: columns?.length },
React.createElement(CollapseChild, { data: ele, index: index })))))) })) : (React.createElement(Row, { className: "errorRow" },
React.createElement(Td, { colSpan: columns.length }, "No data found.")))))),
isPaginated && pageNo > 0 && totalPages > 0 && (React.createElement(PaginationContainer, null,
React.createElement(Pagination, { totalPages: totalPages, currentPage: pageNo, setCurrentPage: setPageNo, prevBtnLabel: prevBtnLabel, nextBtnLabel: nextBtnLabel })))));
};
export { Pagination, Table };
//# sourceMappingURL=index.js.map