rez-table-listing-mui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.eslintrc.cjs +18 -0
  2. package/README.md +164 -0
  3. package/dist/index.d.ts +90 -0
  4. package/dist/index.js +1 -0
  5. package/dist/index.mjs +1 -0
  6. package/index.html +13 -0
  7. package/package.json +64 -0
  8. package/public/vite.svg +1 -0
  9. package/rollup.config.js +42 -0
  10. package/src/App.tsx +153 -0
  11. package/src/assets/svg.tsx +833 -0
  12. package/src/components/columm-visibility-modal/column-list-item.tsx +44 -0
  13. package/src/components/columm-visibility-modal/index.scss +72 -0
  14. package/src/components/columm-visibility-modal/index.tsx +175 -0
  15. package/src/components/common/index.scss +11 -0
  16. package/src/components/common/index.tsx +11 -0
  17. package/src/components/dropdown/index.scss +17 -0
  18. package/src/components/dropdown/index.tsx +27 -0
  19. package/src/components/index-table.tsx +266 -0
  20. package/src/components/index.scss +176 -0
  21. package/src/components/inputs/checkbox/index.tsx +58 -0
  22. package/src/components/inputs/index.scss +63 -0
  23. package/src/components/inputs/switch.tsx +14 -0
  24. package/src/components/nestedcomponent/index.scss +14 -0
  25. package/src/components/nestedcomponent/index.tsx +53 -0
  26. package/src/components/pagination/default/index.scss +76 -0
  27. package/src/components/pagination/default/index.tsx +168 -0
  28. package/src/components/sorting-modal.tsx/index.tsx +200 -0
  29. package/src/components/sorting-modal.tsx/sorting-item.tsx +35 -0
  30. package/src/components/table-body-dnd-cell.tsx +50 -0
  31. package/src/components/table-body.tsx +109 -0
  32. package/src/components/table-change-layout.tsx +106 -0
  33. package/src/components/table-dnd.tsx +62 -0
  34. package/src/components/table-head-dnd-cell.tsx +144 -0
  35. package/src/components/table-head-pin.tsx +16 -0
  36. package/src/components/table-head-popover.tsx +85 -0
  37. package/src/components/table-head.tsx +156 -0
  38. package/src/components/table.tsx +38 -0
  39. package/src/components/tabs/index.scss +41 -0
  40. package/src/components/tabs/index.tsx +132 -0
  41. package/src/components/topbar/index.scss +84 -0
  42. package/src/components/topbar/index.tsx +226 -0
  43. package/src/components/viewmore/index.scss +0 -0
  44. package/src/components/viewmore/index.tsx +171 -0
  45. package/src/index.ts +4 -0
  46. package/src/libs/hooks/useCraftTable.tsx +37 -0
  47. package/src/libs/hooks/useDefaultColumns.tsx +96 -0
  48. package/src/libs/hooks/useFullScreen.tsx +25 -0
  49. package/src/libs/hooks/useOutsideClick.tsx +24 -0
  50. package/src/libs/utils/Data-format.ts +18 -0
  51. package/src/libs/utils/amount-format.ts +70 -0
  52. package/src/libs/utils/common.ts +62 -0
  53. package/src/libs/utils/date-format.ts +6 -0
  54. package/src/libs/utils/make-data.ts +79 -0
  55. package/src/libs/utils/make-hierar-data.ts +51 -0
  56. package/src/libs/utils/make-nested-data.ts +86 -0
  57. package/src/libs/utils/rows-data.ts +251 -0
  58. package/src/main.tsx +9 -0
  59. package/src/types/common.ts +30 -0
  60. package/src/types/table-options.ts +38 -0
  61. package/src/types/table.ts +65 -0
  62. package/src/vite-env.d.ts +1 -0
  63. package/tsconfig.json +25 -0
  64. package/tsconfig.node.json +11 -0
  65. package/vite.config.ts +7 -0
