/** * The new input element * * @author Platon Fedorov * @date 2021-01-13 */ import * as React from 'react'; import * as styles from './wrapper.m.scss'; import {joinClassNames, safeInvoke, SIZE} from '../../index'; import {renderIcon} from '../../utils/renderIcon'; import {getSizeThemeKey} from '../../utils/getSizeThemeKey'; import {SizeClassNames, Props} from './Wrapper.types'; export type WrapperProps = Props; export class Wrapper extends React.Component { wrapperRef = React.createRef(); constructor (props: WrapperProps) { super(props); this.onClickOutside = this.onClickOutside.bind(this); } override componentDidMount () { document.addEventListener('mousedown', this.onClickOutside); if (this.wrapperRef.current !== null && this.props.onWrapperFocus !== undefined) { this.wrapperRef.current.addEventListener('focus', this.props.onWrapperFocus); } } override componentWillUnmount () { document.removeEventListener('mousedown', this.onClickOutside); if (this.wrapperRef.current !== null && this.props.onWrapperFocus !== undefined) { this.wrapperRef.current.removeEventListener('focus', this.props.onWrapperFocus); } } createRef () { if (this.props.forwardRef) { this.wrapperRef = this.props.forwardRef; } return this.wrapperRef; } onClickOutside (e: MouseEvent) { if (this.wrapperRef.current && this.props.isFocused && e.target instanceof Node && !this.wrapperRef.current.contains(e.target) ) { safeInvoke(this.props.onClickOutside, e); } } renderChild () { const {children} = this.props; return (
{children}
); } renderPrefix () { const {prefix, size, onPrefixClick} = this.props; const classPrefix = joinClassNames( styles.icon, styles.prefixIcon, [styles.iconIsClickable, Boolean(onPrefixClick)] ); return prefix ? ( renderIcon(this.props.prefix, {size}, { className: classPrefix, tabIndex: -1, onClick: onPrefixClick })) : null; } renderSuffix () { const {suffix, size, onSuffixClick} = this.props; const classSuffix = joinClassNames( styles.icon, styles.suffixIcon, [styles.iconIsClickable, Boolean(onSuffixClick)] ); return suffix ? ( renderIcon(this.props.suffix, {size}, { className: classSuffix, tabIndex: -1, onClick: onSuffixClick })) : null; } renderError () { const hasError = this.props.hasError, errorMessage = this.props.errorMessage; if (hasError && errorMessage) { return (
{errorMessage}
); } else { return null; } } override render () { const { hasError, isFocused, transparent, isDisabled, isReadOnly, forwardRef, size = SIZE.MIDDLE, prefixRef, suffixRef, errorMessage, prefix, suffix, onPrefixClick, onSuffixClick, onBlur, onClickOutside, onWrapperFocus, ...props } = this.props; const sizeThemeKey = getSizeThemeKey('', size); const classContainer = joinClassNames( styles.wrapperContainer, styles[sizeThemeKey], [styles.transparent, transparent === true], [styles.error, hasError === true], [styles.focused, isFocused === true], [styles.readonly, isReadOnly === true], [styles.disabled, isDisabled === true] ); return ( <>
{this.renderPrefix()} {this.renderChild()} {this.renderSuffix()}
{this.renderError()} ); } }