reactjs: I have no idea how to render these components with styled-components - reactjs

render the BarItem and BarItemSelect inside the link when the is true, they are all set precisely an using a css class, now it's two components...
I don't see a way to do this
const S = {
BarItem: styled.a`
position: relative;
display: block;
height: 3rem;
text-decoration: none;
cursor: pointer;
border: 0;
`,
BarItemSelected: styled.a`
font-weight: 500;
color: var(--dark-text-color);
filter: invert(1);
&:after {
content: '';
position: absolute;
display: block;
width: 100%;
height: 5px;
background-color: white;
border-radius: 5px 5px 0 0;
bottom: 0;
#media (max-width: 63.8rem) {
color: var(--dark-text-color);
filter: invert(1);
background-color: #000;
top: 0;
border-radius: 0 0 5px 5px;
}
}
`,
const SmartLink = ({ href, test, children, ...props }) => {
const router = useRouter();
const isActive = test ? new RegExp(test, 'g').test(router.pathname) : false;
return (
<Link
href={href}
{...props}
>
<a
className={
isActive
? `${styles.barItem} ${styles.barItemSelected}`
: styles.barItem
}
>
{children}
</a>
</Link>
);
};
I can't solve this... does anyone have any suggestions on how I can do it?

The code above is not clear but I'll try to write a pattern in which styled components are used.
styled component
import styled from "styled-components";
const BarItem = styled.a `
position: relative;
display: block;
height: 3rem;
text-decoration:
none;
cursor: pointer;
border: 0;
`;
const BarItemSelected = styled.a`
font-weight: 500;
color: var(--dark-text-color);
filter: invert(1);
&:after {
content: '';
position: absolute;
display: block;
width: 100%;
height: 5px;
background-color: white;
border-radius: 5px 5px 0 0;
bottom: 0;
#media (max-width: 63.8rem) {
color: var(--dark-text-color);
filter: invert(1);
background-color: #000;
top: 0;
border-radius: 0 0 5px 5px;
}
}
`;
Then in the component
import { NavLink} from "react-router-dom";
return (
<NavLink className={isActive
? BarItemSelected
: BarItem} to={href}>
>
{children}
</a>
</NavLink>
);
Please try the above code, if it does'nt work please comment, I'll make the neccessary changes.

Related

Does anyone know how to fix this ?( Dynamic nth-child & after ) react-sass

I'm trying to figure it out, but I haven't been able to...
It's a list with information and it's really almost ready, but the nth-child:after style I can't make it dynamic with react.
My React component:
const PieList = ({ data, colors = [] }: IPieListProps) => {
return data.length > 1 ? (
data.map(( item, index ) => (
<div
key={item.name}
className={styles['pie-list']}
style={{
backgroundColor: colors[index%colors.length]
}}
>
<ul>
{
item.name === 'others'
? <li>Otros<span>{item.value}</span> </li>
: <li>{item.name}<span>{item.value}</span></li>
}
</ul>
</div>
))
) : ''
}`
.pie-list {
ul {
max-width: 240px;
li {
&::after {
content: '';
width: 8px;
height: 8px;
border-radius: 8px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
&:nth-child(1){
&::after {
background-color: $orion;
}
}
&:nth-child(2){
&::after {
background-color: #433F5C;
}
}
&:nth-child(3){
&::after {
background-color: #898798;
}
}
}
}
}
I am trying to get this result:
But I have this:
you should try this:
ul {
list-style: none;
}
ul li::before {
content: "\2022";
color: red;
font-weight: bold;
display: inline-block;
width: 1em;
margin-left: -1em;
}
I solved it with a package called "styled-components", but if someone has a better solution that doesn't involve a library that would be great.
const Bullet = styled.div`
max-width: 240px;
li{
position: relative;
margin-bottom: 10px;
padding-left: 14px;
font-size: 14px;
color: $orion;
display: flex;
align-items: center;
justify-content: space-between;
&::after {
content: '';
width: 8px;
height: 8px;
background-color: ${ props => props.bulletColor };
border-radius: 8px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin: auto;
}
`
export const PieBanksList = ({ data, colors }: IPieBanksListProps) => {
return data.length > 1 ? (
data.map(( item, index ) => (
<div
key={item.name}
className={styles['pie-list']}
>
<Bullet
bulletColor={colors[index % colors.length]}
>
{
item.name === 'others'
? <li>Otros<span>{item.value}</span> </li>
: <li>{item.name}<span>{item.value}</span></li>
}
</Bullet>
</div>
))
) : <EmptyGraph />
}

Animation react Does not reset

I am working on animation in React app. I need animation starts working after hover off the button, the animation only works one time and after that for next time hover off the button does not make animation works.
I used
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
to reset time to works again but it does not work out.
#keyframes rotate-before {
0% { right:0px; top:0px;}
25% { right:40px; top:0px;}
50% {bottom:10px; top:178px;right:40px;}
}
.content {
position: absolute;
inset: 30px;
z-index: 3;
display: flex;
flex-direction:column;
align-items: center;
justify-content: center;
}
.content:hover .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
}
.hover{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
animation: rotate-before 0.5s linear;
animation-iteration-count: 1;
}
.content .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.hide{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.content img {
position: absolute;
width: 100%;
height:100%;
object-fit: cover;
}
import "./App.css";
import { AnimatePresence, motion, useTransform } from "framer-motion/dist/framer-motion";
import classes from "./components/anm.module.css";
function App() {
const [isHovered, setHovered] = useState(false);
const change = (e) => {
e.target.classList.add(classes.hover);
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
};
return (
<div className={classes.box}>
<div className={classes.content}>
<img
src="https://budgetreno.ca/wp-content/uploads/Pylon-25_compressed-thegem-portfolio-metro.jpg"
alt=""
/>
<motion.div className="square" onHoverEnd={change} whileHover={{}}>
<button id="test" className={classes.button}>
Follow
</button>
</motion.div>
</div>
</div>
);
}
export default App;

Pushing Sign Up & Login buttons to bottom of sidebar

I am trying to recreate this design:
Click to view
However, the below is currently occurring.
Click to view
I am trying to push the SignUp and Login buttons to the bottom of the sidebar to match the first image. Am I missing a CSS class that would allow me to do so, or would this be a JS configuration? Hope I have not overlooked something basic that would allow me to achieve this state.
Sidebar.js
import React from "react";
import "../App.css";
import { SidebarData } from './SidebarData'
import Logo from './Logo.svg'
import { Login } from './Login'
import { SignUp } from './SignUp'
function Sidebar() {
return (
<div className="Sidebar">
<div className="Header">
<div><img src = {Logo} alt='Logo’ className='Logo’ /></div>
</div>
<div class="line-break" />
<ul className="SidebarList">
{SidebarData.map((val, key) => {
return (
<li
key={key}
className="row"
id={window.location.pathname == val.link ? "active" : ""}
onClick={() => {
window.location.pathname = val.link;
}}
>
<div id="icon">{val.icon}</div> <div id="title">{val.title}</div>
</li>
);
})}
</ul>
<div class="line-break" />
<div className="footer">
<ul className= "SidebarList">
{Login.map((val, key) => {
return (
<li
key={key}
className="Login"
id={window.location.pathname == val.link ? "active" : ""}
onClick={() => {
window.location.pathname = val.link;
}}
>
<div id="title">{val.title}</div>
</li>
)}
)}
</ul>
<ul className= "SidebarList">
{SignUp.map((val, key) => {
return (
<li
key={key}
className="SignUp"
id={window.location.pathname == val.link ? "active" : ""}
onClick={() => {
window.location.pathname = val.link;
}}
>
<div id="title">{val.title}</div>
</li>
)}
)}
</ul>
</div>
</div>
Here is CSS
.App {
width: 100vw;
height: 100vh;
}
body {
margin: 0;
padding: 0;
}
.Sidebar {
height: 100%;
width: 300px;
background-color: white;
border-right: 1px solid #F0F4FB;
padding-left: 15px;
box-sizing: border-box;
}
.SidebarList {
height: auto;
width: 100%;
padding-left: 15px;
font-size: 18px;
border: 2px #FD954E;
box-sizing: border-box
}
.SidebarList .row {
width: 100%;
height: 50px;
background-color: white;
list-style-type: none;
margin: 0%;
padding-bottom: 15px;
display: flex;
color: #A7ACB6;
justify-content: center;
align-items: center;
font-family: Arial, Helvetica, sans-serif;
}
.SidebarList .row:hover {
cursor: pointer;
background-color: #E7E7E7 ;
}
.SidebarList #active {
background-color: white;
color: #FD954E
}
.SidebarList .Login {
background-color: white;
color: #FD954E;
width: 90%;
height: 5vh;
right: 1596px;
top: 958px;
border: 1px solid #FD954E;
box-sizing: border-box;
border-radius: 19.5px;
text-align: center;
font-family: Arial, Helvetica, sans-serif
}
.SidebarList .SignUp {
width: 90%;
height: 5vh;
right: 1596px;
top: 1011px;
background: #FD954E;
border-radius: 19.5px;
border: none;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
.row #icon {
flex: 30%;
display: grid;
place-items: center;
transform: scale(1.2)
}
.row #title {
flex: 70%;
}
.Logo {
padding-left: 25px;
padding-top: 25px;
padding-bottom: 30px;
width: 55%;
}
.line-break {
height: 1px;
width: 100%;
background-color: #F0F4FB;
}
ul.nav {
list-style-type: none;
padding: 20px 0 0 40px;
list-style-type: none;
}
ul.nav li {
margin-bottom: 14px;
list-style-type: none;
}
ul.nav li:last-child {
margin-bottom: 0;
list-style-type: none;
}
.footer {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 0;
}
.footer button {
padding: 6px 0;
width: 80%;
margin-bottom: 14px;
}
.footer button:last-child {
margin-bottom: 0;
}
.header .Logo {
height: 40px;
width: 200px;
background-color: grey;
margin: 20px;
}
Without seeing the source for the entire page and not just a couple of the buttons, it is impossible to say for sure, but my guess would be the following is causing your problem:
.Sidebar {
height: 100%;
...
}
Setting height: 100% will only tell the sidebar to take up 100% of the space it needs for its content (or 100% of the height of its bounding container, depending on the display properties of both). I would recommend changing it to this to solve your problem:
.Sidebar {
min-height: 100vh;
...
}

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 Use Classes in Styled-Component

I am new to styled-component. I want to convert custom CSS to Styled-Component. I have already used className in React File.
App.js
<div className="left-menus">
{menus.map(item => {
return (
<Link to={item.name} name={item.name} key={item.name}
className={this.state.activeMenu === item.name ? 'menu active' : 'menu' }
onClick={() => this.setState({ activeMenu: item.name })}
>
<Icon name={item.icon} size="large"/>
<span>{item.name}</span>
</Link>
)
})}
</div>
App.css
.left-menus {
position: fixed;
width: 200px;
padding-right: 0 !important;
background-color: #fff;
height: 100%;
margin-top: 20px;
top: 47px;
font-size: 12px !important;
border-right: 2px solid #e8e8ec; }
.left-menus .menu {
color: #4a4a4a;
width: 100%;
display: block;
cursor: pointer;
text-transform: capitalize !important;
padding: 15px 10px 15px 18px; }
.left-menus .menu .angle.down.icon,
.left-menus .menu .angle.up.icon {
right: 10px;
position: absolute; }
.left-menus .menu .icon:first-child {
margin-right: 10px; }
.left-menus .menu.active {
border-right: 4px solid #3cbfc8;
background-color: #f8f8f8; }
.left-menus .sub-menu-container .sub-menu {
display: none;
height: 0;
transition: 0.3s all ease; }
.left-menus .sub-menu-container.active .sub-menu {
display: block;
height: 100%;
text-transform: capitalize;
transition: 0.3s all ease; }
.left-menus .sub-menu-container.active .sub-menu a {
color: #4a4a4a; }
.left-menus .sub-menu-container.active .sub-menu .icon {
margin: 10px 10px 0 10px; }
CSS with a class selector will only match elements that are members of a class.
To give a styled component that class, you need to do it when you instantiate it.
For example:
const MyStyledComponent = styled.div`
background: red;
`;
const myFunctionComponent = () => {
const myClass = "left-menus";
return(
<div>
Here is MyStyledComponent
<MyStyledComponent className={myClass}>
Example
</MyStyledComponent>
</div>
);
}
If you have an existing stylesheet you want to apply, it is likely that styled components are not the right tool for the job.

Resources