Skip to content

Commit

Permalink
Fix firefox styling of textarea element (#512)
Browse files Browse the repository at this point in the history
* Fix firefox styling of textarea element

* Fix cypress tests
  • Loading branch information
timmydoza authored May 11, 2021
1 parent 526afbc commit 85be841
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 18 deletions.
24 changes: 24 additions & 0 deletions src/components/ChatWindow/ChatInput/ChatInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<ChatInput conversation={{ sendMessage: mockHandleSendMessage } as any} isChatWindowOpen={true} />
);

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(
<ChatInput conversation={{ sendMessage: mockHandleSendMessage } as any} isChatWindowOpen={true} />
Expand Down
53 changes: 36 additions & 17 deletions src/components/ChatWindow/ChatInput/ChatInput.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
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';
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',
Expand All @@ -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;
Expand All @@ -65,6 +75,7 @@ export default function ChatInput({ conversation, isChatWindowOpen }: ChatInputP
const isValidMessage = /\S/.test(messageBody);
const textInputRef = useRef<HTMLTextAreaElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
const [isTextareaFocused, setIsTextareaFocused] = useState(false);

useEffect(() => {
if (isChatWindowOpen) {
Expand Down Expand Up @@ -125,19 +136,27 @@ export default function ChatInput({ conversation, isChatWindowOpen }: ChatInputP
variant="error"
handleClose={() => setFileSendError(null)}
/>

<TextareaAutosize
rowsMin={1}
rowsMax={3}
className={classes.textArea}
aria-label="chat input"
placeholder="Write a message..."
onKeyPress={handleReturnKeyPress}
onChange={handleChange}
value={messageBody}
data-cy-chat-input
ref={textInputRef}
/>
<div className={clsx(classes.textAreaContainer, { [classes.isTextareaFocused]: isTextareaFocused })}>
{/*
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
*/}
<TextareaAutosize
rowsMin={1}
rowsMax={3}
className={classes.textArea}
aria-label="chat input"
placeholder="Write a message..."
onKeyPress={handleReturnKeyPress}
onChange={handleChange}
value={messageBody}
data-cy-chat-input
ref={textInputRef}
onFocus={() => setIsTextareaFocused(true)}
onBlur={() => setIsTextareaFocused(false)}
/>
</div>

<Grid container alignItems="flex-end" justify="flex-end" wrap="nowrap">
{/* Since the file input element is invisible, we can hardcode an empty string as its value.
Expand Down
3 changes: 2 additions & 1 deletion src/components/ChatWindow/ChatWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -20,6 +20,7 @@ const useStyles = makeStyles((theme: Theme) =>
left: 0,
bottom: 0,
right: 0,
zIndex: 100,
},
},
hide: {
Expand Down

0 comments on commit 85be841

Please sign in to comment.