Skip to content

Commit

Permalink
[Badge] Add overlap circular and rectangular (#22076)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon authored and oliviertassinari committed Jan 25, 2021
1 parent ad1b3c8 commit 3225656
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 12 deletions.
10 changes: 9 additions & 1 deletion docs/pages/api-docs/badge.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The `MuiBadge` name can be used for providing [default props](/customization/glo
| <span class="prop-name">component</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'span'</span> | The component used for the root node. Either a string to use a HTML element or a component. |
| <span class="prop-name">invisible</span> | <span class="prop-type">bool</span> | | If `true`, the badge will be invisible. |
| <span class="prop-name">max</span> | <span class="prop-type">number</span> | <span class="prop-default">99</span> | Max count to show. |
| <span class="prop-name">overlap</span> | <span class="prop-type">'circle'<br>&#124;&nbsp;'rectangle'</span> | <span class="prop-default">'rectangle'</span> | Wrapped shape the badge should overlap. |
| <span class="prop-name">overlap</span> | <span class="prop-type">'circle'<br>&#124;&nbsp;'rectangle'<br>&#124;&nbsp;'circular'<br>&#124;&nbsp;'rectangular'</span> | <span class="prop-default">'rectangle'</span> | Wrapped shape the badge should overlap. |
| <span class="prop-name">showZero</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Controls whether the badge is hidden when `badgeContent` is zero. |
| <span class="prop-name">variant</span> | <span class="prop-type">'dot'<br>&#124;&nbsp;'standard'</span> | <span class="prop-default">'standard'</span> | The variant to use. |

Expand All @@ -55,13 +55,21 @@ Any other props supplied will be provided to the root element (native element).
| <span class="prop-name">colorError</span> | <span class="prop-name">.MuiBadge-colorError</span> | Styles applied to the root element if `color="error"`.
| <span class="prop-name">dot</span> | <span class="prop-name">.MuiBadge-dot</span> | Styles applied to the root element if `variant="dot"`.
| <span class="prop-name">anchorOriginTopRightRectangle</span> | <span class="prop-name">.MuiBadge-anchorOriginTopRightRectangle</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="rectangle"`.
| <span class="prop-name">anchorOriginTopRightRectangular</span> | <span class="prop-name">.MuiBadge-anchorOriginTopRightRectangular</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="rectangular"`.
| <span class="prop-name">anchorOriginBottomRightRectangle</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomRightRectangle</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="rectangle"`.
| <span class="prop-name">anchorOriginBottomRightRectangular</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomRightRectangular</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="rectangular"`.
| <span class="prop-name">anchorOriginTopLeftRectangle</span> | <span class="prop-name">.MuiBadge-anchorOriginTopLeftRectangle</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="rectangle"`.
| <span class="prop-name">anchorOriginTopLeftRectangular</span> | <span class="prop-name">.MuiBadge-anchorOriginTopLeftRectangular</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="rectangular"`.
| <span class="prop-name">anchorOriginBottomLeftRectangle</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomLeftRectangle</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="rectangle"`.
| <span class="prop-name">anchorOriginBottomLeftRectangular</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomLeftRectangular</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="rectangular"`.
| <span class="prop-name">anchorOriginTopRightCircle</span> | <span class="prop-name">.MuiBadge-anchorOriginTopRightCircle</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="circle"`.
| <span class="prop-name">anchorOriginTopRightCircular</span> | <span class="prop-name">.MuiBadge-anchorOriginTopRightCircular</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="circular"`.
| <span class="prop-name">anchorOriginBottomRightCircle</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomRightCircle</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="circle"`.
| <span class="prop-name">anchorOriginBottomRightCircular</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomRightCircular</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="circular"`.
| <span class="prop-name">anchorOriginTopLeftCircle</span> | <span class="prop-name">.MuiBadge-anchorOriginTopLeftCircle</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="circle"`.
| <span class="prop-name">anchorOriginTopLeftCircular</span> | <span class="prop-name">.MuiBadge-anchorOriginTopLeftCircular</span> | Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="circular"`.
| <span class="prop-name">anchorOriginBottomLeftCircle</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomLeftCircle</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="circle"`.
| <span class="prop-name">anchorOriginBottomLeftCircular</span> | <span class="prop-name">.MuiBadge-anchorOriginBottomLeftCircular</span> | Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="circular"`.
| <span class="prop-name">invisible</span> | <span class="prop-name">.MuiBadge-invisible</span> | Pseudo-class to the badge `span` element if `invisible={true}`.

You can override the style of the component thanks to one of these customization points:
Expand Down
6 changes: 6 additions & 0 deletions docs/src/modules/components/ThemeContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ export function ThemeProvider(props) {
},
...paletteColors,
},
// v5 migration
props: {
MuiBadge: {
overlap: 'rectangular',
},
},
spacing,
},
dense ? highDensity : null,
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/avatars/BadgeAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function BadgeAvatars() {
return (
<div className={classes.root}>
<StyledBadge
overlap="circle"
overlap="circular"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
Expand All @@ -65,7 +65,7 @@ export default function BadgeAvatars() {
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</StyledBadge>
<Badge
overlap="circle"
overlap="circular"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/avatars/BadgeAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default function BadgeAvatars() {
return (
<div className={classes.root}>
<StyledBadge
overlap="circle"
overlap="circular"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
Expand All @@ -71,7 +71,7 @@ export default function BadgeAvatars() {
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</StyledBadge>
<Badge
overlap="circle"
overlap="circular"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/badges/BadgeOverlap.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ export default function BadgeOverlap() {
<Badge color="secondary" badgeContent=" " variant="dot">
{rectangle}
</Badge>
<Badge color="secondary" overlap="circle" badgeContent=" ">
<Badge color="secondary" overlap="circular" badgeContent=" ">
{circle}
</Badge>
<Badge color="secondary" overlap="circle" badgeContent=" " variant="dot">
<Badge color="secondary" overlap="circular" badgeContent=" " variant="dot">
{circle}
</Badge>
</div>
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/badges/BadgeOverlap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ export default function BadgeOverlap() {
<Badge color="secondary" badgeContent=" " variant="dot">
{rectangle}
</Badge>
<Badge color="secondary" overlap="circle" badgeContent=" ">
<Badge color="secondary" overlap="circular" badgeContent=" ">
{circle}
</Badge>
<Badge color="secondary" overlap="circle" badgeContent=" " variant="dot">
<Badge color="secondary" overlap="circular" badgeContent=" " variant="dot">
{circle}
</Badge>
</div>
Expand Down
9 changes: 8 additions & 1 deletion packages/material-ui/src/Badge/Badge.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface BadgeTypeMap<P = {}, D extends React.ElementType = 'div'> {
/**
* Wrapped shape the badge should overlap.
*/
overlap?: 'rectangle' | 'circle';
overlap?: 'rectangle' | 'circle' | 'rectangular' | 'circular';
/**
* The content rendered within the badge.
*/
Expand Down Expand Up @@ -63,6 +63,13 @@ export type BadgeClassKey =
| 'anchorOriginTopRightCircle'
| 'anchorOriginBottomRightCircle'
| 'anchorOriginTopLeftCircle'
| 'anchorOriginTopRightRectangular'
| 'anchorOriginBottomRightRectangular'
| 'anchorOriginTopLeftRectangular'
| 'anchorOriginBottomLeftRectangular'
| 'anchorOriginTopRightCircular'
| 'anchorOriginBottomRightCircular'
| 'anchorOriginTopLeftCircular'
| 'invisible';
/**
*
Expand Down
131 changes: 129 additions & 2 deletions packages/material-ui/src/Badge/Badge.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { chainPropTypes } from '@material-ui/utils';
import withStyles from '../styles/withStyles';
import capitalize from '../utils/capitalize';

Expand Down Expand Up @@ -72,6 +73,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="rectangular"`. */
anchorOriginTopRightRectangular: {
top: 0,
right: 0,
transform: 'scale(1) translate(50%, -50%)',
transformOrigin: '100% 0%',
'&$invisible': {
transform: 'scale(0) translate(50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="rectangle"`. */
anchorOriginBottomRightRectangle: {
bottom: 0,
Expand All @@ -82,6 +93,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="rectangular"`. */
anchorOriginBottomRightRectangular: {
bottom: 0,
right: 0,
transform: 'scale(1) translate(50%, 50%)',
transformOrigin: '100% 100%',
'&$invisible': {
transform: 'scale(0) translate(50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="rectangle"`. */
anchorOriginTopLeftRectangle: {
top: 0,
Expand All @@ -92,6 +113,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(-50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="rectangular"`. */
anchorOriginTopLeftRectangular: {
top: 0,
left: 0,
transform: 'scale(1) translate(-50%, -50%)',
transformOrigin: '0% 0%',
'&$invisible': {
transform: 'scale(0) translate(-50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="rectangle"`. */
anchorOriginBottomLeftRectangle: {
bottom: 0,
Expand All @@ -102,6 +133,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(-50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="rectangular"`. */
anchorOriginBottomLeftRectangular: {
bottom: 0,
left: 0,
transform: 'scale(1) translate(-50%, 50%)',
transformOrigin: '0% 100%',
'&$invisible': {
transform: 'scale(0) translate(-50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="circle"`. */
anchorOriginTopRightCircle: {
top: '14%',
Expand All @@ -112,6 +153,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'right' }} overlap="circular"`. */
anchorOriginTopRightCircular: {
top: '14%',
right: '14%',
transform: 'scale(1) translate(50%, -50%)',
transformOrigin: '100% 0%',
'&$invisible': {
transform: 'scale(0) translate(50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="circle"`. */
anchorOriginBottomRightCircle: {
bottom: '14%',
Expand All @@ -122,6 +173,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'right' }} overlap="circular"`. */
anchorOriginBottomRightCircular: {
bottom: '14%',
right: '14%',
transform: 'scale(1) translate(50%, 50%)',
transformOrigin: '100% 100%',
'&$invisible': {
transform: 'scale(0) translate(50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="circle"`. */
anchorOriginTopLeftCircle: {
top: '14%',
Expand All @@ -132,6 +193,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(-50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'top', 'left' }} overlap="circular"`. */
anchorOriginTopLeftCircular: {
top: '14%',
left: '14%',
transform: 'scale(1) translate(-50%, -50%)',
transformOrigin: '0% 0%',
'&$invisible': {
transform: 'scale(0) translate(-50%, -50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="circle"`. */
anchorOriginBottomLeftCircle: {
bottom: '14%',
Expand All @@ -142,6 +213,16 @@ export const styles = (theme) => ({
transform: 'scale(0) translate(-50%, 50%)',
},
},
/* Styles applied to the root element if `anchorOrigin={{ 'bottom', 'left' }} overlap="circular"`. */
anchorOriginBottomLeftCircular: {
bottom: '14%',
left: '14%',
transform: 'scale(1) translate(-50%, 50%)',
transformOrigin: '0% 100%',
'&$invisible': {
transform: 'scale(0) translate(-50%, 50%)',
},
},
/* Pseudo-class to the badge `span` element if `invisible={true}`. */
invisible: {
transition: theme.transitions.create('transform', {
Expand Down Expand Up @@ -235,7 +316,34 @@ Badge.propTypes = {
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object,
classes: chainPropTypes(PropTypes.object, (props) => {
const { classes } = props;
if (classes == null) {
return null;
}

[
['anchorOriginTopRightRectangle', 'anchorOriginTopRightRectangular'],
['anchorOriginBottomRightRectangle', 'anchorOriginBottomRightRectangular'],
['anchorOriginTopLeftRectangle', 'anchorOriginTopLeftRectangular'],
['anchorOriginBottomLeftRectangle', 'anchorOriginBottomLeftRectangular'],
['anchorOriginTopRightCircle', 'anchorOriginTopRightCircular'],
['anchorOriginBottomRightCircle', 'anchorOriginBottomRightCircular'],
['anchorOriginTopLeftCircle', 'anchorOriginTopLeftCircular'],
].forEach(([deprecatedClassKey, newClassKey]) => {
if (
classes[deprecatedClassKey] != null &&
// 2 classnames? one from withStyles the other must be custom
classes[deprecatedClassKey].split(' ').length > 1
) {
throw new Error(
`Material-UI: The \`${deprecatedClassKey}\` class was deprecated. Use \`${newClassKey}\` instead.`,
);
}
});

return null;
}),
/**
* @ignore
*/
Expand All @@ -260,7 +368,26 @@ Badge.propTypes = {
/**
* Wrapped shape the badge should overlap.
*/
overlap: PropTypes.oneOf(['circle', 'rectangle']),
overlap: chainPropTypes(
PropTypes.oneOf(['circle', 'rectangle', 'circular', 'rectangular']),
(props) => {
const { overlap } = props;

if (overlap === 'rectangle') {
throw new Error(
'Material-UI: `overlap="rectangle"` was deprecated. Use `overlap="rectangular"` instead.',
);
}

if (overlap === 'circle') {
throw new Error(
'Material-UI: `overlap="circle"` was deprecated. Use `overlap="circular"` instead.',
);
}

return null;
},
),
/**
* Controls whether the badge is hidden when `badgeContent` is zero.
*/
Expand Down
Loading

0 comments on commit 3225656

Please sign in to comment.