react#FormEventHandler TypeScript Examples

The following examples show how to use react#FormEventHandler. 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: AlertAcceptForm.tsx    From backstage with Apache License 2.0 6 votes vote down vote up
AlertAcceptForm = forwardRef<
  HTMLFormElement,
  AlertAcceptFormProps
>(({ onSubmit, disableSubmit }, ref) => {
  const [checked, setChecked] = useState(false);

  const onFormSubmit: FormEventHandler = e => {
    e.preventDefault();
    onSubmit(null);
  };

  const onChecked = (_: ChangeEvent<HTMLInputElement>, isChecked: boolean) => {
    setChecked(isChecked);
    disableSubmit(!isChecked);
  };

  return (
    <form ref={ref} onSubmit={onFormSubmit}>
      <FormControl component="fieldset" fullWidth>
        <FormControlLabel
          label="My team can commit to making this change soon, or has already."
          value={checked}
          control={
            <Checkbox color="primary" checked={checked} onChange={onChecked} />
          }
        />
      </FormControl>
    </form>
  );
})
Example #2
Source File: Prompt.tsx    From mysterium-vpn-desktop with MIT License 6 votes vote down vote up
Prompt: React.FC<PropsWithChildren<PromptProps>> = ({
    visible,
    title,
    onSubmit,
    onCancel,
    submitText = "OK",
    children,
}) => {
    if (!visible) {
        return <></>
    }
    const handleOnSubmit: FormEventHandler = (evt) => {
        evt.preventDefault()
        onSubmit?.()
    }
    const handleCancel = () => {
        onCancel?.()
    }
    return (
        <Background>
            <Box>
                <form onSubmit={handleOnSubmit}>
                    <PromptTitle>{title}</PromptTitle>
                    {children}
                    <PromptButtons>
                        <PromptButtonOK type="submit">{submitText}</PromptButtonOK>
                        <OutlineButton onClick={handleCancel} type="button">
                            Cancel
                        </OutlineButton>
                    </PromptButtons>
                </form>
            </Box>
        </Background>
    )
}
Example #3
Source File: CheckboxField.tsx    From typescript-fun with MIT License 6 votes vote down vote up
CheckboxField: FC<{
  field: Field<boolean, FormErrorID>;
  label: string;
}> = ({ field, label, ...rest }) => {
  const handleChange = useCallback<FormEventHandler<HTMLInputElement>>(
    event => {
      field.onChange(event.currentTarget.checked);
    },
    [field],
  );

  const handleKeyPress = useCallback<KeyboardEventHandler<HTMLInputElement>>(
    event => {
      if (event.key === 'Enter') field.submit();
    },
    [field],
  );

  return (
    <FormControl {...rest}>
      <Checkbox
        isChecked={field.value}
        onChange={handleChange}
        onKeyPress={handleKeyPress}
        ref={field.ref}
      >
        {label}
      </Checkbox>
    </FormControl>
  );
}
Example #4
Source File: KubernetesMigrationDismissForm.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
KubernetesMigrationDismissForm = forwardRef<
  HTMLFormElement,
  KubernetesMigrationDismissFormProps
>(({ onSubmit, disableSubmit, alert }, ref) => {
  const [services, setServices] = useState<Entity[]>(alert.data.services);

  const onFormSubmit: FormEventHandler = e => {
    /* Remember to prevent default form behavior */
    e.preventDefault();
    onSubmit({ services: services });
  };

  const onCheckboxChange = (
    e: ChangeEvent<HTMLInputElement>,
    checked: boolean,
  ) => {
    if (checked) {
      const service = findAlways(
        alert.data.services,
        s => s.id === e.target.value,
      );
      setServices(prevServices => prevServices.concat(service));
    } else {
      setServices(prevServices =>
        prevServices.filter(p => p.id !== e.target.value),
      );
    }
  };

  /* Submit button is disabled by default. Use props.disableSubmit to toggle disabled state. */
  useEffect(() => {
    if (services.length) {
      disableSubmit(false);
    } else {
      disableSubmit(true);
    }
  }, [services, disableSubmit]);

  return (
    /* All custom forms must accept a ref and implement an onSubmit handler. */
    <form ref={ref} onSubmit={onFormSubmit}>
      <FormControl component="fieldset" fullWidth>
        <Typography color="textPrimary">
          <b>Or choose which services to dismiss this alert for.</b>
        </Typography>
        <FormGroup>
          {alert.data.services.map((service, index) => (
            <FormControlLabel
              key={`example-option-${index}`}
              label={service.id}
              value={service.id}
              control={
                <Checkbox
                  color="primary"
                  checked={services.some(p => p.id === service.id)}
                  onChange={onCheckboxChange}
                />
              }
            />
          ))}
        </FormGroup>
      </FormControl>
    </form>
  );
})
Example #5
Source File: AlertSnoozeForm.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
AlertSnoozeForm = forwardRef<
  HTMLFormElement,
  AlertSnoozeFormProps
