draft-js icon indicating copy to clipboard operation
draft-js copied to clipboard

Need contentBlock with style inline-block

Open Marais opened this issue 8 years ago • 26 comments

Feature: I need to have the text in one line. I.e. I need the a custom block to be inserted inline-block. If I change the styles in the css file, IE11 doesn't work.

Example: image

Are there future plans to support this?

Marais avatar Oct 27 '16 17:10 Marais

Anyone found a workaround for this?

aehlke avatar Nov 13 '16 22:11 aehlke

need this feature as well.

mkozhukharenko avatar Dec 12 '16 13:12 mkozhukharenko

I moved to https://github.com/ianstormtaylor/slate which is similar but supports inline blocks. Not quite as fully-baked as DraftJS yet, but it's promisingly active.

aehlke avatar Dec 12 '16 18:12 aehlke

@Marais I think you can try the example below to create your custom content block, then add custom render logic in blockRendererFn to handle your custom contentblock as make it display as inline block.. https://github.com/draft-js-plugins/draft-js-plugins/blob/master/draft-js-sticker-plugin/src/modifiers/addSticker.js#L19

mzbac avatar Dec 12 '16 22:12 mzbac

@mzajac you forgot to attach an example

mkozhukharenko avatar Dec 13 '16 13:12 mkozhukharenko

@mkozhukharenko :sob: Sorry about that, I updated the example..

mzbac avatar Dec 13 '16 23:12 mzbac

@mzbac your example just shows how to insert custom blocks as you described. However the sticker is not inline. @aehlke @Marais can you describe your use case for this? Then we could help other people which have a similar problem.

I don't found any use cases when you must use inline blocks which cannot solved with custom blocks/atomic blocks, decorators and entities. But I were really interested to those to improve draft.js.

However I'm not sure if blocks can be inline-block without creating some other issues with the editor.

aight8 avatar Jan 15 '17 19:01 aight8

@aight8 ruby text, with a button inside <rt> to edit the ruby text.

aehlke avatar Jan 15 '17 23:01 aehlke

Oh wow that's really something on which I would never have come.. However I can't really comprehend why this must be implemented on this way. Are you really sure you can't implement this with entities and decorators? Because this inline-block method looks like a little bit hackish/out-of-concept of blocks for me.

aight8 avatar Jan 16 '17 08:01 aight8

@aight8 I gave it a try with entities, I forget exactly the issues I ran into first. One is that <ruby>/<rt> are not well-supported as-is in contenteditable (and not well-supported by draft-js), which is why I had to use the button to edit the <rt> contents. At which point, I believe I needed the inline-block.

aehlke avatar Jan 17 '17 02:01 aehlke

@aight8 my use case for custom inline block component is giving the user the ability to select a placeholder (static text item) to be inserted into the editor at the cursor position as they write a message. Example: https://cl.ly/kHFC The desired UI is to style the placeholder inline-block like a pill and then be able to click on it and open a popover and an input for fallback text for if first_name is not available in the example. I started off creating an Entity that is immutable and using a decorator to render the Placeholder component. Then a function that uses Entity.create() to create the placeholder entity and then update the EditorState etc. This worked well for the placeholder, but not the popover and fallback input. So inside my Placeholder component I'm using Entity.mergeData() to add the fallback text data to the Entity. So I know I can get the fallback data on the entity where it needs to go, but I can't focus the input. I get an error:

[Deprecation] The behavior that Selection.addRange() merges existing Range and the specified Range was removed. See https://www.chromestatus.com/features/6680566019653632 for more details.
setDraftEditorSelection.js:123 

