Material UI Stepper 4 Different Connector Color at 4 different steps - reactjs

I was wondering if it was possible to have multiple connector colors with a different one at each step. So the first connector would be blue the one after that would be green then yellow then red all while keeping the previous color the same. The closest have gotten changes all previous colors to the same color. Is there a way to keep the previous the same color?
The Example I linked only has connectors of one color
Example of Stepper with Connector only one color

This answer shows how to change the color of individual StepIcons
Given that you have a function outside the component rendering the Stepper that returns an array containing the step labels and their corresponding icon color:
function getStepLabels() {
return [
{
label: "Select campaign settings",
color: "red"
},
{
label: "Create an ad group",
color: "blue"
},
{
label: "Create an ad",
color: "green"
}
];
}
you can generate classes for each label icon using material-ui's Hook API via the makeStyles function (if you are using a class component you might want to take a look at the withStyles function):
const useIconStyles = makeStyles(
(() => {
return getStepLabels().reduce((styles, step, index) => {
styles[index] = { color: `${step.color} !important` };
return styles;
}, {});
})()
);
and add the generated hook to your component: const iconClasses = useIconStyles();
When rendering the stepper you can make use of the generated classes like this:
[...]
<Step key={label} {...stepProps}>
<StepLabel
{...labelProps}
StepIconProps={{ classes: { root: iconClasses[index] } }}
>
{label}
</StepLabel>
</Step>
[...]
Here is a working example:

If you take a closer look at the render output of the Stepper component you will notice that StepLabel and StepConnector are sibling components. This means you can select a specific connector with the CSS :nth-child() pseudo-class. If you want to select the connector after the first step's label you would use the selector :nth-child(2). For the connector after second step's label it would be :nth-child(4).
If you have an array of step labels like this:
[
{
label: "First label",
connectorColor: "red"
},
{
label: "Second label",
connectorColor: "green"
},
{
label: "Third label"
}
];
you can pass this array to a material-ui style hook created by the makeStyles function and dynamically generate all the different CSS selectors necessary to style each connector:
const useConnectorStyles = makeStyles({
stepConnector: steps => {
const styles = {};
steps.forEach(({ connectorColor }, index) => {
if (index < steps.length - 1) {
styles[`&:nth-child(${2 * index + 2})`] = { color: connectorColor };
}
});
return styles;
},
stepConnectorLine: {
borderColor: "currentColor"
}
});
Now use the generated style hook in your component: const connectorClasses = useConnectorStyles(stepLabels); and provide the connector prop to the Stepper component:
connector={
<StepConnector
classes={{
root: connectorClasses.stepConnector,
line: connectorClasses.stepConnectorLine
}}
/>
}
Here is a working example:

Related

Customizing how Chakra components use the color scheme

Chakra allows you to define and pass color schemes to components, but as far as I've been able to tell, it doesn't allow you to customize how those color schemes are used. For example, the button component will use the 500 shade of whichever color scheme you pass in as its default background and a darker shade for the hover background. Suppose I wanted to invert these though, I'm hoping to do something like...
Button: {
baseStyle: {
bg: colorScheme.700,
_hover: {
bg: colorScheme.500,
},
},
}
Is there any way to define how color schemes are used for a given component? It seems like to override the default shading choices, you have to override all colors explicitly, but hopefully I'm missing something.
You can explore Chakra's source to see how they do this for their components. They're not coded any differently than how you can define your own styles.
We know Buttons utilize the colorScheme prop, so I looked in the code to find out how they apply the prop.
Their core component styles are defined in a base theme and Buttons are no different. The source shows various examples of variants being used, but here's the ghost variant definition:
const variantGhost = defineStyle((props) => {
const { colorScheme: c, theme } = props
if (c === "gray") {
return {
color: mode(`inherit`, `whiteAlpha.900`)(props),
_hover: {
bg: mode(`gray.100`, `whiteAlpha.200`)(props),
},
_active: { bg: mode(`gray.200`, `whiteAlpha.300`)(props) },
}
}
const darkHoverBg = transparentize(`${c}.200`, 0.12)(theme)
const darkActiveBg = transparentize(`${c}.200`, 0.24)(theme)
return {
color: mode(`${c}.600`, `${c}.200`)(props),
bg: "transparent",
_hover: {
bg: mode(`${c}.50`, darkHoverBg)(props),
},
_active: {
bg: mode(`${c}.100`, darkActiveBg)(props),
},
}
})
As you can see, there's something special about this definition (in addition to some helper functions being utilized).
In all of Chakra's examples, they use static objects to override styles. But that's not a necessity. You can use this defineStyle function to return a dynamic object based not only on the current colorMode, but the colorScheme passed to the component! defineStyle can be used on your baseStyle property, as well as your variants and sizes properties too.
You can access defineStyle by importing it from #chakra-ui/react like this:
import { defineStyle } from '#chakra-ui/react'
const theme = extendTheme({
components: {
Button: defineStyleConfig({
baseStyle: defineStyle(props => {
return {
color: `${props.colorScheme}.500`
}
}),
}),
},
})
It's not necessary, but you can get fancier, like in the Chakra source, and use the mode helper function to select different colors for your light and dark mode.

pass material ui styles to component - react

