@metron-labs/quote-react 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -97,10 +97,13 @@ function QuickQuoteInner({ fullPage = false, hideHeader = false, internal = fals
97
97
  // Our own state only - copying the host's (e.g. Turbolinks' restoration id) makes its
98
98
  // router treat back/forward between our steps as its page visits and re-render the page,
99
99
  // wiping the quote. Next.js's patched pushState adds its own fields back.
100
- window.history.pushState({ boqQuoteStage: next }, "", url);
100
+ // New results while the URL still carries one of our steps (start over, or the host
101
+ // re-rendered the page under us) reuse that entry, or back would land on a stale copy.
102
+ const stale = next === "results" && (window.location.hash === "#matched-products" || window.location.hash === "#quote-request");
103
+ window.history[stale ? "replaceState" : "pushState"]({ boqQuoteStage: next }, "", url);
101
104
  }, []);
102
105
  useEffect(() => {
103
- const onPopState = () => {
106
+ const onPopState = (event) => {
104
107
  const hash = window.location.hash;
105
108
  if (hash === "#quote-request")
106
109
  setStage("basket");
@@ -109,14 +112,16 @@ function QuickQuoteInner({ fullPage = false, hideHeader = false, internal = fals
109
112
  else
110
113
  setStage("entry");
111
114
  // Turbo's popstate listener (registered before ours, so it can't be pre-empted) stamps its
112
- // restoration id over our entries. On the next back/forward it then treats them as its own
113
- // page visits and reloads the page, dropping the user on entry. Put our state back once
114
- // every listener has run.
115
+ // restoration id over any entry without one - ours, or the host's own entry for this page.
116
+ // On the next back/forward it then treats that entry as its page visit and re-renders the
117
+ // page, wiping the quote. Once every listener has run, undo the stamp.
118
+ const original = event.state;
119
+ const href = window.location.href;
115
120
  setTimeout(() => {
116
- const current = window.location.hash;
117
- if (current !== "#quote-request" && current !== "#matched-products")
121
+ if (original?.turbo || window.location.href !== href)
118
122
  return;
119
- window.history.replaceState({ boqQuoteStage: current === "#quote-request" ? "basket" : "results" }, "", window.location.href);
123
+ if (window.history.state?.turbo)
124
+ window.history.replaceState(original, "", href);
120
125
  });
121
126
  };
122
127
  window.addEventListener("popstate", onPopState);
@@ -127,11 +132,10 @@ function QuickQuoteInner({ fullPage = false, hideHeader = false, internal = fals
127
132
  setStage("basket");
128
133
  }, [writeQuoteHistory]);
129
134
  const backToResults = useCallback(() => {
135
+ // Step back over the basket entry goToBasket pushed (popstate picks the screen), rather
136
+ // than rewriting it: each rewrite left an extra results entry the browser back had to cross.
130
137
  if (window.location.hash === "#quote-request") {
131
- const url = new URL(window.location.href);
132
- url.hash = "matched-products";
133
- window.history.replaceState({ boqQuoteStage: "results" }, "", url);
134
- setStage("results");
138
+ window.history.back();
135
139
  return;
136
140
  }
137
141
  setStage(scheduleResult ? "results" : "entry");