# All files / Input Input.tsx

0% Statements 0/29
0% Branches 0/14
0% Functions 0/5
0% Lines 0/29

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

     import * as React from 'react'
    import classNames from 'classnames'
    import { createUseStyles } from '@fluent-ui/styles'
    import { styles } from './Input.styled'
    import { Theme } from '../styles'
    import { InputClassProps, InputProps, InputPropTypes } from './Input.type'

    import { ChromeClose as ChromeCloseIcon } from '@fluent-ui/icons'
    import Transition from '../Transition'

    export const name = 'Input'

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

    const Input: React.FC<InputProps> = React.forwardRef<HTMLInputElement, InputProps>(
      (props, ref): React.ReactElement => {
        const {
          className: classNameProp,
          value,
          onChange,
          placeholder,
          disabled,
          cleared,
          password,
          error,
          ...rest
        } = props

        const clearedRef = React.useRef<HTMLSpanElement>(null)
        const [clearedHeight, setClearedHeight] = React.useState(0)
        React.useEffect((): void => {
          if (clearedRef && clearedRef.current) {
            setClearedHeight(clearedRef.current.offsetHeight)
          }
        }, [])
        function handleChange(e: React.ChangeEvent<HTMLInputElement> | null): void {
          onChange && onChange(e ? e.target.value : '')
        }
        function handleClear(e: React.MouseEvent<HTMLElement>): void {
          e.preventDefault()
          e.stopPropagation()
          handleChange(null)
        }

        const classes = useStyles(props)
        const className = classNames(
          classes.root,
          {
            [classes.error]: error
          },
          classNameProp
        )
        const clearedInputStyle = React.useMemo(
          (): object =>
            cleared
              ? {
                  paddingRight: clearedHeight
                }
              : {},
          [cleared, clearedHeight]
        )

        return (
          <div className={classes.wrapper}>
            <input
              className={className}
              ref={ref}
              value={value}
              onChange={handleChange}
              placeholder={placeholder}
              disabled={disabled}
              type={password ? 'password' : 'text'}
              style={clearedInputStyle}
              {...rest}
            />
            {cleared && (
              <Transition visible={!!value} wrapper={false}>
                <span
                  className={classes.clearedIcon}
                  onClick={handleClear}
                  ref={clearedRef}
                  style={{
                    width: clearedHeight
                  }}
                >
                  <ChromeCloseIcon />
                </span>
              </Transition>
            )}
          </div>
        )
      }
    )

    Input.displayName = `F${name}`

    Input.propTypes = InputPropTypes

    export default Input