How to change style of selected React-router link? - reactjs

I have NavBar.jsx:
import React from "react";
import { Link } from "react-router-dom";
import "./navBar.sass";
function NavBar() {
return (
<div className="NavBar_container">
<nav className="NavBar">
<Link
to="/CreateReview"
className={(isActive) =>
"selected" + (!isActive ? " unselected" : "")
}
>
<div className="NavBar_img">
<img src="./create_review_icon.png" alt="create_review" />
</div>
<p className="NavBar_title">Create Review</p>
</Link>
<Link to="/Hotels" className="NavBar_item">
<div className="NavBar_img">
<img src="./main_page_icon.png" alt="main_page" />
</div>
<p className="NavBar_title">Reviews</p>
</Link>
<Link to="/MyAccount" className="NavBar_item">
<div className="NavBar_img">
<img src="./my_account_icon.png" alt="my_account" />
</div>
<p className="NavBar_title">My account</p>
</Link>
</nav>
;
</div>
);
}
export default NavBar;
And some styles:
.NavBar
position: fixed
z-index: 9999
display: flex
justify-content: space-between
width: 400px
height: 75px
padding: 15px 25px 0 25px
background-color: rgba(0, 0, 0, 0.81)
border-bottom-left-radius: 30px
border-bottom-right-radius: 30px
&_container
width: 450px
margin: 0 auto
&_item
text-decoration: none
&:hover , &:active
.NavBar_title
transition: 0.2s all
color: #DAAD86
border-bottom: 1px solid #DAAD86
.NavBar_img
transition: 0.2s all
transform: scale(1.1)
&_img
width: 35px
margin: 0 auto
&_title
text-align: center
color: white
padding-bottom: 5px
.selected
background-color: blue
.unselected
background-color: red
I'm trying to set up my NavBar so that the selected link changes style, nothing works right now, what's wrong? I would like the text under the image to change its color and become underlined (as it is done in the :hover classes). I did this according to the React-Router documentation, maybe I missed something?

In your app.jsx file, or wherever you have your navbar component rendering, use the useLocation hook provided by 'react-router-dom' to get the current page. You can then pass it to your navbar as props and give the links the 'selected' class if the current page === the page the link points to.

Related

How can I use emotion/styled in my react project on codepen?

I need to be able to use #emotion/styled CSS-in-JS library so I can pass props to the background-color and color properties of my Button component. The background-color and color of the buttons are supposed to change with the rest of the app.
The commented out section that starts the JS section:
import EmotionStyled from "https://cdn.skypack.dev/#emotion/styled#11.10.5";
import styled from "https://cdn.skypack.dev/#emotion/styled#11.10.5"
function Button(props) {
const Button = styled.button`
margin-top: 2rem;
background-color: ${props.colorChange};
color: white;
border: none;
height: 2.5rem;
border-radius: 4px;
padding: 0 1rem;
font-size: 1rem;
&:nth-of-type(1) {
margin-right: 0.5rem;
}
&:hover {
background-color: ${props.colorChange};
opacity: 0.9;
}
`
return (
<div className='buttons'>
<div className='left'>
<Button><a href='https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=%22Everything%20has%20beauty%2C%20but%20not%20everyone%20can%20see.%22%20Confucius' id='tweet-quote'
target='_blank'
rel='noreferrer'><i className="fa-brands fa-twitter"></i></a></Button>
<Button><a href='https://www.tumblr.com/login?redirect_to=https%3A%2F%2Fwww.tumblr.com%2Fwidgets%2Fshare%2Ftool%3Fposttype%3Dquote%26tags%3Dquotes%252Cfreecodecamp%26caption%3DConfucius%26content%3DEverything%2Bhas%2Bbeauty%252C%2Bbut%2Bnot%2Beveryone%2Bcan%2Bsee.%26canonicalUrl%3Dhttps%253A%252F%252Fwww.tumblr.com%252Fbuttons%26shareSource%3Dtumblr_share_button' id='tumblr-quote'
target='_blank'
rel='noreferrer'><i className="fa-brands fa-tumblr"></i></a></Button>
</div>
<Button id='new-quote'
onClick={props.handleChange}
>New quote</Button>
</div>
)
}
is supposed to replace the Button component I have in place at the moment. Whenever I use this emotion-styled Button component, everything goes blank. Please help!
Here is a link to the codepen project: https://codepen.io/lawlessIndi/pen/gOKjNMG.

