+
void;
+ padding?: string;
}
export type CheckboxSizeVariant = 'small' | 'medium' | 'big';
diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx
new file mode 100644
index 0000000..c64cb0f
--- /dev/null
+++ b/src/components/Modal/Modal.tsx
@@ -0,0 +1,76 @@
+import { Button } from '../../index.js';
+import {
+ ModalBackground,
+ ModalButtonContainer,
+ ModalComponent,
+ ModalErrorMessage,
+ ModalTitle,
+} from './styles.js';
+import type { ModalProps } from './types.js';
+import React, { useState } from 'react';
+
+export const Modal = ({
+ title,
+ children,
+ onSubmit,
+ onCancel,
+ close,
+ submitMessage = 'Submit',
+ cancelMessage = 'Cancel',
+ requirementsMet,
+ errorMessage,
+ mandatory = false,
+ $maxWidth,
+}: ModalProps) => {
+ const [error, setError] = useState(false);
+
+ const handleClick = (event: 'submit' | 'cancel') => {
+ if (requirementsMet && event === 'submit') {
+ if (requirementsMet() === true) {
+ close();
+ onSubmit();
+ } else {
+ setError(true);
+ }
+
+ return;
+ }
+
+ close();
+ event === 'submit' ? onSubmit() : onCancel();
+ };
+
+ return (
+ mandatory === false && close()}>
+ {
+ e.stopPropagation();
+ if (error) setError(false);
+ }}
+ $maxWidth={$maxWidth}
+ >
+ {title}
+ {children}
+
+
+
+
+ {error && {errorMessage}}
+
+
+ );
+};
diff --git a/src/components/Modal/styles.ts b/src/components/Modal/styles.ts
new file mode 100644
index 0000000..a283898
--- /dev/null
+++ b/src/components/Modal/styles.ts
@@ -0,0 +1,52 @@
+import { styled } from 'styled-components';
+import { theme } from '../../theme.js';
+
+export const ModalBackground = styled.div<{ zIndex?: number }>`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.2);
+
+ z-index: ${({ zIndex }) => (zIndex ? zIndex : 1000)};
+`;
+
+export const ModalComponent = styled.div<{
+ zIndex?: number;
+ $maxWidth?: string;
+}>`
+ z-index: ${({ zIndex }) => (zIndex ? zIndex + 1 : 1001)};
+
+ display: flex;
+ flex-direction: column;
+
+ padding: 16px;
+ border-radius: 8px;
+ max-width: ${({ $maxWidth }) =>
+ $maxWidth !== undefined ? $maxWidth : '50%'};
+
+ background-color: ${theme.colors.main};
+ box-shadow: 0px 5px 5px -2px ${theme.colors.lightGray};
+`;
+
+export const ModalTitle = styled.h1`
+ margin: 0;
+`;
+
+export const ModalButtonContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ gap: 5px;
+`;
+
+export const ModalErrorMessage = styled.p`
+ color: red;
+ margin-bottom: 0;
+`;
diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts
new file mode 100644
index 0000000..3df853e
--- /dev/null
+++ b/src/components/Modal/types.ts
@@ -0,0 +1,14 @@
+export interface ModalProps {
+ title: string;
+ children?: React.ReactNode;
+ onSubmit: () => void;
+ onCancel: () => void;
+ close: () => void;
+ requirementsMet?: () => boolean;
+ errorMessage?: string;
+ mandatory?: boolean;
+ $maxWidth?: string;
+
+ submitMessage?: string;
+ cancelMessage?: string;
+}
diff --git a/src/index.tsx b/src/index.tsx
index 5f21a82..fc0188f 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -4,3 +4,4 @@ export { Input } from './components/Input/Input.js';
export { Select } from './components/Select/Select.js';
export { SelectChild } from './components/Select/SelectChild.js';
export { Checkbox } from './components/Checkbox/Checkbox.js';
+export { Modal } from './components/Modal/Modal.js';