All files / components/Modal/ModalBase Modal.tsx

90% Statements 9/10
83.33% Branches 5/6
100% Functions 3/3
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55                                        74x 533x     533x 148x   148x       533x   46x 2x           533x                            
import { useCallback, useEffect, useRef } from 'react'
import { Headline } from '../../Headline/Headline'
import { IconButton } from '../../IconButton/IconButton'
 
export type ModalProps = {
	/** Modal Open/Close State. */
	open: boolean
	/** Handle close method usually set modal open state to false. */
	onClose: () => void
	/** Modal Headline. */
	headline: string
	/** Modal Content. */
	children: React.ReactNode
	/** For testing. */
	datacy?: string
}
 
/**
 * Creates a modal with headline and "x-button".
 */
export const Modal: React.FC<ModalProps> = ({ datacy, open, onClose, headline, children }) => {
	const modalRef = useRef<HTMLDialogElement>(null)
 
	// Open/Close Modal
	useEffect(() => {
		Iif (!modalRef.current) return
 
		open ? modalRef.current.showModal() : modalRef.current.close()
	}, [open])
 
	// Handle Click Outside
	const onClick = useCallback(
		(event: React.MouseEvent) => {
			if (event.target === event.currentTarget) {
				onClose() // TODO(Zoe-Bot): Fix when start click in modal and release outside of modal, modal closes. Issue #139
			}
		},
		[onClose]
	)
 
	return (
		<dialog datacy={datacy} className="rounded-lg" ref={modalRef} onClick={onClick} onClose={onClose}>
			<div className="px-3 pb-2 pt-1 md:px-6 md:pb-4 md:pt-2">
				<div className="flex items-center justify-between">
					<Headline level={3} hasMargin={false} className="mr-2 py-3 md:mr-4">
						{headline}
					</Headline>
					<IconButton datacy="modal-close-button" icon="close" onClick={onClose} className="-mr-3" />
				</div>
				{children}
			</div>
		</dialog>
	)
}