Skip to content

fix: Slider filled track alignment in RTL mode#38875

Open
aniruddhaadak80 wants to merge 2 commits into
RocketChat:developfrom
aniruddhaadak80:fix/slider-rtl-alignment
Open

fix: Slider filled track alignment in RTL mode#38875
aniruddhaadak80 wants to merge 2 commits into
RocketChat:developfrom
aniruddhaadak80:fix/slider-rtl-alignment

Conversation

@aniruddhaadak80
Copy link
Copy Markdown
Contributor

@aniruddhaadak80 aniruddhaadak80 commented Feb 21, 2026

Proposed changes

This PR implements a global CSS workaround to fix an alignment issue with the Slider component when the application is in Right-to-Left (RTL) mode.

The Problem

In the current version of @rocket.chat/fuselage, the slider track background (the fill) uses a hardcoded linear-gradient(to right, ...), causing the highlighted part of the slider to grow from the left even in RTL mode, where it should grow from the right.

The Solution

Since the slider logic (powered by react-aria) correctly mirrors the thumb position, this PR adds a CSS patch that targets the Slider track and applies transform: scaleX(-1) when the document is in RTL mode. This effectively flips the gradient direction without affecting the mirrored interaction logic.

Issue(s)

Fixes #38670

Steps to test or reproduce

  1. Go to My Account > Preferences > Sound.
  2. Switch language to an RTL language (e.g., Arabic).
  3. Observe the Sound Sliders. The blue fill should now correctly start from the right side and align with the thumb position.

Summary by CodeRabbit

  • Bug Fixes

    • Slider now displays and aligns correctly in right-to-left (RTL) language layouts, improving interaction and visuals for RTL users.
  • Documentation

    • Corrected branding in the "Get the Latest News" section: "Youtube" → "YouTube".

Ensures consistent brand naming across the project documentation.
Fixed a typo where 'Youtube' was used instead of 'YouTube'.
@aniruddhaadak80 aniruddhaadak80 requested a review from a team as a code owner February 21, 2026 14:01
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented Feb 21, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 21, 2026

⚠️ No Changeset found

Latest commit: 65e9d72

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 21, 2026

Walkthrough

Adds a client-side startup hook that injects a single style tag to flip the RCX slider track for RTL layouts, and a minor README text change.

Changes

Cohort / File(s) Summary
Documentation
README.md
Fixed capitalization: "Youtube" → "YouTube" in the Get the Latest News section.
RTL slider utility
apps/meteor/client/lib/utils/injectSliderRTLFix.ts
New exported function that creates/guards a style element (id="rcx-slider-rtl-fix") and injects CSS to flip the RCX slider track and its ::before pseudo-element for [dir='rtl'].
Startup wiring
apps/meteor/client/startup/sliderRTLFix.ts, apps/meteor/client/startup/index.ts
Added sliderRTLFix startup module that calls injectSliderRTLFix() on Meteor client startup; imported in startup index to ensure execution at initialization.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client as Meteor Client Startup
    participant Module as sliderRTLFix module
    participant Util as injectSliderRTLFix()
    participant DOM as Browser document.head

    Client->>Module: import/execute on startup
    Module->>Util: call injectSliderRTLFix()
    Util->>DOM: query for element id "rcx-slider-rtl-fix"
    alt element not found
        Util->>DOM: create <style id="rcx-slider-rtl-fix"> with RTL CSS
        Util->>DOM: append style to document.head
    else element exists
        Util-->>DOM: no-op (avoid duplicate injection)
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nudged a track to flip and twirl,
In RTL lands the slider's now a pearl.
One style tag placed with cautious cheer,
Startup whispers, "Fix applied" — all clear. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning All changes are focused on fixing the RTL slider alignment issue; the README change to "YouTube" is a minor unrelated stylistic fix that falls outside the primary objective. Consider removing the YouTube/Youtube capitalization change from this PR or document it as a separate minor fix to keep the PR focused on the RTL slider alignment issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: fixing slider filled track alignment in RTL mode, which is the core objective of the PR.
Linked Issues check ✅ Passed The PR implements a CSS workaround to fix the slider track alignment issue in RTL mode by applying transform: scaleX(-1), directly addressing the bug reported in issue #38670.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts (1)

