react-hook-form#useForm TypeScript Examples

The following examples show how to use react-hook-form#useForm. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: test_utils.tsx    From firebase-tools-ui with Apache License 2.0 7 votes vote down vote up
wrapWithForm = <P, T, F = UseFormProps<T>>(
  Control: React.FC<React.PropsWithChildren<UseFormReturn<T> & P>>,
  options: F,
  props: P
) => {
  const submit = jest.fn();
  const FormWrapper = () => {
    const form = useForm<T>(options);

    return (
      // Ripples cause "not wrapped in act()" warning.
      <RMWCProvider ripple={false}>
        <form data-testid="form" onSubmit={form.handleSubmit(submit)}>
          <Control {...form} {...props} />
        </form>
      </RMWCProvider>
    );
  };

  const methods = render(<FormWrapper />);

  const triggerValidation = async () => {
    await act(async () => {
      fireEvent.submit(methods.getByTestId('form'));
    });
  };

  return { ...methods, triggerValidation, submit };
}
Example #2
Source File: index.tsx    From Tiquet with MIT License 6 votes vote down vote up
AuthForm = ({ onSubmit, btnText }: IPropsForm): JSX.Element => {
  const [recaptchaStatus, setRecaptchaStatus] = useState(false);
  const { handleSubmit, register, errors } = useForm();

  return (
    <form onSubmit={handleSubmit((e) => {
      if (recaptchaStatus || !RECAPTCHA_AVAILABLE) {
        onSubmit(e)
      }
    })}>
      <div className="auth__modal-form-node">
        <input
          type="text"
          name="username"
          ref={register({ required: "Required" })}
          placeholder="Username" />
      </div>
      <div className="auth__modal-form-node">
        <input
          type="password"
          name="password"
          ref={register({ required: "Required" })}
          placeholder="Password" />
      </div>
      {RECAPTCHA_AVAILABLE &&
        <ReCAPTCHA
          sitekey={RECAPTCHA_SITE_KEY}
          onChange={() => setRecaptchaStatus(true)}
          onExpired={() => setRecaptchaStatus(false)}
        />
      }
      <div className="auth__modal-form-node">
        <button type="submit" className="btn btn--block">{btnText}</button>
      </div>
    </form>
  );
}
Example #3
Source File: MultiStepForm.tsx    From frontend with GNU General Public License v3.0 6 votes vote down vote up
MultiStepForm = ({
  children,
  title,
  onNext,
  onBack,
  onSubmit,
  onCancel,
  ...props
}: IMultiStepForm): JSX.Element => {
  const methods = useForm();

  const handleCancel = () => {
    onCancel();
    methods.reset();
  };

  return (
    <div style={{ padding: '65px' }} {...props}>
      <FormProvider {...methods}>
        <MultiStepFormBody
          title={title}
          onNext={onNext}
          onBack={onBack}
          onSubmit={onSubmit}
          onCancel={handleCancel}
        >
          {children}
        </MultiStepFormBody>
      </FormProvider>
    </div>
  );
}
Example #4
Source File: index.tsx    From taskcafe with MIT License 6 votes vote down vote up
CreateChecklistPopup: React.FC<CreateChecklistPopupProps> = ({ onCreateChecklist }) => {
  const { register, handleSubmit } = useForm<CreateChecklistData>();
  const createUser = (data: CreateChecklistData) => {
    onCreateChecklist(data);
  };
  return (
    <CreateChecklistForm onSubmit={handleSubmit(createUser)}>
      <CreateChecklistInput
        floatingLabel
        autoFocus
        autoSelect
        defaultValue="Checklist"
        width="100%"
        label="Name"
        variant="alternate"
        {...register('name', { required: 'Checklist name is required' })}
      />
      <CreateChecklistButton type="submit">Create</CreateChecklistButton>
    </CreateChecklistForm>
  );
}
Example #5
Source File: PlaygroundNftExtrinsics.tsx    From atlas with GNU General Public License v3.0 6 votes vote down vote up
Issue: React.FC<FormProps> = ({ videoId, onSuccess, onError }) => {
  const {
    register,
    handleSubmit: createSubmitHandler,
    formState: { errors },
  } = useForm<IssueInputs>()
  const { joystream, proxyCallback } = useJoystream()
  const handleTransaction = useTransaction()
  const { activeMemberId } = useAuthorizedUser()

  const handleSubmit = (data: IssueInputs) => {
    if (!joystream) return
    const metadata: NftIssuanceInputMetadata = {
      royalty: data.royalties ? parseInt(data.royalties) : undefined,
    }

    handleTransaction({
      onError,
      txFactory: async (updateStatus) =>
        (await joystream.extrinsics).issueNft(videoId, activeMemberId, metadata, proxyCallback(updateStatus)),
      onTxSync: async (_) => onSuccess(),
    })
  }

  return (
    <div>
      <form onSubmit={createSubmitHandler(handleSubmit)}>
        <FormField title="Royalties" optional>
          <TextField
            {...register('royalties', { min: 0, max: 100 })}
            error={!!errors.royalties}
            helperText={errors.royalties?.message}
          />
        </FormField>
        <Button type="submit">Issue NFT</Button>
      </form>
    </div>
  )
}
Example #6
Source File: PreparePullRequestForm.tsx    From backstage with Apache License 2.0 6 votes vote down vote up
PreparePullRequestForm = <
  TFieldValues extends Record<string, any>,
