React css renders correctly only on IDE refresh - css

I have some unexpected CSS behaviour that I don't understand - can anyone help me understand why it's happening, and help me get my CSS imports right?
I have a react app that uses a single component, that imports a stylesheet from a separate file brand.js. The component has an <Avatar className={classes.avatarTM}>; brand.js defines that class as having a backgroundColour of Dark Blue, which is what I'm expecting.
But when I load the app in Chrome, that avatar loads grey, not blue. Inspecting the element shows that two styles apply: .makeStyles-avatarTM-11 with the expected backgroundColor of primary.dark, and .MUIAvatar-colorDefault with backgroundColor #bdbdbd. colorDefault takes precedence on backgroundColor over avatarTM-11, so I get a grey avatar. This is not good.
If I then edit the // deleteme comment in brand.js in Visual Studio and save the file, React auto-refreshes the avatar in Chrome in Blue. avatarTM-11 is now taking precedence over colorDefault.
If I then reload the page in Chrome, it reloads as default grey.
But the bit that really screws up my attempts at bugfixing is that if I create a new file brand2.js, and copy/paste the exact content of brand.js into that new file, then modify the imports in App2.js and testComponent.js to import brand2 instead of brand, it works just fine. avatarTM-11 now takes precedence over default no matter what loads the page, and I get a blue avatar.
So just use brand2 instead of brand, right? Right. So I delete brand.js.... and the problem comes back.
What exactly is happening here? How do I get my defined avatarTM style to always take precedence, no matter what is loading the page or what the stylesheet is called? Why should the presence or absence of a file that is not being used by the app affect anything?
app2.js:
import React from 'react';
import { ThemeProvider } from '#material-ui/core/styles';
import { theme } from './components/Brand';
import TestComponent from './components/testComponent';
export default function App() {
return (
<React.Fragment>
<ThemeProvider theme={theme}>
<TestComponent />
</ThemeProvider>
</React.Fragment>
);
}
testComponent.js:
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Card from '#material-ui/core/Card';
import CardHeader from '#material-ui/core/CardHeader';
import { useStyles } from './Brand';
export default function TestComponent() {
const classes = useStyles();
return (
<Card className={classes.card} variant="outlined">
<CardHeader
avatar={
<Avatar aria-label="testComponent" className={classes.avatarTM}>
t
</Avatar>
}
title="testComponent"
/>
</Card>
)}
brand.js:
import { createMuiTheme } from '#material-ui/core/styles';
import { makeStyles } from '#material-ui/core/styles';
const theme = createMuiTheme({
palette: {
primary: {
main: '#014EAA',
contrastText: '#ffffff',
},
secondary: {
main: '#0099CC',
contrastText: '#ffffff',
},
info: {
main: '#666666',
contrastText: '#ffffff',
},
error: {
main: '#FF6600',
contrastText: '#ffffff',
},
success: {
main: '#339933',
contrastText: '#ffffff',
},
},
});
// deleteme
const useStyles = makeStyles(theme => ({
root: {
color: theme.palette.primary,
fontSize: 10,
padding: '6px 12px',
fontFamily: ['sans-serif']
},
card: {
minwidth: 275,
},
title: {
fontSize: 24
},
cardTitle: {
fontSize: 24,
color: theme.palette.primary.main,
},
cardSubtitle: {
fontSize: 14,
color: theme.palette.secondary.main
},
cardDescription: {
fontSize: 10,
},
avatarTM: {
backgroundColor: theme.palette.primary.dark
},
avatarUnknown: {
backgroundColor: theme.palette.warning.main
},
avatarFixed: {
backgroundColor: theme.palette.primary.light
},
}));
export { theme, useStyles }

You can try force this style putting property like this:
avatarTM: {
backgroundColor: 'theme.palette.primary.dark !important'
},

Related

Access Button Primary Color In React

