react-strict-dom icon indicating copy to clipboard operation
react-strict-dom copied to clipboard

Issue with `css.defineVars` in React Native when using `react-strict-dom` in monorepo

Open christianbach opened this issue 1 year ago • 9 comments

Describe the issue

We are using react-strict-dom in our React web app and React Native app, and everything works great in the web app. However, we are encountering issues in the React Native app when using css.defineVars from our styling package. Interestingly, the issue seems to be resolved when using ...css.props([]) instead of style=[].

We are bundling the app with Metro and have applied unstable_enablePackageExports to resolve potential export issues.

App Structure:

  • Packages Folder:

    • styling-generator: Imports Figma tokens and generates Stylex files for colors, typography, spacings, etc.
    • ui: Contains components used by both React and React Native apps.
  • Apps Folder:

    • Web: React web app.
    • React Native: React Native app.

Example (Simplified):

spacings.stylex.ts (exported from ui-generated):

import {css} from 'react-strict-dom';

export const spacing = css.defineVars({
  s8: 8,
  s16: 16,
  s32: 32,
});

Gap.tsx (exported from ui):

import {memo} from 'react';
import {css, html} from 'react-strict-dom';

import { spacing } from 'ui-generated/spacings.stylex';

const styles = css.create({
  small: {
    height: spacing.s8,
  },
  medium: {
    height: spacing.s16,
  },
  large: {
    height: spacing.s32,
  },
});

type Props = {
  size?: 'small' | 'medium' | 'large';
};

export const Gap = memo(({size}: Props) => {
  return <html.div style={[size && styles[size]]} />;
});

Issue:

  • In React Native, the styles defined using css.create() and passed through style=[] are not applied as expected (the height is undefined). Even though it works correctly in the web app.
  • Interestingly, if we use ...css.props([]) instead of style=[], the issue is resolved in React Native.
  • We are also seeing the following warning in the console: [warn] React Strict DOM: unrecognized custom property "--s16__id__202". This indicates that a custom CSS property is being used, but it's not recognized in React Strict DOM.

Any insight into why style=[] behaves differently in React Native would be greatly appreciated!

Expected behavior

  • Styles created with css.create that use vars should work correctly in both React and React Native when passed to style=[].

Steps to reproduce

"react": "18.3.1",
"react-native": "0.75.4",
"react-strict-dom": "0.0.33"
  1. Set up the project as described, with react-strict-dom in both the React and React Native apps.
  2. Use css.create to generate styles in the Gap component (as shown in the example).
  3. Observe the issue in the React Native app, where the styles are not applied correctly when using style=[].
  4. Replace style=[] with ...css.props([]) and verify that the issue is resolved in React Native.

Test case

No response

Additional comments

  • The issue appears only in React Native, and everything works as expected on the web.
  • The styling generator relies on Figma tokens, and stylex files are shared across both platforms.
  • The mono repo structure includes separate packages for the styling generator and UI components.
  • We are bundling with Metro and have applied unstable_enablePackageExports to resolve potential export issues.

christianbach avatar Jan 18 '25 16:01 christianbach

What does "not correctly" mean? I don't see any description of what the problem is. css.props is not part of the API in RSD and doesn't work with its elements

necolas avatar Jan 18 '25 20:01 necolas

What does "not correctly" mean? I don't see any description of what the problem is. css.props is not part of the API in RSD and doesn't work with its elements

@necolas I'm sorry, it got lost in one of my edits. I updated the issue. But the problem we are facing is that the style of the Gap component resolves to {height: {}} in our react-native app.

christianbach avatar Jan 18 '25 21:01 christianbach

We use this API without issue at Meta. Your example code has various syntax errors, so I can't tell what problem you might be experiencing. Can you create a test case that reproduces the issue using Expo's snack UI, then share the link?

necolas avatar Jan 18 '25 23:01 necolas

Thanks for the response! I wanted to share some additional details:

In our setup, I got everything working if react-native imports all components, tokens, and themes exclusively from the ui-package, which consumes styling-generator and exports the stylex tokens.

However, when we mix imports directly from both ui-package and styling-generator, and both use defineVars, we encounter issues specifically in React Native, resulting in missing styles.

While debugging, I noticed that not all variables are present in the __customProperties) object . This seems to happen when multiple packages independently call defineVars.

I’ll work on creating a Snack later this week to better demonstrate the issue. Let me know if you have any advice or need more details in the meantime!

christianbach avatar Jan 19 '25 19:01 christianbach

Thanks, that's helpful. I better understand the issue. We don't have a package setup like this internally, so it's the kind of thing that could not be working correctly without us noticing.

necolas avatar Jan 19 '25 22:01 necolas

Are you sure you're not bundling RSD in your native packages, rather than having it as a shared dependency?

necolas avatar Jan 21 '25 19:01 necolas

My guess is that everything is bundled with Metro. In our monorepo, the app depends on the ui package, which in turn depends on the style-generator/token package where the variables are defined.

Unfortunately, I haven't had the time to create a reproduction Snack.

christianbach avatar Jan 21 '25 19:01 christianbach

@christianbach Hi there! 👋 This approach (monorepo with UI / Design Variables packages) is very similar to what we're looking at in a new project. Would be great to get an update from you on the matter - did you manage to solve the issues you were facing?

lundn avatar Mar 05 '25 09:03 lundn

@christianbach Hi there! 👋 This approach (monorepo with UI / Design Variables packages) is very similar to what we're looking at in a new project. Would be great to get an update from you on the matter - did you manage to solve the issues you were facing?

@lundn We are running RDS in production sharing both tokens and ui components between web and native and it’s working great.

The only issue we are facing is that variables/tokens can’t be accessed directly from the variable/tokens package directly in react-native. The solution was to reexport them in the ui-package and then accessing them from there in the native app.

christianbach avatar Mar 12 '25 08:03 christianbach