framepexls-ui-lib 0.1.29 → 0.1.31

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.
@@ -11,7 +11,7 @@ type CheckboxProps = Omit<React__default.InputHTMLAttributes<HTMLInputElement>,
11
11
  className?: string;
12
12
  inputClassName?: string;
13
13
  };
14
- declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & {
14
+ declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & {
15
15
  label?: React__default.ReactNode;
16
16
  description?: React__default.ReactNode;
17
17
  error?: boolean;
@@ -11,7 +11,7 @@ type CheckboxProps = Omit<React__default.InputHTMLAttributes<HTMLInputElement>,
11
11
  className?: string;
12
12
  inputClassName?: string;
13
13
  };
14
- declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> & {
14
+ declare const Checkbox: React__default.ForwardRefExoticComponent<Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size" | "type"> & {
15
15
  label?: React__default.ReactNode;
16
16
  description?: React__default.ReactNode;
17
17
  error?: boolean;
package/dist/Dialog.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React__default from 'react';
3
3
 
4
- type Size = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
4
+ type Size = "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";
5
5
  type DialogProps = {
6
6
  open: boolean;
7
7
  onClose: () => void;
package/dist/Dialog.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React__default from 'react';
3
3
 
4
- type Size = "sm" | "md" | "lg" | "xl" | "2xl" | "full";
4
+ type Size = "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";
5
5
  type DialogProps = {
6
6
  open: boolean;
7
7
  onClose: () => void;
package/dist/Dialog.js CHANGED
@@ -41,6 +41,7 @@ __export(Dialog_exports, {
41
41
  module.exports = __toCommonJS(Dialog_exports);
42
42
  var import_jsx_runtime = require("react/jsx-runtime");
43
43
  var import_react = __toESM(require("react"));
44
+ var import_react_dom = require("react-dom");
44
45
  var import_framer_motion = require("framer-motion");
45
46
  var import_ActionIconButton = __toESM(require("./ActionIconButton"));
46
47
  var import_Button = __toESM(require("./Button"));
@@ -50,8 +51,31 @@ const sizeToMaxW = {
50
51
  lg: "max-w-lg",
51
52
  xl: "max-w-xl",
52
53
  "2xl": "max-w-2xl",
54
+ "3xl": "max-w-3xl",
55
+ "4xl": "max-w-4xl",
56
+ "5xl": "max-w-5xl",
53
57
  full: "max-w-[min(96vw,1200px)]"
54
58
  };
59
+ const zManager = /* @__PURE__ */ (() => {
60
+ const stack = [];
61
+ const BASE = 1e3;
62
+ const STEP = 10;
63
+ return {
64
+ acquire() {
65
+ const z = BASE + stack.length * STEP;
66
+ stack.push(z);
67
+ return z;
68
+ },
69
+ release(z) {
70
+ const i = stack.indexOf(z);
71
+ if (i !== -1) stack.splice(i, 1);
72
+ },
73
+ isTop(z) {
74
+ if (z == null) return false;
75
+ return stack.length > 0 && stack[stack.length - 1] === z;
76
+ }
77
+ };
78
+ })();
55
79
  function useLockBodyScroll(open) {
56
80
  (0, import_react.useEffect)(() => {
57
81
  if (!open) return;
@@ -76,15 +100,16 @@ function useLockBodyScroll(open) {
76
100
  };
77
101
  }, [open]);
78
102
  }
79
- function useEscToClose(open, onClose, disabled) {
103
+ function useEscToClose(open, onClose, disabled, onlyIfTop) {
80
104
  (0, import_react.useEffect)(() => {
81
105
  if (!open || disabled) return;
106
+ if (onlyIfTop && !onlyIfTop()) return;
82
107
  const onKey = (e) => {
83
108
  if (e.key === "Escape") onClose();
84
109
  };
85
110
  window.addEventListener("keydown", onKey);
86
111
  return () => window.removeEventListener("keydown", onKey);
87
- }, [open, onClose, disabled]);
112
+ }, [open, onClose, disabled, onlyIfTop == null ? void 0 : onlyIfTop()]);
88
113
  }
89
114
  function cx(...a) {
90
115
  return a.filter(Boolean).join(" ");
@@ -107,8 +132,21 @@ function DialogBase({
107
132
  const containerRef = (0, import_react.useRef)(null);
108
133
  const closeBtnRef = (0, import_react.useRef)(null);
109
134
  const lastFocusedRef = (0, import_react.useRef)(null);
135
+ const [zIndexBase, setZIndexBase] = (0, import_react.useState)(null);
110
136
  useLockBodyScroll(open);
111
- useEscToClose(open, onClose, disableEscClose);
137
+ useEscToClose(open, onClose, disableEscClose, () => zManager.isTop(zIndexBase));
138
+ (0, import_react.useEffect)(() => {
139
+ if (open) {
140
+ const z = zManager.acquire();
141
+ setZIndexBase(z);
142
+ return () => {
143
+ zManager.release(z);
144
+ setZIndexBase(null);
145
+ };
146
+ } else {
147
+ setZIndexBase(null);
148
+ }
149
+ }, [open]);
112
150
  (0, import_react.useEffect)(() => {
113
151
  var _a, _b, _c;
114
152
  if (open) {
@@ -124,59 +162,64 @@ function DialogBase({
124
162
  if (!dismissibleBackdrop) return;
125
163
  if (e.target === e.currentTarget) onClose();
126
164
  };
127
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_framer_motion.AnimatePresence, { children: open && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
128
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
129
- import_framer_motion.motion.div,
130
- {
131
- className: "fixed inset-0 z-[100] bg-black/45 backdrop-blur-sm",
132
- initial: { opacity: 0 },
133
- animate: { opacity: 1 },
134
- exit: { opacity: 0 }
135
- }
136
- ),
137
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
138
- import_framer_motion.motion.div,
139
- {
140
- role: "dialog",
141
- "aria-modal": "true",
142
- "aria-labelledby": title ? "dialog-title" : void 0,
143
- "aria-describedby": description ? "dialog-desc" : void 0,
144
- className: "fixed inset-0 z-[101] grid place-items-center p-4",
145
- initial: { opacity: 0, scale: 0.98, y: 8 },
146
- animate: { opacity: 1, scale: 1, y: 0 },
147
- exit: { opacity: 0, scale: 0.98, y: 8 },
148
- onMouseDown: handleBackdropMouseDown,
149
- children: [
150
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
151
- "div",
152
- {
153
- ref: containerRef,
154
- className: cx(
155
- "w-full overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-xl",
156
- "dark:border-white/10 dark:bg-[#0b0a0a]",
157
- "flex max-h-[88vh] flex-col",
158
- sizeToMaxW[size],
159
- className
160
- ),
161
- onMouseDown: (e) => e.stopPropagation(),
162
- children: children != null ? children : null
163
- }
164
- ),
165
- showClose && !children && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute right-5 top-5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
166
- import_ActionIconButton.default,
167
- {
168
- title: "Cerrar",
169
- size: "lg",
170
- onClick: onClose,
171
- ref: closeBtnRef,
172
- className: "shadow-sm",
173
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
174
- }
175
- ) })
176
- ]
177
- }
178
- )
179
- ] }) });
165
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_framer_motion.AnimatePresence, { children: open && typeof document !== "undefined" && zIndexBase !== null && (0, import_react_dom.createPortal)(
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
168
+ import_framer_motion.motion.div,
169
+ {
170
+ className: "fixed inset-0 bg-black/45 backdrop-blur-sm",
171
+ style: { zIndex: zIndexBase },
172
+ initial: { opacity: 0 },
173
+ animate: { opacity: 1 },
174
+ exit: { opacity: 0 }
175
+ }
176
+ ),
177
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
178
+ import_framer_motion.motion.div,
179
+ {
180
+ role: "dialog",
181
+ "aria-modal": "true",
182
+ "aria-labelledby": title ? "dialog-title" : void 0,
183
+ "aria-describedby": description ? "dialog-desc" : void 0,
184
+ className: "fixed inset-0 grid place-items-center p-4",
185
+ style: { zIndex: zIndexBase + 1 },
186
+ initial: { opacity: 0, scale: 0.98, y: 8 },
187
+ animate: { opacity: 1, scale: 1, y: 0 },
188
+ exit: { opacity: 0, scale: 0.98, y: 8 },
189
+ onMouseDown: handleBackdropMouseDown,
190
+ children: [
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
192
+ "div",
193
+ {
194
+ ref: containerRef,
195
+ className: cx(
196
+ "w-full overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-xl",
197
+ "dark:border-white/10 dark:bg-[#0b0a0a]",
198
+ "flex max-h-[88vh] flex-col",
199
+ sizeToMaxW[size],
200
+ className
201
+ ),
202
+ onMouseDown: (e) => e.stopPropagation(),
203
+ children: children != null ? children : null
204
+ }
205
+ ),
206
+ showClose && !children && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute right-5 top-5", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
207
+ import_ActionIconButton.default,
208
+ {
209
+ title: "Cerrar",
210
+ size: "lg",
211
+ onClick: onClose,
212
+ ref: closeBtnRef,
213
+ className: "shadow-sm",
214
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
215
+ }
216
+ ) })
217
+ ]
218
+ }
219
+ )
220
+ ] }),
221
+ document.body
222
+ ) });
180
223
  }
