Skip to content

Enter key should be the same as "Submit" in the popups #130

@mattakamatsu

Description

@mattakamatsu

I want to be able to enter the dialog (popup) inputs entirely from my keyboard. This would increase the time I'm in flow when making pages. I can navigate and enter all fields, except clicking a checkbox (which isn't a big deal) and "Submit" (which requires me from leaving the keyboard). I'd like to be able to hit Enter, and have that be the same as "Submit" for these popup dialogs.

https://www.loom.com/share/cdf1d58d4f4e48aaa532f0330b06e2a7?sid=f448f640-1ce2-4c92-94cb-94eee78d4dee

Image

This is what copilot thinks needs to be done fwiw:

To make hitting **Enter** behave the same as clicking "Submit" in your `Prompt` component, you should ensure that the **Enter** key triggers the same handler as the "Submit" (which, in this code, is the **onConfirm** handler of `Alert`). 

Currently, the Enter key is only handled on the `<InputGroup>` (the plain text input case). For dropdowns, block inputs, and page inputs, the Enter key may already be handled internally, or may need explicit wiring.

### Universal Solution

Wrap the core of your `<Alert>` in a `<form>` and set its `onSubmit` to call the same resolve logic.  
You also want to prevent the default form submission to avoid page reloads.

#### Steps:

1. **Add a `<form>` around the main content (inside the `<Alert>`)**.
2. **Set `onSubmit` to a handler that calls `resolveAndClose` with the correct value**.
3. **Ensure all main inputs/buttons are inside the `<form>` so pressing Enter triggers submission**.

#### Example Patch

```tsx
// ... inside your Prompt component, replace the return statement with:

return (
  <Alert
    isOpen={true}
    canOutsideClickCancel
    canEscapeKeyCancel
    onCancel={() => resolveAndClose("")}
    onConfirm={() =>
      resolveAndClose(/{ref}/.test(display) ? `((${uid}))` : value)
    }
    cancelButtonText={"cancel"}
    confirmButtonText={"Submit"} // Make the button label explicit, optional
  >
    <H3>SmartBlocks Input</H3>
    <form
      onSubmit={e => {
        e.preventDefault();
        resolveAndClose(/{ref}/.test(display) ? `((${uid}))` : value);
      }}
    >
      <div className={Classes.ALERT_BODY} ref={contentRef}>
        <Label style={{ whiteSpace: "pre-wrap" }}>
          {formattedDisplay}
          {isBlockInput ? (
            <BlockInput
              value={value}
              setValue={(q, s) => {
                setValue(q);
                setUid(s);
              }}
              onConfirm={() => {
                resolveAndClose(/{ref}/.test(display) ? `((${uid}))` : value);
              }}
              getAllBlocks={getAllBlocks}
            />
          ) : formattedOptions.length ? (
            formattedOptions.length < 10 ? (
              <MenuItemSelect
                activeItem={value}
                onItemSelect={(v) => setValue(v)}
                items={[formattedInitialValue, ...formattedOptions]}
                popoverProps={{ portalClassName: "roamjs-prompt-dropdown" }}
                ButtonProps={{ autoFocus: true }}
              />
            ) : (
              <AutocompleteInput
                value={value}
                setValue={setValue}
                options={formattedOptions.concat(value)}
                autoFocus
              />
            )
          ) : isPageInput ? (
            <PageInput
              value={value}
              setValue={setValue}
              onConfirm={() => resolveAndClose(value)}
              autoFocus
            />
          ) : (
            <InputGroup
              placeholder={"Enter value..."}
              value={value}
              onChange={(e) => setValue(e.target.value)}
              autoFocus
              // This onKeyDown is now optional, since form handles submit
            />
          )}
        </Label>
      </div>
      {/* Optionally, hide a submit button for accessibility */}
      <button type="submit" style={{ display: "none" }} tabIndex={-1} />
    </form>
  </Alert>
);

Notes

  • This works for all input types, as the Enter key on any form input will submit the form.
  • Make sure your custom components (like BlockInput, MenuItemSelect, etc.) do not hijack Enter in a way that blocks form submission, or that they call the same handler on Enter as onConfirm.
  • If you want to handle Enter differently in some cases, you can add an onKeyDown prop to those specific components.

Summary:
Wrap your prompt body in a <form onSubmit={...}> and call your submit logic there. This makes Enter behave like clicking "Submit" for all input types!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions