@@ -4,13 +4,7 @@ import {
4
4
} from "@mui/material"
5
5
import { Field , type FieldConfig , type FieldProps } from "formik"
6
6
import { type FC , useState , useEffect } from "react"
7
- import {
8
- type ArraySchema ,
9
- type StringSchema ,
10
- type ValidateOptions ,
11
- array as YupArray ,
12
- type Schema ,
13
- } from "yup"
7
+ import { type StringSchema , type ValidateOptions , array as YupArray } from "yup"
14
8
15
9
import { schemaToFieldValidator } from "../../utils/form"
16
10
import { getNestedProperty } from "../../utils/general"
@@ -52,17 +46,37 @@ const TextField: FC<TextFieldProps> = ({
52
46
53
47
const dotPath = name . split ( "." )
54
48
55
- let _schema : Schema = schema
56
- if ( split ) {
57
- _schema = YupArray ( ) . of ( _schema )
58
- if ( unique || uniqueCaseInsensitive ) {
59
- _schema = _schema . test ( {
49
+ function buildSchema ( ) {
50
+ // Build a schema for a single string.
51
+ let stringSchema = schema
52
+ // 1: Validate string is required.
53
+ if ( required ) stringSchema = stringSchema . required ( )
54
+ // 2: Validate string is dirty.
55
+ if ( dirty && ! split )
56
+ stringSchema = stringSchema . notOneOf (
57
+ [ initialValue as string ] ,
58
+ "cannot be initial value" ,
59
+ )
60
+ // Return a schema for a single string.
61
+ if ( ! split ) return stringSchema
62
+
63
+ // Build a schema for an array of strings.
64
+ let arraySchema = YupArray ( ) . of ( stringSchema )
65
+ // 1: Validate array has min one string.
66
+ if ( required ) arraySchema = arraySchema . required ( ) . min ( 1 )
67
+ // 2: Validate array has unique strings.
68
+ if ( unique || uniqueCaseInsensitive )
69
+ arraySchema = arraySchema . test ( {
60
70
message : "cannot have duplicates" ,
61
71
test : values => {
62
- if ( Array . isArray ( values ) && values . length >= 2 ) {
72
+ if (
73
+ Array . isArray ( values ) &&
74
+ values . length >= 2 &&
75
+ values . every ( value => typeof value === "string" )
76
+ ) {
63
77
return (
64
78
new Set (
65
- uniqueCaseInsensitive && typeof values [ 0 ] === "string"
79
+ uniqueCaseInsensitive
66
80
? values . map ( value => value . toLowerCase ( ) )
67
81
: values ,
68
82
) . size === values . length
@@ -72,19 +86,20 @@ const TextField: FC<TextFieldProps> = ({
72
86
return true
73
87
} ,
74
88
} )
75
- }
76
- }
77
- if ( required ) {
78
- _schema = _schema . required ( )
79
- if ( split ) _schema = ( _schema as ArraySchema < string [ ] , any > ) . min ( 1 )
89
+ // 3: Validate array is dirty.
90
+ if ( dirty )
91
+ arraySchema = arraySchema . notOneOf (
92
+ [ initialValue as string [ ] ] ,
93
+ "cannot be initial value" ,
94
+ )
95
+ // Return a schema for an array of strings.
96
+ return arraySchema
80
97
}
81
- if ( dirty )
82
- _schema = _schema . notOneOf ( [ initialValue ] , "cannot be initial value" )
83
98
84
99
const fieldConfig : FieldConfig = {
85
100
name,
86
101
type,
87
- validate : schemaToFieldValidator ( _schema , validateOptions ) ,
102
+ validate : schemaToFieldValidator ( buildSchema ( ) , validateOptions ) ,
88
103
}
89
104
90
105
const _Field : FC < FieldProps > = ( { form } ) => {
0 commit comments