UNPKG

@azure/communication-react

Version:

React library for building modern communication user experiences utilizing Azure Communication Services

94 lines 5.67 kB
// 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