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.
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +402 -256
- package/dist/index.mjs +400 -253
- package/package.json +1 -1
- package/src/table-advanced/h.table.tsx +343 -273
- package/src/table-advanced/header.tsx +73 -48
- package/src/table-advanced/icons.tsx +37 -0
- package/src/table-advanced/searchable.tsx +1 -1
- package/src/table-advanced/types.ts +1 -0
- package/src/table-advanced/use.pagination.tsx +65 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { createPortal } from "react-dom";
|
|
3
3
|
import DropIcon, {
|
|
4
4
|
ArrowDownIcon,
|
|
@@ -17,18 +17,22 @@ export function Header({
|
|
|
17
17
|
context,
|
|
18
18
|
drag,
|
|
19
19
|
padding,
|
|
20
|
+
index,
|
|
21
|
+
length,
|
|
20
22
|
}: {
|
|
21
23
|
header: string;
|
|
22
24
|
context: ContextType & Omit<TableProps, "data">;
|
|
25
|
+
index: number;
|
|
23
26
|
drag: {
|
|
24
27
|
widths: Record<string, number>;
|
|
25
28
|
gridTemplateColumns: string;
|
|
26
29
|
startDrag: (e: React.MouseEvent, headerKey: string) => void;
|
|
27
30
|
};
|
|
31
|
+
length: number;
|
|
28
32
|
padding: string;
|
|
29
33
|
}) {
|
|
30
34
|
const [visible, setVisible] = useState(false);
|
|
31
|
-
|
|
35
|
+
const [hovered, setHovered] = useState(false);
|
|
32
36
|
const sortIndex = context.sort.findIndex((b) => b.field == header);
|
|
33
37
|
const [text, setText] = useState("");
|
|
34
38
|
const cellRef = useRef<HTMLDivElement>(null);
|
|
@@ -36,17 +40,21 @@ export function Header({
|
|
|
36
40
|
null,
|
|
37
41
|
);
|
|
38
42
|
|
|
39
|
-
const filteredValues =
|
|
40
|
-
...new Set(context.data.map((d) => d[header]))
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
43
|
+
const filteredValues = useMemo(() => {
|
|
44
|
+
return [...new Set(context.data.map((d) => d[header]))].filter((d) => {
|
|
45
|
+
if (text == "") return true;
|
|
46
|
+
return `${d}`.toLowerCase().includes(text.toLowerCase());
|
|
47
|
+
});
|
|
48
|
+
}, [context.data, header, text]);
|
|
45
49
|
|
|
46
|
-
const [selected, setSelected] = useState([
|
|
50
|
+
const [selected, setSelected] = useState<any[]>([]);
|
|
47
51
|
|
|
48
52
|
const hasFilter = context.filters.find((b) => b.field == header);
|
|
49
53
|
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
setSelected(filteredValues);
|
|
56
|
+
}, [filteredValues]);
|
|
57
|
+
|
|
50
58
|
useEffect(() => {
|
|
51
59
|
if (visible) {
|
|
52
60
|
context.setCurrentHeader(header);
|
|
@@ -95,7 +103,7 @@ export function Header({
|
|
|
95
103
|
<div className="">
|
|
96
104
|
<div
|
|
97
105
|
className={
|
|
98
|
-
"
|
|
106
|
+
" flex items-center justify-center text-center relative "
|
|
99
107
|
}
|
|
100
108
|
style={{ zIndex: 10, height: `${padding}px`, maxHeight: "100px" }}
|
|
101
109
|
>
|
|
@@ -118,45 +126,52 @@ export function Header({
|
|
|
118
126
|
);
|
|
119
127
|
} else
|
|
120
128
|
return (
|
|
121
|
-
<div className="">
|
|
129
|
+
<div className=" ">
|
|
122
130
|
<div
|
|
123
131
|
ref={cellRef}
|
|
124
|
-
className={"
|
|
132
|
+
className={index < length - 1 ? "border-r" : ""}
|
|
133
|
+
onMouseEnter={(e) => setHovered(true)}
|
|
134
|
+
onMouseLeave={(e) => setHovered(false)}
|
|
125
135
|
style={{ zIndex: 10, height: `${padding}px`, maxHeight: "100px" }}
|
|
126
136
|
>
|
|
127
137
|
<div className="flex justify-between items-center ">
|
|
128
|
-
|
|
129
|
-
|
|
138
|
+
{!context.disabled ? (
|
|
139
|
+
<div className="flex gap-2">
|
|
140
|
+
{hasFilter ? (
|
|
141
|
+
<div
|
|
142
|
+
className="cursor-pointer"
|
|
143
|
+
onClick={(e) => {
|
|
144
|
+
context.setFilters(null);
|
|
145
|
+
setSelected(filteredValues);
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
<FilterIcon />
|
|
149
|
+
</div>
|
|
150
|
+
) : (
|
|
151
|
+
<div></div>
|
|
152
|
+
)}
|
|
153
|
+
|
|
130
154
|
<div
|
|
131
|
-
className="cursor-pointer"
|
|
132
155
|
onClick={(e) => {
|
|
133
|
-
context.
|
|
134
|
-
|
|
156
|
+
context.setSort({
|
|
157
|
+
[header]: "TOGGLE",
|
|
158
|
+
});
|
|
135
159
|
}}
|
|
136
160
|
>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
onClick={(e) => {
|
|
144
|
-
context.setSort({
|
|
145
|
-
[header]: "TOGGLE",
|
|
146
|
-
});
|
|
147
|
-
}}
|
|
148
|
-
>
|
|
149
|
-
{sortIndex >= 0 ? (
|
|
150
|
-
context.sort[sortIndex].type === "ASC" ? (
|
|
151
|
-
<ArrowUPIcon />
|
|
161
|
+
{sortIndex >= 0 ? (
|
|
162
|
+
context.sort[sortIndex].type === "ASC" ? (
|
|
163
|
+
<ArrowUPIcon />
|
|
164
|
+
) : (
|
|
165
|
+
<ArrowDownIcon />
|
|
166
|
+
)
|
|
152
167
|
) : (
|
|
153
|
-
<
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
<div></div>
|
|
157
|
-
)}
|
|
168
|
+
<div></div>
|
|
169
|
+
)}
|
|
170
|
+
</div>
|
|
158
171
|
</div>
|
|
159
|
-
|
|
172
|
+
) : (
|
|
173
|
+
<div></div>
|
|
174
|
+
)}
|
|
160
175
|
<div
|
|
161
176
|
className="font-bold flex truncate text-xs items-center "
|
|
162
177
|
style={{ height: `${padding}px` }}
|
|
@@ -168,19 +183,23 @@ export function Header({
|
|
|
168
183
|
>
|
|
169
184
|
{header}
|
|
170
185
|
</div>
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
{!context.disabled ? (
|
|
187
|
+
<div
|
|
188
|
+
style={{ zIndex: 10 }}
|
|
189
|
+
className="icon font-bold p-1 cursor-pointer pr-3 "
|
|
190
|
+
onClick={(e) => setVisible(true)}
|
|
191
|
+
>
|
|
192
|
+
{hovered ? <DropIcon /> : ""}
|
|
193
|
+
</div>
|
|
194
|
+
) : (
|
|
195
|
+
<div></div>
|
|
196
|
+
)}
|
|
178
197
|
</div>
|
|
179
198
|
|
|
180
|
-
{context.currentHeader != header && (
|
|
199
|
+
{!context.disabled && context.currentHeader != header && (
|
|
181
200
|
<div
|
|
182
201
|
onMouseDown={(e) => drag.startDrag(e, header)}
|
|
183
|
-
className="absolute top-0 h-full cursor-col-resize hover:bg-blue-300
|
|
202
|
+
className="absolute top-0 h-full cursor-col-resize hover:bg-blue-300 "
|
|
184
203
|
style={{ right: -2, width: 6, zIndex: 20 }}
|
|
185
204
|
/>
|
|
186
205
|
)}
|
|
@@ -302,7 +321,13 @@ export function Header({
|
|
|
302
321
|
}}
|
|
303
322
|
checked={text != "" || selected.includes(d)}
|
|
304
323
|
/>
|
|
305
|
-
<div className="truncate">
|
|
324
|
+
<div className="truncate">
|
|
325
|
+
{d == ""
|
|
326
|
+
? "Vacias"
|
|
327
|
+
: !Boolean(d)
|
|
328
|
+
? "null"
|
|
329
|
+
: d}
|
|
330
|
+
</div>
|
|
306
331
|
</div>
|
|
307
332
|
);
|
|
308
333
|
})}
|
|
@@ -16,6 +16,43 @@ export default function DropIcon() {
|
|
|
16
16
|
</svg>
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
export function PrevIcon() {
|
|
21
|
+
return (
|
|
22
|
+
<svg
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
fill="currentColor"
|
|
25
|
+
strokeWidth="0"
|
|
26
|
+
viewBox="0 0 24 24"
|
|
27
|
+
height="1em"
|
|
28
|
+
width="1em"
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
+
>
|
|
31
|
+
<polyline
|
|
32
|
+
fill="none"
|
|
33
|
+
strokeWidth="2"
|
|
34
|
+
points="7 2 17 12 7 22"
|
|
35
|
+
transform="matrix(-1 0 0 1 24 0)"
|
|
36
|
+
></polyline>
|
|
37
|
+
</svg>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function NextIcon() {
|
|
42
|
+
return (
|
|
43
|
+
<svg
|
|
44
|
+
stroke="currentColor"
|
|
45
|
+
fill="currentColor"
|
|
46
|
+
strokeWidth="0"
|
|
47
|
+
viewBox="0 0 24 24"
|
|
48
|
+
height="1em"
|
|
49
|
+
width="1em"
|
|
50
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
51
|
+
>
|
|
52
|
+
<polyline fill="none" stroke-width="2" points="7 2 17 12 7 22"></polyline>
|
|
53
|
+
</svg>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
19
56
|
export function EditIcon() {
|
|
20
57
|
return (
|
|
21
58
|
<svg
|
|
@@ -8,7 +8,7 @@ export default function Searchable({
|
|
|
8
8
|
context: ContextType & Omit<TableProps, "data">;
|
|
9
9
|
}) {
|
|
10
10
|
return (
|
|
11
|
-
<div className="flex justify-start p-2 relative w-96">
|
|
11
|
+
<div className="flex justify-start p-2 relative w-96 text-xs">
|
|
12
12
|
<input
|
|
13
13
|
type="search"
|
|
14
14
|
placeholder="Buscar por ...."
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useState, useMemo, useCallback, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
function usePaginacion({
|
|
4
|
+
total,
|
|
5
|
+
tamanioPagina = 100,
|
|
6
|
+
paginaInicial = 1,
|
|
7
|
+
}: {
|
|
8
|
+
total: number;
|
|
9
|
+
tamanioPagina?: number;
|
|
10
|
+
paginaInicial?: number;
|
|
11
|
+
}) {
|
|
12
|
+
const [totalPaginas, setTotalPaginas] = useState(
|
|
13
|
+
Math.max(1, Math.ceil(total / tamanioPagina)),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const [pagina, setPagina] = useState(
|
|
17
|
+
Math.min(Math.max(paginaInicial, 1), totalPaginas),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const inicio = total === 0 ? 0 : (pagina - 1) * tamanioPagina + 1;
|
|
21
|
+
const fin = Math.min(pagina * tamanioPagina, total);
|
|
22
|
+
|
|
23
|
+
const rango = useMemo(() => {
|
|
24
|
+
if (total === 0) return "0 a 0";
|
|
25
|
+
return `${inicio} a ${fin}`;
|
|
26
|
+
}, [inicio, fin, total]);
|
|
27
|
+
|
|
28
|
+
const hasNext = pagina < totalPaginas;
|
|
29
|
+
const hasPrev = pagina > 1;
|
|
30
|
+
|
|
31
|
+
const next = useCallback(() => {
|
|
32
|
+
setPagina((p) => Math.min(p + 1, totalPaginas));
|
|
33
|
+
}, [totalPaginas]);
|
|
34
|
+
|
|
35
|
+
const prev = useCallback(() => {
|
|
36
|
+
setPagina((p) => Math.max(p - 1, 1));
|
|
37
|
+
}, []);
|
|
38
|
+
|
|
39
|
+
const irAPagina = useCallback<(n: number) => void>(
|
|
40
|
+
(n) => {
|
|
41
|
+
setPagina(Math.min(Math.max(n, 1), totalPaginas));
|
|
42
|
+
},
|
|
43
|
+
[totalPaginas],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
setTotalPaginas(Math.max(1, Math.ceil(total / tamanioPagina)));
|
|
48
|
+
setPagina(1);
|
|
49
|
+
}, [total]);
|
|
50
|
+
return {
|
|
51
|
+
rango,
|
|
52
|
+
inicio,
|
|
53
|
+
fin,
|
|
54
|
+
total,
|
|
55
|
+
pagina,
|
|
56
|
+
totalPaginas,
|
|
57
|
+
hasNext,
|
|
58
|
+
hasPrev,
|
|
59
|
+
next,
|
|
60
|
+
prev,
|
|
61
|
+
irAPagina,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default usePaginacion;
|