@absreim/react-bootstrap-data-grid 1.1.0 → 1.1.3

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.
@@ -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} name="enabled" onChange={handleEnabledChange}/>
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="Start Date"/>
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="End Date"/>
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>);
@@ -11,7 +11,6 @@ var __assign = (this && this.__assign) || function () {
11
11
  };
12
12
  import { useState } from "react";
13
13
  import StringFilterRow from "./StringFilterRow";
14
- import { datetimeInputStrToUtc } from "../util/datetime";
15
14
  import NumberFilterRow from "./NumberFilterRow";
16
15
  import useFormStateFromTableFilterState from "./useFormStateFromTableFilterState";
17
16
  import DateFilterRow from "./DateFilterRow";
@@ -40,11 +39,8 @@ var convertFilterFormStateToEditableState = function (filterFormState) {
40
39
  type: rowFilterFormState.type,
41
40
  enabled: rowFilterFormState.enabled,
42
41
  };
43
- var strModifierFn_1 = rowFilterFormState.type === "date"
44
- ? function (str) { return str; }
45
- : datetimeInputStrToUtc;
46
42
  var inputStrToDate = function (str) {
47
- return str === "" ? null : new Date(strModifierFn_1(str));
43
+ return str === "" ? null : new Date(str);
48
44
  };
49
45
  switch (rowFilterFormState.scheme) {
50
46
  case "startFrom": {
@@ -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
- // TODO: Input labelling for accessibility
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} name="enabled" onChange={handleEnabledChange}/>
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
- // TODO: Input labelling for accessibility
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} name="enabled" onChange={handleEnabledChange}/>
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
- var getTypeComparator = function (typeStr) {
11
- if (typeStr === "date" || typeStr === "datetime") {
12
- return function (a, b) { return a.valueOf() - b.valueOf(); };
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 filteredRows = useFilter(rows, editableFilterState);
35
- var sortedRows = useMemo(function () {
36
- if (!sortModel || !sortModel.sortColDef) {
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 = useMemo(function () {
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
- // Array index is okay for the key for rows until some type of feature involving changing the index of rows, such as
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={index} aria-rowindex={index + 2}>
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,3 @@
1
+ import { AugRowDef, RowDef } from "../types";
2
+ declare const useAugmentedRows: (rows: RowDef[]) => AugRowDef[];
3
+ export default useAugmentedRows;
@@ -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,3 @@
1
+ import { AugRowDef, FormattedRow, ColDef } from "../types";
2
+ declare const useDisplayRows: (currentPageRows: AugRowDef[], cols: ColDef[]) => FormattedRow[];
3
+ export default useDisplayRows;
@@ -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;
@@ -1,3 +1,3 @@
1
- import { EditableTableFilterState, RowDef } from "../types";
2
- declare const useFilter: (rows: RowDef[], filterState: EditableTableFilterState | null) => RowDef[];
1
+ import { AugRowDef, EditableTableFilterState } from "../types";
2
+ declare const useFilter: (rows: AugRowDef[], filterState: EditableTableFilterState | null) => AugRowDef[];
3
3
  export default useFilter;
@@ -19,7 +19,9 @@ var useFilter = function (rows, filterState) {
19
19
  }
20
20
  }
21
21
  function checkIfPassesNumberFilter(value, state) {
22
- var numValue = Number(state.numValue); // Note that a blank string becomes 0
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,3 @@
1
+ import { AugRowDef, ColDef, TableSortModel } from "../types";
2
+ declare const useSortedRows: (rows: AugRowDef[], cols: ColDef[], sortModel: TableSortModel | undefined) => AugRowDef[];
3
+ export default useSortedRows;
@@ -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.0",
4
+ "version": "1.1.3",
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";
@@ -1,3 +1,2 @@
1
1
  export declare const dateToInputStr: (date: Date) => string;
2
2
  export declare const dateToDatetimeInputStr: (date: Date) => string;
3
- export declare const datetimeInputStrToUtc: (datetimeStr: string) => string;
package/util/datetime.js CHANGED
@@ -3,7 +3,3 @@ export var dateToInputStr = function (date) { return dayjs(date).format("YYYY-MM
3
3
  export var dateToDatetimeInputStr = function (date) {
4
4
  return dayjs(date).format("YYYY-MM-DDTHH:mm");
5
5
  };
6
- // All dates and datetimes that the grid displays are in UTC. The datetime
7
- // string in the value attribute of an input element of type datetime-local
8
- // is based on the local timezone of the client.
9
- export var datetimeInputStrToUtc = function (datetimeStr) { return datetimeStr + "Z"; };
package/component.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { FC } from "react";
2
- import { ColDef, RowDef } from "./types";
3
- interface Props {
4
- rows: RowDef[];
5
- cols: ColDef[];
6
- }
7
- declare const Grid: FC<Props>;
8
- export default Grid;
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;