Material-UI styling the button variant outlined - css

I'm new to Material UI and I'm struggling.
I have a button component
export default function TheButton(props: PropsWithChildren<Props>) {
const { className, hover, level,...rest } = props;
const classes = useStyles();
return (
<Button
{...rest}
className={clsx(classes.root, className, hover === 'contained' && classes.hoverContained)}
>
{props.children}
</Button>
);
}
From this component, I'd like to have two variants: contained and outlined. Here is my outlined button.
<TheButton
variant="outlined"
color="secondary"
>
secondary
</TheButton>
When the variant outlined is selected the button has the class Muibutton-outlined. I'd like to override this class to change the border (only in the outlined variant, so only on this class).
So far I've tried something like:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
'.MuiButton-outlinedSecondary':{
border:"2px solid red" ,
},
}
)
It doesn't work.

I have a similar setting, and I tried:
adding a class submit to my button component
<Button
type="submit"
variant="outlined"
disabled={isSaving || invalid || unchanged}
color="secondary"
className={classes.submit}
>
SAVE CHANGES
</Button>
since I have the submit class I can be more precise in my styling like so:
const useStyles = makeStyles({
submit: {
marginTop: padding.medium,
marginLeft: padding.small,
'&.MuiButton-outlinedSecondary': {
border: '1px solid pink',
},
},
});
Here is the result:
Material-ui button with pink border image

As long as I have used Ant design ui kit and I have overrided styles on its default style like this:
<Button type="primary" className={styles.custom_css}>click</Button>
This has done in react and custom_css class overrides its styles on default
This might can help you, if not please let me know

Related

How to change disabled MUI TextField text color?

I would have black text color, not default gray in the disabled TextField, tried this, based on this: https://stackoverflow.com/a/70943025/239219
<TextField
id="outlined-basic"
value={'https://git.responsive.software/my-app.git'}
fullWidth
size="small"
disabled
variant="filled"
inputProps={{ style: { color: 'black' } }}
/>
But this colors text when it is selected. I need black also for unselected text.
It is also interesting, why my attempt does not work. I guess MUI uses a textfield behind their customized solution. Then why the passed color attribute does not change attribute as in a normal css it would change?
You could add a style specifically if disabled=true. Like this:
// STYLES
export const StyledTextField = styled(TextField, {
shouldForwardProp: (props) => props !== 'disabled',
})<{ disabled: boolean }>(({ disabled }) => ({
color: disabled : 'black' ? 'pink',
}));
// IN THE COMPONENT
<StyledTextField
id="outlined-basic"
value={'https://git.responsive.software/my-app.git'}
fullWidth
size="small"
disabled
variant="filled"
inputProps={{ style: { color: 'black' } }}
/>
(shouldForwardProp makes sure the disabled prop isn't added to the DOM)
Alternatively...
TextField doesn't have a specific disabled class, but if you can change your code to use InputBase instead, you can utilize the disabled class. This CSS is applied when disabled=true in your component. https://mui.com/material-ui/api/input-base/#css
import { inputBaseClasses } from '#mui/material';
...
[`&.${inputBaseClasses.disabled}`]: {
color: 'black',
},

How do I change the underline of a material ui tab

I want to change the underline of:
I use material ui version 4.12.3
The code for creating my tabs is here:
function renderTabs(): JSX.Element {
return (
<Tabs className={classes.tabBar} value={activeTab} component={Paper} onChange={handleChange} centered>
{TABS.map((tab: string) => {
return (
<Tab
className={classes.tabButton}
key={`tab-${tab}`}
label={tab}
value={tab}
component={Link}
to={`${url}/${tab !== TABS[0] ? tab : ''}`}
/>
)
})}
</Tabs>
)
}
and in my tab_menu.style.ts I have the following code:
export default makeStyles(() =>
createStyles({
root: { width: '60%', margin: 'auto' },
tabBar: {},
tabButton: {},
})
)
I tried to change colors/background colors/text decorations in the tabBar as well as the tabButton, but the blue underline never changed.
How can I change the underline style?
As per material-UI documentation (Tab API, Tabs API) , you need to pass classes instead of className as a prop. Just write classes instead className.

How override Material UI Popover CSS classes in Select component in React

I am using Material UI Select component inside my React project.
I am trying to override the CSS class .MuiPaper-root and or .MuiMenu-list.
My Select component:
<Select
value={selectValue}
disableUnderline
onChange={handleChange}
css={styles.select}
>
{cities?.map((city) => {
return (
<MenuItem
key={city.value}
value={city.value}
css={styles.selectItem}
>
{city.label}
</MenuItem>
);
})}
</Select>
Below isn't working?
export default ({ theme }: StylesProps) => ({
select: css`
.MuiPaper-root {
background-color: red;
}
`,
});
According to the doc, there are several ways that we can modify styles in MUI. In order to change MuiPaper, we can take advantage of createMuiTheme and create a theme as below to override MuiPaper:
const theme = createMuiTheme({
overrides: {
MuiPaper: {
root: {
color: "white"
}
}
}
});
Then, we need to pass it as a theme prop to the ThemeProvider component:
<ThemeProvider theme={theme}>
//***Other part of your code***//
</ThemeProvider>
when it comes to changing MenuProps in the Select component, we can use a property called MenuProps in the Select component(description in doc)
First, I created a list style in useStyles:
const useStyles = makeStyles((theme) => ({
//other classes//
list: {
backgroundColor: "blue"
}
}));
and then passed it as a MenuProp property to the select component:
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
onChange={handleChange}
MenuProps={{ classes: { list: classes.list } }}
>
//***other part of your code***//
</Select>
Here is a codesandbox example that I've created for this example. In the Muipaper modification, I changed the color of the text to white. And in the MenuProps changed the background color to blue.

How to style Material UI's Tab component label?

I'm looking for a way to customize the color of the text inside the Tab component but at the same time retaining the ability for it to be colored over when selected as an active Tab.
Example code:
<Tabs centered onChange={handleChange} value={value} textColor={'secondary'} indicatorColor={'secondary'}>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
</Tabs>
The above code will result in the change of the text color BUT when the Tab becomes active, it won't be overridden.
If it helps, I'm also using styled-components for ease of use.
You can use the makeStyles export of material-ui to create your custom class for the label
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
customLabelColor: {
color: "#fff"
}
});
export default function App() {
const classes = useStyles();
return (
...
<Tab
label={"Hello There"}
classes={{
textColorSecondary: classes.customLabelColor
}}
/>
...
);
}
CodeSandBox: https://codesandbox.io/s/quirky-kowalevski-xzf7g?file=/src/App.js
Refer here for other methods on how to override the CSS for Tab.
On the same reference I linked, have a look at the textColorSecondary rule name. This is specific to your question since you are using textColor="secondary" on your parent component Tabs

