Apply separate CSS to one of the multiple instances of same React custom component - css

I have two custom components called Grid and FieldValue and I use the FieldValue component multiple times on a particular page. I am using a class name called .black for all the FieldValue components. Now, I want to use a different class name called .blue-pointer where the data in FieldValue says view2. please help me understand how to do it.
Components on the page look like below
<Grid>
<FieldValue data={'view1'}/>
<FieldValue data={'view2'}/>
<FieldValue data={'view3'}/>
</Grid>
And the FieldValue is defined as below,
class FieldValue extends React.Component<>{
render(){
<div className="black">
{'testView'}
</div>
}
}
And the CSS is defined as below
.black{
color:#4d546d;
}
.blue-pointer {
color: #0070d2;
cursor: pointer;
}

Use props from your component :
class FieldValue extends React.Component{
render() {
return (
<div className={this.props.data === 'view2' ? 'blue-pointer' : 'black'}>
{'testView'}
</div>
);
}
}

You can define className as a prop, and give it a default value of 'black'.
class FieldValue extends React.Component<> {
static defaultProps = {
className: 'black'
}
render() {
const { className } = this.props
<div className={className}>
{'testView'}
</div>}
}
For the default case, you don't need to change anything:
<FieldValue data={'view1'} /> // Still uses the `black` style.
When you want to change the class name, use:
<FieldValue data={'view2'} className='blue-pointer' />

Related

How to style dynamically in lit?

Good time
How to style dynamically in lit?
My main goal is to change the color of an element according to the user's input in the input element.
My code screen shoot
You can't use ‍${} in lit css tag function!
But you can select element and then change style
import {html, css, LitElement} from 'lit';
import {customElement, property, query} from 'lit/decorators.js';
#customElement('dynamic-style')
export class DynamicStyle extends LitElement {
static styles = css`
label {
color: #023047;
}
`;
#property()
color: string;
#query('input') input: HTMLSelectElement | undefined;
#query('label') label: HTMLSelectElement | undefined;
render() {
return html`
<label
>Enter HEX color
<input class="color-input" placeholder="#023047" />
</label>
`;
}
firstUpdated() {
this.input.addEventListener('input', () => {
this.label.style.color = this.input.value;
});
}
}
lit playground
Also read:
Dynamic classes and styles | Lit Doc
Use CSS variable in Lit
Simply! It is good to search more and then ask

extending react style prop with typescript

What is the best way to extend the style prop in react to accept css variables as keys?
<button style={{ "--color": "red", ...props.style }} />
You can do the following:
render() {
var style = { "--color": "red", ...props.style } as React.CSSProperties;
return (<button style={style} />);
}
More in React.CSSProperties type definition: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8871b1e8938a1ed698ec8a88c77ee169294e45d4/types/react/index.d.ts#L974-L983
You'll need to add to the CSSProperties interface, which can be done pretty easily like so
declare module "react" {
interface CSSProperties {
/**
* Add your custom properties here
*/
"--x": string | number;
}
}

Passing css styles from React Parent component to its child component

I have React parent component A which has its own scss file a-style.scss. Component B is child of A. A is passing styleInfo object as props which is applied on B.
My question is - is there any way we can define styleObj in a-style.scss instead of defining it inline. I want all styling related info should be in external scss file.
Component A
import "./a-style.scss";
import B from "./B.js";
class A extends Component {
constructor(props) {
super(props);
}
const styleObj = {
backgroundColor: "#F9F9F9",
borderRadius: '2px',
color: "#686868",
};
render() {
return (<B styleInfo={this.styleObj}></B>);
}
}
Component B
class B extends Component {
constructor(props) {
super(props);
}
render() {
return (<div style={this.props.styleInfo}></div>);
}
}
The standard way is to define CSS properties based on class in your scss/css. And then pass className from props in your React component:
class A extends Component {
theme = "themeA";
render() {
return (<B styleInfo={this.theme} />);
}
}
class B extends Component {
styleClass = ["B"];
render() {
const className = styleClass.push(this.props.styleInfo).join(' ');
return (<div className={className} />);
}
}
.themeA {
background-color: #F9F9F9;
border-radius: 2px;
color: #686868;
}
.B {
/* Some style for B component */
}
Why not just import that one file directly into B.js?
Is there any benefit of having it go through a parent, seems like necessary routing to me!
If you do need this, then I would just keep it in JS, as this is what JS is good at, or at least, have JS just do the className switching and, again, just have one css file that is a main style lookup hash!
Best of luck!

FlowType React Context

Is there a way to make React Context type-safe with flow type?
For example :
Button.contextTypes = {
color: React.PropTypes.string
};
Unfortunately, it is inherently not possible because Context is not known at compile time (so I was told).
A bit of a workaround I use is pulling the the context from the consumer at the parent level, and then calling proptypes at the child...
Parent
//parent
class Parent extends component {
render(){
return (
<Consumer>{(context)=>{
const { color } = context
return(
<div>
<Button color={color} />
</div>
)}}</Consumer>
}
Child
//Button
...
Button.contextTypes = {
color: React.PropTypes.string
};
...

Finding the width of an element when using React?

At which point in a React components life cycle can I get the components css properties which are set in a css file?
I've tried it in the render method and the componentDidMount method and neither assigned the css properties to the component.
export default class HomeArtist extends React.Component {
constructor(props){
super(props);
}
componentDidMount(){
let ImageStore = document.getElementsByClassName('home-artist-display');
console.log("ComponentDidMount: ", ImageStore);
}
render(){
var ImageStyle = {
backgroundImage: "url("+this.props.info.image+")"
};
return (
<div className="home-artist-display" style={ImageStyle}>
<Link to={"artist/" + this.props.info.id}>
<h3 className="home-artist-name">{this.props.info.name}</h3>
</Link>
</div>
)
}
}
I wrote a React library that exposes a size object (with width and height props) to components.
For your use case you could use it like so:
import SizeMe from 'react-sizeme'; // import me!
class HomeArtist extends React.Component {
...
render(){
// Size gets passed in as props!
const { width, height } = this.props.size;
var ImageStyle = {
backgroundImage: "url("+this.props.info.image+")"
};
return (
<div className="home-artist-display" style={ImageStyle}>
<Link to={"artist/" + this.props.info.id}>
<h3 className="home-artist-name">{this.props.info.name}</h3>
</Link>
</div>
)
}
}
// wrap your component export!
export default SizeMe()(HomeArtist);
--
You can find out full details at https://github.com/ctrlplusb/react-sizeme

Resources