@shipfox/react-ui 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/preview.tsx +1 -1
- package/.turbo/turbo-build.log +2 -2
- package/.turbo/turbo-check.log +3 -3
- package/.turbo/turbo-type.log +1 -1
- package/CHANGELOG.md +17 -0
- package/dist/components/alert/alert.d.ts +18 -0
- package/dist/components/alert/alert.d.ts.map +1 -0
- package/dist/components/alert/alert.js +123 -0
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/alert/alert.stories.js +112 -0
- package/dist/components/alert/alert.stories.js.map +1 -0
- package/dist/components/alert/index.d.ts +2 -0
- package/dist/components/alert/index.d.ts.map +1 -0
- package/dist/components/alert/index.js +3 -0
- package/dist/components/alert/index.js.map +1 -0
- package/dist/components/avatar/avatar-group.d.ts +18 -0
- package/dist/components/avatar/avatar-group.d.ts.map +1 -0
- package/dist/components/avatar/avatar-group.js +132 -0
- package/dist/components/avatar/avatar-group.js.map +1 -0
- package/dist/components/avatar/avatar.d.ts +24 -0
- package/dist/components/avatar/avatar.d.ts.map +1 -0
- package/dist/components/avatar/avatar.js +165 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/avatar/avatar.stories.js +267 -0
- package/dist/components/avatar/avatar.stories.js.map +1 -0
- package/dist/components/avatar/index.d.ts +3 -0
- package/dist/components/avatar/index.d.ts.map +1 -0
- package/dist/components/avatar/index.js +4 -0
- package/dist/components/avatar/index.js.map +1 -0
- package/dist/components/badge/badge.d.ts +48 -0
- package/dist/components/badge/badge.d.ts.map +1 -0
- package/dist/components/badge/badge.js +72 -0
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/badge/badge.stories.js +802 -0
- package/dist/components/badge/badge.stories.js.map +1 -0
- package/dist/components/badge/icon-badge.d.ts +9 -0
- package/dist/components/badge/icon-badge.d.ts.map +1 -0
- package/dist/components/badge/icon-badge.js +32 -0
- package/dist/components/badge/icon-badge.js.map +1 -0
- package/dist/components/badge/index.d.ts +5 -0
- package/dist/components/badge/index.d.ts.map +1 -0
- package/dist/components/badge/index.js +6 -0
- package/dist/components/badge/index.js.map +1 -0
- package/dist/components/badge/status-badge.d.ts +9 -0
- package/dist/components/badge/status-badge.d.ts.map +1 -0
- package/dist/components/badge/status-badge.js +29 -0
- package/dist/components/badge/status-badge.js.map +1 -0
- package/dist/components/badge/user-badge.d.ts +8 -0
- package/dist/components/badge/user-badge.d.ts.map +1 -0
- package/dist/components/badge/user-badge.js +24 -0
- package/dist/components/badge/user-badge.js.map +1 -0
- package/dist/components/{button.d.ts → button/button.d.ts} +1 -1
- package/dist/components/button/button.d.ts.map +1 -0
- package/dist/components/{button.js → button/button.js} +2 -2
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/{button.stories.js → button/button.stories.js} +1 -1
- package/dist/components/button/button.stories.js.map +1 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/index.js +3 -0
- package/dist/components/button/index.js.map +1 -0
- package/dist/components/checkbox/checkbox-label.d.ts +14 -0
- package/dist/components/checkbox/checkbox-label.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox-label.js +82 -0
- package/dist/components/checkbox/checkbox-label.js.map +1 -0
- package/dist/components/checkbox/checkbox-links.d.ts +18 -0
- package/dist/components/checkbox/checkbox-links.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox-links.js +58 -0
- package/dist/components/checkbox/checkbox-links.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +9 -0
- package/dist/components/checkbox/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox.js +49 -0
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/checkbox/checkbox.stories.js +566 -0
- package/dist/components/checkbox/checkbox.stories.js.map +1 -0
- package/dist/components/checkbox/index.d.ts +4 -0
- package/dist/components/checkbox/index.d.ts.map +1 -0
- package/dist/components/checkbox/index.js +5 -0
- package/dist/components/checkbox/index.js.map +1 -0
- package/dist/components/code-block/code-block-footer.d.ts +26 -0
- package/dist/components/code-block/code-block-footer.d.ts.map +1 -0
- package/dist/components/code-block/code-block-footer.js +86 -0
- package/dist/components/code-block/code-block-footer.js.map +1 -0
- package/dist/components/code-block/code-block.d.ts +50 -0
- package/dist/components/code-block/code-block.d.ts.map +1 -0
- package/dist/components/code-block/code-block.js +142 -0
- package/dist/components/code-block/code-block.js.map +1 -0
- package/dist/components/code-block/code-block.stories.js +341 -0
- package/dist/components/code-block/code-block.stories.js.map +1 -0
- package/dist/components/code-block/code-content.d.ts +11 -0
- package/dist/components/code-block/code-content.d.ts.map +1 -0
- package/dist/components/code-block/code-content.js +29 -0
- package/dist/components/code-block/code-content.js.map +1 -0
- package/dist/components/code-block/code-copy-button.d.ts +11 -0
- package/dist/components/code-block/code-copy-button.d.ts.map +1 -0
- package/dist/components/code-block/code-copy-button.js +49 -0
- package/dist/components/code-block/code-copy-button.js.map +1 -0
- package/dist/components/code-block/code-tabs.d.ts +16 -0
- package/dist/components/code-block/code-tabs.d.ts.map +1 -0
- package/dist/components/code-block/code-tabs.js +98 -0
- package/dist/components/code-block/code-tabs.js.map +1 -0
- package/dist/components/code-block/index.d.ts +4 -0
- package/dist/components/code-block/index.d.ts.map +1 -0
- package/dist/components/code-block/index.js +5 -0
- package/dist/components/code-block/index.js.map +1 -0
- package/dist/components/dynamic-item/dynamic-item.d.ts +13 -0
- package/dist/components/dynamic-item/dynamic-item.d.ts.map +1 -0
- package/dist/components/dynamic-item/dynamic-item.js +43 -0
- package/dist/components/dynamic-item/dynamic-item.js.map +1 -0
- package/dist/components/dynamic-item/dynamic-item.stories.js +375 -0
- package/dist/components/dynamic-item/dynamic-item.stories.js.map +1 -0
- package/dist/components/dynamic-item/index.d.ts +2 -0
- package/dist/components/dynamic-item/index.d.ts.map +1 -0
- package/dist/components/dynamic-item/index.js +3 -0
- package/dist/components/dynamic-item/index.js.map +1 -0
- package/dist/components/icon/custom/index.d.ts +3 -0
- package/dist/components/icon/custom/index.d.ts.map +1 -1
- package/dist/components/icon/custom/index.js +3 -0
- package/dist/components/icon/custom/index.js.map +1 -1
- package/dist/components/icon/custom/shipfox-logo.d.ts +8 -0
- package/dist/components/icon/custom/shipfox-logo.d.ts.map +1 -0
- package/dist/components/icon/custom/shipfox-logo.js +22 -0
- package/dist/components/icon/custom/shipfox-logo.js.map +1 -0
- package/dist/components/icon/custom/slack-logo.d.ts +6 -0
- package/dist/components/icon/custom/slack-logo.d.ts.map +1 -0
- package/dist/components/icon/custom/slack-logo.js +34 -0
- package/dist/components/icon/custom/slack-logo.js.map +1 -0
- package/dist/components/icon/custom/stripe-logo.d.ts +8 -0
- package/dist/components/icon/custom/stripe-logo.d.ts.map +1 -0
- package/dist/components/icon/custom/stripe-logo.js +24 -0
- package/dist/components/icon/custom/stripe-logo.js.map +1 -0
- package/dist/components/icon/icon.d.ts +13 -1
- package/dist/components/icon/icon.d.ts.map +1 -1
- package/dist/components/icon/icon.js +15 -3
- package/dist/components/icon/icon.js.map +1 -1
- package/dist/components/icon/icon.stories.js +6 -3
- package/dist/components/icon/icon.stories.js.map +1 -1
- package/dist/components/index.d.ts +12 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +13 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/inline-tips/index.d.ts +2 -0
- package/dist/components/inline-tips/index.d.ts.map +1 -0
- package/dist/components/inline-tips/index.js +3 -0
- package/dist/components/inline-tips/index.js.map +1 -0
- package/dist/components/inline-tips/inline-tips.d.ts +19 -0
- package/dist/components/inline-tips/inline-tips.d.ts.map +1 -0
- package/dist/components/inline-tips/inline-tips.js +98 -0
- package/dist/components/inline-tips/inline-tips.js.map +1 -0
- package/dist/components/inline-tips/inline-tips.stories.js +214 -0
- package/dist/components/inline-tips/inline-tips.stories.js.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/index.js +3 -0
- package/dist/components/input/index.js.map +1 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/{input.js → input/input.js} +2 -2
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/{input.stories.js → input/input.stories.js} +1 -1
- package/dist/components/input/input.stories.js.map +1 -0
- package/dist/components/item/index.d.ts +2 -0
- package/dist/components/item/index.d.ts.map +1 -0
- package/dist/components/item/index.js +3 -0
- package/dist/components/item/index.js.map +1 -0
- package/dist/components/item/item.d.ts +32 -0
- package/dist/components/item/item.d.ts.map +1 -0
- package/dist/components/item/item.js +120 -0
- package/dist/components/item/item.js.map +1 -0
- package/dist/components/item/item.stories.js +232 -0
- package/dist/components/item/item.stories.js.map +1 -0
- package/dist/components/label/index.d.ts +2 -0
- package/dist/components/label/index.d.ts.map +1 -0
- package/dist/components/label/index.js +3 -0
- package/dist/components/label/index.js.map +1 -0
- package/dist/components/label/label.d.ts +7 -0
- package/dist/components/label/label.d.ts.map +1 -0
- package/dist/components/label/label.js +13 -0
- package/dist/components/label/label.js.map +1 -0
- package/dist/components/label/label.stories.js +105 -0
- package/dist/components/label/label.stories.js.map +1 -0
- package/dist/components/moving-border/moving-border.d.ts +9 -0
- package/dist/components/moving-border/moving-border.d.ts.map +1 -0
- package/dist/components/moving-border/moving-border.js +54 -0
- package/dist/components/moving-border/moving-border.js.map +1 -0
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/theme/index.d.ts +2 -0
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/index.js +3 -0
- package/dist/components/theme/index.js.map +1 -0
- package/dist/components/{theme-provider.d.ts → theme/theme-provider.d.ts} +1 -1
- package/dist/components/theme/theme-provider.d.ts.map +1 -0
- package/dist/components/{theme-provider.js → theme/theme-provider.js} +1 -1
- package/dist/components/theme/theme-provider.js.map +1 -0
- package/dist/components/toast/index.d.ts +3 -0
- package/dist/components/toast/index.d.ts.map +1 -0
- package/dist/components/toast/index.js +4 -0
- package/dist/components/toast/index.js.map +1 -0
- package/dist/components/toast/toast-custom.d.ts +19 -0
- package/dist/components/toast/toast-custom.d.ts.map +1 -0
- package/dist/components/toast/toast-custom.js +134 -0
- package/dist/components/toast/toast-custom.js.map +1 -0
- package/dist/components/toast/toast.d.ts +5 -0
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +40 -0
- package/dist/components/toast/toast.js.map +1 -0
- package/dist/components/toast/toast.stories.js +326 -0
- package/dist/components/toast/toast.stories.js.map +1 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/index.d.ts.map +1 -0
- package/dist/components/tooltip/index.js +3 -0
- package/dist/components/tooltip/index.js.map +1 -0
- package/dist/components/tooltip/tooltip.d.ts +20 -0
- package/dist/components/tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip/tooltip.js +98 -0
- package/dist/components/tooltip/tooltip.js.map +1 -0
- package/dist/components/tooltip/tooltip.stories.js +560 -0
- package/dist/components/tooltip/tooltip.stories.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useResolvedTheme.d.ts +2 -0
- package/dist/hooks/useResolvedTheme.d.ts.map +1 -0
- package/dist/hooks/useResolvedTheme.js +24 -0
- package/dist/hooks/useResolvedTheme.js.map +1 -0
- package/dist/hooks/useShikiHighlight.d.ts +28 -0
- package/dist/hooks/useShikiHighlight.d.ts.map +1 -0
- package/dist/hooks/useShikiHighlight.js +106 -0
- package/dist/hooks/useShikiHighlight.js.map +1 -0
- package/dist/hooks/useShikiStyleInjection.d.ts +2 -0
- package/dist/hooks/useShikiStyleInjection.d.ts.map +1 -0
- package/dist/hooks/useShikiStyleInjection.js +34 -0
- package/dist/hooks/useShikiStyleInjection.js.map +1 -0
- package/dist/utils/avatar.d.ts +3 -0
- package/dist/utils/avatar.d.ts.map +1 -0
- package/dist/utils/avatar.js +32 -0
- package/dist/utils/avatar.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/index.css +130 -7
- package/package.json +7 -4
- package/src/assets/illustration-1.svg +92 -0
- package/src/assets/illustration-2.svg +14 -0
- package/src/assets/illustration-gradient.svg +7049 -0
- package/src/components/alert/alert.stories.tsx +77 -0
- package/src/components/alert/alert.tsx +144 -0
- package/src/components/alert/index.ts +1 -0
- package/src/components/avatar/avatar-group.tsx +186 -0
- package/src/components/avatar/avatar.stories.tsx +179 -0
- package/src/components/avatar/avatar.tsx +219 -0
- package/src/components/avatar/index.ts +2 -0
- package/src/components/badge/badge.stories.tsx +468 -0
- package/src/components/badge/badge.tsx +147 -0
- package/src/components/badge/icon-badge.tsx +43 -0
- package/src/components/badge/index.ts +4 -0
- package/src/components/badge/status-badge.tsx +43 -0
- package/src/components/badge/user-badge.tsx +34 -0
- package/src/components/{button.tsx → button/button.tsx} +1 -1
- package/src/components/button/index.ts +1 -0
- package/src/components/checkbox/checkbox-label.tsx +125 -0
- package/src/components/checkbox/checkbox-links.tsx +90 -0
- package/src/components/checkbox/checkbox.stories.tsx +375 -0
- package/src/components/checkbox/checkbox.tsx +71 -0
- package/src/components/checkbox/index.ts +3 -0
- package/src/components/code-block/code-block-footer.tsx +173 -0
- package/src/components/code-block/code-block.stories.tsx +323 -0
- package/src/components/code-block/code-block.tsx +283 -0
- package/src/components/code-block/code-content.tsx +60 -0
- package/src/components/code-block/code-copy-button.tsx +73 -0
- package/src/components/code-block/code-tabs.tsx +170 -0
- package/src/components/code-block/index.ts +3 -0
- package/src/components/dynamic-item/dynamic-item.stories.tsx +261 -0
- package/src/components/dynamic-item/dynamic-item.tsx +68 -0
- package/src/components/dynamic-item/index.ts +1 -0
- package/src/components/icon/custom/index.ts +3 -0
- package/src/components/icon/custom/shipfox-logo.tsx +20 -0
- package/src/components/icon/custom/slack-logo.tsx +35 -0
- package/src/components/icon/custom/stripe-logo.tsx +27 -0
- package/src/components/icon/icon.stories.tsx +3 -1
- package/src/components/icon/icon.tsx +29 -1
- package/src/components/index.ts +12 -1
- package/src/components/inline-tips/index.ts +1 -0
- package/src/components/inline-tips/inline-tips.stories.tsx +126 -0
- package/src/components/inline-tips/inline-tips.tsx +132 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/{input.tsx → input/input.tsx} +1 -1
- package/src/components/item/index.ts +1 -0
- package/src/components/item/item.stories.tsx +150 -0
- package/src/components/item/item.tsx +182 -0
- package/src/components/label/index.ts +1 -0
- package/src/components/label/label.stories.tsx +67 -0
- package/src/components/label/label.tsx +15 -0
- package/src/components/moving-border/moving-border.tsx +67 -0
- package/src/components/textarea/textarea.tsx +1 -1
- package/src/components/theme/index.ts +1 -0
- package/src/components/toast/index.ts +2 -0
- package/src/components/toast/toast-custom.tsx +154 -0
- package/src/components/toast/toast.stories.tsx +369 -0
- package/src/components/toast/toast.tsx +41 -0
- package/src/components/tooltip/index.ts +1 -0
- package/src/components/tooltip/tooltip.stories.tsx +284 -0
- package/src/components/tooltip/tooltip.tsx +121 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useResolvedTheme.ts +34 -0
- package/src/hooks/useShikiHighlight.ts +140 -0
- package/src/hooks/useShikiStyleInjection.ts +34 -0
- package/src/utils/avatar.ts +27 -0
- package/src/utils/index.ts +1 -0
- package/dist/components/button.d.ts.map +0 -1
- package/dist/components/button.js.map +0 -1
- package/dist/components/button.stories.js.map +0 -1
- package/dist/components/input.d.ts.map +0 -1
- package/dist/components/input.js.map +0 -1
- package/dist/components/input.stories.js.map +0 -1
- package/dist/components/theme-provider.d.ts.map +0 -1
- package/dist/components/theme-provider.js.map +0 -1
- /package/dist/components/{input.d.ts → input/input.d.ts} +0 -0
- /package/src/components/{button.stories.tsx → button/button.stories.tsx} +0 -0
- /package/src/components/{input.stories.tsx → input/input.stories.tsx} +0 -0
- /package/src/components/{theme-provider.tsx → theme/theme-provider.tsx} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {Header} from 'components/typography';
|
|
3
|
+
import {
|
|
4
|
+
Alert,
|
|
5
|
+
AlertAction,
|
|
6
|
+
AlertActions,
|
|
7
|
+
AlertClose,
|
|
8
|
+
AlertContent,
|
|
9
|
+
AlertDescription,
|
|
10
|
+
AlertTitle,
|
|
11
|
+
} from './alert';
|
|
12
|
+
|
|
13
|
+
const meta = {
|
|
14
|
+
title: 'Components/Alert',
|
|
15
|
+
component: Alert,
|
|
16
|
+
tags: ['autodocs'],
|
|
17
|
+
argTypes: {
|
|
18
|
+
variant: {
|
|
19
|
+
control: 'select',
|
|
20
|
+
options: ['default', 'info', 'success', 'warning', 'error'],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
args: {
|
|
24
|
+
variant: 'default',
|
|
25
|
+
},
|
|
26
|
+
} satisfies Meta<typeof Alert>;
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
|
|
30
|
+
type Story = StoryObj<typeof meta>;
|
|
31
|
+
|
|
32
|
+
const variants = ['default', 'info', 'success', 'warning', 'error'] as const;
|
|
33
|
+
|
|
34
|
+
export const Default: Story = {
|
|
35
|
+
render: (args) => {
|
|
36
|
+
return (
|
|
37
|
+
<Alert {...args}>
|
|
38
|
+
<AlertContent>
|
|
39
|
+
<AlertTitle>Title</AlertTitle>
|
|
40
|
+
<AlertDescription>Description</AlertDescription>
|
|
41
|
+
<AlertActions>
|
|
42
|
+
<AlertAction>Download</AlertAction>
|
|
43
|
+
<AlertAction>View</AlertAction>
|
|
44
|
+
</AlertActions>
|
|
45
|
+
</AlertContent>
|
|
46
|
+
<AlertClose variant={args.variant} />
|
|
47
|
+
</Alert>
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const DesignMock: Story = {
|
|
53
|
+
render: () => {
|
|
54
|
+
return (
|
|
55
|
+
<div className="flex flex-col gap-32 pb-64 pt-32 px-32 bg-background-neutral-base">
|
|
56
|
+
<Header variant="h3" className="text-foreground-neutral-subtle">
|
|
57
|
+
ALERTS
|
|
58
|
+
</Header>
|
|
59
|
+
<div className="flex flex-col gap-16">
|
|
60
|
+
{variants.map((variant) => (
|
|
61
|
+
<Alert key={variant} variant={variant}>
|
|
62
|
+
<AlertContent>
|
|
63
|
+
<AlertTitle>Title</AlertTitle>
|
|
64
|
+
<AlertDescription>Description</AlertDescription>
|
|
65
|
+
<AlertActions>
|
|
66
|
+
<AlertAction>Download</AlertAction>
|
|
67
|
+
<AlertAction>View</AlertAction>
|
|
68
|
+
</AlertActions>
|
|
69
|
+
</AlertContent>
|
|
70
|
+
<AlertClose variant={variant} />
|
|
71
|
+
</Alert>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import {cva, type VariantProps} from 'class-variance-authority';
|
|
2
|
+
import {Icon} from 'components/icon';
|
|
3
|
+
import type {ComponentProps} from 'react';
|
|
4
|
+
import {cn} from 'utils/cn';
|
|
5
|
+
|
|
6
|
+
const alertVariants = cva(
|
|
7
|
+
'relative w-full rounded-l-4 rounded-r-8 px-16 py-12 text-sm flex gap-12 items-start border',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: 'bg-tag-neutral-bg text-foreground-neutral-base border-tag-neutral-border',
|
|
12
|
+
info: 'bg-tag-blue-bg text-foreground-neutral-base border-tag-blue-border',
|
|
13
|
+
success: 'bg-tag-success-bg text-foreground-neutral-base border-tag-success-border',
|
|
14
|
+
warning: 'bg-tag-warning-bg text-foreground-neutral-base border-tag-warning-border',
|
|
15
|
+
error: 'bg-tag-error-bg text-foreground-neutral-base border-tag-error-border',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: 'default',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const alertLineVariants = cva('w-4 self-stretch rounded-full', {
|
|
25
|
+
variants: {
|
|
26
|
+
variant: {
|
|
27
|
+
default: 'bg-tag-neutral-icon',
|
|
28
|
+
info: 'bg-tag-blue-icon',
|
|
29
|
+
success: 'bg-tag-success-icon',
|
|
30
|
+
warning: 'bg-tag-warning-icon',
|
|
31
|
+
error: 'bg-tag-error-icon',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: 'default',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const closeIconVariants = cva('w-16 h-16', {
|
|
40
|
+
variants: {
|
|
41
|
+
variant: {
|
|
42
|
+
default: 'text-tag-neutral-icon',
|
|
43
|
+
info: 'text-tag-blue-icon',
|
|
44
|
+
success: 'text-tag-success-icon',
|
|
45
|
+
warning: 'text-tag-warning-icon',
|
|
46
|
+
error: 'text-tag-error-icon',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
defaultVariants: {
|
|
50
|
+
variant: 'default',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
type AlertProps = ComponentProps<'div'> & VariantProps<typeof alertVariants>;
|
|
55
|
+
|
|
56
|
+
function Alert({className, variant, children, ...props}: AlertProps) {
|
|
57
|
+
return (
|
|
58
|
+
<div className="w-full flex items-start gap-4">
|
|
59
|
+
<div data-slot="alert-line" className={cn(alertLineVariants({variant}))} aria-hidden="true" />
|
|
60
|
+
<div
|
|
61
|
+
data-slot="alert"
|
|
62
|
+
role="alert"
|
|
63
|
+
className={cn(alertVariants({variant}), className)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
{children}
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function AlertContent({className, ...props}: ComponentProps<'div'>) {
|
|
73
|
+
return <div data-slot="alert-content" className={cn('flex-1 min-w-0', className)} {...props} />;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function AlertTitle({className, ...props}: ComponentProps<'div'>) {
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
data-slot="alert-title"
|
|
80
|
+
className={cn('font-medium text-sm leading-20 text-foreground-neutral-base mb-4', className)}
|
|
81
|
+
{...props}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function AlertDescription({className, ...props}: ComponentProps<'div'>) {
|
|
87
|
+
return (
|
|
88
|
+
<div
|
|
89
|
+
data-slot="alert-description"
|
|
90
|
+
className={cn(
|
|
91
|
+
'text-xs leading-20 text-foreground-neutral-base [&_p]:leading-relaxed',
|
|
92
|
+
className,
|
|
93
|
+
)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function AlertActions({className, ...props}: ComponentProps<'div'>) {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
data-slot="alert-actions"
|
|
103
|
+
className={cn('flex items-center gap-8 mt-8', className)}
|
|
104
|
+
{...props}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function AlertAction({className, ...props}: ComponentProps<'button'>) {
|
|
110
|
+
return (
|
|
111
|
+
<button
|
|
112
|
+
data-slot="alert-action"
|
|
113
|
+
type="button"
|
|
114
|
+
className={cn(
|
|
115
|
+
'bg-transparent border-none p-0 cursor-pointer text-xs font-medium leading-20 text-foreground-neutral-base hover:text-foreground-neutral-subtle transition-colors duration-150 outline-none focus-visible:ring-2 focus-visible:ring-background-accent-blue-base focus-visible:ring-offset-2',
|
|
116
|
+
className,
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function AlertClose({
|
|
124
|
+
className,
|
|
125
|
+
variant = 'default',
|
|
126
|
+
...props
|
|
127
|
+
}: ComponentProps<'button'> & VariantProps<typeof closeIconVariants>) {
|
|
128
|
+
return (
|
|
129
|
+
<button
|
|
130
|
+
data-slot="alert-close"
|
|
131
|
+
type="button"
|
|
132
|
+
className={cn(
|
|
133
|
+
'absolute cursor-pointer top-12 right-12 rounded-4 p-4 bg-transparent border-none text-foreground-neutral-muted hover:text-foreground-neutral-base hover:bg-background-components-hover transition-colors duration-150 outline-none focus-visible:ring-2 focus-visible:ring-background-accent-blue-base focus-visible:ring-offset-2',
|
|
134
|
+
className,
|
|
135
|
+
)}
|
|
136
|
+
aria-label="Close"
|
|
137
|
+
{...props}
|
|
138
|
+
>
|
|
139
|
+
<Icon name="close" className={cn(closeIconVariants({variant}))} />
|
|
140
|
+
</button>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export {Alert, AlertContent, AlertTitle, AlertDescription, AlertActions, AlertAction, AlertClose};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './alert';
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
2
|
+
import {cva, type VariantProps} from 'class-variance-authority';
|
|
3
|
+
import {
|
|
4
|
+
Children,
|
|
5
|
+
type ComponentProps,
|
|
6
|
+
cloneElement,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
useMemo,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import {cn} from 'utils/cn';
|
|
12
|
+
import {TooltipContent, TooltipProvider, TooltipTrigger} from '../tooltip/tooltip';
|
|
13
|
+
|
|
14
|
+
const avatarGroupVariants = cva('flex items-start', {
|
|
15
|
+
variants: {
|
|
16
|
+
size: {
|
|
17
|
+
'3xs': '-space-x-4',
|
|
18
|
+
'2xs': '-space-x-4',
|
|
19
|
+
xs: '-space-x-4',
|
|
20
|
+
sm: '-space-x-6',
|
|
21
|
+
md: '-space-x-6',
|
|
22
|
+
lg: '-space-x-6',
|
|
23
|
+
xl: '-space-x-6',
|
|
24
|
+
'2xl': '-space-x-12',
|
|
25
|
+
'3xl': '-space-x-12',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
size: 'md',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const avatarGroupOverflowVariants = cva(
|
|
34
|
+
'flex shrink-0 items-center justify-center rounded-full bg-background-components-base text-foreground-neutral-subtle font-medium ring-1 ring-border-neutral-base-component ring-offset-1 ring-offset-background-neutral-base shadow-button-neutral',
|
|
35
|
+
{
|
|
36
|
+
variants: {
|
|
37
|
+
size: {
|
|
38
|
+
'3xs': 'size-[18px] text-[10px] leading-[10px]',
|
|
39
|
+
'2xs': 'size-[20px] text-[11px] leading-[11px]',
|
|
40
|
+
xs: 'size-[24px] text-xs leading-4',
|
|
41
|
+
sm: 'size-[28px] text-xs leading-5',
|
|
42
|
+
md: 'size-[32px] text-sm leading-5',
|
|
43
|
+
lg: 'size-[36px] text-sm leading-5',
|
|
44
|
+
xl: 'size-[40px] text-base leading-6',
|
|
45
|
+
'2xl': 'size-[80px] text-2xl leading-8',
|
|
46
|
+
'3xl': 'size-[120px] text-4xl leading-[56px]',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
defaultVariants: {
|
|
50
|
+
size: 'md',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
type TooltipContentProps = ComponentProps<typeof TooltipContent>;
|
|
56
|
+
|
|
57
|
+
type AvatarContainerProps = {
|
|
58
|
+
children: ReactNode;
|
|
59
|
+
zIndex: number;
|
|
60
|
+
tooltipContent?: ReactNode;
|
|
61
|
+
tooltipProps?: Partial<TooltipContentProps>;
|
|
62
|
+
animateOnHover?: boolean;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function AvatarContainer({
|
|
66
|
+
children,
|
|
67
|
+
zIndex,
|
|
68
|
+
tooltipContent,
|
|
69
|
+
tooltipProps,
|
|
70
|
+
animateOnHover = false,
|
|
71
|
+
}: AvatarContainerProps) {
|
|
72
|
+
return (
|
|
73
|
+
<TooltipPrimitive.Root>
|
|
74
|
+
<TooltipTrigger asChild>
|
|
75
|
+
<div
|
|
76
|
+
data-slot="avatar-container"
|
|
77
|
+
className={cn(
|
|
78
|
+
'relative',
|
|
79
|
+
animateOnHover && 'transition-transform duration-300 ease-in-out hover:-translate-y-4',
|
|
80
|
+
)}
|
|
81
|
+
style={{zIndex}}
|
|
82
|
+
>
|
|
83
|
+
{children}
|
|
84
|
+
</div>
|
|
85
|
+
</TooltipTrigger>
|
|
86
|
+
{tooltipContent && (
|
|
87
|
+
<AvatarGroupTooltip {...tooltipProps}>{tooltipContent}</AvatarGroupTooltip>
|
|
88
|
+
)}
|
|
89
|
+
</TooltipPrimitive.Root>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getTooltipContent(children: ReactNode): ReactNode | null {
|
|
94
|
+
const tooltip = Children.toArray(children).find(
|
|
95
|
+
(child) =>
|
|
96
|
+
typeof child === 'object' &&
|
|
97
|
+
child !== null &&
|
|
98
|
+
'type' in child &&
|
|
99
|
+
child.type === AvatarGroupTooltip,
|
|
100
|
+
) as ReactElement<ComponentProps<typeof AvatarGroupTooltip>> | undefined;
|
|
101
|
+
|
|
102
|
+
return tooltip?.props.children || null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
type AvatarGroupTooltipProps = TooltipContentProps;
|
|
106
|
+
|
|
107
|
+
function AvatarGroupTooltip(props: AvatarGroupTooltipProps) {
|
|
108
|
+
return <TooltipContent {...props} />;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
type AvatarGroupProps = ComponentProps<'div'> &
|
|
112
|
+
VariantProps<typeof avatarGroupVariants> & {
|
|
113
|
+
children: ReactElement[];
|
|
114
|
+
maxVisible?: number;
|
|
115
|
+
animateOnHover?: boolean;
|
|
116
|
+
tooltipProps?: Partial<TooltipContentProps>;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export function AvatarGroup({
|
|
120
|
+
className,
|
|
121
|
+
size = 'md',
|
|
122
|
+
children,
|
|
123
|
+
maxVisible,
|
|
124
|
+
animateOnHover = false,
|
|
125
|
+
tooltipProps = {side: 'top', sideOffset: 8},
|
|
126
|
+
...props
|
|
127
|
+
}: AvatarGroupProps) {
|
|
128
|
+
const normalizedSize = size ?? 'md';
|
|
129
|
+
|
|
130
|
+
const childrenArray = Children.toArray(children) as ReactElement[];
|
|
131
|
+
|
|
132
|
+
const {visibleCount, visibleAvatars, overflowCount} = useMemo(() => {
|
|
133
|
+
const count =
|
|
134
|
+
maxVisible !== undefined ? Math.min(maxVisible, childrenArray.length) : childrenArray.length;
|
|
135
|
+
return {
|
|
136
|
+
visibleCount: count,
|
|
137
|
+
visibleAvatars: childrenArray.slice(0, count),
|
|
138
|
+
overflowCount: childrenArray.length - count,
|
|
139
|
+
};
|
|
140
|
+
}, [childrenArray, maxVisible]);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<TooltipProvider delayDuration={0}>
|
|
144
|
+
<div
|
|
145
|
+
className={cn(avatarGroupVariants({size: normalizedSize}), className)}
|
|
146
|
+
data-slot="avatar-group"
|
|
147
|
+
{...props}
|
|
148
|
+
>
|
|
149
|
+
{visibleAvatars.map((child, index) => {
|
|
150
|
+
const zIndex = index + 1;
|
|
151
|
+
const childProps = 'props' in child ? (child.props as {children?: ReactNode}) : {};
|
|
152
|
+
const tooltipContent = getTooltipContent(childProps.children);
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<AvatarContainer
|
|
156
|
+
key={child.key || index}
|
|
157
|
+
zIndex={zIndex}
|
|
158
|
+
tooltipContent={tooltipContent}
|
|
159
|
+
tooltipProps={tooltipProps}
|
|
160
|
+
animateOnHover={animateOnHover}
|
|
161
|
+
>
|
|
162
|
+
{cloneElement(child, {
|
|
163
|
+
...childProps,
|
|
164
|
+
children: tooltipContent ? undefined : childProps.children,
|
|
165
|
+
} as Partial<typeof childProps>)}
|
|
166
|
+
</AvatarContainer>
|
|
167
|
+
);
|
|
168
|
+
})}
|
|
169
|
+
{overflowCount > 0 && (
|
|
170
|
+
<div
|
|
171
|
+
className={cn(
|
|
172
|
+
'relative',
|
|
173
|
+
avatarGroupOverflowVariants({size: normalizedSize}),
|
|
174
|
+
'rounded-full',
|
|
175
|
+
)}
|
|
176
|
+
style={{zIndex: visibleCount + 1}}
|
|
177
|
+
>
|
|
178
|
+
+{overflowCount}
|
|
179
|
+
</div>
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
</TooltipProvider>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export {AvatarGroupTooltip, type AvatarGroupTooltipProps};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/react';
|
|
2
|
+
import {Code} from 'components/typography';
|
|
3
|
+
import {Avatar} from './avatar';
|
|
4
|
+
import {AvatarGroup, AvatarGroupTooltip} from './avatar-group';
|
|
5
|
+
|
|
6
|
+
const contentOptions = ['letters', 'logo', 'logoPlaceholder', 'image', 'upload'] as const;
|
|
7
|
+
const radiusOptions = ['full', 'rounded'] as const;
|
|
8
|
+
const sizeOptions = ['3xs', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] as const;
|
|
9
|
+
const logoNameOptions = ['shipfox', 'slack', 'stripe', 'github'] as const;
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'Components/Avatar',
|
|
13
|
+
component: Avatar,
|
|
14
|
+
tags: ['autodocs'],
|
|
15
|
+
argTypes: {
|
|
16
|
+
content: {
|
|
17
|
+
control: 'select',
|
|
18
|
+
options: contentOptions,
|
|
19
|
+
},
|
|
20
|
+
radius: {
|
|
21
|
+
control: 'select',
|
|
22
|
+
options: radiusOptions,
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
control: 'select',
|
|
26
|
+
options: sizeOptions,
|
|
27
|
+
},
|
|
28
|
+
fallback: {
|
|
29
|
+
control: 'text',
|
|
30
|
+
},
|
|
31
|
+
src: {
|
|
32
|
+
control: 'text',
|
|
33
|
+
},
|
|
34
|
+
alt: {
|
|
35
|
+
control: 'text',
|
|
36
|
+
},
|
|
37
|
+
logoName: {
|
|
38
|
+
control: 'select',
|
|
39
|
+
options: logoNameOptions,
|
|
40
|
+
description: 'Logo icon name to display when content is "logo" or "logoPlaceholder"',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
args: {
|
|
44
|
+
content: 'letters',
|
|
45
|
+
radius: 'full',
|
|
46
|
+
size: 'md',
|
|
47
|
+
fallback: 'John Doe',
|
|
48
|
+
logoName: 'shipfox',
|
|
49
|
+
},
|
|
50
|
+
} satisfies Meta<typeof Avatar>;
|
|
51
|
+
|
|
52
|
+
export default meta;
|
|
53
|
+
type Story = StoryObj<typeof meta>;
|
|
54
|
+
|
|
55
|
+
export const Default: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
content: 'logo',
|
|
58
|
+
fallback: 'Shipfox',
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
render: (args) => (
|
|
62
|
+
<div className="flex flex-wrap items-end gap-16">
|
|
63
|
+
{sizeOptions.map((size) => (
|
|
64
|
+
<div key={size} className="flex flex-col items-center gap-8">
|
|
65
|
+
<Avatar {...args} size={size} />
|
|
66
|
+
<Code variant="label" className="text-foreground-neutral-base">
|
|
67
|
+
{size}
|
|
68
|
+
</Code>
|
|
69
|
+
</div>
|
|
70
|
+
))}
|
|
71
|
+
</div>
|
|
72
|
+
),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// AvatarGroup Stories
|
|
76
|
+
const avatarGroupMeta = {
|
|
77
|
+
title: 'Components/AvatarGroup',
|
|
78
|
+
component: AvatarGroup,
|
|
79
|
+
tags: ['autodocs'],
|
|
80
|
+
argTypes: {
|
|
81
|
+
size: {
|
|
82
|
+
control: 'select',
|
|
83
|
+
options: sizeOptions,
|
|
84
|
+
},
|
|
85
|
+
maxVisible: {
|
|
86
|
+
control: 'number',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
args: {
|
|
90
|
+
size: 'md',
|
|
91
|
+
children: [],
|
|
92
|
+
},
|
|
93
|
+
} satisfies Meta<typeof AvatarGroup>;
|
|
94
|
+
|
|
95
|
+
export const AvatarGroupDefault: StoryObj<typeof avatarGroupMeta> = {
|
|
96
|
+
args: {
|
|
97
|
+
children: [],
|
|
98
|
+
},
|
|
99
|
+
render: () => {
|
|
100
|
+
const avatars = [
|
|
101
|
+
{name: 'John Doe', content: 'image'},
|
|
102
|
+
{name: 'Jane Smith', content: 'image'},
|
|
103
|
+
{name: 'Bob Johnson', content: 'image'},
|
|
104
|
+
{name: 'Alice Brown', content: 'image'},
|
|
105
|
+
] as const;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div className="flex flex-col gap-16">
|
|
109
|
+
<div className="flex flex-col gap-8">
|
|
110
|
+
<Code variant="label" className="text-foreground-neutral-base">
|
|
111
|
+
Default (without tooltips)
|
|
112
|
+
</Code>
|
|
113
|
+
<AvatarGroup size="md">
|
|
114
|
+
{avatars.map((avatar) => (
|
|
115
|
+
<Avatar key={avatar.name} content={avatar.content} fallback={avatar.name} />
|
|
116
|
+
))}
|
|
117
|
+
</AvatarGroup>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const AvatarGroupWithTooltips: StoryObj<typeof avatarGroupMeta> = {
|
|
125
|
+
args: {
|
|
126
|
+
children: [],
|
|
127
|
+
},
|
|
128
|
+
render: () => {
|
|
129
|
+
const avatars = [
|
|
130
|
+
{name: 'John Doe', content: 'image'},
|
|
131
|
+
{name: 'Jane Smith', content: 'image'},
|
|
132
|
+
{name: 'Bob Johnson', content: 'image'},
|
|
133
|
+
{name: 'Alice Brown', content: 'image'},
|
|
134
|
+
{name: 'Carlos Vega', content: 'image'},
|
|
135
|
+
{name: 'Linda Tran', content: 'image'},
|
|
136
|
+
] as const;
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<div className="flex flex-col gap-16">
|
|
140
|
+
<div className="flex flex-col gap-8">
|
|
141
|
+
<Code variant="label" className="text-foreground-neutral-base">
|
|
142
|
+
With Tooltips
|
|
143
|
+
</Code>
|
|
144
|
+
<AvatarGroup size="md">
|
|
145
|
+
{avatars.map((avatar) => (
|
|
146
|
+
<Avatar key={avatar.name} content={avatar.content} fallback={avatar.name}>
|
|
147
|
+
<AvatarGroupTooltip>{avatar.name}</AvatarGroupTooltip>
|
|
148
|
+
</Avatar>
|
|
149
|
+
))}
|
|
150
|
+
</AvatarGroup>
|
|
151
|
+
</div>
|
|
152
|
+
<div className="flex flex-col gap-8">
|
|
153
|
+
<Code variant="label" className="text-foreground-neutral-base">
|
|
154
|
+
With Tooltips (maxVisible: 4)
|
|
155
|
+
</Code>
|
|
156
|
+
<AvatarGroup size="md" maxVisible={4}>
|
|
157
|
+
{avatars.map((avatar) => (
|
|
158
|
+
<Avatar key={avatar.name} content={avatar.content} fallback={avatar.name}>
|
|
159
|
+
<AvatarGroupTooltip>{avatar.name}</AvatarGroupTooltip>
|
|
160
|
+
</Avatar>
|
|
161
|
+
))}
|
|
162
|
+
</AvatarGroup>
|
|
163
|
+
</div>
|
|
164
|
+
<div className="flex flex-col gap-8">
|
|
165
|
+
<Code variant="label" className="text-foreground-neutral-base">
|
|
166
|
+
With Tooltips and Hover Animation
|
|
167
|
+
</Code>
|
|
168
|
+
<AvatarGroup size="md" maxVisible={4} animateOnHover>
|
|
169
|
+
{avatars.map((avatar) => (
|
|
170
|
+
<Avatar key={avatar.name} content={avatar.content} fallback={avatar.name}>
|
|
171
|
+
<AvatarGroupTooltip>{avatar.name}</AvatarGroupTooltip>
|
|
172
|
+
</Avatar>
|
|
173
|
+
))}
|
|
174
|
+
</AvatarGroup>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
},
|
|
179
|
+
};
|