How can I use dynamic css variables in react? - javascript

Trying to do a drop-shadow hover effect in react. I thought I'd use inline style attribute so each icon can have a different color when it's hovered over. I'm stuck on how to achieve this. In my IconGrid component I've created an array of objects, each has an image and the image color respectively. Then I map through it and return the individual GridItem component, but I'm stuck as to how I can use the unique color property for the css drop-shadow effect. I'm getting the red lines in my GridItem component because it's clearly not the written correctly. How can I achieve this?
IconGrid Component
import React from "react";
import "./index.scss";
import GridItem from "./GridItem";
import XD from "../../../assets/images/adobe-xd.png";
import PS from "../../../assets/images/adobe-photoshop.png";
import AI from "../../../assets/images/adobe-illustrator.png";
import CSS from "../../../assets/images/css.png";
import GSAP from "../../../assets/images/gsap.png";
import GULP from "../../../assets/images/gulp.png";
import HTML from "../../../assets/images/html.png";
import JS from "../../../assets/images/javascript.png";
import NODE from "../../../assets/images/nodejs.png";
import REACT from "../../../assets/images/react.png";
import WP from "../../../assets/images/wordpress.png";
import PHP from "../../../assets/images/php.png";
const IconGrid = () => {
const icons = [
{ img: XD, color: "#2E001E" },
{ img: PS, color: "#31C5F0" },
{ img: AI, color: "#FF7F18" },
{ img: HTML, color: "#E44D26" },
{ img: CSS, color: "#264DE4" },
{ img: WP, color: "#01579B" },
{ img: PHP, color: "#6181B6" },
{ img: JS, color: "#F7DF1E" },
{ img: GSAP, color: "#8AC640" },
{ img: GULP, color: "#D34A47" },
{ img: NODE, color: "#83CD29" },
{ img: REACT, color: "#61DBFB" },
];
return (
<>
<div className="flex-grid">
{icons.map((icon, idX) => (
<GridItem key={idX} icon={icon} />
))}
</div>
</>
);
};
GridItem Component
import React from "react";
import "./index.scss"
const GridItem = ({ icon }) => {
return (
<div style={{`--color: ${icon.color}`}} className="flex-item">
<img src={icon.img} alt="" />
</div>
);
};
export default GridItem;
And the CSS
.flex-item {
flex-basis: 22.5%;
padding: 2.5rem 0;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.4s ease-in-out;
position: relative;
&:hover {
transition: all 0.4s ease-in-out;
filter: drop-shadow(0 0 20px var(--color)) drop-shadow(0 0 40px var(--color))
drop-shadow(0 0 60px var(--color));
}
img {
max-width: 80px;
height: auto;
}
}

I think you should set your inline style as below, keeping the key: value form.
import React from "react";
import "./index.scss"
const GridItem = ({ icon }) => {
return (
<div style={{'--color': `${icon.color}`}} className="flex-item">
<img src={icon.img} alt="" />
</div>
);
};
export default GridItem;

Related

<Figure> not displaying in <div> container

