Can we use both MUI makeStyles and Theming in _app.js - javascript

I'm making a tricky nav component using MUI Persistent Drawers with a React + Next structure. In order to get the content shrinking thanks to the state change, I had to put the whole navigation system inside of the _app.js file instead of having it in a distinct component.
Even though it clearly works, I wonder if it'll not impact rendering and performance once built. The makeStyles((theme) seems to work just fine but is not highlighted in VScode, probably because I used both of makeStyles, useTheme and ThemeProvider in the same file, as below :
import { makeStyles, useTheme } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/core/styles';
const useStyles = makeStyles((theme) => ({ ...
(className example:) appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}, ... etc
Was it a good idea to put it all together in _app.js, or do I need to refactor everything into a new component passing props to parent somehow ?
Thanks for considering, best regards to all of you

I recommend you to put your theme inside a folder theme/theme.js and use createMuiTheme then in your app.js wrap your whole component with the theme provider ! That would spread your theme across the app and let you use it where you want ! Is the convention we got with material-ui.
theme/theme.js:
import { createMuiTheme } from "#material-ui/core/styles"
export const themeObject = {
palette: {
primary: { main: "#333333" },
secondary: { main: "#FD8C7C" },
},
backgroundColor: {
primary: { main: "#FEF8F8" },
secondary: { main: "#FFFFFF" },
},
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 960,
lg: 1280,
xl: 1920,
},
},
overrides: {
MuiDivider: {
root: {
backgroundColor: "#FFFFFF",
},
},
},
}
export default createMuiTheme(themeObject)
pages/app,js:
import React from "react"
import { ThemeProvider } from "#material-ui/styles"
import Box from "#material-ui/core/Box"
import defaultTheme from "../theme/theme"
const App = () => {
return (
<Box>
<ThemeProvider theme={defaultTheme}>
...
</ThemeProvider>
</Box>
)
}
export default App
component/SideBar.js:
import React from "react"
import { makeStyles } from "#material-ui/core/styles"
const useStyles = makeStyles((theme) => ({
drawer: {
width: theme.sidebar.width,
color: theme.palette.primary
flexShrink: 0,
whiteSpace: "nowrap",
"& .MuiDrawer-paper": {
top: "unset",
},
},
drawerClose: {
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: "hidden",
width: theme.spacing(7) + 1,
[theme.breakpoints.up("sm")]: {
width: theme.spacing(7) + 1,
},
},
expandButton: {
[theme.breakpoints.up("sm")]: {
marginLeft: theme.spacing(-2.5),
marginRight: theme.spacing(2.5),
},
},
}))
export default function Sidebar(props) {
const classes = UseStyles()
return (...)
}
In the SideBar you can see that i have use the theme.zindex.drawer who come from directly theme.js.
I also recommend you to go check this MUI THEMING that would let you dive into the theming more deeply !

Related

Chakra UI custom component variant not working

