@jsenv/navi 0.27.58 → 0.27.60

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.
@@ -14285,9 +14285,14 @@ This prevents cross-test pollution and ensures clean state.`,
14285
14285
  // 1. We're navigating within the same route family (not to completely unrelated routes)
14286
14286
  // 2. AND no matching route extracts this parameter from URL
14287
14287
  // 3. AND parameter has no default value (making it truly optional)
14288
+ // 4. AND parameter is a path segment (not a search param)
14289
+ // Search params represent user preferences/choices and must survive
14290
+ // navigation away — only path segments are explicitly removed from
14291
+ // the URL when the route stops matching.
14288
14292
  if (
14289
14293
  matchingRouteInSameFamily &&
14290
- !parameterExtractedByMatchingRoute
14294
+ !parameterExtractedByMatchingRoute &&
14295
+ pathConnectionMap.has(paramName)
14291
14296
  ) {
14292
14297
  const defaultValue = connection.getDefaultValue();
14293
14298
  if (defaultValue === undefined) {
@@ -14309,6 +14314,10 @@ This prevents cross-test pollution and ensures clean state.`,
14309
14314
  console.debug(
14310
14315
  `[route] Different route family: preserving ${paramName} signal value: ${paramSignal.value}`,
14311
14316
  );
14317
+ } else if (queryConnectionMap.has(paramName)) {
14318
+ console.debug(
14319
+ `[route] Search param ${paramName}: preserving signal value (user choice): ${paramSignal.value}`,
14320
+ );
14312
14321
  } else {
14313
14322
  console.debug(
14314
14323
  `[route] Parameter ${paramName} extracted by matching route: preserving signal value: ${paramSignal.value}`,
@@ -14698,9 +14707,14 @@ const setupBrowserIntegrationViaHistory = ({
14698
14707
  const isSameUrl = url === window.location.href;
14699
14708
 
14700
14709
  if (navigationType === "push" || navigationType === "replace") {
14701
- // Pre-merge visited URLs so push/replaceState is called only once.
14710
+ // Merge onto the current state so existing useNavState entries (e.g. an
14711
+ // open dialog/popover) survive URL changes triggered by signal updates.
14712
+ // "traverse" is intentionally excluded: it restores the exact historical
14713
+ // state from the history entry, which is the source of truth for back/forward.
14714
+ const currentState = getDocumentState() || {};
14702
14715
  markUrlAsVisited(url);
14703
14716
  const effectiveState = {
14717
+ ...currentState,
14704
14718
  ...(state || {}),
14705
14719
  jsenv_visited_urls: Array.from(visitedUrlSet),
14706
14720
  };
@@ -35663,6 +35677,9 @@ const Dialog = props => {
35663
35677
  };
35664
35678
  closeRequestHandler(e, closePermission, detail);
35665
35679
  if (denied) {
35680
+ if (e.type === "cancel") {
35681
+ e.preventDefault();
35682
+ }
35666
35683
  closePermission.allow = () => {
35667
35684
  close(e, detail);
35668
35685
  };
@@ -35713,9 +35730,6 @@ const Dialog = props => {
35713
35730
  }
35714
35731
  },
35715
35732
  onCancel: e => {
35716
- // The browser fires "cancel" (then closes the dialog) when the user presses Escape.
35717
- // Prevent the native close so we control the close flow and dispatch navi_dialog_close.
35718
- e.preventDefault();
35719
35733
  onRequestClose(e);
35720
35734
  },
35721
35735
  onnavi_request_open: e => {
@@ -36403,7 +36417,11 @@ const PickerCustom = props => {
36403
36417
  isClickOutside
36404
36418
  } = {}) => {
36405
36419
  const cancelEvent = findEvent(requestCloseEvent, eInChain => eInChain.type === "navi_request_close" && eInChain.detail.isCancel);
36406
- const isCancel = isClickOutside || Boolean(cancelEvent);
36420
+ // open_prop_change means the parent is driving the open state directly
36421
+ // (e.g. back-button navigation flipped openProp to false before onLeave fires).
36422
+ // Always treat it as cancel — the user's in-progress edit should be discarded.
36423
+ const isPropDrivenClose = requestCloseEvent.type === "open_prop_change";
36424
+ const isCancel = isClickOutside || Boolean(cancelEvent) || isPropDrivenClose;
36407
36425
  if (isCancel) {
36408
36426
  const pickerEl = ref.current;
36409
36427
  const inputEl = getPickerInput(pickerEl);