8-12: Use textContent instead of innerHTML for style element content.

While this content is fully hardcoded and poses no actual XSS risk, textContent is the correct and idiomatic API for setting text content on a <style> element. innerHTML triggers HTML parsing, whereas textContent inserts a direct text node — which is exactly what CSS injection needs.

♻️ Proposed refactor
-    styleElement.innerHTML = `
-		[dir='rtl'] .rcx-slider__track::before {
-			transform: scaleX(-1);
-		}
-	`;
+    styleElement.textContent = `
+		[dir='rtl'] .rcx-slider__track::before {
+			transform: scaleX(-1);
+		}
+	`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts` around lines 8 - 12,
Replace the use of styleElement.innerHTML with styleElement.textContent in the
injectSliderRTLFix implementation: locate the assignment to
styleElement.innerHTML that injects the CSS rule for "[dir='rtl']
.rcx-slider__track::before" and set it via styleElement.textContent instead so
the CSS is inserted as text rather than parsed HTML (keep the same CSS string
and leave the rest of the style element creation logic unchanged).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3145c41 and fd0eaef.

📒 Files selected for processing (4)
  • README.md
  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
  • apps/meteor/client/startup/index.ts
  • apps/meteor/client/startup/sliderRTLFix.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
  • apps/meteor/client/startup/sliderRTLFix.ts
  • apps/meteor/client/startup/index.ts
🧠 Learnings (4)
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
  • apps/meteor/client/startup/sliderRTLFix.ts
  • apps/meteor/client/startup/index.ts
📚 Learning: 2026-01-08T15:03:59.621Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38068
File: apps/meteor/tests/data/apps/app-packages/README.md:14-16
Timestamp: 2026-01-08T15:03:59.621Z
Learning: For the RocketChat/Rocket.Chat repository, do not analyze or report formatting issues (such as hard tabs vs spaces, line breaks, etc.). The project relies on automated linting tools to enforce formatting standards.

Applied to files:

  • README.md
📚 Learning: 2025-11-10T19:06:20.146Z
Learnt from: MartinSchoeler
Repo: RocketChat/Rocket.Chat PR: 37408
File: apps/meteor/client/views/admin/ABAC/useRoomAttributeOptions.tsx:53-69
Timestamp: 2025-11-10T19:06:20.146Z
Learning: In the Rocket.Chat repository, do not provide suggestions or recommendations about code sections marked with TODO comments. The maintainers have already identified these as future work and external reviewers lack the full context about implementation plans and timing.

Applied to files:

  • README.md
📚 Learning: 2025-12-02T22:23:49.593Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37654
File: apps/meteor/client/hooks/useAppSlashCommands.ts:32-38
Timestamp: 2025-12-02T22:23:49.593Z
Learning: In apps/meteor/client/hooks/useAppSlashCommands.ts, the `data?.forEach((command) => slashCommands.add(command))` call during render is intentional. The query is configured with `structuralSharing: false` to prevent React Query from keeping stable data references, and `slashCommands.add` is idempotent, so executing on every render is acceptable and ensures the command registry stays current.

Applied to files:

  • apps/meteor/client/startup/index.ts
🧬 Code graph analysis (1)
apps/meteor/client/startup/sliderRTLFix.ts (1)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts (1)
  • injectSliderRTLFix (1-14)
🪛 ast-grep (0.40.5)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts

[warning] 7-11: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: styleElement.innerHTML = [dir='rtl'] .rcx-slider__track::before { transform: scaleX(-1); }
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)


[warning] 7-11: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: styleElement.innerHTML = [dir='rtl'] .rcx-slider__track::before { transform: scaleX(-1); }
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html

(unsafe-html-content-assignment)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: cubic · AI code reviewer
🔇 Additional comments (3)
README.md (1)

118-118: LGTM!

Correct capitalization of "YouTube".

apps/meteor/client/startup/sliderRTLFix.ts (1)

1-7: LGTM!

Clean Meteor startup hook. Calling injectSliderRTLFix() unconditionally is correct — the [dir='rtl'] selector in the injected CSS handles RTL-scoping at the CSS level, so injecting in LTR contexts is harmless.

apps/meteor/client/startup/index.ts (1)

11-11: LGTM!

Import correctly wires the new startup module into the client startup sequence.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts`:
- Around line 9-10: The injected selector targets a non-existent pseudo-element
and thus does nothing; update the RTL fix in injectSliderRTLFix.ts to target the
real DOM element (.rcx-slider-track) instead of .rcx-slider__track::before, and
replace the naive transform flip with a combination of (a) overriding
positioning using logical properties (use inset-inline-start/inset-inline-end or
set right/inset-inline-end to mirror the inline positioning instead of relying
on left) to counteract inline left/width inline styles, and (b) if the slider
value->position math is computed in JS, invert that calculation for RTL at the
source (where the track width/left are computed) so the fill segment reflects
the correct value direction; ensure any overrides have sufficient specificity
(or !important) to supersede inline styles.