I have created a customTheme file to extend the Chakra them and have created a custom component called card which I would like to have variants applicable, but for some reason the base styles show and the variants never work.
extendTheme.js
`
import { extendTheme } from '#chakra-ui/react';
import { ButtonStyles as Button } from './styles/components/ButtonStyles';
import { CardStyle as Card } from './styles/components/CardStyle';
const customTheme = extendTheme({
colors: {
brand: {
100: '#f7fafc',
900: '#f77070',
},
grey: {
100: '#eff3fa',
},
blue: {
100: '#0098ae',
},
red: {
100: '#ff3d3d',
200: '#f77070'
},
},
fonts: {
body: 'Graphik Font',
heading: 'Graphik Font',
},
fontWeights: {
hairline: 100,
thin: 200,
light: 300,
normal: 400,
medium: 500,
semibold: 600,
bold: 700,
extrabold: 800,
black: 900,
},
components: {
Button,
Card,
}
});
export default customTheme;
`
cardStyle.js
`
import { defineStyleConfig } from '#chakra-ui/react'
export const CardStyle = defineStyleConfig({
// The styles all Cards have in common
baseStyle: {
display: 'flex',
flexDirection: 'column',
background: 'white',
alignItems: 'center',
gap: 6,
},
// Two variants: rounded and smooth
variants: {
rounded: {
padding: 8,
borderRadius: 'xl',
boxShadow: 'xl',
},
smooth: {
padding: 6,
borderRadius: 'base',
boxShadow: 'md',
},
},
// The default variant value
defaultProps: {
variant: 'smooth',
},
})
`
Card.jsx
`
import { Box, useStyleConfig } from '#chakra-ui/react'
function CardTest(props) {
const { variant, ...rest } = props
const styles = useStyleConfig('Card', { variant })
// Pass the computed styles into the `__css` prop
return <Box __css={styles} {...rest} />
}
export default CardTest
`
including the card in another jsx
`
<CardTest variant='rounded'>
<Image
src={imageOne}
rounded='full'
w={32}
h={32}
boxShadow='md'
/>
<Heading mt={6} maxW={60} size='lg' textAlign='center' color='gray.700'>
Explore the outdoors
</Heading>
<Text mt={6} mb={6} size='sm' color='brand.900'>
some text in the card
</Text>
<Image src={imageOne} w={32} h={32} />
</CardTest>
`
import React from 'react';
import ReactDOM from "react-dom/client";
import { ChakraProvider } from '#chakra-ui/react';
import customTheme from './extendTheme';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<ChakraProvider theme={customTheme}>
<App />
</ChakraProvider>
</React.StrictMode>,
);
it uses the example off of the chakra docs but for some reason the variant never changes and I cannot see why when if i tell it o use Button as styles and not Card the variants work for button.
Aha! You're mapping CardStyles to Card, but actually rendering CardTest!
import { CardStyle } from './styles/components/CardStyle';
const customTheme = extendTheme({
// ...
components: {
Button,
Card: CardStyle, // targets Card component...
CardTest: CardStyle, // ...but you're rendering CardTest
}
});
Here's a working version, slightly simplified:
https://codesandbox.io/s/so-74816092-oio6qr?file=/src/index.js
Side note, CardStyle can't apply to Card, as it's a multipart component:
https://chakra-ui.com/docs/styled-system/component-style#single-part-and-multipart-components
https://chakra-ui.com/docs/styled-system/advanced-theming
https://chakra-ui.com/docs/components/card/theming
Outdated
You haven't included a snippet showing where you provide your custom theme to Chakra's ThemeProvider, so this may explain your issue:
// extendTheme.js
import { extendTheme } from "#chakra-ui/react"
const theme = extendTheme({
// ...
})
export default theme
import * as React from 'react'
import { ChakraProvider } from '#chakra-ui/react'
import theme from './extendTheme.js'
function App() {
// Wrap ChakraProvider at the root of your app
return (
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
)
}
// Now you can use these colors in your components
function Usage() {
return <Box bg="brand.100">Welcome</Box>
}
https://chakra-ui.com/docs/styled-system/customize-theme

Changing theme primary color not affect button color

"#mui/material": "^5.5.3"
Hi there,
I'm trying to style my MUI form using values, imported from the SCSS variables.
Everything seems to be working fine (I can see passed values in devtools) except for the colors actually never change.
Registration.tsx
import {AppDataContext} from './context/app-data-context';
import {createTheme, ThemeProvider} from '#mui/material/styles';
export const Registration = () => {
const appData = useContext(AppDataContext);
const myTheme = useMemo(() => {
const colors = appData.brandedSCSS.default;
return createTheme({
palette: {
primary: {
main: colors.primary // #fdab0a
},
secondary: {
main: colors.secondary // #ffffff
}
}
})
}, [appData])
return (
<ThemeProvider theme={myTheme}>
// some code here
</ThemeProvider>
);
Somewhere going down the components tree:
import {Button, CircularProgress, Grid} from "#mui/material";
// some code here
return (
//some code there
<Button
color="primary"
type="submit"
>
)
Theme seems to be applied correctly
but the buttons is still blue
What am I doing wrong? Thanks.
this is how i'm changing the default theme colors of mui
index.js
import { ThemeProvider } from "#mui/material"
// or import { ThemeProvider } from '#emotion/react';
import { createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#554149',
contrastText: '#fff',
},
secondary: {
main: '#00AA9C',
contrastText: '#fff',
},
info: {
main: "#906D9A",
contrastText: '#fff',
},
},
})
<ThemeProvider theme={theme}>
<App/>
</ThemeProvider>
"#mui/material": "^5.0.6",

React-Native-Paper Theme won't use Custom Fonts

