onFocus fires when keyboard focus enters an element as a whole. onBlur fires when focus leaves the element entirely. Both are element-scoped, not field-scoped.
Payload
Element-scoped, not field-scoped
Moving between sub-fields of a compound element (for example, fromline1 to city in billingAddress, or from the card number to the expiration inside card) does not produce intervening blur and focus pairs. Each element fires onFocus once when focus first enters its DOM subtree, and onBlur once when focus leaves the subtree entirely.
Example
Delivery sources
Focus can be delivered by keyboard, mouse, touch, or programmaticelement.focus(). All four go through the same DOM plumbing and produce a single onFocus when net focus enters, and a single onBlur when net focus leaves.
Per-element behavior
- Single-input elements (
email,submitButton,phone, single-modefullName) forward native focus and blur one-to-one. - Multi-input elements (split-mode
fullName,billingAddress,shippingAddress, manual-modebank,checkout,card) emit oneonFocuswhen focus first enters the element and oneonBlurwhen it leaves. Movement between sub-fields does not re-fire. bankfires focus and blur only in manual mode. In Plaid mode, focus and blur are not emitted — the launch button opens an external modal.applePay/googlePaywire focus and blur to the mount container. Focus events from inside the wallet-rendered button may not bubble out on every device — do not rely on them.
Use for analytics, not validation
Focus and blur are good for analytics (“shopper touched the card field”), micro-interactions, and side effects like autofilling a related field. Do not use them for validity gating; drive that offonChange.complete.