Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
33c8028
Adding initial implementation of AvatarGroup
sopranopillow Apr 29, 2022
11be710
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow Apr 29, 2022
9a6f9b4
change files
sopranopillow Apr 29, 2022
5fe2af0
updating popover surface items to use ul and li, updating slots to be…
sopranopillow May 3, 2022
155cdde
t push
sopranopillow May 4, 2022
6a42db5
updating types and package.json
sopranopillow May 4, 2022
d1a04b9
updating api
sopranopillow May 4, 2022
69625b5
adding missing dependency
sopranopillow May 4, 2022
f5583b2
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 9, 2022
c8bb4c4
removing token replacement in strings, removing commons from types, a…
sopranopillow May 9, 2022
f3bfd1d
reverting yarn.lock
sopranopillow May 9, 2022
ffe8b41
fixing dependencies
sopranopillow May 9, 2022
575d8c6
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 10, 2022
cfeea42
updating types and renaming variables
sopranopillow May 10, 2022
2467069
removing strings prop
sopranopillow May 11, 2022
edbfe66
adding requested changes
sopranopillow May 13, 2022
f3bcb81
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 13, 2022
6fb6258
removing useAvatarGroup.ts
sopranopillow May 13, 2022
cd74a0e
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 17, 2022
5a6bced
adding context to Avatar and AvatarGroup
sopranopillow May 18, 2022
2bd144d
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 18, 2022
9761bab
adding single initial for pie layout
sopranopillow May 18, 2022
136b2ea
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow May 20, 2022
539f419
Adding requested changes
sopranopillow May 20, 2022
f802a98
updating snapshots
sopranopillow May 20, 2022
98c7dd5
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow Jun 2, 2022
43b2213
updating stories
sopranopillow Jun 2, 2022
e8e42a6
Merge branch 'avatargroup-implemenation' of https://github.com/sopran…
sopranopillow Jun 2, 2022
4fee5ba
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow Jun 2, 2022
2118864
removing context form Avatar
sopranopillow Jun 2, 2022
8da8f1f
updating AvatarGroup
sopranopillow Jun 2, 2022
bd3ae84
removing v9 button from AvtarGroup
sopranopillow Jun 2, 2022
7501379
removing styling for trigger
sopranopillow Jun 2, 2022
7801453
updating api
sopranopillow Jun 2, 2022
42cc81a
Adding requested changes
sopranopillow Jun 6, 2022
7f1f741
Merge branch 'master' of https://github.com/microsoft/fluentui into a…
sopranopillow Jun 6, 2022
8d932f2
updating stories and snapshots
sopranopillow Jun 6, 2022
6b38759
adding requested changes
sopranopillow Jun 6, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "none",
"comment": "Adding initial implementation of AvatarGroup",
"packageName": "@fluentui/react-avatar",
"email": "[email protected]",
"dependentChangeType": "none"
}
14 changes: 7 additions & 7 deletions packages/react-components/react-avatar/etc/react-avatar.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

