@azure/communication-react
Version:
React library for building modern communication user experiences utilizing Azure Communication Services
94 lines • 5.67 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import React, { useState, useMemo, useCallback } from 'react';
import { mergeStyles, concatStyleSets, Icon, Stack } from '@fluentui/react';
import { sendButtonStyle, sendIconStyle, sendBoxWrapperStyles, borderAndBoxShadowStyle } from './styles/SendBox.styles';
import { useTheme } from '../theming';
import { useLocale } from '../localization';
import { useIdentifiers } from '../identifiers';
import { InputBoxComponent } from './InputBoxComponent';
import { InputBoxButton } from './InputBoxButton';
import { MAXIMUM_LENGTH_OF_MESSAGE, isMessageTooLong, sanitizeText, isSendBoxButtonDisabled } from './utils/SendBoxUtils';
/**
* Component for typing and sending messages.
*
* Supports sending typing notification when user starts entering text.
* Supports an optional message below the text input field.
*
* @public
*/
export const SendBox = (props) => {
const { disabled, systemMessage, supportNewline, onSendMessage, onTyping, onRenderIcon, onRenderSystemMessage, styles, autoFocus } = props;
const theme = useTheme();
const localeStrings = useLocale().strings.sendBox;
const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
const ids = useIdentifiers();
const [textValue, setTextValue] = useState('');
const [textValueOverflow, setTextValueOverflow] = useState(false);
const sendTextFieldRef = React.useRef(null);
const sendMessageOnClick = () => {
var _a;
// don't send a message when disabled
if (disabled || textValueOverflow) {
return;
}
// Don't send message until all attachments have been uploaded successfully
const message = textValue;
// we don't want to send empty messages including spaces, newlines, tabs
// Message can be empty if there is a valid attachment upload
if (sanitizeText(message).length > 0) {
onSendMessage && onSendMessage(message);
setTextValue('');
(_a = sendTextFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
}
};
const setText = (newValue) => {
if (newValue === undefined) {
return;
}
setTextValueOverflow(isMessageTooLong(newValue.length));
setTextValue(newValue);
};
const textTooLongMessage = textValueOverflow ? strings.textTooLong : undefined;
const errorMessage = systemMessage !== null && systemMessage !== void 0 ? systemMessage : textTooLongMessage;
const isSendBoxButtonDisabledValue = useMemo(() => {
return isSendBoxButtonDisabled({
hasContent: sanitizeText(textValue).length > 0,
hasError: !!errorMessage,
disabled: !!disabled
});
}, [disabled, errorMessage, textValue]);
const mergedSendButtonStyle = useMemo(() => mergeStyles(sendButtonStyle, styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer), [styles === null || styles === void 0 ? void 0 : styles.sendMessageIconContainer]);
const mergedStyles = useMemo(() => concatStyleSets(styles), [styles]);
const mergedSendIconStyle = useMemo(() => sendIconStyle({
theme,
isSendBoxButtonDisabled: isSendBoxButtonDisabledValue,
customSendIconStyle: styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon
}), [theme, isSendBoxButtonDisabledValue, styles === null || styles === void 0 ? void 0 : styles.sendMessageIcon]);
const onRenderSendIcon = useCallback((isHover) => onRenderIcon ? onRenderIcon(isHover) : React.createElement(Icon, { iconName: isHover && textValue ? 'SendBoxSendHovered' : 'SendBoxSend', className: mergedSendIconStyle }), [mergedSendIconStyle, onRenderIcon, textValue]);
// Ensure that errors are cleared when there are no attachments in sendBox
return React.createElement(Stack, { className: mergeStyles(sendBoxWrapperStyles, {
overflow: 'visible'
} // This is needed for the mention popup to be visible
) },
React.createElement(Stack, { className: borderAndBoxShadowStyle({
theme,
hasErrorMessage: !!errorMessage,
disabled: !!disabled
}) },
React.createElement(InputBoxComponent, { autoFocus: autoFocus, "data-ui-id": ids.sendboxTextField, disabled: disabled, errorMessage: onRenderSystemMessage ? onRenderSystemMessage(errorMessage) : errorMessage, textFieldRef: sendTextFieldRef, id: "sendbox", placeholderText: strings.placeholderText, textValue: textValue, onChange: (_, newValue) => setText(newValue), onKeyDown: ev => {
const keyWasSendingMessage = ev.key === 'Enter' && (ev.shiftKey === false || !supportNewline);
if (!keyWasSendingMessage) {
onTyping === null || onTyping === void 0 ? void 0 : onTyping();
}
}, onEnterKeyDown: () => {
sendMessageOnClick();
}, styles: mergedStyles, supportNewline: supportNewline, maxLength: MAXIMUM_LENGTH_OF_MESSAGE },
React.createElement(InputBoxButton, { onRenderIcon: onRenderSendIcon, onClick: e => {
if (!textValueOverflow) {
sendMessageOnClick();
}
e.stopPropagation();
}, id: 'sendIconWrapper', className: mergedSendButtonStyle, ariaLabel: localeStrings.sendButtonAriaLabel, tooltipContent: localeStrings.sendButtonAriaLabel, disabled: isSendBoxButtonDisabledValue }))));
};
//# sourceMappingURL=SendBox.js.map