funuicss 3.3.9 → 3.3.10

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/css/fun.css CHANGED
@@ -3528,15 +3528,13 @@ background-color: rgba(var(--borderRgb), 0.3);
3528
3528
  display: flex;
3529
3529
  align-items: center;
3530
3530
  justify-content: space-between;
3531
- padding: var(--inputRoundedPadding);
3531
+ padding: var(--inputRoundedPadding);
3532
3532
  background: inherit;
3533
3533
  border: var(--border);
3534
3534
  border-radius: var(--InputButtonBorderRadius);
3535
3535
  cursor: pointer;
3536
3536
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
3537
3537
  font-size: 14px;
3538
- line-height: 1.5;
3539
- min-height: 48px;
3540
3538
  user-select: none;
3541
3539
  outline: none;
3542
3540
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.3.9",
2
+ "version": "3.3.10",
3
3
  "name": "funuicss",
4
4
  "description": "React and Next.js component UI Library for creating Easy and good looking websites with fewer lines of code. Elevate your web development experience with our cutting-edge React/Next.js component UI Library. Craft stunning websites effortlessly, boasting both seamless functionality and aesthetic appeal—all achieved with minimal lines of code. Unleash the power of simplicity and style in your projects!",
5
5
  "main": "index.js",
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Cleans data by removing columns that contain objects
3
+ * and ensures all values are primitive types (string, number, boolean, null)
4
+ */
5
+ export declare const cleanDataForExport: (data: any[]) => any[];
6
+ /**
7
+ * Enhanced export function with automatic data cleaning
8
+ */
9
+ export declare const ExportData: (filteredData: any, title?: any, selectedField?: any) => void;
10
+ /**
11
+ * Alternative export function that logs what was cleaned (for debugging)
12
+ */
13
+ export declare const ExportDataWithLog: (filteredData: any, title?: any, selectedField?: any) => void;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExportDataWithLog = exports.ExportData = exports.cleanDataForExport = void 0;
4
+ var react_easy_export_1 = require("react-easy-export");
5
+ /**
6
+ * Cleans data by removing columns that contain objects
7
+ * and ensures all values are primitive types (string, number, boolean, null)
8
+ */
9
+ var cleanDataForExport = function (data) {
10
+ if (!data || data.length === 0)
11
+ return [];
12
+ // Get all unique keys from all objects
13
+ var allKeys = new Set();
14
+ data.forEach(function (item) {
15
+ if (item && typeof item === 'object') {
16
+ Object.keys(item).forEach(function (key) { return allKeys.add(key); });
17
+ }
18
+ });
19
+ // Identify columns that contain objects
20
+ var columnsWithObjects = new Set();
21
+ allKeys.forEach(function (key) {
22
+ var hasObject = data.some(function (item) {
23
+ var value = item === null || item === void 0 ? void 0 : item[key];
24
+ return value !== null &&
25
+ value !== undefined &&
26
+ typeof value === 'object' &&
27
+ !Array.isArray(value) &&
28
+ !(value instanceof Date);
29
+ });
30
+ if (hasObject) {
31
+ columnsWithObjects.add(key);
32
+ }
33
+ });
34
+ // Clean the data by removing problematic columns and converting values
35
+ return data.map(function (item) {
36
+ if (!item || typeof item !== 'object')
37
+ return item;
38
+ var cleanedItem = {};
39
+ Object.keys(item).forEach(function (key) {
40
+ // Skip columns that contain objects
41
+ if (columnsWithObjects.has(key)) {
42
+ return;
43
+ }
44
+ var value = item[key];
45
+ // Handle different value types
46
+ if (value === null || value === undefined) {
47
+ cleanedItem[key] = '';
48
+ }
49
+ else if (Array.isArray(value)) {
50
+ // Convert arrays to comma-separated strings
51
+ cleanedItem[key] = value.join(', ');
52
+ }
53
+ else if (value instanceof Date) {
54
+ // Convert dates to ISO strings
55
+ cleanedItem[key] = value.toISOString();
56
+ }
57
+ else if (typeof value === 'object') {
58
+ // Skip objects (shouldn't reach here due to column filtering above)
59
+ return;
60
+ }
61
+ else {
62
+ // Primitive values (string, number, boolean)
63
+ cleanedItem[key] = value;
64
+ }
65
+ });
66
+ return cleanedItem;
67
+ }).filter(function (item) { return Object.keys(item).length > 0; }); // Remove empty objects
68
+ };
69
+ exports.cleanDataForExport = cleanDataForExport;
70
+ /**
71
+ * Enhanced export function with automatic data cleaning
72
+ */
73
+ var ExportData = function (filteredData, title, selectedField) {
74
+ // Clean the data before export
75
+ var cleanedData = (0, exports.cleanDataForExport)(filteredData);
76
+ // Generate filename
77
+ var filename = title
78
+ ? "".concat(title).concat(selectedField ? "_".concat(selectedField) : '', ".csv")
79
+ : 'data.csv';
80
+ // Export cleaned data
81
+ (0, react_easy_export_1.exportToCSV)(cleanedData, filename);
82
+ };
83
+ exports.ExportData = ExportData;
84
+ /**
85
+ * Alternative export function that logs what was cleaned (for debugging)
86
+ */
87
+ var ExportDataWithLog = function (filteredData, title, selectedField) {
88
+ if (!filteredData || filteredData.length === 0) {
89
+ console.warn('No data to export');
90
+ return;
91
+ }
92
+ // Get original columns
93
+ var originalColumns = Object.keys(filteredData[0] || {});
94
+ // Clean the data
95
+ var cleanedData = (0, exports.cleanDataForExport)(filteredData);
96
+ // Get cleaned columns
97
+ var cleanedColumns = cleanedData.length > 0 ? Object.keys(cleanedData[0]) : [];
98
+ // Log what was removed
99
+ var removedColumns = originalColumns.filter(function (col) { return !cleanedColumns.includes(col); });
100
+ if (removedColumns.length > 0) {
101
+ console.log('Removed columns containing objects:', removedColumns);
102
+ }
103
+ console.log('Cleaned data preview:', cleanedData.slice(0, 2));
104
+ // Generate filename
105
+ var filename = title
106
+ ? "".concat(title).concat(selectedField ? "_".concat(selectedField) : '', ".csv")
107
+ : 'data.csv';
108
+ // Export cleaned data
109
+ (0, react_easy_export_1.exportToCSV)(cleanedData, filename);
110
+ };
111
+ exports.ExportDataWithLog = ExportDataWithLog;
package/ui/table/Table.js CHANGED
@@ -74,32 +74,39 @@ var Head_1 = __importDefault(require("./Head"));
74
74
  var Body_1 = __importDefault(require("./Body"));
