How to change the position of an Icon component, within a Tab component?

Issue

I’m using MaterialUI’s tabs in my React project.

This is the JSX for the tabs:

<AppBar color="default" position="static">
       <Tabs indicatorColor="primary" textColor="primary" value={tabIndex} onChange={this.handleChange}>
         {instances.map(instance =>    
            <StyledTab                        
                    style={{ textTransform: 'initial' }}
                    onClick={() => { this.changeActiveInstance(instance.id) }}
                    label={this.getTabAddress(instance)}
                    icon={<ClearIcon ></ClearIcon>}
                  >    
            </StyledTab>
         )}                   
 </Tabs>

This is how i inject the css:

const StyledTab = withStyles({
  root: {
    textTransform: 'initial' 
  },  
})(Tab);

The result is this:
Tab

I would like to position the “ClearIcon” elsewhere. I tried playing with the style injection a bit, with no success.

Can somebody point me to the right direction?

Solution

When trying to customize any Material-UI component, the starting point is the CSS portion of the API documentation. The most relevant classes that you may want to override in this case are wrapper, labelContainer, and label.

The best way to fully understand how these are used and how they are styled by default (and therefore what you may want to override) is to look at the source code.

Here are the most relevant portions of the styles from Tab.js:

  /* Styles applied to the `icon` and `label`'s wrapper element. */
  wrapper: {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
    flexDirection: 'column',
  },
  /* Styles applied to the label container element if `label` is provided. */
  labelContainer: {
    width: '100%', // Fix an IE 11 issue
    boxSizing: 'border-box',
    padding: '6px 12px',
    [theme.breakpoints.up('md')]: {
      padding: '6px 24px',
    },
  },

And here is the relevant code for understanding how these are used:

    if (labelProp !== undefined) {
      label = (
        <span className={classes.labelContainer}>
          <span
            className={classNames(classes.label, {
              [classes.labelWrapped]: this.state.labelWrapped,
            })}
            ref={ref => {
              this.labelRef = ref;
            }}
          >
            {labelProp}
          </span>
        </span>
      );
    }
        <span className={classes.wrapper}>
          {icon}
          {label}
        </span>

Below are some examples of possible ways to customize this.

import React from "react";
import PropTypes from "prop-types";
import Paper from "@material-ui/core/Paper";
import { withStyles } from "@material-ui/core/styles";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import PhoneIcon from "@material-ui/icons/Phone";
import FavoriteIcon from "@material-ui/icons/Favorite";
import PersonPinIcon from "@material-ui/icons/PersonPin";

const styles = {
  root: {
    flexGrow: 1,
    maxWidth: 700
  },
  firstIcon: {
    paddingLeft: 70
  },
  labelContainer: {
    width: "auto",
    padding: 0
  },
  iconLabelWrapper: {
    flexDirection: "row"
  },
  iconLabelWrapper2: {
    flexDirection: "row-reverse"
  }
};

class IconLabelTabs extends React.Component {
  state = {
    value: 0
  };

  handleChange = (event, value) => {
    this.setState({ value });
  };

  render() {
    const { classes } = this.props;

    return (
      <Paper square className={classes.root}>
        <Tabs
          value={this.state.value}
          onChange={this.handleChange}
          variant="fullWidth"
          indicatorColor="secondary"
          textColor="secondary"
        >
          <Tab
            icon={<PhoneIcon className={classes.firstIcon} />}
            label="Class On Icon"
          />
          <Tab
            classes={{
              wrapper: classes.iconLabelWrapper,
              labelContainer: classes.labelContainer
            }}
            icon={<FavoriteIcon />}
            label="Row"
          />
          <Tab
            classes={{
              wrapper: classes.iconLabelWrapper2,
              labelContainer: classes.labelContainer
            }}
            icon={<PersonPinIcon />}
            label="Row-Reverse"
          />

          <Tab icon={<PersonPinIcon />} label="Default" />
        </Tabs>
      </Paper>
    );
  }
}

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

export default withStyles(styles)(IconLabelTabs);

Edit Tab Icon Placement

Answered By – Ryan Cogswell

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published