@neukoio/react-table 0.0.1
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.
Potentially problematic release.
This version of @neukoio/react-table might be problematic. Click here for more details.
- package/.babelrc +4 -0
- package/README.md +52 -0
- package/dist/Button.js +215 -0
- package/dist/Table.js +214 -0
- package/dist/index.js +13 -0
- package/dist/styles.css +3 -0
- package/dist/useWindowSize.js +27 -0
- package/package.json +30 -0
- package/src/Table.js +189 -0
- package/src/index.js +2 -0
- package/src/styles.css +3 -0
- package/src/useWindowSize.js +16 -0
package/.babelrc
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# My React Table Package
|
|
2
|
+
|
|
3
|
+
**`react-table-neuko-io`** is a lightweight, customizable, and reusable table component designed for React applications. Built with React and styled using Tailwind CSS, this package simplifies the creation of interactive and visually appealing tables.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- π¦ **Reusable Components**: Comes with a `Table` and `Button` component out of the box.
|
|
10
|
+
- π¨ **Tailwind CSS Styling**: Fully styled and customizable using Tailwind CSS.
|
|
11
|
+
- π **Ease of Use**: Simple API for quick integration.
|
|
12
|
+
- β‘ **Responsive Design**: Adapts to all screen sizes seamlessly.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install the package via npm:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install react-table-neuko-io
|
|
22
|
+
```
|
|
23
|
+
---
|
|
24
|
+
## File Structure
|
|
25
|
+
|
|
26
|
+
Hereβs the structure of the package:
|
|
27
|
+
|
|
28
|
+
react-table-neuko-io/
|
|
29
|
+
βββ src/
|
|
30
|
+
β βββ index.js # Entry point for the components
|
|
31
|
+
β βββ Table.js # Table component
|
|
32
|
+
β βββ Button.js # Button component
|
|
33
|
+
β βββ styles.css # Tailwind CSS styles
|
|
34
|
+
β βββ useWindowSize.js # Custom hook for handling responsive design
|
|
35
|
+
βββ dist/ # Transpiled output
|
|
36
|
+
βββ package.json # Package configuration
|
|
37
|
+
βββ .babelrc # Babel configuration
|
|
38
|
+
βββ tailwind.config.js # Tailwind configuration
|
|
39
|
+
βββ postcss.config.js # PostCSS configuration
|
|
40
|
+
βββ README.md # Documentation
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
## Development
|
|
45
|
+
If you'd like to contribute or make changes to the package, follow these steps:
|
|
46
|
+
|
|
47
|
+
Clone the repository:
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
## License
|
|
51
|
+
This project is licensed under the MIT License. See the LICENSE file for more details.
|
|
52
|
+
|
package/dist/Button.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
12
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
15
|
+
require("./styles.css");
|
|
16
|
+
var _solid = require("@heroicons/react/20/solid");
|
|
17
|
+
var _useWindowSize = _interopRequireDefault(require("./useWindowSize"));
|
|
18
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
19
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
|
|
20
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
21
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
22
|
+
var Button = function Button(_ref) {
|
|
23
|
+
var data = _ref.data,
|
|
24
|
+
columnDefs = _ref.columnDefs,
|
|
25
|
+
isMoreData = _ref.isMoreData,
|
|
26
|
+
onLoadMore = _ref.onLoadMore;
|
|
27
|
+
var width = (0, _useWindowSize["default"])();
|
|
28
|
+
var _useState = (0, _react.useState)(columnDefs),
|
|
29
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
30
|
+
mergedColumnDefs = _useState2[0],
|
|
31
|
+
setMergedColumnDefs = _useState2[1];
|
|
32
|
+
var _useState3 = (0, _react.useState)(data),
|
|
33
|
+
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
|
|
34
|
+
mergedData = _useState4[0],
|
|
35
|
+
setMergedData = _useState4[1];
|
|
36
|
+
|
|
37
|
+
// Merge columns and data based on the screen width
|
|
38
|
+
(0, _react.useEffect)(function () {
|
|
39
|
+
if (width >= 640 && width < 768) {
|
|
40
|
+
// sm screen
|
|
41
|
+
var removedColumns = columnDefs.slice(1, 3);
|
|
42
|
+
var combinedColumnName = removedColumns.join(' and ');
|
|
43
|
+
var updatedColumnDefs = columnDefs.filter(function (_, index) {
|
|
44
|
+
return index !== 1 && index !== 2;
|
|
45
|
+
}).concat(combinedColumnName);
|
|
46
|
+
var updatedData = data.map(function (item) {
|
|
47
|
+
return _objectSpread(_objectSpread({}, item), {}, (0, _defineProperty2["default"])({}, combinedColumnName, "".concat(item.Priority, " - ").concat(item.Description)));
|
|
48
|
+
});
|
|
49
|
+
setMergedColumnDefs(updatedColumnDefs);
|
|
50
|
+
setMergedData(updatedData);
|
|
51
|
+
} else {
|
|
52
|
+
setMergedColumnDefs(columnDefs);
|
|
53
|
+
setMergedData(data);
|
|
54
|
+
}
|
|
55
|
+
}, [width, data, columnDefs]);
|
|
56
|
+
|
|
57
|
+
// Pagination state
|
|
58
|
+
var _useState5 = (0, _react.useState)(1),
|
|
59
|
+
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
60
|
+
currentPage = _useState6[0],
|
|
61
|
+
setCurrentPage = _useState6[1];
|
|
62
|
+
var _useState7 = (0, _react.useState)(10),
|
|
63
|
+
_useState8 = (0, _slicedToArray2["default"])(_useState7, 2),
|
|
64
|
+
itemsPerPage = _useState8[0],
|
|
65
|
+
setItemsPerPage = _useState8[1]; // State for results per page
|
|
66
|
+
var _useState9 = (0, _react.useState)(false),
|
|
67
|
+
_useState10 = (0, _slicedToArray2["default"])(_useState9, 2),
|
|
68
|
+
userTriggeredAction = _useState10[0],
|
|
69
|
+
setUserTriggeredAction = _useState10[1];
|
|
70
|
+
var handleResultsPerPageChange = function handleResultsPerPageChange(value) {
|
|
71
|
+
setItemsPerPage(value);
|
|
72
|
+
setCurrentPage(1); // Reset to the first page when items per page changes
|
|
73
|
+
setUserTriggeredAction(true);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Get the data for the current page
|
|
77
|
+
var startIndex = (currentPage - 1) * itemsPerPage;
|
|
78
|
+
var currentData = mergedData.slice(startIndex, startIndex + itemsPerPage);
|
|
79
|
+
var totalPages = Math.ceil(mergedData.length / itemsPerPage);
|
|
80
|
+
var handleNextPage = /*#__PURE__*/function () {
|
|
81
|
+
var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
|
|
82
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
83
|
+
while (1) switch (_context.prev = _context.next) {
|
|
84
|
+
case 0:
|
|
85
|
+
if (!(currentPage === totalPages && isMoreData)) {
|
|
86
|
+
_context.next = 3;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
_context.next = 3;
|
|
90
|
+
return onLoadMore();
|
|
91
|
+
case 3:
|
|
92
|
+
setCurrentPage(function (prevPage) {
|
|
93
|
+
return Math.min(prevPage + 1, totalPages + (isMoreData ? 1 : 0));
|
|
94
|
+
});
|
|
95
|
+
setUserTriggeredAction(true);
|
|
96
|
+
case 5:
|
|
97
|
+
case "end":
|
|
98
|
+
return _context.stop();
|
|
99
|
+
}
|
|
100
|
+
}, _callee);
|
|
101
|
+
}));
|
|
102
|
+
return function handleNextPage() {
|
|
103
|
+
return _ref2.apply(this, arguments);
|
|
104
|
+
};
|
|
105
|
+
}();
|
|
106
|
+
var handlePreviousPage = function handlePreviousPage() {
|
|
107
|
+
setCurrentPage(function (prevPage) {
|
|
108
|
+
return Math.max(prevPage - 1, 1);
|
|
109
|
+
});
|
|
110
|
+
setUserTriggeredAction(true); // Mark user triggered action
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Run the effect only when user triggers the action (next page or results per page change)
|
|
114
|
+
(0, _react.useEffect)(function () {
|
|
115
|
+
if (userTriggeredAction && mergedData.length < currentPage * itemsPerPage) {
|
|
116
|
+
onLoadMore(); // Load more data if the current page exceeds the available data
|
|
117
|
+
setUserTriggeredAction(false); // Reset after loading more data
|
|
118
|
+
}
|
|
119
|
+
}, [currentPage, itemsPerPage, mergedData, onLoadMore, userTriggeredAction]);
|
|
120
|
+
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
121
|
+
className: "px-4 sm:px-6 lg:px-8"
|
|
122
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
123
|
+
className: "mt-8 flow-root"
|
|
124
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
125
|
+
className: "-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"
|
|
126
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
127
|
+
className: "inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8"
|
|
128
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
129
|
+
className: "overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg"
|
|
130
|
+
}, /*#__PURE__*/_react["default"].createElement("table", {
|
|
131
|
+
className: "min-w-full divide-y divide-gray-300"
|
|
132
|
+
}, /*#__PURE__*/_react["default"].createElement("thead", {
|
|
133
|
+
className: "bg-gray-50"
|
|
134
|
+
}, /*#__PURE__*/_react["default"].createElement("tr", null, mergedColumnDefs.map(function (columnDef, index) {
|
|
135
|
+
return /*#__PURE__*/_react["default"].createElement("th", {
|
|
136
|
+
key: columnDef,
|
|
137
|
+
scope: "col",
|
|
138
|
+
className: "".concat(index === 0 ? 'py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:text-base' : 'px-3 py-3.5 text-left text-sm font-semibold text-gray-900 md:text-sm lg:text-base')
|
|
139
|
+
}, columnDef);
|
|
140
|
+
}), /*#__PURE__*/_react["default"].createElement("th", {
|
|
141
|
+
scope: "col",
|
|
142
|
+
className: "relative py-3.5 pl-3 pr-4 sm:pr-6"
|
|
143
|
+
}, /*#__PURE__*/_react["default"].createElement("span", {
|
|
144
|
+
className: "sr-only"
|
|
145
|
+
}, "Edit")))), /*#__PURE__*/_react["default"].createElement("tbody", {
|
|
146
|
+
className: "divide-y divide-gray-200 bg-white"
|
|
147
|
+
}, currentData.map(function (item, index) {
|
|
148
|
+
return /*#__PURE__*/_react["default"].createElement("tr", {
|
|
149
|
+
key: index
|
|
150
|
+
}, mergedColumnDefs.map(function (columnDef, index) {
|
|
151
|
+
return /*#__PURE__*/_react["default"].createElement("td", {
|
|
152
|
+
key: columnDef,
|
|
153
|
+
className: "".concat(index === 0 ? 'whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 md:text-sm lg:text-base' : 'whitespace-nowrap px-3 py-4 text-sm text-gray-500 md:text-sm lg:text-base')
|
|
154
|
+
}, item[columnDef]);
|
|
155
|
+
}), /*#__PURE__*/_react["default"].createElement("td", {
|
|
156
|
+
className: "relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6"
|
|
157
|
+
}, /*#__PURE__*/_react["default"].createElement("a", {
|
|
158
|
+
href: "#",
|
|
159
|
+
className: "text-indigo-600 hover:text-indigo-900"
|
|
160
|
+
}, "Edit", /*#__PURE__*/_react["default"].createElement("span", {
|
|
161
|
+
className: "sr-only"
|
|
162
|
+
}, ", ", item['Group Name']))));
|
|
163
|
+
}))))))), /*#__PURE__*/_react["default"].createElement("div", {
|
|
164
|
+
className: "flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6"
|
|
165
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
166
|
+
className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between"
|
|
167
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
168
|
+
className: "flex items-center"
|
|
169
|
+
}, /*#__PURE__*/_react["default"].createElement("label", {
|
|
170
|
+
htmlFor: "results-per-page",
|
|
171
|
+
className: "mr-3 text-sm text-gray-700"
|
|
172
|
+
}, "Results per page:"), /*#__PURE__*/_react["default"].createElement("select", {
|
|
173
|
+
id: "results-per-page",
|
|
174
|
+
name: "results-per-page",
|
|
175
|
+
value: itemsPerPage,
|
|
176
|
+
onChange: function onChange(e) {
|
|
177
|
+
return handleResultsPerPageChange(Number(e.target.value));
|
|
178
|
+
},
|
|
179
|
+
className: "block w-24 rounded-md border-gray-300 bg-white py-2 pl-3 pr-10 text-gray-900 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
|
180
|
+
}, /*#__PURE__*/_react["default"].createElement("option", {
|
|
181
|
+
value: "10"
|
|
182
|
+
}, "10"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
183
|
+
value: "20"
|
|
184
|
+
}, "20"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
185
|
+
value: "50"
|
|
186
|
+
}, "50"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
187
|
+
value: "100"
|
|
188
|
+
}, "100"))), /*#__PURE__*/_react["default"].createElement("nav", {
|
|
189
|
+
"aria-label": "Pagination",
|
|
190
|
+
className: "isolate inline-flex -space-x-px rounded-md shadow-sm"
|
|
191
|
+
}, /*#__PURE__*/_react["default"].createElement("button", {
|
|
192
|
+
onClick: handlePreviousPage,
|
|
193
|
+
className: "relative inline-flex items-center rounded-l-md px-3 py-2 text-sm font-medium ".concat(currentPage === 1 ? 'text-gray-300 bg-gray-50 cursor-not-allowed' : 'text-gray-700 bg-white hover:bg-gray-100'),
|
|
194
|
+
disabled: currentPage === 1
|
|
195
|
+
}, /*#__PURE__*/_react["default"].createElement(_solid.ChevronLeftIcon, {
|
|
196
|
+
"aria-hidden": "true",
|
|
197
|
+
className: "w-5 h-5"
|
|
198
|
+
})), (0, _toConsumableArray2["default"])(Array(totalPages)).map(function (_, index) {
|
|
199
|
+
return /*#__PURE__*/_react["default"].createElement("button", {
|
|
200
|
+
key: index,
|
|
201
|
+
onClick: function onClick() {
|
|
202
|
+
return setCurrentPage(index + 1);
|
|
203
|
+
},
|
|
204
|
+
className: "relative inline-flex items-center px-4 py-2 text-sm font-medium ".concat(currentPage === index + 1 ? 'bg-indigo-600 text-white' : 'text-gray-700 bg-white hover:bg-gray-100')
|
|
205
|
+
}, index + 1);
|
|
206
|
+
}), /*#__PURE__*/_react["default"].createElement("button", {
|
|
207
|
+
onClick: handleNextPage,
|
|
208
|
+
className: "relative inline-flex items-center rounded-r-md px-3 py-2 text-sm font-medium ".concat(currentPage === totalPages && !isMoreData ? 'text-gray-300 bg-gray-50 cursor-not-allowed' : 'text-gray-700 bg-white hover:bg-gray-100'),
|
|
209
|
+
disabled: currentPage === totalPages && !isMoreData
|
|
210
|
+
}, /*#__PURE__*/_react["default"].createElement(_solid.ChevronRightIcon, {
|
|
211
|
+
"aria-hidden": "true",
|
|
212
|
+
className: "w-5 h-5"
|
|
213
|
+
}))))));
|
|
214
|
+
};
|
|
215
|
+
var _default = exports["default"] = Button;
|
package/dist/Table.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports["default"] = void 0;
|
|
9
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
10
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
12
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
15
|
+
require("./styles.css");
|
|
16
|
+
var _solid = require("@heroicons/react/20/solid");
|
|
17
|
+
var _useWindowSize = _interopRequireDefault(require("./useWindowSize"));
|
|
18
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
19
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
|
|
20
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
21
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
22
|
+
var Table = function Table(_ref) {
|
|
23
|
+
var data = _ref.data,
|
|
24
|
+
columnDefs = _ref.columnDefs,
|
|
25
|
+
isMoreData = _ref.isMoreData,
|
|
26
|
+
onLoadMore = _ref.onLoadMore;
|
|
27
|
+
var width = (0, _useWindowSize["default"])();
|
|
28
|
+
var _useState = (0, _react.useState)(columnDefs),
|
|
29
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
30
|
+
mergedColumnDefs = _useState2[0],
|
|
31
|
+
setMergedColumnDefs = _useState2[1];
|
|
32
|
+
var _useState3 = (0, _react.useState)(data),
|
|
33
|
+
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
|
|
34
|
+
mergedData = _useState4[0],
|
|
35
|
+
setMergedData = _useState4[1];
|
|
36
|
+
|
|
37
|
+
// Merge columns and data based on the screen width
|
|
38
|
+
(0, _react.useEffect)(function () {
|
|
39
|
+
if (width >= 640 && width < 768) {
|
|
40
|
+
// sm screen
|
|
41
|
+
var removedColumns = columnDefs.slice(1, 3);
|
|
42
|
+
var combinedColumnName = removedColumns.join(' and ');
|
|
43
|
+
var updatedColumnDefs = columnDefs.filter(function (_, index) {
|
|
44
|
+
return index !== 1 && index !== 2;
|
|
45
|
+
}).concat(combinedColumnName);
|
|
46
|
+
var updatedData = data.map(function (item) {
|
|
47
|
+
return _objectSpread(_objectSpread({}, item), {}, (0, _defineProperty2["default"])({}, combinedColumnName, "".concat(item.Priority, " - ").concat(item.Description)));
|
|
48
|
+
});
|
|
49
|
+
setMergedColumnDefs(updatedColumnDefs);
|
|
50
|
+
setMergedData(updatedData);
|
|
51
|
+
} else {
|
|
52
|
+
setMergedColumnDefs(columnDefs);
|
|
53
|
+
setMergedData(data);
|
|
54
|
+
}
|
|
55
|
+
}, [width, data, columnDefs]);
|
|
56
|
+
|
|
57
|
+
// Pagination state
|
|
58
|
+
var _useState5 = (0, _react.useState)(1),
|
|
59
|
+
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
60
|
+
currentPage = _useState6[0],
|
|
61
|
+
setCurrentPage = _useState6[1];
|
|
62
|
+
var _useState7 = (0, _react.useState)(10),
|
|
63
|
+
_useState8 = (0, _slicedToArray2["default"])(_useState7, 2),
|
|
64
|
+
itemsPerPage = _useState8[0],
|
|
65
|
+
setItemsPerPage = _useState8[1]; // State for results per page
|
|
66
|
+
var _useState9 = (0, _react.useState)(false),
|
|
67
|
+
_useState10 = (0, _slicedToArray2["default"])(_useState9, 2),
|
|
68
|
+
userTriggeredAction = _useState10[0],
|
|
69
|
+
setUserTriggeredAction = _useState10[1];
|
|
70
|
+
var handleResultsPerPageChange = function handleResultsPerPageChange(value) {
|
|
71
|
+
setItemsPerPage(value);
|
|
72
|
+
setCurrentPage(1); // Reset to the first page when items per page changes
|
|
73
|
+
setUserTriggeredAction(true);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Get the data for the current page
|
|
77
|
+
var startIndex = (currentPage - 1) * itemsPerPage;
|
|
78
|
+
var currentData = mergedData.slice(startIndex, startIndex + itemsPerPage);
|
|
79
|
+
var totalPages = Math.ceil(mergedData.length / itemsPerPage);
|
|
80
|
+
var handleNextPage = /*#__PURE__*/function () {
|
|
81
|
+
var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
|
|
82
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
83
|
+
while (1) switch (_context.prev = _context.next) {
|
|
84
|
+
case 0:
|
|
85
|
+
if (!(currentPage === totalPages && isMoreData)) {
|
|
86
|
+
_context.next = 3;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
_context.next = 3;
|
|
90
|
+
return onLoadMore();
|
|
91
|
+
case 3:
|
|
92
|
+
setCurrentPage(function (prevPage) {
|
|
93
|
+
return Math.min(prevPage + 1, totalPages + (isMoreData ? 1 : 0));
|
|
94
|
+
});
|
|
95
|
+
setUserTriggeredAction(true);
|
|
96
|
+
case 5:
|
|
97
|
+
case "end":
|
|
98
|
+
return _context.stop();
|
|
99
|
+
}
|
|
100
|
+
}, _callee);
|
|
101
|
+
}));
|
|
102
|
+
return function handleNextPage() {
|
|
103
|
+
return _ref2.apply(this, arguments);
|
|
104
|
+
};
|
|
105
|
+
}();
|
|
106
|
+
var handlePreviousPage = function handlePreviousPage() {
|
|
107
|
+
setCurrentPage(function (prevPage) {
|
|
108
|
+
return Math.max(prevPage - 1, 1);
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Run the effect only when user triggers the action (next page or results per page change)
|
|
113
|
+
(0, _react.useEffect)(function () {
|
|
114
|
+
if (userTriggeredAction && mergedData.length < currentPage * itemsPerPage) {
|
|
115
|
+
onLoadMore(); // Load more data if the current page exceeds the available data
|
|
116
|
+
setUserTriggeredAction(false); // Reset after loading more data
|
|
117
|
+
}
|
|
118
|
+
}, [currentPage, itemsPerPage, mergedData, onLoadMore, userTriggeredAction]);
|
|
119
|
+
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
120
|
+
className: "px-4 sm:px-6 lg:px-8"
|
|
121
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
122
|
+
className: "mt-8 flow-root"
|
|
123
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
124
|
+
className: "-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"
|
|
125
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
126
|
+
className: "inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8"
|
|
127
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
128
|
+
className: "overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg"
|
|
129
|
+
}, /*#__PURE__*/_react["default"].createElement("table", {
|
|
130
|
+
className: "min-w-full divide-y divide-gray-300"
|
|
131
|
+
}, /*#__PURE__*/_react["default"].createElement("thead", {
|
|
132
|
+
className: "bg-gray-50"
|
|
133
|
+
}, /*#__PURE__*/_react["default"].createElement("tr", null, mergedColumnDefs.map(function (columnDef, index) {
|
|
134
|
+
return /*#__PURE__*/_react["default"].createElement("th", {
|
|
135
|
+
key: columnDef,
|
|
136
|
+
scope: "col",
|
|
137
|
+
className: "".concat(index === 0 ? 'py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:text-base' : 'px-3 py-3.5 text-left text-sm font-semibold text-gray-900 md:text-sm lg:text-base')
|
|
138
|
+
}, columnDef);
|
|
139
|
+
}), /*#__PURE__*/_react["default"].createElement("th", {
|
|
140
|
+
scope: "col",
|
|
141
|
+
className: "relative py-3.5 pl-3 pr-4 sm:pr-6"
|
|
142
|
+
}, /*#__PURE__*/_react["default"].createElement("span", {
|
|
143
|
+
className: "sr-only"
|
|
144
|
+
}, "Edit")))), /*#__PURE__*/_react["default"].createElement("tbody", {
|
|
145
|
+
className: "divide-y divide-gray-200 bg-white"
|
|
146
|
+
}, currentData.map(function (item, index) {
|
|
147
|
+
return /*#__PURE__*/_react["default"].createElement("tr", {
|
|
148
|
+
key: index
|
|
149
|
+
}, mergedColumnDefs.map(function (columnDef, index) {
|
|
150
|
+
return /*#__PURE__*/_react["default"].createElement("td", {
|
|
151
|
+
key: columnDef,
|
|
152
|
+
className: "".concat(index === 0 ? 'whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 md:text-sm lg:text-base' : 'whitespace-nowrap px-3 py-4 text-sm text-gray-500 md:text-sm lg:text-base')
|
|
153
|
+
}, item[columnDef]);
|
|
154
|
+
}), /*#__PURE__*/_react["default"].createElement("td", {
|
|
155
|
+
className: "relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6"
|
|
156
|
+
}, /*#__PURE__*/_react["default"].createElement("a", {
|
|
157
|
+
href: "#",
|
|
158
|
+
className: "text-indigo-600 hover:text-indigo-900"
|
|
159
|
+
}, "Edit", /*#__PURE__*/_react["default"].createElement("span", {
|
|
160
|
+
className: "sr-only"
|
|
161
|
+
}, ", ", item['Group Name']))));
|
|
162
|
+
}))))))), /*#__PURE__*/_react["default"].createElement("div", {
|
|
163
|
+
className: "flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6"
|
|
164
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
165
|
+
className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between"
|
|
166
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
167
|
+
className: "flex items-center"
|
|
168
|
+
}, /*#__PURE__*/_react["default"].createElement("label", {
|
|
169
|
+
htmlFor: "results-per-page",
|
|
170
|
+
className: "mr-3 text-sm text-gray-700"
|
|
171
|
+
}, "Results per page:"), /*#__PURE__*/_react["default"].createElement("select", {
|
|
172
|
+
id: "results-per-page",
|
|
173
|
+
name: "results-per-page",
|
|
174
|
+
value: itemsPerPage,
|
|
175
|
+
onChange: function onChange(e) {
|
|
176
|
+
return handleResultsPerPageChange(Number(e.target.value));
|
|
177
|
+
},
|
|
178
|
+
className: "block w-24 rounded-md border-gray-300 bg-white py-2 pl-3 pr-10 text-gray-900 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
|
179
|
+
}, /*#__PURE__*/_react["default"].createElement("option", {
|
|
180
|
+
value: "10"
|
|
181
|
+
}, "10"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
182
|
+
value: "20"
|
|
183
|
+
}, "20"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
184
|
+
value: "50"
|
|
185
|
+
}, "50"), /*#__PURE__*/_react["default"].createElement("option", {
|
|
186
|
+
value: "100"
|
|
187
|
+
}, "100"))), /*#__PURE__*/_react["default"].createElement("nav", {
|
|
188
|
+
"aria-label": "Pagination",
|
|
189
|
+
className: "isolate inline-flex -space-x-px rounded-md shadow-sm"
|
|
190
|
+
}, /*#__PURE__*/_react["default"].createElement("button", {
|
|
191
|
+
onClick: handlePreviousPage,
|
|
192
|
+
className: "relative inline-flex items-center rounded-l-md px-3 py-2 text-sm font-medium ".concat(currentPage === 1 ? 'text-gray-300 bg-gray-50 cursor-not-allowed' : 'text-gray-700 bg-white hover:bg-gray-100'),
|
|
193
|
+
disabled: currentPage === 1
|
|
194
|
+
}, /*#__PURE__*/_react["default"].createElement(_solid.ChevronLeftIcon, {
|
|
195
|
+
"aria-hidden": "true",
|
|
196
|
+
className: "w-5 h-5"
|
|
197
|
+
})), (0, _toConsumableArray2["default"])(Array(totalPages)).map(function (_, index) {
|
|
198
|
+
return /*#__PURE__*/_react["default"].createElement("button", {
|
|
199
|
+
key: index,
|
|
200
|
+
onClick: function onClick() {
|
|
201
|
+
return setCurrentPage(index + 1);
|
|
202
|
+
},
|
|
203
|
+
className: "relative inline-flex items-center px-4 py-2 text-sm font-medium ".concat(currentPage === index + 1 ? 'bg-indigo-600 text-white' : 'text-gray-700 bg-white hover:bg-gray-100')
|
|
204
|
+
}, index + 1);
|
|
205
|
+
}), /*#__PURE__*/_react["default"].createElement("button", {
|
|
206
|
+
onClick: handleNextPage,
|
|
207
|
+
className: "relative inline-flex items-center rounded-r-md px-3 py-2 text-sm font-medium ".concat(currentPage === totalPages && !isMoreData ? 'text-gray-300 bg-gray-50 cursor-not-allowed' : 'text-gray-700 bg-white hover:bg-gray-100'),
|
|
208
|
+
disabled: currentPage === totalPages && !isMoreData
|
|
209
|
+
}, /*#__PURE__*/_react["default"].createElement(_solid.ChevronRightIcon, {
|
|
210
|
+
"aria-hidden": "true",
|
|
211
|
+
className: "w-5 h-5"
|
|
212
|
+
}))))));
|
|
213
|
+
};
|
|
214
|
+
var _default = exports["default"] = Table;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
Object.defineProperty(exports, "Table", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function get() {
|
|
10
|
+
return _Table["default"];
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
var _Table = _interopRequireDefault(require("./Table"));
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var useWindowSize = function useWindowSize() {
|
|
11
|
+
var _useState = (0, _react.useState)(window.innerWidth),
|
|
12
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
13
|
+
width = _useState2[0],
|
|
14
|
+
setWidth = _useState2[1]; // Initial value is window.innerWidth
|
|
15
|
+
|
|
16
|
+
(0, _react.useEffect)(function () {
|
|
17
|
+
var handleResize = function handleResize() {
|
|
18
|
+
return setWidth(window.innerWidth);
|
|
19
|
+
};
|
|
20
|
+
window.addEventListener('resize', handleResize);
|
|
21
|
+
return function () {
|
|
22
|
+
return window.removeEventListener('resize', handleResize);
|
|
23
|
+
};
|
|
24
|
+
}, []);
|
|
25
|
+
return width; // Return width directly
|
|
26
|
+
};
|
|
27
|
+
var _default = exports["default"] = useWindowSize;
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neukoio/react-table",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
7
|
+
"build": "babel src --out-dir dist --copy-files"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"description": "",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@heroicons/react": "^2.1.5",
|
|
15
|
+
"@tailwindcss/aspect-ratio": "^0.4.2",
|
|
16
|
+
"@tailwindcss/forms": "^0.5.9",
|
|
17
|
+
"@tailwindcss/typography": "^0.5.15",
|
|
18
|
+
"react": "^18.3.1",
|
|
19
|
+
"react-dom": "^18.3.1",
|
|
20
|
+
"tailwindcss-animate": "^1.0.7"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@babel/cli": "^7.25.9",
|
|
24
|
+
"@babel/core": "^7.26.0",
|
|
25
|
+
"@babel/plugin-transform-runtime": "^7.21.0",
|
|
26
|
+
"@babel/preset-env": "^7.26.0",
|
|
27
|
+
"@babel/preset-react": "^7.25.9",
|
|
28
|
+
"tailwindcss": "^3.2.4"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/Table.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import './styles.css';
|
|
3
|
+
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/20/solid';
|
|
4
|
+
import useWindowSize from './useWindowSize';
|
|
5
|
+
|
|
6
|
+
const Table = ({ data, columnDefs, isMoreData, onLoadMore }) => {
|
|
7
|
+
const width = useWindowSize();
|
|
8
|
+
|
|
9
|
+
const [mergedColumnDefs, setMergedColumnDefs] = useState(columnDefs);
|
|
10
|
+
const [mergedData, setMergedData] = useState(data);
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// Merge columns and data based on the screen width
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (width >= 640 && width < 768) { // sm screen
|
|
16
|
+
const removedColumns = columnDefs.slice(1, 3);
|
|
17
|
+
const combinedColumnName = removedColumns.join(' and ');
|
|
18
|
+
|
|
19
|
+
const updatedColumnDefs = columnDefs
|
|
20
|
+
.filter((_, index) => index !== 1 && index !== 2)
|
|
21
|
+
.concat(combinedColumnName);
|
|
22
|
+
|
|
23
|
+
const updatedData = data.map((item) => ({
|
|
24
|
+
...item,
|
|
25
|
+
[combinedColumnName]: `${item.Priority} - ${item.Description}`,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
setMergedColumnDefs(updatedColumnDefs);
|
|
29
|
+
setMergedData(updatedData);
|
|
30
|
+
} else {
|
|
31
|
+
setMergedColumnDefs(columnDefs);
|
|
32
|
+
setMergedData(data);
|
|
33
|
+
}
|
|
34
|
+
}, [width, data, columnDefs]);
|
|
35
|
+
|
|
36
|
+
// Pagination state
|
|
37
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
38
|
+
const [itemsPerPage, setItemsPerPage] = useState(10); // State for results per page
|
|
39
|
+
const [userTriggeredAction, setUserTriggeredAction] = useState(false);
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
const handleResultsPerPageChange = (value) => {
|
|
43
|
+
setItemsPerPage(value);
|
|
44
|
+
setCurrentPage(1); // Reset to the first page when items per page changes
|
|
45
|
+
setUserTriggeredAction(true);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Get the data for the current page
|
|
49
|
+
const startIndex = (currentPage - 1) * itemsPerPage;
|
|
50
|
+
const currentData = mergedData.slice(startIndex, startIndex + itemsPerPage);
|
|
51
|
+
|
|
52
|
+
const totalPages = Math.ceil(mergedData.length / itemsPerPage);
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
const handleNextPage = async () => {
|
|
56
|
+
if (currentPage === totalPages && isMoreData) await onLoadMore();
|
|
57
|
+
setCurrentPage((prevPage) => Math.min(prevPage + 1, totalPages + (isMoreData ? 1 : 0)));
|
|
58
|
+
setUserTriggeredAction(true);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handlePreviousPage = () => {
|
|
62
|
+
setCurrentPage((prevPage) => Math.max(prevPage - 1, 1));
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Run the effect only when user triggers the action (next page or results per page change)
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (userTriggeredAction && mergedData.length < currentPage * itemsPerPage) {
|
|
68
|
+
onLoadMore(); // Load more data if the current page exceeds the available data
|
|
69
|
+
setUserTriggeredAction(false); // Reset after loading more data
|
|
70
|
+
}
|
|
71
|
+
}, [currentPage, itemsPerPage, mergedData, onLoadMore, userTriggeredAction]);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className="px-4 sm:px-6 lg:px-8">
|
|
75
|
+
<div className="mt-8 flow-root">
|
|
76
|
+
<div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
|
77
|
+
<div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
|
78
|
+
<div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg">
|
|
79
|
+
<table className="min-w-full divide-y divide-gray-300">
|
|
80
|
+
<thead className="bg-gray-50">
|
|
81
|
+
<tr>
|
|
82
|
+
{mergedColumnDefs.map((columnDef, index) => (
|
|
83
|
+
<th
|
|
84
|
+
key={columnDef}
|
|
85
|
+
scope="col"
|
|
86
|
+
className={`${index === 0
|
|
87
|
+
? 'py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:text-base'
|
|
88
|
+
: 'px-3 py-3.5 text-left text-sm font-semibold text-gray-900 md:text-sm lg:text-base'
|
|
89
|
+
}`}
|
|
90
|
+
>
|
|
91
|
+
{columnDef}
|
|
92
|
+
</th>
|
|
93
|
+
))}
|
|
94
|
+
<th scope="col" className="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
|
95
|
+
<span className="sr-only">Edit</span>
|
|
96
|
+
</th>
|
|
97
|
+
</tr>
|
|
98
|
+
</thead>
|
|
99
|
+
<tbody className="divide-y divide-gray-200 bg-white">
|
|
100
|
+
{currentData.map((item, index) => (
|
|
101
|
+
<tr key={index}>
|
|
102
|
+
{mergedColumnDefs.map((columnDef, index) => (
|
|
103
|
+
<td
|
|
104
|
+
key={columnDef}
|
|
105
|
+
className={`${index === 0
|
|
106
|
+
? 'whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 md:text-sm lg:text-base'
|
|
107
|
+
: 'whitespace-nowrap px-3 py-4 text-sm text-gray-500 md:text-sm lg:text-base'
|
|
108
|
+
}`}
|
|
109
|
+
>
|
|
110
|
+
{item[columnDef]}
|
|
111
|
+
</td>
|
|
112
|
+
))}
|
|
113
|
+
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
|
|
114
|
+
<a href="#" className="text-indigo-600 hover:text-indigo-900">
|
|
115
|
+
Edit<span className="sr-only">, {item['Group Name']}</span>
|
|
116
|
+
</a>
|
|
117
|
+
</td>
|
|
118
|
+
</tr>
|
|
119
|
+
))}
|
|
120
|
+
</tbody>
|
|
121
|
+
</table>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
{/* Pagination Section */}
|
|
128
|
+
<div className="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
|
|
129
|
+
<div className="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
|
|
130
|
+
<div className="flex items-center">
|
|
131
|
+
<label htmlFor="results-per-page" className="mr-3 text-sm text-gray-700">
|
|
132
|
+
Results per page:
|
|
133
|
+
</label>
|
|
134
|
+
<select
|
|
135
|
+
id="results-per-page"
|
|
136
|
+
name="results-per-page"
|
|
137
|
+
value={itemsPerPage}
|
|
138
|
+
onChange={(e) => handleResultsPerPageChange(Number(e.target.value))}
|
|
139
|
+
className="block w-24 rounded-md border-gray-300 bg-white py-2 pl-3 pr-10 text-gray-900 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
|
140
|
+
>
|
|
141
|
+
<option value="10">10</option>
|
|
142
|
+
<option value="20">20</option>
|
|
143
|
+
<option value="50">50</option>
|
|
144
|
+
<option value="100">100</option>
|
|
145
|
+
</select>
|
|
146
|
+
</div>
|
|
147
|
+
<nav aria-label="Pagination" className="isolate inline-flex -space-x-px rounded-md shadow-sm">
|
|
148
|
+
<button
|
|
149
|
+
onClick={handlePreviousPage}
|
|
150
|
+
className={`relative inline-flex items-center rounded-l-md px-3 py-2 text-sm font-medium ${currentPage === 1
|
|
151
|
+
? 'text-gray-300 bg-gray-50 cursor-not-allowed'
|
|
152
|
+
: 'text-gray-700 bg-white hover:bg-gray-100'
|
|
153
|
+
}`}
|
|
154
|
+
disabled={currentPage === 1}
|
|
155
|
+
>
|
|
156
|
+
<ChevronLeftIcon aria-hidden="true" className="w-5 h-5" />
|
|
157
|
+
</button>
|
|
158
|
+
|
|
159
|
+
{[...Array(totalPages)].map((_, index) => (
|
|
160
|
+
<button
|
|
161
|
+
key={index}
|
|
162
|
+
onClick={() => setCurrentPage(index + 1)}
|
|
163
|
+
className={`relative inline-flex items-center px-4 py-2 text-sm font-medium ${currentPage === index + 1
|
|
164
|
+
? 'bg-indigo-600 text-white'
|
|
165
|
+
: 'text-gray-700 bg-white hover:bg-gray-100'
|
|
166
|
+
}`}
|
|
167
|
+
>
|
|
168
|
+
{index + 1}
|
|
169
|
+
</button>
|
|
170
|
+
))}
|
|
171
|
+
|
|
172
|
+
<button
|
|
173
|
+
onClick={handleNextPage}
|
|
174
|
+
className={`relative inline-flex items-center rounded-r-md px-3 py-2 text-sm font-medium ${currentPage === totalPages && !isMoreData
|
|
175
|
+
? 'text-gray-300 bg-gray-50 cursor-not-allowed'
|
|
176
|
+
: 'text-gray-700 bg-white hover:bg-gray-100'
|
|
177
|
+
}`}
|
|
178
|
+
disabled={currentPage === totalPages && !isMoreData}
|
|
179
|
+
>
|
|
180
|
+
<ChevronRightIcon aria-hidden="true" className="w-5 h-5" />
|
|
181
|
+
</button>
|
|
182
|
+
</nav>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export default Table;
|
package/src/index.js
ADDED
package/src/styles.css
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const useWindowSize = () => {
|
|
4
|
+
const [width, setWidth] = useState(window.innerWidth); // Initial value is window.innerWidth
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const handleResize = () => setWidth(window.innerWidth);
|
|
8
|
+
|
|
9
|
+
window.addEventListener('resize', handleResize);
|
|
10
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
11
|
+
}, []);
|
|
12
|
+
|
|
13
|
+
return width; // Return width directly
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default useWindowSize;
|