Я работаю над своим первым проектом React, проектом в рамках курса Udacity.
Задача (или ее часть) состоит в том, чтобы сначала визуализировать серию книжных объектов горизонтально на трех полках.
Мне удалось отобразить полки и книги внутри них, однако книги внутри каждой полки отображаются сверху вниз, а не слева направо.
Одно из опубликованных мной решений - использовать display: inline;
в файле CSS, но я сделал это безуспешно.
Как исправить код, чтобы книги на полках отображались горизонтально?
Я включил файлы ListBooks.js
и App.css
. Дайте мне знать, если мне нужно добавить что-нибудь еще.
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;
}