# All files / Dialog Dialog.tsx

0% Statements 0/37
0% Branches 0/11
0% Functions 0/7
0% Lines 0/37

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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122

     import * as React from 'react'
    import classNames from 'classnames'
    import { createUseStyles } from '@fluent-ui/styles'
    import { styles } from './Dialog.styled'
    import { Theme } from '../styles'

    import Portal from '../Portal'
    import Transition from '../Transition'
    import Title from './components/Title'
    import Content from './components/Content'
    import Actions from './components/Actions'
    import {
      DialogProps,
      DialogType,
      DialogChild,
      DialogContainer,
      DialogContextType,
      DialogPropTypes,
      DialogClassProps
    } from './Dialog.type'

    export const name = 'Dialog'

    const useStyles = createUseStyles<Theme, DialogClassProps>(styles, { name })

    export const DialogContext = React.createContext<DialogContextType>({
      onChange: (): void => {}
    })

    const Dialog: React.FC<DialogProps> = React.forwardRef<HTMLDivElement, DialogProps>(
      (props, ref): React.ReactElement | null => {
        const {
          as: Component = 'div',
          className: classNameProp,
          children,
          visible,
          onChange,
          ...rest
        } = props

        function handleClose(): void {
          onChange && onChange(false)
        }

        const container: DialogContainer = {
          title: undefined,
          content: [],
          actions: undefined
        }
        React.Children.forEach(
          children,
          (child: DialogChild): void => {
            if (child.type.displayName! === `F${name}Title`) {
              container.title = child
            } else if (child.type.displayName === `F${name}Actions`) {
              container.actions = child
            } else {
              container.content.push(child)
            }
          }
        )

        const contextValue: DialogContextType = {
          onChange: onChange as (visible: boolean) => void
        }

        const classes = useStyles(props)
        const className = classNames(classes.root, classNameProp)

        return (
          <>
            <Portal>
              <Transition visible={visible} wrapper={false} mountOnEnter unmountOnExit>
                <div className={classes.mask} onClick={handleClose} />
              </Transition>
            </Portal>
            <Portal>
              <Transition visible={visible} wrapper={false} mountOnEnter unmountOnExit>
                <Component
                  className={className}
                  ref={ref}
                  boxShadow="5"
                  width={{ xs: '288px', sm: 'auto' }}
                  maxWidth={{ xs: '340px', sm: '450px' }}
                  minWidth={{ xs: '288px', sm: '340px' }}
                  {...rest}
                >
                  <DialogContext.Provider value={contextValue}>
                    {!!container.title && container.title}
                    <div className={classes.content}>{container.content}</div>
                    {!!container.actions && container.actions}
                  </DialogContext.Provider>
                </Component>
              </Transition>
            </Portal>
          </>
        )
      }
    )

    Object.defineProperty(Dialog, 'Title', {
      get(): typeof Title {
        return Title
      }
    })
    Object.defineProperty(Dialog, 'Content', {
      get(): typeof Content {
        return Content
      }
    })
    Object.defineProperty(Dialog, 'Actions', {
      get(): typeof Actions {
        return Actions
      }
    })

    Dialog.displayName = `F${name}`

    Dialog.propTypes = DialogPropTypes

    export default Dialog as DialogType