-
Notifications
You must be signed in to change notification settings - Fork 7
Add RTL text direction support for translation into RTL languages #762
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: ericnewcomer <[email protected]>
Co-authored-by: ericnewcomer <[email protected]>
📊 Coverage ReportSummary
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds comprehensive RTL (Right-to-Left) text direction support for translating flows into RTL languages like Arabic, Hebrew, Farsi, and Urdu. The implementation enables proper text rendering and alignment throughout the flow editor when working with RTL translations.
Key changes:
- New
isRTLLanguage()utility function that detects RTL languages by ISO 639 codes (2-letter and 3-letter) - RTL property added to
TextInputcomponent with corresponding CSS styling - Integration of RTL support in
NodeEditor,CanvasNode,StickyNote, andFieldRenderercomponents
Reviewed Changes
Copilot reviewed 12 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/utils.ts |
Added isRTLLanguage() utility function with comprehensive RTL language code detection |
test/temba-utils-index.test.ts |
Complete test coverage for isRTLLanguage() function including edge cases |
src/form/TextInput.ts |
Added rtl boolean property and CSS styling for RTL text direction and right alignment |
test/temba-textinput.test.ts |
Tests for RTL rendering in both input and textarea modes with screenshot verification |
src/form/FieldRenderer.ts |
Extended FieldRenderContext interface with rtl property and integrated it into text input/textarea rendering |
src/flow/NodeEditor.ts |
Automatic RTL enablement when translating into RTL languages, passes RTL context to field renderer |
src/flow/CanvasNode.ts |
RTL CSS class for action bodies when translating into RTL languages |
src/flow/StickyNote.ts |
RTL support for sticky note title and body contenteditable fields during translation |
src/locales/*.ts |
Auto-generated formatting changes from lit-localize (no functional changes) |
screenshots/truth/textinput/*.png |
Screenshot truth images for RTL input and textarea rendering |
Comments suppressed due to low confidence (2)
src/flow/CanvasNode.ts:1350
- The RTL class application in the action body template lacks test coverage. This should be covered by the same test suggested for lines 178-181.
return action;
}
// Create a new action with localized values, falling back to base language
const localizedAction = { ...action };
src/flow/CanvasNode.ts:181
- The new RTL CSS class for action bodies lacks test coverage. Add a test in an appropriate test file that verifies RTL rendering when translating into an RTL language:
it('renders action body with RTL in translation mode', async () => {
// Set up app state for RTL translation
const state = zustand.getState();
zustand.setState({
...state,
isTranslating: true,
languageCode: 'ar' // Arabic
});
const testNode: Node = {
uuid: 'test-node',
actions: [
{
type: 'send_msg',
uuid: 'test-action',
text: 'مرحبا بك',
quick_replies: []
} as SendMsg
],
exits: []
};
const editorNode: CanvasNode = await fixture(html`
<temba-flow-node
.node=${testNode}
.ui=${{ position: { left: 0, top: 0 } }}
></temba-flow-node>
`);
await editorNode.updateComplete;
const actionBody = editorNode.querySelector('.action .body');
expect(actionBody.classList.contains('rtl')).to.be.true;
// Reset state
zustand.setState({
...state,
isTranslating: false,
languageCode: 'eng'
});
}); background: #fff;
}
.action .body {
src/utils.ts
Outdated
| * @param languageCode - ISO 639 language code (2-letter or 3-letter) | ||
| * @returns true if the language is RTL, false otherwise | ||
| */ | ||
| export const isRTLLanguage = (languageCode: string): boolean => { |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function signature should accept string | null | undefined to match the test cases at lines 1558-1559 of test/temba-utils-index.test.ts, which explicitly test null and undefined inputs.
Change the signature to:
export const isRTLLanguage = (languageCode: string | null | undefined): boolean => {This ensures type safety while maintaining the runtime behavior that already handles falsy values correctly.
| export const isRTLLanguage = (languageCode: string): boolean => { | |
| export const isRTLLanguage = (languageCode: string | null | undefined): boolean => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 54c50e2. The function signature now accepts string | null | undefined as suggested.
| onChange, | ||
| showLabel = true, | ||
| extraClasses, | ||
| style | ||
| style, | ||
| rtl = false | ||
| } = context; |
Copilot
AI
Nov 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rtl parameter is extracted from context here but not passed to temba-completion when rendering fields with evaluated: true (lines 115-127). This means evaluated text fields won't display in RTL mode during translation.
To fix this:
- Add an
rtlproperty to theCompletionclass insrc/form/Completion.ts - Forward the
rtlproperty to the underlyingtemba-textinputinCompletion.renderWidget()(around line 272) - Pass
?rtl="${rtl}"totemba-completionat lines 115-127
The same issue exists for evaluated textareas at lines 168-181.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in commit 54c50e2. Added rtl property to the Completion class and forwarded it to the underlying temba-textinput. Updated FieldRenderer to pass rtl to temba-completion for both text and textarea evaluated fields.
|
@copilot The RTL isn't being applied universally. In the case of send_msg localization it uses temba-completion which should also get RTL treatment all the way down to the underlying widgets. |
Co-authored-by: ericnewcomer <[email protected]>
Fixed in commit 54c50e2. RTL is now applied universally through temba-completion. Added the Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot Look at the message editor for send_msg. It looks like it is still missing the necessary bits for RTL. |
Co-authored-by: ericnewcomer <[email protected]>
Fixed in commit e9fe06f. Added The Arabic text "مرحبا بك في نظامنا" (Welcome to our system) is now properly right-aligned with RTL direction in the message editor. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|

✅ RTL (Right-to-Left) Language Support Complete
This PR adds comprehensive support for Right-to-Left text rendering when translating into RTL languages like Arabic, Farsi, Hebrew, and Urdu.
Recent Updates (addressing feedback)
Latest Changes (Message Editor)
rtlproperty toMessageEditorcomponentrtlproperty to underlyingtemba-completioninMessageEditor.renderWidget()FieldRenderer.renderMessageEditor()to passrtlfrom contextPrevious Changes
isRTLLanguage()type signature to acceptstring | null | undefinedrtlproperty toCompletioncomponentrtlproperty to underlyingtemba-textinputinCompletion.renderWidget()FieldRendererto passrtltotemba-completionfor both text and textarea fieldsImplementation Summary
Core Changes
isRTLLanguage()to detect RTL languages (Arabic, Hebrew, Farsi, Urdu, Kurdish, Pashto, etc.)TextInputcomponent withrtlproperty for RTL text directionCompletioncomponent withrtlproperty for expression fieldsMessageEditorcomponent withrtlproperty for send_msg localizationFieldRendererto pass RTL context to all text input componentsNodeEditorto automatically apply RTL when translatingCanvasNodeto render action bodies with RTL text alignmentStickyNoteto support RTL for title and body fieldsTesting & Validation
How It Works
When a user translates into an RTL language:
Component Chain for send_msg Localization
The RTL property now flows through the entire component chain:
Supported RTL Languages
ISO 639-3 (3-letter) and ISO 639-1 (2-letter) codes supported:
Browser Compatibility
Uses standard CSS properties (
direction: rtl,text-align: right) with universal browser support.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.