@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 ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "presets": ["@babel/preset-env", "@babel/preset-react"],
3
+ "plugins": ["@babel/plugin-transform-runtime"]
4
+ }
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"));
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -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
@@ -0,0 +1,2 @@
1
+ // index.js
2
+ export { default as Table } from './Table';
package/src/styles.css ADDED
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -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;