UNPKG

@explita/daily-toolset-components

Version:

A lightweight and versatile collection of TypeScript utility functions and form components, inspired by ShadCN UI, designed for seamless everyday development. Enhance your Node.js, React, and Next.js projects with a well-structured suite of helpers for st

218 lines (217 loc) 11.5 kB
"use client"; "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.DataTable = DataTable; const react_1 = __importStar(require("react")); const fa6_1 = require("react-icons/fa6"); const _1 = require("./"); const daily_toolset_hooks_1 = require("@explita/daily-toolset-hooks"); function defaultColumns(columns, sortable) { if (!sortable) return columns; return columns.map((col) => { var _a; return ({ ...col, sortable: (_a = col.sortable) !== null && _a !== void 0 ? _a : true, }); }); } function DataTable({ sortable = true, columns = [], data = [], onRowClick, hideFilter = false, hideHeader = false, hideFooter = false, additionalFilter, ref, emptyMessage = "No records found.", defaultRowsPerPage = 10, }) { var _a, _b, _c; const [filterValue, setFilterValue] = (0, react_1.useState)(""); const [page, setPage] = (0, react_1.useState)(1); const [rowsPerPage, setRowsPerPage] = (0, react_1.useState)(10); const [sortDescriptor, setSortDescriptor] = (0, react_1.useState)({ column: (_a = columns[0]) === null || _a === void 0 ? void 0 : _a.key.toString(), direction: (_c = (_b = columns[0]) === null || _b === void 0 ? void 0 : _b.sortDir) !== null && _c !== void 0 ? _c : "asc", }); (0, react_1.useEffect)(() => { if (hideFooter === true) setRowsPerPage(data === null || data === void 0 ? void 0 : data.length); }, [data, hideFooter]); const hasSearchFilter = Boolean(filterValue); const filteredItems = (0, react_1.useMemo)(() => { let filteredData = [...data]; if (hasSearchFilter) { filteredData = filteredData.filter((item) => { return Object.values(item) .map((item) => (0, daily_toolset_hooks_1.stripTags)(item)) .join("") .toLowerCase() .includes(filterValue.toLowerCase()); }); } return filteredData; }, [data, filterValue, hasSearchFilter]); const pages = Math.ceil(filteredItems.length / rowsPerPage); const items = (0, react_1.useMemo)(() => { const start = (page - 1) * rowsPerPage; const end = start + rowsPerPage; return filteredItems.slice(start, end); }, [page, filteredItems, rowsPerPage]); const sortedItems = (0, react_1.useMemo)(() => { if (!sortable) return items; return [...items].sort((a, b) => { const typeOfA = typeof a[sortDescriptor.column]; const typeOfB = typeof b[sortDescriptor.column]; const first = typeOfA === "number" ? Number(a[sortDescriptor.column]) : (0, daily_toolset_hooks_1.stripTags)(a[sortDescriptor.column]); const second = typeOfB === "number" ? Number(b[sortDescriptor.column]) : (0, daily_toolset_hooks_1.stripTags)(b[sortDescriptor.column]); const cmp = first < second ? -1 : first > second ? 1 : 0; return sortDescriptor.direction === "desc" ? -cmp : cmp; }); }, [sortDescriptor, items, sortable]); const onNextPage = (0, react_1.useCallback)(() => { if (page < pages) setPage(page + 1); else setPage(1); }, [page, pages]); const onPreviousPage = (0, react_1.useCallback)(() => { if (page > 1) setPage(page - 1); else setPage(pages); }, [page, pages]); const onRowsPerPageChange = (0, react_1.useCallback)((value) => { setRowsPerPage(Number(value)); setPage(1); }, []); const onSearchChange = (0, react_1.useCallback)((e) => { if (e.target.value) { setFilterValue(e.target.value); setPage(1); } else { setFilterValue(""); } }, []); return (react_1.default.createElement("div", { className: "explita-table-container" }, (pages > 0 || filterValue !== "") && hideFilter === false && (react_1.default.createElement(TableFilter, { filterValue, onSearchChange, rowsPerPage, onRowsPerPageChange, additionalFilter })), react_1.default.createElement("div", { className: "table-main" }, react_1.default.createElement("table", { className: "explita-table", ref: ref }, hideHeader === false && (react_1.default.createElement(TableHeader, { columns, setSortDescriptor, sortDescriptor, sortable })), react_1.default.createElement("tbody", null, sortedItems.map((row, index) => { return (react_1.default.createElement("tr", { key: index, onClick: () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row) }, columns.map((column, index) => { // if (row.includes("_id_")) return; return (react_1.default.createElement("td", { key: index, style: column.style, className: column.className || "", "data-title": typeof column.title === "string" ? column.title : "" }, react_1.default.createElement("div", { className: column.key === "actions" ? "actions-container" : "" }, column.render ? column.render(row) : row[column.key]))); }))); }), sortedItems.length === 0 && (react_1.default.createElement("tr", null, react_1.default.createElement("td", { colSpan: columns.length, "data-empty": sortedItems.length === 0 }, emptyMessage)))))), pages > 0 && filteredItems.length > rowsPerPage && hideFooter === false && (react_1.default.createElement(TableFooter, { pages, page, onNextPage, onPreviousPage, filteredItems })))); } function TableFilter({ filterValue, onSearchChange, rowsPerPage, onRowsPerPageChange, additionalFilter, }) { return (react_1.default.createElement("div", { className: "table-filter" }, react_1.default.createElement("div", null, react_1.default.createElement("span", { className: "filter-label" }, "Show"), react_1.default.createElement(_1.Select, { defaultValue: rowsPerPage, options: [ { value: 10, label: "10 Records" }, { value: 25, label: "25 Records" }, { value: 50, label: "50 Records" }, { value: 100, label: "100 Records" }, ], isClearable: false, handleSelection: onRowsPerPageChange })), react_1.default.createElement("div", null, additionalFilter, react_1.default.createElement(_1.Input.Search, { defaultValue: filterValue, placeholder: "Search table...", onChange: onSearchChange })))); } function TableHeader({ columns, sortable, sortDescriptor, setSortDescriptor, }) { const processedColumns = defaultColumns(columns, sortable); const setSortDescription = (0, react_1.useCallback)((item) => { var _a; if (!item.sortable || !sortable) return; if (item.key === sortDescriptor.column) { if (sortDescriptor.direction === "asc") { setSortDescriptor({ column: item.key, direction: "desc" }); } else { setSortDescriptor({ column: item.key, direction: "asc" }); } } else { setSortDescriptor({ column: String(item.key), direction: (_a = item.sortDir) !== null && _a !== void 0 ? _a : "asc", }); } }, [sortDescriptor, setSortDescriptor, sortable]); return (react_1.default.createElement("thead", null, react_1.default.createElement("tr", null, processedColumns.map((item, i) => (react_1.default.createElement("th", { key: i, style: { width: item.width }, onClick: () => setSortDescription(item), role: "button" }, react_1.default.createElement("div", { className: "header-container" }, item.title, item.key !== "actions" && (react_1.default.createElement(SortArrow, { sortDescriptor, sortable: !item.sortable ? false : sortable, columnKey: String(item.key) }))))))))); } function TableFooter({ pages, page, onNextPage, onPreviousPage, filteredItems, }) { return (react_1.default.createElement("div", { className: "footer-container" }, react_1.default.createElement("div", null, react_1.default.createElement("span", null, "Page ", page, " of ", pages), react_1.default.createElement("span", null)), react_1.default.createElement("div", null, react_1.default.createElement(_1.Button, { size: "sm", variant: "outline", isDisabled: pages === 1, onClick: onPreviousPage }, react_1.default.createElement(fa6_1.FaChevronLeft, null), react_1.default.createElement("span", { className: "label" }, "Previous")), react_1.default.createElement(_1.Button, { size: "sm", variant: "outline", isDisabled: pages === 1, onClick: onNextPage }, react_1.default.createElement(fa6_1.FaChevronRight, null), react_1.default.createElement("span", { className: "label" }, "Next"))))); } function SortArrow({ columnKey, sortable, sortDescriptor }) { if (!sortable || sortDescriptor.column === "") return null; return sortDescriptor.column === columnKey ? (react_1.default.createElement("span", { className: `sort-icon ${sortDescriptor.direction === "asc" ? "asc" : "desc"}` }, sortDescriptor.direction === "desc" ? (react_1.default.createElement(fa6_1.FaArrowDownZA, null)) : (react_1.default.createElement(fa6_1.FaArrowDownAZ, null)))) : (react_1.default.createElement("span", { className: "sort-icon inactive" }, react_1.default.createElement(fa6_1.FaArrowDownAZ, null))); }