import React , { useState , ReactNode , FormEvent , useCallback } from 'react' ; import { Stack , TextField , mergeStyles , IStyle , ITextField , concatStyleSets , IconButton } from '@fluentui/react' ; import { BaseCustomStyles } from '../types' ; import { inputBoxStyle , inputBoxWrapperStyle , inputButtonStyle , textFieldStyle , textContainerStyle , inlineButtonsContainerStyle , newLineButtonsContainerStyle , inputBoxNewLineSpaceAffordance } from './styles/InputBoxComponent.style' ; import { isDarkThemed } from '../theming/themeUtils' ; import { useTheme } from '../theming' ; private export interface InputBoxStylesProps extends BaseCustomStyles { /** Styles for the text field. */ textField ? : IStyle ; /** Styles for the system message; These styles will be ignored when a custom system message component is provided. */ systemMessage ? : IStyle ; /** Styles for customizing the container of the text field */ textFieldContainer ? : IStyle ; } type InputBoxComponentProps = { children : ReactNode ; /**
     * Inline child elements passed in. Setting to false will mean they are on a new line.
     */ inlineChildren : boolean ; 'data-ui-id' ? : string ; id ? : string ; textValue : string ; onChange : ( event : FormEvent < HTMLInputElement | HTMLTextAreaElement > , newValue ? : string | undefined ) => void ; textFieldRef ? : React . RefObject < ITextField > ; inputClassName ? : string ; placeholderText ? : string ; supportNewline ? : boolean ; maxLength : number ; onKeyDown ? : ( ev : React . KeyboardEvent < HTMLInputElement | HTMLTextAreaElement > ) => void ; onEnterKeyDown ? : ( ) => void ; errorMessage ? : string | React . ReactElement ; disabled ? : boolean ; styles ? : InputBoxStylesProps ; autoFocus ? : 'sendBoxTextField' | false ; } ; private export const InputBoxComponent = ( props ) : JSX . Element => { const { styles , id , 'data-ui-id' : dataUiId , textValue , onChange , textFieldRef , placeholderText , onKeyDown , onEnterKeyDown , supportNewline , inputClassName , errorMessage , disabled , children } = props ; const theme = useTheme ( ) ; const mergedRootStyle = mergeStyles ( inputBoxWrapperStyle , styles ?. root ) ; const mergedTextFiledStyle = mergeStyles ( inputBoxStyle , inputClassName , props . inlineChildren ? { } : inputBoxNewLineSpaceAffordance ) ; const mergedTextContainerStyle = mergeStyles ( textContainerStyle , styles ?. textFieldContainer ) ; const mergedTextFieldStyle = concatStyleSets ( textFieldStyle ( isDarkThemed ( theme ) ? '#f1707b' : '#a80000' , ! ! errorMessage , ! ! disabled ) , { fieldGroup : styles ?. textField , errorMessage : styles ?. systemMessage } ) ; const onTexFieldKeyDown = useCallback ( ( ev ) => { if ( ev . key === 'Enter' && ( ev . shiftKey === false || ! supportNewline ) ) { ev . preventDefault ( ) ; onEnterKeyDown && onEnterKeyDown ( ) ; } onKeyDown && onKeyDown ( ev ) ; } , [ onEnterKeyDown , onKeyDown , supportNewline ] ) ; return ( < Stack className = { mergedRootStyle } > < div className = { mergedTextContainerStyle } > < TextField autoFocus = { props . autoFocus === 'sendBoxTextField' } data - ui - id = { dataUiId } multiline autoAdjustHeight multiple = { false } resizable = { false } componentRef = { textFieldRef } id = { id } inputClassName = { mergedTextFiledStyle } placeholder = { placeholderText } value = { textValue } onChange = { onChange } autoComplete = "off" onKeyDown = { onTexFieldKeyDown } styles = { mergedTextFieldStyle } disabled = { disabled } errorMessage = { errorMessage } / > < Stack horizontal className = { mergeStyles ( props . inlineChildren ? inlineButtonsContainerStyle : newLineButtonsContainerStyle ) } > { children } < /Stack> < /div> < /Stack>); } ; private export type InputBoxButtonProps = { onRenderIcon : ( isHover : boolean ) => JSX . Element ; onClick : ( e : React . MouseEvent < HTMLDivElement , MouseEvent > ) => void ; className ? : string ; id ? : string ; ariaLabel ? : string ; } ; private export const InputBoxButton = ( props ) : JSX . Element => { const { onRenderIcon , onClick , ariaLabel , className , id } = props ; const [ isHover , setIsHover ] = useState ( false ) ; const mergedButtonStyle = mergeStyles ( inputButtonStyle , className ) ; return ( < IconButton className = { mergedButtonStyle } ariaLabel = { ariaLabel } onClick = { onClick } id = { id } onMouseEnter = { ( ) => { setIsHover ( true ) ; } } onMouseLeave = { ( ) => { setIsHover ( false ) ; } } onRenderIcon = { ( ) => onRenderIcon ( isHover ) } />); } ;