Skip to content
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

Styling strategy #9072

Closed
futbolistua opened this issue Nov 9, 2017 · 9 comments
Closed

Styling strategy #9072

futbolistua opened this issue Nov 9, 2017 · 9 comments

Comments

@futbolistua
Copy link

futbolistua commented Nov 9, 2017

In my opinion current styling strategy is awful.

  1. Why you cannot move all styling logic inside component? I do not want to create new components or write extra code. I want to pass object with styles to component and have result as in previous version. But at this moment what should I do to style component

import { withStyles } from 'material-ui/styles';
const styles = {
'list-item-root': {
padding: 0,
},
'checkbox-default': {
padding: 0,
},
};

<ListItem classes={{ root: this.props.classes['list-item-root'] }}>
<Checkbox
classes={{ default: this.props.classes['checkbox-default'] }}/>
<ListItemText primary={value} />
</ListItem>

export default withStyles(styles)(SetFilter);

I want to have 'smart' components
<ListItem classes={this.listItemStyles}>
<Checkbox classes={this.CheckboxStyles}>

  1. I want to style checkbox but this component is to complex
    capture

You provide next API
default
checked
disabled

but I want to change styles for each child node of the component. And I had to write very strange selectors to do that.

Please note that it becomes very difficult to use your components, to style them and to override some behavior

@TroySchmidt
Copy link
Contributor

Wow I literally was just posting about the same thing. The html tags that get generated for a single component with nested ones makes it difficult to customize with CSS. I am not understanding how do I pass CSS styling to a singular component like ListItem and have it apply to the "parent" html tag and the child separately. And I surely don't want to use selectors.
I was wanting to make the secondary action not a singular button but a slider and trying to make that layout properly was so challenging I punted back to using Grid.

@TroySchmidt
Copy link
Contributor

Another example is styling the DialogTitle. I wanted the header text to be a color, but passing the style override didn't do it. I have ended up wrapping the simple text in a span to get it accomplished.

<DialogTitle style={{ backgroundColor: 'navy' }}>
  <span style={{color: 'white'}}>Title</span>
</DialogTitle>

@jordangotbaum
Copy link

Class styling is a nightmare for the table as well. I'm using withstyles and the tablecells will receive some styles but not others, !important hack doesn't work. It's so frustrating.

@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 9, 2017

Another example is styling the DialogTitle

@TroySchmidt We apply some default styles that aren't inherited, you can use the disableTypography to use the inheritance feature of CSS.

<DialogTitle style={{ backgroundColor: 'navy', color: 'white' }} disableTypography>
  <Typography type="title" color="inherit">Title</Typography>
</DialogTitle>

@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 9, 2017

@futbolistua We do no longer offer a first-class support for the inline-style approach with the v1-beta branch. Let us know if you find a case where the CSS API isn't enough. p.s. you don't have to use withStyles.

@oliviertassinari
Copy link
Member

@jordangotbaum Sorry, I can't help with the provided information.

@TroySchmidt
Copy link
Contributor

TroySchmidt commented Nov 9, 2017

@oliviertassinari Okay that example helps a little more in this particular situation. I am still wrapping Title with a lot of stuff there just to tell it the color because of the way the tag spits out nested tags like every time.

<ListItem className={classes.itemClass}>
      <ListItemText primary={label} className={classes.labelClass} style={{flex: '0 auto'}}/>
      <ListItemSecondaryAction className={classes.sliderClass}>
        <Slider discrete={true} min={1} max={7} value={value}/>
      </ListItemSecondaryAction>
</ListItem>

This is another example of where I was having major issues with the parent and child relationship of nearly every tag. What I was trying to do was to take the standard list item example with the button action and add a slider that would grow with the width and the label for it (ListItemText) I could either make it fixed width or growing significantly less using flex styling.
It was so difficult I ended up punting back to Grid tag because it appeared to be a little more clean in not having nested divs. The Slider component here is from rmwc.

@oliviertassinari
Copy link
Member

oliviertassinari commented Nov 9, 2017

Just to tell it the color because of the way the tag spits out nested tags like every time.

@TroySchmidt You have the disableTypography and the classes property to reach nested elements. Here is how to change the color of the list item.

import React from "react";
import PropTypes from "prop-types";
import {
  ListItem,
  ListItemText,
  ListItemSecondaryAction
} from "material-ui/List";
import { withStyles } from "material-ui/styles";

const styles = {
  labelClass: {
    color: "red"
  }
};

function Index(props) {
  const { classes } = props;
  return (
    <ListItem>
      <ListItemText
        primary="primary"
        secondary="primary"
        classes={{ text: classes.labelClass }}
      />
    </ListItem>
  );
}

Index.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(Index);

https://codesandbox.io/s/mm1q4o65zp

I'm closing this issue, the classes property is here to make customization as easy as possible. If you find a case where the situation isn't ideal and have some ideas on how to improve it, let us know!

@TroySchmidt
Copy link
Contributor

TroySchmidt commented Nov 9, 2017

For anyone finding this later and interested in how classes and stateless functional components in TypeScript work out. Here is an example customizing the badge behavior.

import * as React from 'react';
import { Badge, Typography, withStyles, StyledComponentProps } from 'material-ui';

interface Props {
  value: number;
}

const decorate = withStyles<'root' | 'badge'>(({palette, spacing}) => ({
  root: {
    alignItems: 'center',
    flexDirection: 'column',
  },
  badge: {
    color: 'white',
    backgroundColor: '#E81248',
    position: 'relative',
    borderRadius: '10%',
    height: 'auto',
    width: 'auto',
    top: 0,
    right: 0,
    paddingLeft: spacing.unit * 0.5,
    paddingRight: spacing.unit * 0.5,
    margin: spacing.unit,
  }
}));

const MyBadge = decorate<Props & StyledComponentProps<'root' | 'badge'>>( props => {
  const { value, classes } = props;
  
  return (
    <Badge 
      badgeContent={<Typography color="inherit" align="center" type="subheading">{value}</Typography>}
      classes={{root: classes.root, badge: classes.badge}}
    >
      <Typography type="subheading">Total Value</Typography>
    </Badge>
  );
});

export default MyBadge;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants