Skip to content

Commit

Permalink
feat: add new combobox component
Browse files Browse the repository at this point in the history
  • Loading branch information
ervinpiol committed Sep 28, 2024
1 parent ee230c0 commit 5857355
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 202 deletions.
96 changes: 2 additions & 94 deletions web/src/app/ee/admin/teams/UserEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,97 +1,6 @@
/* import { User } from "@/lib/types";
import { SearchMultiSelectDropdown } from "@/components/Dropdown";
import { UsersIcon } from "@/components/icons/icons";
import { Button } from "@/components/ui/button";
import { Plus, X } from "lucide-react";
import { Badge } from "@/components/ui/badge";
interface UserEditorProps {
selectedUserIds: string[];
setSelectedUserIds: (userIds: string[]) => void;
allUsers: User[];
existingUsers: User[];
onSubmit?: (users: User[]) => void;
}
export const UserEditor = ({
selectedUserIds,
setSelectedUserIds,
allUsers,
existingUsers,
onSubmit,
}: UserEditorProps) => {
const selectedUsers = allUsers.filter((user) =>
selectedUserIds.includes(user.id)
);
return (
<>
<div className="flex">
<SearchMultiSelectDropdown
options={allUsers
.filter(
(user) =>
!selectedUserIds.includes(user.id) &&
!existingUsers.map((user) => user.id).includes(user.id)
)
.map((user) => {
return {
name: user.email,
value: user.id,
};
})}
onSelect={(option) => {
setSelectedUserIds([
...Array.from(
new Set([...selectedUserIds, option.value as string])
),
]);
}}
itemComponent={({ option }) => (
<div className="flex w-full">
<UsersIcon className="mr-2 my-auto" />
{option.name}
<div className="ml-auto my-auto">
<Plus size={16} />
</div>
</div>
)}
/>
{onSubmit && (
<Button
className="ml-3 flex-nowrap w-32"
onClick={() => onSubmit(selectedUsers)}
>
Add Users
</Button>
)}
</div>
<div className="flex flex-wrap gap-2 pt-2">
{selectedUsers.length > 0 &&
selectedUsers.map((selectedUser) => (
<Badge
key={selectedUser.id}
onClick={() => {
setSelectedUserIds(
selectedUserIds.filter((userId) => userId !== selectedUser.id)
);
}}
variant="outline"
className="cursor-pointer hover:bg-opacity-80"
>
{selectedUser.email}{" "}
<X className="ml-1 my-auto cursor-pointer" size={14} />
</Badge>
))}
</div>
</>
);
}; */
import { User } from "@/lib/types";
import { UsersIcon } from "@/components/icons/icons";
import { Button } from "@/components/ui/button";
import { Plus, X } from "lucide-react";
import { X } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Combobox } from "@/components/Combobox";

Expand All @@ -114,7 +23,6 @@ export const UserEditor = ({
selectedUserIds.includes(user.id)
);

// Prepare the list of available users for the Combobox
const availableUsers = allUsers
.filter(
(user) =>
Expand Down Expand Up @@ -165,7 +73,7 @@ export const UserEditor = ({
variant="outline"
className="cursor-pointer hover:bg-opacity-80"
>
{selectedUser.email}{" "}
{selectedUser.email}
<X className="ml-1 my-auto cursor-pointer" size={14} />
</Badge>
))}
Expand Down
118 changes: 10 additions & 108 deletions web/src/components/Combobox.tsx
Original file line number Diff line number Diff line change
@@ -1,102 +1,7 @@
/* "use client";
import * as React from "react";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
const frameworks = [
{
value: "next.js",
label: "Next.js",
},
{
value: "sveltekit",
label: "SvelteKit",
},
{
value: "nuxt.js",
label: "Nuxt.js",
},
{
value: "remix",
label: "Remix",
},
{
value: "astro",
label: "Astro",
},
];
export function Combobox() {
const [open, setOpen] = React.useState(false);
const [value, setValue] = React.useState("");
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className="w-[200px] justify-between"
>
{value
? frameworks.find((framework) => framework.value === value)?.label
: "Select framework..."}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput placeholder="Search framework..." />
<CommandList>
<CommandEmpty>No framework found.</CommandEmpty>
<CommandGroup>
{frameworks.map((framework) => (
<CommandItem
key={framework.value}
value={framework.value}
onSelect={(currentValue) => {
setValue(currentValue === value ? "" : currentValue);
setOpen(false);
}}
>
<Check
className={cn(
"mr-2 h-4 w-4",
value === framework.value ? "opacity-100" : "opacity-0"
)}
/>
{framework.label}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
} */
"use client";

import * as React from "react";
import { Check, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { ChevronsUpDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Command,
Expand All @@ -112,7 +17,6 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";

// Reusable Combobox component
interface ComboboxProps {
items: { value: string; label: string }[];
onSelect?: (selectedValue: string) => void;
Expand All @@ -130,7 +34,9 @@ export function Combobox({
const [value, setValue] = React.useState("");

const handleSelect = (currentValue: string) => {
const newValue = currentValue === value ? "" : currentValue;
const selectedItem = items.find((item) => item.label === currentValue);
const newValue = selectedItem ? selectedItem.value : "";

setValue(newValue);
setOpen(false);

Expand All @@ -139,6 +45,8 @@ export function Combobox({
}
};

const selectedItemLabel = items.find((item) => item.value === value)?.label;

return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
Expand All @@ -148,12 +56,12 @@ export function Combobox({
aria-expanded={open}
className="w-full justify-between"
>
{value ? items.find((item) => item.value === value)?.label : label}
{selectedItemLabel || label}
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="min-w-[300px] sm:min-w-[490px] xl:min-w-[625px]"
className="min-w-[300px] sm:min-w-[495px] md:min-w-[550px] lg:min-w-[495px] xl:min-w-[630px]"
align="start"
>
<Command>
Expand All @@ -166,15 +74,9 @@ export function Combobox({
{items.map((item) => (
<CommandItem
key={item.value}
value={item.value}
onSelect={() => handleSelect(item.value)}
value={item.label}
onSelect={() => handleSelect(item.label)}
>
<Check
className={cn(
"mr-2 h-4 w-4",
value === item.value ? "opacity-100" : "opacity-0"
)}
/>
{item.label}
</CommandItem>
))}
Expand Down

0 comments on commit 5857355

Please sign in to comment.