I'm creating a react app (w/o react-router) with UIKit for a portfolio, and as of yesterday when I finished my projects section, the page is now automatically scrolling down to that id, even when hosted on Netlify. The navbar has anchors to each id, but this definitely isn't causing the problem (since the whole page worked as intended before I implemented the projects section yesterday).
/#projects is not being appended to the web address, and I am not using any window functions.
I tried using the useEffect() hook with window.scrollTo(0,0) inside, but the page still starts at the projects section and then scrolls to the top with looks odd.
This is the hosted version if you want to see exactly what I'm talking about.
Here's the projects component:
const Projects = () => {
const [selected, setSelected] = useState(proj[0]);
return (
<Fragment>
<div className="projects" id="projects">
<div className="about-head-wrapper">
<h2 className="about-head heading">Projects</h2>
</div>
<MediaQuery minDeviceWidth={1001}>
<div className="projects-container">
<div className="projects-container-buttons">
<button
href="#!"
onClick={() => {
setSelected(proj[0]);
}}
className="project-button"
key={proj[0].title}
autoFocus>
<img src={proj[0].logo} alt="" />
</button>
<button
href="#!"
onClick={() => {
setSelected(proj[1]);
}}
className="project-button"
key={proj[1].title}>
<img src={proj[1].logo} alt="" />
</button>
<button
href="#!"
onClick={() => {
setSelected(proj[2]);
}}
className="project-button"
key={proj[2].title}>
<img src={proj[2].logo} alt="" />
</button>
</div>
<div className="projects-container-splitter" />
<div className="projects-container-info">
<ProjectInfo
title={selected.title}
sc={selected.sc}
desc={selected.desc}
link={selected.link}
/>
</div>
</div>
</MediaQuery>
<MediaQuery maxDeviceWidth={1000}>
<div className="project-accordion-container">
<ul uk-accordion="collapsible: true; animation: false; multiple: true;">
{proj.map((p) => {
return (
<ProjectAccordion
title={p.title}
sc={p.sc}
desc={p.desc}
link={p.link}
logo={p.logo}
key={p.title}
/>
);
})}
</ul>
</div>
</MediaQuery>
</div>
</Fragment>
);
};
And here's my scss code for the component container:
.projects {
height: 100rem;
background-color: #3a4750;
padding-top: 8rem;
#media (max-width: 1000px) {
height: 100%;
padding-bottom: 5rem;
}
&-container {
display: flex;
justify-content: space-between;
align-items: center;
margin: 5rem 0;
height: 70rem;
&-buttons {
flex: 0 0 32%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
&-splitter {
flex: 0 0 1px;
height: 60rem;
background-color: white;
transform: rotate(0) scaleY(1);
}
&-info {
flex: 0 0 65%;
}
}
}
Update, I just found an autofocus that accidentally slipped past me. It was in .projects-container-buttons in the first button element that I was using in an old version of the projects component.
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'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
I'm new to react so when I tried aligning my image the CSS way it failed. The only way I can get the image to align to the right side of the screen is by positioning it. Any alternatives?
I tried doing jjustifyContent ,justifySelf and even floating to right. Nothing works.
Image to my app
My code:
import React from "react";
import { makeStyles } from "#material-ui/styles";
const useStyles = makeStyles({
main: {
display: "flex",
justifyContent: "flex-end"
},
header: {
color: "white"
},img: {
justifySelf: "flex-end"
}});
export default function Header() {
const classes = useStyles();
return (
<div className={classes.main}>
<span className={classes.header}>Header</span>
<img
className={classes.img}
src="https://facebook.github.io/react-native/img/header_logo.png"
/>
</div>
);
}
You can use this, justify-content: space-between
Your style should be,
const useStyles = makeStyles({
main: {
display: "flex",
justifyContent: "space-between"
},
header: {
color: "white"
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.grid-container {
display: flex;
}
<section>
<div class="grid-container">
<div style="width: 50%;">
<img width="20%" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHGbRmrMlg4j7xLGAEp1GLJ-oeq3-1C7rkXPm8uhu5cq1vx1n8" alt="">
</div>
<div style="width: 50%;">
<img width="20%" style="float: right;" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRHGbRmrMlg4j7xLGAEp1GLJ-oeq3-1C7rkXPm8uhu5cq1vx1n8" alt="">
</div>
</div>
</section>
Try this if that works for you!
you just have to make image `margin-left:auto;` please check attached example.
.main{
background: black;
display: flex;
align-items: center;
}
span{
color: #fff;
}
img{
margin-left: auto;
}
<div class="main">
<span class="header">Header</span>
<img
class="main-image"
src="https://facebook.github.io/react-native/img/header_logo.png"
/>
</div>