Skip to content

Commit

Permalink
[AvatarGroup] Introduce new component
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Dec 6, 2019
1 parent c98b9c4 commit 69e8ced
Show file tree
Hide file tree
Showing 25 changed files with 271 additions and 14 deletions.
7 changes: 7 additions & 0 deletions docs/pages/api/avatar-group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import markdown from './avatar-group.md';

export default function Page() {
return <MarkdownDocs markdown={markdown} />;
}
51 changes: 51 additions & 0 deletions docs/pages/api/avatar-group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
filename: /packages/material-ui/src/AvatarGroup/AvatarGroup.js
---

<!--- This documentation is automatically generated, do not try to edit it. -->

# AvatarGroup API

<p class="description">The API documentation of the AvatarGroup React component. Learn more about the props and the CSS customization points.</p>

## Import

```js
import AvatarGroup from '@material-ui/core/AvatarGroup';
// or
import { AvatarGroup } from '@material-ui/core';
```

You can learn more about the difference by [reading this guide](/guides/minimizing-bundle-size/).



## Props

| Name | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| <span class="prop-name">children</span> | <span class="prop-type">node</span> | | Used to render icon or text elements inside the AvatarGroup if `src` is not set. This can be an element, or just a string. |
| <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. |

The `ref` is forwarded to the root element.

Any other props supplied will be provided to the root element (native element).

## CSS

- Style sheet name: `MuiAvatarGroup`.
- Style sheet details:

| Rule name | Global class | Description |
|:-----|:-------------|:------------|
| <span class="prop-name">root</span> | <span class="prop-name">.MuiAvatarGroup-root</span> | Styles applied to the root element.
| <span class="prop-name">avatar</span> | <span class="prop-name">.MuiAvatarGroup-avatar</span> | Styles applied to the avatar elements.

You can override the style of the component thanks to one of these customization points:

- With a rule name of the [`classes` object prop](/customization/components/#overriding-styles-with-classes).
- With a [global class name](/customization/components/#overriding-styles-with-global-class-names).
- With a theme and an [`overrides` property](/customization/globals/#css).

If that's not sufficient, you can check the [implementation of the component](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/AvatarGroup/AvatarGroup.js) for more detail.

16 changes: 16 additions & 0 deletions docs/src/pages/components/avatars/BadgeAvatars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import Badge from '@material-ui/core/Badge';
import Avatar from '@material-ui/core/Avatar';

export default function BadgeAvatars() {
return (
<Badge
overlap="circle"
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
badgeContent={1}
color="error"
>
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</Badge>
);
}
16 changes: 16 additions & 0 deletions docs/src/pages/components/avatars/BadgeAvatars.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import Badge from '@material-ui/core/Badge';
import Avatar from '@material-ui/core/Avatar';

export default function BadgeAvatars() {
return (
<Badge
overlap="circle"
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
badgeContent={1}
color="error"
>
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</Badge>
);
}
17 changes: 17 additions & 0 deletions docs/src/pages/components/avatars/GroupAvatars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import Avatar from '@material-ui/core/Avatar';
import AvatarGroup from '@material-ui/core/AvatarGroup';
import Tooltip from '@material-ui/core/Tooltip';

export default function GroupAvatars() {
return (
<AvatarGroup>
<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>
</AvatarGroup>
);
}
17 changes: 17 additions & 0 deletions docs/src/pages/components/avatars/GroupAvatars.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import Avatar from '@material-ui/core/Avatar';
import AvatarGroup from '@material-ui/core/AvatarGroup';
import Tooltip from '@material-ui/core/Tooltip';

export default function GroupAvatars() {
return (
<AvatarGroup>
<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>
</AvatarGroup>
);
}
2 changes: 1 addition & 1 deletion docs/src/pages/components/avatars/IconAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const useStyles = makeStyles(theme => ({
},
},
pink: {
color: '#fff',
color: theme.palette.getContrastText(pink[500]),
backgroundColor: pink[500],
},
green: {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/components/avatars/IconAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const useStyles = makeStyles((theme: Theme) =>
},
},
pink: {
color: '#fff',
color: theme.palette.getContrastText(pink[500]),
backgroundColor: pink[500],
},
green: {
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/avatars/LetterAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const useStyles = makeStyles(theme => ({
},
},
orange: {
color: '#fff',
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
},
purple: {
color: '#fff',
color: theme.palette.getContrastText(deepPurple[500]),
backgroundColor: deepPurple[500],
},
}));
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/avatars/LetterAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ const useStyles = makeStyles((theme: Theme) =>
},
},
orange: {
color: '#fff',
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
},
purple: {
color: '#fff',
color: theme.palette.getContrastText(deepPurple[500]),
backgroundColor: deepPurple[500],
},
}),
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/components/avatars/VariantAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const useStyles = makeStyles(theme => ({
},
},
square: {
color: '#fff',
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
},
rounded: {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/pages/components/avatars/VariantAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const useStyles = makeStyles((theme: Theme) =>
},
},
square: {
color: '#fff',
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
},
rounded: {
Expand Down
10 changes: 10 additions & 0 deletions docs/src/pages/components/avatars/avatars.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ Icon avatars are created by passing an icon as `children`.
If you need square or rounded avatars, use the `variant` prop.

{{"demo": "pages/components/avatars/VariantAvatars.js"}}

## With badge

{{"demo": "pages/components/avatars/BadgeAvatars.js"}}

## Grouped

`AvatarGroup` is a wrapper around avatars designed to render a stacked collection of avatars.

{{"demo": "pages/components/avatars/GroupAvatars.js"}}
4 changes: 2 additions & 2 deletions docs/src/pages/components/badges/CustomizedBadges.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function CustomizedBadges() {
}}
variant="dot"
>
<Avatar alt="Stock avatar" src="/static/images/avatar/1.jpg" />
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</StyledBadge2>
</Box>
<Box m={1}>
Expand All @@ -81,7 +81,7 @@ export default function CustomizedBadges() {
}}
badgeContent={<SmallAvatar alt="Stock avatar" src="/static/images/avatar/1.jpg" />}
>
<Avatar alt="Stock avatar" src="/static/images/avatar/2.jpg" />
<Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />
</Badge>
</Box>
</Box>
Expand Down
4 changes: 2 additions & 2 deletions docs/src/pages/components/badges/CustomizedBadges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function CustomizedBadges() {
}}
variant="dot"
>
<Avatar alt="Stock avatar" src="/static/images/avatar/1.jpg" />
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</StyledBadge2>
</Box>
<Box m={1}>
Expand All @@ -87,7 +87,7 @@ export default function CustomizedBadges() {
}}
badgeContent={<SmallAvatar alt="Stock avatar" src="/static/images/avatar/1.jpg" />}
>
<Avatar alt="Stock avatar" src="/static/images/avatar/2.jpg" />
<Avatar alt="Travis Howard" src="/static/images/avatar/2.jpg" />
</Badge>
</Box>
</Box>
Expand Down
14 changes: 14 additions & 0 deletions packages/material-ui/src/AvatarGroup/AvatarGroup.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from 'react';
import { StandardProps, PropTypes } from '..';

export interface AvatarGroupProps
extends StandardProps<React.HTMLAttributes<HTMLDivElement>, AvatarGroupClassKey> {
/**
* The badge will be added relative to this node.
*/
children: React.ReactNode;
}

export type AvatarGroupClassKey = 'root' | 'avatar';

export default function AvatarGroup(props: AvatarGroupProps): JSX.Element | null;
72 changes: 72 additions & 0 deletions packages/material-ui/src/AvatarGroup/AvatarGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import PropTypes from 'prop-types';
import { isFragment } from 'react-is';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';

export const styles = theme => ({
/* Styles applied to the root element. */
root: {
display: 'flex',
},
/* Styles applied to the avatar elements. */
avatar: {
border: `2px solid ${theme.palette.background.default}`,
marginLeft: -8,
},
});

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

const children = React.Children.toArray(childrenProp).filter(child => {
if (process.env.NODE_ENV !== 'production') {
if (isFragment(child)) {
console.error(
[
"Material-UI: the Breadcrumbs component doesn't accept a Fragment as a child.",
'Consider providing an array instead.',
].join('\n'),
);
}
}

return React.isValidElement(child);
});

return (
<div className={clsx(classes.root, className)} ref={ref} {...other}>
{children.map((child, index) => {
return React.cloneElement(child, {
className: clsx(child.props.className, classes.avatar),
style: {
zIndex: children.length - index,
...child.props.style,
},
});
})}
</div>
);
});

AvatarGroup.propTypes = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the d.ts file and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The badge will be added relative to this node.
*/
children: PropTypes.node,
/**
* Override or extend the styles applied to the component.
* See [CSS API](#css) below for more details.
*/
classes: PropTypes.object,
/**
* @ignore
*/
className: PropTypes.string,
};

export default withStyles(styles, { name: 'MuiAvatarGroup' })(AvatarGroup);
26 changes: 26 additions & 0 deletions packages/material-ui/src/AvatarGroup/AvatarGroup.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { createMount, getClasses } from '@material-ui/core/test-utils';
import describeConformance from '../test-utils/describeConformance';
import AvatarGroup from './AvatarGroup';

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

before(() => {
mount = createMount({ strict: true });
classes = getClasses(<AvatarGroup />);
});

after(() => {
mount.cleanUp();
});

describeConformance(<AvatarGroup />, () => ({
classes,
inheritComponent: 'div',
mount,
refInstanceof: window.HTMLDivElement,
skip: ['componentProp'],
}));
});
2 changes: 2 additions & 0 deletions packages/material-ui/src/AvatarGroup/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './AvatarGroup';
export * from './AvatarGroup';
1 change: 1 addition & 0 deletions packages/material-ui/src/AvatarGroup/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './AvatarGroup';
2 changes: 0 additions & 2 deletions packages/material-ui/src/Badge/Badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ export const styles = theme => ({
padding: '0 6px',
height: RADIUS_STANDARD * 2,
borderRadius: RADIUS_STANDARD,
backgroundColor: theme.palette.color,
color: theme.palette.textColor,
zIndex: 1, // Render the badge on top of potential ripples.
transition: theme.transitions.create('transform', {
easing: theme.transitions.easing.easeInOut,
Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export * from './AppBar';
export { default as Avatar } from './Avatar';
export * from './Avatar';

export { default as AvatarGroup } from './AvatarGroup';
export * from './AvatarGroup';

export { default as Backdrop } from './Backdrop';
export * from './Backdrop';

Expand Down
3 changes: 3 additions & 0 deletions packages/material-ui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export * from './AppBar';
export { default as Avatar } from './Avatar';
export * from './Avatar';

export { default as AvatarGroup } from './AvatarGroup';
export * from './AvatarGroup';

export { default as Backdrop } from './Backdrop';
export * from './Backdrop';

Expand Down
Loading

0 comments on commit 69e8ced

Please sign in to comment.