1414 * limitations under the License.
1515 */
1616
17- import { TextareaHTMLAttributes , useEffect , useRef , useState } from 'react'
17+ import { TextareaHTMLAttributes , useCallback , useEffect , useRef , useState } from 'react'
1818
1919import { useThrottledEffect } from '@Common/Helper'
2020import {
@@ -25,16 +25,15 @@ import {
2525import { deriveBorderRadiusAndBorderClassFromConfig } from '@Shared/Helpers'
2626
2727import { FormFieldWrapper , getFormFieldAriaAttributes } from '../FormFieldWrapper'
28- import { TEXTAREA_CONSTRAINTS } from './constants'
2928import { TextareaProps } from './types'
29+ import { getTextAreaConstraintsForSize } from './utils'
3030
3131import './textarea.scss'
3232
33- const { MIN_HEIGHT , AUTO_EXPANSION_MAX_HEIGHT } = TEXTAREA_CONSTRAINTS
34-
3533const Textarea = ( {
3634 name,
3735 label,
36+ textareaRef : textareaRefProp ,
3837 fullWidth,
3938 error,
4039 helperText,
@@ -51,20 +50,37 @@ const Textarea = ({
5150 hideFormFieldInfo,
5251 value,
5352 borderConfig,
53+ disableResize,
54+ newlineOnShiftEnter = false ,
5455 ...props
5556} : TextareaProps ) => {
5657 const textareaRef = useRef < HTMLTextAreaElement > ( null )
5758 // If the passed value remains the same, the component will behave as un-controlled
5859 // else, it behaves as controlled
5960 const [ text , setText ] = useState ( '' )
6061
62+ const { MIN_HEIGHT , AUTO_EXPANSION_MAX_HEIGHT } = getTextAreaConstraintsForSize ( size )
63+
6164 const updateRefsHeight = ( height : number ) => {
6265 const refElement = textareaRef . current
6366 if ( refElement ) {
6467 refElement . style . height = `${ height } px`
6568 }
6669 }
6770
71+ const refCallback = useCallback ( ( node : HTMLTextAreaElement ) => {
72+ if ( textareaRefProp ) {
73+ if ( typeof textareaRefProp === 'function' ) {
74+ textareaRefProp ( node )
75+ } else {
76+ // eslint-disable-next-line no-param-reassign
77+ textareaRefProp . current = node
78+ }
79+ }
80+
81+ textareaRef . current = node
82+ } , [ ] )
83+
6884 const reInitHeight = ( ) => {
6985 const currentHeight = parseInt ( textareaRef . current . style . height , 10 )
7086 let nextHeight = textareaRef . current . scrollHeight || 0
@@ -116,9 +132,13 @@ const Textarea = ({
116132 const handleKeyDown : TextareaHTMLAttributes < HTMLTextAreaElement > [ 'onKeyDown' ] = (
117133 event : React . KeyboardEvent < HTMLTextAreaElement > ,
118134 ) => {
119- if ( ( event . key === 'Enter' && ! event . metaKey && ! event . ctrlKey ) || event . key === 'Escape' ) {
135+ if ( event . key === 'Enter' || event . key === 'Escape' ) {
120136 event . stopPropagation ( )
121137
138+ if ( newlineOnShiftEnter && event . key === 'Enter' && ! event . shiftKey ) {
139+ event . preventDefault ( )
140+ }
141+
122142 if ( event . key === 'Escape' ) {
123143 textareaRef . current . blur ( )
124144 }
@@ -163,11 +183,12 @@ const Textarea = ({
163183 onBlur = { handleBlur }
164184 onKeyDown = { handleKeyDown }
165185 className = { `${ COMPONENT_SIZE_TYPE_TO_FONT_AND_BLOCK_PADDING_MAP [ size ] } ${ COMPONENT_SIZE_TYPE_TO_INLINE_PADDING_MAP [ size ] } ${ deriveBorderRadiusAndBorderClassFromConfig ( { borderConfig, borderRadiusConfig } ) } w-100 dc__overflow-auto textarea` }
166- ref = { textareaRef }
186+ ref = { refCallback }
167187 style = { {
168188 // No max height when user is expanding
169189 maxHeight : 'none' ,
170190 minHeight : MIN_HEIGHT ,
191+ resize : disableResize ? 'none' : 'vertical' ,
171192 } }
172193 />
173194 </ FormFieldWrapper >
0 commit comments