@neukoio/react-table 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.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/Table.js ADDED
@@ -0,0 +1,175 @@
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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+ var _react = _interopRequireWildcard(require("react"));
14
+ require("./styles.css");
15
+ var _useWindowSize = _interopRequireDefault(require("./useWindowSize"));
16
+ var _solid = require("@heroicons/react/20/solid");
17
+ 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); }
18
+ 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; }
19
+ var Table = function Table(_ref) {
20
+ var data = _ref.data,
21
+ columnDefs = _ref.columnDefs,
22
+ _ref$isMoreData = _ref.isMoreData,
23
+ isMoreData = _ref$isMoreData === void 0 ? false : _ref$isMoreData,
24
+ _ref$onLoadMore = _ref.onLoadMore,
25
+ onLoadMore = _ref$onLoadMore === void 0 ? function () {} : _ref$onLoadMore;
26
+ var width = (0, _useWindowSize["default"])();
27
+
28
+ // Get the appropriate column definitions based on the screen size
29
+ var getColumnDefs = function getColumnDefs() {
30
+ if (width >= 640 && width <= 768) return columnDefs.sm || columnDefs["default"];
31
+ if (width >= 769 && width <= 1024) return columnDefs.md || columnDefs["default"];
32
+ if (width >= 1025 && width <= 1280) return columnDefs.lg || columnDefs["default"];
33
+ if (width >= 1281 && width <= 1536) return columnDefs.xl || columnDefs["default"];
34
+ if (width >= 1537) return columnDefs.xxl || columnDefs["default"];
35
+ return columnDefs["default"];
36
+ };
37
+ var currentColumnDefs = getColumnDefs();
38
+
39
+ // Pagination state
40
+ var _useState = (0, _react.useState)(1),
41
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
42
+ currentPage = _useState2[0],
43
+ setCurrentPage = _useState2[1];
44
+ var _useState3 = (0, _react.useState)(10),
45
+ _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
46
+ itemsPerPage = _useState4[0],
47
+ setItemsPerPage = _useState4[1]; // State for results per page
48
+
49
+ var handleResultsPerPageChange = function handleResultsPerPageChange(value) {
50
+ setItemsPerPage(value);
51
+ setCurrentPage(1); // Reset to the first page when items per page changes
52
+ };
53
+
54
+ // Get the data for the current page
55
+ var startIndex = (currentPage - 1) * itemsPerPage;
56
+ var currentData = data.slice(startIndex, startIndex + itemsPerPage);
57
+ var totalPages = Math.ceil(data.length / itemsPerPage);
58
+
59
+ // Handle next page logic
60
+ var handleNextPage = /*#__PURE__*/function () {
61
+ var _ref2 = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
62
+ return _regenerator["default"].wrap(function _callee$(_context) {
63
+ while (1) switch (_context.prev = _context.next) {
64
+ case 0:
65
+ if (!(currentPage === totalPages && isMoreData)) {
66
+ _context.next = 3;
67
+ break;
68
+ }
69
+ _context.next = 3;
70
+ return onLoadMore();
71
+ case 3:
72
+ // Increase page number after data is loaded (or if data was already loaded)
73
+ setCurrentPage(function (prevPage) {
74
+ return Math.min(prevPage + 1, totalPages + (isMoreData ? 1 : 0));
75
+ });
76
+ case 4:
77
+ case "end":
78
+ return _context.stop();
79
+ }
80
+ }, _callee);
81
+ }));
82
+ return function handleNextPage() {
83
+ return _ref2.apply(this, arguments);
84
+ };
85
+ }();
86
+
87
+ // Handle previous page logic
88
+ var handlePreviousPage = function handlePreviousPage() {
89
+ setCurrentPage(function (prevPage) {
90
+ return Math.max(prevPage - 1, 1);
91
+ });
92
+ };
93
+ return /*#__PURE__*/_react["default"].createElement("div", {
94
+ className: "px-4 sm:px-6 lg:px-8"
95
+ }, /*#__PURE__*/_react["default"].createElement("div", {
96
+ className: "mt-8 flow-root"
97
+ }, /*#__PURE__*/_react["default"].createElement("div", {
98
+ className: "-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"
99
+ }, /*#__PURE__*/_react["default"].createElement("div", {
100
+ className: "inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8"
101
+ }, /*#__PURE__*/_react["default"].createElement("div", {
102
+ className: "overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg"
103
+ }, /*#__PURE__*/_react["default"].createElement("table", {
104
+ className: "min-w-full divide-y divide-gray-300"
105
+ }, /*#__PURE__*/_react["default"].createElement("thead", {
106
+ className: "bg-gray-50"
107
+ }, /*#__PURE__*/_react["default"].createElement("tr", null, currentColumnDefs.map(function (col, index) {
108
+ return /*#__PURE__*/_react["default"].createElement("th", {
109
+ key: index,
110
+ className: "".concat(col.style)
111
+ }, col.name);
112
+ }))), /*#__PURE__*/_react["default"].createElement("tbody", {
113
+ className: "divide-y divide-gray-200 bg-white"
114
+ }, currentData.map(function (row, rowIndex) {
115
+ return /*#__PURE__*/_react["default"].createElement("tr", {
116
+ key: rowIndex
117
+ }, currentColumnDefs.map(function (column, colIndex) {
118
+ return /*#__PURE__*/_react["default"].createElement("td", {
119
+ key: "cell-".concat(rowIndex, "-").concat(colIndex),
120
+ className: "px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
121
+ }, column.row ? column.row(row) : row[column.accessorKey]);
122
+ }));
123
+ }))))))), /*#__PURE__*/_react["default"].createElement("div", {
124
+ className: "flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6"
125
+ }, /*#__PURE__*/_react["default"].createElement("div", {
126
+ className: "hidden sm:flex sm:flex-1 sm:items-center sm:justify-between"
127
+ }, /*#__PURE__*/_react["default"].createElement("div", {
128
+ className: "flex items-center"
129
+ }, /*#__PURE__*/_react["default"].createElement("label", {
130
+ htmlFor: "results-per-page",
131
+ className: "mr-3 text-sm text-gray-700"
132
+ }, "Results per page:"), /*#__PURE__*/_react["default"].createElement("select", {
133
+ id: "results-per-page",
134
+ name: "results-per-page",
135
+ value: itemsPerPage,
136
+ onChange: function onChange(e) {
137
+ return handleResultsPerPageChange(Number(e.target.value));
138
+ },
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
+ }, /*#__PURE__*/_react["default"].createElement("option", {
141
+ value: "10"
142
+ }, "10"), /*#__PURE__*/_react["default"].createElement("option", {
143
+ value: "20"
144
+ }, "20"), /*#__PURE__*/_react["default"].createElement("option", {
145
+ value: "50"
146
+ }, "50"), /*#__PURE__*/_react["default"].createElement("option", {
147
+ value: "100"
148
+ }, "100"))), /*#__PURE__*/_react["default"].createElement("nav", {
149
+ "aria-label": "Pagination",
150
+ className: "isolate inline-flex -space-x-px rounded-md shadow-sm"
151
+ }, /*#__PURE__*/_react["default"].createElement("button", {
152
+ onClick: handlePreviousPage,
153
+ 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'),
154
+ disabled: currentPage === 1
155
+ }, /*#__PURE__*/_react["default"].createElement(_solid.ChevronLeftIcon, {
156
+ "aria-hidden": "true",
157
+ className: "w-5 h-5"
158
+ })), (0, _toConsumableArray2["default"])(Array(totalPages)).map(function (_, index) {
159
+ return /*#__PURE__*/_react["default"].createElement("button", {
160
+ key: index,
161
+ onClick: function onClick() {
162
+ return setCurrentPage(index + 1);
163
+ },
164
+ 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')
165
+ }, index + 1);
166
+ }), /*#__PURE__*/_react["default"].createElement("button", {
167
+ onClick: handleNextPage,
168
+ 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'),
169
+ disabled: currentPage === totalPages && !isMoreData
170
+ }, /*#__PURE__*/_react["default"].createElement(_solid.ChevronRightIcon, {
171
+ "aria-hidden": "true",
172
+ className: "w-5 h-5"
173
+ }))))));
174
+ };
175
+ 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,26 @@
1
+ {
2
+ "name": "@neukoio/react-table",
3
+ "version": "0.0.2",
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
+ "react": "^18.3.1",
16
+ "react-dom": "^18.3.1"
17
+ },
18
+ "devDependencies": {
19
+ "@babel/cli": "^7.25.9",
20
+ "@babel/core": "^7.26.0",
21
+ "@babel/plugin-transform-runtime": "^7.21.0",
22
+ "@babel/preset-env": "^7.26.0",
23
+ "@babel/preset-react": "^7.25.9",
24
+ "tailwindcss": "^3.2.4"
25
+ }
26
+ }
package/src/Table.js ADDED
@@ -0,0 +1,150 @@
1
+ import React, { useState } from 'react';
2
+ import './styles.css';
3
+ import useWindowSize from './useWindowSize';
4
+ import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/20/solid';
5
+
6
+ const Table = ({ data, columnDefs, isMoreData = false, onLoadMore = () => {} }) => {
7
+ const width = useWindowSize();
8
+
9
+ // Get the appropriate column definitions based on the screen size
10
+ const getColumnDefs = () => {
11
+ if (width >= 640 && width <= 768) return columnDefs.sm || columnDefs.default;
12
+ if (width >= 769 && width <= 1024) return columnDefs.md || columnDefs.default;
13
+ if (width >= 1025 && width <= 1280) return columnDefs.lg || columnDefs.default;
14
+ if (width >= 1281 && width <= 1536) return columnDefs.xl || columnDefs.default;
15
+ if (width >= 1537) return columnDefs.xxl || columnDefs.default;
16
+ return columnDefs.default;
17
+ };
18
+
19
+ const currentColumnDefs = getColumnDefs();
20
+
21
+ // Pagination state
22
+ const [currentPage, setCurrentPage] = useState(1);
23
+ const [itemsPerPage, setItemsPerPage] = useState(10); // State for results per page
24
+
25
+ const handleResultsPerPageChange = (value) => {
26
+ setItemsPerPage(value);
27
+ setCurrentPage(1); // Reset to the first page when items per page changes
28
+ };
29
+
30
+ // Get the data for the current page
31
+ const startIndex = (currentPage - 1) * itemsPerPage;
32
+ const currentData = data.slice(startIndex, startIndex + itemsPerPage);
33
+
34
+ const totalPages = Math.ceil(data.length / itemsPerPage);
35
+
36
+ // Handle next page logic
37
+ const handleNextPage = async () => {
38
+ if (currentPage === totalPages && isMoreData) {
39
+ // Fetch more data when on the last page
40
+ await onLoadMore(); // Fetch more data
41
+ }
42
+ // Increase page number after data is loaded (or if data was already loaded)
43
+ setCurrentPage((prevPage) => Math.min(prevPage + 1, totalPages + (isMoreData ? 1 : 0)));
44
+ };
45
+
46
+ // Handle previous page logic
47
+ const handlePreviousPage = () => {
48
+ setCurrentPage((prevPage) => Math.max(prevPage - 1, 1));
49
+ };
50
+
51
+ return (
52
+ <div className="px-4 sm:px-6 lg:px-8">
53
+ <div className="mt-8 flow-root">
54
+ <div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
55
+ <div className="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
56
+ <div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 sm:rounded-lg">
57
+ <table className="min-w-full divide-y divide-gray-300">
58
+ <thead className="bg-gray-50">
59
+ <tr>
60
+ {currentColumnDefs.map((col, index) => (
61
+ <th key={index} className={`${col.style}`}>
62
+ {col.name}
63
+ </th>
64
+ ))}
65
+ </tr>
66
+ </thead>
67
+ <tbody className="divide-y divide-gray-200 bg-white">
68
+ {currentData.map((row, rowIndex) => (
69
+ <tr key={rowIndex}>
70
+ {currentColumnDefs.map((column, colIndex) => (
71
+ <td
72
+ key={`cell-${rowIndex}-${colIndex}`}
73
+ className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900"
74
+ >
75
+ {column.row ? column.row(row) : row[column.accessorKey]}
76
+ </td>
77
+ ))}
78
+ </tr>
79
+ ))}
80
+ </tbody>
81
+ </table>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+
87
+ {/* Pagination Section */}
88
+ <div className="flex items-center justify-between border-t border-gray-200 bg-white px-4 py-3 sm:px-6">
89
+ <div className="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
90
+ <div className="flex items-center">
91
+ <label htmlFor="results-per-page" className="mr-3 text-sm text-gray-700">
92
+ Results per page:
93
+ </label>
94
+ <select
95
+ id="results-per-page"
96
+ name="results-per-page"
97
+ value={itemsPerPage}
98
+ onChange={(e) => handleResultsPerPageChange(Number(e.target.value))}
99
+ 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"
100
+ >
101
+ <option value="10">10</option>
102
+ <option value="20">20</option>
103
+ <option value="50">50</option>
104
+ <option value="100">100</option>
105
+ </select>
106
+ </div>
107
+
108
+ <nav aria-label="Pagination" className="isolate inline-flex -space-x-px rounded-md shadow-sm">
109
+ <button
110
+ onClick={handlePreviousPage}
111
+ className={`relative inline-flex items-center rounded-l-md px-3 py-2 text-sm font-medium ${currentPage === 1
112
+ ? 'text-gray-300 bg-gray-50 cursor-not-allowed'
113
+ : 'text-gray-700 bg-white hover:bg-gray-100'
114
+ }`}
115
+ disabled={currentPage === 1}
116
+ >
117
+ <ChevronLeftIcon aria-hidden="true" className="w-5 h-5" />
118
+ </button>
119
+
120
+ {[...Array(totalPages)].map((_, index) => (
121
+ <button
122
+ key={index}
123
+ onClick={() => setCurrentPage(index + 1)}
124
+ className={`relative inline-flex items-center px-4 py-2 text-sm font-medium ${currentPage === index + 1
125
+ ? 'bg-indigo-600 text-white'
126
+ : 'text-gray-700 bg-white hover:bg-gray-100'
127
+ }`}
128
+ >
129
+ {index + 1}
130
+ </button>
131
+ ))}
132
+
133
+ <button
134
+ onClick={handleNextPage}
135
+ className={`relative inline-flex items-center rounded-r-md px-3 py-2 text-sm font-medium ${currentPage === totalPages && !isMoreData
136
+ ? 'text-gray-300 bg-gray-50 cursor-not-allowed'
137
+ : 'text-gray-700 bg-white hover:bg-gray-100'
138
+ }`}
139
+ disabled={currentPage === totalPages && !isMoreData}
140
+ >
141
+ <ChevronRightIcon aria-hidden="true" className="w-5 h-5" />
142
+ </button>
143
+ </nav>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ );
148
+ };
149
+
150
+ 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;