Using Material-ui theme in styled component - css

Need to use theme spacing value in a styled component like below with no success.
When I first created it, style was applied to button. But now, no style is applied!
You can see it here: sandbox.
import React from "react";
import styled, { ThemeProvider } from "styled-components";
import {
createMuiTheme,
ThemeProvider as MuiThemeProvider,
darken
} from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
const customTheme = createMuiTheme({
palette: {
primary: {
main: "#6772e5"
}
},
spacing: 8
});
const StyledButton = styled(Button)`
${({ theme }) => `
background-color: ${theme.palette.primary.main};
color: #fff;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
padding-left: 20px;
padding-right: ${theme.spacing(2)};
font-size: 13px;
&:hover {
background-color: ${darken(theme.palette.primary.main, 0.2)};
}
`}
`;
export default function App() {
return (
<MuiThemeProvider theme={customTheme}>
<ThemeProvider theme={customTheme}>
<StyledButton>Customized</StyledButton>
</ThemeProvider>
</MuiThemeProvider>
);
}

Your styled-component styles is overridden by the default JSS styles. By default, JSS styles is injected at the bottom of the <head> (higher CSS specificity). You can tell MUI to override JSS styles by putting your component tree inside <StylesProvider injectFirst>. See controlling priority.
// tell MUI to inject JSS style first, so styled-component can override it
<StylesProvider injectFirst>
<MuiThemeProvider theme={customTheme}>
<ThemeProvider theme={customTheme}>
<StyledButton>Customized</StyledButton>
</ThemeProvider>
</MuiThemeProvider>
</StylesProvider>

Related

How to override css properties of Material UI components

I am working on project in which I have to use Material UI, just for simplicity, consider I am having a simple functional component in which I am having 2 Material UI components Button and Text Field
import React from 'react';
import { Button, TextField } from '#material-ui/core';
function RenderComponent(){
return(
<>
<Button variant="contained">Contained</Button>
<TextField id="outlined-basic" label="Outlined" variant="outlined" />
</>
)
}
export default RenderComponent
Can anyone please tell me how to override the css properties of these 2 Material UI components.
Thankyou 🙏
There are several ways to do this, you can directly override the built-in CSS class of an MUI component using the class name in your imported CSS file, for example in if you want to change the Button component's style, you can do this by applying your required CSS properties to .MuiButton-root class on your "CSS" file. Like bellow.
.MuiButton-root{
color: white;
height: 20px;
padding: 10px;
}
You can also use the available props of a component, you can easily find them in their individual documentation page of mui site.
Again you can use makeStyles or styled to style your component.
Here is an example to use makeStyles in your Button component.
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { Button, TextField } from '#material-ui/core';
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
function RenderComponent(){
const classes = useStyles();
return(
<>
<Button className={classes.root} variant="contained">Contained</Button>
<TextField id="outlined-basic" label="Outlined" variant="outlined" />
</>
)
}
export default RenderComponent
You can find more about styles here.
Give them id's/classes and write your custom CSS for them. If it doesn't override the standard Material-UI styles, add the keyword !important. If you are using create-react-app, you can import CSS right to the file like this:
import "./styles.css";
If this doesn't help, that means Material-UI uses inline styles for the elements. In this case, you would have to write your CSS right into your components' attributes: like this. If it doesn't override standard styles, use !important again.

antd overwriting styled components

