DEV Community

independnt
independnt

Posted on

Styled Components pt 2

Recently I started using Styled Components to make styled divs in order to make styling individual information easier, now that I'm digging a bit deeper, I've been using them to build upon each other's styles in order to make certain components react based on conditionals!

For instance, I've been working on an application that has the ability to add, remove, or nullify certain components based on conditionals. I have a grid at the bottom, which allows the addition of objects, and I have a top section, where the newly added objects are displayed. The bottom grid should allow for adding the objects, the top grid should allow for the removal of objects, and any objects that have already been added should be nullified, thus eliminating the possibility for duplications.

First, we create a styled div, with our default desired styles, this is the base style we expect for every component wrapped in this div.

///Imported 
///subtleBoxShadow = `box-shadow: 0px 0px 5px 1px ${lightTheme ? '#a9b6ff' : '#121d5b'}`;
///lightBlueBackground = `background-color: #061a44`;
///greenBoxShadow = `box-shadow: 0px 0px 4px 2px #5fff17`;
///redBoxShadow = `box-shadow: 0px 0px 2px 2px #e41111`;


export const Tile = styled.div `
  ${subtleBoxShadow}
  ${lightBlueBackground}
  padding: 10px;
`

Now we can create additional styled components building upon our base "Tile". We now want selectable tiles, with a cursor action on hover, so we add one more. This time, instead of styled.div, we do styled(Tile) so we can build upon the already shown base style.

export const SelectableTile = styled(Tile)`
  &:hover {
    cursor: pointer;
    ${greenBoxShadow}
  }
`

Now we build two more to handle our Deletable Tiles and our Disabled Tile (to avoid duplicates).

export const DeletableTile = styled(SelectableTile)`
  &:hover {
    cursor: pointer;
    ${redBoxShadow}
  }
`

export const DisabledTile = styled(Tile)`
  pointer-events: none;
  opacity: 0.4;
`

Now we have our selectable tiles with a green shadow on hover, but our deletable tyles will override those styles and add a red shadow on hover. Lastly our disabled tiles has a pointer-events set at none, with opacity showing it has been selected and removing the click event action.

Now in the desired component, I set the "Current Tile" variable to our imported Selectable Tile that was created and throw in some conditionals. I add a topSection prop to all tiles in the top section, and create a method called "AlreadyInFavorites()" to find if the desired selected tile is already in my favorites state. Now my function which I'm exporting looks like this:

export default function({coinKey, topSection}){
  return <AppContext.Consumer>
    {({coinList, isInFavorites}) => {
      let coin = coinList[coinKey];

      let TileClass = SelectableTile;
      if(topSection){
        TileClass = DeletableTile
      }else if(isInFavorites(coinKey)){
        TileClass = DisabledTile
      }
      return <TileClass>
        <CoinHeaderGrid topSection={topSection} name={coin.CoinName} symbol={coin.Symbol}/>
        <CoinImage coin={coin}/>
      </TileClass>
    }}
  </AppContext.Consumer>
}

For a little "Context".... ahem. I'm using React context and returning a Consumer which will update upon the state changing. I'm passing it "coinList" from my state which houses all the objects. I se Tileclass equal to my Selectable Tile div, and say that if the object has the topSection prop equaling true, then this means its on the top section and should be deletable, so set to Deletable Tile. If the tile already exists on my favorites, then on the bottom section (where it was originally added from) we make it a Disabled Tile, so we can't add it again. Styled components is changing the way I will create styles and hover/click events moving forward in React. Definitely a new favorite!

Top comments (0)