|
1 | 1 | <script setup lang="ts"> |
2 | | -import { z } from "zod"; |
| 2 | +import * as v from "valibot"; |
3 | 3 | import emojiRegex from "emoji-regex"; |
4 | 4 |
|
5 | 5 | import { useLocaleRoute } from "@typed-router"; |
@@ -51,52 +51,51 @@ const sizeInMB = (sizeInBytes: number, decimalsNum = 2) => { |
51 | 51 | return +result.toFixed(decimalsNum); |
52 | 52 | }; |
53 | 53 |
|
54 | | -const schema = z.object({ |
55 | | - name: z |
56 | | - .string() |
57 | | - .min(1, t("nameBadge.form.name.error.required")) |
58 | | - .refine( |
| 54 | +const schema = v.objectAsync({ |
| 55 | + name: v.pipe( |
| 56 | + v.string(), |
| 57 | + v.minLength(1, t("nameBadge.form.name.error.required")), |
| 58 | + v.check( |
59 | 59 | (value) => { |
60 | 60 | const len = [...value].reduce( |
61 | 61 | (len, char) => len + (/[\u2E80-\u9FFF\uF900-\uFAFF\uFF00-\uFFEF]/.test(char) ? 2 : 1), |
62 | 62 | 0, |
63 | 63 | ); |
64 | 64 | return len <= 24; |
65 | 65 | }, |
66 | | - { message: t("nameBadge.form.name.error.tooLong") }, |
67 | | - ) |
68 | | - .refine( |
| 66 | + t("nameBadge.form.name.error.tooLong"), |
| 67 | + ), |
| 68 | + v.check( |
69 | 69 | value => !emojiRegex().test(value), |
70 | | - { message: t("nameBadge.form.name.error.emoji") }, |
| 70 | + t("nameBadge.form.name.error.emoji"), |
71 | 71 | ), |
| 72 | + ), |
| 73 | +
|
| 74 | + salesId: v.pipe( |
| 75 | + v.string(), |
| 76 | + v.minLength(1, t("nameBadge.form.receipt.error.required")), |
| 77 | + ), |
72 | 78 |
|
73 | | - salesId: z |
74 | | - .string() |
75 | | - .min(1, t("nameBadge.form.receipt.error.required")), |
76 | | -
|
77 | | - avatarImage: z |
78 | | - .custom<VFFile>() |
79 | | - .refine( |
80 | | - file => !!file, |
81 | | - { message: t("nameBadge.form.avatarImage.error.required") }, |
82 | | - ) |
83 | | - .refine( |
84 | | - async (file) => { |
| 79 | + avatarImage: v.pipeAsync( |
| 80 | + v.custom<VFFile>((input: unknown): input is VFFile => !!input), |
| 81 | + v.checkAsync( |
| 82 | + async (file: VFFile) => { |
85 | 83 | const { size } = await fetch(file.objectURL).then(r => r.blob()); |
86 | 84 | return sizeInMB(size) <= 5; |
87 | 85 | }, |
88 | | - { message: t("nameBadge.form.avatarImage.error.size") }, |
89 | | - ) |
90 | | - .refine( |
91 | | - file => ["image/jpg", "image/jpeg", "image/png"].includes(file.type), |
92 | | - { message: t("nameBadge.form.avatarImage.error.type") }, |
| 86 | + t("nameBadge.form.avatarImage.error.size"), |
| 87 | + ), |
| 88 | + v.check( |
| 89 | + (file: VFFile) => ["image/jpg", "image/jpeg", "image/png"].includes(file.type), |
| 90 | + t("nameBadge.form.avatarImage.error.type"), |
93 | 91 | ), |
| 92 | + ), |
94 | 93 | }); |
95 | 94 |
|
96 | 95 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
97 | 96 | const form = useTemplateRef<any>("form"); |
98 | | -const currentStates = computed(() => form.value?.currentState?.() as FormFieldStates<z.infer<typeof schema>> | undefined); |
99 | | -const initialValues = ref<Partial<z.infer<typeof schema>>>({ |
| 97 | +const currentStates = computed(() => form.value?.currentState?.() as FormFieldStates<v.InferOutput<typeof schema>> | undefined); |
| 98 | +const initialValues = ref<Partial<v.InferOutput<typeof schema>>>({ |
100 | 99 | name: "", |
101 | 100 | salesId: "", |
102 | 101 | avatarImage: undefined, |
|
0 commit comments