>(
  props: PreparePullRequestFormProps<TFieldValues>,
) => {
  const { defaultValues, onSubmit, render } = props;

  const methods = useForm<TFieldValues>({ mode: 'onTouched', defaultValues });
  const { handleSubmit, watch, control, register, formState, setValue } =
    methods;

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSubmit)}>
        {render({ values: watch(), formState, register, control, setValue })}
      </form>
    </FormProvider>
  );
}
Example #7
Source File: FormContainer.tsx    From react-hook-form-mui with MIT License 6 votes vote down vote up
FormContainerCore: FunctionComponent<FormContainerProps> = ({
  defaultValues = {},
  onSuccess = () => {
  },
  FormProps,
  children
}) => {
  const methods = useForm<typeof defaultValues>({
    defaultValues
  })
  const { handleSubmit } = methods

  return (
    <FormProvider {...methods}>
      <form onSubmit={handleSubmit(onSuccess)} noValidate {...FormProps}>
        {children}
      </form>
    </FormProvider>
  )
}
Example #8
Source File: index.tsx    From tobira with Apache License 2.0 6 votes vote down vote up
EditMode: React.FC<EditModeProps> = props => {
    const { realm: realmRef, index } = props;
    const result = useFragment(graphql`
        fragment EditModeRealmData on Realm {
            blocks {
                # Querying only the type and the fragments bugs out Relay type generation
                id
                __typename
                ... on TitleBlock { ...TitleEditModeBlockData }
                ... on TextBlock { ...TextEditModeBlockData }
                ... on SeriesBlock { ...SeriesEditModeBlockData }
                ... on VideoBlock { ...VideoEditModeBlockData }
            }
            ...EditModeFormRealmData
        }
    `, realmRef);
    const block = result.blocks[index];
    const { __typename: type } = block;

    const form = useForm();

    return <EditModeFormContext.Provider value={{ ...props, realm: result }}>
        <FormProvider {...form}>
            {match(type, {
                TitleBlock: () => <EditTitleBlock block={block} />,
                TextBlock: () => <EditTextBlock block={block} />,
                SeriesBlock: () => <EditSeriesBlock block={block} />,
                VideoBlock: () => <EditVideoBlock block={block} />,
            }, () => bug("unknown block type"))}
        </FormProvider>
    </EditModeFormContext.Provider>;
}
Example #9
Source File: CreditCardForm.test.tsx    From rn-credit-card with MIT License 6 votes vote down vote up
Wrapper = () => {
  const formMethods = useForm({
    mode: 'onBlur',
    defaultValues: {
      holderName: '',
      cardNumber: '',
      expiration: '',
      cvv: '',
    },
  })
  const { handleSubmit } = formMethods

  const onSubmit = (model: FormModel) => {
    get.onSubmit(model)
  }

  return (
    <FormProvider {...formMethods}>
      <CreditCardForm />
      <Button onPress={handleSubmit(onSubmit)} title={'Submit'} />
    </FormProvider>
  )
}
Example #10
Source File: FormSection.tsx    From next-saas-starter with MIT License 5 votes vote down vote up
export default function FormSection() {
  const [hasSuccessfullySentMail, setHasSuccessfullySentMail] = useState(false);
  const [hasErrored, setHasErrored] = useState(false);
  const { register, handleSubmit, formState } = useForm();
  const { isSubmitSuccessful, isSubmitting, isSubmitted, errors } = formState;

  async function onSubmit(payload: EmailPayload) {
    try {
      const res = await fetch('/api/sendEmail', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ subject: 'Email from contact form', ...payload }),
      });

      if (res.status !== 204) {
        setHasErrored(true);
      }
    } catch {
      setHasErrored(true);
      return;
    }

    setHasSuccessfullySentMail(true);
  }

  const isSent = isSubmitSuccessful && isSubmitted;
  const isDisabled = isSubmitting || isSent;
  const isSubmitDisabled = Object.keys(errors).length > 0 || isDisabled;

  if (hasSuccessfullySentMail) {
    return <MailSentState />;
  }

  return (
    <Wrapper>
      <Form onSubmit={handleSubmit(onSubmit)}>
        {hasErrored && <ErrorMessage>Couldn&apos;t send email. Please try again.</ErrorMessage>}
        <InputGroup>
          <InputStack>
            {errors.name && <ErrorMessage>Name is required</ErrorMessage>}
            <Input placeholder="Your Name" id="name" disabled={isDisabled} {...register('name', { required: true })} />
          </InputStack>
          <InputStack>
            {errors.email && <ErrorMessage>Email is required</ErrorMessage>}
            <Input placeholder="Your Email" id="email" disabled={isDisabled} {...register('email', { required: true })} />
          </InputStack>
        </InputGroup>
        <InputStack>
          {errors.description && <ErrorMessage>Description is required</ErrorMessage>}
          <Textarea
            as="textarea"
            placeholder="Enter Your Message..."
            id="description"
            disabled={isDisabled}
            {...register('description', { required: true })}
          />
        </InputStack>
        <Button as="button" type="submit" disabled={isSubmitDisabled}>
          Send Message
        </Button>
      </Form>
    </Wrapper>
  );
}
Example #11
Source File: index.tsx    From Tiquet with MIT License 5 votes vote down vote up
CreateBoardModal = ({
  onCreationSuccess,
  onCreationFailure,
  closeModal,
  isOpen
}: CreateBoardModalProps): JSX.Element => {
  const { handleSubmit, register, errors } = useForm();
  const [isLoading, setIsLoading] = useState(false);

  const onSubmit = ({ boardName }: CreateBoardModalForm): void => {
    const boardService = new BoardsServices();
    setIsLoading(true);

    boardService.createBoard(boardName)
      .then(({ data }) => {
        setIsLoading(false);
        trackEvent({
          category: 'Boards',
          action: 'Board created',
        });
        cogoToast.success(`${boardName} has been created ?`, { position: 'bottom-right' });
        onCreationSuccess(data);
      })
      .catch((e) => {
        trackEvent({
          category: 'Boards',
          action: 'Failed to create board',
        });
        cogoToast.error('Whoops, something happened.', { position: 'bottom-right' });
        onCreationFailure(e);
      })
  }

  return (
    <Modal
      isOpen={isOpen}
      style={customStyles}
      onRequestClose={closeModal}
    >
      <Loading display={isLoading} />
      <div className="create-board-modal">
        <div className="create-board-modal__header">
          <h6 className="create-board-modal__header-title">Create a new board</h6>
          <i
            onClick={() => closeModal()}
            className="fas fa-times create-board-modal__header-close"
          >
          </i>
        </div>
        <hr />
        <form onSubmit={handleSubmit(onSubmit)}>
          <div className="form-group">
            <input
              name="boardName"
              className="form-control"
              disabled={isLoading}
              ref={register({ required: "Required" })}
              placeholder="How should it be named?" />
            <button disabled={isLoading} className="btn btn--block">Submit</button>
          </div>
        </form>
      </div>
    </Modal>
  );
}
Example #12
Source File: Form.tsx    From react-hook-form-generator with MIT License 5 votes vote down vote up
Form: FC<FormProps> = ({
  title,
  schema,
  handleSubmit,
  formOptions,
  overwriteDefaultStyles,
  buttons,
  styles = {},
}) => {
  const form = useForm(formOptions);

  const baseStyles = useMemo(() => {
    return overwriteDefaultStyles ? styles : merge(defaultStyles, styles);
  }, [styles, overwriteDefaultStyles]);

  return (
    <StyleCtx.Provider value={baseStyles}>
      <FormProvider {...form}>
        <Box
          as="form"
          onSubmit={form.handleSubmit(handleSubmit)}
          {...baseStyles.form?.container}
        >
          {!!title && <Heading {...baseStyles.form?.title}>{title}</Heading>}
          <Stack spacing={baseStyles.form?.fieldSpacing}>
            {Object.entries(schema).map(renderField)}
          </Stack>
          <ButtonGroup {...baseStyles.form?.buttonGroup}>
            {buttons?.reset?.hidden ? null : (
              <Button type="reset" {...baseStyles.form?.resetButton}>
                {buttons?.reset?.text || 'Reset'}
              </Button>
            )}
            <Button type="submit" {...baseStyles.form?.submitButton}>
              {buttons?.submit?.text || 'Submit'}
            </Button>
          </ButtonGroup>
        </Box>
      </FormProvider>
    </StyleCtx.Provider>
  );
}
Example #13
Source File: index.tsx    From taskcafe with MIT License 5 votes vote down vote up
AddUserPopup: React.FC<AddUserPopupProps> = ({ onAddUser }) => {
  const {
    register,
    handleSubmit,
    formState: { errors },
    setError,
    control,
  } = useForm<CreateUserData>();

  const createUser = (data: CreateUserData) => {
    onAddUser(data, setError);
  };
  return (
    <CreateUserForm onSubmit={handleSubmit(createUser)}>
      <AddUserInput
        width="100%"
        label="Full Name"
        variant="alternate"
        {...register('fullName', { required: 'Full name is required' })}
      />
      {errors.fullName && <InputError>{errors.fullName.message}</InputError>}
      <AddUserInput
        floatingLabel
        width="100%"
        label="Email"
        variant="alternate"
        {...register('email', { required: 'Email is required' })}
      />
      {errors.email && <InputError>{errors.email.message}</InputError>}
      <Controller
        control={control}
        name="roleCode"
        rules={{ required: 'Role is required' }}
        render={({ field }) => (
          <Select
            {...field}
            label="Role"
            options={[
              { label: 'Admin', value: 'admin' },
              { label: 'Member', value: 'member' },
            ]}
          />
        )}
      />
      {errors.roleCode && errors.roleCode.value && <InputError>{errors.roleCode.value.message}</InputError>}
      <AddUserInput
        floatingLabel
        width="100%"
        label="Username"
        variant="alternate"
        {...register('username', { required: 'Username is required' })}
      />
      {errors.username && <InputError>{errors.username.message}</InputError>}
      <AddUserInput
        floatingLabel
        width="100%"
        label="Initials"
        variant="alternate"
        {...register('initials', { required: 'Initials is required' })}
      />
      {errors.initials && <InputError>{errors.initials.message}</InputError>}
      <AddUserInput
        floatingLabel
        width="100%"
        label="Password"
        variant="alternate"
        type="password"
        {...register('password', { required: 'Password is required' })}
      />
      {errors.password && <InputError>{errors.password.message}</InputError>}
      <CreateUserButton type="submit">Create</CreateUserButton>
    </CreateUserForm>
  );
}
Example #14
Source File: useCreateEditMember.tsx    From atlas with GNU General Public License v3.0 5 votes vote down vote up
useCreateEditMemberForm = ({ prevHandle }: UseCreateEditMemberFormArgs) => {
  const client = useApolloClient()

  const debouncedAvatarValidation = useRef(debouncePromise(imageUrlValidation, 500))
  const debouncedHandleUniqueValidation = useRef(
    debouncePromise(async (value: string, prevValue?: string) => {
      if (value === prevValue) {
        return true
      }
      const {
        data: { membershipByUniqueInput },
      } = await client.query<GetMembershipQuery, GetMembershipQueryVariables>({
        query: GetMembershipDocument,
        variables: { where: { handle: value } },
      })
      return !membershipByUniqueInput
    }, 500)
  )

  const schema = z.object({
    handle: z
      .string()
      .nonempty({ message: 'Member handle cannot be empty' })
      .min(5, {
        message: 'Member handle must be at least 5 characters',
      })
      .max(40, {
        message: `Member handle cannot be longer than 40 characters`,
      })
      .refine((val) => (val ? MEMBERSHIP_NAME_PATTERN.test(val) : true), {
        message: 'Member handle may contain only lowercase letters, numbers and underscores',
      })
      .refine((val) => debouncedHandleUniqueValidation.current(val, prevHandle), {
        message: 'Member handle already in use',
      }),
    avatar: z
      .string()
      .max(400)
      .refine((val) => (val ? URL_PATTERN.test(val) : true), { message: 'Avatar URL must be a valid url' })
      .refine(
        (val) => {
          if (!val) return true
          return debouncedAvatarValidation.current(val)
        },
        { message: 'Image not found' }
      )
      .nullable(),
    about: z.string().max(1000, { message: 'About cannot be longer than 1000 characters' }).nullable(),
  })

  const {
    register,
    handleSubmit,
    setFocus,
    getValues,
    reset,
    watch,
    formState: { errors, isDirty, isValid, dirtyFields, isValidating },
  } = useForm<Inputs>({
    mode: 'onChange',
    resolver: zodResolver(schema),
    shouldFocusError: true,
  })

  return {
    register,
    handleSubmit,
    getValues,
    reset,
    watch,
    setFocus,
    errors,
    isDirty,
    isValid,
    isValidating,
    dirtyFields,
  }
}
Example #15
Source File: index.tsx    From github-explorer with MIT License 5 votes vote down vote up
export function Dashboard() {
  const {
    errors,
    setError,
    register,
    formState,
    handleSubmit,
  } = useForm({
    mode: "onChange",
    resolver: yupResolver(addRepositorySchema),
  });

  const { repositories, addRepository, isLoading } = useRepositories();

  const [t] = useTranslation();

  const onSubmit: SubmitHandler<RepositoryFormValues> = async (
    data,
  ) => {
    const { repositoryName } = data;

    try {
      await addRepository(repositoryName);
    } catch (error) {
      setError("repositoryName", {
        type: "manual",
        message: error.message,
      });
    }
  };

  const { isDirty, isValid } = formState;
  const { repositoryName: repositoryNameError } = errors;

  const isButtonDisabled = isLoading || !isValid || !isDirty;
  const hasError = Boolean(repositoryNameError?.message) && !isValid && isDirty;

  return (
    <Layout>
      <Title>{t("dashboard.title")}</Title>

      <Form onSubmit={handleSubmit(onSubmit)}>
        <Input
          id="repositoryName"
          ref={register}
          type="text"
          name="repositoryName"
          hasError={hasError}
          aria-label="Repository Name"
          placeholder={t("dashboard.repository_name_placeholder")}
        />

        <Button
          type="submit"
          isLoading={isLoading}
          disabled={isButtonDisabled}
        >
          {t("buttons.search")}
        </Button>
      </Form>

      {repositoryNameError && (
        <AddRepositoryInputError>
          {repositoryNameError.message}
        </AddRepositoryInputError>
      )}

      <RepositoriesList>
        {repositories.map(repository => (
          <li key={repository.full_name}>
            <Repository repository={repository} />
          </li>
        ))}
      </RepositoriesList>
    </Layout>
  );
}
Example #16
Source File: feedback-form.tsx    From tams-club-cal with MIT License 5 votes vote down vote up
FeedbackForm = () => {
    const [backdrop, setBackdrop] = useState(false);
    const [popupEvent, setPopupEvent] = useState<PopupEvent>(null);
    const { register, control, handleSubmit, setValue, setError } = useForm();

    const onSubmit = async (data) => {
        // Make sure feedback isn't just spaces lol
        if (data.feedback.trim().length === 0) {
            setError('feedback', { message: 'Feedback is empty' });
            return;
        }

        // Start the upload process
        setBackdrop(true);

        // Create feedback object and send POST request to server
        const name = data.name ? data.name.trim() : '';
        const feedback = { id: null, feedback: data.feedback.trim(), name, time: new Date().valueOf() } as Feedback;
        const res = await postFeedback(feedback);

        // Finished uploading
        setBackdrop(false);

        // Check if feedback was successfully sent and send message to user
        if (res.status == 204) {
            setValue('feedback', '');
            setValue('name', '');
            setPopupEvent({ severity: 2, message: 'Feedback successfully submitted!', time: new Date().valueOf() });
        } else setPopupEvent({ severity: 4, message: 'Error submitting feedback', time: new Date().valueOf() });
    };

    return (
        <React.Fragment>
            <UploadBackdrop open={backdrop} />
            <Popup event={popupEvent} />
            <FormWrapper onSubmit={handleSubmit(onSubmit)}>
                <ControlledTextField
                    control={control}
                    setValue={setValue}
                    value=""
                    name="feedback"
                    label="Feedback"
                    errorMessage="Please enter a valid feedback before submitting"
                    area
                    required
                    variant="outlined"
                />
                <Box sx={{ display: 'flex' }}>
                    <ControlledTextField
                        control={control}
                        setValue={setValue}
                        value=""
                        name="name"
                        label="Name"
                        variant="outlined"
                        sx={{ flexGrow: 1 }}
                    />
                    <Button
                        type="submit"
                        variant="outlined"
                        color="primary"
                        size="large"
                        sx={{ height: 48, marginLeft: 4 }}
                    >
                        Submit
                    </Button>
                </Box>
            </FormWrapper>
        </React.Fragment>
    );
}
Example #17
Source File: CreateRoom.tsx    From convoychat with GNU General Public License v3.0 5 votes vote down vote up
CreateRoom: React.FC = () => {
  const { state, dispatch } = useModalContext();
  const { register, handleSubmit, errors: formErrors } = useForm<Inputs>();

  const [createRoom, { loading }] = useCreateRoomMutation({
    refetchQueries: [{ query: ListCurrentUserRoomsDocument }],
  });

  const closeModal = () => {
    dispatch({ type: "CLOSE", modal: "CreateRoom" });
  };

  const onSubmit = async (data: Inputs) => {
    try {
      await createRoom({
        variables: {
          name: data.roomName,
        },
      });
      closeModal();
    } catch (err) {
      console.log(err);
    }
  };

  return (
    <Modal
      isOpen={state.isCreateRoomModalOpen}
      closeTimeoutMS={300}
      onRequestClose={closeModal}
      contentLabel="Create New Room"
      className="ModalContent"
      overlayClassName="ModalOverlay"
    >
      <h2>Create New Room</h2>
      <small className="textcolor--gray">Give it a cool name</small>
      <Spacer gap="xlarge" />

      <form onSubmit={handleSubmit(onSubmit)}>
        <Input
          type="text"
          name="roomName"
          label="Room Name"
          placeholder="Anurag's room"
          icon={FaUsers}
          errors={formErrors}
          inputRef={register({ required: "Room name is required" })}
        />

        <ButtonGroup gap="medium" float="right">
          <Button onClick={closeModal} variant="danger" icon={FaTimes}>
            Cancel
          </Button>
          <Button isLoading={loading} icon={FaUsers}>
            Create room
          </Button>
        </ButtonGroup>
      </form>
    </Modal>
  );
}
Example #18
Source File: CreditCardForm.tsx    From storefront with MIT License 5 votes vote down vote up
CreditCardForm = React.forwardRef<HTMLFormElement, Props>(({ onSubmit }, ref) => {
  const innerRef = useRef<HTMLFormElement>(null);

  const { control, formState, handleSubmit } = useForm<CreditCardFormData>({
    defaultValues: { ccNumber: '', ccExp: '', ccCsc: '' },
  });

  // Override standard form methods, this works for now:
  useImperativeHandle(ref, () => ({
    ...(innerRef.current ?? new HTMLFormElement()),
    checkValidity: () => innerRef.current?.checkValidity() ?? false,
    reportValidity: () => innerRef.current?.reportValidity() ?? false,
    submit: () => {
      handleSubmit(onSubmit)();
    },
  }));

  return (
    <form ref={innerRef} onSubmit={handleSubmit(onSubmit)}>
      <Controller
        control={control}
        name="ccNumber"
        render={({ field }) => (
          <NumberFormat
            fullWidth
            required
            autoComplete="cc-number"
            customInput={TextField}
            error={'ccNumber' in formState.errors}
            format="#### #### #### ####"
            label="Number"
            margin="normal"
            {...field}
          />
        )}
      />
      <Grid container spacing={2}>
        <Grid item xs={6}>
          <Controller
            control={control}
            name="ccExp"
            render={({ field }) => (
              <NumberFormat
                fullWidth
                required
                autoComplete="cc-csc"
                customInput={TextField}
                error={'ccExp' in formState.errors}
                format="## / ##"
                label="Expiry date"
                margin="normal"
                {...field}
              />
            )}
          />
        </Grid>
        <Grid item xs={6}>
          <Controller
            control={control}
            name="ccCsc"
            render={({ field }) => (
              <NumberFormat
                fullWidth
                required
                autoComplete="cc-csc"
                customInput={TextField}
                error={'ccCsc' in formState.errors}
                format="###"
                label="CVC"
                margin="normal"
                {...field}
              />
            )}
          />
        </Grid>
      </Grid>
    </form>
  );
})
Example #19
Source File: customForm.tsx    From playwright-react-typescript-jest-example with MIT License 5 votes vote down vote up
CustomForm = ({ onSubmit }) => {
  const [visible, setVisible] = React.useState(true);
  const { register, errors, handleSubmit } = useForm<formErrors>({
    mode: "onSubmit"
  });

  return (
    <form
      className="grid grid-rows-2 grid-cols-2 gap-2"
      onSubmit={handleSubmit(onSubmit)}
    >
      <div className="row-span-1 col-span-2 flex justify-center static pt-2">
        {errors.username && (
          <p className="absolute inset-x--0 mt-12 font-bold bg-white top-0 row-span-1 col-start-1 col-end-2 object-center text-red-600">
            {errors.username.message}
          </p>
        )}
        <label
          htmlFor="username"
          className="text-center flex-1 flex-grow text-black text-m"
        >
          Username
        </label>
        <input
          className="flex-1 flex-shrink w-1/4 bg-white w-3/12 focus:outline-none focus:shadow-outline border border-gray-300"
          name="username"
          placeholder="please enter a username"
          type="text"
          ref={register({
            required: "a username is required",
            minLength: {
              value: 4,
              message: "minimum length is 4 characters"
            },
            maxLength: {
              value: 16,
              message: "maximum length is 16 characters"
            }
          })}
        />
      </div>
      <div className="row-span-2 col-span-2 flex flex-row justify-center pt-1">
          <button className="text-center bg-white w-1/4 shadow-2xl focus:shadow-outline focus:shadow-none">
          submit
        </button>
      </div>
    </form>
  );
}
Example #20
Source File: customProvider.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
Component: ProviderComponent = ({ onSignInSuccess }) => {
  const classes = useFormStyles();
  const { register, handleSubmit, formState } = useForm<Data>({
    mode: 'onChange',
  });

  const { errors } = formState;

  const handleResult = ({ userId }: Data) => {
    onSignInSuccess(
      UserIdentity.fromLegacy({
        userId,
        profile: {
          email: `${userId}@example.com`,
        },
      }),
    );
  };

  return (
    <GridItem>
      <InfoCard title="Custom User" variant="fullHeight">
        <Typography variant="body1">
          Enter your own User ID and credentials.
          <br />
          This selection will not be stored.
        </Typography>

        <form className={classes.form} onSubmit={handleSubmit(handleResult)}>
          <FormControl>
            <TextField
              {...asInputRef(register('userId', { required: true }))}
              label="User ID"
              margin="normal"
              error={Boolean(errors.userId)}
            />
            {errors.userId && (
              <FormHelperText error>{errors.userId.message}</FormHelperText>
            )}
          </FormControl>
          <FormControl>
            <TextField
              {...asInputRef(
                register('idToken', {
                  required: false,
                  validate: token =>
                    !token ||
                    ID_TOKEN_REGEX.test(token) ||
                    'Token is not a valid OpenID Connect JWT Token',
                }),
              )}
              label="ID Token (optional)"
              margin="normal"
              autoComplete="off"
              error={Boolean(errors.idToken)}
            />
            {errors.idToken && (
              <FormHelperText error>{errors.idToken.message}</FormHelperText>
            )}
          </FormControl>
          <Button
            type="submit"
            color="primary"
            variant="outlined"
            className={classes.button}
            disabled={!formState?.isDirty || !isEmpty(errors)}
          >
            Continue
          </Button>
        </form>
      </InfoCard>
    </GridItem>
  );
}
Example #21
Source File: index.tsx    From ever-wallet-browser-extension with GNU General Public License v3.0 5 votes vote down vote up
export function CheckNewSeedPhrase({ seedWords, onSubmit, onBack }: Props) {
    const intl = useIntl()
    const { register, handleSubmit, formState } = useForm()

    const numbers = React.useMemo(() => generateRandomNumbers(), [seedWords])

    const validateWord = (word: string, position: number) => {
        return seedWords?.[position - 1] === word
    }

    return (
        <div className="accounts-management">
            <header className="accounts-management__header">
                <h2 className="accounts-management__header-title">
                    {intl.formatMessage({ id: 'CHECK_THE_SEED_PHRASE' })}
                </h2>
            </header>

            <div className="accounts-management__wrapper">
                <form
                    id="words"
                    onSubmit={handleSubmit(onSubmit)}
                    className="accounts-management__content-form"
                >
                    {numbers.map((item, idx) => (
                        <CheckSeedInput
                            key={item}
                            number={item}
                            autoFocus={idx === 0}
                            {...register(`word${idx}`, {
                                required: true,
                                validate: (word: string) => validateWord(word, item),
                            })}
                        />
                    ))}
                    {(formState.errors.word0 ||
                        formState.errors.word1 ||
                        formState.errors.word2 ||
                        formState.errors.word3) && (
                        <div className="accounts-management__content-error">
                            {intl.formatMessage({ id: 'ERROR_SEED_DOES_NOT_MATCH' })}
                        </div>
                    )}
                </form>

                <footer className="accounts-management__footer">
                    <div className="accounts-management__footer-button-back">
                        <Button
                            text={intl.formatMessage({ id: 'BACK_BTN_TEXT' })}
                            white
                            onClick={onBack}
                        />
                    </div>
                    <Button
                        text={intl.formatMessage({ id: 'CONFIRM_BTN_TEXT' })}
                        form="words"
                        onClick={handleSubmit(onSubmit)}
                    />
                </footer>
            </div>
        </div>
    )
}
Example #22
Source File: InputNodename.tsx    From raspiblitz-web with MIT License 5 votes vote down vote up
InputNodename: FC<Props> = ({ callback }) => {
  const [inputNodeName, setInputNodeName] = useState("");
  const { t } = useTranslation();

  const changeNodenameHandler = (event: ChangeEvent<HTMLInputElement>) => {
    setInputNodeName(event.target.value);
  };

  const continueHandler = () => {
    callback(inputNodeName);
  };

  const {
    register,
    handleSubmit,
    formState: { errors, isValid },
  } = useForm<IFormInputs>({
    mode: "onChange",
  });

  return (
    <SetupContainer>
      <section className="flex h-full flex-col items-center justify-center p-8">
        <h2 className="text-center text-lg font-bold">
          {t("setup.nodename_input")}
        </h2>
        <form
          onSubmit={handleSubmit(continueHandler)}
          className="flex h-full w-full flex-col py-1 md:w-10/12"
        >
          <article className="m-auto md:w-1/2">
            <InputField
              {...register("inputNodeName", {
                required: t("setup.nodename_error_empty"),
                onChange: changeNodenameHandler,
                pattern: {
                  value: /^[a-zA-Z0-9]*$/,
                  message: t("setup.nodename_err_chars"),
                },
                minLength: {
                  value: 4,
                  message: t("setup.nodename_err_min_length"),
                },
                maxLength: {
                  value: 32,
                  message: t("setup.nodename_err_max_length"),
                },
              })}
              label={t("setup.nodename_name")}
              errorMessage={errors.inputNodeName}
            />
          </article>
          <article className="mt-10 flex flex-col items-center justify-center gap-10 md:flex-row">
            <button
              type="button"
              onClick={() => callback(null)}
              className="flex items-center rounded  bg-red-500 px-2 text-white shadow-xl hover:bg-red-400 disabled:bg-gray-400"
            >
              <X className="inline h-6 w-6" />
              <span className="p-2">{t("setup.cancel")}</span>
            </button>
            <button
              disabled={!isValid}
              type="submit"
              className="bd-button flex items-center px-2 disabled:bg-gray-400"
            >
              <span className="p-2">Continue</span>
              <ArrowRight className="inline h-6 w-6" />
            </button>
          </article>
        </form>
      </section>
    </SetupContainer>
  );
}
Example #23
Source File: DelegationChangeProposalForm.tsx    From homebase-app with MIT License 5 votes vote down vote up
DelegationChangeProposalForm: React.FC<Props> = ({ open, handleClose, defaultValues }) => {
  const daoId = useDAOID();
  const { data: dao } = useDAO(daoId);
  const { data: daoHoldings } = useDAOHoldings(daoId);

  const methods = useForm<Values>({
    defaultValues: useMemo(
      () => ({
        newDelegationAddress: "",
        ...defaultValues,
      }),
      [defaultValues]
    ),
    // resolver: yupResolver(validationSchema as any),
  });

  const newDelegationAddress = methods.watch("newDelegationAddress");

  useEffect(() => {
    methods.reset(defaultValues);
  }, [defaultValues, methods]);

  const { mutate } = useProposeDelegationChange();

  const onSubmit = useCallback(
    (values: Values) => {
      if (dao) {
        mutate({ dao, newDelegationAddress: values.newDelegationAddress });
        handleClose();
      }
    },
    [dao, handleClose, mutate]
  );

  return (
    <FormProvider {...methods}>
      <ResponsiveDialog
        open={open}
        onClose={handleClose}
        aria-labelledby='alert-dialog-title'
        aria-describedby='alert-dialog-description'
        title={"Change Delegate"}>
        <Content container direction={"column"} style={{ gap: 18 }}>
          <Grid item>
            <ProposalFormInput label={"New Delegate Address"}>
              <Controller
                control={methods.control}
                name={`newDelegationAddress`}
                render={({ field }) => (
                  <TextField
                    {...field}
                    type='text'
                    placeholder=' tz1...'
                    InputProps={{ disableUnderline: true }}
                  />
                )}
              />
            </ProposalFormInput>
          </Grid>

          <Grid item>
            <Typography align='left' variant='subtitle2' color='textPrimary' display={"inline"}>
              Proposal Fee:{" "}
            </Typography>
            <Typography align='left' variant='subtitle2' color='secondary' display={"inline"}>
              {dao && dao.data.extra.frozen_extra_value.toString()} {dao ? dao.data.token.symbol : ""}
            </Typography>
          </Grid>

          <SendButton
            onClick={methods.handleSubmit(onSubmit as any)}
            disabled={!dao || !daoHoldings || !newDelegationAddress}>
            Submit
          </SendButton>
        </Content>
      </ResponsiveDialog>
    </FormProvider>
  );
}
Example #24
Source File: Upload.tsx    From tobira with Apache License 2.0 5 votes vote down vote up
MetaDataEdit: React.FC<MetaDataEditProps> = ({ onSave, disabled }) => {
    const { t } = useTranslation();

    const { register, handleSubmit, formState: { errors } } = useForm<Metadata>({
        mode: "onChange",
    });

    const onSubmit = handleSubmit(data => onSave(data));

    // TODO: it might be too easy to accidentally submit the form with enter
    return (
        <Form noValidate onSubmit={onSubmit} css={{ margin: "32px 2px" }}>
            {/* Title */}
            <InputContainer>
                <TitleLabel htmlFor="title-field" />
                <Input
                    id="title-field"
                    required
                    error={!!errors.title}
                    css={{ width: 400, maxWidth: "100%" }}
                    autoFocus
                    {...register("title", {
                        required: t("upload.errors.field-required") as string,
                    })}
                />
                {boxError(errors.title?.message)}
            </InputContainer>

            {/* Description */}
            <InputContainer>
                <label htmlFor="description-field">{t("upload.metadata.description")}</label>
                <TextArea id="description-field" {...register("description")} />
            </InputContainer>

            {/* Submit button */}
            <Button kind="happy" type="submit" disabled={disabled}>
                {t("upload.metadata.save")}
            </Button>
        </Form>
    );
}
Example #25
Source File: BasicExample.tsx    From react-native-paper-form-builder with MIT License 5 votes vote down vote up
function BasicExample() {
  const {control, setFocus, handleSubmit} = useForm({
    defaultValues: {
      email: '',
      password: '',
    },
    mode: 'onChange',
  });

  return (
    <View style={styles.containerStyle}>
      <ScrollView contentContainerStyle={styles.scrollViewStyle}>
        <Text style={styles.headingStyle}>Form Builder Basic Demo</Text>
        <FormBuilder
          control={control}
          setFocus={setFocus}
          formConfigArray={[
            {
              type: 'email',
              name: 'email',

              rules: {
                required: {
                  value: true,
                  message: 'Email is required',
                },
              },
              textInputProps: {
                label: 'Email',
              },
            },
            {
              type: 'password',
              name: 'password',
              rules: {
                required: {
                  value: true,
                  message: 'Password is required',
                },
              },
              textInputProps: {
                label: 'Password',
              },
            },
          ]}
        />
        <Button
          mode={'contained'}
          onPress={handleSubmit((data: any) => {
            console.log('form data', data);
          })}>
          Submit
        </Button>
      </ScrollView>
    </View>
  );
}
Example #26
Source File: GeoPointEditor.test.tsx    From firebase-tools-ui with Apache License 2.0 5 votes vote down vote up
TestForm: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
  const methods = useForm({ mode: 'all' });
  return <FormProvider {...methods}>{children}</FormProvider>;
}
Example #27
Source File: App.tsx    From rn-credit-card with MIT License 5 votes vote down vote up
App: React.FC = () => {
  let [fontsLoaded] = useFonts({
    RobotoMono_400Regular,
    RobotoMono_700Bold,
  })
  const formMethods = useForm<FormModel>({
    // to trigger the validation on the blur event
    mode: 'onBlur',
    defaultValues: {
      holderName: '',
      cardNumber: '',
      expiration: '',
      cvv: '',
    },
  })
  const { handleSubmit, formState } = formMethods

  function onSubmit(model: FormModel) {
    Alert.alert('Success: ' + JSON.stringify(model, null, 2))
  }

  if (!fontsLoaded) {
    return <AppLoading />
  }

  return (
    <FormProvider {...formMethods}>
      <SafeAreaView style={styles.container}>
        <KeyboardAvoidingView
          style={styles.avoider}
          behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
        >
          <CreditCardForm
            LottieView={LottieView}
            horizontalStart
            overrides={{
              labelText: {
                marginTop: 16,
              },
            }}
          />
        </KeyboardAvoidingView>
        {formState.isValid && (
          <Button
            style={styles.button}
            title={'CONFIRM PAYMENT'}
            onPress={handleSubmit(onSubmit)}
          />
        )}
      </SafeAreaView>
    </FormProvider>
  )
}
Example #28
Source File: Rooms.tsx    From dh-web with GNU General Public License v3.0 5 votes vote down vote up
RoomCreationForm: FC = () => {
    const [expanded, setExpanded] = useState(false);
    const toggleExpanded = () => setExpanded(!expanded);
    const router = useRouter();

    const { register, handleSubmit, formState: { errors } } = useForm<RoomCreationFormValidationVals>({
        resolver: yupResolver(roomCreationFormValidationSchema)
    });

    const [createNewRoom, { loading, error }] = useMutation<CreateNewRoomMutation, CreateNewRoomMutationVariables>(CREATE_NEW_ROOM_MUTATION);

    const onSubmit = handleSubmit(async (data) => {
        setExpanded(false);
        const f = await createNewRoom({ variables: { name: data.name, description: data.description } });
        router.push("/room/" + f.data.createRoom.id);
    });

    if (loading) {
        return (<p>...Loading</p>);
    } else if (error) {
        return (<p>...Mutation Failed</p>);
    }

    const RoomForm = () => {
        return (
            <FormWrapper>
                <FormHeader>
                    <Row>
                        <div>
                            <Title>New room</Title>
                            <SubTitle>Fill the following fields to start a new room</SubTitle>
                        </div>
                        <CloseButton onClick={toggleExpanded} > X </CloseButton>
                    </Row>
                </FormHeader>
                <form onSubmit={handleSubmit(onSubmit)}>
                    <Input placeholder="Room Name" {...register("name")} />
                    <p>{errors.name?.message}</p>
                    <TextArea placeholder="Room Description" {...register("description")} />
                    <p>{errors.description?.message}</p>
                    <Input type="Submit" />
                </form>
            </FormWrapper>
        );
    };

    return (
        <RoomCreationWrapper>
            <Button variant="ACCENT" onClick={toggleExpanded}>New room</Button>
            {expanded && (<Modal>
                <RoomCreationMenuItem>
                    <RoomForm />
                </RoomCreationMenuItem>
            </Modal>)}
        </RoomCreationWrapper>
    );
}
Example #29
Source File: index.tsx    From admin with MIT License 5 votes vote down vote up
LoginCard: React.FC<LoginCardProps> = ({ toResetPassword }) => {
  const [isInvalidLogin, setIsInvalidLogin] = useState(false)
  const { register, handleSubmit, reset } = useForm<FormValues>()
  const login = useAdminLogin()

  const onSubmit = (values: FormValues) => {
    login.mutate(values, {
      onSuccess: () => {
        navigate("/a/orders")
      },
      onError: () => {
        setIsInvalidLogin(true)
        reset()
      },
    })
  }
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div className="flex flex-col items-center">
        <span className="inter-2xlarge-semibold mt-4 text-grey-90">
          Welcome back!
        </span>
        <span className="inter-base-regular text-grey-50 mt-2">
          It's great to see you ??
        </span>
        <span className="inter-base-regular text-grey-50 mb-xlarge">
          Log in to your account below
        </span>
        <SigninInput
          placeholder="Email..."
          name="email"
          ref={register({ required: true })}
          autoComplete="email"
        />
        <SigninInput
          placeholder="Password..."
          type={"password"}
          name="password"
          ref={register({ required: true })}
          autoComplete="current-password"
        />
        {isInvalidLogin && (
          <span className="text-rose-50 w-full mt-2 inter-small-regular">
            These credentials do not match our records
          </span>
        )}
        <Button
          className="rounded-rounded mt-4 w-[320px] inter-base-regular"
          variant="primary"
          size="large"
          type="submit"
          loading={login.isLoading}
        >
          Continue
        </Button>
        <span
          className="inter-small-regular text-grey-50 mt-8 cursor-pointer"
          onClick={toResetPassword}
        >
          Reset password
        </span>
      </div>
    </form>
  )
}