UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

210 lines (209 loc) • 8.33 kB
import React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { useTheme } from 'styled-components'; import { useElementSize } from '../../hooks/element'; import { AreaContext } from '../area-provider/AreaContextProvider'; import Icon from '../icon/Icon'; import { StyledInput, StyledInputContent, StyledInputContentWrapper, StyledInputField, StyledInputIconWrapper, StyledInputLabel, StyledInputRightElement, StyledMotionInputClearIcon, StyledMotionInputLabelWrapper } from './Input.styles'; import { ContentCardType } from '../../types/contentCard'; import { useCursorRepaint } from '../../hooks/resize'; import Tooltip from '../tooltip/Tooltip'; import { useKeyboardFocusHighlighting } from '../../hooks/useKeyboardFocusHighlighting'; export let InputSize = /*#__PURE__*/function (InputSize) { InputSize["Small"] = "small"; InputSize["Medium"] = "medium"; return InputSize; }({}); const Input = /*#__PURE__*/forwardRef(({ leftElement, inputMode, isDisabled, onBlur, onChange, onFocus, onKeyDown, onPaste, placeholder, color, rightElement, shouldShowOnlyBottomBorder, shouldRemainPlaceholder = false, shouldShowClearIcon = false, shouldShowCenteredContent = false, size = InputSize.Medium, type = 'text', value, disabledHint, shouldUseAutoFocus = false, isInvalid = false, shouldPreventPlaceholderAnimation = false, id, shouldShowTransparentBackground = false, autoComplete, shouldEnableKeyboardHighlighting }, ref) => { const [hasValue, setHasValue] = useState(typeof value === 'string' && value !== ''); const [placeholderWidth, setPlaceholderWidth] = useState(0); const areaProvider = useContext(AreaContext); const theme = useTheme(); const inputRef = useRef(null); const placeholderRef = useRef(null); useCursorRepaint(inputRef); const placeholderSize = useElementSize(placeholderRef); useEffect(() => { if (placeholderSize && shouldShowOnlyBottomBorder) { setPlaceholderWidth(placeholderSize.width + 5); } }, [placeholderSize, shouldShowOnlyBottomBorder]); const handleClearIconClick = useCallback(() => { if (inputRef.current) { inputRef.current.value = ''; setHasValue(false); if (typeof onChange === 'function') { onChange({ target: inputRef.current }); } } }, [onChange]); const handleClearIconKeyDown = useCallback(event => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); handleClearIconClick(); inputRef.current?.focus(); } }, [handleClearIconClick]); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const shouldShowBorder = rightElement?.props?.style?.backgroundColor === undefined; const handleInputFieldChange = useCallback(event => { setHasValue(event.target.value !== ''); if (typeof onChange === 'function') { onChange(event); } }, [onChange]); useImperativeHandle(ref, () => ({ focus: () => inputRef.current?.focus(), blur: () => inputRef.current?.blur() }), []); useEffect(() => { if (typeof value === 'string') { setHasValue(value !== ''); } }, [value]); let backgroundColor; let internalColor; if (shouldShowTransparentBackground) { backgroundColor = 'transparent'; } else if (areaProvider.contentCardType && [ContentCardType.Error, ContentCardType.Success, ContentCardType.Warning].includes(areaProvider.contentCardType)) { backgroundColor = 'white'; internalColor = '#555'; } else if (areaProvider.shouldChangeColor) { backgroundColor = theme['000']; } const shouldShowKeyboardHighlighting = useKeyboardFocusHighlighting(shouldEnableKeyboardHighlighting && !isDisabled); const borderColor = color?.border; const placeholderColor = color?.placeholder; const labelPosition = useMemo(() => { if (hasValue && !shouldRemainPlaceholder && !shouldPreventPlaceholderAnimation) { return shouldShowOnlyBottomBorder ? { right: 3, top: -1.5 } : { bottom: size === InputSize.Small ? -4 : -10, right: -6 }; } return { left: -1, top: -1.5 }; }, [hasValue, shouldPreventPlaceholderAnimation, shouldRemainPlaceholder, shouldShowOnlyBottomBorder, size]); const inputElement = useMemo(() => /*#__PURE__*/React.createElement(StyledInput, { className: "beta-chayns-input", $isDisabled: isDisabled }, /*#__PURE__*/React.createElement(StyledInputContentWrapper, { $shouldShowTransparentBackground: shouldShowTransparentBackground, $backgroundColor: backgroundColor, $isInvalid: isInvalid, $shouldRoundRightCorners: shouldShowBorder, $shouldShowOnlyBottomBorder: shouldShowOnlyBottomBorder, $size: size, $borderColor: borderColor, $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting }, leftElement && /*#__PURE__*/React.createElement(StyledInputIconWrapper, null, leftElement), /*#__PURE__*/React.createElement(StyledInputContent, { $shouldShowOnlyBottomBorder: shouldShowOnlyBottomBorder }, /*#__PURE__*/React.createElement(StyledInputField, { $color: internalColor, $placeholderWidth: placeholderWidth, id: id, disabled: isDisabled, onBlur: onBlur, onChange: handleInputFieldChange, onFocus: onFocus, onKeyDown: onKeyDown, onClick: event => { event.preventDefault(); event.stopPropagation(); }, onPaste: onPaste, ref: inputRef, type: type, value: value, autoFocus: shouldUseAutoFocus, inputMode: inputMode, autoComplete: autoComplete, $isInvalid: isInvalid, $shouldShowCenteredContent: shouldShowCenteredContent }), /*#__PURE__*/React.createElement(StyledMotionInputLabelWrapper, { animate: shouldPreventPlaceholderAnimation ? { opacity: hasValue ? 0 : 1 } : { fontSize: hasValue && !shouldShowOnlyBottomBorder && !shouldRemainPlaceholder ? '9px' : `${Number(theme.fontSize)}px` }, initial: false, layout: true, ref: placeholderRef, style: { ...labelPosition }, transition: { type: 'tween', duration: shouldPreventPlaceholderAnimation ? 0 : 0.1 } }, /*#__PURE__*/React.createElement(StyledInputLabel, { $color: placeholderColor, $isInvalid: isInvalid }, placeholder))), shouldShowClearIcon && /*#__PURE__*/React.createElement(StyledMotionInputClearIcon, { $shouldShowOnlyBottomBorder: shouldShowOnlyBottomBorder, $size: size, $shouldShowKeyboardHighlighting: shouldShowKeyboardHighlighting, animate: { opacity: hasValue ? 1 : 0 }, initial: false, onClick: handleClearIconClick, onKeyDown: handleClearIconKeyDown, tabIndex: shouldShowKeyboardHighlighting && hasValue && !isDisabled ? 0 : -1, role: shouldShowKeyboardHighlighting ? 'button' : undefined, "aria-hidden": !hasValue, transition: { type: 'tween' } }, /*#__PURE__*/React.createElement(Icon, { icons: ['fa fa-times'], color: isInvalid ? theme.wrong : undefined })), rightElement && shouldShowBorder && /*#__PURE__*/React.createElement(StyledInputRightElement, { $isInline: true }, rightElement)), rightElement && !shouldShowBorder && /*#__PURE__*/React.createElement(StyledInputRightElement, null, rightElement)), [isDisabled, shouldShowTransparentBackground, backgroundColor, isInvalid, shouldShowBorder, shouldShowOnlyBottomBorder, size, leftElement, internalColor, placeholderWidth, id, onBlur, handleInputFieldChange, onFocus, onKeyDown, onPaste, type, value, shouldUseAutoFocus, inputMode, autoComplete, shouldShowCenteredContent, shouldPreventPlaceholderAnimation, hasValue, shouldRemainPlaceholder, theme.fontSize, theme.wrong, labelPosition, borderColor, placeholderColor, placeholder, shouldShowClearIcon, handleClearIconClick, handleClearIconKeyDown, rightElement, shouldEnableKeyboardHighlighting, shouldShowKeyboardHighlighting]); if (isDisabled && typeof disabledHint === 'string') { return /*#__PURE__*/React.createElement(Tooltip, { item: { text: disabledHint }, shouldUseFullWidth: true }, inputElement); } return inputElement; }); Input.displayName = 'Input'; export default Input; //# sourceMappingURL=Input.js.map