import React, { useRef, useImperativeHandle, useEffect, useMemo, useState } from 'react' import useTheme from '../use-theme' import withDefaults from '../utils/with-defaults' import { NormalTypes } from '../utils/prop-types' import { getColors } from '../input/styles' interface Props { value?: string initialValue?: string placeholder?: string status?: NormalTypes width?: string minHeight?: string disabled?: boolean readOnly?: boolean onChange?: (e: React.ChangeEvent) => void onFocus?: (e: React.FocusEvent) => void onBlur?: (e: React.FocusEvent) => void className?: string } const defaultProps = { initialValue: '', status: 'default' as NormalTypes, width: 'initial', minHeight: '6.25rem', disabled: false, readOnly: false, className: '' } type NativeAttrs = Omit, keyof Props> export type TextareaProps = Props & typeof defaultProps & NativeAttrs const Textarea = React.forwardRef>( ( { width, status, minHeight, disabled, readOnly, onFocus, onBlur, className, initialValue, onChange, value, placeholder, ...props }, ref: React.Ref ) => { const theme = useTheme() const textareaRef = useRef(null) useImperativeHandle(ref, () => textareaRef.current) const isControlledComponent = useMemo(() => value !== undefined, [value]) const [selfValue, setSelfValue] = useState(initialValue) const [hover, setHover] = useState(false) const { color, borderColor, hoverBorder } = useMemo( () => getColors(theme.palette, status), [theme.palette, status] ) const changeHandler = (event: React.ChangeEvent) => { if (disabled || readOnly) return setSelfValue(event.target.value) onChange && onChange(event) } const focusHandler = (e: React.FocusEvent) => { setHover(true) onFocus && onFocus(e) } const blurHandler = (e: React.FocusEvent) => { setHover(false) onBlur && onBlur(e) } useEffect(() => { if (isControlledComponent) { setSelfValue(value as string) } }) const controlledValue = isControlledComponent ? { value: selfValue } : { defaultValue: initialValue } const textareaProps = { ...props, ...controlledValue } return (