Custom SMTP port input disappears when a typed prefix matches a preset (5877 stops at 587)

Description

I need to enter SMTP port 5877 because port 587 is blocked by a firewall. When entering the custom port one digit at a time, the input disappears as soon as I reach 587, and the dropdown selects the preset 587. I cannot type the final digit into the port field.

Steps to reproduce

  1. Open the IMAP/SMTP account setup form.
  2. Under Outgoing Mail (SMTP), change Port to Custom.
  3. Focus the custom port input and select its existing contents.
  4. Type 5877 one digit at a time.

The issue occurs while editing the form, before attempting to connect to a mail server.

Actual behavior

After typing 5 and 8, the custom input remains visible. Typing the next 7 sets the port to 587, switches the dropdown to its 587 preset, and removes the custom input. Focus leaves the port field, preventing entry of the final 7 there.

Expected behavior

The custom input should stay visible and focused while I enter the complete port number, even when an intermediate prefix matches a preset. The final value should be 5877.

Version and verification

Checked on September 8, 2026 against Mailspring 1.23.0, the latest published stable release (published July 22, 2026).

The symptom was reproduced by executing the unmodified release-tag account form, form decorator, and field component with React 17.0.2, jsdom 26.1.0, and simulated user keyboard input. Peripheral application services and the account data model were stubbed. This is a component-level reproduction, not a full packaged Electron application test.

The current master form at f1a64fe0c04348be20006890581e6cfa5378d434 is byte-for-byte identical to the release form and reproduces the same behavior.

Additional component checks:

Input Result
Type SMTP 5877 Input disappears at 587
Paste SMTP 5877 in one operation Full value remains editable
Type SMTP 1587 Full value remains editable
Type SMTP 2525 or 4650 Input disappears at 25 or 465
Type IMAP 1430 or 9930 Input disappears at 143 or 993

Relevant code

In renderPortDropdown, each custom-input change goes through onPortChange, which converts the current text to a number. When that number matches a preset, isStandard becomes true and the !isStandard render condition removes the custom input immediately.

Keeping the user’s choice of Custom separate from the current numeric value would allow editing through a preset prefix without removing the input.

Related history: #1702 described the same prefix symptom for 2525. #2646 changed the custom input to use onPortChange; the prefix issue remains in 1.23.0.

Workaround

Select the custom input’s existing contents and paste 5877 in one operation. This preserves the full port value in the component test.