Skip to content

refactor(core): mirror Pagination chevrons under RTL via CSS, not JS direction read - #4687

Draft
nynexman4464 wants to merge 5 commits into
mainfrom
nynexman4464/refactor/pagination-css-mirror
Draft

refactor(core): mirror Pagination chevrons under RTL via CSS, not JS direction read#4687
nynexman4464 wants to merge 5 commits into
mainfrom
nynexman4464/refactor/pagination-css-mirror

Conversation

@nynexman4464

@nynexman4464 nynexman4464 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Why

Pagination was the last component in the library that chose a physical icon name from a render-time useDirection() read to flip its prev/next chevrons under RTL. Everything else (Calendar, Carousel, Table disclosure, SideNav, …) mirrors directional icons purely with CSS via the shared rtlStyles.mirror (scaleX(-1)), flipping from an ancestor's dir through the cascade.

Two payoffs:

  • Removes the only internal consumer of the i18n direction context. After this, no component reads direction from context at render time — every internal RTL decision resolves from the DOM (logical CSS + CSS mirror + lazy DOM reads for behavior). useDirection() remains a public, SSR-safe convenience for consumers who need render-time direction in their own client components.
  • Eliminates a potential hydration mismatch. A render-time direction read is a spot where the provider's direction and the actual <html dir> could disagree and flash the wrong chevron on hydration. Pure CSS has no such branch.

What

Code: Render fixed chevronLeft / chevronRight glyphs, each wrapped in <span {...stylex.props(rtlStyles.mirror)}>, and drop the useDirection()-based name-swap. aria-labels are unchanged (they were already semantic, not directional). No API change; patch-level.

Docs (internationalization.doc.mjs) — brought in line with reality now that no component reads direction at render time:

  • Consumer: added an "it just works — set dir once, components mirror themselves" note, and corrected a stale caveat that claimed pop-up overlays (menus/dialogs) aren't mirrored yet. They mirror now via logical CSS anchor positioning (Layer logical placement + Dialog start/end, feat(core): add logical start/end to Dialog position; deprecate physical left/right #4568).
  • Contributor: replaced the old "read useDirection() to swap an icon" example — the exact anti-pattern this PR removes — with a priority hierarchy: (1) logical CSS, (2) directional icons via rtlStyles.mirror, (3) behavioral logic via lazy isRtlElement/focus-hook auto-detect, (4) useDirection() context only as a render-time last resort. Also notes isRtl is deprecated on the focus hooks.

Testing

  • Pagination suite: 64/64 pass
  • @astryxdesign/core typecheck clean, ESLint clean, check:sync clean
  • Doc module parses + imports as valid ESM; docsite data regenerates cleanly
  • Visual: chevrons point outward correctly in both LTR and RTL (Storybook dir toggle)

…direction read

Pagination was the last component selecting a physical icon name from a
render-time useDirection() read. Switch it to render fixed chevronLeft/
chevronRight glyphs wrapped in the shared rtlStyles.mirror (scaleX(-1)),
so they flip purely from an ancestor's dir via the CSS cascade -- matching
Calendar and the rest of the library. This removes the only internal
consumer of the i18n direction context and eliminates a potential
server/client hydration mismatch on the chevrons. No API change.
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview Aug 3, 2026 11:16pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 3, 2026
@github-actions github-actions Bot added the needs:design-review Affects visuals — Design should review label Aug 3, 2026
Consumer side: add an 'it just works' note (set dir once, components
mirror themselves) and correct the stale caveat that claimed overlays
(menus/dialogs) aren't mirrored yet -- they mirror via logical CSS
anchor positioning now (#4568 and the Layer logical placement).

Contributor side: replace the single 'read useDirection() to swap an
icon' example -- the exact anti-pattern this stack removes from
Pagination -- with a priority hierarchy: (1) logical CSS, (2) icons via
rtlStyles.mirror, (3) behavioral logic via lazy isRtlElement / focus-hook
auto-detect, (4) useDirection() context only as a render-time last resort.
Notes that isRtl on the focus hooks is deprecated and that no component
reads direction from context at render time after the CSS-mirror migration.
The docsite prose renderer (renderInlineMarkdown) only supports backtick
code-spans and [label](href) links -- **bold** renders as literal
asterisks. Convert the four contributor priority tiers from fake-bold
prose lead-ins into real level-4 headings + prose, which the renderer
supports and which gives proper visual hierarchy. Code identifiers stay
in the prose (where backticks work), since headings render text
verbatim.
The hook's own doc-comment still told authors to reach for it to 'swap
directional icons' -- the exact pattern the Pagination refactor and the
updated guide move away from. Reframe it to point at the preferred tools
first (logical CSS, rtlStyles.mirror for icons, lazy isRtlElement for
behavior) and note the hydration caveat, so IDE hovers and the API
surface match the guidance. Comment-only.
The provider's dir prop feeds context direction only; it never touches
the DOM dir attribute. Since astryx components mirror layout and
directional icons from the DOM dir (not the context value), an RTL
locale won't visually mirror unless the consumer also sets dir on <html>
or a wrapping element. Make this explicit where a provider user will
look: add the previously-undocumented dir prop to the component doc, a
best-practice entry, and expand the dir JSDoc (IDE hover). Docs only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant