Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define className in styled components

I'm busy refactoring a React project to use styled components. It's currently using SASS. So, I've got a working component:

import React from 'react';
import styled from 'styled-components';

const MainNavDiv = styled.div`
  display: none;
  font-weight: 300;
  font-size: 1.7rem;
  background-color: #F5F5F5;
  grid-column: 1 / span 2;
  grid-row: 2 / span 1;
  border-top: #D3D3D3 solid 1px;
  border-bottom: #D3D3D3 solid 1px;
  z-index: 3;
  @media (min-width: 51rem) {
    display: block;
  }
`;

const Ul = styled.ul`
  list-style-type: none;
  margin: 0;
  padding: 0;
`;

const Li = styled.li`
  border-bottom: 1px dotted #D3D3D3;
  text-indent: 3rem;
  padding: .5rem 0 .5rem 0;
  height: 2.1rem;
  & :last-child {
    border: none;
  }
  & a {
    text-decoration: none;
    color: #000;
    WebkitTransition: text-indent 0.5s ease, color 0.5s ease;
    MozTransition: text-indent 0.5s ease, color 0.5s ease;
    transition: text-indent 0.5s ease, color 0.5s ease;
    display: block;
    width: 200px;
  }
  & :hover {
    text-indent: 4rem;
    & a {
      color: $secondary-color;
    }
  }
  & span {
    font-size: 1.3rem;
  }
`;

 const MainNav = (props) => {
    return (
      <MainNavDiv>
        <Ul>
          <Li className={props.linkIndentHome}><a href="#" onClick={props.homeContent}>HOME</a></Li>
          <Li className={props.linkIndentSonata}><a href="#" onClick={props.sonataContent}>SONATAS <span>(adults)</span></a></Li>
          <Li className={props.linkIndentIntermezzo}><a href="#" onClick={props.intermezzoContent}>INTERMEZZI <span>(adults)</span></a></Li>
          <Li className={props.linkIndentSonatina}><a href="#" onClick={props.sonatinaContent}>SONATINA <span>(Children)</span></a></Li>
          <Li className={props.linkIndentDatesFees}><a href="#" onClick={props.datesFeesContent}>DATES & FEES</a></Li>
          <Li className={props.linkIndentLive}><a href="#" onClick={props.liveContent}>LIVE! & CHAT</a></Li>
          <Li className={props.linkIndentVideoArchive}><a href="#" onClick={props.videoArchiveContent}>VIDEO ARCHIVE</a></Li>
          <Li className={props.linkIndentGeneral}><a href="#" onClick={props.generalContent}>GENERAL</a></Li>
          <Li className={props.linkIndentMisc}><a href="#" onClick={props.miscContent}>MISC</a></Li>
        </Ul>
      </MainNavDiv>
    )
 };

export default MainNav;

Each Li component is importing a prop from the parent that attaches a class. For example, the first list item will indent that list item when clicked and un-indent all the other list items. This is all kept in the parent state. All good so far. Right now, this indented class is defined in a scss file:

.main-nav__indented {
  border-bottom: 1px dotted $secondary-color !important;
  & a {
    text-indent: 5rem;
    color: $secondary-color !important;
  }
}

I don't want to keep that scss file harboring that indented class. It should be defined somewhere in my MainNavDiv component so I can dropkick that scss file out of my project. But I'm confused on how to implement it.

Can I use the 'attrs' method somehow?:

const MainNavDiv = styled.div.attrs({
  className = // something here
})`
  display: none...
  ...
`;

How and where do I define the main-nav__indented class other than inside a scss file?

like image 206
flimflam57 Avatar asked Jun 11 '18 15:06

flimflam57


1 Answers

You can remove the className prop and add a prop isIndented={props.linkIndentHome} props.linkIndentHome is a bool that holds true or false, to represent if its indented or not.

Pass the prop to the Li component and use it there to take the decision. Something like as follow:

const Li = styled.li`
  border-bottom: 1px dotted #D3D3D3;
  text-indent: 3rem;
  ...other styles
  ${props => props.isIndented && `
    border-bottom: 1px dotted
    ...whatever other styles for indentation
`}
`
like image 106
johnny peter Avatar answered Oct 23 '22 22:10

johnny peter