Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NativeWind support #26

Closed
freitagdavid opened this issue Oct 4, 2023 · 17 comments
Closed

NativeWind support #26

freitagdavid opened this issue Oct 4, 2023 · 17 comments

Comments

@freitagdavid
Copy link

I've been trying and trying but no matter what I do I can't seem to get this working with NativeWind. I'm not sure if I'm doing something wrong or if this plugin just fundamentally wouldn't work. But it does precisely what I'm needing out of tailwind in my project.

Just thought I would ask, has this been tested in NativeWind?

@L-Blondy
Copy link
Owner

L-Blondy commented Oct 5, 2023

Hi @freitagdavid, do you mind sharing your tailwind config and package.json?

@freitagdavid
Copy link
Author

freitagdavid commented Oct 5, 2023

I've got my redux provider wrapped in a nativewind styled with a dark class on it. I've also tried putting the class directly on the component I'm styling but it's always coming back as undefined in the style object in react devtools.

Here is my config, I was trying to do the minimum required to get it working. I'm currently working on getting tw into our project, gotta have simple theming to do that though. Tailwinds is definitely working got a screen themed but couldn't get tw-colors working.

Edit: Forgot to mention I've got this setup using babel so I don't need to wrap everything.

const {createThemes} = require('tw-colors');

/** @type {import('tailwindcss').Config} */
console.log('ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhh');
module.exports = {
    content: [
        './App.tsx',
        './src/screens/**/*.tsx',
        './src/components/**/*.tsx',
    ],
    theme: {
        extends: {
            // colors: {
            //     grey: {
            //         1400: '#1A1A1A',
            //     },
            //     blue: {
            //         200: '#48B6FF',
            //         500: '#1D609E',
            //         300: '#0192ed',
            //         1000: '#1F3F66',
            //     },
            // },
        },
    },
    plugins: [
        createThemes({
            dark: {
                background: 'black',
            }, 
            red: {
                background: 'red',
            },
        }),
    ],
};

Sadly I can't post my full package.json this is a project for work but here is a sanitized one I'm not sure exactly what is proprietary so I removed anything relating to my company but I think this covers what you would need.