I am using a functional component with React, I need to show SVG Icon based on state and I want to load the relevant icon
so the parent will show only call :
<icon classes:... , state..></icon>
1- how can I pass style and if it does not exist and use a default style in the child?
now I have smth like in the parent :
... createStyle
IconSuccess: {
fontSize: 20,
width: 20,
},
IconWarning: {
fontSize: 20,
width: 20,
},
but i want smth like :
icon:{
width:..
font ..
warning: { color}
success: { color}
}
then
<IconChild state={state} classes={{ icon: itemStyle.icon}} />
this is work only if I pass specific style like:
<IconChild state={state} classes={{ iconWarning: itemStyle.iconWarning}} />
then in the childCOmponent I am doing smth like:
const classes = useStyles(props);
if( props.state == 1){
return <className={`${classes.iconWarning}`} />
}
else{
return <className={`${classes.iconSuccess}`} />
}
so basically I am trying to understand how to create a really generic component that I can use and pass and that need a state to choose the specific icon and also from specific class
do I need HOC ? or different approach
As I understand, you want to:
Reuse some common properties like width and fontSize.
Custom render other properties like color.
Then this is my approach:
First, make new style for commonly used properties.
Secondly, create new styles for conditional use of each state.
Last, use something like classnames to combine all classes.
So the main idea here is: instead of using one class for each item, now using two classes for each one. That's it!
const useStyles = withStyles({
commonProperty: {
fontSize: '20px',
width: '20px',
},
successOnlyProperty: {
color: 'green'
},
warningOnlyProperty: {
color: 'orange'
},
});

Remove (or at least hide) card on react-admin List

I want to get rid of the Card on the background react-admin's List (v3.4.2). I get the desired effect if I define a string on the component property:
<List component={"some string"}/>
But this spams the console with an error:
And I don't want to have that error. On top of that, I think I shouldn't be changing the component property (I can't find it on the official docs).
The code should be the following: https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/list/List.js
How should I do this? Is it possible to pass a style? Is there any component that works out of the box? Or should I just go custom?
You can hide the background using styling:
import { makeStyles } from '#material-ui/core/styles'
const useListStyles = makeStyles(theme => ({
content: {
boxShadow: 'none',
backgroundColor: 'inherit',
},
main: {
// backgroundColor: 'red',
},
root: {
// backgroundColor: 'red',
},
}))
const MyList = (props) => {
const classes = useListStyles()
return (
<List classes={classes} {...props} >
...
</List>
)
}

Set dynamic style for Checkbox in Ant Design

Is it possible to set tick container's style backgroundColor and borderColor in Checkbox dynamically from JSX?
I can do it with CSS/LESS, but I need to set specific color based on data from API.
Example:
.
If the colors from API are completely unknown to you until the time of running, then there is no way to accomplish the task with Antd library. Because the class you need to update colors for (.ant-checkbox-checked .ant-checkbox-inner) is nested inside the parent component , and can be changed only in your .less file.
As you can see in Rafael's example, you can only control the colors of the parent (.ant-checkbox-wrapper) from .js file.
On the other hand, if you know there will always be, let's say "#1890FF", "#FA8072", and "#008100" colors, you just don't know in what order, you can easily change the colors dynamically, by creating your logic around CSS classes. Which means you can map through all your checkboxes and give the classNames based on the color you get from API (getColor function). In order to do so, in your .js file import the data from API and define getColor function:
import React, { PureComponent } from "react";
import { Checkbox } from "antd";
export default class ColoredCheckboxes extends PureComponent {
getColor = color => {
let checkboxClassName = "checkbox-green";
if (color === "#FA8072") {
checkboxClassName = "checkbox-orange"
}
if (color === "#1890FF") {
checkboxClassName = "checkbox-blue"
}
return checkboxClassName;
};
render() {
const dataFromAPI = [
{
key: "first",
name: "First",
color: "#008100",
},
{
key: "second",
name: "Second",
color: "#FA8072",
},
{
key: "third",
name: "Third",
color: "#1890FF",
},
]
return (
<div>
{dataFromAPI.map(item => (
<div key={item.key}>
<Checkbox className={this.getColor(item.color)}>
{item.name}
</Checkbox>
</div>
))}
</div>
);
}
}
Then in your .less file reassign the colors for ".ant-checkbox-checked .ant-checkbox-inner" class originally coming from Antd Library:
.checkbox-green {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #008100;
border-color: #008100;
}
}
.checkbox-orange {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #FA8072;
border-color: #FA8072;
}
}
.checkbox-blue {
.ant-checkbox-checked .ant-checkbox-inner {
background-color: #1890FF;
border-color: #1890FF;
}
}
You just styled it, something like
<Checkbox
style={{
backgroundColor: data.backgroundColor,
borderColor : data.borderColor
}}
/>

Apply radiobutton color using styled-components in Material UI?

In the Material UI documents, they provided sample code to show how one can change the color of a Radiobutton.
const GreenRadio = withStyles({
root: {
color: green[400],
'&$checked': {
color: green[600],
},
},
checked: {},
})(props => <Radio color="default" {...props} />);
I would like to replicate this with styled-component instead i.e. const StyledRadio = styled(Radio) but I am not too familiar with the syntax such as the ampersand and the dollar sign - how can I do this?
When using styled components with MUI, the CSS is applied to the root class of the component. If you need to apply a more specific style, then you'll need to target the relevant class. In this case, you'll need to target the .Mui-checked class:
const StyledRadio = styled(Radio)`
color: ${green[400]};
&.Mui-checked {
color: ${green[600]};
}
`;
The MUI docs are really good in that they list the CSS classnames for each component. If you visit the API docs for the Radio component, you'll see the .Mui-checked class listed there (under the 'Global Styles' column).
Here's a working example in Code Sandbox: https://codesandbox.io/embed/styled-components-9pewl
Here's the appropriate styled-components syntax:
const GreenRadio = styled(Radio)`
color: ${green[400]};
&.Mui-checked {
color: ${green[600]};
}
`;
Related documentation: https://material-ui.com/customization/components/#pseudo-classes

Resources