Cannot override CSS Module class style with more specific one - javascript

I'm having a problem applying a CSS Module to a React Component (in an app created with 'create-react-app' and using webpack). I have an element that has a 'className' and an 'id' attribute. The 'className' style get applied, but when I attempt to 'override' it with a more specific 'id' style, it doesn't take. My Use Case is that the more-specific style override is in a separate file, but the problem exists with the two styles in the same CSS file.
Here's my component:
import React from 'react';
import styles from './styles.module.css'
class QuestionTag extends React.Component {
render() {
let c1 = "qumultiline";
return (
<>
<div className={`${styles[c1]}`} id={`${c1}`}>
Hello there
</div>
</>
);
}
}
export default QuestionTag;
This is how the element gets rendered:
<div class="styles_qumultiline__iXUv1" id="qumultiline">Hello there</div>
Here's styles.module.css:
.qumultiline {
background-color: #006699;
color: white;
}
div#qumultiline {
background-color: red;
color: red;
}
Is there something special I need to do to be able to override the 'className'?

Related

Problem in higher order components in react

I'm learning how to use higher order components. There I want to highlight some text. In my code I can highlight the whole line by using <div>. The problem is I only want to highlight a part of the text. So I tried <span>. But when I use span the whole highlighting part doesn't work. Since it doesn't give any error I can't understand what where the error comes from.
HighlightedText.js
import React, { Component } from 'react';
import UpdatedComponent from './Hoc';
class HighlightedText extends Component {
render() {
return <h1>Highlighted Text</h1>
}
}
export default UpdatedComponent(HighlightedText);
Hoc.js
const UpdatedComponent = OriginalComponent => {
class NewComponent extends React.Component {
render() {
return(props) =>(
<div style={{ background: 'Yellow', padding: 2 }}>
<OriginalComponent {...props}/>
</div>
)
}
}
return NewComponent;
}
export default UpdatedComponent;
Issues
Your HOC looks to be trying to return a functional component from the render method of a class-based component.
Props aren't spread correctly.
padding: 2 may not be valid, it should probably provide a unit, whatever you need
Solution
To fix the highlighting I believe you just need to specify a display: inline-block; CSS rule to the div. Spread this.props from the class-based component to the wrapped component.
const updatedComponent = (OriginalComponent) => {
class NewComponent extends React.Component {
render() {
return (
<div
style={{
background: "Yellow",
padding: "1rem", // <-- provide unit, 1rem ~ 16px
display: "inline-block" // <-- inline-block display
}}
>
<OriginalComponent {...this.props} />
</div>
);
}
}
return NewComponent;
};
If you want to highlight just a part of the text, it requires modifying the virtual DOM tree returned by the original component, since you can't just easily wrap it like in your example. You might want to use react-string-replace to achieve this.

Pass a stylesheet to a Lit-Element Web component

Is it possible to pass a stylesheet to a web component using lit-element?
I mean in a similiar way to the one used to set up the properties of the web component.
For example, I have this web component and I want to pass it, from the outside, a stylesheet that has to be pushed to the array returned inside "static get styles" after "SharedStyles".
class MyComponent extends LitElement {
static get properties() {
return {
name: { type: String }
};
}
static get styles () {
return [
super.styles,
SharedStyles,
css`
`
];
}
}
If I want to set the property "name" i do:
<my-component .name="${"Fred"}"></my-component>
Is there a way to pass a stylesheet to my-component?
Yes you can. But you need to export css file first.
step 1: create styles.js
import { css } from 'lit-element';
export const styleSheet = css`
:host{
// global css
}
.cssProp1{
// your properties
}
.cssProp2{
// your properties
}
`
Step 2: import css in to your component
import { styleSheet } from styles.js;
static get styles(){
return styleSheet;
}
Step 3: render html:
render(){
return html`
<div class="cssProp1"></div>
<div class="cssProp2"></div>
`
}
This will do the job

Styled-component object can't observe mobx changes

