Skip to content

Commit 355b774

Browse files
committed
fix: char set
1 parent 4bb40e1 commit 355b774

File tree

2 files changed

+41
-24
lines changed

2 files changed

+41
-24
lines changed

src/components/form/TextField.tsx

+37-22
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,7 @@ import {
44
} from "@mui/material"
55
import { Field, type FieldConfig, type FieldProps } from "formik"
66
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"
148

159
import { schemaToFieldValidator } from "../../utils/form"
1610
import { getNestedProperty } from "../../utils/general"
@@ -52,17 +46,37 @@ const TextField: FC<TextFieldProps> = ({
5246

5347
const dotPath = name.split(".")
5448

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({
6070
message: "cannot have duplicates",
6171
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+
) {
6377
return (
6478
new Set(
65-
uniqueCaseInsensitive && typeof values[0] === "string"
79+
uniqueCaseInsensitive
6680
? values.map(value => value.toLowerCase())
6781
: values,
6882
).size === values.length
@@ -72,19 +86,20 @@ const TextField: FC<TextFieldProps> = ({
7286
return true
7387
},
7488
})
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
8097
}
81-
if (dirty)
82-
_schema = _schema.notOneOf([initialValue], "cannot be initial value")
8398

8499
const fieldConfig: FieldConfig = {
85100
name,
86101
type,
87-
validate: schemaToFieldValidator(_schema, validateOptions),
102+
validate: schemaToFieldValidator(buildSchema(), validateOptions),
88103
}
89104

90105
const _Field: FC<FieldProps> = ({ form }) => {

src/schemas/user.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as yup from "yup"
22

3-
// TODO: restrict character set; no special characters
4-
export const firstNameSchema = yup.string().max(150)
3+
export const firstNameSchema = yup
4+
.string()
5+
.max(150)
6+
.matches(/^[a-zA-Z]*$/, "can only contain only letters characters")

0 commit comments

Comments
 (0)