Skip to content

Commit

Permalink
feat(AvatarStack): add total prop (#1869)
Browse files Browse the repository at this point in the history
  • Loading branch information
ogonkov authored Sep 24, 2024
1 parent 052889d commit 29c9084
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/components/AvatarStack/AvatarStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const b = block('avatar-stack');

const AvatarStackComponent = ({
max = 3,
total,
overlapSize = 's',
size,
children,
Expand All @@ -22,6 +23,7 @@ const AvatarStackComponent = ({
}: AvatarStackProps) => {
const visibleItems: React.ReactElement[] = [];
let moreItems = 0;
const normalizedMax = max < 1 ? 1 : max;

React.Children.forEach(children, (child) => {
if (!React.isValidElement(child)) {
Expand All @@ -30,13 +32,15 @@ const AvatarStackComponent = ({

const item = <AvatarStackItem key={visibleItems.length}>{child}</AvatarStackItem>;

if (visibleItems.length <= max) {
if (visibleItems.length <= normalizedMax) {
visibleItems.unshift(item);
} else {
moreItems += 1;
}
});

moreItems = Math.max(moreItems, total ? total - normalizedMax : 0);

const hasMoreButton = moreItems > 0;
/** Avatars + more button, or just avatars, when avatars count is equal to `max` or less */
const normalOverflow = moreItems >= 1;
Expand All @@ -59,7 +63,7 @@ const AvatarStackComponent = ({
)}
</AvatarStackItem>
) : null}
{normalOverflow ? visibleItems.slice(0, max) : visibleItems}
{normalOverflow ? visibleItems.slice(0, normalizedMax) : visibleItems}
</ul>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/components/AvatarStack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Component is not limit you to what components to render, basic usage is:
| Name | Description | Type | Default |
| :---------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------: | :-----: |
| max | How much avatars should be visible before more button. If avatars count is only 1 short from `max`, than more button would be replaced with avatar. | `number` | 3 |
| total | Total amount of items, used to calculate number of not rendered avatars | `number` | |
| overlapSize | How much each item should overlap next one. `s` recommended for `Avatar`'s of sizes `xs`-`m`, `m` recomended for `l` size avatars and `l` overlap for `xl` avatars | `s`, `m`, `l` | `s` |
| size | Size for control displaying extra avatars. Value same to `Avatar` size. | `AvatarSize` | |
| className | Class name of root DOM node | `string` | |
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ export const MoreButton: Story = {
render: getTemplate({count: 6}),
};

export const Total: Story = {
render: getTemplate({count: 6}),
args: {
max: 3,
total: 12,
},
};

export const MoreButtonOmit: Story = {
render: getTemplate({count: 4}),
parameters: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ test.describe('AvatarStack', () => {

await expectScreenshot();
});

test('render story <Total>', async ({mount, expectScreenshot}) => {
await mount(<AvatarStackStories.Total randomAvatar={false} />);

await expectScreenshot();
});
});
2 changes: 2 additions & 0 deletions src/components/AvatarStack/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export type AvatarStackOverlapSize = 's' | 'm' | 'l';
export interface AvatarStackProps {
/** Amount of avatars to be shown before more button. Default 3. */
max?: number;
/** Total amount of items, used to calculate number of not rendered avatars */
total?: number;
/**
* How much each avatar should overlap next one
* | Avatar sizes | Recommended overlap |
Expand Down

0 comments on commit 29c9084

Please sign in to comment.