main

mattermost/focalboard

Last updated at: 28/12/2023 01:37

dialog.tsx

TLDR

This file, located at webapp/src/components/dialog.tsx, contains the code for a React component called Dialog. The Dialog component is a reusable dialog box that can be used to display various types of content. It includes a title, subtitle, toolbar, and customizable close button. The dialog can also be closed by pressing the Esc key.

Methods

This file does not contain any methods.

Classes

This file does not contain any additional classes.

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

import IconButton from '../widgets/buttons/iconButton'
import CloseIcon from '../widgets/icons/close'
import OptionsIcon from '../widgets/icons/options'
import MenuWrapper from '../widgets/menuWrapper'
import './dialog.scss'

type Props = {
    children: React.ReactNode
    size?: string
    toolsMenu?: React.ReactNode // some dialogs may not  require a toolmenu
    toolbar?: React.ReactNode
    hideCloseButton?: boolean
    className?: string
    title?: JSX.Element
    subtitle?: JSX.Element
    onClose: () => void
}

const Dialog = (props: Props) => {
    const {toolsMenu, toolbar, title, subtitle, size} = props
    const intl = useIntl()

    const closeDialogText = intl.formatMessage({
        id: 'Dialog.closeDialog',
        defaultMessage: 'Close dialog',
    })

    useHotkeys('esc', () => props.onClose())

    const isBackdropClickedRef = useRef(false)

    return (
        <div className={`Dialog dialog-back ${props.className} size--${size || 'medium'}`}>
            <div className='backdrop'/>
            <div
                className='wrapper'
                onClick={(e) => {
                    e.stopPropagation()
                    if (!isBackdropClickedRef.current) {
                        return
                    }
                    isBackdropClickedRef.current = false
                    props.onClose()
                }}
                onMouseDown={(e) => {
                    if (e.target === e.currentTarget) {
                        isBackdropClickedRef.current = true
                    }
                }}
            >
                <div
                    role='dialog'
                    className='dialog'
                >
                    <div className='toolbar'>
                        <div>
                            {<h1 className='dialog-title'>{title || ''}</h1>}
                            {subtitle && <h5 className='dialog-subtitle'>{subtitle}</h5>}
                        </div>
                        <div className='toolbar--right'>
                            {toolbar && <div className='d-flex'>{toolbar}</div>}
                            {toolsMenu && <MenuWrapper>
                                <IconButton
                                    size='medium'
                                    icon={<OptionsIcon/>}
                                />
                                {toolsMenu}
                            </MenuWrapper>
                            }
                            {
                                !props.hideCloseButton &&
                                <IconButton
                                    className='dialog__close'
                                    onClick={props.onClose}
                                    icon={<CloseIcon/>}
                                    title={closeDialogText}
                                    size='medium'
                                />
                            }
                        </div>
                    </div>
                    {props.children}
                </div>
            </div>
        </div>
    )
}

export default React.memo(Dialog)