1import { Controller } from '@hotwired/stimulus'; 2 3/** 4 * Briefly highlights the deal-show "Purchase" value cell whenever the 5 * server-side auto-MAO recompute changes it. The flash distinguishes 6 * "the server just adjusted this number for you" from "you typed 7 * something" â the latter doesn't deserve attention. 8 * 9 * How it knows the difference: 10 * 11 * - When the auto-MAO recompute fires (user adjusted ARV / rehab 12 * and offerPriceAutoSet was still true), the Live Component 13 * morphs the rendered value text in place. This element stays 14 * present with `data-offer-auto-set="1"`. MutationObserver fires 15 * on the text change â flash plays. 16 * 17 * - When the user manually edits the offer field, the server-side 18 * syncToEntity check flips `offerPriceAutoSet` to false BEFORE 19 * the render returns. The morph either swaps this element for 20 * the non-auto variant (this controller disconnects, never sees 21 * the change) OR keeps the element but with `data-offer-auto-set` 22 * now "0" â the observer skips the flash in that case. 23 * 24 * Pure client-side â no server state needed for the animation. 25 */ 26export default class extends Controller { 27 connect() { 28 this._lastText = this.element.textContent.trim(); 29 this._observer = new MutationObserver(() => this._maybeFlash()); 30 this._observer.observe(this.element, { 31 childList: true, 32 characterData: true, 33 subtree: true, 34 }); 35 } 36 37 disconnect() { 38 if (this._observer) { 39 this._observer.disconnect(); 40 this._observer = null; 41 } 42 } 43 44 _maybeFlash() { 45 const current = this.element.textContent.trim(); 46 if (current === this._lastText) return; 47 this._lastText = current; 48 49 // Only flash when the offer is still server-owned (auto-set). 50 // A manual edit would have flipped this attribute to "0". 51 if (this.element.dataset.offerAutoSet !== '1') return; 52 53 // Force-restart the animation by removing + re-adding the 54 // class with a reflow in between. Otherwise the second 55 // recompute (same class still present) wouldn't replay. 56 this.element.classList.remove('offer-flash-anim'); 57 void this.element.offsetWidth; 58 this.element.classList.add('offer-flash-anim'); 59 } 60}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.