@symply.io/basic-components 1.0.0-beta.6 → 1.0.0-beta.9
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.
- package/BasicTable/TableBody.d.ts +4 -0
- package/BasicTable/TableBody.js +51 -0
- package/BasicTable/TableBodyRow.d.ts +3 -0
- package/BasicTable/TableBodyRow.js +42 -0
- package/BasicTable/TableFooter.d.ts +3 -0
- package/BasicTable/TableFooter.js +44 -0
- package/BasicTable/TableHeader.d.ts +3 -0
- package/BasicTable/TableHeader.js +47 -0
- package/BasicTable/index.d.ts +5 -0
- package/BasicTable/index.js +88 -0
- package/BasicTable/types.d.ts +74 -0
- package/BasicTable/types.js +1 -0
- package/BasicTable/useScroll.d.ts +9 -0
- package/BasicTable/useScroll.js +76 -0
- package/BasicTable/useTable.d.ts +41 -0
- package/BasicTable/useTable.js +94 -0
- package/README.md +57 -1
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +1 -1
@@ -0,0 +1,51 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
13
|
+
import { forwardRef } from "react";
|
14
|
+
import Grid from "@mui/material/Grid";
|
15
|
+
import useCustomTheme from "../useCustomTheme";
|
16
|
+
import TableBodyRow from "./TableBodyRow";
|
17
|
+
var BasicTableBody = forwardRef(function (props, ref) {
|
18
|
+
var rows = props.rows, columns = props.columns, forFrozen = props.forFrozen, noDataText = props.noDataText, cellMinWidth = props.cellMinWidth;
|
19
|
+
var theme = useCustomTheme();
|
20
|
+
return (_jsx(Grid, __assign({ item: true, sx: {
|
21
|
+
maxHeight: "41vh",
|
22
|
+
overflowY: "auto",
|
23
|
+
display: "block",
|
24
|
+
minWidth: "100%",
|
25
|
+
scrollbarWidth: forFrozen ? "none" : "initial",
|
26
|
+
"&::-webkit-scrollbar": {
|
27
|
+
width: forFrozen ? 0 : "initial"
|
28
|
+
}
|
29
|
+
} }, { children: _jsx("div", __assign({ ref: ref }, { children: rows && rows.length > 0 ? (rows.map(function (row, index) {
|
30
|
+
return (_jsx(TableBodyRow, { row: row, rows: rows, columns: columns, cellMinWidth: cellMinWidth }, "BasicTable_".concat(index)));
|
31
|
+
})) : (_jsx(Grid, __assign({ container: true, justifyContent: "space-around", alignItems: "center", wrap: "nowrap", sx: {
|
32
|
+
height: "60px",
|
33
|
+
borderBottomWidth: "thin",
|
34
|
+
borderBottomColor: "#e5e5e5",
|
35
|
+
borderBottomStyle: "solid",
|
36
|
+
padding: theme.spacing(0.5, 0),
|
37
|
+
minHeight: theme.spacing(6),
|
38
|
+
"& :nth-of-last-type(1)": {
|
39
|
+
borderBottom: "none"
|
40
|
+
},
|
41
|
+
"& input": {
|
42
|
+
fontSize: "0.9rem",
|
43
|
+
fontWeight: 600
|
44
|
+
}
|
45
|
+
} }, { children: _jsx(Grid, __assign({ item: true, xs: 4, md: 3, lg: 2, textAlign: "center", sx: {
|
46
|
+
minWidth: cellMinWidth,
|
47
|
+
paddingLeft: theme.spacing(0.625),
|
48
|
+
paddingRight: theme.spacing(0.625)
|
49
|
+
} }, { children: noDataText })) }))) })) })));
|
50
|
+
});
|
51
|
+
export default BasicTableBody;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
13
|
+
import { cloneElement } from "react";
|
14
|
+
import Grid from "@mui/material/Grid";
|
15
|
+
import useCustomTheme from "../useCustomTheme";
|
16
|
+
function BasicTableBodyRow(props) {
|
17
|
+
var row = props.row, rows = props.rows, columns = props.columns, cellMinWidth = props.cellMinWidth;
|
18
|
+
var theme = useCustomTheme();
|
19
|
+
return (_jsx(Grid, __assign({ container: true, justifyContent: "space-evenly", alignItems: "center", wrap: "nowrap", sx: {
|
20
|
+
height: "60px",
|
21
|
+
borderBottomWidth: "thin",
|
22
|
+
borderBottomColor: "#e5e5e5",
|
23
|
+
borderBottomStyle: "solid",
|
24
|
+
padding: theme.spacing(0.5, 0),
|
25
|
+
minHeight: theme.spacing(6),
|
26
|
+
"& :nth-of-last-type(1)": {
|
27
|
+
borderBottom: "none"
|
28
|
+
},
|
29
|
+
"& input": {
|
30
|
+
fontSize: "0.9rem",
|
31
|
+
fontWeight: 600
|
32
|
+
}
|
33
|
+
} }, { children: columns.map(function (col) {
|
34
|
+
var accessor = col.accessor, Cell = col.Cell, _a = col.align, align = _a === void 0 ? "center" : _a;
|
35
|
+
return (_jsx(Grid, __assign({ item: true, xs: 4, md: 3, lg: 2, textAlign: align, sx: {
|
36
|
+
minWidth: cellMinWidth,
|
37
|
+
paddingLeft: theme.spacing(0.625),
|
38
|
+
paddingRight: theme.spacing(0.625)
|
39
|
+
} }, { children: cloneElement(Cell, { column: col, rows: rows, row: row }) }), accessor));
|
40
|
+
}) })));
|
41
|
+
}
|
42
|
+
export default BasicTableBodyRow;
|
@@ -0,0 +1,44 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
13
|
+
import { cloneElement } from "react";
|
14
|
+
import Grid from "@mui/material/Grid";
|
15
|
+
import useCustomTheme from "../useCustomTheme";
|
16
|
+
function BasicTableFooter(props) {
|
17
|
+
var footers = props.footers, cellMinWidth = props.cellMinWidth;
|
18
|
+
var theme = useCustomTheme();
|
19
|
+
return footers && footers.length > 0 ? (_jsx(Grid, __assign({ item: true, sx: {
|
20
|
+
backgroundColor: "#eaf0f6",
|
21
|
+
padding: theme.spacing(1.5, 0),
|
22
|
+
height: "50px"
|
23
|
+
} }, { children: _jsx(Grid, __assign({ container: true, justifyContent: "space-evenly", alignItems: "center", wrap: "nowrap", sx: {
|
24
|
+
lineHeight: "24px",
|
25
|
+
minWidth: "100%",
|
26
|
+
"& span": {
|
27
|
+
color: "#172b4d",
|
28
|
+
fontSize: "1rem",
|
29
|
+
fontWeight: 600
|
30
|
+
}
|
31
|
+
} }, { children: footers.map(function (footer) {
|
32
|
+
var accessor = footer.accessor, Cell = footer.Cell, _a = footer.align, align = _a === void 0 ? "center" : _a;
|
33
|
+
return (_jsx(Grid, __assign({ item: true, xs: 4, md: 3, lg: 2, textAlign: align, sx: {
|
34
|
+
minWidth: cellMinWidth,
|
35
|
+
paddingLeft: theme.spacing(0.625),
|
36
|
+
paddingRight: theme.spacing(0.625),
|
37
|
+
whiteSpace: "nowrap",
|
38
|
+
textOverflow: "ellipsis",
|
39
|
+
overflow: "hidden",
|
40
|
+
userSelect: "none"
|
41
|
+
} }, { children: cloneElement(Cell) }), accessor));
|
42
|
+
}) })) }))) : (_jsx(_Fragment, {}));
|
43
|
+
}
|
44
|
+
export default BasicTableFooter;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
13
|
+
import { cloneElement } from "react";
|
14
|
+
import Grid from "@mui/material/Grid";
|
15
|
+
import useCustomTheme from "../useCustomTheme";
|
16
|
+
function BasicTableHeader(props) {
|
17
|
+
var headers = props.headers, cellMinWidth = props.cellMinWidth;
|
18
|
+
var theme = useCustomTheme();
|
19
|
+
return headers && headers.length > 0 ? (_jsx(Grid, __assign({ item: true, sx: {
|
20
|
+
backgroundColor: "#eaf0f6",
|
21
|
+
padding: theme.spacing(1.5, 0),
|
22
|
+
height: "50px"
|
23
|
+
} }, { children: _jsx(Grid, __assign({ container: true, justifyContent: "space-evenly", alignItems: "center", wrap: "nowrap", sx: {
|
24
|
+
lineHeight: "24px",
|
25
|
+
minWidth: "100%",
|
26
|
+
"& span": {
|
27
|
+
color: "#172b4d",
|
28
|
+
fontSize: "1rem",
|
29
|
+
fontWeight: 600
|
30
|
+
}
|
31
|
+
} }, { children: headers.map(function (header) {
|
32
|
+
var accessor = header.accessor, Cell = header.Cell, _a = header.align, align = _a === void 0 ? "center" : _a, title = header.title, onSort = header.onSort, _b = header.canSort, canSort = _b === void 0 ? false : _b;
|
33
|
+
return (_jsx(Grid, __assign({ item: true, xs: 4, md: 3, lg: 2, title: title, textAlign: align, sx: {
|
34
|
+
minWidth: cellMinWidth,
|
35
|
+
paddingLeft: theme.spacing(0.625),
|
36
|
+
paddingRight: theme.spacing(0.625),
|
37
|
+
whiteSpace: "nowrap",
|
38
|
+
textOverflow: "ellipsis",
|
39
|
+
overflow: "hidden",
|
40
|
+
userSelect: "none",
|
41
|
+
cursor: canSort ? "pointer" : "default"
|
42
|
+
}, onClick: function () {
|
43
|
+
onSort({ field: accessor });
|
44
|
+
} }, { children: cloneElement(Cell) }), accessor));
|
45
|
+
}) })) }))) : (_jsx(_Fragment, {}));
|
46
|
+
}
|
47
|
+
export default BasicTableHeader;
|
@@ -0,0 +1,88 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
13
|
+
import { useMemo, useEffect } from "react";
|
14
|
+
import Grid from "@mui/material/Grid";
|
15
|
+
import TableContainer from "@mui/material/TableContainer";
|
16
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
17
|
+
import ThemeProvider from "@mui/material/styles/ThemeProvider";
|
18
|
+
import useCustomTheme from "../useCustomTheme";
|
19
|
+
import useScroll from "./useScroll";
|
20
|
+
import TableBody from "./TableBody";
|
21
|
+
import TableHeader from "./TableHeader";
|
22
|
+
import TableFooter from "./TableFooter";
|
23
|
+
function BasicTable(props) {
|
24
|
+
var _a;
|
25
|
+
var _b;
|
26
|
+
var _c = props.columns, columns = _c === void 0 ? [] : _c, _d = props.rows, rows = _d === void 0 ? [] : _d, _e = props.headers, headers = _e === void 0 ? [] : _e, _f = props.footers, footers = _f === void 0 ? [] : _f, _g = props.noDataText, noDataText = _g === void 0 ? "No Data!" : _g, primaryColor = props.primaryColor, secondaryColor = props.secondaryColor, _h = props.cellMinWidth, cellMinWidth = _h === void 0 ? "initial" : _h;
|
27
|
+
var theme = useCustomTheme({ primaryColor: primaryColor, secondaryColor: secondaryColor });
|
28
|
+
var isUpMd = useMediaQuery(theme.breakpoints.up("md"));
|
29
|
+
var fronzenColsCount = useMemo(function () { var _a; return (_a = columns.filter(function (col) { return col.canBeFrozen; })) === null || _a === void 0 ? void 0 : _a.length; }, [columns]);
|
30
|
+
var canFreeze = useMemo(function () { return isUpMd && (rows === null || rows === void 0 ? void 0 : rows.length) > 0 && fronzenColsCount > 0; }, [fronzenColsCount, isUpMd, rows.length]);
|
31
|
+
var _j = useScroll({
|
32
|
+
canFreeze: canFreeze
|
33
|
+
}), frozenWidth = _j.frozenWidth, setFrozenWidth = _j.setFrozenWidth, fixedRef = _j.fixedRef, dynamicRef = _j.dynamicRef;
|
34
|
+
useEffect(function () {
|
35
|
+
var _a, _b;
|
36
|
+
var initFrozenWidth = ((_a = document.getElementById("frozenContainer")) === null || _a === void 0 ? void 0 : _a.clientWidth) ||
|
37
|
+
((_b = fixedRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) ||
|
38
|
+
fronzenColsCount * 123 ||
|
39
|
+
370;
|
40
|
+
if (columns) {
|
41
|
+
setFrozenWidth(function (fw) {
|
42
|
+
if (fw !== initFrozenWidth) {
|
43
|
+
return initFrozenWidth;
|
44
|
+
}
|
45
|
+
return fw;
|
46
|
+
});
|
47
|
+
}
|
48
|
+
}, [columns, fixedRef, fronzenColsCount, setFrozenWidth]);
|
49
|
+
return (_jsx(ThemeProvider, __assign({ theme: theme }, { children: _jsx(TableContainer, __assign({ sx: (_a = {
|
50
|
+
borderWidth: "thin",
|
51
|
+
borderColor: "#e5e5e5",
|
52
|
+
borderStyle: "solid",
|
53
|
+
borderRadius: "4px",
|
54
|
+
borderCollapse: "unset !important",
|
55
|
+
margin: theme.spacing(2, 0, 3, 0),
|
56
|
+
width: "100%"
|
57
|
+
},
|
58
|
+
_a[theme.breakpoints.up("sm")] = {
|
59
|
+
minWidth: "600px"
|
60
|
+
},
|
61
|
+
_a.position = "relative",
|
62
|
+
_a.transition = "all 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
|
63
|
+
_a) }, { children: _jsxs(Grid, __assign({ container: true, direction: "row", justifyContent: "flex-start", alignItems: "center", wrap: "nowrap" }, { children: [canFreeze && (_jsx(Grid, __assign({ id: "frozenContainer", item: true, sx: {
|
64
|
+
top: 0,
|
65
|
+
left: 0,
|
66
|
+
position: "absolute",
|
67
|
+
zIndex: 999,
|
68
|
+
backgroundColor: "Menu",
|
69
|
+
boxShadow: "6px 0 6px -4px rgba(0,0,0,0.15)"
|
70
|
+
} }, { children: _jsxs(Grid, __assign({ container: true, direction: "column", justifyContent: "center" }, { children: [_jsx(TableHeader, { cellMinWidth: cellMinWidth, headers: headers.filter(function (header) { return header.canBeFrozen; }) }), _jsx(TableBody, { forFrozen: true, rows: rows, ref: fixedRef, cellMinWidth: cellMinWidth, columns: columns.filter(function (col) { return col.canBeFrozen; }) }), _jsx(TableFooter, { cellMinWidth: cellMinWidth, footers: footers.filter(function (footer) { return footer.canBeFrozen; }) })] })) }))), _jsx(Grid, __assign({ item: true, style: {
|
71
|
+
width: "100%",
|
72
|
+
marginLeft: canFreeze
|
73
|
+
? ((_b = document.getElementById("frozenContainer")) === null || _b === void 0 ? void 0 : _b.clientWidth) ||
|
74
|
+
frozenWidth ||
|
75
|
+
0
|
76
|
+
: 0,
|
77
|
+
overflow: "auto"
|
78
|
+
} }, { children: _jsxs(Grid, __assign({ container: true, direction: "column", justifyContent: "center" }, { children: [_jsx(TableHeader, { cellMinWidth: cellMinWidth, headers: headers.filter(function (header) {
|
79
|
+
return isUpMd ? !header.canBeFrozen : true;
|
80
|
+
}) }), _jsx(TableBody, { rows: rows, ref: dynamicRef, noDataText: noDataText, columns: columns.filter(function (col) {
|
81
|
+
return isUpMd ? !col.canBeFrozen : true;
|
82
|
+
}), cellMinWidth: cellMinWidth }), _jsx(TableFooter, { footers: footers.filter(function (footer) {
|
83
|
+
return isUpMd ? !footer.canBeFrozen : true;
|
84
|
+
}), cellMinWidth: cellMinWidth })] })) }))] })) })) })));
|
85
|
+
}
|
86
|
+
export default BasicTable;
|
87
|
+
export * from "./types";
|
88
|
+
export { default as useTable } from "./useTable";
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { ReactElement, CSSProperties } from "react";
|
2
|
+
interface SortByProps {
|
3
|
+
id: string;
|
4
|
+
desc: boolean;
|
5
|
+
}
|
6
|
+
interface InitialStateProps {
|
7
|
+
sortBy?: SortByProps;
|
8
|
+
}
|
9
|
+
export interface IColumn {
|
10
|
+
Header: ReactElement;
|
11
|
+
headerTip?: string;
|
12
|
+
Body: ReactElement;
|
13
|
+
Footer?: ReactElement;
|
14
|
+
align?: "left" | "center" | "right";
|
15
|
+
accessor: string;
|
16
|
+
canSort?: boolean;
|
17
|
+
canBeFrozen?: boolean;
|
18
|
+
[name: string]: unknown;
|
19
|
+
}
|
20
|
+
interface IHeader extends IColumn {
|
21
|
+
Cell: ReactElement;
|
22
|
+
title: string;
|
23
|
+
canSort?: boolean;
|
24
|
+
onSort: (props: SortingProps) => unknown;
|
25
|
+
}
|
26
|
+
interface IFooter extends IColumn {
|
27
|
+
Cell: ReactElement;
|
28
|
+
}
|
29
|
+
interface IBodyColumn extends IColumn {
|
30
|
+
Cell: ReactElement;
|
31
|
+
}
|
32
|
+
export interface IRow {
|
33
|
+
[name: string]: unknown;
|
34
|
+
}
|
35
|
+
export interface SortingProps {
|
36
|
+
field: string;
|
37
|
+
isSorted?: boolean;
|
38
|
+
descending?: boolean;
|
39
|
+
}
|
40
|
+
export interface UseTableProps {
|
41
|
+
data: Array<IRow>;
|
42
|
+
columns: Array<IColumn>;
|
43
|
+
initialState?: InitialStateProps;
|
44
|
+
disableSortBy?: boolean;
|
45
|
+
onSort?: (props: SortingProps) => unknown;
|
46
|
+
}
|
47
|
+
export interface UseScrollProps {
|
48
|
+
canFreeze?: boolean;
|
49
|
+
}
|
50
|
+
interface BasicTableBaseProps {
|
51
|
+
cellMinWidth?: CSSProperties["minWidth"];
|
52
|
+
}
|
53
|
+
export interface BasicTableHeaderProps extends BasicTableBaseProps {
|
54
|
+
headers: Array<IHeader>;
|
55
|
+
}
|
56
|
+
export interface BasicTableFooterProps extends BasicTableBaseProps {
|
57
|
+
footers: Array<IFooter>;
|
58
|
+
}
|
59
|
+
export interface BasicTableBodyProps extends BasicTableBaseProps {
|
60
|
+
columns: Array<IBodyColumn>;
|
61
|
+
rows: Array<IRow>;
|
62
|
+
noDataText?: string;
|
63
|
+
forFrozen?: boolean;
|
64
|
+
}
|
65
|
+
export interface BasicTableBodyRowProps extends BasicTableBaseProps {
|
66
|
+
columns: Array<IBodyColumn>;
|
67
|
+
rows: Array<IRow>;
|
68
|
+
row: IRow;
|
69
|
+
}
|
70
|
+
export declare type BasicTableProps = BasicTableHeaderProps & Omit<BasicTableBodyProps, "forFrozen"> & Partial<BasicTableFooterProps> & {
|
71
|
+
primaryColor?: CSSProperties["color"];
|
72
|
+
secondaryColor?: CSSProperties["color"];
|
73
|
+
};
|
74
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { UseScrollProps } from "./types";
|
3
|
+
declare function useScroll(props: UseScrollProps): {
|
4
|
+
frozenWidth: number;
|
5
|
+
setFrozenWidth: import("react").Dispatch<import("react").SetStateAction<number>>;
|
6
|
+
fixedRef: import("react").RefObject<HTMLDivElement>;
|
7
|
+
dynamicRef: import("react").RefObject<HTMLDivElement>;
|
8
|
+
};
|
9
|
+
export default useScroll;
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import { useState, useCallback, useEffect, useRef } from "react";
|
2
|
+
import useTheme from "@mui/material/styles/useTheme";
|
3
|
+
import useMediaQuery from "@mui/material/useMediaQuery";
|
4
|
+
function useScroll(props) {
|
5
|
+
var canFreeze = props.canFreeze;
|
6
|
+
var theme = useTheme();
|
7
|
+
var isUpMd = useMediaQuery(theme.breakpoints.up("md"));
|
8
|
+
var _a = useState(370), frozenWidth = _a[0], setFrozenWidth = _a[1];
|
9
|
+
var fixedRef = useRef(null);
|
10
|
+
var dynamicRef = useRef(null);
|
11
|
+
var resetFrozenWidth = useCallback(function () {
|
12
|
+
setFrozenWidth(function (fw) {
|
13
|
+
var _a, _b;
|
14
|
+
if (fw !== ((_a = fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth)) {
|
15
|
+
return ((_b = fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current) === null || _b === void 0 ? void 0 : _b.clientWidth) || fw;
|
16
|
+
}
|
17
|
+
return fw;
|
18
|
+
});
|
19
|
+
}, [fixedRef]);
|
20
|
+
var onFixedScroll = useCallback(function (event) {
|
21
|
+
if (isUpMd && (dynamicRef === null || dynamicRef === void 0 ? void 0 : dynamicRef.current)) {
|
22
|
+
var targetDiv = event.target;
|
23
|
+
dynamicRef.current.scrollTop = targetDiv.scrollTop;
|
24
|
+
resetFrozenWidth();
|
25
|
+
}
|
26
|
+
}, [dynamicRef, isUpMd, resetFrozenWidth]);
|
27
|
+
var onDynamicScroll = useCallback(function (event) {
|
28
|
+
if (isUpMd && (fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current)) {
|
29
|
+
var targetDiv = event.target;
|
30
|
+
fixedRef.current.scrollTop = targetDiv.scrollTop;
|
31
|
+
resetFrozenWidth();
|
32
|
+
}
|
33
|
+
}, [fixedRef, isUpMd, resetFrozenWidth]);
|
34
|
+
var removeEventFixed = useCallback(function () {
|
35
|
+
if (fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current) {
|
36
|
+
fixedRef.current.removeEventListener("scroll", onFixedScroll);
|
37
|
+
}
|
38
|
+
}, [fixedRef, onFixedScroll]);
|
39
|
+
var removeEventDynamic = useCallback(function () {
|
40
|
+
if (dynamicRef === null || dynamicRef === void 0 ? void 0 : dynamicRef.current) {
|
41
|
+
dynamicRef.current.removeEventListener("scroll", onDynamicScroll);
|
42
|
+
}
|
43
|
+
}, [dynamicRef, onDynamicScroll]);
|
44
|
+
var bindEventFixed = useCallback(function () {
|
45
|
+
removeEventDynamic();
|
46
|
+
if (fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current) {
|
47
|
+
fixedRef.current.addEventListener("scroll", onFixedScroll);
|
48
|
+
}
|
49
|
+
}, [fixedRef, onFixedScroll, removeEventDynamic]);
|
50
|
+
var bindEventDynamic = useCallback(function () {
|
51
|
+
removeEventFixed();
|
52
|
+
if (dynamicRef === null || dynamicRef === void 0 ? void 0 : dynamicRef.current) {
|
53
|
+
dynamicRef.current.addEventListener("scroll", onDynamicScroll);
|
54
|
+
}
|
55
|
+
}, [dynamicRef, onDynamicScroll, removeEventFixed]);
|
56
|
+
useEffect(function () {
|
57
|
+
if (canFreeze) {
|
58
|
+
if (fixedRef === null || fixedRef === void 0 ? void 0 : fixedRef.current) {
|
59
|
+
fixedRef.current.addEventListener("mouseover", bindEventFixed);
|
60
|
+
}
|
61
|
+
if (dynamicRef === null || dynamicRef === void 0 ? void 0 : dynamicRef.current) {
|
62
|
+
dynamicRef.current.addEventListener("mouseover", bindEventDynamic);
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}, [
|
66
|
+
bindEventDynamic,
|
67
|
+
bindEventFixed,
|
68
|
+
canFreeze,
|
69
|
+
dynamicRef,
|
70
|
+
fixedRef,
|
71
|
+
onDynamicScroll,
|
72
|
+
onFixedScroll
|
73
|
+
]);
|
74
|
+
return { frozenWidth: frozenWidth, setFrozenWidth: setFrozenWidth, fixedRef: fixedRef, dynamicRef: dynamicRef };
|
75
|
+
}
|
76
|
+
export default useScroll;
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { UseTableProps, SortingProps } from "./types";
|
3
|
+
declare function useTable(props: UseTableProps): {
|
4
|
+
headers: {
|
5
|
+
Header: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
6
|
+
headerTip?: string | undefined;
|
7
|
+
Body: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
8
|
+
Footer?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
9
|
+
align?: "left" | "right" | "center" | undefined;
|
10
|
+
accessor: string;
|
11
|
+
canSort: boolean | undefined;
|
12
|
+
canBeFrozen?: boolean | undefined;
|
13
|
+
Cell: JSX.Element;
|
14
|
+
title: string;
|
15
|
+
onSort: ({ field }: Pick<SortingProps, "field">) => void;
|
16
|
+
}[];
|
17
|
+
footers: {
|
18
|
+
Header: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
19
|
+
headerTip?: string | undefined;
|
20
|
+
Body: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
21
|
+
Footer?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
22
|
+
align?: "left" | "right" | "center" | undefined;
|
23
|
+
accessor: string;
|
24
|
+
canSort?: boolean | undefined;
|
25
|
+
canBeFrozen?: boolean | undefined;
|
26
|
+
Cell: import("react").FunctionComponentElement<any>;
|
27
|
+
}[];
|
28
|
+
columns: {
|
29
|
+
Header: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
30
|
+
headerTip?: string | undefined;
|
31
|
+
Body: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
32
|
+
Footer?: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | undefined;
|
33
|
+
align?: "left" | "right" | "center" | undefined;
|
34
|
+
accessor: string;
|
35
|
+
canSort?: boolean | undefined;
|
36
|
+
canBeFrozen?: boolean | undefined;
|
37
|
+
Cell: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
38
|
+
}[];
|
39
|
+
rows: import("./types").IRow[];
|
40
|
+
};
|
41
|
+
export default useTable;
|
@@ -0,0 +1,94 @@
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
2
|
+
__assign = Object.assign || function(t) {
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
+
s = arguments[i];
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
+
t[p] = s[p];
|
7
|
+
}
|
8
|
+
return t;
|
9
|
+
};
|
10
|
+
return __assign.apply(this, arguments);
|
11
|
+
};
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
13
|
+
var t = {};
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
15
|
+
t[p] = s[p];
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
19
|
+
t[p[i]] = s[p[i]];
|
20
|
+
}
|
21
|
+
return t;
|
22
|
+
};
|
23
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
24
|
+
import { cloneElement, useState, useMemo, useCallback } from "react";
|
25
|
+
function useTable(props) {
|
26
|
+
var data = props.data, columns = props.columns, initialState = props.initialState, disableSortBy = props.disableSortBy, onSort = props.onSort, rest = __rest(props, ["data", "columns", "initialState", "disableSortBy", "onSort"]);
|
27
|
+
if (!data) {
|
28
|
+
throw new Error('"data" is required but got null or undefined');
|
29
|
+
}
|
30
|
+
if (!columns) {
|
31
|
+
throw new Error('"columns" is required but got null or undefined');
|
32
|
+
}
|
33
|
+
var sortBy = (initialState || {}).sortBy;
|
34
|
+
var _a = sortBy || {}, id = _a.id, desc = _a.desc;
|
35
|
+
var _b = useState({
|
36
|
+
field: id || "",
|
37
|
+
isSorted: !!id,
|
38
|
+
descending: desc || false
|
39
|
+
}), sortingProps = _b[0], setSortingProps = _b[1];
|
40
|
+
var handleSort = useCallback(function (_a) {
|
41
|
+
var field = _a.field;
|
42
|
+
if (!disableSortBy) {
|
43
|
+
var newSortingProps = __assign({}, sortingProps);
|
44
|
+
if (field !== sortingProps.field || !sortingProps.isSorted) {
|
45
|
+
newSortingProps = { field: field, isSorted: true, descending: false };
|
46
|
+
}
|
47
|
+
else if (!sortingProps.descending) {
|
48
|
+
newSortingProps = __assign(__assign({}, sortingProps), { descending: true });
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
newSortingProps = __assign(__assign({}, sortingProps), { isSorted: false });
|
52
|
+
}
|
53
|
+
if (onSort) {
|
54
|
+
onSort(__assign({}, newSortingProps));
|
55
|
+
}
|
56
|
+
setSortingProps(__assign({}, newSortingProps));
|
57
|
+
}
|
58
|
+
}, [disableSortBy, onSort, sortingProps]);
|
59
|
+
var renderSortingSymbol = useCallback(function (accessor) {
|
60
|
+
var field = sortingProps.field, isSorted = sortingProps.isSorted, descending = sortingProps.descending;
|
61
|
+
if (accessor !== field || !isSorted) {
|
62
|
+
return "";
|
63
|
+
}
|
64
|
+
if (!descending) {
|
65
|
+
return "↑";
|
66
|
+
}
|
67
|
+
return "↓";
|
68
|
+
}, [sortingProps]);
|
69
|
+
var rows = useMemo(function () { return data.map(function (d) { return d; }); }, [data]);
|
70
|
+
var cols = useMemo(function () {
|
71
|
+
return columns.map(function (col) {
|
72
|
+
var Body = col.Body;
|
73
|
+
return __assign(__assign({ Cell: cloneElement(Body || _jsx(_Fragment, {}), { column: col }) }, col), rest);
|
74
|
+
});
|
75
|
+
}, [columns, rest]);
|
76
|
+
var headers = useMemo(function () {
|
77
|
+
return columns.map(function (col) {
|
78
|
+
var Header = col.Header, accessor = col.accessor, canSort = col.canSort, headerTip = col.headerTip;
|
79
|
+
var canSortBy = canSort && !disableSortBy;
|
80
|
+
return __assign(__assign({ Cell: (_jsxs(_Fragment, { children: [cloneElement(Header || _jsx(_Fragment, {}), { column: col }), canSortBy && renderSortingSymbol(accessor)] })), title: "".concat(headerTip || "").concat(canSortBy ? " (Click to sort)" : ""), canSort: canSortBy, onSort: canSortBy ? handleSort : function () { } }, col), rest);
|
81
|
+
});
|
82
|
+
}, [columns, disableSortBy, handleSort, renderSortingSymbol, rest]);
|
83
|
+
var footers = useMemo(function () {
|
84
|
+
return columns.map(function (col) {
|
85
|
+
var Footer = col.Footer;
|
86
|
+
return __assign(__assign({ Cell: cloneElement(Footer || _jsx(_Fragment, {}), {
|
87
|
+
column: col,
|
88
|
+
rows: rows
|
89
|
+
}) }, col), rest);
|
90
|
+
});
|
91
|
+
}, [columns, rest, rows]);
|
92
|
+
return { headers: headers, footers: footers, columns: cols, rows: rows };
|
93
|
+
}
|
94
|
+
export default useTable;
|
package/README.md
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
- [Autocomplete](#autocomplete)
|
16
16
|
- [AutocompleteWithFilter](#autocompletewithfilter)
|
17
17
|
- [BasicModal](#basicmodal)
|
18
|
+
- [BasicTable](#basictable)
|
18
19
|
- [BreadCrumbs](#breadcrumbs)
|
19
20
|
- [CheckBox](#checkbox)
|
20
21
|
- [CheckBoxGroup](#checkboxgroup)
|
@@ -201,6 +202,61 @@ import BasicModal from '@symply.io/basic-components/BasicModal';
|
|
201
202
|
|
202
203
|
|
203
204
|
|
205
|
+
<h3>BasicTable</h3>
|
206
|
+
|
207
|
+
Reusable table component
|
208
|
+
|
209
|
+
<h5>Import</h5>
|
210
|
+
|
211
|
+
```tsx
|
212
|
+
import { BasicTable, useTable } from '@symply.io/basic-components';
|
213
|
+
// or
|
214
|
+
import BasicTable, { useTable } from '@symply.io/basic-components//BasicTable';
|
215
|
+
```
|
216
|
+
|
217
|
+
<h5>Column Props (IColumn)</h5>
|
218
|
+
|
219
|
+
| Name | Type | Default | Required | Description |
|
220
|
+
| ----------- | --------------------------- | ------- | -------- | ----------------------------------------------- |
|
221
|
+
| Body | ReactElement | | true | The component to render the column body cell. |
|
222
|
+
| Header | ReactElement | | true | The component to render the column header cell. |
|
223
|
+
| Footer | ReactElement | | false | The component to render the column footer cell. |
|
224
|
+
| accessor | string | | true | The key of the column, it should be unique. |
|
225
|
+
| align | "left" \|"center" \|"right" | | false | The alignment of the column. |
|
226
|
+
| canBeFrozen | bool | | false | If true, the column can be frozen |
|
227
|
+
| canSort | bool | | false | If true, the column can be sortable. |
|
228
|
+
|
229
|
+
<h5>Hook Props</h5>
|
230
|
+
|
231
|
+
| Name | Type | Default | Required | Description |
|
232
|
+
| ------------- | -------------------------- | ------- | -------- | ------------------------------------------- |
|
233
|
+
| columns | Array\<IColumn\> | | true | table columns |
|
234
|
+
| data | Array<{ [name]: unknown }> | | true | table data/rows |
|
235
|
+
| disableSortBy | bool | | false | If true, the whole table can't be sortable. |
|
236
|
+
| initialState | { sortBy?: SortByProps } | | false | Set the initial states |
|
237
|
+
| onSort | func | | false | The function for sorting rows. |
|
238
|
+
|
239
|
+
<h5>Hook Returns</h5>
|
240
|
+
|
241
|
+
| Name | Type | Description |
|
242
|
+
| ------- | -------------------- | ------------------------- |
|
243
|
+
| headers | Array\<IHeader\> | The cells for the header. |
|
244
|
+
| columns | Array\<IBodyColumn\> | The cells for the body. |
|
245
|
+
| footers | Array\<IFooter> | The cells for the footer. |
|
246
|
+
| rows | Array<IRow\> | The rows for the table. |
|
247
|
+
|
248
|
+
<h5>Component Props</h5>
|
249
|
+
|
250
|
+
| Name | Type | Default | Required | Description |
|
251
|
+
| ---------- | -------------------- | ---------- | -------- | ----------------------------------------- |
|
252
|
+
| headers | Array\<IHeader\> | | true | The cells for the header. (from the hook) |
|
253
|
+
| columns | Array\<IBodyColumn\> | | true | The cells for the body. (from the hook) |
|
254
|
+
| footers | Array\<IFooter> | [] | false | The cells for the footer. (from the hook) |
|
255
|
+
| noDataText | string | 'No Data!' | false | The text when no data rendered. |
|
256
|
+
| rows | Array<IRow\> | | true | The rows for the table. (from the hook) |
|
257
|
+
|
258
|
+
|
259
|
+
|
204
260
|
<h3>BreadCrumbs</h3>
|
205
261
|
|
206
262
|
A list of links that help a user visualize a page's location within the hierarchical structure of a website, and allow navigation up to any of its "ancestors".
|
@@ -213,7 +269,7 @@ import { BreadCrumbs } from '@symply.io/basic-components/';
|
|
213
269
|
import BreadCrumbs from '@symply.io/basic-components/BreadCrumbs';
|
214
270
|
```
|
215
271
|
|
216
|
-
<h5>Props</h5>
|
272
|
+
<h5>Props</h5>
|
217
273
|
|
218
274
|
| Name | Type | Default | Required | Description |
|
219
275
|
| ------ | --------------------------------------- | ------- | -------- | ------------------------- |
|
package/index.d.ts
CHANGED
@@ -2,6 +2,7 @@ export * from "./AlertDialog";
|
|
2
2
|
export * from "./Autocomplete";
|
3
3
|
export * from "./AutocompleteWithFilter";
|
4
4
|
export * from "./BasicModal";
|
5
|
+
export * from "./BasicTable";
|
5
6
|
export * from "./BreadCrumbs";
|
6
7
|
export * from "./CheckBox";
|
7
8
|
export * from "./Copyright";
|
@@ -28,6 +29,7 @@ export { default as AlertDialog } from "./AlertDialog";
|
|
28
29
|
export { default as Autocomplete } from "./Autocomplete";
|
29
30
|
export { default as AutocompleteWithFilter } from "./AutocompleteWithFilter";
|
30
31
|
export { default as BasicModal } from "./BasicModal";
|
32
|
+
export { default as BasicTable } from "./BasicTable";
|
31
33
|
export { default as BreadCrumbs } from "./BreadCrumbs";
|
32
34
|
export { default as Copyright } from "./Copyright";
|
33
35
|
export { default as DigitInput } from "./DigitInput";
|
package/index.js
CHANGED
@@ -2,6 +2,7 @@ export * from "./AlertDialog";
|
|
2
2
|
export * from "./Autocomplete";
|
3
3
|
export * from "./AutocompleteWithFilter";
|
4
4
|
export * from "./BasicModal";
|
5
|
+
export * from "./BasicTable";
|
5
6
|
export * from "./BreadCrumbs";
|
6
7
|
export * from "./CheckBox";
|
7
8
|
export * from "./Copyright";
|
@@ -28,6 +29,7 @@ export { default as AlertDialog } from "./AlertDialog";
|
|
28
29
|
export { default as Autocomplete } from "./Autocomplete";
|
29
30
|
export { default as AutocompleteWithFilter } from "./AutocompleteWithFilter";
|
30
31
|
export { default as BasicModal } from "./BasicModal";
|
32
|
+
export { default as BasicTable } from "./BasicTable";
|
31
33
|
export { default as BreadCrumbs } from "./BreadCrumbs";
|
32
34
|
export { default as Copyright } from "./Copyright";
|
33
35
|
export { default as DigitInput } from "./DigitInput";
|