{
    "name": "mobile",
    "version": "8.0.1",
    "private": true,
    "engines": {
        "npm": ">=8.11.0",
        "node": ">=16.16.0"
    },
    "scripts": {
        
    },
    "dependencies": {
        "@notifee/react-native": "^7.7.1",
        "@react-native-async-storage/async-storage": "^1.17.11",
        "@react-native-community/hooks": "^3.0.0",
        "@react-native-community/masked-view": "^0.1.11",
        "@react-native-firebase/analytics": "^18.3.0",
        "@react-native-firebase/app": "^18.3.0",
        "@react-native-firebase/crashlytics": "^18.3.0",
        "@react-native-firebase/messaging": "^18.3.0",
        "@react-native-firebase/remote-config": "^18.3.0",
        "@react-native-firebase/storage": "^18.3.0",
        "@react-native-picker/picker": "^2.4.8",
        "@react-navigation/bottom-tabs": "5.11.7",
        "@react-navigation/elements": "1.3.12",
        "@react-navigation/material-top-tabs": "5.2.17",
        "@react-navigation/native": "5.9.3",
        "@react-navigation/stack": "5.9.1",
        "@skele/components": "^1.0.0-alpha.40",
        "@taboola/react-native-taboola": "2.3.8",
        "@types/uuid": "^9.0.2",
        "axios": "^1.2.0",
        "css-tree": "^2.3.0",
        "date-fns": "^2.29.3",
        "deprecated-react-native-prop-types": "^2.3.0",
        "lodash": "^4.17.21",
        "md5": "^2.3.0",
        "nativewind": "^2.0.11",
        "node-html-parser": "^6.1.4",
        "path": "^0.12.7",
        "react": "18.1.0",
        "react-content-loader": "^6.2.0",
        "react-dom": "18.1.0",
        "react-native": "0.70.1",
        "react-native-android-open-settings": "^1.3.0",
        "react-native-auth0": "^3.0.1",
        "react-native-blob-util": "^0.19.0",
        "react-native-build-config": "^0.3.2",
        "react-native-email-link": "^1.14.7",
        "react-native-fs": "^2.20.0",
        "react-native-gesture-handler": "^2.8.0",
        "react-native-get-random-values": "^1.9.0",
        "react-native-google-analytics-bridge": "^7.1.0",
        "react-native-idle-timer": "2.1.7",
        "react-native-json-tree": "^1.3.0",
        "react-native-linear-gradient": "^2.6.2",
        "react-native-maps": "^1.7.1",
        "react-native-orientation-locker": "^1.5.0",
        "react-native-pager-view": "6.1.2",
        "react-native-pdf": "^6.7.1",
        "react-native-reanimated": "^2.13.0",
        "react-native-render-html": "5.1.1",
        "react-native-safe-area-context": "^4.4.1",
        "react-native-screens": "^3.18.2",
        "react-native-share": "^8.2.2",
        "react-native-svg": "^13.6.0",
        "react-native-svg-transformer": "^1.0.0",
        "react-native-tab-view": "^3.3.2",
        "react-native-url-polyfill": "^1.3.0",
        "react-native-vector-icons": "^9.2.0",
        "react-native-webview": "^11.25.0",
        "react-redux": "^7.2.5",
        "redux": "^4.2.0",
        "typesafe-actions": "^5.1.0",
        "uuid": "^9.0.0"
    },
    "devDependencies": {
        "@babel/core": "^7.12.9",
        "@babel/node": "^7.20.5",
        "@babel/preset-env": "^7.20.2",
        "@babel/runtime": "^7.12.5",
        "@native-html/css-processor": "^1.11.0",
        "@react-native-community/eslint-config": "^2.0.0",
        "@testing-library/react-native": "^11.5.0",
        "@types/gulp": "^4.0.10",
        "@types/jest": "^26.0.24",
        "@types/lodash": "^4.14.150",
        "@types/md5": "^2.3.0",
        "@types/plist": "^3.0.2",
        "@types/qs": "^6.9.7",
        "@types/react-native": "0.70.1",
        "@types/react-native-auth0": "^2.17.5",
        "@types/react-native-share": "^3.3.3",
        "@types/react-native-vector-icons": "^6.4.12",
        "@types/react-redux": "^7.1.18",
        "@types/react-test-renderer": "^18.0.0",
        "@types/redux-mock-store": "^1.0.3",
        "@types/trim": "^0.1.1",
        "@types/yargs": "^17.0.17",
        "@typescript-eslint/eslint-plugin": "^5.51.0",
        "@typescript-eslint/parser": "^5.51.0",
        "@wdio/cli": "^7.19.3",
        "@wdio/local-runner": "^7.19.3",
        "@wdio/mocha-framework": "^7.19.3",
        "babel-jest": "^26.6.3",
        "babel-plugin-module-resolver": "^4.0.0",
        "detox": "^18.20.4",
        "eslint": "^7.32.0",
        "eslint-plugin-wdio": "^7.19.0",
        "gulp": "^4.0.2",
        "husky": "^8.0.0",
        "jest": "^26.6.3",
        "jest-circus": "^29.3.1",
        "jetifier": "1.6.8",
        "metro-react-native-babel-preset": "^0.72.1",
        "mocha": "^9.2.2",
        "patch-package": "^6.5.0",
        "plist": "^3.0.6",
        "prettier": "^2.0.5",
        "qs": "^6.11.0",
        "react-test-renderer": "18.1.0",
        "redux-mock-store": "^1.5.4",
        "redux-thunk": "^2.4.2",
        "tailwindcss": "^3.3.2",
        "tailwindcss-themer": "^3.1.2",
        "tw-colors": "^3.0.3",
        "typescript": "~4.8.4",
        "yargs": "^17.6.2"
    },
    "jest": {
        "preset": "react-native"
    },
    "bundleDependencies": [
        "@react-native-async-storage/async-storage",
        "@react-native-community/masked-view",
        "@react-native-firebase/analytics",
        "@react-native-firebase/app",
        "@react-native-firebase/crashlytics",
        "@react-native-firebase/messaging",
        "@react-native-firebase/remote-config",
        "@react-native-firebase/storage",
        "@react-native-picker/picker",
        "@react-navigation/bottom-tabs",
        "@react-navigation/material-top-tabs",
        "@react-navigation/native",
        "@react-navigation/stack",
        "@skele/components",
        "@taboola/react-native-taboola",
        "axios",
        "css-tree",
        "date-fns",
        "lodash",
        "md5",
        "node-html-parser",
        "path",
        "react",
        "react-content-loader",
        "react-dom",
        "react-native",
        "react-native-android-open-settings",
        "react-native-build-config",
        "react-native-fs",
        "react-native-gesture-handler",
        "react-native-google-analytics-bridge",
        "react-native-idle-timer",
        "react-native-linear-gradient",
        "react-native-maps",
        "react-native-orientation-locker",
        "react-native-reanimated",
        "react-native-render-html",
        "react-native-safe-area-context",
        "react-native-screens",
        "react-native-share",
        "react-native-svg",
        "react-native-svg-transformer",
        "react-native-tab-view",
        "react-native-url-polyfill",
        "react-native-vector-icons",
        "react-native-webview",
        "react-redux",
        "redux",
        "trim",
        "typesafe-actions"
    ]
}

