<div id="root"></div><div id="root"></div><div id="root"></div>
.voces-regular {
  font-family: "Voces", sans-serif;
  font-weight: 400;
  font-style: normal;
}
const { useState, useRef, useCallback, useEffect, forwardRef, memo } = React;
const { createGlobalStyle } = styled;

const useModal = (initialShow: boolean): [boolean, () => void] => {
	const [show, setShow] = useState(initialShow);

	const closeModal = () => setShow(false);

	useEffect(() => {
		setShow(initialShow);
	}, [initialShow]);

	return [show, closeModal];
};

type ButtonComponentProps = {
	disabled?: boolean;
	color?: {
		background?: string;
		text?: string;
	};
	callback?: () => void;
	children: React.ReactNode;
	fontSize?: string
};

const StyledButton = styled.button<ButtonComponentProps>`
	background-color: ${({ color }) => (color && color.background) || "lightgray"};
	border: none;
	border-radius: 0.3em;
	color: ${({ color }) => (color && color.text) || "#333333"};
	cursor: pointer;
	font-size: ${({ fontSize }) => (fontSize && fontSize) || "1em"};
	outline: none;
	opacity: ${({ disabled }) => disabled && .3 || 1};;
	padding: ${({ fontSize }) => fontSize && fontSize || "1em"};
	width: 100%;
`;

const Button = ({ className, onClick, color, fontSize, disabled, children }: ButtonComponentProps) => {
	return (
		<StyledButton
			className={className}
			onClick={onClick}
			color={color}
			fontSize={fontSize}
			disabled={disabled}
		>{children}</StyledButton>
	);
};

type ModalComponentProps = {
	className?: string;
	initialShow?: boolean;
	showCloseButton?: boolean;
	closableOverlay?: boolean;
	//closeable?: boolean;
};

const StyledModal = styled.div`
	background-color: #fff;
	border-radius: .4em;
	box-shadow: 0 .5em .6em 0 rgba(0,0,0,0.2),0 .6em 2em 0 rgba(0,0,0,0.17);
	color: #333;
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 1em;
	position: relative;
	min-height: 14em;
	min-width: 20em;

	& .modal-close-button {
		background: transparent;//#6486ed;
		color: #aaa;
		border-radius: 100%;
		display: block;
		font-size: 1.4em;
		height: 2.4em;
		padding: 0;
		position: absolute;
		top: 0;//-1.2em;
		right: 0;//-1.2em;
		width: 2.4em;
	}
`;

const Overlay = styled.div`
	background-color: rgba(0, 0, 0, .5);
	display: flex;
	align-items: center;
	justify-content: center;
	height: 100%;
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	z-index: 2000;
`;

const ModalContent = styled.p`
	text-align: center;
`;

const Modal = ({ className, initialShow=true, showCloseButton=true, closableOverlay=true, children }: ModalComponentProps) => {
	const [show, closeModal] = useModal(initialShow);

	return show ? (
		<Overlay className="modal-overlay" {...(closableOverlay && {onClick: closeModal})}>
			<StyledModal className={className} onClick={e => e.stopPropagation()}>
				<ModalContent className="modal-content">{children}</ModalContent>
				{showCloseButton && <Button
					className="modal-close-button"
					onClick={closeModal}
				>×</Button>}
			</StyledModal>
		</Overlay>
	) : null;
};

const GlobalStyle = createGlobalStyle`
	html {
		
	}
    body {
		background-color: #C7E5E6;
		text-align: center;
    }
`;

const App = () => {
	return (
		<div>
		<GlobalStyle />
		<h1>Hello world!</h1>
			<Modal className="voces-regular">
					<div>
						<h1>Modal</h1>
						<p>something</p>
					</div>
				</Modal>
		</div>
	);
};

ReactDOM.render(<App />, document.getElementById("root"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/styled-components/6.1.8/styled-components.min.js