useStyles not working as it should in mui5? - material-ui

I am trying to custom style my icon adding a bigger font size, the background is working fine but the font size is not, I read that I can use important! but I want to know why it is not working as it has been working in version 4 .
const useStyles = makeStyles((theme: Theme) => ({
root: {
flexGrow: 1,
},
icon: {
fontSize: 140,
backgroundColor: 'red',
'&:hover': {
backgroundColor: 'red',
},
},
}));
<Box style={{ display: 'flex', alignItems: 'center' }}>
<EmojiObjectsIcon color='primary' className={classes.icon} onClick={switchTheme} />
</Box>

add px for fontSize like this :
const useStyles = makeStyles((theme: Theme) => ({
root: {
flexGrow: 1,
},
icon: {
fontSize: '140px',
backgroundColor: 'red',
'&:hover': {
backgroundColor: 'red',
},
},
}));
const PublicSidebar = () => {
const classes = useStyles();
return (
<Box style={{ display: 'flex', alignItems: 'center' }}>
<EmojiObjectsIcon color='primary' className={classes.icon} onClick={switchTheme} />
</Box>
)
}

Related

MUIButton outlined style change using ThemeProvider

I wants to create 5 custom format for any type of button(variant=outlined/contained)
I found some articles to override existing or root component style like below
export const myTheme = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
backgroundColor: colors.yellow[500]
},
outlined: {
backgroundColor: colors.orange[500]
,'&:hover': {
backgroundColor: colors.green[500],
}
}
},
},
}
})
I would like to create a set of styles to MuiButton Variant = outlined like below,
ButtonSubmit:{
backgroundColor: colors.lightBlue[500],
color: colors.cyan[100] //Text color
'&:hover': {
backgroundColor: colors.lightBlue[100]
}
}
ButtonCancel:{
backgroundColor: colors.Orange[500],
color: colors.cyan[100] //Text color
'&:hover': {
backgroundColor: colors.Orange[100]
}
}
ButtonNav:{
backgroundColor: colors.green[500],
color: colors.cyan[100] //Text color
'&:hover': {
backgroundColor: colors.green[100]
}
}
How to apply those styles to button variant outlined
<Button variant="outlined" size='small' sx={{ height: '30px'}}>ButtonSubmit</Button>
<Button variant="outlined" size='small' sx={{ height: '30px'}}>ButtonCacel</Button>
<Button variant="outlined" size='small' sx={{ height: '30px'}}>ButtonNav</Button>

MUI v5 styles broken with makeStyles() hook

I am using MUI v5 with Next.js and I styled all my pages and components using makeStyles() hook. When my website loads, on initial render all the CSS are broken for 2 or 3 seconds.
I noticed MUI default styles are loaded first then my Custom CSS Loads.
I also used emotion and emotion cache but it didn't worked.
Below is the code how I Integrate MUI v5 With Next.js
_app.tsx
import Head from 'next/head'
import { AppProps } from 'next/app'
import { useEffect } from 'react'
import { ApolloProvider } from '#apollo/client'
import { ThemeProvider } from '#mui/material/styles'
import { SessionProvider } from 'next-auth/react'
import CssBaseline from '#mui/material/CssBaseline'
import client from '#/lib/apollo'
import { wrapper } from '#/redux/store'
import theme from '../theme'
import { CookiesProvider } from 'react-cookie'
const MyApp = (props: AppProps) => {
const { Component, pageProps } = props
const { session } = pageProps
useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector(`#jss-server-side`) as HTMLElement
if (jssStyles) {
jssStyles.parentElement?.removeChild(jssStyles)
}
}, [])
return (
<>
<Head>
<meta name="viewport" content="initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<SessionProvider session={session}>
<ApolloProvider client={client}>
<CookiesProvider>
<Component {...pageProps} />
</CookiesProvider>
</ApolloProvider>
</SessionProvider>
</ThemeProvider>
</>
)
}
export default wrapper.withRedux(MyApp)
_document.tsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { ServerStyleSheets } from '#mui/styles'
import React from 'react'
import theme from '../theme'
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Pacifico|Raleway:100,400,400i,700|Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
MyDocument.getInitialProps = async (ctx) => {
const sheets = new ServerStyleSheets()
const originalRenderPage = ctx.renderPage
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
}
}
theme.ts
import { createTheme, Theme, ThemeOptions } from '#mui/material'
import { red } from '#mui/material/colors'
const blueColor = `#0B72B9`
const orangeColor = `#FFBA60`
const greyColor = `#868686`
declare module '#mui/material/styles' {
interface CustomTheme extends Theme {
commonColors: {
blue: string
orange: string
}
tab: {
fontFamily: string
textTransform: string
fontSize: string
fontWeight: number
}
orangeButton: {
fontFamily: string
textTransform: string
fontSize: string
color: string
}
learnMoreButton: {
borderColor: string
color: string
borderWidth: number
textTransform: string
borderRadius: number
fontWeight: string
fontFamily: string
}
}
interface CustomThemeOptions extends ThemeOptions {
commonColors?: {
blue?: string
orange?: string
}
tab?: {
fontFamily?: string
textTransform?: string
fontSize?: string
fontWeight?: number
}
orangeButton?: {
fontFamily?: string
textTransform?: string
fontSize?: string
color?: string
}
learnMoreButton?: {
borderColor?: string
color?: string
borderWidth?: number
textTransform?: string
borderRadius?: number
fontWeight?: string
fontFamily?: string
}
}
export function createTheme(options?: CustomThemeOptions): CustomTheme
}
const theme = createTheme({
commonColors: {
blue: `${blueColor}`,
orange: `${orangeColor}`,
},
tab: {
fontFamily: `Raleway`,
textTransform: `none`,
fontSize: `1rem`,
fontWeight: 500,
},
orangeButton: {
fontSize: `1rem`,
fontFamily: `Pacifico`,
textTransform: `none`,
color: `white`,
},
learnMoreButton: {
borderColor: `${blueColor}`,
color: `${blueColor}`,
borderWidth: 2,
textTransform: `none`,
borderRadius: 50,
fontWeight: `bold`,
fontFamily: `Roboto`,
},
palette: {
primary: {
main: `${blueColor}`,
},
secondary: {
main: `${orangeColor}`,
},
error: {
main: red.A400,
},
},
typography: {
h5: {
fontWeight: 300,
},
h2: {
fontFamily: `Raleway`,
fontWeight: 700,
fontSize: `1.75em`,
color: `${blueColor}`,
lineHeight: 1.5,
},
h4: {
fontSize: `1.75rem`,
fontFamily: `Raleway`,
fontWeight: 700,
color: `${blueColor}`,
},
subtitle1: {
fontSize: `1.25rem`,
color: `${greyColor}`,
fontWeight: 300,
},
body1: {
fontSize: `1.25rem`,
color: `${greyColor}`,
fontWeight: 400,
},
caption: {
fontSize: `1rem`,
fontWeight: 300,
color: `${greyColor}`,
},
},
components: {
MuiInputLabel: {
styleOverrides: {
root: {
color: `${blueColor}`,
fontSize: `1rem`,
},
},
},
MuiInput: {
styleOverrides: {
root: {
fontSize: `1rem`,
fontWeight: 400,
color: `${greyColor}`,
'&.MuiInput-underline:after': {
borderBottom: `2px solid #000000`,
},
'&.MuiInput-underline:hover:before': {
borderBottom: `2px solid ${blueColor}`,
},
},
underline: {
'&:before': {
borderBottom: `2px solid ${blueColor}`,
},
},
},
},
},
})
export default theme
Hero.tsx (I styled all my component and pages like this)
/* eslint-disable #typescript-eslint/no-unsafe-call */
/* eslint-disable #typescript-eslint/no-unsafe-member-access */
/* eslint-disable #typescript-eslint/no-unsafe-assignment */
/* eslint-disable #typescript-eslint/no-unused-vars */
/* eslint-disable #typescript-eslint/no-explicit-any */
import { FC } from 'react'
import Lottie from 'react-lottie'
import Box from '#mui/material/Box'
import Button from '#mui/material/Button'
import Typography from '#mui/material/Typography'
import { makeStyles } from '#mui/styles'
import landingAnimation from '../../../animations/landing.json'
import ArrowIcon from '#mui/icons-material/ArrowForward'
const useStyles = makeStyles((theme?: any) => ({
mainContainer: {
display: `flex`,
justifyContent: `center`,
alignItems: `center`,
[theme.breakpoints.down(`md`)]: {
flexWrap: `wrap`,
},
width: `100%`,
},
heroText: {
[theme.breakpoints.down(`md`)]: {
fontSize: `1.6em`,
},
},
heroTextContainer: {
textAlign: `center`,
[theme.breakpoints.down(`md`)]: {
marginBottom: `1.2rem`,
},
},
learnButton: {
...theme.learnMoreButton,
fontSize: `0.9rem`,
height: 45,
width: 145,
},
learnButtonIcon: {
fontSize: `0.9rem`,
marginLeft: `0.3em`,
},
animationContainer: {
marginTop: `-28px`,
},
}))
const Hero: FC = (): JSX.Element => {
const classes = useStyles()
const defaultOptions = {
loop: true,
autoplay: true,
animationData: landingAnimation,
rendererSettings: {
preserveAspectRatio: `xMidYMid slice`,
},
}
return (
<Box component="div" className={classes.mainContainer}>
<Box className={classes.heroTextContainer} component="section">
<Typography className={classes.heroText} variant="h2">
Bringing West Coast Technologies
<br />
To The MidWest
</Typography>
<Button className={classes.learnButton} variant="outlined">
Learn More <ArrowIcon className={classes.learnButtonIcon} />
</Button>
</Box>
<Box className={classes.animationContainer} component="section">
<Lottie options={defaultOptions} height={`100%`} width={`100%`} />
</Box>
</Box>
)
}
export default Hero

