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.

user7637745
  • 965
  • 2
  • 14
  • 27
zhuscat
  • 604
  • 1
  • 6
  • 12
  • Have you checked out https://facebook.github.io/draft-js/docs/advanced-topics-block-styling.html – NooBskie Sep 01 '16 at 07:07
  • Yes. But I still don't how to do it exactly... Becase every block type can be aligned left, center or right. – zhuscat Sep 01 '16 at 08:19
  • you need dynamic block style which not supported by draft now. check my answer in http://stackoverflow.com/questions/39143664/draft-js-unordered-list-bullet-colour – Jiang YD Sep 02 '16 at 03:53

4 Answers4

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

Window0006
  • 11
  • 1
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;
}
.....
Asim
  • 91
  • 2
  • 4
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

PumpkinBreath
  • 831
  • 1
  • 9
  • 22
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;
    }
}
Meraj al Maksud
  • 1,528
  • 2
  • 22
  • 36
strangedk
  • 19
  • 5