Skip to content

RFC: Improvements to compat.native to support resolving vars correctly and access to the inherited text style#501

Open
martinbooth wants to merge 1 commit into
mainfrom
improved_compat.native
Open

RFC: Improvements to compat.native to support resolving vars correctly and access to the inherited text style#501
martinbooth wants to merge 1 commit into
mainfrom
improved_compat.native

Conversation

@martinbooth

Copy link
Copy Markdown
Contributor

Add a second argument to the react.compat callback which exposes StrictReactNativeMetaProps

StrictReactNativeMetaProps has:

resolveStyleValue

A function that will resolve variables to their concrete values

resolveStyleValue('red')            // → 'red'        (no var → returned unchanged)
resolveStyleValue('10px')           // → '10px'       (no var → unchanged)
resolveStyleValue(vars.brand)       // → 'magenta'    (token resolved through the theme cascade)
resolveStyleValue('var(--brand)')   // → 'magenta'    (explicit var() resolved)
resolveStyleValue('var(--missing)') // → null         (unresolvable reference)
  • Ancestor/ingerited theme tokens correctly resolve using this function
  • Light/dark tokens resolve correctly
  • Correctly resolves fallbacks, nested vars, non color vars, etc
  • Avoid exposing any private internals

inheritedTextStyle

Provides access to the text style that would be inherrited by child component

Importantly, it provide access to the color which is used on things like svg elements

A more real world example:

import { compat } from 'react-strict-dom';
import { Path as RNPath } from 'react-native-svg';

function Path({ style, fill, stroke, ...rest }) {
  return (
    <compat.native style={style}>
      {(nativeProps, { inheritedTextStyle, resolveStyleValue }) => (
        <RNPath
          {...rest}
          // RSD doesn't know about SVG paint props, so resolve var()/tokens yourself:
          fill={fill != null ? resolveStyleValue(fill) : undefined}
          stroke={stroke != null ? resolveStyleValue(stroke) : undefined}
          // wire CSS `color` inheritance so `currentColor` works:
          color={inheritedTextStyle.color}
        />
      )}
    </compat.native>
  );
}

@meta-cla meta-cla Bot added the cla signed label Jun 12, 2026
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

workflow: benchmarks/perf (native)

Comparison of performance test results, measured in operations per second. Larger is better.

Results Base Patch Ratio
css.create
· small 1,164,223 1,177,970 1.01 +
· small with units 514,061 518,891 1.01 +
· small with variables 704,971 698,810 0.99 -
· several small 373,987 373,604 1.00 -
· large 215,553 211,909 0.98 -
· large with polyfills 161,960 156,818 0.97 -
· complex 112,157 112,545 1.00 +
· unsupported 220,263 221,720 1.01 +
css.createTheme
· simple theme 235,058 238,038 1.01 +
· polyfill theme 229,265 219,125 0.96 -

@github-actions

Copy link
Copy Markdown

workflow: benchmarks/size

Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.

Results Base Patch Ratio
react-strict-dom/dist/web/index.js
· compressed 3,251 3,251 1.00
· minified 10,375 10,375 1.00
react-strict-dom/dist/web/runtime.js
· compressed 1,645 1,645 1.00
· minified 4,131 4,131 1.00
react-strict-dom/dist/native/index.js
· compressed 16,618 16,719 1.01 +
· minified 64,626 65,279 1.01 +
react-strict-animated/dist/web/index.js
· compressed 6,861 6,861 1.00
· minified 23,486 23,486 1.00
react-strict-animated/dist/native/index.js
· compressed 797 797 1.00
· minified 2,518 2,518 1.00

Summary:
Add a second argument to the react.compat callback which exposes StrictReactNativeMetaProps

StrictReactNativeMetaProps has:

# resolveStyleValue

A function that will resolve variables to their concrete values

```
resolveStyleValue('red')            // → 'red'        (no var → returned unchanged)
resolveStyleValue('10px')           // → '10px'       (no var → unchanged)
resolveStyleValue(vars.brand)       // → 'magenta'    (token resolved through the theme cascade)
resolveStyleValue('var(--brand)')   // → 'magenta'    (explicit var() resolved)
resolveStyleValue('var(--missing)') // → null         (unresolvable reference)
```

- Ancestor/ingerited theme tokens correctly resolve using this function
- Light/dark tokens resolve correctly
- Correctly resolves fallbacks, nested vars, non color vars, etc
- Avoid exposing any private internals

# inheritedTextStyle

Provides access to the text style that would be inherrited by child component

Importantly, it provide access to the color which is used on things like `svg` elements



# A more real world example:

```
import { compat } from 'react-strict-dom';
import { Path as RNPath } from 'react-native-svg';

function Path({ style, fill, stroke, ...rest }) {
  return (
    <compat.native style={style}>
      {(nativeProps, { inheritedTextStyle, resolveStyleValue }) => (
        <RNPath
          {...rest}
          // RSD doesn't know about SVG paint props, so resolve var()/tokens yourself:
          fill={fill != null ? resolveStyleValue(fill) : undefined}
          stroke={stroke != null ? resolveStyleValue(stroke) : undefined}
          // wire CSS `color` inheritance so `currentColor` works:
          color={inheritedTextStyle.color}
        />
      )}
    </compat.native>
  );
}
```
@martinbooth martinbooth force-pushed the improved_compat.native branch from 7b8e4d1 to 7e156de Compare June 12, 2026 22:47
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