1

I'm trying to make a list where, when you click on the title, it shows/hide the description below each one. It is partly working (when you click on a title, it shows all the descriptions and when you click again, it hides them all), but I need it to show/hide each item individualy.

import React from 'react'
import styled from 'styled-components'
import girl from '../assets/steps-image.png'
import arrow from '../assets/down-arrow.svg'

class StepsSection extends React.Component{
  constructor() {
    super();
    this.state = {
      show: true
    }
  }
render() {
  return (
    <StepsStyles  className="sections">
    <Illustration />
     <Content>
       <div><span className="tag">3 easy steps</span></div>
      <h1>How it works</h1>

Here we have the list:

      <ul>
        {Steps.map((lista, i)=>(
        <li key={i}>
        <div key={i} onClick={()=>{this.setState({show:!this.state.show})}} className="dropdown"><h2>{lista.title}</h2><img src={arrow} alt="" /></div>
        { this.state.show? <p>{lista.desc}</p> : null}
    </li>
        ))}
        
      </ul>
     </Content>
  </StepsStyles>
  )
}
}

export default StepsSection

This is just styled components:

const StepsStyles = styled.div`
  background: url(${girl}) no-repeat left;
  background-position: left center;
  background-size: contain;  
  margin-top: 200px;
  text-align: left;
  display: grid;
  height: 50vh;
  grid-template-columns:1fr 1fr;
  /* max-height: 50vh; */
  h1{
    font-weight: bold;
    margin-bottom: 5vh;
  }
`

  const Illustration = styled.div`
  grid: 1;
  `

  const Content = styled.div`
  grid: 2;
  text-align: left;
  img {
    max-width: 10px;
    max-height: 10px;
  }
  h2{
    font-weight: bold;
    font-size: 16px;
  }
  ul{
    width: 60%;
  }
  li {
    margin-bottom: 2vh;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--superlight-gray);
    ::last-child{
      border-bottom: none;
    }
    .dropdown {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 10px;
    }
  }
  ` 

And the json static data lays here on the bottom:

const Steps = [
    {
      title: '1. Download Tattoo master app (dropdown)',
      desc: 'Download the application in App Store and you acan find the wizard in any location around the world. '
    },
    {
      title: '2. Enter your location',
      desc: 'Download the application in App Store and you acan find the wizard in any location around the world.'
    },
    {
      title: '3. Find your tattoo master',
      desc: 'Download the application in App Store and you acan find the wizard in any location around the world.'
    }
  ]

here is the page: https://mastertattoo-landpage.netlify.app and repo:https://github.com/micazev/mastertattoo-landpage

Any ideas? Thanks in advance!

Mi Azevedo
  • 39
  • 5

3 Answers3

1

You can use something like this...

{Steps.map((lista, index) => (
  <details className='collapse'>
    <summary className='title'>{lista.title}</summary>
    <div className='description'>
      {lista.desc}
    </div>
  </details>
))}

details and summary are HTML tags for collapse.

locemarn
  • 26
  • 2
0

if you are trying to change the state by the value in the state please pass a function to setState as first argument like this:

this.setState((state, props) => ({
  show: !state.show
}));
  • the state is changing, but it opens all the
  • item once. I want it to open the item respective to the title the user is clicking. for example, if the person click on step number one, only the description hidden of the number 1 opens. right now I click on the number 1 and it opens all the hidden items.
  • – Mi Azevedo May 17 '21 at 22:26