ui icon indicating copy to clipboard operation
ui copied to clipboard

[bug]: Select in FieldGroup with conditional field disappear

Open andreadecastri opened this issue 3 months ago • 3 comments

Describe the bug

"use client";

import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSet,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import { useTranslations } from "next-intl";
import type { FC } from "react";
import { Controller, useForm } from "react-hook-form";

export const SubscriptionForm: FC = () => {
  const t = useTranslations("CreateProductPage");
  const tDurationTypes = useTranslations("DurationTypes");
  const tPeriodTypes = useTranslations("PeriodTypes");

  const { register, watch, control } = useForm({
    defaultValues: {
      name: "",
      internal_name: "",
      description: "",
      duration_type: "TIME_BASED",
      period: "MONTH",
      period_count: 1,
      max_weekly_entries: 0,
      entry_count: "",
      session_count: "",
      validity_days: "",
    },
  });

  const durationType = watch("duration_type");

  return (
    <form className="max-w-4xl">
      <FieldSet>
        {/* <FieldGroup className="grid grid-cols-1 gap-4"> */}
        {/* NOTE: Field group rimosso perché va in conflitto con shadcn e react hook form */}
        <div className="grid grid-cols-1 gap-4">
          <Field>
            <FieldLabel>{t("fields.name")}</FieldLabel>
            <FieldDescription>{t("descriptions.name")}</FieldDescription>
            <Input {...register("name")} />
          </Field>
          <Field>
            <FieldLabel>{t("fields.internal_name")}</FieldLabel>
            <FieldDescription>
              {t("descriptions.internal_name")}
            </FieldDescription>
            <Input {...register("internal_name")} />
          </Field>
        </div>

        <div className="grid grid-cols-1 gap-4">
          <Field>
            <FieldLabel>{t("fields.description")}</FieldLabel>
            <Textarea {...register("description")} />
          </Field>
        </div>

        <FieldGroup className="grid grid-cols-2 gap-4">
          <Field>
            <FieldLabel>{t("fields.duration_type")}</FieldLabel>
            <Controller
              name="duration_type"
              control={control}
              render={({ field }) => (
                <Select
                  name={field.name}
                  value={field.value}
                  onValueChange={field.onChange}
                >
                  <SelectTrigger className="w-64">
                    <SelectValue placeholder={t("fields.duration_type")} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value={"TIME_BASED"}>
                      {tDurationTypes("TIME_BASED")}
                    </SelectItem>
                    <SelectItem value={"ENTRY_BASED"}>
                      {tDurationTypes("ENTRY_BASED")}
                    </SelectItem>
                    <SelectItem value={"SESSION_BASED"}>
                      {tDurationTypes("SESSION_BASED")}
                    </SelectItem>
                  </SelectContent>
                </Select>
              )}
            />
          </Field>
        </FieldGroup>
       
        {durationType === "TIME_BASED" && (
          <div className="grid grid-cols-2 gap-4">
            <Field>
              <FieldLabel>{t("fields.period")}</FieldLabel>
              <Controller
                name="period"
                control={control}
                render={({ field }) => (
                  <Select
                    name={field.name}
                    value={field.value}
                    onValueChange={field.onChange}
                  >
                    <SelectTrigger className="w-64">
                      <SelectValue placeholder={t("fields.period")} />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value={"WEEK"}>
                        {tPeriodTypes("WEEK")}
                      </SelectItem>
                      <SelectItem value={"MONTH"}>
                        {tPeriodTypes("MONTH")}
                      </SelectItem>
                      <SelectItem value={"QUARTER"}>
                        {tPeriodTypes("QUARTER")}
                      </SelectItem>
                      <SelectItem value={"SEMESTER"}>
                        {tPeriodTypes("SEMESTER")}
                      </SelectItem>
                      <SelectItem value={"YEAR"}>
                        {tPeriodTypes("YEAR")}
                      </SelectItem>
                    </SelectContent>
                  </Select>
                )}
              />
            </Field>

            <Field>
              <FieldLabel>{t("fields.period_count")}</FieldLabel>
              <Input {...register("period_count")} type="number" />
            </Field>
          </div>
        )}

        {durationType === "TIME_BASED" && (
          <div className="grid grid-cols-2 gap-4">
            <Field>
              <FieldLabel>{t("fields.max_weekly_entries")}</FieldLabel>
              <FieldDescription>
                {t("descriptions.max_weekly_entries")}
              </FieldDescription>
              <Input {...register("max_weekly_entries")} type="number" />
            </Field>
          </div>
        )}

        {durationType === "ENTRY_BASED" && (
          <div className="grid grid-cols-2 gap-4">
            <Field>
              <FieldLabel>{t("fields.entry_count")}</FieldLabel>
              <Input {...register("entry_count")} type="number" />
            </Field>

            <Field>
              <FieldLabel>{t("fields.validity_days")}</FieldLabel>
              <Input {...register("validity_days")} type="number" />
            </Field>
          </div>
        )}

        {durationType === "SESSION_BASED" && (
          <div className="grid grid-cols-2 gap-4">
            <Field>
              <FieldLabel>{t("fields.session_count")}</FieldLabel>
              <Input {...register("session_count")} type="number" />
            </Field>

            <Field>
              <FieldLabel>{t("fields.validity_days")}</FieldLabel>
              <Input {...register("validity_days")} type="number" />
            </Field>
          </div>
        )}
      </FieldSet>
    </form>
  );
};

Affected component/components

Select

How to reproduce

If i wrap the Select in a FieldGroup and I have conditional Fields the select (in this case duration_type) disappear and is not visible onChange. Replacing the FieldGroup with div works. I guess some conflicts with tailwind classes.

Codesandbox/StackBlitz link

No response

Logs


System Info

"react-hook-form": "^7.63.0"
"@radix-ui/react-select": "^2.2.6"
Chrome 141.0.7390.76 (Build ufficiale) (arm64) Mac

Before submitting

  • [x] I've made research efforts and searched the documentation
  • [x] I've searched for existing issues

andreadecastri avatar Oct 14 '25 06:10 andreadecastri

@andreadecastri any chance you can share an example I can test please?

shadcn avatar Oct 16 '25 10:10 shadcn

@andreadecastri any chance you can share an example I can test please?

Hi, I’m encountering a similar issue. The issue only occurs after the field has already been validated and an error message is displayed. When I uncheck the item, the pets options disappear, and this only happens on mobile devices. It does not occur on desktop browsers.

https://github.com/user-attachments/assets/af7f5781-bf22-4115-a711-092525c67a80

this is the minimal reproducible example: here

aboyo avatar Nov 29 '25 07:11 aboyo

Image Seems to fix

jakeleventhal avatar Dec 15 '25 16:12 jakeleventhal

Hi @andreadecastri, try removing FieldSet and see what happens its seems like fieldset (BFC) conflicts with CSS Container Queries @container/field-group need more time to investigate, hope to return with an answer soon

BuhayovA avatar Dec 19 '25 10:12 BuhayovA

Create separate bug with live demo and code example: https://github.com/shadcn-ui/ui/issues/9147

BuhayovA avatar Dec 19 '25 11:12 BuhayovA