next-recomponents 2.0.41 → 2.0.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-recomponents",
3
- "version": "2.0.41",
3
+ "version": "2.0.42",
4
4
  "description": "description nueva",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.tsx CHANGED
@@ -19,3 +19,4 @@ export { useFormValues } from "./form";
19
19
  export { default as DocumentViewer } from "./doc-viewer";
20
20
  export { default as Table3 } from "./table3";
21
21
  export { default as usePopup } from "./pop";
22
+ export { default as TableAdvanced } from "./table-advanced";
@@ -15,6 +15,7 @@ export default function Modal({
15
15
  children,
16
16
  color = "primary",
17
17
  title,
18
+ onClose,
18
19
  }: {
19
20
  button: ReactElement<React.ComponentPropsWithRef<"button">>;
20
21
  children: ReactElement<
@@ -22,9 +23,12 @@ export default function Modal({
22
23
  >;
23
24
  color?: PopupColor;
24
25
  title?: string;
26
+ onClose?: () => Promise<boolean>;
25
27
  }) {
26
28
  const pop = usePopup();
27
- const hide = () => pop.close(false);
29
+ const hide = () => {
30
+ pop.close(false);
31
+ };
28
32
 
29
33
  const childrenWithHide = useMemo(
30
34
  () => cloneElement(children, { hide }),
@@ -39,14 +43,14 @@ export default function Modal({
39
43
  const onClick = props?.onClick;
40
44
 
41
45
  return (
42
- <>
46
+ <div className="">
43
47
  {cloneElement(button, {
44
48
  onClick: (e) => {
45
49
  onClick?.(e as any);
46
- pop.modal(childrenWithHide, color, false, true);
50
+ pop.modal(childrenWithHide, color, false, true, onClose);
47
51
  },
48
52
  })}
49
53
  {pop.PopupComponent}
50
- </>
54
+ </div>
51
55
  );
52
56
  }
package/src/pop/color.tsx CHANGED
@@ -58,7 +58,7 @@ export const COLOR_CONFIG: Record<PopupColor, ColorTokens> = {
58
58
  label: "◎",
59
59
  },
60
60
  white: {
61
- bg: "from-gray-50 to-white",
61
+ bg: "from-white to-white",
62
62
  iconBg: "bg-gray-100",
63
63
  iconText: "text-gray-500",
64
64
  border: "border-gray-200",
package/src/pop/index.tsx CHANGED
@@ -30,13 +30,21 @@ export default function usePopup() {
30
30
  [],
31
31
  );
32
32
 
33
- const close = useCallback((confirmed: boolean, value?: string) => {
34
- setPopup((prev) => {
35
- if (confirmed) prev.onConfirm?.(value);
36
- else prev.onCancel?.();
37
- return { ...prev, visible: false, inputValue: "" };
38
- });
39
- }, []);
33
+ const close = useCallback(
34
+ async (confirmed: boolean, value?: string) => {
35
+ const prev = { ...popup };
36
+ let visible = false;
37
+ if (confirmed) {
38
+ prev.onConfirm?.(value);
39
+ } else if (prev?.onCancel) {
40
+ visible = !Boolean(await prev.onCancel?.());
41
+ }
42
+
43
+ const data = { ...prev, visible, inputValue: "" };
44
+ setPopup(data);
45
+ },
46
+ [popup],
47
+ );
40
48
 
41
49
  const alert = useCallback(
42
50
  (message: string, color: PopupColor = "primary"): Promise<void> =>
@@ -58,14 +66,19 @@ export default function usePopup() {
58
66
  color: PopupColor = "primary",
59
67
  icons: boolean = false,
60
68
  full: boolean = false,
69
+ onClose?: () => Promise<boolean>,
61
70
  ): Promise<void> =>
62
71
  new Promise((resolve) =>
63
72
  open({
64
73
  type: "modal",
65
74
  message,
66
75
  color,
67
- onConfirm: () => resolve(),
68
- onCancel: () => resolve(),
76
+ // onConfirm: () => {
77
+ // resolve();
78
+ // },
79
+ onCancel: async () => {
80
+ return await onClose?.();
81
+ },
69
82
  icons,
70
83
  full,
71
84
  }),
@@ -16,7 +16,7 @@ export function PopupOverlay({
16
16
 
17
17
  return (
18
18
  <div
19
- className={"fixed inset-0 flex items-center justify-center z-[1000] "}
19
+ className="fixed inset-0 flex items-center justify-center z-[1000] overflow-auto p-1"
20
20
  style={{ background: "rgba(15,23,42,0.45)", backdropFilter: "blur(2px)" }}
21
21
  // onClick={(e) => {
22
22
  // if (e.target === e.currentTarget) {
@@ -33,7 +33,7 @@ export function PopupOverlay({
33
33
  `}</style>
34
34
 
35
35
  <div
36
- className={`bg-gradient-to-br ${c.bg} border ${c.border} ${popup.full == true ? " w-full h-screen m-20 " : " max-w-sm "} rounded-2xl shadow-2xl mx-4`}
36
+ className={`bg-gradient-to-br ${c.bg} border ${c.border} ${popup.full == true ? " w-screen h-screen mt-10 " : " max-w-sm "} rounded shadow m-2`}
37
37
  style={{ animation: "fadeInScale 0.18s ease-out", overflow: "auto" }}
38
38
  >
39
39
  {/* Header */}
@@ -77,7 +77,9 @@ export function PopupOverlay({
77
77
  )}
78
78
 
79
79
  {/* Divider */}
80
- <div className={`border-t ${c.border} mt-4`} />
80
+ {popup.type !== "modal" && (
81
+ <div className={`border-t ${c.border} mt-4`} />
82
+ )}
81
83
 
82
84
  {/* Actions */}
83
85
  {popup.type !== "modal" && (
package/src/pop/types.ts CHANGED
@@ -40,7 +40,7 @@ export interface PopupState {
40
40
  inputValue: string;
41
41
  color: PopupColor;
42
42
  onConfirm?: (value?: string) => void;
43
- onCancel?: () => void;
43
+ onCancel?: () => void | Promise<boolean | void>;
44
44
  icons?: boolean;
45
45
  full?: boolean;
46
46
  }
@@ -9,13 +9,6 @@ import regularExpresions from "../regular-expresions";
9
9
 
10
10
  // ─── Types ────────────────────────────────────────────────────────────────────
11
11
 
12
- export interface TableButtonProps extends React.MouseEvent<
13
- HTMLButtonElement,
14
- MouseEvent
15
- > {
16
- row: Record<string, any>;
17
- }
18
-
19
12
  type FooterAggregation = "sum" | "avg" | "count";
20
13
 
21
14
  interface FooterType {
@@ -23,7 +16,12 @@ interface FooterType {
23
16
  }
24
17
 
25
18
  type GridDensity = "compact" | "standard" | "comfortable";
26
-
19
+ export interface TableButtonProps extends React.MouseEvent<
20
+ HTMLButtonElement,
21
+ MouseEvent
22
+ > {
23
+ row: Record<string, any>;
24
+ }
27
25
  interface TableProps {
28
26
  data: any;
29
27
  searchable?: boolean;
@@ -0,0 +1,88 @@
1
+ import { useEffect, useMemo, useReducer, useState } from "react";
2
+ import { filterReducer } from "./filter.reducer";
3
+ import { FiltersType, SortType } from "./types";
4
+ import { sortReducer } from "./sort.reducer";
5
+ import useExcel from "../use-excel";
6
+
7
+ export default function useContext({ onSelect }: { onSelect?: boolean }) {
8
+ const excel = useExcel();
9
+ const [editions, setEditions] = useState<any[]>([]);
10
+ const [selected, setSelected] = useState<any[]>([]);
11
+ const [data, setData] = useState<any[]>([]);
12
+ const headers = [...new Set(data.map((b) => Object.keys(b)).flat())];
13
+
14
+ const [currentHeader, setCurrentHeader] = useState<string | null>(null);
15
+ const cols = headers.length;
16
+ const [filters, setFilters] = useReducer(
17
+ filterReducer,
18
+ new Array<FiltersType>(),
19
+ );
20
+ const [searchBy, setSearchBy] = useState<string>("");
21
+ const [sort, setSort] = useReducer(sortReducer, new Array<SortType>());
22
+
23
+ const sortedData: any[] = useMemo(() => {
24
+ return [...data].sort((a, b) => {
25
+ for (const { field, type } of sort.reverse()) {
26
+ const av = a[field];
27
+ const bv = b[field];
28
+
29
+ // nulls/undefined van siempre al final, independiente de ASC/DESC
30
+ if (av == null && bv == null) continue;
31
+ if (av == null) return 1;
32
+ if (bv == null) return -1;
33
+
34
+ let cmp: number;
35
+ if (typeof av === "number" && typeof bv === "number") {
36
+ cmp = av - bv;
37
+ } else {
38
+ cmp = `${av}`.localeCompare(`${bv}`, undefined, { numeric: true });
39
+ }
40
+
41
+ if (cmp !== 0) {
42
+ return type === "DESC" ? -cmp : cmp;
43
+ }
44
+ // empate: sigue al siguiente campo en context.sort
45
+ }
46
+ return 0;
47
+ });
48
+ }, [data, sort]);
49
+ const filteredData = [...sortedData].filter((d) => {
50
+ if (editions.includes(d?.id)) return true;
51
+
52
+ for (const { field, values } of filters) {
53
+ if (!values.includes(d[field])) {
54
+ return false;
55
+ }
56
+ }
57
+ return true;
58
+ });
59
+
60
+ useEffect(() => {
61
+ if (filters.length == 0) {
62
+ setEditions([]);
63
+ }
64
+ }, [filters]);
65
+ return {
66
+ currentHeader,
67
+ setCurrentHeader,
68
+ sort,
69
+ setSort,
70
+ cols,
71
+ headers,
72
+ data,
73
+ sortedData,
74
+ filters,
75
+ setFilters,
76
+ filteredData,
77
+ setData,
78
+ searchBy,
79
+ setSearchBy,
80
+ selected,
81
+ setSelected,
82
+ editions,
83
+ excel,
84
+ setEditions,
85
+ };
86
+ }
87
+
88
+ export type ContextType = ReturnType<typeof useContext>;
@@ -0,0 +1,19 @@
1
+ import { FiltersType } from "./types";
2
+
3
+ export const filterReducer = (acc: FiltersType[], b: FiltersType | null) => {
4
+ if (b == null) return [];
5
+ const newAcc: FiltersType[] = [];
6
+ newAcc.push(b);
7
+ return newAcc;
8
+
9
+ // const newAcc = [...acc];
10
+
11
+ // const index = newAcc.findIndex((aa) => aa.field == b.field);
12
+ // if (index >= 0) {
13
+ // newAcc[index].values = b.values;
14
+ // } else {
15
+ // newAcc.push(b);
16
+ // }
17
+
18
+ // return newAcc;
19
+ };