@reactorui/datagrid 1.0.0

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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +778 -0
  3. package/dist/components/DataGrid/DataGrid.d.ts +5 -0
  4. package/dist/components/DataGrid/DataGrid.d.ts.map +1 -0
  5. package/dist/components/DataGrid/DataGrid.js +87 -0
  6. package/dist/components/DataGrid/index.d.ts +3 -0
  7. package/dist/components/DataGrid/index.d.ts.map +1 -0
  8. package/dist/components/DataGrid/index.js +1 -0
  9. package/dist/components/Filter/FilterControls.d.ts +11 -0
  10. package/dist/components/Filter/FilterControls.d.ts.map +1 -0
  11. package/dist/components/Filter/FilterControls.js +78 -0
  12. package/dist/components/Filter/index.d.ts +2 -0
  13. package/dist/components/Filter/index.d.ts.map +1 -0
  14. package/dist/components/Filter/index.js +1 -0
  15. package/dist/components/Pagination/Pagination.d.ts +17 -0
  16. package/dist/components/Pagination/Pagination.d.ts.map +1 -0
  17. package/dist/components/Pagination/Pagination.js +12 -0
  18. package/dist/components/Pagination/index.d.ts +2 -0
  19. package/dist/components/Pagination/index.d.ts.map +1 -0
  20. package/dist/components/Pagination/index.js +1 -0
  21. package/dist/components/Search/SearchInput.d.ts +11 -0
  22. package/dist/components/Search/SearchInput.d.ts.map +1 -0
  23. package/dist/components/Search/SearchInput.js +9 -0
  24. package/dist/components/Search/index.d.ts +2 -0
  25. package/dist/components/Search/index.d.ts.map +1 -0
  26. package/dist/components/Search/index.js +1 -0
  27. package/dist/components/Table/TableBody.d.ts +20 -0
  28. package/dist/components/Table/TableBody.d.ts.map +1 -0
  29. package/dist/components/Table/TableBody.js +56 -0
  30. package/dist/components/Table/TableHeader.d.ts +13 -0
  31. package/dist/components/Table/TableHeader.d.ts.map +1 -0
  32. package/dist/components/Table/TableHeader.js +24 -0
  33. package/dist/components/Table/index.d.ts +3 -0
  34. package/dist/components/Table/index.d.ts.map +1 -0
  35. package/dist/components/Table/index.js +2 -0
  36. package/dist/hooks/index.d.ts +2 -0
  37. package/dist/hooks/index.d.ts.map +1 -0
  38. package/dist/hooks/index.js +1 -0
  39. package/dist/hooks/useDataGrid.d.ts +49 -0
  40. package/dist/hooks/useDataGrid.d.ts.map +1 -0
  41. package/dist/hooks/useDataGrid.js +356 -0
  42. package/dist/index.d.ts +7 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +8 -0
  45. package/dist/setupTests.d.ts +12 -0
  46. package/dist/setupTests.d.ts.map +1 -0
  47. package/dist/setupTests.js +1 -0
  48. package/dist/themes/index.d.ts +22 -0
  49. package/dist/themes/index.d.ts.map +1 -0
  50. package/dist/themes/index.js +31 -0
  51. package/dist/types/index.d.ts +108 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/types/index.js +1 -0
  54. package/dist/utils/index.d.ts +12 -0
  55. package/dist/utils/index.d.ts.map +1 -0
  56. package/dist/utils/index.js +209 -0
  57. package/package.json +80 -0
