next-recomponents 2.0.26 → 2.0.28
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/dist/index.d.mts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +137 -24
- package/dist/index.mjs +137 -24
- package/package.json +1 -1
- package/src/table/index.tsx +176 -22
package/dist/index.d.mts
CHANGED
|
@@ -66,13 +66,16 @@ type FooterAggregation = "sum" | "avg" | "count";
|
|
|
66
66
|
interface FooterType {
|
|
67
67
|
[key: string]: FooterAggregation;
|
|
68
68
|
}
|
|
69
|
+
type GridDensity = "compact" | "standard" | "comfortable";
|
|
69
70
|
interface TableProps {
|
|
70
71
|
data: any;
|
|
72
|
+
/** Muestra un input de búsqueda general que filtra filas por palabras clave */
|
|
73
|
+
searchable?: boolean;
|
|
71
74
|
flex?: number;
|
|
72
75
|
editableFields?: string[];
|
|
73
76
|
onSelect?: (data: GridValidRowModel[]) => void;
|
|
74
77
|
onSave?: (data: GridValidRowModel[]) => void;
|
|
75
|
-
onCloseModal?: (data: GridValidRowModel | undefined) => boolean
|
|
78
|
+
onCloseModal?: (data: GridValidRowModel | undefined) => boolean | Promise<boolean>;
|
|
76
79
|
buttons?: Record<string, any>;
|
|
77
80
|
exportName?: string;
|
|
78
81
|
modal?: React$1.ReactNode;
|
|
@@ -86,6 +89,28 @@ interface TableProps {
|
|
|
86
89
|
className?: string;
|
|
87
90
|
fontSize?: string;
|
|
88
91
|
colSize?: Record<string, number>;
|
|
92
|
+
/**
|
|
93
|
+
* Alto fijo de fila en px.
|
|
94
|
+
* Si se omite usa el default de MUI según `density`
|
|
95
|
+
* (compact ≈ 36, standard ≈ 52, comfortable ≈ 68).
|
|
96
|
+
* Se ignora automáticamente cuando `wrapText` es true.
|
|
97
|
+
*/
|
|
98
|
+
rowHeight?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Cuando es true el texto largo hace wrap en lugar de truncarse,
|
|
101
|
+
* y el alto de cada fila crece para mostrar todo el contenido.
|
|
102
|
+
* Internamente activa `getRowHeight={() => "auto"}` en el DataGrid.
|
|
103
|
+
*/
|
|
104
|
+
wrapText?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Densidad visual de la tabla.
|
|
107
|
+
* Afecta el padding de celdas y encabezados independientemente
|
|
108
|
+
* del tamaño de fuente.
|
|
109
|
+
* - "compact" → padding mínimo, tabla muy densa
|
|
110
|
+
* - "standard" → (default) comportamiento por defecto de MUI
|
|
111
|
+
* - "comfortable" → padding generoso, fácil de leer
|
|
112
|
+
*/
|
|
113
|
+
density?: GridDensity;
|
|
89
114
|
[key: string]: any;
|
|
90
115
|
}
|
|
91
116
|
declare function Table(props: TableProps): react_jsx_runtime.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -66,13 +66,16 @@ type FooterAggregation = "sum" | "avg" | "count";
|
|
|
66
66
|
interface FooterType {
|
|
67
67
|
[key: string]: FooterAggregation;
|
|
68
68
|
}
|
|
69
|
+
type GridDensity = "compact" | "standard" | "comfortable";
|
|
69
70
|
interface TableProps {
|
|
70
71
|
data: any;
|
|
72
|
+
/** Muestra un input de búsqueda general que filtra filas por palabras clave */
|
|
73
|
+
searchable?: boolean;
|
|
71
74
|
flex?: number;
|
|
72
75
|
editableFields?: string[];
|
|
73
76
|
onSelect?: (data: GridValidRowModel[]) => void;
|
|
74
77
|
onSave?: (data: GridValidRowModel[]) => void;
|
|
75
|
-
onCloseModal?: (data: GridValidRowModel | undefined) => boolean
|
|
78
|
+
onCloseModal?: (data: GridValidRowModel | undefined) => boolean | Promise<boolean>;
|
|
76
79
|
buttons?: Record<string, any>;
|
|
77
80
|
exportName?: string;
|
|
78
81
|
modal?: React$1.ReactNode;
|
|
@@ -86,6 +89,28 @@ interface TableProps {
|
|
|
86
89
|
className?: string;
|
|
87
90
|
fontSize?: string;
|
|
88
91
|
colSize?: Record<string, number>;
|
|
92
|
+
/**
|
|
93
|
+
* Alto fijo de fila en px.
|
|
94
|
+
* Si se omite usa el default de MUI según `density`
|
|
95
|
+
* (compact ≈ 36, standard ≈ 52, comfortable ≈ 68).
|
|
96
|
+
* Se ignora automáticamente cuando `wrapText` es true.
|
|
97
|
+
*/
|
|
98
|
+
rowHeight?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Cuando es true el texto largo hace wrap en lugar de truncarse,
|
|
101
|
+
* y el alto de cada fila crece para mostrar todo el contenido.
|
|
102
|
+
* Internamente activa `getRowHeight={() => "auto"}` en el DataGrid.
|
|
103
|
+
*/
|
|
104
|
+
wrapText?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Densidad visual de la tabla.
|
|
107
|
+
* Afecta el padding de celdas y encabezados independientemente
|
|
108
|
+
* del tamaño de fuente.
|
|
109
|
+
* - "compact" → padding mínimo, tabla muy densa
|
|
110
|
+
* - "standard" → (default) comportamiento por defecto de MUI
|
|
111
|
+
* - "comfortable" → padding generoso, fácil de leer
|
|
112
|
+
*/
|
|
113
|
+
density?: GridDensity;
|
|
89
114
|
[key: string]: any;
|
|
90
115
|
}
|
|
91
116
|
declare function Table(props: TableProps): react_jsx_runtime.JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -35828,6 +35828,7 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35828
35828
|
buttons,
|
|
35829
35829
|
hideColumns,
|
|
35830
35830
|
modal,
|
|
35831
|
+
wrapText,
|
|
35831
35832
|
handleRowUpdate,
|
|
35832
35833
|
onModalOpen
|
|
35833
35834
|
} = options;
|
|
@@ -35866,6 +35867,20 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35866
35867
|
width: key == "id" ? 80 : (_a = colSize == null ? void 0 : colSize[key]) != null ? _a : void 0,
|
|
35867
35868
|
editable: (_b = editableFields == null ? void 0 : editableFields.includes(key)) != null ? _b : false,
|
|
35868
35869
|
type: typeof rows[0][key] === "number" ? "number" : "string",
|
|
35870
|
+
// When wrapText is enabled, allow cells to grow vertically
|
|
35871
|
+
...wrapText && {
|
|
35872
|
+
renderHeader: (params) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35873
|
+
"span",
|
|
35874
|
+
{
|
|
35875
|
+
style: {
|
|
35876
|
+
whiteSpace: "normal",
|
|
35877
|
+
lineHeight: 1.3,
|
|
35878
|
+
wordBreak: "break-word"
|
|
35879
|
+
},
|
|
35880
|
+
children: params.colDef.headerName
|
|
35881
|
+
}
|
|
35882
|
+
)
|
|
35883
|
+
},
|
|
35869
35884
|
renderCell: (buttons == null ? void 0 : buttons[key]) ? (params) => {
|
|
35870
35885
|
var _a2, _b2, _c;
|
|
35871
35886
|
const children = ((_a2 = buttons == null ? void 0 : buttons[key]) == null ? void 0 : _a2.type) == "input" ? null : (_b2 = params == null ? void 0 : params.row) == null ? void 0 : _b2[key];
|
|
@@ -35882,6 +35897,24 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35882
35897
|
}
|
|
35883
35898
|
}
|
|
35884
35899
|
});
|
|
35900
|
+
} : wrapText ? (params) => {
|
|
35901
|
+
var _a2;
|
|
35902
|
+
return (
|
|
35903
|
+
// Plain cell with wrap — no custom button
|
|
35904
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35905
|
+
"span",
|
|
35906
|
+
{
|
|
35907
|
+
style: {
|
|
35908
|
+
whiteSpace: "normal",
|
|
35909
|
+
wordBreak: "break-word",
|
|
35910
|
+
lineHeight: 1.4,
|
|
35911
|
+
padding: "6px 0",
|
|
35912
|
+
display: "block"
|
|
35913
|
+
},
|
|
35914
|
+
children: (_a2 = params.formattedValue) != null ? _a2 : params.value
|
|
35915
|
+
}
|
|
35916
|
+
)
|
|
35917
|
+
);
|
|
35885
35918
|
} : null
|
|
35886
35919
|
};
|
|
35887
35920
|
});
|
|
@@ -35889,7 +35922,6 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35889
35922
|
cols.unshift({
|
|
35890
35923
|
field: "Modal",
|
|
35891
35924
|
headerName: "Modal",
|
|
35892
|
-
// flex,
|
|
35893
35925
|
editable: false,
|
|
35894
35926
|
type: "string",
|
|
35895
35927
|
width: 10,
|
|
@@ -35908,7 +35940,57 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35908
35940
|
});
|
|
35909
35941
|
}
|
|
35910
35942
|
return cols;
|
|
35911
|
-
}, [rows]);
|
|
35943
|
+
}, [rows, wrapText]);
|
|
35944
|
+
}
|
|
35945
|
+
function SearchBar({
|
|
35946
|
+
value,
|
|
35947
|
+
onChange
|
|
35948
|
+
}) {
|
|
35949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2 px-2 pb-1", children: [
|
|
35950
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35951
|
+
"svg",
|
|
35952
|
+
{
|
|
35953
|
+
className: "text-gray-400 shrink-0",
|
|
35954
|
+
width: "14",
|
|
35955
|
+
height: "14",
|
|
35956
|
+
viewBox: "0 0 20 20",
|
|
35957
|
+
fill: "currentColor",
|
|
35958
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35959
|
+
"path",
|
|
35960
|
+
{
|
|
35961
|
+
fillRule: "evenodd",
|
|
35962
|
+
d: "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
|
|
35963
|
+
clipRule: "evenodd"
|
|
35964
|
+
}
|
|
35965
|
+
)
|
|
35966
|
+
}
|
|
35967
|
+
),
|
|
35968
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35969
|
+
"input",
|
|
35970
|
+
{
|
|
35971
|
+
type: "text",
|
|
35972
|
+
value,
|
|
35973
|
+
onChange: (e) => onChange(e.target.value),
|
|
35974
|
+
placeholder: "Buscar\u2026",
|
|
35975
|
+
className: "w-full max-w-xs text-xs border border-gray-300 rounded px-2 py-1 outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-200 transition"
|
|
35976
|
+
}
|
|
35977
|
+
),
|
|
35978
|
+
value && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
35979
|
+
"button",
|
|
35980
|
+
{
|
|
35981
|
+
onClick: () => onChange(""),
|
|
35982
|
+
className: "text-gray-400 hover:text-gray-600 text-sm leading-none",
|
|
35983
|
+
title: "Limpiar b\xFAsqueda",
|
|
35984
|
+
children: "\xD7"
|
|
35985
|
+
}
|
|
35986
|
+
)
|
|
35987
|
+
] });
|
|
35988
|
+
}
|
|
35989
|
+
function rowMatchesSearch(row, query) {
|
|
35990
|
+
if (!query.trim()) return true;
|
|
35991
|
+
const words = query.trim().toLowerCase().split(/\s+/);
|
|
35992
|
+
const rowText = Object.values(row).filter((v) => v != null && v !== "").join(" ").toLowerCase();
|
|
35993
|
+
return words.every((word) => rowText.includes(word));
|
|
35912
35994
|
}
|
|
35913
35995
|
function IHTable({
|
|
35914
35996
|
data,
|
|
@@ -35928,7 +36010,11 @@ function IHTable({
|
|
|
35928
36010
|
currentCoin = "$",
|
|
35929
36011
|
fontSize = "1rem",
|
|
35930
36012
|
className,
|
|
35931
|
-
colSize
|
|
36013
|
+
colSize,
|
|
36014
|
+
rowHeight,
|
|
36015
|
+
wrapText = false,
|
|
36016
|
+
density = "standard",
|
|
36017
|
+
searchable = false
|
|
35932
36018
|
}) {
|
|
35933
36019
|
var _a;
|
|
35934
36020
|
if (modal && onSelect)
|
|
@@ -35940,6 +36026,7 @@ function IHTable({
|
|
|
35940
36026
|
ids: /* @__PURE__ */ new Set()
|
|
35941
36027
|
});
|
|
35942
36028
|
const [modalRow, setModalRow] = (0, import_react4.useState)();
|
|
36029
|
+
const [searchQuery, setSearchQuery] = (0, import_react4.useState)("");
|
|
35943
36030
|
const resolvedButtons = modal ? { ...buttons, Modal: "" } : buttons;
|
|
35944
36031
|
(0, import_react4.useEffect)(() => {
|
|
35945
36032
|
setRows(data);
|
|
@@ -35948,8 +36035,8 @@ function IHTable({
|
|
|
35948
36035
|
setModalRow(row);
|
|
35949
36036
|
setOpen(true);
|
|
35950
36037
|
};
|
|
35951
|
-
const handleClose = () => {
|
|
35952
|
-
const pass = onCloseModal ? onCloseModal == null ? void 0 : onCloseModal(modalRow) : true;
|
|
36038
|
+
const handleClose = async () => {
|
|
36039
|
+
const pass = onCloseModal ? await (onCloseModal == null ? void 0 : onCloseModal(modalRow)) : true;
|
|
35953
36040
|
if (!pass) return;
|
|
35954
36041
|
setOpen(false);
|
|
35955
36042
|
setModalRow(void 0);
|
|
@@ -35971,8 +36058,12 @@ function IHTable({
|
|
|
35971
36058
|
}
|
|
35972
36059
|
return [];
|
|
35973
36060
|
}, [selectedRows, rows]);
|
|
36061
|
+
const displayRows = (0, import_react4.useMemo)(
|
|
36062
|
+
() => searchable ? rows.filter((r) => rowMatchesSearch(r, searchQuery)) : rows,
|
|
36063
|
+
[rows, searchQuery, searchable]
|
|
36064
|
+
);
|
|
35974
36065
|
const columns = useColumns(
|
|
35975
|
-
|
|
36066
|
+
displayRows,
|
|
35976
36067
|
currentCoin,
|
|
35977
36068
|
{
|
|
35978
36069
|
flex,
|
|
@@ -35980,31 +36071,36 @@ function IHTable({
|
|
|
35980
36071
|
buttons: resolvedButtons,
|
|
35981
36072
|
hideColumns,
|
|
35982
36073
|
modal,
|
|
36074
|
+
wrapText,
|
|
35983
36075
|
handleRowUpdate,
|
|
35984
36076
|
onModalOpen: handleModalOpen
|
|
35985
36077
|
},
|
|
35986
36078
|
colSize
|
|
35987
36079
|
);
|
|
35988
36080
|
if (!rows.length) return null;
|
|
36081
|
+
const rowHeightProps = wrapText ? { getRowHeight: () => "auto" } : rowHeight != null ? { rowHeight } : {};
|
|
35989
36082
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "m-2", children: [
|
|
35990
36083
|
header && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "font-bold p-2 ", children: header }),
|
|
35991
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.
|
|
35992
|
-
|
|
35993
|
-
|
|
35994
|
-
|
|
35995
|
-
|
|
35996
|
-
|
|
35997
|
-
|
|
35998
|
-
|
|
35999
|
-
|
|
36000
|
-
|
|
36084
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex justify-between", children: [
|
|
36085
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
36086
|
+
Toolbar,
|
|
36087
|
+
{
|
|
36088
|
+
exportName,
|
|
36089
|
+
onSave,
|
|
36090
|
+
onSelect,
|
|
36091
|
+
rows,
|
|
36092
|
+
filteredRows
|
|
36093
|
+
}
|
|
36094
|
+
),
|
|
36095
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SearchBar, { value: searchQuery, onChange: setSearchQuery })
|
|
36096
|
+
] }),
|
|
36001
36097
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
36002
36098
|
import_material.Box,
|
|
36003
36099
|
{
|
|
36004
36100
|
sx: {
|
|
36005
36101
|
display: "flex",
|
|
36006
36102
|
flexDirection: "column",
|
|
36007
|
-
height: (_a = HEIGHT_MAP[
|
|
36103
|
+
height: (_a = HEIGHT_MAP[displayRows.length]) != null ? _a : height,
|
|
36008
36104
|
width,
|
|
36009
36105
|
zIndex: 999999999
|
|
36010
36106
|
},
|
|
@@ -36022,25 +36118,42 @@ function IHTable({
|
|
|
36022
36118
|
import_x_data_grid.DataGrid,
|
|
36023
36119
|
{
|
|
36024
36120
|
className,
|
|
36025
|
-
rows,
|
|
36121
|
+
rows: displayRows,
|
|
36026
36122
|
columns,
|
|
36123
|
+
density,
|
|
36027
36124
|
checkboxSelection: Boolean(onSelect),
|
|
36028
36125
|
rowSelectionModel: selectedRows,
|
|
36029
36126
|
onRowSelectionModelChange: !modal ? setSelectedRows : void 0,
|
|
36127
|
+
...rowHeightProps,
|
|
36030
36128
|
sx: {
|
|
36031
36129
|
fontSize,
|
|
36032
|
-
// equivalente a text-xs
|
|
36033
36130
|
"& .MuiDataGrid-cell": {
|
|
36034
|
-
fontSize
|
|
36131
|
+
fontSize,
|
|
36132
|
+
// Allow cells to wrap text when wrapText is enabled
|
|
36133
|
+
...wrapText && {
|
|
36134
|
+
alignItems: "flex-start",
|
|
36135
|
+
paddingTop: "8px",
|
|
36136
|
+
paddingBottom: "8px",
|
|
36137
|
+
whiteSpace: "normal",
|
|
36138
|
+
wordBreak: "break-word"
|
|
36139
|
+
}
|
|
36035
36140
|
},
|
|
36036
36141
|
"& .MuiDataGrid-columnHeader": {
|
|
36037
|
-
fontSize
|
|
36142
|
+
fontSize,
|
|
36143
|
+
...wrapText && {
|
|
36144
|
+
whiteSpace: "normal",
|
|
36145
|
+
"& .MuiDataGrid-columnHeaderTitle": {
|
|
36146
|
+
whiteSpace: "normal",
|
|
36147
|
+
lineHeight: 1.3,
|
|
36148
|
+
wordBreak: "break-word"
|
|
36149
|
+
}
|
|
36150
|
+
}
|
|
36038
36151
|
},
|
|
36039
36152
|
"& .MuiDataGrid-cell--editable": {
|
|
36040
36153
|
backgroundColor: "#c6d8f0",
|
|
36041
36154
|
fontWeight: 500
|
|
36042
36155
|
},
|
|
36043
|
-
...
|
|
36156
|
+
...displayRows.length <= Object.keys(HEIGHT_MAP).length && {
|
|
36044
36157
|
"& .MuiDataGrid-filler": {
|
|
36045
36158
|
display: "none"
|
|
36046
36159
|
}
|
|
@@ -36049,13 +36162,13 @@ function IHTable({
|
|
|
36049
36162
|
editMode: "row",
|
|
36050
36163
|
processRowUpdate: handleRowUpdate,
|
|
36051
36164
|
pageSizeOptions: [5, 10],
|
|
36052
|
-
hideFooter:
|
|
36165
|
+
hideFooter: displayRows.length <= Object.keys(HEIGHT_MAP).length
|
|
36053
36166
|
}
|
|
36054
36167
|
)
|
|
36055
36168
|
]
|
|
36056
36169
|
}
|
|
36057
36170
|
),
|
|
36058
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CustomFooter, { footer, rows })
|
|
36171
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CustomFooter, { footer, rows: displayRows })
|
|
36059
36172
|
] });
|
|
36060
36173
|
}
|
|
36061
36174
|
function Table(props) {
|
package/dist/index.mjs
CHANGED
|
@@ -35808,6 +35808,7 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35808
35808
|
buttons,
|
|
35809
35809
|
hideColumns,
|
|
35810
35810
|
modal,
|
|
35811
|
+
wrapText,
|
|
35811
35812
|
handleRowUpdate,
|
|
35812
35813
|
onModalOpen
|
|
35813
35814
|
} = options;
|
|
@@ -35846,6 +35847,20 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35846
35847
|
width: key == "id" ? 80 : (_a = colSize == null ? void 0 : colSize[key]) != null ? _a : void 0,
|
|
35847
35848
|
editable: (_b = editableFields == null ? void 0 : editableFields.includes(key)) != null ? _b : false,
|
|
35848
35849
|
type: typeof rows[0][key] === "number" ? "number" : "string",
|
|
35850
|
+
// When wrapText is enabled, allow cells to grow vertically
|
|
35851
|
+
...wrapText && {
|
|
35852
|
+
renderHeader: (params) => /* @__PURE__ */ jsx6(
|
|
35853
|
+
"span",
|
|
35854
|
+
{
|
|
35855
|
+
style: {
|
|
35856
|
+
whiteSpace: "normal",
|
|
35857
|
+
lineHeight: 1.3,
|
|
35858
|
+
wordBreak: "break-word"
|
|
35859
|
+
},
|
|
35860
|
+
children: params.colDef.headerName
|
|
35861
|
+
}
|
|
35862
|
+
)
|
|
35863
|
+
},
|
|
35849
35864
|
renderCell: (buttons == null ? void 0 : buttons[key]) ? (params) => {
|
|
35850
35865
|
var _a2, _b2, _c;
|
|
35851
35866
|
const children = ((_a2 = buttons == null ? void 0 : buttons[key]) == null ? void 0 : _a2.type) == "input" ? null : (_b2 = params == null ? void 0 : params.row) == null ? void 0 : _b2[key];
|
|
@@ -35862,6 +35877,24 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35862
35877
|
}
|
|
35863
35878
|
}
|
|
35864
35879
|
});
|
|
35880
|
+
} : wrapText ? (params) => {
|
|
35881
|
+
var _a2;
|
|
35882
|
+
return (
|
|
35883
|
+
// Plain cell with wrap — no custom button
|
|
35884
|
+
/* @__PURE__ */ jsx6(
|
|
35885
|
+
"span",
|
|
35886
|
+
{
|
|
35887
|
+
style: {
|
|
35888
|
+
whiteSpace: "normal",
|
|
35889
|
+
wordBreak: "break-word",
|
|
35890
|
+
lineHeight: 1.4,
|
|
35891
|
+
padding: "6px 0",
|
|
35892
|
+
display: "block"
|
|
35893
|
+
},
|
|
35894
|
+
children: (_a2 = params.formattedValue) != null ? _a2 : params.value
|
|
35895
|
+
}
|
|
35896
|
+
)
|
|
35897
|
+
);
|
|
35865
35898
|
} : null
|
|
35866
35899
|
};
|
|
35867
35900
|
});
|
|
@@ -35869,7 +35902,6 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35869
35902
|
cols.unshift({
|
|
35870
35903
|
field: "Modal",
|
|
35871
35904
|
headerName: "Modal",
|
|
35872
|
-
// flex,
|
|
35873
35905
|
editable: false,
|
|
35874
35906
|
type: "string",
|
|
35875
35907
|
width: 10,
|
|
@@ -35888,7 +35920,57 @@ function useColumns(rows, currentCoin, options, colSize) {
|
|
|
35888
35920
|
});
|
|
35889
35921
|
}
|
|
35890
35922
|
return cols;
|
|
35891
|
-
}, [rows]);
|
|
35923
|
+
}, [rows, wrapText]);
|
|
35924
|
+
}
|
|
35925
|
+
function SearchBar({
|
|
35926
|
+
value,
|
|
35927
|
+
onChange
|
|
35928
|
+
}) {
|
|
35929
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 px-2 pb-1", children: [
|
|
35930
|
+
/* @__PURE__ */ jsx6(
|
|
35931
|
+
"svg",
|
|
35932
|
+
{
|
|
35933
|
+
className: "text-gray-400 shrink-0",
|
|
35934
|
+
width: "14",
|
|
35935
|
+
height: "14",
|
|
35936
|
+
viewBox: "0 0 20 20",
|
|
35937
|
+
fill: "currentColor",
|
|
35938
|
+
children: /* @__PURE__ */ jsx6(
|
|
35939
|
+
"path",
|
|
35940
|
+
{
|
|
35941
|
+
fillRule: "evenodd",
|
|
35942
|
+
d: "M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",
|
|
35943
|
+
clipRule: "evenodd"
|
|
35944
|
+
}
|
|
35945
|
+
)
|
|
35946
|
+
}
|
|
35947
|
+
),
|
|
35948
|
+
/* @__PURE__ */ jsx6(
|
|
35949
|
+
"input",
|
|
35950
|
+
{
|
|
35951
|
+
type: "text",
|
|
35952
|
+
value,
|
|
35953
|
+
onChange: (e) => onChange(e.target.value),
|
|
35954
|
+
placeholder: "Buscar\u2026",
|
|
35955
|
+
className: "w-full max-w-xs text-xs border border-gray-300 rounded px-2 py-1 outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-200 transition"
|
|
35956
|
+
}
|
|
35957
|
+
),
|
|
35958
|
+
value && /* @__PURE__ */ jsx6(
|
|
35959
|
+
"button",
|
|
35960
|
+
{
|
|
35961
|
+
onClick: () => onChange(""),
|
|
35962
|
+
className: "text-gray-400 hover:text-gray-600 text-sm leading-none",
|
|
35963
|
+
title: "Limpiar b\xFAsqueda",
|
|
35964
|
+
children: "\xD7"
|
|
35965
|
+
}
|
|
35966
|
+
)
|
|
35967
|
+
] });
|
|
35968
|
+
}
|
|
35969
|
+
function rowMatchesSearch(row, query) {
|
|
35970
|
+
if (!query.trim()) return true;
|
|
35971
|
+
const words = query.trim().toLowerCase().split(/\s+/);
|
|
35972
|
+
const rowText = Object.values(row).filter((v) => v != null && v !== "").join(" ").toLowerCase();
|
|
35973
|
+
return words.every((word) => rowText.includes(word));
|
|
35892
35974
|
}
|
|
35893
35975
|
function IHTable({
|
|
35894
35976
|
data,
|
|
@@ -35908,7 +35990,11 @@ function IHTable({
|
|
|
35908
35990
|
currentCoin = "$",
|
|
35909
35991
|
fontSize = "1rem",
|
|
35910
35992
|
className,
|
|
35911
|
-
colSize
|
|
35993
|
+
colSize,
|
|
35994
|
+
rowHeight,
|
|
35995
|
+
wrapText = false,
|
|
35996
|
+
density = "standard",
|
|
35997
|
+
searchable = false
|
|
35912
35998
|
}) {
|
|
35913
35999
|
var _a;
|
|
35914
36000
|
if (modal && onSelect)
|
|
@@ -35920,6 +36006,7 @@ function IHTable({
|
|
|
35920
36006
|
ids: /* @__PURE__ */ new Set()
|
|
35921
36007
|
});
|
|
35922
36008
|
const [modalRow, setModalRow] = useState4();
|
|
36009
|
+
const [searchQuery, setSearchQuery] = useState4("");
|
|
35923
36010
|
const resolvedButtons = modal ? { ...buttons, Modal: "" } : buttons;
|
|
35924
36011
|
useEffect3(() => {
|
|
35925
36012
|
setRows(data);
|
|
@@ -35928,8 +36015,8 @@ function IHTable({
|
|
|
35928
36015
|
setModalRow(row);
|
|
35929
36016
|
setOpen(true);
|
|
35930
36017
|
};
|
|
35931
|
-
const handleClose = () => {
|
|
35932
|
-
const pass = onCloseModal ? onCloseModal == null ? void 0 : onCloseModal(modalRow) : true;
|
|
36018
|
+
const handleClose = async () => {
|
|
36019
|
+
const pass = onCloseModal ? await (onCloseModal == null ? void 0 : onCloseModal(modalRow)) : true;
|
|
35933
36020
|
if (!pass) return;
|
|
35934
36021
|
setOpen(false);
|
|
35935
36022
|
setModalRow(void 0);
|
|
@@ -35951,8 +36038,12 @@ function IHTable({
|
|
|
35951
36038
|
}
|
|
35952
36039
|
return [];
|
|
35953
36040
|
}, [selectedRows, rows]);
|
|
36041
|
+
const displayRows = useMemo(
|
|
36042
|
+
() => searchable ? rows.filter((r) => rowMatchesSearch(r, searchQuery)) : rows,
|
|
36043
|
+
[rows, searchQuery, searchable]
|
|
36044
|
+
);
|
|
35954
36045
|
const columns = useColumns(
|
|
35955
|
-
|
|
36046
|
+
displayRows,
|
|
35956
36047
|
currentCoin,
|
|
35957
36048
|
{
|
|
35958
36049
|
flex,
|
|
@@ -35960,31 +36051,36 @@ function IHTable({
|
|
|
35960
36051
|
buttons: resolvedButtons,
|
|
35961
36052
|
hideColumns,
|
|
35962
36053
|
modal,
|
|
36054
|
+
wrapText,
|
|
35963
36055
|
handleRowUpdate,
|
|
35964
36056
|
onModalOpen: handleModalOpen
|
|
35965
36057
|
},
|
|
35966
36058
|
colSize
|
|
35967
36059
|
);
|
|
35968
36060
|
if (!rows.length) return null;
|
|
36061
|
+
const rowHeightProps = wrapText ? { getRowHeight: () => "auto" } : rowHeight != null ? { rowHeight } : {};
|
|
35969
36062
|
return /* @__PURE__ */ jsxs5("div", { className: "m-2", children: [
|
|
35970
36063
|
header && /* @__PURE__ */ jsx6("div", { className: "font-bold p-2 ", children: header }),
|
|
35971
|
-
/* @__PURE__ */
|
|
35972
|
-
|
|
35973
|
-
|
|
35974
|
-
|
|
35975
|
-
|
|
35976
|
-
|
|
35977
|
-
|
|
35978
|
-
|
|
35979
|
-
|
|
35980
|
-
|
|
36064
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex justify-between", children: [
|
|
36065
|
+
/* @__PURE__ */ jsx6(
|
|
36066
|
+
Toolbar,
|
|
36067
|
+
{
|
|
36068
|
+
exportName,
|
|
36069
|
+
onSave,
|
|
36070
|
+
onSelect,
|
|
36071
|
+
rows,
|
|
36072
|
+
filteredRows
|
|
36073
|
+
}
|
|
36074
|
+
),
|
|
36075
|
+
searchable && /* @__PURE__ */ jsx6(SearchBar, { value: searchQuery, onChange: setSearchQuery })
|
|
36076
|
+
] }),
|
|
35981
36077
|
/* @__PURE__ */ jsxs5(
|
|
35982
36078
|
Box,
|
|
35983
36079
|
{
|
|
35984
36080
|
sx: {
|
|
35985
36081
|
display: "flex",
|
|
35986
36082
|
flexDirection: "column",
|
|
35987
|
-
height: (_a = HEIGHT_MAP[
|
|
36083
|
+
height: (_a = HEIGHT_MAP[displayRows.length]) != null ? _a : height,
|
|
35988
36084
|
width,
|
|
35989
36085
|
zIndex: 999999999
|
|
35990
36086
|
},
|
|
@@ -36002,25 +36098,42 @@ function IHTable({
|
|
|
36002
36098
|
DataGrid,
|
|
36003
36099
|
{
|
|
36004
36100
|
className,
|
|
36005
|
-
rows,
|
|
36101
|
+
rows: displayRows,
|
|
36006
36102
|
columns,
|
|
36103
|
+
density,
|
|
36007
36104
|
checkboxSelection: Boolean(onSelect),
|
|
36008
36105
|
rowSelectionModel: selectedRows,
|
|
36009
36106
|
onRowSelectionModelChange: !modal ? setSelectedRows : void 0,
|
|
36107
|
+
...rowHeightProps,
|
|
36010
36108
|
sx: {
|
|
36011
36109
|
fontSize,
|
|
36012
|
-
// equivalente a text-xs
|
|
36013
36110
|
"& .MuiDataGrid-cell": {
|
|
36014
|
-
fontSize
|
|
36111
|
+
fontSize,
|
|
36112
|
+
// Allow cells to wrap text when wrapText is enabled
|
|
36113
|
+
...wrapText && {
|
|
36114
|
+
alignItems: "flex-start",
|
|
36115
|
+
paddingTop: "8px",
|
|
36116
|
+
paddingBottom: "8px",
|
|
36117
|
+
whiteSpace: "normal",
|
|
36118
|
+
wordBreak: "break-word"
|
|
36119
|
+
}
|
|
36015
36120
|
},
|
|
36016
36121
|
"& .MuiDataGrid-columnHeader": {
|
|
36017
|
-
fontSize
|
|
36122
|
+
fontSize,
|
|
36123
|
+
...wrapText && {
|
|
36124
|
+
whiteSpace: "normal",
|
|
36125
|
+
"& .MuiDataGrid-columnHeaderTitle": {
|
|
36126
|
+
whiteSpace: "normal",
|
|
36127
|
+
lineHeight: 1.3,
|
|
36128
|
+
wordBreak: "break-word"
|
|
36129
|
+
}
|
|
36130
|
+
}
|
|
36018
36131
|
},
|
|
36019
36132
|
"& .MuiDataGrid-cell--editable": {
|
|
36020
36133
|
backgroundColor: "#c6d8f0",
|
|
36021
36134
|
fontWeight: 500
|
|
36022
36135
|
},
|
|
36023
|
-
...
|
|
36136
|
+
...displayRows.length <= Object.keys(HEIGHT_MAP).length && {
|
|
36024
36137
|
"& .MuiDataGrid-filler": {
|
|
36025
36138
|
display: "none"
|
|
36026
36139
|
}
|
|
@@ -36029,13 +36142,13 @@ function IHTable({
|
|
|
36029
36142
|
editMode: "row",
|
|
36030
36143
|
processRowUpdate: handleRowUpdate,
|
|
36031
36144
|
pageSizeOptions: [5, 10],
|
|
36032
|
-
hideFooter:
|
|
36145
|
+
hideFooter: displayRows.length <= Object.keys(HEIGHT_MAP).length
|
|
36033
36146
|
}
|
|
36034
36147
|
)
|
|
36035
36148
|
]
|
|
36036
36149
|
}
|
|
36037
36150
|
),
|
|
36038
|
-
/* @__PURE__ */ jsx6(CustomFooter, { footer, rows })
|
|
36151
|
+
/* @__PURE__ */ jsx6(CustomFooter, { footer, rows: displayRows })
|
|
36039
36152
|
] });
|
|
36040
36153
|
}
|
|
36041
36154
|
function Table(props) {
|
package/package.json
CHANGED
package/src/table/index.tsx
CHANGED
|
@@ -22,13 +22,19 @@ interface FooterType {
|
|
|
22
22
|
[key: string]: FooterAggregation;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
type GridDensity = "compact" | "standard" | "comfortable";
|
|
26
|
+
|
|
25
27
|
interface TableProps {
|
|
26
28
|
data: any;
|
|
29
|
+
/** Muestra un input de búsqueda general que filtra filas por palabras clave */
|
|
30
|
+
searchable?: boolean;
|
|
27
31
|
flex?: number;
|
|
28
32
|
editableFields?: string[];
|
|
29
33
|
onSelect?: (data: GridValidRowModel[]) => void;
|
|
30
34
|
onSave?: (data: GridValidRowModel[]) => void;
|
|
31
|
-
onCloseModal?: (
|
|
35
|
+
onCloseModal?: (
|
|
36
|
+
data: GridValidRowModel | undefined,
|
|
37
|
+
) => boolean | Promise<boolean>;
|
|
32
38
|
buttons?: Record<string, any>;
|
|
33
39
|
exportName?: string;
|
|
34
40
|
modal?: React.ReactNode;
|
|
@@ -42,6 +48,28 @@ interface TableProps {
|
|
|
42
48
|
className?: string;
|
|
43
49
|
fontSize?: string;
|
|
44
50
|
colSize?: Record<string, number>;
|
|
51
|
+
/**
|
|
52
|
+
* Alto fijo de fila en px.
|
|
53
|
+
* Si se omite usa el default de MUI según `density`
|
|
54
|
+
* (compact ≈ 36, standard ≈ 52, comfortable ≈ 68).
|
|
55
|
+
* Se ignora automáticamente cuando `wrapText` es true.
|
|
56
|
+
*/
|
|
57
|
+
rowHeight?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Cuando es true el texto largo hace wrap en lugar de truncarse,
|
|
60
|
+
* y el alto de cada fila crece para mostrar todo el contenido.
|
|
61
|
+
* Internamente activa `getRowHeight={() => "auto"}` en el DataGrid.
|
|
62
|
+
*/
|
|
63
|
+
wrapText?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Densidad visual de la tabla.
|
|
66
|
+
* Afecta el padding de celdas y encabezados independientemente
|
|
67
|
+
* del tamaño de fuente.
|
|
68
|
+
* - "compact" → padding mínimo, tabla muy densa
|
|
69
|
+
* - "standard" → (default) comportamiento por defecto de MUI
|
|
70
|
+
* - "comfortable" → padding generoso, fácil de leer
|
|
71
|
+
*/
|
|
72
|
+
density?: GridDensity;
|
|
45
73
|
[key: string]: any;
|
|
46
74
|
}
|
|
47
75
|
|
|
@@ -254,6 +282,7 @@ function useColumns(
|
|
|
254
282
|
buttons?: Record<string, any>;
|
|
255
283
|
hideColumns: string[];
|
|
256
284
|
modal?: React.ReactNode;
|
|
285
|
+
wrapText?: boolean;
|
|
257
286
|
handleRowUpdate: (row: GridRowModel) => GridRowModel;
|
|
258
287
|
onModalOpen: (row: GridValidRowModel) => void;
|
|
259
288
|
},
|
|
@@ -265,9 +294,11 @@ function useColumns(
|
|
|
265
294
|
buttons,
|
|
266
295
|
hideColumns,
|
|
267
296
|
modal,
|
|
297
|
+
wrapText,
|
|
268
298
|
handleRowUpdate,
|
|
269
299
|
onModalOpen,
|
|
270
300
|
} = options;
|
|
301
|
+
|
|
271
302
|
return useMemo(() => {
|
|
272
303
|
if (!rows.length) return [];
|
|
273
304
|
|
|
@@ -307,7 +338,6 @@ function useColumns(
|
|
|
307
338
|
|
|
308
339
|
if (isNumber) {
|
|
309
340
|
if (isNaN(value)) return value;
|
|
310
|
-
|
|
311
341
|
return value;
|
|
312
342
|
}
|
|
313
343
|
|
|
@@ -317,6 +347,20 @@ function useColumns(
|
|
|
317
347
|
width: key == "id" ? 80 : (colSize?.[key] ?? undefined),
|
|
318
348
|
editable: editableFields?.includes(key) ?? false,
|
|
319
349
|
type: typeof rows[0][key] === "number" ? "number" : "string",
|
|
350
|
+
// When wrapText is enabled, allow cells to grow vertically
|
|
351
|
+
...(wrapText && {
|
|
352
|
+
renderHeader: (params: any) => (
|
|
353
|
+
<span
|
|
354
|
+
style={{
|
|
355
|
+
whiteSpace: "normal",
|
|
356
|
+
lineHeight: 1.3,
|
|
357
|
+
wordBreak: "break-word",
|
|
358
|
+
}}
|
|
359
|
+
>
|
|
360
|
+
{params.colDef.headerName}
|
|
361
|
+
</span>
|
|
362
|
+
),
|
|
363
|
+
}),
|
|
320
364
|
renderCell: buttons?.[key]
|
|
321
365
|
? (params: any) => {
|
|
322
366
|
const children =
|
|
@@ -336,14 +380,28 @@ function useColumns(
|
|
|
336
380
|
},
|
|
337
381
|
});
|
|
338
382
|
}
|
|
339
|
-
:
|
|
383
|
+
: wrapText
|
|
384
|
+
? (params: any) => (
|
|
385
|
+
// Plain cell with wrap — no custom button
|
|
386
|
+
<span
|
|
387
|
+
style={{
|
|
388
|
+
whiteSpace: "normal",
|
|
389
|
+
wordBreak: "break-word",
|
|
390
|
+
lineHeight: 1.4,
|
|
391
|
+
padding: "6px 0",
|
|
392
|
+
display: "block",
|
|
393
|
+
}}
|
|
394
|
+
>
|
|
395
|
+
{params.formattedValue ?? params.value}
|
|
396
|
+
</span>
|
|
397
|
+
)
|
|
398
|
+
: null,
|
|
340
399
|
}));
|
|
341
400
|
|
|
342
401
|
if (modal) {
|
|
343
402
|
cols.unshift({
|
|
344
403
|
field: "Modal",
|
|
345
404
|
headerName: "Modal",
|
|
346
|
-
// flex,
|
|
347
405
|
editable: false,
|
|
348
406
|
type: "string",
|
|
349
407
|
width: 10,
|
|
@@ -361,10 +419,63 @@ function useColumns(
|
|
|
361
419
|
}
|
|
362
420
|
|
|
363
421
|
return cols;
|
|
364
|
-
}, [rows]);
|
|
422
|
+
}, [rows, wrapText]);
|
|
365
423
|
}
|
|
366
424
|
|
|
367
|
-
// ───
|
|
425
|
+
// ─── SearchBar ────────────────────────────────────────────────────────────────
|
|
426
|
+
|
|
427
|
+
function SearchBar({
|
|
428
|
+
value,
|
|
429
|
+
onChange,
|
|
430
|
+
}: {
|
|
431
|
+
value: string;
|
|
432
|
+
onChange: (v: string) => void;
|
|
433
|
+
}) {
|
|
434
|
+
return (
|
|
435
|
+
<div className="flex items-center gap-2 px-2 pb-1">
|
|
436
|
+
<svg
|
|
437
|
+
className="text-gray-400 shrink-0"
|
|
438
|
+
width="14"
|
|
439
|
+
height="14"
|
|
440
|
+
viewBox="0 0 20 20"
|
|
441
|
+
fill="currentColor"
|
|
442
|
+
>
|
|
443
|
+
<path
|
|
444
|
+
fillRule="evenodd"
|
|
445
|
+
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
|
|
446
|
+
clipRule="evenodd"
|
|
447
|
+
/>
|
|
448
|
+
</svg>
|
|
449
|
+
<input
|
|
450
|
+
type="text"
|
|
451
|
+
value={value}
|
|
452
|
+
onChange={(e) => onChange(e.target.value)}
|
|
453
|
+
placeholder="Buscar…"
|
|
454
|
+
className="w-full max-w-xs text-xs border border-gray-300 rounded px-2 py-1 outline-none focus:border-blue-400 focus:ring-1 focus:ring-blue-200 transition"
|
|
455
|
+
/>
|
|
456
|
+
{value && (
|
|
457
|
+
<button
|
|
458
|
+
onClick={() => onChange("")}
|
|
459
|
+
className="text-gray-400 hover:text-gray-600 text-sm leading-none"
|
|
460
|
+
title="Limpiar búsqueda"
|
|
461
|
+
>
|
|
462
|
+
×
|
|
463
|
+
</button>
|
|
464
|
+
)}
|
|
465
|
+
</div>
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/** Devuelve true si la fila contiene TODAS las palabras del query */
|
|
470
|
+
function rowMatchesSearch(row: GridValidRowModel, query: string): boolean {
|
|
471
|
+
if (!query.trim()) return true;
|
|
472
|
+
const words = query.trim().toLowerCase().split(/\s+/);
|
|
473
|
+
const rowText = Object.values(row)
|
|
474
|
+
.filter((v) => v != null && v !== "")
|
|
475
|
+
.join(" ")
|
|
476
|
+
.toLowerCase();
|
|
477
|
+
return words.every((word) => rowText.includes(word));
|
|
478
|
+
}
|
|
368
479
|
|
|
369
480
|
function IHTable({
|
|
370
481
|
data,
|
|
@@ -385,6 +496,10 @@ function IHTable({
|
|
|
385
496
|
fontSize = "1rem",
|
|
386
497
|
className,
|
|
387
498
|
colSize,
|
|
499
|
+
rowHeight,
|
|
500
|
+
wrapText = false,
|
|
501
|
+
density = "standard",
|
|
502
|
+
searchable = false,
|
|
388
503
|
}: TableProps) {
|
|
389
504
|
if (modal && onSelect)
|
|
390
505
|
throw new Error("Solo se puede usar modal o onSelect por separado");
|
|
@@ -396,6 +511,7 @@ function IHTable({
|
|
|
396
511
|
ids: new Set(),
|
|
397
512
|
});
|
|
398
513
|
const [modalRow, setModalRow] = useState<GridValidRowModel | undefined>();
|
|
514
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
399
515
|
|
|
400
516
|
// Inject Modal button key if modal is provided
|
|
401
517
|
const resolvedButtons = modal ? { ...buttons, Modal: "" } : buttons;
|
|
@@ -408,8 +524,8 @@ function IHTable({
|
|
|
408
524
|
setModalRow(row);
|
|
409
525
|
setOpen(true);
|
|
410
526
|
};
|
|
411
|
-
const handleClose = () => {
|
|
412
|
-
const pass = onCloseModal ? onCloseModal?.(modalRow) : true;
|
|
527
|
+
const handleClose = async () => {
|
|
528
|
+
const pass = onCloseModal ? await onCloseModal?.(modalRow) : true;
|
|
413
529
|
|
|
414
530
|
if (!pass) return;
|
|
415
531
|
setOpen(false);
|
|
@@ -435,8 +551,15 @@ function IHTable({
|
|
|
435
551
|
return [];
|
|
436
552
|
}, [selectedRows, rows]);
|
|
437
553
|
|
|
554
|
+
// Rows after applying the search filter (only when searchable is enabled)
|
|
555
|
+
const displayRows = useMemo(
|
|
556
|
+
() =>
|
|
557
|
+
searchable ? rows.filter((r) => rowMatchesSearch(r, searchQuery)) : rows,
|
|
558
|
+
[rows, searchQuery, searchable],
|
|
559
|
+
);
|
|
560
|
+
|
|
438
561
|
const columns = useColumns(
|
|
439
|
-
|
|
562
|
+
displayRows,
|
|
440
563
|
currentCoin,
|
|
441
564
|
{
|
|
442
565
|
flex,
|
|
@@ -444,6 +567,7 @@ function IHTable({
|
|
|
444
567
|
buttons: resolvedButtons,
|
|
445
568
|
hideColumns,
|
|
446
569
|
modal,
|
|
570
|
+
wrapText,
|
|
447
571
|
handleRowUpdate,
|
|
448
572
|
onModalOpen: handleModalOpen,
|
|
449
573
|
},
|
|
@@ -452,22 +576,34 @@ function IHTable({
|
|
|
452
576
|
|
|
453
577
|
if (!rows.length) return null;
|
|
454
578
|
|
|
579
|
+
// When wrapText is active we must use getRowHeight; rowHeight prop is ignored.
|
|
580
|
+
const rowHeightProps = wrapText
|
|
581
|
+
? { getRowHeight: () => "auto" as const }
|
|
582
|
+
: rowHeight != null
|
|
583
|
+
? { rowHeight }
|
|
584
|
+
: {};
|
|
585
|
+
|
|
455
586
|
return (
|
|
456
587
|
<div className="m-2">
|
|
457
588
|
{header && <div className="font-bold p-2 ">{header}</div>}
|
|
458
|
-
<
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
589
|
+
<div className="flex justify-between">
|
|
590
|
+
<Toolbar
|
|
591
|
+
exportName={exportName}
|
|
592
|
+
onSave={onSave}
|
|
593
|
+
onSelect={onSelect}
|
|
594
|
+
rows={rows}
|
|
595
|
+
filteredRows={filteredRows}
|
|
596
|
+
/>
|
|
597
|
+
{searchable && (
|
|
598
|
+
<SearchBar value={searchQuery} onChange={setSearchQuery} />
|
|
599
|
+
)}
|
|
600
|
+
</div>
|
|
465
601
|
|
|
466
602
|
<Box
|
|
467
603
|
sx={{
|
|
468
604
|
display: "flex",
|
|
469
605
|
flexDirection: "column",
|
|
470
|
-
height: HEIGHT_MAP[
|
|
606
|
+
height: HEIGHT_MAP[displayRows.length] ?? height,
|
|
471
607
|
width,
|
|
472
608
|
zIndex: 999999999,
|
|
473
609
|
}}
|
|
@@ -483,24 +619,42 @@ function IHTable({
|
|
|
483
619
|
|
|
484
620
|
<DataGrid
|
|
485
621
|
className={className}
|
|
486
|
-
rows={
|
|
622
|
+
rows={displayRows}
|
|
487
623
|
columns={columns as any}
|
|
624
|
+
density={density}
|
|
488
625
|
checkboxSelection={Boolean(onSelect)}
|
|
489
626
|
rowSelectionModel={selectedRows}
|
|
490
627
|
onRowSelectionModelChange={!modal ? setSelectedRows : undefined}
|
|
628
|
+
{...rowHeightProps}
|
|
491
629
|
sx={{
|
|
492
|
-
fontSize,
|
|
630
|
+
fontSize,
|
|
493
631
|
"& .MuiDataGrid-cell": {
|
|
494
632
|
fontSize,
|
|
633
|
+
// Allow cells to wrap text when wrapText is enabled
|
|
634
|
+
...(wrapText && {
|
|
635
|
+
alignItems: "flex-start",
|
|
636
|
+
paddingTop: "8px",
|
|
637
|
+
paddingBottom: "8px",
|
|
638
|
+
whiteSpace: "normal",
|
|
639
|
+
wordBreak: "break-word",
|
|
640
|
+
}),
|
|
495
641
|
},
|
|
496
642
|
"& .MuiDataGrid-columnHeader": {
|
|
497
643
|
fontSize,
|
|
644
|
+
...(wrapText && {
|
|
645
|
+
whiteSpace: "normal",
|
|
646
|
+
"& .MuiDataGrid-columnHeaderTitle": {
|
|
647
|
+
whiteSpace: "normal",
|
|
648
|
+
lineHeight: 1.3,
|
|
649
|
+
wordBreak: "break-word",
|
|
650
|
+
},
|
|
651
|
+
}),
|
|
498
652
|
},
|
|
499
653
|
"& .MuiDataGrid-cell--editable": {
|
|
500
654
|
backgroundColor: "#c6d8f0",
|
|
501
655
|
fontWeight: 500,
|
|
502
656
|
},
|
|
503
|
-
...(
|
|
657
|
+
...(displayRows.length <= Object.keys(HEIGHT_MAP).length && {
|
|
504
658
|
"& .MuiDataGrid-filler": {
|
|
505
659
|
display: "none",
|
|
506
660
|
},
|
|
@@ -509,10 +663,10 @@ function IHTable({
|
|
|
509
663
|
editMode="row"
|
|
510
664
|
processRowUpdate={handleRowUpdate}
|
|
511
665
|
pageSizeOptions={[5, 10]}
|
|
512
|
-
hideFooter={
|
|
666
|
+
hideFooter={displayRows.length <= Object.keys(HEIGHT_MAP).length}
|
|
513
667
|
/>
|
|
514
668
|
</Box>
|
|
515
|
-
<CustomFooter footer={footer} rows={
|
|
669
|
+
<CustomFooter footer={footer} rows={displayRows} />
|
|
516
670
|
</div>
|
|
517
671
|
);
|
|
518
672
|
}
|