Skip to content

fix(ui): mirror directional chevrons in right-to-left layouts - #913

Open
rkj-builds wants to merge 1 commit into
cosscom:mainfrom
rkj-builds:fix/rtl-directional-chevrons
Open

rkj-builds wants to merge 1 commit into
cosscom:mainfrom
rkj-builds:fix/rtl-directional-chevrons

Conversation

@rkj-builds

@rkj-builds rkj-builds commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

In short

In a right-to-left layout (Arabic, Hebrew), five components still draw their chevrons pointing the left-to-right way: the Menu, ContextMenu and DrawerMenu submenu triggers, Pagination, and the default Breadcrumb separator. So the submenu chevron points away from the submenu it opens, and the pagination and breadcrumb arrows point backwards.

The fix adds rtl:rotate-180 to those six icons, the same class Calendar already uses. Left-to-right layouts don't change.

Right to left, before Right to left, after
Before, RTL After, RTL
Left to right, before Left to right, after (unchanged)
Before, LTR After, LTR

What to look at in the screenshots: the "More" submenu opens to the left in RTL, and its chevron now points that way. Pagination's Next and Previous arrows, and the breadcrumb arrows, now point the way you move.


What happens today

coss already ships DirectionProvider (@coss/ui/base-ui/direction-provider), and Calendar flips its navigation chevrons with rtl:rotate-180. Five other places draw a physical ChevronLeft/ChevronRight and do not flip:

  • Menu, ContextMenu, DrawerMenu submenu triggers. MenuSubPopup uses side="inline-end", so in RTL the submenu correctly opens to the left. The trigger's chevron still points right, away from the panel it opens.
  • Pagination Previous / Next. In RTL, Previous sits at the right edge, but its chevron points left toward the page numbers. Next has the same problem the other way.
  • Breadcrumb separator (the default one). In RTL it points back toward the root, so the trail reads backwards.

To reproduce: render any of these inside <DirectionProvider direction="rtl"> with dir="rtl" on <html>.

What this changes

Adds rtl:rotate-180 to those six icons, the same class Calendar uses. Nothing else changes:

  • Icons that have no direction (ChevronsUpDown in Select, Combobox and Autocomplete, and the Accordion ChevronDown) are left as they are.
  • BreadcrumbSeparator only flips its default icon. If you pass your own children (a /, for example), it renders untouched.
  • LTR is unchanged. The computed rotate is none both before and after.

Files: registry/default/ui/{menu,context-menu,drawer,pagination,breadcrumb}.tsx. Their mirrors in packages/ui/src/components/ and public/r/*.json were regenerated with registry:build and ui:sync. The unrelated p-*.json churn that registry:build produces on main was reverted.

Before / after (RTL)

Before After
Submenu trigger (popup opens left) › More ‹ More
Pagination › Next … Previous ‹ ‹ Next … Previous ›
Breadcrumb Breadcrumb › Components › Home Breadcrumb ‹ Components ‹ Home

The screenshots are above.

Checks actually run

  • A throwaway page (not committed) rendered Breadcrumb, Pagination and an open Menu with an open submenu inside DirectionProvider, with html[dir] set. A Playwright/Chrome script (repro-shot.mjs) read the computed rotate of each icon and where the submenu sits relative to its trigger:
    • before, RTL: submenu opens left; every chevron rotate: none
    • after, RTL: submenu opens left; every chevron rotate: 180deg
    • LTR, before and after: rotate: none; submenu opens right
  • bun run typecheck (apps/ui): passed.
  • bun run lint (apps/ui): no findings in the touched files. The warnings it does print are already on main, in use-composer-editor.ts.
  • biome check on the touched files: clean. The husky and lint-staged hook ran on commit.
  • DrawerMenu was not checked visually. It is the same one-class change on the same icon.

Alongside the open RTL work

This touches different lines from #892 (drawer animations and swipe). The only overlap is the generated public/r/drawer.json, so whichever lands second just needs registry:build re-run. It fits with the docs RTL toggle in #910, too: every chevron changed here is visible from that toggle.

Rebased on main @ 3d8ca28 (#909); typecheck and biome check re-run on the touched files.

Submenu triggers in Menu, ContextMenu and DrawerMenu, Pagination
Previous/Next, and the default Breadcrumb separator draw physical
ChevronLeft/ChevronRight icons. In RTL the submenu already opens to the
left (MenuSubPopup uses side="inline-end"), yet its chevron still points
right; Previous points toward the next page; breadcrumb separators point
back toward the root.

Add rtl:rotate-180 to these icons, the same treatment Calendar already
gives its navigation chevrons. Non-directional icons (ChevronsUpDown,
the accordion ChevronDown) and custom separator children are left alone.
LTR is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 24, 2026

Copy link
Copy Markdown

@rkj-builds is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
vercel Bot temporarily deployed to Preview – coss-com-origin October 24, 2026 12:50 Inactive
@vercel

vercel Bot commented Oct 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
coss-com-origin Skipped Skipped Oct 24, 2026 12:50pm UTC

Request Review

This branch was previously deployed

1 inactive deployment
Preview – coss-com-origin — 20b48cd1 Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant