Skip to content

Commit

Permalink
[AvatarGroup] Add max avatar prop (mui#19853)
Browse files Browse the repository at this point in the history
  • Loading branch information
GFynbo authored and EsoterikStare committed Mar 30, 2020
1 parent 4cdb31c commit 7fe7c75
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 12 deletions.
1 change: 1 addition & 0 deletions docs/pages/api-docs/avatar-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
|:-----|:-----|:--------|:------------|
| <span class="prop-name">children</span> | <span class="prop-type">node</span> | | The avatars to stack. |
| <span class="prop-name">classes</span> | <span class="prop-type">object</span> | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. |
| <span class="prop-name">max</span> | <span class="prop-type">number</span> | <span class="prop-default">5</span> | Max avatars to show before +x. |
| <span class="prop-name">spacing</span> | <span class="prop-type">'medium'<br>&#124;&nbsp;'small'<br>&#124;&nbsp;number</span> | <span class="prop-default">'medium'</span> | Spacing between avatars. |

The `ref` is forwarded to the root element.
Expand Down
7 changes: 2 additions & 5 deletions docs/src/pages/components/avatars/GroupAvatars.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import React from 'react';
import Avatar from '@material-ui/core/Avatar';
import AvatarGroup from '@material-ui/lab/AvatarGroup';
import Tooltip from '@material-ui/core/Tooltip';

export default function GroupAvatars() {
return (
<AvatarGroup>
<AvatarGroup max={3}>
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
<Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />
<Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />
<Tooltip title="Foo • Bar • Baz">
<Avatar>+3</Avatar>
</Tooltip>
<Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />
</AvatarGroup>
);
}
7 changes: 2 additions & 5 deletions docs/src/pages/components/avatars/GroupAvatars.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import React from 'react';
import Avatar from '@material-ui/core/Avatar';
import AvatarGroup from '@material-ui/lab/AvatarGroup';
import Tooltip from '@material-ui/core/Tooltip';

export default function GroupAvatars() {
return (
<AvatarGroup>
<AvatarGroup max={3}>
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
<Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />
<Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />
<Tooltip title="Foo • Bar • Baz">
<Avatar>+3</Avatar>
</Tooltip>
<Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" />
</AvatarGroup>
);
}
4 changes: 4 additions & 0 deletions packages/material-ui-lab/src/AvatarGroup/AvatarGroup.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export interface AvatarGroupProps
* The avatars to stack.
*/
children: React.ReactNode;
/**
* Max avatars to show before +x.
*/
max?: number;
/**
* Spacing between avatars.
*/
Expand Down
29 changes: 27 additions & 2 deletions packages/material-ui-lab/src/AvatarGroup/AvatarGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { isFragment } from 'react-is';
import clsx from 'clsx';
import { withStyles } from '@material-ui/core/styles';
import Avatar from '@material-ui/core/Avatar';

const SPACINGS = {
small: -16,
Expand All @@ -22,7 +23,14 @@ export const styles = theme => ({
});

const AvatarGroup = React.forwardRef(function AvatarGroup(props, ref) {
const { children: childrenProp, classes, className, spacing = 'medium', ...other } = props;
const {
children: childrenProp,
classes,
className,
spacing = 'medium',
max = 5,
...other
} = props;

const children = React.Children.toArray(childrenProp).filter(child => {
if (process.env.NODE_ENV !== 'production') {
Expand All @@ -39,9 +47,11 @@ const AvatarGroup = React.forwardRef(function AvatarGroup(props, ref) {
return React.isValidElement(child);
});

const extraAvatars = children.length > max ? children.length - max : 0;

return (
<div className={clsx(classes.root, className)} ref={ref} {...other}>
{children.map((child, index) => {
{children.slice(0, children.length - extraAvatars).map((child, index) => {
return React.cloneElement(child, {
className: clsx(child.props.className, classes.avatar),
style: {
Expand All @@ -51,6 +61,17 @@ const AvatarGroup = React.forwardRef(function AvatarGroup(props, ref) {
},
});
})}
{extraAvatars ? (
<Avatar
className={classes.avatar}
style={{
zIndex: 0,
marginLeft: spacing && SPACINGS[spacing] !== undefined ? SPACINGS[spacing] : -spacing,
}}
>
+{extraAvatars}
</Avatar>
) : null}
</div>
);
});
Expand All @@ -73,6 +94,10 @@ AvatarGroup.propTypes = {
* @ignore
*/
className: PropTypes.string,
/**
* Max avatars to show before +x.
*/
max: PropTypes.number,
/**
* Spacing between avatars.
*/
Expand Down
16 changes: 16 additions & 0 deletions packages/material-ui-lab/src/AvatarGroup/AvatarGroup.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import * as React from 'react';
import { expect } from 'chai';
import { createMount, getClasses } from '@material-ui/core/test-utils';
import describeConformance from '@material-ui/core/test-utils/describeConformance';
import { createClientRender } from 'test/utils/createClientRender';
import AvatarGroup from './AvatarGroup';
import { Avatar } from '@material-ui/core';

describe('<AvatarGroup />', () => {
let mount;
let classes;
const render = createClientRender();

before(() => {
mount = createMount({ strict: true });
Expand All @@ -23,4 +27,16 @@ describe('<AvatarGroup />', () => {
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
}));

it('should not display all the avatars', () => {
const { container } = render(
<AvatarGroup max={1}>
<Avatar src="broken-url" />
<Avatar src="broken-url" />
<Avatar src="broken-url" />
</AvatarGroup>,
);
expect(container.querySelectorAll('img').length).to.equal(1);
expect(container.textContent).to.equal('+2');
});
});

0 comments on commit 7fe7c75

Please sign in to comment.