Skip to content

Commit a6ee9a5

Browse files
committed
Add horizontal resizing
1 parent b7fef89 commit a6ee9a5

File tree

2 files changed

+83
-41
lines changed

2 files changed

+83
-41
lines changed

packages/module/src/MessageBar/MessageBar.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,10 @@
7070
outline: none;
7171
}
7272
}
73+
74+
@media screen and (max-width: 359px) {
75+
.pf-chatbot__message-textarea {
76+
margin-top: var(--pf-t--global--spacer--md) !important;
77+
margin-bottom: var(--pf-t--global--spacer--md) !important;
78+
}
79+
}

packages/module/src/MessageBar/MessageBar.tsx

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React from 'react';
2-
import { DropEvent, TextArea, TextAreaProps, TextInput } from '@patternfly/react-core';
3-
import { AutoTextArea } from 'react-textarea-auto-witdth-height';
2+
import { DropEvent, TextArea, TextAreaProps } from '@patternfly/react-core';
43

54
// Import Chatbot components
65
import SendButton from './SendButton';
76
import MicrophoneButton from './MicrophoneButton';
87
import { AttachButton } from './AttachButton';
98
import AttachMenu from '../AttachMenu';
9+
import { ChatbotDisplayMode } from '../Chatbot';
1010

1111
export interface MessageBarWithAttachMenuProps {
1212
/** Flag to enable whether attach menu is open */
@@ -46,6 +46,8 @@ export interface MessageBarProps extends TextAreaProps {
4646
attachMenuProps?: MessageBarWithAttachMenuProps;
4747
/** Flag to provide manual control over whether send button is disabled */
4848
isSendButtonDisabled?: boolean;
49+
/** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
50+
displayMode?: ChatbotDisplayMode;
4951
}
5052

5153
export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
@@ -57,15 +59,14 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
5759
handleAttach,
5860
attachMenuProps,
5961
isSendButtonDisabled,
62+
displayMode,
6063
...props
6164
}: MessageBarProps) => {
6265
// Text Input
6366
// --------------------------------------------------------------------------
6467
const [message, setMessage] = React.useState<string>('');
6568
const [isListeningMessage, setIsListeningMessage] = React.useState<boolean>(false);
66-
const [height, setHeight] = React.useState<number>();
6769
const [hasSentMessage, setHasSentMessage] = React.useState(false);
68-
6970
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
7071
const attachButtonRef = React.useRef<HTMLButtonElement>(null);
7172

@@ -75,6 +76,11 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
7576
if (parent) {
7677
parent.style.setProperty('margin-top', `0rem`);
7778
parent.style.setProperty('margin-bottom', `0rem`);
79+
80+
const grandparent = parent.parentElement;
81+
if (grandparent) {
82+
grandparent.style.setProperty('flex-basis', 'auto');
83+
}
7884
}
7985
};
8086

@@ -92,25 +98,34 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
9298
parseInt(computed.getPropertyValue('border-bottom-width'));
9399
parent.style.setProperty('height', `${height}px`);
94100

95-
if (height > 32 || window.innerWidth <= 359) {
101+
if (height > 32 || window.innerWidth <= 466) {
96102
parent.style.setProperty('margin-bottom', `1rem`);
97103
parent.style.setProperty('margin-top', `1rem`);
98104
}
105+
}
106+
};
99107

100-
setHeight(height);
108+
const textIsLongerThan2Lines = (field: HTMLTextAreaElement) => {
109+
const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
110+
const lines = field.scrollHeight / lineHeight;
111+
return lines > 2;
112+
};
113+
114+
const setAutoWidth = (field: HTMLTextAreaElement) => {
115+
const parent = field.parentElement;
116+
if (parent) {
117+
const grandparent = parent.parentElement;
118+
if (textIsLongerThan2Lines(field) && grandparent) {
119+
grandparent.style.setProperty('flex-basis', `100%`);
120+
}
101121
}
102122
};
103123

104124
const handleNewLine = (field: HTMLTextAreaElement) => {
105125
const parent = field.parentElement;
106-
const oldHeight = height ?? 0;
107126
if (parent) {
108-
if (oldHeight === 0) {
109-
parent.style.setProperty('margin-bottom', `1rem`);
110-
parent.style.setProperty('margin-top', `1rem`);
111-
} else {
112-
parent.style.setProperty('height', `${oldHeight + 16}px`);
113-
}
127+
parent.style.setProperty('margin-bottom', `1rem`);
128+
parent.style.setProperty('margin-top', `1rem`);
114129
}
115130
};
116131

@@ -125,26 +140,68 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
125140
React.useEffect(() => {
126141
const field = textareaRef.current;
127142
if (field) {
128-
setInitialLineHeight(field);
129-
setAutoHeight(field);
143+
if (field.value === '') {
144+
if (window.innerWidth > 467) {
145+
setInitialLineHeight(field);
146+
} else {
147+
handleMobileHeight(field);
148+
}
149+
} else {
150+
setAutoHeight(field);
151+
setAutoWidth(field);
152+
}
130153
}
154+
const resetHeight = () => {
155+
if (field) {
156+
if (field.value === '') {
157+
if (window.innerWidth > 467) {
158+
setInitialLineHeight(field);
159+
} else {
160+
handleMobileHeight(field);
161+
}
162+
} else {
163+
setAutoHeight(field);
164+
setAutoWidth(field);
165+
}
166+
}
167+
};
168+
window.addEventListener('resize', resetHeight);
169+
170+
return () => {
171+
window.removeEventListener('resize', resetHeight);
172+
};
131173
}, []);
132174

133175
React.useEffect(() => {
134176
const field = textareaRef.current;
135177
if (field) {
136-
setInitialLineHeight(field);
137-
setAutoHeight(field);
178+
if (field.value === '') {
179+
setInitialLineHeight(textareaRef.current);
180+
} else {
181+
setAutoHeight(textareaRef.current);
182+
}
183+
}
184+
}, [displayMode, message]);
185+
186+
React.useEffect(() => {
187+
const field = textareaRef.current;
188+
if (field) {
189+
if (field.value === '') {
190+
setInitialLineHeight(field);
191+
} else {
192+
setAutoHeight(field);
193+
}
194+
setHasSentMessage(false);
138195
}
139-
setHasSentMessage(false);
140196
}, [hasSentMessage]);
141197

142198
const handleChange = React.useCallback((event) => {
143199
if (textareaRef.current) {
144200
if (event.target.value === '') {
145201
setInitialLineHeight(textareaRef.current);
202+
} else {
203+
setAutoHeight(textareaRef.current);
146204
}
147-
setAutoHeight(textareaRef.current);
148205
}
149206
setMessage(event.target.value);
150207
}, []);
@@ -158,13 +215,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
158215
});
159216
}, [onSendMessage]);
160217

161-
// want to exclude things like delete, shift, etc.
162-
const isTypeableKey = (key) => {
163-
if (key.length > 1) {
164-
return false;
165-
}
166-
return true;
167-
};
168218
const handleKeyDown = React.useCallback(
169219
(event) => {
170220
if (event.key === 'Enter' && !event.shiftKey) {
@@ -178,11 +228,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
178228
handleNewLine(textareaRef.current);
179229
}
180230
}
181-
if (window.innerWidth <= 411 && isTypeableKey(event.key)) {
182-
if (textareaRef.current) {
183-
handleMobileHeight(textareaRef.current);
184-
}
185-
}
186231
},
187232
[handleSend]
188233
);
@@ -195,16 +240,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
195240
const messageBarContents = (
196241
<>
197242
<div className="pf-chatbot__message-bar-input">
198-
{/* <AutoTextArea
199-
ref={textareaRef}
200-
className="pf-chatbot__message-textarea"
201-
value={message as any} // Added any to make the third part TextArea component types happy. Remove when replced with PF TextArea
202-
onChange={handleChange as any} // Added any to make the third part TextArea component types happy. Remove when replced with PF TextArea
203-
onKeyDown={handleKeyDown}
204-
placeholder={isListeningMessage ? 'Listening' : 'Send a message...'}
205-
aria-label={isListeningMessage ? 'Listening' : 'Send a message...'}
206-
{...props}
207-
/>*/}
208243
<TextArea
209244
className="pf-chatbot__message-textarea"
210245
value={message}

0 commit comments

Comments
 (0)