>(({ onSubmit, disableSubmit }, ref) => {
  const classes = useStyles();
  const [duration, setDuration] = useState<Maybe<Duration>>(Duration.P7D);

  useEffect(() => disableSubmit(false), [disableSubmit]);

  const onFormSubmit: FormEventHandler = e => {
    e.preventDefault();
    if (duration) {
      const repeatInterval = 1;
      const today = DateTime.now().toFormat(DEFAULT_DATE_FORMAT);
      onSubmit({
        intervals: intervalsOf(duration, today, repeatInterval),
      });
    }
  };

  const onSnoozeDurationChange = (
    _: ChangeEvent<HTMLInputElement>,
    value: string,
  ) => {
    setDuration(value as Duration);
  };

  return (
    <form ref={ref} onSubmit={onFormSubmit}>
      <FormControl component="fieldset" fullWidth>
        <Typography color="textPrimary">
          <b>For how long?</b>
        </Typography>
        <Box mb={1}>
          <RadioGroup
            name="snooze-alert-options"
            value={duration}
            onChange={onSnoozeDurationChange}
          >
            {AlertSnoozeOptions.map(option => (
              <FormControlLabel
                key={`snooze-alert-option-${option.duration}`}
                label={option.label}
                value={option.duration}
                control={<Radio className={classes.radio} />}
              />
            ))}
          </RadioGroup>
        </Box>
      </FormControl>
    </form>
  );
})
Example #6
Source File: TextInputField.tsx    From typescript-fun with MIT License 5 votes vote down vote up
TextInputField: FC<{
  field: FieldMaybeOptional<string, FormErrorID>;
  icon?: ReactNode;
  label: string;
  type: 'text' | 'email' | 'password' | 'tel';
}> = ({ field, icon, label, type, ...rest }) => {
  const handleChange = useCallback<FormEventHandler<HTMLInputElement>>(
    ({ currentTarget: { value } }) => {
      if (isOptionalField(field)) {
        field.onChange(value.length === 0 ? O.none : O.some(value));
      } else {
        field.onChange(value);
      }
    },
    [field],
  );

  const handleKeyPress = useCallback<KeyboardEventHandler<HTMLInputElement>>(
    event => {
      if (event.key === 'Enter') field.submit();
    },
    [field],
  );

  const value = isOptionalField(field)
    ? pipe(
        field.value,
        O.getOrElse(() => ''),
      )
    : field.value;

  const input = (
    <Input
      id={field.key}
      type={type}
      value={value}
      onChange={handleChange}
      onKeyPress={handleKeyPress}
      ref={field.ref}
    />
  );

  return (
    <FormControl
      isRequired={!isOptionalField(field)}
      isInvalid={field.isInvalid}
      {...rest}
    >
      <FormLabel htmlFor={field.key}>{label}</FormLabel>
      {icon ? (
        <InputGroup>
          <InputLeftElement>{icon}</InputLeftElement>
          {input}
        </InputGroup>
      ) : (
        input
      )}
      <FormErrorMessage error={field.firstError} />
    </FormControl>
  );
}
Example #7
Source File: General.tsx    From one-platform with MIT License 4 votes vote down vote up
export default function General ( { app }: IGeneralSettings ) {
  const { forceRefreshApp } = useContext( AppContext );
  const [ isDeleteModalOpen, setDeleteModalOpen ] = useState( false );
  const [ deleteAppConfirmation, setDeleteAppConformation ] = useState( '' );
  const history = useHistory();
  const location = useLocation();
  const { control, handleSubmit, formState: { errors, isValid }, watch, reset } = useForm<IAppInput>( {
    mode: 'onBlur',
    resolver: yupResolver( formSchema ),
    defaultValues: {
      name: '',
      description: ''
    },
  } );
  const [ isSaving, setIsSaving ] = useState( false );

  const editedName = watch( 'name' );
  const editedDescription = watch( 'description' );
  const isChanged = useMemo( () => {
    return editedName !== app.name || editedDescription !== app.description;
  }, [app, editedName, editedDescription] );

  const handleReset = useCallback( () => {
    reset( {
      name: app.name,
      description: app.description
    } );
  }, [ app, reset ] );

  const handleSaveApp = useCallback(( data: any ) => {
    setIsSaving( true );
    updateAppService( app.id, data )
      .then( updatedApp => {
        forceRefreshApp( updatedApp );
        window.OpNotification?.success( { subject: 'App Updated Successfully!' } );
        setIsSaving( false );
      } )
      .catch( err => {
        window.OpNotification?.danger( { subject: 'An error occurred when updating the App.', body: 'Please try again later.' } );
        console.error( err );
        setIsSaving( false );
      } );
  }, [ app.id, forceRefreshApp ] );

  useEffect( () => {
    handleReset();
  }, [ app, handleReset ] );

  useEffect( () => {
    const searchParams = new URLSearchParams( location.search );
    if ( searchParams.get( 'action' ) === 'delete' ) {
      setDeleteModalOpen( true );
    } else {
      setDeleteModalOpen( false );
    }
  }, [ location ] );

  const handleOwnershipTransferToggle = () => {
    /* TODO: gqlQuery for toggling ownership transfer */
  };

  const handleDeleteApp: FormEventHandler = ( event ) => {
    event.preventDefault();
    deleteAppService( app.id )
      .then( () => {
        window.OpNotification?.success( { subject: 'App Deleted Successfully!' } );
        history.push( '/' );
      } )
      .catch( err => {
        window.OpNotification?.danger( { subject: 'An error occurred when deleting the App.', body: 'Please try again later.' } );
        console.error( err );
      } );
  };

  const handleModalClose = () => {
    /* Remove the new=true from the url search params */
    const searchParams = new URLSearchParams( location.search );
    searchParams.delete( 'action' );
    history.replace( { search: searchParams.toString() } );
    setDeleteAppConformation( '' );
  };

  return (
    <>
      <Stack hasGutter>
        <StackItem>
          <Form onSubmit={ handleSubmit( handleSaveApp ) } onReset={ handleReset }>
            <Card isRounded>
              <CardBody>
                <Grid hasGutter>
                  <GridItem>
                    <FormGroup
                      isRequired
                      fieldId="name"
                      label="App Name"
                      helperText="Name of the project"
                      helperTextInvalid={ errors.name?.message }
                      validated={errors.name ? 'error' : 'default' }>
                      <Controller
                        name="name"
                        control={ control }
                        render={ ( { field } ) => (
                          <TextInput
                            { ...field }
                            id="name"
                            placeholder="Enter a name for your project"
                            validated={ errors.name ? 'error' : 'default' }
                            isRequired></TextInput>
                        ) }/>
                    </FormGroup>
                  </GridItem>
                  <GridItem>
                    <FormGroup
                      fieldId="description"
                      label="Description"
                      helperText="Describe the project"
                      helperTextInvalid={ errors.description?.message }
                      validated={errors.description ? 'error' : 'default' }>
                      <Controller
                        name="description"
                        control={ control }
                        render={ ( { field } ) => (
                          <TextArea
                            { ...field }
                            id="description"
                            rows={ 3 }
                            validated={errors.description ? 'error' : 'default' }
                            placeholder="Enter a description for your project" />
                        )} />
                    </FormGroup>
                  </GridItem>
                </Grid>
              </CardBody>
              <CardFooter>
                <Button variant="primary" type="submit" isLoading={ isSaving } isDisabled={ !isValid || !isChanged || isSaving }>Save</Button>
                <Button variant="plain" type="reset">Reset</Button>
              </CardFooter>
            </Card>
          </Form>
        </StackItem>
        <StackItem>
          <Card isRounded style={ { border: '1px solid var(--pf-global--danger-color--100)', overflow: 'hidden' } }>
            <CardTitle className="pf-u-danger-color-100">Advanced Settings</CardTitle>
            <Menu style={ { boxShadow: 'none' } }>
              <MenuContent>
                <MenuList>
                  <MenuItem
                    description="Transfer this project to another user"
                    itemId={ 0 }
                    onClick={ handleOwnershipTransferToggle }
                    actions={
                      <MenuItemAction
                        actionId="transfer"
                        icon={ <ion-icon name="swap-horizontal-outline"></ion-icon> }
                        aria-label="Transfer ownership" />
                    }>
                    Transfer ownership
                  </MenuItem>
                  <MenuItem
                    description="Deletes the app from One Platform. Cannot be reverted."
                    itemId={ 1 }
                    onClick={ () => history.push( { search: 'action=delete' } ) }
                    actions={
                      <MenuItemAction
                        actionId="delete"
                        icon={ <ion-icon class="pf-u-danger-color-100" name="trash" /> }
                        aria-label="Delete the app" />
                    }>
                    <span className="pf-u-danger-color-100">Delete this App</span>
                  </MenuItem>
                </MenuList>
              </MenuContent>
            </Menu>
          </Card>
        </StackItem>
      </Stack>
      <Modal
        variant="small"
        isOpen={ isDeleteModalOpen }
        aria-label="Delete App Modal"
        title="Are you sure?"
        titleIconVariant="danger"
        showClose={ true }
        onClose={ handleModalClose }>
        <Text>This action is irreversible and will permanently delete the <strong><em>{ app.name }</em></strong> app from One Platform.</Text>
        <br />
        <Form onSubmit={ handleDeleteApp }>
          <FormGroup fieldId="delete-app" label={ `Please type "${ app.name }" to confirm` } isRequired>
            <TextInput id="delete-app" autoFocus onChange={ val => setDeleteAppConformation( val ) } isRequired></TextInput>
          </FormGroup>
          <Button variant="danger" type="submit" isDisabled={ app.name !== deleteAppConfirmation }>I understand the consequences, delete this app</Button>
        </Form>
      </Modal>
    </>
  );
}
Example #8
Source File: AlertDismissForm.tsx    From backstage with Apache License 2.0 4 votes vote down vote up
AlertDismissForm = forwardRef<
  HTMLFormElement,
  AlertDismissFormProps