75
75
  var Row_1 = __importDefault(require("./Row"));
76
76
  var Data_1 = __importDefault(require("./Data"));
77
+ var Input_1 = __importDefault(require("../input/Input"));
77
78
  var react_1 = require("react");
78
79
  var RowFlex_1 = __importDefault(require("../specials/RowFlex"));
79
80
  var Button_1 = __importDefault(require("../button/Button"));
80
81
  var pi_1 = require("react-icons/pi");
81
82
  var Circle_1 = __importDefault(require("../specials/Circle"));
82
83
  var Text_1 = __importDefault(require("../text/Text"));
83
- var react_easy_export_1 = require("react-easy-export");
84
84
  var View_1 = __importDefault(require("../view/View"));
85
85
  var ScrollInView_1 = __importDefault(require("../ScrollInView/ScrollInView"));
86
86
  var Select_1 = __importDefault(require("../select/Select"));
87
+ var Export_1 = require("./Export");
88
+ var ToolTip_1 = __importDefault(require("../tooltip/ToolTip"));
89
+ var Tip_1 = __importDefault(require("../tooltip/Tip"));
90
+ var Flex_1 = __importDefault(require("../flex/Flex"));
91
+ var ci_1 = require("react-icons/ci");
87
92
  function Table(_a) {
88
93
  var _b, _c;
89
- var children = _a.children, funcss = _a.funcss, bordered = _a.bordered, noStripped = _a.noStripped, hoverable = _a.hoverable, title = _a.title, showTotal = _a.showTotal, light = _a.light, dark = _a.dark, head = _a.head, body = _a.body, data = _a.data, _d = _a.isLoading, isLoading = _d === void 0 ? false : _d, right = _a.right, hideExport = _a.hideExport, height = _a.height, _e = _a.pageSize, pageSize = _e === void 0 ? data ? 10 : 0 : _e, // Default page size,
94
+ var children = _a.children, funcss = _a.funcss, bordered = _a.bordered, noStripped = _a.noStripped, hoverable = _a.hoverable, _d = _a.title, title = _d === void 0 ? "" : _d, showTotal = _a.showTotal, light = _a.light, dark = _a.dark, head = _a.head, body = _a.body, data = _a.data, _e = _a.isLoading, isLoading = _e === void 0 ? false : _e, right = _a.right, hideExport = _a.hideExport, height = _a.height, _f = _a.pageSize, pageSize = _f === void 0 ? data ? 10 : 0 : _f, // Default page size,
90
95
  customColumns = _a.customColumns, filterableFields = _a.filterableFields, // New prop
91
96
  emptyResponse = _a.emptyResponse, filterOnchange = _a.filterOnchange, rest = __rest(_a, ["children", "funcss", "bordered", "noStripped", "hoverable", "title", "showTotal", "light", "dark", "head", "body", "data", "isLoading", "right", "hideExport", "height", "pageSize", "customColumns", "filterableFields", "emptyResponse", "filterOnchange"]);
92
97
  // Check if data is null or undefined before accessing its properties
93
98
  // Replace this in your component
94
- var _f = (0, react_1.useState)(''), search = _f[0], setSearch = _f[1];
95
- var _g = (0, react_1.useState)(1), currentPage = _g[0], setCurrentPage = _g[1];
99
+ var _g = (0, react_1.useState)(''), search = _g[0], setSearch = _g[1];
100
+ var _h = (0, react_1.useState)(1), currentPage = _h[0], setCurrentPage = _h[1];
96
101
  // Determine the total number of pages based on data length and page size
97
102
  var totalPages = data ? Math.ceil((((_b = data === null || data === void 0 ? void 0 : data.data) === null || _b === void 0 ? void 0 : _b.length) || 0) / pageSize) : 0;
98
103
  // Calculate start and end indices for data pagination
99
104
  var startIndex = data ? (currentPage - 1) * pageSize : 0;
100
105
  var endIndex = data ? Math.min(startIndex + pageSize, ((_c = data === null || data === void 0 ? void 0 : data.data) === null || _c === void 0 ? void 0 : _c.length) || 0) : 0;
101
- var _h = (0, react_1.useState)(null), selectedField = _h[0], setSelectedField = _h[1];
102
- var _j = (0, react_1.useState)(null), selectedValue = _j[0], setSelectedValue = _j[1];
106
+ var _j = (0, react_1.useState)(null), selectedField = _j[0], setSelectedField = _j[1];
107
+ var _k = (0, react_1.useState)(null), selectedValue = _k[0], setSelectedValue = _k[1];
108
+ var _l = (0, react_1.useState)(false), showSearch = _l[0], setshowSearch = _l[1];
109
+ var _m = (0, react_1.useState)(""), searchQuery = _m[0], setsearchQuery = _m[1];
103
110
  // Enhanced filter logic:
104
111
  var normalize = function (val) { return val === null || val === void 0 ? void 0 : val.toString().toLowerCase().trim(); };
105
112
  var matchesSearch = function (item) {
@@ -159,7 +166,7 @@ function Table(_a) {
159
166
  }
160
167
  // Function to export data to CSV
161
168
  var Export = function () {
162
- (0, react_easy_export_1.exportToCSV)(filteredData, title ? "".concat(title, " ").concat(selectedField ? "_".concat(selectedField) : '', ".csv") : 'data.csv');
169
+ (0, Export_1.ExportData)(filteredData, title, selectedField);
163
170
  };
164
171
  // Extract the data array
165
172
  var dataArray = data ? data.data : [];
@@ -181,50 +188,69 @@ function Table(_a) {
181
188
  showTotal && data &&
182
189
  React.createElement("div", null,
183
190
  React.createElement(Text_1.default, { text: 'Records: ', size: 'sm' }),
184
- React.createElement(Text_1.default, { text: filteredData.length, size: 'h6' })),
191
+ React.createElement(Text_1.default, { text: filteredData.length, weight: 600 })),
185
192
  title &&
186
193
  React.createElement("div", null,
187
- React.createElement(Text_1.default, { text: title || "", size: 'h4' })))
194
+ React.createElement(Text_1.default, { text: title || "", size: 'h6' })))
188
195
  :
