-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c327189
commit 2dfe0fa
Showing
8 changed files
with
345 additions
and
3 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
src/plugins/components/avatar-group/avatar-group.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { html } from 'lit' | ||
import { spread } from '@open-wc/lit-helpers' | ||
|
||
import type { AvatarGroupAttrs } from './avatar-group.types' | ||
import { Avatar } from '../avatar/avatar.component' | ||
import * as variants from './avatar-group.variants' | ||
|
||
/** | ||
* Primary UI component for user interaction | ||
*/ | ||
export const AvatarGroup = ({ | ||
avatars, | ||
size = 'sm', | ||
limit = 4, | ||
...attrs | ||
}: AvatarGroupAttrs) => { | ||
return html` | ||
<div | ||
class=${['nui-avatar-group', size && variants.size[size]] | ||
.filter(Boolean) | ||
.join(' ')} | ||
${spread(attrs)} | ||
> | ||
${avatars.map( | ||
(avatar) => html` | ||
<div class="nui-avatar-outer"> | ||
${Avatar({ | ||
shape: 'full', | ||
size: size, | ||
src: avatar.src, | ||
'data-nui-tooltip': avatar.text, | ||
})} | ||
</div> | ||
`, | ||
)} | ||
${avatars.length > limit | ||
? html` | ||
<div class="nui-avatar-count"> | ||
<div class="nui-avatar-count-inner"> | ||
<span class="nui-avatar-count-text"> | ||
+${avatars.length - limit + 1} | ||
</span> | ||
</div> | ||
</div> | ||
` | ||
: ''} | ||
</div> | ||
` | ||
} |
104 changes: 104 additions & 0 deletions
104
src/plugins/components/avatar-group/avatar-group.doc.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Meta, Primary, Controls, Story } from '@storybook/blocks' | ||
import * as AvatarGroupStories from './avatar-group.stories' | ||
import { defaultAvatarGroupConfig } from '.' | ||
|
||
<Meta of={AvatarGroupStories} /> | ||
|
||
# Avatar group | ||
|
||
Avatars groups can have different sizes. This example shows an avatar group using the xs size. Use the size prop to change the size of the avatar group. | ||
|
||
<Primary /> | ||
|
||
## Props | ||
|
||
<Controls /> | ||
|
||
## Variants | ||
|
||
<br /> | ||
|
||
### Size: xxs | ||
|
||
Avatars can have different sizes and different shapes. The below examples shows all avatar sizes for the full shape. | ||
|
||
<div className="flex gap-2 bg-slate-100 dark:bg-slate-900 p-6 rounded-sm"> | ||
<Story of={AvatarGroupStories.SizeXxs} /> | ||
</div> | ||
|
||
<br /> | ||
|
||
### Size: xs | ||
|
||
Avatars can have different sizes and different shapes. The below examples shows all avatar sizes for the full shape. | ||
|
||
<div className="flex gap-2 bg-slate-100 dark:bg-slate-900 p-6 rounded-sm"> | ||
<Story of={AvatarGroupStories.SizeXs} /> | ||
</div> | ||
|
||
<br /> | ||
|
||
### Size: sm | ||
|
||
Avatars can have different sizes and different shapes. The below examples shows all avatar sizes for the full shape. | ||
|
||
<div className="flex gap-2 bg-slate-100 dark:bg-slate-900 p-6 rounded-sm"> | ||
<Story of={AvatarGroupStories.SizeSm} /> | ||
</div> | ||
|
||
<br /> | ||
|
||
### Size: md | ||
|
||
Avatars can have different sizes and different shapes. The below examples shows all avatar sizes for the full shape. | ||
|
||
<div className="flex gap-2 bg-slate-100 dark:bg-slate-900 p-6 rounded-sm"> | ||
<Story of={AvatarGroupStories.SizeMd} /> | ||
</div> | ||
|
||
<br /> | ||
|
||
### Size: Lg | ||
Avatars can have different sizes and different shapes. The below examples shows all avatar sizes for the full shape. | ||
|
||
<div className="flex gap-2 bg-slate-100 dark:bg-slate-900 p-6 rounded-sm"> | ||
<Story of={AvatarGroupStories.SizeLg} /> | ||
</div> | ||
|
||
<br /> | ||
<br /> | ||
|
||
## Customization | ||
|
||
### Default config | ||
|
||
<div class="relative"> | ||
<details class="relative bg-slate-50 border border-slate-200 rounded-lg p-4 [&>summary>svg]:open:-rotate-180"> | ||
<summary class="list-none cursor-pointer"> | ||
<span class="font-sans text-slate-500">View configuration options</span> | ||
<svg | ||
class="w-5 h-5 text-slate-500 absolute top-5 end-4 transition-transform duration-300" | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="32" | ||
height="32" | ||
viewBox="0 0 24 24" | ||
> | ||
<path | ||
fill="none" | ||
stroke="currentColor" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
stroke-width="2" | ||
d="m6 9l6 6l6-6" | ||
/> | ||
</svg> | ||
</summary> | ||
|
||
<div class="!mt-4"> | ||
<pre > | ||
{JSON.stringify(defaultAvatarGroupConfig, null, 2)} | ||
</pre> | ||
</div> | ||
|
||
</details> | ||
</div> |
127 changes: 127 additions & 0 deletions
127
src/plugins/components/avatar-group/avatar-group.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import type { Meta, StoryObj } from '@storybook/web-components' | ||
import { html } from 'lit' | ||
|
||
import type { AvatarGroupAttrs } from './avatar-group.types' | ||
import { AvatarGroup } from './avatar-group.component' | ||
|
||
const demoAvatars = [ | ||
{ | ||
src: 'https://apollux.cssninja.io/img/avatars/10.svg', | ||
srcDark: 'https://apollux.cssninja.io/img/avatars/10.svg', | ||
text: 'Kendra Wilson', | ||
}, | ||
{ | ||
src: 'https://apollux.cssninja.io/img/avatars/12.svg', | ||
srcDark: 'https://apollux.cssninja.io/img/avatars/12.svg', | ||
text: 'Ella Milburn', | ||
}, | ||
{ | ||
src: 'https://apollux.cssninja.io/img/avatars/8.svg', | ||
srcDark: 'https://apollux.cssninja.io/img/avatars/8.svg', | ||
text: 'John Baxter', | ||
}, | ||
{ | ||
src: 'https://apollux.cssninja.io/img/avatars/24.svg', | ||
srcDark: 'https://apollux.cssninja.io/img/avatars/24.svg', | ||
text: 'Anna Lopez', | ||
}, | ||
{ | ||
src: 'https://apollux.cssninja.io/img/avatars/25.svg', | ||
srcDark: 'https://apollux.cssninja.io/img/avatars/25.svg', | ||
text: 'Melany Smith', | ||
}, | ||
] | ||
|
||
// More on how to set up stories at: https://storybook.js.org/docs/web-components/writing-stories/introduction | ||
const meta = { | ||
title: 'Shuriken UI/Base/Avatar Group', | ||
// tags: ['autodocs'], | ||
render: (args) => AvatarGroup(args), | ||
argTypes: { | ||
size: { | ||
control: { type: 'select' }, | ||
options: ['xxs', 'xs', 'sm', 'md', 'lg'], | ||
defaultValue: 'sm', | ||
}, | ||
limit: { | ||
control: { type: 'number' }, | ||
defaultValue: 4, | ||
}, | ||
avatars: { | ||
control: { type: 'array' }, | ||
defaultValue: demoAvatars, | ||
}, | ||
}, | ||
} satisfies Meta<AvatarGroupAttrs> | ||
|
||
export default meta | ||
type Story = StoryObj<AvatarGroupAttrs> | ||
|
||
// first export is the Primary story | ||
|
||
// #region Main | ||
export const Main: Story = { | ||
name: 'Main example', | ||
args: { | ||
// set default values used for UI preview | ||
size: 'lg', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion | ||
|
||
// #region Size:XXs | ||
export const SizeXxs: Story = { | ||
name: 'Size: xxs', | ||
args: { | ||
size: 'xxs', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion | ||
|
||
// #region Size:Xs | ||
export const SizeXs: Story = { | ||
name: 'Size: xs', | ||
args: { | ||
size: 'xs', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion | ||
|
||
// #region Size:Sm | ||
export const SizeSm: Story = { | ||
name: 'Size: sm', | ||
args: { | ||
size: 'sm', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion | ||
|
||
// #region Size:Md | ||
export const SizeMd: Story = { | ||
name: 'Size: md', | ||
args: { | ||
size: 'md', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion | ||
|
||
// #region Size:Lg | ||
export const SizeLg: Story = { | ||
name: 'Size: lg', | ||
args: { | ||
size: 'lg', | ||
limit: 4, | ||
avatars: demoAvatars, | ||
}, | ||
} | ||
// #endregion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { axe } from 'vitest-axe' | ||
import { expect, test, describe } from 'vitest' | ||
import { render, html } from 'lit' | ||
|
||
import { AvatarGroup } from './avatar-group.component' | ||
|
||
describe('AvatarGroup', () => { | ||
test('Should render slot', () => { | ||
const avatarGroup = AvatarGroup({ | ||
size: 'sm', | ||
avatars: [], | ||
}) | ||
|
||
render(avatarGroup, document.body) | ||
|
||
expect( | ||
document.body.querySelector('.nui-avatar-group')?.outerHTML, | ||
)?.toContain('Hello world') | ||
}) | ||
|
||
test('Should have no axe violations', async () => { | ||
const avatarGroup = AvatarGroup({ | ||
size: 'sm', | ||
avatars: [], | ||
}) | ||
|
||
render(avatarGroup, document.body) | ||
|
||
expect( | ||
await axe(document.body.querySelector('.nui-avatar-group')!.outerHTML), | ||
)?.toHaveNoViolations() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { PropertyVariant } from '~/types/utils' | ||
|
||
export interface AvatarGroupProps extends Record<string, unknown> { | ||
limit?: number | ||
size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | ||
avatars: { | ||
src?: string | ||
srcDark?: string | ||
text?: string | ||
}[] | ||
} | ||
|
||
export interface AvatarGroupEvents {} | ||
|
||
export interface AvatarGroupSlots {} | ||
|
||
export type AvatarGroupAttrs = AvatarGroupProps & | ||
AvatarGroupEvents & | ||
AvatarGroupSlots | ||
export type AvatarGroupVariant<T> = PropertyVariant<T, AvatarGroupProps> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import type { AvatarGroupVariant } from './avatar-group.types' | ||
|
||
export const size = { | ||
xxs: 'nui-avatar-group-xxs', | ||
xs: 'nui-avatar-group-xs', | ||
sm: 'nui-avatar-group-sm', | ||
md: 'nui-avatar-group-md', | ||
lg: 'nui-avatar-group-lg', | ||
} as const satisfies AvatarGroupVariant<'size'> |
4 changes: 2 additions & 2 deletions
4
src/plugins/components/avatar-group.ts → src/plugins/components/avatar-group/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters