@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.
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BLFNaheX.js → ChatMessageComponentAsRichTextEditBox-r0U_8d3I.js} +22 -17
- package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-r0U_8d3I.js.map +1 -0
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BhTpuspw.js → RichTextSendBoxWrapper-DNlYAgO2.js} +6 -8
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BhTpuspw.js.map → RichTextSendBoxWrapper-DNlYAgO2.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-C9I6Mcil.js → index-BLj9R9ms.js} +894 -462
- package/dist/dist-cjs/communication-react/index-BLj9R9ms.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +5 -7
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js +17 -10
- package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js +1 -1
- package/dist/dist-esm/react-components/src/components/InputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.d.ts +9 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.js +29 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/ContextMenuPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +15 -20
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.d.ts +12 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.js +23 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/KeyboardInputPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.d.ts +15 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js +39 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.d.ts +24 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.js +66 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/RichTextToolbarPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.d.ts +20 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.js +46 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.d.ts +29 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +71 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.d.ts +7 -10
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +170 -91
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js +29 -12
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +12 -46
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.d.ts +19 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.js +209 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/RichTextToolbar.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.d.ts +7 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.js +49 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTableCommandBarItem.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/{Buttons → Toolbar}/Table/RichTextInsertTablePane.d.ts +2 -2
- package/dist/dist-esm/react-components/src/components/RichTextEditor/{Buttons → Toolbar}/Table/RichTextInsertTablePane.js +3 -3
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextInsertTablePane.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.d.ts +6 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.js +13 -0
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Toolbar/Table/RichTextToolbarTableIcon.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js +3 -1
- package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js +4 -5
- package/dist/dist-esm/react-components/src/components/styles/RichTextEditor.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.d.ts +37 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +60 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.d.ts +11 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js +95 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils.d.ts +1 -1
- package/dist/dist-esm/react-components/src/components/utils.js +1 -3
- package/dist/dist-esm/react-components/src/components/utils.js.map +1 -1
- package/package.json +6 -8
- package/dist/dist-cjs/communication-react/ChatMessageComponentAsRichTextEditBox-BLFNaheX.js.map +0 -1
- package/dist/dist-cjs/communication-react/index-C9I6Mcil.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.d.ts +0 -7
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js +0 -86
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/RichTextRibbonButtons.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.d.ts +0 -7
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js +0 -55
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTableButton.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextInsertTablePane.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.d.ts +0 -8
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.js +0 -66
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/RichTextTableContextMenu.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.d.ts +0 -9
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.js +0 -56
- package/dist/dist-esm/react-components/src/components/RichTextEditor/Buttons/Table/insertTableAction.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.d.ts +0 -15
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.js +0 -39
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorStringsUtils.js.map +0 -1
@@ -0,0 +1,20 @@
|
|
1
|
+
import type { ContextMenuProvider, IEditor } from 'roosterjs-content-model-types';
|
2
|
+
import { RichTextStrings } from '../RichTextSendBox';
|
3
|
+
import { IContextualMenuItem } from '@fluentui/react';
|
4
|
+
/**
|
5
|
+
* Provides a context menu for editing tables in the rich text editor.
|
6
|
+
*/
|
7
|
+
export declare class TableEditContextMenuProvider implements ContextMenuProvider<IContextualMenuItem> {
|
8
|
+
private editor;
|
9
|
+
strings: Partial<RichTextStrings>;
|
10
|
+
private items;
|
11
|
+
updateStrings(strings: Partial<RichTextStrings>): void;
|
12
|
+
getName(): string;
|
13
|
+
initialize(editor: IEditor): void;
|
14
|
+
/**
|
15
|
+
* Dispose this plugin
|
16
|
+
*/
|
17
|
+
dispose(): void;
|
18
|
+
getContextMenuItems(node: Node): IContextualMenuItem[] | null;
|
19
|
+
}
|
20
|
+
//# sourceMappingURL=TableEditContextMenuProvider.d.ts.map
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { getTableEditContextMenuItems } from '../../utils/RichTextTableUtils';
|
2
|
+
/**
|
3
|
+
* Provides a context menu for editing tables in the rich text editor.
|
4
|
+
*/
|
5
|
+
export class TableEditContextMenuProvider {
|
6
|
+
constructor() {
|
7
|
+
this.editor = null;
|
8
|
+
this.strings = {};
|
9
|
+
this.items = null;
|
10
|
+
}
|
11
|
+
updateStrings(strings) {
|
12
|
+
this.strings = strings;
|
13
|
+
if (this.editor) {
|
14
|
+
this.items = getTableEditContextMenuItems(this.editor, this.strings);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
getName() {
|
18
|
+
return 'TableEditContextMenuProvider';
|
19
|
+
}
|
20
|
+
initialize(editor) {
|
21
|
+
this.editor = editor;
|
22
|
+
this.items = getTableEditContextMenuItems(editor, this.strings);
|
23
|
+
}
|
24
|
+
/**
|
25
|
+
* Dispose this plugin
|
26
|
+
*/
|
27
|
+
dispose() {
|
28
|
+
this.editor = null;
|
29
|
+
}
|
30
|
+
getContextMenuItems(node) {
|
31
|
+
// return this.items;
|
32
|
+
if (this.editor && isTableEditable(this.editor, node)) {
|
33
|
+
return this.items;
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
const isTableEditable = (editor, node) => {
|
41
|
+
const domHelper = editor.getDOMHelper();
|
42
|
+
const td = domHelper.findClosestElementAncestor(node, 'TD,TH');
|
43
|
+
const table = td && domHelper.findClosestElementAncestor(td, 'table');
|
44
|
+
return (table === null || table === void 0 ? void 0 : table.isContentEditable) === true;
|
45
|
+
};
|
46
|
+
//# sourceMappingURL=TableEditContextMenuProvider.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TableEditContextMenuProvider.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/TableEditContextMenuProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E;;GAEG;AACH,MAAM,OAAO,4BAA4B;IAAzC;QACU,WAAM,GAAmB,IAAI,CAAC;QACtC,YAAO,GAA6B,EAAE,CAAC;QAC/B,UAAK,GAAiC,IAAI,CAAC;IAiCrD,CAAC;IA/BC,aAAa,CAAC,OAAiC;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,8BAA8B,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,MAAe;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,4BAA4B,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,mBAAmB,CAAC,IAAU;QAC5B,qBAAqB;QACrB,IAAI,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAED,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,IAAU,EAAW,EAAE;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACxC,MAAM,EAAE,GAAG,SAAS,CAAC,0BAA0B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,EAAE,IAAI,SAAS,CAAC,0BAA0B,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAEtE,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,iBAAiB,MAAK,IAAI,CAAC;AAC3C,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport type { ContextMenuProvider, IEditor } from 'roosterjs-content-model-types';\nimport { RichTextStrings } from '../RichTextSendBox';\nimport { IContextualMenuItem } from '@fluentui/react';\nimport { getTableEditContextMenuItems } from '../../utils/RichTextTableUtils';\n\n/**\n * Provides a context menu for editing tables in the rich text editor.\n */\nexport class TableEditContextMenuProvider implements ContextMenuProvider<IContextualMenuItem> {\n private editor: IEditor | null = null;\n strings: Partial<RichTextStrings> = {};\n private items: IContextualMenuItem[] | null = null;\n\n updateStrings(strings: Partial<RichTextStrings>): void {\n this.strings = strings;\n if (this.editor) {\n this.items = getTableEditContextMenuItems(this.editor, this.strings);\n }\n }\n\n getName(): string {\n return 'TableEditContextMenuProvider';\n }\n\n initialize(editor: IEditor): void {\n this.editor = editor;\n this.items = getTableEditContextMenuItems(editor, this.strings);\n }\n\n /**\n * Dispose this plugin\n */\n dispose(): void {\n this.editor = null;\n }\n\n getContextMenuItems(node: Node): IContextualMenuItem[] | null {\n // return this.items;\n if (this.editor && isTableEditable(this.editor, node)) {\n return this.items;\n } else {\n return null;\n }\n }\n}\n\nconst isTableEditable = (editor: IEditor, node: Node): boolean => {\n const domHelper = editor.getDOMHelper();\n const td = domHelper.findClosestElementAncestor(node, 'TD,TH');\n const table = td && domHelper.findClosestElementAncestor(td, 'table');\n\n return table?.isContentEditable === true;\n};\n"]}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';
|
2
|
+
/**
|
3
|
+
* An update mode to indicate when the content update happens
|
4
|
+
*/
|
5
|
+
export declare enum UpdateEvent {
|
6
|
+
Init = "Init",
|
7
|
+
Dispose = "Dispose",
|
8
|
+
ContentChanged = "ContentChanged",
|
9
|
+
UserInput = "UserInput",
|
10
|
+
Blur = "Blur"
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* A plugin to handle content update
|
14
|
+
*/
|
15
|
+
export declare class UpdateContentPlugin implements EditorPlugin {
|
16
|
+
private editor;
|
17
|
+
private disposer;
|
18
|
+
onUpdate: ((event: UpdateEvent) => void) | null;
|
19
|
+
getName(): string;
|
20
|
+
/**
|
21
|
+
* Initialize this plugin
|
22
|
+
* @param editor The editor instance
|
23
|
+
*/
|
24
|
+
initialize(editor: IEditor): void;
|
25
|
+
dispose(): void;
|
26
|
+
onPluginEvent(event: PluginEvent): void;
|
27
|
+
private onBlur;
|
28
|
+
}
|
29
|
+
//# sourceMappingURL=UpdateContentPlugin.d.ts.map
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
2
|
+
// Licensed under the MIT License.
|
3
|
+
import { PluginEventType } from '../../utils/RichTextEditorUtils';
|
4
|
+
/**
|
5
|
+
* An update mode to indicate when the content update happens
|
6
|
+
*/
|
7
|
+
export var UpdateEvent;
|
8
|
+
(function (UpdateEvent) {
|
9
|
+
UpdateEvent["Init"] = "Init";
|
10
|
+
UpdateEvent["Dispose"] = "Dispose";
|
11
|
+
UpdateEvent["ContentChanged"] = "ContentChanged";
|
12
|
+
UpdateEvent["UserInput"] = "UserInput";
|
13
|
+
UpdateEvent["Blur"] = "Blur";
|
14
|
+
})(UpdateEvent || (UpdateEvent = {}));
|
15
|
+
/**
|
16
|
+
* A plugin to handle content update
|
17
|
+
*/
|
18
|
+
export class UpdateContentPlugin {
|
19
|
+
constructor() {
|
20
|
+
this.editor = null;
|
21
|
+
this.disposer = null;
|
22
|
+
// don't set callback in constructor to be able to update callback without plugin recreation
|
23
|
+
this.onUpdate = null;
|
24
|
+
this.onBlur = () => {
|
25
|
+
if (this.onUpdate === null) {
|
26
|
+
return;
|
27
|
+
}
|
28
|
+
this.onUpdate(UpdateEvent.Blur);
|
29
|
+
};
|
30
|
+
}
|
31
|
+
getName() {
|
32
|
+
return 'UpdateContentPlugin';
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* Initialize this plugin
|
36
|
+
* @param editor The editor instance
|
37
|
+
*/
|
38
|
+
initialize(editor) {
|
39
|
+
this.editor = editor;
|
40
|
+
this.disposer = this.editor.attachDomEvent({
|
41
|
+
blur: { beforeDispatch: this.onBlur }
|
42
|
+
});
|
43
|
+
}
|
44
|
+
dispose() {
|
45
|
+
this.editor = null;
|
46
|
+
if (this.disposer) {
|
47
|
+
this.disposer();
|
48
|
+
this.disposer = null;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
onPluginEvent(event) {
|
52
|
+
if (this.onUpdate === null) {
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
switch (event.eventType) {
|
56
|
+
case PluginEventType.EditorReady:
|
57
|
+
this.onUpdate(UpdateEvent.Init);
|
58
|
+
break;
|
59
|
+
case PluginEventType.BeforeDispose:
|
60
|
+
this.onUpdate(UpdateEvent.Dispose);
|
61
|
+
break;
|
62
|
+
case PluginEventType.ContentChanged:
|
63
|
+
this.onUpdate(UpdateEvent.ContentChanged);
|
64
|
+
break;
|
65
|
+
case PluginEventType.Input:
|
66
|
+
this.onUpdate(UpdateEvent.UserInput);
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
//# sourceMappingURL=UpdateContentPlugin.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"UpdateContentPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE;;GAEG;AACH,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,kCAAmB,CAAA;IACnB,gDAAiC,CAAA;IACjC,sCAAuB,CAAA;IACvB,4BAAa,CAAA;AACf,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED;;GAEG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACU,WAAM,GAAmB,IAAI,CAAC;QAC9B,aAAQ,GAAwB,IAAI,CAAC;QAC7C,4FAA4F;QAC5F,aAAQ,GAA0C,IAAI,CAAC;QAiD/C,WAAM,GAAG,GAAS,EAAE;YAC1B,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IArDC,OAAO;QACL,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,MAAe;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;YACzC,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,MAAM,EAAE;SACtC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,KAAkB;QAC9B,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,QAAQ,KAAK,CAAC,SAAS,EAAE,CAAC;YACxB,KAAK,eAAe,CAAC,WAAW;gBAC9B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBAChC,MAAM;YAER,KAAK,eAAe,CAAC,aAAa;gBAChC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM;YAER,KAAK,eAAe,CAAC,cAAc;gBACjC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;gBAC1C,MAAM;YAER,KAAK,eAAe,CAAC,KAAK;gBACxB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gBACrC,MAAM;QACV,CAAC;IACH,CAAC;CAQF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport { PluginEventType } from '../../utils/RichTextEditorUtils';\n\n/**\n * An update mode to indicate when the content update happens\n */\nexport enum UpdateEvent {\n Init = 'Init',\n Dispose = 'Dispose',\n ContentChanged = 'ContentChanged',\n UserInput = 'UserInput',\n Blur = 'Blur'\n}\n\n/**\n * A plugin to handle content update\n */\nexport class UpdateContentPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n // don't set callback in constructor to be able to update callback without plugin recreation\n onUpdate: ((event: UpdateEvent) => void) | null = null;\n\n getName(): string {\n return 'UpdateContentPlugin';\n }\n\n /**\n * Initialize this plugin\n * @param editor The editor instance\n */\n initialize(editor: IEditor): void {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n blur: { beforeDispatch: this.onBlur }\n });\n }\n\n dispose(): void {\n this.editor = null;\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n }\n\n onPluginEvent(event: PluginEvent): void {\n if (this.onUpdate === null) {\n return;\n }\n switch (event.eventType) {\n case PluginEventType.EditorReady:\n this.onUpdate(UpdateEvent.Init);\n break;\n\n case PluginEventType.BeforeDispose:\n this.onUpdate(UpdateEvent.Dispose);\n break;\n\n case PluginEventType.ContentChanged:\n this.onUpdate(UpdateEvent.ContentChanged);\n break;\n\n case PluginEventType.Input:\n this.onUpdate(UpdateEvent.UserInput);\n break;\n }\n }\n\n private onBlur = (): void => {\n if (this.onUpdate === null) {\n return;\n }\n this.onUpdate(UpdateEvent.Blur);\n };\n}\n"]}
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import {
|
2
|
+
import { RichTextStrings } from './RichTextSendBox';
|
3
|
+
import type { ContentModelDocument } from 'roosterjs-content-model-types';
|
3
4
|
/**
|
4
|
-
*
|
5
|
+
* Style props for {@link RichTextEditor}.
|
5
6
|
*
|
6
7
|
* @private
|
7
8
|
*/
|
@@ -16,20 +17,16 @@ export interface RichTextEditorStyleProps {
|
|
16
17
|
*/
|
17
18
|
export interface RichTextEditorProps {
|
18
19
|
initialContent?: string;
|
19
|
-
content?: string;
|
20
20
|
onChange: (newValue?: string) => void;
|
21
|
-
onKeyDown?: (ev:
|
21
|
+
onKeyDown?: (ev: KeyboardEvent) => void;
|
22
|
+
onContentModelUpdate?: (contentModel: ContentModelDocument | undefined) => void;
|
23
|
+
contentModel?: ContentModelDocument | undefined;
|
22
24
|
placeholderText?: string;
|
23
|
-
strings: Partial<
|
25
|
+
strings: Partial<RichTextStrings>;
|
24
26
|
showRichTextEditorFormatting: boolean;
|
25
27
|
styles: RichTextEditorStyleProps;
|
26
28
|
autoFocus?: 'sendBoxTextField';
|
27
29
|
}
|
28
|
-
/**
|
29
|
-
* Props for {@link RichTextEditor}.
|
30
|
-
*
|
31
|
-
* @beta
|
32
|
-
*/
|
33
30
|
/**
|
34
31
|
* Represents a reference to the RichTextEditor component.
|
35
32
|
*/
|
@@ -1,27 +1,33 @@
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
2
2
|
// Licensed under the MIT License.
|
3
|
-
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
4
|
-
import {
|
5
|
-
import { Editor } from 'roosterjs-editor-core';
|
6
|
-
import { CompatibleContentPosition, CompatibleGetContentMode, CompatiblePositionType } from 'roosterjs-editor-types-compatible';
|
7
|
-
import { Rooster, createUpdateContentPlugin, UpdateMode, createRibbonPlugin, Ribbon, createContextMenuPlugin } from 'roosterjs-react';
|
8
|
-
import { ribbonButtonStyle, ribbonOverflowButtonStyle, ribbonStyle, richTextEditorWrapperStyle, richTextEditorStyle } from '../styles/RichTextEditor.styles';
|
3
|
+
import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
4
|
+
import { richTextEditorWrapperStyle, richTextEditorStyle } from '../styles/RichTextEditor.styles';
|
9
5
|
import { useTheme } from '../../theming';
|
10
|
-
import { ribbonButtons } from './Buttons/RichTextRibbonButtons';
|
11
6
|
import { isDarkThemed } from '../../theming/themeUtils';
|
12
|
-
import { ribbonButtonsStrings } from '../utils/RichTextEditorStringsUtils';
|
13
|
-
import { createTableEditMenuProvider } from './Buttons/Table/RichTextTableContextMenu';
|
14
7
|
import CopyPastePlugin from './Plugins/CopyPastePlugin';
|
8
|
+
import { createModelFromHtml, Editor, exportContent } from 'roosterjs-content-model-core';
|
9
|
+
import { createParagraph, createSelectionMarker, setSelection } from 'roosterjs-content-model-dom';
|
10
|
+
import { KeyboardInputPlugin } from './Plugins/KeyboardInputPlugin';
|
11
|
+
import { AutoFormatPlugin, EditPlugin, PastePlugin, ShortcutPlugin } from 'roosterjs-content-model-plugins';
|
12
|
+
import { UpdateContentPlugin, UpdateEvent } from './Plugins/UpdateContentPlugin';
|
13
|
+
import { RichTextToolbar } from './Toolbar/RichTextToolbar';
|
14
|
+
import { RichTextToolbarPlugin } from './Plugins/RichTextToolbarPlugin';
|
15
|
+
import { ContextMenuPlugin } from './Plugins/ContextMenuPlugin';
|
16
|
+
import { TableEditContextMenuProvider } from './Plugins/TableEditContextMenuProvider';
|
17
|
+
import { borderApplier, dataSetApplier } from '../utils/RichTextEditorUtils';
|
18
|
+
import { ContextualMenu } from '@fluentui/react';
|
19
|
+
import PlaceholderPlugin from './Plugins/PlaceholderPlugin';
|
15
20
|
/**
|
16
21
|
* A component to wrap RoosterJS Rich Text Editor.
|
17
22
|
*
|
18
23
|
* @beta
|
19
24
|
*/
|
20
25
|
export const RichTextEditor = React.forwardRef((props, ref) => {
|
21
|
-
const { initialContent, onChange, placeholderText, strings, showRichTextEditorFormatting,
|
26
|
+
const { initialContent, onChange, placeholderText, strings, showRichTextEditorFormatting, autoFocus, onKeyDown, onContentModelUpdate, contentModel } = props;
|
22
27
|
const editor = useRef(null);
|
23
|
-
const
|
28
|
+
const editorDiv = useRef(null);
|
24
29
|
const theme = useTheme();
|
30
|
+
const [contextMenuProps, setContextMenuProps] = useState(null);
|
25
31
|
useImperativeHandle(ref, () => {
|
26
32
|
return {
|
27
33
|
focus() {
|
@@ -31,108 +37,181 @@ export const RichTextEditor = React.forwardRef((props, ref) => {
|
|
31
37
|
},
|
32
38
|
setEmptyContent() {
|
33
39
|
if (editor.current) {
|
34
|
-
editor
|
40
|
+
// remove all content from the editor and update the model
|
41
|
+
// ContentChanged event will be sent by RoosterJS automatically
|
42
|
+
editor.current.formatContentModel((model) => {
|
43
|
+
model.blocks = [];
|
44
|
+
return true;
|
45
|
+
});
|
46
|
+
//reset content model
|
47
|
+
onContentModelUpdate && onContentModelUpdate(undefined);
|
35
48
|
}
|
36
49
|
},
|
37
50
|
getPlainContent() {
|
38
|
-
|
39
|
-
|
51
|
+
if (editor.current) {
|
52
|
+
return exportContent(editor.current, 'PlainTextFast');
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
return undefined;
|
56
|
+
}
|
40
57
|
}
|
41
58
|
};
|
59
|
+
}, [onContentModelUpdate]);
|
60
|
+
const toolbarPlugin = React.useMemo(() => {
|
61
|
+
return new RichTextToolbarPlugin();
|
42
62
|
}, []);
|
43
|
-
const
|
44
|
-
return
|
45
|
-
}, []);
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
focusAndUpdateContent(editorValue, contentValue.current);
|
53
|
-
}
|
54
|
-
else if (initialContent !== undefined && initialContent.length > 0) {
|
55
|
-
// changing layout in rich text send box cause the editor to be recreated
|
56
|
-
// to keep the content, we need to set messageContent to the current content
|
57
|
-
focusAndUpdateContent(editorValue, initialContent);
|
58
|
-
}
|
59
|
-
editor.current = editorValue;
|
60
|
-
return editorValue;
|
61
|
-
},
|
62
|
-
// trigger force editor reset when strings are changed to update context menu strings
|
63
|
-
// see RosterJS documentation for 'editorCreator' for more details
|
64
|
-
// the editorCreator callback shouldn't be updated when the initialContent is changed
|
65
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
66
|
-
[strings]);
|
67
|
-
const placeholderPlugin = React.useMemo(() => {
|
68
|
-
return new Watermark('');
|
63
|
+
const isDarkThemedValue = useMemo(() => {
|
64
|
+
return isDarkThemed(theme);
|
65
|
+
}, [theme]);
|
66
|
+
useEffect(() => {
|
67
|
+
var _a;
|
68
|
+
(_a = editor.current) === null || _a === void 0 ? void 0 : _a.setDarkModeState(isDarkThemedValue);
|
69
|
+
}, [isDarkThemedValue]);
|
70
|
+
const placeholderPlugin = useMemo(() => {
|
71
|
+
return new PlaceholderPlugin('');
|
69
72
|
}, []);
|
70
73
|
useEffect(() => {
|
71
74
|
if (placeholderText !== undefined) {
|
72
|
-
placeholderPlugin.
|
75
|
+
placeholderPlugin.updatePlaceholder(placeholderText);
|
73
76
|
}
|
74
77
|
}, [placeholderPlugin, placeholderText]);
|
75
|
-
const
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
78
|
+
const toolbar = useMemo(() => {
|
79
|
+
return React.createElement(RichTextToolbar, { plugin: toolbarPlugin, strings: strings });
|
80
|
+
}, [strings, toolbarPlugin]);
|
81
|
+
const updatePlugin = useMemo(() => {
|
82
|
+
return new UpdateContentPlugin();
|
83
|
+
}, []);
|
84
|
+
useEffect(() => {
|
85
|
+
// don't set callback in plugin constructor to update callback without plugin recreation
|
86
|
+
updatePlugin.onUpdate = (event) => {
|
87
|
+
if (editor.current === null) {
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
if (event === UpdateEvent.Blur || event === UpdateEvent.Dispose) {
|
91
|
+
onContentModelUpdate && onContentModelUpdate(editor.current.getContentModelCopy('disconnected'));
|
92
|
+
}
|
93
|
+
else {
|
94
|
+
onChange && onChange(exportContent(editor.current));
|
95
|
+
}
|
96
|
+
};
|
97
|
+
}, [onChange, onContentModelUpdate, updatePlugin]);
|
98
|
+
const keyboardInputPlugin = useMemo(() => {
|
99
|
+
return new KeyboardInputPlugin();
|
100
|
+
}, []);
|
101
|
+
useEffect(() => {
|
102
|
+
// don't set callback in plugin constructor to update callback without plugin recreation
|
103
|
+
keyboardInputPlugin.onKeyDown = onKeyDown;
|
104
|
+
}, [keyboardInputPlugin, onKeyDown]);
|
105
|
+
const tableContextMenuPlugin = useMemo(() => {
|
106
|
+
return new TableEditContextMenuProvider();
|
107
|
+
}, []);
|
108
|
+
useEffect(() => {
|
109
|
+
tableContextMenuPlugin.updateStrings(strings);
|
110
|
+
}, [tableContextMenuPlugin, strings]);
|
111
|
+
const onContextMenuRender = useCallback((container, items, onDismiss) => {
|
112
|
+
setContextMenuProps({
|
113
|
+
items: items,
|
114
|
+
target: container,
|
115
|
+
onDismiss: onDismiss
|
82
116
|
});
|
117
|
+
}, []);
|
118
|
+
const onContextMenuDismiss = useCallback(() => {
|
119
|
+
setContextMenuProps(null);
|
120
|
+
}, []);
|
121
|
+
const plugins = useMemo(() => {
|
122
|
+
const contentEdit = new EditPlugin();
|
123
|
+
// AutoFormatPlugin previously was a part of the edit plugin
|
124
|
+
const autoFormatPlugin = new AutoFormatPlugin({ autoBullet: true, autoNumbering: true, autoLink: true });
|
83
125
|
const copyPastePlugin = new CopyPastePlugin();
|
126
|
+
const roosterPastePlugin = new PastePlugin(false);
|
127
|
+
const shortcutPlugin = new ShortcutPlugin();
|
128
|
+
const contextMenuPlugin = new ContextMenuPlugin(onContextMenuRender, onContextMenuDismiss);
|
84
129
|
return [
|
85
|
-
contentEdit,
|
86
130
|
placeholderPlugin,
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
copyPastePlugin
|
131
|
+
keyboardInputPlugin,
|
132
|
+
contentEdit,
|
133
|
+
autoFormatPlugin,
|
134
|
+
updatePlugin,
|
135
|
+
copyPastePlugin,
|
136
|
+
roosterPastePlugin,
|
137
|
+
toolbarPlugin,
|
138
|
+
shortcutPlugin,
|
139
|
+
// contextPlugin and tableEditMenuProvider allow to show insert/delete menu for the table
|
140
|
+
contextMenuPlugin,
|
141
|
+
tableContextMenuPlugin
|
92
142
|
];
|
93
|
-
}, [
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
143
|
+
}, [
|
144
|
+
onContextMenuRender,
|
145
|
+
onContextMenuDismiss,
|
146
|
+
placeholderPlugin,
|
147
|
+
keyboardInputPlugin,
|
148
|
+
updatePlugin,
|
149
|
+
toolbarPlugin,
|
150
|
+
tableContextMenuPlugin
|
151
|
+
]);
|
152
|
+
useEffect(() => {
|
153
|
+
var _a;
|
154
|
+
const initialModel = createEditorInitialModel(initialContent, contentModel);
|
155
|
+
if (editorDiv.current) {
|
156
|
+
editor.current = new Editor(editorDiv.current, {
|
157
|
+
inDarkMode: isDarkThemedValue,
|
158
|
+
// doNotAdjustEditorColor is used to disable default color and background color for Rooster component
|
159
|
+
doNotAdjustEditorColor: true,
|
160
|
+
// TODO: confirm the color during inline images implementation
|
161
|
+
imageSelectionBorderColor: 'blue',
|
162
|
+
plugins: plugins,
|
163
|
+
initialModel: initialModel,
|
164
|
+
defaultModelToDomOptions: {
|
165
|
+
formatApplierOverride: {
|
166
|
+
// apply border and dataset formats for table
|
167
|
+
border: borderApplier,
|
168
|
+
dataset: dataSetApplier
|
169
|
+
}
|
102
170
|
}
|
103
|
-
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
171
|
+
});
|
172
|
+
}
|
173
|
+
if (autoFocus === 'sendBoxTextField') {
|
174
|
+
(_a = editor.current) === null || _a === void 0 ? void 0 : _a.focus();
|
175
|
+
}
|
176
|
+
return () => {
|
177
|
+
if (editor.current) {
|
178
|
+
editor.current.dispose();
|
179
|
+
editor.current = null;
|
180
|
+
}
|
111
181
|
};
|
182
|
+
// don't update the editor on deps update as everything is handled in separate hooks or plugins
|
183
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
112
184
|
}, []);
|
113
185
|
return (React.createElement("div", { "data-testid": 'rich-text-editor-wrapper' },
|
114
|
-
showRichTextEditorFormatting &&
|
186
|
+
showRichTextEditorFormatting && toolbar,
|
115
187
|
React.createElement("div", { className: richTextEditorWrapperStyle(theme, !showRichTextEditorFormatting) },
|
116
|
-
React.createElement(
|
117
|
-
|
118
|
-
imageSelectionBorderColor: 'blue',
|
119
|
-
// doNotAdjustEditorColor is used to fix the default background color for Rooster component
|
120
|
-
doNotAdjustEditorColor: true, "data-testid": 'rooster-rich-text-editor',
|
121
|
-
// if we don't use 'allowKeyboardEventPropagation' only the enter key is caught
|
122
|
-
onKeyDown: props.onKeyDown, focusOnInit: autoFocus === 'sendBoxTextField' }))));
|
188
|
+
React.createElement("div", { ref: editorDiv, tabIndex: 0, role: "textbox", "aria-multiline": "true", "data-testid": 'rooster-rich-text-editor', className: richTextEditorStyle(props.styles) })),
|
189
|
+
contextMenuProps && React.createElement(ContextualMenu, Object.assign({}, contextMenuProps, { calloutProps: { isBeakVisible: false } }))));
|
123
190
|
});
|
124
|
-
const
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
191
|
+
const createEditorInitialModel = (initialContent, contentModel) => {
|
192
|
+
if (contentModel) {
|
193
|
+
// contentModel is the current content of the editor
|
194
|
+
return contentModel;
|
195
|
+
}
|
196
|
+
else {
|
197
|
+
const initialContentValue = initialContent;
|
198
|
+
const initialModel = initialContentValue && initialContentValue.length > 0 ? createModelFromHtml(initialContentValue) : undefined;
|
199
|
+
if (initialModel && initialModel.blocks.length > 0) {
|
200
|
+
// lastBlock should have blockType = paragraph, otherwise add a new paragraph
|
201
|
+
// to set focus to the end of the content
|
202
|
+
let lastBlock = initialModel.blocks[initialModel.blocks.length - 1];
|
203
|
+
if ((lastBlock === null || lastBlock === void 0 ? void 0 : lastBlock.blockType) === 'Paragraph') {
|
204
|
+
// now lastBlock is paragraph
|
205
|
+
}
|
206
|
+
else {
|
207
|
+
lastBlock = createParagraph(true);
|
208
|
+
initialModel.blocks.push(lastBlock);
|
209
|
+
}
|
210
|
+
const marker = createSelectionMarker();
|
211
|
+
lastBlock.segments.push(marker);
|
212
|
+
setSelection(initialModel, marker);
|
213
|
+
}
|
214
|
+
return initialModel;
|
136
215
|
}
|
137
216
|
};
|
138
217
|
//# sourceMappingURL=RichTextEditor.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RichTextEditor.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';\nimport { ContentEdit, Watermark } from 'roosterjs-editor-plugins';\nimport { Editor } from 'roosterjs-editor-core';\nimport type { DefaultFormat, EditorOptions, IEditor } from 'roosterjs-editor-types-compatible';\nimport {\n CompatibleContentPosition,\n CompatibleGetContentMode,\n CompatiblePositionType\n} from 'roosterjs-editor-types-compatible';\nimport {\n Rooster,\n createUpdateContentPlugin,\n UpdateMode,\n createRibbonPlugin,\n Ribbon,\n createContextMenuPlugin\n} from 'roosterjs-react';\nimport {\n ribbonButtonStyle,\n ribbonOverflowButtonStyle,\n ribbonStyle,\n richTextEditorWrapperStyle,\n richTextEditorStyle\n} from '../styles/RichTextEditor.styles';\nimport { useTheme } from '../../theming';\nimport { ribbonButtons } from './Buttons/RichTextRibbonButtons';\nimport { RichTextSendBoxStrings } from './RichTextSendBox';\nimport { isDarkThemed } from '../../theming/themeUtils';\nimport { ribbonButtonsStrings } from '../utils/RichTextEditorStringsUtils';\nimport { createTableEditMenuProvider } from './Buttons/Table/RichTextTableContextMenu';\nimport CopyPastePlugin from './Plugins/CopyPastePlugin';\n\n/**\n * Props for {@link RichTextEditor}.\n *\n * @private\n */\nexport interface RichTextEditorStyleProps {\n minHeight: string;\n maxHeight: string;\n}\n\n/**\n * Props for {@link RichTextEditor}.\n *\n * @private\n */\nexport interface RichTextEditorProps {\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 onKeyDown?: (ev: React.KeyboardEvent<HTMLElement>) => void;\n placeholderText?: string;\n strings: Partial<RichTextSendBoxStrings>;\n showRichTextEditorFormatting: boolean;\n styles: RichTextEditorStyleProps;\n autoFocus?: 'sendBoxTextField';\n}\n\n/**\n * Props for {@link RichTextEditor}.\n *\n * @beta\n */\n/**\n * Represents a reference to the RichTextEditor component.\n */\nexport interface RichTextEditorComponentRef {\n /**\n * Sets focus on the RichTextEditor component.\n */\n focus: () => void;\n\n /**\n * Sets the content of the RichTextEditor component to an empty string.\n */\n setEmptyContent: () => void;\n\n /**\n * Retrieves the plain text content of the RichTextEditor component.\n * @returns The plain text content of the RichTextEditor component, or undefined if the editor isn't available.\n */\n getPlainContent: () => string | undefined;\n}\n\n/**\n * A component to wrap RoosterJS Rich Text Editor.\n *\n * @beta\n */\nexport const RichTextEditor = React.forwardRef<RichTextEditorComponentRef, RichTextEditorProps>((props, ref) => {\n const { initialContent, onChange, placeholderText, strings, showRichTextEditorFormatting, content, autoFocus } =\n props;\n const editor = useRef<IEditor | null>(null);\n const contentValue = useRef<string | undefined>(content);\n const theme = useTheme();\n useImperativeHandle(\n ref,\n () => {\n return {\n focus() {\n if (editor.current) {\n editor.current.focus();\n }\n },\n setEmptyContent() {\n if (editor.current) {\n editor.current.setContent('');\n }\n },\n getPlainContent() {\n return editor?.current?.getContent(CompatibleGetContentMode.PlainTextFast);\n }\n };\n },\n []\n );\n\n const ribbonPlugin = React.useMemo(() => {\n return createRibbonPlugin();\n }, []);\n\n const editorCreator = useCallback(\n (div: HTMLDivElement, options: EditorOptions) => {\n const editorValue = new Editor(div, options);\n // this is to fix issue when editor is created or re-rendered and has existing text\n // Content model package has a correct behavior and this fix can be deleted\n if (contentValue.current !== undefined && contentValue.current.length > 0) {\n // in case if initialContent is not empty, RoosterJS doesn't set caret position to the end.\n focusAndUpdateContent(editorValue, contentValue.current);\n } else if (initialContent !== undefined && initialContent.length > 0) {\n // changing layout in rich text send box cause the editor to be recreated\n // to keep the content, we need to set messageContent to the current content\n focusAndUpdateContent(editorValue, initialContent);\n }\n editor.current = editorValue;\n return editorValue;\n },\n // trigger force editor reset when strings are changed to update context menu strings\n // see RosterJS documentation for 'editorCreator' for more details\n // the editorCreator callback shouldn't be updated when the initialContent is changed\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [strings]\n );\n\n const placeholderPlugin = React.useMemo(() => {\n return new Watermark('');\n }, []);\n\n useEffect(() => {\n if (placeholderText !== undefined) {\n placeholderPlugin.updateWatermark(placeholderText);\n }\n }, [placeholderPlugin, placeholderText]);\n\n const plugins = useMemo(() => {\n // contextPlugin and tableEditMenuProvider allow to show insert/delete menu for the table\n const contextPlugin = createContextMenuPlugin();\n const tableEditMenuProvider = createTableEditMenuProvider(strings);\n const contentEdit = new ContentEdit();\n const updateContentPlugin = createUpdateContentPlugin(\n UpdateMode.OnContentChangedEvent | UpdateMode.OnUserInput,\n (content: string) => {\n onChange && onChange(content);\n }\n );\n const copyPastePlugin = new CopyPastePlugin();\n return [\n contentEdit,\n placeholderPlugin,\n updateContentPlugin,\n ribbonPlugin,\n contextPlugin,\n tableEditMenuProvider,\n copyPastePlugin\n ];\n }, [onChange, placeholderPlugin, ribbonPlugin, strings]);\n\n const ribbon = useMemo(() => {\n const buttons = ribbonButtons(theme);\n\n return (\n <Ribbon\n styles={ribbonStyle}\n buttons={buttons}\n plugin={ribbonPlugin}\n overflowButtonProps={{\n styles: ribbonButtonStyle(theme),\n menuProps: {\n items: [], // CommandBar will determine items rendered in overflow\n isBeakVisible: false,\n styles: ribbonOverflowButtonStyle(theme)\n }\n }}\n strings={ribbonButtonsStrings(strings)}\n data-testid={'rich-text-editor-ribbon'}\n />\n );\n }, [strings, ribbonPlugin, theme]);\n\n const defaultFormat: DefaultFormat = useMemo(() => {\n // without setting any styles, text input is not handled properly for tables (when insert or paste one in the editor)\n // because of https://github.com/microsoft/roosterjs/blob/14dbb947e3ae94580109cbd05e48ceb05327c4dc/packages/roosterjs-editor-core/lib/corePlugins/TypeInContainerPlugin.ts#L75\n // this issue is fixed for content model package\n return {\n backgroundColor: 'transparent'\n };\n }, []);\n\n return (\n <div data-testid={'rich-text-editor-wrapper'}>\n {showRichTextEditorFormatting && ribbon}\n <div className={richTextEditorWrapperStyle(theme, !showRichTextEditorFormatting)}>\n <Rooster\n defaultFormat={defaultFormat}\n inDarkMode={isDarkThemed(theme)}\n plugins={plugins}\n className={richTextEditorStyle(props.styles)}\n editorCreator={editorCreator}\n // TODO: confirm the color during inline images implementation\n imageSelectionBorderColor={'blue'}\n // doNotAdjustEditorColor is used to fix the default background color for Rooster component\n doNotAdjustEditorColor={true}\n data-testid={'rooster-rich-text-editor'}\n // if we don't use 'allowKeyboardEventPropagation' only the enter key is caught\n onKeyDown={props.onKeyDown}\n focusOnInit={autoFocus === 'sendBoxTextField'}\n />\n </div>\n </div>\n );\n});\n\nconst focusAndUpdateContent = (editor: Editor, content: string): void => {\n // setting focus before setting content, works for Chrome and Edge but not Safari\n editor.setContent(content);\n // this is a recommended way (by RoosterJS team) to set focus at the end of the text\n // RoosterJS v9 has this issue fixed and this code can be removed\n // CompatibleContentPosition.DomEnd shouldn't be used here as it set focus after the editor div\n editor.insertContent('<span id=\"focus-position-span\"></span>', { position: CompatibleContentPosition.End });\n const elements = editor.queryElements('#focus-position-span');\n if (elements.length > 0) {\n const placeholder = editor.queryElements('#focus-position-span')[0];\n editor.select(placeholder, CompatiblePositionType.Before);\n placeholder.remove();\n }\n};\n"]}
|
1
|
+
{"version":3,"file":"RichTextEditor.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport { richTextEditorWrapperStyle, richTextEditorStyle } from '../styles/RichTextEditor.styles';\nimport { useTheme } from '../../theming';\nimport { RichTextStrings } from './RichTextSendBox';\nimport { isDarkThemed } from '../../theming/themeUtils';\nimport CopyPastePlugin from './Plugins/CopyPastePlugin';\nimport type { ContentModelDocument, EditorPlugin, IEditor } from 'roosterjs-content-model-types';\nimport { createModelFromHtml, Editor, exportContent } from 'roosterjs-content-model-core';\nimport { createParagraph, createSelectionMarker, setSelection } from 'roosterjs-content-model-dom';\nimport { KeyboardInputPlugin } from './Plugins/KeyboardInputPlugin';\nimport { AutoFormatPlugin, EditPlugin, PastePlugin, ShortcutPlugin } from 'roosterjs-content-model-plugins';\nimport { UpdateContentPlugin, UpdateEvent } from './Plugins/UpdateContentPlugin';\nimport { RichTextToolbar } from './Toolbar/RichTextToolbar';\nimport { RichTextToolbarPlugin } from './Plugins/RichTextToolbarPlugin';\nimport { ContextMenuPlugin } from './Plugins/ContextMenuPlugin';\nimport { TableEditContextMenuProvider } from './Plugins/TableEditContextMenuProvider';\nimport { borderApplier, dataSetApplier } from '../utils/RichTextEditorUtils';\nimport { ContextualMenu, IContextualMenuItem, IContextualMenuProps } from '@fluentui/react';\nimport PlaceholderPlugin from './Plugins/PlaceholderPlugin';\n\n/**\n * Style props for {@link RichTextEditor}.\n *\n * @private\n */\nexport interface RichTextEditorStyleProps {\n minHeight: string;\n maxHeight: string;\n}\n\n/**\n * Props for {@link RichTextEditor}.\n *\n * @private\n */\nexport interface RichTextEditorProps {\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 onKeyDown?: (ev: KeyboardEvent) => void;\n // update the current content of the rich text editor\n onContentModelUpdate?: (contentModel: ContentModelDocument | undefined) => void;\n contentModel?: ContentModelDocument | undefined;\n placeholderText?: string;\n strings: Partial<RichTextStrings>;\n showRichTextEditorFormatting: boolean;\n styles: RichTextEditorStyleProps;\n autoFocus?: 'sendBoxTextField';\n}\n\n/**\n * Represents a reference to the RichTextEditor component.\n */\nexport interface RichTextEditorComponentRef {\n /**\n * Sets focus on the RichTextEditor component.\n */\n focus: () => void;\n\n /**\n * Sets the content of the RichTextEditor component to an empty string.\n */\n setEmptyContent: () => void;\n\n /**\n * Retrieves the plain text content of the RichTextEditor component.\n * @returns The plain text content of the RichTextEditor component, or undefined if the editor isn't available.\n */\n getPlainContent: () => string | undefined;\n}\n\n/**\n * A component to wrap RoosterJS Rich Text Editor.\n *\n * @beta\n */\nexport const RichTextEditor = React.forwardRef<RichTextEditorComponentRef, RichTextEditorProps>((props, ref) => {\n const {\n initialContent,\n onChange,\n placeholderText,\n strings,\n showRichTextEditorFormatting,\n autoFocus,\n onKeyDown,\n onContentModelUpdate,\n contentModel\n } = props;\n const editor = useRef<IEditor | null>(null);\n const editorDiv = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const [contextMenuProps, setContextMenuProps] = useState<IContextualMenuProps | null>(null);\n\n useImperativeHandle(\n ref,\n () => {\n return {\n focus() {\n if (editor.current) {\n editor.current.focus();\n }\n },\n setEmptyContent() {\n if (editor.current) {\n // remove all content from the editor and update the model\n // ContentChanged event will be sent by RoosterJS automatically\n editor.current.formatContentModel((model: ContentModelDocument): boolean => {\n model.blocks = [];\n return true;\n });\n //reset content model\n onContentModelUpdate && onContentModelUpdate(undefined);\n }\n },\n getPlainContent() {\n if (editor.current) {\n return exportContent(editor.current, 'PlainTextFast');\n } else {\n return undefined;\n }\n }\n };\n },\n [onContentModelUpdate]\n );\n\n const toolbarPlugin = React.useMemo(() => {\n return new RichTextToolbarPlugin();\n }, []);\n\n const isDarkThemedValue = useMemo(() => {\n return isDarkThemed(theme);\n }, [theme]);\n\n useEffect(() => {\n editor.current?.setDarkModeState(isDarkThemedValue);\n }, [isDarkThemedValue]);\n\n const placeholderPlugin = useMemo(() => {\n return new PlaceholderPlugin('');\n }, []);\n\n useEffect(() => {\n if (placeholderText !== undefined) {\n placeholderPlugin.updatePlaceholder(placeholderText);\n }\n }, [placeholderPlugin, placeholderText]);\n\n const toolbar = useMemo(() => {\n return <RichTextToolbar plugin={toolbarPlugin} strings={strings} />;\n }, [strings, toolbarPlugin]);\n\n const updatePlugin = useMemo(() => {\n return new UpdateContentPlugin();\n }, []);\n\n useEffect(() => {\n // don't set callback in plugin constructor to update callback without plugin recreation\n updatePlugin.onUpdate = (event: string) => {\n if (editor.current === null) {\n return;\n }\n if (event === UpdateEvent.Blur || event === UpdateEvent.Dispose) {\n onContentModelUpdate && onContentModelUpdate(editor.current.getContentModelCopy('disconnected'));\n } else {\n onChange && onChange(exportContent(editor.current));\n }\n };\n }, [onChange, onContentModelUpdate, updatePlugin]);\n\n const keyboardInputPlugin = useMemo(() => {\n return new KeyboardInputPlugin();\n }, []);\n\n useEffect(() => {\n // don't set callback in plugin constructor to update callback without plugin recreation\n keyboardInputPlugin.onKeyDown = onKeyDown;\n }, [keyboardInputPlugin, onKeyDown]);\n\n const tableContextMenuPlugin = useMemo(() => {\n return new TableEditContextMenuProvider();\n }, []);\n\n useEffect(() => {\n tableContextMenuPlugin.updateStrings(strings);\n }, [tableContextMenuPlugin, strings]);\n\n const onContextMenuRender = useCallback(\n (container: HTMLElement, items: IContextualMenuItem[], onDismiss: () => void): void => {\n setContextMenuProps({\n items: items,\n target: container,\n onDismiss: onDismiss\n });\n },\n []\n );\n\n const onContextMenuDismiss = useCallback((): void => {\n setContextMenuProps(null);\n }, []);\n\n const plugins: EditorPlugin[] = useMemo(() => {\n const contentEdit = new EditPlugin();\n // AutoFormatPlugin previously was a part of the edit plugin\n const autoFormatPlugin = new AutoFormatPlugin({ autoBullet: true, autoNumbering: true, autoLink: true });\n const copyPastePlugin = new CopyPastePlugin();\n const roosterPastePlugin = new PastePlugin(false);\n const shortcutPlugin = new ShortcutPlugin();\n const contextMenuPlugin = new ContextMenuPlugin(onContextMenuRender, onContextMenuDismiss);\n return [\n placeholderPlugin,\n keyboardInputPlugin,\n contentEdit,\n autoFormatPlugin,\n updatePlugin,\n copyPastePlugin,\n roosterPastePlugin,\n toolbarPlugin,\n shortcutPlugin,\n // contextPlugin and tableEditMenuProvider allow to show insert/delete menu for the table\n contextMenuPlugin,\n tableContextMenuPlugin\n ];\n }, [\n onContextMenuRender,\n onContextMenuDismiss,\n placeholderPlugin,\n keyboardInputPlugin,\n updatePlugin,\n toolbarPlugin,\n tableContextMenuPlugin\n ]);\n\n useEffect(() => {\n const initialModel = createEditorInitialModel(initialContent, contentModel);\n if (editorDiv.current) {\n editor.current = new Editor(editorDiv.current, {\n inDarkMode: isDarkThemedValue,\n // doNotAdjustEditorColor is used to disable default color and background color for Rooster component\n doNotAdjustEditorColor: true,\n // TODO: confirm the color during inline images implementation\n imageSelectionBorderColor: 'blue',\n plugins: plugins,\n initialModel: initialModel,\n defaultModelToDomOptions: {\n formatApplierOverride: {\n // apply border and dataset formats for table\n border: borderApplier,\n dataset: dataSetApplier\n }\n }\n });\n }\n\n if (autoFocus === 'sendBoxTextField') {\n editor.current?.focus();\n }\n\n return () => {\n if (editor.current) {\n editor.current.dispose();\n editor.current = null;\n }\n };\n // don't update the editor on deps update as everything is handled in separate hooks or plugins\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div data-testid={'rich-text-editor-wrapper'}>\n {showRichTextEditorFormatting && toolbar}\n <div className={richTextEditorWrapperStyle(theme, !showRichTextEditorFormatting)}>\n {/* div that is used by Rooster JS as a parent of the editor */}\n <div\n ref={editorDiv}\n tabIndex={0}\n role=\"textbox\"\n aria-multiline=\"true\"\n data-testid={'rooster-rich-text-editor'}\n className={richTextEditorStyle(props.styles)}\n />\n </div>\n {contextMenuProps && <ContextualMenu {...contextMenuProps} calloutProps={{ isBeakVisible: false }} />}\n </div>\n );\n});\n\nconst createEditorInitialModel = (\n initialContent?: string,\n contentModel?: ContentModelDocument\n): ContentModelDocument | undefined => {\n if (contentModel) {\n // contentModel is the current content of the editor\n return contentModel;\n } else {\n const initialContentValue = initialContent;\n const initialModel =\n initialContentValue && initialContentValue.length > 0 ? createModelFromHtml(initialContentValue) : undefined;\n if (initialModel && initialModel.blocks.length > 0) {\n // lastBlock should have blockType = paragraph, otherwise add a new paragraph\n // to set focus to the end of the content\n let lastBlock = initialModel.blocks[initialModel.blocks.length - 1];\n if (lastBlock?.blockType === 'Paragraph') {\n // now lastBlock is paragraph\n } else {\n lastBlock = createParagraph(true);\n initialModel.blocks.push(lastBlock);\n }\n const marker = createSelectionMarker();\n lastBlock.segments.push(marker);\n setSelection(initialModel, marker);\n }\n return initialModel;\n }\n};\n"]}
|
package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextInputBoxComponent.d.ts
CHANGED
@@ -13,7 +13,6 @@ export interface RichTextInputBoxComponentStylesProps extends BaseCustomStyles {
|
|
13
13
|
export interface RichTextInputBoxComponentProps {
|
14
14
|
placeholderText?: string;
|
15
15
|
initialContent?: string;
|
16
|
-
content?: string;
|
17
16
|
onChange: (newValue?: string) => void;
|
18
17
|
onEnterKeyDown?: () => void;
|
19
18
|
editorComponentRef: React.RefObject<RichTextEditorComponentRef>;
|