cocool97
cocool97

Reputation: 1251

Make element's height adaptative to what's inside

I want to make a grey-colored background for my list in ReactJS.
The problem is that the background seems to have a fixed height which seems to be smaller than the inside's height...
I never met this problem before, and the only way I found to have the background size bigger than the element's is to put height: XXXpx, which is not suitable...
Can someone explain me what I did wrong ?

Here is my class file :

import React, { Component } from "react";
import { ListGroupItem } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
import { API } from "aws-amplify";

import "./ProjectList.css";

export default class ProjectList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isLoading: true,
      projects: [],
      reducedView: true,
      projectsNumber: 1000,
      numberOfElementsToDisplay: 1000
    };
  }

  async componentDidMount() {
    try {
      const projects = await this.projects();
      console.log(projects)
      this.setState({ projects });
    } catch (e) {
      alert(e);
    }

    this.setState({ isLoading: false });
  }

  projects() {
    return API.get("economics-endpoint", "/list");
  }

  handleClick(e) {
    this.setState({ reducedView: false });
    e.preventDefault();
  }

  renderNotesList(projects) {
    return [{}].concat(projects).map(
      (note, i) => {
        if(i !== 0){
            if((this.state.reducedView && i <= this.state.numberOfElementsToDisplay) || !this.state.reducedView){
              return(
                <div className="element">
                  <ListGroupItem className="mainContainer">
                    <div>
                      ProjectName#{i}
                    </div>
                  </ListGroupItem>
                </div>
              );
            }
        }
        else{
          if(this.state.projectsNumber === 0){
            return(
              <div className="element">
                <LinkContainer to={`/econx/new`}>
                  <ListGroupItem className="new">
                    <div>
                      + Create New Project
                    </div>
                  </ListGroupItem>
                </LinkContainer>
                <div className="errorMessage">
                  You don't have any existing project yet.
                </div>
              </div>
              );
          }
          else{
            return(
              <div className="element">
                <LinkContainer to={`/econx/new`}>
                  <ListGroupItem className="new">
                    <div>
                      + Create New Project
                    </div>
                  </ListGroupItem>
                </LinkContainer>
              </div>
            );
          }
        }
      }
    );
  }

  render() {
    return (
      <div className="ProjectList">
        <div className="projects">
          {!this.state.isLoading &&
                this.renderNotesList(this.state.projects)}
        </div>
      </div>
    );
  }
}

And my css file :

.ProjectList .notes h4 {
  font-family: "Open Sans", sans-serif;
  font-weight: 600;
  overflow: hidden;
  line-height: 1.5;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.projects{
  background-color: #E0E0E0;
  border-radius: 10px;
  padding: 1%;
}

.list-group-item{
  margin-bottom: 3px;
  padding: 0px;
  line-height: 200px;
  text-align: center;
  vertical-align: middle;
  border-radius: 6px;
  padding-bottom: 50px;
}

.list-group-item:first-child{
  padding: 0px;
  border-radius: 6px;
}

.list-group-item:hover{
  vertical-align: baseline;
}

.element{
  width: 20%;
  float: left;
  padding: 0% 1% 1% 1%;
}

Upvotes: 1

Views: 66

Answers (1)

Reed Dunkle
Reed Dunkle

Reputation: 3587

This doesn't answer your CSS question. I did have some thoughts on the JavaScript, though. I'll offer my refactor for your consideration. Hopefully I interpreted your original logic correctly:

import React, { Component } from "react";
import { ListGroupItem } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
import { API } from "aws-amplify";

import "./ProjectList.css";

export default class ProjectList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isLoading: true,
      projects: [],
      reducedView: true,
      projectsNumber: 1000,
      numberOfElementsToDisplay: 1000
    };
  }

  async componentDidMount() {
    try {
      const projects = await this.fetchProjects();
      console.log(projects);
      this.setState({ projects });
    } catch (e) {
      alert(e);
    } finally {
      this.setState({ isLoading: false });
    }
  }

  fetchProjects = () => {
    return API.get("economics-endpoint", "/list");
  };

  handleClick = e => {
    e.preventDefault();
    this.setState({ reducedView: false });
  };

  render() {
    const {
      isLoading,
      numberOfElementsToDisplay,
      projectsNumber,
      reducedView
    } = this.state;

    const projects = reducedView
      ? this.state.projects.slice(0, numberOfElementsToDisplay)
      : this.state.projects;

    return (
      <div className="ProjectList">
        <div className="projects">
          {!isLoading && (
            <React.Fragment>
              <div className="element">
                <LinkContainer to={`/econx/new`}>
                  <ListGroupItem className="new">
                    <div>+ Create New Project</div>
                  </ListGroupItem>
                </LinkContainer>
                {projectsNumber === 0 && (
                  <div className="errorMessage">
                    You don't have any existing projects yet.
                  </div>
                )}
              </div>
              {projects.map((project, index) => (
                <div className="element">
                  <ListGroupItem className="mainContainer">
                    <div>ProjectName#{index}</div>
                  </ListGroupItem>
                </div>;
              ))}
            </React.Fragment>
          )}
        </div>
      </div>
    );
  }
}

This fixes your off-by-one issue by hopefully capturing your intentions as I understand them:

  1. If it's not loading...
  2. Show a "Create New Project" item
  3. If they don't have any projects yet, show them a message
  4. If they do have projects, create a new element for each one

It's worth considering whether your projectsNumber could be replaced with projects.length. If so, you can probably combine (2) and (3) above to be an either-or scenario: If they don't have projects, show a message, if they do, show the projects.

Upvotes: 1

Related Questions