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
- 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"]
}
}
}
- Use default form options that defer validation, e.g.:
<Form
schema={schema}
validator={validator}
liveValidate={false}
showErrorList={false}
/>
- 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.
Prerequisites
What theme are you using?
shadcn
Version
6.x
Current Behavior
In
@rjsf/shadcn, requiredenumfields rendered bySelectWidget→FancySelectshow a red border (border-red-500) as soon as the form mounts, even when the form has not been validated andliveValidateisfalse. This makes empty required selects look like validation failures on first paint.Package / version
@rjsf/shadcn:6.6.2(also present in currentmainsource)@rjsf/core/@rjsf/utils: compatible v6.xExpected behavior
The select should use the default border (
border-input) until an actual validation error exists (e.g. after submit / whenrawErrors.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:FancySelecttreats “required + no selected value” as an error state, independently of RJSF validation /rawErrors. Meanwhile,SelectWidgetalready applies error styling correctly based onvalidation:
So there are two competing error styles, and the FancySelect one fires too early.
Steps to reproduce
{ "type": "object", "required": ["status"], "properties": { "status": { "type": "string", "title": "Status", "enum": ["draft", "active", "archived"] } } }formDataforstatus.Environment
Additional notes
liveValidate={false}, because the UI showsan error state with no validation having run.
BaseInputTemplatedo not show this premature red border; they only applyborder-destructivewhenrawErrors.length > 0.Happy to open a PR if useful.