Skip to content

[@rjsf/shadcn] FancySelect shows red error border on required empty enums before validation #5187

Description

@moustaphaotf

Prerequisites

What theme are you using?

shadcn

Version

6.x

Current Behavior

In @rjsf/shadcn, required enum fields rendered by SelectWidget
FancySelect show a red border (border-red-500) as soon as the form mounts, even when the form has not been validated and liveValidate is false. This makes empty required selects look like validation failures on first paint.

Package / version

  • @rjsf/shadcn: 6.6.2 (also present in current main source)
  • @rjsf/core / @rjsf/utils: compatible v6.x

Expected behavior

The select should use the default border (border-input) until an actual validation error exists (e.g. after submit / when rawErrors.length > 0).
Being required and empty should not by itself show an error style before validation.

Actual behavior

The select immediately renders with border-red-500.

Root cause

In packages/shadcn/src/components/ui/fancy-select.tsx:

className={cn(
  '... border border-input ...',
  !selectedItem && required && 'border-red-500',
  // ...
)}

FancySelect treats “required + no selected value” as an error state, independently of RJSF validation / rawErrors. Meanwhile, SelectWidget already applies error styling correctly based on
validation:

const cnClassName = cn({ 'border-destructive': rawErrors.length > 0 },
className);

So there are two competing error styles, and the FancySelect one fires too early.

Steps to reproduce

  1. Render a form with the shadcn theme and a required string enum:
{
  "type": "object",
  "required": ["status"],
  "properties": {
    "status": {
      "type": "string",
      "title": "Status",
      "enum": ["draft", "active", "archived"]
    }
  }
}
  1. Use default form options that defer validation, e.g.:
<Form
  schema={schema}
  validator={validator}
  liveValidate={false}
  showErrorList={false}
/>
  1. Open the form with no initial formData for status.

Environment

- OS: Windows
- Node: v20.19.6
- npm: 10.8.2

Additional notes

  • This mainly affects required enums with no default / empty initial value.
  • It is especially confusing when liveValidate={false}, because the UI shows
    an error state with no validation having run.
  • Non-enum inputs using BaseInputTemplate do not show this premature red border; they only apply border-destructive when rawErrors.length > 0.

Happy to open a PR if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugneeds triageInitial label given, to be assigned correct labels and assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions