I'm wondering how to align text in Draft.js just like on the picture below.
I have searched this several days, but I haven't found the solution.
I'm wondering how to align text in Draft.js just like on the picture below.
I have searched this several days, but I haven't found the solution.
After reading the source code, I found a way for it. Using blockRenderMap
, you can add some custom block types like this:
const blockRenderMap: Record<string, DraftBlockRenderConfig> = {
'header-one-right': {
element: 'h1',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-one'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'header-two-right': {
element: 'h2',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-two'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'header-three-right': {
element: 'h3',
wrapper: <StyleHOC style={{ ...blockStylesMap['header-three'], display: 'flex', justifyContent: 'flex-end' }} />,
},
'unstyled-right': {
element: 'div',
wrapper: <StyleHOC style={{ ...blockStylesMap['unstyled'], display: 'flex', justifyContent: 'flex-end' }} />,
},
};
I use flex
to avoid wasting time to find a away to override the internal style .public-DraftStyleDefault-ltr
.
StyleHOC is quite simple:
const StyleHOC: React.FC<Props> = ({ style, children }) => {
const childrenWithStyle = React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { style });
}
return child;
});
return <>{childrenWithStyle}</>;
};
And then you can toggle the blockType
using RichUtils.toggleBlockType(editorState, blockType)
.
To change block alignment you can:
1- set alignment data
const modifiedBlockState = Modifier.setBlockData(editorState.getCurrentContent(),
editorState.getSelection(),Map({align:'align-center'}));
setEditorState(EditorState.push(modifiedBlockState,'change-block-data'));
2- use it in styling function
/*
JSX
blockStyleFn={ block => block.getData().get('align')
this will return 'align-center|left|right' which will be assigned as a classname
*/
<Editor blockStyleFn={ block => block.getData().get('align')} .../>
//CSS
.align-center div{
text-align: center;
}
.align-right div{
text-align: right;
}
.....
The Editor component has a div with the class .public-DraftStyleDefault-ltr
. This controls the text alignment of each paragraph that you write. As you create more paragraphs, more of these divs are created to contain the text. The text is wrapped in a span element and .public-DraftStyleDefault-ltr
has a default alignment of text-align: left
.
I created some css classes for text-align: left
, text-align: center
, text-align: right
and text-align: justify
and added this basic for loop to my component for creating text alignment buttons.
const textBlock = document.querySelectorAll(".public-DraftStyleDefault-ltr");
for (let i = 0; i < textBlock.length; i++) {
textBlock[i].classList.toggle(this.props.style);
}
this.props.style is the name of the css class that determines the text-alignment I wanted.
It is a pretty basic fix since this way when you click align right say, the whole document is aligned right. I am planning to work on this so only the selected text is aligned so should be able to update this answer soon. Hope it helps in some way
I tried to make almost the same thing. But my trouble was in text-align property, which was correctly set to block span, but .public-DraftStyleDefault-ltr
doesn't react to it.
So, I have made next decision, which get the first div child, and copy it's params:
const paragraphs: any = document.querySelectorAll(".public-DraftStyleDefault-ltr");
for (let i = 0; i < paragraphs.length; i++) {
const paragraph = paragraphs.item(i);
if (paragraph) {
const firstItem = paragraph.querySelectorAll('*').item(0);
// Apply to the parent the first child style
paragraph.style.textAlign = firstItem.style.textAlign;
}
}
© 2022 - 2024 — McMap. All rights reserved.