shadcn-ui / ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.
https://ui.shadcn.com
MIT License
74.17k stars 4.58k forks source link

How do I close the popover component when I use the combobox component in useFieldArray? #1625

Closed jinzhe closed 8 months ago

jinzhe commented 1 year ago

I saw in the documentation that a single combobox is handled in the following way

https://ui.shadcn.com/docs/components/combobox

const [open, setOpen] = React.useState(false)
...
<Popover open={open} onOpenChange={setOpen}>

this is my project code

import { useEffect, useState } from "react";
import { useForm, useFieldArray } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
  // toast,
  Calendar,
  Button,
  Input,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  Popover,
  PopoverContent,
  PopoverTrigger,
  // PopoverClose,
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  ScrollArea,
  Form,
  FormControl,
  // FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/";

const schema = z.object({
  diagnois: z
    .array(
      z.object({
        name: z.string().default(""),
        code: z.string().default(""),
      })
    )
    .optional(),
});

type formValues = z.infer<typeof schema>;
export default function SearchPatient() {
  const form = useForm<formValues>({
    resolver: zodResolver(schema),
    mode: "onChange",
    defaultValues: {
      diagnois: [{ name: "", code: "A0001" }],
    },
  });

  const { register, control, watch, setValue, getValues, handleSubmit } = form;

  const diagnoisList = useFieldArray({
    control,
    name: "diagnois",
  });
  const [diagnoisSearch, setDiagnoisSearch] = useState("");
  {
    diagnoisList.fields.map((item, index) => (
      <Popover>
        <PopoverTrigger asChild>
          <Button variant="outline" role="combobox" className="justify-between">
            <Input
              readOnly
              className="w-[500px] p-0 shadow-none border-none focus-visible:ring-0"
              {...register(`fields.${index}.name`)}
              onChange={() => null}
            />
            <Search className="ml-2 h-4 w-4 shrink-0 opacity-50" />
          </Button>
        </PopoverTrigger>
        <PopoverContent className="w-[558px] p-0">
          <Command>
            <CommandInput value={diagnoisSearch} onValueChange={setDiagnoisSearch} />
            <CommandEmpty>No result found.</CommandEmpty>
            <CommandGroup>
              <ScrollArea className="h-72">
                {serviceSearch != "" &&
                  diagnois.map((s: any) => (
                    <CommandItem
                      key={s.DIAG_ID}
                      onSelect={(currentValue) => {
                        //do something
                      }}
                    >
                      {s.Name}
                    </CommandItem>
                  ))}
              </ScrollArea>
            </CommandGroup>
          </Command>
        </PopoverContent>
      </Popover>
    ));
  }
}
TesheMaximillan commented 1 year ago

... First import <PopoverClose /> component .. this has to be imported at ui/popover

import * as PopoverPrimitive from '@radix-ui/react-popover';
const PopoverClose = PopoverPrimitive.Close;

then add the component inside the CommandItem ...

<CommandItem
    value={data}
    key={data}
    onSelect={() => {
        setValue(name, data);
     }}
>
  <PopoverClose>{data}</PopoverClose>
</CommandItem>
shadcn commented 8 months ago

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.