How can I change the css styles using JavaScript on React ?
For example I would make this:
document.querySelector('.container').style.backGroundColor='purple';
}
Is it right ? Or should i make it with another way ?
You can use the style attribute.
<SomeComponent style={{
backgroundColor: someCondition ? 'purple' : null
}} />
Considering paragraph element
document.getElementsByClassName("container").style.color = "blue";
The simple way to change css in Reactjs is Inline styling. Others way you can see at: https://codeburst.io/4-four-ways-to-style-react-components-ac6f323da822
Let example. If your want change color of user status. Active will be green or deactive will be red.
const Example = (props) => {
let isActive = Math.floor(Math.random() * 2) % 2 === 0;
const color = isActive ? 'green' : 'red';
return <div style={{backgroundColor: color}}> {isActive ? 'Active' : 'Deactive'} </div>;
}
OR:
const Example = (props) => {
let isActive = Math.floor(Math.random() * 2) % 2 === 0;
return <div style={{backgroundColor: isActive ? 'green' : 'red'}}> {isActive ? 'Active' : 'Deactive'} </div>;
}
OR all styling:
const Example = (props) => {
let isActive = Math.floor(Math.random() * 2) % 2 === 0;
let styleStatus = isActive ?
{
backgroundColor: 'green',
fontSize: '20',
} :
{
backgroundColor: 'red',
fontSize: '15',
};
return <div style={styleStatus}> {isActive ? 'Active' : 'Deactive'} </div>;
}
make a const type obj like this(must create inside render method)
const mystyle = {
color: "white",
backgroundColor: "DodgerBlue",
padding: "10px",
fontFamily: "Arial"
};
and assign this into your element like this
h1 style={mystyle}>Hello Style!</h1>
Related
I have the following code to style a button based off of a select box:
const buttonStyles = {
backgroundColor: buttonStyle === 'Black' ? colors.interactiveForegroundSecondary : buttonStyle === 'Green' ? colors.backgroundInverseSecondary : buttonStyle === 'White' ? colors.backgroundPrimary : buttonStyle === 'Lime Green' ? colors.graphTertiary : '',
color: buttonStyle === 'Black' ? colors.textInversePrimary : buttonStyle === 'Green' ? colors.textInversePrimary : buttonStyle === 'White' ? colors.interactiveForegroundSecondary : buttonStyle === 'Lime Green' ? colors.backgroundInverseSecondary : '',
"&:hover": {
background: buttonStyle === 'Black' ? colors.backgroundInversePrimary : buttonStyle === 'Green' ? colors.accentPrimary : buttonStyle === 'White' ? colors.errorBackground : buttonStyle === 'Lime Green' ? colors.backgroundInverseSecondary : '',
color: buttonStyle === 'Lime Green' ? colors.graphTertiary : ''
},
} as CrateStyleObject
And I am trying to refactor this into an Enum map in typescript like so:
enum ButtonBackground {
Black = colors.interactiveForegroundSecondary,
Green = colors.backgroundInverseSecondary,
White = colors.backgroundPrimary,
Lime Green = colors.graphTertiary ,
}
const submitBackground = (Object.keys(ButtonBackground) as (keyof typeof ButtonBackground)[]).map(
(key, index) => {
console.log(key);
return ButtonBackground[key] + index;
},
);
then setting it here on the component:
<Button
style={
buttonStyles
}
type="submit">
{text}
</Button/>
But I am having trouble assigning colors.interactiveForegroundSecondary to one of the keys since it is not a string.
Also the background color and color of the button needs to change based off of the selected value – would I have to create a separate Enum for each of the Background Color/Text Color as well as the Hover Background Color / Text Color?
I think that it would be convenient to create a separate enum for ButtonBackgroundColor, ButtonColor, ButtonBackgroundColorOnHover and ButtonColorOnHover.
I'm not sure though why are you trying to iterate over the enum when you actually want to set the buttonStyles according only to the value of the buttonStyle variable. I would go about it like this:
const buttonStyle = 'Lime Green' // For example
// You'll need to remove whitespace because enums cannot have two words
const buttonStyleWithNoWhitespace = buttonStyle.replace(/\s/g, '')
enum ButtonBackground {
Black = colors.interactiveForegroundSecondary,
Green = colors.backgroundInverseSecondary,
White = colors.backgroundPrimary,
LimeGreen = colors.graphTertiary,
}
enum ButtonColor {
Black = colors.backgroundInversePrimary,
Green = colors.accentPrimary,
White = colors.errorBackground,
LimeGreen = colors.backgroundInverseSecondary,
}
enum ButtonBackgroundOnHover {
Black = colors.backgroundInversePrimary,
Green = colors.accentPrimary,
White = colors.errorBackground,
LimeGreen = colors.backgroundInverseSecondary,
}
enum ButtonColorOnHover {
Black = '',
Green = '',
White = '',
LimeGreen = colors.graphTertiary,
}
const buttonStyles = {
backgroundColor: ButtonBackground[buttonStyle as keyof typeof ButtonBackground],
color: ButtonColor[buttonStyle as keyof typeof ButtonColor],
"&:hover": {
background: ButtonBackgroundOnHover[buttonStyle as keyof typeof ButtonBackgroundOnHover],
color: ButtonColorOnHover[buttonStyle as keyof typeof ButtonColorOnHover]
}
} as CreateStyleObject
<Button
style={buttonStyles}
type="submit">
{text}
</Button/>
The as keyof typeof Enum makes the usage of enums a bit too much when you can use a simple object for each of them, but perhaps there are other specific reasons that makes using enums necessary.
I'm having a problem where I'm using map method to create a table, then on each row of the table I have a Button that triggers conditional rendering based on state (true/false).
The problem is that all conditional renders are based on the same state this.state.displayColorPicker ? So when you click the button on one row it triggers the conditional render on all the rows.
Here is my function that renders the body of the Table :
display_table = () => {
if (!this.state.data) {
return <tr />
}
if (!this.state.data[1]) {
return <tr />
}
let xx = this.state.valuesplayers;
let i=-1;
let j=-1;
let k=500;
let l = -400;
if (typeof xx !== 'undefined' && xx !== 's') {
let xx3 = xx.map((player_row, row) =>{
i = i+1;
return (<tr className='dataRow' key={i} id={i}>{
player_row.map((player_col, col)=>{
if (this.state.data[1][col].length > 2) {
k=k+1;
return(<td key={'displayTable'+k} style={{backgroundColor: this.state.valuesplayers[row][col] === this.state.savedData[row][col] ? '' : 'yellow'}}><select key={this.state.valuesplayers[row][col]+k+0.5} value={this.state.valuesplayers[row][col]} onChange={e => this.handleChangeCell(e, row, col)}>
{this.state.data[1][col].map((DefValue, index) => {
i+=1;
if (index >= 2) {
return(<option key={'option' +i}>{DefValue}</option>);
}
return'';
})}
</select></td>)
} else if (this.state.data[1][col][0] === "Color") {
l = l+1;
const popover = {
position: 'absolute',
zIndex: '2',
top :'55px',
right:'0px',
}
const cover = {
position:'fixed',
top: '0px',
right: '0px',
bottom: '0px',
left: '0px',
}
return(<td className='SliderPicker' key={'couleur'+l} style={{backgroundColor: this.state.valuesplayers[row][col] === this.state.savedData[row][col] ? '' : 'yellow'}}>
<div className='ColorWrapper'>
<button className='colorButton' style={{borderColor: this.state.valuesplayers[row][col] === this.state.savedData[row][col] ? '' : this.state.valuesplayers[row][col],
borderWidth: this.state.valuesplayers[row][col] === this.state.savedData[row][col] ? '' : '5px' }} onClick={e => this.handleClick(e) }>Pick Color
</button>
{this.state.displayColorPicker ?
<div style={ popover }>
<div style={ cover } onClick={e => this.handleClose(e) }/>
<SketchPicker key={'ColorSelector'+l+1.5} type='color' color={this.state.valuesplayers[row][col]} value={this.state.valuesplayers[row][col]}
onChange={color => this.handleChangeColor(color, row, col)}/>
</div> : null }
</div>
</td>)
}
else {
j+=2;
return(<td key={'cellule'+j} style={{backgroundColor: this.state.valuesplayers[row][col] === this.state.savedData[row][col] ? '' : 'yellow'}}>
<input key={'inputText'+k+1.5} type="text" className='inputTable' value={this.state.valuesplayers[row][col]}
onChange={e => this.handleChangeCell(e, row, col)}/></td>)
}
})
}
<td className='ButtonRow' key={'buttonRow'+i}>
<button key={'DelRow' + i} onClick={this.delARow} className='DeleteRow'>X</button>
<button key={'AddRow' + i} onClick={this.addARow} className='AddRow'>+</button>
</td></tr>
)
})
return(xx3);
}
else {
return <td key='display table error'/>
}
}
Currently my state is declared in the constructor method :
constructor(props) {
super(props);
this.state = {
displayColorPicker: false,
};
}
If someone could help me to map a different state for each row (or any other idea that could work)
Thanks in advance.
Edit : some HandleChange functions :
handleChangeCell(e, row, col) {
let newplayers2 = this.state.valuesplayers;
newplayers2[row][col] = e.target.value;
this.setState({valuesplayers: newplayers2});
}
handleChangeColor(color, row, col) {
this.setState({color: color.hex});
console.log('color', color.hex)
let newplayers2 = this.state.valuesplayers;
newplayers2[row][col] = color.hex;
this.setState({valuesplayers: newplayers2});
}
I've made a covid related travel map here: Where Can We Go Now
It's a static react JS website, billy basic with create-react-app. It uses amongst other things the excellent React Simple Maps (kudos to the creator) and react-tooltip.
Expected behaviour:
Locally the tooltip works fine when tested with npm run start
I move my mouse over a country and the tooltip displays some relevant information approximately where my mouse is on the map.
The Problem:
. . . once published with npm run build sort of works but strange things happen.
Please follow link to website to observe, but in short, if the sea (i.e. an area that isn't a country - so not defined by an svg in the topojson) is clicked then the tooltip is place at the top centre of the whole map itself.
Some bits of relevant code:
Index.js (snippet):
const [content, setContent] = useState("");
return (
<div><h1> Where can we go on holiday ?* </h1>
<MapChart setTooltipContent={setContent}/>
<ReactTooltip html={true}>{content}</ReactTooltip>
</div>
);
}
MapChart.js (snippet):
return (
<div>
<p><small>*Right now in the UK: {data.headlineAdviceNow} Last updated at {updateString}</small></p>
<ComposableMap
projectionConfig={{
rotate: [-40, -30, 10],
scale: 1600
}}
width={mapWidth}
height={mapHeight}
style={{ maxWidth: "100%", height: "80vh", background: "#b3b3b3", borderStyle: "solid", borderColor: "white", margin: 0.5,
borderRadius: 20 }}
>
<ZoomableGroup zoom={zoom} center={center} translateExtent={[
[0, 0],
[mapWidth, mapHeight]
]} maxZoom={15} data-tip="">
<Sphere stroke="#E4E5E6" strokeWidth={0.5} />
<Graticule stroke="#E4E5E6" strokeWidth={0.2} />
{!loading && (<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map((geo) => {
const d = data.countries.find((s) => s.country.iso_a3 === geo.properties.ISO_A3);
return (
<Geography
key={geo.rsmKey}
geography={geo}
style={{
default: {
outline: "none",
stroke: "grey",
strokeWidth: "1",
strokeLinecap: "butt",
fill: d ? colorScale(d[attr]) : "#F5F4F6"
},
hover: {
outline: "none",
stroke: "black",
strokeWidth: "3",
strokeLinecap: "butt",
fill: d ? colorScale(d[attr]) : "#F5F4F6"
},
pressed: {
outline: "none"
}
}}
onMouseEnter={() => {
const NAME = geo.properties.NAME;
const travelIndex = d ? d["indexDescription"] : "Unknown";
//const border = d ? d["borderStatusString"] : "Unknown";
const returnStatus = d ? (fromCountry==="GBR" ? d["ukCategory"] : "TBC") : "Unknown";
const vaccinePc = d ? d.vaccineData["total_vaccinations_per_hundred"] + "%" : "NK";
const arrival = (() => {try{ return d["restrictionsFrom"][data["iomKeys"].indexOf(fromCountry)].split("-") } catch {return [4,""]}});
const arrivalLevel = rstrctLkup[arrival()[0]]["short"]
//const arvlRtns = arrival()[1].length===0 ? arrival()[1] : arrival()[1].split(",")
//var text =""
//var i;
//for (i = 0; i < arvlRtns.length; i++) {
// if (data["restrictionDefs"][arvlRtns[i]]) {
// if (i===0) {text="<br />Arrival Details:<br />"}
// text += data["restrictionDefs"][arvlRtns[i]] + "<br>";
//}}
setTooltipContent(`<b>${NAME.toUpperCase()}:</b> ${travelIndex}<br /><p style="text-align: left"><b>RISK FACTORS</b><br />Vaccinated: ${vaccinePc}<br /><br /><b>CURRENT RESTRICTIONS</b><br />Entry: ${arrivalLevel}<br />Return: ${returnStatus}</p>`);
}}
onMouseLeave={() => {
setTooltipContent("");
}}
/>
);
})
}
</Geographies>
)}
</ZoomableGroup>
</ComposableMap>
</div>
);
};
export default memo(MapChart);
What I've tried:
Variations of setting tooltip position, and moving where and what data-tip="" is. Also, banging head on wall.
I was inaccurate in my question, so didn't provide relevant details that was the source of the problem.
I publish with github actions and this was the fix:
yarn install --frozen-lockfile
The frozen lockfile was the key to make sure I was using the exact versions of relevant packages as I had been testing locally. I'd erroneously suggested I was using npm.
const Dropdown = ({ options, selected, onSelectedChange }) => {
const [ open, setopen ] = useState(false);
const renderedOptions = options.map((option) => {
if (option.value === selected.value) {
return null;
}
return (
<div key={option.value} className="item" onClick={() => onSelectedChange(option)}>
{option.label}
</div>
);
});
return (
<div className="ui form">
<div className="field">
<label className="label">Select a color</label>
<div onClick={() => setopen(!open)} className={`ui selection dropdown ${open ? 'visible active' : ''}`}>
<i className="dropdown icon" />
<div className="text">{selected.label}</div>
<div className={`menu ${open ? 'visible transition' : ''}`}>{renderedOptions}</div>
</div>
</div>
//Here is the selected.value state (value contains string of color name
{<div style={{ color: `${selected.value}` }}>{selected.value}</div>}
</div>
);
};
export default Dropdown;
const options = [
{
label: 'The Color Red',
value: 'red'
},
{
label: 'The Color Green',
value: 'green'
},
{
label: 'The Color Blue',
value: 'blue'
}
];
How can I use the selected.value in an external CSS file?
The data in the selected.value is a string of color name(s).
You can probably use Styled Components if that's what you're looking for, just an example, not really well thought out. The component can be in another file
const HoveredLink = styled.span`
color: ${props => props.selected ? 'black' : 'rgb(150, 153, 156)'};
`
<HoveredLink selected={\\someconditionhere} > Hover me <HoveredLink/>
You can simple use as a variable, this is not exactly CSS. So this one should work:
<div style={{color: selected.value}} >{ selected.label } </div>
You can also set style as a new variable:
const Dropdown = ({options,...}) => {
const styleDiv = {
color: options.value
}
//...
return (
//...
<div style={styleDiv}> {options.label} </div>
)
}
Here is how I solved it by using concept from this URL
import styles from './colorchange.css';
//...
//For setting default value (and closing dropdown when clicked outside)
useEffect(() => {
document.body.addEventListener('click', (event) => {
if (ref.current.contains(event.target)) {
return;
}
setopen(false);
});
document.documentElement.style.setProperty(`--variablename`, selected.value);
}, []);
//...
//inside renderedoption
return (
<div
key={option.value}
className="item"
onClick={() => {
onSelectedChange(option);
document.documentElement.style.setProperty(`--variablename`, option.value);
}}
>
{option.label}
</div>
);
//....
//for printing the color
<div className="colorcolor">This text is: {selected.value}</div>
CSS FILE:
{
--variablename: default;
}
.colorcolor {
color: var(--variablename);
}
Another way using CSS stylesheet.
Usually when I need to pass a value to use it for CSS I'll
go for specific CSS classes as I rather use the stylesheet
for style ( !== style within component ) for scalability reasons &
ease to access. If it can help ...
I. Known values case / no need to convert into word
to expect ( seems like it should be either [ blue,red,green ])
<div className = { selected.value } />
II. Need to convert into word
Let's say you need to change a selected.value that could be an hexadecimal value, you'll need to associate a word className you could use for CSS later on.
This is just an example and you can do a lot more within the expression passed
// convert anticipated value to the word you need
const colors = {'#F00': 'red', '#0F0' : green, '#00F': 'blue'};
<div className = { colors[ selected.value ] } />
📌Applied example
import './style.css' // style.css as same level of your component
const Dropdown = ({options,...}) => {
// if need to make wording *(cf:. case )
// const color = {'#F00': 'red', '#0F0' : green, '#00F': 'blue'};
//...
return (
//...
// if need to make wording *(cf:. case )
// <div className = { colors[ selected.value ] }> { selected.value } </div> */ }
<div className = { selected.value }> { selected.value } </div>
)
}
CSS for the above cases.
/*CSS file: style.css*/
.red { ...code... }
.green { ...code... }
.blue { ...code... }
I need to make a calendar with events and I decided to use react-big-calendar. But I need to make events of different colors. So each event will have some category and each category has corresponding color. How can I change the color of the event with react?
Result should look something like this
Sorry, I haven't read the documentation really well. It can be done with the help of eventPropGetter attribute. I've made it like this:
eventStyleGetter: function(event, start, end, isSelected) {
console.log(event);
var backgroundColor = '#' + event.hexColor;
var style = {
backgroundColor: backgroundColor,
borderRadius: '0px',
opacity: 0.8,
color: 'black',
border: '0px',
display: 'block'
};
return {
style: style
};
},
render: function () {
return (
<Layout active="plan" title="Planning">
<div className="content-app fixed-header">
<div className="app-body">
<div className="box">
<BigCalendar
events={this.events}
defaultDate={new Date()}
defaultView='week'
views={[]}
onSelectSlot={(this.slotSelected)}
onSelectEvent={(this.eventSelected)}
eventPropGetter={(this.eventStyleGetter)}
/>
</div>
</div>
</div>
</Layout>
);
}
Additional tip on how to style different kinds of events: In the myEvents array of event objects, I gave each object a boolean property isMine, then I defined:
<BigCalendar
// other props here
eventPropGetter={
(event, start, end, isSelected) => {
let newStyle = {
backgroundColor: "lightgrey",
color: 'black',
borderRadius: "0px",
border: "none"
};
if (event.isMine){
newStyle.backgroundColor = "lightgreen"
}
return {
className: "",
style: newStyle
};
}
}
/>
This solution is simple !
eventPropGetter={(event) => {
const backgroundColor = event.allday ? 'yellow' : 'blue';
return { style: { backgroundColor } }
}}
change the condition according to your need and it is done.
Siva Surya's solution is the fastest, and I have added the color property as well. Thanks...
import React, {useEffect, useLayoutEffect} from 'react';
import { Calendar, momentLocalizer,globalizeLocalizer } from 'react-big-calendar'
import moment from 'moment';
import { connect } from 'frontity';
import BackgroundWrapper from 'react-big-calendar/lib/BackgroundWrapper';
const MyCalendar = ({ actions, state, objetoBloque, formato }) => {
const localizer = momentLocalizer(moment);
const myEventsList = [
{
title: 'My Event',
start: '2022-06-21T13:45:00-05:00',
end: '2022-06-25T14:00:00-05:00',
// elcolor:'red'
colorEvento:'red'
},
{
title: 'Otro',
start: '2022-06-15T13:45:00-05:00',
end: '2022-06-23T14:00:00-05:00',
colorEvento:'green',
color:'white'
}
];
return(
<div>
<Calendar
// defaultDate = {defaultDate}
localizer={localizer}
events={myEventsList}
startAccessor="start"
endAccessor="end"
style={{ height: 500 }}
BackgroundWrapper = "red"
eventPropGetter={(myEventsList) => {
const backgroundColor = myEventsList.colorEvento ? myEventsList.colorEvento : 'blue';
const color = myEventsList.color ? myEventsList.color : 'blue';
return { style: { backgroundColor ,color} }
}}
/>
</div>
)
}
export default connect(MyCalendar);
Searching for how to change the border colour of an event also lead me here, and I couldn't find the answer anywhere else, but found that adding the following done the trick:
border: "black",
borderStyle: "solid"