-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
[withStyles] Add the ability to get the component's props from within the style object #7633
Comments
react-jss implement that feature. You can always use it over our styling solution. The real motivation for implementing that feature here should be around simpler/better internal implementation of the components. |
react-jss injectStyles() does this too, but it seems to be that it would be better to add props to the
|
@Shamplol feedback makes me think that we could be taking advantage of this new feature to allow users providing a custom |
@oliviertassinari wouldn't the css size actually decrease in some cases? Either way, I think this would hugely improve dx as we have to basically reimplement complex classes like https://github.com/callemall/material-ui/blob/v1-beta/src/Button/Button.js#L11 when we want to use non palette colors. |
@sakulstra Hard to tell. It will depend on the implementation. Maybe :). |
From a TypeScript typing perspective, it would be nice if both const styles = {
button: {
background: ({ theme }) => theme.palette.primary[200]
},
root: {
backgroundImage: ({ props }) => `url(${props.backgroundImage})`
}
}; The reason is that TypeScript frequently fails to infer the right type for withStyles<'button' | 'root'>(theme => ...) If props are passed in too, this will become withStyles<'button' | 'root', Props>((theme, props) => ...) |
What's the current status of this? It would be really nice to have that feature |
@lucasmafra I have added this feature to the post v1 release milestone. The sooner we can release v1, the better. |
This functionality is key to being able to write expressive style rules that combine props, media queries, and interactive states. You can't replace that functionality with inline styles. Unfortunately, |
You can always setup a custom theme, and use this convention: We really like how styled components gives you access to the props.theme out of the box by nesting ThemeProvider inside MuiThemeProvider when both called theme={theme}. It extends the default theme that mui exposes
|
I just needed to use function values, so I used react-jss' |
@oliviertassinari this probably has significant implications for the typing of |
@pelotom Thanks, I will let you know. I hope I can start looking at the issue this month. |
Is there work in progress regarding this? It's a key feature IMO, maybe I could help with it. EDIT: I started to work on it. Managed to pass props to the |
Hi I just came across a use case where i needed this to customize the colors of the avatar component and there is no other way to control the style for all the variants of the component other than this.
|
You can check my solution Japrogramer: https://github.com/JacquesBonet/jss-material-ui |
thanks, I will take a look at it. |
I needed this feature earlier today so i wrote a HOC. WarningThis component will do a full remount if props change something to do with the index number of the stylesheet class changing or somthing in the withStyles HOC import React from 'react';
import { withStyles } from '@material-ui/core/styles';
const { createElement, forwardRef } = React
const withPropsStyles = ( style ) => {
const withPropsStyles = ( component ) => {
return forwardRef( (props, ref) => {
const proxy = (theme) => style(props, theme)
const hoc = withStyles(proxy)(component)
return props.children ?
createElement(hoc, { ...props, ref}, props.children) :
createElement(hoc, {...props, ref})
})
}
return withPropsStyles
}
export default withPropsStyles Example useconst styles = (props, theme) => ({
root:{
backgroundColor: props.light ? theme.palette.primary.light : theme.palette.primary.main
},
})
const SomeComponent = ({classes}) => <div className={classes.root}/>
export default withPropsStyles(styles)(SomeComponent) conclusionSimple and works(but rem the full remount cost too) |
With this change can we remove inline style usage from the library in favor of 100% JSS? My app does not work with inline styles and when I went to replace the ripple effect with JSS I realized I needed this feature. Maybe a small performance hit, but seems cleaner. |
@koshea ditch the inline style. I also really don't like inline styles too, it should work just fine as a drop in replacement for |
I also wanted to mention, that using inline styles doesn't allow to enable strong Content Security Policy. Dynamic styles with props support should resolve that problem |
Hi guys, sorry to jump in to the discussion "just like this". I recently started using Mui (with Typescript) and whilst I find it an extremely powerful library, it certainly has its complexities. I noticed in some comments above that there's a bit of a discussion for whether this feature should be |
Thank you everyone for the patience! This issue is being taken care of in #13503. It's a requirement for the component helpers we want to implement. We have also started experimenting with the hook API: https://twitter.com/olivtassinari/status/1058805751404261376. |
Did this make it into 4.0? It looks like the |
@city41 |
I see. So it looks like it is
I don't see this documented in the styles API section on the website. Let me see if I can send a PR. |
@city41 There is a start of a documentation in https://material-ui.com/styles/basics/#adapting-based-on-props. |
cool, glad to see the docs are getting updated. for anyone else coming to this issue, here is how I combined theme and props to style a component import React from 'react';
import { Button, Theme, makeStyles } from '@material-ui/core';
interface ButtonProps {
destructive: boolean;
}
const useButtonStyles = makeStyles<Theme, ButtonProps>(theme => {
return {
root: props => ({
backgroundColor: props.destructive ? theme.palette.error.main : theme.palette.primary.main
})
};
});
export const PrimaryButton: React.FunctionComponent<ButtonProps> = props => {
const classes = useButtonStyles(props);
return <Button {...props} className={classes.root} variant="contained" />;
}; |
How can i use prop in an external styles json file ? for example this is external file
i import this file and spread the object
now on color function i get props = {} . can someone help me in this regard ? UPDATE: seems like i am doing something wrong cause i am getting empty object even in my main styles.js file
|
Description
When using
createStyleSheet
, there is no way (at least that i know of) to access the component's props. I think this is important, as sometimes it is wanted to pass sizes, url images, and other stylings as props to the component.Today the only solution to this is to separate these stuff into inline-styles, but as far as i know, material-ui v1 uses
jss
andreact-jss
, and those two already gives you the possibility of access the props via functions that receive the props and then return the desired style, like that:What do you think of implementing something like that on material-ui too?
The text was updated successfully, but these errors were encountered: