How to align text in Draft.js
Asked Answered
P

4

14

I'm wondering how to align text in Draft.js just like on the picture below.

text-align

I have searched this several days, but I haven't found the solution.

Parasitism answered 1/9, 2016 at 5:1 Comment(3)
Have you checked out facebook.github.io/draft-js/docs/…Pedigree
Yes. But I still don't how to do it exactly... Becase every block type can be aligned left, center or right.Parasitism
you need dynamic block style which not supported by draft now. check my answer in #39144164Spiral
D
1

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).

Dye answered 20/3, 2021 at 16:33 Comment(0)
F
1

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;
}
.....
Frimaire answered 22/8, 2022 at 3:7 Comment(0)
K
0

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

Kreutzer answered 10/9, 2019 at 14:52 Comment(0)
P
0

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;
    }
}
Paynim answered 18/10, 2019 at 9:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.