I learned about custom block components and that you can pass props to them if the component has interaction (like the TeX example that is often referenced) and then set the Editor to readOnly false while interacting with the custom block component. (like hellendag recommends in issue 449 Since you can't pass props to decorator components (to be able to set the state of the Editor from inside the decorate component) and I read that rendering things inside the component that are not received through props is a bad idea, I tried using custom block components. But then ran into an issue where the placeholders I'm inserting at the cursor are not inline-block. And changing all the custom block component wrappers to display: inline-block doesn't work because it is actually rendered in a new block below the block where the cursor was before insert. So I need to create editor UI and interaction very similar to the TeX example, except I need my component to be rendered inline. Seems so close to working and maybe I'm overlooking something. If anyone has any ideas for how to accomplish this I'd greatly appreciate it!

rblakejohnson avatar May 03 '17 22:05 rblakejohnson

@aight8 I also need the ability to insert tokens/pills, same as @rblakejohnson. I too headed down the path of using entities and custom-component decorators, but the tokens themselves are not supposed to be editable/selectable/etc. in the same way as other text—they should be treated like atomic blocks. For instance, think of dragging and dropping from a menu of variables (with fixed immutable names) into an email template editor. The cursor should jump over these tokens, rather than moving into their content.

FWIW, I don't think this is a crazy/non-obvious use case! Are there any solutions/workarounds? Thanks!

yang avatar Jul 23 '17 07:07 yang

I'm running into issues here as well. I don't know if I'm doing something wrong, but I'm trying to get a similar pill thing going on. However, I run into a lot of issues by using entities:

draftjs-1

draftjs-2

draftjs-3

When I first started trying to implement this using blocks, everything seemed to be fine, but they were always wrapped in a <figure> element which is a block. I'm getting tempted to try using blocks again, but overriding those <figure> elements to be display: inline-block or something.

Anyone from this thread have any updates/solutions yet?

GRardB avatar Oct 14 '17 21:10 GRardB

@GRardB I didn't find a solution for this. We ended up switching to QuillJS for our editors and ran into different problems :) but it's been fine. Anyway, I just wanted to point out that changing all the custom block component wrappers to display: inline-block doesn't work because they actually render in a new block below the block where the cursor was before insert.

rblakejohnson avatar Oct 16 '17 17:10 rblakejohnson

Thanks for the response, @rblakejohnson! I tested out display: inline-block shortly after my comment, and things did indeed not work. My main issue was that I was no longer able to add newlines between paragraphs, hah!

I ended up switching over to Slate, and it worked like a charm for what we needed!

GRardB avatar Oct 16 '17 18:10 GRardB

@GRardB how to disable to add newlines?

wzuhyl avatar Dec 04 '17 13:12 wzuhyl

@wzuhyl Hey, not sure I understand your question. I wasn't able to get draft-js to work how I wanted, so I switched to the Slate library.

GRardB avatar Dec 04 '17 14:12 GRardB

An update: we tried to move to Slate to resolve the lack of inline-block content, but ran into serious performance issues with larger document sizes in Slate and have since been forced back to DraftJS. We're now designing around the lack of inline-block as Slate was unusable with large documents.

aehlke avatar Dec 04 '17 17:12 aehlke

Anyone find a solution for this issue?

athomann avatar Jun 01 '18 21:06 athomann

Any solution for this?

demianrosas avatar May 20 '19 13:05 demianrosas

I'm currently trying to implement something like this with entities and decorators and running into a log of issues. My use case is for inserting shortcodes like in Wordpress, where the underlying text contains [ref id="xxx"], but the editor should display a "pill" component with a nice label so the user never needs to see the underlying codes which can get quite long.

purplesquirrels avatar Dec 13 '19 04:12 purplesquirrels

four years later this is not possible?

UXDart avatar Mar 26 '20 15:03 UXDart

I resolved this. Had the same issue. What i found by this huge pile of same comments on this thread and also from my own findings that block is not for use as an inline thing. It creates new block, new section of content and it's not part of another block.

i create entity to hold all the data and insert text with that entity

  const selectionState = editorState.getSelection();
  const contentState = editorState.getCurrentContent();

  const contentStateWithEmojiEntity = contentState.createEntity('EMOJI', 'SEGMENTED', emoji);
  const entityKey = contentStateWithEmojiEntity.getLastCreatedEntityKey();

  const newContentStateWithAddedColon = Modifier.insertText(contentState, selectionState, emoji.colons, null, entityKey);
  const newEditorState = EditorState.push(editorState, newContentStateWithAddedColon, 'insert-characters');

  onChange({newEditorState});

Then i have emoji decorator which get's needed data from entity and renders inline emoji.

const entityData = contentState.getEntity(entityKey).getData();

i know that for emoji i was able just to insert the native symbol yet i want to have option to use images, gifs and other stuff as 'emoji' that's why i needed inline "block".

liesislukas avatar Jun 10 '20 13:06 liesislukas

No resolution here!?!?!?!?!?!

agrohs avatar Jun 30 '21 20:06 agrohs

Also looking for a solution for this

gijsmin avatar Sep 16 '21 10:09 gijsmin

Would be great to see this on a roadmap..

tdurnford avatar Feb 16 '22 03:02 tdurnford