communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
100 lines • 6.53 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import React, { useCallback, useMemo, useState } from 'react';
import { RichTextEditor } from './RichTextEditor';
import { useTheme } from '../../theming';
import { Icon, Stack } from '@fluentui/react';
import { InputBoxButton } from '../InputBoxButton';
import { isEnterKeyEventFromCompositionSession } from '../utils';
import { richTextActionButtonsDividerStyle, richTextActionButtonsStackStyle, richTextActionButtonsStyle, richTextFormatButtonIconStyle } from '../styles/RichTextEditor.styles';
import { inputBoxContentStackStyle, inputBoxRichTextStackItemStyle, inputBoxRichTextStackStyle, richTextBorderBoxStyle } from '../styles/RichTextInputBoxComponent.styles';
/**
* @private
*/
export const RichTextInputBoxComponent = (props) => {
const { placeholderText, initialContent, onChange, onEnterKeyDown, editorComponentRef, disabled, strings, actionComponents,
/* @conditional-compile-remove(file-sharing-acs) */
onRenderAttachmentUploads,
/* @conditional-compile-remove(file-sharing-acs) */
hasAttachments, richTextEditorStyleProps, isHorizontalLayoutDisabled = false, autoFocus, onTyping,
/* @conditional-compile-remove(rich-text-editor-image-upload) */
onInsertInlineImage } = props;
const theme = useTheme();
// undefined is used to indicate that the rich text editor toolbar state wasn't changed yet
const [showRichTextEditorFormatting, setShowRichTextEditorFormatting] = useState(undefined);
const [contentModel, setContentModel] = useState(undefined);
const onRenderRichTextEditorIcon = useCallback((isHover) => {
const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
return (React.createElement(Icon, { iconName: isHover || isRichTextEditorToolbarShown ? 'RichTextEditorButtonIconFilled' : 'RichTextEditorButtonIcon', className: richTextFormatButtonIconStyle(theme, !disabled && (isHover || isRichTextEditorToolbarShown)) }));
}, [disabled, showRichTextEditorFormatting, theme]);
const actionButtons = useMemo(() => {
return (React.createElement(Stack.Item, { align: "end", className: richTextActionButtonsStackStyle },
React.createElement(Stack, { horizontal: true },
React.createElement(InputBoxButton, { onRenderIcon: onRenderRichTextEditorIcon, onClick: (e) => {
const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
setShowRichTextEditorFormatting(!isRichTextEditorToolbarShown);
e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.
}, ariaLabel: strings.richTextFormatButtonTooltip, tooltipContent: strings.richTextFormatButtonTooltip, className: richTextActionButtonsStyle, "data-testId": 'rich-text-input-box-format-button', ariaExpanded: showRichTextEditorFormatting }),
React.createElement(Icon, { iconName: "RichTextDividerIcon", className: richTextActionButtonsDividerStyle(theme) }),
actionComponents)));
}, [
actionComponents,
onRenderRichTextEditorIcon,
showRichTextEditorFormatting,
strings.richTextFormatButtonTooltip,
theme
]);
const richTextEditorStyle = useMemo(() => {
return richTextEditorStyleProps(showRichTextEditorFormatting === true);
}, [richTextEditorStyleProps, showRichTextEditorFormatting]);
const onKeyDown = useCallback((ev) => {
if (isEnterKeyEventFromCompositionSession(ev)) {
return;
}
const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
if (ev.key === 'Enter' && ev.shiftKey === false && !isRichTextEditorToolbarShown) {
ev.preventDefault();
onEnterKeyDown === null || onEnterKeyDown === void 0 ? void 0 : onEnterKeyDown();
}
else {
onTyping === null || onTyping === void 0 ? void 0 : onTyping();
}
}, [onEnterKeyDown, showRichTextEditorFormatting, onTyping]);
const onCompositionUpdate = useCallback(() => {
onTyping === null || onTyping === void 0 ? void 0 : onTyping();
}, [onTyping]);
const useHorizontalLayout = useMemo(() => {
const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
return (!isHorizontalLayoutDisabled &&
!isRichTextEditorToolbarShown &&
/* @conditional-compile-remove(file-sharing-acs) */ !hasAttachments);
}, [
isHorizontalLayoutDisabled,
showRichTextEditorFormatting,
/* @conditional-compile-remove(file-sharing-acs) */ hasAttachments
]);
const onContentModelUpdate = useCallback((contentModel) => {
setContentModel(contentModel);
}, []);
return (React.createElement("div", { className: richTextBorderBoxStyle({
theme: theme,
disabled: !!disabled
}) },
React.createElement("div", { className: inputBoxContentStackStyle, style: {
display: 'flex',
flexGrow: 1,
flexDirection: useHorizontalLayout ? 'row' : 'column',
justifyContent: useHorizontalLayout ? 'flex-end' : 'space-between',
flexWrap: useHorizontalLayout ? 'wrap' : 'nowrap'
} },
React.createElement(Stack, { grow: true, className: inputBoxRichTextStackStyle },
React.createElement(Stack.Item, { className: inputBoxRichTextStackItemStyle },
React.createElement(RichTextEditor, { contentModel: contentModel, initialContent: initialContent, placeholderText: placeholderText, onChange: onChange, onKeyDown: onKeyDown, onCompositionUpdate: onCompositionUpdate, ref: editorComponentRef, strings: strings, showRichTextEditorFormatting: showRichTextEditorFormatting === true, styles: richTextEditorStyle, autoFocus: autoFocus, onContentModelUpdate: onContentModelUpdate,
/* @conditional-compile-remove(rich-text-editor-image-upload) */
onPaste: props.onPaste,
/* @conditional-compile-remove(rich-text-editor-image-upload) */
onInsertInlineImage: onInsertInlineImage })), /* @conditional-compile-remove(file-sharing-acs) */
onRenderAttachmentUploads && onRenderAttachmentUploads()),
actionButtons)));
};
//# sourceMappingURL=RichTextInputBoxComponent.js.map