Is there a way to specify defaultProps for a variant? - reactjs

I created variant for MuiButton like so...
const theme = createTheme({
components: {
MuiButton: {
variants: [{
props: {
variant: 'myVariantX'
},
style: {
backgroundColor: 'blue'
}
}]
}
},
});
...I know I can do this...
const theme = createTheme({
components: {
// Name of the component
MuiButton: {
defaultProps: {
// The props to change the default for.
disableRipple: true, // No more ripple, on the whole application 💣!
},
},
},
});
... but is there a way I could specify defaultProps for my 'myVariantX' variant? Dont want to target all MuiButtons. Something like...
const theme = createTheme({
components: {
MuiButton: {
variants: [{
props: {
variant: 'myVariantX',
defaultProps: {
disableRipple: true
}
},
style: {
backgroundColor: 'blue'
}
}]
}
},
});

Related

Switch storybook background through global parameter

I have the following globalTypes to enable a toolbar in storybook that lets me select the theme:
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme',
defaultValue: MyTheme.Light,
toolbar: {
icon: 'mirror',
items: [MyTheme.Light, MyTheme.Dark],
showName: true,
dynamicTitle: true,
},
},
};
This works fine and I can switch the theme through the toolbar:
Now I want to set the background color of the story (background-color of the body) according to the theme, but I cannot figure out how to do that for all stories globally.
I know how to configure different background colors, but I have no idea how to switch them based on the theme set in context.globals. How does this work?
You can use decorators to set global view and se
Like here
import { useEffect } from "react";
import "./preview.css";
enum MyTheme {
Light = "light",
Dark = "dark",
Tomato = "tomato"
}
export const globalTypes = {
theme: {
name: "Theme",
description: "Global theme",
defaultValue: MyTheme.Light,
toolbar: {
icon: "mirror",
items: [
{
title: "light",
value: MyTheme.Light
},
{ title: "dark", value: MyTheme.Dark },
{ title: "tomato", value: MyTheme.Tomato }
],
showName: true,
dynamicTitle: true
}
}
};
const clearStyles = (element: HTMLElement) => {
for (const className of Object.values(MyTheme)) {
element.classList.remove(className);
}
};
const applyStyle = (element: HTMLElement, className: string) => {
element.classList.add(className);
};
const WithThemeProvider = (Story, context) => {
useEffect(() => {
const body = window.document.body;
clearStyles(body);
applyStyle(body, context.globals.theme);
return () => {
clearStyles(body);
};
}, [context.globals.theme]);
return <Story />;
};
export const decorators = [WithThemeProvider];
I know it might feel "dirty" to work directly with body. But it is suggested way for instance addons decorator.

Customize multiple mui components

From MUI's docs you have the ability to customize a component. But is there a way to customize multiple components?
Say I want to customize MuiPaper and MuiList with the same styles.
E.g of customizable components:
const theme = createTheme({
components: {
// Name of the component
MuiPaper: {
defaultProps: {
// The props to change the default for.
backgroundColor: '#101010',
},
},
},
});
there are multiple ways to customize the default props. please check below I have added three ways to customize the components. also you can add more components to it.
theme.js
const mytheme = {
components: {
MuiPaper: {
styleOverrides: {
root: ({ theme }) => ({ // using with theme
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
}),
},
},
MuiList : {
styleOverrides: {
root: { // adding direct CSS properties with screensize condition.
'#media (min-width:600px)': {
minHeight: '4.5rem',
backgroundColor: '#101010',
},
},
},
},
MuiButton: {
styleOverrides: {
root: ({ ownerState, theme }) => ({ // changing only 'contained' variant or adding new variant.
textTransform: 'capitalize',
...(ownerState.variant === 'contained' && {
color: theme.palette.primary.contrastText,
backgroundColor: theme.palette.primary.light,
}),
}),
},
},
},
};
export default mytheme;
app.js
const App = () => {
<ThemeProvider theme={createTheme(mytheme)}>
...
</ThemeProvider>
}
export default App;

Theme override support for custom components

After the migration to mui v5 for react-admin, we realized that supporting theme overrides for our custom components seems to require more code than we expected. As it looks that this could be handled by the styled API, I would like to know if this is really required.
Here's an example of our Navigation link:
const PREFIX = 'RaMenuItemLink';
export const MenuItemLinkClasses = {
root: `${PREFIX}-root`,
active: `${PREFIX}-active`,
icon: `${PREFIX}-icon`,
};
const StyledMenuItem = styled(MenuItem, {
name: PREFIX,
// Why do I have to do this?
overridesResolver: (props, styles) => [
{ [`&.${MenuItemLinkClasses.active}`]: styles.active },
{ [`& .${MenuItemLinkClasses.icon}`]: styles.icon },
styles.root,
],
})(({ theme }) => ({
[`&.${MenuItemLinkClasses.root}`]: {
color: theme.palette.text.secondary,
},
[`&.${MenuItemLinkClasses.active}`]: {
color: theme.palette.text.primary,
},
[`& .${MenuItemLinkClasses.icon}`]: { minWidth: theme.spacing(5) },
}));
In your case, I think that I would start to simplify the code to:
const PREFIX = 'RaMenuItemLink';
export const MenuItemLinkClasses = {
root: `${PREFIX}-root`,
active: `Mui-active`,
icon: `${PREFIX}-icon`,
};
const StyledMenuItem = styled(MenuItem, {
name: PREFIX,
overridesResolver: (props, styles) => [
styles.root,
{ [`&.${MenuItemLinkClasses.active}`]: styles.active },
{ [`& .${MenuItemLinkClasses.icon}`]: styles.icon },
],
})(({ theme }) => ({
color: theme.palette.text.secondary,
[`&.${MenuItemLinkClasses.active}`]: {
color: theme.palette.text.primary,
},
[`& .${MenuItemLinkClasses.icon}`]: { minWidth: theme.spacing(5) },
}));
The overridesResolver property is meant to resolve this object:
const theme = {
components: {
[PREFIX]: {
styleOverrides: /* this object, it's the 'styles' arg of overridesResolver */,
},
},
};

Change ripple effect duration in MUI React

I want to modify ripple effect duration in theme file
I've tried things like
const theme = createMuiTheme({
props: {
MuiButtonBase: {
TouchRippleProps: {
animationDuration: '5s',
transitionDuration: '5s',
},
classes: {
root: 'CustomizeTouchRipple'
}
},
}
})
Not working.. but class is added
Edit:
I found its a constant in TouchRipple component
https://github.com/mui-org/material-ui/blob/c06a88d24235685dd769c1a3df82152ded17a6ca/packages/material-ui/src/ButtonBase/TouchRipple.js#L8
From the source, the class name where the animationDuration is set is MuiTouchRipple-rippleVisible. You just need to override that value:
V5
<Button
sx={{
'&& .MuiTouchRipple-rippleVisible': {
animationDuration: '200ms',
},
}}
>
V4
const theme = createTheme({
overrides: {
MuiButton: {
root: {
'& .MuiTouchRipple-rippleVisible': {
animationDuration: '200ms',
},
},
},
// if you want to change the ripple duration of all components that have ripple
// effect (e.g. Button, CardActionArea, FAB...)
MuiTouchRipple: {
rippleVisible: {
animationDuration: '200ms',
},
},
},
});

react-select change singleValue color based on options

I would like to modify the 'selected' singleValue color in my styles object based on the options that are provided.
const statusOptions = [
{ value: "NEW", label: i18n._(t`NEW`) },
{ value: "DNC", label: i18n._(t`DNC`) },
{ value: "WON", label: i18n._(t`WON`) },
{ value: "LOST", label: i18n._(t`LOST`) },
];
For example, if the option selected in "NEW", I want the font color to be red, if it's "WON", then green, and so on. I am having trouble putting an if statement into the styles object. I see that its simple to put a ternary statement in, but how to you add more "complex" logic?
const customStyles = {
...
singleValue: (provided) => ({
...provided,
color: 'red' <----- something like if('NEW') { color: 'green' } etc..
})
};
Use an style map object:
import React from 'react';
import Select from 'react-select';
const statusOptions = [
{ value: 'NEW', label: 'NEW' },
{ value: 'DNC', label: 'DNC' },
{ value: 'WON', label: 'WON' },
{ value: 'LOST', label: 'LOST' },
];
const styleMap = {
NEW: 'red',
DNC: 'blue',
};
const colourStyles = {
singleValue: (provided, { data }) => ({
...provided,
color: styleMap[data.value] ? styleMap[data.value] : 'defaultColor',
// specify a fallback color here for those values not accounted for in the styleMap
}),
};
export default function SelectColorThing() {
return (
<Select
options={statusOptions}
styles={colourStyles}
/>
);
}

Resources