```ts

import { Button } from '@fluentui/react-button';
import type { ComponentProps } from '@fluentui/react-utilities';
import type { ComponentState } from '@fluentui/react-utilities';
import type { ForwardRefComponent } from '@fluentui/react-utilities';
Expand Down Expand Up @@ -52,20 +51,21 @@ export type AvatarGroupItemState = ComponentState<AvatarGroupItemSlots> & {
export type AvatarGroupProps = ComponentProps<AvatarGroupSlots> & {
layout?: 'spread' | 'stack' | 'pie';
maxAvatars?: number;
overflowIndicator?: 'number-overflowed' | 'icon';
overflowIndicator?: 'count' | 'icon';
size?: AvatarSizes;
strings?: AvatarGroupStrings;
};

// @public (undocumented)
export type AvatarGroupSlots = {
root: Slot<'div'>;
popoverTrigger?: Slot<typeof Button>;
popoverSurface?: Slot<typeof PopoverSurface>;
root: NonNullable<Slot<'div'>>;
overflowButton?: NonNullable<Slot<'button'>>;
overflowList?: NonNullable<Slot<'ul'>>;
overflowSurface?: NonNullable<Slot<typeof PopoverSurface>>;
};

// @public
export type AvatarGroupState = ComponentState<AvatarGroupSlots> & Required<Pick<AvatarGroupProps, 'layout' | 'maxAvatars' | 'size' | 'overflowIndicator'>> & {
export type AvatarGroupState = ComponentState<AvatarGroupSlots> & Required<Pick<AvatarGroupProps, 'layout' | 'size' | 'overflowIndicator'>> & {
hasOverflow: boolean;
tooltipContent: TooltipProps['content'];
};

Expand Down
1 change: 0 additions & 1 deletion packages/react-components/react-avatar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
},
"dependencies": {
"@fluentui/react-badge": "9.0.0-rc.12",
"@fluentui/react-button": "9.0.0-rc.13",
"@fluentui/react-context-selector": "9.0.0-rc.10",
"@fluentui/react-icons": "^2.0.166-rc.3",
"@fluentui/react-popover": "9.0.0-rc.13",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ const useStyles = makeStyles({
icon48: { fontSize: '48px' },
});

const useSizeStyles = makeStyles({
export const useSizeStyles = makeStyles({
16: { width: '16px', height: '16px' },
20: { width: '20px', height: '20px' },
24: { width: '24px', height: '24px' },
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { AvatarGroup } from './AvatarGroup';
import { AvatarGroupItem } from '../AvatarGroupItem';
import { isConformant } from '../../common/isConformant';
import { render } from '@testing-library/react';

describe('AvatarGroup', () => {
// TODO: Remove component-has-static-classnames-object from disabled tests.
Expand All @@ -18,7 +19,19 @@ describe('AvatarGroup', () => {
// TODO add more tests here, and create visual regression tests in /apps/vr-tests

it('renders a default state', () => {
const result = render(<AvatarGroup>Default AvatarGroup</AvatarGroup>);
const result = render(
<AvatarGroup>
<AvatarGroupItem name="Katri Athokas" />
<AvatarGroupItem name="Elvia Atkins" />
<AvatarGroupItem name="Cameron Evans" />
<AvatarGroupItem name="Wanda Howard" />
<AvatarGroupItem name="Mona Kane" />
<AvatarGroupItem name="Allan Munger" />
<AvatarGroupItem name="Daisy Phillips" />
<AvatarGroupItem name="Robert Tolbert" />
<AvatarGroupItem name="Kevin Sturgis" />
</AvatarGroup>,
);
expect(result.container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import type { AvatarGroupProps } from './AvatarGroup.types';
import type { ForwardRefComponent } from '@fluentui/react-utilities';

/**
* AvatarGroup component - TODO: add more docs
* The AvatarGroup component represents a group of multiple people or entities by taking care of the arrangement
* of individual Avatars in a spread, stack, or pie layout.
*/
export const AvatarGroup: ForwardRefComponent<AvatarGroupProps> = React.forwardRef((props, ref) => {
const state = useAvatarGroup_unstable(props, ref);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { Button } from '@fluentui/react-button';
import { PopoverSurface } from '@fluentui/react-popover';
import { TooltipProps } from '@fluentui/react-tooltip';
import type { AvatarSizes } from '../Avatar/Avatar.types';
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';

export type AvatarGroupSlots = {
root: Slot<'div'>;
root: NonNullable<Slot<'div'>>;

/**
* Popover trigger slot that can be used to change the overflow indicator.
*/
popoverTrigger?: Slot<typeof Button>;
overflowButton?: NonNullable<Slot<'button'>>;

/**
* Unordered list that contains the overflow AvatarGroupItems.
*/
overflowList?: NonNullable<Slot<'ul'>>;

/**
* Popover surface that will be displayed when the popover is triggered.
*/
popoverSurface?: Slot<typeof PopoverSurface>;
overflowSurface?: NonNullable<Slot<typeof PopoverSurface>>;
};

/**
Expand All @@ -30,42 +34,38 @@ export type AvatarGroupProps = ComponentProps<AvatarGroupSlots> & {

/**
* Maximum number of Avatars to be displayed before overflowing.
* NOTE: if pie layout is used, `maxAvatars` will be ignored.
* Note: if pie layout is used, `maxAvatars` will be ignored.
* @default 5
*/
maxAvatars?: number;

/**
* Whether the overflow indicator should render an icon instead of the number of overflowed avatars.
* @default false
* Note: The overflowIndicator will default to `icon` when the size is less than 24.
* @default count
*/
overflowIndicator?: 'number-overflowed' | 'icon';
overflowIndicator?: 'count' | 'icon';

/**
* Size of the avatars.
* @default 32
*/
size?: AvatarSizes;

/**
* Strings for localizing text in the tooltip.
*/
strings?: AvatarGroupStrings;
};

/**
* State used in rendering AvatarGroup
*/
export type AvatarGroupState = ComponentState<AvatarGroupSlots> &
Required<Pick<AvatarGroupProps, 'layout' | 'maxAvatars' | 'size' | 'overflowIndicator'>> & {
Required<Pick<AvatarGroupProps, 'layout' | 'size' | 'overflowIndicator'>> & {
/**
* Whether there are more Avatars than `maxAvatars`.
* @default false
*/
hasOverflow: boolean;

/**
* Tooltip content for the overflow indicator.
*/
tooltipContent: TooltipProps['content'];
};

// TODO: Remove strings from AvatarGroup.
export type AvatarGroupStrings = {
/**
* Text applied to the overflow indicator's tooltip.
* Can include the token "\{numOverflowedAvatars\}" which will be replaced with the number of overflowed avatars.
*/
tooltipContent: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,84 @@ exports[`AvatarGroup renders a default state 1`] = `
<div>
<div
class="fui-AvatarGroup"
role="group"
>
Default AvatarGroup
<div
class="fui-AvatarGroupItem"
>
<span
aria-label="Allan Munger"
class="fui-Avatar fui-AvatarGroupItem__avatar"
id="avatar-1"
role="img"
>
<span
class="fui-Avatar__initials"
id="avatar-1__initials"
>
AM
</span>
</span>
</div>
<div
class="fui-AvatarGroupItem"
>
<span
aria-label="Daisy Phillips"
class="fui-Avatar fui-AvatarGroupItem__avatar"
id="avatar-2"
role="img"
>
<span
class="fui-Avatar__initials"
id="avatar-2__initials"
>
DP
</span>
</span>
</div>
<div
class="fui-AvatarGroupItem"
>
<span
aria-label="Robert Tolbert"
class="fui-Avatar fui-AvatarGroupItem__avatar"
id="avatar-3"
role="img"
>
<span
class="fui-Avatar__initials"
id="avatar-3__initials"
>
RT
</span>
</span>
</div>
<div
class="fui-AvatarGroupItem"
>
<span
aria-label="Kevin Sturgis"
class="fui-Avatar fui-AvatarGroupItem__avatar"
id="avatar-4"
role="img"
>
<span
class="fui-Avatar__initials"
id="avatar-4__initials"
>
KS
</span>
</span>
</div>
<button
aria-expanded="false"
aria-label="View more people."
class="fui-AvatarGroup__overflowButton"
data-tabster="{\\"deloser\\":{}}"
>
+5
</button>
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import * as React from 'react';
import { Popover, PopoverTrigger } from '@fluentui/react-popover';
import { Tooltip } from '@fluentui/react-tooltip';
import { getSlots } from '@fluentui/react-utilities';
import { AvatarGroupContext } from '../../contexts/AvatarGroupContext';
import type { AvatarGroupState, AvatarGroupSlots } from './AvatarGroup.types';

/**
* Render the final JSX of AvatarGroup
*/
export const renderAvatarGroup_unstable = (state: AvatarGroupState) => {
const { slots, slotProps } = getSlots<AvatarGroupSlots>(state);
const { layout, size } = state;

// TODO Add additional slots in the appropriate place
return <slots.root {...slotProps.root} />;
return (
<AvatarGroupContext.Provider value={{ layout, size }}>
<slots.root {...slotProps.root}>
{state.root.children}
{state.hasOverflow && slots.overflowButton && slots.overflowSurface && slots.overflowList && (
<Popover trapFocus size="small">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also need a slot for this Popover so it can be configured by the user (fine to do in a separate PR).

Copy link
Contributor Author

@sopranopillow sopranopillow Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Popover is not rendered as an element, it cannot be made into a slot.

<PopoverTrigger>
<Tooltip content={state.tooltipContent} relationship="label">
<slots.overflowButton {...slotProps.overflowButton} />
</Tooltip>
</PopoverTrigger>
<slots.overflowSurface {...slotProps.overflowSurface}>
<AvatarGroupContext.Provider value={{ isOverflow: true, layout, size: 24 }}>
<slots.overflowList {...slotProps.overflowList} />
</AvatarGroupContext.Provider>
</slots.overflowSurface>
</Popover>
)}
</slots.root>
</AvatarGroupContext.Provider>
);
};

This file was deleted.

Loading