Skip to content

Commit

Permalink
feat: experimetnal validitystate support
Browse files Browse the repository at this point in the history
  • Loading branch information
edmundhung committed Nov 29, 2023
1 parent 0aeca96 commit 21a9008
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 155 deletions.
45 changes: 18 additions & 27 deletions examples/chakra-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,13 @@ import {
} from '@chakra-ui/react';
import { useRef } from 'react';

interface Schema {
email: string;
language: string;
description: string;
quantity: number;
pin: string;
title: string;
progress: number;
ranges: number[];
subscribe: boolean;
enabled: boolean;
active: boolean;
}
type Error = {
validity: ValidityState;
validationMessage: string;
};

export default function Example() {
const form = useForm<Schema>({
const form = useForm({
shouldValidate: 'onBlur',
shouldRevalidate: 'onInput',
onValidate(context) {
Expand All @@ -79,7 +70,7 @@ export default function Example() {
<FormLabel>Email (Input)</FormLabel>
<Input type="email" name={form.fields.email.name} required />
<FormErrorMessage>
{form.fields.email.error?.join(', ')}
{form.fields.email.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -95,15 +86,15 @@ export default function Example() {
<option value="japanese">Japanese</option>
</Select>
<FormErrorMessage>
{form.fields.language.error?.join(', ')}
{form.fields.language.error?.validationMessage}
</FormErrorMessage>
</FormControl>

<FormControl isInvalid={!form.fields.description.valid}>
<FormLabel>Description (Textarea)</FormLabel>
<Textarea name={form.fields.description.name} required />
<FormErrorMessage>
{form.fields.description.error?.join(', ')}
{form.fields.description.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -114,15 +105,15 @@ export default function Example() {
formId={form.id}
/>
<FormErrorMessage>
{form.fields.quantity.error?.join(', ')}
{form.fields.quantity.error?.validationMessage}
</FormErrorMessage>
</FormControl>

<FormControl isInvalid={!form.fields.pin.valid}>
<FormLabel>PIN (PinInput)</FormLabel>
<ExamplePinInput name={form.fields.pin.name} formId={form.id} />
<FormErrorMessage>
{form.fields.pin.error?.join(', ')}
{form.fields.pin.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -136,7 +127,7 @@ export default function Example() {
<EditableInput name={form.fields.title.name} required />
</Editable>
<FormErrorMessage>
{form.fields.title.error?.join(', ')}
{form.fields.title.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -146,15 +137,15 @@ export default function Example() {
Newsletter
</Checkbox>
<FormErrorMessage>
{form.fields.subscribe.error?.join(', ')}
{form.fields.subscribe.error?.validationMessage}
</FormErrorMessage>
</FormControl>

<FormControl isInvalid={!form.fields.enabled.valid}>
<FormLabel>Enabled (Switch)</FormLabel>
<Switch name={form.fields.enabled.name} required />
<FormErrorMessage>
{form.fields.enabled.error?.join(', ')}
{form.fields.enabled.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -165,7 +156,7 @@ export default function Example() {
formId={form.id}
/>
<FormErrorMessage>
{form.fields.progress.error?.join(', ')}
{form.fields.progress.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand Down Expand Up @@ -197,7 +188,7 @@ export default function Example() {
</Stack>
</RadioGroup>
<FormErrorMessage>
{form.fields.active.error?.join(', ')}
{form.fields.active.error?.validationMessage}
</FormErrorMessage>
</FormControl>

Expand All @@ -216,7 +207,7 @@ export default function Example() {
);
}

function ExampleNumberInput(props: FieldProps<number>) {
function ExampleNumberInput(props: FieldProps<number, Error>) {
const field = useField(props);
const control = useInputControl(field);

Expand All @@ -236,7 +227,7 @@ function ExampleNumberInput(props: FieldProps<number>) {
);
}

function ExamplePinInput(config: FieldProps<string>) {
function ExamplePinInput(config: FieldProps<string, Error>) {
const inputRef = useRef<HTMLInputElement>(null);
const field = useField(config);
const control = useInputControl(field);
Expand All @@ -256,7 +247,7 @@ function ExamplePinInput(config: FieldProps<string>) {
);
}

function ExampleSlider(config: FieldProps<number>) {
function ExampleSlider(config: FieldProps<number, Error>) {
const field = useField(config);
const control = useInputControl(field, {
initialize(value) {
Expand Down
28 changes: 13 additions & 15 deletions examples/headless-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ import { Listbox, Combobox, Switch, RadioGroup } from '@headlessui/react';
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/react/20/solid';
import { useState } from 'react';

interface Schema {
owner: string;
assignee: string;
enabled: boolean;
color: string;
}
type Error = {
validity: ValidityState;
validationMessage: string;
};

export default function Example() {
const form = useForm<Schema>({
const form = useForm({
shouldValidate: 'onBlur',
shouldRevalidate: 'onInput',
onValidate(context) {
Expand Down Expand Up @@ -58,7 +56,7 @@ export default function Example() {
/>
</div>
<p className="mt-2 text-sm text-red-500">
{form.fields.owner.error?.join(', ')}
{form.fields.owner.error?.validationMessage}
</p>
</div>

Expand All @@ -73,7 +71,7 @@ export default function Example() {
/>
</div>
<p className="mt-2 text-sm text-red-500">
{form.fields.assignee.error?.join(', ')}
{form.fields.assignee.error?.validationMessage}
</p>
</div>

Expand All @@ -88,7 +86,7 @@ export default function Example() {
/>
</div>
<p className="mt-2 text-sm text-red-500">
{form.fields.enabled.error?.join(', ')}
{form.fields.enabled.error?.validationMessage}
</p>
</div>

Expand All @@ -103,7 +101,7 @@ export default function Example() {
/>
</div>
<p className="mt-2 text-sm text-red-500">
{form.fields.color.error?.join(', ')}
{form.fields.color.error?.validationMessage}
</p>
</div>
</div>
Expand Down Expand Up @@ -144,7 +142,7 @@ function classNames(...classes: Array<string | boolean>): string {
return classes.filter(Boolean).join(' ');
}

function ExampleListBox(config: FieldProps<string>) {
function ExampleListBox(config: FieldProps<string, Error>) {
const field = useField(config);
const control = useInputControl(field);

Expand Down Expand Up @@ -206,7 +204,7 @@ function ExampleListBox(config: FieldProps<string>) {
);
}

function ExampleCombobox(config: FieldProps<string>) {
function ExampleCombobox(config: FieldProps<string, Error>) {
const [query, setQuery] = useState('');
const field = useField(config);
const control = useInputControl(field);
Expand Down Expand Up @@ -285,7 +283,7 @@ function ExampleCombobox(config: FieldProps<string>) {
);
}

function ExampleSwitch(config: FieldProps<boolean>) {
function ExampleSwitch(config: FieldProps<boolean, Error>) {
const field = useField(config);
const control = useInputControl(field, {
initialize(value) {
Expand Down Expand Up @@ -315,7 +313,7 @@ function ExampleSwitch(config: FieldProps<boolean>) {
);
}

function ExampleRadioGroup(config: FieldProps<string>) {
function ExampleRadioGroup(config: FieldProps<string, Error>) {
const field = useField(config);
const control = useInputControl(field);
const colors = [
Expand Down
40 changes: 16 additions & 24 deletions examples/material-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,8 @@ import {
Switch,
} from '@mui/material';

interface Schema {
email: string;
description: string;
language: string;
movie: string;
subscribe: boolean;
enabled: boolean;
active: boolean;
score: number;
progress: number;
}

export default function ExampleForm() {
const form = useForm<Schema>({
const form = useForm({
shouldValidate: 'onBlur',
shouldRevalidate: 'onInput',
onValidate(context) {
Expand Down Expand Up @@ -69,15 +57,15 @@ export default function ExampleForm() {
type="email"
name="email"
error={!form.fields.email.valid}
helperText={form.fields.email.error?.join(', ')}
helperText={form.fields.email.error?.validationMessage}
required
/>

<TextField
label="Description (TextField - multline)"
name={form.fields.description.name}
error={!form.fields.description.valid}
helperText={form.fields.description.error?.join(', ')}
helperText={form.fields.description.error?.validationMessage}
inputProps={{
minLength: 10,
}}
Expand Down Expand Up @@ -115,7 +103,7 @@ export default function ExampleForm() {
/>
</FormGroup>
<FormHelperText>
{form.fields.subscribe.error?.join(', ')}
{form.fields.subscribe.error?.validationMessage}
</FormHelperText>
</FormControl>

Expand All @@ -138,13 +126,13 @@ export default function ExampleForm() {
/>
</RadioGroup>
<FormHelperText>
{form.fields.active.error?.join(', ')}
{form.fields.active.error?.validationMessage}
</FormHelperText>
</FormControl>

<FormControl
variant="standard"
error={Boolean(form.fields.enabled.error?.join(', '))}
error={Boolean(form.fields.enabled.error?.validationMessage)}
required
>
<FormLabel>Enabled (Switch)</FormLabel>
Expand All @@ -155,7 +143,7 @@ export default function ExampleForm() {
/>
</FormGroup>
<FormHelperText>
{form.fields.enabled.error?.join(', ')}
{form.fields.enabled.error?.validationMessage}
</FormHelperText>
</FormControl>

Expand Down Expand Up @@ -188,7 +176,11 @@ export default function ExampleForm() {
);
}

interface Field<Schema> extends FieldProps<Schema> {
interface Field<Schema>
extends FieldProps<
Schema,
{ validity: ValidityState; validationMessage: string }
> {
label: string;
required?: boolean;
}
Expand All @@ -208,7 +200,7 @@ function ExampleSelect({ label, required, formId, name }: Field<string>) {
onChange={(event) => control.change(event.target.value)}
onBlur={control.blur}
error={!field.valid}
helperText={field.error?.join(', ')}
helperText={field.error?.validationMessage}
select
required={required}
>
Expand Down Expand Up @@ -241,7 +233,7 @@ function ExampleAutocomplete({ label, name, formId, required }: Field<string>) {
label={label}
name={field.name}
error={!field.valid}
helperText={field.error?.join(', ')}
helperText={field.error?.validationMessage}
required={required}
/>
)}
Expand Down Expand Up @@ -270,7 +262,7 @@ function ExampleRating({ label, name, formId, required }: Field<number>) {
}}
onBlur={control.blur}
/>
<FormHelperText>{field.error?.join(', ')}</FormHelperText>
<FormHelperText>{field.error?.validationMessage}</FormHelperText>
</FormControl>
);
}
Expand Down Expand Up @@ -300,7 +292,7 @@ function ExampleSlider({ label, name, formId, required }: Field<number>) {
control.change(value);
}}
/>
<FormHelperText>{field.error?.join(', ')}</FormHelperText>
<FormHelperText>{field.error?.validationMessage}</FormHelperText>
</FormControl>
);
}
Loading

0 comments on commit 21a9008

Please sign in to comment.