{text}
+
+
+ Abrir ModalSimple
+
+ Contenido libre del modal...
+
+ >
+ )
+}`}
+ />
+ Tipo ModalCard
+
+ Es una variante pensada para contenido tipo card, como logros o medallas. No renderiza
+ iconos ni encabezado por defecto, mantiene la X para cerrar y permite
+ contenido completamente libre. Su ancho está pensado para cards compactas.
+
+ El componente se importa de la siguiente manera:
+
+
+
+
+
+ Abrir ModalCard
+
+
+ Contenido libre del card...
+
+
+
+ Entendido
+
+
+
+ >
+ )
}`}
/>
Variantes del tipo Modal
diff --git a/src/index.ts b/src/index.ts
index 4913aecc1..310caf1f9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -26,6 +26,9 @@ export {
ModalContent,
ModalAlertButtons,
ModalMultiple,
+ ModalSimple,
+ ModalCard,
+ ModalCardContent,
} from './organisms/Modals'
export type { ModalMultipleProps } from './organisms/Modals'
export { ModalAlert } from './organisms/ModalAlert'
diff --git a/src/organisms/Modals/Modal/ModalCard.test.tsx b/src/organisms/Modals/Modal/ModalCard.test.tsx
new file mode 100644
index 000000000..eb33b572c
--- /dev/null
+++ b/src/organisms/Modals/Modal/ModalCard.test.tsx
@@ -0,0 +1,31 @@
+import { ChakraProvider } from '@chakra-ui/react'
+import { render, screen } from '@testing-library/react'
+
+import { ModalCard } from './ModalCard'
+
+const renderWithChakra = (ui: React.ReactElement): any => {
+ return render({ui} )
+}
+
+describe('ModalCard Component', () => {
+ it('renders children content', () => {
+ renderWithChakra(
+
+ Card content
+
+ )
+
+ expect(screen.getByText('Card content')).toBeInTheDocument()
+ expect(screen.getByRole('dialog')).toBeInTheDocument()
+ })
+
+ it('does not render a close button', () => {
+ renderWithChakra(
+
+ Card content
+
+ )
+
+ expect(screen.queryByLabelText('Close')).not.toBeInTheDocument()
+ })
+})
diff --git a/src/organisms/Modals/Modal/ModalCard.tsx b/src/organisms/Modals/Modal/ModalCard.tsx
new file mode 100644
index 000000000..8089349f3
--- /dev/null
+++ b/src/organisms/Modals/Modal/ModalCard.tsx
@@ -0,0 +1,52 @@
+import { Modal as ChakraModal, ModalOverlay, ModalContent, Box } from '@chakra-ui/react'
+
+import { vars } from '@/theme'
+import { IModalCard } from '../types'
+import { useModalConfig } from './useModalConfig'
+
+export const ModalCard = ({
+ children,
+ isOpen,
+ onClose,
+ closeOnOverlayClick = true,
+ closeOnEsc = true,
+}: IModalCard): JSX.Element => {
+ const modalConfig = useModalConfig({
+ closeOnOverlayClick,
+ scrollBehavior: 'outside',
+ fixedButtons: false,
+ withoutMargin: false,
+ })
+
+ return (
+
+
+
+ {children}
+
+
+ )
+}
+
+export const ModalCardContent = ({ children }: { children: React.ReactNode }): JSX.Element => {
+ return {children}
+}
diff --git a/src/organisms/Modals/Modal/ModalSimple.test.tsx b/src/organisms/Modals/Modal/ModalSimple.test.tsx
new file mode 100644
index 000000000..7b34209e5
--- /dev/null
+++ b/src/organisms/Modals/Modal/ModalSimple.test.tsx
@@ -0,0 +1,61 @@
+import { ChakraProvider } from '@chakra-ui/react'
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+
+import { ModalSimple } from './ModalSimple'
+
+const renderWithChakra = (ui: React.ReactElement): any => {
+ return render({ui} )
+}
+
+describe('ModalSimple Component', () => {
+ it('renders children content', () => {
+ renderWithChakra(
+
+ Simple content
+
+ )
+
+ expect(screen.getByText('Simple content')).toBeInTheDocument()
+ expect(screen.getByRole('dialog')).toBeInTheDocument()
+ })
+
+ it('calls onClose when close button is clicked', async () => {
+ const user = userEvent.setup()
+ const onCloseMock = jest.fn()
+
+ renderWithChakra(
+
+ Simple content
+
+ )
+
+ await user.click(screen.getByLabelText('Close'))
+ expect(onCloseMock).toHaveBeenCalledTimes(1)
+ })
+
+ it('does not call onClose when Escape key is pressed and closeOnEsc is false', async () => {
+ const user = userEvent.setup()
+ const onCloseMock = jest.fn()
+
+ renderWithChakra(
+
+ Simple content
+
+ )
+
+ await user.keyboard('{Escape}')
+ expect(onCloseMock).not.toHaveBeenCalled()
+ })
+
+ it('removes inner spacing when withoutMargin is true', () => {
+ renderWithChakra(
+
+ Simple content
+
+ )
+
+ expect(screen.getByTestId('modal-simple-content')).toBeInTheDocument()
+ expect(screen.getByText('Simple content')).toBeInTheDocument()
+ })
+})
diff --git a/src/organisms/Modals/Modal/ModalSimple.tsx b/src/organisms/Modals/Modal/ModalSimple.tsx
new file mode 100644
index 000000000..ace6b56da
--- /dev/null
+++ b/src/organisms/Modals/Modal/ModalSimple.tsx
@@ -0,0 +1,70 @@
+import {
+ Modal as ChakraModal,
+ ModalOverlay,
+ ModalContent,
+ ModalCloseButton,
+ Box,
+} from '@chakra-ui/react'
+
+import { vars } from '@/theme'
+import { IModalSimple } from '../types'
+import { useModalConfig } from './useModalConfig'
+
+export const ModalSimple = ({
+ children,
+ isOpen,
+ onClose,
+ closeOnOverlayClick = true,
+ closeOnEsc,
+ withoutMargin = false,
+}: IModalSimple): JSX.Element => {
+ const modalConfig = useModalConfig({
+ closeOnOverlayClick,
+ scrollBehavior: 'outside',
+ fixedButtons: false,
+ withoutMargin,
+ })
+
+ return (
+
+
+
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/src/organisms/Modals/index.ts b/src/organisms/Modals/index.ts
index b6340e6ed..a21d327cf 100644
--- a/src/organisms/Modals/index.ts
+++ b/src/organisms/Modals/index.ts
@@ -1,4 +1,6 @@
export { Modal } from './Modal/Modal'
+export { ModalCard, ModalCardContent } from './Modal/ModalCard'
+export { ModalSimple } from './Modal/ModalSimple'
export { ModalButtons, ModalContent } from './Modal/ModalButtons'
export { ModalAlertNew, ModalAlertButtons } from './ModalAlert/ModalAlert'
export { ModalMultiple } from './ModalMultiple/ModalMultiple'
diff --git a/src/organisms/Modals/types.d.ts b/src/organisms/Modals/types.d.ts
index 952bf808b..70784020f 100644
--- a/src/organisms/Modals/types.d.ts
+++ b/src/organisms/Modals/types.d.ts
@@ -16,6 +16,23 @@ export interface IModal {
autoFocus?: boolean
}
+export interface IModalSimple {
+ children: React.ReactNode
+ closeOnEsc?: boolean
+ closeOnOverlayClick?: boolean
+ isOpen: boolean
+ onClose: () => void
+ withoutMargin?: boolean
+}
+
+export interface IModalCard {
+ children: React.ReactNode
+ closeOnEsc?: boolean
+ closeOnOverlayClick?: boolean
+ isOpen: boolean
+ onClose: () => void
+}
+
export interface IModalContentBase {
children: React.ReactNode
closeOnOverlayClick: IModal['closeOnOverlayClick']