@absreim/react-bootstrap-data-grid 0.1.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ColHeaderCell.d.ts +9 -0
- package/ColHeaderCell.jsx +92 -0
- package/Grid.d.ts +2 -1
- package/Grid.jsx +71 -12
- package/package.json +5 -5
- package/types.d.ts +14 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
3
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
4
|
+
if (ar || !(i in from)) {
|
|
5
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
6
|
+
ar[i] = from[i];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
10
|
+
};
|
|
11
|
+
import { useState } from "react";
|
|
12
|
+
import classNames from "classnames";
|
|
13
|
+
var getUpArrow = function (grayed) { return (<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className={classNames(__spreadArray([
|
|
14
|
+
"bi",
|
|
15
|
+
"bi-arrow-up"
|
|
16
|
+
], (grayed ? ["text-body-secondary"] : []), true))} viewBox="0 0 16 16">
|
|
17
|
+
{!grayed && (<>
|
|
18
|
+
<title>(sorted ascending)</title>
|
|
19
|
+
<desc>
|
|
20
|
+
Up arrow indicating that the column is being sorted in an ascending
|
|
21
|
+
manner
|
|
22
|
+
</desc>
|
|
23
|
+
</>)}
|
|
24
|
+
<path fillRule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5"/>
|
|
25
|
+
</svg>); };
|
|
26
|
+
var downArrow = (<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-down" viewBox="0 0 16 16">
|
|
27
|
+
<title>(sorted descending)</title>
|
|
28
|
+
<desc>
|
|
29
|
+
Down arrow indicating that the column is being sorted in an descending
|
|
30
|
+
manner
|
|
31
|
+
</desc>
|
|
32
|
+
<path fillRule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1"/>
|
|
33
|
+
</svg>);
|
|
34
|
+
// Temporary solution to prevent column widths from changing when hovering over
|
|
35
|
+
// columns with a mouse.
|
|
36
|
+
// More ideal permanent solution would be to fix column widths based on preset
|
|
37
|
+
// values.
|
|
38
|
+
var placeholder = (<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-down" viewBox="0 0 16 16"></svg>);
|
|
39
|
+
var ColHeaderCell = function (_a) {
|
|
40
|
+
var label = _a.label, sortModel = _a.sortModel, ariaColIndex = _a.ariaColIndex;
|
|
41
|
+
var _b = useState(false), isHovering = _b[0], setIsHovering = _b[1];
|
|
42
|
+
var handleMouseOver = function () {
|
|
43
|
+
return setIsHovering(true);
|
|
44
|
+
};
|
|
45
|
+
var handleMouseOut = function () {
|
|
46
|
+
return setIsHovering(false);
|
|
47
|
+
};
|
|
48
|
+
var handleClick = function () {
|
|
49
|
+
if (!sortModel) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
switch (sortModel.sortOrder) {
|
|
53
|
+
case null: {
|
|
54
|
+
sortModel.setSortOrder("asc");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
case "asc": {
|
|
58
|
+
sortModel.setSortOrder("desc");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
case "desc": {
|
|
62
|
+
sortModel.setSortOrder(null);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var getSortSymbol = function () {
|
|
67
|
+
if (!sortModel) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
switch (sortModel.sortOrder) {
|
|
71
|
+
case null: {
|
|
72
|
+
if (isHovering) {
|
|
73
|
+
return getUpArrow(true);
|
|
74
|
+
}
|
|
75
|
+
return placeholder;
|
|
76
|
+
}
|
|
77
|
+
case "asc": {
|
|
78
|
+
return getUpArrow(false);
|
|
79
|
+
}
|
|
80
|
+
case "desc": {
|
|
81
|
+
return downArrow;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return (<th onClick={sortModel && handleClick} onMouseOver={handleMouseOver} onMouseOut={handleMouseOut} aria-description={sortModel
|
|
86
|
+
? "Column header"
|
|
87
|
+
: "Column header that can be clicked to change the sorting mode"} style={{ cursor: sortModel ? "pointer" : "default" }} aria-colindex={ariaColIndex}>
|
|
88
|
+
{label}
|
|
89
|
+
{getSortSymbol()}
|
|
90
|
+
</th>);
|
|
91
|
+
};
|
|
92
|
+
export default ColHeaderCell;
|
package/Grid.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC } from "react";
|
|
2
|
-
import { ColDef, RowDef, Size } from "./types";
|
|
2
|
+
import { ColDef, RowDef, Size, TableSortModel } from "./types";
|
|
3
3
|
export interface GridPaginationState {
|
|
4
4
|
pageSizeOptions: number[];
|
|
5
5
|
pageSizeIndex: number;
|
|
@@ -13,6 +13,7 @@ export interface GridProps {
|
|
|
13
13
|
rows: RowDef[];
|
|
14
14
|
cols: ColDef[];
|
|
15
15
|
pagination?: GridPaginationState;
|
|
16
|
+
sortModel?: TableSortModel;
|
|
16
17
|
}
|
|
17
18
|
declare const Grid: FC<GridProps>;
|
|
18
19
|
export default Grid;
|
package/Grid.jsx
CHANGED
|
@@ -2,18 +2,63 @@
|
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import Pagination from "./Pagination";
|
|
4
4
|
import classNames from "classnames";
|
|
5
|
+
import ColHeaderCell from "./ColHeaderCell";
|
|
6
|
+
var getTypeComparator = function (typeStr) {
|
|
7
|
+
if (typeStr === "date" || typeStr === "datetime") {
|
|
8
|
+
return function (a, b) { return a.valueOf() - b.valueOf(); };
|
|
9
|
+
}
|
|
10
|
+
if (typeStr === "number") {
|
|
11
|
+
return function (a, b) { return a - b; };
|
|
12
|
+
}
|
|
13
|
+
return function (a, b) {
|
|
14
|
+
if (a < b) {
|
|
15
|
+
return -1;
|
|
16
|
+
}
|
|
17
|
+
if (a > b) {
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
return 0;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
var getRowComparator = function (comparator, fieldName) {
|
|
24
|
+
return function (rowA, rowB) { return comparator(rowA[fieldName], rowB[fieldName]); };
|
|
25
|
+
};
|
|
5
26
|
var Grid = function (_a) {
|
|
6
|
-
var rows = _a.rows, cols = _a.cols, pagination = _a.pagination;
|
|
27
|
+
var rows = _a.rows, cols = _a.cols, pagination = _a.pagination, sortModel = _a.sortModel;
|
|
28
|
+
var sortedRows = useMemo(function () {
|
|
29
|
+
if (!sortModel || !sortModel.sortColDef) {
|
|
30
|
+
return rows;
|
|
31
|
+
}
|
|
32
|
+
var sortFieldName = sortModel.sortColDef.name;
|
|
33
|
+
var sortOrder = sortModel.sortColDef.order;
|
|
34
|
+
var sortColIndex = cols.findIndex(function (_a) {
|
|
35
|
+
var name = _a.name;
|
|
36
|
+
return name === sortFieldName;
|
|
37
|
+
});
|
|
38
|
+
if (sortColIndex < 0) {
|
|
39
|
+
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."));
|
|
40
|
+
}
|
|
41
|
+
var typeStr = cols[sortColIndex].type;
|
|
42
|
+
var ascComparator = getTypeComparator(typeStr);
|
|
43
|
+
var rowComparator = getRowComparator(ascComparator, sortFieldName);
|
|
44
|
+
if (sortOrder === "desc") {
|
|
45
|
+
var descComparator = function (a, b) {
|
|
46
|
+
return ascComparator(a, b) * -1;
|
|
47
|
+
};
|
|
48
|
+
rowComparator = getRowComparator(descComparator, sortFieldName);
|
|
49
|
+
}
|
|
50
|
+
return rows.slice().sort(rowComparator);
|
|
51
|
+
}, [rows, cols, sortModel]);
|
|
7
52
|
var currentPageRows = useMemo(function () {
|
|
8
53
|
if (pagination === undefined) {
|
|
9
|
-
return
|
|
54
|
+
return sortedRows;
|
|
10
55
|
}
|
|
11
56
|
var pageSizeOptions = pagination.pageSizeOptions, pageSizeIndex = pagination.pageSizeIndex, currentPage = pagination.currentPage;
|
|
12
57
|
var pageSize = pageSizeOptions[pageSizeIndex];
|
|
13
58
|
var lowerIndex = pageSize * (currentPage - 1);
|
|
14
59
|
var upperIndex = lowerIndex + pageSize;
|
|
15
|
-
return
|
|
16
|
-
}, [
|
|
60
|
+
return sortedRows.slice(lowerIndex, upperIndex);
|
|
61
|
+
}, [sortedRows, pagination]);
|
|
17
62
|
var displayRows = useMemo(function () {
|
|
18
63
|
var nameToIndex = new Map();
|
|
19
64
|
cols.forEach(function (_a, index) {
|
|
@@ -28,13 +73,14 @@ var Grid = function (_a) {
|
|
|
28
73
|
})
|
|
29
74
|
.forEach(function (name) {
|
|
30
75
|
if (!(name in row)) {
|
|
31
|
-
throw new Error("Column definition specifies a property named \"".concat(name, "\"
|
|
76
|
+
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, "."));
|
|
32
77
|
}
|
|
33
78
|
});
|
|
34
79
|
var displayRow = [];
|
|
35
80
|
Object.keys(row).forEach(function (name) {
|
|
36
81
|
if (!nameToIndex.has(name)) {
|
|
37
|
-
|
|
82
|
+
console.error("Warning: row data contains a property named \"".concat(name, "\", but it was not found among the column definitions."));
|
|
83
|
+
return;
|
|
38
84
|
}
|
|
39
85
|
var index = nameToIndex.get(name);
|
|
40
86
|
var formatter = cols[index].formatter;
|
|
@@ -80,16 +126,29 @@ var Grid = function (_a) {
|
|
|
80
126
|
return (<div>
|
|
81
127
|
<table className="table">
|
|
82
128
|
<thead>
|
|
83
|
-
<tr>
|
|
84
|
-
{cols.map(function (_a) {
|
|
85
|
-
var
|
|
86
|
-
|
|
129
|
+
<tr aria-rowindex={1}>
|
|
130
|
+
{cols.map(function (_a, index) {
|
|
131
|
+
var _b;
|
|
132
|
+
var name = _a.name, label = _a.label, sortable = _a.sortable;
|
|
133
|
+
var colSortModel = sortModel && sortable
|
|
134
|
+
? {
|
|
135
|
+
sortOrder: ((_b = sortModel.sortColDef) === null || _b === void 0 ? void 0 : _b.name) === name
|
|
136
|
+
? sortModel.sortColDef.order
|
|
137
|
+
: null,
|
|
138
|
+
setSortOrder: function (order) {
|
|
139
|
+
sortModel.setSortColDef(order && { name: name, order: order });
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
: undefined;
|
|
143
|
+
return (<ColHeaderCell key={name} label={label} sortModel={colSortModel} ariaColIndex={index + 1}/>);
|
|
87
144
|
})}
|
|
88
145
|
</tr>
|
|
89
146
|
</thead>
|
|
90
147
|
<tbody>
|
|
91
|
-
{displayRows.map(function (row, index) { return (<tr key={index}>
|
|
92
|
-
{row.map(function (value, index) { return (<td key={index}
|
|
148
|
+
{displayRows.map(function (row, index) { return (<tr key={index} aria-rowindex={index + 2}>
|
|
149
|
+
{row.map(function (value, index) { return (<td key={index} aria-colindex={index + 1}>
|
|
150
|
+
{value}
|
|
151
|
+
</td>); })}
|
|
93
152
|
</tr>); })}
|
|
94
153
|
</tbody>
|
|
95
154
|
</table>
|
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": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Brook Li",
|
|
7
7
|
"homepage": "https://react-bootstrap-data-grid.vercel.app/",
|
|
@@ -17,15 +17,15 @@
|
|
|
17
17
|
"classnames": "^2.5.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"react": "^
|
|
21
|
-
"react-dom": "^
|
|
20
|
+
"react": "^19",
|
|
21
|
+
"react-dom": "^19"
|
|
22
22
|
},
|
|
23
23
|
"main": "./index.js",
|
|
24
24
|
"module": "./index.js",
|
|
25
25
|
"types": "./index.d.ts",
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/absreim/react-bootstrap-data-grid.git",
|
|
28
|
+
"url": "git+https://github.com/absreim/react-bootstrap-data-grid.git",
|
|
29
29
|
"directory": "src/grid"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
package/types.d.ts
CHANGED
|
@@ -5,7 +5,21 @@ export interface ColDef {
|
|
|
5
5
|
name: string;
|
|
6
6
|
label: string;
|
|
7
7
|
formatter?: (value: any) => string;
|
|
8
|
+
sortable?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export type RowDef = Record<string, ColDataType>;
|
|
10
11
|
export type JustifyContentSetting = "start" | "end" | "center" | "between" | "around" | "evenly";
|
|
11
12
|
export type Size = "small" | "medium" | "large";
|
|
13
|
+
export type SortOrder = "asc" | "desc";
|
|
14
|
+
export interface SortColDef {
|
|
15
|
+
name: string;
|
|
16
|
+
order: SortOrder;
|
|
17
|
+
}
|
|
18
|
+
export interface ColSortModel {
|
|
19
|
+
sortOrder: SortOrder | null;
|
|
20
|
+
setSortOrder: (order: SortOrder | null) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface TableSortModel {
|
|
23
|
+
sortColDef: SortColDef | null;
|
|
24
|
+
setSortColDef: (sortColDef: SortColDef | null) => void;
|
|
25
|
+
}
|