---

Nitpick comments:
In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts`:
- Around line 8-12: Replace the use of styleElement.innerHTML with
styleElement.textContent in the injectSliderRTLFix implementation: locate the
assignment to styleElement.innerHTML that injects the CSS rule for "[dir='rtl']
.rcx-slider__track::before" and set it via styleElement.textContent instead so
the CSS is inserted as text rather than parsed HTML (keep the same CSS string
and leave the rest of the style element creation logic unchanged).

Comment thread apps/meteor/client/lib/utils/injectSliderRTLFix.ts Outdated
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 4 files

Adds a global CSS patch to flip the Slider track gradient when the document direction is set to RTL. This addresses a hardcoded direction in the @rocket.chat/fuselage dependency.

Fixes RocketChat#38670
@aniruddhaadak80 aniruddhaadak80 force-pushed the fix/slider-rtl-alignment branch from fd0eaef to 65e9d72 Compare February 21, 2026 14:47
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts (1)

7-19: Use textContent instead of innerHTML for the style element.

textContent is the semantically correct setter for <style> elements (no HTML parsing; bypasses the innerHTML code path that static analysis flags as CWE-79).

♻️ Proposed fix
-    styleElement.innerHTML = `
-		[dir='rtl'] .rcx-slider-track {
-			left: auto !important;
-			right: auto !important;
-			inset-inline-start: 0 !important;
-		}
-
-		[dir='rtl'] .rcx-slider-track::before {
-			transform: scaleX(-1) !important;
-			transform-origin: center !important;
-		}
-	`;
+    styleElement.textContent = `
+		[dir='rtl'] .rcx-slider-track {
+			left: auto !important;
+			right: auto !important;
+			inset-inline-start: 0 !important;
+		}
+
+		[dir='rtl'] .rcx-slider-track::before {
+			transform: scaleX(-1) !important;
+			transform-origin: center !important;
+		}
+	`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts` around lines 7 - 19,
Replace the use of styleElement.innerHTML with styleElement.textContent in
injectSliderRTLFix.ts to avoid HTML parsing and CWE-79 flags; locate the style
injection block where styleElement and id are set (the template string assigning
RTL rules to the style element) and assign that CSS string to
styleElement.textContent instead of innerHTML so the <style> content is set
semantically and securely.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd0eaef and 65e9d72.

📒 Files selected for processing (3)
  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
  • apps/meteor/client/startup/index.ts
  • apps/meteor/client/startup/sliderRTLFix.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/meteor/client/startup/index.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/startup/sliderRTLFix.ts
  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
🧠 Learnings (1)
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/startup/sliderRTLFix.ts
  • apps/meteor/client/lib/utils/injectSliderRTLFix.ts
🧬 Code graph analysis (1)
apps/meteor/client/startup/sliderRTLFix.ts (1)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts (1)
  • injectSliderRTLFix (1-21)