I am trying to provide overrides in the theme for buttons that are contained, primary and hovered. I tried this but it doesn't work
CODESANDBOX LINK CLICK HERE
theme/overrides/MuiButton.js
import palette from '../palette';
export default {
contained: {
backgroundColor: '#FFFFFF',
'&.primary': {
'&:hover': {
backgroundColor: palette.primary.dark,
},
},
},
};
theme/overrides/index.js
import MuiButton from "./MuiButton";
export default {
MuiButton
};
theme/index.js
import { createMuiTheme } from "#material-ui/core";
import palette from "./palette";
import typography from "./typography";
import overrides from "./overrides";
const theme = createMuiTheme({
palette,
typography,
overrides,
zIndex: {
appBar: 1200,
drawer: 1100
}
});
export default theme;
The best resource for determining how to appropriately override the default styles in your theme, is to look at how the default styles are defined.
From https://github.com/mui-org/material-ui/blob/v4.11.0/packages/material-ui/src/Button/Button.js#L138:
containedPrimary: {
color: theme.palette.primary.contrastText,
backgroundColor: theme.palette.primary.main,
'&:hover': {
backgroundColor: theme.palette.primary.dark,
// Reset on touch devices, it doesn't add specificity
'#media (hover: none)': {
backgroundColor: theme.palette.primary.main,
},
},
},
Translating this approach to the code in your question would look like this:
import palette from '../palette';
export default {
containedPrimary: {
backgroundColor: '#FFFFFF',
'&:hover': {
backgroundColor: palette.primary.dark,
},
},
};

Material-ui style type override

I'd like to modify MuiIconButton-root class when I use MuiSvgIcon with fontSizeSmall.
import React from 'react'
import { createMuiTheme, ThemeProvider } from '#material-ui/core/styles';
const theme = createMuiTheme({
overrides: {
MuiSvgIcon: {
fontSizeSmall: {
padding: "5px"
}
}
}
});
export default function Root(props) {
return (
<ThemeProvider theme={theme}>
<MyApp />
</ThemeProvider>
)
}
I've modified MuiSvgIcon, but it can't modify MuiButtonBase-root.
Is there any way to override the padding value of MuiIconButton-root when I use small MuiSvgIcon?
Following the picture:
yes you can override the style of root like this, I am not creating your exact scenario but I am going to show you the same functionality with a button from Material UI, first get all the files needed:
npm install #material-ui/styles
npm install #material-ui/core
and then:
//other react imports
import { makeStyles, withStyles } from '#material-ui/core/styles'; //you need to include this to change the style
import Button from '#material-ui/core/Button'; //this is just the button
const useStyles = theme => ({
root: {
'& > *': {
margin: theme.spacing(1),
},
},
button: {
fontSize: "16px",
fontWeight: "600",
textAlign: "center",
border: "none",
cursor: "pointer",
color: "#fff",
backgroundColor: "#C8385E"
}
});
class Welcome extends React.Component {
render() {
return (<div>
<Button
className={classes.button}
variant="contained" component="span">
BUTTON TEXT
</Button>
</div>);
}
}
export default withStyles(useStyles)(Welcome);
you need to export the class like shown above, include the "withStyles" and pass in the styles that you have, here its called "useStyles" and then pass the class name. this way you can edit the styles in the UseStyles and it will actually show those changes on the screen.

Reddit text field implementation Material-UI

So I'm trying to immitate the reddit text field implementation from material-ui, I've gone ahead and setup this custom component, but I'm getting a invalid hook call error everytime I run on the const classes=... Line
Here's the code:
import React, { Component } from "react";
import { TextField } from "#material-ui/core";
import { fade, makeStyles } from "#material-ui/core/styles";
import styles from "./LNTextField.module.css";
const useStylesReddit = makeStyles(theme => ({
root: {
border: "1px solid #e2e2e1",
overflow: "hidden",
borderRadius: 4,
backgroundColor: "#fcfcfb",
transition: theme.transitions.create(["border-color", "box-shadow"]),
"&:hover": {
backgroundColor: "#fff"
},
"&$focused": {
backgroundColor: "#fff",
boxShadow: `${fade(theme.palette.primary.main, 0.25)} 0 0 0 2px`,
borderColor: theme.palette.primary.main
}
},
focused: {}
}));
class LNTextField extends Component {
render() {
var classNames = require("classnames");
const classes = useStylesReddit();
return (
<TextField
InputProps={{ classes, disableUnderline: true }}
{...this.props}
/>
);
}
}
export default LNTextField;
Also since I just copied it I'm not sure how I can type this code in a seperate css files and refer to the hover and focused bits appropriately, so If you could also tell me how to do that that'd be great. Thanks!
According to React, you are getting this error because:
You can’t use Hooks inside of a class component
Convert your class component to functional component:
const LNTextField = props => {
var classNames = require("classnames");
const classes = useStylesReddit();
return (
<TextField
InputProps={{ classes, disableUnderline: true }}
{...props}
/>
);
}

How to reuse react-native StyleSheet (styles) in react?

