-
Notifications
You must be signed in to change notification settings - Fork 82
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
Pseudo selectors #7
Comments
Interesting proposal, I was actually playing around with this the other day. Re pseudo selectors: It might make sense to follow the plans for the new
|
Good idea re: the outline, would you mind moving that to a separate issue? I think a good start could be following what Theme UI does: export JSX versions of primitive components, and then add styled H1, H2, etc..., as well as a base button, and such. I like the way theme UI isn't too opinionated, but it also has all the base components you need to build great UIs out of the box. |
I agree the new pressable component would definitely be the way to follow. I'm all for the JS approach I think that's a great idea. The animated value is also an interesting proposition; I think that it would be especially helpful with the addition of the pressable component as well if you wanted to animate the button on press states along with the hover. Yes! I'll move this into a new issue and just throw some components up there in a checklist and we can add/remove items from there. |
Just came across https://github.com/Sharcoux/rn-css, which has an interesting approach to pseudo selectors like hover, as well as web units like Figured I'd put any other relevant repos / resources here as I figure out the optimal next steps. |
One concern for this solution is to make sure we don't trigger unnecessary re-renders from touches, hovers, etc. necolas/react-native-web#205 (comment) |
While we're at it, the |
Another thing I like about designing in web is responsive font size. It might be out of the scope of this prop, but a |
That's a helpful Github issue. Re-renders would be bad especially if it was listening for hover events on mobile devices as well. I'm a big fan of responsive font sizes as well. I think that if we can create an elegant solution for that it would be a big plus. I'm going to start experimenting with some of these ideas and potentially get a POC or at least a better understanding of some of the obstacles for the psuedo selectors. |
Could From react docs: https://reactnative.dev/docs/direct-manipulation |
Looks like the creator of RNW is chiming in on this here...necolas/react-native-web#1708 |
I'll be sticking to using |
I'm not sure what the move is for now on this. Maybe we can support a On the other hand, if we wrap every element with Maybe the best we could do is re-export pressable, and theme-ify the |
What do you think about adding a boolean to the createThemedComponent/styled function that wraps it in a Pressable? |
That's an interesting idea, a simple I like that it would make it explicitly clear that we have hover styles. |
I think that the prop passed could be a good idea. The component could inherit most of the props from pressable so it would be super convenient to access the hovered state. For example, in a button component, the label styles could be updated from the prop that's passed. I could definitely see this replacing some of my Pressable components atm. |
True, I think that could work. I'm already using RNW 0.14, but since it has some breaking changes and many probably aren't using it yet, maybe we wait for expo to support it by default to keep dripsy backwards compatible with expo. I'll play around with it. |
I think I know how we could add hover support. I'll make it happen after merging the monorepo. The API could be a |
That would be super sweet. I'm currently trying to figure out the best way to support It would be cool if we could handle some of these under the hood in dripsy for sure. |
Some ideas come to mind for how we could do that. I'll look at the monorepo today, hopefully we can get that published to production. |
In our recent project, we've came up with the following solution and it works fine for now, it is heavily inspired by the material ui library - in each component you call With the "makeInteractiveStyles" variant, it also calls a hook underneath that generates all handlers required for the pressable component, and connects those states to the props inside the function, so you have dynamic, changable stylesheets, that take all of the themed values. Even better, it is fully typed so you get props and names inside the returned object, eg. export const Tag: React.FC<TagProps> = ({ onPress, children, ...props }) => {
const { classes, handlers } = useStyles({ onPress })
return (
<Pressable sx={classes.root} {...(onPress && handlers)} {...props} accessibilityRole="button">
<Text sx={classes.text}>{children}</Text>
</Pressable>
)
}
const useStyles = makeInteractiveStyles(
({ isHovered, onPress }: PropsWithInteractions<TagProps>) => ({
root: {
backgroundColor: pickValue('primary-400', isHovered && 'primary-600'),
cursor: pickValue('default', onPress && 'pointer'),
borderRadius: 100,
px: [3, null, 4],
py: 2,
},
text: {
color: 'white',
fontWeight: 'semibold',
fontSize: [1, null, 2],
lineHeight: [0, null, 2],
},
})
)` |
This is awesome. Thanks for sharing. I might use some of this logic in one of my projects. I'm still curious if there might be a way to work in variants inside of the theme and be able to pass them to the hook to produce results. The part I'm currently struggling with is being able to theme pseudo styles including animations with |
Interesting approach! As I mentioned at #69 (comment), I've opted to just use |
I may have found something interesting regarding not only pseudo selectors but also media queries. Recently I've been looking for alternatives to Fresnel as the responsive style solution, as I'm not really keen on the idea of generating all breakpoints on the server side and sending them to client. I've decided to try Emotion and react-responsive, with the idea of estimating the client screen dimensions on the server side based on client-hints and user-agent, and populating the media query state with it. After some time I've encountered a bug related to SSR with @emotion/native and react-native-web, which led me to the idea of using separate packages on web and native. It turned out to be working quite well, generating media queries and SSR styles on the web without the need for rendering each breakpoint as a DOM node, while on native responsive styles are handled by JS. It seems like it would be possible to use the same approach to use pseudo selectors on web, and handle them using JS on native (maybe wrapping with Pressable and passing interaction state as a prop - isHovered, isFocused?). Here's the issue in detail with an example repo: emotion-js/emotion#2356 (comment). Maybe we could a similar approach with Dripsy? |
Yeah I hear you, and I did try that. The problem is, I still want to wrap React Native components, such as View, Text, and any custom ones. But React Native Web doesn't forward the className prop, which is what allows us to use those kinds of styles, such as media queries. |
The best solution I've come up with for 95% of the time is a |
That's true, I had to use the patch from SnackUI which brings back the className to get @emotion/styled to work with React Native components through React Native Web. Not sure if using this patch for a library would be ideal, but it fixes a lot of problems |
Yeah, I'm concerned about a patch for something so fundamental, though. While I really wish RNW had a className escape hatch (like, I am shocked it doesn't), it seems like this is the best we can do. I don't want a design system to force people to change such a fundamental thing about RNW. I tried to discuss this on the RNW repo, along with many others, and got nowhere. Nicolas doesn't seem interested in allowing class names, and doesn't think CSS media queries should be used. Instead, he recommends conditional rendering altogether. 🤷🏼♂️ |
I'll probably release a major version (v2) with the Div and Span as the recommended API. It's really a bummer, since I don't want to entirely circumvent RNW, and it feels like doing exactly that. The alternative, and recommended approach by RNW, is to just drop SSR support and use the |
I tried my best here: necolas/react-native-web#1318 (comment) |
Yeah, I've seen the discussion around the className is quite heated 😁. Guess I'll continue using the patch for now as it seems to be the simplest and most efficient solution in my case. |
Yeah it's really tough. |
Is this the best solution at this point? // * We have extracted colors to an external refrence for use in
// * react native element's `style={({ hovered, pressed }) => ({`
// * because Dripsy doesn't support hover states through `sx` and `&:hover`
// * https://github.com/nandorojo/dripsy/issues/7 |
I ultimately decided to leave this up to |
Gotcha, so this is fine if I need theme values, just that if I want to change or animate anything, I'm gonna have to explicitly pull those in. I'm not so in need of animations, I may upgrade later though. I need the responsive stuff most of all so Dripsy takes precedence. Although there is probably a hook way of doing that without SX. |
Is there a current plan to support pseudo selectors like hover, focus, etc. I know they aren't currently supported by react-native-web and are usually handled with react hooks similar to how the breakpoints are currently being handled. I think this could be a handy feature but I'm not 100% sure the best way this is currently being handled but I did read an article by Evan Bacon about handling them elegantly.
I think that a similar approach could be used to hijack the sx object being passed into the components that would key off of the basic pseudo-selectors (:hover, :focus, :active) and use the proper logic to allow for the desired effect.
Also is there any idea for what components should be implemented? I think it might be helpful to create a top-level outline of the different components that might be implemented and what it's in the scope of the design system from a library perspective.
The text was updated successfully, but these errors were encountered: