diff --git a/src/components/Inputs/Input.types.ts b/src/components/Inputs/Input.types.ts index 970eeebbd..493748bb8 100644 --- a/src/components/Inputs/Input.types.ts +++ b/src/components/Inputs/Input.types.ts @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Ref } from 'react'; import { Placement, Strategy } from '@floating-ui/react-dom'; import { IconName, IconProps } from '../Icon'; import { LabelProps } from '../Label'; @@ -146,6 +146,10 @@ export interface TextAreaProps * @default false */ enableExpand?: boolean; + /** + * The text area component ref. + */ + ref?: Ref; /** * The text area required attribute. * @default false @@ -164,6 +168,12 @@ export interface TextAreaProps } export interface TextInputProps extends InputProps { + /** + * option to show the clear input button. + * default is true for backward compatibility + * @default true + */ + clearable?: boolean; /** * The input html type. * @default 'text' @@ -175,22 +185,18 @@ export interface TextInputProps extends InputProps { */ numbersOnly?: boolean; /** - * The input required attribute. - * @default false + * onclear event handler. */ - required?: boolean; - + onClear?: React.MouseEventHandler; /** - * option to show the clear input button. - * default is true for backward compatibility - * @default true + * The input component ref. */ - clearable?: boolean; - + ref?: Ref; /** - * onclear event handler. + * The input required attribute. + * @default false */ - onClear?: React.MouseEventHandler; + required?: boolean; } export interface InputProps diff --git a/src/components/Inputs/SearchBox/SearchBox.tsx b/src/components/Inputs/SearchBox/SearchBox.tsx index 793092181..248b19e59 100644 --- a/src/components/Inputs/SearchBox/SearchBox.tsx +++ b/src/components/Inputs/SearchBox/SearchBox.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, Ref } from 'react'; import { IconName } from '../../Icon'; import { TextInputWidth, @@ -8,63 +8,71 @@ import { TextInputTheme, } from '../index'; -export const SearchBox: FC = ({ - allowDisabledFocus = false, - ariaLabel, - autoFocus = false, - classNames, - clearButtonAriaLabel, - disabled = false, - iconProps, - iconButtonProps = { - allowDisabledFocus: false, - disabled: false, - iconProps: { path: IconName.mdiMagnify }, - }, - inputWidth = TextInputWidth.fitContent, - labelProps, - maxlength, - minlength, - name, - onBlur, - onChange, - onFocus, - onKeyDown, - placeholder = 'Search', - shape = TextInputShape.Rectangle, - style, - theme = TextInputTheme.light, - value, - waitInterval = 500, - ...rest -}) => ( -
- - +export const SearchBox: FC = React.forwardRef( + ( + { + allowDisabledFocus = false, + ariaLabel, + autoFocus = false, + classNames, + clearButtonAriaLabel, + disabled = false, + iconProps, + iconButtonProps = { + allowDisabledFocus: false, + disabled: false, + iconProps: { path: IconName.mdiMagnify }, + }, + inputWidth = TextInputWidth.fitContent, + labelProps, + maxlength, + minlength, + name, + onBlur, + onChange, + onFocus, + onKeyDown, + placeholder = 'Search', + shape = TextInputShape.Rectangle, + style, + theme = TextInputTheme.light, + value, + waitInterval = 500, + ...rest + }, + ref: Ref + ) => { + return ( +
+ + + ); + } ); diff --git a/src/components/Inputs/TextArea/TextArea.tsx b/src/components/Inputs/TextArea/TextArea.tsx index 1db7526da..afd87afa3 100644 --- a/src/components/Inputs/TextArea/TextArea.tsx +++ b/src/components/Inputs/TextArea/TextArea.tsx @@ -1,4 +1,4 @@ -import React, { FC, useState } from 'react'; +import React, { FC, Ref, useState } from 'react'; import { Icon, IconName } from '../../Icon'; import { Label } from '../../Label'; import { TextInputWidth, TextAreaProps, TextInputTheme } from '../index'; @@ -7,94 +7,105 @@ import { mergeClasses, uniqueId } from '../../../shared/utilities'; import styles from '../input.module.scss'; -export const TextArea: FC = ({ - allowDisabledFocus = false, - ariaLabel, - autoFocus = false, - classNames, - disabled = false, - enableExpand = false, - id, - inputWidth = TextInputWidth.fitContent, - labelProps, - maxlength, - minlength, - name, - onBlur, - onChange, - onFocus, - onKeyDown, - placeholder, - required = false, - style, - textAreaCols = 50, - textAreaRows = 5, - theme = TextInputTheme.light, - value, - waitInterval = 10, - ...rest -}) => { - const [textAreaId] = useState(uniqueId(id || 'textarea-')); - - const textAreaClassNames: string = mergeClasses([ - classNames, - styles.textArea, - { [styles.textAreaNoExpand]: !enableExpand }, - { [styles.dark]: theme === TextInputTheme.dark }, - { [styles.inputStretch]: inputWidth === TextInputWidth.fill }, - ]); - - const textAreaWrapperClassNames: string = mergeClasses([ - styles.inputWrapper, +export const TextArea: FC = React.forwardRef( + ( { - [styles.inputStretch]: inputWidth === TextInputWidth.fill, + allowDisabledFocus = false, + ariaLabel, + autoFocus = false, + classNames, + disabled = false, + enableExpand = false, + id, + inputWidth = TextInputWidth.fitContent, + labelProps, + maxlength, + minlength, + name, + onBlur, + onChange, + onFocus, + onKeyDown, + placeholder, + required = false, + style, + textAreaCols = 50, + textAreaRows = 5, + theme = TextInputTheme.light, + value, + waitInterval = 10, + ...rest }, - ]); + ref: Ref + ) => { + const [textAreaId] = useState(uniqueId(id || 'textarea-')); - const handleChange = useDebounce>( - (_event?: React.ChangeEvent) => - triggerChange(_event), - waitInterval - ); + const textAreaClassNames: string = mergeClasses([ + classNames, + styles.textArea, + { [styles.textAreaNoExpand]: !enableExpand }, + { [styles.dark]: theme === TextInputTheme.dark }, + { [styles.inputStretch]: inputWidth === TextInputWidth.fill }, + ]); - const triggerChange = ( - _event?: React.ChangeEvent - ) => { - onChange && onChange(_event); - }; + const textAreaWrapperClassNames: string = mergeClasses([ + styles.inputWrapper, + { + [styles.inputStretch]: inputWidth === TextInputWidth.fill, + }, + ]); + + const handleChange = useDebounce< + React.ChangeEvent + >( + ( + _event?: React.ChangeEvent< + HTMLTextAreaElement | HTMLInputElement + > + ) => triggerChange(_event), + waitInterval + ); + + const triggerChange = ( + _event?: React.ChangeEvent + ) => { + onChange && onChange(_event); + }; - return ( -
- {labelProps &&