Where is color property defined when creating a custom theme for Material-UI - material-ui

I am following the example here [1] to create a custom theme using Material-UI. On Line 10 in App.js [2] it references color="textSecondary", can someone explain where the value textSecondary comes from?
I was able to get the example to work using:
style={{ color: theme.palette.secondary.light }}
but I'd prefer to be able to use the shorter syntax reference.
Full App.js code below:
import React from 'react';
import Container from '#material-ui/core/Container';
import Typography from '#material-ui/core/Typography';
import Box from '#material-ui/core/Box';
import ProTip from './ProTip';
import Link from '#material-ui/core/Link';
import theme from './theme';
function MadeWithLove() {
return (
<Typography variant="body2" style={{ color: theme.palette.secondary.light }} align="center">
{'Built with love by the '}
<Link color="inherit" href="https://material-ui.com/">
Material-UI
</Link>
{' team.'}
</Typography>
);
}
export default function App() {
return (
<Container maxWidth="sm">
<Box my={4}>
<Typography variant="h4" component="h1" gutterBottom>
Create React App v4-beta example
</Typography>
<ProTip />
<MadeWithLove />
</Box>
</Container>
);
}
My theme.js file is:
import { createMuiTheme } from '#material-ui/core/styles';
const theme = createMuiTheme({
palette: {
primary: {
light: '#6fbf73',
main: '#4caf50',
dark: '#357a38',
contrastText: '#fff',
},
secondary: {
light: '#5464c0',
main: '#2a3eb1',
dark: '#1d2b7b',
contrastText: '#000',
},
},
});
export default theme;
[1] https://github.com/mui-org/material-ui/tree/master/examples/create-react-app
[2] https://github.com/mui-org/material-ui/blob/master/examples/create-react-app/src/App.js#L10

If you have a look at the documentation for Typography component, you can provide several options for the color prop:
name: color
type: enum: 'initial', 'inherit', 'primary', 'secondary', 'textPrimary', 'textSecondary', 'error'
default: 'initial'
description: The color of the component. It supports those theme colors that make sense for this component.
textSecondary is defined here: https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Typography/Typography.js#L92 as
theme.palette.text.secondary

Related

material text field label not copyable?

I am using MUI's Text Field component and found there's literally no way to copy the label contents. Is there a way to copy the label somehow?
See the demo here: https://codesandbox.io/s/4ou0l7?file=/demo.tsx
Thanks
It is because material UI is disabling the label selection using CSS.
You can enable it back in a few ways. You can enable it for a certain field or across all of them using the material UI theme override ability.
In order to enable label selection only to one field, you have pass an additional prop to your TextField: InputLabelProps={{ sx: { userSelect: "text" } }}
And here I have provided you with the second way to do that for all the text fields:
import * as React from "react";
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
import { createTheme, ThemeProvider } from "#mui/material/styles";
const theme = createTheme({
components: {
MuiInputLabel: {
styleOverrides: {
root: {
userSelect: "text"
}
}
}
}
});
const StateTextFields = () => {
const [name, setName] = React.useState("Cat in the Hat");
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
return (
<Box
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
>
<TextField
id="outlined-name"
label="Name"
value={name}
onChange={handleChange}
/>
<TextField
id="outlined-uncontrolled"
label="Uncontrolled"
defaultValue="foo"
/>
</Box>
);
};
export default () => (
<ThemeProvider theme={theme}>
<StateTextFields />
</ThemeProvider>
);
Of course, you can extract this ThemeProvider into a separate file and wrap with it the whole project, not only this file. It is combined just for the example.
I found a way that this can be done using the helperText and my solution is more of a hack. I am using the helperText and positioning it where the label was used to be, giving it a background and bringing it to front using z-index.
Also you can either choose to use the label or replace it with the placeholder depending if you are happy with the animation.
Here is a codesandbox based on your code in case you need it.
<TextField
id="outlined-name"
label="Name"
// placeholder="Name"
value={name}
onChange={handleChange}
helperText="Name"
sx={{
"& .MuiFormHelperText-root": {
top: "-11px",
position: "absolute",
zIndex: "1",
background: "white",
padding: "0 4px",
}
}}
/>

How can I override CSSfor material UI TextField component?

I am using Material UI's Autocomplete/TextField and I want to override its default CSS on hover and when the text field is in focus state.
Default CSS:
Image for default CSS in focused state
I want to change this blue colour when input box is in focus state.
I have tried using ThemeProvider/createTheme hook but it is not helping. Below is the code for createTheme:
import { ThemeProvider, createTheme } from "#mui/material/styles";
const overrideTheme = createTheme({
overrides: {
MuiInput: {
root: {
"&$focused": {
borderColor: "red",
},
},
},
},
});
export default function AutocompleteComponent() {
return (
<ThemeProvider theme={overrideTheme}>
<Autocomplete
classes={classes}
freeSolo
id="free-solo-2-demo"
options={
autocompleteResult ? top100Films.map((option) => option.title) : []
}
renderInput={(params) => (
<TextField
variant="outlined"
{...params}
placeholder="Search..."
InputProps={{
...params.InputProps,
type: "search",
classes: {
root: classes.root,
notchedOutline: classes.notchedOutline,
},
className: classes.input,
endAdornment: false,
}}
/>
)}
/>
</ThemeProvider>
);
}
You have to use the browser dev tools to identify the slot for the component you want to override. Once that's done, you write a CSS file with the class you want to change.
To force the class you can use :
!important
file : styles.css
exemple:
.css-1q6at85-MuiInputBase-root-MuiOutlinedInput-root{
border-radius: 50px!important;
}

MUI: The `styles` argument provided is invalid. function without a theme in the context. One of the parent elements needs to use a ThemeProvider

I am trying to build a table using mui-datatables in mui v5
What does this error mean?
index.js:1 MUI: The styles argument provided is invalid.
You are providing a function without a theme in the context.
One of the parent elements needs to use a ThemeProvider.
NewsWatch.js
import React from "react";
import MUIDataTable from "mui-datatables";
const columns = ["Name", "Company", "City", "State"];
const data = [
["Joe James", "Test Corp", "Yonkers", "NY"],
["John Walsh", "Test Corp", "Hartford", "CT"],
["Bob Herm", "Test Corp", "Tampa", "FL"],
["James Houston", "Test Corp", "Dallas", "TX"],
];
const options = {
filterType: "checkbox",
};
const NewsTable = () => {
return (
<>
<MUIDataTable
title={"Employee List"}
data={data}
columns={columns}
options={options}
/>
</>
);
};
export default NewsTable;
MUI-Datatables lib depends heavily on #mui or(as known previously #material-ui), and it needs two important things to exist
Wrap your root components/pages with a theme provider from MUI
import { ThemeProvider } from "#mui/material";
import { responsiveFontSizes, createTheme } from "#mui/material";
export const themeOptions: ThemeOptions = {
// ... any theme customiztion you can write here
}
let theme = responsiveFontSizes(createTheme(themeOptions));
and wrap the root with the provider
<ThemeProvider theme={theme}>
{children}
</ThemeProvider>
Install the icons' library in your project(because it internally needs it)
yarn add #mui/icons-material # or npm i #mui/icons-material

Material UI Display property not hiding content

Material UI explains Display in their docs as a way to Quickly and responsively toggle the display value of components!
I have an icon that i want it to be hidden on xs. I am trying
display={{ xs: 'none', sm: 'block' }} its not working.
I am trying display='none' just to see if it hides, also not working. If i set a className={classes.icon} and then i create an icon class in useStyles
icon: {
display: none,
},
the icon is hidden.
The behaviour is making me go crazy but am sure i am missing a concept on how these things rended or something is overriding the behaviour.
Also i dont know how to use display={{ xs: 'none', sm: 'block' }} inside the useStyle as double brackets are not allowed there
Here is full code:
const useStyles = makeStyles((theme) => ({
icon: {
paddingRight: 10,
color: 'white',
display: 'none', //setting this hides the icon
},
}
<Grid item container xs={12}>
<AccountBalanceIcon fontSize='large' className={classes.icon} display={{ xs: 'none', sm: 'block' }}/>
</Grid>
You can hide the AdbIcon when the screen's width becomes xs by using [theme.breakpoints.only("xs")] in the useStyles hook :-
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import {
Box
} from '#material-ui/core';
import AdbIcon from '#material-ui/icons/Adb';
const useStyles = makeStyles((theme) => ({
icon: {
color: 'red',
[theme.breakpoints.only("xs")]: {
display: "none",
},
}
}));
export default function ButtonSizes() {
const classes = useStyles();
return (
<AdbIcon
fontSize="large"
className={classes.icon}
/>
);
}
Read about all the breakpoint queries that are given by material-ui here
'display' property belongs to 'Box' component, not the Icon component.. I.e. the Icon must be wrapped in the Box component. The following sample works:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import {
Box
} from '#material-ui/core';
import AdbIcon from '#material-ui/icons/Adb';
const useStyles = makeStyles((theme) => ({
icon: {
color: 'red',
//display: 'none',
}
}));
export default function ButtonSizes() {
const classes = useStyles();
return (
<Box
display="block"
//display="none"
>
<AdbIcon
fontSize="large"
className={classes.icon}
/>
</Box>
);
}

Material UI RTL

The RTL demo provided in material ui guides seems does not work for components.
As they said in the Right-to-left guide internally they are dynamically enabling jss-rtl plugin when direction: 'rtl' is set on the theme but in the demo only the html input is rtl and TextField isn't.
Here's the demo code from https://material-ui-next.com/guides/right-to-left/#demo
import React from 'react';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import TextField from 'material-ui/TextField';
const theme = createMuiTheme({
direction: 'rtl', // Both here and <body dir="rtl">
});
function Direction() {
return (
<MuiThemeProvider theme={theme}>
<div dir="rtl">
<TextField label="Name" />
<input type="text" placeholder="Name" />
</div>
</MuiThemeProvider>
);
}
export default Direction;
Once you have created a new JSS instance with the plugin, you need to
make it available to all components in the component tree. JSS has a
JssProvider component for this:
import { create } from 'jss';
import rtl from 'jss-rtl';
import JssProvider from 'react-jss/lib/JssProvider';
import { createGenerateClassName, jssPreset } from '#material-ui/core/styles';
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
// Custom Material-UI class name generator.
const generateClassName = createGenerateClassName();
function RTL(props) {
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
{props.children}
</JssProvider>
);
}