Skip to content

fix(elements): keep drop listeners stable during text input - #474

Open
ephraimduncan wants to merge 1 commit into
vercel:mainfrom
ephraimduncan:fix/prompt-input-drop-listener-churn
Open

fix(elements): keep drop listeners stable during text input#474
ephraimduncan wants to merge 1 commit into
vercel:mainfrom
ephraimduncan:fix/prompt-input-drop-listener-churn

Conversation

@ephraimduncan

@ephraimduncan ephraimduncan commented Aug 6, 2026

Copy link
Copy Markdown

With PromptInputProvider, each keystroke removed the dragover and drop listeners on the document or the form, and installed them again. The registration effect for the hidden file input also ran on each keystroke. After this change, the listeners attach one time for each mount, and text input does not touch them. The drop handlers call a useEffectEvent wrapper, and the wrapper calls the latest add closure. Thus the validation behavior for accept, maxFiles, maxFileSize, and onError does not change.

Five new tests spy on the document listeners and the form listeners during text input, and drop files after prop changes and count changes. Four of the five tests are not successful on the code before this change. The fifth test makes sure that a drop on the document adds the file.

Evidence:

Claim Evidence
Each keystroke makes a new controller identity packages/elements/src/prompt-input.tsx:348-359
Before this change, the drop effects had a dependency on add main, packages/elements/src/prompt-input.tsx:762,788
Before this change, the registration effect had a dependency on the controller main, packages/elements/src/prompt-input.tsx:717-722
The drop effects have a dependency on globalDrop only packages/elements/src/prompt-input.tsx:772,798
The useEffectEvent wrapper calls the latest add closure packages/elements/src/prompt-input.tsx:711-713
The registration effect has a dependency on the stable callback only packages/elements/src/prompt-input.tsx:726-732
The validation callback did not change packages/elements/src/prompt-input.tsx:644-685
Five new tests packages/elements/__tests__/prompt-input.test.tsx:1970,2005,2047,2106,2165
Four tests are not successful before this change Test runs in this session with the source change stashed

With PromptInputProvider, each keystroke made a new controller identity. The drop effects had a dependency on the add callback through that identity. Thus each keystroke removed the dragover and drop listeners and installed them again. The file-input registration effect also ran again on each keystroke.

This change uses useEffectEvent for the drop path. After this change, the listeners attach one time for each mount. The effect event calls the latest add closure. The validation behavior for accept, maxFiles, and maxFileSize does not change. The registration effect has a dependency only on the stable __registerFileInput callback.

Four new tests show stable listener counts during text input and successful drops after prop changes. These tests are not successful on the code before this change.
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

@ephraimduncan is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

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.

1 participant