@azure/communication-react 1.17.0-alpha-202405170014 → 1.17.0-alpha-202405180013

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.
Files changed (90) hide show
  1. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BLFNaheX.js → ChatMessageComponentAsRichTextEditBox-r0U_8d3I.js} +22 -17
  2. package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-r0U_8d3I.js.map +1 -0
  3. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BhTpuspw.js → RichTextSendBoxWrapper-DNlYAgO2.js} +6 -8
  4. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BhTpuspw.js.map → RichTextSendBoxWrapper-DNlYAgO2.js.map} +1 -1
  5. package/dist/dist-cjs/communication-react/{index-C9I6Mcil.js → index-BLj9R9ms.js} +894 -462
  6. package/dist/dist-cjs/communication-react/index-BLj9R9ms.js.map +1 -0
  7. package/dist/dist-cjs/communication-react/index.js +5 -7
  8. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  9. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  10. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  11. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js +17 -10
  12. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js.map +1 -1
  13. package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +1 -1
  14. package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
  15. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.d.ts +9 -0
  16. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.js +29 -0
  17. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.js.map +1 -0
  18. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +1 -1
  19. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +15 -20
  20. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
  21. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.d.ts +12 -0
  22. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.js +23 -0
  23. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.js.map +1 -0
  24. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.d.ts +15 -0
  25. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js +39 -0
  26. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js.map +1 -0
  27. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.d.ts +24 -0
  28. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.js +66 -0
  29. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.js.map +1 -0
  30. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.d.ts +20 -0
  31. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.js +46 -0
  32. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.js.map +1 -0
  33. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.d.ts +29 -0
  34. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +71 -0
  35. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -0
  36. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +7 -10
  37. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +170 -91
  38. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
  39. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +0 -1
  40. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js +29 -12
  41. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
  42. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +12 -46
  43. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
  44. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.d.ts +19 -0
  45. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.js +209 -0
  46. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.js.map +1 -0
  47. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.d.ts +7 -0
  48. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.js +49 -0
  49. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.js.map +1 -0
  50. package/dist/dist-esm/react-components/src/components/RichTextEditor/{Buttons → Toolbar}/Table/RichTextInsertTablePane.d.ts +2 -2
  51. package/dist/dist-esm/react-components/src/components/RichTextEditor/{Buttons → Toolbar}/Table/RichTextInsertTablePane.js +3 -3
  52. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTablePane.js.map +1 -0
  53. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.d.ts +6 -0
  54. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.js +13 -0
  55. package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.js.map +1 -0
  56. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -1
  57. package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
  58. package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js +3 -1
  59. package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js.map +1 -1
  60. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +3 -3
  61. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +4 -5
  62. package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -1
  63. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.d.ts +37 -0
  64. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +60 -0
  65. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -0
  66. package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.d.ts +11 -0
  67. package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js +95 -0
  68. package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js.map +1 -1
  69. package/dist/dist-esm/react-components/src/components/utils.d.ts +1 -1
  70. package/dist/dist-esm/react-components/src/components/utils.js +1 -3
  71. package/dist/dist-esm/react-components/src/components/utils.js.map +1 -1
  72. package/package.json +6 -8
  73. package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-BLFNaheX.js.map +0 -1
  74. package/dist/dist-cjs/communication-react/index-C9I6Mcil.js.map +0 -1
  75. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.d.ts +0 -7
  76. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js +0 -86
  77. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js.map +0 -1
  78. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.d.ts +0 -7
  79. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js +0 -55
  80. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js.map +0 -1
  81. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.js.map +0 -1
  82. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.d.ts +0 -8
  83. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.js +0 -66
  84. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.js.map +0 -1
  85. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.d.ts +0 -9
  86. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.js +0 -56
  87. package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.js.map +0 -1
  88. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.d.ts +0 -15
  89. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.js +0 -39
  90. package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import React, { useCallback, useMemo, useState } from 'react';
3
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
4
  import { RichTextEditor } from './RichTextEditor';
5
5
  import { useTheme } from '../../theming';
6
6
  import { Icon, Stack } from '@fluentui/react';
@@ -16,37 +16,50 @@ export const RichTextInputBoxComponent = (props) => {
16
16
  /* @conditional-compile-remove(attachment-upload) */
17
17
  onRenderAttachmentUploads,
18
18
  /* @conditional-compile-remove(attachment-upload) */
19
- hasAttachments, richTextEditorStyleProps, isHorizontalLayoutDisabled = false, content, autoFocus, onTyping } = props;
19
+ hasAttachments, richTextEditorStyleProps, isHorizontalLayoutDisabled = false, autoFocus, onTyping } = props;
20
20
  const theme = useTheme();