Radio Input As Cards - React + Antd

I wanted to create Radio Input Buttons styled Cards.
I am using react js and ant design.
Tried to create my own native component using good old input type="radio".
Connecting them to antd forms wasen't smooth sailing, then I had another idea.
Using antd react Radio component and just passing a card component. That's the working result!
Usage.tsx
// Other Code
<Radio.Group onChange={onChange} value={value} className="cards-container">
<Radio value={FOCUS_LEVEL.Regular} className="radio-input-card-container">
<InputCard
title="First Card"
checked={value === CONSTANT1}
imgPath="../../assets/icon1.svg"
points={["This is a point explain why this card is the best!", "Wow this is also a great point"]} />
</Radio>
<Radio value={FOCUS_LEVEL.DeepFocus} className="radio-input-card-container">
<InputCard
title="Second Card"
checked={value === CONSTANT2}
imgPath="../../assets/icon2.svg"
points={["This point explains why this card is way better", "The other card as shitty points!"]} />
</Radio>
</Radio.Group>
// Other Code
Usage.scss
.cards-container {
display: flex;
justify-content: space-between;
margin-left: 20px;
}
InputCard.tsx
import React from "react"
import Title from "antd/lib/typography/Title";
import "./InputCard.scss"
export function InputCard({ title, checked, imgPath, points }): JSX.Element {
return (
<div className={checked ? "card checked" : "card"}>
<div className="header-container">
<Title className="card-title">{title}</Title>
<img src={imgPath} alt="regular focus"></img>
</div>
<ul>
{points.map((point) =>
<li key={point.toString()}>{point}</li>
)}
</ul>
</div >
);
}
InputCard.scss
.card {
height: 420px !important;
width: 360px !important;
position: relative !important;
left: -45px; // A work around. Placing the card under the native radio button
-webkit-appearance: none;
appearance: none;
border: 2px solid rgba(2,28,53,0.08);
border-radius: 14px;
box-shadow: 7px 7px 15px rgba(2,28,53,0.08);
cursor: pointer;
outline: none;
.header-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
ul {
padding: 0em 1em 0em 2.5em !important;
}
img {
margin: 0.5em 0em 1em 0em;
}
}
.card-title {
font-size: 20px !important;
margin-top: 16px !important;
}
.checked {
transition: border 0.5s ease;
border: 2px solid rgba(255,0,0,0.6);
}
The antd component creates a radio input circle right before the card childe. Moving the card to the left (left: -45px) so the card will include the radio circle is a workaround. I don't want to change too much in the parent component for me to use this InputCard component, and this is my try to do it within the component.

I've seen all of the other answers, REALLY struggling with Sticky Footer in React. WON'T STICK TO THE BOTTOM

