formik#Formik TypeScript Examples

The following examples show how to use formik#Formik. 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 abacus with GNU General Public License v2.0 7 votes vote down vote up
MockFormik = ({
  children,
  initialValues = {},
}: {
  children: React.ReactNode
  initialValues?: FormikValues
}) => {
  return (
    <Formik initialValues={initialValues} onSubmit={() => undefined}>
      {children}
    </Formik>
  )
}
Example #2
Source File: login.component.tsx    From master-frontend-lemoncode with MIT License 6 votes vote down vote up
LoginComponent: React.FunctionComponent<Props> = props => {
  const { onLogin } = props;

  return (
    <Card>
      <CardHeader title="Login" />
      <CardContent>
        <Formik
          onSubmit={onLogin}
          initialValues={createEmptyLogin()}
          validate={formValidation.validateForm}
        >
          {() => (
            <Form>
              <div
                style={{
                  display: 'flex',
                  flexDirection: 'column',
                  justifyContent: 'center',
                }}
              >
                <TextFieldComponent name="user" label="Name" />
                <TextFieldComponent
                  name="password"
                  label="Password"
                  type="password"
                />
                <Button type="submit" variant="contained" color="primary">
                  Login
                </Button>
              </div>
            </Form>
          )}
        </Formik>
      </CardContent>
    </Card>
  );
}
Example #3
Source File: CommentForm.tsx    From End-to-End-Web-Testing-with-Cypress with MIT License 6 votes vote down vote up
CommentForm: React.FC<CommentFormProps> = ({ transactionId, transactionComment }) => {
  const classes = useStyles();
  const initialValues = { content: "" };

  return (
    <div>
      <Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={(values, { setSubmitting }) => {
          setSubmitting(true);
          transactionComment({ transactionId, ...values });
        }}
      >
        {() => (
          <Form className={classes.form}>
            <Field name="content">
              {({ field, meta }: FieldProps) => (
                <TextField
                  variant="outlined"
                  margin="dense"
                  fullWidth
                  id={`transaction-comment-input-${transactionId}`}
                  type="text"
                  placeholder="Write a comment..."
                  inputProps={{ "data-test": `transaction-comment-input-${transactionId}` }}
                  error={meta.touched && Boolean(meta.error)}
                  helperText={meta.touched ? meta.error : ""}
                  {...field}
                />
              )}
            </Field>
          </Form>
        )}
      </Formik>
    </div>
  );
}
Example #4
Source File: ParametersForm.stories.tsx    From panvala with Apache License 2.0 6 votes vote down vote up
storiesOf('ParametersForm', module).add('ParametersForm', () => (
  <StoryWrapper>
    <Box width="620px">
      <Formik initialValues={parameters} onSubmit={noop}>
        {() => (
          <Form>
            <ParametersForm
              onChange={(name: string, value: any) => {
                console.log('name, value:', name, value);
              }}
              parameters={parameters}
            />
          </Form>
        )}
      </Formik>
    </Box>
  </StoryWrapper>
));
Example #5
Source File: SQFormReadOnly.tsx    From SQForm with MIT License 6 votes vote down vote up
function SQFormReadOnly<Values extends FormikValues>({
  readOnlyFields,
  initialValues,
  enableReinitialize = false,
  muiGridProps = {},
}: SQFormReadOnlyProps<Values>): JSX.Element {
  return (
    <Formik<Values>
      initialValues={initialValues}
      onSubmit={noop}
      enableReinitialize={enableReinitialize}
    >
      {(_props) => {
        return (
          <Form>
            <Grid
              {...muiGridProps}
              container
              spacing={muiGridProps.spacing ?? 2}
            >
              {readOnlyFields.map((readOnlyField, index) => {
                const props = {
                  key: readOnlyField?.key ?? index,
                  muiFieldProps: noBottomMarginStyle,
                  ...readOnlyField,
                };

                if (readOnlyField?.mask) {
                  return <SQFormMaskedReadOnlyField {...props} />;
                }
                return <SQFormReadOnlyField {...props} />;
              })}
            </Grid>
          </Form>
        );
      }}
    </Formik>
  );
}
Example #6
Source File: RoleForm.tsx    From amplication with Apache License 2.0 6 votes vote down vote up
RoleForm = ({ onSubmit, defaultValues }: Props) => {
  const initialValues = useMemo(() => {
    const sanitizedDefaultValues = omit(
      defaultValues,
      NON_INPUT_GRAPHQL_PROPERTIES
    );
    return {
      ...INITIAL_VALUES,
      ...sanitizedDefaultValues,
    } as models.AppRole;
  }, [defaultValues]);

  return (
    <Formik
      initialValues={initialValues}
      validate={(values: models.AppRole) => validate(values, FORM_SCHEMA)}
      enableReinitialize
      onSubmit={onSubmit}
    >
      <Form childrenAsBlocks>
        <FormikAutoSave debounceMS={1000} />

        <NameField name="name" />

        <DisplayNameField
          name="displayName"
          label="Display Name"
          minLength={1}
        />

        <TextField name="description" label="Description" textarea rows={3} />
      </Form>
    </Formik>
  );
}
Example #7
Source File: index.tsx    From formik-material-ui with MIT License 6 votes vote down vote up
App: React.FC = () => {
  const handleSubmit = (values: FormValues): void => {
    alert(JSON.stringify(values));
  };

  return (
    <div className="App">
      <h1>Sign Up</h1>
      <Formik
        initialValues={initialValues}
        onSubmit={handleSubmit}
        validationSchema={SignupSchema}
      >
        {({ dirty, isValid }) => {
          return (
            <Form>
              <FormikField name="name" label="Name" required />
              <FormikSelect
                name="position"
                items={positionItems}
                label="Position"
                required
              />

              <Button
                variant="contained"
                color="primary"
                disabled={!dirty || !isValid}
                type="submit"
              >
                Primary
              </Button>
            </Form>
          );
        }}
      </Formik>
    </div>
  );
}
Example #8
Source File: InteractiveOptions.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 6 votes vote down vote up
test('it render interactive options for quick reply template', async () => {
  props.inputFields = quickReplyInputFields;
  props.form.values.templateButtons = quickReplyInputFields;
  props.templateType = templateType[1];

  render(
    <Formik initialValues={{ templateButtons: props.inputFields }} onSubmit={mock}>
      <InteractiveOptions {...props} />
    </Formik>
  );

  const textboxes = screen.getAllByRole('textbox');
  const inputData = ['Excited', 'Very Excited'];
  let count = 0;

  for await (let input of textboxes) {
    expect(input).toBeInTheDocument();
    fireEvent.change(input, { target: { value: inputData[count] } });
    await waitFor(() => {});
    count++;
  }

  const [addButton] = screen.getAllByRole('button');
  expect(addButton).toBeInTheDocument();

  fireEvent.click(addButton);
  await waitFor(() => {});

  const [deleteFirstItem] = screen.getAllByText('Cross.svg');
  expect(deleteFirstItem).toBeInTheDocument();

  fireEvent.click(deleteFirstItem);
  await waitFor(() => {});
});
Example #9
Source File: NewProject.view.tsx    From tezos-link with Apache License 2.0 6 votes vote down vote up
NewProjectView = ({ handleSubmitForm, loading  }: NewPostViewProps) => {
        const [networkValue, setNetwork] = useState('MAINNET')

        return (
        <NewProjectCard>
            <h1>New Project</h1>
            <Formik
                initialValues={{title: '', network: ''}}
                validationSchema={newProjectValidator}
                validateOnBlur={false}
                onSubmit={(values, actions) => handleSubmitForm({ ...values, network: networkValue }, actions)}
            >
                {formikProps => {
                    const {handleSubmit} = formikProps
                    return (
                        <div>
                            <Select
                                options={['MAINNET', 'CARTHAGENET']}
                                defaultOption={networkValue}
                                selectCallback={(e: string) => setNetwork(e)}
                            />
                            <form onSubmit={handleSubmit}>

                                <Field InputType={Input} component={FormInputField} icon="user" name="title"
                                       placeholder="Project title"/>

                                <Button text="Create project" icon="sign-up" type="submit" loading={loading}/>
                            </form>
                        </div>
                    )
                }}
            </Formik>
        </NewProjectCard>
    )
}
Example #10
Source File: address-field.test.tsx    From openmrs-esm-patient-registration with MIT License 6 votes vote down vote up
describe('address field', () => {
  it('renders input fields matching addressTemplate config', async () => {
    const { findByLabelText } = render(
      <ResourcesContext.Provider value={{ addressTemplate: mockResponse } as Resources}>
        <Formik initialValues={{}} onSubmit={null}>
          <Form>
            <AddressField />
          </Form>
        </Formik>
      </ResourcesContext.Provider>,
    );

    const postalCode = await findByLabelText('Location.postalCode');
    const address1 = await findByLabelText('Location.address1');
    const country = await findByLabelText('Location.country');
    const stateProvince = await findByLabelText('Location.stateProvince');
    const cityVillage = await findByLabelText('Location.cityVillage');

    expect(postalCode).toBeInTheDocument();
    expect(address1).toBeInTheDocument();
    expect(country).toBeInTheDocument();
    expect(stateProvince).toBeInTheDocument();
    expect(cityVillage).toBeInTheDocument();
  });
});
Example #11
Source File: Audience.test.tsx    From abacus with GNU General Public License v2.0 5 votes vote down vote up
test('renders as expected', async () => {
  const indexedSegments: Record<number, Segment> = {
    1: { segmentId: 1, name: 'us', type: SegmentType.Country },
    2: { segmentId: 2, name: 'au', type: SegmentType.Country },
    3: { segmentId: 3, name: 'en-US', type: SegmentType.Locale },
    4: { segmentId: 4, name: 'en-AU', type: SegmentType.Locale },
  }

  // Turning on debug mode for the exclusion group tags
  mockedUtilsGeneral.isDebugMode.mockImplementation(() => true)

  const { container } = render(
    <Formik
      initialValues={{ experiment: experimentToFormData({}) }}
      onSubmit={
        /* istanbul ignore next; This is unused */
        () => undefined
      }
    >
      {(formikProps: FormikProps<{ experiment: ExperimentFormData }>) => (
        <Audience {...{ formikProps, indexedSegments, completionBag }} />
      )}
    </Formik>,
  )
  expect(container).toMatchSnapshot()

  const addVariationButton = screen.getByRole('button', { name: /Add variation/i })
  fireEvent.click(addVariationButton)
  const removeVariationButton = screen.getAllByRole('button', { name: /Remove variation/i })
  fireEvent.click(removeVariationButton[0])

  const segmentComboboxInput = screen.getByPlaceholderText(/Search and select to customize/)

  await act(async () => {
    fireEvent.change(segmentComboboxInput, { target: { value: 'AU' } })
  })

  const segmentOption = await screen.findByRole('option', { name: /Locale: en-AU/i })
  await act(async () => {
    fireEvent.click(segmentOption)
  })

  // eslint-disable-next-line @typescript-eslint/require-await
  await act(async () => {
    fireEvent.click(screen.getByLabelText(/Exclude/))
  })

  await changeFieldByRole('textbox', /Exclusion Groups/, 'tag_1')
  await act(async () => {
    fireEvent.click(screen.getByRole('option', { name: /tag_1/ }))
  })

  expect(container).toMatchSnapshot()
})
Example #12
Source File: data.component.tsx    From master-frontend-lemoncode with MIT License 5 votes vote down vote up
DataComponent: React.FunctionComponent<Props> = ({
  employee,
  className,
  onSave,
  isEditMode,
  onCancel,
}) => {
  React.useEffect(() => {
    const newValidationSchema = produce(validationSchema, darft => {
      darft.field.temporalPassword = isEditMode ? [] : [Validators.required];
    });
    formValidation.updateValidationSchema(newValidationSchema);
  }, [isEditMode]);

  return (
    <Formik
      initialValues={employee}
      enableReinitialize={true}
      onSubmit={onSave}
      validate={formValidation.validateForm}
    >
      {() => (
        <Form className={cx(classes.form({ isEditMode }), className)}>
          <TextFieldComponent
            label="Id"
            name="id"
            className={classes.id}
            InputProps={{
              readOnly: true,
            }}
          />
          {!isEditMode && (
            <TextFieldComponent
              label="Clave Temporal"
              name="temporalPassword"
              className={classes.temporalPassword}
            />
          )}
          <TextFieldComponent
            label="Nombre"
            name="name"
            className={classes.name}
          />
          <TextFieldComponent
            label="Email"
            name="email"
            className={classes.email}
          />
          <CheckboxComponent
            name="isActive"
            label="Activo"
            color="primary"
            className={classes.isActive}
          />
          <CommandFooterComponent
            onCancel={onCancel}
            className={classes.commands}
          />
        </Form>
      )}
    </Formik>
  );
}
Example #13
Source File: ChangeEmail.tsx    From abrechnung with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function ChangeEmail() {
    useTitle("Abrechnung - Change E-Mail");

    const handleSubmit = (values, { setSubmitting }) => {
        changeEmail({
            password: values.password,
            newEmail: values.newEmail,
        })
            .then((res) => {
                setSubmitting(false);
                toast.success("Requested email change, you should receive an email with a confirmation link soon");
            })
            .catch((error) => {
                setSubmitting(false);
                toast.error(error);
            });
    };

    return (
        <MobilePaper>
            <Typography component="h3" variant="h5">
                Change E-Mail
            </Typography>
            <Formik initialValues={{ password: "", newEmail: "" }} onSubmit={handleSubmit}>
                {({ values, handleChange, handleBlur, handleSubmit, isSubmitting }) => (
                    <Form>
                        <TextField
                            required
                            fullWidth
                            margin="normal"
                            autoFocus
                            type="password"
                            name="password"
                            variant="standard"
                            value={values.password}
                            onChange={handleChange}
                            onBlur={handleBlur}
                            label="Password"
                        />

                        <TextField
                            required
                            fullWidth
                            margin="normal"
                            type="email"
                            name="newEmail"
                            variant="standard"
                            value={values.newEmail}
                            onChange={handleChange}
                            onBlur={handleBlur}
                            label="New E-Mail"
                        />

                        {isSubmitting && <LinearProgress />}
                        <Button type="submit" color="primary" disabled={isSubmitting}>
                            Save
                        </Button>
                    </Form>
                )}
            </Formik>
        </MobilePaper>
    );
}
Example #14
Source File: SQForm.tsx    From SQForm with MIT License 5 votes vote down vote up
function SQForm<Values extends FormikValues>({
  children,
  enableReinitialize = false,
  initialValues,
  muiGridProps = {},
  onSubmit,
  validationSchema,
}: SQFormProps<Values>): JSX.Element {
  const initialErrors = useInitialRequiredErrors(
    validationSchema,
    initialValues
  );

  // HACK: This is a workaround for: https://github.com/mui-org/material-ui-pickers/issues/2112
  // Remove this reset handler when the issue is fixed.
  const handleReset = () => {
    document &&
      document.activeElement &&
      (document.activeElement as HTMLElement).blur();
  };

  const handleSubmit = useDebouncedCallback(
    (values: Values, formikHelpers: FormikHelpers<Values>) =>
      onSubmit(values, formikHelpers),
    500,
    {leading: true, trailing: false}
  );

  return (
    <Formik<Values>
      enableReinitialize={enableReinitialize}
      initialErrors={initialErrors}
      initialValues={initialValues}
      onSubmit={handleSubmit}
      onReset={handleReset}
      validationSchema={validationSchema}
      validateOnMount={true}
    >
      {(_props) => {
        return (
          <Form>
            <Grid
              {...muiGridProps}
              container
              spacing={muiGridProps.spacing ?? 2}
            >
              {children}
            </Grid>
          </Form>
        );
      }}
    </Formik>
  );
}
Example #15
Source File: CreateAppFromExcelForm.tsx    From amplication with Apache License 2.0 5 votes vote down vote up
CreateAppFromExcelForm = ({
  initialValues,
  fileName,
  loading,
  onSubmit,
  onClearForm,
}: Props) => {
  return (
    <Formik
      initialValues={initialValues}
      enableReinitialize
      onSubmit={onSubmit}
      render={({ values, handleSubmit }) => (
        <Form className={`${CLASS_NAME}__layout__body`}>
          <div className={`${CLASS_NAME}__layout__body__side`}>
            <h2>App Details</h2>
            <h3>{fileName}</h3>
            <DisplayNameField
              name="app.name"
              label="Give your app a descriptive name"
              required
            />
            <Panel className={`${CLASS_NAME}__notice`}>
              <div className={`${CLASS_NAME}__notice__title`}>
                <Icon size="xsmall" icon="info_circle" />
                <span>Good to know</span>
              </div>
              <ul className={`${CLASS_NAME}__layout__body__side__message`}>
                <li>
                  All relations are created as one-to-many by default. You can
                  change that later if needed.
                </li>

                <li>
                  Once your app is ready, you can simply download the generated
                  code or push it directly to a GitHub repository.
                </li>
              </ul>
            </Panel>
            <Button
              buttonStyle={EnumButtonStyle.Primary}
              disabled={loading}
              onClick={handleSubmit}
              type="button"
            >
              Create App
            </Button>
          </div>

          <div className={`${CLASS_NAME}__layout__body__content`}>
            <div className={`${CLASS_NAME}__layout__body__content__toolbar`}>
              <Button
                buttonStyle={EnumButtonStyle.Clear}
                disabled={loading}
                type="button"
                onClick={onClearForm}
                icon="arrow_left"
              >
                Back
              </Button>
            </div>
            <div className={`${CLASS_NAME}__entities`}>
              <EntitiesDiagram />
            </div>
          </div>
        </Form>
      )}
    />
  );
}
Example #16
Source File: index.tsx    From advanced-formik-validations-with-yup with MIT License 5 votes vote down vote up
App: React.FC = () => {
  const handleSubmit = (values: FormValues): void => {
    alert(JSON.stringify(values));
  };

  return (
    <div className="App">
      <h1>Sign Up</h1>
      <Formik
        initialValues={initialValues}
        onSubmit={handleSubmit}
        validationSchema={SignupSchema}
      >
        {({ dirty, isValid }) => {
          return (
            <Form>
              <FormikField name="name" label="Name" required />
              <FormikField name="email" label="Email" required />
              <FormikField
                name="password"
                label="Password"
                required
                type="password"
              />
              <FormikField
                name="passwordConfirm"
                label="Confirm Password"
                required
                type="password"
              />
              <FormikSelect
                name="position"
                items={positionItems}
                label="Position"
                required
              />

              <Button
                variant="contained"
                color="primary"
                disabled={!dirty || !isValid}
                type="submit"
              >
                Primary
              </Button>
            </Form>
          );
        }}
      </Formik>
    </div>
  );
}
Example #17
Source File: [token].tsx    From lireddit with MIT License 5 votes vote down vote up
ChangePassword: NextPage = () => {
  const router = useRouter();
  const [changePassword] = useChangePasswordMutation();
  const [tokenError, setTokenError] = useState("");
  return (
    <Wrapper variant="small">
      <Formik
        initialValues={{ newPassword: "" }}
        onSubmit={async (values, { setErrors }) => {
          const response = await changePassword({
            variables: {
              newPassword: values.newPassword,
              token:
                typeof router.query.token === "string"
                  ? router.query.token
                  : "",
            },
            update: (cache, { data }) => {
              cache.writeQuery<MeQuery>({
                query: MeDocument,
                data: {
                  __typename: "Query",
                  me: data?.changePassword.user,
                },
              });
            },
          });
          if (response.data?.changePassword.errors) {
            const errorMap = toErrorMap(response.data.changePassword.errors);
            if ("token" in errorMap) {
              setTokenError(errorMap.token);
            }
            setErrors(errorMap);
          } else if (response.data?.changePassword.user) {
            // worked
            router.push("/");
          }
        }}
      >
        {({ isSubmitting }) => (
          <Form>
            <InputField
              name="newPassword"
              placeholder="new password"
              label="New Password"
              type="password"
            />
            {tokenError ? (
              <Flex>
                <Box mr={2} style={{ color: "red" }}>
                  {tokenError}
                </Box>
                <NextLink href="/forgot-password">
                  <Link>click here to get a new one</Link>
                </NextLink>
              </Flex>
            ) : null}
            <Button
              mt={4}
              type="submit"
              isLoading={isSubmitting}
              variantColor="teal"
            >
              change password
            </Button>
          </Form>
        )}
      </Formik>
    </Wrapper>
  );
}
Example #18
Source File: EmailLogin.tsx    From vsinder with Apache License 2.0 5 votes vote down vote up
EmailLogin: React.FC<AuthStackNav<"EmailLogin">> = ({
  navigation,
}) => {
  const [mutate, { isLoading }] = useMutation(defaultMutationFn);
  return (
    <ScreenWrapper>
      <KeyboardAwareScrollView keyboardShouldPersistTaps="handled">
        <Formik
          validationSchema={schema}
          validateOnBlur={false}
          validateOnChange={false}
          initialValues={{ email: "", password: "" }}
          onSubmit={async (values) => {
            const tokens = await mutate(["/email/login", values, "POST"]);
            navigation.navigate("tokens", tokens);
          }}
        >
          {({ handleSubmit }) => (
            <>
              <FormSpacer>
                <TextField
                  label="Email"
                  textContentType="emailAddress"
                  autoCapitalize="none"
                  name="email"
                />
              </FormSpacer>
              <FormSpacer>
                <TextField
                  autoCapitalize="none"
                  label="Password"
                  secureTextEntry
                  textContentType="password"
                  name="password"
                />
              </FormSpacer>
              <LoadingButton
                isLoading={isLoading}
                onPress={() => handleSubmit()}
              >
                Login
              </LoadingButton>
            </>
          )}
        </Formik>
      </KeyboardAwareScrollView>
    </ScreenWrapper>
  );
}
Example #19
Source File: EmailLogin.tsx    From vsinder-app with Apache License 2.0 5 votes vote down vote up
EmailLogin: React.FC<AuthStackNav<"EmailLogin">> = ({
  navigation,
}) => {
  const [mutate, { isLoading }] = useMutation(defaultMutationFn);
  return (
    <ScreenWrapper>
      <KeyboardAwareScrollView keyboardShouldPersistTaps="handled">
        <Formik
          validationSchema={schema}
          validateOnBlur={false}
          validateOnChange={false}
          initialValues={{ email: "", password: "" }}
          onSubmit={async (values) => {
            const tokens = await mutate(["/email/login", values, "POST"]);
            navigation.navigate("tokens", tokens);
          }}
        >
          {({ handleSubmit }) => (
            <>
              <FormSpacer>
                <TextField
                  label="email"
                  textContentType="emailAddress"
                  autoCapitalize="none"
                  name="email"
                />
              </FormSpacer>
              <FormSpacer>
                <TextField
                  autoCapitalize="none"
                  label="password"
                  secureTextEntry
                  textContentType="password"
                  name="password"
                />
              </FormSpacer>
              <LoadingButton
                isLoading={isLoading}
                onPress={() => handleSubmit()}
              >
                login
              </LoadingButton>
            </>
          )}
        </Formik>
      </KeyboardAwareScrollView>
    </ScreenWrapper>
  );
}
Example #20
Source File: index.tsx    From youtube-2020-june-material-ui-themes with MIT License 5 votes vote down vote up
export function FormikStepper({
  children,
  ...props
}: FormikConfig<FormikValues>) {
  const childrenArray = React.Children.toArray(children) as React.ReactElement<
    FormikStepProps
  >[];
  const [step, setStep] = useState(0);
  const currentChild = childrenArray[step];
  const [completed, setCompleted] = useState(false);

  function isLastStep() {
    return step === childrenArray.length - 1;
  }

  return (
    <Formik
      {...props}
      validationSchema={currentChild.props.validationSchema}
      onSubmit={async (values, helpers) => {
        if (isLastStep()) {
          await props.onSubmit(values, helpers);
          setCompleted(true);
        } else {
          setStep(s => s + 1);
        }
      }}
    >
      {({ isSubmitting }) => (
        <Form autoComplete="off">
          <Stepper alternativeLabel activeStep={step}>
            {childrenArray.map((child, index) => (
              <Step
                key={child.props.label}
                completed={step > index || completed}
              >
                <StepLabel>{child.props.label}</StepLabel>
              </Step>
            ))}
          </Stepper>

          {currentChild}

          <Grid container spacing={2}>
            {step > 0 ? (
              <Grid item>
                <Button
                  disabled={isSubmitting}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep(s => s - 1)}
                >
                  Back
                </Button>
              </Grid>
            ) : null}
            <Grid item xs={12}>
              <Button
                startIcon={
                  isSubmitting ? <CircularProgress size="1rem" /> : null
                }
                disabled={isSubmitting}
                type="submit"
                fullWidth
              >
                {isSubmitting ? "Submitting" : isLastStep() ? "Submit" : "NeXt"}
              </Button>
            </Grid>
          </Grid>
        </Form>
      )}
    </Formik>
  );
}
Example #21
Source File: index.tsx    From youtube-2020-june-multi-step-form-formik with MIT License 5 votes vote down vote up
export function FormikStepper({ children, ...props }: FormikConfig<FormikValues>) {
  const childrenArray = React.Children.toArray(children) as React.ReactElement<FormikStepProps>[];
  const [step, setStep] = useState(0);
  const currentChild = childrenArray[step];
  const [completed, setCompleted] = useState(false);

  function isLastStep() {
    return step === childrenArray.length - 1;
  }

  return (
    <Formik
      {...props}
      validationSchema={currentChild.props.validationSchema}
      onSubmit={async (values, helpers) => {
        if (isLastStep()) {
          await props.onSubmit(values, helpers);
          setCompleted(true);
        } else {
          setStep((s) => s + 1);

          // the next line was not covered in the youtube video
          //
          // If you have multiple fields on the same step
          // we will see they show the validation error all at the same time after the first step!
          //
          // If you want to keep that behaviour, then, comment the next line :)
          // If you want the second/third/fourth/etc steps with the same behaviour
          //    as the first step regarding validation errors, then the next line is for you! =)
          //
          // In the example of the video, it doesn't make any difference, because we only
          //    have one field with validation in the second step :)
          helpers.setTouched({});
        }
      }}
    >
      {({ isSubmitting }) => (
        <Form autoComplete="off">
          <Stepper alternativeLabel activeStep={step}>
            {childrenArray.map((child, index) => (
              <Step key={child.props.label} completed={step > index || completed}>
                <StepLabel>{child.props.label}</StepLabel>
              </Step>
            ))}
          </Stepper>

          {currentChild}

          <Grid container spacing={2}>
            {step > 0 ? (
              <Grid item>
                <Button
                  disabled={isSubmitting}
                  variant="contained"
                  color="primary"
                  onClick={() => setStep((s) => s - 1)}
                >
                  Back
                </Button>
              </Grid>
            ) : null}
            <Grid item>
              <Button
                startIcon={isSubmitting ? <CircularProgress size="1rem" /> : null}
                disabled={isSubmitting}
                variant="contained"
                color="primary"
                type="submit"
              >
                {isSubmitting ? 'Submitting' : isLastStep() ? 'Submit' : 'Next'}
              </Button>
            </Grid>
          </Grid>
        </Form>
      )}
    </Formik>
  );
}
Example #22
Source File: Governance.tsx    From homebase-app with MIT License 5 votes vote down vote up
Governance: React.FC = () => {
  const { dispatch, state, updateCache } = useContext(CreatorContext);
  const { votingSettings } = state.data;
  const history = useHistory();

  const saveStepInfo = (
    values: VotingSettings,
    { setSubmitting }: { setSubmitting: (b: boolean) => void }
  ) => {
    const newState = {
      ...state.data,
      votingSettings: values,
    };
    updateCache(newState);
    setSubmitting(true);
    dispatch({ type: ActionTypes.UPDATE_VOTING_SETTINGS, voting: values });
    history.push(`quorum`);
  };

  return (
    <Box maxWidth={950}>
      <Grid container direction="row" justify="space-between">
        <Grid item xs={12}>
          <Typography variant="h3" color="textSecondary">
            Proposals & Voting
          </Typography>
        </Grid>
      </Grid>
      <Grid container direction="row">
        <Grid item xs={12}>
          <CustomTypography variant="subtitle1" color="textSecondary">
            These settings will define the duration, support and approval
            required for proposals.
          </CustomTypography>
        </Grid>
      </Grid>

      <Formik
        enableReinitialize
        validate={validateForm}
        onSubmit={saveStepInfo}
        initialValues={votingSettings}
      >
        {({
          submitForm,
          isSubmitting,
          setFieldValue,
          values,
          errors,
          touched,
        }) => {
          return (
            <Form style={{ width: "100%" }}>
              <GovernanceForm
                submitForm={submitForm}
                isSubmitting={isSubmitting}
                setFieldValue={setFieldValue}
                errors={errors}
                touched={touched}
                values={values}
              />
            </Form>
          );
        }}
      </Formik>
    </Box>
  );
}
Example #23
Source File: configure.tsx    From dendron with GNU Affero General Public License v3.0 5 votes vote down vote up
export default function Config({
  engine,
}: {
  engine: engineSlice.EngineState;
}) {
  const logger = createLogger("Config");
  if (!engine.config) {
    return <></>;
  }

  const formItemLayout = {
    labelCol: {
      xs: { span: 24 },
      sm: { span: 8 },
    },
    wrapperCol: {
      xs: { span: 24 },
      sm: { span: 16 },
    },
  };

  return (
    <Formik initialValues={engine.config} onSubmit={() => {}}>
      {({ handleSubmit, handleChange, handleBlur, values, errors }) => (
        <Form {...formItemLayout}>
          <Typography>
            <Title>Publishing </Title>
          </Typography>

          <Form.Item name="siteHierarchies" label="Site Hierarchies">
            <FieldArray
              name="siteHierarchies"
              render={(arrayHelpers) => {
                const publishingConfig = ConfigUtils.getPublishingConfig(
                  values as IntermediateDendronConfig
                );
                return renderArray(
                  publishingConfig.siteHierarchies,
                  arrayHelpers
                );
              }}
            />
          </Form.Item>
          {createFormItem({ name: "site.siteRootDir", label: "Site Root Dir" })}
        </Form>
      )}
    </Formik>
  );
}
Example #24
Source File: PhotoSwipe.tsx    From bada-frame with GNU General Public License v3.0 5 votes vote down vote up
FileNameEditForm = ({ filename, saveEdits, discardEdits, extension }) => {
    const [loading, setLoading] = useState(false);

    const onSubmit = async (values: formValues) => {
        try {
            setLoading(true);
            await saveEdits(values.filename);
        } finally {
            setLoading(false);
        }
    };
    return (
        <Formik<formValues>
            initialValues={{ filename }}
            validationSchema={Yup.object().shape({
                filename: Yup.string()
                    .required(constants.REQUIRED)
                    .max(
                        MAX_EDITED_FILE_NAME_LENGTH,
                        constants.FILE_NAME_CHARACTER_LIMIT
                    ),
            })}
            validateOnBlur={false}
            onSubmit={onSubmit}>
            {({ values, errors, handleChange, handleSubmit }) => (
                <Form noValidate onSubmit={handleSubmit}>
                    <Form.Row>
                        <Form.Group
                            bsPrefix="ente-form-group"
                            as={Col}
                            xs={extension ? 7 : 8}>
                            <Form.Control
                                as="textarea"
                                placeholder={constants.FILE_NAME}
                                value={values.filename}
                                onChange={handleChange('filename')}
                                isInvalid={Boolean(errors.filename)}
                                autoFocus
                                disabled={loading}
                            />
                            <FormControl.Feedback
                                type="invalid"
                                style={{ textAlign: 'center' }}>
                                {errors.filename}
                            </FormControl.Feedback>
                        </Form.Group>
                        {extension && (
                            <Form.Group
                                bsPrefix="ente-form-group"
                                as={Col}
                                xs={1}
                                controlId="formHorizontalFileName">
                                <FlexWrapper style={{ padding: '5px' }}>
                                    {`.${extension}`}
                                </FlexWrapper>
                            </Form.Group>
                        )}
                        <Form.Group bsPrefix="ente-form-group" as={Col} xs={2}>
                            <Value width={'16.67%'}>
                                <IconButton type="submit" disabled={loading}>
                                    {loading ? (
                                        <SmallLoadingSpinner />
                                    ) : (
                                        <TickIcon />
                                    )}
                                </IconButton>
                                <IconButton
                                    onClick={discardEdits}
                                    disabled={loading}>
                                    <CloseIcon />
                                </IconButton>
                            </Value>
                        </Form.Group>
                    </Form.Row>
                </Form>
            )}
        </Formik>
    );
}
Example #25
Source File: InteractiveOptions.test.tsx    From glific-frontend with GNU Affero General Public License v3.0 5 votes vote down vote up
test('it render interactive options for list reply template', async () => {
  render(
    <Formik initialValues={{ templateButtons: inputFields }} onSubmit={mock}>
      <InteractiveOptions {...props} />
    </Formik>
  );

  const textboxes = screen.getAllByRole('textbox');
  const inputData = ['show', 'section 1', 'title 1', 'desc 1', 'section 2', 'title 2', 'desc 2'];
  let count = 0;

  for await (let input of textboxes) {
    expect(input).toBeInTheDocument();
    fireEvent.change(input, { target: { value: inputData[count] } });
    await waitFor(() => {});
    count++;
  }

  const [addAnotherList, addAnotherListItem] = screen.getAllByRole('button');
  expect(addAnotherListItem).toBeInTheDocument();
  expect(addAnotherList).toBeInTheDocument();

  fireEvent.click(addAnotherListItem);
  await waitFor(() => {});

  fireEvent.click(addAnotherList);
  await waitFor(() => {});

  const [list1] = screen.getAllByText('Red.svg');
  const [listItem1] = screen.getAllByText('Cross.svg');

  expect(list1).toBeInTheDocument();
  expect(listItem1).toBeInTheDocument();

  fireEvent.click(list1);
  await waitFor(() => {});

  fireEvent.click(listItem1);
  await waitFor(() => {});

  const [quickReplyRadio] = screen.getAllByRole('radio');

  expect(quickReplyRadio).toBeInTheDocument();
  fireEvent.click(quickReplyRadio);

  await waitFor(() => {});
});
Example #26
Source File: LoginView.tsx    From nyxo-app with GNU General Public License v3.0 5 votes vote down vote up
SignInScreen: FC<Props> = ({ back, goToRegister, login }) => {
  const loading = useAppSelector(({ auth }) => auth.loading)

  const submit = ({ email, password }: { email: string; password: string }) => {
    login(email, password)
  }

  return (
    <SafeAreaView>
      <Circle />
      <Formik
        initialValues={{ email: '', password: '' }}
        validationSchema={LoginSchema}
        onSubmit={submit}>
        {({
          handleChange,
          handleSubmit,
          handleBlur,
          values,
          touched,
          errors,
          isValid
        }) => (
          <>
            <Container>
              <ScrollView>
                <TitleRow>
                  <H1>TITLE_SIGNIN</H1>
                </TitleRow>

                <Input
                  key="email"
                  fieldName="INPUT_EMAIL"
                  autoCompleteType="email"
                  returnKeyType="next"
                  value={values.email}
                  error={touched.email ? errors.email : ''}
                  blurOnSubmit={false}
                  enablesReturnKeyAutomatically
                  autoCapitalize="none"
                  textContentType="emailAddress"
                  placeholder="INPUT_EMAIL"
                  onBlur={handleBlur('email')}
                  icon="emailUnread"
                  onChangeText={handleChange('email')}
                />
                <Input
                  key="password"
                  fieldName="INPUT_PASSWORD"
                  textContentType="password"
                  autoCompleteType="password"
                  value={values.password}
                  error={touched.password ? errors.password : ''}
                  returnKeyType="done"
                  enablesReturnKeyAutomatically
                  placeholder="INPUT_PASSWORD"
                  secureTextEntry
                  icon="lockCircle"
                  onBlur={handleBlur('password')}
                  blurOnSubmit
                  onChangeText={handleChange('password')}
                />

                <Register onPress={goToRegister}>MOVE_TO_REGISTER</Register>
              </ScrollView>
            </Container>

            <BottomButton
              loading={loading === 'pending'}
              disabled={!isValid || (!touched.email && !touched.password)}
              onPress={handleSubmit}
              title="BUTTON_SIGNIN"
            />
          </>
        )}
      </Formik>
      <BackToAppButton back={back} />
    </SafeAreaView>
  )
}
Example #27
Source File: Login.tsx    From krmanga with MIT License 5 votes vote down vote up
Login = ({ navigation, dispatch, isLogin, loading }: IProps) => {

    const [disabled, setDisabled] = useState<boolean>(false);

    useEffect(() => {
        if (isLogin) {
            setTimeout(() => {
                navigation.goBack();
            }, 100);
        }
    }, [isLogin]);

    const onSubmit = (values: Values) => {

        if (disabled || loading) {
            return;
        }

        setDisabled(true);

        dispatch({
            type: "user/login",
            payload: values,
            callback: () => {
                setDisabled(false);
            }
        });
    };

    const cancel = (form: FormikProps<string>, field: FieldInputProps<string>) => {
        if (field.name === "account") {
            form.setFieldValue("account", "");
        } else if (field.name === "password") {
            form.setFieldValue("password", "");
        }
    };

    return (
        <ScrollView keyboardShouldPersistTaps="handled" style={styles.container}>
            <Formik
                initialValues={initialValues}
                onSubmit={onSubmit}
                validationSchema={customerValidation}>
                {({ handleSubmit }) => (
                    <View>
                        <Field
                            name="account"
                            placeholder="请输入用户名"
                            component={Input}
                            iconName={"icon-Account"}
                            cancel={cancel}
                        />
                        <Field
                            name="password"
                            placeholder="请输入密码"
                            component={Input}
                            iconName={"icon-mima"}
                            secureTextEntry
                            cancel={cancel}
                        />
                        <View style={styles.jumpView}>
                            <Text style={styles.jumpTitle}>忘记密码?</Text>
                            <Touchable onPress={() => navigation.navigate("Register")}>
                                <Text style={styles.jumpTitle}>注册账号</Text>
                            </Touchable>
                        </View>
                        <Touchable disabled={disabled} onPress={handleSubmit} style={styles.login}>
                            <Text style={styles.loginText}>登录</Text>
                        </Touchable>
                    </View>
                )}
            </Formik>
        </ScrollView>
    );
}
Example #28
Source File: input.test.tsx    From openmrs-esm-patient-registration with MIT License 5 votes vote down vote up
describe.skip('checkbox input', () => {
  const setupInput = async () => {
    render(
      <Formik initialValues={{ checkbox: false }} onSubmit={null}>
        <Form>
          <Input id="checkbox" labelText="checkbox" name="checkbox" light />
        </Form>
      </Formik>,
    );
    return screen.getByLabelText('checkbox') as HTMLInputElement;
  };

  it('exists', async () => {
    const input = await setupInput();
    expect(input.type).toEqual('checkbox');
  });

  it('can input data', async () => {
    const input = await setupInput();
    const expected = true;

    fireEvent.click(input);
    fireEvent.blur(input);

    await wait();

    expect(input.checked).toEqual(expected);
  });

  it('can update data', async () => {
    const input = await setupInput();
    const expected = false;

    fireEvent.click(input);
    fireEvent.blur(input);

    fireEvent.click(input);
    fireEvent.blur(input);

    await wait();

    expect(input.checked).toEqual(expected);
  });
});
Example #29
Source File: ConclusionsPanel.tsx    From abacus with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Renders the conclusion information of an experiment in a panel component.
 *
 * @param experiment - The experiment with the conclusion information.
 * @param experimentReloadRef - A ref for reloading the experiment.
 */
