Bottom navigation bar animation - reactjs

I want to make it so that when you click on one of the icons, a certain strip appears under it, which will mean that the person is on this page (something like this)
At the moment, my navbar looks like this
Here's what I have at the moment (HTML):
let marker = document.querySelector('#marker');
let item = document.querySelectorAll('nav a .MuiSvgIcon-root');
function indicator(e) {
marker.style.left = e.offsetLeft + "px";
marker.style.width = e.offsetWidth + "px";
}
item.forEach(link => {
link.addEventListener('click', (e) => {
indicator(e.target)
})
})
body {
position: fixed;
bottom: 0;
left: 0;
background: #f2f2f2;
width: 100%;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 40px;
border-top: 1px solid lightgray;
z-index: 100;
}
.MuiSvgIcon-root {
font-size: 35px;
cursor: pointer;
transition: 0.3s cubic-bezier(0.1, 0.1, 0.5, 1.4);
:hover {
transform: translateY(-5px);
}
}
#marker {
position: absolute;
height: 4px;
width: 0;
background: #000;
bottom: 8px;
left: 0;
transition: 0.5s;
border-radius: 4px;
}
<div id="marker"></div>
<HomeIcon/>
<TimelineIcon/>
<AccountCircleIcon/>
<ExploreIcon/>
.MuiSvgIcon-root there is defining all icons.

Your js code is correct. You should check your HTML and CSS. Because their structure is important

Related

Is it possible to use the same React component with different CSS, using css modules?

I found the React CSS modules usefull, but having problem when I tried to reuse the same component with a little modified css I stuck. For example I created Neon glowing button, but now need to change only the width of the Button and some additional small changes in the css.
The only option I see is component without css and for every different case need to rewrite the whole css. Is there a smarter way?
import React from "react";
import styles from "./index.module.css";
import { Link } from "react-router-dom";
const GlowingButton = ({ title, path }) => {
return (
<div className={styles.buttonWrapper}>
<Link className={styles.button} to={path}>
<button className={styles["glow-on-hover"]}>{title}</button>
</Link>
</div>
);
};
export default GlowingButton;
And here is index.module.css
.buttonWrapper {
margin: 0px;
padding: 0px;
display: flex;
justify-content: center;
align-items: center;
background: transparent;
font-family: "consolas";
}
.button {
margin: 0;
padding: 0;
width: 80%;
height: 8vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #100f;
text-decoration: none;
}
.glow-on-hover {
width: 400px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: "";
background: linear-gradient(
45deg,
#ff0000,
#ff7300,
#fffb00,
#48ff00,
#00ffd5,
#002bff,
#7a00ff,
#ff00c8,
#ff0000
);
position: absolute;
top: -2px;
left: -2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity 0.3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000;
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}

how to change a styled component's before content on hover [emotion.js , styled components ]

on button hover I want to make changes to the :before content too , I couldn't find an answer in the official documentation I wonder f this is possible .
here is the css selector I want to convert to a styled component syntax is:
.button:hover::before{}
and here is the styled component :
import styled from '#emotion/styled'
export const Button =styled.button(props=>{
return`
padding: .75rem 2rem ;
color: #fff;
background-color: transparent;
border: 1px solid #000;
position: relative;
z-index: 1;
transition: all .5s cubic-bezier(0.785, 0.135, 0.15, 0.86);
cursor: pointer;
width: ${props.width ? props.width:'fit-content'};
margin-top: ${props.marginTop ? props.marginTop :0}rem;
&:before{
content: '';
position: absolute;
z-index: -1;
height: 100%;
width: 100%;
top: 0;
left: 0;
${props.collection?"background-color: #fff;":"background-color: var(--colorGrey);"}
transition: all .5s cubic-bezier(0.785, 0.135, 0.15, 0.86);
transform-origin: left center;
//I want to change style on hover
}
&:hover{
color:var(--colorGrey);
}
`})
Simply nest a :before pseudo-element inside the :hover pseudo class.
Also, consider using a template literal, instead of a function that takes props.
import styled from '#emotion/styled';
export const Button = styled.button`
padding: 0.75rem 2rem;
color: #fff;
background-color: transparent;
border: 1px solid #000;
position: relative;
z-index: 1;
transition: all 0.5s cubic-bezier(0.785, 0.135, 0.15, 0.86);
cursor: pointer;
width: ${(props) => (props.width ? props.width : 'fit-content')};
margin-top: ${(props) => (props.marginTop ? props.marginTop : 0)}rem;
&:before {
content: '';
position: absolute;
z-index: -1;
height: 100%;
width: 100%;
top: 0;
left: 0;
${(props) => (props.collection ? 'background-color: #fff;' : 'background-color: var(--colorGrey);')}
transition: all .5s cubic-bezier(0.785, 0.135, 0.15, 0.86);
transform-origin: left center;
}
&:hover {
color: var(--colorGrey);
&:before {
content: 'Hovered';
}
}
`;

Problem accessing styled component nth-child