I am trying to get my footer to stick to the bottom and not cover any body elements toward the bottom of the screen and I cannot seem to figure it out. Here is my footer.js
import React from "react";
import './Stylesheets/Footer.css';
import NavbarBrand from 'react-bootstrap/NavbarBrand';
import Navbar from 'react-bootstrap/Navbar';
import Container from 'react-bootstrap/Container';
class Footer extends React.Component {
state = { clicked: false }
handleClick = () => {
this.setState({ clicked: !this.state.clicked })
}
render() {
return (
<footer className="footerItems">
<div className="phantom"></div>
<div>
<Navbar>
<Container>
<NavbarBrand className="wrapper">
<i class="fab fa-2x fa-github"></i>
<i class="fab fa-2x fa-facebook-square"></i>
<i class="fab fa-2x fa-twitter-square"></i>
<i class="fab fa-2x fa-instagram"></i>
</NavbarBrand>
</Container>
</Navbar>
</div>
</footer>
)
}
}
export default Footer
I am trying to use a phantom <div> to force some additional spacing but that is not working. Here is the corresponding css file.
footer {
height: 80px;
margin-top: -200px;
bottom: 0;
z-index: 999;
}
.phantom {
display: 'block';
padding: '20px';
height: '60px';
width: '100%';
}
.footerItems {
position: fixed;
width: 100%;
background: linear-gradient(90deg, rgb(110, 94, 254) 0%, rgba(73, 63, 252, 1) 100%);
display: flex;
justify-content: center;
}
.wrapper {
align-items: center;
height: 100vh;
}
.wrapper i {
padding: 10px;
text-shadow: 0px 6px 8px rgba(0, 0, 0, 0.6);
transition: all ease-in-out 150ms;
}
.wrapper a:nth-child(1) {
color: #080202;
}
.wrapper a:nth-child(2) {
color: white;
}
.wrapper a:nth-child(3) {
color: #1DA1F2;
}
.wrapper a:nth-child(4){
color: #f24f1d;
}
.wrapper i:hover {
margin-top: -3px;
text-shadow: 0px 14px 10px rgba(0, 0, 0, 0.4);
}
Any thoughts or suggestions??
THANK YOU
Here's a solution using position: sticky. The main things to note here is that the main div needs to be at least the height of the page, that way the top property can force it to the bottom. The bottom property then forces it to stay at the bottom even if scrolled past.
This doesn't remove the footer from affecting the height of the page, so it'll all be scrollable without issue.
The other thing to note is that this solution (as written) is based on knowing the height of the footer in advance, so I put a custom css property --footer-height: 60px to set that.
I'm not really sure why the icons and things don't show on the footer as given, but that's a different question
const { NavbarBrand, Navbar, Container } = ReactBootstrap;
class Footer extends React.Component {
state = {
clicked: false,
};
handleClick = () => {
this.setState({
clicked: !this.state.clicked,
});
};
render() {
return (
<footer className="footerItems">
<div className="phantom"> </div>
<div>
<Navbar>
<Container>
<NavbarBrand className="wrapper">
<a href="http://www.github.com" target="_blank">
<i class="fab fa-2x fa-github"> </i>
</a>
<a href="http://www.facebook.com" target="_blank">
<i class="fab fa-2x fa-facebook-square"> </i>
</a>
<a href="http://www.twitter.com" target="_blank">
<i class="fab fa-2x fa-twitter-square"> </i>
</a>
<a href="http://www.instagram.com" target="_blank">
<i class="fab fa-2x fa-instagram"> </i>
</a>
</NavbarBrand>
</Container>
</Navbar>
</div>
</footer>
);
}
}
ReactDOM.render(
<div className="main">
<div className="content">Content!</div> <Footer />
</div>,
document.getElementById('root')
);
.main {
min-height: 100vh;
--footer-height: 60px;
}
.content {
height: 100vh;
background: linear-gradient(0deg, green 0%, white 100%);
}
footer {
height: var(--footer-height);
position: sticky;
top: calc(100vh - var(--footer-height));
bottom: 0;
}
.phantom {
display: block;
padding: 20px;
height: var(--footer-height);
width: 100%;
}
.footerItems {
/*position: fixed;*/
width: 100%;
background: linear-gradient(90deg, rgb(110, 94, 254) 0%, rgba(73, 63, 252, 1) 100%);
display: flex;
justify-content: center;
}
.wrapper {
align-items: center;
/*height: 100vh*/
;
}
.wrapper i {
padding: 10px;
text-shadow: 0px 6px 8px rgba(0, 0, 0, 0.6);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous" />
<script src="https://unpkg.com/react-bootstrap#next/dist/react-bootstrap.min.js" crossorigin></script>
<div id="root" />

Why CSS(sass) calc() method doesn't work in React?

At first look at my codes:
JSX:
import React from "react";
import "./styles.scss";
export default function App() {
return (
<div className="App">
<h1> This is a Portfolio Item </h1>
<div className="item-container">
<div className="img-container">
<img
src="https://tf-react-chester.now.sh/images/portfolio-image-5.jpg"
alt="Portfolio 1"
/>
</div>
<h3>This is the Title of Item </h3>
<h4>
This is the description of Item. This is the description of Item.{" "}
</h4>
</div>
</div>
);
}
And CSS(SASS):
.App {
.item-container {
width: 100%;
height:auto;
.img-container {
position: relative;
$margin: 20px;
&::before{
position: absolute;
content: '';
**width: calc(100%-20px);
height: calc(100%-20px);** /* These two line don't work. */
left: 10px;
top: 10px;
background-color: #fff;
transition: all 0.5s ease-in-out;
transform: scaleX(0);
transform-origin: 0;
}
&:hover {
transform: scaleX(1);
}
img{
max-width: 100%;
}
}
}
}
I am trying to create a ::before animated content over the image. But when I am using calc() method it doesn't work at all.
What's the reason?
Note: I have tried some solution to the same problem from StackOverflow but those don't work for me.
This is the codesandbox link:CodeSandBox
Try with spaces ;)
width: calc(100% - 20px);
height: calc(100% - 20px);

