[lexical] Bug Fix: Resolve --lexical-indent-base-value via CSS var() instead of pre-computing in JS#8466
Merged
Conversation
…instead of pre-computing in JS ## Description `setElementIndent` read `--lexical-indent-base-value` via `getComputedStyle(activeEditor._rootElement || dom)` and substituted the resolved value into a `calc(...)` expression on `padding-inline-start`. This is brittle in two ways: (a) `getComputedStyle` only sees the CSS variable if it cascades to `_rootElement` or `dom`, so themes that put the variable on the indent class itself (or any selector below the root) silently fell back to `DEFAULT_INDENT_VALUE` (`40px`); (b) when called from `$createNode` before the new DOM is attached to its parent, no cascade has happened yet, so even the same selector layout could miss the variable depending on timing. The reported symptom was that copy/pasted paragraphs ignored a custom `--lexical-indent-base-value` setting and used `40px` instead. ## Fix `setElementIndent` now writes `padding-inline-start: calc(N * var(--lexical-indent-base-value, 40px))` directly. The CSS variable reference is preserved in the inline style, so the browser resolves it at cascade time using whichever scope defines the variable. Mount timing no longer matters, and `getComputedStyle` (which forces layout) is no longer called per indent change. Existing test snapshots that asserted the old pre-resolved string (`calc(40px)`, `calc(80px)`, etc.) were updated to the new `calc(N * var(--..., 40px))` form. Two regression tests were added in `LexicalReconciler.test.ts` covering the var() output and the indent=0 padding clear. Closes facebook#7730. ## Test plan - [x] `pnpm tsc` clean - [x] `pnpm test-unit` — 117 files / 3038 pass (was 3036, +2 new) - [ ] `pnpm test-e2e-chromium` — defer to CI (mechanical snapshot update; CI verifies in real browsers)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
etrepum
approved these changes
May 6, 2026
This was referenced May 27, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
setElementIndentread--lexical-indent-base-valueviagetComputedStyle(activeEditor._rootElement || dom)and substituted the resolved value into acalc(...)expression onpadding-inline-start. This was brittle in two ways:getComputedStyleonly sees the CSS variable if it cascades to_rootElementordom, so themes that put the variable on the indent class itself (or any selector below the root) silently fell back toDEFAULT_INDENT_VALUE(40px); and when called from$createNodebefore the new DOM is attached to its parent, no cascade has happened yet, so even the same selector layout could miss the variable depending on timing. The reported symptom was that copy/pasted paragraphs ignored a custom--lexical-indent-base-valuesetting and used40pxinstead.setElementIndentnow writespadding-inline-start: calc(N * var(--lexical-indent-base-value, 40px))directly. The CSS variable reference is preserved in the inline style, so the browser resolves it at cascade time using whichever scope defines the variable. Mount timing no longer matters, andgetComputedStyle(which forces layout) is no longer called per indent change. This is the approach etrepum suggested in the issue thread.Existing test snapshots that asserted the old pre-resolved string (
calc(40px),calc(80px), etc.) were updated to the newcalc(N * var(--..., 40px))form. Two regression tests were added inLexicalReconciler.test.tscovering the var() output and the indent=0 padding clear.Closes #7730
Test plan
pnpm tscclean.pnpm test-unit— 117 files / 3038 pass (was 3036 before, +2 new regression tests inLexicalReconciler.test.ts).--lexical-indent-base-valuedefined on the indent class only, paragraphs lost their custom indent value before the fix; after the fix the value cascades correctly.