@patternfly/chatbot 2.2.0-prerelease.21 → 2.2.0-prerelease.23

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.
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ButtonProps, DropEvent } from '@patternfly/react-core';
3
+ import { ChatbotDisplayMode } from '../Chatbot';
3
4
  export interface MessageBarWithAttachMenuProps {
4
5
  /** Flag to enable whether attach menu is open */
5
6
  isAttachMenuOpen: boolean;
@@ -66,7 +67,9 @@ export interface MessageBarProps {
66
67
  };
67
68
  };
68
69
  /** A callback for when the text area value changes. */
69
- onChange?: (event: React.ChangeEvent<HTMLDivElement>, value: string) => void;
70
+ onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
71
+ /** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
72
+ displayMode?: ChatbotDisplayMode;
70
73
  }
71
74
  export declare const MessageBar: React.FunctionComponent<MessageBarProps>;
72
75
  export default MessageBar;
@@ -16,52 +16,144 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.MessageBar = void 0;
18
18
  const react_1 = __importDefault(require("react"));
19
+ const react_core_1 = require("@patternfly/react-core");
19
20
  // Import Chatbot components
20
21
  const SendButton_1 = __importDefault(require("./SendButton"));
21
22
  const MicrophoneButton_1 = __importDefault(require("./MicrophoneButton"));
22
23
  const AttachButton_1 = require("./AttachButton");
23
24
  const AttachMenu_1 = __importDefault(require("../AttachMenu"));
24
25
  const StopButton_1 = __importDefault(require("./StopButton"));
25
- const dompurify_1 = __importDefault(require("dompurify"));
26
26
  const MessageBar = (_a) => {
27
- var { onSendMessage, className, alwayShowSendButton, hasAttachButton = true, hasMicrophoneButton, handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "hasAttachButton", "hasMicrophoneButton", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange"]);
27
+ var { onSendMessage, className, alwayShowSendButton, hasAttachButton = true, hasMicrophoneButton, handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "hasAttachButton", "hasMicrophoneButton", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode"]);
28
28
  // Text Input
29
29
  // --------------------------------------------------------------------------
30
30
  const [message, setMessage] = react_1.default.useState('');
31
31
  const [isListeningMessage, setIsListeningMessage] = react_1.default.useState(false);
32
- const [showPlaceholder, setShowPlaceholder] = react_1.default.useState(true);
32
+ const [hasSentMessage, setHasSentMessage] = react_1.default.useState(false);
33
33
  const textareaRef = react_1.default.useRef(null);
34
34
  const attachButtonRef = react_1.default.useRef(null);
35
- const handleInput = (event) => {
36
- // newMessage === '' doesn't work unless we trim, which causes other problems
37
- // textContent seems to work, but doesn't allow for markdown, so we need both
38
- const messageText = dompurify_1.default.sanitize(event.target.textContent);
39
- if (messageText === '') {
40
- setShowPlaceholder(true);
41
- setMessage('');
42
- onChange && onChange(event, '');
35
+ const setInitialLineHeight = (field) => {
36
+ field.style.setProperty('line-height', '1rem');
37
+ const parent = field.parentElement;
38
+ if (parent) {
39
+ parent.style.setProperty('margin-top', `1rem`);
40
+ parent.style.setProperty('margin-bottom', `0rem`);
41
+ parent.style.setProperty('height', 'inherit');
42
+ const grandparent = parent.parentElement;
43
+ if (grandparent) {
44
+ grandparent.style.setProperty('flex-basis', 'auto');
45
+ }
43
46
  }
44
- else {
45
- setShowPlaceholder(false);
46
- // this is so that tests work; RTL doesn't seem to like event.target.innerText, but browsers don't pick up markdown without it
47
- let newMessage = messageText;
48
- if (event.target.innerText) {
49
- newMessage = dompurify_1.default.sanitize(event.target.innerText);
47
+ };
48
+ const setAutoHeight = (field) => {
49
+ const parent = field.parentElement;
50
+ if (parent) {
51
+ parent.style.setProperty('height', 'inherit');
52
+ const computed = window.getComputedStyle(field);
53
+ // Calculate the height
54
+ const height = parseInt(computed.getPropertyValue('border-top-width')) +
55
+ parseInt(computed.getPropertyValue('padding-top')) +
56
+ field.scrollHeight +
57
+ parseInt(computed.getPropertyValue('padding-bottom')) +
58
+ parseInt(computed.getPropertyValue('border-bottom-width'));
59
+ parent.style.setProperty('height', `${height}px`);
60
+ if (height > 32 || window.innerWidth <= 507) {
61
+ parent.style.setProperty('margin-bottom', `1rem`);
62
+ parent.style.setProperty('margin-top', `1rem`);
50
63
  }
51
- setMessage(newMessage);
52
- onChange && onChange(event, newMessage);
53
64
  }
54
65
  };
55
- // Handle sending message
56
- const handleSend = react_1.default.useCallback(() => {
57
- onSendMessage(message);
66
+ const textIsLongerThan2Lines = (field) => {
67
+ const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
68
+ const lines = field.scrollHeight / lineHeight;
69
+ return lines > 2;
70
+ };
71
+ const setAutoWidth = (field) => {
72
+ const parent = field.parentElement;
73
+ if (parent) {
74
+ const grandparent = parent.parentElement;
75
+ if (textIsLongerThan2Lines(field) && grandparent) {
76
+ grandparent.style.setProperty('flex-basis', `100%`);
77
+ }
78
+ }
79
+ };
80
+ const handleNewLine = (field) => {
81
+ const parent = field.parentElement;
82
+ if (parent) {
83
+ parent.style.setProperty('margin-bottom', `1rem`);
84
+ parent.style.setProperty('margin-top', `1rem`);
85
+ }
86
+ };
87
+ react_1.default.useEffect(() => {
88
+ const field = textareaRef.current;
89
+ if (field) {
90
+ if (field.value === '') {
91
+ if (window.innerWidth > 507) {
92
+ setInitialLineHeight(field);
93
+ }
94
+ }
95
+ else {
96
+ setAutoHeight(field);
97
+ setAutoWidth(field);
98
+ }
99
+ }
100
+ const resetHeight = () => {
101
+ if (field) {
102
+ if (field.value === '') {
103
+ if (window.innerWidth > 507) {
104
+ setInitialLineHeight(field);
105
+ }
106
+ }
107
+ else {
108
+ setAutoHeight(field);
109
+ setAutoWidth(field);
110
+ }
111
+ }
112
+ };
113
+ window.addEventListener('resize', resetHeight);
114
+ return () => {
115
+ window.removeEventListener('resize', resetHeight);
116
+ };
117
+ }, []);
118
+ react_1.default.useEffect(() => {
119
+ const field = textareaRef.current;
120
+ if (field) {
121
+ if (field.value === '') {
122
+ setInitialLineHeight(textareaRef.current);
123
+ }
124
+ else {
125
+ setAutoHeight(textareaRef.current);
126
+ setAutoWidth(field);
127
+ }
128
+ }
129
+ }, [displayMode, message]);
130
+ react_1.default.useEffect(() => {
131
+ const field = textareaRef.current;
132
+ if (field) {
133
+ setInitialLineHeight(field);
134
+ setHasSentMessage(false);
135
+ }
136
+ }, [hasSentMessage]);
137
+ const handleChange = react_1.default.useCallback((event) => {
138
+ onChange && onChange(event, event.target.value);
58
139
  if (textareaRef.current) {
59
- textareaRef.current.innerText = '';
60
- setShowPlaceholder(true);
61
- textareaRef.current.blur();
140
+ if (event.target.value === '') {
141
+ setInitialLineHeight(textareaRef.current);
142
+ }
143
+ else {
144
+ setAutoHeight(textareaRef.current);
145
+ }
62
146
  }
63
- setMessage('');
64
- }, [onSendMessage, message]);
147
+ setMessage(event.target.value);
148
+ }, []);
149
+ // Handle sending message
150
+ const handleSend = react_1.default.useCallback(() => {
151
+ setMessage((m) => {
152
+ onSendMessage(m);
153
+ setHasSentMessage(true);
154
+ return '';
155
+ });
156
+ }, [onSendMessage]);
65
157
  const handleKeyDown = react_1.default.useCallback((event) => {
66
158
  if (event.key === 'Enter' && !event.shiftKey) {
67
159
  event.preventDefault();
@@ -69,6 +161,11 @@ const MessageBar = (_a) => {
69
161
  handleSend();
70
162
  }
71
163
  }
164
+ if (event.key === 'Enter' && event.shiftKey) {
165
+ if (textareaRef.current) {
166
+ handleNewLine(textareaRef.current);
167
+ }
168
+ }
72
169
  }, [handleSend, isSendButtonDisabled, handleStopButton]);
73
170
  const handleAttachMenuToggle = () => {
74
171
  (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen) && (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen(!(attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.isAttachMenuOpen)));
@@ -76,11 +173,6 @@ const MessageBar = (_a) => {
76
173
  };
77
174
  const handleSpeechRecognition = (message) => {
78
175
  setMessage(message);
79
- const textarea = textareaRef.current;
80
- if (textarea) {
81
- textarea.focus();
82
- textarea.textContent = dompurify_1.default.sanitize(message);
83
- }
84
176
  onChange && onChange({}, message);
85
177
  };
86
178
  const renderButtons = () => {
@@ -94,15 +186,9 @@ const MessageBar = (_a) => {
94
186
  hasMicrophoneButton && (react_1.default.createElement(MicrophoneButton_1.default, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _h === void 0 ? void 0 : _h.tooltipContent, language: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _j === void 0 ? void 0 : _j.language }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.props))),
95
187
  (alwayShowSendButton || message) && (react_1.default.createElement(SendButton_1.default, Object.assign({ value: message, onClick: handleSend, isDisabled: isSendButtonDisabled, tooltipContent: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _l === void 0 ? void 0 : _l.tooltipContent }, (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _m === void 0 ? void 0 : _m.props)))));
96
188
  };
97
- const placeholder = isListeningMessage ? 'Listening' : 'Send a message...';
98
189
  const messageBarContents = (react_1.default.createElement(react_1.default.Fragment, null,
99
190
  react_1.default.createElement("div", { className: "pf-chatbot__message-bar-input" },
100
- (showPlaceholder || message === '') && (react_1.default.createElement("div", { className: "pf-chatbot__message-bar-placeholder" }, placeholder)),
101
- react_1.default.createElement("div", Object.assign({ contentEditable: true, suppressContentEditableWarning: true, role: "textbox", "aria-multiline": "false", className: "pf-chatbot__message-textarea", onInput: handleInput, onFocus: () => setShowPlaceholder(false), onBlur: () => {
102
- if (message === '') {
103
- setShowPlaceholder(!showPlaceholder);
104
- }
105
- }, "aria-label": placeholder, ref: textareaRef, onKeyDown: handleKeyDown }, props))),
191
+ react_1.default.createElement(react_core_1.TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? 'Listening' : 'Send a message...', placeholder: isListeningMessage ? 'Listening' : 'Send a message...', ref: textareaRef, onKeyDown: handleKeyDown }, props))),
106
192
  react_1.default.createElement("div", { className: "pf-chatbot__message-bar-actions" }, renderButtons())));
107
193
  if (attachMenuProps) {
108
194
  return (react_1.default.createElement(AttachMenu_1.default, Object.assign({ toggle: (toggleRef) => (react_1.default.createElement("div", { ref: toggleRef, className: `pf-chatbot__message-bar ${className !== null && className !== void 0 ? className : ''}` }, messageBarContents)), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
package/dist/css/main.css CHANGED
@@ -1571,25 +1571,15 @@
1571
1571
  }
1572
1572
  .pf-chatbot__message-bar-input {
1573
1573
  flex: 1 1 auto;
1574
- padding-block-start: var(--pf-chatbot__message-bar-child--PaddingBlockStart);
1575
- padding-block-end: var(--pf-chatbot__message-bar-child--PaddingBlockEnd);
1576
- overflow: hidden;
1577
- position: relative;
1578
- }
1579
- .pf-chatbot__message-bar-placeholder {
1580
- position: absolute;
1581
- top: 20px;
1582
- left: 16px;
1583
- color: var(--pf-t--global--text--color--placeholder);
1584
- pointer-events: none;
1585
- font-size: var(--pf-t--chatbot--font-size);
1574
+ padding-block-start: var(--pf-t--global--spacer--sm);
1575
+ padding-block-end: var(--pf-t--global--spacer--sm);
1586
1576
  }
1587
1577
 
1588
1578
  .pf-chatbot__message-textarea {
1589
- padding-block-start: var(--pf-t--global--spacer--md);
1590
- padding-block-end: var(--pf-t--global--spacer--md);
1591
- padding-inline-start: var(--pf-t--global--spacer--md);
1592
- padding-inline-end: var(--pf-t--global--spacer--md);
1579
+ --pf-v6-c-form-control--before--BorderStyle: none;
1580
+ --pf-v6-c-form-control--after--BorderStyle: none;
1581
+ resize: none;
1582
+ background-color: transparent;
1593
1583
  font-size: var(--pf-t--global--font--size--md);
1594
1584
  line-height: 1.5rem;
1595
1585
  max-height: 12rem;
@@ -1600,7 +1590,31 @@
1600
1590
  height: 100%;
1601
1591
  width: 100%;
1602
1592
  display: block !important;
1603
- position: relative;
1593
+ }
1594
+ .pf-chatbot__message-textarea .pf-v6-c-form-control__textarea:focus-visible {
1595
+ outline: none;
1596
+ }
1597
+ .pf-chatbot__message-textarea .pf-v6-c-form-control > textarea {
1598
+ outline-offset: 0px;
1599
+ --pf-v6-c-form-control--PaddingBlockStart: 0;
1600
+ --pf-v6-c-form-control--PaddingBlockEnd: 0;
1601
+ --pf-v6-c-form-control--BorderRadius: 0;
1602
+ }
1603
+ .pf-chatbot__message-textarea .pf-v6-c-form-control > textarea:focus-visible {
1604
+ outline: none;
1605
+ }
1606
+
1607
+ @media screen and (max-width: 359px) {
1608
+ .pf-chatbot__message-textarea {
1609
+ margin-top: var(--pf-t--global--spacer--md) !important;
1610
+ margin-bottom: var(--pf-t--global--spacer--md) !important;
1611
+ }
1612
+ }
1613
+ @media screen and (max-width: 415px) {
1614
+ .pf-chatbot--embedded .pf-chatbot__message-textarea {
1615
+ margin-top: var(--pf-t--global--spacer--md) !important;
1616
+ margin-bottom: var(--pf-t--global--spacer--md) !important;
1617
+ }
1604
1618
  }
1605
1619
 
1606
1620
  .pf-chatbot__jump {
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AC1GF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAGI;AAAA;IACE;IACA;;;ACpBJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;ACvLN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AC5CJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;ACvIF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AClFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAMJ;EACE;EACA;EACA;;;AC7FF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AD9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AC7CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AJjBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AKjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACzEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;ADtCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC7BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../src/AttachMenu/AttachMenu.scss","../../src/Chatbot/Chatbot.scss","../../src/ChatbotAlert/ChatbotAlert.scss","../../src/ChatbotContent/ChatbotContent.scss","../../src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss","../../src/ChatbotFooter/ChatbotFootnote.scss","../../src/ChatbotFooter/ChatbotFooter.scss","../../src/ChatbotHeader/ChatbotHeader.scss","../../src/ChatbotModal/ChatbotModal.scss","../../src/ChatbotPopover/ChatbotPopover.scss","../../src/ChatbotToggle/ChatbotToggle.scss","../../src/ChatbotWelcomePrompt/ChatbotWelcomePrompt.scss","../../src/CodeModal/CodeModal.scss","../../src/Compare/Compare.scss","../../src/FileDetails/FileDetails.scss","../../src/FileDetailsLabel/FileDetailsLabel.scss","../../src/FileDropZone/FileDropZone.scss","../../src/Message/Message.scss","../../src/Message/MessageLoading.scss","../../src/Message/CodeBlockMessage/CodeBlockMessage.scss","../../src/Message/TextMessage/TextMessage.scss","../../src/Message/ListMessage/ListMessage.scss","../../src/Message/TableMessage/TableMessage.scss","../../src/Message/QuickStarts/QuickStartTile.scss","../../src/Message/QuickResponse/QuickResponse.scss","../../src/Message/UserFeedback/UserFeedback.scss","../../src/MessageBar/AttachButton.scss","../../src/MessageBar/MicrophoneButton.scss","../../src/MessageBar/SendButton.scss","../../src/MessageBar/StopButton.scss","../../src/MessageBar/MessageBar.scss","../../src/MessageBox/JumpButton.scss","../../src/MessageBox/MessageBox.scss","../../src/ResponseActions/ResponseActions.scss","../../src/Settings/Settings.scss","../../src/SourcesCard/SourcesCard.scss","../../src/SourceDetailsMenuItem/SourceDetailsMenuItem.scss","../../src/TermsOfUse/TermsOfUse.scss","../../src/main.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;AACE;AAsBA;AASA;;AA9BA;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAGF;AACE;;AACA;EACE;EACA;EACA;EACA;EACA;;AAKJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;ACxDJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAKF;EAvBF;IAwBI;IACA;;;AAIF;EA7BF;IA8BI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EAXF;IAYI;;;;AAOJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EAdF;IAeI;;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AC1GF;EACE;EACA;EACA;;;ACAF;EACE;EACA;EACA;EACA;EACA;;AAGA;EARF;IASI;;;;AAOJ;EAGI;AAAA;IACE;IACA;;;ACpBJ;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAMJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAKA;EACE;;;AASJ;EACE;;;AAQF;EACE;;AACA;EACE;;;AASJ;EACE;;AACA;EACE;EACA;;AAEF;EACE;;;AASF;AAAA;AAAA;EACE;;;ACvLN;EACE;;AAEA;EACE;EACA;;;ACHJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAMF;EAGI;AAAA;IACE;;EACA;AAAA;IACE;;EAGJ;AAAA;IACE;IACA;IACA;;;AASJ;EACE;;;AC5CJ;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;;AAQN;EAGI;AAAA;IACE;;EAEF;AAAA;IACE;;;AASJ;EACE;;;AAOJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAGF;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAOJ;EACE;;;AAOJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;;;ACvIF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;AAAA;EAEE;;AAEF;EACE;EACA;;AAEF;EACE;;;AAOJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAGJ;EACE;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;;AAOJ;EACE;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQE;EACE;;;AAQN;EACE;;;ACvFA;EAA0B;;AAMxB;EAAM;;AACN;EAAuB;;AACvB;EACE;;AAIF;EACE;EACA;;AAEF;EACE;;;ACnBN;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAIF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AC3BF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAOJ;EAIM;AAAA;IACE;IACA;;;AC1CN;EACE;EACA;EACA;EACA;;AAEF;EACE;AACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EACE;;AAEF;EACE;EACA;;AAEF;EACE;;AAEF;EACE;;;AASA;EACE;EACA;;;AAKN;EACE;;;AAGF;EACE;;;AClFF;EACE;EACA;EACA;EACA;;;AAEF;EACE;;AAEA;EACE;EACA;EACA;;;AAGJ;EACE;EACA;EACA;;AAEA;EALF;IAMI;;;AAGF;EACE;;AAEA;EAHF;IAII;;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAIA;EADF;IAEI;;;;AAIN;EACE;;AAEA;EAHF;IAII;;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;;ACrEJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvBF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EAEA;EACA;EACA;;AACA;EACE;;AAGF;AAAA;EAEE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;AAAA;EAEE;EACA;;AAEA;AAAA;EACE;;;AAKF;EACE;;;AAMF;AAAA;EACE;;;AC/DJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAGA;EANF;IAOI;;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAME;EADF;IAEI;IACA;IACA;;EAEA;IACE;;;;AChDR;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAKF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;;AAEF;EACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAMJ;EACE;EACA;EACA;;;AC7FF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AC9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AD9CN;EACE;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EAEE;;AAMN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAEF;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1EE;EACE;;;AAMN;EACE;;;AAIF;EACE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EAKE;;;AC7CN;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKF;AAAA;EAEE;EACA;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AJjBJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;IACE;;EAEF;IAEE;;;;AKjDN;EACE;EACA;;AAEA;EAJF;IAKI;IACA;;;AAKA;EACE;;;AAOF;EACE;;;ACnBJ;EACE;;AAEA;EAHF;IAII;;;AAGF;EAPF;IAQI;;;AAKF;EACE;EACA;;AAIJ;AAAA;EAEE;EACA;;AAIF;EACE;EACA;EACA;;;AC7BJ;EACE;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AChDF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKA;EACE;;AAIJ;EAEE;;AAEA;EACE;;AAKA;EACE;;;AC5BR;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAMA;EACE;;AAKJ;EACE;EACA;;AAGA;EACE;;AAKA;EACE;;;AAMR;EACE;IACE;;EAEF;IACE;;;AC1CJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;AAEA;EACE;;;AAMJ;EACE;;AACA;EACE;;AAIJ;EACE;EACA;;AAGF;AAAA;EAEE;;;AAIJ;EACE;IACE;IACA;;EAEF;IACE;IACA;;;AC/CJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAKA;EACE;;;ACrBR;EACE;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;;;AAIJ;EACE;IACE;IACA;;;AAKF;EACE;IACE;IACA;;;;ACxFN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AC9CJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIA;EAVF;IAWI;;;AAGF;EAdF;IAeI;;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAGI;AAAA;IACE;IACA;;;ADtCN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAIF;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAIF;EA3CF;IA4CI;;;;AEhDJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;;;AAKN;EACE;EACA;;;AC1BF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AChCF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;AAAA;EACE;;AAGJ;EACE;EACA;;AAKA;AAAA;EACE;;AAGJ;EACE;;;ACrER;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAIF;EACE;EACA;;;AAGA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AC9BA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAIF;EACE;IACE;IACA;;;;AAKN;AAAA;EAGE;;AAGE;AAAA;EACE;;AAIJ;AAAA;EACE;;;AC7BJ;EAKE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASA;EACA;EAEA;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EAMA;EAKA;EAEA;EACA;EACA;EAEA;EAEA;;;AAMF;EACE;EACA;EAEA;EAEA;EACA;;;AAGF;EACE;EACA","file":"main.css"}
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ButtonProps, DropEvent } from '@patternfly/react-core';
3
+ import { ChatbotDisplayMode } from '../Chatbot';
3
4
  export interface MessageBarWithAttachMenuProps {
4
5
  /** Flag to enable whether attach menu is open */
