For the most part, I have a WYSIWYG text editor up and running properly. However, in the same regard when you open a new Google doc, and you see that the "text-align-left" in the formatting toolbar is already toggled on, I am trying to accomplish the same with my editor.
I've tried to implement this via using a useEffect that toggles the left alignment on render, but it doesn't persist after I click the editor. I believe this has something to do with the focusEditor callback, but I am not sure how to properly manage it. (Code and notes below)
(Also, I realize the desired behavior is technically default as is, however, I'd like for it to be toggled on until another alignment style is selected.)
Current behavior: When the component renders, the align left button is active. When I click the text editor, the style toggles off.
Expected behavior: When I click on the editor to focus, the "ALIGN_LEFT" button/style should remain active until an alternate alignment style is selected.
const editor = useRef<Editor>(null);
const focusEditor = useCallback(() => {
editor?.current?.focus();
}, [editor]);
// This useEffect should set ALIGN_LEFT as a default style
useEffect(() => {
setEditorState(RichUtils.toggleInlineStyle(editorState, 'ALIGN_LEFT'));
// eslint-disable-next-line
}, []);
const toggleBlockType = (blockType: string, index: number) => {
return (e: MouseEvent) => {
e.preventDefault();
const newState = RichUtils.toggleBlockType(editorState, blockType);
setEditorState(newState);
};
};
const toggleInlineStyle = (inlineStyle: string, index: number) => {
return (e: MouseEvent) => {
e.preventDefault();
let newState = RichUtils.toggleInlineStyle(
editorState,
inlineStyle,
);
const activeStyles = editorState.getCurrentInlineStyle().toObject();
if (inlineStyle === 'ALIGN_LEFT' && activeStyles['ALIGN_RIGHT']) {
newState = RichUtils.toggleInlineStyle(newState, 'ALIGN_RIGHT');
}
if (inlineStyle === 'ALIGN_LEFT' && activeStyles['ALIGN_CENTER']) {
newState = RichUtils.toggleInlineStyle(
newState,
'ALIGN_CENTER',
);
}
if (inlineStyle === 'ALIGN_CENTER' && activeStyles['ALIGN_RIGHT']) {
newState = RichUtils.toggleInlineStyle(newState, 'ALIGN_RIGHT');
}
if (inlineStyle === 'ALIGN_CENTER' && activeStyles['ALIGN_LEFT']) {
newState = RichUtils.toggleInlineStyle(newState, 'ALIGN_LEFT');
}
if (inlineStyle === 'ALIGN_RIGHT' && activeStyles['ALIGN_CENTER']) {
newState = RichUtils.toggleInlineStyle(
newState,
'ALIGN_CENTER',
);
}
if (inlineStyle === 'ALIGN_RIGHT' && activeStyles['ALIGN_LEFT']) {
newState = RichUtils.toggleInlineStyle(newState, 'ALIGN_LEFT');
}
setEditorState(newState);
};
};
...
const selection = editorState.getSelection();
const blockType = editorState
.getCurrentContent()
.getBlockForKey(selection.getStartKey())
.getType();
const isStyleActivated = (style: string): boolean => {
return !!editorState.getCurrentInlineStyle().toObject()[style];
};
return (
<div>
<div>
{styleFormattingOptions.map((option: any, index) => (
<ToggleButton
key={index}
onMouseDown={toggleInlineStyle(option.name, index)}
active={isStyleActivated(option.name)}
>
<FontAwesomeIcon icon={option.icon} />
</ToggleButton>
))}
{blockFormattingOptions.map((option: any, index) => (
<ToggleButton
key={index}
active={blockType === option.name}
onMouseDown={toggleBlockType(option.name, index)}
>
<FontAwesomeIcon icon={option.icon} />
</ToggleButton>
))}
</div>
<InputContainer onClick={focusEditor}>
<Editor
// @ts-ignore
customStyleMap={customStyleMap}
editorState={editorState}
onChange={setEditorState}
placeholder="Click here to add a description..."
blockRendererFn={renderBlock}
handleKeyCommand={handleKeyCommand}
keyBindingFn={inlineCodeKeyBind}
ref={editor}
/>
</InputContainer>
</div>
)