@patternfly/chatbot 2.2.0-prerelease.20 → 2.2.0-prerelease.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Message/Message.d.ts +3 -0
- package/dist/cjs/Message/Message.js +22 -5
- package/dist/cjs/Message/Message.test.js +94 -0
- package/dist/cjs/Message/TableMessage/TableMessage.d.ts +20 -0
- package/dist/cjs/Message/TableMessage/TableMessage.js +67 -0
- package/dist/cjs/Message/TableMessage/TbodyMessage.d.ts +7 -0
- package/dist/cjs/Message/TableMessage/TbodyMessage.js +33 -0
- package/dist/cjs/Message/TableMessage/TdMessage.d.ts +5 -0
- package/dist/cjs/Message/TableMessage/TdMessage.js +26 -0
- package/dist/cjs/Message/TableMessage/ThMessage.d.ts +5 -0
- package/dist/cjs/Message/TableMessage/ThMessage.js +26 -0
- package/dist/cjs/Message/TableMessage/TheadMessage.d.ts +5 -0
- package/dist/cjs/Message/TableMessage/TheadMessage.js +26 -0
- package/dist/cjs/Message/TableMessage/TrMessage.d.ts +7 -0
- package/dist/cjs/Message/TableMessage/TrMessage.js +37 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +4 -1
- package/dist/cjs/MessageBar/MessageBar.js +125 -39
- package/dist/css/main.css +59 -17
- package/dist/css/main.css.map +1 -1
- package/dist/esm/Message/Message.d.ts +3 -0
- package/dist/esm/Message/Message.js +22 -5
- package/dist/esm/Message/Message.test.js +94 -0
- package/dist/esm/Message/TableMessage/TableMessage.d.ts +20 -0
- package/dist/esm/Message/TableMessage/TableMessage.js +62 -0
- package/dist/esm/Message/TableMessage/TbodyMessage.d.ts +7 -0
- package/dist/esm/Message/TableMessage/TbodyMessage.js +28 -0
- package/dist/esm/Message/TableMessage/TdMessage.d.ts +5 -0
- package/dist/esm/Message/TableMessage/TdMessage.js +21 -0
- package/dist/esm/Message/TableMessage/ThMessage.d.ts +5 -0
- package/dist/esm/Message/TableMessage/ThMessage.js +21 -0
- package/dist/esm/Message/TableMessage/TheadMessage.d.ts +5 -0
- package/dist/esm/Message/TableMessage/TheadMessage.js +21 -0
- package/dist/esm/Message/TableMessage/TrMessage.d.ts +7 -0
- package/dist/esm/Message/TableMessage/TrMessage.js +32 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +4 -1
- package/dist/esm/MessageBar/MessageBar.js +125 -39
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +27 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +27 -1
- package/src/Message/Message.test.tsx +99 -0
- package/src/Message/Message.tsx +25 -4
- package/src/Message/TableMessage/TableMessage.scss +23 -0
- package/src/Message/TableMessage/TableMessage.tsx +83 -0
- package/src/Message/TableMessage/TbodyMessage.tsx +20 -0
- package/src/Message/TableMessage/TdMessage.tsx +11 -0
- package/src/Message/TableMessage/ThMessage.tsx +11 -0
- package/src/Message/TableMessage/TheadMessage.tsx +11 -0
- package/src/Message/TableMessage/TrMessage.tsx +27 -0
- package/src/Message/TextMessage/TextMessage.scss +5 -0
- package/src/MessageBar/MessageBar.scss +35 -18
- package/src/MessageBar/MessageBar.tsx +144 -53
- package/src/main.scss +1 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { ButtonProps, DropEvent } from '@patternfly/react-core';
|
2
|
+
import { ButtonProps, DropEvent, TextArea } from '@patternfly/react-core';
|
3
3
|
|
4
4
|
// Import Chatbot components
|
5
5
|
import SendButton from './SendButton';
|
@@ -7,7 +7,7 @@ import MicrophoneButton from './MicrophoneButton';
|
|
7
7
|
import { AttachButton } from './AttachButton';
|
8
8
|
import AttachMenu from '../AttachMenu';
|
9
9
|
import StopButton from './StopButton';
|
10
|
-
import
|
10
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
11
11
|
|
12
12
|
export interface MessageBarWithAttachMenuProps {
|
13
13
|
/** Flag to enable whether attach menu is open */
|
@@ -63,7 +63,9 @@ export interface MessageBarProps {
|
|
63
63
|
};
|
64
64
|
};
|
65
65
|
/** A callback for when the text area value changes. */
|
66
|
-
onChange?: (event: React.ChangeEvent<
|
66
|
+
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
|
67
|
+
/** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
|
68
|
+
displayMode?: ChatbotDisplayMode;
|
67
69
|
}
|
68
70
|
|
69
71
|
export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
@@ -79,46 +81,148 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
|
79
81
|
hasStopButton,
|
80
82
|
buttonProps,
|
81
83
|
onChange,
|
84
|
+
displayMode,
|
82
85
|
...props
|
83
86
|
}: MessageBarProps) => {
|
84
87
|
// Text Input
|
85
88
|
// --------------------------------------------------------------------------
|
86
89
|
const [message, setMessage] = React.useState<string>('');
|
87
90
|
const [isListeningMessage, setIsListeningMessage] = React.useState<boolean>(false);
|
88
|
-
const [
|
89
|
-
const textareaRef = React.useRef<
|
91
|
+
const [hasSentMessage, setHasSentMessage] = React.useState(false);
|
92
|
+
const textareaRef = React.useRef<HTMLTextAreaElement>(null);
|
90
93
|
const attachButtonRef = React.useRef<HTMLButtonElement>(null);
|
91
94
|
|
92
|
-
const
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
let newMessage = messageText;
|
104
|
-
if (event.target.innerText) {
|
105
|
-
newMessage = DOMPurify.sanitize(event.target.innerText);
|
95
|
+
const setInitialLineHeight = (field: HTMLTextAreaElement) => {
|
96
|
+
field.style.setProperty('line-height', '1rem');
|
97
|
+
const parent = field.parentElement;
|
98
|
+
if (parent) {
|
99
|
+
parent.style.setProperty('margin-top', `1rem`);
|
100
|
+
parent.style.setProperty('margin-bottom', `0rem`);
|
101
|
+
parent.style.setProperty('height', 'inherit');
|
102
|
+
|
103
|
+
const grandparent = parent.parentElement;
|
104
|
+
if (grandparent) {
|
105
|
+
grandparent.style.setProperty('flex-basis', 'auto');
|
106
106
|
}
|
107
|
-
setMessage(newMessage);
|
108
|
-
onChange && onChange(event, newMessage);
|
109
107
|
}
|
110
108
|
};
|
111
109
|
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
const setAutoHeight = (field: HTMLTextAreaElement) => {
|
111
|
+
const parent = field.parentElement;
|
112
|
+
if (parent) {
|
113
|
+
parent.style.setProperty('height', 'inherit');
|
114
|
+
const computed = window.getComputedStyle(field);
|
115
|
+
// Calculate the height
|
116
|
+
const height =
|
117
|
+
parseInt(computed.getPropertyValue('border-top-width')) +
|
118
|
+
parseInt(computed.getPropertyValue('padding-top')) +
|
119
|
+
field.scrollHeight +
|
120
|
+
parseInt(computed.getPropertyValue('padding-bottom')) +
|
121
|
+
parseInt(computed.getPropertyValue('border-bottom-width'));
|
122
|
+
parent.style.setProperty('height', `${height}px`);
|
123
|
+
|
124
|
+
if (height > 32 || window.innerWidth <= 507) {
|
125
|
+
parent.style.setProperty('margin-bottom', `1rem`);
|
126
|
+
parent.style.setProperty('margin-top', `1rem`);
|
127
|
+
}
|
128
|
+
}
|
129
|
+
};
|
130
|
+
|
131
|
+
const textIsLongerThan2Lines = (field: HTMLTextAreaElement) => {
|
132
|
+
const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
|
133
|
+
const lines = field.scrollHeight / lineHeight;
|
134
|
+
return lines > 2;
|
135
|
+
};
|
136
|
+
|
137
|
+
const setAutoWidth = (field: HTMLTextAreaElement) => {
|
138
|
+
const parent = field.parentElement;
|
139
|
+
if (parent) {
|
140
|
+
const grandparent = parent.parentElement;
|
141
|
+
if (textIsLongerThan2Lines(field) && grandparent) {
|
142
|
+
grandparent.style.setProperty('flex-basis', `100%`);
|
143
|
+
}
|
144
|
+
}
|
145
|
+
};
|
146
|
+
|
147
|
+
const handleNewLine = (field: HTMLTextAreaElement) => {
|
148
|
+
const parent = field.parentElement;
|
149
|
+
if (parent) {
|
150
|
+
parent.style.setProperty('margin-bottom', `1rem`);
|
151
|
+
parent.style.setProperty('margin-top', `1rem`);
|
152
|
+
}
|
153
|
+
};
|
154
|
+
|
155
|
+
React.useEffect(() => {
|
156
|
+
const field = textareaRef.current;
|
157
|
+
if (field) {
|
158
|
+
if (field.value === '') {
|
159
|
+
if (window.innerWidth > 507) {
|
160
|
+
setInitialLineHeight(field);
|
161
|
+
}
|
162
|
+
} else {
|
163
|
+
setAutoHeight(field);
|
164
|
+
setAutoWidth(field);
|
165
|
+
}
|
166
|
+
}
|
167
|
+
const resetHeight = () => {
|
168
|
+
if (field) {
|
169
|
+
if (field.value === '') {
|
170
|
+
if (window.innerWidth > 507) {
|
171
|
+
setInitialLineHeight(field);
|
172
|
+
}
|
173
|
+
} else {
|
174
|
+
setAutoHeight(field);
|
175
|
+
setAutoWidth(field);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
};
|
179
|
+
window.addEventListener('resize', resetHeight);
|
180
|
+
|
181
|
+
return () => {
|
182
|
+
window.removeEventListener('resize', resetHeight);
|
183
|
+
};
|
184
|
+
}, []);
|
185
|
+
|
186
|
+
React.useEffect(() => {
|
187
|
+
const field = textareaRef.current;
|
188
|
+
if (field) {
|
189
|
+
if (field.value === '') {
|
190
|
+
setInitialLineHeight(textareaRef.current);
|
191
|
+
} else {
|
192
|
+
setAutoHeight(textareaRef.current);
|
193
|
+
setAutoWidth(field);
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}, [displayMode, message]);
|
197
|
+
|
198
|
+
React.useEffect(() => {
|
199
|
+
const field = textareaRef.current;
|
200
|
+
if (field) {
|
201
|
+
setInitialLineHeight(field);
|
202
|
+
setHasSentMessage(false);
|
203
|
+
}
|
204
|
+
}, [hasSentMessage]);
|
205
|
+
|
206
|
+
const handleChange = React.useCallback((event) => {
|
207
|
+
onChange && onChange(event, event.target.value);
|
115
208
|
if (textareaRef.current) {
|
116
|
-
|
117
|
-
|
118
|
-
|
209
|
+
if (event.target.value === '') {
|
210
|
+
setInitialLineHeight(textareaRef.current);
|
211
|
+
} else {
|
212
|
+
setAutoHeight(textareaRef.current);
|
213
|
+
}
|
119
214
|
}
|
120
|
-
setMessage(
|
121
|
-
}, [
|
215
|
+
setMessage(event.target.value);
|
216
|
+
}, []);
|
217
|
+
|
218
|
+
// Handle sending message
|
219
|
+
const handleSend = React.useCallback(() => {
|
220
|
+
setMessage((m) => {
|
221
|
+
onSendMessage(m);
|
222
|
+
setHasSentMessage(true);
|
223
|
+
return '';
|
224
|
+
});
|
225
|
+
}, [onSendMessage]);
|
122
226
|
|
123
227
|
const handleKeyDown = React.useCallback(
|
124
228
|
(event: React.KeyboardEvent) => {
|
@@ -128,6 +232,11 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
|
128
232
|
handleSend();
|
129
233
|
}
|
130
234
|
}
|
235
|
+
if (event.key === 'Enter' && event.shiftKey) {
|
236
|
+
if (textareaRef.current) {
|
237
|
+
handleNewLine(textareaRef.current);
|
238
|
+
}
|
239
|
+
}
|
131
240
|
},
|
132
241
|
[handleSend, isSendButtonDisabled, handleStopButton]
|
133
242
|
);
|
@@ -139,12 +248,7 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
|
139
248
|
|
140
249
|
const handleSpeechRecognition = (message) => {
|
141
250
|
setMessage(message);
|
142
|
-
|
143
|
-
if (textarea) {
|
144
|
-
textarea.focus();
|
145
|
-
textarea.textContent = DOMPurify.sanitize(message);
|
146
|
-
}
|
147
|
-
onChange && onChange({} as React.ChangeEvent<HTMLDivElement>, message);
|
251
|
+
onChange && onChange({} as React.ChangeEvent<HTMLTextAreaElement>, message);
|
148
252
|
};
|
149
253
|
|
150
254
|
const renderButtons = () => {
|
@@ -200,28 +304,15 @@ export const MessageBar: React.FunctionComponent<MessageBarProps> = ({
|
|
200
304
|
);
|
201
305
|
};
|
202
306
|
|
203
|
-
const placeholder = isListeningMessage ? 'Listening' : 'Send a message...';
|
204
|
-
|
205
307
|
const messageBarContents = (
|
206
308
|
<>
|
207
309
|
<div className="pf-chatbot__message-bar-input">
|
208
|
-
|
209
|
-
<div className="pf-chatbot__message-bar-placeholder">{placeholder}</div>
|
210
|
-
)}
|
211
|
-
<div
|
212
|
-
contentEditable
|
213
|
-
suppressContentEditableWarning={true}
|
214
|
-
role="textbox"
|
215
|
-
aria-multiline="false"
|
310
|
+
<TextArea
|
216
311
|
className="pf-chatbot__message-textarea"
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
setShowPlaceholder(!showPlaceholder);
|
222
|
-
}
|
223
|
-
}}
|
224
|
-
aria-label={placeholder}
|
312
|
+
value={message}
|
313
|
+
onChange={handleChange}
|
314
|
+
aria-label={isListeningMessage ? 'Listening' : 'Send a message...'}
|
315
|
+
placeholder={isListeningMessage ? 'Listening' : 'Send a message...'}
|
225
316
|
ref={textareaRef}
|
226
317
|
onKeyDown={handleKeyDown}
|
227
318
|
{...props}
|
package/src/main.scss
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
@import './Message/CodeBlockMessage/CodeBlockMessage';
|
19
19
|
@import './Message/TextMessage/TextMessage';
|
20
20
|
@import './Message/ListMessage/ListMessage';
|
21
|
+
@import './Message/TableMessage/TableMessage';
|
21
22
|
@import './Message/MessageLoading';
|
22
23
|
@import './Message/QuickStarts/QuickStartTile';
|
23
24
|
@import './Message/QuickResponse/QuickResponse';
|