addon-react-native-web icon indicating copy to clipboard operation
addon-react-native-web copied to clipboard

(Feature request) — support react-native-postcss-transformer

Open movie4 opened this issue 2 years ago • 8 comments

Hello! it is possible to add support react-native-postcss-transformer?

Thanks!

movie4 avatar Jul 19 '23 12:07 movie4

You should already be able to make this work by adding postcss configuration. Similar to how you can use tailwind/nativewind.

I can try to create an example if you like.

dannyhw avatar Jul 19 '23 12:07 dannyhw

@dannyhw Thanks for the quick response!

As I understand it, the problem is that the storybook does not use metro.config.js

It will be great if you help!

metro.config.js

const defaults = require('metro-config/src/defaults/defaults')
const fileTransformer = require.resolve('./metro-transformer.js')
const configMain = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
    babelTransformerPath: fileTransformer,
  },
  resolver: {
    assetExts: defaults.assetExts?.filter((ext) => ext !== 'svg' && ext !== 'css'),
    sourceExts: [...defaults.sourceExts, 'svg', 'css'],
    resolverMainFields: ['sbmodern', 'react-native', 'browser', 'main'],
  },
}

const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')

metro-transformer.js

const upstreamTransformer = require('metro-react-native-babel-transformer')
const postCSSTransformer = require('react-native-postcss-transformer')

module.exports.transform = function ({ src, filename, options }) {
  if (filename.endsWith('.css')) {
    return postCSSTransformer.transform({ src, filename, options })
  } else {
    return upstreamTransformer.transform({ src, filename, options })
  }
}

.storybook/main.js

module.exports = {
  stories: ['../src/components/**/*.stories.?(ts|tsx|js|jsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-react-native-web',
  ],
  framework: '@storybook/react',
  core: {
    builder: '@storybook/builder-webpack5',
  },
}

movie4 avatar Jul 19 '23 12:07 movie4

Yeah but you don't need metro for the plugin because post css is already supported on web

dannyhw avatar Jul 19 '23 12:07 dannyhw

In fact if you just used the classname property with this it should just work already surely?

dannyhw avatar Jul 19 '23 12:07 dannyhw

Let me give you an example

Example component

Test
— test.js
— test.css
— test.stories.js

test.js

import React from 'react'
import { Text, View } from 'react-native'

import styles from './test.css'

export const Example = () => (
  <View style={styles.test}>
    <Text style={styles.test__text}>Text</Text>
  </View>
)

test.css

.test {
  background: black;
  &__text {
    padding: 20px;
    text-align: center;
    color: lime;
  }
}

test.stories.js

import React from 'react'

import { Example } from './test'

export default {
  title: 'components / Example',
  component: Example,
}

export const Basic = (args) => <Example {...args} />

Result in storybook at android emulator

Screenshot 2023-07-19 at 18 04 21

Result in storybook at web, there is no transformation of test.css Screenshot 2023-07-19 at 18 05 48

movie4 avatar Jul 19 '23 13:07 movie4

I understand but my point is still the same.

dannyhw avatar Jul 19 '23 14:07 dannyhw

If you wanted seemless web support from that package it would have to be a feature of react-native-postcss-transformer not storybook anyway.

But my point is that css importing already works for web. So if you used:

React Native CSS modules using className property:

like

<MyElement className={styles.myClass} />

then it should really work because of how classname is part of the dom and css is already supported on web.

You might have to configure css modules for web I guess

dannyhw avatar Jul 19 '23 14:07 dannyhw

@dannyhw something similar https://github.com/kristerkari/react-native-css-modules/issues/31

movie4 avatar Jul 19 '23 14:07 movie4