I have two components
/components/main/index.jsx
/components/main/main.scss
My main component is as follows
import css from './main.module.scss'
import React from 'react'
const Main = () => {
return <div className={css.main}>Main Component</div>
}
export default Main
and in my main.scss I would like to do the following
.main {
color: theme('colors.black');
}
or if possible even use the #apply keyword
.main {
#apply bg-black-200;
}
but I have not been able to figure out a way to do this?
Related
I am trying to test CSS properties that i have defined inside a class in css, wing the react testing library. However I am unable to do so.
Adding the simplified snippets.
import React from "react";
import { render, screen } from "#testing-library/react";
import '#testing-library/jest-dom/extend-expect';
import styled from "styled-components";
const Title = styled.span`
display: none;
background: red;
`
test("testRender", () => {
render(
<div>
<Title>Test</Title>
</div>
)
const spanElement = screen.getByText("Test");
const elementStyle = window.getComputedStyle(spanElement);
expect(elementStyle.display).toBe('none');
});
The test fails at the expect statement. I have tried refactoring to traditional css, there also the test fails. In both cases, I have tested it manually and the styles are taking effect.
I also understand that we should not directly test CSS properties, but I have tried testing the visibility with toBeVisible(), but that only works if the display: none is directly entered as a style, and not as part of a class.
This should be a very simple thing, that works out of the box, but I have been at it for some time now, without any luck.
Any help is appreciated.
I agree with #ourmaninamsterdam answer.
In addition, for checking appearance or disappearance of any element, you can also use .not.toBeInTheDocument like so:
expect(screen.queryByText("Test")).not.toBeInTheDocument();
NOTE: You must use queryByText instead of getByText in this case since queryByText wont throw an error if it doesn't find the element (it will return null).
Official docs Reference - https://testing-library.com/docs/guide-disappearance#nottobeinthedocument
You can use expect(screen.getByText("Test")).not.toBeVisible();
import React from "react";
import { render, screen } from "#testing-library/react";
import "#testing-library/jest-dom/extend-expect";
import styled from "styled-components";
it("does display", () => {
const Title = styled.span`
display: block;
background: red;
`;
render(
<div>
<Title>Test</Title>
</div>
);
expect(screen.getByText("Test")).toBeVisible();
});
it("doesn't display", () => {
const Title = styled.span`
display: none;
background: red;
`;
render(
<div>
<Title>Test</Title>
</div>
);
expect(screen.getByText("Test")).not.toBeVisible();
});
...see the sandbox: https://codesandbox.io/s/blazing-river-l6rn6?file=/App.test.js
The 'Using ClassNames' section of react-select docs states that using the className and classNamePrefix props
ensures compatibility with styled components, CSS modules and
other libraries.
In this CodeSandbox, with CSS modules and node-sass, it seems to work. However, if I replicate the following code on my local machine in a create-react-app, it doesn't work. My CRA uses the Typescript template. Is that the problem? Everything else is just the same.
Select.module.scss
.select {
outline: 1px solid red;
.select__control {
background-color: salmon;
}
}
Select.tsx
import React from 'react';
import RS from 'react-select';
import style from './Select.module.scss';
const options = [
{label: "hi", value: "hi"}
]
function Select(props: any) {
return (
<RS
options={options}
className={style.select}
classNamePrefix={style.select}
/>
)
}
export default Select;
App.tsx
import React from 'react';
import Select from './Select';
function App() {
return (
<div className="App">
<Select />
</div>
);
}
export default App;
I could make it work here by doing:
Select.module.scss
.select {
outline: 1px solid red;
[class$="-control"] {
background-color: salmon;
}
}
Select.tsx
import React from 'react';
import RS from 'react-select';
import style from './Select.module.scss';
const options = [
{label: "hi", value: "hi"}
]
function Select(props: any) {
return (
<RS
options={options}
className={style.select}
/>
)
}
export default Select;
Basically, I removed classNamePrefix from react-select component and changed .select__control to [class$="-control"], which matches all classes ending with -control.
The problem here was because css loader was adding a hash in my classnames eg {select: "styles_select__SQ71h", select__control: "styles_select__control__xcj2p"}.
I am fairly new to React and JavaScript in general.
I am using Button from react-bootstrap from https://react-bootstrap.github.io/components/buttons/ but I want to style the Button on top of it in my React app from my css file but it does not seem to apply.
my Home.js file looks like
import React from "react";
import '../App.css'; // Reflects the directory structure
export default function Home() {
return (
<div>
<h2>Home</h2>
<Button variant="light" className="formButtons">
</div>
)
}
My App.css file looks like
.formButtons {
margin: 10;
overflow-wrap: break-word;
color: red;
}
I can tell it does not apply since the text color isn't red.
Thanks in advance!
First of all you need to import the Button element from react-bootstrap. You can write something like this:
import Button from 'react-bootstrap/Button'
After that, you can remove the className attribute because React Bootstrap builds the component classNames in a consistent way that you can rely on. You can base your styles on the variant attribute, so try something like this:
Home.js
import React from "react";
import Button from 'react-bootstrap/Button'
import '../App.css'; // Reflects the directory structure
export default function Home() {
return (
<div>
<h2>Home</h2>
<Button variant="light">TEXT</Button>
</div>
)
}
App.css
.btn-light {
margin: 10;
overflow-wrap: break-word;
color: red;
}
I'm trying to reference a color variable from my main.scss file within my component but not sure what the correct syntax is. Right now it works by hard coding the color hex value.
I can make it work by adding an external stylsheet, and referencing the theme color that way however don't want to create an extra file but rather use internal styling.
Here's main.scs:
$theme-colors: (
'primary': #00a677,
);
Here's the component:
import React from 'react';
const box = {
color: '#9D2235',
};
const Box = () => {
return(
<div style={box}><h1>I'm A Box!</h1></div>
)
}
export default Box;
Any idea how I can do this?
What you can do is, put a class on the box component
In main.scss
$primary: #00a677
.box {
color: $primary
}
In your component
import React from 'react';
const Box = () => {
return(
<div className='box'><h1>I'm A Box!</h1></div>
)
}
export default Box;
I have my "App-component" and a "B-component" that gets rendered inside my app component. Each has its own style.
But when it gets compiled, my ComponentB.css is put before my app.css, making the ComponentB styles being overwritten by my app styles.
Why is this happening??
APP
import React, { Component } from 'react';
import ComponentB from './components/ComponentB';
import './styles/app.css';
class App extends Component {
render() {
return (
<div className="App">
<ComponentB />
</div>
);
}
}
export default App;
COMPONENT B
import React, { Component } from 'react';
import './styles/ComponentB.css';
class ComponentB extends Component {
render() {
return (
<div>
<h1>Hello from ComponentB</h1>
</div>
);
}
}
export default ComponentB;
The way you do it results in a styles conflicts(one style overwriting another style), because after React compiles your code you are still using the same selectors for the same classes.
If you want to use different css files for different components while using the same class names, you should use CSS modules.
This will make your CSS class names scoped locally by default.