5
6
  isAttachMenuOpen: boolean;
@@ -66,7 +67,9 @@ export interface MessageBarProps {
66
67
  };
67
68
  };
68
69
  /** A callback for when the text area value changes. */
69
- onChange?: (event: React.ChangeEvent<HTMLDivElement>, value: string) => void;
70
+ onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>, value: string) => void;
71
+ /** Display mode of chatbot, if you want to message bar to resize when the display mode changes */
72
+ displayMode?: ChatbotDisplayMode;
70
73
  }
71
74
  export declare const MessageBar: React.FunctionComponent<MessageBarProps>;
72
75
  export default MessageBar;
@@ -10,52 +10,144 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import React from 'react';
13
+ import { TextArea } from '@patternfly/react-core';
13
14
  // Import Chatbot components
14
15
  import SendButton from './SendButton';
15
16
  import MicrophoneButton from './MicrophoneButton';
16
17
  import { AttachButton } from './AttachButton';
17
18
  import AttachMenu from '../AttachMenu';
18
19
  import StopButton from './StopButton';
19
- import DOMPurify from 'dompurify';
20
20
  export const MessageBar = (_a) => {
21
- var { onSendMessage, className, alwayShowSendButton, hasAttachButton = true, hasMicrophoneButton, handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "hasAttachButton", "hasMicrophoneButton", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange"]);
21
+ var { onSendMessage, className, alwayShowSendButton, hasAttachButton = true, hasMicrophoneButton, handleAttach, attachMenuProps, isSendButtonDisabled, handleStopButton, hasStopButton, buttonProps, onChange, displayMode } = _a, props = __rest(_a, ["onSendMessage", "className", "alwayShowSendButton", "hasAttachButton", "hasMicrophoneButton", "handleAttach", "attachMenuProps", "isSendButtonDisabled", "handleStopButton", "hasStopButton", "buttonProps", "onChange", "displayMode"]);
22
22
  // Text Input
23
23
  // --------------------------------------------------------------------------
24
24
  const [message, setMessage] = React.useState('');
25
25
  const [isListeningMessage, setIsListeningMessage] = React.useState(false);
26
- const [showPlaceholder, setShowPlaceholder] = React.useState(true);
26
+ const [hasSentMessage, setHasSentMessage] = React.useState(false);
27
27
  const textareaRef = React.useRef(null);
28
28
  const attachButtonRef = React.useRef(null);
29
- const handleInput = (event) => {
30
- // newMessage === '' doesn't work unless we trim, which causes other problems
31
- // textContent seems to work, but doesn't allow for markdown, so we need both
32
- const messageText = DOMPurify.sanitize(event.target.textContent);
33
- if (messageText === '') {
34
- setShowPlaceholder(true);
35
- setMessage('');
36
- onChange && onChange(event, '');
29
+ const setInitialLineHeight = (field) => {
30
+ field.style.setProperty('line-height', '1rem');
31
+ const parent = field.parentElement;
32
+ if (parent) {
33
+ parent.style.setProperty('margin-top', `1rem`);
34
+ parent.style.setProperty('margin-bottom', `0rem`);
35
+ parent.style.setProperty('height', 'inherit');
36
+ const grandparent = parent.parentElement;
37
+ if (grandparent) {
38
+ grandparent.style.setProperty('flex-basis', 'auto');
39
+ }
37
40
  }
38
- else {
39
- setShowPlaceholder(false);
40
- // this is so that tests work; RTL doesn't seem to like event.target.innerText, but browsers don't pick up markdown without it
41
- let newMessage = messageText;
42
- if (event.target.innerText) {
43
- newMessage = DOMPurify.sanitize(event.target.innerText);
41
+ };
42
+ const setAutoHeight = (field) => {
43
+ const parent = field.parentElement;
44
+ if (parent) {
45
+ parent.style.setProperty('height', 'inherit');
46
+ const computed = window.getComputedStyle(field);
47
+ // Calculate the height
48
+ const height = parseInt(computed.getPropertyValue('border-top-width')) +
49
+ parseInt(computed.getPropertyValue('padding-top')) +
50
+ field.scrollHeight +
51
+ parseInt(computed.getPropertyValue('padding-bottom')) +
52
+ parseInt(computed.getPropertyValue('border-bottom-width'));
53
+ parent.style.setProperty('height', `${height}px`);
54
+ if (height > 32 || window.innerWidth <= 507) {
55
+ parent.style.setProperty('margin-bottom', `1rem`);
56
+ parent.style.setProperty('margin-top', `1rem`);
44
57
  }
45
- setMessage(newMessage);
46
- onChange && onChange(event, newMessage);
47
58
  }
48
59
  };
49
- // Handle sending message
50
- const handleSend = React.useCallback(() => {
51
- onSendMessage(message);
60
+ const textIsLongerThan2Lines = (field) => {
61
+ const lineHeight = parseFloat(window.getComputedStyle(field).lineHeight);
62
+ const lines = field.scrollHeight / lineHeight;
63
+ return lines > 2;
64
+ };
65
+ const setAutoWidth = (field) => {
66
+ const parent = field.parentElement;
67
+ if (parent) {
68
+ const grandparent = parent.parentElement;
69
+ if (textIsLongerThan2Lines(field) && grandparent) {
70
+ grandparent.style.setProperty('flex-basis', `100%`);
71
+ }
72
+ }
73
+ };
74
+ const handleNewLine = (field) => {
75
+ const parent = field.parentElement;
76
+ if (parent) {
77
+ parent.style.setProperty('margin-bottom', `1rem`);
78
+ parent.style.setProperty('margin-top', `1rem`);
79
+ }
80
+ };
81
+ React.useEffect(() => {
82
+ const field = textareaRef.current;
83
+ if (field) {
84
+ if (field.value === '') {
85
+ if (window.innerWidth > 507) {
86
+ setInitialLineHeight(field);
87
+ }
88
+ }
89
+ else {
90
+ setAutoHeight(field);
91
+ setAutoWidth(field);
92
+ }
93
+ }
94
+ const resetHeight = () => {
95
+ if (field) {
96
+ if (field.value === '') {
97
+ if (window.innerWidth > 507) {
98
+ setInitialLineHeight(field);
99
+ }
100
+ }
101
+ else {
102
+ setAutoHeight(field);
103
+ setAutoWidth(field);
104
+ }
105
+ }
106
+ };
107
+ window.addEventListener('resize', resetHeight);
108
+ return () => {
109
+ window.removeEventListener('resize', resetHeight);
110
+ };
111
+ }, []);
112
+ React.useEffect(() => {
113
+ const field = textareaRef.current;
114
+ if (field) {
115
+ if (field.value === '') {
116
+ setInitialLineHeight(textareaRef.current);
117
+ }
118
+ else {
119
+ setAutoHeight(textareaRef.current);
120
+ setAutoWidth(field);
121
+ }
122
+ }
123
+ }, [displayMode, message]);
124
+ React.useEffect(() => {
125
+ const field = textareaRef.current;
126
+ if (field) {
127
+ setInitialLineHeight(field);
128
+ setHasSentMessage(false);
129
+ }
130
+ }, [hasSentMessage]);
131
+ const handleChange = React.useCallback((event) => {
132
+ onChange && onChange(event, event.target.value);
52
133
  if (textareaRef.current) {
53
- textareaRef.current.innerText = '';
54
- setShowPlaceholder(true);
55
- textareaRef.current.blur();
134
+ if (event.target.value === '') {
135
+ setInitialLineHeight(textareaRef.current);
136
+ }
137
+ else {
138
+ setAutoHeight(textareaRef.current);
139
+ }
56
140
  }
57
- setMessage('');
58
- }, [onSendMessage, message]);
141
+ setMessage(event.target.value);
142
+ }, []);
143
+ // Handle sending message
144
+ const handleSend = React.useCallback(() => {
145
+ setMessage((m) => {
146
+ onSendMessage(m);
147
+ setHasSentMessage(true);
148
+ return '';
149
+ });
150
+ }, [onSendMessage]);
59
151
  const handleKeyDown = React.useCallback((event) => {
60
152
  if (event.key === 'Enter' && !event.shiftKey) {
61
153
  event.preventDefault();
@@ -63,6 +155,11 @@ export const MessageBar = (_a) => {
63
155
  handleSend();
64
156
  }
65
157
  }
158
+ if (event.key === 'Enter' && event.shiftKey) {
159
+ if (textareaRef.current) {
160
+ handleNewLine(textareaRef.current);
161
+ }
162
+ }
66
163
  }, [handleSend, isSendButtonDisabled, handleStopButton]);
67
164
  const handleAttachMenuToggle = () => {
68
165
  (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen) && (attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.setIsAttachMenuOpen(!(attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.isAttachMenuOpen)));
@@ -70,11 +167,6 @@ export const MessageBar = (_a) => {
70
167
  };
71
168
  const handleSpeechRecognition = (message) => {
72
169
  setMessage(message);
73
- const textarea = textareaRef.current;
74
- if (textarea) {
75
- textarea.focus();
76
- textarea.textContent = DOMPurify.sanitize(message);
77
- }
78
170
  onChange && onChange({}, message);
79
171
  };
80
172
  const renderButtons = () => {
@@ -88,15 +180,9 @@ export const MessageBar = (_a) => {
88
180
  hasMicrophoneButton && (React.createElement(MicrophoneButton, Object.assign({ isListening: isListeningMessage, onIsListeningChange: setIsListeningMessage, onSpeechRecognition: handleSpeechRecognition, tooltipContent: (_h = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _h === void 0 ? void 0 : _h.tooltipContent, language: (_j = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _j === void 0 ? void 0 : _j.language }, (_k = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.microphone) === null || _k === void 0 ? void 0 : _k.props))),
89
181
  (alwayShowSendButton || message) && (React.createElement(SendButton, Object.assign({ value: message, onClick: handleSend, isDisabled: isSendButtonDisabled, tooltipContent: (_l = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _l === void 0 ? void 0 : _l.tooltipContent }, (_m = buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.send) === null || _m === void 0 ? void 0 : _m.props)))));
90
182
  };
91
- const placeholder = isListeningMessage ? 'Listening' : 'Send a message...';
92
183
  const messageBarContents = (React.createElement(React.Fragment, null,
93
184
  React.createElement("div", { className: "pf-chatbot__message-bar-input" },
94
- (showPlaceholder || message === '') && (React.createElement("div", { className: "pf-chatbot__message-bar-placeholder" }, placeholder)),
95
- React.createElement("div", Object.assign({ contentEditable: true, suppressContentEditableWarning: true, role: "textbox", "aria-multiline": "false", className: "pf-chatbot__message-textarea", onInput: handleInput, onFocus: () => setShowPlaceholder(false), onBlur: () => {
96
- if (message === '') {
97
- setShowPlaceholder(!showPlaceholder);
98
- }
99
- }, "aria-label": placeholder, ref: textareaRef, onKeyDown: handleKeyDown }, props))),
185
+ React.createElement(TextArea, Object.assign({ className: "pf-chatbot__message-textarea", value: message, onChange: handleChange, "aria-label": isListeningMessage ? 'Listening' : 'Send a message...', placeholder: isListeningMessage ? 'Listening' : 'Send a message...', ref: textareaRef, onKeyDown: handleKeyDown }, props))),
100
186
  React.createElement("div", { className: "pf-chatbot__message-bar-actions" }, renderButtons())));
101
187
  if (attachMenuProps) {
102
188
  return (React.createElement(AttachMenu, Object.assign({ toggle: (toggleRef) => (React.createElement("div", { ref: toggleRef, className: `pf-chatbot__message-bar ${className !== null && className !== void 0 ? className : ''}` }, messageBarContents)), filteredItems: attachMenuProps === null || attachMenuProps === void 0 ? void 0 : attachMenuProps.attachMenuItems }, (attachMenuProps && { isOpen: attachMenuProps.isAttachMenuOpen }), { onOpenChange: (isAttachMenuOpen) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/chatbot",
3
- "version": "2.2.0-prerelease.21",
3
+ "version": "2.2.0-prerelease.23",
4
4
  "description": "This library provides React components based on PatternFly 6 that can be used to build chatbots.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -44,27 +44,16 @@
44
44
 
45
45
  &-input {
46
46
  flex: 1 1 auto;
47
- padding-block-start: var(--pf-chatbot__message-bar-child--PaddingBlockStart);
48
- padding-block-end: var(--pf-chatbot__message-bar-child--PaddingBlockEnd);
49
- overflow: hidden;
50
- position: relative;
51
- }
52
-
53
- &-placeholder {
54
- position: absolute;
55
- top: 20px;
56
- left: 16px;
57
- color: var(--pf-t--global--text--color--placeholder);
58
- pointer-events: none;
59
- font-size: var(--pf-t--chatbot--font-size);
47
+ padding-block-start: var(--pf-t--global--spacer--sm);
48
+ padding-block-end: var(--pf-t--global--spacer--sm);
60
49
  }
61
50
  }
62
51
 
63
52
  .pf-chatbot__message-textarea {
64
- padding-block-start: var(--pf-t--global--spacer--md);
65
- padding-block-end: var(--pf-t--global--spacer--md);
66
- padding-inline-start: var(--pf-t--global--spacer--md);
67
- padding-inline-end: var(--pf-t--global--spacer--md);
53
+ --pf-v6-c-form-control--before--BorderStyle: none;
54
+ --pf-v6-c-form-control--after--BorderStyle: none;
55
+ resize: none;
56
+ background-color: transparent;
68
57
  font-size: var(--pf-t--global--font--size--md);
69
58
  line-height: 1.5rem;
70
59
  max-height: 12rem;
@@ -75,5 +64,33 @@
75
64
  height: 100%;
76
65
  width: 100%;
77
66
  display: block !important;
78
- position: relative;
67
+
68
+ .pf-v6-c-form-control__textarea:focus-visible {
69
+ outline: none;
70
+ }
71
+ .pf-v6-c-form-control > textarea {
72
+ outline-offset: 0px;
73
+ --pf-v6-c-form-control--PaddingBlockStart: 0;
74
+ --pf-v6-c-form-control--PaddingBlockEnd: 0;
75
+ --pf-v6-c-form-control--BorderRadius: 0;
76
+ }
77
+ .pf-v6-c-form-control > textarea:focus-visible {
78
+ outline: none;
79
+ }
80
+ }
81
+
82
+ @media screen and (max-width: 359px) {
83
+ .pf-chatbot__message-textarea {
84
+ margin-top: var(--pf-t--global--spacer--md) !important;
85
+ margin-bottom: var(--pf-t--global--spacer--md) !important;
86
+ }
87
+ }
88
+
89
+ .pf-chatbot--embedded {
90
+ @media screen and (max-width: 415px) {
91
+ .pf-chatbot__message-textarea {
92
+ margin-top: var(--pf-t--global--spacer--md) !important;
93
+ margin-bottom: var(--pf-t--global--spacer--md) !important;
94
+ }
95
+ }
79
96
  }
@@ -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 DOMPurify from 'dompurify';
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<HTMLDivElement>, value: string) => void;
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 [showPlaceholder, setShowPlaceholder] = React.useState(true);
89
- const textareaRef = React.useRef<HTMLDivElement>(null);
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 handleInput = (event) => {
93
- // newMessage === '' doesn't work unless we trim, which causes other problems
94
- // textContent seems to work, but doesn't allow for markdown, so we need both
95
- const messageText = DOMPurify.sanitize(event.target.textContent);
96
- if (messageText === '') {
97
- setShowPlaceholder(true);
98
- setMessage('');
99
- onChange && onChange(event, '');
100
- } else {
101
- setShowPlaceholder(false);
102
- // this is so that tests work; RTL doesn't seem to like event.target.innerText, but browsers don't pick up markdown without it
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
- // Handle sending message
113
- const handleSend = React.useCallback(() => {
114
- onSendMessage(message);
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
- textareaRef.current.innerText = '';
117
- setShowPlaceholder(true);
118
- textareaRef.current.blur();
209
+ if (event.target.value === '') {
210
+ setInitialLineHeight(textareaRef.current);
211
+ } else {
212
+ setAutoHeight(textareaRef.current);
213
+ }
119
214
  }
120
- setMessage('');
121
- }, [onSendMessage, message]);
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
- const textarea = textareaRef.current;
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
- {(showPlaceholder || message === '') && (
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
- onInput={handleInput}
218
- onFocus={() => setShowPlaceholder(false)}
219
- onBlur={() => {
220
- if (message === '') {
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}