I am new at react and am trying to build an app from a tutorial. I used the figure tag in the component but cannot see it in inspect element of chrome. Here are the codes.
The container in tutorial has tag as child. I am not getting that
Image from the tutorial containing div tag with figure tag as child element
My code with only div tag
index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Main from './Components/Main'
import './styles/stylesheet.css'
ReactDOM.render(<Main/>, document.getElementById('root'));
ReactDOM.render(, document.getElementById('root'));
Main.js
import React, { Component } from 'react'
import Title from './Title'
import Photowall from './Photowall'
const posts = [{
id: "0",
description: "beautiful landscape",
imageLink: "https://image.jimcdn.com/app/cms/image/transf/none/path/sa6549607c78f5c11/image/i4eeacaa2dbf12d6d/version/1490299332/most-beautiful-landscapes-in-europe-lofoten-european-best-destinations-copyright-iakov-kalinin.jpg" +
"3919321_1443393332_n.jpg"
},
{
id: "1",
description: "Aliens???", imageLink: "https://s3.india.com/wp-content/uploads/2017/12/rocket.jpg"
},
{
id: "2",
description: "On a vacation!",imageLink: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2017/08/24/104670887-VacationExplainsTHUMBWEB.1910x1000.jpg"
}
class Main extends Component{
render(){
return <div>
<Title title={'Photowall'}/>
<Photowall posts={posts}/>
</div>
}
}
export default Main
Photowall.js
import React,{ Component} from 'react'
import Photo from './Photo'
class Photowall extends Component{
render() {
return
<div className='photo-grid'>
{this.props.posts.map((post,index)=> <Photo key={index} post={post}/>)}
</div>
}
}
export default Photowall
Photo.js
import React, {Component} from "react";
class Photo extends Component{
render(){
const post =this.props.post
return <figure className="figure"></figure>
}
}
export default Photo
Stylesheet.js
html{
font-size: 10px;
}
h1{
font-family: billabong;
text-align: center;
font-size: 13rem;
margin: 2rem 0rem;
font-weight: 400;
letter-spacing: 4px;
color: grey;
}
#font-face {
font-family: billabong;
src: url('https://fonts.cdnfonts.com/s/13949/Billabong.woff') format('woff');
}
.photo-grid {
max-width: 1000px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.figure {
flex-basis: calc (33.333%-4rem);
border: 1px solid #d3d3d3;
padding: 2rem;
flex-grow: 1;
margin: 0 2rem;
}
Your Photowall HTML is dead code
Seems like your enitre Photowall component is not rendering itself.
The problem is that your HTML is not on the same line as return (becoming dead code).
If you put your HTML below your return is like you are returning undefined so the component doesn't render nothing.
You should always put your first HTML line right after return , not some line below.
class Photowall extends Component{
render() {
return <div className='photo-grid'>
{this.props.posts.map((post,index)=> <Photo key={index} post={post}/>)}
</div>
}
}
or wrapping your html between brakets (more readable in my opinion)
class Photowall extends Component{
render() {
return ( // starting from the same line as return
<div className='photo-grid'>
{this.props.posts.map((post,index)=> <Photo key={index} post={post}/>)}
</div>
)
}
}

How do I fix with Next JS and Antd Design Styling not working?

Whenever I try to style Antd Design component ( Layout, Sider and so on ) but it doesn't seems to be working. Therefore there won't be any changes on them. But it works fine on other HTML elements like div, h1, p tags.
Here's my code:
.sidbar{
flex: 1;
background-color: red;
border-right: 0.5px solid rgb(218, 217, 217);
min-height: 100vh;
background-color: white;
}
import styles from "../styles/Sidebar.module.scss";
import React from "react";
import { Layout, Menu } from "antd";
const { Header, Content, Footer, Sider } = Layout;
import {
HomeOutlined,
DashboardOutlined,
TeamOutlined,
} from "#ant-design/icons";
import Link from "next/link";
const Sidebar = () => {
return (
<div>
<Layout className={styles.sidebar}>
<Header>header</Header>
<Layout>
<Sider>left sidebar</Sider>
<Content>main content</Content>
<Sider>right sidebar</Sider>
</Layout>
<Footer>footer</Footer>
</Layout>
</div>
);
};
export default Sidebar;

React color background on event

I use the npm package use-dark-mode as the name implies, it makes it possible to change the theme to light or dark, The problem is that I want to change the background-color of some blocks when changing the theme to dark, and vice versa, return the old color when I switch to light mode, for example, my block background is orange, I switch to dark mode, it turns red and when I switch to light mode, it returns old orange
App.js
import React from 'react';
import './App.css'
import Content from "./components/Content/Content";
import Dark_Mode from "./components/Dark Mode/Dark_Mode";
const App = () => {
return(
<div>
<Dark_Mode />
<Content />
</div>
);
};
export default App;
Content.jsx
import React from 'react';
import './style.css'
const Content = () => {
return (
<>
<div className={"content_container"}>
<h3>Hello from React.JS</h3>
</div>
</>
);
};
export default Content;
Dark_Mode.jsx
import React from 'react';
import useDarkMode from 'use-dark-mode';
const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<div>
<button type="button" onClick={darkMode.disable}>
☀
</button>
<button type="button" onClick={darkMode.enable}>
☾
</button>
</div>
);
};
export default DarkModeToggle;
style.css
#import '../../App.css';
.content_container {
margin: auto;
width: 500px;
max-width: 100%;
background: orange;
}
.content_container h3 {
text-align: center;
}
App.css
body.light-mode {
background-color: #fff;
color: #333;
transition: background-color 0.3s ease;
}
body.dark-mode {
background-color: #1a1919;
color: #999;
}
:root {
--color-orange: orange;
}
As you can see, I have App.css when the theme changes, it changes the background of the <body>, I still have Content.jsx when switching theme I want to change the background of the block with the className content_container which is connected to style.css, In addition, you may have noticed that I tried to use global styles, but I failed. Finally, I would like to show a screenshot on the site for a clear understanding of everything.
You could give the root element a class on theme change and use css variables in root, but be class specific:
Dark_mode.jsx:
function setTheme(themeName) {
document.documentElement.classList.remove('light-theme', 'dark-theme');
document.documentElement.classList.add(themeName);
}
const DarkModeToggle = () => {
const activateDarkTheme = () => setTheme('dark-theme');
const activateLightTheme = () => setTheme('light-theme');
return (
<div>
<button type="button" onClick={activateDarkTheme}>
☀
</button>
<button type="button" onClick={activateLightTheme}>
☾
</button>
</div>
);
};
Styles:
:root, // this is used for the default theme, will be overwritten by other styles with classes because of specifity
:root.dark-theme {
--color-bg: #000;
}
:root.light-theme {
--color-bg: #fff;
}
I found a more convenient solution! although it is my fault, I was a little inattentive and did not study the documentation of this package that I use in my project, here is a simple solution
Content.jsx
import './Content.css'
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
}
Content.css
.Dark_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: orange;
}
.Light_Mode {
margin: auto;
max-width: 100%;
width: 400px;
height: 275px;
background-color: rgb(24, 106, 199);
}

