main

mattermost/focalboard

Last updated at: 29/12/2023 09:46

modal.tsx

TLDR

This file contains a React component that represents a modal. The modal can be positioned at the top, bottom, or bottom-right of the screen. It includes a toolbar with a close button and can contain any child elements.

Methods

None

Classes

None

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useRef, useEffect, useCallback} from 'react'

import IconButton from '../widgets/buttons/iconButton'
import CloseIcon from '../widgets/icons/close'
import './modal.scss'

type Props = {
    onClose: () => void
    position?: 'top'|'bottom'|'bottom-right'
    children: React.ReactNode
}

const Modal = (props: Props): JSX.Element => {
    const node = useRef<HTMLDivElement>(null)

    const {position, onClose, children} = props

    const closeOnBlur = useCallback((e: Event) => {
        if (e.target && node.current?.contains(e.target as Node)) {
            return
        }
        onClose()
    }, [onClose])

    useEffect(() => {
        document.addEventListener('click', closeOnBlur, true)
        return () => {
            document.removeEventListener('click', closeOnBlur, true)
        }
    }, [closeOnBlur])

    return (
        <div
            className={'Modal ' + (position || 'bottom')}
            ref={node}
        >
            <div className='toolbar hideOnWidescreen'>
                <IconButton
                    onClick={() => onClose()}
                    icon={<CloseIcon/>}
                    title={'Close'}
                />
            </div>
            {children}
        </div>
    )
}

export default React.memo(Modal)