21
- const [showRichTextEditorFormatting, setShowRichTextEditorFormatting] = useState(false);
22
- const onRenderRichTextEditorIcon = useCallback((isHover) => (React.createElement(Icon, { iconName: isHover || showRichTextEditorFormatting ? 'RichTextEditorButtonIconFilled' : 'RichTextEditorButtonIcon', className: richTextFormatButtonIconStyle(theme, !disabled && (isHover || showRichTextEditorFormatting)) })), [disabled, showRichTextEditorFormatting, theme]);
21
+ // undefined is used to indicate that the rich text editor toolbar state wasn't changed yet
22
+ const [showRichTextEditorFormatting, setShowRichTextEditorFormatting] = useState(undefined);
23
+ const [contentModel, setContentModel] = useState(undefined);
24
+ const onRenderRichTextEditorIcon = useCallback((isHover) => {
25
+ const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
26
+ return (React.createElement(Icon, { iconName: isHover || isRichTextEditorToolbarShown ? 'RichTextEditorButtonIconFilled' : 'RichTextEditorButtonIcon', className: richTextFormatButtonIconStyle(theme, !disabled && (isHover || isRichTextEditorToolbarShown)) }));
27
+ }, [disabled, showRichTextEditorFormatting, theme]);
28
+ useEffect(() => {
29
+ var _a;
30
+ if (showRichTextEditorFormatting !== undefined) {
31
+ // Focus the editor when toolbar shown/hidden
32
+ (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
33
+ }
34
+ // we don't need execute this useEffect if editorComponentRef is changed
35
+ // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ }, [showRichTextEditorFormatting]);
23
37
  const actionButtons = useMemo(() => {
24
38
  return (React.createElement(Stack.Item, { align: "end", className: richTextActionButtonsStackStyle },
25
39
  React.createElement(Stack, { horizontal: true },
26
40
  React.createElement(InputBoxButton, { onRenderIcon: onRenderRichTextEditorIcon, onClick: (e) => {
27
- var _a;
28
- setShowRichTextEditorFormatting(!showRichTextEditorFormatting);
29
- (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
41
+ const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
42
+ setShowRichTextEditorFormatting(!isRichTextEditorToolbarShown);
30
43
  e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.
31
44
  }, ariaLabel: strings.richTextFormatButtonTooltip, tooltipContent: strings.richTextFormatButtonTooltip, className: richTextActionButtonsStyle, "data-testId": 'rich-text-input-box-format-button' }),
32
45
  React.createElement(Icon, { iconName: "RichTextDividerIcon", className: richTextActionButtonsDividerStyle(theme) }),
33
46
  actionComponents)));
34
47
  }, [
35
48
  actionComponents,
36
- editorComponentRef,
37
49
  onRenderRichTextEditorIcon,
38
50
  showRichTextEditorFormatting,
39
51
  strings.richTextFormatButtonTooltip,
40
52
  theme
41
53
  ]);
42
54
  const richTextEditorStyle = useMemo(() => {
43
- return richTextEditorStyleProps(showRichTextEditorFormatting);
55
+ return richTextEditorStyleProps(showRichTextEditorFormatting === true);
44
56
  }, [richTextEditorStyleProps, showRichTextEditorFormatting]);
45
57
  const onKeyDown = useCallback((ev) => {
46
58
  if (isEnterKeyEventFromCompositionSession(ev)) {
47
59
  return;
48
60
  }
49
- if (ev.key === 'Enter' && ev.shiftKey === false && !showRichTextEditorFormatting) {
61
+ const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
62
+ if (ev.key === 'Enter' && ev.shiftKey === false && !isRichTextEditorToolbarShown) {
50
63
  ev.preventDefault();
51
64
  onEnterKeyDown && onEnterKeyDown();
52
65
  }
@@ -55,14 +68,18 @@ export const RichTextInputBoxComponent = (props) => {
55
68
  }
56
69
  }, [onEnterKeyDown, showRichTextEditorFormatting, onTyping]);
57
70
  const useHorizontalLayout = useMemo(() => {
71
+ const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;
58
72
  return (!isHorizontalLayoutDisabled &&
59
- !showRichTextEditorFormatting &&
73
+ !isRichTextEditorToolbarShown &&
60
74
  /* @conditional-compile-remove(attachment-upload) */ !hasAttachments);
61
75
  }, [
62
76
  isHorizontalLayoutDisabled,
63
77
  showRichTextEditorFormatting,
64
78
  /* @conditional-compile-remove(attachment-upload) */ hasAttachments
65
79
  ]);
80
+ const onContentModelUpdate = useCallback((contentModel) => {
81
+ setContentModel(contentModel);
82
+ }, []);
66
83
  return (React.createElement("div", { className: richTextBorderBoxStyle({
67
84
  theme: theme,
68
85
  disabled: !!disabled
@@ -70,7 +87,7 @@ export const RichTextInputBoxComponent = (props) => {
70
87
  React.createElement(Stack, { grow: true, horizontal: useHorizontalLayout, horizontalAlign: useHorizontalLayout ? 'end' : 'space-between', className: inputBoxContentStackStyle, wrap: useHorizontalLayout },
71
88
  React.createElement(Stack, { grow: true, className: inputBoxRichTextStackStyle },
72
89
  React.createElement(Stack.Item, { className: inputBoxRichTextStackItemStyle },
73
- React.createElement(RichTextEditor, { content: content, initialContent: initialContent, placeholderText: placeholderText, onChange: onChange, onKeyDown: onKeyDown, ref: editorComponentRef, strings: strings, showRichTextEditorFormatting: showRichTextEditorFormatting, styles: richTextEditorStyle, autoFocus: autoFocus })),
90
+ React.createElement(RichTextEditor, { contentModel: contentModel, initialContent: initialContent, placeholderText: placeholderText, onChange: onChange, onKeyDown: onKeyDown, ref: editorComponentRef, strings: strings, showRichTextEditorFormatting: showRichTextEditorFormatting === true, styles: richTextEditorStyle, autoFocus: autoFocus, onContentModelUpdate: onContentModelUpdate })),
74
91
  /* @conditional-compile-remove(attachment-upload) */ onRenderAttachmentUploads &&
75
92
  onRenderAttachmentUploads()),
76
93
  actionButtons)));
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextInputBoxComponent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextInputBoxComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { ReactNode, useCallback, useMemo, useState } from 'react';\nimport { BaseCustomStyles } from '../../types';\nimport { RichTextEditor, RichTextEditorComponentRef, RichTextEditorStyleProps } from './RichTextEditor';\nimport { RichTextSendBoxStrings } from './RichTextSendBox';\nimport { useTheme } from '../../theming';\nimport { Icon, Stack } from '@fluentui/react';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { isEnterKeyEventFromCompositionSession } from '../utils';\nimport {\n richTextActionButtonsDividerStyle,\n richTextActionButtonsStackStyle,\n richTextActionButtonsStyle,\n richTextFormatButtonIconStyle\n} from '../styles/RichTextEditor.styles';\nimport {\n inputBoxContentStackStyle,\n inputBoxRichTextStackItemStyle,\n inputBoxRichTextStackStyle,\n richTextBorderBoxStyle\n} from '../styles/RichTextInputBoxComponent.styles';\n\n/**\n * @private\n */\nexport interface RichTextInputBoxComponentStylesProps extends BaseCustomStyles {}\n\n/**\n * @private\n */\nexport interface RichTextInputBoxComponentProps {\n placeholderText?: string;\n // the initial content of editor that is set when editor is created (e.g. when editing a message)\n initialContent?: string;\n // the current content of the editor\n content?: string;\n onChange: (newValue?: string) => void;\n onEnterKeyDown?: () => void;\n editorComponentRef: React.RefObject<RichTextEditorComponentRef>;\n strings: Partial<RichTextSendBoxStrings>;\n disabled: boolean;\n actionComponents: ReactNode;\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads?: () => JSX.Element;\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments?: boolean;\n // props for min and max height for the rich text editor\n // otherwise the editor will grow to fit the content\n richTextEditorStyleProps: (isExpanded: boolean) => RichTextEditorStyleProps;\n isHorizontalLayoutDisabled?: boolean;\n autoFocus?: 'sendBoxTextField';\n onTyping?: () => Promise<void>;\n}\n\n/**\n * @private\n */\nexport const RichTextInputBoxComponent = (props: RichTextInputBoxComponentProps): JSX.Element => {\n const {\n placeholderText,\n initialContent,\n onChange,\n onEnterKeyDown,\n editorComponentRef,\n disabled,\n strings,\n actionComponents,\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments,\n richTextEditorStyleProps,\n isHorizontalLayoutDisabled = false,\n content,\n autoFocus,\n onTyping\n } = props;\n const theme = useTheme();\n const [showRichTextEditorFormatting, setShowRichTextEditorFormatting] = useState(false);\n\n const onRenderRichTextEditorIcon = useCallback(\n (isHover: boolean) => (\n <Icon\n iconName={\n isHover || showRichTextEditorFormatting ? 'RichTextEditorButtonIconFilled' : 'RichTextEditorButtonIcon'\n }\n className={richTextFormatButtonIconStyle(theme, !disabled && (isHover || showRichTextEditorFormatting))}\n />\n ),\n [disabled, showRichTextEditorFormatting, theme]\n );\n\n const actionButtons = useMemo(() => {\n return (\n <Stack.Item align=\"end\" className={richTextActionButtonsStackStyle}>\n <Stack horizontal>\n <InputBoxButton\n onRenderIcon={onRenderRichTextEditorIcon}\n onClick={(e) => {\n setShowRichTextEditorFormatting(!showRichTextEditorFormatting);\n editorComponentRef.current?.focus();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n ariaLabel={strings.richTextFormatButtonTooltip}\n tooltipContent={strings.richTextFormatButtonTooltip}\n className={richTextActionButtonsStyle}\n data-testId={'rich-text-input-box-format-button'}\n />\n <Icon iconName=\"RichTextDividerIcon\" className={richTextActionButtonsDividerStyle(theme)} />\n {actionComponents}\n </Stack>\n </Stack.Item>\n );\n }, [\n actionComponents,\n editorComponentRef,\n onRenderRichTextEditorIcon,\n showRichTextEditorFormatting,\n strings.richTextFormatButtonTooltip,\n theme\n ]);\n\n const richTextEditorStyle = useMemo(() => {\n return richTextEditorStyleProps(showRichTextEditorFormatting);\n }, [richTextEditorStyleProps, showRichTextEditorFormatting]);\n\n const onKeyDown = useCallback(\n (ev: React.KeyboardEvent<HTMLElement>) => {\n if (isEnterKeyEventFromCompositionSession(ev)) {\n return;\n }\n if (ev.key === 'Enter' && ev.shiftKey === false && !showRichTextEditorFormatting) {\n ev.preventDefault();\n onEnterKeyDown && onEnterKeyDown();\n } else {\n onTyping?.();\n }\n },\n [onEnterKeyDown, showRichTextEditorFormatting, onTyping]\n );\n\n const useHorizontalLayout = useMemo(() => {\n return (\n !isHorizontalLayoutDisabled &&\n !showRichTextEditorFormatting &&\n /* @conditional-compile-remove(attachment-upload) */ !hasAttachments\n );\n }, [\n isHorizontalLayoutDisabled,\n showRichTextEditorFormatting,\n /* @conditional-compile-remove(attachment-upload) */ hasAttachments\n ]);\n\n return (\n <div\n className={richTextBorderBoxStyle({\n theme: theme,\n disabled: !!disabled\n })}\n >\n {/* This layout is used for the compact view when formatting options are not shown */}\n <Stack\n grow\n horizontal={useHorizontalLayout}\n horizontalAlign={useHorizontalLayout ? 'end' : 'space-between'}\n className={inputBoxContentStackStyle}\n wrap={useHorizontalLayout}\n >\n {/* Fixes the issue when flex box can grow to be bigger than parent */}\n <Stack grow className={inputBoxRichTextStackStyle}>\n <Stack.Item className={inputBoxRichTextStackItemStyle}>\n <RichTextEditor\n content={content}\n initialContent={initialContent}\n placeholderText={placeholderText}\n onChange={onChange}\n onKeyDown={onKeyDown}\n ref={editorComponentRef}\n strings={strings}\n showRichTextEditorFormatting={showRichTextEditorFormatting}\n styles={richTextEditorStyle}\n autoFocus={autoFocus}\n />\n </Stack.Item>\n {\n /* @conditional-compile-remove(attachment-upload) */ onRenderAttachmentUploads &&\n onRenderAttachmentUploads()\n }\n </Stack>\n {actionButtons}\n </Stack>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"RichTextInputBoxComponent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextInputBoxComponent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { ReactNode, useCallback, useEffect, useMemo, useState } from 'react';\nimport { BaseCustomStyles } from '../../types';\nimport { RichTextEditor, RichTextEditorComponentRef, RichTextEditorStyleProps } from './RichTextEditor';\nimport { RichTextSendBoxStrings } from './RichTextSendBox';\nimport { useTheme } from '../../theming';\nimport { Icon, Stack } from '@fluentui/react';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { isEnterKeyEventFromCompositionSession } from '../utils';\nimport {\n richTextActionButtonsDividerStyle,\n richTextActionButtonsStackStyle,\n richTextActionButtonsStyle,\n richTextFormatButtonIconStyle\n} from '../styles/RichTextEditor.styles';\nimport {\n inputBoxContentStackStyle,\n inputBoxRichTextStackItemStyle,\n inputBoxRichTextStackStyle,\n richTextBorderBoxStyle\n} from '../styles/RichTextInputBoxComponent.styles';\nimport type { ContentModelDocument } from 'roosterjs-content-model-types';\n\n/**\n * @private\n */\nexport interface RichTextInputBoxComponentStylesProps extends BaseCustomStyles {}\n\n/**\n * @private\n */\nexport interface RichTextInputBoxComponentProps {\n placeholderText?: string;\n // the initial content of editor that is set when editor is created (e.g. when editing a message)\n initialContent?: string;\n onChange: (newValue?: string) => void;\n onEnterKeyDown?: () => void;\n editorComponentRef: React.RefObject<RichTextEditorComponentRef>;\n // Partial needs to be removed when the rich text editor feature goes to GA\n strings: Partial<RichTextSendBoxStrings>;\n disabled: boolean;\n actionComponents: ReactNode;\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads?: () => JSX.Element;\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments?: boolean;\n // props for min and max height for the rich text editor\n // otherwise the editor will grow to fit the content\n richTextEditorStyleProps: (isExpanded: boolean) => RichTextEditorStyleProps;\n isHorizontalLayoutDisabled?: boolean;\n autoFocus?: 'sendBoxTextField';\n onTyping?: () => Promise<void>;\n}\n\n/**\n * @private\n */\nexport const RichTextInputBoxComponent = (props: RichTextInputBoxComponentProps): JSX.Element => {\n const {\n placeholderText,\n initialContent,\n onChange,\n onEnterKeyDown,\n editorComponentRef,\n disabled,\n strings,\n actionComponents,\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments,\n richTextEditorStyleProps,\n isHorizontalLayoutDisabled = false,\n autoFocus,\n onTyping\n } = props;\n const theme = useTheme();\n // undefined is used to indicate that the rich text editor toolbar state wasn't changed yet\n const [showRichTextEditorFormatting, setShowRichTextEditorFormatting] = useState<boolean | undefined>(undefined);\n const [contentModel, setContentModel] = useState<ContentModelDocument | undefined>(undefined);\n\n const onRenderRichTextEditorIcon = useCallback(\n (isHover: boolean) => {\n const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;\n return (\n <Icon\n iconName={\n isHover || isRichTextEditorToolbarShown ? 'RichTextEditorButtonIconFilled' : 'RichTextEditorButtonIcon'\n }\n className={richTextFormatButtonIconStyle(theme, !disabled && (isHover || isRichTextEditorToolbarShown))}\n />\n );\n },\n [disabled, showRichTextEditorFormatting, theme]\n );\n\n useEffect(() => {\n if (showRichTextEditorFormatting !== undefined) {\n // Focus the editor when toolbar shown/hidden\n editorComponentRef.current?.focus();\n }\n // we don't need execute this useEffect if editorComponentRef is changed\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [showRichTextEditorFormatting]);\n\n const actionButtons = useMemo(() => {\n return (\n <Stack.Item align=\"end\" className={richTextActionButtonsStackStyle}>\n <Stack horizontal>\n <InputBoxButton\n onRenderIcon={onRenderRichTextEditorIcon}\n onClick={(e) => {\n const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;\n setShowRichTextEditorFormatting(!isRichTextEditorToolbarShown);\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n ariaLabel={strings.richTextFormatButtonTooltip}\n tooltipContent={strings.richTextFormatButtonTooltip}\n className={richTextActionButtonsStyle}\n data-testId={'rich-text-input-box-format-button'}\n />\n <Icon iconName=\"RichTextDividerIcon\" className={richTextActionButtonsDividerStyle(theme)} />\n {actionComponents}\n </Stack>\n </Stack.Item>\n );\n }, [\n actionComponents,\n onRenderRichTextEditorIcon,\n showRichTextEditorFormatting,\n strings.richTextFormatButtonTooltip,\n theme\n ]);\n\n const richTextEditorStyle = useMemo(() => {\n return richTextEditorStyleProps(showRichTextEditorFormatting === true);\n }, [richTextEditorStyleProps, showRichTextEditorFormatting]);\n\n const onKeyDown = useCallback(\n (ev: KeyboardEvent) => {\n if (isEnterKeyEventFromCompositionSession(ev)) {\n return;\n }\n const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;\n if (ev.key === 'Enter' && ev.shiftKey === false && !isRichTextEditorToolbarShown) {\n ev.preventDefault();\n onEnterKeyDown && onEnterKeyDown();\n } else {\n onTyping?.();\n }\n },\n [onEnterKeyDown, showRichTextEditorFormatting, onTyping]\n );\n\n const useHorizontalLayout = useMemo(() => {\n const isRichTextEditorToolbarShown = showRichTextEditorFormatting === true;\n return (\n !isHorizontalLayoutDisabled &&\n !isRichTextEditorToolbarShown &&\n /* @conditional-compile-remove(attachment-upload) */ !hasAttachments\n );\n }, [\n isHorizontalLayoutDisabled,\n showRichTextEditorFormatting,\n /* @conditional-compile-remove(attachment-upload) */ hasAttachments\n ]);\n\n const onContentModelUpdate = useCallback((contentModel: ContentModelDocument | undefined) => {\n setContentModel(contentModel);\n }, []);\n\n return (\n <div\n className={richTextBorderBoxStyle({\n theme: theme,\n disabled: !!disabled\n })}\n >\n {/* This layout is used for the compact view when formatting options are not shown */}\n <Stack\n grow\n horizontal={useHorizontalLayout}\n horizontalAlign={useHorizontalLayout ? 'end' : 'space-between'}\n className={inputBoxContentStackStyle}\n wrap={useHorizontalLayout}\n >\n {/* Fixes the issue when flex box can grow to be bigger than parent */}\n <Stack grow className={inputBoxRichTextStackStyle}>\n <Stack.Item className={inputBoxRichTextStackItemStyle}>\n <RichTextEditor\n contentModel={contentModel}\n initialContent={initialContent}\n placeholderText={placeholderText}\n onChange={onChange}\n onKeyDown={onKeyDown}\n ref={editorComponentRef}\n strings={strings}\n showRichTextEditorFormatting={showRichTextEditorFormatting === true}\n styles={richTextEditorStyle}\n autoFocus={autoFocus}\n onContentModelUpdate={onContentModelUpdate}\n />\n </Stack.Item>\n {\n /* @conditional-compile-remove(attachment-upload) */ onRenderAttachmentUploads &&\n onRenderAttachmentUploads()\n }\n </Stack>\n {actionButtons}\n </Stack>\n </div>\n );\n};\n"]}
@@ -52,6 +52,13 @@ export const RichTextSendBox = (props) => {
52
52
  setContentValueOverflow(isMessageTooLong(newValue.length));
53
53
  setContentValue(newValue);
54
54
  }, []);
55
+ const hasContent = useMemo(() => {
56
+ var _a;
57
+ // get plain text content from the editor to check if the message is empty
58
+ // as the content may contain tags even when the content is empty
59
+ const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
60
+ return sanitizeText(contentValue !== null && contentValue !== void 0 ? contentValue : '').length > 0 && sanitizeText(plainTextContent !== null && plainTextContent !== void 0 ? plainTextContent : '').length > 0;
61
+ }, [contentValue]);
55
62
  /* @conditional-compile-remove(attachment-upload) */
56
63
  const toAttachmentMetadata = useCallback((attachmentsWithProgress) => {
57
64
  return attachmentsWithProgress === null || attachmentsWithProgress === void 0 ? void 0 : attachmentsWithProgress.filter((attachment) => {
@@ -67,7 +74,7 @@ export const RichTextSendBox = (props) => {
67
74
  });
68
75
  }, []);
69
76
  const sendMessageOnClick = useCallback(() => {
70
- var _a, _b, _c;
77
+ var _a, _b;
71
78
  if (disabled || contentValueOverflow) {
72
79
  return;
73
80
  }
@@ -80,14 +87,6 @@ export const RichTextSendBox = (props) => {
80
87
  return;
81
88
  }
82
89
  const message = contentValue;
83
- // get plain text content from the editor to check if the message is empty
84
- // as the content may contain tags even when the content is empty
85
- const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
86
- const hasContent = !isContentEmpty({
87
- plainTextContent,
88
- content: message,
89
- placeholder: strings.placeholderText
90
- });
91
90
  // we don't want to send empty messages including spaces, newlines, tabs
92
91
  // Message can be empty if there is a valid attachment upload
93
92
  if (hasContent || /* @conditional-compile-remove(attachment-upload) */ isAttachmentUploadCompleted(attachments)) {
@@ -100,8 +99,8 @@ export const RichTextSendBox = (props) => {
100
99
  type: 'html'
101
100
  });
102
101
  setContentValue('');
103
- (_b = editorComponentRef.current) === null || _b === void 0 ? void 0 : _b.setEmptyContent();
104
- (_c = editorComponentRef.current) === null || _c === void 0 ? void 0 : _c.focus();
102
+ (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.setEmptyContent();
103
+ (_b = editorComponentRef.current) === null || _b === void 0 ? void 0 : _b.focus();
105
104
  }
106
105
  }, [
107
106
  disabled,
@@ -109,7 +108,7 @@ export const RichTextSendBox = (props) => {
109
108
  /* @conditional-compile-remove(attachment-upload) */
110
109
  attachments,
111
110
  contentValue,
112
- strings.placeholderText,
111
+ hasContent,
113
112
  /* @conditional-compile-remove(attachment-upload) */
114
113
  strings.attachmentUploadsPendingError,
115
114
  onSendMessage,
@@ -132,17 +131,6 @@ export const RichTextSendBox = (props) => {
132
131
  attachmentUploadsPendingError,
133
132
  systemMessage
134
133
  ]);
135
- const hasContent = useMemo(() => {
136
- var _a;
137
- // get plain text content from the editor to check if the message is empty
138
- // as the content may contain tags even when the content is empty
139
- const plainTextContent = (_a = editorComponentRef.current) === null || _a === void 0 ? void 0 : _a.getPlainContent();
140
- return !isContentEmpty({
141
- plainTextContent: plainTextContent,
142
- content: contentValue,
143
- placeholder: strings.placeholderText
144
- });
145
- }, [contentValue, strings.placeholderText]);
146
134
  const onRenderSendIcon = useCallback((isHover) => {
147
135
  return (React.createElement(Icon, { iconName: isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend', className: sendIconStyle({
148
136
  theme,
@@ -218,32 +206,10 @@ export const RichTextSendBox = (props) => {
218
206
  }, [attachments]);
219
207
  return (React.createElement(Stack, null,
220
208
  React.createElement(RichTextSendBoxErrors, Object.assign({}, sendBoxErrorsProps)),
221
- React.createElement(RichTextInputBoxComponent
222
- // in case when format bar is shown, the editor is re-rendered that causes the content to be lost
223
- // setting the content will ensure that the latest content is used when editor is re-rendered
224
- , {
225
- // in case when format bar is shown, the editor is re-rendered that causes the content to be lost
226
- // setting the content will ensure that the latest content is used when editor is re-rendered
227
- content: contentValue, placeholderText: strings.placeholderText, autoFocus: autoFocus, onChange: setContent, onEnterKeyDown: sendMessageOnClick, onTyping: onTyping, editorComponentRef: editorComponentRef, strings: strings, disabled: disabled, actionComponents: sendButton, richTextEditorStyleProps: sendBoxRichTextEditorStyle,
209
+ React.createElement(RichTextInputBoxComponent, { placeholderText: strings.placeholderText, autoFocus: autoFocus, onChange: setContent, onEnterKeyDown: sendMessageOnClick, onTyping: onTyping, editorComponentRef: editorComponentRef, strings: strings, disabled: disabled, actionComponents: sendButton, richTextEditorStyleProps: sendBoxRichTextEditorStyle,
228
210
  /* @conditional-compile-remove(attachment-upload) */
229
211
  onRenderAttachmentUploads: onRenderAttachmentUploads,
230
212
  /* @conditional-compile-remove(attachment-upload) */
231
213
  hasAttachments: hasAttachmentUploads })));
232
214
  };
233
- /**
234
- * Checks if the content of the rich text editor is empty.
235
- *
236
- * @param {Object} params - The parameters for the function.
237
- * @param {string | undefined} params.plainTextContent - The plain text content of the editor.
238
- * @param {string} params.content - The HTML content of the editor.
239
- * @param {string} params.placeholder - The placeholder text of the editor.
240
- * @returns {boolean} - True if the content is empty, false otherwise.
241
- */
242
- const isContentEmpty = ({ plainTextContent, content, placeholder }) => {
243
- // RoosterJS returns placeholder text as plain text when the editor is empty and in this case,
244
- // plainTextContent contains only placeholder text but content doesn't include the placeholder text
245
- // this needs to be reviewed after migration to the content model packages.
246
- const plainTextContainsPlaceholderOnly = plainTextContent === placeholder && !content.includes(placeholder);
247
- return plainTextContainsPlaceholderOnly || sanitizeText(plainTextContent !== null && plainTextContent !== void 0 ? plainTextContent : '').length === 0;
248
- };
249
215
  //# sourceMappingURL=RichTextSendBox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from '../Attachment/AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataInProgress, MessageOptions } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(attachment-upload) */\nimport { isAttachmentUploadCompleted, hasIncompleteAttachmentUploads } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends RichTextStrings, SendBoxStrings {}\n\n/**\n * Strings of RichText that can be overridden.\n *\n * @beta\n */\nexport interface RichTextStrings {\n /**\n * Tooltip text for the bold button.\n */\n richTextBoldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n richTextItalicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n richTextUnderlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n richTextBulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n richTextNumberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n richTextIncreaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n richTextDecreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n richTextInsertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n richTextInsertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n richTextInsertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n richTextInsertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n richTextInsertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n richTextInsertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n richTextInsertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n richTextDeleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n richTextDeleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n richTextDeleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n richTextDeleteTableMenu: string;\n /**\n * Text for the rich text toolbar more button.\n */\n richTextToolbarMoreButtonAriaLabel: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachments?: AttachmentMetadataInProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (\n content: string,\n /* @conditional-compile-remove(attachment-upload) */\n options?: MessageOptions\n ) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n /* @conditional-compile-remove(attachment-upload) */\n onCancelAttachmentUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n /* @conditional-compile-remove(attachment-upload) */\n const toAttachmentMetadata = useCallback((attachmentsWithProgress: AttachmentMetadataInProgress[] | undefined) => {\n return attachmentsWithProgress\n ?.filter((attachment) => {\n return !('error' in attachment) && !attachment.error?.message;\n })\n .map((attachment) => {\n return {\n id: attachment.id,\n name: attachment.name,\n url: attachment.url ?? ''\n };\n });\n }, []);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachments)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = contentValue;\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n const hasContent = !isContentEmpty({\n plainTextContent,\n content: message,\n placeholder: strings.placeholderText\n });\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (hasContent || /* @conditional-compile-remove(attachment-upload) */ isAttachmentUploadCompleted(attachments)) {\n onSendMessage(\n message,\n /* @conditional-compile-remove(attachment-upload) */ /* @conditional-compile-remove(rich-text-editor-composite-support) */\n {\n /* @conditional-compile-remove(attachment-upload) */\n attachments: toAttachmentMetadata(attachments),\n /* @conditional-compile-remove(rich-text-editor-composite-support) */\n type: 'html'\n }\n );\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n editorComponentRef.current?.focus();\n }\n }, [\n disabled,\n contentValueOverflow,\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentValue,\n strings.placeholderText,\n /* @conditional-compile-remove(attachment-upload) */\n strings.attachmentUploadsPendingError,\n onSendMessage,\n /* @conditional-compile-remove(attachment-upload) */\n toAttachmentMetadata\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n const hasContent = useMemo(() => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n return !isContentEmpty({\n plainTextContent: plainTextContent,\n content: contentValue,\n placeholder: strings.placeholderText\n });\n }, [contentValue, strings.placeholderText]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [disabled, hasContent, hasErrorMessage, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(attachment-upload) */\n const uploadErrorMessage = attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error?.message;\n return {\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachments={attachments}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachments,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploadCompleted,\n strings.uploading,\n strings.attachmentMoreMenu,\n theme\n ]);\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent,\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads:\n isAttachmentUploadCompleted(attachments),\n hasError: hasErrorMessage,\n disabled\n });\n }, [/* @conditional-compile-remove(attachment-upload) */ attachments, disabled, hasContent, hasErrorMessage]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n );\n }, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const hasAttachmentUploads = useMemo(() => {\n return isAttachmentUploadCompleted(attachments) || hasIncompleteAttachmentUploads(attachments);\n }, [attachments]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n // in case when format bar is shown, the editor is re-rendered that causes the content to be lost\n // setting the content will ensure that the latest content is used when editor is re-rendered\n content={contentValue}\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={setContent}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments={hasAttachmentUploads}\n />\n </Stack>\n );\n};\n\n/**\n * Checks if the content of the rich text editor is empty.\n *\n * @param {Object} params - The parameters for the function.\n * @param {string | undefined} params.plainTextContent - The plain text content of the editor.\n * @param {string} params.content - The HTML content of the editor.\n * @param {string} params.placeholder - The placeholder text of the editor.\n * @returns {boolean} - True if the content is empty, false otherwise.\n */\nconst isContentEmpty = ({\n plainTextContent,\n content,\n placeholder\n}: {\n plainTextContent: string | undefined;\n content: string;\n placeholder: string;\n}): boolean => {\n // RoosterJS returns placeholder text as plain text when the editor is empty and in this case,\n // plainTextContent contains only placeholder text but content doesn't include the placeholder text\n // this needs to be reviewed after migration to the content model packages.\n const plainTextContainsPlaceholderOnly = plainTextContent === placeholder && !content.includes(placeholder);\n return plainTextContainsPlaceholderOnly || sanitizeText(plainTextContent ?? '').length === 0;\n};\n"]}
1
+ {"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { _AttachmentUploadCards } from '../Attachment/AttachmentUploadCards';\n/* @conditional-compile-remove(attachment-upload) */\nimport { AttachmentMetadataInProgress, MessageOptions } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(attachment-upload) */\nimport { isAttachmentUploadCompleted, hasIncompleteAttachmentUploads } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(attachment-upload) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(attachment-upload) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(attachment-upload) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends RichTextStrings, SendBoxStrings {}\n\n/**\n * Strings of RichText that can be overridden.\n *\n * @beta\n */\nexport interface RichTextStrings {\n /**\n * Tooltip text for the bold button.\n */\n richTextBoldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n richTextItalicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n richTextUnderlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n richTextBulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n richTextNumberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n richTextIncreaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n richTextDecreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n richTextInsertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n richTextInsertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n richTextInsertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n richTextInsertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n richTextInsertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n richTextInsertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n richTextInsertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n richTextDeleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n richTextDeleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n richTextDeleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n richTextDeleteTableMenu: string;\n /**\n * Text for the rich text toolbar more button.\n */\n richTextToolbarMoreButtonAriaLabel: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachments?: AttachmentMetadataInProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(attachment-upload) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n * @beta\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (\n content: string,\n /* @conditional-compile-remove(attachment-upload) */\n options?: MessageOptions\n ) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n /* @conditional-compile-remove(attachment-upload) */\n onCancelAttachmentUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(attachment-upload) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n const hasContent = useMemo(() => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n return sanitizeText(contentValue ?? '').length > 0 && sanitizeText(plainTextContent ?? '').length > 0;\n }, [contentValue]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const toAttachmentMetadata = useCallback((attachmentsWithProgress: AttachmentMetadataInProgress[] | undefined) => {\n return attachmentsWithProgress\n ?.filter((attachment) => {\n return !('error' in attachment) && !attachment.error?.message;\n })\n .map((attachment) => {\n return {\n id: attachment.id,\n name: attachment.name,\n url: attachment.url ?? ''\n };\n });\n }, []);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(attachment-upload) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(attachment-upload) */\n if (hasIncompleteAttachmentUploads(attachments)) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n const message = contentValue;\n\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (hasContent || /* @conditional-compile-remove(attachment-upload) */ isAttachmentUploadCompleted(attachments)) {\n onSendMessage(\n message,\n /* @conditional-compile-remove(attachment-upload) */ /* @conditional-compile-remove(rich-text-editor-composite-support) */\n {\n /* @conditional-compile-remove(attachment-upload) */\n attachments: toAttachmentMetadata(attachments),\n /* @conditional-compile-remove(rich-text-editor-composite-support) */\n type: 'html'\n }\n );\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n editorComponentRef.current?.focus();\n }\n }, [\n disabled,\n contentValueOverflow,\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentValue,\n hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n strings.attachmentUploadsPendingError,\n onSendMessage,\n /* @conditional-compile-remove(attachment-upload) */\n toAttachmentMetadata\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(attachment-upload) */\n !!attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [disabled, hasContent, hasErrorMessage, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(attachment-upload) */\n const uploadErrorMessage = attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error?.message;\n return {\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(attachment-upload) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(attachment-upload) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme}>\n <_AttachmentUploadCards\n attachments={attachments}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n attachments,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploadCompleted,\n strings.uploading,\n strings.attachmentMoreMenu,\n theme\n ]);\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent,\n /* @conditional-compile-remove(attachment-upload) */ hasCompletedAttachmentUploads:\n isAttachmentUploadCompleted(attachments),\n hasError: hasErrorMessage,\n disabled\n });\n }, [/* @conditional-compile-remove(attachment-upload) */ attachments, disabled, hasContent, hasErrorMessage]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n );\n }, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(attachment-upload) */\n const hasAttachmentUploads = useMemo(() => {\n return isAttachmentUploadCompleted(attachments) || hasIncompleteAttachmentUploads(attachments);\n }, [attachments]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={setContent}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(attachment-upload) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(attachment-upload) */\n hasAttachments={hasAttachmentUploads}\n />\n </Stack>\n );\n};\n"]}
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { RichTextToolbarPlugin } from '../Plugins/RichTextToolbarPlugin';
3
+ import { RichTextStrings } from '../RichTextSendBox';
4
+ /**
5
+ * Props for {@link RichTextToolbar}.
6
+ *
7
+ * @private
8
+ */
9
+ export interface RichTextToolbarProps {
10
+ plugin: RichTextToolbarPlugin;
11
+ strings: Partial<RichTextStrings>;
12
+ }
13
+ /**
14
+ * A component to display rich text toolbar.
15
+ *
16
+ * @beta
17
+ */
18
+ export declare const RichTextToolbar: (props: RichTextToolbarProps) => JSX.Element;
19
+ //# sourceMappingURL=RichTextToolbar.d.ts.map
@@ -0,0 +1,209 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import React, { useCallback, useEffect, useMemo } from 'react';
4
+ import { CommandBar, ContextualMenuItemType, Icon } from '@fluentui/react';
5
+ import { toolbarButtonStyle, ribbonDividerStyle, ribbonOverflowButtonStyle, richTextToolbarStyle } from '../../styles/RichTextEditor.styles';
6
+ import { useTheme } from '../../../theming';
7
+ import { toggleBold, toggleItalic, toggleUnderline, toggleBullet, toggleNumbering, setIndentation, insertTable } from 'roosterjs-content-model-api';
8
+ import { richTextInsertTableCommandBarItem } from './Table/RichTextInsertTableCommandBarItem';
9
+ const MaxRowsNumber = 5;
10
+ const MaxColumnsNumber = 5;
11
+ /**
12
+ * A component to display rich text toolbar.
13
+ *
14
+ * @beta
15
+ */
16
+ export const RichTextToolbar = (props) => {
17
+ const { plugin, strings } = props;
18
+ const theme = useTheme();
19
+ // need to re-render the buttons when format state changes
20
+ const [formatState, setFormatState] = React.useState(undefined);
21
+ useEffect(() => {
22
+ // update the format state on editor events
23
+ plugin.onFormatChanged = setFormatState;
24
+ }, [plugin]);
25
+ const boldButton = useMemo(() => {
26
+ return getCommandBarItem({
27
+ dataTestId: 'rich-text-toolbar-bold-button',
28
+ key: 'RichTextToolbarBoldButton',
29
+ icon: 'RichTextBoldButtonIcon',
30
+ onClick: () => {
31
+ plugin.onToolbarButtonClick((editor) => {
32
+ toggleBold(editor);
33
+ });
34
+ },
35
+ text: strings.richTextBoldTooltip,
36
+ checked: formatState !== undefined && formatState.isBold === true,
37
+ theme: theme
38
+ });
39
+ }, [formatState, plugin, strings.richTextBoldTooltip, theme]);
40
+ const italicButton = useMemo(() => {
41
+ return getCommandBarItem({
42
+ dataTestId: 'rich-text-toolbar-italic-button',
43
+ key: 'RichTextToolbarItalicButton',
44
+ icon: 'RichTextItalicButtonIcon',
45
+ onClick: () => {
46
+ plugin.onToolbarButtonClick((editor) => {
47
+ toggleItalic(editor);
48
+ });
49
+ },
50
+ text: strings.richTextItalicTooltip,
51
+ checked: formatState !== undefined && (formatState === null || formatState === void 0 ? void 0 : formatState.isItalic) === true,
52
+ theme: theme
53
+ });
54
+ }, [formatState, plugin, strings.richTextItalicTooltip, theme]);
55
+ const underlineButton = useMemo(() => {
56
+ return getCommandBarItem({
57
+ dataTestId: 'rich-text-toolbar-underline-button',
58
+ key: 'RichTextToolbarUnderlineButton',
59
+ icon: 'RichTextUnderlineButtonIcon',
60
+ onClick: () => {
61
+ plugin.onToolbarButtonClick((editor) => {
62
+ toggleUnderline(editor);
63
+ });
64
+ },
65
+ text: strings.richTextUnderlineTooltip,
66
+ checked: formatState !== undefined && (formatState === null || formatState === void 0 ? void 0 : formatState.isUnderline) === true,
67
+ theme: theme
68
+ });
69
+ }, [formatState, plugin, strings.richTextUnderlineTooltip, theme]);
70
+ const bulletListButton = useMemo(() => {
71
+ return getCommandBarItem({
72
+ dataTestId: 'rich-text-toolbar-bullet-list-button',
73
+ key: 'RichTextToolbarBulletListButton',
74
+ icon: 'RichTextBulletListButtonIcon',
75
+ onClick: () => {
76
+ plugin.onToolbarButtonClick((editor) => {
77
+ toggleBullet(editor);
78
+ });
79
+ },
80
+ text: strings.richTextBulletListTooltip,
81
+ checked: formatState !== undefined && (formatState === null || formatState === void 0 ? void 0 : formatState.isBullet) === true,
82
+ theme: theme
83
+ });
84
+ }, [formatState, plugin, strings.richTextBulletListTooltip, theme]);
85
+ const numberListButton = useMemo(() => {
86
+ return getCommandBarItem({
87
+ dataTestId: 'rich-text-toolbar-number-list-button',
88
+ key: 'RichTextToolbarNumberListButton',
89
+ icon: 'RichTextNumberListButtonIcon',
90
+ onClick: () => {
91
+ plugin.onToolbarButtonClick((editor) => {
92
+ toggleNumbering(editor);
93
+ });
94
+ },
95
+ text: strings.richTextNumberListTooltip,
96
+ checked: formatState !== undefined && (formatState === null || formatState === void 0 ? void 0 : formatState.isNumbering) === true,
97
+ theme: theme
98
+ });
99
+ }, [formatState, plugin, strings.richTextNumberListTooltip, theme]);
100
+ const indentDecreaseButton = useMemo(() => {
101
+ return getCommandBarItem({
102
+ dataTestId: 'rich-text-toolbar-indent-decrease-button',
103
+ key: 'RichTextToolbarIndentDecreaseButton',
104
+ icon: 'RichTextIndentDecreaseButtonIcon',
105
+ onClick: () => {
106
+ plugin.onToolbarButtonClick((editor) => {
107
+ setIndentation(editor, 'outdent');
108
+ });
109
+ },
110
+ text: strings.richTextDecreaseIndentTooltip,
111
+ canCheck: false,
112
+ theme: theme
113
+ });
114
+ }, [plugin, strings.richTextDecreaseIndentTooltip, theme]);
115
+ const indentIncreaseButton = useMemo(() => {
116
+ return getCommandBarItem({
117
+ dataTestId: 'rich-text-toolbar-indent-increase-button',
118
+ key: 'RichTextToolbarIndentIncreaseButton',
119
+ icon: 'RichTextIndentIncreaseButtonIcon',
120
+ onClick: () => {
121
+ plugin.onToolbarButtonClick((editor) => {
122
+ setIndentation(editor, 'indent');
123
+ });
124
+ },
125
+ text: strings.richTextIncreaseIndentTooltip,
126
+ canCheck: false,
127
+ theme: theme
128
+ });
129
+ }, [plugin, strings.richTextIncreaseIndentTooltip, theme]);
130
+ const divider = useCallback((key) => {
131
+ return dividerCommandBarItem(theme, key);
132
+ }, [theme]);
133
+ const tableButton = useMemo(() => {
134
+ return richTextInsertTableCommandBarItem(theme, MaxRowsNumber, MaxColumnsNumber, strings, (column, row) => {
135
+ plugin.onToolbarButtonClick((editor) => {
136
+ //add format
137
+ insertTable(editor, column, row);
138
+ // when subMenuProps is used and the menu is dismissed, focus is set to the command bar item that opened the menu
139
+ // set focus to editor on next re-render
140
+ setTimeout(() => {
141
+ editor.focus();
142
+ });
143
+ });
144
+ });
145
+ }, [plugin, strings, theme]);
146
+ const buttons = useMemo(() => {
147
+ return [
148
+ boldButton,
149
+ italicButton,
150
+ underlineButton,
151
+ divider('RichTextRibbonTextFormatDivider'),
152
+ bulletListButton,
153
+ numberListButton,
154
+ indentDecreaseButton,
155
+ indentIncreaseButton,
156
+ divider('RichTextRibbonTableDivider'),
157
+ tableButton
158
+ ];
159
+ }, [
160
+ boldButton,
161
+ italicButton,
162
+ underlineButton,
163
+ divider,
164
+ bulletListButton,
165
+ numberListButton,
166
+ indentDecreaseButton,
167
+ indentIncreaseButton,
168
+ tableButton
169
+ ]);
170
+ const overflowButtonProps = useMemo(() => {
171
+ return {
172
+ ariaLabel: strings.richTextToolbarMoreButtonAriaLabel,
173
+ styles: toolbarButtonStyle(theme),
174
+ menuProps: {
175
+ items: [], // CommandBar will determine items rendered in overflow
176
+ isBeakVisible: false,
177
+ styles: ribbonOverflowButtonStyle(theme)
178
+ }
179
+ };
180
+ }, [strings.richTextToolbarMoreButtonAriaLabel, theme]);
181
+ return (React.createElement(CommandBar, { items: buttons, "data-testid": 'rich-text-editor-toolbar', styles: richTextToolbarStyle, overflowButtonProps: overflowButtonProps }));
182
+ };
183
+ const getCommandBarItem = ({ key, icon, onClick, text, canCheck = true, checked = false, disabled = false, theme, dataTestId }) => {
184
+ return {
185
+ 'data-testid': dataTestId,
186
+ key: key,
187
+ iconProps: { iconName: icon },
188
+ onClick: onClick,
189
+ text: text,
190
+ ariaLabel: text,
191
+ iconOnly: true,
192
+ canCheck: canCheck,
193
+ buttonStyles: Object.assign({}, toolbarButtonStyle(theme)),
194
+ checked: checked,
195
+ disabled: disabled
196
+ };
197
+ };
198
+ const dividerCommandBarItem = (theme, key) => {
199
+ return {
200
+ key: key,
201
+ disabled: true,
202
+ // show the item correctly for the overflow menu
203
+ itemType: ContextualMenuItemType.Divider,
204
+ // this is still needed to remove checkmark icon space even though it is a divider
205
+ canCheck: false,
206
+ onRender: () => React.createElement(Icon, { iconName: "RichTextDividerIcon", className: ribbonDividerStyle(theme) })
207
+ };
208
+ };
209
+ //# sourceMappingURL=RichTextToolbar.js.map