Skip to content

Commit 62477ca

Browse files
Update paddings and theme handling for rich text editor toolbar (#4852)
1 parent f77faed commit 62477ca

File tree

72 files changed

+54
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+54
-17
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "RTE",
5+
"comment": "Update paddings and theme handling for rich text editor toolbar",
6+
"packageName": "@azure/communication-react",
7+
"email": "98852890+vhuseinova-msft@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "fix",
4+
"workstream": "RTE",
5+
"comment": "Update paddings and theme handling for rich text editor toolbar",
6+
"packageName": "@azure/communication-react",
7+
"email": "98852890+vhuseinova-msft@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}

packages/react-components/src/components/RichTextEditor/RichTextEditor.tsx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ import { RichTextToolbarPlugin } from './Plugins/RichTextToolbarPlugin';
2424
import { ContextMenuPlugin } from './Plugins/ContextMenuPlugin';
2525
import { TableEditContextMenuProvider } from './Plugins/TableEditContextMenuProvider';
2626
import { borderApplier, dataSetApplier, DefaultSanitizers } from '../utils/RichTextEditorUtils';
27-
import { ContextualMenu, IContextualMenuItem, IContextualMenuProps } from '@fluentui/react';
27+
import { ContextualMenu, IContextualMenuItem, IContextualMenuProps, Theme } from '@fluentui/react';
2828
import { PlaceholderPlugin } from './Plugins/PlaceholderPlugin';
29+
import { getFormatState, setDirection } from 'roosterjs-content-model-api';
2930

3031
/**
3132
* Style props for {@link RichTextEditor}.
@@ -107,6 +108,7 @@ export const RichTextEditor = React.forwardRef<RichTextEditorComponentRef, RichT
107108
const editorDiv = useRef<HTMLDivElement>(null);
108109
const theme = useTheme();
109110
const [contextMenuProps, setContextMenuProps] = useState<IContextualMenuProps | null>(null);
111+
const previousThemeDirection = useRef(themeDirection(theme));
110112

111113
useImperativeHandle(ref, () => {
112114
return {
@@ -313,10 +315,26 @@ export const RichTextEditor = React.forwardRef<RichTextEditorComponentRef, RichT
313315
// eslint-disable-next-line react-hooks/exhaustive-deps
314316
}, [theme, plugins]);
315317

318+
useEffect(() => {
319+
const themeDirectionValue = themeDirection(theme);
320+
// check that editor exists and theme was actually changed
321+
// as format.direction will be undefined if setDirection is not called
322+
if (editor.current && previousThemeDirection.current !== themeDirectionValue) {
323+
const format = getFormatState(editor.current);
324+
if (format.direction !== themeDirectionValue) {
325+
// should be set after the hook where editor is created as the editor might be null
326+
// setDirection will cause the focus change back to the editor and this might not be what we want to do (autoFocus prop)
327+
// that's why it's not part of the create editor hook
328+
setDirection(editor.current, theme.rtl ? 'rtl' : 'ltr');
329+
}
330+
previousThemeDirection.current = themeDirectionValue;
331+
}
332+
}, [theme]);
333+
316334
return (
317335
<div data-testid={'rich-text-editor-wrapper'}>
318336
{showRichTextEditorFormatting && toolbar}
319-
<div className={richTextEditorWrapperStyle(theme, !showRichTextEditorFormatting)}>
337+
<div className={richTextEditorWrapperStyle(theme)}>
320338
{/* div that is used by Rooster JS as a parent of the editor */}
321339
<div
322340
id="richTextSendBox"
@@ -366,3 +384,7 @@ const setSelectionAfterLastSegment = (model: ReadonlyContentModelBlockGroup, blo
366384
block.segments.push(marker);
367385
setSelection(model, marker);
368386
};
387+
388+
const themeDirection = (theme: Theme): 'rtl' | 'ltr' => {
389+
return theme.rtl ? 'rtl' : 'ltr';
390+
};

packages/react-components/src/components/styles/RichTextEditor.styles.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,15 @@ export const richTextEditorStyle = (props: { minHeight: string; maxHeight: strin
1515
minHeight: props.minHeight,
1616
maxHeight: props.maxHeight,
1717
maxWidth: '100%',
18-
// this is needed to fix an issue when text has some indentation, indentation uses blockquote tag and
19-
// it gets both horizontal margins because of the user agent stylesheet
20-
// remove this code when RoosterJS content model packages are used as they use different approach for indentation
21-
'& blockquote': {
22-
marginInlineEnd: '0'
23-
}
18+
paddingTop: '0.5rem'
2419
});
2520
};
2621

