Skip to content

Add text alignment (left/center/right/justify)#1086

Open
brandonpark wants to merge 1 commit into
basecamp:mainfrom
brandonpark:text-alignment
Open

Add text alignment (left/center/right/justify)#1086
brandonpark wants to merge 1 commit into
basecamp:mainfrom
brandonpark:text-alignment

Conversation

@brandonpark

Copy link
Copy Markdown

Implements text alignment as a toolbar dropdown by dispatching Lexical's FORMAT_ELEMENT_COMMAND. Works on paragraphs, headings, list items, and table cells. Adds state-driven active-button highlighting in the dropdown.

  • Add "text-align" to DOMPurify's allowed style properties so the inline style survives sanitization.
  • Surface blockAlignment from Selection#getFormat for toolbar state reads.
  • Register the four align commands in the command dispatcher.
  • Add the alignment dropdown to the default toolbar template, after the format dropdown and before highlight.
  • Add 4 alignment SVG icons.

Bumps the viewport in the existing overflow-compaction test from 360px to 400px to accommodate one more non-overflowable toolbar item.

Closes #1067

image

Copilot AI review requested due to automatic review settings June 2, 2026 20:24

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds text-alignment support to the editor toolbar (left/center/right/justify), including sanitization support and end-to-end tests to ensure alignment is applied and preserved.

Changes:

  • Add an “Alignment” dropdown to the toolbar and dispatch Lexical element-format commands for alignment.
  • Track current block alignment in selection formatting and reflect it in toolbar pressed states.
  • Add Playwright + Rails system tests covering alignment behavior and persistence.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/test_helpers/toolbar_helper.rb Adds a test helper to apply alignment via the toolbar dropdown.
test/system/text_alignment_test.rb Introduces Rails system tests to verify alignment persistence after save/edit.
test/browser/tests/formatting/toolbar.test.js Tweaks viewport width used in the toolbar overflow test.
test/browser/tests/formatting/text_alignment.test.js Adds Playwright coverage for alignment commands and UI state.
test/browser/helpers/toolbar.js Extends toolbar helpers to open the alignment dropdown automatically.
src/elements/toolbar.js Adds alignment dropdown UI and pressed-state syncing based on selection format.
src/editor/selection.js Exposes blockAlignment from the current selection.
src/editor/command_dispatcher.js Adds alignment commands using FORMAT_ELEMENT_COMMAND.
src/config/dom_purify.js Allows text-align through DOMPurify style filtering.
Files not reviewed (1)
  • src/elements/toolbar_icons.js: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


click_on "Update Post"

assert_selector "p[style='text-align:right;']", text: "Hello everyone"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mirroring the existing precedent in test/system/color_highlighter_test.rb — it uses the same strict mark[style='background-color:var(--highlight-bg-1);'] matcher. The serialized format is stable for server-rendered HTML (it's the CSSStyleDeclaration cssText form, not the editor JS output), and the test passes consistently. Happy to switch to style*= if you'd prefer, but the strict form matches the codebase convention.

Comment thread src/editor/selection.js
Comment on lines +119 to +121
#getBlockAlignment(anchorNode) {
return $getNearestBlockElementAncestorOrThrow(anchorNode).getFormatType() ?? ""
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — agreed that toolbar state updates shouldn't be able to crash the editor on edge-case selections. Wrapped the call in a try/catch with a "" fallback in 0ee9fa7. (The non-throwing $getNearestBlockElementAncestor variant isn't exported from @lexical/utils 0.44, so try/catch is the lightest fix.)

Comment thread src/elements/toolbar.js
Comment on lines +441 to +454
<div data-dropdown-panel role="menu" class="lexxy-editor__toolbar-dropdown-list" hidden>
<button type="button" name="align-left" data-command="alignLeft" title="Align left" role="menuitem">
${ToolbarIcons.alignLeft} <span>Left</span>
</button>
<button type="button" name="align-center" data-command="alignCenter" title="Align center" role="menuitem">
${ToolbarIcons.alignCenter} <span>Center</span>
</button>
<button type="button" name="align-right" data-command="alignRight" title="Align right" role="menuitem">
${ToolbarIcons.alignRight} <span>Right</span>
</button>
<button type="button" name="align-justify" data-command="alignJustify" title="Justify" role="menuitem">
${ToolbarIcons.alignJustify} <span>Justify</span>
</button>
</div>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point on the ARIA semantics, but the existing format dropdown (Normal / Large / Medium / Small Heading) right above this one is also a mutually exclusive set using role="menuitem" + aria-pressed. Matching that pattern here for consistency — happy to flip both dropdowns to menuitemradio + aria-checked in a follow-up PR if that's the direction you'd like.

Implements text alignment as a toolbar dropdown by dispatching Lexical's
FORMAT_ELEMENT_COMMAND. Works on paragraphs, headings, list items, and
table cells. Adds state-driven active-button highlighting in the dropdown.

- Add "text-align" to DOMPurify's allowed style properties so the
  inline style survives sanitization.
- Surface blockAlignment from Selection#getFormat for toolbar state
  reads.
- Register the four align* commands in the command dispatcher.
- Add the alignment dropdown to the default toolbar template, after the
  format dropdown and before highlight.
- Add 4 alignment SVG icons.

Bumps the viewport in the existing overflow-compaction test from 360px
to 400px to accommodate one more non-overflowable toolbar item.

Closes basecamp#1067
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text alignment support (left, center, right, justify)

2 participants