>(({ onSubmit, disableSubmit }, ref) => {
  const classes = useStyles();
  const [other, setOther] = useState<Maybe<string>>(null);
  const [feedback, setFeedback] = useState<Maybe<string>>(null);
  const [reason, setReason] = useState<AlertDismissReason>(
    AlertDismissReason.Resolved,
  );

  const onFormSubmit: FormEventHandler = e => {
    e.preventDefault();
    if (reason) {
      onSubmit({
        other: other,
        reason: reason,
        feedback: feedback,
      });
    }
  };

  const onReasonChange = (_: ChangeEvent<HTMLInputElement>, value: string) => {
    if (other) {
      setOther(null);
    }
    setReason(value as AlertDismissReason);
  };

  const onOtherChange = (e: ChangeEvent<HTMLInputElement>) => {
    return e.target.value
      ? setOther(e.target.value as AlertDismissReason)
      : setOther(null);
  };

  const onFeedbackChange = (e: ChangeEvent<HTMLInputElement>) => {
    return e.target.value
      ? setFeedback(e.target.value as AlertDismissReason)
      : setFeedback(null);
  };

  useEffect(() => {
    function validateDismissForm() {
      if (reason === AlertDismissReason.Other) {
        if (other) {
          disableSubmit(false);
        } else {
          disableSubmit(true);
        }
      } else if (reason) {
        disableSubmit(false);
      } else {
        disableSubmit(true);
      }
    }

    validateDismissForm();
  }, [reason, other, disableSubmit]);

  return (
    <form ref={ref} onSubmit={onFormSubmit}>
      <FormControl component="fieldset" fullWidth>
        <Typography color="textPrimary">
          <b>Reason for dismissing?</b>
        </Typography>
        <Box mb={1}>
          <RadioGroup
            name="dismiss-alert-reasons"
            value={reason}
            onChange={onReasonChange}
          >
            {AlertDismissOptions.map(option => (
              <FormControlLabel
                key={`dismiss-alert-option-${option.reason}`}
                label={option.label}
                value={option.reason}
                control={<Radio className={classes.radio} />}
              />
            ))}
          </RadioGroup>
          <Collapse in={reason === AlertDismissReason.Other}>
            <Box ml={4}>
              <TextField
                id="dismiss-alert-option-other"
                variant="outlined"
                multiline
                fullWidth
                rows={4}
                value={other ?? ''}
                onChange={onOtherChange}
              />
            </Box>
          </Collapse>
        </Box>
        <Typography gutterBottom>
          <b>Any other feedback you can provide?</b>
        </Typography>
        <TextField
          id="dismiss-alert-feedback"
          variant="outlined"
          multiline
          rows={4}
          fullWidth
          value={feedback ?? ''}
          onChange={onFeedbackChange}
        />
      </FormControl>
    </form>
  );
})
Example #9
Source File: GamepadConfigEditor.tsx    From xcloud-keyboard-mouse with GNU General Public License v3.0 4 votes vote down vote up
function GamepadConfigEditor({ name, onSubmitChanges, onCancelCreate, onActivate, onDelete }: SensitivityEditorProps) {
  const { status, config: storedGamepadConfig } = useAppSelector((state) => getGamepadConfig(state, name));
  const isActive = useAppSelector((state) => isConfigActive(state, name));
  const isSubmitting = status === 'writing';
  const isNewDraft = !storedGamepadConfig;
  const isDefaultConfig = name === DEFAULT_CONFIG_NAME;
  const initialGamepadConfig = storedGamepadConfig || emptyGamepadConfig;
  const [state, dispatch] = useKeyConfigEditorState(initialGamepadConfig);
  const noMouse = state.config.mouseConfig.mouseControls === undefined;
  const hasChanges = isNewDraft || state.changes.keyConfig || state.changes.mouseConfig;
  // Starts in read-only state, but have button to enable editing/save changes?
  const [isEditing, setIsEditing] = useState(isNewDraft);
  useEffect(() => {
    if (isNewDraft) {
      setIsEditing(true);
    } else {
      setIsEditing(false);
    }
    dispatch({ type: 'reset', config: initialGamepadConfig });
  }, [dispatch, name, isNewDraft, initialGamepadConfig]);

  const handleKeybindChange = useCallback(
    (button: string, updated: KeyMap) => {
      dispatch({
        type: 'updateKeyConfig',
        button,
        keyMap: updated,
      });
    },
    [dispatch],
  );

  const handleMouseControlsChange = useCallback(
    (mouseControls?: StickNum) => {
      dispatch({
        type: 'updateMouseControls',
        mouseControls,
      });
    },
    [dispatch],
  );

  const handleActivate = useCallback(() => {
    onActivate(name);
  }, [name, onActivate]);

  const handleToggleEditing = useCallback(() => {
    if (isNewDraft && isEditing) {
      if (confirm('Are you sure you want to cancel creating a new preset?')) {
        onCancelCreate();
      }
      return;
    }
    if (isEditing && (!hasChanges || confirm('Are you sure you want to cancel? You will lose any changes.'))) {
      // Reset
      dispatch({ type: 'reset', config: storedGamepadConfig });
      setIsEditing(!isEditing);
    } else if (!isEditing) {
      setIsEditing(!isEditing);
    }
  }, [dispatch, hasChanges, isEditing, isNewDraft, onCancelCreate, storedGamepadConfig]);

  const handleDelete = useCallback(() => {
    if (confirm('Are you sure you want to delete this preset?')) {
      onDelete(name);
    }
  }, [name, onDelete]);

  const handleExport = useCallback(() => {
    exportConfig(state.config, name);
  }, [state.config, name]);

  const handleSubmit: FormEventHandler<HTMLFormElement> = useCallback(
    (e) => {
      e.preventDefault();
      if (!state.errors.hasErrors) {
        onSubmitChanges(name, state.config);
      } else {
        console.error('Cannot submit', state.errors);
      }
    },
    [name, onSubmitChanges, state.config, state.errors],
  );

  return (
    <form className="vertical full-height" onSubmit={handleSubmit}>
      <section className="config-editor full-absolute vertical">
        <table className="margin-vertical">
          <tbody>
            {(Object.keys(emptyGamepadConfig.keyConfig) as Array<keyof typeof state.config.keyConfig>).map((button) => {
              const val = state.config.keyConfig[button];
              return (
                <KeybindingsForButton
                  key={button.toString()}
                  useSpacers
                  button={button}
                  readOnly={!isEditing}
                  value={val}
                  onChange={handleKeybindChange}
                  error={state.errors.keyConfig[button]}
                />
              );
            })}
          </tbody>
        </table>
        <div className="margin-bottom">
          <div className="horizontal">
            <StickSelector
              readOnly={!isEditing}
              onChange={handleMouseControlsChange}
              stick={state.config.mouseConfig.mouseControls}
            />
          </div>
          <SensitivitySelector
            dispatch={dispatch}
            disabled={noMouse}
            readOnly={!isEditing}
            sensitivity={state.config.mouseConfig.sensitivity}
          />
        </div>
      </section>
      <section className="horizontal space-between padding-top-s">
        <div className="margin-right-s">
          <DefaultButton onClick={handleToggleEditing}>{isEditing ? 'Cancel' : 'Edit'}</DefaultButton>
          {!isEditing ? (
            <DefaultButton className="margin-left-s" disabled={isDefaultConfig} onClick={handleDelete}>
              Delete
            </DefaultButton>
          ) : null}
          {!isEditing ? (
            <DefaultButton className="margin-left-s" onClick={handleExport}>
              Export
            </DefaultButton>
          ) : null}
        </div>
        {isEditing ? (
          <PrimaryButton type="submit" disabled={state.errors.hasErrors || !hasChanges || isSubmitting}>
            {isNewDraft ? 'Create' : 'Save'}
          </PrimaryButton>
        ) : (
          <PrimaryButton onClick={handleActivate} disabled={state.errors.hasErrors || isActive || isSubmitting}>
            Use
          </PrimaryButton>
        )}
      </section>
    </form>
  );
}
Example #10
Source File: EmailSignup.tsx    From oxen-website with GNU General Public License v3.0 4 votes vote down vote up
export default function EmailSignup(props: Props): ReactElement {
  const { classes } = props;
  const router = useRouter();
  const buttonRef = useRef<HTMLButtonElement>(null);
  const setButtonText = (value: string) => {
    if (null !== buttonRef.current) {
      buttonRef.current.innerText = value;
    }
  };
  const [email, setEmail] = useState('');
  const handleSubscription: FormEventHandler = async event => {
    event.preventDefault();
    setButtonText('Subscribing...');
    let response;
    try {
      response = await fetch('/api/email', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ email }),
      });
    } catch (error) {
      response = error;
    }
    switch (response?.status) {
      case 201:
        setEmail('');
        setButtonText('Signed up ✓');
        break;
      case 400:
      default:
        setButtonText('Signup failed ✗');
        break;
    }
  };
  return (
    <Contained
      id="signup"
      classes={classNames(
        'border-2 border-solid border-primary py-6 px-2 mt-6 mb-10',
        'tablet:w-4/5 tablet:mx-auto tablet:py-4 tablet:mt-6 tablet:mb-8',
        'desktop:py-6',
        router.asPath !== '/get-involved' && 'tablet:w-full',
        classes,
      )}
    >
      <h3
        className={classNames(
          'text-2xl font-semibold leading-none mb-2',
          'tablet:text-3xl',
          'desktop:text-4xl desktop:mb-3',
        )}
      >
        You&apos;ve got mail!
      </h3>
      <p
        className={classNames(
          'leading-none mb-6',
          'tablet:mb-3 tablet:leading-tight',
          'desktop:mb-6 desktop:text-xl',
        )}
      >
        Sign up to our newsletter to keep up to date with everything Oxen.
      </p>
      <form onSubmit={handleSubscription}>
        <Input
          type="email"
          placeholder="Your Email"
          value={email}
          onValueChange={value => setEmail(value)}
          size={'large'}
          border={'primary'}
          inputMode={'text'}
          className={classNames(
            'mb-6 rounded-sm',
            'tablet:mb-4',
            'desktop:mb-6',
          )}
          required
        />
        <Button
          color="primary"
          size="medium"
          className={classNames('mx-auto', 'tablet:w-40')}
          buttonType={'submit'}
          reference={buttonRef}
        >
          Sign up
        </Button>
      </form>
    </Contained>
  );
}