@freitagdavid
Copy link
Author

I've done some further tinkering and it seems like at least vs code intellisense sees that bg-background is a twc variable so that definitely suggests to me that this might just be an issue with using this on a native platform, or with NativeWind itself. It could potentially be that my className isn't being applied properly but I'm unsure. Have you been able to think of any potentials?

image

@L-Blondy
Copy link
Owner

L-Blondy commented Oct 6, 2023

Didn't have time to work on it yet. I need to check if the following color definitions work in NativeWind without using tw-colors

primary: 'hsl(var(--color-primary) / <alpha-value>)'

And

primary: () => #00ff00

If just the first one works, I might get tw-colors to work with NativeWind without supporting colors with a default opacity other than 1

If the second one also works, NativeWind might not have full support for all tailwind plugins features.

I'll try to investigate it next week

@freitagdavid
Copy link
Author

Thanks so much for the quick responses. If this can work with NativeWind it's gonna make my life so much easier. Goodbye 5000 line theme file haha.

@L-Blondy
Copy link
Owner

Fixed in version 3.1.0

@freitagdavid you can say goodbye to your 5000 lines file 😏

@mikewheaton
Copy link

This looks very promising, but I haven't quite been able to get it to work. Here's what I've tried:

// Tailwind config
plugins: [
  createThemes({
    light: {
      test: '#ffcc00',
    },
    dark: {
      test: '#ff0000',
    },
  }),
],
// Component
<Text className="text-test">Testing</Text>

When I inspect the resulting styles, the color being applied is hsl(undefined / 1). Any ideas what I might be missing here?

@L-Blondy
Copy link
Owner

L-Blondy commented Oct 23, 2023

Did you declare your theme in the markup?
Something like this

<html data-theme='light'>

You can also define a default theme in the options.

Also make sire to use version 3.1.2

@mikewheaton
Copy link

mikewheaton commented Oct 23, 2023

Just confirmed I'm on version 3.1.2. This is a React Native project, so I wasn't quite sure where to put data-theme="light". For a quick test I tried it on a parent View like so:

<View data-theme="light">
  <Text className="text-test">Testing</Text>
</View>

If I can get this working manually, I'm hoping to then get the value via the useColorScheme() hook as documented in NativeWind's dark mode page.

@L-Blondy
Copy link
Owner

Try with className instead of data-theme, the View component most likely does not support data attributes

<View className="light">
  <Text className="text-test">Testing</Text>
</View> 

@mikewheaton
Copy link

Unfortunately it's the same result, with the inspector showing a color of hsl(undefined / 1) being set.

@L-Blondy
Copy link
Owner

Can you share your package.json?

@mikewheaton
Copy link

