diff --git a/src/components/ChatWindow/ChatInput/ChatInput.test.tsx b/src/components/ChatWindow/ChatInput/ChatInput.test.tsx index 8123d3480..461dd3bc8 100644 --- a/src/components/ChatWindow/ChatInput/ChatInput.test.tsx +++ b/src/components/ChatWindow/ChatInput/ChatInput.test.tsx @@ -114,6 +114,30 @@ describe('the ChatInput component', () => { expect(mockHandleSendMessage).not.toHaveBeenCalled(); }); + it('should add the "isTextareaFocused" class to the parent of TextareaAutosize when the focus event is fired, and remove it when the blur event is fired', () => { + const wrapper = mount( + + ); + + wrapper.find(TextareaAutosize).simulate('focus'); + + expect( + wrapper + .find(TextareaAutosize) + .parent() + .prop('className') + ).toContain('isTextareaFocused'); + + wrapper.find(TextareaAutosize).simulate('blur'); + + expect( + wrapper + .find(TextareaAutosize) + .parent() + .prop('className') + ).not.toContain('isTextareaFocused'); + }); + it('should disable the file input button and display a loading spinner while sending a file', done => { const wrapper = shallow( diff --git a/src/components/ChatWindow/ChatInput/ChatInput.tsx b/src/components/ChatWindow/ChatInput/ChatInput.tsx index e5ed34dd1..a0646394b 100644 --- a/src/components/ChatWindow/ChatInput/ChatInput.tsx +++ b/src/components/ChatWindow/ChatInput/ChatInput.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { Button, CircularProgress, Grid, makeStyles } from '@material-ui/core'; +import clsx from 'clsx'; import { Conversation } from '@twilio/conversations/lib/conversation'; import FileAttachmentIcon from '../../../icons/FileAttachmentIcon'; import { isMobile } from '../../../utils'; @@ -7,20 +8,19 @@ import SendMessageIcon from '../../../icons/SendMessageIcon'; import Snackbar from '../../Snackbar/Snackbar'; import TextareaAutosize from '@material-ui/core/TextareaAutosize'; -const useStyles = makeStyles({ +const useStyles = makeStyles(theme => ({ chatInputContainer: { borderTop: '1px solid #e4e7e9', borderBottom: '1px solid #e4e7e9', padding: '1em 1.2em 1em', }, textArea: { - padding: '0.75em 1em', - marginTop: '0.4em', width: '100%', border: '0', resize: 'none', fontSize: '14px', fontFamily: 'Inter', + outline: 'none', }, button: { padding: '0.56em', @@ -47,7 +47,17 @@ const useStyles = makeStyles({ marginTop: -12, marginLeft: -12, }, -}); + textAreaContainer: { + display: 'flex', + marginTop: '0.4em', + padding: '0.48em 0.7em', + border: '2px solid transparent', + }, + isTextareaFocused: { + borderColor: theme.palette.primary.main, + borderRadius: '4px', + }, +})); interface ChatInputProps { conversation: Conversation; @@ -65,6 +75,7 @@ export default function ChatInput({ conversation, isChatWindowOpen }: ChatInputP const isValidMessage = /\S/.test(messageBody); const textInputRef = useRef(null); const fileInputRef = useRef(null); + const [isTextareaFocused, setIsTextareaFocused] = useState(false); useEffect(() => { if (isChatWindowOpen) { @@ -125,19 +136,27 @@ export default function ChatInput({ conversation, isChatWindowOpen }: ChatInputP variant="error" handleClose={() => setFileSendError(null)} /> - - +
+ {/* + Here we add the "isTextareaFocused" class when the user is focused on the TextareaAutosize component. + This helps to ensure a consistent appearance across all browsers. Adding padding to the TextareaAutosize + component does not work well in Firefox. See: https://github.com/twilio/twilio-video-app-react/issues/498 + */} + setIsTextareaFocused(true)} + onBlur={() => setIsTextareaFocused(false)} + /> +
{/* Since the file input element is invisible, we can hardcode an empty string as its value. diff --git a/src/components/ChatWindow/ChatWindow.tsx b/src/components/ChatWindow/ChatWindow.tsx index 618404bad..6eb0b419c 100644 --- a/src/components/ChatWindow/ChatWindow.tsx +++ b/src/components/ChatWindow/ChatWindow.tsx @@ -10,7 +10,7 @@ const useStyles = makeStyles((theme: Theme) => createStyles({ chatWindowContainer: { background: '#FFFFFF', - zIndex: 100, + zIndex: 9, display: 'flex', flexDirection: 'column', borderLeft: '1px solid #E4E7E9', @@ -20,6 +20,7 @@ const useStyles = makeStyles((theme: Theme) => left: 0, bottom: 0, right: 0, + zIndex: 100, }, }, hide: {