@@ -0,0 +1,209 @@
1
+ // Data formatting utilities (keeping existing ones)
2
+ export const formatters = {
3
+ date: (value, includeTime = false) => {
4
+ if (!value)
5
+ return '';
6
+ const date = new Date(value);
7
+ return includeTime ? date.toLocaleString() : date.toLocaleDateString();
8
+ },
9
+ currency: (value, currency = 'USD') => {
10
+ return new Intl.NumberFormat('en-US', {
11
+ style: 'currency',
12
+ currency,
13
+ }).format(value);
14
+ },
15
+ number: (value, decimals = 0) => {
16
+ return new Intl.NumberFormat('en-US', {
17
+ minimumFractionDigits: decimals,
18
+ maximumFractionDigits: decimals,
19
+ }).format(value);
20
+ },
21
+ truncate: (text, length) => {
22
+ if (!text || text.length <= length)
23
+ return text;
24
+ return text.substring(0, length) + '...';
25
+ },
26
+ };
27
+ // Filter comparison functions (keeping existing implementation)
28
+ export const compareValues = (dataValue, filterValue, operator, dataType) => {
29
+ if (dataValue == null)
30
+ return false;
31
+ switch (dataType) {
32
+ case 'string':
33
+ const str = dataValue.toString().toLowerCase();
34
+ const filter = filterValue.toString().toLowerCase();
35
+ switch (operator) {
36
+ case 'eq':
37
+ return str === filter;
38
+ case 'contains':
39
+ return str.includes(filter);
40
+ case 'startsWith':
41
+ return str.startsWith(filter);
42
+ case 'endsWith':
43
+ return str.endsWith(filter);
44
+ default:
45
+ return str.includes(filter);
46
+ }
47
+ case 'number':
48
+ const num = parseFloat(dataValue);
49
+ const filterNum = parseFloat(filterValue);
50
+ switch (operator) {
51
+ case 'eq':
52
+ return num === filterNum;
53
+ case 'gt':
54
+ return num > filterNum;
55
+ case 'gte':
56
+ return num >= filterNum;
57
+ case 'lt':
58
+ return num < filterNum;
59
+ case 'lte':
60
+ return num <= filterNum;
61
+ default:
62
+ return num === filterNum;
63
+ }
64
+ case 'date':
65
+ case 'datetime':
66
+ const date = new Date(dataValue).getTime();
67
+ const filterDate = new Date(filterValue).getTime();
68
+ switch (operator) {
69
+ case 'eq':
70
+ return date === filterDate;
71
+ case 'gt':
72
+ return date > filterDate;
73
+ case 'gte':
74
+ return date >= filterDate;
75
+ case 'lt':
76
+ return date < filterDate;
77
+ case 'lte':
78
+ return date <= filterDate;
79
+ default:
80
+ return date === filterDate;
81
+ }
82
+ case 'boolean':
83
+ return Boolean(dataValue) === Boolean(filterValue);
84
+ default:
85
+ return String(dataValue).toLowerCase().includes(String(filterValue).toLowerCase());
86
+ }
87
+ };
88
+ // Simplified API utilities
89
+ export const createApiRequest = async (endpoint, request, config = {}) => {
90
+ const { method = 'GET', bearerToken, apiKey, customHeaders = {}, withCredentials = false, timeout = 30000, } = config;
91
+ // Build headers
92
+ const headers = {
93
+ 'Content-Type': 'application/json',
94
+ ...customHeaders,
95
+ };
96
+ if (bearerToken) {
97
+ headers.Authorization = `Bearer ${bearerToken}`;
98
+ }
99
+ if (apiKey) {
100
+ headers['X-API-Key'] = apiKey;
101
+ }
102
+ // Build request
103
+ const requestOptions = {
104
+ method,
105
+ headers,
106
+ credentials: withCredentials ? 'include' : 'same-origin',
107
+ };
108
+ let url = endpoint;
109
+ if (method === 'POST') {
110
+ requestOptions.body = JSON.stringify({ request });
111
+ }
112
+ else {
113
+ const params = new URLSearchParams({ request: JSON.stringify(request) });
114
+ url = `${endpoint}?${params.toString()}`;
115
+ }
116
+ // Create timeout
117
+ const controller = new AbortController();
118
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
119
+ requestOptions.signal = controller.signal;
120
+ try {
121
+ const response = await fetch(url, requestOptions);
122
+ clearTimeout(timeoutId);
123
+ if (!response.ok) {
124
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
125
+ }
126
+ const data = await response.json();
127
+ return mapServerResponse(data);
128
+ }
129
+ catch (error) {
130
+ clearTimeout(timeoutId);
131
+ throw error;
132
+ }
133
+ };
134
+ // Simplified server response mapping with flexible casing
135
+ export const mapServerResponse = (data) => {
136
+ // Helper to get value with flexible casing
137
+ const getValue = (obj, keys) => {
138
+ for (const key of keys) {
139
+ if (obj[key] !== undefined)
140
+ return obj[key];
141
+ }
142
+ return undefined;
143
+ };
144
+ // Get items with flexible casing
145
+ const items = getValue(data, ['Items', 'items', 'data', 'Data']);
146
+ // Get continuation token with flexible casing
147
+ const continuationToken = getValue(data, [
148
+ 'ContinuationToken',
149
+ 'continuationToken',
150
+ 'continuationtoken',
151
+ 'nextToken',
152
+ 'next_token',
153
+ 'NextToken',
154
+ ]);
155
+ // Get hasMore with flexible casing
156
+ const hasMore = getValue(data, [
157
+ 'HasMore',
158
+ 'hasMore',
159
+ 'hasmore',
160
+ 'has_more',
161
+ 'hasNextPage',
162
+ 'has_next_page',
163
+ ]);
164
+ // Get count with flexible casing
165
+ const count = getValue(data, ['Count', 'count', 'COUNT', 'total', 'Total', 'length', 'size']);
166
+ // Direct mapping for arrays
167
+ if (Array.isArray(data)) {
168
+ return {
169
+ Items: data,
170
+ HasMore: false,
171
+ Count: data.length,
172
+ };
173
+ }
174
+ // AWS DynamoDB style response (special case)
175
+ if (data.Items && data.LastEvaluatedKey) {
176
+ return {
177
+ Items: data.Items,
178
+ ContinuationToken: JSON.stringify(data.LastEvaluatedKey),
179
+ HasMore: !!data.LastEvaluatedKey,
180
+ Count: data.Count || data.Items.length,
181
+ };
182
+ }
183
+ // Standard response mapping
184
+ return {
185
+ Items: Array.isArray(items) ? items : [],
186
+ ContinuationToken: continuationToken,
187
+ HasMore: Boolean(hasMore),
188
+ Count: Number(count) || 0,
189
+ };
190
+ };
191
+ // Sorting utilities (keeping existing implementation)
192
+ export const sortData = (data, sortColumn, direction) => {
193
+ if (!sortColumn)
194
+ return data;
195
+ return [...data].sort((a, b) => {
196
+ const aVal = a[sortColumn];
197
+ const bVal = b[sortColumn];
198
+ if (aVal == null && bVal == null)
199
+ return 0;
200
+ if (aVal == null)
201
+ return 1;
202
+ if (bVal == null)
203
+ return -1;
204
+ const aStr = String(aVal).toLowerCase();
205
+ const bStr = String(bVal).toLowerCase();
206
+ const result = aStr.localeCompare(bStr, undefined, { numeric: true });
207
+ return direction === 'desc' ? -result : result;
208
+ });
209
+ };
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@reactorui/datagrid",
3
+ "version": "1.0.0",
4
+ "description": "High-performance React data grid with TypeScript support, server-side integration, and continuation token pagination",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "npm run clean && tsc",
15
+ "build:rollup": "npm run clean && rollup -c",
16
+ "clean": "rm -rf dist",
17
+ "test": "jest",
18
+ "test:watch": "jest --watch",
19
+ "test:coverage": "jest --coverage",
20
+ "lint": "echo 'Linting skipped for now'",
21
+ "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
22
+ "typecheck": "tsc --noEmit",
23
+ "prepublishOnly": "npm run build && npm run test"
24
+ },
25
+ "keywords": [
26
+ "react",
27
+ "datagrid",
28
+ "table",
29
+ "data-table",
30
+ "grid",
31
+ "reactor",
32
+ "typescript",
33
+ "performance",
34
+ "pagination",
35
+ "continuation-token",
36
+ "server-side",
37
+ "filtering",
38
+ "sorting"
39
+ ],
40
+ "author": "ReactorUI",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/reactorui/datagrid.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/reactorui/datagrid/issues"
48
+ },
49
+ "homepage": "https://reactorui.dev",
50
+ "peerDependencies": {
51
+ "react": ">=16.8.0",
52
+ "react-dom": ">=16.8.0"
53
+ },
54
+ "devDependencies": {
55
+ "@rollup/plugin-commonjs": "^25.0.7",
56
+ "@rollup/plugin-node-resolve": "^15.2.3",
57
+ "@rollup/plugin-terser": "^0.4.4",
58
+ "@rollup/plugin-typescript": "^11.1.5",
59
+ "@testing-library/jest-dom": "^6.1.5",
60
+ "@testing-library/react": "^13.4.0",
61
+ "@testing-library/user-event": "^14.5.1",
62
+ "@types/jest": "^29.5.8",
63
+ "@types/node": "^20.10.5",
64
+ "@types/react": "^18.2.45",
65
+ "@types/react-dom": "^18.2.18",
66
+ "jest": "^29.7.0",
67
+ "jest-environment-jsdom": "^29.7.0",
68
+ "prettier": "^3.1.1",
69
+ "react": "^18.2.0",
70
+ "react-dom": "^18.2.0",
71
+ "rollup": "^4.9.1",
72
+ "rollup-plugin-dts": "^6.1.0",
73
+ "rollup-plugin-peer-deps-external": "^2.2.4",
74
+ "ts-jest": "^29.1.1",
75
+ "typescript": "^5.3.3"
76
+ },
77
+ "publishConfig": {
78
+ "access": "public"
79
+ }
80
+ }