lexical
lexical copied to clipboard
Feature: paragraphNode should apply configured indent value from theme on exportDOM
from exportDOM
from reconciler
element returned from exportDOM of paragraphNode doesn't have indent class from theme and doesn't apply configured indentation base value as well.
instead, it always has 20px as indentation value which makes difference between generated html and contenteditable.
Should this exported element have indent class from theme and also same indent value as configured in indent class ?
What i understand:
- When importing, 20px seems to be set considering to pasting HTML with a small base indent size. https://github.com/facebook/lexical/blob/157b77c2d84fb47aa85f98171e4285b284c26abc/packages/lexical/src/nodes/LexicalParagraphNode.ts#L197
- For consistency between exporting and importing, we are setting 20px
text-indenton exporting as well. https://github.com/facebook/lexical/blob/157b77c2d84fb47aa85f98171e4285b284c26abc/packages/lexical/src/nodes/LexicalParagraphNode.ts#L126 - However, the default indent size when creating DOM is 40px. https://github.com/facebook/lexical/blob/157b77c2d84fb47aa85f98171e4285b284c26abc/packages/lexical/src/LexicalReconciler.ts#L122
- Pasting HTML copied from the same editor (same namespace) doesn't trigger
importDOM, which is utilized for HTML strings copied from outside sources. https://github.com/facebook/lexical/blob/157b77c2d84fb47aa85f98171e4285b284c26abc/packages/lexical-clipboard/src/clipboard.ts#L134 - Thus, the situation here: ensuring (A) consistency between exporting and importing for outside the editor vs (B) consistency between creating and exporting from within the editor.
Personally, I lean towards (B) since it ensures the same result for the same editor state source but (A) is for outside sources.
For someone who needs this, you can utilize HTML config as a workaround.
for example:
const htmlConfig: HTMLConfig = {
export: new Map([
[
ParagraphNode,
(editor, node) => {
const targetNode = node as ParagraphNode;
const element = document.createElement('p');
if (element && isHTMLElement(element)) {
if (targetNode.isEmpty()) {
element.append(document.createElement('br'));
}
const formatType = targetNode.getFormatType();
element.style.textAlign = formatType;
const direction = targetNode.getDirection();
if (direction) {
element.dir = direction;
}
const indent = targetNode.getIndent();
setElementIndent(element, indent, editor._config.theme.indent);
}
return {
element,
};
},
],
]),
};
const DEFAULT_INDENT_VALUE = '40px';
function setElementIndent(dom: HTMLElement, indent: number, indentClassName?: string): void {
if (indent < 1) {
return;
}
if (typeof indentClassName === 'string') {
dom.classList.add(indentClassName);
}
const indentationBaseValue =
window.getComputedStyle(dom).getPropertyValue('--lexical-indent-base-value') ||
DEFAULT_INDENT_VALUE;
dom.style.setProperty(
// padding-inline-start is not widely supported in email HTML, but
// Lexical Reconciler uses padding-inline-start. Using text-indent instead.
'text-indent',
`${indent * parseInt(indentationBaseValue, 10)}px`
);
}