styled-components toggle classes - reactjs

this.state.checkBool is true / false
The HTML structure like this, toggle class1 and class2
<div class='common class1'>
<div class='common class2'>
css looks like
common {
display: block;
background: grey;
}
.class1 {
position: absolute;
left: 1px;
right: auto;
top: 2px;
background: blue;
}
.class2 {
position: absolute;
left: auto;
top: 2px;
right: 30px;
background: yellow;
}
The styled component
const Wrapper = styled.div`
display: block;
background: grey;
// Should this part use props to check true or false?
${prosp => }
`
I am stuck on how to toggle classes
<Wrapper toggle={this.state.checkBool ? class1 :class2 }/>

You want to keep all the CSS in the styled.div and use the toggle prop to decide which CSS you should use for the component depending on its value.
Example
const Wrapper = styled.div`
display: block;
background: grey;
${props => {
if (props.toggle) {
return `
position: absolute;
left: 1px;
right: auto;
top: 2px;
background: blue;
`;
} else {
return `
position: absolute;
left: auto;
top: 2px;
right: 30px;
background: yellow;
`;
}
}}
`;
class App extends React.Component {
state = { checkBool: false };
componentDidMount() {
setTimeout(() => {
this.setState({ checkBool: true });
}, 1000);
}
render() {
return <Wrapper toggle={this.state.checkBool}> Foo </Wrapper>;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root"></div>

Related

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

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.

How to change class of Nav bar when scrolling down in react?

hi this is my code and i want to change my Navigation bar color on scrolling but how can i do it?
i want to remove my class and add my new class to it,but i cant do this and i am newbie in react.
do i need life cycle hooks?
what should i do for my state?
import React from 'react';
import DrawerToggleButton from '../SideDrawer/DrawerToggleButton'
import './Toolbar.css'
class Toolbar extends React.Component {
state = {
};
scroll = () => {
if (this.scrollTop() <= 10){
(".toolbar").addClass("scroll");
}
else{
(".toolbar").removeClass("scroll")
}
};
render() {
return(
<header className="toolbar">
<nav className="toolbar__navigation">
<div className="toolbar__toggle-button">
<DrawerToggleButton click={this.props.drawerClickHandler} />
</div>
<div className="toolbar__logo"><a href={"/"}>THE LOGO</a></div>
<div className="spacer"/>
<div className="toolbar_navigation-items">
<ul>
<li><a href={"/"}>Products</a> </li>
<li><a href={"/"}>Users</a> </li>
</ul>
</div>
</nav>
</header>
);
}
}
export default Toolbar;
and this is my css code:
.toolbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: linear-gradient(
to right,
#e4faff 0%,
#e9f8ff 50%,
#f9f6ff 50%,
#e9f8ff 100%);
height: 56px;
z-index: 200;
}
.toolbar__navigation {
display: flex;
height: 100%;
align-items: center;
padding: 0 1rem;
}
.toolbar__logo {
margin-left: 1rem;
}
.toolbar__logo a {
color: #3500b6;
text-decoration: none;
font-size: 1.5rem;
}
.spacer {
flex: 1;
}
.toolbar_navigation-items ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
}
.toolbar_navigation-items li {
padding: 0 0.5rem;
}
.toolbar_navigation-items a {
color: #370ab6;
text-decoration: none;
font-size: 18px;
font-weight: bold;
}
.toolbar_navigation-items a:hover,
.toolbar_navigation-items a:active {
color: #000000;
border-bottom: 2px solid black;
}
.toolbar.scroll {
background-color: black;
color: white;
}
#media (max-width: 768px) {
.toolbar_navigation-items {
display: none;
}
}
#media (min-width: 769px) {
.toolbar__toggle-button {
display: none;
}
.toolbar__logo {
margin-left: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
i used javascript as i now about this syntax but in react what should i do?

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.

Reactjs - setState() make all texts of apps flickering

In component A, I got some setState functions to update states when clicking on some element. What strange happens is that all texts of the whole app flicked. Component A is completed isolated from others. This only happens on Chrome, firefox works just fine :( please help
My MenuButton component code :
import React, { Component } from 'react';
import styled, { css } from 'styled-components';
const InsideLineCommon = styled.span`
position: absolute;
width: 100%;
height: 100%;
left: 0%;
&:after {
content: '';
width: 100%;
height: 100%;
position: absolute;
background: ${props => props.theme.colors.primary1};
}
&:before {
content: '';
width: 100%;
height: 100%;
position: absolute;
background: ${props => props.theme.colors.primary1};
}
`;
const InsideLine = InsideLineCommon.extend`
&:after {
left: -200%;
}
transition: left ${props => props.theme.animationTime};
left: ${props => (props.isHalfWidth ? '-100%' : '-200%')};
${props => props.isInitialMoving && css`
left: -50%;
`}
${props => props.isInitialMoving && props.isHalfWidth && css`
left: 100%;
`}
${props => props.isHorizontalBarsMoving && css`
left: 200%;
`}
${props => props.isCrossoverBarMoving && css`
left: -200%;
`}
${props => props.isHalfWidth && css`
&:after {
width: 50%;
}
&:before {
width: 50%;
left: -100%;
}
`}
`;
const CommonLine = styled.div`
width: 100%;
height: 15%;
position: absolute;
`;
const MiddleLine = CommonLine.extend`
top: calc(100% / 2 - 7.5%);
`;
const TopLine = CommonLine.extend`
top: 0px;
`;
const BottomLine = CommonLine.extend`
bottom: 0px;
`;
const Wrapper = styled.button`
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
cursor: pointer;
border-style: none;
background: transparent
padding: 0px;
&:focus {
outline: 0px;
}
`;
const CrossoverWrapper = styled.div`
width: 100%;
height: 100%;
position: absolute;
top: 0px;
display: flex;
flex-direction: column;
justify-content: center;
&:after {
content: '';
position: absolute;
width: 100%;
height: 15%;
background: ${props => props.theme.colors.primary1};
transform-origin: center;
transform: ${props => (props.isCrossoverBarMoving ? 'rotate(45deg) translate(0%)' : 'rotate(45deg) translate(-130%)')};
transition: ${props => (!props.isCrossoverBarMoving
? `transform ${props.theme.animationTime} 0s`
: `transform ${props.theme.animationTime} ${props.theme.animationTime}`)};
border-radius: 5px;
}
&:before {
content: '';
position: absolute;
width: 100%;
height: 15%;
background: ${props => props.theme.colors.primary1};
transform-origin: center;
transform: ${props => (props.isCrossoverBarMoving ? 'rotate(-45deg) translate(0%)' : 'rotate(-45deg) translate(130%)')};
border-radius: 5px;
transition : ${props => (!props.isCrossoverBarMoving
? `transform ${props.theme.animationTime} 0s`
: `transform ${props.theme.animationTime} ${props.theme.animationTime}`)};
}
`;
class MenuButton extends Component {
constructor(props) {
super(props);
this.state = {
isCrossoverBarMoving: false,
isHorizontalBarsMoving: false,
isInitialMoving: false,
};
this.handleMouseClick = this.handleMouseClick.bind(this);
this.handleMouseHover = this.handleMouseHover.bind(this);
}
componentDidMount() {
setTimeout(() => {
this.setState({
isInitialMoving: true,
});
}, 1000);
}
handleMouseClick() {
this.setState(prevState => ({
isCrossoverBarMoving: !prevState.isCrossoverBarMoving,
}));
}
handleMouseHover() {
this.setState(prevState => ({
isHorizontalBarsMoving: !prevState.isHorizontalBarsMoving,
}));
}
render() {
const { isHorizontalBarsMoving, isCrossoverBarMoving, isInitialMoving } = { ...this.state };
return (
<Wrapper
onClick={this.handleMouseClick}
onMouseEnter={this.handleMouseHover}
onMouseLeave={this.handleMouseHover}
>
<TopLine>
<InsideLine
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</TopLine>
<MiddleLine>
<InsideLine
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</MiddleLine>
<BottomLine>
<InsideLine
isHalfWidth
isHorizontalBarsMoving={isHorizontalBarsMoving}
isCrossoverBarMoving={isCrossoverBarMoving}
isInitialMoving={isInitialMoving}
/>
</BottomLine>
<CrossoverWrapper
isCrossoverBarMoving={isCrossoverBarMoving}
/>
</Wrapper>
);
}
}
export default MenuButton;
Whenever I click this component, the all texts of whole app did flickering :/

ReactCSSTransitionGroup enter animation not working, exit is working fine

I am creating a reusable modal, and everything is working but when I actually call the component, the enter transition is not working. Exit works perfectly. I get the error:
warning.js:45 Warning: Failed propType: transitionLeaveTimeout wasn't
supplied to ReactCSSTransitionGroup: this can cause unreliable
animations and won't be supported in a future version of React.Check
the render method of Modal
I have supplied enter and leave timeouts as instructed and still no luck.
import React from 'react';
import { render } from 'react-dom';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import '../../modal.css';
const Modal = React.createClass({
render(){
if(this.props.isOpen){
return (
<ReactCSSTransitionGroup transitionName={this.props.transitionName} transitionEnterTimeout={400} transitionLeaveTimeout={400}>
<div className="ui-modal" key={this.props.transitionName} {...this.props}>
{this.props.children}
</div>
</ReactCSSTransitionGroup>
);
} else {
return <ReactCSSTransitionGroup transitionName={this.props.transitionName} />;
}
}
});
const UiModal = React.createClass({
getInitialState(){
return { isModalOpen: false };
},
openModal() {
this.setState({ isModalOpen: true });
},
closeModal() {
this.setState({ isModalOpen: false });
},
setModalSize() {
this.setState({ isModalLarge: false });
},
render() {
const { openBtnText, header, subHeader, body, footer, optionalFooterText, closeBtnText, size } = this.props;
const modalSize = size === 'large' ? 'ui-modal-large' : 'ui-modal-small';
return (
<div className="ui-modal-trigger-container">
<h1>Modal small enter from bottom</h1>
<div className="button" onClick={this.openModal}>{ this.props.openBtnText }</div>
<Modal isOpen={this.state.isModalOpen} transitionName="modal-anim" id={modalSize}>
<h1 className="ui-modal-header">{header}</h1>
<div className="ui-modal-subheader">{subHeader}</div>
<div className="ui-modal-body">
{body}
</div>
<div className="ui-modal-footer">
<div className="ui-modal-footer-button-group">
<div className="ui-modal-footer-button button" onClick={this.closeModal}>{closeBtnText}</div>
<div className="ui-modal-optional-footer-text" onClick={this.closeModal}>{optionalFooterText}</div>
</div>
</div>
</Modal>
</div>
);
}
});
export default UiModal;
The only information I get back in the console is:
warning.js:45 Warning: Failed propType: transitionLeaveTimeout wasn't
supplied to ReactCSSTransitionGroup: this can cause unreliable
animations and won't be supported in a future version of React.Check
the render method of Modal
I am unsure how to fix since I have provided enter and leave timeouts already and it does not fix the issue.
The CSS for the modal is below:
.ui-modal-trigger-container {
width: 500px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 4px;
z-index: 0;
margin-top: 300px;
}
.ui-modal {
width: 450px;
margin: 0 auto;
top: 70%;
left: 35%;
padding: 20px;
background-color: green;
position: absolute;
z-index: 1;
border: 1px solid grey;
box-shadow: 0 0 5px 2px #fff;
background: white;
}
#ui-modal-small {
width: 450px;
margin: 0 auto;
top: 70%;
left: 35%;
padding: 20px;
background-color: green;
position: absolute;
z-index: 1;
border: 1px solid grey;
box-shadow: 0 0 5px 2px #fff;
background: white;
}
#ui-modal-large {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
top: 8%;
left:0%;
border: 1px solid #ccc;
background: white;
}
.ui-modal-header {
font-family: 'Flexo';
font-size: 28px;
border-bottom: 2px solid black;
width: 90%;
margin: 0 auto;
}
.ui-modal-subheader {
font-family: 'Flexo';
font-size: 13px;
width: 90%;
margin: 0 auto;
}
.ui-modal-body {
margin: 0 auto;
width: 90%;
padding: 10px;
}
.ui-modal-footer {
border-top: 2px solid black;
margin: 0 auto;
width: 90%;
}
.ui-modal-footer-button-group {
padding-top: 10px;
}
.ui-modal-footer-button {
float: right;
}
.ui-modal-optional-footer-text {
float: left;
color: #4099D4;
font-style: italic;
}
.modal-anim-enter {
opacity: 0.00;
transform: translateY(100%);
transition: all .5s;
}
.modal-anim-enter.modal-anim-enter-active {
opacity: 1;
transform: scale(1);
transition: all .5s;
}
.modal-anim-leave {
opacity: 1;
transform: translateY(100%);
transition: all .5s;
}
.modal-anim-leave.modal-anim-leave-active {
opacity: 0.00;
transform: translateY(100%);
}

Resources