Skip to content

feat: layout direction component#577

Merged
Brentlok merged 3 commits into
mainfrom
layout-direction
Jun 10, 2026
Merged

feat: layout direction component#577
Brentlok merged 3 commits into
mainfrom
layout-direction

Conversation

@Brentlok

@Brentlok Brentlok commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

fixes #573

Summary by CodeRabbit

  • New Features

    • Added a LayoutDirection component to scope RTL/LTR directionality within subtrees.
  • Improvements

    • Context now includes explicit layout-direction state; theme scoping and style resolution respect per-subtree direction on web and native.
    • Style caching and variable lookup now account for layout direction to prevent cross-direction collisions.
  • Documentation

    • Updated docs to describe LayoutDirection usage and web dir semantics.
  • Tests

    • Added web and native tests covering LayoutDirection and direction-based style resolution.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8aa98b9-43c6-4ef8-b998-95448392329a

📥 Commits

Reviewing files that changed from the base of the PR and between 9537782 and 3894641.

📒 Files selected for processing (1)
  • skills/uniwind/SKILL.md

📝 Walkthrough

Walkthrough

Adds a subtree-scoped LayoutDirection component that sets nullable UniwindContext.rtl, threads that context into web/native style resolution and cache keys, updates ScopedTheme to merge context, and adds tests, entry re-exports, and docs for scoped RTL/LTR behavior.

Changes

Scoped Layout Direction Support

Layer / File(s) Summary
Context Foundation
packages/uniwind/src/core/context.ts
UniwindContext now includes rtl: boolean | null and useUniwindContext uses React use() to consume the context.
LayoutDirection Component
packages/uniwind/src/components/LayoutDirection/LayoutDirection.tsx, packages/uniwind/src/components/LayoutDirection/LayoutDirection.native.tsx, packages/uniwind/src/components/LayoutDirection/index.ts, packages/uniwind/src/index.ts
New LayoutDirection component accepts optional rtl prop, memoizes an updated UniwindContext value, renders a wrapper (div dir on web, View direction on native) with display: contents, and is re-exported at package entry.
ScopedTheme Context Merging
packages/uniwind/src/components/ScopedTheme/ScopedTheme.tsx, .../ScopedTheme.native.tsx
ScopedTheme now merges the current UniwindContext with scopedTheme, preserving rtl, and adds uniwindContext to useMemo deps.
Native Style Resolution with Context
packages/uniwind/src/core/native/store.ts
Native style cache keys include uniwindContext.rtl; validateDir now compares style.rtl against uniwindContext.rtl (fallback to runtime) instead of inferring from inline style.direction.
Web Rendering with Direction Context
packages/uniwind/src/core/web/getWebStyles.ts
getWebStyles and getWebVariable set or remove the dir attribute on the injected dummyParent based on uniwindContext.rtl so variant resolution is scoped by direction.
Configuration RTL Integration
packages/uniwind/src/core/config/config.common.ts, packages/uniwind/src/core/config/config.ts
Calls to variable lookup functions now explicitly pass { rtl: null } when deriving existing theme variables.
Tests & Fixtures
packages/uniwind/tests/consts.ts, packages/uniwind/tests/e2e/getWebStyles.test.ts, packages/uniwind/tests/native/styles-parsing/dir.test.tsx, packages/uniwind/tests/web/components/layout-direction.test.tsx
Include rtl in test context mocks, update test helpers defaults, add web/native tests covering LayoutDirection behavior, nested inheritance, and cache separation by direction.
Documentation
CONTEXT.md, skills/uniwind/SKILL.md
Adds LayoutDirection to public exports and documents scoped direction behavior, cache keying, web dir semantics, and runtime context-based variant resolution.

Sequence Diagram(s)

sequenceDiagram
  participant LayoutDirection
  participant UniwindContextProvider
  participant getWebStyles
  participant NativeStyleStore
  LayoutDirection->>UniwindContextProvider: provide { rtl: true|false|null }
  UniwindContextProvider->>getWebStyles: used by getWebStyles/getWebVariable (dir on dummyParent)
  UniwindContextProvider->>NativeStyleStore: used by native store cacheKey & validateDir
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • uni-stack/uniwind#574: Modifies RTL direction applicability logic in native store and related direction tests; closely related to validateDir changes.
  • uni-stack/uniwind#345: Touches updateCSSVariables/getWebVariable paths; overlaps with this PR's per-theme variable lookup option changes.
  • uni-stack/uniwind#521: Introduced getCSSVariable helper usage that this PR extends by adding an explicit rtl parameter.

