Override material-ui button styles with styled-components - html

I am using a material-ui button and trying to override the border-radius (i.e, make it 0) through styled-components. However, it's not working.
Code:
import React from "react";
import styled from "styled-components";
import { Button } from "#material-ui/core";
const StyledButton = styled(Button)`
background-color: #d29d12;
border-radius: 0;
`;
export default function App() {
return <StyledButton>Hello</StyledButton>;
}

By default, Material-UI injects it styles at the end of the <head> element. This means that its styles will come after styles generated by styled-components and thus the Material-UI styles will win over the styled-components styles when CSS specificity is the same.
You can use the StylesProvider component with the injectFirst property to move the Material-UI styles to the beginning of the <head> and then the styled-components styles will come after it and win.
import React from "react";
import styled from "styled-components";
import Button from "#material-ui/core/Button";
import { StylesProvider } from "#material-ui/core/styles";
const StyledButton = styled(Button)`
background-color: red;
border-radius: 0;
`;
export default function App() {
return (
<StylesProvider injectFirst>
<div className="App">
<StyledButton>Hello</StyledButton>
</div>
</StylesProvider>
);
}
Related answers:
Media Queries in Material-UI Using Styled-Components

Use styled-components higher specificity syntax:
https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity
const StyledButton = styled(Button)`
&& {
background-color: red;
border-radius: 0;
}
`;

const StyledButton = styled(Button)({
'&&&': {
backgroundColor: red,
borderRadius: 0
}
)}

By adding className to StyledButton, it can override MUI button style,
<StyledButton className={'myclassName'}>Hello</styledButton>
const StyledButton = styled(Button)`
&.myclassName {
background-color: red,
border-radius: 0
}
`;

You can override the default border-radius of button by applying !important to your styled component.
const StyledButton = styled(Button)`
borderRadius: 0px !important;
`;

Related

Making multiple react icons changing different color on hover using JSX

I'm trying to make different icons in the footer, with different brands. I want them to change color when I'm hovering over them. I've created a CSS class with the hover pseudo-class, but I want to make a sort of parameter in my JSX file which tells the class that a certain color should be applied to a certain icon
This Is my CSS class:
.icon-background {
color: rgb(49, 45, 44, 0.8);
}
.icon-background:focus,
.icon-background:hover {
background-color: var(--color);
transition-duration: 0.2s;
padding: 2.5px;
}
An easy way to accomplish this would be through utility css classes. For instance, you could insert an icon in the jsx file like this:
<div className="blue default_icon">ICON</div>
With corresponding css:
.blue:hover,
.blue:focus {
background-color: #0000ff;
}
.default_icon {
color: rgb(49, 45, 44, 0.8);
}
.default_icon:hover {
transition-duration: 0.2s;
padding: 2.5px;
}
A better way you could do this is with React state. Basically, create an icon component and pass a color as a prop. This will be much less css and will be more scalable:
import { useState } from 'react';
const Icon = (props) => {
const hoverColor = props.hoverColor;
const [isHover, setIsHover] = useState(false);
const handleMouseEnter = () => {
setIsHover(true);
};
const handleMouseLeave = () => {
setIsHover(false);
};
const hoverStyle = {
backgroundColor: isHover ? hoverColor : "defaultColor",
};
return (
<div
style={hoverStyle}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
ICON
</div>
);
};
export default Icon;
You can then use the icon anywhere in your project like so:
<Icon hoverColor={"#0000ff"} /> // This would turn blue on hover

How can I style CSS parts using :root?

I have a button web component built that I am trying to style using CSS parts. In my web component below you can see that the button is colored tomato because I have used exportparts and then in my consumer CSS I have styled it using btn-comp::part(btn) { ... }.
However, I would prefer to not have to style it using btn-comp, instead I would like to just use :root to style it like this author does.
For example I should be able to do this:
:root::part(btn) { /* my styles here */ }
But that does not work, it only works when I use the component name. How can I style my CSS parts using :root?
const template = document.createElement('template');
template.innerHTML = `<button part="btn">I should be a green button</button>`;
class BtnComp extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
const button = this.shadowRoot.querySelector("button");
button.addEventListener("click", () => alert('Clicked'));
}
}
window.customElements.define('btn-comp', BtnComp);
:root::part(btn) {
background-color: green !important; /* I want this color to be applied! */
}
btn-comp::part(btn) {
background-color: tomato;
color: white;
padding: 1rem 2rem;
border: 0;
cursor: pointer;
}
<btn-comp exportparts="btn" />

Modify default classes of DataGrid material UI