How to properly target the Matrial UI nested prop attributes?

Even after having read the Material UI Customization rules, I haven't quite understood how to properly target nested elements.
Here is an example, where I am targeting the label of the <TextField> component. The styling for the label works, but the styling for when the label is shrinked does not.
const useStyles = makeStyles({
label: {
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
right: '22px',
bottom: '0px',
'&.MuiInputLabel-shrink': {
right: 'unset',
color: 'green',
},
'&. MuiInputLabel-shrink': {
right: 'unset',
color: 'green',
},
'&.shrink': {
right: 'unset',
color: 'green',
},
'&.shrinked': {
right: 'unset',
color: 'green',
},
},
'&.MuiInputLabel-shrink': {
color: 'purple',
},
});
To target a the class 'shrink', this would be the correct usage:
const useStyles = makeStyles({
label: {
'& .shrink': {
right: 'unset',
color: 'green',
},
},
},
If this doesn't work for you - it may be an issue of specificity. Just as a test, I'd add the '!important' flag to the css to validate that you're styles are actually being applied.
You'll also have to apply object on the 'classes' prop of the material-ui component.
Hope this helps

How to display input values in <Text> instead of alert in react native expo?

How to display form's input value in json format instead of alert?
Like this:
{
'username':'abcd',
'password':'kkkk'
}
this is the code
import React, { Component } from 'react';
import { Alert, Button, Text, TouchableOpacity, TextInput, View, StyleSheet } from 'react-native';
export default class App extends Component {
state = {
email: '',
password: '',
};
onLogin() {
const { email, password } = this.state;
Alert.alert('Credentials', `email: ${email} + password: ${password}`);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.titleText}>Hi, Welcome To</Text>
<Text style={styles.titleText}>Momento</Text>
<TextInput
value={this.state.email}
keyboardType = 'email-address'
onChangeText={(email) => this.setState({ email })}
placeholder='email'
placeholderTextColor = 'white'
style={styles.input}
/>
<TextInput
value={this.state.password}
onChangeText={(password) => this.setState({ password })}
placeholder={'password'}
secureTextEntry={true}
placeholderTextColor = 'white'
style={styles.input}
/>
<TouchableOpacity
style={styles.button}
onPress={this.onLogin.bind(this)}
>
<Text style={styles.buttonText}> Sign Up / Login </Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'salmon',
},
titleText:{
fontFamily: 'Baskerville',
fontSize: 50,
alignItems: 'center',
justifyContent: 'center',
},
button: {
alignItems: 'center',
backgroundColor: 'powderblue',
width: 200,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: 'white',
borderRadius: 25,
marginBottom: 10,
},
buttonText:{
fontFamily: 'Baskerville',
fontSize: 20,
alignItems: 'center',
justifyContent: 'center',
},
input: {
width: 200,
fontFamily: 'Baskerville',
fontSize: 20,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: 'white',
marginVertical: 10,
},
});
Try this might help
state = {
inputData:'',
};
onLogin() {
const { email, password } = this.state;
const data = {};
data.email = email;
data.password = password;
this.setState({inputData: JSON.stringify(data) });
// Alert.alert('Credentials', `email: ${email} + password: ${password}`);
}
<Text>{this.state.inputData}</Text>

Material-UI Tabs 'selected' isn't specific enough.

Code Sandbox here:
https://codesandbox.io/s/ypx4qpjvpx
Relevant bits:
const styles = theme => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper
},
label: {
fontWeight: "normal"
},
selected: {
fontWeight: "bold"
}
});
<Tabs value={value} onChange={this.handleChange}>
<Tab
label="Item One"
classes={{
label: classes.label,
selected: classes.selected
}}
/>
<Tab
label="Item Two"
classes={{
label: classes.label,
selected: classes.selected
}}
/>
<Tab
label="Item Three"
href="#basic-tabs"
classes={{
label: classes.label,
selected: classes.selected
}}
/>
</Tabs>
What I'm trying to do here is I need to override the default font weight style, but on selected, I want it to be bold.
The problem is - these have the same level of specificity, and label appears after selected, so it overrides it.
How would I make selected more specific/achieve what I want without using !important.
I think the easiest way is to use the root class instead of label (for the Tab component).
Demo: https://codesandbox.io/s/q3pmn9o7m4
(I added colours to make the changes easier to see.)
<Tab
label="Item One"
classes={{
root: classes.tabRoot,
selected: classes.selected,
}}
/>
const styles = theme => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
fontWeight: "normal",
color: "#fff",
},
selected: {
fontWeight: "bold",
color: "#0ff",
}
});
A different way: https://codesandbox.io/s/8op0kwxpj
const styles = theme => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
fontWeight: "normal",
color: "#fff",
'&$selected': {
fontWeight: "bold",
color: "#0ff",
},
},
selected: {},
});