I am working on a RN app using react-native-paper to handle theming and UI. I have the theme working to format my components, however when I try to incorporate custom fonts it does not have any effect on the react-native-paper components. I have followed the [font guide][1] but it did not change this issue.
I follow the expo example of how to load fonts using loadFontAsync(), and when I pass these fonts to my own components using the style prop fontFamily: 'Rubik-Regular the font works so I know it is not an issue of the font not existing.
As I am new to react-native-paper, I think my issue is with my fontConfig or configureFonts(). Any help or direction would be greatly appreciated.
import React from 'react';
import { Provider as ReduxProvider } from 'react-redux'
import configureStore from './store'
]import { configureFonts, DefaultTheme, Provider as PaperProvider } from 'react-native-paper'
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
import AppNavigator from './components/AppNavigator'
const store = configureStore();
const fontConfig = {
default: {
regular: {
fontFamily: 'Rubik-Regular',
fontWeight: 'normal',
},
medium: {
fontFamily: 'Rubik-Black',
fontWeight: 'normal',
},
light: {
fontFamily: 'Rubik-Light',
fontWeight: 'normal',
},
thin: {
fontFamily: 'Rubik-LightItalic',
fontWeight: 'normal',
},
},
};
let customFonts = {
'Rubik-Regular': require('./assets/fonts/Rubik-Regular.ttf'),
'Rubik-Black': require('./assets/fonts/Rubik-Black.ttf'),
'Rubik-Light': require('./assets/fonts/Rubik-Light.ttf'),
'Rubik-LightItalic': require('./assets/fonts/Rubik-LightItalic.ttf'),
}
const theme = {
...DefaultTheme,
roundness: 30,
fonts: configureFonts(fontConfig),
colors: {
...DefaultTheme.colors,
primary: '#0d80d6',
accent: '#E68FAE',
background: '#C6E1F2',
},
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
fontsLoaded: false,
};
}
async loadFontsAsync() {
await Font.loadAsync(customFonts);
this.setState({ fontsLoaded: true });
}
componentDidMount() {
this.loadFontsAsync();
}
render() {
if (this.state.fontsLoaded) {
return (
<ReduxProvider store={store}>
<PaperProvider theme={theme}>
<AppNavigator/>
</PaperProvider>
</ReduxProvider>
);
}
else {
return <AppLoading/>;
}
}
}
I am using react-native 0.63.3 and Expo.
I know this is from a while ago but I ran into the same problem today and found this related issue in their repository on GitHub: https://github.com/callstack/react-native-paper/issues/1502#issuecomment-576534682
TL;DR the solution is you have to specify fontConfig.ios and probably fontConfig.android for it to work, instead of just having fontConfig.default.
for your case, you can probably adapt to something like
const _fontConfig = {
regular: {
fontFamily: 'Rubik-Regular',
fontWeight: 'normal',
},
medium: {
fontFamily: 'Rubik-Black',
fontWeight: 'normal',
},
light: {
fontFamily: 'Rubik-Light',
fontWeight: 'normal',
},
thin: {
fontFamily: 'Rubik-LightItalic',
fontWeight: 'normal',
},
};
const fontConfig = {
ios: _fontConfig,
android: _fontConfig,
};

in a GroupAvatar, my "max" Avatar does not obey the rules of my theme

I'm trying to create an AvatarGroup with MaterialUi, all my avatars obey a previously created style.
All, except the avatar automatically generated by AvatarGroup when the "max" parameter has been defined. :(
const styles = makeStyles((theme) => createStyles({
avatar: {
marginRight: theme.spacing(4),
borderWidth: '1px',
borderStyle: 'solid',
borderColor: grey[200],
width: theme.spacing(3),
height: theme.spacing(3)
}
}))
export default function GroupAvatars() {
const classes = styles();
const nameList = ['Alexandre', 'Regis', 'Leo', 'Thing', 'ola', 'que', 'tal']
const avatarList = nameList.map(name => {
return (<Avatar key={name}
className={classes.avatar}
alt={name}
/>)
})
return (
<AvatarGroup max={4} >
{avatarList}
</AvatarGroup>
);
}
it gives me this:
GroupAvatar with last avatar too big
as you can see the last avatar (+4) is way bigger than the others.
You can test the code on website like stackblitz.com using react:
stackblitz where you can test project
here are the import
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import { createMuiTheme } from '#material-ui/core/styles';
import { withStyles, WithStyles, createStyles, makeStyles, Theme } from '#material-ui/core/styles';
import { grey, blue } from '#material-ui/core/colors'
import AvatarGroup from '#material-ui/lab/AvatarGroup';
how do i make my avatar "+4" the same size as the other avatars ?
Target the avatar rule name for AvatarGroup instead of the individual Avatar components
<AvatarGroup max={4} classes={{avatar: classes.avatar}}>

React export stylesheet

I would like to create an external stylesheet using the MaterialUI 'makeStyles' and 'createStyles' like you can in React Native however, I don't know how to do it.
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex'
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
}
}),
);
So this would be called 'globalStyle.tsx' and then in any other file I can import it then do something like styles.root, etc. I've done it before in React Native but as said previously, I'm stuck on how to proceed.
React Native way: https://reactnative.dev/docs/stylesheet
First you should import the makeStyles like:
import { makeStyles } from "#material-ui/core/styles";
and then you can use it with something like this:
export const useStyles = makeStyles((theme) => ({
container: {
width: "100%",
},
}));

Categories

Resources