diff --git a/docs/pages/api-docs/badge-unstyled.md b/docs/pages/api-docs/badge-unstyled.md
index efe4313aad0a1b..391efc86321e4f 100644
--- a/docs/pages/api-docs/badge-unstyled.md
+++ b/docs/pages/api-docs/badge-unstyled.md
@@ -30,7 +30,6 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| badgeContent | node | | The content rendered within the badge. |
| children | node | | The badge will be added relative to this node. |
| classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. |
-| color | 'default'
| 'error'
| 'primary'
| 'secondary' | 'default' | The color of the component. It supports those theme colors that make sense for this component. |
| components | { Badge?: elementType, Root?: elementType } | {} | The components used for each slot inside the Badge. Either a string to use a HTML element or a component. |
| componentsProps | object | {} | The props used for each slot inside the Badge. |
| invisible | bool | | If `true`, the badge is invisible. |
@@ -49,9 +48,6 @@ Any other props supplied will be provided to the root element (native element).
|:-----|:-------------|:------------|
| root | .MuiBadge-root | Styles applied to the root element.
| badge | .MuiBadge-badge | Styles applied to the badge `span` element.
-| colorPrimary | .MuiBadge-colorPrimary | Styles applied to the root element if `color="primary"`.
-| colorSecondary | .MuiBadge-colorSecondary | Styles applied to the root element if `color="secondary"`.
-| colorError | .MuiBadge-colorError | Styles applied to the root element if `color="error"`.
| dot | .MuiBadge-dot | Styles applied to the root element if `variant="dot"`.
| standard | .MuiBadge-standard | Styles applied to the root element if `variant="standard"`.
| anchorOriginTopRightRectangular | .MuiBadge-anchorOriginTopRightRectangular | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="rectangular"`.
diff --git a/docs/pages/api-docs/badge.md b/docs/pages/api-docs/badge.md
index dd6ca581b83c9f..bd21e2d53f7270 100644
--- a/docs/pages/api-docs/badge.md
+++ b/docs/pages/api-docs/badge.md
@@ -52,9 +52,6 @@ Any other props supplied will be provided to the root element ([BadgeUnstyled](/
|:-----|:-------------|:------------|
| root | .MuiBadge-root | Styles applied to the root element.
| badge | .MuiBadge-badge | Styles applied to the badge `span` element.
-| colorPrimary | .MuiBadge-colorPrimary | Styles applied to the root element if `color="primary"`.
-| colorSecondary | .MuiBadge-colorSecondary | Styles applied to the root element if `color="secondary"`.
-| colorError | .MuiBadge-colorError | Styles applied to the root element if `color="error"`.
| dot | .MuiBadge-dot | Styles applied to the root element if `variant="dot"`.
| standard | .MuiBadge-standard | Styles applied to the root element if `variant="standard"`.
| anchorOriginTopRightRectangular | .MuiBadge-anchorOriginTopRightRectangular | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="rectangular"`.
@@ -66,6 +63,9 @@ Any other props supplied will be provided to the root element ([BadgeUnstyled](/
| anchorOriginTopLeftCircular | .MuiBadge-anchorOriginTopLeftCircular | Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="circular"`.
| anchorOriginBottomLeftCircular | .MuiBadge-anchorOriginBottomLeftCircular | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="circular"`.
| invisible | .MuiBadge-invisible | Pseudo-class to the badge `span` element if `invisible={true}`.
+| colorPrimary | .MuiBadge-colorPrimary | Styles applied to the root element if `color="primary"`.
+| colorSecondary | .MuiBadge-colorSecondary | Styles applied to the root element if `color="secondary"`.
+| colorError | .MuiBadge-colorError | Styles applied to the root element if `color="error"`.
You can override the style of the component thanks to one of these customization points:
diff --git a/docs/scripts/buildApi.ts b/docs/scripts/buildApi.ts
index 0e19d8e2122969..b6218ae82b475c 100644
--- a/docs/scripts/buildApi.ts
+++ b/docs/scripts/buildApi.ts
@@ -20,6 +20,7 @@ import createGenerateClassName from '../../packages/material-ui-styles/src/creat
import getStylesCreator from '../../packages/material-ui-styles/src/getStylesCreator';
import createMuiTheme from '../../packages/material-ui/src/styles/createMuiTheme';
import { getLineFeed, getUnstyledFilename } from './helpers';
+import { CssBaseline } from '@material-ui/core';
const generateClassName = createGenerateClassName();
@@ -227,7 +228,6 @@ async function updateStylesDefinition(context: {
const unstyledFileName = getUnstyledFilename(typesFilename, true);
try {
- // If the JSON file doesn't exists try extracting the info from the TS definition
const typesSource = readFileSync(unstyledFileName, { encoding: 'utf8' });
const typesAST = await babel.parseAsync(typesSource, {
configFile: false,
@@ -251,7 +251,53 @@ async function updateStylesDefinition(context: {
const members = (node.typeAnnotation.typeAnnotation as babel.types.TSTypeLiteral).members;
if (members) {
- styles.descriptions = {};
+ styles.descriptions = styles.descriptions || {};
+ members.forEach((member) => {
+ const className = ((member as babel.types.TSPropertySignature)
+ .key as babel.types.Identifier).name;
+ styles.classes.push(className);
+ if (member.leadingComments) {
+ styles.descriptions[className] = trimComment(member.leadingComments[0].value);
+ }
+ });
+ }
+ }
+ },
+ });
+
+ const source = readFileSync(typesFilename, { encoding: 'utf8' });
+ const sourceAST = await babel.parseAsync(source, {
+ configFile: false,
+ filename: typesFilename,
+ presets: [require.resolve('@babel/preset-typescript')],
+ });
+ if (sourceAST === null) {
+ throw new Error('No AST returned from babel.');
+ }
+
+ traverse(sourceAST, {
+ TSPropertySignature(babelPath) {
+ const { node } = babelPath;
+ const possiblyPropName = (node.key as babel.types.Identifier).name;
+ if (possiblyPropName === 'classes' && node.typeAnnotation !== null) {
+ let classesDeclarationNode = null;
+ const types = (node.typeAnnotation.typeAnnotation as babel.types.TSIntersectionType)
+ .types;
+
+ if (types) {
+ types.forEach((node) => {
+ if (node.type === 'TSTypeLiteral') {
+ classesDeclarationNode = node;
+ }
+ });
+ }
+
+ const members = classesDeclarationNode
+ ? (classesDeclarationNode as babel.types.TSTypeLiteral).members
+ : [];
+
+ if (members) {
+ styles.descriptions = styles.descriptions || {};
members.forEach((member) => {
const className = ((member as babel.types.TSPropertySignature)
.key as babel.types.Identifier).name;
@@ -267,6 +313,8 @@ async function updateStylesDefinition(context: {
} catch (e) {
// Do nothing as not every components has an unstyled version
}
+
+ styles.classes = Array.from(new Set(styles.classes));
}
async function annotateClassesDefinition(context: {
diff --git a/packages/material-ui-unstyled/src/BadgeUnstyled/BadgeUnstyled.d.ts b/packages/material-ui-unstyled/src/BadgeUnstyled/BadgeUnstyled.d.ts
index a451805c5192ba..8471bfaa5c9a9f 100644
--- a/packages/material-ui-unstyled/src/BadgeUnstyled/BadgeUnstyled.d.ts
+++ b/packages/material-ui-unstyled/src/BadgeUnstyled/BadgeUnstyled.d.ts
@@ -60,12 +60,6 @@ export interface BadgeUnstyledTypeMap
{
- const ref = React.useRef({});
- React.useEffect(() => {
- ref.current = value;
- });
- return ref.current;
-};
-
-const useBadgeClasses = (props) => {
- const { color, variant, anchorOrigin, overlap, invisible, classes = {} } = props;
+const useBadgeClasses = (props, extendClasses) => {
+ const classes = (extendClasses ? extendClasses(props) : props.classes) || {};
+ const { variant, anchorOrigin, overlap, invisible } = props;
const utilityClasses = {
root: clsx(badgeClasses['root'], classes['root']),
badge: clsx(
badgeClasses['badge'],
classes['badge'],
- getUtilityClass(variant),
+ getBadgeUtilityClass(variant),
badgeClasses[
`anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(
anchorOrigin.horizontal,
@@ -33,8 +26,6 @@ const useBadgeClasses = (props) => {
)}${capitalize(overlap)}`
],
{
- [badgeClasses[`color${capitalize(color)}`]]: color !== 'default',
- [classes[`color${capitalize(color)}`]]: color !== 'default',
[badgeClasses['invisible']]: invisible,
[classes.invisible]: invisible,
},
@@ -53,7 +44,6 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
badgeContent: badgeContentProp,
children,
className,
- color: colorProp = 'default',
components = {},
componentsProps = {},
invisible: invisibleProp,
@@ -61,6 +51,8 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
overlap: overlapProp = 'rectangular',
showZero = false,
variant: variantProp = 'standard',
+ styleProps: stylePropsProp = {},
+ extendClasses,
/* eslint-disable react/prop-types */
theme,
...other
@@ -69,10 +61,10 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
const prevProps = usePreviousProps({
anchorOrigin: anchorOriginProp,
badgeContent: badgeContentProp,
- color: colorProp,
max: maxProp,
overlap: overlapProp,
variant: variantProp,
+ styleProps: stylePropsProp,
});
let invisible = invisibleProp;
@@ -87,17 +79,16 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
const {
anchorOrigin = anchorOriginProp,
badgeContent,
- color = colorProp,
max = maxProp,
overlap = overlapProp,
variant = variantProp,
+ styleProps = stylePropsProp,
} = invisible ? prevProps : props;
const stateAndProps = {
...props,
anchorOrigin,
badgeContent,
- color,
invisible,
max,
overlap,
@@ -110,7 +101,9 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
displayValue = badgeContent > max ? `${max}+` : badgeContent;
}
- const classes = useBadgeClasses(stateAndProps);
+ const classes = useBadgeClasses(stateAndProps, extendClasses);
+
+ const extendedStyleProps = { ...stateAndProps, ...styleProps };
const Root = components.Root || 'span';
const rootProps = componentsProps.root || {};
@@ -121,7 +114,7 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) {
return (