🪛 ast-grep (0.40.5)
apps/meteor/client/lib/utils/injectSliderRTLFix.ts

[warning] 7-18: Direct modification of innerHTML or outerHTML properties detected. Modifying these properties with unsanitized user input can lead to XSS vulnerabilities. Use safe alternatives or sanitize content first.
Context: styleElement.innerHTML = `
[dir='rtl'] .rcx-slider-track {
left: auto !important;
right: auto !important;
inset-inline-start: 0 !important;
}

	[dir='rtl'] .rcx-slider-track::before {
		transform: scaleX(-1) !important;
		transform-origin: center !important;
	}
`

Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://owasp.org/www-community/xss-filter-evasion-cheatsheet
- https://cwe.mitre.org/data/definitions/79.html

(dom-content-modification)


[warning] 7-18: Direct HTML content assignment detected. Modifying innerHTML, outerHTML, or using document.write with unsanitized content can lead to XSS vulnerabilities. Use secure alternatives like textContent or sanitize HTML with libraries like DOMPurify.
Context: styleElement.innerHTML = `
[dir='rtl'] .rcx-slider-track {
left: auto !important;
right: auto !important;
inset-inline-start: 0 !important;
}

	[dir='rtl'] .rcx-slider-track::before {
		transform: scaleX(-1) !important;
		transform-origin: center !important;
	}
`

Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://www.dhairyashah.dev/posts/why-innerhtml-is-a-bad-idea-and-how-to-avoid-it/
- https://cwe.mitre.org/data/definitions/79.html

(unsafe-html-content-assignment)

🔇 Additional comments (2)
apps/meteor/client/startup/sliderRTLFix.ts (1)

1-7: Startup hook structure is correct.

Meteor.startup() runs after the client DOM is ready, making it a safe point to call document.head.appendChild. The hook correctly defers to the utility's own idempotency guard. No issues with this file; the RTL fix correctness concerns are in injectSliderRTLFix.ts.

apps/meteor/client/lib/utils/injectSliderRTLFix.ts (1)

9-13: CSS class .rcx-slider-track is valid and already in use—revise the verification scope.

The .rcx-slider-track class is not speculative; it is actively targeted in the existing RTL fix and confirmed to be emitted by the fuselage Slider component. Your concern that fuselage uses CSS-in-JS with generated class names instead of BEM-style classes appears incorrect; the codebase already applies this fix to the same class.

One minor technical point: right: auto !important on line 11 is redundant. In RTL context, both right: auto and inset-inline-start: 0 resolve to the physical right property, and the latter's declaration wins. The right: auto declaration has no effect. This is harmless but can be removed.

The concerns about non-zero min/startFrom offsets and range sliders (two thumbs) are theoretical. All Slider usage in the codebase is single-thumb with default minValue={0}, and no range slider implementation is present.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts`:
- Around line 15-18: The CSS rule targeting “[dir='rtl']
.rcx-slider-track::before” is dead and the scaleX flip breaks interactions;
remove that rule and instead update injectSliderRTLFix.ts to operate on the
actual DOM element “.rcx-slider-track” (not ::before) and avoid transform flips
— read the element’s inline left/width and swap them into right/width (e.g., set
track.style.right = track.style.left; track.style.left = 'auto') or mutate the
slider render values so the filled segment is positioned via right/width in RTL;
ensure this logic runs for elements under dir='rtl' and on DOM mutations/updates
just like the original injection logic.

---

Nitpick comments:
In `@apps/meteor/client/lib/utils/injectSliderRTLFix.ts`:
- Around line 7-19: Replace the use of styleElement.innerHTML with
styleElement.textContent in injectSliderRTLFix.ts to avoid HTML parsing and
CWE-79 flags; locate the style injection block where styleElement and id are set
(the template string assigning RTL rules to the style element) and assign that
CSS string to styleElement.textContent instead of innerHTML so the <style>
content is set semantically and securely.

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.

[Bug]: Sound slider filled track is not aligned with RTL direction in Account Preferences

2 participants