@soyfri/shared-library 2.0.0-beta.32 → 2.0.0-beta.34
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/Breadcrumbs-B9I3vxPb.cjs +25 -0
- package/Breadcrumbs-B9I3vxPb.cjs.map +1 -0
- package/Breadcrumbs-C41SPbtX.js +26 -0
- package/Breadcrumbs-C41SPbtX.js.map +1 -0
- package/ButtonGroup-CNunDofQ.cjs +33 -0
- package/ButtonGroup-CNunDofQ.cjs.map +1 -0
- package/ButtonGroup-CcKUZ-lT.js +34 -0
- package/ButtonGroup-CcKUZ-lT.js.map +1 -0
- package/Divider-BApcM5CV.js +28 -0
- package/Divider-BApcM5CV.js.map +1 -0
- package/Divider-CIY0JK4U.cjs +27 -0
- package/Divider-CIY0JK4U.cjs.map +1 -0
- package/{Modal-BqgnC6yu.js → Modal-C_QY7ZzY.js} +4 -3
- package/Modal-C_QY7ZzY.js.map +1 -0
- package/{Modal-CA0J0xpO.cjs → Modal-D_6ZdSzw.cjs} +4 -3
- package/Modal-D_6ZdSzw.cjs.map +1 -0
- package/components/Breadcrumbs/Breadcrumbs.cjs +6 -0
- package/components/Breadcrumbs/Breadcrumbs.cjs.map +1 -0
- package/components/Breadcrumbs/Breadcrumbs.d.ts +16 -0
- package/components/Breadcrumbs/Breadcrumbs.js +6 -0
- package/components/Breadcrumbs/Breadcrumbs.js.map +1 -0
- package/components/Breadcrumbs/index.d.ts +2 -0
- package/components/Breadcrumbs.d.ts +6 -0
- package/components/ButtonGroup/ButtonGroup.cjs +6 -0
- package/components/ButtonGroup/ButtonGroup.cjs.map +1 -0
- package/components/ButtonGroup/ButtonGroup.d.ts +18 -0
- package/components/ButtonGroup/ButtonGroup.js +6 -0
- package/components/ButtonGroup/ButtonGroup.js.map +1 -0
- package/components/ButtonGroup/index.d.ts +2 -0
- package/components/ButtonGroup.d.ts +6 -0
- package/components/Divider/Divider.cjs +6 -0
- package/components/Divider/Divider.cjs.map +1 -0
- package/components/Divider/Divider.d.ts +17 -0
- package/components/Divider/Divider.js +6 -0
- package/components/Divider/Divider.js.map +1 -0
- package/components/Divider/index.d.ts +2 -0
- package/components/Divider.d.ts +6 -0
- package/components/Modal/Modal.cjs +1 -1
- package/components/Modal/Modal.d.ts +2 -0
- package/components/Modal/Modal.js +1 -1
- package/index.cjs +7 -5
- package/index.cjs.map +1 -1
- package/index.d.ts +6 -0
- package/index.js +12 -7
- package/index.js.map +1 -1
- package/package.json +16 -1
- package/Modal-BqgnC6yu.js.map +0 -1
- package/Modal-CA0J0xpO.cjs.map +0 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const material = require("@mui/material");
|
|
4
|
+
function Breadcrumbs({
|
|
5
|
+
children,
|
|
6
|
+
separator,
|
|
7
|
+
maxItems,
|
|
8
|
+
sx,
|
|
9
|
+
className,
|
|
10
|
+
"aria-label": ariaLabel = "breadcrumb"
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
13
|
+
material.Breadcrumbs,
|
|
14
|
+
{
|
|
15
|
+
separator,
|
|
16
|
+
maxItems,
|
|
17
|
+
sx,
|
|
18
|
+
className,
|
|
19
|
+
"aria-label": ariaLabel,
|
|
20
|
+
children
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
exports.Breadcrumbs = Breadcrumbs;
|
|
25
|
+
//# sourceMappingURL=Breadcrumbs-B9I3vxPb.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumbs-B9I3vxPb.cjs","sources":["../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Breadcrumbs as MuiBreadcrumbs } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface BreadcrumbsProps {\n /** Items (Links / Typography). */\n children?: ReactNode;\n /** Separador entre items. Default: `/`. */\n separator?: ReactNode;\n /** Colapsa si hay más de N items. */\n maxItems?: number;\n sx?: SxProps<Theme>;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** Migas de pan. Wrapper fino sobre MUI `Breadcrumbs`. */\nexport function Breadcrumbs({\n children,\n separator,\n maxItems,\n sx,\n className,\n 'aria-label': ariaLabel = 'breadcrumb',\n}: BreadcrumbsProps) {\n return (\n <MuiBreadcrumbs\n separator={separator}\n maxItems={maxItems}\n sx={sx}\n className={className}\n aria-label={ariaLabel}\n >\n {children}\n </MuiBreadcrumbs>\n );\n}\n\nexport default Breadcrumbs;\n"],"names":["jsx","MuiBreadcrumbs"],"mappings":";;;AAiBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,YAAY;AAC5B,GAAqB;AACnB,SACEA,2BAAAA;AAAAA,IAACC,SAAAA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAY;AAAA,MAEX;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Breadcrumbs as Breadcrumbs$1 } from "@mui/material";
|
|
3
|
+
function Breadcrumbs({
|
|
4
|
+
children,
|
|
5
|
+
separator,
|
|
6
|
+
maxItems,
|
|
7
|
+
sx,
|
|
8
|
+
className,
|
|
9
|
+
"aria-label": ariaLabel = "breadcrumb"
|
|
10
|
+
}) {
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
Breadcrumbs$1,
|
|
13
|
+
{
|
|
14
|
+
separator,
|
|
15
|
+
maxItems,
|
|
16
|
+
sx,
|
|
17
|
+
className,
|
|
18
|
+
"aria-label": ariaLabel,
|
|
19
|
+
children
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
Breadcrumbs as B
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=Breadcrumbs-C41SPbtX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumbs-C41SPbtX.js","sources":["../src/components/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Breadcrumbs as MuiBreadcrumbs } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface BreadcrumbsProps {\n /** Items (Links / Typography). */\n children?: ReactNode;\n /** Separador entre items. Default: `/`. */\n separator?: ReactNode;\n /** Colapsa si hay más de N items. */\n maxItems?: number;\n sx?: SxProps<Theme>;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** Migas de pan. Wrapper fino sobre MUI `Breadcrumbs`. */\nexport function Breadcrumbs({\n children,\n separator,\n maxItems,\n sx,\n className,\n 'aria-label': ariaLabel = 'breadcrumb',\n}: BreadcrumbsProps) {\n return (\n <MuiBreadcrumbs\n separator={separator}\n maxItems={maxItems}\n sx={sx}\n className={className}\n aria-label={ariaLabel}\n >\n {children}\n </MuiBreadcrumbs>\n );\n}\n\nexport default Breadcrumbs;\n"],"names":["MuiBreadcrumbs"],"mappings":";;AAiBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc,YAAY;AAC5B,GAAqB;AACnB,SACE;AAAA,IAACA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAY;AAAA,MAEX;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const material = require("@mui/material");
|
|
4
|
+
function ButtonGroup({
|
|
5
|
+
children,
|
|
6
|
+
size = "medium",
|
|
7
|
+
variant = "outlined",
|
|
8
|
+
orientation = "horizontal",
|
|
9
|
+
color = "primary",
|
|
10
|
+
disabled,
|
|
11
|
+
fullWidth,
|
|
12
|
+
sx,
|
|
13
|
+
className,
|
|
14
|
+
"aria-label": ariaLabel
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17
|
+
material.ButtonGroup,
|
|
18
|
+
{
|
|
19
|
+
size,
|
|
20
|
+
variant,
|
|
21
|
+
orientation,
|
|
22
|
+
color,
|
|
23
|
+
disabled,
|
|
24
|
+
fullWidth,
|
|
25
|
+
sx,
|
|
26
|
+
className,
|
|
27
|
+
"aria-label": ariaLabel,
|
|
28
|
+
children
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
exports.ButtonGroup = ButtonGroup;
|
|
33
|
+
//# sourceMappingURL=ButtonGroup-CNunDofQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonGroup-CNunDofQ.cjs","sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { ButtonGroup as MuiButtonGroup } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface ButtonGroupProps {\n /** Botones agrupados. */\n children?: ReactNode;\n size?: 'small' | 'medium' | 'large';\n variant?: 'text' | 'outlined' | 'contained';\n orientation?: 'horizontal' | 'vertical';\n color?: 'inherit' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n disabled?: boolean;\n fullWidth?: boolean;\n sx?: SxProps<Theme>;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** Grupo de botones segmentado. Wrapper fino sobre MUI `ButtonGroup`. */\nexport function ButtonGroup({\n children,\n size = 'medium',\n variant = 'outlined',\n orientation = 'horizontal',\n color = 'primary',\n disabled,\n fullWidth,\n sx,\n className,\n 'aria-label': ariaLabel,\n}: ButtonGroupProps) {\n return (\n <MuiButtonGroup\n size={size}\n variant={variant}\n orientation={orientation}\n color={color}\n disabled={disabled}\n fullWidth={fullWidth}\n sx={sx}\n className={className}\n aria-label={ariaLabel}\n >\n {children}\n </MuiButtonGroup>\n );\n}\n\nexport default ButtonGroup;\n"],"names":["jsx","MuiButtonGroup"],"mappings":";;;AAmBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAAqB;AACnB,SACEA,2BAAAA;AAAAA,IAACC,SAAAA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAY;AAAA,MAEX;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ButtonGroup as ButtonGroup$1 } from "@mui/material";
|
|
3
|
+
function ButtonGroup({
|
|
4
|
+
children,
|
|
5
|
+
size = "medium",
|
|
6
|
+
variant = "outlined",
|
|
7
|
+
orientation = "horizontal",
|
|
8
|
+
color = "primary",
|
|
9
|
+
disabled,
|
|
10
|
+
fullWidth,
|
|
11
|
+
sx,
|
|
12
|
+
className,
|
|
13
|
+
"aria-label": ariaLabel
|
|
14
|
+
}) {
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
ButtonGroup$1,
|
|
17
|
+
{
|
|
18
|
+
size,
|
|
19
|
+
variant,
|
|
20
|
+
orientation,
|
|
21
|
+
color,
|
|
22
|
+
disabled,
|
|
23
|
+
fullWidth,
|
|
24
|
+
sx,
|
|
25
|
+
className,
|
|
26
|
+
"aria-label": ariaLabel,
|
|
27
|
+
children
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
ButtonGroup as B
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=ButtonGroup-CcKUZ-lT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonGroup-CcKUZ-lT.js","sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { ButtonGroup as MuiButtonGroup } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface ButtonGroupProps {\n /** Botones agrupados. */\n children?: ReactNode;\n size?: 'small' | 'medium' | 'large';\n variant?: 'text' | 'outlined' | 'contained';\n orientation?: 'horizontal' | 'vertical';\n color?: 'inherit' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';\n disabled?: boolean;\n fullWidth?: boolean;\n sx?: SxProps<Theme>;\n className?: string;\n 'aria-label'?: string;\n}\n\n/** Grupo de botones segmentado. Wrapper fino sobre MUI `ButtonGroup`. */\nexport function ButtonGroup({\n children,\n size = 'medium',\n variant = 'outlined',\n orientation = 'horizontal',\n color = 'primary',\n disabled,\n fullWidth,\n sx,\n className,\n 'aria-label': ariaLabel,\n}: ButtonGroupProps) {\n return (\n <MuiButtonGroup\n size={size}\n variant={variant}\n orientation={orientation}\n color={color}\n disabled={disabled}\n fullWidth={fullWidth}\n sx={sx}\n className={className}\n aria-label={ariaLabel}\n >\n {children}\n </MuiButtonGroup>\n );\n}\n\nexport default ButtonGroup;\n"],"names":["MuiButtonGroup"],"mappings":";;AAmBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAAqB;AACnB,SACE;AAAA,IAACA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAY;AAAA,MAEX;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Divider as Divider$1 } from "@mui/material";
|
|
3
|
+
function Divider({
|
|
4
|
+
orientation = "horizontal",
|
|
5
|
+
variant = "fullWidth",
|
|
6
|
+
flexItem,
|
|
7
|
+
textAlign,
|
|
8
|
+
children,
|
|
9
|
+
sx,
|
|
10
|
+
className
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
Divider$1,
|
|
14
|
+
{
|
|
15
|
+
orientation,
|
|
16
|
+
variant,
|
|
17
|
+
flexItem,
|
|
18
|
+
textAlign,
|
|
19
|
+
sx,
|
|
20
|
+
className,
|
|
21
|
+
children
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
Divider as D
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=Divider-BApcM5CV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider-BApcM5CV.js","sources":["../src/components/Divider/Divider.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Divider as MuiDivider } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface DividerProps {\n orientation?: 'horizontal' | 'vertical';\n variant?: 'fullWidth' | 'inset' | 'middle';\n /** Para usar dentro de contenedores flex (ej. divider vertical). */\n flexItem?: boolean;\n /** Alineación del contenido cuando hay `children` (label centrado, etc.). */\n textAlign?: 'center' | 'left' | 'right';\n /** Contenido opcional (label) en medio del divider. */\n children?: ReactNode;\n sx?: SxProps<Theme>;\n className?: string;\n}\n\n/** Separador. Wrapper fino sobre MUI `Divider`. */\nexport function Divider({\n orientation = 'horizontal',\n variant = 'fullWidth',\n flexItem,\n textAlign,\n children,\n sx,\n className,\n}: DividerProps) {\n return (\n <MuiDivider\n orientation={orientation}\n variant={variant}\n flexItem={flexItem}\n textAlign={textAlign}\n sx={sx}\n className={className}\n >\n {children}\n </MuiDivider>\n );\n}\n\nexport default Divider;\n"],"names":["MuiDivider"],"mappings":";;AAkBO,SAAS,QAAQ;AAAA,EACtB,cAAc;AAAA,EACd,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,SACE;AAAA,IAACA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const material = require("@mui/material");
|
|
4
|
+
function Divider({
|
|
5
|
+
orientation = "horizontal",
|
|
6
|
+
variant = "fullWidth",
|
|
7
|
+
flexItem,
|
|
8
|
+
textAlign,
|
|
9
|
+
children,
|
|
10
|
+
sx,
|
|
11
|
+
className
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
14
|
+
material.Divider,
|
|
15
|
+
{
|
|
16
|
+
orientation,
|
|
17
|
+
variant,
|
|
18
|
+
flexItem,
|
|
19
|
+
textAlign,
|
|
20
|
+
sx,
|
|
21
|
+
className,
|
|
22
|
+
children
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
exports.Divider = Divider;
|
|
27
|
+
//# sourceMappingURL=Divider-CIY0JK4U.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider-CIY0JK4U.cjs","sources":["../src/components/Divider/Divider.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Divider as MuiDivider } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport interface DividerProps {\n orientation?: 'horizontal' | 'vertical';\n variant?: 'fullWidth' | 'inset' | 'middle';\n /** Para usar dentro de contenedores flex (ej. divider vertical). */\n flexItem?: boolean;\n /** Alineación del contenido cuando hay `children` (label centrado, etc.). */\n textAlign?: 'center' | 'left' | 'right';\n /** Contenido opcional (label) en medio del divider. */\n children?: ReactNode;\n sx?: SxProps<Theme>;\n className?: string;\n}\n\n/** Separador. Wrapper fino sobre MUI `Divider`. */\nexport function Divider({\n orientation = 'horizontal',\n variant = 'fullWidth',\n flexItem,\n textAlign,\n children,\n sx,\n className,\n}: DividerProps) {\n return (\n <MuiDivider\n orientation={orientation}\n variant={variant}\n flexItem={flexItem}\n textAlign={textAlign}\n sx={sx}\n className={className}\n >\n {children}\n </MuiDivider>\n );\n}\n\nexport default Divider;\n"],"names":["jsx","MuiDivider"],"mappings":";;;AAkBO,SAAS,QAAQ;AAAA,EACtB,cAAc;AAAA,EACd,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,SACEA,2BAAAA;AAAAA,IAACC,SAAAA;AAAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEC;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
|
|
@@ -152,6 +152,7 @@ const Modal = forwardRef(
|
|
|
152
152
|
hiddenBody = false,
|
|
153
153
|
hiddenFooter = false,
|
|
154
154
|
staticBackdrop = false,
|
|
155
|
+
"data-testid": dataTestId,
|
|
155
156
|
sx,
|
|
156
157
|
paperSx,
|
|
157
158
|
className,
|
|
@@ -236,7 +237,7 @@ const Modal = forwardRef(
|
|
|
236
237
|
"aria-describedby": message ? descId : void 0,
|
|
237
238
|
closeAfterTransition: true,
|
|
238
239
|
sx,
|
|
239
|
-
children: /* @__PURE__ */ jsxs(Paper, { className, sx: mergedPaperSx, children: [
|
|
240
|
+
children: /* @__PURE__ */ jsxs(Paper, { className, sx: mergedPaperSx, "data-testid": dataTestId, children: [
|
|
240
241
|
/* @__PURE__ */ jsxs(Stack, { spacing: 2.5, sx: { p: 3, alignItems: "center", textAlign: "center" }, children: [
|
|
241
242
|
/* @__PURE__ */ jsx(
|
|
242
243
|
Box,
|
|
@@ -332,7 +333,7 @@ const Modal = forwardRef(
|
|
|
332
333
|
"aria-describedby": descId,
|
|
333
334
|
closeAfterTransition: true,
|
|
334
335
|
sx,
|
|
335
|
-
children: /* @__PURE__ */ jsx(Paper, { className, sx: mergedPaperSx, children: renderChildren() })
|
|
336
|
+
children: /* @__PURE__ */ jsx(Paper, { className, sx: mergedPaperSx, "data-testid": dataTestId, children: renderChildren() })
|
|
336
337
|
}
|
|
337
338
|
);
|
|
338
339
|
}
|
|
@@ -348,4 +349,4 @@ export {
|
|
|
348
349
|
ModalBody as b,
|
|
349
350
|
ModalFooter as c
|
|
350
351
|
};
|
|
351
|
-
//# sourceMappingURL=Modal-
|
|
352
|
+
//# sourceMappingURL=Modal-C_QY7ZzY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal-C_QY7ZzY.js","sources":["../src/components/Modal/ModalFooter.tsx","../src/components/Modal/ModalHeader.tsx","../src/components/Modal/ModalBody.tsx","../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Stack } from '@mui/material';\nimport type { ButtonProps as MuiButtonProps } from '@mui/material/Button';\n\nimport { Button } from '../Button';\n\n// Interfaz para acciones personalizadas (se mantiene aquí)\nexport interface ModalAction {\n text: string;\n onClick?: () => void;\n disabled?: boolean;\n variant?: MuiButtonProps['variant'];\n color?: MuiButtonProps['color'];\n /**\n * Props adicionales que se forwardean al `<Button>` interno. Útil para casos\n * avanzados como conectar el botón con un `<form id=\"...\">` externo usando\n * `buttonProps={{ type: 'submit', form: 'my-form-id' }}`.\n */\n buttonProps?: Partial<MuiButtonProps> & { form?: string };\n}\n\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n onClose: () => void;\n actions?: ModalAction[];\n}\n\nexport const ModalFooter: React.FC<ModalFooterProps> = ({\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n onClose,\n actions = [],\n}) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 1,\n }}\n >\n {children}\n <Stack direction=\"row\" spacing={1}>\n {showCloseButton && (\n <Button\n onClick={onClose}\n disabled={closeButtonDisabled}\n variant=\"outlined\"\n color=\"secondary\"\n >\n {closeButtonText}\n </Button>\n )}\n {actions.map((action) => {\n const { buttonProps, text, onClick, disabled, variant, color } = action;\n return (\n <Button\n key={text}\n onClick={onClick}\n disabled={disabled}\n variant={variant || 'contained'}\n color={color || 'primary'}\n {...(buttonProps as any)}\n >\n {text}\n </Button>\n );\n })}\n </Stack>\n </Box>\n );\n};\n\nModalFooter.displayName = 'ModalFooter';\n\nexport default ModalFooter;\n","import React from 'react';\nimport { Box, Typography } from '@mui/material';\n\nexport interface ModalHeaderProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-labelledby` del Modal. Se setea\n * automáticamente cuando el header se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalHeader: React.FC<ModalHeaderProps> = ({ children, id }) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <Typography id={id} variant=\"h6\" component=\"h2\">\n {children}\n </Typography>\n </Box>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n\nexport default ModalHeader;\n","import React from 'react';\nimport { Box } from '@mui/material';\n\nexport interface ModalBodyProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-describedby` del Modal. Se setea\n * automáticamente cuando el body se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalBody: React.FC<ModalBodyProps> = ({ children, id }) => {\n return (\n <Box id={id} sx={{ padding: 2, overflowY: 'auto', flexGrow: 1 }}>\n {children}\n </Box>\n );\n};\n\nModalBody.displayName = 'ModalBody';\n\nexport default ModalBody;\n","import {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useImperativeHandle,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Modal as MuiModal,\n Paper,\n useMediaQuery,\n useTheme,\n Box,\n Stack,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';\nimport WarningAmberIcon from '@mui/icons-material/WarningAmber';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';\nimport CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';\n\nimport type { DialogProps } from '@mui/material/Dialog';\nimport { ModalFooter, type ModalAction, type ModalFooterProps } from './ModalFooter';\nimport { ModalHeader } from './ModalHeader';\nimport { ModalBody } from './ModalBody';\nimport { mergeSx } from '../_shared/mergeSx';\n\n// Detección robusta de sub-componentes — funciona con wrappers / HMR que\n// rompen la igualdad de referencia (`child.type === ModalHeader`).\nconst isModalSlot = (\n child: ReactElement,\n Component: unknown,\n displayName: string,\n): boolean => {\n if (child.type === Component) return true;\n const type = child.type as { displayName?: string };\n return type?.displayName === displayName;\n};\n\n// Define la interfaz para los métodos que el padre puede llamar a través de la ref\nexport interface ModalRef {\n open: () => void;\n close: () => void;\n}\n\nexport type ModalMode = 'default' | 'confirm';\nexport type ModalSeverity = 'info' | 'warning' | 'error' | 'success';\n\nexport interface ModalProps {\n /**\n * Modo del modal.\n * - `default` (default): modal genérico con slots `Header`/`Body`/`Footer` y\n * `actions` custom.\n * - `confirm`: reemplaza al `ConfirmModal` legacy. Renderiza un layout\n * focalizado con icono por severidad, mensaje y botones \"Cancelar\" /\n * \"Confirmar\".\n */\n mode?: ModalMode;\n\n // ── Props comunes ────────────────────────────────────────────────────\n /** Controlado externamente. Omitir si se usa vía ref. */\n open?: boolean;\n /** Callback al cerrar. También se dispara al confirmar/cancelar. */\n onClose?: () => void;\n title?: string;\n children?: ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n actions?: ModalAction[];\n maxWidth?: DialogProps['maxWidth'];\n /**\n * Si `true`, el modal NO se cierra al hacer click en el backdrop ni con Escape\n * (equivale a `backdrop=\"static\"`). Cerrar solo vía botón/acción.\n */\n staticBackdrop?: boolean;\n /** Test id aplicado al Paper interno (contenedor visual). */\n 'data-testid'?: string;\n /** Oculta el header (incluso si hay `title` o se pasa un `<Modal.Header>`). */\n hiddenHeader?: boolean;\n /** Oculta el body (incluso si se pasa un `<Modal.Body>`). */\n hiddenBody?: boolean;\n /** Oculta el footer (incluso si se pasa un `<Modal.Footer>` o `actions`). */\n hiddenFooter?: boolean;\n /** sx del Modal root (MuiModal). */\n sx?: SxProps<Theme>;\n /** sx del Paper interno (contenedor visual). Se mergea sobre el default. */\n paperSx?: SxProps<Theme>;\n /** className del Paper interno. */\n className?: string;\n\n // ── Props del modo confirm ───────────────────────────────────────────\n /**\n * Callback de confirmación. Soporta promesa — si devuelve `Promise`, el\n * botón muestra estado `disabled` mientras resuelve.\n *\n * Si la promesa **rechaza**, el modal queda abierto para que el consumer\n * pueda mostrar el error en su UI. El modal se cierra solo en éxito.\n */\n onConfirm?: () => void | Promise<void>;\n /** Texto del botón primario en modo `confirm`. Default: \"Confirmar\". */\n confirmText?: string;\n /** Deshabilita el botón de confirmar. */\n confirmDisabled?: boolean;\n /**\n * Severidad visual en modo `confirm`. Controla el icono y el color del\n * botón de confirmación.\n * - `info` (default): primary\n * - `warning`: warning (amarillo)\n * - `error`: error (rojo) — típico para \"Eliminar\"\n * - `success`: success (verde) — típico para \"Aprobar\"\n */\n severity?: ModalSeverity;\n /**\n * Mensaje del confirm. Puede ser string o cualquier ReactNode. Si se omite,\n * se usa `children`.\n */\n confirmMessage?: ReactNode;\n}\n\nconst modalStyle = {\n position: 'absolute' as const,\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90%',\n maxHeight: '90vh',\n display: 'flex',\n flexDirection: 'column' as const,\n outline: 'none',\n};\n\nconst severityConfig: Record<\n ModalSeverity,\n { color: ModalAction['color']; icon: ReactNode; paletteKey: 'primary' | 'warning' | 'error' | 'success' }\n> = {\n info: {\n color: 'primary',\n icon: <InfoOutlinedIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'primary',\n },\n warning: {\n color: 'warning',\n icon: <WarningAmberIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'warning',\n },\n error: {\n color: 'error',\n icon: <ErrorOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'error',\n },\n success: {\n color: 'success',\n icon: <CheckCircleOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'success',\n },\n};\n\nexport const Modal = forwardRef<ModalRef, ModalProps>(\n (\n {\n mode = 'default',\n open: controlledOpen,\n onClose: controlledOnClose,\n title,\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n actions = [],\n maxWidth = 'sm',\n hiddenHeader = false,\n hiddenBody = false,\n hiddenFooter = false,\n staticBackdrop = false,\n 'data-testid': dataTestId,\n sx,\n paperSx,\n className,\n\n // Props del modo confirm\n onConfirm,\n confirmText = 'Confirmar',\n confirmDisabled = false,\n severity = 'info',\n confirmMessage,\n },\n ref,\n ) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const [confirmLoading, setConfirmLoading] = useState(false);\n\n // IDs estables para a11y: `aria-labelledby` y `aria-describedby`.\n const titleId = useId();\n const descId = useId();\n\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n useImperativeHandle(ref, () => ({\n open: () => setInternalOpen(true),\n close: () => {\n setInternalOpen(false);\n controlledOnClose?.();\n },\n }));\n\n const handleCloseInternal = (\n _event?: object,\n reason?: 'backdropClick' | 'escapeKeyDown',\n ) => {\n // Backdrop estático: ignora cierres por click fuera o Escape.\n if (\n staticBackdrop &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n setInternalOpen(false);\n controlledOnClose?.();\n };\n\n const handleConfirm = async () => {\n if (!onConfirm) {\n handleCloseInternal();\n return;\n }\n const result = onConfirm();\n if (!(result instanceof Promise)) {\n handleCloseInternal();\n return;\n }\n setConfirmLoading(true);\n try {\n await result;\n handleCloseInternal();\n } catch (err) {\n // No cerrar el modal en caso de error — el consumer es responsable\n // de mostrar un estado de error en su UI. Logueamos para trazabilidad\n // en dev.\n // eslint-disable-next-line no-console\n console.error('Modal onConfirm failed:', err);\n } finally {\n setConfirmLoading(false);\n }\n };\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n\n const getWidth = () => {\n if (isMobile) return '95%';\n switch (maxWidth) {\n case 'xs':\n return 300;\n case 'sm':\n return 500;\n case 'md':\n return 700;\n case 'lg':\n return 900;\n case 'xl':\n return 1100;\n case false:\n return 'auto';\n default:\n // Soporta string custom: `maxWidth=\"600px\"` se pasa tal cual.\n return typeof maxWidth === 'string' ? maxWidth : 500;\n }\n };\n\n // Base sx del Paper + width responsive; el consumer puede pisarlos via `paperSx`.\n const paperBaseSx: SxProps<Theme> = { ...modalStyle, width: getWidth() };\n const mergedPaperSx = mergeSx(paperBaseSx, paperSx);\n\n // ── Render modo CONFIRM ─────────────────────────────────────────────\n if (mode === 'confirm') {\n const config = severityConfig[severity];\n const message = confirmMessage ?? children;\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={message ? descId : undefined}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx} data-testid={dataTestId}>\n <Stack spacing={2.5} sx={{ p: 3, alignItems: 'center', textAlign: 'center' }}>\n <Box\n sx={{\n width: 72,\n height: 72,\n borderRadius: '50%',\n backgroundColor: (t) => t.palette[config.paletteKey].light,\n color: (t) => t.palette[config.paletteKey].dark,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: 0.9,\n }}\n >\n {config.icon}\n </Box>\n {title && (\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{ fontWeight: 700 }}>\n {title}\n </Typography>\n )}\n {message && (\n <Typography id={descId} variant=\"body2\" color=\"text.secondary\">\n {message}\n </Typography>\n )}\n </Stack>\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled || confirmLoading}\n onClose={handleCloseInternal}\n actions={[\n {\n text: confirmText,\n onClick: handleConfirm,\n disabled: confirmDisabled || confirmLoading,\n variant: 'contained',\n color: config.color,\n },\n ]}\n />\n </Paper>\n </MuiModal>\n );\n }\n\n // ── Render modo DEFAULT (compuesto) ─────────────────────────────────\n const renderChildren = () => {\n let header: ReactNode | null = null;\n let body: ReactNode | null = null;\n let footer: ReactNode | null = null;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n\n if (isModalSlot(child, ModalHeader, 'ModalHeader')) {\n const headerChild = child as ReactElement<{ id?: string }>;\n header = cloneElement(headerChild, { id: titleId, ...headerChild.props });\n } else if (isModalSlot(child, ModalBody, 'ModalBody')) {\n const bodyChild = child as ReactElement<{ id?: string }>;\n body = cloneElement(bodyChild, { id: descId, ...bodyChild.props });\n } else if (isModalSlot(child, ModalFooter, 'ModalFooter')) {\n const footerChild = child as ReactElement<ModalFooterProps>;\n // Props del child ganan sobre los del Modal padre: si el consumer\n // declara `<Modal.Footer showCloseButton={false}>`, ese valor se\n // respeta. Solo los que vengan `undefined` caen al default del padre.\n const childProps = footerChild.props;\n footer = cloneElement(footerChild, {\n showCloseButton: childProps.showCloseButton ?? showCloseButton,\n closeButtonText: childProps.closeButtonText ?? closeButtonText,\n closeButtonDisabled: childProps.closeButtonDisabled ?? closeButtonDisabled,\n onClose: childProps.onClose ?? handleCloseInternal,\n actions: childProps.actions ?? actions,\n });\n }\n });\n\n if (!footer && !hiddenFooter) {\n footer = (\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled}\n onClose={handleCloseInternal}\n actions={actions}\n />\n );\n }\n\n return (\n <>\n {!hiddenHeader && (header || (title && <ModalHeader id={titleId}>{title}</ModalHeader>))}\n {!hiddenBody && body}\n {footer}\n </>\n );\n };\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={titleId}\n aria-describedby={descId}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx} data-testid={dataTestId}>\n {renderChildren()}\n </Paper>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\n// Define los sub-componentes como propiedades estáticas con tipos explícitos\ntype ModalComponent = ReturnType<typeof forwardRef<ModalRef, ModalProps>> & {\n Header: typeof ModalHeader;\n Body: typeof ModalBody;\n Footer: typeof ModalFooter;\n};\n\nconst ModalWithStatics = Modal as ModalComponent;\n\nModalWithStatics.Header = ModalHeader;\nModalWithStatics.Body = ModalBody;\nModalWithStatics.Footer = ModalFooter;\n\nexport default ModalWithStatics;\n"],"names":["MuiModal"],"mappings":"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"}
|
|
@@ -153,6 +153,7 @@ const Modal = React.forwardRef(
|
|
|
153
153
|
hiddenBody = false,
|
|
154
154
|
hiddenFooter = false,
|
|
155
155
|
staticBackdrop = false,
|
|
156
|
+
"data-testid": dataTestId,
|
|
156
157
|
sx,
|
|
157
158
|
paperSx,
|
|
158
159
|
className,
|
|
@@ -237,7 +238,7 @@ const Modal = React.forwardRef(
|
|
|
237
238
|
"aria-describedby": message ? descId : void 0,
|
|
238
239
|
closeAfterTransition: true,
|
|
239
240
|
sx,
|
|
240
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(material.Paper, { className, sx: mergedPaperSx, children: [
|
|
241
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(material.Paper, { className, sx: mergedPaperSx, "data-testid": dataTestId, children: [
|
|
241
242
|
/* @__PURE__ */ jsxRuntime.jsxs(material.Stack, { spacing: 2.5, sx: { p: 3, alignItems: "center", textAlign: "center" }, children: [
|
|
242
243
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
243
244
|
material.Box,
|
|
@@ -333,7 +334,7 @@ const Modal = React.forwardRef(
|
|
|
333
334
|
"aria-describedby": descId,
|
|
334
335
|
closeAfterTransition: true,
|
|
335
336
|
sx,
|
|
336
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(material.Paper, { className, sx: mergedPaperSx, children: renderChildren() })
|
|
337
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(material.Paper, { className, sx: mergedPaperSx, "data-testid": dataTestId, children: renderChildren() })
|
|
337
338
|
}
|
|
338
339
|
);
|
|
339
340
|
}
|
|
@@ -347,4 +348,4 @@ exports.ModalBody = ModalBody;
|
|
|
347
348
|
exports.ModalFooter = ModalFooter;
|
|
348
349
|
exports.ModalHeader = ModalHeader;
|
|
349
350
|
exports.ModalWithStatics = ModalWithStatics;
|
|
350
|
-
//# sourceMappingURL=Modal-
|
|
351
|
+
//# sourceMappingURL=Modal-D_6ZdSzw.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal-D_6ZdSzw.cjs","sources":["../src/components/Modal/ModalFooter.tsx","../src/components/Modal/ModalHeader.tsx","../src/components/Modal/ModalBody.tsx","../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Stack } from '@mui/material';\nimport type { ButtonProps as MuiButtonProps } from '@mui/material/Button';\n\nimport { Button } from '../Button';\n\n// Interfaz para acciones personalizadas (se mantiene aquí)\nexport interface ModalAction {\n text: string;\n onClick?: () => void;\n disabled?: boolean;\n variant?: MuiButtonProps['variant'];\n color?: MuiButtonProps['color'];\n /**\n * Props adicionales que se forwardean al `<Button>` interno. Útil para casos\n * avanzados como conectar el botón con un `<form id=\"...\">` externo usando\n * `buttonProps={{ type: 'submit', form: 'my-form-id' }}`.\n */\n buttonProps?: Partial<MuiButtonProps> & { form?: string };\n}\n\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n onClose: () => void;\n actions?: ModalAction[];\n}\n\nexport const ModalFooter: React.FC<ModalFooterProps> = ({\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n onClose,\n actions = [],\n}) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 1,\n }}\n >\n {children}\n <Stack direction=\"row\" spacing={1}>\n {showCloseButton && (\n <Button\n onClick={onClose}\n disabled={closeButtonDisabled}\n variant=\"outlined\"\n color=\"secondary\"\n >\n {closeButtonText}\n </Button>\n )}\n {actions.map((action) => {\n const { buttonProps, text, onClick, disabled, variant, color } = action;\n return (\n <Button\n key={text}\n onClick={onClick}\n disabled={disabled}\n variant={variant || 'contained'}\n color={color || 'primary'}\n {...(buttonProps as any)}\n >\n {text}\n </Button>\n );\n })}\n </Stack>\n </Box>\n );\n};\n\nModalFooter.displayName = 'ModalFooter';\n\nexport default ModalFooter;\n","import React from 'react';\nimport { Box, Typography } from '@mui/material';\n\nexport interface ModalHeaderProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-labelledby` del Modal. Se setea\n * automáticamente cuando el header se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalHeader: React.FC<ModalHeaderProps> = ({ children, id }) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <Typography id={id} variant=\"h6\" component=\"h2\">\n {children}\n </Typography>\n </Box>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n\nexport default ModalHeader;\n","import React from 'react';\nimport { Box } from '@mui/material';\n\nexport interface ModalBodyProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-describedby` del Modal. Se setea\n * automáticamente cuando el body se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalBody: React.FC<ModalBodyProps> = ({ children, id }) => {\n return (\n <Box id={id} sx={{ padding: 2, overflowY: 'auto', flexGrow: 1 }}>\n {children}\n </Box>\n );\n};\n\nModalBody.displayName = 'ModalBody';\n\nexport default ModalBody;\n","import {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useImperativeHandle,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Modal as MuiModal,\n Paper,\n useMediaQuery,\n useTheme,\n Box,\n Stack,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';\nimport WarningAmberIcon from '@mui/icons-material/WarningAmber';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';\nimport CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';\n\nimport type { DialogProps } from '@mui/material/Dialog';\nimport { ModalFooter, type ModalAction, type ModalFooterProps } from './ModalFooter';\nimport { ModalHeader } from './ModalHeader';\nimport { ModalBody } from './ModalBody';\nimport { mergeSx } from '../_shared/mergeSx';\n\n// Detección robusta de sub-componentes — funciona con wrappers / HMR que\n// rompen la igualdad de referencia (`child.type === ModalHeader`).\nconst isModalSlot = (\n child: ReactElement,\n Component: unknown,\n displayName: string,\n): boolean => {\n if (child.type === Component) return true;\n const type = child.type as { displayName?: string };\n return type?.displayName === displayName;\n};\n\n// Define la interfaz para los métodos que el padre puede llamar a través de la ref\nexport interface ModalRef {\n open: () => void;\n close: () => void;\n}\n\nexport type ModalMode = 'default' | 'confirm';\nexport type ModalSeverity = 'info' | 'warning' | 'error' | 'success';\n\nexport interface ModalProps {\n /**\n * Modo del modal.\n * - `default` (default): modal genérico con slots `Header`/`Body`/`Footer` y\n * `actions` custom.\n * - `confirm`: reemplaza al `ConfirmModal` legacy. Renderiza un layout\n * focalizado con icono por severidad, mensaje y botones \"Cancelar\" /\n * \"Confirmar\".\n */\n mode?: ModalMode;\n\n // ── Props comunes ────────────────────────────────────────────────────\n /** Controlado externamente. Omitir si se usa vía ref. */\n open?: boolean;\n /** Callback al cerrar. También se dispara al confirmar/cancelar. */\n onClose?: () => void;\n title?: string;\n children?: ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n actions?: ModalAction[];\n maxWidth?: DialogProps['maxWidth'];\n /**\n * Si `true`, el modal NO se cierra al hacer click en el backdrop ni con Escape\n * (equivale a `backdrop=\"static\"`). Cerrar solo vía botón/acción.\n */\n staticBackdrop?: boolean;\n /** Test id aplicado al Paper interno (contenedor visual). */\n 'data-testid'?: string;\n /** Oculta el header (incluso si hay `title` o se pasa un `<Modal.Header>`). */\n hiddenHeader?: boolean;\n /** Oculta el body (incluso si se pasa un `<Modal.Body>`). */\n hiddenBody?: boolean;\n /** Oculta el footer (incluso si se pasa un `<Modal.Footer>` o `actions`). */\n hiddenFooter?: boolean;\n /** sx del Modal root (MuiModal). */\n sx?: SxProps<Theme>;\n /** sx del Paper interno (contenedor visual). Se mergea sobre el default. */\n paperSx?: SxProps<Theme>;\n /** className del Paper interno. */\n className?: string;\n\n // ── Props del modo confirm ───────────────────────────────────────────\n /**\n * Callback de confirmación. Soporta promesa — si devuelve `Promise`, el\n * botón muestra estado `disabled` mientras resuelve.\n *\n * Si la promesa **rechaza**, el modal queda abierto para que el consumer\n * pueda mostrar el error en su UI. El modal se cierra solo en éxito.\n */\n onConfirm?: () => void | Promise<void>;\n /** Texto del botón primario en modo `confirm`. Default: \"Confirmar\". */\n confirmText?: string;\n /** Deshabilita el botón de confirmar. */\n confirmDisabled?: boolean;\n /**\n * Severidad visual en modo `confirm`. Controla el icono y el color del\n * botón de confirmación.\n * - `info` (default): primary\n * - `warning`: warning (amarillo)\n * - `error`: error (rojo) — típico para \"Eliminar\"\n * - `success`: success (verde) — típico para \"Aprobar\"\n */\n severity?: ModalSeverity;\n /**\n * Mensaje del confirm. Puede ser string o cualquier ReactNode. Si se omite,\n * se usa `children`.\n */\n confirmMessage?: ReactNode;\n}\n\nconst modalStyle = {\n position: 'absolute' as const,\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90%',\n maxHeight: '90vh',\n display: 'flex',\n flexDirection: 'column' as const,\n outline: 'none',\n};\n\nconst severityConfig: Record<\n ModalSeverity,\n { color: ModalAction['color']; icon: ReactNode; paletteKey: 'primary' | 'warning' | 'error' | 'success' }\n> = {\n info: {\n color: 'primary',\n icon: <InfoOutlinedIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'primary',\n },\n warning: {\n color: 'warning',\n icon: <WarningAmberIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'warning',\n },\n error: {\n color: 'error',\n icon: <ErrorOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'error',\n },\n success: {\n color: 'success',\n icon: <CheckCircleOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'success',\n },\n};\n\nexport const Modal = forwardRef<ModalRef, ModalProps>(\n (\n {\n mode = 'default',\n open: controlledOpen,\n onClose: controlledOnClose,\n title,\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n actions = [],\n maxWidth = 'sm',\n hiddenHeader = false,\n hiddenBody = false,\n hiddenFooter = false,\n staticBackdrop = false,\n 'data-testid': dataTestId,\n sx,\n paperSx,\n className,\n\n // Props del modo confirm\n onConfirm,\n confirmText = 'Confirmar',\n confirmDisabled = false,\n severity = 'info',\n confirmMessage,\n },\n ref,\n ) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const [confirmLoading, setConfirmLoading] = useState(false);\n\n // IDs estables para a11y: `aria-labelledby` y `aria-describedby`.\n const titleId = useId();\n const descId = useId();\n\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n useImperativeHandle(ref, () => ({\n open: () => setInternalOpen(true),\n close: () => {\n setInternalOpen(false);\n controlledOnClose?.();\n },\n }));\n\n const handleCloseInternal = (\n _event?: object,\n reason?: 'backdropClick' | 'escapeKeyDown',\n ) => {\n // Backdrop estático: ignora cierres por click fuera o Escape.\n if (\n staticBackdrop &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n setInternalOpen(false);\n controlledOnClose?.();\n };\n\n const handleConfirm = async () => {\n if (!onConfirm) {\n handleCloseInternal();\n return;\n }\n const result = onConfirm();\n if (!(result instanceof Promise)) {\n handleCloseInternal();\n return;\n }\n setConfirmLoading(true);\n try {\n await result;\n handleCloseInternal();\n } catch (err) {\n // No cerrar el modal en caso de error — el consumer es responsable\n // de mostrar un estado de error en su UI. Logueamos para trazabilidad\n // en dev.\n // eslint-disable-next-line no-console\n console.error('Modal onConfirm failed:', err);\n } finally {\n setConfirmLoading(false);\n }\n };\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n\n const getWidth = () => {\n if (isMobile) return '95%';\n switch (maxWidth) {\n case 'xs':\n return 300;\n case 'sm':\n return 500;\n case 'md':\n return 700;\n case 'lg':\n return 900;\n case 'xl':\n return 1100;\n case false:\n return 'auto';\n default:\n // Soporta string custom: `maxWidth=\"600px\"` se pasa tal cual.\n return typeof maxWidth === 'string' ? maxWidth : 500;\n }\n };\n\n // Base sx del Paper + width responsive; el consumer puede pisarlos via `paperSx`.\n const paperBaseSx: SxProps<Theme> = { ...modalStyle, width: getWidth() };\n const mergedPaperSx = mergeSx(paperBaseSx, paperSx);\n\n // ── Render modo CONFIRM ─────────────────────────────────────────────\n if (mode === 'confirm') {\n const config = severityConfig[severity];\n const message = confirmMessage ?? children;\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={message ? descId : undefined}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx} data-testid={dataTestId}>\n <Stack spacing={2.5} sx={{ p: 3, alignItems: 'center', textAlign: 'center' }}>\n <Box\n sx={{\n width: 72,\n height: 72,\n borderRadius: '50%',\n backgroundColor: (t) => t.palette[config.paletteKey].light,\n color: (t) => t.palette[config.paletteKey].dark,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: 0.9,\n }}\n >\n {config.icon}\n </Box>\n {title && (\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{ fontWeight: 700 }}>\n {title}\n </Typography>\n )}\n {message && (\n <Typography id={descId} variant=\"body2\" color=\"text.secondary\">\n {message}\n </Typography>\n )}\n </Stack>\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled || confirmLoading}\n onClose={handleCloseInternal}\n actions={[\n {\n text: confirmText,\n onClick: handleConfirm,\n disabled: confirmDisabled || confirmLoading,\n variant: 'contained',\n color: config.color,\n },\n ]}\n />\n </Paper>\n </MuiModal>\n );\n }\n\n // ── Render modo DEFAULT (compuesto) ─────────────────────────────────\n const renderChildren = () => {\n let header: ReactNode | null = null;\n let body: ReactNode | null = null;\n let footer: ReactNode | null = null;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n\n if (isModalSlot(child, ModalHeader, 'ModalHeader')) {\n const headerChild = child as ReactElement<{ id?: string }>;\n header = cloneElement(headerChild, { id: titleId, ...headerChild.props });\n } else if (isModalSlot(child, ModalBody, 'ModalBody')) {\n const bodyChild = child as ReactElement<{ id?: string }>;\n body = cloneElement(bodyChild, { id: descId, ...bodyChild.props });\n } else if (isModalSlot(child, ModalFooter, 'ModalFooter')) {\n const footerChild = child as ReactElement<ModalFooterProps>;\n // Props del child ganan sobre los del Modal padre: si el consumer\n // declara `<Modal.Footer showCloseButton={false}>`, ese valor se\n // respeta. Solo los que vengan `undefined` caen al default del padre.\n const childProps = footerChild.props;\n footer = cloneElement(footerChild, {\n showCloseButton: childProps.showCloseButton ?? showCloseButton,\n closeButtonText: childProps.closeButtonText ?? closeButtonText,\n closeButtonDisabled: childProps.closeButtonDisabled ?? closeButtonDisabled,\n onClose: childProps.onClose ?? handleCloseInternal,\n actions: childProps.actions ?? actions,\n });\n }\n });\n\n if (!footer && !hiddenFooter) {\n footer = (\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled}\n onClose={handleCloseInternal}\n actions={actions}\n />\n );\n }\n\n return (\n <>\n {!hiddenHeader && (header || (title && <ModalHeader id={titleId}>{title}</ModalHeader>))}\n {!hiddenBody && body}\n {footer}\n </>\n );\n };\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={titleId}\n aria-describedby={descId}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx} data-testid={dataTestId}>\n {renderChildren()}\n </Paper>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\n// Define los sub-componentes como propiedades estáticas con tipos explícitos\ntype ModalComponent = ReturnType<typeof forwardRef<ModalRef, ModalProps>> & {\n Header: typeof ModalHeader;\n Body: typeof ModalBody;\n Footer: typeof ModalFooter;\n};\n\nconst ModalWithStatics = Modal as ModalComponent;\n\nModalWithStatics.Header = ModalHeader;\nModalWithStatics.Body = ModalBody;\nModalWithStatics.Footer = ModalFooter;\n\nexport default ModalWithStatics;\n"],"names":["jsxs","Box","Stack","jsx","Button","Typography","forwardRef","useState","useId","useImperativeHandle","useTheme","useMediaQuery","mergeSx","MuiModal","Paper","Children","isValidElement","cloneElement","Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const Breadcrumbs = require("../../Breadcrumbs-B9I3vxPb.cjs");
|
|
4
|
+
exports.Breadcrumbs = Breadcrumbs.Breadcrumbs;
|
|
5
|
+
exports.default = Breadcrumbs.Breadcrumbs;
|
|
6
|
+
//# sourceMappingURL=Breadcrumbs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumbs.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SxProps, Theme } from '@mui/material/styles';
|
|
3
|
+
export interface BreadcrumbsProps {
|
|
4
|
+
/** Items (Links / Typography). */
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
/** Separador entre items. Default: `/`. */
|
|
7
|
+
separator?: ReactNode;
|
|
8
|
+
/** Colapsa si hay más de N items. */
|
|
9
|
+
maxItems?: number;
|
|
10
|
+
sx?: SxProps<Theme>;
|
|
11
|
+
className?: string;
|
|
12
|
+
'aria-label'?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Migas de pan. Wrapper fino sobre MUI `Breadcrumbs`. */
|
|
15
|
+
export declare function Breadcrumbs({ children, separator, maxItems, sx, className, 'aria-label': ariaLabel, }: BreadcrumbsProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export default Breadcrumbs;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumbs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const ButtonGroup = require("../../ButtonGroup-CNunDofQ.cjs");
|
|
4
|
+
exports.ButtonGroup = ButtonGroup.ButtonGroup;
|
|
5
|
+
exports.default = ButtonGroup.ButtonGroup;
|
|
6
|
+
//# sourceMappingURL=ButtonGroup.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonGroup.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SxProps, Theme } from '@mui/material/styles';
|
|
3
|
+
export interface ButtonGroupProps {
|
|
4
|
+
/** Botones agrupados. */
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
size?: 'small' | 'medium' | 'large';
|
|
7
|
+
variant?: 'text' | 'outlined' | 'contained';
|
|
8
|
+
orientation?: 'horizontal' | 'vertical';
|
|
9
|
+
color?: 'inherit' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
fullWidth?: boolean;
|
|
12
|
+
sx?: SxProps<Theme>;
|
|
13
|
+
className?: string;
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Grupo de botones segmentado. Wrapper fino sobre MUI `ButtonGroup`. */
|
|
17
|
+
export declare function ButtonGroup({ children, size, variant, orientation, color, disabled, fullWidth, sx, className, 'aria-label': ariaLabel, }: ButtonGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export default ButtonGroup;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonGroup.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const Divider = require("../../Divider-CIY0JK4U.cjs");
|
|
4
|
+
exports.Divider = Divider.Divider;
|
|
5
|
+
exports.default = Divider.Divider;
|
|
6
|
+
//# sourceMappingURL=Divider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SxProps, Theme } from '@mui/material/styles';
|
|
3
|
+
export interface DividerProps {
|
|
4
|
+
orientation?: 'horizontal' | 'vertical';
|
|
5
|
+
variant?: 'fullWidth' | 'inset' | 'middle';
|
|
6
|
+
/** Para usar dentro de contenedores flex (ej. divider vertical). */
|
|
7
|
+
flexItem?: boolean;
|
|
8
|
+
/** Alineación del contenido cuando hay `children` (label centrado, etc.). */
|
|
9
|
+
textAlign?: 'center' | 'left' | 'right';
|
|
10
|
+
/** Contenido opcional (label) en medio del divider. */
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
sx?: SxProps<Theme>;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Separador. Wrapper fino sobre MUI `Divider`. */
|
|
16
|
+
export declare function Divider({ orientation, variant, flexItem, textAlign, children, sx, className, }: DividerProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export default Divider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
-
const Modal = require("../../Modal-
|
|
3
|
+
const Modal = require("../../Modal-D_6ZdSzw.cjs");
|
|
4
4
|
exports.Modal = Modal.ModalWithStatics;
|
|
5
5
|
exports.ModalBody = Modal.ModalBody;
|
|
6
6
|
exports.ModalFooter = Modal.ModalFooter;
|
|
@@ -36,6 +36,8 @@ export interface ModalProps {
|
|
|
36
36
|
* (equivale a `backdrop="static"`). Cerrar solo vía botón/acción.
|
|
37
37
|
*/
|
|
38
38
|
staticBackdrop?: boolean;
|
|
39
|
+
/** Test id aplicado al Paper interno (contenedor visual). */
|
|
40
|
+
'data-testid'?: string;
|
|
39
41
|
/** Oculta el header (incluso si hay `title` o se pasa un `<Modal.Header>`). */
|
|
40
42
|
hiddenHeader?: boolean;
|
|
41
43
|
/** Oculta el body (incluso si se pasa un `<Modal.Body>`). */
|
package/index.cjs
CHANGED
|
@@ -11,11 +11,14 @@ const Avatar = require("./Avatar-Dw5rzayR.cjs");
|
|
|
11
11
|
const Stat = require("./Stat-BUcFCGrz.cjs");
|
|
12
12
|
const Spinner = require("./Spinner-D7qRmNS9.cjs");
|
|
13
13
|
const Alert = require("./Alert-B3SMPD1s.cjs");
|
|
14
|
+
const Divider = require("./Divider-CIY0JK4U.cjs");
|
|
15
|
+
const ButtonGroup = require("./ButtonGroup-CNunDofQ.cjs");
|
|
16
|
+
const Breadcrumbs = require("./Breadcrumbs-B9I3vxPb.cjs");
|
|
14
17
|
const Step = require("./Step-Nd7SJbRZ.cjs");
|
|
15
18
|
const Tab = require("./Tab-BbP8jBcK.cjs");
|
|
16
19
|
const Table = require("./Table-C4OM6rrC.cjs");
|
|
17
20
|
const StatusMessage = require("./StatusMessage-B3nXpuRl.cjs");
|
|
18
|
-
const Modal = require("./Modal-
|
|
21
|
+
const Modal = require("./Modal-D_6ZdSzw.cjs");
|
|
19
22
|
const Input = require("./Input-CScC87J5.cjs");
|
|
20
23
|
const Select = require("./Select-CURrHSyl.cjs");
|
|
21
24
|
const Autocomplete = require("./Autocomplete-CejWztBY.cjs");
|
|
@@ -58,10 +61,6 @@ Object.defineProperty(exports, "Container", {
|
|
|
58
61
|
enumerable: true,
|
|
59
62
|
get: () => material.Container
|
|
60
63
|
});
|
|
61
|
-
Object.defineProperty(exports, "Divider", {
|
|
62
|
-
enumerable: true,
|
|
63
|
-
get: () => material.Divider
|
|
64
|
-
});
|
|
65
64
|
Object.defineProperty(exports, "Fade", {
|
|
66
65
|
enumerable: true,
|
|
67
66
|
get: () => material.Fade
|
|
@@ -166,6 +165,9 @@ exports.Avatar = Avatar.Avatar;
|
|
|
166
165
|
exports.Stat = Stat.Stat;
|
|
167
166
|
exports.Spinner = Spinner.Spinner;
|
|
168
167
|
exports.Alert = Alert.Alert;
|
|
168
|
+
exports.Divider = Divider.Divider;
|
|
169
|
+
exports.ButtonGroup = ButtonGroup.ButtonGroup;
|
|
170
|
+
exports.Breadcrumbs = Breadcrumbs.Breadcrumbs;
|
|
169
171
|
exports.Step = Step.Step;
|
|
170
172
|
exports.Stepper = Step.Stepper;
|
|
171
173
|
exports.Tab = Tab.Tab;
|
package/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/utils/scrollToTop.ts"],"sourcesContent":["export interface ScrollToTopOptions {\n /** Comportamiento del scroll. Default: `'smooth'`. */\n behavior?: ScrollBehavior;\n /**\n * Elemento target del scroll. Default: `window`. Útil cuando el contenedor\n * scrolleable NO es `window` (p.ej. un `<Box>` con `overflow: auto`).\n */\n target?: Window | HTMLElement;\n /** Offset desde el top. Default: `0`. */\n top?: number;\n}\n\n/**\n * Hace scroll al tope (por default con animación suave). Safe en SSR — si\n * `window` no existe, es un no-op.\n *\n * Llamar tras mutaciones / cambios de filtros / apertura de modales para\n * asegurar que el usuario vea el mensaje de confirmación en la parte\n * superior de la página.\n *\n * ```ts\n * import { scrollToTop } from '@soyfri/shared-library';\n *\n * scrollToTop(); // window, smooth\n * scrollToTop({ behavior: 'auto' }); // window, instantáneo\n * scrollToTop({ target: myScrollableRef.current }); // container custom\n * ```\n */\nexport function scrollToTop({\n behavior = 'smooth',\n target = typeof window !== 'undefined' ? window : undefined,\n top = 0,\n}: ScrollToTopOptions = {}): void {\n if (!target) return;\n target.scrollTo({ top, left: 0, behavior });\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/utils/scrollToTop.ts"],"sourcesContent":["export interface ScrollToTopOptions {\n /** Comportamiento del scroll. Default: `'smooth'`. */\n behavior?: ScrollBehavior;\n /**\n * Elemento target del scroll. Default: `window`. Útil cuando el contenedor\n * scrolleable NO es `window` (p.ej. un `<Box>` con `overflow: auto`).\n */\n target?: Window | HTMLElement;\n /** Offset desde el top. Default: `0`. */\n top?: number;\n}\n\n/**\n * Hace scroll al tope (por default con animación suave). Safe en SSR — si\n * `window` no existe, es un no-op.\n *\n * Llamar tras mutaciones / cambios de filtros / apertura de modales para\n * asegurar que el usuario vea el mensaje de confirmación en la parte\n * superior de la página.\n *\n * ```ts\n * import { scrollToTop } from '@soyfri/shared-library';\n *\n * scrollToTop(); // window, smooth\n * scrollToTop({ behavior: 'auto' }); // window, instantáneo\n * scrollToTop({ target: myScrollableRef.current }); // container custom\n * ```\n */\nexport function scrollToTop({\n behavior = 'smooth',\n target = typeof window !== 'undefined' ? window : undefined,\n top = 0,\n}: ScrollToTopOptions = {}): void {\n if (!target) return;\n target.scrollTo({ top, left: 0, behavior });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BO,SAAS,YAAY;AAAA,EAC1B,WAAW;AAAA,EACX,SAAS,OAAO,WAAW,cAAc,SAAS;AAAA,EAClD,MAAM;AACR,IAAwB,IAAU;AAChC,MAAI,CAAC,OAAQ;AACb,SAAO,SAAS,EAAE,KAAK,MAAM,GAAG,UAAU;AAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/index.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ export { Spinner } from './components/Spinner';
|
|
|
14
14
|
export type { SpinnerProps, SpinnerSize, SpinnerColor } from './components/Spinner';
|
|
15
15
|
export { Alert } from './components/Alert';
|
|
16
16
|
export type { AlertProps, AlertSeverity, AlertVariant } from './components/Alert';
|
|
17
|
+
export { Divider } from './components/Divider';
|
|
18
|
+
export type { DividerProps } from './components/Divider';
|
|
19
|
+
export { ButtonGroup } from './components/ButtonGroup';
|
|
20
|
+
export type { ButtonGroupProps } from './components/ButtonGroup';
|
|
21
|
+
export { Breadcrumbs } from './components/Breadcrumbs';
|
|
22
|
+
export type { BreadcrumbsProps } from './components/Breadcrumbs';
|
|
17
23
|
export { Stepper, Step } from './components/Stepper';
|
|
18
24
|
export { Tabs, Tab } from './components/Tabs';
|
|
19
25
|
export { Table } from './components/Table';
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { D, r } from "./resolvePreset-K6_BfWHD.js";
|
|
2
|
-
import { AlertTitle, Backdrop, Box, CircularProgress, Collapse, Container,
|
|
2
|
+
import { AlertTitle, Backdrop, Box, CircularProgress, Collapse, Container, Fade, Grid, Grow, LinearProgress, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Paper, Skeleton, Snackbar, Stack, ThemeProvider, Typography, Zoom, alpha, createTheme, styled, useMediaQuery, useTheme } from "@mui/material";
|
|
3
3
|
import { renderMultiSectionDigitalClockTimeView } from "@mui/x-date-pickers/timeViewRenderers";
|
|
4
4
|
import { B } from "./Button-UkkP-bNw.js";
|
|
5
5
|
import { C } from "./Card-DYKGY-NG.js";
|
|
@@ -9,19 +9,22 @@ import { A } from "./Avatar-H8akSege.js";
|
|
|
9
9
|
import { S } from "./Stat-C06A_izS.js";
|
|
10
10
|
import { S as S2 } from "./Spinner-B6sThC1p.js";
|
|
11
11
|
import { A as A2 } from "./Alert-YsPScpSE.js";
|
|
12
|
+
import { D as D2 } from "./Divider-BApcM5CV.js";
|
|
13
|
+
import { B as B2 } from "./ButtonGroup-CcKUZ-lT.js";
|
|
14
|
+
import { B as B3 } from "./Breadcrumbs-C41SPbtX.js";
|
|
12
15
|
import { a, S as S3 } from "./Step-BArsou1V.js";
|
|
13
16
|
import { a as a2, T } from "./Tab-BxSxKJsP.js";
|
|
14
17
|
import { T as T2 } from "./Table-C2LbW0B1.js";
|
|
15
18
|
import { S as S4 } from "./StatusMessage-D0WgSBx7.js";
|
|
16
|
-
import { M, b, c, a as a3 } from "./Modal-
|
|
19
|
+
import { M, b, c, a as a3 } from "./Modal-C_QY7ZzY.js";
|
|
17
20
|
import { I } from "./Input-DP_fKl38.js";
|
|
18
21
|
import { O, S as S5 } from "./Select-BY5Y0qZ1.js";
|
|
19
22
|
import { A as A3, a as a4 } from "./Autocomplete-C_lW1VER.js";
|
|
20
23
|
import { S as S6 } from "./Switch-D72dpkH2.js";
|
|
21
24
|
import { R } from "./RadioGroup-bO-ahP9T.js";
|
|
22
25
|
import { C as C3 } from "./Checkbox-gB5YKkVo.js";
|
|
23
|
-
import { D as
|
|
24
|
-
import { D as
|
|
26
|
+
import { D as D3 } from "./DatePicker-_IGWc3I5.js";
|
|
27
|
+
import { D as D4 } from "./DateTimePicker-CrmWav_j.js";
|
|
25
28
|
import './index.css';function scrollToTop({
|
|
26
29
|
behavior = "smooth",
|
|
27
30
|
target = typeof window !== "undefined" ? window : void 0,
|
|
@@ -38,7 +41,9 @@ export {
|
|
|
38
41
|
A as Avatar,
|
|
39
42
|
Backdrop,
|
|
40
43
|
Box,
|
|
44
|
+
B3 as Breadcrumbs,
|
|
41
45
|
B as Button,
|
|
46
|
+
B2 as ButtonGroup,
|
|
42
47
|
C as Card,
|
|
43
48
|
C3 as Checkbox,
|
|
44
49
|
C2 as Chip,
|
|
@@ -47,9 +52,9 @@ export {
|
|
|
47
52
|
Column,
|
|
48
53
|
Container,
|
|
49
54
|
D as DEFAULT_PRESET_NAME,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Divider,
|
|
55
|
+
D3 as DatePicker,
|
|
56
|
+
D4 as DateTimePicker,
|
|
57
|
+
D2 as Divider,
|
|
53
58
|
Fade,
|
|
54
59
|
Grid,
|
|
55
60
|
Grow,
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils/scrollToTop.ts"],"sourcesContent":["export interface ScrollToTopOptions {\n /** Comportamiento del scroll. Default: `'smooth'`. */\n behavior?: ScrollBehavior;\n /**\n * Elemento target del scroll. Default: `window`. Útil cuando el contenedor\n * scrolleable NO es `window` (p.ej. un `<Box>` con `overflow: auto`).\n */\n target?: Window | HTMLElement;\n /** Offset desde el top. Default: `0`. */\n top?: number;\n}\n\n/**\n * Hace scroll al tope (por default con animación suave). Safe en SSR — si\n * `window` no existe, es un no-op.\n *\n * Llamar tras mutaciones / cambios de filtros / apertura de modales para\n * asegurar que el usuario vea el mensaje de confirmación en la parte\n * superior de la página.\n *\n * ```ts\n * import { scrollToTop } from '@soyfri/shared-library';\n *\n * scrollToTop(); // window, smooth\n * scrollToTop({ behavior: 'auto' }); // window, instantáneo\n * scrollToTop({ target: myScrollableRef.current }); // container custom\n * ```\n */\nexport function scrollToTop({\n behavior = 'smooth',\n target = typeof window !== 'undefined' ? window : undefined,\n top = 0,\n}: ScrollToTopOptions = {}): void {\n if (!target) return;\n target.scrollTo({ top, left: 0, behavior });\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils/scrollToTop.ts"],"sourcesContent":["export interface ScrollToTopOptions {\n /** Comportamiento del scroll. Default: `'smooth'`. */\n behavior?: ScrollBehavior;\n /**\n * Elemento target del scroll. Default: `window`. Útil cuando el contenedor\n * scrolleable NO es `window` (p.ej. un `<Box>` con `overflow: auto`).\n */\n target?: Window | HTMLElement;\n /** Offset desde el top. Default: `0`. */\n top?: number;\n}\n\n/**\n * Hace scroll al tope (por default con animación suave). Safe en SSR — si\n * `window` no existe, es un no-op.\n *\n * Llamar tras mutaciones / cambios de filtros / apertura de modales para\n * asegurar que el usuario vea el mensaje de confirmación en la parte\n * superior de la página.\n *\n * ```ts\n * import { scrollToTop } from '@soyfri/shared-library';\n *\n * scrollToTop(); // window, smooth\n * scrollToTop({ behavior: 'auto' }); // window, instantáneo\n * scrollToTop({ target: myScrollableRef.current }); // container custom\n * ```\n */\nexport function scrollToTop({\n behavior = 'smooth',\n target = typeof window !== 'undefined' ? window : undefined,\n top = 0,\n}: ScrollToTopOptions = {}): void {\n if (!target) return;\n target.scrollTo({ top, left: 0, behavior });\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BO,SAAS,YAAY;AAAA,EAC1B,WAAW;AAAA,EACX,SAAS,OAAO,WAAW,cAAc,SAAS;AAAA,EAClD,MAAM;AACR,IAAwB,IAAU;AAChC,MAAI,CAAC,OAAQ;AACb,SAAO,SAAS,EAAE,KAAK,MAAM,GAAG,UAAU;AAC5C;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soyfri/shared-library",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.34",
|
|
4
4
|
"main": "./index.cjs",
|
|
5
5
|
"module": "./index.js",
|
|
6
6
|
"types": "./index.d.ts",
|
|
@@ -128,6 +128,11 @@
|
|
|
128
128
|
"require": "./components/Drawer/Drawer.cjs",
|
|
129
129
|
"types": "./components/Drawer/index.d.ts"
|
|
130
130
|
},
|
|
131
|
+
"./components/Divider": {
|
|
132
|
+
"import": "./components/Divider/Divider.js",
|
|
133
|
+
"require": "./components/Divider/Divider.cjs",
|
|
134
|
+
"types": "./components/Divider/index.d.ts"
|
|
135
|
+
},
|
|
131
136
|
"./components/DateTimePicker": {
|
|
132
137
|
"import": "./components/DateTimePicker/DateTimePicker.js",
|
|
133
138
|
"require": "./components/DateTimePicker/DateTimePicker.cjs",
|
|
@@ -158,11 +163,21 @@
|
|
|
158
163
|
"require": "./components/Card/Card.cjs",
|
|
159
164
|
"types": "./components/Card/index.d.ts"
|
|
160
165
|
},
|
|
166
|
+
"./components/ButtonGroup": {
|
|
167
|
+
"import": "./components/ButtonGroup/ButtonGroup.js",
|
|
168
|
+
"require": "./components/ButtonGroup/ButtonGroup.cjs",
|
|
169
|
+
"types": "./components/ButtonGroup/index.d.ts"
|
|
170
|
+
},
|
|
161
171
|
"./components/Button": {
|
|
162
172
|
"import": "./components/Button/Button.js",
|
|
163
173
|
"require": "./components/Button/Button.cjs",
|
|
164
174
|
"types": "./components/Button/index.d.ts"
|
|
165
175
|
},
|
|
176
|
+
"./components/Breadcrumbs": {
|
|
177
|
+
"import": "./components/Breadcrumbs/Breadcrumbs.js",
|
|
178
|
+
"require": "./components/Breadcrumbs/Breadcrumbs.cjs",
|
|
179
|
+
"types": "./components/Breadcrumbs/index.d.ts"
|
|
180
|
+
},
|
|
166
181
|
"./components/Avatar": {
|
|
167
182
|
"import": "./components/Avatar/Avatar.js",
|
|
168
183
|
"require": "./components/Avatar/Avatar.cjs",
|
package/Modal-BqgnC6yu.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Modal-BqgnC6yu.js","sources":["../src/components/Modal/ModalFooter.tsx","../src/components/Modal/ModalHeader.tsx","../src/components/Modal/ModalBody.tsx","../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Stack } from '@mui/material';\nimport type { ButtonProps as MuiButtonProps } from '@mui/material/Button';\n\nimport { Button } from '../Button';\n\n// Interfaz para acciones personalizadas (se mantiene aquí)\nexport interface ModalAction {\n text: string;\n onClick?: () => void;\n disabled?: boolean;\n variant?: MuiButtonProps['variant'];\n color?: MuiButtonProps['color'];\n /**\n * Props adicionales que se forwardean al `<Button>` interno. Útil para casos\n * avanzados como conectar el botón con un `<form id=\"...\">` externo usando\n * `buttonProps={{ type: 'submit', form: 'my-form-id' }}`.\n */\n buttonProps?: Partial<MuiButtonProps> & { form?: string };\n}\n\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n onClose: () => void;\n actions?: ModalAction[];\n}\n\nexport const ModalFooter: React.FC<ModalFooterProps> = ({\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n onClose,\n actions = [],\n}) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 1,\n }}\n >\n {children}\n <Stack direction=\"row\" spacing={1}>\n {showCloseButton && (\n <Button\n onClick={onClose}\n disabled={closeButtonDisabled}\n variant=\"outlined\"\n color=\"secondary\"\n >\n {closeButtonText}\n </Button>\n )}\n {actions.map((action) => {\n const { buttonProps, text, onClick, disabled, variant, color } = action;\n return (\n <Button\n key={text}\n onClick={onClick}\n disabled={disabled}\n variant={variant || 'contained'}\n color={color || 'primary'}\n {...(buttonProps as any)}\n >\n {text}\n </Button>\n );\n })}\n </Stack>\n </Box>\n );\n};\n\nModalFooter.displayName = 'ModalFooter';\n\nexport default ModalFooter;\n","import React from 'react';\nimport { Box, Typography } from '@mui/material';\n\nexport interface ModalHeaderProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-labelledby` del Modal. Se setea\n * automáticamente cuando el header se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalHeader: React.FC<ModalHeaderProps> = ({ children, id }) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <Typography id={id} variant=\"h6\" component=\"h2\">\n {children}\n </Typography>\n </Box>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n\nexport default ModalHeader;\n","import React from 'react';\nimport { Box } from '@mui/material';\n\nexport interface ModalBodyProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-describedby` del Modal. Se setea\n * automáticamente cuando el body se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalBody: React.FC<ModalBodyProps> = ({ children, id }) => {\n return (\n <Box id={id} sx={{ padding: 2, overflowY: 'auto', flexGrow: 1 }}>\n {children}\n </Box>\n );\n};\n\nModalBody.displayName = 'ModalBody';\n\nexport default ModalBody;\n","import {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useImperativeHandle,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Modal as MuiModal,\n Paper,\n useMediaQuery,\n useTheme,\n Box,\n Stack,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';\nimport WarningAmberIcon from '@mui/icons-material/WarningAmber';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';\nimport CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';\n\nimport type { DialogProps } from '@mui/material/Dialog';\nimport { ModalFooter, type ModalAction, type ModalFooterProps } from './ModalFooter';\nimport { ModalHeader } from './ModalHeader';\nimport { ModalBody } from './ModalBody';\nimport { mergeSx } from '../_shared/mergeSx';\n\n// Detección robusta de sub-componentes — funciona con wrappers / HMR que\n// rompen la igualdad de referencia (`child.type === ModalHeader`).\nconst isModalSlot = (\n child: ReactElement,\n Component: unknown,\n displayName: string,\n): boolean => {\n if (child.type === Component) return true;\n const type = child.type as { displayName?: string };\n return type?.displayName === displayName;\n};\n\n// Define la interfaz para los métodos que el padre puede llamar a través de la ref\nexport interface ModalRef {\n open: () => void;\n close: () => void;\n}\n\nexport type ModalMode = 'default' | 'confirm';\nexport type ModalSeverity = 'info' | 'warning' | 'error' | 'success';\n\nexport interface ModalProps {\n /**\n * Modo del modal.\n * - `default` (default): modal genérico con slots `Header`/`Body`/`Footer` y\n * `actions` custom.\n * - `confirm`: reemplaza al `ConfirmModal` legacy. Renderiza un layout\n * focalizado con icono por severidad, mensaje y botones \"Cancelar\" /\n * \"Confirmar\".\n */\n mode?: ModalMode;\n\n // ── Props comunes ────────────────────────────────────────────────────\n /** Controlado externamente. Omitir si se usa vía ref. */\n open?: boolean;\n /** Callback al cerrar. También se dispara al confirmar/cancelar. */\n onClose?: () => void;\n title?: string;\n children?: ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n actions?: ModalAction[];\n maxWidth?: DialogProps['maxWidth'];\n /**\n * Si `true`, el modal NO se cierra al hacer click en el backdrop ni con Escape\n * (equivale a `backdrop=\"static\"`). Cerrar solo vía botón/acción.\n */\n staticBackdrop?: boolean;\n /** Oculta el header (incluso si hay `title` o se pasa un `<Modal.Header>`). */\n hiddenHeader?: boolean;\n /** Oculta el body (incluso si se pasa un `<Modal.Body>`). */\n hiddenBody?: boolean;\n /** Oculta el footer (incluso si se pasa un `<Modal.Footer>` o `actions`). */\n hiddenFooter?: boolean;\n /** sx del Modal root (MuiModal). */\n sx?: SxProps<Theme>;\n /** sx del Paper interno (contenedor visual). Se mergea sobre el default. */\n paperSx?: SxProps<Theme>;\n /** className del Paper interno. */\n className?: string;\n\n // ── Props del modo confirm ───────────────────────────────────────────\n /**\n * Callback de confirmación. Soporta promesa — si devuelve `Promise`, el\n * botón muestra estado `disabled` mientras resuelve.\n *\n * Si la promesa **rechaza**, el modal queda abierto para que el consumer\n * pueda mostrar el error en su UI. El modal se cierra solo en éxito.\n */\n onConfirm?: () => void | Promise<void>;\n /** Texto del botón primario en modo `confirm`. Default: \"Confirmar\". */\n confirmText?: string;\n /** Deshabilita el botón de confirmar. */\n confirmDisabled?: boolean;\n /**\n * Severidad visual en modo `confirm`. Controla el icono y el color del\n * botón de confirmación.\n * - `info` (default): primary\n * - `warning`: warning (amarillo)\n * - `error`: error (rojo) — típico para \"Eliminar\"\n * - `success`: success (verde) — típico para \"Aprobar\"\n */\n severity?: ModalSeverity;\n /**\n * Mensaje del confirm. Puede ser string o cualquier ReactNode. Si se omite,\n * se usa `children`.\n */\n confirmMessage?: ReactNode;\n}\n\nconst modalStyle = {\n position: 'absolute' as const,\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90%',\n maxHeight: '90vh',\n display: 'flex',\n flexDirection: 'column' as const,\n outline: 'none',\n};\n\nconst severityConfig: Record<\n ModalSeverity,\n { color: ModalAction['color']; icon: ReactNode; paletteKey: 'primary' | 'warning' | 'error' | 'success' }\n> = {\n info: {\n color: 'primary',\n icon: <InfoOutlinedIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'primary',\n },\n warning: {\n color: 'warning',\n icon: <WarningAmberIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'warning',\n },\n error: {\n color: 'error',\n icon: <ErrorOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'error',\n },\n success: {\n color: 'success',\n icon: <CheckCircleOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'success',\n },\n};\n\nexport const Modal = forwardRef<ModalRef, ModalProps>(\n (\n {\n mode = 'default',\n open: controlledOpen,\n onClose: controlledOnClose,\n title,\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n actions = [],\n maxWidth = 'sm',\n hiddenHeader = false,\n hiddenBody = false,\n hiddenFooter = false,\n staticBackdrop = false,\n sx,\n paperSx,\n className,\n\n // Props del modo confirm\n onConfirm,\n confirmText = 'Confirmar',\n confirmDisabled = false,\n severity = 'info',\n confirmMessage,\n },\n ref,\n ) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const [confirmLoading, setConfirmLoading] = useState(false);\n\n // IDs estables para a11y: `aria-labelledby` y `aria-describedby`.\n const titleId = useId();\n const descId = useId();\n\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n useImperativeHandle(ref, () => ({\n open: () => setInternalOpen(true),\n close: () => {\n setInternalOpen(false);\n controlledOnClose?.();\n },\n }));\n\n const handleCloseInternal = (\n _event?: object,\n reason?: 'backdropClick' | 'escapeKeyDown',\n ) => {\n // Backdrop estático: ignora cierres por click fuera o Escape.\n if (\n staticBackdrop &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n setInternalOpen(false);\n controlledOnClose?.();\n };\n\n const handleConfirm = async () => {\n if (!onConfirm) {\n handleCloseInternal();\n return;\n }\n const result = onConfirm();\n if (!(result instanceof Promise)) {\n handleCloseInternal();\n return;\n }\n setConfirmLoading(true);\n try {\n await result;\n handleCloseInternal();\n } catch (err) {\n // No cerrar el modal en caso de error — el consumer es responsable\n // de mostrar un estado de error en su UI. Logueamos para trazabilidad\n // en dev.\n // eslint-disable-next-line no-console\n console.error('Modal onConfirm failed:', err);\n } finally {\n setConfirmLoading(false);\n }\n };\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n\n const getWidth = () => {\n if (isMobile) return '95%';\n switch (maxWidth) {\n case 'xs':\n return 300;\n case 'sm':\n return 500;\n case 'md':\n return 700;\n case 'lg':\n return 900;\n case 'xl':\n return 1100;\n case false:\n return 'auto';\n default:\n // Soporta string custom: `maxWidth=\"600px\"` se pasa tal cual.\n return typeof maxWidth === 'string' ? maxWidth : 500;\n }\n };\n\n // Base sx del Paper + width responsive; el consumer puede pisarlos via `paperSx`.\n const paperBaseSx: SxProps<Theme> = { ...modalStyle, width: getWidth() };\n const mergedPaperSx = mergeSx(paperBaseSx, paperSx);\n\n // ── Render modo CONFIRM ─────────────────────────────────────────────\n if (mode === 'confirm') {\n const config = severityConfig[severity];\n const message = confirmMessage ?? children;\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={message ? descId : undefined}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx}>\n <Stack spacing={2.5} sx={{ p: 3, alignItems: 'center', textAlign: 'center' }}>\n <Box\n sx={{\n width: 72,\n height: 72,\n borderRadius: '50%',\n backgroundColor: (t) => t.palette[config.paletteKey].light,\n color: (t) => t.palette[config.paletteKey].dark,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: 0.9,\n }}\n >\n {config.icon}\n </Box>\n {title && (\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{ fontWeight: 700 }}>\n {title}\n </Typography>\n )}\n {message && (\n <Typography id={descId} variant=\"body2\" color=\"text.secondary\">\n {message}\n </Typography>\n )}\n </Stack>\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled || confirmLoading}\n onClose={handleCloseInternal}\n actions={[\n {\n text: confirmText,\n onClick: handleConfirm,\n disabled: confirmDisabled || confirmLoading,\n variant: 'contained',\n color: config.color,\n },\n ]}\n />\n </Paper>\n </MuiModal>\n );\n }\n\n // ── Render modo DEFAULT (compuesto) ─────────────────────────────────\n const renderChildren = () => {\n let header: ReactNode | null = null;\n let body: ReactNode | null = null;\n let footer: ReactNode | null = null;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n\n if (isModalSlot(child, ModalHeader, 'ModalHeader')) {\n const headerChild = child as ReactElement<{ id?: string }>;\n header = cloneElement(headerChild, { id: titleId, ...headerChild.props });\n } else if (isModalSlot(child, ModalBody, 'ModalBody')) {\n const bodyChild = child as ReactElement<{ id?: string }>;\n body = cloneElement(bodyChild, { id: descId, ...bodyChild.props });\n } else if (isModalSlot(child, ModalFooter, 'ModalFooter')) {\n const footerChild = child as ReactElement<ModalFooterProps>;\n // Props del child ganan sobre los del Modal padre: si el consumer\n // declara `<Modal.Footer showCloseButton={false}>`, ese valor se\n // respeta. Solo los que vengan `undefined` caen al default del padre.\n const childProps = footerChild.props;\n footer = cloneElement(footerChild, {\n showCloseButton: childProps.showCloseButton ?? showCloseButton,\n closeButtonText: childProps.closeButtonText ?? closeButtonText,\n closeButtonDisabled: childProps.closeButtonDisabled ?? closeButtonDisabled,\n onClose: childProps.onClose ?? handleCloseInternal,\n actions: childProps.actions ?? actions,\n });\n }\n });\n\n if (!footer && !hiddenFooter) {\n footer = (\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled}\n onClose={handleCloseInternal}\n actions={actions}\n />\n );\n }\n\n return (\n <>\n {!hiddenHeader && (header || (title && <ModalHeader id={titleId}>{title}</ModalHeader>))}\n {!hiddenBody && body}\n {footer}\n </>\n );\n };\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={titleId}\n aria-describedby={descId}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx}>\n {renderChildren()}\n </Paper>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\n// Define los sub-componentes como propiedades estáticas con tipos explícitos\ntype ModalComponent = ReturnType<typeof forwardRef<ModalRef, ModalProps>> & {\n Header: typeof ModalHeader;\n Body: typeof ModalBody;\n Footer: typeof ModalFooter;\n};\n\nconst ModalWithStatics = Modal as ModalComponent;\n\nModalWithStatics.Header = ModalHeader;\nModalWithStatics.Body = ModalBody;\nModalWithStatics.Footer = ModalFooter;\n\nexport default ModalWithStatics;\n"],"names":["MuiModal"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BO,MAAM,cAA0C,CAAC;AAAA,EACtD;AAAA,EACA,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB;AAAA,EACA,UAAU,CAAA;AACZ,MAAM;AACJ,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,IAAI;AAAA,QACF,SAAS;AAAA,QACT,WAAW,CAAC,UAAU,aAAa,MAAM,QAAQ,OAAO;AAAA,QACxD,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,KAAK;AAAA,MAAA;AAAA,MAGN,UAAA;AAAA,QAAA;AAAA,QACD,qBAAC,OAAA,EAAM,WAAU,OAAM,SAAS,GAC7B,UAAA;AAAA,UAAA,mBACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS;AAAA,cACT,UAAU;AAAA,cACV,SAAQ;AAAA,cACR,OAAM;AAAA,cAEL,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGJ,QAAQ,IAAI,CAAC,WAAW;AACvB,kBAAM,EAAE,aAAa,MAAM,SAAS,UAAU,SAAS,UAAU;AACjE,mBACE;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC;AAAA,gBACA;AAAA,gBACA,SAAS,WAAW;AAAA,gBACpB,OAAO,SAAS;AAAA,iBACX,cANN;AAAA,gBAQE,UAAA;AAAA,cAAA;AAAA,cAPI;AAAA,YAAA;AAAA,UAUX,CAAC;AAAA,QAAA,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,YAAY,cAAc;ACpEnB,MAAM,cAA0C,CAAC,EAAE,UAAU,SAAS;AAC3E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,IAAI;AAAA,QACF,SAAS;AAAA,QACT,cAAc,CAAC,UAAU,aAAa,MAAM,QAAQ,OAAO;AAAA,QAC3D,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAAA;AAAA,MAGlB,8BAAC,YAAA,EAAW,IAAQ,SAAQ,MAAK,WAAU,MACxC,SAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,YAAY,cAAc;AClBnB,MAAM,YAAsC,CAAC,EAAE,UAAU,SAAS;AACvE,SACE,oBAAC,KAAA,EAAI,IAAQ,IAAI,EAAE,SAAS,GAAG,WAAW,QAAQ,UAAU,EAAA,GACzD,SAAA,CACH;AAEJ;AAEA,UAAU,cAAc;ACcxB,MAAM,cAAc,CAClB,OACA,WACA,gBACY;AACZ,MAAI,MAAM,SAAS,UAAW,QAAO;AACrC,QAAM,OAAO,MAAM;AACnB,UAAO,6BAAM,iBAAgB;AAC/B;AAiFA,MAAM,aAAa;AAAA,EACjB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,WAAW;AAAA,EACX,OAAO;AAAA,EACP,WAAW;AAAA,EACX,SAAS;AAAA,EACT,eAAe;AAAA,EACf,SAAS;AACX;AAEA,MAAM,iBAGF;AAAA,EACF,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,oBAAC,kBAAA,EAAiB,IAAI,EAAE,UAAU,MAAM;AAAA,IAC9C,YAAY;AAAA,EAAA;AAAA,EAEd,SAAS;AAAA,IACP,OAAO;AAAA,IACP,MAAM,oBAAC,kBAAA,EAAiB,IAAI,EAAE,UAAU,MAAM;AAAA,IAC9C,YAAY;AAAA,EAAA;AAAA,EAEd,OAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,oBAAC,kBAAA,EAAiB,IAAI,EAAE,UAAU,MAAM;AAAA,IAC9C,YAAY;AAAA,EAAA;AAAA,EAEd,SAAS;AAAA,IACP,OAAO;AAAA,IACP,MAAM,oBAAC,wBAAA,EAAuB,IAAI,EAAE,UAAU,MAAM;AAAA,IACpD,YAAY;AAAA,EAAA;AAEhB;AAEO,MAAM,QAAQ;AAAA,EACnB,CACE;AAAA,IACE,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,IACtB,UAAU,CAAA;AAAA,IACV,WAAW;AAAA,IACX,eAAe;AAAA,IACf,aAAa;AAAA,IACb,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAGA;AAAA,IACA,cAAc;AAAA,IACd,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX;AAAA,EAAA,GAEF,QACG;AACH,UAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,UAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAG1D,UAAM,UAAU,MAAA;AAChB,UAAM,SAAS,MAAA;AAEf,UAAM,SAAS,mBAAmB,SAAY,iBAAiB;AAE/D,wBAAoB,KAAK,OAAO;AAAA,MAC9B,MAAM,MAAM,gBAAgB,IAAI;AAAA,MAChC,OAAO,MAAM;AACX,wBAAgB,KAAK;AACrB;AAAA,MACF;AAAA,IAAA,EACA;AAEF,UAAM,sBAAsB,CAC1B,QACA,WACG;AAEH,UACE,mBACC,WAAW,mBAAmB,WAAW,kBAC1C;AACA;AAAA,MACF;AACA,sBAAgB,KAAK;AACrB;AAAA,IACF;AAEA,UAAM,gBAAgB,YAAY;AAChC,UAAI,CAAC,WAAW;AACd,4BAAA;AACA;AAAA,MACF;AACA,YAAM,SAAS,UAAA;AACf,UAAI,EAAE,kBAAkB,UAAU;AAChC,4BAAA;AACA;AAAA,MACF;AACA,wBAAkB,IAAI;AACtB,UAAI;AACF,cAAM;AACN,4BAAA;AAAA,MACF,SAAS,KAAK;AAKZ,gBAAQ,MAAM,2BAA2B,GAAG;AAAA,MAC9C,UAAA;AACE,0BAAkB,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,QAAQ,SAAA;AACd,UAAM,WAAW,cAAc,MAAM,YAAY,KAAK,IAAI,CAAC;AAE3D,UAAM,WAAW,MAAM;AACrB,UAAI,SAAU,QAAO;AACrB,cAAQ,UAAA;AAAA,QACN,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT,KAAK;AACH,iBAAO;AAAA,QACT;AAEE,iBAAO,OAAO,aAAa,WAAW,WAAW;AAAA,MAAA;AAAA,IAEvD;AAGA,UAAM,cAA8B,iCAAK,aAAL,EAAiB,OAAO,WAAS;AACrE,UAAM,gBAAgB,QAAQ,aAAa,OAAO;AAGlD,QAAI,SAAS,WAAW;AACtB,YAAM,SAAS,eAAe,QAAQ;AACtC,YAAM,UAAU,0CAAkB;AAElC,aACE;AAAA,QAACA;AAAAA,QAAA;AAAA,UACC,MAAM;AAAA,UACN,SAAS;AAAA,UACT,mBAAiB,QAAQ,UAAU;AAAA,UACnC,oBAAkB,UAAU,SAAS;AAAA,UACrC,sBAAoB;AAAA,UACpB;AAAA,UAEA,UAAA,qBAAC,OAAA,EAAM,WAAsB,IAAI,eAC/B,UAAA;AAAA,YAAA,qBAAC,OAAA,EAAM,SAAS,KAAK,IAAI,EAAE,GAAG,GAAG,YAAY,UAAU,WAAW,SAAA,GAChE,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,IAAI;AAAA,oBACF,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,cAAc;AAAA,oBACd,iBAAiB,CAAC,MAAM,EAAE,QAAQ,OAAO,UAAU,EAAE;AAAA,oBACrD,OAAO,CAAC,MAAM,EAAE,QAAQ,OAAO,UAAU,EAAE;AAAA,oBAC3C,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,gBAAgB;AAAA,oBAChB,SAAS;AAAA,kBAAA;AAAA,kBAGV,UAAA,OAAO;AAAA,gBAAA;AAAA,cAAA;AAAA,cAET,SACC,oBAAC,YAAA,EAAW,IAAI,SAAS,SAAQ,MAAK,WAAU,MAAK,IAAI,EAAE,YAAY,IAAA,GACpE,UAAA,OACH;AAAA,cAED,+BACE,YAAA,EAAW,IAAI,QAAQ,SAAQ,SAAQ,OAAM,kBAC3C,UAAA,QAAA,CACH;AAAA,YAAA,GAEJ;AAAA,YACA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA,qBAAqB,uBAAuB;AAAA,gBAC5C,SAAS;AAAA,gBACT,SAAS;AAAA,kBACP;AAAA,oBACE,MAAM;AAAA,oBACN,SAAS;AAAA,oBACT,UAAU,mBAAmB;AAAA,oBAC7B,SAAS;AAAA,oBACT,OAAO,OAAO;AAAA,kBAAA;AAAA,gBAChB;AAAA,cACF;AAAA,YAAA;AAAA,UACF,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAGN;AAGA,UAAM,iBAAiB,MAAM;AAC3B,UAAI,SAA2B;AAC/B,UAAI,OAAyB;AAC7B,UAAI,SAA2B;AAE/B,eAAS,QAAQ,UAAU,CAAC,UAAU;;AACpC,YAAI,CAAC,eAAe,KAAK,EAAG;AAE5B,YAAI,YAAY,OAAO,aAAa,aAAa,GAAG;AAClD,gBAAM,cAAc;AACpB,mBAAS,aAAa,aAAa,iBAAE,IAAI,WAAY,YAAY,MAAO;AAAA,QAC1E,WAAW,YAAY,OAAO,WAAW,WAAW,GAAG;AACrD,gBAAM,YAAY;AAClB,iBAAO,aAAa,WAAW,iBAAE,IAAI,UAAW,UAAU,MAAO;AAAA,QACnE,WAAW,YAAY,OAAO,aAAa,aAAa,GAAG;AACzD,gBAAM,cAAc;AAIpB,gBAAM,aAAa,YAAY;AAC/B,mBAAS,aAAa,aAAa;AAAA,YACjC,kBAAiB,gBAAW,oBAAX,YAA8B;AAAA,YAC/C,kBAAiB,gBAAW,oBAAX,YAA8B;AAAA,YAC/C,sBAAqB,gBAAW,wBAAX,YAAkC;AAAA,YACvD,UAAS,gBAAW,YAAX,YAAsB;AAAA,YAC/B,UAAS,gBAAW,YAAX,YAAsB;AAAA,UAAA,CAChC;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,CAAC,UAAU,CAAC,cAAc;AAC5B,iBACE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,UAAA;AAAA,QAAA;AAAA,MAGN;AAEA,aACE,qBAAA,UAAA,EACG,UAAA;AAAA,QAAA,CAAC,iBAAiB,UAAW,6BAAU,aAAA,EAAY,IAAI,SAAU,UAAA,MAAA,CAAM;AAAA,QACvE,CAAC,cAAc;AAAA,QACf;AAAA,MAAA,GACH;AAAA,IAEJ;AAEA,WACE;AAAA,MAACA;AAAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,mBAAiB;AAAA,QACjB,oBAAkB;AAAA,QAClB,sBAAoB;AAAA,QACpB;AAAA,QAEA,8BAAC,OAAA,EAAM,WAAsB,IAAI,eAC9B,2BAAe,CAClB;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,MAAM,cAAc;AASpB,MAAM,mBAAmB;AAEzB,iBAAiB,SAAS;AAC1B,iBAAiB,OAAO;AACxB,iBAAiB,SAAS;"}
|
package/Modal-CA0J0xpO.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Modal-CA0J0xpO.cjs","sources":["../src/components/Modal/ModalFooter.tsx","../src/components/Modal/ModalHeader.tsx","../src/components/Modal/ModalBody.tsx","../src/components/Modal/Modal.tsx"],"sourcesContent":["import React from 'react';\nimport { Box, Stack } from '@mui/material';\nimport type { ButtonProps as MuiButtonProps } from '@mui/material/Button';\n\nimport { Button } from '../Button';\n\n// Interfaz para acciones personalizadas (se mantiene aquí)\nexport interface ModalAction {\n text: string;\n onClick?: () => void;\n disabled?: boolean;\n variant?: MuiButtonProps['variant'];\n color?: MuiButtonProps['color'];\n /**\n * Props adicionales que se forwardean al `<Button>` interno. Útil para casos\n * avanzados como conectar el botón con un `<form id=\"...\">` externo usando\n * `buttonProps={{ type: 'submit', form: 'my-form-id' }}`.\n */\n buttonProps?: Partial<MuiButtonProps> & { form?: string };\n}\n\nexport interface ModalFooterProps {\n children?: React.ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n onClose: () => void;\n actions?: ModalAction[];\n}\n\nexport const ModalFooter: React.FC<ModalFooterProps> = ({\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n onClose,\n actions = [],\n}) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 1,\n }}\n >\n {children}\n <Stack direction=\"row\" spacing={1}>\n {showCloseButton && (\n <Button\n onClick={onClose}\n disabled={closeButtonDisabled}\n variant=\"outlined\"\n color=\"secondary\"\n >\n {closeButtonText}\n </Button>\n )}\n {actions.map((action) => {\n const { buttonProps, text, onClick, disabled, variant, color } = action;\n return (\n <Button\n key={text}\n onClick={onClick}\n disabled={disabled}\n variant={variant || 'contained'}\n color={color || 'primary'}\n {...(buttonProps as any)}\n >\n {text}\n </Button>\n );\n })}\n </Stack>\n </Box>\n );\n};\n\nModalFooter.displayName = 'ModalFooter';\n\nexport default ModalFooter;\n","import React from 'react';\nimport { Box, Typography } from '@mui/material';\n\nexport interface ModalHeaderProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-labelledby` del Modal. Se setea\n * automáticamente cuando el header se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalHeader: React.FC<ModalHeaderProps> = ({ children, id }) => {\n return (\n <Box\n sx={{\n padding: 2,\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n }}\n >\n <Typography id={id} variant=\"h6\" component=\"h2\">\n {children}\n </Typography>\n </Box>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n\nexport default ModalHeader;\n","import React from 'react';\nimport { Box } from '@mui/material';\n\nexport interface ModalBodyProps {\n children: React.ReactNode;\n /**\n * ID del elemento — usado para `aria-describedby` del Modal. Se setea\n * automáticamente cuando el body se renderiza dentro de `<Modal>`.\n */\n id?: string;\n}\n\nexport const ModalBody: React.FC<ModalBodyProps> = ({ children, id }) => {\n return (\n <Box id={id} sx={{ padding: 2, overflowY: 'auto', flexGrow: 1 }}>\n {children}\n </Box>\n );\n};\n\nModalBody.displayName = 'ModalBody';\n\nexport default ModalBody;\n","import {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n useId,\n useImperativeHandle,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Modal as MuiModal,\n Paper,\n useMediaQuery,\n useTheme,\n Box,\n Stack,\n Typography,\n} from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';\nimport WarningAmberIcon from '@mui/icons-material/WarningAmber';\nimport ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';\nimport CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';\n\nimport type { DialogProps } from '@mui/material/Dialog';\nimport { ModalFooter, type ModalAction, type ModalFooterProps } from './ModalFooter';\nimport { ModalHeader } from './ModalHeader';\nimport { ModalBody } from './ModalBody';\nimport { mergeSx } from '../_shared/mergeSx';\n\n// Detección robusta de sub-componentes — funciona con wrappers / HMR que\n// rompen la igualdad de referencia (`child.type === ModalHeader`).\nconst isModalSlot = (\n child: ReactElement,\n Component: unknown,\n displayName: string,\n): boolean => {\n if (child.type === Component) return true;\n const type = child.type as { displayName?: string };\n return type?.displayName === displayName;\n};\n\n// Define la interfaz para los métodos que el padre puede llamar a través de la ref\nexport interface ModalRef {\n open: () => void;\n close: () => void;\n}\n\nexport type ModalMode = 'default' | 'confirm';\nexport type ModalSeverity = 'info' | 'warning' | 'error' | 'success';\n\nexport interface ModalProps {\n /**\n * Modo del modal.\n * - `default` (default): modal genérico con slots `Header`/`Body`/`Footer` y\n * `actions` custom.\n * - `confirm`: reemplaza al `ConfirmModal` legacy. Renderiza un layout\n * focalizado con icono por severidad, mensaje y botones \"Cancelar\" /\n * \"Confirmar\".\n */\n mode?: ModalMode;\n\n // ── Props comunes ────────────────────────────────────────────────────\n /** Controlado externamente. Omitir si se usa vía ref. */\n open?: boolean;\n /** Callback al cerrar. También se dispara al confirmar/cancelar. */\n onClose?: () => void;\n title?: string;\n children?: ReactNode;\n showCloseButton?: boolean;\n closeButtonText?: string;\n closeButtonDisabled?: boolean;\n actions?: ModalAction[];\n maxWidth?: DialogProps['maxWidth'];\n /**\n * Si `true`, el modal NO se cierra al hacer click en el backdrop ni con Escape\n * (equivale a `backdrop=\"static\"`). Cerrar solo vía botón/acción.\n */\n staticBackdrop?: boolean;\n /** Oculta el header (incluso si hay `title` o se pasa un `<Modal.Header>`). */\n hiddenHeader?: boolean;\n /** Oculta el body (incluso si se pasa un `<Modal.Body>`). */\n hiddenBody?: boolean;\n /** Oculta el footer (incluso si se pasa un `<Modal.Footer>` o `actions`). */\n hiddenFooter?: boolean;\n /** sx del Modal root (MuiModal). */\n sx?: SxProps<Theme>;\n /** sx del Paper interno (contenedor visual). Se mergea sobre el default. */\n paperSx?: SxProps<Theme>;\n /** className del Paper interno. */\n className?: string;\n\n // ── Props del modo confirm ───────────────────────────────────────────\n /**\n * Callback de confirmación. Soporta promesa — si devuelve `Promise`, el\n * botón muestra estado `disabled` mientras resuelve.\n *\n * Si la promesa **rechaza**, el modal queda abierto para que el consumer\n * pueda mostrar el error en su UI. El modal se cierra solo en éxito.\n */\n onConfirm?: () => void | Promise<void>;\n /** Texto del botón primario en modo `confirm`. Default: \"Confirmar\". */\n confirmText?: string;\n /** Deshabilita el botón de confirmar. */\n confirmDisabled?: boolean;\n /**\n * Severidad visual en modo `confirm`. Controla el icono y el color del\n * botón de confirmación.\n * - `info` (default): primary\n * - `warning`: warning (amarillo)\n * - `error`: error (rojo) — típico para \"Eliminar\"\n * - `success`: success (verde) — típico para \"Aprobar\"\n */\n severity?: ModalSeverity;\n /**\n * Mensaje del confirm. Puede ser string o cualquier ReactNode. Si se omite,\n * se usa `children`.\n */\n confirmMessage?: ReactNode;\n}\n\nconst modalStyle = {\n position: 'absolute' as const,\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '90%',\n maxHeight: '90vh',\n display: 'flex',\n flexDirection: 'column' as const,\n outline: 'none',\n};\n\nconst severityConfig: Record<\n ModalSeverity,\n { color: ModalAction['color']; icon: ReactNode; paletteKey: 'primary' | 'warning' | 'error' | 'success' }\n> = {\n info: {\n color: 'primary',\n icon: <InfoOutlinedIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'primary',\n },\n warning: {\n color: 'warning',\n icon: <WarningAmberIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'warning',\n },\n error: {\n color: 'error',\n icon: <ErrorOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'error',\n },\n success: {\n color: 'success',\n icon: <CheckCircleOutlineIcon sx={{ fontSize: 48 }} />,\n paletteKey: 'success',\n },\n};\n\nexport const Modal = forwardRef<ModalRef, ModalProps>(\n (\n {\n mode = 'default',\n open: controlledOpen,\n onClose: controlledOnClose,\n title,\n children,\n showCloseButton = true,\n closeButtonText = 'Cerrar',\n closeButtonDisabled = false,\n actions = [],\n maxWidth = 'sm',\n hiddenHeader = false,\n hiddenBody = false,\n hiddenFooter = false,\n staticBackdrop = false,\n sx,\n paperSx,\n className,\n\n // Props del modo confirm\n onConfirm,\n confirmText = 'Confirmar',\n confirmDisabled = false,\n severity = 'info',\n confirmMessage,\n },\n ref,\n ) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const [confirmLoading, setConfirmLoading] = useState(false);\n\n // IDs estables para a11y: `aria-labelledby` y `aria-describedby`.\n const titleId = useId();\n const descId = useId();\n\n const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen;\n\n useImperativeHandle(ref, () => ({\n open: () => setInternalOpen(true),\n close: () => {\n setInternalOpen(false);\n controlledOnClose?.();\n },\n }));\n\n const handleCloseInternal = (\n _event?: object,\n reason?: 'backdropClick' | 'escapeKeyDown',\n ) => {\n // Backdrop estático: ignora cierres por click fuera o Escape.\n if (\n staticBackdrop &&\n (reason === 'backdropClick' || reason === 'escapeKeyDown')\n ) {\n return;\n }\n setInternalOpen(false);\n controlledOnClose?.();\n };\n\n const handleConfirm = async () => {\n if (!onConfirm) {\n handleCloseInternal();\n return;\n }\n const result = onConfirm();\n if (!(result instanceof Promise)) {\n handleCloseInternal();\n return;\n }\n setConfirmLoading(true);\n try {\n await result;\n handleCloseInternal();\n } catch (err) {\n // No cerrar el modal en caso de error — el consumer es responsable\n // de mostrar un estado de error en su UI. Logueamos para trazabilidad\n // en dev.\n // eslint-disable-next-line no-console\n console.error('Modal onConfirm failed:', err);\n } finally {\n setConfirmLoading(false);\n }\n };\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n\n const getWidth = () => {\n if (isMobile) return '95%';\n switch (maxWidth) {\n case 'xs':\n return 300;\n case 'sm':\n return 500;\n case 'md':\n return 700;\n case 'lg':\n return 900;\n case 'xl':\n return 1100;\n case false:\n return 'auto';\n default:\n // Soporta string custom: `maxWidth=\"600px\"` se pasa tal cual.\n return typeof maxWidth === 'string' ? maxWidth : 500;\n }\n };\n\n // Base sx del Paper + width responsive; el consumer puede pisarlos via `paperSx`.\n const paperBaseSx: SxProps<Theme> = { ...modalStyle, width: getWidth() };\n const mergedPaperSx = mergeSx(paperBaseSx, paperSx);\n\n // ── Render modo CONFIRM ─────────────────────────────────────────────\n if (mode === 'confirm') {\n const config = severityConfig[severity];\n const message = confirmMessage ?? children;\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={message ? descId : undefined}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx}>\n <Stack spacing={2.5} sx={{ p: 3, alignItems: 'center', textAlign: 'center' }}>\n <Box\n sx={{\n width: 72,\n height: 72,\n borderRadius: '50%',\n backgroundColor: (t) => t.palette[config.paletteKey].light,\n color: (t) => t.palette[config.paletteKey].dark,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n opacity: 0.9,\n }}\n >\n {config.icon}\n </Box>\n {title && (\n <Typography id={titleId} variant=\"h6\" component=\"h2\" sx={{ fontWeight: 700 }}>\n {title}\n </Typography>\n )}\n {message && (\n <Typography id={descId} variant=\"body2\" color=\"text.secondary\">\n {message}\n </Typography>\n )}\n </Stack>\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled || confirmLoading}\n onClose={handleCloseInternal}\n actions={[\n {\n text: confirmText,\n onClick: handleConfirm,\n disabled: confirmDisabled || confirmLoading,\n variant: 'contained',\n color: config.color,\n },\n ]}\n />\n </Paper>\n </MuiModal>\n );\n }\n\n // ── Render modo DEFAULT (compuesto) ─────────────────────────────────\n const renderChildren = () => {\n let header: ReactNode | null = null;\n let body: ReactNode | null = null;\n let footer: ReactNode | null = null;\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n\n if (isModalSlot(child, ModalHeader, 'ModalHeader')) {\n const headerChild = child as ReactElement<{ id?: string }>;\n header = cloneElement(headerChild, { id: titleId, ...headerChild.props });\n } else if (isModalSlot(child, ModalBody, 'ModalBody')) {\n const bodyChild = child as ReactElement<{ id?: string }>;\n body = cloneElement(bodyChild, { id: descId, ...bodyChild.props });\n } else if (isModalSlot(child, ModalFooter, 'ModalFooter')) {\n const footerChild = child as ReactElement<ModalFooterProps>;\n // Props del child ganan sobre los del Modal padre: si el consumer\n // declara `<Modal.Footer showCloseButton={false}>`, ese valor se\n // respeta. Solo los que vengan `undefined` caen al default del padre.\n const childProps = footerChild.props;\n footer = cloneElement(footerChild, {\n showCloseButton: childProps.showCloseButton ?? showCloseButton,\n closeButtonText: childProps.closeButtonText ?? closeButtonText,\n closeButtonDisabled: childProps.closeButtonDisabled ?? closeButtonDisabled,\n onClose: childProps.onClose ?? handleCloseInternal,\n actions: childProps.actions ?? actions,\n });\n }\n });\n\n if (!footer && !hiddenFooter) {\n footer = (\n <ModalFooter\n showCloseButton={showCloseButton}\n closeButtonText={closeButtonText}\n closeButtonDisabled={closeButtonDisabled}\n onClose={handleCloseInternal}\n actions={actions}\n />\n );\n }\n\n return (\n <>\n {!hiddenHeader && (header || (title && <ModalHeader id={titleId}>{title}</ModalHeader>))}\n {!hiddenBody && body}\n {footer}\n </>\n );\n };\n\n return (\n <MuiModal\n open={isOpen}\n onClose={handleCloseInternal}\n aria-labelledby={titleId}\n aria-describedby={descId}\n closeAfterTransition\n sx={sx}\n >\n <Paper className={className} sx={mergedPaperSx}>\n {renderChildren()}\n </Paper>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\n// Define los sub-componentes como propiedades estáticas con tipos explícitos\ntype ModalComponent = ReturnType<typeof forwardRef<ModalRef, ModalProps>> & {\n Header: typeof ModalHeader;\n Body: typeof ModalBody;\n Footer: typeof ModalFooter;\n};\n\nconst ModalWithStatics = Modal as ModalComponent;\n\nModalWithStatics.Header = ModalHeader;\nModalWithStatics.Body = ModalBody;\nModalWithStatics.Footer = ModalFooter;\n\nexport default ModalWithStatics;\n"],"names":["jsxs","Box","Stack","jsx","Button","Typography","forwardRef","useState","useId","useImperativeHandle","useTheme","useMediaQuery","mergeSx","MuiModal","Paper","Children","isValidElement","cloneElement","Fragment"],"mappings":"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"}
|