Conditionally inline style a react component based on prop - css

I need to set the background color of a div based on a prop passed into my react component. Inline styling of React components I am pretty clear on, but I don't know how to correctly apply the inline style to change depending on a prop. I only want to assign the value of the prop rightSideColor in the inline styling of right-toggle if the prop selected is equal true.
export default function UiToggle(props) {
const { leftLabel, rightLabel, selected, rightSideColor, leftSideColor } = props;
return (
<div className="lr-toggle-select" style={{ width: `${width}px` }} >
<div className="lr-gray-background" />
<div>
{leftLabel}
</div>
<div className={'lr-toggle right-toggle' style={{ selected ? (backgroundColor: rightSideColor) : null }}>
{rightLabel}
</div>
</div>
);
}

Fixed a typo - { before className
and you can return an empty object if selected is false else the expected value
Example:
export default function UiToggle(props) {
const { leftLabel, rightLabel, selected, rightSideColor, leftSideColor } = props;
return (
<div className="lr-toggle-select" style={{ width: `${width}px` }} >
<div className="lr-gray-background" />
<div>
{leftLabel}
</div>
<div className='lr-toggle right-toggle' style={ selected ? {backgroundColor: rightSideColor} : {} }}>
{rightLabel}
</div>
</div>
);
}

I would suggest placing all styling and also the conditional operator in a separate const.
export default function UiToggle(props) {
const { leftLabel, rightLabel, selected, rightSideColor, leftSideColor } = props;
const rightToggleStyle = {
backgroundColor: selected ? rightSideColor : null
};
return (
<div className="lr-toggle-select" style={{ width: `${width}px` }} >
<div className="lr-gray-background" />
<div>
{leftLabel}
</div>
<div className="lr-toggle right-toggle" style={rightToggleStyle}>
{rightLabel}
</div>
</div>
);
}
I would try to do the same with the styling of the width. Good luck!

You can conditionally set the value of attributes like style, override them using rules of precedence, and determine whether to include them at all.
export default function UiToggle(props) {
const { leftLabel, rightLabel, selected, rightSideColor, leftSideColor } = props;
//specify style and id (and any other attributes) or don't.
const attrs = selected ? { style: { backgroundColor: "rightSideColor" },id:"hi123" }:{}
//Conditionally override the class names if we want:
if (props.className) attrs.className = props.className
return (
<div className="lr-toggle-select" style={{ width: `${width}px` }} >
<div className="lr-gray-background" />
<div>
{leftLabel}
</div>
{/*Use the spread operator to apply your attributes from attr*/}
{/*Note that the 'id' set below can't be overridden by attrs whereas*/}
{/*className will be. That's because precedence goes from right to left.*/}
{/*Rearrange them to get what you want.*/}
{/*Funky comment format is to make valid JSX and also make SO formatter happy*/}
<div className='lr-toggle right-toggle' {...attrs} id="attrs_cant_override_this_because_its_on_the_right">
{rightLabel}
</div>
</div>
);
}

Try something like this:
<div className='lr-toggle right-toggle' style={ selected ? {backgroundColor: rightSideColor} : '' }}>
{rightLabel}
</div>

Related

Add and remove classes in React

How can I add/ remove a className on click to change the style of some component?
I want to rotate the arrow on the right when I click on it and display: none; all the components beside it.
I also want to add do the same thing when I hit the mobile breakpoint
const [isRotated, setIsRotated] = useState(false);
handleClick() {
setIsRotated(true)
}
<button className={isRotated && 'rotate-class'} onClick={handleClick} />
{ !isRotated && <Element/>} // this will hide the element when clicked on the button
This would a better approach then setting display: none on the other elements, but if you must do that, do this:
<Element style={{ display: isRotated ? 'none': 'block' }} /> // I'm guessing the default style of display is 'block' of the elements you want to hide
You can add boolean state and function for change state same this code.
function App() {
const [state, setState] = useState(true);
const rotateHandler = () => {
setState(() => !state);
};
return (
<div className="App">
{/* button for change state */}
<button onClick={rotateHandler}>click for rotate and hide</button>
{/* icon for rotate */}
<div>
<FontAwesomeIcon
icon={faAngleRight}
style={{
transform: state ? "rotate(90deg)" : "rotate(0deg)"
}}
/>
</div>
{/* text hide when */}
<div style={{ display: state ? " block" : "none" }}>
<div>text hide after state is false</div>
<div>you can click on button</div>
<div>for rotate arrow icon</div>
<div>and hide this text</div>
</div>
</div>
);
}
I add conditions in inline style, but you can add conditions on className
className={state ? "show" : "hide"}

Hide nav button in react-material-ui-carousel

