# Mui Material > Every Material UI component available so far. --- # Source: https://mui.com/material-ui/all-components.md # Material UI components Every Material UI component available so far. Material UI aims to provide building blocks for developers to create great user interfaces using the Material Design guidelines as a reference, which we strive to follow where practical. The library doesn't necessarily implement the exact specs of every component or feature—where official guidelines are incomplete or contradictory, maintainers apply common sense along with the latest standards in web development. ## Inputs ## Data display ## Feedback ## Surface ## Navigation ## Layout ## Lab ## Utils --- # Source: https://mui.com/material-ui/guides/api.md # API design approach We have learned a great deal regarding how Material UI is used, and the v1 rewrite allowed us to completely rethink the component API. > API design is hard because you can make it seem simple but it's actually deceptively complex, or make it actually simple but seem complex. > [@sebmarkbage](https://x.com/sebmarkbage/status/728433349337841665) As Sebastian Markbage [pointed out](https://2014.jsconf.eu/speakers/sebastian-markbage-minimal-api-surface-area-learning-patterns-instead-of-frameworks.html), no abstraction is superior to wrong abstractions. We are providing low-level components to maximize composition capabilities. ## Composition You may have noticed some inconsistency in the API regarding composing components. To provide some transparency, we have been using the following rules when designing the API: 1. Using the `children` prop is the idiomatic way to do composition with React. 2. Sometimes we only need limited child composition, for instance when we don't need to allow child order permutations. In this case, providing explicit props makes the implementation simpler and more performant; for example, the `Tab` takes an `icon` and a `label` prop. 3. API consistency matters. ## Rules Aside from the above composition trade-off, we enforce the following rules: ### Spread Props supplied to a component which are not explicitly documented are spread to the root element; for instance, the `className` prop is applied to the root. Now, let's say you want to disable the ripples on the `MenuItem`. You can take advantage of the spread behavior: ```jsx ``` The `disableRipple` prop will flow this way: [`MenuItem`](/material-ui/api/menu-item/) > [`ListItem`](/material-ui/api/list-item/) > [`ButtonBase`](/material-ui/api/button-base/). ### Native properties We avoid documenting native properties supported by the DOM like [`className`](/material-ui/customization/how-to-customize/#overriding-styles-with-class-names). ### CSS Classes All components accept a [`classes`](/material-ui/customization/how-to-customize/#overriding-styles-with-class-names) prop to customize the styles. The classes design answers two constraints: to make the classes structure as simple as possible, while sufficient to implement the Material Design guidelines. - The class applied to the root element is always called `root`. - All the default styles are grouped in a single class. - The classes applied to non-root elements are prefixed with the name of the element, for example `paperWidthXs` in the Dialog component. - The variants applied by a boolean prop **aren't** prefixed, for example the `rounded` class applied by the `rounded` prop. - The variants applied by an enum prop **are** prefixed, for example the `colorPrimary` class applied by the `color="primary"` prop. - A variant has **one level of specificity**. The `color` and `variant` props are considered a variant. The lower the style specificity is, the simpler it is to override. - We increase the specificity for a variant modifier. We already **have to do it** for the pseudo-classes (`:hover`, `:focus`, etc.). It allows much more control at the cost of more boilerplate. Hopefully, it's also more intuitive. ```js const styles = { root: { color: green[600], '&$checked': { color: green[500], }, }, checked: {}, }; ``` ### Nested components Nested components inside a component have: - their own flattened props when these are key to the top level component abstraction, for instance an `id` prop for the `Input` component. - their own `xxxProps` prop when users might need to tweak the internal render method's subcomponents, for instance, exposing the `inputProps` and `InputProps` props on components that use `Input` internally. - their own `xxxComponent` prop for performing component injection. - their own `xxxRef` prop when you might need to perform imperative actions, for instance, exposing an `inputRef` prop to access the native `input` on the `Input` component. This helps answer the question ["How can I access the DOM element?"](/material-ui/getting-started/faq/#how-can-i-access-the-dom-element) ### Prop naming - **Boolean** - The default value of a boolean prop should be `false`. This allows for better shorthand notation. Consider an example of an input that is enabled by default. How should you name the prop that controls this state? It should be called `disabled`: ```jsx ❌ ``` - If the name of the boolean is a single word, it should be an adjective or a noun rather than a verb. This is because props describe _states_ and not _actions_. For example an input prop can be controlled by a state, which wouldn't be described with a verb: ```jsx const [disabled, setDisabled] = React.useState(false); ❌ ``` ### Controlled components Most controlled components are controlled by the `value` and the `onChange` props. The `open` / `onClose` / `onOpen` combination is also used for displaying related state. In the cases where there are more events, the noun comes first, and then the verb—for example: `onPageChange`, `onRowsChange`. :::info - A component is **controlled** when it's managed by its parent using props. - A component is **uncontrolled** when it's managed by its own local state. Learn more about controlled and uncontrolled components in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ### boolean vs. enum There are two options to design the API for the variations of a component: with a _boolean_; or with an _enum_. For example, let's take a button that has different types. Each option has its pros and cons: - Option 1 _boolean_: ```tsx type Props = { contained: boolean; fab: boolean; }; ``` This API enables the shorthand notation: ` ); } const appTheme2 = createTheme({ ...brandedTokens, palette: { ...brandedTokens.palette, primary: { main: '#ffa726', }, }, components: { ...brandedComponents, MuiButton: { defaultProps: { ...brandedComponents?.MuiButton?.defaultProps, variant: 'outlined', }, styleOverrides: { root: [ brandedComponents?.MuiButton?.styleOverrides?.root, ({ theme }) => ({ color: theme.palette.primary.dark, }), ], }, }, }, }); function App2() { return ( ); } export default function ExtensibleThemes() { return ( ); } ``` --- # Source: https://mui.com/material-ui/discover-more/changelog.md # Changelog Material UI follows Semantic Versioning 2.0.0. All notable changes of the current major version are described in the [CHANGELOG.md file](https://github.com/mui/material-ui/blob/HEAD/CHANGELOG.md). Changes of older versions are described in the [CHANGELOG.old.md file](https://github.com/mui/material-ui/blob/HEAD/CHANGELOG.old.md) --- # Source: https://mui.com/material-ui/customization/color.md # Color Convey meaning through color. Out of the box you get access to all colors in the Material Design guidelines. The Material Design [color system](https://m2.material.io/design/color/) can be used to create a color theme that reflects your brand or style. ## Picking colors ### Official color tool The Material Design team has also built an awesome palette configuration tool: [material.io/resources/color/](https://m2.material.io/inline-tools/color/). This can help you create a color palette for your UI, as well as measure the accessibility level of any color combination. Official color tool

