I'd like to show the buttons row direction.
I've given disply:flex but it still shows column.
It should be the button has a first character of the name which is underneath the button
and these buttons should be next to each other.
Not like button on the left and the name on the right.
Would be appreciated if I could get help.
RoomList.js
import React from 'react';
import './RoomList.css';
import PropTypes from 'prop-types';
const RoomList = ({ roomList }) => {
return (
<div>
{roomList.map((room) => {
const firstToChar = room.split('');
const firstChar = firstToChar[0];
return (
<div>
<li className="list">
<div className="room-list">
<button type="submit">{firstChar}</button>
<div>{room}</div>
</div>
</li>
</div>
);
})}
</div>
);
};
RoomList.propTypes = {
roomList: PropTypes.func.isRequired,
};
export default RoomList;
RoomList.css
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
The problem is with the HTML you produce. You produce one list by room. Which is not what you want, you want one list, and one item by room in your list.
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
<div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">K</button>
<div>Kitchen</div>
</div>
</li>
</div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">B</button>
<div>Bathroom</div>
</div>
</li>
</div>
</div>
What you want is:
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
<div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">K</button>
<div>Kitchen</div>
</div>
<div class="room-list">
<button type="submit">B</button>
<div>Bathroom</div>
</div>
</li>
</div>
</div>
So you actually want:
const RoomList = ({ roomList }) => {
return (
<div>
<div>
<li className="list">
{roomList.map((room) => {
const firstToChar = room.split('');
const firstChar = firstToChar[0];
return (
<div className="room-list">
<button type="submit">{firstChar}</button>
<div>{room}</div>
</div>
);
})}
</li>
</div>
</div>
);
};
The flex should be on the room list instead
Related
what is the best practice to show/hide the side menu with animation? The way I implement works fine but I can't implement the animation. I also shared images so everyone can have some idea.
The answer might be easy but I couldn't fully understand the toggle class efficiently. If I would I should be able to implement transition just by changing the width from the same classname.
Also I am getting this error on console: Received false for a non-boolean attribute className.
React code ;
const handleSize = () => {
setOpen(!open); }; return (
<div
className={"sideBar" + `${open ? " sideBar__show" : " sideBar__hide"}`}
>
<div className="sideBar__header">
<div className="menu_buttons" onClick={handleSize}>
<MenuIcon className="sideBar_icon" />
<p className={!open && "sideBar_hide__content"}>Menu</p>
</div>
</div>
<hr className="sideBar__divider" />
<div className="sideBar__content">
{sideBarContent.map((item) => {
return (
<div className="menu_buttons" key={item.name}>
<item.icon />
<p className={!open && "sideBar_hide__content"}>{item.name}</p>
</div>
);
})}
</div>
<hr className="sideBar__divider" />
<div className="sideBar__footer">
<Avatar>{firstLetter}</Avatar>
<p className={!open && "sideBar_hide__content"}>{adminName}</p>
</div>
</div> ); };
CSS;
.sideBar {
position: fixed;
left: var(--sidebar-left-margin);
height: max-content;
top: calc(var(--header-height) + 10px);
bottom: 10px;
border-radius: 10px;
background-color: var(--second-color);
display: flex;
flex-direction: column;
align-items: center;
padding: 10px 5px;
border: 1px solid var(--main-color);
/* transition: all ease-in 1s; */
}
.sideBar__show {
width: var(--sidebarOpen-width);
}
.sideBar_hide {
width: var(--sidebarClose-width);
}
.sideBar_hide__content {
display: none;
}
Not sure what is best practice, this is my currently approach:
const handleSize = () => setOpen(!open);
const sideBarClasses = open ? "sideBar sideBar_show : "sideBar sideBar_hide;
<div className="sideBar__header">
<div className={sideBarClasses}>
This was pretty simple in Vanilla JS but I'm struggling to implement this in React.
I have Navbar with some links. Upon hovering over each link, I'd like the background color of the entire Navbar (classname: nav-section) to change accordingly.
And by default I want to have a black color for the page. Anytime the cursor is not on any of the links, the navbar should be back to black again.
Say, my simplified Navbar.js is like this:
const Navbar = () => {
return (
<nav className='nav-section'>
<div className="nav-list">
<a className="list-item one">
<div className="navlink-text">Red</div>
</a>
<a className="list-item two">
<div className="navlink-text">Blue</div>
</a>
<a className="list-item three">
<div className="navlink-text">Aqua</div>
</a>
<a className="list-item four">
<div className="navlink-text">Cyan</div>
</a>
</div>
</nav>
);
};
export default Navbar;
I have an external css file styling the navbar and other elements that I have in it.
What is the most efficient way to achieve what I want, with React? I tried to use emotion/css but I couldn't make it work. Any guidance is well appreciated.
If I understand it correctly there are 2 possible solutions I wrote;
with css =>
.nav-section {
pointer-events: none;
background-color: black;
}
.nav-section:hover {
pointer-events: none;
background-color: red;
}
.nav-section > .nav-list {
display: inline-flex;
flex-direction: column;
}
.nav-section > .nav-list > .list-item {
display: inline-block;
pointer-events: auto;
background-color: aqua;
}
.nav-section > .nav-list > .list-item:hover {
background-color: rgb(154, 225, 225);
}
with react =>
const Navbar = () => {
const [isHover, setIsHover] = useState(false);
const handleHover = (_isHover) => setIsHover(_isHover);
return (
<nav className={`nav-section ${isHover ? "nav-hover" : ""}`}>
<div className="nav-list">
<a
className="list-item one"
onMouseOver={() => handleHover(true)}
onMouseLeave={() => handleHover(false)}
>
<div className="navlink-text">Red</div>
</a>
<a
className="list-item two"
onMouseOver={() => handleHover(true)}
onMouseLeave={() => handleHover(false)}
>
<div className="navlink-text">Blue</div>
</a>
<a
className="list-item three"
onMouseOver={() => handleHover(true)}
onMouseLeave={() => handleHover(false)}
>
<div className="navlink-text">Aqua</div>
</a>
<a
className="list-item four"
onMouseOver={() => handleHover(true)}
onMouseLeave={() => handleHover(false)}
>
<div className="navlink-text">Cyan</div>
</a>
</div>
</nav>
);
};
export default Navbar;
and its style =>
.nav-section {
background-color: black;
}
.nav-section.nav-hover {
background-color: red;
}
.nav-section > .nav-list {
display: inline-flex;
flex-direction: column;
}
.nav-section > .nav-list > .list-item {
display: inline-block;
background-color: aqua;
}
.nav-section > .nav-list > .list-item:hover {
background-color: rgb(154, 225, 225);
}
And also it can be done with useRef, but it seems a bit complicated to me
Take a look at useRef() in react. It's a great way to access style properties of an element. Therefore you could change the background of the navbar.
Of course you could also use the native css property :hover to change the backgound on hover.
Leaving this for anyone who comes across this post,
I solved it using Emotion.
/** #jsxImportSource #emotion/react */
import { useState } from "react";
import "./navbar.css";
import { css } from "#emotion/react";
const Navbar = () => {
const [background, setBackground] = useState("#410099");
const setStyle = (background) => {
setBackground(background);
};
return (
<nav css={css`
position: sticky;
left: 0;
top: 0;
right: 0;
bottom: auto;
z-index: 998;
background-color: ${background};
display: flex;
flex-direction: column;
padding: 0px 60px;
`}
>
<div className="nav-list">
<a
className="list-item one"
onMouseEnter={() => setStyle("#424246")}
onMouseLeave={() => setStyle("#410099")}
>
<div className="navlink-text">Color</div>
</a>
<a className="list-item two"
onMouseEnter={() => setStyle("#424246")}
onMouseLeave={() => setStyle("#410099")}>
<div className="navlink-text">Color</div>
</a>
<a className="list-item three"
onMouseEnter={() => setStyle("#424246")}
onMouseLeave={() => setStyle("#410099")}>
<div className="navlink-text">Color</div>
</a>
<a className="list-item four"
onMouseEnter={() => setStyle("#424246")}
onMouseLeave={() => setStyle("#410099")}>
<div className="navlink-text">Color</div>
</a>
</div>
</nav>
);
};
export default Navbar;
Customize this as needed. :)
I want to show items as flex but still it is showing like a column. What am I doing wrong here?
This is my component :
import React from "react";
import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import "./Listing.css";
const ProductComponent = () => {
const products = useSelector((state) => state.allProducts.products);
const renderList = products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div className="container">
<div key={id} className="item-box" >
<Link to={`/product/${id}`}>
<div className="image-box">
<img src={image} alt={title} />
</div>
<div className="detail">
<div >{title}</div>
<div >$ {price}</div>
<div >{category}</div>
</div>
</Link>
</div>
</div>
);
});
return <>{renderList}</>;
};
export default ProductComponent;
This is the css file of this component:
.container{
width: 100%;
height: 90vh;
flex-wrap: wrap;
display: flex;
}
.item-box{
border: 2px solid #000;
display: flex;
height: auto;
width: 380px;
padding: 10px;
justify-content: center;
margin: 20px;
}
img{
height: auto;
width: 300px;
}
And finally this is my App.css:
* {
font-family: "Roboto", sans-serif;
padding: 0;
margin: 0;
box-sizing: border-box;
}
Thanks in advance.
I wanna show the items as flex (from left to right) but it is like a column though I defined "display:flex"
You are looping through the array and outputing multiple containers. Each container is display-flex but the problem is that they all have only one child. Move the map inside the container:
return (
<div className="container">
{ products.map((product) => {
const { id, title, image, price, category } = product;
return (
<div key={id} className="item-box" >
<Link to={`/product/${id}`}>
<div className="image-box">
<img src={image} alt={title} />
</div>
<div className="detail">
<div >{title}</div>
<div >$ {price}</div>
<div >{category}</div>
</div>
</Link>
</div>
)
})}
</div>
)
In the style of .container just add flex-direction:coloum
.container{
width: 100%;
height: 90vh;
display: flex;
flex-direction: column;
}
If you want the column in center, then you can append justify-content:center & align-items:center as well.
I am trying to create a multiple images per slide slider that show three images per slid, when click the right arrow a 3 new images should be shown, and when the left one clicked the previous 3 images returns back to be shown.
I can not manage to make that work so this is my code:
Slider Component (parent)
class Slider extends Component {
state = {
left: 0
}
moveToRight = () =>{
this.setState(prevState => ({
left: prevState.left + 500
}))
console.log(this.state.left)
}
moveToLeft = () => {
this.setState(prevState => ({
left: prevState.left - 500
}))
}
render() {
return (
<div className="slider container">
<div className="slider__arrow slider__arrow--left" onClick={this.moveToLeft}>
<i class="fa fa-angle-left fa-2x" aria-hidden="true"></i>
</div>
<Slider_content categories={this.state.categories} style={{marginLeft: `${this.state.left}px`}}/>
<div className="slider__arrow slider__arrow--right" onClick={this.moveToRight}>
<i class="fa fa-angle-right fa-2x" aria-hidden="true"></i>
</div>
</div>
);
}
}
export default Slider;
Slider_content Component:
import React, {Component} from 'react';
class Slider_content extends Component {
render () {
const { categories, left } = this.props;
return (
<div className="slider__content ">
<div className="slider__wrapper container--vertical">
{categories.map((category, i) => (
<div className="slider__item container" key={i} style={{backgroundColor: category.categoryColor}}>
<div className="slider__item-details">
<span>{category.name}</span>
View Products
</div>
<div className="slider__item-img">
<img src={category.image} class="slider__img"/>
</div>
</div>
))}
</div>
</div>
);
}
}
export default Slider_content;
CSS:
.slider {
margin-top: 3em;
height: 100%;
position: relative;
}
.slider__content {
height: 100%;
width: 100%;
position: relative;
}
.slider__wrapper {
height: 100%;
flex-wrap: wrap;
overflow: hidden;
justify-content: space-between
}
.slider__item {
height: 100%;
margin : 9px;
position: relative;
overflow: hidden;
}
What i am doing wrong in this code, how can i manage to make the slider_content slider slides to left when click the right arrow and to right when click the left arrow??
I don't want the slider slides by 500px per click, it is just for experimenting
i need it to slide accurately to show the next 3 images in right position, i could not do that too!!
I want to add animation to the sidedrawer I made in reactjs. And I am not sure how to do that should i use react transition group or anything else which would be good ?
sidedrawer.js
import React from 'react'
import './sidedrawer.scss'
export default function SideDrawer() {
return (
<aside className="menu is-dark sidedrawer__wrapper">
<ul className="menu-list">
<li><a>Home</a></li>
<li><a>Contact</a></li>
<li><a>About</a></li>
</ul>
</aside>
)
}
sidedrawer.scss
.sidedrawer__wrapper{
background-color: #363636;
right: 0;
width: 80%;
height: 100%;
top: 0;
box-shadow: 1px 0px 7px rgba(0, 0, 0, 0.5);
position: fixed;
overflow-y: hidden;
z-index: 200;
.menu-list {
padding: 5rem 2rem 0rem 3rem;
li {
padding-top: 2rem;
a {
text-decoration: none;
color: white;
font-size: 30px;
}
}
}
}
navbar.js
import React,{Component} from 'react'
import './navbar.scss';
import Backdrop from './backdrop/backdrop';
import SideDrawer from './sidedrawer/sidedrawer';
class Navbar extends Component {
render() {
let backdrop;
let sidedrawer;
if(this.props.sideDrawerOpen) {
backdrop = <Backdrop click={this.props.backdropClickHandler}/>
sidedrawer= <SideDrawer/>
}
return (
<nav style={{width: '85%', margin:'0 auto'}} className="navbar is-dark" role="navigation" aria-label="main navigation">
<div className="navbar-brand">
<a className="navbar-item" href="/">ADI</a>
<a onClick={this.props.drawerToggleClickHandler} role="button" className="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div className="navbar-menu">
<div className="navbar-end">
HOME
CONTACT
ABOUT
</div>
</div>
{sidedrawer}
{backdrop}
</nav>
)
}
}
export default Navbar
In navbar.js there is hamburger icon which activate the side drawer. Here i want to add animation to the component when it will appear.
The simplest way is to just do that by setting the original margin to -sidedrawerwidth and adding a CSS class on state-change when you click the icon. And giving it {transition: margin transition-time}.