Skip to content

fix(vidstack): right-to-left layout and spoken time in the page's language - #1866

Open
aviahmorag wants to merge 2 commits into
vidstack:mainfrom
aviahmorag:fix/slider-rtl
Open

aviahmorag wants to merge 2 commits into
vidstack:mainfrom
aviahmorag:fix/slider-rtl

Conversation

@aviahmorag

@aviahmorag aviahmorag commented Oct 4, 2026 •

Copy link
Copy Markdown

Related:

No existing issue.

Description:

Makes sliders and the default layout's menus work in right-to-left pages (Hebrew, Arabic, Persian), and speaks times in the page's language. Today, in a dir="rtl" page:

  • Horizontal sliders (time, volume, speed, quality, caption size, audio boost) still run left to right. Pointer, touch-drag and arrow keys are all measured from the left.
  • Menu rows are pinned to the physical left (justify-content: left), and icons, hints, radio check marks and their indentation use physical margins and padding, so they sit on the wrong side.
  • The back and submenu arrows point the left-to-right way, and the switch knob is positioned with an unanchored translateX, so it leaves the track.

Changes:

  • SliderEventsController: a horizontal slider whose computed direction is rtl reads pointer position from the right edge, inverts touch-drag, and swaps ArrowLeft/ArrowRight. Up/Down, Home/End and vertical sliders are unchanged.

  • default/sliders.css: horizontal sliders in :dir(rtl) are mirrored with scale: -1 1 (so the transforms Vidstack sets on the thumb and fill still apply), and the preview is mirrored back so its text and thumbnail read normally.

  • default/menus.css: physical properties become logical ones (margin-inline-*, padding-inline-*, inset-inline-start, border-inline-start, justify-content: flex-start). The two menu arrows flip in :dir(rtl), and the switch knob is anchored to the right and moves left.

  • Spoken time: formatSpokenTime(duration, lang?) spells the units with Intl.DurationFormat in the given language when the browser has it, so plurals follow CLDR (Arabic "دقيقتان", Russian "21 минута 3 секунды"). The time slider's value text, the announcer's seek announcement and the chapters menu pass the closest lang attribute. Without a lang, or without Intl.DurationFormat, the output is the current "1 min 23 sec".

  • The time slider gets a translations prop for the two words CLDR has no pattern for, out of and live; both default layouts pass theirs, and DefaultLayoutWord gains the two words.

Left-to-right rendering is unchanged. One visible difference in English: on a page with lang="en", the screen-reader text now says "6 seconds out of 12 seconds" instead of "6 sec out of 12 sec".

Ready?

Yes.

Anything Else?

Before: the Accessibility menu in Hebrew with dir="rtl" alone. The back arrow runs into the title and the switch knobs sit outside their tracks.

Hebrew settings menu before the fix

After: the same menu as the mirror image of the left-to-right one.

Hebrew settings menu after the fix

Tested in WebKit (Playwright) and Safari with React + DefaultVideoLayout in a dir="rtl" page:

  • Clicking 10% from the left of the time slider seeks to 90%.
  • Clicking the left side of the volume slider raises the volume; ArrowLeft raises it and ArrowRight lowers it.
  • Every settings menu level was compared with the left-to-right one and is its mirror image.
  • Left-to-right menus are pixel-identical before and after, apart from hover state.
  • Time slider value text on a lang="he" page with Hebrew translations: "6 שניות מתוך 12 שניות"; on lang="en": "6 seconds out of 12 seconds".
  • pnpm -F vidstack test passes, with new cases for formatSpokenTime in English, Hebrew and Arabic and for an invalid language tag.

The Plyr layout is not covered here.

Review Process:

  1. Open a player with the default video layout inside <html dir="rtl">.
  2. Drag and click the time and volume sliders, and use the arrow keys on them.
  3. Open the settings menu and its submenus, including Accessibility → Caption Styles, and toggle a switch.

@aviahmorag aviahmorag changed the title fix(vidstack): right-to-left sliders and default menus fix(vidstack): right-to-left layout and spoken time in the page's language Oct 4, 2026

This branch has not been deployed

No deployments
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.

1 participant