The output can be fed into `createTheme()` function: ```js import { createTheme } from '@mui/material/styles'; const theme = createTheme({ palette: { primary: { light: '#757ce8', main: '#3f50b5', dark: '#002884', contrastText: '#fff', }, secondary: { light: '#ff7961', main: '#f44336', dark: '#ba000d', contrastText: '#000', }, }, }); ``` ### Playground To test a [material.io/design/color](https://m2.material.io/design/color/) color scheme with the Material UI documentation, simply select colors using the palette and sliders below. Alternatively, you can enter hex values in the Primary and Secondary text fields. ```jsx import * as React from 'react'; import PropTypes from 'prop-types'; import { rgbToHex, useTheme } from '@mui/material/styles'; import * as colors from '@mui/material/colors'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import Input from '@mui/material/Input'; import Radio from '@mui/material/Radio'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; import CheckIcon from '@mui/icons-material/Check'; import Slider from '@mui/material/Slider'; import { capitalize } from '@mui/material/utils'; import { resetDocsColor, setDocsColors } from 'docs/src/BrandingCssVarsProvider'; import ColorDemo from './ColorDemo'; const defaults = { primary: '#2196f3', secondary: '#f50057', }; const hues = [ 'red', 'pink', 'purple', 'deepPurple', 'indigo', 'blue', 'lightBlue', 'cyan', 'teal', 'green', 'lightGreen', 'lime', 'yellow', 'amber', 'orange', 'deepOrange', ]; const shades = [ 900, 800, 700, 600, 500, 400, 300, 200, 100, 50, 'A700', 'A400', 'A200', 'A100', ]; const TooltipRadio = React.forwardRef(function TooltipRadio(props, ref) { const { 'aria-labelledby': ariaLabelledBy, 'aria-label': ariaLabel, inputProps, ...other } = props; return ( ); }); TooltipRadio.propTypes = { // possibly opaque identifier 'aria-label': PropTypes.oneOfType([PropTypes.string, PropTypes.object]), 'aria-labelledby': PropTypes.oneOfType([PropTypes.string, PropTypes.object]), inputProps: PropTypes.object, }; function ColorTool() { const theme = useTheme(); const [state, setState] = React.useState({ primary: defaults.primary, secondary: defaults.secondary, primaryInput: defaults.primary, secondaryInput: defaults.secondary, primaryHue: 'blue', secondaryHue: 'pink', primaryShade: 4, secondaryShade: 11, }); const handleChangeColor = (name) => (event) => { const isRgb = (string) => /rgb\([0-9]{1,3}\s*,\s*[0-9]{1,3}\s*,\s*[0-9]{1,3}\)/i.test(string); const isHex = (string) => /^#?([0-9a-f]{3})$|^#?([0-9a-f]){6}$/i.test(string); let { target: { value: color }, } = event; setState((prevState) => ({ ...prevState, [`${name}Input`]: color, })); let isValidColor = false; if (isRgb(color)) { isValidColor = true; } else if (isHex(color)) { isValidColor = true; if (!color.includes('#')) { color = `#${color}`; } } if (isValidColor) { setState((prevState) => ({ ...prevState, [name]: color, })); } }; const handleChangeHue = (name) => (event) => { const hue = event.target.value; const color = colors[hue][shades[state[`${name}Shade`]]]; setState({ ...state, [`${name}Hue`]: hue, [name]: color, [`${name}Input`]: color, }); }; const handleChangeShade = (name) => (event, shade) => { const color = colors[state[`${name}Hue`]][shades[shade]]; setState({ ...state, [`${name}Shade`]: shade, [name]: color, [`${name}Input`]: color, }); }; const handleChangeDocsColors = () => { const paletteColors = { primary: { ...colors[state.primaryHue], main: state.primary }, secondary: { ...colors[state.secondaryHue], main: state.secondary }, }; setDocsColors(paletteColors.primary, paletteColors.secondary); document.cookie = `paletteColors=${JSON.stringify( paletteColors, )};path=/;max-age=31536000`; }; const handleResetDocsColors = () => { resetDocsColor(); document.cookie = 'paletteColors=;path=/;max-age=0'; }; const colorBar = (color) => { const background = theme.palette.augmentColor({ color: { main: color, }, }); return ( {['dark', 'main', 'light'].map((key) => ( {rgbToHex(background[key])} ))} ); }; const colorPicker = (intent) => { const intentInput = state[`${intent}Input`]; const intentShade = state[`${intent}Shade`]; const color = state[`${intent}`]; return ( {capitalize(intent)} Shade: {shades[intentShade]} {hues.map((hue) => { const shade = intent === 'primary' ? shades[state.primaryShade] : shades[state.secondaryShade]; const backgroundColor = colors[hue][shade]; return ( } checkedIcon={ } /> ); })} {colorBar(color)} ); }; return ( {colorPicker('primary')} {colorPicker('secondary')} ); } export default ColorTool; ``` The output shown in the color sample can be pasted directly into a [`createTheme()`](/material-ui/customization/theming/#createtheme-options-args-theme) function (to be used with [`ThemeProvider`](/material-ui/customization/theming/#theme-provider)): ```jsx import { createTheme } from '@mui/material/styles'; import { purple } from '@mui/material/colors'; const theme = createTheme({ palette: { primary: { main: purple[500], }, secondary: { main: '#f44336', }, }, }); ``` Only the `main` shades need to be provided (unless you wish to further customize `light`, `dark` or `contrastText`), as the other colors will be calculated by `createTheme()`, as described in the [Theme customization](/material-ui/customization/palette/) section. If you are using the default primary and / or secondary shades then by providing the color object, `createTheme()` will use the appropriate shades from the material color for main, light and dark. ### Tools by the community - [mui-theme-creator](https://zenoo.github.io/mui-theme-creator/): A tool to help design and customize themes for the Material UI component library. Includes basic site templates to show various components and how they are affected by the theme - [Material palette generator](https://m2.material.io/inline-tools/color/): The Material palette generator can be used to generate a palette for any color you input. ## 2014 Material Design color palettes These color palettes, originally created by Material Design in 2014, are comprised of colors designed to work together harmoniously, and can be used to develop your brand palette. To generate your own harmonious palettes, use the palette generation tool. ### Important Terms - **Palette**: A palette is a collection of colors, that is hues and their shades. Material UI provides all colors from the Material Design guidelines. [This color palette](#color-palette) has been designed with colors that work harmoniously with each other. - **Hue & Shade**: A single color within the palette is made up of a hue such as "red", and shade, such as "500". "red 50" is the lightest shade of red (_pink!_), while "red 900" is the darkest. In addition, most hues come with "accent" shades, prefixed with an `A`. ### Color palette Given a _HUE_ (red, pink, etc.) and a _SHADE_ (500, 600, etc.) you can import the color like this: ```jsx import { red } from '@mui/material/colors'; const color = red[500]; ``` ```jsx import Box from '@mui/material/Box'; import { styled, useTheme } from '@mui/material/styles'; import * as colors from '@mui/material/colors'; const mainColors = [ 'Red', 'Pink', 'Purple', 'Deep Purple', 'Indigo', 'Blue', 'Light Blue', 'Cyan', 'Teal', 'Green', 'Light Green', 'Lime', 'Yellow', 'Amber', 'Orange', 'Deep Orange', 'Brown', 'Grey', 'Blue Grey', ]; const mainPalette = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]; const altPalette = ['A100', 'A200', 'A400', 'A700']; const ColorGroup = styled('ul', { name: 'ColorGroup' })(({ theme }) => ({ padding: 0, margin: theme.spacing(0, 2, 2, 0), flexGrow: 1, [theme.breakpoints.up('sm')]: { flexGrow: 0, width: '30%', }, })); const ColorValue = styled('span', { name: 'ColorValue' })(({ theme }) => ({ ...theme.typography.caption, color: 'inherit', fontWeight: 'inherit', })); const ColorBlock = styled('li', { name: 'ColorBlock' })( ({ theme }) => theme.typography.body2, ); function getColorBlock(theme, colorName, colorValue, colorTitle) { const bgColor = colors[colorName][colorValue]; const fgColor = theme.palette.getContrastText(bgColor); let blockTitle; if (colorTitle) { blockTitle = {colorName}; } let rowStyle = { backgroundColor: bgColor, color: fgColor, listStyle: 'none', padding: 15, }; if (colorValue.toString().startsWith('A1')) { rowStyle = { ...rowStyle, marginTop: 4, }; } return ( {blockTitle} {colorValue} {bgColor} ); } function getColorGroup(options) { const { theme, color, showAltPalette } = options; const cssColor = color .replace(' ', '') .replace(color.charAt(0), color.charAt(0).toLowerCase()); let colorsList = []; colorsList = mainPalette.map((mainValue) => getColorBlock(theme, cssColor, mainValue), ); if (showAltPalette) { altPalette.forEach((altValue) => { colorsList.push(getColorBlock(theme, cssColor, altValue)); }); } return ( {getColorBlock(theme, cssColor, 500, true)} {colorsList} ); } function Color() { const theme = useTheme(); return ( {mainColors.map((mainColor) => getColorGroup({ theme, color: mainColor, showAltPalette: true, }), )} ); } export default Color; ``` ### Examples For instance, you can refer to complementary primary and accent colors, "red 500" and "purple A200" like so: ```js import { purple, red } from '@mui/material/colors'; const primary = red[500]; // #f44336 const accent = purple['A200']; // #e040fb const accent = purple.A200; // #e040fb (alternative method) ``` ### Accessibility [WCAG 2.1 Rule 1.4.3](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html) does recommend that you have a minimum of a 4.5:1 contrast ratio for the visual presentation of text and images of text. Material UI currently only enforces a 3:1 contrast ratio. If you would like to meet WCAG 2.1 AA compliance, you can increase your minimum contrast ratio as described in the [Theme customization](/material-ui/customization/palette/#accessibility) section. --- # Source: https://mui.com/material-ui/guides/composition.md # Composition Material UI tries to make composition as easy as possible. ## Wrapping components To provide maximum flexibility and performance, Material UI needs a way to know the nature of the child elements a component receives. To solve this problem, we tag some of the components with a `muiName` static property when needed. You may, however, need to wrap a component in order to enhance it, which can conflict with the `muiName` solution. If you wrap a component, verify if that component has this static property set. If you encounter this issue, you need to use the same tag for your wrapping component that is used with the wrapped component. In addition, you should forward the props, as the parent component may need to control the wrapped components props. Let's see an example: ```jsx const WrappedIcon = (props) => ; WrappedIcon.muiName = Icon.muiName; ``` ```tsx import IconButton from '@mui/material/IconButton'; import Icon, { IconProps } from '@mui/material/Icon'; function WrappedIcon(props: IconProps) { return ; } WrappedIcon.muiName = 'Icon'; export default function Composition() { return (
alarm alarm
); } ``` ### Forwarding slot props Use the `mergeSlotProps` utility function to merge custom props with the slot props. If the arguments are functions then they'll be resolved before merging, and the result from the first argument will override the second. Special properties that merged between the two arguments are listed below: - `className`: values are concatenated rather than overriding one another. In the snippet below, the `custom-tooltip-popper` class is applied to the Tooltip's popper slot. ```jsx import Tooltip, { TooltipProps } from '@mui/material/Tooltip'; import { mergeSlotProps } from '@mui/material/utils'; export const CustomTooltip = (props: TooltipProps) => { const { children, title, sx: sxProps } = props; return ( {title}} slotProps={{ ...props.slotProps, popper: mergeSlotProps(props.slotProps?.popper, { className: 'custom-tooltip-popper', disablePortal: true, placement: 'top', }), }} > {children} ); }; ``` If you added another `className` via the `slotProps` prop on the Custom Tooltip—as shown below—then both would be present on the rendered popper slot: ```js ``` The popper slot in the original example would now have both classes applied to it, in addition to any others that may be present: `"[…] custom-tooltip-popper foo"`. - `style`: object are shallow merged rather than replacing one another. The style keys from the first argument have higher priority. - `sx`: values are concatenated into an array. - `^on[A-Z]` event handlers: these functions are composed between the two arguments. ```js mergeSlotProps(props.slotProps?.popper, { onClick: (event) => {}, // composed with the `slotProps?.popper?.onClick` createPopper: (popperOptions) => {}, // overridden by the `slotProps?.popper?.createPopper` }); ``` ## Component prop Material UI allows you to change the root element that will be rendered via a prop called `component`. For example, by default a `List` component will render a `