function ConclusionsPanel({
  className,
  experiment,
  experimentReloadRef,
}: {
  className?: string
  experiment: ExperimentFull
  experimentReloadRef: React.MutableRefObject<() => void>
}): JSX.Element {
  const classes = useStyles()

  const deployedVariation = Experiments.getDeployedVariation(experiment)
  const data = [
    { label: 'Reason the experiment ended', value: experiment.endReason },
    {
      label: 'Conclusion URL',
      value: !!experiment.conclusionUrl && (
        <a href={experiment.conclusionUrl} rel='noopener noreferrer' target='_blank'>
          {experiment.conclusionUrl}
        </a>
      ),
    },
    { label: 'Deployed variation', value: deployedVariation?.name },
  ]

  // Edit Modal
  const { enqueueSnackbar } = useSnackbar()
  const [isEditing, setIsEditing] = useState<boolean>(false)
  const editInitialValues = {
    endReason: experiment.endReason ?? '',
    conclusionUrl: experiment.conclusionUrl ?? '',
    deployedVariationId: String(experiment.deployedVariationId ?? ''),
  }
  const onEdit = () => setIsEditing(true)
  const onCancelEdit = () => setIsEditing(false)
  const onSubmitEdit = async ({ experiment: formValues }: { experiment: typeof editInitialValues }) => {
    try {
      await ExperimentsApi.patch(experiment.experimentId, {
        endReason: formValues.endReason,
        conclusionUrl: formValues.conclusionUrl === '' ? undefined : formValues.conclusionUrl,
        deployedVariationId: formValues.deployedVariationId ? Number(formValues.deployedVariationId) : undefined,
      })
      enqueueSnackbar('Experiment Updated!', { variant: 'success' })
      experimentReloadRef.current()
      setIsEditing(false)
    } catch (e) {
      // istanbul ignore next; shouldn't happen
      enqueueSnackbar(`Oops! Something went wrong while trying to update your experiment. ${serverErrorMessage(e)}`, {
        variant: 'error',
      })
    }
  }

  return (
    <Paper className={className}>
      <Toolbar>
        <Typography className={classes.title} color='textPrimary' variant='h3'>
          Conclusions
        </Typography>
        <Button onClick={onEdit} variant='outlined' aria-label='Edit Conclusion'>
          <Edit />
          Edit
        </Button>
      </Toolbar>

      <LabelValueTable data={data} />

      <Dialog open={isEditing} fullWidth aria-labelledby='edit-experiment-conclusions-dialog-title'>
        <DialogTitle id='edit-experiment-conclusions-dialog-title'>Edit Experiment: Conclusions</DialogTitle>
        <Formik
          initialValues={{ experiment: editInitialValues }}
          validationSchema={yup.object({ experiment: yupPick(experimentFullSchema, Object.keys(editInitialValues)) })}
          onSubmit={onSubmitEdit}
        >
          {(formikProps) => (
            <form onSubmit={formikProps.handleSubmit}>
              <DialogContent>
                <div className={classes.row}>
                  <Field
                    component={TextField}
                    name='experiment.endReason'
                    id='experiment.endReason'
                    label='Reason the experiment ended'
                    placeholder='Completed successfully'
                    variant='outlined'
                    fullWidth
                    required
                    multiline
                    rows={2}
                    InputLabelProps={{
                      shrink: true,
                    }}
                  />
                </div>

                <div className={classes.row}>
                  <Field
                    component={TextField}
                    id='experiment.conclusionUrl'
                    name='experiment.conclusionUrl'
                    placeholder='https://your-p2-post-here/#conclusion-comment'
                    label='Conclusion URL'
                    variant='outlined'
                    fullWidth
                    InputLabelProps={{
                      shrink: true,
                    }}
                  />
                </div>

                <div className={classes.row}>
                  <FormControl component='fieldset'>
                    <FormLabel component='legend'>Deployed variation</FormLabel>
                    <Field component={FormikMuiRadioGroup} name='experiment.deployedVariationId'>
                      {experiment.variations.map((variation) => (
                        <FormControlLabel
                          key={variation.variationId}
                          value={String(variation.variationId)}
                          control={<Radio />}
                          label={variation.name}
                        />
                      ))}
                    </Field>
                  </FormControl>
                </div>
              </DialogContent>
              <DialogActions>
                <Button onClick={onCancelEdit} color='primary'>
                  Cancel
                </Button>
                <LoadingButtonContainer isLoading={formikProps.isSubmitting}>
                  <Button
                    type='submit'
                    variant='contained'
                    color='secondary'
                    disabled={formikProps.isSubmitting || !formikProps.isValid}
                  >
                    Save
                  </Button>
                </LoadingButtonContainer>
              </DialogActions>
            </form>
          )}
        </Formik>
      </Dialog>
    </Paper>
  )
}