189
196
  React.createElement(React.Fragment, null, showTotal && data &&
190
197
  React.createElement("div", null,
191
198
  React.createElement(Text_1.default, { text: 'Records: ', size: 'sm' }),
192
- React.createElement(Text_1.default, { text: filteredData.length, size: 'h6' }))),
199
+ React.createElement(Text_1.default, { text: filteredData.length, weight: 600, color: 'primary' }))),
193
200
  data && filterableFields ?
194
- React.createElement("div", { className: "col width-200-max" },
195
- React.createElement(RowFlex_1.default, { gap: 0.7 },
196
- !selectedField &&
197
- React.createElement(Select_1.default, { searchable: true, value: selectedField || '', onChange: function (e) { return handleFieldChange(e); }, options: __spreadArray([
198
- { text: '🔍 Filter', value: '' },
201
+ React.createElement("div", null,
202
+ React.createElement(Flex_1.default, { width: '100%', wrap: 'nowrap', alignItems: 'center', gap: 0.7 },
203
+ !selectedField && !showSearch &&
204
+ React.createElement(ScrollInView_1.default, null,
205
+ React.createElement(Select_1.default, { fullWidth: true, searchable: true, funcss: 'min-w-300 w-full', rounded: true, value: selectedField || '', onChange: function (e) { return handleFieldChange(e); }, options: __spreadArray([
206
+ { text: '🔍 Filter', value: '' },
207
+ { text: 'All*', value: '' }
208
+ ], (filterableFields || []).map(function (field) { return ({
209
+ text: field,
210
+ value: field
211
+ }); }), true) })),
212
+ selectedField && !showSearch && (React.createElement(ScrollInView_1.default, null,
213
+ React.createElement(Select_1.default, { rounded: true, searchable: true, funcss: 'min-w-300 w-full', fullWidth: true, value: selectedValue || '', onChange: function (e) {
214
+ if (e === 'clear_all') {
215
+ setSelectedField('');
216
+ }
217
+ else {
218
+ handleValueChange(e);
219
+ handleChangePage(1);
220
+ }
221
+ }, options: __spreadArray(__spreadArray([
199
222
  { text: 'All*', value: '' }
200
- ], (filterableFields || []).map(function (field) { return ({
201
- text: field,
202
- value: field
203
- }); }), true) }),
204
- selectedField && (React.createElement(Select_1.default, { searchable: true, funcss: "width-200-max", value: selectedValue || '', onChange: function (e) {
205
- if (e === 'clear_all') {
206
- setSelectedField('');
207
- }
208
- else {
209
- handleValueChange(e);
210
- handleChangePage(1);
211
- }
212
- }, options: __spreadArray(__spreadArray([
213
- { text: 'All*', value: '' }
214
- ], uniqueValues
215
- .filter(Boolean) // remove null/undefined/empty
216
- .map(function (item) { return ({
217
- text: item.toString(),
218
- value: item
219
- }); }), true), [
220
- { text: 'Clear', value: 'clear_all' }
221
- ], false) }))))
223
+ ], uniqueValues
224
+ .filter(Boolean) // remove null/undefined/empty
225
+ .map(function (item) { return ({
226
+ text: item.toString(),
227
+ value: item
228
+ }); }), true), [
229
+ { text: 'Clear', value: 'clear_all' }
230
+ ], false) }))),
231
+ showSearch ?
232
+ React.createElement(Flex_1.default, { gap: 0.5, wrap: 'nowrap', alignItems: 'center' },
233
+ React.createElement(ScrollInView_1.default, null,
234
+ React.createElement(Input_1.default, { borderless: true, funcss: 'min-w-300', fullWidth: true, rounded: true, value: searchQuery, onChange: function (e) { return setsearchQuery(e.target.value); }, label: "Search..." })),
235
+ React.createElement(ScrollInView_1.default, { delay: 0.2 },
236
+ React.createElement("div", { onClick: function () { return setshowSearch(false); } },
237
+ React.createElement(ToolTip_1.default, null,
238
+ React.createElement(pi_1.PiXThin, { className: 'pointer', size: 23, onClick: function () { return setshowSearch(false); } }),
239
+ React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: "Close Search" })))))
240
+ :
241
+ React.createElement(ScrollInView_1.default, { delay: 0.2 },
242
+ React.createElement(ToolTip_1.default, null,
243
+ React.createElement(ci_1.CiSearch, { className: 'pointer', size: 23, onClick: function () { return setshowSearch(true); } }),
244
+ React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: "Search Data" })))))
222
245
  : '',
