@absreim/react-bootstrap-data-grid 1.1.0 → 1.1.2
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/FilterOptionsTable/DateFilterRow.jsx +8 -4
- package/FilterOptionsTable/NumberFilterRow.jsx +6 -4
- package/FilterOptionsTable/StringFilterRow.jsx +6 -4
- package/Grid.jsx +11 -100
- package/hooks/useAugmentedRows.d.ts +3 -0
- package/hooks/useAugmentedRows.js +12 -0
- package/hooks/useDisplayRows.d.ts +3 -0
- package/hooks/useDisplayRows.js +52 -0
- package/hooks/useFilter.d.ts +2 -2
- package/hooks/useFilter.js +7 -5
- package/hooks/useSortedRows.d.ts +3 -0
- package/hooks/useSortedRows.js +48 -0
- package/package.json +1 -1
- package/types.d.ts +11 -0
- package/component.d.ts +0 -8
- package/component.jsx +0 -72
|
@@ -35,14 +35,18 @@ var DateFilterRow = function (_a) {
|
|
|
35
35
|
var inputId = useMemo(function () { return nanoid(); }, []);
|
|
36
36
|
var startDateInputId = "$startDate-".concat(inputId);
|
|
37
37
|
var endDateInputId = "$endDate-".concat(inputId);
|
|
38
|
+
var checkboxLabel = "".concat(columnLabel, " Column Filter Toggle");
|
|
39
|
+
var opSelectLabel = "".concat(columnLabel, " Column Filter Operator Selection");
|
|
40
|
+
var startDateInputLabel = "".concat(columnLabel, " Column Filter Start Date");
|
|
41
|
+
var endDateInputLabel = "".concat(columnLabel, " Column Filter End Date");
|
|
38
42
|
return (<tr>
|
|
39
43
|
<td>
|
|
40
|
-
<input type="checkbox" checked={enabled}
|
|
44
|
+
<input name={checkboxLabel} aria-label={checkboxLabel} type="checkbox" checked={enabled} onChange={handleEnabledChange}/>
|
|
41
45
|
</td>
|
|
42
46
|
<td>{columnLabel}</td>
|
|
43
47
|
<td>{filterState.type === "date" ? "Date" : "Datetime"}</td>
|
|
44
48
|
<td>
|
|
45
|
-
<select disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
49
|
+
<select name={opSelectLabel} aria-label={opSelectLabel} disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
46
50
|
{dateFilterSchemes.map(function (scheme) { return (<option key={scheme} value={scheme}>
|
|
47
51
|
{dateFilterSchemeNames[scheme]}
|
|
48
52
|
</option>); })}
|
|
@@ -51,11 +55,11 @@ var DateFilterRow = function (_a) {
|
|
|
51
55
|
<td>
|
|
52
56
|
{scheme !== "endAt" && (<>
|
|
53
57
|
{scheme === "between" && (<label htmlFor={startDateInputId}>Start Date</label>)}
|
|
54
|
-
<input id={startDateInputId} className="form-control" type={inputType} required={enabled} disabled={!enabled} value={startDate} onChange={handleStartValueChange} aria-label=
|
|
58
|
+
<input id={startDateInputId} className="form-control" type={inputType} required={enabled} disabled={!enabled} value={startDate} onChange={handleStartValueChange} aria-label={startDateInputLabel}/>
|
|
55
59
|
</>)}
|
|
56
60
|
{scheme !== "startFrom" && (<>
|
|
57
61
|
{scheme === "between" && (<label htmlFor={endDateInputId}>End Date</label>)}
|
|
58
|
-
<input className="form-control" type={inputType} required={enabled} disabled={!enabled} value={endDate} onChange={handleEndValueChange} aria-label=
|
|
62
|
+
<input id={endDateInputId} className="form-control" type={inputType} required={enabled} disabled={!enabled} value={endDate} onChange={handleEndValueChange} aria-label={endDateInputLabel}/>
|
|
59
63
|
</>)}
|
|
60
64
|
</td>
|
|
61
65
|
</tr>);
|
|
@@ -25,22 +25,24 @@ var NumberFilterRow = function (_a) {
|
|
|
25
25
|
setFilterState(__assign(__assign({}, filterState), { inputValue: target.value }));
|
|
26
26
|
};
|
|
27
27
|
var enabled = filterState.enabled, scheme = filterState.scheme, inputValue = filterState.inputValue;
|
|
28
|
-
|
|
28
|
+
var checkboxLabel = "".concat(columnLabel, " Column Filter Toggle");
|
|
29
|
+
var opSelectLabel = "".concat(columnLabel, " Column Filter Operator Selection");
|
|
30
|
+
var valueInputLabel = "".concat(columnLabel, " Column Filter Value");
|
|
29
31
|
return (<tr>
|
|
30
32
|
<td>
|
|
31
|
-
<input type="checkbox" checked={enabled}
|
|
33
|
+
<input name={checkboxLabel} aria-label={checkboxLabel} type="checkbox" checked={enabled} onChange={handleEnabledChange}/>
|
|
32
34
|
</td>
|
|
33
35
|
<td>{columnLabel}</td>
|
|
34
36
|
<td>Number</td>
|
|
35
37
|
<td>
|
|
36
|
-
<select disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
38
|
+
<select name={opSelectLabel} aria-label={opSelectLabel} disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
37
39
|
{numberFilterSchemes.map(function (scheme) { return (<option key={scheme} value={scheme}>
|
|
38
40
|
{numberFilterSchemeNames[scheme]}
|
|
39
41
|
</option>); })}
|
|
40
42
|
</select>
|
|
41
43
|
</td>
|
|
42
44
|
<td>
|
|
43
|
-
<input className="form-control" type="number" required={enabled} disabled={!enabled} value={inputValue} onChange={handleNumInputValueChange}/>
|
|
45
|
+
<input name={valueInputLabel} aria-label={valueInputLabel} className="form-control" type="number" required={enabled} disabled={!enabled} value={inputValue} onChange={handleNumInputValueChange}/>
|
|
44
46
|
</td>
|
|
45
47
|
</tr>);
|
|
46
48
|
};
|
|
@@ -25,22 +25,24 @@ var StringFilterRow = function (_a) {
|
|
|
25
25
|
setFilterState(__assign(__assign({}, filterState), { searchString: target.value }));
|
|
26
26
|
};
|
|
27
27
|
var enabled = filterState.enabled, scheme = filterState.scheme, searchString = filterState.searchString;
|
|
28
|
-
|
|
28
|
+
var checkboxLabel = "".concat(columnLabel, " Column Filter Toggle");
|
|
29
|
+
var opSelectLabel = "".concat(columnLabel, " Column Filter Operator Selection");
|
|
30
|
+
var valueInputLabel = "".concat(columnLabel, " Column Filter Value");
|
|
29
31
|
return (<tr>
|
|
30
32
|
<td>
|
|
31
|
-
<input type="checkbox" checked={enabled}
|
|
33
|
+
<input name={checkboxLabel} aria-label={checkboxLabel} type="checkbox" checked={enabled} onChange={handleEnabledChange}/>
|
|
32
34
|
</td>
|
|
33
35
|
<td>{columnLabel}</td>
|
|
34
36
|
<td>String</td>
|
|
35
37
|
<td>
|
|
36
|
-
<select disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
38
|
+
<select name={opSelectLabel} aria-label={opSelectLabel} disabled={!enabled} className="form-select" value={scheme} onChange={handleOpChange}>
|
|
37
39
|
{stringFilterSchemes.map(function (scheme) { return (<option key={scheme} value={scheme}>
|
|
38
40
|
{stringFilterSchemeNames[scheme]}
|
|
39
41
|
</option>); })}
|
|
40
42
|
</select>
|
|
41
43
|
</td>
|
|
42
44
|
<td>
|
|
43
|
-
<input className="form-control" required={enabled} disabled={!enabled} value={searchString} onChange={handleSearchStringChange}/>
|
|
45
|
+
<input name={valueInputLabel} aria-label={valueInputLabel} className="form-control" required={enabled} disabled={!enabled} value={searchString} onChange={handleSearchStringChange}/>
|
|
44
46
|
</td>
|
|
45
47
|
</tr>);
|
|
46
48
|
};
|
package/Grid.jsx
CHANGED
|
@@ -7,55 +7,16 @@ import useFilter from "./hooks/useFilter";
|
|
|
7
7
|
import ToggleButton from "./ToggleButton";
|
|
8
8
|
import FilterOptionsTable from "./FilterOptionsTable/FilterOptionsTable";
|
|
9
9
|
import useFilterStateFromEditable from "./hooks/useFilterStateFromEditable";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
if (typeStr === "number") {
|
|
15
|
-
return function (a, b) { return a - b; };
|
|
16
|
-
}
|
|
17
|
-
return function (a, b) {
|
|
18
|
-
if (a < b) {
|
|
19
|
-
return -1;
|
|
20
|
-
}
|
|
21
|
-
if (a > b) {
|
|
22
|
-
return 1;
|
|
23
|
-
}
|
|
24
|
-
return 0;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
var getRowComparator = function (comparator, fieldName) {
|
|
28
|
-
return function (rowA, rowB) { return comparator(rowA[fieldName], rowB[fieldName]); };
|
|
29
|
-
};
|
|
10
|
+
import useAugmentedRows from "./hooks/useAugmentedRows";
|
|
11
|
+
import useSortedRows from "./hooks/useSortedRows";
|
|
12
|
+
import useDisplayRows from "./hooks/useDisplayRows";
|
|
30
13
|
var Grid = function (_a) {
|
|
31
14
|
var rows = _a.rows, cols = _a.cols, pagination = _a.pagination, sortModel = _a.sortModel, filterModel = _a.filterModel;
|
|
32
15
|
var editableFilterState = (filterModel === null || filterModel === void 0 ? void 0 : filterModel.tableFilterState) || null;
|
|
33
16
|
var filterState = useFilterStateFromEditable(cols, editableFilterState);
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
return filteredRows;
|
|
38
|
-
}
|
|
39
|
-
var sortFieldName = sortModel.sortColDef.name;
|
|
40
|
-
var sortOrder = sortModel.sortColDef.order;
|
|
41
|
-
var sortColIndex = cols.findIndex(function (_a) {
|
|
42
|
-
var name = _a.name;
|
|
43
|
-
return name === sortFieldName;
|
|
44
|
-
});
|
|
45
|
-
if (sortColIndex < 0) {
|
|
46
|
-
throw new Error("The sortModel for the grid specifies that the data should be sorted based on a column named ".concat(sortFieldName, ", but it was not found among the column definitions."));
|
|
47
|
-
}
|
|
48
|
-
var typeStr = cols[sortColIndex].type;
|
|
49
|
-
var ascComparator = getTypeComparator(typeStr);
|
|
50
|
-
var rowComparator = getRowComparator(ascComparator, sortFieldName);
|
|
51
|
-
if (sortOrder === "desc") {
|
|
52
|
-
var descComparator = function (a, b) {
|
|
53
|
-
return ascComparator(a, b) * -1;
|
|
54
|
-
};
|
|
55
|
-
rowComparator = getRowComparator(descComparator, sortFieldName);
|
|
56
|
-
}
|
|
57
|
-
return filteredRows.slice().sort(rowComparator);
|
|
58
|
-
}, [filteredRows, cols, sortModel]);
|
|
17
|
+
var augmentedRows = useAugmentedRows(rows);
|
|
18
|
+
var filteredRows = useFilter(augmentedRows, editableFilterState);
|
|
19
|
+
var sortedRows = useSortedRows(filteredRows, cols, sortModel);
|
|
59
20
|
var currentPageRows = useMemo(function () {
|
|
60
21
|
if (pagination === undefined) {
|
|
61
22
|
return sortedRows;
|
|
@@ -66,54 +27,7 @@ var Grid = function (_a) {
|
|
|
66
27
|
var upperIndex = lowerIndex + pageSize;
|
|
67
28
|
return sortedRows.slice(lowerIndex, upperIndex);
|
|
68
29
|
}, [sortedRows, pagination]);
|
|
69
|
-
var displayRows =
|
|
70
|
-
var nameToIndex = new Map();
|
|
71
|
-
cols.forEach(function (_a, index) {
|
|
72
|
-
var name = _a.name;
|
|
73
|
-
nameToIndex.set(name, index);
|
|
74
|
-
});
|
|
75
|
-
return currentPageRows.map(function (row, index) {
|
|
76
|
-
cols
|
|
77
|
-
.map(function (_a) {
|
|
78
|
-
var name = _a.name;
|
|
79
|
-
return name;
|
|
80
|
-
})
|
|
81
|
-
.forEach(function (name) {
|
|
82
|
-
if (!(name in row)) {
|
|
83
|
-
throw new Error("Column definition specifies a property named \"".concat(name, "\", but it was not found in the row data object at index ").concat(index, "."));
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
var displayRow = [];
|
|
87
|
-
Object.keys(row).forEach(function (name) {
|
|
88
|
-
if (!nameToIndex.has(name)) {
|
|
89
|
-
console.error("Warning: row data contains a property named \"".concat(name, "\", but it was not found among the column definitions."));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
var index = nameToIndex.get(name);
|
|
93
|
-
var formatter = cols[index].formatter;
|
|
94
|
-
var typeString = cols[index].type;
|
|
95
|
-
var value = row[name];
|
|
96
|
-
if (formatter) {
|
|
97
|
-
displayRow[index] = formatter(value);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (typeString === "date") {
|
|
101
|
-
displayRow[index] = value.toDateString();
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
if (typeString === "datetime") {
|
|
105
|
-
displayRow[index] = value.toLocaleString();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
if (typeString === "number") {
|
|
109
|
-
displayRow[index] = value.toLocaleString();
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
displayRow[index] = value;
|
|
113
|
-
});
|
|
114
|
-
return displayRow;
|
|
115
|
-
});
|
|
116
|
-
}, [currentPageRows, cols]);
|
|
30
|
+
var displayRows = useDisplayRows(currentPageRows, cols);
|
|
117
31
|
var _b = useState(false), filterOptionsVisible = _b[0], setFilterOptionsVisible = _b[1];
|
|
118
32
|
var handleSetPageNum = function (pageNum) {
|
|
119
33
|
if (pagination === undefined) {
|
|
@@ -132,16 +46,13 @@ var Grid = function (_a) {
|
|
|
132
46
|
};
|
|
133
47
|
// Once this component implements selection state, and if such interactivity is enabled, (conditionally) change the
|
|
134
48
|
// aria role to "grid".
|
|
135
|
-
//
|
|
136
|
-
// sorting or pagination, is implemented.
|
|
137
|
-
// TODO: implement the above described features: conditionally changing aria role to grid and a key field other than
|
|
138
|
-
// index
|
|
49
|
+
// TODO: implement the above described features: conditionally changing aria role to grid
|
|
139
50
|
return (<div>
|
|
140
51
|
{filterState && filterModel && (<div>
|
|
141
52
|
<ToggleButton isActive={filterOptionsVisible} label={"".concat(filterOptionsVisible ? "Hide" : "Show ", " Filter Options")} onClick={handleToggleFilterOptions}/>
|
|
142
53
|
{filterOptionsVisible && (<FilterOptionsTable filterState={filterState} setFilterState={filterModel.setTableFilterState}/>)}
|
|
143
54
|
</div>)}
|
|
144
|
-
<table className="table">
|
|
55
|
+
<table className="table" aria-rowcount={filteredRows.length + 1}>
|
|
145
56
|
<thead>
|
|
146
57
|
<tr aria-rowindex={1}>
|
|
147
58
|
{cols.map(function (_a, index) {
|
|
@@ -162,8 +73,8 @@ var Grid = function (_a) {
|
|
|
162
73
|
</tr>
|
|
163
74
|
</thead>
|
|
164
75
|
<tbody>
|
|
165
|
-
{displayRows.map(function (row, index) { return (<tr key={
|
|
166
|
-
{row.map(function (value, index) { return (<td key={index} aria-colindex={index + 1}>
|
|
76
|
+
{displayRows.map(function (row, index) { return (<tr key={row.origIndex} aria-rowindex={index + 2}>
|
|
77
|
+
{row.contents.map(function (value, index) { return (<td key={index} aria-colindex={index + 1}>
|
|
167
78
|
{value}
|
|
168
79
|
</td>); })}
|
|
169
80
|
</tr>); })}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
var useAugmentedRows = function (rows) {
|
|
3
|
+
return useMemo(function () {
|
|
4
|
+
return rows.map(function (row, index) { return ({
|
|
5
|
+
data: row,
|
|
6
|
+
meta: {
|
|
7
|
+
origIndex: index,
|
|
8
|
+
},
|
|
9
|
+
}); });
|
|
10
|
+
}, [rows]);
|
|
11
|
+
};
|
|
12
|
+
export default useAugmentedRows;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
var useDisplayRows = function (currentPageRows, cols) {
|
|
3
|
+
return useMemo(function () {
|
|
4
|
+
var nameToIndex = new Map();
|
|
5
|
+
cols.forEach(function (_a, index) {
|
|
6
|
+
var name = _a.name;
|
|
7
|
+
nameToIndex.set(name, index);
|
|
8
|
+
});
|
|
9
|
+
return currentPageRows.map(function (row, index) {
|
|
10
|
+
cols
|
|
11
|
+
.map(function (_a) {
|
|
12
|
+
var name = _a.name;
|
|
13
|
+
return name;
|
|
14
|
+
})
|
|
15
|
+
.forEach(function (name) {
|
|
16
|
+
if (!(name in row.data)) {
|
|
17
|
+
throw new Error("Column definition specifies a property named \"".concat(name, "\", but it was not found in the row data object at index ").concat(index, "."));
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
var displayRow = [];
|
|
21
|
+
Object.keys(row.data).forEach(function (name) {
|
|
22
|
+
if (!nameToIndex.has(name)) {
|
|
23
|
+
console.error("Warning: row data contains a property named \"".concat(name, "\", but it was not found among the column definitions."));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
var index = nameToIndex.get(name);
|
|
27
|
+
var formatter = cols[index].formatter;
|
|
28
|
+
var typeString = cols[index].type;
|
|
29
|
+
var value = row.data[name];
|
|
30
|
+
if (formatter) {
|
|
31
|
+
displayRow[index] = formatter(value);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (typeString === "date") {
|
|
35
|
+
displayRow[index] = value.toDateString();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (typeString === "datetime") {
|
|
39
|
+
displayRow[index] = value.toLocaleString();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (typeString === "number") {
|
|
43
|
+
displayRow[index] = value.toLocaleString();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
displayRow[index] = value;
|
|
47
|
+
});
|
|
48
|
+
return { contents: displayRow, origIndex: row.meta.origIndex };
|
|
49
|
+
});
|
|
50
|
+
}, [currentPageRows, cols]);
|
|
51
|
+
};
|
|
52
|
+
export default useDisplayRows;
|
package/hooks/useFilter.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const useFilter: (rows:
|
|
1
|
+
import { AugRowDef, EditableTableFilterState } from "../types";
|
|
2
|
+
declare const useFilter: (rows: AugRowDef[], filterState: EditableTableFilterState | null) => AugRowDef[];
|
|
3
3
|
export default useFilter;
|
package/hooks/useFilter.js
CHANGED
|
@@ -19,7 +19,9 @@ var useFilter = function (rows, filterState) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
function checkIfPassesNumberFilter(value, state) {
|
|
22
|
-
|
|
22
|
+
// Note that a blank string becomes 0. This situation should usually be
|
|
23
|
+
// prevented by form validation.
|
|
24
|
+
var numValue = Number(state.numValue);
|
|
23
25
|
switch (state.scheme) {
|
|
24
26
|
case "equals":
|
|
25
27
|
return value === numValue;
|
|
@@ -45,7 +47,7 @@ var useFilter = function (rows, filterState) {
|
|
|
45
47
|
(value >= state.startDate && value <= state.endDate));
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
|
-
var columnNames = Object.keys(row);
|
|
50
|
+
var columnNames = Object.keys(row.data);
|
|
49
51
|
for (var _i = 0, columnNames_1 = columnNames; _i < columnNames_1.length; _i++) {
|
|
50
52
|
var columnName = columnNames_1[_i];
|
|
51
53
|
if (!(columnName in filterState)) {
|
|
@@ -57,19 +59,19 @@ var useFilter = function (rows, filterState) {
|
|
|
57
59
|
var columnFilterState = filterState[columnName];
|
|
58
60
|
switch (columnFilterState.type) {
|
|
59
61
|
case "string": {
|
|
60
|
-
if (!checkIfPassesStringFilter(row[columnName], columnFilterState)) {
|
|
62
|
+
if (!checkIfPassesStringFilter(row.data[columnName], columnFilterState)) {
|
|
61
63
|
return false;
|
|
62
64
|
}
|
|
63
65
|
break;
|
|
64
66
|
}
|
|
65
67
|
case "number": {
|
|
66
|
-
if (!checkIfPassesNumberFilter(row[columnName], columnFilterState)) {
|
|
68
|
+
if (!checkIfPassesNumberFilter(row.data[columnName], columnFilterState)) {
|
|
67
69
|
return false;
|
|
68
70
|
}
|
|
69
71
|
break;
|
|
70
72
|
}
|
|
71
73
|
default: {
|
|
72
|
-
if (!checkIfPassesDateFilter(row[columnName], columnFilterState)) {
|
|
74
|
+
if (!checkIfPassesDateFilter(row.data[columnName], columnFilterState)) {
|
|
73
75
|
return false;
|
|
74
76
|
}
|
|
75
77
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
var getTypeComparator = function (typeStr) {
|
|
3
|
+
if (typeStr === "date" || typeStr === "datetime") {
|
|
4
|
+
return function (a, b) { return a.valueOf() - b.valueOf(); };
|
|
5
|
+
}
|
|
6
|
+
if (typeStr === "number") {
|
|
7
|
+
return function (a, b) { return a - b; };
|
|
8
|
+
}
|
|
9
|
+
return function (a, b) {
|
|
10
|
+
if (a < b) {
|
|
11
|
+
return -1;
|
|
12
|
+
}
|
|
13
|
+
if (a > b) {
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
var getRowComparator = function (comparator, fieldName) {
|
|
20
|
+
return function (rowA, rowB) { return comparator(rowA.data[fieldName], rowB.data[fieldName]); };
|
|
21
|
+
};
|
|
22
|
+
var useSortedRows = function (rows, cols, sortModel) {
|
|
23
|
+
return useMemo(function () {
|
|
24
|
+
if (!sortModel || !sortModel.sortColDef) {
|
|
25
|
+
return rows;
|
|
26
|
+
}
|
|
27
|
+
var sortFieldName = sortModel.sortColDef.name;
|
|
28
|
+
var sortOrder = sortModel.sortColDef.order;
|
|
29
|
+
var sortColIndex = cols.findIndex(function (_a) {
|
|
30
|
+
var name = _a.name;
|
|
31
|
+
return name === sortFieldName;
|
|
32
|
+
});
|
|
33
|
+
if (sortColIndex < 0) {
|
|
34
|
+
throw new Error("The sortModel for the grid specifies that the data should be sorted based on a column named ".concat(sortFieldName, ", but it was not found among the column definitions."));
|
|
35
|
+
}
|
|
36
|
+
var typeStr = cols[sortColIndex].type;
|
|
37
|
+
var ascComparator = getTypeComparator(typeStr);
|
|
38
|
+
var rowComparator = getRowComparator(ascComparator, sortFieldName);
|
|
39
|
+
if (sortOrder === "desc") {
|
|
40
|
+
var descComparator = function (a, b) {
|
|
41
|
+
return ascComparator(a, b) * -1;
|
|
42
|
+
};
|
|
43
|
+
rowComparator = getRowComparator(descComparator, sortFieldName);
|
|
44
|
+
}
|
|
45
|
+
return rows.slice().sort(rowComparator);
|
|
46
|
+
}, [rows, cols, sortModel]);
|
|
47
|
+
};
|
|
48
|
+
export default useSortedRows;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absreim/react-bootstrap-data-grid",
|
|
3
3
|
"description": "Data grid UI component for use with web apps using React and Bootstrap",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Brook Li",
|
|
7
7
|
"homepage": "https://react-bootstrap-data-grid.vercel.app/",
|
package/types.d.ts
CHANGED
|
@@ -8,6 +8,17 @@ export interface ColDef {
|
|
|
8
8
|
sortable?: boolean;
|
|
9
9
|
}
|
|
10
10
|
export type RowDef = Record<string, ColDataType>;
|
|
11
|
+
export interface RowMetadata {
|
|
12
|
+
origIndex: number;
|
|
13
|
+
}
|
|
14
|
+
export interface AugRowDef {
|
|
15
|
+
data: RowDef;
|
|
16
|
+
meta: RowMetadata;
|
|
17
|
+
}
|
|
18
|
+
export interface FormattedRow {
|
|
19
|
+
contents: string[];
|
|
20
|
+
origIndex: number;
|
|
21
|
+
}
|
|
11
22
|
export type JustifyContentSetting = "start" | "end" | "center" | "between" | "around" | "evenly";
|
|
12
23
|
export type Size = "small" | "medium" | "large";
|
|
13
24
|
export type SortOrder = "asc" | "desc";
|
package/component.d.ts
DELETED
package/component.jsx
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
var Grid = function (_a) {
|
|
4
|
-
var rows = _a.rows, cols = _a.cols;
|
|
5
|
-
var displayRows = useMemo(function () {
|
|
6
|
-
var nameToIndex = new Map();
|
|
7
|
-
cols.forEach(function (_a, index) {
|
|
8
|
-
var name = _a.name;
|
|
9
|
-
nameToIndex.set(name, index);
|
|
10
|
-
});
|
|
11
|
-
return rows.map(function (row, index) {
|
|
12
|
-
cols
|
|
13
|
-
.map(function (_a) {
|
|
14
|
-
var name = _a.name;
|
|
15
|
-
return name;
|
|
16
|
-
})
|
|
17
|
-
.forEach(function (name) {
|
|
18
|
-
if (!(name in row)) {
|
|
19
|
-
throw new Error("Column definition specifies a property named \"".concat(name, "\",\n but it was no found in the row data object at index ").concat(index));
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
var displayRow = [];
|
|
23
|
-
Object.keys(row).forEach(function (name) {
|
|
24
|
-
if (!nameToIndex.has(name)) {
|
|
25
|
-
throw new Error("Row data contains a property named \"".concat(name, "\",\n but it was not found among the column definitions"));
|
|
26
|
-
}
|
|
27
|
-
var index = nameToIndex.get(name);
|
|
28
|
-
var formatter = cols[index].formatter;
|
|
29
|
-
var typeString = cols[index].type;
|
|
30
|
-
var value = row[name];
|
|
31
|
-
if (formatter) {
|
|
32
|
-
displayRow[index] = formatter(value);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
if (typeString === "date") {
|
|
36
|
-
displayRow[index] = value.toDateString();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (typeString === "datetime") {
|
|
40
|
-
displayRow[index] = value.toLocaleString();
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (typeString === "number") {
|
|
44
|
-
displayRow[index] = value.toLocaleString();
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
displayRow[index] = value;
|
|
48
|
-
});
|
|
49
|
-
return displayRow;
|
|
50
|
-
});
|
|
51
|
-
}, [rows, cols]);
|
|
52
|
-
// Once this component implements selection state, and if such interactivity is enabled, (conditionally) change the
|
|
53
|
-
// aria role to "grid".
|
|
54
|
-
// Array index is okay for the key for rows until some type of feature involving changing the index of rows, such as
|
|
55
|
-
// sorting or pagination, is implemented.
|
|
56
|
-
return (<table className="table">
|
|
57
|
-
<thead>
|
|
58
|
-
<tr>
|
|
59
|
-
{cols.map(function (_a) {
|
|
60
|
-
var name = _a.name, label = _a.label;
|
|
61
|
-
return (<th key={name}>{label}</th>);
|
|
62
|
-
})}
|
|
63
|
-
</tr>
|
|
64
|
-
</thead>
|
|
65
|
-
<tbody>
|
|
66
|
-
{displayRows.map(function (row, index) { return (<tr key={index}>
|
|
67
|
-
{row.map(function (value, index) { return (<td key={index}>{value}</td>); })}
|
|
68
|
-
</tr>); })}
|
|
69
|
-
</tbody>
|
|
70
|
-
</table>);
|
|
71
|
-
};
|
|
72
|
-
export default Grid;
|