import clsx from 'clsx'; import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; import Stack from '../stack/stack'; import Text from '../text/text'; interface ITextarea extends Pick, 'maxLength' | 'onChange' | 'onKeyDown' | 'onPaste' | 'required' | 'disabled' | 'rows' | 'readOnly'> { /** Put the cursor into the input on mount. */ autoFocus?: boolean /** Allows the textarea height to grow while typing */ autoGrow?: boolean /** Used with "autoGrow". Sets a max number of rows. */ maxRows?: number /** Used with "autoGrow". Sets a min number of rows. */ minRows?: number /** The initial text in the input. */ defaultValue?: string /** Internal input name. */ name?: string /** Renders the textarea as a code editor. */ isCodeEditor?: boolean /** Text to display before a value is entered. */ placeholder?: string /** Text in the textarea. */ value?: string /** Whether the device should autocomplete text in this textarea. */ autoComplete?: string /** Whether to display the textarea in red. */ hasError?: boolean /** Whether or not you can resize the teztarea */ isResizeable?: boolean /** Textarea theme. */ theme?: 'default' | 'transparent' /** Whether to display a character counter below the textarea. */ withCounter?: boolean } /** Textarea with custom styles. */ const Textarea = React.forwardRef(({ isCodeEditor = false, hasError = false, isResizeable = true, onChange, autoGrow = false, maxRows = 10, minRows = 1, theme = 'default', maxLength, value, ...props }: ITextarea, ref: React.ForwardedRef) => { const length = value?.length || 0; const [rows, setRows] = useState(autoGrow ? 1 : 4); const handleChange = (event: React.ChangeEvent) => { if (autoGrow) { const textareaLineHeight = 20; const previousRows = event.target.rows; event.target.rows = minRows; const currentRows = ~~(event.target.scrollHeight / textareaLineHeight); if (currentRows === previousRows) { event.target.rows = currentRows; } if (currentRows >= maxRows) { event.target.rows = maxRows; event.target.scrollTop = event.target.scrollHeight; } setRows(currentRows < maxRows ? currentRows : maxRows); } if (onChange) { onChange(event); } }; return (