import {
KolComboboxController,
KolInputCheckboxController,
KolInputColorController,
KolInputDateController,
KolInputEmailController,
KolInputFileController,
KolInputNumberController,
KolInputPasswordController,
KolInputRadioController,
KolInputRangeController,
KolInputTextController,
KolSelectController,
KolSingleSelectController,
KolTextareaController,
} from '@public-ui/react-hook-form-adapter';
import { KolButton, KolForm } from '@public-ui/react-v19';
import React, { type BaseSyntheticEvent, type FC } from 'react';
import type { FieldErrors, SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import { SampleDescription } from '../../components/SampleDescription';
import { COUNTRY_SUGGESTIONS } from '../../shares/country';
interface FormData {
firstName: string;
lastName: string;
email: string;
password: string;
age: number;
volume: number;
birthday: string;
favoriteColor: string;
cv: FileList | null;
bio: string;
country: string;
language: string;
framework: string;
gender: string;
termsAccepted: boolean;
}
const defaultValues: FormData = {
firstName: '',
lastName: '',
email: '',
password: '',
age: 18,
volume: 50,
birthday: '',
favoriteColor: '#000000',
cv: null,
bio: '',
country: '',
language: 'de',
framework: '',
gender: '',
termsAccepted: false,
};
const languageOptions = [
{ label: 'English', value: 'en' },
{ label: 'German', value: 'de' },
{ label: 'French', value: 'fr' },
];
const frameworkOptions = [
{ label: 'React', value: 'react' },
{ label: 'Vue', value: 'vue' },
{ label: 'Stencil', value: 'stencil' },
];
const genderOptions = [
{ label: 'Male', value: 'male' },
{ label: 'Female', value: 'female' },
{ label: 'Other', value: 'other' },
];
const allFields: Array<keyof FormData> = [
'firstName',
'lastName',
'email',
'password',
'age',
'volume',
'birthday',
'favoriteColor',
'cv',
'bio',
'country',
'language',
'framework',
'gender',
'termsAccepted',
];
export const RHFBasic: FC = () => {
const { control, handleSubmit, setValue, getValues, trigger } = useForm<FormData>({
defaultValues,
mode: 'onTouched',
shouldFocusError: true,
});
const touchAndValidateAll = () => {
allFields.forEach((name) => {
setValue(name, getValues(name), { shouldTouch: true, shouldValidate: true });
});
};
const onSubmit: SubmitHandler<FormData> = (data) => {
alert(JSON.stringify(data, null, 2));
};
const onError = (errors: FieldErrors<FormData>) => {
touchAndValidateAll();
void trigger(undefined, { shouldFocus: true });
console.warn('Validation errors:', errors);
};
return (
<>
<SampleDescription>
<p>
This sample demonstrates a form using React Hook Form with KoliBri adapters wrapped in a KolForm. All inputs are validated, and error messages are
shown on submit.
</p>
</SampleDescription>
<KolForm
className="w-full max-w-xl"
_on={{
onSubmit: (event) => {
void handleSubmit(onSubmit, onError)(event as unknown as BaseSyntheticEvent);
},
}}
>
<div className="grid gap-4">
<KolInputTextController name="firstName" control={control} _label="First Name" rules={{ required: 'First name is required' }} _required />
<KolInputTextController name="lastName" control={control} _label="Last Name" rules={{ required: 'Last name is required' }} _required />
<KolInputEmailController name="email" control={control} _label="Email" rules={{ required: 'Email is required' }} _required />
<KolInputPasswordController name="password" control={control} _label="Password" rules={{ required: 'Password is required' }} _required />
<KolInputNumberController name="age" control={control} _label="Age" rules={{ required: 'Age is required', min: 0 }} _required />
<KolInputRangeController name="volume" control={control} _label="Volume (0–100)" _min={0} _max={100} />
<KolInputDateController name="birthday" control={control} _label="Birthday" rules={{ required: 'Birthday is required' }} />
<KolInputColorController name="favoriteColor" control={control} _label="Favorite Color" id="favoriteColor" />
<KolInputFileController name="cv" control={control} _label="Upload CV" rules={{ required: 'Please upload your CV' }} _required />
<KolTextareaController name="bio" control={control} _label="Bio" rules={{ required: 'Please provide a short bio' }} _required />
<KolComboboxController
control={control}
rules={{ required: 'Please select a country' }}
name="country"
_label="Country"
_suggestions={COUNTRY_SUGGESTIONS}
_required
/>
<KolSelectController
control={control}
rules={{ required: 'Please select a language' }}
name="language"
_label="Preferred Language"
_options={languageOptions}
_required
/>
<KolSingleSelectController
rules={{ required: 'Please select a framework' }}
control={control}
name="framework"
_label="Favorite Framework"
_options={frameworkOptions}
_required
/>
<KolInputRadioController
control={control}
rules={{ required: 'Please select your gender' }}
name="gender"
_label="Gender"
_options={genderOptions}
_required
/>
<KolInputCheckboxController
name="termsAccepted"
control={control}
_label="I accept the terms and conditions"
rules={{ required: 'You must accept the terms' }}
_required
/>
<KolButton _label="Submit" _type="submit" />
</div>
</KolForm>
</>
);
};