Skip to content

CUI-5: Prevent implicit form submission on Enter for non-text elements#1014

Draft
JeanMarcMilletScality wants to merge 1 commit intodevelopment/1.0from
bugfix/CUI-5-select-enter-prevents-default
Draft

CUI-5: Prevent implicit form submission on Enter for non-text elements#1014
JeanMarcMilletScality wants to merge 1 commit intodevelopment/1.0from
bugfix/CUI-5-select-enter-prevents-default

Conversation

@JeanMarcMilletScality
Copy link
Contributor

@JeanMarcMilletScality JeanMarcMilletScality commented Feb 25, 2026

Summary

Pressing Enter on a Select inside a Form triggers form submission instead of interacting with the widget. Fixed by adding a preventImplicitSubmission handler on the Form's <form> element that only allows Enter to submit when the focused element is a writable text input or a button.

Ticket: https://scality.atlassian.net/browse/CUI-5

Changes

  • Added preventImplicitSubmission in Form.component.tsx (both PageForm and TabForm)
  • Added Form.test.tsx verifying Enter on a Select does not submit, and Enter on a text input still submits

Details: why this solution, alternatives considered, references

Root cause

The browser's implicit submission mechanism submits a <form> when Enter is pressed on any input element. React-select uses an internal readonly text input, which the browser treats as a regular text input. React-select does not call preventDefault() when the menu is closed, and its onKeyDown prop cannot be used with preventDefault() because react-select checks event.defaultPrevented and skips all keyboard handling if set.

Why fix this in the Form component

Per the WHATWG HTML spec, implicit submission is designed for text fields. The WAI-ARIA Combobox Pattern defines Enter on a combobox as accepting an autocomplete suggestion — it does not define Enter as triggering form submission. Since the combobox pattern does not delegate Enter to the form, implicit submission from a combobox is unexpected behavior. Keyboard operability is also an accessibility requirement (WCAG 2.1 SC 2.1.1).

Since the Form component owns the <form> element, it is the right place to control submission behavior. Individual widgets should not need to know they are inside a form, and this fix applies to all non-text elements uniformly.

Alternatives considered

1. preventDefault() in the Select's onKeyDown prop — Not viable. React-select checks event.defaultPrevented and skips all keyboard handling if set, breaking menu opening and option selection.

2. stopPropagation() in the Select's onKeyDown prop — Not viable. Implicit form submission is a browser default action, not triggered by event bubbling. stopPropagation() cannot prevent default actions.

3. Wrapper <div> with onKeyDown + preventDefault() around the Select — Works, but adds an unnecessary DOM node and places form submission logic inside the Select, which is the wrong abstraction.

The Form component now intercepts Enter keydown events and only allows
form submission when the focused element is a writable text input or a
button. This prevents custom widgets like Select from accidentally
triggering form submission when users press Enter to interact with them.
@bert-e
Copy link
Contributor

bert-e commented Feb 25, 2026

Hello jeanmarcmilletscality,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request TBA
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e
Copy link
Contributor

bert-e commented Feb 25, 2026

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

Comment on lines +275 to +289
const TEXT_INPUT_TYPES = ['text', 'search', 'url', 'tel', 'password', 'email', 'number'];

const preventImplicitSubmission = (
event: KeyboardEvent<HTMLFormElement>,
) => {
if (event.key !== 'Enter') return;
const target = event.target as HTMLElement;
const isTextInput =
target instanceof HTMLInputElement &&
TEXT_INPUT_TYPES.includes(target.type) &&
!target.readOnly;
if (!isTextInput && !(target instanceof HTMLButtonElement)) {
event.preventDefault();
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really unsure about this proposal. What if we have a select with search field (because we have more than 8 items) ? Then pressing enter on the search field trigger the submission.

Are we trying to solve a real problem in this PR ? What is described as a pb in here is a standard behavior I think.

@JeanMarcMilletScality JeanMarcMilletScality marked this pull request as draft February 26, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants