rez-table-listing-mui 1.3.61 → 2.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 (34) hide show
  1. package/dist/index.d.ts +4 -5
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +1 -1
  7. package/src/listing/components/index.scss +0 -144
  8. package/src/listing/components/login/index.tsx +4 -4
  9. package/src/listing/components/pagination/default/index.tsx +108 -138
  10. package/src/listing/components/pagination/default/pagination.styles.ts +113 -0
  11. package/src/listing/components/{table-body-dnd-cell.tsx → table-body/table-body-dnd-cell.tsx} +18 -25
  12. package/src/listing/components/table-body/table-body.styles.ts +64 -0
  13. package/src/listing/components/{table-body.tsx → table-body/table-body.tsx} +35 -32
  14. package/src/listing/components/table-head/table-head-dnd-cell.tsx +112 -0
  15. package/src/listing/components/table-head/table-head-pin.tsx +29 -0
  16. package/src/listing/components/{table-head-popover.tsx → table-head/table-head-popover.tsx} +4 -16
  17. package/src/listing/components/table-head/table-head-resizer.tsx +22 -0
  18. package/src/listing/components/table-head/table-head.styles.ts +115 -0
  19. package/src/listing/components/{table-head.tsx → table-head/table-head.tsx} +36 -69
  20. package/src/listing/components/table.tsx +2 -2
  21. package/src/listing/components/tabs/index.tsx +28 -42
  22. package/src/listing/components/tabs/tabs.styles.ts +49 -0
  23. package/src/listing/libs/hooks/useEntityTableAPI.tsx +8 -0
  24. package/src/listing/libs/hooks/useEntityTableHooks.ts +3 -3
  25. package/src/listing/libs/services/getLayoutAPI.tsx +1 -1
  26. package/src/listing/libs/utils/apiColumn.ts +17 -8
  27. package/src/listing/libs/utils/common.ts +45 -1
  28. package/src/listing/types/common.ts +1 -0
  29. package/src/listing/types/table.ts +2 -2
  30. package/src/view/ListingView.tsx +58 -91
  31. package/src/listing/components/table-head-dnd-cell.tsx +0 -150
  32. package/src/listing/components/table-head-pin.tsx +0 -22
  33. package/src/listing/components/tabs/index.scss +0 -42
  34. package/src/listing/components/tabs/styles.ts +0 -34
@@ -0,0 +1,64 @@
1
+ import { styled } from "@mui/material";
2
+
3
+ export const TableBodyRow = styled("tr", {
4
+ shouldForwardProp: (prop) =>
5
+ prop !== "hoverable" &&
6
+ prop !== "selected" &&
7
+ prop !== "striped" &&
8
+ prop !== "expanded",
9
+ })<{
10
+ hoverable?: boolean;
11
+ selected?: boolean;
12
+ striped?: boolean;
13
+ expanded?: boolean;
14
+ }>(({ theme, hoverable, selected, striped }) => ({
15
+ backgroundColor: selected
16
+ ? theme.palette.action.selected
17
+ : theme.palette.background.paper,
18
+
19
+ ...(striped && {
20
+ "&:nth-of-type(odd)": {
21
+ backgroundColor:
22
+ theme.palette.mode === "dark"
23
+ ? theme.palette.action.hover
24
+ : theme.palette.grey[50],
25
+ },
26
+ }),
27
+
28
+ ...(hoverable && {
29
+ transition: "background-color 0.2s ease, box-shadow 0.2s ease",
30
+ "&:hover": {
31
+ backgroundColor: theme.palette.action.hover,
32
+ boxShadow: `inset 0 2px 2px rgba(0,0,0,0.05),
33
+ inset 0 -2px 2px rgba(0,0,0,0.05)`,
34
+ },
35
+ }),
36
+ }));
37
+
38
+ export const TableBodyCell = styled("td", {
39
+ shouldForwardProp: (prop) =>
40
+ prop !== "compact" &&
41
+ prop !== "isDragging" &&
42
+ prop !== "isPinned" &&
43
+ prop !== "wrap",
44
+ })<{
45
+ compact?: boolean;
46
+ isDragging?: boolean;
47
+ isPinned?: boolean;
48
+ wrap?: boolean;
49
+ }>(({ theme, compact, isDragging, wrap }) => ({
50
+ fontSize: theme.typography.pxToRem(14),
51
+ padding: compact ? theme.spacing(0.25, 0.5) : theme.spacing(0.5, 1),
52
+ borderTop: `1px solid ${theme.palette.divider}`,
53
+ borderBottom: `1px solid ${theme.palette.divider}`,
54
+
55
+ ...(wrap && {
56
+ wordBreak: "break-all",
57
+ whiteSpace: "normal",
58
+ }),
59
+
60
+ ...(isDragging && {
61
+ opacity: 0.85,
62
+ backgroundColor: theme.palette.action.hover,
63
+ }),
64
+ }));
@@ -8,15 +8,16 @@ import {
8
8
  import {
9
9
  CraftTableFeatureProps,
10
10
  CraftTableOptionsProps,
11
- } from "../types/table-options";
12
- import { align } from "../types/common";
11
+ } from "../../types/table-options";
12
+ import { align } from "../../types/common";
13
13
  import DragAlongCell from "./table-body-dnd-cell";
14
14
  import {
15
15
  horizontalListSortingStrategy,
16
16
  SortableContext,
17
17
  } from "@dnd-kit/sortable";
18
- import { getColumnPinningStylesBody } from "../libs/utils/common";
19
- import Checkbox from "./inputs/checkbox";
18
+ import { getColumnPinningStylesBody } from "../../libs/utils/common";
19
+ import Checkbox from "../inputs/checkbox";
20
+ import { TableBodyCell, TableBodyRow } from "./table-body.styles";
20
21
 
21
22
  interface TableBodyProps<T> {
22
23
  table: Table<T>;
@@ -39,10 +40,15 @@ function TableBody<T>({
39
40
 
40
41
  const renderRow = (row: Row<T>) => {
41
42
  const renderedRow = (
42
- <tr key={row.id} className="ts__body__tr">
43
+ <TableBodyRow
44
+ key={row?.id}
45
+ hoverable
46
+ striped={featureOptions.striped}
47
+ selected={row.getIsSelected()}
48
+ expanded={row.getIsExpanded()}
49
+ >
43
50
  {enableRowSelection && (
44
- <td
45
- className="ts__body__td ts__body__checkbox"
51
+ <TableBodyCell
46
52
  style={{
47
53
  position: "sticky",
48
54
  left: 0,
@@ -55,23 +61,10 @@ function TableBody<T>({
55
61
  onChange={row.getToggleSelectedHandler()}
56
62
  className="checkbox__input"
57
63
  />
58
- </td>
64
+ </TableBodyCell>
59
65
  )}
60
66
 
61
67
  {row?.getVisibleCells()?.map((cell) => {
62
- const tdProps = {
63
- className: "ts__body__td",
64
- style: {
65
- ...getColumnPinningStylesBody(cell.column),
66
- width: cell.column.getSize(),
67
- ...((wrapColumns.all_wrap || wrapColumns[cell.column.id]) && {
68
- wordBreak: "break-all",
69
- // whiteSpace: "normal",
70
- }),
71
- } as React.CSSProperties,
72
- align: (cell.column.columnDef.meta as align)?.align || "left",
73
- };
74
-
75
68
  return enableColumnReordering ? (
76
69
  <SortableContext
77
70
  key={cell.id}
@@ -85,12 +78,22 @@ function TableBody<T>({
85
78
  />
86
79
  </SortableContext>
87
80
  ) : (
88
- <td key={cell?.id} {...tdProps}>
81
+ <TableBodyCell
82
+ style={{
83
+ ...getColumnPinningStylesBody(cell.column),
84
+ width: cell.column.getSize(),
85
+ ...((wrapColumns.all_wrap || wrapColumns[cell.column.id]) && {
86
+ wordBreak: "break-all",
87
+ whiteSpace: "normal",
88
+ }),
89
+ }}
90
+ align={(cell.column.columnDef.meta as align)?.align || "left"}
91
+ >
89
92
  {flexRender(cell?.column?.columnDef?.cell, cell?.getContext())}
90
- </td>
93
+ </TableBodyCell>
91
94
  );
92
95
  })}
93
- </tr>
96
+ </TableBodyRow>
94
97
  );
95
98
 
96
99
  if (row.getIsExpanded()) {
@@ -98,12 +101,14 @@ function TableBody<T>({
98
101
  <React.Fragment key={row.id}>
99
102
  {renderedRow}
100
103
  {NestedComponent && (
101
- <tr>
102
- {/* <td colSpan={table.getAllLeafColumns().length}>//commented out to remove extra line on opening of
103
- {NestedComponent && <NestedComponent {...{ row }} />}
104
- </td> */}
104
+ <TableBodyRow
105
+ hoverable
106
+ striped={featureOptions.striped}
107
+ selected={row.getIsSelected()}
108
+ expanded={row.getIsExpanded()}
109
+ >
105
110
  {<NestedComponent {...{ row }} />}
106
- </tr>
111
+ </TableBodyRow>
107
112
  )}
108
113
  </React.Fragment>
109
114
  );
@@ -113,9 +118,7 @@ function TableBody<T>({
113
118
  };
114
119
 
115
120
  return (
116
- <tbody className="ts__body">
117
- {table?.getRowModel()?.rows?.map((row) => renderRow(row))}
118
- </tbody>
121
+ <tbody>{table?.getRowModel()?.rows?.map((row) => renderRow(row))}</tbody>
119
122
  );
120
123
  }
121
124
 
@@ -0,0 +1,112 @@
1
+ import { flexRender } from "@tanstack/react-table";
2
+ import { useSortable } from "@dnd-kit/sortable";
3
+ import { useState } from "react";
4
+ import { CSS } from "@dnd-kit/utilities";
5
+ import { DownArrow, DragHandleIcon, UpArrow } from "../../../assets/svg";
6
+ import { getColumnPinningStyles } from "../../libs/utils/common";
7
+ import { TableHeaderProps } from "../../types/table";
8
+ import TableHeadPin from "./table-head-pin";
9
+ import TableHeadPopover from "./table-head-popover";
10
+ import TableColumnResizeHandle from "./table-head-resizer";
11
+ import {
12
+ TableDndButton,
13
+ TableHeadCell,
14
+ TableHeadContent,
15
+ TableHeadSort,
16
+ } from "./table-head.styles";
17
+ import { Box } from "@mui/material";
18
+
19
+ function DraggableTableHeader<T>({
20
+ header,
21
+ activeTab,
22
+ featureOptions,
23
+ tableStates,
24
+ onSaveSettings,
25
+ }: TableHeaderProps<T>) {
26
+ const { enableColumnPinning } = featureOptions;
27
+
28
+ // Popover
29
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
30
+
31
+ const handleHover = (event: React.MouseEvent<HTMLElement>) => {
32
+ setAnchorEl((prev) => (prev ? null : event.currentTarget));
33
+ };
34
+
35
+ const handleClose = () => {
36
+ setAnchorEl(null);
37
+ };
38
+
39
+ const { isDragging, transform, attributes, listeners } = useSortable({
40
+ id: header.column.id,
41
+ });
42
+
43
+ const isPinned = header.column.getIsPinned();
44
+
45
+ return (
46
+ <TableHeadCell
47
+ onMouseLeave={handleClose}
48
+ colSpan={header.colSpan}
49
+ onClick={handleHover}
50
+ compact={featureOptions?.compactTable}
51
+ isDragging={isDragging}
52
+ isPinned={Boolean(isPinned)}
53
+ style={{
54
+ width: `${header.column.getSize()}px`,
55
+ minWidth: `${header.column.columnDef.minSize ?? 180}px`,
56
+ maxWidth: `${header.column.columnDef.maxSize}px`,
57
+ transform: CSS.Translate.toString(transform),
58
+ transition: "width transform 0.2s ease-in-out",
59
+ ...getColumnPinningStyles(header.column),
60
+ }}
61
+ >
62
+ {header.isPlaceholder ? null : (
63
+ <TableHeadContent>
64
+ <TableHeadSort sortable={header.column.getCanSort()}>
65
+ {flexRender(header.column.columnDef.header, header.getContext())}
66
+ </TableHeadSort>
67
+
68
+ <Box
69
+ display={"flex"}
70
+ alignItems={"center"}
71
+ justifyContent={"center"}
72
+ gap={0.5}
73
+ >
74
+ {{
75
+ asc: <UpArrow />,
76
+ desc: <DownArrow />,
77
+ }[header.column.getIsSorted() as "asc" | "desc"] ?? null}
78
+
79
+ {enableColumnPinning && (
80
+ <TableHeadPin
81
+ header={header}
82
+ featureOptions={featureOptions}
83
+ tableStates={tableStates}
84
+ />
85
+ )}
86
+
87
+ <TableDndButton {...attributes} {...listeners}>
88
+ <DragHandleIcon />
89
+ </TableDndButton>
90
+ </Box>
91
+ </TableHeadContent>
92
+ )}
93
+
94
+ {/* column resizing */}
95
+ {header.column.getCanResize() ? (
96
+ <TableColumnResizeHandle header={header} />
97
+ ) : null}
98
+
99
+ {/* Popover */}
100
+ <TableHeadPopover
101
+ anchorEl={anchorEl}
102
+ activeTab={activeTab}
103
+ onClose={handleClose}
104
+ header={header}
105
+ tableStates={tableStates}
106
+ onSaveSettings={onSaveSettings}
107
+ />
108
+ </TableHeadCell>
109
+ );
110
+ }
111
+
112
+ export default DraggableTableHeader;
@@ -0,0 +1,29 @@
1
+ import { IconPinOffOutline } from "../../../assets/svg";
2
+ import { TableHeaderProps } from "../../types/table";
3
+ import { TableHeadButton } from "./table-head.styles";
4
+
5
+ function TableHeadPin<T>({ header }: TableHeaderProps<T>) {
6
+ // ! Header now is pinned via dropdown on table head
7
+ // if (header.column.getIsPinned() !== "left") {
8
+ // return (
9
+ // <TableHeadButton onClick={() => header.column.pin("left")}>
10
+ // {/* <IconPinOutline /> */}
11
+ // </TableHeadButton>
12
+ // );
13
+ // }
14
+
15
+ return (
16
+ header.column.getIsPinned() && (
17
+ <TableHeadButton
18
+ onClick={(e) => {
19
+ e.stopPropagation();
20
+ header.column.pin(false);
21
+ }}
22
+ >
23
+ <IconPinOffOutline />
24
+ </TableHeadButton>
25
+ )
26
+ );
27
+ }
28
+
29
+ export default TableHeadPin;
@@ -13,21 +13,12 @@ import {
13
13
  HideIcon,
14
14
  IconPinOffOutline,
15
15
  IconPinOutline,
16
- } from "../../assets/svg";
16
+ } from "../../../assets/svg";
17
17
  import {
18
18
  craftTableFilterSettingsOptionsProps,
19
19
  CraftTableOptionsProps,
20
- } from "../types/table-options";
21
- import { useFullscreenPopoverContainer } from "../libs/hooks/useFullScreen";
22
- import { ENTITY_TYPE, MAPPED_ENTITY_TYPE } from "../libs/utils/common";
23
- import {
24
- ColumnTabConfigProps,
25
- SettingsDataProps,
26
- } from "../types/filter-settings";
27
- import { useSaveSettingsDataAPI } from "../libs/hooks/useEntityTableAPI";
28
- import { useQueryClient } from "@tanstack/react-query";
29
- import { useCraftTableFilterSettings } from "../libs/hooks/useCraftTableFilterSettings";
30
- import { ColumnItem } from "./table-settings/components/column";
20
+ } from "../../types/table-options";
21
+ import { useFullscreenPopoverContainer } from "../../libs/hooks/useFullScreen";
31
22
 
32
23
  type Props<T> = {
33
24
  anchorEl: HTMLElement | null;
@@ -35,24 +26,21 @@ type Props<T> = {
35
26
  onClose: () => void;
36
27
  header: Header<T, unknown>;
37
28
  tableStates: CraftTableOptionsProps;
38
- filterSettingStates: craftTableFilterSettingsOptionsProps;
29
+ filterSettingStates?: craftTableFilterSettingsOptionsProps;
39
30
  onSaveSettings?: (columnId: string) => void;
40
31
  };
41
32
 
42
33
  function TableHeadPopover<T>({
43
34
  anchorEl,
44
- activeTab,
45
35
  onClose,
46
36
  header,
47
37
  tableStates,
48
- filterSettingStates,
49
38
  onSaveSettings,
50
39
  }: Props<T>) {
51
40
  const open = Boolean(anchorEl);
52
41
  const column = header.column;
53
42
  const isPinned = column.getIsPinned() === "left";
54
43
  const { container: fullscreenContainer } = useFullscreenPopoverContainer();
55
- const queryClient = useQueryClient();
56
44
  const { wrapColumns, setWrapColumns } = tableStates;
57
45
 
58
46
  const toggleWrapForColumn = (columnId: string) => {
@@ -0,0 +1,22 @@
1
+ import { Header } from "@tanstack/react-table";
2
+ import { ColumnResizeHandle } from "./table-head.styles";
3
+
4
+ interface Props<T> {
5
+ header: Header<T, unknown>;
6
+ }
7
+
8
+ function TableColumnResizeHandle<T>({ header }: Props<T>) {
9
+ return (
10
+ <ColumnResizeHandle
11
+ isResizing={header.column.getIsResizing()}
12
+ onDoubleClick={() => header.column.resetSize()}
13
+ onMouseDown={header.getResizeHandler()}
14
+ onTouchStart={header.getResizeHandler()}
15
+ className={`column__resize ${
16
+ header.column.getIsResizing() ? "is__resizing" : ""
17
+ }`}
18
+ />
19
+ );
20
+ }
21
+
22
+ export default TableColumnResizeHandle;
@@ -0,0 +1,115 @@
1
+ // columnResize.styles.ts
2
+ import { Box } from "@mui/material";
3
+ import { styled } from "@mui/material/styles";
4
+
5
+ export const ColumnResizeHandle = styled(Box, {
6
+ shouldForwardProp: (prop) => prop !== "isResizing",
7
+ })<{ isResizing?: boolean }>(({ theme, isResizing }) => ({
8
+ position: "absolute",
9
+ top: 0,
10
+ right: 0,
11
+ height: "100%",
12
+ width: theme.spacing(0.5),
13
+ cursor: "col-resize",
14
+ userSelect: "none",
15
+ touchAction: "none",
16
+ opacity: isResizing ? 1 : 0,
17
+ background: isResizing ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.5)",
18
+
19
+ "&:hover": {
20
+ opacity: 1,
21
+ },
22
+ }));
23
+
24
+ export const TableHeadButton = styled(Box)(({ theme }) => ({
25
+ display: "flex",
26
+ justifyContent: "center",
27
+ alignItems: "center",
28
+ cursor: "pointer",
29
+ transition: "transform 0.15s ease",
30
+
31
+ "&:hover": {
32
+ transform: "scale(1.1)",
33
+ },
34
+
35
+ "& svg": {
36
+ color: theme.palette.grey[700],
37
+ },
38
+ }));
39
+
40
+ export const TableHeadSort = styled(Box, {
41
+ shouldForwardProp: (prop) => prop !== "sortable",
42
+ })<{ sortable?: boolean }>(({ theme, sortable }) => ({
43
+ userSelect: sortable ? "none" : "auto",
44
+ fontSize: theme.typography.pxToRem(14),
45
+
46
+ "& svg": {
47
+ marginLeft: "0.25rem",
48
+ },
49
+ }));
50
+
51
+ export const TableDndButton = styled(Box)(({ theme }) => ({
52
+ display: "inline-flex",
53
+ alignItems: "center",
54
+ justifyContent: "center",
55
+ color: theme.palette.grey[600],
56
+ cursor: "grab",
57
+ transition: "transform 0.15s ease, color 0.15s ease",
58
+
59
+ "&:hover": {
60
+ transform: "scale(1.1)",
61
+ color: theme.palette.grey[900],
62
+ cursor: "grabbing",
63
+ },
64
+ }));
65
+
66
+ export const TableHeadContent = styled(Box)(({ theme }) => ({
67
+ display: "flex",
68
+ alignItems: "center",
69
+ justifyContent: "space-between",
70
+ gap: theme.spacing(1),
71
+ }));
72
+
73
+ export const TableHeadRoot = styled("thead", {
74
+ shouldForwardProp: (prop) => prop !== "sticky",
75
+ })<{ sticky?: boolean }>(({ sticky }) => ({
76
+ position: sticky ? "sticky" : "relative",
77
+ top: sticky ? 0 : "auto",
78
+ zIndex: sticky ? 3 : "auto",
79
+ }));
80
+
81
+ export const TableHeadRow = styled("tr", {
82
+ shouldForwardProp: (prop) => prop !== "striped",
83
+ })<{ striped?: boolean }>(({ theme, striped }) => ({
84
+ backgroundColor: striped
85
+ ? theme.palette.common.white
86
+ : theme.palette.grey[100],
87
+ }));
88
+
89
+ export const TableHeadCell = styled("th", {
90
+ shouldForwardProp: (prop) =>
91
+ prop !== "compact" && prop !== "isDragging" && prop !== "isPinned",
92
+ })<{
93
+ compact?: boolean;
94
+ isDragging?: boolean;
95
+ isPinned?: boolean;
96
+ sticky?: boolean;
97
+ }>(({ theme, compact, isDragging, isPinned, sticky }) => ({
98
+ position: "relative",
99
+ padding: compact ? theme.spacing(0.375, 0.675) : theme.spacing(0.75, 1),
100
+ borderWidth: "0.5px",
101
+ borderStyle: "solid",
102
+ borderColor: theme.palette.grey[500],
103
+ cursor: "pointer",
104
+ backgroundColor: theme.palette.common.white,
105
+ userSelect: "none",
106
+ // smoother drag feedback
107
+ opacity: isDragging ? 0.8 : 1,
108
+ zIndex: isPinned ? 3 : isDragging ? 1 : 0,
109
+
110
+ ...(sticky && {
111
+ position: "sticky",
112
+ left: 0,
113
+ zIndex: 4,
114
+ }),
115
+ }));