@@ -0,0 +1,44 @@
1
+ import { useSortable } from "@dnd-kit/sortable";
2
+ import { Box, Typography } from "@mui/material";
3
+ import {
4
+ DragandDrogIcon,
5
+ VisibilityIcon,
6
+ VisibilityOffIcon,
7
+ } from "../../assets/svg";
8
+ import { CSS } from "@dnd-kit/utilities";
9
+
10
+ const DraggableColumn = ({
11
+ column,
12
+ onToggle,
13
+ }: {
14
+ column: any;
15
+ onToggle: () => void;
16
+ }) => {
17
+ const { attributes, listeners, setNodeRef, transform, transition } =
18
+ useSortable({
19
+ id: column.id,
20
+ });
21
+
22
+ const style = {
23
+ transform: CSS.Transform.toString(transform),
24
+ transition,
25
+ };
26
+
27
+ const isVisible = column.getIsVisible();
28
+
29
+ return (
30
+ <div ref={setNodeRef} style={style} {...attributes} className="column-row">
31
+ <Box {...listeners} className="drag-icon">
32
+ <DragandDrogIcon />
33
+ </Box>
34
+ <Typography>
35
+ {(column.columnDef.meta as any)?.label || column.id}
36
+ </Typography>
37
+ <Box onClick={onToggle} className="visibility-icon">
38
+ {isVisible ? <VisibilityIcon /> : <VisibilityOffIcon />}
39
+ </Box>
40
+ </div>
41
+ );
42
+ };
43
+
44
+ export default DraggableColumn;
@@ -0,0 +1,72 @@
1
+ .column-manager {
2
+ width: 320px;
3
+ padding: 0;
4
+ background-color: var(--white);
5
+
6
+ .header {
7
+ width: 100%;
8
+ padding: 10px 16px;
9
+ display: flex;
10
+ justify-content: space-between;
11
+ align-items: center;
12
+ font-weight: 400;
13
+ font-size: 18px;
14
+ background-color: #fbfbfc;
15
+ color: #0c2033;
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ .content-wrapper {
20
+ padding: 10px;
21
+ }
22
+
23
+ .list-section {
24
+ margin-top: 10px;
25
+
26
+ .list-header {
27
+ display: flex;
28
+ justify-content: space-between;
29
+ align-items: center;
30
+ font-size: 12px;
31
+ font-weight: 500;
32
+ color: #888888;
33
+ margin-bottom: 8px;
34
+ padding: 10px 4px;
35
+ }
36
+
37
+ .column-row {
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: space-between;
41
+ padding: 9px 8px;
42
+ border-radius: 6px;
43
+ transition: background-color 0.2s ease;
44
+ cursor: grab;
45
+
46
+ &:hover {
47
+ background-color: #f5f5f5;
48
+ }
49
+
50
+ &.hidden {
51
+ opacity: 0.6;
52
+ }
53
+
54
+ .drag-icon {
55
+ cursor: grab;
56
+ margin-right: 14px;
57
+ color: #888;
58
+ }
59
+
60
+ .visibility-icon {
61
+ cursor: pointer;
62
+ color: #505050;
63
+ }
64
+
65
+ .MuiTypography-root {
66
+ flex-grow: 1;
67
+ font-size: 14px;
68
+ font-weight: 400;
69
+ }
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,175 @@
1
+ import React from "react";
2
+ import {
3
+ DndContext,
4
+ closestCenter,
5
+ useSensor,
6
+ useSensors,
7
+ MouseSensor,
8
+ TouchSensor,
9
+ KeyboardSensor,
10
+ DragEndEvent,
11
+ } from "@dnd-kit/core";
12
+ import {
13
+ SortableContext,
14
+ arrayMove,
15
+ verticalListSortingStrategy,
16
+ } from "@dnd-kit/sortable";
17
+ import { Popover, IconButton, Typography, Box } from "@mui/material";
18
+ import { Table } from "@tanstack/react-table";
19
+ import DraggableColumn from "./column-list-item";
20
+ import "./index.scss";
21
+ import { CloseIcon } from "../../assets/svg";
22
+
23
+ interface ColumnToggleProps<T> {
24
+ anchorEl: HTMLElement | null;
25
+ onClose: () => void;
26
+ table: Table<T>;
27
+ columnOrder: string[];
28
+ setColumnOrder: React.Dispatch<React.SetStateAction<string[]>>;
29
+ }
30
+
31
+ const ColumnToggle = <T,>({
32
+ anchorEl,
33
+ onClose,
34
+ table,
35
+ columnOrder,
36
+ setColumnOrder,
37
+ }: ColumnToggleProps<T>) => {
38
+ const open = Boolean(anchorEl);
39
+ const sensors = useSensors(
40
+ useSensor(MouseSensor),
41
+ useSensor(TouchSensor),
42
+ useSensor(KeyboardSensor)
43
+ );
44
+
45
+ const allColumns = table.getAllLeafColumns();
46
+
47
+ const shownColumns = columnOrder
48
+ .map((id) => allColumns.find((col) => col.id === id))
49
+ .filter((col) => col?.getIsVisible());
50
+
51
+ const hiddenColumns = columnOrder
52
+ .map((id) => allColumns.find((col) => col.id === id))
53
+ .filter((col) => col && !col.getIsVisible());
54
+
55
+ const handleDragEnd = (event: DragEndEvent) => {
56
+ const { active, over } = event;
57
+
58
+ if (!over || active.id === over.id) return;
59
+
60
+ const activeCol = table.getColumn(active.id as string);
61
+ const overCol = table.getColumn(over.id as string);
62
+ if (!activeCol || !overCol) return;
63
+
64
+ const activeVisible = activeCol.getIsVisible();
65
+ const overVisible = overCol.getIsVisible();
66
+
67
+ if (activeVisible !== overVisible) {
68
+ activeCol.toggleVisibility();
69
+ }
70
+
71
+ const oldIndex = columnOrder.indexOf(active.id as string);
72
+ const newIndex = columnOrder.indexOf(over.id as string);
73
+ setColumnOrder(arrayMove(columnOrder, oldIndex, newIndex));
74
+ };
75
+
76
+ const toggleVisibility = (columnId: string) => {
77
+ const col = table.getColumn(columnId);
78
+ col?.toggleVisibility();
79
+ };
80
+
81
+ const handleHideAll = () => {
82
+ allColumns.forEach((col) => col.toggleVisibility(false));
83
+ };
84
+
85
+ const handleShowAll = () => {
86
+ allColumns.forEach((col) => col.toggleVisibility(true));
87
+ };
88
+
89
+ return (
90
+ <Popover
91
+ open={open}
92
+ anchorEl={anchorEl}
93
+ onClose={onClose}
94
+ anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
95
+ sx={{ width: "600px" }}
96
+ >
97
+ <div className="column-manager">
98
+ <div className="header">
99
+ <Typography variant="h6">Column</Typography>
100
+ <IconButton size="small" onClick={onClose}>
101
+ <CloseIcon />
102
+ </IconButton>
103
+ </div>
104
+
105
+ <div className="content-wrapper">
106
+ <DndContext
107
+ sensors={sensors}
108
+ collisionDetection={closestCenter}
109
+ onDragEnd={handleDragEnd}
110
+ >
111
+ <div className="list-section">
112
+ <div className="list-header">
113
+ <Typography variant="subtitle2">Shown in List</Typography>
114
+ {/* <button onClick={handleHideAll}>Hide All</button> */}
115
+ <Box
116
+ onClick={handleHideAll}
117
+ fontStyle={{
118
+ cursor: "pointer",
119
+ color: "#C5C5C5",
120
+ fontSize: "12px",
121
+ }}
122
+ >
123
+ Hide All
124
+ </Box>
125
+ </div>
126
+ <SortableContext
127
+ items={shownColumns.map((col) => col!.id)}
128
+ strategy={verticalListSortingStrategy}
129
+ >
130
+ {shownColumns.map((col) => (
131
+ <DraggableColumn
132
+ key={col!.id}
133
+ column={col!}
134
+ onToggle={() => toggleVisibility(col!.id)}
135
+ />
136
+ ))}
137
+ </SortableContext>
138
+ </div>
139
+
140
+ <div className="list-section">
141
+ <div className="list-header">
142
+ <Typography variant="subtitle2">Hidden in List</Typography>
143
+ {/* <button onClick={handleShowAll}>Show All</button> */}
144
+ <Box
145
+ onClick={handleShowAll}
146
+ fontStyle={{
147
+ cursor: "pointer",
148
+ color: "#C5C5C5",
149
+ fontSize: "12px",
150
+ }}
151
+ >
152
+ Show All
153
+ </Box>
154
+ </div>
155
+ <SortableContext
156
+ items={hiddenColumns.map((col) => col!.id)}
157
+ strategy={verticalListSortingStrategy}
158
+ >
159
+ {hiddenColumns.map((col) => (
160
+ <DraggableColumn
161
+ key={col!.id}
162
+ column={col!}
163
+ onToggle={() => toggleVisibility(col!.id)}
164
+ />
165
+ ))}
166
+ </SortableContext>
167
+ </div>
168
+ </DndContext>
169
+ </div>
170
+ </div>
171
+ </Popover>
172
+ );
173
+ };
174
+
175
+ export default ColumnToggle;
@@ -0,0 +1,11 @@
1
+ .records-container {
2
+ display: flex;
3
+ justify-content: center;
4
+ align-items: center;
5
+
6
+ h3 {
7
+ color: var(--grey-900);
8
+ font-size: 2rem;
9
+ font-family: var(--fira-700);
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import "./index.scss";
2
+
3
+ function ConditionalData() {
4
+ return (
5
+ <div className="records-container">
6
+ <h3>No records</h3>
7
+ </div>
8
+ );
9
+ }
10
+
11
+ export default ConditionalData;
@@ -0,0 +1,17 @@
1
+ .ts__table__container {
2
+ .ts-dropdown {
3
+ cursor: default;
4
+ position: absolute;
5
+ z-index: 9;
6
+ top: 1.5rem;
7
+
8
+ .ts-dropdown-content {
9
+ background-color: #fff;
10
+ border-radius: 0.25rem;
11
+ border: 1px solid #e5e7eb;
12
+ box-shadow: 0 2px 3px 0 rgb(0 0 0 / 0.1), 0 2px 4px 0 rgb(0 0 0 / 0.1);
13
+ padding: 0.5rem 0.75rem;
14
+ min-width: 12rem;
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import "./index.scss";
3
+
4
+ interface DropdownMenuProps {
5
+ children: React.ReactNode;
6
+ position?: "left" | "right";
7
+ }
8
+
9
+ const DropdownMenu = ({ children, position = "left" }: DropdownMenuProps) => {
10
+ let props: React.HTMLAttributes<HTMLDivElement> = {
11
+ className: "ts-dropdown",
12
+ };
13
+
14
+ if (position === "left") {
15
+ props = { ...props, style: { left: "0rem" } };
16
+ } else if (position === "right") {
17
+ props = { ...props, style: { right: "0rem" } };
18
+ }
19
+
20
+ return (
21
+ <div {...props}>
22
+ <div className="ts-dropdown-content">{children}</div>
23
+ </div>
24
+ );
25
+ };
26
+
27
+ export default DropdownMenu;
@@ -0,0 +1,266 @@
1
+ import {
2
+ ColumnDef,
3
+ getCoreRowModel,
4
+ getExpandedRowModel,
5
+ getPaginationRowModel,
6
+ getSortedRowModel,
7
+ useReactTable,
8
+ } from "@tanstack/react-table";
9
+ import "./index.scss";
10
+ import { useEffect, useRef, useState } from "react";
11
+ import {
12
+ CraftTablePaginationProps,
13
+ CraftTableProps,
14
+ TopbarOptionsProps,
15
+ } from "../types/table";
16
+ import { CraftTableFeatureProps } from "../types/table-options";
17
+ import { LoaderAnimation } from "../assets/svg";
18
+ import Topbar from "./topbar";
19
+ import DefaultPagination from "./pagination/default";
20
+ import TableDND from "./table-dnd";
21
+ import Table from "./table";
22
+
23
+ function TableWrapper<T>({
24
+ data = [],
25
+ columns = [],
26
+ tableStates,
27
+ paginationOptions,
28
+ featureOptions,
29
+ topbarOptions,
30
+ nestedComponent,
31
+ loadingOptions = {
32
+ isLoading: false,
33
+ },
34
+ }: CraftTableProps<T>) {
35
+ // Throw an error if data is not an array
36
+ if (!Array.isArray(data)) {
37
+ throw new Error("data must be an array of objects.");
38
+ }
39
+
40
+ const [newColumns] = useState<ColumnDef<T>[]>(() =>
41
+ columns.map((col, index) => ({
42
+ ...col,
43
+ id:
44
+ "accessorKey" in col
45
+ ? (col as { accessorKey: string }).accessorKey
46
+ : `col_${index}`,
47
+ }))
48
+ );
49
+
50
+ const [columnOrder, setColumnOrder] = useState<string[]>(() =>
51
+ newColumns.map((c) => c.id!)
52
+ );
53
+
54
+ const [isCompactTable, setIsCompactTable] = useState<boolean>(
55
+ featureOptions?.compactTable ?? false
56
+ );
57
+
58
+ const tableRef = useRef<HTMLDivElement>(null);
59
+
60
+ useEffect(() => {
61
+ setIsCompactTable(featureOptions?.compactTable ?? false);
62
+ }, [featureOptions?.compactTable]);
63
+
64
+ const craftPaginationOptions: CraftTablePaginationProps = {
65
+ showPagination: true,
66
+ paginationPosition: "bottom",
67
+ paginationView: "full",
68
+
69
+ ...paginationOptions,
70
+ };
71
+
72
+ const totalRows = craftPaginationOptions?.totalRows ?? data.length;
73
+ const rowsPerPageArray = craftPaginationOptions?.rowsPerPageArray ?? [
74
+ 25, 50, 100, 150,
75
+ ];
76
+ const craftTopbarOptions: TopbarOptionsProps = {
77
+ showColumnToggle: true,
78
+ showCompactTableToggle: true,
79
+ showFullscreenToggle: true,
80
+ showChangeLayoutToggle: true,
81
+ viewMoreToggle: true,
82
+ showAddNewButton: true,
83
+ showSearch: true,
84
+ showFilter: true,
85
+ showCustomizationToggle: true,
86
+
87
+ // Add other conditions above topbarOptions
88
+ ...topbarOptions,
89
+ };
90
+
91
+ const craftFeatureOptions: CraftTableFeatureProps = {
92
+ enableTopbar: true,
93
+ enableSorting: true,
94
+ enableServerSidePagination: false,
95
+ enableServerSideSorting: false,
96
+ enableRowSelection: false,
97
+ enableColumnResizing: true,
98
+ enableColumnReordering: true,
99
+ enableColumnPinning: true,
100
+ enableMultiColumnSorting: true,
101
+ compactTable: false,
102
+ stickyHeader: true,
103
+ enableWordBreakAll: false,
104
+ striped: false,
105
+
106
+ // Add other conditions above featureOptions
107
+ ...featureOptions,
108
+ };
109
+
110
+ const {
111
+ enableTopbar,
112
+ enableRowSelection,
113
+ enableServerSidePagination,
114
+ enableServerSideSorting,
115
+ enableSorting,
116
+ enableColumnResizing,
117
+ enableColumnReordering,
118
+ enableColumnPinning,
119
+ // enableMultiColumnSorting,
120
+ } = craftFeatureOptions;
121
+
122
+ const {
123
+ sorting,
124
+ setSorting,
125
+ pagination,
126
+ setPagination,
127
+ rowSelection,
128
+ setRowSelection,
129
+ expanded,
130
+ setExpanded,
131
+ } = tableStates;
132
+
133
+ const table = useReactTable({
134
+ data,
135
+ columns,
136
+ state: {
137
+ sorting,
138
+ pagination,
139
+ rowSelection,
140
+ columnOrder,
141
+ expanded,
142
+ },
143
+
144
+ getCoreRowModel: getCoreRowModel(),
145
+
146
+ /** Sorting options start here */
147
+ enableSorting: enableSorting,
148
+ onSortingChange: setSorting,
149
+ getSortedRowModel: getSortedRowModel(),
150
+ manualSorting: enableServerSideSorting,
151
+ // isMultiSortEvent: () => enableMultiColumnSorting || false,
152
+ /** Sorting options end here */
153
+
154
+ /** Pagination options start here */
155
+ getPaginationRowModel: getPaginationRowModel(),
156
+ onPaginationChange: setPagination,
157
+ rowCount: totalRows,
158
+ manualPagination: enableServerSidePagination,
159
+ /** Pagination options end here */
160
+
161
+ /** Row selection options start here */
162
+ enableRowSelection: enableRowSelection,
163
+ onRowSelectionChange: setRowSelection,
164
+ /** Row selection options end here */
165
+
166
+ /** Column Sizing options start here */
167
+ enableColumnResizing: enableColumnResizing,
168
+ columnResizeDirection: "ltr",
169
+ columnResizeMode: "onChange",
170
+ /** Column Sizing options end here */
171
+
172
+ /** Column Ordering options start here */
173
+ onColumnOrderChange: setColumnOrder,
174
+ /** Column Ordering options end here */
175
+
176
+ /** Column Pinning options end here */
177
+ enableColumnPinning: enableColumnPinning,
178
+ /** Column Pinning options end here */
179
+
180
+ /** Row expanding options start here */
181
+ getExpandedRowModel: getExpandedRowModel(),
182
+ onExpandedChange: setExpanded,
183
+ getSubRows: (row) => (row as { subRows?: T[] }).subRows ?? [],
184
+ /** Row expanding options end here */
185
+ });
186
+
187
+ const { isLoading, loadingComponent, loaderText } = loadingOptions;
188
+
189
+ const handleFullscreenToggle = () => {
190
+ if (!document.fullscreenElement) {
191
+ tableRef.current?.requestFullscreen().catch((err) => {
192
+ console.error("Error attempting to enable fullscreen mode:", err);
193
+ });
194
+ } else {
195
+ document.exitFullscreen();
196
+ }
197
+ };
198
+
199
+ return (
200
+ <div className="ts__table__container" ref={tableRef}>
201
+ {isLoading ? (
202
+ loadingComponent ?? (
203
+ <div className="ts__loader">
204
+ <LoaderAnimation />
205
+ {loaderText && <p>{loaderText}</p>}
206
+ </div>
207
+ )
208
+ ) : (
209
+ <>
210
+ {enableTopbar && (
211
+ <Topbar
212
+ table={table}
213
+ topbarOptions={craftTopbarOptions}
214
+ isCompactTable={isCompactTable}
215
+ setIsCompactTable={setIsCompactTable}
216
+ fullscreenToggle={handleFullscreenToggle}
217
+ paginationComponent={
218
+ craftPaginationOptions?.showPagination === true &&
219
+ craftPaginationOptions?.paginationPosition === "top" ? (
220
+ <DefaultPagination
221
+ table={table}
222
+ rowsPerPageArray={rowsPerPageArray}
223
+ paginationOptions={craftPaginationOptions}
224
+ />
225
+ ) : null
226
+ }
227
+ />
228
+ )}
229
+
230
+ <div className="ts__table__wrapper">
231
+ {enableColumnReordering ? (
232
+ <TableDND
233
+ table={table}
234
+ columnOrder={columnOrder}
235
+ featureOptions={craftFeatureOptions}
236
+ NestedComponent={nestedComponent}
237
+ setColumnOrder={setColumnOrder}
238
+ isCompactTable={isCompactTable}
239
+ />
240
+ ) : (
241
+ <Table
242
+ table={table}
243
+ featureOptions={craftFeatureOptions}
244
+ NestedComponent={nestedComponent}
245
+ columnOrder={columnOrder}
246
+ setColumnOrder={setColumnOrder}
247
+ isCompactTable={isCompactTable}
248
+ />
249
+ )}
250
+ </div>
251
+
252
+ {craftPaginationOptions?.showPagination === true &&
253
+ craftPaginationOptions?.paginationPosition === "bottom" ? (
254
+ <DefaultPagination
255
+ table={table}
256
+ rowsPerPageArray={rowsPerPageArray}
257
+ paginationOptions={craftPaginationOptions}
258
+ />
259
+ ) : null}
260
+ </>
261
+ )}
262
+ </div>
263
+ );
264
+ }
265
+
266
+ export default TableWrapper;