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
[React Native] Expand supported CSS for React Native #1309
Comments
Cool! In theory, we can support
It's worth noting that if we did include these units, we could lose the (future?) ability for pre-parsing on native. |
I should first say thanks for your work on this @jacobp100! It's great to have the ability to use styled-components when building for native! Some responses:
My apologies for not digging deeper on I'm just spitballing here, but if features requiring css rules were to be brought to This would allow other parts of css to be supported in the
This would depend on a
Yeah, the base values would rely on I'm not completely clear on future plans for pre-parsing on native. I suppose this would be a tradeoff. Perhaps pre-parsing could be done elsewhere and style declarations that involve these units could be left dynamic (or default base values could be used for pre-parsing, but updated at runtime). Also, I know styled-components is avoiding config as much as possible, but perhaps using these units could be opt-in via config. Or if config is to be avoided, it could be noted in the docs that using these units would prevent pre-parsing of styles. |
@mjsisley @jacobp100 Whatever you end up going with, it'd be great to take ISTF into account, since in the foreseeable future it's likely that styled-components will move to a pipeline that's based on it: https://github.com/cssinjs/istf-spec This would actually be great for a lot of RN transformations, since a lot of transformations can be done just once using the ISTF format. |
ISTF looks great! What is the current target for the ISTF pipeline? v3? It makes sense to wait for the ISTF spec to be finalized and an implementation brought to styled-components before doing much on this front. Based on this, the task would become expanding supported ISTF for React Native (and something like ISTF-to-react-native would be used)? styled-components/native CSS-> ISTF -> react-native stylesheet |
@mjsisley I'd leave that in @jacobp100's judgement 😄 It'll certainly still take a while for this pipeline to be completed. Since ISTF is just a format our idea is to introduce transformers, like for ASTs as in Babel, to introduce certain features and changes. So we'd just need to transform ISTF as we transform CSS today, and on top of that we should have the ability to support lots of new features with less effort. |
Would it be too hard to introduce at least media queries? This is basically the only thing stopping us from using styled components everywhere. |
@sebasgarcep this would be a great starting point for a library that adds helpers for media queries. On Native it could just use the Dimensions window API. I could write a quick proof of concept if you’d like? That has been on my todo list for a while. If you’re interested it’d be great to maintain a community wide version on the org Edit: actually, I could add native support to @morajabi’s https://github.com/morajabi/styled-media-query |
@philpl Skimming through the source of And I tried to understand the source of |
Please beef up support for RN including things like media queries, or put a big banner at top of this page that says you don't support things like media queries. Who makes RN apps w/o media queries? 😤 |
Why this is not a thing yet? |
Actually, @kitten meant we can add media queries support for RN by mixing Dimensions window API with |
@jacobp100 I think the reasons for rejecting #489 should be reconsidered. The reasons given, as far as I can tell: 2 got shot down and 3 is clearly no longer the case, so that just leaves 1. I don't see why leveraging external libraries today means we can't replace them later, either with internal implementations or other libraries. If adding extended-stylesheet support is still even close to as simple as 489 makes it look, we could really have most of this functionality by tomorrow. |
Good to see this discussion is still alive in an open issue! This would be hugely helpful for styled-components primitives. If someone uses media queries to handle responsiveness on the web, it's difficult to have to take a pure js strategy on native if the components and styles are shared. |
@kristerkari has a project that supports additional units. As for media queries, I got something working in cssta. Probably the biggest issue is that these both require adding a runtime to the components, and styled-components doesn't have anything like this yet. There'll probably be a lot of bikeshedding around that |
Yeah so my project react-native-css-modules has support for rem/viewport units and CSS media queries by using regular CSS files. Adding support for With For media queries and viewport units I have created library that calculates the values at runtime based on the values from React Natives Here's a simplified example of how I parse/match the media queries: I think that the same things that I have implemented can be implemented styled-components, but there just needs to be some libraries to handle the runtime calculations. I'm willing to help out with figuring out things, or even creating common libraries as my own project, cssta and styled-components have similar goals. |
The fantasy version of this for me would be to keep styled-component's use of css media queries on web and then do what you've outlined for native. Other libraries have gone 100% JS dimension-detecting on both web and native in an effort to have support on both platforms -- which works unless you want to be able to server side render your pages (the server will never know the dimensions of the screen on request and will have to render styles for a default breakpoint) |
@mjsisley I'm on a project now where we're assessing options for using responsive units with React Native and Styled Components, is there a work around for achieving this yet? React Native Extended Stylesheet is now a pretty popular library: https://www.npmtrends.com/react-native-extended-stylesheet |
Looks like #489 was closed a few years ago, is there a chance it would be merged into the project today? |
Nothing has changed on this front since then, so that PR is still unlikely to be merged |
I think what's changed in the last 2/3 years for React Native developers is that they recognise that some scaling is required across device sizes - React Native Extended Stylesheet's increased download count might support this claim. Having a way to achieve this inside of Styled Components would be ideal. |
Looking at the previous discussion, it seems to me that the problem is more related to the fact that the responsive CSS features require some kind of runtime library for React Native to be added on top of styled-components. It's quite difficult to just pick some of the existing libraries, because you would get more than you are asking for (a lot of features that you are not using). Maybe there has not been anyone willing to put all the effort (probably hundreds of hours) into creating completely new libraries that would be styled-components specific. I know that at least media queries, viewport units, transitions, animations and variables are possible to implement in React Native. A good example of this is the cssta library: |
I think I might be able to make a PR for this. I'm just a little lost with the project structure. Can anyone help me out? I'll explain what I intend to do. vw, vhThis is the easiest part I think. For vw support for instance, we could add a step where we read values for emFor this, it becomes quite easy with the Context API. But we need to assume that all the font-size styling uses styled-components. I think that it is fair to request as much from the users if they want to use em units. Then, all we have to do is create a FontSizeContext initialized to 16, and each time we encounter the style key "font-size", we create a new context Provider with the calculated value within. And each time we encounter an 'em' value, we create a context Consumer to read the current font-size value within the DOM tree, and deduce the actual value of the props. Can someone who is familiar to the project help me out on where I should introduce this logic? |
@Sharcoux I'm not too familiar with the SC project, but I think you're on the right lines for vw/vh. You'd have to do some refactoring because you'll need to listen to dimension changes for when you change from portrait to landscape - and you'd only want to listen to those changes if the component actually depended on these units |
Nice remark. I think I'm set up. I understood where to put my code I think. I'm on my way to create a first draft. |
@jacobp100 @kristerkari could you check what I did if you have a few minutes? I'm still having some minor issues to fix. In the meantime, i'll give it a try for the em system as I couldn't test it with the testing API in place. |
I did a brief review - but neither of us actually work on the styled-components project. We develop css-to-react-native for our own projects and share the library with styled-components |
Ok, Technically, I'm done. I Had to make some architectural choices that might be not ideal in terms of readability but that I can defend in terms of performance. |
But I need to listen to the screen size BEFORE calling css-to-rn, same for em if I want to retrieve the current value... |
How about something like, const Example = () => {
const forceUpdate = useForceUpdate()
const { width, height } = Dimensions.get('window')
let didUseViewportDimensions = false
const style = cssToReactNative([['width', '60vw']], {
get vw() {
didUseViewportDimensions = true
return width / 100
}
})
React.useEffect(() => {
if (didUseViewportDimensions) {
Dimensions.addListener(forceUpdate)
return () => Dimensions.removeListener(forceUpdate)
} else {
return undefined
}
}, [didUseViewportDimensions, forceUpdate])
return <WrappedComponent style={style} />
} |
Yeah, sorry, you are right about v-units. This would work. |
That’s why I think doing it two PRs would make more sense. It will be possible to add font size support, but the overhead might be significant |
Hum... But to create the PR for v-units, it means that I would need to wait for you guys to provide the API that you described above... Do you see a valid reason to do this whereas we can have it working right now? |
I’m not a maintainer for styled components, I just know a bit about parsing css and giving my 2c. It’s up to the maintainers what happens in their project I do think this approach effectively adds css parsing though another means, which is a huge undertaking. We have a huge test suite for each property shorthand supported and we’ve referred to the css specification for these tests. Also, I think properties like border-left-width, border-top-right-radius might be broken in your PR We would consider a PR in css-to-react-native for something that adds the ability to resolve these units though Hope this helps! 😃 |
I don't think that |
Yeah we could totally do that, if it means that we can still support my use case with viewport units which is to parse the CSS at bundle time and do the viewport unit calculations at runtime. I previously created this small library for my own use to do the viewport units calculation: |
@kristerkari It would definitely support doing it at runtime. It looks like we'd just have css-to-react-native absorb your css-viewport-units-transform. Does that work for you? |
Sure, that's fine. |
It would still remain the problem for the user to know if it should listen to window's size changes... |
The example I gave above (using getters) should give you that information. We can look at adding a more official API later |
My bad, I misunderstood how you imagined this being used. Indeed, that would work. |
So what's up guys. @jacobp100 @kristerkari , should I be doing something? |
I don't have a tonne of time at the moment to do this, but I can review a PR if you wanted to give it a shot. Or if I get some time I can pick it up later, but I don't know when that will be |
Well... I tried to understand how things worked there, but I'm not quite sure, so I'd rather let you do it, sorry... |
I'm not very familiar with styled-components' codebase, but I can have a look at the PR. |
Hi all. So what should we do about this? |
Guys, I don't understand. This seems to be a feature requested for a long time. I'm sure that the current implementation in this PR does fill the gap. Isn't there anyone working for this project that could help finishing it? The only issue remaining comes from the tools that were chosen for the project (flow, mainly)... |
Basically, I created rn-css to fix this issue. I'm also bringing other stuff like hover. It's not yet ready for production because of some performance issues I need to fix, but I'm close. I'll also bring media queries. For people looking for a solution while this subject is being merged into styled-components, you can give it a try. |
Hey Guys, Sorry to brought it up. But what's the update on this? I'm trying to use react native on the new project (coming from react and styled-components) but it seems like there are some units missing. I can't seem to find the conclusion after reading the docs and comments here. Does the css-to-react-native allows us to use em and rem in react native now? Cheers |
I'd say that the solution for now is to use rn-css in the place of styled-components (just replace all occurences of |
Well, for those interested, I think that rn-css is now working as expected. Please report if you have issue. |
@Sharcoux, looking at the documentation of rn-css, things like |
@calumjames, this feature would request or to have a ref to the parent which seems complicated to obtain, or to ask users that parents of such a feature must be created with rn-css, which seems more likely to introduce bugs than to help the user. On the other hand, just passing the index of the child as a props and using this kind of code within your component seems easy enough: const StyledChild = styled(Child)`
${props => (props.index % 2) ? /* your css if index is not multiple of 2 */ : /* your css if index is multiple of 2 */}
` You could even create a HOC like that to automatically inject the index as props to your children: const withIndex = (Component) => ({children, ...props}) => {
return <Component {...props}>
{
React.Children.map(children, (child, index) => React.cloneElement(child, { index }));
}
</Component>
} (I didn't exactly try the above code, so use with care) |
Thanks for the response, @Sharcoux. I went with the |
Try using this library emotion-native-extended, also advise, look at this publication. |
We likely would only address this if we start working on #1617. Closing due to inactivity. |
I would like to start a discussion on expanding the CSS supported by
styled-components/native
.Primary items of interest:
It would seem that some of this functionality could be included in css-to-react-native... further improving the convenience of writing styles for React Native components with styled-components. @jacobp100, this looks to be your domain.
It appears this has been discussed in at least a limited manner, but that was in context of a specific method of accomplishing these features and was some time ago.
Looking to precedent in styled-components
Based on the inclusion of shortand and convenient syntax for properties like
transform
, it seems that styled-components is not limiting itself to simple mapping of styles to RN. (https://www.styled-components.com/docs/basics#react-native)Looking elsewhere in the React Native ecosystem
Addressing template questions
How is this product-centric? By allowing usage of em/rem units, viewport units, and media queries... creating native apps in a responsive manner (so they look ideal on all devices) would become much easier. Other included items improve convenience as well.
How does it make workarounds straight forward? Any functionality that is included eliminates the need for using helper libraries or each app having their own method to deal with responsiveness of their styles.
Limitations of React Native in regards to styling.
As discussed here: #1243, some css properties (such as
text-transform
) aren't going to be easy to support, as limitations in React Native prevent them. This discussion is meant for CSS that can be supported (as evidenced elsewhere in the React Native ecosystem) with the current state of React Native.Related issues
*Unitless properties in React Native #835 (comment)
The text was updated successfully, but these errors were encountered: