kristerkari / react-native-css-modules Goto Github PK
View Code? Open in Web Editor NEWStyle React Native components using CSS, PostCSS, Sass, Less or Stylus.
License: MIT License
Style React Native components using CSS, PostCSS, Sass, Less or Stylus.
License: MIT License
Hi,
I have integration as follow the steps you provided but the after creating CSS file and apply on js file. it's working fine in the iOS device but not working on web.
My Code :
import React, { Component } from 'react'
import { ScrollView, StyleSheet, TouchableOpacity, Text, View } from 'react-native'
import styles from "./styles.css";
export default class Dashboard extends React.Component {
render() {
return (
<View className={styles.container}>
<Text className={styles.blue}>Blue Text</Text>
</View>
)
}
}
Can you help me.
Thanks.
Currently CSS media queries and CSS viewport units are not included in the default setup docs.
The main reason is that the default setup of React Native CSS modules does all the transformation during the build of the app, so it means that is no added runtime dependency for your React Native app.
CSS media queries and CSS viewport units need to be calculated at runtime, which means that there is a small piece of javascript that runs each time the app is rendered.
I have not noticed any difference in performance when replacing the default setup with the responsive support (CSS media queries and CSS viewport units). This is why the setup and docs would be much simpler if the responsive features would always be included by default.
The only worry that I have is that there should be some way of verifying that there are no runtime performance regressions if a runtime library is always used. This could be achieved by somehow measuring the runtime performance with the runtime library and without it.
Add support for the export { ... }
syntax from ICSS and Webpack's css-loader which can be used to share code (variables/strings/numbers/etc) between CSS and Javascript.
The way it works is that you'd have a block of code that gets exported to the Javascript side:
variables.scss
$black-color: #414042;
:export {
blackcolor: $black-color;
}
import variables from 'variables.scss';
const CSS = {
backgroudColor: variables.blackcolor
}
export default ({}) => {
return <div style={CSS}>Content</div>
}
It seems that all of the preprocessors support using this syntax, so the syntax only needs to be handled in the CSS parser.
The only compatibility issue compared to Webpack's CSS modules that I noticed is that the exported property can not have the same name as a class that is exported by that file (the last one would overwrite the previous property by the same name). This can be a bit problematic if there is a file with a lot of @imports
that are use the :export
syntax. In most cases that won't be an issue.
Hey! Love your work on this repo.
One suggestion I'd love to see and I'd be happy to help with is to use strings in place of objects or arrays when using react-native-classname-to-style
and react-native-platform-specific-extensions
.
I find it a bit awkward to write
<View
className={[styles.wrapper, disabled ? styles.grey : styles[color].join( ' ' )}
...
especially when there's a ternary involved or there's many configurable styles to apply.
An related example of a similar transformation can found here:
https://github.com/gajus/babel-plugin-react-css-modules
I was wondering if you have any concerns or know any limitations regarding making this into a Babel plugin, and if you would be interested in this?
Cheers :)
Currently the import system for each supported preprocessor works independently, so we won't get the features from metro bundler built in.
It would be great to be able to do something like this:
// variables.ios.scss
$primary-color: blue;
// variables.android.scss
$primary-color: red;
// helloworld.scss
@include 'variables.scss';
.helloWorld {
color: $primary-color;
}
Which would result in blue
color for android and red
color for ios.
It would be great to be able to use metros resolver for this, but second option would be to implement extension to each preprocessors resolver somehow.
Note: platform extensions work when importing from JavaScript, this issue is about within an css file.
In the doc https://github.com/kristerkari/react-native-css-modules/blob/master/docs/setup-css.md for example:
The step 5 is different:
in app.json
:
{
"expo": {
"packagerOpts": {
"sourceExts": ["css"],
"transformer": "node_modules/react-native-css-transformer/index.js"
}
}
}
Any ideas?? Please help.
I followed the instructions in "react-native-css-modules/docs/setup-stylus.md"
While starting my app, it errors like this. It was working till I made all that setup and added .styl.
Error in Bundler console:
Cant start index.js. error
BUNDLE [ios, dev] ../../index.js ░░░░░░░░░░░░░░░░ 0.0% (0/1)::1 - - [29/Nov/2018:00:57:53 +0000] "GET /index.bundle?platform=ios&dev=true&minify=false HTTP/1.1" 200 - "-" "Mobile/1 CFNetwork/974.2.1 Darwin/17.7.0" error: bundling failed: TypeError: transform is not a function
Stack trace
Failed to load bundle(http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false) with error:(/Users/XXX/Documents/mobileXXX/index.js: transform is not a function (null))
__38-[RCTCxxBridge loadSource:onProgress:]_block_invoke.248
RCTCxxBridge.mm:429
___ZL36attemptAsynchronousLoadOfBundleAtURLP5NSURLU13block_pointerFvP18RCTLoadingProgressEU13block_pointerFvP7NSErrorP9RCTSourceE_block_invoke.118
__80-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]_block_invoke
-[RCTMultipartStreamReader emitChunk:headers:callback:done:]
-[RCTMultipartStreamReader readAllPartsWithCompletionCallback:progressCallback:]
-[RCTMultipartDataTask URLSession:streamTask:didBecomeInputStream:outputStream:]
__88-[NSURLSession delegate_streamTask:didBecomeInputStream:outputStream:completionHandler:]_block_invoke
__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__
-[NSBlockOperation main]
-[__NSOperationInternal _start:]
_dispatch_client_callout
_dispatch_block_invoke_direct
_dispatch_client_callout
_dispatch_block_invoke_direct
dispatch_block_perform
__NSOQSchedule_f
_dispatch_client_callout
_dispatch_continuation_pop
_dispatch_async_redirect_invoke
_dispatch_root_queue_drain
_dispatch_worker_thread3
_pthread_wqthread
start_wqthread
```
JS file
import React from 'react';
import styles from './View.less';
import { SafeAreaView, View, Text, TouchableOpacity, } from 'react-native';
class DashboardView extends React.Component {
static navigationOptions = {
title: 'Dashboard',
};
render() {
return (
<SafeAreaView>
<View>
<TouchableOpacity className={styles.button}>
<Text>Hello</Text>
</TouchableOpacity>
<TouchableOpacity className={styles.button1}>
<Text>World</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
}
export default DashboardView;
Style file:
.button, .button1 {
background-color: blue;
padding: 15px;
font-size: 18px;
}
@media screen and (min-width : 768px) and (max-width: 991px) {
.button1 {
background-color: yellow;
}
}
@media screen and (min-width : 1200px) {
.button1 {
background-color: pink;
}
}
When change the screen from landscape to portrait the color of the button with style "button1" changes correct. But when I save my JS file which triggers hot reloading, the background-color changes to the initial value. Tested it on Android.
It seems that Sass imports are not working. I think that I had it working at some point, but maybe some changes broke the imports.
This issue is tracked at the Sass transformer repo:
kristerkari/react-native-sass-transformer#3
When used with Expo Router, Web bundling fails
Web Bundling failed 4470ms (node_modules/expo-router/entry.js)
error: node_modules/expo-router/_ctx.web.js: /node_modules/expo-router/_ctx.web.js: Expected `fromDir` to be of type `string`, got `undefined`
If I comment out the transformer and resolver from metro.config.js, the bundle can succeed.
const { getDefaultConfig } = require("expo/metro-config");
module.exports = (async () => {
const {
resolver: { sourceExts },
} = await getDefaultConfig(__dirname);
// return {
// transformer: {
// babelTransformerPath: require.resolve("react-native-css-transformer"),
// },
// resolver: {
// sourceExts: [...sourceExts, "css"],
// },
// };
})();
PostCSS seems to support having a config file called postcss.config.js
. That file could be used to pass options to a postcss transformer.
Hope that grid layout the amazing feature of css will be in hand of react native that will solve many problems as the default flex layout
make it hardly to arrange the page in diffrent dimenstions
Currently when using React Native CSS modules with Typescript it is only possible to do simple type checking by generating mycssfilename.d.ts
file for each CSS file, which make sure that the classes from the CSS file match the ones that you are using in your React component.
That could be improved by also type checking the CSS properties and values.
How it could be achieved:
<View className={styles.foo} />
, then we know that a matching type should be StyleProp<ViewStyle>
.typed
transformers, (e.g. react-native-typed-sass-transformer
) by first transforming the styles to a react native compatible object and then calling typescript with that CSS + the type.The typescript
package can be used to compile the code from Node.js:
https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
Example
.wrapper {
background-color: blue;
color: red;
}
.text {
color: red;
}
<View className={styles.wrapper} />
<Text className={styles.text} />
↓ ↓ ↓ ↓ ↓ ↓
// This is done as a separate step from the regular transformation
// To typecheck the styles.
typescriptCompile(`
import { TextStyle, ViewStyle } from "react-native";
interface Styles {
wrapper: ViewStyle;
text: TextStyle
}
const _ : Styles = {
wrapper: {
backgroundColor: "blue",
color: "red"
},
text: {
color: "red"
}
}
`)
↓ ↓ ↓ ↓ ↓ ↓
TSError: ⨯ Unable to compile TypeScript:
mystyle.scss.ts:12:7 - error TS2322: Type '{ backgroundColor: string; color: string; }' is not assignable to type 'ViewStyle'.
Object literal may only specify known properties, and 'color' does not exist in type 'ViewStyle'.
12 color: "red"
~~~~~~~~~~~~
When we use css style for border radius, we are having an error on only android devices. IOS works fine!
CSS:
.input { border-radius: 4px; }
The error makes sense since react stylesheet borderRadius only excepts a double:
borderRadius: 4.
But the sass complier should take care of this right?
Our setup:
https://github.com/kristerkari/react-native-css-modules/blob/master/docs/setup-sass.md
We run a clean installation, so newest version of everything (expo).
See screenshot for full android error:
react native 0.61 fast refresh scss style has not changed the UI until reset cache in IOS app
I couldn't find anything to explain that.
It would be great to have a CSS-based solution for linear-gradient. Possibly relying on this community project? https://github.com/react-native-community/react-native-linear-gradient
Add support for CSS calc():
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
Like CSS media queries and CSS viewport units, calc()
values needs to be calculated at runtime because the values can be dynamic (percentages, viewport units).
One of the tricky things with calc()
is that you can use percentages with it for width and height, e.g. calc(50% - 2px)
. That means that in order to support percentages, we need to know the width or height of the element that is using the value.
Getting width/height for an element at runtime in React Native seems possible, so it just needs a proof of concept to see if it actually works together with the style
property:
http://matthewsessions.com/2017/06/27/react-native-on-layout.html
More info:
<View className="style.container">
<Text className="style.text">this should be green</Text>
</View>
in .scss file
.container .text{
color : green
}
The text has not the green color. Am I doing something wrong? Does the library allow this?
Calculating styles dynamically makes it possible to add support for viewport units.
Affected/related projects:
className
property to a call to react-native-dynamic-style-processor
.It would be great to have a CSS-based way of handling animations. I'm guessing it would be possible to delegate to the underlying Animated api?
Todo:
"expo": "40.0.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz"
I checked each step according to the proposed instructions (https://github.com/kristerkari/react-native-css-modules/blob/master/docs/setup-less.md), but not working.
Not for web, not for android
metro.config.js
const { getDefaultConfig } = require('@expo/metro-config')
module.exports = (async () => {
const { resolver: { sourceExts } } = await getDefaultConfig(__dirname)
return {
transformer: {
babelTransformerPath: require.resolve('react-native-less-transformer')
},
resolver: {
sourceExts: [...sourceExts, 'less']
}
}
})()
import theme from './layout.less'
<View className={theme.layout}>
it's okay for using
border:var(--header-background-border);
but if turn to be
border-bottom:var(--header-background-border);
immediately doesn't work
11:29:49 AM: Unable to resolve ./index.scss" from ".//src/containers/Login/index.js: The module
./index.scss could not be found" 11:29:49 AM: Failed building JavaScript bundle 11:29:49 AM: Unable to resolve ./index.scss" from ".//src/containers/Login/index.js
: The module ./index.scss
could not be found"
react native version
react-native-cli: 2.0.1
react-native: 0.55.4
expo version
"expo": "^27.0.1"
packages installed
"babel-plugin-react-native-classname-to-style": "^1.2.1"
"babel-plugin-react-native-platform-specific-extensions": "^1.1.1"
"node-sass": "^4.9.3"
"react-native-sass-transformer": "^1.2.2"
package.json
"expo": { "packagerOpts": { "sourceExts": [ "js", "jsx", "scss", "sass" ], "transformer": "node_modules/react-native-sass-transformer/index.js" } },
.babelrc
{ "presets": ["babel-preset-expo", "react-native"], "env": { "development": { "plugins": ["transform-react-jsx-source", "react-native-classname-to-style", [ "react-native-platform-specific-extensions", { "extensions": ["scss", "sass"] } ] ] } } }
index.js
import Styles from './index.scss';
<TextInput style={Styles.inputClass} />
index.scss
.inputClass { width: 100% }
If I type for example
align-items: notexist;
it instantly crashes in expo go with no errors
Node-sass is deprecated right now - https://www.npmjs.com/package/node-sass:
Warning: LibSass and Node Sass are deprecated. While they will continue to receive maintenance releases indefinitely, there are no plans to add additional features or compatibility with any new CSS or Sass features. Projects that still use it should move onto Dart Sass..
Is it possible to migrate to Dart Sass - https://www.npmjs.com/package/sass in this documentation https://github.com/kristerkari/react-native-css-modules/blob/master/docs/setup-sass.md?
Find out a clean way to pass options from rn-cli.config.js
to node-sass
.
Hello,
I use scss files with react-native, however I was wondering if it was also possible to add path aliases in scss files, I thought of using react-native-sass-transformer but I couldn't find anything,
Here is a typical example:
@import "../../assets/common/__global-colors";
Will become:
@import "@colors"; with alias
Thanks in advance
.footer{
height: 100px;
}
.footer{
height:pxtoDp(100)
}
and the pxtoDp function run at runtime.
I'd love to use react-native-stylus-transformer but due to react-native 0.57.0, it could not find styl path.
https://github.com/react-native-community/react-native-releases/blob/master/CHANGELOG.md#057
Please help!
I'm currently working on a themeable react native project and wanted to implement cascading styles with child selectors.
I saw that you wrote in your FAQ, that cascading childs and complex CSS selectors are not supported:
There is no cascade, CSS properties are not inherited from parent elements.
No complex CSS selectors. There is only support for simple CSS class selector that maps 1-to-1 with an element.
and wanted to add this optional feature.
I had a look at the internal react properties and theoretically could make child selectors, however can't subscribe for child element updates.
Do you have any idea how this feature could theoretically be implemented?
From the typescript setup docs:
Make sure that jsx property is set to react-native in Typescript's compilerOptions
I am trying to setup a react-native-web project with typescript support. Have been using jsx option 'react' as recommended in pretty much all the sample code I have been reading. On switching to 'react-native', module parser throws errors like these:
ERROR in ../src/index.tsx 10:12
Module parse failed: Unexpected token (10:12)
File was processed with these loaders:
../node_modules/ts-loader/index.js
You may need an additional loader to handle the result of these loaders.
| const { height } = react_native_1.Dimensions.get('screen');
| const App = () => {
return (<react_native_1.View>
| <react_native_1.View>
| <react_native_1.Text>hello</react_native_1.Text>
@ ../index.web.tsx 8:30-46
Is there a way to support 'react'? Or an example of react-native-web setup that uses jsx option of 'react-native' with css-loader? I am using the following versions:
"react-native": "0.61.5",
"react-native-web": "^0.11.7",
"typescript": "^3.7.4",
"css-loader": "^3.4.0"
The question likes #22, but when I upgrade expo-cli
, I can't get this working.
expo-cli version: 3.0.10
expo-sdk version: 34.0.0
Thanks
Whenever I use the style or className attribute, I get this error: TS2769: No overload matches this call.
When I run it, it works but I'm not sure why it still gives the red lines and the errors.
Does anyone know a fix to this?
I keep getting Unable to resolve "./App.scss" from "src/modules/app/App.js"
I put the correct babel plugins in .babelrc and put the packageOpts in my app.json. Still not working :(
Add support for CSS custom properties:
https://developer.mozilla.org/en-US/docs/Web/CSS/--*
I'm not yet sure if it's going to be easy, hard or nearly impossible to add support for custom properties as I haven't used them yet myself.
The trickiest part with custom properties is most likely being able to parse them correctly with the css-to-react-native-transform parser.
It's also unlikely that you could update the custom properties using Javascript as React Native does not have the required DOM implementation to do that.
I use react-native-less-transformer and less to style my app。
If i import another .less file in .less file, metro will throw Error 。
┌──────────────────────────────────────────────────────────────────────────────┐
│ │
│ Running Metro Bundler on port 8081. │
│ │
│ Keep Metro running while developing on any JS projects. Feel free to │
│ close this tab and run your own Metro instance if you prefer. │
│ │
│ https://github.com/facebook/react-native │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
Looking for JS files in
D:\P-Project\dproject
Loading dependency graph, done.
transform[stderr]: internal/validators.js:125
transform[stderr]: throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
transform[stderr]: ^
transform[stderr]:
transform[stderr]: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type object
transform[stderr]: at validateString (internal/validators.js:125:11)
transform[stderr]: at Object.join (path.js:427:7)
transform[stderr]: at tryPrefix (D:\P-Project\dproject\node_modules\less\lib\less-node\file-manager.js:76:49)
transform[stderr]: at tryPathIndex (D:\P-Project\dproject\node_modules\less\lib\less-node\file-manager.js:163:19)
transform[stderr]: at tryPrefix (D:\P-Project\dproject\node_modules\less\lib\less-node\file-manager.js:161:25)
transform[stderr]: at ReadFileContext.<anonymous> (D:\P-Project\dproject\node_modules\less\lib\less-node\file-manager.js:148:48)
transform[stderr]: at ReadFileContext.callback (D:\P-Project\dproject\node_modules\graceful-fs\graceful-fs.js:90:16)transform[stderr]: at FSReqWrap.readFileAfterOpen [as oncomplete] (fs.js:237:13)
Hi I have the following problem with @import. I have the following directory structure:
In every View.js I import the View.less, so far so good. The Views.less files look like this:
globals/Default.less
@color_black: #424242;
dashboard/View.less
@import "src/globals/Default.less";
.module {color: @color_black;}
help/View.less
@import "src/modules/dashboard/View.less";
.module {font-size: 14px;}
When I try to run this code it breaks: "TypeError: Path must be a string. Received { resolve: [Function: resolve]". It looks like the first time you import a less file the relative path is the root directory of my project. But when I import the next file "dashboard/View.less" the relative path in that file isn't the root directory anymore, but the directory it is imported from "src/modules/help/". I've tried using ./ or / in "dashboard/View.less" for the Default.less import.
I hope that i've described my problem clear enough en hope you can help me with it.
As the title says, would it be possible to update the typings of an scss file on save, in Visual Studio Code?
Hi!
This issue may be similar to existing issue #31 except I am not using Expo.
Accessing styles through either style
or className
properties has no effect on web. Both properties work fine on mobile though.
Here's a sample repo that can help reproduce. Commit messages have the steps I followed from the documentation on this repo.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.