Jakub
Jakub

Reputation: 2709

How in Material UI to pass a props or a condition to a nested style method

In my react app I have a style built with Material Ui and in detail using makeStyles

My issue is I have these 2 styles applied and I have to pass a condition called isRTL. When isRTL is true I should apply the corresponding style property. However, I tried a below and this does not work for the isRTL condition as getting as undefined.

The method line is used inside the useStyles = makeStyle{} and inside the component is used as const classes = useStyles({ isRTL }).

Need help to make this work correctly for the line element and in general if my approach is ok.

    const line = (theme, isRTL) => {
      console.log('isRTL', isRTL);
      return {
        display: 'block',
        content: '""',
        height: '100%',
        width: 1,
        backgroundColor: '#A3A9AA',
        position: 'absolute',
        top: 0,
        bottom: 0,
        left: isRTL ? 26 : 'initial',
        right: isRTL ? 'initial' : 26,
        zIndex: -1,
    
        [theme.breakpoints.down('sm')]: {
          left: isRTL ? 13 : 'initial',
          right: isRTL ? 'initial' : 13,
        },
      };
    };

const useStyles = makeStyles(theme => ({
  container: {
    paddingLeft: theme.spacing(6),
    paddingRight: theme.spacing(6),
    paddingTop: theme.spacing(4),
    overflowY: 'scroll',
    position: 'relative',
    scrollBehavior: 'smooth',

    [theme.breakpoints.down('sm')]: {
      paddingLeft: theme.spacing(2),
      paddingRight: theme.spacing(2),
      paddingTop: theme.spacing(4),
    },
  },

  itemIndex: {
    width: 51,
    height: 51,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: '50%',
    border: '1px solid currentColor',
    color: theme.palette.grey[500],
    fontSize: '20px',
    backgroundColor: 'white',
    position: 'absolute',
    top: 0,
    left: 0,
    zIndex: 1,
    transition: 'color 0.5s',
    fontFamily: theme.typography.fontFamily,

    [theme.breakpoints.down('sm')]: {
      width: 25,
      height: 25,
      fontSize: '15px',
    },
  },
  itemIndexRTL: {
    width: 51,
    height: 51,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: '50%',
    border: '1px solid currentColor',
    color: theme.palette.grey[500],
    fontSize: '20px',
    backgroundColor: 'white',
    position: 'absolute',
    top: 0,
    right: 0,

    zIndex: 1,
    transition: 'color 0.5s',
    fontFamily: theme.typography.fontFamily,

    [theme.breakpoints.down('sm')]: {
      width: 25,
      height: 25,
      fontSize: '15px',
    },
  },

  completedIndex: {
    color: theme.palette.primary.main,
  },
  skippedIndex: {
    color: theme.palette.warning.main,
    backgroundColor: theme.palette.warning.extraLight,
  },

  item: {
    counterIncrement: 'item',
    position: 'relative',
    paddingLeft: 100,
    paddingBottom: 60,

    [theme.breakpoints.down('sm')]: {
      paddingLeft: 40,
    },

    '&:not(:last-child):before': {
      ...line(theme, isRTL),
      backgroundColor: '#A3A9AA',
    },

    '&:not(:last-child):after': {
      ...line(theme, isRTL),
      backgroundColor: theme.palette.primary.main,
      transformOrigin: 'top',
      transform: 'scaleY(0)',
      transition: 'transform 0.4s',
    },
  },

  itemRTL: {
    counterIncrement: 'item',
    position: 'relative',
    paddingRight: 100,
    paddingBottom: 60,

    [theme.breakpoints.down('sm')]: {
      paddingRight: 40,
    },

    '&:not(:last-child):before': {
      ...line(theme, isRTL),
      backgroundColor: '#A3A9AA',
    },

    '&:not(:last-child):after': {
      ...line(theme, isRTL),
      backgroundColor: theme.palette.primary.main,
      transformOrigin: 'top',
      transform: 'scaleY(0)',
      transition: 'transform 0.4s',
    },
  },

  completedAnswer: {
    '&:not(:last-child):after': {
      transform: 'scaleY(1)',
    },
  },

  skippedAnswer: {
    '&:not(:last-child):after': {
      transform: 'scaleY(1)',
      backgroundColor: theme.palette.warning.main,
    },
  },
}));

Extra details how that used inside the related component and only the line is not working the rest where I was able to apply the condition as in className worked.

<div
            key={item.id}
            ref={itemRefs[index]}
            className={classNames(isRTL ? classes.itemRTL : classes.item, {
              [classes.completedAnswer]: isCompleted,
              [classes.skippedAnswer]: isSkipped,
            })}
          >
            <span
              aria-hidden="true"
              className={classNames(
                isRTL ? classes.itemIndexRTL : classes.itemIndex,
                {
                  [classes.completedIndex]: isCompleted,
                  [classes.skippedIndex]: isSkipped,
                },
              )}
            >
              {index + 1}
            </span>

            <LinearStepperItem
              clearAnswer={setAnswer}
              country={country}
              disableAutoScroll={() => {
                autoScrollConfig.enabled = false;
              }}
              item={item}
              itemIndex={index + 1}
              setAnswer={(answer, autoAcroll) => {
                setAnswer(answer);
                autoScrollConfig.enabled = autoAcroll;
                if (autoAcroll) scrollToNextItem(index);
              }}
              setMeta={setMeta}
            />
          </div>
        );
      })}
    </div>

Upvotes: 1

Views: 243

Answers (1)

Melvynx
Melvynx

Reputation: 1145

You do:

'&:not(:last-child):before': {
      ...line(theme, isRTL),
      backgroundColor: '#A3A9AA',
    },

But You need to do:


'&:not(:last-child):before': props => ({
  ...line(theme, props.isRTL),
  backgroundColor: '#A3A9AA',
}),

Upvotes: 1

Related Questions