import React, { useEffect } from 'react'; import styled from 'styled-components'; import v from '../../styles/Variables'; import H2 from '../Headings/H2'; import Close from '../NavButton/Close'; interface Props { /** * Valid JSX object that you want displayed in the modal */ children: string; /** * A callback to run when the close button or the modal mask is clicked */ closeCb: () => void; /** * The color of the alpha mask, in rgba format (will be black if none supplied) * */ maskColor: string; /** * If the modal should be shown or not */ show: boolean; /** * Classes to be applied to the wrapper of the modal */ theme: string; /** * Classes to be applied to the body of the modal */ themeBody: string; /** * The title displayed on the modal */ title: string; /** * Width, in percent, of the modal, mobile will also 94% unless you override with css */ width: number; /** * If the close button should be shown or not */ showCloseButton: boolean; ariaLabel?: string; } interface StyleProps { width: number; } interface MaskProps { maskColor: string; } const ModalBody = styled.div` margin-top: 15; position: fixed; z-index: 99999; max-height: 95%; overflow: scroll; text-align: left; width: ${({ width }) => `${width}%`}; left: ${({ width }) => `${(100 - width) / 2}%`}; background: ${v.colors.light}; top: 20px; box-shadow: ${v.shadow}; min-height: 300px; `; const ContentBody = styled.div` padding: 15px; `; const ModalClose = styled.span` float: right; margin: 7px; `; const ModalHeader = styled.header` h2 { padding: 15px; } `; const ModalMask = styled.aside` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: ${({ maskColor }) => maskColor}; z-index: 9999; `; const Modal = ({ children, closeCb, maskColor = 'rgba(0,0,0,0.7)', show, theme, themeBody, title, ariaLabel = '', width, showCloseButton = false }: Props) => { useEffect(() => { const win = window.document.getElementsByTagName('html')[0]; if (show === true) { win.classList.add('nwc--noscroll'); document.getElementById('nwc--modal')?.focus(); } else { win.classList.remove('nwc--noscroll'); } }, [show]); useEffect(() => { var dialog = document.querySelector('[role="dialog"]'); var firstFocusableElement = document?.getElementById('nwc--modal'); var lastFocusableElement = document?.getElementById('nwc--modal-mask'); if (show === true) { dialog?.addEventListener('keydown', function (e: any) { console.log(e.target.id, 'id'); if (e.target.id === firstFocusableElement?.id && e.key === 'Tab' && e.shiftKey) { // console.log(e.target.id, 'shift'); e.preventDefault(); lastFocusableElement?.focus(); } else if (e.target.id === lastFocusableElement?.id && e.key === 'Tab' && !e.shiftKey) { // console.log(e.target.id, firstFocusableElement?.id, 'tab'); e.preventDefault(); firstFocusableElement?.focus(); } }); } }, [show]); if (show !== true) return <>; return ( ); }; export default Modal;