-
Notifications
You must be signed in to change notification settings - Fork 594
Add support for RTL writing direction #1102
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?
Changes from all commits
6e5aa57
f214e77
8df2984
49cd4e0
a30c66e
fe724df
bb0466a
012810c
bdb01c7
5642edf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| 'nuka-carousel': patch | ||
| --- | ||
|
|
||
| Add support for RTL (right-to-left) document direction. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,59 @@ | ||||||
| import { isBrowser, isRTL } from './browser'; | ||||||
|
|
||||||
| describe('browser utils', () => { | ||||||
| describe('isBrowser', () => { | ||||||
| it('should return true in a browser environment', () => { | ||||||
| expect(isBrowser()).toBe(true); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| describe('isRTL', () => { | ||||||
| let originalDir: string; | ||||||
|
|
||||||
| beforeEach(() => { | ||||||
| originalDir = document.documentElement.dir; | ||||||
| }); | ||||||
|
|
||||||
| afterEach(() => { | ||||||
| document.documentElement.dir = originalDir; | ||||||
| }); | ||||||
|
|
||||||
| it.each([ | ||||||
| ['rtl', true], | ||||||
| ['ltr', false], | ||||||
| ['', false], | ||||||
| ['auto', false], | ||||||
| ])('should return %s when document direction is "%s"', (dir, expected) => { | ||||||
|
||||||
| ])('should return %s when document direction is "%s"', (dir, expected) => { | |
| ])('when document direction is "%s", should return %s', (dir, expected) => { |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1 +1,17 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| export const isBrowser = () => typeof window !== 'undefined'; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||
| * Detects if an element or the document is in right-to-left (RTL) mode. | ||||||||||||||||||||||||||||||||||||||||||||||
| * Checks the computed direction style to support both document-level and element-level RTL. | ||||||||||||||||||||||||||||||||||||||||||||||
| * This is used to adjust scroll offsets for RTL layouts. | ||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||
| export function isRTL(element?: HTMLElement | null) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!isBrowser()) return false; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (element) { | ||||||||||||||||||||||||||||||||||||||||||||||
| const direction = window.getComputedStyle(element).direction; | ||||||||||||||||||||||||||||||||||||||||||||||
| return direction === 'rtl'; | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+15
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (element) { | |
| const direction = window.getComputedStyle(element).direction; | |
| return direction === 'rtl'; | |
| } | |
| if (element) { | |
| const direction = window.getComputedStyle(element).direction; | |
| return direction === 'rtl'; | |
| } |
Copilot
AI
Apr 7, 2026
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.
isRTL()'s docstring says it checks computed styles for document-level direction, but the implementation only reads document.documentElement.dir (attribute) when no element is passed. This misses cases where direction is set via CSS or inherited (e.g., body { direction: rtl; }). Consider using getComputedStyle(document.documentElement).direction (and/or document.body) for the no-element path so behavior matches the comment and is more robust.
| if (element) { | |
| const direction = window.getComputedStyle(element).direction; | |
| return direction === 'rtl'; | |
| } | |
| return document.documentElement.dir === 'rtl'; | |
| if (element) { | |
| const direction = window.getComputedStyle(element).direction; | |
| return direction === 'rtl'; | |
| } | |
| if (document.documentElement.dir) { | |
| return document.documentElement.dir === 'rtl'; | |
| } | |
| const documentDirection = | |
| window.getComputedStyle(document.documentElement).direction || | |
| (document.body ? window.getComputedStyle(document.body).direction : ''); | |
| return documentDirection === 'rtl'; |
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.
RTL
scrollLeftsemantics are not consistent across browsers (some use negative values, others use positive descending/ascending). The current approach of simply negating offsets (and the comment asserting negativescrollLeft) will be incorrect in browsers that don't use the "negative" RTL model, causing navigation to scroll to the wrong positions. Consider normalizing RTLscrollLeftbehavior (detect the browser's RTL scroll model at runtime and convert logical offsets to the correctscrollLeftvalues) instead of assuming negatives.