181
224
  function DialogHeader({
182
225
  title,
package/dist/Dialog.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import React, { useEffect, useRef } from "react";
3
+ import React, { useEffect, useRef, useState } from "react";
4
+ import { createPortal } from "react-dom";
4
5
  import { motion, AnimatePresence } from "framer-motion";
5
6
  import ActionIconButton from "./ActionIconButton";
6
7
  import Button from "./Button";
@@ -10,8 +11,31 @@ const sizeToMaxW = {
10
11
  lg: "max-w-lg",
11
12
  xl: "max-w-xl",
12
13
  "2xl": "max-w-2xl",
14
+ "3xl": "max-w-3xl",
15
+ "4xl": "max-w-4xl",
16
+ "5xl": "max-w-5xl",
13
17
  full: "max-w-[min(96vw,1200px)]"
14
18
  };
19
+ const zManager = /* @__PURE__ */ (() => {
20
+ const stack = [];
21
+ const BASE = 1e3;
22
+ const STEP = 10;
23
+ return {
24
+ acquire() {
25
+ const z = BASE + stack.length * STEP;
26
+ stack.push(z);
27
+ return z;
28
+ },
29
+ release(z) {
30
+ const i = stack.indexOf(z);
31
+ if (i !== -1) stack.splice(i, 1);
32
+ },
33
+ isTop(z) {
34
+ if (z == null) return false;
35
+ return stack.length > 0 && stack[stack.length - 1] === z;
36
+ }
37
+ };
38
+ })();
15
39
  function useLockBodyScroll(open) {
16
40
  useEffect(() => {
17
41
  if (!open) return;
@@ -36,15 +60,16 @@ function useLockBodyScroll(open) {
36
60
  };
37
61
  }, [open]);
38
62
  }
39
- function useEscToClose(open, onClose, disabled) {
63
+ function useEscToClose(open, onClose, disabled, onlyIfTop) {
40
64
  useEffect(() => {
41
65
  if (!open || disabled) return;
66
+ if (onlyIfTop && !onlyIfTop()) return;
42
67
  const onKey = (e) => {
43
68
  if (e.key === "Escape") onClose();
44
69
  };
45
70
  window.addEventListener("keydown", onKey);
46
71
  return () => window.removeEventListener("keydown", onKey);
47
- }, [open, onClose, disabled]);
72
+ }, [open, onClose, disabled, onlyIfTop == null ? void 0 : onlyIfTop()]);
48
73
  }
49
74
  function cx(...a) {
50
75
  return a.filter(Boolean).join(" ");
@@ -67,8 +92,21 @@ function DialogBase({
67
92
  const containerRef = useRef(null);
68
93
  const closeBtnRef = useRef(null);
69
94
  const lastFocusedRef = useRef(null);
95
+ const [zIndexBase, setZIndexBase] = useState(null);
70
96
  useLockBodyScroll(open);
71
- useEscToClose(open, onClose, disableEscClose);
97
+ useEscToClose(open, onClose, disableEscClose, () => zManager.isTop(zIndexBase));
98
+ useEffect(() => {
99
+ if (open) {
100
+ const z = zManager.acquire();
101
+ setZIndexBase(z);
102
+ return () => {
103
+ zManager.release(z);
104
+ setZIndexBase(null);
105
+ };
106
+ } else {
107
+ setZIndexBase(null);
108
+ }
109
+ }, [open]);
72
110
  useEffect(() => {
73
111
  var _a, _b, _c;
74
112
  if (open) {
@@ -84,59 +122,64 @@ function DialogBase({
84
122
  if (!dismissibleBackdrop) return;
85
123
  if (e.target === e.currentTarget) onClose();
86
124
  };
87
- return /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Fragment, { children: [
88
- /* @__PURE__ */ jsx(
89
- motion.div,
90
- {
91
- className: "fixed inset-0 z-[100] bg-black/45 backdrop-blur-sm",
92
- initial: { opacity: 0 },
93
- animate: { opacity: 1 },
94
- exit: { opacity: 0 }
95
- }
96
- ),
97
- /* @__PURE__ */ jsxs(
98
- motion.div,
99
- {
100
- role: "dialog",
101
- "aria-modal": "true",
102
- "aria-labelledby": title ? "dialog-title" : void 0,
103
- "aria-describedby": description ? "dialog-desc" : void 0,
104
- className: "fixed inset-0 z-[101] grid place-items-center p-4",
105
- initial: { opacity: 0, scale: 0.98, y: 8 },
106
- animate: { opacity: 1, scale: 1, y: 0 },
107
- exit: { opacity: 0, scale: 0.98, y: 8 },
108
- onMouseDown: handleBackdropMouseDown,
109
- children: [
110
- /* @__PURE__ */ jsx(
111
- "div",
112
- {
113
- ref: containerRef,
114
- className: cx(
115
- "w-full overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-xl",
116
- "dark:border-white/10 dark:bg-[#0b0a0a]",
117
- "flex max-h-[88vh] flex-col",
118
- sizeToMaxW[size],
119
- className
120
- ),
121
- onMouseDown: (e) => e.stopPropagation(),
122
- children: children != null ? children : null
123
- }
124
- ),
125
- showClose && !children && /* @__PURE__ */ jsx("div", { className: "absolute right-5 top-5", children: /* @__PURE__ */ jsx(
126
- ActionIconButton,
127
- {
128
- title: "Cerrar",
129
- size: "lg",
130
- onClick: onClose,
131
- ref: closeBtnRef,
132
- className: "shadow-sm",
133
- children: /* @__PURE__ */ jsx(CloseIcon, {})
134
- }
135
- ) })
136
- ]
137
- }
138
- )
139
- ] }) });
125
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: open && typeof document !== "undefined" && zIndexBase !== null && createPortal(
126
+ /* @__PURE__ */ jsxs(Fragment, { children: [
127
+ /* @__PURE__ */ jsx(
128
+ motion.div,
129
+ {
130
+ className: "fixed inset-0 bg-black/45 backdrop-blur-sm",
131
+ style: { zIndex: zIndexBase },
132
+ initial: { opacity: 0 },
133
+ animate: { opacity: 1 },
134
+ exit: { opacity: 0 }
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsxs(
138
+ motion.div,
139
+ {
140
+ role: "dialog",
141
+ "aria-modal": "true",
142
+ "aria-labelledby": title ? "dialog-title" : void 0,
143
+ "aria-describedby": description ? "dialog-desc" : void 0,
144
+ className: "fixed inset-0 grid place-items-center p-4",
145
+ style: { zIndex: zIndexBase + 1 },
146
+ initial: { opacity: 0, scale: 0.98, y: 8 },
147
+ animate: { opacity: 1, scale: 1, y: 0 },
148
+ exit: { opacity: 0, scale: 0.98, y: 8 },
149
+ onMouseDown: handleBackdropMouseDown,
150
+ children: [
151
+ /* @__PURE__ */ jsx(
152
+ "div",
153
+ {
154
+ ref: containerRef,
155
+ className: cx(
156
+ "w-full overflow-hidden rounded-3xl border border-slate-200 bg-white shadow-xl",
157
+ "dark:border-white/10 dark:bg-[#0b0a0a]",
158
+ "flex max-h-[88vh] flex-col",
159
+ sizeToMaxW[size],
160
+ className
161
+ ),
162
+ onMouseDown: (e) => e.stopPropagation(),
163
+ children: children != null ? children : null
164
+ }
165
+ ),
166
+ showClose && !children && /* @__PURE__ */ jsx("div", { className: "absolute right-5 top-5", children: /* @__PURE__ */ jsx(
167
+ ActionIconButton,
168
+ {
169
+ title: "Cerrar",
170
+ size: "lg",
171
+ onClick: onClose,
172
+ ref: closeBtnRef,
173
+ className: "shadow-sm",
174
+ children: /* @__PURE__ */ jsx(CloseIcon, {})
175
+ }
176
+ ) })
177
+ ]
178
+ }
179
+ )
180
+ ] }),
181
+ document.body
182
+ ) });
140
183
  }
141
184
  function DialogHeader({
142
185
  title,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framepexls-ui-lib",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Componentes UI de Framepexls para React/Next.",