Add and remove classes in React - css

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"}

Related

Modal fullscreen is aligned to the left

My fullscreen modal is aligned to the left. Centered property does not solve it. I have a row of the grid that dynamically displays a series of Cards. Each Card has the modal associated, so when you click the Card the modal opens with information from the Card.
This is the grid where i render it
<Grid.Column key={this.props.sensorid} width={4}>
<Card
onClick={() => {
this.setState({ modalOpen: true });
}}
color={color}
header={String(porce) + " %"}
description={this.props.sensorname}
meta={nivelUno + " mm"}
/>
<ModalSensor
sensorWell={this.props.sensorWell}
sensorName={this.props.sensorConPrefijo}
sensorId = {this.props.sensorid}
modalOpen={this.state.modalOpen}
handleClose={() => {
this.setState({ modalOpen: false });
}}
/>
</Grid.Column>
This is the modal
export default class ModalSensor extends Component {
render() {
return (
<div>
<Modal
centered={true}
open={this.props.modalOpen}
onClose={this.props.handleClose}
closeOnEscape={true}
size={"Fullscreen"}
>
<Modal.Header>Nivel del sensor {this.props.sensorName}</Modal.Header>
<Modal.Content>
<Sensor sensorwell={this.props.sensorWell} sensorcodigo={this.props.sensorName}/>
</Modal.Content>
<Modal.Actions>
<Button
inverted
color="orange"
type="button"
icon="checkmark"
labelPosition="right"
onClick={this.props.handleClose}
content="Cerrar"
/>
</Modal.Actions>
</Modal>
</div>
);
}
}
that's a common problem when using more than one css library just inspect your element with your browser dev tool and try to figure it out or else past it here None can help you (probably) because it's a css problem and you haven't any css here.
Good luck man.
I've also encountered this type of layout bug, but I fixed it by adding a custom class to <div class="ui fullscreen modal transition visible active" />
.customClass {
left: 50%;
transform: translateX(-50%);
}

Bottom margin has no effect on App Bar spacing

This app bar's bottom margin settings are being ignored while other css rules are displaying correctly:
<AppBar
className={appBarContainer}
style={{marginBottom : 100}} // also doesn't work
>
<Typography
variant='h6'
>{setNavTitle(view)}</Typography>
<CloseIcon
onClick={() => setFullViewIsOpen(false)}
style={{ cursor : 'pointer' }}
/>
</AppBar>
// App Bar Styles
const defineJss = makeStyles(theme => ({
appBarContainer : {
padding : '10px 20px'
, display : 'flex'
, flexFlow : 'row nowrap'
, justifyContent : 'space-between'
, marginBottom : '100px !important' // removing !important doesn't help
, '& > *' : {
border : "2px dashed orange"
}
}
}));
The <AppBar /> is from a Material Ui React.js library. Margin top on the next element does work to push everything down but then creates a coupling issue. How can I get margin-bottom to work here?
Working Example
Here I have the issue shown in a style object: https://codesandbox.io/s/cool-heisenberg-jgt9l?fontsize=14
This is happening because you are using position="fixed" (this is the default position of AppBar).
When you render the app bar position fixed, the dimension of the
element doesn't impact the rest of the page. This can cause some part
of your content to be invisible, behind the app bar. Here are 3
possible solutions:
You can use position="sticky" instead of fixed. ⚠️ sticky is not
supported by IE 11.
You can render a second component:
function App() {
return (
<React.Fragment>
<AppBar position="fixed">
<Toolbar>{/* content */}</Toolbar>
</AppBar>
<Toolbar />
</React.Fragment>
);
}
You can use theme.mixins.toolbar CSS:
const useStyles = makeStyles(theme => ({
offset: theme.mixins.toolbar,
}))
function App() {
const classes = useStyles();
return (
<React.Fragment>
<AppBar position="fixed">
<Toolbar>{/* content */}</Toolbar>
</AppBar>
<div className={classes.offset} />
</React.Fragment>
)
};
In my opinion, the best solution for you is add a separator div, and set it's marginBottom to theme.mixins.toolbar :
function App(props) {
const classes = useStyles(props);
return (
<div className="App">
<AppBar
position="fixed"
className={classes.appBarContainer}
>
Placeholder Text
</AppBar>
<div className={classes.appBarSeparator} />
<p>Exterior Text</p>
</div>
);
}
const useStyles = makeStyles(theme => ({
appBarContainer : {
offset: theme.mixins.toolbar,
padding : '10px 20px',
marginBottom:'200px !important'
, display : 'flex'
, flexFlow : 'row nowrap'
, justifyContent : 'space-between'
, '& > *' : {
border : "2px dashed orange"
}
},
appBarSeparator: theme.mixins.toolbar
}));

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.

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