Hover Material UI Icon and Text - css

I am working on a React JS Project. I was making something like a breadcrumb where there is a text and an icon. I am using material UI icon.
import UpdateIcon from "#material-ui/icons/Update";
import styles from " myfile.module.css "
<div className={styles.headItem}>
<UpdateIcon
className={classes.bread}
/>
<h1
className={styles.bread}
>
Bread Text
</h1>
</div>
Problem : I want to set the hover of this icon + text. But I have module file for normal html elements and material UI makestyles for materia UI items.
So I can't set the hover of whole. I tried setting the headItem class but it is not working

I would suggest to make some changes, the first one is that I prefer to import the css styles like this, because you can use the classes as regular strings
import "./styles.css";
Suppose that your styles.css have this class that is just applying the regular styles for your breadcrumb.
.head {
text-decoration: underline;
text-transform: uppercase;
}
Then you can reference this class in your file:
import React from "react";
import UpdateIcon from "#material-ui/icons/Update";
import "./styles.css";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
bread: {
"&:hover": {
color: "green"
}
}
});
export default function App() {
const classes = useStyles();
return (
<div className={`head ${classes.bread}`}>
<UpdateIcon />
<h1>Bread Text</h1>
</div>
);
}
Notice that we're referencing the css class that we have on the styles.css as a string, and then we just add the material ui class variable by using string interpolation. I have this sandbox where you can see the result:
https://codesandbox.io/s/still-pine-0v2jw

Related

How to test CSS properties defined inside a class with react testing library

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

Adding CSS to react Component

I'm trying to add css to my newly created component. When I use inline styles it works. But when I try to import css from another separate file it doesn't work. Below I mention my 2 files.
Layouts.css
.Content {
margin-top: 16px;
}
Layouts.js
import React from 'react';
import Auxillary from './../../hoc/Auxillary'
import classes from './Layouts.css'
const Layout = (props) => (
<Auxillary>
<div>
Toolbar,Sidebar,Backdrop
</div>
<main className={classes.Content}>
{props.children}
</main>
</Auxillary>
);
export default Layout;
Have you tried making className='Content'
If you want to use classes.Content you must name your Layout css file like this
Layouts.module.css

Style material-ui tooltip using #emotion/styled

Is it possible to style material-ui tooltips using the styled function from #emotion/styled?
import { Tooltip } from '#material-ui/core';
import styled from '#emotion/styled';
const MyTooltip = styled(Tooltip)`
// style the tooltip label
`
I tried using the global Mui classes etc. but did not succeed.
I know that an option is to use createMuiTheme and use <ThemeProvider> to apply it, but then the default theme is also applied to the children of the Tooltip component.
The difficulty with styling Tooltip in this manner is that Tooltip doesn't support a className prop (which is what the styled function injects) -- the className prop would simply be forwarded on to the element wrapped by the tooltip.
The solution is to intercept the props passed by styled and leverage the classes prop of Tooltip as shown below:
import React from "react";
import { StylesProvider } from "#material-ui/core/styles";
import Tooltip from "#material-ui/core/Tooltip";
import styled from "#emotion/styled";
const StyledTooltip = styled(({ className, ...other }) => (
<Tooltip classes={{ tooltip: className }} {...other} />
))`
font-size: 2em;
color: blue;
background-color: yellow;
`;
export default function App() {
return (
<StylesProvider injectFirst>
<StyledTooltip title="Test tooltip">
<span>Hover over me</span>
</StyledTooltip>
</StylesProvider>
);
}
Related GitHub issue: https://github.com/mui-org/material-ui/issues/11467

Style react-bootstrap button from css

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

React style/css/sass order

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.

Resources