Skip to content

fix(alignment): apply alignment to all blocks in a multi-block selection#191

Merged
Samyssmile merged 1 commit into
mainfrom
fix/alignment-multiblock-190
Jun 28, 2026
Merged

fix(alignment): apply alignment to all blocks in a multi-block selection#191
Samyssmile merged 1 commit into
mainfrom
fix/alignment-multiblock-190

Conversation

@Samyssmile

Copy link
Copy Markdown
Owner

Summary

Closes #190.

Choosing a text alignment with several blocks selected aligned only the anchor block and silently ignored the rest. TextDirectionPlugin already handled the full range correctly, which confirmed this was incomplete behavior rather than a design choice.

Root cause

AlignmentPlugin.setAlignment resolved a single block (getSelectedBlock + getSelectedBlockId) and applied align only to that anchor.

Fix

Rather than duplicating text-direction's range logic into alignment (which would let the two diverge again), the shared logic is extracted so both plugins run one code path:

  • PluginHelpers.ts — new exported getSelectedBlockIds(state): returns every leaf-block ID covered by the selection (NodeSelection → its node; single/collapsed → one ID; multi-block → the full inclusive anchor→head range in document order).
  • TextDirectionPlugin.ts — deletes its private duplicate and consumes the shared helper.
  • AlignmentPlugin.tssetAlignment now iterates every selected block, applies align to each alignable one (skipping non-alignable blocks), and commits a single transaction.

Toolbar isActive/isEnabled are intentionally left checking the anchor only, matching text-direction's existing behavior.

Tests

Two multi-block cases added to AlignmentPlugin.test.ts, mirroring the text-direction suite:

  • all blocks in a range selection get aligned
  • non-alignable blocks in the range are left untouched (the continue branch)

Verification

  • Unit: 4405 passed (incl. the 2 new tests)
  • Typecheck: clean · Lint (biome): clean · Build: succeeds
  • E2E: text-direction.spec.ts (3 tests) passes, confirming the extraction is behavior-preserving in a real browser

Note (out of scope)

Alignment does not announce() to screen readers on any path, whereas text-direction does. This is a pre-existing gap orthogonal to this bug (no a11y regression introduced); worth a separate follow-up ticket.

setAlignment resolved only the anchor block, so choosing an alignment with
several blocks selected aligned just the first one and silently ignored the
rest. TextDirectionPlugin already handled the full range, confirming this was
incomplete behavior.

Extract the range-resolution logic into a shared getSelectedBlockIds helper in
PluginHelpers, consume it from both AlignmentPlugin and TextDirectionPlugin
(removing the latter's private duplicate), and rewrite setAlignment to apply
the align attribute to every alignable block in the selection in a single
transaction. Sharing one code path keeps alignment and direction from diverging
again.

Closes #190
@Samyssmile Samyssmile merged commit 73bdf1f into main Jun 28, 2026
5 checks passed
@Samyssmile Samyssmile deleted the fix/alignment-multiblock-190 branch June 28, 2026 10:32
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.

Alignment only applies to the first block of a multi-block selection

1 participant