Skip to content

Commit 47a2486

Browse files
committed
feat: a working version of selector
1 parent 6b9a47d commit 47a2486

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

src/components/common/share.tsx

+4-15
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,16 @@ const Share = ({ title, subtitle, trigger, contacts }: Props) => {
6161
) : (
6262
<div className="my-3">
6363
<MultipleSelector
64+
customLabel={true}
6465
className="bg-white py-3"
6566
selected={selected}
6667
setSelected={setSelected}
67-
// options={options}
6868
options={contacts.map((contact) => ({
69-
label: contact.email,
69+
label: contact.name || "",
70+
subLabel: contact.email,
71+
image: contact.image,
7072
value: contact.email,
7173
}))}
72-
// options={[
73-
// { label: "nextjs", value: "nextjs" },
74-
// { label: "React", value: "react" },
75-
// { label: "Remix", value: "remix" },
76-
// { label: "Vite", value: "vite" },
77-
// { label: "Nuxt", value: "nuxt" },
78-
// { label: "Vue", value: "vue" },
79-
// { label: "Svelte", value: "svelte" },
80-
// { label: "Angular", value: "angular" },
81-
// { label: "Ember", value: "ember", disable: true },
82-
// { label: "Gatsby", value: "gatsby", disable: true },
83-
// { label: "Astro", value: "astro" },
84-
// ]}
8574
placeholder="Search stakeholders, members or add email addresses"
8675
creatable
8776
emptyIndicator={

src/components/ui/multi-selector.tsx

+26-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { Avatar, AvatarImage } from "@/components/ui/avatar";
34
import { RiCloseLine as CloseIcon } from "@remixicon/react";
45
import * as React from "react";
56

@@ -15,10 +16,10 @@ import { Command as CommandPrimitive, useCommandState } from "cmdk";
1516
import { forwardRef, useEffect } from "react";
1617

1718
export type Option = {
18-
name?: string;
19-
image?: string;
2019
value: string;
2120
label: string;
21+
subLabel?: string;
22+
image?: string;
2223
disable?: boolean;
2324
/** fixed option that can't be removed. */
2425
fixed?: boolean;
@@ -29,6 +30,7 @@ type GroupOption = Record<string, Option[]>;
2930

3031
interface MultipleSelectorProps {
3132
value?: Option[];
33+
customLabel: boolean; // If true, the label will be rendered as a ReactNode, provide subLabel and image props to Option
3234
defaultOptions?: Option[];
3335
/** manually controlled options */
3436
options?: Option[];
@@ -186,6 +188,7 @@ const MultipleSelector = React.forwardRef<
186188
inputProps,
187189
selected,
188190
setSelected,
191+
customLabel = false,
189192
}: MultipleSelectorProps,
190193
ref: React.Ref<MultipleSelectorRef>,
191194
) => {
@@ -493,7 +496,27 @@ const MultipleSelector = React.forwardRef<
493496
"cursor-default text-muted-foreground",
494497
)}
495498
>
496-
{option.label}
499+
{customLabel ? (
500+
<div className="flex items-center gap-2">
501+
<Avatar className="h-8 w-8 rounded-full">
502+
<AvatarImage
503+
src={
504+
option.image ?? "/placeholders/user.svg"
505+
}
506+
/>
507+
</Avatar>
508+
<span className="flex flex-col font-medium">
509+
<span className="text-sm">
510+
{option.label}
511+
</span>
512+
<span className="text-xs text-primary/50">
513+
{option.subLabel}
514+
</span>
515+
</span>
516+
</div>
517+
) : (
518+
<>{option.label}</>
519+
)}
497520
</CommandItem>
498521
);
499522
})}

0 commit comments

Comments
 (0)