diff --git a/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.styles.ts b/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.styles.ts
new file mode 100644
index 000000000..77620c121
--- /dev/null
+++ b/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.styles.ts
@@ -0,0 +1,37 @@
+import { Styles } from '@monkvision/types';
+
+export const styles: Styles = {
+ container: {
+ width: '100%',
+ height: '100%',
+ top: '0',
+ left: '0',
+ position: 'fixed',
+ zIndex: '999',
+ backgroundColor: 'black',
+ },
+ title: {
+ position: 'absolute',
+ top: '8px',
+ left: '50%',
+ transform: 'translate(-50%)',
+ padding: '8px',
+ margin: '8px',
+ fontWeight: '500',
+ fontSize: '20px',
+ color: 'white',
+ },
+ closeButton: {
+ cursor: 'pointer',
+ position: 'absolute',
+ padding: '8px',
+ top: '8px',
+ right: '8px',
+ },
+ content: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: '100%',
+ },
+};
diff --git a/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.tsx b/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.tsx
new file mode 100644
index 000000000..fa94942ae
--- /dev/null
+++ b/packages/public/common-ui-web/src/components/FullscreenModal/FullscreenModal.tsx
@@ -0,0 +1,32 @@
+import { JSX } from 'react';
+import { Button } from '../Button';
+import { styles } from './FullscreenModal.styles';
+
+/**
+ * Props that can be passed to the Fullscreen Modal component.
+ */
+export interface FullscreenModalProps {
+ show: boolean;
+ onClose?: () => void;
+ title?: string;
+ children?: string | JSX.Element | JSX.Element[];
+}
+
+/**
+ * Generic Fullscreen Modal component used to display a full screen modal on top of the screen.
+ */
+export function FullscreenModal({ show, onClose, title = '', children }: FullscreenModalProps) {
+ return show ? (
+
+
{children}
+
{title}
+
+
+ ) : null;
+}
diff --git a/packages/public/common-ui-web/src/components/FullscreenModal/index.ts b/packages/public/common-ui-web/src/components/FullscreenModal/index.ts
new file mode 100644
index 000000000..6868758fe
--- /dev/null
+++ b/packages/public/common-ui-web/src/components/FullscreenModal/index.ts
@@ -0,0 +1 @@
+export { FullscreenModal } from './FullscreenModal';
diff --git a/packages/public/common-ui-web/src/components/index.ts b/packages/public/common-ui-web/src/components/index.ts
index 219a92c61..747e4ac69 100644
--- a/packages/public/common-ui-web/src/components/index.ts
+++ b/packages/public/common-ui-web/src/components/index.ts
@@ -4,3 +4,4 @@ export * from './TakePictureButton';
export * from './DynamicSVG';
export * from './SightOverlay';
export * from './SwitchButton';
+export * from './FullscreenModal';
diff --git a/packages/public/common-ui-web/test/components/FullscreenModal.test.tsx b/packages/public/common-ui-web/test/components/FullscreenModal.test.tsx
new file mode 100644
index 000000000..c25a4cb91
--- /dev/null
+++ b/packages/public/common-ui-web/test/components/FullscreenModal.test.tsx
@@ -0,0 +1,33 @@
+import '@testing-library/jest-dom';
+import { render, screen } from '@testing-library/react';
+import { FullscreenModal } from '../../src';
+
+describe('FullsreenModal component', () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ const mockOnClose = jest.fn();
+ const title = 'test title';
+ const content = 'test content';
+
+ it('should not render modal when show is false', () => {
+ const { unmount } = render();
+ expect(screen.queryByText(title)).toBeNull();
+ expect(screen.queryByText(content)).toBeNull();
+
+ unmount();
+ });
+
+ it('renders modal with title and content when show is true', () => {
+ const { unmount } = render(
+
+ {content}
+ ,
+ );
+ expect(screen.getByText(title)).toBeInTheDocument();
+ expect(screen.getByText(content)).toBeInTheDocument();
+
+ unmount();
+ });
+});