2722
/**
2823
* @private
2924
*/
30-
export const richTextEditorWrapperStyle = (theme: Theme, addTopOffset: boolean): string => {
25+
export const richTextEditorWrapperStyle = (theme: Theme): string => {
3126
return mergeStyles({
32-
paddingTop: `${addTopOffset ? '0.5rem' : '0'}`,
3327
paddingInlineStart: `0.75rem`,
3428
paddingInlineEnd: `0.75rem`,
3529
maxWidth: '100%',
@@ -116,7 +110,7 @@ const ribbonOverflowButtonRootStyles = (theme: Theme): IStyle => {
116110
},
117111
'.ribbon-table-button-regular-icon': {
118112
display: 'inline-block',
119-
margin: '-0.25rem 0.25rem 0 0.25rem',
113+
margin: '0 0.25rem 0 0.25rem',
120114
width: '1.25rem',
121115
height: '1.25rem'
122116
},
@@ -157,8 +151,8 @@ const ribbonButtonRootStyles = (iconColor: string, hoverIconColor: string): ISty
157151
*/
158152
export const toolbarButtonStyle = (theme: Theme): Partial<IButtonStyles> => {
159153
return {
160-
icon: { color: theme.palette.neutralPrimary, height: 'auto' },
161-
menuIcon: { color: theme.palette.neutralPrimary, height: 'auto' },
154+
icon: { color: theme.palette.neutralPrimary, height: 'auto', paddingTop: '0.25rem' },
155+
menuIcon: { color: theme.palette.neutralPrimary, height: 'auto', paddingTop: '0.25rem' },
162156
root: { minWidth: 'auto', backgroundColor: 'transparent' },
163157
rootChecked: ribbonButtonRootStyles(theme.palette.themePrimary, theme.palette.themePrimary),
164158
// there is a bug for Android where the press action is considered hover sometimes
@@ -200,14 +194,14 @@ const ribbonTableButtonRootStyles = (theme: Theme, isSelected: boolean): IStyle
200194
'.ribbon-table-button-regular-icon': {
201195
width: '1.25rem',
202196
height: '1.25rem',
203-
margin: '-0.25rem 0.25rem 0 0.25rem',
197+
margin: '0 0.25rem 0 0.25rem',
204198
color: theme.palette.neutralPrimary,
205199
display: isSelected ? 'none' : 'inline-block'
206200
},
207201
'.ribbon-table-button-filled-icon': {
208202
width: '1.25rem',
209203
height: '1.25rem',
210-
margin: '-0.25rem 0.25rem 0 0.25rem',
204+
margin: '0 0.25rem 0 0.25rem',
211205
color: theme.palette.themePrimary,
212206
display: isSelected ? 'inline-block' : 'none'
213207
}
@@ -222,7 +216,7 @@ export const ribbonDividerStyle = (theme: Theme): string => {
222216
return mergeStyles({
223217
color: theme.palette.neutralQuaternaryAlt,
224218
margin: '0 -0.5rem',
225-
paddingTop: '0.5rem'
219+
paddingTop: '0.25rem'
226220
});
227221
};
228222

@@ -231,7 +225,7 @@ export const ribbonDividerStyle = (theme: Theme): string => {
231225
*/
232226
export const richTextToolbarStyle: Partial<ICommandBarStyles> = {
233227
// Override for the default white color of the Ribbon component
234-
root: { backgroundColor: 'transparent', padding: '0px' }
228+
root: { backgroundColor: 'transparent', padding: '0.25rem 0 0 0', height: '2rem' }
235229
};
236230

237231
/**

packages/react-components/tests/browser/RichTextInputBoxComponent.spec.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,8 @@ const addList = async (listButtonLabel: string, component: Locator): Promise<voi
106106
await editor.pressSequentially('First submenu');
107107
await editor.press('Enter');
108108
await component.getByLabel('Decrease indent').click();
109+
// the tests are fast and sometimes UI state for "decrease indent" button doesn't have enough time to update
110+
// this call is to fix it
111+
editor.click();
109112
await editor.pressSequentially('Third line');
110113
};

0 commit comments

Comments
 (0)