pull/6632/head
Mert Sincan 2024-10-23 10:27:41 +01:00
parent 47f243fb5c
commit 5bbc7a57d4
4 changed files with 36 additions and 11 deletions

View File

@ -3,13 +3,13 @@
<p>Form uses the <i>name</i> property to create a state object for tracking values, errors, and actions.</p> <p>Form uses the <i>name</i> property to create a state object for tracking values, errors, and actions.</p>
</DocSectionText> </DocSectionText>
<div class="card flex justify-center"> <div class="card flex justify-center">
<Form v-slot="$form" :initialValues="initialValues" :resolver="resolver" @submit="onFormSubmit" class="grid md:grid-cols-2 gap-4 w-full"> <Form v-slot="$form" :initialValues :resolver @submit="onFormSubmit" class="grid lg:grid-cols-2 gap-4 w-full">
<div class="flex flex-col justify-center items-center gap-4"> <div class="flex flex-col justify-center items-center gap-4">
<InputText name="username" type="text" placeholder="Username" /> <InputText name="username" type="text" placeholder="Username" />
<Button type="submit" severity="secondary" label="Submit" /> <Button type="submit" severity="secondary" label="Submit" />
</div> </div>
<Fieldset legend="Form States"> <Fieldset legend="Form States">
<pre>{{ $form }}</pre> <pre class="whitespace-pre-wrap">{{ $form }}</pre>
</Fieldset> </Fieldset>
</Form> </Form>
</div> </div>
@ -25,13 +25,13 @@ export default {
}, },
code: { code: {
basic: ` basic: `
<Form v-slot="$form" :initialValues :resolver @submit="onFormSubmit" class="grid md:grid-cols-2 gap-4 w-full"> <Form v-slot="$form" :initialValues :resolver @submit="onFormSubmit" class="grid lg:grid-cols-2 gap-4 w-full">
<div class="flex flex-col justify-center items-center gap-4"> <div class="flex flex-col justify-center items-center gap-4">
<InputText name="username" type="text" placeholder="Username" /> <InputText name="username" type="text" placeholder="Username" />
<Button type="submit" severity="secondary" label="Submit" /> <Button type="submit" severity="secondary" label="Submit" />
</div> </div>
<Fieldset legend="Form States"> <Fieldset legend="Form States">
<pre>{{ $form }}</pre> <pre class="whitespace-pre-wrap">{{ $form }}</pre>
</Fieldset> </Fieldset>
</Form> </Form>
`, `,
@ -99,10 +99,14 @@ export default {
}, },
methods: { methods: {
resolver: ({ values }) => { resolver: ({ values }) => {
const errors = {}; const errors = { username: [] };
if (!values.username) { if (!values.username) {
errors.username = [{ message: 'Username is required.' }]; errors.username.push({ type: 'required', message: 'Username is required.' });
}
if (values.username?.length < 3) {
errors.username.push({ type: 'minimum', message: 'Username must be at least 3 characters long.' });
} }
return { return {

View File

@ -72,14 +72,29 @@ export interface FormPassThroughAttributes {
[key: string]: any; [key: string]: any;
} }
/**
* Resolver options for Form component.
*/
export interface FormResolverOptions {
/**
* The values of the form fields.
*/
values: Record<string, any>;
/**
* The names of the form fields.
*/
names: string[] | undefined;
}
/** /**
* Defines valid properties in Form component. * Defines valid properties in Form component.
*/ */
export interface FormProps { export interface FormProps {
/** /**
* A function that resolves validation logic. * A function that resolves validation logic.
* @param {FormResolverOptions} e - Resolver options
*/ */
resolver?: (values: Record<string, any>) => Promise<Record<string, any>> | Record<string, any> | undefined; resolver?: (e: FormResolverOptions) => Promise<Record<string, any>> | Record<string, any> | undefined;
/** /**
* The initial values for the form fields. * The initial values for the form fields.
*/ */

View File

@ -7,8 +7,13 @@ export interface useFormReturn {
states: any; states: any;
} }
export interface useFormResolverOptions {
values: Record<string, any>;
names: string[] | undefined;
}
export interface useFormOptions { export interface useFormOptions {
resolver?: (values: Record<string, any>) => Promise<Record<string, any>> | Record<string, any> | undefined; resolver?: (e: useFormResolverOptions) => Promise<Record<string, any>> | Record<string, any> | undefined;
initialValues?: Record<string, any> | undefined; initialValues?: Record<string, any> | undefined;
validateOnValueUpdate?: boolean | string[]; validateOnValueUpdate?: boolean | string[];
validateOnBlur?: boolean | string[]; validateOnBlur?: boolean | string[];

View File

@ -84,13 +84,14 @@ export const useForm = (options = {}) => {
}; };
const validate = async (field) => { const validate = async (field) => {
const names = Object.keys(states) ?? [];
const values = Object.entries(states).reduce((acc, [key, val]) => { const values = Object.entries(states).reduce((acc, [key, val]) => {
acc[key] = val.value; acc[key] = val.value;
return acc; return acc;
}, {}); }, {});
const result = (await options.resolver?.({ values })) ?? {}; const result = (await options.resolver?.({ values, names })) ?? {};
for (const sField of Object.keys(states)) { for (const sField of Object.keys(states)) {
if (sField === field || !field) { if (sField === field || !field) {
@ -118,7 +119,7 @@ export const useForm = (options = {}) => {
handleSubmit, handleSubmit,
validate, validate,
reset, reset,
valid: toValue(valid), valid,
states: toValue(states) states
}; };
}; };