Skip to content

Commit 91483f2

Browse files
Josem1801Brayan-724
authored andcommitted
feat(react): add Collaborators component
1 parent 07aa3b4 commit 91483f2

File tree

7 files changed

+146
-0
lines changed

7 files changed

+146
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { withAs } from "../../utils/hoc/with-as.hoc";
2+
import { cn } from "../../utils/tw-merge";
3+
4+
type AvatarProps = {
5+
avatarUrl: string;
6+
alt?: string;
7+
className?: string;
8+
size?: number;
9+
style?: React.CSSProperties;
10+
};
11+
12+
export const Avatar = withAs(
13+
(
14+
Component,
15+
{ avatarUrl, alt, size = 32, className, style, ...rest }: AvatarProps
16+
) => {
17+
return (
18+
<Component
19+
{...rest}
20+
className={cn([
21+
"grid aspect-square place-items-center overflow-hidden rounded-full border object-cover",
22+
className,
23+
])}
24+
style={{
25+
width: size,
26+
height: size,
27+
...style,
28+
}}
29+
>
30+
<img
31+
className="aspect-square h-full w-full"
32+
src={avatarUrl}
33+
alt={alt}
34+
/>
35+
</Component>
36+
);
37+
}
38+
);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./avatar.component";
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { Fragment } from "react/jsx-runtime";
2+
import { Github } from "../../icons";
3+
import { Avatar } from "../avatar/avatar.component";
4+
import { MAX_COLLABORATORS } from "./collaborators.const";
5+
import { Button } from "../button";
6+
7+
type Collaborator = {
8+
avatarUrl: string;
9+
nickname: string;
10+
};
11+
12+
type CollaboratorsProps = {
13+
collaborators: Array<Collaborator>;
14+
sourceUrl: string;
15+
};
16+
17+
export const Collaborators = ({
18+
collaborators = [],
19+
sourceUrl,
20+
}: CollaboratorsProps) => {
21+
const numberOfCollaborators = collaborators.length;
22+
const isSingleCollaborator = numberOfCollaborators === 1;
23+
24+
const hasMaxCollaborators = numberOfCollaborators > MAX_COLLABORATORS;
25+
const extraCollaborators = numberOfCollaborators - MAX_COLLABORATORS;
26+
return (
27+
<div className="flex h-12 w-full items-center justify-between">
28+
<div className="flex w-fit items-center">
29+
{collaborators.slice(0, MAX_COLLABORATORS).map((collaborator, idx) => {
30+
const space = idx ? 12 : 0;
31+
return (
32+
<Fragment>
33+
<Avatar
34+
avatarUrl={collaborator.avatarUrl}
35+
style={{ marginLeft: `-${space}px` }}
36+
as="div"
37+
/>
38+
</Fragment>
39+
);
40+
})}
41+
42+
{isSingleCollaborator ? (
43+
<span className="text-caption pl-2">{collaborators[0].nickname}</span>
44+
) : null}
45+
46+
{hasMaxCollaborators ? (
47+
<span className="text-caption pl-2">+{extraCollaborators}</span>
48+
) : null}
49+
</div>
50+
51+
<Button
52+
as="a"
53+
href={sourceUrl}
54+
target="_blank"
55+
rel="noopener noreferrer"
56+
icon={<Github />}
57+
variant="icon"
58+
/>
59+
</div>
60+
);
61+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const MAX_COLLABORATORS = 4;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./collaborators.component";

js/react/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export * from "./components/chip";
44
export * from "./components/tag";
55
export * from "./components/flap";
66
export * from "./components/level";
7+
export * from "./components/collaborators";
78
export * from "./icons";

js/react/showcase/App.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ import {
77
Flap,
88
Chip,
99
Level,
10+
Collaborators,
1011
} from "@rustlanges/react";
1112
import { ShowComponent } from "./ShowComponent";
1213

14+
const collaborator = {
15+
avatarUrl:
16+
"https://images.unsplash.com/photo-1575936123452-b67c3203c357?fm=jpg&q=60&w=3000&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8aW1hZ2V8ZW58MHx8MHx8fDA%3D",
17+
nickname: "Colaborador",
18+
};
19+
1320
export function App() {
1421
return (
1522
<div className="mx-auto mt-10 max-w-[1024px] px-5">
@@ -164,6 +171,42 @@ export function App() {
164171
}}
165172
component={Level}
166173
/>
174+
175+
<ShowComponent title="Collaborators">
176+
<div className="grid w-full justify-center gap-4">
177+
<div className="w-60">
178+
<Collaborators
179+
collaborators={[
180+
collaborator,
181+
collaborator,
182+
collaborator,
183+
collaborator,
184+
]}
185+
sourceUrl="https://github.com/RustLangES/design-system-components"
186+
/>
187+
</div>
188+
<div className="w-60">
189+
<Collaborators
190+
collaborators={[collaborator]}
191+
sourceUrl="https://github.com/RustLangES/design-system-components"
192+
/>
193+
</div>
194+
<div className="w-60">
195+
<Collaborators
196+
collaborators={[
197+
collaborator,
198+
collaborator,
199+
collaborator,
200+
collaborator,
201+
collaborator,
202+
collaborator,
203+
collaborator,
204+
]}
205+
sourceUrl="https://github.com/RustLangES/design-system-components"
206+
/>
207+
</div>
208+
</div>
209+
</ShowComponent>
167210
</div>
168211
);
169212
}

0 commit comments

Comments
 (0)