Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: paragraphNode should apply configured indent value from theme on exportDOM #6082

Open
2wheeh opened this issue May 10, 2024 · 2 comments
Labels
enhancement Improvement over existing feature

Comments

@2wheeh
Copy link
Contributor

2wheeh commented May 10, 2024

from exportDOM

image

from reconciler

image

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 ?

@2wheeh
Copy link
Contributor Author

2wheeh commented May 11, 2024

What i understand:

  1. When importing, 20px seems to be set considering to pasting HTML with a small base indent size.
    const indent = parseInt(element.style.textIndent, 10) / 20;
  2. For consistency between exporting and importing, we are setting 20px text-indent on exporting as well.
    element.style.textIndent = `${indent * 20}px`;
  3. However, the default indent size when creating DOM is 40px.
    const DEFAULT_INDENT_VALUE = '40px';
  4. Pasting HTML copied from the same editor (same namespace) doesn't trigger importDOM, which is utilized for HTML strings copied from outside sources.
    payload.namespace === editor._config.namespace &&
  5. 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.

@2wheeh
Copy link
Contributor Author

2wheeh commented May 11, 2024

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`
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement over existing feature
Projects
None yet
Development

No branches or pull requests

1 participant