How to customize width and height of Floating Action Button material ui component in React. Also the button does not show the edit icon correctly

I want to add a Floating Action Button (FAB) on my app. Where I want to adjust its width and height to reduce its size using css. Also the button does not show the edit icon inside the button as expected.
Below are the code that I tried,
Code Sandbox
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './profile/profile.css';
import ProfileInfo from './profile/profile';
ReactDOM.render(
<ProfileInfo />,
document.getElementById('root')
);
profile.js
import React from 'react';
import './profile.css';
import Fab from '#material-ui/core/Fab';
import Icon from '#material-ui/core/Icon';
class ProfileInfo extends React.Component{
render(){
return(
<div className='prof-main-container'>
<div className='prof-items-container'>
<div className='prof-pic-container'><img src="https://ik.imagekit.io/upgrad1/upgradlogo.png" className="prof-pic" alt="profile pic" /></div>
<div className='prof-info-data-container'>
<div className='user-name'>User Name</div>
<div className='posts-follows-container'>
{/* <span className='posts-follows-item-first'>Posts:6</span>
<span className='posts-follows-item'>Follows:4</span>
<span className='posts-follows-item'>Followed By:6</span> */}
<span>Posts:6</span>
<span className='posts-follows-item'>Follows:4</span>
<span>Followed By:6</span>
</div>
<div className='full-name-container'>
<div className='full-name'>UpGrad Education</div>
<div className='full-name-edit-btn'>
{/* <Button variant="fab" color="secondary" size='medium'>
Edit
</Button> */}
<Fab color="secondary" aria-label="Edit" className='edit-btn'>
<Icon>edit_icon</Icon>
</Fab>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default ProfileInfo
profile.css
.prof-main-container {
display: flex;
background-color: #5995DA; /* Blue */
padding: 20px 0;
}
.prof-items-container {
border: 1px solid #fff;
width: 100%;
display: flex;
/* justify-content: space-around; */
padding: 0% 20%;
/* padding-left: 500px; */
}
.prof-info-data-container{
display: flex;
/* justify-content: space-between; */
flex-direction: column;
margin: 0px 40px;
}
.prof-pic-container{
padding: 15px 0px 0px 0px;
}
.prof-pic{
width: 50px;
height: 50px;
}
.posts-follows-item{
margin: 0px 60px;
}
.posts-follows-container{
font-size: 11px;
margin: 2px 0px;
}
.full-name-container{
display: flex;
flex-direction: row;
}
.full-name{
font-size: 12px;
margin: 10px 0px;
}
.user-name{
font-size: 12px;
font-weight: bold;
margin: 5px 0px;
}
.full-name-edit-btn{
margin: 5px 20px;
}
.edit-btn{
width: 20px;
height: 20px;
}
The expected edit icon is as below.
But actually it is rendering as below. Note that, no edit icon is displaying inside the button as expected instead it is showing "EC" inside the button.Please ignore the background color here.
Also, I should be able to adjust the width and height of the below edit button to reduce its size.But I am not able to do it using css. I tried adding a class named "edit-btn" inside profile.css but it does not work.
Did you try using classes prop instead of className on your Fab element.
According to the documentation you should use the former.
Refer this link for the same :
Material UI FAB props
I have updated my answer. Your .edit-btn class will work fine if you give it more specificity. Refer my code sandbox for the same.
Regarding your <Icon> can you help me understand what is edit_icon?
code sandbox
Do give it a try and see if it works. Also please share what you have tried so far.Thanks!

Resources