@neukoio/react-table 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|