Invite a teammate
Submit it empty to see every error, or with an email on example.org to see a refusal.
import { useState } from 'react';
import type { Key } from 'react-aria-components';
import { SelectItem } from '@arbol-ai/ui';
import { useAppForm } from '@arbol-ai/ui/form';
interface Invitation {
email: string;
role: Key | null;
notify: boolean;
}
const NO_INVITATION: Invitation = { email: '', role: null, notify: true };
const InviteForm = () => {
const [sentTo, setSentTo] = useState('');
const form = useAppForm({
defaultValues: NO_INVITATION,
onSubmit: ({ value }) => {
setSentTo(value.email);
},
validators: {
onSubmit: ({ value }) =>
value.email.endsWith('@example.org') ? 'Invitations to example.org are turned off.' : undefined,
},
});
return (
<form.AppForm>
<form.Form aria-label="Invite a teammate" className="max-w-sm">
<form.AppField
name="email"
validators={{
onBlur: ({ value }) =>
/^\S+@\S+\.\S+$/u.test(value) ? undefined : 'Enter an email like ana@example.com.',
}}
>
{(field) => (
<field.TextField description="We send the invitation there." label="Email" type="email" />
)}
</form.AppField>
<form.AppField
name="role"
validators={{ onSubmit: ({ value }) => (value === null ? 'Choose a role.' : undefined) }}
>
{(field) => (
<field.Select label="Role">
<SelectItem id="front-desk">Front desk</SelectItem>
<SelectItem id="doctor">Doctor</SelectItem>
<SelectItem id="admin">Administrator</SelectItem>
</field.Select>
)}
</form.AppField>
<form.AppField name="notify">
{(field) => (
<field.Switch description="By email, once a day.">Notify about new conversations</field.Switch>
)}
</form.AppField>
<form.FormError />
<form.SubmitButton className="self-start">Send invitation</form.SubmitButton>
<output className="text-muted-foreground text-sm">
{sentTo === '' ? null : `Invitation sent to ${sentTo}.`}
</output>
</form.Form>
</form.AppForm>
);
};
<InviteForm />Source
The examples above are src/form/app-form.examples.tsx, which the library’s tests render too.