Sorry for my bad English. I have some difficulty accessing the children of a menu in styled component. This is my component I want to access the AccountMenuItem children, I want to apply a higher height to the first and last children, but I can not access the way and the way.
CodeSandbox
I tried many options, but to no avail:
These are the last ones.
&:nth-child(2) ${AccountMenuItem} {
height: 80px;
}
&${AccountMenuItem}:nth-child(2) {
height: 80px;
}
<AccountMenu>
{menuItems.map((item, indice) => {
return (
<AccountMenuItem key={indice}>
<MenuImage src={item.icon} alt={item.text} />
<MenuItem>{item.text}</MenuItem>
</AccountMenuItem>
)
})}
</AccountMenu
const AccountMenuItem = styled.span`
height: 40px;
color: ${props => props.theme.primary[100]};
display: flex;
align-items: center;
text-decoration: none;
background-color: ${props => props.theme.TextPalette[100]};
&:hover {
background-color: rgba(131, 0, 196, 0.05);
font-weight: bold;
}
`
const AccountMenu = styled.div`
display: inline-block;
visibility: hidden;
position: absolute;
bottom: -240px;
width: 198px;
right: 0;
z-index: 99999;
text-decoration: none;
background-color: #f1f1f1;
border-bottom: 5px solid ${props => props.theme.primary[100]};
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
#media only screen and (min-width: 720px) {
left: -55px;
bottom: -240px;
}
&:hover {
visibility: visible;
}
&::after {
content: '';
position: absolute;
bottom: 100%;
left: 90%;
margin-left: -10px;
border-width: 10px;
border-style: solid;
border-color: transparent transparent #12ff92 transparent;
#media only screen and (min-width: 720px) {
margin-right: 0;
height: 120px;
left: 50%;
}
}
&:nth-child(2) ${AccountMenuItem} {
height: 80px;
}
`
There are two solutions to this. I have implemented both solutions in this link, one by setting background of the second child to black, and another by setting the background of the third child to blue.
Code: https://codesandbox.io/s/determined-tree-0l1hs
The important bit is that you were missing a space between & and the child's identifier in your first example. It should be like this:
// v-- Space here!!
& ${AccountMenuItem}:nth-child(3) {
background: blue;
}
The difference of the space is the same as this difference in traditional CSS:
.account-menu.account-menu-item // means an element that has both classes
.account-menu .account-menu-item // means the second element is a descendant of the first
The other way to do this, which I prefer, is just define the rule in the AccountMenuItem instead of defining it in the parent. That way you can skip the weird inheritance stuff and apply the style directly. So in AccountMenuItem you just need this:
&:nth-child(2) {
background: black;
}

flip an image when onClick event

In order to implement some features in my react app I need to flip an image in a grid horizonaly when the user choose it with onClick event.
I've readed regarding states in react , and noticed that this is what I need.
When onClick event, flip the image.
The follwing code isn't working well.
The isExpanded working fine, but the image in the grid isn't fliping.
What I'm doing wrong ?
I have initiated the isExpanded to false in my constractor.
handleToggle(e){
e.preventDefault();
this.setState({
isExpanded: !this.state.isExpanded,
})
render() {
const {isExpanded } = this.state;
return (
<div
className={`image-root ${isExpanded ? 'image-flip' : ''}`}
style={{
backgroundImage: `url(${this.urlFromDto(this.props.dto)})`,
width: this.state.size + 'px',
height: this.state.size + 'px'
}}
>
<div>
<FontAwesome className="image-icon" onClick={(e)=>
this.handleToggle(e)} name="arrows-alt-h" title="flip"/>
</div>
</div>
);
}
}
The .scss code:
.image-root {
background-size: cover;
background-position: center center;
display: inline-block;
vertical-align: top;
box-sizing: border-box;
position: relative;
border: 1px solid white;
> div {
visibility: hidden;
background: rgba(0, 0, 0, 0.7);
cursor: pointer;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
color: white;
padding: 15px;
text-align: center;
text-align: center;
box-sizing: border-box;
white-space: pre;
display: flex;
align-items: center;
justify-content: center;
}
&:hover > div {
visibility: visible;
}
.image-icon {
font-size: 20px;
vertical-align: middle;
border: 1px solid #ccc;
color: #ccc;
border-radius: 5px;
cursor: pointer;
padding: 12px;
margin: 3px;
&:hover {
color: white;
border-color: white;
}
}
.image-flip {
-moz-transform: scaleX(-1);
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
filter: FlipH;
-ms-filter: "FlipH";
}
The issue was accured due to the image-flip css was in the wrong scope.
I just move the image-flip css out of the image-root scope.
Thanks.

angularjs dynamically modify css class

My object is to modify css class value dynamically using angular js
My html
<body class="loader progress-bar">
</body>
Css class :
body {
margin: 0 auto;
font-family: 'Source Sans Pro', sans-serif;
color: #4a4a4a;
letter-spacing: 1px;
background: url('#{$imgPath}vsn-bg.png') #f5f5f5 no-repeat 50% 0;
#media only screen and (max-width: 1024px) { background-position-y: -20px; }
&.loader {
> div {
width: 40px;
height: 36px;
background: url('#{$imgPath}/v-360-contact-color#2x.png') center 100%;
position: absolute;
top: 50%;
left: 50%;
margin: -20px 0 0 -18px;
z-index: 9999999;
}
#{$project}_cc {
display: none;
}
}
&.progress-bar {
&::before {
content: '';
display: block;
width: 20%;
height: 4px;
background: rgba(245, 245, 245, 0.9);
transition: width ease .3s;
}
}
}
the target is to modify the value of progress-bar width for example from 20% to 30% dynamically

Resources