// react-native example
import { StyleSheet, View } from 'react-native';
const styles = {
container: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#d6d7da',
}
}
const stylesRN = StyleSheet.create(styles);
<View style={stylesRN.container}></View>
What the best way to reuse
// inner styles
{
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#d6d7da',
}
in both react-native and react?
What i want to achieve in pseudocode (or another way of reuse in React):
<div style={magicAdapter(styles.container)}>Hello World!</div>
Problem: It is impossible to reuse all react-native inline-styles in react as is without magicAdapter.
What you could do is store all your styles in an object in some file e.g. const containerStyles = { borderRadius: 2 }, export it, then for React Native use the StyleSheets javascript class to create the styles for your div container
import {containerStyles} from '../someFile.js'
const styles = StyleSheets.create({
container: containerStyles
})
then for React you could do inline styling with the same object, but be aware that not all styles supported in StyleSheets can be used for inline styling, so if you want to do something equivalent there's libraries out there like emotion.js to dynamically load CSS in JS
https://github.com/emotion-js/emotion
Heres an example
import {css} from 'emotion'
import {containerStyle} from '../someFile'
const getContainerStyles = css`
border-radius: ${containerStyle.borderRadius}
`
export default class SomeClass extends Component {
render() {
return(
<div
style={getContainerStyles}
>
</div>
)
}
}
I hope this helps
You could concatenate the style of your new component with the style of container, like below
const styles = StyleSheet.create({
container: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#d6d7da',
},
newComponent:{
// New component style
}
});
<View style={[styles.container, styles.newComponent]}>
</View>
// your component file name (button.js)
import React, { Component } from 'react';
// import the style from another file present in the same directory
import styles from 'button.style.js';
// you can reuse this style in another component also
class Button extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.buttonText}> Press Me! </Text>
</View>
);
}
}
export default Button;
// your style file name ( "button.style.js")
import { StyleSheet } from 'react-native';
export default StyleSheet.create({
container: {
padding: 10,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#43a1c9',
},
buttonText: {
fontSize: 20,
textAlign: 'center'
}
});

How to change the default properties of a css framework as material ui

I'm pretty new to css and i'm a little confused here. I'm using material ui with react and redux. I want somehow to edit some properties of a specific component. For example suppose we use TextField with disabled property. As i can see the disabled property contains these properties(i saw that from the material ui node modules in textfield).
var styles = {
root: {
borderTop: 'none',
borderLeft: 'none',
borderRight: 'none',
borderBottomStyle: 'solid',
borderBottomWidth: 1,
borderColor: borderColor,
bottom: 8,
boxSizing: 'content-box',
margin: 0,
position: 'absolute',
width: '100%'
},
disabled: {
borderBottomStyle: 'dotted',
borderBottomWidth: 2,
borderColor: disabledTextColor
},
But i dont want when it's disable for the borderBottomLine to be dotted. I want to change it to hidden. How to do such an action without affecting the frameworks code?
You can override some default styles of material-ui components. Look at this section of docs. Pay attention to this example:
import React from 'react';
import {cyan500} from 'material-ui/styles/colors';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import AppBar from 'material-ui/AppBar';
// This replaces the textColor value on the palette
// and then update the keys for each component that depends on it.
// More on Colors: http://www.material-ui.com/#/customization/colors
const muiTheme = getMuiTheme({
textField: {
backgroundColor: 'yellow',
},
datePicker: {
color: 'yellow',
},
});
// MuiThemeProvider takes the theme as a property and passed it down the hierarchy.
const Main = () => (
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar" />
</MuiThemeProvider>
);
export default Main;
Here, we override background-color for TextField component and color for DatePicker. You should import getMuiTheme function, pass to its object with properties which you want to override. Unfortunately, for disabled TextField you can override only text color. You can check all properties which you can override from source of default theme - https://github.com/callemall/material-ui/blob/master/src/styles/getMuiTheme.js
const muiTheme = getMuiTheme({
textField: {
backgroundColor: 'yellow',
},
datePicker: {
color: 'yellow',
},
});
After that, you should pass muiTheme to the eponymous property
of MuiThemeProvider component. This component should wrap root-component of your application.
const Main = () => (
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar" />
</MuiThemeProvider>
);
Here's sample code. Use style in your preferred jsx tag and edit it normally like CSS, but the properties & values must be inside quotation marks("").
import React from "react";
import AppBar from "#mui/material/AppBar";
import Toolbar from "#mui/material/Toolbar";
const index = () => {
return (
<AppBar style={{ backgroundColor: "black", height: "65px" }}>
<Toolbar></Toolbar>
</AppBar>
);
};
export default index;

Resources