Dynamically Styled Button in React Native using Styled Components

A Button component is generally comprised of the Text element wrapped with a TouchableHighlight (or other touchable). I'm trying to create a Button component styled using styled-components, but am having trouble getting my style to respond dynamically to props.
Button Component
Below, I've created a Button component similar to the Adapting based on props example found in the styled-component docs.
import React from 'react';
import { Text, TouchableHighlight } from 'react-native';
import styled from 'styled-components/native';
const colors = {
accent: '#911',
highlight: '#D22',
contrast: '#FFF',
}
const Label = styled.Text`
color: ${props => !props.outline ? colors.contrast : colors.accent};
font-weight: 700;
align-self: center;
padding: 10px;
`
const ButtonContainer = styled.TouchableHighlight`
background-color: ${props => props.outline ? colors.contrast : colors.accent};
width: 80%;
margin-top: 5px;
border-color: ${colors.accent};
border-width: 2px;
`
const Button = (props) => {
return (
<ButtonContainer
onPress={props.onPress}
underlayColor={colors.highlight}
>
<Label>
{props.children}
</Label>
</ButtonContainer>
);
};
export default Button;
Button Usage
After importing it, I'm using the button like this...
<Button
outline
onPress={() => console.log('pressed')}>
Press Me!
</Button>
Expected Result
And so, I would expect my button to look like this...
Actual Result
But instead it looks like this...
What I've done to troubleshoot so far
When I inspect using react-devtools, I can see that the outline prop is being passed down to the Button component.
But the prop is not passed down to any of it's children
The Passed Props part of the docs state, "styled-components pass on all their props", but I guess not all the way down?
My Question
What do I need to change so that I can dynamically style my Button based on it's props?
Here you have:
const Button = (props) => {
return (
<ButtonContainer underlayColor={colors.highlight}>
<Label>
{props.children}
</Label>
</ButtonContainer>
);
};
If ButtonContainer was a normal React component, you wouldn't expect the props passed to Button to be automatically passed to ButtonContainer. You'll have to do <ButtonContainer underlayColor={colors.highlight} {...props} /> to do it.
Actually ButtonContainer is a normal React component, the only difference is you pre-apply some styles using an HOC.
Also if you desugar this to a React.createElement call, you can see there's no way props can be passed automatically, because a Function's arguments don't get passed automatically to the function calls inside it.
const Button = (props) => {
return React.createElement(ButtonContainer, { underlayColor: colors.highlight }, ...);
};
It's nothing specific to styled-components. You just have to pass down the props yourself to ButtonContainer, as well as to Label.
So you'd rewrite your code to:
const Button = (props) => {
return (
<ButtonContainer underlayColor={colors.highlight} onPress={props.onPress} outline={props.outline}>
<Label outline={props.outline}>
{props.children}
</Label>
</ButtonContainer>
);
};
Technically a React component can pass down props to it's children, so ButtonContainer could pass them down to Label using React.Children and React.cloneElement APIs. But ButtonContainer doesn't do that for obvious reasons, e.g. you'd not want underlayColor and onPress to be passed to Label automatically. It would cause a lot of confusing bugs.

Resources