React styled-components not applying styles to custom styled components

I'm using react-styled-components to style some custom components in my React/AntDesign application but the styles are not applied to my application.
When I tried reproducing the component in a clean codesandbox.io project the styles were applied successfully.
While some styled-components in my project do work this doesn't, what could be interfering with styled-components?
Here's the code:
import React from "react";
import "antd/dist/antd.css";
import styled from "styled-components";
import { FaMale, FaFemale, FaChild, FaUserFriends } from "react-icons/fa";
import { MdChildFriendly } from "react-icons/md";
import { Row, Col, Modal, Button } from 'antd';
class App extends React.Component {
state = { visible: false };
showModal = () => {
this.setState({
visible: true,
});
};
handleCancel = e => {
console.log(e);
this.setState({
visible: false,
});
};
ProductBtn = styled.div`
box-shadow: 0 0 15px rgba(0,0,0,0.1);
border: 1px solid #eee;
padding: 16px;
text-align: center;
border-radius: 5px;
cursor: pointer;
background-color: #fff
p {
margin-bottom: 0;
margin-top: 5px;
font-weight: bold;
}
`;
render() {
return (
<div>
<Button type="primary" onClick={this.showModal}>New Transaction</Button>
<Modal
title="New transaction"
visible={this.state.visible}
nOk={this.handleCancel}
onCancel={this.handleCancel}
>
<Row gutter={[16, 16]}>
<Col span={8}>
<this.ProductBtn onClick={this.handleProductClicked}>
<FaUserFriends style={{ fontSize: '24px' }} />
<p>Add couple</p>
<small>$70.00</small>
</this.ProductBtn>
</Col>
...
</Row>
</Modal>
</div>
)
}
}
export default App;
This is how it should look and how it looks in CodeSandbox:
This is how it looks in my application, without the widget/button-like styling on the ProductBtn styled component:

How to use StyledComponents theme inside of Component

Below I've created a style called Link. However the theme is inside of this.props. What is the way to get the theme out of props and passed into the Link styled component?
ReferenceError: theme is not defined
import React from 'react';
import styled from 'styled-components';
import { withTheme } from 'styled-components';
export const Link = styled.p`
position: absolute;
z-index: 10;
bottom: 20px;
right: 300px;
width: 100%;
font-size: 1.5rem;
text-align: right;
cursor: pointer;
a {
color: ${theme.apricot}; // <-- error
cursor: pointer;
:hover {
color: ${theme.offWhite}; // <-- error
}
}
`;
class NomicsLink extends React.Component {
render() {
console.log(this.props.theme);
return (<Link>Powered by Nomics APIs.</Link>)
}
}
export default withTheme(NomicsLink);
This console.log prints the following:
{ red: '#FF0000',
black: '#393939',
grey: '#3A3A3A',
lightgrey: '#E1E1E1',
offWhite: '#EDEDED',
apricot: '#FEBE7E',
margin: 0,
padding: 0 }
All styled-components receive theme prop automatically.
You can access them inside the styled component with:
const Link = styled.a`
color: ${props=>props.theme.apricot};
`;
More options on theming, see docs

Categories

Resources