Skip to content

Commit c76039f

Browse files
committed
Add horizontal resizing
1 parent 44bfe49 commit c76039f

File tree

2 files changed

+83
-39
lines changed

2 files changed

+83
-39
lines changed

packages/module/src/MessageBar/MessageBar.scss

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

packages/module/src/MessageBar/MessageBar.tsx

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import MicrophoneButton from './MicrophoneButton';
77
import { AttachButton } from './AttachButton';
88
import AttachMenu from '../AttachMenu';
99
import StopButton from './StopButton';
10+
import { ChatbotDisplayMode } from '../Chatbot';
1011

1112
export interface MessageBarWithAttachMenuProps {
1213
/** Flag to enable whether attach menu is open */
@@ -62,6 +63,8 @@ export interface MessageBarProps extends TextAreaProps {
6263
};
6364
/** A callback for when the text area value changes. */
6465
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
66+
/** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
67+
displayMode?: ChatbotDisplayMode;
6568
}
6669

6770
export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
@@ -77,15 +80,14 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
7780
hasStopButton,
7881
buttonProps,
7982
onChange,
83+
displayMode,
8084
...props
8185
}: MessageBarProps) => {
8286
// Text Input
8387
// --------------------------------------------------------------------------
8488
const [message, setMessage] = React.useState<string>('');
8589
const [isListeningMessage, setIsListeningMessage] = React.useState<boolean>(false);
86-
const [height, setHeight] = React.useState<number>();
8790
const [hasSentMessage, setHasSentMessage] = React.useState(false);
88-
8991
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
9092
const attachButtonRef = React.useRef<HTMLButtonElement>(null);
9193

@@ -95,6 +97,11 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
9597
if (parent) {
9698
parent.style.setProperty('margin-top', `0rem`);
9799
parent.style.setProperty('margin-bottom', `0rem`);
100+
101+
const grandparent = parent.parentElement;
102+
if (grandparent) {
103+
grandparent.style.setProperty('flex-basis', 'auto');
104+
}
98105
}
99106
};
100107

@@ -112,25 +119,34 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
112119
parseInt(computed.getPropertyValue('border-bottom-width'));
113120
parent.style.setProperty('height', `${height}px`);
114121

115-
if (height > 32 || window.innerWidth <= 359) {
122+
if (height > 32 || window.innerWidth <= 466) {
116123
parent.style.setProperty('margin-bottom', `1rem`);
117124
parent.style.setProperty('margin-top', `1rem`);
118125
}
126+
}
127+
};
128+
129+
const textIsLongerThan2Lines = (field: HTMLTextAreaElement) => {
130+
const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
131+
const lines = field.scrollHeight / lineHeight;
132+
return lines > 2;
133+
};
119134

120-
setHeight(height);
135+
const setAutoWidth = (field: HTMLTextAreaElement) => {
136+
const parent = field.parentElement;
137+
if (parent) {
138+
const grandparent = parent.parentElement;
139+
if (textIsLongerThan2Lines(field) && grandparent) {
140+
grandparent.style.setProperty('flex-basis', `100%`);
141+
}
121142
}
122143
};
123144

124145
const handleNewLine = (field: HTMLTextAreaElement) => {
125146
const parent = field.parentElement;
126-
const oldHeight = height ?? 0;
127147
if (parent) {
128-
if (oldHeight === 0) {
129-
parent.style.setProperty('margin-bottom', `1rem`);
130-
parent.style.setProperty('margin-top', `1rem`);
131-
} else {
132-
parent.style.setProperty('height', `${oldHeight + 16}px`);
133-
}
148+
parent.style.setProperty('margin-bottom', `1rem`);
149+
parent.style.setProperty('margin-top', `1rem`);
134150
}
135151
};
136152

@@ -145,27 +161,70 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
145161
React.useEffect(() => {
146162
const field = textareaRef.current;
147163
if (field) {
148-
setInitialLineHeight(field);
149-
setAutoHeight(field);
164+
if (field.value === '') {
165+
if (window.innerWidth > 467) {
166+
setInitialLineHeight(field);
167+
} else {
168+
handleMobileHeight(field);
169+
}
170+
} else {
171+
setAutoHeight(field);
172+
setAutoWidth(field);
173+
}
150174
}
175+
const resetHeight = () => {
176+
if (field) {
177+
if (field.value === '') {
178+
if (window.innerWidth > 467) {
179+
setInitialLineHeight(field);
180+
} else {
181+
handleMobileHeight(field);
182+
}
183+
} else {
184+
setAutoHeight(field);
185+
setAutoWidth(field);
186+
}
187+
}
188+
};
189+
window.addEventListener('resize', resetHeight);
190+
191+
return () => {
192+
window.removeEventListener('resize', resetHeight);
193+
};
151194
}, []);
152195

153196
React.useEffect(() => {
154197
const field = textareaRef.current;
155198
if (field) {
156-
setInitialLineHeight(field);
157-
setAutoHeight(field);
199+
if (field.value === '') {
200+
setInitialLineHeight(textareaRef.current);
201+
} else {
202+
setAutoHeight(textareaRef.current);
203+
setAutoWidth(field);
204+
}
205+
}
206+
}, [displayMode, message]);
207+
208+
React.useEffect(() => {
209+
const field = textareaRef.current;
210+
if (field) {
211+
if (field.value === '') {
212+
setInitialLineHeight(field);
213+
} else {
214+
setAutoHeight(field);
215+
}
216+
setHasSentMessage(false);
158217
}
159-
setHasSentMessage(false);
160218
}, [hasSentMessage]);
161219

162220
const handleChange = React.useCallback((event) => {
163221
onChange && onChange(event, event.target.value);
164222
if (textareaRef.current) {
165223
if (event.target.value === '') {
166224
setInitialLineHeight(textareaRef.current);
225+
} else {
226+
setAutoHeight(textareaRef.current);
167227
}
168-
setAutoHeight(textareaRef.current);
169228
}
170229
setMessage(event.target.value);
171230
}, []);
@@ -179,13 +238,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
179238
});
180239
}, [onSendMessage]);
181240

182-
// want to exclude things like delete, shift, etc.
183-
const isTypeableKey = (key) => {
184-
if (key.length > 1) {
185-
return false;
186-
}
187-
return true;
188-
};
189241
const handleKeyDown = React.useCallback(
190242
(event: React.KeyboardEvent) => {
191243
if (event.key === 'Enter' && !event.shiftKey) {
@@ -199,11 +251,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
199251
handleNewLine(textareaRef.current);
200252
}
201253
}
202-
if (window.innerWidth <= 411 && isTypeableKey(event.key)) {
203-
if (textareaRef.current) {
204-
handleMobileHeight(textareaRef.current);
205-
}
206-
}
207254
},
208255
[handleSend]
209256
);
@@ -268,16 +315,6 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
268315
const messageBarContents = (
269316
<>
270317
<div className="pf-chatbot__message-bar-input">
271-
{/* <AutoTextArea
272-
ref={textareaRef}
273-
className="pf-chatbot__message-textarea"
274-
value={message as any} // Added any to make the third part TextArea component types happy. Remove when replced with PF TextArea
275-
onChange={handleChange as any} // Added any to make the third part TextArea component types happy. Remove when replced with PF TextArea
276-
onKeyDown={handleKeyDown}
277-
placeholder={isListeningMessage ? 'Listening' : 'Send a message...'}
278-
aria-label={isListeningMessage ? 'Listening' : 'Send a message...'}
279-
{...props}
280-
/>*/}
281318
<TextArea
282319
className="pf-chatbot__message-textarea"
283320
value={message}

0 commit comments

Comments
 (0)