nativewind / nativewind

React Native utility-first universal design system - powered by Tailwind CSS
https://nativewind.dev
MIT License
4.91k stars 263 forks source link

v4 (4.1.1) - Some styles don't work using className, but do work using style #1018

Closed Cleover closed 1 week ago

Cleover commented 2 weeks ago

In some cases a style does not work in the className prop, but what should be identical to that style does apply in a style prop.

I've run into this issue with a few styles, but the main two instances are listed below.

Honestly I'm more curious why there may be a difference between using className and style with (to my understanding) identical styles being passed, just not sure what may be causing it.

Screenshots

<View
      className="absolute flex-row justify-between items-center px-4"
      style={{width: "100%"}}
>

image

<View
      className="absolute flex-row justify-between items-center px-4 w-full"
>

image

Removing absolute does fix the issue, removing the need to even have w-full, however I'd need absolute still applied.

Additional context I've also had this issue with a few custom styles:

  plugins: [
    plugin(function ({ addComponents }) {
      addComponents({
        ".shadow-0": {
          shadowOffset: {
            width: 0,
            height: 0,
          },
        },
        ".shadow-opacity-half": {
          shadowOpacity: 0.5,
        },
        ".shadow-opacity-1": {
          shadowOpacity: 1,
        },
      });
    }),
  ],

Using shadow-0, shadow-opacity-half or shadow-opacity-1 doesn't do anything however the same styles within the style prop do work.

I know it is properly loading the custom components as making one with fontSize: 50 does work when used in className

ahmedbna commented 1 week ago

I have the same issue but for width except for w-full and also not working for padding nor margin and most of classes!!!

marklawlor commented 1 week ago

I've created this online unit test allowing you to see what props are passed to the underlying component. Both tests are passing for width. Can you please edit this unit test to reproduce the behaviour https://stackblitz.com/edit/nativewind-test-wgnvsy?file=nativewind.test.tsx&view=editor

Alternatively, please provide a minimal repo with the issue replicated.

hlf2016 commented 1 week ago

I've created this online unit test allowing you to see what props are passed to the underlying component. Both tests are passing for width. Can you please edit this unit test to reproduce the behaviour https://stackblitz.com/edit/nativewind-test-wgnvsy?file=nativewind.test.tsx&view=editor

Alternatively, please provide a minimal repo with the issue replicated.

@marklawlor I have the same issue when I use the react-native-safe-area-context sample code below and you may try it

import fs from 'node:fs';
import { View } from 'react-native';
import { screen, render, enableCompilerLogging } from 'nativewind/test';
import config from './tailwind.config';
import { SafeAreaView } from 'react-native-safe-area-context';

// This tells NativeWind log information to the console
enableCompilerLogging(true);

// This is used to identify your component
const testID = 'nativewind';
// Load your CSS as text
const css = fs.readFileSync('./global.css', 'utf-8');

test('should work with inline styles', async () => {
  // Render your component using your custom CSS and tailwind config
  await render(
    <SafeAreaView testID={testID} className="h-full bg-white"></SafeAreaView>,

    {
      css,
      config,
    }
  );

  // Assert that the component was rendered with the correct props
  expect(screen.getByTestId(testID).props).toStrictEqual({
    testID,
    children: undefined,
    style: {
      height: '100%',
      backgroundColor: 'white',
    },
  });
});

test('should work with width', async () => {
  // Render your component using your custom CSS and tailwind config
  await render(
    <SafeAreaView testID={testID} className="h-full bg-white"></SafeAreaView>,
    {
      css,
      config,
    }
  );

  // Assert that the component was rendered with the correct props
  expect(screen.getByTestId(testID).props).toStrictEqual({
    testID,
    children: undefined,
    style: {
      height: '100%',
      backgroundColor: 'white',
    },
  });
});
marklawlor commented 1 week ago

@hlf2016 SafeAreaView is a native component (if you run screen.debug() you can see that it renders RNSafeAreaView and not a View) so you'll need to enable the interop for it via cssInterop(SafeAreaView, { className: "style" })

You can also just share the URL to your test by pressing "Share" and copying the URL. Here is a working version of your test https://stackblitz.com/edit/nativewind-test-wgnvsy?file=nativewind.test.tsx&view=editor

danstepanov commented 1 week ago

Please provide a repro https://github.com/nativewind/nativewind/blob/next/contributing.md#opening-an-issue

hlf2016 commented 1 week ago

@hlf2016 SafeAreaView is a native component (if you run screen.debug() you can see that it renders RNSafeAreaView and not a View) so you'll need to enable the interop for it via cssInterop(SafeAreaView, { className: "style" })

You can also just share the URL to your test by pressing "Share" and copying the URL. Here is a working version of your test https://stackblitz.com/edit/nativewind-test-wgnvsy?file=nativewind.test.tsx&view=editor

OK thanks. But it works well with v2, not so well with v4. Is all this normal?

marklawlor commented 1 week ago

@hlf2016 Yes, please re-read the the v4 post for the changes between v2 and v4. V2 used to change the styles in place with v4 changes them within primitive components. There are pro's and con's to both approaches, but the v4 approach has much better performance and generally provides better styling. It's biggest downside is that it cannot style native components unless you tell it to.

danstepanov commented 1 week ago

closing until there's a proper repro https://github.com/nativewind/nativewind/blob/main/contributing.md#opening-an-issue