next-recomponents 2.0.56 → 2.0.58

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.
@@ -10,12 +10,13 @@ import React, {
10
10
  import Pre from "../pre";
11
11
  import { ContextType } from "./context";
12
12
  import { Header } from "./header";
13
- import { ExcelIcon, SearchIcon } from "./icons";
13
+ import { ExcelIcon, NextIcon, PrevIcon, SearchIcon } from "./icons";
14
14
  import Searchable from "./searchable";
15
15
  import Modal from "../modal";
16
16
  import { EditIcon } from "./icons";
17
17
  import regularExpresions, { TableProps } from "./types";
18
18
  import { valueFormatter } from "./formatter";
19
+ import usePaginacion from "./use.pagination";
19
20
  type Widths = Record<string, number>;
20
21
  export default function HTable({
21
22
  context,
@@ -120,15 +121,7 @@ export default function HTable({
120
121
  sizeadosLength -
121
122
  personalizados.length -
122
123
  ocultos.length);
123
- console.log({
124
- w,
125
- ancho,
126
- sizeadosWidth,
127
- personalizadosSum,
128
- headers,
129
- sizeadosLength,
130
- personalizados,
131
- });
124
+
132
125
  setWidths(
133
126
  Object.fromEntries(
134
127
  headers.map((h) => [
@@ -145,19 +138,24 @@ export default function HTable({
145
138
  observer.observe(tableRef.current);
146
139
  return () => observer.disconnect();
147
140
  }, [headers.length]);
148
- const searchedData = context.filteredData.filter((row) => {
149
- if (context.searchBy === "") return true;
150
141
 
151
- return Object.values(row).some((value) =>
152
- String(value).toLowerCase().includes(context.searchBy.toLowerCase()),
153
- );
154
- });
142
+ const searchedData = useMemo(() => {
143
+ return context.filteredData.filter((row) => {
144
+ if (context.searchBy === "") return true;
145
+
146
+ return Object.values(row).some((value) =>
147
+ String(value).toLowerCase().includes(context.searchBy.toLowerCase()),
148
+ );
149
+ });
150
+ }, [context.filteredData]);
151
+
152
+ const pagination = usePaginacion({ total: searchedData.length });
155
153
  return (
156
154
  <div
157
155
  className={[
158
156
  context.className,
159
157
  "bg-white relative",
160
- "p-2 border shadow rounded-2xl",
158
+ "p-2 border shadow rounded-2xl w-full rounded-lg ",
161
159
  ].join(" ")}
162
160
  ref={tableRef}
163
161
  >
@@ -180,10 +178,11 @@ export default function HTable({
180
178
  }
181
179
  return obj;
182
180
  }),
181
+ `${context.exportName}.xlsx`,
183
182
  );
184
183
  }}
185
184
  className={
186
- "flex gap-1 items-center border shadow rounded p-1 text-white bg-green-800 px-2"
185
+ "flex gap-1 items-center border shadow rounded p-1 text-white bg-green-800 p-1 text-xs"
187
186
  }
188
187
  >
189
188
  <ExcelIcon />
@@ -193,8 +192,7 @@ export default function HTable({
193
192
  {context.onSelect && (
194
193
  <button
195
194
  className={
196
- "border shadow rounded p-1 text-white px-2 " +
197
- (context.selected.length > 0 ? "bg-blue-500" : "bg-gray-500")
195
+ "border shadow rounded p-1 text-white p-1 text-xs bg-blue-500 cursor-pointer "
198
196
  }
199
197
  disabled={context.selected.length == 0}
200
198
  onClick={async (e) => {
@@ -215,7 +213,9 @@ export default function HTable({
215
213
  )}
216
214
  {context.onSave && (
217
215
  <button
218
- className={"border shadow rounded p-1 text-white px-2 bg-blue-500"}
216
+ className={
217
+ "border shadow rounded p-1 text-white p-1 text-xs bg-blue-500 cursor-pointer "
218
+ }
219
219
  onClick={async (e) => {
220
220
  setIsloading(true);
221
221
  const ex = context.filteredData.map((d) => {
@@ -230,278 +230,348 @@ export default function HTable({
230
230
  </button>
231
231
  )}
232
232
  </div>
233
- <div className="grid " style={{ gridTemplateColumns }}>
234
- {headers.map((header, i) => {
235
- if (context?.hideColumns?.includes?.(header)) return null;
236
- if (header.startsWith("_") && !header.startsWith("__")) return null;
237
- return (
238
- <div
239
- key={header}
240
- className="bg-white relative w-full bg-red-100"
241
- // style={{ position: "relative" }}
242
- >
243
- <Header
244
- padding={padding}
245
- header={header}
246
- context={context}
247
- drag={{ gridTemplateColumns, startDrag, widths }}
248
- />
249
- {i < headers.length - 1 && (
250
- <div
251
- onMouseDown={(e) => startDrag(e, header)}
252
- style={{
253
- position: "absolute",
254
- right: -3,
255
- top: 0,
256
- width: 6,
257
- height: "100%",
258
- cursor: "col-resize",
259
- background: "transparent",
260
- }}
261
- onMouseEnter={(e) =>
262
- (e.currentTarget.style.background =
263
- "var(--border-strong, #ccc)")
264
- }
265
- onMouseLeave={(e) =>
266
- (e.currentTarget.style.background = "transparent")
267
- }
233
+ <div
234
+ // className={["grid w-full bg-green-100"].join(" ")}
235
+ // style={{ gridTemplateColumns }}
236
+ >
237
+ <div
238
+ style={{
239
+ gridTemplateColumns,
240
+ width: Object.values(widths).reduce((acc, i) => acc + i, 0),
241
+ }}
242
+ className={["grid w-full "].join(" ")}
243
+ >
244
+ {headers.map((header, i) => {
245
+ if (context?.hideColumns?.includes?.(header)) return null;
246
+ if (header.startsWith("_") && !header.startsWith("__")) return null;
247
+ return (
248
+ <div
249
+ key={header}
250
+ className="bg-white relative w-full bg-red-100"
251
+ // style={{ position: "relative" }}
252
+ >
253
+ <Header
254
+ length={headers.length}
255
+ index={i}
256
+ padding={padding}
257
+ header={header}
258
+ context={context}
259
+ drag={{ gridTemplateColumns, startDrag, widths }}
268
260
  />
269
- )}
270
- </div>
271
- );
272
- })}
273
- {searchedData.map((row, rowIndex) => {
274
- const items: any[] = Object.entries(row);
261
+ {/* {i < headers.length - 1 && (
262
+ <div
263
+ onMouseDown={(e) => startDrag(e, header)}
264
+ className="hover:bg-blue-100"
265
+ style={{
266
+ position: "absolute",
267
+ right: -3,
268
+ top: 0,
269
+ width: "15px",
270
+ height: "100%",
271
+ cursor: "col-resize",
272
+ background: "transparent",
273
+ }}
274
+ onMouseEnter={(e) =>
275
+ (e.currentTarget.style.background =
276
+ "var(--border-strong, #ccc)")
277
+ }
278
+ onMouseLeave={(e) =>
279
+ (e.currentTarget.style.background = "transparent")
280
+ }
281
+ />
282
+ )} */}
283
+ </div>
284
+ );
285
+ })}
286
+ </div>
287
+ <div
288
+ style={{
289
+ gridTemplateColumns,
290
+ width: Object.values(widths).reduce((acc, i) => acc + i, 0),
291
+ }}
292
+ className={[
293
+ "grid max-h-[500px] ",
294
+ context.filteredData.length >= 5
295
+ ? "overflow-hidden overflow-y-scroll "
296
+ : "",
297
+ ].join(" ")}
298
+ >
299
+ {searchedData
300
+ .slice(pagination.inicio - 1, pagination.fin)
301
+ .map((row, rowIndex) => {
302
+ const items: any[] = Object.entries(row);
275
303
 
276
- return items.map(([key, item], i) => {
277
- if (context?.hideColumns?.includes?.(key)) return null;
278
- if (key.startsWith("_") && !key.startsWith("__")) return null;
304
+ return items.map(([key, item], i) => {
305
+ if (context?.hideColumns?.includes?.(key)) return null;
306
+ if (key.startsWith("_") && !key.startsWith("__")) return null;
279
307
 
280
- if (key == "__modal__") {
281
- return (
282
- <div
283
- onMouseEnter={(e) => setCurrentIndex(rowIndex)}
284
- key={row.id + i}
285
- style={{
286
- height: `${padding}px`,
287
- }}
288
- className={
289
- (rowIndex == currentIndex
290
- ? " bg-blue-100 "
291
- : " bg-white ") +
292
- " border-b p-2 flex items-center justify-center " +
293
- (context.searchBy &&
294
- String(item)
295
- .toLowerCase()
296
- .includes(context.searchBy.toLowerCase())
297
- ? "bg-yellow-100"
298
- : "")
299
- }
300
- >
301
- {context?.modalButton || (
302
- <button
303
- className="border shadow rounded bg-blue-500 text-white p-2 "
304
- onClick={(e) => {
305
- setCurrentIndex(rowIndex);
306
- modalRef.current?.click();
308
+ if (key == "__modal__") {
309
+ return (
310
+ <div
311
+ onMouseEnter={(e) => setCurrentIndex(rowIndex)}
312
+ key={row.id + i}
313
+ style={{
314
+ height: `${padding}px`,
307
315
  }}
316
+ className={
317
+ (rowIndex == currentIndex
318
+ ? " bg-blue-100 "
319
+ : " bg-white ") +
320
+ " border-b p-2 flex items-center justify-center " +
321
+ (context.searchBy &&
322
+ String(item)
323
+ .toLowerCase()
324
+ .includes(context.searchBy.toLowerCase())
325
+ ? "bg-yellow-100"
326
+ : "")
327
+ }
308
328
  >
309
- <EditIcon />
310
- </button>
311
- )}
312
- </div>
313
- );
314
- }
329
+ {context?.modalButton || (
330
+ <button
331
+ className="border shadow rounded bg-blue-500 text-white p-2 "
332
+ onClick={(e) => {
333
+ setCurrentIndex(rowIndex);
334
+ modalRef.current?.click();
335
+ }}
336
+ >
337
+ <EditIcon />
338
+ </button>
339
+ )}
340
+ </div>
341
+ );
342
+ }
315
343
 
316
- if (key == "__select__") {
317
- return (
318
- <div
319
- key={row.id + i}
320
- onMouseEnter={(e) => setCurrentIndex(rowIndex)}
321
- style={{
322
- height: `${padding}px`,
323
- }}
324
- className={
325
- (rowIndex == currentIndex
326
- ? " bg-blue-100 "
327
- : " bg-white ") +
328
- " border-b p-2 flex items-center justify-center " +
329
- (context.searchBy &&
330
- String(item)
331
- .toLowerCase()
332
- .includes(context.searchBy.toLowerCase())
333
- ? "bg-yellow-100"
334
- : "")
335
- }
336
- >
337
- <input
338
- type="checkbox"
339
- className="w-5 h-5 accent-blue-600 transition-all duration-300 checked:scale-110 "
340
- checked={Boolean(
341
- context.selected.find((s) => s == row?.id),
342
- )}
343
- onChange={(e) => {
344
- const newSelected = [...context.selected];
345
- const index = newSelected.findIndex((s) => s == row?.id);
346
- if (index >= 0) {
347
- newSelected.splice(index, 1);
348
- } else {
349
- newSelected.push(row?.id);
344
+ if (key == "__select__") {
345
+ return (
346
+ <div
347
+ key={row.id + i}
348
+ onMouseEnter={(e) => setCurrentIndex(rowIndex)}
349
+ style={{
350
+ height: `${padding}px`,
351
+ }}
352
+ className={
353
+ (rowIndex == currentIndex
354
+ ? " bg-blue-100 "
355
+ : " bg-white ") +
356
+ " border-b flex items-start p-2 justify-center " +
357
+ (context.searchBy &&
358
+ String(item)
359
+ .toLowerCase()
360
+ .includes(context.searchBy.toLowerCase())
361
+ ? "bg-yellow-100"
362
+ : "")
350
363
  }
351
- context.setSelected(newSelected);
352
- }}
353
- />
354
- </div>
355
- );
356
- }
357
-
358
- return (
359
- <div
360
- onMouseEnter={(e) => setCurrentIndex(rowIndex)}
361
- key={row.id + i}
362
- style={{
363
- fontSize: context.fontSize,
364
- ...(context?.wrapText
365
- ? { minHeight: `${padding}px` }
366
- : { height: `${padding}px` }),
367
- }}
368
- className={
369
- " flex justify-center items-center " +
370
- (rowIndex == currentIndex ? " bg-blue-100 " : " bg-white ") +
371
- (context.wrapText ? " text-wrap truncate " : " truncate ") +
372
- " border-b " +
373
- (context.searchBy &&
374
- String(item)
375
- .toLowerCase()
376
- .includes(context.searchBy.toLowerCase())
377
- ? rowIndex == currentIndex
378
- ? " bg-yellow-200 "
379
- : " bg-yellow-100 "
380
- : "")
364
+ >
365
+ <input
366
+ type="checkbox"
367
+ className="w-5 h-5 accent-blue-600 transition-all duration-300 checked:scale-110 "
368
+ checked={Boolean(
369
+ context.selected.find((s) => s == row?.id),
370
+ )}
371
+ onChange={(e) => {
372
+ const newSelected = [...context.selected];
373
+ const index = newSelected.findIndex(
374
+ (s) => s == row?.id,
375
+ );
376
+ if (index >= 0) {
377
+ newSelected.splice(index, 1);
378
+ } else {
379
+ newSelected.push(row?.id);
380
+ }
381
+ context.setSelected(newSelected);
382
+ }}
383
+ />
384
+ </div>
385
+ );
381
386
  }
382
- >
383
- {context?.editableFields &&
384
- context.editableFields.includes(key) ? (
385
- <input
386
- defaultValue={item}
387
+
388
+ return (
389
+ <div
390
+ onMouseEnter={(e) => setCurrentIndex(rowIndex)}
391
+ key={row.id + i}
392
+ style={{
393
+ fontSize: context?.fontSize || "12px",
394
+ ...(context?.wrapText
395
+ ? { minHeight: `${padding}px` }
396
+ : { height: `${padding}px` }),
397
+ }}
387
398
  className={
388
- "w-full " +
389
- (context.editions.includes(row?.id)
390
- ? "bg-blue-400 text-white"
391
- : "bg-blue-100")
399
+ " p-1" +
400
+ (rowIndex == currentIndex
401
+ ? " bg-blue-100 "
402
+ : " bg-white ") +
403
+ (context.wrapText
404
+ ? " text-wrap truncate "
405
+ : " truncate ") +
406
+ " border-b " +
407
+ (context.searchBy &&
408
+ String(item)
409
+ .toLowerCase()
410
+ .includes(context.searchBy.toLowerCase())
411
+ ? rowIndex == currentIndex
412
+ ? " bg-yellow-200 "
413
+ : " bg-yellow-100 "
414
+ : "")
392
415
  }
393
- onBlur={(e) => {
394
- const id = row?.id;
395
- const newData = [...context.data];
396
- const index = newData.findIndex((d) => +d.id == +id);
397
- newData[index][key] = e.target.value;
398
- context.setData(newData);
416
+ >
417
+ {context?.editableFields &&
418
+ context.editableFields.includes(key) ? (
419
+ <input
420
+ defaultValue={item}
421
+ className={
422
+ "w-full " +
423
+ (context.editions.includes(row?.id)
424
+ ? "bg-blue-400 text-white"
425
+ : "bg-blue-100")
426
+ }
427
+ onBlur={(e) => {
428
+ const id = row?.id;
429
+ const newData = [...context.data];
430
+ const index = newData.findIndex((d) => +d.id == +id);
431
+ newData[index][key] = e.target.value;
432
+ context.setData(newData);
399
433
 
400
- const newEditions = [
401
- ...new Set([...context.editions, id]),
402
- ];
403
- context.setEditions(newEditions);
404
- }}
405
- />
406
- ) : context.buttons?.[key] ? (
407
- React.cloneElement(context.buttons[key], {
408
- // children: context.buttons[key]?.props?.children
409
- // ? item
410
- // : undefined,
411
- value: item,
412
- children: context.buttons[key]?.props?.children
413
- ? item
414
- : null,
415
- onClick: async (e: any) => {
416
- const ret =
417
- (await context.buttons[key].props?.onClick?.({
418
- e,
419
- row,
420
- })) || {};
421
- const newData = [...context.data];
422
- const index = newData.findIndex((f) => f.id == row?.id);
423
- newData[index] = { ...newData[index], ...ret };
424
- context.setData(newData);
425
- },
426
- onChange: async (e: { target: { value: string } }) => {
427
- const value = e.target.value;
428
- const ret =
429
- (await context.buttons[key].props?.onChange?.({
430
- e,
431
- row,
432
- })) || {};
434
+ const newEditions = [
435
+ ...new Set([...context.editions, id]),
436
+ ];
437
+ context.setEditions(newEditions);
438
+ }}
439
+ />
440
+ ) : context.buttons?.[key] ? (
441
+ React.cloneElement(context.buttons[key], {
442
+ // children: context.buttons[key]?.props?.children
443
+ // ? item
444
+ // : undefined,
445
+ value: item,
446
+ children: context.buttons[key]?.props?.children
447
+ ? item
448
+ : null,
449
+ onClick: async (e: any) => {
450
+ const ret =
451
+ (await context.buttons[key].props?.onClick?.({
452
+ e,
453
+ row,
454
+ })) || {};
455
+ const newData = [...context.data];
456
+ const index = newData.findIndex(
457
+ (f) => f.id == row?.id,
458
+ );
459
+ newData[index] = { ...newData[index], ...ret };
460
+ context.setData(newData);
461
+ },
462
+ onChange: async (e: { target: { value: string } }) => {
463
+ const value = e.target.value;
464
+ const ret =
465
+ (await context.buttons[key].props?.onChange?.({
466
+ e,
467
+ row,
468
+ })) || {};
433
469
 
434
- const newData = [...context.data];
435
- const index = newData.findIndex((f) => f.id == row?.id);
470
+ const newData = [...context.data];
471
+ const index = newData.findIndex(
472
+ (f) => f.id == row?.id,
473
+ );
436
474
 
437
- if (index >= 0) {
438
- newData[index][key] = value;
439
- }
475
+ if (index >= 0) {
476
+ newData[index][key] = value;
477
+ }
440
478
 
441
- for (let i in ret) {
442
- if (newData[index]?.[i]) {
443
- const v = ret[i];
444
- newData[index][i] = v;
445
- }
446
- }
479
+ for (let i in ret) {
480
+ if (newData[index]?.[i]) {
481
+ const v = ret[i];
482
+ newData[index][i] = v;
483
+ }
484
+ }
447
485
 
448
- context.setData(newData);
449
- },
450
- })
451
- ) : ["number", "string"].includes(typeof item) ? (
452
- valueFormatter({
453
- value: item,
486
+ context.setData(newData);
487
+ },
488
+ })
489
+ ) : ["number", "string"].includes(typeof item) ? (
490
+ valueFormatter({
491
+ value: item,
492
+ currentCoin: context.currentCoin,
493
+ })
494
+ ) : React.isValidElement(item) ? (
495
+ item
496
+ ) : (
497
+ JSON.stringify(item)
498
+ )}
499
+ </div>
500
+ );
501
+ });
502
+ })}
503
+ </div>
504
+ <div
505
+ style={{
506
+ gridTemplateColumns,
507
+ width: Object.values(widths).reduce((acc, i) => acc + i, 0),
508
+ }}
509
+ className={["grid border-b bg-white"].join(" ")}
510
+ >
511
+ {Object.keys(context?.footer || {}).length > 0 &&
512
+ headers.map((header) => {
513
+ if (context?.hideColumns?.includes?.(header)) return null;
514
+ if (header.startsWith("_") && !header.startsWith("__"))
515
+ return null;
516
+ return (
517
+ <div
518
+ key={header}
519
+ style={{
520
+ // height: `${padding}px`,
521
+ maxHeight: "100px",
522
+ }}
523
+ title={context.footer?.[header] + " de " + header}
524
+ className={
525
+ " cursor-default font-bold " +
526
+ " bg-white flex items-center justify-center" +
527
+ " text-xs my-5 " +
528
+ (context.footer?.[header] ? " border-r border-l " : "")
529
+ }
530
+ >
531
+ {valueFormatter({
454
532
  currentCoin: context.currentCoin,
455
- })
456
- ) : React.isValidElement(item) ? (
457
- item
458
- ) : (
459
- JSON.stringify(item)
460
- )}
461
- </div>
462
- );
463
- });
464
- })}
465
- {Object.keys(context?.footer || {}).length > 0 &&
466
- headers.map((header) => {
467
- if (context?.hideColumns?.includes?.(header)) return null;
468
- if (header.startsWith("_") && !header.startsWith("__")) return null;
469
- return (
470
- <div
471
- key={header}
472
- style={{
473
- height: `${padding}px`,
474
- maxHeight: "100px",
475
- }}
476
- className={
477
- "border-b font-bold " +
478
- " bg-white flex items-center justify-center"
479
- }
480
- >
481
- {valueFormatter({
482
- currentCoin: context.currentCoin,
483
- value: context.footer?.[header]
484
- ? context.footer[header] == "sum"
485
- ? context.filteredData
486
- .map((d) => +d[header])
487
- .reduce((acc, h) => h + acc, 0)
488
- : context.footer[header] == "count"
533
+ value: context.footer?.[header]
534
+ ? context.footer[header] == "sum"
489
535
  ? context.filteredData
490
- .map((d) => (d[header] != "" ? 1 : 0))
491
- .reduce((acc: number, h) => acc + h, 0)
492
- : context.footer[header] == "avg"
536
+ .map((d) => +d[header])
537
+ .reduce((acc, h) => h + acc, 0)
538
+ : context.footer[header] == "count"
493
539
  ? context.filteredData
494
- .map((d) => +d[header])
495
- .reduce((acc, h) => h + acc, 0) /
496
- context.filteredData
497
540
  .map((d) => (d[header] != "" ? 1 : 0))
498
541
  .reduce((acc: number, h) => acc + h, 0)
499
- : ""
500
- : "",
501
- })}
502
- </div>
503
- );
504
- })}
542
+ : context.footer[header] == "avg"
543
+ ? context.filteredData
544
+ .map((d) => +d[header])
545
+ .reduce((acc, h) => h + acc, 0) /
546
+ context.filteredData
547
+ .map((d) => (d[header] != "" ? 1 : 0))
548
+ .reduce((acc: number, h) => acc + h, 0)
549
+ : ""
550
+ : "",
551
+ })}
552
+ </div>
553
+ );
554
+ })}
555
+ </div>
556
+ {searchedData.length > 100 && (
557
+ <div className="flex justify-end p-2">
558
+ {pagination.rango} de {pagination.total}
559
+ <div className="flex items-center gap-5 mx-5">
560
+ <button
561
+ onClick={(e) => pagination.hasPrev && pagination.prev()}
562
+ className={pagination.hasPrev ? "" : "text-gray-300"}
563
+ >
564
+ <PrevIcon />
565
+ </button>
566
+ <button
567
+ onClick={(e) => pagination.hasNext && pagination.next()}
568
+ className={pagination.hasNext ? "" : "text-gray-300"}
569
+ >
570
+ <NextIcon />
571
+ </button>
572
+ </div>
573
+ </div>
574
+ )}
505
575
  </div>
506
576
 
507
577
  {context.modal && (