I would like an HOC generated by styled-components to re-render when one of its properties get changed. I'm using MobX for change detection.
This doesn't respond to changes, I think I understand why. The question is if there is a simple workaround to make it work.
const DemoComponent = observer(styled.div`
background-color: ${props => props.myObject.myObservableIsTrue ? 'red' :
'green'};
`);
It's hard to tell by this little snippet, but one of my guesses would be you are not injecting any store, so currently, no store is being connected to your component.
here's a simple example of how I used styled-components with mobx if it helps:
EDITED:
I've updated the code example.
Do you know the Container / Presentational pattern?
This was the missing link.
In order to keep your renders as little as possible
you need to separate your stateful component from each other.
Spread them across a Container component (aka Dumb Components)
This way you separate state concerns and render only the component with the changed state.
UPDATED:
https://codesandbox.io/s/zxx6o2pq3l
Sorry!!! A bit of a hack job, but attempt to bring your entire code inside the #inject("store") class:
import React from "react";
import { observer, inject } from "mobx-react";
import styled, { css } from "styled-components";
#inject("store")
#observer
export default class OtherComponent extends React.Component {
render() {
const MyWrapper = (store) => {
const Wrapper = styled.div`
border: 1px solid black;
display: flex;
justify-content: space-between;
color: ${({ color }) => color};
border: 2px solid ${({ color }) => color || "black"};
padding: 10px;
margin-bottom: 10px;
`;
return (
<Wrapper {...store}>
styled-component
<button onClick={store.changeColor}>change color</button>
</Wrapper>
);
}
const { store } = this.props;
return (
<div>
{
MyWrapper(store)
}
</div>
);
}
}
Mobx is actually read like this: #inject("store") #observer export default class...
So it really an extension of an extended component; only wrapped variables will apply!

SCSS effects not showing in React jsx component

I am trying to style a React component but I can't see the effect. There isn't any error, just there are no styles.
ButtonFilled.jsx (my React component)
import React from 'react';
import css from './button.scss';
class ButtonFilled extends React.Component {
render() {
return (
<div>
<button className = {css.buttonFilled}>
Learn More
</button>
</div>
);
}
}
export default ButtonFilled;
button.scss (my stylesheet)
#import "base.scss";
.buttonFilled{
font-size: 24;
color: '#6D0839';
font-weight: "bold";
background-color: '#FFFFFF';
padding-top: 17;
padding-bottom: 22;
padding-left: 15;
padding-right: 15;
width: 203;
border-radius: 5;
border-color: '#FFFFFF';
}
Why is this happening? Am I not specifying the class name correctly?
Try to import it this way.
import React from 'react';
import './button.scss';
class ButtonFilled extends React.Component {
render() {
return (
<div>
<button className = "buttonFilled">
Learn More
</button>
</div>
);
}
}
export default ButtonFilled;
Where is button.scss located ? If its the same folder with ButtonFilled.jsx i dont see anything wrong. Otherwise change the path to the correct one, kindly note the . in './button.scss' means current folder. Other way to use the css is just import the css like import'./button.scss'; (make sure its the right path). and on your jsx className="buttonFilled"

Can I set styles to document body from styled-components?

I want to know if there is a possibility to cast styles from styled-components to wrapping element, like <body> tag in the way that looks like this:
class SomePageWrapper = styled.div`
body {
font-size: 62.5%
}
`
No, but you can use the global inject function to set stuff on your body like this:
import { injectGlobal } from 'styled-components';
injectGlobal`
#font-face {
font-family: 'Operator Mono';
src: url('../fonts/Operator-Mono.ttf');
}
body {
margin: 0;
}
`;
The example is from here: https://www.styled-components.com/docs/api#injectglobal
As it turns out - you can't set styled components to outer elements. This violates the philosophy of encapsulation - a benefit from styled-components.
So the way to do this would be to add a new class to body element called classList via JS in the parent component with componentDidMount() and remove it with componentWillUnmount().
For v4 styled-components, use createGlobalStyle .
import { createGlobalStyle } from 'styled-components'
const GlobalStyle = createGlobalStyle`
body {
color: ${props => (props.whiteColor ? 'white' : 'black')};
}
`
// later in your app
<React.Fragment>
<GlobalStyle whiteColor />
<Navigation /> {/* example of other top-level stuff */}
</React.Fragment>
I think you can't do that.
class SomePageWrapper = styled.body`
font-size: 62.5%
`
So,when you put <SomePageWrapper/> in the render,it turns to be <body></body>.Then you need to put it in the root part,to replace <body>.
But how do you replace the <body> you have in index.html.When you can't replace it,you will end up two <body> in browser,or something weird will happen.
Just simply use css file for

Categories

Resources