We're using DraftJS to insert an <a>
around some selected text in an editor.
Current state
It presently works by wrapping the anchor tag around the highlighted text.
E.g., for this text: Foo bar foo
.
If the user highlights "bar", our editor will render <a href='http://...'>bar</a>
The current code to alter the content state:
private addLinkToSelection(url: RawDraftContentStateWithSelection, color?: string, underline?: boolean) {
const {editorState} = this.props;
const selectionState = editorState.getSelection();
let entity = null;
if (url) {
entity = Entity.create('LINK', 'MUTABLE', {url, color, underline});
}
const update = RichUtils.toggleLink(editorState, selectionState, entity);
this.props.onChange(update);
}
And the actual Link that is getting rendered:
const Link = (props, style = null) => {
const {url} = props.contentState.getEntity(props.entityKey).getData();
return (
<a href={url} style={style}>
{props.children}
</a>
);
};
Desired state
Our product owner has asked that the links retain any other elements which may be selected.
E.g., for text with an image: Foo bar <img src='http:\...'/> foo
.
If the user highlights "bar" and the image, we want to render the anchor tag around both of them. I.e. <a href='http://...'>bar <img src='http:\...'/> </a>
.
However, our code is stripping anything that isn't text-- the <img>
disappears.
Any help is greatly appreciated.
Update
If this helps any, here's the custom decorator which creates the Link:
private decorate(editorState: EditorState) {
if (editorState.getDecorator()) {
return editorState;
}
const decorator = new CompositeDecorator([{
strategy: findLinkEntitiesFactory(editorState),
component: (props) => {
const data = props.contentState.getEntity(props.entityKey).getData() as LinkData;
return Link(props, {
color: (data.color == null ? this.props.linkColor : data.color) || undefined,
textDecoration: (data.underline == null ? this.props.linkUnderline : data.underline) ? 'underline' : 'none'
}
);
}
}]);
return EditorState.set(editorState, {decorator});
}
function findLinkEntitiesFactory(state: EditorState) {
return (contentBlock: ContentBlock, callback) => {
contentBlock.findEntityRanges(
linkEntityFilterFactory(state),
callback
);
};
}
from How to display children components in an Anchor tag in DraftJS?
No comments:
Post a Comment