{
  "name": "app",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start --reset-cache",
    "test": "jest",
    "type-check": "tsc",
    "test:report": "jest --collectCoverage --coverageDirectory=\"./coverage\" --ci --reporters=default --reporters=jest-junit --coverage",
    "bitrise-pod-install": "cd ios && NO_FLIPPER=1 pod install && cd ..",
    "pod-install": "cd ios && bundle exec pod install && cd ..",
    "storybook-generate": "sb-rn-get-stories",
    "storybook-watch": "sb-rn-watcher",
    "storybook": "yarn storybook-generate && STORYBOOK_ENABLED='true' yarn start",
    "postinstall": "patch-package"
  },
  "dependencies": {
    "@atomicfi/transact-react-native": "^3.0.4",
    "@gorhom/bottom-sheet": "^4",
    "@react-native-community/geolocation": "^3.1.0",
    "@react-native-masked-view/masked-view": "^0.2.9",
    "@react-native-segmented-control/segmented-control": "^2.4.2",
    "@react-navigation/bottom-tabs": "^6.5.8",
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.13",
    "@react-navigation/stack": "^6.3.17",
    "@reduxjs/toolkit": "^1.9.5",
    "@shopify/flash-list": "^1.6.1",
    "@types/underscore": "^1.11.6",
    "classnames": "^2.3.2",
    "clsx": "^2.0.0",
    "expo": "^49.0.0",
    "expo-linear-gradient": "~12.3.0",
    "lodash": "^4.17.21",
    "lottie-react-native": "^6.1.2",
    "moment": "^2.29.4",
    "nativewind": "^2.0.11",
    "numeral": "^2.0.6",
    "patch-package": "^8.0.0",
    "postinstall-postinstall": "^2.1.0",
    "react": "18.2.0",
    "react-freeze": "^1.0.3",
    "react-native": "0.72.1",
    "react-native-animatable": "^1.3.3",
    "react-native-config": "^1.5.1",
    "react-native-confirmation-code-field": "^7.3.1",
    "react-native-contacts": "^7.0.6",
    "react-native-currency-input": "^1.1.0",
    "react-native-draggable-flatlist": "^4.0.1",
    "react-native-flipper": "^0.212.0",
    "react-native-gesture-handler": "2.12.0",
    "react-native-haptic-feedback": "^2.0.3",
    "react-native-loading-spinner-overlay": "^3.0.1",
    "react-native-magic-modal": "^0.2.20",
    "react-native-maps": "^1.8.0",
    "react-native-mmkv": "^2.10.0",
    "react-native-modal": "^13.0.1",
    "react-native-permissions": "3.10.0",
    "react-native-persona": "^2.6.1",
    "react-native-plaid-link-sdk": "^10.5.0",
    "react-native-reanimated": "^3.3.0",
    "react-native-safe-area-context": "^4.7.2",
    "react-native-screens": "^3.22.0",
    "react-native-segmented-control-tab": "^4.0.0",
    "react-native-svg": "^13.10.0",
    "react-native-svg-transformer": "^1.1.0",
    "react-native-text-input-mask": "^3.2.0",
    "react-native-uuid": "^2.0.1",
    "react-native-vector-icons": "^10.0.0",
    "react-native-webview": "^13.6.0",
    "react-redux": "^8.1.1",
    "redux-flipper": "^2.0.2",
    "redux-persist": "^6.0.0",
    "rn-emoji-keyboard": "^1.5.1",
    "underscore": "^1.13.6"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native-async-storage/async-storage": "^1.19.3",
    "@react-native-community/datetimepicker": "^7.5.0",
    "@react-native-community/slider": "^4.4.3",
    "@react-native/eslint-config": "^0.72.2",
    "@react-native/metro-config": "^0.72.7",
    "@react-navigation/devtools": "^6.0.19",
    "@storybook/addon-actions": "^6.5.16",
    "@storybook/addon-controls": "^6.5.16",
    "@storybook/addon-ondevice-actions": "^6.5.6",
    "@storybook/addon-ondevice-controls": "^6.5.6",
    "@storybook/react-native": "^6.5.6",
    "@testing-library/jest-native": "^5.4.2",
    "@testing-library/react-native": "^12.1.2",
    "@tsconfig/react-native": "^3.0.0",
    "@types/jest": "^29.4.0",
    "@types/metro-config": "^0.76.3",
    "@types/node": "^18.14.1",
    "@types/numeral": "^2.0.3",
    "@types/react": "^18.0.24",
    "@types/react-native": "^0.72.3",
    "@types/react-test-renderer": "^18.0.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^29.2.1",
    "babel-loader": "^8.3.0",
    "babel-plugin-inline-dotenv": "^1.7.0",
    "babel-plugin-module-resolver": "^5.0.0",
    "babel-plugin-root-import": "^6.6.0",
    "dotenv": "^16.3.1",
    "eslint": "^8.19.0",
    "eslint-plugin-import": "^2.28.1",
    "expo-secure-store": "~12.3.1",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "0.76.5",
    "prettier": "^2.4.1",
    "prettier-eslint": "^15.0.1",
    "react-dom": "18.2.0",
    "react-test-renderer": "18.2.0",
    "tailwindcss": "3.3.2",
    "tw-colors": "^3.1.2",
    "typescript": "4.8.4"
  },
  "engines": {
    "node": ">=18"
  }
}

@L-Blondy
Copy link
Owner

I made some tests with an expo setup this time (the previous attempt was with a Next.js setup).

I'm sorry to tell you that NativeWind 2 cannot be supported.
For it to work it should at least support css variables containing multiple values (e.g. --twc-primary: 50 50% 50%)

NativeWind version 3 will not add support for it (see the :root CSS Variables / limitiations section).

@mikewheaton
Copy link

@L-Blondy Thank you for looking into this. It looks like setting CSS variables via the theme might be the way to achieve this in NativeWind v3:

// Source: https://github.com/marklawlor/nativewind/issues/308
// tailwind.config.js
module.exports = {
  theme: {
    variables: {
      "--colors-custom-500": "black"
    },
    darkVariables: {
      "--colors-custom-500": "white"
    },
  }
}

// Compiles to
:root { --custom-500: 'black'; }
.dark { --custom-500: 'white'; }

@L-Blondy
Copy link
Owner

L-Blondy commented Oct 26, 2023

Indeed, in this case tw-colors should not be used.

I might add a nativewind specific export with light and dark themes only in some future version. Need to wait for NativeWind v3 anyways...

@useEffects
Copy link

any update on this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants