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,16 @@
1
+ import { IconPinOffOutline } from "../assets/svg";
2
+ import { TableHeaderProps } from "../types/table";
3
+
4
+ function TableHeadPin<T>({ header }: TableHeaderProps<T>) {
5
+ return header.column.getIsPinned() !== "left" ? (
6
+ <div className="ts--head--button" onClick={() => header.column.pin("left")}>
7
+ {/* <IconPinOutline /> */}
8
+ </div>
9
+ ) : (
10
+ <div className="ts--head--button" onClick={() => header.column.pin(false)}>
11
+ <IconPinOffOutline />
12
+ </div>
13
+ );
14
+ }
15
+
16
+ export default TableHeadPin;
@@ -0,0 +1,85 @@
1
+ import {
2
+ Popover,
3
+ List,
4
+ ListItemButton,
5
+ ListItemText,
6
+ ListItemIcon,
7
+ Switch,
8
+ } from "@mui/material";
9
+ import { Header } from "@tanstack/react-table";
10
+ import {
11
+ UpArrow,
12
+ DownArrow,
13
+ HideIcon,
14
+ IconPinOffOutline,
15
+ IconPinOutline,
16
+ } from "../assets/svg";
17
+
18
+ type Props<T> = {
19
+ anchorEl: HTMLElement | null;
20
+ onClose: () => void;
21
+ header: Header<T, unknown>;
22
+ wrap: boolean;
23
+ onToggleWrap: () => void;
24
+ };
25
+
26
+ function TableHeadPopover<T>({
27
+ anchorEl,
28
+ onClose,
29
+ header,
30
+ wrap,
31
+ onToggleWrap,
32
+ }: Props<T>) {
33
+ const open = Boolean(anchorEl);
34
+ const column = header.column;
35
+ const isPinned = column.getIsPinned() === "left";
36
+
37
+ return (
38
+ <Popover
39
+ open={open}
40
+ anchorEl={anchorEl}
41
+ onClose={onClose}
42
+ anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
43
+ >
44
+ <List dense>
45
+ <ListItemButton onClick={() => column.toggleSorting(false)}>
46
+ <ListItemIcon>
47
+ <UpArrow />
48
+ </ListItemIcon>
49
+ <ListItemText primary="Sort ascending" />
50
+ </ListItemButton>
51
+ <ListItemButton onClick={() => column.toggleSorting(true)}>
52
+ <ListItemIcon>
53
+ <DownArrow />
54
+ </ListItemIcon>
55
+ <ListItemText primary="Sort descending" />
56
+ </ListItemButton>
57
+ <ListItemButton onClick={() => column.toggleVisibility()}>
58
+ <ListItemIcon>
59
+ <HideIcon />
60
+ </ListItemIcon>
61
+ <ListItemText primary="Hide in view" />
62
+ </ListItemButton>
63
+ <ListItemButton
64
+ onClick={() => {
65
+ column.pin(isPinned ? false : "left");
66
+ }}
67
+ >
68
+ <ListItemIcon>
69
+ {isPinned ? <IconPinOffOutline /> : <IconPinOutline />}
70
+ </ListItemIcon>
71
+ <ListItemText
72
+ primary={isPinned ? "Unfreeze column" : "Freeze up to column"}
73
+ />
74
+ </ListItemButton>
75
+
76
+ <ListItemButton>
77
+ <ListItemText primary="Wrap Cell" />
78
+ <Switch checked={wrap} onChange={onToggleWrap} />
79
+ </ListItemButton>
80
+ </List>
81
+ </Popover>
82
+ );
83
+ }
84
+
85
+ export default TableHeadPopover;
@@ -0,0 +1,156 @@
1
+ import { ColumnOrderState, flexRender, Table } from "@tanstack/react-table";
2
+ import { CraftTableFeatureProps } from "../types/table-options";
3
+ import { DownArrow, UpArrow } from "../assets/svg";
4
+ import { CSSProperties } from "react";
5
+ import {
6
+ getColumnAlignment,
7
+ getColumnPinningStyles,
8
+ } from "../libs/utils/common";
9
+ import { align } from "../types/common";
10
+ import {
11
+ horizontalListSortingStrategy,
12
+ SortableContext,
13
+ } from "@dnd-kit/sortable";
14
+ import DraggableTableHeader from "./table-head-dnd-cell";
15
+ import TableHeadPin from "./table-head-pin";
16
+ import Checkbox from "./inputs/checkbox";
17
+
18
+ interface TableHeadProps<T> {
19
+ table: Table<T>;
20
+ featureOptions: CraftTableFeatureProps;
21
+ columnOrder: ColumnOrderState;
22
+ }
23
+
24
+ function TableHead<T>({
25
+ table,
26
+ featureOptions,
27
+ columnOrder,
28
+ }: TableHeadProps<T>) {
29
+ const {
30
+ stickyHeader,
31
+ enableColumnReordering,
32
+ enableColumnPinning,
33
+ enableRowSelection,
34
+ } = featureOptions;
35
+
36
+ return (
37
+ <thead className={`ts__head ${stickyHeader ? "ts--sticky" : ""}`.trim()}>
38
+ {table.getHeaderGroups().map((headerGroup) => (
39
+ <tr className="ts__head__tr" key={headerGroup?.id}>
40
+ {enableRowSelection && (
41
+ <th
42
+ className="ts__head__th ts__head__checkbox"
43
+ style={{
44
+ position: "sticky",
45
+ left: 0,
46
+ width: "50px",
47
+ }}
48
+ >
49
+ <div className="ts__content">
50
+ <Checkbox
51
+ checked={table.getIsAllRowsSelected()}
52
+ indeterminate={table.getIsSomeRowsSelected()}
53
+ onChange={() => table.toggleAllRowsSelected()}
54
+ />
55
+ </div>
56
+ </th>
57
+ )}
58
+
59
+ {headerGroup.headers.map((header) => {
60
+ let sortProps: {
61
+ className: string;
62
+ title?: string;
63
+ style?: CSSProperties;
64
+ } = {
65
+ className: "ts__content",
66
+ style: {
67
+ justifyContent: getColumnAlignment(
68
+ (header?.column?.columnDef?.meta as align)?.align
69
+ ),
70
+ },
71
+ };
72
+
73
+ // if (header.column.getCanSort()) {
74
+ // sortProps = {
75
+ // ...sortProps,
76
+ // title:
77
+ // header.column.getNextSortingOrder() === "asc"
78
+ // ? "Sort ascending"
79
+ // : header.column.getNextSortingOrder() === "desc"
80
+ // ? "Sort descending"
81
+ // : "Clear sort",
82
+ // };
83
+ // }
84
+
85
+ return enableColumnReordering ? (
86
+ <SortableContext
87
+ key={header?.id}
88
+ items={columnOrder}
89
+ strategy={horizontalListSortingStrategy}
90
+ >
91
+ <DraggableTableHeader
92
+ header={header}
93
+ featureOptions={featureOptions}
94
+ />
95
+ </SortableContext>
96
+ ) : (
97
+ <th
98
+ key={header?.id}
99
+ className="ts__head__th"
100
+ colSpan={header.colSpan}
101
+ style={{
102
+ ...getColumnPinningStyles(header.column),
103
+ width: `${header.column.getSize()}px`,
104
+ minWidth: `${header.column.columnDef.minSize}px`,
105
+ maxWidth: `${header.column.columnDef.maxSize}px`,
106
+ }}
107
+ >
108
+ {header.isPlaceholder ? null : (
109
+ <div {...sortProps}>
110
+ <div
111
+ className={`${
112
+ header.column.getCanSort() ? "ts__content__sort" : ""
113
+ }`.trim()}
114
+ // onClick={header.column.getToggleSortingHandler()}
115
+ >
116
+ {flexRender(
117
+ header.column.columnDef.header,
118
+ header.getContext()
119
+ )}
120
+
121
+ {{
122
+ asc: <UpArrow />,
123
+ desc: <DownArrow />,
124
+ }[header.column.getIsSorted() as "asc" | "desc"] ?? null}
125
+ </div>
126
+
127
+ {enableColumnPinning && (
128
+ <TableHeadPin
129
+ header={header}
130
+ featureOptions={featureOptions}
131
+ />
132
+ )}
133
+ </div>
134
+ )}
135
+
136
+ {/* column resizing */}
137
+ {header.column.getCanResize() ? (
138
+ <div
139
+ onDoubleClick={() => header.column.resetSize()}
140
+ onMouseDown={header.getResizeHandler()}
141
+ onTouchStart={header.getResizeHandler()}
142
+ className={`column__resize ${
143
+ header.column.getIsResizing() ? "is__resizing" : ""
144
+ }`}
145
+ />
146
+ ) : null}
147
+ </th>
148
+ );
149
+ })}
150
+ </tr>
151
+ ))}
152
+ </thead>
153
+ );
154
+ }
155
+
156
+ export default TableHead;
@@ -0,0 +1,38 @@
1
+ import { formatClassName } from "../libs/utils/common";
2
+ import { CraftTableComponentProps } from "../types/table";
3
+ import TableBody from "./table-body";
4
+ import TableHead from "./table-head";
5
+
6
+ function Table<T>({
7
+ table,
8
+ featureOptions,
9
+ NestedComponent,
10
+ columnOrder,
11
+ isCompactTable,
12
+ }: CraftTableComponentProps<T>) {
13
+ const { striped } = featureOptions;
14
+
15
+ return (
16
+ <table
17
+ className={formatClassName(
18
+ `ts__table ${striped ? "ts--striped" : ""} ${
19
+ isCompactTable ? "ts--compact" : ""
20
+ }`
21
+ )}
22
+ >
23
+ <TableHead
24
+ table={table}
25
+ featureOptions={featureOptions}
26
+ columnOrder={columnOrder}
27
+ />
28
+ <TableBody
29
+ table={table}
30
+ featureOptions={featureOptions}
31
+ NestedComponent={NestedComponent}
32
+ columnOrder={columnOrder}
33
+ />
34
+ </table>
35
+ );
36
+ }
37
+
38
+ export default Table;
@@ -0,0 +1,41 @@
1
+ .table-tabs {
2
+ .tabs {
3
+ display: flex;
4
+ justify-content: flex-start;
5
+ align-items: center;
6
+ margin: 0rem;
7
+ padding: 0rem;
8
+
9
+ .tabs-settings {
10
+ margin-left: 0.1rem;
11
+ margin-right: 0.5rem;
12
+ cursor: pointer;
13
+ }
14
+
15
+ .tab {
16
+ display: flex;
17
+ gap: 0.5rem;
18
+ padding: 0.5rem 1rem;
19
+ cursor: pointer;
20
+ color: var(--grey-900);
21
+ font-size: 0.875rem;
22
+ font-family: var(--fira-700);
23
+
24
+ .tab__label {
25
+ font-family: inherit;
26
+ }
27
+
28
+ &.active {
29
+ background: var(--grey-500);
30
+ border-top-left-radius: 0.5rem;
31
+ border-top-right-radius: 0.5rem;
32
+ backdrop-filter: blur(200px);
33
+ }
34
+ }
35
+
36
+ .tabs-dropdown {
37
+ margin-left: 1rem;
38
+ cursor: pointer;
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,132 @@
1
+ import { useMemo, useState } from "react";
2
+ import "./index.scss";
3
+ import { formatClassName } from "../../libs/utils/common";
4
+ import { SettingIcon, DropDownIcon } from "../../assets/svg";
5
+ import {
6
+ Popover,
7
+ Box,
8
+ Typography,
9
+ List,
10
+ ListItemButton,
11
+ ListItemText,
12
+ } from "@mui/material";
13
+
14
+ interface TableTabsProps<T> {
15
+ data: T[];
16
+ state: string;
17
+ onClick: (state: string) => void;
18
+ }
19
+
20
+ export function TableTabs<T>({
21
+ data = [],
22
+ state = "All",
23
+ onClick,
24
+ }: TableTabsProps<T>) {
25
+ const [activeTab, setActiveTab] = useState<string>(state);
26
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
27
+ const [selectedColumn, setSelectedColumn] = useState<string | null>(null);
28
+
29
+ const columns = useMemo(() => {
30
+ if (!data.length) return [];
31
+ return Object.entries(data[0] as Record<string, any>)
32
+ .filter(([, value]) => typeof value !== "object" && !Array.isArray(value))
33
+ .map(([key]) => ({
34
+ accessorKey: key,
35
+ header: key
36
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
37
+ .replace(/^./, (str) => str.toUpperCase()),
38
+ }));
39
+ }, [data]);
40
+
41
+ const tabsData = useMemo(() => {
42
+ if (!selectedColumn) return [];
43
+
44
+ const counts: Record<string, number> = {};
45
+ data.forEach((item) => {
46
+ const key = (item as Record<string, any>)[selectedColumn];
47
+ const label = key?.toString?.() ?? "Unknown";
48
+ counts[label] = (counts[label] || 0) + 1;
49
+ });
50
+
51
+ return Object.entries(counts).map(([label, count]) => ({ label, count }));
52
+ }, [data, selectedColumn]);
53
+
54
+ const handleColumnSelect = (columnKey: string) => {
55
+ setSelectedColumn(columnKey);
56
+ setActiveTab("All");
57
+ setAnchorEl(null);
58
+ };
59
+
60
+ return (
61
+ <div className="table-tabs">
62
+ <ul className="tabs">
63
+ <div
64
+ className="tabs-settings"
65
+ onClick={(event) => {
66
+ setAnchorEl(event.currentTarget);
67
+ }}
68
+ >
69
+ <SettingIcon />
70
+ </div>
71
+
72
+ {selectedColumn && (
73
+ <>
74
+ <li
75
+ className={formatClassName(
76
+ `tab ${activeTab === "All" ? "active" : ""}`
77
+ )}
78
+ onClick={() => {
79
+ setActiveTab("All");
80
+ onClick("All");
81
+ }}
82
+ >
83
+ <span>All {selectedColumn}</span>
84
+ <span>{data.length}</span>
85
+ </li>
86
+ {tabsData.map(({ label, count }) => (
87
+ <li
88
+ key={label}
89
+ className={formatClassName(
90
+ `tab ${activeTab === label ? "active" : ""}`
91
+ )}
92
+ onClick={() => {
93
+ setActiveTab(label);
94
+ onClick(label);
95
+ }}
96
+ >
97
+ <span>{label}</span>
98
+ <span>{count}</span>
99
+ </li>
100
+ ))}
101
+ <div className="tabs-dropdown">
102
+ <DropDownIcon />
103
+ </div>
104
+ </>
105
+ )}
106
+ </ul>
107
+
108
+ <Popover
109
+ open={Boolean(anchorEl)}
110
+ anchorEl={anchorEl}
111
+ onClose={() => setAnchorEl(null)}
112
+ anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
113
+ >
114
+ <Box p={2} sx={{ width: 200 }}>
115
+ <Typography variant="subtitle1" gutterBottom>
116
+ Select a Column
117
+ </Typography>
118
+ <List dense>
119
+ {columns.map(({ accessorKey, header }) => (
120
+ <ListItemButton
121
+ key={accessorKey}
122
+ onClick={() => handleColumnSelect(accessorKey)}
123
+ >
124
+ <ListItemText primary={header} />
125
+ </ListItemButton>
126
+ ))}
127
+ </List>
128
+ </Box>
129
+ </Popover>
130
+ </div>
131
+ );
132
+ }
@@ -0,0 +1,84 @@
1
+ .ts__table__container {
2
+ .ts-topbar {
3
+ display: flex;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+ min-height: 2.5rem;
7
+ background-color: #fff;
8
+
9
+ .right-section {
10
+ display: flex;
11
+ justify-content: center;
12
+ gap: 0.4rem;
13
+
14
+ .ts--button {
15
+ margin-right: 0.6rem;
16
+ margin-top: 1rem;
17
+ cursor: pointer;
18
+ }
19
+
20
+ .change-layout {
21
+ margin-top: 1rem;
22
+ cursor: pointer;
23
+ }
24
+
25
+ .sort {
26
+ margin-top: 1rem;
27
+ }
28
+
29
+ // .add-new-button {
30
+ // margin-right: 0.9rem;
31
+ // margin-bottom: 0.5rem;
32
+ // border-radius: 2px;
33
+ // // padding: 4px 14px;
34
+ // background-color: #505050;
35
+ // cursor: pointer;
36
+ // }
37
+
38
+ .fullscreen-toggle {
39
+ margin-right: 0.5rem;
40
+ margin-top: 0.9rem;
41
+ }
42
+
43
+ .hide-column {
44
+ margin-top: 0.9rem;
45
+ position: relative;
46
+
47
+ .ts-dropdown {
48
+ .ts-dropdown-content {
49
+ .toggle-all {
50
+ cursor: pointer;
51
+ width: inherit;
52
+ background-color: #fff;
53
+ padding: 0.25rem 1rem;
54
+ border-radius: 0.25rem;
55
+ border: 1px solid #dbdbdb;
56
+
57
+ &:hover {
58
+ box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.1);
59
+ }
60
+ }
61
+
62
+ .switches {
63
+ margin-top: 1rem;
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: 0.5rem;
67
+
68
+ .ts-column-visible {
69
+ display: flex;
70
+ // align-items: center;
71
+ gap: 0.5rem;
72
+
73
+ .ts-column-visible-label {
74
+ font-size: 0.875rem;
75
+ font-weight: 500;
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }