| 174 | } |
| 175 | |
| 176 | function FieldError({ |
| 177 | className, |
| 178 | children, |
| 179 | errors, |
| 180 | ...props |
| 181 | }: React.ComponentProps<"div"> & { |
| 182 | errors?: Array<{ message?: string } | undefined>; |
| 183 | }) { |
| 184 | const content = useMemo(() => { |
| 185 | if (children) { |
| 186 | return children; |
| 187 | } |
| 188 | |
| 189 | if (!errors?.length) { |
| 190 | return null; |
| 191 | } |
| 192 | |
| 193 | const uniqueErrors = [ |
| 194 | ...new Map(errors.map((error) => [error?.message, error])).values(), |
| 195 | ]; |
| 196 | |
| 197 | if (uniqueErrors?.length == 1) { |
| 198 | return uniqueErrors[0]?.message; |
| 199 | } |
| 200 | |
| 201 | return ( |
| 202 | <ul className="ml-4 flex list-disc flex-col gap-1"> |
| 203 | {uniqueErrors.map( |
| 204 | (error, index) => |
| 205 | error?.message && <li key={index}>{error.message}</li> |
| 206 | )} |
| 207 | </ul> |
| 208 | ); |
| 209 | }, [children, errors]); |
| 210 | |
| 211 | if (!content) { |
| 212 | return null; |
| 213 | } |
| 214 | |
| 215 | return ( |
| 216 | <div |
| 217 | role="alert" |
| 218 | data-slot="field-error" |
| 219 | className={cn("text-destructive text-xs font-normal", className)} |
| 220 | {...props} |
| 221 | > |
| 222 | {content} |
| 223 | </div> |
| 224 | ); |
| 225 | } |
| 226 | |
| 227 | export { |
| 228 | Field, |