lexical
lexical copied to clipboard
How to keep styles between lines?
Lexical version: 0.14.5
The current behavior
As mentioned in #5620, I am looking for a way to keep both formats and styles between lines. There was an update in #5822 with logic to persist formats (bold, italic, underline) between paragraphs and it works great. One part of the issue remains that I can't persist CSS styles in new paragraphs.
So in my use case, if the user selects a "body" font family different than the default one, or maybe a different text color, he needs to reapply them in every new paragraph after an empty line (See #5620 to understand this).
The expected behavior
When user breaks no matter how much lines, the CSS styles applied to a paragraph persist between lines.
Attempt to fix the issue
As an attempt to address this, I have created a CustomParagraphNode which is generating a new performance problem.
import { $applyNodeReplacement, ParagraphNode } from 'lexical';
import { $patchStyleText } from '@lexical/selection';
export class CustomParagraphNode extends ParagraphNode {
constructor(cssStyle, key) {
super(key);
this.__cssStyle = cssStyle;
}
static getType() {
return 'custom-paragraph';
}
getCssStyle() {
const self = this.getLatest();
return self.__cssStyle;
}
setCssStyle(style) {
const self = this.getWritable();
self.__cssStyle = style;
return self;
}
static clone(node) {
return new CustomParagraphNode(node.__cssStyle, node.__key);
}
// View
static importJSON(serializedNode) {
const node = $createCustomParagraphNode(serializedNode.cssStyle);
node.setFormat(serializedNode.format);
node.setIndent(serializedNode.indent);
node.setDirection(serializedNode.direction);
node.setTextFormat(serializedNode.textFormat);
node.setCssStyle(serializedNode.cssStyle);
return node;
}
createDOM(config) {
const element = super.createDOM(config);
element.style.cssText = this.__cssStyle;
return element;
}
exportJSON() {
return {
...super.exportJSON(),
cssStyle: this.getCssStyle(),
textFormat: this.getTextFormat(),
type: 'custom-paragraph',
version: 1,
};
}
// Mutation
insertNewAfter(rangeSelection, restoreSelection) {
const newElement = $createCustomParagraphNode(rangeSelection.style);
newElement.setTextFormat(rangeSelection.format);
newElement.setCssStyle(rangeSelection.style);
const direction = this.getDirection();
newElement.setDirection(direction);
newElement.setFormat(this.getFormatType());
this.insertAfter(newElement, restoreSelection);
$patchStyleText(rangeSelection, rangeSelection.style);
return newElement;
}
}
function $createCustomParagraphNode(cssStyle = '') {
return new CustomParagraphNode(cssStyle);
}
The $patchStyleText(rangeSelection, rangeSelection.style)
line is what reinstate the selection to keep having the same style, but that creates a performance issue that after creating some lines, the application will totally freeze.
Have you tried using the example from the docs for the extendedTextNode: https://lexical.dev/docs/concepts/serialization#handling-extended-html-styling
This doesn't seem to solve the issue. I'm now trying to create some solution to apply the new "cssStyle" parameter that I created on CustomParagraphNode to apply to this ExtendedTextNode on creation, but I don't know if that's the right way of doing it.
Hey @trueadm is it possible to give some attention to this issue? It seems like an important issue from a use-case and developers demand point of view. There's a discussion on discord about this: https://discord.com/channels/953974421008293909/1210630834458206312
Hey @trueadm is it possible to give some attention to this issue? It seems like an important issue from a use-case and developers demand point of view. There's a discussion on discord about this: https://discord.com/channels/953974421008293909/1210630834458206312
Trueadm is no longer working on Lexical.
Regarding your use case, I think that a PR was recently merged that should help. Not sure if it has already been released or not.
Hey @trueadm is it possible to give some attention to this issue? It seems like an important issue from a use-case and developers demand point of view. There's a discussion on discord about this: https://discord.com/channels/953974421008293909/1210630834458206312
Trueadm is no longer working on Lexical.
Regarding your use case, I think that a PR was recently merged that should help. Not sure if it has already been released or not.
Are you talking about this PR? It certainly is an advance on this matter. But the issue is that it only persists the formatting (bold, italic, underline, etc) between paragraphs. Any very common use cases of persisting styles (font-family, color, font-size, etc) will be lost between spaced paragraphs.
Are you talking about this PR?
Yep, that one. Now I see that it doesn't maintain the styles across paragraphs, thanks for pointing that out.