How to wrapp Reactjs component with CSS - 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.

Related

Keeping two components the same height in all screen sizes (one with scroll, another without)

I have the following use case described in the image below.
I'm using Bootstrap 5 & React with Typescript
There are two components in a page called MainPage.tsx called Component1.tsx and Component2.tsx
Component2 has many more elements/content than Component1, so I want to put a scrollbar into it
I want Component1 to be the same height as Component2
On screen sizes with a width larger than >=768px (Boostrap .md breakpoint) I want the Component2 to be to the right of Component1. On mobile-like screens with widths >=576px (Bootstrap .sm breakpoint), I want Component2 to be right below Component1. In both modes, Component1 maintains its scrollbar.
However, what happens in my current code is that on mobile-like screens (when Component2 is below Component1), there is a big empty space between the two components.
My current code looks like this:
// MainPage Component
const MainPage = () => {
}
return (
<div className='d-flex flex-column flex-lg-row'>
<Component1 />
<Component2 />
</div>
)
}
export { MainPage }
// Component1.tsx
const Component1 = () => {
return (
<div className='flex-column flex-lg-row-auto w-100 w-lg-300px w-xl-400px mb-10 mb-lg-0'
style={{ overflow: 'scroll', overflowX: "hidden", height: "100vh" }}>
<div className='card card-flush'>
<div className='card-header pt-7'>
<OtherComponent1>
</div>
<div className='card-body pt-5'>
<div
className='scroll-y me-n5 pe-5 h-200px h-lg-auto'>
<OtherComponent2> />
</div>
</div>
</div>
</div>
)
}
export { Component1 }
// Component2.tsx
const Component2 = () => {
return (
<div className='flex-lg-row-fluid ms-lg-7 ms-xl-10'>
<div className='card' style={{ height: '100vh', overflowX: "hidden" }}>
<OtherComponent3/>
</div>
</div>
)
}
export { Component2}
However, what happens is that with this code, in boostrap .md screen-sizes it works as intended, but in bootstrap .sm screens-sizes, there's a big empty space between the two components. I suspect the problem is due to the "100vh" in Component1.tsx
What is the culprit and how can I solve it?

React-bootstrap modal adding margin or padding

I have added a modal to display a login pop-up.
My issue is that the Modal itself seems having padding internally which break my user experience.
As you can see below in the image:
Adding a link as I am not able to attached the image. https://photos.app.goo.gl/iJZRZ28o8dQhmJh4A
[enter link description here][1]
and below the code
import React from "react";
import { Modal } from "react-bootstrap";
import '../../assets/styles/Login.css';
class LoginRegisterModal extends React.Component {
constructor(props, context) {
super(props);
this.state = {show: false};
}
....
render() {
const styleModal = {
marginTop: "15%",
marginLeft: "30%",
padding: 0,
width:770,
height:480,
backgroundColor:"#ffffffff",
borderRadius:21.5,
}
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('container');
signUpButton.addEventListener('click', () => {
container.classList.add('right-panel-active');
});
signInButton.addEventListener('click', () => {
container.classList.remove('right-panel-active');
});
return (
<Modal show={this.state.show} style={styleModal} >
<div class="container" id="container">
<div>
.....
</div>
<div class="overlay-container">
<div class="overlay">
<div class="overlay-panel overlay-left">
<h1>Sign in.</h1>
<p>
Nice to see you again.Login and continue the journey.
</p>
<button class="ghost" id="signIn">Sign In</button>
</div>
<div class="overlay-panel overlay-right">
<h1>Hey, new friend!</h1>
<p>New to the Village? Sign up and start your journey</p>
<button class="ghost" id="signUp">Sign Up</button>
</div>
</div>
</div>
</div>
</Modal>
);
}
}
export default LoginRegisterModal;```
I have tried to remove all my containers and just display a simple text using `<p> test </p>` and I am facing the same issue. The `marginTop` and `marginLeft` defined in the style allowed my to move the Modal from the top left corner.
Any idea why I have some margin inside the modal ?
[1]: https://photos.app.goo.gl/iJZRZ28o8dQhmJh4A

How to add !important into React inline CSS style

How to add !important into my inline CSS property?
If I add it after 2px it just ignore whole style.
import React from "react";
export default class Todo extends React.Component {
render() {
const {text} = this.props;
const cardStyles = {
borderWidth: '2px'
};
return (
<div class="card mb-2 border" style={cardStyles}>
<div class="card-body">
<h5 class="card-title m-0">{text}</h5>
</div>
</div>
)
}
}
Apparently it is not supported https://github.com/facebook/react/issues/1881#issuecomment-262257503
meanwhile you can use a hack doing:
<div ref={element => {
if (element) element.style.setProperty('border', '2px', 'important');
}}
/>
It appears it currently isn't supported based on this GitHub issue https://github.com/facebook/react/issues/1881

Conditionally inline style a react component based on prop

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>

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