I've just implemented the react material ui carousel, and it was pretty straightforward, the only thing i didn't catch, is how to hide buttons and show them only on over.
I noticed the props navButtonsAlwaysVisible and set it to false but it isn't enough.
Should i implement my own logic for that, or maybe I'm just missing something?
here's the component code:
import styles from '../../styles/Testimonial.module.scss'
import Image from 'next/image'
import Carousel from 'react-material-ui-carousel'
const Testimonial = _ => {
const items = [
{
imageUrl: "/png/image0.webp",
feedback: "feedback0",
name: "name0",
location: "location0"
},
{
imageUrl: "/png/image1.jpeg",
feedback: "feedback1",
name: "name1",
location: "location1"
}
]
return (
<div id="customers" className={`section ${styles.testimonial}`}>
<h2 className={`title ${styles.title}`}>Clientes Felizes</h2>
<span className={"separator"}> </span>
<Carousel
className={styles.carousel}
autoPlay={true}
stopAutoPlayOnHover={true}
interval={5000}
animation={"slide"}
swipe={true}
navButtonsAlwaysVisible={false}
navButtonsProps={{
style: {
backgroundColor: "#8f34eb",
opacity: 0.4
}
}}
>
{
items.map( (item, i) => <Item key={i} item={item} /> )
}
</Carousel>
</div>
)
}
function Item(props)
{
return (
<article className={styles.testimonial__card}>
<div className={styles.testimonial__photo_container}>
<Image
className={styles.testimonial__photo}
src={props.item.imageUrl}
alt="Testimonial"
width={312}
height={300}
/>
</div>
<p className={styles.testimonial__copy}>{props.item.feedback}</p>
<span className={styles.testimonial__name}>{props.item.name}</span>
<span className={styles.testimonial__city}>{props.item.location}</span>
</article>
)
}
export default Testimonial;
there's a prop called navButtonsAlwaysInvisible
navButtonsAlwaysInvisible={true}
You can try using Custom CSS for your purpose. Based on the current rendered markup,
.jss6 {
opacity: 0;
transition: all ease 1000ms; /* So that it does not disappear quickly */
}
You can define the hover for the parent so that it displays only when the parent container is hovered on:
.jss1.Testimonial_carousel__3rny3:hover .jss6 {
opacity: 1;
}
This is how it works now:

How to hide wrapped components in React

I need to be able to hide components that gets wrapped because it goes over the max width.
<div style={{width:100}}>
<div style={{width:50}}>
component1
</div>
<div style={{width:50}}>
component2
</div>
<div style={{width:50}}>
component3
</div>
</div>
//But I actually use map to render children
<div style={{width:100}}>
{components.map((item, index) => {
return <div style={{width:50}}>component{index + 1}</div>)
}}
</div>
as shown in the code above, the parent div is of with 100. So the last component (component3) would go over the width of the parent by 50px and will be rendered in the second line. However, I want any component that leaves the first line to be not rendered at all. How do I make sure that only component1 and component2 shows and excludes component3?
You could add up the widths of all the components in a separate variable, and render null for all components remaining after the total width of those already rendered exceeds 100.
Example
class App extends React.Component {
state = {
components: [{ width: 50 }, { width: 50 }, { width: 50 }]
};
render() {
const { components } = this.state;
let totalWidth = 0;
return (
<div style={{ width: 100 }}>
{components.map((item, index) => {
totalWidth += item.width;
if (totalWidth > 100) {
return null;
}
return (
<div key={index} style={{ width: 50 }}>
component{index + 1}
</div>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

How to wrapp Reactjs component with CSS

I'm pretty new to Reactjs world and I have wrote component that I would love to make beautiful with CSS :)
I have component consisted of few buttons and boxes which would be displayed after button is clicked.
class Days extends React.Component {
constructor(props) {
super(props);
this.state = { showComponent: "Box1" };
}
toggleDiv = name => {
if (name === "monday") {
this.setState({
showComponent: "Box1"
});
} else if (name === "thursday") {
this.setState({
showComponent: "Box2"
});
}
};
render() {
return (
<div>
<button onClick={() => this.toggleDiv("monday")}>
<div className="botun">Monday</div>
</button>
{this.state.showComponent === "Box1" && <Box1 />}
<button onClick={() => this.toggleDiv("thursday")}>
<div className="botun">Thursday</div>
</button>
{this.state.showComponent === "Box2" && <Box2 />}
</div>
);
}
}
class Box1 extends React.Component {
render() {
return (
<div className="container">
<div className="row">
<div className="col">
<h1>BOx1</h1>
</div>
</div>
</div>
);
}
}
class Box2 extends React.Component {
render() {
return (
<div className="container">
<div className="row">
<div className="col">
<h1>Box2</h1>
</div>
</div>
</div>
);
}
}
After button1 is clicked belonging boxes will be shown under.
So my question is how to put all buttons and boxes into one container and style it like in screenshot?
If I include it in my landingpage.js like this
<div className="container">
<div className="row">
<Days />
</div>
</div>
How can I still make my buttons be in one line?
I am not sure how to approach this with CSS.
What is the best practice when using CSS and CSS frameworks with ReactJS?
I am using global style.css and Boostrap.
You should wrap all your buttons inside a single div, give the container a single class, give it's children a modifier class when they are active and if you want to animate the display of the boxes then you shouldn't unmount them when another button is active opting for making them invisible or something like that because otherwise it's kinda difficult to not have React just pop them into existence.
I use inline style tags. It's really a personal preference situation. As you try new things you'll discover the practice that's best for you and for individual projects. An inline style tag looks like this.<div style={{ display: 'flex', width: '100%', backgroundColor: 'red' }}></div> the benefit to this is you can keep styles defined in the component.

Add a State property to an Inline Style in React

I have a react element that has an inline style like this: (Shortened version)
<div className='progress-bar'
role='progressbar'
style={{width: '30%'}}>
</div>
I want to replace the width with a property from my state, although I'm not quite sure how to do it.
I tried:
<div className='progress-bar'
role='progressbar'
style={{{width: this.state.percentage}}}>
</div>
Is this even possible?
You can do it like this
style={ { width: `${ this.state.percentage }%` } }
Example
yes its possible check below
class App extends React.Component {
constructor(props){
super(props)
this.state = {
width:30; //default
};
}
render(){
//when state changes the width changes
const style = {
width: this.state.width
}
return(
<div>
//when button is clicked the style value of width increases
<button onClick={() => this.setState({width + 1})}></button>
<div className='progress-bar'
role='progressbar'
style={style}>
</div>
</div>
);
}
:-)

Resources