3therk1ll
3therk1ll

Reputation: 2421

Rendering a list of objects left to right in React

I am working on my first React project, a project as part of a Udacity course.

The task (or this part of it) is to initially render a series of book objects horizontally in three shelves.

I have managed to render the shelves and the books within them, however the books within each shelf are being rendered top to bottom rather than left to right.

One of the solutions I have seen posted is to use display: inline; in the CSS file but I have done that with no success.

How can I fix the code so that books within shelves are rendered horizontally?

I have included the ListBooks.js and App.css files. Let me know if I need to add anything else.

ListBooks.js

import React, { Component } from 'react';
import PropTypes from 'prop-types'
import './App.css'

const shelves = [
  {
    key: 'currentlyReading',
    name: 'Currently Reading'
  },
  {
    key: 'wantToRead',
    name: 'Want To Read'
  },
  {
    key: 'read',
    name: 'Read'
  }
];

class ListBooks extends Component {

    static propTypes = {
       books: PropTypes.array.isRequired
    }

    state = {
        showSearchPage: false,
        query: ''
      }

    render() {

        const { books } = this.props

        function getBooksForShelf(shelfKey) {
          return books.filter(book => book.shelf === shelfKey);
        }

        return(
            <div className="app">
            {this.state.showSearchPage ? (
              <div className="search-books">
                <div className="search-books-bar">
                  <a className="close-search" onClick={() => this.setState({ showSearchPage: false })}>Close</a>
                  <div className="search-books-input-wrapper">
                    {/*
                      NOTES: The search from BooksAPI is limited to a particular set of search terms.
                      You can find these search terms here:
                      https://github.com/udacity/reactnd-project-myreads-starter/blob/master/SEARCH_TERMS.md
                      However, remember that the BooksAPI.search method DOES search by title or author. So, don't worry if
                      you don't find a specific author or title. Every search is limited by search terms.
                    */}
                    <input type="text" placeholder="Search by title or author"/>
                  </div>
                </div>
                <div className="search-books-results">
                  <ol className="books-grid"></ol>
                </div>
              </div>
            ) : (
              <div className="list-books">
                <div className="list-books-title">
                  <h1>My Reads</h1>
                </div>
                <div className="list-books-content">
                  <div>
                    { shelves.map((shelf) => (
                      <div key={shelf.key} className="bookshelf">
                        <h2 className="bookshelf-title">{shelf.name}</h2>
                          <div className="bookshelf-books">
                            <ol className="books-grid">
                        <li>
                          { getBooksForShelf(shelf.key).map((book) => (
                            <div key={book.id} className="book">
                              <div className="book-top">
                               <div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${book.imageLinks.thumbnail})` }}></div>
                                <div className="book-shelf-changer"> 
                                 <select>
                                  <option value="none" disabled>Move to...</option>
                                    <option value="currentlyReading">Currently Reading</option>
                                    <option value="wantToRead">Want to Read</option>
                                    <option value="read">Read</option>
                                    <option value="none">None</option>
                                   </select>
                                </div>
                              </div>
                              <div className="book-title">{book.title}</div>
                             <div className="book-authors">{book.author}</div>
                            </div>
                            ))}
                          </li>
                        </ol>
                        </div> 
                      </div>
                    )) }
                  </div>
                </div>
                <div className="open-search">
                  <a onClick={() => this.setState({ showSearchPage: true })}>Add a book</a>
                </div>
              </div>
            )}
          </div>
        )
    }
}

export default ListBooks

App.css

html, body, .root {
  height: 100%;
}
body {
  line-height: 1.5;
}
body, .app {
  background: white;
}

/* main page */

.list-books-title {
  padding: 10px 0;
  background: #2e7c31;
  text-align: center;
}
.list-books-title h1 {
  font-weight: 400;
  margin: 0;
  color: white;
}

.list-books-content {
  padding: 0 0 80px;
  flex: 1;
}

.bookshelf {
  padding: 0 10px 20px;
}

@media (min-width: 600px) {
  .bookshelf {
    padding: 0 20px 40px;
  }

}

.bookshelf-title {
  border-bottom: 1px solid #dedede;
}
.bookshelf-books {
  text-align: center;
}

.open-search {
  position: fixed;
  right: 25px;
  bottom: 25px;
}
.open-search a {
  display: block;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: #2e7d32;
  background-image: url('./icons/add.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 28px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
  font-size: 0;
}

/* search page */

.search-books-bar {
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
  z-index: 5;
  display: flex;
  box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 0 6px rgba(0,0,0,0.23);
}
.search-books-input-wrapper {
  flex: 1;
  background: #e9e;
}
.search-books-bar input {
  width: 100%;
  padding: 15px 10px;
  font-size: 1.25em;
  border: none;
  outline: none;
}

.close-search {
  display: block;
  top: 20px;
  left: 15px;
  width: 50px;
  height: 53px;
  background: white;
  background-image: url('./icons/arrow-back.svg');
  background-position: center;
  background-repeat: no-repeat;
  background-size: 28px;
  font-size: 0;
}

.search-books-results {
  padding: 80px 10px 20px;
}

/* books grid */

.books-grid {
  list-style-type: none;
  padding: 0;
  margin: 0;

  display: inline;
  justify-content: center;
  flex-wrap: wrap;
}
.books-grid li {
  padding: 10px 15px;
  text-align: left;
}

.book {
  width: 140px;
}
.book-title,
.book-authors {
  font-size: 0.8em;
}
.book-title {
  margin-top: 10px;
}
.book-authors {
  color: #999;
}

.book-top {
  position: relative;
  height: 200px;
  display: flex;
  align-items: flex-end;
}

.book-shelf-changer {
  position: absolute;
  right: 0;
  bottom: -10px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #60ac5d;
  background-image: url('./icons/arrow-drop-down.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 20px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
.book-shelf-changer select {
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

/* book cover */

.book-cover {
  box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
  background: #eee;
}
.book-cover-title {
  padding: 20px 10px 0;
  text-align: center;
  font-size: 0.8em;
}

Upvotes: 1

Views: 2084

Answers (1)

Renzo Calla
Renzo Calla

Reputation: 7696

Try setting your shelf element, with display flex as it is suggested in your comments...

 .list-books-content li {display: flex; flex-direction: row;}

Upvotes: 1

Related Questions