In "DataGrid" material UI I am trying to modify the css properties like font weight, overflow of header.
Here is my jsx code
import React, {useState, useEffect} from 'react';
import {DataGrid, GridToolbarContainer, GridToolbarExport} from '#material- ui/data-grid';
import {makeStyles} from '#material-ui/styles';
const useStyles = makeStyles({
root: {
'& .super-app-theme--header': {
backgroundColor: 'white'
}
},
'.MuiDataGrid-root .MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold',
overFlow: 'visible'
}
});
function CustomToolbar() {
return (
<GridToolbarContainer>
<GridToolbarExport />
</GridToolbarContainer>
);
}
export default function DataTable(props) {
const classes = useStyles();
return (
<div style={{height: '700px', width: '100%'}} className={classes.root}>
<DataGrid
rows={props.records}
columns={props.headers}
pageSize={12}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
);
}
I also tried to add properties like font weight and overflow in super-app-theme--header but it didn't work. Some properties like background colour are working but the properties which are already there in MuiDataGrid-columnHeaderTitle are not getting overridden.
I created a css file and in that overridden the properties with same class name and imported that css file
Here is the css code
.MuiDataGrid-columnHeaderTitle { font-weight: bold !important; overflow: visible !important; }
Using MUI V5+ and building on Pravin's answer you can define the header style this way:
<Datagrid
sx={{
'.MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold !important',
overflow: 'visible !important'
}
}}
/>

Tie css file to a component in ReactJs like Angular 2+

In Angular 2+, we have #component directive where we can pass element-selector, css file, html template file,.. We do it by the following snippet.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
In Angular 2+, CSS styles are local to that HomeComponent element alone. So, I can add different styles to different components without affecting each other.
AngularLayout.html
<section>
<app-home></app-home>
<app-about></app-about>
<app-contact></app-contact>
</section>
For ReactJs, I tried to add styles to different components like,
LayoutHome.js
import React, { Component } from 'react';
import './LayoutHome.css';
class LayoutHome extends Component {
render() { return <span>home</span>; }
}
export default LayoutHome;
LayoutAbout.js
import React, { Component } from 'react';
import './LayoutAbout.css';
class LayoutAbout extends Component {
render() { return <span>about</span>; }
}
export default LayoutAbout;
ReactLayoutApp.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import LayoutHome from './components/LayoutHome';
import LayoutAbout from './components/LayoutAbout';
class App extends Component {
render() {
return (
<section>
<LayoutHome/>
<LayoutAbout />
</section>
);
}
}
export default App;
For example, let './LayoutAbout.css' be having the following
span {
color: blue;
}
'./LayoutHome.css' be having the following
span {
color: red;
}
CSS styles are getting collapsed with each other.
What could be the cleaner way of tagging CSS file to a local component in ReactJs?
You should probably just add some more CSS selectors.
For instance, your LayoutAbout.css would look like
.about span {
color: red;
}
And your LayoutHome.css
.home span {
color: blue;
}
One way to solve this problem is to be more specific in your css to avoid conflicts by giving a class or id to an outer element within your component and nesting any needed styles for that component under them like so:
LayoutAbout.js
import React, { Component } from 'react';
import './LayoutAbout.css';
class LayoutAbout extends Component {
render() {
return (
<span id="about">
about
<span>nested content</span>
</span>
);
}
}
export default LayoutAbout;
LayoutAbout.css
#about {
color: blue;
}
#about span {
color: dodgerblue;
}
Another alternative would be to take advantage of the shadow dom which will encapsulate your styles within your custom component. This ensures that the css in your component won't affect anything outside and that you'd have to be explicit to affect any elements inside the shadow dom of your custom component.

styled components, with gatsby-link anchor tag css coloring

I am trying to style a <Link/> component from gatsby-link package using styled-components package Normally I just create a const give it a Name set it equal to styled.a for example and write my css. However when I create a const for <Link/> I get a Duplicate declaration "Link" error. How do I style a <Link> component with styled-components.
Here is my code Below
import React from 'react';
import Link from 'gatsby-link';
import styled from "styled-components";
const Header = styled.div`
margin: 3rem auto;
max-width: 600px;
background:red;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;
const Title = styled.h1`
color: aqua;
`;
const Link = styled.a`
color: aqua;
`;
export default () => (
<Header>
<Title>
<Link to="/">
Gatsby
</Link>
</Title>
</Header>
);
You should be able to do something like:
import { Link } from 'gatsby';
const StyledLink = styled(props => <Link {...props} />)`
color: aqua;
`;
// ...
<StyledLink to="/">
Gatsby
</StyledLink>
Outdated version (gatsby v1, styled-components v3):
import Link from 'gatsby-link';
const StyledLink = styled(Link)`
color: aqua;
`;
// ...
<StyledLink to="/">
Gatsby
</StyledLink>
Rename the Link import.
import { Link as GatsbyLink } from "gatsby";
If you name your component Link you might encounter naming collisions because that name is so ubiquitous among different frameworks. The error you describe points out that you have more than one component with the same name.
Name your components explicitly (adapted from #Fabian Schultz's answer):
import { Link as GatsbyLink } from "gatsby";
const StyledLink = styled(GatsbyLink)`
color: aqua;
`;
// ...
<StyledLink to="/">
Gatsby
</StyledLink>