diff --git a/docs/data/base/components/badge/AccessibleBadges.js b/docs/data/base/components/badge/AccessibleBadges.js index 1d895eb585d8e6..9f23beebbdb628 100644 --- a/docs/data/base/components/badge/AccessibleBadges.js +++ b/docs/data/base/components/badge/AccessibleBadges.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -15,7 +15,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; diff --git a/docs/data/base/components/badge/AccessibleBadges.tsx b/docs/data/base/components/badge/AccessibleBadges.tsx index e5754f2761c08b..5480ab145e94bb 100644 --- a/docs/data/base/components/badge/AccessibleBadges.tsx +++ b/docs/data/base/components/badge/AccessibleBadges.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -15,7 +15,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; diff --git a/docs/data/base/components/badge/BadgeMax.js b/docs/data/base/components/badge/BadgeMax.js index 4ab282f10a8bd7..311884fd798863 100644 --- a/docs/data/base/components/badge/BadgeMax.js +++ b/docs/data/base/components/badge/BadgeMax.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Stack from '@mui/material/Stack'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -16,7 +16,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; diff --git a/docs/data/base/components/badge/BadgeMax.tsx b/docs/data/base/components/badge/BadgeMax.tsx index 4ab282f10a8bd7..311884fd798863 100644 --- a/docs/data/base/components/badge/BadgeMax.tsx +++ b/docs/data/base/components/badge/BadgeMax.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Stack from '@mui/material/Stack'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -16,7 +16,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; diff --git a/docs/data/base/components/badge/BadgeVisibility.js b/docs/data/base/components/badge/BadgeVisibility.js index 9591dc07aed366..0c026af7603a39 100644 --- a/docs/data/base/components/badge/BadgeVisibility.js +++ b/docs/data/base/components/badge/BadgeVisibility.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import ButtonGroup from '@mui/material/ButtonGroup'; import Button from '@mui/material/Button'; import AddIcon from '@mui/icons-material/Add'; @@ -22,7 +22,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -45,7 +45,7 @@ const StyledBadge = styled(BadgeUnstyled)` transition: opacity 0.2s ease-in-out; } - & .MuiBadge-invisible { + & .${badgeUnstyledClasses.invisible} { opacity: 0; pointer-events: none; } @@ -68,7 +68,7 @@ export default function BadgeVisibility() { '& > *': { marginBottom: 2, }, - '& .MuiBadge-root': { + [`& .${badgeUnstyledClasses.root}`]: { marginRight: 4, }, }} diff --git a/docs/data/base/components/badge/BadgeVisibility.tsx b/docs/data/base/components/badge/BadgeVisibility.tsx index 9591dc07aed366..0c026af7603a39 100644 --- a/docs/data/base/components/badge/BadgeVisibility.tsx +++ b/docs/data/base/components/badge/BadgeVisibility.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Box from '@mui/material/Box'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import ButtonGroup from '@mui/material/ButtonGroup'; import Button from '@mui/material/Button'; import AddIcon from '@mui/icons-material/Add'; @@ -22,7 +22,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -45,7 +45,7 @@ const StyledBadge = styled(BadgeUnstyled)` transition: opacity 0.2s ease-in-out; } - & .MuiBadge-invisible { + & .${badgeUnstyledClasses.invisible} { opacity: 0; pointer-events: none; } @@ -68,7 +68,7 @@ export default function BadgeVisibility() { '& > *': { marginBottom: 2, }, - '& .MuiBadge-root': { + [`& .${badgeUnstyledClasses.root}`]: { marginRight: 4, }, }} diff --git a/docs/data/base/components/badge/ShowZeroBadge.js b/docs/data/base/components/badge/ShowZeroBadge.js index 0443a3f4093f56..380716b1ce1fbd 100644 --- a/docs/data/base/components/badge/ShowZeroBadge.js +++ b/docs/data/base/components/badge/ShowZeroBadge.js @@ -1,7 +1,7 @@ import * as React from 'react'; import Stack from '@mui/material/Stack'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -16,7 +16,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -37,7 +37,7 @@ const StyledBadge = styled(BadgeUnstyled)` transform-origin: 100% 0; } - & .MuiBadge-invisible { + & .${badgeUnstyledClasses.invisible} { display: none; } `; diff --git a/docs/data/base/components/badge/ShowZeroBadge.tsx b/docs/data/base/components/badge/ShowZeroBadge.tsx index 0443a3f4093f56..380716b1ce1fbd 100644 --- a/docs/data/base/components/badge/ShowZeroBadge.tsx +++ b/docs/data/base/components/badge/ShowZeroBadge.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import Stack from '@mui/material/Stack'; import { styled } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; import MailIcon from '@mui/icons-material/Mail'; const StyledBadge = styled(BadgeUnstyled)` @@ -16,7 +16,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -37,7 +37,7 @@ const StyledBadge = styled(BadgeUnstyled)` transform-origin: 100% 0; } - & .MuiBadge-invisible { + & .${badgeUnstyledClasses.invisible} { display: none; } `; diff --git a/docs/data/base/components/badge/UnstyledBadge.js b/docs/data/base/components/badge/UnstyledBadge.js index 64ca09a108c729..26fc179f223c89 100644 --- a/docs/data/base/components/badge/UnstyledBadge.js +++ b/docs/data/base/components/badge/UnstyledBadge.js @@ -1,6 +1,6 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; const StyledBadge = styled(BadgeUnstyled)` box-sizing: border-box; @@ -15,7 +15,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -29,20 +29,6 @@ const StyledBadge = styled(BadgeUnstyled)` background: #07f; border-radius: 10px; box-shadow: 0 0 0 1px #fff; - } - - & .MuiBadge-dot { - padding: 0; - z-index: auto; - min-width: 6px; - width: 6px; - height: 6px; - background: #07f; - border-radius: 100%; - box-shadow: 0 0 0 1px #fff; - } - - & .MuiBadge-anchorOriginTopRight { position: absolute; top: 0; right: 0; @@ -69,13 +55,8 @@ function BadgeContent() { export default function UnstyledBadge() { return ( - :not(style) + :not(style)': { ml: 4 } }}> - - - - - - - + + + ); } diff --git a/docs/data/base/components/badge/UnstyledBadge.tsx b/docs/data/base/components/badge/UnstyledBadge.tsx index 64ca09a108c729..26fc179f223c89 100644 --- a/docs/data/base/components/badge/UnstyledBadge.tsx +++ b/docs/data/base/components/badge/UnstyledBadge.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { styled, Box } from '@mui/system'; -import BadgeUnstyled from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled, { badgeUnstyledClasses } from '@mui/base/BadgeUnstyled'; const StyledBadge = styled(BadgeUnstyled)` box-sizing: border-box; @@ -15,7 +15,7 @@ const StyledBadge = styled(BadgeUnstyled)` display: inline-block; line-height: 1; - & .MuiBadge-badge { + & .${badgeUnstyledClasses.badge} { z-index: auto; min-width: 20px; height: 20px; @@ -29,20 +29,6 @@ const StyledBadge = styled(BadgeUnstyled)` background: #07f; border-radius: 10px; box-shadow: 0 0 0 1px #fff; - } - - & .MuiBadge-dot { - padding: 0; - z-index: auto; - min-width: 6px; - width: 6px; - height: 6px; - background: #07f; - border-radius: 100%; - box-shadow: 0 0 0 1px #fff; - } - - & .MuiBadge-anchorOriginTopRight { position: absolute; top: 0; right: 0; @@ -69,13 +55,8 @@ function BadgeContent() { export default function UnstyledBadge() { return ( - :not(style) + :not(style)': { ml: 4 } }}> - - - - - - - + + + ); } diff --git a/docs/data/base/components/badge/UnstyledBadge.tsx.preview b/docs/data/base/components/badge/UnstyledBadge.tsx.preview index 55c0c93be1c769..0f52f923d64e43 100644 --- a/docs/data/base/components/badge/UnstyledBadge.tsx.preview +++ b/docs/data/base/components/badge/UnstyledBadge.tsx.preview @@ -1,6 +1,3 @@ - - - \ No newline at end of file diff --git a/docs/pages/base/api/badge-unstyled.json b/docs/pages/base/api/badge-unstyled.json index 3f2e08fe96f395..209b3566a8324c 100644 --- a/docs/pages/base/api/badge-unstyled.json +++ b/docs/pages/base/api/badge-unstyled.json @@ -1,15 +1,7 @@ { "props": { - "anchorOrigin": { - "type": { - "name": "shape", - "description": "{ horizontal: 'left'
| 'right', vertical: 'bottom'
| 'top' }" - }, - "default": "{\n vertical: 'top',\n horizontal: 'right',\n}" - }, "badgeContent": { "type": { "name": "node" } }, "children": { "type": { "name": "node" } }, - "classes": { "type": { "name": "object" } }, "component": { "type": { "name": "elementType" } }, "components": { "type": { "name": "shape", "description": "{ Badge?: elementType, Root?: elementType }" }, @@ -21,35 +13,10 @@ }, "invisible": { "type": { "name": "bool" } }, "max": { "type": { "name": "number" }, "default": "99" }, - "showZero": { "type": { "name": "bool" } }, - "variant": { "type": { "name": "string" }, "default": "'standard'" } + "showZero": { "type": { "name": "bool" } } }, "name": "BadgeUnstyled", - "styles": { - "classes": [ - "root", - "badge", - "dot", - "standard", - "anchorOriginTopRight", - "anchorOriginBottomRight", - "anchorOriginTopLeft", - "anchorOriginBottomLeft", - "invisible" - ], - "globalClasses": { - "root": "MuiBadge-root", - "badge": "MuiBadge-badge", - "dot": "MuiBadge-dot", - "standard": "MuiBadge-standard", - "anchorOriginTopRight": "MuiBadge-anchorOriginTopRight", - "anchorOriginBottomRight": "MuiBadge-anchorOriginBottomRight", - "anchorOriginTopLeft": "MuiBadge-anchorOriginTopLeft", - "anchorOriginBottomLeft": "MuiBadge-anchorOriginBottomLeft", - "invisible": "MuiBadge-invisible" - }, - "name": null - }, + "styles": { "classes": [], "globalClasses": {}, "name": null }, "spread": true, "forwardsRefTo": "HTMLSpanElement", "filename": "/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.js", diff --git a/docs/translations/api-docs/badge-unstyled/badge-unstyled.json b/docs/translations/api-docs/badge-unstyled/badge-unstyled.json index 554dfd8183d080..dace81cd66002f 100644 --- a/docs/translations/api-docs/badge-unstyled/badge-unstyled.json +++ b/docs/translations/api-docs/badge-unstyled/badge-unstyled.json @@ -1,58 +1,14 @@ { "componentDescription": "", "propDescriptions": { - "anchorOrigin": "The anchor of the badge.", "badgeContent": "The content rendered within the badge.", "children": "The badge will be added relative to this node.", - "classes": "Override or extend the styles applied to the component. See CSS API below for more details.", "component": "The component used for the root node. Either a string to use a HTML element or a component.", "components": "The components used for each slot inside the Badge. Either a string to use a HTML element or a component.", "componentsProps": "The props used for each slot inside the Badge.", "invisible": "If true, the badge is invisible.", "max": "Max count to show.", - "showZero": "Controls whether the badge is hidden when badgeContent is zero.", - "variant": "The variant to use." + "showZero": "Controls whether the badge is hidden when badgeContent is zero." }, - "classDescriptions": { - "root": { "description": "Class name applied to the root element." }, - "badge": { - "description": "Class name applied to {{nodeName}}.", - "nodeName": "the badge `span` element" - }, - "dot": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "variant=\"dot\"" - }, - "standard": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "variant=\"standard\"" - }, - "anchorOriginTopRight": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "anchorOrigin={{ 'top', 'right' }}" - }, - "anchorOriginBottomRight": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "anchorOrigin={{ 'bottom', 'right' }}" - }, - "anchorOriginTopLeft": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "anchorOrigin={{ 'top', 'left' }}" - }, - "anchorOriginBottomLeft": { - "description": "Class name applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "anchorOrigin={{ 'bottom', 'left' }}" - }, - "invisible": { - "description": "State class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the badge `span` element", - "conditions": "invisible={true}" - } - } + "classDescriptions": {} } diff --git a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.js b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.js index f6d1529405cd88..f46cbb07d83e43 100644 --- a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.js +++ b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.js @@ -1,35 +1,24 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { unstable_capitalize as capitalize } from '@mui/utils'; import composeClasses from '../composeClasses'; import appendOwnerState from '../utils/appendOwnerState'; import useBadge from './useBadge'; import { getBadgeUtilityClass } from './badgeUnstyledClasses'; const useUtilityClasses = (ownerState) => { - const { variant, anchorOrigin, invisible, classes } = ownerState; + const { invisible } = ownerState; const slots = { root: ['root'], - badge: [ - 'badge', - variant, - `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(anchorOrigin.horizontal)}`, - invisible && 'invisible', - ], + badge: ['badge', invisible && 'invisible'], }; - return composeClasses(slots, getBadgeUtilityClass, classes); + return composeClasses(slots, getBadgeUtilityClass, undefined); }; const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) { const { - anchorOrigin: anchorOriginProp = { - vertical: 'top', - horizontal: 'right', - }, - classes: classesProp, badgeContent: badgeContentProp, component, children, @@ -39,25 +28,19 @@ const BadgeUnstyled = React.forwardRef(function BadgeUnstyled(props, ref) { invisible: invisibleProp, max: maxProp = 99, showZero = false, - variant: variantProp = 'standard', ...other } = props; - const { anchorOrigin, badgeContent, max, variant, displayValue, invisible } = useBadge({ + const { badgeContent, max, displayValue, invisible } = useBadge({ ...props, - anchorOrigin: anchorOriginProp, max: maxProp, - variant: variantProp, }); const ownerState = { ...props, - anchorOrigin, badgeContent, - classes: classesProp, invisible, max, - variant, showZero, }; @@ -89,17 +72,6 @@ BadgeUnstyled.propTypes /* remove-proptypes */ = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the d.ts file and run "yarn proptypes" | // ---------------------------------------------------------------------- - /** - * The anchor of the badge. - * @default { - * vertical: 'top', - * horizontal: 'right', - * } - */ - anchorOrigin: PropTypes.shape({ - horizontal: PropTypes.oneOf(['left', 'right']).isRequired, - vertical: PropTypes.oneOf(['bottom', 'top']).isRequired, - }), /** * The content rendered within the badge. */ @@ -108,10 +80,6 @@ BadgeUnstyled.propTypes /* remove-proptypes */ = { * The badge will be added relative to this node. */ children: PropTypes.node, - /** - * Override or extend the styles applied to the component. - */ - classes: PropTypes.object, /** * @ignore */ @@ -153,11 +121,6 @@ BadgeUnstyled.propTypes /* remove-proptypes */ = { * @default false */ showZero: PropTypes.bool, - /** - * The variant to use. - * @default 'standard' - */ - variant: PropTypes.string, }; export default BadgeUnstyled; diff --git a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.test.js b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.test.js index 8c715d30f47866..ce3b209af8c3b9 100644 --- a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.test.js +++ b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyled.test.js @@ -19,7 +19,7 @@ describe('', () => { mount, refInstanceof: window.HTMLSpanElement, testComponentPropWith: 'div', - muiName: 'MuiBadge', + muiName: 'BaseBadge', slots: { root: { expectedClassName: classes.root, diff --git a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyledProps.ts b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyledProps.ts index 207686fcee8475..050a1cdbf8cd83 100644 --- a/packages/mui-base/src/BadgeUnstyled/BadgeUnstyledProps.ts +++ b/packages/mui-base/src/BadgeUnstyled/BadgeUnstyledProps.ts @@ -1,24 +1,10 @@ import * as React from 'react'; import { OverrideProps, OverridableTypeMap } from '@mui/types'; -import { BadgeUnstyledClasses } from './badgeUnstyledClasses'; - -export interface BadgeOrigin { - vertical: 'top' | 'bottom'; - horizontal: 'left' | 'right'; -} export interface BadgeUnstyledComponentsPropsOverrides {} export interface BadgeUnstyledTypeMap

{ props: P & { - /** - * The anchor of the badge. - * @default { - * vertical: 'top', - * horizontal: 'right', - * } - */ - anchorOrigin?: BadgeOrigin; /** * The components used for each slot inside the Badge. * Either a string to use a HTML element or a component. @@ -44,10 +30,6 @@ export interface BadgeUnstyledTypeMap

= usePreviousProps({ - anchorOrigin: anchorOriginProp, badgeContent: badgeContentProp, max: maxProp, - variant: variantProp, }); let invisible = invisibleProp; - if ( - invisibleProp === false && - ((badgeContentProp === 0 && !showZero) || (badgeContentProp == null && variantProp !== 'dot')) - ) { + if (invisibleProp === false && badgeContentProp === 0 && !showZero) { invisible = true; } - const { - anchorOrigin = anchorOriginProp, - badgeContent, - max = maxProp, - variant = variantProp, - } = invisible ? prevProps : props; + const { badgeContent, max = maxProp } = invisible ? prevProps : props; - let displayValue: React.ReactNode = ''; - - if (variant !== 'dot') { - displayValue = badgeContent && Number(badgeContent) > max ? `${max}+` : badgeContent; - } + const displayValue: React.ReactNode = + badgeContent && Number(badgeContent) > max ? `${max}+` : badgeContent; return { - anchorOrigin, badgeContent, invisible, max, - variant, displayValue, }; } diff --git a/packages/mui-material/src/Badge/Badge.d.ts b/packages/mui-material/src/Badge/Badge.d.ts index 59dd60c30b21dc..038a250b0db970 100644 --- a/packages/mui-material/src/Badge/Badge.d.ts +++ b/packages/mui-material/src/Badge/Badge.d.ts @@ -1,23 +1,37 @@ import * as React from 'react'; import { SxProps } from '@mui/system'; import { OverridableStringUnion } from '@mui/types'; -import { ExtendBadgeUnstyledTypeMap, BadgeUnstyledTypeMap } from '@mui/base/BadgeUnstyled'; +import { ExtendBadgeUnstyledTypeMap } from '@mui/base/BadgeUnstyled'; import { Theme } from '../styles'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; +import { BadgeClasses } from './badgeClasses'; export interface BadgePropsVariantOverrides {} export interface BadgePropsColorOverrides {} +export interface BadgeOrigin { + vertical: 'top' | 'bottom'; + horizontal: 'left' | 'right'; +} + export type BadgeTypeMap< D extends React.ElementType = 'span', P = {}, > = ExtendBadgeUnstyledTypeMap<{ props: P & { + /** + * The anchor of the badge. + * @default { + * vertical: 'top', + * horizontal: 'right', + * } + */ + anchorOrigin?: BadgeOrigin; /** * Override or extend the styles applied to the component. */ - classes?: BadgeUnstyledTypeMap['props']['classes'] & { + classes?: Partial & { /** Styles applied to the badge `span` element if `color="primary"`. */ colorPrimary?: string; /** Styles applied to the badge `span` element if `color="secondary"`. */ @@ -51,6 +65,10 @@ export type BadgeTypeMap< /** Class name applied to the badge `span` element if `overlap="circular"`. */ overlapCircular?: string; }; + /** + * @ignore + */ + className?: string; /** * The color of the component. * It supports both default and custom theme colors, which can be added as shown in the @@ -85,7 +103,6 @@ type BadgeBadgeProps = NonNullable['ba export const BadgeRoot: React.FC; export const BadgeMark: React.FC; -export type BadgeClassKey = keyof NonNullable; /** * * Demos: @@ -100,10 +117,6 @@ export type BadgeClassKey = keyof NonNullable; */ declare const Badge: OverridableComponent; -export type BadgeClasses = Record; - -export const badgeClasses: BadgeClasses; - export type BadgeProps< D extends React.ElementType = BadgeTypeMap['defaultComponent'], P = {}, diff --git a/packages/mui-material/src/Badge/Badge.js b/packages/mui-material/src/Badge/Badge.js index ba38e89ace1bbf..964312b2f5278e 100644 --- a/packages/mui-material/src/Badge/Badge.js +++ b/packages/mui-material/src/Badge/Badge.js @@ -2,46 +2,27 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { usePreviousProps } from '@mui/utils'; -import { generateUtilityClasses } from '@mui/base'; -import BadgeUnstyled, { badgeUnstyledClasses, getBadgeUtilityClass } from '@mui/base/BadgeUnstyled'; +import BadgeUnstyled from '@mui/base/BadgeUnstyled'; import styled from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; import shouldSpreadAdditionalProps from '../utils/shouldSpreadAdditionalProps'; import capitalize from '../utils/capitalize'; - -export const badgeClasses = { - ...badgeUnstyledClasses, - ...generateUtilityClasses('MuiBadge', [ - 'colorError', - 'colorInfo', - 'colorPrimary', - 'colorSecondary', - 'colorSuccess', - 'colorWarning', - 'overlapRectangular', - 'overlapCircular', - // TODO: v6 remove the overlap value from these class keys - 'anchorOriginTopLeftCircular', - 'anchorOriginTopLeftRectangular', - 'anchorOriginTopRightCircular', - 'anchorOriginTopRightRectangular', - 'anchorOriginBottomLeftCircular', - 'anchorOriginBottomLeftRectangular', - 'anchorOriginBottomRightCircular', - 'anchorOriginBottomRightRectangular', - ]), -}; +import badgeClasses, { getBadgeUtilityClass } from './badgeClasses'; const RADIUS_STANDARD = 10; const RADIUS_DOT = 4; const extendUtilityClasses = (ownerState) => { - const { color, anchorOrigin, overlap, classes = {} } = ownerState; + const { color, anchorOrigin, invisible, overlap, variant, classes = {} } = ownerState; return { - ...classes, + root: clsx(classes.root, 'root'), badge: clsx( classes.badge, + getBadgeUtilityClass('badge'), + getBadgeUtilityClass(variant), + invisible && getBadgeUtilityClass('invisible'), + `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(anchorOrigin.horizontal)}`, getBadgeUtilityClass( `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize( anchorOrigin.horizontal, @@ -221,12 +202,14 @@ const Badge = React.forwardRef(function Badge(inProps, ref) { vertical: 'top', horizontal: 'right', }, + className, component = 'span', components = {}, componentsProps = {}, overlap: overlapProp = 'rectangular', color: colorProp = 'default', invisible: invisibleProp = false, + max, badgeContent: badgeContentProp, showZero = false, variant: variantProp = 'standard', @@ -237,6 +220,7 @@ const Badge = React.forwardRef(function Badge(inProps, ref) { anchorOrigin: anchorOriginProp, color: colorProp, overlap: overlapProp, + variant: variantProp, }); let invisible = invisibleProp; @@ -252,40 +236,60 @@ const Badge = React.forwardRef(function Badge(inProps, ref) { color = colorProp, overlap = overlapProp, anchorOrigin = anchorOriginProp, + variant = variantProp, } = invisible ? prevProps : props; - const ownerState = { ...props, anchorOrigin, invisible, color, overlap }; + const ownerState = { ...props, anchorOrigin, invisible, color, overlap, variant }; const classes = extendUtilityClasses(ownerState); + let displayValue; + + if (variant !== 'dot') { + displayValue = + badgeContentProp && Number(badgeContentProp) > max ? `${max}+` : badgeContentProp; + } + return ( ); @@ -319,6 +323,10 @@ Badge.propTypes /* remove-proptypes */ = { * Override or extend the styles applied to the component. */ classes: PropTypes.object, + /** + * @ignore + */ + className: PropTypes.string, /** * The color of the component. * It supports both default and custom theme colors, which can be added as shown in the diff --git a/packages/mui-material/src/Badge/badgeClasses.ts b/packages/mui-material/src/Badge/badgeClasses.ts new file mode 100644 index 00000000000000..10e192c8749346 --- /dev/null +++ b/packages/mui-material/src/Badge/badgeClasses.ts @@ -0,0 +1,60 @@ +import generateUtilityClasses from '@mui/base/generateUtilityClasses'; +import generateUtilityClass from '@mui/base/generateUtilityClass'; + +export interface BadgeClasses { + /** Class name applied to the root element. */ + root: string; + /** Class name applied to the badge `span` element. */ + badge: string; + /** Class name applied to the badge `span` element if `variant="dot"`. */ + dot: string; + /** Class name applied to the badge `span` element if `variant="standard"`. */ + standard: string; + /** Class name applied to the badge `span` element if `anchorOrigin={{ 'top', 'right' }}`. */ + anchorOriginTopRight: string; + /** Class name applied to the badge `span` element if `anchorOrigin={{ 'bottom', 'right' }}`. */ + anchorOriginBottomRight: string; + /** Class name applied to the badge `span` element if `anchorOrigin={{ 'top', 'left' }}`. */ + anchorOriginTopLeft: string; + /** Class name applied to the badge `span` element if `anchorOrigin={{ 'bottom', 'left' }}`. */ + anchorOriginBottomLeft: string; + /** State class applied to the badge `span` element if `invisible={true}`. */ + invisible: string; +} + +export type BadgeClassKey = keyof BadgeClasses; + +export function getBadgeUtilityClass(slot: string): string { + return generateUtilityClass('MuiBadge', slot); +} + +const badgeClasses: BadgeClasses = generateUtilityClasses('MuiBadge', [ + 'root', + 'badge', + 'dot', + 'standard', + 'anchorOriginTopRight', + 'anchorOriginBottomRight', + 'anchorOriginTopLeft', + 'anchorOriginBottomLeft', + 'invisible', + 'colorError', + 'colorInfo', + 'colorPrimary', + 'colorSecondary', + 'colorSuccess', + 'colorWarning', + 'overlapRectangular', + 'overlapCircular', + // TODO: v6 remove the overlap value from these class keys + 'anchorOriginTopLeftCircular', + 'anchorOriginTopLeftRectangular', + 'anchorOriginTopRightCircular', + 'anchorOriginTopRightRectangular', + 'anchorOriginBottomLeftCircular', + 'anchorOriginBottomLeftRectangular', + 'anchorOriginBottomRightCircular', + 'anchorOriginBottomRightRectangular', +]); + +export default badgeClasses; diff --git a/packages/mui-material/src/Badge/index.d.ts b/packages/mui-material/src/Badge/index.d.ts index dcb875afff71d0..1d30fdc3f64b4c 100644 --- a/packages/mui-material/src/Badge/index.d.ts +++ b/packages/mui-material/src/Badge/index.d.ts @@ -1,2 +1,5 @@ export { default } from './Badge'; export * from './Badge'; + +export { default as badgeClasses } from './badgeClasses'; +export * from './badgeClasses'; diff --git a/packages/mui-material/src/Badge/index.js b/packages/mui-material/src/Badge/index.js index dcb875afff71d0..42f9d0102195b5 100644 --- a/packages/mui-material/src/Badge/index.js +++ b/packages/mui-material/src/Badge/index.js @@ -1,2 +1,4 @@ export { default } from './Badge'; -export * from './Badge'; + +export { default as badgeClasses } from './badgeClasses'; +export * from './badgeClasses';