Skip to content

fix: emit React Native border-start/end props for border-inline styles#379

Open
danstepanov wants to merge 1 commit into
mainfrom
fix-logical-border-props
Open

fix: emit React Native border-start/end props for border-inline styles#379
danstepanov wants to merge 1 commit into
mainfrom
fix-logical-border-props

Conversation

@danstepanov

Copy link
Copy Markdown
Member

Closes #378, follow up to nativewind/nativewind#1737.

What

border-inline-start-color, border-inline-end-color, and the width and shorthand variants compiled to props like borderInlineStartColor that React Native does not have, so every border-s-* and border-e-* utility (and border-x-, which Tailwind v4 also emits as border-inline-) was a silent no-op on native.

  • Renames the inline logical border color and width properties to RN's RTL aware border-start-* and border-end-* props, in both the parsed path and the unparsed path that var() based colors take (the original Custom colors on border-s-* and border-e-* don't work nativewind#1737 report).
  • Fixes the border-inline, border-inline-start, and border-inline-end shorthands to emit those props, and fixes border-inline-width which previously only read the start value.
  • Drops per-side border styles since RN only has a uniform borderStyle. solid is dropped silently because it matches the native default; anything else records a compiler warning.
  • Dev builds now print compiler warnings from the metro transformer, so declarations without a native equivalent are visible while building instead of being collected and discarded.

Tests

  • New src/tests/compiler/logical-borders.test.ts covering colors (literal and var()), widths, shorthands, and the style drop and warning behavior.
  • Updated borders.test.tsx expectations, which previously locked in the invalid borderInline* prop names.
  • Full suite, typecheck, and lint pass locally. The three babel suites fail identically on clean main (missing --experimental-vm-modules in this environment) and are unrelated.

border-inline-start-color and friends compiled to props like
borderInlineStartColor that React Native does not support, so every
border-s-* and border-e-* utility was a silent no-op on native. Rename
them to the RTL-aware border-start-* and border-end-* props in both the
parsed and unparsed paths, fix the border-inline shorthands, and drop
per-side border styles (with a compiler warning when the style is not
solid, since solid matches the native default).

Dev builds now print compiler warnings from the metro transformer so
declarations without a native equivalent are visible while building.

Closes #378
@danstepanov danstepanov added the v5 stability Tracking v5 stability for @latest release label Jul 17, 2026
@danstepanov danstepanov added deferred (post-5.0) Not required for the 5.0 latest release; revisit after and removed v5 stability Tracking v5 stability for @latest release labels Jul 17, 2026

@YevheniiKotyrlo YevheniiKotyrlo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirming from production (Expo SDK 55 · RN 0.83.6 · Tailwind v4) — border-s-* / border-e-* were silently dropped on native before this. Thanks for fixing it at the parser layer.

I compiled the full logical-border matrix through fix-logical-border-props. Longhands and literal shorthands are handled. One gap remains: var()-valued border-inline shorthands still emit borderInline*.

declaration this branch emits
border-inline-start-color: hsl(var(--p)) — longhand borderStartColor
border-inline-color: red blue — literal shorthand borderStartColor + borderEndColor
border-inline-color: hsl(var(--p))var shorthand borderInlineColor
border-inline-width: var(--w)var shorthand borderInlineWidth

A var() routes the shorthand to parseUnparsedDeclaration, where propertyRename maps only the longhands and parseBorderInline* never runs — so border-inline-color / -width fall through unrenamed. Not hypothetical: Tailwind v4's border-x-<token> emits exactly border-inline-color: var(...) (v4 theme colors are CSS vars), so a themed border-x-primary is still a native no-op after this PR.

propertyRename can't cover it — a shorthand needs a 1→2 expansion, not a 1→1 rename — so the fix goes in the same parseUnparsedDeclaration, mirroring your parseBorderInline*. I've opened it as #393, stacked on this branch so the diff is just the delta (+2 cases, logical-borders at 15/15). Merge it in, cherry-pick the commit, or tell me to retarget — whichever's easiest.

Out of scope by design: the full border-inline: 2px solid var() form (still emits borderInline; needs runtime shorthand splitting, and Tailwind never emits it) — a small follow-up if you want it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deferred (post-5.0) Not required for the 5.0 latest release; revisit after

Projects

None yet

Development

Successfully merging this pull request may close these issues.

border-s-* and border-e-* compile to style props React Native does not support

2 participants