How to customize different components with ChakraUI? - reactjs

I'm using chakraUI in my React project. I have some custom buttons, texts, alerts and more components.
Is there a way to customize something like the following.
components: {
Button: {
primaryDefault: {
colorScheme: '#5c186a',
size: 'lg',
border: '2px',
},
//more customize buttons
}
}
I have my theme.js with the import { extendTheme } from '#chakra-ui/react'; and the configuration from the chakra's documentation link here. But I can't be able to use my own customize buttons, do you know how to use this?
Also, in my extendTheme file I was trying to do something like this:
colors: {
primary: {
dark: '#5c186a',
light: '#7c4188',
},
secondary: {
yellow: '#fdb813',
red: '#d6075b',
blue: '#007ac3',
},
//more colors
}
And if I want to use them in the same file for customize other elements I don't know how to reference them. If I want to use primary dark color in some button I tried to use
colorScheme: this.colors.primary.dark
But it throws me an error :(

Related

Dynamic Material-UI Theme Provider Color Palette hex values from either API response or values from form

i working on front end project for my company.project is based on next/reactJs with material-ui v5 as styling support. i am fairly familiar with MUIv5 ThemeProvider and its usage. As per company's latest requirements themeproviders color palette values should be coming from backend or should be coming from form where user types the color codes or names in respective fields and it should be reflected throughout the app. i provided them with dropdown with 2-3 color options but they want to give an option to their clients to customize the app (hope it technically possible! ;)).
i am attaching the code snippets of themeprovider which utilize the useContext concept.
i request you all guys to provide me some kind of solution/guidance to my problem
have a nice day ahead
you guys are awesome.................
import { createTheme, responsiveFontSizes } from "#mui/material";
const primaryColor = "#02475B";
const secondaryColor = "#07AE8B";
const warningColor = "#FFA343";
const errorColor = "#CD4A4A";
const textColorLight = "#f5f5f5";
const textColorDark = "#001219";
const baseTheme = createTheme({
palette: {
mode: "light",
primary: {
main: primaryColor,
},
secondary: {
main: secondaryColor,
},
warning: {
main: warningColor,
},
error: {
main: errorColor,
},
neutral: {
main: "#f2f4f3",
},
darkNeutral: {
main: "#353c55",
},
typography: {
fontFamily: ["Nunito Sans", "sans-serif"].join(","),
},
},
});
const theme = responsiveFontSizes(baseTheme);
export default theme;
i did try calling api in theme.js file but throw an error about useContext also tried making theme component to make work ... its child to data manipulation i was successful for manipulating one color from child
I would for example create a function that will create my theme and store that theme in the local state of my root component.
import { createTheme } from '#mui/material/styles';
const createCustomTheme = (severty?: 'primary' | 'secondary' | undefined , color?: undefined | string)=>{
return createTheme({
palette: {
mode: 'dark',
primary: {
main: (severty == 'primary' ) ? color :'#2a7696',
},
secondary: {
main: (severty == 'secondary' ) ? color :'#f50057',
},
background: {
default: '#0a1929',
paper: '#0f2237',
},
divider: 'rgba(255,255,255,0.54)',
},
shape: {
borderRadius: 4
}
});};
export default createCustomTheme;
This way you can customize the creation of your theme. Here my function is not really developed. Once the theme is created and stored in the local state of your root component. You will only have to pass that local state to the ThemeProvider.
You can then create a form that will ask the user to choose the colors and everything... once created, simply update your state by passing the user's information to your function for creating the theme.

Dynamic switching between prepackaged CSS themes

I'm attempting to use ready-made themes for Bulma components (https://jenil.github.io/bulmaswatch/) in my React app, in a way that allows the user to toggle between them (specifically, between Flatly and Darkly).
I can import one theme at a time, but can't figure out how to implement switching between the contents of two .css files. I have attempted searching, but I only find generic solutions for very basic custom themes that do not seem to be suitable for switching between ready-made themes.
Below is an example of the kind of stuff I find, but I don't know how to scale it up to using two 100kb+ .min.css files.
export const themes = {
light: {
foreground: '#000000',
background: '#eeeeee',
},
dark: {
foreground: '#ffffff',
background: '#222222',
},
};
export const ThemeContext = React.createContext( themes.dark // default value);

Make MUI Checkbox border color as gradient

I am writing styleOverrides to MuiCheckBox and want to make its borders as linear gradient. Any ideas how to make it possible?
MuiCheckbox: {
styleOverrides: {
root: {
color: 'linear-gradient(89.38deg, #957947 -13.88%, #E1BC6C 27.59%, #EFDB7C 66.54%, #E9BA6A 105.86%)',
backgroundColor: 'transparent',
}
}
You can add borderColor property to your root like this,
root:{
borderColor: 'linear-gradient()'
}
Something I use and I am converting our whole app to in order to do the migration from MUI 4 to 5, is component overrides.
So say you have a or component. Basically in like a styled.js file, you can do:
import { withStyles } from '#material-ui/core';
import { MenuItem } from '#material-ui/core';
const MenuItemStyled = withStyles((theme) => ({
root: {
borderColor: 'yourGradient'
}
})(MenuItem);
export { MenuItemStyled }
(in jsx file like 'index.js')
import MenuItemStyled from './styled';
import Menu from '#material-ui/core';
<Menu>
<MenuItemStyled value={blah}>blah</MenuItemStyled>
<MenuItemStyled value={blahblah}>blahblah</MenuItemStyled>
</Menu>
I find this gives you more root access to component styles without having to dig through specific classnames in the inspector. When overriding components like this is checks for your custom styles first before render and it just makes everything significantly easier. Plus in MUI 5 useStyles is depricated, so you'll want to do it this way regardless in order to keep your app current.

How do I extend the color palette from mui with Typescript

I'm trying to extend the color palette that mui provides. The overriding of primary, secondary etc colors works well but if I want to create a custom set of colors just after, I can't figure out how to make it works. There are plenty of examples without typescript but when this guy comes into the game it makes it trickier. Let's say I have this:
theme.tsx
palette: {
primary: {...}, // override works
custom: {
main: 'color',
dark: 'color1',
light: 'color2',
contrastText: 'color3'
}
}
from what mui document says, I should use module augmentation:
declare module "#material-ui/core/styles/createPalette" {
interface Palette {
custom: Palette['primary'];
}
interface PaletteOptions {
custom: PaletteOptions['primary'];
}
}
Nothing is yelling, but when I use it for a Box component for example, it doesn't work (others like primary.dark works well). It's been several days that I'm trying to find out how to do this, but I have to say I'm out of knowledge there.
I'd appreciate some help! Thanks! :)
Ps: Someone already posted the same question but it didn't help me here
MUI 5
This is the approach I took for extending the palette in MUI 5.
You can remove the extends however you still need to import the Palette and PaletteOptions without the aliases. This might cause some issues with the linter, though (unused imports).
To avoid any gross eslint disable stuff, I just overwrote the types and extended them with the existing types by importing them under an alias.
import {
Palette as MuiPallete,
PaletteOptions as MuiPaletteOptions,
} from '#mui/material/styles/createPalette';
declare module '#mui/material/styles/createPalette' {
interface Palette extends MuiPallete {
neutralShade: {main: string};
}
interface PaletteOptions extends MuiPaletteOptions {
neutralShade?: {main: string};
}
}
No idea if there is a better way but this seemed the cleanest to me.
As others mentioned, the documentation shows how to add a color to the theme interface, but not for the color property of components. I think I found a proper solution in the source code. This example is using Material UI 5, so I'm not sure if it works in 4, and I couldn't find any official docs on it.
In my example, the Chip component exports several interfaces which you can extend with declaration merging. The following code should allow you to set the color of a chip to "facebook" or "twitter"
// define custom colors: https://material-ui.com/customization/palette/
declare module '#mui/material/styles/createPalette' {
interface Palette {
facebook: Palette['primary'];
twitter: Palette['primary'];
}
interface PaletteOptions {
facebook: PaletteOptions['primary'];
twitter: PaletteOptions['primary'];
}
}
// Extend color prop on components
declare module '#mui/material/Chip' {
export interface ChipPropsColorOverrides {
facebook: true
twitter: true
}
}
This is from my current project. I reuse the primary type.
declare module '#material-ui/core/styles/createPalette' {
interface Palette {
magic: Palette['primary'];
}
interface PaletteOptions {
magic: PaletteOptions['primary'];
}
}
export const Theme = createMuiTheme({
palette: {
magic: { main: '#1a1a1a' },
}
})
You can extend it like this
import { Color, Palette, PaletteOptions } from '#mui/material';
export interface MyGrey extends Color {
custom: string;
}
export const myGrey: MyGrey = {
custom:'#FFFFFF'
}
interface MyPaletteExtensions {
myGrey: MyGrey;
}
declare module '#mui/material/styles' {
interface Palette extends MyPaletteExtensions {}
interface PaletteOptions extends MyPaletteExtensions {}
}
export const myPalette: PaletteOptions = {
primary: {
light: '#FFFFFF',
main: '#FFFFFF',
dark: '#FFFFFF',
},
secondary: {
light: '#FFFFFF',
main: '#FFFFFF',
},
myGrey,
};
This will then allow
theme.palette.myGrey.custom
One thing to bear in mind with the above approach you can't extend the default palette keys e.g grey it must be a custom name had we done theme.palette.grey.custom this would work but give a TS error.
From looking at the source code, you should be using:
declare module "#material-ui/core/styles/createPalette" {
interface Palette {
custom: PaletteColorOptions;
}
interface PaletteOptions {
custom: PaletteColorOptions;
}
}
I'm not sure why this is documented like that though.

In material-ui, how can I set different theme-styles for different breakpoints?

This questions targets material-ui 1.0.
When I create a theme with createMuiTheme, how can I set, for example for typography.title, different styles for different breakpoints? On a component level I can achieve this with something like this:
const styles = theme => ({
title: {
fontSize: 34,
},
[theme.breakpoints.down('sm')]: {
title: {
fontSize: 28,
}
},
})
Material-ui sure has a lot of different theming solutions. When you look for one that would be useful to you, you are looking for two things:
Creating a theme that can be applied to component hierarchy.
Doc page "Nesting the theme"
Changing single styling rules while keeping the others intact.
Doc page "Customizing all instances of component type"
and "Typography API"
The key to make it work is to create a second theme that can see the breakpoints, and provide it with some special options for overriding typography:
...outerTheme,
overrides: {
MuiTypography: {
title: {
[outerTheme.breakpoints.down("sm")]: {
fontSize: 28
},
}
}
}
I find the "Nesting the theme" example code suitable to test it on, so this is what it could look like:
codesandbox.io/s/98192p85zy
EDIT: replaced the final code link to make it more useful an answer than just the examples from the docs.
There is another way to work with createMuiTheme with the breakpoints methods.
If you check the createMuiTheme core, you will see that it uses the createBreakpoints class.
So, you can do like that:
// theme.js
import createBreakpoints from '#material-ui/core/styles/createBreakpoints'
import { createMuiTheme } from '#material-ui/core/styles'
const breakpoints = createBreakpoints({})
const theme = createMuiTheme({
overrides: {
MuiTab: {
root: {
[breakpoints.up('lg')]: {
minWidth: '200px',
backgroundColor: 'yellow',
},
},
wrapper: {
padding: '0 10px',
backgroundColor: 'black',
},
},
},
})
export default theme
(tested: #material-ui/core 4.0.1)

Resources