A product picker can look like a small list with one simple action. Actual users may enter a quantity first, collect several products before inserting them or consult prices from earlier transactions. Requests in this project introduced a compact popup, selection-order insertion, immediate double-click insertion and a visible active result. I treat these details as rules for preserving work, rather than decorative options added after search is complete.

Preserve the row that existed before the picker opened

A user may have entered quantity and price before selecting a product. Replacing the entire row with product defaults would lose those values. Overwriting a row that already contains a description could remove another item. The archived selection code distinguishes a reusable row from an occupied row and determines whether insertion should fill it or create new rows after it. This boundary matters more than the appearance of the popup.

I would agree on concrete examples before implementing the interaction: an empty row, a quantity-only row, a manually named row and a row already linked to a product. Apply the same selection to each and describe which values survive and where a new line appears. This gives a reviewer a meaningful expectation. It also avoids writing tests that merely reproduce the implementation's current behavior without asking whether the user loses previously entered work.

Highlighting is not the same as selecting a set

The result under keyboard focus and the collection of checked products are different states. If a highlight remains on the wrong row, the user may misunderstand which product an action affects. Multiple selection also needs its own order. Changing a search term or moving to another page should have deliberate behavior for selections already made, rather than clearing them as an accidental side effect of loading new results.

The preserved selection helper appends a newly selected item and removes an item when it is selected again. The resulting collection determines insertion order. Immediate double-click insertion needs an explicit relationship with that collection, otherwise two event paths can insert the same product twice. A correct selected appearance does not establish a correct insertion result. Review the action count and resulting rows as well as the visible state of the list.

Partner-specific results are useful defaults

An earlier request prioritizes products frequently ordered by the selected customer. A later purchasing request narrows results to products associated with the selected supplier. Those are different contexts. Mixing sales history and purchasing history into one ranking could make a plausible suggestion for the wrong document. Document role and selected partner therefore need to travel into the search request, rather than being inferred from whichever list was most recently open.

If no related products exist, showing another partner's items as a silent substitute would conceal that fact. A clear empty state with an explicit route to the full catalog is easier to understand. A frequency ranking helps people find likely items; it does not prove that a supplier currently provides them. Separating defaults from a user's explicit changes makes room for exceptional purchases without presenting a convenience rule as verified business information.

Small popups still have important edge cases

Opening near the edge of a screen or above a mobile keyboard changes the available space. The archived implementation includes positioning against the visible viewport. The existence of that function does not establish comfortable behavior on a physical phone. Finding the active row, dismissing the popup and restoring focus are separate usability questions. Their answers should not be inferred from a static source check.

The reusable idea is to separate search conditions, active result, selected collection, destination row and insertion outcome. That separation makes lost input and duplicate actions easier to trace. This account is reconstructed from selected requests and preserved code; I did not replay the original customer screen or query its catalog. In a new implementation I would also check the row-limit failure: an unsuccessful insertion must leave the user's existing rows and values intact, rather than partially applying a selection and reporting an error afterward.