next-recomponents 1.7.63 → 1.8.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.
@@ -1,116 +0,0 @@
1
- export default function FilterIcon() {
2
- return (
3
- <svg
4
- stroke="currentColor"
5
- fill="currentColor"
6
- strokeWidth="0"
7
- viewBox="0 0 576 512"
8
- height="1rem"
9
- width="1rem"
10
- xmlns="http://www.w3.org/2000/svg"
11
- >
12
- <path d="M3.9 22.9C10.5 8.9 24.5 0 40 0L472 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L396.4 195.6C316.2 212.1 256 283 256 368c0 27.4 6.3 53.4 17.5 76.5c-1.6-.8-3.2-1.8-4.7-2.9l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 65.3C-.7 53.4-2.8 36.8 3.9 22.9zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm59.3 107.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L432 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L409.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L432 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L454.6 368l36.7-36.7z"></path>
13
- </svg>
14
- );
15
- }
16
-
17
- export function MdOutlineFirstPage() {
18
- return (
19
- <svg
20
- stroke="currentColor"
21
- fill="currentColor"
22
- strokeWidth="0"
23
- viewBox="0 0 24 24"
24
- height="1rem"
25
- width="1rem"
26
- xmlns="http://www.w3.org/2000/svg"
27
- >
28
- <path fill="none" d="M24 0v24H0V0h24z" opacity=".87"></path>
29
- <path d="M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6 1.41-1.41zM6 6h2v12H6V6z"></path>
30
- </svg>
31
- );
32
- }
33
-
34
- export function MdOutlineLastPage() {
35
- return (
36
- <svg
37
- stroke="currentColor"
38
- fill="currentColor"
39
- strokeWidth="0"
40
- viewBox="0 0 24 24"
41
- height="1rem"
42
- width="1rem"
43
- xmlns="http://www.w3.org/2000/svg"
44
- >
45
- <path fill="none" d="M0 0h24v24H0V0z" opacity=".87"></path>
46
- <path d="M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6-1.41 1.41zM16 6h2v12h-2V6z"></path>
47
- </svg>
48
- );
49
- }
50
- export function GrFormNext() {
51
- return (
52
- <svg
53
- stroke="currentColor"
54
- fill="currentColor"
55
- strokeWidth="0"
56
- viewBox="0 0 24 24"
57
- height="1rem"
58
- width="1rem"
59
- xmlns="http://www.w3.org/2000/svg"
60
- >
61
- <polyline fill="none" strokeWidth="2" points="9 6 15 12 9 18"></polyline>
62
- </svg>
63
- );
64
- }
65
- export function GrFormPrevious() {
66
- return (
67
- <svg
68
- stroke="currentColor"
69
- fill="currentColor"
70
- strokeWidth="0"
71
- viewBox="0 0 24 24"
72
- height="1rem"
73
- width="1rem"
74
- xmlns="http://www.w3.org/2000/svg"
75
- >
76
- <polyline
77
- fill="none"
78
- strokeWidth="2"
79
- points="9 6 15 12 9 18"
80
- transform="matrix(-1 0 0 1 24 0)"
81
- ></polyline>
82
- </svg>
83
- );
84
- }
85
-
86
- export function RiFileExcel2Fill() {
87
- return (
88
- <svg
89
- stroke="currentColor"
90
- fill="currentColor"
91
- strokeWidth="0"
92
- viewBox="0 0 24 24"
93
- height="1rem"
94
- width="1rem"
95
- xmlns="http://www.w3.org/2000/svg"
96
- >
97
- <path d="M2.85858 2.87732L15.4293 1.0815C15.7027 1.04245 15.9559 1.2324 15.995 1.50577C15.9983 1.52919 16 1.55282 16 1.57648V22.4235C16 22.6996 15.7761 22.9235 15.5 22.9235C15.4763 22.9235 15.4527 22.9218 15.4293 22.9184L2.85858 21.1226C2.36593 21.0522 2 20.6303 2 20.1327V3.86727C2 3.36962 2.36593 2.9477 2.85858 2.87732ZM17 2.99997H21C21.5523 2.99997 22 3.44769 22 3.99997V20C22 20.5523 21.5523 21 21 21H17V2.99997ZM10.2 12L13 7.99997H10.6L9 10.2857L7.39999 7.99997H5L7.8 12L5 16H7.39999L9 13.7143L10.6 16H13L10.2 12Z"></path>
98
- </svg>
99
- );
100
- }
101
- export function IoIosSave() {
102
- return (
103
- <svg
104
- stroke="currentColor"
105
- fill="currentColor"
106
- strokeWidth="0"
107
- viewBox="0 0 512 512"
108
- height="1rem"
109
- width="1rem"
110
- xmlns="http://www.w3.org/2000/svg"
111
- >
112
- <path d="M272 64h-16c-4.4 0-8 3.6-8 8v72c0 4.4 7.6 8 12 8h12c4.4 0 8-3.6 8-8V72c0-4.4-3.6-8-8-8z"></path>
113
- <path d="M433.9 130.1L382 78.2c-9-9-21.3-14.2-34.1-14.2h-28c-8.8 0-16 7.3-16 16.2v80c0 8.8-7.2 16-16 16H160c-8.8 0-16-7.2-16-16v-80c0-8.8-7.2-16.2-16-16.2H96c-17.6 0-32 14.4-32 32v320c0 17.6 14.4 32 32 32h320c17.6 0 32-14.4 32-32V164c0-12.7-5.1-24.9-14.1-33.9zM322 400.1c0 8.8-8 16-17.8 16H143.8c-9.8 0-17.8-7.2-17.8-16v-96c0-8.8 8-16 17.8-16h160.4c9.8 0 17.8 7.2 17.8 16v96z"></path>
114
- </svg>
115
- );
116
- }
@@ -1,70 +0,0 @@
1
- "use client";
2
- import React, {
3
- DetailedHTMLProps,
4
- TableHTMLAttributes,
5
- useEffect,
6
- useState,
7
- } from "react";
8
- import useTableContext from "./context";
9
- import VTable from "./v.table";
10
- import HTable from "./h.table";
11
-
12
- interface TableProps
13
- extends DetailedHTMLProps<
14
- TableHTMLAttributes<HTMLTableElement>,
15
- HTMLTableElement
16
- > {
17
- data: Record<string, any>[];
18
- maxItems?: number;
19
- symbols?: Record<string, React.ReactNode>;
20
- handlers?: Record<string, React.ReactNode>;
21
- onSave?: (data: Record<string, any>[]) => void;
22
- exportName?: string;
23
- selectItems?: boolean;
24
- colSizes?: Record<string, number>;
25
- }
26
-
27
- export default function TableDos({
28
- data,
29
- maxItems = Infinity,
30
- symbols = {},
31
- handlers = {},
32
- onSave,
33
- exportName,
34
- selectItems,
35
- colSizes,
36
- ...props
37
- }: TableProps) {
38
- if (data.length == 0) return null;
39
-
40
- const [myData, setMyData] = useState(data);
41
-
42
- const isArray = Array.isArray(data);
43
-
44
- const context = useTableContext({
45
- data: myData,
46
- maxItems,
47
- symbols,
48
- handlers,
49
- onSave,
50
- exportName,
51
- selectItems,
52
- colSizes,
53
- });
54
-
55
- useEffect(() => {
56
- setMyData(data);
57
- }, [data]);
58
-
59
- if (!context) return null;
60
-
61
- return (
62
- <>
63
- {isArray ? (
64
- <VTable context={context} {...props} />
65
- ) : (
66
- <HTable context={context} />
67
- )}
68
- </>
69
- );
70
- }
@@ -1,155 +0,0 @@
1
- import React, { useCallback, useMemo } from "react";
2
- import { TableContextType } from "./context";
3
-
4
- interface RowProps {
5
- rowKey: string;
6
- context: TableContextType;
7
- handleCheck: (key: string, checked: boolean) => void;
8
- }
9
-
10
- // Memoizamos cada fila
11
- const Row = React.memo(
12
- ({ rowKey, context, handleCheck }: RowProps) => {
13
- const rowData = context.defaultData[rowKey];
14
-
15
- return (
16
- <tr className="hover:bg-gray-200">
17
- {context.selectItems && (
18
- <th className="border-b">
19
- <input
20
- type="checkbox"
21
- className="w-5 h-5 accent-green-500"
22
- checked={!!rowData?._checkedItem}
23
- onChange={(e) => handleCheck(rowKey, e.target.checked)}
24
- />
25
- </th>
26
- )}
27
-
28
- {context.headers.map((header, index) => {
29
- if (header.startsWith("_")) return null;
30
-
31
- const value = rowData[header];
32
-
33
- if (context.handlers?.[header]) {
34
- return (
35
- <td className="p-1 w-[100px]" key={index}>
36
- {React.isValidElement(context.handlers[header]) &&
37
- React.cloneElement(context.handlers[header] as any, {
38
- value,
39
- onChange: (e: any) => {
40
- const result = (
41
- context.handlers[header] as any
42
- )?.props?.onChange?.(e);
43
- const newData = { ...context.defaultData };
44
- for (let item in result) {
45
- newData[rowKey][item] = result[item];
46
- }
47
- newData[rowKey][header] = e.target.value;
48
- context.setDefaultData(newData);
49
- },
50
- })}
51
- </td>
52
- );
53
- } else {
54
- const updateRow = (data: any) => {
55
- const newData = { ...context.defaultData };
56
- for (let item in data) {
57
- newData[rowKey][item] = data[item];
58
- }
59
- context.setDefaultData(newData);
60
- };
61
-
62
- return (
63
- <td className="p-1 w-[100px] border-b" key={index}>
64
- {context.symbols?.[header] ? (
65
- <div className="flex justify-between w-full">
66
- <div>
67
- {React.isValidElement(context.symbols?.[header]) &&
68
- React.cloneElement(context.symbols?.[header] as any, {
69
- row: rowData,
70
- updateRow,
71
- onClick: (e: any) => {
72
- e.row = rowData;
73
- e.updateRow = updateRow;
74
- (
75
- context.symbols?.[header] as any
76
- )?.props?.onClick?.(e);
77
- },
78
- })}
79
- </div>
80
- <div className="w-full px-2 py-[3px] truncate">{value}</div>
81
- </div>
82
- ) : (
83
- <div className="w-full px-2 py-[3px]">{value}</div>
84
- )}
85
- </td>
86
- );
87
- }
88
- })}
89
- </tr>
90
- );
91
- },
92
- (prev, next) => {
93
- // Solo re-renderiza si cambió la fila específica
94
- return (
95
- prev.context.defaultData[prev.rowKey] ===
96
- next.context.defaultData[next.rowKey]
97
- );
98
- }
99
- );
100
-
101
- export default function VTableBody({ context }: { context: TableContextType }) {
102
- const handleCheck = useCallback((key: string, checked: boolean) => {
103
- context.setDefaultData((prev: any) => ({
104
- ...prev,
105
- [key]: { ...prev[key], _checkedItem: checked },
106
- }));
107
- }, []);
108
-
109
- return (
110
- <tbody className="bg-white">
111
- {context.paginatedBody.map((key) => (
112
- <Row
113
- key={key}
114
- rowKey={key}
115
- context={context}
116
- handleCheck={handleCheck}
117
- />
118
- ))}
119
- </tbody>
120
- );
121
- }
122
-
123
- // function Handler({
124
- // item,
125
- // row,
126
- // name,
127
- // context,
128
- // id,
129
- // }: {
130
- // item: React.ReactNode;
131
- // row: any;
132
- // name: string;
133
- // context: TableContextType;
134
- // id: string | number;
135
- // }) {
136
- // return (
137
- // context && (
138
- // <div>
139
- // {React.isValidElement(item) &&
140
- // React.cloneElement(item, {
141
- // value: row[name],
142
- // onChange: (e: any) => {
143
- // const newData = [...context?.defaultData];
144
- // const index = newData.findIndex((d) =>
145
- // [d._id, d.id].includes(id)
146
- // );
147
- // console.log(newData, index, name, row);
148
- // newData[index][name] = e.target.value;
149
- // context?.setDefaultData(newData);
150
- // },
151
- // })}
152
- // </div>
153
- // )
154
- // );
155
- // }
@@ -1,196 +0,0 @@
1
- import { useMemo, useState } from "react";
2
- import { TableContextType } from "./context";
3
- import FilterIcon from "./icons";
4
-
5
- export default function TH({
6
- context,
7
- h,
8
- }: {
9
- context: TableContextType;
10
- h: any;
11
- }) {
12
- if (!context) return null;
13
- if (`${h}`.startsWith("_")) return;
14
-
15
- const [search, setSearch] = useState("");
16
- const [visible, setVisible] = useState(false);
17
- const list = context.list[h];
18
- const [prev, setPrev] = useState<any[]>(context.filters[h]);
19
-
20
- const filteredList = useMemo(() => {
21
- return list.filter((item: any) => {
22
- if (!search) return true;
23
-
24
- return item?.toString().toLowerCase().includes(search.toLowerCase());
25
- });
26
- }, [list, search]);
27
-
28
- const colSize = context?.colSizes?.[h] || 100;
29
- const hasFilter = useMemo(
30
- () => !Object.values(context.filters[h]).every((p) => p === true),
31
- [context.filters[h]]
32
- );
33
-
34
- return (
35
- <th className="p-1 relative" style={{ zIndex: 9 }}>
36
- <div className={" min-w-[" + colSize + "px] resize-x overflow-auto"}>
37
- <div className="flex justify-between gap-2 text-white p-1 shadow rounded text-center w-full font-bold text-xs">
38
- <div
39
- onClick={(e) => setVisible(!visible)}
40
- className="w-full text-center flex gap-2 justify-center cursor-pointer"
41
- >
42
- {h}{" "}
43
- {hasFilter && (
44
- <div className="text-red-500 ">
45
- <FilterIcon />
46
- </div>
47
- )}
48
- </div>
49
- </div>
50
- {visible && (
51
- <>
52
- <div
53
- className="fixed top-0 left-0 w-screen h-screen "
54
- style={{ zIndex: 10 }}
55
- onClick={(e) => setVisible(!visible)}
56
- ></div>
57
- <div
58
- className="absolute border shadow rounded w-[300px] flex flex-col gap-2 bg-white p-2 text-sm resize-x overflow-auto"
59
- style={{ zIndex: 11 }}
60
- >
61
- <form
62
- onSubmit={(e) => {
63
- e.preventDefault();
64
- setSearch("");
65
- setVisible(false);
66
- context.setPage(1);
67
- const p = {
68
- ...Object.keys(prev).reduce((acc, i) => {
69
- if (search != "") {
70
- acc[i] = i
71
- .toString()
72
- .toLowerCase()
73
- .includes(search.toLowerCase())
74
- ? prev[i as any]
75
- : false;
76
- } else {
77
- acc[i] = prev[i as any];
78
- }
79
- return acc;
80
- }, {} as any),
81
- };
82
- setPrev(p);
83
-
84
- context.setFilters((nf: any) => {
85
- return { ...nf, [h]: p };
86
- });
87
- }}
88
- >
89
- {hasFilter && (
90
- <button
91
- type="button"
92
- className="border p-2 flex justify-center gap-2 w-full items-center text-red-500"
93
- onClick={(e) => {
94
- const p = {
95
- ...Object.keys(context.filters[h]).reduce((acc, i) => {
96
- acc[i] = true;
97
- return acc;
98
- }, {} as any),
99
- };
100
- setPrev(p);
101
- context.setFilters((nf: any) => {
102
- return { ...nf, [h]: p };
103
- });
104
- setVisible(false);
105
- }}
106
- >
107
- <FilterIcon /> Quitar Filtro
108
- </button>
109
- )}
110
- <input
111
- className="border p-1 w-full p-2"
112
- placeholder="Buscar..."
113
- type="search"
114
- onChange={(e) => setSearch(e.target.value)}
115
- value={search}
116
- />
117
- <div
118
- className="w-full h-[300px] p-2 "
119
- style={{ overflowY: "auto" }}
120
- >
121
- <label className="flex gap-2 truncate">
122
- <input
123
- type="checkbox"
124
- checked={Object.keys(prev)
125
- .filter((v) => {
126
- return v
127
- .toString()
128
- .toLowerCase()
129
- .includes(search.toLowerCase());
130
- })
131
- .every((v: any) => prev[v] === true)}
132
- onChange={(e) => {
133
- setPrev((preveN: any) => {
134
- return {
135
- ...Object.keys(preveN).reduce((acc, i) => {
136
- if (search != "") {
137
- acc[i] = i
138
- .toString()
139
- .toLowerCase()
140
- .includes(search.toLowerCase())
141
- ? !preveN[i]
142
- : false;
143
- } else {
144
- acc[i] = e.target.checked;
145
- }
146
- return acc;
147
- }, {} as any),
148
- };
149
- });
150
- }}
151
- />
152
- (Seleccionar Todo)
153
- </label>
154
- {filteredList.map((item: any, i: number) => {
155
- const checked = prev[item];
156
- const visibles = Array.from(context.filters[h]);
157
-
158
- return (
159
- <label className="flex gap-2 truncate" key={item + i}>
160
- <input
161
- type="checkbox"
162
- checked={checked}
163
- onChange={(e) => {
164
- setPrev((preveN: any) => {
165
- return { ...preveN, [item]: !checked };
166
- });
167
- }}
168
- />
169
- {item != null ? item : "(Vacio)"}
170
- </label>
171
- );
172
- })}
173
- </div>
174
- <div className="flex justify-between py-2">
175
- <button
176
- type="button"
177
- className="p-1 bg-red-500 text-white border shadow rounded"
178
- onClick={(e) => setVisible(!visible)}
179
- >
180
- Cancelar
181
- </button>
182
- <button
183
- type="submit"
184
- className="p-1 bg-blue-500 text-white border shadow rounded"
185
- >
186
- Aceptar
187
- </button>
188
- </div>
189
- </form>
190
- </div>
191
- </>
192
- )}
193
- </div>
194
- </th>
195
- );
196
- }
@@ -1,43 +0,0 @@
1
- import { TableContextType } from "./context";
2
- import TH from "./v.table.head.filter";
3
-
4
- export default function THead({ context }: { context: TableContextType }) {
5
- return (
6
- context && (
7
- <thead className="bg-blue-400">
8
- <tr className="">
9
- {context.selectItems && (
10
- <th className="border-b">
11
- <div className={""}>
12
- <div className="flex justify-between gap-2 text-white p-1 shadow rounded text-center w-full font-bold text-xs">
13
- <label className="w-full text-center flex items-center justify-center gap-1">
14
- <input
15
- type="checkbox"
16
- className="w-5 h-5 accent-green-500"
17
- defaultChecked={false}
18
- onChange={(e) => {
19
- const newData = Object.keys(context.defaultData).map(
20
- (key: any) => {
21
- const row = context.defaultData[key];
22
- return {
23
- ...row,
24
- _checkedItem: e.target.checked,
25
- };
26
- }
27
- );
28
- context.setDefaultData(newData);
29
- }}
30
- />
31
- </label>
32
- </div>
33
- </div>
34
- </th>
35
- )}
36
- {context.headers.map((h) => {
37
- return <TH key={h} h={h} context={context} />;
38
- })}
39
- </tr>
40
- </thead>
41
- )
42
- );
43
- }
@@ -1,73 +0,0 @@
1
- import { TableContextType } from "./context";
2
- import {
3
- GrFormNext,
4
- GrFormPrevious,
5
- MdOutlineFirstPage,
6
- MdOutlineLastPage,
7
- } from "./icons";
8
-
9
- export default function VtablePagination({
10
- context,
11
- }: {
12
- context: TableContextType;
13
- }) {
14
- return (
15
- context && (
16
- <div className="flex justify-center p-2 bg-gray-100 ">
17
- <div className="flex gap-2">
18
- {context.maxItems != Infinity && (
19
- <>
20
- <button
21
- onClick={() => context.setPage(1)}
22
- className="border shadow rounded p-1 bg-gray-200 hover:bg-gray-300"
23
- // disabled={!context.canPreviousPage}
24
- >
25
- <MdOutlineFirstPage />
26
- </button>
27
- <button
28
- className="border shadow rounded p-1 bg-gray-200 hover:bg-gray-300"
29
- onClick={() =>
30
- context.setPage((page) => (page > 1 ? page - 1 : page))
31
- }
32
- // disabled={!context.canPreviousPage}
33
- >
34
- <GrFormPrevious />
35
- </button>
36
- </>
37
- )}
38
- <div className="flex flex-col gap-1 items-center justify-center text-xs font-bold bg-white border rounded py-1 px-10">
39
- <span>
40
- Página {context.page} de {context.totalPages}
41
- </span>
42
- <span>
43
- Mostrando {context.filteredBody.length} de{" "}
44
- {Object.values(context.defaultData).length} Elementos
45
- </span>
46
- </div>
47
- {context.maxItems != Infinity && (
48
- <>
49
- <button
50
- className="border shadow rounded p-1 bg-gray-200 hover:bg-gray-300"
51
- onClick={() =>
52
- context.setPage((page) =>
53
- page < context.totalPages ? page + 1 : page
54
- )
55
- }
56
- // disabled={!context.canNextPage}
57
- >
58
- <GrFormNext />
59
- </button>
60
- <button
61
- className="border shadow rounded p-1 bg-gray-200 hover:bg-gray-300"
62
- onClick={() => context.setPage(context.totalPages)}
63
- // disabled={!context.canPreviousPage}
64
- >
65
- <MdOutlineLastPage />
66
- </button>
67
- </>
68
- )}
69
- </div>
70
- </div>
71
- )
72
- );
73
- }