feat(texteditor): add text alignment toggling buttons#5677
feat(texteditor): add text alignment toggling buttons#5677habibayman wants to merge 11 commits intolearningequality:unstablefrom
Conversation
|
👋 Thanks for contributing! We will assign a reviewer within the next two weeks. In the meantime, please ensure that:
We'll be in touch! 😊 |
00187e5 to
f2aa6e6
Compare
…gs with alignment dir
…hildren by calling serializeChildren directly
rtibblesbot
left a comment
There was a problem hiding this comment.
Good feature addition for RTL/LTR text alignment toggling. The serializer refactoring from mutation-based to return-based is a nice improvement. One bug in the overflow dropdown disabled logic.
CI passing.
Blocking:
- Inverted
:disabledlogic on overflow align button (see inline)
Suggestions:
- SVG icon dimension mismatch between align-left and align-right
- Peer dependency version mismatch for
@tiptap/extension-text-align
Nitpick:
- Double space in image markdown output when no dimensions present
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Reviewed the pull request diff checking for:
- Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
- Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
- Architecture: duplicated concerns, minimal interfaces, composition over inheritance
- Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
- Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
- Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
- Checked CI status and linked issue acceptance criteria
- For UI changes: inspected screenshots for layout, visual completeness, and consistency
| class="dropdown-item" | ||
| :class="{ active: alignAction.isActive }" | ||
| role="menuitem" | ||
| :disabled="alignAction.isAvailable" |
There was a problem hiding this comment.
blocking: This is inverted. alignAction.isAvailable is true when the action IS available (not in a code block), so :disabled="alignAction.isAvailable" disables the button when it should be enabled, and vice versa.
Compare with line 262 which correctly uses :disabled="!canClearFormat" — note the negation.
Fix: :disabled="!alignAction.isAvailable"
| @@ -0,0 +1,3 @@ | |||
| <svg width="8" height="8" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
There was a problem hiding this comment.
suggestion: This SVG has width="8" height="8" while icon-alignLeft.svg has width="10" height="10". Both share the same viewBox="0 0 15 17" so they represent the same logical space but will render at different sizes. Should these match?
| return ``; | ||
| } | ||
| return ``; | ||
| return ``; |
There was a problem hiding this comment.
nitpick: When there are no dimensions but alignment exists, alignSuffix already starts with a space ( align=right), then ` ${alignSuffix}` adds another space, producing a double space like . The regex still parses it correctly (\s+), but you could simplify to just ${alignSuffix} (without the extra template literal wrapping) since the leading space is already in the variable.
| "@tiptap/extension-link": "^3.13.0", | ||
| "@tiptap/extension-subscript": "^3.13.0", | ||
| "@tiptap/extension-superscript": "^3.13.0", | ||
| "@tiptap/extension-text-align": "^3.18.0", |
There was a problem hiding this comment.
suggestion: @tiptap/extension-text-align@3.18.0 declares a peer dependency of @tiptap/core: ^3.18.0, but the project has @tiptap/core@3.13.0. CI passes so it likely works today, but this gap (3.13 vs 3.18) could cause subtle issues if the extension uses newer core APIs. Consider either pinning to a text-align version compatible with 3.13 (e.g., @tiptap/extension-text-align@^3.13.0) or upgrading the other tiptap packages.
| } | ||
| } | ||
| break; | ||
| return parts.join('\n\n'); |
There was a problem hiding this comment.
praise: Nice refactoring of the serializer from mutation-based (result +=) to a return-based approach. This makes each case self-contained and much easier to reason about, especially now that alignment wrapping needs to inspect the serialized children before deciding the output format.
| type: 'paragraph', | ||
| content: [{ type: 'text', text: 'n', marks: [{ type: 'subscript' }] }], | ||
| }, | ||
| ]; |
There was a problem hiding this comment.
praise: Thorough test coverage for text alignment serialization — covers right/left/center/no-attr cases, headings, inline marks inside aligned paragraphs, and mixed alignment documents. Good edge case thinking.
| default: 'small-text', | ||
| }, | ||
| textAlign: { | ||
| default: 'left', |
There was a problem hiding this comment.
question/suggestion: I wonder if this should be set based on the user's current language - when I load the page up in Arabic, the direction defaults to the left but I expected it to go to the right.
When I type Arabic into the box, it automatically aligns the text to the right and then when I insert things into it they all stay right-aligned, but the icon indicator is showing to the left:
But I could do all as described (ie, right/left aligning one paragraph between others that stay put).
There was a problem hiding this comment.
I interpret this button (outlined here) as "Right to Left"
There was a problem hiding this comment.
Looks that way to me too... Can you reverse the alignment manually to LTR for the paragraphs that are not in Arabic?
Summary
This PR includes the addition of a toggle alignment (Left/Right) button.
From the motives of making the RTL editor experience better and give users the ability to seamlessly mix RTL & LTR text in the same editing block.
It includes support for all nodes & Marks we have:
For this to work with our backward compatible dual markdown conversion pipeline; I have altered the markdown serializer to wrap non-default direction nodes with HTML tags containing the
alignattribute set.And of course, updated the unit tests accordingly.
References
Figma Design
currently this PR represents part of Update rich text editor to flexible, extensible rich text editing framework #5049
fixes [Rich Text Editor]: add a toggle text alignment (R/L) button #5385
Reviewer guidance
Note
Check the native behavior of the extension from the official TipTap documentation to see where its limitations -if any- exist.
https://tiptap.dev/docs/editor/extensions/functionality/textalign