UNPKG

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
// 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