223
246
  React.createElement(React.Fragment, null,
224
247
  React.createElement(RowFlex_1.default, { gap: 0.5 },
225
248
  right && right,
226
249
  !hideExport &&
227
- React.createElement(Button_1.default, { small: true, bold: true, text: 'Export', startIcon: React.createElement(pi_1.PiFileCsv, null), color: 'gradient', onClick: Export }))))),
250
+ React.createElement(ToolTip_1.default, null,
251
+ React.createElement(Circle_1.default, { bg: 'lighter', bordered: true, onClick: Export },
252
+ React.createElement(pi_1.PiExportThin, null)),
253
+ React.createElement(Tip_1.default, { tip: "bottom", animation: "Opacity", duration: 1, content: "Export Data" })))))),
228
254
  React.createElement("main", { style: { overflow: "auto", width: "100%" } },
229
255
  React.createElement("table", __assign({ className: "table ".concat(bordered ? 'border' : '', " ").concat(noStripped ? '' : 'stripped', " ").concat(hoverable ? 'hoverableTr' : '', " ").concat(light ? 'light' : '', " ").concat(dark ? 'dark' : ''), style: {
230
256
  height: height ? height + "px" : ""
@@ -236,7 +262,35 @@ function Table(_a) {
236
262
  head && React.createElement(Head_1.default, null, head),
237
263
  body && React.createElement(Body_1.default, null, body),
238
264
  data &&
239
- filteredData.slice(startIndex, endIndex).map(function (mdoc, index) { return (React.createElement(Row_1.default, { funcss: 'animated slide-down', rowKey: index },
265
+ filteredData.filter(function (mdoc, index) {
266
+ if (searchQuery) {
267
+ // Convert search query to lowercase for case-insensitive search
268
+ var query_1 = searchQuery.toLowerCase().trim();
269
+ if (!query_1)
270
+ return true; // If empty query after trim, show all
271
+ // Search through all fields defined in data.fields
272
+ return data.fields.some(function (field) {
273
+ try {
274
+ // Get the value using the same getNestedValue function used for display
275
+ var value = getNestedValue(mdoc, field);
276
+ // Convert value to string and search
277
+ if (value !== null && value !== undefined) {
278
+ var stringValue = String(value).toLowerCase();
279
+ return stringValue.includes(query_1);
280
+ }
281
+ return false;
282
+ }
283
+ catch (error) {
284
+ // Handle any errors in accessing nested values
285
+ console.warn("Error accessing field ".concat(field, ":"), error);
286
+ return false;
287
+ }
288
+ });
289
+ }
290
+ else {
291
+ return true; // If no search query, return all items
292
+ }
293
+ }).slice(startIndex, endIndex).map(function (mdoc, index) { return (React.createElement(Row_1.default, { funcss: 'animated slide-down', rowKey: index },
240
294
  data.fields.map(function (fdoc, findex) {
241
295
  var _a;
242
296
  return (React.createElement(Data_1.default, { key: fdoc, funcss: data.funcss ? ((_a = data === null || data === void 0 ? void 0 : data.funcss) === null || _a === void 0 ? void 0 : _a[findex]) || '' : '' }, getNestedValue(mdoc, fdoc)));