Suggested reviewers

  • jpudysz

"🐰 I scoped the dir for subtrees wide,
I set rtl where rules may hide,
From web to native I provide,
A little wrapper, direction as guide."

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: layout direction component' directly describes the main change—introduction of a new LayoutDirection component for scoping RTL/LTR direction to subtrees.
Linked Issues check ✅ Passed The PR fully implements issue #573: LayoutDirection component scopes rtl: variant resolution to subtrees via context (rtl field in UniwindContext), enabling mixed-direction interfaces as requested.
Out of Scope Changes check ✅ Passed All changes directly support the LayoutDirection feature and its integration with context-based RTL scoping. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch layout-direction

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.

@Brentlok Brentlok requested a review from jpudysz June 10, 2026 12:42
Comment thread CONTEXT.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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)
packages/uniwind/tests/web/components/layout-direction.test.tsx (1)

5-25: ⚡ Quick win

Add a test for omitted rtl prop (dir should be absent).

Current tests cover explicit rtl and ltr, but not the optional-prop path. A rtl-omitted case would lock in inheritance behavior and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/uniwind/tests/web/components/layout-direction.test.tsx` around lines
5 - 25, Add a new test in the LayoutDirection test suite that renders
<LayoutDirection> without the rtl prop (e.g., <LayoutDirection><span>Default
content</span></LayoutDirection>) and assert that the span's parentElement does
NOT have a "dir" attribute (use getByText('Default content').parentElement and
expect(...).not.toHaveAttribute('dir')); keep test name descriptive like "omits
dir attribute when rtl prop is not provided".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/uniwind/src/components/LayoutDirection/LayoutDirection.tsx`:
- Around line 11-16: The current useMemo sets rtl to rtl ?? null which wipes out
parent direction when the prop is omitted; change the logic in LayoutDirection
(and mirror in LayoutDirection.native.tsx) to derive the effective rtl from the
parent context when the rtl prop is undefined—e.g., compute const effectiveRtl =
rtl === undefined ? uniwindContext.rtl : rtl and use that in the useMemo ({
...uniwindContext, rtl: effectiveRtl }) and for dir compute const dir =
effectiveRtl === undefined ? undefined : effectiveRtl ? 'rtl' : 'ltr' so the
subtree inherits parent direction unless explicitly overridden.

---

Nitpick comments:
In `@packages/uniwind/tests/web/components/layout-direction.test.tsx`:
- Around line 5-25: Add a new test in the LayoutDirection test suite that
renders <LayoutDirection> without the rtl prop (e.g.,
<LayoutDirection><span>Default content</span></LayoutDirection>) and assert that
the span's parentElement does NOT have a "dir" attribute (use getByText('Default
content').parentElement and expect(...).not.toHaveAttribute('dir')); keep test
name descriptive like "omits dir attribute when rtl prop is not provided".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3e8c8805-1f88-4b85-92e4-ef94697df37b

📥 Commits

Reviewing files that changed from the base of the PR and between 0a50373 and 384fcd2.

📒 Files selected for processing (16)
  • CONTEXT.md
  • packages/uniwind/src/components/LayoutDirection/LayoutDirection.native.tsx
  • packages/uniwind/src/components/LayoutDirection/LayoutDirection.tsx
  • packages/uniwind/src/components/LayoutDirection/index.ts
  • packages/uniwind/src/components/ScopedTheme/ScopedTheme.native.tsx
  • packages/uniwind/src/components/ScopedTheme/ScopedTheme.tsx
  • packages/uniwind/src/core/config/config.common.ts
  • packages/uniwind/src/core/config/config.ts
  • packages/uniwind/src/core/context.ts
  • packages/uniwind/src/core/native/store.ts
  • packages/uniwind/src/core/web/getWebStyles.ts
  • packages/uniwind/src/index.ts
  • packages/uniwind/tests/consts.ts
  • packages/uniwind/tests/e2e/getWebStyles.test.ts
  • packages/uniwind/tests/native/styles-parsing/dir.test.tsx
  • packages/uniwind/tests/web/components/layout-direction.test.tsx

Comment thread packages/uniwind/src/components/LayoutDirection/LayoutDirection.tsx
@Brentlok Brentlok merged commit ceb276d into main Jun 10, 2026
2 checks passed
@Brentlok Brentlok deleted the layout-direction branch June 10, 2026 14:03
@github-actions

Copy link
Copy Markdown
Contributor

🚀 This pull request is included in v1.9.0. See Release v1.9.0 for release notes.

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.

Support subtree direction for the rtl: variant (currently resolved globally)

2 participants