fix(compiler): map color: inherit to the inherited-color variable#391
Draft
YevheniiKotyrlo wants to merge 1 commit into
Draft
fix(compiler): map color: inherit to the inherited-color variable#391YevheniiKotyrlo wants to merge 1 commit into
color: inherit to the inherited-color variable#391YevheniiKotyrlo wants to merge 1 commit into
Conversation
Tailwind's `text-inherit` (`color: inherit`) was dropped by the compiler and rendered React Native's default text color (black on Android) instead of the parent's color; web inherited correctly via real CSS. lightningcss emits `color: inherit` as an UnparsedProperty (the keyword is not a CssColor), and parseUnparsed's token/ident branch discarded it with a warning. Per CSS Color 4, `currentcolor` used as the value of `color` is defined as `inherit`, so both resolve to the --__rn-css-color variable every color rule already publishes to its subtree -- no new machinery. - parseUnparsed: resolve the inherited-color keywords -- `inherit`, `unset` (CSS Cascade: `unset` computes to `inherit` on the inherited `color` property), and `currentcolor` -- to the variable, matched case-insensitively (`currentColor`, `INHERIT`), instead of dropping them. - parseUnparsedDeclaration: fix the self-reference guard, which compared against a stale "-css-color" literal that never matched the emitted "__rn-css-color". Without it an inheriting rule publishes a circular --__rn-css-color: var(--__rn-css-color), breaking resolution for its subtree. `inherit` on non-color properties, and `initial`, remain dropped with a warning (no per-property inheritance context exists). Adds compiler + native-render tests, including the parent -> child -> grandchild chain that proves the self-reference fix, and corrects the vendor text-inherit test that had encoded the dropped-declaration behaviour.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
text-inherit(color: inherit) renders correctly on web but falls back to React Native's default text color on native — a dark surface with an inheriting label becomes black-on-black:Cause — web keeps the CSS, native drops it
The two runtimes handle
classNamedifferently, and only native breaks:web/api.tsx'suseCssElementassigns{ $$css: true, className }tostyle, so react-native-web applies the class name as a real CSS class.color: inheritis then resolved by the browser's own cascade — nothing is compiled.compiler/declarations.tscompiles each value to an RN style object. Its token/ident branch treatsinheritas unsupported and drops it with a warning, so the<Text>gets no color at all and RN's default wins.So this is a native-only compiler gap, and the fix is native-only.
Fix
The native runtime already carries the mechanism. Because React Native doesn't inherit
coloracross elements, every color rule publishes--__rn-css-colordown its subtree, andparseUnparsedalready resolvescurrentcolorto it.color: inheritjust needs the same path — and it isn't an approximation: per CSS Color 3 §4.4, "if thecurrentColorkeyword is set on thecolorproperty itself, it is treated ascolor: inherit." Same value, same descriptor.1.
parseUnparsed— resolve the inherited-color keywords to that variable instead of dropping them.unsetis included because it computes toinheriton inherited properties andcoloris inherited; matched case-insensitively so thecurrentColorReact authors write (andINHERIT) also land here:2.
parseUnparsedDeclaration— the publish guard compared against a stale"-css-color"literal that never matched the emitted"__rn-css-color", so an inheriting rule would republish a circular--__rn-css-color: var(--__rn-css-color)and break its own descendants:Keyword coverage
colorinherit,unset,currentcolor(any case)var(--__rn-css-color)— the inherited colorinitialinheriton a non-color propertyrevert/revert-layerReproduction
Test plan
Compiler (
src/__tests__/compiler/compiler.test.tsx):color: inheritcompiles to the__rn-css-colorlookup instead of being dropped, with no self-referentialvpublish;inheritandcurrentcolorcompile identically.color: redstill publishes--__rn-css-color; non-colorinheritandinitialstill drop to{}.unset,INHERIT, andcurrentColor(case-insensitive) compile identically toinherit;currentcolorresolves on a non-color property too (border-color).Native render (
src/__tests__/native/colors.test.tsx):color: inherit(andunset) resolves to the parent's color, onViewandText.text-inherittest (vendor/tailwind/typography.test.tsx) that had encoded the dropped-declaration behaviour; it now resolves identically totext-current.yarn test,yarn typecheck,yarn eslint, andprettier --checkpass. (Twobabel/import-plugin suites fail only on Windows — a pre-existing path-separator bug in the plugin, unrelated to this change; green on the maintainer's CI.)