I have a react project (which was not bootstrapped from CRA) which uses antd and styled components.
EDIT:
Components rendered 'under' a route do not apply styles from styled components.
I initially thought that antd, the ui framework I am using was overwriting the styled components styles but I discovered something interesting; If I add a styled component to the header component it works just fine but if I add a styled component to any component rendered on a route, the styles are not applied.
My main App component has the following structure:
import React, { Fragment } from 'react';
import { ConnectedRouter } from 'connected-react-router';
import { history } from '../store/config';
...
const App = () => {
return (
<ConnectedRouter history={history}>
<Fragment>
<Header />
<Routes />
</Fragment>
</ConnectedRouter>
);
};
For completeness, the routes component looks like this:
import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import HomePage from '../components/pages/HomePage';
import EditorPage from '../components/pages/EditorPage';
export const Routes = () => {
return (
<Switch>
<Route exact path="/" component={withRouter(HomePage)} />
<Route exact path="/editor" component={withRouter(EditorPage)} />
</Switch>
);
};
export default Routes;
The example below is code I've added to the HomePage component.
package versions in use:
"antd": "^4.3.4",
"history": "^4.10.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5",
"styled-components": "^5.1.1",
END EDIT.
For some reason the styles from styled components are overwritten by antd unless I place the styles inline.
For example, in the following code snippet the border does not get applied. A super basic example but it demo's the point.
const HomePage = () => {
render(
<Container>
Hello
</Container>
);
};
const Container = styled.div`
border: 1px solid red;
`;
It renders like this:
Looking in dev tools the style doesn't even show up.
But if I add the style inline like this:
<Container style={{ border: '1px solid red' }}>
Boom! red border:
What am I missing??
Of course any help or suggestions is greatly appreciated!
I read the docs of styled-components and I think this is the problem.You should use style before render.
const Button = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0.5em 1em;
padding: 0.25em 1em;
${props => props.primary && css`
background: palevioletred;
color: white;
`}
`;
const Container = styled.div`
text-align: center;
`
render(
<Container>
<Button>Normal Button</Button>
<Button primary>Primary Button</Button>
</Container>
);
Look at the above example that appears on the page.
You can write styled like:
const Container = styled.div`
&& {
border: 1px solid red;
}
`

input[type="search"]::-webkit-search-decoration:hover {cursor: pointer;} in styled-components

like the title says, how do I use input[type="search"]::-webkit-search-decoration:hover {cursor: pointer;} in a styled component?...
the code below isn't working or being recognized.
const SomeInput = styled.input`
border-radius: 8px;
input[type="search"]::-webkit-search-decoration:hover,
input[type="search"]::-webkit-search-cancel-button:hover {
cursor:pointer;
}
`;
Trying to implement from here as a styled component: display pointer on hover close icon in search textbox
I got this working by using the ampersand character inside the styled component and added type="search" in the JSX.
import React from "react";
import "./styles.css";
import styled from "styled-components";
export default function App() {
const SomeInput = styled.input`
border-radius: 8px;
&::-webkit-search-decoration:hover,
&::-webkit-search-cancel-button:hover {
cursor: pointer;
}
`;
return (
<div className="App">
<SomeInput type="search" />
</div>
);
}
CodeSandbox

Is there a way to style the border color and text color of <TextField/> in Material-UI without using makeStyles

Is it possible to style Material-UI without using the makeStyles feature, for example, css? Just trying to understand how Material-UI style works.
The red style on the bottom is the style I'm trying to achieve with simple css here.
Below is an example of how to customize the various colors in an outlined select using simple CSS.
styles.css
.customSelect {
width: 200px;
}
.customSelect .MuiInputLabel-root {
color: red;
}
.customSelect .MuiInputBase-input {
color: green;
}
.customSelect .MuiOutlinedInput-notchedOutline {
border-color: red;
}
.customSelect:hover .MuiOutlinedInput-notchedOutline {
border-color: orange;
}
.customSelect
.MuiOutlinedInput-root.Mui-focused
.MuiOutlinedInput-notchedOutline {
border-color: purple;
}
.customSelectMenu .MuiMenuItem-root {
color: blue;
}
App.js
import React from "react";
import "./styles.css";
import TextField from "#material-ui/core/TextField";
import MenuItem from "#material-ui/core/MenuItem";
export default function App() {
const [value, setValue] = React.useState("");
return (
<TextField
className="customSelect"
label="Sale Type"
required
select
value={value}
onChange={event => setValue(event.target.value)}
variant="outlined"
SelectProps={{ MenuProps: { className: "customSelectMenu" } }}
>
<MenuItem value={1}>Sale Type 1</MenuItem>
<MenuItem value={2}>Sale Type 2</MenuItem>
</TextField>
);
}
Related answers:
Change border color on Material-UI TextField
Global outlined override
Change outline for OutlinedInput with React material-ui

Styled component does not inherit styles when using "as" attribute

I'm using styled-system with styled components and have a basic case like this:
const buttonFont = {
fontFamily: "Chilanka"
};
// style a boilerplate for text
const Text = styled.div`
${typography}
${color}
`;
// button blueprint
const Button = ({ children, ...rest }) => {
return (
<Text as="button" {...buttonFont } {...rest}>
{children}
</Text>
);
};
// styled button using button
const StyledButton = styled(Button)`
color: white;
background-color: gray;
padding: 10px 20px;
border: 2px solid black;
`;
// When using "as" this component does not includes buttonFont styles
const StyledLabel = styled(StyledButton).attrs({
as: "label"
})``;
I want to create a StyledLabel which will inherit all styles from StyledButton, but change tag to label. But StyledLabel does not get the buttonFont styles when using "as" attribute.
Please see live example here: demo
I'm not sure what your end goal is, but these 2 examples worked in terms of inheritance. However, they might not help with your plan for composition:
import React from "react";
import styled, {css} from "styled-components";
import { typography, color } from "styled-system";
import ReactDOM from "react-dom";
import "./styles.css";
const buttonFont = {
fontFamily: "Chilanka"
};
const Text = styled.div`
${typography}
${color}
margin: 24px;
`;
const StyledButton = styled(Text)`
color: white;
background-color: gray;
padding: 10px 20px;
border: 2px solid black;
`;
const StyledLabel = styled(StyledButton)`
color: yellow;
`;
const __Text = styled.div`
${typography(buttonFont)}
${color}
margin: 24px;
`;
const __StyledButton = styled(__Text)`
color: white;
background-color: gray;
padding: 10px 20px;
border: 2px solid black;
`;
const __StyledLabel = styled(__StyledButton)`
color: yellow;
`;
function App() {
return (
<div className="App">
<StyledButton as="button" {...buttonFont}>styled button</StyledButton>
<StyledLabel as="label" {...buttonFont}>Does inherit styled font with "as"</StyledLabel>
<br />
<br />
<br />
<__StyledButton as="button">styled button</__StyledButton>
<__StyledLabel as="label">Does inherit styled font with "as"</__StyledLabel>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Resources